diff --git a/.gitignore b/.gitignore index 8ca7bf2b0..c5a81c16c 100644 --- a/.gitignore +++ b/.gitignore @@ -164,6 +164,8 @@ ipch/ node_modules/ packages/* publish/ +source/*/build/* +source/build/* source/build-cmake/*/build-win32/* source/build-cmake/*/build/* source/src/vm/libcpu_newdev/mame0185/* diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 000000000..2ebba742d --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,59 @@ +

** HowTo build/install Qt porting for Common Source Code Project **

+

-- CSP/Qt(略称)のビルドとインストールの仕方

+
+

Oct 08, 2020
+K.Ohta

+
+ +はじめに +======== +この文章では、Qt porting for Common Source Code Project (CSP/Qt)のビルド手順について記述します。 + +用意すべきもの(標準) +======= +--GCC又はCLANGなどの、コンパイラツールチェイン + +--CMake (3.9以上推奨) + +- 以下の開発ライブラリ(大抵のGNU/Linux OSやBSD系のOSなどではパッケージマネージャ(dfnやaptなど)で入るはずです。)が必要になります。**なお、現状、表示にOpenGL2.1以上かOpenGL ES2以上が必要になります**。 + - QT5 (QTCore, QtOpenGL, QtNetworkなど) + - SDL2 + - libAV + - zlib +  その他、色々必要になります。 + +- Windows向けのビルドの場合、OpenGL ESを実装した[Angle Project]()が実行に必要になるかもしれません。これは、Google Chromeブラウザのオープンソース版である[Chromium Project]()のWindow (x86 32bit)ビルドの中にある、libEGL.dllとlibGLESv2.dllを使えばどうにかなります。 + +## なお、Windows向けのビルドをするための環境を、Dockerの形でビルドして使うと便利です。 +## Dockerレポジトリは +## 元のDockerfileは + +ビルド手法 +========= + +既にgitからcloneしたりリリースに添付されたソースコードを解凍してビルドする場合、 + +$ `cd ${SRCROOT}/source` +$ `mkdir build` +$ `cd build/` +$ `cmake ..` +$ `make` + +とすればとにかくのビルドが可能ですが、**標準的な設定パラメータを収めたシェルスクリプトを、${SRCROOT}/source/sample-scripts/ 以下に入れてあります(まだまだ追加するかも)**。 + +このサンプルを使って、 +$ `cd ${SRCROOT}/source` +$ `mkdir build` +$ `cd build/` +$ `cp ../sample-scripts/build_default_vars.llvm.sh .` +とビルドディレクトリに取って来た後で、 +$ `sh ./build_default_vars.llvm.sh` +などとしてブートストラップ設定をして、CMakeがエラー起こさなかったら、 +$ `make {色々オプション}` +としてビルドしてみましょう。 + +インストール手法 +=============== + +普通は、 # `make install`で可能なはずです。Windowsビルドの場合は、まだToDoです。 + Last Update: Oct 08, 2020 04:52:37 diff --git a/README.md b/README.md index 7e2538b49..5d9242451 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ K.Ohta

## *If you can't read Japanese, [english writing is here](/README.en.md/).* - +## *ビルドやインストールをされたい方は、[こちらを](/INSTALL.md/)。 概要 ====== diff --git a/doc/CrossBuild_Win32.ja.txt b/doc/CrossBuild_Win32.ja.txt new file mode 100644 index 000000000..b0e10d582 --- /dev/null +++ b/doc/CrossBuild_Win32.ja.txt @@ -0,0 +1,50 @@ +** クロスビルド環境に関して +--- Oct 26, 2019 Kyuma Ohta + +1.はじめに + Common Source code Project(以下CSP)では、今までWindows向けビルドには + Debian GNU/Linux上で動くMinGW-w64 クロスコンパイラツールチェーンを使 + って来ました。 + しかし、MinGW-w64でビルドされたプログラムは、遅い。と言うか、重い。 + C++の例外処理(exception)について、32ビット環境に関しては、歴史的な + 特許の問題があって、高速な処理法が使えない。と言う問題があるからです。 + (64ビットビルドだと、特許に引っかからない方法が使われてる?) + その他にもいくつか問題があったので、コンパイラツールチェーンをLLVM CLANG + に切り替えてみました。が、MinGW-w64と共存させているとヘッダが派手に + 衝突しまくるので、どうしたものか…と考えていたら、Docker環境でコン + テナを作ってクロスビルド環境を作るという方法がされていたので、カスタ + マイズしてみたのです。 + +2.具体的にはどうするか。 + まず、Dockerを入れて下さい。Dockerは、GNU/LinuxなOSなら、ほぼ簡単に + インストール出来ますし、WindowsでもWindows10ならば簡単に入るらしいで + す。 + MacやWindows8.1以前は、できるようですがよくわからない。 + + そして、Dockerhubから、以下のイメージ(※Ubuntu がアップデートしたら + 変わるかも)をpullしてください。[1] + $ docker pull artanejp/mingw-w64-llvm-ubuntu19.10:initial + + 数GB以上のディスクが必要になりますが、LLVM CLANGのクロス + ツールチェインと、CSPをビルドするのに必要なライブラリ群が一気に + 用意されます。 + 後は、このイメージを起動して、 + adduser でユーザを作りsuでユーザを切り替え、docker コンテナ内から + $ mkdir ~/src + $ cd ~/src + $ git pull https://github.com/Artanejp/common_source_project-fm7.git + $ cd common_source_project-fm7/source/build-cmake + $ cp buildvars_mingw_cross_win32.dat.tmpl buildvars_mingw_cross_win32.dat + として、 buildvars_mingw_cross_win32.dat を適切に設定した上で、 + $ ./config_build_cross_win32.sh VM名 + とすれば、ビルドを始めるはずです。多分。 + +お楽しみを! +K.Ohta + +[1] Dockerを作る時のスクリプトなどは、 https://github.com/Artanejp/llvm-mingw + でメンテナンスをしています。 + + 又、DockerHubの直接のページは、 + https://cloud.docker.com/u/artanejp/repository/docker/artanejp/mingw-w64-llvm-ubuntu19.10 + です。 diff --git a/doc/VMs/bmjr.txt b/doc/VMs/bmjr.txt index 1802e8e30..9371c6c18 100644 --- a/doc/VMs/bmjr.txt +++ b/doc/VMs/bmjr.txt @@ -1,5 +1,5 @@ "eBASICMasterJr" - HITACHI BASIC Master Jr emulator for Win32 - 9/8/2015 + 1/14/2020 --- Internal ROM image @@ -12,11 +12,13 @@ Virtual PC -------------------------------- - EISUU Left Ctrl - EIKIGOU Left Shift - KANA Right Ctrl - KANAKIGOU Right Shift - + EISUU Left Ctrl + EIKIGOU Left Shift + KANA Right Ctrl (Qt: or Katakana Hiragana) + KANAKIGOU Right Shift + KOUTAI/DEL Back Space or Delete + FUKKAI/RETURN Enter + BREAK Esc or Pause / Break ---------------------------------------- TAKEDA, toshiya t-takeda@m1.interq.or.jp diff --git a/doc/VMs/fmtowns.txt b/doc/VMs/fmtowns.txt new file mode 100644 index 000000000..80ba90717 --- /dev/null +++ b/doc/VMs/fmtowns.txt @@ -0,0 +1,70 @@ +"eFMTowns" - FUJITSU FM-Towns series emulator for some platforms. + 6/26/2020 + +--- Internal ROM images + + FMT_SYS.ROM IPL/BIOS ROM 256KB + FMT_FNT.ROM 16pixs FONT ROM 256KB + FMT_DOS.ROM MS-DOS ROM 512KB + FMT_DIC.ROM OAK DICTIONARY ROM 512KB + + Optional: + FMT_F20.ROM 20pixs ROM 512KB (Optional for later machines) + + Note: + - You can use both *real* machine's ROM and compatible ROM + that supports a emulated machine. + - Pseudo BIOS *DON'T* include these emulators. + This may be policy of eFM-Towns (maybe not change). + +--- STATUS (6/24/2020) + + - Bootable from SCSI HDD. + - Softwares using SPRITE are not working YET. + - Unable to boot TownsOS v1.1 excepts v1.1L10. + - CD-ROM still does not work well. + - E-Volumes are not implement yet. + - See source/src/vm/fmtowns/00_status.ja.md for more information. + +--- Key maps + Virtual PC + -------------------------------- + BREAK Pause Break + ALT/GRAPH Left ALT + HIRAGANA/ROMAJI HIRAGANA + HANKAKU/ZENKAKU HANKAKU/ZENKAKU + HENKAN HENKAN + MUHENKAN MUHENKAN + KANA/KANJI F11 + KATAKANA F12 + COPY Print Screen + ZENGYOU PgUp + JIGYOU PgDn + JIKKOU Right WIN + TORIKESHI Left WIN + KANJI JISHO Right ALT + Print Screen + TANGO MASSHOU Right ALT + Scroll Lock + TANGO TOUROKU Right ALT + Pause Break + PF11 Right ALT + F1 + PF12 Right ALT + F2 + PF13 Right ALT + F3 + PF14 Right ALT + F4 + PF15 Right ALT + F5 + PF16 Right ALT + F6 + PF17 Right ALT + F7 + PF18 Right ALT + F8 + PF19 Right ALT + F9 + PF20 Right ALT + F10 + + Tips: + 1. Romaji-Kana conversion (at some OSs) will enable "Ctrl + HIRAGANA". + +--- Have fun! + +---------------------------------------- +Kyuma Ohta +whatisthis.sowhat _at_ gmail.com + +https://github.com/Artanejp/common_source_project-fm7 +https://osdn.net/projects/csp-qt +Twitter: @Artanejp diff --git a/doc/VMs/micom_mahjong.txt b/doc/VMs/micom_mahjong.txt new file mode 100644 index 000000000..df25aaee4 --- /dev/null +++ b/doc/VMs/micom_mahjong.txt @@ -0,0 +1,98 @@ +◇ MICOM MAHJONG Emulator 'eMuCom Mahjong'on Common Source Code Project + Hiroaki GOTO as GORRY / http://GORRY.hauN.org/ + Version 20200721a + +======================================================================== +1. これはなに? +======================================================================== + +'eMuCom Mahjong'は、家庭用ゲーム機「マイコン麻雀(日本メールサービス、 +1982年)」を再現するエミュレータを、武田俊也氏による「Common Source +Code Project」上にて実装したものです。 + +「Common Source Code Project」については、以下をご覧ください。 +http://takeda-toshiya.my.coocan.jp/common/index.html + + +======================================================================== +2. なにがいる? +======================================================================== + +'eMuCom Mahjong'の動作には、以下のものが必要です。 + +1. ハードウェア + + Windows 10 32/64bit上で動作確認をしています。 + +2. 実機ROMイメージファイル + + 「マイコン麻雀」実機には、以下のROMが搭載されています。 + + - MS-1 2732(32x8bit ROM) + - MS-2 2732(32x8bit ROM) + - MS-3 2732(32x8bit ROM) + - MS-4 2732(32x8bit ROM) + →以上を連結し、「PRG.ROM」ファイル(16384バイト)を作成します。 + + - MS-A 2716(16x8bit ROM) + →「CG.ROM」ファイル(2048バイト)を作成します。 + + 以上を実行ファイル「micom_mahjong.exe」と同じフォルダに置き、実行ファ + イルを起動します。 + + +======================================================================== +3. なにをおす? +======================================================================== + +'eMuCom Mahjong'は、以下のキーで操作します。 + + 1 1(フルキー) + 2 2(フルキー) + 3 3(フルキー) + 4 4(フルキー) + 5 5(フルキー) + 6 6(フルキー) + 7 7(フルキー) + 8 8(フルキー) + 9 9(フルキー) + 10 0(フルキー) + 11 [-=ほ](JPキー), [-~](USキー), 1(テンキー) + 12 [^~へ](JPキー), [=+](USキー), 2(テンキー) + 13 [\|](JPキー), [BackSpace](JP/USキー), 3(テンキー) + 0(ツモ) Enter, Space + ポン Z, F1 + チー X, F2 + カン C, F3 + リーチ V, F4 + ロン A, F5 + + +======================================================================== +4. びるどする? +======================================================================== + +このパッケージに含まれるソースは、「Common Source Code Project」のソース + (4/6/2020版)の上に重ねて解凍することで、ビルドを行うことができます。 +「vc++2013/micom_mahjong.vcxproj」をVisual Studio 2013で開いてください。 + + +======================================================================== +5. 著作権表記 +======================================================================== + +このパッケージには、当方が記名したソースファイルが同梱されています。これ +らは当方が著作権を主張しますが、使用・再配布は当方または「Common Source +Code Project」管理者が定める方法・条件に基づいて行うことができます。 + + +======================================================================== +6. 連絡先 +======================================================================== + +後藤 浩昭 / GORRY +http://GORRY.hauN.org/ +twitter/gorry5 + +======================================================================== +[EOF] diff --git a/source/000_gitlog.txt b/source/000_gitlog.txt index a6139cc76..b34c6aa50 100644 --- a/source/000_gitlog.txt +++ b/source/000_gitlog.txt @@ -1,3 +1,4010 @@ +commit cdfc81b7398812d0f9206d5b978808fcbc5ebf0e +Author: K.Ohta +Date: Sun Sep 27 00:32:11 2020 +0900 + + [VM][FMTOWNS][CDROM] Re-Disable value handling around command 80h. + +commit 122d13863dd8fdf7a16dc0f4d473f534d353265b +Author: K.Ohta +Date: Sun Sep 27 00:31:49 2020 +0900 + + [VM][FMTOWNS][JOYPAD] Fix around input. + +commit a246d9479b9cbff883077b23f4952cb2a37efcf8 +Author: K.Ohta +Date: Sun Sep 27 00:31:18 2020 +0900 + + [UI][Qt] Fix not update around virtual media display. + +commit 1afadd48f6e652f877152480c47fe6a994455de4 +Author: K.Ohta +Date: Sat Sep 26 21:14:07 2020 +0900 + + [TOOLS][PATCH][LKAME] . + +commit 303a5ecdb6686d51d1742188d4c82689d6d4a6e0 +Author: K.Ohta +Date: Sat Sep 26 21:13:42 2020 +0900 + + [TOOL] I forgot to add pathes for Qt5.15 X-) + +commit 014ee89021e07f39d9fc95257f83392fd1d85869 +Author: K.Ohta +Date: Sat Sep 26 21:02:59 2020 +0900 + + [INSTALLER] Update Installer. + +commit cc57316ff34c63bef1e79cccb2f7b440c2c70dd6 +Author: K.Ohta +Date: Sat Sep 26 18:33:07 2020 +0900 + + [DOC] Update to release. + +commit 97db8d7a26eb8eeb7722b009456d7c9bcadda0f7 +Author: K.Ohta +Date: Sat Sep 26 17:47:47 2020 +0900 + + [VM][FMTOWNS][CDROM] Re-Enable around command 80h. + +commit b7903525a7164ac167d25b6ba8dda1c2fc464cea +Author: K.Ohta +Date: Sat Sep 26 16:53:51 2020 +0900 + + [VM][FMTOWNS][JOYSTICK][JOYPAD] Update credits.Add #pragma once to joypad.h . + +commit 9e84653b731dfb3f8f8223f50675cfe23249395a +Author: K.Ohta +Date: Sat Sep 26 16:51:13 2020 +0900 + + [VM][FMTOWNS][JOYSTICK][JOYPAD] Add 6button pad emulation (OK?).Separate JOYPAD to a class. + +commit 1adf959ecea003129afb13b52f1e7bab55245665 +Author: K.Ohta +Date: Sat Sep 26 07:34:48 2020 +0900 + + [VM][I386_NP21][FMTOWNS][DMAC][CDROM] Stop LOG SPAM. + +commit 1e2ccb3e738a9dddcc5d8a9616c94fa7e96d5a3d +Author: K.Ohta +Date: Sat Sep 26 03:35:31 2020 +0900 + + [VM][FMTOWNS][CDROM] Don't stop CDDA at SEEK COMMAND. + +commit 45b430ad73fee1c2c2dc4940cf7ee79260faba99 +Author: K.Ohta +Date: Sat Sep 26 03:34:11 2020 +0900 + + [VM][FMTOWNS] Update status. + +commit 0ae9dca8543a9c3d0116dc55c3cc87a9c4a16212 +Author: K.Ohta +Date: Sat Sep 26 03:21:25 2020 +0900 + + [VM][I386_NP21] Add debug message for exception. + +commit abb868f0ed9071e63940b876eec8c7a8cb3ec041 +Author: K.Ohta +Date: Sat Sep 26 03:20:14 2020 +0900 + + [VM][FMTOWNS][KEYBOARD][WIP] TRY: Implementing key repeat, but still not work (by HOST OS's key input spec). + +commit 4ea5cea3fa68554a5126d2c968741627d2dc599d +Author: K.Ohta +Date: Sat Sep 26 03:19:28 2020 +0900 + + [VM][FMTOWNS][CDROM] Should read per a sector, not variable length. + +commit 4e60e31243491b26928ad8081c7a19cccb4c7b88 +Author: K.Ohta +Date: Sat Sep 26 03:18:40 2020 +0900 + + [VM][FMTOWNS][DMAC] Bootable TownsOS v1.1L30 based softwares.Fix around DMA address mask. + +commit 57a064cd1b0f01b7cd4f040a7a44194dc33a2a53 +Author: K.Ohta +Date: Fri Sep 25 22:31:10 2020 +0900 + + [VM][FMTOWNS][KEYBOARD] TRY: Boot with 'CD' 'H0' etc.Still works only with 'DEBUG'. + +commit 4c8469d854b474ed8af92b90d1df7d3859adb66e +Author: K.Ohta +Date: Fri Sep 25 22:30:53 2020 +0900 + + [VM][FMTOWNS][SPRITE] Fix fallthrough. + +commit 54a06540479d1c37f6a7ab83942192cce8bf250e +Author: K.Ohta +Date: Fri Sep 25 22:30:29 2020 +0900 + + [VM][FMTOWNS][MEMORY] Fix fallthrough. + +commit 8eca5c6d73d0d3d19c49216eae1933785c5871c8 +Author: K.Ohta +Date: Fri Sep 25 22:29:55 2020 +0900 + + [VM][FMTOWNS][FLOPPY] Fix fallthrough on I/O. + +commit 5885d240e1a4abefdf12d259dd6cfeb3e4f5a1c4 +Author: K.Ohta +Date: Fri Sep 25 22:29:02 2020 +0900 + + [VM][FMTOWNS][CDROM] Set CDDA_STATUS=CDDA_OFF before reading data.Fix スーパーリアル麻雀PIV. + +commit c7144c953f184f840f4d0e6fe9c63f1da0ff77d8 +Author: K.Ohta +Date: Fri Sep 25 19:40:32 2020 +0900 + + [VM][FMTOWNS][TIMER][OOPs] Fix fallthrough at write_iox().Didable 1uS wait feature wait before xxF/xxH. + +commit 0b26f6c591a825b56abd4825ecf045ee7a03e9cc +Author: K.Ohta +Date: Fri Sep 25 19:29:55 2020 +0900 + + [VM][FMTOWNS][FLOPPY] Implement some bits and disk changed feature (0208h:bit0:R after Towns2H/2F/1H/1F). + +commit 85353378e24de330491932d115cbdd63a53902aa +Author: K.Ohta +Date: Fri Sep 25 19:28:13 2020 +0900 + + [EMU][UI][FLOPPY] Implement 1sec delayed open() for floppy, fix not detect when changing from HISTORY. + +commit c17ea7059156e05d05945674bc47af6518c7aa9d +Author: K.Ohta +Date: Sat Sep 19 01:33:34 2020 +0900 + + [VM][FMTOWNS][CDROM] Comment out some debug messages. + +commit d852769d183183b75a6b7794e1c4a25163a89335 +Author: K.Ohta +Date: Sat Sep 19 01:32:52 2020 +0900 + + [VM][FMTOWNS][TIMER] Disable free run counter before 1H/2H/1F/2F. + +commit 6647feba7fdd6af12354fe83a7de273e5bce2bf0 +Author: K.Ohta +Date: Sat Sep 19 00:40:18 2020 +0900 + + [VM][FMTOWNS]{CDROM] Implement pseudo burst transfer. + +commit 047feed6239254cedcb82e5bb04310e07eaf15f7 +Author: K.Ohta +Date: Fri Sep 18 20:36:18 2020 +0900 + + [VM][FMTOWNS][CDROM Adjust timing. + +commit 1e321abe98df35b7919a61a9c49665a207d25830 +Author: K.Ohta +Date: Fri Sep 18 16:35:50 2020 +0900 + + [VM][FMTOWNS][CDROM] Adjust around RESTORE command (00h). + +commit 59428c4f508d018e6c21ab9bf6a61537475483a6 +Author: K.Ohta +Date: Fri Sep 18 16:34:55 2020 +0900 + + [VM][UPD71071] Implement ENDx signal for stopping DMA from some devices. + +commit 2b3dc459c5ae2f2864a93e95bdd428078d27e228 +Author: K.Ohta +Date: Fri Sep 18 02:52:22 2020 +0900 + + [VM][FMTOWNS][CDROM] Re-Adjust wait timing.Fix freezing at Fractal Engine. + +commit ea94af563e9bfa61feded148e57fa46ec486a6bb +Author: K.Ohta +Date: Fri Sep 18 02:15:57 2020 +0900 + + [VM][FMTOWNS][CDROM] Adjust read timing and EOT(a.k.a TC from DMAC) sequence. + +commit 369096732b033ee40f8f46761746694ad7117d81 +Author: K.Ohta +Date: Fri Sep 18 02:15:01 2020 +0900 + + [VM][FMTOWNS][SCSI] Set ctr_reg after sending command to host. + +commit 58376563d6f5b99d54ab82c12f5aeab0ea1b0a6f +Author: K.Ohta +Date: Fri Sep 18 02:13:56 2020 +0900 + + [VM][UPD71071] SREQ is prior than MASK.Don't auto transfer at demand mode. + +commit d902d7bfd479cc5d66922a807a2e575238fa4fea +Author: K.Ohta +Date: Wed Sep 16 19:13:52 2020 +0900 + + [VM][UPD71071] . + +commit 32361d4f7b828fbb0a8a17e4005e7ae4fa2332df +Author: K.Ohta +Date: Wed Sep 16 19:13:23 2020 +0900 + + [VM][FMTOWNS][SCSI] TRY: Add SIG_SCSI_EOT signal (still not effective). + +commit 4d4fd775ed248728787aa32caeb58362fa79e6d5 +Author: K.Ohta +Date: Wed Sep 16 16:13:37 2020 +0900 + + [VM][UPD71071] Improve around TC sequence. + +commit 9bf46a566cbce93556eab44afae46a83853374fb +Author: K.Ohta +Date: Wed Sep 16 16:13:09 2020 +0900 + + [VM][FMTOWNS][CDROM] TRY: Implement PIO transfer. + +commit 861d10504e32a6751a09c624aacd21e7e50d9b2b +Author: K.Ohta +Date: Tue Sep 15 17:46:22 2020 +0900 + + [VM][I386_NP21] Record exception even not debugging. + +commit 107d47d1b929b32776dcbde95affb89e4e4be6fa +Author: K.Ohta +Date: Tue Sep 15 17:46:13 2020 +0900 + + [VM][FMTOWNS] . + +commit 9db22ea33042e2c2131cd27d351fc6c2957d3f62 +Author: K.Ohta +Date: Tue Sep 15 14:53:48 2020 +0900 + + [VM][I8259] . + +commit f07c4c33b250e75a65adce372ee985473cbd941e +Author: K.Ohta +Date: Tue Sep 15 14:52:58 2020 +0900 + + [VM][I8259] Initialize registers by reset(). + +commit 3ba0cc56d72f6a5fb72e3dfdd1fee2660ed14ba4 +Author: K.Ohta +Date: Mon Sep 7 16:53:49 2020 +0900 + + [VM][I386_NP21] . + +commit 0cc275111151c33c927b5574f532fa54aa95286e +Author: K.Ohta +Date: Mon Sep 7 16:53:05 2020 +0900 + + [VM][FMTOWNS][CDROM][WIP] Status around CMD A0h. This is working-in-progress. + +commit 6b92586a1b4b57e1a066b8cf12365ff8f97f67cf +Author: K.Ohta +Date: Sun Sep 6 19:27:36 2020 +0900 + + [VM][UPD71071][FMTOWNS][MZ2800] Update API; Separate TC signals per a channel. + +commit 4e303fecfc1024cb996d4f2db350ba78cf8b56d0 +Author: K.Ohta +Date: Sun Sep 6 18:26:21 2020 +0900 + + [VM][FMTOWNS] Now, build with _IO_DEBUG_LOG to debug CDROM'ed TownsOS v1.1L30's issue. + + [VM][FMTOWNS][DMAC] Re-Enable debug message. + +commit 25fbdc5bdacffb377c1794a99e284091630a5345 +Author: K.Ohta +Date: Sun Sep 6 18:25:38 2020 +0900 + + [VM][FMTOWNS][MEMORY] Integrate memory accessing to primitive inline functions. + +commit 3b1be96ae8ef088e7f45b00bb3a3e6c01196b931 +Author: K.Ohta +Date: Sun Sep 6 03:32:07 2020 +0900 + + [VM][FMTOWNS][CDROM] READ MODE1: May not need extra status, integrated after reading. + +commit afcd73554add455a2241747aeadc02248edcd846 +Author: K.Ohta +Date: Sun Sep 6 02:05:22 2020 +0900 + + [VM][FMTOWNS][CDROM] PAUSE COMMAND (85h) : Return extra status even isn't audio track. + +commit 1d52b39fd74875b6ecdba1aea72bf73c2d1a2d69 +Author: K.Ohta +Date: Sun Sep 6 01:42:01 2020 +0900 + + [VM][FMTOWNS][CDROM] Event driven sector reading. + +commit 0fb1eb09a1e64a863d1e000f615d0d9e6f4dd97b +Author: K.Ohta +Date: Sun Sep 6 01:40:11 2020 +0900 + + [VM][UPD71071] Fix tc bit down. + + [VM][UPD71071] Add some signals. + +commit 05fc0653e1bee2842da9244cc7646498bebec43b +Author: K.Ohta +Date: Fri Sep 4 00:22:39 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix double interrupt when over count DMA. + +commit 3778a786d5edc8932605a076f90370348c0df26f +Author: K.Ohta +Date: Fri Sep 4 00:02:05 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 69f9143c01994639e620037bf6f12210f57407f8 +Author: K.Ohta +Date: Thu Sep 3 16:59:12 2020 +0900 + + [VM][FMTOWNS][CDROM][DMA] Add debug messages. + +commit c1c45d04c2452ddfaad2db6a07a6647201ac5357 +Author: K.Ohta +Date: Mon Aug 31 02:15:51 2020 +0900 + + [VM][FMTOWNS][CDROM] Set status to CDDA PLAYING even seeking to target track. + +commit 9e1001984e4e49d4f4a771841f9fe3ff56ff8808 +Author: K.Ohta +Date: Mon Aug 31 01:52:42 2020 +0900 + + [VM][FMTOWNS][PLANE_VRAM] Comment out unneeded debuggig log. + +commit 4eefcc5a39bd8d91fef99209609147f9abdada43 +Author: K.Ohta +Date: Mon Aug 31 01:10:36 2020 +0900 + + [VM][FMTOWNS][MEMORY] . + +commit 7b6234623dc585e81be2cd596b8aa4b82312d6a4 +Author: K.Ohta +Date: Mon Aug 31 01:08:29 2020 +0900 + + [VM][FMTOWNS][CRTC] Adjust around VSYNC/HSYNC. + +commit 600a07d1212a70286471535a7349ba38d8b45629 +Author: K.Ohta +Date: Mon Aug 31 01:07:12 2020 +0900 + + [VM][FMTOWNS][CDROM] Revert before two commits.Now base on commit c1ad560a478708194b72a80ab79b56556e55537d. + +commit 1f20810411ec4e90372fcb2e29a3caea11a93d83 +Author: K.Ohta +Date: Sun Aug 30 22:38:58 2020 +0900 + + [VM][DEVICE] Change API: special_reset(num).This aimes to support FM-Towns's multiple special resetting. + +commit 51efc809aa22520030361dcb19a5955b672af80e +Author: K.Ohta +Date: Sun Aug 30 17:23:02 2020 +0900 + + [VM][FMTONWS][CDROM] DMA transfer: DMA driven sector reading. + + [VM][FMTOWNS][KEYBOARD] . + +commit c446b69f5137984600cedc673b00fa0e4db9b998 +Author: K.Ohta +Date: Sun Aug 30 16:27:37 2020 +0900 + + [VM][FMTOWNS][CDROM] Re-check around command queue. + +commit 1f1ead7f8da5acefff5ac10689972b878a05b025 +Merge: 18a2fc6f f77bb68d +Author: K.Ohta +Date: Sun Aug 23 04:38:08 2020 +0900 + + Merge branch 'master' + +commit 18a2fc6f559b2ffbe03f32d64c34617e52c2322f +Author: K.Ohta +Date: Sun Aug 23 04:32:34 2020 +0900 + + [VM][FMTOWNS][CRTC][WIP] Adjusting H-offset on transferring. + +commit f92a2a8575e2d90f6a55fc4d8e6b543215c8b236 +Author: K.Ohta +Date: Sun Aug 23 03:25:57 2020 +0900 + + [VM][FMTOWNS][SPRITE] Fix offset value. + +commit ab61e244d1684729263bee7de987aaa612d34328 +Author: K.Ohta +Date: Sun Aug 23 03:24:40 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix screen shift (at sprite layer) of LIBBLE LABBLE. + +commit c1ad560a478708194b72a80ab79b56556e55537d +Author: K.Ohta +Date: Sun Aug 23 03:23:43 2020 +0900 + + [VM][FMTOWNS][CDROM] Revert before commit, and re-implement them. + +commit f77bb68dae8b06568bbb9fa6ba6866b09ef253d1 +Author: K.Ohta +Date: Sat Aug 22 23:10:05 2020 +0900 + + [BUILD][WIN32] Will support Qt5.15. + +commit c416cc6972a18f3207fa9a24c4c5e68c8a28b286 +Author: K.Ohta +Date: Sat Aug 22 23:09:41 2020 +0900 + + [VM][I386_NP21] . + +commit 0a462e58770d975888fcbb579dd3a2eb8d8bf716 +Author: K.Ohta +Date: Sat Aug 22 23:08:09 2020 +0900 + + [VM][FMTOWNS][CDROM] Import some commands from TSUGARU. + + [VM][FMTOWNS][CDROM][DEBUG] Display PC register of CPU when enterring a command.Will remove. + +commit b4be827a31d7cb2edcc5692a6316147b6a9ea8e1 +Author: K.Ohta +Date: Mon Aug 17 18:32:22 2020 +0900 + + [VM][FMTOWNS][CDROM] Make penalty shorter at SEEK.Add more debug messages. + +commit a92653dcf445a9a15a7c07485e144762f7420166 +Author: K.Ohta +Date: Thu Aug 13 16:47:24 2020 +0900 + + [VM][FMTOWNS][CRTC] . + +commit 66aba30c0ef2b0e0e03fff581a4b500da829abdf +Author: K.Ohta +Date: Thu Aug 13 04:27:27 2020 +0900 + + [VM][FMTOWNS][SPRITE] . + +commit 8e46307df319148d9e87bbf2865760e94b0a12d9 +Author: K.Ohta +Date: Wed Aug 12 19:36:50 2020 +0900 + + [VM][FMTOWNS][SPRITE] Move beginning timing to BEFORE FRAME from per vert line. + +commit ad5fca40007a3eae2ce4b92d389afdb35940a02f +Author: K.Ohta +Date: Wed Aug 12 19:36:23 2020 +0900 + + [VM][FMTOWNS][CRTC] . + +commit a48eece128b329e2ad8dc2cee48e842c594029d1 +Author: K.Ohta +Date: Wed Aug 12 19:35:07 2020 +0900 + + [Qt][Draw][GL4_5] Wait until complete to mapping.Fix crash with QUAZZLE (FMTOWNS;FSW Collection 10). + +commit 35f08bfd8d17e91e5f450227a9f5cd3d99e03476 +Author: K.Ohta +Date: Wed Aug 12 19:34:35 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix too long seek time. + +commit 962ee96fc25db901a3d448fceb36715f6c954090 +Author: K.Ohta +Date: Wed Aug 12 17:28:50 2020 +0900 + + [VM][FMTOWNS][SPRITE] Use more SIMD to render_sprite(). + +commit 6af9d667e7501dffb1ce9458ef7d7d87ff9793d6 +Author: K.Ohta +Date: Wed Aug 12 05:50:26 2020 +0900 + + [VM][FMTOWNS][SPRITE] Improve SIMD using. + +commit bc7c391a0bb21e6c93eb8f2903df0c07b93c5f8c +Author: K.Ohta +Date: Wed Aug 12 04:18:27 2020 +0900 + + [VM][FMTOWNS][CRTC] More simple logic at rendering. + + [VM][FMTOWNS][CRTC] Fix Typo. + +commit 3cf6cbdb0fbb6ca544a11e5e9d3d44bd1ae3e2fa +Author: K.Ohta +Date: Wed Aug 12 04:17:37 2020 +0900 + + [VM][FMTOWNS][VRAM] Faster write access via write_memory_mapped_io[16|32]() . + +commit f0be5185da9465de511f6ca0732872b423352827 +Author: K.Ohta +Date: Mon Aug 10 22:33:41 2020 +0900 + + [VM][FMTOWNS][CDROM][WIP] Adjust timing. + +commit a7b60216d1f96702d62d78f74b6163a38654ba13 +Author: K.Ohta +Date: Mon Aug 10 22:33:27 2020 +0900 + + [VM][FMTOWNS] Add IC CARD feature. + +commit 94a2c7a3a8c942ec89adaf78738a36638274452b +Author: K.Ohta +Date: Mon Aug 10 14:10:59 2020 +0900 + + [VM][FMTOWNS][VRAM][SPRITE] Fix crash on VIEW POINT's demonstration. + +commit c1a4bae2bee7b9b1844edeffaf0e7281fc673e3d +Author: K.Ohta +Date: Sun Aug 9 22:06:30 2020 +0900 + + [VM][FMTOWNS][SPRITE] More correctness emulation. + +commit 4ad38e9f7fd063ad396c970a14c8384f7ce781a9 +Author: K.Ohta +Date: Sun Aug 9 20:41:10 2020 +0900 + + [VM][FMTOWNS][SPRITE] Initially works.Some features still not work. + +commit a24c5c5564aa70362c0aa0187815d7442904ee7f +Author: K.Ohta +Date: Sun Aug 9 17:45:58 2020 +0900 + + [VM][FMTOWNS][SPRITE] Partly avaiable to display of sprite.This still be weird. + +commit 8fcdb52c329574b2bdf6fb10c2347de8439f4840 +Author: K.Ohta +Date: Sat Aug 8 20:05:31 2020 +0900 + + [VM][PC9801][DISPLAY] . + +commit 01971c9816f9a3110ce54078769ce7bd65f8854c +Author: K.Ohta +Date: Sat Aug 8 20:04:38 2020 +0900 + + [VM][UPD7220] Limit address of PSET.More correctness clock feature. + +commit a094a25624347959d37b69de41ed32f570010a07 +Author: K.Ohta +Date: Sat Aug 8 06:32:41 2020 +0900 + + [BUILD][CMAKE] . + +commit 49c084964e434561d765c12ac77f149e5f1ebb3c +Author: K.Ohta +Date: Fri Aug 7 21:19:21 2020 +0900 + + [BUILD][Qt][SMC777] Fix FTBFS. + +commit c47e8889de5c15d326ec7415eb5ff17427e20e81 +Author: K.Ohta +Date: Fri Aug 7 16:35:29 2020 +0900 + + [UI][Qt][I18N] Update definition files. + +commit 0410678754c5436e6d4014b9ed082b431271c401 +Author: K.Ohta +Date: Fri Aug 7 04:44:26 2020 +0900 + + [VM][FMTOWNS][MEMORY] Faster mapping. + +commit 175f40cb566049f5d95b5bac1bd1418de648ec11 +Author: K.Ohta +Date: Fri Aug 7 04:44:05 2020 +0900 + + [UI][Qt][FMTOWNS] Fix FTBFS. + +commit 58e0b5403e00b81569e46281b77a278dcb3e7e48 +Author: K.Ohta +Date: Fri Aug 7 04:41:05 2020 +0900 + + [UI][Qt][I18N] Prepare to support multiple languages. + +commit 0fc2ef8d6a63eb8a37579664dc8b15d13dcbcffa +Author: K.Ohta +Date: Fri Jul 17 21:03:59 2020 +0900 + + [VM][FMTOWNS] Set I/O wait value to 6 (maybe faster). + +commit 3dd9b590619598beae9b4036d69fe0f698fe8dd6 +Author: K.Ohta +Date: Fri Jul 17 20:42:38 2020 +0900 + + [VM][Z80] Remove Z80_BASE::, integrate to Z80:: . + +commit 1a377d33f20db2dd22e22f3896ec963838df10a4 +Author: K.Ohta +Date: Fri Jul 17 20:40:10 2020 +0900 + + [VM][X1][DRAW] Fix spending a lot of host CPU usage on draw_screen().This issue has happened at only X1 (not turbo). + + [VM][X1][DRAW] Set alignment of RAM and some values. + +commit ee05d5ee963df0cdbb3a99bc570f6c40b5ca9fa4 +Author: K.Ohta +Date: Fri Jul 17 03:38:32 2020 +0900 + + [VM][MC6809] Remove MC6809_BASE::, integrated to MC6809:: . + +commit f8061ccc49ccbdc71704d3107e1f8152abde0027 +Author: K.Ohta +Date: Fri Jul 17 01:43:27 2020 +0900 + + [VM][COMMON_VM] Fix warining of 'set_context_intr' hides overloaded virtual function [-Woverloaded-virtual] with LLVM Clang++. + +commit 877410416383fc9dd33797388fc8c82ec96afef0 +Author: K.Ohta +Date: Fri Jul 17 00:38:03 2020 +0900 + + [VM][I386_NP21] Memory access:Make functions inline to be faster processing. + +commit 95d2c7369f1000ef5f4b3205cd0d2264cd676833 +Author: K.Ohta +Date: Sat Jun 27 20:13:29 2020 +0900 + + [Qt][LOGGER] Fix not initialize (internal)osd_pointer;wish to fix below issue (@Fedora Linux) https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/935 by this + +commit a279924c92ceb9c3cf3cb953fdc6fb5d5d6e3d3b +Author: K.Ohta +Date: Sat Jun 27 15:14:50 2020 +0900 + + [RELEASE] Update installer. + +commit 8d83dff29e90115cc459d8ca27a36e174097c018 +Author: K.Ohta +Date: Sat Jun 27 01:55:39 2020 +0900 + + [DOC] RE-Update. + +commit d2322eb3793c06a3056ed10245d49c6a865a79d4 +Author: K.Ohta +Date: Sat Jun 27 01:46:01 2020 +0900 + + [VM][FMTOWNS][SERIALROM] Implement correctness.Thanks to Soji Yamakawa-San. + +commit d1ddd00625f3ac0512ad03f6c2d4c0470dae18d1 +Author: K.Ohta +Date: Sat Jun 27 01:43:14 2020 +0900 + + [VM][FMTOWNS] Re-adjust around interrupt with COMMAND 80h, 81h. + +commit b0deb0dce04b848db2f5c455995affdac5c08078 +Author: K.Ohta +Date: Fri Jun 26 23:48:48 2020 +0900 + + [BUILD][CMAKE] Fix around optimize. + +commit f55e633d01cd2ef1190a3fef54892c39301c85aa +Author: K.Ohta +Date: Fri Jun 26 23:45:22 2020 +0900 + + [VM][FMTOWNS][CDROM] Add comment for CMD 00h (SEEK). + +commit 2253898c1386a393dcd5758168935b344e7e04c7 +Author: K.Ohta +Date: Fri Jun 26 23:38:58 2020 +0900 + + [VM][FMTOWNS][CDROM] Implement CMD 00h (SEEK) correctness.May work Fractal engine. + +commit e691abda53b535f493b2bc7690fa3fa8d20ba5ea +Author: K.Ohta +Date: Fri Jun 26 19:56:13 2020 +0900 + + [GENERAL][DOC] Update documents. + +commit f5a2505cb38b92ae68df12f306ba03eeb5b836cd +Author: K.Ohta +Date: Fri Jun 26 19:05:07 2020 +0900 + + [BUILD][CMake][Linux] Use dwarf4 debug information for GCC/Linux. + +commit 60da9c3eecf6ba6043963a787315a2036b52b326 +Author: K.Ohta +Date: Fri Jun 26 19:04:27 2020 +0900 + + [VM][FMTOWNS] Update 00_status.ja.md. + +commit 92389270f74950a7e1fe57718e1a1cf8ce5f1239 +Author: K.Ohta +Date: Fri Jun 26 18:53:53 2020 +0900 + + [VM][GENERAL][I386_NP21] Merge upstream 2020-04-06. + +commit 44bd5c13116124618ce5945eea932b03d8deca9b +Author: K.Ohta +Date: Fri Jun 26 03:59:42 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 1cd52e60e6e88a9290914d784901362c4e42c855 +Author: K.Ohta +Date: Fri Jun 26 03:26:35 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit a0b1c3cf80fd22ea55f8b00f3a6b9ecfd563b5a9 +Author: K.Ohta +Date: Fri Jun 26 02:11:52 2020 +0900 + + [VM][FMTOWNS][CDROM] Adjust CD-ROM transfer timing.May Fractal engine works (launched from TownsOS 2.1). + +commit 3b10794a507816a4b2fe443b1368cf5e711d598e +Author: K.Ohta +Date: Fri Jun 26 00:24:45 2020 +0900 + + [VM][FMTOWNS][CRTC] . + +commit fc8cbf40f5cef3c6369e75cf4e67375dfbdf734c +Author: K.Ohta +Date: Thu Jun 25 22:57:06 2020 +0900 + + [VM][FMTOWNS][VRAM] Expect to write access more faster. + +commit 9a687bbc26ad20fad3f28cf2cfc37061b1b2c9d9 +Author: K.Ohta +Date: Thu Jun 25 22:56:16 2020 +0900 + + [VM][FMTOWNS][PLANEVRAM] Fix read access algorythm. + +commit 69b39b360df411d1d948b487f6422b020f90b6ed +Author: K.Ohta +Date: Thu Jun 25 20:53:33 2020 +0900 + + [VM][FMTOWNS][CDROM] Adjust around seek command. + +commit 5eaf8d54017aa44279c2f6d44e270baeccdd4155 +Author: K.Ohta +Date: Thu Jun 25 19:50:57 2020 +0900 + + [VM][FMTOWNS][MEMORY] Make wait values more correctness. + +commit ae73cbb5e18b8b6b2567fb0ac143ee5afffdb7bd +Author: K.Ohta +Date: Thu Jun 25 19:07:03 2020 +0900 + + [VM][FMTOWNS][CDROM] Revert before commit de6c349b8cc5bebe1c6b6013d991d7a87693de3e. + +commit ca8dfde6e5cd23feda4b9760608f2f8e55e75240 +Author: K.Ohta +Date: Thu Jun 25 18:37:04 2020 +0900 + + [VM][I386_NP21] Add interrupt within rep prefix'ed ops. + +commit 8acae7f9a67d082d402c80664ff311de0830e05b +Author: K.Ohta +Date: Thu Jun 25 18:36:48 2020 +0900 + + [VM][TOWNS_CDROM] . + +commit a2729e58a5562eec8c0c102775d3f580d66eb28f +Author: K.Ohta +Date: Thu Jun 25 03:47:23 2020 +0900 + + [VM][I386_NP21] Add ToDo around interrupt. + +commit 163495dda58781bb7017fcf759e841cdaf78f8ef +Author: K.Ohta +Date: Thu Jun 25 03:15:25 2020 +0900 + + [VM][FMTOWNS][CDROM] Adjust around status code. + +commit de6c349b8cc5bebe1c6b6013d991d7a87693de3e +Author: K.Ohta +Date: Thu Jun 25 01:44:15 2020 +0900 + + [VM][FMTOWNS][CDROM] Around command 00h (SEEK). + +commit 7a4f5cc437d2255b03541ff3fd04ccc3c41321e6 +Author: K.Ohta +Date: Thu Jun 25 00:44:16 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix around I/O port accessing. + +commit ee8ed04f2c5b4831ef3bc71bdefb6443f966838f +Author: K.Ohta +Date: Thu Jun 25 00:43:30 2020 +0900 + + [VM][FMTOWNS][CDROM] Adjust timing. + +commit bdcfcc64f5191ae7853d2c1ae9ea5ba8f728914d +Author: K.Ohta +Date: Thu Jun 25 00:40:37 2020 +0900 + + [VM][UPD71071][FMTOWNS][DMAC] More correctness register handling. + +commit 5350e3a9958e91915bb618c3471e553e5614307a +Author: K.Ohta +Date: Wed Jun 24 18:51:38 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit bb1b182016110cf940993e2dcf2d53062f461071 +Author: K.Ohta +Date: Wed Jun 24 18:39:32 2020 +0900 + + [VM][FMTOWNS][DMAC] . + +commit eab725b27ac0ddfa1fecade1c18db54c54f634bf +Author: K.Ohta +Date: Wed Jun 24 01:45:22 2020 +0900 + + [VM][I386_NP21] Make some functions inline to resolve bottole-neck of memory access. + +commit d2a081a8ee232127148d3f72a11bf147e639b3c7 +Author: K.Ohta +Date: Wed Jun 24 00:30:43 2020 +0900 + + [BUILD][CMAKE][GCC][LINUX] DO LTO even for shared libraries. + +commit 8f59c9f41d82d6ad7d1746c569eb38cf74a36782 +Author: K.Ohta +Date: Tue Jun 23 23:41:03 2020 +0900 + + . + +commit 570b1b974c71ac74acdd909a67e112346c46d3ef +Author: K.Ohta +Date: Tue Jun 23 23:40:03 2020 +0900 + + [BUILD][CMAKE][LINUX][GCC] Adjust around debugging symbols. + +commit a80ec6dca54b1fc446e52b0c5c6ef44c423d7b56 +Author: K.Ohta +Date: Tue Jun 23 01:40:37 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix mixing screen(s). + +commit 7a4a608cad40adc5a66de77f7c9ff68621a57b97 +Author: K.Ohta +Date: Tue Jun 23 01:39:17 2020 +0900 + + [Qt][OpenGL4_5][Draw] Fix crash with external mapping.Still not implement reading buffer. + +commit cbaec231e375b7b06f5aefa835b36c8bfc9faeb2 +Author: K.Ohta +Date: Mon Jun 22 22:16:10 2020 +0900 + + [VM][EMU] For ALL VMs/Devices; use EMU_TEMPLATE:: instead of EMU::. + +commit 0deebac36ec74e65362d78c922434cbfb3ceddc3 +Author: K.Ohta +Date: Mon Jun 22 05:56:54 2020 +0900 + + [VM][EVENT][PC8801][PCENGINE] Fix crash caused by differ event. + +commit 71535609955a626edca5ff8892ff8dd807482e23 +Author: K.Ohta +Date: Mon Jun 22 05:25:58 2020 +0900 + + [VM][EMU][Qt] . + +commit 30cf525af6e5959f83e6ed7df1a1b37bb7c62d44 +Author: K.Ohta +Date: Mon Jun 22 05:05:43 2020 +0900 + + [VM][Qt][UI][EMU][WIP] Use EMU_TEMPLATE:: instead of EMU:: . Some VMs are not apply yet. + +commit 98a4d0f769e2093951d1922031e3ba0190f689a9 +Author: K.Ohta +Date: Mon Jun 22 02:45:52 2020 +0900 + + [EMU][EMU_TEMPLATE][OOPS] (;´Д`) + +commit ffb344c261dc25ecc825b502c91d0eba33b21cde +Author: K.Ohta +Date: Mon Jun 22 02:30:21 2020 +0900 + + [BUILD][LINUX][LLVM] Support for LLVM10. + +commit eb4e113211168f21e38f471f943a7dd76253cddc +Author: K.Ohta +Date: Mon Jun 22 02:29:37 2020 +0900 + + [VM][EMU] Important: now EMU:: class is on EMU_TEMPLATE:: . + +commit a1f091a7181f224f88b1d5d59a1078a17fc9078c +Author: K.Ohta +Date: Mon Jun 22 02:29:07 2020 +0900 + + [VM][FMTOWNS] Simplify around debugger. + +commit 9537b3b05c4c3701792d65246a479ae3c376ffba +Author: K.Ohta +Date: Mon Jun 22 02:28:26 2020 +0900 + + [VM][FMTONWS][DICTIONARY][CMOS] Available to use dictionary ROM. + +commit 72989c17ab0693541a84e0ca3e242eb706e4a814 +Author: K.Ohta +Date: Wed Jun 17 20:26:08 2020 +0900 + + [VM][I386_NP21] Fix FTBFS with (Cross)CLANG 10.0 for MinGW32. + +commit aa71ab8ab4b82df3ac5ed17682551b801fd670e2 +Author: K.Ohta +Date: Wed Jun 17 20:24:51 2020 +0900 + + [BUILD][CMake][Win32] Update toolchain for LLVM10.x and Ubuntu20.04 (Will upload to Dockerhub). + +commit ba8d3df3d55943d8acbe7721dd4691d73c26be32 +Author: K.Ohta +Date: Wed Jun 17 20:23:48 2020 +0900 + + [OSD][Qt][LOGGER] Fix linkage error for LLD 10.x and Win32 cross. + +commit 3ba80381d8eccc47ee4aaa67a9321073d449700a +Author: K.Ohta +Date: Sun Jun 14 06:45:28 2020 +0900 + + [VM][FMTOWNS][CRTC] Faster transferring from VRAM to line buffer. + +commit 9fc24652b4efb6926b4f05ad7531b4d0d0a75a06 +Author: K.Ohta +Date: Sun Jun 14 06:28:12 2020 +0900 + + [VM][FMTOWNS][CRTC] Reduce rendering when zooming. + +commit 8fd30e7dcfdd5066508bc13fd328295d8905d47e +Author: K.Ohta +Date: Sun Jun 14 06:15:33 2020 +0900 + + [VM][DEVICE][I386_NP21] Fix FTBFS with LLVM CLANG++. + +commit b9255438255c8f555206dfa7cfbc632afe83d199 +Author: K.Ohta +Date: Sun Jun 14 06:15:08 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix FTBFS with LLVM CLANG. + +commit ba745868507aaa86d02bb44ce832e157d95ca7fe +Author: K.Ohta +Date: Sun Jun 14 06:14:43 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix crash with TACTICAL AIR WING. + +commit 811a81e3a3df89cd66f4d7b24c081de51cd2763b +Author: K.Ohta +Date: Sat Jun 13 17:50:34 2020 +0900 + + [VM][FMTOWNS][CRTC] Reduce transferring.Support wrapping adddress. + +commit 7367622e7ea3ce5a0e2e0af6f21c59e239ddff75 +Author: K.Ohta +Date: Sat Jun 13 16:33:40 2020 +0900 + + [VM][FMTOWNS][CRTC] More correctness drawing. + +commit 8388c306c1ef20be1712fc1ff356bc23a34e43a4 +Author: K.Ohta +Date: Fri Jun 12 22:34:28 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit dee285246020433262dcb506feb3adc941414023 +Author: K.Ohta +Date: Fri Jun 12 22:33:56 2020 +0900 + + [VM][FMTOWNS][CRTC] More correctness horizonal scrolling. + +commit 306d257ee0c3bffc40e1c438954f8b480dd4e8cd +Author: K.Ohta +Date: Fri Jun 12 20:02:37 2020 +0900 + + [VM][FMTOWNS][MEMORY] . + +commit f5d84f43603176f85e8349f928d3e6048290a163 +Author: K.Ohta +Date: Fri Jun 12 20:02:03 2020 +0900 + + [VM][FMTOWNS][CDROM] Add variable buffer (after Towns2HR) feature. + +commit b0ba3d88f3863fad4634928e20acdfb7b48562dd +Author: K.Ohta +Date: Fri Jun 12 02:44:18 2020 +0900 + + [VM][FMTOWNS][CRTC] . + +commit 58d54702fb0d2a6f4d4c130fcc57695465ce3e65 +Author: K.Ohta +Date: Fri Jun 12 02:43:13 2020 +0900 + + [VM][FMTOWNS][CDROM] Force DMA interrupt even DMA count != 0.May fix for YUMIMI MIX. + +commit 5b61d3bdde9e40514057925fd9f0547b495ceb62 +Author: K.Ohta +Date: Fri Jun 12 01:52:11 2020 +0900 + + [VM][FMTOWNS][TIMER] . + +commit 15413be919312bafd22f8d6bf828dd0987d5bd9e +Author: K.Ohta +Date: Fri Jun 12 01:51:38 2020 +0900 + + [VM][FMTOWNS][SPRITE] More correctness port emulation. + +commit 33891599870c1095b4d68a2a7bb44a9eae2425b0 +Author: K.Ohta +Date: Fri Jun 12 01:50:16 2020 +0900 + + [VM][FMTOWNS][CRTC] Adjust display timing.Fix offset of スーパーリアル麻雀 P IV. + + [VM][FMTOWNS][CRTC] Cleanup unused signals. + +commit 1e410e06f88b2d158af455056760f99b3be1c1e8 +Author: K.Ohta +Date: Mon Jun 1 02:20:30 2020 +0900 + + [VM][FMTOWNS][CDROM] Only DMA TRANSFER PHASE flag (04C0h:R:bit4) down at END-OF-DMA, not another situation (excepts reset manually). + +commit ce50d50f0dab9f6c32986b4cbd36554c1fdb3423 +Author: K.Ohta +Date: Mon Jun 1 02:19:09 2020 +0900 + + [VM][I386_NP21] *Perhaps* REPNE MOVS[B|W|D] don't dedicate Z flag, Thanks to Soji Yamakawa-San. + +commit 3e2b5aae041f84947867709e2e8d6374b3cf46d2 +Author: K.Ohta +Date: Sun May 31 18:10:27 2020 +0900 + + [VM][I386_NP21] Disable FPU with I386, enable with I486SX. + + [VM][I386_NP21] Change FPUemul to DOSBOX2 (temporally). + [VM][I386_NP21] Initialize CR0 to 0x00000000 (+some bits) for i386. + +commit ab5fe3c474e6340483dbd30d3d4066c74969269e +Author: K.Ohta +Date: Sun May 31 18:08:54 2020 +0900 + + [VM][I386_NP21] FPU: FISTTP INSNs (prefix DF) are only later than Pentium 4, not exists I386/486/Pentium. + +commit 529a1354273c481b724de6410de86736fcfd9e97 +Author: K.Ohta +Date: Sun May 31 03:44:54 2020 +0900 + + [VM][FMTOWNS][CRTC] Expect to be faster a bit@32768 colors mode. + +commit 908fbd1f0620fe301f21e53eaba28e2eaf670e46 +Author: K.Ohta +Date: Sun May 31 03:44:01 2020 +0900 + + [VM][FMTOWNS][CDROM] Drive status on accepting, fix hang-up on RANCE3. + +commit 963191b035d0078ff843f5086698a28214dda084 +Author: K.Ohta +Date: Sun May 31 01:39:52 2020 +0900 + + [VM][FMTOWNS][CDROM] TownsOS v.1.1: Enable to through CMD A0,PARAM=08 01.But, still not continue (trapped). + +commit cd857804c93551538be49954df47eabed5b403b3 +Author: K.Ohta +Date: Sat May 30 19:02:43 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit c50c515e6dfcf29f9408122f1da9e1f4b5e5ab1f +Author: K.Ohta +Date: Fri May 29 16:18:38 2020 +0900 + + [EMU][Qt] . + +commit 78ad1a25d2ee9ee346a036359893d5e5e3e63931 +Author: K.Ohta +Date: Fri May 29 16:18:27 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit c4b67362506c9821638cd12ed573d762241ec83e +Author: K.Ohta +Date: Thu May 28 23:20:54 2020 +0900 + + [VM][FMTOWNS][JOYSTICK] Fix FTBFS. + +commit 617327d371da6bd4e5899506a551395657f279e1 +Author: K.Ohta +Date: Thu May 28 23:20:12 2020 +0900 + + [UI][Qt][OpenGL4] Add copy_screen_buffer(), but not usable. + +commit f8dcec3f79dab64e2c18d4e86d35023144a0fc32 +Author: K.Ohta +Date: Thu May 28 23:19:47 2020 +0900 + + [EMU][Qt] Adjust timing for before commit. + +commit 764aaa7579f46c4f836177e48cb28523b3cfdbba +Author: K.Ohta +Date: Thu May 28 20:06:55 2020 +0900 + + [VM][FMTOWNS][JOYSTICK] Sample per 8ms (at emulation, not real). + +commit 34ae92a457461b1bb3794c8cde4e9764dd9d536b +Author: K.Ohta +Date: Thu May 28 20:05:51 2020 +0900 + + [VM][EVENT][Qt] execute event->drive() (or event->run()) by half frame.This is workaround for choppy mouse pointer/joystick. + +commit b2685af227b761bfc930db9b90cf79c8325b3770 +Author: K.Ohta +Date: Thu May 28 18:29:18 2020 +0900 + + [VM][FMTOWNS][RF5C68] Improve save/load. + +commit b186d2e91167948e185d9cf102b0f81dae3d10cc +Author: K.Ohta +Date: Thu May 28 18:07:56 2020 +0900 + + [VM][FMTOWNS][RF5C68] Add 3 tap low pass filter. + +commit 119acac57857bdc0ca4132a7cd5d7ceea4cd765d +Author: K.Ohta +Date: Thu May 28 09:15:30 2020 +0900 + + [VM][FMTOWNS][RF5C68] Add interpollation LPF. + +commit 0a0d6edef59fac2ffd8df50f09a58ccbe01fab35 +Author: K.Ohta +Date: Thu May 28 06:19:46 2020 +0900 + + [VM][FMTOWNS][VRAM] Faster a bit. + +commit 5f088510ad76064bbae10d97e72696589d6c5c80 +Author: K.Ohta +Date: Thu May 28 05:30:51 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit a22f6d6f9ee26e6e8006d33bf2b8b05f1c4fb5cb +Author: K.Ohta +Date: Thu May 28 05:16:53 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 8d760a6d3a78f9b7f060a4cc997dfb0bc987ed00 +Author: K.Ohta +Date: Thu May 28 04:58:08 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix around looping, sector count. + +commit 535e5052a30761c0b42531b1448501b1163f86d8 +Author: K.Ohta +Date: Thu May 28 04:00:28 2020 +0900 + + [VM][FMTOWNS][TIMER] Add 16bit read/write freerun counter and interval timer. + +commit 1859c6a82837824a737631187504a16f468385f0 +Author: K.Ohta +Date: Thu May 28 04:00:01 2020 +0900 + + [VM][FMTOWNS][MEMORY] More correctness reset sequence. + +commit eb97b9a6c37dc8a9e78a411592780dfacc59ed7c +Author: K.Ohta +Date: Thu May 28 03:59:36 2020 +0900 + + [VM][FMTOWNS][CDROM] Re-Enable MODE1/2048 etc. + +commit cb7a18dcbc29726378de4ad5979b171bcdbc7029 +Author: K.Ohta +Date: Thu May 28 02:11:15 2020 +0900 + + [VM][FMTOWNS][CDROM] Revert CD-ROM's commits after 66532afe71120b85a93b835f5a2541c406ff7699. + +commit c203da90777dea03ffbd906503e409d1b43cbee8 +Author: K.Ohta +Date: Thu May 28 02:05:34 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 78411b296de059fb8b3f6e61fd08b81095759311 +Author: K.Ohta +Date: Wed May 27 23:38:21 2020 +0900 + + [VM][FMTOWNS] Update some registers. + +commit d07c9e9b6854ae91258d51aca5f6f281d1dcfc58 +Author: K.Ohta +Date: Wed May 27 23:38:06 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 05b33b663e2c4e90f0d0dbe9d558fe67d7e0307a +Author: K.Ohta +Date: Wed May 27 19:50:32 2020 +0900 + + [VM][I386_NP21][DEBUGGER] Add call trace feature. + +commit 704d3639f466166a36ff2f1cedae71903c4ed983 +Author: K.Ohta +Date: Wed May 27 19:49:56 2020 +0900 + + [VM][FMTOWNS][CDROM] Remove has_status, check status queue directly. + +commit c0b160ebf762aef24464b14e0946ea611e1a6e7c +Author: K.Ohta +Date: Wed May 27 03:36:49 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 900c4869b03e57ed14023fecd3867f3015978afe +Author: K.Ohta +Date: Wed May 27 03:35:34 2020 +0900 + + [VM][I386_NP21] Add undefined instruction "0F A6".This may act as "int 6".Thanks to captainys. + +commit 66532afe71120b85a93b835f5a2541c406ff7699 +Author: K.Ohta +Date: Sat May 23 13:47:51 2020 +0900 + + [OOPs][Qt][GUI] I forgot to add a new dialog X-) + +commit dec494e487135e47b4167327d7ca6733e61321ee +Author: K.Ohta +Date: Sat May 23 04:52:42 2020 +0900 + + [VM][FMTOWNS][SPRITE] . + +commit 5549094ae30db73c927abe9466aa644880a04566 +Author: K.Ohta +Date: Sat May 23 03:58:14 2020 +0900 + + [VM][FMTOWNS][SPRITE] Start to adjust sprite. + +commit 97c73994cd37bfb33099fff212aaf03764752113 +Author: K.Ohta +Date: Sat May 23 03:57:42 2020 +0900 + + [VM][FMTOWNS][RF5C68] Buffered ADPCM.Will implement low pass filter. + +commit d41072a26aa0e2b1e139ee8e90cfb2963e068d88 +Author: K.Ohta +Date: Fri May 22 19:36:32 2020 +0900 + + [VM][UI][FMTOWNS] Add variable memory size feature. + +commit 8e8015f64511fb0a0fb287097c4efc1426c5a7fd +Author: K.Ohta +Date: Fri May 22 19:20:35 2020 +0900 + + [UI][Qt][CDROM] Add "SWAP BYTE ORDER for AUDIO" config entry. + +commit 3437d9d6ef91540ef314a80cceceacfdd8d6f94d +Author: K.Ohta +Date: Fri May 22 16:54:55 2020 +0900 + + [DOC][FMTOWNS] Update status. + +commit e08e8fccbc01b9df864cb9eaa2308f4dc75769db +Author: K.Ohta +Date: Fri May 22 15:50:07 2020 +0900 + + [VM][FMTOWNS][CDROM] Simplify interrut by MCU. + +commit e21a011566166268f2bfdab1fea5148b94557858 +Author: K.Ohta +Date: Fri May 22 15:48:27 2020 +0900 + + [VM][FMTOWNS][SCSI] Re-enable machine check feature. + +commit e9227e89ab4ba989d71afde0e4d5b5e1f9e7df1d +Author: K.Ohta +Date: Fri May 22 15:48:16 2020 +0900 + + [VM][FMTOWNS][DOC] . + +commit f2fa3d5068288173ba87679b0f7900438b3b7897 +Author: K.Ohta +Date: Fri May 22 14:02:40 2020 +0900 + + [DOC][TOWNS] Update status. + +commit 7031b5f12cbd08f7bed77847c5e46986249a3e39 +Author: K.Ohta +Date: Thu May 21 22:34:15 2020 +0900 + + [VM][FMTOWNS] Upodate status. + +commit 9cefa8ea967b36f32c6bafda1642338e9d9c7922 +Author: K.Ohta +Date: Thu May 21 22:33:47 2020 +0900 + + [Qt][OSD][MOUSE] Lock values via accessing. + +commit 43625e99ba57e2f32cdb52d68f44c5fdd7632f6b +Author: K.Ohta +Date: Thu May 21 22:33:16 2020 +0900 + + [VM][UPD71071] Adjust status of on-demand-mode. + +commit e3d4d8b58f82fe2ec3da40f3d99d13c6f6f02baf +Author: K.Ohta +Date: Thu May 21 16:47:06 2020 +0900 + + [VM][FMTOWNS][SCSI][DMAC] Temporally disable 16bit transfer mode for SCSI. + +commit 507c2280edf7d809e0d605c841bc686306706e60 +Author: K.Ohta +Date: Wed May 20 03:37:53 2020 +0900 + + [VM][FMTOWNS][JOYSTICK] Move mouse polling to event_frame(). + +commit 8fc4117c5edc51449f69ec0b0bbe0c3665931931 +Author: K.Ohta +Date: Wed May 20 03:36:35 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit e0110b6c43897654d1a33060f91b1c9067be862a +Author: K.Ohta +Date: Tue May 19 15:11:22 2020 +0900 + + [VM][FMTOWNS][CDROM] Adjust interrupt timing. + +commit 7f88f255f553fe0b72384b213200c6b655bd410a +Author: K.Ohta +Date: Tue May 19 03:42:25 2020 +0900 + + [VM][Z80TVGAME] Fix FTBFS. + +commit 7e788f9844b923c06882b8256232d68038c413cb +Author: K.Ohta +Date: Tue May 19 01:07:49 2020 +0900 + + [VM][LOGGER][OSD][VM_TEMPLATE] Add API to log with VM's time. + +commit 4c6ba797b3dedca3ae633ad551298a3470d867b3 +Author: K.Ohta +Date: Sun May 17 13:26:07 2020 +0900 + + [VM][FMTOWNS][CDROM] Determine prefetching or not. + +commit 72a00ec46e533352b057d824f35ce860bde47ee4 +Author: K.Ohta +Date: Sun May 17 13:25:57 2020 +0900 + + [COMMON][FIFO] . + +commit c4edcc5c7a0f2eeac51cea6235aae75f24d710c4 +Author: K.Ohta +Date: Sun May 17 13:25:14 2020 +0900 + + [COMMON][FIFO] Add FIFO::fifo_size() and FIFO::left().Update SOVERSION. + +commit c2e7b1101e4edf1fe498be20e1591e1bef6ad027 +Author: K.Ohta +Date: Sun May 17 06:43:51 2020 +0900 + + [VM][FMTOWNS][ADPCM][RF5C68][CDROM] . + +commit ed366f7a825043a9159103d53945d3eb95b29c44 +Author: K.Ohta +Date: Sun May 17 04:33:56 2020 +0900 + + [VM][FMTOWNS][CRTC] Avaiable to display 256 colors. + + [VM][FMTOWNS][VRAM] . + +commit 781ccb984c31e7e0e32970b9d738417d1c1eef41 +Author: K.Ohta +Date: Sun May 17 01:53:40 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix forcing to calcurate CRTC clock per setting. + +commit 036d129cd0996949c4414f86d326c004ee34d7fa +Author: K.Ohta +Date: Sun May 17 00:50:46 2020 +0900 + + [VM][FMTOWNS][VRAM] Separate plane access to a class (PLAVEVRAM::) to be faster.. + +commit 0f22864abffca195d3eef9e6369fbaaeba1fa541 +Author: K.Ohta +Date: Sun May 17 00:49:59 2020 +0900 + + [VM][FMTOWNS][CRTC] Reduce flickering (a lot). + +commit 942c8fa714e3fb80aeb0c97d70445c6ffebf0408 +Author: K.Ohta +Date: Sat May 16 21:47:59 2020 +0900 + + [VM][FMTOWNS][CDROM] Add MODE2/2336 and RAW/2340 read modes. + +commit aff40d33092cb0bc6a631c9e859f81cea7f3dc25 +Author: K.Ohta +Date: Sat May 16 17:40:50 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 206cc537bb1194b9db64464f3b42e15c5f93780d +Author: K.Ohta +Date: Sat May 16 15:25:10 2020 +0900 + + [VM][FMTOWNS][CDROM] Add debugging features. + +commit bcdac3a67ece3dd648bf92f8aaf49835d301f033 +Author: K.Ohta +Date: Tue May 12 02:15:55 2020 +0900 + + [VM][FMTOWNS][CDROM] TRY: Start to implement PIO transfer mode. + +commit 3dc41b2bb2316a5d30a789dea6d8341c80246478 +Author: K.Ohta +Date: Tue May 12 01:29:11 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 7e0926841011ddd017aa8ab81c58ede2c3615c8d +Author: K.Ohta +Date: Tue May 12 01:20:15 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix fault (fall to CS:4DD4h) when reading CD-ROM with TownsOS v1.1.But, still not works. + +commit eaa6c4acdd9c966e7313ce721e7d762991188890 +Author: K.Ohta +Date: Mon May 11 23:37:01 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix interrupt handling. + +commit 7076c9644d8adc57a8c0f6a2b0dd875e90f07d25 +Author: K.Ohta +Date: Mon May 11 23:11:07 2020 +0900 + + [VM][FMTOWNS][RF5C68] Adjust audio volume. + +commit 970cff9044acd38cdbd32d9fad4d3c00e27a6e3c +Author: K.Ohta +Date: Mon May 11 22:56:47 2020 +0900 + + [VM][FMTOWNS][CDROM] Add clear_event(). + +commit 5ff69aaa03f64508df60bc6fe67f95e912f8fbe1 +Author: K.Ohta +Date: Mon May 11 21:13:46 2020 +0900 + + [VM][FMTOWNS][DMAC] Disable debugging messsage. + +commit 364e39e8e3014c1e92c5869aef1d7f808e94bebd +Author: K.Ohta +Date: Mon May 11 21:13:23 2020 +0900 + + [VM][DEBUGGER] Add logging to "UCT" command. + +commit 752a0292e4760fee9b9d25d600f70b416b39d5f1 +Author: K.Ohta +Date: Mon May 11 21:12:24 2020 +0900 + + [VM][FMTOWNS][DICTIONARY] Write CMOS RAM when resetting. + +commit 5d88c4ee5ded9095f78001fdf9d4959814b163d4 +Author: K.Ohta +Date: Mon May 11 21:11:41 2020 +0900 + + [VM][TOWNS][CDROM] Re-loading fine from TownsOS v2.1.v1.x still not loading. + +commit c129dc55b00ffe4d8f356cf4d7b7c0118a7d8c68 +Author: K.Ohta +Date: Mon May 11 19:34:18 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 53c5422ce15cda3a9784c95727c865898dac17cc +Author: K.Ohta +Date: Mon May 11 02:28:56 2020 +0900 + + [VM][I386_NP21] Log when made panic. + +commit f6f1069261c7d86578bb118501d22f36a85155dd +Author: K.Ohta +Date: Mon May 11 01:41:48 2020 +0900 + + [VM][GENERAL][CMAKE] Update major SOVERSION. + +commit e078eefdf16546fd5eb83af7883229c2816a20bf +Author: K.Ohta +Date: Mon May 11 01:41:12 2020 +0900 + + [VM][FMTOWNS][CDROM][WIP] Adjusting CDROM seek timing. + +commit 04a3fbdd2eb97988202ed75432444321b7c281c2 +Author: K.Ohta +Date: Mon May 11 01:40:42 2020 +0900 + + [VM][FMTOWNS][SPRITE] More safer VRAM access. + +commit 4cf73dcca06fdb57657f5f5f9da58ac653c95863 +Author: K.Ohta +Date: Mon May 11 01:40:14 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix OVERKILL alignment. + +commit a91f8e19a2264cbc1b70236f1c970b6721082e5f +Author: K.Ohta +Date: Sun May 10 20:43:05 2020 +0900 + + [VM][FMTONWS][SPRITE] . + +commit a38c6f5367a225ba61919227da493bc801fc7719 +Author: K.Ohta +Date: Sun May 10 18:01:52 2020 +0900 + + [VM][DEVICE][DEBUGGER][I386_NP21] Add Call trace feature.DEVICE::'s API HAS CHANGED. + +commit a17a03d02d8105146dbab29383a22a6cc5638f44 +Author: K.Ohta +Date: Sat May 9 23:05:46 2020 +0900 + + [VM][FMTOWNS][RF5C68] . + +commit 7ba44010f5d577bf16bbe5cd766c321557027482 +Author: K.Ohta +Date: Sat May 9 22:01:06 2020 +0900 + + [VM][RF5C68] . + +commit 33ec39c9da3567446b295832cb6e59adfe357c75 +Author: K.Ohta +Date: Sat May 9 21:06:09 2020 +0900 + + [VM][FMTOWNS][TIMER] Add SIG_TIMER_CH3 for BEEP handling. + + [VM][FMTOWNS][CRTC] Fix crash with debugging-DUMP command. + +commit cba19bdf78e5054691456b8a9d52619f68cc181f +Author: K.Ohta +Date: Sat May 9 21:05:36 2020 +0900 + + [VM][FMTOWNS][OPN2][ADPCM] Fix interrupt handling. + +commit 09bc3dbca02c8a57180adc8085a056c471a99fe1 +Author: K.Ohta +Date: Sat May 9 21:04:37 2020 +0900 + + [FMGEN][YM2612][VM][FMTOWNS] Fix prescaler value, calculating for own OPN2. + +commit a7d41ef64b1a82ad068596fd8edbff47d72c3381 +Author: K.Ohta +Date: Sat May 9 21:03:57 2020 +0900 + + [VM][I8253] Add debugger feature, still reading only. + +commit cdc8fb61001196b8985319eb85d51a8af6d98e50 +Author: K.Ohta +Date: Sat May 9 18:58:44 2020 +0900 + + [VM][FMTOWNS] . + +commit dc87ec4c25981aefe992680ef3bd876aacb73fa4 +Author: K.Ohta +Date: Sat May 9 18:06:06 2020 +0900 + + [VM][FMTOWNS][CDROM] CD-DA: Implement prefetch feature. + +commit 0d3ad78ac58a01dbde9c90d94c3e0c665d84134f +Author: K.Ohta +Date: Sat May 9 16:29:08 2020 +0900 + + [VM][FMTOWNS][DOC] . + +commit 1217a2481f3762a81171a1d036bf953090594d94 +Author: K.Ohta +Date: Sat May 9 16:27:13 2020 +0900 + + [VM][FMTOWNS][CDROM] TRY: Integrate both CD-DA and CD-DATA. + +commit ca05466a5f4f2ca5d035cb5550c35612a5297ee3 +Author: K.Ohta +Date: Fri May 8 22:30:13 2020 +0900 + + [VM][FMTOWNS][DOC] Update STATUS. + +commit 5a1be81d76f8ebca71547387759a8d462e7e18ef +Author: K.Ohta +Date: Fri May 8 22:14:26 2020 +0900 + + [VM][FMTOWNS][DOC] . + +commit eeb73e42a17ca42d9292a9b1d1a9804afd80b0fc +Author: K.Ohta +Date: Fri May 8 22:11:11 2020 +0900 + + [VM][FMTOWNS] Add implement status document,written in only Japanese, sorry. + +commit 73c5f12c38b98db7c906d753ca6a42cd93cedd86 +Author: K.Ohta +Date: Fri May 8 22:09:13 2020 +0900 + + [VM][FMTOWNS][CRTC] Comment out unused debugging message. + +commit cb74e334a23b4cea80fcb129ff956c13a43886d7 +Author: K.Ohta +Date: Fri May 8 22:08:41 2020 +0900 + + [VM][FMTOWNS][RF5C68][ADPCM] Sounds via RF5C68 works. + +commit a60701579cbcff9cbbab7cbc8c6479dae45fbed2 +Author: K.Ohta +Date: Fri May 8 02:39:21 2020 +0900 + + [VM][FMTOWNS][CDROM][OOPS] Fix em-bugged around READ1/2352. + +commit 8421b20d1d84b9b5051a35ef9b77b1e9cef6b945 +Author: K.Ohta +Date: Fri May 8 02:17:39 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix around CDDA repeating and TOC table. + +commit 4403fd56e0f9fc8a5f2519101ad9f2fafd022a14 +Author: K.Ohta +Date: Fri May 8 00:52:36 2020 +0900 + + [VM][FMTOWNS][CDROM] CD-DA works mostly. + +commit e8c5a9aaae7240960569facad3a8503613272bd3 +Author: K.Ohta +Date: Thu May 7 21:37:51 2020 +0900 + + [VM][FMTOWNS][CDROM] More correctness cue handling. + +commit d436bd158956d93235ffce0d52110475a0f950cd +Author: K.Ohta +Date: Thu May 7 20:49:50 2020 +0900 + + [VM][FMTOWNS][CDROM] Before commit is something wrong, revert excepts around READ TOC. + +commit cef9cbe8c0849d5b8fe431d6c0f1b9d44bb4255b +Author: K.Ohta +Date: Thu May 7 20:15:59 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix tok. + +commit 162496944304deb4d1f727fd75e05306b3a4cf2d +Author: K.Ohta +Date: Thu May 7 05:07:25 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 708607b4d951ae608932b4777b3b2261c9e10ce0 +Author: K.Ohta +Date: Thu May 7 04:20:03 2020 +0900 + + [VM][FMTOWNS][CDROM] More correctness CDIO.Implement disc changed feature. + +commit d4326378032cb3b68a92d4c8ef6a4f45719828b8 +Author: K.Ohta +Date: Wed May 6 06:05:22 2020 +0900 + + [VM][FMTOWNS][MEMORY] Add memory wait hidden register (05E0h/05E2h).AB.COM may work at i386 VMs. + +commit d6b47b69d0d4f4a9f34327375167288d97756701 +Author: K.Ohta +Date: Wed May 6 04:45:31 2020 +0900 + + [VM][FMTOWNS] Re-Disable _SCSI_DEBUG_LOG. + +commit c1203d01a12ab266957a01072f41a21354834cb1 +Author: K.Ohta +Date: Wed May 6 04:44:57 2020 +0900 + + [VM][FMTONWS][MEMORY][VRAM] Make some R/W functions __inline__. + +commit e2accfa8881ce456b9657013931b1e60a6b86620 +Author: K.Ohta +Date: Wed May 6 04:44:32 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix overkill initializing. + +commit de256c2eb82e97b4411c96a9a6ab9fe476cb358c +Author: K.Ohta +Date: Wed May 6 04:43:29 2020 +0900 + + [VM][I386_NP21] Optimise for speed, make some functions __inline__ . + + [VM][I386_NP21][DEBUGGER][WIP] Adding exception handling. + +commit 39de7f0fe28e2761f0ff1afc0bc93d0d1864acef +Author: K.Ohta +Date: Wed May 6 01:07:20 2020 +0900 + + [UI][Qt][OSD] Add tooltip for virtual medias. + +commit c7c9ae620187f99c897a8fd4445edf29469f4f11 +Author: K.Ohta +Date: Wed May 6 01:06:45 2020 +0900 + + [VM][FM8] Fix warning from EVENT:: when resetting. + +commit 53f51aaa71c648c4984b36622925af0aa922ffa5 +Author: K.Ohta +Date: Tue May 5 12:51:00 2020 +0900 + + [UI][Qt] Add filename feature to Virtual-Media indicator.Adjust width for HDD. + +commit f215e75a3e1d150a231f7cc6a1d0962f47c72a21 +Author: K.Ohta +Date: Tue May 5 12:06:04 2020 +0900 + + [UI][Qt] Virtual media: Adjust width of "HDx:". + +commit 34b8032eaaf5d16de2dc68a0b28f7aebe41ad24b +Author: K.Ohta +Date: Mon May 4 17:02:48 2020 +0900 + + [VM][FMTOWNS][MEMORY] Add I/O 05edh, improve registers around clock and wait. + +commit 28059ba3f035f06a2aaca831a4f172fbbc189a2e +Author: K.Ohta +Date: Mon May 4 17:02:20 2020 +0900 + + [OSD][Qt][MOUSE] Remove mouse position limiter. + +commit da92a8eb75b863883fb184958e3c0d975b1796b0 +Author: K.Ohta +Date: Mon May 4 15:59:55 2020 +0900 + + [VM][FMTOWNS] Extend extra RAMs. + +commit 1f5a59167dbd475c65563c36c6be4440a6e9cd30 +Author: K.Ohta +Date: Mon May 4 15:31:19 2020 +0900 + + [VM][SCSI_DEV] Some commands needs longer wait (i.e. READ_CAPAC) for some VMs. + +commit 59a758f8864de418926c3084ca1dc35b938dc66b +Author: K.Ohta +Date: Mon May 4 03:56:30 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix interrupt handling. + + [VM][FMTOWNS][CRTC] Replace cancelling event by a function. + +commit 87618d7cf9d4b4925b1f0054e723992fafdbd42e +Author: K.Ohta +Date: Mon May 4 03:55:35 2020 +0900 + + [VM][FMTOWNS][RF5C68] Adjust handling around PCM. + +commit ba19b8b9b9d3de52a08dcecdc8868d79993abbf5 +Author: K.Ohta +Date: Mon May 4 03:55:03 2020 +0900 + + [VM][FMTOWNS][MOUSE] Fix mouse not working with TownsOS v2.x. + +commit fbaeab20b521f67b8cdc42b81ac12129a51b5a62 +Author: K.Ohta +Date: Sun May 3 03:31:46 2020 +0900 + + [VM][FMTOWNS][CDROM] More correctness track parsing. + +commit 140fd489914db1f64c521335c2e9900288e39882 +Author: K.Ohta +Date: Sun May 3 01:37:48 2020 +0900 + + [VM][FMTOWNS][CDROM] CUE FILE: Use std::map instead of string compare. + +commit 60b084caed51cd8d347e4d881ab966e8b59df04d +Author: K.Ohta +Date: Sun May 3 00:36:50 2020 +0900 + + [VM][FMTOWNS] Fix porality of IO:FF99h.Adjust I/O address. + +commit 6d3350e47f484a811585b5422de98549762a2475 +Author: K.Ohta +Date: Sat May 2 02:57:40 2020 +0900 + + [VM][FMTOWNS][KEYBOARD] Event driven keyboard.Now enable to keyin with Towns-Linux. + +commit 246842689e8bb2d6d1bffd4ad33b79ab04e064f6 +Author: K.Ohta +Date: Sat May 2 02:12:44 2020 +0900 + + [VM][I386_NP21] Fix EDX value at resetting. + + [VM][I386_NP21] Temporally enable FPU for i386. + +commit f5b24a67d1a6a8fe846b46fe9ca095dc202e9b37 +Author: K.Ohta +Date: Sat May 2 02:12:22 2020 +0900 + + [VM][FMTOWNS][VRAM] Remove test-pattern. + +commit 226f6ff0e4bc768545c5723fa54ec60efd15748b +Author: K.Ohta +Date: Sat May 2 02:11:55 2020 +0900 + + [VM][FMTOWNS][BUILD] Build without SCSI_DEBUG_LOG. + +commit c6026f463123aae56daa5e31660b3be0c0e626ae +Author: K.Ohta +Date: Sat May 2 02:11:24 2020 +0900 + + [VM][FMTOWNS][MOUSE] Fix wrong port out for 04D6h for MOUSE. + +commit 537e543e221d2292ecf7f63214f24dcbb7cbd2eb +Author: K.Ohta +Date: Sat May 2 02:10:35 2020 +0900 + + [VM][TOWNS_DMAC][i8259] Comment out unneeded debugging-logging entries. + +commit c7fe9f7008cf10ba1947729336124722dc238b78 +Author: K.Ohta +Date: Sat May 2 02:09:43 2020 +0900 + + [VM][FMTOWNS][KEYBOARD] Fix wrong VK - scancode table.Update scancode list. + +commit 62cc735ea1b1cbfce7be609bc39c06acca543ddf +Author: K.Ohta +Date: Thu Apr 30 02:24:07 2020 +0900 + + [VM][FMTOWNS][CDROM] At last, enable to boot TownsOS 2.1 from CD-ROM,but something wrong. + +commit 28817ef5f374525de26d35467de56245a5c485e0 +Author: K.Ohta +Date: Wed Apr 29 22:10:13 2020 +0900 + + [VM][UPD71071][TOWNS_DMAC] Improve displaying of DEBUG REGs. + +commit eddaf7935147e05241ef31826f2926fc121dafc7 +Author: K.Ohta +Date: Wed Apr 29 01:24:14 2020 +0900 + + [VM][UPD71071][TOWNS_DMAC] Fix mandatory name with "mask" variable/arg. + +commit 4b4ae3b363884330795ec59bc07eb99b611424bc +Author: K.Ohta +Date: Wed Apr 29 01:23:11 2020 +0900 + + [VM][FMTOWNS][CDROM] Enable to load boot sectors (and next sections),still not implement some command. + +commit c35006d7350d4d72a174bb6c0ecbff107e344c6b +Author: K.Ohta +Date: Tue Apr 28 17:37:37 2020 +0900 + + [VM][UPD71070] Change mean of TC bus bits (per channel).See mz2800.cpp. + + [VM][FMTOWNS][CDROM] DMAC driven DMA_IRQ. + +commit e12d8241561ad292a065d8033d937bc5c18bec5c +Author: K.Ohta +Date: Tue Apr 28 16:58:11 2020 +0900 + + [BUILD][LINUX][CLANG] Add LTO flags. + +commit 547948b85ff4eeeb935ee817ae90f672838fdb2e +Author: K.Ohta +Date: Tue Apr 28 16:57:42 2020 +0900 + + [VM][FMTOWNS][CDROM] Simplize retundant function calling. + +commit d08d0ffde4d833116554bc4f991d597e335214e0 +Author: K.Ohta +Date: Sun Apr 26 22:09:52 2020 +0900 + + [VM][FMTOWNS][CDROM] Numeric from Towns Linux (v1.1) + +commit 2013cbdb83427b70bd2bc4c1b5d2d08fe77a84aa +Author: K.Ohta +Date: Sun Apr 26 20:36:41 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit da0f74a5fc06c56bdf857f3e68320291f7fccf2f +Author: K.Ohta +Date: Sun Apr 26 20:10:08 2020 +0900 + + [VM][FMTOWNS] . + +commit 683e1060025784ea2d0f1344dc7f1a02b657b4e8 +Author: K.Ohta +Date: Sun Apr 26 19:57:14 2020 +0900 + + [VM][FMTOWNS][CDROM] Remove unused lines. + +commit 41dd8571f29e173ac0f42b052cb87f439d392b7a +Author: K.Ohta +Date: Sun Apr 26 19:10:42 2020 +0900 + + [VM][FMTOWNS][CDROM][DMAC] . + +commit e81a9ab5352b6b79c20ff1fee03a459a170d9291 +Author: K.Ohta +Date: Sun Apr 26 17:35:35 2020 +0900 + + [VM][FMTOWNS][CDROM] Fix around reading.Still doesn't boot. + +commit 8fa4c6450e89512783ad6300879a69bcdb167df7 +Author: K.Ohta +Date: Sun Apr 26 03:52:42 2020 +0900 + + [VM][FMTOWNS][CDROM] Re-New around CD-ROM.But, still not working. + +commit 464de703fdb57bfdaf35d0155338f14318743b06 +Author: K.Ohta +Date: Sat Apr 18 22:34:23 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit 53b9fa373727a980b955076086a71139d6d2ed86 +Author: K.Ohta +Date: Sat Apr 18 21:47:07 2020 +0900 + + [VM][FMTOWNS][CDROM] . + +commit c52db4a4a9e14979859d401f921696bb13aa3e16 +Author: K.Ohta +Date: Sat Apr 18 18:48:20 2020 +0900 + + [VM][FMTOWNS][CDC] . + +commit 5761ca5094adf1a5e63b10ab6155e8003d8a6a1d +Author: K.Ohta +Date: Sat Apr 18 18:26:05 2020 +0900 + + [VM][FMTOWNS][CDROM][WIP] Implementing around STATUS register. + +commit efdc38a06ea5a67263b18191b6f779f22fc27341 +Author: K.Ohta +Date: Mon Apr 13 18:49:16 2020 +0900 + + [VM][FMTOWNS][TOWNS_CDROM] Implementing right SUBC REGISTER, still not make public. + +commit b223a0b987b610992086c1e226784a7d9bf33214 +Author: K.Ohta +Date: Sat Apr 11 23:08:49 2020 +0900 + + [VM][FMTOWNS][TOWNS_CDROM] RE-Write DRAFT of SEQUENCES for some commands. + +commit 490d7c1272082d260a6b8a20a354a2d84c8ee968 +Author: K.Ohta +Date: Sat Apr 11 05:26:53 2020 +0900 + + [VM][FMTOWNS][MEMORY] Fix memory layout. + +commit 24fb7e88a7ad24130a1dd6fc7220556e9d9c4cbf +Author: K.Ohta +Date: Sat Apr 11 01:33:42 2020 +0900 + + [VM][FMTOWNS] Add some VMs. + +commit c37684989eedb8b2b12aa73e8f0e1e8b59ec0e4f +Author: K.Ohta +Date: Fri Apr 10 23:49:23 2020 +0900 + + [FMTOWNS] Rename VMNAMEs and config names. + +commit 2a0b74526d9d91c0aee7a9af5eed21863434df59 +Author: K.Ohta +Date: Fri Apr 10 23:03:34 2020 +0900 + + [VM][FMTOWNS][VRAM][CRTC] . + +commit 38f317dc4ca1af77b34323cb2a2f8ba8fc379e3c +Author: K.Ohta +Date: Fri Apr 10 19:27:57 2020 +0900 + + [GENERAL] Comment out some unusable messages. + +commit 2ab3cc57f16b943d89401cce1d1ea9a80301cf6e +Author: K.Ohta +Date: Fri Apr 10 18:06:54 2020 +0900 + + [VM][FMGEN][OPN2] Fix clock rate. + +commit 41d9c8f09792f34e363af635171eab92a6b00263 +Author: K.Ohta +Date: Fri Apr 10 17:43:10 2020 +0900 + + [VM][FMTOWNS] Remove unused line. + +commit 851523f5e6f5681c01be65d8fae3834d203c4678 +Author: K.Ohta +Date: Fri Apr 10 17:37:27 2020 +0900 + + [VM][FMTOWNS][YM2612] Clock of FM-Sounder may be 7200KHz.See P.201 of FM-Towns Technical data book rev.2. + +commit ab6af3910465e162fdb755da3cf733d1df9ffb7a +Author: K.Ohta +Date: Fri Apr 10 17:36:59 2020 +0900 + + [VM][FMTOWNS][ADPCM][YM2612] Fix interrupt handling. + +commit 743cca128ff5b61834ac9a51ca163af1094ad67c +Author: K.Ohta +Date: Fri Apr 10 17:36:17 2020 +0900 + + [VM][FMGEN][OPN2] Mostly working (with after apppling commits for FM-Towns) + +commit d5d1b7d9f2529cfc7ee6dc169eea65e92be429a2 +Author: K.Ohta +Date: Fri Apr 10 02:49:28 2020 +0900 + + [VM][FMTOWNS][CRTC] Adjust render feature. + +commit c27c38f90935c2d75997d9a53d0abbc337f3d495 +Author: K.Ohta +Date: Fri Apr 10 02:19:11 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix layer mixing and layer order.Fix wrong palette accessing. + +commit dd437d5a871fd52fd6885e2f9e07ec124679b238 +Author: K.Ohta +Date: Thu Apr 9 23:50:36 2020 +0900 + + [FMGEN][OPN2] . + +commit ebba316f76b5719754cbbc20e6c9ae276cc30c4d +Author: K.Ohta +Date: Thu Apr 9 23:49:09 2020 +0900 + + [VM][FMGEN][OPN2][WIP] Adjusting register features. + +commit 272a3dccb905e9a514a6a544af9ca386212b32c9 +Author: K.Ohta +Date: Thu Apr 9 21:21:19 2020 +0900 + + [VM][FMTOWNS][JOYSTICK] Fix not moving rever of joystick. + +commit 90ec26e7db683160614bb8f8ba4582b806d44fe4 +Author: K.Ohta +Date: Thu Apr 9 21:20:25 2020 +0900 + + [VM][FMTOWNS][YM2612][OPN2][WIP] Adjusting around registers.This still not completed. + +commit 1f1cd85bc4c71a3562aa044de1833c4a8409692e +Author: K.Ohta +Date: Thu Apr 9 19:15:08 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix bitorder of 16 colors mode. + +commit 224ee59b81655019a3d05758cc544aa5148ff32c +Author: K.Ohta +Date: Thu Apr 9 19:13:04 2020 +0900 + + [VM][FMTOWNS][FONTROMS] Add API read_direct_data8() to reading faster by CRTC. + +commit 532dc43b7d7b8e3a9c81dad9dff9f315abe16491 +Author: K.Ohta +Date: Thu Mar 26 01:07:47 2020 +0900 + + [VM][DEBUGGER][I386_NP21][MC6809] Add "RH" command to debugger and bool get_debug_regs_description(_TCHAR *, size_t) to API. + +commit 3bc4bc0f2bb64107219794dca6b21b7c8150cf54 +Author: K.Ohta +Date: Wed Mar 25 23:03:55 2020 +0900 + + [VM][FMTOWNS][CRTC] Add registers dump feature. + + [VM][FMTOWNS][SPRITE] Delete unused cache feature. + +commit e14c3feeab0ca62e8db0699950846f1185c0c6ff +Author: K.Ohta +Date: Wed Mar 25 20:14:47 2020 +0900 + + [VM][JOYSTICK][MOUSE] Implement *true* Joystick and MOUSE. + +commit 5708de74be76da59630b2be33d2be7fcf3188dce +Author: K.Ohta +Date: Wed Mar 25 17:15:58 2020 +0900 + + [VM][FMTOWNS][SCSI] Add I/O:READ:0034h. This indicates enable to use 16bit width DMA transfer. + +commit 81c835fb12f9eaec3d7ec38fc52cb87e806a6e55 +Author: K.Ohta +Date: Wed Mar 25 17:15:05 2020 +0900 + + [VM][FMTOWNS][FONTROM] Remove unused variables.Add features after CX. + +commit d2f92f9abef96b06fc2c1a03bf8cc2e63768ba88 +Author: K.Ohta +Date: Wed Mar 25 17:14:21 2020 +0900 + + [VM][FMTOWNS][CRTC] Improve around I/O port, implement regsieters of later machines. + +commit 27e8b62f72d53f149f0e4a9e3c7f207550ffc6e7 +Author: K.Ohta +Date: Wed Mar 25 17:13:08 2020 +0900 + + [VM][FMTOWNS][MEMORY] Fix around FONT ROM and Improve around SYSTEM REGISTERS. + +commit 302954777313f1d025bd300e9afc48d196dc2e60 +Author: K.Ohta +Date: Wed Mar 25 17:12:26 2020 +0900 + + [VM][FMTOWNS][TOWNS_SPRITE] Fix around I/O address handling. + +commit b995c897b29ef9dfa40e8963ba564a334e7a53a9 +Author: K.Ohta +Date: Wed Mar 25 03:58:44 2020 +0900 + + [VM][FMTOWNS][VRAM] TVRAM: Don't arrive CGROM.Fix weird scrolling for text layer. + +commit 3f1367610117350efd7b42da4336baf7601541ca +Author: K.Ohta +Date: Wed Mar 25 03:57:47 2020 +0900 + + [VM][FMTOWNS][SPRITE] Add debug feature. + + [VM][FMTOWNS][SPRITE] Adjust TVRAM writing feature. + +commit a58ca88db8fa48531674023cd0ba725f8ae5f1ea +Author: K.Ohta +Date: Wed Mar 18 18:56:18 2020 +0900 + + [VM][FMTOWNS] Adjust memory map.Simplify signals around CRTC<->SPRITE. + +commit de97d3c95655b9541109b1cda28102787ac44f0a +Author: K.Ohta +Date: Wed Mar 18 16:22:44 2020 +0900 + + [VM][FMTOWNS][MEMORY] Adjust WAIT value. + +commit 1beaf295ac8ff9a73664b5635ccdde02e73a6108 +Author: K.Ohta +Date: Wed Mar 18 16:21:46 2020 +0900 + + [VM][FMTOWNS][SCSI_HOST] Add USE_QUEUED_SCSI_TRANSFER flag, will use queued transfer (still not using). + +commit 847117966df8969325451c23c0af0b7e3e980e94 +Author: K.Ohta +Date: Wed Mar 18 03:23:23 2020 +0900 + + [VM][HARDDISK] . + +commit 9b90561d69303671ff33c8f6608f035dd82db4d0 +Author: K.Ohta +Date: Wed Mar 18 03:22:18 2020 +0900 + + [VM][FMTOWNS][HARDDISK] Fix wrong HARDDISK number setting at OPENING/CLOSING, etc. + +commit 20a6db03a5aa939422e88b5761282ee57f549583 +Author: K.Ohta +Date: Wed Mar 18 01:04:00 2020 +0900 + + [VM][FMTOWNS] (Maybe temporally) Allow IRQ SPAM. + +commit dfcaae0037c69071f26e3c9031cdf487a25077b3 +Author: K.Ohta +Date: Wed Mar 18 01:00:33 2020 +0900 + + [VM][UPD71071][TOWNS_DMAC] Ugly workaround for 16bit transfer DMAC command.Will fix. + +commit eff4b0804ae7591dc8058a5c2fccd58998609c65 +Author: K.Ohta +Date: Tue Mar 17 18:02:34 2020 +0900 + + [VM][SCSI] Add new (pseudo) SIGNAL for preparing use buffered transfer. + +commit ab54189e3978dedb8eae52733f80b9cc49bbbad3 +Author: K.Ohta +Date: Tue Mar 17 15:47:13 2020 +0900 + + [Qt][LOGGER] Shrink redundant title. + +commit 94c901591174232d27dbd6edeb97a93570176cf2 +Author: K.Ohta +Date: Tue Mar 17 15:46:02 2020 +0900 + + [VM][UPD71071][TOWNS_DMAC] Implement *truely* 16bit transfer feature from Renesas(NEC Electronics)'s DATA SHEET. + +commit cd4dea998a7601ecdfab09a5f53b61980bc70431 +Author: K.Ohta +Date: Mon Mar 16 17:48:26 2020 +0900 + + [VM][FMTOWNS] . + +commit 1b2d64e95801c2b2fd697833effacd2a827ff158 +Author: K.Ohta +Date: Mon Mar 16 17:47:23 2020 +0900 + + [VM][FMTOWNS][SCSI_DEV][UPD71071][WIP] Fixing weird DROPPING DMA, this is work-in-progress, not completed. + +commit e150300cfc5efb145d5e7c94524aeb589ff421ae +Author: K.Ohta +Date: Sun Mar 15 18:19:09 2020 +0900 + + [VM][UPD71071] Modify handling of 16bit transfer mode. + +commit bfdb29673a3aac36881a2d5ecdc22ffb082022f8 +Author: K.Ohta +Date: Sun Mar 15 18:18:14 2020 +0900 + + [VM][FMTOWNS][SCSI][TOWNS_DMAC][WIP] Implementing 16bit DMA.Still not be completed. + +commit 790765fc67b6bbdbc238eeac22a03ff62a74c80c +Author: K.Ohta +Date: Tue Mar 3 23:09:36 2020 +0900 + + [VM][PC9801][CPUREG] Fix FTBFS with High-Resolution PC98s. + +commit 2139f871646d44e9c35295868f4c653270bce68f +Merge: d34d40a7 d9ce98cc +Author: Kyuma Ohta +Date: Tue Mar 3 22:20:22 2020 +0900 + + Merge branch 'master' of github.com:Artanejp/common_source_project-fm7 + +commit d34d40a7d391a2862517d658ca2e20681285c6a7 +Author: Kyuma Ohta +Date: Tue Mar 3 22:19:57 2020 +0900 + + [VM][I386_NP21] Merge upstream + +commit d9ce98ccb07bdbd05f5ab5912ad1dc5ccfb1a419 +Author: K.Ohta +Date: Tue Mar 3 22:17:30 2020 +0900 + + [VM][I386_NP21] Fix FTBFS with gcc 5.4. + +commit de999074b414daeacab7d0e6b3bc86dc86523474 +Author: K.Ohta +Date: Tue Mar 3 21:29:15 2020 +0900 + + [VM][WIN32] Fix FTBFS with LLVM/Win32. + +commit 082ef903f731add12573f07e480b24aa65291f0f +Author: K.Ohta +Date: Tue Mar 3 21:27:23 2020 +0900 + + [VM][PC9801] Fix FTBFS with LLVM/Win32. + +commit c7170ec44efb8c1f479f3157afa163f4b4564675 +Author: K.Ohta +Date: Tue Mar 3 15:36:19 2020 +0900 + + [VM][PC9801][DISPLAY] Fix FTBFS with LLVM CLANG. + +commit 5df270898e851be1cba463c421cb1191d6b3bc14 +Author: K.Ohta +Date: Tue Mar 3 15:29:37 2020 +0900 + + [VM] Fix FTBFS. + +commit 4c4e8beec934c15b654d4e952ffad69565e7bbdd +Author: K.Ohta +Date: Tue Mar 3 15:28:04 2020 +0900 + + [Z80DMA] Fix FTBFS. + +commit 581dfbe61f1fa22854ec51d2afbbfda971fe438a +Author: K.Ohta +Date: Tue Mar 3 15:25:23 2020 +0900 + + [VM][I86] Fix FTBFS with Win32. + +commit 7aff9eff8b2b00bc09ba5c790afdaae20a9ab251 +Author: K.Ohta +Date: Tue Mar 3 15:18:36 2020 +0900 + + [INSTALLER][UINX] Update SOVERSION. + +commit 05503f023325e040f305faef26e8a5c3e6dcdfbf +Author: K.Ohta +Date: Tue Mar 3 15:15:48 2020 +0900 + + [DOC] Re-Update documents. + +commit fd1687a197f8e25788c8231a08e73fb3a5667763 +Author: K.Ohta +Date: Tue Mar 3 15:11:15 2020 +0900 + + [DOC][FMTOWNS] Update FM-Towns status. + +commit bb54da75384e70e20503d377f9fb23dcfe4297ab +Author: K.Ohta +Date: Tue Mar 3 15:09:42 2020 +0900 + + [UI][Qt] Add HARDDISK CREATION feature. + [I18N] Add Japanese translations. + +commit e9959a717496ea6a75d1d3a091e4b77ec0531796 +Author: K.Ohta +Date: Tue Mar 3 06:53:41 2020 +0900 + + [VM][PC9801][86PCM] Adjust volume multiplier of PCM. + +commit ff6b8ffe94eda721f736324ce67e2aa7ec4aaa4d +Author: K.Ohta +Date: Tue Mar 3 06:36:52 2020 +0900 + + [VM][FMSOWND][86PCM] Fix Initial value of PCM_MUTE(A66Eh). + +commit 155f29ee4b65906c49358356b274c558b10dede7 +Author: K.Ohta +Date: Tue Mar 3 06:30:37 2020 +0900 + + [VM][PC9801][FMSOUND] Temporally disable PCM_MUTE(A66Eh).Temporally fix not sound PCM. + +commit 7b8aaba8dd5bba29859942f40b6373a543118a82 +Author: K.Ohta +Date: Tue Mar 3 04:03:24 2020 +0900 + + [UI][Qt] Add HARDDISK create widget.Still not working, only dummy. + +commit 9c47959ef8f965dfdc942a4c7c674e877212c384 +Author: K.Ohta +Date: Tue Mar 3 01:51:25 2020 +0900 + + [DOC] . + +commit 22bd0f796586f796b96fa83242d90b712f4a34ea +Author: K.Ohta +Date: Tue Mar 3 01:48:18 2020 +0900 + + [General] Update Document. + +commit 177db8ccb3765bf7f49ef3d9f25738bb15348e2b +Author: K.Ohta +Date: Tue Mar 3 01:26:33 2020 +0900 + + [VM][I286][I386][PC9801] Merge upstreeam 2020-02-21. + +commit 24a74fdbe6a7472b85c03ba13ff634b71ac388f8 +Author: K.Ohta +Date: Mon Mar 2 21:17:51 2020 +0900 + + [VM][JX][MZ2800] Fix FTBFS with I8088. + + [VM][MZ6550] Fix FTBFS. + +commit dd351894cec0ada1df15b4363ce4e5935743c8b0 +Author: K.Ohta +Date: Mon Mar 2 20:57:45 2020 +0900 + + [VM][FM16BETA] Fix FTBFS. + +commit 46be78be36a2f2651f07b7e34c8f316d725678fb +Author: K.Ohta +Date: Mon Mar 2 20:46:52 2020 +0900 + + [VM][General] Merge upstream 2020-02-17. + +commit 4f88b7a8de97056c95ac83f81df34b3f62978e7c +Author: K.Ohta +Date: Sat Feb 29 19:36:22 2020 +0900 + + [VM][FMTOWNS][KEYBOARD][DOC] Emulate all of JIS key. + +commit 81ee6961b0a154584b1eeeb1baa9dd71789bed95 +Author: K.Ohta +Date: Sat Feb 29 03:00:40 2020 +0900 + + [VM][FMTOWNS][CDROM][CDC] . + +commit db62a679e637e7275e974397fa0f838ce88964af +Author: K.Ohta +Date: Sat Feb 29 03:00:02 2020 +0900 + + [UI][Qt][FMTOWNS][DOC] Add document and qrc file. + +commit 27c8780f60b1db3f12b4f0394c1ee3eb092579d7 +Author: K.Ohta +Date: Fri Feb 28 13:25:53 2020 +0900 + + [VM][FMTOWNS][CDC][WIP] Fix unexpected SEL signal at reset. + +commit 8214dd83aff65b358e8bf0e88a9da13eb8d457a3 +Author: K.Ohta +Date: Fri Feb 28 00:35:46 2020 +0900 + + [VM][FMTOWNS][CDROM][WIP] Still implement CDC.Still not work. + +commit eae4a809254bf50abc89ab4dd389c06a9e143e91 +Author: K.Ohta +Date: Fri Feb 21 01:07:48 2020 +0900 + + [VM][FMTOWNS][TIMER] Negate polarity of RTC's BUSY signal. + [VM][FMTOWNS][TOWNS_DMAC] . + +commit 3949356448e02b98ecec22d68c621ea52e611288 +Author: K.Ohta +Date: Fri Feb 21 00:25:27 2020 +0900 + + [VM][PC9801][DISPLAY] . + +commit ddbbd2c3d25663b8e646613a1150f287bab93906 +Author: K.Ohta +Date: Thu Feb 20 20:36:59 2020 +0900 + + [Build][PC9801][CMAKE] . + +commit b41c071ba4917bb22882daea5749a0310d37b4ed +Author: K.Ohta +Date: Thu Feb 20 20:22:10 2020 +0900 + + [VM][PC9801][DISPLAY] Re-Backport from Upstream 2020-02-01.Kakinoki Syougi works fine. + + Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/719 . + +commit 6ce4e123d53c2d035c4adb26536c0499066c9041 +Author: K.Ohta +Date: Thu Feb 20 16:36:06 2020 +0900 + + [VM][UPD7220] Fix Hang-Up at N88 BASIC for PC-9801. + +commit 03d6e92d37c5bff7aac37aac92ba95766a189097 +Author: Kyuma Ohta +Date: Wed Feb 19 20:01:51 2020 +0000 + + [VM][FMTOWNS][FMGEN] Fix LACKing DLLEXPORT attribute to OPN2:: class. + [VM][FMTOWNS] Fix FTBFS with LLVM CLANG. + [BUILD][CMAKE][Windows][LLVM] Update Qt version to 5.14. + +commit d4231bce6b9e8023b538708f8fc8365a073c88a4 +Author: Kyuma Ohta +Date: Wed Feb 19 19:30:20 2020 +0000 + + [VM][PC9801][SASI_BIOS] Fix FTBFS with LLVM CLANG. + +commit d82ae54e53e43244bd2b31bc653c47112424d17c +Author: K.Ohta +Date: Wed Feb 19 23:09:48 2020 +0900 + + [Qt][OpenGL2] TRY: Test to fix matrix of glOrtho().Expect to fix wrong display at VirtualBox Windows. + +commit 3a3f799d54056865e7b553da8a372c64a2051fe0 +Author: K.Ohta +Date: Wed Feb 19 22:48:21 2020 +0900 + + [UI][Qt][MAIN] . + +commit 216157bde5018ee08ae69afe5fbfc8be9a3e860a +Author: K.Ohta +Date: Wed Feb 19 22:41:25 2020 +0900 + + [UI][Qt][MAIN] Fix FTBFS with LLVM CLANG. + +commit 00db1a72e7c0efb97df01c5a3a0cab27add7833f +Author: K.Ohta +Date: Wed Feb 19 22:32:40 2020 +0900 + + [VM][I386_NP21] . + +commit 8cd2fce509b9bf71330ca6b539d8d45fb5a50ee2 +Author: K.Ohta +Date: Wed Feb 19 22:30:37 2020 +0900 + + [VM][I386_NP21] Fix FTBFS when enabling __FASTCALL prefix. + +commit b1ccd96f53fe95388cecd6dc7bebf19edcab8f05 +Author: K.Ohta +Date: Wed Feb 19 22:20:57 2020 +0900 + + [UI][Qt][General] Try: Make GUI core (QApplication -> QCoreApplication) to be non-Global. + + This aims to solve for below warning at setting Attributes of QCoreApplication. + +commit 0ab5a189ee3adf3db1e27fd3ba21d0230e6d02a1 +Author: K.Ohta +Date: Wed Feb 19 00:15:06 2020 +0900 + + [VM][FMTOWNS][CDROM][WIP] Has read a first sector, but overwritten by another sector (;_;) + +commit 4db90db17f3af41722981ee097579ceecb56088d +Author: K.Ohta +Date: Tue Feb 18 01:13:31 2020 +0900 + + [VM][FMTOWNS][CDC][WIP] Improve CPU<->DMAC<->CDC<->CDC_SCSI<->TOWNS_CDROM routing, but still not works. + +commit 37c4133be32d818d676eeb2b78d3b3155d0f67fa +Author: K.Ohta +Date: Sun Feb 16 19:19:10 2020 +0900 + + [OSD][Qt][OOPs] Add miss-added entry for _CDROM_DEBUG_LOG flag. + +commit ee6363e6a82d02c89e16b8dea4e5bf99fbb1b5d2 +Author: K.Ohta +Date: Sun Feb 16 19:18:45 2020 +0900 + + [VM][SCSI_DEV] Update log entry. + +commit bc1c1a7f193eaa8ad633b65130b5fc86f9ff8445 +Author: K.Ohta +Date: Sun Feb 16 19:17:51 2020 +0900 + + [VM][FMTOWNS][CDC][WIP] Re-Implementing with *PSEUDO* 4bit MCU.This still not be completed. + +commit 7f8d701b417137795038e8c24df116e01a878bb5 +Author: K.Ohta +Date: Sat Feb 15 23:20:24 2020 +0900 + + [VM][FMTOWNS][CDROM][SCSI_DEV][WIP] Implementing CDC and CDROM. + +commit 6d9d43c36247f5dd01ff4d32d595aa23ce8944b6 +Author: K.Ohta +Date: Sat Feb 15 16:12:39 2020 +0900 + + [VM][SCSI_DEV][SCSI_CDROM] Fix freeze some PC-Engine's CD-ROM^2 games and SCSI HDD for FM-Towns. + +commit 49701e13b81175e039b15b61118443aadb0e8b28 +Author: K.Ohta +Date: Sat Feb 15 05:22:24 2020 +0900 + + [VM][SCSI_DEV] . + +commit 291cd82eec5c0915ddf0a0bb89a18cb2bf6115fb +Author: K.Ohta +Date: Sat Feb 15 05:21:09 2020 +0900 + + [VM][PCENGINE][ADPCM][WIP] Fixing em-bugged freeze ADPCM DMA after CDC STATUS (write to I/O 1800h.) + +commit a9c625ba8c83cd277280bd81cf322a355eb09079 +Author: K.Ohta +Date: Fri Feb 14 23:13:05 2020 +0900 + + [VM][DEVICE] Add update_signal_mask() to modify signal mask for SIG_SCSI_DAT for SCSI/SASI devices. + [VM][COMMON_VM] Include SCSI devices to libCSPcommon_vm, excepts SCSI_HOST::. + +commit effd9e8388ee80c5996f0a52fb8c6427bb8510c8 +Author: K.Ohta +Date: Mon Feb 10 00:57:18 2020 +0900 + + [VM][FMTOWNS][SCSI] Partky working SCSI HDD.Something still be wrong and unstable. + +commit a52ce9ece54f010ac9b360494a5a6d4418d76755 +Author: K.Ohta +Date: Sun Feb 9 19:54:11 2020 +0900 + + [VM][SCSI_DEV] . + +commit 79e039198cdcd8ed5bfb0976a13fab93d518ef91 +Author: K.Ohta +Date: Sun Feb 9 19:24:04 2020 +0900 + + [VM][SCSI_DEV] TRY: Add delayed bsy signal handling features. + +commit a3e45c16b66e0f5fc4803548a2b1268adfbc727b +Author: K.Ohta +Date: Sun Feb 9 19:22:44 2020 +0900 + + [UI][Qt] Add "USE_CUSTOM_SCREEN_ZOOM_FACTOR" flag to fooVM.h. + +commit b4bc0dd6ffbb268fd0681df3a97f49326eee86d7 +Author: K.Ohta +Date: Sun Feb 9 17:27:46 2020 +0900 + + [VM][FMTOWNS] Set "SCSI_DEV_IMMEDIATE_SELECT".Set HDD's vendor ID and product ID. + +commit c695298069c2b53aa18c5f1942cf66b16d41d275 +Author: K.Ohta +Date: Sun Feb 9 17:26:52 2020 +0900 + + [VM][SCSI_HDD][SCSI_DEV] Implement some command.But still not active. + +commit 8d1fdc378138d312fd88fe2961cc9f9dc5ce452e +Author: K.Ohta +Date: Sun Feb 9 04:47:50 2020 +0900 + + [VM][HARDDISK] Uncomment disk recognize part. + +commit ac41c8db4d77f52178151ab1868a9bc4197b31eb +Author: K.Ohta +Date: Sun Feb 9 04:46:24 2020 +0900 + + [VM][PC9801][SASI_BIOS] Update APIs.Fix not working SASI pseudo bios. + +commit 744a110b752f4e9d95f6d74060bfa9cdfb196a15 +Author: K.Ohta +Date: Sun Feb 9 04:45:20 2020 +0900 + + [VM][SCSI_DEV] Revert latest commit. + +commit d9e6ead5190ef41721e1f01a6ab1bd197cb525c7 +Author: K.Ohta +Date: Sun Feb 9 02:51:53 2020 +0900 + + [VM][FMTOWNS][SCSI_DEV] . + +commit 43e5218f4d6baabb454e094c638f1dde787f6a63 +Author: K.Ohta +Date: Sun Feb 9 01:30:25 2020 +0900 + + [VM][FMTOWNS][TOWNS_SCSI_HOST][WIP] Improving SEL sequence. + +commit 0d1add18b6969ddf60461a47f5a6e0af619271d6 +Author: K.Ohta +Date: Sun Feb 9 01:29:40 2020 +0900 + + [VM][SCSI_HDD][WIP] Implement RECALIBRATE SCSI command. + +commit 70ea3f7a878d5899af7e55dc87ed986f4fc85d0d +Author: K.Ohta +Date: Sat Feb 8 22:46:24 2020 +0900 + + [VM][SCSI_DEV][WIP] Adjusting bus timing. + +commit 6ae5f0edc0df081604d2d720851a20057d7882fd +Author: K.Ohta +Date: Sat Feb 8 22:45:48 2020 +0900 + + [VM][FMTOWNS][SCSI] . + +commit 12a304e1fe764b0278f6b75f1ecbb6c2dfe973fb +Author: K.Ohta +Date: Sat Feb 8 18:45:07 2020 +0900 + + [VM][FMTOWNS][SCSI][WIP] Still not working MS-DOS on HDD(´;ω;`) + +commit bcac14845d1e4d6d22735a339edf1ba212752969 +Author: K.Ohta +Date: Sat Feb 8 18:44:06 2020 +0900 + + [VM][HARDDISK] Calculate correctness C/H/S of HDD. + [VM][SCSI_DEV][WIP] Adjusting reply bus on changing phase. + +commit 13a20cbc8e5bef1088972b4b088fb8e68255727c +Author: K.Ohta +Date: Fri Feb 7 13:44:47 2020 +0900 + + [VM_TEMPLATE] Fix FTBFS when include directly. + [VM][I386_NP21] . + +commit 56182292ccc9af4f553124123f7e25d237d12514 +Author: K.Ohta +Date: Fri Feb 7 13:27:55 2020 +0900 + + [VM][I386_NP21] Make VM to VM_TEMPLATE as class. + +commit 041039ba0e5c8dc682df7cb179918c371ee4db5a +Author: K.Ohta +Date: Fri Feb 7 13:22:08 2020 +0900 + + [VM][I386] IMPORTANT: libcpu_newdev/i386 has removed.I386:: porting from NP21 seems to be working nice, no need to porting from MAME/C++. + +commit 27f90df3ff9bd5dc9f1a01f5ffa9f276c284dcba +Author: K.Ohta +Date: Thu Feb 6 23:11:06 2020 +0900 + + [VM][FMTOWNS][SCSI][OOPS] I forgot adding new TONWS_SCSI:: to git X-) + +commit 316325d060ebc27ce1027c9bb8cfeb30879f1903 +Author: K.Ohta +Date: Wed Feb 5 23:02:34 2020 +0900 + + [Qt][OpenGL] Fix FTBFS if don't have libglu. + +commit d39a2e669eb1e0631cd916257b50e81a74c6a8d2 +Author: K.Ohta +Date: Wed Feb 5 23:01:45 2020 +0900 + + [OSD][SOUND] Fix crash when effective sound sink don't exists. + +commit 8d54c24a9c4997ee6e927866ac8e04b2f1eeb60e +Author: K.Ohta +Date: Wed Feb 5 16:17:46 2020 +0900 + + [VM][FMTOWNS][SCSI][WIP] Still not working HDD. + +commit 6802c9acf74a12778f87ee8d8977cb577a882220 +Author: K.Ohta +Date: Wed Feb 5 13:30:21 2020 +0900 + + [VM][FMTOWNS] Bootable with I286_NP21.Fix word/dword access at TOWNS_SYSROM::. + [VM][PC9801][FMSOUND] Fix FTBFS with not SUPPORT_OPNA. + +commit bef24a7cb5f5a14cb0c705c20fe3e0e0f7265707 +Author: K.Ohta +Date: Wed Feb 5 11:39:05 2020 +0900 + + [VM][FMR50][I386] Fix not detect pseudo-bios, not bootable. + +commit feb6fd79868851b6eb6f1055f0dd4101712ac52e +Author: K.Ohta +Date: Wed Feb 5 01:41:36 2020 +0900 + + [VM][FMTOWNS] Still use old I386. + +commit 9b7de3bf642caf3c96524c151c766f63237c16aa +Author: K.Ohta +Date: Wed Feb 5 01:13:24 2020 +0900 + + [GENERAL] . + +commit bc698c87261ff202b1cfd756d257cce79004b7b5 +Author: K.Ohta +Date: Wed Feb 5 01:12:57 2020 +0900 + + [VM] Merge UPstream 2020-02-01. + +commit c3f0d191f800179f19d09ed3df747f5d83769a9c +Author: K.Ohta +Date: Wed Feb 5 01:00:39 2020 +0900 + + [VM] Apply upstream 2020-02-01 to some VMs. + +commit e70ec22c1888ce4d2fcbc4ad53e84c46aba0742e +Author: K.Ohta +Date: Wed Feb 5 00:58:34 2020 +0900 + + [VM][PC9801] Apply upstream 2020-02-01. + +commit 6696da524aa0afb4020c45295dbaae912a5459a8 +Author: K.Ohta +Date: Tue Feb 4 21:52:06 2020 +0900 + + [VM][I386_NP21] Merge Upstream 2020-02-01 's I386::/NP21.Belows are differ from upstream: + * Implement memory wait to change CPU speed. + * Implement extra reset wire to notify CPU reset. + * Some headers are changed due to cause FTBFS with GCC. + * Character encoding chenged to UTF-8 at most of source files(not all?) + +commit 9cb4ed22ffc718a7c70ec2b07618e7e0dfb94721 +Author: K.Ohta +Date: Tue Feb 4 00:52:10 2020 +0900 + + [VM][FMTOWNS][CRTC] May render kanji text. + +commit ddd62b7f0cb7fbbf2328f96e354a009e08877dcd +Author: K.Ohta +Date: Sat Feb 1 03:34:34 2020 +0900 + + [VM][SCSI_HOST] Implement both wide and narrow bus. + +commit 98baafc4ffa0d6a1c008e68434568c9943a8a20e +Author: K.Ohta +Date: Sat Feb 1 03:33:40 2020 +0900 + + [VM][FMTOWNS] Implement Text VRAM emulation .Floppy version ofMS-DOS works. + +commit d0bc8cc0ebc121268d1d093fc31973a9e4769eff +Author: K.Ohta +Date: Fri Jan 31 21:30:36 2020 +0900 + + [UI][Qt][Harddisk] Add *.h0-*.h9 , they are Unz (Towns emulator)'s virtual harddisk images. + +commit dda280eddab4c4d545fee376a4e299c0131d892f +Author: K.Ohta +Date: Fri Jan 31 21:29:51 2020 +0900 + + [VM][FMTOWNS][CDC] Modify DMA Transfer hook. + +commit 88719c854d47728f3a0dd8063e21b237d418c6da +Author: K.Ohta +Date: Fri Jan 31 21:28:30 2020 +0900 + + [VM][FMTOWNS][TOWNS_DMAC][UPD72017] More coirrectness DMA transfer. + +commit d5800fff60d0192fa1e9a05f3c0b8cf31f233dab +Author: K.Ohta +Date: Fri Jan 31 19:15:51 2020 +0900 + + [VM][FMTOWNS][CRTC] (Maybe) Complete palette emulation.Move palette functions from TOWNS_VRAM:: to TOWNS_CRTC:: . + +commit 23213e459eb0d90a4b8c02eea584e8810bd26fc2 +Author: K.Ohta +Date: Fri Jan 31 05:01:18 2020 +0900 + + [VM][I386] . + +commit ac29099071256f80fac42f54f2d980fc0fbbef98 +Author: K.Ohta +Date: Fri Jan 31 04:59:20 2020 +0900 + + [VM][FMTOWNS][MEMORY] Remove implement of address mask. + +commit 41f8716d72a23f07c6a99b9c2c7f1683df324625 +Author: K.Ohta +Date: Fri Jan 31 04:57:30 2020 +0900 + + [VM][FMTOWNS][CRTC] Record VST/HST per frame.Fill by skelton color before starting to transfer. + +commit eed8527435330202a2b84c67dac44481e932d53c +Author: K.Ohta +Date: Fri Jan 31 04:56:51 2020 +0900 + + [VM][FMTOWNS][TOWNS_DMAC] Implement as correctness address handling. + +commit 6c0a7c1df04292a2ae76e878b7b2584d2b46a2d1 +Author: K.Ohta +Date: Fri Jan 31 04:56:03 2020 +0900 + + [VM][FMTOWNS][VRAM] Remove unused values.Add debug message. + +commit 5f1afea3b0da3b4821e98b9cc7be7e5ebc1e8e92 +Author: K.Ohta +Date: Fri Jan 31 04:55:34 2020 +0900 + + [VM][FMTOWNS][FLOPPY] Implement correctness registers. + +commit a204e8011289e90611f7d1a04f9fc5bccc722261 +Author: K.Ohta +Date: Thu Jan 30 04:16:44 2020 +0900 + + [VM][FMTOWNS][TOWNS_CRTC] Fix crash with GL4.5 renderer. + +commit a6cba311a1087abfc0eb7d3435c2f3e703e0d5c1 +Author: K.Ohta +Date: Thu Jan 30 04:16:08 2020 +0900 + + [Qt][OpenGL] Correctness texture magnitude calculating. + +commit c529b4ec8a5b0019d8590dd8adb66659e5b15bb1 +Author: K.Ohta +Date: Thu Jan 30 03:35:56 2020 +0900 + + [Qt][OpenGL] . + +commit 6a795034fda58b1adc5f122068c22dbca8506d73 +Author: K.Ohta +Date: Thu Jan 30 03:34:59 2020 +0900 + + [VM][FMTOWNS][CRTC][WIP] Variable framebuffer. + +commit 03cb044b326ccbf27f5fb7d52e976fad4e610439 +Author: K.Ohta +Date: Thu Jan 30 01:14:00 2020 +0900 + + [VM][FMTOWNS][JOYSTICK] Initial support of 2 buttons PAD. + +commit 67667e01c0b9e3abc6c3d7a26c07f9a644c22a32 +Author: K.Ohta +Date: Thu Jan 30 01:12:36 2020 +0900 + + [VM][FMTOWNS][TOWNS_MEMORY] Now working memory check of Syetem ROM. + +commit 17b0847d9f32175b11ee61cbd09e9611a4c64443 +Author: K.Ohta +Date: Thu Jan 30 01:11:50 2020 +0900 + + [VM][FMTOWNS][TOWNS_DMAC] Fix around address mask value (OK?) + +commit 03a2f642ec55c926ee6564475be2b58918dc2d64 +Author: K.Ohta +Date: Thu Jan 30 01:11:25 2020 +0900 + + [VM][FMTOWNS][DICTIONARY] Fix memory breaking. + +commit 9a09db48678e1090e2f3d4a104f4c0bca551dc99 +Author: K.Ohta +Date: Thu Jan 30 01:10:55 2020 +0900 + + [VM][FMTOWNS][SYSROM] Fix brutal memory breaking. + +commit 1b1861979c9b4746881f6269bbf1e0bac3190feb +Author: K.Ohta +Date: Thu Jan 30 01:10:25 2020 +0900 + + [VM][FMTOWNS][KEYBOARD][WIP] Implementing Towns Keyboard. + +commit 3c7022d51e21df37724225fac3d0025d9f56be49 +Author: K.Ohta +Date: Thu Jan 30 01:09:47 2020 +0900 + + [VM][FMTOWNS][FONT_ROM] Comment out debug message. + +commit 6e9f9a4b023d66531a4e34b168579602024a2f9b +Author: K.Ohta +Date: Thu Jan 30 01:09:15 2020 +0900 + + [VM][FMTOWNS][RF5C60] Fix memory reak. + +commit e1c164ca0031105c2b0f3801b7319611fff0b3b8 +Author: K.Ohta +Date: Thu Jan 30 01:08:28 2020 +0900 + + [VM][I386] Prepare support with A20_MASK. + +commit 208caf1f46d27731d11ec23a57c0dcd25adb2bd7 +Author: K.Ohta +Date: Wed Jan 29 19:22:02 2020 +0900 + + [VM][FMTOWNS][TOWNS_DMAC] Implement DMAC registers to I/O port 0020h-0024h, same as eFMR50. + +commit 92605b15834f9a3c8450683b492a0ae162ec0821 +Author: K.Ohta +Date: Wed Jan 29 19:21:04 2020 +0900 + + [VM][UPD71071][COMMON_VM] Make some functions make virtual to prepare overwrap by TOWNS_DMAC. + +commit e3806a2547e01e67a4f5ea60c8c3016244b9fea1 +Author: K.Ohta +Date: Tue Jan 28 17:43:49 2020 +0900 + + [VM][FMTOWNS][MEMORY][WIP] Debugging around I/O 0020h. + +commit 2e15ae8e0b1aa2090bc6b331bb88edf355b124be +Author: K.Ohta +Date: Tue Jan 28 06:14:59 2020 +0900 + + [VM][FMTOWNS][CDC][WIP] Adjusting around CDC. + +commit 5f34b4d13b71449404317e41ad668602f2e99f07 +Author: K.Ohta +Date: Tue Jan 28 04:41:28 2020 +0900 + + [VM][FMTOWNS][CDC] . + +commit 02b993440bd4b2b5c0fb7e77c29b21dd93bd3d7a +Author: K.Ohta +Date: Tue Jan 28 04:40:49 2020 +0900 + + [VM][FMTOWNS] May PLACE MSDOS-ROM to b00000-bfffff. + +commit 72f684089fa9b4d66d9af798de86147fbbee6cc9 +Author: K.Ohta +Date: Tue Jan 28 03:50:00 2020 +0900 + + [VM][FMTOWNS] Add HARDDISK and CDROM. + +commit 48f32b19722c5f721b05b157c1600d96aeed8b85 +Author: K.Ohta +Date: Tue Jan 28 03:49:10 2020 +0900 + + [VM][FMTOWNS][MEMORY][VM] More correctness mapping. + +commit 7a063cd84484e198ed348cc7c87453fd0c06e719 +Author: K.Ohta +Date: Tue Jan 28 03:48:39 2020 +0900 + + [VM][FMTOWNS][SPRITE] Add TVRAM emulation features. + +commit 0ae599b6498159da8c17ef6fb0887e1b49d38f03 +Author: K.Ohta +Date: Tue Jan 28 03:47:38 2020 +0900 + + [VM][FMTOWNS][VRAM] Plane accessing (FMR50 emulation) may work (perhaps...). + +commit d5b70182814ef885e8902470551e81c37e46576e +Author: K.Ohta +Date: Tue Jan 28 03:46:46 2020 +0900 + + [VM][FMTOWNS][FONTROM] Add kanji code handling for MMIO 0xcff94-0xcff97. + +commit b84fedc7da70eb328b0720e70f3c8660e8025a21 +Author: K.Ohta +Date: Tue Jan 28 03:45:48 2020 +0900 + + [VM][i386] Fix wrong privilage checking on i386_protected_mode_jump(). + +commit d43606aa73bdd425d90cb261ae786234a0be1557 +Author: K.Ohta +Date: Tue Jan 28 03:45:18 2020 +0900 + + [VM_TEMPLATE] Fix oops around CDROM. + +commit c10a0e9247b757fdb8b47b1fb26933901f97b68c +Author: K.Ohta +Date: Mon Jan 27 17:24:13 2020 +0900 + + [VM][FMTOWNS][VRAM] Plane read/write features works. + +commit c0d7f98130634958087f74877997e4bb6cd2f9ae +Author: K.Ohta +Date: Mon Jan 27 16:17:36 2020 +0900 + + [VM][FMTOWNS][TESTCODE] Import document at upstream. + +commit 4ee64327f78598b121695b1548fdd5d3f66f7f00 +Author: K.Ohta +Date: Mon Jan 27 16:17:04 2020 +0900 + + [VM][FMTOWNS][TESTCODE] Import from upstream. + +commit c977bf8dcb3548ccc618d76a6b7031cea527bf1f +Author: K.Ohta +Date: Mon Jan 27 16:15:19 2020 +0900 + + [VM][FMTOWNS][TESTCODE] Import from comp_sysrom (http://townsemu.world.coocan.jp/compatiroms.html .) + +commit d55d7cfb35eeb7260fb9a26959466d2f0280569b +Author: K.Ohta +Date: Mon Jan 27 16:01:26 2020 +0900 + + [VM][FMTOWNS][CRTC] Simplify logic of transfer_line(). + +commit 66030f07fac47b4c3856e203e4703f8874eb1fa1 +Author: K.Ohta +Date: Mon Jan 27 02:44:54 2020 +0900 + + [VM][FMTOWNS][CRTC][WIP] Adjusting CRTC transfer timing. + +commit afb8a8e9d2b182253947e62281dc9f1803a30092 +Author: K.Ohta +Date: Sun Jan 26 20:04:33 2020 +0900 + + [VM][FMTOWNS][VRAM] Change debug pattern. + +commit 32956ba9691f669a6beb645357be7a9393c361e4 +Author: K.Ohta +Date: Sun Jan 26 19:48:43 2020 +0900 + + [VM][FMTOWNS][CRTC] Fix around zooming. + +commit e68cbe5f2dfacb5a021f1d23cd7aaa022a073505 +Author: K.Ohta +Date: Sun Jan 26 17:23:41 2020 +0900 + + [VM][FMTOWNS][CRTC] May display 256 colors mode. + +commit 11e1f07a6165a47aa557376bb767b357ae9765d7 +Author: K.Ohta +Date: Sat Jan 25 03:53:59 2020 +0900 + + [VM][FMTOWNS][VRAM][CRTC][WIP] Debugging CRTC.Using test pattern. + +commit a69ac161b4ab3f0259655fdade0270850d04075a +Author: K.Ohta +Date: Fri Jan 24 21:01:42 2020 +0900 + + [VM][FMTOWNS][MEMORY] Truely implement EXTRA RAM. + +commit 8bfdab5b10016278a432cb9ec3cc8880423e0759 +Author: K.Ohta +Date: Fri Jan 24 20:02:55 2020 +0900 + + [VM][FMTOWNS][VRAM] Fix wrong mask value for writing_as_32bit width. + +commit d48654cf124feb71b4e814de733bde6843f65a0e +Author: K.Ohta +Date: Fri Jan 24 20:01:40 2020 +0900 + + [VM][FMTOWNS][TIMER] Move wait 1us feature to TIMER::.Add interval timer feature (After 10F) + +commit ba008b0a4a611dba21d686301e18aa53042e2cb1 +Author: K.Ohta +Date: Thu Jan 23 22:19:02 2020 +0900 + + [VM][FMTOWNS] Fix crash around CDC. + +commit a3e4306291b3f6906322f81885e79eb502d82411 +Author: K.Ohta +Date: Thu Jan 23 22:15:05 2020 +0900 + + [VM][I386] . + +commit cdb6778856097b87ef2be83066e1cd3604d8fab9 +Author: K.Ohta +Date: Thu Jan 23 22:13:17 2020 +0900 + + [VM][I386] . + +commit f0e4e6f9f6a4783d94cf8534281d15b02e56567f +Author: K.Ohta +Date: Thu Jan 23 22:12:26 2020 +0900 + + [VM][I386][DEBUGGER] Improve display around SEGMENTS. + +commit cb145b3fc5144879178b81c6670705552b03c6e3 +Author: K.Ohta +Date: Thu Jan 23 04:21:49 2020 +0900 + + [VM][FMTOWNS][MEMORY] Free-run counter already implement at TIMER::.Use this. + +commit 3d0e389430a7e5929be57c4c75f1cae6aeab9ac3 +Author: K.Ohta +Date: Thu Jan 23 03:23:30 2020 +0900 + + [VM][FMTOWNS] Improbe I/O definition. + + [VM][FMTOWNS] Add secret free run counter (Thanks to developer of MAME). + +commit 378ceacae59749b89f0471a434fdea43ed0203ff +Author: K.Ohta +Date: Wed Jan 22 03:13:45 2020 +0900 + + [VM][FMTOWNS][WIP] Fixing any sequences. + +commit 60645fba7e550e69354e187f55d6c635af9b9879 +Author: K.Ohta +Date: Wed Jan 22 03:13:06 2020 +0900 + + [VM][I386][DEBUGER] Display registers as 32bit even 16bit mode. + +commit 1a401e72335339255dc253585900440d7c73ff80 +Author: K.Ohta +Date: Wed Jan 22 03:12:29 2020 +0900 + + [VM][I386] Fix freezing even reset() after HLT. + +commit 870ec73b3011adfcb30acc4a5cbc86e28ef0985a +Author: K.Ohta +Date: Tue Jan 21 17:38:11 2020 +0900 + + [VM][FMTOWNS] Maybe booting when starting, but, somthing is wrong for memory structure, not be booted yet. + +commit 8b5ab23f1a44e0debc5132b80039f731b7493cb1 +Author: K.Ohta +Date: Tue Jan 21 17:37:41 2020 +0900 + + [UI][Qt][FMTOWNS] Fix crash when starting. + +commit 7576b64aa4ef5fbc6aa2efb0ba068d52744259a5 +Author: K.Ohta +Date: Mon Jan 20 04:42:42 2020 +0900 + + [VM][FMTOWNS] May buildable, still not working. + [VM][FMTOWNS] Still not implement some devices. + [VM][FMTOWNS][YM2612] Add YM2612 (OPN2) to vm/fmtowns tree. + +commit c2dc2ade4579753c3e135036f9395e76f9897104 +Author: K.Ohta +Date: Mon Jan 20 04:37:55 2020 +0900 + + [VM][FMGEN] Update implemantation of YM2612 (OPN2). + + [VM][FMGEN] libCSPfmgen : Update SOVERSION. + +commit 155e0aa3dc5be6fd6d8b4f7c0787c96920f74716 +Author: K.Ohta +Date: Sun Jan 19 22:27:32 2020 +0900 + + [VM][FMTOWNS] . + +commit a1e3b4b4ef77c8d6c249c3fb89b16e402fe96fbc +Author: K.Ohta +Date: Sun Jan 19 22:20:53 2020 +0900 + + [VM][FMTOWNS] Start to try building.Maybe imcomplete a lot. + +commit cf01cafebb5c8eb01b462e65b953ee5afb48b66a +Author: K.Ohta +Date: Tue Jan 14 18:32:42 2020 +0900 + + [VM][BMJr] Fix Break sequence. Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/648 . + [VM][BMJr] Fix reset-key (EIKIGOU + BREAK) sequence. + [VM][BMJr] Alse assume Back Space key to DELETE key. + [VM][BMJr] Also assume Esc key to BREAK key. + [VM][BMJr] Update document. + +commit 8d58a0e007dc1ca2a8ac04a54234613c1131ec7b +Author: K.Ohta +Date: Tue Jan 14 02:10:30 2020 +0900 + + [UI][Qt][WIN32] Fix closing D77/D88 image when select another slot. + +commit 6ec6e4cf3c15e08a89f75bca246ce1ae051c36cb +Author: K.Ohta +Date: Mon Jan 6 01:48:56 2020 +0900 + + [Qt][GLES3] Win32: More fix shader-compilation errors with Angle Project. + +commit 9414657204c9527b22ee634053d8dfc8012d188c +Author: K.Ohta +Date: Mon Jan 6 01:41:14 2020 +0900 + + [Qt][OpenGL_ES] Win32: Fix shader compilation errors with Angle Project. + +commit 9e94bf171ae7d7a443da159ef24b0f353351b043 +Author: K.Ohta +Date: Sun Jan 5 22:19:45 2020 +0900 + + [Unix] Update installer. + +commit a893e3fd6aa12e5ce15f7c09693e7a070fd8c549 +Author: K.Ohta +Date: Sun Jan 5 22:00:41 2020 +0900 + + [DOC] . + +commit de45e931c3ad246a60fe430d489e10e66ac14ae0 +Author: K.Ohta +Date: Sun Jan 5 21:04:53 2020 +0900 + + [DOC] Update ChangeLog. + +commit 3d5521747ed59ea8b8a462604fe31b1c20f76f00 +Author: K.Ohta +Date: Sun Jan 5 21:02:51 2020 +0900 + + [DOC] Update ChangeLog, gitlog. + +commit e327e2060d37129fed5cb150cbae8ef943fc03f8 +Author: K.Ohta +Date: Sun Jan 5 20:46:59 2020 +0900 + + [DOC] Prepare to release 2020-01-05. + +commit 6c12d47a9734658a4a34e75c5b0ba990fd5fbb58 +Author: K.Ohta +Date: Sun Jan 5 20:35:27 2020 +0900 + + [VM][MZ2500] Merge Upstream 2019-12-31. + +commit 04a5e471d5e8f4578849169a5fd3082dacdf072f +Author: K.Ohta +Date: Wed Dec 25 23:52:05 2019 +0900 + + [VM][X1] Merge UPSTREAM 2019-11-03 (2019-10-28/10-22). + +commit dfaec19a07d9feb679dfbaedd8d77256f0214093 +Author: K.Ohta +Date: Wed Dec 25 23:49:30 2019 +0900 + + [VM][PC9801][COMMON] Merge UPSTREAM 2019-11-03. + +commit 39f03478602be67e54c5b7037ef6b3ed03729929 +Author: K.Ohta +Date: Wed Dec 25 18:42:13 2019 +0900 + + [VM][PCENGINE][ADPCM] Fix stopping with command 60h(REPEAT PLAY).Fix not sounding BOSS round at Valis2, but still hangs up. + +commit bd77f0d6f809c8d0743c095f54cfaf47ea166f33 +Author: K.Ohta +Date: Tue Dec 24 18:54:15 2019 +0900 + + [VM][SCSI_CDROM] WIP: Fixing not play game at Valis 1. + +commit 764ae51dcea9747163911b0ff9923fbd52c3ed54 +Author: K.Ohta +Date: Tue Dec 24 17:23:17 2019 +0900 + + [VM][PCENGINE][ADPCM] Add comments. + +commit 8b27321fcc6a86b1be306604e41ce6db696d86f5 +Author: K.Ohta +Date: Tue Dec 24 17:21:32 2019 +0900 + + [VM][CDROM] CD-DA: Fix playing beyond multiple tracks.Fix freezing some CD-ROM^2 games for PC-Engine (i.e. Vails series). + +commit 491426312249cdd760b4ec977ffd5cc4079f4fd0 +Author: K.Ohta +Date: Mon Dec 16 13:29:11 2019 +0900 + + [VM][FMTOWNS][UPD71071][DMAC] . + +commit 39e178fb5ea9065e5151aecad207c28da058abf8 +Author: K.Ohta +Date: Mon Dec 16 13:25:01 2019 +0900 + + [VM][UPD71071] do_dma() : Split to tiny functions. + +commit 787ba502ade25d01c9a6c445e85959d917f4ddd1 +Author: K.Ohta +Date: Mon Dec 16 13:09:00 2019 +0900 + + [VM][UPD71071] Prepare address extend for uPD71071 (for Towns). + +commit 6c1c2509c8d41e3631cb2b5549f0dbc1e36f9f13 +Author: K.Ohta +Date: Sun Dec 15 21:31:49 2019 +0900 + + [VM][SCSI_DEV] Comment out duplicated writing to SIG_SCSI_DAT. + +commit 73fbc347d77163b342527a45b18a6f71994b65a7 +Author: K.Ohta +Date: Sun Dec 15 15:21:40 2019 +0900 + + [VM][COMMON_VM] Include IO:: class to common_vm. + [VM][COMMON_VM] MEMORY:: ; update API. + +commit f9c9118d4fabcb03813aec19fcacea5aff430ae1 +Author: K.Ohta +Date: Tue Dec 3 01:57:33 2019 +0900 + + [VM][BMJr] Fix FTBFS. + +commit 52bdedc565fa5cb02e869a1f2274f5a47fd90836 +Author: K.Ohta +Date: Mon Dec 2 20:05:32 2019 +0900 + + [VM][I386] Reduce compiler warnings. + +commit ea4bcfbaa18f88d2af5e56dc7a996d48848f2838 +Author: K.Ohta +Date: Mon Dec 2 20:04:46 2019 +0900 + + [VM] Apply before commit to some VMs. + +commit 30dff61489cc6b2db6c7cf79674dfba32920071c +Author: K.Ohta +Date: Mon Dec 2 20:02:37 2019 +0900 + + [VM][COMMON_VM] Add MEMORY:: (vm/memory.[cpp|h]) to libCSPcommon_vm. + +commit 6c5b7e7612246fb0db6fce145f25c1b84f32adda +Author: K.Ohta +Date: Mon Dec 2 04:17:49 2019 +0900 + + [VM][FMTOWNS] CMOS includes to DICTIONARY. + +commit 65d9cb3547add2cfb4e78c39f361301b9bd2dfa6 +Author: K.Ohta +Date: Mon Dec 2 04:16:55 2019 +0900 + + [VM][FMTOWNS] Update APIs. + +commit e0defc47dc9373d4a76581e828a4a95d82a316a2 +Author: K.Ohta +Date: Sun Nov 17 20:51:03 2019 +0900 + + [VM][FMTOWNS][SERIAL_ROM] . + +commit a92f64cdd87cfb34c9ae38deebe5a83c986b1a7d +Author: K.Ohta +Date: Sun Nov 17 20:46:15 2019 +0900 + + [VM][FMTOWNS][SERIAL_ROM] Improve register sequence, and manipulate via read_io8() and write_io8(). + +commit edb940447c084b7cf6197261fd0694f8384b3368 +Author: K.Ohta +Date: Sun Nov 17 20:18:29 2019 +0900 + + [VM][FMTOWNS] More simple implement of serial rom. + +commit aab7762f034a08cb782d9786e4312d73cca82332 +Author: K.Ohta +Date: Tue Nov 5 23:17:49 2019 +0900 + + [Qt][KEYBOARD] . + +commit 5226d9a22a3435e5fa7918c3d25b485d6e30b5e0 +Author: K.Ohta +Date: Tue Nov 5 23:05:57 2019 +0900 + + [VM][BMJR][FAMILYBASIC][FP1100][M5][MULTI8][MAP1010] Apply before commit to some VMs. + +commit 29f0a0fa0d4a6bb2c3b29b415fee45a09c8e5054 +Author: K.Ohta +Date: Tue Nov 5 23:02:53 2019 +0900 + + [Qt][OSD][KEYBOARD] Remove some obsoleted defines. + +commit eb8afea31457a7052d2e32dae28726d26ffbd0ac +Author: K.Ohta +Date: Tue Nov 5 21:39:59 2019 +0900 + + [VM][M5] Fix keyboard input, separate BOTH LSHIFT and RSHIFT. Expect to fix issue of https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/617. + +commit 8ebda574f0cbe9362081202a24092d3097a46e0d +Author: K.Ohta +Date: Mon Oct 28 03:39:14 2019 +0900 + + [Qt][AVIO] Replace fprintf() to logging functions. + +commit 11b6b076a4dc6adf85eea347b5d4c013d049b4fd +Author: K.Ohta +Date: Mon Oct 28 03:38:04 2019 +0900 + + [Qt][OpenGL4.5] Fix not map buffer to screen on most (not all) of emulators. + +commit db92e0360d8ff1bd88f7abd4a52b86ef0e0e38c2 +Author: K.Ohta +Date: Sun Oct 27 20:36:30 2019 +0900 + + [UI][Qt][ABOUT_DIALOG] Print OpenGL version within dialog. + [UI][Qt][ABOUT_DIALOG] Maybe improve credit displaying. + +commit 387492b106c468fb0c578141671439ce11c21a37 +Author: K.Ohta +Date: Sun Oct 27 18:33:57 2019 +0900 + + [Qt][OPenGLES] Add entry for OpenGL ES 3.1. + +commit a5484aece0385b09f6604f557666a07ff60ec513 +Author: K.Ohta +Date: Sun Oct 27 00:14:03 2019 +0900 + + [Qt][DRAW] . + +commit ad31d6b40b2946a50b49e095a65bb05e04052ba5 +Author: K.Ohta +Date: Sun Oct 27 00:06:52 2019 +0900 + + [Qt][OpenGL][GL4.5] Fix not capture GPU snapshot from RENDERDOC. + +commit 96397b22bf0f4744ae0577ef08df658cdacd411c +Author: K.Ohta +Date: Sat Oct 26 20:14:46 2019 +0900 + + [DOC] Add CrossBuild_Win32.ja.txt. + +commit 3ffb0eaa6ff35516a5f7d4588c48a17f7ac1065f +Author: K.Ohta +Date: Sat Oct 26 08:06:58 2019 +0900 + + [Qt][OpenGL] GLPack:: Selective texture having (or not) ALPHA CHANNEL. + +commit f1ad1f9fb4cfbdf9cbc56e79a97df905aa9c59d7 +Author: K.Ohta +Date: Sat Oct 26 04:53:08 2019 +0900 + + [Qt][OpenGL][GLES2] Optimize shaders. + [Qt][OpenGL][GLES2] Optimize usage of textures. + +commit 79bd5e5cc46ff5b0a4e6e70fd56efb7537cb7947 +Author: K.Ohta +Date: Sat Oct 26 04:51:47 2019 +0900 + + [Qt][OpenGL][GL3] Fix using color space; yiq to ycrcb. + [Qt][OpenGL][GL3] Use half float textures if enabled. + +commit 7d9ad385c737ee29cf19c4d0d005111fe2b0d3d5 +Author: K.Ohta +Date: Sat Oct 26 04:50:46 2019 +0900 + + [Qt][OpenGL][GL4.5] Use HALF FLOAT TEXTURE if enabled to reduce GPU usage (mostly NTSC shader PASS2). + +commit a7358eb12a56b48d621934ee105aaf85129a21d8 +Author: K.Ohta +Date: Wed Oct 23 01:30:36 2019 +0900 + + [VM][FM7][DISPLAY] Simplify logic of draw_screen(). + +commit d2d4ba9923f481352083125e0c24573910890835 +Author: K.Ohta +Date: Mon Oct 21 05:51:35 2019 +0900 + + [VM][FM7][VRAM][WIP] More simpleness rendering.This is WORK-IN-PROGRESS. + +commit 404de1fc72315a6995fbdcfca3b018f7eccfc7e4 +Author: K.Ohta +Date: Mon Oct 21 05:51:06 2019 +0900 + + [Qt][DRAW_THREAD] More adjust scheduler. + +commit 8371fcfd892c95d4bef3e5be97a2845c422691e9 +Author: K.Ohta +Date: Mon Oct 21 03:48:16 2019 +0900 + + [Qt][OpenGL][4.5] NTSC SHADER: Adjust scale factor. + +commit 89e0ad9c2c740b1ce9688650172b8fb9b9935476 +Author: K.Ohta +Date: Mon Oct 21 03:47:17 2019 +0900 + + [Qt][DRAW_THREAD] New (more accurate) draw scheduler. + +commit 95837f990f6cdf1656168bd1f37aa9708a67aef9 +Author: K.Ohta +Date: Mon Oct 21 03:45:21 2019 +0900 + + [VM][FM77AV][VRAM] Fix crash with opening of LUXOL. + +commit c7081598f2a1fb46c5b6f35da267e62d887425f1 +Author: K.Ohta +Date: Sun Oct 20 15:37:11 2019 +0900 + + [Qt][OPENGL][GL4.5] Tuning around "TV Renderer". + +commit aff814ae96e93c83e6a7ec386d0d7b35d75b6d3d +Author: K.Ohta +Date: Sat Oct 19 22:50:39 2019 +0900 + + [VM][FMTOWNS][SPRITE] Simplify logics.Now disable to use cache. + +commit f6211b39a816a61c1bc90ab788029205aa6cc6ec +Author: K.Ohta +Date: Tue Oct 15 13:28:19 2019 +0900 + + [TOOL][INSTALLER][OOPs] I forgot update installer.Updated (;_;) + +commit 22ef8f6eeabdf0b8fbe545928ee2c03017dd2e05 +Author: K.Ohta +Date: Tue Oct 15 02:42:47 2019 +0900 + + [DOC] Update documents. + +commit 74c7914381802640510c76f176b3c3ffeceb678d +Author: K.Ohta +Date: Tue Oct 15 02:19:11 2019 +0900 + + [DOC][DUMPCHECK] . + +commit 3b94006f820e808876d62631c42f0b3e11ad3990 +Author: K.Ohta +Date: Tue Oct 15 02:17:29 2019 +0900 + + [DOC][DUMPCHECK] Add document. + +commit c8513abd5bcf9159fa3d430329f5ad88317d531b +Author: K.Ohta +Date: Tue Oct 15 01:40:22 2019 +0900 + + [VM][PC9801][CPUREG] V30 SUB CPU works. + +commit 0aa814aec48526931dfe6e7fec33312ee094dd37 +Author: K.Ohta +Date: Mon Oct 14 05:27:25 2019 +0900 + + [Qt][AVIO] Fix FTBFS with older FFMpeg. + +commit aa57ec7fae3928116ae8cffaf97c1fd655f35059 +Author: K.Ohta +Date: Mon Oct 14 05:20:39 2019 +0900 + + [Qt][OpenGL] Don't makeCurrent()/doneCurrent() inside of resizeGL().Fixed crash running within Docker container. + +commit 9c18fc9259f1042e464eab4e85a60c8371122569 +Author: K.Ohta +Date: Mon Oct 14 03:19:01 2019 +0900 + + [VM][PC8801] Fix double install DEBUGGER:: for OPN#1,#2.Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/598 . + +commit c01549d4c0e0b80f5505a4794064e96304ec3cf7 +Author: K.Ohta +Date: Sun Oct 13 05:18:48 2019 +0900 + + [VM][PC8801] Remove unneeded comment outed lines. + +commit 6e48f01b78bceed325d515fec186aa707f8d8f6f +Author: K.Ohta +Date: Sun Oct 13 05:14:25 2019 +0900 + + [VM][EVENT] Fix wrong effect of before commit.Revert "High resolution accum_clocks" of EVENT::drive().STATE_VERSION is reverted to 4. + [VM][EVENT] Update comment of scheduler (EVENT::drive()). + [VM][EVENT] . + [VM][I386] . + +commit 4fee6d8db9e9880a893b3c2f48af66e10026ce61 +Author: K.Ohta +Date: Sat Oct 12 04:24:02 2019 +0900 + + [Qt][PC9801] Update UI. + +commit 658ecd0226e1238aa08b3d07f13b04ec5f973432 +Author: K.Ohta +Date: Sat Oct 12 04:23:21 2019 +0900 + + [VM][V30][I386] Adjust halt sequence.WIP. + +commit 7ed453ad816789dfd5bc37b4b7b44462b8207f66 +Author: K.Ohta +Date: Sat Oct 12 04:22:07 2019 +0900 + + [VM][PC9801] Re-define DIPSW, to work with V30@PC-9801RA. + +commit 0d330a3a567fba627168adf0377a6d4fdf2858c1 +Author: K.Ohta +Date: Fri Oct 11 19:18:25 2019 +0900 + + [VM][V30] . + +commit aad9f33ab5e526374ad6472f36ca749e2ef638ec +Author: K.Ohta +Date: Fri Oct 11 19:16:47 2019 +0900 + + [VM][I8259][PC9801] Fix crash when changing V30 Sub CPU <-> i286/i386 Main CPU. + +commit e3d809ce03c16ce4cecd41aad159f9326fb02dac +Author: K.Ohta +Date: Fri Oct 11 19:15:20 2019 +0900 + + [VM][EVENT] Clock ratio resolution was changed from 2^10 to 2^12. + [VM][EVENT] More safer scheduling when host cpu spend a lot of clocks. + +commit 364710984d43d2ec63f6bb6cb611bcb021f62ab0 +Author: K.Ohta +Date: Fri Oct 11 16:05:40 2019 +0900 + + [Qt] . + +commit e7ac176d71fbdb2865ebe4a649d536c0a945961a +Author: K.Ohta +Date: Fri Oct 11 16:04:37 2019 +0900 + + [VM][I386][V30] Fix cloick handling when BUSREQ/HALT. + +commit 1ef0c1a88ebacd4554196ae591907807c9477cc5 +Author: K.Ohta +Date: Fri Oct 11 16:00:01 2019 +0900 + + [VM][EVENT] Remove scheduler per CPU_TYPE, because optimize of calling virtual functions may be enough to fast. + [VM][EVENT] EVENT::drive() : Allow larger clock usage for sub CPUs; limit is 255 host clocks.Fix lockup scheduler of PC-9801RA with enabling V30 sub cpu. + +commit 6a34194446dde36a03030f1afbbbe82ecb6a01e8 +Author: K.Ohta +Date: Tue Oct 8 17:51:55 2019 +0900 + + [VM][FAMILYBASIC] Enable to input kana via romaji-kana conversion.Still some characters (i.e. KAGIKAKKO) are not correct. + +commit cf5b3ae2475e143c03bf02ded91322a9892c7435 +Author: K.Ohta +Date: Tue Oct 8 17:49:22 2019 +0900 + + [EMU][ROMAJI_KANA] Some characters are enabled to input via ROMAJI-KANA conversion. + [EMU][AUTOKEY] Some characters are enabled to input via pasting from clipboard. + [UI][Qt][ROMAJI_KANA] Some characters input from KANA mode (by host) are enabled. + +commit e7cca9698b99fb9303c8fcb4184f3521b11e27c1 +Author: K.Ohta +Date: Mon Oct 7 07:32:10 2019 +0900 + + [UI][Qt][AUTO_KEY] Copy and paste: Paste even Zenkaku KATAKANA/HIRAGNA/ASCII to VM (converted to Hankaku letters). + +commit 6dc77cb112b4239d88b12836839917d09abac184 +Author: K.Ohta +Date: Mon Oct 7 01:32:24 2019 +0900 + + [VM][FAMILYBASIC][WIP] Fix wrong string for romaji-kana (and auto key).Still imcoplete, implementing DAKUION,will fix. + +commit f0cea7e39d883c803002bd0c2ce41d3b4e48c60a +Author: K.Ohta +Date: Mon Sep 30 23:45:14 2019 +0900 + + [Tools] Add DUMP LIST CHECKER.Document will write. + +commit 2f5ccd70fa37c13d38b5063ea0420d81c755b87c +Author: K.Ohta +Date: Thu Sep 26 17:41:11 2019 +0900 + + [BUILD][WIN32] Update templete. + +commit 0265a3c66662b95a5223912f5ad0fb18b89002dc +Author: Kyuma Ohta +Date: Wed Sep 25 00:24:39 2019 +0000 + + [BUILD][CMAKE] LLVM: Build against FFMpeg 4.2. + +commit 95d6ef6a85d108b4f1691e7758bf24f3354e8206 +Author: K.Ohta +Date: Wed Sep 25 08:04:31 2019 +0900 + + [CONFIG][WIN32] Re-enable to use Get/WritePrivate** as MyGet/Write**. + +commit df421e6d050394ffa40713e04117e11d7850a237 +Author: K.Ohta +Date: Wed Sep 25 07:59:37 2019 +0900 + + [Qt][JOY_THREAD] Fix memory leak when plug/unplug joystick. + +commit c4e98c4113bafd3b2b0111272a99a96f3e3b9e28 +Author: K.Ohta +Date: Wed Sep 25 07:52:59 2019 +0900 + + [WIN32][CONFIG] Get rid of Assigned joystick. + +commit 1ea12d17a034df07dfb9e9c8380c10caa5326cf8 +Author: K.Ohta +Date: Wed Sep 25 07:46:01 2019 +0900 + + . + +commit ad310a5d95f6053e3020c27a7d980b0623e8c525 +Author: K.Ohta +Date: Wed Sep 25 07:40:22 2019 +0900 + + . + +commit 271617a4a5642c1752abd4be969067af6875e766 +Author: K.Ohta +Date: Wed Sep 25 07:38:29 2019 +0900 + + . + +commit 3d9176170f8d236eb152bf557643554b3cd2b644 +Author: K.Ohta +Date: Wed Sep 25 07:27:25 2019 +0900 + + [CONFIG] . + +commit ed3ee99fad2f7d24fe8ca248aedec8735f3cde9a +Author: K.Ohta +Date: Wed Sep 25 07:22:27 2019 +0900 + + . + +commit 90fff6b997b718dc248971144d6f68e064053e90 +Author: K.Ohta +Date: Wed Sep 25 07:12:00 2019 +0900 + + . + +commit 2d4ec9b6b6cb49ae6d9f1df7655e163c7789502b +Author: K.Ohta +Date: Wed Sep 25 06:57:26 2019 +0900 + + [WIN32][COMMON][CONFIG] Stop to use Junk GetPrivateProfileInt() and Get/WritePrivateProfileString(). + +commit ba8a7fa33c5db263b33424ddc51801a4b5f1f6d1 +Author: K.Ohta +Date: Wed Sep 25 06:35:23 2019 +0900 + + [Qt][MOVIE_SAVER][CONFIG] Some functions make dllexport. + +commit 16dae15140f7df49163cb4168d49e09a733ac846 +Author: K.Ohta +Date: Tue Sep 24 20:42:16 2019 +0900 + + [BUILD][WIN32][CMAKE] . + +commit 50241ea85a2e1ac6a310fe27eb36a13aa27d93f4 +Author: K.Ohta +Date: Tue Sep 24 20:02:37 2019 +0900 + + [BUILD][CMAKE][WIN32] Fix Typos. + +commit 6f3d85b7ae022268e4705a9138558d429fb70d8e +Author: K.Ohta +Date: Tue Sep 24 19:18:54 2019 +0900 + + [BUILD][WIN32][CMAKE] Fix TYPO in build script. + +commit 0f3680febadc8f0c17e79d3f9eb2f42f2f47faae +Merge: 2f9c613f 06223d21 +Author: K.Ohta +Date: Tue Sep 24 19:02:49 2019 +0900 + + Merge branch 'master' of github.com:Artanejp/common_source_project-fm7 + +commit 06223d216c1323ec3ce7c55570c348b4a8f424e4 +Author: Kyuma Ohta +Date: Tue Sep 24 09:58:32 2019 +0000 + + [BUILD][CMAKE][WIN32] Add support cross-build with CLANG-MinGW-w64.You may use with dockered environment, see https://github.com/mstorsjo/llvm-mingw . + +commit 81373c46b1d0fd78d63873a13357e51ee79d13cd +Author: Kyuma Ohta +Date: Tue Sep 24 09:55:45 2019 +0000 + + [COMMON][WIN32] Fix FTBFS with CLANG-MINGW-w64. + +commit 8fa9640533308f400d760157ba02af177e599e16 +Author: Kyuma Ohta +Date: Tue Sep 24 09:54:39 2019 +0000 + + [VM][I386][UPD7810] Fix FTBFS with CLANG/MINGW-W64 (cross build). + +commit 2f9c613f8a6a1cc205eb394e552be5dfe82f84b5 +Author: K.Ohta +Date: Tue Sep 24 18:23:01 2019 +0900 + + . + +commit 0e58074cb5337d0de709c83d141447bcd3b41da0 +Merge: 71faf66e d4098528 +Author: Kyuma Ohta +Date: Tue Sep 24 06:29:49 2019 +0000 + + Merge branch 'master' of github.com:Artanejp/common_source_project-fm7 + +commit 71faf66e8b5148be6e6f03df619e58c906a2eb3d +Author: Kyuma Ohta +Date: Tue Sep 24 06:29:34 2019 +0000 + + . + +commit d4098528f82390b1911babdfc2ad12342d46b146 +Author: K.Ohta +Date: Tue Sep 24 15:27:28 2019 +0900 + + [WIP][BUILD][CMAKE][WIN32] Integrating cross-build and non-cross-build. + +commit 781ecce7e8936f9845681aaf7ca8eb2936cf2048 +Merge: 6bc9dacb 93616c56 +Author: K.Ohta +Date: Sun Sep 22 21:58:46 2019 +0900 + + [VM][FMTOWNS] Merge branch 'tokumeiwokiboushimasu-master' + +commit 93616c563ca5f31f2236d56d91bc5d614caf5568 +Merge: 6bc9dacb da2a3611 +Author: K.Ohta +Date: Sun Sep 22 21:56:23 2019 +0900 + + Merge branch 'master' of https://github.com/tokumeiwokiboushimasu/common_source_project-fm7 into tokumeiwokiboushimasu-master + [VM][FMTOWNS][CRTC] Fix typo.Thanks to tokumeiwokibousimasu-san! + +commit 6bc9dacb6f2f6d6dee466447dd4515a551310e04 +Author: K.Ohta +Date: Sun Sep 22 21:02:27 2019 +0900 + + [VM][FM7][SOUND] Fix reading value of PSG register(s).Fix sound of FM-7's demonstration with FM-7/77 (not with 77AV variants). + [VM][FM7][SOUND] Separate reset sequence for OPN/WHG/THG/PSG to a common function. + [VM][FM7] Replace printf debug messages to out_debug_log(). + +commit 7b5f39fc3ee93fcb44d9729c131d8a78b486bb36 +Author: K.Ohta +Date: Sun Sep 22 19:16:09 2019 +0900 + + [Qt][OpenGL][GLES] Fix texture format for float/half float.May work "TV RENDERER" with Win32 build (via ANGLE). + [Qt][OpenGL] Use half float texture for float textures to reduce GPU usage. + +commit ff20832654d33ffe5161f7ed05dc5165b2bdf9ae +Author: K.Ohta +Date: Sun Sep 22 05:20:03 2019 +0900 + + [VM][FMTOWNS][CRTC] WIP: Implement screen width and height. + +commit 51c2bf995b9cfbf09db4f03deba3ec3a96643cb2 +Author: K.Ohta +Date: Sun Sep 22 04:17:10 2019 +0900 + + [VM][FMTOWNS][CRTC] . + +commit 259cfd5730153f32d687c4e906edfabbcac102b3 +Author: K.Ohta +Date: Sun Sep 22 03:35:51 2019 +0900 + + [VM][FMTOWNS][CRTC] Add comment.ToDo : Will support sprite. + +commit 469c76f18d21537f0ed00567f45331c01a7c083d +Author: K.Ohta +Date: Sun Sep 22 03:27:35 2019 +0900 + + [VM][FMTOWNS][DISPLAY][CRTC] Update implements. + +commit 22b86435921511aa3914067519a90d1c8ad21b85 +Author: K.Ohta +Date: Sat Sep 21 05:34:09 2019 +0900 + + [VM][FMTOWNS][VRAM] . + +commit da2a3611267ba5390d11fedeaf2b503e013f6160 +Author: tokumeiwokiboushimasu +Date: Fri Sep 20 07:58:15 2019 +0900 + + fix typo + +commit 0c2915d0dc3402234fd978ae7feba3a4b8d7e395 +Author: K.Ohta +Date: Thu Sep 19 23:34:50 2019 +0900 + + [VM][FMTOWNS][CRTC] . + +commit 7d0dc579d58ec7a762cb973825539efde55269ee +Author: K.Ohta +Date: Thu Sep 19 23:10:23 2019 +0900 + + [FMTOWNS][CRTC][WIP] Implementing render. + +commit 7c317634da826ca3be704685d2ecf3c323d494aa +Author: K.Ohta +Date: Thu Sep 19 01:54:03 2019 +0900 + + [VM][FMTOWNS][VRAM][CRTC] Apply new drawing feature.WIP. + +commit 4081dfd340aefd9e4083569dd396f85be2a4750f +Author: K.Ohta +Date: Sat Sep 14 00:47:49 2019 +0900 + + [VM][I286][JX] Fix FTBFS. + +commit 558956954eceacda0706997b9ee7874ea9fbb9f5 +Author: K.Ohta +Date: Sat Sep 14 00:22:04 2019 +0900 + + [VM][PC9801] Apply wait factors to before commit. + [VM][PC9801][CPUREG] TRY: Improve reset sequence.Still be imcomplete. + +commit 8b1aacb4fc40059d7b4689fe78ebf594354db779 +Author: K.Ohta +Date: Sat Sep 14 00:20:57 2019 +0900 + + [VM][Ix86][I386] More correctness wait. + [VM][Ix86][I386] Implement wait by memory-wait-factor. + [VM][Ix86][I386] Add SIG_CPU_HALTREQ. + +commit f615baf0f7facd35043882b1c4979be29df56aed +Author: K.Ohta +Date: Fri Sep 13 14:12:38 2019 +0900 + + [VM][FMTOWNS] MEMORY: Re-Implementing from MEMORY. + +commit d1734af52653f3644e20836915926e79daf304ec +Author: K.Ohta +Date: Fri Sep 13 03:24:12 2019 +0900 + + [OSD][SOUND][SDL] Convert sound rate/bitwidth. + +commit a8f89b31670b5cde504f41c80315255925ed53b2 +Author: K.Ohta +Date: Fri Sep 13 00:47:55 2019 +0900 + + [OSD][Qt][SOUND] Update sound APIs: for sound sampling.Still be imcomplete.Will implement. + [OSD][SOUND] Simplify sound callback for SDL. + [OSD][General] Fix not reply version of libvCSPosd.Display OSD version at "about this software". + +commit 24b79a5ecf7011ac38a4608f0dea5fc68de540e7 +Author: K.Ohta +Date: Mon Sep 9 18:33:39 2019 +0900 + + [Qt][AVIO] Add some codec entries (still not implement). + +commit 60d417e806719bd696a4aecb074aa1f07e421673 +Author: K.Ohta +Date: Mon Sep 9 18:09:53 2019 +0900 + + [Qt][AVIO] Finally,drop "deprected" APIs for FFMpeg 4.x(or 3.4)/ + +commit 015039f258b38677f7425ee6878cd0c3bcd8a788 +Author: K.Ohta +Date: Mon Sep 9 03:33:35 2019 +0900 + + [Build][CMAKE] Update SOVERSION. + +commit 430b9601f2dcf193a511dbab3a0deb424c479433 +Author: K.Ohta +Date: Mon Sep 9 03:31:42 2019 +0900 + + [Qt][AVIO][WIP] Drop to use deprecated functions for FFMpeg 4.x.This still disabled for MOVIE_SAVER. + +commit 8145c4bd553fe7de7270868b69c4a0bff7c4aba9 +Author: K.Ohta +Date: Wed Aug 28 04:43:04 2019 +0900 + + [CM][Z80DMA][OOPS] Disable debug spam. + +commit d0365074674a3d6cc830115b3eebb33dd60de1f5 +Author: K.Ohta +Date: Wed Aug 28 04:42:40 2019 +0900 + + [Qt][LOGGER] Threaded console logging. + +commit 7103aef34dff0841d2027838ebaaa915555db030 +Author: K.Ohta +Date: Tue Aug 27 22:51:48 2019 +0900 + + [UI][Qt][VM] Add keycode - vk - name table listing features.See vm/fm7/keyboard.cpp and qt/osd_base.h and gui/dialog_set_key.cpp. + +commit 41a62f0249c2f42c03026f57b0be5a5d0c1d4f04 +Author: K.Ohta +Date: Mon Aug 26 23:14:09 2019 +0900 + + [Qt][HOMEBREW] Fix not detected SDL at configuration of Qt::Gamepad. + +commit f62dbede1ae8c1525ef090bffb693f325a0f3b94 +Author: K.Ohta +Date: Mon Aug 26 22:18:15 2019 +0900 + + [Qt][GUI] Fix linkage error at libCSPgui.dll for Win32. + +commit 53ac6f7f0d34717294864804bc7f80856dd3b195 +Author: K.Ohta +Date: Mon Aug 26 09:08:37 2019 +0900 + + [QT][MOVIE_LOADER] Fix weird initilaizing memory. + +commit fc5203d9d4aedf4c4e85f49b2ae2ee9bfd43dd4b +Author: K.Ohta +Date: Mon Aug 26 08:55:51 2019 +0900 + + [Qt][LOADER] . + +commit f7a4dfd3da0bd9fcfced3d343d0dee3da1feade3 +Author: K.Ohta +Date: Mon Aug 26 08:49:52 2019 +0900 + + [Qt][MOVIE_LOADER][SOUND_LOADER] Will FIX FTBFS with FFMPEG 2.x. + +commit 2b5d20bea8fb0a6c66f98b94663d5a1da1ebc672 +Author: K.Ohta +Date: Mon Aug 26 08:18:31 2019 +0900 + + [Qt][MOVIE_LOADER][SOUND_LOADER] Update FFMPEG's API: Revoke to use functions marked as deprecate. + +commit f3104acc7e3cf0dd48f1f86075b22de14247790d +Author: K.Ohta +Date: Mon Aug 26 02:45:31 2019 +0900 + + [BUILD][CMAKE] Linux: Enable split symbols even using LLVM CLANG. + +commit ed2c81ffb78b53114fe62208cf49af50b542e64c +Author: K.Ohta +Date: Sun Aug 25 23:01:24 2019 +0900 + + [VM][PASOPIA] Fix FTBFS with LLVM CLANG. + +commit b150c24761bb617e97cdf541d7cb33e0adf73efd +Author: K.Ohta +Date: Sun Aug 25 17:51:59 2019 +0900 + + [BUILD][Qt][CMAKE] Update SOVERSION. + +commit d7666278251fc2d033a427acc60f018a9eeafa59 +Author: K.Ohta +Date: Sun Aug 25 17:51:04 2019 +0900 + + [VM][AY_3_891X] Fix pop noise when enabling lpf or hpf. + +commit b6f71179774c80f4a2df3d4ba041bc187822f18c +Author: K.Ohta +Date: Sun Aug 25 17:33:10 2019 +0900 + + [UI][Qt] . + +commit b1b9240b70b3bfd0ac655d935e3765a1cb755e2b +Author: K.Ohta +Date: Sun Aug 25 17:32:46 2019 +0900 + + [UI][Qt] Fix FTBFS with LLVM CLANG. + +commit c9374afc102d07cfe7b7ddf8c70341b1ca1b9959 +Author: K.Ohta +Date: Sun Aug 25 17:31:30 2019 +0900 + + [VM][FM7][PC9801] Fix FTBFSs with LLVM CLANG. + +commit 0c495a4851203edf617ed6311e747f78aae3baf4 +Author: K.Ohta +Date: Sun Aug 25 17:30:32 2019 +0900 + + [VM][COMMON_VM][DEBUGGER] Fix FTBFSs with LLVM CLANG. + [VM][MC6809] Fix duplicate signal; SIG_CPU_HALT. + +commit 7819e24c2fe422f12db57c4b91f7c80ab0cdb9f3 +Author: K.Ohta +Date: Mon Aug 19 02:49:49 2019 +0900 + + [UI][Qt] Add font selection to debugger and log view dialogs. + [Qt][CONFIG] Keep font metrics and window size of debugger and log viewer.Save to foo.ini file. + +commit 373681366e7eef2adc6120d5a46885eeec5bce96 +Author: K.Ohta +Date: Fri Aug 16 20:39:27 2019 +0900 + + [DOC] Re-Update. + commit 0810a8f8b9ba44cedc19bf6b8e903c9c1b5d6f04 Author: K.Ohta Date: Fri Aug 16 20:36:58 2019 +0900 diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100644 index 000000000..1d257fc61 --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,48 @@ +message("* Note: Recommended default values are placed at source/sample-scripts/ , please use them.") +message("* common/common") +# Build Common Sourcecode Project, Agar. +# (C) 2014 K.Ohta +# This is part of , but license is apache 2.2, +# this part was written only me. + +cmake_minimum_required (VERSION 2.8) +cmake_policy(SET CMP0011 NEW) + + +# Note: Belows are temporally disabled, not implemented older CMake. +#project (CSP +# DESCRIPTION "Common Source Code Project/Qt") +project (CSP) + +#ToDo +#set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") +set(USE_DEVICES_SHARED_LIB ON CACHE BOOL "Make devices as one shared library.") +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") + + +include(config) + +include(config_emufm7) +include(config_fm16) +include(config_fmr) +include(config_fmtowns) + +include(config_casio) +include(config_msx) +include(config_mz80_700) +include(config_pc6001) +include(config_pc8801) +include(config_pc9801) +include(config_x1) + +include(config_necmisc) + +include(config_toshiba) +include(config_epson) +include(config_sega) + +include(config_misccom) + +include(config_singleboards) + + diff --git a/source/ChangeLog b/source/ChangeLog index 5bef8b206..e6ce97b83 100644 --- a/source/ChangeLog +++ b/source/ChangeLog @@ -1,5 +1,266 @@ *** If you want to know full changes, please read 000_gitlog.txt and history.txt. *** +* SNAPSHOT September 26, 2020 + * Upstream 2020-04-06. + * [FMTOWNS/DMAC] Bootable TownsOS v1.1L30 based softwares. + Fix around DMA address mask. + See source/src/vm/fmtowns/00_status.ja.md. + * [General] Now, version of all DLLs/SOLIBs are 3.0.x. + * [DEVICE] Change API: special_reset(num). + This aimes to support FM-Towns's multiple special resetting. + * [I18N] Prepare to support multiple languages. + * [Draw/GL4_5] Wait until complete to mapping. + Fix crash with QUAZZLE (FMTOWNS;FSW Collection 10). + * [VM/FMTOWNS][OOPs] Fix fallthroughs. + * [VM/FMTOWNS] Add IC CARD feature. + * [FMTOWNS/CRTC] More simple logic at rendering. + * [FMTOWNS/CDROM] RESTORE/SEEK COMMAND (00h) must seek to lba0, then aimed lba. + * [FMTOWNS/CDROM] PAUSE COMMAND (85h) : Return extra status even isn't audio track. + * [FMTOWNS/CDROM] READ MODE1: May not need extra status, integrated after reading. + * [FMTOWNS/MEMORY] Integrate memory accessing to primitive inline functions. + * [FMTOWNS/CDROM][WIP] Status around CMD A0h. This is working-in-progress. + * [FMTOWNS/CDROM][WIP] TRY: Implement PIO transfer. + * [FMTOWNS/CDROM] Should read per a sector, not variable length. + * [FMTOWNS/CDROM] Implement pseudo burst transfer for DMA. + * [FMTOWNS/CDROM] Set CDDA_STATUS=CDDA_OFF before reading data. + Fix スーパーリアル麻雀PIV. + * [FMTOWNS/SPRITE] Initially works. + * [FMTOWNS/VRAM] Faster write access via write_memory_mapped_io[16|32]() . + * [FMTOWNS/TIMER] Disable free run counter before 1H/2H/1F/2F. + * [FMTOWNS/FLOPPY] Implement some bits and disk changed feature + (0208h:bit0:R after Towns2H/2F/1H/1F). + * [FMTOWNS/TIMER] Didable 1uS wait feature wait before xxF/xxH. + * [FMTOWNS/KEYBOARD] TRY: Boot with 'CD' 'H0' etc.Still works only with 'DEBUG'. + * [FMTOWNS/SCSI] Add SIG_SCSI_EOT signal. + * [FMTOWNS/SCSI] Set ctr_reg after sending command to host. + * [Qt/LOGGER] Fix not initialize (internal)osd_pointer; + wish to fix below issue (@Fedora Linux) + https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/935 + by this. + * [VM/I386_NP21] Memory access:Make functions inline to be faster processing. + * [VM/COMMON_VM] Fix warining of 'set_context_intr' hides overloaded + virtual function [-Woverloaded-virtual] with LLVM Clang++. + * [VM/MC6809] Remove MC6809_BASE::, integrated to MC6809:: . + * [VM/Z80] Remove Z80_BASE::, integrate to Z80:: . + * [VM/UPD7220] Limit address of PSET.More correctness clock feature. + * [VM/UPD71071] Fix tc bit down. + * [VM/UPD71071] Add some signals. + * [VM/UPD71071][FMTOWNS][MZ2800] Update API; Separate TC signals per a channel. + * [VM/UPD71071] SREQ is prior than MASK.Don't auto transfer at demand mode. + * [VM/UPD71071] Implement ENDx signal for stopping DMA from some devices. + + * [VM/I8259] Initialize registers by reset(). + * [EMU][UI/FLOPPY] Implement 1sec delayed open() for floppy, + fix not detect when changing from HISTORY. + * [X1/DRAW] Fix spending a lot of host CPU usage on draw_screen(). + This issue has happened at only X1 (not turbo) due to + memory aligns and cache lines. + Set alignment of RAM and some values. + * Built with 97db8d7a26eb8eeb7722b009456d7c9bcadda0f7 (or later). + +-- Sep 26, 2020 18:29:40 +0900 K.Ohta + +* SNAPSHOT June 27, 2020 + * Upstream 2020-04-06. + * [EMULATION] Now, emulation period is half of one frame. + Because some devices (i.e. mouse) seems to need a short period. + This may change to 1/4 of one frame (or not). + See event.cpp and qt/common/emu_thread.cpp (& more). + * [VM/EMU] Important: now EMU:: class inherits EMU_TEMPLATE:: . + * [VM/EVENT][Qt] execute event->drive() (or event->run()) by half frame. + This is workaround for choppy mouse pointer/joystick. + * [VM/FMTOWNS] Still works initially. + See source/src/vm/fmtowns/00_status.ja.md, + STATUS section of doc/VMs/fmtowns.txt + and 000_gitlog.txt . + * [VM/FMTOWNS] CDROM: Implement CMD 00h (SEEK) correctness. + May Fractal engine works.. + * [VM/DEVICE][DEBUGGER] Add Call trace feature to I386_NP21. + DEVICE::'s API HAS CHANGED. + * [VM/DEBUGGER] Add logging to "UCT" (Call trace) command. + * [VM][CONFIG] Add variable memory size feature to some VMs.See eFMTOWNS. + * [Qt/OpenGL4_5] Draw: Fix crash with external mapping (immutable storage). + Still not implement reading buffer. + * [COMMON/FIFO] Add FIFO::fifo_size() and FIFO::left().Update SOVERSION. + * [BUILD/CMake] Win32: Update toolchain for LLVM10.x and Ubuntu20.04 + (Has uploaded to + https://hub.docker.com/repository/docker/artanejp/mingw-w64-llvm10-ubuntu20.04/general ). + * [BUILD/Linux] Debian Sid: Now, build with CLANG 10 and Qt5.14. + * [VM/FMGEN][VM/YM2612][VM/FMTOWNS] Fix prescaler value, calculating for own OPN2. + * [VM/I386_NP21] Merge Upstream 2020-04-06 's I386::/NP21.Belows are differ from upstream: + - Make some memory access functions inline (these are bottoleneck of emulation). + - And some modifies are same as SNAPSHOT March 03, 2020. + * [VM/I386_NP21] Optimise for speed, make some functions __inline__ . + * [VM/I386_NP21] Fix EDX value at resetting. + * [VM/I386_NP21] Temporally enable FPU for i386. + * [VM/I386_NP21][DEBUGGER] WIP: Adding exception handling. + * [VM/I386_NP21] Log when made panic. + * [VM/I386_NP21] Add undefined instruction "0F A6". + This may act as "int 6".Thanks to Soji Yamakawa-San. + * [VM/I386_NP21] FPU: FISTTP INSNs (prefix DF) are only later than Pentium 4, + not exists I386/486/Pentium. + * [VM/I386_NP21] Disable FPU with I386, enable with I486SX. + * [VM/I386_NP21] Change FPUemul to DOSBOX2 (temporally). + * [VM/I386_NP21] Initialize CR0 to 0x00000000 (+some bits) for i386. + * [VM/I386_NP21] *Perhaps* REPNE MOVS[B|W|D] don't dedicate Z flag, + Thanks to Soji Yamakawa-San. + * [VM/I386_NP21] Fix FTBFS with LLVM CLANG++. + * [VM/I386_NP21] Add interrupt within rep prefix'ed ops. + * [VM/UPD71071] Modify handling of 16bit transfer mode. + * [VM/UPD71071] TOWNS_DMAC: Implement *truely* 16bit transfer feature + from Renesas(NEC Electronics)'s DATA SHEET. + * [VM/UPD71071] TOWNS_DMAC: Ugly workaround for 16bit transfer DMAC command. + Will fix. + * [VM/UPD71071] Change mean of TC bus bits (per channel).See mz2800.cpp. + * [VM/UPD71071] TOWNS_DMAC: Fix mandatory name with "mask" variable/arg. + * [VM/UPD71071] Adjust status of on-demand-mode. + * [VM/I8253] Add debugger feature, still reading only. + * [VM/DEBUGGER] Add "RH" command to debugger and + bool get_debug_regs_description(_TCHAR *, size_t) to API. + * [VM/FMTOWNS] FONTROMS: Add API read_direct_data8() to reading faster by CRTC. + * [VM/FM8] Fix warning from EVENT:: when resetting. + * [VM/SCSI] Add new (pseudo) SIGNAL for preparing to use buffered transfer. + * [Qt/LOGGER] Shrink redundant title. + * [VM/LOGGER][OSD][VM_TEMPLATE] Add API to log with VM's time. + * [OSD/Qt]Remove mouse position limiter. + * [UI/Qt] Virtual media: Adjust width of "HDx:". + * [UI/Qt] Add filename feature to Virtual-Media indicator. + * [UI/Qt] Adjust width for HDD. + * [UI/Qt][OSD] Add tooltip for virtual medias. + * [UI/Qt] CDROM: Add "SWAP BYTE ORDER for AUDIO" config entry. + * [OSD/Qt][LOGGER] Fix linkage error for LLD 10.x and Win32 cross. + * Built with d2322eb3793c06a3056ed10245d49c6a865a79d4 (or later). + +-- Jun 27, 2020 01:51:03 +0900 K.Ohta + +* SNAPSHOT March 03, 2020 + * Upstream 2020-02-21. + * [VM/FMTOWNS] Work initially. + See STATUS section for doc/VMs/fmtowns.txt and + 000_gitlog.txt . + * [VM/I386_NP21] Merge Upstream 2020-02-21 's I386::/NP21.Belows are differ from upstream: + - Implement memory wait to change CPU speed. + - Implement extra reset wire to notify CPU reset. + - Some headers are changed due to cause FTBFS with GCC. + - Character encoding chenged to UTF-8 at most of source files(not all?) + * [VM/I386] IMPORTANT: libcpu_newdev/i386 has removed.I386:: porting from NP21 seems to be working nice, no need to porting from MAME/C++. + * [UI/Qt] Add HARDDISK CREATION feature. + * [VM/HARDDISK] Calculate correctness C/H/S of HDD. + * [VM/SCSI_HDD][WIP] Implement RECALIBRATE SCSI command. + * [VM/SCSI_HDD][VM/SCSI_DEV] Implement some command.But still not active. + * [VM/BMJr] Fix Break sequence. Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/648 . + * [VM/BMJr] Fix reset-key (EIKIGOU + BREAK) sequence. + * [VM/BMJr] Alse assume Back Space key to DELETE key. + * [VM/BMJr] Also assume Esc key to BREAK key. + * [VM/FMGEN] Initial implemantation of YM2612 (OPN2). + * [VM/UPD71071] Make some functions make virtual to prepare overwrap by TOWNS_DMAC. + * [VM/DEVICE] Add update_signal_mask() to modify signal mask for SIG_SCSI_DAT for SCSI/SASI devices. + * [VM/COMMON_VM] Include SCSI devices to libCSPcommon_vm, excepts SCSI_HOST::. + * [VM/PCENGINE] ADPCM: Fix em-bugged freeze ADPCM DMA after CDC STATUS (write to I/O 1800h.) + * [VM/PC9801] 86PCM: Fix Initial value of PCM_MUTE(A66Eh).Adjust volume multiply factor. + * [BUILD/Windows] LLVM: Update Qt version to 5.14. + * [VM/PC9801] DISPLAY: Re-Backport from Upstream 2020-02-01.Kakinoki Syougi works fine. + * [VM/SCSI_CDROM] Fix freeze some PC-Engine's CD-ROM^2 games and SCSI HDD for FM-Towns. + * [Qt/OpenGL_ES] Win32: Fix shader compilation errors with Angle Project. + * [Qt/OpenGL] Correctness texture magnitude calculating. + * [UI/Qt] Win32: Fix closing D77/D88 image when select another slot. + * [UI/Qt] Harddisk: Add *.h0-*.h9 , they are Unz (Towns emulator)'s virtual harddisk images. + * [OSD/SOUND] Fix crash when effective sound sink don't exists. + * [Qt/OpenGL] Fix FTBFS if don't have libglu. + * [UI/Qt] Add "USE_CUSTOM_SCREEN_ZOOM_FACTOR" flag to fooVM.h. + * [UI/Qt] Try: Make GUI core (QApplication -> QCoreApplication) to be non-Global. + Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/719 . + * Built with fd1687a197f8e25788c8231a08e73fb3a5667763 (or later). + +-- Mar 03, 2020 15:13:25 +0900 K.Ohta + +* SNAPSHOT Jan 05, 2020 + * Upstream 2019-12-31. + * This is point release, still exists some issues (i.e.EMM386(NEC/PC98) and FreeBSD(98) don't work) for PC-9801 and PC-Engine and some VMs, will fix them. + * [PCENGINE/CD-ROM^2] More games work.Except some games (i.e. Valis1/2). + * [DOC] Add CrossBuild_Win32.ja.txt. + * [VM/FM77AV] VRAM: Fix crash with opening of LUXOL. + * [VM/FM7] DISPLAY: Simplify logic of draw_screen(). + * [VM/M5] Fix keyboard input, separate BOTH LSHIFT and RSHIFT. + Expect to fix issue of https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/617. + * [VM/COMMON_VM] Add MEMORY:: (vm/memory.[cpp|h]) to libCSPcommon_vm. + * [VM/COMMON_VM] MEMORY:: ; update API. + * [VM/COMMON_VM] Include IO:: class to common_vm. + * [VM/SCSI_DEV] Comment out duplicated writing to SIG_SCSI_DAT. + * [VM/UPD71071] Prepare address extend for uPD71071 (for Towns). + * [VM/UPD71071] do_dma() : Split to tiny functions. + * [VM/SCSI_CDROM] CD-DA: Fix playing beyond multiple tracks. + Fix freezing some CD-ROM^2 games for PC-Engine (i.e. Vails series). + * [VM/PCENGINE] ADPCM: Add comments. + * [VM/PCENGINE] ADPCM: Fix stopping with command 60h(REPEAT PLAY).Fix not sounding BOSS round at Valis2, but still hangs up. + * [VM/PCENGINE] SCSI_CDROM: WIP: Fixing not play game at Valis 1. + * [VM/I386] Reduce compiler warnings. + * [Qt/OpenGL] Use half float textures if enabled. + * [Qt/OpenGL] GL3: Fix using color space; yiq to ycrcb. + * [Qt/OpenGL] GLPack:: Selective texture having (or not) ALPHA CHANNEL. + * [Qt/OpenGL] GL4.5: Fix not capture GPU snapshot from RENDERDOC. + * [Qt/OpenGL] GL4.5: Fix not map buffer to screen on most (not all) of emulators. + * [Qt/OpenGL] GL4.5: Tuning around "TV Renderer". + * [Qt/OpenGL] GL4.5: NTSC SHADER: Adjust scale factor. + * [Qt/OpenGL] OpenGL ES: Add entry for OpenGL ES 3.1. + * [Qt/DRAW_THREAD] New (more accurate) draw scheduler. + * [Qt/ABOUT_DIALOG] Maybe improve credit displaying. + * [Qt/AVIO] Replace fprintf() to logging functions. + * [OSD/KEYBOARD] Remove some obsoleted defines. + * Built with e327e2060d37129fed5cb150cbae8ef943fc03f8 (or later). + +-- Jan 05, 2020 20:59:52 +0900 K.Ohta + +* SNAPSHOT Oct 15, 2019 + * Upstream 2019-04-30. + * This is point release, still exists some issues (i.e.EMM386(NEC/PC98) and FreeBSD(98) don't work) for PC-9801 and PC-Engine and some VMs, will fix them. + * [Tools] Add DUMP LIST CHECKER. + * [BUILD/Win32] Build with LLVM CLANG (for MinGW-w64).Because GCC for MinGW-w64/Win32 has very slow exception handling (due to Borland's patent). + * [BUILD/Win32] See https://github.com/Artanejp/llvm-mingw and https://hub.docker.com/r/artanejp/llvm-mingw64-ubuntu-cosmic for datails. + * [BUILD/Win32] Build against FFMpeg 4.2. + * [FM7/SOUND] Fix reading value of PSG register(s).Fix sound of FM-7's demonstration with FM-7/77 (not with 77AV variants). + * [FM7/SOUND] Separate reset sequence for OPN/WHG/THG/PSG to a common function. + * [VM/FM7] Replace printf debug messages to out_debug_log(). + * [VM/FAMILYBASIC] WIP: Fix wrong string for romaji-kana (and auto key).Still imcoplete, implementing DAKUION,will fix. + * [VM/PC9801] CPUREG: V30 SUB CPU works. + * [VM/PC9801] Re-define DIPSW, to work with V30@PC-9801RA. + * [VM/PC8801] Fix double install DEBUGGER:: for OPN#1,#2.Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/598 . + * [VM/MC6809] Fix duplicate signal; SIG_CPU_HALT. + * [VM/DEBUGGER] Fix FTBFSs with LLVM CLANG. + * [VM/AY_3_891X] Fix pop noise when enabling lpf or hpf. + * [VM/Z80DMA] OOPS: Disable debug spam. + * [VM/Ix86] More correctness wait. + * [VM/Ix86] Implement wait by memory-wait-factor. + * [VM/Ix86] Add SIG_CPU_HALTREQ. + * [VM/I386][VM/V30] Fix cloick handling when BUSREQ/HALT. + * [VM/I8259] PC9801: Fix crash when changing V30 Sub CPU <-> i286/i386 Main CPU. + * [VM/EVENT] Update comment of scheduler (EVENT::drive()). + * [EMU/ROMAJI_KANA] Some characters are enabled to input via ROMAJI-KANA conversion. + * [EMU/AUTOKEY] Some characters are enabled to input via pasting from clipboard.This using UCS-4(aka UTF-32) internal format. + * [Qt/OpenGL] Don't makeCurrent()/doneCurrent() inside of resizeGL().Fixed crash running within Docker container. + * [UI/Qt] ROMAJI_KANA: Some characters input from KANA mode (by host) are enabled. + * [UI/Qt] VM: Add keycode - vk - name table listing features.See vm/fm7/keyboard.cpp and qt/osd_base.h and gui/dialog_set_key.cpp. + * [Qt/LOGGER] Threaded console logging. + * [Qt/AVIO] Update FFMPEG's API: Revoke to use functions marked as deprecate. + * [Qt/AVIO] Drop to use deprecated functions for FFMpeg 4.x. + * [Qt/AVIO] Add some codec entries (still not implement). + * [OSD/Qt] Update sound APIs: for sound sampling.Still be imcomplete.Will implement. + * [OSD/SOUND] Simplify sound callback for SDL. + * [OSD/SOUND] SDL: Convert sound rate/bitwidth. + * [OSD/General] Fix not reply version of libvCSPosd.Display OSD version at "about this software". + * [QT/MOVIE_LOADER] Fix weird initilaizing memory. + * [Qt/MOVIE_SAVER] CONFIG: Some functions make dllexport. + * [Qt/HOMEBREW] Fix not detected SDL at configuration of Qt::Gamepad. + * [Qt/JOY_THREAD] Fix memory leak when plug/unplug joystick. + * [UI/Qt] Add font selection to debugger and log view dialogs. + * [UI/Qt] AUTO_KEY: Copy and paste: Paste even Zenkaku KATAKANA/HIRAGNA/ASCII to VM (converted to Hankaku letters). + * [Qt/CONFIG] Keep font metrics and window size of debugger and log viewer.Save to foo.ini file. + * [Qt/OpenGL] GLES: Fix texture format for float/half float.May work "TV RENDERER" with Win32 build (via ANGLE). + * [Qt/OpenGL] Use half float texture for float textures to reduce GPU usage. + * Built with 74c7914381802640510c76f176b3c3ffeceb678d (or later). + +-- Oct 15, 2019 02:40:49 +0900 K.Ohta + * SNAPSHOT Aug 16, 2019 * Upstream 2019-04-30. * This is point release, still exists some issues (i.e.EMM386(NEC/PC98) and FreeBSD(98) don't work) for PC-9801 and PC-Engine and some VMs, will fix them. diff --git a/source/RELEASENOTE.txt b/source/RELEASENOTE.txt index cdc5e90a1..1642d4727 100644 --- a/source/RELEASENOTE.txt +++ b/source/RELEASENOTE.txt @@ -1,6 +1,6 @@ ** Qt porting and FM-7/77/AV/AV40/EX for Common Source Code Project ** - August 16, 2019 + September 26, 2020 K.Ohta (whatisthis.sowhat _at_ gmail.com) 1.About @@ -10,7 +10,7 @@ and built with Qt5, for Windows, built with MinGW(32bit). Source Code: - https://github.com/Artanejp/common_source_project-fm7/releases/tag/SNAPSHOT_20190816 + https://github.com/Artanejp/common_source_project-fm7/releases/tag/SNAPSHOT_20200926 Additional INFO: @@ -52,9 +52,11 @@ h. Built with Qt5.5 (for Ubuntu 16.04LTS) or Qt 5.10 (for Win32 and Debian/Sid). i. Now, changed default drawing infrastructure to OpenGL ES2.You can change --opengl option via comman line (or GUI). +j. Now for Win32 build, using LLVM CLANG cross toolchains on Docker environment.Because exception handling of MinGW-w64's gcc is very slowly (this cause by *evil* Borland). + See https://github.com/Artanejp/llvm-mingw and https://hub.docker.com/r/artanejp/llvm-mingw64-ubuntu-cosmic for datails. + * TIPS: If emufoo.exe don't show screen drawing, set environment variable QT_OPENGL to software (i.e. Using Windows as VirtualBox's gueat OS). - 3.How to build: After extracting (or git pulled) sourcecodes: @@ -157,77 +159,80 @@ Special thanks to: Ryu Takegami-san, to assist debugging FM-7/77/AV/40/EX . Haserin-san, to assist debugging FM-7/77/AV/40/EX . Developers of Ootake, give hints of emuPCEngine (from source code). - + Soji Yamakawa-San, author of TOWNS emulater "津軽", + and advice for my development a lot. + Changes: * To see older changes, read ChangeLog and 000_gitlog.txt. -* SNAPSHOT Aug 16, 2019 - * Upstream 2019-04-30. - * This is point release, still exists some issues (i.e.EMM386(NEC/PC98) and FreeBSD(98) don't work) for PC-9801 and PC-Engine and some VMs, will fix them. - * [UI/Qt] DEBUGGER: Add history for debugger command line. - * [UI/Qt] DEBUGGER: Add auto-completion for command-line. - * [VM/DEVICE] Use __FASTCALL with interfaces, read_*() ,write_*(), fetch_op() and some functions.Make this faster emulation (i.e.PC-9801RA and EMM386 under FreeDOS). - * [VM/PC9801] Separate EGC functions. - * [VM/PC9801] Add V30@8.0MHz with some I286/I386 machines. - * [VM/PC9801] Check differnt of system work area (0000:0400-0000:05FF) both mame(pc9801rs) and emupc9801ra . - * [VM/PC9801] Add "UPPER_I386" flag for detect using later than HAS_I386. - * [VM/PC9801] CPUREG: (Maybe) improve changing cpu sequence around I/O 00F0h. - * [VM/PC9801] CPUREG: Redirect interrupt signal via CPUREG:: .VMs with V30 sub CPU (i.e.PC9801RA) work with V30. - * [VM/PC9801] Fix wrong initialize SYS_PORT_B. - * [VM/PC9801] Fix wrong initialize memory switch. - * [VM/PC9801] Add DIPSWITCH object. - * [VM/PC9801] Fix different value at [0000:0501]. - * [VM/PC9801] MEMBUS: Split update_bios() to functions. - * [VM/FP1100] Fix lacking some key symbols.Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/540 . - * [VM/AY_3_891X] Fix not supported defines, replace flags. - * [VM/AY_3_891X] Add feature ; dump/set register via debugger. - * [VM/YM2151] Add feature ; dump/set register via debugger. - * [VM/YM2203] Add feature ; dump/set register via debugger. - * [VM/SN74689AN] Add feature ; dump/set register via debugger. - * [VM/BEEP] Add feature ; dump register via debugger. - * [VM/PCM1BIT] Add feature ; dump register via debugger. - * [VM/I80x86/V30] Start debugger even halting. - * [VM/I80x86/8088/V30] Make i86/186/88/286 and V30 to common_vm. - * [VM/I386] Fix WRONG flag mask at LMSW. - * [VM/I386] MOV CR0 EyX : Fix wrong flags handling. - * [VM/I386] Exitable when falling into infinite TRAP-Loop. - * [VM/I386] mov CRx,R32/mov r32,CRx : Adjusting. - * [VM/i8259] Add PIC HACKing flag for PC9801. - * [VM/uPD7810/uPD7907] PC2001: Include uPD7810 variants and uPD7907 to libCSP_common_VM. - * [VM/MB8877] Fix buffer overflow with logging. - * [VM/Z80DMA] TODO/WIP: Workaround for https://tablacus.github.io/LSX-Dodgers/ .This still be not resolved issue. - * [VM/EVENT] Add remove_context_cpu().This may not effect to MAIN_CPU(id==0). - * [DOC/FM7] Fix typo (*ノω・*)てへぺろ - * [Qt/LOGGER] Improve locking. - * [UI/Qt] OOPs: Fix LACK of DATARECORDER BUTTONS(abolish of USE_TAPE_BUTTON): Lack of merging UPSTREAM 2018/10/07. - * [UI/Qt] MENU: Split some methods (of Ui_MainMenuBase::) to menu_emulator.cpp and menu_machine.cpp . - * [UI/Qt] MENU: Simplify menu creation. - * [CONFIG/Qt] Fix bit order of logging configure. - * [BUILD/CMAKE] Add CPU affinity mask when compiling.This may work only with GNU/Linux host. - * [BUILD/CMAKE] Improve build message with finished. - * [BUILD/MINGW] Update optimize parameter. - * [BUILD] Separate definitions of archtecture flags. - * [BUILD] Add ARM32/64 definitions (initial).Still not testing. - * Built with 0810a8f8b9ba44cedc19bf6b8e903c9c1b5d6f04 (or later). - --- Aug 16, 2019 20:38:06 +0900 K.Ohta +* SNAPSHOT September 26, 2020 + * Upstream 2020-04-06. + * [FMTOWNS/DMAC] Bootable TownsOS v1.1L30 based softwares. + Fix around DMA address mask. + See source/src/vm/fmtowns/00_status.ja.md. + * [General] Now, version of all DLLs/SOLIBs are 3.0.x. + * [DEVICE] Change API: special_reset(num). + This aimes to support FM-Towns's multiple special resetting. + * [I18N] Prepare to support multiple languages. + * [Draw/GL4_5] Wait until complete to mapping. + Fix crash with QUAZZLE (FMTOWNS;FSW Collection 10). + * [VM/FMTOWNS][OOPs] Fix fallthroughs. + * [VM/FMTOWNS] Add IC CARD feature. + * [FMTOWNS/CRTC] More simple logic at rendering. + * [FMTOWNS/CDROM] RESTORE/SEEK COMMAND (00h) must seek to lba0, then aimed lba. + * [FMTOWNS/CDROM] PAUSE COMMAND (85h) : Return extra status even isn't audio track. + * [FMTOWNS/CDROM] READ MODE1: May not need extra status, integrated after reading. + * [FMTOWNS/MEMORY] Integrate memory accessing to primitive inline functions. + * [FMTOWNS/CDROM][WIP] Status around CMD A0h. This is working-in-progress. + * [FMTOWNS/CDROM][WIP] TRY: Implement PIO transfer. + * [FMTOWNS/CDROM] Should read per a sector, not variable length. + * [FMTOWNS/CDROM] Implement pseudo burst transfer for DMA. + * [FMTOWNS/CDROM] Set CDDA_STATUS=CDDA_OFF before reading data. + Fix スーパーリアル麻雀PIV. + * [FMTOWNS/SPRITE] Initially works. + * [FMTOWNS/VRAM] Faster write access via write_memory_mapped_io[16|32]() . + * [FMTOWNS/TIMER] Disable free run counter before 1H/2H/1F/2F. + * [FMTOWNS/FLOPPY] Implement some bits and disk changed feature + (0208h:bit0:R after Towns2H/2F/1H/1F). + * [FMTOWNS/TIMER] Didable 1uS wait feature wait before xxF/xxH. + * [FMTOWNS/KEYBOARD] TRY: Boot with 'CD' 'H0' etc.Still works only with 'DEBUG'. + * [FMTOWNS/SCSI] Add SIG_SCSI_EOT signal. + * [FMTOWNS/SCSI] Set ctr_reg after sending command to host. + * [Qt/LOGGER] Fix not initialize (internal)osd_pointer; + wish to fix below issue (@Fedora Linux) + https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/935 + by this. + * [VM/I386_NP21] Memory access:Make functions inline to be faster processing. + * [VM/COMMON_VM] Fix warining of 'set_context_intr' hides overloaded + virtual function [-Woverloaded-virtual] with LLVM Clang++. + * [VM/MC6809] Remove MC6809_BASE::, integrated to MC6809:: . + * [VM/Z80] Remove Z80_BASE::, integrate to Z80:: . + * [VM/UPD7220] Limit address of PSET.More correctness clock feature. + * [VM/UPD71071] Fix tc bit down. + * [VM/UPD71071] Add some signals. + * [VM/UPD71071][FMTOWNS][MZ2800] Update API; Separate TC signals per a channel. + * [VM/UPD71071] SREQ is prior than MASK.Don't auto transfer at demand mode. + * [VM/UPD71071] Implement ENDx signal for stopping DMA from some devices. + + * [VM/I8259] Initialize registers by reset(). + * [EMU][UI/FLOPPY] Implement 1sec delayed open() for floppy, + fix not detect when changing from HISTORY. + * [X1/DRAW] Fix spending a lot of host CPU usage on draw_screen(). + This issue has happened at only X1 (not turbo) due to + memory aligns and cache lines. + Set alignment of RAM and some values. + * Built with 97db8d7a26eb8eeb7722b009456d7c9bcadda0f7 (or later). + +-- Sep 26, 2020 18:29:40 +0900 K.Ohta Upstream changes: * To see older upstream's changes, read history.txt. -4/30/2019 +4/6/2020 -[VM/DEVICE] add is_primary_cpu() and update_extra_event() -[VM/EVENT] support to udpate event while cpu is running one opecode -[VM/I8259] fix reading isr register (thanks Mr.rednow) -[VM/SCSI_HOST] fix to raise irq at command/message phase -[VM/Z80] improve to update event in every read/write cycle +[VM/I386_NP21] update to Neko Project 21/W ver0.86 rev72 -[CEFUCOM21] support Hino Electronics CEFUCOM-21 (not work) -[MZ2500/CRTC] apply crtc patch (thanks Mr.Koucha-Youkan) -[PC8801MA] improve to enable/disable cmdsing and pcg -[PC8801MA] improve to enable/disable changing palette for each scan line ----- diff --git a/source/build-cmake/3rdparty/FindLibAV.cmake b/source/build-cmake/3rdparty/FindLibAV.cmake deleted file mode 100644 index 2d1764052..000000000 --- a/source/build-cmake/3rdparty/FindLibAV.cmake +++ /dev/null @@ -1,202 +0,0 @@ -# Module for locating libav. -# -# Customizable variables: -# LIBAV_ROOT_DIR -# Specifies libav's root directory. -# -# Read-only variables: -# LIBAV_FOUND -# Indicates whether the library has been found. -# -# LIBAV_INCLUDE_DIRS -# Specifies libav's include directory. -# -# LIBAV_LIBRARIES -# Specifies libav libraries that should be passed to target_link_libararies. -# -# LIBAV__LIBRARIES -# Specifies the libraries of a specific . -# -# LIBAV__FOUND -# Indicates whether the specified was found. -# -# -# Copyright (c) 2012 Sergiu Dotenco -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTLIBAVLAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# From: https://github.com/bitmovin/libdash/blob/master/libdash/qtsampleplayer/FindLibAV.cmake -INCLUDE (FindPackageHandleStandardArgs) - -IF (CMAKE_VERSION VERSION_GREATER 2.8.7) - SET (_LIBAV_CHECK_COMPONENTS FALSE) -ELSE (CMAKE_VERSION VERSION_GREATER 2.8.7) - SET (_LIBAV_CHECK_COMPONENTS TRUE) -ENDIF (CMAKE_VERSION VERSION_GREATER 2.8.7) - -FIND_PATH (LIBAV_ROOT_DIR - NAMES include/libavcodec/avcodec.h - include/libavdevice/avdevice.h - include/libavfilter/avfilter.h - include/libavutil/avutil.h - include/libswresample/swresample.h - include/libswscale/swscale.h - PATHS ENV LIBAVROOT - DOC "libav root directory") - -FIND_PATH (LIBAV_INCLUDE_DIR - NAMES libavcodec/avcodec.h - libavdevice/avdevice.h - libavfilter/avfilter.h - libavutil/avutil.h - libswresample/swresample.h - libswscale/swscale.h - HINTS ${LIBAV_ROOT_DIR} - PATH_SUFFIXES include - DOC "libav include directory") - -if (NOT LibAV_FIND_COMPONENTS) - set (LibAV_FIND_COMPONENTS avcodec avdevice avfilter avformat avutil swresample swscale) -endif (NOT LibAV_FIND_COMPONENTS) - -FOREACH (_LIBAV_COMPONENT ${LibAV_FIND_COMPONENTS}) - STRING (TOUPPER ${_LIBAV_COMPONENT} _LIBAV_COMPONENT_UPPER) - SET (_LIBAV_LIBRARY_BASE LIBAV_${_LIBAV_COMPONENT_UPPER}_LIBRARY) - - FIND_LIBRARY (${_LIBAV_LIBRARY_BASE} - NAMES ${_LIBAV_COMPONENT} - HINTS ${LIBAV_ROOT_DIR} - PATH_SUFFIXES bin lib - DOC "libav ${_LIBAV_COMPONENT} library") - - MARK_AS_ADVANCED (${_LIBAV_LIBRARY_BASE}) - - SET (LIBAV_${_LIBAV_COMPONENT_UPPER}_FOUND TRUE) - SET (LibAV_${_LIBAV_COMPONENT}_FOUND ${LIBAV_${_LIBAV_COMPONENT_UPPER}_FOUND}) - - IF (${_LIBAV_LIBRARY_BASE}) - # setup the LIBAV__LIBRARIES variable - SET (LIBAV_${_LIBAV_COMPONENT_UPPER}_LIBRARIES ${${_LIBAV_LIBRARY_BASE}}) - LIST (APPEND LIBAV_LIBRARIES ${LIBAV_${_LIBAV_COMPONENT_UPPER}_LIBRARIES}) - LIST (APPEND _LIBAV_ALL_LIBS ${${_LIBAV_LIBRARY_BASE}}) - ELSE (${_LIBAV_LIBRARY_BASE}) - LIST (APPEND _LIBAV_MISSING_LIBRARIES ${_LIBAV_LIBRARY_BASE}) - ENDIF (${_LIBAV_LIBRARY_BASE}) -ENDFOREACH (_LIBAV_COMPONENT ${LibAV_FIND_COMPONENTS}) - -SET (LIBAV_INCLUDE_DIRS ${LIBAV_INCLUDE_DIR}) - -IF (DEFINED _LIBAV_MISSING_COMPONENTS AND _LIBAV_CHECK_COMPONENTS) - IF (NOT LibAV_FIND_QUIETLY) - MESSAGE (STATUS "One or more libav components were not found:") - # Display missing components indented, each on a separate line - FOREACH (_LIBAV_MISSING_COMPONENT ${_LIBAV_MISSING_COMPONENTS}) - MESSAGE (STATUS " " ${_LIBAV_MISSING_COMPONENT}) - ENDFOREACH (_LIBAV_MISSING_COMPONENT ${_LIBAV_MISSING_COMPONENTS}) - ENDIF (NOT LibAV_FIND_QUIETLY) -ENDIF (DEFINED _LIBAV_MISSING_COMPONENTS AND _LIBAV_CHECK_COMPONENTS) - -# Determine library's version - -FIND_PROGRAM (LIBAV_AVCONV_EXECUTABLE NAMES avconv - HINTS ${LIBAV_ROOT_DIR} - PATH_SUFFIXES bin - DOC "avconv executable") - -IF (LIBAV_AVCONV_EXECUTABLE) - EXECUTE_PROCESS (COMMAND ${LIBAV_AVCONV_EXECUTABLE} -version - OUTPUT_VARIABLE _LIBAV_AVCONV_OUTPUT ERROR_QUIET) - - STRING (REGEX REPLACE ".*avconv[ \t]+([0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1" - LIBAV_VERSION "${_LIBAV_AVCONV_OUTPUT}") - STRING (REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" - LIBAV_VERSION_MAJOR "${LIBAV_VERSION}") - STRING (REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" - LIBAV_VERSION_MINOR "${LIBAV_VERSION}") - STRING (REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\3" - LIBAV_VERSION_PATCH "${LIBAV_VERSION}") - - SET (LIBAV_VERSION_COMPONENTS 3) -ENDIF (LIBAV_AVCONV_EXECUTABLE) - -IF (WIN32) - FIND_PROGRAM (LIB_EXECUTABLE NAMES lib - HINTS "$ENV{VS110COMNTOOLS}/../../VC/bin" - "$ENV{VS100COMNTOOLS}/../../VC/bin" - "$ENV{VS90COMNTOOLS}/../../VC/bin" - "$ENV{VS71COMNTOOLS}/../../VC/bin" - "$ENV{VS80COMNTOOLS}/../../VC/bin" - DOC "Library manager") - - MARK_AS_ADVANCED (LIB_EXECUTABLE) -ENDIF (WIN32) - -MACRO (GET_LIB_REQUISITES LIB REQUISITES) - IF (LIB_EXECUTABLE) - GET_FILENAME_COMPONENT (_LIB_PATH ${LIB_EXECUTABLE} PATH) - - EXECUTE_PROCESS (COMMAND ${LIB_EXECUTABLE} /nologo /list ${LIB} - WORKING_DIRECTORY ${_LIB_PATH}/../../Common7/IDE - OUTPUT_VARIABLE _LIB_OUTPUT ERROR_QUIET) - - STRING (REPLACE "\n" ";" "${REQUISITES}" "${_LIB_OUTPUT}") - LIST (REMOVE_DUPLICATES ${REQUISITES}) - ENDIF (LIB_EXECUTABLE) -ENDMACRO (GET_LIB_REQUISITES) - -IF (_LIBAV_ALL_LIBS) - # collect lib requisites using the lib tool - FOREACH (_LIBAV_COMPONENT ${_LIBAV_ALL_LIBS}) - GET_LIB_REQUISITES (${_LIBAV_COMPONENT} _LIBAV_REQUISITES) - ENDFOREACH (_LIBAV_COMPONENT) -ENDIF (_LIBAV_ALL_LIBS) - -IF (NOT LIBAV_BINARY_DIR) - SET (_LIBAV_UPDATE_BINARY_DIR TRUE) -ELSE (NOT LIBAV_BINARY_DIR) - SET (_LIBAV_UPDATE_BINARY_DIR FALSE) -ENDIF (NOT LIBAV_BINARY_DIR) - -SET (_LIBAV_BINARY_DIR_HINTS bin) - -IF (_LIBAV_REQUISITES) - FIND_FILE (LIBAV_BINARY_DIR NAMES ${_LIBAV_REQUISITES} - HINTS ${LIBAV_ROOT_DIR} - PATH_SUFFIXES ${_LIBAV_BINARY_DIR_HINTS} NO_DEFAULT_PATH) -ENDIF (_LIBAV_REQUISITES) - -IF (LIBAV_BINARY_DIR AND _LIBAV_UPDATE_BINARY_DIR) - SET (_LIBAV_BINARY_DIR ${LIBAV_BINARY_DIR}) - UNSET (LIBAV_BINARY_DIR CACHE) - - IF (_LIBAV_BINARY_DIR) - GET_FILENAME_COMPONENT (LIBAV_BINARY_DIR ${_LIBAV_BINARY_DIR} PATH) - ENDIF (_LIBAV_BINARY_DIR) -ENDIF (LIBAV_BINARY_DIR AND _LIBAV_UPDATE_BINARY_DIR) - -SET (LIBAV_BINARY_DIR ${LIBAV_BINARY_DIR} CACHE PATH "libav binary directory") - -MARK_AS_ADVANCED (LIBAV_INCLUDE_DIR LIBAV_BINARY_DIR) - -IF (NOT _LIBAV_CHECK_COMPONENTS) - SET (_LIBAV_FPHSA_ADDITIONAL_ARGS HANDLE_COMPONENTS) -ENDIF (NOT _LIBAV_CHECK_COMPONENTS) - -FIND_PACKAGE_HANDLE_STANDARD_ARGS (LibAV REQUIRED_VARS LIBAV_ROOT_DIR - LIBAV_INCLUDE_DIR ${_LIBAV_MISSING_LIBRARIES} VERSION_VAR LIBAV_VERSION - ${_LIBAV_FPHSA_ADDITIONAL_ARGS}) diff --git a/source/build-cmake/babbage2nd/CMakeLists.txt b/source/build-cmake/babbage2nd/CMakeLists.txt deleted file mode 100644 index 9599a0631..000000000 --- a/source/build-cmake/babbage2nd/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Babbage2nd, Qt **") -message("") - -project (emubabbage2nd) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - -set(EXEC_TARGET emubabbage2nd) -set(VM_NAME babbage2nd) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - z80ctc.cpp - - io.cpp - memory.cpp - - event.cpp -) - -set(VMFILES_LIB - z80pio.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER OFF CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_BABBAGE2ND) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/babbage2nd.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/bmjr/CMakeLists.txt b/source/build-cmake/bmjr/CMakeLists.txt deleted file mode 100644 index daf7ed869..000000000 --- a/source/build-cmake/bmjr/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Hitachi Basic Master Jr., Qt **") -message("") - -project (emubmjr) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - - -set(VM_NAME bmjr) -set(EXEC_TARGET emubmjr) -set(USE_FMGEN OFF) - -set(VMFILES_BASE - event.cpp -) -set(VMFILES_LIB - noise.cpp - datarec.cpp - mc6800.cpp - mc6820.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_BMJR) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/bmjr.qrc) - -include(config_commonsource) - diff --git a/source/build-cmake/bubcom80/CMakeLists.txt b/source/build-cmake/bubcom80/CMakeLists.txt deleted file mode 100644 index 899e6923f..000000000 --- a/source/build-cmake/bubcom80/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,BUBCOM 80, Qt **") -message("") - -project (emububcom80) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - -set(EXEC_TARGET emububcom80) -set(VM_NAME bubcom80) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - io.cpp - memory.cpp - event.cpp -) - -set(VMFILES_LIB - ls393.cpp - mb8877.cpp - mc6850.cpp - pcm1bit.cpp - z80ctc.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER OFF CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_BUBCOM80) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/bubcom80.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/buildvars.dat.tmpl b/source/build-cmake/buildvars.dat.tmpl deleted file mode 100644 index 20e8741b4..000000000 --- a/source/build-cmake/buildvars.dat.tmpl +++ /dev/null @@ -1,68 +0,0 @@ -### Build definitions for GNU/Linux (and maybe other *nix like OSs) native build. -### Please copy this to buildvars.dat and edit. -# - -BUILD_TOOLCHAIN="GCC" -CC_SUFFIX=6 -#BUILD_TOOLCHAIN="LLVM" -#CC_SUFFIX=4.0 - -# "IA32" "AMD64" "ARM32" "ARM64" -MAJOR_ARCH="AMD64" - -# "GENERIC" "SSE1" "SSE2" "SSE3" "AVX" or "NO" -LOCAL_ARCH_TYPE="GENERIC" - -BUILD_TYPE="Relwithdebinfo" -# "No" or "Yes". -CSP_DEBUG="No" -# "No" or "Yes". -USE_LTO="Yes" -# "No" or "Yes" -STRIP_SYMBOLS="No" -# "No" or "Yes" -COMPRESS_SYMBOLS="No" -# "No" or "Yes" -USE_RADICAL_OPTIMIZE="Yes" -# "No" or "Yes" -USE_COMMON_DEVICE_LIB="Yes" -# "No" or "Yes" -USE_WHOLE_PROGRAM_OPTIMIZE="No" -# Threads when using LTO. -LTO_THREADS=6 - -# Shrinked debug symbols; -# This may not be used both LTO. -USE_SHRINK_DEBUG_SYMBOL="No" - -# "No" or "Yes" -USE_OPENMP="No" - -# "No" or "Yes" -USE_SANITIZER="No" - -# "Default" or "String" or "All" or "No" or "Yes" -USE_STACK_PROTECTION="Default" - -ADDITIONAL_MAKEFLAGS_LINK_EXE="" -ADDITIONAL_MAKEFLAGS_LINK_DLL="" -ADDITIONAL_MAKEFLAGS_LINK_LIB="" - -FFMPEG_DIR="/usr/include/x86_64-linux-gnu/" -#QT5_DIR="/usr/include/x86_64-linux-gnu/" -#FFMPEG_DIR="/usr/include/x86_64-linux-gnu/" -#QT5_DIR="/usr/include/x86_64-linux-gnu/" -#FFMPEG_DIR="/usr/local/ffmpeg-3.2" -#QT5_DIR="/opt/Qt5.5.1/5.5/gcc_64" - -LIB_INSTALL="/usr/local/lib/x86_64-linux-gnu/" - -MAKEFLAGS_GENERAL="-j3" -#MAKEFLAGS_BASE="" -# Below sets make with affinity mask.Using excepts CPU CORE #1 and #7. -#AFFINITY_MAKE="taskset 0xfbe make" - - -CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_MOVIE_SAVER=ON -DUSE_MOVIE_LOADER=ON" - - diff --git a/source/build-cmake/buildvars_mingw.dat.tmpl b/source/build-cmake/buildvars_mingw.dat.tmpl deleted file mode 100644 index bbd60746c..000000000 --- a/source/build-cmake/buildvars_mingw.dat.tmpl +++ /dev/null @@ -1,59 +0,0 @@ -### Build definitions for Win32 (or Win64?) MinGW native build. -### Please copy this to buildvars_mingw.dat and edit. -# -#CMAKE="/c/Program Files (x86)/CMake/bin/cmake" -CCMAKE_CC=gcc -CCMAKE_CXX=g++ - -BUILD_TYPE="Release" - -# "IA32" "AMD64" "ARM32" "ARM64" -MAJOR_ARCH="IA32" - -# "SSE1" "SSE2" "SSE3" "AVX" or "NO" -#LOCAL_ARCH_TYPE="AVX" -LOCAL_ARCH_TYPE="SSE2" -#LOCAL_ARCH_TYPE="No" - -# "No" or "Yes" -USE_SANITIZER="No" - -# "Default" or "String" or "All" or "No" or "Yes" -USE_STACK_PROTECTION="Default" - -#MAKEFLAGS_BASE="-fvect-cost-model=dynamic -ftree-vectorize \ -# -ftree-loop-distribute-patterns \ -# -ftree-loop-optimize -ftree-loop-if-convert-stores \ -# -fbranch-probabilities -fbranch-target-load-optimize \ -# -fselective-scheduling -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops \ -# -funroll-loops \ -# -fgraphite-identity \ -# -floop-nest-optimize \ -# " -MAKEFLAGS_BASE="-fvect-cost-model=dynamic -ftree-vectorize \ - -ftree-loop-distribute-patterns \ - -ftree-loop-optimize -ftree-loop-if-convert-stores \ - -fbranch-probabilities -fbranch-target-load-optimize \ - -msse -msse2" -#MAKEFLAGS_BASE="-ftree-vectorize" - -MAKEFLAGS_CXX="-O3 ${MAKEFLAGS_BASE} -DNDEBUG" -MAKEFLAGS_CC="-O3 ${MAKEFLAGS_BASE} -DNDEBUG" -#MAKEFLAGS_CXX="-O0 -flto -DNDEBUG" -#MAKEFLAGS_CC="-O0 -flto -DNDEBUG" - -MAKEFLAGS_LIB_CXX="-O3 ${MAKEFLAGS_BASE} -DNDEBUG" -MAKEFLAGS_LIB_CC="-O3 ${MAKEFLAGS_BASE} -DNDEBUG" -#MAKEFLAGS_LIB_CXX="-O0 -flto -DNDEBUG" -#MAKEFLAGS_LIB_CC="-O0 -flto -DNDEBUG" - -MAKEFLAGS_GENERAL="-j3" - -#CMAKE_LINKFLAG="-DCMAKE_EXE_LINKER_FLAGS:STRING=-s -O3 -flto ${MAKEFLAGS_BASE} -fwhole-program -static-libgcc -static-libstdc++" -CMAKE_LINKFLAG="-DCMAKE_EXE_LINKER_FLAGS:STRING=-s -static-libgcc -static-libstdc++" - -CMAKE_GENTYPE="MSYS Makefiles" -CMAKE_GENFLAGS="-DCMAKE_MAKE_PROGRAM=mingw32-make" - - - diff --git a/source/build-cmake/buildvars_mingw_cross_win32.dat.tmpl b/source/build-cmake/buildvars_mingw_cross_win32.dat.tmpl deleted file mode 100644 index 5ef025b31..000000000 --- a/source/build-cmake/buildvars_mingw_cross_win32.dat.tmpl +++ /dev/null @@ -1,54 +0,0 @@ -### Build definitions for Win32 cross build. -### BY GNU/Linux (and maybe other *nix like OSs) host to MinGW32 target. -### Please copy this to buildvars_mingw_cross_win32.dat and edit. -# -#CMAKE=/usr/bin/cmake -BUILD_TOOLCHAIN="GCC" - -BUILD_TYPE="Release" - -# "No" or "Yes". -CSP_DEBUG="NO" - -# "IA32" "AMD64" "ARM32" "ARM64" -MAJOR_ARCH="IA32" - -# "SSE1" "SSE2" "SSE3" "AVX" or "NO" -LOCAL_ARCH_TYPE="SSE2" - -# "No" or "Yes". -USE_LTO="Yes" -# "No" or "Yes" -USE_WHOLE_PROGRAM_OPTIMIZE="Yes" -# Threads when using LTO. -LTO_THREADS=12 - -# No" or "Yes" -STRIP_SYMBOLS="Yes" -# "No" or "Yes" -USE_RADICAL_OPTIMIZE="No" -# "No" or "Yes" -COMPRESS_SYMBOLS="No" - -# "No" or "Yes" -USE_COMMON_DEVICE_LIB="Yes" - -# "No" or "Yes" -USE_OPENMP="No" - -# "No" or "Yes" -USE_SANITIZER="No" - -# "Default" or "String" or "All" or "No" or "Yes" -USE_STACK_PROTECTION="Default" - -ADDITIONAL_MAKEFLAGS_LINK_EXE="" -ADDITIONAL_MAKEFLAGS_LINK_DLL="" -ADDITIONAL_MAKEFLAGS_LINK_LIB="" - -FFMPEG_DIR="/usr/local/i586-mingw-msvc/ffmpeg-3.4" -MAKEFLAGS_GENERAL="-j3" -MAKEFLAGS_BASE="" -# Below sets make with affinity mask.Using excepts CPU CORE #1 and #7. -#AFFINITY_MAKE="taskset 0xfbe make" - diff --git a/source/build-cmake/cefucom21/CMakeLists.txt b/source/build-cmake/cefucom21/CMakeLists.txt deleted file mode 100644 index 6fb7a5ba4..000000000 --- a/source/build-cmake/cefucom21/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Hino Electronics CEFUCOM-21, Qt **") -message("") - - -project (cefucom21) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - - -set(VM_NAME cefucom21) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES - mc6847.cpp - io.cpp - memory.cpp - event.cpp -) - -set(VMFILES_LIB - ay_3_891x.cpp - datarec.cpp - i8255.cpp - mc6847_mase.cpp - not.cpp - rp5c01.cpp - z80.cpp - z80ctc.cpp - z80pio.cpp -) -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CEFUCOM21) -set(EXEC_TARGET emucefucom21) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/cefucom21.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/cmake/CompressExeWithUpx.cmake b/source/build-cmake/cmake/CompressExeWithUpx.cmake deleted file mode 120000 index 8dab6e97a..000000000 --- a/source/build-cmake/cmake/CompressExeWithUpx.cmake +++ /dev/null @@ -1 +0,0 @@ -../3rdparty/CompressExeWithUpx.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/FindIconv.cmake b/source/build-cmake/cmake/FindIconv.cmake deleted file mode 120000 index 9b1e01a69..000000000 --- a/source/build-cmake/cmake/FindIconv.cmake +++ /dev/null @@ -1 +0,0 @@ -../3rdparty/FindIconv.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/FindLibAV.cmake b/source/build-cmake/cmake/FindLibAV.cmake deleted file mode 120000 index 7695d457f..000000000 --- a/source/build-cmake/cmake/FindLibAV.cmake +++ /dev/null @@ -1 +0,0 @@ -../3rdparty/FindLibAV.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/FindOpenCL.cmake b/source/build-cmake/cmake/FindOpenCL.cmake deleted file mode 120000 index 558493dc6..000000000 --- a/source/build-cmake/cmake/FindOpenCL.cmake +++ /dev/null @@ -1 +0,0 @@ -../3rdparty/findopencl/FindOpenCL.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/SetMSVCDebugPath.cmake b/source/build-cmake/cmake/SetMSVCDebugPath.cmake deleted file mode 120000 index ef8f3871e..000000000 --- a/source/build-cmake/cmake/SetMSVCDebugPath.cmake +++ /dev/null @@ -1 +0,0 @@ -../3rdparty/SetMSVCDebugPath.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/SplitDebugInformation.cmake b/source/build-cmake/cmake/SplitDebugInformation.cmake deleted file mode 120000 index 160018bfa..000000000 --- a/source/build-cmake/cmake/SplitDebugInformation.cmake +++ /dev/null @@ -1 +0,0 @@ -../3rdparty/SplitDebugInformation.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/config_commonsource.cmake b/source/build-cmake/cmake/config_commonsource.cmake deleted file mode 100644 index 24bc3b6ba..000000000 --- a/source/build-cmake/cmake/config_commonsource.cmake +++ /dev/null @@ -1,366 +0,0 @@ -# Set configuration for building XM7/SDL. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -include(CheckFunctionExists) -#include(cotire) - -#set(ADDITIONAL_MAKE_CLEAN_FILES *.dwo *.obj) - -if(USE_DEVICES_SHARED_LIB) - add_definitions(-DUSE_SHARED_DLL) - add_definitions(-DUSE_SHARED_UI_DLL) - add_definitions(-DUSE_SHARED_DEVICES_DLL) -# set(I386_CPPS -# libcpu_newdev/i386.cpp -# libcpu_newdev/libcpu_i386/i386_real.cpp -# libcpu_newdev/libcpu_i386/i386op16_real.cpp -# libcpu_newdev/libcpu_i386/i386dasm.cpp -# ) - set(MC6809_CPPS - mc6809.cpp - ) - set(MCS48_CPPS - mcs48.cpp - ) - set(IX86_CPPS - libcpu_newdev/i86.cpp - ) - set(Z80_CPPS - z80.cpp - ) -else() - set(I386_CPPS i386.cpp) - set(MC6809_CPPS mc6809_base.cpp mc6809.cpp) - set(MCS48_CPPS mcs48_base.cpp mcs48.cpp) - set(IX86_CPPS i86.cpp) - set(Z80_CPPS z80_base.cpp z80.cpp) - set(VMFILES ${VMFILES} ${VMFILES_LIB}) -endif() - -if(FLAG_USE_I86) - set(VMFILES ${VMFILES} ${IX86_CPPS}) -endif() -if(FLAG_USE_I286) - set(VMFILES ${VMFILES} i286.cpp) -endif() -if(FLAG_USE_Z80) - set(VMFILES ${VMFILES} z80.cpp) -endif() -if(FLAG_USE_MC6809) - set(VMFILES ${VMFILES} ${MC6809_CPPS}) -endif() -if(FLAG_USE_MCS48) - set(VMFILES ${VMFILES} ${MCS48_CPPS}) -endif() -if(FLAG_USE_Z80) - set(VMFILES ${VMFILES} ${Z80_CPPS}) -endif() - -if(DEFINED QT5_ROOT_PATH) - SET(CMAKE_FIND_ROOT_PATH ${QT5_ROOT_PATH} ${CMAKE_FIND_ROOT_PATH}) -endif() - -# Use ccache if enabled. -find_program(USE_CCACHE ccache) -if(USE_CCACHE) - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) -# SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) - endif() -if(WIN32) - FIND_PACKAGE(Qt5Core REQUIRED) -else() - FIND_PACKAGE(Qt5Widgets REQUIRED) -endif() - FIND_PACKAGE(Qt5Gui REQUIRED) - FIND_PACKAGE(Qt5OpenGL REQUIRED) - include_directories(${Qt5Widgets_INCLUDE_DIRS}) - include_directories(${Qt5Core_INCLUDE_DIRS}) - include_directories(${Qt5Gui_INCLUDE_DIRS}) - include_directories(${Qt5OpenGL_INCLUDE_DIRS}) - add_definitions(-D_USE_OPENGL -DUSE_OPENGL) -if(USE_SOCKET) - FIND_PACKAGE(Qt5Network REQUIRED) - include_directories(${Qt5Network_INCLUDE_DIRS}) -endif() - -SET(USE_QT_5 ON) -set(USE_QT5_4_APIS OFF CACHE BOOL "Build with Qt5.4 (or later) APIs if you can.") -set(USE_GCC_OLD_ABI ON CACHE BOOL "Build with older GCC ABIs if you can.") -set(USE_SDL2 ON CACHE BOOL "Build with libSDL2. DIsable is building with libSDL1.") -set(USE_MOVIE_SAVER OFF CACHE BOOL "Save screen/audio as MP4 MOVIE. Needs libav .") -set(USE_MOVIE_LOADER OFF CACHE BOOL "Load movie from screen for some VMs. Needs libav .") -set(USE_LTO ON CACHE BOOL "Use link-time-optimization to build.") - -if(USE_LTO) - # set_property(DIRECTORY PROPERTY INTERPROCEDURAL_OPTIMIZATION true) -else() - # set_property(DIRECTORY PROPERTY INTERPROCEDURAL_OPTIMIZATION false) -endif() - -add_definitions(-D_USE_QT5) - -if(USE_QT5_4_APIS) - add_definitions(-D_USE_QT_5_4) -else() - #add_definitions(-DQT_NO_VERSION_TAGGING) -endif() - -if(USE_GCC_OLD_ABI) - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) -else() - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) -endif() - -SET(CMAKE_AUTOMOC OFF) -SET(CMAKE_AUTORCC ON) -SET(CMAKE_INCLUDE_CURRENT_DIR ON) - -add_definitions(-D_USE_QT) -add_definitions(-DUSE_QT) -add_definitions(-DQT_MAJOR_VERSION=${Qt5Widgets_VERSION_MAJOR}) -add_definitions(-DQT_MINOR_VERSION=${Qt5Widgets_VERSION_MINOR}) - - -if(USE_OPENMP) - find_package(OpenMP) - include_directories(${OPENMP_INCLUDE_PATH}) - if(OPENMP_FOUND) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - endif() -endif() - -find_package(Threads) -include_directories(${THREADS_INCLUDE_PATH}) - -include(FindPkgConfig) - -find_package(Git) -if(GIT_FOUND) - execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD OUTPUT_VARIABLE __tstr) - string(FIND ${__tstr} "fatal" __notfound) - string(REPLACE "\n" "" __tstr2 ${__tstr}) - if(${__notfound} EQUAL -1) - add_definitions(-D__GIT_REPO_VERSION=\"${__tstr2}\") - else() - add_definitions(-U__GIT_REPO_VERSION) - endif() -endif() - -string(TIMESTAMP __build_date "%b %d,%Y %H:%M:%S UTC" UTC) -add_definitions(-D__BUILD_DATE=\"${__build_date}\") - -include(FindLibAV) - if(LIBAV_FOUND) - add_definitions(-DUSE_LIBAV) - if(USE_MOVIE_SAVER) - add_definitions(-DUSE_MOVIE_SAVER) - endif() - if(USE_MOVIE_LOADER) - add_definitions(-DUSE_MOVIE_LOADER) - endif() - add_definitions(-D__STDC_CONSTANT_MACROS) - add_definitions(-D__STDC_FORMAT_MACROS) - else() - set(USE_MOVIE_SAVER OFF) - set(USE_MOVIE_LOADER OFF) - set(LIBAV_LIBRARIES "") - endif() - -if(USE_SDL2) - if(CMAKE_CROSSCOMPILING) - include_directories(${SDL2_INCLUDE_DIRS}) - else() - pkg_search_module(SDL2 REQUIRED sdl2) - include_directories(${SDL2_INCLUDE_DIRS}) - endif() - set(SDL_LIBS ${SDL2_LIBRARIES}) - add_definitions(-DUSE_SDL2) -else() - if(CMAKE_CROSSCOMPILING) - include_directories(${SDL_INCLUDE_DIRS}) - set(SDL_LIBS ${SDL_LIBRARIES}) - else() - include(FindSDL) - #pkg_search_module(SDL REQUIRED sdl) - #include_directories(${SDL_INCLUDE_DIRS}) - include_directories(${SDL_INCLUDE_DIR}) - set(SDL_LIBS ${SDL_LIBRARY}) - endif() -endif() - -include(FindZLIB) -if(ZLIB_FOUND) - add_definitions(-DUSE_ZLIB) - include_directories(${ZLIB_INCLUDE_DIRS}) -endif() - -# GCC Only? -if(CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flax-vector-conversions") -endif() - -if(CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -flax-vector-conversions") -endif() - - -check_function_exists("nanosleep" HAVE_NANOSLEEP) -if(NOT HAVE_NANOSLEEP) - check_library_exists("rt" "nanosleep" "" LIB_RT_HAS_NANOSLEEP) -endif(NOT HAVE_NANOSLEEP) - -if(LIB_RT_HAS_NANOSLEEP) - add_target_library(${EXEC_TARGET} rt) -endif(LIB_RT_HAS_NANOSLEEP) - -if(HAVE_NANOSLEEP OR LIB_RT_HAS_NANOSLEEP) - add_definitions(-DHAVE_NANOSLEEP) -endif(HAVE_NANOSLEEP OR LIB_RT_HAS_NANOSLEEP) - - -set(SRC_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../src) - -if(USE_QT_5) - if(NOT WIN32) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - endif() -endif() - -if(DEFINED VM_NAME) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/${VM_NAME}) -# if(USE_FMGEN) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/fmgen) -# if(WIN32) -# set(FMGEN_LIB vm_fmgen) -# set(FMGEN_LIB "-lCSPfmgen") -# endif() -# endif() -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/machines/${VM_NAME}) -endif() - -if(LIBAV_FOUND) - include_directories(${LIBAV_INCLUDE_DIRS}) -endif() - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/gui) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt) -if(WIN32) -# add_subdirectory(../../src/qt/gui qt/gui) -endif() -#add_subdirectory(../../src/qt qt/osd) -add_subdirectory(../../src common) -add_subdirectory(../../src/vm vm/) - -#add_custom_command(OUTPUT test.txt -# COMMAND grep ARGS -m 1 THIS_LIB_VERSION ${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/fmgen/CMakeLists.txt -# COMMAND sed ARGS "-r" "'s/.*THIS_VERSION\ //'" -# COMMAND sed ARGS "-r" "'s/\).*$//'" -# ) - - -if(DEFINED VM_NAME) -# if(WITH_DEBUGGER) - set(DEBUG_LIBS qt_debugger) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/debugger) - add_subdirectory(../../src/qt/debugger qt/debugger) -# else() -# set(DEBUG_LIBS) -# endif() - if(USE_DEVICES_SHARED_LIB) - else() - if(USE_FMGEN) - set(VM_APPEND_LIBS fmgen ${VM_APPEND_LIBS}) - - else() - set(VM_APPEND_LIBS ${VM_APPEND_LIBS}) - endif() - endif() - if(WIN32) - set(LOCAL_LIBS - common_emu - qt_${VM_NAME} - vm_${VM_NAME} - vm_vm - ${VM_APPEND_LIBS} - ${DEBUG_LIBS} - common_common - ) - else() - set(LOCAL_LIBS - common_emu - qt_${VM_NAME} - vm_${VM_NAME} - vm_vm - ${VM_APPEND_LIBS} - ${DEBUG_LIBS} - common_common - ) - endif() -endif() - -include(simd-x86) - - -if(WIN32) - set(BUNDLE_LIBS - ${OPENGL_LIBRARY} - ${OPENCL_LIBRARY} - ${GETTEXT_LIBRARY} - ${OPENMP_LIBRARY} - ${LIBAV_LIBRARIES} - ${SDL_LIBS} - ${LIBAV_LIBRARIES} - ${ADDITIONAL_LIBRARIES} - ${ZLIB_LIBRARIES} - ) - #SET(CMAKE_C_ARCHIVE_CREATE " qcs ") - #SET(CMAKE_C_ARCHIVE_FINISH true) - #SET(CMAKE_CXX_ARCHIVE_CREATE " qcs ") - #SET(CMAKE_CXX_ARCHIVE_FINISH true) -else() - add_definitions(-D_UNICODE) - set(BUNDLE_LIBS -# ${OPENGL_LIBRARY} - ${OPENCL_LIBRARY} -# ${GETTEXT_LIBRARY} - ${OPENMP_LIBRARY} - ${SDL_LIBS} -# ${LIBAV_LIBRARIES} - ${ADDITIONAL_LIBRARIES} - ) - if(USE_DEVICES_SHARED_LIB) - set(BUNDLE_LIBS ${BUNDLE_LIBS} -lCSPosd -lCSPcommon_vm -lCSPfmgen -lCSPgui -lCSPemu_utils -lCSPavio) - else() - set(BUNDLE_LIBS ${BUNDLE_LIBS} -lCSPosd -lCSPgui -lCSPavio) - endif() -endif() - -if(USE_QT_5) - set(BUNDLE_LIBS ${BUNDLE_LIBS} ${QT_LIBRARIES} ${ZLIB_LIBRARIES}) -endif() - -set(BUNDLE_LIBS ${BUNDLE_LIBS} ${THREADS_LIBRARY}) - -if(DEFINED VM_NAME) - if(USE_DEVICES_SHARED_LIB) - add_subdirectory(../../src/vm/${VM_NAME} vm/${VM_NAME}) - add_subdirectory(../../src/qt/machines/${VM_NAME} qt/${VM_NAME}) - add_subdirectory(../../src/qt/common qt/common) - else() - add_subdirectory(../../src/vm/${VM_NAME} vm/${VM_NAME}) - #add_subdirectory(../../src/vm vm/common) - #add_subdirectory(../../src common/common) - if(USE_FMGEN) - add_subdirectory(../../src/vm/fmgen vm/fmgen) - endif() - add_subdirectory(../../src/qt/machines/${VM_NAME} qt/${VM_NAME}) - add_subdirectory(../../src/qt/common qt/common) - endif() -endif() diff --git a/source/build-cmake/cmake/config_emufm16beta.cmake b/source/build-cmake/cmake/config_emufm16beta.cmake deleted file mode 100644 index 4f0cfa2ca..000000000 --- a/source/build-cmake/cmake/config_emufm16beta.cmake +++ /dev/null @@ -1,77 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(VM_NAME fm16beta) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES - i8237.cpp - msm58321.cpp -# scsi_dev.cpp -# scsi_host.cpp -# scsi_hdd.cpp - memory.cpp - - event.cpp - io.cpp -) - -set(VMFILES_LIB - hd46505.cpp - - i8237_base.cpp - i8251.cpp - i8259.cpp - msm58321_base.cpp - mb8877.cpp - mc6840.cpp - pcm1bit.cpp - - mb61vh010.cpp - noise.cpp - disk.cpp - ) -set(FLAG_USE_MC6809 ON) - -set(BUILD_SHARED_LIBS OFF) - -set(BUILD_FM16BETA_286 OFF CACHE BOOL "Build for FM16Beta, i286 version") -set(BUILD_FM16BETA_86 OFF CACHE BOOL "Build for FM16Beta, i86 version") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") - -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(BUILD_FM16BETA_286) - set(EXEC_TARGET emufm16beta_286) - add_definitions(-D_FM16BETA) - add_definitions(-DHAS_I286) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fm16beta.qrc) -# set(FLAG_USE_I286 ON) -elseif(BUILD_FM16BETA_86) - set(EXEC_TARGET emufm16beta_86) - add_definitions(-D_FM16BETA) - add_definitions(-DHAS_I186) -# set(FLAG_USE_I286 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fm16beta.qrc) -endif() - -#include(config_commonsource) - - diff --git a/source/build-cmake/cmake/config_emufm7.cmake b/source/build-cmake/cmake/config_emufm7.cmake deleted file mode 100644 index 7cb5ebf30..000000000 --- a/source/build-cmake/cmake/config_emufm7.cmake +++ /dev/null @@ -1,195 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -message("") -message("** Start of configure CommonSourceProject,FM-8/7/77/AV, Qt **") -message("") - -set(VM_NAME fm7) -set(USE_FMGEN ON) -set(WITH_DEBUGGER ON) -set(WITH_MOUSE ON) -set(WITH_JOYSTICK ON) - -set(VMFILES - event.cpp -# io.cpp -) - -set(VMFILES_LIB - and.cpp - datarec.cpp - ym2203.cpp - pcm1bit.cpp - disk.cpp - mb8877.cpp - prnfile.cpp - or.cpp - noise.cpp - i8251.cpp -) - -set(FLAG_USE_MC6809 ON) - -if(NOT BUILD_FM7) - set(BUILD_FM7 OFF CACHE BOOL "Build for FM7") -endif() -if(NOT BUILD_FMNEW7) - set(BUILD_FMNEW7 OFF CACHE BOOL "Build for FM7") -endif() - -if(NOT BUILD_FM8) - set(BUILD_FM8 OFF CACHE BOOL "Build for FM8") -endif() - -if(NOT BUILD_FM77) - set(BUILD_FM77 OFF CACHE BOOL "Build for FM77") -endif() - -if(NOT BUILD_FM77L2) - set(BUILD_FM77L2 OFF CACHE BOOL "Build for FM77L2") -endif() - -if(NOT BUILD_FM77L4) - set(BUILD_FM77L4 OFF CACHE BOOL "Build for FM77L4") -endif() - -if(NOT BUILD_FM77AV) - set(BUILD_FM77AV OFF CACHE BOOL "Build for FM77AV") -endif() - -if(NOT BUILD_FM77AV20) - set(BUILD_FM77AV20 OFF CACHE BOOL "Build for FM77AV20") -endif() - -if(NOT BUILD_FM77AV40) - set(BUILD_FM77AV40 OFF CACHE BOOL "Build for FM77AV40") -endif() - -if(NOT BUILD_FM77AV40SX) - set(BUILD_FM77AV40SX OFF CACHE BOOL "Build for FM77AV40SX") -endif() - -if(NOT BUILD_FM77AV40EX) - set(BUILD_FM77AV40EX OFF CACHE BOOL "Build for FM77AV40EX") -endif() - -set(FM77_EXTRAM_PAGES "12" CACHE STRING "Set banks of EXTRAM of FM77/FM77AV40, bank = 64Kbytes") - - -set(BUILD_SHARED_LIBS OFF) -set(FM7_DEBUG_FDC OFF CACHE BOOL "With debug FDC") -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(FM7_DEBUG_FDC) - add_definitions(-D_FM7_FDC_DEBUG) - add_definitions(-D_DEBUG_LOG) -endif() - -if(BUILD_FM7) - set(EXEC_TARGET emufm7) - add_definitions(-D_FM7) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm7.qrc) - set(VMFILES_LIB ${VMFILES_LIB} ay_3_891x.cpp) - set(FLAG_USE_Z80 ON) - add_definitions(-DBUILD_Z80) -elseif(BUILD_FMNEW7) - set(EXEC_TARGET emufmnew7) - add_definitions(-D_FMNEW7) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm7.qrc) - set(VMFILES_LIB ${VMFILES_LIB} ay_3_891x.cpp) - set(FLAG_USE_Z80 ON) - add_definitions(-DBUILD_Z80) -elseif(BUILD_FM8) - set(EXEC_TARGET emufm8) - add_definitions(-D_FM8) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm8.qrc) - set(VMFILES_LIB ${VMFILES_LIB} ay_3_891x.cpp) - set(FLAG_USE_Z80 ON) - add_definitions(-DBUILD_Z80) - -elseif(BUILD_FM77) - set(EXEC_TARGET emufm77) - add_definitions(-D_FM77) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77.qrc) - set(VMFILES_LIB ${VMFILES_LIB} ay_3_891x.cpp) - set(FLAG_USE_Z80 ON) - add_definitions(-DBUILD_Z80) - -elseif(BUILD_FM77L2) - set(EXEC_TARGET emufm77l2) - add_definitions(-D_FM77L2) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77l2.qrc) - set(VMFILES_LIB ${VMFILES_LIB} ay_3_891x.cpp) - set(FLAG_USE_Z80 ON) - add_definitions(-DBUILD_Z80) - -elseif(BUILD_FM77L4) - set(EXEC_TARGET emufm77l4) - add_definitions(-D_FM77L4) - #set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77l4.qrc) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77.qrc) - set(VMFILES_LIB ${VMFILES_LIB} ay_3_891x.cpp hd46505.cpp) - set(FLAG_USE_Z80 ON) - add_definitions(-DBUILD_Z80) - -elseif(BUILD_FM77AV) - set(EXEC_TARGET emufm77av) - add_definitions(-D_FM77AV) - set(FM77AV_VARIANTS ON) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77av.qrc) - set(VMFILES_LIB ${VMFILES_LIB} beep.cpp) - -elseif(BUILD_FM77AV20) - set(EXEC_TARGET emufm77av20) - add_definitions(-D_FM77AV20) - set(FM77AV_VARIANTS ON) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77av20.qrc) - set(VMFILES_LIB ${VMFILES_LIB} beep.cpp) - -elseif(BUILD_FM77AV20EX) - set(EXEC_TARGET emufm77av20ex) - add_definitions(-D_FM77AV20EX) - set(FM77AV_VARIANTS ON) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77av20ex.qrc) - set(VMFILES_LIB ${VMFILES_LIB} beep.cpp) - -elseif(BUILD_FM77AV40) - set(EXEC_TARGET emufm77av40) - add_definitions(-D_FM77AV40) - set(FM77AV_VARIANTS ON) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77av40.qrc) - set(VMFILES_LIB ${VMFILES_LIB} beep.cpp) - -elseif(BUILD_FM77AV40SX) - set(EXEC_TARGET emufm77av40sx) - add_definitions(-D_FM77AV40SX) - set(FM77AV_VARIANTS ON) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77av40sx.qrc) - set(VMFILES_LIB ${VMFILES_LIB} beep.cpp) - -elseif(BUILD_FM77AV40EX) - set(EXEC_TARGET emufm77av40ex) - add_definitions(-D_FM77AV40EX) - set(FM77AV_VARIANTS ON) - set(RESOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common/qrc/fm77av40ex.qrc) - set(VMFILES_LIB ${VMFILES_LIB} beep.cpp) - -endif() - -add_definitions(-DFM77_EXRAM_BANKS=${FM77_EXTRAM_PAGES}) - - - - - diff --git a/source/build-cmake/cmake/config_emufmr50.cmake b/source/build-cmake/cmake/config_emufmr50.cmake deleted file mode 100644 index 8d7da9dd4..000000000 --- a/source/build-cmake/cmake/config_emufmr50.cmake +++ /dev/null @@ -1,123 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(VM_NAME fmr50) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES - msm58321.cpp - scsi_dev.cpp - scsi_host.cpp - scsi_hdd.cpp - memory.cpp - -# disk.cpp - event.cpp - io.cpp -) - -set(VMFILES_LIB - pcm1bit.cpp - mb8877.cpp - hd46505.cpp - upd71071.cpp - i8253.cpp - i8251.cpp - i8253.cpp - i8259.cpp - msm58321_base.cpp - - hd63484.cpp -# i386.cpp -# scsi_dev_base.cpp -# scsi_hdd.cpp - noise.cpp - disk.cpp - harddisk.cpp - ) - -set(BUILD_SHARED_LIBS OFF) - -set(BUILD_FMR50_286 OFF CACHE BOOL "Build for FM-R50, i286 version") -set(BUILD_FMR50_386 OFF CACHE BOOL "Build for FM-R50, i386 version") -set(BUILD_FMR50_486 OFF CACHE BOOL "Build for FM-R50, i486 version") -set(BUILD_FMR250 OFF CACHE BOOL "Build for FM-R250, Pentium version of FMR-50") -set(BUILD_FMR60 OFF CACHE BOOL "Build for FM-R60, i286 version") -set(BUILD_FMR70 OFF CACHE BOOL "Build for FM-R70, i386 version") -set(BUILD_FMR80 OFF CACHE BOOL "Build for FM-R80, i486 version") -set(BUILD_FMR280 OFF CACHE BOOL "Build for FM-R250, Pentium version of FMR-80") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") - -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(BUILD_FMR50_286) - set(EXEC_TARGET emufmr50_286) - add_definitions(-D_FMR50) - add_definitions(-DHAS_I286) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr50.qrc) -# set(FLAG_USE_I286 ON) -elseif(BUILD_FMR50_386) - set(EXEC_TARGET emufmr50_386) - add_definitions(-D_FMR50) - add_definitions(-DHAS_I386) -# set(FLAG_USE_I286 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr50.qrc) -elseif(BUILD_FMR50_486) - set(EXEC_TARGET emufmr50_486) - add_definitions(-D_FMR50) - add_definitions(-DHAS_I486) -# set(FLAG_USE_I286 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr50.qrc) -elseif(BUILD_FMR250) - set(EXEC_TARGET emufmr250) - add_definitions(-D_FMR50) - add_definitions(-DHAS_PENTIUM) -# set(FLAG_USE_I286 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr50.qrc) -elseif(BUILD_FMR60) - set(EXEC_TARGET emufmr60) - add_definitions(-D_FMR60) - add_definitions(-DHAS_I286) -# set(FLAG_USE_I286 ON) - set(VMFILES_LIB ${VMFILES_LIB} hd63484.cpp) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr60.qrc) -elseif(BUILD_FMR70) - set(EXEC_TARGET emufmr70) - add_definitions(-D_FMR60) - add_definitions(-DHAS_I386) -# set(FLAG_USE_I286 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr60.qrc) -elseif(BUILD_FMR80) - set(EXEC_TARGET emufmr80) - add_definitions(-D_FMR60) - add_definitions(-DHAS_I486) -# set(FLAG_USE_I286 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr60.qrc) -elseif(BUILD_FMR280) - set(EXEC_TARGET emufmr280) - add_definitions(-D_FMR60) - add_definitions(-DHAS_PENTIUM) -# set(FLAG_USE_I286 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr60.qrc) -endif() - -include(config_commonsource) - - diff --git a/source/build-cmake/cmake/config_emumastersystem.cmake b/source/build-cmake/cmake/config_emumastersystem.cmake deleted file mode 100644 index b369609b2..000000000 --- a/source/build-cmake/cmake/config_emumastersystem.cmake +++ /dev/null @@ -1,76 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) -set(VM_NAME gamegear) -set(USE_FMGEN ON) -set(WITH_MOUSE OFF) -set(WITH_JOYSTICK ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES - i8255.cpp - event.cpp - io.cpp - memory.cpp -) -set(VMFILES_LIB - i8251.cpp -) - -set(BUILD_SHARED_LIBS OFF) - -set(BUILD_MASTERSYSTEM OFF CACHE BOOL "Build for Sega MASTER SYSTEM") -set(BUILD_GAMEGEAR OFF CACHE BOOL "Build for Sega Game Gear") -set(BUILD_MARK3 OFF CACHE BOOL "Build for Sega MARK3") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build witn debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(BUILD_GAMEGEAR) - set(EXEC_TARGET emugamegear) - add_definitions(-D_GAMEGEAR) - set(VMFILES ${VMFILES} - ) - set(VMFILES_LIB ${VMFILES_LIB} - 315-5124.cpp - datarec.cpp - sn76489an.cpp - upd765a.cpp - disk.cpp - noise.cpp -) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/gamegear.qrc) -elseif(BUILD_MARK3) - set(EXEC_TARGET emumark3) - add_definitions(-D_MASTERSYSTEM) - set(VMFILES_LIB ${VMFILES_LIB} - 315-5124.cpp - ym2413.cpp - sn76489an.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/segamark3.qrc) -elseif(BUILD_MASTERSYSTEM) - set(EXEC_TARGET emumastersystem) - add_definitions(-D_MASTERSYSTEM) - set(VMFILES_LIB ${VMFILES_LIB} - 315-5124.cpp - ym2413.cpp - sn76489an.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mastersystem.qrc) -endif() - -include(config_commonsource) - diff --git a/source/build-cmake/cmake/config_emupasopia.cmake b/source/build-cmake/cmake/config_emupasopia.cmake deleted file mode 100644 index f4bdfa17e..000000000 --- a/source/build-cmake/cmake/config_emupasopia.cmake +++ /dev/null @@ -1,93 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -message("") -message("** Start of configure CommonSourceProject,PASOPIA/7, Qt **") -message("") - -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES - i8255.cpp - io.cpp - event.cpp -) -set(VMFILES_LIB - datarec.cpp - ls393.cpp - not.cpp - z80pio.cpp - z80ctc.cpp - pcm1bit.cpp - upd765a.cpp - noise.cpp - disk.cpp - hd46505.cpp -) - -if(NOT BUILD_PASOPIA) - set(BUILD_PASOPIA OFF CACHE BOOL "Build for PASOPIA") -endif() - -if(NOT BUILD_PASOPIA_LCD) - set(BUILD_PASOPIA_LCD OFF CACHE BOOL "Build for PASOPIA with LCD") -endif() - -if(NOT BUILD_PASOPIA7) - set(BUILD_PASOPIA7 OFF CACHE BOOL "Build for PASOPIA7") -endif() - -if(NOT BUILD_PASOPIA7_LCD) - set(BUILD_PASOPIA7_LCD OFF CACHE BOOL "Build for PASOPIA7 with LCD") -endif() - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(BUILD_PASOPIA) - set(VM_NAME pasopia) - set(EXEC_TARGET emupasopia) - add_definitions(-D_PASOPIA) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pasopia.qrc) - -elseif(BUILD_PASOPIA_LCD) - set(VM_NAME pasopia) - set(EXEC_TARGET emupasopia_lcd) - add_definitions(-D_PASOPIA) - add_definitions(-D_LCD) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pasopia_lcd.qrc) - -elseif(BUILD_PASOPIA7) - set(VM_NAME pasopia7) - set(EXEC_TARGET emupasopia7) - add_definitions(-D_PASOPIA7) - - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pasopia7.qrc) - set(VMFILES_LIB ${VMFILES_LIB} sn76489an.cpp) - -elseif(BUILD_PASOPIA7_LCD) - set(VM_NAME pasopia7) - set(EXEC_TARGET emupasopia7_lcd) - add_definitions(-D_PASOPIA7) - add_definitions(-D_LCD) - - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pasopia7_lcd.qrc) - set(VMFILES_LIB ${VMFILES_LIB} sn76489an.cpp) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/pasopia7) -endif() - -include(config_commonsource) - - - diff --git a/source/build-cmake/cmake/config_emupc9801.cmake b/source/build-cmake/cmake/config_emupc9801.cmake deleted file mode 100644 index be13949d7..000000000 --- a/source/build-cmake/cmake/config_emupc9801.cmake +++ /dev/null @@ -1,253 +0,0 @@ - -set(VM_NAME pc9801) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES - i8237.cpp - - event.cpp - io.cpp - memory.cpp -) -set(VMFILES_LIB - i8237_base.cpp - i8251.cpp - i8253.cpp - i8255.cpp - i8259.cpp - ls244.cpp - pc80s31k.cpp - tms3631.cpp - upd1990a.cpp - upd7220.cpp - upd765a.cpp - ym2203.cpp - prnfile.cpp - noise.cpp - disk.cpp -) - -set(BUILD_SHARED_LIBS OFF) - -set(BUILD_PC9801 OFF CACHE BOOL "Build on PC9801") -set(BUILD_PC9801E OFF CACHE BOOL "Build on PC9801E") -set(BUILD_PC9801RA OFF CACHE BOOL "Build on PC9801RA") -set(BUILD_PC9801U OFF CACHE BOOL "Build on PC9801U") -set(BUILD_PC9801VF OFF CACHE BOOL "Build on PC9801VF") -set(BUILD_PC9801VM OFF CACHE BOOL "Build on PC9801VM") -set(BUILD_PC9801VX OFF CACHE BOOL "Build on PC9801VX") -set(BUILD_PC98DO OFF CACHE BOOL "Build on PC98DO") -set(BUILD_PC98DOP OFF CACHE BOOL "Build on PC98DO+") -set(BUILD_PC98RL OFF CACHE BOOL "Build on PC9801RL/XL^2") -set(BUILD_PC98XA OFF CACHE BOOL "Build on PC98XA") -set(BUILD_PC98XL OFF CACHE BOOL "Build on PC98XL") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_PC9801) - add_definitions(-D_PC9801) - set(EXEC_TARGET emupc9801) - set(FLAG_USE_Z80 ON) - set(VMFILES ${VMFILES} - ) - set(VMFILES_LIB - beep.cpp - not.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc9801.qrc) -elseif(BUILD_PC9801E) - add_definitions(-D_PC9801E) - set(EXEC_TARGET emupc9801e) - set(VMFILES ${VMFILES} - ) - set(FLAG_USE_Z80 ON) - set(VMFILES_LIB - beep.cpp - not.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc9801e.qrc) -elseif(BUILD_PC9801U) - add_definitions(-D_PC9801U) - set(EXEC_TARGET emupc9801u) - set(VMFILES ${VMFILES} - ) - set(FLAG_USE_Z80 ON) - set(VMFILES_LIB - beep.cpp - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc9801u.qrc) -elseif(BUILD_PC9801VM) - add_definitions(-D_PC9801VM) - set(EXEC_TARGET emupc9801vm) - set(VMFILES ${VMFILES} - ) - set(VMFILES_LIB - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc9801vm.qrc) -elseif(BUILD_PC9801VX) - add_definitions(-D_PC9801VX) - set(EXEC_TARGET emupc9801vx) - set(VMFILES ${VMFILES} - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp - ) - set(VMFILES_LIB - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc9801vx.qrc) -elseif(BUILD_PC98XA) - add_definitions(-D_PC98XA) - set(EXEC_TARGET emupc98xa) - set(VMFILES ${VMFILES} - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp - ) - set(VMFILES_LIB - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc98xa.qrc) -elseif(BUILD_PC98XL) - add_definitions(-D_PC98XL) - set(EXEC_TARGET emupc98xl) - set(VMFILES ${VMFILES} - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp - ) - set(VMFILES_LIB - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc98xl.qrc) -elseif(BUILD_PC9801VF) - add_definitions(-D_PC9801VF) - set(EXEC_TARGET emupc9801vf) - set(VMFILES ${VMFILES} - ) - set(VMFILES_LIB - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc9801vf.qrc) -elseif(BUILD_PC9801RA) - add_definitions(-D_PC9801RA) - set(EXEC_TARGET emupc9801ra) - set(VMFILES ${VMFILES} - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp - ) - set(VMFILES_LIB - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 OFF) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc9801ra.qrc) -elseif(BUILD_PC98RL) - add_definitions(-D_PC98RL) - set(EXEC_TARGET emupc98rl) - set(VMFILES ${VMFILES} - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp - ) - set(VMFILES_LIB - not.cpp - pcm1bit.cpp - ${VMFILES_LIB} - ) -# set(FLAG_USE_I286 OFF) -# set(FLAG_USE_I86 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc98rl.qrc) -elseif(BUILD_PC98DO) - add_definitions(-D_PC98DO) - set(EXEC_TARGET emupc98do) - set(VMFILES ${VMFILES} - ) - set(FLAG_USE_Z80 ON) - set(VMFILES_LIB ${VMFILES_LIB} - pc80s31k.cpp - beep.cpp - not.cpp - pcm1bit.cpp - upd4991a.cpp - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(VM_APPEND_LIBS vm_pc8801) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc98do.qrc) -elseif(BUILD_PC98DOP) - add_definitions(-D_PC98DOPLUS) - set(EXEC_TARGET emupc98doplus) - set(VMFILES ${VMFILES} - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp - ) - set(FLAG_USE_Z80 ON) - set(VMFILES_LIB ${VMFILES_LIB} - pc80s31k.cpp - beep.cpp - not.cpp - pcm1bit.cpp - upd4991a.cpp - ) -# set(FLAG_USE_I286 ON) -# set(FLAG_USE_I86 ON) - set(VM_APPEND_LIBS vm_pc8801) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc98doplus.qrc) -endif() - - -if(BUILD_PC98DO) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/pc8801) -elseif(BUILD_PC98DOP) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/pc8801) -endif() - -include(config_commonsource) - -if(BUILD_PC98DO) - add_subdirectory(../../src/vm/pc8801 vm/pc8801) -endif() diff --git a/source/build-cmake/cmake/config_fmtowns.cmake b/source/build-cmake/cmake/config_fmtowns.cmake deleted file mode 100644 index 6c1dc7334..000000000 --- a/source/build-cmake/cmake/config_fmtowns.cmake +++ /dev/null @@ -1,88 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -set(VM_NAME fmtowns) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) -set(VMFILES - event.cpp - io.cpp - - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp - scsi_cdrom.cpp -) -set(VMFILES_LIB - noise.cpp - pcm1bit.cpp - i8251.cpp - i8253.cpp - i8259.cpp - msm58321.cpp - upd71071.cpp - - mb8877.cpp - ym2151.cpp - - disk.cpp - prnfile.cpp - harddisk.cpp -) - -set(FLAG_USE_I386 ON) - -set(BUILD_FMTOWNS_2 OFF CACHE BOOL "Build for FM-Towns Model 2") -set(BUILD_FMTOWNS_2H OFF CACHE BOOL "Build for FM-Towns 2H") -set(BUILD_FMTOWNS_20H OFF CACHE BOOL "Build for FM-Towns 20H") -set(BUILD_FMTOWNS2_UX40 OFF CACHE BOOL "Build for FM-Towns2 UX40") -set(BUILD_FMTOWNS2_CX100 OFF CACHE BOOL "Build for FM-Towns2 CX100") - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_FMTOWNS_2) - set(EXEC_TARGET emufmtowns_2) - add_definitions(-D_FMTOWNS_2) - ## ToDo - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1.qrc) -elseif(BUILD_FMTOWNS_2H) - set(EXEC_TARGET emufmtowns2H) - add_definitions(-D_FMTOWNS_2H) - ## ToDo - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1.qrc) -elseif(BUILD_FMTOWNS_20H) - set(EXEC_TARGET emufmtowns40H) - add_definitions(-D_FMTOWNS_40H) - ## ToDo - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1.qrc) -elseif(BUILD_FMTOWNS2_UX40) - set(EXEC_TARGET emufmtownsUX40) - add_definitions(-D_FMTOWNS2_UX40) - ## ToDo - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1.qrc) -elseif(BUILD_FMTOWNS2_CX100) - set(EXEC_TARGET emufmtownsCX100) - add_definitions(-D_FMTOWNS2_CX100) - ## ToDo - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1.qrc) -endif() - -include(config_commonsource) - - diff --git a/source/build-cmake/cmake/config_msx.cmake b/source/build-cmake/cmake/config_msx.cmake deleted file mode 100644 index 19e3617af..000000000 --- a/source/build-cmake/cmake/config_msx.cmake +++ /dev/null @@ -1,148 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -message("") -message("** Start of configure CommonSourceProject,MSX Series Qt **") -message("") - -set(VMFILES_BASE - event.cpp - io.cpp - memory.cpp -) - -set(VMFILES_LIB - datarec.cpp - ay_3_891x.cpp - i8255.cpp - not.cpp - pcm1bit.cpp - ym2413.cpp - prnfile.cpp - noise.cpp -) -set(FLAG_USE_Z80 ON) - -#set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) -add_definitions(-D_MSX_VDP_MESS) - -set(VMFILES_MSX2 ${VMFILES_BASE} -) - -set(VMFILES_LIB_MSX2 ${VMFILES_LIB} - disk.cpp - v9938.cpp - v99x8.cpp - rp5c01.cpp -) - -set(VMFILES_LIB ${VMFILES_LIB} disk.cpp) - -set(VMFILES_MSX1 ${VMFILES_BASE} -) -set(VMFILES_LIB_MSX1 ${VMFILES_LIB} - tms9918a.cpp - disk.cpp -) - - -set(VMFILES_PX7 ${VMFILES_BASE} - ld700.cpp -) -set(VMFILES_LIB_PX7 ${VMFILES_LIB} - tms9918a.cpp -) - -set(VMFILES_HX20 ${VMFILES_BASE} -) - -set(VMFILES_LIB_HX20 ${VMFILES_LIB} - tms9918a.cpp - disk.cpp -) - -set(VMFILES_FSA1 ${VMFILES_BASE} -) -set(VMFILES_LIB_FSA1 ${VMFILES_LIB} - rp5c01.cpp - v9938.cpp - disk.cpp -) - -set(VMFILES_HBF1XDJ ${VMFILES_BASE} -) -set(VMFILES_LIB_HBF1XDJ ${VMFILES_LIB} - rp5c01.cpp - v9938.cpp - disk.cpp -) - -set(VMFILES_MSX2PLUS ${VMFILES_BASE} -) - -set(VMFILES_LIB_MSX2PLUS ${VMFILES_LIB} - rp5c01.cpp - v9938.cpp - disk.cpp -) - -if(BUILD_PX7) - set(VMFILES ${VMFILES_PX7}) - set(VMFILES_LIB ${VMFILES_LIB_PX7}) - add_definitions(-D_PX7) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/px7.qrc) -elseif(BUILD_MSX2) - set(VMFILES ${VMFILES_MSX2}) - set(VMFILES_LIB ${VMFILES_LIB_MSX2}) - add_definitions(-D_MSX2) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/msx2.qrc) -elseif(BUILD_MSX2PLUS) - set(VMFILES ${VMFILES_MSX2PLUS}) - set(VMFILES_LIB ${VMFILES_LIB_MSX2PLUS}) - add_definitions(-D_MSX2P) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/msx2plus.qrc) -elseif(BUILD_HX20) - set(VMFILES ${VMFILES_HX20}) - set(VMFILES_LIB ${VMFILES_LIB_HX20}) - add_definitions(-D_HX20) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/hx20.qrc) -elseif(BUILD_FSA1) - set(VMFILES ${VMFILES_FSA1}) - set(VMFILES_LIB ${VMFILES_LIB_FSA1}) - add_definitions(-D_FSA1) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fsa1.qrc) -elseif(BUILD_HBF1XDJ) - set(VMFILES ${VMFILES_HBF1XDJ}) - set(VMFILES_LIB ${VMFILES_LIB_HBF1XDJ}) - add_definitions(-D_HBF1XDJ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/hbf1xdj.qrc) -else() - set(VMFILES ${VMFILES_MSX1}) - set(VMFILES_LIB ${VMFILES_LIB_MSX1}) - add_definitions(-D_MSX1) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/msx1.qrc) -endif() - -if(USE_CMT_SOUND) - set(VMFILES_MSX ${VMFILES_BASE}) -endif() - -include(config_commonsource) - - - - - diff --git a/source/build-cmake/cmake/config_mz2500.cmake b/source/build-cmake/cmake/config_mz2500.cmake deleted file mode 100644 index 1bb6ce4d7..000000000 --- a/source/build-cmake/cmake/config_mz2500.cmake +++ /dev/null @@ -1,132 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -set(VM_NAME mz2500) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) -set(FLAG_USE_Z80 ON) -set(VMFILES_2500 - w3100a.cpp - - scsi_host.cpp - scsi_dev.cpp; - scsi_hdd.cpp - -) -set(VMFILES_LIB_2500 - ls393.cpp - rp5c01.cpp - ym2203.cpp - z80sio.cpp - - harddisk.cpp -) - -set(VMFILES_BASE - mz1p17.cpp - - event.cpp - memory.cpp - io.cpp - - ) -set(VMFILES_LIB - noise.cpp - datarec.cpp - i8253.cpp - i8255.cpp - - pcm1bit.cpp - z80pio.cpp - mb8877.cpp - disk.cpp - prnfile.cpp -) -set(VMFILES_QD - mz700/quickdisk.cpp -) -set(VMFILES_LIB_QD - z80sio.cpp -) - -#set(VMFILES_16BIT -# i286.cpp -# ) -set(VMFILES_LIB_16BIT - i86.cpp - i8259.cpp -) - -set(BUILD_MZ2500 OFF CACHE BOOL "Build EMU-MZ2500") -set(BUILD_MZ2200 OFF CACHE BOOL "Build EMU-MZ2200") -set(BUILD_MZ2000 OFF CACHE BOOL "Build EMU-MZ2000") -set(BUILD_MZ80B OFF CACHE BOOL "Build EMU-MZ80B") - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(XM7_VERSION 3) -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_MZ2500) - -set(VMFILES ${VMFILES_2500} ${VMFILES_BASE}) -set(VMFILES_LIB ${VMFILES_LIB} ${VMFILES_LIB_2500}) - -add_definitions(-D_MZ2500) -set(EXEC_TARGET emumz2500) -set(USE_SOCKET ON) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz2500.qrc) -set(USE_FMGEN ON) - -elseif(BUILD_MZ2000) -set(VMFILES ${VMFILES_BASE} ${VMFILES_QD} ) -set(VMFILES_LIB ${VMFILES_LIB} ${VMFILES_LIB_QD} ${VMFILES_LIB_16BIT}) -add_definitions(-D_MZ2000) -set(EXEC_TARGET emumz2000) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz2000.qrc) -set(USE_FMGEN OFF) - -elseif(BUILD_MZ2200) -set(VMFILES ${VMFILES_BASE} ${VMFILES_QD} ) -set(VMFILES_LIB ${VMFILES_LIB} ${VMFILES_LIB_QD} ${VMFILES_LIB_16BIT}) -set(LOCAL_LIBS ${LOCAL_LIBS}) -add_definitions(-D_MZ2200) -set(EXEC_TARGET emumz2200) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz2200.qrc) -set(USE_FMGEN OFF) - -elseif(BUILD_MZ80B) -set(VMFILES ${VMFILES_BASE}) -set(LOCAL_LIBS ${LOCAL_LIBS}) -add_definitions(-D_MZ80B) -set(EXEC_TARGET emumz80b) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz80b.qrc) -set(USE_FMGEN OFF) - -endif() - - - - -#include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/mz2500) -if(BUILD_MZ2200) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/mz700) -elseif(BUILD_MZ2000) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/mz700) -endif() -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/machines/mz2500) - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_mz5500.cmake b/source/build-cmake/cmake/config_mz5500.cmake deleted file mode 100644 index 1923068e1..000000000 --- a/source/build-cmake/cmake/config_mz5500.cmake +++ /dev/null @@ -1,62 +0,0 @@ -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(VM_NAME mz5500) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES -# i286.cpp - i8237.cpp - mz1p17.cpp - - event.cpp - io.cpp -) - -set(VMFILES_LIB - ay_3_891x.cpp - disk.cpp - i8237_base.cpp - i8255.cpp - i8259.cpp - ls393.cpp - not.cpp - noise.cpp - prnfile.cpp - rp5c01.cpp - upd765a.cpp - upd7220.cpp - z80ctc.cpp - z80sio.cpp -) -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(BUILD_MZ5500 OFF CACHE BOOL "Build emumz5500") -set(BUILD_MZ6500 OFF CACHE BOOL "Build emumz6500") -set(BUILD_MZ6550 OFF CACHE BOOL "Build emumz6550") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_MZ5500) - add_definitions(-D_MZ5500) - set(EXEC_TARGET emumz5500) -# set(FLAG_USE_I86 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz5500.qrc) -elseif(BUILD_MZ6500) - add_definitions(-D_MZ6500) - set(EXEC_TARGET emumz6500) -# set(FLAG_USE_I86 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz6500.qrc) -else() - add_definitions(-D_MZ6550) - set(EXEC_TARGET emumz6550) -# set(FLAG_USE_I286 ON) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz6550.qrc) -endif() - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_mz700.cmake b/source/build-cmake/cmake/config_mz700.cmake deleted file mode 100644 index 6ae835bfe..000000000 --- a/source/build-cmake/cmake/config_mz700.cmake +++ /dev/null @@ -1,94 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) -set(VM_NAME mz700) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - event.cpp - io.cpp - memory.cpp -) - -set(VMFILES_MZ800 ${VMFILES_BASE} -) - - -set(VMFILES_MZ1500 ${VMFILES_MZ800} - prnfile.cpp - mz1p17.cpp -) - -set(VMFILES_LIB - noise.cpp - datarec.cpp - i8255.cpp - i8253.cpp - - beep.cpp - pcm1bit.cpp - and.cpp -) -set(VMFILES_LIB_MZ800 - z80sio.cpp - mb8877.cpp - disk.cpp - not.cpp - z80pio.cpp - sn76489an.cpp -) - -set(VMFILES_LIB_MZ1500 ${VMFILES_LIB_MZ800} - ym2203.cpp - prnfile.cpp -) - -set(BUILD_MZ700 OFF CACHE BOOL "Build EMU-MZ800") -set(BUILD_MZ800 OFF CACHE BOOL "Build EMU-MZ800") -set(BUILD_MZ1500 OFF CACHE BOOL "Build EMU-MZ1500") - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - - -if(BUILD_MZ1500) - -set(VMFILES ${VMFILES_MZ1500}) -add_definitions(-D_MZ1500) -set(EXEC_TARGET emumz1500) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz1500.qrc) -set(VMFILES_LIB ${VMFILES_LIB} ${VMFILES_LIB_MZ1500}) -set(USE_FMGEN OFF) -elseif(BUILD_MZ800) - -set(VMFILES ${VMFILES_MZ800}) -add_definitions(-D_MZ800) -set(EXEC_TARGET emumz800) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz800.qrc) -set(VMFILES_LIB ${VMFILES_LIB} ${VMFILES_LIB_MZ800}) -set(USE_FMGEN OFF) -else() - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_MZ700) -set(EXEC_TARGET emumz700) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz700.qrc) -set(USE_FMGEN OFF) -endif() - -include(config_commonsource) - - diff --git a/source/build-cmake/cmake/config_mz80.cmake b/source/build-cmake/cmake/config_mz80.cmake deleted file mode 100644 index a7e53326f..000000000 --- a/source/build-cmake/cmake/config_mz80.cmake +++ /dev/null @@ -1,106 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -set(VM_NAME mz80k) -set(USE_FMGEN OFF) -set(USE_DEBUGGER ON) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) - -set(VMFILES_BASE - mz1p17.cpp - event.cpp - io.cpp - memory.cpp -) - -set(VMFILES_LIB - noise.cpp - beep.cpp - datarec.cpp - i8253.cpp - i8255.cpp - ls393.cpp - pcm1bit.cpp - prnfile.cpp -) -set(FLAG_USE_Z80 ON) - -set(BUILD_MZ80A OFF CACHE BOOL "Build EMU-MZ80A") -set(BUILD_MZ80K OFF CACHE BOOL "Build EMU-MZ80A") -set(BUILD_MZ1200 OFF CACHE BOOL "Build EMU-MZ1200") - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") - -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(XM7_VERSION 3) -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_MZ1200) - -set(VMFILES ${VMFILES_BASE} - and.cpp -# t3444a.cpp -# disk.cpp - ) -set(VMFILES_LIB ${VMFILES_LIB} - t3444a.cpp - disk.cpp -) -add_definitions(-D_MZ1200) -set(EXEC_TARGET emumz1200) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz1200.qrc) -set(BUILD_MZ80FIO ON) - -elseif(BUILD_MZ80A) - -set(VMFILES ${VMFILES_BASE} - and.cpp - ) -add_definitions(-D_MZ80A) -set(EXEC_TARGET emumz80A) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz80a.qrc) -set(BUILD_MZ80AIF ON) - -else() - -set(BUILD_MZ80FIO ON) -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_MZ80K) -set(EXEC_TARGET emumz80k) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz80k.qrc) -set(VMFILES ${VMFILES_BASE} -# t3444a.cpp -# disk.cpp - ) -set(VMFILES_LIB ${VMFILES_LIB} - t3444a.cpp - disk.cpp -) -endif() - -if(BUILD_MZ80A) -set(VMFILES ${VMFILES} -# mb8877.cpp -# disk.cpp - io.cpp ) -#add_definitions(-DSUPPORT_MZ80AIF) -set(VMFILES_LIB ${VMFILES_LIB} - mb8877.cpp - disk.cpp -) -endif() - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_pc6001.cmake b/source/build-cmake/cmake/config_pc6001.cmake deleted file mode 100644 index 2f4a36ca5..000000000 --- a/source/build-cmake/cmake/config_pc6001.cmake +++ /dev/null @@ -1,98 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -set(VM_NAME pc6001) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES - i8255.cpp - event.cpp - io.cpp - memory.cpp -) - -set(VMFILES_LIB - noise.cpp - datarec.cpp - pc6031.cpp - pc80s31k.cpp - upd765a.cpp - - prnfile.cpp - disk.cpp -) -set(FLAG_USE_MCS48 ON) -set(FLAG_USE_Z80 ON) - -set(BUILD_SHARED_LIBS OFF) - -set(BUILD_PC6001 OFF CACHE BOOL "Build on PC6001") -set(BUILD_PC6001MK2 OFF CACHE BOOL "Build on PC6001mk2") -set(BUILD_PC6001MK2SR OFF CACHE BOOL "Build on PC6001mk2SR") -set(BUILD_PC6601 OFF CACHE BOOL "Build on PC6601") -set(BUILD_PC6601SR OFF CACHE BOOL "Build on PC6601SR") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build witn Debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_PC6001) - add_definitions(-D_PC6001) - set(EXEC_TARGET emupc6001) - set(VMFILES ${VMFILES} - mc6847.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} - ay_3_891x.cpp - mc6847_base.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc6001.qrc) -elseif(BUILD_PC6001MK2) - add_definitions(-D_PC6001MK2) - set(EXEC_TARGET emupc6001mk2) - set(VMFILES_LIB ${VMFILES_LIB} - upd7752.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} - ay_3_891x.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc6001mk2.qrc) -elseif(BUILD_PC6001MK2SR) - add_definitions(-D_PC6001MK2SR) - set(EXEC_TARGET emupc6001mk2sr) - set(VMFILES_LIB ${VMFILES_LIB} - upd7752.cpp - ym2203.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc6001mk2sr.qrc) -elseif(BUILD_PC6601) - add_definitions(-D_PC6601) - set(EXEC_TARGET emupc6601) - set(VMFILES_LIB ${VMFILES_LIB} - ay_3_891x.cpp - upd7752.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc6601.qrc) -elseif(BUILD_PC6601SR) - add_definitions(-D_PC6601SR) - set(EXEC_TARGET emupc6601sr) - set(VMFILES_LIB ${VMFILES_LIB} - upd7752.cpp - ym2203.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc6601sr.qrc) -endif() - -include(config_commonsource) - diff --git a/source/build-cmake/cmake/config_pc8201.cmake b/source/build-cmake/cmake/config_pc8201.cmake deleted file mode 100644 index 0e8685161..000000000 --- a/source/build-cmake/cmake/config_pc8201.cmake +++ /dev/null @@ -1,50 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(VM_NAME pc8201) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) -set(VMFILES - i8080.cpp - io.cpp - event.cpp -) -set(VMFILES_LIB - noise.cpp - datarec.cpp - i8080_base.cpp - i8155.cpp - pcm1bit.cpp - upd1990a.cpp -) - - -set(BUILD_SHARED_LIBS OFF) - -set(BUILD_PC8201 OFF CACHE BOOL "Build on PC-8201") -set(BUILD_PC8201A OFF CACHE BOOL "Build on PC-8201A") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build witn XM7 Debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_PC8201) - add_definitions(-D_PC8201) - set(EXEC_TARGET emupc8201) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8201.qrc) -elseif(BUILD_PC8201A) - add_definitions(-D_PC8201A) - set(EXEC_TARGET emupc8201a) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8201a.qrc) -endif() -include(config_commonsource) - diff --git a/source/build-cmake/cmake/config_pc8801.cmake b/source/build-cmake/cmake/config_pc8801.cmake deleted file mode 100644 index bd02c3b6c..000000000 --- a/source/build-cmake/cmake/config_pc8801.cmake +++ /dev/null @@ -1,114 +0,0 @@ -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(VM_NAME pc8801) -set(USE_FMGEN ON) -set(USE_DEBUGGER ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES - event.cpp - io.cpp - memory.cpp -) -set(VMFILES_LIB - noise.cpp - beep.cpp - datarec.cpp - i8251.cpp - i8255.cpp - - pc80s31k.cpp - pcm1bit.cpp - upd1990a.cpp - upd765a.cpp - z80ctc.cpp - z80dma.cpp - z80pio.cpp - z80sio.cpp - disk.cpp - - prnfile.cpp -) -set(FLAG_USE_Z80 ON) - -set(BUILD_SHARED_LIBS OFF) - -set(BUILD_PC8001 OFF CACHE BOOL "Build for PC8001") -set(BUILD_PC8001MK2 OFF CACHE BOOL "Build for PC8001 mk2") -set(BUILD_PC8001SR OFF CACHE BOOL "Build for PC8001SR") -set(BUILD_PC8801 OFF CACHE BOOL "Build with PC8801") -set(BUILD_PC8801MK2 OFF CACHE BOOL "Build with PC8801 mk2") -set(BUILD_PC8801MA OFF CACHE BOOL "Build with PC8801MA") - -set(USE_PCG ON CACHE BOOL "Use PCG8100") -set(PC88_EXTRAM_PAGES "4" CACHE STRING "Set banks of EXTRAM of PC8801, bank = 32Kbytes") -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with Debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(BUILD_PC8001) - set(EXEC_TARGET emupc8001) - add_definitions(-D_PC8001) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8001.qrc) - -elseif(BUILD_PC8001MK2) - set(EXEC_TARGET emupc8001mk2) - add_definitions(-D_PC8001MK2) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8001mk2.qrc) - set(VMFILES_LIB ${VMFILES_LIB} - ym2203.cpp - ) - -elseif(BUILD_PC8001SR) - set(EXEC_TARGET emupc8001sr) - add_definitions(-D_PC8001SR) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8001mk2sr.qrc) - set(VMFILES_LIB ${VMFILES_LIB} - ym2203.cpp - ) - -elseif(BUILD_PC8801) - set(EXEC_TARGET emupc8801) - add_definitions(-D_PC8801) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8801.qrc) - -elseif(BUILD_PC8801MK2) - set(EXEC_TARGET emupc8801mk2) - add_definitions(-D_PC8801MK2) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8801mk2.qrc) - set(VMFILES_LIB ${VMFILES_LIB} - ym2203.cpp - ) - -elseif(BUILD_PC8801MA) - set(EXEC_TARGET emupc8801ma) - add_definitions(-D_PC8801MA) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc8801ma.qrc) - set(VMFILES_LIB ${VMFILES_LIB} - ym2203.cpp - ym2151.cpp - ) - set(VMFILES ${VMFILES} - scsi_dev.cpp scsi_cdrom.cpp scsi_host.cpp - ) -endif() - -add_definitions(-DPC88_EXRAM_BANKS=${PC88_EXTRAM_PAGES}) - -if(USE_PCG) - set(VMFILES_LIB ${VMFILES_LIB} - i8253.cpp - ) - add_definitions(-DSUPPORT_PC88_PCG8100) -endif() - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_pc98ha.cmake b/source/build-cmake/cmake/config_pc98ha.cmake deleted file mode 100644 index 609640750..000000000 --- a/source/build-cmake/cmake/config_pc98ha.cmake +++ /dev/null @@ -1,61 +0,0 @@ - -set(VM_NAME pc98ha) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES -# i286.cpp - event.cpp - io.cpp - memory.cpp -) -set(VMFILES_LIB - noise.cpp - beep.cpp - i8251.cpp - i8253.cpp - i8255.cpp - i8259.cpp - ls244.cpp - not.cpp - - upd71071.cpp - upd765a.cpp - disk.cpp - prnfile.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(BUILD_PC98HA OFF CACHE BOOL "Build on PC98 HA") -set(BUILD_PC98LT OFF CACHE BOOL "Build on PC98 LT") -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - - - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_PC98HA) - add_definitions(-D_PC98HA) - set(EXEC_TARGET emupc98ha) - set(VMFILES_LIB ${VMFILES_LIB} - upd4991a.cpp - ) - set(FLAG_USE_I86 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc98ha.qrc) -elseif(BUILD_PC98LT) - add_definitions(-D_PC98LT) - set(EXEC_TARGET emupc98lt) - set(VMFILES ${VMFILES} - upd1990a.cpp - ) - set(FLAG_USE_I86 OFF) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc98lt.qrc) -endif() - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_phc25.cmake b/source/build-cmake/cmake/config_phc25.cmake deleted file mode 100644 index 14c7ea20c..000000000 --- a/source/build-cmake/cmake/config_phc25.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(VM_NAME phc25) -set(USE_FMGEN ON) -set(WITH_MOUSE OFF) -set(WITH_JOYSTICK ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES - mc6847.cpp - io.cpp - - event.cpp -) -set(VMFILES_LIB - ay_3_891x.cpp - noise.cpp - datarec.cpp - mc6847_base.cpp - not.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -include(detect_target_cpu) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") -set(BUILD_PHC25 OFF CACHE BOOL "Build ePHC25") -set(BUILD_MAP1010 OFF CACHE BOOL "Build eMAP1010") -set(WITH_DEBUGGER ON CACHE BOOL "Use debugger") - -if(BUILD_PHC25) - add_definitions(-D_PHC25) - set(EXEC_TARGET emuphc25) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/phc25.qrc) -elseif(BUILD_MAP1010) - add_definitions(-D_MAP1010) - set(EXEC_TARGET emumap1010) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/map1010.qrc) -endif() - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_qc10.cmake b/source/build-cmake/cmake/config_qc10.cmake deleted file mode 100644 index 612790a96..000000000 --- a/source/build-cmake/cmake/config_qc10.cmake +++ /dev/null @@ -1,50 +0,0 @@ -set(VM_NAME qc10) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES - i8237.cpp - io.cpp - event.cpp -) -set(VMFILES_LIB - noise.cpp - i8237_base.cpp - i8253.cpp - i8255.cpp - i8259.cpp - hd146818p.cpp - pcm1bit.cpp - upd7220.cpp - upd765a.cpp - z80sio.cpp - - disk.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(BUILD_QC10 OFF CACHE BOOL "Build emuqc10 (Monochrome)") -set(BUILD_QC10COLOR OFF CACHE BOOL "Build emuqc10_cms") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) -add_definitions(-D_QC10) -if(BUILD_QC10COLOR) - set(EXEC_TARGET emuqc10_cms) - add_definitions(-D_COLOR_MONITOR) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/qc10cms.qrc) -else() - set(EXEC_TARGET emuqc10) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/qc10.qrc) -endif() - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_sharedlibs.cmake b/source/build-cmake/cmake/config_sharedlibs.cmake deleted file mode 100644 index 39eb44c15..000000000 --- a/source/build-cmake/cmake/config_sharedlibs.cmake +++ /dev/null @@ -1,203 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -#set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -include(CheckFunctionExists) -#include(cotire) - -if(USE_DEVICES_SHARED_LIB) - add_definitions(-DUSE_SHARED_DLL) -endif() -# Use cmake if enabled. - find_program(USE_CCACHE ccache) - if(USE_CCACHE) - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) - endif() - if(NOT CSP_CROSS_BUILD) - #SET(CMAKE_FIND_ROOT_PATH /opt/Qt5.5.1/5.5/gcc_64 ${CMAKE_FIND_ROOT_PATH}) - endif() - FIND_PACKAGE(Qt5Widgets REQUIRED) - FIND_PACKAGE(Qt5Core REQUIRED) - FIND_PACKAGE(Qt5Gui REQUIRED) - FIND_PACKAGE(Qt5OpenGL REQUIRED) - include_directories(${Qt5Widgets_INCLUDE_DIRS}) - include_directories(${Qt5Core_INCLUDE_DIRS}) - include_directories(${Qt5Gui_INCLUDE_DIRS}) - include_directories(${Qt5OpenGL_INCLUDE_DIRS}) - add_definitions(-D_USE_OPENGL -DUSE_OPENGL) -if(USE_SOCKET) - FIND_PACKAGE(Qt5Network REQUIRED) - include_directories(${Qt5Network_INCLUDE_DIRS}) -endif() - -SET(USE_QT_5 ON) -set(USE_QT5_4_APIS OFF CACHE BOOL "Build with Qt5.4 (or later) APIs if you can.") -set(USE_GCC_OLD_ABI ON CACHE BOOL "Build with older GCC ABIs if you can.") -set(USE_SDL2 ON CACHE BOOL "Build with libSDL2. DIsable is building with libSDL1.") -set(USE_MOVIE_SAVER OFF CACHE BOOL "Save screen/audio as MP4 MOVIE. Needs libav .") -set(USE_MOVIE_LOADER OFF CACHE BOOL "Load movie from screen for some VMs. Needs libav .") -set(USE_LTO ON CACHE BOOL "Use link-time-optimization to build.") -if(USE_LTO) -# set_property(DIRECTORY PROPERTY INTERPROCEDURAL_OPTIMIZATION true) -else() -# set_property(DIRECTORY PROPERTY INTERPROCEDURAL_OPTIMIZATION false) -endif() - -add_definitions(-D_USE_QT5) -if(NOT WIN32) - add_definitions(-D_UNICODE) -endif() - -if(USE_QT5_4_APIS) - add_definitions(-D_USE_QT_5_4) -else() - #add_definitions(-DQT_NO_VERSION_TAGGING) -endif() - -if(USE_GCC_OLD_ABI) - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) -else() - add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) -endif() - -include(FindZLIB) -if(ZLIB_FOUND) - add_definitions(-DUSE_ZLIB) - include_directories(${ZLIB_INCLUDE_DIRS}) -endif() - -SET(CMAKE_AUTOMOC OFF) -SET(CMAKE_AUTORCC ON) -SET(CMAKE_INCLUDE_CURRENT_DIR ON) - - -add_definitions(-D_USE_QT) -add_definitions(-DUSE_QT) -add_definitions(-DQT_MAJOR_VERSION=${Qt5Widgets_VERSION_MAJOR}) -add_definitions(-DQT_MINOR_VERSION=${Qt5Widgets_VERSION_MINOR}) - -if(USE_OPENMP) - find_package(OpenMP) - include_directories(${OPENMP_INCLUDE_PATH}) - if(OPENMP_FOUND) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - endif() -endif() - -find_package(Threads) -include_directories(${THREADS_INCLUDE_PATH}) - -include(FindPkgConfig) - -find_package(Git) -if(GIT_FOUND) - execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD OUTPUT_VARIABLE __tstr) - string(FIND ${__tstr} "fatal" __notfound) - string(REPLACE "\n" "" __tstr2 ${__tstr}) - if(${__notfound} EQUAL -1) - add_definitions(-D__GIT_REPO_VERSION=${__tstr2}) - else() - add_definitions(-U__GIT_REPO_VERSION) - endif() -endif() - -string(TIMESTAMP __build_date "%b %d,%Y %H:%M:%S UTC" UTC) -add_definitions(-D__BUILD_DATE=\"${__build_date}\") - -include(FindLibAV) -if(LIBAV_FOUND) - add_definitions(-DUSE_LIBAV) - if(USE_MOVIE_SAVER) - add_definitions(-DUSE_MOVIE_SAVER) - endif() - if(USE_MOVIE_LOADER) - add_definitions(-DUSE_MOVIE_LOADER) - endif() - add_definitions(-D__STDC_CONSTANT_MACROS) - add_definitions(-D__STDC_FORMAT_MACROS) -else() - set(USE_MOVIE_SAVER OFF) - set(USE_MOVIE_LOADER OFF) - set(LIBAV_LIBRARIES "") -endif() -if(USE_SDL2) - if(CMAKE_CROSSCOMPILING) - include_directories(${SDL2_INCLUDE_DIRS}) - else() - pkg_search_module(SDL2 REQUIRED sdl2) - include_directories(${SDL2_INCLUDE_DIRS}) - endif() - set(SDL_LIBS ${SDL2_LIBRARIES}) - add_definitions(-DUSE_SDL2) -else() - if(CMAKE_CROSSCOMPILING) - include_directories(${SDL_INCLUDE_DIRS}) - set(SDL_LIBS ${SDL_LIBRARIES}) - else() - include(FindSDL) - #pkg_search_module(SDL REQUIRED sdl) - #include_directories(${SDL_INCLUDE_DIRS}) - include_directories(${SDL_INCLUDE_DIR}) - set(SDL_LIBS ${SDL_LIBRARY}) - endif() -endif() - -set(SRC_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../src) - -if(USE_QT_5) - if(NOT WIN32) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - endif() -endif() - -if(LIBAV_FOUND) - include_directories(${LIBAV_INCLUDE_DIRS}) -endif() - -add_definitions(-D_USE_QT5) - -if(USE_QT5_4_APIS) - add_definitions(-D_USE_QT_5_4) -endif() - -# GCC Only? -if(CMAKE_COMPILER_IS_GNUCC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flax-vector-conversions") -endif() - -if(CMAKE_COMPILER_IS_GNUCXX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -flax-vector-conversions") -endif() - - -check_function_exists("nanosleep" HAVE_NANOSLEEP) -if(NOT HAVE_NANOSLEEP) - check_library_exists("rt" "nanosleep" "" LIB_RT_HAS_NANOSLEEP) -endif(NOT HAVE_NANOSLEEP) - -if(LIB_RT_HAS_NANOSLEEP) - add_target_library(${EXEC_TARGET} rt) -endif(LIB_RT_HAS_NANOSLEEP) - -if(HAVE_NANOSLEEP OR LIB_RT_HAS_NANOSLEEP) - add_definitions(-DHAVE_NANOSLEEP) -endif(HAVE_NANOSLEEP OR LIB_RT_HAS_NANOSLEEP) - - -set(SRC_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../src) - - - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/gui) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src) diff --git a/source/build-cmake/cmake/config_smc777.cmake b/source/build-cmake/cmake/config_smc777.cmake deleted file mode 100644 index 3f5202e4e..000000000 --- a/source/build-cmake/cmake/config_smc777.cmake +++ /dev/null @@ -1,55 +0,0 @@ - -set(VM_NAME smc777) -set(USE_FMGEN OFF) -set(WITH_MOUSE ON) -set(WITH_JOYSTICK ON) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(BUILD_SMC70 OFF CACHE BOOL "Build SMC-70") -set(BUILD_SMC777 OFF CACHE BOOL "Build SMC-777") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(FLAG_USE_Z80 ON) -if(BUILD_SMC70) - set(EXEC_TARGET emusmc70) - set(VMFILES_BASE - msm58321.cpp - event.cpp - ) -set(VMFILES_LIB - noise.cpp - datarec.cpp - hd46505.cpp - mb8877.cpp - msm58321_base.cpp - pcm1bit.cpp - disk.cpp -) - add_definitions(-D_SMC70) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/smc70.qrc) -elseif(BUILD_SMC777) - - set(EXEC_TARGET emusmc777) - set(VMFILES_BASE - event.cpp - ) - set(VMFILES_LIB - datarec.cpp - hd46505.cpp - sn76489an.cpp - pcm1bit.cpp - mb8877.cpp - disk.cpp - ) - add_definitions(-D_SMC777) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/smc777.qrc) -endif() - -set(VMFILES ${VMFILES_BASE}) - -include(config_commonsource) - diff --git a/source/build-cmake/cmake/config_tk80.cmake b/source/build-cmake/cmake/config_tk80.cmake deleted file mode 100644 index d194e9655..000000000 --- a/source/build-cmake/cmake/config_tk80.cmake +++ /dev/null @@ -1,66 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,TK-80/80 BS/85, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emutk80bs) - -set(WITH_MOUSE ON) - -set(VMFILES_BASE - i8080.cpp - memory.cpp - event.cpp -) -set(VMFILES_LIB - i8080_base.cpp - i8255.cpp - pcm1bit.cpp -) - -if(BUILD_TK80BS) - add_definitions(-D_TK80BS) - set(EXEC_TARGET emutk80bs) - set(VM_NAME tk80bs) - set(VMFILES_LIB ${VMFILES_LIB} noise.cpp datarec.cpp i8251.cpp) - set(VMFILES_BASE ${VMFILES_BASE} io.cpp) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/tk80bs.qrc) -elseif(BUILD_TK80) - add_definitions(-D_TK80) - set(EXEC_TARGET emutk80) - set(VM_NAME tk80) - set(VMFILES_LIB ${VMFILES_LIB} ) - #set(VMFILES_BASE ${VMFILES_BASE} noise.cpp datarec.cpp io.cpp) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/tk80.qrc) -elseif(BUILD_TK85) - add_definitions(-D_TK85) - set(EXEC_TARGET emutk85) - set(VM_NAME tk80bs) - set(VMFILES_LIB ${VMFILES_LIB} noise.cpp datarec.cpp ) - set(VMFILES_BASE ${VMFILES_BASE} io.cpp) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/tk85.qrc) -endif() - - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) - -include(config_commonsource) diff --git a/source/build-cmake/cmake/config_x1.cmake b/source/build-cmake/cmake/config_x1.cmake deleted file mode 100644 index a6e98a459..000000000 --- a/source/build-cmake/cmake/config_x1.cmake +++ /dev/null @@ -1,103 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -set(VM_NAME x1) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) -set(VMFILES - event.cpp - io.cpp - mz1p17.cpp - - scsi_host.cpp - scsi_dev.cpp - scsi_hdd.cpp -) -set(VMFILES_LIB - noise.cpp - ay_3_891x.cpp - beep.cpp - datarec.cpp - hd46505.cpp - i8255.cpp - mb8877.cpp - upd1990a.cpp - ym2151.cpp -# ym2203.cpp - z80ctc.cpp - z80sio.cpp - z80pio.cpp - - disk.cpp - prnfile.cpp - harddisk.cpp -) -set(FLAG_USE_MCS48 ON) -set(FLAG_USE_Z80 ON) - -set(BUILD_X1 OFF CACHE BOOL "Build for X1") -set(BUILD_X1TURBO OFF CACHE BOOL "Build for X1 Turbo") -set(BUILD_X1TURBOZ OFF CACHE BOOL "Build for X1 TurboZ") -set(BUILD_X1TWIN OFF CACHE BOOL "Build for X1 twin") - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(XM7_VERSION 3) -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -if(BUILD_X1) - set(EXEC_TARGET emux1) - add_definitions(-D_X1) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1.qrc) -elseif(BUILD_X1TURBO) - set(EXEC_TARGET emux1turbo) - add_definitions(-D_X1TURBO) - set(VMFILES_LIB ${VMFILES_LIB} z80dma.cpp) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1turbo.qrc) -elseif(BUILD_X1TURBOZ) - set(EXEC_TARGET emux1turboz) - add_definitions(-D_X1TURBOZ) - set(VMFILES_LIB ${VMFILES_LIB} z80dma.cpp) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1turboz.qrc) -elseif(BUILD_X1TWIN) - set(EXEC_TARGET emux1twin) - add_definitions(-D_X1TWIN) - set(LOCAL_LIBS ${LOCAL_LIBS} vm_pcengine) - set(VMFILES ${VMFILES} - huc6280.cpp -# scsi_cdrom.cpp -# scsi_host.cpp -# scsi_dev.cpp -# msm5205.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} - huc6280_base.cpp - ) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x1twin.qrc) -endif() - -if(BUILD_X1TWIN) - set(VM_APPEND_LIBS vm_pcengine) -endif() - -include(config_commonsource) -if(BUILD_X1TWIN) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/pcengine) - add_subdirectory(../../src/vm/pcengine vm/pcengine) -endif() - - diff --git a/source/build-cmake/cmake/config_z80tvgame.cmake b/source/build-cmake/cmake/config_z80tvgame.cmake deleted file mode 100644 index c2e35d655..000000000 --- a/source/build-cmake/cmake/config_z80tvgame.cmake +++ /dev/null @@ -1,40 +0,0 @@ - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(VM_NAME z80tvgame) -set(USE_FMGEN OFF) -set(WITH_MOUSE OFF) -set(WITH_JOYSTICK ON) - -set(VMFILES_BASE - event.cpp -) -set(FLAG_USE_Z80 ON) - -set(BUILD_I8255 OFF CACHE BOOL "Build I8255 version") -set(BUILD_Z80PIO OFF CACHE BOOL "Build Z80 PIO version") -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -add_definitions(-D_Z80TVGAME) -if(BUILD_I8255) - set(EXEC_TARGET emuz80tvgame_i8255) - set(VMFILES ${VMFILES_BASE}) - set(VMFILES_LIB pcm1bit.cpp i8255.cpp) - add_definitions(-D_USE_I8255) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/z80tvgame_i8255.qrc) -else() - set(EXEC_TARGET emuz80tvgame_z80pio) - set(VMFILES ${VMFILES_BASE}) - set(VMFILES_LIB pcm1bit.cpp z80pio.cpp) - add_definitions(-D_USE_Z80PIO) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/z80tvgame_z80pio.qrc) -endif() - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -include(config_commonsource) - diff --git a/source/build-cmake/cmake/cotire.cmake b/source/build-cmake/cmake/cotire.cmake deleted file mode 100644 index 97275d649..000000000 --- a/source/build-cmake/cmake/cotire.cmake +++ /dev/null @@ -1,4190 +0,0 @@ -# - cotire (compile time reducer) -# -# See the cotire manual for usage hints. -# -#============================================================================= -# Copyright 2012-2018 Sascha Kratky -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following -# conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -#============================================================================= - -if(__COTIRE_INCLUDED) - return() -endif() -set(__COTIRE_INCLUDED TRUE) - -# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode -# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid -if (NOT CMAKE_SCRIPT_MODE_FILE) - cmake_policy(PUSH) -endif() -cmake_minimum_required(VERSION 2.8.12) -if (NOT CMAKE_SCRIPT_MODE_FILE) - cmake_policy(POP) -endif() - -set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.8.0") - -# activate select policies -if (POLICY CMP0025) - # Compiler id for Apple Clang is now AppleClang - cmake_policy(SET CMP0025 NEW) -endif() - -if (POLICY CMP0026) - # disallow use of the LOCATION target property - cmake_policy(SET CMP0026 NEW) -endif() - -if (POLICY CMP0038) - # targets may not link directly to themselves - cmake_policy(SET CMP0038 NEW) -endif() - -if (POLICY CMP0039) - # utility targets may not have link dependencies - cmake_policy(SET CMP0039 NEW) -endif() - -if (POLICY CMP0040) - # target in the TARGET signature of add_custom_command() must exist - cmake_policy(SET CMP0040 NEW) -endif() - -if (POLICY CMP0045) - # error on non-existent target in get_target_property - cmake_policy(SET CMP0045 NEW) -endif() - -if (POLICY CMP0046) - # error on non-existent dependency in add_dependencies - cmake_policy(SET CMP0046 NEW) -endif() - -if (POLICY CMP0049) - # do not expand variables in target source entries - cmake_policy(SET CMP0049 NEW) -endif() - -if (POLICY CMP0050) - # disallow add_custom_command SOURCE signatures - cmake_policy(SET CMP0050 NEW) -endif() - -if (POLICY CMP0051) - # include TARGET_OBJECTS expressions in a target's SOURCES property - cmake_policy(SET CMP0051 NEW) -endif() - -if (POLICY CMP0053) - # simplify variable reference and escape sequence evaluation - cmake_policy(SET CMP0053 NEW) -endif() - -if (POLICY CMP0054) - # only interpret if() arguments as variables or keywords when unquoted - cmake_policy(SET CMP0054 NEW) -endif() - -if (POLICY CMP0055) - # strict checking for break() command - cmake_policy(SET CMP0055 NEW) -endif() - -include(CMakeParseArguments) -include(ProcessorCount) - -function (cotire_get_configuration_types _configsVar) - set (_configs "") - if (CMAKE_CONFIGURATION_TYPES) - list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES}) - endif() - if (CMAKE_BUILD_TYPE) - list (APPEND _configs "${CMAKE_BUILD_TYPE}") - endif() - if (_configs) - list (REMOVE_DUPLICATES _configs) - set (${_configsVar} ${_configs} PARENT_SCOPE) - else() - set (${_configsVar} "None" PARENT_SCOPE) - endif() -endfunction() - -function (cotire_get_source_file_extension _sourceFile _extVar) - # get_filename_component returns extension from first occurrence of . in file name - # this function computes the extension from last occurrence of . in file name - string (FIND "${_sourceFile}" "." _index REVERSE) - if (_index GREATER -1) - math (EXPR _index "${_index} + 1") - string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt) - else() - set (_sourceExt "") - endif() - set (${_extVar} "${_sourceExt}" PARENT_SCOPE) -endfunction() - -macro (cotire_check_is_path_relative_to _path _isRelativeVar) - set (${_isRelativeVar} FALSE) - if (IS_ABSOLUTE "${_path}") - foreach (_dir ${ARGN}) - file (RELATIVE_PATH _relPath "${_dir}" "${_path}") - if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")) - set (${_isRelativeVar} TRUE) - break() - endif() - endforeach() - endif() -endmacro() - -function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) - if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) - set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") - else() - set (_languageExtensions "") - endif() - if (CMAKE_${_language}_IGNORE_EXTENSIONS) - set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}") - else() - set (_ignoreExtensions "") - endif() - if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS) - set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}") - else() - set (_excludeExtensions "") - endif() - if (COTIRE_DEBUG AND _languageExtensions) - message (STATUS "${_language} source file extensions: ${_languageExtensions}") - endif() - if (COTIRE_DEBUG AND _ignoreExtensions) - message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") - endif() - if (COTIRE_DEBUG AND _excludeExtensions) - message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") - endif() - if (CMAKE_VERSION VERSION_LESS "3.1.0") - set (_allSourceFiles ${ARGN}) - else() - # as of CMake 3.1 target sources may contain generator expressions - # since we cannot obtain required property information about source files added - # through generator expressions at configure time, we filter them out - string (GENEX_STRIP "${ARGN}" _allSourceFiles) - endif() - set (_filteredSourceFiles "") - set (_excludedSourceFiles "") - foreach (_sourceFile ${_allSourceFiles}) - get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) - get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) - get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) - if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) - cotire_get_source_file_extension("${_sourceFile}" _sourceExt) - if (_sourceExt) - list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex) - if (_ignoreIndex LESS 0) - list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex) - if (_excludeIndex GREATER -1) - list (APPEND _excludedSourceFiles "${_sourceFile}") - else() - list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) - if (_sourceIndex GREATER -1) - # consider source file unless it is excluded explicitly - get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) - if (_sourceIsExcluded) - list (APPEND _excludedSourceFiles "${_sourceFile}") - else() - list (APPEND _filteredSourceFiles "${_sourceFile}") - endif() - else() - get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) - if ("${_sourceLanguage}" STREQUAL "${_language}") - # add to excluded sources, if file is not ignored and has correct language without having the correct extension - list (APPEND _excludedSourceFiles "${_sourceFile}") - endif() - endif() - endif() - endif() - endif() - endif() - endforeach() - # separate filtered source files from already cotired ones - # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire - set (_sourceFiles "") - set (_cotiredSourceFiles "") - foreach (_sourceFile ${_filteredSourceFiles}) - get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) - if (_sourceIsCotired) - list (APPEND _cotiredSourceFiles "${_sourceFile}") - else() - get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) - if (_sourceCompileFlags) - # add to excluded sources, if file has custom compile flags - list (APPEND _excludedSourceFiles "${_sourceFile}") - else() - get_source_file_property(_sourceCompileOptions "${_sourceFile}" COMPILE_OPTIONS) - if (_sourceCompileOptions) - # add to excluded sources, if file has list of custom compile options - list (APPEND _excludedSourceFiles "${_sourceFile}") - else() - list (APPEND _sourceFiles "${_sourceFile}") - endif() - endif() - endif() - endforeach() - if (COTIRE_DEBUG) - if (_sourceFiles) - message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}") - endif() - if (_excludedSourceFiles) - message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}") - endif() - if (_cotiredSourceFiles) - message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}") - endif() - endif() - set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) - set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) - set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE) -endfunction() - -function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type) - set (_filteredObjects "") - foreach (_object ${ARGN}) - get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) - if (_isSet) - get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) - if (_propertyValue) - list (APPEND _filteredObjects "${_object}") - endif() - endif() - endforeach() - set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) -endfunction() - -function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type) - set (_filteredObjects "") - foreach (_object ${ARGN}) - get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) - if (_isSet) - get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) - if (NOT _propertyValue) - list (APPEND _filteredObjects "${_object}") - endif() - endif() - endforeach() - set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_file_property_values _valuesVar _property) - set (_values "") - foreach (_sourceFile ${ARGN}) - get_source_file_property(_propertyValue "${_sourceFile}" ${_property}) - if (_propertyValue) - list (APPEND _values "${_propertyValue}") - endif() - endforeach() - set (${_valuesVar} ${_values} PARENT_SCOPE) -endfunction() - -function (cotire_resolve_config_properties _configurations _propertiesVar) - set (_properties "") - foreach (_property ${ARGN}) - if ("${_property}" MATCHES "") - foreach (_config ${_configurations}) - string (TOUPPER "${_config}" _upperConfig) - string (REPLACE "" "${_upperConfig}" _configProperty "${_property}") - list (APPEND _properties ${_configProperty}) - endforeach() - else() - list (APPEND _properties ${_property}) - endif() - endforeach() - set (${_propertiesVar} ${_properties} PARENT_SCOPE) -endfunction() - -function (cotire_copy_set_properties _configurations _type _source _target) - cotire_resolve_config_properties("${_configurations}" _properties ${ARGN}) - foreach (_property ${_properties}) - get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) - if (_isSet) - get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property}) - set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}") - endif() - endforeach() -endfunction() - -function (cotire_get_target_usage_requirements _target _config _targetRequirementsVar) - set (_targetRequirements "") - get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) - while (_librariesToProcess) - # remove from head - list (GET _librariesToProcess 0 _library) - list (REMOVE_AT _librariesToProcess 0) - if (_library MATCHES "^\\$<\\$:([A-Za-z0-9_:-]+)>$") - set (_library "${CMAKE_MATCH_1}") - elseif (_config STREQUAL "None" AND _library MATCHES "^\\$<\\$:([A-Za-z0-9_:-]+)>$") - set (_library "${CMAKE_MATCH_1}") - endif() - if (TARGET ${_library}) - list (FIND _targetRequirements ${_library} _index) - if (_index LESS 0) - list (APPEND _targetRequirements ${_library}) - # BFS traversal of transitive libraries - get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) - if (_libraries) - list (APPEND _librariesToProcess ${_libraries}) - list (REMOVE_DUPLICATES _librariesToProcess) - endif() - endif() - endif() - endwhile() - set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE) -endfunction() - -function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - set (_flagPrefix "[/-]") - else() - set (_flagPrefix "--?") - endif() - set (_optionFlag "") - set (_matchedOptions "") - set (_unmatchedOptions "") - foreach (_compileFlag ${ARGN}) - if (_compileFlag) - if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}") - # option with separate argument - list (APPEND _matchedOptions "${_compileFlag}") - set (_optionFlag "") - elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$") - # remember option - set (_optionFlag "${CMAKE_MATCH_2}") - elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$") - # option with joined argument - list (APPEND _matchedOptions "${CMAKE_MATCH_3}") - set (_optionFlag "") - else() - # flush remembered option - if (_optionFlag) - list (APPEND _matchedOptions "${_optionFlag}") - set (_optionFlag "") - endif() - # add to unfiltered options - list (APPEND _unmatchedOptions "${_compileFlag}") - endif() - endif() - endforeach() - if (_optionFlag) - list (APPEND _matchedOptions "${_optionFlag}") - endif() - if (COTIRE_DEBUG AND _matchedOptions) - message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}") - endif() - if (COTIRE_DEBUG AND _unmatchedOptions) - message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}") - endif() - set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) - set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) -endfunction() - -function (cotire_is_target_supported _target _isSupportedVar) - if (NOT TARGET "${_target}") - set (${_isSupportedVar} FALSE PARENT_SCOPE) - return() - endif() - get_target_property(_imported ${_target} IMPORTED) - if (_imported) - set (${_isSupportedVar} FALSE PARENT_SCOPE) - return() - endif() - get_target_property(_targetType ${_target} TYPE) - if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") - set (${_isSupportedVar} FALSE PARENT_SCOPE) - return() - endif() - set (${_isSupportedVar} TRUE PARENT_SCOPE) -endfunction() - -function (cotire_get_target_compile_flags _config _language _target _flagsVar) - string (TOUPPER "${_config}" _upperConfig) - # collect options from CMake language variables - set (_compileFlags "") - if (CMAKE_${_language}_FLAGS) - set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}") - endif() - if (CMAKE_${_language}_FLAGS_${_upperConfig}) - set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") - endif() - if (_target) - # add target compile flags - get_target_property(_targetflags ${_target} COMPILE_FLAGS) - if (_targetflags) - set (_compileFlags "${_compileFlags} ${_targetflags}") - endif() - endif() - if (UNIX) - separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") - elseif(WIN32) - separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}") - else() - separate_arguments(_compileFlags) - endif() - # target compile options - if (_target) - get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) - if (_targetOptions) - list (APPEND _compileFlags ${_targetOptions}) - endif() - endif() - # interface compile options from linked library targets - if (_target) - set (_linkedTargets "") - cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) - foreach (_linkedTarget ${_linkedTargets}) - get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS) - if (_targetOptions) - list (APPEND _compileFlags ${_targetOptions}) - endif() - endforeach() - endif() - # handle language standard properties - if (CMAKE_${_language}_STANDARD_DEFAULT) - # used compiler supports language standard levels - if (_target) - get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD) - if (_targetLanguageStandard) - set (_type "EXTENSION") - get_property(_isSet TARGET ${_target} PROPERTY ${_language}_EXTENSIONS SET) - if (_isSet) - get_target_property(_targetUseLanguageExtensions ${_target} ${_language}_EXTENSIONS) - if (NOT _targetUseLanguageExtensions) - set (_type "STANDARD") - endif() - endif() - if (CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION) - list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION}") - endif() - endif() - endif() - endif() - # handle the POSITION_INDEPENDENT_CODE target property - if (_target) - get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) - if (_targetPIC) - get_target_property(_targetType ${_target} TYPE) - if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") - elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") - endif() - endif() - endif() - # handle visibility target properties - if (_target) - get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET) - if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}") - endif() - get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN) - if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}") - endif() - endif() - # platform specific flags - if (APPLE) - get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) - if (NOT _architectures) - get_target_property(_architectures ${_target} OSX_ARCHITECTURES) - endif() - if (_architectures) - foreach (_arch ${_architectures}) - list (APPEND _compileFlags "-arch" "${_arch}") - endforeach() - endif() - if (CMAKE_OSX_SYSROOT) - if (CMAKE_${_language}_SYSROOT_FLAG) - list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") - else() - list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}") - endif() - endif() - if (CMAKE_OSX_DEPLOYMENT_TARGET) - if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG) - list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") - else() - list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") - endif() - endif() - endif() - if (COTIRE_DEBUG AND _compileFlags) - message (STATUS "Target ${_target} compile flags: ${_compileFlags}") - endif() - set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar) - set (_includeDirs "") - set (_systemIncludeDirs "") - # default include dirs - if (CMAKE_INCLUDE_CURRENT_DIR) - list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}") - list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}") - endif() - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - # parse additional include directories from target compile flags - if (CMAKE_INCLUDE_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_dirs "") - cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) - if (_dirs) - list (APPEND _includeDirs ${_dirs}) - endif() - endif() - endif() - # parse additional system include directories from target compile flags - if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_dirs "") - cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) - if (_dirs) - list (APPEND _systemIncludeDirs ${_dirs}) - endif() - endif() - endif() - # target include directories - get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES) - if (_target) - get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _systemIncludeDirs ${_targetDirs}) - endif() - endif() - # interface include directories from linked library targets - if (_target) - set (_linkedTargets "") - cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) - foreach (_linkedTarget ${_linkedTargets}) - get_target_property(_linkedTargetType ${_linkedTarget} TYPE) - if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND - _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") - # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR - # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR - # which are only available with CMake 3.4 or later. - get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - endif() - get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _systemIncludeDirs ${_targetDirs}) - endif() - endforeach() - endif() - if (dirs) - list (REMOVE_DUPLICATES _dirs) - endif() - list (LENGTH _includeDirs _projectInsertIndex) - foreach (_dir ${_dirs}) - if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE) - cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") - if (_isRelative) - list (LENGTH _includeDirs _len) - if (_len EQUAL _projectInsertIndex) - list (APPEND _includeDirs "${_dir}") - else() - list (INSERT _includeDirs _projectInsertIndex "${_dir}") - endif() - math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1") - else() - list (APPEND _includeDirs "${_dir}") - endif() - else() - list (APPEND _includeDirs "${_dir}") - endif() - endforeach() - list (REMOVE_DUPLICATES _includeDirs) - list (REMOVE_DUPLICATES _systemIncludeDirs) - if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) - list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) - endif() - if (WIN32 AND NOT MINGW) - # convert Windows paths in include directories to CMake paths - if (_includeDirs) - set (_paths "") - foreach (_dir ${_includeDirs}) - file (TO_CMAKE_PATH "${_dir}" _path) - list (APPEND _paths "${_path}") - endforeach() - set (_includeDirs ${_paths}) - endif() - if (_systemIncludeDirs) - set (_paths "") - foreach (_dir ${_systemIncludeDirs}) - file (TO_CMAKE_PATH "${_dir}" _path) - list (APPEND _paths "${_path}") - endforeach() - set (_systemIncludeDirs ${_paths}) - endif() - endif() - if (COTIRE_DEBUG AND _includeDirs) - message (STATUS "Target ${_target} include dirs: ${_includeDirs}") - endif() - set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) - if (COTIRE_DEBUG AND _systemIncludeDirs) - message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}") - endif() - set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_export_symbol _target _exportSymbolVar) - set (_exportSymbol "") - get_target_property(_targetType ${_target} TYPE) - get_target_property(_enableExports ${_target} ENABLE_EXPORTS) - if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR - (_targetType STREQUAL "EXECUTABLE" AND _enableExports)) - get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL) - if (NOT _exportSymbol) - set (_exportSymbol "${_target}_EXPORTS") - endif() - string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol) - endif() - set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_compile_definitions _config _language _target _definitionsVar) - string (TOUPPER "${_config}" _upperConfig) - set (_configDefinitions "") - # CMAKE_INTDIR for multi-configuration build systems - if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") - list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"") - endif() - # target export define symbol - cotire_get_target_export_symbol("${_target}" _defineSymbol) - if (_defineSymbol) - list (APPEND _configDefinitions "${_defineSymbol}") - endif() - # directory compile definitions - get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig}) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - # target compile definitions - get_target_property(_definitions ${_target} COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig}) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - # interface compile definitions from linked library targets - set (_linkedTargets "") - cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) - foreach (_linkedTarget ${_linkedTargets}) - get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - endforeach() - # parse additional compile definitions from target compile flags - # and do not look at directory compile definitions, which we already handled - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - list (REMOVE_DUPLICATES _configDefinitions) - if (COTIRE_DEBUG AND _configDefinitions) - message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}") - endif() - set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar) - # parse target compile flags omitting compile definitions and include directives - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - set (_flagFilter "D") - if (CMAKE_INCLUDE_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_flagFilter "${_flagFilter}|${_includeFlag}") - endif() - endif() - if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_flagFilter "${_flagFilter}|${_includeFlag}") - endif() - endif() - set (_compilerFlags "") - cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags}) - if (COTIRE_DEBUG AND _compilerFlags) - message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}") - endif() - set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) -endfunction() - -function (cotire_add_sys_root_paths _pathsVar) - if (APPLE) - if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT) - foreach (_path IN LISTS ${_pathsVar}) - if (IS_ABSOLUTE "${_path}") - get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE) - if (EXISTS "${_path}") - list (APPEND ${_pathsVar} "${_path}") - endif() - endif() - endforeach() - endif() - endif() - set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) - set (_extraProperties ${ARGN}) - set (_result "") - if (_extraProperties) - list (FIND _extraProperties "${_sourceFile}" _index) - if (_index GREATER -1) - math (EXPR _index "${_index} + 1") - list (LENGTH _extraProperties _len) - math (EXPR _len "${_len} - 1") - foreach (_index RANGE ${_index} ${_len}) - list (GET _extraProperties ${_index} _value) - if (_value MATCHES "${_pattern}") - list (APPEND _result "${_value}") - else() - break() - endif() - endforeach() - endif() - endif() - set (${_resultVar} ${_result} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar) - set (_compileDefinitions "") - if (NOT CMAKE_SCRIPT_MODE_FILE) - string (TOUPPER "${_config}" _upperConfig) - get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _compileDefinitions ${_definitions}) - endif() - get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig}) - if (_definitions) - list (APPEND _compileDefinitions ${_definitions}) - endif() - endif() - cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN}) - if (_definitions) - list (APPEND _compileDefinitions ${_definitions}) - endif() - if (COTIRE_DEBUG AND _compileDefinitions) - message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}") - endif() - set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_files_compile_definitions _config _language _definitionsVar) - set (_configDefinitions "") - foreach (_sourceFile ${ARGN}) - cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions) - if (_sourceDefinitions) - list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-") - endif() - endforeach() - set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) - set (_sourceUndefs "") - if (NOT CMAKE_SCRIPT_MODE_FILE) - get_source_file_property(_undefs "${_sourceFile}" ${_property}) - if (_undefs) - list (APPEND _sourceUndefs ${_undefs}) - endif() - endif() - cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN}) - if (_undefs) - list (APPEND _sourceUndefs ${_undefs}) - endif() - if (COTIRE_DEBUG AND _sourceUndefs) - message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}") - endif() - set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_files_undefs _property _sourceUndefsVar) - set (_sourceUndefs "") - foreach (_sourceFile ${ARGN}) - cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs) - if (_undefs) - list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-") - endif() - endforeach() - set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) -endfunction() - -macro (cotire_set_cmd_to_prologue _cmdVar) - set (${_cmdVar} "${CMAKE_COMMAND}") - if (COTIRE_DEBUG) - list (APPEND ${_cmdVar} "--warn-uninitialized") - endif() - list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$") - if (XCODE) - list (APPEND ${_cmdVar} "-DXCODE:BOOL=TRUE") - endif() - if (COTIRE_VERBOSE) - list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") - elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") - list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)") - endif() -endmacro() - -function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1) - if (NOT _compilerLauncher) - set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER}) - endif() - if (NOT _compilerExe) - set (_compilerExe "${CMAKE_${_language}_COMPILER}") - endif() - if (NOT _compilerArg1) - set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) - endif() - if (WIN32) - file (TO_NATIVE_PATH "${_compilerExe}" _compilerExe) - endif() - string (STRIP "${_compilerArg1}" _compilerArg1) - if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # compiler launcher is only supported for Makefile and Ninja - set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) - else() - set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) - endif() -endfunction() - -macro (cotire_add_definitions_to_cmd _cmdVar _language) - foreach (_definition ${ARGN}) - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - list (APPEND ${_cmdVar} "/D${_definition}") - else() - list (APPEND ${_cmdVar} "-D${_definition}") - endif() - endforeach() -endmacro() - -function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar) - set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}}) - if (_includeDirs) - list (REMOVE_DUPLICATES _includeDirs) - foreach (_include ${_includeDirs}) - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - file (TO_NATIVE_PATH "${_include}" _include) - list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") - else() - set (_index -1) - if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+") - list (FIND ${_systemIncludesVar} "${_include}" _index) - endif() - if (_index GREATER -1) - list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") - else() - list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") - endif() - endif() - endforeach() - endif() - set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) -endfunction() - -function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar) - if (APPLE) - set (_frameworkDirs "") - foreach (_include ${${_includesVar}}) - if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") - get_filename_component(_frameworkDir "${_include}" DIRECTORY) - list (APPEND _frameworkDirs "${_frameworkDir}") - endif() - endforeach() - set (_systemFrameworkDirs "") - foreach (_include ${${_systemIncludesVar}}) - if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") - get_filename_component(_frameworkDir "${_include}" DIRECTORY) - list (APPEND _systemFrameworkDirs "${_frameworkDir}") - endif() - endforeach() - if (_systemFrameworkDirs) - list (APPEND _frameworkDirs ${_systemFrameworkDirs}) - endif() - if (_frameworkDirs) - list (REMOVE_DUPLICATES _frameworkDirs) - foreach (_frameworkDir ${_frameworkDirs}) - set (_index -1) - if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+") - list (FIND _systemFrameworkDirs "${_frameworkDir}" _index) - endif() - if (_index GREATER -1) - list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") - else() - list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") - endif() - endforeach() - endif() - endif() - set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) -endfunction() - -macro (cotire_add_compile_flags_to_cmd _cmdVar) - foreach (_flag ${ARGN}) - list (APPEND ${_cmdVar} "${_flag}") - endforeach() -endmacro() - -function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) - if (EXISTS "${_file}") - set (_triggerFile "") - foreach (_dependencyFile ${ARGN}) - if (EXISTS "${_dependencyFile}") - # IS_NEWER_THAN returns TRUE if both files have the same timestamp - # thus we do the comparison in both directions to exclude ties - if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND - NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}") - set (_triggerFile "${_dependencyFile}") - break() - endif() - endif() - endforeach() - if (_triggerFile) - if (COTIRE_VERBOSE) - get_filename_component(_fileName "${_file}" NAME) - message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") - endif() - set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) - else() - if (COTIRE_VERBOSE) - get_filename_component(_fileName "${_file}" NAME) - message (STATUS "${_fileName} is up-to-date.") - endif() - set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) - endif() - else() - if (COTIRE_VERBOSE) - get_filename_component(_fileName "${_file}" NAME) - message (STATUS "${_fileName} does not exist yet.") - endif() - set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) - endif() -endfunction() - -macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) - set (${_relPathVar} "") - foreach (_includeDir ${_includeDirs}) - if (IS_DIRECTORY "${_includeDir}") - file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}") - if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.") - string (LENGTH "${${_relPathVar}}" _closestLen) - string (LENGTH "${_relPath}" _relLen) - if (_closestLen EQUAL 0 OR _relLen LESS _closestLen) - set (${_relPathVar} "${_relPath}") - endif() - endif() - elseif ("${_includeDir}" STREQUAL "${_headerFile}") - # if path matches exactly, return short non-empty string - set (${_relPathVar} "1") - break() - endif() - endforeach() -endmacro() - -macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside) - # check header path against ignored and honored include directories - cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath) - if (_insideRelPath) - # header is inside, but could be become outside if there is a shorter outside match - cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath) - if (_outsideRelPath) - string (LENGTH "${_insideRelPath}" _insideRelPathLen) - string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) - if (_outsideRelPathLen LESS _insideRelPathLen) - set (${_headerIsInside} FALSE) - else() - set (${_headerIsInside} TRUE) - endif() - else() - set (${_headerIsInside} TRUE) - endif() - else() - # header is outside - set (${_headerIsInside} FALSE) - endif() -endmacro() - -macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) - if (NOT EXISTS "${_headerFile}") - set (${_headerIsIgnoredVar} TRUE) - elseif (IS_DIRECTORY "${_headerFile}") - set (${_headerIsIgnoredVar} TRUE) - elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$") - # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path - # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation - # with the error message "error: no include path in which to search for header.h" - set (${_headerIsIgnoredVar} TRUE) - else() - set (${_headerIsIgnoredVar} FALSE) - endif() -endmacro() - -macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar) - # check header file extension - cotire_get_source_file_extension("${_headerFile}" _headerFileExt) - set (${_headerIsIgnoredVar} FALSE) - if (_headerFileExt) - list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index) - if (_index GREATER -1) - set (${_headerIsIgnoredVar} TRUE) - endif() - endif() -endmacro() - -macro (cotire_parse_line _line _headerFileVar _headerDepthVar) - if (MSVC) - # cl.exe /showIncludes produces different output, depending on the language pack used, e.g.: - # English: "Note: including file: C:\directory\file" - # German: "Hinweis: Einlesen der Datei: C:\directory\file" - # We use a very general regular expression, relying on the presence of the : characters - if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$") - string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) - get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) - else() - set (${_headerFileVar} "") - set (${_headerDepthVar} 0) - endif() - else() - if (_line MATCHES "^(\\.+) (.*)$") - # GCC like output - string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) - if (IS_ABSOLUTE "${CMAKE_MATCH_2}") - set (${_headerFileVar} "${CMAKE_MATCH_2}") - else() - get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH) - endif() - else() - set (${_headerFileVar} "") - set (${_headerDepthVar} 0) - endif() - endif() -endmacro() - -function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) - if (WIN32) - # prevent CMake macro invocation errors due to backslash characters in Windows paths - string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") - endif() - # canonize slashes - string (REPLACE "//" "/" _scanOutput "${_scanOutput}") - # prevent semicolon from being interpreted as a line separator - string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}") - # then separate lines - string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}") - list (LENGTH _scanOutput _len) - # remove duplicate lines to speed up parsing - list (REMOVE_DUPLICATES _scanOutput) - list (LENGTH _scanOutput _uniqueLen) - if (COTIRE_VERBOSE OR COTIRE_DEBUG) - message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") - if (_ignoredExtensions) - message (STATUS "Ignored extensions: ${_ignoredExtensions}") - endif() - if (_ignoredIncludeDirs) - message (STATUS "Ignored paths: ${_ignoredIncludeDirs}") - endif() - if (_honoredIncludeDirs) - message (STATUS "Included paths: ${_honoredIncludeDirs}") - endif() - endif() - set (_sourceFiles ${ARGN}) - set (_selectedIncludes "") - set (_unparsedLines "") - # stack keeps track of inside/outside project status of processed header files - set (_headerIsInsideStack "") - foreach (_line IN LISTS _scanOutput) - if (_line) - cotire_parse_line("${_line}" _headerFile _headerDepth) - if (_headerFile) - cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside) - if (COTIRE_DEBUG) - message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") - endif() - # update stack - list (LENGTH _headerIsInsideStack _stackLen) - if (_headerDepth GREATER _stackLen) - math (EXPR _stackLen "${_stackLen} + 1") - foreach (_index RANGE ${_stackLen} ${_headerDepth}) - list (APPEND _headerIsInsideStack ${_headerIsInside}) - endforeach() - else() - foreach (_index RANGE ${_headerDepth} ${_stackLen}) - list (REMOVE_AT _headerIsInsideStack -1) - endforeach() - list (APPEND _headerIsInsideStack ${_headerIsInside}) - endif() - if (COTIRE_DEBUG) - message (STATUS "${_headerIsInsideStack}") - endif() - # header is a candidate if it is outside project - if (NOT _headerIsInside) - # get parent header file's inside/outside status - if (_headerDepth GREATER 1) - math (EXPR _index "${_headerDepth} - 2") - list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside) - else() - set (_parentHeaderIsInside TRUE) - endif() - # select header file if parent header file is inside project - # (e.g., a project header file that includes a standard header file) - if (_parentHeaderIsInside) - cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored) - if (NOT _headerIsIgnored) - cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored) - if (NOT _headerIsIgnored) - list (APPEND _selectedIncludes "${_headerFile}") - else() - # fix header's inside status on stack, it is ignored by extension now - list (REMOVE_AT _headerIsInsideStack -1) - list (APPEND _headerIsInsideStack TRUE) - endif() - endif() - if (COTIRE_DEBUG) - message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}") - endif() - endif() - endif() - else() - if (MSVC) - # for cl.exe do not keep unparsed lines which solely consist of a source file name - string (FIND "${_sourceFiles}" "${_line}" _index) - if (_index LESS 0) - list (APPEND _unparsedLines "${_line}") - endif() - else() - list (APPEND _unparsedLines "${_line}") - endif() - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _selectedIncludes) - set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE) - set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE) -endfunction() - -function (cotire_scan_includes _includesVar) - set(_options "") - set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES SCAN_RESULT) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES - IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) - if (NOT _option_LANGUAGE) - set (_option_LANGUAGE "CXX") - endif() - if (NOT _option_COMPILER_ID) - set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") - endif() - if (NOT _option_COMPILER_VERSION) - set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") - endif() - cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") - cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) - cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) - # only consider existing source files for scanning - set (_existingSourceFiles "") - foreach (_sourceFile ${_sourceFiles}) - if (EXISTS "${_sourceFile}") - list (APPEND _existingSourceFiles "${_sourceFile}") - endif() - endforeach() - if (NOT _existingSourceFiles) - set (${_includesVar} "" PARENT_SCOPE) - return() - endif() - # add source files to be scanned - if (WIN32) - foreach (_sourceFile ${_existingSourceFiles}) - file (TO_NATIVE_PATH "${_sourceFile}" _sourceFileNative) - list (APPEND _cmd "${_sourceFileNative}") - endforeach() - else() - list (APPEND _cmd ${_existingSourceFiles}) - endif() - if (COTIRE_VERBOSE) - message (STATUS "execute_process: ${_cmd}") - endif() - if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC") - # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared - unset (ENV{VS_UNICODE_OUTPUT}) - endif() - execute_process( - COMMAND ${_cmd} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE _result - OUTPUT_QUIET - ERROR_VARIABLE _output) - if (_result) - message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") - endif() - cotire_parse_includes( - "${_option_LANGUAGE}" "${_output}" - "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}" - "${_option_IGNORE_EXTENSIONS}" - _includes _unparsedLines - ${_sourceFiles}) - if (_option_INCLUDE_PRIORITY_PATH) - set (_sortedIncludes "") - foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH}) - foreach (_include ${_includes}) - string (FIND ${_include} ${_priorityPath} _position) - if (_position GREATER -1) - list (APPEND _sortedIncludes ${_include}) - endif() - endforeach() - endforeach() - if (_sortedIncludes) - list (INSERT _includes 0 ${_sortedIncludes}) - list (REMOVE_DUPLICATES _includes) - endif() - endif() - set (${_includesVar} ${_includes} PARENT_SCOPE) - if (_option_UNPARSED_LINES) - set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) - endif() - if (_option_SCAN_RESULT) - set (${_option_SCAN_RESULT} ${_result} PARENT_SCOPE) - endif() -endfunction() - -macro (cotire_append_undefs _contentsVar) - set (_undefs ${ARGN}) - if (_undefs) - list (REMOVE_DUPLICATES _undefs) - foreach (_definition ${_undefs}) - list (APPEND ${_contentsVar} "#undef ${_definition}") - endforeach() - endif() -endmacro() - -macro (cotire_comment_str _language _commentText _commentVar) - if ("${_language}" STREQUAL "CMAKE") - set (${_commentVar} "# ${_commentText}") - else() - set (${_commentVar} "/* ${_commentText} */") - endif() -endmacro() - -function (cotire_write_file _language _file _contents _force) - get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) - cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1) - cotire_comment_str("${_language}" "${_file}" _header2) - set (_contents "${_header1}\n${_header2}\n${_contents}") - if (COTIRE_DEBUG) - message (STATUS "${_contents}") - endif() - if (_force OR NOT EXISTS "${_file}") - file (WRITE "${_file}" "${_contents}") - else() - file (READ "${_file}" _oldContents) - if (NOT "${_oldContents}" STREQUAL "${_contents}") - file (WRITE "${_file}" "${_contents}") - else() - if (COTIRE_DEBUG) - message (STATUS "${_file} unchanged") - endif() - endif() - endif() -endfunction() - -function (cotire_generate_unity_source _unityFile) - set(_options "") - set(_oneValueArgs LANGUAGE) - set(_multiValueArgs - DEPENDS SOURCES_COMPILE_DEFINITIONS - PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (_option_DEPENDS) - cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS}) - if (_unityFileIsUpToDate) - return() - endif() - endif() - set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) - if (NOT _option_PRE_UNDEFS) - set (_option_PRE_UNDEFS "") - endif() - if (NOT _option_SOURCES_PRE_UNDEFS) - set (_option_SOURCES_PRE_UNDEFS "") - endif() - if (NOT _option_POST_UNDEFS) - set (_option_POST_UNDEFS "") - endif() - if (NOT _option_SOURCES_POST_UNDEFS) - set (_option_SOURCES_POST_UNDEFS "") - endif() - set (_contents "") - if (_option_PROLOGUE) - list (APPEND _contents ${_option_PROLOGUE}) - endif() - if (_option_LANGUAGE AND _sourceFiles) - if ("${_option_LANGUAGE}" STREQUAL "CXX") - list (APPEND _contents "#ifdef __cplusplus") - elseif ("${_option_LANGUAGE}" STREQUAL "C") - list (APPEND _contents "#ifndef __cplusplus") - endif() - endif() - set (_compileUndefinitions "") - foreach (_sourceFile ${_sourceFiles}) - cotire_get_source_compile_definitions( - "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions - ${_option_SOURCES_COMPILE_DEFINITIONS}) - cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS}) - cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS}) - if (_option_PRE_UNDEFS) - list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS}) - endif() - if (_sourcePreUndefs) - list (APPEND _compileUndefinitions ${_sourcePreUndefs}) - endif() - if (_compileUndefinitions) - cotire_append_undefs(_contents ${_compileUndefinitions}) - set (_compileUndefinitions "") - endif() - if (_sourcePostUndefs) - list (APPEND _compileUndefinitions ${_sourcePostUndefs}) - endif() - if (_option_POST_UNDEFS) - list (APPEND _compileUndefinitions ${_option_POST_UNDEFS}) - endif() - foreach (_definition ${_compileDefinitions}) - if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$") - list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}") - list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}") - else() - list (APPEND _contents "#define ${_definition}") - list (INSERT _compileUndefinitions 0 "${_definition}") - endif() - endforeach() - # use absolute path as source file location - get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE) - if (WIN32) - file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation) - endif() - list (APPEND _contents "#include \"${_sourceFileLocation}\"") - endforeach() - if (_compileUndefinitions) - cotire_append_undefs(_contents ${_compileUndefinitions}) - set (_compileUndefinitions "") - endif() - if (_option_LANGUAGE AND _sourceFiles) - list (APPEND _contents "#endif") - endif() - if (_option_EPILOGUE) - list (APPEND _contents ${_option_EPILOGUE}) - endif() - list (APPEND _contents "") - string (REPLACE ";" "\n" _contents "${_contents}") - if (COTIRE_VERBOSE) - message ("${_contents}") - endif() - cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE) -endfunction() - -function (cotire_generate_prefix_header _prefixFile) - set(_options "") - set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION) - set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS - INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH - IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (NOT _option_COMPILER_ID) - set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") - endif() - if (NOT _option_COMPILER_VERSION) - set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") - endif() - if (_option_DEPENDS) - cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) - if (_prefixFileIsUpToDate) - # create empty log file - set (_unparsedLinesFile "${_prefixFile}.log") - file (WRITE "${_unparsedLinesFile}" "") - return() - endif() - endif() - set (_prologue "") - set (_epilogue "") - if (_option_COMPILER_ID MATCHES "Clang") - set (_prologue "#pragma clang system_header") - elseif (_option_COMPILER_ID MATCHES "GNU") - set (_prologue "#pragma GCC system_header") - elseif (_option_COMPILER_ID MATCHES "MSVC") - set (_prologue "#pragma warning(push, 0)") - set (_epilogue "#pragma warning(pop)") - elseif (_option_COMPILER_ID MATCHES "Intel") - # Intel compiler requires hdrstop pragma to stop generating PCH file - set (_epilogue "#pragma hdrstop") - endif() - set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) - cotire_scan_includes(_selectedHeaders ${_sourceFiles} - LANGUAGE "${_option_LANGUAGE}" - COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}" - COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" - COMPILER_ARG1 "${_option_COMPILER_ARG1}" - COMPILER_ID "${_option_COMPILER_ID}" - COMPILER_VERSION "${_option_COMPILER_VERSION}" - COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} - COMPILE_FLAGS ${_option_COMPILE_FLAGS} - INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} - SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} - IGNORE_PATH ${_option_IGNORE_PATH} - INCLUDE_PATH ${_option_INCLUDE_PATH} - IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} - INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH} - UNPARSED_LINES _unparsedLines - SCAN_RESULT _scanResult) - cotire_generate_unity_source("${_prefixFile}" - PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) - set (_unparsedLinesFile "${_prefixFile}.log") - if (_unparsedLines) - if (COTIRE_VERBOSE OR _scanResult OR NOT _selectedHeaders) - list (LENGTH _unparsedLines _skippedLineCount) - if (WIN32) - file (TO_NATIVE_PATH "${_unparsedLinesFile}" _unparsedLinesLogPath) - else() - set (_unparsedLinesLogPath "${_unparsedLinesFile}") - endif() - message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesLogPath}") - endif() - string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") - endif() - file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}\n") -endfunction() - -function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) - set (_flags ${${_flagsVar}}) - if (_compilerID MATCHES "MSVC") - # cl.exe options used - # /nologo suppresses display of sign-on banner - # /TC treat all files named on the command line as C source files - # /TP treat all files named on the command line as C++ source files - # /EP preprocess to stdout without #line directives - # /showIncludes list include files - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes) - else() - # return as a flag string - set (_flags "${_sourceFileType${_language}} /EP /showIncludes") - endif() - elseif (_compilerID MATCHES "GNU") - # GCC options used - # -H print the name of each header file used - # -E invoke preprocessor - # -fdirectives-only do not expand macros, requires GCC >= 4.3 - if (_flags) - # append to list - list (APPEND _flags -H -E) - if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") - list (APPEND _flags -fdirectives-only) - endif() - else() - # return as a flag string - set (_flags "-H -E") - if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") - set (_flags "${_flags} -fdirectives-only") - endif() - endif() - elseif (_compilerID MATCHES "Clang") - if (UNIX) - # Clang options used - # -H print the name of each header file used - # -E invoke preprocessor - # -fno-color-diagnostics do not print diagnostics in color - # -Eonly just run preprocessor, no output - if (_flags) - # append to list - list (APPEND _flags -H -E -fno-color-diagnostics -Xclang -Eonly) - else() - # return as a flag string - set (_flags "-H -E -fno-color-diagnostics -Xclang -Eonly") - endif() - elseif (WIN32) - # Clang-cl.exe options used - # /TC treat all files named on the command line as C source files - # /TP treat all files named on the command line as C++ source files - # /EP preprocess to stdout without #line directives - # -H print the name of each header file used - # -fno-color-diagnostics do not print diagnostics in color - # -Eonly just run preprocessor, no output - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags "${_sourceFileType${_language}}" /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly) - else() - # return as a flag string - set (_flags "${_sourceFileType${_language}} /EP -fno-color-diagnostics -Xclang -H -Xclang -Eonly") - endif() - endif() - elseif (_compilerID MATCHES "Intel") - if (WIN32) - # Windows Intel options used - # /nologo do not display compiler version information - # /QH display the include file order - # /EP preprocess to stdout, omitting #line directives - # /TC process all source or unrecognized file types as C source files - # /TP process all source or unrecognized file types as C++ source files - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH) - else() - # return as a flag string - set (_flags "${_sourceFileType${_language}} /EP /QH") - endif() - else() - # Linux / Mac OS X Intel options used - # -H print the name of each header file used - # -EP preprocess to stdout, omitting #line directives - # -Kc++ process all source or unrecognized file types as C++ source files - if (_flags) - # append to list - if ("${_language}" STREQUAL "CXX") - list (APPEND _flags -Kc++) - endif() - list (APPEND _flags -H -EP) - else() - # return as a flag string - if ("${_language}" STREQUAL "CXX") - set (_flags "-Kc++ ") - endif() - set (_flags "${_flags}-H -EP") - endif() - endif() - else() - message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") - endif() - set (${_flagsVar} ${_flags} PARENT_SCOPE) -endfunction() - -function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar) - set (_flags ${${_flagsVar}}) - if (_compilerID MATCHES "MSVC") - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) - # cl.exe options used - # /Yc creates a precompiled header file - # /Fp specifies precompiled header binary file name - # /FI forces inclusion of file - # /TC treat all files named on the command line as C source files - # /TP treat all files named on the command line as C++ source files - # /Zs syntax check only - # /Zm precompiled header memory allocation scaling factor - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" - "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - else() - # return as a flag string - set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - endif() - elseif (_compilerID MATCHES "GNU") - # GCC options used - # -x specify the source language - # -c compile but do not link - # -o place output in file - # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may - # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) - set (_xLanguage_C "c-header") - set (_xLanguage_CXX "c++-header") - if (_flags) - # append to list - list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}") - else() - # return as a flag string - set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") - endif() - elseif (_compilerID MATCHES "Clang") - if (UNIX) - # Clang options used - # -x specify the source language - # -c compile but do not link - # -o place output in file - # -fno-pch-timestamp disable inclusion of timestamp in precompiled headers (clang 4.0.0+) - set (_xLanguage_C "c-header") - set (_xLanguage_CXX "c++-header") - if (_flags) - # append to list - list (APPEND _flags -x "${_xLanguage_${_language}}" -c "${_prefixFile}" -o "${_pchFile}") - if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0") - list (APPEND _flags -Xclang -fno-pch-timestamp) - endif() - else() - # return as a flag string - set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "4.0.0") - set (_flags "${_flags} -Xclang -fno-pch-timestamp") - endif() - endif() - elseif (WIN32) - # Clang-cl.exe options used - # /Yc creates a precompiled header file - # /Fp specifies precompiled header binary file name - # /FI forces inclusion of file - # /Zs syntax check only - # /TC treat all files named on the command line as C source files - # /TP treat all files named on the command line as C++ source files - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags "${_sourceFileType${_language}}" - "/Yc${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}" /Zs "${_hostFile}") - else() - # return as a flag string - set (_flags "/Yc\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"") - endif() - endif() - elseif (_compilerID MATCHES "Intel") - if (WIN32) - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) - # Windows Intel options used - # /nologo do not display compiler version information - # /Yc create a precompiled header (PCH) file - # /Fp specify a path or file name for precompiled header files - # /FI tells the preprocessor to include a specified file name as the header file - # /TC process all source or unrecognized file types as C source files - # /TP process all source or unrecognized file types as C++ source files - # /Zs syntax check only - # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" - "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "/Wpch-messages") - endif() - else() - # return as a flag string - set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} /Wpch-messages") - endif() - endif() - else() - # Linux / Mac OS X Intel options used - # -pch-dir location for precompiled header files - # -pch-create name of the precompiled header (PCH) to create - # -Kc++ process all source or unrecognized file types as C++ source files - # -fsyntax-only check only for correct syntax - # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - get_filename_component(_pchDir "${_pchFile}" DIRECTORY) - get_filename_component(_pchName "${_pchFile}" NAME) - set (_xLanguage_C "c-header") - set (_xLanguage_CXX "c++-header") - set (_pchSuppressMessages FALSE) - if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") - set(_pchSuppressMessages TRUE) - endif() - if (_flags) - # append to list - if ("${_language}" STREQUAL "CXX") - list (APPEND _flags -Kc++) - endif() - list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-create "${_pchName}" -fsyntax-only "${_hostFile}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - if (NOT _pchSuppressMessages) - list (APPEND _flags -Wpch-messages) - endif() - endif() - else() - # return as a flag string - set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - if (NOT _pchSuppressMessages) - set (_flags "${_flags} -Wpch-messages") - endif() - endif() - endif() - endif() - else() - message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") - endif() - set (${_flagsVar} ${_flags} PARENT_SCOPE) -endfunction() - -function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar) - set (_flags ${${_flagsVar}}) - if (_compilerID MATCHES "MSVC") - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - # cl.exe options used - # /Yu uses a precompiled header file during build - # /Fp specifies precompiled header binary file name - # /FI forces inclusion of file - # /Zm precompiled header memory allocation scaling factor - if (_pchFile) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - if (_flags) - # append to list - list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - else() - # return as a flag string - set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - endif() - else() - # no precompiled header, force inclusion of prefix header - if (_flags) - # append to list - list (APPEND _flags "/FI${_prefixFileNative}") - else() - # return as a flag string - set (_flags "/FI\"${_prefixFileNative}\"") - endif() - endif() - elseif (_compilerID MATCHES "GNU") - # GCC options used - # -include process include file as the first line of the primary source file - # -Winvalid-pch warns if precompiled header is found but cannot be used - # note: ccache requires the -include flag to be used in order to process precompiled header correctly - if (_flags) - # append to list - list (APPEND _flags -Winvalid-pch -include "${_prefixFile}") - else() - # return as a flag string - set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") - endif() - elseif (_compilerID MATCHES "Clang") - if (UNIX) - # Clang options used - # -include process include file as the first line of the primary source file - # note: ccache requires the -include flag to be used in order to process precompiled header correctly - if (_flags) - # append to list - list (APPEND _flags -include "${_prefixFile}") - else() - # return as a flag string - set (_flags "-include \"${_prefixFile}\"") - endif() - elseif (WIN32) - # Clang-cl.exe options used - # /Yu uses a precompiled header file during build - # /Fp specifies precompiled header binary file name - # /FI forces inclusion of file - if (_pchFile) - if (_flags) - # append to list - list (APPEND _flags "/Yu${_prefixFile}" "/Fp${_pchFile}" "/FI${_prefixFile}") - else() - # return as a flag string - set (_flags "/Yu\"${_prefixFile}\" /Fp\"${_pchFile}\" /FI\"${_prefixFile}\"") - endif() - else() - # no precompiled header, force inclusion of prefix header - if (_flags) - # append to list - list (APPEND _flags "/FI${_prefixFile}") - else() - # return as a flag string - set (_flags "/FI\"${_prefixFile}\"") - endif() - endif() - endif() - elseif (_compilerID MATCHES "Intel") - if (WIN32) - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - # Windows Intel options used - # /Yu use a precompiled header (PCH) file - # /Fp specify a path or file name for precompiled header files - # /FI tells the preprocessor to include a specified file name as the header file - # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - if (_pchFile) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - if (_flags) - # append to list - list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "/Wpch-messages") - endif() - else() - # return as a flag string - set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} /Wpch-messages") - endif() - endif() - else() - # no precompiled header, force inclusion of prefix header - if (_flags) - # append to list - list (APPEND _flags "/FI${_prefixFileNative}") - else() - # return as a flag string - set (_flags "/FI\"${_prefixFileNative}\"") - endif() - endif() - else() - # Linux / Mac OS X Intel options used - # -pch-dir location for precompiled header files - # -pch-use name of the precompiled header (PCH) to use - # -include process include file as the first line of the primary source file - # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - if (_pchFile) - get_filename_component(_pchDir "${_pchFile}" DIRECTORY) - get_filename_component(_pchName "${_pchFile}" NAME) - set (_pchSuppressMessages FALSE) - if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") - set(_pchSuppressMessages TRUE) - endif() - if (_flags) - # append to list - list (APPEND _flags -include "${_prefixFile}" -pch-dir "${_pchDir}" -pch-use "${_pchName}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - if (NOT _pchSuppressMessages) - list (APPEND _flags -Wpch-messages) - endif() - endif() - else() - # return as a flag string - set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - if (NOT _pchSuppressMessages) - set (_flags "${_flags} -Wpch-messages") - endif() - endif() - endif() - else() - # no precompiled header, force inclusion of prefix header - if (_flags) - # append to list - list (APPEND _flags -include "${_prefixFile}") - else() - # return as a flag string - set (_flags "-include \"${_prefixFile}\"") - endif() - endif() - endif() - else() - message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") - endif() - set (${_flagsVar} ${_flags} PARENT_SCOPE) -endfunction() - -function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) - set(_options "") - set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (NOT _option_LANGUAGE) - set (_option_LANGUAGE "CXX") - endif() - if (NOT _option_COMPILER_ID) - set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") - endif() - if (NOT _option_COMPILER_VERSION) - set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") - endif() - cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") - cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) - cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_pch_compilation_flags( - "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) - if (COTIRE_VERBOSE) - message (STATUS "execute_process: ${_cmd}") - endif() - if (MSVC_IDE OR _option_COMPILER_ID MATCHES "MSVC") - # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared - unset (ENV{VS_UNICODE_OUTPUT}) - elseif (_option_COMPILER_ID MATCHES "Clang" AND _option_COMPILER_VERSION VERSION_LESS "4.0.0") - if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR - _option_COMPILER_EXECUTABLE MATCHES "ccache") - # Newer versions of Clang embed a compilation timestamp into the precompiled header binary, - # which results in "file has been modified since the precompiled header was built" errors if ccache is used. - # We work around the problem by disabling ccache upon pre-compiling the prefix header. - set (ENV{CCACHE_DISABLE} "true") - endif() - endif() - execute_process( - COMMAND ${_cmd} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE _result) - if (_result) - message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.") - endif() -endfunction() - -function (cotire_check_precompiled_header_support _language _target _msgVar) - set (_unsupportedCompiler - "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") - # PCH supported since Visual Studio C++ 6.0 - # and CMake does not support an earlier version - set (${_msgVar} "" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") - # GCC PCH support requires version >= 3.4 - if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") - set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) - else() - set (${_msgVar} "" PARENT_SCOPE) - endif() - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") - if (UNIX) - # all Unix Clang versions have PCH support - set (${_msgVar} "" PARENT_SCOPE) - elseif (WIN32) - # only clang-cl is supported under Windows - get_filename_component(_compilerName "${CMAKE_${_language}_COMPILER}" NAME_WE) - if (NOT _compilerName MATCHES "cl$") - set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}. Use clang-cl instead." PARENT_SCOPE) - endif() - endif() - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") - # Intel PCH support requires version >= 8.0.0 - if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") - set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) - else() - set (${_msgVar} "" PARENT_SCOPE) - endif() - else() - set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) - endif() - # check if ccache is used as a compiler launcher - get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER) - get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" REALPATH) - if (_realCompilerExe MATCHES "ccache" OR _launcher MATCHES "ccache") - # verify that ccache configuration is compatible with precompiled headers - # always check environment variable CCACHE_SLOPPINESS, because earlier versions of ccache - # do not report the "sloppiness" setting correctly upon printing ccache configuration - if (DEFINED ENV{CCACHE_SLOPPINESS}) - if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR - NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros") - set (${_msgVar} - "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"." - PARENT_SCOPE) - endif() - else() - if (_realCompilerExe MATCHES "ccache") - set (_ccacheExe "${_realCompilerExe}") - else() - set (_ccacheExe "${_launcher}") - endif() - execute_process( - COMMAND "${_ccacheExe}" "--print-config" - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" - RESULT_VARIABLE _result - OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET) - if (_result) - set (${_msgVar} "ccache configuration cannot be determined." PARENT_SCOPE) - elseif (NOT _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR - NOT _ccacheConfig MATCHES "sloppiness.*=.*pch_defines") - set (${_msgVar} - "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"." - PARENT_SCOPE) - endif() - endif() - endif() - if (APPLE) - # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) - cotire_get_configuration_types(_configs) - foreach (_config ${_configs}) - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) - list (LENGTH _architectures _numberOfArchitectures) - if (_numberOfArchitectures GREATER 1) - string (REPLACE ";" ", " _architectureStr "${_architectures}") - set (${_msgVar} - "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})." - PARENT_SCOPE) - break() - endif() - endforeach() - endif() -endfunction() - -macro (cotire_get_intermediate_dir _cotireDir) - # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types - get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) -endmacro() - -macro (cotire_setup_file_extension_variables) - set (_unityFileExt_C ".c") - set (_unityFileExt_CXX ".cxx") - set (_prefixFileExt_C ".h") - set (_prefixFileExt_CXX ".hxx") - set (_prefixSourceFileExt_C ".c") - set (_prefixSourceFileExt_CXX ".cxx") -endmacro() - -function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _unityFileExt_${_language}) - set (${_unityFileVar} "" PARENT_SCOPE) - return() - endif() - set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") - set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}") - cotire_get_intermediate_dir(_baseDir) - set (_unityFile "${_baseDir}/${_unityFileName}") - set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) -endfunction() - -function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _unityFileExt_${_language}) - set (${_unityFileVar} "" PARENT_SCOPE) - return() - endif() - set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") - cotire_get_intermediate_dir(_baseDir) - set (_startIndex 0) - set (_index 0) - set (_unityFiles "") - set (_sourceFiles ${ARGN}) - foreach (_sourceFile ${_sourceFiles}) - get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE) - math (EXPR _unityFileCount "${_index} - ${_startIndex}") - if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes)) - if (_index GREATER 0) - # start new unity file segment - math (EXPR _endIndex "${_index} - 1") - set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") - list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") - endif() - set (_startIndex ${_index}) - endif() - math (EXPR _index "${_index} + 1") - endforeach() - list (LENGTH _sourceFiles _numberOfSources) - if (_startIndex EQUAL 0) - # there is only a single unity file - cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles) - elseif (_startIndex LESS _numberOfSources) - # end with final unity file segment - math (EXPR _endIndex "${_index} - 1") - set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") - list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") - endif() - set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) - if (COTIRE_DEBUG AND _unityFiles) - message (STATUS "unity files: ${_unityFiles}") - endif() -endfunction() - -function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _unityFileExt_${_language}) - set (${_prefixFileVar} "" PARENT_SCOPE) - return() - endif() - set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") - set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") - string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}") - string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}") - set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) -endfunction() - -function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _prefixSourceFileExt_${_language}) - set (${_prefixSourceFileVar} "" PARENT_SCOPE) - return() - endif() - string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") - set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) -endfunction() - -function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) - cotire_setup_file_extension_variables() - if (NOT _language) - set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") - set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}") - elseif (DEFINED _prefixFileExt_${_language}) - set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") - set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}") - else() - set (_prefixFileBaseName "") - set (_prefixFileName "") - endif() - set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE) - set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE) -endfunction() - -function (cotire_make_prefix_file_path _language _target _prefixFileVar) - cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) - set (${_prefixFileVar} "" PARENT_SCOPE) - if (_prefixFileName) - if (NOT _language) - set (_language "C") - endif() - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC") - cotire_get_intermediate_dir(_baseDir) - set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) - endif() - endif() -endfunction() - -function (cotire_make_pch_file_path _language _target _pchFileVar) - cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) - set (${_pchFileVar} "" PARENT_SCOPE) - if (_prefixFileBaseName AND _prefixFileName) - cotire_check_precompiled_header_support("${_language}" "${_target}" _msg) - if (NOT _msg) - if (XCODE) - # For Xcode, we completely hand off the compilation of the prefix header to the IDE - return() - endif() - cotire_get_intermediate_dir(_baseDir) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") - # MSVC uses the extension .pch added to the prefix header base name - set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") - # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended - set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") - # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended - set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") - # Intel uses the extension .pchi added to the prefix header base name - set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - -function (cotire_select_unity_source_files _unityFile _sourcesVar) - set (_sourceFiles ${ARGN}) - if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)") - set (_startIndex ${CMAKE_MATCH_1}) - set (_endIndex ${CMAKE_MATCH_2}) - list (LENGTH _sourceFiles _numberOfSources) - if (NOT _startIndex LESS _numberOfSources) - math (EXPR _startIndex "${_numberOfSources} - 1") - endif() - if (NOT _endIndex LESS _numberOfSources) - math (EXPR _endIndex "${_numberOfSources} - 1") - endif() - set (_files "") - foreach (_index RANGE ${_startIndex} ${_endIndex}) - list (GET _sourceFiles ${_index} _file) - list (APPEND _files "${_file}") - endforeach() - else() - set (_files ${_sourceFiles}) - endif() - set (${_sourcesVar} ${_files} PARENT_SCOPE) -endfunction() - -function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) - set (_dependencySources "") - # depend on target's generated source files - get_target_property(_targetSourceFiles ${_target} SOURCES) - cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) - if (_generatedSources) - # but omit all generated source files that have the COTIRE_EXCLUDED property set to true - cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) - if (_excludedGeneratedSources) - list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources}) - endif() - # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly - cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources}) - if (_excludedNonDependencySources) - list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources}) - endif() - if (_generatedSources) - list (APPEND _dependencySources ${_generatedSources}) - endif() - endif() - if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}") - endif() - set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) -endfunction() - -function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) - set (_dependencySources "") - # depend on target source files marked with custom COTIRE_DEPENDENCY property - get_target_property(_targetSourceFiles ${_target} SOURCES) - cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles}) - if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}") - endif() - set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) -endfunction() - -function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar) - set (_targetSources ${ARGN}) - cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources}) - cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources}) - # set up variables to be configured - set (COTIRE_TARGET_LANGUAGE "${_language}") - get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) - cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) - get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) - cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH) - get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) - get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) - get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) - get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH) - cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources}) - cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources}) - set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") - foreach (_config ${_configurations}) - string (TOUPPER "${_config}" _upperConfig) - cotire_get_target_include_directories( - "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) - cotire_get_target_compile_definitions( - "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) - cotire_get_target_compiler_flags( - "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) - cotire_get_source_files_compile_definitions( - "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources}) - endforeach() - get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER) - # set up COTIRE_TARGET_SOURCES - set (COTIRE_TARGET_SOURCES "") - foreach (_sourceFile ${_targetSources}) - get_source_file_property(_generated "${_sourceFile}" GENERATED) - if (_generated) - # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation - get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) - list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}") - else() - list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}") - endif() - endforeach() - # copy variable definitions to cotire target script - get_cmake_property(_vars VARIABLES) - string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") - # omit COTIRE_*_INIT variables - string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}") - if (_initVars) - list (REMOVE_ITEM _matchVars ${_initVars}) - endif() - # omit COTIRE_VERBOSE which is passed as a CMake define on command line - list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) - set (_contents "") - set (_contentsHasGeneratorExpressions FALSE) - foreach (_var IN LISTS _matchVars ITEMS - XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES - CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION - CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 - CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language} - CMAKE_INCLUDE_SYSTEM_FLAG_${_language} - CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG - CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG - CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) - if (DEFINED ${_var}) - string (REPLACE "\"" "\\\"" _value "${${_var}}") - set (_contents "${_contents}set (${_var} \"${_value}\")\n") - if (NOT _contentsHasGeneratorExpressions) - if ("${_value}" MATCHES "\\$<.*>") - set (_contentsHasGeneratorExpressions TRUE) - endif() - endif() - endif() - endforeach() - # generate target script file - get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) - set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") - cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) - if (_contentsHasGeneratorExpressions) - # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time - set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") - set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") - file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") - else() - set (_targetCotireConfigScript "${_targetCotireScript}") - endif() - set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) - set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) -endfunction() - -function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile) - set (_sourceFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR - (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) - # for MSVC, Intel and Clang-cl, we attach the precompiled header compilation to the host file - # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion - if (_sourceFiles) - set (_flags "") - cotire_add_pch_compilation_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) - set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") - # make object file generated from host file depend on prefix header - set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") - # mark host file as cotired to prevent it from being used in another cotired target - set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") - endif() - elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # for makefile based generator, we add a custom command to precompile the prefix header - if (_targetScript) - cotire_set_cmd_to_prologue(_cmds) - list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath) - else() - file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}") - endif() - # make precompiled header compilation depend on the actual compiler executable used to force - # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable" - # warnings when the precompiled header is included. - get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") - endif() - set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) - add_custom_command( - OUTPUT "${_pchFile}" - COMMAND ${_cmds} - DEPENDS "${_prefixFile}" "${_realCompilerExe}" - IMPLICIT_DEPENDS ${_language} "${_prefixFile}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}" - VERBATIM) - endif() - endif() -endfunction() - -function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" OR - (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) - # for MSVC, Intel and clang-cl, we include the precompiled header in all but the host file - # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation - set (_sourceFiles ${ARGN}) - list (LENGTH _sourceFiles _numberOfSourceFiles) - if (_numberOfSourceFiles GREATER 0) - # mark sources as cotired to prevent them from being used in another cotired target - set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - set (_flags "") - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _flags) - set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - # make object files generated from source files depend on precompiled header - set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") - endif() - elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - set (_sourceFiles ${_hostFile} ${ARGN}) - if (NOT _wholeTarget) - # for makefile based generator, we force the inclusion of the prefix header for a subset - # of the source files, if this is a multi-language target or has excluded files - set (_flags "") - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _flags) - set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - # mark sources as cotired to prevent them from being used in another cotired target - set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - endif() - # make object files generated from source files depend on precompiled header - set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") - endif() -endfunction() - -function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) - set (_sourceFiles ${ARGN}) - # force the inclusion of the prefix header for the given source files - set (_flags "") - set (_pchFile "") - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _flags) - set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - # mark sources as cotired to prevent them from being used in another cotired target - set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - # make object files generated from source files depend on prefix header - set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") -endfunction() - -function (cotire_get_first_set_property_value _propertyValueVar _type _object) - set (_properties ${ARGN}) - foreach (_property ${_properties}) - get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) - if (_propertyValue) - set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE) - return() - endif() - endforeach() - set (${_propertyValueVar} "" PARENT_SCOPE) -endfunction() - -function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar) - set (_files ${ARGN}) - set (_filesPaths "") - foreach (_file ${_files}) - get_filename_component(_filePath "${_file}" ABSOLUTE) - list (APPEND _filesPaths "${_filePath}") - endforeach() - cotire_set_cmd_to_prologue(_prefixCmd) - list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") - if (_targetScript) - list (APPEND _prefixCmd "${_targetScript}") - endif() - list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths}) - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") - endif() - set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath) - else() - file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") - endif() - get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) - get_filename_component(_joinedFileExt "${_joinedFile}" EXT) - if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") - set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}") - elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") - if (_joinedFileExt MATCHES "^\\.c") - set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}") - else() - set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}") - endif() - else() - set (_comment "Generating ${_joinedFileLogPath}") - endif() - add_custom_command( - OUTPUT "${_joinedFile}" - COMMAND ${_prefixCmd} - DEPENDS ${_files} - COMMENT "${_comment}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - VERBATIM) - list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_target_pch_usage _languages _target _wholeTarget) - if (XCODE) - # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers - set (_prefixFiles "") - foreach (_language ${_languages}) - get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) - if (_prefixFile) - list (APPEND _prefixFiles "${_prefixFile}") - endif() - endforeach() - set (_cmds ${ARGN}) - list (LENGTH _prefixFiles _numberOfPrefixFiles) - if (_numberOfPrefixFiles GREATER 1) - # we also generate a generic, single prefix header which includes all language specific prefix headers - set (_language "") - set (_targetScript "") - cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader) - cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles}) - else() - set (_prefixHeader "${_prefixFiles}") - endif() - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") - endif() - # because CMake PRE_BUILD command does not support dependencies, - # we check dependencies explicity in cotire script mode when the pre-build action is run - add_custom_command( - TARGET "${_target}" - PRE_BUILD ${_cmds} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMENT "Updating target ${_target} prefix headers" - VERBATIM) - # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ - set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") - set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") - elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # for makefile based generator, we force inclusion of the prefix header for all target source files - # if this is a single-language target without any excluded files - if (_wholeTarget) - set (_language "${_languages}") - # for MSVC, Intel and clang-cl, precompiled header inclusion is always done on the source file level - # see cotire_setup_pch_file_inclusion - if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT - (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) - get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) - if (_prefixFile) - get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) - set (_options COMPILE_OPTIONS) - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _options) - set_property(TARGET ${_target} APPEND PROPERTY ${_options}) - endif() - endif() - endif() - endif() -endfunction() - -function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar) - set (_dependencySources "") - cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) - foreach (_unityFile ${_unityFiles}) - set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) - # set up compiled unity source dependencies via OBJECT_DEPENDS - # this ensures that missing source files are generated before the unity file is compiled - if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") - endif() - if (_dependencySources) - # the OBJECT_DEPENDS property requires a list of full paths - set (_objectDependsPaths "") - foreach (_sourceFile ${_dependencySources}) - get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) - list (APPEND _objectDependsPaths "${_sourceLocation}") - endforeach() - set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths}) - endif() - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # unity file compilation results in potentially huge object file, - # thus use /bigobj by default unter cl.exe and Windows Intel - set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") - endif() - cotire_set_cmd_to_prologue(_unityCmd) - list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") - if (CMAKE_VERSION VERSION_LESS "3.1.0") - set (_unityCmdDepends "${_targetScript}") - else() - # CMake 3.1.0 supports generator expressions in arguments to DEPENDS - set (_unityCmdDepends "${_targetConfigScript}") - endif() - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath) - else() - file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}") - endif() - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}") - endif() - add_custom_command( - OUTPUT "${_unityFile}" - COMMAND ${_unityCmd} - DEPENDS ${_unityCmdDepends} - COMMENT "Generating ${_language} unity source ${_unityFileLogPath}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - VERBATIM) - list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) - endforeach() - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) - set (_sourceFiles ${ARGN}) - set (_dependencySources "") - cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) - cotire_set_cmd_to_prologue(_prefixCmd) - list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles}) - set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) - # make prefix header generation depend on the actual compiler executable used to force - # re-generation when the compiler executable is updated. This prevents "file not found" - # errors for compiler version specific system header files. - get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}") - endif() - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath) - else() - file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") - endif() - get_filename_component(_prefixFileExt "${_prefixFile}" EXT) - if (_prefixFileExt MATCHES "^\\.c") - set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}") - else() - set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}") - endif() - # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist - # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence - # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files - set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre") - if (TARGET ${_preTargetName}) - # custom helper target has already been generated while processing a different language - list (APPEND _dependencySources ${_preTargetName}) - else() - get_target_property(_targetSourceFiles ${_target} SOURCES) - cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) - if (_generatedSources) - add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources}) - cotire_init_target("${_preTargetName}") - list (APPEND _dependencySources ${_preTargetName}) - endif() - endif() - add_custom_command( - OUTPUT "${_prefixFile}" "${_prefixFile}.log" - COMMAND ${_prefixCmd} - DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}" - COMMENT "${_comment}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - VERBATIM) - list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) - set (_sourceFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma - cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) - else() - set (_prefixSourceFile "${_prefixFile}") - endif() - cotire_setup_prefix_generation_command( - ${_language} ${_target} "${_targetScript}" - "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # set up generation of a prefix source file which includes the prefix header - cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) - endif() - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar) - set (_prefixHeaderFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma - cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) - else() - set (_prefixSourceFile "${_prefixFile}") - endif() - cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # set up generation of a prefix source file which includes the prefix header - cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) - endif() - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_init_cotire_target_properties _target) - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE) - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE) - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE) - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}") - cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}") - if (NOT _isRelative) - set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}") - endif() - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) - if (NOT _isSet) - if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}") - else() - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "") - endif() - endif() -endfunction() - -function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar) - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) - string (REPLACE ";" " " _languagesStr "${_languages}") - math (EXPR _numberOfExcludedFiles "${ARGC} - 4") - if (_numberOfExcludedFiles EQUAL 0) - set (_excludedStr "") - elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4) - string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}") - else() - set (_excludedStr "excluding ${_numberOfExcludedFiles} files") - endif() - set (_targetMsg "") - if (NOT _languages) - set (_targetMsg "Target ${_target} cannot be cotired.") - if (_disableMsg) - set (_targetMsg "${_targetMsg} ${_disableMsg}") - endif() - elseif (NOT _targetUsePCH AND NOT _targetAddSCU) - set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.") - if (_disableMsg) - set (_targetMsg "${_targetMsg} ${_disableMsg}") - endif() - elseif (NOT _targetUsePCH) - if (_excludedStr) - set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.") - else() - set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.") - endif() - if (_disableMsg) - set (_targetMsg "${_targetMsg} ${_disableMsg}") - endif() - elseif (NOT _targetAddSCU) - if (_excludedStr) - set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.") - else() - set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") - endif() - if (_disableMsg) - set (_targetMsg "${_targetMsg} ${_disableMsg}") - endif() - else() - if (_excludedStr) - set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") - else() - set (_targetMsg "${_languagesStr} target ${_target} cotired.") - endif() - endif() - set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) -endfunction() - -function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar) - set (_languages ${ARGN}) - set (_allSourceFiles "") - set (_allExcludedSourceFiles "") - set (_allCotiredSourceFiles "") - set (_targetLanguages "") - set (_pchEligibleTargetLanguages "") - get_target_property(_targetType ${_target} TYPE) - get_target_property(_targetSourceFiles ${_target} SOURCES) - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) - set (_disableMsg "") - foreach (_language ${_languages}) - get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) - get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) - if (_prefixHeader OR _unityBuildFile) - message (STATUS "cotire: target ${_target} has already been cotired.") - set (${_targetLanguagesVar} "" PARENT_SCOPE) - return() - endif() - if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID) - if (CMAKE_${_language}_COMPILER_ID) - cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg) - if (_disableMsg) - set (_targetUsePCH FALSE) - endif() - endif() - endif() - set (_sourceFiles "") - set (_excludedSources "") - set (_cotiredSources "") - cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) - if (_sourceFiles OR _excludedSources OR _cotiredSources) - list (APPEND _targetLanguages ${_language}) - endif() - if (_sourceFiles) - list (APPEND _allSourceFiles ${_sourceFiles}) - endif() - list (LENGTH _sourceFiles _numberOfSources) - if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) - list (APPEND _pchEligibleTargetLanguages ${_language}) - endif() - if (_excludedSources) - list (APPEND _allExcludedSourceFiles ${_excludedSources}) - endif() - if (_cotiredSources) - list (APPEND _allCotiredSourceFiles ${_cotiredSources}) - endif() - endforeach() - set (_targetMsgLevel STATUS) - if (NOT _targetLanguages) - string (REPLACE ";" " or " _languagesStr "${_languages}") - set (_disableMsg "No ${_languagesStr} source files.") - set (_targetUsePCH FALSE) - set (_targetAddSCU FALSE) - endif() - if (_targetUsePCH) - if (_allCotiredSourceFiles) - cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) - list (REMOVE_DUPLICATES _cotireTargets) - string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") - set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.") - set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},") - set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") - set (_targetMsgLevel SEND_ERROR) - set (_targetUsePCH FALSE) - elseif (NOT _pchEligibleTargetLanguages) - set (_disableMsg "Too few applicable sources.") - set (_targetUsePCH FALSE) - elseif (XCODE AND _allExcludedSourceFiles) - # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target - set (_disableMsg "Exclusion of source files not supported for generator Xcode.") - set (_targetUsePCH FALSE) - elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY") - # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target - set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.") - set (_targetUsePCH FALSE) - endif() - endif() - if (_targetAddSCU) - # disable unity builds if automatic Qt processing is used - get_target_property(_targetAutoMoc ${_target} AUTOMOC) - get_target_property(_targetAutoUic ${_target} AUTOUIC) - get_target_property(_targetAutoRcc ${_target} AUTORCC) - if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) - if (_disableMsg) - set (_disableMsg "${_disableMsg} Target uses automatic CMake Qt processing.") - else() - set (_disableMsg "Target uses automatic CMake Qt processing.") - endif() - set (_targetAddSCU FALSE) - endif() - endif() - set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) - set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) - cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) - if (_targetMsg) - if (NOT DEFINED COTIREMSG_${_target}) - set (COTIREMSG_${_target} "") - endif() - if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR - NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}") - # cache message to avoid redundant messages on re-configure - set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.") - message (${_targetMsgLevel} "${_targetMsg}") - endif() - endif() - list (LENGTH _targetLanguages _numberOfLanguages) - if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles) - set (${_wholeTargetVar} FALSE PARENT_SCOPE) - else() - set (${_wholeTargetVar} TRUE PARENT_SCOPE) - endif() - set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) -endfunction() - -function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) - set (_sourceFiles ${ARGN}) - get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) - if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") - if (DEFINED CMAKE_MATCH_2) - set (_numberOfThreads "${CMAKE_MATCH_2}") - else() - set (_numberOfThreads "") - endif() - if (NOT _numberOfThreads) - # use all available cores - ProcessorCount(_numberOfThreads) - endif() - list (LENGTH _sourceFiles _numberOfSources) - math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") - elseif (NOT _maxIncludes MATCHES "[0-9]+") - set (_maxIncludes 0) - endif() - if (COTIRE_DEBUG) - message (STATUS "${_target} unity source max includes: ${_maxIncludes}") - endif() - set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) -endfunction() - -function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar) - set (${_cmdsVar} "" PARENT_SCOPE) - get_target_property(_targetSourceFiles ${_target} SOURCES) - set (_sourceFiles "") - set (_excludedSources "") - set (_cotiredSources "") - cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) - if (NOT _sourceFiles AND NOT _cotiredSources) - return() - endif() - set (_cmds "") - # check for user provided unity source file list - get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) - if (NOT _unitySourceFiles) - set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) - endif() - cotire_generate_target_script( - ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) - # set up unity files for parallel compilation - cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) - cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) - list (LENGTH _unityFiles _numberOfUnityFiles) - if (_numberOfUnityFiles EQUAL 0) - return() - elseif (_numberOfUnityFiles GREATER 1) - cotire_setup_unity_generation_commands( - ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) - endif() - # set up single unity file for prefix header generation - cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) - cotire_setup_unity_generation_commands( - ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles}) - cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) - # set up prefix header - if (_prefixFile) - # check for user provided prefix header files - get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) - if (_prefixHeaderFiles) - cotire_setup_prefix_generation_from_provided_command( - ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) - else() - cotire_setup_prefix_generation_from_unity_command( - ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles}) - endif() - # check if selected language has enough sources at all - list (LENGTH _sourceFiles _numberOfSources) - if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) - set (_targetUsePCH FALSE) - else() - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - endif() - if (_targetUsePCH) - cotire_make_pch_file_path(${_language} ${_target} _pchFile) - if (_pchFile) - # first file in _sourceFiles is passed as the host file - cotire_setup_pch_file_compilation( - ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) - cotire_setup_pch_file_inclusion( - ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) - endif() - elseif (_prefixHeaderFiles) - # user provided prefix header must be included unconditionally - cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) - endif() - endif() - # mark target as cotired for language - set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}") - if (_prefixFile) - set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}") - if (_targetUsePCH AND _pchFile) - set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") - endif() - endif() - set (${_cmdsVar} ${_cmds} PARENT_SCOPE) -endfunction() - -function (cotire_setup_clean_target _target) - set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}") - if (NOT TARGET "${_cleanTargetName}") - cotire_set_cmd_to_prologue(_cmds) - get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) - list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") - add_custom_target(${_cleanTargetName} - COMMAND ${_cmds} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - COMMENT "Cleaning up target ${_target} cotire generated files" - VERBATIM) - cotire_init_target("${_cleanTargetName}") - endif() -endfunction() - -function (cotire_setup_pch_target _languages _configurations _target) - if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # for makefile based generators, we add a custom target to trigger the generation of the cotire related files - set (_dependsFiles "") - foreach (_language ${_languages}) - set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) - if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel" AND NOT - (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "Clang")) - # MSVC, Intel and clang-cl only create precompiled header as a side effect - list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) - endif() - cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) - if (_dependsFile) - list (APPEND _dependsFiles "${_dependsFile}") - endif() - endforeach() - if (_dependsFiles) - set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}") - add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles}) - cotire_init_target("${_pchTargetName}") - cotire_add_to_pch_all_target(${_pchTargetName}) - endif() - else() - # for other generators, we add the "clean all" target to clean up the precompiled header - cotire_setup_clean_all_target() - endif() -endfunction() - -function (cotire_filter_object_libraries _target _objectLibrariesVar) - set (_objectLibraries "") - foreach (_source ${ARGN}) - if (_source MATCHES "^\\$$") - list (APPEND _objectLibraries "${_source}") - endif() - endforeach() - set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE) -endfunction() - -function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar) - get_target_property(_targetSourceFiles ${_target} SOURCES) - set (_unityTargetSources ${_targetSourceFiles}) - foreach (_language ${_languages}) - get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) - if (_unityFiles) - # remove source files that are included in the unity source - set (_sourceFiles "") - set (_excludedSources "") - set (_cotiredSources "") - cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) - if (_sourceFiles OR _cotiredSources) - list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) - endif() - # add unity source files instead - list (APPEND _unityTargetSources ${_unityFiles}) - endif() - endforeach() - # handle object libraries which are part of the target's sources - get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) - if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$") - cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles}) - if (_objectLibraries) - cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries}) - list (REMOVE_ITEM _unityTargetSources ${_objectLibraries}) - list (APPEND _unityTargetSources ${_unityObjectLibraries}) - endif() - endif() - set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE) -endfunction() - -function (cotire_setup_unity_target_pch_usage _languages _target) - foreach (_language ${_languages}) - get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) - if (_unityFiles) - get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) - get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) - if (_userPrefixFile AND _prefixFile) - # user provided prefix header must be included unconditionally by unity sources - cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles}) - endif() - endif() - endforeach() -endfunction() - -function (cotire_setup_unity_build_target _languages _configurations _target) - get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) - if (NOT _unityTargetName) - set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") - endif() - # determine unity target sub type - get_target_property(_targetType ${_target} TYPE) - if ("${_targetType}" STREQUAL "EXECUTABLE") - set (_unityTargetSubType "") - elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") - set (_unityTargetSubType "${CMAKE_MATCH_1}") - else() - message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") - return() - endif() - # determine unity target sources - set (_unityTargetSources "") - cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources) - # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created - set (CMAKE_AUTOMOC OFF) - set (CMAKE_AUTOUIC OFF) - set (CMAKE_AUTORCC OFF) - if (COTIRE_DEBUG) - message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") - endif() - # generate unity target - if ("${_targetType}" STREQUAL "EXECUTABLE") - add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) - else() - add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) - endif() - # copy output location properties - set (_outputDirProperties - ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_ - LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_ - RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_) - if (COTIRE_UNITY_OUTPUT_DIRECTORY) - set (_setDefaultOutputDir TRUE) - if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") - set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") - else() - # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) - cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties}) - foreach (_property ${_properties}) - get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) - if (_outputDir) - get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) - set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}") - set (_setDefaultOutputDir FALSE) - endif() - endforeach() - if (_setDefaultOutputDir) - get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) - endif() - endif() - if (_setDefaultOutputDir) - set_target_properties(${_unityTargetName} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}" - LIBRARY_OUTPUT_DIRECTORY "${_outputDir}" - RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") - endif() - else() - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - ${_outputDirProperties}) - endif() - # copy output name - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_ - LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_ - OUTPUT_NAME OUTPUT_NAME_ - RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_ - PREFIX _POSTFIX SUFFIX - IMPORT_PREFIX IMPORT_SUFFIX) - # copy compile stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - COMPILE_DEFINITIONS COMPILE_DEFINITIONS_ - COMPILE_FLAGS COMPILE_OPTIONS - Fortran_FORMAT Fortran_MODULE_DIRECTORY - INCLUDE_DIRECTORIES - INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_ - POSITION_INDEPENDENT_CODE - C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER - C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE - C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN - C_CLANG_TIDY CXX_CLANG_TIDY) - # copy compile features - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED - CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED - COMPILE_FEATURES) - # copy interface stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN - COMPATIBLE_INTERFACE_STRING - INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS - INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES - INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES - INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED) - # copy link stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - BUILD_WITH_INSTALL_RPATH BUILD_WITH_INSTALL_NAME_DIR - INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH - LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED - LINK_FLAGS LINK_FLAGS_ - LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_ - LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_ - LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC - STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_ - NO_SONAME SOVERSION VERSION - LINK_WHAT_YOU_USE BUILD_RPATH) - # copy cmake stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) - # copy Apple platform specific stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR - MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH - OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST - IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE) - # copy Windows platform specific stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - GNUtoMS - COMPILE_PDB_NAME COMPILE_PDB_NAME_ - COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_ - PDB_NAME PDB_NAME_ PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_ - VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION - VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE - VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK - VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION - VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER - VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION - VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES - WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS - DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE - VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY) - # copy Android platform specific stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - ANDROID_API ANDROID_API_MIN ANDROID_GUI - ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES - ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR - ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES - ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH - ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE) - # copy CUDA platform specific stuff - cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} - CUDA_PTX_COMPILATION CUDA_SEPARABLE_COMPILATION CUDA_RESOLVE_DEVICE_SYMBOLS - CUDA_EXTENSIONS CUDA_STANDARD CUDA_STANDARD_REQUIRED) - # use output name from original target - get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) - if (NOT _targetOutputName) - set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}") - endif() - # use export symbol from original target - cotire_get_target_export_symbol("${_target}" _defineSymbol) - if (_defineSymbol) - set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}") - if ("${_targetType}" STREQUAL "EXECUTABLE") - set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) - endif() - endif() - # enable parallel compilation for MSVC - if (MSVC AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio") - list (LENGTH _unityTargetSources _numberOfUnityTargetSources) - if (_numberOfUnityTargetSources GREATER 1) - set_property(TARGET ${_unityTargetName} APPEND PROPERTY COMPILE_OPTIONS "/MP") - endif() - endif() - cotire_init_target(${_unityTargetName}) - cotire_add_to_unity_all_target(${_unityTargetName}) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") -endfunction(cotire_setup_unity_build_target) - -function (cotire_target _target) - set(_options "") - set(_oneValueArgs "") - set(_multiValueArgs LANGUAGES CONFIGURATIONS) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (NOT _option_LANGUAGES) - get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) - endif() - if (NOT _option_CONFIGURATIONS) - cotire_get_configuration_types(_option_CONFIGURATIONS) - endif() - # check if cotire can be applied to target at all - cotire_is_target_supported(${_target} _isSupported) - if (NOT _isSupported) - get_target_property(_imported ${_target} IMPORTED) - get_target_property(_targetType ${_target} TYPE) - if (_imported) - message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.") - else() - message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.") - endif() - return() - endif() - # resolve alias - get_target_property(_aliasName ${_target} ALIASED_TARGET) - if (_aliasName) - if (COTIRE_DEBUG) - message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.") - endif() - set (_target ${_aliasName}) - endif() - # check if target needs to be cotired for build type - # when using configuration types, the test is performed at build time - cotire_init_cotire_target_properties(${_target}) - if (NOT CMAKE_CONFIGURATION_TYPES) - if (CMAKE_BUILD_TYPE) - list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index) - else() - list (FIND _option_CONFIGURATIONS "None" _index) - endif() - if (_index EQUAL -1) - if (COTIRE_DEBUG) - message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})") - endif() - return() - endif() - endif() - # when not using configuration types, immediately create cotire intermediate dir - if (NOT CMAKE_CONFIGURATION_TYPES) - cotire_get_intermediate_dir(_baseDir) - file (MAKE_DIRECTORY "${_baseDir}") - endif() - # choose languages that apply to the target - cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES}) - if (NOT _targetLanguages) - return() - endif() - set (_cmds "") - foreach (_language ${_targetLanguages}) - cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd) - if (_cmd) - list (APPEND _cmds ${_cmd}) - endif() - endforeach() - get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) - if (_targetAddSCU) - cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) - endif() - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - if (_targetUsePCH) - cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds}) - cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) - if (_targetAddSCU) - cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target}) - endif() - endif() - get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) - if (_targetAddCleanTarget) - cotire_setup_clean_target(${_target}) - endif() -endfunction(cotire_target) - -function (cotire_map_libraries _strategy _mappedLibrariesVar) - set (_mappedLibraries "") - foreach (_library ${ARGN}) - if (_library MATCHES "^\\$$") - set (_libraryName "${CMAKE_MATCH_1}") - set (_linkOnly TRUE) - set (_objectLibrary FALSE) - elseif (_library MATCHES "^\\$$") - set (_libraryName "${CMAKE_MATCH_1}") - set (_linkOnly FALSE) - set (_objectLibrary TRUE) - else() - set (_libraryName "${_library}") - set (_linkOnly FALSE) - set (_objectLibrary FALSE) - endif() - if ("${_strategy}" MATCHES "COPY_UNITY") - cotire_is_target_supported(${_libraryName} _isSupported) - if (_isSupported) - # use target's corresponding unity target, if available - get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME) - if (TARGET "${_libraryUnityTargetName}") - if (_linkOnly) - list (APPEND _mappedLibraries "$") - elseif (_objectLibrary) - list (APPEND _mappedLibraries "$") - else() - list (APPEND _mappedLibraries "${_libraryUnityTargetName}") - endif() - else() - list (APPEND _mappedLibraries "${_library}") - endif() - else() - list (APPEND _mappedLibraries "${_library}") - endif() - else() - list (APPEND _mappedLibraries "${_library}") - endif() - endforeach() - list (REMOVE_DUPLICATES _mappedLibraries) - set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE) -endfunction() - -function (cotire_target_link_libraries _target) - cotire_is_target_supported(${_target} _isSupported) - if (NOT _isSupported) - return() - endif() - get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) - if (TARGET "${_unityTargetName}") - get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) - if (COTIRE_DEBUG) - message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") - endif() - if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") - get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) - if (_linkLibraries) - cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries}) - set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}") - if (COTIRE_DEBUG) - message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}") - endif() - endif() - get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) - if (_interfaceLinkLibraries) - cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries}) - set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}") - if (COTIRE_DEBUG) - message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}") - endif() - endif() - get_target_property(_manualDependencies ${_target} MANUALLY_ADDED_DEPENDENCIES) - if (_manualDependencies) - cotire_map_libraries("${_linkLibrariesStrategy}" _unityManualDependencies ${_manualDependencies}) - if (_unityManualDependencies) - add_dependencies("${_unityTargetName}" ${_unityManualDependencies}) - endif() - endif() - endif() - endif() -endfunction(cotire_target_link_libraries) - -function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) - if (_targetName) - file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*") - else() - file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*") - endif() - # filter files in intermediate directory - set (_filesToRemove "") - foreach (_file ${_cotireFiles}) - get_filename_component(_dir "${_file}" DIRECTORY) - get_filename_component(_dirName "${_dir}" NAME) - if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") - list (APPEND _filesToRemove "${_file}") - endif() - endforeach() - if (_filesToRemove) - if (COTIRE_VERBOSE) - message (STATUS "cleaning up ${_filesToRemove}") - endif() - file (REMOVE ${_filesToRemove}) - endif() -endfunction() - -function (cotire_init_target _targetName) - if (COTIRE_TARGETS_FOLDER) - set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") - endif() - set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE) - if (MSVC_IDE) - set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) - endif() -endfunction() - -function (cotire_add_to_pch_all_target _pchTargetName) - set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") - if (NOT TARGET "${_targetName}") - add_custom_target("${_targetName}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - VERBATIM) - cotire_init_target("${_targetName}") - endif() - cotire_setup_clean_all_target() - add_dependencies(${_targetName} ${_pchTargetName}) -endfunction() - -function (cotire_add_to_unity_all_target _unityTargetName) - set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") - if (NOT TARGET "${_targetName}") - add_custom_target("${_targetName}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - VERBATIM) - cotire_init_target("${_targetName}") - endif() - cotire_setup_clean_all_target() - add_dependencies(${_targetName} ${_unityTargetName}) -endfunction() - -function (cotire_setup_clean_all_target) - set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}") - if (NOT TARGET "${_targetName}") - cotire_set_cmd_to_prologue(_cmds) - list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") - add_custom_target(${_targetName} - COMMAND ${_cmds} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - COMMENT "Cleaning up all cotire generated files" - VERBATIM) - cotire_init_target("${_targetName}") - endif() -endfunction() - -function (cotire) - set(_options "") - set(_oneValueArgs "") - set(_multiValueArgs LANGUAGES CONFIGURATIONS) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - set (_targets ${_option_UNPARSED_ARGUMENTS}) - foreach (_target ${_targets}) - if (TARGET ${_target}) - cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}) - else() - message (WARNING "cotire: ${_target} is not a target.") - endif() - endforeach() - foreach (_target ${_targets}) - if (TARGET ${_target}) - cotire_target_link_libraries(${_target}) - endif() - endforeach() -endfunction() - -if (CMAKE_SCRIPT_MODE_FILE) - - # cotire is being run in script mode - # locate -P on command args - set (COTIRE_ARGC -1) - foreach (_index RANGE ${CMAKE_ARGC}) - if (COTIRE_ARGC GREATER -1) - set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}") - math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1") - elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P") - set (COTIRE_ARGC 0) - endif() - endforeach() - - # include target script if available - if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$") - # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES) - include("${COTIRE_ARGV2}") - endif() - - if (COTIRE_DEBUG) - message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") - endif() - - if (NOT COTIRE_BUILD_TYPE) - set (COTIRE_BUILD_TYPE "None") - endif() - string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) - set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) - set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}}) - set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) - set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) - # check if target has been cotired for actual build type COTIRE_BUILD_TYPE - list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index) - if (_index GREATER -1) - set (_sources ${COTIRE_TARGET_SOURCES}) - set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}}) - else() - if (COTIRE_DEBUG) - message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})") - endif() - set (_sources "") - set (_sourcesDefinitions "") - endif() - set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS}) - set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS}) - set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS}) - set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS}) - - if ("${COTIRE_ARGV1}" STREQUAL "unity") - - if (XCODE) - # executing pre-build action under Xcode, check dependency on target script - set (_dependsOption DEPENDS "${COTIRE_ARGV2}") - else() - # executing custom command, no need to re-check for dependencies - set (_dependsOption "") - endif() - - cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) - - cotire_generate_unity_source( - "${COTIRE_ARGV3}" ${_sources} - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} - PRE_UNDEFS ${_targetPreUndefs} - POST_UNDEFS ${_targetPostUndefs} - SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} - SOURCES_POST_UNDEFS ${_sourcesPostUndefs} - ${_dependsOption}) - - elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") - - if (XCODE) - # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies - set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}) - else() - # executing custom command, no need to re-check for dependencies - set (_dependsOption "") - endif() - - set (_files "") - foreach (_index RANGE 4 ${COTIRE_ARGC}) - if (COTIRE_ARGV${_index}) - list (APPEND _files "${COTIRE_ARGV${_index}}") - endif() - endforeach() - - cotire_generate_prefix_header( - "${COTIRE_ARGV3}" ${_files} - COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" - COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" - COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} - COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" - COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" - INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} - IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" - INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH} - INCLUDE_DIRECTORIES ${_includeDirs} - SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} - COMPILE_DEFINITIONS ${_compileDefinitions} - COMPILE_FLAGS ${_compileFlags} - ${_dependsOption}) - - elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") - - set (_files "") - foreach (_index RANGE 5 ${COTIRE_ARGC}) - if (COTIRE_ARGV${_index}) - list (APPEND _files "${COTIRE_ARGV${_index}}") - endif() - endforeach() - - cotire_precompile_prefix_header( - "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" - COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" - COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" - COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} - COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" - COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - INCLUDE_DIRECTORIES ${_includeDirs} - SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} - COMPILE_DEFINITIONS ${_compileDefinitions} - COMPILE_FLAGS ${_compileFlags}) - - elseif ("${COTIRE_ARGV1}" STREQUAL "combine") - - if (COTIRE_TARGET_LANGUAGE) - set (_combinedFile "${COTIRE_ARGV3}") - set (_startIndex 4) - else() - set (_combinedFile "${COTIRE_ARGV2}") - set (_startIndex 3) - endif() - set (_files "") - foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) - if (COTIRE_ARGV${_index}) - list (APPEND _files "${COTIRE_ARGV${_index}}") - endif() - endforeach() - - if (XCODE) - # executing pre-build action under Xcode, check dependency on files to be combined - set (_dependsOption DEPENDS ${_files}) - else() - # executing custom command, no need to re-check for dependencies - set (_dependsOption "") - endif() - - if (COTIRE_TARGET_LANGUAGE) - cotire_generate_unity_source( - "${_combinedFile}" ${_files} - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - ${_dependsOption}) - else() - cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption}) - endif() - - elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") - - cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") - - else() - message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".") - endif() - -else() - - # cotire is being run in include mode - # set up all variable and property definitions - - if (NOT DEFINED COTIRE_DEBUG_INIT) - if (DEFINED COTIRE_DEBUG) - set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) - else() - set (COTIRE_DEBUG_INIT FALSE) - endif() - endif() - option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT}) - - if (NOT DEFINED COTIRE_VERBOSE_INIT) - if (DEFINED COTIRE_VERBOSE) - set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE}) - else() - set (COTIRE_VERBOSE_INIT FALSE) - endif() - endif() - option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT}) - - set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING - "Ignore headers with the listed file extensions from the generated prefix header.") - - set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING - "Ignore headers from these directories when generating the prefix header.") - - set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING - "Ignore sources with the listed file extensions from the generated unity source.") - - set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "2" CACHE STRING - "Minimum number of sources in target required to enable use of precompiled header.") - - if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) - if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}) - elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio") - # enable parallelization for generators that run multiple jobs by default - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j") - else() - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0") - endif() - endif() - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING - "Maximum number of source files to include in a single unity source file.") - - if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX) - set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix") - endif() - if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX) - set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity") - endif() - if (NOT COTIRE_INTDIR) - set (COTIRE_INTDIR "cotire") - endif() - if (NOT COTIRE_PCH_ALL_TARGET_NAME) - set (COTIRE_PCH_ALL_TARGET_NAME "all_pch") - endif() - if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME) - set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity") - endif() - if (NOT COTIRE_CLEAN_ALL_TARGET_NAME) - set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire") - endif() - if (NOT COTIRE_CLEAN_TARGET_SUFFIX) - set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire") - endif() - if (NOT COTIRE_PCH_TARGET_SUFFIX) - set (COTIRE_PCH_TARGET_SUFFIX "_pch") - endif() - if (MSVC) - # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code - # use a bigger default factor of 170 percent (128 MB) - if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR) - set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170") - endif() - endif() - if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) - set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") - endif() - if (NOT DEFINED COTIRE_TARGETS_FOLDER) - set (COTIRE_TARGETS_FOLDER "cotire") - endif() - if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY) - if ("${CMAKE_GENERATOR}" MATCHES "Ninja") - # generated Ninja build files do not work if the unity target produces the same output file as the cotired target - set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity") - else() - set (COTIRE_UNITY_OUTPUT_DIRECTORY "") - endif() - endif() - - # define cotire cache variables - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH" - BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." - FULL_DOCS - "The variable can be set to a semicolon separated list of include directories." - "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." - "If not defined, defaults to empty list." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS" - BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header." - FULL_DOCS - "The variable can be set to a semicolon separated list of file extensions." - "If a header file extension matches one in the list, it will be excluded from the generated prefix header." - "Includes with an extension in CMAKE__SOURCE_FILE_EXTENSIONS are always ignored." - "If not defined, defaults to inc;inl;ipp." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS" - BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source." - FULL_DOCS - "The variable can be set to a semicolon separated list of file extensions." - "If a source file extension matches one in the list, it will be excluded from the generated unity source file." - "Source files with an extension in CMAKE__IGNORE_EXTENSIONS are always excluded." - "If not defined, defaults to m;mm." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES" - BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header." - FULL_DOCS - "The variable can be set to an integer > 0." - "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." - "If not defined, defaults to 2." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES" - BRIEF_DOCS "Maximum number of source files to include in a single unity source file." - FULL_DOCS - "This may be set to an integer >= 0." - "If 0, cotire will only create a single unity source file." - "If a target contains more than that number of source files, cotire will create multiple unity source files for it." - "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores." - "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs." - "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." - "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise." - ) - - # define cotire directory properties - - define_property( - DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" - BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header." - FULL_DOCS - "See target property COTIRE_ENABLE_PRECOMPILED_HEADER." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD" - BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory." - FULL_DOCS - "See target property COTIRE_ADD_UNITY_BUILD." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_ADD_CLEAN" - BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory." - FULL_DOCS - "See target property COTIRE_ADD_CLEAN." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" - BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." - FULL_DOCS - "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" - BRIEF_DOCS "Honor headers from these directories when generating the prefix header." - FULL_DOCS - "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" - BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header." - FULL_DOCS - "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." - FULL_DOCS - "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file." - FULL_DOCS - "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" - BRIEF_DOCS "Maximum number of source files to include in a single unity source file." - FULL_DOCS - "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" - BRIEF_DOCS "Define strategy for setting up the unity target's link libraries." - FULL_DOCS - "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT." - ) - - # define cotire target properties - - define_property( - TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED - BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header." - FULL_DOCS - "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header." - "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target." - "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header." - "The target name will be set to this target's name with the suffix _pch appended." - "Inherited from directory." - "Defaults to TRUE." - ) - - define_property( - TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED - BRIEF_DOCS "Add a new target that performs a unity build for this target." - FULL_DOCS - "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources." - "Most of the relevant target properties will be copied from this target to the new unity build target." - "Target dependencies and linked libraries have to be manually set up for the new unity build target." - "The unity target name will be set to this target's name with the suffix _unity appended." - "Inherited from directory." - "Defaults to TRUE." - ) - - define_property( - TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED - BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target." - FULL_DOCS - "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)." - "The clean target name will be set to this target's name with the suffix _clean_cotire appended." - "Inherited from directory." - "Defaults to FALSE." - ) - - define_property( - TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED - BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." - FULL_DOCS - "The property can be set to a list of directories." - "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." - "Inherited from directory." - "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}." - ) - - define_property( - TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED - BRIEF_DOCS "Honor headers from these directories when generating the prefix header." - FULL_DOCS - "The property can be set to a list of directories." - "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header." - "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH," - "the option which yields the closer relative path match wins." - "Inherited from directory." - "If not set, this property is initialized to the empty list." - ) - - define_property( - TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED - BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header." - FULL_DOCS - "The property can be set to a list of directories." - "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header." - "Header files are sorted according to the order of the directories in the property." - "If not set, this property is initialized to the empty list." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file before each target source file." - "Inherited from directory." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file after each target source file." - "Inherited from directory." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED - BRIEF_DOCS "Maximum number of source files to include in a single unity source file." - FULL_DOCS - "This may be set to an integer > 0." - "If a target contains more than that number of source files, cotire will create multiple unity build files for it." - "If not set, cotire will only create a single unity source file." - "Inherited from directory." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE__UNITY_SOURCE_INIT" - BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one." - FULL_DOCS - "If set, cotire will only add the given file(s) to the generated unity source file." - "If not set, cotire will add all the target source files to the generated unity source file." - "The property can be set to a user provided unity source file." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE__PREFIX_HEADER_INIT" - BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one." - FULL_DOCS - "If set, cotire will add the given header file(s) to the generated prefix header file." - "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file." - "The property can be set to a user provided prefix header file (e.g., stdafx.h)." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED - BRIEF_DOCS "Define strategy for setting up unity target's link libraries." - FULL_DOCS - "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually." - "If this property is set to COPY, the unity target's link libraries will be copied from this target." - "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." - "Inherited from directory." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE__UNITY_SOURCE" - BRIEF_DOCS "Read-only property. The generated unity source file(s)." - FULL_DOCS - "cotire sets this property to the path of the generated single computation unit source file for the target." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE__PREFIX_HEADER" - BRIEF_DOCS "Read-only property. The generated prefix header file." - FULL_DOCS - "cotire sets this property to the full path of the generated language prefix header for the target." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE__PRECOMPILED_HEADER" - BRIEF_DOCS "Read-only property. The generated precompiled header file." - FULL_DOCS - "cotire sets this property to the full path of the generated language precompiled header binary for the target." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME" - BRIEF_DOCS "The name of the generated unity build target corresponding to this target." - FULL_DOCS - "This property can be set to the desired name of the unity target that will be created by cotire." - "If not set, the unity target name will be set to this target's name with the suffix _unity appended." - "After this target has been processed by cotire, the property is set to the actual name of the generated unity target." - "Defaults to empty string." - ) - - # define cotire source properties - - define_property( - SOURCE PROPERTY "COTIRE_EXCLUDED" - BRIEF_DOCS "Do not modify source file's build command." - FULL_DOCS - "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header." - "The source file will also be excluded from the generated unity source file." - "Source files that have their COMPILE_FLAGS property set will be excluded by default." - "Defaults to FALSE." - ) - - define_property( - SOURCE PROPERTY "COTIRE_DEPENDENCY" - BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file." - FULL_DOCS - "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file." - "If the file is modified, cotire will re-generate the prefix header source upon build." - "Defaults to FALSE." - ) - - define_property( - SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file before this file is included." - "Defaults to empty string." - ) - - define_property( - SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file after this file is included." - "Defaults to empty string." - ) - - define_property( - SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE" - BRIEF_DOCS "Start a new unity source file which includes this source file as the first one." - FULL_DOCS - "If this property is set to TRUE, cotire will complete the current unity file and start a new one." - "The new unity source file will include this source file as the first one." - "This property essentially works as a separator for unity source files." - "Defaults to FALSE." - ) - - define_property( - SOURCE PROPERTY "COTIRE_TARGET" - BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target." - FULL_DOCS - "cotire sets this property to the name of target, that the source file's build command has been altered for." - "Defaults to empty string." - ) - - message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") - -endif() diff --git a/source/build-cmake/cmake/toolchain_win32_cross_linux_llvm.cmake b/source/build-cmake/cmake/toolchain_win32_cross_linux_llvm.cmake deleted file mode 100644 index 58cc5bc12..000000000 --- a/source/build-cmake/cmake/toolchain_win32_cross_linux_llvm.cmake +++ /dev/null @@ -1,65 +0,0 @@ -# the name of the target operating system -SET(CMAKE_SYSTEM_NAME Windows) - -# which compilers to use for C and C++ -SET(CMAKE_SYSTEM_NAME Windows) -SET(CMAKE_C_COMPILER i686-w64-mingw32-clang) -SET(CMAKE_CXX_COMPILER i686-w64-mingw32-clang++) -SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) -SET(CMAKE_AR llvm-ar) -SET(CMAKE_LD llvm-link) -SET(CMAKE_LINKSE /usr/bin/i686-w64-mingw32-ld) -SET(CMAKE_NM llvm-nm) - -set(CMAKE_CXX_FLAGS "-target i686-w64-mingw32") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/lib/clang/3.9.0/include") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include/../../../usr/lib/gcc/i686-w64-mingw32/8.2-win32/include/c++") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include/../../../usr/lib/gcc/i686-w64-mingw32/8.2-win32/include/c++/i686-w64-mingw32") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include") - -set(CMAKE_EXE_LINKER_FLAGS "-L/usr/lib/gcc/i686-w64-mingw32/8.2-win32 -target i686-w64-mingw32 ") -#set(CMAKE_EXE_LINKER_FLAGS "") - -set(LIBAV_ROOT_DIR "/usr/local/i586-mingw-msvc/ffmpeg-4.1") - - -# here is the target environment located -set(USE_SDL2 ON) -if(USE_SDL2) - SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 - /usr/local/i586-mingw-msvc - /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32 - /usr/local/i586-mingw-msvc/5.12/mingw_82x - ) -else() - SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 - /usr/local/i586-mingw-msvc - /usr/local/i586-mingw-msvc/SDL1/ - /usr/local/i586-mingw-msvc/5.12/mingw_82x - ) -endif() -SET(CSP_CROSS_BUILD 1) - -# adjust the default behaviour of the FIND_XXX() commands: -# search headers and libraries in the target environment, search -# programs in the host environment -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - - -set(SDL2_LIBRARIES - /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/lib/libSDL2.dll.a - /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/lib/libSDL2main.a) -set(SDL2_INCLUDE_DIRS /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/include/SDL2) - -set(SDL_LIBRARIES - /usr/local/i586-mingw-msvc/SDL1/lib/libSDL.dll.a - /usr/local/i586-mingw-msvc/SDL1/lib/libSDLmain.a) -set(SDL_INCLUDE_DIRS /usr/local/i586-mingw-msvc/SDL1/include/SDL) - -set(SDLMAIN_LIBRARY "") - -set(ADDITIONAL_LIBRARIES libwinmm.a) - diff --git a/source/build-cmake/colecovision/CMakeLists.txt b/source/build-cmake/colecovision/CMakeLists.txt deleted file mode 100644 index fb041669a..000000000 --- a/source/build-cmake/colecovision/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,COLECO Vision, Qt **") -message("") - - -project (colecovision) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - - -set(VM_NAME colecovision) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES - io.cpp - event.cpp -) - -set(VMFILES_LIB - tms9918a.cpp - sn76489an.cpp -) -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_COLECOVISION) -set(EXEC_TARGET emucolecovision) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/colecovision.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/config_build.sh b/source/build-cmake/config_build.sh deleted file mode 100755 index f56fa85dc..000000000 --- a/source/build-cmake/config_build.sh +++ /dev/null @@ -1,266 +0,0 @@ -#!/bin/bash - -CMAKE=/usr/bin/cmake -CCMAKE_CC=gcc-6 -CCMAKE_CXX=g++-6 -LLVM_VERSION=7 -LIB_INSTALL="/usr/local/lib/x86_64-linux-gnu/" -MAKE_STATUS_FILE="./000_make_status_config_build.log" -AFFINITY_MAKE="make" - -BUILD_TYPE="Relwithdebinfo" - -#MAJOR_ARCH="IA32" -MAJOR_ARCH="AMD64" -#MAJOR_ARCH="ARM32" -#MAJOR_ARCH="ARM64" - -CMAKE_APPENDFLAG="" - -echo "Make status." > ${MAKE_STATUS_FILE} -echo "Started at `date --rfc-2822`:" >> ${MAKE_STATUS_FILE} - -if [ -e ./buildvars.dat ] ; then - . ./buildvars.dat -else - echo "WARN: Config file does not exist." >> ${MAKE_STATUS_FILE} - echo "WARN: Read configs from templete." >> ${MAKE_STATUS_FILE} - . ./buildvars.dat.tmpl -fi - -#Check if LD_LIBRARY_PATH includes in LIB_INSTALL - -typeset -i __res -__res=0; -nr_list=`/bin/ls /etc/ld.so.conf.d/*.conf` -__DIR=`echo ${LIB_INSTALL} | sed 's/\/$//'` -echo ${__DIR} -for __FILE in ${nr_list} ; do \ - if [ -z `echo ${__FILE} | grep "zz_"` ] ; then - _t=`grep -e ${__DIR} ${__FILE}` - if grep -e ${__DIR} ${__FILE} > /dev/null ; then - __res=1 - fi - fi -done - -if [ ${__res} -eq 0 ] ; then - if [ -z `printenv LD_LIBRARY_PATH | grep ${LIB_INSTALL}` ] ; then - echo 'WARN: NO ${LIB_INSTALL} exists $LD_LIBRARY_PATH' >> ${MAKE_STATUS_FILE} - __res=0 - else - __res=1 - fi -fi - -if [ ${__res} -eq 0 ] ; then - echo "FALLBACK ${LIB_INSTALL} to /usr/local/lib ." >> ${MAKE_STATUS_FILE} - LIB_INSTALL="/usr/local/lib" -fi - -case ${BUILD_TOOLCHAIN} in - "LLVM" | "llvm" | "CLANG" | "clang" ) - #TOOLCHAIN_SCRIPT="../../cmake/toolchain_win32_cross_linux_llvm.cmake" - . ./params/buildvars_linux_params_llvm.dat - echo "Setup for LLVM" - ;; - "GCC" | "gcc" | "GNU" ) - #TOOLCHAIN_SCRIPT="../../cmake/toolchain_mingw_cross_linux.cmake" - . ./params/buildvars_linux_params_gcc.dat - echo "Setup for GCC" - ;; - * ) - #TOOLCHAIN_SCRIPT="../../cmake/toolchain_mingw_cross_linux.cmake" - . ./params/buildvars_linux_params_gcc.dat - echo "ASSUME GCC" - ;; -esac - -case ${STRIP_SYMBOLS} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE2="-s ${MAKEFLAGS_BASE2}" - MAKEFLAGS_LINK_BASE="-s ${MAKEFLAGS_LINK_BASE2}" - MAKEFLAGS_DLL_LINK_BASE="-s ${MAKEFLAGS_DLL_LINK_BASE}" - MAKEFLAGS_DLL_BASE="-s ${MAKEFLAGS_DLL_BASE}" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2}" - MAKEFLAGS_LINK_BASE="${MAKEFLAGS_LINK_BASE2}" - MAKEFLAGS_DLL_LINK_BASE="${MAKEFLAGS_DLL_LINK_BASE}" - MAKEFLAGS_DLL_BASE="${MAKEFLAGS_DLL_BASE}" - ;; -esac -################# -# -# -MAKEFLAGS_CXX="${MAKEFLAGS_BASE2}" -MAKEFLAGS_CC="${MAKEFLAGS_BASE2}" -MAKEFLAGS_LIB_CXX="${MAKEFLAGS_DLL_BASE}" -MAKEFLAGS_LIB_CC="${MAKEFLAGS_DLL_BASE}" - -################### -# -# -if [ -n "${FFMPEG_DIR}" ]; then \ - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DLIBAV_ROOT_DIR=${FFMPEG_DIR}" -fi -if [ -n "${QT5_DIR}" ]; then \ - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DQT5_ROOT_PATH=${QT5_DIR}" -fi - -################################# -# -# -function build_dll() { - # $1 = dir - mkdir -p $1/build - cd $1/build - echo ${CMAKE_FLAGS1} ${CMAKE_FLAGS2} - ${CMAKE} -DCMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -DCMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - -DCOTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES=1 \ - -DCOTIRE_ADD_CLEAN=0 \ - "-DLIBCSP_INSTALL_DIR:STRING=${LIB_INSTALL}" \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_LIB_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_LIB_CC}" \ - "${CMAKE_FLAGS4}" \ - ${CMAKE_APPENDFLAG} \ - .. | tee make.log - - ${CMAKE} -DCMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -DCMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - -DCOTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES=1 \ - -DCOTIRE_ADD_CLEAN=0 \ - "-DLIBCSP_INSTALL_DIR:STRING=${LIB_INSTALL}" \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_LIB_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_LIB_CC}" \ - "${CMAKE_FLAGS4}" \ - ${CMAKE_APPENDFLAG} \ - .. | tee -a make.log - - make clean - ${AFFINITY_MAKE} ${MAKEFLAGS_GENERAL} 2>&1 | tee -a ./make.log - _STATUS=${PIPESTATUS[0]} - echo -e "$1 at `date --rfc-2822`:" "${_STATUS}" >> ../../${MAKE_STATUS_FILE} - case ${_STATUS} in - 0 ) sudo make install 2>&1 | tee -a ./make.log ;; - * ) - echo -e "Abort at `date --rfc-2822`." >> ../../${MAKE_STATUS_FILE} - exit ${_STATUS} - ;; - esac - - make clean - cd ../.. -} - -case ${BUILD_TYPE} in - "Debug" | "DEBUG" | "debug" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=debug" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_DEBUG:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_DEBUG:STRING" - ;; - "Release" | "RELEASE" | "release" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=Release" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_RELEASE:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_RELEASE:STRING" - ;; - "Relwithdebinfo" | "RELWITHDEBINFO" | "relwithdebinfo" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=Relwithdebinfo" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING" - ;; - * ) - echo "Specify BUILD_TYPE in buildvars.dat to Debug, Release, Relwithdebinfo." - exit -1 - ;; -esac - -# libCSPGui -case ${USE_COMMON_DEVICE_LIB} in - "Yes" | "yes" | "YES" ) - CMAKE_FLAGS4="-DUSE_DEVICES_SHARED_LIB=ON" - build_dll libCSPcommon_vm - ;; - * ) - CMAKE_FLAGS4="" - ;; -esac - -case ${USE_COMMON_DEVICE_LIB} in - "Yes" | "yes" | "YES" ) - build_dll libCSPfmgen - build_dll libCSPavio - build_dll libCSPgui - build_dll libCSPosd - build_dll libCSPemu_utils - ;; - "No" | "no" | "NO" | * ) - build_dll libCSPavio - build_dll libCSPgui - build_dll libCSPosd - ;; -esac - -typeset -i SUCCESS_COUNT -SUCCESS_COUNT=0 - -typeset -i FAIL_COUNT -FAIL_COUNT=0 - -for SRCDATA in $@ ; do\ - - mkdir -p ${SRCDATA}/build - cd ${SRCDATA}/build - - echo ${CMAKE_FLAGS1} ${CMAKE_FLAGS2} - ${CMAKE} -D CMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -D CMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - -DCOTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES=1 \ - -DCOTIRE_ADD_CLEAN=0 \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_CC}" \ - "${CMAKE_FLAGS4}" \ - ${CMAKE_APPENDFLAG} \ - "-DCMAKE_EXE_LINKER_FLAGS:STRING=${MAKEFLAGS_LINK_BASE}" \ - .. | tee make.log - ${CMAKE} -D CMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -D CMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_CC}" \ - "${CMAKE_FLAGS4}" \ - ${CMAKE_APPENDFLAG} \ - "-DCMAKE_EXE_LINKER_FLAGS:STRING=${MAKEFLAGS_LINK_BASE}" \ - .. | tee -a make.log - - - make clean - - ${AFFINITY_MAKE} ${MAKEFLAGS_GENERAL} 2>&1 | tee -a ./make.log - _STATUS=${PIPESTATUS[0]} - echo -e "${SRCDATA} at `date --rfc-2822`:" "${_STATUS}" >> ../../${MAKE_STATUS_FILE} - - case ${_STATUS} in - 0 ) - SUCCESSS_COUNT=$((++SUCCESS_COUNT)) - sudo make install 2>&1 | tee -a ./make.log - ;; - * ) - FAIL_COUNT=$((++FAIL_COUNT)) - echo -e "Abort at `date --rfc-2822`." >> ../../${MAKE_STATUS_FILE} - #exit ${_STATUS} - ;; - esac - - make clean - cd ../.. -done -echo -e "VM BUILD:Successed ${SUCCESS_COUNT} / Failed ${FAIL_COUNT}" >> ./${MAKE_STATUS_FILE} -echo -e "End at `date --rfc-2822`." >> ./${MAKE_STATUS_FILE} - -exit 0 - diff --git a/source/build-cmake/config_build_cross_win32.sh b/source/build-cmake/config_build_cross_win32.sh deleted file mode 100755 index 261998d1d..000000000 --- a/source/build-cmake/config_build_cross_win32.sh +++ /dev/null @@ -1,254 +0,0 @@ -#!/bin/bash - -CMAKE=/usr/bin/cmake - -MAJOR_ARCH="IA32" -#MAJOR_ARCH="AMD64" -#MAJOR_ARCH="ARM32" -#MAJOR_ARCH="ARM64" - -BUILD_TYPE="Relwithdebinfo" -CMAKE_APPENDFLAG="" -export WINEDEBUG="-all" -CMAKE_LINKFLAG="" -CMAKE_APPENDFLAG="" -MAKEFLAGS_GENERAL="-j4" -MAKE_STATUS_FILE="./000_make_status_config_build_cross_win32.log" -AFFINITY_MAKE="make" -export WCLANG_FORCE_CXX_EXCEPTIONS=1 - -mkdir -p ./bin-win32/ - -echo "Make status." > ${MAKE_STATUS_FILE} -echo "Started at `date --rfc-2822`:" >> ${MAKE_STATUS_FILE} -if [ -e ./buildvars_mingw_cross_win32.dat ] ; then - . ./buildvars_mingw_cross_win32.dat -else - echo "WARN: Config file does not exist." >> ${MAKE_STATUS_FILE} - echo "WARN: Read configs from templete." >> ${MAKE_STATUS_FILE} - . ./buildvars_mingw_cross_win32.dat.tmpl -fi - -case ${BUILD_TOOLCHAIN} in - "LLVM" | "llvm" | "CLANG" | "clang" ) - TOOLCHAIN_SCRIPT="../../cmake/toolchain_win32_cross_linux_llvm.cmake" - . ./params/buildvars_mingw_params_llvm.dat - echo "Setup for LLVM" - ;; - "GCC" | "gcc" | "GNU" ) - TOOLCHAIN_SCRIPT="../../cmake/toolchain_mingw_cross_linux.cmake" - . ./params/buildvars_mingw_params_gcc.dat - echo "Setup for GCC" - ;; - * ) - TOOLCHAIN_SCRIPT="../../cmake/toolchain_mingw_cross_linux.cmake" - . ./params/buildvars_mingw_params_gcc.dat - echo "ASSUME GCC" - ;; -esac - -CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DLIBAV_ROOT_DIR=${FFMPEG_DIR}" - - -########################### -# -# -MAKEFLAGS_CXX="${MAKEFLAGS_BASE2} " -MAKEFLAGS_CC="${MAKEFLAGS_BASE2}" -MAKEFLAGS_LIB_CXX="${ADDITIONAL_MAKEFLAGS_LINK_LIB} ${MAKEFLAGS_BASE2}" -MAKEFLAGS_LIB_CC="${ADDITIONAL_MAKEFLAGS_LINK_LIB} ${MAKEFLAGS_BASE2}" - -CMAKE_LINKFLAG="${ADDITIONAL_MAKEFLAGS_LINK_EXE} ${MAKEFLAGS_LINK_BASE}" -CMAKE_DLL_LINKFLAG="${ADDITIONAL_MAKEFLAGS_LINK_DLL} ${MAKEFLAGS_LINK_BASE}" - -# To use MOC, please enable wine as interpreter of EXEs , below: -# $ sudo update-binfmts --install Win32_Wine /usr/bin/wine --extension exe . -# Compatible with GCC-4.9 (-fabi-version=8) -MAKEFLAGS_CXX="${MAKEFLAGS_CXX} -DWINVER=0x501" -MAKEFLAGS_CC="${MAKEFLAGS_CC} -DWINVER=0x501" - -MAKEFLAGS_LIB_CXX="${MAKEFLAGS_LIB_CXX} -DWINVER=0x501" -MAKEFLAGS_LIB_CC="${MAKEFLAGS_LIB_CC} -DWINVER=0x501" - -function build_dll() { - mkdir -p $1/build-win32 - cd $1/build-win32 - echo ${CMAKE_FLAGS1} ${CMAKE_FLAGS2} - ${CMAKE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_SCRIPT} \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_LIB_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_LIB_CC}" \ - "${CMAKE_FLAGS4}" \ - "-DUSE_SDL2=ON" \ - ${CMAKE_APPENDFLAG} \ - "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_LINKFLAG}" \ - "-DCMAKE_CROSSCOMPILING=true"\ - .. | tee make.log - - ${CMAKE} ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_LIB_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_LIB_CC}" \ - "${CMAKE_FLAGS4}" \ - "-DUSE_SDL2=ON" \ - ${CMAKE_APPENDFLAG} \ - "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_LINKFLAG}" \ - .. | tee -a make.log - - make clean - - ${AFFINITY_MAKE} ${MAKEFLAGS_GENERAL} 2>&1 | tee -a ./make.log - _STATUS=${PIPESTATUS[0]} - echo -e "$1 at `date --rfc-2822`:" "${_STATUS}" >> ../../${MAKE_STATUS_FILE} - case ${_STATUS} in - 0 ) - ;; - * ) - echo -e "Abort at `date --rfc-2822`." >> ../../${MAKE_STATUS_FILE} - exit ${_STATUS} - ;; - esac - cd ../../ -} - -case ${BUILD_TYPE} in - "Debug" | "DEBUG" | "debug" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=debug" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_DEBUG:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_DEBUG:STRING" - ;; - "Release" | "RELEASE" | "release" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=Release" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_RELEASE:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_RELEASE:STRING" - ;; - "Relwithdebinfo" | "RELWITHDEBINFO" | "relwithdebinfo" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=Relwithdebinfo" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING" - ;; - * ) - echo "Specify BUILD_TYPE in buildvars.dat to Debug, Release, Relwithdebinfo." - exit -1 - ;; -esac - -# libCSPGui -case ${USE_COMMON_DEVICE_LIB} in - "Yes" | "yes" | "YES" ) - CMAKE_FLAGS4="-DUSE_DEVICES_SHARED_LIB=ON" - ;; - * ) - CMAKE_FLAGS4="" - ;; -esac - -build_dll libCSPemu_utils -echo $PWD -cp ./libCSPemu_utils/build-win32/qt/emuutils/*.h ./bin-win32/ -cp ./libCSPemu_utils/build-win32/qt/emuutils/*.dll ./bin-win32/ -cp ./libCSPemu_utils/build-win32/qt/emuutils/*.a ./bin-win32/ - -build_dll libCSPfmgen -cp ./libCSPfmgen/build-win32/vm/fmgen/*.h ./bin-win32/ -cp ./libCSPfmgen/build-win32/vm/fmgen/*.dll ./bin-win32/ -cp ./libCSPfmgen/build-win32/vm/fmgen/*.a ./bin-win32/ - - -build_dll libCSPosd -cp ./libCSPosd/build-win32/qt/osd/*.h ./bin-win32/ -cp ./libCSPosd/build-win32/qt/osd/*.dll ./bin-win32/ -cp ./libCSPosd/build-win32/qt/osd/*.a ./bin-win32/ - -build_dll libCSPavio -cp ./libCSPavio/build-win32/qt/avio/*.h ./bin-win32/ -cp ./libCSPavio/build-win32/qt/avio/*.dll ./bin-win32/ -cp ./libCSPavio/build-win32/qt/avio/*.a ./bin-win32/ - - -case ${USE_COMMON_DEVICE_LIB} in - "Yes" | "yes" | "YES" ) - build_dll libCSPcommon_vm - cp ./libCSPcommon_vm/build-win32/vm/common_vm/*.h ./bin-win32/ - cp ./libCSPcommon_vm/build-win32/vm/common_vm/*.dll ./bin-win32/ - cp ./libCSPcommon_vm/build-win32/vm/common_vm/*.a ./bin-win32/ - ;; - * ) - ;; -esac - -build_dll libCSPgui -cp ./libCSPgui/build-win32/qt/gui/*.h ./bin-win32/ -cp ./libCSPgui/build-win32/qt/gui/*.dll ./bin-win32/ -cp ./libCSPgui/build-win32/qt/gui/*.a ./bin-win32/ - -#build_dll libCSPosd -#cp ./libCSPosd/build-win32/qt/osd/*.h ./bin-win32/ -#cp ./libCSPosd/build-win32/qt/osd/*.dll ./bin-win32/ -#cp ./libCSPosd/build-win32/qt/osd/*.a ./bin-win32/ - -typeset -i SUCCESS_COUNT -SUCCESS_COUNT=0 - -typeset -i FAIL_COUNT -FAIL_COUNT=0 - -for SRCDATA in $@ ; do\ - - mkdir -p ${SRCDATA}/build-win32 - cd ${SRCDATA}/build-win32 - - echo ${CMAKE_FLAGS1} ${CMAKE_FLAGS2} - ${CMAKE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_SCRIPT} \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_CC}" \ - "${CMAKE_FLAGS4}" \ - "-DUSE_SDL2=ON" \ - "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_LINKFLAG}" \ - ${CMAKE_APPENDFLAG} \ - .. | tee make.log - - ${CMAKE} ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_CC}" \ - "${CMAKE_FLAGS4}" \ - "-DUSE_SDL2=ON" \ - "-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_LINKFLAG}" \ - ${CMAKE_APPENDFLAG} \ - .. | tee -a make.log - - make clean - - ${AFFINITY_MAKE} ${MAKEFLAGS_GENERAL} 2>&1 | tee -a ./make.log - _STATUS=${PIPESTATUS[0]} - echo -e "${SRCDATA} at `date --rfc-2822`:" "${_STATUS}" >> ../../${MAKE_STATUS_FILE} - case ${_STATUS} in - 0 ) - SUCCESSS_COUNT=$((++SUCCESS_COUNT)) - cp ./qt/common/*.exe ../../bin-win32/ - ;; - * ) - FAIL_COUNT=$((++FAIL_COUNT)) - echo -e "Abort at `date --rfc-2822`." >> ../../${MAKE_STATUS_FILE} - #exit ${_STATUS} - ;; - esac - - make clean - cd ../.. -done - -echo -e "End at `date --rfc-2822`." >> ../../${MAKE_STATUS_FILE} - -for ii in libCSPavio libCSPgui libCSPosd libCSPemu_utils; do - cd $ii/build-win32 - make clean - cd ../.. -done - -echo -e "VM BUILD:Successed ${SUCCESS_COUNT} / Failed ${FAIL_COUNT}" >> ./${MAKE_STATUS_FILE} -echo -e "End at `date --rfc-2822`." >> ./${MAKE_STATUS_FILE} - - -exit 0 - diff --git a/source/build-cmake/config_build_mingw.sh b/source/build-cmake/config_build_mingw.sh deleted file mode 100755 index b87771215..000000000 --- a/source/build-cmake/config_build_mingw.sh +++ /dev/null @@ -1,163 +0,0 @@ -#!/bin/bash - -CMAKE=cmake -CCMAKE_CC=gcc -CCMAKE_CXX=g++ - -MAKEFLAGS_CXX="-g -O2 -DNDEBUG" -MAKEFLAGS_CC="-g -O2 -DNDEBUG" -BUILD_TYPE="Relwithdebinfo" - -CMAKE_LINKFLAG="" -#CMAKE_GENTYPE="\"MinGW Makefiles\"" -#CMAKE_APPENDFLAG="" -CMAKE_GENTYPE="\"MSYS Makefiles\"" -CMAKE_GENFLAGS="-DCMAKE_MAKE_PROGRAM=mingw32-make" -mkdir -p ./bin-win32/ - -echo "Make status." > ${MAKE_STATUS_FILE} -echo "Started at `date --rfc-2822`:" >> ${MAKE_STATUS_FILE} -if [ -e ./buildvars_mingw.dat ] ; then - . ./buildvars_mingw.dat -else - echo "WARN: Config file does not exist." >> ${MAKE_STATUS_FILE} - echo "WARN: Read configs from templete." >> ${MAKE_STATUS_FILE} - . ./buildvars_mingw.dat.tmpl -fi - - -MAKEFLAGS_CXX="${MAKEFLAGS_CXX} -DWINVER=0x501" -MAKEFLAGS_CC="${MAKEFLAGS_CC} -DWINVER=0x501" -MAKEFLAGS_LIB_CXX="${MAKEFLAGS_LIB_CXX} -DWINVER=0x501" -MAKEFLAGS_LIB_CC="${MAKEFLAGS_LIB_CC} -DWINVER=0x501" - -function build_dll() { - mkdir -p $1/build-win32 - cd $1/build-win32 - echo ${CMAKE_FLAGS1} ${CMAKE_FLAGS2} - ${CMAKE} -G "${CMAKE_GENTYPE}" \ - ${CMAKE_GENFLAGS} \ - -D CMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -D CMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_LIB_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_LIB_CC}" \ - ${CMAKE_APPENDFLAG} \ - ${CMAKE_LINKFLAG} \ - .. | tee make.log - - ${CMAKE} -D CMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -D CMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_LIB_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_LIB_CC}" \ - ${CMAKE_APPENDFLAG} \ - ${CMAKE_LINKFLAG} \ - .. | tee -a make.log - - mingw32-make clean - mingw32-make ${MAKEFLAGS_GENERAL} 2>&1 | tee -a ./make.log - - case $? in - 0 ) - # cp ./qt/gui/libqt_gui.a ../../bin-win32/ - # cp ./qt/gui/*.lib ../../bin-win32/ - # cp ./qt/gui/*.dll ../../bin-win32/ - ;; - * ) exit $? ;; - esac - #mingw32-make clean - cd ../.. -} - -case ${BUILD_TYPE} in - "Debug" | "DEBUG" | "debug" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=debug" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_DEBUG:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_DEBUG:STRING" - ;; - "Release" | "RELEASE" | "release" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=Release" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_RELEASE:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_RELEASE:STRING" - ;; - "Relwithdebinfo" | "RELWITHDEBINFO" | "relwithdebinfo" ) - CMAKE_FLAGS1="-DCMAKE_BUILD_TYPE:STRING=Relwithdebinfo" - CMAKE_FLAGS2="-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING" - CMAKE_FLAGS3="-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING" - ;; - * ) - echo "Specify BUILD_TYPE in buildvars.dat to Debug, Release, Relwithdebinfo." - exit -1 - ;; -esac - -# libCSPGui -build_dll libCSPavio -build_dll libCSPgui -build_dll libCSPosd -build_dll libCSPemu_utils - -typeset -i SUCCESS_COUNT -SUCCESS_COUNT=0 - -typeset -i FAIL_COUNT -FAIL_COUNT=0 - -for SRCDATA in $@ ; do\ - - mkdir -p ${SRCDATA}/build - cd ${SRCDATA}/build - - echo ${CMAKE_FLAGS1} ${CMAKE_FLAGS2} - ${CMAKE} -G "${CMAKE_GENTYPE}" \ - ${CMAKE_GENFLAGS} \ - -D CMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -D CMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_CC}" \ - ${CMAKE_APPENDFLAG} \ - ${CMAKE_LINKFLAG} \ - .. | tee make.log - - ${CMAKE} -D CMAKE_C_COMPILER:STRING=${CCMAKE_CC} \ - -D CMAKE_CXX_COMPILER:STRING=${CCMAKE_CXX} \ - ${CMAKE_FLAGS1} \ - "${CMAKE_FLAGS2}=${MAKEFLAGS_CXX}" \ - "${CMAKE_FLAGS3}=${MAKEFLAGS_CC}" \ - ${CMAKE_APPENDFLAG} \ - ${CMAKE_LINKFLAG} \ - .. | tee -a make.log - - mingw32-make clean - - mingw32-make ${MAKEFLAGS_GENERAL} 2>&1 | tee -a ./make.log - case $? in - 0 ) - SUCCESSS_COUNT=$((++SUCCESS_COUNT)) - cp ./qt/common/*.exe ../../bin-win32/ - ;; -# 0 ) sudo make install 2>&1 | tee -a ./make.log ;; - * ) - FAIL_COUNT=$((++FAIL_COUNT)) - echo -e "Abort at `date --rfc-2822`." >> ../../${MAKE_STATUS_FILE} - #exit $? - ;; - esac - - mingw32-make clean - cd ../.. -done - -for ii in libCSPavio libCSPgui libCSPosd libCSPemu_utils; do - cd $ii/build-win32 - make clean - cd ../.. -done - -echo -e "VM BUILD:Successed ${SUCCESS_COUNT} / Failed ${FAIL_COUNT}" >> ./${MAKE_STATUS_FILE} -echo -e "End at `date --rfc-2822`." >> ./${MAKE_STATUS_FILE} - -exit 0 - diff --git a/source/build-cmake/ex80/CMakeLists.txt b/source/build-cmake/ex80/CMakeLists.txt deleted file mode 100644 index 1eec51a48..000000000 --- a/source/build-cmake/ex80/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,EX80, Qt **") -message("") - -project (emuex80) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - -set(EXEC_TARGET emuex80) -set(VM_NAME ex80) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES_BASE - i8080.cpp - io.cpp - event.cpp -) - -set(VMFILES_LIB - i8080_base.cpp - i8251.cpp - i8255.cpp - pcm1bit.cpp -) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_EX80) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/ex80.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/familybasic/CMakeLists.txt b/source/build-cmake/familybasic/CMakeLists.txt deleted file mode 100644 index 369199b78..000000000 --- a/source/build-cmake/familybasic/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,EPSON HC 80, Qt **") -message("") - -project (emufamilybasic) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - -set(EXEC_TARGET emufamilybasic) -set(VM_NAME familybasic) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES_BASE - n2a03.cpp - event.cpp -) - -set(VMFILES_LIB - m6502_base.cpp - noise.cpp - datarec.cpp - ym2413.cpp -) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER OFF CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_FAMILYBASIC) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/familybasic.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/fm16beta_286/CMakeLists.txt b/source/build-cmake/fm16beta_286/CMakeLists.txt deleted file mode 100644 index 54723652d..000000000 --- a/source/build-cmake/fm16beta_286/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FM16β(i286), Qt **") -message("") - - - -project (emufm16beta_286) -set(CMAKE_MODULE_PATH "${emufm16beta_286_SOURCE_DIR}/../cmake") - - -set(EXEC_TARGET emufm16beta_266) -set(VM_NAME fm16beta_286) -set(BUILD_FM16BETA_286 ON CACHE BOOL "Build for FM16Beta, i86 version") - -include(config_emufm16beta) -include(config_commonsource) diff --git a/source/build-cmake/fm16beta_86/CMakeLists.txt b/source/build-cmake/fm16beta_86/CMakeLists.txt deleted file mode 100644 index f8c24f3a9..000000000 --- a/source/build-cmake/fm16beta_86/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FM16β(i86), Qt **") -message("") - - - -project (emufm16beta_86) -set(CMAKE_MODULE_PATH "${emufm16beta_86_SOURCE_DIR}/../cmake") - - -set(EXEC_TARGET emufm16beta_86) -set(VM_NAME fm16beta_86) -set(BUILD_FM16BETA_86 ON CACHE BOOL "Build for FM16Beta, i86 version") - -include(config_emufm16beta) -include(config_commonsource) diff --git a/source/build-cmake/fm16pi/CMakeLists.txt b/source/build-cmake/fm16pi/CMakeLists.txt deleted file mode 100644 index 0df6d22c0..000000000 --- a/source/build-cmake/fm16pi/CMakeLists.txt +++ /dev/null @@ -1,62 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FM16π, Qt **") -message("") - - - -project (emufm16pi) -set(CMAKE_MODULE_PATH "${emufm16pi_SOURCE_DIR}/../cmake") - - -set(EXEC_TARGET emufm16pi) -set(VM_NAME fm16pi) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES - msm58321.cpp - event.cpp - io.cpp - memory.cpp -) - -set(VMFILES_LIB -# datarec.cpp - disk.cpp - i8251.cpp - i8253.cpp - i8255.cpp - i8259.cpp - mb8877.cpp - msm58321_base.cpp - noise.cpp - not.cpp - pcm1bit.cpp - ym2203.cpp -) - -#set(FLAG_USE_I86 ON) -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) -add_definitions(-D_FM16PI) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fm16pi.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/fm7/CMakeLists.txt b/source/build-cmake/fm7/CMakeLists.txt deleted file mode 100644 index 876f7378c..000000000 --- a/source/build-cmake/fm7/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - - -project (emufm7) -set(CMAKE_MODULE_PATH "${emufm7_SOURCE_DIR}/../cmake") - -set(BUILD_FM7 ON CACHE BOOL "Build for FM7") - -include(config_emufm7) -include(config_commonsource) - diff --git a/source/build-cmake/fm77/CMakeLists.txt b/source/build-cmake/fm77/CMakeLists.txt deleted file mode 100644 index 22d13a100..000000000 --- a/source/build-cmake/fm77/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -project (emufm77) -set(CMAKE_MODULE_PATH "${emufm77_SOURCE_DIR}/../cmake") -set(BUILD_FM77 ON CACHE BOOL "Build for FM77") - -include(config_emufm7) -include(config_commonsource) diff --git a/source/build-cmake/fm77av/CMakeLists.txt b/source/build-cmake/fm77av/CMakeLists.txt deleted file mode 100644 index 48431d37f..000000000 --- a/source/build-cmake/fm77av/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ - -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emufm77av) - -set(CMAKE_MODULE_PATH "${emufm77av_SOURCE_DIR}/../cmake") -set(BUILD_FM77AV ON CACHE BOOL "Build for FM77AV") - -include(config_emufm7) -include(config_commonsource) diff --git a/source/build-cmake/fm77av40/CMakeLists.txt b/source/build-cmake/fm77av40/CMakeLists.txt deleted file mode 100644 index 07ada4240..000000000 --- a/source/build-cmake/fm77av40/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -project (emufm77av40) - - -set(CMAKE_MODULE_PATH "${emufm77av40_SOURCE_DIR}/../cmake") -set(BUILD_FM77AV40 ON CACHE BOOL "Build for FM77AV40") - -include(config_emufm7) -include(config_commonsource) diff --git a/source/build-cmake/fm77av40ex/CMakeLists.txt b/source/build-cmake/fm77av40ex/CMakeLists.txt deleted file mode 100644 index d95852087..000000000 --- a/source/build-cmake/fm77av40ex/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - - -project (emufm77av40ex) - -set(CMAKE_MODULE_PATH "${emufm77av40ex_SOURCE_DIR}/../cmake") -set(BUILD_FM77AV40EX ON CACHE BOOL "Build for FM77AV40EX") - -include(config_emufm7) -include(config_commonsource) diff --git a/source/build-cmake/fm77l4/CMakeLists.txt b/source/build-cmake/fm77l4/CMakeLists.txt deleted file mode 100644 index 465929f48..000000000 --- a/source/build-cmake/fm77l4/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - - -project (emufm77l4) - -set(CMAKE_MODULE_PATH "${emufm77l4_SOURCE_DIR}/../cmake") -set(BUILD_FM77L4 ON CACHE BOOL "Build for FM77L4") - -include(config_emufm7) -include(config_commonsource) diff --git a/source/build-cmake/fm8/CMakeLists.txt b/source/build-cmake/fm8/CMakeLists.txt deleted file mode 100644 index e175a9258..000000000 --- a/source/build-cmake/fm8/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emufm8) - -set(BUILD_FM8 ON CACHE BOOL "Build for FM-8") - -include(config_emufm7) -include(config_commonsource) - diff --git a/source/build-cmake/fmr250/CMakeLists.txt b/source/build-cmake/fmr250/CMakeLists.txt deleted file mode 100644 index 8a99eeeb3..000000000 --- a/source/build-cmake/fmr250/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR250, Qt **") -message("") - -project (emufmr250) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - -set(BUILD_FMR250 ON CACHE BOOL "Build for FM-R250") - -include(config_emufmr50) diff --git a/source/build-cmake/fmr280/CMakeLists.txt b/source/build-cmake/fmr280/CMakeLists.txt deleted file mode 100644 index 0b8179e47..000000000 --- a/source/build-cmake/fmr280/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR280, Qt **") -message("") - -project (emufmr280) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - -set(BUILD_FMR280 ON CACHE BOOL "Build for FM-R280") - -include(config_emufmr50) diff --git a/source/build-cmake/fmr30_i286/CMakeLists.txt b/source/build-cmake/fmr30_i286/CMakeLists.txt deleted file mode 100644 index c0a67cf11..000000000 --- a/source/build-cmake/fmr30_i286/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR 30, Qt **") -message("") - -project (emufmr30_i286) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - - -set(VM_NAME fmr30) -set(USE_FMGEN OFF) -set(VMFILES -# i286.cpp - i8237.cpp - fmr50/bios.cpp - - scsi_dev.cpp - scsi_host.cpp - scsi_hdd.cpp - - io.cpp - - event.cpp -) -set(VMFILES_LIB - disk.cpp - i8251.cpp - i8253.cpp - i8259.cpp - i8237_base.cpp - mb8877.cpp - noise.cpp - pcm1bit.cpp - sn76489an.cpp -# scsi_dev_base.cpp -# scsi_hdd.cpp -) - -set(BUILD_FMR30_86 OFF CACHE BOOL "Build for FM-R30, i86 version") -set(BUILD_FMR30_286 ON CACHE BOOL "Build for FM-R30, i286 version") -if(BUILD_FMR30_86) - set(EXEC_TARGET emufmr30_i86) -# set(FLAG_USE_I86 OFF) -# set(VMFILES ${VMFILES} -# i286.cpp -# ) - add_definitions(-DHAS_I86) -elseif(BUILD_FMR30_286) - set(EXEC_TARGET emufmr30_i286) -# set(FLAG_USE_I86 OFF) -# set(VMFILES ${VMFILES} -# i286.cpp -# ) - add_definitions(-DHAS_I286) -endif() - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) -add_definitions(-D_FMR30) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr30.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/fmr30_i86/CMakeLists.txt b/source/build-cmake/fmr30_i86/CMakeLists.txt deleted file mode 100644 index ffa915bdd..000000000 --- a/source/build-cmake/fmr30_i86/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR 30, Qt **") -message("") - - -project (emufmr30_i86) - -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") - -set(VM_NAME fmr30) -set(USE_FMGEN OFF) -set(VMFILES -# i286.cpp - i8237.cpp - fmr50/bios.cpp - - scsi_dev.cpp - scsi_host.cpp - scsi_hdd.cpp - - io.cpp - - event.cpp -) -set(VMFILES_LIB - disk.cpp - i8251.cpp - i8253.cpp - i8259.cpp - i8237_base.cpp - mb8877.cpp - noise.cpp - pcm1bit.cpp - sn76489an.cpp -# scsi_dev_base.cpp -# scsi_hdd.cpp - -) - -set(BUILD_FMR30_86 ON CACHE BOOL "Build for FM-R30, i86 version") -set(BUILD_FMR30_286 OFF CACHE BOOL "Build for FM-R30, i286 version") -if(BUILD_FMR30_86) - set(EXEC_TARGET emufmr30_i86) - set(FLAG_USE_I86 OFF) -# set(VMFILES ${VMFILES} -# i286.cpp -# ) - add_definitions(-DHAS_I86) -elseif(BUILD_FMR30_286) - set(EXEC_TARGET emufmr30_i286) -# set(FLAG_USE_I86 OFF) -# set(VMFILES ${VMFILES} -# i286.cpp -# ) - add_definitions(-DHAS_I286) -endif() - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) -add_definitions(-D_FMR30) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fmr30.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/fmr50_286/CMakeLists.txt b/source/build-cmake/fmr50_286/CMakeLists.txt deleted file mode 100644 index cb6c12b81..000000000 --- a/source/build-cmake/fmr50_286/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR50 (i286), Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emufmr50_286) - -set(BUILD_FMR50_286 ON CACHE BOOL "Build for FM-R50, i286 version") - -include(config_emufmr50) diff --git a/source/build-cmake/fmr50_386/CMakeLists.txt b/source/build-cmake/fmr50_386/CMakeLists.txt deleted file mode 100644 index 49565ac38..000000000 --- a/source/build-cmake/fmr50_386/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR50 (i386), Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emufmr50_386) - -set(BUILD_FMR50_386 ON CACHE BOOL "Build for FM-R50, i386 version") - -include(config_emufmr50) diff --git a/source/build-cmake/fmr50_486/CMakeLists.txt b/source/build-cmake/fmr50_486/CMakeLists.txt deleted file mode 100644 index d3bc431b9..000000000 --- a/source/build-cmake/fmr50_486/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR50 (i486), Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emufmr50_486) - -set(BUILD_FMR50_486 ON CACHE BOOL "Build for FM-R50, i486 version") - -include(config_emufmr50) diff --git a/source/build-cmake/fmr60/CMakeLists.txt b/source/build-cmake/fmr60/CMakeLists.txt deleted file mode 100644 index 3c0586983..000000000 --- a/source/build-cmake/fmr60/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR60, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emufmr60) - -set(BUILD_FMR60 ON CACHE BOOL "Build for FM-R60") - -include(config_emufmr50) diff --git a/source/build-cmake/fmr70/CMakeLists.txt b/source/build-cmake/fmr70/CMakeLists.txt deleted file mode 100644 index c671a6d95..000000000 --- a/source/build-cmake/fmr70/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR70, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emufmr70) - -set(BUILD_FMR70 ON CACHE BOOL "Build for FM-R70") - -include(config_emufmr50) diff --git a/source/build-cmake/fmr80/CMakeLists.txt b/source/build-cmake/fmr80/CMakeLists.txt deleted file mode 100644 index 7fbe458b7..000000000 --- a/source/build-cmake/fmr80/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FMR80, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emufmr80) - -set(BUILD_FMR80 ON CACHE BOOL "Build for FM-R80") - -include(config_emufmr50) diff --git a/source/build-cmake/fmtowns_2h/CMakeLists.txt b/source/build-cmake/fmtowns_2h/CMakeLists.txt deleted file mode 100644 index d66662eb2..000000000 --- a/source/build-cmake/fmtowns_2h/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - - -project (emufmtowns_2h) -set(CMAKE_MODULE_PATH "${emufmtowns_2h_SOURCE_DIR}/../cmake") - -set(BUILD_FMTOWNS_2H ON CACHE BOOL "Build for FM-Towns 2H") - -include(config_fmtowns) -#include(config_commonsource) - diff --git a/source/build-cmake/fp1100/CMakeLists.txt b/source/build-cmake/fp1100/CMakeLists.txt deleted file mode 100644 index ca9a7950f..000000000 --- a/source/build-cmake/fp1100/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FP1100, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emufp1100) -set(VM_NAME fp1100) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES - event.cpp - io.cpp - memory.cpp -) -set(VMFILES_LIB - beep.cpp - datarec.cpp - disk.cpp - hd46505.cpp - noise.cpp - upd7801.cpp - upd765a.cpp -# pcm1bit.cpp - ym2203.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with FP1100 debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - - set(EXEC_TARGET emufp1100) - add_definitions(-D_FP1100) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fp1100.qrc) - - -include(config_commonsource) diff --git a/source/build-cmake/fp200/CMakeLists.txt b/source/build-cmake/fp200/CMakeLists.txt deleted file mode 100644 index d33c776cc..000000000 --- a/source/build-cmake/fp200/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,FP200, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emufp200) -set(VM_NAME fp200) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) - -set(VMFILES - i8080.cpp - - memory.cpp - event.cpp -) -set(VMFILES_LIB - noise.cpp - datarec.cpp - i8080_base.cpp - rp5c01.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) -set(EXEC_TARGET emufp200) -add_definitions(-D_FP200) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/fp200.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/fsa1/CMakeLists.txt b/source/build-cmake/fsa1/CMakeLists.txt deleted file mode 100644 index b57a5e6b8..000000000 --- a/source/build-cmake/fsa1/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MSX2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emufsa1) -set(EXEC_TARGET emufsa1) -set(VM_NAME msx) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(BUILD_PX7 OFF CACHE BOOL "Build for Pioneer PX7") -set(BUILD_MSX1 OFF CACHE BOOL "Build for MSX1") -set(BUILD_MSX2 OFF CACHE BOOL "Build for MSX2") -set(BUILD_MSX2PLUS OFF CACHE BOOL "Build for MSX2+") -set(BUILD_HX20 OFF CACHE BOOL "Build for Toshiba HX-20") -set(BUILD_FSA1 ON CACHE BOOL "Build for Panasonic FS-A1") -set(BUILD_HBF1XDJ OFF CACHE BOOL "Build for Sony HB-F1XDJ") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(config_msx) diff --git a/source/build-cmake/gamegear/CMakeLists.txt b/source/build-cmake/gamegear/CMakeLists.txt deleted file mode 100644 index 1cbf60312..000000000 --- a/source/build-cmake/gamegear/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Sega Game Gear, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emugamegear) -set(BUILD_GAMEGEAR ON CACHE BOOL "Build for Sega Game Gear") -include(config_emumastersystem) diff --git a/source/build-cmake/hc20/CMakeLists.txt b/source/build-cmake/hc20/CMakeLists.txt deleted file mode 100644 index a58da0abe..000000000 --- a/source/build-cmake/hc20/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,HC20, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuhc20) - -set(EXEC_TARGET emuhc20) -set(VM_NAME hc20) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) -set(FLAG_USE_Z80 ON) - -set(VMFILES_BASE - event.cpp - io.cpp - memory.cpp -) -set(VMFILES_LIB - beep.cpp - datarec.cpp - disk.cpp - hd146818p.cpp - hd6301.cpp - i8255.cpp - mc6800.cpp - mc6801.cpp - noise.cpp - - tf20.cpp - upd765a.cpp - z80sio.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -set(VMFILES_HC20 ${VMFILES_BASE}) - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_HC20}) -add_definitions(-D_HC20) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/hc20.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/hc40/CMakeLists.txt b/source/build-cmake/hc40/CMakeLists.txt deleted file mode 100644 index 29c0f0111..000000000 --- a/source/build-cmake/hc40/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,HC 40, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuhc40) - -set(EXEC_TARGET emuhc40) -set(VM_NAME hc40) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - event.cpp -) -set(VMFILES_LIB - beep.cpp - datarec.cpp - disk.cpp - noise.cpp - ptf20.cpp - -) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -set(VMFILES_HC40 ${VMFILES_BASE}) - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_HC40}) -add_definitions(-D_HC40) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/hc40.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/hc80/CMakeLists.txt b/source/build-cmake/hc80/CMakeLists.txt deleted file mode 100644 index 9843e4ad4..000000000 --- a/source/build-cmake/hc80/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,EPSON HC 80, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuhc80) -set(VM_NAME hc80) -set(USE_FMGEN OFF) - -set(EXEC_TARGET emuhc80) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - event.cpp -) -set(VMFILES_LIB - beep.cpp - disk.cpp - i8251.cpp - noise.cpp - ptf20.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_HC80) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/hc80.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/hx20/CMakeLists.txt b/source/build-cmake/hx20/CMakeLists.txt deleted file mode 100644 index 1d6d08e03..000000000 --- a/source/build-cmake/hx20/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MSX2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emuhx20) -set(EXEC_TARGET emuhx20) -set(VM_NAME msx) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(BUILD_PX7 OFF CACHE BOOL "Build for Pioneer PX7") -set(BUILD_MSX1 OFF CACHE BOOL "Build for MSX1") -set(BUILD_MSX2 OFF CACHE BOOL "Build for MSX2") -set(BUILD_MSX2PLUS OFF CACHE BOOL "Build for MSX2+") -set(BUILD_HX20 ON CACHE BOOL "Build for Toshiba HX-20") -set(BUILD_FSA1 OFF CACHE BOOL "Build for Panasonic FS-A1") -set(BUILD_HBF1XDJ OFF CACHE BOOL "Build for Sony HB-F1XDJ") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(config_msx) diff --git a/source/build-cmake/j3100gt/CMakeLists.txt b/source/build-cmake/j3100gt/CMakeLists.txt deleted file mode 100644 index e301958c7..000000000 --- a/source/build-cmake/j3100gt/CMakeLists.txt +++ /dev/null @@ -1,99 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Toshiba J3100, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuj3100gt) -set(VM_NAME j3100) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES - i8237.cpp - io.cpp - event.cpp -) -set(VMFILES_LIB - disk.cpp - hd46505.cpp - i8237_base.cpp - i8253.cpp - i8259.cpp - noise.cpp - pcm1bit.cpp - upd765a.cpp -) - -set(BUILD_J3100GT ON CACHE BOOL "Build emuJ3100GT") -set(BUILD_J3100SL OFF CACHE BOOL "Build emuJ3100SL") -set(BUILD_J3100SS OFF CACHE BOOL "Build emuJ3100SS") -set(BUILD_J3100SE OFF CACHE BOOL "Build emuJ3100SE") - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER OFF CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(BUILD_J3100GT) - set(EXEC_TARGET emuj3100gt) - add_definitions(-D_J3100GT) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100gt.qrc) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} - hd146818p.cpp - ) -elseif(BUILD_J3100SL) - set(EXEC_TARGET emuj3100sl) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100sl.qrc) - add_definitions(-D_J3100SL) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} -# i86.cpp - rp5c01.cpp - ) -set(FLAG_USE_I86 OFF) -elseif(BUILD_J3100SS) - set(EXEC_TARGET emuj3100ss) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100ss.qrc) - add_definitions(-D_J3100SS) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} -# i86.cpp - rp5c01.cpp - ) -elseif(BUILD_J3100SE) - set(EXEC_TARGET emuj3100se) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100se.qrc) - add_definitions(-D_J3100SE) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} -# i86.cpp - rp5c01.cpp - ) -set(FLAG_USE_I86 ON) -endif() -include(config_commonsource) diff --git a/source/build-cmake/j3100sl/CMakeLists.txt b/source/build-cmake/j3100sl/CMakeLists.txt deleted file mode 100644 index b44d9bf4b..000000000 --- a/source/build-cmake/j3100sl/CMakeLists.txt +++ /dev/null @@ -1,101 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Toshiba J3100, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuj3100sl) -set(VM_NAME j3100) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES - i8237.cpp - io.cpp - event.cpp -) - -set(VMFILES_LIB - disk.cpp - hd46505.cpp - i8237_base.cpp - i8253.cpp - i8259.cpp - noise.cpp - pcm1bit.cpp - upd765a.cpp -) - -set(BUILD_J3100GT OFF CACHE BOOL "Build emuJ3100GT") -set(BUILD_J3100SL ON CACHE BOOL "Build emuJ3100SL") -set(BUILD_J3100SS OFF CACHE BOOL "Build emuJ3100SS") -set(BUILD_J3100SE OFF CACHE BOOL "Build emuJ3100SE") -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") - -set(WITH_DEBUGGER OFF CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") -add_definitions(-D_CONFIGURE_WITH_CMAKE) - -if(BUILD_J3100GT) - set(EXEC_TARGET emuj3100gt) - add_definitions(-D_J3100GT) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100gt.qrc) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} - hd146818p.cpp - ) -elseif(BUILD_J3100SL) - set(EXEC_TARGET emuj3100sl) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100sl.qrc) - add_definitions(-D_J3100SL) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} -# i86.cpp - rp5c01.cpp - ) -set(FLAG_USE_I86 OFF) -elseif(BUILD_J3100SS) - set(EXEC_TARGET emuj3100ss) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100ss.qrc) - add_definitions(-D_J3100SS) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} - i86.cpp - rp5c01.cpp - ) -elseif(BUILD_J3100SE) - set(EXEC_TARGET emuj3100se) - set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/j3100se.qrc) - add_definitions(-D_J3100SE) - set(VMFILES ${VMFILES} - i286.cpp - ) - set(VMFILES_LIB ${VMFILES_LIB} -# i86.cpp - rp5c01.cpp - ) -set(FLAG_USE_I86 ON) -endif() - -include(config_commonsource) diff --git a/source/build-cmake/jr100/CMakeLists.txt b/source/build-cmake/jr100/CMakeLists.txt deleted file mode 100644 index b50d30832..000000000 --- a/source/build-cmake/jr100/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,EPSON HC 80, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emujr100) - -set(EXEC_TARGET emujr100) -set(VM_NAME jr100) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(VMFILES_BASE - sy6522.cpp - - event.cpp -) - -set(VMFILES_LIB - datarec.cpp - mb8861.cpp - mc6800.cpp - noise.cpp - not.cpp - pcm1bit.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_JR100) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/jr100.qrc) -include(config_commonsource) diff --git a/source/build-cmake/jr800/CMakeLists.txt b/source/build-cmake/jr800/CMakeLists.txt deleted file mode 100644 index d73e85d11..000000000 --- a/source/build-cmake/jr800/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,National JR-800, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emujr800) - -set(EXEC_TARGET emujr800) -set(VM_NAME jr800) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(VMFILES_BASE - memory.cpp - event.cpp -) - -set(VMFILES_LIB - datarec.cpp - hd44102.cpp - hd6301.cpp - mc6801.cpp - mc6800.cpp - noise.cpp - pcm1bit.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_JR800) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/jr800.qrc) -include(config_commonsource) diff --git a/source/build-cmake/jx/CMakeLists.txt b/source/build-cmake/jx/CMakeLists.txt deleted file mode 100644 index 0f4b701e5..000000000 --- a/source/build-cmake/jx/CMakeLists.txt +++ /dev/null @@ -1,55 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,IBM JX, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emujx) - -set(EXEC_TARGET emujx) -set(VM_NAME jx) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES_BASE - i286.cpp - io.cpp - memory.cpp - event.cpp -) -set(VMFILES_LIB - disk.cpp - i8251.cpp - i8253.cpp - i8255.cpp - i8259.cpp - - hd46505.cpp - not.cpp - noise.cpp - pcm1bit.cpp - upd765a.cpp - sn76489an.cpp -) -set(FLAG_USE_I86 OFF) - -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") -include(detect_target_cpu) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_JX) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/jx.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/libCSPavio/CMakeLists.txt b/source/build-cmake/libCSPavio/CMakeLists.txt deleted file mode 100644 index 5e64b7bd2..000000000 --- a/source/build-cmake/libCSPavio/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -project (libCSPavio) -set(CMAKE_MODULE_PATH "${libCSPavio_SOURCE_DIR}/../cmake") - -#include(config_commonsource) - -include(config_sharedlibs) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/avio) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/gui) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src) -add_subdirectory(../../src/qt/avio qt/avio) - diff --git a/source/build-cmake/libCSPcommon_vm/CMakeLists.txt b/source/build-cmake/libCSPcommon_vm/CMakeLists.txt deleted file mode 100644 index 1618435fa..000000000 --- a/source/build-cmake/libCSPcommon_vm/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - - -project (libCSPcommon_vm) -set(CMAKE_MODULE_PATH "${libCSPcommon_vm_SOURCE_DIR}/../cmake") - -include(config_sharedlibs) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/libcpu_newdev/libcpu_i386/) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm/fmgen) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src) -add_subdirectory(../../src/vm/common_vm vm/common_vm) - diff --git a/source/build-cmake/libCSPemu_utils/CMakeLists.txt b/source/build-cmake/libCSPemu_utils/CMakeLists.txt deleted file mode 100644 index e13b74e75..000000000 --- a/source/build-cmake/libCSPemu_utils/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -project (libCSPemu_utils) -set(CMAKE_MODULE_PATH "${libCSPemu_utils_SOURCE_DIR}/../cmake") - - -include(config_sharedlibs) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/common) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt/gui) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/qt) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src) -add_subdirectory(../../src/qt/emuutils qt/emuutils) - - diff --git a/source/build-cmake/libCSPfmgen/CMakeLists.txt b/source/build-cmake/libCSPfmgen/CMakeLists.txt deleted file mode 100644 index 828c2016a..000000000 --- a/source/build-cmake/libCSPfmgen/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -project (libCSPfmgen) - -set(CMAKE_MODULE_PATH "${libCSPfmgen_SOURCE_DIR}/../cmake") -include(config_sharedlibs) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/vm) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src) -add_subdirectory(../../src/vm/fmgen vm/fmgen) - diff --git a/source/build-cmake/libCSPgui/CMakeLists.txt b/source/build-cmake/libCSPgui/CMakeLists.txt deleted file mode 100644 index 75e86ac4b..000000000 --- a/source/build-cmake/libCSPgui/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -project (libCSPgui) - -set(CMAKE_MODULE_PATH "${libCSPgui_SOURCE_DIR}/../cmake") -include(config_sharedlibs) - -add_subdirectory(../../src/qt/gui qt/gui) - diff --git a/source/build-cmake/libCSPosd/CMakeLists.txt b/source/build-cmake/libCSPosd/CMakeLists.txt deleted file mode 100644 index 19088e628..000000000 --- a/source/build-cmake/libCSPosd/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -project (libCSPgui) - -set(CMAKE_MODULE_PATH "${libCSPgui_SOURCE_DIR}/../cmake") -include(config_sharedlibs) - -add_subdirectory(../../src/qt qt/osd) - diff --git a/source/build-cmake/m5/CMakeLists.txt b/source/build-cmake/m5/CMakeLists.txt deleted file mode 100644 index 25b136127..000000000 --- a/source/build-cmake/m5/CMakeLists.txt +++ /dev/null @@ -1,51 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SORD m5, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emum5) - -set(EXEC_TARGET emum5) -set(VM_NAME m5) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - memory.cpp - - io.cpp - event.cpp -) - -set(VMFILES_LIB - datarec.cpp - noise.cpp - sn76489an.cpp - tms9918a.cpp - z80ctc.cpp -) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_M5) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/m5.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/map1010/CMakeLists.txt b/source/build-cmake/map1010/CMakeLists.txt deleted file mode 100644 index 5ff57d1c0..000000000 --- a/source/build-cmake/map1010/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SEIKO MAP1010, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (map1010) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(BUILD_MAP1010 ON CACHE BOOL "Build eMAP1010") - -include(config_phc25) diff --git a/source/build-cmake/mastersystem/CMakeLists.txt b/source/build-cmake/mastersystem/CMakeLists.txt deleted file mode 100644 index 29b45e684..000000000 --- a/source/build-cmake/mastersystem/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Sega Master System, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emumastersystem) - -set(BUILD_MASTERSYSTEM ON CACHE BOOL "Build for Sega MASTER SYSTEM") -include(config_emumastersystem) diff --git a/source/build-cmake/msx1/CMakeLists.txt b/source/build-cmake/msx1/CMakeLists.txt deleted file mode 100644 index 43cd47dfa..000000000 --- a/source/build-cmake/msx1/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MSX1, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumsx1) -set(EXEC_TARGET emumsx1) -set(VM_NAME msx) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(BUILD_PX7 OFF CACHE BOOL "Build for Pioneer PX7") -set(BUILD_MSX1 ON CACHE BOOL "Build for MSX1") -set(BUILD_MSX2 OFF CACHE BOOL "Build for MSX2") -set(BUILD_MSX2PLUS OFF CACHE BOOL "Build for MSX2+") -set(BUILD_HX20 OFF CACHE BOOL "Build for Toshiba HX-20") -set(BUILD_FSA1 OFF CACHE BOOL "Build for Panasonic FS-A1") -set(BUILD_HBF1XDJ OFF CACHE BOOL "Build for Sony HB-F1XDJ") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(config_msx) diff --git a/source/build-cmake/msx2/CMakeLists.txt b/source/build-cmake/msx2/CMakeLists.txt deleted file mode 100644 index 09e8986fa..000000000 --- a/source/build-cmake/msx2/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MSX2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumsx2) -set(EXEC_TARGET emumsx2) -set(VM_NAME msx) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(BUILD_PX7 OFF CACHE BOOL "Build for Pioneer PX7") -set(BUILD_MSX1 OFF CACHE BOOL "Build for MSX1") -set(BUILD_MSX2 ON CACHE BOOL "Build for MSX2") -set(BUILD_MSX2PLUS OFF CACHE BOOL "Build for MSX2+") -set(BUILD_HX20 OFF CACHE BOOL "Build for Toshiba HX-20") -set(BUILD_FSA1 OFF CACHE BOOL "Build for Panasonic FS-A1") -set(BUILD_HBF1XDJ OFF CACHE BOOL "Build for Sony HB-F1XDJ") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(config_msx) diff --git a/source/build-cmake/msx2p/CMakeLists.txt b/source/build-cmake/msx2p/CMakeLists.txt deleted file mode 100644 index 1c1133c52..000000000 --- a/source/build-cmake/msx2p/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MSX2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumsx2p) -set(EXEC_TARGET emumsx2p) -set(VM_NAME msx) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(BUILD_PX7 OFF CACHE BOOL "Build for Pioneer PX7") -set(BUILD_MSX1 OFF CACHE BOOL "Build for MSX1") -set(BUILD_MSX2 OFF CACHE BOOL "Build for MSX2") -set(BUILD_MSX2PLUS ON CACHE BOOL "Build for MSX2+") -set(BUILD_HX20 OFF CACHE BOOL "Build for Toshiba HX-20") -set(BUILD_FSA1 OFF CACHE BOOL "Build for Panasonic FS-A1") -set(BUILD_HBF1XDJ OFF CACHE BOOL "Build for Sony HB-F1XDJ") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(config_msx) diff --git a/source/build-cmake/multi8/CMakeLists.txt b/source/build-cmake/multi8/CMakeLists.txt deleted file mode 100644 index 40a700c7f..000000000 --- a/source/build-cmake/multi8/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Mitsubishi Multi 8, Qt **") -message("") -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumulti8) -set(VM_NAME multi8) -set(USE_FMGEN ON) -set(EXEC_TARGET emumulti8) -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - i8253.cpp - io.cpp - - event.cpp -) -set(VMFILES_LIB - ay_3_891x.cpp - beep.cpp - disk.cpp - datarec.cpp - hd46505.cpp - i8251.cpp -# i8253.cpp - i8255.cpp - i8259.cpp - noise.cpp - upd765a.cpp -) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_MULTI8) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/multi8.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/mycomz80a/CMakeLists.txt b/source/build-cmake/mycomz80a/CMakeLists.txt deleted file mode 100644 index 37de0a9cc..000000000 --- a/source/build-cmake/mycomz80a/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MYCOM Z80A, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (mycomz80a) -set(VM_NAME mycomz80a) -set(USE_FMGEN OFF) -set(FLAG_USE_Z80 ON) -set(VMFILES - msm5832.cpp - datarec.cpp - - event.cpp - io.cpp -) -set(VMFILES_LIB - datarec.cpp - hd46505.cpp - i8255.cpp - msm58321_base.cpp - noise.cpp - sn76489an.cpp -) - -set(BUILD_MYCOMZ80A ON CACHE BOOL "Build EMU-MYCOMZ80A") -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_MYCOMZ80A) -set(EXEC_TARGET emumycomz80a) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mycomz80a.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/mz1200/CMakeLists.txt b/source/build-cmake/mz1200/CMakeLists.txt deleted file mode 100644 index 8aeeb4a58..000000000 --- a/source/build-cmake/mz1200/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ1200, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emumz1200) - -set(BUILD_MZ1200 ON CACHE BOOL "Build EMU-MZ1200") -include(config_mz80) diff --git a/source/build-cmake/mz1500/CMakeLists.txt b/source/build-cmake/mz1500/CMakeLists.txt deleted file mode 100644 index 81faa3298..000000000 --- a/source/build-cmake/mz1500/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ-1500, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emumz1500) - -set(BUILD_MZ1500 ON CACHE BOOL "Build EMU-MZ1500") - -include(config_mz700) diff --git a/source/build-cmake/mz2200/CMakeLists.txt b/source/build-cmake/mz2200/CMakeLists.txt deleted file mode 100644 index fa4746570..000000000 --- a/source/build-cmake/mz2200/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ2200, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumz2200) - -set(BUILD_MZ2200 ON CACHE BOOL "Build EMU-MZ2200") -include(config_mz2500) - diff --git a/source/build-cmake/mz2500/CMakeLists.txt b/source/build-cmake/mz2500/CMakeLists.txt deleted file mode 100644 index 3de29b242..000000000 --- a/source/build-cmake/mz2500/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ2500, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumz2500) - -set(BUILD_MZ2500 ON CACHE BOOL "Build EMU-MZ2500") -include(config_mz2500) diff --git a/source/build-cmake/mz2800/CMakeLists.txt b/source/build-cmake/mz2800/CMakeLists.txt deleted file mode 100644 index 716f92470..000000000 --- a/source/build-cmake/mz2800/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MYCOM Z80A, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (mz2800) -set(VM_NAME mz2800) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES - mz1p17.cpp - scsi_dev.cpp - scsi_hdd.cpp - scsi_host.cpp - event.cpp - io.cpp -) -set(VMFILES_LIB - i8253.cpp - i8255.cpp - i8259.cpp - noise.cpp - rp5c01.cpp - z80sio.cpp - z80pio.cpp - prnfile.cpp - # i286.cpp - upd71071.cpp - mb8877.cpp - not.cpp - pcm1bit.cpp - ym2203.cpp - disk.cpp -) -set(FLAG_USE_I286 ON) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_MZ2800) -set(EXEC_TARGET emumz2800) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz2800.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/mz3500/CMakeLists.txt b/source/build-cmake/mz3500/CMakeLists.txt deleted file mode 100644 index 2e96771bf..000000000 --- a/source/build-cmake/mz3500/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MYCOM Z80A, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (mz3500) -set(VM_NAME mz3500) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES - mz1p17.cpp - event.cpp - io.cpp -) -set(VMFILES_LIB - i8251.cpp - i8253.cpp - i8255.cpp - - ls244.cpp - not.cpp - noise.cpp - pcm1bit.cpp - upd1990a.cpp - upd765a.cpp - upd7220.cpp - - prnfile.cpp - - disk.cpp -) -set(FLAG_USE_Z80 ON) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_MZ3500) -set(EXEC_TARGET emumz3500) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/mz3500.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/mz5500/CMakeLists.txt b/source/build-cmake/mz5500/CMakeLists.txt deleted file mode 100644 index 2ccd3571d..000000000 --- a/source/build-cmake/mz5500/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Sharp MZ5500/6500/6550, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (mz5500) - -set(BUILD_MZ5500 ON CACHE BOOL "Build emumz5500") -include(config_mz5500) - diff --git a/source/build-cmake/mz6500/CMakeLists.txt b/source/build-cmake/mz6500/CMakeLists.txt deleted file mode 100644 index 98a3465ca..000000000 --- a/source/build-cmake/mz6500/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Sharp MZ5500/6500/6550, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (mz6500) -set(BUILD_MZ6500 ON CACHE BOOL "Build emumz6500") - -include(config_mz5500) diff --git a/source/build-cmake/mz6550/CMakeLists.txt b/source/build-cmake/mz6550/CMakeLists.txt deleted file mode 100644 index daf2d494f..000000000 --- a/source/build-cmake/mz6550/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Sharp MZ5500/6500/6550, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (mz6550) -set(BUILD_MZ6550 ON CACHE BOOL "Build emumz6550") - -include(config_mz5500) diff --git a/source/build-cmake/mz700/CMakeLists.txt b/source/build-cmake/mz700/CMakeLists.txt deleted file mode 100644 index 913c40a98..000000000 --- a/source/build-cmake/mz700/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ-700, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emumz700) - -set(BUILD_MZ700 ON CACHE BOOL "Build EMU-MZ700") - -include(config_mz700) diff --git a/source/build-cmake/mz800/CMakeLists.txt b/source/build-cmake/mz800/CMakeLists.txt deleted file mode 100644 index 1d8b7b1d7..000000000 --- a/source/build-cmake/mz800/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ-800, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emumz800) - -set(BUILD_MZ800 ON CACHE BOOL "Build EMU-MZ800") - -include(config_mz700) diff --git a/source/build-cmake/mz80a/CMakeLists.txt b/source/build-cmake/mz80a/CMakeLists.txt deleted file mode 100644 index c5fdf3c32..000000000 --- a/source/build-cmake/mz80a/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ80A, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumz80a) - -set(BUILD_MZ80A ON CACHE BOOL "Build EMU-MZ80A") -include(config_mz80) diff --git a/source/build-cmake/mz80b/CMakeLists.txt b/source/build-cmake/mz80b/CMakeLists.txt deleted file mode 100644 index 87c3c8fb5..000000000 --- a/source/build-cmake/mz80b/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ 80B, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumz80b) -set(BUILD_MZ80B ON CACHE BOOL "Build EMU-MZ80B") -include(config_mz2500) - diff --git a/source/build-cmake/mz80k/CMakeLists.txt b/source/build-cmake/mz80k/CMakeLists.txt deleted file mode 100644 index 220b54344..000000000 --- a/source/build-cmake/mz80k/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ80K, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emumz80k) - -set(BUILD_MZ80K ON CACHE BOOL "Build EMU-MZ80K") -include(config_mz80) - diff --git a/source/build-cmake/n5200/CMakeLists.txt b/source/build-cmake/n5200/CMakeLists.txt deleted file mode 100644 index 865380e93..000000000 --- a/source/build-cmake/n5200/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,NEC N5200, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emun5200) - -set(EXEC_TARGET emun5200) -set(VM_NAME n5200) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES_BASE -# i386.cpp - i8237.cpp - - io.cpp - event.cpp -) -set(VMFILES_LIB - beep.cpp - i8237_base.cpp - i8251.cpp - i8253.cpp - i8255.cpp - i8259.cpp - noise.cpp - upd1990a.cpp - upd7220.cpp - upd765a.cpp - disk.cpp -) -set(FLAG_USE_I386_VARIANTS ON) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_N5200) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/n5200.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/params/archdef_arm32.dat b/source/build-cmake/params/archdef_arm32.dat deleted file mode 100644 index 49f27a151..000000000 --- a/source/build-cmake/params/archdef_arm32.dat +++ /dev/null @@ -1,66 +0,0 @@ -# ARM32 -WITH_FPU="No" -case ${LOCAL_ARCH_TYPE} in - "GENERIC" | "generic" ) - ARCH_FLAGS="" - ;; - "ARMV6" | "armv6" | "V6" | "v6" ) - ARCH_FLAGS="-march=armv6 -mtune=generic" - WITH_FPU="No" - ;; - "ARMV6FPU" | "armv6fpu" | "V6FPU" | "v6fpu" ) - ARCH_FLAGS="-march=armv6+fp -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV7" | "armv7" | "V7" | "v7" ) - ARCH_FLAGS="-march=armv7 -mtune=generic" - WITH_FPU="No" - ;; - "ARMV7FPU" | "armv7fpu" | "V7FPU" | "v7fpu" ) - ARCH_FLAGS="-march=armv7+fp -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV7AMP" | "armv7amp" | "V7AMP" | "v7amp" ) - ARCH_FLAGS="-march=armv7-a+mp -mtune=generic" - WITH_FPU="No" - ;; - "ARMV7AMPFPU" | "armv7ampfpu" | "V7AMPFPU" | "v7ampfpu" ) - ARCH_FLAGS="-march=armv7-a+mp+fp -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV7MPSIMD" | "armv7asimd" | "V7ASIMD" | "v7asimd" ) - ARCH_FLAGS="-march=armv7-a+mp+fp+simd -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV8A" | "armv8a" | "V8A" | "v8a" ) - ARCH_FLAGS="-march=armv8-a -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV81A" | "armv81a" | "V81A" | "v81a" ) - ARCH_FLAGS="-march=armv8.1-a+simd -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV82A" | "armv82a" | "V82A" | "v82a" ) - ARCH_FLAGS="-march=armv8.2-a+simd -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV83A" | "armv83a" | "V83A" | "v83a" ) - ARCH_FLAGS="-march=armv8.3-a+simd -mtune=generic" - WITH_FPU="Yes" - ;; - "ARMV84A" | "armv84a" | "V84A" | "v84a" ) - ARCH_FLAGS="-march=armv8.4-a+simd -mtune=generic" - WITH_FPU="Yes" - ;; - "Custom" | "CUSTOM" | "custom" ) - ARCH_FLAGS="" - ;; - "None" | "NONE " | "none" | "No" | "no" | "NO" ) - ARCH_FLAGS="" - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -ARCH_FLAGS="${ARCH_FLAGS} ${APPEND_ARCH_FLAGS}" diff --git a/source/build-cmake/params/archdef_arm64.dat b/source/build-cmake/params/archdef_arm64.dat deleted file mode 100644 index 0d0e04904..000000000 --- a/source/build-cmake/params/archdef_arm64.dat +++ /dev/null @@ -1,41 +0,0 @@ -# AArch64 (or ARM64) -case ${LOCAL_ARCH_TYPE} in - "GENERIC" | "generic" ) - ARCH_FLAGS="" - ;; - "ARMV81A" | "armv81a" | "V81A" | "v81a" ) - ARCH_FLAGS="-march=armv8.1-a -mtune=generic" - ;; - "ARMV82A" | "armv82a" | "V82A" | "v82a" ) - ARCH_FLAGS="-march=armv8.2-a -mtune=generic" - ;; - "ARMV83A" | "armv83a" | "V83A" | "v83a" ) - ARCH_FLAGS="-march=armv8.3-a -mtune=generic" - ;; - "ARMV84A" | "armv84a" | "V84A" | "v84a" ) - ARCH_FLAGS="-march=armv8.4-a -mtune=generic" - ;; - "ARMV81ASVE" | "armv81asve" | "V81ASVE" | "v81asve" ) - ARCH_FLAGS="-march=armv8.1-a+sve" - ;; - "ARMV82ASVE" | "armv82asve" | "V82ASVE" | "v82asve" ) - ARCH_FLAGS="-march=armv8.2-a+sve" - ;; - "ARMV83ASVE" | "armv83asve" | "V83ASVE" | "v83asve" ) - ARCH_FLAGS="-march=armv8.3-a+sve" - ;; - "ARMV84ASVE" | "armv84asve" | "V84ASVE" | "v84asve" ) - ARCH_FLAGS="-march=armv8.4-a+sve" - ;; - "Custom" | "CUSTOM" | "custom" ) - ARCH_FLAGS="" - ;; - "None" | "NONE " | "none" | "No" | "no" | "NO" ) - ARCH_FLAGS="" - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -ARCH_FLAGS="${ARCH_FLAGS} ${APPEND_ARCH_FLAGS}" diff --git a/source/build-cmake/params/archdef_ia32.dat b/source/build-cmake/params/archdef_ia32.dat deleted file mode 100644 index 4a1193f98..000000000 --- a/source/build-cmake/params/archdef_ia32.dat +++ /dev/null @@ -1,66 +0,0 @@ -# IA32/ix86 -case ${LOCAL_ARCH_TYPE} in - "GENERIC" | "generic" ) - ARCH_FLAGS="-m32 -mtune=generic" - ;; - "SSE2" | "sse2" ) - ARCH_FLAGS="-march=i686 -mtune=generic -msse -msse2" - ;; - "SSE3" | "sse3" ) - ARCH_FLAGS="-march=prescott" - ;; - "AVX" | "avx" ) - ARCH_FLAGS="-march=pentium4 -msse3 -mssse3 -msse4.1 -msse4.2 -mavx" - ;; - "SSE1" | "sse1" ) - ARCH_FLAGS="-march=pentium3 -mtune=generic -msse" - ;; - "k6" | "K6" ) - ARCH_FLAGS="-march=k6" - ;; - "athlon" | "ATHLON" ) - ARCH_FLAGS="-march=athlon" - ;; - "athlonxp" | "ATHLONXP" ) - ARCH_FLAGS="-march=athlon-xp" - ;; - "pentium" | "PENTIUM" ) - ARCH_FLAGS="-march=pentium -mtune=generic" - ;; - "pentiummmx" | "PENTIUMMMX" | "MMX" | "mmx") - ARCH_FLAGS="-march=pentium-mmx" - ;; - "pentiumpro" | "PENTIUMPRO" ) - ARCH_FLAGS="-march=pentiumpro" - ;; - "pentium2" | "PENTIUM2" ) - ARCH_FLAGS="-march=pentium2" - ;; - "pentium3" | "PENTIUM3" ) - ARCH_FLAGS="-march=pentium3" - ;; - "pentium4" | "PENTIUM4" ) - ARCH_FLAGS="-march=pentium4" - ;; - "pentium4m" | "PENTIUM4M" ) - ARCH_FLAGS="-march=pentium4m" - ;; - "pentiumM" | "PENTIUMM" ) - ARCH_FLAGS="-march=pentium-m" - ;; - "prescott" | "PRESCOTT" ) - ARCH_FLAGS="-march=prescott" - ;; - - "Custom" | "CUSTOM" | "custom" ) - ARCH_FLAGS="" - ;; - "None" | "NONE " | "none" | "No" | "no" | "NO" | "686" | "I686" | "i686" ) - ARCH_FLAGS="-march=i686 -mtune=generic" - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -ARCH_FLAGS="${ARCH_FLAGS} ${APPEND_ARCH_FLAGS}" diff --git a/source/build-cmake/params/archdef_x86_64.dat b/source/build-cmake/params/archdef_x86_64.dat deleted file mode 100644 index 0c0c90030..000000000 --- a/source/build-cmake/params/archdef_x86_64.dat +++ /dev/null @@ -1,129 +0,0 @@ -# AMD64/x86_64 - -case ${LOCAL_ARCH_TYPE} in - "NATIVE" | "native" ) - ARCH_FLAGS="-march=native" - ;; - "GENERIC" | "generic" ) - ARCH_FLAGS="" - ;; - "32BIT" | "32bit" ) - ARCH_FLAGS="-m32" - ;; - "32BITSSE" | "32bitSSE" ) - ARCH_FLAGS="-march=i686 -m32 -msse" - ;; - "32BITSSE2" | "32bitSSE2" ) - ARCH_FLAGS="-march=i686 -m32 -msse -msse2" - ;; - "32BITSSE3" | "32bitSSE3" ) - ARCH_FLAGS="-march=i686 -m32 -msse -msse2 -msse3" - ;; - "32BITAVX" | "32bitAVX" ) - ARCH_FLAGS="-march=i686 -m32 -msse -msse2 -msse3 -mavx" - ;; - "32BITAVX2" | "32bitAVX2" ) - ARCH_FLAGS="-march=i686 -m32 -msse -msse2 -msse3 -mavx -mzvx2" - ;; - "SSE2" | "sse2" ) - ARCH_FLAGS="-msse -msse2" - ;; - "SSE3" | "sse3" ) - ARCH_FLAGS="-msse3" - ;; - "AVX" | "avx" ) - ARCH_FLAGS="-msse3 -mavx" - ;; - "AVX2" | "avx2" ) - ARCH_FLAGS="-msse3 -mavx -mavx2" - ;; - "AMDFAM10" | "amdfam10" ) - ARCH_FLAGS="-march=amdfam10 -mtune=generic" - ;; - "BDVER1" | "bdver1" ) - ARCH_FLAGS="-march=bdver1 -mtune=generic" - ;; - "BDVER2" | "bdver2" ) - ARCH_FLAGS="-march=bdver2 -mtune=generic" - ;; - "BDVER3" | "bdver3" ) - ARCH_FLAGS="-march=bdver3 -mtune=generic" - ;; - "BDVER4" | "bdver4" ) - ARCH_FLAGS="-march=bdver4 -mtune=generic" - ;; - "ZNVER1" | "znver1" | "ZEN1" | "zen1" ) - ARCH_FLAGS="-march=znver1 -mtune=generic" - ;; - "ZNVER2" | "znver2" | "ZEN2" | "zen2") - ARCH_FLAGS="-march=znver2 -mtune=generic" - ;; - "BTVER1" | "btver1" ) - ARCH_FLAGS="-march=btver1 -mtune=generic" - ;; - "BTVER2" | "btver2" ) - ARCH_FLAGS="-march=btver2 -mtune=generic" - ;; - "NOCONA" | "nocona" ) - ARCH_FLAGS="-march=nocona -mtune=generic" - ;; - "CORE2" | "core2" ) - ARCH_FLAGS="-march=core2 -mtune=generic" - ;; - "NEHALEM" | "nehalem" ) - ARCH_FLAGS="-march=nehalem -mtune=generic" - ;; - "WESTMERE" | "westmere" ) - ARCH_FLAGS="-march=westmere -mtune=generic" - ;; - "SANDYBRIDGE" | "sandybridge" ) - ARCH_FLAGS="-march=sandybridge -mtune=generic" - ;; - "IVYBRIDGE" | "ivybridge" ) - ARCH_FLAGS="-march=ivybridge -mtune=generic" - ;; - "SKYLAKE" | "skylake" ) - ARCH_FLAGS="-march=skylake -mtune=generic" - ;; - "CANNONLAKE" | "cannonlake" ) - ARCH_FLAGS="-march=cannonlake -mtune=generic" - ;; - "ICELAKE" | "icelake" ) - ARCH_FLAGS="-march=icelake-client -mtune=generic" - ;; - "CASCADELAKE" | "skylake" ) - ARCH_FLAGS="-march=cascadelake -mtune=generic" - ;; - "BONNELL" | "bonnell" ) - ARCH_FLAGS="-march=bonnell -mtune=generic" - ;; - "SILVERMONT" | "silvermont" ) - ARCH_FLAGS="-march=silvermont -mtune=generic" - ;; - "GOLDMONT" | "goldmont" ) - ARCH_FLAGS="-march=goldmont -mtune=generic" - ;; - "GOLDMONTPLUS" | "goldmontplus" ) - ARCH_FLAGS="-march=goldmont-plus -mtune=generic" - ;; - "TREMONT" | "tremont" ) - ARCH_FLAGS="-march=tremont -mtune=generic" - ;; - "KNL" | "knl" ) - ARCH_FLAGS="-march=knl -mtune=generic" - ;; - "KNM" | "knm" ) - ARCH_FLAGS="-march=knm -mtune=generic" - ;; - "Custom" | "CUSTOM" | "custom" ) - ARCH_FLAGS="" - ;; - "No" | "no" | "NO" | "None" | "NONE" | "none" ) - ARCH_FLAGS="" - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -ARCH_FLAGS="${ARCH_FLAGS} ${APPEND_ARCH_FLAGS}" diff --git a/source/build-cmake/params/buildvars_linux_params_gcc.dat b/source/build-cmake/params/buildvars_linux_params_gcc.dat deleted file mode 100644 index 948de8041..000000000 --- a/source/build-cmake/params/buildvars_linux_params_gcc.dat +++ /dev/null @@ -1,198 +0,0 @@ -################ -# -# This is build-parameters fo GCC/Linux. -# Neither for GCC/MinGW and LLVM. -# -CCMAKE_CC=gcc -CCMAKE_CXX=g++ - -if [ -v CC_SUFFIX ] ; then - CCMAKE_CC=${CCMAKE_CC}-${CC_SUFFIX} - CCMAKE_CXX=${CCMAKE_CXX}-${CC_SUFFIX} - if [ ${CC_SUFFIX} -le 5 ] ; then - MAKEFLAGS_BASE="-std=gnu++11 ${MAKEFLAGS_BASE}" - fi -fi -if [ -v CC_PREFIX ] ; then - CCMAKE_CC=${CC_PREFIX}-${CCMAKE_CC} - CCMAKE_CXX=${CC_PREFIX}-${CCMAKE_CXX} -fi -if [ -v CC_PATH ] ; then - CCMAKE_CC=${CC_PATH}/${CCMAKE_CC} - CCMAKE_CXX=${CC_PATH}/${CCMAKE_CXX} -fi - -case ${MAJOR_ARCH} in - "AMD64" | "amd64" | "x86_64" | "X86_64" ) - . ./params/archdef_x86_64.dat - ;; - "IA32" | "ia32" | "x86" | "X86" ) - . ./params/archdef_ia32.dat - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -case ${USE_RADICAL_OPTIMIZE} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3=" \ - -O3 \ - ${ARCH_FLAGS} \ - -Wall \ - ${MAKEFLAGS_BASE} \ - " - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_BASE3=" \ - -O2 \ - -mtune=generic \ - -ftree-vectorize \ - -funroll-loops \ - ${ARCH_FLAGS} \ - -Wall \ - ${MAKEFLAGS_BASE} \ - " - ;; -esac - -case ${USE_SANITIZER} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fsanitize=address \ - -fsanitize=undefined \ - -fsanitize=vptr \ - " - ;; - "No" | "no" | "NO" | * ) - ;; -esac - -case ${USE_STACK_PROTECTION} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector \ - " - ;; - "All" | "all" | "ALL" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector-all \ - " - ;; - "Strong" | "strong" | "STRONG" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector-strong \ - " - ;; - "No" | "no" | "NO" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fno-stack-protector \ - " - ;; - "Default" | "default" | "DEFAULT" | * ) - ;; -esac - -# -fstack-clash-protection \ -# -ftree-vectorize \ -# -ftree-loop-vectorize \ -# -ftree-loop-distribute-patterns \ -# -ftree-loop-optimize \ -# -ftree-loop-if-convert-stores \ -# -ftree-loop-distribution \ -# -ftree-loop-ivcanon \ -# -fvect-cost-model=unlimited \ -# -fsimd-cost-model=unlimited \ -# -fivopts \ -# -fbranch-probabilities \ -# -fbranch-target-load-optimize \ -# -fbranch-target-load-optimize2 \ -# -fbtr-bb-exclusive \ -# -fselective-scheduling \ -# -fsel-sched-pipelining \ -# -fsel-sched-pipelining-outer-loops \ -# -funroll-loops \ -# -fvariable-expansion-in-unroller \ -# -fprefetch-loop-arrays \ -# -fgraphite-identity \ -# -floop-nest-optimize \ - -case ${USE_WHOLE_PROGRAM_OPTIMIZE} in - "Yes" | "yes" | "YES" ) - LTO_FLAGS="-fwhole-program" - ;; - * ) - LTO_FLAGS="" - ;; -esac - -case ${COMPRESS_SYMBOLS} in - "Yes" | "yes" | "YES" ) - COMPRESS_CFLAGS="-gz=zlib" - ;; - "No" | "no" | "NO" | * ) - COMPRESS_CFLAGS="" - ;; -esac - -#ToDo: Its ugly hack. -if [ -z ${EXTRA_DLL_DIR} ] ; then - EXTRA_DLL_DIR="/usr/local/lib/x86_64-linux-gnu" -fi - - -case ${USE_SHRINK_DEBUG_SYMBOL} in - "Yes" | "yes" | "YES" ) - EXTRA_LINKER_FLAGS="-L${EXTRA_DLL_DIR} -fuse-ld=gold -Wl,--gdb-index -Wl,--compress-debug-sections,zlib ${EXTRA_LINKER_FLAGS}" - EXTRA_LINKER_DLL_FLAGS="-L${EXTRA_DLL_DIR} -fuse-ld=gold -Wl,--gdb-index -Wl,--compress-debug-sections,zlib ${EXTRA_LINKER_DLL_FLAGS}" - MAKEFLAGS_BASE3DLL="-gsplit-dwarf ${MAKEFLAGS_BASE3}" - MAKEFLAGS_BASE3="-gsplit-dwarf ${MAKEFLAGS_BASE3}" - ;; -esac - -case ${CSP_DEBUG} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_DLL_LINK_BASE="-ggdb ${EXTRA_LINKER_DLL_FLAGS} ${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3DLL} -DNDEBUG" - MAKEFLAGS_DLL_BASE="-ggdb ${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3DLL} -DNDEBUG" - MAKEFLAGS_BASE2="-ggdb ${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3} -DNDEBUG" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_DLL_LINK_BASE="${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3}" - MAKEFLAGS_DLL_BASE="${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3}" - MAKEFLAGS_BASE2="${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3}" - ;; -esac - -if [ -n "${LTO_THREADS}" ] ; then - LTO_FLAGS="-flto=${LTO_THREADS} -flto-compression-level=9 ${LTO_FLAGS}" - LTO_FLAGS2="-flto -ffat-lto-objects" -else - LTO_FLAGS="" - LTO_FLAGS2="" -fi - -case ${USE_LTO} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_LINK_BASE2="${EXTRA_LINKER_FLAGS} ${LTO_FLAGS} ${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="${LTO_FLAGS2} ${MAKEFLAGS_BASE2}" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_LINK_BASE2="${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2}" - ;; -esac - -case ${USE_OPENMP} in - "Yes" | "yes" | "YES" ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=YES" - ;; - "No" | "no" | "NO" | * ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=NO" - ;; -esac - -CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} \ - -DCMAKE_AR:STRING=gcc-ar \ - -DCMAKE_NM:STRING=gcc-nm \ - -DCMAKE_RANLIB:STRING=gcc-ranlib \ - " diff --git a/source/build-cmake/params/buildvars_linux_params_llvm.dat b/source/build-cmake/params/buildvars_linux_params_llvm.dat deleted file mode 100644 index 741baa0c8..000000000 --- a/source/build-cmake/params/buildvars_linux_params_llvm.dat +++ /dev/null @@ -1,169 +0,0 @@ -################ -# -# This is build-parameters fo LLVM/Linux. -# Neither for LLVM/MinGW and GCC. -# -## CLANG -CCMAKE_CC=clang -CCMAKE_CXX=clang++ - -if [ -v CC_SUFFIX ] ; then - CCMAKE_CC=${CCMAKE_CC}-${CC_SUFFIX} - CCMAKE_CXX=${CCMAKE_CXX}-${CC_SUFFIX} -fi -if [ -v CC_PREFIX ] ; then - CCMAKE_CC=${CC_PREFIX}-${CCMAKE_CC} - CCMAKE_CXX=${CC_PREFIX}-${CCMAKE_CXX} -fi -if [ -v CC_PATH ] ; then - CCMAKE_CC=${CC_PATH}/${CCMAKE_CC} - CCMAKE_CXX=${CC_PATH}/${CCMAKE_CXX} -fi - -case ${MAJOR_ARCH} in - "AMD64" | "amd64" | "x86_64" | "X86_64" ) - . ./params/archdef_x86_64.dat - ;; - "IA32" | "ia32" | "x86" | "X86" ) - . ./params/archdef_ia32.dat - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -case ${USE_RADICAL_OPTIMIZE} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3=" \ - -O3 \ - -Wreserved-user-defined-literal \ - -fslp-vectorize \ - -fvectorize \ - -fstrict-vtable-pointers \ - -fstrict-enums \ - -std=c++11 \ - ${ARCH_FLAGS} \ - -Wall \ - ${MAKEFLAGS_BASE} \ - " - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_BASE3=" \ - -O2 \ - -Wreserved-user-defined-literal \ - -fslp-vectorize \ - -fvectorize \ - -fstrict-vtable-pointers \ - -fstrict-enums \ - -std=c++11 \ - ${ARCH_FLAGS} \ - -Wall \ - ${MAKEFLAGS_BASE} \ - " - ;; -esac - -case ${USE_SANITIZER} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fsanitize=address \ - -fsanitize=undefined \ - -fsanitize=vptr \ - " - ;; - "No" | "no" | "NO" | * ) - ;; -esac - -case ${USE_STACK_PROTECTION} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector \ - " - ;; - "All" | "all" | "ALL" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector-all \ - " - ;; - "Strong" | "strong" | "STRONG" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector-strong \ - " - ;; - "No" | "no" | "NO" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fno-stack-protector \ - " - ;; - "Default" | "default" | "DEFAULT" | * ) - ;; -esac - -case ${USE_WHOLE_PROGRAM_OPTIMIZE} in - "Yes" | "yes" | "YES" ) - LTO_FLAGS="-fwhole-program -fwhole-program-vtables" - ;; - * ) - LTO_FLAGS="" - ;; -esac - -case ${COMPRESS_SYMBOLS} in - "Yes" | "yes" | "YES" ) - COMPRESS_CFLAGS="-gz=zlib" - ;; - "No" | "no" | "NO" | * ) - COMPRESS_CFLAGS="" - ;; -esac - -#ToDo: Its ugly hack. -if [ -z ${EXTRA_DLL_DIR} ] ; then - EXTRA_DLL_DIR="/usr/local/lib/x86_64-linux-gnu" -fi - -case ${USE_SHRINK_DEBUG_SYMBOL} in - "Yes" | "yes" | "YES" ) - EXTRA_LINKER_FLAGS="-L${EXTRA_DLL_DIR} -fuse-ld=gold -Wl,--gdb-index -Wl,--compress-debug-sections,zlib ${EXTRA_LINKER_FLAGS}" - EXTRA_LINKER_DLL_FLAGS="-L${EXTRA_DLL_DIR} -fuse-ld=gold -Wl,--gdb-index -Wl,--compress-debug-sections,zlib ${EXTRA_LINKER_DLL_FLAGS}" - MAKEFLAGS_BASE3DLL="-gsplit-dwarf ${MAKEFLAGS_BASE3}" - MAKEFLAGS_BASE3="-gsplit-dwarf ${MAKEFLAGS_BASE3}" - ;; -esac -case ${CSP_DEBUG} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_DLL_LINK_BASE="-ggdb ${EXTRA_LINKER_DLL_FLAGS} ${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3DLL} -DNDEBUG" - MAKEFLAGS_DLL_BASE="-ggdb ${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3DLL} -DNDEBUG" - MAKEFLAGS_BASE2="-ggdb ${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3} -DNDEBUG" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_DLL_LINK_BASE="${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3}" - MAKEFLAGS_DLL_BASE="${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3}" - MAKEFLAGS_BASE2="${COMPRESS_CFLAGS} ${MAKEFLAGS_BASE3}" - ;; -esac -case ${USE_LTO} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_LINK_BASE2="${EXTRA_LINKER_FLAGS} ${LTO_FLAGS} ${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="${LTO_FLAGS2} ${MAKEFLAGS_BASE2}" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_LINK_BASE2="${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2}" - ;; -esac - -case ${USE_OPENMP} in - "Yes" | "yes" | "YES" ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=YES" - ;; - "No" | "no" | "NO" | * ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=NO" - ;; -esac - -CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DCMAKE_AR:STRING=llvm-ar-${LLVM_VERSION} -DCMAKE_NM:STRING=llvm-nm-${LLVM_VERSION} -DCMAKE_RANLIB:STRING=llvm-ranlib-${LLVM_VERSION}" -CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DCMAKE_AS:STRING=llvm-as-${LLVM_VERSION}" - - diff --git a/source/build-cmake/params/buildvars_mingw_params_gcc.dat b/source/build-cmake/params/buildvars_mingw_params_gcc.dat deleted file mode 100644 index 747d11074..000000000 --- a/source/build-cmake/params/buildvars_mingw_params_gcc.dat +++ /dev/null @@ -1,133 +0,0 @@ -################ -# -# This is build-parameters fo GCC/MinGW. -# Neither for GCC/Linux and LLVM. -# - -MAKEFLAGS_BASE2="${MAKEFLAGS_BASE} -mthread=posix -pthread -mthreads" - -case ${MAJOR_ARCH} in - "AMD64" | "amd64" | "x86_64" | "X86_64" ) - . ./params/archdef_x86_64.dat - ;; - "IA32" | "ia32" | "x86" | "X86" ) - . ./params/archdef_ia32.dat - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -case ${CSP_DEBUG} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE2="-g ${MAKEFLAGS_BASE} -O2 \ - ${ARCH_FLAGS} \ - -std=c++11 \ - ${ADDITIONAL_CFLAGS} \ - -DNDEBUG" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE} -O2 \ - ${ARCH_FLAGS} \ - -std=c++11 \ - ${ADDITIONAL_CFLAGS} \ - -DNDEBUG " -# -ftree-vectorize \ -# -ftree-loop-optimize \ -# -floop-nest-optimize \ - ;; -esac - -case ${USE_WHOLE_PROGRAM_OPTIMIZE} in - "Yes" | "yes" | "YES" ) - LTO_FLAGS="-fwhole-program" - ;; - * ) - LTO_FLAGS="" - ;; -esac - -case ${USE_SANITIZER} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2} \ - -fsanitize=address \ - -fsanitize=undefined \ - -fsanitize=vptr \ - " - ;; - "No" | "no" | "NO" | * ) - ;; -esac - -case ${USE_STACK_PROTECTION} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector \ - " - ;; - "All" | "all" | "ALL" ) - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2} \ - -fstack-protector-all \ - " - ;; - "Strong" | "strong" | "STRONG" ) - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2} \ - -fstack-protector-strong \ - " - ;; - "No" | "no" | "NO" ) - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2} \ - -fno-stack-protector \ - " - ;; - "Default" | "default" | "DEFAULT" | * ) - ;; -esac - -if [ -n "${LTO_THREADS}" ] ; then - LTO_FLAGS="-flto=${LTO_THREADS} -flto-compression-level=9 ${LTO_FLAGS}" - LTO_FLAGS2="-flto -ffat-lto-objects" -else - LTO_FLAGS="" - LTO_FLAGS2="" -fi -case ${USE_LTO} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_LINK_BASE="${LTO_FLAGS} ${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="${LTO_FLAGS2} ${MAKEFLAGS_BASE2}" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_LINK_BASE="${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2}" - ;; -esac -case ${STRIP_SYMBOLS} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE2="-s ${MAKEFLAGS_BASE2}" - MAKEFLAGS_LINK_BASE="-s ${MAKEFLAGS_LINK_BASE}" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2}" - MAKEFLAGS_LINK_BASE="${MAKEFLAGS_LINK_BASE}" - ;; -esac -case ${USE_OPENMP} in - "Yes" | "yes" | "YES" ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=YES" - ;; - "No" | "no" | "NO" | * ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=NO" - ;; -esac - -#CMAKE_APPENDFLAG="-DUSE_QT5_4_APIS=ON -DUSE_MOVIE_LOADER=ON \ - -CMAKE_APPENDFLAG=" -DUSE_QT5_4_APIS=ON \ - -DUSE_MOVIE_LOADER=ON \ - -DUSE_MOVIE_SAVER=ON \ - -DCMAKE_AR:STRING=i686-w64-mingw32-gcc-ar \ - -DCMAKE_LD:STRING=i686-w64-mingw32-gcc-ld \ - -DCMAKE_NM:STRING=i686-w64-mingw32-gcc-nm \ - -DCMAKE_RANLIB:STRING=i686-w64-mingw32-gcc-ranlib \ - " - diff --git a/source/build-cmake/params/buildvars_mingw_params_llvm.dat b/source/build-cmake/params/buildvars_mingw_params_llvm.dat deleted file mode 100644 index f4d1b686b..000000000 --- a/source/build-cmake/params/buildvars_mingw_params_llvm.dat +++ /dev/null @@ -1,157 +0,0 @@ -################ -# -# This is build-parameters fo LLVM/MinGW. -# Neither for GCC and LLVM/Linux . -# - -if [ -v CC_SUFFIX ] ; then - CCMAKE_CC=${CCMAKE_CC}-${CC_SUFFIX} - CCMAKE_CXX=${CCMAKE_CXX}-${CC_SUFFIX} -fi -if [ -v CC_PREFIX ] ; then - CCMAKE_CC=${CC_PREFIX}-${CCMAKE_CC} - CCMAKE_CXX=${CC_PREFIX}-${CCMAKE_CXX} -fi -if [ -v CC_PATH ] ; then - CCMAKE_CC=${CC_PATH}/${CCMAKE_CC} - CCMAKE_CXX=${CC_PATH}/${CCMAKE_CXX} -fi - -case ${MAJOR_ARCH} in - "AMD64" | "amd64" | "x86_64" | "X86_64" ) - . ./params/archdef_x86_64.dat - ;; - "IA32" | "ia32" | "x86" | "X86" ) - . ./params/archdef_ia32.dat - ;; - * ) - ARCH_FLAGS="" - ;; -esac - -case ${USE_RADICAL_OPTIMIZE} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3=" \ - -O3 \ - -fvect-cost-model=dynamic -ftree-vectorize \ - -ftree-loop-distribute-patterns \ - -ftree-loop-optimize -ftree-loop-if-convert-stores \ - -fbranch-probabilities -fbranch-target-load-optimize \ - -fselective-scheduling -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops \ - -funroll-loops \ - -fgraphite-identity \ - -floop-nest-optimize \ - ${ARCH_FLAGS} \ - -Wall \ - ${MAKEFLAGS_BASE} \ - " - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_BASE3=" \ - -O2 \ - \ - -ftree-vectorize \ - -funroll-loops \ - ${ARCH_FLAGS} \ - -Wall \ - ${MAKEFLAGS_BASE} \ - " - ;; -esac - -case ${USE_WHOLE_PROGRAM_OPTIMIZE} in - "Yes" | "yes" | "YES" ) - LTO_FLAGS="-fwhole-program" - ;; - * ) - LTO_FLAGS="" - ;; -esac -case ${USE_SANITIZER} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fsanitize=address \ - -fsanitize=undefined \ - -fsanitize=vptr \ - " - ;; - "No" | "no" | "NO" | * ) - ;; -esac - -case ${USE_STACK_PROTECTION} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector \ - " - ;; - "All" | "all" | "ALL" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector-all \ - " - ;; - "Strong" | "strong" | "STRONG" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fstack-protector-strong \ - " - ;; - "No" | "no" | "NO" ) - MAKEFLAGS_BASE3="${MAKEFLAGS_BASE3} \ - -fno-stack-protector \ - " - ;; - "Default" | "default" | "DEFAULT" | * ) - ;; -esac - -case ${COMPRESS_SYMBOLS} in - "Yes" | "yes" | "YES" ) - COMPRESS_CFLAGS="-gz" - ;; - "No" | "no" | "NO" | * ) - COMPRESS_CFLAGS="" - ;; -esac - -case ${CSP_DEBUG} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_BASE2="-g -ggdb ${MAKEFLAGS_BASE} -DNDEBUG" - MAKEFLAGS_LINK_BASE="-g -ggdb ${MAKEFLAGS_BASE}" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_BASE2="-O3 ${MAKEFLAGS_BASE} -DNDEBUG \ - -std=c++0x \ - -Wreserved-user-defined-literal \ - -D_HAS_EXCEPTIONS \ - -D__float128=\"long double\" - " - MAKEFLAGS_LINK_BASE="-s ${MAKEFLAGS_BASE}" - ;; -esac - -case ${USE_LTO} in - "Yes" | "yes" | "YES" ) - MAKEFLAGS_LINK_BASE2="-flto=${LTO_THREADS} ${LTO_FLAGS} ${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="-flto -ffat-lto-objects ${MAKEFLAGS_BASE2}" - ;; - "No" | "no" | "NO" | * ) - MAKEFLAGS_LINK_BASE2="${MAKEFLAGS_BASE2}" - MAKEFLAGS_BASE2="${MAKEFLAGS_BASE2}" - ;; -esac -case ${USE_OPENMP} in - "Yes" | "yes" | "YES" ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=YES" - ;; - "No" | "no" | "NO" | * ) - CMAKE_APPENDFLAG="${CMAKE_APPENDFLAG} -DUSE_OPENMP=NO" - ;; -esac - -CMAKE_APPENDFLAG="-DUSE_QT5_4_APIS=ON -DUSE_MOVIE_LOADER=ON \ - -DUSE_MOVIE_SAVER=ON \ - -DCMAKE_AR:STRING=llvm-ar \ - -DCMAKE_LD:STRING=i686-w64-mingw32-ld \ - -DCMAKE_NM:STRING=llvm-nm \ - -DCMAKE_RANLIB:STRING=llvm-ranlib \ - " diff --git a/source/build-cmake/pasopia/CMakeLists.txt b/source/build-cmake/pasopia/CMakeLists.txt deleted file mode 100644 index c85e405e0..000000000 --- a/source/build-cmake/pasopia/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupasopia) - -set(BUILD_PASOPIA ON CACHE BOOL "Build for PASOPIA") - -include(config_emupasopia) - - diff --git a/source/build-cmake/pasopia7/CMakeLists.txt b/source/build-cmake/pasopia7/CMakeLists.txt deleted file mode 100644 index 8e0198528..000000000 --- a/source/build-cmake/pasopia7/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupasopia7) - -set(BUILD_PASOPIA7 ON CACHE BOOL "Build for PASOPIA7") - -include(config_emupasopia) diff --git a/source/build-cmake/pasopia7_lcd/CMakeLists.txt b/source/build-cmake/pasopia7_lcd/CMakeLists.txt deleted file mode 100644 index e1f7e62f0..000000000 --- a/source/build-cmake/pasopia7_lcd/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupasopia7_lcd) -set(BUILD_PASOPIA7_LCD ON CACHE BOOL "Build for PASOPIA7 with LCD") - -include(config_emupasopia) diff --git a/source/build-cmake/pasopia_lcd/CMakeLists.txt b/source/build-cmake/pasopia_lcd/CMakeLists.txt deleted file mode 100644 index 1d279b6b2..000000000 --- a/source/build-cmake/pasopia_lcd/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupasopia_lcd) - -set(BUILD_PASOPIA_LCD ON CACHE BOOL "Build for PASOPIA with LCD") - -include(config_emupasopia) diff --git a/source/build-cmake/pc100/CMakeLists.txt b/source/build-cmake/pc100/CMakeLists.txt deleted file mode 100644 index a8c67bb9b..000000000 --- a/source/build-cmake/pc100/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,NEC PC-100, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (pc100) -set(VM_NAME pc100) -set(USE_FMGEN ON) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(VMFILES - i286.cpp - msm58321.cpp - - memory.cpp - event.cpp - io.cpp -) -set(VMFILES_LIB - beep.cpp - and.cpp - i8251.cpp - i8255.cpp - i8259.cpp - msm58321_base.cpp - noise.cpp - pcm1bit.cpp - upd765a.cpp - disk.cpp -) -set(FLAG_USE_I86 OFF) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_PC100) -set(EXEC_TARGET emupc100) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc100.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/pc2001/CMakeLists.txt b/source/build-cmake/pc2001/CMakeLists.txt deleted file mode 100644 index 698048447..000000000 --- a/source/build-cmake/pc2001/CMakeLists.txt +++ /dev/null @@ -1,45 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,NEC PC-100, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (pc2001) -set(VM_NAME pc2001) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE OFF) -set(WITH_DEBUGGER ON) - -set(VMFILES - memory.cpp - event.cpp -) -set(VMFILES_LIB - datarec.cpp - noise.cpp - pcm1bit.cpp - upd16434.cpp - upd1990a.cpp - upd7907.cpp -) -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER OFF CACHE BOOL "Build with debugger") -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_PC2001) -set(EXEC_TARGET emupc2001) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pc2001.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/pc6001/CMakeLists.txt b/source/build-cmake/pc6001/CMakeLists.txt deleted file mode 100644 index bfb0aad6f..000000000 --- a/source/build-cmake/pc6001/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC6001, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupc6001) -set(BUILD_PC6001 ON CACHE BOOL "Build on PC6001") - -include(config_pc6001) diff --git a/source/build-cmake/pc6001mk2/CMakeLists.txt b/source/build-cmake/pc6001mk2/CMakeLists.txt deleted file mode 100644 index 9e787a7d7..000000000 --- a/source/build-cmake/pc6001mk2/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC6001 mk2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupc6001mk2) -set(BUILD_PC6001MK2 ON CACHE BOOL "Build on PC6001 mk2") - -include(config_pc6001) diff --git a/source/build-cmake/pc6001mk2sr/CMakeLists.txt b/source/build-cmake/pc6001mk2sr/CMakeLists.txt deleted file mode 100644 index 116113d89..000000000 --- a/source/build-cmake/pc6001mk2sr/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC6001mk2SR, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupc6001mk2sr) -set(BUILD_PC6001MK2SR ON CACHE BOOL "Build on PC6001mk2SR") - -include(config_pc6001) diff --git a/source/build-cmake/pc6601/CMakeLists.txt b/source/build-cmake/pc6601/CMakeLists.txt deleted file mode 100644 index 86278b688..000000000 --- a/source/build-cmake/pc6601/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC6601 mk2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc6601) -set(BUILD_PC6601 ON CACHE BOOL "Build on PC6601") - -include(config_pc6001) diff --git a/source/build-cmake/pc6601sr/CMakeLists.txt b/source/build-cmake/pc6601sr/CMakeLists.txt deleted file mode 100644 index 1c4c84a86..000000000 --- a/source/build-cmake/pc6601sr/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC6601SR, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc6601sr) -set(BUILD_PC6601SR ON CACHE BOOL "Build on PC6601SR") - -include(config_pc6001) \ No newline at end of file diff --git a/source/build-cmake/pc8001/CMakeLists.txt b/source/build-cmake/pc8001/CMakeLists.txt deleted file mode 100644 index 50245c791..000000000 --- a/source/build-cmake/pc8001/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8001, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc8001) -set(BUILD_PC8001 ON CACHE BOOL "Build for PC8001") - -include(config_pc8801) diff --git a/source/build-cmake/pc8001mk2/CMakeLists.txt b/source/build-cmake/pc8001mk2/CMakeLists.txt deleted file mode 100644 index 1df301691..000000000 --- a/source/build-cmake/pc8001mk2/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8001mk2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc8001mk2) -set(BUILD_PC8001MK2 ON CACHE BOOL "Build for PC8001mk2") - -include(config_pc8801) diff --git a/source/build-cmake/pc8001sr/CMakeLists.txt b/source/build-cmake/pc8001sr/CMakeLists.txt deleted file mode 100644 index c79d01c79..000000000 --- a/source/build-cmake/pc8001sr/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8001mk2 SR, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc8001sr) -set(BUILD_PC8001SR ON CACHE BOOL "Build for PC8001SR") - -include(config_pc8801) diff --git a/source/build-cmake/pc8201/CMakeLists.txt b/source/build-cmake/pc8201/CMakeLists.txt deleted file mode 100644 index 4233eb7d3..000000000 --- a/source/build-cmake/pc8201/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8201, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupc8201) -set(BUILD_PC8201 ON CACHE BOOL "Build on PC8201") - -include(config_pc8201) diff --git a/source/build-cmake/pc8201a/CMakeLists.txt b/source/build-cmake/pc8201a/CMakeLists.txt deleted file mode 100644 index 86b1bcff7..000000000 --- a/source/build-cmake/pc8201a/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8201A, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupc8201a) -set(BUILD_PC8201A ON CACHE BOOL "Build on PC8201A") - -include(config_pc8201) diff --git a/source/build-cmake/pc8801/CMakeLists.txt b/source/build-cmake/pc8801/CMakeLists.txt deleted file mode 100644 index d376fa222..000000000 --- a/source/build-cmake/pc8801/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8801, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emupc8801) - -set(BUILD_PC8801 ON CACHE BOOL "Build with PC8801") - -include(config_pc8801) \ No newline at end of file diff --git a/source/build-cmake/pc8801ma/CMakeLists.txt b/source/build-cmake/pc8801ma/CMakeLists.txt deleted file mode 100644 index 008e2cba7..000000000 --- a/source/build-cmake/pc8801ma/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8801MA, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emupc8801ma) - -set(BUILD_PC8801MA ON CACHE BOOL "Build with PC8801MA") - -include(config_pc8801) \ No newline at end of file diff --git a/source/build-cmake/pc8801mk2/CMakeLists.txt b/source/build-cmake/pc8801mk2/CMakeLists.txt deleted file mode 100644 index e95b29c40..000000000 --- a/source/build-cmake/pc8801mk2/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC8801mk2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emupc8801mk2) - -set(BUILD_PC8801MK2 ON CACHE BOOL "Build with PC8801mk2") - -include(config_pc8801) \ No newline at end of file diff --git a/source/build-cmake/pc9801/CMakeLists.txt b/source/build-cmake/pc9801/CMakeLists.txt deleted file mode 100644 index dbdd550da..000000000 --- a/source/build-cmake/pc9801/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC9801, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emupc9801) - -set(BUILD_PC9801 ON CACHE BOOL "Build on PC9801") -include(config_emupc9801) diff --git a/source/build-cmake/pc9801e/CMakeLists.txt b/source/build-cmake/pc9801e/CMakeLists.txt deleted file mode 100644 index 27aa2cfdb..000000000 --- a/source/build-cmake/pc9801e/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC9801E, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc9801e) -set(BUILD_PC9801E ON CACHE BOOL "Build on PC9801E") -include(config_emupc9801) diff --git a/source/build-cmake/pc9801ra/CMakeLists.txt b/source/build-cmake/pc9801ra/CMakeLists.txt deleted file mode 100644 index 67fc98ce6..000000000 --- a/source/build-cmake/pc9801ra/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC9801RA, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc9801ra) - -set(BUILD_PC9801RA ON CACHE BOOL "Build on PC9801RA") -include(config_emupc9801) diff --git a/source/build-cmake/pc9801u/CMakeLists.txt b/source/build-cmake/pc9801u/CMakeLists.txt deleted file mode 100644 index 9bdafb26c..000000000 --- a/source/build-cmake/pc9801u/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC9801U, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc9801u) - -set(BUILD_PC9801U ON CACHE BOOL "Build on PC9801U") -include(config_emupc9801) - diff --git a/source/build-cmake/pc9801vf/CMakeLists.txt b/source/build-cmake/pc9801vf/CMakeLists.txt deleted file mode 100644 index 4cf33249c..000000000 --- a/source/build-cmake/pc9801vf/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC9801VF, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupc9801vf) - -set(BUILD_PC9801VF ON CACHE BOOL "Build on PC9801VF") -include(config_emupc9801) diff --git a/source/build-cmake/pc9801vm/CMakeLists.txt b/source/build-cmake/pc9801vm/CMakeLists.txt deleted file mode 100644 index a132c8943..000000000 --- a/source/build-cmake/pc9801vm/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC9801VM, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc9801vm) - -set(BUILD_PC9801VM ON CACHE BOOL "Build on PC9801VM") -include(config_emupc9801) diff --git a/source/build-cmake/pc9801vx/CMakeLists.txt b/source/build-cmake/pc9801vx/CMakeLists.txt deleted file mode 100644 index f0cfe37ac..000000000 --- a/source/build-cmake/pc9801vx/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC9801VX, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc9801vx) - -set(BUILD_PC9801VX ON CACHE BOOL "Build on PC9801VX") -include(config_emupc9801) diff --git a/source/build-cmake/pc98do/CMakeLists.txt b/source/build-cmake/pc98do/CMakeLists.txt deleted file mode 100644 index 357195bac..000000000 --- a/source/build-cmake/pc98do/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC98DO, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc98DO) - -set(BUILD_PC98DO ON CACHE BOOL "Build on PC98DO") -include(config_emupc9801) diff --git a/source/build-cmake/pc98ha/CMakeLists.txt b/source/build-cmake/pc98ha/CMakeLists.txt deleted file mode 100644 index cac7fd560..000000000 --- a/source/build-cmake/pc98ha/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC98 HA, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupc98ha) -set(BUILD_PC98HA ON CACHE BOOL "Build on PC98 HA") - -include(config_pc98ha) diff --git a/source/build-cmake/pc98lt/CMakeLists.txt b/source/build-cmake/pc98lt/CMakeLists.txt deleted file mode 100644 index c225fd951..000000000 --- a/source/build-cmake/pc98lt/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC98 LT, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc98lt) -set(BUILD_PC98LT ON CACHE BOOL "Build on PC98 LT") - -include(config_pc98ha) diff --git a/source/build-cmake/pc98rl/CMakeLists.txt b/source/build-cmake/pc98rl/CMakeLists.txt deleted file mode 100644 index 579423c3c..000000000 --- a/source/build-cmake/pc98rl/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC98RL, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc98rl) - -set(BUILD_PC98RL ON CACHE BOOL "Build on PC98RL") -include(config_emupc9801) diff --git a/source/build-cmake/pc98xl/CMakeLists.txt b/source/build-cmake/pc98xl/CMakeLists.txt deleted file mode 100644 index 31a14b555..000000000 --- a/source/build-cmake/pc98xl/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,PC98XL, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupc98xl) - -set(BUILD_PC98XL ON CACHE BOOL "Build on PC98XL") -include(config_emupc9801) diff --git a/source/build-cmake/pcengine/CMakeLists.txt b/source/build-cmake/pcengine/CMakeLists.txt deleted file mode 100644 index 22b710e14..000000000 --- a/source/build-cmake/pcengine/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MZ-1500, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupcengine) -set(VM_NAME pcengine) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(VMFILES_BASE - huc6280.cpp - scsi_host.cpp - scsi_dev.cpp - scsi_cdrom.cpp - - event.cpp - io.cpp - memory.cpp -) -set(VMFILES_LIB - huc6280_base.cpp - msm5205.cpp -# scsi_cdrom.cpp -# scsi_dev_base.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_PCENGINE) -set(EXEC_TARGET emupcengine) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pcengine.qrc) -include(config_commonsource) diff --git a/source/build-cmake/phc20/CMakeLists.txt b/source/build-cmake/phc20/CMakeLists.txt deleted file mode 100644 index 3ceaee669..000000000 --- a/source/build-cmake/phc20/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SANYO PHC-20, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (phc20) -set(VM_NAME phc20) -set(USE_FMGEN OFF) -set(FLAG_USE_Z80 ON) -set(VMFILES - mc6847.cpp - event.cpp -) -set(VMFILES_LIB - mc6847_base.cpp - noise.cpp - datarec.cpp -) -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debigger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_PHC20) -set(EXEC_TARGET emuphc20) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/phc20.qrc) -include(config_commonsource) diff --git a/source/build-cmake/phc25/CMakeLists.txt b/source/build-cmake/phc25/CMakeLists.txt deleted file mode 100644 index e02526301..000000000 --- a/source/build-cmake/phc25/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SEIKO MAP1010, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (phc25) -set(BUILD_PHC25 ON CACHE BOOL "Build ePHC25") - -include(config_phc25) - diff --git a/source/build-cmake/pv1000/CMakeLists.txt b/source/build-cmake/pv1000/CMakeLists.txt deleted file mode 100644 index 9629c460e..000000000 --- a/source/build-cmake/pv1000/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,CASIO PV-1000, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (pv1000) -set(VM_NAME pv1000) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) -set(FLAG_USE_Z80 ON) -set(VMFILES - io.cpp - memory.cpp - - event.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_PV1000) -set(EXEC_TARGET emupv1000) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pv1000.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/pv2000/CMakeLists.txt b/source/build-cmake/pv2000/CMakeLists.txt deleted file mode 100644 index 7a3ce303f..000000000 --- a/source/build-cmake/pv2000/CMakeLists.txt +++ /dev/null @@ -1,44 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,CASIO PV-2000, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (pv2000) -set(VM_NAME pv2000) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(FLAG_USE_Z80 ON) -set(VMFILES - io.cpp - memory.cpp - event.cpp -) -set(VMFILES_LIB - sn76489an.cpp - tms9918a.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_PV2000) -set(EXEC_TARGET emupv2000) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pv2000.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/px7/CMakeLists.txt b/source/build-cmake/px7/CMakeLists.txt deleted file mode 100644 index 4ba4cb3c8..000000000 --- a/source/build-cmake/px7/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,MSX2, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emupx7) -set(EXEC_TARGET emupx7) -set(VM_NAME msx) -set(USE_FMGEN ON) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(BUILD_PX7 ON CACHE BOOL "Build for Pioneer PX7") -set(BUILD_MSX1 OFF CACHE BOOL "Build for MSX1") -set(BUILD_MSX2 OFF CACHE BOOL "Build for MSX2") -set(BUILD_MSX2PLUS OFF CACHE BOOL "Build for MSX2+") -set(BUILD_HX20 OFF CACHE BOOL "Build for Toshiba HX-20") -set(BUILD_FSA1 OFF CACHE BOOL "Build for Panasonic FS-A1") -set(BUILD_HBF1XDJ OFF CACHE BOOL "Build for Sony HB-F1XDJ") - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(config_msx) diff --git a/source/build-cmake/pyuta/CMakeLists.txt b/source/build-cmake/pyuta/CMakeLists.txt deleted file mode 100644 index fb3eb4db1..000000000 --- a/source/build-cmake/pyuta/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject, TOMY Pyuta, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emupyuta) -set(VM_NAME pyuta) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(VMFILES_BASE - tms9995.cpp - event.cpp - memory.cpp -) -set(VMFILES_LIB - datarec.cpp - noise.cpp - sn76489an.cpp - tms9918a.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_PYUTA) -set(EXEC_TARGET emupyuta) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/pyuta.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/qc10/CMakeLists.txt b/source/build-cmake/qc10/CMakeLists.txt deleted file mode 100644 index e01cdb957..000000000 --- a/source/build-cmake/qc10/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,QC-10(Monochrome), Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emuqc10) -set(BUILD_QC10 ON CACHE BOOL "Build emuqc10 (Monochrome)") - -include(config_qc10) diff --git a/source/build-cmake/qc10cms/CMakeLists.txt b/source/build-cmake/qc10cms/CMakeLists.txt deleted file mode 100644 index a648ad078..000000000 --- a/source/build-cmake/qc10cms/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Build Common Sourcecode Project, Agar. -# (C) 2014 K.Ohta -# This is part of , but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,QC-10 (COLOR), Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -project (emuqc10cms) -set(BUILD_QC10COLOR ON CACHE BOOL "Build emuqc10_cms") - -include(config_qc10) diff --git a/source/build-cmake/rx78/CMakeLists.txt b/source/build-cmake/rx78/CMakeLists.txt deleted file mode 100644 index cdd4987a1..000000000 --- a/source/build-cmake/rx78/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,BANDAI RX-78, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (rx78) -set(VM_NAME rx78) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES - io.cpp - event.cpp -) -set(VMFILES_LIB - datarec.cpp - noise.cpp - sn76489an.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_RX78) -set(EXEC_TARGET emurx78) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/rx78.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/sc3000/CMakeLists.txt b/source/build-cmake/sc3000/CMakeLists.txt deleted file mode 100644 index 3ffd888b1..000000000 --- a/source/build-cmake/sc3000/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SEGA SC-3000, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (sc3000) -set(VM_NAME sc3000) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES - io.cpp - event.cpp -) - -set(VMFILES_LIB - datarec.cpp - i8251.cpp - i8255.cpp - noise.cpp - sn76489an.cpp - tms9918a.cpp - upd765a.cpp - disk.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_SC3000) -set(EXEC_TARGET emusc3000) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/sc3000.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/scv/CMakeLists.txt b/source/build-cmake/scv/CMakeLists.txt deleted file mode 100644 index f8cd0c00a..000000000 --- a/source/build-cmake/scv/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,EPOCH Super Casette Vision, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (scv) -set(VM_NAME scv) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK ON) -set(WITH_MOUSE OFF) - -set(VMFILES - event.cpp -) -set(VMFILES_LIB - upd7801.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger") - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -add_definitions(-D_SCV) -set(EXEC_TARGET emuscv) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/scv.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/smb80te/CMakeLists.txt b/source/build-cmake/smb80te/CMakeLists.txt deleted file mode 100644 index 6777c6886..000000000 --- a/source/build-cmake/smb80te/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SM-B-80TE, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuemb80te) -set(EXEC_TARGET emusmb80te) -set(VM_NAME smb80te) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - io.cpp - event.cpp -) - -set(VMFILES_LIB - datarec.cpp - not.cpp - noise.cpp - z80pio.cpp -) - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_SMB80TE) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/smb80te.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/smc70/CMakeLists.txt b/source/build-cmake/smc70/CMakeLists.txt deleted file mode 100644 index fe17ee07f..000000000 --- a/source/build-cmake/smc70/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SONY SMC-70, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emusmc70) -set(BUILD_SMC70 ON CACHE BOOL "Build SMC-70") -include(config_smc777) diff --git a/source/build-cmake/smc777/CMakeLists.txt b/source/build-cmake/smc777/CMakeLists.txt deleted file mode 100644 index 00cf1e46a..000000000 --- a/source/build-cmake/smc777/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SONY SMC-777, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emusmc777) -set(BUILD_SMC777 ON CACHE BOOL "Build SMC-777") - -include(config_smc777) diff --git a/source/build-cmake/tk80bs/CMakeLists.txt b/source/build-cmake/tk80bs/CMakeLists.txt deleted file mode 100644 index 69de9d4b6..000000000 --- a/source/build-cmake/tk80bs/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,TK-80 BS, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emutk80bs) - -set(BUILD_TK80BS ON CACHE BOOL "Build for TK-80 BS") -set(BUILD_TK80 OFF CACHE BOOL "Build for TK-80") -set(BUILD_TK85 OFF CACHE BOOL "Build for TK-85") - -include(config_tk80) \ No newline at end of file diff --git a/source/build-cmake/tk85/CMakeLists.txt b/source/build-cmake/tk85/CMakeLists.txt deleted file mode 100644 index 5195d4df2..000000000 --- a/source/build-cmake/tk85/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,TK-80 BS, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emutk80bs) - -set(BUILD_TK80BS OFF CACHE BOOL "Build for TK-80 BS") -set(BUILD_TK80 OFF CACHE BOOL "Build for TK-80") -set(BUILD_TK85 ON CACHE BOOL "Build for TK-85") - -include(config_tk80) \ No newline at end of file diff --git a/source/build-cmake/x07/CMakeLists.txt b/source/build-cmake/x07/CMakeLists.txt deleted file mode 100644 index dfde87a4e..000000000 --- a/source/build-cmake/x07/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,CANON X07, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emux07) - -set(VM_NAME x07) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - - event.cpp - memory.cpp -) -set(VMFILES_LIB - beep.cpp -) - -set(BUILD_SHARED_LIBS OFF) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - -include(detect_target_cpu) -#include(windows-mingw-cross) -# set entry -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - - -set(VMFILES ${VMFILES_BASE}) -add_definitions(-D_X07) -set(EXEC_TARGET emux07) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/x07.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/x1/CMakeLists.txt b/source/build-cmake/x1/CMakeLists.txt deleted file mode 100644 index 611249590..000000000 --- a/source/build-cmake/x1/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,X1, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emux1) - -set(BUILD_X1 ON CACHE BOOL "Build for X1") - -include(config_x1) - diff --git a/source/build-cmake/x1/dummy.c b/source/build-cmake/x1/dummy.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/source/build-cmake/x1turbo/CMakeLists.txt b/source/build-cmake/x1turbo/CMakeLists.txt deleted file mode 100644 index 192c1c2a5..000000000 --- a/source/build-cmake/x1turbo/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,X1 Turbo, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emux1turbo) - -set(BUILD_X1TURBO ON CACHE BOOL "Build for X1 Turbo") -include(config_x1) - diff --git a/source/build-cmake/x1turboz/CMakeLists.txt b/source/build-cmake/x1turboz/CMakeLists.txt deleted file mode 100644 index c398fdbaa..000000000 --- a/source/build-cmake/x1turboz/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,X1 TurboZ, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emux1turboz) - -set(BUILD_X1TURBOZ ON CACHE BOOL "Build for X1 TurboZ") -include(config_x1) diff --git a/source/build-cmake/x1twin/CMakeLists.txt b/source/build-cmake/x1twin/CMakeLists.txt deleted file mode 100644 index 1cb429db5..000000000 --- a/source/build-cmake/x1twin/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,X1 Twin, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emux1twin) - -set(BUILD_X1TWIN ON CACHE BOOL "Build for X1 Twin") -include(config_x1) diff --git a/source/build-cmake/yalky/CMakeLists.txt b/source/build-cmake/yalky/CMakeLists.txt deleted file mode 100644 index 4049b91f1..000000000 --- a/source/build-cmake/yalky/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject, Yuasa Kyouiku System YALKY, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emuyalky) - -set(EXEC_TARGET emuyalky) -set(VM_NAME yalky) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) -set(WITH_DEBUGGER ON) - -set(VMFILES_BASE - i8080.cpp - memory.cpp - event.cpp -) - -set(VMFILES_LIB - datarec.cpp - i8080_base.cpp - i8155.cpp - noise.cpp - not.cpp -) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) - -add_definitions(-D_YALKY) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/yalky.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/yis/CMakeLists.txt b/source/build-cmake/yis/CMakeLists.txt deleted file mode 100644 index bc3e019fc..000000000 --- a/source/build-cmake/yis/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject, YAMAHA YIS, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - -project (emuyis) - -set(EXEC_TARGET emuyis) -set(VM_NAME yis) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) -set(WITH_DEBUGGER ON) - -set(VMFILES_BASE - msm58321.cpp - m6502.cpp - io.cpp - memory.cpp - event.cpp -) - -set(VMFILES_LIB - am9511.cpp - beep.cpp - disk.cpp - m6502_base.cpp - mb8877.cpp - mc6820.cpp - mc6844.cpp - mc6850.cpp - msm58321_base.cpp - noise.cpp -) -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER ON CACHE BOOL "Build with debugger.") - - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) - -add_definitions(-D_YIS) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/yis.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/ys6464a/CMakeLists.txt b/source/build-cmake/ys6464a/CMakeLists.txt deleted file mode 100644 index 72eb48889..000000000 --- a/source/build-cmake/ys6464a/CMakeLists.txt +++ /dev/null @@ -1,49 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,SHINKO SANGYOU YS6464A, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuys6464a) - -set(EXEC_TARGET emuys6464a) -set(VM_NAME ys6464a) -set(USE_FMGEN OFF) -set(WITH_JOYSTICK OFF) -set(WITH_MOUSE ON) - -set(FLAG_USE_Z80 ON) -set(VMFILES_BASE - i8255.cpp - - io.cpp - memory.cpp - - event.cpp -) - - -set(USE_OPENMP ON CACHE BOOL "Build using OpenMP") -set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") -set(WITH_DEBUGGER OFF CACHE BOOL "Build with debugger.") - - -include(detect_target_cpu) -set(CMAKE_SYSTEM_PROCESSOR ${ARCHITECTURE} CACHE STRING "Set processor to build.") - -set(VMFILES ${VMFILES_BASE}) - -add_definitions(-D_YS6464A) -add_definitions(-DWITHOUT_SOUND) -set(RESOURCE ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/ys6464a.qrc) - -include(config_commonsource) diff --git a/source/build-cmake/z80tvgame_i8255/CMakeLists.txt b/source/build-cmake/z80tvgame_i8255/CMakeLists.txt deleted file mode 100644 index a98434a52..000000000 --- a/source/build-cmake/z80tvgame_i8255/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Z80 TV Game i8255 version, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") - - -project (emuz80tvgame_i8255) - -set(BUILD_I8255 ON CACHE BOOL "Build I8255 version") - -include(config_z80tvgame) diff --git a/source/build-cmake/z80tvgame_z80pio/CMakeLists.txt b/source/build-cmake/z80tvgame_z80pio/CMakeLists.txt deleted file mode 100644 index b294e3df4..000000000 --- a/source/build-cmake/z80tvgame_z80pio/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Build Common Sourcecode Project, Qt. -# (C) 2014 K.Ohta -# This is part of XM7/SDL, but license is apache 2.2, -# this part was written only me. - -cmake_minimum_required (VERSION 2.8) -cmake_policy(SET CMP0011 NEW) - -message("") -message("** Start of configure CommonSourceProject,Z80 TV Game Z80PIO version, Qt **") -message("") - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/../cmake") -set(BUILD_Z80PIO ON CACHE BOOL "Build Z80 PIO version") - -include(config_z80tvgame) diff --git a/source/build-cmake/3rdparty/CompressExeWithUpx.cmake b/source/cmake/3rdparty/CompressExeWithUpx.cmake similarity index 100% rename from source/build-cmake/3rdparty/CompressExeWithUpx.cmake rename to source/cmake/3rdparty/CompressExeWithUpx.cmake diff --git a/source/build-cmake/3rdparty/FindIconv.cmake b/source/cmake/3rdparty/FindIconv.cmake similarity index 100% rename from source/build-cmake/3rdparty/FindIconv.cmake rename to source/cmake/3rdparty/FindIconv.cmake diff --git a/source/build-cmake/3rdparty/FindIconv.patch b/source/cmake/3rdparty/FindIconv.patch similarity index 100% rename from source/build-cmake/3rdparty/FindIconv.patch rename to source/cmake/3rdparty/FindIconv.patch diff --git a/source/cmake/3rdparty/FindLibAV.cmake b/source/cmake/3rdparty/FindLibAV.cmake new file mode 100644 index 000000000..f68fc4b60 --- /dev/null +++ b/source/cmake/3rdparty/FindLibAV.cmake @@ -0,0 +1,202 @@ +# Module for locating libav. +# +# Customizable variables: +# LIBAV_ROOT_DIR +# Specifies libav's root directory. +# +# Read-only variables: +# LIBAV_FOUND +# Indicates whether the library has been found. +# +# LIBAV_INCLUDE_DIRS +# Specifies libav's include directory. +# +# LIBAV_LIBRARIES +# Specifies libav libraries that should be passed to target_link_libararies. +# +# LIBAV__LIBRARIES +# Specifies the libraries of a specific . +# +# LIBAV__FOUND +# Indicates whether the specified was found. +# +# +# Copyright (c) 2012 Sergiu Dotenco +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTLIBAVLAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# From: https://github.com/bitmovin/libdash/blob/master/libdash/qtsampleplayer/FindLibAV.cmake +INCLUDE (FindPackageHandleStandardArgs) + +IF (CMAKE_VERSION VERSION_GREATER 2.8.7) + SET (_LIBAV_CHECK_COMPONENTS FALSE) +ELSE (CMAKE_VERSION VERSION_GREATER 2.8.7) + SET (_LIBAV_CHECK_COMPONENTS TRUE) +ENDIF (CMAKE_VERSION VERSION_GREATER 2.8.7) + +FIND_PATH (LIBAV_ROOT_DIR + NAMES libavcodec/avcodec.h + libavdevice/avdevice.h + libavfilter/avfilter.h + libavutil/avutil.h + libswresample/swresample.h + libswscale/swscale.h + PATHS ENV LIBAVROOT + DOC "libav root directory") + +FIND_PATH (LIBAV_INCLUDE_DIR + NAMES libavcodec/avcodec.h + libavdevice/avdevice.h + libavfilter/avfilter.h + libavutil/avutil.h + libswresample/swresample.h + libswscale/swscale.h + HINTS ${LIBAV_ROOT_DIR} + PATH_SUFFIXES include + DOC "libav include directory") + +if (NOT LibAV_FIND_COMPONENTS) + set (LibAV_FIND_COMPONENTS avcodec avdevice avfilter avformat avutil swresample swscale) +endif (NOT LibAV_FIND_COMPONENTS) + +FOREACH (_LIBAV_COMPONENT ${LibAV_FIND_COMPONENTS}) + STRING (TOUPPER ${_LIBAV_COMPONENT} _LIBAV_COMPONENT_UPPER) + SET (_LIBAV_LIBRARY_BASE LIBAV_${_LIBAV_COMPONENT_UPPER}_LIBRARY) + + FIND_LIBRARY (${_LIBAV_LIBRARY_BASE} + NAMES ${_LIBAV_COMPONENT} + HINTS ${LIBAV_ROOT_DIR} + PATH_SUFFIXES bin lib + DOC "libav ${_LIBAV_COMPONENT} library") + + MARK_AS_ADVANCED (${_LIBAV_LIBRARY_BASE}) + + SET (LIBAV_${_LIBAV_COMPONENT_UPPER}_FOUND TRUE) + SET (LibAV_${_LIBAV_COMPONENT}_FOUND ${LIBAV_${_LIBAV_COMPONENT_UPPER}_FOUND}) + + IF (${_LIBAV_LIBRARY_BASE}) + # setup the LIBAV__LIBRARIES variable + SET (LIBAV_${_LIBAV_COMPONENT_UPPER}_LIBRARIES ${${_LIBAV_LIBRARY_BASE}}) + LIST (APPEND LIBAV_LIBRARIES ${LIBAV_${_LIBAV_COMPONENT_UPPER}_LIBRARIES}) + LIST (APPEND _LIBAV_ALL_LIBS ${${_LIBAV_LIBRARY_BASE}}) + ELSE (${_LIBAV_LIBRARY_BASE}) + LIST (APPEND _LIBAV_MISSING_LIBRARIES ${_LIBAV_LIBRARY_BASE}) + ENDIF (${_LIBAV_LIBRARY_BASE}) +ENDFOREACH (_LIBAV_COMPONENT ${LibAV_FIND_COMPONENTS}) + +SET (LIBAV_INCLUDE_DIRS ${LIBAV_INCLUDE_DIR}) + +IF (DEFINED _LIBAV_MISSING_COMPONENTS AND _LIBAV_CHECK_COMPONENTS) + IF (NOT LibAV_FIND_QUIETLY) + MESSAGE (STATUS "One or more libav components were not found:") + # Display missing components indented, each on a separate line + FOREACH (_LIBAV_MISSING_COMPONENT ${_LIBAV_MISSING_COMPONENTS}) + MESSAGE (STATUS " " ${_LIBAV_MISSING_COMPONENT}) + ENDFOREACH (_LIBAV_MISSING_COMPONENT ${_LIBAV_MISSING_COMPONENTS}) + ENDIF (NOT LibAV_FIND_QUIETLY) +ENDIF (DEFINED _LIBAV_MISSING_COMPONENTS AND _LIBAV_CHECK_COMPONENTS) + +# Determine library's version + +FIND_PROGRAM (LIBAV_AVCONV_EXECUTABLE NAMES avconv + HINTS ${LIBAV_ROOT_DIR} + PATH_SUFFIXES bin + DOC "avconv executable") + +IF (LIBAV_AVCONV_EXECUTABLE) + EXECUTE_PROCESS (COMMAND ${LIBAV_AVCONV_EXECUTABLE} -version + OUTPUT_VARIABLE _LIBAV_AVCONV_OUTPUT ERROR_QUIET) + + STRING (REGEX REPLACE ".*avconv[ \t]+([0-9]+\\.[0-9]+\\.[0-9]+).*" "\\1" + LIBAV_VERSION "${_LIBAV_AVCONV_OUTPUT}") + STRING (REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\1" + LIBAV_VERSION_MAJOR "${LIBAV_VERSION}") + STRING (REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\2" + LIBAV_VERSION_MINOR "${LIBAV_VERSION}") + STRING (REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+)" "\\3" + LIBAV_VERSION_PATCH "${LIBAV_VERSION}") + + SET (LIBAV_VERSION_COMPONENTS 3) +ENDIF (LIBAV_AVCONV_EXECUTABLE) + +IF (WIN32) + FIND_PROGRAM (LIB_EXECUTABLE NAMES lib + HINTS "$ENV{VS110COMNTOOLS}/../../VC/bin" + "$ENV{VS100COMNTOOLS}/../../VC/bin" + "$ENV{VS90COMNTOOLS}/../../VC/bin" + "$ENV{VS71COMNTOOLS}/../../VC/bin" + "$ENV{VS80COMNTOOLS}/../../VC/bin" + DOC "Library manager") + + MARK_AS_ADVANCED (LIB_EXECUTABLE) +ENDIF (WIN32) + +MACRO (GET_LIB_REQUISITES LIB REQUISITES) + IF (LIB_EXECUTABLE) + GET_FILENAME_COMPONENT (_LIB_PATH ${LIB_EXECUTABLE} PATH) + + EXECUTE_PROCESS (COMMAND ${LIB_EXECUTABLE} /nologo /list ${LIB} + WORKING_DIRECTORY ${_LIB_PATH}/../../Common7/IDE + OUTPUT_VARIABLE _LIB_OUTPUT ERROR_QUIET) + + STRING (REPLACE "\n" ";" "${REQUISITES}" "${_LIB_OUTPUT}") + LIST (REMOVE_DUPLICATES ${REQUISITES}) + ENDIF (LIB_EXECUTABLE) +ENDMACRO (GET_LIB_REQUISITES) + +IF (_LIBAV_ALL_LIBS) + # collect lib requisites using the lib tool + FOREACH (_LIBAV_COMPONENT ${_LIBAV_ALL_LIBS}) + GET_LIB_REQUISITES (${_LIBAV_COMPONENT} _LIBAV_REQUISITES) + ENDFOREACH (_LIBAV_COMPONENT) +ENDIF (_LIBAV_ALL_LIBS) + +IF (NOT LIBAV_BINARY_DIR) + SET (_LIBAV_UPDATE_BINARY_DIR TRUE) +ELSE (NOT LIBAV_BINARY_DIR) + SET (_LIBAV_UPDATE_BINARY_DIR FALSE) +ENDIF (NOT LIBAV_BINARY_DIR) + +SET (_LIBAV_BINARY_DIR_HINTS bin) + +IF (_LIBAV_REQUISITES) + FIND_FILE (LIBAV_BINARY_DIR NAMES ${_LIBAV_REQUISITES} + HINTS ${LIBAV_ROOT_DIR} + PATH_SUFFIXES ${_LIBAV_BINARY_DIR_HINTS} NO_DEFAULT_PATH) +ENDIF (_LIBAV_REQUISITES) + +IF (LIBAV_BINARY_DIR AND _LIBAV_UPDATE_BINARY_DIR) + SET (_LIBAV_BINARY_DIR ${LIBAV_BINARY_DIR}) + UNSET (LIBAV_BINARY_DIR CACHE) + + IF (_LIBAV_BINARY_DIR) + GET_FILENAME_COMPONENT (LIBAV_BINARY_DIR ${_LIBAV_BINARY_DIR} PATH) + ENDIF (_LIBAV_BINARY_DIR) +ENDIF (LIBAV_BINARY_DIR AND _LIBAV_UPDATE_BINARY_DIR) + +SET (LIBAV_BINARY_DIR ${LIBAV_BINARY_DIR} CACHE PATH "libav binary directory") + +MARK_AS_ADVANCED (LIBAV_INCLUDE_DIR LIBAV_BINARY_DIR) + +IF (NOT _LIBAV_CHECK_COMPONENTS) + SET (_LIBAV_FPHSA_ADDITIONAL_ARGS HANDLE_COMPONENTS) +ENDIF (NOT _LIBAV_CHECK_COMPONENTS) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS (LibAV REQUIRED_VARS LIBAV_ROOT_DIR + LIBAV_INCLUDE_DIR ${_LIBAV_MISSING_LIBRARIES} VERSION_VAR LIBAV_VERSION + ${_LIBAV_FPHSA_ADDITIONAL_ARGS}) diff --git a/source/build-cmake/3rdparty/SetMSVCDebugPath.cmake b/source/cmake/3rdparty/SetMSVCDebugPath.cmake similarity index 100% rename from source/build-cmake/3rdparty/SetMSVCDebugPath.cmake rename to source/cmake/3rdparty/SetMSVCDebugPath.cmake diff --git a/source/build-cmake/3rdparty/SplitDebugInformation.cmake b/source/cmake/3rdparty/SplitDebugInformation.cmake similarity index 100% rename from source/build-cmake/3rdparty/SplitDebugInformation.cmake rename to source/cmake/3rdparty/SplitDebugInformation.cmake diff --git a/source/build-cmake/3rdparty/findopencl.url.txt b/source/cmake/3rdparty/findopencl.url.txt similarity index 100% rename from source/build-cmake/3rdparty/findopencl.url.txt rename to source/cmake/3rdparty/findopencl.url.txt diff --git a/source/build-cmake/3rdparty/findopencl/FindOpenCL.cmake b/source/cmake/3rdparty/findopencl/FindOpenCL.cmake similarity index 100% rename from source/build-cmake/3rdparty/findopencl/FindOpenCL.cmake rename to source/cmake/3rdparty/findopencl/FindOpenCL.cmake diff --git a/source/build-cmake/3rdparty/findopencl/example/CMakeLists.txt b/source/cmake/3rdparty/findopencl/example/CMakeLists.txt similarity index 100% rename from source/build-cmake/3rdparty/findopencl/example/CMakeLists.txt rename to source/cmake/3rdparty/findopencl/example/CMakeLists.txt diff --git a/source/build-cmake/3rdparty/findopencl/example/example.cpp b/source/cmake/3rdparty/findopencl/example/example.cpp similarity index 100% rename from source/build-cmake/3rdparty/findopencl/example/example.cpp rename to source/cmake/3rdparty/findopencl/example/example.cpp diff --git a/source/cmake/CompressExeWithUpx.cmake b/source/cmake/CompressExeWithUpx.cmake new file mode 120000 index 000000000..4dd7136b7 --- /dev/null +++ b/source/cmake/CompressExeWithUpx.cmake @@ -0,0 +1 @@ +3rdparty/CompressExeWithUpx.cmake \ No newline at end of file diff --git a/source/cmake/FindIconv.cmake b/source/cmake/FindIconv.cmake new file mode 120000 index 000000000..7b952f075 --- /dev/null +++ b/source/cmake/FindIconv.cmake @@ -0,0 +1 @@ +3rdparty/FindIconv.cmake \ No newline at end of file diff --git a/source/cmake/FindLibAV.cmake b/source/cmake/FindLibAV.cmake new file mode 120000 index 000000000..b4e2a824e --- /dev/null +++ b/source/cmake/FindLibAV.cmake @@ -0,0 +1 @@ +3rdparty/FindLibAV.cmake \ No newline at end of file diff --git a/source/cmake/FindOpenCL.cmake b/source/cmake/FindOpenCL.cmake new file mode 120000 index 000000000..6aeaca8da --- /dev/null +++ b/source/cmake/FindOpenCL.cmake @@ -0,0 +1 @@ +3rdparty/findopencl/FindOpenCL.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/PrecompiledHeader.cmake b/source/cmake/PrecompiledHeader.cmake similarity index 100% rename from source/build-cmake/cmake/PrecompiledHeader.cmake rename to source/cmake/PrecompiledHeader.cmake diff --git a/source/cmake/SetMSVCDebugPath.cmake b/source/cmake/SetMSVCDebugPath.cmake new file mode 120000 index 000000000..bd366edcf --- /dev/null +++ b/source/cmake/SetMSVCDebugPath.cmake @@ -0,0 +1 @@ +3rdparty/SetMSVCDebugPath.cmake \ No newline at end of file diff --git a/source/cmake/SplitDebugInformation.cmake b/source/cmake/SplitDebugInformation.cmake new file mode 120000 index 000000000..c5d0940f3 --- /dev/null +++ b/source/cmake/SplitDebugInformation.cmake @@ -0,0 +1 @@ +3rdparty/SplitDebugInformation.cmake \ No newline at end of file diff --git a/source/build-cmake/cmake/compile_gettext_catalogue.cmake b/source/cmake/compile_gettext_catalogue.cmake similarity index 100% rename from source/build-cmake/cmake/compile_gettext_catalogue.cmake rename to source/cmake/compile_gettext_catalogue.cmake diff --git a/source/cmake/config.cmake b/source/cmake/config.cmake new file mode 100644 index 000000000..4016fde9b --- /dev/null +++ b/source/cmake/config.cmake @@ -0,0 +1,542 @@ +# +include(CheckFunctionExists) + +# Still not as one shared lib with win32 +if(WIN32) + set(USING_TOOLCHAIN_GCC_DEBIAN OFF CACHE BOOL "Workaround for Debian's mingw-w64 linker.") +endif() +if(UNIX) + include(GNUInstallDirs) +endif() +# Note: Belows are temporally disabled, not implemented older CMake. +# Check HOST NAME +#cmake_host_system_information(RESULT OSNAME QUERY OS_NAME) +#cmake_host_system_information(RESULT OSVERSION QUERY OS_VERSION) +#cmake_host_system_information(RESULT OSARCH QUERY OS_PLATFORM) +#message("* HOST: OSNAME=" ${OSNAME} " RELEASE=" ${OSVERSION} " ARCH=" ${OSARCH} " OSARCH=" ${CMAKE_LIBRARY_ARCHITECTURE}) + +set(NEED_REPLACE_LIBDIR OFF) +if((UNIX) AND (NOT DEFINED LIBCSP_INSTALL_DIR)) + # Modify LIBDIR if supports MULTI-ARCH. + # ToDo: Another OSs i.e)Fedora + if(EXISTS "/etc/lsb-release") + file(READ "/etc/lsb-release" TMPDATA) + string(TOUPPER "${TMPDATA}" U_TMPDATA) + string(REGEX MATCH "UBUNTU" D_UBUNTU "${U_TMPDATA}") + string(REGEX MATCH "DEBIAN" D_DEBIAN "${U_TMPDATA}") +# message("*BUILD: UBUNTU=" ${D_UBUNTU} " DEBIAN=" ${D_DEBIAN}) + endif() + if(("${D_DEBIAN}" STREQUAL "DEBIAN") OR ("${D_UBUNTU}" STREQUAL "UBUNTU")) + set(NEED_REPLACE_LIBDIR ON) +# elseif(("${OSVERSION}" MATCHES "^.*Debian.*$") OR ("${OSVERSION}" MATCHES "^.*Ubuntu.*$")) +# # Fallback, but this may misdetect OS, by HOST when under DOCKER. +# # Will not use. +# set(NEED_REPLACE_LIBDIR ON) + endif() +endif() +if(NEED_REPLACE_LIBDIR) + set(LIBCSP_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}") + message("* CHANGE LIB_CSP_INSTALL_DIR TO " ${LIBCSP_INSTALL_DIR}) +endif() + + +if(USE_DEVICES_SHARED_LIB) + add_definitions(-DUSE_SHARED_DLL) + add_definitions(-DUSE_SHARED_UI_DLL) + add_definitions(-DUSE_SHARED_DEVICES_DLL) + add_definitions(-DUSE_FIXED_CONFIG) +elseif(WIN32) + add_definitions(-DUSE_SHARED_DLL) + add_definitions(-DUSE_SHARED_UI_DLL) +endif() + +set(USE_FMGEN ON) +set(WITH_DEBUGGER ON) +set(WITH_MOUSE ON) +set(WITH_JOYSTICK ON) + +include(detect_target_cpu) +# set entry + +add_definitions(-D_CONFIGURE_WITH_CMAKE) +#ccache +find_program(USE_CCACHE ccache) +if(USE_CCACHE) + SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) +endif() + +if(WIN32) + FIND_PACKAGE(Qt5Core REQUIRED) +else() + FIND_PACKAGE(Qt5Widgets REQUIRED) +endif() + FIND_PACKAGE(Qt5Gui REQUIRED) + FIND_PACKAGE(Qt5OpenGL REQUIRED) + FIND_PACKAGE(Qt5Network REQUIRED) + include_directories(${Qt5Widgets_INCLUDE_DIRS}) + include_directories(${Qt5Core_INCLUDE_DIRS}) + include_directories(${Qt5Gui_INCLUDE_DIRS}) + include_directories(${Qt5OpenGL_INCLUDE_DIRS}) + include_directories(${Qt5Network_INCLUDE_DIRS}) + add_definitions(-D_USE_OPENGL -DUSE_OPENGL) +if(DEFINED QT5_ROOT_PATH) + SET(CMAKE_FIND_ROOT_PATH ${QT5_ROOT_PATH} ${CMAKE_FIND_ROOT_PATH}) +endif() + +#socket +function(APPEND_SOCKET_FEATURE) + if(${USE_SOCKET_${EXE_NAME}}) + FIND_PACKAGE(Qt5Network REQUIRED) + include_directories(${Qt5Network_INCLUDE_DIRS}) + endif() +endfunction(APPEND_SOCKET_FEATURE) + +SET(USE_QT_5 ON) +set(USE_QT5_4_APIS ON CACHE BOOL "Build with Qt5.4 (or later) APIs if you can.") +set(USE_GCC_OLD_ABI ON CACHE BOOL "Build with older GCC ABIs if you can.") +set(USE_SDL2 ON CACHE BOOL "Build with libSDL2. DIsable is building with libSDL1.") +set(USE_MOVIE_SAVER ON CACHE BOOL "Save screen/audio as MP4 MOVIE. Needs libav .") +set(USE_MOVIE_LOADER ON CACHE BOOL "Load movie from screen for some VMs. Needs libav .") +set(USE_LTO ON CACHE BOOL "Use link-time-optimization to build.") +set(USE_OPENMP OFF CACHE BOOL "Build using OpenMP") +set(USE_OPENGL ON CACHE BOOL "Build using OpenGL") + +#if(USE_LTO) +# include(CheckIPOSupported) +#endif() +add_definitions(-D_USE_QT5) + +if(USE_QT5_4_APIS) + add_definitions(-D_USE_QT_5_4) +else() + #add_definitions(-DQT_NO_VERSION_TAGGING) +endif() + +if(USE_GCC_OLD_ABI) + add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) +else() + add_definitions(-D_GLIBCXX_USE_CXX11_ABI=1) +endif() + +SET(CMAKE_AUTOMOC OFF) +SET(CMAKE_AUTORCC ON) +SET(CMAKE_INCLUDE_CURRENT_DIR ON) + +add_definitions(-D_USE_QT) +add_definitions(-DUSE_QT) +add_definitions(-DQT_MAJOR_VERSION=${Qt5Widgets_VERSION_MAJOR}) +add_definitions(-DQT_MINOR_VERSION=${Qt5Widgets_VERSION_MINOR}) + +if(USE_OPENMP) + find_package(OpenMP) + include_directories(${OPENMP_INCLUDE_PATH}) + if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + endif() +endif() + +#find_package(Threads) +#include_directories(${THREADS_INCLUDE_PATH}) +include(FindThreads) + +include(FindPkgConfig) + +find_package(Git) +if(GIT_FOUND) + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD OUTPUT_VARIABLE __tstr) + string(FIND ${__tstr} "fatal" __notfound) + string(REPLACE "\n" "" __tstr2 ${__tstr}) + if(${__notfound} EQUAL -1) + add_definitions(-D__GIT_REPO_VERSION=\"${__tstr2}\") + else() + add_definitions(-U__GIT_REPO_VERSION) + endif() +endif() + +string(TIMESTAMP __build_date "%b %d,%Y %H:%M:%S UTC" UTC) +add_definitions(-D__BUILD_DATE=\"${__build_date}\") + +include(FindLibAV) + if(LIBAV_FOUND) + add_definitions(-DUSE_LIBAV) + if(USE_MOVIE_SAVER) + add_definitions(-DUSE_MOVIE_SAVER) + endif() + if(USE_MOVIE_LOADER) + add_definitions(-DUSE_MOVIE_LOADER) + endif() + add_definitions(-D__STDC_CONSTANT_MACROS) + add_definitions(-D__STDC_FORMAT_MACROS) + else() + set(USE_MOVIE_SAVER OFF) + set(USE_MOVIE_LOADER OFF) + set(LIBAV_LIBRARIES "") + endif() + +if(USE_SDL2) + if(CMAKE_CROSSCOMPILING) + include_directories(${SDL2_INCLUDE_DIRS}) + else() + pkg_search_module(SDL2 REQUIRED sdl2) + include_directories(${SDL2_INCLUDE_DIRS}) + endif() + set(SDL_LIBS ${SDL2_LIBRARIES}) + add_definitions(-DUSE_SDL2) +else() + if(CMAKE_CROSSCOMPILING) + include_directories(${SDL_INCLUDE_DIRS}) + set(SDL_LIBS ${SDL_LIBRARIES}) + else() + include(FindSDL) + #pkg_search_module(SDL REQUIRED sdl) + #include_directories(${SDL_INCLUDE_DIRS}) + include_directories(${SDL_INCLUDE_DIR}) + set(SDL_LIBS ${SDL_LIBRARY}) + endif() +endif() + +include(FindZLIB) +if(ZLIB_FOUND) + add_definitions(-DUSE_ZLIB) + include_directories(${ZLIB_INCLUDE_DIRS}) +endif() + +# GCC Only? +if(CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flax-vector-conversions") +endif() + +if(CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -flax-vector-conversions") +endif() + + +check_function_exists("nanosleep" HAVE_NANOSLEEP) +if(NOT HAVE_NANOSLEEP) + check_library_exists("rt" "nanosleep" "" LIB_RT_HAS_NANOSLEEP) +endif(NOT HAVE_NANOSLEEP) + +if(LIB_RT_HAS_NANOSLEEP) + add_target_library(${EXEC_TARGET} rt) +endif(LIB_RT_HAS_NANOSLEEP) + +if(HAVE_NANOSLEEP OR LIB_RT_HAS_NANOSLEEP) + add_definitions(-DHAVE_NANOSLEEP) +endif(HAVE_NANOSLEEP OR LIB_RT_HAS_NANOSLEEP) + + +set(SRC_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../src) + +if(USE_QT_5) + if(NOT WIN32) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + endif() +endif() + +#include(simd-x86) + +if(LIBAV_FOUND) + include_directories(${LIBAV_INCLUDE_DIRS}) +endif() + +# Now make DLLs +include_directories( + "${PROJECT_SOURCE_DIR}/src" + "${PROJECT_SOURCE_DIR}/src/vm" + "${PROJECT_SOURCE_DIR}/src/qt/common" + "${PROJECT_SOURCE_DIR}/src/qt/gui" + "${PROJECT_SOURCE_DIR}/src/qt/debugger" + "${PROJECT_SOURCE_DIR}/src/qt" +) + +# Additional flags from toolchain. +function(additional_link_options n_target) + string(TOUPPER "${CMAKE_BUILD_TYPE}" U_BUILD_TYPE) + if("${U_BUILD_TYPE}" STREQUAL "RELWITHDEBINFO") + if(DEFINED CSP_ADDTIONAL_FLAGS_LINK_RELWITHDEBINFO) + target_link_options(${n_target} + PRIVATE ${CSP_ADDTIONAL_FLAGS_COMPILE_RELWITHDEBINFO} + ) + endif() + elseif("${U_BUILD_TYPE}" STREQUAL "RELEASE") + if(DEFINED CSP_ADDTIONAL_FLAGS_LINK_RELEASE) + target_link_options(${n_target} + PRIVATE ${CSP_ADDTIONAL_FLAGS_COMPILE_RELEASE} + ) + endif() + elseif("${U_BUILD_TYPE}" STREQUAL "DEBUG") + if(DEFINED CSP_ADDTIONAL_FLAGS_LINK_DEBUG) + target_link_options(${n_target} + PRIVATE ${CSP_ADDTIONAL_FLAGS_COMPILE_DEBUG} + ) + endif() + endif() +endfunction(additional_link_options) + +function(additional_options n_target) + string(TOUPPER "${CMAKE_BUILD_TYPE}" U_BUILD_TYPE) + if("${U_BUILD_TYPE}" STREQUAL "RELWITHDEBINFO") + if(DEFINED CSP_ADDTIONAL_FLAGS_COMPILE_RELWITHDEBINFO) + target_compile_options(${n_target} + PRIVATE ${CSP_ADDTIONAL_FLAGS_COMPILE_RELWITHDEBINFO} + ) + endif() + elseif("${U_BUILD_TYPE}" STREQUAL "RELEASE") + if(DEFINED CSP_ADDTIONAL_FLAGS_COMPILE_RELEASE) + target_compile_options(${n_target} + PRIVATE ${CSP_ADDTIONAL_FLAGS_COMPILE_RELEASE} + ) + endif() + elseif("${U_BUILD_TYPE}" STREQUAL "DEBUG") + if(DEFINED CSP_ADDTIONAL_FLAGS_COMPILE_DEBUG) + target_compile_options(${n_target} + PRIVATE ${CSP_ADDTIONAL_FLAGS_COMPILE_DEBUG} + ) + endif() + endif() +endfunction(additional_options) + +#ToDo: MSVC. +#if(CMAKE_VERSION VERSION_LESS "3.1") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") +#endif() + +function(set_std TARGET) +# if(CMAKE_VERSION VERSION_LESS "3.1") +# else() +# set_property(TARGET ${TARGET} PROPERTY CXX_STANDARD 11) +# set_property(TARGET ${TARGET} PROPERTY C_STANDARD 11) +# endif() +endfunction(SET_STD) + +add_subdirectory("${PROJECT_SOURCE_DIR}/src/qt" osd) +add_subdirectory("${PROJECT_SOURCE_DIR}/src/qt/avio" qt/avio) +add_subdirectory("${PROJECT_SOURCE_DIR}/src/qt/gui" qt/gui) +add_subdirectory("${PROJECT_SOURCE_DIR}/src/qt/emuutils" emu_utils) + +if(USE_DEVICES_SHARED_LIB) + add_subdirectory("${PROJECT_SOURCE_DIR}/src/vm/common_vm" vm/) + add_subdirectory("${PROJECT_SOURCE_DIR}/src/vm/fmgen" vm/fmgen) +else() + add_subdirectory("${PROJECT_SOURCE_DIR}/src" common) + add_subdirectory("${PROJECT_SOURCE_DIR}/src/vm/common_vm" vm/) + add_subdirectory("${PROJECT_SOURCE_DIR}/src/vm/fmgen" vm/fmgen) +endif() + +function(ADD_VM VM_NAME EXE_NAME VMDEF) + set(COMMON_DIRECTORY ${PROJECT_SOURCE_DIR}/src/qt/common) + set(s_qt_common_headers + ${COMMON_DIRECTORY}/emu_thread.h + ${COMMON_DIRECTORY}/mainwidget.h + ${PROJECT_SOURCE_DIR}/src/qt/osd.h + ) + + QT5_ADD_RESOURCES(RESOURCE_${EXE_NAME} ${RESOURCE}) + QT5_WRAP_CPP(s_qt_common_headers_MOC ${s_qt_common_headers}) + + set(QT_COMMON_BASE + ${COMMON_DIRECTORY}/main.cpp + ${COMMON_DIRECTORY}/qt_utils.cpp + ${COMMON_DIRECTORY}/menu_flags.cpp + ${COMMON_DIRECTORY}/emu_thread.cpp +# ${COMMON_DIRECTORY}/emu_thread_slots.cpp + ${COMMON_DIRECTORY}/util_bubble2.cpp + ${COMMON_DIRECTORY}/util_main.cpp + ${COMMON_DIRECTORY}/../osd.cpp + ${COMMON_DIRECTORY}/../osd_wrapper.cpp + ) + if(${USE_SOCKET_${EXE_NAME}}) + set(QT_COMMON_BASE + ${QT_COMMON_BASE} + ${s_qt_net_headers_MOC} + ) + endif() + if(WIN32) + add_executable(${EXE_NAME} WIN32 + ${PROJECT_SOURCE_DIR}/src/vm/event.cpp + ${VMFILES} + ${PROJECT_SOURCE_DIR}/src/emu.cpp + ${COMMON_DIRECTORY}/../gui/qt_main.cpp + ${s_qt_common_headers_MOC} + ${RESOURCE_${EXE_NAME}} + ${QT_COMMON_BASE} + ) + else() + add_executable(${EXE_NAME} + ${PROJECT_SOURCE_DIR}/src/vm/event.cpp + ${PROJECT_SOURCE_DIR}/src/emu.cpp + ${QT_COMMON_BASE} + ${s_qt_common_headers_MOC} + ${RESOURCE_${EXE_NAME}} + ) + endif() + QT5_USE_MODULES(${EXE_NAME} Widgets Core Gui OpenGL Network) + target_include_directories(${EXE_NAME} + PRIVATE "${PROJECT_SOURCE_DIR}/src/qt/machines/${VM_NAME}" + PRIVATE "${PROJECT_SOURCE_DIR}/src/vm/${VM_NAME}" + ) + if(LIBAV_FOUND) + target_include_directories(${EXE_NAME} PUBLIC + "${PROJECT_SOURCE_DIR}/src/qt/avio" + ) + endif() +# if(WITH_DEBUGGER) + set(DEBUG_LIBS qt_debugger_${EXE_NAME}) +# target_include_directories(${EXE_NAME} PUBLIC +# PUBLIC "${PROJECT_SOURCE_DIR}/src/qt/debugger" +# ) +# else() +# set(DEBUG_LIBS) +# endif() + if(NOT USE_DEVICES_SHARED_LIB) + if(USE_FMGEN) + set(VM_APPEND_LIBS CSPfmgen) + else() + set(VM_APPEND_LIBS) + endif() + endif() + if(WIN32) + set(BUNDLE_LIBS + ${OPENGL_LIBRARY} + ${OPENCL_LIBRARY} + ${GETTEXT_LIBRARY} + ${OPENMP_LIBRARY} + ${LIBAV_LIBRARIES} + ${SDL_LIBS} + ${ADDITIONAL_LIBRARIES} + ${QT_LIBRARIES} + ${ZLIB_LIBRARIES} + ) + else() + add_definitions(-D_UNICODE) + set(BUNDLE_LIBS + ${OPENMP_LIBRARY} + ${SDL_LIBS} + ${ADDITIONAL_LIBRARIES} + ${BUNDLE_LIBS} + ${QT_LIBRARIES} + ${ZLIB_LIBRARIES} + ${THREADS_LIBRARY} + ) + endif() + if(WIN32) + set(LOCAL_LIBS + qt_${EXE_NAME} + vm_${EXE_NAME} +# vm_common_vm + ${VM_APPEND_LIBS} + ${DEBUG_LIBS} + common_${EXE_NAME} + ) + else() + set(LOCAL_LIBS + qt_${EXE_NAME} + vm_${EXE_NAME} + ${VM_APPEND_LIBS} + ${DEBUG_LIBS} + common_${EXE_NAME} + ) + endif() + if(USE_DEVICES_SHARED_LIB) + set(BUNDLE_LIBS + ${BUNDLE_LIBS} + CSPosd + CSPcommon_vm + CSPfmgen + CSPgui + CSPemu_utils + CSPavio + ) + else() + set(BUNDLE_LIBS + ${BUNDLE_LIBS} + CSPosd +# CSPfmgen + CSPgui + CSPemu_utils + CSPavio + ) + endif() + + # Subdirectories + add_subdirectory("${PROJECT_SOURCE_DIR}/src" common/${EXE_NAME} EXCLUDE_FROM_ALL) + add_subdirectory("${PROJECT_SOURCE_DIR}/src/vm/${VM_NAME}" vm/${EXE_NAME} EXCLUDE_FROM_ALL) + set_std(vm_${EXE_NAME}) + if(NOT USE_DEVICES_SHARED_LIB) + if(USE_FMGEN) +# add_subdirectory("${PROJECT_SOURCE_DIR}/src/vm/fmgen" vm/fmgen_${EXE_NAME} EXCLUDE_FROM_ALL) + endif() + endif() + add_subdirectory("${PROJECT_SOURCE_DIR}/src/qt/machines/${VM_NAME}" qt/${EXE_NAME} EXCLUDE_FROM_ALL) + set_std(qt_${EXE_NAME}) + +# if(WITH_DEBUGGER) + add_subdirectory("${PROJECT_SOURCE_DIR}/src/qt/debugger" qt/debugger_${EXE_NAME} EXCLUDE_FROM_ALL) +# endif() +# add_subdirectory("${PROJECT_SOURCE_DIR}/src/qt/common" qt/common EXCLUDE_FROM_ALL) + set_std(${EXE_NAME}) + add_dependencies(${EXE_NAME} + CSPosd + CSPcommon_vm + CSPfmgen + common_${EXE_NAME} + CSPemu_utils + CSPgui + CSPavio + qt_debugger_${EXE_NAME} + qt_${EXE_NAME} + ) + target_compile_definitions(${EXE_NAME} + PRIVATE ${VMDEF} + ) + target_compile_definitions(vm_${EXE_NAME} + PRIVATE ${VMDEF} + ) + target_compile_definitions(qt_${EXE_NAME} + PUBLIC ${VMDEF} + ) + target_compile_definitions(qt_debugger_${EXE_NAME} + PRIVATE ${VMDEF} + ) + target_compile_definitions(common_${EXE_NAME} + PRIVATE ${VMDEF} + ) + +# additional_options(common_${EXE_NAME}) +# additional_options(vm_${EXE_NAME}) +# additional_options(qt_${EXE_NAME}) +# additional_options(qt_debug_${EXE_NAME}) + +# additional_options(${EXE_NAME}) +# additional_link_options(${EXE_NAME}) + + if(WIN32) + # Note: With Debian's foo-mingw-w64-g++, needs below workaround + # due to problems of linker. + if(USING_TOOLCHAIN_GCC_DEBIAN) + set(DUPLICATE_LINK_LIB CSPcommon_vm CSPgui) + endif() + target_link_libraries(${EXE_NAME} + ${BUNDLE_LIBS} + ${LOCAL_LIBS} + ${DUPLICATE_LINK_LIB} +# libpthread.a + -lpthread + ) + else() + target_link_libraries(${EXE_NAME} + ${LOCAL_LIBS} + ${BUNDLE_LIBS} + -lpthread) + endif() + install(TARGETS ${EXE_NAME} + RUNTIME DESTINATION bin + LIBRARY DESTINATION "${CMAKE_LIBRARY_ARCHITECTURE}" + ARCHIVE DESTINATION "${CMAKE_LIBRARY_ARCHITECTURE}" + ) +endfunction() + + diff --git a/source/cmake/config_casio.cmake b/source/cmake/config_casio.cmake new file mode 100644 index 000000000..d7e682eaa --- /dev/null +++ b/source/cmake/config_casio.cmake @@ -0,0 +1,21 @@ +set(BUILD_FP1100 ON CACHE BOOL "Build for CASIO FP-1100") +set(BUILD_FP200 ON CACHE BOOL "Build for CASIO FP-200") +set(BUILD_PV1000 ON CACHE BOOL "Build for CASIO PV-1000") +set(BUILD_PV2000 ON CACHE BOOL "Build for CASIO PV-2000") + +if(BUILD_FP1100) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fp1100.qrc) + ADD_VM(fp1100 emufp1100 _FP1100) +endif() +if(BUILD_FP200) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fp200.qrc) + ADD_VM(fp200 emufp200 _FP200) +endif() +if(BUILD_PV1000) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pv1000.qrc) + ADD_VM(pv1000 emupv1000 _PV1000) +endif() +if(BUILD_PV2000) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pv2000.qrc) + ADD_VM(pv2000 emupv2000 _PV2000) +endif() diff --git a/source/cmake/config_emufm7.cmake b/source/cmake/config_emufm7.cmake new file mode 100644 index 000000000..2a46a1cb0 --- /dev/null +++ b/source/cmake/config_emufm7.cmake @@ -0,0 +1,126 @@ +# Build Common Sourcecode Project, Qt. +# (C) 2014 K.Ohta +# This is part of , but license is apache 2.2, +# this part was written only me. + +message("") +message("** Start of configure CommonSourceProject,FM-8/7/77/AV, Qt **") +message("") + +#set(VMFILES_FM7 +# event.cpp +#) + +set(VMFILES_LIB_FM7 + and.cpp + datarec.cpp + ym2203.cpp + pcm1bit.cpp + disk.cpp + mb8877.cpp + prnfile.cpp + or.cpp + noise.cpp + i8251.cpp +) + +set(BUILD_FM7 ON CACHE BOOL "Build for FM7") +set(BUILD_FMNEW7 ON CACHE BOOL "Build for FM7") +set(BUILD_FM8 ON CACHE BOOL "Build for FM8") +set(BUILD_FM77 ON CACHE BOOL "Build for FM77") +#set(BUILD_FM77L2 ON CACHE BOOL "Build for FM77L2") +set(BUILD_FM77L4 ON CACHE BOOL "Build for FM77L4") +set(BUILD_FM77AV ON CACHE BOOL "Build for FM77AV") +#set(BUILD_FM77AV20 ON CACHE BOOL "Build for FM77AV20") +set(BUILD_FM77AV40 ON CACHE BOOL "Build for FM77AV40") +set(BUILD_FM77AV40SX ON CACHE BOOL "Build for FM77AV40SX") +set(BUILD_FM77AV40EX ON CACHE BOOL "Build for FM77AV40EX") +set(FM77_EXTRAM_PAGES "3" CACHE STRING "Set banks of EXTRAM of FM77, bank = 64Kbytes") +#set(FM77L2_EXTRAM_PAGES "3" CACHE STRING "Set banks of EXTRAM of FM77L2, bank = 64Kbytes") +set(FM77L4_EXTRAM_PAGES "3" CACHE STRING "Set banks of EXTRAM of FM77L4, bank = 64Kbytes") +set(FM77AV40_EXTRAM_PAGES "12" CACHE STRING "Set banks of EXTRAM of FM77AV40, bank = 64Kbytes") +set(FM77AV40SX_EXTRAM_PAGES "12" CACHE STRING "Set banks of EXTRAM of FM77AV40SX, bank = 64Kbytes") +set(FM77AV40EX_EXTRAM_PAGES "12" CACHE STRING "Set banks of EXTRAM of FM77AV40SX, bank = 64Kbytes") + +set(FM7_DEBUG_FDC OFF CACHE BOOL "With debug FDC") + +if(FM7_DEBUG_FDC) + add_definitions(-D_FM7_FDC_DEBUG) + add_definitions(-D_DEBUG_LOG) +endif() + +if(BUILD_FM7) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm7.qrc) + ADD_VM(fm7 emufm7 _FM7) +endif() +if(BUILD_FM8) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} ay_3_891x.cpp) + #set(FLAG_USE_Z80 ON) + #add_definitions(-DBUILD_Z80) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm8.qrc) + ADD_VM(fm7 emufm8 _FM8) +endif() +if(BUILD_FM77) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} ay_3_891x.cpp) + #set(FLAG_USE_Z80 ON) + #add_definitions(-DBUILD_Z80) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77.qrc) + ADD_VM(fm7 emufm77 _FM77) + target_compile_definitions(emufm77 + PRIVATE -DFM77_EXRAM_BANKS=${FM77_EXTRAM_PAGES} + ) +endif() +if(BUILD_FM77L4) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} ay_3_891x.cpp) + #set(FLAG_USE_Z80 ON) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77.qrc) + ADD_VM(fm7 emufm77l4 _FM77L4) + target_compile_definitions(emufm77l4 + PRIVATE -DFM77_EXRAM_BANKS=${FM77L4_EXTRAM_PAGES} + ) +endif() +if(BUILD_FM77AV) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} beep.cpp) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77av.qrc) + ADD_VM(fm7 emufm77av _FM77AV) +endif() +if(BUILD_FM77AV20) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} beep.cpp) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77av20.qrc) + ADD_VM(fm7 emufm77av20 _FM77AV20) +endif() +if(BUILD_FM77AV20EX) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} beep.cpp) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77av20ex.qrc) + ADD_VM(fm7 emufm77av20ex _FM77AV20EX) +endif() +if(BUILD_FM77AV40) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} beep.cpp) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77av40.qrc) + ADD_VM(fm7 emufm77av40 _FM77AV40) + target_compile_definitions(emufm77av40 + PRIVATE -DFM77_EXRAM_BANKS=${FM77AV40_EXTRAM_PAGES} + ) +endif() +if(BUILD_FM77AV40SX) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} beep.cpp) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77av40sx.qrc) + ADD_VM(fm7 emufm77av40sx _FM77AV40SX) + target_compile_definitions(emufm77av40sx + PRIVATE -DFM77_EXRAM_BANKS=${FM77AV40SX_EXTRAM_PAGES} + ) +endif() +if(BUILD_FM77AV40EX) + #set(VMFILES_LIB_FM7 ${VMFILES_LIB_FM7} beep.cpp) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm77av40ex.qrc) + ADD_VM(fm7 emufm77av40ex _FM77AV40EX) + target_compile_definitions(emufm77av40ex + PRIVATE -DFM77_EXRAM_BANKS=${FM77AV40EX_EXTRAM_PAGES} + ) +endif() + + + + + + diff --git a/source/cmake/config_epson.cmake b/source/cmake/config_epson.cmake new file mode 100644 index 000000000..3474de216 --- /dev/null +++ b/source/cmake/config_epson.cmake @@ -0,0 +1,31 @@ +set(BUILD_HC20 ON CACHE BOOL "Build for Epson HC-20") +set(BUILD_HC40 ON CACHE BOOL "Build for Epson HC-40") +set(BUILD_HC80 ON CACHE BOOL "Build for Epson HC-80") + +set(BUILD_QC10 ON CACHE BOOL "Build for Epson QC-10 (Monochrome)") +set(BUILD_QC10COLOR ON CACHE BOOL "Build for Epson QC-10 (Color) ") + +if(BUILD_QC10) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/qc10cms.qrc) + ADD_VM(qc10 emuqc10 _QC10) +endif() +if(BUILD_QC10COLOR) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/qc10cms.qrc) + ADD_VM(qc10 emuqc10_cms _QC10) + target_compile_definitions(emuqc10_cms + PRIVATE -D_COLOR_MONITOR + ) +endif() +if(BUILD_HC20) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/hc20.qrc) + ADD_VM(hc20 emuhc20 _HC20) +endif() +if(BUILD_HC40) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/hc40.qrc) + ADD_VM(hc40 emuhc40 _HC40) +endif() +if(BUILD_HC80) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/hc80.qrc) + ADD_VM(hc80 emuhc80 _HC80) +endif() + diff --git a/source/cmake/config_fm16.cmake b/source/cmake/config_fm16.cmake new file mode 100644 index 000000000..1f1b787a4 --- /dev/null +++ b/source/cmake/config_fm16.cmake @@ -0,0 +1,20 @@ +set(BUILD_FM16BETA_286 ON CACHE BOOL "Build for Fujitsu FM-16β(i286)") +set(BUILD_FM16BETA_186 ON CACHE BOOL "Build for Fujitsu FM-16β(i186)") +set(BUILD_FM16PI ON CACHE BOOL "Build for Fujitsu FM-16π") + +if(BUILD_FM16BETA_186) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm16beta.qrc) + ADD_VM(fm16beta emufm16beta_186 _FM16BETA) + target_compile_definitions(emufm16beta_186 PRIVATE -DHAS_I186) + target_compile_definitions(common_emufm16beta_186 PRIVATE -DHAS_I186) +endif() +if(BUILD_FM16BETA_286) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm16beta.qrc) + ADD_VM(fm16beta emufm16beta_286 _FM16BETA) + target_compile_definitions(emufm16beta_286 PRIVATE -DHAS_I286) + target_compile_definitions(common_emufm16beta_286 PRIVATE -DHAS_I286) +endif() +if(BUILD_FM16PI) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fm16beta.qrc) + ADD_VM(fm16pi emufm16pi _FM16PI) +endif() diff --git a/source/cmake/config_fmr.cmake b/source/cmake/config_fmr.cmake new file mode 100644 index 000000000..a643df5af --- /dev/null +++ b/source/cmake/config_fmr.cmake @@ -0,0 +1,64 @@ +set(BUILD_FMR30_86 ON CACHE BOOL "Build for FM-R30, i8086 version") +set(BUILD_FMR30_286 ON CACHE BOOL "Build for FM-R30, i286 version") +set(BUILD_FMR50_286 ON CACHE BOOL "Build for FM-R50, i286 version") +set(BUILD_FMR50_386 ON CACHE BOOL "Build for FM-R50, i386 version") +set(BUILD_FMR50_486 ON CACHE BOOL "Build for FM-R50, i486 version") +set(BUILD_FMR250 ON CACHE BOOL "Build for FM-R250, Pentium version of FMR-50") +set(BUILD_FMR60 ON CACHE BOOL "Build for FM-R60, i286 version") +set(BUILD_FMR70 ON CACHE BOOL "Build for FM-R70, i386 version") +set(BUILD_FMR80 ON CACHE BOOL "Build for FM-R80, i486 version") +set(BUILD_FMR280 ON CACHE BOOL "Build for FM-R250, Pentium version of FMR-80") + +if(BUILD_FMR30_86) + ADD_VM(fmr30 emufmr30_i86 _FMR30) + target_compile_definitions(emufmr30_i86 PRIVATE -DHAS_I86) + target_compile_definitions(common_emufmr30_i86 PRIVATE -DHAS_I86) +endif() +if(BUILD_FMR30_286) + ADD_VM(fmr30 emufmr30_i286 _FMR30) + target_compile_definitions(emufmr30_i286 PRIVATE -DHAS_I286) + target_compile_definitions(common_emufmr30_i286 PRIVATE -DHAS_I286) +endif() + +if(BUILD_FMR50_286) + ADD_VM(fmr50 emufmr50_286 _FMR50) + target_compile_definitions(emufmr50_286 PRIVATE -DHAS_I286) + target_compile_definitions(common_emufmr50_286 PRIVATE -DHAS_I286) +endif() +if(BUILD_FMR50_386) + ADD_VM(fmr50 emufmr50_386 _FMR50) + target_compile_definitions(emufmr50_386 PRIVATE -DHAS_I386) + target_compile_definitions(common_emufmr50_386 PRIVATE -DHAS_I386) +endif() +if(BUILD_FMR50_486) + ADD_VM(fmr50 emufmr50_486 _FMR50) + target_compile_definitions(emufmr50_486 PRIVATE -DHAS_I486) + target_compile_definitions(common_emufmr50_486 PRIVATE -DHAS_I486) +endif() + +if(BUILD_FMR60) + ADD_VM(fmr50 emufmr60 _FMR60) + target_compile_definitions(emufmr60 PRIVATE -DHAS_I286) + target_compile_definitions(common_emufmr60 PRIVATE -DHAS_I286) +endif() +if(BUILD_FMR70) + ADD_VM(fmr50 emufmr70 _FMR60) + target_compile_definitions(emufmr70 PRIVATE -DHAS_I386) + target_compile_definitions(common_emufmr70 PRIVATE -DHAS_I386) +endif() +if(BUILD_FMR80) + ADD_VM(fmr50 emufmr80 _FMR60) + target_compile_definitions(emufmr80 PRIVATE -DHAS_I486) + target_compile_definitions(common_emufmr80 PRIVATE -DHAS_I486) +endif() + +if(BUILD_FMR250) + ADD_VM(fmr50 emufmr250 _FMR50) + target_compile_definitions(emufmr250 PRIVATE -DHAS_PENTIUM) + target_compile_definitions(common_emufmr250 PRIVATE -DHAS_PENTIUM) +endif() +if(BUILD_FMR280) + ADD_VM(fmr50 emufmr280 _FMR60) + target_compile_definitions(emufmr280 PRIVATE -DHAS_PENTIUM) + target_compile_definitions(common_emufmr280 PRIVATE -DHAS_PENTIUM) +endif() diff --git a/source/cmake/config_fmtowns.cmake b/source/cmake/config_fmtowns.cmake new file mode 100644 index 000000000..ffb3f82e4 --- /dev/null +++ b/source/cmake/config_fmtowns.cmake @@ -0,0 +1,140 @@ +set(VMFILES_LIB + i386.cpp + noise.cpp + pcm1bit.cpp + i8251.cpp + i8253.cpp + i8259.cpp + io.cpp + upd71071.cpp + mb8877.cpp + + scsi_dev.cpp + scsi_hdd.cpp + scsi_cdrom.cpp + + disk.cpp + prnfile.cpp + harddisk.cpp +) +set(VMFILES + ${PROJECT_SOURCE_DIR}/src/vm/scsi_host.cpp + ${PROJECT_SOURCE_DIR}/src/vm/msm58321.cpp +) + +set(BUILD_FMTOWNS_1 ON CACHE BOOL "Build for FM-Towns Model 1") +#set(BUILD_FMTOWNS_2 ON CACHE BOOL "Build for FM-Towns Model 2") +#set(BUILD_FMTOWNS_2F ON CACHE BOOL "Build for FM-Towns 2F") +set(BUILD_FMTOWNS_2H ON CACHE BOOL "Build for FM-Towns 2H") +#set(BUILD_FMTOWNS_20F ON CACHE BOOL "Build for FM-Towns 20F") +#set(BUILD_FMTOWNS_20H ON CACHE BOOL "Build for FM-Towns 20H") +#set(BUILD_FMTOWNS2_UX20 ON CACHE BOOL "Build for FM-Towns2 UX20") +#set(BUILD_FMTOWNS2_UX40 ON CACHE BOOL "Build for FM-Towns2 UX40") +set(BUILD_FMTOWNS2_CX20 ON CACHE BOOL "Build for FM-Towns2 CX20") +set(BUILD_FMTOWNS2_CX40 ON CACHE BOOL "Build for FM-Towns2 CX40") +#set(BUILD_FMTOWNS2_CX100 ON CACHE BOOL "Build for FM-Towns2 CX100") +#set(BUILD_FMTOWNS2_UG10 ON CACHE BOOL "Build for FM-Towns2 UG10") +#set(BUILD_FMTOWNS2_UG20 ON CACHE BOOL "Build for FM-Towns2 UG20") +#set(BUILD_FMTOWNS2_UG40 ON CACHE BOOL "Build for FM-Towns2 UG40") +#set(BUILD_FMTOWNS2_UG80 ON CACHE BOOL "Build for FM-Towns2 UG80") +#set(BUILD_FMTOWNS2_HG20 ON CACHE BOOL "Build for FM-Towns2 HG20") +set(BUILD_FMTOWNS2_HG40 ON CACHE BOOL "Build for FM-Towns2 HG40") +#set(BUILD_FMTOWNS2_HG100 ON CACHE BOOL "Build for FM-Towns2 HG100") +#set(BUILD_FMTOWNS2_HR20 ON CACHE BOOL "Build for FM-Towns2 HR20") +set(BUILD_FMTOWNS2_HR100 ON CACHE BOOL "Build for FM-Towns2 HR100") +#set(BUILD_FMTOWNS2_HR200 ON CACHE BOOL "Build for FM-Towns2 HR200") + +if(BUILD_FMTOWNS_1) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns _FMTOWNS_1) + ## ToDo +endif() + +if(BUILD_FMTOWNS_2) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2 _FMTOWNS_2) + ## ToDo +endif() +if(BUILD_FMTOWNS_1F) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns1F _FMTOWNS_1F) + ## ToDo +endif() +if(BUILD_FMTOWNS_2F) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2F _FMTOWNS_2F) + ## ToDo +endif() +if(BUILD_FMTOWNS_1H) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns1H _FMTOWNS_1H) + ## ToDo +endif() +if(BUILD_FMTOWNS_2H) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2H _FMTOWNS_2H) + ## ToDo +endif() + +if(BUILD_FMTOWNS_10F) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns10F _FMTOWNS_10F) + ## ToDo +endif() +if(BUILD_FMTOWNS_20F) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns20F _FMTOWNS_20F) + ## ToDo +endif() +if(BUILD_FMTOWNS_10H) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns10H _FMTOWNS_10H) + ## ToDo +endif() +if(BUILD_FMTOWNS_20H) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns20H _FMTOWNS_20H) + ## ToDo +endif() + +if(BUILD_FMTOWNS2_UX20) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2UX20 _FMTOWNS2_UX20) + ## ToDo +endif() +if(BUILD_FMTOWNS2_UX40) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2UX40 _FMTOWNS2_UX40) + ## ToDo +endif() +if(BUILD_FMTOWNS2_CX20) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2CX20 _FMTOWNS2_CX20) + ## ToDo +endif() +if(BUILD_FMTOWNS2_CX40) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2CX40 _FMTOWNS2_CX40) + ## ToDo +endif() +if(BUILD_FMTOWNS2_CX100) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2CX100 _FMTOWNS2_CX100) + ## ToDo +endif() + +if(BUILD_FMTOWNS2_HR20) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2HR20 _FMTOWNS2_HR20) + ## ToDo +endif() +if(BUILD_FMTOWNS2_HR100) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2HR100 _FMTOWNS2_HR100) + ## ToDo +endif() +if(BUILD_FMTOWNS2_HR200) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fmtowns.qrc) + ADD_VM(fmtowns emufmtowns2HR200 _FMTOWNS2_HR200) + ## ToDo +endif() diff --git a/source/cmake/config_misccom.cmake b/source/cmake/config_misccom.cmake new file mode 100644 index 000000000..33169536d --- /dev/null +++ b/source/cmake/config_misccom.cmake @@ -0,0 +1,158 @@ +set(BUILD_BMJR ON CACHE BOOL "Build for Hitachi BASIC MASTER Jr.") +set(BUILD_BUBCOM80 ON CACHE BOOL "Build for Systems Formulate BUBCOM-80.") +set(BUILD_CEFUCOM21 ON CACHE BOOL "Build Hino Electronics CEFUCOM-21.") +set(BUILD_COLECOVISION ON CACHE BOOL "Build for COLECO ColecoVision.") +set(BUILD_FAMILYBASIC ON CACHE BOOL "Build Nintendo Family Basic.") + +set(BUILD_JR100 ON CACHE BOOL "Build Matsushita JR-100.") +set(BUILD_JR800 ON CACHE BOOL "Build Matsushita JR-800.") + +set(BUILD_JX ON CACHE BOOL "Build IBM JX.") + +set(BUILD_M5 ON CACHE BOOL "Build SORD M5.") +set(BUILD_MAP1010 ON CACHE BOOL "Build SEIKO MAP-1010.") +set(BUILD_MICOM_MAHJONG ON CACHE BOOL "Build MICOM MAHJONG.") +set(BUILD_MULTI8 ON CACHE BOOL "Build Mitsubishi Multi 8.") +set(BUILD_MYCOMZ80A ON CACHE BOOL "Build Japan Electronics College MYCOM Z-80A.") + +set(BUILD_PHC20 ON CACHE BOOL "Build Sanyo PHC-20.") +set(BUILD_PHC25 ON CACHE BOOL "Build Sanyo PHC-25.") +set(BUILD_PYUTA ON CACHE BOOL "Build TOMY PYUTA.") +set(BUILD_RX78 ON CACHE BOOL "Build BANDAI RX-78.") +set(BUILD_SCV ON CACHE BOOL "Build EPOCH Cuper Casette Vision.") + +set(BUILD_SMC70 ON CACHE BOOL "Build SONY SMC-70") +set(BUILD_SMC777 ON CACHE BOOL "Build SONY SMC-777") + +set(BUILD_TVBOY ON CACHE BOOL "Build GAKKEN TV BOY") + +set(BUILD_X07 ON CACHE BOOL "Build CANON X07") +set(BUILD_YALKY ON CACHE BOOL "Build Yuasa Kyouiku System YALKY") +set(BUILD_YIS ON CACHE BOOL "Build YAMAHA YIS") +set(BUILD_Z80TVGAME_I8255 ON CACHE BOOL "Build Homebrew Z80 TV GAME SYSTEM (i8255)") +set(BUILD_Z80TVGAME_Z80PIO ON CACHE BOOL "Build Homebrew Z80 TV GAME SYSTEM (Z80PIO)") + +if(BUILD_BMJR) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/bmjr.qrc) + ADD_VM(bmjr emubmjr _BMJR) +endif() +if(BUILD_BUBCOM80) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/bubcom80.qrc) + ADD_VM(bubcom80 emububcom80 _BUBCOM80) +endif() +if(BUILD_CEFUCOM21) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/cefucom21.qrc) + ADD_VM(cefucom21 emucefucom21 _CEFUCOM21) +endif() +if(BUILD_COLECOVISION) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/colecovision.qrc) + ADD_VM(colecovision emucolecovision _COLECOVISION) +endif() +if(BUILD_FAMILYBASIC) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/familybasic.qrc) + ADD_VM(familybasic emufamilybasic _FAMILYBASIC) +endif() + +if(BUILD_JR100) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/jr100.qrc) + ADD_VM(jr100 emujr100 _JR100) +endif() +if(BUILD_JR800) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/jr800.qrc) + ADD_VM(jr800 emujr800 _JR800) +endif() + +if(BUILD_JX) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/jx.qrc) + ADD_VM(jx emujx _JX) +endif() + +if(BUILD_M5) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/jr800.qrc) + ADD_VM(m5 emum5 _M5) +endif() +if(BUILD_MAP1010) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/map1010.qrc) + ADD_VM(phc25 emumap1010 _MAP1010) +endif() +if(BUILD_MICOM_MAHJONG) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/micom_mahjong.qrc) + ADD_VM(micom_mahjong emumicom_mahjong _MICOM_MAHJONG) +endif() + +if(BUILD_MULTI8) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/multi8.qrc) + ADD_VM(multi8 emumulti8 _MULTI8) +endif() +if(BUILD_MYCOMZ80A) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mycomz80a.qrc) + ADD_VM(mycomz80a emumycomz80a _MYCOMZ80A) +endif() + + +if(BUILD_PHC20) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/phc20.qrc) + ADD_VM(phc20 emuphc20 _PHC20) +endif() +if(BUILD_PHC25) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/phc25.qrc) + ADD_VM(phc25 emuphc25 _PHC25) +endif() +if(BUILD_PYUTA) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pyuta.qrc) + ADD_VM(pyuta emupyuta _PYUTA) +endif() + +if(BUILD_RX78) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/rx78.qrc) + ADD_VM(rx78 emurx78 _RX78) +endif() +if(BUILD_SCV) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/scv.qrc) + ADD_VM(scv emuscv _SCV) +endif() +if(BUILD_SMC70) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/smc70.qrc) + ADD_VM(smc777 emusmc70 _SMC70) +endif() +if(BUILD_SMC777) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/smc777.qrc) + ADD_VM(smc777 emusmc777 _SMC777) +endif() +if(BUILD_TVBOY) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/tvboy.qrc) + ADD_VM(tvboy emutvboy _TVBOY) +endif() + +if(BUILD_X07) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/x07.qrc) + ADD_VM(x07 emux07 _X07) +endif() + +if(BUILD_YALKY) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/yalky.qrc) + ADD_VM(yalky emuyalky _YALKY) +endif() + +if(BUILD_YIS) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/yis.qrc) + ADD_VM(yis emuyis _YIS) +endif() + +if(BUILD_Z80TVGAME_I8255) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/z80tvgame_i8255.qrc) + ADD_VM(z80tvgame emuz80tvgame_i8255 _Z80TVGAME) + target_compile_definitions(emuz80tvgame_i8255 PRIVATE -D_USE_I8255) + target_compile_definitions(vm_emuz80tvgame_i8255 PRIVATE -D_USE_I8255) + target_compile_definitions(qt_emuz80tvgame_i8255 PRIVATE -D_USE_I8255) + target_compile_definitions(common_emuz80tvgame_i8255 PRIVATE -D_USE_I8255) +endif() +if(BUILD_Z80TVGAME_Z80PIO) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/z80tvgame_z80pio.qrc) + ADD_VM(z80tvgame emuz80tvgame_z80pio _Z80TVGAME) + target_compile_definitions(emuz80tvgame_z80pio PRIVATE -D_USE_Z80PIO) + target_compile_definitions(vm_emuz80tvgame_z80pio PRIVATE -D_USE_Z80PIO) + target_compile_definitions(qt_emuz80tvgame_z80pio PRIVATE -D_USE_Z80PIO) + target_compile_definitions(common_emuz80tvgame_z80pio PRIVATE -D_USE_Z80PIO) +endif() + diff --git a/source/cmake/config_msx.cmake b/source/cmake/config_msx.cmake new file mode 100644 index 000000000..5aded941d --- /dev/null +++ b/source/cmake/config_msx.cmake @@ -0,0 +1,48 @@ +set(BUILD_MSX1 ON CACHE BOOL "Build for standard MSX1") +set(BUILD_MSX2 ON CACHE BOOL "Build for standard MSX2") +set(BUILD_MSX2PLUS ON CACHE BOOL "Build for standard MSX2+") +set(BUILD_FSA1 ON CACHE BOOL "Build for Matsushita FS-A1") +set(BUILD_HX20 ON CACHE BOOL "Build for Toshiba HX20") +#set(BUILD_HBF1XDJ ON CACHE BOOL "Build for Sony HBF1XDJ") +set(BUILD_PX7 ON CACHE BOOL "Build for Pioneer PX7") +set(BUILD_SVI3X8 ON CACHE BOOL "Build for SPECTRAVIDEO SVI-3x8") + +if(BUILD_MSX1) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/msx1.qrc) + ADD_VM(msx emumsx1 _MSX1) +endif() +if(BUILD_MSX2) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/msx2.qrc) + ADD_VM(msx emumsx2 _MSX2) + target_compile_definitions(emumsx2 PRIVATE -D_MSX_VDP_MESS) +endif() +if(BUILD_MSX2PLUS) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/msx2plus.qrc) + ADD_VM(msx emumsx2p _MSX2P) + target_compile_definitions(emumsx2p PRIVATE -D_MSX_VDP_MESS) +endif() + +if(BUILD_PX7) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/px7.qrc) + ADD_VM(msx emupx7 _PX7) +endif() +if(BUILD_HX20) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/hx20.qrc) + ADD_VM(msx emuhx20 _HX20) + target_compile_definitions(emuhx20 PRIVATE -D_MSX_VDP_MESS) +endif() +if(BUILD_FSA1) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/fsa1.qrc) + ADD_VM(msx emufsa1 _FSA1) + target_compile_definitions(emufsa1 PRIVATE -D_MSX_VDP_MESS) +endif() +#if(BUILD_HBF1XDJ) +# set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/hbf1xdj.qrc) +# ADD_VM(msx emuhbf1xdj _HBF1XDJ) +# target_compile_definitions(emuhbf1xdj PRIVATE -D_MSX_VDP_MESS) +#endif() +if(BUILD_SVI3X8) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/svi3x8.qrc) + ADD_VM(svi3x8 emusvi3x8 _SVI3X8) + target_compile_definitions(emufsa1 PRIVATE -D_MSX_VDP_MESS) +endif() diff --git a/source/cmake/config_mz80_700.cmake b/source/cmake/config_mz80_700.cmake new file mode 100644 index 000000000..ae7bb08a3 --- /dev/null +++ b/source/cmake/config_mz80_700.cmake @@ -0,0 +1,103 @@ +set(BUILD_MZ80A ON CACHE BOOL "Build for SHARP MZ-80A") +set(BUILD_MZ80K ON CACHE BOOL "Build for SHARP MZ-80K") +set(BUILD_MZ1200 ON CACHE BOOL "Build for SHARP MZ-1200") + +set(BUILD_MZ80B ON CACHE BOOL "Build for SHARP MZ-80B") +#set(BUILD_MZ2000 ON CACHE BOOL "Build for SHARP MZ-2000") +set(BUILD_MZ2200 ON CACHE BOOL "Build for SHARP MZ-2200") +set(BUILD_MZ2500 ON CACHE BOOL "Build for SHARP MZ-2500") + +set(BUILD_MZ700 ON CACHE BOOL "Build for SHARP MZ-700") +set(BUILD_MZ800 ON CACHE BOOL "Build for SHARP MZ-800") +set(BUILD_MZ1500 ON CACHE BOOL "Build for SHARP MZ-1500") + +set(BUILD_MZ2800 ON CACHE BOOL "Build for SHARP MZ-2800") +set(BUILD_MZ3500 ON CACHE BOOL "Build for SHARP MZ-3500") + +set(BUILD_MZ5500 ON CACHE BOOL "Build for SHARP MZ-5500") +set(BUILD_MZ6500 ON CACHE BOOL "Build for SHARP MZ-6500") +set(BUILD_MZ6550 ON CACHE BOOL "Build for SHARP MZ-6550") + +if(BUILD_MZ80A) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz80a.qrc) + ADD_VM(mz80k emumz80A _MZ80A) + # MZ80AIF +endif() +if(BUILD_MZ80K) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz80k.qrc) + ADD_VM(mz80k emumz80k _MZ80K) + # MZ80AIF +endif() +if(BUILD_MZ1200) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz1200.qrc) + ADD_VM(mz80k emumz1200 _MZ1200) + # MZ80FIO +endif() + +if(BUILD_MZ700) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz700.qrc) + ADD_VM(mz700 emumz700 _MZ700) +endif() +if(BUILD_MZ800) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz800.qrc) + ADD_VM(mz700 emumz800 _MZ800) +endif() +if(BUILD_MZ1500) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz1500.qrc) + ADD_VM(mz700 emumz1500 _MZ1500) +endif() + +if(BUILD_MZ80B) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz80b.qrc) + ADD_VM(mz2500 emumz80b _MZ80B) +endif() +if(BUILD_MZ2000) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz2000.qrc) + ADD_VM(mz2500 emumz2000 _MZ2000) +endif() +if(BUILD_MZ2200) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz2200.qrc) + ADD_VM(mz2500 emumz2200 _MZ2200) +endif() + +if(BUILD_MZ2500) + set(USE_SOCKET_emumz2500 ON) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz2500.qrc) + ADD_VM(mz2500 emumz2500 _MZ2500) + # Set soicket flags + # ToDo: To be separated. + target_compile_definitions(common_emumz2500 + PRIVATE ${USE_SOCKET} + ) + target_compile_definitions(qt_emumz2500 + PUBLIC ${USE_SOCKET} + ) + target_compile_definitions(emumz2500 + PUBLIC ${USE_SOCKET} + ) + +endif() + +if(BUILD_MZ2800) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz2800.qrc) + ADD_VM(mz2800 emumz2800 _MZ2800) +endif() + +if(BUILD_MZ3500) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz3500.qrc) + ADD_VM(mz3500 emumz3500 _MZ3500) +endif() + +if(BUILD_MZ5500) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz5500.qrc) + ADD_VM(mz5500 emumz5500 _MZ5500) +endif() +if(BUILD_MZ6500) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz6500.qrc) + ADD_VM(mz5500 emumz6500 _MZ6500) +endif() +if(BUILD_MZ6550) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mz6550.qrc) + ADD_VM(mz5500 emumz6550 _MZ6550) +endif() + diff --git a/source/cmake/config_necmisc.cmake b/source/cmake/config_necmisc.cmake new file mode 100644 index 000000000..b78dbc87a --- /dev/null +++ b/source/cmake/config_necmisc.cmake @@ -0,0 +1,43 @@ +set(BUILD_N5200 ON CACHE BOOL "Build for NEC N5200.") +set(BUILD_PC100 ON CACHE BOOL "Build for NEC PC-100.") +set(BUILD_PC2001 ON CACHE BOOL "Build for NEC PC 2001.") +set(BUILD_PC8201 ON CACHE BOOL "Build for NEC PC-8201.") +set(BUILD_PC8201A ON CACHE BOOL "Build for NEC PC-8201A.") +set(BUILD_PC98LT ON CACHE BOOL "Build for NEC PC98LT.") +set(BUILD_PC98HA ON CACHE BOOL "Build for NEC PC98HA.") +set(BUILD_PCENGINE ON CACHE BOOL "Build NEC PC Engine.") + +if(BUILD_N5200) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/n5200.qrc) + ADD_VM(n5200 emun5200 _N5200) +endif() +if(BUILD_PC100) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc100.qrc) + ADD_VM(pc100 emupc100 _PC100) +endif() + +if(BUILD_PC2001) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc2001.qrc) + ADD_VM(pc2001 emupc2001 _PC2001) +endif() +if(BUILD_PC8201) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8201.qrc) + ADD_VM(pc8201 emupc8201 _PC8201) +endif() +if(BUILD_PC8201A) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8201a.qrc) + ADD_VM(pc8201 emupc8201a _PC8201A) +endif() + +if(BUILD_PC98LT) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc98lt.qrc) + ADD_VM(pc98ha emupc98lt _PC98LT) +endif() +if(BUILD_PC98HA) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc98ha.qrc) + ADD_VM(pc98ha emupc98ha _PC98HA) +endif() +if(BUILD_PCENGINE) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pcengine.qrc) + ADD_VM(pcengine emupcengine _PCENGINE) +endif() diff --git a/source/cmake/config_pc6001.cmake b/source/cmake/config_pc6001.cmake new file mode 100644 index 000000000..58c1388fc --- /dev/null +++ b/source/cmake/config_pc6001.cmake @@ -0,0 +1,26 @@ +set(BUILD_PC6001 ON CACHE BOOL "Build for NEC PC-6001") +set(BUILD_PC6001MK2 ON CACHE BOOL "Build for NEC PC-6001mk2") +set(BUILD_PC6001MK2SR ON CACHE BOOL "Build for NEC PC-6001mk2SR") +set(BUILD_PC6601 ON CACHE BOOL "Build for NEC PC-6601") +set(BUILD_PC6601SR ON CACHE BOOL "Build for NEC PC-6601SR") + +if(BUILD_PC6001) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc6001.qrc) + ADD_VM(pc6001 emupc6001 _PC6001) +endif() +if(BUILD_PC6001MK2) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc6001mk2.qrc) + ADD_VM(pc6001 emupc6001mk2 _PC6001MK2) +endif() +if(BUILD_PC6001MK2SR) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc6001mk2sr.qrc) + ADD_VM(pc6001 emupc6001mk2sr _PC6001MK2SR) +endif() +if(BUILD_PC6601) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc6601.qrc) + ADD_VM(pc6001 emupc6601 _PC6601) +endif() +if(BUILD_PC6601SR) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc6601sr.qrc) + ADD_VM(pc6001 emupc6601sr _PC6601SR) +endif() diff --git a/source/cmake/config_pc8801.cmake b/source/cmake/config_pc8801.cmake new file mode 100644 index 000000000..669892234 --- /dev/null +++ b/source/cmake/config_pc8801.cmake @@ -0,0 +1,32 @@ +set(BUILD_PC8001 ON CACHE BOOL "Build for NEC PC-8001") +set(BUILD_PC8001MK2 ON CACHE BOOL "Build for NEC PC-8001mk2") +set(BUILD_PC8001SR ON CACHE BOOL "Build for NEC PC-8001 SR") +set(BUILD_PC8801 ON CACHE BOOL "Build for NEC PC-8801") +set(BUILD_PC8801MK2 ON CACHE BOOL "Build for NEC PC-8801mk2") +set(BUILD_PC8801MA ON CACHE BOOL "Build for NEC PC-8801 MA") + +if(BUILD_PC8001) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8001.qrc) + ADD_VM(pc8801 emupc8001 _PC8001) +endif() +if(BUILD_PC8001MK2) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8001mk2.qrc) + ADD_VM(pc8801 emupc8001mk2 _PC8001MK2) +endif() +if(BUILD_PC8001SR) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8001mk2sr.qrc) + ADD_VM(pc8801 emupc8001mk2sr _PC8001SR) +endif() + +if(BUILD_PC8801) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8801.qrc) + ADD_VM(pc8801 emupc8801 _PC8801) +endif() +if(BUILD_PC8801MK2) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8801mk2.qrc) + ADD_VM(pc8801 emupc8801mk2 _PC8801MK2) +endif() +if(BUILD_PC8801MA) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc8801ma.qrc) + ADD_VM(pc8801 emupc8801ma _PC8801MA) +endif() diff --git a/source/cmake/config_pc9801.cmake b/source/cmake/config_pc9801.cmake new file mode 100644 index 000000000..ea73b45dd --- /dev/null +++ b/source/cmake/config_pc9801.cmake @@ -0,0 +1,59 @@ +set(BUILD_PC9801 ON CACHE BOOL "Build for NEC PC-9801.") +set(BUILD_PC9801E ON CACHE BOOL "Build for NEC PC-9801E.") +set(BUILD_PC9801RA ON CACHE BOOL "Build for NEC PC-9801RA.") +set(BUILD_PC9801U ON CACHE BOOL "Build for NEC PC-9801U.") +set(BUILD_PC9801VF ON CACHE BOOL "Build for NEC PC-9801VF.") +set(BUILD_PC9801VM ON CACHE BOOL "Build for NEC PC-9801VM.") +set(BUILD_PC9801VX ON CACHE BOOL "Build for NEC PC-9801VX.") + +set(BUILD_PC98DO ON CACHE BOOL "Build for NEC PC-98DO.") + +set(BUILD_PC98RL ON CACHE BOOL "Build for NEC PC-98RL.") +set(BUILD_PC98XL ON CACHE BOOL "Build for NEC PC-98XL.") + +if(BUILD_PC9801) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc9801.qrc) + ADD_VM(pc9801 emupc9801 _PC9801) +endif() +if(BUILD_PC9801E) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc9801e.qrc) + ADD_VM(pc9801 emupc9801e _PC9801E) +endif() +if(BUILD_PC9801RA) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc9801ra.qrc) + ADD_VM(pc9801 emupc9801ra _PC9801RA) +endif() +if(BUILD_PC9801U) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc9801u.qrc) + ADD_VM(pc9801 emupc9801u _PC9801U) +endif() +if(BUILD_PC9801VF) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc9801vf.qrc) + ADD_VM(pc9801 emupc9801vf _PC9801VF) +endif() +if(BUILD_PC9801VM) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc9801vm.qrc) + ADD_VM(pc9801 emupc9801vm _PC9801VM) +endif() +if(BUILD_PC9801VX) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc9801vx.qrc) + ADD_VM(pc9801 emupc9801vx _PC9801VX) +endif() + +if(BUILD_PC98RL) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc98rl.qrc) + ADD_VM(pc9801 emupc98rl _PC98RL) +endif() +if(BUILD_PC98XL) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc98xl.qrc) + ADD_VM(pc9801 emupc98xl _PC98XL) +endif() + +if(BUILD_PC98DO) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc98do.qrc) + ADD_VM(pc9801 emupc98do _PC98DO) +endif() +if(BUILD_PC98DOPLUS) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pc98do.qrc) + ADD_VM(pc9801 emupc98doplus _PC98DOPLUS) +endif() diff --git a/source/cmake/config_sega.cmake b/source/cmake/config_sega.cmake new file mode 100644 index 000000000..a1c9bc730 --- /dev/null +++ b/source/cmake/config_sega.cmake @@ -0,0 +1,21 @@ +set(BUILD_SC3000 ON CACHE BOOL "Build for Sega SC-3000") +set(BUILD_GAMEGEAR ON CACHE BOOL "Build for Sega GameGear") +set(BUILD_MASTERSYSTEM ON CACHE BOOL "Build for Sega Master System") +#set(BUILD_MARK3 OFF CACHE BOOL "Build for Sega MarkIII") + +if(BUILD_SC3000) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/sc3000.qrc) + ADD_VM(sc3000 emusc3000 _SC3000) +endif() +if(BUILD_GAMEGEAR) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/gamegear.qrc) + ADD_VM(gamegear emugamegear _GAMEGEAR) +endif() +if(BUILD_MASTERSYSTEM) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mastersystem.qrc) + ADD_VM(gamegear emumastersystem _MASTERSYSTEM) +endif() +if(BUILD_MARK3) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/mark3.qrc) + ADD_VM(gamegear emumark3 _MARK3) +endif() diff --git a/source/cmake/config_singleboards.cmake b/source/cmake/config_singleboards.cmake new file mode 100644 index 000000000..24bbe47c5 --- /dev/null +++ b/source/cmake/config_singleboards.cmake @@ -0,0 +1,41 @@ +set(BUILD_BABBAGE2ND ON CACHE BOOL "Build Gijutsu-Hyoron-Sha Babbage-2nd") +set(BUILD_EX80 ON CACHE BOOL "Build TOSHIBA EX-80") +set(BUILD_SMB80TE ON CACHE BOOL "Build SHARP SM-B-80TE") +set(BUILD_TK80 ON CACHE BOOL "Build NEC TK-80") +set(BUILD_TK80BS ON CACHE BOOL "Build NEC TK-80BS") +set(BUILD_TK85 ON CACHE BOOL "Build NEC TK-85") +set(BUILD_YS6464A ON CACHE BOOL "Build SHINKO SANGYO YS-6464A") + + +if(BUILD_BABBAGE2ND) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/babbage2nd.qrc) + ADD_VM(babbage2nd emubabbage2nd _BABBAGE2ND) +endif() +if(BUILD_EX80) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/ex80.qrc) + ADD_VM(ex80 emuex80 _EX80) +endif() + +if(BUILD_SMB80TE) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/smb80te.qrc) + ADD_VM(smb80te emusmb80te _SMB80TE) +endif() + +if(BUILD_TK80) + # still not implemented 20200930 K.O + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/tk80.qrc) + ADD_VM(tk80bs emutk80 _TK80) +endif() +if(BUILD_TK80BS) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/tk80bs.qrc) + ADD_VM(tk80bs emutk80bs _TK80BS) +endif() +if(BUILD_TK85) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/tk85.qrc) + ADD_VM(tk80bs emutk85 _TK85) +endif() + +if(BUILD_YS6464A) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/ys6464a.qrc) + ADD_VM(ys6464a emuys6464a _YS6464A) +endif() diff --git a/source/cmake/config_toshiba.cmake b/source/cmake/config_toshiba.cmake new file mode 100644 index 000000000..966dc2d7e --- /dev/null +++ b/source/cmake/config_toshiba.cmake @@ -0,0 +1,47 @@ +set(BUILD_PASOPIA ON CACHE BOOL "Build for TOSHIBA PASOPIA") +set(BUILD_PASOPIA_LCD ON CACHE BOOL "Build for TOSHIBA PASOPIA with LCD") +set(BUILD_PASOPIA7 ON CACHE BOOL "Build for TOSHIBA PASOPIA7") +set(BUILD_PASOPIA7_LCD ON CACHE BOOL "Build for TOSHIBA PASOPIA7 with LCD") +set(BUILD_J3100GT ON CACHE BOOL "Build for Toshiba J-3100GT") +set(BUILD_J3100SL ON CACHE BOOL "Build for Toshiba J-3100SL") + +if(BUILD_PASOPIA) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pasopia.qrc) + ADD_VM(pasopia emupasopia _PASOPIA) +endif() +if(BUILD_PASOPIA_LCD) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pasopia_lcd.qrc) + ADD_VM(pasopia emupasopia_lcd _PASOPIA) + target_compile_definitions(emupasopia_lcd + PRIVATE -D_LCD + ) +endif() +if(BUILD_PASOPIA7) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pasopia7.qrc) + ADD_VM(pasopia7 emupasopia7 _PASOPIA7) +endif() +if(BUILD_PASOPIA7_LCD) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/pasopia7_lcd.qrc) + ADD_VM(pasopia7 emupasopia7_lcd _PASOPIA7) + target_compile_definitions(emupasopia_lcd + PRIVATE -D_LCD + ) +endif() + +if(BUILD_J3100GT) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/j3100gt.qrc) + ADD_VM(j3100 emuj3100gt _J3100GT) +endif() +if(BUILD_J3100SE) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/j3100se.qrc) + ADD_VM(j3100 emuj3100se _J3100SE) +endif() +if(BUILD_J3100SL) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/j3100sl.qrc) + ADD_VM(j3100 emuj3100sl _J3100SL) +endif() +if(BUILD_J3100SS) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/j3100ss.qrc) + ADD_VM(j3100 emuj3100ss _J3100SS) +endif() + diff --git a/source/cmake/config_x1.cmake b/source/cmake/config_x1.cmake new file mode 100644 index 000000000..017fb581a --- /dev/null +++ b/source/cmake/config_x1.cmake @@ -0,0 +1,27 @@ +set(BUILD_X1 ON CACHE BOOL "Build for X1") +set(BUILD_X1TURBO ON CACHE BOOL "Build for X1 Turbo") +set(BUILD_X1TURBOZ ON CACHE BOOL "Build for X1 TurboZ") +set(BUILD_X1TWIN ON CACHE BOOL "Build for X1 twin") + + +set(USE_FMGEN ON) +set(WITH_JOYSTICK ON) +set(WITH_MOUSE ON) +if(BUILD_X1) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/x1.qrc) + ADD_VM(x1 emux1 _X1) +endif() + +if(BUILD_X1TURBO) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/x1turbo.qrc) + ADD_VM(x1 emux1turbo _X1TURBO) +endif() +if(BUILD_X1TURBOZ) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/x1turboz.qrc) + ADD_VM(x1 emux1turboz _X1TURBOZ) +endif() + +if(BUILD_X1TWIN) + set(RESOURCE ${PROJECT_SOURCE_DIR}/src/qt/common/qrc/x1twin.qrc) + ADD_VM(x1 emux1twin _X1TWIN) +endif() diff --git a/source/build-cmake/cmake/detect_target_cpu.cmake b/source/cmake/detect_target_cpu.cmake similarity index 100% rename from source/build-cmake/cmake/detect_target_cpu.cmake rename to source/cmake/detect_target_cpu.cmake diff --git a/source/build-cmake/cmake/simd-x86.cmake b/source/cmake/simd-x86.cmake similarity index 100% rename from source/build-cmake/cmake/simd-x86.cmake rename to source/cmake/simd-x86.cmake diff --git a/source/cmake/toolchains/toolchain_mingw_cross_gcc.cmake b/source/cmake/toolchains/toolchain_mingw_cross_gcc.cmake new file mode 100644 index 000000000..c90f50d0c --- /dev/null +++ b/source/cmake/toolchains/toolchain_mingw_cross_gcc.cmake @@ -0,0 +1,52 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +SET(TARGET_ARCH i686-w64-mingw32) +SET(LIBS_PREFIX /usr/local/i586-mingw-msvc) +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER ${TARGET_ARCH}-gcc) +SET(CMAKE_CXX_COMPILER ${TARGET_ARCH}-g++) +SET(CMAKE_RC_COMPILER ${TARGET_ARCH}-windres) +SET(CMAKE_AR ${TARGET_ARCH}-ar) +SET(CMAKE_LD ${TARGET_ARCH}-ld.bfd) +SET(USING_TOOLCHAIN_GCC_DEBIAN ON) + +#set(LIBAV_ROOT_DIR "${LIBS_PREFIX}/ffmpeg-4.1") + +# here is the target environment located +set(USE_SDL2 ON) +if(USE_SDL2) + SET(CMAKE_FIND_ROOT_PATH /usr/${TARGET_ARCH} + ${LIBS_PREFIX} + ${LIBS_PREFIX}/SDL/${TARGET_ARCH} + ${LIBS_PREFIX}/Qt5.15/mingw_82x + ) +else() + SET(CMAKE_FIND_ROOT_PATH /usr/${TARGET_ARCH} + ${LIBS_PREFIX} + ${LIBS_PREFIX}/SDL1/ + ${LIBS_PREFIX}/Qt5.15/mingw_82x + ) +endif() +SET(CSP_CROSS_BUILD 1) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(SDL2_LIBRARIES + ${LIBS_PREFIX}/SDL/${TARGET_ARCH}/lib/libSDL2.dll.a + ${LIBS_PREFIX}/SDL/${TARGET_ARCH}/lib/libSDL2main.a) +set(SDL2_INCLUDE_DIRS ${LIBS_PREFIX}/SDL/${TARGET_ARCH}/include/SDL2) + +set(SDL_LIBRARIES + ${LIBS_PREFIX}/SDL1/lib/libSDL.dll.a + ${LIBS_PREFIX}/SDL1/lib/libSDLmain.a) +set(SDL_INCLUDE_DIRS ${LIBS_PREFIX}/SDL1/include/SDL) + +set(SDLMAIN_LIBRARY "") + +set(ADDITIONAL_LIBRARIES libwinmm.a) diff --git a/source/build-cmake/cmake/toolchain_mingw_cross_linux.cmake b/source/cmake/toolchains/toolchain_mingw_cross_linux.cmake similarity index 84% rename from source/build-cmake/cmake/toolchain_mingw_cross_linux.cmake rename to source/cmake/toolchains/toolchain_mingw_cross_linux.cmake index 23c891d22..fb97f2c86 100644 --- a/source/build-cmake/cmake/toolchain_mingw_cross_linux.cmake +++ b/source/cmake/toolchains/toolchain_mingw_cross_linux.cmake @@ -5,12 +5,8 @@ SET(CMAKE_SYSTEM_NAME Windows) SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc) SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++) SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) -SET(CMAKE_AR i686-w64-mingw32-gcc-ar) +SET(CMAKE_AR i686-w64-mingw32-ar) -#SET(CMAKE_C_COMPILER i686-w64-mingw32-clang) -#SET(CMAKE_CXX_COMPILER i686-w64-mingw32-clang++) -#SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) -#SET(CMAKE_AR i686-w64-mingw32-gcc-ar) #set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") #set(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++") @@ -21,7 +17,7 @@ SET(CMAKE_AR i686-w64-mingw32-gcc-ar) #SET(CMAKE_CXX_ARCHIVE_CREATE " qcs --plugin==$(i686-w64-mingw32-gcc --print-file-name=liblto_plugin.so) ") #SET(CMAKE_CXX_ARCHIVE_FINISH true) -set(LIBAV_ROOT_DIR "/usr/local/i586-mingw-msvc/ffmpeg-4.1") +#set(LIBAV_ROOT_DIR "/usr/local/i586-mingw-msvc/ffmpeg-4.1") # here is the target environment located set(USE_SDL2 ON) @@ -29,13 +25,13 @@ if(USE_SDL2) SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 /usr/local/i586-mingw-msvc /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32 - /usr/local/i586-mingw-msvc/5.12/mingw_82x + /usr/local/i586-mingw-msvc/Qt5.15/mingw_82x ) else() SET(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32 /usr/local/i586-mingw-msvc /usr/local/i586-mingw-msvc/SDL1/ - /usr/local/i586-mingw-msvc/5.12/mingw_82x + /usr/local/i586-mingw-msvc/Qt5.15/mingw_82x ) endif() SET(CSP_CROSS_BUILD 1) diff --git a/source/cmake/toolchains/toolchain_mingw_cross_llvm11.cmake b/source/cmake/toolchains/toolchain_mingw_cross_llvm11.cmake new file mode 100644 index 000000000..c162bda0a --- /dev/null +++ b/source/cmake/toolchains/toolchain_mingw_cross_llvm11.cmake @@ -0,0 +1,52 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) + +SET(TARGET_ARCH i686-w64-mingw32) +SET(LIBS_PREFIX /usr/local/i586-mingw-msvc) +# which compilers to use for C and C++ +SET(CMAKE_C_COMPILER ${TARGET_ARCH}-clang) +SET(CMAKE_CXX_COMPILER ${TARGET_ARCH}-clang++) +SET(CMAKE_RC_COMPILER ${TARGET_ARCH}-windres) +SET(CMAKE_AR ${TARGET_ARCH}-ar) +SET(CMAKE_LD ${TARGET_ARCH}-ld) + + +#set(LIBAV_ROOT_DIR "${LIBS_PREFIX}/ffmpeg-4.1") + +# here is the target environment located +set(USE_SDL2 ON) +if(USE_SDL2) + SET(CMAKE_FIND_ROOT_PATH /usr/${TARGET_ARCH} + ${LIBS_PREFIX} + ${LIBS_PREFIX}/SDL/${TARGET_ARCH} + ${LIBS_PREFIX}/Qt5.15/mingw_82x + ) +else() + SET(CMAKE_FIND_ROOT_PATH /usr/${TARGET_ARCH} + ${LIBS_PREFIX} + ${LIBS_PREFIX}/SDL1/ + ${LIBS_PREFIX}/Qt5.15/mingw_82x + ) +endif() +SET(CSP_CROSS_BUILD 1) + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(SDL2_LIBRARIES + ${LIBS_PREFIX}/SDL/${TARGET_ARCH}/lib/libSDL2.dll.a + ${LIBS_PREFIX}/SDL/${TARGET_ARCH}/lib/libSDL2main.a) +set(SDL2_INCLUDE_DIRS ${LIBS_PREFIX}/SDL/${TARGET_ARCH}/include/SDL2) + +set(SDL_LIBRARIES + ${LIBS_PREFIX}/SDL1/lib/libSDL.dll.a + ${LIBS_PREFIX}/SDL1/lib/libSDLmain.a) +set(SDL_INCLUDE_DIRS ${LIBS_PREFIX}/SDL1/include/SDL) + +set(SDLMAIN_LIBRARY "") + +set(ADDITIONAL_LIBRARIES libwinmm.a) diff --git a/source/cmake/toolchains/toolchain_native_gcc.cmake b/source/cmake/toolchains/toolchain_native_gcc.cmake new file mode 100644 index 000000000..ecda34fca --- /dev/null +++ b/source/cmake/toolchains/toolchain_native_gcc.cmake @@ -0,0 +1,12 @@ +# the name of the target operating system +#SET(CMAKE_SYSTEM_NAME Windows) +SET(CSP_CROSS_BUILD 0) + +# Choose an appropriate compiler prefix +#set(CMAKE_TOOLCHAIN_PREFIX "i686-w64-mingw32") + +# which compilers to use for C and C++ +#SET(CMAKE_SYSTEM_NAME Windows) + +SET(CMAKE_C_COMPILER gcc) +SET(CMAKE_CXX_COMPILER g++) diff --git a/source/cmake/toolchains/toolchain_native_llvm.cmake b/source/cmake/toolchains/toolchain_native_llvm.cmake new file mode 100644 index 000000000..95910a026 --- /dev/null +++ b/source/cmake/toolchains/toolchain_native_llvm.cmake @@ -0,0 +1,32 @@ +# the name of the target operating system +#SET(CMAKE_SYSTEM_NAME Windows) +SET(CSP_CROSS_BUILD 0) + +# Choose an appropriate compiler prefix +#set(CMAKE_TOOLCHAIN_PREFIX "i686-w64-mingw32") + +# which compilers to use for C and C++ +#SET(CMAKE_SYSTEM_NAME Windows) + +SET(CMAKE_C_COMPILER clang) +SET(CMAKE_CXX_COMPILER clang++) +#SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) +SET(CMAKE_AR llvm-ar) +SET(CMAKE_C_COMPILER_AR llvm-ar) +SET(CMAKE_CXX_COMPILER_AR llvm-ar) +SET(CMAKE_LD lld) +SET(CMAKE_LINKER lld-10) +SET(CMAKE_EXE_LINKER lld-10) +SET(CMAKE_SHARED_LINKER lld-10) +SET(CMAKE_NM nm) +#SET(CMAKE_RANLIB ranlib) +#SET(CMAKE_C_COMPILER_RANLIB ranlib) +#SET(CMAKE_CXX_COMPILER_RANLIB ranlib) + +#SET(CSP_ADDTIONAL_FLAGS_COMPILE_RELWITHDEBINFO -g2 -gz -flto) +#SET(CSP_ADDTIONAL_FLAGS_LINK_RELWITHDEBINFO -g2 -gz -flto -O2) +#SET(CSP_ADDTIONAL_FLAGS_COMPILE_RELEASE -flto) +#SET(CSP_ADDTIONAL_FLAGS_LINK_RELEASE -flto -O3) +#SET(CMAKE_CXX_FLAGS "-g2 -gz -flto") +#SET(CMAKE_C_FLAGS "-g2 -gz -flto") +#SET(CMAKE_EXE_LINK_FLAGS "-g2 -gz -flto") diff --git a/source/cmake/toolchains/toolchain_native_llvm11.cmake b/source/cmake/toolchains/toolchain_native_llvm11.cmake new file mode 100644 index 000000000..12f985f7a --- /dev/null +++ b/source/cmake/toolchains/toolchain_native_llvm11.cmake @@ -0,0 +1,32 @@ +# the name of the target operating system +#SET(CMAKE_SYSTEM_NAME Windows) +SET(CSP_CROSS_BUILD 0) + +# Choose an appropriate compiler prefix +#set(CMAKE_TOOLCHAIN_PREFIX "i686-w64-mingw32") + +# which compilers to use for C and C++ +#SET(CMAKE_SYSTEM_NAME Windows) + +SET(CMAKE_C_COMPILER clang-11) +SET(CMAKE_CXX_COMPILER clang++-11) +#SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) +SET(CMAKE_AR llvm-ar) +SET(CMAKE_C_COMPILER_AR llvm-ar) +SET(CMAKE_CXX_COMPILER_AR llvm-ar) +SET(CMAKE_LD lld) +SET(CMAKE_LINKER lld-10) +SET(CMAKE_EXE_LINKER lld-10) +SET(CMAKE_SHARED_LINKER lld-10) +SET(CMAKE_NM nm) +#SET(CMAKE_RANLIB ranlib) +#SET(CMAKE_C_COMPILER_RANLIB ranlib) +#SET(CMAKE_CXX_COMPILER_RANLIB ranlib) + +#SET(CSP_ADDTIONAL_FLAGS_COMPILE_RELWITHDEBINFO -g2 -gz -flto) +#SET(CSP_ADDTIONAL_FLAGS_LINK_RELWITHDEBINFO -g2 -gz -flto -O2) +#SET(CSP_ADDTIONAL_FLAGS_COMPILE_RELEASE -flto) +#SET(CSP_ADDTIONAL_FLAGS_LINK_RELEASE -flto -O3) +#SET(CMAKE_CXX_FLAGS "-g2 -gz -flto") +#SET(CMAKE_C_FLAGS "-g2 -gz -flto") +#SET(CMAKE_EXE_LINK_FLAGS "-g2 -gz -flto") diff --git a/source/cmake/toolchains/toolchain_win32_cross_linux_llvm.cmake b/source/cmake/toolchains/toolchain_win32_cross_linux_llvm.cmake new file mode 100644 index 000000000..ca18567fb --- /dev/null +++ b/source/cmake/toolchains/toolchain_win32_cross_linux_llvm.cmake @@ -0,0 +1,92 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) +SET(CSP_CROSS_BUILD 1) + +# Choose an appropriate compiler prefix +set(CMAKE_TOOLCHAIN_PREFIX "i686-w64-mingw32") + +# which compilers to use for C and C++ +SET(CMAKE_SYSTEM_NAME Windows) + +SET(CMAKE_C_COMPILER i686-w64-mingw32-clang) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-clang++) +SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) +SET(CMAKE_AR i686-w64-mingw32-ar) +SET(CMAKE_C_COMPILER_AR i686-w64-mingw32-ar) +SET(CMAKE_CXX_COMPILER_AR i686-w64-mingw32-ar) +SET(CMAKE_LD /usr/bin/i686-w64-mingw32-ld) +#SET(CMAKE_LINKER /usr/bin/i686-w64-mingw32-ld) +#SET(CMAKE_EXE_LINKER /usr/bin/i686-w64-mingw32-ld) +#SET(CMAKE_SHARED_LINKER /usr/bin/i686-w64-mingw32-ld) +SET(CMAKE_NM i686-w64-mingw32-nm) +SET(CMAKE_RANLIB i686-w64-mingw32-ranlib) +SET(CMAKE_C_COMPILER_RANLIB i686-w64-mingw32-ranlib) +SET(CMAKE_CXX_COMPILER_RANLIB i686-w64-mingw32-ranlib) + +#find_program(CMAKE_RC_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-windres) +#find_program(CMAKE_C_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-clang) +#find_program(CMAKE_CXX_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-clang++) +#find_program(CMAKE_ASM_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-as) + +#set(CMAKE_C_COMPILER "${CMAKE_TOOLCHAIN_PREFIX}-clang" "-target ${CMAKE_TOOLCHAIN_PREFIX} -isystem /opt/llvm-mingw/${CMAKE_TOOLCHAIN_PREFIX}/include -isystem /usr/local/${CMAKE_TOOLCHAIN_PREFIX}/include") +#set(CMAKE_CXX_COMPILER "${CMAKE_TOOLCHAIN_PREFIX}-clang++" "-target ${CMAKE_TOOLCHAIN_PREFIX} -isystem /opt/llvm-mingw/${CMAKE_TOOLCHAIN_PREFIX}/include -isystem /usr/local/${CMAKE_TOOLCHAIN_PREFIX}/include") + +set(CMAKE_CXX_FLAGS "-target i686-w64-mingw32") +set(CMAKE_C_FLAGS "-target i686-w64-mingw32") +#set(CMAKE_CXX_FLAGS "-target i686-w64-mingw32") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/lib/clang/3.9.0/include") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include/../../../usr/lib/gcc/i686-w64-mingw32/8.2-win32/include/c++") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include/../../../usr/lib/gcc/i686-w64-mingw32/8.2-win32/include/c++/i686-w64-mingw32") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include") + +set(CMAKE_EXE_LINKER_FLAGS "-L/usr/i686-w64-mingw32/lib -target i686-w64-mingw32 ") +set(CMAKE_SHARED_LINKER_FLAGS "-L/usr/i686-w64-mingw32/lib -target i686-w64-mingw32 ") + +#set(CMAKE_EXE_LINKER_FLAGS "") + +set(LIBAV_ROOT_DIR "/usr/local/i586-mingw-msvc/ffmpeg-4.3") + + +# here is the target environment located +# here is the target environment located +set(CMAKE_FIND_ROOT_PATH /usr/${CMAKE_TOOLCHAIN_PREFIX} /opt/llvm-mingw/${CMAKE_TOOLCHAIN_PREFIX}) + +set(USE_SDL2 ON) +if(USE_SDL2) + SET(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} /usr/i686-w64-mingw32 + /usr/local/i586-mingw-msvc + /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32 + /usr/local/i586-mingw-msvc/Qt5.15/mingw_82x + ) +else() + SET(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} /usr/i686-w64-mingw32 + /usr/local/i586-mingw-msvc + /usr/local/i586-mingw-msvc/SDL1/ + /usr/local/i586-mingw-msvc/Qt5.15/mingw_82x + ) +endif() + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +#set(CMAKE_CROSS_COMPILING TRUE) + + +set(SDL2_LIBRARIES + /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/lib/libSDL2.dll.a + /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/lib/libSDL2main.a) +set(SDL2_INCLUDE_DIRS /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/include/SDL2) + +set(SDL_LIBRARIES + /usr/local/i586-mingw-msvc/SDL1/lib/libSDL.dll.a + /usr/local/i586-mingw-msvc/SDL1/lib/libSDLmain.a) +set(SDL_INCLUDE_DIRS /usr/local/i586-mingw-msvc/SDL1/include/SDL) + +set(SDLMAIN_LIBRARY "") + +set(ADDITIONAL_LIBRARIES libwinmm.a) + diff --git a/source/cmake/toolchains/toolchain_win32_cross_llvm11.cmake b/source/cmake/toolchains/toolchain_win32_cross_llvm11.cmake new file mode 100644 index 000000000..82f0af15d --- /dev/null +++ b/source/cmake/toolchains/toolchain_win32_cross_llvm11.cmake @@ -0,0 +1,92 @@ +# the name of the target operating system +SET(CMAKE_SYSTEM_NAME Windows) +SET(CSP_CROSS_BUILD 1) + +# Choose an appropriate compiler prefix +set(CMAKE_TOOLCHAIN_PREFIX "i686-w64-mingw32") + +# which compilers to use for C and C++ +SET(CMAKE_SYSTEM_NAME Windows) + +SET(CMAKE_C_COMPILER i686-w64-mingw32-clang) +SET(CMAKE_CXX_COMPILER i686-w64-mingw32-clang++) +SET(CMAKE_RC_COMPILER i686-w64-mingw32-windres) +SET(CMAKE_AR i686-w64-mingw32-ar) +SET(CMAKE_C_COMPILER_AR i686-w64-mingw32-ar) +SET(CMAKE_CXX_COMPILER_AR i686-w64-mingw32-ar) +SET(CMAKE_LD /usr/bin/i686-w64-mingw32-ld) +#SET(CMAKE_LINKER /usr/bin/i686-w64-mingw32-ld) +#SET(CMAKE_EXE_LINKER /usr/bin/i686-w64-mingw32-ld) +#SET(CMAKE_SHARED_LINKER /usr/bin/i686-w64-mingw32-ld) +SET(CMAKE_NM i686-w64-mingw32-nm) +SET(CMAKE_RANLIB i686-w64-mingw32-ranlib) +SET(CMAKE_C_COMPILER_RANLIB i686-w64-mingw32-ranlib) +SET(CMAKE_CXX_COMPILER_RANLIB i686-w64-mingw32-ranlib) + +#find_program(CMAKE_RC_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-windres) +#find_program(CMAKE_C_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-clang) +#find_program(CMAKE_CXX_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-clang++) +#find_program(CMAKE_ASM_COMPILER NAMES ${CMAKE_TOOLCHAIN_PREFIX}-as) + +#set(CMAKE_C_COMPILER "${CMAKE_TOOLCHAIN_PREFIX}-clang" "-target ${CMAKE_TOOLCHAIN_PREFIX} -isystem /opt/llvm-mingw-11/${CMAKE_TOOLCHAIN_PREFIX}/include -isystem /usr/local/${CMAKE_TOOLCHAIN_PREFIX}/include") +#set(CMAKE_CXX_COMPILER "${CMAKE_TOOLCHAIN_PREFIX}-clang++" "-target ${CMAKE_TOOLCHAIN_PREFIX} -isystem /opt/llvm-mingw-11/${CMAKE_TOOLCHAIN_PREFIX}/include -isystem /usr/local/${CMAKE_TOOLCHAIN_PREFIX}/include") + +set(CMAKE_CXX_FLAGS "-target i686-w64-mingw32") +set(CMAKE_C_FLAGS "-target i686-w64-mingw32") +#set(CMAKE_CXX_FLAGS "-target i686-w64-mingw32") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/lib/clang/3.9.0/include") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include/../../../usr/lib/gcc/i686-w64-mingw32/8.2-win32/include/c++") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include/../../../usr/lib/gcc/i686-w64-mingw32/8.2-win32/include/c++/i686-w64-mingw32") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem /usr/i686-w64-mingw32/include") + +set(CMAKE_EXE_LINKER_FLAGS "-L/usr/i686-w64-mingw32/lib -target i686-w64-mingw32 ") +set(CMAKE_SHARED_LINKER_FLAGS "-L/usr/i686-w64-mingw32/lib -target i686-w64-mingw32 ") + +#set(CMAKE_EXE_LINKER_FLAGS "") + +set(LIBAV_ROOT_DIR "/usr/local/i586-mingw-msvc/ffmpeg-4.3") + + +# here is the target environment located +# here is the target environment located +set(CMAKE_FIND_ROOT_PATH /opt/llvm-mingw-11/${CMAKE_TOOLCHAIN_PREFIX} /usr/${CMAKE_TOOLCHAIN_PREFIX} ) + +set(USE_SDL2 ON) +if(USE_SDL2) + SET(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} /usr/i686-w64-mingw32 + /usr/local/i586-mingw-msvc + /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32 + /usr/local/i586-mingw-msvc/Qt5.15/mingw_82x + ) +else() + SET(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} /usr/i686-w64-mingw32 + /usr/local/i586-mingw-msvc + /usr/local/i586-mingw-msvc/SDL1/ + /usr/local/i586-mingw-msvc/Qt5.15/mingw_82x + ) +endif() + +# adjust the default behaviour of the FIND_XXX() commands: +# search headers and libraries in the target environment, search +# programs in the host environment +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +#set(CMAKE_CROSS_COMPILING TRUE) + + +set(SDL2_LIBRARIES + /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/lib/libSDL2.dll.a + /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/lib/libSDL2main.a) +set(SDL2_INCLUDE_DIRS /usr/local/i586-mingw-msvc/SDL/i686-w64-mingw32/include/SDL2) + +set(SDL_LIBRARIES + /usr/local/i586-mingw-msvc/SDL1/lib/libSDL.dll.a + /usr/local/i586-mingw-msvc/SDL1/lib/libSDLmain.a) +set(SDL_INCLUDE_DIRS /usr/local/i586-mingw-msvc/SDL1/include/SDL) + +set(SDLMAIN_LIBRARY "") + +set(ADDITIONAL_LIBRARIES libwinmm.a) + diff --git a/source/build-cmake/cmake/windows-mingw-cross.cmake b/source/cmake/toolchains/windows-mingw-cross.cmake similarity index 100% rename from source/build-cmake/cmake/windows-mingw-cross.cmake rename to source/cmake/toolchains/windows-mingw-cross.cmake diff --git a/source/history.txt b/source/history.txt index b271589f1..41334a788 100644 --- a/source/history.txt +++ b/source/history.txt @@ -1,3 +1,120 @@ +8/16/2020 + +[VM/SCSI_DEV] improve to specify data req signal delay (thanks Mr.Sato) +[VM/SCSI_DEV] fix read6/write6 command in 0 length case (thanks Mr.Sato) +[VM/SISI_HDD] change drive type to hot swappable +[VM/SISI_HDD] improve seek time (thanks Mr.Sato) +[VM/SASI_HDD] support winchester drive parameters command +[VM/Z80DMA] improve to sense rdy signal as level, not edge (thanks Mr.Sato) + +[MZ2500/CRTC] fix sub plane address in 640x200 16colors mode (thanks Mr.856) +[SVI3X8] support SPECTRAVIDEO SVI-3x8 (thanks Mr.tanam) +[X1] add menu items for FD2/FD3 (thanks Mr.Sato) +[X1/DISPLAY] fix high speed pcg definition (thanks Mr.YAT) +[X1TURBOZ/DISPLAY] improve palette update timing (thanks Mr.Sato) + + +8/14/2020 + +[OSD/WIN32] support x64 build (thank Mr.Marukun) +[OSD/WIN32] support Direct2D + +[MICOM_MAHJONG] support Nippon Mail Service MICOM MAHJONG (thanks Mr.GORRY) +[TVBOY] support GAKKEN TV BOY (thanks Mr.tanam) + + +4/6/2020 + +[VM/I386_NP21] update to Neko Project 21/W ver0.86 rev72 + + +2/21/2020 + +[VM/I386_NP21] update to Neko Project 21/W ver0.86 rev71 beta4 + +[PC9801VX] support to switch cpu mode to V30 +[PC9801RA] support to switch cpu mode to V30 + + +2/17/2020 + +[EMU] add is_floppy_disk_connected() and is_quick_disk_connected() +[WINMAIN] disable floppy/quick disk drive menus when drives are disconnected + +[VM/I8080] improve disassembler to distinguish 8080 and 8085 +[VM/I86] split i86/i88/i186/v30 from I286 class +[VM/I86] fix aam in v30 +[VM/I86] support 8080 emulation mode in V30 +[VM/I386_NP21] improve not to explicitly accept irq while executing opecode +[VM/I386_DASM] split i386 disassembler from I286/I386 class +[VM/V30_DASM] split v30 disassembler from I286 class +[VM/V30_DASM] add 8080 disassebler for 8080 emulation mode +[VM/VM_TEMPLATE] add is_floppy_disk_connected() and is_quick_disk_connected() + +[PC9801] support to enable/disable 1MB/640K/320KB-FDD interfaces + + +2/1/2020 + +[EMU] support to create blank hard disk image (*.hdi/*.nhd) +[WINMAIN] add menu items to mount blank hard disk image + +[VM/DEVICE] improve memory/io bus interfaces for 16/32bit access +[VM/DEVICE] add get_event_clocks() and get_cpu_clocks() +[VM/EVENT] add get_event_clocks() and get_cpu_clocks() +[VM/I386_NP21] support 80386 (based on Neko Project 21/W i386 core) +[VM/I8259] make update_intr() public +[VM/MEMORY] improve memory bus interfaces for 16/32bit access +[VM/MEMORY] make rd_table/wr_table/addr_shift public +[VM/UPD7220] fix stop command (thanks Neko Project 21/W) + +[FMR50] change i386 core from MAME to Neko Project 21/W +[FMR50] support to mount blank hard disk image +[MZ2500] support to mount blank hard disk image +[MZ2800] support to mount blank hard disk image +[PC9801] change i386 core from MAME to Neko Project 21/W +[PC9801] support to mount blank hard disk image +[PC9801/DISPLAY] improve code for big-endian host machine +[PC9801/FMSOUND] support 86-type PCM (thanks Neko Project 21/W) +[PC9801/MEMBUS] improve memory bus interfaces for 16/32bit access +[PC9801/MOUSE] fix irq number in hireso mode +[PC9801/SASI] improve irq/drq signals to generate from sasi bus signals +[X1TURBO] support to mount blank hard disk image +[X1TURBO/IOBUS] fix not to clear vram in reset() + + +1/23/2020 + +[VM/Z80DMA] fix byte counter read by read mask follows command (thanks Mr.Sato) + + +12/31/2019 + +[MZ2500/CRTC] apply crtc patch (thanks Mr.Koucha-Youkan) + + +11/3/2019 + +[PC98RL] fix horizontal frequency +[PC98RL/DISPLAY] fix not to change horizontal frequency +[PC98RL/DISPLAY] fix cg window +[PC98RL/DISPLAY] fix multiple vram planes accessing +[PC9801/DISPLAY] fix vram word accessing (thanks Mr.Artane.) + + +10/28/2019 + +[X1/PSUB] improve tape recording +[X1/SUB] improve tape stopping +[X1/SUB] improve tape write-protected signal + + +10/22/2019 + +[X1/PSUB] improve tape end signal +[X1/SUB] improve tape end signal + + 4/30/2019 [VM/DEVICE] add is_primary_cpu() and update_extra_event() @@ -12,6 +129,13 @@ [PC8801MA] improve to enable/disable changing palette for each scan line +2/19/2019-2 + +[VM/DEVICE] revirt fixes in 2/19/2019 +[VM/EVENT] revirt fixes in 2/19/2019 +[VM/Z80] revirt fixes in 2/19/2019 + + 2/19/2019 [VM/DEVICE] add is_primary_cpu() and update_extra_event() diff --git a/source/license/KST32B/LICENSE_KST32B_v2.txt b/source/license/KST32B/LICENSE_KST32B_v2.txt index 7b47887b7..eb8f4d77b 100644 --- a/source/license/KST32B/LICENSE_KST32B_v2.txt +++ b/source/license/KST32B/LICENSE_KST32B_v2.txt @@ -1,78 +1,78 @@ - K S T 3 2 B (KST32B version 2.0) + K S T 3 2 B (KST32B version 2.0) 説明文書 COPYRIGHT (C) 2004 by Saka.N (Saka.N.06@b3.mnx.ne.jp) - FREEWARE (free to copy,change...; NO RESPONSIBILITY) : ۏ + FREEWARE (free to copy,change...; NO RESPONSIBILITY) : 無保証 for KST32B ver 2.000 : 2004/01/24 by Saka.N - y 1 : Tv z - - JISfɂKST(Kanji-Stroke-Table:FontFile)ł. - KST,CSF/1ƂƎ`PlainTextFile(ASCII+pJi), -dl̓tHg{̂HeaderCommentɋLqĂ܂. tHgt@C -{̂,擪20sQƂĂ. - ver2.0ł,JIS1,(p)ASCII,p,ISO8859-15, -,(80%)JIS2Ă܂. A,ISO8859-15, -0xAD,,A0`FF1A20`1A7FMappingēĂ܂. - KST32B̓t[EFAł̂Ŗۏ؂,gp,zt,Ĕzt͎R -,gpʂ̂Ȃeɂ‚Ă,ӔCyєӔC,ؕ -˂܂. - - CSF/1(CompactStrokeFontFormat/ver1)`yKST32B̓L܂. - - E RpNgł; 2Ɩ160KByte. - E 30x32̊iq_WԒ(Segment),Stroke`Ă. - E JISC6226X0208̕`ɊÂĂ邪,ɏ]Ă킯 - ł͂Ȃ. - E PlainText`Ȃ̂,pIł͂Ȃ,eLXgGfB^[łe - mFύX”\ł. - E R,|[^reB[ɗDĂ. + 【 1 : 概要 】 + + JIS漢字をモデルにしたKST(Kanji-Stroke-Table:FontFile)です. + このKSTは,CSF/1という独自形式のPlainTextFile(ASCII+半角カナ)で,その +仕様はフォント本体のHeaderCommentに記述しています. フォント・ファイル +本体の,先頭から約20行を参照してください. + 今回のver2.0では,JIS第1水準文字と,(半角の)ASCII,半角カナ,ISO8859-15, +それと,多く(約80%)のJIS第2水準漢字が入っています. 但し,ISO8859-15は, +0xADを除き,且つ,A0〜FFを1A20〜1A7FにMappingして入れています. + KST32Bはフリーウェアですので無保証で,使用,配付改変,再配付等は自由で +すが,使用した結果のいかなる影響についても,責任及び賠償責任は,一切負いか +ねます. + + CSF/1(CompactStrokeFontFormat/ver1)形式及びKST32Bの特徴を列記します. + + ・ コンパクトである; 第2水準を除くと約160KByte. + ・ 30x32の格子点座標を結ぶ直線(Segment)で,Strokeを定義している. + ・ JISのC6226とX0208の文字定義に基づいているが,厳密に従っているわけ + ではない. + ・ PlainText形式なので,実用的ではないが,テキスト・エディターでも内容 + 確認や変更が可能である. + ・ 同じ理由で,ポータビリティーに優れている. - y 2 : t@Cꗗ z + 【 2 : ファイル一覧 】 - KST32B.RDM : THIS FILE : { + KST32B.RDM : THIS FILE : 日本語取説 KST32B.MAN : Brief manual text(EnglishLike?) - KST32B.TXT : KST-FontData { + KST32B.TXT : KST-FontData 本体 - y 3 : ⑫ z + 【 3 : 補足 】 - (3.1) ֘ATool : - KST(tHg)̌`͓Ǝ`(CSF/1)ł̂,ʏ,̂܂ - ł͎g܂. KST̕\//`ϊ/XVTool,'KSTool' - ̂,VectorЂWib-siteɂČJł. Unix(Linux)& - X-WindowΏۂƂĂ܂,MS-Windows(95,98,98se,Me,2000,Xp) - NEC/PC-9801ł̍Œ̕\ToolĂ܂. + (3.1) 関連Tool : + このKST(フォント)の形式は独自形式(CSF/1)ですので,通常は,そのまま + では使えません. KSTの表示/印刷/形式変換/更新等のToolを,'KSTool'と + いう名称で,Vector社のWib-siteにて公開中です. これはUnix(Linux)& + X-Windowを主対象としていますが,MS-Windows(95,98,98se,Me,2000,Xp)や + NEC/PC-9801での最低限の表示Toolも入っています. - (3.2) BitmapWJsize : - Bitmapւ̓WJsize(Y-),12`150pixelxz肵Ă܂, - KSŤ`32pixelœKł(X-ɂ30). ̑,Y- - size32Ƃꍇ,1.1`1.9z肵Ă܂. Ă,i - ɒ[ɗȂƎv(?)܂. `̐[`(Cap)''𐄏 - ܂. + (3.2) Bitmap展開size : + Bitmapへの展開size(Y-方向)は,12〜150pixel程度を想定していますが, + KSTの形式上は32pixelが最適です(X-方向には30). 線の太さは,Y-方向の + sizeを32とした場合で,1.1〜1.9を想定しています. 多少太くても,品質が + 極端に落ちないと思って(?)います. 描画線の先端形状(Cap)は'丸'を推奨 + します. (3.3) Version_Up History : (3.3.1) KST32A : 1999/10 - ()1992NɊJJIS1KSTVector-Web-Site֌J. + (主に)1992年に開発したJIS第1水準KSTをVector-Web-Siteへ公開. (3.3.2) KST32B ver 1.0 : 2001/03 - JIS2̈ꕔlj,pASCIIƔpłlj. ꕔ̊ - \JIS-C6226X0208֕ύX. + JIS第2水準の一部を追加し,半角ASCIIと半角カナも追加. 一部の漢字の + 表現をJIS-C6226からX0208へ変更等. (3.3.3) KST32B ver 2.0 : 2004/01 - JIS2𑝂₵(Ŝ̖80%),1̌, - ISO8859-15̒lj. SpEuroSign0x2921ɉݒ蓙. + JIS第2水準漢字を増やした事(全体の約80%)と,第1水準漢字の見直し, + ISO8859-15の追加. 全角EuroSignも0x2921に仮設定等. - (3.4) p̒`̈ : - Sp,CSF/1̑SĂ̒`̈(30x32)gĂ܂,p - ꍇ,̍,15x32݂̂gĂ܂. + (3.4) 半角文字の定義領域 : + 全角文字は,CSF/1の全ての定義領域(30x32)を使っていますが,半角文字の + 場合は,その左半分の,15x32のみを使っています. - --- --- + --- 以 上 --- diff --git "a/source/license/np21w/\343\201\212\345\257\237\343\201\227\343\201\217\343\201\240\343\201\225\343\201\204.txt" "b/source/license/np21w/\343\201\212\345\257\237\343\201\227\343\201\217\343\201\240\343\201\225\343\201\204.txt" new file mode 100644 index 000000000..470bb93f8 --- /dev/null +++ "b/source/license/np21w/\343\201\212\345\257\237\343\201\227\343\201\217\343\201\240\343\201\225\343\201\204.txt" @@ -0,0 +1,1150 @@ + +・CPU 1GHz以上のマシンでの動作を推奨します … お察し下さい + +・SSE2,SSE3は試作段階です … お察し下さい + +・Screen Optionの Graphic Charger 及び 16色ボードは固定設定で選択できません … お察し下さい + +・フルスクリーンは16bpp固定です … お察し下さい + +・ver0.86 rev35からはfmgenを使用できます。fmgenはcisc氏が著作権を所有しています。 + +・fmgen_fmgen.cppの343行目は曖昧さを回避するためにインクリメントを分離しています + +Neko Project 21/W +開発者: SimK +site: https://sites.google.com/site/np21win +Twitter: https://twitter.com/simk98l +mail: simk98lfo@gmail.com + + +【改造版について】 + +この改造版は本家ねこぷろとは無関係の人間が作っています。 +無保証です。大事なHDイメージのバックアップはとっておくようにしてください。 + +改造により追加した以下のファイルはQEMUのうちMITライセンス部分のコードを含んでいるためMITライセンス≒BSDライセンスとします。 +・networkディレクトリ内のファイル +・wabディレクトリ内のファイル + +改造により追加した以下のファイルはDOSBoxのコードを含んでいるためGPLとします。 +・fpemul_dosbox.c +・fpemul_dosbox2.c +・fpemul_softfloat.c + +改造により追加した以下のファイルはMAMEのコードを含んでいるためGPLとします。 +・sound/mameディレクトリ内のファイル + +LGY-98はSUPPORT_NETとSUPPORT_LGY98を、CL-GD5430はSUPPORT_WABとSUPPORT_CL_GD5430をプリプロセッサ定義に追加することで使用できるようになります。ただし、これにより上記MITライセンスのファイルが含まれる点にご留意ください。 + +FPUはUSE_FPUをプリプロセッサ定義に追加することで使用できるようになります。ただし、これにより上記GPLのファイルが含まれる点にご留意ください。 + +MAME OPL3はUSE_MAMEをプリプロセッサ定義に追加することで使用できるようになります。ただし、これにより上記GPLのファイルが含まれる点にご留意ください。 + +また、SUPPORT_LARGE_HDDを定義すると2GBオーバーのハードディスクイメージを扱えるようになります。この際、compiler.hのNHD_MAXSIZEで作成可能な最大サイズ(MB)を指定可能です。DOS上では8GBまで正常に扱えます。それ以上はBIOSの都合によりWindowsのプロテクトモードドライバでしか利用できません。 + +SUPPORT_PC9821 +PC-9821関連の機能(256色モードとか)をサポートします。本家にもありますが以下の定義はこれが無いとまともに使えないので念のためここに書いておきます。 + +SUPPORT_IDEIO +IDEをサポートします。Windows2000の動作には必須。この定義自体は本家にもありますが、Neko Project 21/WではTRACEの定義は不要で、TRACEを定義してもSUPPORT_IDEIOは定義されません。 + +SUPPORT_LARGE_HDD +2GBを越えるNHD形式ディスクイメージをサポートします。Windows2000を使う場合には事実上必須。 + +SUPPORT_HRTIMER +高分解能タイマをサポートします + +SUPPORT_NET +ネットワーク(LAN)基本機能を有効にします。ネットワークデバイスを使用する場合には必須(の予定)。 + +SUPPORT_WAB +ウィンドウアクセラレータ基本機能を有効にします。ウィンドウアクセラレータを使用する場合には必須(の予定)。 + +SUPPORT_LGY98 +メルコのLGY-98を使用可能にする。SUPPORT_NETの定義が必要。定義するとライセンスがGPLv2になります。 + +SUPPORT_CL_GD5430 +Cirrus LogicのCL-GD5430を使用可能にする。SUPPORT_WABの定義が必要。定義するとライセンスがGPLv2になります。 + +SUPPORT_VPCVHD +VirtualPCの固定サイズVHDイメージをサポートする。 + +SUPPORT_PHYSICAL_CDDRV +物理CD/DVDドライブのマウントをサポートする。コンパイルにWinDDKが必要です。 + +SUPPORT_FMGEN +fmgenをサポートします。使用する際はsound/fmgenのfmgen_readme.txtに書かれているfmgenのライセンス(著作権明記・フリーソフト化・改変明示・テキスト添付など)に従ってください。 +fmgenにはソースコード再配布にも制約がありますので、fmgenのライセンスに従えない場合はこれらのソース(sound/fmgen)を削除してください。 + +SUPPORT_PCI +PCIバスをサポートします。 + +SUPPORT_FPU_DOSBOX +DOSBoxから移植された64bit倍精度浮動小数点FPUを使用可能にします。実CPUの精度より劣るため結果が不正確になる場合があります。USE_FPUの定義も必要です。DOSBoxからの移植コードが含まれるため、これを含めてコンパイルするとライセンスがGPLになります。 + +SUPPORT_FPU_DOSBOX2 +DOSBoxから移植された64bit倍精度浮動小数点FPUに80bit拡張倍精度相当の整数ロード・ストア機能を追加したものを使用可能にします。整数のロード・ストア命令以外は実CPUの精度より劣るため結果が不正確になる場合があります。USE_FPUの定義も必要です。DOSBoxからの移植コードが含まれるため、これを含めてコンパイルするとライセンスがGPLになります。 + +SUPPORT_FPU_SOFTFLOAT +FPUでBerkeley SoftFloatによる拡張倍精度浮動小数点数演算を使用します。ほとんどの浮動小数点数演算がx87 FPUの仕様通りの精度になりますが、パフォーマンスは悪くなります。USE_FPUの定義も必要です。DOSBoxからの移植コードも含まれるため、これを含めてコンパイルするとライセンスがGPLになります。 + +USE_FPU +FPUをサポートします。このバージョンでは使用可能なエミュレーションFPUを指定するためにSUPPORT_FPU_DOSBOX, SUPPORT_FPU_DOSBOX2またはSUPPORT_FPU_SOFTFLOATも定義してください。 + +SUPPORT_SCRN_DIRECT3D +Direct3Dによる画面描画をサポートします。拡大縮小時の補間モードを指定できるようになります。 + +SUPPORT_FAST_MEMORYCHECK +高速メモリチェック機能をサポートします + +SUPPORT_LARGE_MEMORY +256MBを超える大容量メモリの割り当てを可能にします。 + +SUPPORT_PEGC +PEGCプレーンモードを部分的にサポートします。 + +SUPPORT_ASYNC_CPU +CPUの非同期動作をサポートします。 + +SUPPORT_SMPU98 +Super MPUをサポートします。 + +SUPPORT_WACOM_TABLET +WACOM製ペンタブレットのエミュレーションをサポートします。 + +SUPPORT_RS232C_FIFO +RS-232CでFIFO通信モードをサポートします。 + +SUPPORT_NAMED_PIPE +COMポートとして名前付きパイプを使用できるようにします。 + +SUPPORT_IA32_HAXM +Intel Hardware Accelerated Execution Managerの仮想化支援を使用してCPUエミュレーションを行います +注意:HAXMを使用するとPC-98としての互換性がかなり失われるため注意 + +USE_TSC +タイムスタンプカウンタをサポートします。Pentium以降のエミュレーションに必要。 + +USE_MMX +MMX命令をサポートします。USE_FPUも必要です。Pentium II/MMX Pentiumのエミュレーションに必要。 + +USE_3DNOW +3DNow!命令をサポートします。USE_FPUも必要です。AMD K6-2, K6-IIIのエミュレーションに必要。 + +USE_SSE +SSE命令をサポートします。USE_FPU, USE_MMXも必要です。Pentium III/AMD K7 Athlon/AMD K7 Athlon XPのエミュレーションに必要。 + +USE_SSE2 +SSE2命令をサポートします。USE_FPU, USE_MMX, USE_SSEも必要です。Pentium Mのエミュレーションに必要。 + +USE_SSE3 +SSE3命令をサポートします。USE_FPU, USE_MMX, USE_SSE, USE_SSE2も必要です。Pentium 4のエミュレーションに必要。 + +USE_MAME +MAMEによるOPL3 FM音源をサポートします。MAMEのライセンス(GPL)に従えない場合はこれらのソース(sound/mame)を削除してください。 + +USE_FASTPAGING +ページングの際にウィンドウアクセラレータ関係のVRAMウィンドウ・MMIO処理を省略して高速化します。 + +USE_VME +仮想86モード拡張をサポートします。 + +BIOS_IO_EMULATION +エミュレーションBIOSによるI/Oポート操作のエミュレーション機能をサポートします。 + +HOOK_SYSKEY +システム関連ショートカットキーをローレベルシステムフックで乗っ取る。 + +ALLOW_MULTIRUN +猫を無条件で複数起動可能にする。ほぼテスト用。英語が怪しい。 + +・メモリは最大1500MB程度です。128MBを超え始めると挙動怪しいプログラムが増えてきます。64MB以下はどのようなプログラムでもほぼ安全です。 + +・Ctrl+Alt+Delは代わりにCtrl+Alt+ScrollLockに割り当てられていますが、押すのが無理な場合はメニューのSend Ctrl+Alt+Delを使うかソフトウェアキーボードを駆使してください(この場合実キーボードでCtrl+Altを押しながらソフトウェアキーボードのDelを押せばOKです) + +・LANはMELCOのLGY-98固定です + +・LANを動作させるにはTAP-Win32が必要です。外部ネットワークに繋ぎたいときはブリッジ接続などをしてください。 + +・対応しているウィンドウアクセラレータはPC-9821内蔵のCL-GD54xx(PCI接続含む)、PC-9801-96ボード、MELCO WAB-S, WSN-A2F, WSN-A4F、及びI-O DATA GA-98NBシリーズです(排他) + +・ウィンドウアクセラレータ別窓モードはキー操作とマウスキャプチャはメインウィンドウでしかできません + +・ウィンドウアクセラレータ別窓ではキー動作とマウスキャプチャ操作のみ可能です + +・ウィンドウアクセラレータ別窓のサイズをデフォルトに戻したい場合はシステムメニューで画面サイズリセットを選択してください + +・noreset版は廃止されました + +・trace版もバイナリ配布をやめました(TRACEをプリプロセッサ定義に追加して自分でコンパイルしてください) + +・2GB以上のサイズのNHDディスクイメージを作成可能ですが、オリジナルのNeko Project II/21では使用できません(ディスクが破壊される可能性があります) + + +【既知の問題点】 + +・LGY-98は公式のDOS用設定ユーティリティが使えません(設定が出来ないだけで状態確認などは出来ます) + +・IDEはWindows上での認識が不安定です(実機BIOS無しWin95/98ではCD-ROMドライブのみ) + + +【Special thanks】 +Neko Project 21/W の開発にあたり、以下の方々のご協力を頂きました。 +この場を借りて御礼申し上げます。 + +・富沢さん(SL9821作者) +Win9xにおけるマルチメディアタイマーの不具合修正と、Win95を除く全Windows用のFDC修正をしてくださいました。 + +・横内さん +Win95におけるFDC修正、Win2000においてIDEのスレーブデバイスを認識しない問題修正、WSN-A2F/A4FがWin9xで認識しない不具合、GA-98NBが正常に動作しない問題を修正してくださいました。 + + +【改造版 更新履歴】 +0.86 rev69 -> 0.86 rev70β1 +・CL-GD5446のVideo Window機能に対応しました +・非同期CD-ROMアクセスを改良しました(つもり) +・CD-DAでデータトラックを再生しようとしたときに自動スキップするオプションを追加 + ・INIにCDDTSKIP=trueを書くとスキップされるようになります +・マウスを高速で動かすと移動量がおかしくなる問題について対策 +・AsyncCPUの時の上限クロックを設定即時反映ではなくリセットまで記憶する仕様に変更 +・最近のCPUは高速らしいのでCPUクロック倍率設定に42倍を超える値を足しました + ・とりあえず90倍まで用意しましたが直接入力でそれ以上にも出来ます + ・ただし処理落ちすると無意味なので程々に + ・処理落ちはOther->Clock dispで表示されるクロックが設定値くらいになっているかどうかで分かります +・CPUフラグのCPU_FEATURE_CX8を立て忘れていたので立てました + ・この関係でConfigureのCPUタイプがcustomに変わってしまうので再設定してください + +0.86 rev68 -> 0.86 rev69 +・IDE BIOS無しの状態でもWin9xのIDEドライバでHDDを認識するようになりました + ・WINNTFIX=trueな状態でもちゃんと動きます + ・存在意義のなくなった従来のWINNTFIXは廃止されました + ・IDEデバイスの接続フラグの入れ方が多分間違っていたので直しました + ・デフォルト設定をIDE BIOSを使用しないように変更しました +・WinNT3.50が動かせるように出来たらしいです  + ・この機能を新たにWINNTFIX=trueに割り当てました(デフォルト状態では動きません) +・固定ディスク起動メニューが表示されるとWin9xの起動メニューに事実上入れなくなる不具合を修正 +・エミュレーションBIOS使用時のDA/UAとIDEデバイスの対応関係を正常化しました +・CR4のPCE(性能モニタリング・カウンタ・イネーブル)を実装しました +・HDイメージファイルをNVL.DLLで開いている時にステートセーブを使うとアクセス違反で落ちる不具合を修正 + ・この不具合はVHD形式などで発生していました(HDIやNHD等では起こりません) +・CDトレイの開閉コマンドの判定がおかしかったのを修正 +・CirrusのBitBltの範囲判定がおかしかったのを修正 +・Win2000でシリアルポートがおかしくなる不具合を修正 + ・HAXM版は修正されていましたが通常版に反映されていませんでした +・HAXM版とソースを統合しました + +0.86 rev67 -> 0.86 rev68 +・Win10 1903環境のDirect3Dフルスクリーンでメニューが出ない問題に対応 + ・この関係でDirect3D使用時は画面解像度を変更しない設定になります +  ・No change screen colors/resolutionにチェックを入れた扱いになります + ・以前の挙動にしたいときはScreen option->Rederer->Use Direct3D fullscreen exclusive modeにチェックを入れてください +  ・ただしメニューが出ない問題は再発します +・シリアルポート周りをいじくりました + ・今まで動かなかったものが動くようになっている可能性があります + ・今まで動いていたものが動かなくなっている可能性もあります → あったら教えて下さい + ・シリアルポートの通信設定をエミュレータ内から変えられるようにしました +  ・固定にしたいときはCOM設定のFixedにチェックを入れてください +・ワコム製ペンタブレットに何故か対応しました + ・Serial optionのCOM1 PortでPENTABを選んでください +  ・ホストに接続されているペンタブをシリアル接続ペンタブに見せかけます +  ・ArtPad IIをエミュレーションしているつもりです +  ・本物ペンタブを使いたいときはCOM1 Portを実際のポートにしてください + ・追加のモード(相対座標モードや筆圧無効モードなど)にも対応 +・メモリリークやアクセス違反系のバグを徹底的に修正しました + ・free/deleteのし忘れ、deleteとdelete[]の書き間違い、フック関数の登録解除忘れ等を修正 + ・メモリリークや終了時アクセス違反は起こらなくなったはずです +・MPU-PC98IIを無効にした状態で118音源を使うとおかしくなる不具合を修正 +・デバッグウィンドウの不具合とメモリリークを修正 +・Win2000でシリアルポートが使えない不具合を修正 +・シリアルポートで名前付きパイプをサポートしました + +0.86 rev66 -> 0.86 rev67 +・Super MPUを部分実装しました + ・NativeモードはIMMのMIDI IN/OUTしか使えません +  ・IMMのMIDI INはとりあえず実装したつもりですがノーチェックです + ・ラインナンバーはよく分からないのでとりあえず以下の設定で固定です +  ・ライン 0〜15 → Port A CH1〜CH16 +  ・ライン16〜31 → Port B CH1〜CH16 + ・S-MPU用の拡張メッセージはほぼ全部無視しています +  ・実質Continue Exclusiveだけしか実装してません + ・MPU-PC98IIとは独立に動きますので設定画面はMPU-PC98IIとS-MPUで分けました +  ・ちゃんと設定すればMPU-PC98IIとS-MPUで3ポート48ch使えるようになるそうです +  ・設定画面はMPU-PC98IIの使い回しですが気にしないで下さい +  ・Port AとPort Bに同じものを指定すると動かないと思いますのでご注意 +   ・MSGSしかない人は適当なソフトウェアMIDIを探してきて下さい + +0.86 rev65 -> 0.86 rev66 +・処理落ち時に86音源のPCMが鳴らなくなる場合がある不具合を今度こそ修正 +・内蔵固定ディスクを「切り離す」にしても完全に切り離せていなかった不具合を修正 +・IDE BIOSを配置するアドレスを指定できるようにしました + ・デフォルトで置かれる場所はD8000h(実機と同じ)です + ・非公開機能IDEBADDRを参照のこと + ・INIにIDEBADDR=D0を書くと本家猫と同じくD0000hに置かれます + ・INIにIDEBADDR=0を書くとBIOSが置かれなくなります +・Direct3Dフルスクリーンでメニューが出ない場合がある不具合を一部修正 + ・以前よりはマシだと思いますが完全ではなさそうです +・ツールウィンドウ絡みの変数名のtypo修正 +・MIDIのランニングステータスの扱いがおかしかったのを修正 +・BIOSの256色モード切替がおかしかったのを修正 +・Async CPUを改良しました(改悪かもしれない) + ・完全なクロック数可変にしてみました + ・タイトルバーのクロック数は実際のエミュレーションCPUのクロック数になります + ・設定のクロック数はクロック数可変の上限設定になります(即時反映) +・試しに21じゃない方を作ってみました + ・CPUがリアルモードのみの286相当なので動かせるものが制限されます(Win系はほぼ不可能) + ・リアルモードだけで十分なら21よりも動作が軽いと思います + ・np21/Wで拡張された機能も一部を除いて一応使用可能です +  ・使えない機能はIDE周り(CD-ROM等)やCPU周り(FPU等)などの拡張です +  ・追加音源やWAB、LANは一応有効化されています + ・32bit版ではASync CPUは使えません + +0.86 rev64 -> 0.86 rev65 +・ウィンドウアクセラレータのマルチスレッドモードを使うと画面描画が止まる不具合を修正 + +0.86 rev63 -> 0.86 rev64 +・118音源設定にジャンパ画像を表示するようにしました + ・クリックで設定は出来ないのであしからず +・処理落ち時に86音源のPCMが鳴らなくなる場合がある不具合を修正 +・サウンドボードにWaveStarを追加しました + ・現状ではDOS/Win3.1でしかまともに使えません + ・WinNTでも一応動きますがFM MIDIは大変気難しいので些細なことですぐいなくなります +・86音源+スピークボードを使うとOPNAタイマーがおかしくなる不具合を修正 + ・スピークボード側OPNAタイマーを使うと落ちる現象が起こらなくなるはず + +0.86 rev62 -> 0.86 rev63 +・F12キーでマウスキャプチャ解除すると非キャプチャ操作モードでダブルクリックが出来なくなる不具合を修正 +・86音源+118音源について118音源側のYM2608(OPNA)拡張部分機能をデフォルトで有効にしました + ・最初からI/OポートB460hに再配置されてるくらいなのでこの際はじめから有効にしました +・スパークボードでYM3438が鳴らない不具合を修正 +・86音源+スピークボードを選択できるようにしました + ・86音源+118音源のように割り込みとI/Oポート競合を自動で解消したりはしないので注意 +・118音源にROM無効化設定を足しました + ・EMSで邪魔になる場合があるようなので・・・ + +0.86 rev61 -> 0.86 rev62 +・ウィンドウアクセラレータ使用中も画面回転が出来るようにしました + ・用途は・・・思いつきません(ォィ +・各画面解像度毎にフルスクリーン時の表示設定やウィンドウサイズ設定を覚えるオプションを追加しました + ・デフォルトでは無効になっています + ・ウィンドウサイズを記憶させたい場合はConfigureでの設定も必要なので注意 + ・非公開機能(付属ヘルプ参照)ですのでINIのFSRESCFGを手動でtrueにする必要があります + +0.86 rev60 -> 0.86 rev61 +・PageDownキーとPageUpキーの入れ替えをメニューで設定可能にしました +・デフォルト設定をPageDown/PageUpキー入れ替え状態(xrollkey=true)にしました + ・Anex86やT98-Nextと同じ設定です + ・NP2系の設定にしたい場合はDevice→Keyboard→Swap PageUp/PageDownのチェックを外して下さい + +0.86 rev59 -> 0.86 rev60 +・RaSCSI形式(.HDN)で作成可能なイメージファイルサイズ制限を緩和 + ・6GBくらいまで作れます + ・古いBIOSで扱う場合は399MiBが上限の場合がある注意 +・ディスク作成時に作成可能な容量上限を超える選択肢を非表示にしました + +0.86 rev58 -> 0.86 rev59 +・TAP仮想ネットワークデバイスのエラーで終了時にプロセスが残りっぱなしになるバグを修正 +・いろんな場所でスレッドハンドルを閉じ忘れていたバグを修正 +・アプリケーション終了時にスレッドが暫く待っても終了しない場合は強制終了する仕様に変更 + ・プロセスが残りっぱなしになるリスクは減るはず + ・あまり綺麗な終了の仕方じゃないですが基本的に起こらないはずなので問題ないかと +・CDイメージのアンマウント時にファイルハンドルを閉じ忘れていた問題を修正 +・DirectDrawのマルチスレッドを真面目に実装してみました +・TAPデバイス名やホストディレクトリ共有のパス指定に文字数制限が付いていたバグを修正 + +0.86 rev57 -> 0.86 rev58 +・CS4231を無理やり調整しました + ・Win9x,2000で長時間再生すると発生するノイズがなくなるはずです + ・Win3.1+CanBe Soundは相変わらず駄目です +・LGY-98を使ってWindowsファイル共有をやると大きなファイルのコピー時にエラーが発生する問題を改善したつもり + ・ちょっとパフォーマンスは落ちるかもしれませんが止まるよりはマシだと思います(たぶん) +・PCI絡みで無計画に足したI/Oポートを整理しました +・COPYキーをPrintScreenに割り当てました + ・Device->Keyboard->System Key Hookが有効な場合のみ使用可能 + +0.86 rev56 -> 0.86 rev57 +・タイミングを維持したままCPUをフル稼働させるオプションを足しました + ・Screen→Async CPUにチェックを入れると有効になります(即時反映) + ・CPU実行速度はno wait相当になります + ・クロック数表示はConfigureで設定したCPUクロックになります + ・処理落ちしてもBGM等があまりスロー化しないはず + ・実質的にCPUクロック可変のような挙動です + ・CPUクロックの扱いが厳密なソフトは不具合を起こすかもしれません + ・Async CPUを有効にしている間はScreen→No waitは効かなくなります + ・ConfigureのCPUクロックはAsync CPU無しでも程々に使えるレベルのCPUクロックにしておいて下さい +  ・あまりに極端なクロック数設定のときにAsync CPUを使うと挙動がおかしくなります +・ウィンドウメッセージループをいじくりました + ・環境によっては問題を起こすかも・・・ + +0.86 rev55 -> 0.86 rev56 +・Direct3D描画の安定性を改善したつもり +・Win3.1でOPL3SA.DRVが多分使えるようなりました + ・PCMも鳴るようになりましたがかなりノイズが酷いです +・隠し機能だった86音源+118音源をメニューに足しました + ・一応頑張ればWin3.1で使えるようなので・・・ + ・86音源とポートが被らないように細工しています +・言語リソースファイルのミスを修正 + ・16MB越えメモリチェック(機能廃止)のメニュー項目を削除 + ・日本語リソースで「ジョイパッド1を使う」のラベルが途中で切れていたのを修正 + ・日本語リソースで「PCMC」のラベルが途中で切れていたのを修正 + +0.86 rev54 -> 0.86 rev55 +・Win3.1でOPL3SA.DRVがそこそこ使えるように細工しました + ・設定では118音源を選択して下さい + ・FM音源のMIDIは使えますがPCMは微妙です(環境依存?) +・PEGCのMMIOがおかしくなっていたのを修正 + ・rev52以降に表示が変になっていたのが直っているはず + +0.86 rev53 -> 0.86 rev54 +・CDイメージ使用時にEDC/ECCのエミュレーションを行う機能を追加しました + ・使用するにはIDE optionでUSE CD-ROM EDC/ECC Emulationにチェックを入れて下さい(即時反映) + ・CDイメージ使用時に可能であればEDC/ECCのチェックが行われます + ・EDCがおかしい場合はATAPIのREADコマンドでECCエラーを返すようになります + ・いわゆる不良セクタ検出系のCDチェックが正しく機能するようになります + ・実CD-ROMをマウントした場合は上記オプションに関係なくECCエラーを発生させます +・WAB,WSN系アクセラレータを使用中にメモリアクセス違反を起こす可能性を少し減らしました +・Windows10環境でウィンドウのサイズがおかしくなる不具合を完全修正したはず + +0.86 rev52 -> 0.86 rev53 +・高速メモリチェックの設定が正しく保存されない不具合を修正 +・Windows10環境でウィンドウのサイズがおかしくなる不具合を暫定修正 + +0.86 rev51 -> 0.86 rev52 +・PEGCプレーンモードの一部を仮実装しました + ・Screen optionのChipタブでPEGC plane modeを有効にして下さい + ・まともに使えるレベルではないのでご注意(Better than nothing) + ・面倒なところやよく分からないところは実装せず無視するか勘で書いてます(ォィ + ・Windows3.1付属の256色ドライバでもとりあえず操作ができるレベルになります + ・プレーンモードを使うソフトがどうなるか分かりませんが多分まともじゃないと思います +・WAB-SやWSN-A2F/A4Fを使うと画面表示がおかしくなる不具合を修正 +・BIOS I/Oエミュレーションを無効にすると挙動がおかしくなるバグを修正 + +0.86 rev50 -> 0.86 rev51 +・Win3.1でFDDアクセス時にフリーズする場合がある不具合を修正 + ・最短でも3秒はフリーズしますが自動復帰するはずです +・ツールウィンドウのファイル履歴数を変更できるようにしました + ・非公開機能TWNDHISTを参照のこと + ・例えばTWNDHIST=16と書くと過去16件のファイル履歴が記憶されます + ・指定できる最大値は64件です + ・ファイル履歴番号が16進数なのは作者の趣味・・・ではなくて文字数の節約のためということにしてください +・一部のソフトでマウスクリックが出来ない不具合を修正 + +0.86 rev49 -> 0.86 rev50 +・CL-GD5446有効時にWin2000のハードウェアの追加と削除が進まない不具合を修正 +・レンダラをDirectDrawにした場合にウィンドウアクセラレータ画面がレジュームで正しく復帰できない不具合を修正 +・レンダラをDirectDrawにした場合に1600x1024が表示できない不具合を修正 + +0.86 rev48 -> 0.86 rev49 +・16MBを超えるメモリを積んでいるときにMemopy Mapを表示するとバッファオーバーフローする場合があるバグを修正 +・256MB以上のメモリを積むとEMSがおかしくなる問題を暫定修正 + ・とりあえず256MBを超えた分は無視するような扱いにしています +・BIOS INT 18h AH=03hのI/Oポートエミュレーションがおかしかったのを修正 + ・EMM386等使用時にキー入力が二重になる現象が直ります +・マスタボリューム設定が使えない環境があるようなので使用しないようにする設定を追加 + ・無効にしたい場合はINIにUSE_MVOL=falseを書いて下さい + +0.86 rev47 -> 0.86 rev48 +・GA-98NBがまともに使えるようになりました + ・Win3.1, Win95, Win98や光栄製ゲームの一部などで使えます + ・Win95, Win98ではOS付属ドライバが正常に動きませんので公式サイトからドライバを入手して下さい + ・ドライバ付属アクセラユーティリティの画面位置調整は使用できません +・JPGVCLHやJPGVALPでGA-98NBを使用できるように調整しました + ・ビッグスクリーンを用いたスクロール表示にも対応 +・GA-98NBで1600x1024が表示できる怪しげなモードを足しました + ・Windows3.1でのみ表示可能です + ・INIで非公開機能GANBBSEXをtrueにして下さい + ・アクセラユーティリティで解像度を1024x768または1280x1024に、ビッグスクリーンを1600x1024に設定して下さい + ・実機ではあり得ない状態ですので一部表示がおかしくなるかもしれません +・ウィンドウアクセラレータ系の画面描画処理をシンプル化しました +・全てのCL-GD54xx系ウィンドウアクセラレータでDouble Bufferに対応させました +・ウィンドウアクセラレータのMMIO周りの挙動を変更しました +・バイナリ公開はしていませんがお察しくださいではない方のソースもメンテナンスしておきました + ・かなり厳しいですがウィンドウアクセラレータやLANも使えるかもしれません + ・当然のことながらお察しくださいではない方でUSE_FPUやSUPPORT_PCIは使えませんのであしからず +・マスタボリュームの調整が微妙だったのを調整 +・NHD,VHDイメージを5MBの容量で作ろうとすると何も作成されない不具合を修正 + +0.86 rev46 -> 0.86 rev47 +・Windows2000でIDEスレーブデバイスを認識するようになりました +・BIOSでのI/Oポート操作エミュレーションを改良 + ・WAB無しでコマンドプロンプトをウィンドウ表示で起動できるようになりました +  ・若干ごまかした部分があるのでWindows以外での挙動は要検証 + ・DOSプロンプト使用時に勝手にカナロックがオンになる不具合も直ったはず + ・マルチメディアタイマー不具合が暫定修正から完全な修正になりました +  ・メニュー及びINIでのTIMERFIXの設定は廃止されました +・640x480モード判定を少しいじりました +・設定初期値をウィンドウのリサイズ(Allow resize)が有効になるように変更しました +・IA-32 panic時のリセットが上手くいかない不具合を修正 +・ウィンドウアクセラレータが無効の場合にCPUをリセットすると落ちるかもしれない不具合を修正 +・フルスクリーンでのDirect3D描画の安定性を改善したつもり +・Direct3D描画の排他制御に漏れがあったのを修正 +・Direct3D描画でピクセル形状保持を使うとメモリリークする問題を修正 + ・画面解像度が切り替わった時にフリーズする現象も直ったはず +・Win9xでWSN-A2F/A4Fがある程度使用可能になりました + ・一応1024x768 16M色や1280x1024 64k色が使えます(DirectX 5ドライバが必要) + ・WGN-A2/A4と誤認識される場合がありますがドライバはWSN-A2FまたはA4Fを使用してください + ・DirectXを使うアプリケーションの画面描画がおかしい場合があります + ・DirectXのフルスクリーンはまともに使えません +  ・一旦フルスクリーンにしてウィンドウ表示に戻すと何故か出力切り替えリレーが98グラフィック側になります +  ・WABリレースイッチをF12に割り当てて手動切り替えすれば一応復帰できますが・・・ +・WSN-A2F/A4FのE-BANKモード以外の挙動を改善しました + ・Win3.1で仮ドライバを使わずにそのままセットアップが出来るようになりました +・拡張メモリ容量設定を実質無制限にしました + ・理論上は4GBあたりまで・・・のはずですが実際は1.4GBくらいでメモリ割り当てに失敗します + ・Win3.1は128MBを超えたあたりからまともに起動しなくなったりエラーが出たりします + ・DOSプログラムもものによっては128MBを超えたあたりから挙動不審になります + ・Win95は512MB、Win98は1GBあたりからおかしくなります + ・WinNT4.0, Win2000は1GBを超えても一応大丈夫だと思われます + ・Xe10内蔵ウィンドウアクセラレータを使用中に230MB以上のメモリを積むと画面がおかしくなってフリーズします +  ・○○内蔵アクセラレータのものは基本的に駄目っぽいです +  ・WSN-A2F/A4FやPCI CL-GD5446は一応大丈夫なようです +・メモリチェックを高速化する機能を付けました + ・Other->Fast memcheckにチェックを入れると8倍速でメモリチェックが行われます + ・それ以外の速度にしたい場合は非公開機能のmemckspdを参照のこと +・GA-98NBを強引に使えるようにしました + ・とりあえずWin3.1と信長の野望 天翔記で使えますが、Win3.1では描画の乱れがあります + ・明らかに正しくない挙動なので他で動くことは保証できません + ・ドライバ付属アクセラユーティリティの大半の機能はまともに使えません + ・16M色は正常に表示できません +・MELCO WAB/WSNとI-O DATA GA-98NBをDouble Bufferに対応させました +・CL-GD54xxでステートセーブやレジューム時に関数アドレスがNULLになって落ちる可能性があるバグを修正 +・fmgenのレジューム関連の不具合を修正 +・非公開機能でクロック同期モードの設定を足しました + ・INIのTICKMODEとして0=自動, 1=GetTickCount, 2=timeGetTime, 3=QueryPerformanceCounterを指定できます + ・QueryPerformanceCounterは一部環境で問題を起こす可能性があるのでその場合は1か2にしてみてください + ・使用できないものを指定した場合は使用できるものが適当に選択されます +・非キャプチャマウス操作でもマウス速度設定が反映されるようにしました +・np2fmgen風のマウスホイール操作を追加しました + ・INIでUSEWHEEL=trueにすると有効になります + ・マウスホイールでマスタボリュームを変更出来ます(DirectSoundのみ対応) + ・Ctrl+Shift+マウスホイールでマウス速度を変更出来ます + +0.86 rev45 -> 0.86 rev46 +・Windows95でプロテクトモードFDDドライバが使用できるようになりました + ・Win95でFD未挿入時も入っているような挙動になっていたのを修正 +・言語リソースファイルの抜けを修正 +・32bit版で3DNow!命令が無効になっていたので有効化 +・hostdrvのバグらしきものを修正 +・32bit版のプロテクトモードがまともに動かなくなっていた問題を暫定修正 +・マスタボリューム設定を試験的に足してみました +・仮想86モード拡張の一部をサポートしました + ・現状で実装されているのはSTI, CLI, PUSHF, POPFのみです。 + ・Windows2000でNTVDMが落ちなくなります + ・CPU機能フラグにVMEが追加される関係でCPU種類を設定し直す必要があります +・Windows98でPCIを有効にするとIDEデバイスが認識しなくなる不具合を修正 + ・Windows95のドライバを借りなくてもHDDが認識するようになります +・BIOSでのI/Oポート操作をエミュレーションできるようにしました + ・現状では画面表示関連のI/Oポートのみエミュレーションします + ・Win3.1,9xのDOSプロンプトでGDCにコマンドを送らなくても画面が出るようになります + ・問題を起こす場合は非公開オプションBIOSIOEMをFALSEにすると無効になります + +0.86 rev44 -> 0.86 rev45 +・Direct3Dによる画面表示に対応 + ・必要に応じてDirectXランタイムは入れてください + ・拡大縮小時の補間モードを細かく設定できます + ・Screen optionのFullScreenタブでNo change screen resolutionにチェックを入れるのを推奨 +・CPU変更時にバージョン情報でCPUの名前がおかしくなる不具合を修正 +・フルスクリーン時にもキャプチャ無し操作設定が効くように仕様変更 +・CPU周りを速くしようとしてみました +・Screen optionのFullscreen, Rendererタブの設定を即時反映するように変更しました +・Windows2000ホストで動かなくなっていた問題を修正しました +・システムメニューのRestore window borderから枠無し状態を戻せるようにしました +・システムキーフック関係を多少安定化させたつもり +・CL-GD5446のGraphics Double Bufferに対応 + ・主にDirectX対応プログラムの画面のちらつきと描画速度が改善されます +・NumLockキーを有効にするオプションを足しました + +0.86 rev43 -> 0.86 rev44 +・SSE命令のプリフィックスの扱いがおかしかったのを修正 +・SSE2, SSE3命令を追加しました + ・現時点でSSE2, SSE3はバグまみれなので通常用途ではPentium III以前にしておいてください + ・実機ではSSE2, SSE3命令に対応したものは存在しませんので完全に自己満足の世界です + ・Pentium M, Pentium 4を選択できるようにしました(一応SSE3が使えるかどうかで棲み分け) +・バージョン情報ウィンドウの表示内容を調整 +・fmgenをデフォルト設定で有効になるように変更 +・エミュレータ内でハードウェア設定をいじる怪しい(危ない?)機能を追加 + ・設定ツールはnp21wtool.d88として公開しています + ・NPCNGCLK.EXEはCPUクロックを動的に変更します +  ・CPUが速すぎると問題を起こす場合等に使えます(蟹味噌など) +  ・Configureの内容は変更されません(リセットで元に戻ります) + ・NPCNGCFG.EXEはハードウェア構成を動的に変更します +  ・ディスクイメージで使うハードウェア構成が決まり切っている場合に使えるかも +  ・Configureの内容は変更されません(リセットで元に戻ります) +  ・現時点ではウインドウアクセラレータボードとサウンドボードに対応しています +・HRTIMER関連のBIOSを実装しました + ・古いバージョンのHRTIMER.SYSで時計が止まってしまう不具合が解消されます +・日付が変わった時にHRTIMERの時刻が不正になる不具合を修正 +・PCIバスが試験的に追加されました + ・Device->PCI optionでEnabledにチェックを入れて下さい + ・追加のBIOSファイルは要りません + ・起動しない場合はBIOSファイル無しにすると動くかもしれません + ・PCIを有効にするとWin98でIDEデバイスが行方不明になりますがWin95のDRIVERSからESDI_506.PDRを借りてくれば一応動きます + ・Win2000の場合はPCIの有無を変更するとセットアップし直さないと駄目です(互換性無し) +・PCI接続の内蔵ウィンドウアクセラレータCL-GD5446が追加されました + ・現時点ではWindows98, NT4.0, 2000で動くことを確認しています + ・Device->Window Accelerator board optionのCL-GD54xxタブでPC-9821 PCI CL-GD5446 built-inを選択 + ・Auto Select(Xe10, WSN-A2F, PCI)も使えますがあまりテストしていないので注意 + ・NPCNGCFGでのウィンドウアクセラレータ機種IDは160です +・WAB-S, WSN-A2F/A4FをWin3.1で使用した際に壁紙の描画がおかしくなる不具合を修正 + +0.86 rev42 -> 0.86 rev43 +・NVL.DLLで結構色々読めることが判明したのでファイル選択時の拡張子にそこそこ有名な形式を追加 + ・あくまでディスクイメージを使用できるだけですので中身に関してはユーザーが注意を払う必要があります +  ・ハードディスクのPC/AT互換機フォーマットとPC-98フォーマットには互換性がありません +  ・不用意にPC/AT互換機用イメージをPC-98に繋いだりその逆をしたりすると実機同様ディスク内容が破壊される恐れがあります + ・一覧になくても読めるファイルがあると思われます +・ソース中のCreateThread関数を_beginthreadexへ置き換え +・複数の実CD/DVDドライブがある場合にトレイ開閉が正常に動かない不具合を修正 +・実CD/DVDドライブのマウント状態がResumeで復元されない場合がある不具合を修正 + +0.86 rev41 -> 0.86 rev42 +・処理落ち時のBEEP音ノイズを抑制しました +・マウスキャプチャ解除直後に非キャプチャ操作モードのダブルクリックが出来なくなる不具合を修正 +・非同期CD-ROMアクセスが出来るようになりました(IDE optionで設定・やや不安定な気がするので注意) + ・CD-ROMを読みつつ他の処理をするようなプログラムで処理落ちがなくなるはず + ・実際には実CD-ROMを使わない限り大差はないと思われます + ・非同期CD-ROMアクセスの状態でNo waitにするとタイムアウトになる可能性があるので注意 +・エミュレータ内から実CDドライブのトレイ開閉が出来るようになりました(IDE optionで設定) +・挿入したCDイメージを次回起動時に復元する設定を追加しました(付属ヘルプの非公開機能SVCDFILEを参照) +・Raw Input Modeでない時にマウスキャプチャするとダブルクリックが出来ない不具合を修正(β1のバグ) +・IDEのアクセスウェイトを入れるとDOSからCD-ROMが読めなくなる問題を修正 +・SoftFloat FPU FXAM命令の符号判定バグを修正 +・容量可変VHDイメージが255/256の確率で作成できない(実際には64bit版は作れて32bit版は作れないことが多い)問題を修正 + +0.86 rev40 -> 0.86 rev41 +・CPUにSSE命令, Enhanced 3DNow!命令を実装しました + ・Intel Pentium III, AMD K7 Athlon, AMD K7 Athlon XPを選択できるようにしました + ・あまり動作テストができていないので注意(ほぼノーチェック) +・CPUクロック安定化機構を試験的に搭載してみました + ・Screen → CPU clock stabilizerにチェックを入れてください + ・瞬間的な処理落ちは吸収してくれるはず + ・あんまり処理落ちしすぎると逆に邪魔になるかもしれません +・ベタ形式のFDイメージを新規作成できるようにしました +・FDとHDの新規作成メニューを分離しました +・非キャプチャマウス操作を有効にした状態で一旦フルスクリーンにしてウィンドウに戻すとダブルクリックが出来なくなる不具合を修正 +・ia32_panicの時に強制終了ではなくリセットするようにしてみました +・DOS環境でCD交換を認識しない不具合を修正したつもり + +0.86 rev39 -> 0.86 rev40 +・FPUで拡張倍精度浮動小数点演算をサポートしました + ・Berkeley SoftFloat Release 2cを使用しています + ・四則演算系は全て拡張倍精度で計算されます + ・三角関数や定数などは従来通り倍精度で計算されます + ・従来の倍精度限定FPUもオプションで使用可能です +  ・暫定でDevice->FPUメニュー内に設定追加 +・アセンブラ版FPU(fpemul_dosbox_asm.c)は削除しました +・FPUにFCMOVcc,FCOM系,FXSAVE/FXRSTOR命令を実装しました + ・.NET Framework 2.0でエラーが出なくなるはず + ・結構手抜きしているので特殊なことをやるアプリケーションでは問題を起こすかも +・FSAVE/FXSAVE/FRSTOR/FXRSTORのTOSフィールドの扱いがおかしかったのを修正 +・CPUにMMX命令, 3DNow!命令を実装しました + ・mmx.c, mmx.hのライセンスは修正BSDライセンスとしておきます(DOSBoxから移植したFPUがないと使えませんが・・・) + ・3dnow.c, 3dnow.hのライセンスも修正BSDライセンスとしておきます +・タスクスイッチ時にFPU/MMXレジスタの内容が破壊されるバグを直しました + ・CR0のTSフラグが立っている時にデバイス使用不可例外を出しているだけです +・CPUの種類を選択できるようになりました + ・選択できるのは486SX,486DX,Pentium,MMX Pentium,Pentium Pro,Pentium II,AMD K6-2,AMD K6-III,Neko Processor IIです + ・基本的にはCPUIDと機能フラグのみが変わります(486は挙動も若干変わります) + ・各CPUの機能は以下の通り +  ・486SX - 何も無し +  ・486DX - FPU命令 +  ・Pentium - FPU命令,RDTSC命令 +  ・MMX Pentium - FPU命令,RDTSC命令,MMX命令 +  ・Pentium Pro - FPU命令,RDTSC命令,CMOV/FCMOV系命令,FXSAVE/FXRSTOR命令 +  ・Pentium II - FPU命令,RDTSC命令,CMOV/FCMOV系命令,FXSAVE/FXRSTOR命令,MMX命令 +  ・AMD K6-2 - FPU命令,RDTSC命令,3DNow!命令 +  ・AMD K6-III - FPU命令,RDTSC命令,3DNow!命令 +  ・Neko Processor II - Neko Project 21/Wに実装されている全機能 + ・特に理由が無ければIntel系の最新CPU(Pentium II)が無難です +  ・AMD系は3DNow!命令が使えますが利用可能なアプリケーションが皆無な上にCPUチェックに引っかかる場合があります +  ・Neko Processor IIは全機能が使えますがベンダ名がIntelでもAMDでもないので追加命令を使ってくれない場合があります + ・Pentium IIには未実装命令があるので注意 +  ・未実装命令が呼ばれると困るのでCPUIDの機能ビットでは使えないということにしてあります +  ・未実装命令はSYSENTER,SYSEXITです + ・Pentium ProにしてWin2000を起動するとHLT命令を使わなくなるので注意(アイドル時のCPU使用量が増えます) +  ・一度でもこの状態になるとCPUをPentium Pro以外にしても直りません +  ・レジストリエディタでHKLM¥SYSTEM¥CurrentControlSet¥Control¥Session ManagerのEnableHaltを1にすれば直ります +・CS4231(118音源のPCM, Mate-X PCM)を再調整しました(泥沼感) +・非キャプチャ操作モードでマウスを速く動かしすぎると移動量がおかしくなる不具合を修正 + +0.86 rev38 -> 0.86 rev39 +・FDCを若干修正しました + ・rev27で動かなくなっていた某オープンソースOSが再び動くようになりました + ・Win98,WinNT4,Win2000でのFDアクセスはこれまで通り問題ないはず + ・あまり根拠がないので不具合が出るかも・・・ +・FPUを若干修正しました + ・移植ミスっぽいところをいくつか直しました(今まで何故動いていたのか・・・) + ・ついでにx86に限りアセンブラ版FPU(fpemul_dosbox_asm.c)もコンパイルできるようにしましたがテスト不十分のため無効にしています +  ・USE_FPUに加えてUSE_FPU_ASMを定義してコンパイルすれば使えます +  ・挙動に関しては基本的に通常版FPUとの差は無いはず +・規格上怪しいCUEシートもとりあえず読めるようにしました +・Load VM configをするとファイルがロックされたままになる不具合を修正 +・非公開機能で起動音の長さを設定できるようにしました + ・デフォルトの長さが気に入らない人向け + ・クロック倍率を変えても大体同じ長さで聞こえるようにするオプションも足しました + +0.86 rev37 -> 0.86 rev38 +・シーク音とリレー切替音をカスタマイズできるようにしました + ・詳細は付属ヘルプの外部ファイルの頁を参照 + ・シーク音はseek.wav, seek1.wavで、リレー切替音はrelay1.wavです +・118音源とMate-X PCM用の設定画面を追加しました +・Sound Blaster 16の設定画面を追加しました +・CS4231の処理を修正しました(改悪かも) +・NECCDM.SYSをある程度使用できるようにしました + ・β1の無根拠な修正もなおしました + ・NECCDM.SYSが前提のDOSアプリケーションでCD-DA再生が正常化するかもしれません + ・既知の不具合:Win3.1のメディアプレーヤーでのCD-DA再生時にものすごく時間がかかります +・実機BIOS無しの場合にWindows2000でFDDが見えなくなる不具合を修正 +・128MB以上のメモリチェックがエミュレーションされるようになりました + ・搭載メモリを230MBにした場合でもちゃんと最後までカウントされます + ・時間がかかって嫌な場合はOtherメニューのSkip over 16MB memcheckを使うか非公開機能を参照のこと + +0.86 rev36 -> 0.86 rev37 +・Win2000のデバイス検出でブルースクリーンが出る不具合を修正 + ・この修正でPC-9801時代のプログラムが問題を起こす可能性もあるので注意 + ・従来の挙動に戻したい場合はINIのSYSIOMSKをff00から0000に変えてください +・完全に未フォーマットのHDイメージを作成できるようにしました + ・Win2000セットアップを起動ディスクから行う場合は未フォーマット状態で作成する必要があります + ・現時点ではNHD, VHD形式限定です + ・ディスク作成時にAdvancedのBlankにチェックを入れて作成してください +・CS4231(118音源のPCMとMate-X PCM)を修正 + ・Mate-X PCMのWin3.1用ドライバ(necpcm.drv)がそこそこ動くようになりました + ・レジュームやステートセーブでDMAがおかしくなる不具合を修正 +・画面を強制的に4:3表示する謎のオプションを追加しました + ・4:3のディスプレイに無理矢理640x400を映していたのを再現したい人におすすめ? + ・普通は用事がないと思われるのでFSCRNMODの非公開機能参照 +・CS4231の処理と32bitメモリREAD/WRITE、CPUのコードフェッチを若干高速化したつもり +・Win10(恐らくWin8とWin8.1も)でウィンドウサイズが変になる不具合が発生していたのを修正 + ・多分rev24からある不具合(画面サイズが変わる度にウィンドウがどんどん小さくなる) + ・過去バージョンの変な設定を覚えっぱなしの場合があるので、本バージョンに更新したら一旦ウィンドウサイズ変更等をして設定をリセットしてください +・タスクバーへのウィンドウスナップを再び行えるようにしました +・スリープから復帰すると画面が真っ黒になる場合がある不具合を修正 + +0.86 rev35 -> 0.86 rev36 +・BEEP PCM周りの修正 +・サンプリングレートを変えるとCD-DA再生がおかしくなる不具合を修正 +・DirectDrawエミュレーション設定が効かない不具合を修正 +・D88形式のFDイメージでブートできない場合がある不具合を修正 +・118音源やMate-X PCMがWindowsでそこそこ使えるようになりました + ・ドライバはYMF701互換Sound System(Win95の場合)等を手動で入れてください + ・118音源またはMate-X PCM単独を選んだ場合、DMA3, INT5(IRQ12)になります + ・86音源+Mate-X PCM(B460)を選んだ場合、DMA1, INT0(IRQ3)になります + ・Mate-X PCM(B460)はSoundIDがデフォルトでB460に移動しているのでWinで使う場合はドライバのinfをB460に書き換えてやる必要があります + ・OPL3によるFM音源はほぼ大丈夫(ただし、レジュームやステートセーブで音色がおかしくなります) + ・CS4231は長時間でなければそれなりに再生されます +  ・長時間再生するとノイズが入り始めます + ・Win3.1とかではテストしていません + ・CS4231の無根拠コードが根拠あるコードに置き換わりました + ・ボリューム調整を実装(Win等からWAVEやFMのボリューム調整が出来ます) + ・他の音源から118音源に切り替えるとボード設定がおかしくなる不具合を修正 +・Sound Blaster 16が追加されました + ・118音源にくっついていたのを分離しました +・IDE BIOSの有効/無効を自動切り替えする機能を追加 + ・IDE optionのAuto IDE BIOSにチェックを入れると機能が有効になります + ・ヘッド数8,セクタ数17でないディスクイメージが接続されている場合は自動でIDE BIOSが無効になります + ・たまにヘッド数8,セクタ数17でも起動しないケースがあるようですが今のところ原因が分からないので手動で無効にしてください + +0.86 rev34 -> 0.86 rev35 +・fmgenをサポートしました + ・使いたい場合はSound optionのfmgenタブにあるUse fmgenにチェックを入れてください + ・リズム音の外部ファイルも読むようになりました + ・ステートセーブやレジュームが出来るようになりました(旧版のステートセーブとは互換性がないので注意) + ・Load VM configで落ちる不具合を修正(β3) +・4GB超えのディスクイメージ作成が出来ない不具合を修正 +・ジョイパッドを繋がずにUse JoyPad-1にチェックを入れるとジョイパッド対応ソフトがほぼフリーズ状態になる不具合を修正 +・設定の初期値を最近のPCの性能を考慮して見直しました +・RaSCSIのSCSIディスクイメージが読めるようになりました(SCSIディスク選択より指定可) +・SCSIメニューも選択中のディスクイメージを表示するようにしました +・CPUを若干修正(したつもり) + +0.86 rev33 -> 0.86 rev34 +・Ctrl+Alt+Delをメニューからも送れるようにしました + ・Device->Keyboard->Send Ctrl+Alt+Delで送れます + ・Ctrl+Alt+ScrollLockは今まで通り使えます +・HRTIMER関連を大幅変更 +・Win98+HRTIMER.SYSで発生する日付ずれを修正 +・実ドライブマウント機能のバグ修正 + ・旧バージョンで部分的に読めなかったディスクが読めるようになりました(多分) + ・Win3.1で実ドライブのCD-DAが再生できなかった問題を修正 + +0.86 rev32 -> 0.86 rev33 +・ソフトリセットをするとHOSTDRVが使えなくなる不具合を修正 +・物理ドライブのCD/DVDをマウントできるようになりました + ・メニューでPhysical Drive x:を選択するとホストのxドライブがマウントされます + ・一度マウントするとRemoveを選ぶまでマウントされたままになります +  ・マウントされた状態でディスクを交換しても再マウントする必要はありません +・マウスキャプチャしなくても簡易的にマウス操作ができる機能を付けました + ・現時点ではマウス速度調整は反映されません + +0.86 rev31 -> 0.86 rev32 +・Win9xでのマルチメディアタイマーの不具合が修正されました + ・MIDIファイルが普通に再生されるようになります + ・マルチメディアタイマーを使っていて激遅になっていたゲーム等もまともになります + ・何らかの不具合があって前の挙動に戻したい場合はOtherメニューのFix MMTimerにチェックを外してください + ・Windows98の起動時間が安定&ようこそ画面のエラーが解消します(おそらく) +・上記修正のためMIDIスロー再生ごまかしオプション(TIMERADJ)が廃止されました + +0.86 rev30 -> 0.86 rev31 +・LGY-98 LANボードのDOSドライバが使用可能になりました + ・頑張ればWindows3.1でネットサーフィンが出来ます +・終了時のウィンドウサイズを記録する機能を追加しました + ・デフォルトでは無効なのでConfigureでSave window sizeにチェックを入れてください + +0.86 rev29 -> 0.86 rev30 +・FreeBSD4.11のX Window SystemでXe10内蔵ウィンドウアクセラレータが使えなくなっていた不具合を修正 +・ウィンドウアクセラレータ自動選択に選択肢追加 + ・Xe10+WAB-S, Xe10+WSN-A2F, Xe10+WSN-A4F のいずれか + ・特に理由がなければいろいろなOSやアプリケーションで使えるXe10+WSN-A2Fがおすすめ + ・rev29以前のデフォルト動作はXe10+WSN-A4Fでしたが、Win3.1で画面が乱れるのであまりおすすめしません +・サウンドにMate-X PCMなどという選択肢が増えていますが動きませんので選んでも無意味です +・(5/17追加)ウィンドウアクセラレータが無効の状態だとステートセーブが正しく動かない問題を修正 + +0.86 rev28 -> 0.86 rev29 +・Win9xで高速再起動を使うとCDドライブが認識しなくなる不具合を修正 +・B-MATE系ウィンドウアクセラレータを使うと98内蔵グラフィック描画がおかしくなる問題を若干改善 +・CDドライブがChanger(連装)デバイス扱いになっていた不具合を修正 + ・FreeBSDでCDが使えるようになります +・音楽CDを挿入しているとWin3.1のメディアプレイヤーの起動が異様に遅くなる不具合を修正 +・Load VM configを使うとツールウィンドウの挿入中フロッピー表示が更新されない不具合を修正 +・CD交換中にリセットするとCD挿入処理がおかしくなる不具合を修正 +・CL-GD54xx使用中にWin3.1,Win9xの文字列描画が乱れる不具合を修正 +・任意のCHSパラメータを持つハードディスクイメージを作成できるようになりました + ・現時点ではNHD,VHD形式のみのサポートです + ・変なパラメータにすると実機BIOSでは使えないので注意 +・ディスク作成の進捗が表示されるようになりました + ・これも現時点ではNHD,VHD形式のみのサポートです + ・キャンセルも出来ます +・動的容量VHDハードディスクイメージが使用できるようになりました + ・イメージアクセスはNVL.DLLに丸投げするのでNVL.DLLが必要です + ・NVL.DLLについては「Neko Project 21/W(np21w, ねこープロジェクト21/W)用のVirtualPC等イメージ使用ライブラリ」で検索 +・HOSTDRVのディレクトリ設定を過去10件まで記憶するようにしました + + +0.86 rev27 -> 0.86 rev28 +・LGY-98とCL-GD54xxの有効/無効設定がリセット無しに即時反映されてしまうバグを修正 + ・その関係で、rev27以前のステートセーブ/レジュームとの互換性がありません・・・(一旦削除する必要があります) +・Win9xで86音源を使うとサウンド再生終了時に時々フリーズするバグを修正 + ・具体的には、起動音再生終了直後のフリーズ、動画再生停止時のフリーズ等がなくなるはずです +・GetWindowPlacementとSetWindowPlacementの使い方がおかしかったので修正 +・現在選択されているHDイメージファイル名をメニューから分かるようにしました + ・次回リセット時に反映される設定は「旧ファイル名 -> 新ファイル名」の形式で表示されます + ・クリックするとエクスプローラで場所を教えてくれます +・使用中のHDイメージファイルもダイアログで選択できるようにしました + ・選択したファイル名が重複している場合はリセット時にエラーを出します(ファイル選択時には出ません) + ・リセット無しにプライマリ/セカンダリのマスタ/スレーブの構成を入れ替えたりできます + ・接続デバイスの種類をいじったとき(HD/CD/未接続を変更した場合)はリセットが必要です +・Clock DispまたはFrame Dispを有効にしていないと挿入中CDの表示が正しく更新されない問題を修正 +・HOSTDRVの設定をGUIで出来るようにしました + ・HOSTDRVのディレクトリ/パーミッション設定は即時反映されます(リセット不要) + ・ディレクトリを変更すると安全のためWRITEとDELETEが自動で無効になりますので、必要であればもう一度有効にしてください +・非公開機能でMPU-PC98IIのI/OポートをPC/AT互換機で使われている330h-331hにも開ける機能を付けました + ・詳細は付属のヘルプファイルを参照 + ・Win2000のwdmaudio.infにある隠しMPU-401ドライバが使えるようになります(inf内のExcludeFromSelectの行を削除) + ・実機では開いていないI/Oポートなので不具合を起こす可能性があります +・F12キーにノーウェイトを割り当てられるようにしました +・rev27以降ポリスノーツのCDが正常認識しなくなっていた問題を修正 +・暫定でDPIスケーリングをSystem DPI Awareにしてみました +・実機IDE BIOS無しで3台以上のIDE HDDを認識するようにしました +・ウィンドウアクセラレータにPC-9801-96が追加されました + ・ただし、800x600や64k色が使えないのであまり価値はないかも知れません + +0.86 rev26 -> 0.86 rev27 +・プロテクトモードドライバでのFDD読み書きが出来るようになりました + ・WindowsNT4.0とWindows2000がFDからセットアップできます + ・Windows98でプロテクトモードFDドライバが使えます + ・Windows95だけは動きません + ・ベタ形式, FDI形式, NFD(r0)をWindowsの32bitドライバでフォーマット出来るようになりました +  ・それ以外のイメージ形式をフォーマットすると破損すると思われます +  ・DOSでやったら良いだけなので困らないと思います +・セットアップ時にLGY-98を外す必要がなくなりました + ・ハードウェアの自動検索が使えるようになりました + ・公式ユーティリティのMELCHKによるボードチェックが通るようになりました + ・ただし相変わらずDOSのドライバは使えません +・Windows2000セットアップ時にCD交換を検出できないバグを修正しました +・CD選択とHDD選択のディレクトリを別々に覚えるようにしました + +0.86 rev26 -> 0.86 rev27 +・プロテクトモードドライバでのFDD読み書きが出来るようになりました + ・WindowsNT4.0とWindows2000がFDからセットアップできます + ・Windows98でプロテクトモードFDドライバが使えます + ・Windows95だけは動きません + ・ベタ形式, FDI形式, NFD(r0)をWindowsの32bitドライバでフォーマット出来るようになりました +  ・それ以外のイメージ形式をフォーマットすると破損すると思われます +  ・DOSでやったら良いだけなので困らないと思います +・セットアップ時にLGY-98を外す必要がなくなりました + ・ハードウェアの自動検索が使えるようになりました + ・公式ユーティリティのMELCHKによるボードチェックが通るようになりました + ・ただし相変わらずDOSのドライバは使えません +・Windows2000セットアップ時にCD交換を検出できないバグを修正しました +・CD選択とHDD選択のディレクトリを別々に覚えるようにしました + +0.86 rev25 -> 0.86 rev26 +・書き込み時のIDE割り込みタイミングがおかしかった問題を修正 +・IDE割り込みディレイ値が指定した値にならないバグを修正 +・IDE割り込みディレイ中にBSYビットがセットされていなかった問題を修正 +・IDE BIOS使用時の最小ディレイ値が廃止されました +・IDE BIOSを使うと(rev18以降は使わなくても)データ破壊を起こす問題に暫定対応 + ・BIOSデータエリアの0x0457で値を返すとバグる模様 + ・スレーブにアクセスするとデータ破壊が起こる問題も直っているかも + ・IDE BIOS有りでWin3.1/95はセットアップが完走する事を確認しましたが、他はまだ確認できていません +・WSN-A4Fを大画面多色表示環境で使うとウィンドウ描画がおかしくなる問題を修正 + ・壁紙がおかしい問題はとりあえず棚上げ +・ウィンドウアクセラレータ設定に自動選択を追加 + ・内蔵とMELCO製を手動で切り替えるのが面倒な人向け + ・とりあえずポートを両方用意してどちらにアクセスが来たかで内蔵とWSN-A4Fを切り替えます + ・一度どちらかに切り替わるとCPUがリセットされるまで変わる事はありません + ・セットアップのデバイス検出時などポートをサーチしに来る状況での使用はおすすめしません +・FreeBSD + X Window System + Xe10内蔵CL-GD5430が程々に映るようにしました +・ネタにも出来ないレベルですが設定にGA-98NBを足してみました(動きません) +・ソフトウェアキーボード表示状態を覚えるようにしました +・クロック設定の選択肢を増やしました + ・手動で値を入れれば良いんですけど面倒なので +・HRTIMER.SYSを使った場合の時刻が0:00になってしまう不具合を修正 + +0.86 rev24 -> 0.86 rev25 +・ウィンドウアクセラレータ画面表示を少しだけ真面目に実装(QEMUコードを解析) + ・例の都市シミュレーションゲーム用修正かも + ・画面のスキャン幅ずれの発生が減ると思います + ・逆に悪化していることもあり得るのでその場合は報告をお願いします + ・WSN-A4Fを使ってWin3.1を動かすと1024x764 64k色(インターレース)だけ画面崩壊しますがインターレースじゃない方はちゃんと映るのでとりあえず放置 +・SL9821ディスクイメージを一応サポート + ・フォーマットが特殊なので実機IDE BIOSを使うとフリーズすると思われます + +0.86 rev23 -> 0.86 rev24 +・MELCO WSN-A4FがWindows3.1で程々に映るようになりました + ・ドライバインストールが若干ややこしいのでサイトのWin3.1セットアップの項目を参照 + ・Win3.1では1280x1024 ハイカラーが使えます + ・ただし、高解像度や色数が多い場合には画面にゴミが出やすくなります + ・部分的にグラフィックが化ける場合があります +・DirectDrawエミュレーションモードの切替設定を追加しました + ・従来は非公開機能として存在していましたが表に出しました + ・エミュレーションモードでは大抵の場合は最近傍補間になるので整数倍拡大の場合にはドットが綺麗に出ます +・フルスクリーン時の表示モードに整数倍拡大(Integer multiple)を追加しました + ・DirectDrawエミュレーションモードと組み合わせて使ってください +・ウィンドウアクセラレータのMultiThreadモードで画面切替時に時々落ちる問題を修正 + +0.86 rev22 -> 0.86 rev23 +・WAB-Sのハードウェアカーソルが表示できるようになりました +・ウィンドウアクセラレータの種類設定がリセット無しに即時反映されてしまう問題を修正 +・WSN−A2F/A4Fらしきものを試験的に追加しました + ・将来的にはWin3.1で使えるようにしたい + ・現時点ではネタに出来るかもしれないレベルの画面しか出ません(グラフィック崩壊) + ・Win3.1用ドライバはファイル名にm2の付いた16MBバージョンでしか動きません + ・公式のインストーラはボード自動認識失敗でセットアップできないので手動でINFを指定してください + +0.86 rev21 -> 0.86 rev22 +・ウィンドウアクセラレータの再現性が向上しました(Windows系ではハードウェアカーソルも普通に表示できます) + ・WinNT4.0のSP無しドライバでも表示が出るようになりました + ・Win3.1でも改善しているかもしれません(手元に内蔵CL-GD54xx対応のドライバがないので確認できませんが) +・メルコのWAB-S ウィンドウアクセラレータを実装しました + ・使用する場合はリストからWAB-Sを選んでください(内蔵CL-GD54xxとは排他) + ・ハードウェアカーソルは上手く動かないようなので設定でFake Hardware Cursorにチェックを入れてやってください + ・WAB系が使えるゲーム(信長の野望 天翔記PKなど)で使えます + ・Windows系は未テスト +・メモリ上限を120MBから230MBに引き上げました + ・メモリカウントは130MBくらいまでしかしませんが一応ちゃんと認識しています + ・上記のような状態なので何かトラブルがある可能性があります。常用は十分にテストの上で + ・これ以上増やすとウィンドウアクセラレータがバグります(^_^; +・VM設定ファイル保存時に正しくダイアログが表示されない問題を修正 +・言語ファイルを使用しているときにVM設定ファイル読込のファイルフィルタが使えない問題を修正 +・メインウィンドウ以外のスナップON/OFFの切替が出来るように修正 +・DWM環境でのウィンドウスナップ位置が正しくなりました +・ウィンドウアクセラレータ画面のBMP保存が可能になりました +・クリップボードを用いたコピーアンドペースト機能が試験的に追加されました + ・コピー可能なのはテキストVRAM全体(テキスト)、98グラフィック画面(画像)、ウィンドウアクセラレータ画面(画像)です。 + ・貼り付け可能なのはテキスト(キー送信をエミュレーションするのでASCII文字のみ)です。 +  ・CAPSロックを考えていないのでロックした状態だと大文字小文字が反転します(ォィ +  ・一応マルチバイト文字は考慮していますが、判定が雑なので出来るだけ混ぜない方が良いかも +  ・あんまり早すぎるとちゃんと入力できないので程々に減速していますが、長文では場合によってはおかしくなるかも +  ・長文過ぎて心が折れたなどの理由で貼り付け途中でキャンセルしたいときは、画面をマウスでクリックするかキーを叩けば止まります。 +・ウィンドウアクセラレータ画面で左側の1pxマージンが消える不具合を修正 +・ウィンドウアクセラレータ画面描画関連をさらにマルチスレッド化にしてみました(不安定になったらやめます) + ・マルチスレッド設定でない場合はむしろ遅くなると思います・・・ + ・マルチスレッドを有効にする場合はウィンドウアクセラレータ設定のMulti Thread Modeにチェックを入れてください + +0.86 rev20 -> 0.86 rev21 +・マウスのRaw Input Modeを有効にすると時々エラーで落ちる不具合を修正 +・INIファイルにWINNTFIX=trueを書くとWinNT系でIDE HDDが認識するようにシステム共通域をいじくるようにしました + ・WinNT4.0が実機BIOS無しで起動できるようになります + ・CDドライブしか検出しなかったWin9xでもIDE HDDの存在を確認しに行くようになりますが、残念ながらエラーでCDドライブもろとも認識しなくなります・・・ +  ・たぶんHDDの方がCDドライブよりもチェックが厳しいのだろうと思います +  ・ESDI_506.PDRをEPSON版Win95のアップデートに含まれるものに置き換えると認識するようになったりします(Win98も可) + ・本来はより実機の動作に近くなるのでデフォルトでONにしたいところですが・・・ +・Load VM Configを追加(ただし、既知の不具合がいくつかあるので、出来るだけ起動オプションでVM設定ファイルを渡すのを推奨) + ・既知の不具合:Load VM Configを使うと追加メニュー項目(FDD3,FDD4とかStatとか)の表示が更新されません +・最後にnpcfgファイルを保存読込したディレクトリの場所を覚えるようにしました +・最後のスクリーン状態(フルスクリーンや回転)を記憶するようにする隠しオプションを追加しました + ・無用な混乱を避けるためデフォルトでは無効になっています + ・INIファイル(npcfgファイル)にSAVESCRN=trueを書くと有効になります +・Aero環境でフルスクリーン→ウィンドウの操作でタイトルバーアイコンが消える不具合を適当にごまかしました + ・これってDirectDrawの不具合な気がする +・本家で出ているパッチをいくつか当てました + +0.86 rev19 -> 0.86 rev20 +・IDE BIOSの使用/不使用の設定をIDE設定画面に追加しました +・DOSで1.44MB FDイメージを読み取ったあとD88形式以外の1.25MB FDイメージに入れ替えるとセクタが見つからないエラーが出る問題を修正しました +・独自拡張子のVM設定ファイルを作成できるようにしました(中身はただのINIファイルですが) + ・設定ファイルを読み込む場合はコマンドライン引数にVM設定ファイルを渡してください(ドラッグアンドドロップでもOK) + ・ファイル関連付けで簡単に起動できます + ・面倒な設定(GCPUクロック・GDCクロック・IDE BIOSの有無など)を1ファイルで切り替えできます + ・ステートセーブとレジュームのファイルは設定ファイル毎に独立します + ・拡張子は複数種類用意しました(本家は対応していないのであまり意味は無いですね・・・(^^; ) +  ・.npcfg -> Neko Project II, 21, 21/W汎用 +  ・.npc -> 同上(拡張子が3文字でないと違和感を感じてしまう人用) +  ・.np2cfg -> Neko Project II向け +  ・.np21cfg -> Neko Project 21向け +  ・.np21wcfg -> Neko Project 21/W向け +・非公開機能としてFDDにセットしたイメージファイルを記憶して次回起動時にも挿入する設定を追加しました + ・INIにSVFDFILE=trueを書くと有効になります(前の動作の方が好きな人も多いと思いますのでデフォルトでOFF) + ・自分でイメージファイルを抜くまで挿入されっぱなしになります + ・上記VM設定ファイルと組み合わせれば割と使えるかも + ・コマンドライン引数にイメージファイルが指定されている場合そちらが優先されます + +0.86 rev18 -> 0.86 rev19 +・マウスデータ直接読み取りモードを使うとアクセラレータ出力切替をするタイミングで時々マウスが動かなくなる問題を修正 +・bios9821.romを他のIDE BIOS系のファイルと同じ扱いに変更 +・CL-GD5430やLGY-98を使用中にステートセーブとレジューム機能が使えるようになりました + ・テスト不十分なので各自で十分にテストしてからお使いください + ・起動が遅いWin2000等で効果を発揮するかも? + ・レジューム機能があるときに複数起動するとやばいのでレジューム機能が有効な時は複数起動しないように変更(暫定) +・言語リソースファイル最新版を作りました(また更新忘れ) + +0.86 rev17 -> 0.86 rev18 +・IDE BIOSを使用してWindowsをセットアップすると書き込みデータが破損するバグを修正 +・IDEデータ書き込みディレイ時間を設定できるようにしました(IDE設定画面に追加) + ・ディレイ時間はクロック数で指定します(ゆえに、CPUの速さでウェイト時間が変わります) + ・IDE BIOS有りの場合は20000以上が適切? + ・IDE BIOS有りの時は小さい値にしても自動的に最低値は20000になります + ・IDE BIOS無しなら0で問題ありません + ・値を大きくすると実機のHDD速度を再現できるかも?(要らない機能) +・nevent_setbymsに入れたテストコードがそのままになっていたので修正 +・バージョン情報でIDE BIOSの読み込み状態も表示するようにしました +・テキストVRAMの内容をテキストファイルに出力する機能を付けました(ただし、保存できるのは単純なASCII文字及び漢字だけです) + +0.86 rev16 -> 0.86 rev17 +・2GBを超えるCDイメージがWin2000で正常に読めないバグを修正 +・非公開機能(INIのMODELNUM)で機種IDが設定できるようになりました(書き忘れ) +・サウンド設定でCD-DAの音量調整が出来るようになりました(書き忘れ) +・I/O 1E8Ehのバンク切り替えに暫定対応 + ・使用できるIDE BIOSの制限が緩くなった可能性があります + +0.86 rev15 -> 0.86 rev16 +・CL-GD5430のVRAMウィンドウをPEGCの場所に開けてしまっていたのを修正 +・CL-GD5430のBitBltのROPにあったミスを修正(MJLが比較的普通に使えるようになります) +・さりげなくCL-GD5430のVRAMを4MBにしてみました(JLの専用ドライバ限定で1280x1024解像度が使えます。Windowsでは無理) +・hostdrvでディレクトリに入れないバグを修正(本家より) +・hostdrvで新規作成できないバグを修正(本家より) +・HRTIMERを改良(別スレッドに丸投げ?)してを若干高速化 + +0.86 rev14 -> 0.86 rev15 +・行儀の悪いメモリ読み書き乗っ取りを減らした +・CL-GD5430のVRAMウィンドウを実装しました + ・CL-GD54XXを使うDOSアプリケーションもある程度動くようになります + ・Win3.1の起動はTriple Faultは起こらないもののまだ出来ない模様 +・非公開機能でタイマー10倍速モードを搭載(MIDIスロー再生ごまかし・付属ヘルプ参照) + +0.86 rev13 -> 0.86 rev14 +・MS-DOS, Windows3.1での音楽CD再生が正常になりました + +0.86 rev12 -> 0.86 rev13 +・マウスをゆっくり動かした場合に動かないバグを修正 +・マウス設定をサブメニュー化 +・マウス速度倍率設定を追加(分数形式で指定) + ・メニューにはよく使われそうな倍率しかありませんが、INIを直接編集することにより任意の倍率に設定可能です + ・マウスの倍率設定をマイナスに設定すると・・・(極秘) +・マウスデータ直接読み取りモードを追加しました + ・OSの加速度設定などが反映されないのでより実機に近い操作感になるかも + ・たまにキャプチャに失敗するようなのでそのときはキャプチャし直してください +・システムショートカットキーのフック機能のON/OFFをKeyboardメニューのSystem Key Hookで切り替えられるようにしました +・言語リソースDLLファイルが古いままだったので更新しました +・言語リソース有りだとデバッグユーティリティが開けない問題に暫定対応 +・Windows95/98/NT4.0/2000での音楽CD再生が正常になりました(DOS/Win3.1ではおかしいままです・・・) + +0.86 rev11 -> 0.86 rev12 +・FPUがほぼ正常に動くようになりました(例外処理はまだ動きません) + +0.86 rev10 -> 0.86 rev11 +・FPUが試験的に追加されました +・Win98でVrtwd.386を消さずに動くようになりました(何が効いたのかは不明) +・LANにCPU負荷低減モードが追加されました(データ転送が少ないときは低速モードに切り替えます) +・WindowsNTのためのATAコマンドが追加実装されました +・SMART関連のATAコマンドで落ちないようにしました +・再起動でIDEデバイスが認識しなくなる問題を適当にごまかしました(ォィ 高速再起動には効果ありません +・実機IDE BIOS読み込み機能若干修正 + ・WindowsNTでは実機IDE BIOS(D8000hあたり)が必須です + ・ファイル名はIDE.ROM, D8000.ROM, BANK3.BINのいずれか + ・環境によっては実機IDE BIOSを使うと遅かったり不安定になったりするので注意 + ・IDE BIOS有りで領域確保したディスクと、無しで領域確保したディスクは互換性がないようです。運がいいと両方で読めるディスクが出来ます + +0.86 rev9 -> 0.86 rev10 +・Win2000でのウィンドウアクセラレータの動作が改善しました(ハードウェアアクセラレーション有りでもそこそこ映ります) + +0.86 rev8 -> 0.86 rev9 +・NFD形式含む各種FDイメージ形式のサポートと、CDイメージのサポートを追加しました(Kai版より) +・非公開機能でファイルのドラッグアンドドロップに対応しました(Kai版より) +・Virtual Calendarで月の最終日が飛ばされるバグを修正しました +・ホストの画面解像度が1024x768以下だとウィンドウアクセラレータ未使用でも強制的にフルスクリーンになる問題を修正 +・WinNT3.51,4.0が動くとの噂なので実機のIDE BIOS(ファイル名はIDE.ROM, d8000.rom, bank3.binのいずれか)の読み込み機能を追加しました(手持ちの機種のBIOSでは動かないので動作未確認) + +0.86 rev7 -> 0.86 rev8 +・Win2000ホストサポートとVirtualPC VHDサポートが無効になっていたので使えるように修正 +・CL-GD5430のハードウェアアクセラレーションのバグ修正(Win95,98ではハードウェアカーソル以外ほぼ問題ないレベルになります) +・アイコンをリニューアル(256x256アイコンにも対応) +・見た目だけの問題だけどEGC固定なのに設定の表示がGRCG+になってるのをEGCにしました +・カスタムINI設定ファイルを正しく読み書きできるようにしました + +0.86 rev6 -> 0.86 rev7 +・ウィンドウアクセラレータを一旦High Colorにしてから256色にすると色が化ける不具合を修正 +・Windowsキー対応しました(ただしWin98以降でしか効きません) +・何故かUnicode版関数固定になっていたのを修正 +・画面回転で落ちるバグを修正しました(本家のyuiさんより) + +0.86 rev5 -> 0.86 rev6 +・x86版でVirtual PCの固定サイズVHD形式のサポートが出来ていなかった問題を修正 +・Windows2000でも起動できるようにした(黒翼猫さんのVC++2005/2008/2010 でコンパイルしたプログラムを Windows 95/98/Me/2000で動くようにするライブラリ使用) +・ウィンドウアクセラレータ別窓で常にビジーカーソルが出ていた問題を修正 +・ウィンドウアクセラレータ別窓を統合できるようになりました +・ウィンドウアクセラレータ別窓統合でフルスクリーンモードをサポートしました + ・別窓はGDI、統合後はDirectDrawで描画されます。 + ・フルスクリーンはNo change screen resolutionをONにしておくのがおすすめ。ウィンドウアクセラレータの解像度に実環境の解像度が振り回されるので。DirectDrawにあるウィンドウサイズがフルスクリーン解像度の大きさに変更されるバグも起こりやすいです。ウィンドウサイズと配置が変更されるのを気にしないならOFFでも多分問題ありません。 +・ウィンドウアクセラレータ動作中のマウスカーソル描画が滑らかになりました +・マルチスレッドモード描画モードも搭載しています + ・若干速くなるかも? + ・CPUコア数が少ないならONにしてもあまり意味が無いと思う + ・エラーが出やすいかも + ・ちなみに最速になるのは別窓+マルチスレッドモードの場合です(描画系がすべて別スレッドで動作するため) +・Alt+TabやCtrl+Escなどのシステム関連キーをエミュレータに送信できるようになりました + ・原則として左側のCtrl,Alt,Shift修飾はエミュレータ、右側のCtrl,Alt,Shift修飾はシステムに送られます + ・Ctrl+Alt+Delは例外で無条件でシステムに送られます。エミュレータにCtrl+Alt+Delを送りたいときは代わりにCtrl+Alt+ScrollLockを入力してください。 +・ウィンドウモードを利用する場合は画面解像度を1024x768より大きくしてください(1280x1024とか1920x1080とか)。 + +0.86 rev4 -> 0.86 rev5 +・Virtual PCの固定サイズVHD形式のサポートを追加しました(ただし、AT互換機形式とPC-98形式のパーティションに互換性がないのでConv98AT等を使う必要があります) + +0.86 rev3 -> 0.86 rev4 +・ウィンドウアクセラレータ関連のファイル/ディレクトリ名がvideoだと紛らわしいので名前いじくりました(video/video.c, video/video.c -> wab/wab.c, wab/wab.h) +・NetworkとWindow Acceleratorのモジュール独立性を高めて(比較的)他のボードを追加しやすいようにしてみた(そのうちSoundみたいにメニューで選択できるようにした方が良いかも?) +・上記修正でQEMU由来の部分を分離できたので曖昧だったnet.c,net.hとwab.c,wab.hは完全に修正BSDライセンスになります +・分離されたということで、ネットワークサポート追加のSUPPORT_NET, ウィンドウアクセラレータサポート追加のSUPPORT_WABが追加されました。これらだけを定義してもQEMUのコードはバイナリに組み込まれないので修正BSDライセンスになります +(ただし、これらを定義するだけではLANもウィンドウアクセラレータも使えません。あくまで基本部分を提供するだけなので、QEMUのLGY-98やCL-GD5430を使わないのであれば新たに自作しなければなりません) +・詳しい人がLGY-98やCL-GD5430以外のデバイスも作ってくれると期待(WAB-SとかTridentとか・・・PCI使えるようにしたらだいぶ作りやすくなる気がする) + +0.86 rev2 -> 0.86 rev3 +・カレンダ設定画面でOKが押せない不具合を修正 +・ウィンドウアクセラレータにアナログスイッチモードを追加(要は切り替えの音が鳴らないだけ) + +0.86 rev1 -> 0.86 rev2 +・IDE設定画面を追加 +・ITF workメニューのバグ修正 +・起動時STOPキーによるITFスキップ機能追加(実機ではメモリチェック無し起動ですがnp21wではちゃんとメモリ初期化はします) +・ウィンドウアクセラレータ別窓の操作性改善(キー送信対応・マウス中ボタンでのマウスキャプチャ対応・ウィンドウリサイズサポート) +・x64版の試験提供 + +0.86 -> 0.86 rev1 +・512MB以上のNHDイメージを作成できなくなっていた問題を修正 + +0.85 -> 0.86 +・本家np2 0.86をベースに作り直し&試行錯誤の結果残っていた不要コード整理 +・LAN,ウィンドウアクセラレータともに複数種類対応を想定してダイアログ作り直し +・TAPデバイス名をGUIで選択できるように改良 +・CL-GD5430ウィンドウアクセラレータ内蔵機種選択を追加(ただし、Xe10内蔵以外で動く保証は無し) \ No newline at end of file diff --git a/source/readme.qt.txt b/source/readme.qt.txt index 535c5f980..0a561c0d8 100644 --- a/source/readme.qt.txt +++ b/source/readme.qt.txt @@ -1,5 +1,5 @@ ** Qt porting for Common Source Code Project ** - August 16, 2019 + March 03, 2020 K.Ohta 0. About diff --git a/source/readme.txt b/source/readme.txt index 02b5d872a..893f74825 100644 --- a/source/readme.txt +++ b/source/readme.txt @@ -1,9 +1,9 @@ -Binary archive of retro pc emulator common source code - 4/30/2019 +retro pc emulator common source code + 8/16/2020 --- What's this ? -This archive includes the binaries of the emulators listed below: +This archive includes the all source codes of emulators listed below: ASCII yayaMSX1 MSX1 (by Mr.tanam and Mr.umaiboux) @@ -42,6 +42,8 @@ This archive includes the binaries of the emulators listed below: eFMR-60 FMR-60 eFMR-70 FMR-70 eFMR-80 FMR-80 + GAKKEN + yaTVBOY TV BOY (by Mr.tanam) Gijutsu Hyoron Sha eBabbage-2nd Babbage-2nd HITACHI @@ -90,10 +92,13 @@ This archive includes the binaries of the emulators listed below: ePC-100 PC-100 eTK-80BS TK-80BS / COMPO BS/80 eTK-85 TK-85 + eN5200 N5200 (work in progress) NEC-HE ePCEngine PC Engine / SuperGrafx + CD-ROM^2 Nintendo eFamilyBASIC Family BASIC + Nippon Mail Service + eMuCom Mahjong MICOM MAHJONG (by Mr.GORRY) Pioneer ePX-7 PX-7 (MSX1 + LaserDisc) SANYO @@ -119,6 +124,7 @@ This archive includes the binaries of the emulators listed below: EmuZ-3500 MZ-3500 EmuZ-5500 MZ-5500 EmuZ-6500 MZ-6500 + EmuZ-6550 MZ-6550 (work in progress) eSM-B-80TE SM-B-80TE eX1 X1 eX1twin X1twin @@ -131,6 +137,8 @@ This archive includes the binaries of the emulators listed below: eSMC-777 SMC-777 SORD Emu5 m5 + SPECTRAVIDEO + yaSVI-3x8 SVI-3x8 (by Mr.tanam) Systems Formulate eBUBCOM80 BUBCOM80 TOMY @@ -140,190 +148,43 @@ This archive includes the binaries of the emulators listed below: yayaHX-20+ HX-20 + FDD (by Mr.umaiboux) EmuPIA PASOPIA/PASOPIA5 EmuPIA7 PASOPIA7 + eJ-3100GT J-3100GT (work in progress) + eJ-3100SL J-3100SL (work in progress) YAMAHA eYIS YIS Yuasa Kyouiku System eYALKY YALKY -These binaries are for Windows XP/Vista/7. -DirectX9 and GDI+ are required. -They are tested on Windows 7 Home Premium with SP1. +--- How to build ---- How to use +Build the projects with the Microsoft Visual C++ 2008 with Service Pack 1 or +the Microsoft Visual C++ 2017. -Common menus: +The DirectX SDK is required. +I recommend the DirectX 9.0 SDK Update (December 2004), +and dinput.lib included in the DirectX 9.0 SDK Update (October 2004). -Control - Reset Reset the virtual machine - -------- - CPU x1 Set CPU clock multipler - CPU x2 - CPU x4 - CPU x8 - CPU x16 - Full Speed Run simulation at full speed - -------- - Paste Auto key hitting from the clip board text - Stop Stop the auto key hitting - Romaji to Kana Enter kana letters with alphabet keys - -------- - Save State Save the virtual machine state - Load State Load the virtual machine state - -------- - Debug Main CPU Open console and debug target CPU like SYMDEB - Close Debugger Close debugger console - -------- - Exit Terminate the emulator +If you install the newer DirectX SDK, for example DirectX SDK (June 2010), +and it does not contain dinput.lib, pelase modify src/win32/osd.h to change +the definition of DIRECTINPUT_VERSION from 0x500 to 0x800 as follows: -Cart - Insert Insert the cart image - Eject Eject the cart image - -------- - History Insert the cart image +//#define DIRECTINPUT_VERSION 0x500 +#define DIRECTINPUT_VERSION 0x800 -FD - Insert Insert the floppy disk image - Eject Eject the floppy disk image - -------- - Write Protected Set the write protection of the inserted disk - Correct Timing Emulate FDC with correct timing - Ignore CRC Errors Ignore crc error status - ---- - History Insert the floppy disk image +When you use the Microsoft Visual C++ 2017, the dir macros, +WindowsSDK_IncludePath, WindowsSDK_LibraryPath_x86, and DXSDK_DIR shoud be +defined and should specifies the install directories of the Windows SDK +and the DirectX SDK. +They are usually defined automatically when you install the SDKs. -CMT - Play Insert the cassette tape image to play - Rec Insert the cassette tape image to record - Eject Eject the cassette tape image - -------- - Play Button Control the cassette tape recorder - Stop Button - Fast Foward - Fast Rewind - -------- - Waveform Shaper Enable waveform shaping for *.wav data - -------- - History Insert the cassette tape image to play -Device - Sound - Sound Device Types - -------- - Play FDD Noise Enable playing FDD noise (seek, head up/down) - Play CMT Noise Enable playing CMT noise (relay on/off) - Play CMT Sound Enable playing CMT signal sound - Display - Monitor Types - -------- - Scanline Draw scanline +--- License -Host - Rec Movie 60fps Record the movie to avi and wav files - Rec Movie 30fps - Rec Movie 15fps - Rec Sound Record the wave file - Stop Stop recording - Capture Screen Capture the screen to png file - -------- - Screen - - - Window x1 Set the window size - : - Window x8 - Fullscreen ?x? Set the fullscreen size - -------- - Dot By Dot Set the stretch screen mode in the fullscreen - Stretch (Aspect) - Stretch (Fill) - -------- - Rotate 0deg Rotate the screen - Rotate +90deg - Rotate 180deg - Rotate -90deg - Filter - RGB Filter Enable the RGB CRT filter - None - Sound - 2000Hz Set the sound frequency - 4000Hz You need to restart the emulator - 8000Hz - 11025Hz - 22050Hz - 44100Hz - 48000Hz - 96000Hz - -------- - 50msec Set the sound buffer size (latency) - 100msec You need to restart the emulator - 200msec - 300msec - 400msec - -------- - Realtime Mix Mix the sound in realtime - Light Weight Mix - -------- - Volume Set the volume of each sound device - Input - Joystcik #1/#2 Setup Joystick buttons - -------- - Use Direct3D9 Enable Direct3D9 to render screen - Wait Vsync Wait Vsync when Direct3D9 is enabled - Use DirectInput Enable DirectInput for keyboard - Disable Windows8 DWM Disable the Desktop Window Manager - Show Status Bar Show/Hide the status bar in windwo mode +The copyright belongs to the author, but you can use the source codes +under the GNU GENERAL PUBLIC LICENSE Version 2. - ---- Note - -For Windows PC environment: - - Support Windows PC compatible mouse and joystick devices. - - Accelerator key: - ALT+RETURN - Switch window / fullscreen - CTRL+RETURN - Enable/Disenable mouse control - APPLICATION - Enable/Disable full speed emulation - CTR+APPLICATION - Enable/Disable roman to kana conversion - - *) While the mouse control is enabled, the mouse cursor is hidden. - -Floppy disk images: - - P88SR D88 (*.d88;*.d77;*.1dd) - TeleDisk (*.td0) - ImageDisk (*.imd) - CPDRead (*.dsk) - T98-NEXT r0 (*.nfd) - Anex86 (*.fdi) - BKDSK (*.hdm;*.hd5;*.hd4;*.hdb;*.dd9;*.dd6) - - and any other solid images (*.tfd;*.xdf;*.2d;*.sf7;*.img;*.ima;*.vfd) - -Cassette tape images: - - Support wav files (PCM only) or special format images for each machine. - -CD-ROM images: - - Support BIN/IMG+CUE or IMG+CCD (CloneCD) format images. - -FDD noise: - - Place the wave files below: FDDSEEK.WAV. HEADDOWN.WAV. HEADUP.WAV - -CMT noise: - - Place the wave files below: RELAY_ON.WAV, RELAYOFF.WAV, FAST_FWD.WAV - -Save/Load State info: - - The state file contains any disk or other images. - Please NEVER upload your state files on the web. - - The state file format will be often changed. - Please don't invite your state file can be loaded after you update - the emulator binary. +See also COPYING.txt for more details about the license. --- Thanks @@ -352,6 +213,8 @@ Save/Load State info: MAME i286 core - vm/i386.* MAME i386 core +- vm/i386_np21.* + Neko Project 21/W i386 core - vm/i8259.* Neko Project 2 and MESS 8259 core - vm/ld700.* @@ -450,6 +313,8 @@ Save/Load State info: - vm/m5/* MESS sord driver Mr.Moriya for Sord M5 hardware design info +- vm/micom_mahjong/* + eMuCom Mahjong by Mr.GORRY - vm/msx/* yaMSX1 and yaMSX2 by Mr.tanam - vm/msx/memory.* @@ -494,6 +359,10 @@ Save/Load State info: Mr.Fred Han Kraan for EPSON QC-10/QX-10 hardware design info - vm/scv/* Mr.Enri and Mr.333 for Epoch Super Cassette Vision hardware info +- vm/svi3x8/* + yaSVI-3x8 by Mr.tanam +- vm/tvboy/* + yaTVBOY by Mr.tanam - vm/x07/io.* x07_emul by Mr.Jacques Brigaud - vm/x1/* diff --git a/source/readme_by_artane.txt b/source/readme_by_artane.txt index 5655cd8ac..25e92322e 100644 --- a/source/readme_by_artane.txt +++ b/source/readme_by_artane.txt @@ -1,5 +1,5 @@ ** Qt porting for Common Source Code Project ** - August 16, 2019 + September 26, 2020 K.Ohta * If you can't read Japanese, read readme.qt.txt . @@ -12,7 +12,7 @@ ソースコード: - https://github.com/Artanejp/common_source_project-fm7/releases/tag/SNAPSHOT_20190816 + https://github.com/Artanejp/common_source_project-fm7/releases/tag/SNAPSHOT_2020926 追加情報: @@ -59,8 +59,12 @@ h. Qt5.5(Ubuntu 16.04LTS向け)もしくはQt5.10(Win32とDebian GNU/Linux sid向け)でビルドしてあります。 i. 表示基盤のデフォルトが、OpenGL ES2.0になりました。コマンドラインオプション --opengl で変更が可能です(--helpで参照) + + j. Windows のビルドを、Docker環境上のLLVM CLANG (9) にしました。例外処理に関して、MinGW-w64のgccは非常に遅い方法を取ってるためです(Borlandが悪いのですが)。 + 詳細は、 https://github.com/Artanejp/llvm-mingw と https://hub.docker.com/r/artanejp/llvm-mingw64-ubuntu-cosmic を参照して下さい。 - * Windows もしくは GNU/Linux のcross tool chain (要Wine)で、MinGW (gcc6) と Qt 5.10 でのビルドができることを確認しました。 + * Windows もしくは GNU/Linux のcross tool chain (要Wine)で、MinGW (gcc6) と Qt 5.10 でのビルドができることを確認しました。 + * TIPS: * Windows等で動かした時に、画面の書き替えが表示されない場合は、環境変数 QT_OPENGL を software にしてみてください。(例えば、 @@ -155,77 +159,79 @@ Special thanks to: Ryu Takegamiさん : eFM-8/7/77/AV/40/EX のデバッグに協力していただいています。 はせりんさん : eFM-8/7/77/AV/40/EX のデバッグに協力していただいています。 Ootake 開発者の皆さん: ePCENGINEの改善のヒントをソースコードから勉強させていただいてます。 - + Soji Yamakawaさん : eFM-Townsの開発で「津軽」を参考にさせていただいたり、 + アドバイスを頂いたりしています。 Changes: * 前の変更点をお読みになる場合には、ChangeLogと000_gitlog.txtをお読み下さい。 -* SNAPSHOT Aug 16, 2019 - * Upstream 2019-04-30. - * This is point release, still exists some issues (i.e.EMM386(NEC/PC98) and FreeBSD(98) don't work) for PC-9801 and PC-Engine and some VMs, will fix them. - * [UI/Qt] DEBUGGER: Add history for debugger command line. - * [UI/Qt] DEBUGGER: Add auto-completion for command-line. - * [VM/DEVICE] Use __FASTCALL with interfaces, read_*() ,write_*(), fetch_op() and some functions.Make this faster emulation (i.e.PC-9801RA and EMM386 under FreeDOS). - * [VM/PC9801] Separate EGC functions. - * [VM/PC9801] Add V30@8.0MHz with some I286/I386 machines. - * [VM/PC9801] Check differnt of system work area (0000:0400-0000:05FF) both mame(pc9801rs) and emupc9801ra . - * [VM/PC9801] Add "UPPER_I386" flag for detect using later than HAS_I386. - * [VM/PC9801] CPUREG: (Maybe) improve changing cpu sequence around I/O 00F0h. - * [VM/PC9801] CPUREG: Redirect interrupt signal via CPUREG:: .VMs with V30 sub CPU (i.e.PC9801RA) work with V30. - * [VM/PC9801] Fix wrong initialize SYS_PORT_B. - * [VM/PC9801] Fix wrong initialize memory switch. - * [VM/PC9801] Add DIPSWITCH object. - * [VM/PC9801] Fix different value at [0000:0501]. - * [VM/PC9801] MEMBUS: Split update_bios() to functions. - * [VM/FP1100] Fix lacking some key symbols.Thanks to https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/540 . - * [VM/AY_3_891X] Fix not supported defines, replace flags. - * [VM/AY_3_891X] Add feature ; dump/set register via debugger. - * [VM/YM2151] Add feature ; dump/set register via debugger. - * [VM/YM2203] Add feature ; dump/set register via debugger. - * [VM/SN74689AN] Add feature ; dump/set register via debugger. - * [VM/BEEP] Add feature ; dump register via debugger. - * [VM/PCM1BIT] Add feature ; dump register via debugger. - * [VM/I80x86/V30] Start debugger even halting. - * [VM/I80x86/8088/V30] Make i86/186/88/286 and V30 to common_vm. - * [VM/I386] Fix WRONG flag mask at LMSW. - * [VM/I386] MOV CR0 EyX : Fix wrong flags handling. - * [VM/I386] Exitable when falling into infinite TRAP-Loop. - * [VM/I386] mov CRx,R32/mov r32,CRx : Adjusting. - * [VM/i8259] Add PIC HACKing flag for PC9801. - * [VM/uPD7810/uPD7907] PC2001: Include uPD7810 variants and uPD7907 to libCSP_common_VM. - * [VM/MB8877] Fix buffer overflow with logging. - * [VM/Z80DMA] TODO/WIP: Workaround for https://tablacus.github.io/LSX-Dodgers/ .This still be not resolved issue. - * [VM/EVENT] Add remove_context_cpu().This may not effect to MAIN_CPU(id==0). - * [DOC/FM7] Fix typo (*ノω・*)てへぺろ - * [Qt/LOGGER] Improve locking. - * [UI/Qt] OOPs: Fix LACK of DATARECORDER BUTTONS(abolish of USE_TAPE_BUTTON): Lack of merging UPSTREAM 2018/10/07. - * [UI/Qt] MENU: Split some methods (of Ui_MainMenuBase::) to menu_emulator.cpp and menu_machine.cpp . - * [UI/Qt] MENU: Simplify menu creation. - * [CONFIG/Qt] Fix bit order of logging configure. - * [BUILD/CMAKE] Add CPU affinity mask when compiling.This may work only with GNU/Linux host. - * [BUILD/CMAKE] Improve build message with finished. - * [BUILD/MINGW] Update optimize parameter. - * [BUILD] Separate definitions of archtecture flags. - * [BUILD] Add ARM32/64 definitions (initial).Still not testing. - * Built with 0810a8f8b9ba44cedc19bf6b8e903c9c1b5d6f04 (or later). - --- Aug 16, 2019 20:38:06 +0900 K.Ohta +* SNAPSHOT September 26, 2020 + * Upstream 2020-04-06. + * [FMTOWNS/DMAC] Bootable TownsOS v1.1L30 based softwares. + Fix around DMA address mask. + See source/src/vm/fmtowns/00_status.ja.md. + * [General] Now, version of all DLLs/SOLIBs are 3.0.x. + * [DEVICE] Change API: special_reset(num). + This aimes to support FM-Towns's multiple special resetting. + * [I18N] Prepare to support multiple languages. + * [Draw/GL4_5] Wait until complete to mapping. + Fix crash with QUAZZLE (FMTOWNS;FSW Collection 10). + * [VM/FMTOWNS][OOPs] Fix fallthroughs. + * [VM/FMTOWNS] Add IC CARD feature. + * [FMTOWNS/CRTC] More simple logic at rendering. + * [FMTOWNS/CDROM] RESTORE/SEEK COMMAND (00h) must seek to lba0, then aimed lba. + * [FMTOWNS/CDROM] PAUSE COMMAND (85h) : Return extra status even isn't audio track. + * [FMTOWNS/CDROM] READ MODE1: May not need extra status, integrated after reading. + * [FMTOWNS/MEMORY] Integrate memory accessing to primitive inline functions. + * [FMTOWNS/CDROM][WIP] Status around CMD A0h. This is working-in-progress. + * [FMTOWNS/CDROM][WIP] TRY: Implement PIO transfer. + * [FMTOWNS/CDROM] Should read per a sector, not variable length. + * [FMTOWNS/CDROM] Implement pseudo burst transfer for DMA. + * [FMTOWNS/CDROM] Set CDDA_STATUS=CDDA_OFF before reading data. + Fix スーパーリアル麻雀PIV. + * [FMTOWNS/SPRITE] Initially works. + * [FMTOWNS/VRAM] Faster write access via write_memory_mapped_io[16|32]() . + * [FMTOWNS/TIMER] Disable free run counter before 1H/2H/1F/2F. + * [FMTOWNS/FLOPPY] Implement some bits and disk changed feature + (0208h:bit0:R after Towns2H/2F/1H/1F). + * [FMTOWNS/TIMER] Didable 1uS wait feature wait before xxF/xxH. + * [FMTOWNS/KEYBOARD] TRY: Boot with 'CD' 'H0' etc.Still works only with 'DEBUG'. + * [FMTOWNS/SCSI] Add SIG_SCSI_EOT signal. + * [FMTOWNS/SCSI] Set ctr_reg after sending command to host. + * [Qt/LOGGER] Fix not initialize (internal)osd_pointer; + wish to fix below issue (@Fedora Linux) + https://matsuri.5ch.net/test/read.cgi/i4004/1526806551/935 + by this. + * [VM/I386_NP21] Memory access:Make functions inline to be faster processing. + * [VM/COMMON_VM] Fix warining of 'set_context_intr' hides overloaded + virtual function [-Woverloaded-virtual] with LLVM Clang++. + * [VM/MC6809] Remove MC6809_BASE::, integrated to MC6809:: . + * [VM/Z80] Remove Z80_BASE::, integrate to Z80:: . + * [VM/UPD7220] Limit address of PSET.More correctness clock feature. + * [VM/UPD71071] Fix tc bit down. + * [VM/UPD71071] Add some signals. + * [VM/UPD71071][FMTOWNS][MZ2800] Update API; Separate TC signals per a channel. + * [VM/UPD71071] SREQ is prior than MASK.Don't auto transfer at demand mode. + * [VM/UPD71071] Implement ENDx signal for stopping DMA from some devices. + + * [VM/I8259] Initialize registers by reset(). + * [EMU][UI/FLOPPY] Implement 1sec delayed open() for floppy, + fix not detect when changing from HISTORY. + * [X1/DRAW] Fix spending a lot of host CPU usage on draw_screen(). + This issue has happened at only X1 (not turbo) due to + memory aligns and cache lines. + Set alignment of RAM and some values. + * Built with 97db8d7a26eb8eeb7722b009456d7c9bcadda0f7 (or later). + +-- Sep 26, 2020 18:29:40 +0900 K.Ohta 本家の変更: * 前の変更点をお読みになる場合には、history.txtをお読み下さい。 -4/30/2019 +4/6/2020 -[VM/DEVICE] add is_primary_cpu() and update_extra_event() -[VM/EVENT] support to udpate event while cpu is running one opecode -[VM/I8259] fix reading isr register (thanks Mr.rednow) -[VM/SCSI_HOST] fix to raise irq at command/message phase -[VM/Z80] improve to update event in every read/write cycle +[VM/I386_NP21] update to Neko Project 21/W ver0.86 rev72 -[CEFUCOM21] support Hino Electronics CEFUCOM-21 (not work) -[MZ2500/CRTC] apply crtc patch (thanks Mr.Koucha-Youkan) -[PC8801MA] improve to enable/disable cmdsing and pcg -[PC8801MA] improve to enable/disable changing palette for each scan line ----- diff --git a/source/readme_by_mr_gorry.txt b/source/readme_by_mr_gorry.txt new file mode 100644 index 000000000..df25aaee4 --- /dev/null +++ b/source/readme_by_mr_gorry.txt @@ -0,0 +1,98 @@ +◇ MICOM MAHJONG Emulator 'eMuCom Mahjong'on Common Source Code Project + Hiroaki GOTO as GORRY / http://GORRY.hauN.org/ + Version 20200721a + +======================================================================== +1. これはなに? +======================================================================== + +'eMuCom Mahjong'は、家庭用ゲーム機「マイコン麻雀(日本メールサービス、 +1982年)」を再現するエミュレータを、武田俊也氏による「Common Source +Code Project」上にて実装したものです。 + +「Common Source Code Project」については、以下をご覧ください。 +http://takeda-toshiya.my.coocan.jp/common/index.html + + +======================================================================== +2. なにがいる? +======================================================================== + +'eMuCom Mahjong'の動作には、以下のものが必要です。 + +1. ハードウェア + + Windows 10 32/64bit上で動作確認をしています。 + +2. 実機ROMイメージファイル + + 「マイコン麻雀」実機には、以下のROMが搭載されています。 + + - MS-1 2732(32x8bit ROM) + - MS-2 2732(32x8bit ROM) + - MS-3 2732(32x8bit ROM) + - MS-4 2732(32x8bit ROM) + →以上を連結し、「PRG.ROM」ファイル(16384バイト)を作成します。 + + - MS-A 2716(16x8bit ROM) + →「CG.ROM」ファイル(2048バイト)を作成します。 + + 以上を実行ファイル「micom_mahjong.exe」と同じフォルダに置き、実行ファ + イルを起動します。 + + +======================================================================== +3. なにをおす? +======================================================================== + +'eMuCom Mahjong'は、以下のキーで操作します。 + + 1 1(フルキー) + 2 2(フルキー) + 3 3(フルキー) + 4 4(フルキー) + 5 5(フルキー) + 6 6(フルキー) + 7 7(フルキー) + 8 8(フルキー) + 9 9(フルキー) + 10 0(フルキー) + 11 [-=ほ](JPキー), [-~](USキー), 1(テンキー) + 12 [^~へ](JPキー), [=+](USキー), 2(テンキー) + 13 [\|](JPキー), [BackSpace](JP/USキー), 3(テンキー) + 0(ツモ) Enter, Space + ポン Z, F1 + チー X, F2 + カン C, F3 + リーチ V, F4 + ロン A, F5 + + +======================================================================== +4. びるどする? +======================================================================== + +このパッケージに含まれるソースは、「Common Source Code Project」のソース + (4/6/2020版)の上に重ねて解凍することで、ビルドを行うことができます。 +「vc++2013/micom_mahjong.vcxproj」をVisual Studio 2013で開いてください。 + + +======================================================================== +5. 著作権表記 +======================================================================== + +このパッケージには、当方が記名したソースファイルが同梱されています。これ +らは当方が著作権を主張しますが、使用・再配布は当方または「Common Source +Code Project」管理者が定める方法・条件に基づいて行うことができます。 + + +======================================================================== +6. 連絡先 +======================================================================== + +後藤 浩昭 / GORRY +http://GORRY.hauN.org/ +twitter/gorry5 + +======================================================================== +[EOF] diff --git a/source/readme_fm7.jp.txt b/source/readme_fm7.jp.txt index a81fc764a..5c047160b 100644 --- a/source/readme_fm7.jp.txt +++ b/source/readme_fm7.jp.txt @@ -1,5 +1,5 @@ ** FM-7 series emulator for common source code project. ** - August 16, 2019 + March 03, 2020 K.Ohta diff --git a/source/readme_fm7.txt b/source/readme_fm7.txt index 7caf4d5c3..922615315 100644 --- a/source/readme_fm7.txt +++ b/source/readme_fm7.txt @@ -1,5 +1,5 @@ ** FM-7 series emulator for common source code project. ** - August 16, 2019 + January 05, 2020 K.Ohta 1.Background diff --git a/source/revision.txt b/source/revision.txt index 6740cb2f3..a3b98a3ae 100644 --- a/source/revision.txt +++ b/source/revision.txt @@ -1,3 +1,3 @@ -Upstream 2019-04-30
-Qt Port and FM7 series 2019-08-16
+Upstream 2020-08-16
+Qt Port and FM7 series 2020-09-26
diff --git a/source/sample-scripts/build_default_gcc_mingw-cross.sh b/source/sample-scripts/build_default_gcc_mingw-cross.sh new file mode 100644 index 000000000..d66c3c1b0 --- /dev/null +++ b/source/sample-scripts/build_default_gcc_mingw-cross.sh @@ -0,0 +1,63 @@ +FFMPEG_DIR="/usr/local/i586-mingw-msvc/ffmpeg-4.3" +QT5_DIR="/usr/local/i586-mingw-msvc/Qt5.15/mingw_82x" +EXTRA_INCLUDE_DIR="-I/usr/share/mingw-w64/include" +PATH=/opt/llvm-mingw/bin:$PATH +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE="$PWD/../cmake/toolchains/toolchain_mingw_cross_gcc.cmake" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -ggdb \ + -gz=zlib \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + ${EXTRA_INCLUDE_DIR} \ + " \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -ggdb \ + -gz=zlib \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + ${EXTRA_INCLUDE_DIR} \ + " \ + -DCMAKE_C_FLAGS_RELEASE=" \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + ${EXTRA_INCLUDE_DIR} \ + " \ + -DCMAKE_CXX_FLAGS_RELEASE=" \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + ${EXTRA_INCLUDE_DIR} \ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELEASE="\ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELEASE="\ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -ggdb \ + -gz=zlib \ + -L/usr/i686-w64-mingw32/lib \ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -ggdb \ + -gz=zlib \ + -L/usr/i686-w64-mingw32/lib \ + " \ + -DLIBAV_ROOT_DIR="${FFMPEG_DIR}" \ + -DQT5_ROOT_PATH="${QT5_DIR}" \ + -DUSE_DEVICES_SHARED_LIB=ON \ + -DUSING_TOOLCHAIN_GCC_DEBIAN=ON \ + + \ No newline at end of file diff --git a/source/sample-scripts/build_default_vars.Xenial.gcc.sh b/source/sample-scripts/build_default_vars.Xenial.gcc.sh new file mode 100644 index 000000000..6c2657cd9 --- /dev/null +++ b/source/sample-scripts/build_default_vars.Xenial.gcc.sh @@ -0,0 +1,23 @@ +cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD/../cmake/toolchains/toolchain_native_gcc.cmake" \ + -DCMAKE_BUILD_TYPE=Relwithdebinfo \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -O3 \ + -msse2 \ + -mfpmath=sse \ + " \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -O3 \ + -msse2 \ + -mfpmath=sse \ + -std=c++11 \ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -ggdb \ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -O3 \ + " \ diff --git a/source/sample-scripts/build_default_vars.llvm.sh b/source/sample-scripts/build_default_vars.llvm.sh new file mode 100644 index 000000000..f59739cca --- /dev/null +++ b/source/sample-scripts/build_default_vars.llvm.sh @@ -0,0 +1,30 @@ +cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD/../cmake/toolchains/toolchain_native_llvm.cmake" \ + -DCMAKE_BUILD_TYPE=Relwithdebinfo \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=" \ + -g \ + -gz=zlib \ + -O3 \ + -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=" \ + -g \ + -gz=zlib \ + -O3 \ + -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_EXE_LINKER_FLAGS="\ + -g \ + -gz=zlib \ + " \ diff --git a/source/sample-scripts/build_default_vars.llvm11.sh b/source/sample-scripts/build_default_vars.llvm11.sh new file mode 100644 index 000000000..38b6153d5 --- /dev/null +++ b/source/sample-scripts/build_default_vars.llvm11.sh @@ -0,0 +1,42 @@ +cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD/../cmake/toolchains/toolchain_native_llvm11.cmake" \ + -DCMAKE_BUILD_TYPE=Relwithdebinfo \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=" \ + -g \ + -gz=zlib \ + -O3 \ + -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + -Wa,--compress-debug-sections=zlib \ + " \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=" \ + -g \ + -gz=zlib \ + -O3 \ + -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + -Wa,--compress-debug-sections=zlib \ + " \ + -DCMAKE_EXE_LINKER_FLAGS="\ + -g \ + -gz=zlib \ + -O3 \ + -msse2 \ + -Wl,--compress-debug-sections=zlib \ + " \ + -DCMAKE_MODULE_LINKER_FLAGS="\ + -g \ + -gz \ + -O3 \ + -msse2 \ + -Wl,--compress-debug-sections=zlib \ + " \ diff --git a/source/sample-scripts/build_default_vars.sh.gcc.sh b/source/sample-scripts/build_default_vars.sh.gcc.sh new file mode 100644 index 000000000..8447f4d9e --- /dev/null +++ b/source/sample-scripts/build_default_vars.sh.gcc.sh @@ -0,0 +1,41 @@ +cmake .. -DCMAKE_TOOLCHAIN_FILE="$PWD/../cmake/toolchains/toolchain_native_gcc.cmake" \ + -DCMAKE_BUILD_TYPE=Relwithdebinfo \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=" \ + -gz \ + -ggdb \ + -O3 \ + -msse2 \ + -mfpmath=sse \ + -flto \ + -flto-compression-level=9 \ + -ffat-lto-objects \ + -Wa,--compress-debug-sections=zlib \ + " \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=" \ + -gz \ + -ggdb \ + -O3 \ + -msse2 \ + -flto \ + -flto-compression-level=9 \ + -ffat-lto-objects \ + -Wa,--compress-debug-sections=zlib \ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO="\ + -ggdb \ + -gz \ + -O3 \ + -flto=6 \ + -msse2 \ + -Wl,--compress-debug-sections=zlib \ + -Wa,--compress-debug-sections=zlib \ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO="\ + -ggdb \ + -gz \ + -O3 \ + -flto=6 \ + -msse2 \ + -Wl,--compress-debug-sections=zlib \ + -Wa,--compress-debug-sections=zlib \ + " \ diff --git a/source/sample-scripts/build_default_vars_mingw-cross.sh b/source/sample-scripts/build_default_vars_mingw-cross.sh new file mode 100644 index 000000000..a9f0d065e --- /dev/null +++ b/source/sample-scripts/build_default_vars_mingw-cross.sh @@ -0,0 +1,77 @@ +FFMPEG_DIR="/usr/local/i586-mingw-msvc/ffmpeg-4.3" +QT5_DIR="/usr/local/i586-mingw-msvc/Qt5.15/mingw_82x" +PATH=/opt/llvm-mingw/bin:$PATH +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE="$PWD/../cmake/toolchains/toolchain_mingw_cross_linux.cmake" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -ggdb \ + -gz=zlib \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -ggdb \ + -gz=zlib \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_C_FLAGS_RELEASE=" \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_CXX_FLAGS_RELEASE=" \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELEASE="\ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELEASE="\ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -ggdb \ + -gz=zlib \ + -L/usr/i686-w64-mingw32/lib \ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -ggdb \ + -gz=zlib \ + -L/usr/i686-w64-mingw32/lib \ + " \ + -DLIBAV_ROOT_DIR="${FFMPEG_DIR}" \ + -DQT5_ROOT_PATH="${QT5_DIR}" \ + -DUSE_DEVICES_SHARED_LIB=ON \ + + \ No newline at end of file diff --git a/source/sample-scripts/build_default_vars_mingw-llvm11-cross.sh b/source/sample-scripts/build_default_vars_mingw-llvm11-cross.sh new file mode 100644 index 000000000..27116bcfe --- /dev/null +++ b/source/sample-scripts/build_default_vars_mingw-llvm11-cross.sh @@ -0,0 +1,84 @@ +#!/bin/sh +ARCH_TRIPLE=i686-w64-mingw32 +LIBS_PREFIX="/usr/local/i586-mingw-msvc" + +FFMPEG_DIR="${LIBS_PREFIX}/ffmpeg-4.3" +QT5_DIR="${LIBS_PREFIX}/Qt5.15/mingw_82x" + +PATH=/opt/llvm-mingw-11/bin:$PATH +cmake .. \ + -DCMAKE_TOOLCHAIN_FILE="$PWD/../cmake/toolchains/toolchain_mingw_cross_llvm11.cmake" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -ggdb \ + -gz=zlib \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=" \ + -g2 \ + -ggdb \ + -gz=zlib \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_C_FLAGS_RELEASE=" \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_CXX_FLAGS_RELEASE=" \ + -O3 \ + -march=i686 \ + -msse -msse2 \ + -mfpmath=sse \ + -Wreserved-user-defined-literal \ + -fslp-vectorize \ + -fvectorize \ + -fstrict-vtable-pointers \ + -fstrict-enums \ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELEASE="\ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELEASE="\ + " \ + -DCMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -ggdb \ + -gz=zlib \ + -L/usr/i686-w64-mingw32/lib \ + " \ + -DCMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO="\ + -g2 \ + -ggdb \ + -gz=zlib \ + -L/usr/${ARCH_TRIPLE}/lib \ + " \ + -DLIBAV_ROOT_DIR="${FFMPEG_DIR}" \ + -DQT5_ROOT_PATH="${QT5_DIR}" \ + -DTARGET_ARCH="${ARCH_TRIPLE}" \ + -DLIBS_PREFIX="${LIBS_PREFIX}" \ + -DUSE_DEVICES_SHARED_LIB=ON \ + + \ No newline at end of file diff --git a/source/src/CMakeLists.txt b/source/src/CMakeLists.txt index b18c09d5f..0edcec466 100644 --- a/source/src/CMakeLists.txt +++ b/source/src/CMakeLists.txt @@ -2,21 +2,24 @@ message("* common/common") #set(CMAKE_BUILD_SETTING_C_FLAGS "${CMAKE_C_FLAGS} -msse2 -msse -mmmx") -add_library(common_emu - emu.cpp -) +#add_library(common_emu +# emu.cpp +#) if(USE_DEVICES_SHARED_LIB) - add_library(common_common + add_library(common_${EXE_NAME} config.cpp debugger.cpp ) else() - add_library(common_common + add_library(common_${EXE_NAME} common.cpp config.cpp + config_dll.cpp debugger.cpp fileio.cpp fifo.cpp ringbuffer.cpp ) endif() + +set_std(common_${EXE_NAME}) diff --git a/source/src/common.cpp b/source/src/common.cpp index 0683eab49..777729c72 100644 --- a/source/src/common.cpp +++ b/source/src/common.cpp @@ -1341,7 +1341,7 @@ const _TCHAR *DLL_PREFIX get_initial_current_path() #else getcwd(current_path, _MAX_PATH); #endif - int len = strlen(current_path); + size_t len = strlen(current_path); if(current_path[len - 1] != '\\' && current_path[len - 1] != '/') { #if defined(_WIN32) || defined(Q_OS_WIN) current_path[len] = '\\'; @@ -1437,8 +1437,8 @@ bool DLL_PREFIX check_file_extension(const _TCHAR *file_path, const _TCHAR *ext) if((pos != (int)std::string::npos) && (pos >= ((int)s_fpath.length() - (int)s_ext.length()))) return true; return false; #else - int nam_len = _tcslen(file_path); - int ext_len = _tcslen(ext); + size_t nam_len = _tcslen(file_path); + size_t ext_len = _tcslen(ext); return (nam_len >= ext_len && _tcsncicmp(&file_path[nam_len - ext_len], ext, ext_len) == 0); #endif @@ -1594,6 +1594,158 @@ const wchar_t *DLL_PREFIX tchar_to_wchar(const _TCHAR *ts) #endif } +int DLL_PREFIX ucs4_kana_zenkaku_to_hankaku(const uint32_t in, uint32_t *buf, int bufchars) +{ + uint32_t out = (uint32_t)in; + int letters = 1; + if((buf != NULL) && (bufchars >= 4)) { + memset(buf, 0x00, sizeof(uint32_t) * bufchars); + } else { + return -1; + } + // U+FF61-U+FF9F = HANKAKU KANA + // U+FF01-U+FF5E = ZENKAKU ALPHABET + // U+3041-U+309E = ZENKAKU HIRAGANA + // U+30A1-U+30FE = ZENKAKU KATAKANA + static const uint32_t kanacnvtable[] = { + // AIUEO + 0xff67, 0xff71, 0xff68, 0xff72, 0xff69, 0xff73, 0xff6a, 0xff74, 0xff6b, 0xff75, + // KA/GA + 0xff76, 0xff76, 0xff77, 0xff77, 0xff78, 0xff78, 0xff79, 0xff79, 0xff7a, 0xff7a, + // SA/ZA + 0xff7b, 0xff7b, 0xff7c, 0xff7c, 0xff7d, 0xff7d, 0xff7e, 0xff7e, 0xff7f, 0xff7f, + // TA/DA + 0xff80, 0xff80, 0xff81, 0xff81, 0xff6f, 0xff82, 0xff82, 0xff83, 0xff83, 0xff84, 0xff84, + // NA + 0xff85, 0xff86, 0xff87, 0xff88, 0xff89, + // HA/BA/PA + 0xff8a, 0xff8a, 0xff8a, 0xff8b, 0xff8b, 0xff8b, 0xff8c, 0xff8c, 0xff8c, + 0xff8d, 0xff8d, 0xff8d, 0xff8e, 0xff8e, 0xff8e, + // MA + 0xff8f, 0xff90, 0xff91, 0xff92, 0xff93, + // YAYUYO + 0xff6c, 0xff94, 0xff6d, 0xff95, 0xff6e, 0xff96, + // RA + 0xff97, 0xff98, 0xff99, 0xff9a, 0xff9b, + // WA + 0xff9c, 0xff9c, 0xff68, 0xff69, 0xff66, 0xff9d, 0xff73, 0xff76, 0xff79, 0xff9e, 0xff9f, + 0x00000000, + }; + + enum { + L_NORMAL, + L_SMALL, + L_DAKUON, + L_HANDAKUON, + L_SMALL_WA, + L_WI, + L_WO, + L_WE, + L_VU, + L_XKA, + L_XKE + }; + static const int attr_tbl[] = { + // AIUEO + L_SMALL, L_NORMAL, L_SMALL, L_NORMAL, L_SMALL, L_NORMAL, L_SMALL, L_NORMAL, L_SMALL, L_NORMAL, + // Kx + L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, + // Sx + L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, + // Tx + L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, L_SMALL, L_NORMAL, L_DAKUON, L_NORMAL, L_DAKUON, + // Nx + L_NORMAL, L_NORMAL, L_NORMAL, L_NORMAL, L_NORMAL, + // Hx + L_NORMAL, L_DAKUON, L_HANDAKUON, L_NORMAL, L_DAKUON, L_HANDAKUON, L_NORMAL, L_DAKUON, L_HANDAKUON, L_NORMAL, L_DAKUON, L_HANDAKUON, L_NORMAL, L_DAKUON, L_HANDAKUON, + // Mx + L_NORMAL, L_NORMAL, L_NORMAL, L_NORMAL, L_NORMAL, + // Yx + L_SMALL, L_NORMAL, L_SMALL, L_NORMAL, L_SMALL, L_NORMAL, + // Rx + L_NORMAL, L_NORMAL, L_NORMAL, L_NORMAL, L_NORMAL, + // Wx + L_SMALL_WA, L_NORMAL, L_WI, L_WE, L_NORMAL, L_NORMAL, L_VU, L_XKA, L_XKE + }; + + uint32_t tmp = 0; + if((in < 0xFF5F) && (in > 0xFF00)) { // ALPHABET + out = in - 0xff00 + 0x20; // Zenkaku alphabet to Hankaku alphabet + buf[0] = out; + return 1; + } else if((in < 0x3095) && (in > 0x3040)) { // Hiragana + tmp = in - 0x3041; + } else if((in < 0x30f5) && (in > 0x30a0)) { // Katakana + tmp = in - 0x30a1; + } else if((in == 0x3099) || (in == 0x309b)) { // DAKUON + buf[0] = 0xff9e; + return 1; + } else if((in == 0x309a) || (in == 0x309c)) { // HAN DAKUON + buf[0] = 0xff9f; + return 1; + } else if(in == 0x3002) {// MARU + buf[0] = 0xff61; + return 1; + } else if(in == 0x30fb) {// NAKAGURO + buf[0] = 0xff65; + return 1; + } else if(in == 0x30fc) {// ONBIKI + buf[0] = 0xff70; + return 1; + } else if(in == 0x3001) {// Ten + buf[0] = 0xff64; + return 1; + } else if((in == 0x300c) || (in == 0x300d)){// KagiKakko + buf[0] = 0xff62 + (in - 0x300c); + return 1; + } else { + buf[0] = in; + return 1; + } + uint32_t kana = kanacnvtable[tmp]; + int attr = attr_tbl[tmp]; + switch(attr) { + case L_NORMAL: + case L_SMALL: + buf[0] = kana; + break; + case L_DAKUON: + buf[0] = kana; + buf[1] = 0xff9e; // DAKUON + letters = 2; + break; + case L_HANDAKUON: + buf[0] = kana; + buf[1] = 0xff9f; // DAKUON + letters = 2; + break; + case L_SMALL_WA: + buf[0] = kana; + break; + case L_WI: + buf[0] = kana; // WIP + break; + case L_WE: + buf[0] = kana; // WIP + break; + case L_VU: + buf[0] = 0xff73; // U + buf[1] = 0xff9f; // DAKUON + letters = 2; + break; + case L_XKA: + buf[0] = 0xff76; // KA + break; + case L_XKE: + buf[0] = 0xff79; // KE + break; + default: + buf[0] = kana; + break; + } + return letters; +} + const _TCHAR *DLL_PREFIX create_string(const _TCHAR* format, ...) { static _TCHAR buffer[8][1024]; @@ -1739,7 +1891,7 @@ int DLL_PREFIX decibel_to_volume(int decibel) return (int)(1024.0 * pow(10.0, decibel / 40.0) + 0.5); } -int32_t DLL_PREFIX apply_volume(int32_t sample, int volume) +int32_t DLL_PREFIX __FASTCALL apply_volume(int32_t sample, int volume) { // int64_t output; int32_t output; @@ -2334,8 +2486,8 @@ void DLL_PREFIX calc_high_pass_filter(int32_t* dst, int32_t* src, int sample_fre if(alpha <= 0.0f) alpha = 0.0f; float ialpha = 1.0f - alpha; - __DECL_ALIGNED(16) float tmp_v[samples * 2]; // 2ch stereo - __DECL_ALIGNED(16) float tmp_h[samples * 2]; + __DECL_ALIGNED(16) float tmp_v[samples * 2 + 4]; // 2ch stereo + __DECL_ALIGNED(16) float tmp_h[samples * 2 + 4]; for(int i = 0; i < (samples * 2); i ++) { tmp_h[i] = (float)(src[i]); } @@ -2371,8 +2523,8 @@ void DLL_PREFIX calc_low_pass_filter(int32_t* dst, int32_t* src, int sample_freq if(alpha <= 0.0f) alpha = 0.0f; float ialpha = 1.0f - alpha; - __DECL_ALIGNED(16) float tmp_v[samples * 2]; // 2ch stereo - __DECL_ALIGNED(16) float tmp_h[samples * 2]; + __DECL_ALIGNED(16) float tmp_v[samples * 2 + 4]; // 2ch stereo + __DECL_ALIGNED(16) float tmp_h[samples * 2 + 4]; for(int i = 0; i < (samples * 2); i++) { tmp_h[i] = (float)(src[i]); diff --git a/source/src/common.h b/source/src/common.h index a6dfd1c94..2c33599fa 100644 --- a/source/src/common.h +++ b/source/src/common.h @@ -119,6 +119,7 @@ #include #ifdef _MSC_VER #include +#include #include #else #include @@ -274,7 +275,9 @@ typedef unsigned int UINT; #endif #endif - +#if /*!defined(_WIN32) || */!defined(SOCKET) + typedef uintptr_t SOCKET; +#endif typedef union { struct { #ifdef __BIG_ENDIAN__ @@ -295,24 +298,24 @@ typedef union { uint16_t w; int16_t sw; - inline void read_2bytes_le_from(uint8_t *t) + inline void __FASTCALL read_2bytes_le_from(uint8_t *t) { b.l = t[0]; b.h = t[1]; } - inline void write_2bytes_le_to(uint8_t *t) + inline void __FASTCALL write_2bytes_le_to(uint8_t *t) { t[0] = b.l; t[1] = b.h; } - inline void read_2bytes_be_from(uint8_t *t) + inline void __FASTCALL read_2bytes_be_from(uint8_t *t) { b.h = t[0]; b.l = t[1]; } - inline void write_2bytes_be_to(uint8_t *t) + inline void __FASTCALL write_2bytes_be_to(uint8_t *t) { t[0] = b.h; t[1] = b.l; } - inline void set_2bytes_be_from(uint16_t n) + inline void __FASTCALL set_2bytes_be_from(uint16_t n) { union { uint16_t w; @@ -323,7 +326,7 @@ typedef union { bigv.w = n; b.l = bigv.b.l; b.h = bigv.b.h; } - inline void set_2bytes_le_from(uint16_t n) + inline void __FASTCALL set_2bytes_le_from(uint16_t n) { union { uint16_t w; @@ -334,7 +337,7 @@ typedef union { littlev.w = n; b.l = littlev.b.l; b.h = littlev.b.h; } - inline uint16_t get_2bytes_be_to() + inline uint16_t __FASTCALL get_2bytes_be_to() { union { uint16_t w; @@ -345,7 +348,7 @@ typedef union { bigv.b.l = b.l; bigv.b.h = b.h; return bigv.w; } - inline uint16_t get_2bytes_le_to() + inline uint16_t __FASTCALL get_2bytes_le_to() { union { uint16_t w; @@ -399,40 +402,40 @@ typedef union { int32_t sd; float f; // single float - inline void read_2bytes_le_from(uint8_t *t) + inline void __FASTCALL read_2bytes_le_from(uint8_t *t) { b.l = t[0]; b.h = t[1]; b.h2 = b.h3 = 0; } - inline void write_2bytes_le_to(uint8_t *t) + inline void __FASTCALL write_2bytes_le_to(uint8_t *t) { t[0] = b.l; t[1] = b.h; } - inline void read_2bytes_be_from(uint8_t *t) + inline void __FASTCALL read_2bytes_be_from(uint8_t *t) { b.h3 = b.h2 = 0; b.h = t[0]; b.l = t[1]; } - inline void write_2bytes_be_to(uint8_t *t) + inline void __FASTCALL write_2bytes_be_to(uint8_t *t) { t[0] = b.h; t[1] = b.l; } - inline void read_4bytes_le_from(uint8_t *t) + inline void __FASTCALL read_4bytes_le_from(uint8_t *t) { b.l = t[0]; b.h = t[1]; b.h2 = t[2]; b.h3 = t[3]; } - inline void write_4bytes_le_to(uint8_t *t) + inline void __FASTCALL write_4bytes_le_to(uint8_t *t) { t[0] = b.l; t[1] = b.h; t[2] = b.h2; t[3] = b.h3; } - inline void read_4bytes_be_from(uint8_t *t) + inline void __FASTCALL read_4bytes_be_from(uint8_t *t) { b.h3 = t[0]; b.h2 = t[1]; b.h = t[2]; b.l = t[3]; } - inline void write_4bytes_be_to(uint8_t *t) + inline void __FASTCALL write_4bytes_be_to(uint8_t *t) { t[0] = b.h3; t[1] = b.h2; t[2] = b.h; t[3] = b.l; } - inline void set_2bytes_be_from(uint16_t n) + inline void __FASTCALL set_2bytes_be_from(uint16_t n) { union { uint16_t w; @@ -444,7 +447,7 @@ typedef union { b.l = bigv.b.l; b.h = bigv.b.h; b.h2 = 0; b.h3 = 0; } - inline void set_2bytes_le_from(uint16_t n) + inline void __FASTCALL set_2bytes_le_from(uint16_t n) { union { uint16_t w; @@ -456,7 +459,7 @@ typedef union { b.l = littlev.b.l; b.h = littlev.b.h; b.h2 = 0; b.h3 = 0; } - inline uint16_t get_2bytes_be_to() + inline uint16_t __FASTCALL get_2bytes_be_to() { union { uint16_t w; @@ -467,7 +470,7 @@ typedef union { bigv.b.l = b.l; bigv.b.h = b.h; return bigv.w; } - inline uint16_t get_2bytes_le_to() + inline uint16_t __FASTCALL get_2bytes_le_to() { union { uint16_t w; @@ -479,7 +482,7 @@ typedef union { return littlev.w; } - inline void set_4bytes_be_from(uint32_t n) + inline void __FASTCALL set_4bytes_be_from(uint32_t n) { union { uint32_t dw; @@ -490,7 +493,7 @@ typedef union { bigv.dw = n; b.l = bigv.b.l; b.h = bigv.b.h; b.h2 = bigv.b.h2; b.h3 = bigv.b.h3; } - inline void set_4bytes_le_from(uint32_t n) + inline void __FASTCALL set_4bytes_le_from(uint32_t n) { union { uint32_t dw; @@ -501,7 +504,7 @@ typedef union { littlev.dw = n; b.l = littlev.b.l; b.h = littlev.b.h; b.h2 = littlev.b.h2; b.h3 = littlev.b.h3; } - inline uint32_t get_4bytes_be_to() + inline uint32_t __FASTCALL get_4bytes_be_to() { union { uint32_t dw; @@ -512,7 +515,7 @@ typedef union { bigv.b.l = b.l; bigv.b.h = b.h; bigv.b.h2 = b.h2; bigv.b.h3 = b.h3; return bigv.dw; } - inline uint32_t get_4bytes_le_to() + inline uint32_t __FASTCALL get_4bytes_le_to() { union { uint32_t dw; @@ -593,65 +596,65 @@ typedef union { uint64_t q; int64_t sq; double df; // double float - inline void read_2bytes_le_from(uint8_t *t) + inline void __FASTCALL read_2bytes_le_from(uint8_t *t) { b.l = t[0]; b.h = t[1]; b.h2 = b.h3 = 0; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline void write_2bytes_le_to(uint8_t *t) + inline void __FASTCALL write_2bytes_le_to(uint8_t *t) { t[0] = b.l; t[1] = b.h; } - inline void read_2bytes_be_from(uint8_t *t) + inline void __FASTCALL read_2bytes_be_from(uint8_t *t) { b.h3 = b.h2 = 0; b.h = t[0]; b.l = t[1]; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline void write_2bytes_be_to(uint8_t *t) + inline void __FASTCALL write_2bytes_be_to(uint8_t *t) { t[0] = b.h; t[1] = b.l; } - inline void read_4bytes_le_from(uint8_t *t) + inline void __FASTCALL read_4bytes_le_from(uint8_t *t) { b.l = t[0]; b.h = t[1]; b.h2 = t[2]; b.h3 = t[3]; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline void write_4bytes_le_to(uint8_t *t) + inline void __FASTCALL write_4bytes_le_to(uint8_t *t) { t[0] = b.l; t[1] = b.h; t[2] = b.h2; t[3] = b.h3; } - inline void read_4bytes_be_from(uint8_t *t) + inline void __FASTCALL read_4bytes_be_from(uint8_t *t) { b.h3 = t[0]; b.h2 = t[1]; b.h = t[2]; b.l = t[3]; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline void write_4bytes_be_to(uint8_t *t) + inline void __FASTCALL write_4bytes_be_to(uint8_t *t) { t[0] = b.h3; t[1] = b.h2; t[2] = b.h; t[3] = b.l; } - inline void read_8bytes_le_from(uint8_t *t) + inline void __FASTCALL read_8bytes_le_from(uint8_t *t) { b.l = t[0]; b.h = t[1]; b.h2 = t[2]; b.h3 = t[3]; b.h4 = t[4]; b.h5 = t[5]; b.h6 = t[6]; b.h7 = t[7]; } - inline void write_8bytes_le_to(uint8_t *t) + inline void __FASTCALL write_8bytes_le_to(uint8_t *t) { t[0] = b.l; t[1] = b.h; t[2] = b.h2; t[3] = b.h3; t[4] = b.h4; t[5] = b.h5; t[6] = b.h6; t[7] = b.h7; } - inline void read_8bytes_be_from(uint8_t *t) + inline void __FASTCALL read_8bytes_be_from(uint8_t *t) { b.h7 = t[0]; b.h6 = t[1]; b.h5 = t[2]; b.h4 = t[3]; b.h3 = t[4]; b.h2 = t[5]; b.h = t[6]; b.l = t[7]; } - inline void write_8bytes_be_to(uint8_t *t) + inline void __FASTCALL write_8bytes_be_to(uint8_t *t) { t[0] = b.h7; t[1] = b.h6; t[2] = b.h5; t[3] = b.h4; t[4] = b.h3; t[5] = b.h2; t[6] = b.h; t[7] = b.l; } - inline void set_2bytes_be_from(uint16_t n) + inline void __FASTCALL set_2bytes_be_from(uint16_t n) { union { uint16_t w; @@ -664,7 +667,7 @@ typedef union { b.h2 = 0; b.h3 = 0; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline void set_2bytes_le_from(uint16_t n) + inline void __FASTCALL set_2bytes_le_from(uint16_t n) { union { uint16_t w; @@ -677,7 +680,7 @@ typedef union { b.h2 = 0; b.h3 = 0; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline uint16_t get_2bytes_be_to() + inline uint16_t __FASTCALL get_2bytes_be_to() { union { uint16_t w; @@ -688,7 +691,7 @@ typedef union { bigv.b.l = b.l; bigv.b.h = b.h; return bigv.w; } - inline uint16_t get_2bytes_le_to() + inline uint16_t __FASTCALL get_2bytes_le_to() { union { uint16_t w; @@ -700,7 +703,7 @@ typedef union { return littlev.w; } - inline void set_4bytes_be_from(uint32_t n) + inline void __FASTCALL set_4bytes_be_from(uint32_t n) { union { uint32_t dw; @@ -712,7 +715,7 @@ typedef union { b.l = bigv.b.l; b.h = bigv.b.h; b.h2 = bigv.b.h2; b.h3 = bigv.b.h3; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline void set_4bytes_le_from(uint32_t n) + inline void __FASTCALL set_4bytes_le_from(uint32_t n) { union { uint32_t dw; @@ -724,7 +727,7 @@ typedef union { b.l = littlev.b.l; b.h = littlev.b.h; b.h2 = littlev.b.h2; b.h3 = littlev.b.h3; b.h4 = 0; b.h5 = 0; b.h6 = 0; b.h7 = 0; } - inline uint32_t get_4bytes_be_to() + inline uint32_t __FASTCALL get_4bytes_be_to() { union { uint32_t dw; @@ -735,7 +738,7 @@ typedef union { bigv.b.l = b.l; bigv.b.h = b.h; bigv.b.h2 = b.h2; bigv.b.h3 = b.h3; return bigv.dw; } - inline uint32_t get_4bytes_le_to() + inline uint32_t __FASTCALL get_4bytes_le_to() { union { uint32_t dw; @@ -747,7 +750,7 @@ typedef union { return littlev.dw; } - inline void set_8bytes_be_from(uint64_t n) + inline void __FASTCALL set_8bytes_be_from(uint64_t n) { union { uint64_t qw; @@ -759,7 +762,7 @@ typedef union { b.l = bigv.b.l; b.h = bigv.b.h; b.h2 = bigv.b.h2; b.h3 = bigv.b.h3; b.h4 = bigv.b.h4; b.h5 = bigv.b.h5; b.h6 = bigv.b.h6; b.h7 = bigv.b.h7; } - inline void set_8bytes_le_from(uint64_t n) + inline void __FASTCALL set_8bytes_le_from(uint64_t n) { union { uint64_t qw; @@ -771,7 +774,7 @@ typedef union { b.l = littlev.b.l; b.h = littlev.b.h; b.h2 = littlev.b.h2; b.h3 = littlev.b.h3; b.h4 = littlev.b.h4; b.h5 = littlev.b.h5; b.h6 = littlev.b.h6; b.h7 = littlev.b.h7; } - inline uint64_t get_8bytes_be_to() + inline uint64_t __FASTCALL get_8bytes_be_to() { union { uint64_t qw; @@ -783,7 +786,7 @@ typedef union { bigv.b.h4 = b.h4; bigv.b.h5 = b.h5; bigv.b.h6 = b.h6; bigv.b.h7 = b.h7; return bigv.qw; } - inline uint64_t get_8bytes_le_to() + inline uint64_t __FASTCALL get_8bytes_le_to() { union { uint64_t qw; @@ -984,7 +987,7 @@ uint16_t DLL_PREFIX EndianFromBig_WORD(uint16_t x); #define _RGB888 #endif -inline uint16_t swap_endian_u16(uint16_t n) +inline uint16_t __FASTCALL swap_endian_u16(uint16_t n) { pair16_t r1, r2; r1.w = n; @@ -1003,7 +1006,7 @@ inline uint16_t swap_endian_u16(uint16_t n) uint8_t DLL_PREFIX B_OF_COLOR(scrntype_t c); uint8_t DLL_PREFIX A_OF_COLOR(scrntype_t c); #if defined(_RGB565) -inline scrntype_t rgb555le_to_scrntype_t(uint16_t n) +inline scrntype_t __FASTCALL rgb555le_to_scrntype_t(uint16_t n) { #if !defined(__LITTLE_ENDIAN__) n = swap_endian_u16(n); @@ -1016,7 +1019,7 @@ inline scrntype_t rgb555le_to_scrntype_t(uint16_t n) return r; } #else // RGB555 -inline scrntype_t rgb555le_to_scrntype_t(uint16_t n) +inline scrntype_t __FASTCALL rgb555le_to_scrntype_t(uint16_t n) { #if !defined(__LITTLE_ENDIAN__) n = swap_endian_u16(n); @@ -1025,7 +1028,7 @@ inline scrntype_t rgb555le_to_scrntype_t(uint16_t n) } #endif -inline scrntype_t msb_to_mask_u16le(uint16_t n) +inline scrntype_t __FASTCALL msb_to_mask_u16le(uint16_t n) { // bit15: '0' = NOT TRANSPARENT // '1' = TRANSPARENT @@ -1036,7 +1039,7 @@ inline scrntype_t msb_to_mask_u16le(uint16_t n) return _n; } -inline scrntype_t msb_to_alpha_mask_u16le(uint16_t n) +inline scrntype_t __FASTCALL msb_to_alpha_mask_u16le(uint16_t n) { // bit15: '0' = NOT TRANSPARENT // '1' = TRANSPARENT @@ -1064,8 +1067,25 @@ inline scrntype_t msb_to_alpha_mask_u16le(uint16_t n) #define B_OF_COLOR(c) (((c) ) & 0xff) #define A_OF_COLOR(c) (((c) >> 24) & 0xff) #endif +// 20181104 K.O: +// Below routines aim to render common routine. + +#ifdef _MSC_VER + #define __DECL_ALIGNED(foo) __declspec(align(foo)) + #ifndef __builtin_assume_aligned + #define __builtin_assume_aligned(foo, a) foo + #endif +#elif defined(__GNUC__) + // C++ >= C++11 + #define __DECL_ALIGNED(foo) __attribute__((aligned(foo))) + //#define __DECL_ALIGNED(foo) alignas(foo) +#else + // ToDo + #define __builtin_assume_aligned(foo, a) foo + #define __DECL_ALIGNED(foo) +#endif -inline scrntype_t rgb555le_to_scrntype_t(uint16_t n) +inline scrntype_t __FASTCALL rgb555le_to_scrntype_t(uint16_t n) { scrntype_t r, g, b; #if defined(__LITTLE_ENDIAN__) @@ -1083,7 +1103,7 @@ inline scrntype_t rgb555le_to_scrntype_t(uint16_t n) #endif } -inline scrntype_t msb_to_mask_u16le(uint16_t n) +inline scrntype_t __FASTCALL msb_to_mask_u16le(uint16_t n) { // bit15: '0' = NOT TRANSPARENT // '1' = TRANSPARENT @@ -1096,7 +1116,7 @@ inline scrntype_t msb_to_mask_u16le(uint16_t n) return _n; } -inline scrntype_t msb_to_alpha_mask_u16le(uint16_t n) +inline scrntype_t __FASTCALL msb_to_alpha_mask_u16le(uint16_t n) { // bit15: '0' = NOT TRANSPARENT // '1' = TRANSPARENT @@ -1108,23 +1128,6 @@ inline scrntype_t msb_to_alpha_mask_u16le(uint16_t n) #endif return _n; } - -#endif - -// 20181104 K.O: -// Below routines aim to render common routine. - -#ifdef _MSC_VER - #define __DECL_ALIGNED(foo) __declspec(align(foo)) - #ifndef __builtin_assume_aligned - #define __builtin_assume_aligned(foo, a) foo - #endif -#elif defined(__GNUC__) - #define __DECL_ALIGNED(foo) __attribute__((aligned(foo))) -#else - // ToDo - #define __builtin_assume_aligned(foo, a) foo - #define __DECL_ALIGNED(foo) #endif // ToDo: for MSVC @@ -1385,7 +1388,7 @@ void DLL_PREFIX Convert8ColorsToByte_Line(_render_command_data_t *src, uint8_t * void DLL_PREFIX Convert2NColorsToByte_Line(_render_command_data_t *src, uint8_t *dst, int planes); void DLL_PREFIX Convert2NColorsToByte_LineZoom2(_render_command_data_t *src, uint8_t *dst, int planes); -inline uint64_t ExchangeEndianU64(uint64_t __in) +inline uint64_t __FASTCALL ExchangeEndianU64(uint64_t __in) { pair64_t __i, __o; __i.q = __in; @@ -1400,7 +1403,7 @@ inline uint64_t ExchangeEndianU64(uint64_t __in) return __o.q; } -inline int64_t ExchangeEndianS64(uint64_t __in) +inline int64_t __FASTCALL ExchangeEndianS64(uint64_t __in) { pair64_t __i, __o; __i.q = __in; @@ -1414,7 +1417,7 @@ inline int64_t ExchangeEndianS64(uint64_t __in) __o.b.l = __i.b.h7; return __o.sq; } -inline uint32_t ExchangeEndianU32(uint32_t __in) +inline uint32_t __FASTCALL ExchangeEndianU32(uint32_t __in) { pair32_t __i, __o; __i.d = __in; @@ -1425,7 +1428,7 @@ inline uint32_t ExchangeEndianU32(uint32_t __in) return __o.d; } -inline int32_t ExchangeEndianS32(uint32_t __in) +inline int32_t __FASTCALL ExchangeEndianS32(uint32_t __in) { pair32_t __i, __o; __i.d = __in; @@ -1436,7 +1439,7 @@ inline int32_t ExchangeEndianS32(uint32_t __in) return __o.sd; } -inline uint16_t ExchangeEndianU16(uint16_t __in) +inline uint16_t __FASTCALL ExchangeEndianU16(uint16_t __in) { pair16_t __i, __o; __i.u16 = __in; @@ -1445,7 +1448,7 @@ inline uint16_t ExchangeEndianU16(uint16_t __in) return __o.u16; } -inline int16_t ExchangeEndianS16(uint16_t __in) +inline int16_t __FASTCALL ExchangeEndianS16(uint16_t __in) { pair16_t __i, __o; __i.u16 = __in; @@ -1454,6 +1457,7 @@ inline int16_t ExchangeEndianS16(uint16_t __in) return __o.s16; } + // wav file header #pragma pack(1) typedef struct { @@ -1525,6 +1529,9 @@ const char *DLL_PREFIX tchar_to_char(const _TCHAR *ts); const _TCHAR *DLL_PREFIX wchar_to_tchar(const wchar_t *ws); const wchar_t *DLL_PREFIX tchar_to_wchar(const _TCHAR *ts); +// Convert Zenkaku KATAKANA/HIRAGANA/ALPHABET to Hankaku.Data must be UCS-4 encoding Unicode (UTF-32). +int DLL_PREFIX ucs4_kana_zenkaku_to_hankaku(const uint32_t in, uint32_t *buf, int bufchars); + // for disassedmbler uint32_t DLL_PREFIX get_relative_address_8bit(uint32_t base, uint32_t mask, int8_t offset); uint32_t DLL_PREFIX get_relative_address_16bit(uint32_t base, uint32_t mask, int16_t offset); @@ -1540,7 +1547,7 @@ uint32_t DLL_PREFIX calc_crc32(uint32_t seed, uint8_t data[], int size); uint16_t DLL_PREFIX jis_to_sjis(uint16_t jis); int DLL_PREFIX decibel_to_volume(int decibel); -int32_t DLL_PREFIX apply_volume(int32_t sample, int volume); +int32_t DLL_PREFIX __FASTCALL apply_volume(int32_t sample, int volume); // High pass filter and Low pass filter. void DLL_PREFIX calc_high_pass_filter(int32_t* dst, int32_t* src, int sample_freq, int hpf_freq, int samples, double quality = 1.0, bool is_add = true); @@ -1562,14 +1569,14 @@ void DLL_PREFIX calc_low_pass_filter(int32_t* dst, int32_t* src, int sample_freq typedef DLL_PREFIX struct cur_time_s { int year, month, day, day_of_week, hour, minute, second; bool initialized; - cur_time_s() + DLL_PREFIX cur_time_s() { initialized = false; } - void increment(); - void update_year(); - void update_day_of_week(); - bool process_state(void *f, bool loading); + void DLL_PREFIX increment(); + void DLL_PREFIX update_year(); + void DLL_PREFIX update_day_of_week(); + bool DLL_PREFIX process_state(void *f, bool loading); } cur_time_t; void DLL_PREFIX get_host_time(cur_time_t* cur_time); diff --git a/source/src/config.cpp b/source/src/config.cpp index f1b3c839e..8340642ee 100644 --- a/source/src/config.cpp +++ b/source/src/config.cpp @@ -21,14 +21,8 @@ extern CSP_Logger *csp_logger; #include #include -#include "common.h" +#include "vm/vm.h" #include "config.h" -#include "fileio.h" -#if defined(_USE_AGAR) -#include "agar_main.h" -#endif - -config_t config; #ifndef CONFIG_NAME #define CONFIG_NAME "conf" @@ -79,6 +73,8 @@ void initialize_config() #if defined(USE_MOUSE_TYPE) && defined(MOUSE_TYPE_DEFAULT) config.mouse_type = MOUSE_TYPE_DEFAULT; #endif + config.mouse_sensitivity_x = 1 << 12; // 1.0 + config.mouse_sensitivity_y = 1 << 12; // 1.0 #if defined(USE_JOYSTICK_TYPE) && defined(JOYSTICK_TYPE_DEFAULT) config.joystick_type = JOYSTICK_TYPE_DEFAULT; #endif @@ -112,6 +108,12 @@ void initialize_config() config.baud_high[drv] = true; } #endif + #ifdef USE_COMPACT_DISC + for(int drv = 0; drv < USE_COMPACT_DISC_TMP; drv++) { + config.swap_audio_byteorder[drv] = false; + } + #endif + config.compress_state = true; // screen @@ -148,6 +150,9 @@ void initialize_config() config.joy_to_key_buttons[0] = -('Z'); config.joy_to_key_buttons[1] = -('X'); #endif + #if defined(USE_VARIABLE_MEMORY) + config.current_ram_size = USE_VARIABLE_MEMORY; + #endif // debug config.special_debug_fdc = false; config.print_statistics = false; @@ -155,6 +160,7 @@ void initialize_config() // win32 #if defined(_WIN32) && !defined(_USE_QT) #ifndef ONE_BOARD_MICRO_COMPUTER +// config.use_d2d1 = true; config.use_d3d9 = true; #endif config.use_dinput = true; @@ -273,6 +279,9 @@ void load_config(const _TCHAR *config_path) #ifdef USE_PRINTER config.printer_type = MyGetPrivateProfileInt(_T("Control"), _T("PrinterType"), config.printer_type, config_path); #endif + #if defined(USE_VARIABLE_MEMORY) + config.current_ram_size = MyGetPrivateProfileInt(_T("Control"), _T("CurrentRAMSize"), config.current_ram_size, config_path); + #endif #ifdef USE_FLOPPY_DISK for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) { config.correct_disk_timing[drv] = MyGetPrivateProfileBool(_T("Control"), create_string(_T("CorrectDiskTiming%d"), drv + 1), config.correct_disk_timing[drv], config_path); @@ -393,6 +402,11 @@ void load_config(const _TCHAR *config_path) config.sound_noise_cmt = MyGetPrivateProfileBool(_T("Sound"), _T("NoiseCMT"), config.sound_noise_cmt, config_path);; config.sound_play_tape = MyGetPrivateProfileBool(_T("Sound"), _T("PlayTape"), config.sound_play_tape, config_path); #endif + #ifdef USE_COMPACT_DISC + for(int drv = 0; drv < USE_COMPACT_DISC; drv++) { + config.swap_audio_byteorder[drv] = MyGetPrivateProfileBool(_T("Sound"), create_string(_T("SwapCDByteOrder%d"), drv + 1), config.swap_audio_byteorder[drv], config_path); + } + #endif #ifdef USE_SOUND_VOLUME for(int i = 0; i < USE_SOUND_VOLUME; i++) { int tmp_l = MyGetPrivateProfileInt(_T("Sound"), create_string(_T("VolumeLeft%d"), i + 1), config.sound_volume_l[i], config_path); @@ -420,7 +434,6 @@ void load_config(const _TCHAR *config_path) MyGetPrivateProfileString(_T("Sound"), _T("YM2151GenDll"), config.mame2151_dll_path, config.mame2151_dll_path, _MAX_PATH, config_path); MyGetPrivateProfileString(_T("Sound"), _T("YM2608GenDll"), config.mame2608_dll_path, config.mame2608_dll_path, _MAX_PATH, config_path); #endif - // input #ifdef USE_JOYSTICK for(int i = 0; i < 4; i++) { @@ -438,6 +451,8 @@ void load_config(const _TCHAR *config_path) config.joy_to_key_buttons[i] = MyGetPrivateProfileInt(_T("Input"), create_string(_T("JoyToKeyButtons%d"), i + 1), config.joy_to_key_buttons[i], config_path); } #endif + config.mouse_sensitivity_x = MyGetPrivateProfileInt(_T("Control"), _T("MouseSensitivityX"), config.mouse_sensitivity_x, config_path); + config.mouse_sensitivity_y = MyGetPrivateProfileInt(_T("Control"), _T("MouseSensitivityY"), config.mouse_sensitivity_y, config_path); // debug #ifdef USE_FLOPPY_DISK config.special_debug_fdc = MyGetPrivateProfileInt(_T("Debug"), _T("SpecialDebugFDC"), config.special_debug_fdc, config_path); @@ -451,6 +466,7 @@ void load_config(const _TCHAR *config_path) // win32 #if defined(_WIN32) && !defined(_USE_QT) #ifndef ONE_BOARD_MICRO_COMPUTER + config.use_d2d1 = MyGetPrivateProfileBool(_T("Win32"), _T("UseDirect2D1"), config.use_d2d1, config_path); config.use_d3d9 = MyGetPrivateProfileBool(_T("Win32"), _T("UseDirect3D9"), config.use_d3d9, config_path); config.wait_vsync = MyGetPrivateProfileBool(_T("Win32"), _T("WaitVSync"), config.wait_vsync, config_path); #endif @@ -478,13 +494,6 @@ void load_config(const _TCHAR *config_path) if(config.rendering_type < 0) config.rendering_type = 0; if(config.rendering_type >= CONFIG_RENDER_TYPE_END) config.rendering_type = CONFIG_RENDER_TYPE_END - 1; - // Assigning joysticks. - for(i = 0; i < 16; i++) { - _TCHAR name[256]; - my_stprintf_s(name, 256, _T("AssignedJoystick"), i + 1); - MyGetPrivateProfileString(_T("Qt"), (const _TCHAR *)name, _T(""), - config.assigned_joystick_name[i], 256, config_path); - } // Extra UI config.swap_kanji_pause = MyGetPrivateProfileBool(_T("Qt"), _T("SwapKanjiPause"), config.swap_kanji_pause, config_path); @@ -497,57 +506,63 @@ void load_config(const _TCHAR *config_path) MyGetPrivateProfileString(_T("Qt"), _T("LogWindowFont"), _T("Sans"), config.logwindow_font, sizeof(config.logwindow_font) - 1, config_path); config.logwindow_width = MyGetPrivateProfileInt(_T("Qt"), _T("LogWindowWidth"), 800, config_path); config.logwindow_height = MyGetPrivateProfileInt(_T("Qt"), _T("LogWindowHeight"), 500, config_path); - - + // Assigning joysticks. + for(i = 0; i < 16; i++) { + _TCHAR name[256]; + my_stprintf_s(name, 255, _T("AssignedJoystick%d"), i + 1); + MyGetPrivateProfileString(_T("Qt"), (const _TCHAR *)name, _T(""), + config.assigned_joystick_name[i], 255, config_path); +// printf("%d->%s\n", i, config.assigned_joystick_name[i]); + } // Movie load/save. - config.video_width = MyGetPrivateProfileInt(_T("Qt"), _T("VideoWidth"), config.video_width, config_path); + config.video_width = MyGetPrivateProfileInt(_T("Qt"), _T("VideoWidth"), 640, config_path); if(config.video_width < 128) config.video_width = 128; - config.video_height = MyGetPrivateProfileInt(_T("Qt"), _T("VideoHeight"), config.video_height, config_path); + config.video_height = MyGetPrivateProfileInt(_T("Qt"), _T("VideoHeight"), 480, config_path); if(config.video_height < 80) config.video_height = 80; - config.video_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("VideoCodecType"), config.video_codec_type, config_path); + config.video_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("VideoCodecType"), 1, config_path); if(config.video_codec_type > 1) config.video_codec_type = 1; if(config.video_codec_type < 0) config.video_codec_type = 0; - config.audio_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("AudioCodecType"), config.audio_codec_type, config_path); + config.audio_codec_type = MyGetPrivateProfileInt(_T("Qt"), _T("AudioCodecType"), 0, config_path); if(config.video_codec_type > 2) config.audio_codec_type = 2; if(config.video_codec_type < 0) config.audio_codec_type = 0; - config.video_h264_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("H264Bitrate"), config.video_h264_bitrate, config_path); + config.video_h264_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("H264Bitrate"), 3500, config_path); if(config.video_h264_bitrate < 64) config.video_h264_bitrate = 64; - config.video_h264_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("H264BFrames"), config.video_h264_bframes, config_path); + config.video_h264_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("H264BFrames"), 4, config_path); if(config.video_h264_bframes < 0) config.video_h264_bframes = 0; if(config.video_h264_bframes > 10) config.video_h264_bframes = 10; - config.video_h264_b_adapt = MyGetPrivateProfileInt(_T("Qt"), _T("H264BAdapt"), config.video_h264_b_adapt, config_path); + config.video_h264_b_adapt = MyGetPrivateProfileInt(_T("Qt"), _T("H264BAdapt"), 2, config_path); if(config.video_h264_b_adapt < 0) config.video_h264_b_adapt = 0; if(config.video_h264_b_adapt > 2) config.video_h264_b_adapt = 2; - config.video_h264_subme = MyGetPrivateProfileInt(_T("Qt"), _T("H264Subme"), config.video_h264_subme, config_path); + config.video_h264_subme = MyGetPrivateProfileInt(_T("Qt"), _T("H264Subme"), 7, config_path); if(config.video_h264_subme < 0) config.video_h264_subme = 0; if(config.video_h264_subme > 11) config.video_h264_subme = 11; - config.video_h264_minq = MyGetPrivateProfileInt(_T("Qt"), _T("H264MinQ"), config.video_h264_minq, config_path); + config.video_h264_minq = MyGetPrivateProfileInt(_T("Qt"), _T("H264MinQ"), 15, config_path); if(config.video_h264_minq < 0) config.video_h264_minq = 0; if(config.video_h264_minq > 63) config.video_h264_minq = 63; - config.video_h264_maxq = MyGetPrivateProfileInt(_T("Qt"), _T("H264MaxQ"), config.video_h264_maxq, config_path); + config.video_h264_maxq = MyGetPrivateProfileInt(_T("Qt"), _T("H264MaxQ"), 28, config_path); if(config.video_h264_maxq < 0) config.video_h264_maxq = 0; if(config.video_h264_maxq > 63) config.video_h264_maxq = 63; - config.video_mpeg4_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4Bitrate"), config.video_mpeg4_bitrate, config_path); + config.video_mpeg4_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4Bitrate"), 1500, config_path); if(config.video_mpeg4_bitrate < 64) config.video_mpeg4_bitrate = 64; - config.video_mpeg4_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4BFrames"), config.video_mpeg4_bframes, config_path); + config.video_mpeg4_bframes = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4BFrames"), 2, config_path); if(config.video_mpeg4_bframes < 0) config.video_mpeg4_bframes = 0; if(config.video_mpeg4_bframes > 10) config.video_mpeg4_bframes = 10; - config.video_mpeg4_minq = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MinQ"), config.video_mpeg4_minq, config_path); + config.video_mpeg4_minq = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MinQ"), 1, config_path); if(config.video_mpeg4_minq < 1) config.video_mpeg4_minq = 1; if(config.video_mpeg4_minq > 31) config.video_mpeg4_minq = 31; - config.video_mpeg4_maxq = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MaxQ"), config.video_mpeg4_maxq, config_path); + config.video_mpeg4_maxq = MyGetPrivateProfileInt(_T("Qt"), _T("MPEG4MaxQ"), 15, config_path); if(config.video_mpeg4_maxq < 1) config.video_mpeg4_maxq = 1; if(config.video_mpeg4_maxq > 31) config.video_mpeg4_maxq = 31; if(config.video_mpeg4_maxq < config.video_mpeg4_minq) { @@ -557,15 +572,15 @@ void load_config(const _TCHAR *config_path) config.video_mpeg4_minq = n; } - config.video_threads = MyGetPrivateProfileInt(_T("Qt"), _T("VideoThreads"), config.video_threads, config_path); + config.video_threads = MyGetPrivateProfileInt(_T("Qt"), _T("VideoThreads"), 0, config_path); if(config.video_threads < 0) config.video_threads = 0; if(config.video_threads > 16) config.video_threads = 16; - config.audio_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("AudioBitrate"), config.audio_bitrate, config_path); + config.audio_bitrate = MyGetPrivateProfileInt(_T("Qt"), _T("AudioBitrate"), 224, config_path); if(config.audio_bitrate < 16) config.audio_bitrate = 16; if(config.audio_bitrate > 448) config.audio_bitrate = 448; - config.video_frame_rate = MyGetPrivateProfileInt(_T("Qt"), _T("VideoFramerate"), config.video_frame_rate, config_path); + config.video_frame_rate = MyGetPrivateProfileInt(_T("Qt"), _T("VideoFramerate"), 60, config_path); if(config.video_frame_rate < 15) config.video_frame_rate = 15; if(config.video_frame_rate > 75) config.video_frame_rate = 75; // Logging @@ -652,6 +667,9 @@ void save_config(const _TCHAR *config_path) #ifdef USE_PRINTER MyWritePrivateProfileInt(_T("Control"), _T("PrinterType"), config.printer_type, config_path); #endif + #if defined(USE_VARIABLE_MEMORY) + MyWritePrivateProfileInt(_T("Control"), _T("CurrentRAMSize"), config.current_ram_size, config_path); + #endif #ifdef USE_FLOPPY_DISK for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) { MyWritePrivateProfileBool(_T("Control"), create_string(_T("CorrectDiskTiming%d"), drv + 1), config.correct_disk_timing[drv], config_path); @@ -720,7 +738,9 @@ void save_config(const _TCHAR *config_path) for(int i = 0; i < MAX_HISTORY; i++) { MyWritePrivateProfileString(_T("RecentFiles"), create_string(_T("RecentCompactDiscPath%d_%d"), drv + 1, i + 1), config.recent_compact_disc_path[drv][i], config_path); } + } + #endif #ifdef USE_LASER_DISC MyWritePrivateProfileString(_T("RecentFiles"), _T("InitialLaserDiscDir"), config.initial_laser_disc_dir, config_path); @@ -774,6 +794,11 @@ void save_config(const _TCHAR *config_path) MyWritePrivateProfileBool(_T("Sound"), _T("NoiseCMT"), config.sound_noise_cmt, config_path); MyWritePrivateProfileBool(_T("Sound"), _T("PlayTape"), config.sound_play_tape, config_path); #endif + #ifdef USE_COMPACT_DISC + for(int drv = 0; drv < USE_COMPACT_DISC; drv++) { + MyWritePrivateProfileBool(_T("Sound"), create_string(_T("SwapCDByteOrder%d"), drv + 1), config.swap_audio_byteorder[drv], config_path); + } + #endif #ifdef USE_SOUND_VOLUME for(int i = 0; i < USE_SOUND_VOLUME; i++) { MyWritePrivateProfileInt(_T("Sound"), create_string(_T("VolumeLeft%d"), i + 1), config.sound_volume_l[i], config_path); @@ -799,6 +824,8 @@ void save_config(const _TCHAR *config_path) MyWritePrivateProfileInt(_T("Input"), create_string(_T("JoyToKeyButtons%d"), i + 1), config.joy_to_key_buttons[i], config_path); } #endif + MyWritePrivateProfileInt(_T("Control"), _T("MouseSensitivityX"), config.mouse_sensitivity_x, config_path); + MyWritePrivateProfileInt(_T("Control"), _T("MouseSensitivityY"), config.mouse_sensitivity_y, config_path); // debug #ifdef USE_FLOPPY_DISK @@ -814,6 +841,7 @@ void save_config(const _TCHAR *config_path) // win32 #if defined(_WIN32) && !defined(_USE_QT) #ifndef ONE_BOARD_MICRO_COMPUTER + MyWritePrivateProfileBool(_T("Win32"), _T("UseDirect2D1"), config.use_d2d1, config_path); MyWritePrivateProfileBool(_T("Win32"), _T("UseDirect3D9"), config.use_d3d9, config_path); MyWritePrivateProfileBool(_T("Win32"), _T("WaitVSync"), config.wait_vsync, config_path); #endif @@ -851,7 +879,7 @@ void save_config(const _TCHAR *config_path) for(i = 0; i < 16; i++) { _TCHAR name[256]; - my_stprintf_s(name, 256, _T("AssignedJoystick%d"), i + 1); + my_stprintf_s(name, 255, _T("AssignedJoystick%d"), i + 1); MyWritePrivateProfileString(_T("Qt"), (const _TCHAR *)name, config.assigned_joystick_name[i], config_path); } @@ -911,7 +939,7 @@ void save_config(const _TCHAR *config_path) #endif } -#define STATE_VERSION 6 +#define STATE_VERSION 7 bool process_config_state(void *f, bool loading) { @@ -920,47 +948,63 @@ bool process_config_state(void *f, bool loading) if(!state_fio->StateCheckUint32(STATE_VERSION)) { return false; } - #ifdef USE_BOOT_MODE + #if defined(USE_FIXED_CONFIG) || defined(USE_BOOT_MODE) state_fio->StateValue(config.boot_mode); #endif - #ifdef USE_CPU_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_CPU_TYPE) state_fio->StateValue(config.cpu_type); #endif - #ifdef USE_DIPSWITCH + #if defined(USE_FIXED_CONFIG) || defined(USE_DIPSWITCH) state_fio->StateValue(config.dipswitch); #endif - #ifdef USE_DEVICE_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_DEVICE_TYPE) state_fio->StateValue(config.device_type); #endif - #ifdef USE_DRIVE_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_DRIVE_TYPE) state_fio->StateValue(config.drive_type); #endif - #ifdef USE_KEYBOARD_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_KEYBOARD_TYPE) state_fio->StateValue(config.keyboard_type); #endif - #ifdef USE_MOUSE_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_MOUSE_TYPE) state_fio->StateValue(config.mouse_type); #endif - #ifdef USE_JOYSTICK_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_JOYSTICK_TYPE) state_fio->StateValue(config.joystick_type); #endif - #ifdef USE_SOUND_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_SOUND_TYPE) state_fio->StateValue(config.sound_type); #endif - #ifdef USE_MONITOR_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_MONITOR_TYPE) state_fio->StateValue(config.monitor_type); #endif - #ifdef USE_PRINTER_TYPE + #if defined(USE_FIXED_CONFIG) || defined(USE_PRINTER_TYPE) state_fio->StateValue(config.printer_type); #endif - #ifdef USE_FLOPPY_DISK - for(int drv = 0; drv < USE_FLOPPY_DISK; drv++) { + #if defined(USE_SHARED_DLL) || defined(USE_FLOPPY_DISK) + for(int drv = 0; drv < 16; drv++) { state_fio->StateValue(config.correct_disk_timing[drv]); state_fio->StateValue(config.ignore_disk_crc[drv]); } #endif state_fio->StateValue(config.sound_frequency); state_fio->StateValue(config.sound_latency); + + #if defined(USE_FIXED_CONFIG) || defined(USE_SCANLINE) + state_fio->StateValue(config.scan_line); + #endif + #if defined(USE_SHARED_DLL) || defined(USE_TAPE) + for(int i = 0; i < USE_TAPE_TMP; i++) { + state_fio->StateValue(config.wave_shaper[i]); + state_fio->StateValue(config.direct_load_mzt[i]); + state_fio->StateValue(config.baud_high[i]); + } + #endif + #if defined(USE_SHARED_DLL) || defined(USE_VARIABLE_MEMORY) + state_fio->StateValue(config.current_ram_size); + #endif + state_fio->StateValue(config.cpu_power); + return true; } diff --git a/source/src/config.h b/source/src/config.h index 8ef54447b..e1f61c646 100644 --- a/source/src/config.h +++ b/source/src/config.h @@ -10,7 +10,8 @@ #ifndef _CONFIG_H_ #define _CONFIG_H_ -#include "vm/vm.h" +#include "common.h" +#include "vm/vm_template.h" #include "fileio.h" #if defined(_USE_QT) #define USE_FIXED_CONFIG 1 @@ -98,10 +99,10 @@ enum { #endif #endif -void DLL_PREFIX initialize_config(); -void DLL_PREFIX load_config(const _TCHAR* config_path); -void DLL_PREFIX save_config(const _TCHAR* config_path); -bool DLL_PREFIX process_config_state(void *f, bool loading); +void initialize_config(); +void load_config(const _TCHAR* config_path); +void save_config(const _TCHAR* config_path); +bool process_config_state(void *f, bool loading); /* * 20160407 Ohta: @@ -130,10 +131,10 @@ typedef struct { int keyboard_type; #endif #if defined(USE_FIXED_CONFIG) || defined(USE_MOUSE_TYPE) - int mouse_type; + int mouse_type; /*!< Emulated type of mouse by VM */ #endif #if defined(USE_FIXED_CONFIG) || defined(USE_JOYSTICK_TYPE) - int joystick_type; + int joystick_type; /*!< Emulated type of joystick by VM */ #endif #if defined(USE_FIXED_CONFIG) || defined(USE_SOUND_TYPE) int sound_type; @@ -156,6 +157,9 @@ typedef struct { bool direct_load_mzt[USE_TAPE_TMP]; bool baud_high[USE_TAPE_TMP]; #endif + #if defined(USE_SHARED_DLL) || defined(USE_VARIABLE_MEMORY) + uint32_t current_ram_size; + #endif bool compress_state; int cpu_power; bool full_speed; @@ -185,6 +189,7 @@ typedef struct { #if defined(USE_SHARED_DLL) || defined(USE_COMPACT_DISC) _TCHAR initial_compact_disc_dir[_MAX_PATH]; _TCHAR recent_compact_disc_path[USE_COMPACT_DISC_TMP][MAX_HISTORY][_MAX_PATH]; + bool swap_audio_byteorder[USE_COMPACT_DISC_TMP]; #endif #if defined(USE_SHARED_DLL) || defined(USE_LASER_DISC) _TCHAR initial_laser_disc_dir[_MAX_PATH]; @@ -212,6 +217,8 @@ typedef struct { int filter_type; #endif + uint32_t mouse_sensitivity_x; /*!< SENSITIVITY of MOUSE , X Value * 2^12, limit is 2^16-1 */ + uint32_t mouse_sensitivity_y; /*!< SENSITIVITY of MOUSE , Y Value * 2^12, limit is 2^16 - 1 */ // NOTE: Belows contain STAGED CONFIGURATION. #if defined(_USE_QT) bool use_separate_thread_draw; @@ -301,6 +308,7 @@ typedef struct { bool use_direct_input; bool disable_dwm; + bool use_d2d1; bool use_d3d9; bool wait_vsync; bool use_dinput; @@ -347,7 +355,7 @@ typedef struct { } config_t; -extern config_t config; +extern config_t DLL_PREFIX_I config; #if defined(_USE_QT) # include diff --git a/source/src/config_dll.cpp b/source/src/config_dll.cpp new file mode 100644 index 000000000..f225db41c --- /dev/null +++ b/source/src/config_dll.cpp @@ -0,0 +1,24 @@ +/* + Note: This file is only for DLL. + Author : Kyuma.Ohta + Date : 2020.10.11 - + */ +#if defined(_USE_QT) +#include +#include +#include "fileio.h" +#include "csp_logger.h" +#include "qt_main.h" +# if defined(Q_OS_WIN) +# include +# endif +extern CSP_Logger *csp_logger; +#endif + +#include +#include +#include "common.h" +#include "config.h" +#include "fileio.h" + +config_t DLL_PREFIX config; diff --git a/source/src/debugger.cpp b/source/src/debugger.cpp index 1031b1523..1fa1c43ae 100644 --- a/source/src/debugger.cpp +++ b/source/src/debugger.cpp @@ -15,13 +15,23 @@ #include #include "vm/device.h" #include "vm/debugger.h" + #include "vm/vm.h" +#include "emu.h" #include "fileio.h" + #include #include #include #include #include + +#if defined(OSD_QT) +#include "qt/osd.h" +#else /* WIN32 */ +#include "win32/osd.h" +#endif + #ifdef USE_DEBUGGER static FILEIO* logfile = NULL; @@ -51,7 +61,7 @@ void my_printf(OSD *osd, const _TCHAR *format, ...) if(logfile != NULL && logfile->IsOpened()) { logfile->Fwrite(buffer, _tcslen(buffer) * sizeof(_TCHAR), 1); } - osd->write_console(buffer, _tcslen(buffer)); + osd->write_console(buffer, (unsigned int)_tcslen(buffer)); } void my_putch(OSD *osd, _TCHAR c) @@ -285,9 +295,11 @@ void* debugger_thread(void *lpx) helplist.push_back("O[{B,W,D}] - output port (byte,word,dword)"); helplist.push_back("R - show register(s)"); helplist.push_back("R - edit register"); + helplist.push_back("RH - show registers description"); helplist.push_back("S - search"); helplist.push_back("U [] - unassemble"); helplist.push_back("UT [ | ] - unassemble back trace"); + helplist.push_back("UCT [] - display call trace"); helplist.push_back("H - hexadd"); helplist.push_back("N - name"); helplist.push_back("L [] - load binary/hex/symbol file"); @@ -336,6 +348,7 @@ void* debugger_thread(void *lpx) complist.push_back("S "); complist.push_back("U [RANGE]"); complist.push_back("UT [STEPS [LOGGING_FILE]]"); + complist.push_back("UCT [STEPS]"); complist.push_back("H "); complist.push_back("N "); complist.push_back("L [RANGE]"); @@ -523,7 +536,7 @@ void* debugger_thread(void *lpx) } memcpy(command, cpu_debugger->history[index], sizeof(command)); my_printf(p->osd, _T("%s"), command); - enter_ptr = _tcslen(command); + enter_ptr = (int)_tcslen(command); } else { history_ptr = history_ptr_stored; } @@ -635,7 +648,7 @@ void* debugger_thread(void *lpx) uint32_t addr = my_hexatoi(target, params[1]) % target->get_debug_data_addr_space(); my_tcscpy_s(buffer, array_length(buffer), prev_command); if((token = my_tcstok_s(buffer, _T("\""), &context)) != NULL && (token = my_tcstok_s(NULL, _T("\""), &context)) != NULL) { - int len = _tcslen(token); + int len = (int)_tcslen(token); for(int i = 0; i < len; i++) { target->write_debug_data8(addr, token[i] & 0xff); addr = (addr + 1) % target->get_debug_data_addr_space(); @@ -768,6 +781,78 @@ void* debugger_thread(void *lpx) } else { my_printf(p->osd, _T("invalid parameter number\n")); } + } else if(_tcsicmp(params[0], _T("UCT")) == 0) { + if(target_debugger == NULL) { + my_printf(p->osd, _T("debugger is not attached to target device %s\n"), target->this_device_name); + + } else { + int steps = 1024; + int xsteps; + _TCHAR log_path[_MAX_PATH] = {0}; + FILEIO log_fio; + bool logging = false; + if(num > 1) { + xsteps = min((int)atoi(params[1]), MAX_CPU_TRACE - 1); + if(xsteps >= 1) steps = xsteps; + if(xsteps <= 0) steps = MAX_CPU_TRACE - 1; + if(num > 2) { + if(strlen(params[2]) > 0) { + my_tcscpy_s(log_path, _MAX_PATH - 1, my_absolute_path(params[2])); + } + if(log_fio.Fopen((const _TCHAR*)log_path, FILEIO_WRITE_APPEND_ASCII)) { // Failed to open + logging = true; + } + } + } + if(logging && log_fio.IsOpened()) { + _TCHAR timestr[512] = {0}; + struct tm *timedat; + time_t nowtime; + struct timeval tv; + + nowtime = time(NULL); + gettimeofday(&tv, NULL); + timedat = localtime(&nowtime); + strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", timedat); + log_fio.Fprintf("**** Start of logging CALL TRACE %d steps for %s at %s.%06ld ****\n\n", steps, target->this_device_name, timestr, tv.tv_usec); + } + int begin_step = (target_debugger->cpu_trace_call_ptr - steps) & (MAX_CPU_TRACE - 1); + int max_step = target_debugger->cpu_trace_call_ptr & (MAX_CPU_TRACE - 1); + int steps_left = steps; + for(int i = begin_step; i != max_step; i = ((i + 1) & (MAX_CPU_TRACE - 1)) ) { + int index = i; + + if(!(target_debugger->cpu_trace[index] & ~target->get_debug_prog_addr_mask())) { + int len = 0; + bool hit = target->debug_rewind_call_trace( + target_debugger->cpu_trace_call[i] & target->get_debug_prog_addr_mask(), + len, + buffer, + array_length(buffer), + target_debugger->cpu_trace_call_type[i] + ); + if(hit) { + const _TCHAR *name = my_get_symbol(target, target_debugger->cpu_trace[index] & target->get_debug_prog_addr_mask()); + if(name != NULL) { + my_printf(p->osd, "%s (%s)", buffer, name); + if(logging && log_fio.IsOpened()) { + log_fio.Fprintf("%s (%s)", buffer, name); + } + } else { + my_printf(p->osd, "%s", buffer); + if(logging && log_fio.IsOpened()) { + log_fio.Fprintf("%s ", buffer); + } + } + } + } + steps_left--; + if(steps_left <= 0) break; + } + if(logging && log_fio.IsOpened()) { + log_fio.Fclose(); + } + } } else if(_tcsicmp(params[0], _T("UT")) == 0) { if(target_debugger == NULL) { my_printf(p->osd, _T("debugger is not attached to target device %s\n"), target->this_device_name); @@ -847,7 +932,6 @@ void* debugger_thread(void *lpx) } } int index = i; - if(!(target_debugger->cpu_trace[index] & ~target->get_debug_prog_addr_mask())) { const _TCHAR *name = my_get_symbol(target, target_debugger->cpu_trace[index] & target->get_debug_prog_addr_mask()); int len = target->debug_dasm_with_userdata(target_debugger->cpu_trace[index] & target->get_debug_prog_addr_mask(), buffer, array_length(buffer), target_debugger->cpu_trace_userdata[index]); @@ -890,7 +974,6 @@ void* debugger_thread(void *lpx) steps_left--; if(steps_left <= 0) break; } - } } if(log_fio != NULL) { @@ -1588,7 +1671,11 @@ void* debugger_thread(void *lpx) } } else if(_tcsicmp(params[0], _T("!!")) == 0) { // do nothing - } else if(_tcsicmp(params[0], _T("?")) == 0) { + } else if(_tcsicmp(params[0], _T("RH")) == 0) { + if(target->get_debug_regs_description(buffer, array_length(buffer))) { + my_printf(p->osd, _T("REGISTER DESCRIPTION:\n%s\n"), buffer); + } + } else if(_tcsicmp(params[0], _T("?")) == 0) { for(auto n = helplist.begin(); n != helplist.end(); ++n) { std::string tmps = *n; my_printf(p->osd, (const _TCHAR *)(tmps.c_str())); @@ -1655,7 +1742,7 @@ void EMU::open_debugger(int cpu_index) close_debugger(); if(vm->get_cpu(cpu_index) != NULL && vm->get_cpu(cpu_index)->get_debugger() != NULL) { debugger_thread_param.emu = this; - debugger_thread_param.osd = osd; + debugger_thread_param.osd = (OSD*)osd; debugger_thread_param.vm = vm; debugger_thread_param.cpu_index = cpu_index; debugger_thread_param.request_terminate = false; diff --git a/source/src/emu.cpp b/source/src/emu.cpp index 9c0fcada2..d4db6c059 100644 --- a/source/src/emu.cpp +++ b/source/src/emu.cpp @@ -10,6 +10,7 @@ #if defined(_USE_QT) #include #endif + #include "emu.h" #include "vm/vm.h" #include "fifo.h" @@ -37,11 +38,11 @@ extern CSP_Logger *csp_logger; #endif #if defined(_USE_QT) -EMU::EMU(class Ui_MainWindow *hwnd, GLDrawClass *hinst, USING_FLAGS *p) +EMU::EMU(class Ui_MainWindow *hwnd, GLDrawClass *hinst, USING_FLAGS *p) : EMU_TEMPLATE(hwnd, hinst, p) #elif defined(OSD_WIN32) -EMU::EMU(HWND hwnd, HINSTANCE hinst) +EMU::EMU(HWND hwnd, HINSTANCE hinst) : EMU_TEMPLATE(hwnd, hinst) #else -EMU::EMU() +EMU::EMU() : EMU() #endif { message_count = 0; @@ -271,6 +272,7 @@ void EMU::reset() #if defined(_USE_QT) osd->reset_vm_node(); osd->update_keyname_table(); + osd->reset_screen_buffer(); #endif int presented_rate; int presented_samples; @@ -307,8 +309,10 @@ void EMU::reset() } #ifdef USE_SPECIAL_RESET -void EMU::special_reset() +void EMU::special_reset(int num) { + if(num < 0) return; + if(num >= USE_SPECIAL_RESET) return; #ifdef USE_AUTO_KEY stop_auto_key(); config.romaji_to_kana = false; @@ -316,7 +320,7 @@ void EMU::special_reset() // reset virtual machine osd->lock_vm(); - vm->special_reset(); + vm->special_reset(num); osd->unlock_vm(); // restart recording #if !defined(_USE_QT) // Temporally @@ -394,6 +398,7 @@ void EMU::key_down(int code, bool extended, bool repeat) } else if(!is_auto_key_running()) #endif osd->key_down(code, extended, repeat); +// printf("KEY DOWN: %04X EXT=%d REPEAT=%d\n", code, extended, repeat); } void EMU::key_up(int code, bool extended) @@ -407,6 +412,7 @@ void EMU::key_up(int code, bool extended) } else if(!is_auto_key_running()) #endif osd->key_up(code, extended); +// printf("KEY UP: %04X EXT=%d\n", code, extended); } void EMU::key_char(char code) @@ -478,6 +484,8 @@ static const int auto_key_table_base[][2] = { // 0x200: kana // 0x400: alphabet // 0x800: ALPHABET + // 0x1000 : LOCK + // 0x2000 : UNLOCK {0x08, 0x000 | 0x08}, // BS {0x09, 0x000 | 0x09}, // Tab {0x0d, 0x000 | 0x0d}, // Enter @@ -625,136 +633,136 @@ static const int auto_key_table_base[][2] = { }; static const int auto_key_table_kana_base[][2] = { - {0xa1, 0x300 | 0xbe}, // '' - {0xa2, 0x300 | 0xdb}, // '' - {0xa3, 0x300 | 0xdd}, // '' - {0xa4, 0x300 | 0xbc}, // '' - {0xa5, 0x300 | 0xbf}, // '' - {0xa6, 0x300 | 0x30}, // '' - {0xa7, 0x300 | 0x33}, // '' - {0xa8, 0x300 | 0x45}, // '' - {0xa9, 0x300 | 0x34}, // '' - {0xaa, 0x300 | 0x35}, // '' - {0xab, 0x300 | 0x36}, // '' - {0xac, 0x300 | 0x37}, // '' - {0xad, 0x300 | 0x38}, // '' - {0xae, 0x300 | 0x39}, // '' - {0xaf, 0x300 | 0x5a}, // '' - {0xb0, 0x200 | 0xdc}, // '' - {0xb1, 0x200 | 0x33}, // '' - {0xb2, 0x200 | 0x45}, // '' - {0xb3, 0x200 | 0x34}, // '' - {0xb4, 0x200 | 0x35}, // '' - {0xb5, 0x200 | 0x36}, // '' - {0xb6, 0x200 | 0x54}, // '' - {0xb7, 0x200 | 0x47}, // '' - {0xb8, 0x200 | 0x48}, // '' - {0xb9, 0x200 | 0xba}, // '' - {0xba, 0x200 | 0x42}, // '' - {0xbb, 0x200 | 0x58}, // '' - {0xbc, 0x200 | 0x44}, // '' - {0xbd, 0x200 | 0x52}, // '' - {0xbe, 0x200 | 0x50}, // '' - {0xbf, 0x200 | 0x43}, // '' - {0xc0, 0x200 | 0x51}, // '' - {0xc1, 0x200 | 0x41}, // '' - {0xc2, 0x200 | 0x5a}, // '' - {0xc3, 0x200 | 0x57}, // '' - {0xc4, 0x200 | 0x53}, // '' - {0xc5, 0x200 | 0x55}, // '' - {0xc6, 0x200 | 0x49}, // '' - {0xc7, 0x200 | 0x31}, // '' - {0xc8, 0x200 | 0xbc}, // '' - {0xc9, 0x200 | 0x4b}, // '' - {0xca, 0x200 | 0x46}, // '' - {0xcb, 0x200 | 0x56}, // '' - {0xcc, 0x200 | 0x32}, // '' - {0xcd, 0x200 | 0xde}, // '' - {0xce, 0x200 | 0xbd}, // '' - {0xcf, 0x200 | 0x4a}, // '' - {0xd0, 0x200 | 0x4e}, // '' - {0xd1, 0x200 | 0xdd}, // '' - {0xd2, 0x200 | 0xbf}, // '' - {0xd3, 0x200 | 0x4d}, // '' - {0xd4, 0x200 | 0x37}, // '' - {0xd5, 0x200 | 0x38}, // '' - {0xd6, 0x200 | 0x39}, // '' - {0xd7, 0x200 | 0x4f}, // '' - {0xd8, 0x200 | 0x4c}, // '' - {0xd9, 0x200 | 0xbe}, // '' - {0xda, 0x200 | 0xbb}, // '' - {0xdb, 0x200 | 0xe2}, // '' - {0xdc, 0x200 | 0x30}, // '' - {0xdd, 0x200 | 0x59}, // '' - {0xde, 0x200 | 0xc0}, // '' - {0xdf, 0x200 | 0xdb}, // '' + {0xa1, 0x300 | 0xbe}, // '。' + {0xa2, 0x300 | 0xdb}, // '「' + {0xa3, 0x300 | 0xdd}, // '」' + {0xa4, 0x300 | 0xbc}, // '、' + {0xa5, 0x300 | 0xbf}, // '・' + {0xa6, 0x300 | 0x30}, // 'ヲ' + {0xa7, 0x300 | 0x33}, // 'ァ' + {0xa8, 0x300 | 0x45}, // 'ィ' + {0xa9, 0x300 | 0x34}, // 'ゥ' + {0xaa, 0x300 | 0x35}, // 'ェ' + {0xab, 0x300 | 0x36}, // 'ォ' + {0xac, 0x300 | 0x37}, // 'ャ' + {0xad, 0x300 | 0x38}, // 'ュ' + {0xae, 0x300 | 0x39}, // 'ョ' + {0xaf, 0x300 | 0x5a}, // 'ッ' + {0xb0, 0x200 | 0xdc}, // 'ー' + {0xb1, 0x200 | 0x33}, // 'ア' + {0xb2, 0x200 | 0x45}, // 'イ' + {0xb3, 0x200 | 0x34}, // 'ウ' + {0xb4, 0x200 | 0x35}, // 'エ' + {0xb5, 0x200 | 0x36}, // 'オ' + {0xb6, 0x200 | 0x54}, // 'カ' + {0xb7, 0x200 | 0x47}, // 'キ' + {0xb8, 0x200 | 0x48}, // 'ク' + {0xb9, 0x200 | 0xba}, // 'ケ' + {0xba, 0x200 | 0x42}, // 'コ' + {0xbb, 0x200 | 0x58}, // 'サ' + {0xbc, 0x200 | 0x44}, // 'シ' + {0xbd, 0x200 | 0x52}, // 'ス' + {0xbe, 0x200 | 0x50}, // 'セ' + {0xbf, 0x200 | 0x43}, // 'ソ' + {0xc0, 0x200 | 0x51}, // 'タ' + {0xc1, 0x200 | 0x41}, // 'チ' + {0xc2, 0x200 | 0x5a}, // 'ツ' + {0xc3, 0x200 | 0x57}, // 'テ' + {0xc4, 0x200 | 0x53}, // 'ト' + {0xc5, 0x200 | 0x55}, // 'ナ' + {0xc6, 0x200 | 0x49}, // 'ニ' + {0xc7, 0x200 | 0x31}, // 'ヌ' + {0xc8, 0x200 | 0xbc}, // 'ネ' + {0xc9, 0x200 | 0x4b}, // 'ノ' + {0xca, 0x200 | 0x46}, // 'ハ' + {0xcb, 0x200 | 0x56}, // 'ヒ' + {0xcc, 0x200 | 0x32}, // 'フ' + {0xcd, 0x200 | 0xde}, // 'ヘ' + {0xce, 0x200 | 0xbd}, // 'ホ' + {0xcf, 0x200 | 0x4a}, // 'マ' + {0xd0, 0x200 | 0x4e}, // 'ミ' + {0xd1, 0x200 | 0xdd}, // 'ム' + {0xd2, 0x200 | 0xbf}, // 'メ' + {0xd3, 0x200 | 0x4d}, // 'モ' + {0xd4, 0x200 | 0x37}, // 'ヤ' + {0xd5, 0x200 | 0x38}, // 'ユ' + {0xd6, 0x200 | 0x39}, // 'ヨ' + {0xd7, 0x200 | 0x4f}, // 'ラ' + {0xd8, 0x200 | 0x4c}, // 'リ' + {0xd9, 0x200 | 0xbe}, // 'ル' + {0xda, 0x200 | 0xbb}, // 'レ' + {0xdb, 0x200 | 0xe2}, // 'ロ' + {0xdc, 0x200 | 0x30}, // 'ワ' + {0xdd, 0x200 | 0x59}, // 'ン' + {0xde, 0x200 | 0xc0}, // '゙' + {0xdf, 0x200 | 0xdb}, // '゚' {-1, -1}, }; static const int auto_key_table_50on_base[][2] = { - {0xa1, 0x300 | 0xbf}, // '' - {0xa2, 0x300 | 0xdb}, // '' - {0xa3, 0x300 | 0xdd}, // '' - {0xa4, 0x300 | 0xbe}, // '' - {0xa5, 0x300 | 0xe2}, // '' - {0xa6, 0x200 | 0xbf}, // '' - {0xa7, 0x300 | 0x31}, // '' - {0xa8, 0x300 | 0x32}, // '' - {0xa9, 0x300 | 0x33}, // '' - {0xaa, 0x300 | 0x34}, // '' - {0xab, 0x300 | 0x35}, // '' - {0xac, 0x300 | 0x4e}, // '' - {0xad, 0x300 | 0x4d}, // '' - {0xae, 0x300 | 0xbc}, // '' - {0xaf, 0x300 | 0x43}, // '' - {0xb0, 0x300 | 0xba}, // '' - {0xb1, 0x200 | 0x31}, // '' - {0xb2, 0x200 | 0x32}, // '' - {0xb3, 0x200 | 0x33}, // '' - {0xb4, 0x200 | 0x34}, // '' - {0xb5, 0x200 | 0x35}, // '' - {0xb6, 0x200 | 0x51}, // '' - {0xb7, 0x200 | 0x57}, // '' - {0xb8, 0x200 | 0x45}, // '' - {0xb9, 0x200 | 0x52}, // '' - {0xba, 0x200 | 0x54}, // '' - {0xbb, 0x200 | 0x41}, // '' - {0xbc, 0x200 | 0x53}, // '' - {0xbd, 0x200 | 0x44}, // '' - {0xbe, 0x200 | 0x46}, // '' - {0xbf, 0x200 | 0x47}, // '' - {0xc0, 0x200 | 0x5a}, // '' - {0xc1, 0x200 | 0x58}, // '' - {0xc2, 0x200 | 0x43}, // '' - {0xc3, 0x200 | 0x56}, // '' - {0xc4, 0x200 | 0x42}, // '' - {0xc5, 0x200 | 0x36}, // '' - {0xc6, 0x200 | 0x37}, // '' - {0xc7, 0x200 | 0x38}, // '' - {0xc8, 0x200 | 0x39}, // '' - {0xc9, 0x200 | 0x30}, // '' - {0xca, 0x200 | 0x59}, // '' - {0xcb, 0x200 | 0x55}, // '' - {0xcc, 0x200 | 0x49}, // '' - {0xcd, 0x200 | 0x4f}, // '' - {0xce, 0x200 | 0x50}, // '' - {0xcf, 0x200 | 0x48}, // '' - {0xd0, 0x200 | 0x4a}, // '' - {0xd1, 0x200 | 0x4b}, // '' - {0xd2, 0x200 | 0x4c}, // '' - {0xd3, 0x200 | 0xbb}, // '' - {0xd4, 0x200 | 0x4e}, // '' - {0xd5, 0x200 | 0x4d}, // '' - {0xd6, 0x200 | 0xbc}, // '' - {0xd7, 0x200 | 0xbd}, // '' - {0xd8, 0x200 | 0xde}, // '' - {0xd9, 0x200 | 0xdc}, // '' - {0xda, 0x200 | 0xc0}, // '' - {0xdb, 0x200 | 0xdb}, // '' - {0xdc, 0x200 | 0xbe}, // '' - {0xdd, 0x200 | 0xe2}, // '' - {0xde, 0x200 | 0xba}, // '' - {0xdf, 0x200 | 0xdd}, // '' + {0xa1, 0x300 | 0xbf}, // '。' + {0xa2, 0x300 | 0xdb}, // '「' + {0xa3, 0x300 | 0xdd}, // '」' + {0xa4, 0x300 | 0xbe}, // '、' + {0xa5, 0x300 | 0xe2}, // '・' + {0xa6, 0x200 | 0xbf}, // 'ヲ' + {0xa7, 0x300 | 0x31}, // 'ァ' + {0xa8, 0x300 | 0x32}, // 'ィ' + {0xa9, 0x300 | 0x33}, // 'ゥ' + {0xaa, 0x300 | 0x34}, // 'ェ' + {0xab, 0x300 | 0x35}, // 'ォ' + {0xac, 0x300 | 0x4e}, // 'ャ' + {0xad, 0x300 | 0x4d}, // 'ュ' + {0xae, 0x300 | 0xbc}, // 'ョ' + {0xaf, 0x300 | 0x43}, // 'ッ' + {0xb0, 0x300 | 0xba}, // 'ー' + {0xb1, 0x200 | 0x31}, // 'ア' + {0xb2, 0x200 | 0x32}, // 'イ' + {0xb3, 0x200 | 0x33}, // 'ウ' + {0xb4, 0x200 | 0x34}, // 'エ' + {0xb5, 0x200 | 0x35}, // 'オ' + {0xb6, 0x200 | 0x51}, // 'カ' + {0xb7, 0x200 | 0x57}, // 'キ' + {0xb8, 0x200 | 0x45}, // 'ク' + {0xb9, 0x200 | 0x52}, // 'ケ' + {0xba, 0x200 | 0x54}, // 'コ' + {0xbb, 0x200 | 0x41}, // 'サ' + {0xbc, 0x200 | 0x53}, // 'シ' + {0xbd, 0x200 | 0x44}, // 'ス' + {0xbe, 0x200 | 0x46}, // 'セ' + {0xbf, 0x200 | 0x47}, // 'ソ' + {0xc0, 0x200 | 0x5a}, // 'タ' + {0xc1, 0x200 | 0x58}, // 'チ' + {0xc2, 0x200 | 0x43}, // 'ツ' + {0xc3, 0x200 | 0x56}, // 'テ' + {0xc4, 0x200 | 0x42}, // 'ト' + {0xc5, 0x200 | 0x36}, // 'ナ' + {0xc6, 0x200 | 0x37}, // 'ニ' + {0xc7, 0x200 | 0x38}, // 'ヌ' + {0xc8, 0x200 | 0x39}, // 'ネ' + {0xc9, 0x200 | 0x30}, // 'ノ' + {0xca, 0x200 | 0x59}, // 'ハ' + {0xcb, 0x200 | 0x55}, // 'ヒ' + {0xcc, 0x200 | 0x49}, // 'フ' + {0xcd, 0x200 | 0x4f}, // 'ヘ' + {0xce, 0x200 | 0x50}, // 'ホ' + {0xcf, 0x200 | 0x48}, // 'マ' + {0xd0, 0x200 | 0x4a}, // 'ミ' + {0xd1, 0x200 | 0x4b}, // 'ム' + {0xd2, 0x200 | 0x4c}, // 'メ' + {0xd3, 0x200 | 0xbb}, // 'モ' + {0xd4, 0x200 | 0x4e}, // 'ヤ' + {0xd5, 0x200 | 0x4d}, // 'ユ' + {0xd6, 0x200 | 0xbc}, // 'ヨ' + {0xd7, 0x200 | 0xbd}, // 'ラ' + {0xd8, 0x200 | 0xde}, // 'リ' + {0xd9, 0x200 | 0xdc}, // 'ル' + {0xda, 0x200 | 0xc0}, // 'レ' + {0xdb, 0x200 | 0xdb}, // 'ロ' + {0xdc, 0x200 | 0xbe}, // 'ワ' + {0xdd, 0x200 | 0xe2}, // 'ン' + {0xde, 0x200 | 0xba}, // '゙' + {0xdf, 0x200 | 0xdd}, // '゚' {-1, -1}, }; @@ -1038,6 +1046,13 @@ static const struct { {",", {0xa4, 0x00}}, {".", {0xa1, 0x00}}, {"/", {0xa5, 0x00}}, + // Pass through kana key codes. + {"\x0bc", {0xa4, 0x00}}, + {"\x0bd", {0xb0, 0x00}}, + {"\x0be", {0xa1, 0x00}}, + {"\x0bf", {0xa5, 0x00}}, + {"\x0db", {0xa2, 0x00}}, + {"\x0dd", {0xa3, 0x00}}, {"", {0x00}}, }; @@ -1112,6 +1127,7 @@ void EMU::set_auto_key_code(int code) { if(code == 0xf2 || (code = get_auto_key_code(code)) != 0) { if(code == 0x08 || code == 0x09 || code == 0x0d || code == 0x1b || code == 0x20 || code == 0xf2) { + // VK_BACK, VK_TAB, VK_RETURN, VK_ESCAPE, VK_SPACE, VK_OEM_COPY(Katakana/Hiragana) auto_key_buffer->write(code); #ifdef USE_AUTO_KEY_NUMPAD } else if(code >= 0x30 && code <= 0x39) { @@ -1159,6 +1175,59 @@ void EMU::set_auto_key_list(char *buf, int size) auto_key_buffer->write(0xf2); } prev_kana = kana; + // check handakuon + if(i < (size - 1)) { + bool dakuon_lock = false; + bool handakuon_lock = false; +#if defined(USE_TWO_STROKE_AUTOKEY_HANDAKUON) + if((buf[i + 1] & 0xff) == 0xdf) { // Is Handakuon + for(int jj = 0; ; jj++) { + if(kana_handakuon_keyboard_table[jj][0] == -1) break; + if(kana_handakuon_keyboard_table[jj][0] == (buf[i] & 0xff)) { // Found + handakuon_lock = true; + for(int l = 1; l < 6; l++) { + int n_code = kana_handakuon_keyboard_table[jj][l]; + if(n_code == 0x00) break; + if(n_code & (0x100 | 0x400 | 0x800)) { + auto_key_buffer->write((n_code & 0x30ff)| 0x100); + } else { + auto_key_buffer->write(n_code & 0x30ff); + } + } + break; + } + } + if(handakuon_lock) { + i++; + continue; + } + } +#endif +#if defined(USE_TWO_STROKE_AUTOKEY_DAKUON) + if((buf[i + 1] & 0xff) == 0xde) { // Is Dakuon + for(int jj = 0; ; jj++) { + if(kana_dakuon_keyboard_table[jj][0] == -1) break; + if(kana_dakuon_keyboard_table[jj][0] == (buf[i] & 0xff)) { // Found + dakuon_lock = true; + for(int l = 1; l < 6; l++) { + int n_code = kana_dakuon_keyboard_table[jj][l]; + if(n_code == 0x00) break; + if(n_code & (0x100 | 0x400 | 0x800)) { + auto_key_buffer->write((n_code & 0x30ff)| 0x100); + } else { + auto_key_buffer->write(n_code & 0x30ff); + } + } + break; + } + } + if(dakuon_lock) { + i++; + continue; + } + } +#endif + } #if defined(USE_AUTO_KEY_CAPS_LOCK) // use caps lock key to switch uppercase/lowercase of alphabet // USE_AUTO_KEY_CAPS_LOCK shows the caps lock key code @@ -1228,20 +1297,20 @@ void EMU::set_auto_key_char(char code) } else if(code == 0) { // end if(codes[3] == 'n') { - set_auto_key_code(0xdd); // '' + set_auto_key_code(0xdd); // 'ン' } set_auto_key_code(0xf2); memset(codes, 0, sizeof(codes)); } else if(code == 0x08 || code == 0x09 || code == 0x0d || code == 0x1b || code == 0x20) { if(codes[3] == 'n') { - set_auto_key_code(0xdd); // '' + set_auto_key_code(0xdd); // 'ン' } set_auto_key_code(code); memset(codes, 0, sizeof(codes)); #ifdef USE_AUTO_KEY_NUMPAD } else if(code >= 0x30 && code <= 0x39) { if(codes[3] == 'n') { - set_auto_key_code(0xdd); // '' + set_auto_key_code(0xdd); // 'ン' } set_auto_key_code(code); memset(codes, 0, sizeof(codes)); @@ -1250,24 +1319,25 @@ void EMU::set_auto_key_char(char code) codes[0] = codes[1]; codes[1] = codes[2]; codes[2] = codes[3]; - codes[3] = (code >= 'A' && code <= 'Z') ? ('a' + (code - 'A')) : code; + codes[3] = (code >= 'A' && code <= 'Z') ? ('a' + (code - 'A')) : code & 0xff; codes[4] = '\0'; if(codes[2] == 'n' && !is_vowel(codes[3])) { - set_auto_key_code(0xdd); // '' + set_auto_key_code(0xdd); // 'ン' if(codes[3] == 'n') { memset(codes, 0, sizeof(codes)); return; } } else if(codes[2] == codes[3] && is_consonant(codes[3])) { - set_auto_key_code(0xaf); // '' + set_auto_key_code(0xaf); // 'ッ' return; } for(int i = 0;; i++) { - int len = strlen(romaji_table[i].romaji), comp = -1; + size_t len = strlen(romaji_table[i].romaji); + int comp = -1; if(len == 0) { // end of table - if(!is_alphabet(codes[3])) { + if(!(is_alphabet(codes[3])) /*&& !((codes[3] >= 0x2c) && (codes[3] <= 0x2e)) && !((codes[3] == 0x5b) || (codes[3] == 0x5d))*/) { set_auto_key_code(codes[3]); memset(codes, 0, sizeof(codes)); } @@ -1286,6 +1356,53 @@ void EMU::set_auto_key_char(char code) if(!romaji_table[i].kana[j]) { break; } + if(j == 0) { + bool handakuon_found = false; + bool dakuon_found = false; +#if defined(USE_TWO_STROKE_AUTOKEY_HANDAKUON) + if(romaji_table[i].kana[1] == 0xdf) { + // HANDAKUON + for(int jj = 0;;jj++) { + if(kana_handakuon_keyboard_table[jj][0] == -1) break; + if(kana_handakuon_keyboard_table[jj][0] == romaji_table[i].kana[0]) { + for(int l = 1; l < 6; l++) { + if(kana_handakuon_keyboard_table[jj][l] == 0x00) break; + auto_key_buffer->write(kana_handakuon_keyboard_table[jj][l] & 0x31ff); + if(!is_auto_key_running()) { + start_auto_key(); + } + } + handakuon_found = true; + j += 1; + break; + } + } + } +#endif +#if defined(USE_TWO_STROKE_AUTOKEY_DAKUON) + if(romaji_table[i].kana[1] == 0xde) { + // DAKUON + for(int jj = 0;;jj++) { + if(kana_dakuon_keyboard_table[jj][0] == -1) break; + if(kana_dakuon_keyboard_table[jj][0] == romaji_table[i].kana[0]) { + for(int l = 1; l < 6; l++) { + if(kana_dakuon_keyboard_table[jj][l] == 0x00) break; + auto_key_buffer->write(kana_dakuon_keyboard_table[jj][l] & 0x31ff); + } + if(!is_auto_key_running()) { + start_auto_key(); + } + j += 1; + dakuon_found = true; + break; + } + } + } +#endif + if((handakuon_found) || (dakuon_found)) { + continue; + } + } set_auto_key_code(romaji_table[i].kana[j]); } memset(codes, 0, sizeof(codes)); @@ -1336,13 +1453,19 @@ void EMU::update_auto_key() } case 3 + USE_AUTO_KEY_SHIFT: if(auto_key_buffer && !auto_key_buffer->empty()) { - osd->key_down_native(auto_key_buffer->read_not_remove(0) & 0xff, false); + if(!(auto_key_buffer->read_not_remove(0) & 0x2000)) { + osd->key_down_native(auto_key_buffer->read_not_remove(0) & 0xff, false); +// printf("Press key: %04X\n", auto_key_buffer->read_not_remove(0)); + } } auto_key_phase++; break; case USE_AUTO_KEY + USE_AUTO_KEY_SHIFT: if(auto_key_buffer && !auto_key_buffer->empty()) { - osd->key_up_native(auto_key_buffer->read_not_remove(0) & 0xff); + if(!(auto_key_buffer->read_not_remove(0) & 0x1000)) { + osd->key_up_native(auto_key_buffer->read_not_remove(0) & 0xff); +// printf("Release key: %04X\n", auto_key_buffer->read_not_remove(0)); + } } auto_key_phase++; break; @@ -1774,7 +1897,7 @@ void EMU::write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path) // ---------------------------------------------------------------------------- #ifdef USE_SOCKET -int EMU::get_socket(int ch) +SOCKET EMU::get_socket(int ch) { return osd->get_socket(ch); } @@ -1888,7 +2011,7 @@ void EMU::release_debug_log() #endif #ifdef _DEBUG_LOG -static _TCHAR prev_buffer[1024] = {0}; +static _TCHAR prev_buffer[2048] = {0}; #endif void EMU::out_debug_log(const _TCHAR* format, ...) @@ -1897,22 +2020,24 @@ void EMU::out_debug_log(const _TCHAR* format, ...) #ifdef _DEBUG_LOG va_list ap; - _TCHAR buffer[1024]; + _TCHAR buffer[2048]; va_start(ap, format); - my_vstprintf_s(buffer, 1024, format, ap); + my_vstprintf_s(buffer, 2048, format, ap); va_end(ap); if(_tcscmp(prev_buffer, buffer) == 0) { return; } - my_tcscpy_s(prev_buffer, 1024, buffer); + my_tcscpy_s(prev_buffer, 2048, buffer); #if defined(_USE_QT) || defined(_USE_AGAR) || defined(_USE_SDL) - csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_EMU, "%s", buffer); + if((vm != NULL) && (csp_logger != NULL)) { + csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_EMU, vm->get_current_usec(), "%s", buffer); + } #else if(debug_log) { - _ftprintf(debug_log, _T("%s"), buffer); + _ftprintf(debug_log, _T("(%f uS) %s"), vm->get_current_usec(), buffer); static int size = 0; if((size += _tcslen(buffer)) > 0x8000000) { // 128MB fclose(debug_log); @@ -1936,6 +2061,7 @@ void EMU::force_out_debug_log(const _TCHAR* format, ...) my_tcscpy_s(prev_buffer, 1024, buffer); #if defined(_USE_QT) || defined(_USE_AGAR) || defined(_USE_SDL) + if(csp_logger == NULL) return; csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_EMU, "%s", buffer); #else if(debug_log) { @@ -2283,7 +2409,7 @@ bool EMU::is_cart_inserted(int drv) #endif #ifdef USE_FLOPPY_DISK -void EMU::create_bank_floppy_disk(const _TCHAR* file_path, uint8_t type) +bool EMU::create_blank_floppy_disk(const _TCHAR* file_path, uint8_t type) { /* type: 0x00 = 2D, 0x10 = 2DD, 0x20 = 2HD @@ -2308,6 +2434,7 @@ void EMU::create_bank_floppy_disk(const _TCHAR* file_path, uint8_t type) fio->Fclose(); } delete fio; + return true; } void EMU::open_floppy_disk(int drv, const _TCHAR* file_path, int bank) @@ -2316,7 +2443,7 @@ void EMU::open_floppy_disk(int drv, const _TCHAR* file_path, int bank) if(vm->is_floppy_disk_inserted(drv)) { vm->close_floppy_disk(drv); // wait 0.5sec - floppy_disk_status[drv].wait_count = (int)(vm->get_frame_rate() / 2); + floppy_disk_status[drv].wait_count = (int)(vm->get_frame_rate() / 1); #if USE_FLOPPY_DISK > 1 out_message(_T("FD%d: Ejected"), drv + BASE_FLOPPY_DISK_NUM); #else @@ -2348,6 +2475,15 @@ void EMU::close_floppy_disk(int drv) } } +bool EMU::is_floppy_disk_connected(int drv) +{ + if(drv < USE_FLOPPY_DISK) { + return vm->is_floppy_disk_connected(drv); + } else { + return false; + } +} + bool EMU::is_floppy_disk_inserted(int drv) { if(drv < USE_FLOPPY_DISK) { @@ -2426,6 +2562,15 @@ bool EMU::is_quick_disk_inserted(int drv) } } +bool EMU::is_quick_disk_connected(int drv) +{ + if(drv < USE_QUICK_DISK) { + return vm->is_quick_disk_connected(drv); + } else { + return false; + } +} + uint32_t EMU::is_quick_disk_accessed() { return vm->is_quick_disk_accessed(); @@ -2433,6 +2578,92 @@ uint32_t EMU::is_quick_disk_accessed() #endif #ifdef USE_HARD_DISK +bool EMU::create_blank_hard_disk(const _TCHAR* file_path, int sector_size, int sectors, int surfaces, int cylinders) +{ + if(check_file_extension(file_path, _T(".nhd"))) { + // T98-Next + const char sig_nhd[] = "T98HDDIMAGE.R0"; + typedef struct nhd_header_s { + char sig[16]; + char comment[256]; + int32_t header_size; // +272 + int32_t cylinders; // +276 + int16_t surfaces; // +280 + int16_t sectors; // +282 + int16_t sector_size; // +284 + uint8_t reserved[0xe2]; + } nhd_header_t; + nhd_header_t header; + + memset(&header, 0, sizeof(header)); + strcpy(header.sig, "T98HDDIMAGE.R0"); + header.header_size = sizeof(header); + header.cylinders = cylinders; + header.surfaces = surfaces; + header.sectors = sectors; + header.sector_size = sector_size; + + FILEIO *fio = new FILEIO(); + if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) { + fio->Fwrite(&header, sizeof(header), 1); + void *empty = calloc(sector_size, 1); +#if 0 + fio->Fwrite(empty, sector_size, sectors * surfaces * cylinders); +#else + for(int i = 0; i < sectors * surfaces * cylinders; i++) { + fio->Fwrite(empty, sector_size, 1); + } +#endif + free(empty); + fio->Fclose(); + } + delete fio; + return true; + } else if(check_file_extension(file_path, _T(".hdi"))) { + // ANEX86 + typedef struct hdi_header_s { + int32_t dummy; // + 0 + int32_t hdd_type; // + 4 + int32_t header_size; // + 8 + int32_t hdd_size; // +12 + int32_t sector_size; // +16 + int32_t sectors; // +20 + int32_t surfaces; // +24 + int32_t cylinders; // +28 + uint8_t padding[0x1000 - sizeof(int32_t) * 8]; + } hdi_header_t; + hdi_header_t header; + + memset(&header, 0, sizeof(header)); + header.hdd_type = 0; // ??? + header.header_size = sizeof(header); + header.hdd_size = sector_size * sectors * surfaces * cylinders; + header.sector_size = sector_size; + header.sectors = sectors; + header.surfaces = surfaces; + header.cylinders = cylinders; + + FILEIO *fio = new FILEIO(); + if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) { + fio->Fwrite(&header, sizeof(header), 1); + void *empty = calloc(sector_size, 1); +#if 0 + fio->Fwrite(empty, sector_size, sectors * surfaces * cylinders); +#else + for(int i = 0; i < sectors * surfaces * cylinders; i++) { + fio->Fwrite(empty, sector_size, 1); + } +#endif + free(empty); + fio->Fclose(); + } + delete fio; + return true; + } + // unknown extension + return false; +} + void EMU::open_hard_disk(int drv, const _TCHAR* file_path) { if(drv < USE_HARD_DISK) { @@ -2848,19 +3079,6 @@ void EMU::update_config() vm->update_config(); } -#ifdef OSD_QT - // New APIs -void EMU::load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size) -{ - osd->load_sound_file(id, name, data, dst_size); -} - -void EMU::free_sound_file(int id, int16_t **data) -{ - osd->free_sound_file(id, data); -} -#endif - // ---------------------------------------------------------------------------- // state @@ -3023,6 +3241,7 @@ bool EMU::load_state_tmp(const _TCHAR* file_path) # if defined(_USE_QT) osd->reset_vm_node(); osd->update_keyname_table(); + osd->reset_screen_buffer(); # endif vm->initialize_sound(sound_rate, sound_samples); #ifdef USE_SOUND_VOLUME diff --git a/source/src/emu.h b/source/src/emu.h index 3fae94a90..dddbb5efc 100644 --- a/source/src/emu.h +++ b/source/src/emu.h @@ -10,6 +10,8 @@ #ifndef _EMU_H_ #define _EMU_H_ +#include "./emu_template.h" +#include "vm/vm.h" // for debug //#define _DEBUG_LOG #ifdef _DEBUG_LOG @@ -21,25 +23,6 @@ // #define _IO_DEBUG_LOG #endif -#include -#include -#include "common.h" -#include "config.h" -//#include "vm/vm_template.h" - -#if defined(_USE_QT) -#include -#define OSD_QT -#elif defined(_USE_SDL) -#include -#define OSD_SDL -#elif defined(_WIN32) -#define OSD_WIN32 -#else -// oops! -#endif - - // OS dependent header files should be included in each osd.h // Please do not include them in emu.h @@ -63,65 +46,30 @@ class VM_TEMPLATE; class EMU; class FIFO; class FILEIO; -class OSD; - +/* #ifdef USE_DEBUGGER -#if defined(OSD_QT) -class CSP_Debugger; -class CSP_DebuggerThread; -#endif typedef struct { EMU *emu; OSD *osd; - VM_TEMPLATE *vm; + VM *vm; int cpu_index; bool running; bool request_terminate; } debugger_thread_t; #endif - -#if defined(OSD_QT) -class USING_FLAGS; -class GLDrawClass; -class EmuThreadClass; -class DrawThreadClass; -#endif - -class EMU +*/ +class EMU : public EMU_TEMPLATE { protected: VM* vm; - OSD* osd; private: - _TCHAR app_path[_MAX_PATH]; // debugger #ifdef USE_DEBUGGER void initialize_debugger(); void release_debugger(); #endif - - - // misc - int sound_frequency, sound_latency; - int sound_rate, sound_samples; -#ifdef USE_CPU_TYPE - int cpu_type; -#endif -#ifdef USE_DIPSWITCH - uint32_t dipswitch; -#endif -#ifdef USE_SOUND_TYPE - int sound_type; -#endif -#ifdef USE_PRINTER_TYPE - int printer_type; -#endif - bool now_suspended; // input #ifdef USE_AUTO_KEY - FIFO* auto_key_buffer; - int auto_key_phase, auto_key_shift; - bool shift_pressed; void initialize_auto_key(); void release_auto_key(); int get_auto_key_code(int code); @@ -129,43 +77,10 @@ class EMU void update_auto_key(); #endif #ifdef USE_JOYSTICK - uint32_t joy_status[4]; void update_joystick(); #endif // media - typedef struct { - _TCHAR path[_MAX_PATH]; - bool play; - int bank; - int wait_count; - } media_status_t; - -#ifdef USE_CART - media_status_t cart_status[USE_CART]; -#endif -#ifdef USE_FLOPPY_DISK - media_status_t floppy_disk_status[USE_FLOPPY_DISK]; -#endif -#ifdef USE_QUICK_DISK - media_status_t quick_disk_status[USE_QUICK_DISK]; -#endif -#ifdef USE_HARD_DISK - media_status_t hard_disk_status[USE_HARD_DISK]; -#endif -#ifdef USE_TAPE - media_status_t tape_status[USE_TAPE]; -#endif -#ifdef USE_COMPACT_DISC - media_status_t compact_disc_status[USE_COMPACT_DISC]; -#endif -#ifdef USE_LASER_DISC - media_status_t laser_disc_status[USE_LASER_DISC]; -#endif -#ifdef USE_BUBBLE - media_status_t bubble_casette_status[USE_BUBBLE]; -#endif - void initialize_media(); void update_media(); void restore_media(); @@ -188,7 +103,7 @@ class EMU #if defined(OSD_QT) EMU(class Ui_MainWindow *hwnd, GLDrawClass *hinst, USING_FLAGS *p); #elif defined(OSD_WIN32) - EMU(HWND hwnd, HINSTANCE hinst); + EMU(HWND hwnd, HINSTANCE hinst); #else EMU(); #endif @@ -201,7 +116,7 @@ class EMU { return (VM_TEMPLATE *)vm; } - OSD *get_osd() + OSD_BASE *get_osd() { return osd; } @@ -221,7 +136,7 @@ class EMU void reset(); #ifdef USE_SPECIAL_RESET - void special_reset(); + void special_reset(int num); #endif #ifdef USE_NOTIFY_POWER_OFF void notify_power_off(); @@ -234,9 +149,6 @@ class EMU bool is_vm_locked(); // input -#ifdef OSD_QT - void key_modifiers(uint32_t mod); -#endif void key_down(int code, bool extended, bool repeat); void key_up(int code, bool extended); void key_char(char code); @@ -362,7 +274,7 @@ class EMU #endif // socket #ifdef USE_SOCKET - int get_socket(int ch); + SOCKET get_socket(int ch); void notify_socket_connected(int ch); void notify_socket_disconnected(int ch); bool initialize_socket_tcp(int ch); @@ -380,30 +292,17 @@ class EMU #ifdef USE_DEBUGGER void open_debugger(int cpu_index); void close_debugger(); - bool now_debugging; - debugger_thread_t debugger_thread_param; bool is_debugger_enabled(int cpu_index); -#if defined(OSD_QT) - pthread_t debugger_thread_id; - CSP_Debugger *hDebugger; -#elif defined(OSD_WIN32) - HANDLE hDebuggerThread; -#else - int debugger_thread_id; -#endif #endif void start_waiting_in_debugger(); void finish_waiting_in_debugger(); void process_waiting_in_debugger(); - bool now_waiting_in_debugger; // debug log void out_debug_log(const _TCHAR* format, ...); void force_out_debug_log(const _TCHAR* format, ...); void out_message(const _TCHAR* format, ...); - int message_count; - _TCHAR message[1024]; // misc void sleep(uint32_t ms); @@ -412,20 +311,14 @@ class EMU #ifdef _DEBUG_LOG void initialize_debug_log(); void release_debug_log(); - FILE* debug_log; #endif // media #ifdef USE_FLOPPY_DISK - struct { - _TCHAR path[_MAX_PATH]; - _TCHAR disk_name[MAX_D88_BANKS][128]; // Convert to UTF8 - int bank_num; - int cur_bank; - } d88_file[USE_FLOPPY_DISK]; - void create_bank_floppy_disk(const _TCHAR* file_path, uint8_t type); + bool create_blank_floppy_disk(const _TCHAR* file_path, uint8_t type); void open_floppy_disk(int drv, const _TCHAR* file_path, int bank); void close_floppy_disk(int drv); + bool is_floppy_disk_connected(int drv); bool is_floppy_disk_inserted(int drv); void is_floppy_disk_protected(int drv, bool value); bool is_floppy_disk_protected(int drv); @@ -441,10 +334,12 @@ class EMU #ifdef USE_QUICK_DISK void open_quick_disk(int drv, const _TCHAR* file_path); void close_quick_disk(int drv); + bool is_quick_disk_connected(int drv); bool is_quick_disk_inserted(int drv); uint32_t is_quick_disk_accessed(); #endif #ifdef USE_HARD_DISK + bool create_blank_hard_disk(const _TCHAR* file_path, int sector_size, int sectors, int surfaces, int cylinders); void open_hard_disk(int drv, const _TCHAR* file_path); void close_hard_disk(int drv); bool is_hard_disk_inserted(int drv); @@ -483,12 +378,6 @@ class EMU void save_binary(int drv, const _TCHAR* file_path); #endif #ifdef USE_BUBBLE - struct { - _TCHAR path[_MAX_PATH]; - _TCHAR bubble_name[MAX_B77_BANKS][128]; // Convert to UTF8 - int bank_num; - int cur_bank; - } b77_file[USE_BUBBLE]; void open_bubble_casette(int drv, const _TCHAR* file_path, int bank); void close_bubble_casette(int drv); bool is_bubble_casette_inserted(int drv); @@ -507,11 +396,6 @@ class EMU void save_state(const _TCHAR* file_path); void load_state(const _TCHAR* file_path); #endif -#ifdef OSD_QT - // New APIs - void load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size); - void free_sound_file(int id, int16_t **data); -#endif }; #endif // _EMU_H_ diff --git a/source/src/emu_template.h b/source/src/emu_template.h new file mode 100644 index 000000000..095497a2e --- /dev/null +++ b/source/src/emu_template.h @@ -0,0 +1,475 @@ +/* + Skelton for retropc emulator + + Author : Kyuma.Ohta + Date : 2020.06.21 - + + [ interface for emulation i/f ] +*/ +#pragma once + +#include +#include +#include "common.h" +#include "config.h" + +//#include "vm/vm_template.h" +#if defined(_USE_QT) +#include +#define OSD_QT +#elif defined(_USE_SDL) +#include +#define OSD_SDL +#elif defined(_WIN32) +#define OSD_WIN32 +#else +// oops! +#endif + +#if defined(OSD_QT) +#include "qt/osd_base.h" +#endif + +class VM; +class VM_TEMPLATE; +class EMU; +class EMU_TEMPLATE; +class OSD; +class FIFO; +class FILEIO; + +#if defined(OSD_QT) +class CSP_Debugger; +class CSP_DebuggerThread; + +class USING_FLAGS; +class GLDrawClass; +class EmuThreadClass; +class DrawThreadClass; +#endif + +typedef struct { + EMU *emu; + OSD *osd; + VM *vm; + int cpu_index; + bool running; + bool request_terminate; +} debugger_thread_t; + +class DLL_PREFIX EMU_TEMPLATE { +protected: + OSD_BASE* osd; + + _TCHAR app_path[_MAX_PATH]; + // misc + int sound_frequency, sound_latency; + int sound_rate, sound_samples; + + int cpu_type; + uint32_t dipswitch; + int sound_type; + int printer_type; + + bool now_suspended; + // input + FIFO* auto_key_buffer; + int auto_key_phase, auto_key_shift; + bool shift_pressed; + + uint32_t joy_status[4]; + + typedef struct { + _TCHAR path[_MAX_PATH]; + bool play; + int bank; + int wait_count; + } media_status_t; + + media_status_t cart_status[16]; + media_status_t floppy_disk_status[16]; + media_status_t quick_disk_status[16]; + media_status_t hard_disk_status[16]; + media_status_t tape_status[16]; + media_status_t compact_disc_status[16]; + media_status_t laser_disc_status[16]; + media_status_t bubble_casette_status[16]; + +private: + uint8_t dummy_key_buffer[256]; + uint32_t dummy_joy_buffer[8]; + int dummy_mouse_buffer[4]; +public: + // ---------------------------------------- + // initialize + // --------------------------------------- +#if defined(OSD_QT) + EMU_TEMPLATE(class Ui_MainWindow *hwnd, GLDrawClass *hinst, USING_FLAGS *p) +#elif defined(OSD_WIN32) + EMU_TEMPLATE(HWND hwnd, HINSTANCE hinst) +#else + EMU_TEMPLATE() +#endif + { + memset(dummy_key_buffer, 0x00, sizeof(dummy_key_buffer)); + memset(dummy_joy_buffer, 0x00, sizeof(dummy_joy_buffer)); + memset(dummy_mouse_buffer, 0x00, sizeof(dummy_mouse_buffer)); + memset(message, 0x00, sizeof(message)); + + now_debugging = false; + memset(&debugger_thread_param, 0x00, sizeof(debugger_thread_t)); + + memset(app_path, 0x00, sizeof(app_path)); + + sound_frequency = 44100; + sound_latency = 100; + sound_rate = 44100; + sound_samples = 4410; + + cpu_type = 0; + dipswitch = 0x00000000; + sound_type = 0; + printer_type = 0; + + now_suspended = false; + + auto_key_buffer = NULL; + auto_key_phase = 0; + auto_key_shift = 0; + shift_pressed = false; + + memset(joy_status, 0x00, sizeof(joy_status)); + for(int i = 0; i < 16; i++) { + memset(&(cart_status[i]), 0x00, sizeof(media_status_t)); + memset(&(floppy_disk_status[i]), 0x00, sizeof(media_status_t)); + memset(&(quick_disk_status[i]), 0x00, sizeof(media_status_t)); + memset(&(hard_disk_status[i]), 0x00, sizeof(media_status_t)); + memset(&(tape_status[i]), 0x00, sizeof(media_status_t)); + memset(&(compact_disc_status[i]), 0x00, sizeof(media_status_t)); + memset(&(laser_disc_status[i]), 0x00, sizeof(media_status_t)); + memset(&(bubble_casette_status[i]), 0x00, sizeof(media_status_t)); + } + +#if defined(OSD_QT) + debugger_thread_id = (pthread_t)0; + hDebugger = NULL; +#elif defined(OSD_WIN32) + hDebuggerThread = (HANDLE)0; +#else + debugger_thread_id = 0; +#endif + + message_count = 0; + debug_log = NULL; + } + virtual ~EMU_TEMPLATE() {} + + // ---------------------------------------- + // for windows + // ---------------------------------------- + virtual VM_TEMPLATE *get_vm() { return NULL; } + virtual OSD_BASE *get_osd() { return NULL; } + +#ifdef OSD_QT + // qt dependent + virtual EmuThreadClass *get_parent_handler() { return NULL; } + virtual void set_parent_handler(EmuThreadClass *p, DrawThreadClass *q) {} + virtual void set_host_cpus(int v) {} + virtual int get_host_cpus() { return 1; } +#endif + virtual double get_frame_rate() { return 59.94; } + virtual int get_frame_interval() { return 1; } + virtual bool is_frame_skippable() { return false; } + virtual int run() { return 1; } + + virtual void reset() {} + virtual void special_reset(int num) {} + virtual void notify_power_off() {} + virtual void power_off() {} + virtual void suspend() {} + + // around locking VM, these are useful for multi-threaded environment. + virtual void lock_vm() {} + virtual void unlock_vm() {} + virtual void force_unlock_vm() {} + virtual bool is_vm_locked() { return false; } + + // input + // around Keyboard. + virtual void key_down(int code, bool extended, bool repeat) {} + virtual void key_up(int code, bool extended) {} + virtual void key_char(char code) {} + + virtual bool get_caps_locked() { return false; } + virtual bool get_kana_locked() { return false; } + virtual void key_lost_focus() {} + virtual void press_button(int num) {} + + // Auto Key + virtual void set_auto_key_list(char *buf, int size) {} + virtual void set_auto_key_char(char code) {} + virtual void start_auto_key() {} + virtual void stop_auto_key() {} + virtual bool is_auto_key_running() { return false; } + virtual FIFO* get_auto_key_buffer() { return NULL; } + // Mouse + virtual const uint8_t* get_key_buffer() { return dummy_key_buffer; } + virtual const uint32_t* get_joy_buffer() { return dummy_joy_buffer; } + virtual const int* get_mouse_buffer() { return dummy_mouse_buffer; } + virtual void enable_mouse() {} + virtual void disable_mouse() {} + virtual void toggle_mouse() {} + virtual bool is_mouse_enabled() { return false; } + + // screen + virtual double get_window_mode_power(int mode) { return 1.0; } + virtual int get_window_mode_width(int mode) { return 640; } + virtual int get_window_mode_height(int mode) { return 200; } + virtual void set_host_window_size(int window_width, int window_height, + bool window_mode) {} + virtual void set_vm_screen_size(int screen_width, int screen_height, + int window_width, int window_height, + int window_width_aspect, int window_height_aspect) {} + virtual void set_vm_screen_lines(int lines) {} + virtual int get_vm_window_width() { return 640; } + virtual int get_vm_window_height() { return 200; } + virtual int get_vm_window_width_aspect() { return 640; } + virtual int get_vm_window_height_aspect() { return 200; } + virtual bool is_screen_changed() { return true; } + virtual int draw_screen() { return 1; } + virtual scrntype_t* get_screen_buffer(int y) { return NULL;} + virtual void screen_skip_line(bool skip_line) {} + + // One-board-micro-computer + virtual void get_invalidated_rect(int *left, int *top, int *right, int *bottom) {} + virtual void reload_bitmap() {} + +#ifdef OSD_WIN32 + virtual void invalidate_screen() {} + virtual void update_screen(HDC hdc) {} +#endif + // Screen capture and recording.Will update API. + virtual void capture_screen() {} + virtual bool start_record_video(int fps) { return false;} + virtual void stop_record_video() {} + virtual bool is_video_recording() { return false; } + + // sound + virtual int get_sound_rate() { return 44100; } + virtual void mute_sound() {} + virtual void start_record_sound() {} + virtual void stop_record_sound() {} + virtual bool is_sound_recording() { return false; } + + // video device + virtual void get_video_buffer() {} + virtual void mute_video_dev(bool l, bool r) {} + + // Movie player. + virtual bool open_movie_file(const _TCHAR* file_path) { return false; } + virtual void close_movie_file() {} + virtual void play_movie() {} + virtual void stop_movie() {} + virtual void pause_movie() {} + virtual double get_movie_frame_rate() { return 29.97; } + virtual int get_movie_sound_rate() { return 44100; } + virtual void set_cur_movie_frame(int frame, bool relative) {} + virtual uint32_t get_cur_movie_frame() { return 0; } + + // Capturing video. + virtual int get_cur_capture_dev_index() { return 0; } + virtual int get_num_capture_devs() { return 0; } + virtual _TCHAR* get_capture_dev_name(int index) { return (_TCHAR*)_T("DUMMY"); } + virtual void open_capture_dev(int index, bool pin) {} + virtual void close_capture_dev() {} + virtual void show_capture_dev_filter() {} + virtual void show_capture_dev_pin() {} + virtual void show_capture_dev_source() {} + virtual void set_capture_dev_channel(int ch) {} + + // Printer + virtual void create_bitmap(bitmap_t *bitmap, int width, int height) {} + virtual void release_bitmap(bitmap_t *bitmap) {} + virtual void create_font(font_t *font, + const _TCHAR *family, + int width, int height, + int rotate, bool bold, bool italic) {} + virtual void release_font(font_t *font) {} + virtual void create_pen(pen_t *pen, int width, + uint8_t r, uint8_t g, uint8_t b) {} + virtual void release_pen(pen_t *pen) {} + virtual void clear_bitmap(bitmap_t *bitmap, + uint8_t r, uint8_t g, uint8_t b) {} + virtual int get_text_width(bitmap_t *bitmap, + font_t *font, const char *text) { return 16; } + virtual void draw_text_to_bitmap(bitmap_t *bitmap, font_t *font, + int x, int y, const char *text, + uint8_t r, uint8_t g, uint8_t b) {} + virtual void draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen, + int sx, int sy, int ex, int ey) {} + virtual void draw_rectangle_to_bitmap(bitmap_t *bitmap, + int x, int y, + int width, int height, + uint8_t r, uint8_t g, uint8_t b) {} + virtual void draw_point_to_bitmap(bitmap_t *bitmap, + int x, int y, + uint8_t r, uint8_t g, uint8_t b) {} + virtual void stretch_bitmap(bitmap_t *dest, int dest_x, int dest_y, + int dest_width, int dest_height, + bitmap_t *source, + int source_x, int source_y, int source_width, + int source_height) {} + virtual void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path) {} + + // socket + virtual SOCKET get_socket(int ch) { return (SOCKET)0; } + virtual void notify_socket_connected(int ch) {} + virtual void notify_socket_disconnected(int ch) {} + virtual bool initialize_socket_tcp(int ch) { return false; } + virtual bool initialize_socket_udp(int ch) { return false; } + + virtual bool connect_socket(int ch, uint32_t ipaddr, int port) {return false;} + virtual void disconnect_socket(int ch) {} + + virtual bool listen_socket(int ch) { return false; } + virtual void send_socket_data_tcp(int ch) {} + virtual void send_socket_data_udp(int ch, uint32_t ipaddr, int port) {} + + virtual void send_socket_data(int ch) {} + virtual void recv_socket_data(int ch) {} + + // debugger + virtual void open_debugger(int cpu_index) {} + virtual void close_debugger() {} + virtual bool is_debugger_enabled(int cpu_index) { return false; } + bool now_debugging; + debugger_thread_t debugger_thread_param; + +#if defined(OSD_QT) + pthread_t debugger_thread_id; + CSP_Debugger *hDebugger; +#elif defined(OSD_WIN32) + HANDLE hDebuggerThread; +#else + int debugger_thread_id; +#endif + + virtual void start_waiting_in_debugger() {} + virtual void finish_waiting_in_debugger() {} + virtual void process_waiting_in_debugger() {} + bool now_waiting_in_debugger; + + // debug log + virtual void out_debug_log(const _TCHAR* format, ...) {} + virtual void force_out_debug_log(const _TCHAR* format, ...) {} + + virtual void out_message(const _TCHAR* format, ...) {} + int message_count; + _TCHAR message[1024]; + + // misc + virtual void sleep(uint32_t ms) {} + + // debug log + virtual void initialize_debug_log() {} + virtual void release_debug_log() {} + FILE* debug_log; + + // media + // floppy disk + struct { + _TCHAR path[_MAX_PATH]; + _TCHAR disk_name[64][128]; // Convert to UTF8 + int bank_num; + int cur_bank; + } d88_file[16]; + virtual bool create_blank_floppy_disk(const _TCHAR* file_path, uint8_t type) { return false;} + virtual void open_floppy_disk(int drv, const _TCHAR* file_path, int bank) {} + virtual void close_floppy_disk(int drv) {} + virtual bool is_floppy_disk_connected(int drv) { return false;} + virtual bool is_floppy_disk_inserted(int drv) { return false;} + virtual void is_floppy_disk_protected(int drv, bool value) {} + virtual bool is_floppy_disk_protected(int drv) { return false;} + virtual uint32_t is_floppy_disk_accessed() { return 0x00000000; } + + // cartridge + virtual void open_cart(int drv, const _TCHAR* file_path) {} + virtual void close_cart(int drv) {} + virtual bool is_cart_inserted(int drv) { return false; } + + // quick disk + virtual void open_quick_disk(int drv, const _TCHAR* file_path) {} + virtual void close_quick_disk(int drv) {} + virtual bool is_quick_disk_connected(int drv) { return false; } + virtual bool is_quick_disk_inserted(int drv) { return false; } + virtual uint32_t is_quick_disk_accessed() { return 0x00000000; } + + // hard disk + virtual bool create_blank_hard_disk(const _TCHAR* file_path, + int sector_size, int sectors, + int surfaces, int cylinders) { return false; } + virtual void open_hard_disk(int drv, const _TCHAR* file_path) {} + virtual void close_hard_disk(int drv) {} + virtual bool is_hard_disk_inserted(int drv) { return false; } + virtual uint32_t is_hard_disk_accessed() { return 0x00000000; } + + // tape (CMT) + virtual void play_tape(int drv, const _TCHAR* file_path) {} + virtual void rec_tape(int drv, const _TCHAR* file_path) {} + virtual void close_tape(int drv) {} + virtual bool is_tape_inserted(int drv) { return false; } + virtual bool is_tape_playing(int drv) { return false; } + virtual bool is_tape_recording(int drv) { return false; } + virtual int get_tape_position(int drv) { return 0; } + virtual const _TCHAR* get_tape_message(int drv) { return _T(" "); } + virtual void push_play(int drv) {} + virtual void push_stop(int drv) {} + virtual void push_fast_forward(int drv) {} + virtual void push_fast_rewind(int drv) {} + virtual void push_apss_forward(int drv) {} + virtual void push_apss_rewind(int drv) {} + + // compact disc (CD) + virtual void open_compact_disc(int drv, const _TCHAR* file_path) {} + virtual void close_compact_disc(int drv) {} + virtual bool is_compact_disc_inserted(int drv) { return false; } + virtual uint32_t is_compact_disc_accessed() { return 0x00000000; } + + // laser disc (LD) + virtual void open_laser_disc(int drv, const _TCHAR* file_path) {} + virtual void close_laser_disc(int drv) {} + virtual bool is_laser_disc_inserted(int drv) { return false; } + virtual uint32_t is_laser_disc_accessed() { return 0x00000000; } + + // binary file (memory image) + virtual void load_binary(int drv, const _TCHAR* file_path) {} + virtual void save_binary(int drv, const _TCHAR* file_path) {} + + // bubble casette + struct { + _TCHAR path[_MAX_PATH]; + _TCHAR bubble_name[16][128]; // Convert to UTF8 + int bank_num; + int cur_bank; + } b77_file[16]; + virtual void open_bubble_casette(int drv, const _TCHAR* file_path, int bank) {} + virtual void close_bubble_casette(int drv) {} + virtual bool is_bubble_casette_inserted(int drv) { return false; } + virtual bool is_bubble_casette_protected(int drv) { return false; } + virtual void is_bubble_casette_protected(int drv, bool value) {} + + // LED device + virtual uint32_t get_led_status() { return 0x00000000; } + + // sound volume + virtual void set_sound_device_volume(int ch, int decibel_l, int decibel_r) {} + + // configure + virtual void update_config() {} + + // state + virtual void save_state(const _TCHAR* file_path) {} + virtual void load_state(const _TCHAR* file_path) {} + +}; + diff --git a/source/src/fifo.cpp b/source/src/fifo.cpp index 802e96e98..98fd0c9a3 100644 --- a/source/src/fifo.cpp +++ b/source/src/fifo.cpp @@ -131,11 +131,24 @@ int FIFO::count() return cnt; } +int FIFO::fifo_size() +{ + return size; +} + bool FIFO::full() { return (cnt == size); } +int FIFO::left() +{ + int val = cnt - size; + if(val < 0) val = 0; + if(val > size) val = size; + return val; +} + bool FIFO::empty() { return (cnt == 0); diff --git a/source/src/fifo.h b/source/src/fifo.h index fad118bf1..8da86c213 100644 --- a/source/src/fifo.h +++ b/source/src/fifo.h @@ -29,6 +29,8 @@ class DLL_PREFIX FIFO virtual int read_not_remove(int pt, bool *p_empty_warn = nullptr); virtual void write_not_push(int pt, int d, bool *p_fill_warn = nullptr); virtual int count(); + virtual int left(); + virtual int fifo_size(); virtual bool full(); virtual bool empty(); virtual bool is_fill_warn() { return fill_warn_flag; } diff --git a/source/src/qt/CMakeLists.txt b/source/src/qt/CMakeLists.txt index f98b97093..c8aab6f8b 100644 --- a/source/src/qt/CMakeLists.txt +++ b/source/src/qt/CMakeLists.txt @@ -1,72 +1,60 @@ message("* qt/osd") -SET(THIS_LIB_VERSION 2.22.1) +SET(THIS_LIB_VERSION 3.3.3) set(s_qt_osd_headers osd_base.h + osd_socket.h ) -#include(PrecompiledHeader) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_osd_headers_MOC ${s_qt_osd_headers}) -else() - QT4_WRAP_CPP(s_qt_osd_headers_MOC ${s_qt_osd_headers}) -endif() +QT5_WRAP_CPP(s_qt_osd_headers_MOC ${s_qt_osd_headers}) SET(s_qt_osd_srcs -# pch.cpp - osd_base.cpp - osd_screen.cpp - osd_console.cpp - osd_input.cpp - osd_printer.cpp - osd_socket.cpp - osd_sound.cpp - osd_video.cpp - ${s_qt_osd_headers_MOC} + osd_base.cpp + osd_screen.cpp + osd_console.cpp + osd_input.cpp + osd_printer.cpp + osd_socket.cpp + osd_sound.cpp + osd_video.cpp + qudpsocket2.cpp + qtcpsocket2.cpp + ${s_qt_osd_headers_MOC} ) add_definitions(-D__LIBOSD_VERSION=\"libCSPosd.${THIS_LIB_VERSION}\") -if(WIN32) -#add_library(qt_osd -# ${s_qt_osd_srcs} -# ${s_qt_osd_headers_MOC} -# ) -#set_property(TARGET qt_osd PROPERTY INTERPROCEDURAL_OPTIMIZATION True) include (GenerateExportHeader) - add_library(CSPosd SHARED - ${s_qt_osd_srcs} - ${s_qt_osd_headers_MOC} - ) +add_library(CSPosd SHARED + ${s_qt_osd_srcs} + ${s_qt_osd_headers_MOC} +) +set_std(CSPosd) + +if(WIN32) target_link_libraries(CSPosd PUBLIC - PRIVATE ${CMAKE_SOURCE_DIR}/../../build-cmake/bin-win32/libCSPemu_utils.dll.a -# INTERFACE ${CMAKE_SOURCE_DIR}/../../build-cmake/bin-win32/libCSPgui.dll.a -# ${CMAKE_SOURCE_DIR}/../../build-cmake/bin-win32/libCSPavio.dll.a - Qt5::Core - Qt5::Gui - Qt5::OpenGL - Qt5::Widgets - ${SDL2_LIBRARIES} - ) + CSPemu_utils + Qt5::Core + Qt5::Gui + Qt5::OpenGL + Qt5::Widgets + Qt5::Network + ${SDL2_LIBRARIES} + ) generate_export_header(CSPosd BASE_NAME CSPosd EXPORT_MACRO_NAME CSPosd_EXPORT EXPORT_FILE_NAME CSPosd_Export.h STATIC_DEFINE CSPgosd_BUILT_AS_STATIC ) - set_target_properties(CSPosd PROPERTIES - SOVERSION ${THIS_LIB_VERSION} - VERSION ${THIS_LIB_VERSION} - ) +set_target_properties(CSPosd PROPERTIES + SOVERSION ${THIS_LIB_VERSION} + VERSION ${THIS_LIB_VERSION} +) else() #if(USE_DEVICES_SHARED_LIB) - add_library(CSPosd SHARED - ${s_qt_osd_srcs} - ${s_qt_osd_headers_MOC} -# pch.cpp - ) # add_precompiled_header(CSPosd pch_list # SOURCE_CXX pch.cpp FORCEINCLUDE # ) @@ -74,6 +62,7 @@ else() Qt5::Core Qt5::Gui Qt5::Widgets + Qt5::Network ${SDL2_LIBRARIES} ) set_target_properties(CSPosd PROPERTIES diff --git a/source/src/qt/avio/CMakeLists.txt b/source/src/qt/avio/CMakeLists.txt index 08e5e609b..45acb5c83 100644 --- a/source/src/qt/avio/CMakeLists.txt +++ b/source/src/qt/avio/CMakeLists.txt @@ -1,6 +1,6 @@ message("* qt/avio") -SET(THIS_LIB_VERSION 2.11.1) +SET(THIS_LIB_VERSION 3.1.0) set(s_qt_avio_headers movie_saver.h movie_loader.h @@ -37,9 +37,8 @@ add_library(CSPavio SHARED target_link_libraries(CSPavio PUBLIC PRIVATE ${LIBAV_LIBRARIES} - ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPosd.dll.a -# ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPgui.dll.a - ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPemu_utils.dll.a + CSPosd + CSPemu_utils Qt5::Core Qt5::Gui Qt5::Widgets @@ -56,12 +55,14 @@ generate_export_header(CSPavio EXPORT_FILE_NAME CSPavio_Export.h STATIC_DEFINE CSPavio_BUILT_AS_STATIC ) + set_std(CSPavio) else() add_library(CSPavio SHARED ${s_qt_avio_srcs} ${s_qt_avio_headers_MOC} ) + set_std(CSPavio) target_link_libraries(CSPavio PUBLIC ${LIBAV_LIBRARIES} diff --git a/source/src/qt/avio/movie_loader.cpp b/source/src/qt/avio/movie_loader.cpp index b8be64203..9a459be5e 100644 --- a/source/src/qt/avio/movie_loader.cpp +++ b/source/src/qt/avio/movie_loader.cpp @@ -105,16 +105,16 @@ int MOVIE_LOADER::decode_video(AVCodecContext *dec_ctx, int *got_frame) if(got_frame != NULL) *got_frame = 0; ret = avcodec_send_packet(dec_ctx, &pkt); if (ret < 0) { - printf("0\n"); +// printf("0\n"); return ret; } /* read all the output frames (in general there may be any number of them */ ret = avcodec_receive_frame(dec_ctx, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { - printf("1\n"); +// printf("1\n"); return ret; } else if (ret < 0) { - printf("2\n"); +// printf("2\n"); return ret; } if(got_frame != NULL) *got_frame = 1; diff --git a/source/src/qt/avio/movie_saver_audio.cpp b/source/src/qt/avio/movie_saver_audio.cpp index f199691a9..9b4609564 100644 --- a/source/src/qt/avio/movie_saver_audio.cpp +++ b/source/src/qt/avio/movie_saver_audio.cpp @@ -128,7 +128,7 @@ bool MOVIE_SAVER::open_audio(void) #ifdef AVCODEC_UPPER_V56 ret = avcodec_parameters_from_context(ost->st->codecpar, c); if (ret < 0) { - fprintf(stderr, "Could not copy the stream parameters\n"); + p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_MOVIE_SAVER, "Could not copy the stream parameters\n"); return false; } #endif diff --git a/source/src/qt/avio/movie_saver_fileio.cpp b/source/src/qt/avio/movie_saver_fileio.cpp index 8d7272ce1..39dd1b5e1 100644 --- a/source/src/qt/avio/movie_saver_fileio.cpp +++ b/source/src/qt/avio/movie_saver_fileio.cpp @@ -259,7 +259,7 @@ bool MOVIE_SAVER::do_open_main() /* allocate the output media context */ avformat_alloc_output_context2(&oc, NULL, NULL, _filename.toLocal8Bit().constData()); if (!oc) { - printf("Could not reduce output format from file extension: using MPEG.\n"); +// printf("Could not reduce output format from file extension: using MPEG.\n"); avformat_alloc_output_context2(&oc, NULL, "mpeg", _filename.toLocal8Bit().constData()); } if (!oc) diff --git a/source/src/qt/avio/movie_saver_video.cpp b/source/src/qt/avio/movie_saver_video.cpp index f5b8340f6..b57a55e8c 100644 --- a/source/src/qt/avio/movie_saver_video.cpp +++ b/source/src/qt/avio/movie_saver_video.cpp @@ -122,7 +122,7 @@ void MOVIE_SAVER::setup_mpeg4(void *_codec) c->scenechange_threshold = 30; c->noise_reduction = 0; c->chromaoffset = 2; - c->b_strategy = 1; +// c->b_strategy = 1; c->b_sensitivity = 55; #endif #endif @@ -197,14 +197,14 @@ bool MOVIE_SAVER::open_video() //if (c->pix_fmt != AV_PIX_FMT_YUV420P) { ost->tmp_frame = (AVFrame *)alloc_picture(AV_PIX_FMT_RGBA, _width, _height); if (!ost->tmp_frame) { - fprintf(stderr, "Could not allocate temporary picture\n"); + p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_MOVIE_SAVER, "Could not allocate temporary picture\n"); return false; } //} #ifdef AVCODEC_UPPER_V56 ret = avcodec_parameters_from_context(ost->st->codecpar, c); if (ret < 0) { - fprintf(stderr, "Could not copy the stream parameters\n"); + p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_MOVIE_SAVER, "Could not copy the stream parameters\n"); return false; } #endif diff --git a/source/src/qt/common/CMakeLists.txt b/source/src/qt/common/CMakeLists.txt index d31bc13c6..a56b54953 100644 --- a/source/src/qt/common/CMakeLists.txt +++ b/source/src/qt/common/CMakeLists.txt @@ -1,8 +1,4 @@ message("* qt/common") - -#include(cotire) -#include(PrecompiledHeader) - set(s_qt_common_headers emu_thread.h mainwidget.h @@ -19,13 +15,13 @@ else() endif() set(QT_COMMON_BASE - main.cpp +# main.cpp qt_utils.cpp menu_flags.cpp emu_thread.cpp - emu_thread_slots.cpp -# util_fd2.cpp +# emu_thread_slots.cpp +## util_fd2.cpp # util_hdd2.cpp util_bubble2.cpp util_main.cpp @@ -33,11 +29,16 @@ set(QT_COMMON_BASE ../osd_wrapper.cpp ) +if(0) + if(WIN32) + set(QT_COMMON_BASE ../gui/qt_main.cpp ${QT_COMMON_BASE} ) + endif() + add_library(common + ${QT_COMMON_BASE} + ${s_qt_common_headers_MOC} + ) - QT5_ADD_RESOURCES(s_qt_common_RCC ${RESOURCE} - ${CMAKE_CURRENT_SOURCE_DIR}/qrc/i18n_global.qrc - ${CMAKE_CURRENT_SOURCE_DIR}/qrc/icons.qrc) - +else() if(WIN32) set(QT_COMMON_BASE ../gui/qt_main.cpp ${QT_COMMON_BASE} ) @@ -45,17 +46,12 @@ if(WIN32) WIN32 ${QT_COMMON_BASE} ${s_qt_common_headers_MOC} - ${s_qt_common_RCC} ) else() - add_executable(${EXEC_TARGET} + add_executable(${EXEC_TARGET} ${QT_COMMON_BASE} ${s_qt_common_headers_MOC} - ${s_qt_common_RCC} ) -# add_precompiled_header(${EXEC_TARGET} pch_list -# SOURCE_CXX pch.cpp FORCEINCLUDE -# ) endif() #cotire(${EXEC_TARGET}) @@ -88,4 +84,4 @@ else() target_link_libraries(${EXEC_TARGET} ${LOCAL_LIBS} ${BUNDLE_LIBS} -lpthread) endif() install(TARGETS ${EXEC_TARGET} DESTINATION bin) - +endif() diff --git a/source/src/qt/common/csp_qt_common.ts b/source/src/qt/common/common.ja_JP.ts similarity index 100% rename from source/src/qt/common/csp_qt_common.ts rename to source/src/qt/common/common.ja_JP.ts diff --git a/source/src/qt/common/emu_thread.cpp b/source/src/qt/common/emu_thread.cpp index 5293a7296..8bcf598c8 100644 --- a/source/src/qt/common/emu_thread.cpp +++ b/source/src/qt/common/emu_thread.cpp @@ -22,6 +22,7 @@ #include "menu_flags.h" #include "../osd.h" #include "mainwidget_base.h" +#include "../../fileio.h" // buttons #ifdef MAX_BUTTONS @@ -34,11 +35,11 @@ extern CSP_Logger *csp_logger; EmuThreadClass::EmuThreadClass(Ui_MainWindowBase *rootWindow, USING_FLAGS *p, QObject *parent) : EmuThreadClassBase(rootWindow, p, parent) { - emu = new EMU(rMainWindow, rMainWindow->getGraphicsView(), using_flags); + emu = new EMU((Ui_MainWindow *)rootWindow, rootWindow->getGraphicsView(), using_flags); p_emu = emu; + p_osd = emu->get_osd(); p->set_emu(emu); - p->set_osd(emu->get_osd()); - emu->get_osd()->moveToThread(this); + p->set_osd((OSD*)p_osd); connect(this, SIGNAL(sig_open_binary_load(int, QString)), MainWindow, SLOT(_open_binary_load(int, QString))); connect(this, SIGNAL(sig_open_binary_save(int, QString)), MainWindow, SLOT(_open_binary_save(int, QString))); @@ -46,9 +47,12 @@ EmuThreadClass::EmuThreadClass(Ui_MainWindowBase *rootWindow, USING_FLAGS *p, QO connect(this, SIGNAL(sig_open_cmt_load(int, QString)), MainWindow, SLOT(do_open_read_cmt(int, QString))); connect(this, SIGNAL(sig_open_cmt_write(int, QString)), MainWindow, SLOT(do_open_write_cmt(int, QString))); connect(this, SIGNAL(sig_open_fd(int, QString)), MainWindow, SLOT(_open_disk(int, QString))); - + connect(this, SIGNAL(sig_update_d88_list(int, int)), MainWindow, SLOT(do_update_d88_list(int, int))); + connect(this, SIGNAL(sig_open_d88_fd(int, QString, int)), this, SLOT(do_open_disk(int, QString, int))); connect(this, SIGNAL(sig_open_quick_disk(int, QString)), MainWindow, SLOT(_open_quick_disk(int, QString))); connect(this, SIGNAL(sig_open_bubble(int, QString)), MainWindow, SLOT(_open_bubble(int, QString))); + connect(this, SIGNAL(sig_open_b77_bubble(int, QString, int)), this, SLOT(do_open_bubble_casette(int, QString, int))); + connect(this, SIGNAL(sig_open_cdrom(int, QString)), MainWindow, SLOT(do_open_cdrom(int, QString))); connect(this, SIGNAL(sig_open_laser_disc(int, QString)), MainWindow, SLOT(do_open_laserdisc(int, QString))); @@ -57,284 +61,23 @@ EmuThreadClass::EmuThreadClass(Ui_MainWindowBase *rootWindow, USING_FLAGS *p, QO connect(this, SIGNAL(sig_set_d88_num(int, int)), MainWindow, SLOT(set_d88_slot(int, int))); connect(this, SIGNAL(sig_set_b77_num(int, int)), MainWindow, SLOT(set_b77_slot(int, int))); + p_osd->moveToThread(this); } EmuThreadClass::~EmuThreadClass() { } -void EmuThreadClass::set_romakana(bool flag) -{ -#if defined(USE_AUTO_KEY) - p_emu->set_auto_key_char(flag ? 1 : 0); -#endif -} int EmuThreadClass::get_interval(void) { - static int accum = 0; - accum += p_emu->get_frame_interval(); + static int64_t accum = 0; + accum += (p_emu->get_frame_interval() / 2); int interval = accum >> 10; accum -= interval << 10; return interval; } -void EmuThreadClass::moved_mouse(int x, int y) -{ - mouse_x = x; - mouse_y = y; - //printf("Moved Mouse %d, %d\n", x, y); -#if defined(USE_MOUSE) - bool flag = p_emu->get_osd()->is_mouse_enabled(); - if(!flag) return; - //printf("Mouse Moved: %d, %d\n", x, y); - p_emu->get_osd()->set_mouse_pointer(x, y); -#endif -} - -void EmuThreadClass::button_pressed_mouse_sub(Qt::MouseButton button) -{ -#if defined(USE_MOUSE) - int stat = p_emu->get_osd()->get_mouse_button(); - bool flag = p_emu->get_osd()->is_mouse_enabled(); - switch(button) { - case Qt::LeftButton: - stat |= 0x01; - break; - case Qt::RightButton: - stat |= 0x02; - break; - case Qt::MiddleButton: - flag = !flag; - emit sig_mouse_enable(flag); - return; - break; - default: - break; - } - if(!flag) return; - p_emu->get_osd()->set_mouse_button(stat); -#endif -} - -void EmuThreadClass::button_released_mouse_sub(Qt::MouseButton button) -{ -#if defined(USE_MOUSE) - int stat = p_emu->get_osd()->get_mouse_button(); - switch(button) { - case Qt::LeftButton: - stat &= 0x7ffffffe; - break; - case Qt::RightButton: - stat &= 0x7ffffffd; - break; - case Qt::MiddleButton: - //emit sig_mouse_enable(false); - break; - default: - break; - } - p_emu->get_osd()->set_mouse_button(stat); -#endif -} - -void EmuThreadClass::get_fd_string(void) -{ -#if defined(USE_FLOPPY_DISK) - int i; - QString tmpstr; - QString iname; - QString alamp; - uint32_t access_drv = 0; - bool lamp_stat = false; - access_drv = p_emu->is_floppy_disk_accessed(); - { - for(i = 0; i < (int)using_flags->get_max_drive(); i++) { - tmpstr.clear(); - alamp.clear(); - lamp_stat = false; - if(p_emu->is_floppy_disk_inserted(i)) { - if(i == (access_drv - 1)) { - lamp_stat = true; - alamp = QString::fromUtf8(""); // 💾U+1F4BE Floppy Disk - } else { - alamp = QString::fromUtf8(""); // 💾U+1F4BE Floppy Disk - } - if(emu->d88_file[i].bank_num > 0) { - iname = QString::fromUtf8(emu->d88_file[i].disk_name[emu->d88_file[i].cur_bank]); - } else { - iname = QString::fromUtf8("*Inserted*"); - } - tmpstr = iname; - } else { - tmpstr.clear(); - alamp = QString::fromUtf8("×"); - } - if(alamp != fd_lamp[i]) { - emit sig_set_access_lamp(i + 2, lamp_stat); - emit sig_change_access_lamp(CSP_DockDisks_Domain_FD, i, alamp); - fd_lamp[i] = alamp; - } - if(tmpstr != fd_text[i]) { - emit sig_set_access_lamp(i + 2, lamp_stat); - emit sig_change_osd(CSP_DockDisks_Domain_FD, i, tmpstr); - fd_text[i] = tmpstr; - } - lamp_stat = false; - } - } -#endif -} - -void EmuThreadClass::get_qd_string(void) -{ -#if defined(USE_QUICK_DISK) - int i; - QString iname; - QString alamp; - QString tmpstr; - uint32_t access_drv = 0; - bool lamp_stat = false; - access_drv = p_emu->is_quick_disk_accessed(); - for(i = 0; i < using_flags->get_max_qd(); i++) { - tmpstr.clear(); - lamp_stat = false; - if(p_emu->is_quick_disk_inserted(i)) { - if(i == (access_drv - 1)) { - alamp = QString::fromUtf8(""); // 💽 U+1F4BD MiniDisc - lamp_stat = true; - } else { - alamp = QString::fromUtf8(""); // 💽U+1F4BD MiniDisc - } - tmpstr = alamp; - //tmpstr = tmpstr + QString::fromUtf8(" "); - //iname = QString::fromUtf8("*Inserted*"); - //tmpstr = tmpstr + iname; - } else { - tmpstr = QString::fromUtf8("×"); - } - if(tmpstr != qd_text[i]) { - emit sig_set_access_lamp(i + 10, lamp_stat); - emit sig_change_access_lamp(CSP_DockDisks_Domain_QD, i, tmpstr); - qd_text[i] = tmpstr; - } - lamp_stat = false; - } -#endif -} - -void EmuThreadClass::get_tape_string() -{ - QString tmpstr; - bool readwrite; - bool inserted; -#if defined(USE_TAPE) && !defined(TAPE_BINARY_ONLY) - for(int i = 0; i < USE_TAPE; i++) { - inserted = p_emu->is_tape_inserted(i); - readwrite = false; - if(inserted) { - tmpstr.clear(); - const _TCHAR *ts = p_emu->get_tape_message(i); - if(ts != NULL) { - tmpstr = QString::fromUtf8(ts); - readwrite = p_emu->is_tape_recording(i); - if(readwrite) { - tmpstr = QString::fromUtf8("") + tmpstr + QString::fromUtf8(""); - } else { - tmpstr = QString::fromUtf8("") + tmpstr + QString::fromUtf8(""); - } - } - } else { - tmpstr = QString::fromUtf8(" EMPTY "); - } - if(tmpstr != cmt_text[i]) { - //emit sig_set_access_lamp(i + 12 + ((readwrite) ? 2 : 0), inserted); - emit sig_change_osd(CSP_DockDisks_Domain_CMT, i, tmpstr); - cmt_text[i] = tmpstr; - } - } -#endif -} - -void EmuThreadClass::get_hdd_string(void) -{ -#if defined(USE_HARD_DISK) - QString tmpstr, alamp; - uint32_t access_drv = p_emu->is_hard_disk_accessed(); - bool lamp_stat = false; - alamp.clear(); - tmpstr.clear(); - for(int i = 0; i < (int)using_flags->get_max_hdd(); i++) { - if(p_emu->is_hard_disk_inserted(i)) { - if((access_drv & (1 << i)) != 0) { - alamp = QString::fromUtf8(""); // - lamp_stat = true; - } else { - alamp = QString::fromUtf8(""); // - } - } else { - alamp = QString::fromUtf8("×"); - } - if(tmpstr != hdd_text[i]) { - emit sig_set_access_lamp(i + 16, lamp_stat); - emit sig_change_osd(CSP_DockDisks_Domain_HD, i, tmpstr); - hdd_text[i] = tmpstr; - } - if(alamp != hdd_lamp[i]) { - emit sig_set_access_lamp(i + 16, lamp_stat); - emit sig_change_access_lamp(CSP_DockDisks_Domain_HD, i, alamp); - hdd_lamp[i] = alamp; - } - lamp_stat = false; - } -#endif -} -void EmuThreadClass::get_cd_string(void) -{ -#if defined(USE_COMPACT_DISC) - QString tmpstr; - uint32_t access_drv = p_emu->is_compact_disc_accessed(); - for(int i = 0; i < (int)using_flags->get_max_cd(); i++) { - if(p_emu->is_compact_disc_inserted(i)) { - if((access_drv & (1 << i)) != 0) { - tmpstr = QString::fromUtf8(""); // U+1F4BF OPTICAL DISC - } else { - tmpstr = QString::fromUtf8(""); // U+1F4BF OPTICAL DISC - } - } else { - tmpstr = QString::fromUtf8("×"); - } - if(tmpstr != cdrom_text[i]) { - emit sig_change_access_lamp(CSP_DockDisks_Domain_CD, i, tmpstr); - cdrom_text[i] = tmpstr; - } - } -#endif -} - -void EmuThreadClass::get_bubble_string(void) -{ -#if defined(USE_BUBBLE) - uint32_t access_drv; - int i; - QString alamp; - QString tmpstr; - for(i = 0; i < using_flags->get_max_bubble() ; i++) { - if(p_emu->is_bubble_casette_inserted(i)) { - alamp = QString::fromUtf8("● "); - //tmpstr = alamp + QString::fromUtf8(" "); - } else { - tmpstr = QString::fromUtf8("×"); - //tmpstr = tmpstr + QString::fromUtf8(" "); - } - if(alamp != bubble_text[i]) { - emit sig_change_access_lamp(CSP_DockDisks_Domain_Bubble, i, tmpstr); - bubble_text[i] = alamp; - } - } -#endif -} - #include #include @@ -346,31 +89,32 @@ void EmuThreadClass::resetEmu() p_emu->reset(); } -void EmuThreadClass::specialResetEmu() +void EmuThreadClass::specialResetEmu(int num) { -#ifdef USE_SPECIAL_RESET - p_emu->special_reset(); -#endif + if(using_flags->is_use_special_reset()) { + p_emu->special_reset(num); + } } void EmuThreadClass::loadState() { -#ifdef USE_STATE + if(!(using_flags->is_use_state())) return; + if(!lStateFile.isEmpty()) { p_emu->load_state(lStateFile.toLocal8Bit().constData()); lStateFile.clear(); } -#endif } void EmuThreadClass::saveState() { -#ifdef USE_STATE + if(!(using_flags->is_use_state())) return; + if(!sStateFile.isEmpty()) { p_emu->save_state(sStateFile.toLocal8Bit().constData()); sStateFile.clear(); } -#endif + } void EmuThreadClass::doWork(const QString ¶ms) @@ -411,11 +155,11 @@ void EmuThreadClass::doWork(const QString ¶ms) bStartRecordSoundReq = false; bStopRecordSoundReq = false; bStartRecordMovieReq = false; + specialResetNum = 0; sStateFile.clear(); lStateFile.clear(); thread_id = this->currentThreadId(); record_fps = -1; - tick_timer.start(); update_fps_time = tick_timer.elapsed(); //update_fps_time = SDL_GetTicks(); @@ -426,11 +170,14 @@ void EmuThreadClass::doWork(const QString ¶ms) //key_up_queue.clear(); //key_down_queue.clear(); clear_key_queue(); - + bool half_count = false; for(int i = 0; i < using_flags->get_max_qd(); i++) qd_text[i].clear(); for(int i = 0; i < using_flags->get_max_drive(); i++) { fd_text[i].clear(); fd_lamp[i] = QString::fromUtf8("×"); + fd_open_wait_count[i] = 0; + fd_reserved_path[i].clear(); + fd_reserved_bank[i] = 0; } for(int i = 0; i < using_flags->get_max_tape(); i++) { cmt_text[i].clear(); @@ -452,7 +199,7 @@ void EmuThreadClass::doWork(const QString ¶ms) do { //p_emu->SetHostCpus(this->idealThreadCount()); - if(MainWindow == NULL) { + if((MainWindow == NULL) || (bBlockTask)) { if(bRunThread == false){ goto _exit; } @@ -474,7 +221,11 @@ void EmuThreadClass::doWork(const QString ¶ms) } for(int ii = 0; ii < using_flags->get_max_hdd(); ii++ ) { emit sig_change_access_lamp(CSP_DockDisks_Domain_HD, ii, hdd_text[ii]); + if(config.last_hard_disk_path[ii][0] != _T('\0') && FILEIO::IsFileExisting(config.last_hard_disk_path[ii])) { + emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, ii, config.last_hard_disk_path[ii]); + } } + first = false; } interval = 0; @@ -488,13 +239,16 @@ void EmuThreadClass::doWork(const QString ¶ms) } if(bResetReq != false) { + half_count = false; resetEmu(); bResetReq = false; req_draw = true; } if(bSpecialResetReq != false) { - specialResetEmu(); + half_count = false; + specialResetEmu(specialResetNum); bSpecialResetReq = false; + specialResetNum = 0; } if(bSaveStateReq != false) { saveState(); @@ -575,25 +329,26 @@ void EmuThreadClass::doWork(const QString ¶ms) //printf("%08x %04x %08x %d\n", sp.type, sp.code, sp.mod, sp.repeat); switch(sp.type) { case KEY_QUEUE_UP: - key_mod = sp.mod; - p_emu->get_osd()->key_modifiers(sp.mod); - p_emu->key_up(sp.code, true); // need decicion of extend. - break; + key_mod = sp.mod; + p_osd->key_modifiers(sp.mod); + p_emu->key_up(sp.code, true); // need decicion of extend. + break; case KEY_QUEUE_DOWN: - if(config.romaji_to_kana) { - p_emu->get_osd()->key_modifiers(sp.mod); - p_emu->key_char(sp.code); - } else { - p_emu->get_osd()->key_modifiers(sp.mod); - p_emu->key_down(sp.code, true, sp.repeat); - } - break; + if(config.romaji_to_kana) { + p_osd->key_modifiers(sp.mod); + p_emu->key_char(sp.code); + } else { + p_osd->key_modifiers(sp.mod); + p_emu->key_down(sp.code, true, sp.repeat); + } + break; default: break; } } } - if(multithread_draw) { + + if(!(half_count) && (multithread_draw)) { if(nr_fps < 0.0) { nr_fps = get_emu_frame_rate(); if(nr_fps >= 1.0) emit sig_set_draw_fps(nr_fps); @@ -601,50 +356,78 @@ void EmuThreadClass::doWork(const QString ¶ms) } run_frames = p_emu->run(); total_frames += run_frames; - if(using_flags->is_use_minimum_rendering()) { + // After frame, delayed open + for(int i = 0; i < using_flags->get_max_drive(); i++) { + if(fd_open_wait_count[i] > 0) { + fd_open_wait_count[i] -= run_frames; + if(fd_open_wait_count[i] <= 0) { + do_open_disk(i, fd_reserved_path[i], fd_reserved_bank[i]); + fd_reserved_path[i].clear(); + fd_reserved_bank[i] = 0; + fd_open_wait_count[i] = 0; + } + } + } + if(!(half_count)) { + if(using_flags->is_use_minimum_rendering()) { #if defined(USE_MINIMUM_RENDERING) - req_draw |= p_emu->is_screen_changed(); + req_draw |= p_emu->is_screen_changed(); #else - req_draw = true; + req_draw = true; #endif - } else { - req_draw = true; - } + } else { + req_draw = true; + } #if defined(USE_KEY_LOCKED) && !defined(INDEPENDENT_CAPS_KANA_LED) - led_data = p_emu->get_caps_locked() ? 0x01 : 0x00; - led_data |= (p_emu->get_kana_locked() ? 0x02 : 0x00); + led_data = p_emu->get_caps_locked() ? 0x01 : 0x00; + led_data |= (p_emu->get_kana_locked() ? 0x02 : 0x00); #else - led_data = 0x00; + led_data = 0x00; #endif #if defined(USE_LED_DEVICE) - #if !defined(INDEPENDENT_CAPS_KANA_LED) - led_data <<= USE_LED_DEVICE; - #endif - led_data |= p_emu->get_led_status(); +#if !defined(INDEPENDENT_CAPS_KANA_LED) + led_data <<= USE_LED_DEVICE; +#endif + led_data |= p_emu->get_led_status(); #endif #if defined(USE_LED_DEVICE) || defined(USE_KEY_LOCKED) - if(led_data != led_data_old) { - emit sig_send_data_led((quint32)led_data); - led_data_old = led_data; - } + if(led_data != led_data_old) { + emit sig_send_data_led((quint32)led_data); + led_data_old = led_data; + } #endif - sample_access_drv(); - now_skip = p_emu->is_frame_skippable() && !p_emu->is_video_recording(); - if(config.full_speed) { - interval = 1; - } else { - interval = get_interval(); - } - if((prev_skip && !now_skip) || next_time == 0) { - next_time = tick_timer.elapsed(); - //next_time = SDL_GetTicks(); - } - if(!now_skip) { - next_time += interval; + sample_access_drv(); + now_skip = p_emu->is_frame_skippable() && !p_emu->is_video_recording(); + if(config.full_speed) { + interval = 1; + } else { + interval = get_interval(); + } + if((prev_skip && !now_skip) || next_time == 0) { + next_time = tick_timer.elapsed(); + //next_time = SDL_GetTicks(); + } + if(!now_skip) { + next_time += interval; + } +// prev_skip = now_skip; + } else { // (half_count) + if(config.full_speed) { + interval = 1; + } else { + interval = get_interval(); + } +// if((prev_skip && !now_skip) || next_time == 0) { +// next_time = tick_timer.elapsed(); +// //next_time = SDL_GetTicks(); +// } + if(!now_skip) { + next_time += interval; + } + prev_skip = now_skip; } - prev_skip = now_skip; #if 0 { struct tm *timedat; @@ -681,20 +464,23 @@ void EmuThreadClass::doWork(const QString ¶ms) no_draw_count = 0; //emit sig_draw_thread(true); } + if(!(half_count)) { double nd; nd = emu->get_frame_rate(); if(nr_fps != nd) emit sig_set_draw_fps(nd); nr_fps = nd; } - if(multithread_draw) { - emit sig_draw_thread(req_draw); - } else { - emit sig_draw_thread(req_draw); - emit sig_draw_one_turn(true); + if(!(half_count)) { + //printf("DRAW %dmsec\n", tick_timer.elapsed()); + if(multithread_draw) { + emit sig_draw_thread(req_draw); + } else { + emit sig_draw_thread(req_draw); + emit sig_draw_one_turn(true); + } + skip_frames = 0; } - skip_frames = 0; - // sleep 1 frame priod if need current_time = tick_timer.elapsed(); //current_time = SDL_GetTicks(); @@ -706,17 +492,21 @@ void EmuThreadClass::doWork(const QString ¶ms) } } else if(++skip_frames > MAX_SKIP_FRAMES) { // update window at least once per 10 frames + if(!(half_count)) { double nd; nd = emu->get_frame_rate(); if(nr_fps != nd) emit sig_set_draw_fps(nd); nr_fps = nd; } - if(multithread_draw) { - emit sig_draw_thread(req_draw); - } else { - emit sig_draw_thread(req_draw); - emit sig_draw_one_turn(true); + if(!(half_count)) { + //printf("DRAW(SKIP) %dmsec\n", tick_timer.elapsed()); + if(multithread_draw) { + emit sig_draw_thread(req_draw); + } else { + emit sig_draw_thread(req_draw); + emit sig_draw_one_turn(true); + } } no_draw_count = 0; skip_frames = 0; @@ -745,121 +535,24 @@ void EmuThreadClass::doWork(const QString ¶ms) msleep(sleep_period); //SDL_Delay(sleep_period); } +// printf("HALF=%s %dmsec\n", (half_count) ? "YES" : "NO ", tick_timer.elapsed()); + half_count = !(half_count); //SDL_Delay(sleep_period); } while(1); _exit: //emit quit_draw_thread(); - csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, - "EmuThread : EXIT"); + if(csp_logger != NULL) { + csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, + "EmuThread : EXIT"); + } emit sig_finished(); this->quit(); } -void EmuThreadClass::do_set_display_size(int w, int h, int ww, int wh) -{ - p_emu->suspend(); - p_emu->set_host_window_size(w, h, true); -} - -const _TCHAR *EmuThreadClass::get_emu_message(void) -{ - return (const _TCHAR *)(p_emu->message); -} - -double EmuThreadClass::get_emu_frame_rate(void) -{ - return emu->get_frame_rate(); -} - -int EmuThreadClass::get_message_count(void) -{ - return p_emu->message_count; -} - -void EmuThreadClass::dec_message_count(void) -{ - p_emu->message_count--; -} - const _TCHAR *EmuThreadClass::get_device_name(void) { return (const _TCHAR *)_T(DEVICE_NAME); } -bool EmuThreadClass::get_power_state(void) -{ - return MainWindow->GetPowerState(); -} - -int EmuThreadClass::get_d88_file_cur_bank(int drive) -{ -#ifdef USE_FLOPPY_DISK - if(drive < USE_FLOPPY_DISK) { - QMutexLocker _locker(&uiMutex); - return p_emu->d88_file[drive].cur_bank; - } -#endif - return -1; -} - -int EmuThreadClass::get_d88_file_bank_num(int drive) -{ -#ifdef USE_FLOPPY_DISK - if(drive < USE_FLOPPY_DISK) { - QMutexLocker _locker(&uiMutex); - return p_emu->d88_file[drive].bank_num; - } -#endif - return -1; -} - - -QString EmuThreadClass::get_d88_file_disk_name(int drive, int banknum) -{ -#ifdef USE_FLOPPY_DISK - if(drive < 0) return QString::fromUtf8(""); - if((drive < USE_FLOPPY_DISK) && (banknum < get_d88_file_bank_num(drive))) { - QMutexLocker _locker(&uiMutex); - QString _n = QString::fromLocal8Bit((const char *)(&(p_emu->d88_file[drive].disk_name[banknum][0]))); - return _n; - } -#endif - return QString::fromUtf8(""); -} - - -bool EmuThreadClass::is_floppy_disk_protected(int drive) -{ - -#ifdef USE_FLOPPY_DISK - QMutexLocker _locker(&uiMutex); - - bool _b = p_emu->is_floppy_disk_protected(drive); - return _b; -#endif - return false; -} - -void EmuThreadClass::set_floppy_disk_protected(int drive, bool flag) -{ -#ifdef USE_FLOPPY_DISK - QMutexLocker _locker(&uiMutex); - - p_emu->is_floppy_disk_protected(drive, flag); -#endif -} - -QString EmuThreadClass::get_d88_file_path(int drive) -{ -#ifdef USE_FLOPPY_DISK - if(drive < 0) return QString::fromUtf8(""); - if(drive < USE_FLOPPY_DISK) { - QMutexLocker _locker(&uiMutex); - QString _n = QString::fromLocal8Bit((const char *)(&(p_emu->d88_file[drive].path))); - return _n; - } -#endif - return QString::fromUtf8(""); -} diff --git a/source/src/qt/common/emu_thread.h b/source/src/qt/common/emu_thread.h index b4f1ebd86..ebe364176 100644 --- a/source/src/qt/common/emu_thread.h +++ b/source/src/qt/common/emu_thread.h @@ -31,8 +31,6 @@ #ifndef MAX_HISTORY #define MAX_HISTORY 8 #endif -#define MAX_COMMAND_LEN 64 - class META_MainWindow; class EMU; @@ -44,27 +42,10 @@ QT_BEGIN_NAMESPACE class EmuThreadClass : public EmuThreadClassBase { Q_OBJECT protected: - - QMutex uiMutex; - char dbg_prev_command[MAX_COMMAND_LEN]; - - void button_pressed_mouse_sub(Qt::MouseButton button); - void button_released_mouse_sub(Qt::MouseButton button); - void get_qd_string(void); - void get_fd_string(void); - void get_hdd_string(void); - void get_tape_string(void); - void get_cd_string(void); - void get_bubble_string(void); - - const _TCHAR *get_emu_message(void); - double get_emu_frame_rate(void); - int get_message_count(void); - void dec_message_count(void); const _TCHAR *get_device_name(void); - bool get_power_state(void); + void resetEmu(); - void specialResetEmu(); + void specialResetEmu(int num); void loadState(); void saveState(); @@ -72,59 +53,11 @@ class EmuThreadClass : public EmuThreadClassBase { EmuThreadClass(Ui_MainWindowBase *rootWindow, USING_FLAGS *p, QObject *parent = 0); ~EmuThreadClass(); void run() { doWork("");} - bool now_debugging(); int get_interval(void); - int get_d88_file_cur_bank(int drive); - int get_d88_file_bank_num(int drive); - QString get_d88_file_disk_name(int drive, int banknum); - bool is_floppy_disk_protected(int drive); - void set_floppy_disk_protected(int drive, bool flag); - QString get_d88_file_path(int drive); - - public slots: void doWork(const QString ¶m); - - void do_set_display_size(int w, int h, int ww, int wh); - void moved_mouse(int, int); - - void do_write_protect_disk(int drv, bool flag); - void do_close_disk(int); - void do_open_disk(int, QString, int); - void do_close_hard_disk(int); - void do_open_hard_disk(int, QString); - void do_play_tape(int drv, QString name); - void do_rec_tape(int drv, QString name); - void do_close_tape(int drv); - void do_cmt_push_play(int drv); - void do_cmt_push_stop(int drv); - void do_cmt_push_fast_forward(int drv); - void do_cmt_push_fast_rewind(int drv); - void do_cmt_push_apss_forward(int drv); - void do_cmt_push_apss_rewind(int drv); - void do_write_protect_quickdisk(int drv, bool flag); - void do_close_quickdisk(int drv); - void do_open_quickdisk(int drv, QString path); - void do_close_cart(int drv); - void do_open_cart(int drv, QString path); - void do_close_laser_disc(int drv); - void do_open_laser_disc(int drv, QString path); - void do_eject_cdrom(int drv); - void do_open_cdrom(int drv, QString path); - void do_load_binary(int drv, QString path); - void do_save_binary(int drv, QString path); - void do_write_protect_bubble_casette(int drv, bool flag); - void do_close_bubble_casette(int); - void do_open_bubble_casette(int, QString, int); - void do_start_auto_key(QString text); - void do_stop_auto_key(void); - void set_romakana(bool flag); - void do_close_debugger(void); -signals: - int sig_set_draw_fps(double); - int sig_draw_one_turn(bool); }; QT_END_NAMESPACE diff --git a/source/src/qt/common/emu_thread_slots.cpp b/source/src/qt/common/emu_thread_slots.cpp index d26386e49..56e7868ba 100644 --- a/source/src/qt/common/emu_thread_slots.cpp +++ b/source/src/qt/common/emu_thread_slots.cpp @@ -14,12 +14,12 @@ #include -#include "emu_thread.h" +#include "../gui/emu_thread_tmpl.h" #include "qt_gldraw.h" #include "csp_logger.h" -#include "menu_flags.h" - +#include "../gui/menu_flags.h" +#include "dock_disks.h" // buttons #ifdef MAX_BUTTONS #define MAX_FONT_SIZE 32 @@ -32,6 +32,8 @@ const int auto_key_table_base[][2] = { // 0x200: kana // 0x400: alphabet // 0x800: ALPHABET + // 0x1000 : LOCK + // 0x2000 : UNLOCK {0x0a, 0x000 | 0x0d}, // Enter(Unix) {0x0d, 0x000 | 0x0d}, // Enter {0x20, 0x000 | 0x20}, // ' ' @@ -378,139 +380,155 @@ const int auto_key_table_base_us[][2] = { {-1, -1}, }; -void EmuThreadClass::do_start_auto_key(QString ctext) +const int auto_key_table_50on_base[][2] = { + {0xa1, 0x300 | 0xbf}, // '。' + {0xa2, 0x300 | 0xdb}, // '「' + {0xa3, 0x300 | 0xdd}, // '」' + {0xa4, 0x300 | 0xbe}, // '、' + {0xa5, 0x300 | 0xe2}, // '・' + {0xa6, 0x200 | 0xbf}, // 'ヲ' + {0xa7, 0x300 | 0x31}, // 'ァ' + {0xa8, 0x300 | 0x32}, // 'ィ' + {0xa9, 0x300 | 0x33}, // 'ゥ' + {0xaa, 0x300 | 0x34}, // 'ェ' + {0xab, 0x300 | 0x35}, // 'ォ' + {0xac, 0x300 | 0x4e}, // 'ャ' + {0xad, 0x300 | 0x4d}, // 'ュ' + {0xae, 0x300 | 0xbc}, // 'ョ' + {0xaf, 0x300 | 0x43}, // 'ッ' + {0xb0, 0x300 | 0xba}, // 'ー' + {0xb1, 0x200 | 0x31}, // 'ア' + {0xb2, 0x200 | 0x32}, // 'イ' + {0xb3, 0x200 | 0x33}, // 'ウ' + {0xb4, 0x200 | 0x34}, // 'エ' + {0xb5, 0x200 | 0x35}, // 'オ' + {0xb6, 0x200 | 0x51}, // 'カ' + {0xb7, 0x200 | 0x57}, // 'キ' + {0xb8, 0x200 | 0x45}, // 'ク' + {0xb9, 0x200 | 0x52}, // 'ケ' + {0xba, 0x200 | 0x54}, // 'コ' + {0xbb, 0x200 | 0x41}, // 'サ' + {0xbc, 0x200 | 0x53}, // 'シ' + {0xbd, 0x200 | 0x44}, // 'ス' + {0xbe, 0x200 | 0x46}, // 'セ' + {0xbf, 0x200 | 0x47}, // 'ソ' + {0xc0, 0x200 | 0x5a}, // 'タ' + {0xc1, 0x200 | 0x58}, // 'チ' + {0xc2, 0x200 | 0x43}, // 'ツ' + {0xc3, 0x200 | 0x56}, // 'テ' + {0xc4, 0x200 | 0x42}, // 'ト' + {0xc5, 0x200 | 0x36}, // 'ナ' + {0xc6, 0x200 | 0x37}, // 'ニ' + {0xc7, 0x200 | 0x38}, // 'ヌ' + {0xc8, 0x200 | 0x39}, // 'ネ' + {0xc9, 0x200 | 0x30}, // 'ノ' + {0xca, 0x200 | 0x59}, // 'ハ' + {0xcb, 0x200 | 0x55}, // 'ヒ' + {0xcc, 0x200 | 0x49}, // 'フ' + {0xcd, 0x200 | 0x4f}, // 'ヘ' + {0xce, 0x200 | 0x50}, // 'ホ' + {0xcf, 0x200 | 0x48}, // 'マ' + {0xd0, 0x200 | 0x4a}, // 'ミ' + {0xd1, 0x200 | 0x4b}, // 'ム' + {0xd2, 0x200 | 0x4c}, // 'メ' + {0xd3, 0x200 | 0xbb}, // 'モ' + {0xd4, 0x200 | 0x4e}, // 'ヤ' + {0xd5, 0x200 | 0x4d}, // 'ユ' + {0xd6, 0x200 | 0xbc}, // 'ヨ' + {0xd7, 0x200 | 0xbd}, // 'ラ' + {0xd8, 0x200 | 0xde}, // 'リ' + {0xd9, 0x200 | 0xdc}, // 'ル' + {0xda, 0x200 | 0xc0}, // 'レ' + {0xdb, 0x200 | 0xdb}, // 'ロ' + {0xdc, 0x200 | 0xbe}, // 'ワ' + {0xdd, 0x200 | 0xe2}, // 'ン' + {0xde, 0x200 | 0xba}, // '゙' + {0xdf, 0x200 | 0xdd}, // '゚' + {-1, -1}, +}; + +void EmuThreadClassBase::do_start_auto_key(QString ctext) { -#ifdef USE_AUTO_KEY + //QMutexLocker _locker(&uiMutex); + if(using_flags->is_use_auto_key()) { QTextCodec *codec = QTextCodec::codecForName("Shift-Jis"); QByteArray array; - clipBoardText = ctext; + QVector ucs4_src = ctext.toUcs4(); + QString dst; + dst.clear(); + uint32_t pool[8] = {0}; + for(auto itr = ucs4_src.constBegin(); itr != ucs4_src.constEnd(); ++itr) { + uint val = (*itr); + int chrs = ucs4_kana_zenkaku_to_hankaku((const uint32_t)val, pool, sizeof(pool) / sizeof(uint32_t)); + if(chrs > 0) { + dst.append(QString::fromUcs4((uint*)pool, chrs)); + } + } + clipBoardText = dst; + //printf("%s\n", clipBoardText.toLocal8Bit().constData()); array = codec->fromUnicode(clipBoardText); + //printf("Array is:"); + //for(int l = 0; l < array.size(); l++) { + // printf("%02X ", array.at(l)); + //} + //printf("\n"); if(clipBoardText.size() > 0) { - static int auto_key_table[256]; - static bool initialized = false; - if(!initialized) { - memset(auto_key_table, 0, sizeof(auto_key_table)); - if(using_flags->is_use_auto_key_us()) { - for(int i = 0;; i++) { - if(auto_key_table_base_us[i][0] == -1) { - break; - } - auto_key_table[auto_key_table_base_us[i][0]] = auto_key_table_base_us[i][1]; - } - } else { - for(int i = 0;; i++) { - if(auto_key_table_base[i][0] == -1) { - break; - } - auto_key_table[auto_key_table_base[i][0]] = auto_key_table_base[i][1]; - } - } - if(using_flags->is_use_vm_auto_key_table()) { - if(using_flags->is_use_auto_key_us()) { - for(int i = 0;; i++) { - if(auto_key_table_base_us[i][0] == -1) { - break; - } - auto_key_table[auto_key_table_base_us[i][0]] = auto_key_table_base_us[i][1]; - } - } else { - for(int i = 0;; i++) { - if(auto_key_table_base[i][0] == -1) { - break; - } - auto_key_table[auto_key_table_base[i][0]] = auto_key_table_base[i][1]; - } - } - } - initialized = true; - } - - FIFO* auto_key_buffer = emu->get_auto_key_buffer(); - auto_key_buffer->clear(); - - int size = strlen(array.constData()), prev_kana = 0; + int size = array.size(); const char *buf = (char *)(array.constData()); - - for(int i = 0; i < size; i++) { - int code = buf[i] & 0xff; - if((0x81 <= code && code <= 0x9f) || 0xe0 <= code) { - i++; // kanji ? - continue; - } - // Effect [Enter] even Unix etc.(0x0a should not be ignored). - //else if(code == 0xa) { - //continue; // cr-lf - //} - if((code = auto_key_table[code]) != 0) { - int kana = code & 0x200; - if(prev_kana != kana) { - auto_key_buffer->write(0xf2); - } - prev_kana = kana; - if(using_flags->is_use_auto_key_no_caps()) { - if((code & 0x100) && !(code & (0x400 | 0x800))) { - auto_key_buffer->write((code & 0xff) | 0x100); - } else { - auto_key_buffer->write(code & 0xff); - } - } else if(using_flags->is_use_auto_key_caps()) { - if(code & (0x100 | 0x800)) { - auto_key_buffer->write((code & 0xff) | 0x100); - } else { - auto_key_buffer->write(code & 0xff); - } - } else if(code & (0x100 | 0x400)) { - auto_key_buffer->write((code & 0xff) | 0x100); - } else { - auto_key_buffer->write(code & 0xff); - } - } - } - - if(prev_kana) { - auto_key_buffer->write(0xf2); - } p_emu->stop_auto_key(); + p_emu->set_auto_key_list((char *)buf, size); p_emu->start_auto_key(); } } -#endif + } -void EmuThreadClass::do_stop_auto_key(void) +void EmuThreadClassBase::do_stop_auto_key(void) { + //QMutexLocker _locker(&uiMutex); //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, // "AutoKey: stop\n"); -#if defined(USE_AUTO_KEY) - p_emu->stop_auto_key(); -#endif + if(using_flags->is_use_auto_key()) { + p_emu->stop_auto_key(); + } } -void EmuThreadClass::do_write_protect_disk(int drv, bool flag) +void EmuThreadClassBase::do_write_protect_disk(int drv, bool flag) { -#ifdef USE_FLOPPY_DISK - p_emu->is_floppy_disk_protected(drv, flag); -#endif + //QMutexLocker _locker(&uiMutex); + if(using_flags->is_use_fd()) { + p_emu->is_floppy_disk_protected(drv, flag); + } } -void EmuThreadClass::do_close_disk(int drv) +void EmuThreadClassBase::do_close_disk(int drv) { -#ifdef USE_FLOPPY_DISK - p_emu->close_floppy_disk(drv); - p_emu->d88_file[drv].bank_num = 0; - p_emu->d88_file[drv].cur_bank = -1; -#endif + //QMutexLocker _locker(&uiMutex); + if(using_flags->is_use_fd()) { + p_emu->close_floppy_disk(drv); + p_emu->d88_file[drv].bank_num = 0; + p_emu->d88_file[drv].cur_bank = -1; + fd_open_wait_count[drv] = (int)(get_emu_frame_rate() * 1.0); + emit sig_change_virtual_media(CSP_DockDisks_Domain_FD, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_open_disk(int drv, QString path, int bank) +void EmuThreadClassBase::do_open_disk(int drv, QString path, int bank) { -#ifdef USE_FLOPPY_DISK - QByteArray localPath = path.toLocal8Bit(); - - //p_emu->d88_file[drv].bank_num = 0; - //p_emu->d88_file[drv].cur_bank = -1; + if(!(using_flags->is_use_fd())) return; + //QMutexLocker _locker(&uiMutex); + if(fd_open_wait_count[drv] > 0) { + fd_reserved_path[drv] = path.toUtf8(); + fd_reserved_bank[drv] = bank; + return; + } + QByteArray localPath = path.toLocal8Bit(); + bool multiple_disk = false; + bool past_update = false; + p_emu->d88_file[drv].bank_num = 0; + p_emu->d88_file[drv].cur_bank = -1; if(check_file_extension(localPath.constData(), ".d88") || check_file_extension(localPath.constData(), ".d77")) { FILEIO *fio = new FILEIO(); @@ -518,7 +536,7 @@ void EmuThreadClass::do_open_disk(int drv, QString path, int bank) try { fio->Fseek(0, FILEIO_SEEK_END); int file_size = fio->Ftell(), file_offset = 0; - while(file_offset + 0x2b0 <= file_size && p_emu->d88_file[drv].bank_num < MAX_D88_BANKS) { + while(file_offset + 0x2b0 <= file_size && p_emu->d88_file[drv].bank_num < using_flags->get_max_d88_banks()) { fio->Fseek(file_offset, FILEIO_SEEK_SET); char tmp[18]; memset(tmp, 0x00, sizeof(tmp)); @@ -530,7 +548,7 @@ void EmuThreadClass::do_open_disk(int drv, QString path, int bank) file_offset += fio->FgetUint32_LE(); p_emu->d88_file[drv].bank_num++; } - strcpy(emu->d88_file[drv].path, path.toUtf8().constData()); + strcpy(p_emu->d88_file[drv].path, path.toUtf8().constData()); if(bank >= p_emu->d88_file[drv].bank_num) bank = p_emu->d88_file[drv].bank_num - 1; if(bank < 0) bank = 0; p_emu->d88_file[drv].cur_bank = bank; @@ -539,191 +557,246 @@ void EmuThreadClass::do_open_disk(int drv, QString path, int bank) bank = 0; p_emu->d88_file[drv].bank_num = 0; } + past_update = true; fio->Fclose(); + if(((drv + 1) < using_flags->get_max_drive()) && ((bank + 1) < p_emu->d88_file[drv].bank_num)) { + multiple_disk = true; + } } delete fio; } else { bank = 0; } + if(multiple_disk) { + do_close_disk(drv + 1); + do_open_disk(drv + 1, path, bank + 1); + } +// do_close_disk(drv); p_emu->open_floppy_disk(drv, localPath.constData(), bank); + emit sig_change_virtual_media(CSP_DockDisks_Domain_FD, drv, path); emit sig_update_recent_disk(drv); -#endif + if(past_update) { + emit sig_update_d88_list(drv, bank); + } + } -void EmuThreadClass::do_play_tape(int drv, QString name) +void EmuThreadClassBase::do_play_tape(int drv, QString name) { -#if defined(USE_TAPE) - p_emu->play_tape(drv, name.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_tape()) { + //QMutexLocker _locker(&uiMutex); + p_emu->play_tape(drv, name.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, drv, name); + } } -void EmuThreadClass::do_rec_tape(int drv, QString name) +void EmuThreadClassBase::do_rec_tape(int drv, QString name) { -#if defined(USE_TAPE) - p_emu->rec_tape(drv, name.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_tape()) { + //QMutexLocker _locker(&uiMutex); + p_emu->rec_tape(drv, name.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, drv, name); + } } -void EmuThreadClass::do_close_tape(int drv) +void EmuThreadClassBase::do_close_tape(int drv) { -#if defined(USE_TAPE) - p_emu->close_tape(drv); -#endif + if(using_flags->is_use_tape()) { + //QMutexLocker _locker(&uiMutex); + p_emu->close_tape(drv); + emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_cmt_push_play(int drv) +void EmuThreadClassBase::do_cmt_push_play(int drv) { -#ifdef USE_TAPE - p_emu->push_play(drv); -#endif + if(using_flags->is_use_tape()) { + //QMutexLocker _locker(&uiMutex); + p_emu->push_play(drv); + } } -void EmuThreadClass::do_cmt_push_stop(int drv) +void EmuThreadClassBase::do_cmt_push_stop(int drv) { -#ifdef USE_TAPE - p_emu->push_stop(drv); -#endif + if(using_flags->is_use_tape()) { + //QMutexLocker _locker(&uiMutex); + p_emu->push_stop(drv); + } } -void EmuThreadClass::do_cmt_push_fast_forward(int drv) +void EmuThreadClassBase::do_cmt_push_fast_forward(int drv) { -#ifdef USE_TAPE - p_emu->push_fast_forward(drv); -#endif + if(using_flags->is_use_tape()) { + //QMutexLocker _locker(&uiMutex); + p_emu->push_fast_forward(drv); + } } -void EmuThreadClass::do_cmt_push_fast_rewind(int drv) +void EmuThreadClassBase::do_cmt_push_fast_rewind(int drv) { -#ifdef USE_TAPE - p_emu->push_fast_rewind(drv); -#endif + if(using_flags->is_use_tape()) { + //QMutexLocker _locker(&uiMutex); + p_emu->push_fast_rewind(drv); + } } -void EmuThreadClass::do_cmt_push_apss_forward(int drv) +void EmuThreadClassBase::do_cmt_push_apss_forward(int drv) { -#ifdef USE_TAPE - p_emu->push_apss_forward(drv); -#endif + if(using_flags->is_use_tape()) { + ////QMutexLocker _locker(&uiMutex); + p_emu->push_apss_forward(drv); + } } -void EmuThreadClass::do_cmt_push_apss_rewind(int drv) +void EmuThreadClassBase::do_cmt_push_apss_rewind(int drv) { -#ifdef USE_TAPE - p_emu->push_apss_rewind(drv); -#endif + if(using_flags->is_use_tape()) { + ////QMutexLocker _locker(&uiMutex); + p_emu->push_apss_rewind(drv); + } } -void EmuThreadClass::do_write_protect_quickdisk(int drv, bool flag) +void EmuThreadClassBase::do_write_protect_quickdisk(int drv, bool flag) { -#ifdef USE_QUICK_DISK - //p_emu->write_protect_Qd(drv, flag); -#endif + if(using_flags->is_use_qd()) { + ////QMutexLocker _locker(&uiMutex); + //p_emu->write_protect_Qd(drv, flag); + } } -void EmuThreadClass::do_close_quickdisk(int drv) +void EmuThreadClassBase::do_close_quickdisk(int drv) { -#ifdef USE_QUICK_DISK - p_emu->close_quick_disk(drv); -#endif + if(using_flags->is_use_qd()) { + //QMutexLocker _locker(&uiMutex); + p_emu->close_quick_disk(drv); + emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_open_quickdisk(int drv, QString path) +void EmuThreadClassBase::do_open_quickdisk(int drv, QString path) { -#ifdef USE_QUICK_DISK - p_emu->open_quick_disk(drv, path.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_qd()) { + //QMutexLocker _locker(&uiMutex); + p_emu->open_quick_disk(drv, path.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, drv, path); + } } -void EmuThreadClass::do_open_cdrom(int drv, QString path) +void EmuThreadClassBase::do_open_cdrom(int drv, QString path) { -#ifdef USE_COMPACT_DISC - p_emu->open_compact_disc(drv, path.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_compact_disc()) { + //QMutexLocker _locker(&uiMutex); + p_emu->open_compact_disc(drv, path.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, drv, path); + } } -void EmuThreadClass::do_eject_cdrom(int drv) +void EmuThreadClassBase::do_eject_cdrom(int drv) { -#ifdef USE_COMPACT_DISC - p_emu->close_compact_disc(drv); -#endif + if(using_flags->is_use_compact_disc()) { + //QMutexLocker _locker(&uiMutex); + p_emu->close_compact_disc(drv); + emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_close_hard_disk(int drv) +void EmuThreadClassBase::do_close_hard_disk(int drv) { -#ifdef USE_HARD_DISK - p_emu->close_hard_disk(drv); -#endif + if(using_flags->is_use_hdd()) { + //QMutexLocker _locker(&uiMutex); + p_emu->close_hard_disk(drv); + emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_open_hard_disk(int drv, QString path) +void EmuThreadClassBase::do_open_hard_disk(int drv, QString path) { -#ifdef USE_HARD_DISK - p_emu->open_hard_disk(drv, path.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_hdd()) { + //QMutexLocker _locker(&uiMutex); + p_emu->open_hard_disk(drv, path.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drv, path); + } } -void EmuThreadClass::do_close_cart(int drv) +void EmuThreadClassBase::do_close_cart(int drv) { -#ifdef USE_CART - p_emu->close_cart(drv); -#endif + if(using_flags->is_use_cart()) { + //QMutexLocker _locker(&uiMutex); + p_emu->close_cart(drv); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_open_cart(int drv, QString path) +void EmuThreadClassBase::do_open_cart(int drv, QString path) { -#ifdef USE_CART - p_emu->open_cart(drv, path.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_cart()) { + //QMutexLocker _locker(&uiMutex); + p_emu->open_cart(drv, path.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, drv, path); + } } -void EmuThreadClass::do_close_laser_disc(int drv) +void EmuThreadClassBase::do_close_laser_disc(int drv) { -#ifdef USE_LASER_DISC - p_emu->close_laser_disc(drv); -#endif + if(using_flags->is_use_laser_disc()) { + //QMutexLocker _locker(&uiMutex); + p_emu->close_laser_disc(drv); + emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_open_laser_disc(int drv, QString path) +void EmuThreadClassBase::do_open_laser_disc(int drv, QString path) { -#ifdef USE_LASER_DISC - p_emu->open_laser_disc(drv, path.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_laser_disc()) { + //QMutexLocker _locker(&uiMutex); + p_emu->open_laser_disc(drv, path.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, drv, path); + } } -void EmuThreadClass::do_load_binary(int drv, QString path) +void EmuThreadClassBase::do_load_binary(int drv, QString path) { -#ifdef USE_BINARY_FILE - p_emu->load_binary(drv, path.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_binary_file()) { + //QMutexLocker _locker(&uiMutex); + p_emu->load_binary(drv, path.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, drv, path); + } } -void EmuThreadClass::do_save_binary(int drv, QString path) +void EmuThreadClassBase::do_save_binary(int drv, QString path) { -#ifdef USE_BINARY_FILE - p_emu->save_binary(drv, path.toLocal8Bit().constData()); -#endif + if(using_flags->is_use_binary_file()) { + //QMutexLocker _locker(&uiMutex); + p_emu->save_binary(drv, path.toLocal8Bit().constData()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_write_protect_bubble_casette(int drv, bool flag) +void EmuThreadClassBase::do_write_protect_bubble_casette(int drv, bool flag) { -#ifdef USE_BUBBLE - p_emu->is_bubble_casette_protected(drv, flag); -#endif + if(using_flags->is_use_bubble()) { + //QMutexLocker _locker(&uiMutex); + p_emu->is_bubble_casette_protected(drv, flag); + } } -void EmuThreadClass::do_close_bubble_casette(int drv) +void EmuThreadClassBase::do_close_bubble_casette(int drv) { -#ifdef USE_BUBBLE - p_emu->close_bubble_casette(drv); - p_emu->b77_file[drv].bank_num = 0; - p_emu->b77_file[drv].cur_bank = -1; -#endif + if(using_flags->is_use_bubble()) { + //QMutexLocker _locker(&uiMutex); + p_emu->close_bubble_casette(drv); + p_emu->b77_file[drv].bank_num = 0; + p_emu->b77_file[drv].cur_bank = -1; + emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, drv, QString::fromUtf8("")); + } } -void EmuThreadClass::do_open_bubble_casette(int drv, QString path, int bank) +void EmuThreadClassBase::do_open_bubble_casette(int drv, QString path, int bank) { -#ifdef USE_BUBBLE + if(!(using_flags->is_use_bubble())) return; + + //QMutexLocker _locker(&uiMutex); QByteArray localPath = path.toLocal8Bit(); p_emu->b77_file[drv].bank_num = 0; @@ -736,7 +809,7 @@ void EmuThreadClass::do_open_bubble_casette(int drv, QString path, int bank) try { fio->Fseek(0, FILEIO_SEEK_END); int file_size = fio->Ftell(), file_offset = 0; - while(file_offset + 0x2b0 <= file_size && p_emu->b77_file[drv].bank_num < MAX_B77_BANKS) { + while(file_offset + 0x2b0 <= file_size && p_emu->b77_file[drv].bank_num < using_flags->get_max_b77_banks()) { fio->Fseek(file_offset, FILEIO_SEEK_SET); char tmp[18]; memset(tmp, 0x00, sizeof(tmp)); @@ -764,24 +837,97 @@ void EmuThreadClass::do_open_bubble_casette(int drv, QString path, int bank) bank = 0; } p_emu->open_bubble_casette(drv, localPath.constData(), bank); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, drv, path); emit sig_update_recent_bubble(drv); -#endif + } // Debugger -void EmuThreadClass::do_close_debugger(void) +void EmuThreadClassBase::do_close_debugger(void) { -#if defined(USE_DEBUGGER) - emit sig_quit_debugger(); -#endif + if(using_flags->is_use_debugger()) { + emit sig_quit_debugger(); + } } -bool EmuThreadClass::now_debugging() { -#if defined(USE_DEBUGGER) - return p_emu->now_debugging; -#else - return false; -#endif +void EmuThreadClassBase::set_romakana(bool flag) +{ + if(using_flags->is_use_auto_key()) { + p_emu->set_auto_key_char(flag ? 1 : 0); + } +} + +void EmuThreadClassBase::moved_mouse(int x, int y, int globalx, int globaly) +{ + if(using_flags->is_use_one_board_computer() || using_flags->is_use_mouse() || (using_flags->get_max_button() > 0)) { + mouse_x = x; + mouse_y = y; + //printf("Moved Mouse %d, %d\n", x, y); + bool flag = p_osd->is_mouse_enabled(); + if(!flag) return; + //printf("Mouse Moved: %d, %d\n", x, y); + p_osd->set_mouse_pointer(globalx, globaly); + } +} + +void EmuThreadClassBase::button_pressed_mouse_sub(Qt::MouseButton button) +{ + + if(using_flags->is_use_one_board_computer() || using_flags->is_use_mouse() || (using_flags->get_max_button() > 0)) { + int stat = p_osd->get_mouse_button(); + bool flag = p_osd->is_mouse_enabled(); + switch(button) { + case Qt::LeftButton: + stat |= 0x01; + break; + case Qt::RightButton: + stat |= 0x02; + break; + case Qt::MiddleButton: + flag = !flag; + emit sig_mouse_enable(flag); + return; + break; + default: + break; + } + if(!flag) return; + p_osd->set_mouse_button(stat); + } +} + +void EmuThreadClassBase::button_released_mouse_sub(Qt::MouseButton button) +{ + + if(using_flags->is_use_one_board_computer() || using_flags->is_use_mouse() || (using_flags->get_max_button() > 0)) { + int stat = p_osd->get_mouse_button(); + switch(button) { + case Qt::LeftButton: + stat &= 0x7ffffffe; + break; + case Qt::RightButton: + stat &= 0x7ffffffd; + break; + case Qt::MiddleButton: + //emit sig_mouse_enable(false); + break; + default: + break; + } + p_osd->set_mouse_button(stat); + } +} + +void EmuThreadClassBase::do_set_display_size(int w, int h, int ww, int wh) +{ + p_emu->suspend(); + p_emu->set_host_window_size(w, h, true); +} + +void EmuThreadClassBase::dec_message_count(void) +{ + p_emu->message_count--; } + diff --git a/source/src/qt/common/main.cpp b/source/src/qt/common/main.cpp index 19c3a8c12..1df9cf788 100644 --- a/source/src/qt/common/main.cpp +++ b/source/src/qt/common/main.cpp @@ -24,8 +24,6 @@ // emulation core -extern EMU* emu; -extern QApplication *GuiMain; #if defined(CSP_OS_WINDOWS) CSP_Logger DLL_PREFIX_I *csp_logger; #else diff --git a/source/src/qt/common/mainwidget.h b/source/src/qt/common/mainwidget.h index 93d2ba0b1..e323a1313 100644 --- a/source/src/qt/common/mainwidget.h +++ b/source/src/qt/common/mainwidget.h @@ -13,6 +13,7 @@ QT_BEGIN_NAMESPACE class USING_FLAGS; +class EmuThreadClassBase; #ifndef _SCREEN_MODE_NUM #define _SCREEN_MODE_NUM 32 @@ -34,7 +35,7 @@ class Ui_MainWindow : public Ui_MainWindowBase //void retranslateUI_Help(void); // EmuThread void StopEmuThread(void); - void LaunchEmuThread(void); + void LaunchEmuThread(EmuThreadClassBase *m); // JoyThread void StopJoyThread(void); void LaunchJoyThread(void); @@ -61,7 +62,7 @@ public slots: void _open_bubble(int drv, const QString fname); void eject_bubble(int drv); #endif - + void do_create_hard_disk(int drv, int sector_size, int sectors, int surfaces, int cylinders, QString name); void do_create_d88_media(int drv, quint8 media_type, QString name); #if defined(USE_DEBUGGER) void OnOpenDebugger(int n); diff --git a/source/src/qt/common/menu_flags.cpp b/source/src/qt/common/menu_flags.cpp index d41272440..6828ed56f 100644 --- a/source/src/qt/common/menu_flags.cpp +++ b/source/src/qt/common/menu_flags.cpp @@ -64,9 +64,21 @@ USING_FLAGS_EXT::USING_FLAGS_EXT(config_t *cfg) : USING_FLAGS(cfg) use_fd = false; base_fd_num = 1; max_drive = max_d88_banks = 0; - + #if defined(USE_FLOPPY_TYPE_BIT) + floppy_type_bit = USE_FLOPPY_TYPE_BIT; + #endif max_draw_ranges = 0; - + + #if defined(USE_VARIABLE_MEMORY) + use_ram_size = true; + max_ram_size = USE_VARIABLE_MEMORY; + #if defined(MIN_RAM_SIZE) + min_ram_size = MIN_RAM_SIZE; + #endif + #if defined(RAM_SIZE_ORDER) + ram_size_order = RAM_SIZE_ORDER; + #endif + #endif use_hd = false; max_hd = 0; base_hd_num = 1; @@ -94,7 +106,6 @@ USING_FLAGS_EXT::USING_FLAGS_EXT(config_t *cfg) : USING_FLAGS(cfg) base_qd_num = 1; use_scanline = use_screen_rotate = false; - use_shift_numpad_key = false; screen_mode_num = 1; @@ -114,7 +125,9 @@ USING_FLAGS_EXT::USING_FLAGS_EXT(config_t *cfg) : USING_FLAGS(cfg) real_screen_width = SCREEN_WIDTH; real_screen_height = SCREEN_HEIGHT; - +#if defined(USE_CUSTOM_SCREEN_ZOOM_FACTOR) + custom_screen_zoom_factor = USE_CUSTOM_SCREEN_ZOOM_FACTOR; +#endif #if defined(SCREEN_FAKE_WIDTH) screen_width = SCREEN_FAKE_WIDTH; #else @@ -137,7 +150,6 @@ USING_FLAGS_EXT::USING_FLAGS_EXT(config_t *cfg) : USING_FLAGS(cfg) vm_buttons_d = NULL; use_vertical_pixel_lines = false; - notify_key_down_lr_shift = false; tape_binary_only = false; #if defined(DEVICE_NAME) device_name = QString::fromUtf8(DEVICE_NAME); @@ -402,9 +414,6 @@ USING_FLAGS_EXT::USING_FLAGS_EXT(config_t *cfg) : USING_FLAGS(cfg) #if defined(USE_SCREEN_ROTATE) use_screen_rotate = true; #endif -#if defined(USE_SHIFT_NUMPAD_KEY) - use_shift_numpad_key = true; -#endif #if defined(MAX_SCSI) max_scsi = MAX_SCSI; #endif @@ -425,6 +434,7 @@ USING_FLAGS_EXT::USING_FLAGS_EXT(config_t *cfg) : USING_FLAGS(cfg) #endif #if defined(USE_SPECIAL_RESET) use_special_reset = true; + special_reset_num = USE_SPECIAL_RESET; #endif #if defined(USE_VM_AUTO_KEY_TABLE) use_vm_auto_key_table = true; @@ -441,9 +451,6 @@ USING_FLAGS_EXT::USING_FLAGS_EXT(config_t *cfg) : USING_FLAGS(cfg) #if defined(USE_VERTICAL_PIXEL_LINES) use_vertical_pixel_lines = true; #endif -#if defined(NOTIFY_KEY_DOWN_LR_SHIFT) - notify_key_down_lr_shift = true; -#endif #if defined(TAPE_BINARY_ONLY) tape_binary_only = true; #endif diff --git a/source/src/qt/common/qrc/babbage2nd.qrc b/source/src/qt/common/qrc/babbage2nd.qrc index ce12a3d20..edec36ef4 100644 --- a/source/src/qt/common/qrc/babbage2nd.qrc +++ b/source/src/qt/common/qrc/babbage2nd.qrc @@ -24,6 +24,6 @@ ../../../res/babbage2nd/button18.png ../../../res/babbage2nd/button19.png ../../../res/babbage2nd/button20.png - ../../../res/i18n/ja/babbage2nd.qm + ../../../res/i18n/ja/babbage2nd.ja_JP.qm diff --git a/source/src/qt/common/qrc/bmjr.qrc b/source/src/qt/common/qrc/bmjr.qrc index d10a857d1..458e5f26b 100644 --- a/source/src/qt/common/qrc/bmjr.qrc +++ b/source/src/qt/common/qrc/bmjr.qrc @@ -2,5 +2,6 @@ ../../../res/bmjr.ico ../../../../../doc/VMs/bmjr.txt + ../../../res/i18n/ja/bmjr.ja_JP.qm diff --git a/source/src/qt/common/qrc/bubcom80.qrc b/source/src/qt/common/qrc/bubcom80.qrc index a2ac83ec3..58bb6c5f9 100644 --- a/source/src/qt/common/qrc/bubcom80.qrc +++ b/source/src/qt/common/qrc/bubcom80.qrc @@ -2,6 +2,6 @@ ../../../res/bubcom80.ico ../../../../../doc/VMs/bubcom80.txt - ../../../res/i18n/ja/bubcom80.qm + ../../../res/i18n/ja/bubcom80.ja_JP.qm diff --git a/source/src/qt/common/qrc/ex80.qrc b/source/src/qt/common/qrc/ex80.qrc index 849190c75..e0aaf3fbe 100644 --- a/source/src/qt/common/qrc/ex80.qrc +++ b/source/src/qt/common/qrc/ex80.qrc @@ -3,7 +3,7 @@ ../../../res/ex80/board.png ../../../res/ex80.ico ../../../../../doc/VMs/ex80.txt - ../../../res/i18n/ja/ex80.qm + ../../../res/i18n/ja/ex80.ja_JP.qm ../../../res/ex80/button00.png ../../../res/ex80/button01.png ../../../res/ex80/button02.png diff --git a/source/src/qt/common/qrc/familybasic.qrc b/source/src/qt/common/qrc/familybasic.qrc index ba5cfbf27..c18f566f8 100644 --- a/source/src/qt/common/qrc/familybasic.qrc +++ b/source/src/qt/common/qrc/familybasic.qrc @@ -2,6 +2,6 @@ ../../../res/familybasic.ico ../../../../../doc/VMs/familybasic.txt - ../../../res/i18n/ja/familybasic.qm + ../../../res/i18n/ja/familybasic.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm16beta.qrc b/source/src/qt/common/qrc/fm16beta.qrc index 3f7c80bbd..94f816d40 100644 --- a/source/src/qt/common/qrc/fm16beta.qrc +++ b/source/src/qt/common/qrc/fm16beta.qrc @@ -2,6 +2,6 @@ ../../../res/fm16beta.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/fm16beta.qm + ../../../res/i18n/ja/fm16beta.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm7.qrc b/source/src/qt/common/qrc/fm7.qrc index ed5fbae7b..b61ab5c51 100644 --- a/source/src/qt/common/qrc/fm7.qrc +++ b/source/src/qt/common/qrc/fm7.qrc @@ -2,6 +2,6 @@ ../../../res/fm7.ico ../../../../../doc/VMs/fm7.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77.qrc b/source/src/qt/common/qrc/fm77.qrc index 05fa7931d..c978c8f3e 100644 --- a/source/src/qt/common/qrc/fm77.qrc +++ b/source/src/qt/common/qrc/fm77.qrc @@ -2,6 +2,6 @@ ../../../res/fm77.ico ../../../../../doc/VMs/fm7.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77av.qrc b/source/src/qt/common/qrc/fm77av.qrc index 4562fcc1a..7a6fb5e99 100644 --- a/source/src/qt/common/qrc/fm77av.qrc +++ b/source/src/qt/common/qrc/fm77av.qrc @@ -2,6 +2,6 @@ ../../../res/fm77av.ico ../../../../../doc/VMs/fm77av.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77av20.qrc b/source/src/qt/common/qrc/fm77av20.qrc index 4562fcc1a..7a6fb5e99 100644 --- a/source/src/qt/common/qrc/fm77av20.qrc +++ b/source/src/qt/common/qrc/fm77av20.qrc @@ -2,6 +2,6 @@ ../../../res/fm77av.ico ../../../../../doc/VMs/fm77av.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77av20ex.qrc b/source/src/qt/common/qrc/fm77av20ex.qrc index 4562fcc1a..7a6fb5e99 100644 --- a/source/src/qt/common/qrc/fm77av20ex.qrc +++ b/source/src/qt/common/qrc/fm77av20ex.qrc @@ -2,6 +2,6 @@ ../../../res/fm77av.ico ../../../../../doc/VMs/fm77av.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77av20sx.qrc b/source/src/qt/common/qrc/fm77av20sx.qrc index 4562fcc1a..7a6fb5e99 100644 --- a/source/src/qt/common/qrc/fm77av20sx.qrc +++ b/source/src/qt/common/qrc/fm77av20sx.qrc @@ -2,6 +2,6 @@ ../../../res/fm77av.ico ../../../../../doc/VMs/fm77av.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77av40.qrc b/source/src/qt/common/qrc/fm77av40.qrc index ee5fae454..00395f9e4 100644 --- a/source/src/qt/common/qrc/fm77av40.qrc +++ b/source/src/qt/common/qrc/fm77av40.qrc @@ -2,6 +2,6 @@ ../../../res/fm77av40wx0.ico ../../../../../doc/VMs/fm77av.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77av40ex.qrc b/source/src/qt/common/qrc/fm77av40ex.qrc index 329a9c609..ebee2ce32 100644 --- a/source/src/qt/common/qrc/fm77av40ex.qrc +++ b/source/src/qt/common/qrc/fm77av40ex.qrc @@ -2,6 +2,6 @@ ../../../res/fm77av40wx1.ico ../../../../../doc/VMs/fm77av.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm77av40sx.qrc b/source/src/qt/common/qrc/fm77av40sx.qrc index ccc386239..ebee2ce32 100644 --- a/source/src/qt/common/qrc/fm77av40sx.qrc +++ b/source/src/qt/common/qrc/fm77av40sx.qrc @@ -1,7 +1,7 @@ - ../../../res/fm77av40sx.ico + ../../../res/fm77av40wx1.ico ../../../../../doc/VMs/fm77av.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fm8.qrc b/source/src/qt/common/qrc/fm8.qrc index 109d508df..5ccc783ec 100644 --- a/source/src/qt/common/qrc/fm8.qrc +++ b/source/src/qt/common/qrc/fm8.qrc @@ -2,6 +2,6 @@ ../../../res/fm8.ico ../../../../../doc/VMs/fm8.txt - ../../../res/i18n/ja/fm7.qm + ../../../res/i18n/ja/fm7.ja_JP.qm diff --git a/source/src/qt/common/qrc/fmtowns.qrc b/source/src/qt/common/qrc/fmtowns.qrc new file mode 100644 index 000000000..eb580c764 --- /dev/null +++ b/source/src/qt/common/qrc/fmtowns.qrc @@ -0,0 +1,7 @@ + + + ../../../res/fmr50.ico + ../../../../../doc/VMs/fmtowns.txt + ../../../res/i18n/ja/fmtowns.ja_JP.qm + + diff --git a/source/src/qt/common/qrc/fp200.qrc b/source/src/qt/common/qrc/fp200.qrc index a7cd80374..d85a8b118 100644 --- a/source/src/qt/common/qrc/fp200.qrc +++ b/source/src/qt/common/qrc/fp200.qrc @@ -2,6 +2,6 @@ ../../../res/fp200.ico ../../../../../doc/VMs/fp200.txt - ../../../res/i18n/ja/fp200.qm + ../../../res/i18n/ja/fp200.ja_JP.qm diff --git a/source/src/qt/common/qrc/fsa1.qrc b/source/src/qt/common/qrc/fsa1.qrc index 9aa9c9e07..5ecdebdcb 100644 --- a/source/src/qt/common/qrc/fsa1.qrc +++ b/source/src/qt/common/qrc/fsa1.qrc @@ -2,6 +2,6 @@ ../../../res/fsa1.ico ../../../../../doc/VMs/px7.txt - ../../../res/i18n/ja/msx.qm + ../../../res/i18n/ja/msx.ja_JP.qm diff --git a/source/src/qt/common/qrc/hbf1xdj.qrc b/source/src/qt/common/qrc/hbf1xdj.qrc index 0c422536e..eb0969518 100644 --- a/source/src/qt/common/qrc/hbf1xdj.qrc +++ b/source/src/qt/common/qrc/hbf1xdj.qrc @@ -2,5 +2,6 @@ ../../../res/hx20.ico ../../../../../doc/VMs/px7.txt + ../../../res/i18n/ja/msx.ja_JP.qm diff --git a/source/src/qt/common/qrc/hc20.qrc b/source/src/qt/common/qrc/hc20.qrc index d92c14aad..7f808d794 100644 --- a/source/src/qt/common/qrc/hc20.qrc +++ b/source/src/qt/common/qrc/hc20.qrc @@ -2,6 +2,6 @@ ../../../res/hc20.ico ../../../../../doc/VMs/hc20.txt - ../../../res/i18n/ja/hc20.qm + ../../../res/i18n/ja/hc20.ja_JP.qm diff --git a/source/src/qt/common/qrc/hc40.qrc b/source/src/qt/common/qrc/hc40.qrc index cbf4b48fc..4218d0ebe 100644 --- a/source/src/qt/common/qrc/hc40.qrc +++ b/source/src/qt/common/qrc/hc40.qrc @@ -2,6 +2,6 @@ ../../../res/hc40.ico ../../../../../doc/VMs/hc40.txt - ../../../res/i18n/ja/hc40.qm + ../../../res/i18n/ja/hc40.ja_JP.qm diff --git a/source/src/qt/common/qrc/hc80.qrc b/source/src/qt/common/qrc/hc80.qrc index f3a5d5490..28bf3e186 100644 --- a/source/src/qt/common/qrc/hc80.qrc +++ b/source/src/qt/common/qrc/hc80.qrc @@ -2,6 +2,6 @@ ../../../res/hc80.ico ../../../../../doc/VMs/hc80.txt - ../../../res/i18n/ja/hc80.qm + ../../../res/i18n/ja/hc80.ja_JP.qm diff --git a/source/src/qt/common/qrc/hx20.qrc b/source/src/qt/common/qrc/hx20.qrc index f1717a4d9..eb0969518 100644 --- a/source/src/qt/common/qrc/hx20.qrc +++ b/source/src/qt/common/qrc/hx20.qrc @@ -2,6 +2,6 @@ ../../../res/hx20.ico ../../../../../doc/VMs/px7.txt - ../../../res/i18n/ja/msx.qm + ../../../res/i18n/ja/msx.ja_JP.qm diff --git a/source/src/qt/common/qrc/i18n_global.qrc b/source/src/qt/common/qrc/i18n_global.qrc index efdcb9134..1ddb25a9b 100644 --- a/source/src/qt/common/qrc/i18n_global.qrc +++ b/source/src/qt/common/qrc/i18n_global.qrc @@ -1,7 +1,7 @@ - ../../../res/i18n/ja/csp_qt_gui.qm - ../../../res/i18n/ja/csp_qt_common.qm - ../../../res/i18n/ja/csp_qt_debugger.qm + ../../../res/i18n/ja/gui.ja_JP.qm + ../../../res/i18n/ja/common.ja_JP.qm + ../../../res/i18n/ja/debugger.ja_JP.qm diff --git a/source/src/qt/common/qrc/j3100gt.qrc b/source/src/qt/common/qrc/j3100gt.qrc index 08084b476..92ec97bae 100644 --- a/source/src/qt/common/qrc/j3100gt.qrc +++ b/source/src/qt/common/qrc/j3100gt.qrc @@ -1,5 +1,5 @@ ../../../res/j3100.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/j3100.qm + ../../../res/i18n/ja/j3100.ja_JP.qm diff --git a/source/src/qt/common/qrc/j3100se.qrc b/source/src/qt/common/qrc/j3100se.qrc index af4658531..f3cbaa33f 100644 --- a/source/src/qt/common/qrc/j3100se.qrc +++ b/source/src/qt/common/qrc/j3100se.qrc @@ -2,6 +2,6 @@ ../../../res/j3100.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/j3100.qm + ../../../res/i18n/ja/j3100.ja_JP.qm diff --git a/source/src/qt/common/qrc/j3100sl.qrc b/source/src/qt/common/qrc/j3100sl.qrc index af4658531..f3cbaa33f 100644 --- a/source/src/qt/common/qrc/j3100sl.qrc +++ b/source/src/qt/common/qrc/j3100sl.qrc @@ -2,6 +2,6 @@ ../../../res/j3100.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/j3100.qm + ../../../res/i18n/ja/j3100.ja_JP.qm diff --git a/source/src/qt/common/qrc/j3100ss.qrc b/source/src/qt/common/qrc/j3100ss.qrc index af4658531..f3cbaa33f 100644 --- a/source/src/qt/common/qrc/j3100ss.qrc +++ b/source/src/qt/common/qrc/j3100ss.qrc @@ -2,6 +2,6 @@ ../../../res/j3100.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/j3100.qm + ../../../res/i18n/ja/j3100.ja_JP.qm diff --git a/source/src/qt/common/qrc/micom_mahjong.qrc b/source/src/qt/common/qrc/micom_mahjong.qrc new file mode 100644 index 000000000..e299d1f5a --- /dev/null +++ b/source/src/qt/common/qrc/micom_mahjong.qrc @@ -0,0 +1,6 @@ + + + ../../../res/micom_mahjong.ico + ../../../../../doc/VMs/micom_mahjong.txt + + diff --git a/source/src/qt/common/qrc/msx1.qrc b/source/src/qt/common/qrc/msx1.qrc index d10c412b2..ced133107 100644 --- a/source/src/qt/common/qrc/msx1.qrc +++ b/source/src/qt/common/qrc/msx1.qrc @@ -2,6 +2,6 @@ ../../../res/msx1.ico ../../../../../doc/VMs/px7.txt - ../../../res/i18n/ja/msx.qm + ../../../res/i18n/ja/msx.ja_JP.qm diff --git a/source/src/qt/common/qrc/msx2.qrc b/source/src/qt/common/qrc/msx2.qrc index e525e62e8..dddd7918e 100644 --- a/source/src/qt/common/qrc/msx2.qrc +++ b/source/src/qt/common/qrc/msx2.qrc @@ -2,6 +2,6 @@ ../../../res/msx2.ico ../../../../../doc/VMs/px7.txt - ../../../res/i18n/ja/msx.qm + ../../../res/i18n/ja/msx.ja_JP.qm diff --git a/source/src/qt/common/qrc/msx2plus.qrc b/source/src/qt/common/qrc/msx2plus.qrc index 5cb0bac80..eec30b8cd 100644 --- a/source/src/qt/common/qrc/msx2plus.qrc +++ b/source/src/qt/common/qrc/msx2plus.qrc @@ -2,6 +2,6 @@ ../../../res/msx2p.ico ../../../../../doc/VMs/px7.txt - ../../../res/i18n/ja/msx.qm + ../../../res/i18n/ja/msx.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz1200.qrc b/source/src/qt/common/qrc/mz1200.qrc index 1d1fb1f35..8a20bfaa4 100644 --- a/source/src/qt/common/qrc/mz1200.qrc +++ b/source/src/qt/common/qrc/mz1200.qrc @@ -2,6 +2,6 @@ ../../../res/mz1200.ico ../../../../../doc/VMs/mz1200.txt - ../../../res/i18n/ja/mz80k.qm + ../../../res/i18n/ja/mz80k.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz1500.qrc b/source/src/qt/common/qrc/mz1500.qrc index 04870f6e5..de27bb36b 100644 --- a/source/src/qt/common/qrc/mz1500.qrc +++ b/source/src/qt/common/qrc/mz1500.qrc @@ -2,6 +2,6 @@ ../../../res/mz1500.ico ../../../../../doc/VMs/mz1500.txt - ../../../res/i18n/ja/mz700.qm + ../../../res/i18n/ja/mz700.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz2000.qrc b/source/src/qt/common/qrc/mz2000.qrc index 06672d1a7..a2c9cf30f 100644 --- a/source/src/qt/common/qrc/mz2000.qrc +++ b/source/src/qt/common/qrc/mz2000.qrc @@ -2,6 +2,6 @@ ../../../res/mz2000.ico ../../../../../doc/VMs/mz80b.txt - ../../../res/i18n/ja/mz2500.qm + ../../../res/i18n/ja/mz2500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz2200.qrc b/source/src/qt/common/qrc/mz2200.qrc index 5cd976375..07526fba4 100644 --- a/source/src/qt/common/qrc/mz2200.qrc +++ b/source/src/qt/common/qrc/mz2200.qrc @@ -2,6 +2,6 @@ ../../../res/mz2200.ico ../../../../../doc/VMs/mz80b.txt - ../../../res/i18n/ja/mz2500.qm + ../../../res/i18n/ja/mz2500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz2500.qrc b/source/src/qt/common/qrc/mz2500.qrc index ccea95b06..b66e3b523 100644 --- a/source/src/qt/common/qrc/mz2500.qrc +++ b/source/src/qt/common/qrc/mz2500.qrc @@ -2,6 +2,6 @@ ../../../res/mz2500.ico ../../../../../doc/VMs/mz2500.txt - ../../../res/i18n/ja/mz2500.qm + ../../../res/i18n/ja/mz2500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz2800.qrc b/source/src/qt/common/qrc/mz2800.qrc index 137791d7d..7a3d9dae5 100644 --- a/source/src/qt/common/qrc/mz2800.qrc +++ b/source/src/qt/common/qrc/mz2800.qrc @@ -2,6 +2,6 @@ ../../../res/mz2800.ico ../../../../../doc/VMs/mz2800.txt - ../../../res/i18n/ja/mz2800.qm + ../../../res/i18n/ja/mz2800.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz3500.qrc b/source/src/qt/common/qrc/mz3500.qrc index 576e9b756..40ed6ba08 100644 --- a/source/src/qt/common/qrc/mz3500.qrc +++ b/source/src/qt/common/qrc/mz3500.qrc @@ -2,6 +2,6 @@ ../../../res/mz3500.ico ../../../../../doc/VMs/mz3500.txt - ../../../res/i18n/ja/mz3500.qm + ../../../res/i18n/ja/mz3500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz5500.qrc b/source/src/qt/common/qrc/mz5500.qrc index f3d9cb6b2..40ce24a9e 100644 --- a/source/src/qt/common/qrc/mz5500.qrc +++ b/source/src/qt/common/qrc/mz5500.qrc @@ -2,6 +2,6 @@ ../../../res/mz5500.ico ../../../../../doc/VMs/mz5500.txt - ../../../res/i18n/ja/mz5500.qm + ../../../res/i18n/ja/mz5500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz6500.qrc b/source/src/qt/common/qrc/mz6500.qrc index 8dd3f954a..4500cbd38 100644 --- a/source/src/qt/common/qrc/mz6500.qrc +++ b/source/src/qt/common/qrc/mz6500.qrc @@ -2,6 +2,6 @@ ../../../res/mz6500.ico ../../../../../doc/VMs/mz5500.txt - ../../../res/i18n/ja/mz5500.qm + ../../../res/i18n/ja/mz5500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz6550.qrc b/source/src/qt/common/qrc/mz6550.qrc index 9eb1c577f..3c9cf36b3 100644 --- a/source/src/qt/common/qrc/mz6550.qrc +++ b/source/src/qt/common/qrc/mz6550.qrc @@ -2,6 +2,6 @@ ../../../res/mz6550.ico ../../../../../doc/VMs/mz5500.txt - ../../../res/i18n/ja/mz5500.qm + ../../../res/i18n/ja/mz5500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz700.qrc b/source/src/qt/common/qrc/mz700.qrc index 6cb64a7f4..f6e7b0228 100644 --- a/source/src/qt/common/qrc/mz700.qrc +++ b/source/src/qt/common/qrc/mz700.qrc @@ -2,6 +2,6 @@ ../../../res/mz700.ico ../../../../../doc/VMs/mz700.txt - ../../../res/i18n/ja/mz700.qm + ../../../res/i18n/ja/mz700.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz800.qrc b/source/src/qt/common/qrc/mz800.qrc index a735f6c56..961eba5f2 100644 --- a/source/src/qt/common/qrc/mz800.qrc +++ b/source/src/qt/common/qrc/mz800.qrc @@ -2,6 +2,6 @@ ../../../res/mz800.ico ../../../../../doc/VMs/mz800.txt - ../../../res/i18n/ja/mz700.qm + ../../../res/i18n/ja/mz700.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz80a.qrc b/source/src/qt/common/qrc/mz80a.qrc index 41c30d35e..23b40cc53 100644 --- a/source/src/qt/common/qrc/mz80a.qrc +++ b/source/src/qt/common/qrc/mz80a.qrc @@ -2,6 +2,6 @@ ../../../res/mz80a.ico ../../../../../doc/VMs/mz80a.txt - ../../../res/i18n/ja/mz80k.qm + ../../../res/i18n/ja/mz80k.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz80b.qrc b/source/src/qt/common/qrc/mz80b.qrc index 64ab81dbc..96950b3f1 100644 --- a/source/src/qt/common/qrc/mz80b.qrc +++ b/source/src/qt/common/qrc/mz80b.qrc @@ -2,6 +2,6 @@ ../../../res/mz80b.ico ../../../../../doc/VMs/mz80b.txt - ../../../res/i18n/ja/mz2500.qm + ../../../res/i18n/ja/mz2500.ja_JP.qm diff --git a/source/src/qt/common/qrc/mz80k.qrc b/source/src/qt/common/qrc/mz80k.qrc index e0275267c..bb7a19e08 100644 --- a/source/src/qt/common/qrc/mz80k.qrc +++ b/source/src/qt/common/qrc/mz80k.qrc @@ -2,6 +2,6 @@ ../../../res/mz80k.ico ../../../../../doc/VMs/mz80k.txt - ../../../res/i18n/ja/mz80k.qm + ../../../res/i18n/ja/mz80k.ja_JP.qm diff --git a/source/src/qt/common/qrc/n5200.qrc b/source/src/qt/common/qrc/n5200.qrc index b6d308c13..c58e0a9be 100644 --- a/source/src/qt/common/qrc/n5200.qrc +++ b/source/src/qt/common/qrc/n5200.qrc @@ -2,6 +2,6 @@ ../../../res/n5200.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/n5200.qm + ../../../res/i18n/ja/n5200.ja_JP.qm diff --git a/source/src/qt/common/qrc/pasopia.qrc b/source/src/qt/common/qrc/pasopia.qrc index 20cbcbe5a..b9fdf7f31 100644 --- a/source/src/qt/common/qrc/pasopia.qrc +++ b/source/src/qt/common/qrc/pasopia.qrc @@ -2,6 +2,6 @@ ../../../res/pasopia5.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/pasopia.qm + ../../../res/i18n/ja/pasopia.ja_JP.qm diff --git a/source/src/qt/common/qrc/pasopia7.qrc b/source/src/qt/common/qrc/pasopia7.qrc index ce20b65a4..206a419c1 100644 --- a/source/src/qt/common/qrc/pasopia7.qrc +++ b/source/src/qt/common/qrc/pasopia7.qrc @@ -2,6 +2,6 @@ ../../../res/pasopia7.ico ../../../../../doc/VMs/pasopia7.txt - ../../../res/i18n/ja/pasopia7.qm + ../../../res/i18n/ja/pasopia7.ja_JP.qm diff --git a/source/src/qt/common/qrc/pasopia7_lcd.qrc b/source/src/qt/common/qrc/pasopia7_lcd.qrc index f7aca5c64..206a419c1 100644 --- a/source/src/qt/common/qrc/pasopia7_lcd.qrc +++ b/source/src/qt/common/qrc/pasopia7_lcd.qrc @@ -2,6 +2,6 @@ ../../../res/pasopia7.ico ../../../../../doc/VMs/pasopia7.txt - ../../../res/i18n/ja/pasopia.qm + ../../../res/i18n/ja/pasopia7.ja_JP.qm diff --git a/source/src/qt/common/qrc/pasopia_lcd.qrc b/source/src/qt/common/qrc/pasopia_lcd.qrc index 20cbcbe5a..b9fdf7f31 100644 --- a/source/src/qt/common/qrc/pasopia_lcd.qrc +++ b/source/src/qt/common/qrc/pasopia_lcd.qrc @@ -2,6 +2,6 @@ ../../../res/pasopia5.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/pasopia.qm + ../../../res/i18n/ja/pasopia.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc100.qrc b/source/src/qt/common/qrc/pc100.qrc index 8c8246266..d42f54024 100644 --- a/source/src/qt/common/qrc/pc100.qrc +++ b/source/src/qt/common/qrc/pc100.qrc @@ -2,6 +2,6 @@ ../../../res/pc100.ico ../../../../../doc/VMs/pc100.txt - ../../../res/i18n/ja/pc100.qm + ../../../res/i18n/ja/pc100.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc6001.qrc b/source/src/qt/common/qrc/pc6001.qrc index 059238d21..fc891b4ad 100644 --- a/source/src/qt/common/qrc/pc6001.qrc +++ b/source/src/qt/common/qrc/pc6001.qrc @@ -2,6 +2,6 @@ ../../../res/pc6001.ico ../../../../../doc/VMs/pc6001.txt - ../../../res/i18n/ja/pc6001.qm + ../../../res/i18n/ja/pc6001.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc6001mk2.qrc b/source/src/qt/common/qrc/pc6001mk2.qrc index 3fa2a3a2e..be7aabc98 100644 --- a/source/src/qt/common/qrc/pc6001mk2.qrc +++ b/source/src/qt/common/qrc/pc6001mk2.qrc @@ -2,6 +2,6 @@ ../../../res/pc6001mk2.ico ../../../../../doc/VMs/pc6001.txt - ../../../res/i18n/ja/pc6001.qm + ../../../res/i18n/ja/pc6001.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc6001mk2sr.qrc b/source/src/qt/common/qrc/pc6001mk2sr.qrc index 2b3a337bc..9ad723609 100644 --- a/source/src/qt/common/qrc/pc6001mk2sr.qrc +++ b/source/src/qt/common/qrc/pc6001mk2sr.qrc @@ -2,6 +2,6 @@ ../../../res/pc6001mk2sr.ico ../../../../../doc/VMs/pc6001.txt - ../../../res/i18n/ja/pc6001.qm + ../../../res/i18n/ja/pc6001.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc6601.qrc b/source/src/qt/common/qrc/pc6601.qrc index eb4452ebf..22b9e587d 100644 --- a/source/src/qt/common/qrc/pc6601.qrc +++ b/source/src/qt/common/qrc/pc6601.qrc @@ -2,6 +2,6 @@ ../../../res/pc6601.ico ../../../../../doc/VMs/pc6001.txt - ../../../res/i18n/ja/pc6001.qm + ../../../res/i18n/ja/pc6001.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc6601sr.qrc b/source/src/qt/common/qrc/pc6601sr.qrc index ca95ac311..67f502e08 100644 --- a/source/src/qt/common/qrc/pc6601sr.qrc +++ b/source/src/qt/common/qrc/pc6601sr.qrc @@ -2,6 +2,6 @@ ../../../res/pc6601sr.ico ../../../../../doc/VMs/pc6001.txt - ../../../res/i18n/ja/pc6001.qm + ../../../res/i18n/ja/pc6001.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc8001.qrc b/source/src/qt/common/qrc/pc8001.qrc index 417c42fa1..23f54ad14 100644 --- a/source/src/qt/common/qrc/pc8001.qrc +++ b/source/src/qt/common/qrc/pc8001.qrc @@ -2,6 +2,6 @@ ../../../res/pc8001.ico ../../../../../doc/VMs/pc8801.txt - ../../../res/i18n/ja/pc8801.qm + ../../../res/i18n/ja/pc8801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc8001mk2.qrc b/source/src/qt/common/qrc/pc8001mk2.qrc index 3f2ed243b..899648508 100644 --- a/source/src/qt/common/qrc/pc8001mk2.qrc +++ b/source/src/qt/common/qrc/pc8001mk2.qrc @@ -2,6 +2,6 @@ ../../../res/pc8001mk2.ico ../../../../../doc/VMs/pc8801.txt - ../../../res/i18n/ja/pc8801.qm + ../../../res/i18n/ja/pc8801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc8001mk2sr.qrc b/source/src/qt/common/qrc/pc8001mk2sr.qrc index 10fc23bc4..d35d74bec 100644 --- a/source/src/qt/common/qrc/pc8001mk2sr.qrc +++ b/source/src/qt/common/qrc/pc8001mk2sr.qrc @@ -2,6 +2,6 @@ ../../../res/pc8001mk2sr.ico ../../../../../doc/VMs/pc8801.txt - ../../../res/i18n/ja/pc8801.qm + ../../../res/i18n/ja/pc8801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc8801.qrc b/source/src/qt/common/qrc/pc8801.qrc index 2ac7942e6..61243c6cb 100644 --- a/source/src/qt/common/qrc/pc8801.qrc +++ b/source/src/qt/common/qrc/pc8801.qrc @@ -2,6 +2,6 @@ ../../../res/pc8801.ico ../../../../../doc/VMs/pc8801.txt - ../../../res/i18n/ja/pc8801.qm + ../../../res/i18n/ja/pc8801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc8801ma.qrc b/source/src/qt/common/qrc/pc8801ma.qrc index 34aeb7189..4e642ea94 100644 --- a/source/src/qt/common/qrc/pc8801ma.qrc +++ b/source/src/qt/common/qrc/pc8801ma.qrc @@ -2,6 +2,6 @@ ../../../res/pc8801ma.ico ../../../../../doc/VMs/pc8801.txt - ../../../res/i18n/ja/pc8801.qm + ../../../res/i18n/ja/pc8801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc8801mk2.qrc b/source/src/qt/common/qrc/pc8801mk2.qrc index 207f89309..8403d01aa 100644 --- a/source/src/qt/common/qrc/pc8801mk2.qrc +++ b/source/src/qt/common/qrc/pc8801mk2.qrc @@ -2,6 +2,6 @@ ../../../res/pc8801mk2.ico ../../../../../doc/VMs/pc8801.txt - ../../../res/i18n/ja/pc8801.qm + ../../../res/i18n/ja/pc8801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc9801.qrc b/source/src/qt/common/qrc/pc9801.qrc index 22f3fc1fc..f6c35dc76 100644 --- a/source/src/qt/common/qrc/pc9801.qrc +++ b/source/src/qt/common/qrc/pc9801.qrc @@ -2,6 +2,6 @@ ../../../res/pc9801.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc9801e.qrc b/source/src/qt/common/qrc/pc9801e.qrc index a841114b9..cd5cb03e1 100644 --- a/source/src/qt/common/qrc/pc9801e.qrc +++ b/source/src/qt/common/qrc/pc9801e.qrc @@ -2,6 +2,6 @@ ../../../res/pc9801e.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc9801ra.qrc b/source/src/qt/common/qrc/pc9801ra.qrc index c953777a1..1f43b8a63 100644 --- a/source/src/qt/common/qrc/pc9801ra.qrc +++ b/source/src/qt/common/qrc/pc9801ra.qrc @@ -1,7 +1,7 @@ - ../../../res/pc9801vx.ico + ../../../res/pc9801ra.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc9801u.qrc b/source/src/qt/common/qrc/pc9801u.qrc index 865cead19..5b4f2283e 100644 --- a/source/src/qt/common/qrc/pc9801u.qrc +++ b/source/src/qt/common/qrc/pc9801u.qrc @@ -2,6 +2,6 @@ ../../../res/pc9801u.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc9801vf.qrc b/source/src/qt/common/qrc/pc9801vf.qrc index 97ec64d44..a3adf3e7c 100644 --- a/source/src/qt/common/qrc/pc9801vf.qrc +++ b/source/src/qt/common/qrc/pc9801vf.qrc @@ -2,6 +2,6 @@ ../../../res/pc9801vf.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc9801vm.qrc b/source/src/qt/common/qrc/pc9801vm.qrc index 8c550e5f3..05452ac11 100644 --- a/source/src/qt/common/qrc/pc9801vm.qrc +++ b/source/src/qt/common/qrc/pc9801vm.qrc @@ -2,6 +2,6 @@ ../../../res/pc9801vm.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc9801vx.qrc b/source/src/qt/common/qrc/pc9801vx.qrc index c953777a1..c45678220 100644 --- a/source/src/qt/common/qrc/pc9801vx.qrc +++ b/source/src/qt/common/qrc/pc9801vx.qrc @@ -2,6 +2,6 @@ ../../../res/pc9801vx.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc98do.qrc b/source/src/qt/common/qrc/pc98do.qrc index dd74c86cb..e609b0b24 100644 --- a/source/src/qt/common/qrc/pc98do.qrc +++ b/source/src/qt/common/qrc/pc98do.qrc @@ -2,6 +2,6 @@ ../../../res/pc98do.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc98doplus.qrc b/source/src/qt/common/qrc/pc98doplus.qrc index dd74c86cb..e609b0b24 100644 --- a/source/src/qt/common/qrc/pc98doplus.qrc +++ b/source/src/qt/common/qrc/pc98doplus.qrc @@ -2,6 +2,6 @@ ../../../res/pc98do.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc98ha.qrc b/source/src/qt/common/qrc/pc98ha.qrc index a62f4171c..ef3e9471f 100644 --- a/source/src/qt/common/qrc/pc98ha.qrc +++ b/source/src/qt/common/qrc/pc98ha.qrc @@ -2,6 +2,6 @@ ../../../res/pc98ha.ico ../../../../../doc/VMs/pc98ha.txt - ../../../res/i18n/ja/pc98ha.qm + ../../../res/i18n/ja/pc98ha.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc98lt.qrc b/source/src/qt/common/qrc/pc98lt.qrc index fb8053afb..444f8d495 100644 --- a/source/src/qt/common/qrc/pc98lt.qrc +++ b/source/src/qt/common/qrc/pc98lt.qrc @@ -2,6 +2,6 @@ ../../../res/pc98lt.ico ../../../../../doc/VMs/pc98ha.txt - ../../../res/i18n/ja/pc98ha.qm + ../../../res/i18n/ja/pc98ha.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc98rl.qrc b/source/src/qt/common/qrc/pc98rl.qrc index e8f006b87..c2f49338e 100644 --- a/source/src/qt/common/qrc/pc98rl.qrc +++ b/source/src/qt/common/qrc/pc98rl.qrc @@ -2,6 +2,6 @@ ../../../res/pc98rl.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc98xa.qrc b/source/src/qt/common/qrc/pc98xa.qrc index c953777a1..c45678220 100644 --- a/source/src/qt/common/qrc/pc98xa.qrc +++ b/source/src/qt/common/qrc/pc98xa.qrc @@ -2,6 +2,6 @@ ../../../res/pc9801vx.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pc98xl.qrc b/source/src/qt/common/qrc/pc98xl.qrc index 502839c74..91673c165 100644 --- a/source/src/qt/common/qrc/pc98xl.qrc +++ b/source/src/qt/common/qrc/pc98xl.qrc @@ -2,6 +2,6 @@ ../../../res/pc98xl.ico ../../../../../doc/VMs/pc9801.txt - ../../../res/i18n/ja/pc9801.qm + ../../../res/i18n/ja/pc9801.ja_JP.qm diff --git a/source/src/qt/common/qrc/pcengine.qrc b/source/src/qt/common/qrc/pcengine.qrc index c1548601b..abb2fa77b 100644 --- a/source/src/qt/common/qrc/pcengine.qrc +++ b/source/src/qt/common/qrc/pcengine.qrc @@ -2,6 +2,6 @@ ../../../res/pcengine.ico ../../../../../doc/VMs/00_still_not_written.txt - ../../../res/i18n/ja/pcengine.qm + ../../../res/i18n/ja/pcengine.ja_JP.qm diff --git a/source/src/qt/common/qrc/px7.qrc b/source/src/qt/common/qrc/px7.qrc index 5aa2de8e4..c37f68c70 100644 --- a/source/src/qt/common/qrc/px7.qrc +++ b/source/src/qt/common/qrc/px7.qrc @@ -2,6 +2,6 @@ ../../../res/px7.ico ../../../../../doc/VMs/px7.txt - ../../../res/i18n/ja/msx.qm + ../../../res/i18n/ja/msx.ja_JP.qm diff --git a/source/src/qt/common/qrc/qc10.qrc b/source/src/qt/common/qrc/qc10.qrc index c5f8cbe34..56c47ffd3 100644 --- a/source/src/qt/common/qrc/qc10.qrc +++ b/source/src/qt/common/qrc/qc10.qrc @@ -2,6 +2,6 @@ ../../../res/qc10.ico ../../../../../doc/VMs/qc10.txt - ../../../res/i18n/ja/qc10.qm + ../../../res/i18n/ja/qc10.ja_JP.qm diff --git a/source/src/qt/common/qrc/qc10cms.qrc b/source/src/qt/common/qrc/qc10cms.qrc index c5f8cbe34..56c47ffd3 100644 --- a/source/src/qt/common/qrc/qc10cms.qrc +++ b/source/src/qt/common/qrc/qc10cms.qrc @@ -2,6 +2,6 @@ ../../../res/qc10.ico ../../../../../doc/VMs/qc10.txt - ../../../res/i18n/ja/qc10.qm + ../../../res/i18n/ja/qc10.ja_JP.qm diff --git a/source/src/qt/common/qrc/shaders.qrc b/source/src/qt/common/qrc/shaders.qrc index fbd1f0a48..e5c56b5ef 100644 --- a/source/src/qt/common/qrc/shaders.qrc +++ b/source/src/qt/common/qrc/shaders.qrc @@ -1,64 +1,23 @@ + ../../gui/gl/shaders/vertex_shader.glsl + ../../gui/gl/shaders/fragment_shader.glsl + ../../gui/gl/shaders/distortion_fragment.frag + ../../gui/gl/shaders/afterglow.frag + ../../gui/gl/shaders/ntsc_pass1.glsl + ../../gui/gl/shaders/ntsc_pass2.glsl + ../../gui/gl/shaders/chromakey_fragment_shader.glsl + ../../gui/gl/shaders/chromakey_fragment_shader2.glsl + ../../gui/gl/shaders/icon_fragment_shader.glsl + ../../gui/gl/shaders/normal_fragment_shader.glsl + ../../gui/gl/shaders/led_fragment_shader.glsl + ../../gui/gl/shaders/led_vertex_shader.glsl + ../../gui/gl/shaders/grids_fragment_shader.glsl + ../../gui/gl/shaders/grids_vertex_shader.glsl + ../../gui/gl/shaders/grids_vertex_shader_fixed.glsl + ../../gui/gl2/chromakey_fragment_shader2.glsl ../../gui/gl2/vertex_shader.glsl ../../gui/gl2/normal_fragment_shader.glsl - ../../gui/gl2/icon_fragment_shader.glsl - - ../../gui/gl3/chromakey_fragment_shader.glsl - ../../gui/gl3/chromakey_fragment_shader2.glsl - ../../gui/gl3/fragment_shader.glsl - ../../gui/gl3/icon_fragment_shader.glsl - ../../gui/gl3/normal_fragment_shader.glsl - - ../../gui/gl3/vertex_shader.glsl - ../../gui/gl3/tmp_vertex_shader.glsl - - ../../gui/gl3/led_fragment_shader.glsl - ../../gui/gl3/led_vertex_shader.glsl - - ../../gui/gl3/grids_fragment_shader.glsl - ../../gui/gl3/grids_vertex_shader.glsl - ../../gui/gl3/grids_vertex_shader_fixed.glsl - ../../gui/gl3/ntsc_pass1.glsl - ../../gui/gl3/ntsc_pass2.glsl - - ../../gui/gles2/chromakey_fragment_shader.glsl - ../../gui/gles2/chromakey_fragment_shader2.glsl - ../../gui/gles2/fragment_shader.glsl - ../../gui/gles2/icon_fragment_shader.glsl - ../../gui/gles2/normal_fragment_shader.glsl - - ../../gui/gles2/vertex_shader.glsl - ../../gui/gles2/tmp_vertex_shader.glsl - - ../../gui/gles2/led_fragment_shader.glsl - ../../gui/gles2/led_vertex_shader.glsl - - ../../gui/gles2/grids_fragment_shader.glsl - ../../gui/gles2/grids_vertex_shader.glsl - ../../gui/gles2/grids_vertex_shader_fixed.glsl - - ../../gui/gles2/ntsc_pass1.glsl - ../../gui/gles2/ntsc_pass2.glsl - - ../../gui/gl4_5/chromakey_fragment_shader.glsl - ../../gui/gl4_5/chromakey_fragment_shader2.glsl - ../../gui/gl4_5/fragment_shader.glsl - ../../gui/gl4_5/icon_fragment_shader.glsl - ../../gui/gl4_5/normal_fragment_shader.glsl - - ../../gui/gl4_5/vertex_shader.glsl - ../../gui/gl4_5/tmp_vertex_shader.glsl - - ../../gui/gl4_5/led_fragment_shader.glsl - ../../gui/gl4_5/led_vertex_shader.glsl - - ../../gui/gl4_5/grids_fragment_shader.glsl - ../../gui/gl4_5/grids_vertex_shader.glsl - ../../gui/gl4_5/grids_vertex_shader_fixed.glsl - ../../gui/gl4_5/ntsc_pass1.glsl - ../../gui/gl4_5/ntsc_pass2.glsl - - + ../../gui/gl2/icon_fragment_shader.glsl diff --git a/source/src/qt/common/qrc/smb80te.qrc b/source/src/qt/common/qrc/smb80te.qrc index a71d07cf0..82d34ed20 100644 --- a/source/src/qt/common/qrc/smb80te.qrc +++ b/source/src/qt/common/qrc/smb80te.qrc @@ -3,7 +3,7 @@ ../../../res/smb80te.ico ../../../res/smb80te/board.png ../../../../../doc/VMs/smb80te.txt - ../../../res/i18n/ja/smb80te.qm + ../../../res/i18n/ja/smb80te.ja_JP.qm ../../../res/smb80te/button00.png ../../../res/smb80te/button01.png ../../../res/smb80te/button02.png diff --git a/source/src/qt/common/qrc/smc70.qrc b/source/src/qt/common/qrc/smc70.qrc index 63c90f8ec..149ea446a 100644 --- a/source/src/qt/common/qrc/smc70.qrc +++ b/source/src/qt/common/qrc/smc70.qrc @@ -2,6 +2,6 @@ ../../../res/smc70.ico ../../../../../doc/VMs/smc70.txt - ../../../res/i18n/ja/smc777.qm + ../../../res/i18n/ja/smc777.ja_JP.qm diff --git a/source/src/qt/common/qrc/smc777.qrc b/source/src/qt/common/qrc/smc777.qrc index 5aa44f0f4..ad931c3dd 100644 --- a/source/src/qt/common/qrc/smc777.qrc +++ b/source/src/qt/common/qrc/smc777.qrc @@ -1,6 +1,6 @@ ../../../res/smc777.ico - ../../../res/i18n/ja/smc777.qm + ../../../res/i18n/ja/smc777.ja_JP.qm diff --git a/source/src/qt/common/qrc/svi3x8.qrc b/source/src/qt/common/qrc/svi3x8.qrc new file mode 100644 index 000000000..bee211bde --- /dev/null +++ b/source/src/qt/common/qrc/svi3x8.qrc @@ -0,0 +1,7 @@ + + + ../../../res/svi3x8.ico + ../../../../../doc/VMs/00_still_not_written.txt + ../../../res/i18n/ja/svi3x8.ja_JP.qm + + diff --git a/source/src/qt/common/qrc/tk80.qrc b/source/src/qt/common/qrc/tk80.qrc new file mode 100644 index 000000000..45cd4bb57 --- /dev/null +++ b/source/src/qt/common/qrc/tk80.qrc @@ -0,0 +1,33 @@ + + + ../../../res/tk80bs.ico + ../../../res/tk80bs/board.png + ../../../../../doc/VMs/tk80bs.txt + ../../../res/i18n/ja/tk80bs.ja_JP.qm + ../../../res/tk80bs/button00.png + ../../../res/tk80bs/button01.png + ../../../res/tk80bs/button02.png + ../../../res/tk80bs/button03.png + ../../../res/tk80bs/button04.png + ../../../res/tk80bs/button05.png + ../../../res/tk80bs/button06.png + ../../../res/tk80bs/button07.png + ../../../res/tk80bs/button08.png + ../../../res/tk80bs/button09.png + ../../../res/tk80bs/button10.png + ../../../res/tk80bs/button11.png + ../../../res/tk80bs/button12.png + ../../../res/tk80bs/button13.png + ../../../res/tk80bs/button14.png + ../../../res/tk80bs/button15.png + ../../../res/tk80bs/button16.png + ../../../res/tk80bs/button17.png + ../../../res/tk80bs/button18.png + ../../../res/tk80bs/button19.png + ../../../res/tk80bs/button20.png + ../../../res/tk80bs/button21.png + ../../../res/tk80bs/button22.png + ../../../res/tk80bs/button23.png + ../../../res/tk80bs/button24.png + + diff --git a/source/src/qt/common/qrc/tk80bs.qrc b/source/src/qt/common/qrc/tk80bs.qrc index 7d76f52d2..45cd4bb57 100644 --- a/source/src/qt/common/qrc/tk80bs.qrc +++ b/source/src/qt/common/qrc/tk80bs.qrc @@ -3,7 +3,7 @@ ../../../res/tk80bs.ico ../../../res/tk80bs/board.png ../../../../../doc/VMs/tk80bs.txt - ../../../res/i18n/ja/tk80bs.qm + ../../../res/i18n/ja/tk80bs.ja_JP.qm ../../../res/tk80bs/button00.png ../../../res/tk80bs/button01.png ../../../res/tk80bs/button02.png diff --git a/source/src/qt/common/qrc/tk85.qrc b/source/src/qt/common/qrc/tk85.qrc index e3f8940d3..a8c5da63c 100644 --- a/source/src/qt/common/qrc/tk85.qrc +++ b/source/src/qt/common/qrc/tk85.qrc @@ -3,7 +3,7 @@ ../../../res/tk85.ico ../../../res/tk85/board.png ../../../../../doc/VMs/tk80bs.txt - ../../../res/i18n/ja/tk80bs.qm + ../../../res/i18n/ja/tk80bs.ja_JP.qm ../../../res/tk85/button00.png ../../../res/tk85/button01.png ../../../res/tk85/button02.png diff --git a/source/src/qt/common/qrc/tvboy.qrc b/source/src/qt/common/qrc/tvboy.qrc new file mode 100644 index 000000000..79ad7c998 --- /dev/null +++ b/source/src/qt/common/qrc/tvboy.qrc @@ -0,0 +1,6 @@ + + + ../../../res/tvboy.ico + ../../../../../doc/VMs/00_still_not_written.txt + + diff --git a/source/src/qt/common/qrc/x1.qrc b/source/src/qt/common/qrc/x1.qrc index b4b0c3c2c..0bb48ac1b 100644 --- a/source/src/qt/common/qrc/x1.qrc +++ b/source/src/qt/common/qrc/x1.qrc @@ -2,6 +2,6 @@ ../../../res/x1.ico ../../../../../doc/VMs/x1twin_turbo.txt - ../../../res/i18n/ja/x1.qm + ../../../res/i18n/ja/x1.ja_JP.qm diff --git a/source/src/qt/common/qrc/x1turbo.qrc b/source/src/qt/common/qrc/x1turbo.qrc index dbe260ea5..f9e8963b2 100644 --- a/source/src/qt/common/qrc/x1turbo.qrc +++ b/source/src/qt/common/qrc/x1turbo.qrc @@ -2,6 +2,6 @@ ../../../res/x1turbo.ico ../../../../../doc/VMs/x1twin_turbo.txt - ../../../res/i18n/ja/x1.qm + ../../../res/i18n/ja/x1.ja_JP.qm diff --git a/source/src/qt/common/qrc/x1turboz.qrc b/source/src/qt/common/qrc/x1turboz.qrc index 82a293fb3..5f5b2441d 100644 --- a/source/src/qt/common/qrc/x1turboz.qrc +++ b/source/src/qt/common/qrc/x1turboz.qrc @@ -2,6 +2,6 @@ ../../../res/x1turboz.ico ../../../../../doc/VMs/x1twin_turbo.txt - ../../../res/i18n/ja/x1.qm + ../../../res/i18n/ja/x1.ja_JP.qm diff --git a/source/src/qt/common/qrc/x1twin.qrc b/source/src/qt/common/qrc/x1twin.qrc index c15749aec..e7c1a6162 100644 --- a/source/src/qt/common/qrc/x1twin.qrc +++ b/source/src/qt/common/qrc/x1twin.qrc @@ -2,6 +2,6 @@ ../../../res/x1twin.ico ../../../../../doc/VMs/x1twin_turbo.txt - ../../../res/i18n/ja/x1.qm + ../../../res/i18n/ja/x1.ja_JP.qm diff --git a/source/src/qt/common/qrc/yis.qrc b/source/src/qt/common/qrc/yis.qrc index 66d0396e3..2ad94a31d 100644 --- a/source/src/qt/common/qrc/yis.qrc +++ b/source/src/qt/common/qrc/yis.qrc @@ -2,6 +2,6 @@ ../../../res/yis.ico ../../../../../doc/VMs/yis.txt - ../../../res/i18n/ja/yis.qm + ../../../res/i18n/ja/yis.ja_JP.qm diff --git a/source/src/qt/common/qrc/ys6464a.qrc b/source/src/qt/common/qrc/ys6464a.qrc index 08a3e3422..9d567f8f5 100644 --- a/source/src/qt/common/qrc/ys6464a.qrc +++ b/source/src/qt/common/qrc/ys6464a.qrc @@ -23,6 +23,6 @@ ../../../res/ys6464a/button18.png ../../../res/ys6464a/button19.png ../../../res/ys6464a/button20.png - ../../../res/i18n/ja/ys6464a.qm + ../../../res/i18n/ja/ys6464a.ja_JP.qm diff --git a/source/src/qt/common/qt_utils.cpp b/source/src/qt/common/qt_utils.cpp index a814e6252..4f9a58d94 100644 --- a/source/src/qt/common/qt_utils.cpp +++ b/source/src/qt/common/qt_utils.cpp @@ -46,7 +46,7 @@ #include "../../vm/fmgen/fmgen.h" EMU* emu; -QApplication *GuiMain = NULL; +//QApplication *GuiMain = NULL; extern config_t config; #if defined(CSP_OS_WINDOWS) CSP_Logger DLL_PREFIX_I *csp_logger; @@ -120,14 +120,15 @@ void Ui_MainWindow::rise_movie_dialog(void) dlg->setWindowTitle(QApplication::translate("CSP_DialogMovie", "Configure movie encodings", 0)); dlg->show(); } -void Ui_MainWindow::LaunchEmuThread(void) + +void Ui_MainWindow::LaunchEmuThread(EmuThreadClassBase *m) { QString objNameStr; GLDrawClass *glv = this->getGraphicsView(); int drvs; - hRunEmu = new EmuThreadClass(rMainWindow, using_flags); + hRunEmu = m; connect(hRunEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString))); connect(hRunEmu, SIGNAL(sig_is_enable_mouse(bool)), glv, SLOT(do_set_mouse_enabled(bool))); connect(glv, SIGNAL(sig_key_down(uint32_t, uint32_t, bool)), hRunEmu, SLOT(do_key_down(uint32_t, uint32_t, bool))); @@ -137,7 +138,7 @@ void Ui_MainWindow::LaunchEmuThread(void) //connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread())); connect(this, SIGNAL(sig_vm_reset()), hRunEmu, SLOT(do_reset())); - connect(this, SIGNAL(sig_vm_specialreset()), hRunEmu, SLOT(do_special_reset())); + connect(this, SIGNAL(sig_vm_specialreset(int)), hRunEmu, SLOT(do_special_reset(int))); connect(this, SIGNAL(sig_emu_update_config()), hRunEmu, SLOT(do_update_config())); connect(this, SIGNAL(sig_emu_update_volume_level(int, int)), hRunEmu, SLOT(do_update_volume_level(int, int))); @@ -244,7 +245,7 @@ void Ui_MainWindow::LaunchEmuThread(void) objNameStr = QString("EmuThreadClass"); hRunEmu->setObjectName(objNameStr); - hDrawEmu = new DrawThreadClass(emu->get_osd(), csp_logger, this); + hDrawEmu = new DrawThreadClass((OSD*)(emu->get_osd()), csp_logger, this); emu->set_parent_handler((EmuThreadClass*)hRunEmu, hDrawEmu); #ifdef ONE_BOARD_MICRO_COMPUTER @@ -259,10 +260,11 @@ void Ui_MainWindow::LaunchEmuThread(void) #endif csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Start."); connect(hDrawEmu, SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int))); - //connect(emu->get_osd(), SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int))); + //connect((OSD*)(emu->get_osd()), SIGNAL(sig_draw_frames(int)), hRunEmu, SLOT(print_framerate(int))); connect(hRunEmu, SIGNAL(window_title_changed(QString)), this, SLOT(do_set_window_title(QString))); connect(hDrawEmu, SIGNAL(message_changed(QString)), this, SLOT(message_status_bar(QString))); connect(actionCapture_Screen, SIGNAL(triggered()), glv, SLOT(do_save_frame_screen())); + connect(this, SIGNAL(sig_emu_launched()), glv, SLOT(set_emu_launched())); /*if(config.use_separate_thread_draw) { connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), hDrawEmu, SLOT(doDraw(bool)), Qt::QueuedConnection); @@ -273,12 +275,12 @@ void Ui_MainWindow::LaunchEmuThread(void) connect(hRunEmu, SIGNAL(sig_set_draw_fps(double)), hDrawEmu, SLOT(do_set_frames_per_second(double))); connect(hRunEmu, SIGNAL(sig_draw_one_turn(bool)), hDrawEmu, SLOT(do_draw_one_turn(bool))); } - //connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), emu->get_osd(), SLOT(do_draw(bool))); + //connect(hRunEmu, SIGNAL(sig_draw_thread(bool)), (OSD*)(emu->get_osd()), SLOT(do_draw(bool))); //connect(hRunEmu, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit())); connect(this, SIGNAL(quit_draw_thread()), hDrawEmu, SLOT(doExit())); - connect(glv, SIGNAL(do_notify_move_mouse(int, int)), - hRunEmu, SLOT(moved_mouse(int, int))); + connect(glv, SIGNAL(do_notify_move_mouse(int, int, int, int)), + hRunEmu, SLOT(moved_mouse(int, int, int, int))); connect(glv, SIGNAL(do_notify_button_pressed(Qt::MouseButton)), hRunEmu, SLOT(button_pressed_mouse(Qt::MouseButton))); connect(glv, SIGNAL(do_notify_button_released(Qt::MouseButton)), @@ -290,24 +292,23 @@ void Ui_MainWindow::LaunchEmuThread(void) connect(hRunEmu, SIGNAL(sig_resize_screen(int, int)), glv, SLOT(resizeGL(int, int))); connect(hRunEmu, SIGNAL(sig_resize_osd(int)), driveData, SLOT(setScreenWidth(int))); + connect(hRunEmu, SIGNAL(sig_change_osd(int, int, QString)), driveData, SLOT(updateMessage(int, int, QString))); connect(glv, SIGNAL(sig_resize_uibar(int, int)), this, SLOT(resize_statusbar(int, int))); connect(hRunEmu, SIGNAL(sig_resize_uibar(int, int)), this, SLOT(resize_statusbar(int, int))); - connect(emu->get_osd(), SIGNAL(sig_req_encueue_video(int, int, int)), + connect((OSD*)(emu->get_osd()), SIGNAL(sig_req_encueue_video(int, int, int)), hDrawEmu, SLOT(do_req_encueue_video(int, int, int))); connect(hRunEmu, SIGNAL(sig_finished()), glv, SLOT(releaseKeyCode(void))); connect(hRunEmu, SIGNAL(sig_finished()), this, SLOT(delete_emu_thread())); objNameStr = QString("EmuDrawThread"); hDrawEmu->setObjectName(objNameStr); - if(config.use_separate_thread_draw) hDrawEmu->start(); - csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "DrawThread : Launch done."); - hSaveMovieThread = new MOVIE_SAVER(640, 400, 30, emu->get_osd(), &config); + hSaveMovieThread = new MOVIE_SAVER(640, 400, 30, (OSD*)(emu->get_osd()), &config); connect(actionStart_Record_Movie->binds, SIGNAL(sig_start_record_movie(int)), hRunEmu, SLOT(do_start_record_video(int))); connect(this, SIGNAL(sig_start_saving_movie()), @@ -319,9 +320,9 @@ void Ui_MainWindow::LaunchEmuThread(void) connect(hSaveMovieThread, SIGNAL(sig_set_state_saving_movie(bool)), this, SLOT(do_set_state_saving_movie(bool))); connect(actionStop_Record_Movie, SIGNAL(triggered()), this, SLOT(do_stop_saving_movie())); - connect(emu->get_osd(), SIGNAL(sig_save_as_movie(QString, int, int)), + connect((OSD*)(emu->get_osd()), SIGNAL(sig_save_as_movie(QString, int, int)), hSaveMovieThread, SLOT(do_open(QString, int, int))); - connect(emu->get_osd(), SIGNAL(sig_stop_saving_movie()), hSaveMovieThread, SLOT(do_close())); + connect((OSD*)(emu->get_osd()), SIGNAL(sig_stop_saving_movie()), hSaveMovieThread, SLOT(do_close())); actionStop_Record_Movie->setIcon(QIcon(":/icon_process_stop.png")); actionStop_Record_Movie->setVisible(false); @@ -329,11 +330,11 @@ void Ui_MainWindow::LaunchEmuThread(void) connect(this, SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int))); connect(this, SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int))); - connect(emu->get_osd(), SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int))); - connect(emu->get_osd(), SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int))); + connect((OSD*)(emu->get_osd()), SIGNAL(sig_movie_set_width(int)), hSaveMovieThread, SLOT(do_set_width(int))); + connect((OSD*)(emu->get_osd()), SIGNAL(sig_movie_set_height(int)), hSaveMovieThread, SLOT(do_set_height(int))); - connect(emu->get_osd(), SIGNAL(sig_enqueue_audio(int16_t*, int)), hSaveMovieThread, SLOT(enqueue_audio(int16_t *, int))); - connect(emu->get_osd(), SIGNAL(sig_enqueue_video(int, int, int, QImage *)), + connect((OSD*)(emu->get_osd()), SIGNAL(sig_enqueue_audio(int16_t*, int)), hSaveMovieThread, SLOT(enqueue_audio(int16_t *, int))); + connect((OSD*)(emu->get_osd()), SIGNAL(sig_enqueue_video(int, int, int, QImage *)), hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *)), Qt::DirectConnection); connect(glv->extfunc, SIGNAL(sig_push_image_to_movie(int, int, int, QImage *)), hSaveMovieThread, SLOT(enqueue_video(int, int, int, QImage *))); @@ -345,17 +346,25 @@ void Ui_MainWindow::LaunchEmuThread(void) csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "MovieThread : Launch done."); connect(action_SetupMovie, SIGNAL(triggered()), this, SLOT(rise_movie_dialog())); - connect(hRunEmu, SIGNAL(sig_change_osd(int, int, QString)), driveData, SLOT(updateMessage(int, int, QString))); connect(hRunEmu, SIGNAL(sig_change_access_lamp(int, int, QString)), driveData, SLOT(updateLabel(int, int, QString))); connect(hRunEmu, SIGNAL(sig_set_access_lamp(int, bool)), graphicsView, SLOT(do_display_osd_leds(int, bool))); - connect(emu->get_osd(), SIGNAL(sig_enable_mouse()), glv, SLOT(do_enable_mouse())); - connect(emu->get_osd(), SIGNAL(sig_disable_mouse()), glv, SLOT(do_disable_mouse())); + connect(hRunEmu, SIGNAL(sig_change_virtual_media(int, int, QString)), driveData, SLOT(updateMediaFileName(int, int, QString))); + connect((OSD*)(emu->get_osd()), SIGNAL(sig_change_virtual_media(int, int, QString)), driveData, SLOT(updateMediaFileName(int, int, QString))); + connect((OSD*)(emu->get_osd()), SIGNAL(sig_enable_mouse()), glv, SLOT(do_enable_mouse())); + connect((OSD*)(emu->get_osd()), SIGNAL(sig_disable_mouse()), glv, SLOT(do_disable_mouse())); - hRunEmu->start(QThread::HighestPriority); - csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Launch done."); + connect(this, SIGNAL(sig_unblock_task()), hRunEmu, SLOT(do_unblock())); + connect(this, SIGNAL(sig_block_task()), hRunEmu, SLOT(do_block())); + connect(this, SIGNAL(sig_start_emu_thread()), hRunEmu, SLOT(do_start_emu_thread())); + connect(this, SIGNAL(sig_start_draw_thread()), hDrawEmu, SLOT(do_start_draw_thread())); + + +// hRunEmu->start(QThread::HighestPriority); this->set_screen_aspect(config.window_stretch_type); emit sig_movie_set_width(SCREEN_WIDTH); emit sig_movie_set_height(SCREEN_HEIGHT); +// hRunEmu->start(QThread::HighestPriority); + csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "EmuThread : Launch done."); } void Ui_MainWindow::do_create_d88_media(int drv, quint8 media_type, QString name) @@ -364,8 +373,23 @@ void Ui_MainWindow::do_create_d88_media(int drv, quint8 media_type, QString name #if defined(USE_FLOPPY_DISK) if(drv < USE_FLOPPY_DISK) { const _TCHAR* path = (const _TCHAR *)(name.toLocal8Bit().data()); - emu->create_bank_floppy_disk(path, media_type); - emit sig_open_disk(drv, name, 0); + if(emu->create_blank_floppy_disk(path, media_type)) { + emit sig_open_disk(drv, name, 0); + } + } +#endif + } +} + +void Ui_MainWindow::do_create_hard_disk(int drv, int sector_size, int sectors, int surfaces, int cylinders, QString name) +{ + if(!(name.isEmpty()) && (drv >= 0)) { +#if defined(USE_HARD_DISK) + if(drv < USE_HARD_DISK) { + const _TCHAR* path = (const _TCHAR *)(name.toLocal8Bit().data()); + if(emu->create_blank_hard_disk(path, sector_size, sectors, surfaces, cylinders)) { + emit sig_open_hard_disk(drv, name); + } } #endif } @@ -374,7 +398,7 @@ void Ui_MainWindow::do_create_d88_media(int drv, quint8 media_type, QString name void Ui_MainWindow::LaunchJoyThread(void) { #if defined(USE_JOYSTICK) - hRunJoy = new JoyThreadClass(emu, emu->get_osd(), using_flags, &config, csp_logger); + hRunJoy = new JoyThreadClass(emu, (OSD*)(emu->get_osd()), using_flags, &config, csp_logger); connect(this, SIGNAL(quit_joy_thread()), hRunJoy, SLOT(doExit())); hRunJoy->setObjectName("JoyThread"); hRunJoy->start(); @@ -612,8 +636,8 @@ extern QCommandLineOption *_opt_dump_envver; extern QCommandLineOption *_opt_dipsw_on; extern QCommandLineOption *_opt_dipsw_off; extern QProcessEnvironment _envvers; -bool _b_dump_envver; -std::string config_fullpath; +extern bool _b_dump_envver; +extern std::string config_fullpath; void SetFDOptions(QCommandLineParser *cmdparser) { @@ -1000,13 +1024,21 @@ void ProcessCmdLine(QCommandLineParser *cmdparser, QStringList *_l) config.render_major_version = 3; config.render_minor_version = 0; } else if((render == QString::fromUtf8("GLES2")) || - (render == QString::fromUtf8("GLESV2")) || - (render == QString::fromUtf8("GLES3")) || - (render == QString::fromUtf8("GLESV3")) || - (render == QString::fromUtf8("GLES"))) { + (render == QString::fromUtf8("GLESV2")) || + (render == QString::fromUtf8("ESV2")) || + (render == QString::fromUtf8("ES2")) || + (render == QString::fromUtf8("ES")) || + (render == QString::fromUtf8("GLES"))) { config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES; config.render_major_version = 2; config.render_minor_version = 1; + } else if((render == QString::fromUtf8("GLES3")) || + (render == QString::fromUtf8("GLESV3")) || + (render == QString::fromUtf8("ESV3")) || + (render == QString::fromUtf8("ES3"))) { + config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES; + config.render_major_version = 3; + config.render_minor_version = 1; } else if((render == QString::fromUtf8("GL4")) || (render == QString::fromUtf8("GL43")) || (render == QString::fromUtf8("GL4.3")) || @@ -1021,16 +1053,16 @@ void ProcessCmdLine(QCommandLineParser *cmdparser, QStringList *_l) switch(config.render_platform) { case CONFIG_RENDER_PLATFORM_OPENGL_MAIN: case CONFIG_RENDER_PLATFORM_OPENGL_CORE: - GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, true); - GuiMain->setAttribute(Qt::AA_UseOpenGLES, false); + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, false); break; case CONFIG_RENDER_PLATFORM_OPENGL_ES: - GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, false); - GuiMain->setAttribute(Qt::AA_UseOpenGLES, true); + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, false); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); break; default: // to GLES 2.1 as Default - GuiMain->setAttribute(Qt::AA_UseDesktopOpenGL, false); - GuiMain->setAttribute(Qt::AA_UseOpenGLES, true); + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, false); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); config.render_platform = CONFIG_RENDER_PLATFORM_OPENGL_ES; config.render_major_version = 2; config.render_minor_version = 1; @@ -1179,24 +1211,19 @@ int MainLoop(int argc, char *argv[]) delim = "/"; #endif - GuiMain = new QApplication(argc, argv); - GuiMain->setObjectName(QString::fromUtf8("Gui_Main")); - _envvers = QProcessEnvironment::systemEnvironment(); - QCommandLineParser cmdparser; virtualMediaList.clear(); SetOptions(&cmdparser); - cmdparser.process(QCoreApplication::arguments()); - - ProcessCmdLine(&cmdparser, &virtualMediaList); - - emustr = emustr + cfgstr; - - SetupLogger(GuiMain, emustr, CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); - - + QStringList arglist; + if(argv != NULL) { + for(int i = 0; i < argc; i++) { + if(argv[i] != NULL) { + arglist.append(QString::fromLocal8Bit(argv[i])); + } + } + } archstr = "Generic"; #if defined(__x86_64__) archstr = "amd64"; @@ -1204,28 +1231,43 @@ int MainLoop(int argc, char *argv[]) #if defined(__i386__) archstr = "ia32"; #endif + emustr = emustr + cfgstr; + USING_FLAGS_EXT *using_flags = new USING_FLAGS_EXT(&config); + cmdparser.process(arglist); + ProcessCmdLine(&cmdparser, &virtualMediaList); + + QApplication *GuiMain = NULL; + + GuiMain = new QApplication(argc, argv); + GuiMain->setObjectName(QString::fromUtf8("Gui_Main")); + _envvers = QProcessEnvironment::systemEnvironment(); + + SetupLogger(GuiMain, emustr, CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); OpeningMessage(archstr); SetupSDL(); + /* * Into Qt's Loop. */ //SetupTranslators(); QTranslator local_translator; - QLocale s_locale; - if(local_translator.load(s_locale, QLatin1String("csp_qt_machine"), QLatin1String("_"), QLatin1String(":/"))) { + QLocale s_locale = QLocale::system(); + + if(local_translator.load(s_locale, "machine", ".", ":/", ".qm")) { GuiMain->installTranslator(&local_translator); } QTranslator s_translator; - if(s_translator.load(s_locale, QLatin1String("csp_qt_gui"), QLatin1String("_"), QLatin1String(":/"))) { + if(s_translator.load(s_locale, "gui", ".", ":/", ".qm")) { GuiMain->installTranslator(&s_translator); } + QTranslator common_translator; - if(common_translator.load(s_locale, QLatin1String("csp_qt_common"), QLatin1String("_"), QLatin1String(":/"))) { + if(common_translator.load(s_locale, "common", ".", ":/", ".qm")) { GuiMain->installTranslator(&common_translator); } QTranslator debugger_translator; - if(debugger_translator.load(s_locale, QLatin1String("csp_qt_debugger"), QLatin1String("_"), QLatin1String(":/"))) { + if(debugger_translator.load(s_locale, "debugger", ".", ":/", ".qm")) { GuiMain->installTranslator(&debugger_translator); } //QProcessEnvironment::systemEnvironment() = _envvers; @@ -1241,28 +1283,22 @@ int MainLoop(int argc, char *argv[]) } } - USING_FLAGS_EXT *using_flags = new USING_FLAGS_EXT(&config); +// USING_FLAGS_EXT *using_flags = new USING_FLAGS_EXT(&config); // initialize emulation core rMainWindow = new META_MainWindow(using_flags, csp_logger); rMainWindow->connect(rMainWindow, SIGNAL(sig_quit_all(void)), rMainWindow, SLOT(deleteLater(void))); rMainWindow->setCoreApplication(GuiMain); rMainWindow->getWindow()->show(); - - // main loop - rMainWindow->LaunchEmuThread(); -#if defined(USE_JOYSTICK) - rMainWindow->LaunchJoyThread(); -#endif - GLDrawClass *pgl = rMainWindow->getGraphicsView(); - pgl->set_emu_launched(); - pgl->setFixedSize(pgl->width(), pgl->height()); rMainWindow->retranselateUi_Depended_OSD(); - QObject::connect(emu->get_osd(), SIGNAL(sig_update_device_node_name(int, const _TCHAR *)), + EmuThreadClass *hRunEmu = new EmuThreadClass(rMainWindow, using_flags); + + + QObject::connect((OSD*)(emu->get_osd()), SIGNAL(sig_update_device_node_name(int, const _TCHAR *)), rMainWindow, SLOT(do_update_device_node_name(int, const _TCHAR *))); for(int i = 0; i < (CSP_LOG_TYPE_VM_DEVICE_END - CSP_LOG_TYPE_VM_DEVICE_0 + 1); i++) { rMainWindow->do_update_device_node_name(i, using_flags->get_vm_node_name(i)); } - csp_logger->set_osd(emu->get_osd()); + csp_logger->set_osd((OSD*)(emu->get_osd())); csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, "InitInstance() OK."); // ToDo: Update raltime. for(int i = 0; i < 16; i++) { @@ -1277,10 +1313,22 @@ int MainLoop(int argc, char *argv[]) QObject::connect(GuiMain, SIGNAL(lastWindowClosed()), rMainWindow, SLOT(on_actionExit_triggered())); - QObject::connect(emu->get_osd(), SIGNAL(sig_clear_keyname_table()), rMainWindow, SLOT(do_clear_keyname_table())); - QObject::connect(emu->get_osd(), SIGNAL(sig_add_keyname_table(uint32_t, QString)), rMainWindow, SLOT(do_add_keyname_table(uint32_t, QString))); + QObject::connect((OSD*)(emu->get_osd()), SIGNAL(sig_clear_keyname_table()), rMainWindow, SLOT(do_clear_keyname_table())); + QObject::connect((OSD*)(emu->get_osd()), SIGNAL(sig_add_keyname_table(uint32_t, QString)), rMainWindow, SLOT(do_add_keyname_table(uint32_t, QString))); emu->get_osd()->update_keyname_table(); + GLDrawClass *pgl = rMainWindow->getGraphicsView(); + pgl->do_set_texture_size(NULL, -1, -1); // It's very ugly workaround (;_;) 20191028 K.Ohta +// pgl->setFixedSize(pgl->width(), pgl->height()); + // main loop + rMainWindow->LaunchEmuThread(hRunEmu); + +#if defined(USE_JOYSTICK) + rMainWindow->LaunchJoyThread(); +#endif + rMainWindow->do_start_emu_thread(); + rMainWindow->do_unblock_task(); + rMainWindow->do_start_draw_thread(); GuiMain->exec(); return 0; } @@ -1405,10 +1453,10 @@ void Ui_MainWindow::OnOpenDebugger(int no) if(vm->get_cpu(no) != NULL && vm->get_cpu(no)->get_debugger() != NULL) { QString windowName = QString::fromUtf8(vm->get_cpu(no)->get_device_name()); windowName = QString::fromUtf8("Debugger ") + windowName; - emu->hDebugger = new CSP_Debugger(emu->get_osd(), this); + emu->hDebugger = new CSP_Debugger((OSD*)(emu->get_osd()), this); QString objNameStr = QString("EmuDebugThread"); emu->hDebugger->setObjectName(objNameStr); - emu->hDebugger->debugger_thread_param.osd = emu->get_osd(); + emu->hDebugger->debugger_thread_param.osd = (OSD*)(emu->get_osd()); emu->hDebugger->debugger_thread_param.vm = vm; emu->hDebugger->debugger_thread_param.cpu_index = no; emu->stop_record_sound(); diff --git a/source/src/qt/common/util_fd2.cpp b/source/src/qt/common/util_fd2.cpp index 133560d2e..8e6c4b7f4 100644 --- a/source/src/qt/common/util_fd2.cpp +++ b/source/src/qt/common/util_fd2.cpp @@ -31,7 +31,9 @@ int Ui_MainWindowBase::set_d88_slot(int drive, int num) //path = QString::fromUtf8(emu->d88_file[drive].path); path = hRunEmu->get_d88_file_path(drive); menu_fds[drive]->do_select_inner_media(num); + if(hRunEmu->get_d88_file_cur_bank(drive) != num) { + emit sig_close_disk(drive); emit sig_open_disk(drive, path, num); if(hRunEmu->is_floppy_disk_protected(drive)) { menu_fds[drive]->do_set_write_protect(true); @@ -142,4 +144,10 @@ void Ui_MainWindowBase::_open_disk(int drv, const QString fname) } } +void Ui_MainWindowBase::do_update_d88_list(int drv, int bank) +{ + UPDATE_D88_LIST(drv, listD88[drv]); + menu_fds[drv]->do_update_inner_media(listD88[drv], bank); +} + //#endif diff --git a/source/src/qt/common/util_main.cpp b/source/src/qt/common/util_main.cpp index 9b1e5c1ba..877919e7e 100644 --- a/source/src/qt/common/util_main.cpp +++ b/source/src/qt/common/util_main.cpp @@ -26,6 +26,7 @@ #include "../gui/csp_logger.h" extern CSP_Logger *csp_logger; +extern EMU* emu; Ui_MainWindow::Ui_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent) : Ui_MainWindowBase(p, logger, parent) { diff --git a/source/src/qt/debugger/CMakeLists.txt b/source/src/qt/debugger/CMakeLists.txt index d87848a25..faa2d062b 100644 --- a/source/src/qt/debugger/CMakeLists.txt +++ b/source/src/qt/debugger/CMakeLists.txt @@ -1,4 +1,4 @@ -message("* qt/debugger") +message("* qt/debugger_${EXE_NAME}") set(s_qt_debugger_headers qt_debugger.h @@ -10,8 +10,9 @@ else() QT4_WRAP_CPP(s_qt_debugger_headers_MOC ${s_qt_debugger_headers}) endif() -add_library(qt_debugger +add_library(qt_debugger_${EXE_NAME} qt_debugger.cpp ${s_qt_debugger_headers_MOC} ) +set_std(qt_debugger_${EXE_NAME}) diff --git a/source/src/qt/debugger/csp_qt_debugger.ts b/source/src/qt/debugger/csp_qt_debugger.ts deleted file mode 100644 index 4f51fda4c..000000000 --- a/source/src/qt/debugger/csp_qt_debugger.ts +++ /dev/null @@ -1,14 +0,0 @@ - - - - - Debugger - - - Emulator still not start -Please wait. - エミュレータが未だ始まっていません。 -お待ち下さい。 - - - diff --git a/source/src/qt/debugger/debugger.ja_JP.ts b/source/src/qt/debugger/debugger.ja_JP.ts new file mode 100644 index 000000000..8a0a4dbb5 --- /dev/null +++ b/source/src/qt/debugger/debugger.ja_JP.ts @@ -0,0 +1,14 @@ + + + + + Debugger + + + Emulator still not start +Please wait. + エミュレータが未だ始まっていません。 +お待ち下さい。 + + + diff --git a/source/src/qt/emuutils/CMakeLists.txt b/source/src/qt/emuutils/CMakeLists.txt index 287f0e7a9..3f1ae95df 100644 --- a/source/src/qt/emuutils/CMakeLists.txt +++ b/source/src/qt/emuutils/CMakeLists.txt @@ -1,6 +1,6 @@ message("* qt/emuutils") -SET(THIS_LIB_VERSION 2.16.4) +SET(THIS_LIB_VERSION 2.21.1) set(s_qt_emuutils_headers ../gui/csp_logger.h @@ -8,6 +8,7 @@ set(s_qt_emuutils_headers set(s_qt_emuutils_srcs ../../common.cpp + ../../config_dll.cpp ../../fifo.cpp ../../fileio.cpp ../../ringbuffer.cpp @@ -30,7 +31,7 @@ add_library(CSPemu_utils SHARED target_link_libraries(CSPemu_utils PRIVATE Qt5::Core - libz.dll.a + ${ZLIB_LIBRARIES} ${SDL2_LIBRARIES} ) @@ -45,6 +46,7 @@ generate_export_header(CSPemu_utils EXPORT_FILE_NAME CSPemu_utils_Export.h STATIC_DEFINE CSPemu_utils_BUILT_AS_STATIC ) + set_std(CSPemu_utils) else() add_library(CSPemu_utils SHARED @@ -56,8 +58,8 @@ set_target_properties(CSPemu_utils PROPERTIES SOVERSION ${THIS_LIB_VERSION} VERSION ${THIS_LIB_VERSION} ) + set_std(CSPemu_utils) INSTALL(TARGETS CSPemu_utils DESTINATION ${LIBCSP_INSTALL_DIR}) endif() - diff --git a/source/src/qt/gui/CMakeLists.txt b/source/src/qt/gui/CMakeLists.txt index a0ce88550..10e14adac 100644 --- a/source/src/qt/gui/CMakeLists.txt +++ b/source/src/qt/gui/CMakeLists.txt @@ -1,6 +1,6 @@ message("* qt/gui") -set(THIS_LIB_VERSION 2.19.9) +set(THIS_LIB_VERSION 3.2.5) #include(cotire) #include(PrecompiledHeader) @@ -40,6 +40,8 @@ set(s_qt_gui_headers dialog_set_key.h dialog_set_key_combo.h dialog_movie.h + dialog_memory.h + display_log.h tab_movie_general.h @@ -62,6 +64,7 @@ set(s_qt_gui_srcs qt_gldraw.cpp qt_glutil.cpp qt_glpack.cpp + gl/qt_glutil_gl_tmpl.cpp gl2/qt_glutil_gl2_0.cpp gl3/qt_glutil_gl3_0.cpp gl4_5/qt_glutil_gl4_5.cpp @@ -102,6 +105,8 @@ set(s_qt_gui_srcs display_about.cpp display_text_document.cpp sound_dialog.cpp + dialog_memory.cpp + dropdown_keyset.cpp dropdown_joystick.cpp dropdown_jsbutton.cpp @@ -124,9 +129,12 @@ set(s_qt_gui_srcs draw_thread.cpp joy_thread.cpp emu_thread_tmpl.cpp + ../common/emu_thread_slots.cpp + qt_debugger_tmpl.cpp menu_flags_tmpl.cpp + ../common/util_fd2.cpp ../common/util_hdd2.cpp # ../common/util_bubble2.cpp @@ -136,13 +144,11 @@ add_definitions(-D__GUI_LIBRARY_NAME=\"libCSPgui.${THIS_LIB_VERSION}\") if(USE_QT_5) QT5_WRAP_CPP(s_qt_gui_headers_MOC ${s_qt_gui_headers}) -# QT5_ADD_RESOURCES(s_qt_gui_RCC ${RESOURCE} -# ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/commontexts.qrc -# ${CMAKE_SOURCE_DIR}/../../src/qt/common/qrc/shaders.qrc -# ) - QT5_ADD_RESOURCES(s_qt_gui_RCC ${RESOURCE} - ${CMAKE_CURRENT_SOURCE_DIR}/../common/qrc/commontexts.qrc + QT5_ADD_RESOURCES(s_qt_gui_RCC ${RESOURCE} + ${CMAKE_CURRENT_SOURCE_DIR}/../common/qrc/commontexts.qrc ${CMAKE_CURRENT_SOURCE_DIR}/../common/qrc/shaders.qrc + ${CMAKE_CURRENT_SOURCE_DIR}/../common/qrc/i18n_global.qrc + ${CMAKE_CURRENT_SOURCE_DIR}/../common/qrc/icons.qrc ) else() QT4_WRAP_CPP(s_qt_gui_headers_MOC ${s_qt_gui_headers}) @@ -157,10 +163,9 @@ add_library(CSPgui SHARED ) target_link_libraries(CSPgui - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPosd.dll.a -# ${LIBAV_LIBRARIES} - ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPavio.dll.a - ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPemu_utils.dll.a + PRIVATE CSPosd + CSPavio + CSPemu_utils Qt5::Core Qt5::Gui Qt5::OpenGL @@ -178,6 +183,7 @@ generate_export_header(CSPgui EXPORT_FILE_NAME CSPgui_Export.h STATIC_DEFINE CSPgui_BUILT_AS_STATIC ) + set_std(CSPgui) else() set(s_qt_gui_srcs ${s_qt_gui_srcs} qt_main.cpp) @@ -202,7 +208,6 @@ set_target_properties(CSPgui PROPERTIES VERSION ${THIS_LIB_VERSION} ) INSTALL(TARGETS CSPgui DESTINATION ${LIBCSP_INSTALL_DIR}) + set_std(CSPgui) endif() - -#cotire(CSPgui) diff --git a/source/src/qt/gui/commonclasses.h b/source/src/qt/gui/commonclasses.h index 079b1d712..00c2eb656 100644 --- a/source/src/qt/gui/commonclasses.h +++ b/source/src/qt/gui/commonclasses.h @@ -18,9 +18,6 @@ #include "common.h" #include "config.h" #include "menu_flags.h" -class EMU; -//class USING_FLAGS; -//extern class EMU* emu; QT_BEGIN_NAMESPACE typedef class DLL_PREFIX Object_Menu_Control: public QObject { @@ -80,6 +77,7 @@ public slots: void do_set_ignore_crc_error(bool flag); void do_set_correct_disk_timing(bool flag); void do_set_disk_count_immediate(bool flag); + void do_special_reset(void); // Bubble void insert_bubble(void); void eject_bubble(void); @@ -131,7 +129,7 @@ public slots: int on_cpu_type(int); int on_cpu_power(int); int on_open_debugger(int); - + int sig_specialreset(int); int sig_insert_fd(int); int sig_eject_fd(int); int set_d88_slot(int, int); diff --git a/source/src/qt/gui/csp_logger.cpp b/source/src/qt/gui/csp_logger.cpp index 2d94c671f..e09fde965 100644 --- a/source/src/qt/gui/csp_logger.cpp +++ b/source/src/qt/gui/csp_logger.cpp @@ -11,13 +11,100 @@ #include "csp_logger.h" #include -#include "emu.h" -#include "vm/vm.h" +#include "emu_template.h" +#include "../../vm/vm_template.h" #include "menu_flags.h" -#include "../osd.h" +#include "../osd_base.h" + +CSP_LoggerLine::CSP_LoggerLine(int64_t line, int _level, QString _domain, QString time_s, QString s, double us) +{ + mainstr = s; + linenum = line; + level = _level; + domain = _domain; + timestamp = time_s; + vm_usec = us; +} + +CSP_LoggerLine::~CSP_LoggerLine() +{ +} + +int64_t CSP_LoggerLine::get_line_num(void) +{ + return linenum; +} + +QString CSP_LoggerLine::get_domain(void) +{ + return domain; +} + +QString CSP_LoggerLine::get_element_syslog(void) +{ + QString s; + _TCHAR secstr[64] = {0}; + my_stprintf_s(secstr, 63, _T(" (%6.7fSec) "), vm_usec / 1.0e6); + if(domain.isEmpty()) { + s = timestamp + QString::fromUtf8(secstr) + mainstr; + } else { + s = timestamp + QString::fromUtf8(secstr) + domain + QString::fromUtf8(" ") + mainstr; + } + return s; +} + +QString CSP_LoggerLine::get_element_console(void) +{ + QString s; + _TCHAR secstr[64] = {0}; + my_stprintf_s(secstr, 63, _T(" (%6.7fSec) "), vm_usec / 1.0e6); + if(domain.isEmpty()) { + s = timestamp + QString::fromUtf8(secstr) + mainstr; + } else { + s = timestamp + QString::fromUtf8(secstr) + domain + QString::fromUtf8(" ") + mainstr; + } + return s; +} + +bool CSP_LoggerLine::check_level(QString _domain, int _level) +{ + bool f = true; + if(!_domain.isEmpty()) { + if(_domain != domain) f = false; + } + if(_level >= 0) { + if(_level != level) { + f = false; + } + } + return f; +} + +bool CSP_LoggerLine::contains(QString s, bool case_sensitive) +{ + if(!(check_domain(s, case_sensitive))) { + return contains_mainstr(s, case_sensitive); + } + return true; +} + +bool CSP_LoggerLine::check_domain(QString s, bool case_sensitive) +{ + Qt::CaseSensitivity _n = (case_sensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive; + if(domain.contains(s, _n)) return true; + return false; +} + +bool CSP_LoggerLine::contains_mainstr(QString s, bool case_sensitive) +{ + Qt::CaseSensitivity _n = (case_sensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive; + if(mainstr.contains(s, _n)) return true; + return false; +} CSP_Logger::CSP_Logger(QObject *parent, bool b_syslog, bool cons, const char *devname) : QObject(parent) { + p_osd = NULL; lock_mutex = new QMutex(QMutex::Recursive); this->reset(); this->open(b_syslog, cons, devname); @@ -159,7 +246,7 @@ void CSP_Logger::open(bool b_syslog, bool cons, const char *devname) } else { dname = QString::fromUtf8("*Undefined*"); } - log_sysname = QString::fromUtf8("Common Source Code Project("); + log_sysname = QString::fromUtf8("CSP("); log_sysname = log_sysname + dname + QString::fromUtf8(")"); if(b_syslog) { @@ -309,7 +396,7 @@ void CSP_Logger::debug_log(int level, int domain_num, char *strbuf) do { if(p != NULL) { CSP_LoggerLine *tmps = NULL; - tmps = new CSP_LoggerLine(linenum, level, domain_s, time_s, QString::fromUtf8(p)); + tmps = new CSP_LoggerLine(linenum, level, domain_s, time_s, QString::fromUtf8(p), get_vm_clocks_usec()); //tmps = new CSP_LoggerLine(linenum, level, domain_s, time_s, QString::fromLocal8Bit(p)); if(log_onoff) { if(cons_log_level_n != 0) { @@ -433,7 +520,7 @@ void CSP_Logger::set_emu_vm_name(const char *devname) } else { dname = QString::fromUtf8("*Undefined*"); } - log_sysname = QString::fromUtf8("Common Source Code Project("); + log_sysname = QString::fromUtf8("CSP("); log_sysname = log_sysname + dname + QString::fromUtf8(")"); } @@ -740,6 +827,19 @@ void *CSP_Logger::get_raw_data(bool forget, int64_t start, int64_t *end_line) return (void *)NULL; } +uint64_t CSP_Logger::get_vm_clocks() +{ + if(p_osd == NULL) return (uint64_t)0; + return p_osd->get_vm_current_clock_uint64(); +} + +double CSP_Logger::get_vm_clocks_usec() +{ + if(p_osd == NULL) return 0.0; + return p_osd->get_vm_current_usec(); +} + + CSP_Log_ConsoleThread::CSP_Log_ConsoleThread(QObject *parent) : QThread(parent) { _mutex = new QMutex(QMutex::Recursive); @@ -778,6 +878,7 @@ void CSP_Log_ConsoleThread::run() } while(!isFinished()); } + #if defined(CSP_OS_WINDOWS) CSP_Logger DLL_PREFIX *csp_logger; #endif diff --git a/source/src/qt/gui/csp_logger.h b/source/src/qt/gui/csp_logger.h index 10b2b96fb..16a831077 100644 --- a/source/src/qt/gui/csp_logger.h +++ b/source/src/qt/gui/csp_logger.h @@ -82,67 +82,32 @@ enum { CSP_LOG_TYPE_VM_STATE = 512, CSP_LOG_TYPE_END = 1023, }; - - - + QT_BEGIN_NAMESPACE class DLL_PREFIX CSP_LoggerLine { private: int64_t linenum; + double vm_usec; int level; QString domain; QString mainstr; QString timestamp; public: - CSP_LoggerLine(int64_t line, int _level, QString _domain, QString time_s, QString s) { - mainstr = s; - linenum = line; - level = _level; - domain = _domain; - timestamp = time_s; - }; - ~CSP_LoggerLine() {}; - int64_t get_line_num(void) { - return linenum; - } - QString get_domain(void) { - return domain; - } - QString get_element_syslog(void) { - QString s; - if(domain.isEmpty()) { - s = timestamp + QString::fromUtf8(" ") + mainstr; - } else { - s = timestamp + QString::fromUtf8(" ") + domain + QString::fromUtf8(" ") + mainstr; - } - return s; - }; - QString get_element_console(void) { - QString s; - if(domain.isEmpty()) { - s = timestamp + QString::fromUtf8(" ") + mainstr; - } else { - s = timestamp + QString::fromUtf8(" ") + domain + QString::fromUtf8(" ") + mainstr; - } - return s; - }; - bool check_level(QString _domain, int _level) { - bool f = true; - if(!_domain.isEmpty()) { - if(_domain != domain) f = false; - } - if(_level >= 0) { - if(_level != level) { - f = false; - } - } - return f; - } + CSP_LoggerLine(int64_t line, int _level, QString _domain, QString time_s, QString s, double us = 0.0); + ~CSP_LoggerLine(); + int64_t get_line_num(void); + QString get_domain(void); + QString get_element_syslog(void); + QString get_element_console(void); + bool check_level(QString _domain, int _level); + bool contains(QString s, bool case_sensitive = false); + bool contains_mainstr(QString s, bool case_sensitive = false); + bool check_domain(QString s, bool case_sensitive = false); }; class QMutex; -class OSD; +class OSD_BASE; class DLL_PREFIX CSP_Log_ConsoleThread: public QThread { Q_OBJECT @@ -198,21 +163,22 @@ class DLL_PREFIX CSP_Logger: public QObject { QVector squeue; QMutex *lock_mutex; - OSD *p_osd; + OSD_BASE *p_osd; int max_devices; int max_cpus; protected: - + uint64_t get_vm_clocks(); + double get_vm_clocks_usec(); public: CSP_Logger(QObject *parent, bool b_syslog, bool cons, const char *devname); ~CSP_Logger(); - void set_osd(OSD *p) { p_osd = p; } + void set_osd(OSD_BASE *p) { p_osd = p; } void open(bool b_syslog, bool cons, const char *devname); void reset(void); - void debug_log(int level, const char *fmt, ...); - void debug_log(int level, int domain_num, const char *fmt, ...); - void debug_log(int level, int domain_num, char *strbuf); + void __FASTCALL debug_log(int level, const char *fmt, ...); + void __FASTCALL debug_log(int level, int domain_num, const char *fmt, ...); + void __FASTCALL debug_log(int level, int domain_num, char *strbuf); void close(void); void set_log_status(bool sw); void set_log_syslog(int level, bool sw); diff --git a/source/src/qt/gui/csp_qt_gui.ts b/source/src/qt/gui/csp_qt_gui.ts deleted file mode 100644 index 199aea7df..000000000 --- a/source/src/qt/gui/csp_qt_gui.ts +++ /dev/null @@ -1,2697 +0,0 @@ - - - - - CSP_DropDownJoysticks - - - Configure Joysticks - ジョイステックを設定する - - - - Configure Joystick to KEYBOARD - ジョイスティック→キーボード変換の設定 - - - - JoykeyDialog - - - Use 5 key to stop - <B>Use 5 key to stop</B> - テンキーの「5」でカーソルを止める - - - - Cursor keys - カーソルキー - - - - 2468 - 2468 - - - - 2468 + 1379 - 2468 + 1379 - - - - 1235 - 1235 - - - - Joykey Type: - <B>Joykey Type:</B> - ジョイスティック→キーボード 変換方式: - - - - Physical Buttons: - <B>Physical Buttons:</B> - 物理ボタン: - - - - JoystickDialog - - - <B>Physical Axis:</B> - <B>動かす軸</B> - - - - <B>Physical Buttons:</B> - <B>ボタン</B> - - - - KeySetDialog - - - <B>Define Keys</B> - <B>キーコード(VK_xxx)</B> - - - - <B>Scan Code</B> - <B>スキャンコード</B> - - - - Undefined - *未定義* - - - - Configure Keyboard - キーボードの設定 - - - - MainWindow - - Stop Recorded Sound - 録音停止 - - - Start Recording Sound - 録音開始する - - - Save Binary - バイナリを保存する - - - Load - ロード - - - Load memory image from a file. - メモリイメージをファイルから読み込みます。 - - - Save - セーブ - - - Save memory image to a file. - メモリイメージをファイルにセーブします。 - - - Recently Loaded - 最近ロードしたファイル - - - Cartridge - カートリッジ - - - Insert - さしこむ - - - Eject - 取り出す - - - Insert a cartridge image file. - カートリッジのイメージファイルを外します。 - - - Eject a cartridge image. - カートリッジイメージを取り出します。 - - - Recent Opened - 最近開いた物 - - - Save Tape - テープをサーブします - - - Insert CMT - テープを入れる - - - Insert a TAPE image file. - テープのイメージファイルを読み込みます。 - - - Eject CMT - テープを取り出す - - - Eject a TAPE image file. - テープのイメージファイルを取り出します。 - - - Enable Wave Shaper - Wave Shaper - - - Enable wave shaping. -Useful for some images. - 波形整形を行います。 -いくらかのイメージファイル等で効果があるでしょう。 - - - Direct load from MZT - MZTから直接読む - - - Direct loading to memory. -Only for MZT image file. - テープイメージから直接メモリに読み込みます。 -MZTファイルのみサポートしています。 - - - Cassette Tape - カセットテープ - - - Play Stop - 停止 - - - Play Start - 開始 - - - Fast Forward - 早送り - - - Rewind - 巻き戻し - - - APSS Forward - APSSで前に - - - APSS Rewind - APSSで後ろに - - - Record to a WAV File - WAVファイルに録音 - - - Record CMT output to a file. - マシンからテープに書かれる音声データを、WAVファイルに書き出します。 - - - Insert Compact Disc - CDを入れる - - - Insert a image file; CD-ROM or CD audio. - CDのイメージファイルを入れます。 -CD-ROMやCDなどです。 - - - Eject Compact Disc - CDを取り出す - - - Eject a compact disc. - CDを取り出します。 - - - CD ROM - CD ROM - - - Reset - リセット - - - Reset virtual machine. - 仮想マシンをリセットします。 - - - Exit Emulator - 終了 - - - Exit emulator. -**WARN: WITHOUT confirming.** - エミュレータを終了します。 -*注意:確認せずに終了します* - - - Speed x1 - 1倍 - - - Speed x2 - 2倍 - - - Speed x4 - 4倍 - - - Speed x8 - 8倍 - - - Speed x16 - 16倍 - - - Paste from Clipboard - クリップボードから貼り付け - - - Paste ANK text to virtual machine from desktop's clop board. - デスクトップのクリップボードにある、 -ANK(アルファベットと数字と半角カタカナ)のテキストを、 -仮想マシンにコピペします。 - - - Stop Pasting - 貼り付け中止 - - - Abort pasting ANK text to virtual machine. - 仮想マシンへのANKテキストの貼り付けを中止します。 - - - Save State - ステートを保存 - - - Save snapshot to fixed bin file. - 仮想マシンのスナップショットを定位置のbinファイルにセーブします。 - - - Load State - ステートロード - - - Load snapshot from fixed bin file. - 仮想マシンのスナップショットを定位置のbinファイルから読み込みます。 - - - Main CPU - メインCPU - - - Sub CPU - サブCPU - - - Debugger 3 - デバッガ3 - - - Debugger 4 - デバッガ4 - - - Debugger - デバッガ - - - Control - 操作 - - - State - ステート - - - Copy/Paste - コピペ - - - CPU Speed - CPU速度 - - - Grab MOUSE - マウスを取り込む - - - Grabbing host's mouse. -Press RIGHT Application key (or another) to toggle enable/disable. - ホスト側のマウスを取り込みます。 -右アプリケーション キー(もしくはその他)を押す度に、 -トグル動作します。 - - - Insert virtual floppy disk file. - 仮想フロッピーディスクファイルを挿入します。 - - - Eject virtual floppy disk. - 仮想フロッピーディスクを取り出します。 - - - Ignore CRC error - CRCエラー無視 - - - Ignore CRC error of virtual floppy. -Useful for some softwares, - but causes wrong working with some softwares. - 仮想ディスクイメージ上のCRCエラーを無視します。 -幾つかのソフトウェアで効果がありますが、 -他のソフトウェアではバグなどの問題の原因になるかもしれません。 - - - Correct transfer timing - 転送タイミング調整 - - - Correct transferring timing. -Useful for some softwares - needs strict transfer timing. - ディスクの転送タイミングを調整します。 -正確な転送タイミングが必要な、いくつかの -ソフトウェアでの不具合が解消するかもしれ -ません。 - - - - Insert Laserdisc - LDを入れる - - - Insert a MOVIE file. - LDのムービーを記録した動画ファイルを入れます。 - - - Eject Laserdisc - LDを取り出す - - - Eject a MOVIE file. - 動画ファイル(の仮想ディスク)を取り出します。 - - - Laserdisc - レーザディスク - - - Configure Joysticks - ジョイスティックの設定 - - - Configure assigning buttons/directions of joysticks. - ジョイスティックの方向やボタンの割当を設定します。 - - - ROMA-KANA Conversion - ローマ字かな変換 - - - Use romaji-kana conversion assistant of emulator. - エミュレータ上のローマ字かな変換を使用します。 - - - None - None - - - Emulator - エミュレータ - - - Focus on click - 画面クリックでフォーカス - - - If set, focus with click, not mouse-over. - 設定すると、マウスオーバーではなく、表示画面のクリックでフォーカスします。 - - - Configure Keyboard - キーボード設定 - - - Set addignation of keyboard. - キーの割当を設定します。 - - - Configure movie encoding - 動画保存設定 - - - Configure parameters of movie encoding. - 動画保存での、エンコーディングのパラメータを設定します。 - - - Log to Console - コンソールに記録 - - - Enable logging to STDOUT if checked. - チェックすると、標準出力にログが出ます。 - - - Log to Syslog - SYSLOGに記録 - - - Enable logging to SYSTEM log. -May be having permission to system and using *nix OS. - ホストのシステムログにログを記録します。 -ホスト上で記録できる権限があり、なおか -つ*nix OSでないと使えないかもしれません。 - - - Sound FDD Seek - FDシーク音を鳴らす - - - Enable FDD HEAD seeking sound. -Needs sound file. -See HELP->READMEs->Bios and Key assigns - フロッピーディスクのシーク音を鳴らします。 -音声ファイルが必要です。 -ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい - - - Sound CMT Relay - レコーダのリレー音を鳴らす - - - Enable CMT relay's sound. -Needs sound file. -See HELP->READMEs->Bios and Key assigns - データレコーダのリレー音を鳴らします。 -音声ファイルが必要です。 -ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい - - - Sound CMT Buttons - ボタン音を鳴らす - - - Enable CMT button's sound. -Needs sound file. -See HELP->READMEs->Bios and Key assigns - データレコーダのボタンの音を鳴らします。 -音声ファイルが必要です。 -ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい - - - Sound CMT Relay and Buttons - テープのリレーと音のボタンを鳴らす - - - Enable CMT relay's sound and buttons's sounds. -Needs sound file. -See HELP->READMEs->Bios and Key assigns - カセットテープレコーダのボタンの音と、リレーの音を鳴らします。 -音声ファイルが必要です。 -詳しくは、「ヘルプ」→「READMEs」→「BIOSとキー割り当て」の項目をお読みください。 - - - Per Device - デバイスごと - - - Video Platform(need restart) - 表示基盤(要再起動) - - - OpenGLv3.0 - OpenGL v3.0 - - - OpenGLv2.0 - OpenGL v2.0 - - - OpenGL(Core profile) - OpenGL(Core Profile) - - - Using OpenGL v3.0(MAIN). -This is recommanded. -If changed, need to restart this emulator. - OpenGLv3.0(メインプロファイル)で描画します。 -これを推奨します。 -変更した場合は、エミュレータの再起動が必要です。 - - - Using OpenGLv2. -This is fallback of some systems. -If changed, need to restart this emulator. - OpenGLv2.0で描画します。 -機能が劣りますが、幾つかのシステムでは代用とし -て、これが選択されるでしょう。 -変更した場合は、エミュレータの再起動が必要です。 - - - Using OpenGL core profile. -This still not implement. -If changed, need to restart this emulator. - OpenGLのCore Profileを使用します。 -まだ、実装されていません。 -変更した場合は、エミュレータの再起動が必要です。 - - - Show Virtual Medias. - 仮想メディアを表示する - - - None. - 表示しない - - - Upper. - 上に表示する - - - Lower. - 下に表示する - - - View Log - ログを見る - - - View emulator logs with a dialog. - エミュレータのログを、ダイアログで見ます。 - - - Help - ヘルプ - - - About Qt - Qtについて - - - Display Qt version. - Qtのヴァージョンを表示します。 - - - About... - このソフトについて... - - - About this emulator. - このエミュレータについて。 -クレジット表記などです。 - - - READMEs - READMEs - - - General Document - 総合的な文書 - - - About Qt ports - Qt移植版について(英語) - - - About Qt ports (Japanese). - Qt移植版について(日本語)。 - - - By Mr. Umaiboux. - Umaibouxさんによる文書 - - - By Mr. tanam - Tanamさんによる文書 - - - About eFM-7/8/77/AV. - eFM-7/8/77/AVについて。 - - - About eFM-7/8/77/AV (Japanese). - eFM-7/8/77/AVについて(日本語)。 - - - FAQs(English) - FAQs(英語) - - - FAQs(Japanese) - FAQs(日本語) - - - BIOS and Key assigns - BIOSとキー割り当てについて - - - Histories - 履歴・歴史 - - - General History - 全体の歴史 - - - Release Note - リリースノート - - - Change Log - チェンジログ - - - History by Tanam - Tanamさん部分の履歴 - - - Show License - ライセンス - - - Show general license (GPLv2). - ライセンスを読みます。GPL2です。 - - - Show License (Japanese) - ライセンス(日本語) - - - Show general license (GPLv2). -Translated to Japanese. - 日本語に翻訳されたライセンスを読みます(GPL2)。 - - - Machine - 仮想マシン - - - Device Type - デバイス - - - Sound Cards - サウンドカード - - - Drive Type - ドライブタイプ - - - Printer (Need RESET) - プリンタ(リセットが必要) - - - Dump to File - ファイルに書き込む - - - Dump printer output to file. -Maybe output only ascii text. - プリンタ出力をファイルに書き込みます。 -書き込まれるのは、多分、アスキーテキストだけです。 - - - Printer - プリンター - - - Not Connect - 未接続 - - - None devices connect to printer port. - プリンタポートに何も繋がってない状態です。 - - - Open - 開く- - - - Insert a virtual image file. - 仮想イメージファイルを入れます。 - - - Eject a inserted virtual image file. - 入れてあった仮想イメージファイルを取り出します。 - - - Write Protection - 書き込み保護 - - - On - オン - - - Enable write protection. -You can't write any data to this media. - 書き込み保護をします。 -このメディアには、如何なるデータも*書き込めません*。 - - - Off - オフ - - - Disable write protection. -You *can* write datas to this media. - 書き込み保護を解除します。 -このメディアには、データを書き込むことが出来ます。 - - - Select D88 Image - D88イメージ選択 - - - Recent opened - 最近開いたファイル - - - Zoom Screen - 画面ズーム - - - Display Mode - 表示モード - - - Software Scan Line - スキャンライン(ソフト) - - - Display scan line by software. - ソフトウェアでスキャンラインを表示します。 - - - Rotate Screen - 画面回転 - - - Rotate screen. - 画面を回転します。 - - - Software Filter - 画面フィルタ(ソフト) - - - Use display filter by software. - ソフトウェアの画面フィルタを使います。 - - - OpenGL Scan Line - スキャンライン(OpenGL) - - - Display scan line by OpenGL. - OpenGLのスキャンラインを表示します。 - - - OpenGL Pixel Line - ピクセルライン(OpenGL) - - - Display pixel line by OpenGL. - OpenGLのピクセルラインを表示します。 - - - OpenGL Filter - OpenGLフィルタ - - - Use display filter by OpenGL - OpenGLの画面フィルタを使用します(多少ぼやける) - - - Dot by Dot - ドット拡大なし - - - Keep Aspect: Refer to X - アスペクト比保存/横に合わせる - - - Keep Aspect: Refer to Y - アスペクト比保存/縦にあわせる - - - Keep Aspect: Fill - アスペクト比保存/画面を満たす - - - Stretch Mode - 拡大モード - - - Capture Screen - 画面取り込み - - - Capture screen to a PNG file. - 画面を、PNGファイルとして取り込みます。 - - - Screen - 画面 - - - Start Recording Movie - 動画記録開始 - - - Stop Recording Movie - 動画記録終了 - - - Record as Movie - 動画として記録する - - - Screen Size - 画面サイズ - - - Render Mode - 画面描画モード - - - Standard - 標準 - - - Standard render. - 通常のレンダラです。 - - - TV - TV - - - Rendering like tubed television with RF modulator. -Needs OpenGL 3.0 or later.Not effect with OpenGL 2.0. - 昔のブラウン管テレビにRFモジュレータを通して映したように表示します。 -OpenGL 3.0以上が必要です。 -OpenGL 2.0では無効です。 - - - Hz - Hz - - - mSec - mSec - - - Record sound as WAV file. - 音声をWAVファイルとして記録します。 - - - Play CMT sound - Sound CMT - カセットレコーダの音を出す - - - Enable sound of CMT TAPE recorder. - カセットテープレコーダに記録されている音を鳴らします。 - - - Strict Rendering - 厳密なレンダリング - - - Rendering per a sample.Select to slower, but accurate rendering sound. - 音声1サンプルごと(サンプルレートが44100Hzならば、1/44100秒ごと)に、 -音のレンダリングをします。これを選択すると動作が重くなる場合がありますが、 -音声のレンダリングが正確になります。 - - - Play sound from CMTs. - カセットレコーダの音を鳴らす - - - Sound - - - - Output Frequency - 出力周波数(サンプルレート) - - - Sound Latency - 音声(遅延)バッファサイズ - - - Set Volumes - 音量設定 - - - Open a VOLUME dialog. - 音量調整ダイアログを開きます。 - - - Binary - バイナリ - - - - Bubble - バブル - - - Floppy - フロッピーディスク - - - Quick Disk - クイックディスク - - - - MenuControl - - - Reset - リセット - - - - Reset virtual machine. - 仮想マシンをリセットします。 - - - - Exit Emulator - 終了 - - - - Exit emulator. -**WARN: WITHOUT confirming.** - エミュレータを終了します。 -*注意:確認せずに終了します* - - - - Speed x1 - 1倍速 - - - - Speed x2 - 2倍速 - - - - Speed x4 - 4倍速 - - - - Speed x8 - 8倍速 - - - - Speed x16 - 16倍速 - - - - Paste from Clipboard - クリップボードから貼り付け - - - - Paste ANK text to virtual machine from desktop's clop board. - デスクトップのクリップボードにある、 -ANK(アルファベットと数字と半角カタカナ)のテキストを、 -仮想マシンにコピペします。 - - - - Stop Pasting - 貼り付け中止 - - - - Abort pasting ANK text to virtual machine. - 仮想マシンへのANKテキストの貼り付けを中止します。 - - - - Save State - ステートを保存 - - - - Save snapshot to fixed bin file. - 仮想マシンのスナップショットを定位置のbinファイルにセーブします。 - - - - Load State - ステートロード - - - - Load snapshot from fixed bin file. - 仮想マシンのスナップショットを定位置のbinファイルから読み込みます。 - - - - Main CPU - メインCPU - - - - Sub CPU - サブCPU - - - - Debugger 3 - デバッガ3 - - - - Debugger 4 - デバッガ4 - - - - Debugger - デバッガ - - - - Control - 操作 - - - - State - ステート - - - - Copy/Paste - コピペ - - - - CPU Speed - CPU速度 - - - - Grab MOUSE - マウスを取り込む - - - - Grabbing host's mouse. -Press RIGHT Application key (or another) to toggle enable/disable. - ホスト側のマウスを取り込みます。 -右アプリケーション キー(もしくはその他)を押す度に、 -トグル動作します。 - - - - MenuEmulator - - - Configure Joysticks - ジョイスティックの設定 - - - - Configure assigning buttons/directions of joysticks. - ジョイスティックの方向やボタンの割当を設定します。 - - - - Configure Joystick to KEYBOARD - ジョイスティック→キーボード変換の設定 - - - - Configure assigning keycode to joystick buttons. -This feature using Joystick #1. - Configure assigning keycode to joystick buttons. - ジョイスティックからキーボードの変換を設定します。 -ジョイスティック1番が使用されます。 - - - - Joystick to KEYBOARD - ジョイスティックをキーボードに変換する - - - - Use Joystick axis/buttons to input keyboard. -This feature using Joystick #1. - Use Joystick axis/buttons to input keyboard. - ジョイスティックの方向とボタンでキーボードを入力します。 -ジョイスティック1番が使用されます。 - - - - ROMA-KANA Conversion - ローマ字かな変換 - - - - Use romaji-kana conversion assistant of emulator. - エミュレータ上のローマ字かな変換を使用します。 - - - - Emulate as FULL SPEED - 全速力でエミュレート - - - - Run emulation thread without frame sync. - フレーム同期を取らずに全速力でエミュレーションします。 - - - - Numpad's Enter is Fullkey's - テンキーのEnterをフルキーとみなす - - - - Numpad's enter key makes full key's enter. -Useful for some VMs. - テンキー側のEnterキーを押した時に、フルキーのEnterを出力します。 -いくつかのVMやいくつかの環境で有用なはずです。 - - - - Print Statistics - 統計を表示する - - - - Print statistics of CPUs (or some devices). -Useful for debugging. - CPU使用の統計を表示します。 -デバッグに有益なはずです。 - - - - FDC: Turn ON Debug log. - FDCのデバッグログを開始する。 - - - - Turn ON debug logging for FDCs.Useful to resolve issues from guest software. - FDCのデバッグログを取ります。 -ゲストで使用するソフトウェアの問題解決に役立つかも知れません。 - - - - Emulate cursor as - カーソルキーで - - - - Emulate cursor as ten-key. - カーソルキーでテンキーをエミュレートします。 - - - - None - テンキーエミュレートしない - - - - 2 4 6 8 - テンキーの「2 4 6 8」をエミュレート - - - - 1 2 3 5 - テンキーの「1 2 3 5 」をエミュレート - - - - Emulator - エミュレータ - - - - Focus on click - 画面クリックでウィンドウフォーカスを固定 - - - - If set, focus with click, not mouse-over. - 設定すると、マウスオーバーではなく、表示画面のクリックでフォーカスします。 - - - - Configure Keyboard - キーボードの設定 - - - - Set addignation of keyboard. - キーの割当を設定します。 - - - - Configure movie encoding - 動画保存設定 - - - - Configure parameters of movie encoding. - 動画保存での、エンコーディングのパラメータを設定します。 - - - - Log to Console - コンソールに記録 - - - - Enable logging to STDOUT if checked. - チェックすると、標準出力にログが出ます。 - - - - Log to Syslog - SYSLOGに記録 - - - - Enable logging to SYSTEM log. -May be having permission to system and using *nix OS. - ホストのシステムログにログを記録します。 -ホスト上で記録できる権限があり、なおか -つ*nix OSでないと使えないかもしれません。 - - - - Sound FDD Seek - FDシーク音を鳴らす - - - - Enable FDD HEAD seeking sound. -Needs sound file. -See HELP->READMEs->Bios and Key assigns - フロッピーディスクのシーク音を鳴らします。 -音声ファイルが必要です。 -ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい - - - - Sound CMT Relay and Buttons - テープのリレーと音のボタンを鳴らす - - - - Enable CMT relay's sound and buttons's sounds. -Needs sound file. -See HELP->READMEs->Bios and Key assigns - カセットレコーダーのリレーとボタンの音を再生します。 -サウンドファイルが必要です。 -HELP->READMEs->BIOSとキー割当 をお読み下さい。 - カセットテープレコーダのボタンの音と、リレーの音を鳴らします。 -音声ファイルが必要です。 -詳しくは、「ヘルプ」→「READMEs」→「BIOSとキー割り当て」の項目をお読みください。 - - - - - Per Device - デバイスごと - - - - Video Platform(need restart) - 画面表示基盤(要再起動) - - - - Occupy Fixed CPU - 固定CPUでエミュレーションを行う。 - - - - Using all CPU - 全CPUでエミュレーションする - - - - Using all CPU to emulation. -Reset cpu usings. - すべてのCPUでエミュレーションを分担します。 -CPU利用はリセットされます。 - - - - Set Fixed logical CPU #%1 to be occupied by emulation thread. -May useful for heavy VM (i.e. using i386 CPU). -Still implement LINUX host only, not another operating systems. - エミュレーションスレッドを、論理CPU #%1で固定します。 -重いVM(例えばi386C CPUを利用している)で便利かも知れません。 -この機能はまだ、LINUXでしか実装されていません。 - - - - OpenGL ES v2.0 - - - - - OpenGLv3.0 - OpenGL v3.0 - - - - OpenGLv2.0 - OpenGL v2.0 - - - - OpenGL(Core profile) - OpenGL(コアプロファイル) - - - - Using OpenGL ES v2.0. -This is recommanded. -If changed, need to restart this emulator. - OpenGL ES(v2.0)で描画します。 -この方法をおすすめします。 -変更した場合、エミュレータ自体の再起動が必要です。 - - - - Using OpenGL v3.0(MAIN). -This is recommanded. -If changed, need to restart this emulator. - OpenGLv3.0(メインプロファイル)で描画します。 -これを推奨します。 -変更した場合は、エミュレータの再起動が必要です。 - - - - Using OpenGLv2. -This is fallback of some systems. -If changed, need to restart this emulator. - OpenGLv2.0で描画します。 -機能が劣りますが、幾つかのシステムでは代用とし -て、これが選択されるでしょう。 -変更した場合は、エミュレータの再起動が必要です。 - - - - Using OpenGL core profile. -This still not implement. -If changed, need to restart this emulator. - OpenGLのCore Profileを使用します。 -まだ、実装されていません。 -変更した場合は、エミュレータの再起動が必要です。 - - - - Show Virtual Medias. - 仮想メディア一覧を表示する。 - 仮想メディアを表示する - - - - None. - 表示しない - 表示しない - - - - Upper. - 上側 - 上に表示する - - - - Lower. - 下側 - 下に表示する - - - - View Log - ログを見る - - - - View emulator logs with a dialog. - エミュレータのログを、ダイアログで見ます。 - - - - MenuHDD - - - Mount - マウントする - - - - Mount virtual hard disk file. - 仮想ハードディスクをつないでマウントします。 - - - - Unmount - はずす - - - - Unmount virtual hard disk. - 仮想ハードディスクを取り外します。 - - - - MenuHelp - - - Help - ヘルプ - - - - About Qt - Qtについて - - - - Display Qt version. - Qtのヴァージョンを表示します。 - - - - About... - このソフトについて... - - - - About this emulator. - このエミュレータについて。 -クレジット表記などです。 - - - - READMEs - READMEs - - - - General Document - 総合的な文書 - - - - About Qt ports - Qt移植版について(英語) - - - - About Qt ports (Japanese). - Qt移植版について(日本語)。 - - - - By Mr. Umaiboux. - Umaibouxさんによる文書 - Umaibouxさんによる文書 - - - - By Mr. tanam - Tanamさんによる文書 - - - - About eFM-7/8/77/AV. - eFM-7/8/77/AVについて。 - - - - About eFM-7/8/77/AV (Japanese). - eFM-7/8/77/AVについて(日本語)。 - - - - FAQs(English) - FAQs(英語) - - - - FAQs(Japanese) - FAQs(日本語) - - - - BIOS and Key assigns - BIOSとキー割り当てについて - - - - Histories - 履歴・歴史 - - - - General History - 全体の歴史 - - - - Release Note - リリースノート - - - - Change Log - チェンジログ - - - - History by Tanam - Tanamさん部分の履歴 - - - - Show License - ライセンス - - - - Show general license (GPLv2). - ライセンスを読みます。GPL2です。 - - - - Show License (Japanese) - ライセンス(日本語) - - - - Show general license (GPLv2). -Translated to Japanese. - 日本語に翻訳されたライセンスを読みます(GPL2)。 - - - - MenuMachine - - - Machine - 仮想マシン - - - - Device Type - デバイス - - - - Sound Cards - サウンドカード - - - - Drive Type - ドライブタイプ - - - - Printer (Need RESET) - プリンタ(リセットが必要) - - - - Dump to File - ファイルに書き込む - - - - Dump printer output to file. -Maybe output only ascii text. - プリンタ出力をファイルに書き込みます。 -書き込まれるのは、多分、アスキーテキストだけです。 - - - - Printer - プリンター - - - - Not Connect - 未接続 - - - - None devices connect to printer port. - プリンタポートに何も繋がってない状態です。 - - - - Monitor Type - ディスプレイのタイプ - - - - MenuMedia - - - Save Binary - バイナリを保存する - - - - Load - ロード - - - - Load memory image from a file. - メモリイメージをファイルから読み込みます。 - - - - Save - セーブ - - - - Save memory image to a file. - メモリイメージをファイルにセーブします。 - - - - Recently Loaded - 最近ロードしたファイル - - - - Cartridge - カートリッジ - カートリッジ - - - - - Insert - さしこむ - - - - - Eject - 取り出す - - - - Insert a cartridge image file. - カートリッジのイメージファイルを外します。 - - - - Eject a cartridge image. - カートリッジイメージを取り出します。 - - - - Recent Opened - 最近開いた物 - - - - Save Tape - テープをサーブします - - - - Insert CMT - テープを入れる - - - - Insert a TAPE image file. - テープのイメージファイルを読み込みます。 - - - - Eject CMT - テープを取り出す - - - - Eject a TAPE image file. - テープのイメージファイルを取り出します。 - - - - Enable Wave Shaper - Wave Shaper - - - - Enable wave shaping. -Useful for some images. - 波形整形を行います。 -いくらかのイメージファイル等で効果があるでしょう。 - - - - Direct load from MZT - MZTから直接読む - - - - Direct loading to memory. -Only for MZT image file. - テープイメージから直接メモリに読み込みます。 -MZTファイルのみサポートしています。 - - - - Cassette Tape - カセットテープ - - - - Play Stop - 停止 - - - - Play Start - 開始 - - - - Fast Forward - 早送り - - - - Rewind - 巻き戻し - - - - APSS Forward - APSSで前に - - - - APSS Rewind - APSSで後ろに - - - - Record to a WAV File - WAVファイルに録音 - - - - Record CMT output to a file. - マシンからテープに書かれる音声データを、WAVファイルに書き出します。 - - - - Insert Compact Disc - CDを入れる - - - - Insert a image file; CD-ROM or CD audio. - CDのイメージファイルを入れます。 -CD-ROMやCDなどです。 - - - - Eject Compact Disc - CDを取り出す - - - - Eject a compact disc. - CDを取り出します。 - - - - CD ROM - CD ROM - - - - Create D88/D77 virtual floppy - D88/D77形式の仮想フロッピーを作成する。 - - - - Insert virtual floppy disk file. - 仮想フロッピーディスクファイルを挿入します。 - - - - Eject virtual floppy disk. - 仮想フロッピーディスクを取り出します。 - - - - Ignore CRC error - CRCエラー無視 - - - - Ignore CRC error of virtual floppy. -Useful for some softwares, - but causes wrong working with some softwares. - 仮想ディスクイメージ上のCRCエラーを無視します。 -幾つかのソフトウェアで効果がありますが、 -他のソフトウェアではバグなどの問題の原因になるかもしれません。 - - - - Correct transfer timing - 転送タイミング調整 - - - - Correct transferring timing. -Useful for some softwares - needs strict transfer timing. - ディスクの転送タイミングを調整します。 -正確な転送タイミングが必要な、いくつかの -ソフトウェアでの不具合が解消するかもしれ -ません。 - - - - - Create Virtual Floppy - 仮想フロッピーの作成 - - - - Create and mount virtual blank-floppy disk. -This makes only D88/D77 format. - 仮想ブランクディスクを作成してマウントします。 -D88/D77形式の仮想ディスクのみ作成可能です。 - - - - Immediate increment - データカウンターを即時加算する - - - - Increment data pointer immediately. -This is test hack for MB8877. -Useful for some softwares - needs strict transfer timing. - データカウンターを即座に1足します。 -これは、MB8877 FDCで、転送タイミングを厳しくするHACKです。 - - - - Insert Laserdisc - LDを入れる - - - - Insert a MOVIE file. - LDのムービーを記録した動画ファイルを入れます。 - - - - Eject Laserdisc - LDを取り出す - - - - Eject a MOVIE file. - 動画ファイル(の仮想ディスク)を取り出します。 - - - - Laserdisc - レーザディスク - - - - Open - 開く- - - - - Insert a virtual image file. - 仮想イメージファイルを入れます。 - - - - Eject a inserted virtual image file. - 入れてあった仮想イメージファイルを取り出します。 - - - - Write Protection - 書き込み保護 - - - - On - オン - - - - Enable write protection. -You can't write any data to this media. - 書き込み保護をします。 -このメディアには、如何なるデータも*書き込めません*。 - - - - Off - オフ - - - - Disable write protection. -You *can* write datas to this media. - 書き込み保護を解除します。 -このメディアには、データを書き込むことが出来ます。 - - - - Select D88 Image - D88イメージ選択 - - - - Recent opened - 最近開いたファイル - - - - Binary - バイナリ - - - - FDD - FD - - - - Quick Disk - クイックディスク - クイックディスク - - - Connect virtual hard disk file. - 仮想ハードディスクを接続する - - - Disconnect virtual hard disk. - 仮想ハードディスクを取り外す - - - - HDD - HD - - - - Virtual FD type: - 仮想ディスク形式: - - - - Select type of virtual floppy. - 仮想フロッピーの種類を選択してください。 - - - - MenuScreen - - - Zoom Screen - 画面ズーム - - - - Display Mode - 表示モード - - - - Separate Draw (need restart) - 独立スレッドで描画(再起動が必要) - - - - Do drawing(rendering) sequence to separate thread. -If you feels emulator is slowly at your host-machine, disable this. -You should restart this emulator when changed. - 描画を独立したスレッドで行います。 -低速な場合に無効にすると効果があるかも知れません。 -変更したら、エミュレータを再起動して下さい。 - - - - - Display access Icons on screen. - アクセスランプのアイコンを表示する - アクセスアイコンを表示する - - - - Use icons on screen to display accessing virtual media(s). - 仮想メディアのアイコンを、アクセスランプとして表示します。 - - - - Software Scan Line - スキャンライン(ソフト) - - - - Display scan line by software. - ソフトウェアでスキャンラインを表示します。 - - - - Rotate Screen - 画面回転 - - - - Rotate screen. - 画面を回転します。 - - - - 0 deg - 0度 - - - - Not rotate screen. - 画面を回転<B>しません</B>。 - - - - 90 deg - 90度 - - - - Rotate screen to 90 deg. - 画面を時計回りに90度回転します。 - - - - 180 deg - 180度 - - - - Rotate screen to 180 deg. - 画面を時計回りに180度(<B>上下左右逆さに</B>)回転します。 - - - - 270 deg - 270度 - - - - Rotate screen to 270 deg. - 画面を時計回りに270度回転します。 - - - - OpenGL Scan Line - スキャンライン(OpenGL) - - - - Display scan line by OpenGL. - OpenGLのスキャンラインを表示します。 - - - - OpenGL Pixel Line - ピクセルライン(OpenGL) - - - - Display pixel line by OpenGL. - OpenGLのピクセルラインを表示します。 - - - - OpenGL Filter - OpenGLフィルタ - - - - Use display filter by OpenGL - OpenGLの画面フィルタを使用します(多少ぼやける) - - - - Dot by Dot - ドット拡大なし - - - - Keep Aspect: Refer to X - アスペクト比保存/横に合わせる - - - - Keep Aspect: Refer to Y - アスペクト比保存/縦にあわせる - - - - Keep Aspect: Fill - アスペクト比保存/画面を満たす - - - - Stretch Mode - 拡大モード - - - - Capture Screen - 画面取り込み - - - - Capture screen to a PNG file. - 画面を、PNGファイルとして取り込みます。 - - - - Screen - 画面 - - - - - Start Recording Movie - 動画記録開始 - - - - - Stop Recording Movie - 動画記録終了 - - - - Record as Movie - 動画として記録する - - - - Screen Size - 画面サイズ - - - - Render Mode - 画面描画モード - - - - Standard - 普通 - - - - Standard render. - 通常のレンダラです。 - - - - TV - TVっぽく - - - - Rendering like tubed television with RF modulator. -Needs OpenGL 3.0 or later.Not effect with OpenGL 2.0. - 昔のブラウン管テレビにRFモジュレータを通して映したように表示します。 -OpenGL 3.0以上が必要です。 -OpenGL 2.0では無効です。 - - - - MenuSound - - - Hz - Hz - - - - mSec - mSec - - - - Start Recording Sound - 録音開始する - - - - Record sound as WAV file. - 音声をWAVファイルとして記録します。 - - - - Strict Rendering - 厳密なレンダリング - - - - Rendering per a sample.Select to slower, but accurate rendering sound. - 音声1サンプルごと(サンプルレートが44100Hzならば、1/44100秒ごと)に、 -音のレンダリングをします。これを選択すると動作が重くなる場合がありますが、 -音声のレンダリングが正確になります。 - - - - Play CMT sound - カセットレコーダの音を出す - - - - Play sound from CMTs. - カセットレコーダの音を鳴らす - - - - Output to: - 音の出力先: - - - - Select sound device to output. -This effects after re-start this emulator. - 音を出すデバイスを選択します。 -デバイス選択後はエミュレータを再起動すると有効に出来ます。 - - - - Sound - - - - - Output Frequency - 出力周波数(サンプルレート) - - - - Sound Latency - 音声(遅延)バッファサイズ - - - - Set Volumes - 音量設定 - - - - Open a VOLUME dialog. - 音量調整ダイアログを開きます。 - - - - MovieDialog - - - General - 総合 - - - - H.264 - H.264 - - - - MPEG4v1 - MPEG4v1 - - - - Set movie codecs. - 動画のコーデックを設定します。 - - - - Cancel - 戻る - - - - Save Options - 設定を保存する - - - - MovieTabGeneral - - - Video Codec - ビデオコーデック - - - - MPEG4 will make larger and lower quality file. -But very fast. -H.264 will make smaller and better quality file. -But very slowly. -**Note: Movie file is using MP4 container, not AVI.** - MPEG4はファイルサイズが大きく、画質も良くないですが、非常に速くエンコードします。 -H.264はファイルサイズが小さく、画質も良く出来ますが、非常に遅いエンコードです。 -**注意:動画ファイルは、MP4コンテナに記録されます。AVIではありません。** - - - - Resolution - 解像度 - - - - Set resolution of encoded movie file. - エンコードする動画の大きさを設定します。 - - - - Video Threads - ビデオスレッド数 - - - - Set number of threads used by H.264 movie endcoding. - H.264エンコーディングで使用するスレッド数を設定します。 - - - - Audio Bitrate - 音声ビットレート - - - - Audio Codec - 音声コーデック - - - - Set codec of audio. -MP3 is using LAME. -AAC is experimental; using libAV's AAC encoder. - 音声コーデックを設定します。 -MP3は標準的なコーデックで、LAMEを使用しています。 -AACは実験的なコーデックで、 -libAVのAACコーデックを使用しています。 - - - - Framerate - フレームレート - - - - MovieTabH264 - - - Max B Frames - 最大Bフレーム数 - - - - B Adaption - B Adaption - - - - Subpixel motion estimate - サブピクセル動き予測 - - - - Bitrate - ビットレート - - - - Set bitrate of video. -Larger is better quality, but makes larger file. - ビデオのビットレートを設定します。 -大きな値は画質が良くなりますが、ファイルサイズも大きくなってしまいます。 - - - - Max numbers of B FRAMEs. -Larger value will make smaller file, but slowly. - Bフレームの最大数を設定します。 -大きな値は小さなファイルにすることが期待できますが、 -エンコードが遅くなります。 - - - - None - None - - - - Fast - Fast - - - - Optimal (Slow with high B-Frames) - Optimal(Bフレームが多い場合に、遅くなる) - - - - Set decision of using B FRAMEs. - Bフレームにするかどうかの判断基準を設定します。 - - - - Minimum Quant. -Smaller value is better quality, but making larger file. -Larger value is dirty picture, but making smaller file. -15 to 24 is recommended. - 最小Quant。 -小さな値は画質が良くなりますが、大きなファイルを作ってしまいます。 -大きな値は画質が悪くなる代わりに、小さなファイルが作れます。 -15~24がオススメです。 - - - - Maximum Quant. -Smaller value is better quality, but making larger file. -Larger value is dirty picture, but making smaller file. -20 to 28 is recommended. - 最大Quant。 -小さな値は画質が良くなりますが、大きなファイルを作ってしまいます。 -大きな値は画質が悪くなる代わりに、小さなファイルが作れます。 -20~28がオススメです。 - - - - RD mode decision for I/P-frames - RD mode decision for I/P-frames - - - - RD mode decision for all frames - RD mode decision for all frames - - - - RD refinement for I/P-frames - RD refinement for I/P-frames - - - - RD refinement for all frames - RD refinement for all frames - - - - QP-RD - QP-RD - - - - Full RD: disable all early terminations - 最大Bフレーム - - - - Set motion estimation. -Larger value is better, but slowly. - 動き予測を設定します。 -大きな値が良いのですが、遅くなります。 - - - - Set H.264 parameter. - H.264のパラメータを設定します。 - - - - MovieTabMPEG4 - - - Max B Frames - 最大Bフレーム数 - - - - Bitrate - ビットレート - - - - Set MPEG4v1 parameter. - MPEG4v1のエンコード設定をします。 - - - - SoundMenu - - - Stop Recorded Sound - 録音停止する - - - - Start Recording Sound - 録音開始する - - - - Ui_SoundDialog - - - - Set Volume - 音量設定 - - - - Main - メイン - - - - Reset to center. - 真ん中に戻す。 - - - - Volume - 音量 - - - - Balance - バランス - - - - main - - - Custom home directory. - ホームディレクトリを指定する - - - - Custom config file (without path). - 設定ファイルの名前を指定する(相対パス) - - - - Custom config directory. - 設定ファイルのあるディレクトリを指定する - - - - Custom resource directory (ROMs, WAVs, etc). - ROMやWAVなどのリソースディレクトリを指定する - - - - Turn on <onbit> of dip switch. - DIPSWの<onbit>を"1"にする - - - - Turn off <offbit> of dip switch. - DIPSWの<onbit>を"0"にする - - - - Force set using renderer type. - 表示レンダラのタイプを強制的に決める - - - - Set / Delete environment variable. - 環境変数を設定/削除する - - - - Dump environment variables. - 環境変数をダンプする - - - diff --git a/source/src/qt/gui/dialog_memory.cpp b/source/src/qt/gui/dialog_memory.cpp new file mode 100644 index 000000000..5f167e088 --- /dev/null +++ b/source/src/qt/gui/dialog_memory.cpp @@ -0,0 +1,103 @@ +/* + * Common Source Project/ Qt + * (C) 2015 K.Ohta + * Qt: Menu->Emulator->Define Strings + * History: Feb 24, 2016 : Initial + */ + +#include "dialog_memory.h" + +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "menu_flags.h" + +CSP_MemoryDialog::CSP_MemoryDialog(USING_FLAGS *p, QWidget *parent) : QWidget(parent) +{ + p_wid = parent; + using_flags = p; + p_config = NULL; + _min = -1; + _max = -1; + current_val = -1; + layout = new QGridLayout(this); + label_head = new QLabel(QApplication::translate("MemorySetDialog", "Memory Size", 0)); + layout->addWidget(label_head); + + spin_ram = new QSpinBox(this); + current_val = -1; + + if(p != NULL) { + p_config = p->get_config_ptr(); + order = p->get_ram_size_order(); + _max = p->get_max_ram_size(); + _min = p->get_min_ram_size(); + current_val = p_config->current_ram_size; + } + QString orderstring; + spin_ram->setEnabled(true); + if((order == 0) || (_max < 0) || (_min < 0)) { + spin_ram->setEnabled(false); + orderstring = QString::fromUtf8(""); + } else if(order < 1024) { + orderstring = QString::fromUtf8("x %1Bytes").arg(order); + } else if(order == 1024) { + orderstring = QString::fromUtf8("KBytes"); + } else if(order < (1024 * 1024)) { + orderstring = QString::fromUtf8("x %1KBytes").arg(order); + } else if(order == (1024 * 1024)) { + orderstring = QString::fromUtf8("MBytes"); + } else { + orderstring = QString::fromUtf8("x %1MBytes").arg(order); + } + order_label = new QLabel(orderstring); + if(_max < _min) _min = _max; + if(current_val > _max) current_val = _max; + if(current_val < _min) current_val = _min; + + spin_ram->setMaximum(_max); + spin_ram->setMinimum(_min); + spin_ram->setValue(current_val); + + reset_button = new QPushButton(QApplication::translate("MemoryDialog", "Reset", 0)); + cancel_button = new QPushButton(QApplication::translate("MemoryDialog", "Cancel", 0)); + close_button = new QPushButton(QApplication::translate("MemoryDialog", "Save Options", 0)); + + connect(close_button, SIGNAL(clicked()), this, SLOT(do_set_value())); + connect(close_button, SIGNAL(clicked()), this, SLOT(do_reset_value())); + connect(cancel_button, SIGNAL(clicked()), this, SLOT(close())); + + layout->addWidget(label_head, 0, 0); + layout->addWidget(spin_ram, 1, 0); + layout->addWidget(order_label, 1, 2); + layout->addWidget(reset_button, 3, 0); + layout->addWidget(cancel_button, 3, 2); + layout->addWidget(close_button, 3, 3); + this->setLayout(layout); +} + +CSP_MemoryDialog::~CSP_MemoryDialog() +{ +} +void CSP_MemoryDialog::do_set_value() +{ + if(p_config != NULL) { + int val = spin_ram->value(); + if(val < _min) val = _min; + if(val > _max) val = _max; + if(val < 0) val = 0; + p_config->current_ram_size = val; + // Update config? + } + close(); +} + +void CSP_MemoryDialog::do_reset_value() +{ + spin_ram->setValue(current_val); +} diff --git a/source/src/qt/gui/dialog_memory.h b/source/src/qt/gui/dialog_memory.h new file mode 100644 index 000000000..ed7829c82 --- /dev/null +++ b/source/src/qt/gui/dialog_memory.h @@ -0,0 +1,45 @@ + +#pragma once + +#include + +class QGridLayout; +class QLabel; +class QSpinBox; +class QLabel; +class QPushButton; + +#include "../../config.h" +class USING_FLAGS; + +QT_BEGIN_NAMESPACE +class CSP_MemoryDialog : public QWidget { + Q_OBJECT +protected: + config_t* p_config; + USING_FLAGS* using_flags; + QWidget *p_wid; + + int _min; + int _max; + int current_val; + uint32_t order; + + QGridLayout *layout; + QLabel *label_head; + QSpinBox *spin_ram; + QLabel *order_label; + + QPushButton *reset_button; + QPushButton *cancel_button; + QPushButton *close_button; + +public: + CSP_MemoryDialog(USING_FLAGS *p, QWidget *parent); + ~CSP_MemoryDialog(); + +public slots: + void do_set_value(); + void do_reset_value(); +}; +QT_END_NAMESPACE diff --git a/source/src/qt/gui/display_about.cpp b/source/src/qt/gui/display_about.cpp index 769ac3dc8..4ec8104fc 100644 --- a/source/src/qt/gui/display_about.cpp +++ b/source/src/qt/gui/display_about.cpp @@ -18,7 +18,7 @@ //extern USING_FLAGS *using_flags; -Dlg_AboutCSP::Dlg_AboutCSP(USING_FLAGS *p, QWidget *parent) : QWidget(NULL) +Dlg_AboutCSP::Dlg_AboutCSP(USING_FLAGS *p, QString rendererString, QWidget *parent) : QWidget(NULL) { QByteArray tmps; QFile f_credits(":/credits.html"); @@ -33,7 +33,9 @@ Dlg_AboutCSP::Dlg_AboutCSP(USING_FLAGS *p, QWidget *parent) : QWidget(NULL) using_flags = p; // Credits credits.clear(); - printf("%x\n",parent_widget); + renderer = rendererString; + +// printf("%x\n",parent_widget); if(f_credits.open(QIODevice::ReadOnly | QIODevice::Text)) { tmps = f_credits.readAll(); if(!tmps.isEmpty()) { @@ -55,6 +57,11 @@ Dlg_AboutCSP::Dlg_AboutCSP(USING_FLAGS *p, QWidget *parent) : QWidget(NULL) if(ni >= 0) { ns.replace(ni, reps.length(), bs); } + reps = QString::fromUtf8("@@RendererType@@"); + ni = ns.indexOf(reps); + if(ni >= 0) { + ns.replace(ni, reps.length(), renderer); + } credits = ns; } diff --git a/source/src/qt/gui/display_about.h b/source/src/qt/gui/display_about.h index a8bc1fc9d..1b0b7b713 100644 --- a/source/src/qt/gui/display_about.h +++ b/source/src/qt/gui/display_about.h @@ -13,12 +13,12 @@ #include #include #include +#include #include "common.h" QT_BEGIN_NAMESPACE class USING_FLAGS; -class EMU; class Ui_MainWindowBase; class DLL_PREFIX Dlg_AboutCSP : public QWidget { @@ -34,8 +34,9 @@ class DLL_PREFIX Dlg_AboutCSP : public QWidget QLabel *revarea; QWidget *BoxTitle; QVBoxLayout *VBox; + QString renderer; public: - Dlg_AboutCSP(USING_FLAGS *p, QWidget *parent = 0); + Dlg_AboutCSP(USING_FLAGS *p, QString rendererString = QString::fromUtf8(""), QWidget *parent = 0); ~Dlg_AboutCSP(); }; diff --git a/source/src/qt/gui/dock_disks.cpp b/source/src/qt/gui/dock_disks.cpp index 40dee8e0c..ac2a9bc7b 100644 --- a/source/src/qt/gui/dock_disks.cpp +++ b/source/src/qt/gui/dock_disks.cpp @@ -64,7 +64,9 @@ CSP_LabelVirtualDevice::CSP_LabelVirtualDevice(QWidget *parent, HBox->addWidget(Message); HBox->setContentsMargins(0, 0, 0, 0); this->setLayout(HBox); - + setAttribute(Qt::WA_AlwaysShowToolTips, true); + mediaFileName = QApplication::translate("CSP_LabelVirtualDevice", ("**BLANK**"), 0); + this->setToolTip(mediaFileName); //this->setGeometry(0, 0, this->width(), _height); } @@ -318,7 +320,7 @@ CSP_DockDisks::CSP_DockDisks(QWidget *parent, USING_FLAGS *p) : QWidget(parent) _wmod = 0; } for(int i = 0; i < using_flags->get_max_hdd(); i++) { - pHardDisk[i] = new CSP_LabelVirtualDevice(this, 12, font_pt, QString::fromUtf8("HD"), i); + pHardDisk[i] = new CSP_LabelVirtualDevice(this, 4, font_pt, QString::fromUtf8("HD"), i); pHardDisk[i]->setVisible(true); } int _xtmp = _x; @@ -435,6 +437,77 @@ void CSP_DockDisks::updateLabel(int dom, int localnum, QString str) } } +void CSP_DockDisks::updateMediaFileName(int dom, int localnum, QString filename) +{ + switch(dom) { + case CSP_DockDisks_Domain_Binary: + if((localnum < 8) && (localnum >= 0)) { + if(pBinary[localnum] != NULL) { + pBinary[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_Bubble: + if((localnum < 8) && (localnum >= 0)) { + if(pBubble[localnum] != NULL) { + pBubble[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_Cart: + if((localnum < 8) && (localnum >= 0)) { + if(pCart[localnum] != NULL) { + pCart[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_CMT: + if((localnum < 2) && (localnum >= 0)) { + if(pCMT[localnum] != NULL) { + pCMT[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_CD: + if((localnum < 2) && (localnum >= 0)) { + if(pCompactDisc[localnum] != NULL) { + pCompactDisc[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_FD: + if((localnum < 8) && (localnum >= 0)) { + if(pFloppyDisk[localnum] != NULL) { + pFloppyDisk[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_HD: + if((localnum < 8) && (localnum >= 0)) { + if(pHardDisk[localnum] != NULL) { + pHardDisk[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_LD: + if((localnum < 2) && (localnum >= 0)) { + if(pLaserDisc[localnum] != NULL) { + pLaserDisc[localnum]->setMediaFileName(filename); + } + } + break; + case CSP_DockDisks_Domain_QD: + if((localnum < 2) && (localnum >= 0)) { + if(pQuickDisk[localnum] != NULL) { + pQuickDisk[localnum]->setMediaFileName(filename); + } + } + break; + default: + break; + } +} + void CSP_DockDisks::updateMessage(int dom, int localnum, QString str) { switch(dom) { @@ -619,3 +692,13 @@ void CSP_DockDisks::setScreenWidth(int width) this->setGeometry(0, 0, now_width, now_height); } +void CSP_LabelVirtualDevice::setMediaFileName(QString filename) +{ + if(filename.size() < 1) { + mediaFileName = QApplication::translate("CSP_LabelVirtualDevice", ("**BLANK**"), 0); + } else { + mediaFileName = filename; + } + this->setToolTip(mediaFileName); +} + diff --git a/source/src/qt/gui/dock_disks.h b/source/src/qt/gui/dock_disks.h index 9b43c9d7a..c7cfdf1c2 100644 --- a/source/src/qt/gui/dock_disks.h +++ b/source/src/qt/gui/dock_disks.h @@ -49,6 +49,7 @@ class CSP_LabelVirtualDevice : public QWidget { int _now_height; float _now_pt; int local_num; + QString mediaFileName; public: CSP_LabelVirtualDevice(QWidget *parent = 0, int width = 6, float point = 12.0f, @@ -68,6 +69,7 @@ public slots: void setScreenWidth(int width, int basewidth); void setPixmapLabel(QPixmap p); void setPixmapIndicator(QPixmap p); + void setMediaFileName(QString filename); }; class CSP_DockDisks : public QWidget { @@ -101,6 +103,7 @@ public slots: void setPixmap(int dom, int localNum, const QPixmap &); void setOrientation(int loc); void setScreenWidth(int width); + void updateMediaFileName(int dom, int localnum, QString filename); }; QT_END_NAMESPACE diff --git a/source/src/qt/gui/draw_thread.cpp b/source/src/qt/gui/draw_thread.cpp index 8c388160b..1d82b1da6 100644 --- a/source/src/qt/gui/draw_thread.cpp +++ b/source/src/qt/gui/draw_thread.cpp @@ -15,10 +15,10 @@ #include #include #include +#include -#include -#include "emu.h" -#include "osd.h" +#include "emu_template.h" +#include "osd_base.h" #include "vm/vm.h" #include "qt_main.h" @@ -29,7 +29,7 @@ #include "config.h" -DrawThreadClass::DrawThreadClass(OSD *o, CSP_Logger *logger,QObject *parent) : QThread(parent) { +DrawThreadClass::DrawThreadClass(OSD_BASE *o, CSP_Logger *logger,QObject *parent) : QThread(parent) { MainWindow = (Ui_MainWindowBase *)parent; glv = MainWindow->getGraphicsView(); p_osd = o; @@ -38,7 +38,6 @@ DrawThreadClass::DrawThreadClass(OSD *o, CSP_Logger *logger,QObject *parent) : Q if(p_osd != NULL) using_flags = p_osd->get_config_flags(); screen = QGuiApplication::primaryScreen(); - is_shared_glcontext = false; glContext = NULL; draw_screen_buffer = NULL; @@ -88,10 +87,21 @@ DrawThreadClass::~DrawThreadClass() } -void DrawThreadClass::SetEmu(EMU *p) +void DrawThreadClass::do_start_draw_thread(void) +{ + bool _separate = false; + if(using_flags->get_config_ptr() != NULL) { + if(using_flags->get_config_ptr()->use_separate_thread_draw) { + _separate = true; + } + } + if(_separate) start(QThread::HighPriority); +} + +void DrawThreadClass::SetEmu(EMU_TEMPLATE *p) { //p_emu = p; - p_osd = p->get_osd(); + p_osd = (OSD_BASE*)(p->get_osd()); } void DrawThreadClass::do_set_frames_per_second(double fps) @@ -113,7 +123,6 @@ void DrawThreadClass::doDrawMain(bool flag) draw_frames = p_osd->no_draw_screen(); } //req_unmap_screen_texture(); - emit sig_draw_frames(draw_frames); } void DrawThreadClass::doDraw(bool flag) @@ -122,7 +131,11 @@ void DrawThreadClass::doDraw(bool flag) if(!use_separate_thread_draw) { doDrawMain(flag); } else { - if(renderSemaphore != NULL) renderSemaphore->release(1); + if(renderSemaphore != NULL) { + if(renderSemaphore->available() < 1) { + renderSemaphore->release(1); + } + } } } @@ -159,25 +172,48 @@ void DrawThreadClass::doWork(const QString ¶m) bRunThread = true; double _rate = 1000.0 / 30.0; bDrawReq = false; - if(renderSemaphore == NULL) goto __exit; + QElapsedTimer tick_timer; + tick_timer.start(); + quint64 elapsed = (quint64)_rate; + double drate; + double vrate; + bool rendered = false; + if(renderSemaphore == NULL) { + QSemaphore *s = new QSemaphore(0); + if(s == NULL) goto __exit; + renderSemaphore = s; + } do { + double __fps = p_osd->vm_frame_rate(); // FPS; + vrate = 1.0e3 / __fps; // to Msec _rate = (wait_refresh < emu_frame_rate) ? emu_frame_rate : wait_refresh; - if(_rate < 2.0) { - wait_factor = 2.0; - } else { - wait_factor = (int)_rate - 1; - } + if((vrate * 2.0) > _rate) _rate = vrate * 2.0; + drate = (double)elapsed / 1.0e6; // nsec to msec + wait_factor = (int)nearbyint(_rate); +// if(_rate >= drate) { +// wait_factor = (int)nearbyint(_rate - drate) + ; +// } else { +// wait_factor = (int)_rate; +// } +// msleep(1); if(renderSemaphore->tryAcquire(1, wait_factor)) { // Success - if(!bRunThread) break; + if(!bRunThread) goto __exit; volatile bool _b = bRecentRenderStatus; bRecentRenderStatus = false; doDrawMain(_b); - } - if(!bRunThread) break; + rendered = true; + } else { + rendered = false; + } + /*printf("RATE:%f VM_RATE:%f ELAPSED:%f WAIT_FACTOR:%d RENDER=%s\n", _rate, vrate, drate, wait_factor, + (rendered) ? "YES" : "NO");*/ + if(!bRunThread) goto __exit; volatile bool _d = bDrawReq; if(draw_screen_buffer == NULL) _d = false; if((_d) && (draw_screen_buffer != NULL)) bDrawReq = false; do_draw_one_turn(_d); + elapsed = tick_timer.nsecsElapsed(); + tick_timer.start(); } while(bRunThread); __exit: csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GENERAL, diff --git a/source/src/qt/gui/draw_thread.h b/source/src/qt/gui/draw_thread.h index aae8f88db..d1664f2d9 100644 --- a/source/src/qt/gui/draw_thread.h +++ b/source/src/qt/gui/draw_thread.h @@ -17,8 +17,8 @@ #include "qt_gldraw.h" class Ui_MainWindowBase; -class EMU; -class OSD; +class EMU_TEMPLATE; +class OSD_BASE; class CSP_Logger; class QSemaphore; class QScreen; @@ -30,7 +30,7 @@ QT_BEGIN_NAMESPACE class DLL_PREFIX DrawThreadClass : public QThread { Q_OBJECT private: - OSD *p_osd; + OSD_BASE *p_osd; Ui_MainWindowBase *MainWindow; GLDrawClass *glv; @@ -65,14 +65,15 @@ class DLL_PREFIX DrawThreadClass : public QThread { bool mapped_drawn; void doDrawMain(bool flag); public: - DrawThreadClass(OSD *o, CSP_Logger *logger, QObject *parent = 0); + DrawThreadClass(OSD_BASE *o, CSP_Logger *logger, QObject *parent = 0); ~DrawThreadClass(); QSemaphore *renderSemaphore; QSemaphore *textureMappingSemaphore; void run() { doWork("");} - void SetEmu(EMU *p); + void SetEmu(EMU_TEMPLATE *p); public slots: + void do_start_draw_thread(void); void doWork(const QString &); void doExit(void); void doDraw(bool flag); diff --git a/source/src/qt/gui/emu_thread_tmpl.cpp b/source/src/qt/gui/emu_thread_tmpl.cpp index 661b7239d..8f2b83252 100644 --- a/source/src/qt/gui/emu_thread_tmpl.cpp +++ b/source/src/qt/gui/emu_thread_tmpl.cpp @@ -22,6 +22,7 @@ #include "mainwidget_base.h" #include "qt_gldraw.h" #include "common.h" +#include "dock_disks.h" //#include "../../romakana.h" @@ -30,9 +31,11 @@ EmuThreadClassBase::EmuThreadClassBase(Ui_MainWindowBase *rootWindow, USING_FLAGS *p, QObject *parent) : QThread(parent) { MainWindow = rootWindow; + bBlockTask = true; using_flags = p; p_config = p->get_config_ptr(); - + p_emu = NULL; + p_osd = NULL; is_shared_glcontext = false; glContext = NULL; @@ -44,7 +47,7 @@ EmuThreadClassBase::EmuThreadClassBase(Ui_MainWindowBase *rootWindow, USING_FLAG } if(glContext->isValid()) { is_shared_glcontext = true; - printf("Context sharing succeeded.ADDR=%08x GLES=%s\n", glContext, (glContext->isOpenGLES()) ? "YES" : "NO"); +// printf("Context sharing succeeded.ADDR=%08x GLES=%s\n", glContext, (glContext->isOpenGLES()) ? "YES" : "NO"); } bRunThread = true; @@ -257,9 +260,25 @@ void EmuThreadClassBase::do_reset() bResetReq = true; } -void EmuThreadClassBase::do_special_reset() +void EmuThreadClassBase::do_unblock() { + bBlockTask = false; +} + +void EmuThreadClassBase::do_block() +{ + bBlockTask = true; +} +void EmuThreadClassBase::do_start_emu_thread() +{ + start(QThread::TimeCriticalPriority); +} +void EmuThreadClassBase::do_special_reset(int num) +{ + if(num < 0) return; + if(num >= using_flags->get_use_special_reset_num()) return; bSpecialResetReq = true; + specialResetNum = num; } void EmuThreadClassBase::do_load_state(QString s) @@ -327,23 +346,32 @@ int EmuThreadClassBase::parse_command_queue(QStringList _l, int _begin) fileInfo = QFileInfo(_file.right(_file.size() - (_n + 1))); } else { fileInfo = QFileInfo(_file); + _slot = 0; } } else { fileInfo = QFileInfo(_file); + _slot = 0; } if(fileInfo.isFile()) { const _TCHAR *path_shadow = (const _TCHAR *)(fileInfo.absoluteFilePath().toLocal8Bit().constData()); if(_dom_type == QString::fromUtf8("vFloppyDisk")) { - emit sig_open_fd(_dom_num, fileInfo.absoluteFilePath()); if(check_file_extension(path_shadow, ".d88") || check_file_extension(path_shadow, ".d77")) { - emit sig_set_d88_num(_dom_num, _slot); + emit sig_open_d88_fd(_dom_num, fileInfo.absoluteFilePath(), _slot); + emit sig_change_virtual_media(CSP_DockDisks_Domain_FD, _dom_num, fileInfo.absoluteFilePath());; + } else { + emit sig_open_fd(_dom_num, fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_FD, _dom_num, fileInfo.absoluteFilePath());; } } else if(_dom_type == QString::fromUtf8("vHardDisk")) { emit sig_open_hdd(_dom_num, fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, _dom_num, fileInfo.absoluteFilePath());; } else if(_dom_type == QString::fromUtf8("vBubble")) { - emit sig_open_bubble(_dom_num, fileInfo.absoluteFilePath()); if(check_file_extension(path_shadow, ".b77")) { - emit sig_set_b77_num(_dom_num, _slot); + emit sig_open_b77_bubble(_dom_num, fileInfo.absoluteFilePath(), _slot); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, _dom_num, fileInfo.absoluteFilePath());; + } else { + emit sig_open_bubble(_dom_num, fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Bubble, _dom_num, fileInfo.absoluteFilePath());; } } } @@ -352,18 +380,24 @@ int EmuThreadClassBase::parse_command_queue(QStringList _l, int _begin) if(fileInfo.isFile()) { if(_dom_type == QString::fromUtf8("vQuickDisk")) { emit sig_open_quick_disk(_dom_num, fileInfo.absoluteFilePath()); - } else if(_dom_type == QString::fromUtf8("vCmt")) { + emit sig_change_virtual_media(CSP_DockDisks_Domain_QD, _dom_num, fileInfo.absoluteFilePath());; + } else if(_dom_type == QString::fromUtf8("vCmt")) { emit sig_open_cmt_load(_dom_num, fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_CMT, _dom_num, fileInfo.absoluteFilePath());; } else if(_dom_type == QString::fromUtf8("vBinary")) { emit sig_open_binary_load(_dom_num, fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Binary, _dom_num, fileInfo.absoluteFilePath());; } else if(_dom_type == QString::fromUtf8("vCart")) { emit sig_open_cart(_dom_num, fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_Cart, _dom_num, fileInfo.absoluteFilePath());; } else if(_dom_type == QString::fromUtf8("vLD")) { vMovieQueue.append(_dom); vMovieQueue.append(fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_LD, _dom_num, fileInfo.absoluteFilePath());; //emit sig_open_laser_disc(_dom_num, fileInfo.absoluteFilePath()); } else if(_dom_type == QString::fromUtf8("vCD")) { emit sig_open_cdrom(_dom_num, fileInfo.absoluteFilePath()); + emit sig_change_virtual_media(CSP_DockDisks_Domain_CD, _dom_num, fileInfo.absoluteFilePath());; } } } @@ -374,36 +408,12 @@ int EmuThreadClassBase::parse_command_queue(QStringList _l, int _begin) return _ret; } -const _TCHAR *EmuThreadClassBase::get_emu_message(void) -{ - static const _TCHAR str[] = ""; - return (const _TCHAR *)str; -} - -double EmuThreadClassBase::get_emu_frame_rate(void) -{ - return 30.00; -} -int EmuThreadClassBase::get_message_count(void) -{ - return 0; -} - -void EmuThreadClassBase::dec_message_count(void) -{ - -} const _TCHAR *EmuThreadClassBase::get_device_name(void) { return (const _TCHAR *)_T("TEST"); } -bool EmuThreadClassBase::get_power_state(void) -{ - return true; -} - void EmuThreadClassBase::print_framerate(int frames) { if(frames >= 0) draw_frames += frames; @@ -417,11 +427,11 @@ void EmuThreadClassBase::print_framerate(int frames) //int ratio = (int)(100.0 * (double)draw_frames / (double)total_frames + 0.5); if(get_power_state() == false){ - snprintf(buf, 255, _T("*Power OFF*")); - } else if(now_skip) { - int ratio = (int)(100.0 * (double)total_frames / get_emu_frame_rate() + 0.5); - snprintf(buf, 255, create_string(_T("%s - Skip Frames (%d %%)"), get_device_name(), ratio)); - } else { + snprintf(buf, 255, _T("*Power OFF*")); + } else if(now_skip) { + int ratio = (int)(100.0 * (double)total_frames / (get_emu_frame_rate() * 2) + 0.5); + snprintf(buf, 255, create_string(_T("%s - Skip Frames (%d %%)"), get_device_name(), ratio)); + } else { if(get_message_count() > 0) { snprintf(buf, 255, _T("%s - %s"), get_device_name(), get_emu_message()); dec_message_count(); @@ -453,34 +463,80 @@ void EmuThreadClassBase::print_framerate(int frames) int EmuThreadClassBase::get_d88_file_cur_bank(int drive) { - return 0; + if(!(using_flags->is_use_fd())) return -1; + + if(drive < using_flags->get_max_drive()) { + QMutexLocker _locker(&uiMutex); + return p_emu->d88_file[drive].cur_bank; + } + + return -1; } int EmuThreadClassBase::get_d88_file_bank_num(int drive) { - return 0; + if(!(using_flags->is_use_fd())) return -1; + + if(drive < using_flags->get_max_drive()) { + QMutexLocker _locker(&uiMutex); + return p_emu->d88_file[drive].bank_num; + } + + return -1; } QString EmuThreadClassBase::get_d88_file_disk_name(int drive, int banknum) { + if(!(using_flags->is_use_fd())) return QString::fromUtf8(""); + + if(drive < 0) return QString::fromUtf8(""); + if((drive < using_flags->get_max_drive()) && (banknum < get_d88_file_bank_num(drive))) { + QMutexLocker _locker(&uiMutex); + QString _n = QString::fromLocal8Bit((const char *)(&(p_emu->d88_file[drive].disk_name[banknum][0]))); + return _n; + } + return QString::fromUtf8(""); } bool EmuThreadClassBase::is_floppy_disk_protected(int drive) { + QMutexLocker _locker(&uiMutex); + if(!(using_flags->is_use_fd())) return false; + + bool _b = p_emu->is_floppy_disk_protected(drive); + return _b; + return false; } -void EmuThreadClassBase::set_floppy_disk_protected(int drive, bool flag) -{ -} QString EmuThreadClassBase::get_d88_file_path(int drive) { + QMutexLocker _locker(&uiMutex); + + if(!(using_flags->is_use_fd())) return QString::fromUtf8(""); + if(drive < 0) return QString::fromUtf8(""); + + if(drive < using_flags->get_max_drive()) { + QMutexLocker _locker(&uiMutex); + QString _n = QString::fromUtf8((const char *)(&(p_emu->d88_file[drive].path))); + return _n; + } + return QString::fromUtf8(""); } + +void EmuThreadClassBase::set_floppy_disk_protected(int drive, bool flag) +{ + QMutexLocker _locker(&uiMutex); + if(!(using_flags->is_use_fd())) return; + + p_emu->is_floppy_disk_protected(drive, flag); + +} #if defined(Q_OS_LINUX) //#define _GNU_SOURCE #include @@ -516,6 +572,235 @@ void EmuThreadClassBase::set_emu_thread_to_fixed_cpu(int cpunum) return; } +void EmuThreadClassBase::get_fd_string(void) +{ + if(!(using_flags->is_use_fd())) return; + int i; + QString tmpstr; + QString iname; + QString alamp; + uint32_t access_drv = 0; + bool lamp_stat = false; + access_drv = p_emu->is_floppy_disk_accessed(); + { + for(i = 0; i < (int)using_flags->get_max_drive(); i++) { + tmpstr.clear(); + alamp.clear(); + lamp_stat = false; + if(p_emu->is_floppy_disk_inserted(i)) { + if(i == (access_drv - 1)) { + lamp_stat = true; + alamp = QString::fromUtf8(""); // 💾U+1F4BE Floppy Disk + } else { + alamp = QString::fromUtf8(""); // 💾U+1F4BE Floppy Disk + } + if(p_emu->d88_file[i].bank_num > 0) { + iname = QString::fromUtf8(p_emu->d88_file[i].disk_name[p_emu->d88_file[i].cur_bank]); + } else { + iname = QString::fromUtf8("*Inserted*"); + } + tmpstr = iname; + } else { + tmpstr.clear(); + alamp = QString::fromUtf8("×"); + } + if(alamp != fd_lamp[i]) { + emit sig_set_access_lamp(i + 2, lamp_stat); + emit sig_change_access_lamp(CSP_DockDisks_Domain_FD, i, alamp); + fd_lamp[i] = alamp; + } + if(tmpstr != fd_text[i]) { + emit sig_set_access_lamp(i + 2, lamp_stat); + emit sig_change_osd(CSP_DockDisks_Domain_FD, i, tmpstr); + fd_text[i] = tmpstr; + } + lamp_stat = false; + } + } +} + +void EmuThreadClassBase::get_qd_string(void) +{ + if(!(using_flags->is_use_qd())) return; + int i; + QString iname; + QString alamp; + QString tmpstr; + uint32_t access_drv = 0; + bool lamp_stat = false; + access_drv = p_emu->is_quick_disk_accessed(); + for(i = 0; i < using_flags->get_max_qd(); i++) { + tmpstr.clear(); + lamp_stat = false; + if(p_emu->is_quick_disk_inserted(i)) { + if(i == (access_drv - 1)) { + alamp = QString::fromUtf8(""); // 💽 U+1F4BD MiniDisc + lamp_stat = true; + } else { + alamp = QString::fromUtf8(""); // 💽U+1F4BD MiniDisc + } + tmpstr = alamp; + //tmpstr = tmpstr + QString::fromUtf8(" "); + //iname = QString::fromUtf8("*Inserted*"); + //tmpstr = tmpstr + iname; + } else { + tmpstr = QString::fromUtf8("×"); + } + if(tmpstr != qd_text[i]) { + emit sig_set_access_lamp(i + 10, lamp_stat); + emit sig_change_access_lamp(CSP_DockDisks_Domain_QD, i, tmpstr); + qd_text[i] = tmpstr; + } + lamp_stat = false; + } +} + +void EmuThreadClassBase::get_tape_string() +{ + QString tmpstr; + bool readwrite; + bool inserted; + + if(!(using_flags->is_use_tape()) || (using_flags->is_tape_binary_only())) return; + for(int i = 0; i < using_flags->get_max_tape(); i++) { + inserted = p_emu->is_tape_inserted(i); + readwrite = false; + if(inserted) { + tmpstr.clear(); + const _TCHAR *ts = p_emu->get_tape_message(i); + if(ts != NULL) { + tmpstr = QString::fromUtf8(ts); + readwrite = p_emu->is_tape_recording(i); + if(readwrite) { + tmpstr = QString::fromUtf8("") + tmpstr + QString::fromUtf8(""); + } else { + tmpstr = QString::fromUtf8("") + tmpstr + QString::fromUtf8(""); + } + } + } else { + tmpstr = QString::fromUtf8(" EMPTY "); + } + emit sig_set_access_lamp(i + 12 + ((readwrite) ? 2 : 0), inserted); + if(tmpstr != cmt_text[i]) { + emit sig_change_osd(CSP_DockDisks_Domain_CMT, i, tmpstr); + cmt_text[i] = tmpstr; + } + } + +} + +void EmuThreadClassBase::get_hdd_string(void) +{ + if(!(using_flags->is_use_hdd())) return; + + QString tmpstr, alamp; + uint32_t access_drv = p_emu->is_hard_disk_accessed(); + bool lamp_stat = false; + alamp.clear(); + tmpstr.clear(); + for(int i = 0; i < (int)using_flags->get_max_hdd(); i++) { + if(p_emu->is_hard_disk_inserted(i)) { + if((access_drv & (1 << i)) != 0) { + alamp = QString::fromUtf8(""); // + lamp_stat = true; + } else { + alamp = QString::fromUtf8(""); // + } + } else { + alamp = QString::fromUtf8("×"); + } + if(tmpstr != hdd_text[i]) { + emit sig_set_access_lamp(i + 16, lamp_stat); + emit sig_change_osd(CSP_DockDisks_Domain_HD, i, tmpstr); + hdd_text[i] = tmpstr; + } + if(alamp != hdd_lamp[i]) { + emit sig_set_access_lamp(i + 16, lamp_stat); + emit sig_change_access_lamp(CSP_DockDisks_Domain_HD, i, alamp); + hdd_lamp[i] = alamp; + } + lamp_stat = false; + } + +} +void EmuThreadClassBase::get_cd_string(void) +{ + if(!(using_flags->is_use_compact_disc())) return; + + QString tmpstr; + uint32_t access_drv = p_emu->is_compact_disc_accessed(); + for(int i = 0; i < (int)using_flags->get_max_cd(); i++) { + if(p_emu->is_compact_disc_inserted(i)) { + if((access_drv & (1 << i)) != 0) { + tmpstr = QString::fromUtf8(""); // U+1F4BF OPTICAL DISC + } else { + tmpstr = QString::fromUtf8(""); // U+1F4BF OPTICAL DISC + } + } else { + tmpstr = QString::fromUtf8("×"); + } + if(tmpstr != cdrom_text[i]) { + emit sig_set_access_lamp(i + 24, ((access_drv & (1 << i)) != 0)); + emit sig_change_access_lamp(CSP_DockDisks_Domain_CD, i, tmpstr); + cdrom_text[i] = tmpstr; + } + } + +} + +void EmuThreadClassBase::get_bubble_string(void) +{ + if(!(using_flags->is_use_bubble())) return; + + uint32_t access_drv; + int i; + QString alamp; + QString tmpstr; + for(i = 0; i < using_flags->get_max_bubble() ; i++) { + if(p_emu->is_bubble_casette_inserted(i)) { + alamp = QString::fromUtf8("● "); + //tmpstr = alamp + QString::fromUtf8(" "); + } else { + tmpstr = QString::fromUtf8("×"); + //tmpstr = tmpstr + QString::fromUtf8(" "); + } + if(alamp != bubble_text[i]) { + emit sig_change_access_lamp(CSP_DockDisks_Domain_Bubble, i, tmpstr); + bubble_text[i] = alamp; + } + } + +} + +bool EmuThreadClassBase::get_power_state(void) +{ + return MainWindow->GetPowerState(); +} + +double EmuThreadClassBase::get_emu_frame_rate(void) +{ + return p_emu->get_frame_rate(); +} + +int EmuThreadClassBase::get_message_count(void) +{ + return p_emu->message_count; +} + +const _TCHAR *EmuThreadClassBase::get_emu_message(void) +{ + return (const _TCHAR *)(p_emu->message); +} + +bool EmuThreadClassBase::now_debugging() +{ + if(using_flags->is_use_debugger()) { + return p_emu->now_debugging; + } else { + return false; + } +} + #if defined(Q_OS_LINUX) //#undef _GNU_SOURCE #endif diff --git a/source/src/qt/gui/emu_thread_tmpl.h b/source/src/qt/gui/emu_thread_tmpl.h index 90a31d414..ff985dea4 100644 --- a/source/src/qt/gui/emu_thread_tmpl.h +++ b/source/src/qt/gui/emu_thread_tmpl.h @@ -27,11 +27,17 @@ #include "commonclasses.h" #include "config.h" +#ifndef MAX_HISTORY +#define MAX_HISTORY 8 +#endif +#define MAX_COMMAND_LEN 64 + class EMU; class QWaitCondition; class QOpenGLContext; class USING_FLAGS; class Ui_MainWindowBase; +class OSD_BASE; //class META_MainWindow; QT_BEGIN_NAMESPACE @@ -49,6 +55,9 @@ typedef struct { class DLL_PREFIX EmuThreadClassBase : public QThread { Q_OBJECT protected: + EMU *p_emu; + OSD_BASE *p_osd; + bool now_skip; bool calc_message; bool tape_play_flag; @@ -59,14 +68,13 @@ class DLL_PREFIX EmuThreadClassBase : public QThread { int mouse_y; Qt::HANDLE thread_id; int queue_fixed_cpu; - + FIFO *key_fifo; QOpenGLContext *glContext; bool is_shared_glcontext; uint32_t key_mod; - EMU *p_emu; USING_FLAGS *using_flags; config_t *p_config; @@ -77,6 +85,7 @@ class DLL_PREFIX EmuThreadClassBase : public QThread { Ui_MainWindowBase *MainWindow; QElapsedTimer tick_timer; + bool bBlockTask; bool bRunThread; bool bResetReq; bool bSpecialResetReq; @@ -89,12 +98,19 @@ class DLL_PREFIX EmuThreadClassBase : public QThread { QString sStateFile; QString lStateFile; + QMutex uiMutex; + char dbg_prev_command[MAX_COMMAND_LEN]; + int fd_open_wait_count[8]; + QString fd_reserved_path[8]; + int fd_reserved_bank[8]; + // bool draw_timing; bool doing_debug_command; bool bUpdateVolumeReq[32]; int volume_balance[32]; int volume_avg[32]; int record_fps; + int specialResetNum; qint64 next_time; qint64 update_fps_time; @@ -111,6 +127,7 @@ class DLL_PREFIX EmuThreadClassBase : public QThread { QString cdrom_text[4]; QString laserdisc_text[4]; QString bubble_text[16]; + QString clipBoardText; QStringList vMovieQueue; @@ -118,24 +135,25 @@ class DLL_PREFIX EmuThreadClassBase : public QThread { void calc_volume_from_level(int num, int level); int parse_command_queue(QStringList _l, int _begin); - virtual void button_pressed_mouse_sub(Qt::MouseButton button) {}; - virtual void button_released_mouse_sub(Qt::MouseButton button) {}; - virtual void get_qd_string(void) {}; - virtual void get_fd_string(void) {}; - virtual void get_hdd_string(void) {}; - virtual void get_tape_string(void) {}; - virtual void get_cd_string(void) {}; - virtual void get_bubble_string(void) {}; + void button_pressed_mouse_sub(Qt::MouseButton button); + void button_released_mouse_sub(Qt::MouseButton button); + + void get_qd_string(void); + void get_fd_string(void); + void get_hdd_string(void); + void get_tape_string(void); + void get_cd_string(void); + void get_bubble_string(void); - virtual const _TCHAR *get_emu_message(void); - virtual double get_emu_frame_rate(void); - virtual int get_message_count(void); - virtual void dec_message_count(void); - virtual const _TCHAR *get_device_name(void); - virtual bool get_power_state(void); + const _TCHAR *get_emu_message(void); + double get_emu_frame_rate(void); + int get_message_count(void); + void dec_message_count(void); + bool get_power_state(void); + virtual const _TCHAR *get_device_name(void); virtual void resetEmu() { } - virtual void specialResetEmu() { } + virtual void specialResetEmu(int num) { } virtual void loadState() { } virtual void saveState() { } @@ -200,20 +218,20 @@ class DLL_PREFIX EmuThreadClassBase : public QThread { void set_tape_play(bool); void resize_screen(int sw, int sh, int stw, int sth); void sample_access_drv(void); - virtual bool now_debugging() { return false; }; + bool now_debugging(); - virtual int get_d88_file_cur_bank(int drive); - virtual int get_d88_file_bank_num(int drive); - virtual QString get_d88_file_disk_name(int drive, int banknum); - virtual bool is_floppy_disk_protected(int drive); - virtual void set_floppy_disk_protected(int drive, bool flag); - virtual QString get_d88_file_path(int drive); + int get_d88_file_cur_bank(int drive); + int get_d88_file_bank_num(int drive); + QString get_d88_file_disk_name(int drive, int banknum); + bool is_floppy_disk_protected(int drive); + void set_floppy_disk_protected(int drive, bool flag); + QString get_d88_file_path(int drive); public slots: void doExit(void); void do_reset(); - void do_special_reset(); + void do_special_reset(int num); void do_load_state(QString name); void do_save_state(QString name); void do_update_config(); @@ -230,6 +248,46 @@ public slots: void do_key_up(uint32_t vk, uint32_t mod); void print_framerate(int frames); void set_emu_thread_to_fixed_cpu(int cpunum); + void do_block(); + void do_unblock(); + void do_start_emu_thread(); + + // From emu_thread_slots.cpp . + void do_set_display_size(int w, int h, int ww, int wh); + void moved_mouse(int x, int y, int globalx, int globaly); + + void do_write_protect_disk(int drv, bool flag); + void do_close_disk(int); + void do_open_disk(int, QString, int); + void do_close_hard_disk(int); + void do_open_hard_disk(int, QString); + void do_play_tape(int drv, QString name); + void do_rec_tape(int drv, QString name); + void do_close_tape(int drv); + void do_cmt_push_play(int drv); + void do_cmt_push_stop(int drv); + void do_cmt_push_fast_forward(int drv); + void do_cmt_push_fast_rewind(int drv); + void do_cmt_push_apss_forward(int drv); + void do_cmt_push_apss_rewind(int drv); + void do_write_protect_quickdisk(int drv, bool flag); + void do_close_quickdisk(int drv); + void do_open_quickdisk(int drv, QString path); + void do_close_cart(int drv); + void do_open_cart(int drv, QString path); + void do_close_laser_disc(int drv); + void do_open_laser_disc(int drv, QString path); + void do_eject_cdrom(int drv); + void do_open_cdrom(int drv, QString path); + void do_load_binary(int drv, QString path); + void do_save_binary(int drv, QString path); + void do_write_protect_bubble_casette(int drv, bool flag); + void do_close_bubble_casette(int); + void do_open_bubble_casette(int, QString, int); + void do_start_auto_key(QString text); + void do_stop_auto_key(void); + void set_romakana(bool flag); + void do_close_debugger(void); signals: int message_changed(QString); @@ -269,16 +327,22 @@ public slots: int sig_open_cmt_load(int, QString); int sig_open_cmt_write(int, QString); int sig_open_fd(int, QString); + int sig_open_d88_fd(int, QString, int); int sig_open_hdd(int, QString); int sig_open_quick_disk(int, QString); int sig_open_bubble(int, QString); + int sig_open_b77_bubble(int, QString, int); int sig_open_cdrom(int, QString); int sig_open_laser_disc(int, QString); int sig_set_d88_num(int, int); int sig_set_b77_num(int, int); + // From emu_thread_slots.cpp . + int sig_set_draw_fps(double); + int sig_draw_one_turn(bool); + int sig_update_d88_list(int, int); }; QT_END_NAMESPACE diff --git a/source/src/qt/gui/emuevents_control.cpp b/source/src/qt/gui/emuevents_control.cpp index 269a16b64..0f7c9f883 100644 --- a/source/src/qt/gui/emuevents_control.cpp +++ b/source/src/qt/gui/emuevents_control.cpp @@ -12,20 +12,12 @@ #include "qt_dialogs.h" #include "csp_logger.h" -extern EMU *emu; - void Ui_MainWindowBase::OnReset(void) { csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GUI, "Reset"); emit sig_vm_reset(); } -void Ui_MainWindowBase::OnSpecialReset(void) -{ - csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GUI, "Special reset"); - emit sig_vm_specialreset(); -} - void Ui_MainWindowBase::do_emu_full_speed(bool flag) { p_config->full_speed = flag; diff --git a/source/src/qt/gui/gl/qt_glutil_gl_tmpl.cpp b/source/src/qt/gui/gl/qt_glutil_gl_tmpl.cpp new file mode 100644 index 000000000..e1c6252bc --- /dev/null +++ b/source/src/qt/gui/gl/qt_glutil_gl_tmpl.cpp @@ -0,0 +1,590 @@ + +#include "osd_types.h" +#include "qt_gldraw.h" +#include "qt_glpack.h" +#include "./qt_glutil_gl_tmpl.h" +#include "csp_logger.h" +#include +#include + +#include +#include +#include +#include + +GLDraw_Tmpl::GLDraw_Tmpl(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu) : QObject((QObject *)parent) +{ + p_wid = parent; + p_emu = emu; + using_flags = p; + p_config = p->get_config_ptr(); + vert_lines = using_flags->get_real_screen_height(); + horiz_pixels = using_flags->get_real_screen_width(); + screen_texture_width = using_flags->get_screen_width(); + screen_texture_width_old = using_flags->get_screen_width(); + screen_texture_height = using_flags->get_screen_height(); + screen_texture_height_old = using_flags->get_screen_height(); + + osd_pass = NULL; + led_pass = NULL; + uTmpTextureID = 0; + ringing_phase = 0.0f; + + grids_shader = NULL; + main_pass = NULL; + std_pass = NULL; + ntsc_pass1 = NULL; + ntsc_pass2 = NULL; + grids_horizonal_buffer = NULL; + grids_horizonal_vertex = NULL; + + grids_vertical_buffer = NULL; + grids_vertical_vertex = NULL; + for(int i = 0; i < 32; i++) { + led_pass_vao[i] = NULL; + led_pass_vbuffer[i] = NULL; + osd_pass_vao[i] = NULL; + osd_pass_vbuffer[i] = NULL; + } + +#if 0 + if(using_flags->is_use_fd()) { + osd_led_bit_width = 10; + } + if(using_flags->is_use_qd()) { + osd_led_bit_width = 12; + } + if(using_flags->is_use_tape()) { + osd_led_bit_width = 16; + } + if(using_flags->get_max_scsi() > 0) { + osd_led_bit_width = 24; + } + if(using_flags->is_use_compact_disc()) { + osd_led_bit_width = 26; + } + if(using_flags->is_use_laser_disc()) { + osd_led_bit_width = 28; + } +#else + osd_led_bit_width = 32; +#endif + int i; + // Will fix: Must fix setup of vm_buttons[]. + button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); + if(vm_buttons_d != NULL) { + for(i = 0; i < using_flags->get_max_button(); i++) { + uButtonTextureID[i] = new QOpenGLTexture(QOpenGLTexture::Target2D);; + fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width(); + fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height(); + fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width(); + fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height(); + } // end of will fix. + } + + for(int i = 0; i < 10; i++) { + for(int j = 0; j < 10; j++) { + icon_texid[i][j] = NULL; + } + } + + rec_width = using_flags->get_screen_width(); + rec_height = using_flags->get_screen_height(); + ButtonImages.clear(); + + csp_logger = logger; + + gl_grid_horiz = false; + gl_grid_vert = false; + glVertGrids = NULL; + glHorizGrids = NULL; + + set_brightness = false; + crt_flag = false; + smoosing = false; + uVramTextureID = NULL; + emu_launched = false; + + imgptr = NULL; + screen_multiply = 1.0f; + redraw_required = false; + + osd_led_status = 0x00000000; + osd_led_status_bak = 0x00000000; + osd_led_bit_width = 12; + + osd_onoff = true; + + uBitmapTextureID = NULL; + bitmap_uploaded = false; + texture_max_size = 128; + low_resolution_screen = false; + + button_updated = false; + button_drawn = false; + + fBrightR = 1.0; // 輝度の初期化 + fBrightG = 1.0; + fBrightB = 1.0; + set_brightness = false; + crt_flag = false; + smoosing = false; + + screen_width = 1.0; + screen_height = 1.0; + + buffer_screen_vertex = NULL; + vertex_screen = NULL; + + offscreen_frame_buffer = NULL; + offscreen_frame_buffer_format = NULL; + rec_count = 0; +} + +GLDraw_Tmpl::~GLDraw_Tmpl() +{ + if(main_pass != NULL) delete main_pass; + if(std_pass != NULL) delete std_pass; + if(ntsc_pass1 != NULL) delete ntsc_pass1; + if(ntsc_pass2 != NULL) delete ntsc_pass2; + + if(grids_horizonal_buffer != NULL) { + if(grids_horizonal_buffer->isCreated()) grids_horizonal_buffer->destroy(); + } + if(grids_horizonal_vertex != NULL) { + if(grids_horizonal_vertex->isCreated()) grids_horizonal_vertex->destroy(); + } + if(grids_vertical_buffer != NULL) { + if(grids_vertical_buffer->isCreated()) grids_vertical_buffer->destroy(); + } + if(grids_horizonal_vertex != NULL) { + if(grids_vertical_vertex->isCreated()) grids_vertical_vertex->destroy(); + } + if(osd_pass != NULL) delete osd_pass; + if(led_pass != NULL) delete led_pass; + for(int i = 0; i < 32; i++) { + if(led_pass_vao[i] != NULL) delete led_pass_vao[i]; + if(led_pass_vbuffer[i] != NULL) delete led_pass_vbuffer[i]; + if(osd_pass_vao[i] != NULL) delete osd_pass_vao[i]; + if(osd_pass_vbuffer[i] != NULL) delete osd_pass_vbuffer[i]; + } +} + +void GLDraw_Tmpl::initBitmapVertex(void) +{ + if(using_flags->is_use_one_board_computer()) { + vertexBitmap[0].x = -1.0f; + vertexBitmap[0].y = -1.0f; + vertexBitmap[0].z = 0.5f; + vertexBitmap[0].s = 0.0f; + vertexBitmap[0].t = 1.0f; + + vertexBitmap[1].x = +1.0f; + vertexBitmap[1].y = -1.0f; + vertexBitmap[1].z = 0.5f; + vertexBitmap[1].s = 1.0f; + vertexBitmap[1].t = 1.0f; + + vertexBitmap[2].x = +1.0f; + vertexBitmap[2].y = +1.0f; + vertexBitmap[2].z = 0.5f; + vertexBitmap[2].s = 1.0f; + vertexBitmap[2].t = 0.0f; + + vertexBitmap[3].x = -1.0f; + vertexBitmap[3].y = +1.0f; + vertexBitmap[3].z = 0.5f; + vertexBitmap[3].s = 0.0f; + vertexBitmap[3].t = 0.0f; + + } +} + +void GLDraw_Tmpl::initButtons(void) +{ + button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); + QOpenGLContext *context = QOpenGLContext::currentContext(); + QPair _version = QOpenGLVersionProfile(context->format()).version(); + QString versionext = QString::fromUtf8(""); + + if(context->isOpenGLES()) { + if(((_version.first == 3) && (_version.second >= 1)) || (_version.first >= 4)){ + versionext = QString::fromUtf8("#version 310 es \n"); + } /* else if((_version.first == 3)) { + _ext = _ext + QString::fromUtf8("#version 300 es \n"); + } */ else { + versionext = QString::fromUtf8("#version 100 \n"); + } + } else { + if(((_version.first == 4) && (_version.second >= 3)) || (_version.first >= 5)) { + versionext = QString::fromUtf8("#version 430 core \n"); // OK? + } else if((_version.first == 4)) { + versionext = QString::fromUtf8("#version 400 core \n"); + } else if((_version.first == 3) && (_version.second >= 3)) { + versionext = QString::fromUtf8("#version 330 core \n"); + } else if((_version.first == 3)) { + versionext = QString::fromUtf8("#version 130 \n"); + } else { // Require GLVersion >= 2 + versionext = QString::fromUtf8("#version 120 \n"); + } + } + if(vm_buttons_d != NULL) { + button_shader = new QOpenGLShaderProgram(p_wid); + if(button_shader != NULL) { + bool f = false; + QFile vertex_src(QString::fromUtf8(":/gl/shaders/vertex_shader.glsl")); + if (vertex_src.open(QIODevice::ReadOnly | QIODevice::Text)) { + QString srcs = versionext; + srcs = srcs + QString::fromUtf8(vertex_src.readAll()); + f = button_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, srcs); + vertex_src.close(); + } else { + return; + } + QFile fragment_src(QString::fromUtf8(":/gl/shaders/normal_fragment_shader.glsl")); + if (fragment_src.open(QIODevice::ReadOnly | QIODevice::Text)) { + QString srcs = versionext; + srcs = srcs + QString::fromUtf8(fragment_src.readAll()); + f &= button_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, srcs); + fragment_src.close(); + } else { + return; + } + if(!f) return; + button_shader->link(); + } + + int ip = using_flags->get_max_button(); + if(ip > 0) { + for(int num = 0; num < ip; num++) { + QString tmps; + tmps = QString::asprintf(":/button%02d.png", num); + QImageReader *reader = new QImageReader(tmps); + QImage *result = new QImage(reader->read()); + QImage pic; + if(result != NULL) { + if(!result->isNull()) { + pic = result->convertToFormat(QImage::Format_ARGB32); + } else { + pic = QImage(10, 10, QImage::Format_RGBA8888); + pic.fill(QColor(0,0,0,0)); + } + delete result; + }else { + pic = QImage(10, 10, QImage::Format_RGBA8888); + pic.fill(QColor(0,0,0,0)); + } + ButtonImages.push_back(pic); + } + } + vertexButtons = new QVector; + for(int i = 0; i < using_flags->get_max_button(); i++) { + buffer_button_vertex[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + buffer_button_vertex[i]->create(); + fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width(); + fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height(); + fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width(); + fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height(); + + vertex_button[i] = new QOpenGLVertexArrayObject; + if(vertex_button[i] != NULL) { + if(vertex_button[i]->create()) { + VertexTexCoord_t vt[4]; + + vt[0].x = fButtonX[i]; + vt[0].y = fButtonY[i]; + vt[0].z = -0.5f; + vt[0].s = 0.0f; + vt[0].t = 0.0f; + + vt[1].x = fButtonX[i] + fButtonWidth[i]; + vt[1].y = fButtonY[i]; + vt[1].z = -0.5f; + vt[1].s = 1.0f; + vt[1].t = 0.0f; + + vt[2].x = fButtonX[i] + fButtonWidth[i]; + vt[2].y = fButtonY[i] - fButtonHeight[i]; + vt[2].z = -0.5f; + vt[2].s = 1.0f; + vt[2].t = 1.0f; + + vt[3].x = fButtonX[i]; + vt[3].y = fButtonY[i] - fButtonHeight[i]; + vt[3].z = -0.5f; + vt[3].s = 0.0f; + vt[3].t = 1.0f; + + vertexButtons->append(vt[0]); + vertexButtons->append(vt[1]); + vertexButtons->append(vt[2]); + vertexButtons->append(vt[3]); + vertex_button[i]->bind(); + buffer_button_vertex[i]->bind(); + buffer_button_vertex[i]->allocate(4 * sizeof(VertexTexCoord_t)); + + buffer_button_vertex[i]->setUsagePattern(QOpenGLBuffer::StaticDraw); + buffer_button_vertex[i]->release(); + vertex_button[i]->release(); + setNormalVAO(button_shader, vertex_button[i], + buffer_button_vertex[i], + vt, 4); + } + } + } + } +} + +void GLDraw_Tmpl::drawLedMain(GLScreenPack *obj, int num, QVector4D color) +{ + QOpenGLShaderProgram *prg = obj->getShader(); + QOpenGLVertexArrayObject *vp = led_pass_vao[num]; + QOpenGLBuffer *bp = led_pass_vbuffer[num]; + int ii; + + { + prologueBlending(); + vp->bind(); + bp->bind(); + prg->bind(); + + ii = prg->uniformLocation("color"); + if(ii >= 0) { + prg->setUniformValue(ii, color); + } + + prg->enableAttributeArray("vertex"); + int vertex_loc = prg->attributeLocation("vertex"); + prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t)); + drawPolygon(vertex_loc); + bp->release(); + vp->release(); + + prg->release(); + epilogueBlending(); + } +} + +void GLDraw_Tmpl::drawOsdLeds() +{ + QVector4D color_on; + QVector4D color_off; + uint32_t bit = 0x00000001; + if(osd_onoff) { + color_on = QVector4D(0.95, 0.0, 0.05, 1.0); + color_off = QVector4D(0.05,0.05, 0.05, 0.10); + } else { + color_on = QVector4D(0.00,0.00, 0.00, 0.0); + color_off = QVector4D(0.00,0.00, 0.00, 0.0); + } + if(osd_onoff) { + //if(osd_led_status_bak != osd_led_status) { + for(int i = 0; i < osd_led_bit_width; i++) { + if((bit & osd_led_status) == (bit & osd_led_status_bak)) { + bit <<= 1; + continue; + } + drawLedMain(led_pass, i, + ((osd_led_status & bit) != 0) ? color_on : color_off); + bit <<= 1; + } + osd_led_status_bak = osd_led_status; + //} + } +} + +void GLDraw_Tmpl::drawOsdIcons() +{ + QVector4D color_on; + QVector4D color_off; + uint32_t bit = 0x00000001; + if(osd_onoff) { + color_on = QVector4D(1.0, 1.0, 1.0, 0.8); + color_off = QVector4D(1.0, 1.0, 1.0, 0.00); + } else { + color_on = QVector4D(0.00,0.00, 0.00, 0.0); + color_off = QVector4D(0.00,0.00, 0.00, 0.0); + } + if(osd_onoff) { + int major, minor; + //if(osd_led_status_bak != osd_led_status) { + for(int i = 0; i < osd_led_bit_width; i++) { + if((bit & osd_led_status) == (bit & osd_led_status_bak)) { + if((bit & osd_led_status) == 0) { + bit <<= 1; + continue; + } + } + if((i >= 2) && (i < 10)) { // FD + major = 2; + minor = i - 2; + } else if((i >= 10) && (i < 12)) { // QD + major = 3; + minor = i - 10; + } else if((i >= 12) && (i < 14)) { // CMT(R) + major = 4; + minor = i - 12; + } else if((i >= 14) && (i < 16)) { // CMT(W) + major = 5; + minor = i - 14; + } else if((i >= 16) && (i < 24)) { // HDD + major = 8; + minor = i - 16; + } else if((i >= 24) && (i < 26)) { // CD + major = 6; + minor = i - 24; + } else if((i >= 26) && (i < 28)) { // LD + major = 7; + minor = i - 26; + } else { + major = 0; + minor = 0; + } + // ToDo: CD(6),LD(7) and HDD(8). + + if((major != 0) && (icon_texid[major][minor] != NULL)) { + if(icon_texid[major][minor] != NULL) { + drawMain(osd_pass->getShader(), osd_pass_vao[i], osd_pass_vbuffer[i], + icon_texid[major][minor]->textureId(), + ((osd_led_status & bit) != 0) ? color_on : color_off, + false, false, QVector3D(0.0, 0.0, 0.0)); + } + } + bit <<= 1; + } + osd_led_status_bak = osd_led_status; + //} + } +} + + +void GLDraw_Tmpl::updateButtonTexture(void) +{ + int i; + button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); + if(button_updated) return; + if(vm_buttons_d != NULL) { + for(i = 0; i < using_flags->get_max_button(); i++) { + QImage img = ButtonImages.at(i); + if(uButtonTextureID[i] != NULL) { + delete uButtonTextureID[i]; + } + uButtonTextureID[i] = new QOpenGLTexture(img); + } + } + button_updated = true; +} + +void GLDraw_Tmpl::uploadBitmapTexture(QImage *p) +{ + if(!using_flags->is_use_one_board_computer()) return; + if(p == NULL) return; + if(!bitmap_uploaded) { + p_wid->makeCurrent(); + if(uBitmapTextureID != NULL) { + delete uBitmapTextureID; + } + uBitmapTextureID = new QOpenGLTexture(*p); + p_wid->doneCurrent(); + bitmap_uploaded = true; + crt_flag = true; + } +} + +void GLDraw_Tmpl::updateBitmap(QImage *p) +{ + if(!using_flags->is_use_one_board_computer()) return; + redraw_required = true; + bitmap_uploaded = false; + uploadBitmapTexture(p); +} + +void GLDraw_Tmpl::uploadIconTexture(QPixmap *p, int icon_type, int localnum) +{ + if((icon_type > 7) || (icon_type < 0)) return; + if((localnum >= 9) || (localnum < 0)) return; + if(p == NULL) return; + p_wid->makeCurrent(); + QImage image = p->toImage(); + if(icon_texid[icon_type][localnum] != NULL) delete icon_texid[icon_type][localnum]; + { + icon_texid[icon_type][localnum] = new QOpenGLTexture(image); + } + p_wid->doneCurrent(); +} +// Slots +void GLDraw_Tmpl::doSetGridsHorizonal(int lines, bool force) +{ + int i; + GLfloat yf; + GLfloat delta; + + if((lines == vert_lines) && !force) return; + //printf("lines: %d\n", lines); + vert_lines = lines; + yf = -screen_height; + if(vert_lines <= 0) return; + if(vert_lines > using_flags->get_real_screen_height()) vert_lines = using_flags->get_real_screen_height(); + + delta = (2.0f * screen_height) / (float)vert_lines; + yf = yf - delta * 1.0f; + if(glHorizGrids != NULL) { + for(i = 0; i < (vert_lines + 1) ; i++) { + glHorizGrids[i * 6] = -screen_width; // XBegin + glHorizGrids[i * 6 + 3] = +screen_width; // XEnd + glHorizGrids[i * 6 + 1] = yf; // YBegin + glHorizGrids[i * 6 + 4] = yf; // YEnd + glHorizGrids[i * 6 + 2] = -0.95f; // ZBegin + glHorizGrids[i * 6 + 5] = -0.95f; // ZEnd + yf = yf + delta; + } + } +} + +void GLDraw_Tmpl::doSetGridsVertical(int pixels, bool force) +{ + int i; + GLfloat xf; + GLfloat delta; + + if((pixels == horiz_pixels) && !force) return; + horiz_pixels = pixels; + if(horiz_pixels <= 0) return; + if(horiz_pixels > using_flags->get_real_screen_width()) horiz_pixels = using_flags->get_real_screen_width(); + + xf = -screen_width; + delta = (2.0f * screen_width) / (float)horiz_pixels; + xf = xf - delta * 0.75f; + if(glVertGrids != NULL) { + if(horiz_pixels > using_flags->get_real_screen_width()) horiz_pixels = using_flags->get_real_screen_width(); + for(i = 0; i < (horiz_pixels + 1) ; i++) { + glVertGrids[i * 6] = xf; // XBegin + glVertGrids[i * 6 + 3] = xf; // XEnd + glVertGrids[i * 6 + 1] = -screen_height; // YBegin + glVertGrids[i * 6 + 4] = screen_height; // YEnd + glVertGrids[i * 6 + 2] = -0.95f; // ZBegin + glVertGrids[i * 6 + 5] = -0.95f; // ZEnd + xf = xf + delta; + } + } +} + +void GLDraw_Tmpl::do_set_display_osd(bool onoff) +{ + osd_onoff = onoff; +} + +void GLDraw_Tmpl::do_display_osd_leds(int lednum, bool onoff) +{ + if(lednum == -1) { + osd_led_status = (onoff) ? 0xffffffff : 0x00000000; + } else if((lednum >= 0) && (lednum < 32)) { + uint32_t nn; + nn = 0x00000001 << lednum; + if(onoff) { + osd_led_status |= nn; + } else { + osd_led_status &= ~nn; + } + } +} diff --git a/source/src/qt/gui/gl/qt_glutil_gl_tmpl.h b/source/src/qt/gui/gl/qt_glutil_gl_tmpl.h index bab231e6e..75f7581d5 100644 --- a/source/src/qt/gui/gl/qt_glutil_gl_tmpl.h +++ b/source/src/qt/gui/gl/qt_glutil_gl_tmpl.h @@ -15,15 +15,19 @@ #include #include #include +#include #include +#include +#include + #include "config.h" #include "common.h" #include "qt_glpack.h" #include "menu_flags.h" QT_BEGIN_NAMESPACE -class EMU; +class EMU_TEMPLATE; class QEvent; class GLDrawClass; class QOpenGLFramebufferObject; @@ -33,17 +37,238 @@ class CSP_Logger; class QOpenGLBuffer; class QOpenGLVertexArrayObject; class QOpenGLShaderProgram; +class GLScreenPack; + +namespace GLShader { +class ShaderDesc { +protected: + QString vertex_shader_name; + QString fragment_shader_name; + QString description; +public: + ShaderDesc(QString _vname = QString::fromUtf8(""), QString _fname = QString::fromUtf8(""), QString _desc = QString::fromUtf8("")) { + vertex_shader_name = _vname; + fragment_shader_name = _fname; + description = _desc; + } + ~ShaderDesc() {} + void setShaders(QString _vname, QString _fname, QString _desc = QString::fromUtf8("")) { + vertex_shader_name = _vname; + fragment_shader_name = _fname; + description = _desc; + } + QString getVertexShaderName() { + return vertex_shader_name; + } + QString getFragmentShaderName() { + return fragment_shader_name; + } + QString getDesc() { + return description; + } + bool matchVertex(QString s, bool caseSensitive = true) { + return (vertex_shader_name.compare(s, (caseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive) == 0) ? true : false; + } + bool matchFragment(QString s, bool caseSensitive = true) { + return (fragment_shader_name.compare(s, (caseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive) == 0) ? true : false; + } + bool matchDesc(QString s, bool caseSensitive = true) { + return (description.compare(s, (caseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive) == 0) ? true : false; + } +}; + +class ShaderAttr { +protected: + bool is_multiple_pass; // Shader needs multiple pass. + bool is_multiple_frame_buffers; // Shader needs multiple frame buffer. + int num_multiple_pass; // Nubmers of multiple pass. + int num_multiple_frame_buffers; // Number of frame_buffers; + QList picture_shader_pair; + QStringList compute_shader_name; // ToDo: Will change with some code. +public: + ShaderAttr(bool mupass = false, bool mbuf = false, int npass = 1, int nfbs = 2) + { + is_multiple_pass = false; + is_multiple_frame_buffers = false; + num_multiple_pass = 1; + num_multiple_frame_buffers = 2; + if(mupass) { + is_multiple_pass = true; + num_multiple_pass = npass; + } + if(mbuf) { + is_multiple_frame_buffers = true; + num_multiple_frame_buffers = nfbs; + } + picture_shader_pair.clear(); + compute_shader_name.clear(); + } + ~ShaderAttr() {} + + QList getShadersList() { + return picture_shader_pair; + } + QStringList getComputeShadersList() { + return compute_shader_name; + } + + void addShaderPair(ShaderDesc n) { + return picture_shader_pair.append(n); + } + ShaderDesc getShaderPair(int n) { + return picture_shader_pair.at(n); + } + int numShaderPairs() { + return picture_shader_pair.size(); + } + bool isEmptyShaderPairs() { + return picture_shader_pair.isEmpty(); + } + void addComputeShader(QString name) { + compute_shader_name.append(name); + } + QString getComputeShader(int num) { + if((num < 0) || (num >= compute_shader_name.size())) return QString::fromUtf8(""); + return compute_shader_name.at(num); + } + int numComputeShaders() { + return compute_shader_name.size(); + } + bool isEmptyComputeShaders() { + return compute_shader_name.isEmpty(); + } + +}; + +class ShaderGroup { +protected: + ShaderAttr attr; + QList effect_shaders; //Compiled Pixel shaders +public: + ShaderGroup(ShaderAttr _a, GLScreenPack* p = NULL) { + attr = _a; + effect_shaders.clear(); + if(p != NULL) { + effect_shaders.append(p); + } + } + ~ShaderGroup() { } + + QList getShaders() { + return effect_shaders; + } + ShaderAttr attribute() { + return attr; + } + void append(GLScreenPack* p) { + if(p != NULL) { + effect_shaders.append(p); + } + } + GLScreenPack *at(int num) { + if((num < 0) || (num >= effect_shaders.size())) return nullptr; + return effect_shaders.at(num); + } + int size() { + return effect_shaders.size(); + } + bool isEmpty() { + return effect_shaders.isEmpty(); + } +}; +} +// End namespace GLShader + class DLL_PREFIX GLDraw_Tmpl : public QObject { Q_OBJECT protected: - EMU *p_emu; + EMU_TEMPLATE* p_emu; GLDrawClass *p_wid; USING_FLAGS *using_flags; QImage *imgptr; CSP_Logger *csp_logger; config_t *p_config; + + const float luma_filter[24 + 1] = { + -0.000012020, + -0.000022146, + -0.000013155, + -0.000012020, + -0.000049979, + -0.000113940, + -0.000122150, + -0.000005612, + 0.000170516, + 0.000237199, + 0.000169640, + 0.000285688, + 0.000984574, + 0.002018683, + 0.002002275, + -0.000909882, + -0.007049081, + -0.013222860, + -0.012606931, + 0.002460860, + 0.035868225, + 0.084016453, + 0.135563500, + 0.175261268, + 0.190176552 + }; + const float chroma_filter[24 + 1] = { + -0.000118847, + -0.000271306, + -0.000502642, + -0.000930833, + -0.001451013, + -0.002064744, + -0.002700432, + -0.003241276, + -0.003524948, + -0.003350284, + -0.002491729, + -0.000721149, + 0.002164659, + 0.006313635, + 0.011789103, + 0.018545660, + 0.026414396, + 0.035100710, + 0.044196567, + 0.053207202, + 0.061590275, + 0.068803602, + 0.074356193, + 0.077856564, + 0.079052396 + }; + const float rot0[4] = {1, -0, 0, 1}; + const float rot90[4] = {0, 1, -1, 0}; + const float rot180[4] = {-1, 0, 0, -1}; + const float rot270[4] = {0, -1, 1, 0}; + + int gl_major_version; + int gl_minor_version; + + GLScreenPack *main_pass; + GLScreenPack *std_pass; + GLScreenPack *ntsc_pass1; + GLScreenPack *ntsc_pass2; + GLScreenPack *bitmap_block; + + QOpenGLShaderProgram *grids_shader; + QOpenGLBuffer *grids_horizonal_buffer; + QOpenGLVertexArrayObject *grids_horizonal_vertex; + QOpenGLBuffer *grids_vertical_buffer; + QOpenGLVertexArrayObject *grids_vertical_vertex; + + GLuint uTmpTextureID; + bool swap_byteorder; + bool main_texture_ready; + float ringing_phase; bool smoosing; bool gl_grid_horiz; @@ -75,6 +300,14 @@ class DLL_PREFIX GLDraw_Tmpl : public QObject QOpenGLVertexArrayObject *vertex_screen; QOpenGLBuffer *buffer_screen_vertex; + GLScreenPack *led_pass; + GLScreenPack *osd_pass; + QOpenGLBuffer *led_pass_vbuffer[32]; + QOpenGLVertexArrayObject *led_pass_vao[32]; + QOpenGLBuffer *osd_pass_vbuffer[32]; + QOpenGLVertexArrayObject *osd_pass_vao[32]; + + VertexTexCoord_t vertexTmpTexture[4]; VertexTexCoord_t vertexBitmap[4]; QOpenGLShaderProgram *bitmap_shader; QOpenGLBuffer *buffer_bitmap_vertex; @@ -86,10 +319,6 @@ class DLL_PREFIX GLDraw_Tmpl : public QObject QOpenGLVertexArrayObject *vertex_osd[32]; QOpenGLBuffer *buffer_osd[32]; QOpenGLShaderProgram *osd_shader; - const float rot0[4] = {1, -0, 0, 1}; - const float rot90[4] = {0, 1, -1, 0}; - const float rot180[4] = {-1, 0, 0, -1}; - const float rot270[4] = {0, -1, 1, 0}; QOpenGLTexture *uVramTextureID; QOpenGLTexture *uButtonTextureID[128]; @@ -128,10 +357,11 @@ class DLL_PREFIX GLDraw_Tmpl : public QObject bool osd_onoff; virtual void drawBitmapTexture(void) { } - virtual void initButtons(void) { } - virtual void initBitmapVertex(void) { } + virtual void initButtons(void); + + virtual void initBitmapVertex(void); virtual void initBitmapVAO(void) { } - virtual void updateButtonTexture(void) { } + virtual void updateButtonTexture(void); virtual void setNormalVAO(QOpenGLShaderProgram *prg, QOpenGLVertexArrayObject *vp, QOpenGLBuffer *bp, VertexTexCoord_t *tp, int size = 4) { } @@ -141,114 +371,22 @@ class DLL_PREFIX GLDraw_Tmpl : public QObject virtual void drawGridsHorizonal(void) { } virtual void drawGridsVertical(void) { } virtual void drawGridsMain(GLfloat *tp, - int number, - GLfloat lineWidth = 0.2f, + int number, + GLfloat lineWidth = 0.2f, QVector4D color = QVector4D(0.0f, 0.0f, 0.0f, 1.0f)) { } virtual void drawButtons() { } - virtual void drawOsdLeds() { } - virtual void drawOsdIcons() { } + virtual void prologueBlending() {} + virtual void epilogueBlending() {} + virtual void drawPolygon(int vertex_loc, uintptr_t p = 0) {} + + virtual void drawLedMain(GLScreenPack *obj, int num, QVector4D color); + virtual void drawOsdLeds(); + virtual void drawOsdIcons(); virtual void set_osd_vertex(int xbit) { } public: - GLDraw_Tmpl(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu = 0) : QObject((QObject *)parent) - { - p_wid = parent; - using_flags = p; - p_config = p->get_config_ptr(); - vert_lines = using_flags->get_real_screen_height(); - horiz_pixels = using_flags->get_real_screen_width(); - screen_texture_width = using_flags->get_screen_width(); - screen_texture_width_old = using_flags->get_screen_width(); - screen_texture_height = using_flags->get_screen_height(); - screen_texture_height_old = using_flags->get_screen_height(); - - if(using_flags->is_use_fd()) { - osd_led_bit_width = 10; - } - if(using_flags->is_use_qd()) { - osd_led_bit_width = 12; - } - if(using_flags->is_use_tape()) { - osd_led_bit_width = 16; - } - if(using_flags->get_max_scsi() > 0) { - osd_led_bit_width = 24; - } - - int i; - // Will fix: Must fix setup of vm_buttons[]. - button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); - if(vm_buttons_d != NULL) { - for(i = 0; i < using_flags->get_max_button(); i++) { - uButtonTextureID[i] = new QOpenGLTexture(QOpenGLTexture::Target2D);; - fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width(); - fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height(); - fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width(); - fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height(); - } // end of will fix. - } - - for(int i = 0; i < 10; i++) { - for(int j = 0; j < 10; j++) { - icon_texid[i][j] = NULL; - } - } - - rec_width = using_flags->get_screen_width(); - rec_height = using_flags->get_screen_height(); - ButtonImages.clear(); - - csp_logger = logger; - - gl_grid_horiz = false; - gl_grid_vert = false; - glVertGrids = NULL; - glHorizGrids = NULL; - - set_brightness = false; - crt_flag = false; - smoosing = false; - uVramTextureID = NULL; - emu_launched = false; - - imgptr = NULL; - screen_multiply = 1.0f; - redraw_required = false; - - osd_led_status = 0x00000000; - osd_led_status_bak = 0x00000000; - osd_led_bit_width = 12; - - osd_onoff = true; - - uBitmapTextureID = NULL; - bitmap_uploaded = false; - texture_max_size = 128; - low_resolution_screen = false; - - button_updated = false; - button_drawn = false; - - fBrightR = 1.0; // 輝度の初期化 - fBrightG = 1.0; - fBrightB = 1.0; - set_brightness = false; - crt_flag = false; - smoosing = false; - - screen_width = 1.0; - screen_height = 1.0; - - buffer_screen_vertex = NULL; - vertex_screen = NULL; - - offscreen_frame_buffer = NULL; - offscreen_frame_buffer_format = NULL; - rec_count = 0; - - } - ~GLDraw_Tmpl() {} - + GLDraw_Tmpl(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu = 0); + ~GLDraw_Tmpl(); virtual void initGLObjects() {} virtual void initFBO(void) {} virtual void initLocalGLObjects(void) {} @@ -258,7 +396,7 @@ class DLL_PREFIX GLDraw_Tmpl : public QObject virtual void drawScreenTexture(void) {} virtual void drawGrids(void) { } - virtual void uploadBitmapTexture(QImage *p) {} + virtual void uploadBitmapTexture(QImage *p); virtual void drawMain(QOpenGLShaderProgram *prg, QOpenGLVertexArrayObject *vp, QOpenGLBuffer *bp, @@ -267,68 +405,36 @@ class DLL_PREFIX GLDraw_Tmpl : public QObject QVector4D color, bool f_smoosing, bool do_chromakey = false, QVector3D chromakey = QVector3D(0.0f, 0.0f, 0.0f)) {} - virtual void doSetGridsHorizonal(int lines, bool force) - { - int i; - GLfloat yf; - GLfloat delta; - - if((lines == vert_lines) && !force) return; - //printf("lines: %d\n", lines); - vert_lines = lines; - yf = -screen_height; - if(vert_lines <= 0) return; - if(vert_lines > using_flags->get_real_screen_height()) vert_lines = using_flags->get_real_screen_height(); - - delta = (2.0f * screen_height) / (float)vert_lines; - yf = yf - delta * 1.0f; - if(glHorizGrids != NULL) { - for(i = 0; i < (vert_lines + 1) ; i++) { - glHorizGrids[i * 6] = -screen_width; // XBegin - glHorizGrids[i * 6 + 3] = +screen_width; // XEnd - glHorizGrids[i * 6 + 1] = yf; // YBegin - glHorizGrids[i * 6 + 4] = yf; // YEnd - glHorizGrids[i * 6 + 2] = -0.95f; // ZBegin - glHorizGrids[i * 6 + 5] = -0.95f; // ZEnd - yf = yf + delta; - } - } - } - virtual void doSetGridsVertical(int pixels, bool force) - { - int i; - GLfloat xf; - GLfloat delta; + virtual void drawMain(QOpenGLShaderProgram *prg, + QOpenGLVertexArrayObject *vp, + QOpenGLBuffer *bp, + GLuint texid, + QVector4D color, + bool f_smoosing, + bool do_chromakey = false, + QVector3D chromakey = QVector3D(0.0f, 0.0f, 0.0f)) {} - if((pixels == horiz_pixels) && !force) return; - horiz_pixels = pixels; - if(horiz_pixels <= 0) return; - if(horiz_pixels > using_flags->get_real_screen_width()) horiz_pixels = using_flags->get_real_screen_width(); + virtual void drawMain(GLScreenPack *obj, + GLuint texid, + QVector4D color, bool f_smoosing, + bool do_chromakey = false, + QVector3D chromakey = QVector3D(0.0f, 0.0f, 0.0f)) {} - xf = -screen_width; - delta = (2.0f * screen_width) / (float)horiz_pixels; - xf = xf - delta * 0.75f; - if(glVertGrids != NULL) { - if(horiz_pixels > using_flags->get_real_screen_width()) horiz_pixels = using_flags->get_real_screen_width(); - for(i = 0; i < (horiz_pixels + 1) ; i++) { - glVertGrids[i * 6] = xf; // XBegin - glVertGrids[i * 6 + 3] = xf; // XEnd - glVertGrids[i * 6 + 1] = -screen_height; // YBegin - glVertGrids[i * 6 + 4] = screen_height; // YEnd - glVertGrids[i * 6 + 2] = -0.95f; // ZBegin - glVertGrids[i * 6 + 5] = -0.95f; // ZEnd - xf = xf + delta; - } - } - } + virtual void doSetGridsHorizonal(int lines, bool force); + virtual void doSetGridsVertical(int pixels, bool force); + virtual bool copy_screen_buffer(scrntype_t* target,int w, int h, int stride) { return false;}; virtual scrntype_t *get_screen_buffer(int y) { return NULL; } virtual void get_screen_geometry(int *w, int *h) { if(w != NULL) *w = 0; if(h != NULL) *h = 0; } + virtual float get_screen_scaling_factor(){ + return QApplication::primaryScreen()->devicePixelRatio(); + } virtual bool is_ready_to_map_vram_texture(void) { return false; } virtual bool map_vram_texture(void) { return false; } virtual bool unmap_vram_texture(void) { return false; } + public slots: virtual void paintGL(void) { } virtual void resizeGL(int width, int height) { } @@ -347,13 +453,13 @@ public slots: virtual void setChangeBrightness(bool) { } virtual void do_set_screen_multiply(float mul) { } - virtual void updateBitmap(QImage *) { } + virtual void updateBitmap(QImage *); virtual void paintGL_OffScreen(int count, int w, int h) { } - virtual void uploadIconTexture(QPixmap *p, int icon_type, int localnum) { } + virtual void uploadIconTexture(QPixmap *p, int icon_type, int localnum); virtual void set_emu_launched(void) { } - virtual void do_set_display_osd(bool onoff) { } - virtual void do_display_osd_leds(int lednum, bool onoff) { } + virtual void do_set_display_osd(bool onoff); + virtual void do_display_osd_leds(int lednum, bool onoff); virtual void do_set_led_width(int bitwidth) { } virtual bool is_mapped_buffer(void) { return false; } virtual GLuint get_mapped_buffer_num(int region) { return (GLuint)0; } diff --git a/source/src/qt/gui/gl/shaders/afterglow.frag b/source/src/qt/gui/gl/shaders/afterglow.frag new file mode 100644 index 000000000..337a615a8 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/afterglow.frag @@ -0,0 +1,91 @@ +// Afterglow Shader - written by Kyuma Ohta +// License: GPLv2 + +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif +#if (__VERSION__ >= 300) +#define _CONST const +#else +#define _CONST +#endif + +#if (__VERSION__ >= 300) +in mediump vec2 v_texcoord; +out mediump vec4 opixel; +#else // ES2.x or Compatible profile +varying mediump vec2 v_texcoord; +#endif + +#define PHASES 6 +uniform sampler2D newest_texture; +uniform sampler2D texture1; +uniform sampler2D texture2; +uniform sampler2D texture3; +uniform sampler2D texture4; +uniform sampler2D texture5; +//uniform sampler2D texture6; +//uniform sampler2D texture7; + +uniform vec2 source_size; +uniform vec2 target_size; +uniform float phase; + +#if (__VERSION__ >= 300) +in mediump vec2 v_texcoord; +out mediump vec4 opixel; +#else // ES2.x or Compatible profile +varying mediump vec2 v_texcoord; +#endif + +#if (__VERSION__ >= 300) + _CONST float pixel_factor[PHASES] = float[PHASES]( + 0.8, + 0.11, + 0.055, + 0.025, + 0.008, + 0.002 + ); +#else + float pixel_factor[PHASES]; +#endif + +void main() +{ + vec4 texel[PHASES]; + vec4 ratio[PHASES]; + for(int i=0; i < PHASES; i++) { + ratio[i] = vec(pixel_factor[i], pixel_factor[i], pixel_factor[i], 1.0); + } + texel[0] = texture(newest_texture, v_texcoord); + texel[1] = texture(texture1, v_texcoord); + texel[2] = texture(texture2, v_texcoord); + texel[3] = texture(texture3, v_texcoord); + texel[4] = texture(texture4, v_texcoord); + texel[5] = texture(texture5, v_texcoord); + + vec4 pixel = vec4(0.0); + for(int i = 0; i < PHASES; i++) { + pixel += (texel[i] * ratio[i]); + } +#if (__VERSION__ >= 300) + opixel = pixel; +#else + gl_FragColor = pixel; +#endif +} \ No newline at end of file diff --git a/source/src/qt/gui/gl/shaders/chromakey_fragment_shader.glsl b/source/src/qt/gui/gl/shaders/chromakey_fragment_shader.glsl new file mode 100644 index 000000000..295f7b165 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/chromakey_fragment_shader.glsl @@ -0,0 +1,64 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +in vec2 v_texcoord; +out vec4 opixel; +#else +varying vec2 v_texcoord; +#endif + +uniform vec4 color; +uniform vec3 chromakey; +uniform bool do_chromakey; +uniform bool swap_byteorder; +uniform sampler2D a_texture; +void main () +{ + vec4 pixel_r_1; + vec4 pixel; + +#if (__VERSION__ >= 300) + pixel_r_1 = texture(a_texture, v_texcoord); +#else + pixel_r_1 = texture2D(a_texture, v_texcoord); +#endif + if(do_chromakey) { + if(pixel_r_1.rgb != chromakey.rgb) { + pixel_r_1 = pixel_r_1 * color; + pixel = vec4(pixel_r_1.rgb, 1.0); +#if (__VERSION__ >= 300) + opixel = pixel; +#else + gl_FragColor = pixel; +#endif + } else { + pixel = vec4(0.0); + //discard; + } + } else { + pixel_r_1 = pixel_r_1 * color; + pixel = vec4(pixel_r_1.rgb, 1.0); +#if (__VERSION__ >= 300) + opixel = pixel; +#else + gl_FragColor = pixel; +#endif + } +} + diff --git a/source/src/qt/gui/gl/shaders/chromakey_fragment_shader2.glsl b/source/src/qt/gui/gl/shaders/chromakey_fragment_shader2.glsl new file mode 100644 index 000000000..abac186c8 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/chromakey_fragment_shader2.glsl @@ -0,0 +1,63 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +in vec2 v_texcoord; +//in mediump float luminance; +//in mediump float lum_offset; +out vec4 opixel; +#else +varying vec2 v_texcoord; +//varying mediump float luminance; +//varying mediump float lum_offset; +#endif + +uniform mediump float luminance; +uniform mediump float lum_offset; + +uniform vec4 color; +uniform vec3 chromakey; +uniform sampler2D a_texture; + +void main () +{ + vec4 pixel_r_1; + vec4 pixel; + bvec3 _match; + +#if (__VERSION__ >= 300) + pixel_r_1 = texture(a_texture, v_texcoord); +#else + pixel_r_1 = texture2D(a_texture, v_texcoord); +#endif + _match = equal(pixel_r_1.rgb, chromakey.rgb); + if(all(_match)) { + pixel = vec4(0.0, 0.0, 0.0, 0.0); + } else { +#if (__VERSION__ < 400) + pixel = vec4(pixel_r_1.rgb, 1.0) * vec4(luminance, luminance, luminance, 1.0) + vec4(lum_offset, lum_offset, lum_offset,0.0); +#else + pixel = fma(vec4(pixel_r_1.rgb, 1.0),vec4(luminance, luminance, luminance, 1.0), vec4(lum_offset, lum_offset, lum_offset, 0.0)); +#endif + } +#if (__VERSION__ >= 300) + opixel = pixel; +#else + gl_FragColor = pixel; +#endif +} diff --git a/source/src/qt/gui/gl/shaders/distortion_fragment.frag b/source/src/qt/gui/gl/shaders/distortion_fragment.frag new file mode 100644 index 000000000..21cfe23d4 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/distortion_fragment.frag @@ -0,0 +1,90 @@ +// Fragmant shader for distortion screen. +// Oct 15, 2020 Kyuma Ohta +// License: GPLv2 +// +// In values: +// a_texture: source texture (sampler2D). +// v_texcoord: source texture coordinate (vec2(s, t)). +// color: Color multiply value (vec4(R, G, B, A)) . +// distortion_v: CRT Distortion factor, vec2(H, V). +// luminance: CRT luminance multiply factor(float). +// lum_offset: Luminance offset (float). +// +// Out value: +// o_pixel: Output pixel(vec4(R, G, B, A)). + +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +#define _CONST const +#else +#define _CONST +#endif + +#if (__VERSION__ >= 300) +in vec2 v_texcoord; +out vec4 opixel; +#else +varying vec2 v_texcoord; +#endif + +uniform sampler2D a_texture; +uniform vec4 color; +uniform vec2 distortion_v; +uniform mediump float luminance; +uniform mediump float lum_offset; + +// Note: This distortion shading from: +// CRT-Geom.shader/curvature.fs , https://github.com/hizzlekizzle/quark-shaders +vec2 radialDistortion(vec2 coord) +{ + vec2 cc = coord - vec2(0.5); + vec2 dist = dot(cc, cc) * distortion_v; // H, V + return coord + cc * (vec2(1.0) - dist) * dist; +} + +void main () +{ + vec2 dist = radialDistortion(v_texcoord); + bvec4 d; +#if (__VERSION__ >= 300) + vec4 pixel = texture(a_texture, dist); +#else + vec4 pixel = texture2D(a_texture, dist); +#endif + // Edge clipping is needed. + _CONST vec2 high = vec2(1.0, 1.0); + _CONST vec2 low = vec2(0.0, 0.0); + d.xy = lessThan(dist, low); + d.zw = greaterThan(dist, high); + if(any(d)) { + pixel = vec4(0.0, 0.0, 0.0, 0.0); + } else { +#if (__VERSION__ < 400) + pixel = vec4(pixel.rgb, 1.0) * vec4(luminance, luminance, luminance, 1.0) + vec4(lum_offset, lum_offset, lum_offset, 0.0); +#else + pixel = fma(vec4(pixel.rgb, 1.0), vec4(luminance, luminance, luminance, 1.0), vec4(lum_offset, lum_offset, lum_offset, 0.0)); +#endif + } +#if (__VERSION__ >= 300) + opixel = pixel * color; +#else + gl_FragColor = pixel * color; +#endif +} diff --git a/source/src/qt/gui/gl/shaders/fragment_shader.glsl b/source/src/qt/gui/gl/shaders/fragment_shader.glsl new file mode 100644 index 000000000..2f45347d6 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/fragment_shader.glsl @@ -0,0 +1,72 @@ +// Fragmant shader for standard screen. +// Oct 15, 2020 Kyuma Ohta +// License: GPLv2 +// +// In values: +// a_texture: source texture (sampler2D). +// v_texcoord: source texture coordinate (vec2(s, t)). +// color: Color multiply value (vec4(R, G, B, A)) . +// luminance: CRT luminance multiply factor(float). +// lum_offset: Luminance offset (float). +// +// Out value: +// o_pixel: Output pixel(vec4(R, G, B, A)). + +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +#define _CONST const +#else +#define _CONST +#endif + +#if (__VERSION__ >= 300) +in vec2 v_texcoord; +out vec4 opixel; +#else +varying vec2 v_texcoord; +#endif + +uniform sampler2D a_texture; +uniform vec4 color; +uniform mediump float luminance; +uniform mediump float lum_offset; + +void main () +{ + vec2 dist = v_texcoord; + bvec4 d; +#if (__VERSION__ >= 300) + vec4 pixel = texture(a_texture, dist); +#else + vec4 pixel = texture2D(a_texture, dist); +#endif + { +#if (__VERSION__ < 400) + pixel = vec4(pixel.rgb, 1.0) * vec4(luminance, luminance, luminance, 1.0) + vec4(lum_offset, lum_offset, lum_offset, 0.0); +#else + pixel = fma(vec4(pixel.rgb, 1.0), vec4(luminance, luminance, luminance, 1.0), vec4(lum_offset, lum_offset, lum_offset, 0.0)); +#endif + } +#if (__VERSION__ >= 300) + opixel = pixel * color; +#else + gl_FragColor = pixel * color; +#endif +} diff --git a/source/src/qt/gui/gl/shaders/grids_fragment_shader.glsl b/source/src/qt/gui/gl/shaders/grids_fragment_shader.glsl new file mode 100644 index 000000000..c7563cf56 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/grids_fragment_shader.glsl @@ -0,0 +1,32 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +uniform vec4 color; + +#if (__VERSION__ >= 300) +out vec4 opixel; +#endif +void main () +{ +#if (__VERSION__ >= 300) + opixel = color; +#else + gl_FragColor = color; +#endif +} + diff --git a/source/src/qt/gui/gl/shaders/grids_vertex_shader.glsl b/source/src/qt/gui/gl/shaders/grids_vertex_shader.glsl new file mode 100644 index 000000000..1095f35be --- /dev/null +++ b/source/src/qt/gui/gl/shaders/grids_vertex_shader.glsl @@ -0,0 +1,32 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +in vec3 vertex; +#else +attribute vec3 vertex; +#endif + +uniform mat2 rotate_mat; +void main () +{ + vec2 xy = vertex.xy; + xy = rotate_mat * xy; + gl_Position = vec4(xy, vertex.z, 1.0); +} + diff --git a/source/src/qt/gui/gl/shaders/grids_vertex_shader_fixed.glsl b/source/src/qt/gui/gl/shaders/grids_vertex_shader_fixed.glsl new file mode 100644 index 000000000..f5921a499 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/grids_vertex_shader_fixed.glsl @@ -0,0 +1,27 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +int vec3 vertex; +void main () +{ + vec4 tmpvar_1; + tmpvar_1.w = 1.0; + tmpvar_1.xyz = vertex; + gl_Position = tmpvar_1; +} + diff --git a/source/src/qt/gui/gl/shaders/icon_fragment_shader.glsl b/source/src/qt/gui/gl/shaders/icon_fragment_shader.glsl new file mode 100644 index 000000000..c9b10ff40 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/icon_fragment_shader.glsl @@ -0,0 +1,50 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +in vec2 v_texcoord; +out mediump vec4 opixel; +#else +varying vec2 v_texcoord; +#endif + +uniform vec4 color; +uniform vec3 chromakey; +uniform bool do_chromakey; +uniform sampler2D a_texture; +void main () +{ + vec4 pixel_r_1; + vec4 pixel; + float alpha; +#if (__VERSION__ >= 300) + pixel_r_1 = texture(a_texture, v_texcoord); +#else + pixel_r_1 = texture2D(a_texture, v_texcoord); +#endif + //alpha = pixel_r_1.a * color.a; + + pixel_r_1 = pixel_r_1 * color; + pixel = pixel_r_1 * color; //;vec4(pixel_r_1.rgb, alpha); +#if (__VERSION__ >= 300) + opixel = pixel; +#else + gl_FragColor = pixel; +#endif +} + diff --git a/source/src/qt/gui/gl/shaders/led_fragment_shader.glsl b/source/src/qt/gui/gl/shaders/led_fragment_shader.glsl new file mode 100644 index 000000000..f13e020a8 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/led_fragment_shader.glsl @@ -0,0 +1,33 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +uniform vec4 color; +#if (__VERSION__ >= 300) +out mediump vec4 opixel; +#endif + +void main () +{ +#if (__VERSION__ >= 300) + opixel = color; +#else + gl_FragColor = color; +#endif +} + + diff --git a/source/src/qt/gui/gl/shaders/led_vertex_shader.glsl b/source/src/qt/gui/gl/shaders/led_vertex_shader.glsl new file mode 100644 index 000000000..2280e3fcf --- /dev/null +++ b/source/src/qt/gui/gl/shaders/led_vertex_shader.glsl @@ -0,0 +1,33 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +in vec3 vertex; +#else +attribute vec3 vertex; +#endif + +uniform mat2 rotate_mat; + +void main () +{ + vec2 xy = vertex.xy; + xy = rotate_mat * xy; + gl_Position = vec4(xy, vertex.z, 1.0); +} + diff --git a/source/src/qt/gui/gl/shaders/normal_fragment_shader.glsl b/source/src/qt/gui/gl/shaders/normal_fragment_shader.glsl new file mode 100644 index 000000000..9ca982aa0 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/normal_fragment_shader.glsl @@ -0,0 +1,36 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +in vec2 v_texcoord; +out mediump vec4 opixel; +#else +varying vec2 v_texcoord; +#endif + +uniform sampler2D a_texture; +uniform vec4 color; +void main () +{ +#if (__VERSION__ >= 300) + opixel = texture(a_texture, v_texcoord) * color; +#else + gl_FragColor = texture(a_texture, v_texcoord) * color; +#endif +} + diff --git a/source/src/qt/gui/gl/shaders/ntsc_pass1.glsl b/source/src/qt/gui/gl/shaders/ntsc_pass1.glsl new file mode 100644 index 000000000..5d5da0178 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/ntsc_pass1.glsl @@ -0,0 +1,149 @@ +// NTSC Shader - written by Hans-Kristian Arntzen +// License: GPLv3 +// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif +#if (__VERSION__ >= 300) +#define _CONST const +#else +#define _CONST +#endif + +#if (__VERSION__ >= 300) +in mediump vec2 v_texcoord; +out mediump vec4 opixel; +#else // ES2.x or Compatible profile +varying mediump vec2 v_texcoord; +#endif + +uniform sampler2D a_texture; +uniform vec2 source_size; +uniform vec2 target_size; +uniform float phase; + + +#define THREE_PHASE //options here include THREE_PHASE, TWO_PHASE or OLD_THREE_PHASE +#define COMPOSITE + +// #include "ntsc-param.inc" // +#define PI 3.14159265 + +#if defined(TWO_PHASE) +#define CHROMA_MOD_FREQ (4.0 * PI / 15.0) +#elif defined(THREE_PHASE) +#define CHROMA_MOD_FREQ (PI / 6.0) +#endif + +#if defined(COMPOSITE) +#define SATURATION 1.2 +#define BRIGHTNESS 1.1 +#define ARTIFACTING 1.8 +#define FRINGING 1.0 +#elif defined(SVIDEO) +#define SATURATION 1.0 +#define BRIGHTNESS 1.0 +#define ARTIFACTING 0.0 +#define FRINGING 0.0 +#endif + +#if defined(COMPOSITE) || defined(SVIDEO) +_CONST mat3 mix_mat = mat3( + BRIGHTNESS, FRINGING, FRINGING, + ARTIFACTING, 2.0 * SATURATION, 0.0, + ARTIFACTING, 0.0, 2.0 * SATURATION +); +#endif +// END "ntsc-param.inc" // + +// moved from vertex +#define pix_no (v_texcoord.xy * source_size.xy * (target_size.xy / source_size.xy)) + +// Change Matrix: [RGB]->[YCbCr] + +_CONST mat3 ycbcr_mat = mat3( + 0.29891, -0.16874, 0.50000, + 0.58661, -0.33126, -0.41869, + 0.11448, 0.50000, -0.08131 +); + +vec3 rgb2ycbcr(vec3 foo) +{ + return (foo * ycbcr_mat); +} + +// #include ntsc-rgbyuv.inc // +_CONST mat3 yiq2rgb_mat = mat3( + 1.0, 1.0, 1.0, + 0.956, -0.2720, -1.1060, + 0.6210, -0.6474, 1.7046 +); + +vec3 yiq2rgb(vec3 yiq) +{ + return (yiq * yiq2rgb_mat); +} + +_CONST mat3 yiq_mat = mat3( + 0.2989, 0.5959, 0.2115, + 0.5870, -0.2744, -0.5229, + 0.1140, -0.3216, 0.3114 +); + +vec3 rgb2yiq(vec4 col) +{ + return (col.xyz * yiq_mat); +} +// END ntsc-rgbyuv.inc // + +void main() +{ + // #include "ntsc-pass1-encode-demodulate.inc" // + vec4 col; +#if (__VERSION__ >= 300) + col = texture(a_texture, v_texcoord); +#else + col = texture2D(a_texture, v_texcoord); +#endif + vec3 ycbcr; + ycbcr = rgb2yiq(col); +#if defined(TWO_PHASE) + float chroma_phase = PI * (mod(pix_no.y, 2.0) + phase); +#elif defined(THREE_PHASE) + float chroma_phase = 0.6667 * PI * (mod(pix_no.y, 3.0) + phase); +#endif + + float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ; + + float i_mod = cos(mod_phase); + float q_mod = sin(mod_phase); + + ycbcr *= vec3(1.0, i_mod, q_mod); // Modulate +#if defined(COMPOSITE) || defined(SVIDEO) + ycbcr *= mix_mat; // Cross-talk +#endif + ycbcr *= vec3(1.0, i_mod, q_mod); // Demodulate +#ifndef HAS_FLOAT_TEXTURE +// ycbcr = ycbcr * vec3(0.277778 ,0.588235, 0.588235); +#endif +#if (__VERSION__ >= 300) + opixel = vec4(ycbcr, 1.0); +#else + gl_FragColor = vec4(ycbcr, 1.0); +#endif +// END "ntsc-pass1-encode-demodulate.inc" // +} \ No newline at end of file diff --git a/source/src/qt/gui/gl/shaders/ntsc_pass2.glsl b/source/src/qt/gui/gl/shaders/ntsc_pass2.glsl new file mode 100644 index 000000000..d65cb1857 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/ntsc_pass2.glsl @@ -0,0 +1,298 @@ +// NTSC Shader - written by Hans-Kristian Arntzen +// License: GPLv3 +// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +#define _CONST const +#else +#define _CONST +#endif + +#define GAMMA_CORRECTION //comment to disable gamma correction, usually because higan's gamma correction is enabled or you have another shader already doing it +#define CRT_GAMMA 2.5 +#define DISPLAY_GAMMA 2.1 + +#define GAMMA_FACTOR (CRT_GAMMA / DISPLAY_GAMMA) + +#if (__VERSION__ >= 300) +in mediump vec2 v_texcoord; +out vec4 opixel; +#else // ES2.x or Compatible profile +varying mediump vec2 v_texcoord; +#endif + +uniform sampler2D a_texture; +uniform vec2 source_size; +uniform vec2 target_size; + + +#define TAPS 24 +#define THREE_PHASE + +#if (__VERSION__ >= 300) + #if defined OLD_THREE_PHASE + _CONST float luma_filter[TAPS + 1] = float[TAPS + 1]( + -0.000071070, + -0.000032816, + 0.000128784, + 0.000134711, + -0.000226705, + -0.000777988, + -0.000997809, + -0.000522802, + 0.000344691, + 0.000768930, + 0.000275591, + -0.000373434, + 0.000522796, + 0.003813817, + 0.007502825, + 0.006786001, + -0.002636726, + -0.019461182, + -0.033792479, + -0.029921972, + 0.005032552, + 0.071226466, + 0.151755921, + 0.218166470, + 0.243902439); + _CONST float chroma_filter[TAPS + 1] = float[TAPS + 1]( + 0.001845562, + 0.002381606, + 0.003040177, + 0.003838976, + 0.004795341, + 0.005925312, + 0.007242534, + 0.008757043, + 0.010473987, + 0.012392365, + 0.014503872, + 0.016791957, + 0.019231195, + 0.021787070, + 0.024416251, + 0.027067414, + 0.029682613, + 0.032199202, + 0.034552198, + 0.036677005, + 0.038512317, + 0.040003044, + 0.041103048, + 0.041777517, + 0.042004791); + #elif defined(THREE_PHASE) +// #include "ntsc-decode-filter-3phase.inc" // + _CONST float luma_filter[TAPS + 1] = float[TAPS + 1]( + -0.000012020, + -0.000022146, + -0.000013155, + -0.000012020, + -0.000049979, + -0.000113940, + -0.000122150, + -0.000005612, + 0.000170516, + 0.000237199, + 0.000169640, + 0.000285688, + 0.000984574, + 0.002018683, + 0.002002275, + -0.000909882, + -0.007049081, + -0.013222860, + -0.012606931, + 0.002460860, + 0.035868225, + 0.084016453, + 0.135563500, + 0.175261268, + 0.190176552); + + _CONST float chroma_filter[TAPS + 1] = float[TAPS + 1]( + -0.000118847, + -0.000271306, + -0.000502642, + -0.000930833, + -0.001451013, + -0.002064744, + -0.002700432, + -0.003241276, + -0.003524948, + -0.003350284, + -0.002491729, + -0.000721149, + 0.002164659, + 0.006313635, + 0.011789103, + 0.018545660, + 0.026414396, + 0.035100710, + 0.044196567, + 0.053207202, + 0.061590275, + 0.068803602, + 0.074356193, + 0.077856564, + 0.079052396); + // END "ntsc-decode-filter-3phase.inc" // + #elif defined(TWO_PHASE) +// #include "ntsc-decode-filter-3phase.inc" // + _CONST float luma_filter[TAPS + 1] = float[TAPS + 1]( + -0.000012020, + -0.000022146, + -0.000013155, + -0.000012020, + -0.000049979, + -0.000113940, + -0.000122150, + -0.000005612, + 0.000170516, + 0.000237199, + 0.000169640, + 0.000285688, + 0.000984574, + 0.002018683, + 0.002002275, + -0.000909882, + -0.007049081, + -0.013222860, + -0.012606931, + 0.002460860, + 0.035868225, + 0.084016453, + 0.135563500, + 0.175261268, + 0.190176552); + _CONST float chroma_filter[TAPS + 1] = float[TAPS + 1]( + -0.000118847, + -0.000271306, + -0.000502642, + -0.000930833, + -0.001451013, + -0.002064744, + -0.002700432, + -0.003241276, + -0.003524948, + -0.003350284, + -0.002491729, + -0.000721149, + 0.002164659, + 0.006313635, + 0.011789103, + 0.018545660, + 0.026414396, + 0.035100710, + 0.044196567, + 0.053207202, + 0.061590275, + 0.068803602, + 0.074356193, + 0.077856564, + 0.079052396); + // END "ntsc-decode-filter-3phase.inc" // + #endif +#else // __VERSION__ < 300, GLES2 or GL3 +uniform float luma_filter[TAPS + 1]; +uniform float chroma_filter[TAPS + 1]; +// END "ntsc-decode-filter-3phase.inc" // +#endif + + +// #include ntsc-rgbyuv.inc // +_CONST mat3 ycbcr2rgb_mat = mat3( + 1.0, 1.0, 1.0, + 0.0, -0.34414 , 1.77200, + 1.40200, -0.71414, 0.0 + ); + +vec3 ycbcr2rgb(vec3 foo) +{ + return foo * ycbcr2rgb_mat; +} +// END ntsc-rgbyuv.inc // +// #include ntsc-rgbyuv.inc // +_CONST mat3 yiq2rgb_mat = mat3( + 1.0, 1.0, 1.0, + 0.956, -0.2720, -1.1060, + 0.6210, -0.6474, 1.7046 +); + +vec3 yiq2rgb(vec3 yiq) +{ + return (yiq * yiq2rgb_mat); +} + +_CONST mat3 yiq_mat = mat3( + 0.2989, 0.5959, 0.2115, + 0.5870, -0.2744, -0.5229, + 0.1140, -0.3216, 0.3114 +); + +vec3 rgb2yiq(vec3 col) +{ + return (col * yiq_mat); +} +// END ntsc-rgbyuv.inc // + +#define fixCoord (v_texcoord - vec2(0.5 / source_size.x, 0.0)) // Compensate for decimate-by-2. +#if __VERSION__ >= 300 +#define fetch_offset(offset, one_x) \ + texture(a_texture, fixCoord + vec2((offset) * (one_x), 0.0)).xyz +#else +#define fetch_offset(offset, one_x) \ + texture2D(a_texture, fixCoord + vec2((offset) * (one_x), 0.0)).xyz +#endif + +void main() +{ + float one_x = 1.0 / source_size.x; + vec3 signal = vec3(0.0); + for (int i = 0; i < TAPS; i++) + { + float offset = float(i); + vec3 sums = fetch_offset(offset - float(TAPS), one_x) + + fetch_offset(float(TAPS) - offset, one_x); + + signal += sums * vec3(luma_filter[i], chroma_filter[i], chroma_filter[i]); + } +#if __VERSION__ >= 300 + signal += texture(a_texture, fixCoord).xyz * vec3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]); +#else + signal += texture2D(a_texture, fixCoord).xyz * vec3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]); +#endif + + vec3 rgb; + rgb = yiq2rgb(signal); + +#ifdef GAMMA_CORRECTION + vec3 gamma = vec3(CRT_GAMMA / DISPLAY_GAMMA); + rgb = pow(rgb, gamma.rgb); +#endif + +#if (__VERSION__ >= 300) + opixel = vec4(rgb, 1.0); +#else + gl_FragColor = vec4(rgb, 1.0); +#endif +} diff --git a/source/src/qt/gui/gl/shaders/tmp_vertex_shader.glsl b/source/src/qt/gui/gl/shaders/tmp_vertex_shader.glsl new file mode 100644 index 000000000..5fdcbfe76 --- /dev/null +++ b/source/src/qt/gui/gl/shaders/tmp_vertex_shader.glsl @@ -0,0 +1,37 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +in vec3 vertex; +in vec2 texcoord; +out vec2 v_texcoord; +#else +attribute vec3 vertex; +attribute vec2 texcoord; +varying vec2 v_texcoord; +#endif + +void main () +{ + vec4 tmpvar_1; + tmpvar_1.w = 1.0; + tmpvar_1.xyz = vertex; + gl_Position = tmpvar_1; + v_texcoord = texcoord; +} + diff --git a/source/src/qt/gui/gl/shaders/vertex_shader.glsl b/source/src/qt/gui/gl/shaders/vertex_shader.glsl new file mode 100644 index 000000000..2babd1d2b --- /dev/null +++ b/source/src/qt/gui/gl/shaders/vertex_shader.glsl @@ -0,0 +1,45 @@ +#if defined(GL_ES) + #define USE_GL_ES 1 +#elif ((__VERSION__ >= 430) || defined(GL_es_profile)) + #if (GL_es_profile) + #define USE_GL_ES 1 + #endif +#endif +#if defined(USE_GL_ES) + #ifdef HAS_FLOAT_TEXTURE + #ifdef HAS_HALF_FLOAT_TEXTURE + #extension GL_OES_texture_half_float : enable + #else + #extension GL_OES_texture_float : enable + #endif + #endif + precision mediump float; +#endif + +#if (__VERSION__ >= 300) +#define _CONST const +#else +#define _CONST +#endif + +#if (__VERSION__ >= 300) +in mediump vec3 vertex; +in mediump vec2 texcoord; +out mediump vec2 v_texcoord; +#else +attribute vec3 vertex; +attribute vec2 texcoord; +varying vec2 v_texcoord; +#endif + +uniform mat2 rotate_mat; + +void main () +{ + vec2 xy = vertex.xy; + xy = rotate_mat * xy; + + gl_Position = vec4(xy, vertex.z, 1.0); + v_texcoord = texcoord; +} + diff --git a/source/src/qt/gui/gl2/chromakey_fragment_shader2.glsl b/source/src/qt/gui/gl2/chromakey_fragment_shader2.glsl index 845749536..399883185 100644 --- a/source/src/qt/gui/gl2/chromakey_fragment_shader2.glsl +++ b/source/src/qt/gui/gl2/chromakey_fragment_shader2.glsl @@ -15,7 +15,8 @@ void main () pixel = vec4(pixel_r_1.rgb, 1.0); gl_FragColor = pixel; } else { - discard; +// discard; + pixel = vec4(0.0); } } diff --git a/source/src/qt/gui/gl2/qt_glutil_gl2_0.cpp b/source/src/qt/gui/gl2/qt_glutil_gl2_0.cpp index 3b3dd8e38..9ad0b0840 100644 --- a/source/src/qt/gui/gl2/qt_glutil_gl2_0.cpp +++ b/source/src/qt/gui/gl2/qt_glutil_gl2_0.cpp @@ -20,7 +20,7 @@ #include "qt_glutil_gl2_0.h" #include "menu_flags.h" -GLDraw_2_0::GLDraw_2_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu) : GLDraw_Tmpl(parent, p, logger, emu) +GLDraw_2_0::GLDraw_2_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu) : GLDraw_Tmpl(parent, p, logger, emu) { extfunc_2 = NULL; @@ -60,10 +60,6 @@ void GLDraw_2_0::initializeGL(void) { } -void GLDraw_2_0::do_set_display_osd(bool onoff) -{ - osd_onoff = onoff; -} void GLDraw_2_0::set_osd_vertex(int xbit) { @@ -129,21 +125,6 @@ void GLDraw_2_0::set_osd_vertex(int xbit) } -void GLDraw_2_0::do_display_osd_leds(int lednum, bool onoff) -{ - if(lednum == -1) { - osd_led_status = (onoff) ? 0xffffffff : 0x00000000; - } else if((lednum >= 0) && (lednum < 32)) { - uint32_t nn; - nn = 0x00000001 << lednum; - if(onoff) { - osd_led_status |= nn; - } else { - osd_led_status &= ~nn; - } - } -} - void GLDraw_2_0::drawOsdLeds() { QVector4D color_on; @@ -165,7 +146,7 @@ void GLDraw_2_0::drawOsdLeds() extfunc_2->glDisable(GL_TEXTURE_2D); extfunc_2->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); extfunc_2->glDisable(GL_DEPTH_TEST); - extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc_2->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); if(osd_led_status != osd_led_status_bak) { if(osd_onoff) { @@ -226,7 +207,7 @@ void GLDraw_2_0::drawOsdIcons() extfunc_2->glEnable(GL_TEXTURE_2D); extfunc_2->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); extfunc_2->glDisable(GL_DEPTH_TEST); - extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc_2->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); if(osd_onoff) { uint32_t _bit = 0x00000001; @@ -251,14 +232,21 @@ void GLDraw_2_0::drawOsdIcons() } else if((ii >= 14) && (ii < 16)) { // CMT(W) major = 5; minor = ii - 14; - } else if(ii >= 16) { - major = 4 + (ii / 8) - 2; - minor = ii % 8; + } else if((ii >= 16) && (ii < 24)) { // HDD + major = 8; + minor = ii - 16; + } else if((ii >= 24) && (ii < 26)) { // CD + major = 6; + minor = ii - 24; + } else if((ii >= 26) && (ii < 28)) { // LD + major = 7; + minor = ii - 26; } else { major = 0; minor = 0; } // ToDo: CD,LD and HDD. + if(icon_texid[major][minor] != NULL) { if(checkf) { drawMain(osd_shader, vertex_osd[ii], buffer_osd[ii], @@ -271,7 +259,8 @@ void GLDraw_2_0::drawOsdIcons() vertexOSD[ii], icon_texid[major][minor]->textureId(), color_off, false); - } + } + } _bit <<= 1; } osd_led_status_bak = osd_led_status; @@ -352,7 +341,7 @@ void GLDraw_2_0::initGLObjects() { extfunc_2 = new QOpenGLFunctions_2_0; extfunc_2->initializeOpenGLFunctions(); - extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc_2->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc_2->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texture_max_size); } @@ -450,35 +439,6 @@ void GLDraw_2_0::initButtons(void) } } -void GLDraw_2_0::initBitmapVertex(void) -{ - if(using_flags->is_use_one_board_computer()) { - vertexBitmap[0].x = -1.0f; - vertexBitmap[0].y = -1.0f; - vertexBitmap[0].z = -0.1f; - vertexBitmap[0].s = 0.0f; - vertexBitmap[0].t = 1.0f; - - vertexBitmap[1].x = +1.0f; - vertexBitmap[1].y = -1.0f; - vertexBitmap[1].z = -0.1f; - vertexBitmap[1].s = 1.0f; - vertexBitmap[1].t = 1.0f; - - vertexBitmap[2].x = +1.0f; - vertexBitmap[2].y = +1.0f; - vertexBitmap[2].z = -0.1f; - vertexBitmap[2].s = 1.0f; - vertexBitmap[2].t = 0.0f; - - vertexBitmap[3].x = -1.0f; - vertexBitmap[3].y = +1.0f; - vertexBitmap[3].z = -0.1f; - vertexBitmap[3].s = 0.0f; - vertexBitmap[3].t = 0.0f; - - } -} void GLDraw_2_0::initBitmapVAO(void) { @@ -696,23 +656,6 @@ void GLDraw_2_0::drawGrids(void) } } -void GLDraw_2_0::updateButtonTexture(void) -{ - int i; - button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); - if(button_updated) return; - if(vm_buttons_d != NULL) { - for(i = 0; i < using_flags->get_max_button(); i++) { - QImage img = ButtonImages.at(i); - if(uButtonTextureID[i] != NULL) { - delete uButtonTextureID[i]; - } - uButtonTextureID[i] = new QOpenGLTexture(img); - } - } - button_updated = true; -} - void GLDraw_2_0::drawButtons() { int i; @@ -800,7 +743,7 @@ void GLDraw_2_0::drawScreenTexture(void) buffer_screen_vertex, vertexFormat, uVramTextureID->textureId(), // v2.0 - color, smoosing); + color, smoosing, false); } } @@ -819,8 +762,9 @@ void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg, QImage *p = imgptr; extfunc_2->glEnable(GL_TEXTURE_2D); - extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height()); - extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); + extfunc_2->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); +// extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); + extfunc_2->glOrtho(1.0f, -1.0f, 1.0f, -1.0f, 1.0, -1.0); extfunc_2->glBindTexture(GL_TEXTURE_2D, texid); if(!f_smoosing) { @@ -830,7 +774,7 @@ void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg, extfunc_2->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); extfunc_2->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); } - +#if 1 if((bp != NULL) && (vp != NULL) && (prg != NULL)) { if((bp->isCreated()) && (vp->isCreated()) && (prg->isLinked())) { bp->bind(); @@ -863,6 +807,11 @@ void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg, break; } prg->setUniformValue("rotate_mat", rot); + if(!(using_flags->is_use_one_board_computer())) { + prg->setUniformValue("distortion_v", 0.08f, 0.08f); // ToDo: Change val + } + prg->setUniformValue("luminance", 0.9f); // ToDo: Change val + prg->setUniformValue("lum_offset", 0.08f); // ToDo: Change val if(do_chromakey) { prg->setUniformValue("chromakey", chromakey); prg->setUniformValue("do_chromakey", GL_TRUE); @@ -895,7 +844,7 @@ void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg, return; } } - +#endif { // Fallback int i; extfunc_2->glDisable(GL_DEPTH_TEST); @@ -911,46 +860,6 @@ void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg, } } -void GLDraw_2_0::uploadBitmapTexture(QImage *p) -{ - if(!using_flags->is_use_one_board_computer()) return; - if(p == NULL) return; - if(!bitmap_uploaded) { - p_wid->makeCurrent(); - if(uBitmapTextureID != NULL) { - delete uBitmapTextureID; - } - uBitmapTextureID = new QOpenGLTexture(*p); - p_wid->doneCurrent(); - bitmap_uploaded = true; - crt_flag = true; - } -} - -void GLDraw_2_0::uploadIconTexture(QPixmap *p, int icon_type, int localnum) -{ - if((icon_type > 8) || (icon_type < 0)) return; - if((localnum >= 9) || (localnum < 0)) return; - if(p == NULL) return; - p_wid->makeCurrent(); - QImage image = p->toImage(); - - if(icon_texid[icon_type][localnum] != NULL) delete icon_texid[icon_type][localnum]; - { - icon_texid[icon_type][localnum] = new QOpenGLTexture(image); - } - p_wid->doneCurrent(); - -} - -void GLDraw_2_0::updateBitmap(QImage *p) -{ - if(!using_flags->is_use_one_board_computer()) return; - redraw_required = true; - bitmap_uploaded = false; - uploadBitmapTexture(p); -} - void GLDraw_2_0::uploadMainTexture(QImage *p, bool use_chromakey, bool was_mapped) { // set vertex @@ -1017,7 +926,6 @@ void GLDraw_2_0::resizeGL_SetVertexs(void) void GLDraw_2_0::resizeGL(int width, int height) { //int side = qMin(width, height); - p_wid->makeCurrent(); extfunc_2->glViewport(0, 0, width, height); extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); crt_flag = true; @@ -1042,7 +950,6 @@ void GLDraw_2_0::resizeGL(int width, int height) if(using_flags->get_max_button() > 0) { updateButtonTexture(); } - p_wid->doneCurrent(); } void GLDraw_2_0::paintGL(void) @@ -1053,7 +960,7 @@ void GLDraw_2_0::paintGL(void) crt_flag = false; } redraw_required = false; - extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc_2->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc_2->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1147,5 +1054,5 @@ void GLDraw_2_0::do_set_horiz_lines(int lines) void GLDraw_2_0::do_set_led_width(int bitwidth) { if((bitwidth >= 0) && (bitwidth < 32)) osd_led_bit_width = bitwidth; - printf("%d\n", bitwidth); +// printf("%d\n", bitwidth); } diff --git a/source/src/qt/gui/gl2/qt_glutil_gl2_0.h b/source/src/qt/gui/gl2/qt_glutil_gl2_0.h index 457fdf649..42a3b0684 100644 --- a/source/src/qt/gui/gl2/qt_glutil_gl2_0.h +++ b/source/src/qt/gui/gl2/qt_glutil_gl2_0.h @@ -21,7 +21,6 @@ #include "../gl/qt_glutil_gl_tmpl.h" QT_BEGIN_NAMESPACE -class EMU; class QEvent; class GLDrawClass; class QOpenGLFramebufferObject; @@ -40,7 +39,7 @@ class DLL_PREFIX GLDraw_2_0 : public GLDraw_Tmpl QOpenGLFunctions_2_0 *extfunc_2; protected: virtual void initButtons(void); - virtual void initBitmapVertex(void); + virtual void initBitmapVAO(void); virtual void setNormalVAO(QOpenGLShaderProgram *prg, QOpenGLVertexArrayObject *vp, QOpenGLBuffer *bp, VertexTexCoord_t *tp, int size = 4); @@ -61,9 +60,8 @@ class DLL_PREFIX GLDraw_2_0 : public GLDraw_Tmpl virtual void drawOsdIcons(); virtual void set_osd_vertex(int xbit); - virtual void updateButtonTexture(void); public: - GLDraw_2_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu = 0); + GLDraw_2_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu = 0); ~GLDraw_2_0(); virtual void initGLObjects(); @@ -75,7 +73,6 @@ class DLL_PREFIX GLDraw_2_0 : public GLDraw_Tmpl virtual void drawScreenTexture(void); void drawGrids(void); - void uploadBitmapTexture(QImage *p); virtual void drawMain(QOpenGLShaderProgram *prg, QOpenGLVertexArrayObject *vp, QOpenGLBuffer *bp, @@ -89,7 +86,6 @@ public slots: virtual void do_set_texture_size(QImage *p, int w, int h); virtual void do_set_horiz_lines(int lines); virtual void do_set_screen_multiply(float mul); - virtual void uploadIconTexture(QPixmap *p, int icon_type, int localnum); void initializeGL(); virtual void paintGL(); @@ -101,11 +97,9 @@ public slots: void setDrawGLGridHoriz(bool); void setVirtualVramSize(int ,int); void setChangeBrightness(bool); - void updateBitmap(QImage *); + void paintGL_OffScreen(int count, int w, int h); void set_emu_launched(void); - void do_set_display_osd(bool onoff); - void do_display_osd_leds(int lednum, bool onoff); void do_set_led_width(int bitwidth); }; QT_END_NAMESPACE diff --git a/source/src/qt/gui/gl3/chromakey_fragment_shader.glsl b/source/src/qt/gui/gl3/chromakey_fragment_shader.glsl deleted file mode 100644 index e78b0426b..000000000 --- a/source/src/qt/gui/gl3/chromakey_fragment_shader.glsl +++ /dev/null @@ -1,28 +0,0 @@ -varying vec2 v_texcoord; -uniform vec4 color; -uniform vec3 chromakey; -uniform bool do_chromakey; -uniform sampler2D a_texture; -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - - pixel_r_1 = texture2D(a_texture, v_texcoord); - - if(do_chromakey) { - if(pixel_r_1.rgb != chromakey.rgb) { - pixel_r_1 = pixel_r_1 * color; - pixel = vec4(pixel_r_1.rgb, 1.0); - gl_FragColor = pixel; - } else { - pixel = vec4(0.0); - //discard; - } - } else { - pixel_r_1 = pixel_r_1 * color; - pixel = vec4(pixel_r_1.rgb, 1.0); - gl_FragColor = pixel; - } -} - diff --git a/source/src/qt/gui/gl3/chromakey_fragment_shader2.glsl b/source/src/qt/gui/gl3/chromakey_fragment_shader2.glsl deleted file mode 100644 index 845749536..000000000 --- a/source/src/qt/gui/gl3/chromakey_fragment_shader2.glsl +++ /dev/null @@ -1,21 +0,0 @@ -varying vec2 v_texcoord; -uniform vec4 color; -uniform vec3 chromakey; -uniform bool do_chromakey; -uniform sampler2D a_texture; -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - - pixel_r_1 = texture2D(a_texture, v_texcoord); - - if(pixel_r_1.rgb != chromakey.rgb) { - pixel_r_1 = pixel_r_1 * color; - pixel = vec4(pixel_r_1.rgb, 1.0); - gl_FragColor = pixel; - } else { - discard; - } -} - diff --git a/source/src/qt/gui/gl3/fragment_shader.glsl b/source/src/qt/gui/gl3/fragment_shader.glsl deleted file mode 100644 index ef884b009..000000000 --- a/source/src/qt/gui/gl3/fragment_shader.glsl +++ /dev/null @@ -1,7 +0,0 @@ -varying vec2 v_texcoord; -uniform sampler2D a_texture; -void main () -{ - gl_FragColor = texture2D (a_texture, v_texcoord); -} - diff --git a/source/src/qt/gui/gl3/grids_fragment_shader.glsl b/source/src/qt/gui/gl3/grids_fragment_shader.glsl deleted file mode 100644 index b0663e8e3..000000000 --- a/source/src/qt/gui/gl3/grids_fragment_shader.glsl +++ /dev/null @@ -1,6 +0,0 @@ -uniform vec4 color; -void main () -{ - gl_FragColor = color; -} - diff --git a/source/src/qt/gui/gl3/grids_vertex_shader.glsl b/source/src/qt/gui/gl3/grids_vertex_shader.glsl deleted file mode 100644 index 5b3a0b937..000000000 --- a/source/src/qt/gui/gl3/grids_vertex_shader.glsl +++ /dev/null @@ -1,9 +0,0 @@ -attribute vec3 vertex; -uniform mat2 rotate_mat; -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - gl_Position = vec4(xy, vertex.z, 1.0); -} - diff --git a/source/src/qt/gui/gl3/grids_vertex_shader_fixed.glsl b/source/src/qt/gui/gl3/grids_vertex_shader_fixed.glsl deleted file mode 100644 index 9ddc45d4a..000000000 --- a/source/src/qt/gui/gl3/grids_vertex_shader_fixed.glsl +++ /dev/null @@ -1,9 +0,0 @@ -attribute vec3 vertex; -void main () -{ - vec4 tmpvar_1; - tmpvar_1.w = 1.0; - tmpvar_1.xyz = vertex; - gl_Position = tmpvar_1; -} - diff --git a/source/src/qt/gui/gl3/icon_fragment_shader.glsl b/source/src/qt/gui/gl3/icon_fragment_shader.glsl deleted file mode 100644 index 687423827..000000000 --- a/source/src/qt/gui/gl3/icon_fragment_shader.glsl +++ /dev/null @@ -1,19 +0,0 @@ -varying vec2 v_texcoord; -uniform vec4 color; -uniform vec3 chromakey; -uniform bool do_chromakey; -uniform sampler2D a_texture; -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - float alpha; - pixel_r_1 = texture2D(a_texture, v_texcoord); - //alpha = pixel_r_1.a * color.a; - - pixel_r_1 = pixel_r_1 * color; - pixel = pixel_r_1 * color; //;vec4(pixel_r_1.rgb, alpha); - gl_FragColor = pixel; - -} - diff --git a/source/src/qt/gui/gl3/led_fragment_shader.glsl b/source/src/qt/gui/gl3/led_fragment_shader.glsl deleted file mode 100644 index 9a755a81d..000000000 --- a/source/src/qt/gui/gl3/led_fragment_shader.glsl +++ /dev/null @@ -1,7 +0,0 @@ -uniform vec4 color; -void main () -{ - gl_FragColor = color; -} - - diff --git a/source/src/qt/gui/gl3/led_vertex_shader.glsl b/source/src/qt/gui/gl3/led_vertex_shader.glsl deleted file mode 100644 index c6d37d351..000000000 --- a/source/src/qt/gui/gl3/led_vertex_shader.glsl +++ /dev/null @@ -1,10 +0,0 @@ -attribute vec3 vertex; -uniform mat2 rotate_mat; - -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - gl_Position = vec4(xy, vertex.z, 1.0); -} - diff --git a/source/src/qt/gui/gl3/normal_fragment_shader.glsl b/source/src/qt/gui/gl3/normal_fragment_shader.glsl deleted file mode 100644 index 9ad765c27..000000000 --- a/source/src/qt/gui/gl3/normal_fragment_shader.glsl +++ /dev/null @@ -1,8 +0,0 @@ -varying vec2 v_texcoord; -uniform sampler2D a_texture; -uniform vec4 color; -void main () -{ - gl_FragColor = (texture2D (a_texture, v_texcoord) * color); -} - diff --git a/source/src/qt/gui/gl3/ntsc_pass1.glsl b/source/src/qt/gui/gl3/ntsc_pass1.glsl deleted file mode 100644 index 7e2a771dc..000000000 --- a/source/src/qt/gui/gl3/ntsc_pass1.glsl +++ /dev/null @@ -1,111 +0,0 @@ -// NTSC Shader - written by Hans-Kristian Arntzen -// License: GPLv3 -// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 -varying vec2 v_texcoord; - -uniform sampler2D a_texture; -uniform vec4 source_size; -uniform vec4 target_size; -uniform float phase; - -// uniforms added for compatibility -//vec3 col; -//float mod_phase; -//float chroma_phase; - -#define THREE_PHASE -#define COMPOSITE - -// #include "ntsc-param.inc" // -#define PI 3.14159265 - -#if defined(TWO_PHASE) -#define CHROMA_MOD_FREQ (4.0 * PI / 15.0) -#elif defined(THREE_PHASE) -#define CHROMA_MOD_FREQ (PI / 3.0) -#endif - -#if defined(COMPOSITE) -#define SATURATION 1.1 -#define BRIGHTNESS 1.0 -#define ARTIFACTING 1.3 -#define FRINGING 1.2 -#elif defined(SVIDEO) -#define SATURATION 1.0 -#define BRIGHTNESS 1.0 -#define ARTIFACTING 0.0 -#define FRINGING 0.0 -#endif - -#if defined(COMPOSITE) || defined(SVIDEO) -mat3 mix_mat = mat3( - BRIGHTNESS, FRINGING, FRINGING, - ARTIFACTING, 2.0 * SATURATION, 0.0, - ARTIFACTING, 0.0, 2.0 * SATURATION -); -#endif -// END "ntsc-param.inc" // - -// moved from vertex -#define pix_no (v_texcoord.xy * source_size.xy * (target_size.xy / source_size.xy)) - -mat3 yiq2rgb_mat = mat3( - 1.0, 1.0, 1.0, - 0.956, -0.2720, -1.1060, - 0.6210, -0.6474, 1.7046 -); - -vec3 yiq2rgb(vec3 yiq) -{ - return (yiq * yiq2rgb_mat); -} - -mat3 yiq_mat = mat3( - 0.2989, 0.5959, 0.2115, - 0.5870, -0.2744, -0.5229, - 0.1140, -0.3216, 0.3114 -); -vec3 rgb2yiq(vec3 col) -{ - return (col * yiq_mat); -} - -// Change Matrix: [RGB]->[YCbCr] -mat3 ycbcr_mat = mat3( - 0.29891, -0.16874, 0.50000, - 0.58661, -0.33126, -0.41869, - 0.11448, 0.50000, -0.08131 -); - -vec3 rgb2ycbcr(vec3 col) -{ - return (col * ycbcr_mat); -} - -void main() { - // #include "ntsc-pass1-encode-demodulate.inc" // - - vec3 col = texture2D(a_texture, v_texcoord).rgb; - vec3 ycbcr; - ycbcr = rgb2yiq(col); - //ycbcr = rgb2ycbcr(col); - -#if defined(TWO_PHASE) - float chroma_phase = PI * (mod(pix_no.y, 2.0) + phase); -#elif defined(THREE_PHASE) - float chroma_phase = 0.6667 * PI * (mod(pix_no.y, 3.0) + phase); -#endif - - float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ; - - float i_mod = cos(mod_phase); - float q_mod = sin(mod_phase); - - ycbcr *= vec3(1.0, i_mod, q_mod); // Modulate - ycbcr *= mix_mat; // Cross-talk - ycbcr *= vec3(1.0, i_mod, q_mod); // Demodulate - //ycbcr = ycbcr + vec3(0.0, 0.5, 0.5); - gl_FragColor = vec4(ycbcr, 1.0); - -// END "ntsc-pass1-encode-demodulate.inc" // -} \ No newline at end of file diff --git a/source/src/qt/gui/gl3/ntsc_pass2.glsl b/source/src/qt/gui/gl3/ntsc_pass2.glsl deleted file mode 100644 index 0fb979574..000000000 --- a/source/src/qt/gui/gl3/ntsc_pass2.glsl +++ /dev/null @@ -1,110 +0,0 @@ -// NTSC Shader - written by Hans-Kristian Arntzen -// License: GPLv3 -// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 - -varying vec2 v_texcoord; - -uniform sampler2D a_texture; -uniform vec4 source_size; -uniform vec4 target_size; - -#define TAPS 24 -uniform float luma_filter[24 + 1]; -uniform float chroma_filter[24 + 1]; - -#define THREE_PHASE //options here include THREE_PHASE, TWO_PHASE or OLD_THREE_PHASE -#define GAMMA_CORRECTION //comment to disable gamma correction, usually because higan's gamma correction is enabled or you have another shader already doing it -#define CRT_GAMMA 2.5 -#define DISPLAY_GAMMA 2.1 - - -// #include ntsc-rgbyuv.inc // -mat3 yiq2rgb_mat = mat3( - 1.0, 1.0, 1.0, - 0.956, -0.2720, -1.1060, - 0.6210, -0.6474, 1.7046 -); - -vec3 yiq2rgb(vec3 yiq) -{ - //yiq = yiq - vec3(0.0, 0.5, 0.5); - return (yiq * yiq2rgb_mat); -} - -mat3 ycbcr2rgb_mat = mat3( - 1.0, 1.0, 1.0, - 0.0, -0.34414 , 1.77200, - 1.40200, -0.71414, 0.0 - ); - -vec3 ycbcr2rgb(vec3 ycbcr) -{ - //vec3 ra = ycbcr - vec3(0.0, 0.5, 0.5); - vec3 ra = ycbcr; - return (ra * ycbcr2rgb_mat); -} - -mat3 yiq_mat = mat3( - 0.2989, 0.5959, 0.2115, - 0.5870, -0.2744, -0.5229, - 0.1140, -0.3216, 0.3114 -); - -vec3 rgb2yiq(vec3 col) -{ - return (col * yiq_mat); -} -// END ntsc-rgbyuv.inc // - -// fixCoord moved from vertex -#define fixCoord (v_texcoord - vec2(0.5 / source_size.x, 0.0)) // Compensate for decimate-by-2. - -#define fetch_offset(offset, one_x) \ - texture2D(a_texture, fixCoord + vec2((offset) * (one_x), 0.0)).xyz - - -void main() { -// #include "ntsc-pass2-decode.inc" // - float one_x = 1.0 / source_size.x; - vec3 signal = vec3(0.0); - int i,j; - int ibegin = 1; -#if 0 - for (i = ibegin; i < TAPS; i++) - { - float offset = float(i); - vec3 sums = fetch_offset(offset - float(TAPS), one_x) + - fetch_offset(float(TAPS) - offset, one_x); - signal += sums * vec3(luma_filter[i], chroma_filter[i], chroma_filter[i]); - } -#else - float pos_offset = float(TAPS - ibegin) * one_x; - vec3 sums_p = vec3(0.0, 0.0, 0.0); - //vec3 sums_n[TAPS]; - vec2 fix_coord = v_texcoord - vec2(0.5 / source_size.x, 0.0); - vec2 delta = vec2(one_x, 0); - vec3 pix_p, pix_n; - vec3 tmpv; - vec2 addr_p = fix_coord + vec2(pos_offset, 0); - vec2 addr_n = fix_coord - vec2(pos_offset, 0); - for (i = ibegin ; i < TAPS; i++) { - pix_p = texture2D(a_texture, addr_p).xyz; - pix_n = texture2D(a_texture, addr_n).xyz; - pix_p = (pix_n + pix_p) * vec3(luma_filter[i], chroma_filter[i], chroma_filter[i]); - signal = signal + pix_p; - addr_p = addr_p - delta; - addr_n = addr_n + delta; - } -#endif - signal += texture2D(a_texture, fixCoord).xyz * vec3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]); -// END "ntsc-pass2-decode.inc" // - - //vec3 rgb = ycbcr2rgb(signal); - vec3 rgb = yiq2rgb(signal); -#ifdef GAMMA_CORRECTION - vec3 gamma = vec3(CRT_GAMMA / DISPLAY_GAMMA); - rgb = pow(rgb, gamma.rgb); -#endif - - gl_FragColor = vec4(rgb, 1.0); -} \ No newline at end of file diff --git a/source/src/qt/gui/gl3/qt_glutil_gl3_0.cpp b/source/src/qt/gui/gl3/qt_glutil_gl3_0.cpp index b7f8403c7..a39b23378 100644 --- a/source/src/qt/gui/gl3/qt_glutil_gl3_0.cpp +++ b/source/src/qt/gui/gl3/qt_glutil_gl3_0.cpp @@ -20,238 +20,39 @@ #include #include -//extern USING_FLAGS *using_flags; -#if 0 - // OLD_THREE_PHASE -const float luma_filter[24 + 1] = { - -0.000071070, - -0.000032816, - 0.000128784, - 0.000134711, - -0.000226705, - -0.000777988, - -0.000997809, - -0.000522802, - 0.000344691, - 0.000768930, - 0.000275591, - -0.000373434, - 0.000522796, - 0.003813817, - 0.007502825, - 0.006786001, - -0.002636726, - -0.019461182, - -0.033792479, - -0.029921972, - 0.005032552, - 0.071226466, - 0.151755921, - 0.218166470, - 0.243902439 - }; -const float chroma_filter[24 + 1] = { - 0.001845562, - 0.002381606, - 0.003040177, - 0.003838976, - 0.004795341, - 0.005925312, - 0.007242534, - 0.008757043, - 0.010473987, - 0.012392365, - 0.014503872, - 0.016791957, - 0.019231195, - 0.021787070, - 0.024416251, - 0.027067414, - 0.029682613, - 0.032199202, - 0.034552198, - 0.036677005, - 0.038512317, - 0.040003044, - 0.041103048, - 0.041777517, - 0.042004791 - }; -#else -#if 1 - // THREE_PHASE -const float luma_filter[24 + 1] = { - -0.000012020, - -0.000022146, - -0.000013155, - -0.000012020, - -0.000049979, - -0.000113940, - -0.000122150, - -0.000005612, - 0.000170516, - 0.000237199, - 0.000169640, - 0.000285688, - 0.000984574, - 0.002018683, - 0.002002275, - -0.000909882, - -0.007049081, - -0.013222860, - -0.012606931, - 0.002460860, - 0.035868225, - 0.084016453, - 0.135563500, - 0.175261268, - 0.190176552 - }; -const float chroma_filter[24 + 1] = { - -0.000118847, - -0.000271306, - -0.000502642, - -0.000930833, - -0.001451013, - -0.002064744, - -0.002700432, - -0.003241276, - -0.003524948, - -0.003350284, - -0.002491729, - -0.000721149, - 0.002164659, - 0.006313635, - 0.011789103, - 0.018545660, - 0.026414396, - 0.035100710, - 0.044196567, - 0.053207202, - 0.061590275, - 0.068803602, - 0.074356193, - 0.077856564, - 0.079052396 - }; -// END "ntsc-decode-filter-3phase.inc" // -#else - // TWO_PHASE -const float luma_filter[24 + 1] = { - -0.000012020, - -0.000022146, - -0.000013155, - -0.000012020, - -0.000049979, - -0.000113940, - -0.000122150, - -0.000005612, - 0.000170516, - 0.000237199, - 0.000169640, - 0.000285688, - 0.000984574, - 0.002018683, - 0.002002275, - -0.000909882, - -0.007049081, - -0.013222860, - -0.012606931, - 0.002460860, - 0.035868225, - 0.084016453, - 0.135563500, - 0.175261268, - 0.190176552 - }; - -const float chroma_filter[24 + 1] = { - -0.000118847, - -0.000271306, - -0.000502642, - -0.000930833, - -0.001451013, - -0.002064744, - -0.002700432, - -0.003241276, - -0.003524948, - -0.003350284, - -0.002491729, - -0.000721149, - 0.002164659, - 0.006313635, - 0.011789103, - 0.018545660, - 0.026414396, - 0.035100710, - 0.044196567, - 0.053207202, - 0.061590275, - 0.068803602, - 0.074356193, - 0.077856564, - 0.079052396 - }; -// END "ntsc-decode-filter-3phase.inc" // -#endif -#endif - -GLDraw_3_0::GLDraw_3_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu) : GLDraw_2_0(parent, p, logger, emu) +GLDraw_3_0::GLDraw_3_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu) : GLDraw_Tmpl(parent, p, logger, emu) { - uTmpTextureID = 0; - - grids_shader = NULL; - - main_pass = NULL; - std_pass = NULL; - ntsc_pass1 = NULL; - ntsc_pass2 = NULL; - led_pass = NULL; - for(int i = 0; i < 32; i++) { - led_pass_vao[i] = NULL; - led_pass_vbuffer[i] = NULL; - osd_pass_vao[i] = NULL; - osd_pass_vbuffer[i] = NULL; - } - grids_horizonal_buffer = NULL; - grids_horizonal_vertex = NULL; - - grids_vertical_buffer = NULL; - grids_vertical_vertex = NULL; - ringing_phase = 0.0f; - } GLDraw_3_0::~GLDraw_3_0() { +} - if(main_pass != NULL) delete main_pass; - if(std_pass != NULL) delete std_pass; - if(ntsc_pass1 != NULL) delete ntsc_pass1; - if(ntsc_pass2 != NULL) delete ntsc_pass2; - if(led_pass != NULL) delete led_pass; - for(int i = 0; i < 32; i++) { - if(led_pass_vao[i] != NULL) delete led_pass_vao[i]; - if(led_pass_vbuffer[i] != NULL) delete led_pass_vbuffer[i]; - if(osd_pass_vao[i] != NULL) delete osd_pass_vao[i]; - if(osd_pass_vbuffer[i] != NULL) delete osd_pass_vbuffer[i]; - } - - if(grids_horizonal_buffer != NULL) { - if(grids_horizonal_buffer->isCreated()) grids_horizonal_buffer->destroy(); - } - if(grids_horizonal_vertex != NULL) { - if(grids_horizonal_vertex->isCreated()) grids_horizonal_vertex->destroy(); - } - if(grids_vertical_buffer != NULL) { - if(grids_vertical_buffer->isCreated()) grids_vertical_buffer->destroy(); - } - if(grids_horizonal_vertex != NULL) { - if(grids_vertical_vertex->isCreated()) grids_vertical_vertex->destroy(); - } +void GLDraw_3_0::epilogueBlending() +{ + extfunc->glDisable(GL_TEXTURE_2D); + extfunc->glDisable(GL_BLEND); +} +void GLDraw_3_0::prologueBlending() +{ + extfunc->glDisable(GL_TEXTURE_2D); + extfunc->glEnable(GL_BLEND); + extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); + extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); } +void GLDraw_3_0::drawPolygon(int vertex_loc, uintptr_t p) +{ + extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), (void*)p); + + extfunc->glEnableVertexAttribArray(vertex_loc); + extfunc->glEnable(GL_VERTEX_ARRAY); + extfunc->glDrawArrays(GL_POLYGON, 0, 4); +} + + void GLDraw_3_0::initFBO(void) { glHorizGrids = (GLfloat *)malloc(sizeof(float) * (using_flags->get_real_screen_height() + 2) * 6); @@ -308,12 +109,12 @@ void GLDraw_3_0::initGLObjects() void GLDraw_3_0::initPackedGLObject(GLScreenPack **p, int _width, int _height, const QString vertex_shader, const QString fragment_shader, - const QString _name, bool req_float, bool req_highp) + const QString _name, bool req_float, bool req_highp, bool req_alpha_channel) { QString s; GLScreenPack *pp; if(p != NULL) { - pp = new GLScreenPack(_width, _height, _name, p_wid, req_float, req_highp); + pp = new GLScreenPack(_width, _height, _name, p_wid, req_float, req_highp, req_alpha_channel); *p = pp; if(pp != NULL) { pp->initialize(_width, _height, vertex_shader, fragment_shader); @@ -426,12 +227,12 @@ void GLDraw_3_0::initLocalGLObjects(void) if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) { initPackedGLObject(&main_pass, using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2, - ":/gl3/vertex_shader.glsl" , ":/gl3/chromakey_fragment_shader2.glsl", - "Main Shader", false, false); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/chromakey_fragment_shader2.glsl", + "Main Shader", true, false); } else { initPackedGLObject(&main_pass, using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2, - ":/gl3/vertex_shader.glsl" , ":/gl3/fragment_shader.glsl", + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/fragment_shader.glsl", "Main Shader", false, false); } if(main_pass != NULL) { @@ -441,11 +242,11 @@ void GLDraw_3_0::initLocalGLObjects(void) } initPackedGLObject(&std_pass, using_flags->get_screen_width(), using_flags->get_screen_height(), - ":/gl3/vertex_shader.glsl" , ":/gl3/chromakey_fragment_shader.glsl", + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/chromakey_fragment_shader.glsl", "Standard Shader", false, false); initPackedGLObject(&led_pass, 10, 10, - ":/gl3/led_vertex_shader.glsl" , ":/gl3/led_fragment_shader.glsl", + ":/gl/shaders/led_vertex_shader.glsl" , ":/gl/shaders/led_fragment_shader.glsl", "LED Shader", false, false); for(int i = 0; i < 32; i++) { led_pass_vao[i] = new QOpenGLVertexArrayObject; @@ -464,7 +265,7 @@ void GLDraw_3_0::initLocalGLObjects(void) } initPackedGLObject(&osd_pass, 48.0, 48.0, - ":/gl3/vertex_shader.glsl" , ":/gl3/icon_fragment_shader.glsl", + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/icon_fragment_shader.glsl", "OSD Shader", false, false); for(int i = 0; i < 32; i++) { osd_pass_vao[i] = new QOpenGLVertexArrayObject; @@ -484,12 +285,12 @@ void GLDraw_3_0::initLocalGLObjects(void) initPackedGLObject(&ntsc_pass1, _width, _height, - ":/gl3/vertex_shader.glsl" , ":/gl3/ntsc_pass1.glsl", - "NTSC Shader Pass1", true, true); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/ntsc_pass1.glsl", + "NTSC Shader Pass1", true, false); initPackedGLObject(&ntsc_pass2, _width / 2, _height, - ":/gl3/vertex_shader.glsl" , ":/gl3/ntsc_pass2.glsl", - "NTSC Shader Pass2", true, true); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/ntsc_pass2.glsl", + "NTSC Shader Pass2", false, false); { int ii; QOpenGLShaderProgram *shader = ntsc_pass2->getShader(); @@ -509,15 +310,15 @@ void GLDraw_3_0::initLocalGLObjects(void) initBitmapVertex(); initPackedGLObject(&bitmap_block, _width * 2, _height * 2, - ":/gl3/vertex_shader.glsl", ":/gl3/normal_fragment_shader.glsl", - "Background Bitmap Shader", false, false); + ":/gl/shaders/vertex_shader.glsl", ":/gl/shaders/normal_fragment_shader.glsl", + "Background Bitmap Shader", true, true, true); if(bitmap_block != NULL) { setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(), bitmap_block->getVertexBuffer(), vertexBitmap, 4); } } - initGridShaders(":/gl3/grids_vertex_shader_fixed.glsl", ":/gl3/grids_vertex_shader.glsl", ":/gl3/grids_fragment_shader.glsl"); + initGridShaders(":/gl/shaders/grids_vertex_shader_fixed.glsl", ":/gl/shaders/grids_vertex_shader.glsl", ":/gl/shaders/grids_fragment_shader.glsl"); initGridVertexObject(&grids_horizonal_buffer, &grids_horizonal_vertex, using_flags->get_real_screen_height() + 3); doSetGridsHorizonal(using_flags->get_real_screen_height(), true); @@ -601,7 +402,7 @@ void GLDraw_3_0::drawGridsMain_3(QOpenGLShaderProgram *prg, prg->enableAttributeArray("vertex"); int vertex_loc = prg->attributeLocation("vertex"); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0); extfunc->glEnableVertexAttribArray(vertex_loc); @@ -693,12 +494,12 @@ void GLDraw_3_0::renderToTmpFrameBuffer_nPass(GLuint src_texture, { ii = shader->uniformLocation("source_size"); if(ii >= 0) { - QVector4D source_size = QVector4D((float)src_w, (float)src_h, 0, 0); + QVector2D source_size = QVector2D((float)src_w, (float)src_h); shader->setUniformValue(ii, source_size); } ii = shader->uniformLocation("target_size"); if(ii >= 0) { - QVector4D target_size = QVector4D((float)dst_w, (float)dst_h, 0, 0); + QVector2D target_size = QVector2D((float)dst_w, (float)dst_h); shader->setUniformValue(ii, target_size); } ii = shader->uniformLocation("phase"); @@ -838,6 +639,21 @@ void GLDraw_3_0::drawScreenTexture(void) } } +void GLDraw_3_0::drawMain(GLScreenPack *obj, + GLuint texid, + QVector4D color, + bool f_smoosing, + bool do_chromakey, + QVector3D chromakey) + +{ + QOpenGLShaderProgram *prg = obj->getShader(); + QOpenGLVertexArrayObject *vp = obj->getVAO(); + QOpenGLBuffer *bp = obj->getVertexBuffer(); + + drawMain(prg, vp, bp, texid, color, f_smoosing, do_chromakey, chromakey); +} + void GLDraw_3_0::drawMain(QOpenGLShaderProgram *prg, QOpenGLVertexArrayObject *vp, QOpenGLBuffer *bp, @@ -854,7 +670,7 @@ void GLDraw_3_0::drawMain(QOpenGLShaderProgram *prg, vp->bind(); bp->bind(); prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc->glActiveTexture(GL_TEXTURE0); extfunc->glBindTexture(GL_TEXTURE_2D, texid); @@ -901,6 +717,11 @@ void GLDraw_3_0::drawMain(QOpenGLShaderProgram *prg, break; } prg->setUniformValue("rotate_mat", rot); + if(!(using_flags->is_use_one_board_computer())) { + prg->setUniformValue("distortion_v", 0.08f, 0.08f); // ToDo: Change val + } + prg->setUniformValue("luminance", 0.9f); // ToDo: Change val + prg->setUniformValue("lum_offset", 0.08f); // ToDo: Change val if(do_chromakey) { ii = prg->uniformLocation("chromakey"); @@ -938,7 +759,7 @@ void GLDraw_3_0::drawMain(QOpenGLShaderProgram *prg, vp->bind(); bp->bind(); prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); ii = prg->uniformLocation("color"); if(ii >= 0) { @@ -994,21 +815,6 @@ void GLDraw_3_0::drawMain(QOpenGLShaderProgram *prg, } } -void GLDraw_3_0::drawMain(GLScreenPack *obj, - GLuint texid, - QVector4D color, - bool f_smoosing, - bool do_chromakey, - QVector3D chromakey) - -{ - QOpenGLShaderProgram *prg = obj->getShader(); - QOpenGLVertexArrayObject *vp = obj->getVAO(); - QOpenGLBuffer *bp = obj->getVertexBuffer(); - - drawMain(prg, vp, bp, texid, color, f_smoosing, do_chromakey, chromakey); -} - void GLDraw_3_0::drawButtonsMain(int num, bool f_smoosing) { GLuint texid; @@ -1025,7 +831,7 @@ void GLDraw_3_0::drawButtonsMain(int num, bool f_smoosing) bp->bind(); vp->bind(); prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc->glActiveTexture(GL_TEXTURE0); extfunc->glBindTexture(GL_TEXTURE_2D, texid); @@ -1099,132 +905,14 @@ void GLDraw_3_0::drawBitmapTexture(void) smoosing = p_config->use_opengl_filters; if(uBitmapTextureID == NULL) return; if(using_flags->is_use_one_board_computer()) { - extfunc->glDisable(GL_BLEND); + +// extfunc->glDisable(GL_BLEND); drawMain(bitmap_block, uBitmapTextureID->textureId(), color, smoosing); } } -void GLDraw_3_0::drawLedMain(GLScreenPack *obj, int num, QVector4D color) -{ - QOpenGLShaderProgram *prg = obj->getShader(); - QOpenGLVertexArrayObject *vp = led_pass_vao[num]; - QOpenGLBuffer *bp = led_pass_vbuffer[num]; - int ii; - - { - extfunc->glDisable(GL_TEXTURE_2D); - extfunc->glEnable(GL_BLEND); - extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - vp->bind(); - bp->bind(); - prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); - extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); - ii = prg->uniformLocation("color"); - if(ii >= 0) { - prg->setUniformValue(ii, color); - } - - prg->enableAttributeArray("vertex"); - int vertex_loc = prg->attributeLocation("vertex"); - prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t)); - extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0); - - extfunc->glEnableVertexAttribArray(vertex_loc); - extfunc->glEnable(GL_VERTEX_ARRAY); - extfunc->glDrawArrays(GL_POLYGON, 0, 4); - bp->release(); - vp->release(); - - prg->release(); - extfunc->glDisable(GL_TEXTURE_2D); - extfunc->glDisable(GL_BLEND); - } - -} - - -void GLDraw_3_0::drawOsdLeds() -{ - QVector4D color_on; - QVector4D color_off; - uint32_t bit = 0x00000001; - if(osd_onoff) { - color_on = QVector4D(0.95, 0.0, 0.05, 1.0); - color_off = QVector4D(0.05,0.05, 0.05, 0.10); - } else { - color_on = QVector4D(0.00,0.00, 0.00, 0.0); - color_off = QVector4D(0.00,0.00, 0.00, 0.0); - } - if(osd_onoff) { - //if(osd_led_status_bak != osd_led_status) { - for(int i = 0; i < osd_led_bit_width; i++) { - if((bit & osd_led_status) == (bit & osd_led_status_bak)) { - bit <<= 1; - continue; - } - drawLedMain(led_pass, i, - ((osd_led_status & bit) != 0) ? color_on : color_off); - bit <<= 1; - } - osd_led_status_bak = osd_led_status; - //} - } -} - -void GLDraw_3_0::drawOsdIcons() -{ - QVector4D color_on; - QVector4D color_off; - uint32_t bit = 0x00000001; - if(osd_onoff) { - color_on = QVector4D(1.0, 1.0, 1.0, 0.8); - color_off = QVector4D(1.0, 1.0, 1.0, 0.00); - } else { - color_on = QVector4D(0.00,0.00, 0.00, 0.0); - color_off = QVector4D(0.00,0.00, 0.00, 0.0); - } - if(osd_onoff) { - int major, minor; - //if(osd_led_status_bak != osd_led_status) { - for(int i = 0; i < osd_led_bit_width; i++) { - if((bit & osd_led_status) == (bit & osd_led_status_bak)) { - if((bit & osd_led_status) == 0) { - bit <<= 1; - continue; - } - } - if((i >= 2) && (i < 10)) { // FD - major = 2; - minor = i - 2; - } else if((i >= 10) && (i < 12)) { // QD - major = 3; - minor = i - 10; - } else if((i >= 12) && (i < 14)) { // CMT(R) - major = 4; - minor = i - 12; - } else if((i >= 14) && (i < 16)) { // CMT(W) - major = 5; - minor = i - 14; - } else { - major = 0; - minor = 0; - } - // ToDo: CD(6),LD(7) and HDD(8). - if((major != 0) && (icon_texid[major][minor] != NULL)) { - drawMain(osd_pass->getShader(), osd_pass_vao[i], osd_pass_vbuffer[i], - icon_texid[major][minor]->textureId(), - ((osd_led_status & bit) != 0) ? color_on : color_off, - false, false, QVector3D(0.0, 0.0, 0.0)); - } - bit <<= 1; - } - osd_led_status_bak = osd_led_status; - //} - } -} void GLDraw_3_0::paintGL(void) { @@ -1235,7 +923,7 @@ void GLDraw_3_0::paintGL(void) crt_flag = false; } redraw_required = false; - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1262,7 +950,7 @@ void GLDraw_3_0::paintGL(void) } extfunc->glFlush(); // } else { -// extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); +// extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); /// extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); // //drawOsdLeds(); // extfunc->glClear(GL_DEPTH_BUFFER_BIT); @@ -1490,18 +1178,22 @@ void GLDraw_3_0::do_set_texture_size(QImage *p, int w, int h) vertexFormat[3].z = -0.9f; vertexFormat[0].s = 0.0f; - //vertexFormat[0].t = (float)h / ih; - //vertexFormat[1].s = (float)w / iw; - //vertexFormat[1].t = (float)h / ih; - //vertexFormat[2].s = (float)w / iw; - vertexFormat[0].t = 1.0f; - vertexFormat[1].s = 1.0f; - vertexFormat[1].t = 1.0f; - vertexFormat[2].s = 1.0f; + vertexFormat[0].t = (float)h / ih; + vertexFormat[1].s = (float)w / iw; + vertexFormat[1].t = (float)h / ih; + vertexFormat[2].s = (float)w / iw; vertexFormat[2].t = 0.0f; vertexFormat[3].s = 0.0f; vertexFormat[3].t = 0.0f; +// vertexFormat[0].t = 1.0f; +// vertexFormat[1].s = 1.0f; +// vertexFormat[1].t = 1.0f; +// vertexFormat[2].s = 1.0f; +// vertexFormat[2].t = 0.0f; +// vertexFormat[3].s = 0.0f; +// vertexFormat[3].t = 0.0f; + setNormalVAO(main_pass->getShader(), main_pass->getVAO(), main_pass->getVertexBuffer(), vertexFormat, 4); @@ -1537,7 +1229,6 @@ void GLDraw_3_0::resizeGL_Screen(void) void GLDraw_3_0::resizeGL(int width, int height) { //int side = qMin(width, height); - p_wid->makeCurrent(); extfunc->glViewport(0, 0, width, height); extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); crt_flag = true; @@ -1557,5 +1248,4 @@ void GLDraw_3_0::resizeGL(int width, int height) if(using_flags->get_max_button() > 0) { updateButtonTexture(); } - p_wid->doneCurrent(); } diff --git a/source/src/qt/gui/gl3/qt_glutil_gl3_0.h b/source/src/qt/gui/gl3/qt_glutil_gl3_0.h index c40ab2059..274cb776c 100644 --- a/source/src/qt/gui/gl3/qt_glutil_gl3_0.h +++ b/source/src/qt/gui/gl3/qt_glutil_gl3_0.h @@ -11,46 +11,20 @@ #define _QT_COMMON_GLUTIL_3_0_H #include -#include "../gl2/qt_glutil_gl2_0.h" -//#include "../gl/qt_glutil_gl_tmpl.h" +//#include "../gl2/qt_glutil_gl2_0.h" +#include "../gl/qt_glutil_gl_tmpl.h" QT_BEGIN_NAMESPACE class GLScreenPack; class QOpenGLFunctions_3_0; class GLDrawClass; -class DLL_PREFIX GLDraw_3_0 : public GLDraw_2_0 +class DLL_PREFIX GLDraw_3_0 : public GLDraw_Tmpl { Q_OBJECT private: QOpenGLFunctions_3_0 *extfunc; - float ringing_phase; protected: - GLScreenPack *main_pass; - GLScreenPack *std_pass; - GLScreenPack *ntsc_pass1; - GLScreenPack *ntsc_pass2; - GLScreenPack *bitmap_block; - GLScreenPack *led_pass; - GLScreenPack *osd_pass; - QOpenGLBuffer *led_pass_vbuffer[32]; - QOpenGLVertexArrayObject *led_pass_vao[32]; - QOpenGLBuffer *osd_pass_vbuffer[32]; - QOpenGLVertexArrayObject *osd_pass_vao[32]; - VertexTexCoord_t vertexTmpTexture[4]; - - QOpenGLShaderProgram *grids_shader; - QOpenGLBuffer *grids_horizonal_buffer; - QOpenGLVertexArrayObject *grids_horizonal_vertex; - QOpenGLBuffer *grids_vertical_buffer; - QOpenGLVertexArrayObject *grids_vertical_vertex; - - GLuint uTmpTextureID; - const float rot0[4] = {1, -0, 0, 1}; - const float rot90[4] = {0, 1, -1, 0}; - const float rot180[4] = {-1, 0, 0, -1}; - const float rot270[4] = {0, -1, 1, 0}; - virtual void setNormalVAO(QOpenGLShaderProgram *prg, QOpenGLVertexArrayObject *vp, QOpenGLBuffer *bp, VertexTexCoord_t *tp, int size = 4); virtual bool initGridShaders(const QString vertex_fixed, const QString vertex_rotate, const QString fragment); @@ -71,7 +45,8 @@ class DLL_PREFIX GLDraw_3_0 : public GLDraw_2_0 virtual void initPackedGLObject(GLScreenPack **p, int _width, int _height, const QString vertex_shader, const QString fragment_shader, - const QString _name, bool req_float = false, bool req_highp = false); + const QString _name, bool req_float = false, + bool req_highp = false, bool req_alpha_channel = true); virtual void drawGridsHorizonal(void); virtual void drawGridsVertical(void); @@ -97,13 +72,17 @@ class DLL_PREFIX GLDraw_3_0 : public GLDraw_2_0 bool use_chromakey = false); virtual void drawBitmapTexture(void); virtual void drawButtonsMain(int num, bool f_smoosing); - virtual void drawOsdLeds(); - virtual void drawOsdIcons(); - virtual void drawLedMain(GLScreenPack *obj, int num, QVector4D color); + virtual void prologueBlending(); + virtual void epilogueBlending(); + virtual void drawPolygon(int vertex_loc, uintptr_t p = 0); + +// virtual void drawOsdLeds(); +// virtual void drawOsdIcons(); +// virtual void drawLedMain(GLScreenPack *obj, int num, QVector4D color); virtual void set_led_vertex(int bit); virtual void set_osd_vertex(int bit); public: - GLDraw_3_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu = 0); + GLDraw_3_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu = 0); ~GLDraw_3_0(); void drawButtons(void); virtual void initGLObjects(); diff --git a/source/src/qt/gui/gl3/tmp_vertex_shader.glsl b/source/src/qt/gui/gl3/tmp_vertex_shader.glsl deleted file mode 100644 index 607d0ece0..000000000 --- a/source/src/qt/gui/gl3/tmp_vertex_shader.glsl +++ /dev/null @@ -1,13 +0,0 @@ -attribute vec3 vertex; -attribute vec2 texcoord; -varying vec2 v_texcoord; - -void main () -{ - vec4 tmpvar_1; - tmpvar_1.w = 1.0; - tmpvar_1.xyz = vertex; - gl_Position = tmpvar_1; - v_texcoord = texcoord; -} - diff --git a/source/src/qt/gui/gl3/vertex_shader.glsl b/source/src/qt/gui/gl3/vertex_shader.glsl deleted file mode 100644 index 7ad9725d7..000000000 --- a/source/src/qt/gui/gl3/vertex_shader.glsl +++ /dev/null @@ -1,18 +0,0 @@ -#if __VERSION__ >= 300 -in mediump vec3 vertex; -in mediump vec2 texcoord; -out mediump vec2 v_texcoord; -#else -attribute vec3 vertex; -attribute vec2 texcoord; -varying vec2 v_texcoord; -#endif -uniform mat2 rotate_mat; -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - gl_Position = vec4(xy, vertex.z, 1.0); - v_texcoord = texcoord; -} - diff --git a/source/src/qt/gui/gl4_5/chromakey_fragment_shader.glsl b/source/src/qt/gui/gl4_5/chromakey_fragment_shader.glsl deleted file mode 100644 index 23d27bd4c..000000000 --- a/source/src/qt/gui/gl4_5/chromakey_fragment_shader.glsl +++ /dev/null @@ -1,33 +0,0 @@ -//precision mediump float; - -in mediump vec2 v_texcoord; -out vec4 opixel; - -uniform vec4 color; -uniform vec3 chromakey; -uniform bool do_chromakey; -uniform bool swap_byteorder; -uniform sampler2D a_texture; -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - - pixel_r_1 = texture(a_texture, v_texcoord); - - if(do_chromakey) { - if(pixel_r_1.rgb != chromakey.rgb) { - pixel_r_1 = pixel_r_1 * color; - pixel = vec4(pixel_r_1.rgb, 1.0); - opixel = pixel; - } else { - pixel = vec4(0.0); - //discard; - } - } else { - pixel_r_1 = pixel_r_1 * color; - pixel = vec4(pixel_r_1.rgb, 1.0); - opixel = pixel; - } -} - diff --git a/source/src/qt/gui/gl4_5/chromakey_fragment_shader2.glsl b/source/src/qt/gui/gl4_5/chromakey_fragment_shader2.glsl deleted file mode 100644 index 8c9a3342d..000000000 --- a/source/src/qt/gui/gl4_5/chromakey_fragment_shader2.glsl +++ /dev/null @@ -1,21 +0,0 @@ -//precision mediump float; - -in vec2 v_texcoord; -out vec4 opixel; - -uniform vec4 color; -uniform vec3 chromakey; -uniform sampler2D a_texture; - -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - bvec3 _match; - - pixel_r_1 = texture(a_texture, v_texcoord); - - _match = equal(pixel_r_1.rgb, chromakey.rgb); - pixel = (all(_match) == true) ? vec4(0.0, 0.0, 0.0, 0.0) : vec4(pixel_r_1.rgb, 1.0); - opixel = pixel; -} diff --git a/source/src/qt/gui/gl4_5/fragment_shader.glsl b/source/src/qt/gui/gl4_5/fragment_shader.glsl deleted file mode 100644 index 5a3e37bf4..000000000 --- a/source/src/qt/gui/gl4_5/fragment_shader.glsl +++ /dev/null @@ -1,10 +0,0 @@ -//precision mediump float; - -in vec2 v_texcoord; -out uvec4 opixel; -//uniform usamplerBuffer s_texture; -uniform usampler2D a_texture; -void main () -{ - opixel = texture(a_texture, v_texcoord); -} diff --git a/source/src/qt/gui/gl4_5/grids_fragment_shader.glsl b/source/src/qt/gui/gl4_5/grids_fragment_shader.glsl deleted file mode 100644 index 2cf046510..000000000 --- a/source/src/qt/gui/gl4_5/grids_fragment_shader.glsl +++ /dev/null @@ -1,7 +0,0 @@ -uniform vec4 color; -out vec4 opixel; -void main () -{ - opixel = color; -} - diff --git a/source/src/qt/gui/gl4_5/grids_vertex_shader.glsl b/source/src/qt/gui/gl4_5/grids_vertex_shader.glsl deleted file mode 100644 index 514db8b27..000000000 --- a/source/src/qt/gui/gl4_5/grids_vertex_shader.glsl +++ /dev/null @@ -1,9 +0,0 @@ -in vec3 vertex; -uniform mat2 rotate_mat; -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - gl_Position = vec4(xy, vertex.z, 1.0); -} - diff --git a/source/src/qt/gui/gl4_5/grids_vertex_shader_fixed.glsl b/source/src/qt/gui/gl4_5/grids_vertex_shader_fixed.glsl deleted file mode 100644 index f9c55a982..000000000 --- a/source/src/qt/gui/gl4_5/grids_vertex_shader_fixed.glsl +++ /dev/null @@ -1,9 +0,0 @@ -int vec3 vertex; -void main () -{ - vec4 tmpvar_1; - tmpvar_1.w = 1.0; - tmpvar_1.xyz = vertex; - gl_Position = tmpvar_1; -} - diff --git a/source/src/qt/gui/gl4_5/icon_fragment_shader.glsl b/source/src/qt/gui/gl4_5/icon_fragment_shader.glsl deleted file mode 100644 index 7cf649413..000000000 --- a/source/src/qt/gui/gl4_5/icon_fragment_shader.glsl +++ /dev/null @@ -1,22 +0,0 @@ -//precision mediump float; - -in vec2 v_texcoord; -out mediump vec4 opixel; - -uniform vec4 color; -uniform vec3 chromakey; -uniform bool do_chromakey; -uniform sampler2D a_texture; -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - float alpha; - pixel_r_1 = texture(a_texture, v_texcoord); - //alpha = pixel_r_1.a * color.a; - - pixel_r_1 = pixel_r_1 * color; - pixel = pixel_r_1 * color; //;vec4(pixel_r_1.rgb, alpha); - opixel = pixel; -} - diff --git a/source/src/qt/gui/gl4_5/led_fragment_shader.glsl b/source/src/qt/gui/gl4_5/led_fragment_shader.glsl deleted file mode 100644 index f4d557e86..000000000 --- a/source/src/qt/gui/gl4_5/led_fragment_shader.glsl +++ /dev/null @@ -1,9 +0,0 @@ -uniform vec4 color; -out mediump vec4 opixel; - -void main () -{ - opixel = color; -} - - diff --git a/source/src/qt/gui/gl4_5/led_vertex_shader.glsl b/source/src/qt/gui/gl4_5/led_vertex_shader.glsl deleted file mode 100644 index 78f6336b5..000000000 --- a/source/src/qt/gui/gl4_5/led_vertex_shader.glsl +++ /dev/null @@ -1,10 +0,0 @@ -in vec3 vertex; -uniform mat2 rotate_mat; - -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - gl_Position = vec4(xy, vertex.z, 1.0); -} - diff --git a/source/src/qt/gui/gl4_5/normal_fragment_shader.glsl b/source/src/qt/gui/gl4_5/normal_fragment_shader.glsl deleted file mode 100644 index 686287fe5..000000000 --- a/source/src/qt/gui/gl4_5/normal_fragment_shader.glsl +++ /dev/null @@ -1,10 +0,0 @@ -in vec2 v_texcoord; -out mediump vec4 opixel; - -uniform sampler2D a_texture; -uniform vec4 color; -void main () -{ - opixel = texture(a_texture, v_texcoord) * color; -} - diff --git a/source/src/qt/gui/gl4_5/ntsc_pass1.glsl b/source/src/qt/gui/gl4_5/ntsc_pass1.glsl deleted file mode 100644 index f88f3add5..000000000 --- a/source/src/qt/gui/gl4_5/ntsc_pass1.glsl +++ /dev/null @@ -1,115 +0,0 @@ -// NTSC Shader - written by Hans-Kristian Arntzen -// License: GPLv3 -// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 -//precision mediump float; - - -in mediump vec2 v_texcoord; -out mediump vec4 opixel; - -uniform sampler2D a_texture; -uniform vec4 source_size; -uniform vec4 target_size; -uniform float phase; - -#define THREE_PHASE //options here include THREE_PHASE, TWO_PHASE or OLD_THREE_PHASE -#define COMPOSITE - -// #include "ntsc-param.inc" // -#define PI 3.14159265 - -#if defined(TWO_PHASE) -#define CHROMA_MOD_FREQ (4.0 * PI / 15.0) -#elif defined(THREE_PHASE) -#define CHROMA_MOD_FREQ (PI / 3.0) -#endif - -#if defined(COMPOSITE) -#define SATURATION 1.1 -#define BRIGHTNESS 1.0 -#define ARTIFACTING 1.3 -#define FRINGING 1.2 -#elif defined(SVIDEO) -#define SATURATION 1.0 -#define BRIGHTNESS 1.0 -#define ARTIFACTING 0.0 -#define FRINGING 0.0 -#endif - -#if defined(COMPOSITE) || defined(SVIDEO) -mat3 mix_mat = mat3( - BRIGHTNESS, FRINGING, FRINGING, - ARTIFACTING, 2.0 * SATURATION, 0.0, - ARTIFACTING, 0.0, 2.0 * SATURATION -); -#endif -// END "ntsc-param.inc" // - -// moved from vertex -#define pix_no (v_texcoord.xy * source_size.xy * (target_size.xy / source_size.xy)) - -// Change Matrix: [RGB]->[YCbCr] - -mat3 ycbcr_mat = mat3( - 0.29891, -0.16874, 0.50000, - 0.58661, -0.33126, -0.41869, - 0.11448, 0.50000, -0.08131 -); - -#define rgb2ycbcr(foo) (col.rgb * ycbcr_mat) - -mat3 ycbcr2rgb_mat = mat3( - 1.0, 1.0, 1.0, - 0.0, -0.34414 , 1.77200, - 1.40200, -0.71414, 0.0 - ); - -vec3 ycbcr2rgb(vec3 ycbcr) -{ - //vec3 ra = ycbcr * vec3(1.0, 0.7, 1.0); - return (ycbcr * ycbcr2rgb_mat); -} - -void main() { - // #include "ntsc-pass1-encode-demodulate.inc" // - - vec3 col = texture(a_texture, v_texcoord).rgb; - vec3 ycbcr; - ycbcr = rgb2ycbcr(col); -// -// From https://ja.wikipedia.org/wiki/YUV#RGB%E3%81%8B%E3%82%89%E3%81%AE%E5%A4%89%E6%8F%9B -// ITU-R BT.601 / ITU-R BT.709 (1250/50/2:1) -// Y = 0.299 * R + 0.587 * G + 0.114 * B -// Cb = -0.168736 * R - 0.331264 * G + 0.5 * B -// Cr = 0.5 * R - 0.418688 * G - 0.081312 * B - -#if defined(TWO_PHASE) - float chroma_phase = PI * (mod(pix_no.y, 2.0) + phase); -#elif defined(THREE_PHASE) - float chroma_phase = 0.6667 * PI * (mod(pix_no.y, 3.0) + phase); -#endif - - float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ; - - float i_mod = cos(mod_phase); - float q_mod = sin(mod_phase); - ycbcr *= vec3(1.0, i_mod, q_mod); // Modulate - ycbcr *= mix_mat; // Cross-talk - ycbcr *= vec3(1.0, i_mod, q_mod); // Demodulate - - // yMax = (0.299+0.587+0.114) * (+-1.0) * (BRIGHTNESS + ARTIFACTING + ARTIFACTING) * (+-1.0) - // CbMax = (-0.168736 -0.331264 + 0.5) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // CrMax = (0.5 - 0.418688 - 0.081312) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // -> y = 0 to +3.6 - // Cb = 0 to +1.7 - // Cr = 0 to +1.7 - -#ifndef HAS_FLOAT_TEXTURE - //ycbcr = ycbcr * vec3(0.277778 ,0.588235, 0.588235); -#endif - // Normalise - vec4 outvar = vec4(ycbcr, 1.0); - - opixel = outvar; -// END "ntsc-pass1-encode-demodulate.inc" // -} \ No newline at end of file diff --git a/source/src/qt/gui/gl4_5/ntsc_pass2.glsl b/source/src/qt/gui/gl4_5/ntsc_pass2.glsl deleted file mode 100644 index babf75f1c..000000000 --- a/source/src/qt/gui/gl4_5/ntsc_pass2.glsl +++ /dev/null @@ -1,162 +0,0 @@ -// NTSC Shader - written by Hans-Kristian Arntzen -// License: GPLv3 -// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 -//precision mediump float; - - -in mediump vec2 v_texcoord; -out vec4 opixel; - -uniform sampler2D a_texture; -uniform vec4 source_size; -uniform vec4 target_size; - -#define TAPS 24 - -#if __VERSION__ >= 300 - // THREE_PHASE -const float luma_filter[24 + 1] = float[24 + 1]( - -0.000012020, - -0.000022146, - -0.000013155, - -0.000012020, - -0.000049979, - -0.000113940, - -0.000122150, - -0.000005612, - 0.000170516, - 0.000237199, - 0.000169640, - 0.000285688, - 0.000984574, - 0.002018683, - 0.002002275, - -0.000909882, - -0.007049081, - -0.013222860, - -0.012606931, - 0.002460860, - 0.035868225, - 0.084016453, - 0.135563500, - 0.175261268, - 0.190176552 - ); -const float chroma_filter[24 + 1] = float [24 + 1]( - -0.000118847, - -0.000271306, - -0.000502642, - -0.000930833, - -0.001451013, - -0.002064744, - -0.002700432, - -0.003241276, - -0.003524948, - -0.003350284, - -0.002491729, - -0.000721149, - 0.002164659, - 0.006313635, - 0.011789103, - 0.018545660, - 0.026414396, - 0.035100710, - 0.044196567, - 0.053207202, - 0.061590275, - 0.068803602, - 0.074356193, - 0.077856564, - 0.079052396 - ); -// END "ntsc-decode-filter-3phase.inc" // - -#else -uniform float luma_filter[24 + 1]; -uniform float chroma_filter[24 + 1]; -#endif - -#define GAMMA_CORRECTION //comment to disable gamma correction, usually because higan's gamma correction is enabled or you have another shader already doing it -#ifndef HAS_FLOAT_TEXTURE -#define CRT_GAMMA 3.3 -#else -#define CRT_GAMMA 2.5 -#endif -#define DISPLAY_GAMMA 2.1 - - -// #include ntsc-rgbyuv.inc // - - -mat3 ycbcr2rgb_mat = mat3( - 1.0, 1.0, 1.0, - 0.0, -0.34414 , 1.77200, - 1.40200, -0.71414, 0.0 - ); - -//vec3 ycbcr2rgb(vec3 ycbcr) -//{ -// //vec3 ra = ycbcr * vec3(1.0, 0.7, 1.0); -// return (ycbcr * ycbcr2rgb_mat); -//} -#define ycbcr2rgb(foo) (foo.rgb * ycbcr2rgb_mat) - -// END ntsc-rgbyuv.inc // - -// fixCoord moved from vertex -#define fixCoord (v_texcoord - (vec2(0.5) * delta)) // Compensate for decimate-by-2. - -void main() { -// #include "ntsc-pass2-decode.inc" // - float one_x = 1.0 / source_size.x; - vec3 signal = vec3(0.0); - int i,j; - int ibegin = 1; - float pos_offset = float(TAPS - ibegin) * one_x; - vec3 sums_p = vec3(0.0, 0.0, 0.0); - - vec2 fix_coord = v_texcoord - vec2(0.5 * one_x, 0.0); - vec2 delta = vec2(one_x, 0); - vec3 pix_p, pix_n; - vec3 tmpv; - vec2 addr_p = fix_coord + vec2(pos_offset, 0); - vec2 addr_n = fix_coord - vec2(pos_offset, 0); - - for(int ii = 1; ii < TAPS; ii++) { - pix_p = texture(a_texture, addr_p).xyz; - pix_n = texture(a_texture, addr_n).xyz; -#ifndef HAS_FLOAT_TEXTURE -// pix_p = pix_p * vec3(3.6, 1.7, 1.7); -// pix_n = pix_n * vec3(3.6, 1.7, 1.7); -#endif - pix_p = (pix_n + pix_p) * vec3(luma_filter[ii], chroma_filter[ii], chroma_filter[ii]); - signal = signal + pix_p; - addr_p = addr_p - delta; - addr_n = addr_n + delta; - } - vec3 texvar = texture2D(a_texture, fix_coord).xyz; - // yMax = (0.299+0.587+0.114) * (+-1.0) * (BRIGHTNESS + ARTIFACTING + ARTIFACTING) * (+-1.0) - // CbMax = (-0.168736 -0.331264 + 0.5) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // CrMax = (0.5 - 0.418688 - 0.081312) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // -> y = 0 to +3.6 - // Cb = 0 to +1.7 - // Cr = 0 to +1.7 -#ifndef HAS_FLOAT_TEXTURE -// texvar = texvar * vec3(3.6, 1.7, 1.7); -#endif - signal += texvar * vec3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]); -// END "ntsc-pass2-decode.inc" // - - vec3 rgb = ycbcr2rgb(signal); -#ifndef HAS_FLOAT_TEXTURE -// rgb = rgb * vec3(0.67, 1.0, 1.0); -#endif - -#ifdef GAMMA_CORRECTION - vec3 gamma = vec3(CRT_GAMMA / DISPLAY_GAMMA); - rgb = pow(abs(rgb), gamma.rgb); -#endif - vec4 pixel = vec4(rgb, 1.0); - - opixel = pixel; -} \ No newline at end of file diff --git a/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.cpp b/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.cpp index 505682a47..6cc3ee15b 100644 --- a/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.cpp +++ b/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.cpp @@ -42,69 +42,58 @@ //extern USING_FLAGS *using_flags; -GLDraw_4_5::GLDraw_4_5(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu) : GLDraw_Tmpl(parent, p, logger, emu) +GLDraw_4_5::GLDraw_4_5(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu) : GLDraw_Tmpl(parent, p, logger, emu) { - uTmpTextureID = 0; - - grids_shader = NULL; - - main_pass = NULL; - std_pass = NULL; - ntsc_pass1 = NULL; - ntsc_pass2 = NULL; - led_pass = NULL; - for(int i = 0; i < 32; i++) { - led_pass_vao[i] = NULL; - led_pass_vbuffer[i] = NULL; - osd_pass_vao[i] = NULL; - osd_pass_vbuffer[i] = NULL; - } - grids_horizonal_buffer = NULL; - grids_horizonal_vertex = NULL; - - grids_vertical_buffer = NULL; - grids_vertical_vertex = NULL; ringing_phase = 0.0f; + pixel_width = 0; + pixel_height = 0; #if defined(__LITTLE_ENDIAN__) swap_byteorder = true; #else swap_byteorder = false; #endif - pixel_width = 0; - pixel_height = 0; main_texture_buffer = 0; + main_read_texture_buffer = 0; map_base_address = NULL; main_mutex = new QMutex(); main_texture_ready = false; + sync_fence = 0; + + // ToDo + screen_texture_width = -1 ; + screen_texture_height = -1; } GLDraw_4_5::~GLDraw_4_5() { + // 20200812 K.O: MUST WAIT when changing texture feature. + extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + extfunc->glDeleteSync(sync_fence); + sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +} - if(main_pass != NULL) delete main_pass; - if(std_pass != NULL) delete std_pass; - if(ntsc_pass1 != NULL) delete ntsc_pass1; - if(ntsc_pass2 != NULL) delete ntsc_pass2; - if(led_pass != NULL) delete led_pass; - for(int i = 0; i < 32; i++) { - if(led_pass_vao[i] != NULL) delete led_pass_vao[i]; - if(led_pass_vbuffer[i] != NULL) delete led_pass_vbuffer[i]; - if(osd_pass_vao[i] != NULL) delete osd_pass_vao[i]; - if(osd_pass_vbuffer[i] != NULL) delete osd_pass_vbuffer[i]; - } - - if(grids_horizonal_buffer != NULL) { - if(grids_horizonal_buffer->isCreated()) grids_horizonal_buffer->destroy(); - } - if(grids_horizonal_vertex != NULL) { - if(grids_horizonal_vertex->isCreated()) grids_horizonal_vertex->destroy(); - } - if(grids_vertical_buffer != NULL) { - if(grids_vertical_buffer->isCreated()) grids_vertical_buffer->destroy(); - } - if(grids_horizonal_vertex != NULL) { - if(grids_vertical_vertex->isCreated()) grids_vertical_vertex->destroy(); - } +void GLDraw_4_5::epilogueBlending() +{ + extfunc->glDisable(GL_TEXTURE_2D); + extfunc->glDisable(GL_BLEND); +} +void GLDraw_4_5::prologueBlending() +{ + extfunc->glDisable(GL_TEXTURE_2D); + extfunc->glEnable(GL_BLEND); + extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); +// extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); +} + + +void GLDraw_4_5::drawPolygon(int vertex_loc, uintptr_t p) +{ + extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), (void *)p); + + extfunc->glEnableVertexAttribArray(vertex_loc); + extfunc->glEnable(GL_VERTEX_ARRAY); + extfunc->glDrawArrays(GL_POLYGON, 0, 4); } QOpenGLTexture *GLDraw_4_5::createMainTexture(QImage *img) @@ -113,95 +102,73 @@ QOpenGLTexture *GLDraw_4_5::createMainTexture(QImage *img) QImage *ip = NULL; int w; int h; + if(img == NULL) { w = using_flags->get_real_screen_width(); h = using_flags->get_real_screen_height(); +// return NULL; } else { w = img->width(); h = img->height(); } - QImage im(w, h, QImage::Format_RGBA8888); + csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SCREEN, "createMainTexture(): WxH: %dx%d\n",w, h); + if((w <= 0) || (h <= 0)) return NULL; + QImage *im = NULL; if(img == NULL) { - ip = &im; + im = new QImage(w, h, QImage::Format_RGBA8888); + ip = im; } else { ip = img; } //tx->setFormat(QOpenGLTexture::RGBA8_UNorm); if(main_texture_buffer != 0) { - main_mutex->lock(); - main_texture_ready = false; this->unmap_vram_texture(); - map_base_address = NULL; - extfunc->glDeleteBuffers(1, &main_texture_buffer); - main_texture_buffer = 0; - - extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); - extfunc->glDeleteSync(sync_fence); - sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - main_mutex->unlock(); + main_texture_ready = false; } { - main_mutex->lock(); - extfunc->glGenBuffers(1, &main_texture_buffer); - extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); - //extfunc->glBufferData(GL_PIXEL_UNPACK_BUFFER, w * h * sizeof(uint32_t), ip->constBits(), GL_DYNAMIC_COPY); - //extfunc->glBufferStorage(GL_PIXEL_UNPACK_BUFFER, w * h * sizeof(uint32_t), ip->constBits(), GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - extfunc->glBufferStorage(GL_PIXEL_UNPACK_BUFFER, w * h * sizeof(uint32_t), ip->constBits(), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + QMutexLocker Locker_S(main_mutex); + if(sync_fence != 0) { + extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + extfunc->glDeleteSync(sync_fence); + } + sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + tx = new QOpenGLTexture(QOpenGLTexture::Target2D); tx->setFormat(QOpenGLTexture::RGBA8_UNorm); tx->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Nearest); tx->setWrapMode(QOpenGLTexture::ClampToEdge); tx->setData(*ip, QOpenGLTexture::DontGenerateMipMaps); tx->bind(); - tx->release(); + extfunc->glGenBuffers(1, &main_texture_buffer); + extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); + extfunc->glBufferStorage(GL_PIXEL_UNPACK_BUFFER, + w * h * sizeof(uint32_t), ip->constBits(), + GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + tx->release(); + + tx->bind(); + extfunc->glGenBuffers(1, &main_read_texture_buffer); + extfunc->glBindBuffer(GL_PIXEL_PACK_BUFFER, main_read_texture_buffer); + extfunc->glBufferStorage(GL_PIXEL_PACK_BUFFER, w * h * sizeof(uint32_t), ip->constBits(), GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + extfunc->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + tx->release(); - extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); - extfunc->glDeleteSync(sync_fence); - sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +// extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); +// extfunc->glDeleteSync(sync_fence); +// sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - if(map_vram_texture()) { - main_texture_ready = true; - } pixel_width = w; pixel_height = h; - main_mutex->unlock(); - } - + if(map_vram_texture()) { + main_texture_ready = true; + } + if(im != NULL) delete im; return tx; } -void GLDraw_4_5::initBitmapVertex(void) -{ - if(using_flags->is_use_one_board_computer()) { - vertexBitmap[0].x = -1.0f; - vertexBitmap[0].y = -1.0f; - vertexBitmap[0].z = 0.5f; - vertexBitmap[0].s = 0.0f; - vertexBitmap[0].t = 1.0f; - - vertexBitmap[1].x = +1.0f; - vertexBitmap[1].y = -1.0f; - vertexBitmap[1].z = 0.5f; - vertexBitmap[1].s = 1.0f; - vertexBitmap[1].t = 1.0f; - - vertexBitmap[2].x = +1.0f; - vertexBitmap[2].y = +1.0f; - vertexBitmap[2].z = 0.5f; - vertexBitmap[2].s = 1.0f; - vertexBitmap[2].t = 0.0f; - - vertexBitmap[3].x = -1.0f; - vertexBitmap[3].y = +1.0f; - vertexBitmap[3].z = 0.5f; - vertexBitmap[3].s = 0.0f; - vertexBitmap[3].t = 0.0f; - - } -} void GLDraw_4_5::initFBO(void) { @@ -262,12 +229,12 @@ void GLDraw_4_5::initGLObjects() void GLDraw_4_5::initPackedGLObject(GLScreenPack **p, int _width, int _height, const QString vertex_shader, const QString fragment_shader, - const QString _name, bool req_float, bool req_highp) + const QString _name, bool req_float, bool req_highp, bool req_alpha_channel) { QString s; GLScreenPack *pp; if(p != NULL) { - pp = new GLScreenPack(_width, _height, _name, p_wid, req_float, req_highp); + pp = new GLScreenPack(_width, _height, _name, p_wid, req_float, req_highp, req_alpha_channel); *p = pp; if(pp != NULL) { pp->initialize(_width, _height, vertex_shader, fragment_shader); @@ -383,8 +350,8 @@ void GLDraw_4_5::initLocalGLObjects(void) int _width = using_flags->get_screen_width(); int _height = using_flags->get_screen_height(); - if((_width * 4) <= texture_max_size) { - _width = _width * 4; + if(((int)(_width * 4)) <= texture_max_size) { + _width = (int)(_width * 4); low_resolution_screen = true; } else { _width = _width * 2; @@ -418,13 +385,13 @@ void GLDraw_4_5::initLocalGLObjects(void) if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) { initPackedGLObject(&main_pass, using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2, - ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/chromakey_fragment_shader2.glsl", - "Main Shader", true); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/chromakey_fragment_shader2.glsl", + "Main Shader", false, false, true); } else { initPackedGLObject(&main_pass, using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2, - ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/fragment_shader.glsl", - "Main Shader", true); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/fragment_shader.glsl", + "Main Shader", false, false, true); } if(main_pass != NULL) { setNormalVAO(main_pass->getShader(), main_pass->getVAO(), @@ -434,13 +401,13 @@ void GLDraw_4_5::initLocalGLObjects(void) #if 0 initPackedGLObject(&std_pass, using_flags->get_screen_width(), using_flags->get_screen_height(), - ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/chromakey_fragment_shader.glsl", - "Standard Shader", true); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/chromakey_fragment_shader.glsl", + "Standard Shader", true, true, true); #endif initPackedGLObject(&led_pass, 10, 10, - ":/gl4_5/led_vertex_shader.glsl" , ":/gl4_5/led_fragment_shader.glsl", - "LED Shader", true); + ":/gl/shaders/led_vertex_shader.glsl" , ":/gl/shaders/led_fragment_shader.glsl", + "LED Shader", true, false, true); for(int i = 0; i < 32; i++) { led_pass_vao[i] = new QOpenGLVertexArrayObject; led_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); @@ -458,8 +425,8 @@ void GLDraw_4_5::initLocalGLObjects(void) } initPackedGLObject(&osd_pass, 48.0, 48.0, - ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/icon_fragment_shader.glsl", - "OSD Shader", true); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/icon_fragment_shader.glsl", + "OSD Shader", false, false, true); for(int i = 0; i < 32; i++) { osd_pass_vao[i] = new QOpenGLVertexArrayObject; osd_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); @@ -478,14 +445,15 @@ void GLDraw_4_5::initLocalGLObjects(void) #if 1 initPackedGLObject(&ntsc_pass1, - _width, _height, - ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/ntsc_pass1.glsl", - "NTSC Shader Pass1", true, true); + _width, _height * 1, + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/ntsc_pass1.glsl", + "NTSC Shader Pass1", true, false); initPackedGLObject(&ntsc_pass2, _width / 2, _height, - ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/ntsc_pass2.glsl", - "NTSC Shader Pass2", true, true); - if(!(((gl_major_version >= 3) && (gl_minor_version >= 1)) || (gl_major_version >= 4))){ + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/ntsc_pass2.glsl", + "NTSC Shader Pass2", false, false); + #if 0 + { int ii; QOpenGLShaderProgram *shader = ntsc_pass2->getShader(); shader->bind(); @@ -499,14 +467,14 @@ void GLDraw_4_5::initLocalGLObjects(void) } shader->release(); } - + #endif #endif if(using_flags->is_use_one_board_computer()) { initBitmapVertex(); initPackedGLObject(&bitmap_block, _width * 2, _height * 2, - ":/gl4_5/vertex_shader.glsl", ":/gl4_5/normal_fragment_shader.glsl", - "Background Bitmap Shader", true); + ":/gl/shaders/vertex_shader.glsl", ":/gl/shaders/normal_fragment_shader.glsl", + "Background Bitmap Shader", true, true, true); if(bitmap_block != NULL) { setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(), bitmap_block->getVertexBuffer(), @@ -514,7 +482,7 @@ void GLDraw_4_5::initLocalGLObjects(void) } } - initGridShaders(":/gl4_5/grids_vertex_shader_fixed.glsl", ":/gl4_5/grids_vertex_shader.glsl", ":/gl4_5/grids_fragment_shader.glsl"); + initGridShaders(":/gl/shaders/grids_vertex_shader_fixed.glsl", ":/gl/shaders/grids_vertex_shader.glsl", ":/gl/shaders/grids_fragment_shader.glsl"); initGridVertexObject(&grids_horizonal_buffer, &grids_horizonal_vertex, using_flags->get_real_screen_height() + 3); doSetGridsHorizonal(using_flags->get_real_screen_height(), true); @@ -611,7 +579,7 @@ void GLDraw_4_5::drawGridsMain(QOpenGLShaderProgram *prg, prg->enableAttributeArray("vertex"); int vertex_loc = prg->attributeLocation("vertex"); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0); extfunc->glEnableVertexAttribArray(vertex_loc); @@ -695,6 +663,8 @@ void GLDraw_4_5::renderToTmpFrameBuffer_nPass(GLuint src_texture, extfunc->glBindTexture(GL_TEXTURE_2D, src_texture); extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +// extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //extfunc->glColor4f(1.0, 1.0, 1.0, 1.0); shader->setUniformValue("a_texture", 0); shader->setUniformValue("v_ortho", ortho); @@ -702,17 +672,18 @@ void GLDraw_4_5::renderToTmpFrameBuffer_nPass(GLuint src_texture, { ii = shader->uniformLocation("source_size"); if(ii >= 0) { - QVector4D source_size = QVector4D((float)src_w, (float)src_h, 0, 0); + QVector2D source_size = QVector2D((float)src_w, (float)src_h); shader->setUniformValue(ii, source_size); } ii = shader->uniformLocation("target_size"); if(ii >= 0) { - QVector4D target_size = QVector4D((float)dst_w, (float)dst_h, 0, 0); + QVector2D target_size = QVector2D((float)dst_w, (float)dst_h); shader->setUniformValue(ii, target_size); } ii = shader->uniformLocation("phase"); if(ii >= 0) { - ringing_phase = ringing_phase + 0.093; +// ringing_phase = ringing_phase + 0.093; + ringing_phase = ringing_phase + 0.063; if(ringing_phase > 1.0) ringing_phase = ringing_phase - 1.0; shader->setUniformValue(ii, ringing_phase); } @@ -773,6 +744,7 @@ void GLDraw_4_5::renderToTmpFrameBuffer_nPass(GLuint src_texture, shader->setUniformValue(ii, GL_FALSE); } } + } shader->enableAttributeArray("texcoord"); @@ -805,60 +777,61 @@ void GLDraw_4_5::uploadMainTexture(QImage *p, bool use_chromakey, bool was_mappe imgptr = p; if(uVramTextureID == NULL) { uVramTextureID = createMainTexture(p); - } else { + } else + { + if((screen_texture_width <= 0) || (screen_texture_height <= 0)) return; + // Upload to main texture - if(p != NULL) { -#if 1 - if(map_base_address == NULL) { + bool is_dummy = false; + + if(((map_base_address == NULL) && (p == NULL)) && (main_texture_buffer != 0)){ + is_dummy = true; + } + if((map_base_address == NULL) && !(is_dummy)) { + if(main_texture_buffer != 0) { extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); - uint32_t* pp = (uint32_t *)(extfunc->glMapNamedBufferRange(main_texture_buffer, 0, pixel_width * pixel_height * sizeof(scrntype_t), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT)); - //uint32_t *pp = (uint32_t *)(extfunc->glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY)); + uint32_t* pp = (uint32_t *)(extfunc->glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, + 0, + pixel_width *pixel_height * sizeof(scrntype_t), + GL_MAP_WRITE_BIT )); + int hh = (pixel_height < p->height()) ? pixel_height : p->height(); + int ww = (pixel_width < p->width()) ? pixel_width : p->width(); if(pp != NULL) { - int hh = (pixel_height < p->height()) ? pixel_height : p->height(); for(int y = 0; y < hh; y++) { - memcpy(&(pp[y * pixel_width]), p->scanLine(y), p->width() * sizeof(uint32_t)); + memcpy(&(pp[y * pixel_width]), p->scanLine(y), ww * sizeof(uint32_t)); } } extfunc->glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); - extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId()); - //extfunc->glActiveTexture(GL_TEXTURE0); - extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, p->width(), p->height(), GL_RGBA, GL_UNSIGNED_BYTE, 0); - extfunc->glBindTexture(GL_TEXTURE_2D, 0); - extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - } else { - main_mutex->lock(); - extfunc->glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, pixel_width *pixel_height * sizeof(scrntype_t)); - extfunc->glWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); - extfunc->glDeleteSync(sync_fence); + if(sync_fence != 0) { + extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + extfunc->glDeleteSync(sync_fence); + } sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - - extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); + extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId()); - //extfunc->glActiveTexture(GL_TEXTURE0); - extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_width, pixel_height, GL_RGBA, GL_UNSIGNED_BYTE, 0); + extfunc->glActiveTexture(GL_TEXTURE0); + extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_width, hh, GL_RGBA, GL_UNSIGNED_BYTE, 0); extfunc->glBindTexture(GL_TEXTURE_2D, 0); extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - //extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); - //extfunc->glDeleteSync(sync_fence); - //sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - main_mutex->unlock(); } -#else - uVramTextureID->setData(*p, QOpenGLTexture::DontGenerateMipMaps); -#endif } else { - // This sequence is *outside* of normal rendering phase, maybe using compute shader. + // p == NULL + main_mutex->lock(); + // Flush buffer range + extfunc->glFlushMappedNamedBufferRange(main_texture_buffer, 0, pixel_width *pixel_height * sizeof(scrntype_t)); + if(sync_fence != 0) { + extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + extfunc->glDeleteSync(sync_fence); + } + sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + uVramTextureID->bind(); extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); - extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId()); - //extfunc->glActiveTexture(GL_TEXTURE0); + extfunc->glActiveTexture(GL_TEXTURE0); extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_width, pixel_height, GL_RGBA, GL_UNSIGNED_BYTE, 0); extfunc->glBindTexture(GL_TEXTURE_2D, 0); extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + main_mutex->unlock(); } } #if 1 @@ -867,15 +840,15 @@ void GLDraw_4_5::uploadMainTexture(QImage *p, bool use_chromakey, bool was_mappe screen_texture_width, screen_texture_height, ntsc_pass1, - ntsc_pass1->getViewportWidth(), - ntsc_pass1->getViewportHeight()); + ntsc_pass1->getTextureWidth(), + ntsc_pass1->getTextureHeight()); renderToTmpFrameBuffer_nPass(ntsc_pass1->getTexture(), - ntsc_pass1->getViewportWidth(), - ntsc_pass1->getViewportHeight(), + ntsc_pass1->getTextureWidth(), + ntsc_pass1->getTextureHeight(), ntsc_pass2, - ntsc_pass2->getViewportWidth(), - ntsc_pass2->getViewportHeight()); + ntsc_pass2->getTextureWidth(), + ntsc_pass2->getTextureHeight()); uTmpTextureID = ntsc_pass2->getTexture(); } else #endif @@ -908,6 +881,7 @@ void GLDraw_4_5::drawScreenTexture(void) true, QVector3D(0.0, 0.0, 0.0)); extfunc->glDisable(GL_BLEND); } else { +// extfunc->glEnable(GL_DEPTH_TEST); drawMain(main_pass, uTmpTextureID, // v2.0 color, smoosing); @@ -924,12 +898,18 @@ void GLDraw_4_5::drawMain(QOpenGLShaderProgram *prg, QVector3D chromakey) { int ii; + if((screen_texture_width <= 0) || (screen_texture_height <= 0)) return; + if(sync_fence != 0) { + extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + extfunc->glDeleteSync(sync_fence); + } + sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); if(texid != 0) { vp->bind(); bp->bind(); prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); QMatrix4x4 ortho; ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); @@ -984,7 +964,11 @@ void GLDraw_4_5::drawMain(QOpenGLShaderProgram *prg, //} else { //prg->setUniformValue("rotate", GL_FALSE); //} - + if(!(using_flags->is_use_one_board_computer())) { + prg->setUniformValue("distortion_v", 0.08f, 0.08f); // ToDo: Change val + } + prg->setUniformValue("luminance", 0.9f); // ToDo: Change val + prg->setUniformValue("lum_offset", 0.08f); // ToDo: Change val if(do_chromakey) { ii = prg->uniformLocation("chromakey"); if(ii >= 0) { @@ -1024,7 +1008,7 @@ void GLDraw_4_5::drawMain(QOpenGLShaderProgram *prg, vp->bind(); bp->bind(); prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); QMatrix4x4 ortho; ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); @@ -1052,6 +1036,9 @@ void GLDraw_4_5::drawMain(QOpenGLShaderProgram *prg, } prg->setUniformValue("rotate_mat", rot); prg->setUniformValue("v_ortho", ortho); + if(!(using_flags->is_use_one_board_computer())) { + prg->setUniformValue("distortion_v", 0.08f, 0.08f); // ToDo: Change val + } if(do_chromakey) { ii = prg->uniformLocation("chromakey"); @@ -1079,9 +1066,6 @@ void GLDraw_4_5::drawMain(QOpenGLShaderProgram *prg, extfunc->glBindTexture(GL_TEXTURE_2D, 0); } - extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); - extfunc->glDeleteSync(sync_fence); - sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } void GLDraw_4_5::drawMain(GLScreenPack *obj, @@ -1116,7 +1100,7 @@ void GLDraw_4_5::drawButtonsMain(int num, bool f_smoosing) prg->bind(); QMatrix4x4 ortho; ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glActiveTexture(GL_TEXTURE0); extfunc->glBindTexture(GL_TEXTURE_2D, texid); @@ -1197,122 +1181,6 @@ void GLDraw_4_5::drawBitmapTexture(void) } } -void GLDraw_4_5::drawLedMain(GLScreenPack *obj, int num, QVector4D color) -{ - QOpenGLShaderProgram *prg = obj->getShader(); - QOpenGLVertexArrayObject *vp = led_pass_vao[num]; - QOpenGLBuffer *bp = led_pass_vbuffer[num]; - int ii; - - { - extfunc->glEnable(GL_BLEND); - extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - vp->bind(); - bp->bind(); - prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); - //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); - ii = prg->uniformLocation("color"); - if(ii >= 0) { - prg->setUniformValue(ii, color); - } - - prg->enableAttributeArray("vertex"); - int vertex_loc = prg->attributeLocation("vertex"); - prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t)); - extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0); - - extfunc->glEnableVertexAttribArray(vertex_loc); - extfunc->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - bp->release(); - vp->release(); - - prg->release(); - extfunc->glDisable(GL_BLEND); - } - -} - - -void GLDraw_4_5::drawOsdLeds() -{ - QVector4D color_on; - QVector4D color_off; - uint32_t bit = 0x00000001; - if(osd_onoff) { - color_on = QVector4D(0.95, 0.0, 0.05, 1.0); - color_off = QVector4D(0.05,0.05, 0.05, 0.10); - } else { - color_on = QVector4D(0.00,0.00, 0.00, 0.0); - color_off = QVector4D(0.00,0.00, 0.00, 0.0); - } - if(osd_onoff) { - //if(osd_led_status_bak != osd_led_status) { - for(int i = 0; i < osd_led_bit_width; i++) { - if((bit & osd_led_status) == (bit & osd_led_status_bak)) { - bit <<= 1; - continue; - } - drawLedMain(led_pass, i, - ((osd_led_status & bit) != 0) ? color_on : color_off); - bit <<= 1; - } - osd_led_status_bak = osd_led_status; - //} - } -} - -void GLDraw_4_5::drawOsdIcons() -{ - QVector4D color_on; - QVector4D color_off; - uint32_t bit = 0x00000001; - if(osd_onoff) { - color_on = QVector4D(1.0, 1.0, 1.0, 0.8); - color_off = QVector4D(1.0, 1.0, 1.0, 0.00); - } else { - color_on = QVector4D(0.00,0.00, 0.00, 0.0); - color_off = QVector4D(0.00,0.00, 0.00, 0.0); - } - if(osd_onoff) { - int major, minor; - //if(osd_led_status_bak != osd_led_status) { - for(int i = 0; i < osd_led_bit_width; i++) { - if((bit & osd_led_status) == (bit & osd_led_status_bak)) { - if((bit & osd_led_status) == 0) { - bit <<= 1; - continue; - } - } - if((i >= 2) && (i < 10)) { // FD - major = 2; - minor = i - 2; - } else if((i >= 10) && (i < 12)) { // QD - major = 3; - minor = i - 10; - } else if((i >= 12) && (i < 14)) { // CMT(R) - major = 4; - minor = i - 12; - } else if((i >= 14) && (i < 16)) { // CMT(W) - major = 5; - minor = i - 14; - } else { - major = 0; - minor = 0; - } - if(major != 0) { - drawMain(osd_pass->getShader(), osd_pass_vao[i], osd_pass_vbuffer[i], - icon_texid[major][minor]->textureId(), - ((osd_led_status & bit) != 0) ? color_on : color_off, - false, false, QVector3D(0.0, 0.0, 0.0)); - } - bit <<= 1; - } - osd_led_status_bak = osd_led_status; - //} - } -} - void GLDraw_4_5::paintGL(void) { //p_wid->makeCurrent(); @@ -1322,7 +1190,7 @@ void GLDraw_4_5::paintGL(void) crt_flag = false; } redraw_required = false; - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1506,6 +1374,7 @@ void GLDraw_4_5::set_led_vertex(int xbit) void GLDraw_4_5::do_set_screen_multiply(float mul) { screen_multiply = mul; + if((screen_texture_width <= 0) || (screen_texture_height <= 0)) return; do_set_texture_size(imgptr, screen_texture_width, screen_texture_height); } @@ -1522,11 +1391,13 @@ void GLDraw_4_5::do_set_texture_size(QImage *p, int w, int h) iw = (float)using_flags->get_real_screen_width(); ih = (float)using_flags->get_real_screen_height(); } - //printf("%dx%d -> %fx%f\n", w, h, iw, ih); - if(p_wid != NULL) { + csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SCREEN, "%dx%d -> %fx%f\n", w, h, iw, ih); + if((p_wid != NULL) && + ((screen_texture_width != w) || (screen_texture_height != h)) && + (w > 0) && (h > 0)) { screen_texture_width = w; screen_texture_height = h; - + p_wid->makeCurrent(); { //set_texture_vertex(p, p_wid->width(), p_wid->height(), w, h); @@ -1541,21 +1412,21 @@ void GLDraw_4_5::do_set_texture_size(QImage *p, int w, int h) vertexTmpTexture, 4); } - if(((int)iw != pixel_width) || ((int)ih != pixel_height)) { + /*if(((int)iw != pixel_width) || ((int)ih != pixel_height))*/ { QImage im((int)screen_texture_width, (int)screen_texture_height, QImage::Format_RGBA8888); if(p == NULL) { p = &im; } if(uVramTextureID != NULL) { - p_wid->makeCurrent(); +// p_wid->makeCurrent(); uVramTextureID->destroy(); delete uVramTextureID; uVramTextureID = createMainTexture(p); - p_wid->doneCurrent(); +// p_wid->doneCurrent(); } else { - p_wid->makeCurrent(); +// p_wid->makeCurrent(); uVramTextureID = createMainTexture(p); - p_wid->doneCurrent(); +// p_wid->doneCurrent(); } } vertexFormat[0].x = -1.0f; @@ -1572,14 +1443,14 @@ void GLDraw_4_5::do_set_texture_size(QImage *p, int w, int h) vertexFormat[3].z = -0.9f; vertexFormat[0].s = 0.0f; - //vertexFormat[0].t = (float)h / ih; - //vertexFormat[1].s = (float)w / iw; - //vertexFormat[1].t = (float)h / ih; - //vertexFormat[2].s = (float)w / iw; - vertexFormat[0].t = 1.0f; - vertexFormat[1].s = 1.0f; - vertexFormat[1].t = 1.0f; - vertexFormat[2].s = 1.0f; + vertexFormat[0].t = (float)h / ih; + vertexFormat[1].s = (float)w / iw; + vertexFormat[1].t = (float)h / ih; + vertexFormat[2].s = (float)w / iw; + //vertexFormat[0].t = 1.0f; + //vertexFormat[1].s = 1.0f; + //vertexFormat[1].t = 1.0f; + //vertexFormat[2].s = 1.0f; vertexFormat[2].t = 0.0f; vertexFormat[3].s = 0.0f; vertexFormat[3].t = 0.0f; @@ -1619,7 +1490,6 @@ void GLDraw_4_5::resizeGL_Screen(void) void GLDraw_4_5::resizeGL(int width, int height) { //int side = qMin(width, height); - p_wid->makeCurrent(); extfunc->glViewport(0, 0, width, height); //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); crt_flag = true; @@ -1639,207 +1509,8 @@ void GLDraw_4_5::resizeGL(int width, int height) if(using_flags->get_max_button() > 0) { updateButtonTexture(); } - p_wid->doneCurrent(); } -void GLDraw_4_5::initButtons(void) -{ - button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); - QOpenGLContext *context = QOpenGLContext::currentContext(); - QPair _version = QOpenGLVersionProfile(context->format()).version(); - QString versionext = QString::fromUtf8(""); - if(((_version.first == 4) && (_version.second >= 3)) || (_version.first >= 5)) { - versionext = QString::fromUtf8("#version 430 core \n"); // OK? - } else if((_version.first == 4)) { - versionext = QString::fromUtf8("#version 400 core \n"); - } else { // Require GLVersion >= 3.2 - versionext = QString::fromUtf8("#version 150 \n"); - } - - if(vm_buttons_d != NULL) { - button_shader = new QOpenGLShaderProgram(p_wid); - if(button_shader != NULL) { - bool f = false; - QFile vertex_src(QString::fromUtf8(":/gl4_5/vertex_shader.glsl")); - if (vertex_src.open(QIODevice::ReadOnly | QIODevice::Text)) { - QString srcs = versionext; - srcs = srcs + QString::fromUtf8(vertex_src.readAll()); - f = button_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, srcs); - vertex_src.close(); - } else { - return; - } - QFile fragment_src(QString::fromUtf8(":/gl4_5/normal_fragment_shader.glsl")); - if (fragment_src.open(QIODevice::ReadOnly | QIODevice::Text)) { - QString srcs = versionext; - srcs = srcs + QString::fromUtf8(fragment_src.readAll()); - f &= button_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, srcs); - fragment_src.close(); - } else { - return; - } - if(!f) return; - button_shader->link(); - } - - int ip = using_flags->get_max_button(); - if(ip > 0) { - for(int num = 0; num < ip; num++) { - QString tmps; - tmps = QString::asprintf(":/button%02d.png", num); - QImageReader *reader = new QImageReader(tmps); - QImage *result = new QImage(reader->read()); - QImage pic; - if(result != NULL) { - if(!result->isNull()) { - pic = result->convertToFormat(QImage::Format_ARGB32); - } else { - pic = QImage(10, 10, QImage::Format_RGBA8888); - pic.fill(QColor(0,0,0,0)); - } - delete result; - }else { - pic = QImage(10, 10, QImage::Format_RGBA8888); - pic.fill(QColor(0,0,0,0)); - } - ButtonImages.push_back(pic); - } - } - vertexButtons = new QVector; - for(int i = 0; i < using_flags->get_max_button(); i++) { - buffer_button_vertex[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - buffer_button_vertex[i]->create(); - fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width(); - fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height(); - fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width(); - fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height(); - - vertex_button[i] = new QOpenGLVertexArrayObject; - if(vertex_button[i] != NULL) { - if(vertex_button[i]->create()) { - VertexTexCoord_t vt[4]; - - vt[0].x = fButtonX[i]; - vt[0].y = fButtonY[i]; - vt[0].z = -0.5f; - vt[0].s = 0.0f; - vt[0].t = 0.0f; - - vt[1].x = fButtonX[i] + fButtonWidth[i]; - vt[1].y = fButtonY[i]; - vt[1].z = -0.5f; - vt[1].s = 1.0f; - vt[1].t = 0.0f; - - vt[2].x = fButtonX[i] + fButtonWidth[i]; - vt[2].y = fButtonY[i] - fButtonHeight[i]; - vt[2].z = -0.5f; - vt[2].s = 1.0f; - vt[2].t = 1.0f; - - vt[3].x = fButtonX[i]; - vt[3].y = fButtonY[i] - fButtonHeight[i]; - vt[3].z = -0.5f; - vt[3].s = 0.0f; - vt[3].t = 1.0f; - - vertexButtons->append(vt[0]); - vertexButtons->append(vt[1]); - vertexButtons->append(vt[2]); - vertexButtons->append(vt[3]); - vertex_button[i]->bind(); - buffer_button_vertex[i]->bind(); - buffer_button_vertex[i]->allocate(4 * sizeof(VertexTexCoord_t)); - - buffer_button_vertex[i]->setUsagePattern(QOpenGLBuffer::StaticDraw); - buffer_button_vertex[i]->release(); - vertex_button[i]->release(); - setNormalVAO(button_shader, vertex_button[i], - buffer_button_vertex[i], - vt, 4); - } - } - } - } -} - -void GLDraw_4_5::do_set_display_osd(bool onoff) -{ - osd_onoff = onoff; -} - -void GLDraw_4_5::do_display_osd_leds(int lednum, bool onoff) -{ - if(lednum == -1) { - osd_led_status = (onoff) ? 0xffffffff : 0x00000000; - } else if((lednum >= 0) && (lednum < 32)) { - uint32_t nn; - nn = 0x00000001 << lednum; - if(onoff) { - osd_led_status |= nn; - } else { - osd_led_status &= ~nn; - } - } -} - -void GLDraw_4_5::uploadIconTexture(QPixmap *p, int icon_type, int localnum) -{ - if((icon_type > 7) || (icon_type < 0)) return; - if((localnum >= 9) || (localnum < 0)) return; - if(p == NULL) return; - p_wid->makeCurrent(); - QImage image = p->toImage(); - - if(icon_texid[icon_type][localnum] != NULL) delete icon_texid[icon_type][localnum]; - { - icon_texid[icon_type][localnum] = new QOpenGLTexture(image); - } - p_wid->doneCurrent(); - -} - - -void GLDraw_4_5::updateBitmap(QImage *p) -{ - if(!using_flags->is_use_one_board_computer()) return; - redraw_required = true; - bitmap_uploaded = false; - uploadBitmapTexture(p); -} - -void GLDraw_4_5::uploadBitmapTexture(QImage *p) -{ - if(!using_flags->is_use_one_board_computer()) return; - if(p == NULL) return; - if(!bitmap_uploaded) { - p_wid->makeCurrent(); - if(uBitmapTextureID != NULL) { - delete uBitmapTextureID; - } - uBitmapTextureID = new QOpenGLTexture(*p); - p_wid->doneCurrent(); - bitmap_uploaded = true; - crt_flag = true; - } -} - -void GLDraw_4_5::updateButtonTexture(void) -{ - int i; - button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); - if(button_updated) return; - if(vm_buttons_d != NULL) { - for(i = 0; i < using_flags->get_max_button(); i++) { - QImage img = ButtonImages.at(i); - if(uButtonTextureID[i] != NULL) { - delete uButtonTextureID[i]; - } - uButtonTextureID[i] = new QOpenGLTexture(img); - } - } - button_updated = true; -} void GLDraw_4_5::get_screen_geometry(int *w, int *h) { @@ -1847,21 +1518,63 @@ void GLDraw_4_5::get_screen_geometry(int *w, int *h) if(h != NULL) *h = pixel_height; } +bool GLDraw_4_5::copy_screen_buffer(scrntype_t *target, int w, int h, int stride) +{ + int hh = h; + if(stride <= 0) return false; + if(target == NULL) return false; + if((w <= 0) || (h <= 0)) return false; + if(w >= pixel_width) w = pixel_width; + if(h >= pixel_height) h = pixel_height; + if(stride >= pixel_width) stride = pixel_width; + if(w >= stride) w = stride; + +// if((map_base_address == NULL) || !(main_texture_ready)) { +// return false; +// } + QMutexLocker Locker_S(main_mutex); + extfunc->glBindBuffer(GL_PIXEL_PACK_BUFFER, main_read_texture_buffer); + extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId()); + extfunc->glActiveTexture(GL_TEXTURE0); + extfunc->glGetTextureImage(uVramTextureID->textureId(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, pixel_width * pixel_height * sizeof(scrntype_t), NULL); + scrntype_t*pp = (scrntype_t *)(extfunc->glMapNamedBufferRange(main_read_texture_buffer, 0, pixel_width * pixel_height * sizeof(scrntype_t), GL_MAP_READ_BIT )); + extfunc->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + if(pp == NULL) return false; +// printf("READ SCREEN\n"); + scrntype_t *p = (scrntype_t *)pp; + scrntype_t *q = target; + for(int y = 0; y < hh; y++) { + memcpy(&(pp[y * pixel_width]), q, w * sizeof(uint32_t)); + q = q + stride; + } +// extfunc->glBindBuffer(GL_PIXEL_PACK_BUFFER, main_read_texture_buffer); +// extfunc->glUnmapBuffer(GL_PIXEL_PACK_BUFFER); +// extfunc->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + return true; +} + scrntype_t *GLDraw_4_5::get_screen_buffer(int y) { - if((y < 0) || (y >= pixel_height)) return NULL; + QMutexLocker Locker_S(main_mutex); + if((y < 0) || (y >= pixel_height) || (pixel_width < 0)) return NULL; if((map_base_address == NULL) || !(main_texture_ready)) { return NULL; } else { - main_mutex->lock(); - extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); - extfunc->glDeleteSync(sync_fence); - sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +// int of = (y <= 0) ? 0 : (pixel_width * (y - 1)); +// int len = (y <= 0) ? (pixel_width * pixel_height) : pixel_width; +// extfunc->glFlushMappedNamedBufferRange(main_texture_buffer, of, len * sizeof(scrntype_t)); +// if(sync_fence != 0) { +// extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); +// extfunc->glDeleteSync(sync_fence); +// } +// sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); scrntype_t *p = (scrntype_t *)map_base_address; + p = p + (pixel_width * y); //printf("%08x\n", (uintptr_t)p); - main_mutex->unlock(); return p; } } @@ -1883,6 +1596,7 @@ bool GLDraw_4_5::is_ready_to_map_vram_texture(void) bool GLDraw_4_5::map_vram_texture(void) { + QMutexLocker Locker_S(main_mutex); if(main_texture_buffer == 0) { return false; } @@ -1899,27 +1613,51 @@ bool GLDraw_4_5::map_vram_texture(void) #if 0 return false; #else - + // 20200812 K.O: MUST WAIT when changing texture feature. + extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + extfunc->glDeleteSync(sync_fence); + sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + + extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); + map_base_address = + (scrntype_t *)(extfunc->glMapNamedBufferRange( + main_texture_buffer, 0, + pixel_width * pixel_height * sizeof(scrntype_t), + GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT)); + + // 20200812 K.O: MUST WAIT when changing texture feature. extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); extfunc->glDeleteSync(sync_fence); sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); - map_base_address = (scrntype_t *)(extfunc->glMapNamedBufferRange(main_texture_buffer, 0, pixel_width * pixel_height * sizeof(scrntype_t), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT)); csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SCREEN, "MAPPED SCREEN TO PHYSICAL ADDRESS:%0llx\n", (uintptr_t)map_base_address); - //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); if(map_base_address == NULL) return false; + return true; #endif } bool GLDraw_4_5::unmap_vram_texture(void) { + QMutexLocker Locker_S(main_mutex); if((map_base_address == NULL) || (main_texture_buffer == 0)) return false; - + if(sync_fence != 0) { + extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0); + extfunc->glDeleteSync(sync_fence); + } + sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + map_base_address = NULL; + extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer); extfunc->glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - + + extfunc->glDeleteBuffers(1, &main_texture_buffer); + main_texture_buffer = 0; + + extfunc->glDeleteBuffers(1, &main_read_texture_buffer); + main_read_texture_buffer = 0; + return true; } diff --git a/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.h b/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.h index b8f38e289..4d10180f5 100644 --- a/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.h +++ b/source/src/qt/gui/gl4_5/qt_glutil_gl4_5.h @@ -28,101 +28,16 @@ class DLL_PREFIX GLDraw_4_5 : public GLDraw_Tmpl Q_OBJECT private: QOpenGLFunctions_4_5_Core *extfunc; - float ringing_phase; -protected: - const float luma_filter[24 + 1] = { - -0.000012020, - -0.000022146, - -0.000013155, - -0.000012020, - -0.000049979, - -0.000113940, - -0.000122150, - -0.000005612, - 0.000170516, - 0.000237199, - 0.000169640, - 0.000285688, - 0.000984574, - 0.002018683, - 0.002002275, - -0.000909882, - -0.007049081, - -0.013222860, - -0.012606931, - 0.002460860, - 0.035868225, - 0.084016453, - 0.135563500, - 0.175261268, - 0.190176552 - }; - const float chroma_filter[24 + 1] = { - -0.000118847, - -0.000271306, - -0.000502642, - -0.000930833, - -0.001451013, - -0.002064744, - -0.002700432, - -0.003241276, - -0.003524948, - -0.003350284, - -0.002491729, - -0.000721149, - 0.002164659, - 0.006313635, - 0.011789103, - 0.018545660, - 0.026414396, - 0.035100710, - 0.044196567, - 0.053207202, - 0.061590275, - 0.068803602, - 0.074356193, - 0.077856564, - 0.079052396 - }; - const float rot0[4] = {1, -0, 0, 1}; - const float rot90[4] = {0, 1, -1, 0}; - const float rot180[4] = {-1, 0, 0, -1}; - const float rot270[4] = {0, -1, 1, 0}; - - int gl_major_version; - int gl_minor_version; +protected: int pixel_width; int pixel_height; GLuint main_texture_buffer; + GLuint main_read_texture_buffer; GLsync sync_fence; QMutex *main_mutex; scrntype_t *map_base_address; - - GLScreenPack *main_pass; - GLScreenPack *std_pass; - GLScreenPack *ntsc_pass1; - GLScreenPack *ntsc_pass2; - GLScreenPack *bitmap_block; - GLScreenPack *led_pass; - GLScreenPack *osd_pass; - QOpenGLBuffer *led_pass_vbuffer[32]; - QOpenGLVertexArrayObject *led_pass_vao[32]; - QOpenGLBuffer *osd_pass_vbuffer[32]; - QOpenGLVertexArrayObject *osd_pass_vao[32]; - - VertexTexCoord_t vertexTmpTexture[4]; - - QOpenGLShaderProgram *grids_shader; - QOpenGLBuffer *grids_horizonal_buffer; - QOpenGLVertexArrayObject *grids_horizonal_vertex; - QOpenGLBuffer *grids_vertical_buffer; - QOpenGLVertexArrayObject *grids_vertical_vertex; - GLuint uTmpTextureID; - bool swap_byteorder; - bool main_texture_ready; - virtual void setNormalVAO(QOpenGLShaderProgram *prg, QOpenGLVertexArrayObject *vp, QOpenGLBuffer *bp, VertexTexCoord_t *tp, int size = 4); virtual bool initGridShaders(const QString vertex_fixed, const QString vertex_rotate, const QString fragment); @@ -143,7 +58,10 @@ class DLL_PREFIX GLDraw_4_5 : public GLDraw_Tmpl virtual void initPackedGLObject(GLScreenPack **p, int _width, int _height, const QString vertex_shader, const QString fragment_shader, - const QString _name, bool req_float = false, bool req_highp = false); + const QString _name, + bool req_float = false, bool req_highp = false, + bool req_alpha_channel = true); + virtual void drawGridsHorizonal(void); virtual void drawGridsVertical(void); virtual void drawGrids(); @@ -170,23 +88,24 @@ class DLL_PREFIX GLDraw_4_5 : public GLDraw_Tmpl bool use_chromakey = false); virtual void drawBitmapTexture(void); virtual void drawButtonsMain(int num, bool f_smoosing); - virtual void drawOsdLeds(); - virtual void drawOsdIcons(); - virtual void drawLedMain(GLScreenPack *obj, int num, QVector4D color); +// virtual void drawOsdLeds(); +// virtual void drawOsdIcons(); +// virtual void drawLedMain(GLScreenPack *obj, int num, QVector4D color); + virtual void prologueBlending(); + virtual void epilogueBlending(); + virtual void drawPolygon(int vertex_loc, uintptr_t p = 0); virtual void set_led_vertex(int bit); virtual void set_osd_vertex(int bit); - virtual void initBitmapVertex(void); - virtual QOpenGLTexture *createMainTexture(QImage *img); - void updateButtonTexture(void); + virtual QOpenGLTexture *createMainTexture(QImage *img); public: - GLDraw_4_5(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu = 0); + GLDraw_4_5(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu = 0); ~GLDraw_4_5(); void drawButtons(void); virtual void initGLObjects(); virtual void initLocalGLObjects(void); virtual void initFBO(void); - void initButtons(void); + //virtual void initBitmapVertex(void); virtual void uploadMainTexture(QImage *p, bool chromakey, bool was_mapped); @@ -194,11 +113,12 @@ class DLL_PREFIX GLDraw_4_5 : public GLDraw_Tmpl virtual void do_set_screen_multiply(float mul); virtual void doSetGridsHorizonal(int lines, bool force); virtual void doSetGridsVertical(int pixels, bool force); - void uploadBitmapTexture(QImage *p); // Note: Mapping vram from draw_thread does'nt work well. // This feature might be disable. 20180728 K.Ohta. void get_screen_geometry(int *w, int *h); + bool copy_screen_buffer(scrntype_t* target,int w, int h, int stride); + scrntype_t *get_screen_buffer(int y); bool is_ready_to_map_vram_texture(void); bool map_vram_texture(void); @@ -215,15 +135,11 @@ class DLL_PREFIX GLDraw_4_5 : public GLDraw_Tmpl } public slots: - void updateBitmap(QImage *); - void uploadIconTexture(QPixmap *p, int icon_type, int localnum); void setBrightness(GLfloat r, GLfloat g, GLfloat b); void do_set_texture_size(QImage *p, int w, int h); void do_set_horiz_lines(int lines); virtual void paintGL(void); virtual void resizeGL(int width, int height); - void do_set_display_osd(bool onoff); - void do_display_osd_leds(int lednum, bool onoff); }; QT_END_NAMESPACE diff --git a/source/src/qt/gui/gl4_5/tmp_vertex_shader.glsl b/source/src/qt/gui/gl4_5/tmp_vertex_shader.glsl deleted file mode 100644 index 70bd7bfab..000000000 --- a/source/src/qt/gui/gl4_5/tmp_vertex_shader.glsl +++ /dev/null @@ -1,13 +0,0 @@ -in vec3 vertex; -in vec2 texcoord; -out vec2 v_texcoord; - -void main () -{ - vec4 tmpvar_1; - tmpvar_1.w = 1.0; - tmpvar_1.xyz = vertex; - gl_Position = tmpvar_1; - v_texcoord = texcoord; -} - diff --git a/source/src/qt/gui/gl4_5/vertex_shader.glsl b/source/src/qt/gui/gl4_5/vertex_shader.glsl deleted file mode 100644 index 50121bda5..000000000 --- a/source/src/qt/gui/gl4_5/vertex_shader.glsl +++ /dev/null @@ -1,13 +0,0 @@ -//precision mediump float; -in mediump vec3 vertex; -in mediump vec2 texcoord; -out mediump vec2 v_texcoord; -uniform mat2 rotate_mat; -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - gl_Position = vec4(xy, vertex.z, 1.0); - v_texcoord = texcoord; -} - diff --git a/source/src/qt/gui/gles2/chromakey_fragment_shader.glsl b/source/src/qt/gui/gles2/chromakey_fragment_shader.glsl deleted file mode 100644 index 4f45cf11f..000000000 --- a/source/src/qt/gui/gles2/chromakey_fragment_shader.glsl +++ /dev/null @@ -1,49 +0,0 @@ -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif -#ifdef HAS_FRAGMENT_HIGH_PRECISION -#extension GL_OES_fragment_precision_high : enable -precision highp float; -#else -precision mediump float; -#endif - -#if __VERSION__ >= 300 -in mediump vec2 v_texcoord; -out vec4 opixel; -#else -varying mediump vec2 v_texcoord; -#endif - -uniform vec4 color; -uniform vec3 chromakey; -uniform bool do_chromakey; -uniform bool swap_byteorder; -uniform sampler2D a_texture; -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - - pixel_r_1 = texture2D(a_texture, v_texcoord); - - if(do_chromakey) { - if(pixel_r_1.rgb != chromakey.rgb) { - pixel_r_1 = pixel_r_1 * color; - pixel = vec4(pixel_r_1.rgb, 1.0); - gl_FragColor = pixel; - } else { - pixel = vec4(0.0); - //discard; - } - } else { - pixel_r_1 = pixel_r_1 * color; - pixel = vec4(pixel_r_1.rgb, 1.0); - gl_FragColor = pixel; - } -} - diff --git a/source/src/qt/gui/gles2/chromakey_fragment_shader2.glsl b/source/src/qt/gui/gles2/chromakey_fragment_shader2.glsl deleted file mode 100644 index 001c8d5cb..000000000 --- a/source/src/qt/gui/gles2/chromakey_fragment_shader2.glsl +++ /dev/null @@ -1,44 +0,0 @@ -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif -#ifdef HAS_FRAGMENT_HIGH_PRECISION -#extension GL_OES_fragment_precision_high : enable -precision highp float; -#else -precision mediump float; -#endif - -#if __VERSION__ >= 300 -in vec2 v_texcoord; -out vec4 opixel; -#else -varying vec2 v_texcoord; -#endif - -uniform vec4 color; -uniform vec3 chromakey; -uniform sampler2D a_texture; - -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - - pixel_r_1 = texture2D(a_texture, v_texcoord); -//#ifdef HOST_ENDIAN_IS_LITTLE -// pixel_r_1.rgb = pixel_r_1.bgr; -//#endif - bvec3 _match; - _match = equal(pixel_r_1.rgb, chromakey.rgb); - pixel = (all(_match) == true) ? vec4(0.0, 0.0, 0.0, 0.0) : vec4(pixel_r_1.rgb, 1.0); -#if __VERSION__ >= 300 - opixel = pixel; -#else - gl_FragColor = pixel; -#endif -} - diff --git a/source/src/qt/gui/gles2/fragment_shader.glsl b/source/src/qt/gui/gles2/fragment_shader.glsl deleted file mode 100644 index b82cc56a8..000000000 --- a/source/src/qt/gui/gles2/fragment_shader.glsl +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif - -precision mediump float; - -#if __VERSION__ >= 300 -in vec2 v_texcoord; -out vec4 opixel; -#else -varying mediump vec2 v_texcoord; -#endif - -#if __VERSION__ >= 300 -uniform sampler2D a_texture; -#else -uniform sampler2D a_texture; -#endif - -void main () -{ -#if __VERSION__ >= 300 - vec4 pixel = texture(a_texture, v_texcoord); -#else - vec4 pixel = texture2D(a_texture, v_texcoord); -#endif -//#ifdef HOST_ENDIAN_IS_LITTLE -// pixel.rgb = pixel.bgr; -//#endif -#if __VERSION__ >= 300 - opixel = pixel; -#else - gl_FragColor = pixel; -#endif -} diff --git a/source/src/qt/gui/gles2/grids_fragment_shader.glsl b/source/src/qt/gui/gles2/grids_fragment_shader.glsl deleted file mode 100644 index 7a471d073..000000000 --- a/source/src/qt/gui/gles2/grids_fragment_shader.glsl +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif -#ifdef HAS_FRAGMENT_HIGH_PRECISION -#extension GL_OES_fragment_precision_high : enable -precision highp float; -#else -precision mediump float; -#endif -#if __VERSION__ >= 300 -out mediump vec4 opixel; -#endif -uniform vec4 color; -void main () -{ -#if __VERSION__ >= 300 - opixel = color; -#else - gl_FragColor = color; -#endif -} - diff --git a/source/src/qt/gui/gles2/grids_vertex_shader.glsl b/source/src/qt/gui/gles2/grids_vertex_shader.glsl deleted file mode 100644 index ca62ef9c4..000000000 --- a/source/src/qt/gui/gles2/grids_vertex_shader.glsl +++ /dev/null @@ -1,16 +0,0 @@ -#if __VERSION__ >= 300 -in mediump vec3 vertex; -#else -attribute mediump vec3 vertex; -#endif - -uniform mat2 rotate_mat; - -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - - gl_Position = vec4(xy, vertex.z, 1.0); -} - diff --git a/source/src/qt/gui/gles2/grids_vertex_shader_fixed.glsl b/source/src/qt/gui/gles2/grids_vertex_shader_fixed.glsl deleted file mode 100644 index a64a3f94b..000000000 --- a/source/src/qt/gui/gles2/grids_vertex_shader_fixed.glsl +++ /dev/null @@ -1,9 +0,0 @@ -attribute mediump vec3 vertex; -void main () -{ - mediump vec4 tmpvar_1; - tmpvar_1.w = 1.0; - tmpvar_1.xyz = vertex; - gl_Position = tmpvar_1; -} - diff --git a/source/src/qt/gui/gles2/icon_fragment_shader.glsl b/source/src/qt/gui/gles2/icon_fragment_shader.glsl deleted file mode 100644 index 4ef3804ef..000000000 --- a/source/src/qt/gui/gles2/icon_fragment_shader.glsl +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif -#ifdef HAS_FRAGMENT_HIGH_PRECISION -#extension GL_OES_fragment_precision_high : enable -precision highp float; -#else -precision mediump float; -#endif - -#if __VERSION__ >= 300 -in vec2 v_texcoord; -out mediump vec4 opixel; -#else -varying vec2 v_texcoord; -#endif -uniform vec4 color; -uniform vec3 chromakey; -uniform bool do_chromakey; -uniform sampler2D a_texture; -void main () -{ - vec4 pixel_r_1; - vec4 pixel; - float alpha; - pixel_r_1 = texture2D(a_texture, v_texcoord); - //alpha = pixel_r_1.a * color.a; - - pixel_r_1 = pixel_r_1 * color; - pixel = pixel_r_1 * color; //;vec4(pixel_r_1.rgb, alpha); -#if __VERSION__ >= 300 - opixel = pixel; -#else - gl_FragColor = pixel; -#endif -} - diff --git a/source/src/qt/gui/gles2/led_fragment_shader.glsl b/source/src/qt/gui/gles2/led_fragment_shader.glsl deleted file mode 100644 index e389b99a3..000000000 --- a/source/src/qt/gui/gles2/led_fragment_shader.glsl +++ /dev/null @@ -1,28 +0,0 @@ -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif -#ifdef HAS_FRAGMENT_HIGH_PRECISION -#extension GL_OES_fragment_precision_high : enable -precision highp float; -#else -precision mediump float; -#endif -#if __VERSION__ >= 300 -out mediump vec4 opixel; -#endif -uniform vec4 color; -void main () -{ -#if __VERSION__ >= 300 - opixel = color; -#else - gl_FragColor = color; -#endif - -} - - diff --git a/source/src/qt/gui/gles2/led_vertex_shader.glsl b/source/src/qt/gui/gles2/led_vertex_shader.glsl deleted file mode 100644 index 30946c033..000000000 --- a/source/src/qt/gui/gles2/led_vertex_shader.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#if __VERSION__ >= 300 -in vec3 vertex; -#else -attribute vec3 vertex; -#endif -void main () -{ - vec4 tmpvar_1; - tmpvar_1.w = 1.0; - tmpvar_1.xyz = vertex.xyz; - gl_Position = tmpvar_1; -} - diff --git a/source/src/qt/gui/gles2/normal_fragment_shader.glsl b/source/src/qt/gui/gles2/normal_fragment_shader.glsl deleted file mode 100644 index 26854eaa1..000000000 --- a/source/src/qt/gui/gles2/normal_fragment_shader.glsl +++ /dev/null @@ -1,19 +0,0 @@ -#if __VERSION__ >= 300 -in mediump vec2 v_texcoord; -uniform sampler2D a_texture; -uniform mediump vec4 color; -out mediump vec4 opixel; -#else -varying mediump vec2 v_texcoord; -uniform sampler2D a_texture; -uniform mediump vec4 color; -#endif -void main () -{ -#if __VERSION__ >= 300 - opixel = (texture2D (a_texture, v_texcoord) * color); -#else - gl_FragColor = (texture2D (a_texture, v_texcoord) * color); -#endif -} - diff --git a/source/src/qt/gui/gles2/ntsc_pass1.glsl b/source/src/qt/gui/gles2/ntsc_pass1.glsl deleted file mode 100644 index ebbb95c80..000000000 --- a/source/src/qt/gui/gles2/ntsc_pass1.glsl +++ /dev/null @@ -1,144 +0,0 @@ -// NTSC Shader - written by Hans-Kristian Arntzen -// License: GPLv3 -// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif -//#ifdef HAS_FRAGMENT_HIGH_PRECISION -//#extension GL_OES_fragment_precision_high : enable -//precision highp float; -//#else -precision mediump float; -//#endif - -#if __VERSION__ >= 300 -in mediump vec2 v_texcoord; -out vec4 opixel; -#else -varying mediump vec2 v_texcoord; -#endif -uniform sampler2D a_texture; -uniform vec4 source_size; -uniform vec4 target_size; -uniform float phase; - -// uniforms added for compatibility -//vec3 col; -//float mod_phase; -//float chroma_phase; - -#define THREE_PHASE //options here include THREE_PHASE, TWO_PHASE or OLD_THREE_PHASE -#define COMPOSITE - -// #include "ntsc-param.inc" // -#define PI 3.14159265 - -#if defined(TWO_PHASE) -#define CHROMA_MOD_FREQ (4.0 * PI / 15.0) -#elif defined(THREE_PHASE) -#define CHROMA_MOD_FREQ (PI / 3.0) -#endif - -#if defined(COMPOSITE) -#define SATURATION 1.1 -#define BRIGHTNESS 1.0 -#define ARTIFACTING 1.3 -#define FRINGING 1.2 -#elif defined(SVIDEO) -#define SATURATION 1.0 -#define BRIGHTNESS 1.0 -#define ARTIFACTING 0.0 -#define FRINGING 0.0 -#endif - -#if defined(COMPOSITE) || defined(SVIDEO) -mat3 mix_mat = mat3( - BRIGHTNESS, FRINGING, FRINGING, - ARTIFACTING, 2.0 * SATURATION, 0.0, - ARTIFACTING, 0.0, 2.0 * SATURATION -); -#endif -// END "ntsc-param.inc" // - -// moved from vertex -#define pix_no (v_texcoord.xy * source_size.xy * (target_size.xy / source_size.xy)) - -// Change Matrix: [RGB]->[YCbCr] - -mat3 ycbcr_mat = mat3( - 0.29891, -0.16874, 0.50000, - 0.58661, -0.33126, -0.41869, - 0.11448, 0.50000, -0.08131 -); -//vec3 rgb2ycbcr(vec3 col) -//{ -// vec3 ycbcr = col * ycbcr_mat; -// return ycbcr; -//} - -#define rgb2ycbcr(foo) (col.rgb * ycbcr_mat) - -mat3 ycbcr2rgb_mat = mat3( - 1.0, 1.0, 1.0, - 0.0, -0.34414 , 1.77200, - 1.40200, -0.71414, 0.0 - ); - -vec3 ycbcr2rgb(vec3 ycbcr) -{ - //vec3 ra = ycbcr * vec3(1.0, 0.7, 1.0); - return (ycbcr * ycbcr2rgb_mat); -} - -void main() { - // #include "ntsc-pass1-encode-demodulate.inc" // - - vec3 col = texture2D(a_texture, v_texcoord).rgb; - vec3 ycbcr; -#ifdef HOST_ENDIAN_IS_LITTLE - col.rgb = col.bgr; -#endif - ycbcr = rgb2ycbcr(col); -// -// From https://ja.wikipedia.org/wiki/YUV#RGB%E3%81%8B%E3%82%89%E3%81%AE%E5%A4%89%E6%8F%9B -// ITU-R BT.601 / ITU-R BT.709 (1250/50/2:1) -// Y = 0.299 * R + 0.587 * G + 0.114 * B -// Cb = -0.168736 * R - 0.331264 * G + 0.5 * B -// Cr = 0.5 * R - 0.418688 * G - 0.081312 * B - -#if defined(TWO_PHASE) - float chroma_phase = PI * (mod(pix_no.y, 2.0) + phase); -#elif defined(THREE_PHASE) - float chroma_phase = 0.6667 * PI * (mod(pix_no.y, 3.0) + phase); -#endif - - float mod_phase = chroma_phase + pix_no.x * CHROMA_MOD_FREQ; - - float i_mod = cos(mod_phase); - float q_mod = sin(mod_phase); - ycbcr *= vec3(1.0, i_mod, q_mod); // Modulate - ycbcr *= mix_mat; // Cross-talk - ycbcr *= vec3(1.0, i_mod, q_mod); // Demodulate - - // yMax = (0.299+0.587+0.114) * (+-1.0) * (BRIGHTNESS + ARTIFACTING + ARTIFACTING) * (+-1.0) - // CbMax = (-0.168736 -0.331264 + 0.5) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // CrMax = (0.5 - 0.418688 - 0.081312) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // -> y = 0 to +3.6 - // Cb = 0 to +1.7 - // Cr = 0 to +1.7 -#ifndef HAS_FLOAT_TEXTURE - ycbcr = ycbcr * vec3(0.277778 ,0.588235, 0.588235); -#endif - // Normalise - vec4 outvar = vec4(ycbcr, 1.0); -#if __VERSION__ >= 300 - opixel = outvar; -#else - gl_FragColor = outvar; -#endif -// END "ntsc-pass1-encode-demodulate.inc" // -} \ No newline at end of file diff --git a/source/src/qt/gui/gles2/ntsc_pass2.glsl b/source/src/qt/gui/gles2/ntsc_pass2.glsl deleted file mode 100644 index d285b2cea..000000000 --- a/source/src/qt/gui/gles2/ntsc_pass2.glsl +++ /dev/null @@ -1,186 +0,0 @@ -// NTSC Shader - written by Hans-Kristian Arntzen -// License: GPLv3 -// pulled from git://github.com/libretro/common-shaders.git on 01/30/2014 -#ifdef HAS_FLOAT_TEXTURE -#ifdef HAS_HALF_FLOAT_TEXTURE -#extension GL_OES_texture_half_float : enable -#else -#extension GL_OES_texture_float : enable -#endif -#endif - -#ifdef HAS_FRAGMENT_HIGH_PRECISION -#extension GL_OES_fragment_precision_high : enable -//precision highp float; -//#else -//precision mediump float; -#endif -precision mediump float; - -#if __VERSION__ >= 300 -in mediump vec2 v_texcoord; -out vec4 opixel; -#else -varying mediump vec2 v_texcoord; -#endif - -uniform sampler2D a_texture; -uniform vec4 source_size; -uniform vec4 target_size; - -#define TAPS 24 - -#if __VERSION__ >= 300 - // THREE_PHASE -const float luma_filter[24 + 1] = float[24 + 1]( - -0.000012020, - -0.000022146, - -0.000013155, - -0.000012020, - -0.000049979, - -0.000113940, - -0.000122150, - -0.000005612, - 0.000170516, - 0.000237199, - 0.000169640, - 0.000285688, - 0.000984574, - 0.002018683, - 0.002002275, - -0.000909882, - -0.007049081, - -0.013222860, - -0.012606931, - 0.002460860, - 0.035868225, - 0.084016453, - 0.135563500, - 0.175261268, - 0.190176552 - ); -const float chroma_filter[24 + 1] = float [24 + 1]( - -0.000118847, - -0.000271306, - -0.000502642, - -0.000930833, - -0.001451013, - -0.002064744, - -0.002700432, - -0.003241276, - -0.003524948, - -0.003350284, - -0.002491729, - -0.000721149, - 0.002164659, - 0.006313635, - 0.011789103, - 0.018545660, - 0.026414396, - 0.035100710, - 0.044196567, - 0.053207202, - 0.061590275, - 0.068803602, - 0.074356193, - 0.077856564, - 0.079052396 - ); -// END "ntsc-decode-filter-3phase.inc" // - -#else -uniform float luma_filter[24 + 1]; -uniform float chroma_filter[24 + 1]; -#endif - -#define GAMMA_CORRECTION //comment to disable gamma correction, usually because higan's gamma correction is enabled or you have another shader already doing it -#ifndef HAS_FLOAT_TEXTURE -#define CRT_GAMMA 3.3 -#else -#define CRT_GAMMA 2.5 -#endif -#define DISPLAY_GAMMA 2.1 - - -// #include ntsc-rgbyuv.inc // - - -mat3 ycbcr2rgb_mat = mat3( - 1.0, 1.0, 1.0, - 0.0, -0.34414 , 1.77200, - 1.40200, -0.71414, 0.0 - ); - -//vec3 ycbcr2rgb(vec3 ycbcr) -//{ -// //vec3 ra = ycbcr * vec3(1.0, 0.7, 1.0); -// return (ycbcr * ycbcr2rgb_mat); -//} -#define ycbcr2rgb(foo) (foo.rgb * ycbcr2rgb_mat) - -// END ntsc-rgbyuv.inc // - -// fixCoord moved from vertex -#define fixCoord (v_texcoord - (vec2(0.5) * delta)) // Compensate for decimate-by-2. - -void main() { -// #include "ntsc-pass2-decode.inc" // - float one_x = 1.0 / source_size.x; - vec3 signal = vec3(0.0); - int i,j; - int ibegin = 1; - float pos_offset = float(TAPS - ibegin) * one_x; - vec3 sums_p = vec3(0.0, 0.0, 0.0); - - vec2 fix_coord = v_texcoord - vec2(0.5 * one_x, 0.0); - vec2 delta = vec2(one_x, 0); - vec3 pix_p, pix_n; - vec3 tmpv; - vec2 addr_p = fix_coord + vec2(pos_offset, 0); - vec2 addr_n = fix_coord - vec2(pos_offset, 0); - - for(int ii = 1; ii < TAPS; ii++) { - pix_p = texture2D(a_texture, addr_p).xyz; - pix_n = texture2D(a_texture, addr_n).xyz; -#ifndef HAS_FLOAT_TEXTURE - pix_p = pix_p * vec3(3.6, 1.7, 1.7); - pix_n = pix_n * vec3(3.6, 1.7, 1.7); -#endif - pix_p = (pix_n + pix_p) * vec3(luma_filter[ii], chroma_filter[ii], chroma_filter[ii]); - signal = signal + pix_p; - addr_p = addr_p - delta; - addr_n = addr_n + delta; - } - vec3 texvar = texture2D(a_texture, fix_coord).xyz; - // yMax = (0.299+0.587+0.114) * (+-1.0) * (BRIGHTNESS + ARTIFACTING + ARTIFACTING) * (+-1.0) - // CbMax = (-0.168736 -0.331264 + 0.5) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // CrMax = (0.5 - 0.418688 - 0.081312) * (+-1.0) * (FRINGING + 2*SATURATION) * (+-1.0) - // -> y = 0 to +3.6 - // Cb = 0 to +1.7 - // Cr = 0 to +1.7 -#ifndef HAS_FLOAT_TEXTURE - texvar = texvar * vec3(3.6, 1.7, 1.7); -#endif - signal += texvar * vec3(luma_filter[TAPS], chroma_filter[TAPS], chroma_filter[TAPS]); -// END "ntsc-pass2-decode.inc" // - - vec3 rgb = ycbcr2rgb(signal); -#ifndef HAS_FLOAT_TEXTURE - rgb = rgb * vec3(0.67, 1.0, 1.0); -#endif - -#ifdef GAMMA_CORRECTION - vec3 gamma = vec3(CRT_GAMMA / DISPLAY_GAMMA); - rgb = pow(abs(rgb), gamma.rgb); -#endif - vec4 pixel = vec4(rgb, 1.0); -#ifdef HOST_ENDIAN_IS_LITTLE - pixel.rgba = pixel.bgra; -#endif - -#if __VERSION__ >= 300 - opixel = pixel; -#else - gl_FragColor = pixel; -#endif -} \ No newline at end of file diff --git a/source/src/qt/gui/gles2/qt_glutil_gles_2.cpp b/source/src/qt/gui/gles2/qt_glutil_gles_2.cpp index f3f08d711..8e54ffe2b 100644 --- a/source/src/qt/gui/gles2/qt_glutil_gles_2.cpp +++ b/source/src/qt/gui/gles2/qt_glutil_gles_2.cpp @@ -40,28 +40,8 @@ //extern USING_FLAGS *using_flags; -GLDraw_ES_2::GLDraw_ES_2(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu) : GLDraw_Tmpl(parent, p, logger, emu) +GLDraw_ES_2::GLDraw_ES_2(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu) : GLDraw_Tmpl(parent, p, logger, emu) { - uTmpTextureID = 0; - - grids_shader = NULL; - - main_pass = NULL; - std_pass = NULL; - ntsc_pass1 = NULL; - ntsc_pass2 = NULL; - led_pass = NULL; - for(int i = 0; i < 32; i++) { - led_pass_vao[i] = NULL; - led_pass_vbuffer[i] = NULL; - osd_pass_vao[i] = NULL; - osd_pass_vbuffer[i] = NULL; - } - grids_horizonal_buffer = NULL; - grids_horizonal_vertex = NULL; - - grids_vertical_buffer = NULL; - grids_vertical_vertex = NULL; ringing_phase = 0.0f; #if defined(__LITTLE_ENDIAN__) swap_byteorder = true; @@ -79,13 +59,6 @@ GLDraw_ES_2::~GLDraw_ES_2() if(std_pass != NULL) delete std_pass; if(ntsc_pass1 != NULL) delete ntsc_pass1; if(ntsc_pass2 != NULL) delete ntsc_pass2; - if(led_pass != NULL) delete led_pass; - for(int i = 0; i < 32; i++) { - if(led_pass_vao[i] != NULL) delete led_pass_vao[i]; - if(led_pass_vbuffer[i] != NULL) delete led_pass_vbuffer[i]; - if(osd_pass_vao[i] != NULL) delete osd_pass_vao[i]; - if(osd_pass_vbuffer[i] != NULL) delete osd_pass_vbuffer[i]; - } if(grids_horizonal_buffer != NULL) { if(grids_horizonal_buffer->isCreated()) grids_horizonal_buffer->destroy(); @@ -101,6 +74,27 @@ GLDraw_ES_2::~GLDraw_ES_2() } if(TextureTransferParam != NULL) delete TextureTransferParam; } +void GLDraw_ES_2::epilogueBlending() +{ + extfunc->glDisable(GL_TEXTURE_2D); + extfunc->glDisable(GL_BLEND); +} +void GLDraw_ES_2::prologueBlending() +{ + extfunc->glDisable(GL_TEXTURE_2D); + extfunc->glEnable(GL_BLEND); + extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); +} + +void GLDraw_ES_2::drawPolygon(int vertex_loc, uintptr_t p) +{ + extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), (void *)p); + + extfunc->glEnableVertexAttribArray(vertex_loc); + extfunc->glEnable(GL_VERTEX_ARRAY); + extfunc->glDrawArrays(GL_POLYGON, 0, 4); +} QOpenGLTexture *GLDraw_ES_2::createMainTexture(QImage *img) { @@ -120,35 +114,6 @@ QOpenGLTexture *GLDraw_ES_2::createMainTexture(QImage *img) tx->setWrapMode(QOpenGLTexture::ClampToEdge); return tx; } -void GLDraw_ES_2::initBitmapVertex(void) -{ - if(using_flags->is_use_one_board_computer()) { - vertexBitmap[0].x = -1.0f; - vertexBitmap[0].y = -1.0f; - vertexBitmap[0].z = 0.5f; - vertexBitmap[0].s = 0.0f; - vertexBitmap[0].t = 1.0f; - - vertexBitmap[1].x = +1.0f; - vertexBitmap[1].y = -1.0f; - vertexBitmap[1].z = 0.5f; - vertexBitmap[1].s = 1.0f; - vertexBitmap[1].t = 1.0f; - - vertexBitmap[2].x = +1.0f; - vertexBitmap[2].y = +1.0f; - vertexBitmap[2].z = 0.5f; - vertexBitmap[2].s = 1.0f; - vertexBitmap[2].t = 0.0f; - - vertexBitmap[3].x = -1.0f; - vertexBitmap[3].y = +1.0f; - vertexBitmap[3].z = 0.5f; - vertexBitmap[3].s = 0.0f; - vertexBitmap[3].t = 0.0f; - - } -} void GLDraw_ES_2::initFBO(void) { @@ -207,12 +172,12 @@ void GLDraw_ES_2::initGLObjects() void GLDraw_ES_2::initPackedGLObject(GLScreenPack **p, int _width, int _height, const QString vertex_shader, const QString fragment_shader, - const QString _name, bool req_float, bool req_highp) + const QString _name, bool req_float, bool req_highp, bool req_alpha_channel) { QString s; GLScreenPack *pp; if(p != NULL) { - pp = new GLScreenPack(_width, _height, _name, p_wid, req_float, req_highp); + pp = new GLScreenPack(_width, _height, _name, p_wid, req_float, req_highp, req_alpha_channel); *p = pp; if(pp != NULL) { pp->initialize(_width, _height, vertex_shader, fragment_shader); @@ -332,13 +297,13 @@ void GLDraw_ES_2::initLocalGLObjects(void) if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) { initPackedGLObject(&main_pass, using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2, - ":/gles2/vertex_shader.glsl" , ":/gles2/chromakey_fragment_shader2.glsl", - "Main Shader", false, false); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/chromakey_fragment_shader2.glsl", + "Main Shader", false, false, true); } else { initPackedGLObject(&main_pass, using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2, - ":/gles2/vertex_shader.glsl" , ":/gles2/fragment_shader.glsl", - "Main Shader", false, false); + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/fragment_shader.glsl", + "Main Shader", false, false, true); } if(main_pass != NULL) { setNormalVAO(main_pass->getShader(), main_pass->getVAO(), @@ -348,12 +313,12 @@ void GLDraw_ES_2::initLocalGLObjects(void) #if 0 initPackedGLObject(&std_pass, using_flags->get_screen_width(), using_flags->get_screen_height(), - ":/gles2/vertex_shader.glsl" , ":/gles2/chromakey_fragment_shader.glsl", + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/chromakey_fragment_shader.glsl", "Standard Shader"); #endif initPackedGLObject(&led_pass, 10, 10, - ":/gles2/led_vertex_shader.glsl" , ":/gles2/led_fragment_shader.glsl", + ":/gl/shaders/led_vertex_shader.glsl" , ":/gl/shaders/led_fragment_shader.glsl", "LED Shader", false, false); for(int i = 0; i < 32; i++) { led_pass_vao[i] = new QOpenGLVertexArrayObject; @@ -372,7 +337,7 @@ void GLDraw_ES_2::initLocalGLObjects(void) } initPackedGLObject(&osd_pass, 48.0, 48.0, - ":/gles2/vertex_shader.glsl" , ":/gles2/icon_fragment_shader.glsl", + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/icon_fragment_shader.glsl", "OSD Shader", false, false); for(int i = 0; i < 32; i++) { osd_pass_vao[i] = new QOpenGLVertexArrayObject; @@ -393,11 +358,11 @@ void GLDraw_ES_2::initLocalGLObjects(void) initPackedGLObject(&ntsc_pass1, _width, _height, - ":/gles2/vertex_shader.glsl" , ":/gles2/ntsc_pass1.glsl", + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/ntsc_pass1.glsl", "NTSC Shader Pass1", true, false); initPackedGLObject(&ntsc_pass2, _width / 2, _height, - ":/gles2/vertex_shader.glsl" , ":/gles2/ntsc_pass2.glsl", + ":/gl/shaders/vertex_shader.glsl" , ":/gl/shaders/ntsc_pass2.glsl", "NTSC Shader Pass2", true, false); if(!(((gl_major_version >= 3) && (gl_minor_version >= 1)) || (gl_major_version >= 4))){ int ii; @@ -419,7 +384,7 @@ void GLDraw_ES_2::initLocalGLObjects(void) initBitmapVertex(); initPackedGLObject(&bitmap_block, _width * 2, _height * 2, - ":/gles2/vertex_shader.glsl", ":/gles2/normal_fragment_shader.glsl", + ":/gl/shaders/vertex_shader.glsl", ":/gl/shaders/normal_fragment_shader.glsl", "Background Bitmap Shader", false, false); if(bitmap_block != NULL) { setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(), @@ -428,7 +393,7 @@ void GLDraw_ES_2::initLocalGLObjects(void) } } - initGridShaders(":/gles2/grids_vertex_shader_fixed.glsl", ":/gles2/grids_vertex_shader.glsl", ":/gles2/grids_fragment_shader.glsl"); + initGridShaders(":/gl/shaders/grids_vertex_shader_fixed.glsl", ":/gl/shaders/grids_vertex_shader.glsl", ":/gl/shaders/grids_fragment_shader.glsl"); initGridVertexObject(&grids_horizonal_buffer, &grids_horizonal_vertex, using_flags->get_real_screen_height() + 3); doSetGridsHorizonal(using_flags->get_real_screen_height(), true); @@ -510,7 +475,7 @@ void GLDraw_ES_2::drawGridsMain(QOpenGLShaderProgram *prg, prg->enableAttributeArray("vertex"); int vertex_loc = prg->attributeLocation("vertex"); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0); extfunc->glEnableVertexAttribArray(vertex_loc); @@ -615,17 +580,17 @@ void GLDraw_ES_2::renderToTmpFrameBuffer_nPass(GLuint src_texture, { ii = shader->uniformLocation("source_size"); if(ii >= 0) { - QVector4D source_size = QVector4D((float)src_w, (float)src_h, 0, 0); + QVector2D source_size = QVector2D((float)src_w, (float)src_h); shader->setUniformValue(ii, source_size); } ii = shader->uniformLocation("target_size"); if(ii >= 0) { - QVector4D target_size = QVector4D((float)dst_w, (float)dst_h, 0, 0); + QVector2D target_size = QVector2D((float)dst_w, (float)dst_h); shader->setUniformValue(ii, target_size); } ii = shader->uniformLocation("phase"); if(ii >= 0) { - ringing_phase = ringing_phase + 0.093; + ringing_phase = ringing_phase + 0.063; if(ringing_phase > 1.0) ringing_phase = ringing_phase - 1.0; shader->setUniformValue(ii, ringing_phase); } @@ -731,15 +696,15 @@ void GLDraw_ES_2::uploadMainTexture(QImage *p, bool use_chromakey, bool was_mapp screen_texture_width, screen_texture_height, ntsc_pass1, - ntsc_pass1->getViewportWidth(), - ntsc_pass1->getViewportHeight()); + ntsc_pass1->getTextureWidth(), + ntsc_pass1->getTextureHeight()); renderToTmpFrameBuffer_nPass(ntsc_pass1->getTexture(), - ntsc_pass1->getViewportWidth(), - ntsc_pass1->getViewportHeight(), + ntsc_pass1->getTextureWidth(), + ntsc_pass1->getTextureHeight(), ntsc_pass2, - ntsc_pass2->getViewportWidth(), - ntsc_pass2->getViewportHeight()); + ntsc_pass2->getTextureWidth(), + ntsc_pass2->getTextureHeight()); uTmpTextureID = ntsc_pass2->getTexture(); } else #endif @@ -793,7 +758,7 @@ void GLDraw_ES_2::drawMain(QOpenGLShaderProgram *prg, vp->bind(); bp->bind(); prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); QMatrix4x4 ortho; ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); @@ -848,6 +813,11 @@ void GLDraw_ES_2::drawMain(QOpenGLShaderProgram *prg, //prg->setUniformValue("rotate", GL_FALSE); //} + if(!(using_flags->is_use_one_board_computer())) { + prg->setUniformValue("distortion_v", 0.08f, 0.08f); // ToDo: Change val + } + prg->setUniformValue("luminance", 0.9f); // ToDo: Change val + prg->setUniformValue("lum_offset", 0.08f); // ToDo: Change val if(do_chromakey) { ii = prg->uniformLocation("chromakey"); if(ii >= 0) { @@ -886,7 +856,7 @@ void GLDraw_ES_2::drawMain(QOpenGLShaderProgram *prg, vp->bind(); bp->bind(); prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); QMatrix4x4 ortho; ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); @@ -974,7 +944,7 @@ void GLDraw_ES_2::drawButtonsMain(int num, bool f_smoosing) prg->bind(); QMatrix4x4 ortho; ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); extfunc->glActiveTexture(GL_TEXTURE0); extfunc->glBindTexture(GL_TEXTURE_2D, texid); @@ -1055,122 +1025,6 @@ void GLDraw_ES_2::drawBitmapTexture(void) } } -void GLDraw_ES_2::drawLedMain(GLScreenPack *obj, int num, QVector4D color) -{ - QOpenGLShaderProgram *prg = obj->getShader(); - QOpenGLVertexArrayObject *vp = led_pass_vao[num]; - QOpenGLBuffer *bp = led_pass_vbuffer[num]; - int ii; - - { - extfunc->glEnable(GL_BLEND); - extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - vp->bind(); - bp->bind(); - prg->bind(); - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); - //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); - ii = prg->uniformLocation("color"); - if(ii >= 0) { - prg->setUniformValue(ii, color); - } - - prg->enableAttributeArray("vertex"); - int vertex_loc = prg->attributeLocation("vertex"); - prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t)); - extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0); - - extfunc->glEnableVertexAttribArray(vertex_loc); - extfunc->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - bp->release(); - vp->release(); - - prg->release(); - extfunc->glDisable(GL_BLEND); - } - -} - - -void GLDraw_ES_2::drawOsdLeds() -{ - QVector4D color_on; - QVector4D color_off; - uint32_t bit = 0x00000001; - if(osd_onoff) { - color_on = QVector4D(0.95, 0.0, 0.05, 1.0); - color_off = QVector4D(0.05,0.05, 0.05, 0.10); - } else { - color_on = QVector4D(0.00,0.00, 0.00, 0.0); - color_off = QVector4D(0.00,0.00, 0.00, 0.0); - } - if(osd_onoff) { - //if(osd_led_status_bak != osd_led_status) { - for(int i = 0; i < osd_led_bit_width; i++) { - if((bit & osd_led_status) == (bit & osd_led_status_bak)) { - bit <<= 1; - continue; - } - drawLedMain(led_pass, i, - ((osd_led_status & bit) != 0) ? color_on : color_off); - bit <<= 1; - } - osd_led_status_bak = osd_led_status; - //} - } -} - -void GLDraw_ES_2::drawOsdIcons() -{ - QVector4D color_on; - QVector4D color_off; - uint32_t bit = 0x00000001; - if(osd_onoff) { - color_on = QVector4D(1.0, 1.0, 1.0, 0.8); - color_off = QVector4D(1.0, 1.0, 1.0, 0.00); - } else { - color_on = QVector4D(0.00,0.00, 0.00, 0.0); - color_off = QVector4D(0.00,0.00, 0.00, 0.0); - } - if(osd_onoff) { - int major, minor; - //if(osd_led_status_bak != osd_led_status) { - for(int i = 0; i < osd_led_bit_width; i++) { - if((bit & osd_led_status) == (bit & osd_led_status_bak)) { - if((bit & osd_led_status) == 0) { - bit <<= 1; - continue; - } - } - if((i >= 2) && (i < 10)) { // FD - major = 2; - minor = i - 2; - } else if((i >= 10) && (i < 12)) { // QD - major = 3; - minor = i - 10; - } else if((i >= 12) && (i < 14)) { // CMT(R) - major = 4; - minor = i - 12; - } else if((i >= 14) && (i < 16)) { // CMT(W) - major = 5; - minor = i - 14; - } else { - major = 0; - minor = 0; - } - if(major != 0) { - drawMain(osd_pass->getShader(), osd_pass_vao[i], osd_pass_vbuffer[i], - icon_texid[major][minor]->textureId(), - ((osd_led_status & bit) != 0) ? color_on : color_off, - false, false, QVector3D(0.0, 0.0, 0.0)); - } - bit <<= 1; - } - osd_led_status_bak = osd_led_status; - //} - } -} - void GLDraw_ES_2::paintGL(void) { //p_wid->makeCurrent(); @@ -1180,7 +1034,7 @@ void GLDraw_ES_2::paintGL(void) crt_flag = false; } redraw_required = false; - extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); + extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -1206,7 +1060,7 @@ void GLDraw_ES_2::paintGL(void) } extfunc->glFlush(); // } else { -// extfunc->glViewport(0, 0, p_wid->width(), p_wid->height()); +// extfunc->glViewport(0, 0, p_wid->width() * get_screen_scaling_factor(), p_wid->height() * get_screen_scaling_factor()); /// extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); // //drawOsdLeds(); // extfunc->glClear(GL_DEPTH_BUFFER_BIT); @@ -1392,7 +1246,7 @@ void GLDraw_ES_2::do_set_texture_size(QImage *p, int w, int h) iw = (float)using_flags->get_real_screen_width(); ih = (float)using_flags->get_real_screen_height(); } - //printf("%dx%d -> %fx%f\n", w, h, iw, ih); +// printf("%dx%d -> %fx%f\n", w, h, iw, ih); if(p_wid != NULL) { screen_texture_width = w; screen_texture_height = h; @@ -1440,14 +1294,14 @@ void GLDraw_ES_2::do_set_texture_size(QImage *p, int w, int h) vertexFormat[3].z = -0.9f; vertexFormat[0].s = 0.0f; - //vertexFormat[0].t = (float)h / ih; - //vertexFormat[1].s = (float)w / iw; - //vertexFormat[1].t = (float)h / ih; - //vertexFormat[2].s = (float)w / iw; - vertexFormat[0].t = 1.0f; - vertexFormat[1].s = 1.0f; - vertexFormat[1].t = 1.0f; - vertexFormat[2].s = 1.0f; + vertexFormat[0].t = (float)h / ih; + vertexFormat[1].s = (float)w / iw; + vertexFormat[1].t = (float)h / ih; + vertexFormat[2].s = (float)w / iw; + //vertexFormat[0].t = 1.0f; + //vertexFormat[1].s = 1.0f; + //vertexFormat[1].t = 1.0f; + //vertexFormat[2].s = 1.0f; vertexFormat[2].t = 0.0f; vertexFormat[3].s = 0.0f; vertexFormat[3].t = 0.0f; @@ -1487,7 +1341,6 @@ void GLDraw_ES_2::resizeGL_Screen(void) void GLDraw_ES_2::resizeGL(int width, int height) { //int side = qMin(width, height); - p_wid->makeCurrent(); extfunc->glViewport(0, 0, width, height); //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0); crt_flag = true; @@ -1507,204 +1360,6 @@ void GLDraw_ES_2::resizeGL(int width, int height) if(using_flags->get_max_button() > 0) { updateButtonTexture(); } - p_wid->doneCurrent(); -} - -void GLDraw_ES_2::initButtons(void) -{ - button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); - QOpenGLContext *context = QOpenGLContext::currentContext(); - QPair _version = QOpenGLVersionProfile(context->format()).version(); - QString versionext = QString::fromUtf8(""); - if(((_version.first == 3) && (_version.second >= 1)) || (_version.first >= 4)){ - versionext = QString::fromUtf8("#version 310 es \n"); - } /* else if((_version.first == 3)) { - _ext = _ext + QString::fromUtf8("#version 300 es \n"); - } */ else { - versionext = QString::fromUtf8("#version 100 \n"); - } - - if(vm_buttons_d != NULL) { - button_shader = new QOpenGLShaderProgram(p_wid); - if(button_shader != NULL) { - bool f = false; - QFile vertex_src(QString::fromUtf8(":/gles2/vertex_shader.glsl")); - if (vertex_src.open(QIODevice::ReadOnly | QIODevice::Text)) { - QString srcs = versionext; - srcs = srcs + QString::fromUtf8(vertex_src.readAll()); - f = button_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, srcs); - vertex_src.close(); - } else { - return; - } - QFile fragment_src(QString::fromUtf8(":/gles2/normal_fragment_shader.glsl")); - if (fragment_src.open(QIODevice::ReadOnly | QIODevice::Text)) { - QString srcs = versionext; - srcs = srcs + QString::fromUtf8(fragment_src.readAll()); - f &= button_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, srcs); - fragment_src.close(); - } else { - return; - } - if(!f) return; - button_shader->link(); - } - - int ip = using_flags->get_max_button(); - if(ip > 0) { - for(int num = 0; num < ip; num++) { - QString tmps; - tmps = QString::asprintf(":/button%02d.png", num); - QImageReader *reader = new QImageReader(tmps); - QImage *result = new QImage(reader->read()); - QImage pic; - if(result != NULL) { - if(!result->isNull()) { - pic = result->convertToFormat(QImage::Format_ARGB32); - } else { - pic = QImage(10, 10, QImage::Format_RGBA8888); - pic.fill(QColor(0,0,0,0)); - } - delete result; - }else { - pic = QImage(10, 10, QImage::Format_RGBA8888); - pic.fill(QColor(0,0,0,0)); - } - ButtonImages.push_back(pic); - } - } - vertexButtons = new QVector; - for(int i = 0; i < using_flags->get_max_button(); i++) { - buffer_button_vertex[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); - buffer_button_vertex[i]->create(); - fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width(); - fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height(); - fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width(); - fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height(); - - vertex_button[i] = new QOpenGLVertexArrayObject; - if(vertex_button[i] != NULL) { - if(vertex_button[i]->create()) { - VertexTexCoord_t vt[4]; - - vt[0].x = fButtonX[i]; - vt[0].y = fButtonY[i]; - vt[0].z = -0.5f; - vt[0].s = 0.0f; - vt[0].t = 0.0f; - - vt[1].x = fButtonX[i] + fButtonWidth[i]; - vt[1].y = fButtonY[i]; - vt[1].z = -0.5f; - vt[1].s = 1.0f; - vt[1].t = 0.0f; - - vt[2].x = fButtonX[i] + fButtonWidth[i]; - vt[2].y = fButtonY[i] - fButtonHeight[i]; - vt[2].z = -0.5f; - vt[2].s = 1.0f; - vt[2].t = 1.0f; - - vt[3].x = fButtonX[i]; - vt[3].y = fButtonY[i] - fButtonHeight[i]; - vt[3].z = -0.5f; - vt[3].s = 0.0f; - vt[3].t = 1.0f; - - vertexButtons->append(vt[0]); - vertexButtons->append(vt[1]); - vertexButtons->append(vt[2]); - vertexButtons->append(vt[3]); - vertex_button[i]->bind(); - buffer_button_vertex[i]->bind(); - buffer_button_vertex[i]->allocate(4 * sizeof(VertexTexCoord_t)); - - buffer_button_vertex[i]->setUsagePattern(QOpenGLBuffer::StaticDraw); - buffer_button_vertex[i]->release(); - vertex_button[i]->release(); - setNormalVAO(button_shader, vertex_button[i], - buffer_button_vertex[i], - vt, 4); - } - } - } - } -} - -void GLDraw_ES_2::do_set_display_osd(bool onoff) -{ - osd_onoff = onoff; -} - -void GLDraw_ES_2::do_display_osd_leds(int lednum, bool onoff) -{ - if(lednum == -1) { - osd_led_status = (onoff) ? 0xffffffff : 0x00000000; - } else if((lednum >= 0) && (lednum < 32)) { - uint32_t nn; - nn = 0x00000001 << lednum; - if(onoff) { - osd_led_status |= nn; - } else { - osd_led_status &= ~nn; - } - } -} - -void GLDraw_ES_2::uploadIconTexture(QPixmap *p, int icon_type, int localnum) -{ - if((icon_type > 7) || (icon_type < 0)) return; - if((localnum >= 9) || (localnum < 0)) return; - if(p == NULL) return; - p_wid->makeCurrent(); - QImage image = p->toImage(); - - if(icon_texid[icon_type][localnum] != NULL) delete icon_texid[icon_type][localnum]; - { - icon_texid[icon_type][localnum] = new QOpenGLTexture(image); - } - p_wid->doneCurrent(); - } -void GLDraw_ES_2::updateBitmap(QImage *p) -{ - if(!using_flags->is_use_one_board_computer()) return; - redraw_required = true; - bitmap_uploaded = false; - uploadBitmapTexture(p); -} - -void GLDraw_ES_2::uploadBitmapTexture(QImage *p) -{ - if(!using_flags->is_use_one_board_computer()) return; - if(p == NULL) return; - if(!bitmap_uploaded) { - p_wid->makeCurrent(); - if(uBitmapTextureID != NULL) { - delete uBitmapTextureID; - } - uBitmapTextureID = new QOpenGLTexture(*p); - p_wid->doneCurrent(); - bitmap_uploaded = true; - crt_flag = true; - } -} - -void GLDraw_ES_2::updateButtonTexture(void) -{ - int i; - button_desc_t *vm_buttons_d = using_flags->get_vm_buttons(); - if(button_updated) return; - if(vm_buttons_d != NULL) { - for(i = 0; i < using_flags->get_max_button(); i++) { - QImage img = ButtonImages.at(i); - if(uButtonTextureID[i] != NULL) { - delete uButtonTextureID[i]; - } - uButtonTextureID[i] = new QOpenGLTexture(img); - } - } - button_updated = true; -} diff --git a/source/src/qt/gui/gles2/qt_glutil_gles_2.h b/source/src/qt/gui/gles2/qt_glutil_gles_2.h index aae685d0d..cfd082008 100644 --- a/source/src/qt/gui/gles2/qt_glutil_gles_2.h +++ b/source/src/qt/gui/gles2/qt_glutil_gles_2.h @@ -29,90 +29,7 @@ class DLL_PREFIX GLDraw_ES_2 : public GLDraw_Tmpl Q_OBJECT private: QOpenGLFunctions *extfunc; - float ringing_phase; protected: - const float luma_filter[24 + 1] = { - -0.000012020, - -0.000022146, - -0.000013155, - -0.000012020, - -0.000049979, - -0.000113940, - -0.000122150, - -0.000005612, - 0.000170516, - 0.000237199, - 0.000169640, - 0.000285688, - 0.000984574, - 0.002018683, - 0.002002275, - -0.000909882, - -0.007049081, - -0.013222860, - -0.012606931, - 0.002460860, - 0.035868225, - 0.084016453, - 0.135563500, - 0.175261268, - 0.190176552 - }; - const float chroma_filter[24 + 1] = { - -0.000118847, - -0.000271306, - -0.000502642, - -0.000930833, - -0.001451013, - -0.002064744, - -0.002700432, - -0.003241276, - -0.003524948, - -0.003350284, - -0.002491729, - -0.000721149, - 0.002164659, - 0.006313635, - 0.011789103, - 0.018545660, - 0.026414396, - 0.035100710, - 0.044196567, - 0.053207202, - 0.061590275, - 0.068803602, - 0.074356193, - 0.077856564, - 0.079052396 - }; - const float rot0[4] = {1, -0, 0, 1}; - const float rot90[4] = {0, 1, -1, 0}; - const float rot180[4] = {-1, 0, 0, -1}; - const float rot270[4] = {0, -1, 1, 0}; - - int gl_major_version; - int gl_minor_version; - GLScreenPack *main_pass; - GLScreenPack *std_pass; - GLScreenPack *ntsc_pass1; - GLScreenPack *ntsc_pass2; - GLScreenPack *bitmap_block; - GLScreenPack *led_pass; - GLScreenPack *osd_pass; - QOpenGLBuffer *led_pass_vbuffer[32]; - QOpenGLVertexArrayObject *led_pass_vao[32]; - QOpenGLBuffer *osd_pass_vbuffer[32]; - QOpenGLVertexArrayObject *osd_pass_vao[32]; - - VertexTexCoord_t vertexTmpTexture[4]; - - QOpenGLShaderProgram *grids_shader; - QOpenGLBuffer *grids_horizonal_buffer; - QOpenGLVertexArrayObject *grids_horizonal_vertex; - QOpenGLBuffer *grids_vertical_buffer; - QOpenGLVertexArrayObject *grids_vertical_vertex; - - GLuint uTmpTextureID; bool swap_byteorder; QOpenGLPixelTransferOptions *TextureTransferParam; @@ -135,7 +52,9 @@ class DLL_PREFIX GLDraw_ES_2 : public GLDraw_Tmpl virtual void initPackedGLObject(GLScreenPack **p, int _width, int _height, const QString vertex_shader, const QString fragment_shader, - const QString _name, bool req_float = false, bool req_highp = false); + const QString _name, + bool req_float = false, bool req_highp = false, + bool req_alpha_channel = true); virtual void drawGridsHorizonal(void); virtual void drawGridsVertical(void); @@ -163,42 +82,38 @@ class DLL_PREFIX GLDraw_ES_2 : public GLDraw_Tmpl bool use_chromakey = false); virtual void drawBitmapTexture(void); virtual void drawButtonsMain(int num, bool f_smoosing); - virtual void drawOsdLeds(); - virtual void drawOsdIcons(); - virtual void drawLedMain(GLScreenPack *obj, int num, QVector4D color); +// virtual void drawOsdLeds(); +// virtual void drawOsdIcons(); +// virtual void drawLedMain(GLScreenPack *obj, int num, QVector4D color); virtual void set_led_vertex(int bit); virtual void set_osd_vertex(int bit); - virtual void initBitmapVertex(void); - virtual QOpenGLTexture *createMainTexture(QImage *img); - void updateButtonTexture(void); + virtual QOpenGLTexture *createMainTexture(QImage *img); public: - GLDraw_ES_2(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu = 0); + GLDraw_ES_2(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU_TEMPLATE *emu = 0); ~GLDraw_ES_2(); void drawButtons(void); virtual void initGLObjects(); virtual void initLocalGLObjects(void); virtual void initFBO(void); - void initButtons(void); + //virtual void initBitmapVertex(void); + virtual void prologueBlending(); + virtual void epilogueBlending(); + virtual void drawPolygon(int vertex_loc, uintptr_t p = 0); virtual void uploadMainTexture(QImage *p, bool chromakey, bool was_mapped); virtual void drawScreenTexture(void); virtual void do_set_screen_multiply(float mul); virtual void doSetGridsHorizonal(int lines, bool force); virtual void doSetGridsVertical(int pixels, bool force); - void uploadBitmapTexture(QImage *p); + public slots: - void updateBitmap(QImage *); - void uploadIconTexture(QPixmap *p, int icon_type, int localnum); void setBrightness(GLfloat r, GLfloat g, GLfloat b); void do_set_texture_size(QImage *p, int w, int h); void do_set_horiz_lines(int lines); virtual void paintGL(void); virtual void resizeGL(int width, int height); - void do_set_display_osd(bool onoff); - void do_display_osd_leds(int lednum, bool onoff); - }; QT_END_NAMESPACE #endif diff --git a/source/src/qt/gui/gles2/tmp_vertex_shader.glsl b/source/src/qt/gui/gles2/tmp_vertex_shader.glsl deleted file mode 100644 index 769e0fb08..000000000 --- a/source/src/qt/gui/gles2/tmp_vertex_shader.glsl +++ /dev/null @@ -1,18 +0,0 @@ -#if __VERSION__ >= 300 -in mediump vec3 vertex; -in mediump vec2 texcoord; -out mediump vec2 v_texcoord; -#else -attribute mediump vec3 vertex; -attribute mediump vec2 texcoord; -varying mediump vec2 v_texcoord; -#endif -void main () -{ - mediump vec4 tmpvar_1; - tmpvar_1.w = 1.0; - tmpvar_1.xyz = vertex; - gl_Position = tmpvar_1; - v_texcoord = texcoord; -} - diff --git a/source/src/qt/gui/gles2/vertex_shader.glsl b/source/src/qt/gui/gles2/vertex_shader.glsl deleted file mode 100644 index 500cd9028..000000000 --- a/source/src/qt/gui/gles2/vertex_shader.glsl +++ /dev/null @@ -1,23 +0,0 @@ -#if __VERSION__ >= 300 -//in mediump vec3 vertex; -in mediump vec3 vertex; -in mediump vec2 texcoord; -out mediump vec2 v_texcoord; -precision mediump float; -#else -attribute mediump vec3 vertex; -attribute mediump vec2 texcoord; -varying mediump vec2 v_texcoord; -#endif - -uniform mat2 rotate_mat; -uniform bool rotate; -uniform mediump mat3 v_ortho; -void main () -{ - vec2 xy = vertex.xy; - xy = rotate_mat * xy; - gl_Position = vec4(xy, vertex.z, 1.0); - v_texcoord = texcoord; -} - diff --git a/source/src/qt/gui/gui.ja_JP.ts b/source/src/qt/gui/gui.ja_JP.ts new file mode 100644 index 000000000..47c7791d7 --- /dev/null +++ b/source/src/qt/gui/gui.ja_JP.ts @@ -0,0 +1,2453 @@ + + + + + CSP_DropDownJoysticks + + Configure Joysticks + ジョイステックを設定する + + + Configure Joystick to KEYBOARD + ジョイスティック→キーボード変換の設定 + + + + Debugger + + Set Font + フォント変更 + + + + JoykeyDialog + + Use 5 key to stop + <B>Use 5 key to stop</B> + テンキーの「5」でカーソルを止める + + + Cursor keys + カーソルキー + + + 2468 + 2468 + + + 2468 + 1379 + 2468 + 1379 + + + 1235 + 1235 + + + Joykey Type: + <B>Joykey Type:</B> + ジョイスティック→キーボード 変換方式: + + + Physical Buttons: + <B>Physical Buttons:</B> + 物理ボタン: + + + + JoystickDialog + + <B>Physical Axis:</B> + <B>動かす軸</B> + + + <B>Physical Buttons:</B> + <B>ボタン</B> + + + + KeySetDialog + + <B>Define Keys</B> + <B>キーコード(VK_xxx)</B> + + + <B>Scan Code</B> + <B>スキャンコード</B> + + + Undefined + *未定義* + + + Configure Keyboard + キーボードの設定 + + + + LogWindow + + Set Font + フォント変更 + + + + MainWindow + + Stop Recorded Sound + 録音停止 + + + Start Recording Sound + 録音開始する + + + Save Binary + バイナリを保存する + + + Load + ロード + + + Load memory image from a file. + メモリイメージをファイルから読み込みます。 + + + Save + セーブ + + + Save memory image to a file. + メモリイメージをファイルにセーブします。 + + + Recently Loaded + 最近ロードしたファイル + + + Cartridge + カートリッジ + + + Insert + さしこむ + + + Eject + 取り出す + + + Insert a cartridge image file. + カートリッジのイメージファイルを外します。 + + + Eject a cartridge image. + カートリッジイメージを取り出します。 + + + Recent Opened + 最近開いた物 + + + Save Tape + テープをサーブします + + + Insert CMT + テープを入れる + + + Insert a TAPE image file. + テープのイメージファイルを読み込みます。 + + + Eject CMT + テープを取り出す + + + Eject a TAPE image file. + テープのイメージファイルを取り出します。 + + + Enable Wave Shaper + Wave Shaper + + + Enable wave shaping. +Useful for some images. + 波形整形を行います。 +いくらかのイメージファイル等で効果があるでしょう。 + + + Direct load from MZT + MZTから直接読む + + + Direct loading to memory. +Only for MZT image file. + テープイメージから直接メモリに読み込みます。 +MZTファイルのみサポートしています。 + + + Cassette Tape + カセットテープ + + + Play Stop + 停止 + + + Play Start + 開始 + + + Fast Forward + 早送り + + + Rewind + 巻き戻し + + + APSS Forward + APSSで前に + + + APSS Rewind + APSSで後ろに + + + Record to a WAV File + WAVファイルに録音 + + + Record CMT output to a file. + マシンからテープに書かれる音声データを、WAVファイルに書き出します。 + + + Insert Compact Disc + CDを入れる + + + Insert a image file; CD-ROM or CD audio. + CDのイメージファイルを入れます。 +CD-ROMやCDなどです。 + + + Eject Compact Disc + CDを取り出す + + + Eject a compact disc. + CDを取り出します。 + + + CD ROM + CD ROM + + + Reset + リセット + + + Reset virtual machine. + 仮想マシンをリセットします。 + + + Exit Emulator + 終了 + + + Exit emulator. +**WARN: WITHOUT confirming.** + エミュレータを終了します。 +*注意:確認せずに終了します* + + + Speed x1 + 1倍 + + + Speed x2 + 2倍 + + + Speed x4 + 4倍 + + + Speed x8 + 8倍 + + + Speed x16 + 16倍 + + + Paste from Clipboard + クリップボードから貼り付け + + + Paste ANK text to virtual machine from desktop's clop board. + デスクトップのクリップボードにある、 +ANK(アルファベットと数字と半角カタカナ)のテキストを、 +仮想マシンにコピペします。 + + + Stop Pasting + 貼り付け中止 + + + Abort pasting ANK text to virtual machine. + 仮想マシンへのANKテキストの貼り付けを中止します。 + + + Save State + ステートを保存 + + + Save snapshot to fixed bin file. + 仮想マシンのスナップショットを定位置のbinファイルにセーブします。 + + + Load State + ステートロード + + + Load snapshot from fixed bin file. + 仮想マシンのスナップショットを定位置のbinファイルから読み込みます。 + + + Main CPU + メインCPU + + + Sub CPU + サブCPU + + + Debugger 3 + デバッガ3 + + + Debugger 4 + デバッガ4 + + + Debugger + デバッガ + + + Control + 操作 + + + State + ステート + + + Copy/Paste + コピペ + + + CPU Speed + CPU速度 + + + Grab MOUSE + マウスを取り込む + + + Grabbing host's mouse. +Press RIGHT Application key (or another) to toggle enable/disable. + ホスト側のマウスを取り込みます。 +右アプリケーション キー(もしくはその他)を押す度に、 +トグル動作します。 + + + Insert virtual floppy disk file. + 仮想フロッピーディスクファイルを挿入します。 + + + Eject virtual floppy disk. + 仮想フロッピーディスクを取り出します。 + + + Ignore CRC error + CRCエラー無視 + + + Ignore CRC error of virtual floppy. +Useful for some softwares, + but causes wrong working with some softwares. + 仮想ディスクイメージ上のCRCエラーを無視します。 +幾つかのソフトウェアで効果がありますが、 +他のソフトウェアではバグなどの問題の原因になるかもしれません。 + + + Correct transfer timing + 転送タイミング調整 + + + Correct transferring timing. +Useful for some softwares + needs strict transfer timing. + ディスクの転送タイミングを調整します。 +正確な転送タイミングが必要な、いくつかの +ソフトウェアでの不具合が解消するかもしれ +ません。 + + + + Insert Laserdisc + LDを入れる + + + Insert a MOVIE file. + LDのムービーを記録した動画ファイルを入れます。 + + + Eject Laserdisc + LDを取り出す + + + Eject a MOVIE file. + 動画ファイル(の仮想ディスク)を取り出します。 + + + Laserdisc + レーザディスク + + + Configure Joysticks + ジョイスティックの設定 + + + Configure assigning buttons/directions of joysticks. + ジョイスティックの方向やボタンの割当を設定します。 + + + ROMA-KANA Conversion + ローマ字かな変換 + + + Use romaji-kana conversion assistant of emulator. + エミュレータ上のローマ字かな変換を使用します。 + + + None + None + + + Emulator + エミュレータ + + + Focus on click + 画面クリックでフォーカス + + + If set, focus with click, not mouse-over. + 設定すると、マウスオーバーではなく、表示画面のクリックでフォーカスします。 + + + Configure Keyboard + キーボード設定 + + + Set addignation of keyboard. + キーの割当を設定します。 + + + Configure movie encoding + 動画保存設定 + + + Configure parameters of movie encoding. + 動画保存での、エンコーディングのパラメータを設定します。 + + + Log to Console + コンソールに記録 + + + Enable logging to STDOUT if checked. + チェックすると、標準出力にログが出ます。 + + + Log to Syslog + SYSLOGに記録 + + + Enable logging to SYSTEM log. +May be having permission to system and using *nix OS. + ホストのシステムログにログを記録します。 +ホスト上で記録できる権限があり、なおか +つ*nix OSでないと使えないかもしれません。 + + + Sound FDD Seek + FDシーク音を鳴らす + + + Enable FDD HEAD seeking sound. +Needs sound file. +See HELP->READMEs->Bios and Key assigns + フロッピーディスクのシーク音を鳴らします。 +音声ファイルが必要です。 +ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい + + + Sound CMT Relay + レコーダのリレー音を鳴らす + + + Enable CMT relay's sound. +Needs sound file. +See HELP->READMEs->Bios and Key assigns + データレコーダのリレー音を鳴らします。 +音声ファイルが必要です。 +ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい + + + Sound CMT Buttons + ボタン音を鳴らす + + + Enable CMT button's sound. +Needs sound file. +See HELP->READMEs->Bios and Key assigns + データレコーダのボタンの音を鳴らします。 +音声ファイルが必要です。 +ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい + + + Sound CMT Relay and Buttons + テープのリレーと音のボタンを鳴らす + + + Enable CMT relay's sound and buttons's sounds. +Needs sound file. +See HELP->READMEs->Bios and Key assigns + カセットテープレコーダのボタンの音と、リレーの音を鳴らします。 +音声ファイルが必要です。 +詳しくは、「ヘルプ」→「READMEs」→「BIOSとキー割り当て」の項目をお読みください。 + + + Per Device + デバイスごと + + + Video Platform(need restart) + 表示基盤(要再起動) + + + OpenGLv3.0 + OpenGL v3.0 + + + OpenGLv2.0 + OpenGL v2.0 + + + OpenGL(Core profile) + OpenGL(Core Profile) + + + Using OpenGL v3.0(MAIN). +This is recommanded. +If changed, need to restart this emulator. + OpenGLv3.0(メインプロファイル)で描画します。 +これを推奨します。 +変更した場合は、エミュレータの再起動が必要です。 + + + Using OpenGLv2. +This is fallback of some systems. +If changed, need to restart this emulator. + OpenGLv2.0で描画します。 +機能が劣りますが、幾つかのシステムでは代用とし +て、これが選択されるでしょう。 +変更した場合は、エミュレータの再起動が必要です。 + + + Using OpenGL core profile. +This still not implement. +If changed, need to restart this emulator. + OpenGLのCore Profileを使用します。 +まだ、実装されていません。 +変更した場合は、エミュレータの再起動が必要です。 + + + Show Virtual Medias. + 仮想メディアを表示する + + + None. + 表示しない + + + Upper. + 上に表示する + + + Lower. + 下に表示する + + + View Log + ログを見る + + + View emulator logs with a dialog. + エミュレータのログを、ダイアログで見ます。 + + + Help + ヘルプ + + + About Qt + Qtについて + + + Display Qt version. + Qtのヴァージョンを表示します。 + + + About... + このソフトについて... + + + About this emulator. + このエミュレータについて。 +クレジット表記などです。 + + + READMEs + READMEs + + + General Document + 総合的な文書 + + + About Qt ports + Qt移植版について(英語) + + + About Qt ports (Japanese). + Qt移植版について(日本語)。 + + + By Mr. Umaiboux. + Umaibouxさんによる文書 + + + By Mr. tanam + Tanamさんによる文書 + + + About eFM-7/8/77/AV. + eFM-7/8/77/AVについて。 + + + About eFM-7/8/77/AV (Japanese). + eFM-7/8/77/AVについて(日本語)。 + + + FAQs(English) + FAQs(英語) + + + FAQs(Japanese) + FAQs(日本語) + + + BIOS and Key assigns + BIOSとキー割り当てについて + + + Histories + 履歴・歴史 + + + General History + 全体の歴史 + + + Release Note + リリースノート + + + Change Log + チェンジログ + + + History by Tanam + Tanamさん部分の履歴 + + + Show License + ライセンス + + + Show general license (GPLv2). + ライセンスを読みます。GPL2です。 + + + Show License (Japanese) + ライセンス(日本語) + + + Show general license (GPLv2). +Translated to Japanese. + 日本語に翻訳されたライセンスを読みます(GPL2)。 + + + Machine + 仮想マシン + + + Device Type + デバイス + + + Sound Cards + サウンドカード + + + Drive Type + ドライブタイプ + + + Printer (Need RESET) + プリンタ(リセットが必要) + + + Dump to File + ファイルに書き込む + + + Dump printer output to file. +Maybe output only ascii text. + プリンタ出力をファイルに書き込みます。 +書き込まれるのは、多分、アスキーテキストだけです。 + + + Printer + プリンター + + + Not Connect + 未接続 + + + None devices connect to printer port. + プリンタポートに何も繋がってない状態です。 + + + Open + 開く- + + + Insert a virtual image file. + 仮想イメージファイルを入れます。 + + + Eject a inserted virtual image file. + 入れてあった仮想イメージファイルを取り出します。 + + + Write Protection + 書き込み保護 + + + On + オン + + + Enable write protection. +You can't write any data to this media. + 書き込み保護をします。 +このメディアには、如何なるデータも*書き込めません*。 + + + Off + オフ + + + Disable write protection. +You *can* write datas to this media. + 書き込み保護を解除します。 +このメディアには、データを書き込むことが出来ます。 + + + Select D88 Image + D88イメージ選択 + + + Recent opened + 最近開いたファイル + + + Zoom Screen + 画面ズーム + + + Display Mode + 表示モード + + + Software Scan Line + スキャンライン(ソフト) + + + Display scan line by software. + ソフトウェアでスキャンラインを表示します。 + + + Rotate Screen + 画面回転 + + + Rotate screen. + 画面を回転します。 + + + Software Filter + 画面フィルタ(ソフト) + + + Use display filter by software. + ソフトウェアの画面フィルタを使います。 + + + OpenGL Scan Line + スキャンライン(OpenGL) + + + Display scan line by OpenGL. + OpenGLのスキャンラインを表示します。 + + + OpenGL Pixel Line + ピクセルライン(OpenGL) + + + Display pixel line by OpenGL. + OpenGLのピクセルラインを表示します。 + + + OpenGL Filter + OpenGLフィルタ + + + Use display filter by OpenGL + OpenGLの画面フィルタを使用します(多少ぼやける) + + + Dot by Dot + ドット拡大なし + + + Keep Aspect: Refer to X + アスペクト比保存/横に合わせる + + + Keep Aspect: Refer to Y + アスペクト比保存/縦にあわせる + + + Keep Aspect: Fill + アスペクト比保存/画面を満たす + + + Stretch Mode + 拡大モード + + + Capture Screen + 画面取り込み + + + Capture screen to a PNG file. + 画面を、PNGファイルとして取り込みます。 + + + Screen + 画面 + + + Start Recording Movie + 動画記録開始 + + + Stop Recording Movie + 動画記録終了 + + + Record as Movie + 動画として記録する + + + Screen Size + 画面サイズ + + + Render Mode + 画面描画モード + + + Standard + 標準 + + + Standard render. + 通常のレンダラです。 + + + TV + TV + + + Rendering like tubed television with RF modulator. +Needs OpenGL 3.0 or later.Not effect with OpenGL 2.0. + 昔のブラウン管テレビにRFモジュレータを通して映したように表示します。 +OpenGL 3.0以上が必要です。 +OpenGL 2.0では無効です。 + + + Hz + Hz + + + mSec + mSec + + + Record sound as WAV file. + 音声をWAVファイルとして記録します。 + + + Play CMT sound + Sound CMT + カセットレコーダの音を出す + + + Enable sound of CMT TAPE recorder. + カセットテープレコーダに記録されている音を鳴らします。 + + + Strict Rendering + 厳密なレンダリング + + + Rendering per a sample.Select to slower, but accurate rendering sound. + 音声1サンプルごと(サンプルレートが44100Hzならば、1/44100秒ごと)に、 +音のレンダリングをします。これを選択すると動作が重くなる場合がありますが、 +音声のレンダリングが正確になります。 + + + Play sound from CMTs. + カセットレコーダの音を鳴らす + + + Sound + + + + Output Frequency + 出力周波数(サンプルレート) + + + Sound Latency + 音声(遅延)バッファサイズ + + + Set Volumes + 音量設定 + + + Open a VOLUME dialog. + 音量調整ダイアログを開きます。 + + + Binary + バイナリ + + + Bubble + バブル + + + Floppy + フロッピーディスク + + + Quick Disk + クイックディスク + + + + MemoryDialog + + Reset + リセット + + + Cancel + 戻る + + + Save Options + 設定を保存する + + + + MemorySetDialog + + <B>Memory Size</B> + + + + + MenuControl + + Reset + リセット + + + Reset virtual machine. + 仮想マシンをリセットします。 + + + Exit Emulator + 終了 + + + Exit emulator. +**WARN: WITHOUT confirming.** + エミュレータを終了します。 +*注意:確認せずに終了します* + + + Speed x1 + 1倍速 + + + Speed x2 + 2倍速 + + + Speed x4 + 4倍速 + + + Speed x8 + 8倍速 + + + Speed x16 + 16倍速 + + + Paste from Clipboard + クリップボードから貼り付け + + + Paste ANK text to virtual machine from desktop's clop board. + デスクトップのクリップボードにある、 +ANK(アルファベットと数字と半角カタカナ)のテキストを、 +仮想マシンにコピペします。 + + + Stop Pasting + 貼り付け中止 + + + Abort pasting ANK text to virtual machine. + 仮想マシンへのANKテキストの貼り付けを中止します。 + + + Save State + ステートを保存 + + + Save snapshot to fixed bin file. + 仮想マシンのスナップショットを定位置のbinファイルにセーブします。 + + + Load State + ステートロード + + + Load snapshot from fixed bin file. + 仮想マシンのスナップショットを定位置のbinファイルから読み込みます。 + + + Main CPU + メインCPU + + + Sub CPU + サブCPU + + + Debugger 3 + デバッガ3 + + + Debugger 4 + デバッガ4 + + + Debugger + デバッガ + + + Control + 操作 + + + State + ステート + + + Copy/Paste + コピペ + + + CPU Speed + CPU速度 + + + Grab MOUSE + マウスを取り込む + + + Grabbing host's mouse. +Press RIGHT Application key (or another) to toggle enable/disable. + ホスト側のマウスを取り込みます。 +右アプリケーション キー(もしくはその他)を押す度に、 +トグル動作します。 + + + + MenuEmulator + + Configure Joysticks + ジョイスティックの設定 + + + Configure assigning buttons/directions of joysticks. + ジョイスティックの方向やボタンの割当を設定します。 + + + Configure Joystick to KEYBOARD + ジョイスティック→キーボード変換の設定 + + + Configure assigning keycode to joystick buttons. +This feature using Joystick #1. + Configure assigning keycode to joystick buttons. + ジョイスティックからキーボードの変換を設定します。 +ジョイスティック1番が使用されます。 + + + Joystick to KEYBOARD + ジョイスティックをキーボードに変換する + + + Use Joystick axis/buttons to input keyboard. +This feature using Joystick #1. + Use Joystick axis/buttons to input keyboard. + ジョイスティックの方向とボタンでキーボードを入力します。 +ジョイスティック1番が使用されます。 + + + ROMA-KANA Conversion + ローマ字かな変換 + + + Use romaji-kana conversion assistant of emulator. + エミュレータ上のローマ字かな変換を使用します。 + + + Emulate as FULL SPEED + 全速力でエミュレート + + + Run emulation thread without frame sync. + フレーム同期を取らずに全速力でエミュレーションします。 + + + Numpad's Enter is Fullkey's + テンキーのEnterをフルキーとみなす + + + Numpad's enter key makes full key's enter. +Useful for some VMs. + テンキー側のEnterキーを押した時に、フルキーのEnterを出力します。 +いくつかのVMやいくつかの環境で有用なはずです。 + + + Print Statistics + 統計を表示する + + + Print statistics of CPUs (or some devices). +Useful for debugging. + CPU使用の統計を表示します。 +デバッグに有益なはずです。 + + + FDC: Turn ON Debug log. + FDCのデバッグログを開始する。 + + + Turn ON debug logging for FDCs.Useful to resolve issues from guest software. + FDCのデバッグログを取ります。 +ゲストで使用するソフトウェアの問題解決に役立つかも知れません。 + + + Emulate cursor as + カーソルキーで + + + Emulate cursor as ten-key. + カーソルキーでテンキーをエミュレートします。 + + + None + テンキーエミュレートしない + + + 2 4 6 8 + テンキーの「2 4 6 8」をエミュレート + + + 1 2 3 5 + テンキーの「1 2 3 5 」をエミュレート + + + Emulator + エミュレータ + + + Focus on click + 画面クリックでウィンドウフォーカスを固定 + + + If set, focus with click, not mouse-over. + 設定すると、マウスオーバーではなく、表示画面のクリックでフォーカスします。 + + + Configure Keyboard + キーボードの設定 + + + Set addignation of keyboard. + キーの割当を設定します。 + + + Configure movie encoding + 動画保存設定 + + + Configure parameters of movie encoding. + 動画保存での、エンコーディングのパラメータを設定します。 + + + Log to Console + コンソールに記録 + + + Enable logging to STDOUT if checked. + チェックすると、標準出力にログが出ます。 + + + Log to Syslog + SYSLOGに記録 + + + Enable logging to SYSTEM log. +May be having permission to system and using *nix OS. + ホストのシステムログにログを記録します。 +ホスト上で記録できる権限があり、なおか +つ*nix OSでないと使えないかもしれません。 + + + Sound FDD Seek + FDシーク音を鳴らす + + + Enable FDD HEAD seeking sound. +Needs sound file. +See HELP->READMEs->Bios and Key assigns + フロッピーディスクのシーク音を鳴らします。 +音声ファイルが必要です。 +ヘルプのREADMEsの「BIOSとキー割り当て」項目をお読み下さい + + + Sound CMT Relay and Buttons + テープのリレーと音のボタンを鳴らす + + + Enable CMT relay's sound and buttons's sounds. +Needs sound file. +See HELP->READMEs->Bios and Key assigns + カセットレコーダーのリレーとボタンの音を再生します。 +サウンドファイルが必要です。 +HELP->READMEs->BIOSとキー割当 をお読み下さい。 + カセットテープレコーダのボタンの音と、リレーの音を鳴らします。 +音声ファイルが必要です。 +詳しくは、「ヘルプ」→「READMEs」→「BIOSとキー割り当て」の項目をお読みください。 + + + Per Device + デバイスごと + + + Video Platform(need restart) + 画面表示基盤(要再起動) + + + Occupy Fixed CPU + 固定CPUでエミュレーションを行う。 + + + Using all CPU + 全CPUでエミュレーションする + + + Using all CPU to emulation. +Reset cpu usings. + すべてのCPUでエミュレーションを分担します。 +CPU利用はリセットされます。 + + + Set Fixed logical CPU #%1 to be occupied by emulation thread. +May useful for heavy VM (i.e. using i386 CPU). +Still implement LINUX host only, not another operating systems. + エミュレーションスレッドを、論理CPU #%1で固定します。 +重いVM(例えばi386C CPUを利用している)で便利かも知れません。 +この機能はまだ、LINUXでしか実装されていません。 + + + OpenGLv3.0 + OpenGL v3.0 + + + OpenGLv2.0 + OpenGL v2.0 + + + OpenGL(Core profile) + OpenGL(コアプロファイル) + + + Using OpenGL ES v2.0. +This is recommanded. +If changed, need to restart this emulator. + OpenGL ES(v2.0)で描画します。 +この方法をおすすめします。 +変更した場合、エミュレータ自体の再起動が必要です。 + + + Using OpenGL ES v3.1. +This is recommanded. +If changed, need to restart this emulator. + OpenGL ES(v3.1)で描画します。 +この方法をおすすめします。 +変更した場合、エミュレータ自体の再起動が必要です。 + + + Using OpenGL v3.0(MAIN). +This is recommanded. +If changed, need to restart this emulator. + OpenGLv3.0(メインプロファイル)で描画します。 +これを推奨します。 +変更した場合は、エミュレータの再起動が必要です。 + + + Using OpenGLv2. +This is fallback of some systems. +If changed, need to restart this emulator. + OpenGLv2.0で描画します。 +機能が劣りますが、幾つかのシステムでは代用とし +て、これが選択されるでしょう。 +変更した場合は、エミュレータの再起動が必要です。 + + + Using OpenGL core profile. +This still not implement. +If changed, need to restart this emulator. + OpenGLのCore Profileを使用します。 +まだ、実装されていません。 +変更した場合は、エミュレータの再起動が必要です。 + + + Show Virtual Medias. + 仮想メディア一覧を表示する。 + 仮想メディアを表示する + + + None. + 表示しない + 表示しない + + + Upper. + 上側 + 上に表示する + + + Lower. + 下側 + 下に表示する + + + View Log + ログを見る + + + View emulator logs with a dialog. + エミュレータのログを、ダイアログで見ます。 + + + OpenGL ES v2.0 + + + + OpenGL ES v3.1 + + + + + MenuHDD + + Mount + マウントする + + + Mount virtual hard disk file. + 仮想ハードディスクをつないでマウントします。 + + + Unmount + はずす + + + Unmount virtual hard disk. + 仮想ハードディスクを取り外します。 + + + Create Virtual HDD + 仮想HDDを作成する + + + Create and mount virtual blank-hard disk. +This makes only NHD/HDI format. + 空の仮想ハードディスクを作成してマウントします。 +NHD形式とHDI形式のみ作成可能です。 + + + + MenuHelp + + Help + ヘルプ + + + About Qt + Qtについて + + + Display Qt version. + Qtのヴァージョンを表示します。 + + + About... + このソフトについて... + + + About this emulator. + このエミュレータについて。 +クレジット表記などです。 + + + READMEs + READMEs + + + General Document + 総合的な文書 + + + About Qt ports + Qt移植版について(英語) + + + About Qt ports (Japanese). + Qt移植版について(日本語)。 + + + By Mr. Umaiboux. + Umaibouxさんによる文書 + Umaibouxさんによる文書 + + + By Mr. tanam + Tanamさんによる文書 + + + About eFM-7/8/77/AV. + eFM-7/8/77/AVについて。 + + + About eFM-7/8/77/AV (Japanese). + eFM-7/8/77/AVについて(日本語)。 + + + FAQs(English) + FAQs(英語) + + + FAQs(Japanese) + FAQs(日本語) + + + BIOS and Key assigns + BIOSとキー割り当てについて + + + Histories + 履歴・歴史 + + + General History + 全体の歴史 + + + Release Note + リリースノート + + + Change Log + チェンジログ + + + History by Tanam + Tanamさん部分の履歴 + + + Show License + ライセンス + + + Show general license (GPLv2). + ライセンスを読みます。GPL2です。 + + + Show License (Japanese) + ライセンス(日本語) + + + Show general license (GPLv2). +Translated to Japanese. + 日本語に翻訳されたライセンスを読みます(GPL2)。 + + + + MenuMachine + + Machine + 仮想マシン + + + Device Type + デバイス + + + Sound Cards + サウンドカード + + + Drive Type + ドライブタイプ + + + Printer (Need RESET) + プリンタ(リセットが必要) + + + Dump to File + ファイルに書き込む + + + Dump printer output to file. +Maybe output only ascii text. + プリンタ出力をファイルに書き込みます。 +書き込まれるのは、多分、アスキーテキストだけです。 + + + Printer + プリンター + + + Not Connect + 未接続 + + + None devices connect to printer port. + プリンタポートに何も繋がってない状態です。 + + + Monitor Type + ディスプレイのタイプ + + + RAM Size + + + + Set (extra) memory size. +This will effect after restarting this emulator. + + + + + MenuMedia + + Save Binary + バイナリを保存する + + + Load + ロード + + + Load memory image from a file. + メモリイメージをファイルから読み込みます。 + + + Save + セーブ + + + Save memory image to a file. + メモリイメージをファイルにセーブします。 + + + Recently Loaded + 最近ロードしたファイル + + + Cartridge + カートリッジ + カートリッジ + + + Insert + さしこむ + + + Eject + 取り出す + + + Insert a cartridge image file. + カートリッジのイメージファイルを外します。 + + + Eject a cartridge image. + カートリッジイメージを取り出します。 + + + Recent Opened + 最近開いた物 + + + Save Tape + テープをサーブします + + + Insert CMT + テープを入れる + + + Insert a TAPE image file. + テープのイメージファイルを読み込みます。 + + + Eject CMT + テープを取り出す + + + Eject a TAPE image file. + テープのイメージファイルを取り出します。 + + + Enable Wave Shaper + Wave Shaper + + + Enable wave shaping. +Useful for some images. + 波形整形を行います。 +いくらかのイメージファイル等で効果があるでしょう。 + + + Direct load from MZT + MZTから直接読む + + + Direct loading to memory. +Only for MZT image file. + テープイメージから直接メモリに読み込みます。 +MZTファイルのみサポートしています。 + + + Cassette Tape + カセットテープ + + + Play Stop + 停止 + + + Play Start + 開始 + + + Fast Forward + 早送り + + + Rewind + 巻き戻し + + + APSS Forward + APSSで前に + + + APSS Rewind + APSSで後ろに + + + Record to a WAV File + WAVファイルに録音 + + + Record CMT output to a file. + マシンからテープに書かれる音声データを、WAVファイルに書き出します。 + + + Insert Compact Disc + CDを入れる + + + Insert a image file; CD-ROM or CD audio. + CDのイメージファイルを入れます。 +CD-ROMやCDなどです。 + + + Eject Compact Disc + CDを取り出す + + + Eject a compact disc. + CDを取り出します。 + + + CD ROM + CD ROM + + + Create D88/D77 virtual floppy + D88/D77形式の仮想フロッピーを作成する。 + + + Insert virtual floppy disk file. + 仮想フロッピーディスクファイルを挿入します。 + + + Eject virtual floppy disk. + 仮想フロッピーディスクを取り出します。 + + + Ignore CRC error + CRCエラー無視 + + + Ignore CRC error of virtual floppy. +Useful for some softwares, + but causes wrong working with some softwares. + 仮想ディスクイメージ上のCRCエラーを無視します。 +幾つかのソフトウェアで効果がありますが、 +他のソフトウェアではバグなどの問題の原因になるかもしれません。 + + + Correct transfer timing + 転送タイミング調整 + + + Correct transferring timing. +Useful for some softwares + needs strict transfer timing. + ディスクの転送タイミングを調整します。 +正確な転送タイミングが必要な、いくつかの +ソフトウェアでの不具合が解消するかもしれ +ません。 + + + + Create Virtual Floppy + 仮想フロッピーの作成 + + + Create and mount virtual blank-floppy disk. +This makes only D88/D77 format. + 仮想ブランクディスクを作成してマウントします。 +D88/D77形式の仮想ディスクのみ作成可能です。 + + + Immediate increment + データカウンターを即時加算する + + + Increment data pointer immediately. +This is test hack for MB8877. +Useful for some softwares + needs strict transfer timing. + データカウンターを即座に1足します。 +これは、MB8877 FDCで、転送タイミングを厳しくするHACKです。 + + + Insert Laserdisc + LDを入れる + + + Insert a MOVIE file. + LDのムービーを記録した動画ファイルを入れます。 + + + Eject Laserdisc + LDを取り出す + + + Eject a MOVIE file. + 動画ファイル(の仮想ディスク)を取り出します。 + + + Laserdisc + レーザディスク + + + Open + 開く- + + + Insert a virtual image file. + 仮想イメージファイルを入れます。 + + + Eject a inserted virtual image file. + 入れてあった仮想イメージファイルを取り出します。 + + + Write Protection + 書き込み保護 + + + On + オン + + + Enable write protection. +You can't write any data to this media. + 書き込み保護をします。 +このメディアには、如何なるデータも*書き込めません*。 + + + Off + オフ + + + Disable write protection. +You *can* write datas to this media. + 書き込み保護を解除します。 +このメディアには、データを書き込むことが出来ます。 + + + Select D88 Image + D88イメージ選択 + + + Recent opened + 最近開いたファイル + + + Binary + バイナリ + + + FDD + FD + + + Quick Disk + クイックディスク + クイックディスク + + + Connect virtual hard disk file. + 仮想ハードディスクを接続する + + + Disconnect virtual hard disk. + 仮想ハードディスクを取り外す + + + HDD + HD + + + Virtual FD type: + 仮想ディスク形式: + + + Select type of virtual floppy. + 仮想フロッピーの種類を選択してください。 + + + Create NHD/HDI Virtual HARDDISK + NHD/HDI形式の仮想ハードディスクを作成する + + + Swap byte order + + + + Swap audio track's byte order. +This is effects some ripped (not dedicated to AUDIO's endian) CD-ROMs. + + + + + MenuScreen + + Zoom Screen + 画面ズーム + + + Display Mode + 表示モード + + + Separate Draw (need restart) + 独立スレッドで描画(再起動が必要) + + + Do drawing(rendering) sequence to separate thread. +If you feels emulator is slowly at your host-machine, disable this. +You should restart this emulator when changed. + 描画を独立したスレッドで行います。 +低速な場合に無効にすると効果があるかも知れません。 +変更したら、エミュレータを再起動して下さい。 + + + + Display access Icons on screen. + アクセスランプのアイコンを表示する + アクセスアイコンを表示する + + + Use icons on screen to display accessing virtual media(s). + 仮想メディアのアイコンを、アクセスランプとして表示します。 + + + Software Scan Line + スキャンライン(ソフト) + + + Display scan line by software. + ソフトウェアでスキャンラインを表示します。 + + + Rotate Screen + 画面回転 + + + Rotate screen. + 画面を回転します。 + + + 0 deg + 0度 + + + Not rotate screen. + 画面を回転<B>しません</B>。 + + + 90 deg + 90度 + + + Rotate screen to 90 deg. + 画面を時計回りに90度回転します。 + + + 180 deg + 180度 + + + Rotate screen to 180 deg. + 画面を時計回りに180度(<B>上下左右逆さに</B>)回転します。 + + + 270 deg + 270度 + + + Rotate screen to 270 deg. + 画面を時計回りに270度回転します。 + + + OpenGL Scan Line + スキャンライン(OpenGL) + + + Display scan line by OpenGL. + OpenGLのスキャンラインを表示します。 + + + OpenGL Pixel Line + ピクセルライン(OpenGL) + + + Display pixel line by OpenGL. + OpenGLのピクセルラインを表示します。 + + + OpenGL Filter + OpenGLフィルタ + + + Use display filter by OpenGL + OpenGLの画面フィルタを使用します(多少ぼやける) + + + Dot by Dot + ドット拡大なし + + + Keep Aspect: Refer to X + アスペクト比保存/横に合わせる + + + Keep Aspect: Refer to Y + アスペクト比保存/縦にあわせる + + + Keep Aspect: Fill + アスペクト比保存/画面を満たす + + + Stretch Mode + 拡大モード + + + Capture Screen + 画面取り込み + + + Capture screen to a PNG file. + 画面を、PNGファイルとして取り込みます。 + + + Screen + 画面 + + + Start Recording Movie + 動画記録開始 + + + Stop Recording Movie + 動画記録終了 + + + Record as Movie + 動画として記録する + + + Screen Size + 画面サイズ + + + Render Mode + 画面描画モード + + + Standard + 普通 + + + Standard render. + 通常のレンダラです。 + + + TV + TVっぽく + + + Rendering like tubed television with RF modulator. +Needs OpenGL 3.0 or later.Not effect with OpenGL 2.0. + 昔のブラウン管テレビにRFモジュレータを通して映したように表示します。 +OpenGL 3.0以上が必要です。 +OpenGL 2.0では無効です。 + + + + MenuSound + + Hz + Hz + + + mSec + mSec + + + Start Recording Sound + 録音開始する + + + Record sound as WAV file. + 音声をWAVファイルとして記録します。 + + + Strict Rendering + 厳密なレンダリング + + + Rendering per a sample.Select to slower, but accurate rendering sound. + 音声1サンプルごと(サンプルレートが44100Hzならば、1/44100秒ごと)に、 +音のレンダリングをします。これを選択すると動作が重くなる場合がありますが、 +音声のレンダリングが正確になります。 + + + Play CMT sound + カセットレコーダの音を出す + + + Play sound from CMTs. + カセットレコーダの音を鳴らす + + + Output to: + 音の出力先: + + + Select sound device to output. +This effects after re-start this emulator. + 音を出すデバイスを選択します。 +デバイス選択後はエミュレータを再起動すると有効に出来ます。 + + + Sound + + + + Output Frequency + 出力周波数(サンプルレート) + + + Sound Latency + 音声(遅延)バッファサイズ + + + Set Volumes + 音量設定 + + + Open a VOLUME dialog. + 音量調整ダイアログを開きます。 + + + + MovieDialog + + General + 総合 + + + H.264 + H.264 + + + MPEG4v1 + MPEG4v1 + + + Set movie codecs. + 動画のコーデックを設定します。 + + + Cancel + 戻る + + + Save Options + 設定を保存する + + + + MovieTabGeneral + + Video Codec + ビデオコーデック + + + MPEG4 will make larger and lower quality file. +But very fast. +H.264 will make smaller and better quality file. +But very slowly. +**Note: Movie file is using MP4 container, not AVI.** + MPEG4はファイルサイズが大きく、画質も良くないですが、非常に速くエンコードします。 +H.264はファイルサイズが小さく、画質も良く出来ますが、非常に遅いエンコードです。 +**注意:動画ファイルは、MP4コンテナに記録されます。AVIではありません。** + + + Resolution + 解像度 + + + Set resolution of encoded movie file. + エンコードする動画の大きさを設定します。 + + + Video Threads + ビデオスレッド数 + + + Set number of threads used by H.264 movie endcoding. + H.264エンコーディングで使用するスレッド数を設定します。 + + + Audio Bitrate + 音声ビットレート + + + Audio Codec + 音声コーデック + + + Set codec of audio. +MP3 is using LAME. +AAC is experimental; using libAV's AAC encoder. + 音声コーデックを設定します。 +MP3は標準的なコーデックで、LAMEを使用しています。 +AACは実験的なコーデックで、 +libAVのAACコーデックを使用しています。 + + + Framerate + フレームレート + + + + MovieTabH264 + + Max B Frames + 最大Bフレーム数 + + + B Adaption + B Adaption + + + Subpixel motion estimate + サブピクセル動き予測 + + + Bitrate + ビットレート + + + Set bitrate of video. +Larger is better quality, but makes larger file. + ビデオのビットレートを設定します。 +大きな値は画質が良くなりますが、ファイルサイズも大きくなってしまいます。 + + + Max numbers of B FRAMEs. +Larger value will make smaller file, but slowly. + Bフレームの最大数を設定します。 +大きな値は小さなファイルにすることが期待できますが、 +エンコードが遅くなります。 + + + None + None + + + Fast + Fast + + + Optimal (Slow with high B-Frames) + Optimal(Bフレームが多い場合に、遅くなる) + + + Set decision of using B FRAMEs. + Bフレームにするかどうかの判断基準を設定します。 + + + Minimum Quant. +Smaller value is better quality, but making larger file. +Larger value is dirty picture, but making smaller file. +15 to 24 is recommended. + 最小Quant。 +小さな値は画質が良くなりますが、大きなファイルを作ってしまいます。 +大きな値は画質が悪くなる代わりに、小さなファイルが作れます。 +15~24がオススメです。 + + + Maximum Quant. +Smaller value is better quality, but making larger file. +Larger value is dirty picture, but making smaller file. +20 to 28 is recommended. + 最大Quant。 +小さな値は画質が良くなりますが、大きなファイルを作ってしまいます。 +大きな値は画質が悪くなる代わりに、小さなファイルが作れます。 +20~28がオススメです。 + + + RD mode decision for I/P-frames + RD mode decision for I/P-frames + + + RD mode decision for all frames + RD mode decision for all frames + + + RD refinement for I/P-frames + RD refinement for I/P-frames + + + RD refinement for all frames + RD refinement for all frames + + + QP-RD + QP-RD + + + Full RD: disable all early terminations + 最大Bフレーム + + + Set motion estimation. +Larger value is better, but slowly. + 動き予測を設定します。 +大きな値が良いのですが、遅くなります。 + + + Set H.264 parameter. + H.264のパラメータを設定します。 + + + + MovieTabMPEG4 + + Max B Frames + 最大Bフレーム数 + + + Bitrate + ビットレート + + + Set MPEG4v1 parameter. + MPEG4v1のエンコード設定をします。 + + + + SoundMenu + + Stop Recorded Sound + 録音停止する + + + Start Recording Sound + 録音開始する + + + + Ui_SoundDialog + + Set Volume + 音量設定 + + + Main + メイン + + + Reset to center. + 真ん中に戻す。 + + + Volume + 音量 + + + Balance + バランス + + + + main + + Custom home directory. + ホームディレクトリを指定する + + + Custom config file (without path). + 設定ファイルの名前を指定する(相対パス) + + + Custom config directory. + 設定ファイルのあるディレクトリを指定する + + + Custom resource directory (ROMs, WAVs, etc). + ROMやWAVなどのリソースディレクトリを指定する + + + Turn on <onbit> of dip switch. + DIPSWの<onbit>を"1"にする + + + Turn off <offbit> of dip switch. + DIPSWの<onbit>を"0"にする + + + Force set using renderer type. + 表示レンダラのタイプを強制的に決める + + + Set / Delete environment variable. + 環境変数を設定/削除する + + + Dump environment variables. + 環境変数をダンプする + + + diff --git a/source/src/qt/gui/joy_thread.cpp b/source/src/qt/gui/joy_thread.cpp index 08bdb0982..d92cf9c1e 100644 --- a/source/src/qt/gui/joy_thread.cpp +++ b/source/src/qt/gui/joy_thread.cpp @@ -10,8 +10,8 @@ #include #include #include -#include "emu.h" -#include "osd.h" +#include "emu_template.h" +#include "osd_base.h" #include "fifo.h" #include "fileio.h" #include "qt_input.h" @@ -21,7 +21,7 @@ #include "joy_thread.h" -JoyThreadClass::JoyThreadClass(EMU *p, OSD *o, USING_FLAGS *pflags, config_t *cfg, CSP_Logger *logger, QObject *parent) : QThread(parent) +JoyThreadClass::JoyThreadClass(EMU_TEMPLATE *p, OSD_BASE *o, USING_FLAGS *pflags, config_t *cfg, CSP_Logger *logger, QObject *parent) : QThread(parent) { //int i, j; int i; @@ -103,7 +103,7 @@ void JoyThreadClass::joystick_plugged(int num) names[num] = QString::fromUtf8(SDL_GameControllerNameForIndex(num)); csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_JOYSTICK, "JoyThread : Controller %d : %s : is plugged.", num, names[num].toUtf8().constData()); strncpy(p_config->assigned_joystick_name[num], names[num].toUtf8().constData(), - (sizeof(p_config->assigned_joystick_name) / sizeof(char)) - 1); + (sizeof(p_config->assigned_joystick_name[num]) / sizeof(char)) - 1); joy_num[num] = num; } } else @@ -119,7 +119,7 @@ void JoyThreadClass::joystick_plugged(int num) names[i] = QString::fromUtf8(SDL_JoystickNameForIndex(num)); csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_JOYSTICK, "JoyThread : Joystick %d : %s : is plugged.", num, names[i].toUtf8().data()); strncpy(p_config->assigned_joystick_name[num], names[num].toUtf8().constData(), - (sizeof(p_config->assigned_joystick_name) / sizeof(char)) - 1); + (sizeof(p_config->assigned_joystick_name[num]) / sizeof(char)) - 1); break; } } diff --git a/source/src/qt/gui/joy_thread.h b/source/src/qt/gui/joy_thread.h index a5884e0ca..557eaec91 100644 --- a/source/src/qt/gui/joy_thread.h +++ b/source/src/qt/gui/joy_thread.h @@ -15,8 +15,8 @@ #include "common.h" #include "config.h" -class EMU; -class OSD; +class EMU_TEMPLATE; +class OSD_BASE; class QString; class USING_FLAGS; @@ -32,8 +32,8 @@ class DLL_PREFIX JoyThreadClass : public QThread { #endif SDL_Joystick *joyhandle[16]; QString names[16]; - EMU *p_emu; - OSD *p_osd; + EMU_TEMPLATE *p_emu; + OSD_BASE *p_osd; USING_FLAGS *using_flags; config_t *p_config; protected: @@ -51,10 +51,10 @@ class DLL_PREFIX JoyThreadClass : public QThread { int get_joyid_from_instanceID(SDL_JoystickID id); # endif public: - JoyThreadClass(EMU *p, OSD *o, USING_FLAGS *pflags, config_t *cfg, CSP_Logger *logger, QObject *parent = 0); + JoyThreadClass(EMU_TEMPLATE *p, OSD_BASE *o, USING_FLAGS *pflags, config_t *cfg, CSP_Logger *logger, QObject *parent = 0); ~JoyThreadClass(); void run() { doWork("");} - void SetEmu(EMU *p) { + void SetEmu(EMU_TEMPLATE *p) { p_emu = p; } public slots: @@ -62,7 +62,7 @@ public slots: void doExit(void); signals: int sig_finished(void); - int call_joy_thread(EMU *); + int call_joy_thread(EMU_TEMPLATE *); }; diff --git a/source/src/qt/gui/mainwidget_base.h b/source/src/qt/gui/mainwidget_base.h index 15f4cfb03..8a890eb46 100644 --- a/source/src/qt/gui/mainwidget_base.h +++ b/source/src/qt/gui/mainwidget_base.h @@ -44,6 +44,7 @@ enum { RENDER_PLATFORMS_OPENGL2_MAIN, RENDER_PLATFORMS_OPENGL_CORE, RENDER_PLATFORMS_OPENGL_ES_2, + RENDER_PLATFORMS_OPENGL_ES_31, RENDER_PLATFORMS_END }; @@ -388,7 +389,7 @@ class DLL_PREFIX Ui_MainWindowBase : public QMainWindow QActionGroup *actionGroup_BootMode; QActionGroup *actionGroup_CpuType; class Action_Control *actionReset; - class Action_Control *actionSpecial_Reset; + class Action_Control *actionSpecial_Reset[16]; class Action_Control *actionExit_Emulator; class Action_Control *actionCpuType[8]; class Action_Control *actionBootMode[8]; @@ -403,6 +404,7 @@ class DLL_PREFIX Ui_MainWindowBase : public QMainWindow class Action_Control *action_ResetFixedCpu; class Action_Control *action_SetFixedCpu[128]; + class Action_Control *action_RAMSize; // Screen class Action_Control *actionCapture_Screen; class Action_Control *action_SetRenderMode[8]; @@ -547,7 +549,7 @@ class DLL_PREFIX Ui_MainWindowBase : public QMainWindow virtual void initStatusBar(void); // EmuThread void StopEmuThread(void); - virtual void LaunchEmuThread(void); + virtual void LaunchEmuThread(EmuThreadClassBase *m); // JoyThread virtual void StopJoyThread(void); virtual void LaunchJoyThread(void); @@ -590,7 +592,8 @@ public slots: void set_screen_size(int w, int h); void do_set_screen_rotate(int type); void OnReset(void); - void OnSpecialReset(void); + void do_special_reset(int); + virtual void do_set_mouse_enable(bool flag); virtual void do_toggle_mouse(void); void do_set_sound_device(int); @@ -624,6 +627,7 @@ public slots: int set_recent_cdrom(int drv, int num); void do_eject_cdrom(int drv); void do_open_cdrom(int drv, QString path); + void do_swap_cdaudio_byteorder(int drv, bool value); int set_recent_laserdisc(int drv, int num); void do_eject_laserdisc(int drv); @@ -667,6 +671,9 @@ public slots: void eject_fd(int drv); void eject_hard_disk(int drv); virtual void do_create_d88_media(int drv, quint8 media_type, QString name) { } + virtual void do_create_hard_disk(int drv, int sector_size, int sectors, int surfaces, int cylinders, QString name) { } + void do_update_d88_list(int drv, int bank); + // Bubble Casette int write_protect_bubble(int drv, bool flag); @@ -744,11 +751,16 @@ public slots: void do_select_fixed_cpu(int num); void do_add_keyname_table(uint32_t vk, QString name); void do_clear_keyname_table(); - + void do_show_ram_size_dialog(void); + void do_block_task(); + void do_unblock_task(); + + void do_start_emu_thread(); + void do_start_draw_thread(); signals: int message_changed(QString); int quit_emu_thread(); - int call_joy_thread(EMU *); + int call_joy_thread(EMU_TEMPLATE *); int quit_joy_thread(); int quit_draw_thread(); int quit_emulator_all(); @@ -766,7 +778,7 @@ public slots: int closed(void); int sig_quit_all(void); int sig_vm_reset(void); - int sig_vm_specialreset(void); + int sig_vm_specialreset(int); int sig_check_grab_mouse(bool); int sig_resize_uibar(int, int); int sig_resize_screen(int, int); @@ -823,6 +835,12 @@ public slots: int sig_save_state(QString); int sig_emu_thread_to_fixed_cpu(int); int sig_add_keyname_table(uint32_t, QString); + + int sig_block_task(); + int sig_unblock_task(); + int sig_start_emu_thread(void); + int sig_start_draw_thread(void); + int sig_emu_launched(void); }; QT_END_NAMESPACE diff --git a/source/src/qt/gui/mainwindow_utils.cpp b/source/src/qt/gui/mainwindow_utils.cpp index d7b1c1762..f48d7debf 100644 --- a/source/src/qt/gui/mainwindow_utils.cpp +++ b/source/src/qt/gui/mainwindow_utils.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include "commonclasses.h" #include "mainwidget_base.h" @@ -18,6 +19,27 @@ #include "qt_dialogs.h" //#include "csp_logger.h" +void Ui_MainWindowBase::do_block_task(void) +{ + emit sig_block_task(); +} + +void Ui_MainWindowBase::do_unblock_task(void) +{ + emit sig_unblock_task(); +} + +void Ui_MainWindowBase::do_start_emu_thread(void) +{ + emit sig_start_emu_thread(); + emit sig_emu_launched(); +} + +void Ui_MainWindowBase::do_start_draw_thread(void) +{ + emit sig_start_draw_thread(); +} + void Ui_MainWindowBase::set_latency(int num) { if((num < 0) || (num >= 8)) return; @@ -209,6 +231,8 @@ void Ui_MainWindowBase::set_screen_aspect(int num) void Ui_MainWindowBase::ConfigDeviceType(void) { +// if(using_flags->is_use_variable_memory()) { +// } if(using_flags->get_use_device_type() > 0) { int ii; menuDeviceType = new QMenu(menuMachine); diff --git a/source/src/qt/gui/menu_compactdisc.cpp b/source/src/qt/gui/menu_compactdisc.cpp index cdb3a2bbd..a98dd2e0b 100644 --- a/source/src/qt/gui/menu_compactdisc.cpp +++ b/source/src/qt/gui/menu_compactdisc.cpp @@ -19,12 +19,22 @@ Menu_CompactDiscClass::Menu_CompactDiscClass(QMenuBar *root_entry, QString desc, { use_write_protect = false; use_d88_menus = false; + action_swap_byteorder = new Action_Control(p_wid, using_flags); + action_swap_byteorder->setVisible(true); + action_swap_byteorder->setCheckable(true); + action_swap_byteorder->setChecked(using_flags->is_cdaudio_swap_byteorder(drv)); + this->addAction(action_swap_byteorder); } Menu_CompactDiscClass::~Menu_CompactDiscClass() { } +void Menu_CompactDiscClass::do_swap_cdaudio_byteorder(bool flag) +{ + emit sig_swap_audio_byteorder(media_drive, flag); +} + void Menu_CompactDiscClass::create_pulldown_menu_device_sub(void) { // @@ -36,6 +46,8 @@ void Menu_CompactDiscClass::connect_menu_device_sub(void) connect(this, SIGNAL(sig_open_media(int, QString)), p_wid, SLOT(do_open_cdrom(int, QString))); connect(this, SIGNAL(sig_eject_media(int)), p_wid, SLOT(do_eject_cdrom(int))); connect(this, SIGNAL(sig_set_recent_media(int, int)), p_wid, SLOT(set_recent_cdrom(int, int))); + connect(action_swap_byteorder, SIGNAL(toggled(bool)), this, SLOT(do_swap_cdaudio_byteorder(bool))); + connect(this, SIGNAL(sig_swap_audio_byteorder(int, bool)), p_wid, SLOT(do_swap_cdaudio_byteorder(int, bool))); } @@ -46,6 +58,9 @@ void Menu_CompactDiscClass::retranslate_pulldown_menu_device_sub(void) action_eject->setText(QApplication::translate("MenuMedia", "Eject Compact Disc", 0)); action_eject->setToolTip(QApplication::translate("MenuMedia", "Eject a compact disc.", 0)); + action_swap_byteorder->setText(QApplication::translate("MenuMedia", "Swap byte order", 0)); + action_swap_byteorder->setToolTip(QApplication::translate("MenuMedia", "Swap audio track's byte order.\nThis is effects some ripped (not dedicated to AUDIO's endian) CD-ROMs.", 0)); + this->setTitle(QApplication::translate("MenuMedia", "CD ROM" , 0)); action_insert->setIcon(QIcon(":/icon_cd.png")); } diff --git a/source/src/qt/gui/menu_compactdisc.h b/source/src/qt/gui/menu_compactdisc.h index 125116651..53a9bd04d 100644 --- a/source/src/qt/gui/menu_compactdisc.h +++ b/source/src/qt/gui/menu_compactdisc.h @@ -15,14 +15,18 @@ QT_BEGIN_NAMESPACE class DLL_PREFIX Menu_CompactDiscClass: public Menu_MetaClass { Q_OBJECT protected: + Action_Control *action_swap_byteorder; public: Menu_CompactDiscClass(QMenuBar *root_entry, QString desc, USING_FLAGS *p, QWidget *parent = 0, int drv = 0, int base_drv = 1); ~Menu_CompactDiscClass(); void create_pulldown_menu_device_sub(); void connect_menu_device_sub(void); void retranslate_pulldown_menu_device_sub(void); + public slots: + void do_swap_cdaudio_byteorder(bool flag); signals: + int sig_swap_audio_byteorder(int, bool); }; QT_END_NAMESPACE diff --git a/source/src/qt/gui/menu_control.cpp b/source/src/qt/gui/menu_control.cpp index 265dbb3ad..5afe46dc7 100644 --- a/source/src/qt/gui/menu_control.cpp +++ b/source/src/qt/gui/menu_control.cpp @@ -24,6 +24,12 @@ void Object_Menu_Control::do_set_monitor_type() emit sig_monitor_type(getValue1()); } +void Object_Menu_Control::do_special_reset(void) +{ +// csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GUI, _T("Special reset #%d"), getValue1()); + emit sig_specialreset(getValue1()); +} + void Object_Menu_Control::set_boot_mode(void) { emit on_boot_mode(bindValue); } @@ -70,6 +76,12 @@ void Action_Control::do_save_state(void) emit sig_save_state(binds->getStringValue()); } +void Ui_MainWindowBase::do_special_reset(int num) +{ +// csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GUI, _T("Special reset #%d"), getValue1()); + emit sig_vm_specialreset(num); +} + void Ui_MainWindowBase::ConfigCpuSpeed(void) { actionSpeed_x1 = new Action_Control(this, using_flags); @@ -215,12 +227,22 @@ void Ui_MainWindowBase::ConfigControlMenu(void) actionReset = new Action_Control(this, using_flags); actionReset->setObjectName(QString::fromUtf8("actionReset")); connect(actionReset, SIGNAL(triggered()), - this, SLOT(OnReset())); // OK? + this, SLOT(OnReset())); // OK? + if(using_flags->is_use_special_reset()) { - actionSpecial_Reset = new Action_Control(this, using_flags); - actionSpecial_Reset->setObjectName(QString::fromUtf8("actionSpecial_Reset")); - connect(actionSpecial_Reset, SIGNAL(triggered()), - this, SLOT(OnSpecialReset())); // OK? + for(int i = 0; i < using_flags->get_use_special_reset_num(); i++) { + QString tmps; + tmps.setNum(i); + tmps = QString::fromUtf8("actionSpecial_Reset") + tmps; + actionSpecial_Reset[i] = new Action_Control(this, using_flags); + actionSpecial_Reset[i]->setObjectName(tmps); + actionSpecial_Reset[i]->binds->setValue1(i); + connect(actionSpecial_Reset[i], SIGNAL(triggered()), + actionSpecial_Reset[i]->binds, SLOT(do_special_reset())); // OK? + connect(actionSpecial_Reset[i]->binds, SIGNAL(sig_specialreset(int)), + this, SLOT(do_special_reset(int))); // OK? + if(i >= 15) break; + } } actionExit_Emulator = new Action_Control(this, using_flags); @@ -287,7 +309,10 @@ void Ui_MainWindowBase::connectActions_ControlMenu(void) { menuControl->addAction(actionReset); if(using_flags->is_use_special_reset()) { - menuControl->addAction(actionSpecial_Reset); + for(int i = 0; i < using_flags->get_use_special_reset_num(); i++) { + menuControl->addAction(actionSpecial_Reset[i]); + if(i >= 15) break; + } } menuControl->addSeparator(); menuControl->addAction(menuCpu_Speed->menuAction()); @@ -339,8 +364,9 @@ void Ui_MainWindowBase::createContextMenu(void) { addAction(actionReset); - if(using_flags->is_use_special_reset()) { - addAction(actionSpecial_Reset); + for(int i = 0; i < using_flags->get_use_special_reset_num(); i++) { + addAction(actionSpecial_Reset[i]); + if(i >= 15) break; } addAction(menuCpu_Speed->menuAction()); @@ -362,8 +388,11 @@ void Ui_MainWindowBase::retranslateControlMenu(const char *SpecialResetTitle, b actionReset->setToolTip(QApplication::translate("MenuControl", "Reset virtual machine.", 0)); actionReset->setIcon(ResetIcon); if(using_flags->is_use_special_reset()) { - actionSpecial_Reset->setText(QApplication::translate("MenuControl", SpecialResetTitle, 0)); - actionSpecial_Reset->setIcon(QIcon(":/icon_reset.png")); + for(int i = 0; i < using_flags->get_use_special_reset_num(); i++) { + actionSpecial_Reset[i]->setText(QApplication::translate("MenuControl", SpecialResetTitle, 0)); + actionSpecial_Reset[i]->setIcon(QIcon(":/icon_reset.png")); + if(i >= 15) break; + } } actionExit_Emulator->setText(QApplication::translate("MenuControl", "Exit Emulator", 0)); diff --git a/source/src/qt/gui/menu_emulator.cpp b/source/src/qt/gui/menu_emulator.cpp index 5a1265c68..c62e12be1 100644 --- a/source/src/qt/gui/menu_emulator.cpp +++ b/source/src/qt/gui/menu_emulator.cpp @@ -189,7 +189,7 @@ void Ui_MainWindowBase::rise_keyboard_dialog(void) for(auto i = phys_key_name_map.constBegin(); i != phys_key_name_map.constEnd(); ++i) { bool is_set = false; - if(!using_flags->is_notify_key_down_lr_shift()) { +// if(!using_flags->is_notify_key_down_lr_shift()) { if(i.key() == VK_SHIFT) { emit sig_add_keyname_table(VK_LSHIFT, i.value()); emit sig_add_keyname_table(VK_RSHIFT, i.value()); @@ -199,7 +199,7 @@ void Ui_MainWindowBase::rise_keyboard_dialog(void) emit sig_add_keyname_table(VK_RMENU, i.value()); is_set = true; } - } +// } if(i.key() == VK_CONTROL) { emit sig_add_keyname_table(VK_LCONTROL, i.value()); emit sig_add_keyname_table(VK_RCONTROL, i.value()); @@ -406,6 +406,7 @@ void Ui_MainWindowBase::ConfigEmulatorMenu(void) { int render_type = p_config->render_platform; int _major_version = p_config->render_major_version; + int _minor_version = p_config->render_minor_version; //int _minor_version = p_config->render_minor_version; // ToDo for(i = 0; i < MAX_RENDER_PLATFORMS; i++) { tmps = QString::number(i); @@ -419,9 +420,17 @@ void Ui_MainWindowBase::ConfigEmulatorMenu(void) action_SetRenderPlatform[i]->setVisible(false); } else { if(render_type == CONFIG_RENDER_PLATFORM_OPENGL_ES) { - if(_major_version >= 2) { - if(i == RENDER_PLATFORMS_OPENGL_ES_2) { - action_SetRenderPlatform[i]->setChecked(true); + if(_major_version == 3) { + if(_minor_version >= 1) { + if(i == RENDER_PLATFORMS_OPENGL_ES_31) { + action_SetRenderPlatform[i]->setChecked(true); + } + } + } else { + if(_major_version >= 2) { + if(i == RENDER_PLATFORMS_OPENGL_ES_2) { + action_SetRenderPlatform[i]->setChecked(true); + } } } } else if(render_type == CONFIG_RENDER_PLATFORM_OPENGL_MAIN) { @@ -590,11 +599,13 @@ void Ui_MainWindowBase::retranslateEmulatorMenu(void) } } action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL_ES_2]->setText(QApplication::translate("MenuEmulator", "OpenGL ES v2.0", 0)); + action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL_ES_31]->setText(QApplication::translate("MenuEmulator", "OpenGL ES v3.1", 0)); action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL3_MAIN]->setText(QApplication::translate("MenuEmulator", "OpenGLv3.0", 0)); action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL2_MAIN]->setText(QApplication::translate("MenuEmulator", "OpenGLv2.0", 0)); action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL_CORE]->setText(QApplication::translate("MenuEmulator", "OpenGL(Core profile)", 0)); action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL_ES_2]->setToolTip(QApplication::translate("MenuEmulator", "Using OpenGL ES v2.0.\nThis is recommanded.\nIf changed, need to restart this emulator.", 0)); + action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL_ES_31]->setToolTip(QApplication::translate("MenuEmulator", "Using OpenGL ES v3.1.\nThis is recommanded.\nIf changed, need to restart this emulator.", 0)); action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL3_MAIN]->setToolTip(QApplication::translate("MenuEmulator", "Using OpenGL v3.0(MAIN).\nThis is recommanded.\nIf changed, need to restart this emulator.", 0)); action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL2_MAIN]->setToolTip(QApplication::translate("MenuEmulator", "Using OpenGLv2.\nThis is fallback of some systems.\nIf changed, need to restart this emulator.", 0)); action_SetRenderPlatform[RENDER_PLATFORMS_OPENGL_CORE]->setToolTip(QApplication::translate("MenuEmulator", "Using OpenGL core profile.\nThis still not implement.\nIf changed, need to restart this emulator.", 0)); diff --git a/source/src/qt/gui/menu_flags.h b/source/src/qt/gui/menu_flags.h index 57e46ba06..570c9a957 100644 --- a/source/src/qt/gui/menu_flags.h +++ b/source/src/qt/gui/menu_flags.h @@ -11,6 +11,7 @@ #endif class EMU; +class EMU_TEMPLATE; class OSD; @@ -67,13 +68,19 @@ class DLL_PREFIX USING_FLAGS { int use_mouse_type; bool use_dipswitch; + bool use_ram_size; + int max_ram_size; + int min_ram_size; + uint32_t ram_size_order; + int use_drive_type; bool use_fd; int base_fd_num; int max_drive; int max_d88_banks; - + uint32_t floppy_type_bit; + int max_draw_ranges; bool use_joystick; @@ -120,7 +127,6 @@ class DLL_PREFIX USING_FLAGS { bool use_scanline; bool use_screen_rotate; - bool use_shift_numpad_key; int max_scsi; @@ -131,6 +137,7 @@ class DLL_PREFIX USING_FLAGS { bool use_sound_files_relay; bool use_special_reset; + int special_reset_num; bool use_state; @@ -158,8 +165,8 @@ class DLL_PREFIX USING_FLAGS { int screen_width_aspect; int screen_height_aspect; - bool notify_key_down_lr_shift; - + double custom_screen_zoom_factor; + bool tape_binary_only; int screen_mode_num; @@ -183,7 +190,7 @@ class DLL_PREFIX USING_FLAGS { button_desc_t *vm_buttons_d; vm_ranges_t *vm_ranges_d; - EMU *p_emu; + EMU_TEMPLATE *p_emu; OSD *p_osd; config_t *p_config; public: @@ -222,7 +229,24 @@ class DLL_PREFIX USING_FLAGS { bool is_use_compact_disc() { return use_compact_disc; } int get_max_cd() { return max_compact_disc; } int get_base_compact_disc_num() { return base_cd_num; } - + bool is_cdaudio_swap_byteorder(int drv) { + if((use_compact_disc) && (p_config != NULL) && (drv < USE_COMPACT_DISC_TMP) && (drv >= 0)) { + return p_config->swap_audio_byteorder[drv]; + } + return false; + } + + bool is_use_ram_size() { return use_ram_size; } + int get_max_ram_size() { return max_ram_size; } + int get_min_ram_size() { return min_ram_size; } + uint32_t get_ram_size_order() { return ram_size_order; } + int get_current_ram_size() { + if(p_config != NULL) { + return p_config->current_ram_size; + } + return -1; + } + bool is_use_debugger() { return use_debugger; } int get_use_device_type() { return use_device_type; } @@ -235,6 +259,7 @@ class DLL_PREFIX USING_FLAGS { int get_max_drive() { return max_drive; } int get_max_d88_banks() { return max_d88_banks; } int get_base_floppy_disk_num() { return base_fd_num; } + uint32_t get_floppy_type_bit() { return floppy_type_bit; } bool is_use_joystick() { return use_joystick; } bool is_use_joy_button_captions() { return use_joy_button_captions; } @@ -278,7 +303,6 @@ class DLL_PREFIX USING_FLAGS { bool is_use_scanline() { return use_scanline; } bool is_use_screen_rotate() { return use_screen_rotate; } - bool is_use_shift_numpad_key() { return use_shift_numpad_key; } int get_max_scsi() { return max_scsi; } @@ -288,6 +312,7 @@ class DLL_PREFIX USING_FLAGS { bool is_use_sound_files_fdd() { return use_sound_files_fdd; } bool is_use_sound_files_relay() { return use_sound_files_relay; } bool is_use_special_reset() { return use_special_reset; } + int get_use_special_reset_num() { return special_reset_num; } bool is_use_state() { return use_state; } @@ -313,12 +338,12 @@ class DLL_PREFIX USING_FLAGS { float get_screen_y_zoom() { return screen_y_zoom; } int get_screen_mode_num() { return screen_mode_num; } + double get_custom_screen_zoom_factor() { return custom_screen_zoom_factor; } int get_max_button() { return max_button; } int get_max_draw_ranges() { return max_ranges; } button_desc_t *get_vm_buttons() { return vm_buttons_d; } vm_ranges_t *get_draw_ranges() { return vm_ranges_d; } - bool is_notify_key_down_lr_shift() { return notify_key_down_lr_shift; } bool is_tape_binary_only() { return tape_binary_only; } bool is_machine_basicmaster_variants() { return machine_basicmaster_variants; } @@ -339,8 +364,8 @@ class DLL_PREFIX USING_FLAGS { virtual const _TCHAR *get_joy_button_captions(int num); virtual const _TCHAR *get_sound_device_caption(int num); virtual int get_s_freq_table(int num); - void set_emu(EMU *p); - EMU *get_emu(void); + void set_emu(EMU_TEMPLATE *p); + EMU_TEMPLATE *get_emu(void); void set_osd(OSD *p); OSD *get_osd(void); virtual const _TCHAR *get_sound_device_name(int num); diff --git a/source/src/qt/gui/menu_flags_tmpl.cpp b/source/src/qt/gui/menu_flags_tmpl.cpp index 0bf95e51f..9fd7e52dd 100644 --- a/source/src/qt/gui/menu_flags_tmpl.cpp +++ b/source/src/qt/gui/menu_flags_tmpl.cpp @@ -34,8 +34,13 @@ USING_FLAGS::USING_FLAGS(config_t *cfg) use_fd = false; max_drive = max_d88_banks = 0; - + floppy_type_bit = 0x00000000; + max_draw_ranges = 0; + use_ram_size = false; + max_ram_size = 1; + min_ram_size = 0; + ram_size_order = 1024 * 1024; use_joystick = use_joy_button_captions = false; num_joy_button_captions = 0; @@ -60,9 +65,8 @@ USING_FLAGS::USING_FLAGS(config_t *cfg) max_qd = 0; max_tape = 0; use_scanline = use_screen_rotate = false; - use_shift_numpad_key = false; screen_mode_num = 1; - + custom_screen_zoom_factor = 0.0; use_sound_device_type = 0; use_sound_volume = 0; @@ -71,6 +75,7 @@ USING_FLAGS::USING_FLAGS(config_t *cfg) use_sound_files_relay = false; use_special_reset = false; + special_reset_num = 0; use_state = false; @@ -148,7 +153,6 @@ USING_FLAGS::USING_FLAGS(config_t *cfg) base_qd_num = 1; use_scanline = use_screen_rotate = false; - use_shift_numpad_key = false; screen_mode_num = 1; @@ -176,15 +180,16 @@ USING_FLAGS::USING_FLAGS(config_t *cfg) screen_x_zoom = 1.0f; screen_y_zoom = 1.0f; - screen_width_aspect = WINDOW_WIDTH_ASPECT; - screen_height_aspect = WINDOW_HEIGHT_ASPECT; +#define _WINDOW_WIDTH_ASPECT 640 +#define _WINDOW_HEIGHT_ASPECT 480 + screen_width_aspect = _WINDOW_WIDTH_ASPECT; + screen_height_aspect = _WINDOW_HEIGHT_ASPECT; max_button = 0; vm_buttons_d = NULL; max_ranges = 0; vm_ranges_d = NULL; use_vertical_pixel_lines = false; - notify_key_down_lr_shift = false; tape_binary_only = false; device_name = QString::fromUtf8(""); config_name = QString::fromUtf8(""); @@ -256,12 +261,12 @@ _TCHAR *USING_FLAGS::get_vm_node_name(int id) return (_TCHAR *)"NODE"; } -void USING_FLAGS::set_emu(EMU *p) +void USING_FLAGS::set_emu(EMU_TEMPLATE *p) { p_emu = p; } -EMU *USING_FLAGS::get_emu(void) +EMU_TEMPLATE *USING_FLAGS::get_emu(void) { return p_emu; } diff --git a/source/src/qt/gui/menu_harddisk.cpp b/source/src/qt/gui/menu_harddisk.cpp index 557f594e7..c2889241b 100644 --- a/source/src/qt/gui/menu_harddisk.cpp +++ b/source/src/qt/gui/menu_harddisk.cpp @@ -24,16 +24,22 @@ Menu_HDDClass::~Menu_HDDClass() void Menu_HDDClass::create_pulldown_menu_device_sub(void) { + action_create_hdd = new Action_Control(p_wid, using_flags); + action_create_hdd->setVisible(true); + action_create_hdd->setCheckable(false); } void Menu_HDDClass::connect_menu_device_sub(void) { this->addSeparator(); + this->addAction(action_create_hdd); + this->addSeparator(); connect(this, SIGNAL(sig_open_media(int, QString)), p_wid, SLOT(_open_hard_disk(int, QString))); connect(this, SIGNAL(sig_eject_media(int)), p_wid, SLOT(eject_hard_disk(int))); connect(this, SIGNAL(sig_set_recent_media(int, int)), p_wid, SLOT(set_recent_hard_disk(int, int))); + connect(action_create_hdd, SIGNAL(triggered()), this, SLOT(do_open_dialog_create_hd())); } void Menu_HDDClass::retranslate_pulldown_menu_device_sub(void) @@ -45,4 +51,53 @@ void Menu_HDDClass::retranslate_pulldown_menu_device_sub(void) action_eject->setText(QApplication::translate("MenuHDD", "Unmount", 0)); action_eject->setToolTip(QApplication::translate("MenuHDD", "Unmount virtual hard disk.", 0)); + action_create_hdd->setText(QApplication::translate("MenuHDD", "Create Virtual HDD", 0)); + action_create_hdd->setToolTip(QApplication::translate("MenuHDD", "Create and mount virtual blank-hard disk.\nThis makes only NHD/HDI format.", 0)); } + +void Menu_HDDClass::do_open_dialog_create_hd() +{ + CSP_CreateHardDiskDialog dlg(media_drive, 512, 15, 4, 1024); + + if(initial_dir.isEmpty()) { + QDir dir; + char app[PATH_MAX]; + initial_dir = dir.currentPath(); + strncpy(app, initial_dir.toLocal8Bit().constData(), PATH_MAX - 1); + initial_dir = QString::fromLocal8Bit(get_parent_dir(app)); + } + dlg.dlg->setDirectory(initial_dir); + QString create_ext = QString::fromUtf8("*.nhd *.hdi"); + QString create_desc = QString::fromUtf8("Virtual HARDDISK Image."); + QString all = QString::fromUtf8("All Files (*.*)"); + QString tmps = create_desc; + tmps.append(QString::fromUtf8(" (")); + tmps.append(create_ext.toLower()); + tmps.append(QString::fromUtf8(" ")); + tmps.append(create_ext.toUpper()); + tmps.append(QString::fromUtf8(")")); + QStringList __filter; + __filter.clear(); + __filter << tmps; + __filter << all; + __filter.removeDuplicates(); + dlg.dlg->setNameFilters(__filter); + + tmps.clear(); + tmps = QApplication::translate("MenuMedia", "Create NHD/HDI Virtual HARDDISK", 0); + if(!window_title.isEmpty()) { + tmps = tmps + QString::fromUtf8(" ") + window_title; + } else { + tmps = tmps + QString::fromUtf8(" ") + this->title(); + } + dlg.dlg->setWindowTitle(tmps); + connect(&dlg, SIGNAL(sig_create_disk(int, int, int, int, int, QString)), + p_wid, SLOT(do_create_hard_disk(int, int, int, int, int, QString))); +// QObject::connect(&dlg, SIGNAL(sig_create_disk(QString)), this, SLOT(do_create_media(QString))); +// QObject::connect(this, SIGNAL(sig_create_d88_media(int, quint8, QString)), p_wid, SLOT(do_create_d88_media(int, quint8, QString))); + + dlg.show(); + dlg.dlg->exec(); + return; +} + diff --git a/source/src/qt/gui/menu_harddisk.h b/source/src/qt/gui/menu_harddisk.h index 0210dd0e1..6f8c5e8e6 100644 --- a/source/src/qt/gui/menu_harddisk.h +++ b/source/src/qt/gui/menu_harddisk.h @@ -16,12 +16,17 @@ QT_BEGIN_NAMESPACE class DLL_PREFIX Menu_HDDClass: public Menu_MetaClass { Q_OBJECT protected: + class Action_Control *action_create_hdd; public: Menu_HDDClass(QMenuBar *root_entry, QString desc, USING_FLAGS *p, QWidget *parent = 0, int drv = 0, int base_drv = 1); ~Menu_HDDClass(); void create_pulldown_menu_device_sub(); void connect_menu_device_sub(void); void retranslate_pulldown_menu_device_sub(void); +public slots: + void do_open_dialog_create_hd(); +signals: +// int sig_create_media(int, quint8, QString); }; QT_END_NAMESPACE diff --git a/source/src/qt/gui/menu_machine.cpp b/source/src/qt/gui/menu_machine.cpp index 0d64f23df..c1920ac40 100644 --- a/source/src/qt/gui/menu_machine.cpp +++ b/source/src/qt/gui/menu_machine.cpp @@ -36,6 +36,10 @@ void Ui_MainWindowBase::retranslateMachineMenu(void) QString tmps; QString tmps2; menuMachine->setTitle(QApplication::translate("MenuMachine", "Machine", 0)); + if(using_flags->is_use_ram_size()) { + action_RAMSize->setText(QApplication::translate("MenuMachine", "RAM Size", 0)); + action_RAMSize->setToolTip(QApplication::translate("MenuMachine", "Set (extra) memory size.\nThis will effect after restarting this emulator.", 0)); + } if(using_flags->get_use_device_type() > 0) { menuDeviceType->setTitle(QApplication::translate("MenuMachine", "Device Type", 0)); for(i = 0; i < using_flags->get_use_device_type(); i++) { @@ -103,4 +107,5 @@ void Ui_MainWindowBase::ConfigMonitorType(void) menuMonitorType->addAction(actionMonitorType[ii]); } } + } diff --git a/source/src/qt/gui/menu_main.cpp b/source/src/qt/gui/menu_main.cpp index 71a393cc8..96b67cb11 100644 --- a/source/src/qt/gui/menu_main.cpp +++ b/source/src/qt/gui/menu_main.cpp @@ -41,6 +41,7 @@ #include "menu_laserdisc.h" #include "menu_bubble.h" #include "dock_disks.h" +#include "dialog_memory.h" #include "qt_gldraw.h" //#include "emu.h" @@ -49,7 +50,6 @@ #include "csp_logger.h" #include "common.h" -extern EMU *emu; //extern USING_FLAGS *using_flags; void DLL_PREFIX _resource_init(void) { @@ -169,9 +169,19 @@ void Ui_MainWindowBase::do_set_window_focus_type(bool flag) } } +void Ui_MainWindowBase::do_show_ram_size_dialog(void) +{ + CSP_MemoryDialog *dlg = new CSP_MemoryDialog(using_flags, NULL); + dlg->show(); +} + void Ui_MainWindowBase::do_show_about(void) { - Dlg_AboutCSP *dlg = new Dlg_AboutCSP(using_flags, static_cast(this)); + QString renderStr; + if(graphicsView != NULL) { + renderStr = graphicsView->getRenderString(); + } + Dlg_AboutCSP *dlg = new Dlg_AboutCSP(using_flags, renderStr, static_cast(this)); dlg->show(); } @@ -298,6 +308,11 @@ void Ui_MainWindowBase::do_select_render_platform(int num) _major = 2; _minor = 0; break; + case RENDER_PLATFORMS_OPENGL_ES_31: + _type = CONFIG_RENDER_PLATFORM_OPENGL_ES; + _major = 3; + _minor = 1; + break; case RENDER_PLATFORMS_OPENGL3_MAIN: _type = CONFIG_RENDER_PLATFORM_OPENGL_MAIN; _major = 3; @@ -390,7 +405,18 @@ void Ui_MainWindowBase::setupUi(void) if(render_type == CONFIG_RENDER_PLATFORM_OPENGL_ES) { fmt.setRenderableType(QSurfaceFormat::OpenGLES); - csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Try to use OpenGL ES."); + if(p_config->render_major_version < 2) p_config->render_platform = 2; + if(p_config->render_major_version > 3) p_config->render_platform = 3; + if(p_config->render_major_version == 2) { + if(p_config->render_minor_version < 0) p_config->render_minor_version = 0; + if(p_config->render_minor_version > 1) p_config->render_minor_version = 1; + } else { + // major == 3 + if(p_config->render_minor_version < 0) p_config->render_minor_version = 0; + if(p_config->render_minor_version > 1) p_config->render_minor_version = 1; + } + fmt.setVersion(p_config->render_major_version , p_config->render_minor_version ); // Requires >=Qt-4.8.0 + csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Try to use OpenGL ES(v%d.%d).", p_config->render_major_version, p_config->render_minor_version); } else if(render_type == CONFIG_RENDER_PLATFORM_OPENGL_CORE) { fmt.setProfile(QSurfaceFormat::CoreProfile); // Requires >=Qt-4.8.0 fmt.setVersion(4, 7); // Requires >=Qt-4.8.0 @@ -553,6 +579,14 @@ void Ui_MainWindowBase::setupUi(void) actionMouseEnable, SLOT(do_check_grab_mouse(bool))); menuMachine->addAction(actionMouseEnable); } + if(using_flags->is_use_ram_size()) { + action_RAMSize = new Action_Control(this, using_flags); + menuMachine->addSeparator(); + menuMachine->addAction(action_RAMSize); + connect(action_RAMSize, SIGNAL(triggered()), this, SLOT(do_show_ram_size_dialog())); + menuMachine->addSeparator(); + } + ConfigDeviceType(); ConfigMouseType(); @@ -1016,7 +1050,7 @@ void Ui_MainWindowBase::do_toggle_mouse(void) { } -void Ui_MainWindowBase::LaunchEmuThread(void) +void Ui_MainWindowBase::LaunchEmuThread(EmuThreadClassBase *m) { } diff --git a/source/src/qt/gui/menu_metaclass.cpp b/source/src/qt/gui/menu_metaclass.cpp index f83185aae..74b29c2bc 100644 --- a/source/src/qt/gui/menu_metaclass.cpp +++ b/source/src/qt/gui/menu_metaclass.cpp @@ -455,7 +455,7 @@ void Menu_MetaClass::retranslateUi(void) retranslate_pulldown_menu_device_sub(); } -void Menu_MetaClass::setEmu(EMU *p) +void Menu_MetaClass::setEmu(EMU_TEMPLATE *p) { p_emu = p; } diff --git a/source/src/qt/gui/menu_metaclass.h b/source/src/qt/gui/menu_metaclass.h index 7a20f1514..c0b19f2dd 100644 --- a/source/src/qt/gui/menu_metaclass.h +++ b/source/src/qt/gui/menu_metaclass.h @@ -17,7 +17,7 @@ #include "config.h" #include "menu_flags.h" -class EMU; +class EMU_TEMPLATE; QT_BEGIN_NAMESPACE class QMenuBar; @@ -34,7 +34,7 @@ class DLL_PREFIX Menu_MetaClass : public QMenu { USING_FLAGS *using_flags; QWidget *p_wid; QMenuBar *menu_root; - EMU *p_emu; + EMU_TEMPLATE *p_emu; config_t *p_config; QMenu *menu_inner_media; @@ -88,7 +88,7 @@ class DLL_PREFIX Menu_MetaClass : public QMenu { void create_pulldown_menu(void); void retranslateUi(void); //void setTitle(QString); - void setEmu(EMU *p); + void setEmu(EMU_TEMPLATE *p); bool getWriteProtect(void) { return write_protect; diff --git a/source/src/qt/gui/menu_screen.cpp b/source/src/qt/gui/menu_screen.cpp index 658fe7865..3ab4820c4 100644 --- a/source/src/qt/gui/menu_screen.cpp +++ b/source/src/qt/gui/menu_screen.cpp @@ -143,12 +143,40 @@ void Ui_MainWindowBase::ConfigScreenMenu_List(void) actionGroup_ScreenSize = new QActionGroup(this); actionGroup_ScreenSize->setExclusive(true); screen_mode_count = 0; - for(i = 0; i < using_flags->get_screen_mode_num(); i++) { - w = (int)(screen_multiply_table[i] * (double)using_flags->get_screen_width()); - h = (int)(screen_multiply_table[i] * (double)using_flags->get_screen_height()); + int ix = 0; + double _iimul = 1.0; + double _zmul = using_flags->get_custom_screen_zoom_factor(); + double _mul = screen_multiply_table[ix]; + for(i = 0; i < using_flags->get_screen_mode_num();i++) { + double _ymul = _zmul * _iimul; + _ymul = _zmul * _iimul; + if((_mul == 0.5) && (i > 0) && (_zmul > 0.0)) { + _mul = _mul * _zmul; + } else if((_ymul > 0.0) && (_ymul < screen_multiply_table[ix + 1]) /*&& (ix > 0)*/) { + if(screen_multiply_table[ix + 1] != 0.0) { + if(_ymul < screen_multiply_table[ix]) { + _mul = _ymul; + _iimul = _iimul + 1.0; + } else { + _mul = screen_multiply_table[ix]; + ix++; + } + } else { + _mul = _ymul; + _iimul = _iimul + 1.0; + } + } else { + _mul = screen_multiply_table[ix]; + ix++; + } + w = (int)(_mul * (double)using_flags->get_screen_width()); + h = (int)(_mul * (double)using_flags->get_screen_height()); if((w <= 0) || (h <= 0)) { break; } + if((w >= 16000) || (h >= 10000)) { + break; + } screen_mode_count++; tmps = QString::number(i); actionScreenSize[i] = new Action_Control(this, using_flags); @@ -159,7 +187,7 @@ void Ui_MainWindowBase::ConfigScreenMenu_List(void) if(i == p_config->window_mode) actionScreenSize[i]->setChecked(true); // OK? actionGroup_ScreenSize->addAction(actionScreenSize[i]); - actionScreenSize[i]->binds->setDoubleValue(screen_multiply_table[i]); + actionScreenSize[i]->binds->setDoubleValue(_mul); connect(actionScreenSize[i], SIGNAL(triggered()), actionScreenSize[i]->binds, SLOT(set_screen_size())); @@ -472,7 +500,8 @@ void Ui_MainWindowBase::retranslateScreenMenu(void) double s_mul; for(i = 0; i < using_flags->get_screen_mode_num(); i++) { if(actionScreenSize[i] == NULL) continue; - s_mul = screen_multiply_table[i]; + s_mul = actionScreenSize[i]->binds->getDoubleValue(); +; if(s_mul <= 0) break; tmps = QString::number(s_mul); tmps = QString::fromUtf8("x", -1) + tmps; diff --git a/source/src/qt/gui/qt_dialogs.cpp b/source/src/qt/gui/qt_dialogs.cpp index 0e408dcd5..b8867f97c 100644 --- a/source/src/qt/gui/qt_dialogs.cpp +++ b/source/src/qt/gui/qt_dialogs.cpp @@ -72,3 +72,146 @@ CSP_CreateDiskDialog::CSP_CreateDiskDialog(bool *masks, QWidget *parent) : QWidg } +CSP_CreateHardDiskDialog::CSP_CreateHardDiskDialog(int drive, int sector_size, int sectors, int surfaces, int cylinders, QWidget *parent) : QWidget(parent) +{ + dlg = new QFileDialog(NULL, Qt::Widget); + dlg->setParent(this); + dlg->setOption(QFileDialog::ReadOnly, false); + dlg->setOption(QFileDialog::DontConfirmOverwrite, false); + dlg->setOption(QFileDialog::DontUseNativeDialog, true); + dlg->setAcceptMode(QFileDialog::AcceptSave); + dlg->setFileMode(QFileDialog::AnyFile); + + if(sector_size < 0) sector_size = 0; + if(sector_size > 4) sector_size = 4; + _sector_size.addItem(QString::fromUtf8("256bytes")); + _sector_size.addItem(QString::fromUtf8("512bytes")); + _sector_size.addItem(QString::fromUtf8("1024bytes")); + _sector_size.addItem(QString::fromUtf8("2048bytes")); + _sector_size.addItem(QString::fromUtf8("4096bytes")); + _sectors.setRange(15, 33); + _surfaces.setRange(2, 16); + _cylinders.setRange(128, 16383); + + _label_sector_size.setText(QString::fromUtf8("Sector Size")); + _label_sectors.setText(QString::fromUtf8("Sector in cylinder")); + _label_surfaces.setText(QString::fromUtf8("Heads")); + _label_cylinders.setText(QString::fromUtf8("Cylinders")); + _label_preset_type.setText(QString::fromUtf8("Preset size")); + media_drv = drive; + + if(sectors < 15) sectors = 15; + if(sectors > 33) sectors = 33; + if(surfaces < 2) surfaces = 2; + if(surfaces > 16) surfaces = 16; + if(cylinders < 128) cylinders = 128; + if(cylinders > 16383) cylinders = 16383; + + // Preset: + // 10MB + // 20MB + // 40MB + // 80MB + // 100MB + // 200MB + // 320MB + // 500MB + // 540MB + _preset_type.addItem(QString::fromUtf8("10MB")); + _preset_type.addItem(QString::fromUtf8("20MB")); + _preset_type.addItem(QString::fromUtf8("40MB")); + _preset_type.addItem(QString::fromUtf8("80MB")); + _preset_type.addItem(QString::fromUtf8("100MB")); + _preset_type.addItem(QString::fromUtf8("200MB")); + _preset_type.addItem(QString::fromUtf8("320MB")); + _preset_type.addItem(QString::fromUtf8("500MB")); + _preset_type.addItem(QString::fromUtf8("540MB")); + _size_label_label.setText(QString::fromUtf8("Total Size:")); + + layout.addWidget(&_label_preset_type, 1, 0); + layout.addWidget(&_preset_type, 1, 1); + layout.addWidget(&_label_sector_size, 2, 0); + layout.addWidget(&_sector_size, 2, 1); + layout.addWidget(&_label_sectors, 2, 2); + layout.addWidget(&_sectors, 2, 3); + + layout.addWidget(&_label_surfaces, 3, 0); + layout.addWidget(&_surfaces, 3, 1); + layout.addWidget(&_label_cylinders, 3, 2); + layout.addWidget(&_cylinders, 3, 3); + layout.addWidget(&_size_label_label, 4, 2); + layout.addWidget(&_size_label, 4, 3); + layout.addWidget(dlg, 5, 0, 5, 4); + + this->setLayout(&layout); + connect(&_preset_type, SIGNAL(activated(int)), this, SLOT(do_preset(int))); + connect(this, SIGNAL(sig_update_total_size(uint64_t)), this, SLOT(do_update_total_size(uint64_t))); +// connect(&_sector_size, SIGNAL(activated(int)), this, SLOT(do_change_sector_size(int))); + connect(&_sector_size, SIGNAL(activated(int)), this, SLOT(do_update_values(int))); + connect(&_sectors, SIGNAL(valueChanged(int)), this, SLOT(do_update_values(int))); + connect(&_surfaces, SIGNAL(valueChanged(int)), this, SLOT(do_update_values(int))); + connect(&_cylinders, SIGNAL(valueChanged(int)), this, SLOT(do_update_values(int))); + connect(dlg, SIGNAL(fileSelected(QString)), this, SLOT(do_create_disk(QString))); + + do_preset(0); // Update label. +} + +void CSP_CreateHardDiskDialog::do_create_disk(QString filename) +{ + int secnum = _sector_size.currentIndex(); + if(secnum < 0) secnum = 0; + if(secnum > 4) secnum = 4; + static const uint64_t valtbl_sec[] = { 256, 512, 1024, 2048, 4096 }; + int secsize = valtbl_sec[secnum]; + int secs = _sectors.value(); + int heads = _surfaces.value(); + int cyl = _cylinders.value(); +// printf("ToDo: Will create media.Filename = %s SEC_SIZE=%d SECS=%d SURFACES=%d CYL=%d\n", +// filename.toLocal8Bit().constData(), secsize, secs, heads, cyl); + + emit sig_create_disk(media_drv, secsize, secs, heads, cyl, filename); +} + +void CSP_CreateHardDiskDialog::do_update_values(int dummy) +{ + int secnum = _sector_size.currentIndex(); + int heads = _surfaces.value(); + int secs = _sectors.value(); + int cyl = _cylinders.value(); + static const uint64_t secsize[] = {256, 512, 1024, 2048, 4096}; + if(secnum < 0) secnum = 0; + if(secnum > 4) secnum = 4; + uint64_t totalsize = (secsize[secnum] * (uint64_t)secs * (uint64_t)heads * (uint64_t)cyl); + do_update_total_size(totalsize); +} +void CSP_CreateHardDiskDialog::do_preset(int num) +{ + if(num >= _preset_type.count()) num = _preset_type.count() - 1; + if(num < 0) num = 0; + + static const uint64_t valtbl[] = { 10, 20, 40, 80, 100, 200, 320, 500, 540 }; + uint64_t total_size = valtbl[num] * 1024 * 1024; + uint64_t sectors_in_track = 15; + uint64_t __heads = 4; + uint64_t cyl; + if(total_size > (100 * 1024 * 1024)) { + sectors_in_track = 33; + __heads = 8; + } + if(total_size > (300 * 1024 * 1024)) { + __heads = 15; + } + cyl = (total_size / (512 * sectors_in_track * __heads)) + 1; + _sector_size.setCurrentIndex(1); // 512bytes + _sectors.setValue((int)sectors_in_track); + _surfaces.setValue((int)__heads); + _cylinders.setValue((int)cyl); + emit sig_update_total_size(total_size); +} + +void CSP_CreateHardDiskDialog::do_update_total_size(uint64_t size) +{ + uint64_t nsize = size / (1024 * 1024); + QString label = QString("%1MB (%2bytes)").arg(nsize).arg(size); + _size_label.setText(label); +} diff --git a/source/src/qt/gui/qt_dialogs.h b/source/src/qt/gui/qt_dialogs.h index ba860efab..f4099b5ab 100644 --- a/source/src/qt/gui/qt_dialogs.h +++ b/source/src/qt/gui/qt_dialogs.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -97,6 +98,42 @@ public slots: } }; +class CSP_CreateHardDiskDialog : public QWidget { + Q_OBJECT + QComboBox _preset_type; + QComboBox _sector_size; + QSpinBox _sectors; + QSpinBox _surfaces; + QSpinBox _cylinders; + + QLabel _label_preset_type; + QLabel _label_sector_size; + QLabel _label_sectors; + QLabel _label_surfaces; + QLabel _label_cylinders; + QLabel type_label; + QLabel _size_label_label; + QLabel _size_label; + + QGridLayout layout; + + int media_drv; +public: + QFileDialog* dlg; + CSP_CreateHardDiskDialog(int drive, int secsize, int sectors, int surfaces, int cylinders, QWidget *parent = 0); + ~CSP_CreateHardDiskDialog() { + delete dlg; + } +signals: + int sig_update_total_size(uint64_t); + int sig_create_disk(int, int, int, int, int, QString); +public slots: + void do_preset(int num); + void do_update_total_size(uint64_t size); + void do_create_disk(QString filename); + void do_update_values(int dummy); +}; + QT_END_NAMESPACE #endif //End. diff --git a/source/src/qt/gui/qt_drawitem.cpp b/source/src/qt/gui/qt_drawitem.cpp index 6da412bc5..38eb09db7 100644 --- a/source/src/qt/gui/qt_drawitem.cpp +++ b/source/src/qt/gui/qt_drawitem.cpp @@ -97,13 +97,23 @@ void CSP_DrawItem::drawFloppy5Inch(QColor &BGColor, QColor &FGColor, QColor &FGC this->fill(BGColor); { double _nwidth = (__width > __height) ? (__height - 2.0) : (__width - 2.0) ; - _nwidth = _nwidth * (0.88 * 0.90); + //_nwidth = _nwidth * (0.88 * 0.90); + _nwidth = _nwidth * 0.88; painter.begin(this); int xbase = (int)((__width - _nwidth) / 2.0); int ybase = (int)((__height - _nwidth) * 0.5); int wbase = (int)_nwidth; int hbase = wbase; - drawRectItem(xbase, ybase, wbase, hbase, fill_brush, FGColor, FGColor); + { + //QPointF points[4] = { + // QPointF((float)xbase, (float)ybase), + // QPointF((float)(xbase + wbase), (float)ybase), + // QPointF((float)(xbase + wbase), (float)(ybase + hbase)), + // QPointF((float)(xbase), (float)(ybase + hbase)) + //}; + //drawPolygonItem(points, 4, fill_brush, FGColor, FGColor); + drawRectItem(xbase, ybase, wbase, hbase, fill_brush, FGColor, FGColor); + } { int r = (int)((_nwidth * 0.35) / 2.0); int x = xbase + wbase / 2 - r; @@ -122,6 +132,13 @@ void CSP_DrawItem::drawFloppy5Inch(QColor &BGColor, QColor &FGColor, QColor &FGC int x = (xbase + wbase / 2) - (int)(w / 2.0); int y = (ybase + wbase / 2) + (int)(_nwidth * 0.45 / 2.0); drawRectItem(x, y, w, h, fill_brush, FGColor2, FGColor2); +// QPointF points[4] = { +// QPointF((float)x, (float)y), +// QPointF((float)(x+ w), (float)y), +// QPointF((float)(x + w), (float)(y + h)), +// QPointF((float)(x), (float)(y + h)) +// }; +// drawPolygonItem(points, 4, fill_brush, FGColor2, FGColor2); } if(!text.isEmpty()) { int x = xbase + (int)(_nwidth * 0.65); diff --git a/source/src/qt/gui/qt_emuevents.h b/source/src/qt/gui/qt_emuevents.h index 05816181f..b2686df84 100644 --- a/source/src/qt/gui/qt_emuevents.h +++ b/source/src/qt/gui/qt_emuevents.h @@ -13,7 +13,5 @@ //#include "emu.h" #include "fileio.h" #include "config.h" -class EMU; -extern EMU *emu; #endif // End diff --git a/source/src/qt/gui/qt_gldraw.cpp b/source/src/qt/gui/qt_gldraw.cpp index eef9217e9..0c766f53d 100644 --- a/source/src/qt/gui/qt_gldraw.cpp +++ b/source/src/qt/gui/qt_gldraw.cpp @@ -19,7 +19,7 @@ #include #include #endif -#include +//#include #ifdef USE_OPENMP @@ -90,12 +90,17 @@ void GLDrawClass::paintGL(void) extfunc->resizeGL(draw_width, draw_height); delay_update = false; } - //extfunc->paintGL(); } emit sig_draw_timing(); SaveToPixmap(); // If save requested, then Save to Pixmap. } +bool GLDrawClass::copy_screen_buffer(scrntype_t* target, int w, int h, int stride) +{ + if(extfunc == NULL) return false; + return extfunc->copy_screen_buffer(target, w, h, stride); +} + scrntype_t* GLDrawClass::get_screen_buffer(int y) { if(extfunc == NULL) return NULL; @@ -129,7 +134,6 @@ GLDrawClass::GLDrawClass(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent, co csp_logger = logger; save_pixmap_req = false; enable_mouse = true; - p_emu = NULL; using_flags = p; p_config = p->get_config_ptr(); @@ -243,3 +247,31 @@ const bool GLDrawClass::is_ready_to_map_vram_texture(void) if(extfunc == NULL) return false; return extfunc->is_ready_to_map_vram_texture(); } + +QString GLDrawClass::getRenderString() +{ + QString s; + QString _head; + QOpenGLContext *ctx; + ctx = context(); + if(ctx != NULL) { + QSurfaceFormat fmt = ctx->format(); + int major = fmt.majorVersion(); + int minor = fmt.minorVersion(); + if(ctx->isOpenGLES()) { + _head = QString::fromUtf8("OpenGL ES v"); + } else { + if(fmt.profile() == QSurfaceFormat::CoreProfile) { + _head = QString::fromUtf8("OpenGL (Core) v"); + } else { + _head = QString::fromUtf8("OpenGL (Main) v"); + } + } + s = QString::fromUtf8("Host: "); + s = s + _head + QString::number(major) + + QString::fromUtf8(".") + QString::number(minor) + QString::fromUtf8("
"); + } else { + s = QString::fromUtf8("Host: NOT OpenGL
"); + } + return s + render_string; +} diff --git a/source/src/qt/gui/qt_gldraw.h b/source/src/qt/gui/qt_gldraw.h index 217172d9f..d4897d2b2 100644 --- a/source/src/qt/gui/qt_gldraw.h +++ b/source/src/qt/gui/qt_gldraw.h @@ -19,8 +19,8 @@ #include #include #include +#include -class EMU; class QEvent; class GLDraw_Tmpl; class CSP_KeyTables; @@ -40,7 +40,6 @@ class DLL_PREFIX GLDrawClass: public QOpenGLWidget { Q_OBJECT private: - EMU *p_emu; CSP_Logger *csp_logger; USING_FLAGS *using_flags; config_t *p_config; @@ -53,10 +52,11 @@ class DLL_PREFIX GLDrawClass: public QOpenGLWidget int draw_height; bool delay_update; - + protected: bool run_vm; - + QString render_string; + void keyReleaseEvent(QKeyEvent *event); void keyPressEvent(QKeyEvent *event); void initializeGL(); @@ -112,6 +112,9 @@ class DLL_PREFIX GLDrawClass: public QOpenGLWidget GLuint get_mapped_buffer_num(int region); scrntype_t* get_screen_buffer(int y); + bool copy_screen_buffer(scrntype_t* target, int w, int h, int stride); + + virtual QString getRenderString(); public slots: void initKeyCode(void); void releaseKeyCode(void); @@ -156,7 +159,7 @@ public slots: signals: void update_screenChanged(int tick); - void do_notify_move_mouse(int x, int y); + void do_notify_move_mouse(int x, int y, int globalx, int globaly); void sig_toggle_mouse(void); void do_notify_button_pressed(Qt::MouseButton button); diff --git a/source/src/qt/gui/qt_glevents.cpp b/source/src/qt/gui/qt_glevents.cpp index a9f038cd9..87ad74657 100644 --- a/source/src/qt/gui/qt_glevents.cpp +++ b/source/src/qt/gui/qt_glevents.cpp @@ -43,13 +43,15 @@ void GLDrawClass::setEnableMouse(bool enable) void GLDrawClass::mouseMoveEvent(QMouseEvent *event) { - double xx; - double yy; + double xx, gxx; + double yy, gyy; int d_ww = using_flags->get_screen_width(); int d_hh = using_flags->get_screen_height(); QPointF pos = event->localPos(); double xpos = (double)(pos.x()) / (double)width(); double ypos = (double)(pos.y()) / (double)height(); + double gxpos = (double)(event->globalPos().x()) / (double)width(); + double gypos = (double)(event->globalPos().y()) / (double)height(); //printf("@@ %d %d\n", pos.x(), pos.y()); if(using_flags->is_use_one_board_computer() || using_flags->is_use_mouse() || (using_flags->get_max_button() > 0)) { if(!enable_mouse) return; @@ -60,31 +62,43 @@ void GLDrawClass::mouseMoveEvent(QMouseEvent *event) case 0: xx = xpos * (double)d_ww; yy = ypos * (double)d_hh; + gxx = gxpos * (double)d_ww; + gyy = gypos * (double)d_hh; break; case 2: xx = (1.0 - xpos) * (double)d_ww; yy = (1.0 - ypos) * (double)d_hh; + gxx = (1.0 - gxpos) * (double)d_ww; + gyy = (1.0 - gypos) * (double)d_hh; break; case 1: xx = ypos * (double)d_ww; yy = (1.0 - xpos) * (double)d_hh; + gxx = gypos * (double)d_ww; + gyy = (1.0 - gxpos) * (double)d_hh; break; case 3: xx = (1.0 - ypos) * (double)d_ww; yy = xpos * (double)d_hh; + gxx = (1.0 - gypos) * (double)d_ww; + gyy = gxpos * (double)d_hh; break; default: xx = xpos * (double)d_ww; yy = ypos * (double)d_hh; + gxx = gxpos * (double)d_ww; + gyy = gypos * (double)d_hh; break; } } else { xx = xpos * (double)d_ww; yy = ypos * (double)d_hh; + gxx = gxpos * (double)d_ww; + gyy = gypos * (double)d_hh; } //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Mouse Move: (%f,%f) -> (%d, %d)\n", xpos, ypos, (int)xx, (int)yy); - emit do_notify_move_mouse((int)xx, (int)yy); + emit do_notify_move_mouse((int)xx, (int)yy, (int)gxx, (int)gyy); } // Will fix. zap of emu-> or ?? diff --git a/source/src/qt/gui/qt_glpack.cpp b/source/src/qt/gui/qt_glpack.cpp index c3de8ead3..7a5392d6e 100644 --- a/source/src/qt/gui/qt_glpack.cpp +++ b/source/src/qt/gui/qt_glpack.cpp @@ -10,7 +10,7 @@ #include "common.h" #include "qt_glpack.h" -GLScreenPack::GLScreenPack(int _width, int _height, QString _name, QObject *parent, bool is_float, bool req_high_presicion) : QObject(parent) +GLScreenPack::GLScreenPack(int _width, int _height, QString _name, QObject *parent, bool is_float, bool req_high_presicion, bool need_alpha) : QObject(parent) { program = new QOpenGLShaderProgram(this); @@ -52,7 +52,7 @@ GLScreenPack::GLScreenPack(int _width, int _height, QString _name, QObject *pare has_extension_texture_float = false; has_extension_texture_half_float = false; has_extension_fragment_high_precision = false; - + need_alpha_channel = need_alpha; log_str.clear(); //genBuffer(_width, _height); } @@ -93,25 +93,40 @@ void GLScreenPack::genBuffer(int width, int height) } _fn.glGenTextures(1, &Texture); _fn.glBindTexture(GL_TEXTURE_2D, Texture); + + GLuint internal_format; + GLuint out_format; + GLuint value_type; + internal_format = (need_alpha_channel) ? GL_RGBA32F : GL_RGB32F; + out_format = (need_alpha_channel) ? GL_RGBA : GL_RGB; + value_type = GL_FLOAT; if(context->isOpenGLES()) { if(texture_is_float) { if((context->hasExtension(QByteArray("GL_OES_texture_half_float"))) && !(texture_is_high_presicion)) { - has_extension_texture_half_float = true; - _fn.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); - push_log("GLES: Using half float texture."); + internal_format = (need_alpha_channel) ? GL_RGBA16F : GL_RGB16F; + has_extension_texture_half_float = true; + has_extension_texture_float = true; + push_log("GLES: Using half float texture."); } else if(context->hasExtension(QByteArray("GL_OES_texture_float"))) { + has_extension_texture_half_float = false; has_extension_texture_float = true; - _fn.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); push_log("GLES: Using float texture."); } else { - _fn.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + has_extension_texture_half_float = false; + has_extension_texture_float = false; + internal_format = (need_alpha_channel) ? GL_RGBA : GL_RGB; + value_type = GL_UNSIGNED_BYTE; push_log("GLES: Using unsigned integer (UNSIGNED_BYTE) texture."); } } else { // Not Float - _fn.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - push_log("GLES: Using unsigned integer (UNSIGNED_BYTE) texture."); + has_extension_texture_half_float = false; + has_extension_texture_float = false; + internal_format = (need_alpha_channel) ? GL_RGBA : GL_RGB; + value_type = GL_UNSIGNED_BYTE; + push_log("GLES: Using unsigned integer (UNSIGNED_BYTE) texture."); } + _fn.glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, out_format, value_type, 0); if(context->hasExtension("GL_OES_fragment_precision_high")) { has_extension_fragment_high_precision = true; push_log("GLES: Using high precision storage."); @@ -121,17 +136,18 @@ void GLScreenPack::genBuffer(int width, int height) if(texture_is_float) { if(context->hasExtension("GL_ARB_half_float_pixel") && !(texture_is_high_presicion)) { has_extension_texture_half_float = true; - _fn.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, 0); + internal_format = (need_alpha_channel) ? GL_RGBA16F : GL_RGB16F; push_log("GL: Using half float texture."); } else { has_extension_texture_float = true; - _fn.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, 0); push_log("GL: Using float texture."); } } else { - _fn.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + internal_format = (need_alpha_channel) ? GL_RGBA : GL_RGB; + value_type = GL_UNSIGNED_BYTE; push_log("GL: Using unsigned integer (UNSIGNED_BYTE) texture."); - } + } + _fn.glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, out_format, value_type, 0); } _fn.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); _fn.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); diff --git a/source/src/qt/gui/qt_glpack.h b/source/src/qt/gui/qt_glpack.h index 5df9206a4..7ff5a8188 100644 --- a/source/src/qt/gui/qt_glpack.h +++ b/source/src/qt/gui/qt_glpack.h @@ -59,11 +59,12 @@ class GLScreenPack : public QObject bool shader_status; bool texture_is_float; bool texture_is_high_presicion; + bool need_alpha_channel; bool has_extension_texture_float; bool has_extension_texture_half_float; bool has_extension_fragment_high_precision; - + QString obj_name; QStringList log_str; void genBuffer(int width, int height); @@ -71,7 +72,7 @@ class GLScreenPack : public QObject void push_log(const char *s) { log_str.append(QString::fromUtf8(s)); } public: GLScreenPack(int _width, int _height, QString _name = QString::fromUtf8(""), QObject *parent = NULL, - bool is_float = false, bool req_high_presicion = false); + bool is_float = false, bool req_high_presicion = false, bool need_alpha = true); ~GLScreenPack(); virtual bool initialize(int total_width, int total_height, const QString &vertex_shader_file, const QString &fragment_shader_file, diff --git a/source/src/qt/gui/qt_glutil.cpp b/source/src/qt/gui/qt_glutil.cpp index 583678fdf..e6a3195f3 100644 --- a/source/src/qt/gui/qt_glutil.cpp +++ b/source/src/qt/gui/qt_glutil.cpp @@ -81,7 +81,8 @@ void GLDrawClass::do_update_icon(int icon_type, int localnum, QString message, Q draw_item->clearCanvas(nullColor); break; case 1: - draw_item->drawFloppy5Inch(bg, fg, fg2, tg, pt, message); + draw_item->drawFloppy5Inch(bg, fg3, fg2, tg, pt, message); + icon_type = 2; // Workaround break; case 2: draw_item->drawFloppy3_5Inch(bg, fg3, fg2, fg, tg, pt, message); @@ -151,13 +152,17 @@ void GLDrawClass::initializeGL(void) } if(using_flags->is_use_fd()) { int drvs = using_flags->get_max_drive(); + uint32_t drvbit = using_flags->get_floppy_type_bit(); QString ts, tmps; for(int i = 0; i < drvs; i++) { tmps = QString::fromUtf8(""); ts.setNum(i); tmps = tmps + ts + QString::fromUtf8(":"); - do_update_icon(1, i, tmps, BG, FG, FG2, FG3, LG, TG, 12.0f); // Dedicate to 3.5/5/8? and startnum. - do_update_icon(2, i, tmps, BG, FG, FG2, FG3, LG, TG2, 12.0f); // Dedicate to 3.5/5/8? and startnum. + if((drvbit & (1 << i)) == 0) { + do_update_icon(1, i, tmps, BG, FG, FG2, FG3, LG, TG2, 12.0f); // Dedicate to 3.5/5/8? and startnum. + } else { + do_update_icon(2, i, tmps, BG, FG, FG2, FG3, LG, TG2, 12.0f); // Dedicate to 3.5/5/8? and startnum. + } } } if(using_flags->is_use_qd()) { @@ -183,8 +188,8 @@ void GLDrawClass::initializeGL(void) tmps = QString::fromUtf8(""); ts.setNum(i + 1); tmps = tmps + ts; - do_update_icon(4, i, tmps, R_BG, C_FG, C_FG2, C_FG3, LG, C_TG, 12.0f); // Dedicate to 3.5/5/8? and startnum. - do_update_icon(5, i, tmps, W_BG, C_FG, C_FG2, C_FG3, LG, C_TG, 12.0f); // Dedicate to 3.5/5/8? and startnum. + do_update_icon(4, i, tmps, R_BG, C_FG, C_FG2, C_FG3, LG, C_TG, 12.0f); + do_update_icon(5, i, tmps, W_BG, C_FG, C_FG2, C_FG3, LG, C_TG, 12.0f); } } } @@ -293,11 +298,26 @@ void GLDrawClass::InitFBO(void) #endif if((render_type == CONFIG_RENDER_PLATFORM_OPENGL_ES) || (glContext->isOpenGLES())){ QPair _glversion = _fmt.version(); + if(_major_version >= 3) { + if((_glversion.first >= 3) && + (extfunc == NULL)) { + if(_glversion.second >= 1) { + extfunc = new GLDraw_ES_2(this, using_flags, csp_logger); + if(extfunc != NULL) { + _major_version = 3; + csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Use OpenGL ES(v3.1) Renderer"); + goto _nr_end; + } + } + } + } if((_glversion.first >= 2) && (_glversion.second >= 0) && (extfunc == NULL) && (_major_version >= 2)){ extfunc = new GLDraw_ES_2(this, using_flags, csp_logger); if(extfunc != NULL) { + _major_version = 2; + _minor_version = 0; csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Use OpenGL ES(v2.0) Renderer"); goto _nr_end; } @@ -310,6 +330,9 @@ void GLDrawClass::InitFBO(void) ((_major_version >= 5) || ((_major_version == 4) && (_minor_version >= 3)))){ extfunc = new GLDraw_4_5(this, using_flags, csp_logger); // ToDo if(extfunc != NULL) { + _major_version = 4; + _minor_version = 5; + render_type = CONFIG_RENDER_PLATFORM_OPENGL_CORE; csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Use OpenGL v4.5(CORE) Renderer"); goto _nr_end; } @@ -321,7 +344,10 @@ void GLDrawClass::InitFBO(void) (_major_version >= 3)){ extfunc = new GLDraw_3_0(this, using_flags, csp_logger); if(extfunc != NULL) { + _major_version = 3; + _minor_version = 0; csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Use OpenGL v3.0 Renderer"); + render_type = CONFIG_RENDER_PLATFORM_OPENGL_MAIN; goto _nr_end; } } @@ -331,13 +357,32 @@ void GLDrawClass::InitFBO(void) } extfunc = new GLDraw_2_0(this, using_flags, csp_logger); if(extfunc != NULL) { + _major_version = 2; + _minor_version = 0; csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Use OpenGL v2.0 Renderer"); + render_type = CONFIG_RENDER_PLATFORM_OPENGL_MAIN; goto _nr_end; } } } _nr_end: if(extfunc != NULL) { + if((render_type != CONFIG_RENDER_PLATFORM_OPENGL_MAIN) && + (render_type != CONFIG_RENDER_PLATFORM_OPENGL_CORE) && + (render_type != CONFIG_RENDER_PLATFORM_OPENGL_ES)) { + render_string = QString::fromUtf8("Emu: Not OpenGL"); + } else { + QString _head; + if(render_type == CONFIG_RENDER_PLATFORM_OPENGL_ES) { + _head = QString::fromUtf8("OpenGL ES v"); + } else if(render_type == CONFIG_RENDER_PLATFORM_OPENGL_CORE) { + _head = QString::fromUtf8("OpenGL (Core) v"); + } else { + _head = QString::fromUtf8("OpenGL (Main) v"); + } + render_string = QString::fromUtf8("Emu:  ") + _head + QString::number(_major_version) + + QString::fromUtf8(".") + QString::number(_minor_version) + QString::fromUtf8("
"); + } extfunc->initGLObjects(); extfunc->initFBO(); extfunc->initLocalGLObjects(); diff --git a/source/src/qt/gui/qt_input.cpp b/source/src/qt/gui/qt_input.cpp index a93e04a6e..fa3efb435 100644 --- a/source/src/qt/gui/qt_input.cpp +++ b/source/src/qt/gui/qt_input.cpp @@ -167,11 +167,13 @@ uint32_t GLDrawClass::get106Scancode2VK(uint32_t data) vk = VK_KANJI; } } + /* if(!using_flags->is_notify_key_down_lr_shift()) { if((vk == VK_LSHIFT) || (vk == VK_RSHIFT)) vk = VK_SHIFT; if((vk == VK_LMENU) || (vk == VK_RMENU)) vk = VK_MENU; } - if((vk == VK_LCONTROL) || (vk == VK_RCONTROL)) vk = VK_CONTROL; + */ +// if((vk == VK_LCONTROL) || (vk == VK_RCONTROL)) vk = VK_CONTROL; if(p_config->numpad_enter_as_fullkey) { if(vk == VK_OEM_CSP_KPRET) vk = VK_RETURN; } @@ -250,8 +252,9 @@ void GLDrawClass::keyReleaseEvent(QKeyEvent *event) if(event->isAutoRepeat()) return; scan = event->nativeScanCode(); vk = get106Scancode2VK(scan); + #if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) - if(using_flags->is_notify_key_down_lr_shift()) { +// if(using_flags->is_notify_key_down_lr_shift()) { if(vk == VK_SHIFT) { if((GetAsyncKeyState(VK_LSHIFT) & 0x8000) == 0) vk = VK_LSHIFT; if((GetAsyncKeyState(VK_RSHIFT) & 0x8000) == 0) vk = VK_RSHIFT; @@ -260,8 +263,9 @@ void GLDrawClass::keyReleaseEvent(QKeyEvent *event) if(GetAsyncKeyState(VK_LMENU) & 0x8000) vk = VK_LMENU; if(GetAsyncKeyState(VK_RMENU) & 0x8000) vk = VK_RMENU; } - } +// } #endif + //QThread::msleep(2); //printf("Key: UP: VK=%d SCAN=%04x MOD=%08x\n", vk, scan, mod); emit sig_key_up(vk, mod); @@ -286,8 +290,9 @@ void GLDrawClass::keyPressEvent(QKeyEvent *event) return; } } + #if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) - if(using_flags->is_notify_key_down_lr_shift()) { + //if(using_flags->is_notify_key_down_lr_shift()) { if(vk == VK_SHIFT) { if(GetAsyncKeyState(VK_LSHIFT) & 0x8000) vk = VK_LSHIFT; if(GetAsyncKeyState(VK_RSHIFT) & 0x8000) vk = VK_RSHIFT; @@ -296,8 +301,9 @@ void GLDrawClass::keyPressEvent(QKeyEvent *event) if(GetAsyncKeyState(VK_LMENU) & 0x8000) vk = VK_LMENU; if(GetAsyncKeyState(VK_RMENU) & 0x8000) vk = VK_RMENU; } - } + //} #endif + emit sig_key_down(vk, mod, false); } diff --git a/source/src/qt/gui/qt_main.cpp b/source/src/qt/gui/qt_main.cpp index fa1c06952..b5be60b25 100644 --- a/source/src/qt/gui/qt_main.cpp +++ b/source/src/qt/gui/qt_main.cpp @@ -66,9 +66,9 @@ QCommandLineOption *_opt_dump_envver; QCommandLineOption *_opt_dipsw_on; QCommandLineOption *_opt_dipsw_off; QProcessEnvironment _envvers; -extern QApplication *GuiMain; -extern bool _b_dump_envver; -extern std::string config_fullpath; + +bool _b_dump_envver; +std::string config_fullpath; DLL_PREFIX void SetOptions_Sub(QCommandLineParser *cmdparser) { @@ -104,7 +104,7 @@ DLL_PREFIX void SetOptions_Sub(QCommandLineParser *cmdparser) _cl.append("gl"); _cl.append("opengl"); _cl.append("render"); - _opt_opengl = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Force set using renderer type."), "{ GL | GL2 | GL3 | GL4 | GLES}"); + _opt_opengl = new QCommandLineOption(_cl, QCoreApplication::translate("main", "Force set using renderer type."), "{ GL2 | GL | GL3 | GL4 | GL4_CORE | GLES | ES2 | ES3}"); _cl.clear(); _cl.append("v"); diff --git a/source/src/qt/gui/qt_main.h b/source/src/qt/gui/qt_main.h index 5342f7375..80f60a824 100644 --- a/source/src/qt/gui/qt_main.h +++ b/source/src/qt/gui/qt_main.h @@ -24,9 +24,7 @@ //#include "../../emu.h" class META_MainWindow; -class EMU; extern class META_MainWindow *rMainWindow; -extern EMU* emu; // menu extern std::string DLL_PREFIX cpp_homedir; extern std::string DLL_PREFIX cpp_confdir; diff --git a/source/src/qt/gui/sound_dialog.cpp b/source/src/qt/gui/sound_dialog.cpp index 702972887..861c37f3e 100644 --- a/source/src/qt/gui/sound_dialog.cpp +++ b/source/src/qt/gui/sound_dialog.cpp @@ -16,7 +16,6 @@ Ui_SndSliderObject::Ui_SndSliderObject(USING_FLAGS *p, Qt::Orientation orientati : QSlider(orientation, parent) { using_flags = p; - p_emu = NULL; bind_num = num; parent_widget = parent; p_config = p->get_config_ptr(); @@ -96,7 +95,6 @@ void Ui_SndSliderObject::resetBalanceValue() Ui_SoundDialog::Ui_SoundDialog(USING_FLAGS *p, QWidget *parent) : QWidget(0) { - p_emu = NULL; using_flags = p; p_config = p->get_config_ptr(); if(parent != NULL) { diff --git a/source/src/qt/gui/sound_dialog.h b/source/src/qt/gui/sound_dialog.h index 0c8c83aca..9a38beb2c 100644 --- a/source/src/qt/gui/sound_dialog.h +++ b/source/src/qt/gui/sound_dialog.h @@ -38,7 +38,6 @@ class DLL_PREFIX Ui_SndSliderObject : public QSlider { Q_OBJECT private: - EMU *p_emu; USING_FLAGS *using_flags; QWidget *parent_widget; @@ -65,7 +64,6 @@ class DLL_PREFIX Ui_SoundDialog : public QWidget { Q_OBJECT private: - EMU *p_emu; QWidget *parent_widget; QGridLayout *MasterLayout; protected: diff --git a/source/src/qt/gui/util_bubble.cpp b/source/src/qt/gui/util_bubble.cpp index 00cd1b195..05ee8ea6e 100644 --- a/source/src/qt/gui/util_bubble.cpp +++ b/source/src/qt/gui/util_bubble.cpp @@ -15,8 +15,6 @@ #include "qt_dialogs.h" //#include "csp_logger.h" -extern class EMU *emu; - void Object_Menu_Control::insert_bubble(void) { emit sig_insert_bubble(getDrive()); } diff --git a/source/src/qt/gui/util_cd.cpp b/source/src/qt/gui/util_cd.cpp index 2328ec04d..433731c30 100644 --- a/source/src/qt/gui/util_cd.cpp +++ b/source/src/qt/gui/util_cd.cpp @@ -105,3 +105,10 @@ void Ui_MainWindowBase::ConfigCDROMMenu(void) { ConfigCDROMMenuSub(); } + +void Ui_MainWindowBase::do_swap_cdaudio_byteorder(int drv, bool value) +{ + if(drv < 0) return; + if(drv > 7) return; + p_config->swap_audio_byteorder[drv] = value; +} diff --git a/source/src/qt/gui/util_hdd.cpp b/source/src/qt/gui/util_hdd.cpp index 80183ec2a..aed66d7db 100644 --- a/source/src/qt/gui/util_hdd.cpp +++ b/source/src/qt/gui/util_hdd.cpp @@ -32,7 +32,7 @@ void Ui_MainWindowBase::eject_hard_disk(int drv) void Ui_MainWindowBase::CreateHardDiskMenu(int drv, int drv_base) { { - QString ext = "*.thd *.nhd *.hdi *.hdd "; // ToDo: Will support *.h[0123456] for Unz, FM-Towns emulator. + QString ext = "*.thd *.nhd *.hdi *.hdd *.h[0-9]"; QString desc1 = "Hard Disk Drive"; menu_hdds[drv] = new Menu_HDDClass(menubar, QString::fromUtf8("HDD"), using_flags, this, drv, drv_base); menu_hdds[drv]->create_pulldown_menu(); diff --git a/source/src/qt/machines/babbage2nd/CMakeLists.txt b/source/src/qt/machines/babbage2nd/CMakeLists.txt index 3ad281e1f..02811633e 100644 --- a/source/src/qt/machines/babbage2nd/CMakeLists.txt +++ b/source/src/qt/machines/babbage2nd/CMakeLists.txt @@ -4,14 +4,9 @@ set(s_qt_b2nd_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_b2nd_headers_MOC ${s_qt_b2nd_headers}) -# QT5_ADD_RESOURCES(s_qt_fm7_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_b2nd_headers_MOC ${s_qt_b2nd_headers}) -endif() +QT5_WRAP_CPP(s_qt_b2nd_headers_MOC ${s_qt_b2nd_headers}) -add_library(qt_babbage2nd +add_library(qt_emubabbage2nd MainWindow.cpp ${s_qt_b2nd_headers_MOC} ) diff --git a/source/src/qt/machines/babbage2nd/babbage2nd.ts b/source/src/qt/machines/babbage2nd/babbage2nd.ja_JP.ts similarity index 100% rename from source/src/qt/machines/babbage2nd/babbage2nd.ts rename to source/src/qt/machines/babbage2nd/babbage2nd.ja_JP.ts diff --git a/source/src/qt/machines/bmjr/CMakeLists.txt b/source/src/qt/machines/bmjr/CMakeLists.txt index dce486af6..c0debad8c 100644 --- a/source/src/qt/machines/bmjr/CMakeLists.txt +++ b/source/src/qt/machines/bmjr/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/bmjr") +message("* qt/${EXE_NAME}") set(s_qt_bmjr_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_bmjr_headers_MOC ${s_qt_bmjr_headers}) -else() - QT4_WRAP_CPP(s_qt_bmjr_headers_MOC ${s_qt_bmjr_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_bmjr_headers}) -add_library(qt_bmjr - MainWindow.cpp - ${s_qt_bmjr_headers_MOC} +add_library(qt_${EXE_NAME} + MainWindow.cpp + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/bmjr/bmjr.ts b/source/src/qt/machines/bmjr/bmjr.ja_JP.ts similarity index 100% rename from source/src/qt/machines/bmjr/bmjr.ts rename to source/src/qt/machines/bmjr/bmjr.ja_JP.ts diff --git a/source/src/qt/machines/bubcom80/CMakeLists.txt b/source/src/qt/machines/bubcom80/CMakeLists.txt index 558f556b6..5268ac34b 100644 --- a/source/src/qt/machines/bubcom80/CMakeLists.txt +++ b/source/src/qt/machines/bubcom80/CMakeLists.txt @@ -1,19 +1,14 @@ -message("* qt/bubcom80") +message("* qt/${EXE_NAME}") set(s_qt_bubcom80_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_bubcom80_headers_MOC ${s_qt_bubcom80_headers}) -# QT5_ADD_RESOURCES(s_qt_bubcom80_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_bubcom80_headers_MOC ${s_qt_bubcom80_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_bubcom80_headers}) -add_library(qt_bubcom80 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_bubcom80_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/bubcom80/bubcom80.ts b/source/src/qt/machines/bubcom80/bubcom80.ja_JP.ts similarity index 100% rename from source/src/qt/machines/bubcom80/bubcom80.ts rename to source/src/qt/machines/bubcom80/bubcom80.ja_JP.ts diff --git a/source/src/qt/machines/cefucom21/CMakeLists.txt b/source/src/qt/machines/cefucom21/CMakeLists.txt index cb3133ac6..a5cba84ae 100644 --- a/source/src/qt/machines/cefucom21/CMakeLists.txt +++ b/source/src/qt/machines/cefucom21/CMakeLists.txt @@ -3,12 +3,8 @@ message("* qt/cefucom21") set(s_qt_cefucom21_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_cefucom21_headers_MOC ${s_qt_cefucom21_headers}) -else() - QT4_WRAP_CPP(s_qt_cefucom21_headers_MOC ${s_qt_cefucom21_headers}) -endif() -add_library(qt_cefucom21 +QT5_WRAP_CPP(s_qt_cefucom21_headers_MOC ${s_qt_cefucom21_headers}) +add_library(qt_emucefucom21 MainWindow.cpp ${s_qt_cefucom21_headers_MOC} ) diff --git a/source/src/qt/machines/cefucom21/cefucom21.ts b/source/src/qt/machines/cefucom21/cefucom21.ja_JP.ts similarity index 100% rename from source/src/qt/machines/cefucom21/cefucom21.ts rename to source/src/qt/machines/cefucom21/cefucom21.ja_JP.ts diff --git a/source/src/qt/machines/colecovision/CMakeLists.txt b/source/src/qt/machines/colecovision/CMakeLists.txt index db3f30c15..9df1f4947 100644 --- a/source/src/qt/machines/colecovision/CMakeLists.txt +++ b/source/src/qt/machines/colecovision/CMakeLists.txt @@ -1,16 +1,14 @@ -message("* qt/colecovision") +message("* qt/${EXE_NAME}") set(s_qt_colecovision_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_colecovision_headers_MOC ${s_qt_colecovision_headers}) -else() - QT4_WRAP_CPP(s_qt_colecovision_headers_MOC ${s_qt_colecovision_headers}) -endif() -add_library(qt_colecovision + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_colecovision_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_colecovision_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/colecovision/colecovision.ts b/source/src/qt/machines/colecovision/colecovision.ja_JP.ts similarity index 100% rename from source/src/qt/machines/colecovision/colecovision.ts rename to source/src/qt/machines/colecovision/colecovision.ja_JP.ts diff --git a/source/src/qt/machines/ex80/CMakeLists.txt b/source/src/qt/machines/ex80/CMakeLists.txt index e31f16ff0..f07df7745 100644 --- a/source/src/qt/machines/ex80/CMakeLists.txt +++ b/source/src/qt/machines/ex80/CMakeLists.txt @@ -4,13 +4,9 @@ set(s_qt_ex80_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_ex80_headers_MOC ${s_qt_ex80_headers}) -else() - QT4_WRAP_CPP(s_qt_ex80_headers_MOC ${s_qt_ex80_headers}) -endif() +QT5_WRAP_CPP(s_qt_ex80_headers_MOC ${s_qt_ex80_headers}) -add_library(qt_ex80 +add_library(qt_emuex80 MainWindow.cpp ${s_qt_ex80_headers_MOC} ) diff --git a/source/src/qt/machines/ex80/ex80.ts b/source/src/qt/machines/ex80/ex80.ja_JP.ts similarity index 100% rename from source/src/qt/machines/ex80/ex80.ts rename to source/src/qt/machines/ex80/ex80.ja_JP.ts diff --git a/source/src/qt/machines/familybasic/CMakeLists.txt b/source/src/qt/machines/familybasic/CMakeLists.txt index f680873e8..f2160096f 100644 --- a/source/src/qt/machines/familybasic/CMakeLists.txt +++ b/source/src/qt/machines/familybasic/CMakeLists.txt @@ -1,18 +1,13 @@ -message("* qt/familybasic") +message("* qt/${EXE_NAME}") set(s_qt_familybasic_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_familybasic_headers_MOC ${s_qt_familybasic_headers}) -else() - QT4_WRAP_CPP(s_qt_familybasic_headers_MOC ${s_qt_familybasic_headers}) -endif() - -add_library(qt_familybasic +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_familybasic_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_familybasic_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/familybasic/familybasic.ts b/source/src/qt/machines/familybasic/familybasic.ja_JP.ts similarity index 100% rename from source/src/qt/machines/familybasic/familybasic.ts rename to source/src/qt/machines/familybasic/familybasic.ja_JP.ts diff --git a/source/src/qt/machines/fm16beta/CMakeLists.txt b/source/src/qt/machines/fm16beta/CMakeLists.txt index 4ee9b5cd2..6891d955e 100644 --- a/source/src/qt/machines/fm16beta/CMakeLists.txt +++ b/source/src/qt/machines/fm16beta/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/fm16beta") +message("* qt/${EXE_NAME}") set(s_qt_fm16beta_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fm16beta_headers_MOC ${s_qt_fm16beta_headers}) -else() - QT4_WRAP_CPP(s_qt_fm16beta_headers_MOC ${s_qt_fm16beta_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_fm16beta_headers}) -add_library(qt_fm16beta +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_fm16beta_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/fm16beta/fm16beta.ts b/source/src/qt/machines/fm16beta/fm16beta.ja_JP.ts similarity index 100% rename from source/src/qt/machines/fm16beta/fm16beta.ts rename to source/src/qt/machines/fm16beta/fm16beta.ja_JP.ts diff --git a/source/src/qt/machines/fm16pi/CMakeLists.txt b/source/src/qt/machines/fm16pi/CMakeLists.txt index 6856a9f7f..06a8a13b1 100644 --- a/source/src/qt/machines/fm16pi/CMakeLists.txt +++ b/source/src/qt/machines/fm16pi/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/fm16pi") +message("* qt/${EXE_NAME}") set(s_qt_fm16pi_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fm16pi_headers_MOC ${s_qt_fm16pi_headers}) -else() - QT4_WRAP_CPP(s_qt_fm16pi_headers_MOC ${s_qt_fm16pi_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_fm16pi_headers}) -add_library(qt_fm16pi +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_fm16pi_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/fm16pi/fm16pi.ts b/source/src/qt/machines/fm16pi/fm16pi.ja_JP.ts similarity index 100% rename from source/src/qt/machines/fm16pi/fm16pi.ts rename to source/src/qt/machines/fm16pi/fm16pi.ja_JP.ts diff --git a/source/src/qt/machines/fm7/CMakeLists.txt b/source/src/qt/machines/fm7/CMakeLists.txt index 71835c3f2..72ba88f73 100644 --- a/source/src/qt/machines/fm7/CMakeLists.txt +++ b/source/src/qt/machines/fm7/CMakeLists.txt @@ -1,19 +1,14 @@ -message("* qt/fm7") +message("* qt/${EXE_NAME}") -set(s_qt_fm7_headers +set(s_qt_fm7_headers_${EXE_NAME} menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fm7_headers_MOC ${s_qt_fm7_headers}) -# QT5_ADD_RESOURCES(s_qt_fm7_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_fm7_headers_MOC ${s_qt_fm7_headers}) -endif() +QT5_WRAP_CPP(s_qt_fm7_headers_${EXE_NAME}_MOC ${s_qt_fm7_headers_${EXE_NAME}}) -add_library(qt_fm7 - MainWindow.cpp - ${s_qt_fm7_headers_MOC} +add_library(qt_${EXE_NAME} + MainWindow.cpp + ${s_qt_fm7_headers_${EXE_NAME}_MOC} ) diff --git a/source/src/qt/machines/fm7/MainWindow.cpp b/source/src/qt/machines/fm7/MainWindow.cpp index a54a05ad2..76c33c432 100644 --- a/source/src/qt/machines/fm7/MainWindow.cpp +++ b/source/src/qt/machines/fm7/MainWindow.cpp @@ -32,7 +32,6 @@ Object_Menu_Control_7::~Object_Menu_Control_7() { } -#if defined(WITH_Z80) void Object_Menu_Control_7::do_set_z80card_on(bool flag) { if(flag) { @@ -71,7 +70,7 @@ void Object_Menu_Control_7::do_set_z80_nmi(bool flag) } emit sig_emu_update_config(); } -#endif + void Object_Menu_Control_7::do_set_uart(bool flag) { uint32_t nval; @@ -98,7 +97,6 @@ void Object_Menu_Control_7::do_set_uart(bool flag) } } -#if defined(CAPABLE_JCOMMCARD) void Object_Menu_Control_7::do_set_jcommcard(bool flag) { if(flag) { @@ -107,9 +105,7 @@ void Object_Menu_Control_7::do_set_jcommcard(bool flag) config.dipswitch = config.dipswitch & ~FM7_DIPSW_JSUBCARD_ON; } } -#endif -#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) void Object_Menu_Control_7::do_set_kanji_rom(bool flag) { if(flag) { @@ -118,9 +114,7 @@ void Object_Menu_Control_7::do_set_kanji_rom(bool flag) config.dipswitch = config.dipswitch & ~FM7_DIPSW_CONNECT_KANJIROM; } } -#endif -#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) void Object_Menu_Control_7::do_set_320kFloppy(bool flag) { if(flag) { @@ -129,9 +123,7 @@ void Object_Menu_Control_7::do_set_320kFloppy(bool flag) config.dipswitch = config.dipswitch & ~FM7_DIPSW_CONNECT_320KFDC; } } -#endif -#if defined(HAS_2HD) void Object_Menu_Control_7::do_set_1MFloppy(bool flag) { if(flag) { @@ -140,7 +132,6 @@ void Object_Menu_Control_7::do_set_1MFloppy(bool flag) config.dipswitch = config.dipswitch & ~FM7_DIPSW_CONNECT_1MFDC; } } -#endif void Object_Menu_Control_7::do_set_autokey_5_8(void) @@ -162,10 +153,6 @@ void Object_Menu_Control_7::do_set_autokey_5_8(void) } } - - - -#if defined(_FM8) void Object_Menu_Control_7::do_set_protect_ram(bool flag) { if(flag) { @@ -175,7 +162,7 @@ void Object_Menu_Control_7::do_set_protect_ram(bool flag) } emit sig_emu_update_config(); } -#else + void Object_Menu_Control_7::do_set_cyclesteal(bool flag) { if(flag) { @@ -185,7 +172,7 @@ void Object_Menu_Control_7::do_set_cyclesteal(bool flag) } emit sig_emu_update_config(); } -#endif + void Object_Menu_Control_7::do_set_hsync(bool flag) { if(flag) { @@ -230,6 +217,7 @@ void META_MainWindow::do_set_extram(bool flag) } #endif } + #if defined(CAPABLE_DICTROM) && !defined(_FM77AV40EX) && !defined(_FM77AV40SX) void META_MainWindow::do_set_use_dictcard(bool flag) { @@ -290,8 +278,8 @@ void META_MainWindow::retranslateUi(void) { } - actionSpecial_Reset->setText(QApplication::translate("Machine", "Hot Start(BREAK+RESET)", 0)); - actionSpecial_Reset->setToolTip(QApplication::translate("Machine", "Do HOT START.\nReset with pressing BREAK key.", 0)); + actionSpecial_Reset[0]->setText(QApplication::translate("Machine", "Hot Start(BREAK+RESET)", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("Machine", "Do HOT START.\nReset with pressing BREAK key.", 0)); #if defined(USE_PRINTER_TYPE) actionPrintDevice[1]->setText(QApplication::translate("Machine", "Dempa Joystick with #1", 0)); diff --git a/source/src/qt/machines/fm7/fm7.ts b/source/src/qt/machines/fm7/fm7.ja_JP.ts similarity index 100% rename from source/src/qt/machines/fm7/fm7.ts rename to source/src/qt/machines/fm7/fm7.ja_JP.ts diff --git a/source/src/qt/machines/fm7/menuclasses.h b/source/src/qt/machines/fm7/menuclasses.h index a6430eacb..e00134e85 100644 --- a/source/src/qt/machines/fm7/menuclasses.h +++ b/source/src/qt/machines/fm7/menuclasses.h @@ -4,6 +4,7 @@ #include "commonclasses.h" #include "mainwidget.h" +#include "vm.h" // This extends class CSP_MainWindow as Ui_MainWindow. // You may use this as QT_BEGIN_NAMESPACE @@ -20,30 +21,22 @@ class Object_Menu_Control_7: public Object_Menu_Control // int sig_sound_device(int); int sig_emu_update_config(void); public slots: -# if defined(WITH_Z80) + void do_set_z80card_on(bool flag); void do_set_z80_irq(bool flag); void do_set_z80_firq(bool flag); void do_set_z80_nmi(bool flag); -# endif - void do_set_hsync(bool flag); -# if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) void do_set_kanji_rom(bool flag); void do_set_320kFloppy(bool flag); -# endif -# if defined(HAS_2HD) + void do_set_1MFloppy(bool flag); -# endif -# if defined(_FM8) void do_set_protect_ram(bool flag); -# else + void do_set_cyclesteal(bool flag); -# endif -#if defined(CAPABLE_JCOMMCARD) void do_set_jcommcard(bool flag); -#endif + void do_set_uart(bool flag); void do_set_autokey_5_8(void); }; diff --git a/source/src/qt/machines/fmr30/CMakeLists.txt b/source/src/qt/machines/fmr30/CMakeLists.txt index 80a18b964..bcd730715 100644 --- a/source/src/qt/machines/fmr30/CMakeLists.txt +++ b/source/src/qt/machines/fmr30/CMakeLists.txt @@ -1,18 +1,12 @@ -message("* qt/fmr30") +message("* qt/${EXE_NAME}") set(s_qt_fmr30_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fmr30_headers_MOC ${s_qt_fmr30_headers}) -else() - QT4_WRAP_CPP(s_qt_fmr30_headers_MOC ${s_qt_fmr30_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_fmr30_headers}) -add_library(qt_fmr30 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_fmr30_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) - - diff --git a/source/src/qt/machines/fmr30/fmr30.ts b/source/src/qt/machines/fmr30/fmr30.ja_JP.ts similarity index 100% rename from source/src/qt/machines/fmr30/fmr30.ts rename to source/src/qt/machines/fmr30/fmr30.ja_JP.ts diff --git a/source/src/qt/machines/fmr50/CMakeLists.txt b/source/src/qt/machines/fmr50/CMakeLists.txt index 2a574e0ce..d446cfef1 100644 --- a/source/src/qt/machines/fmr50/CMakeLists.txt +++ b/source/src/qt/machines/fmr50/CMakeLists.txt @@ -1,18 +1,16 @@ -message("* qt/fmr50") +message("* qt/${EXE_NAME}") set(s_qt_fmr50_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fmr50_headers_MOC ${s_qt_fmr50_headers}) -else() - QT4_WRAP_CPP(s_qt_fmr50_headers_MOC ${s_qt_fmr50_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_fmr50_headers}) -add_library(qt_fmr50 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_fmr50_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) + + diff --git a/source/src/qt/machines/fmr50/fmr50.ts b/source/src/qt/machines/fmr50/fmr50.ja_JP.ts similarity index 100% rename from source/src/qt/machines/fmr50/fmr50.ts rename to source/src/qt/machines/fmr50/fmr50.ja_JP.ts diff --git a/source/src/qt/machines/fmtowns/CMakeLists.txt b/source/src/qt/machines/fmtowns/CMakeLists.txt index 7f636a10a..f80c72e1e 100644 --- a/source/src/qt/machines/fmtowns/CMakeLists.txt +++ b/source/src/qt/machines/fmtowns/CMakeLists.txt @@ -1,19 +1,14 @@ -message("* qt/fmtowns") +message("* qt/${EXE_NAME}") set(s_qt_fmtowns_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fmtowns_headers_MOC ${s_qt_fmtowns_headers}) -# QT5_ADD_RESOURCES(s_qt_fmtowns_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_fmtowns_headers_MOC ${s_qt_fmtowns_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_fmtowns_headers}) -add_library(qt_fmtowns +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_fmtowns_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/fmtowns/MainWindow.cpp b/source/src/qt/machines/fmtowns/MainWindow.cpp index 323bd5c50..b143a1864 100644 --- a/source/src/qt/machines/fmtowns/MainWindow.cpp +++ b/source/src/qt/machines/fmtowns/MainWindow.cpp @@ -16,6 +16,7 @@ #include "qt_main.h" #include "../../vm/fmtowns/fmtowns.h" #include "menu_binary.h" +#include "menu_cart.h" //QT_BEGIN_NAMESPACE @@ -23,11 +24,70 @@ void META_MainWindow::retranslateUi(void) { Ui_MainWindowBase::retranslateUi(); - retranslateControlMenu("", false); - menu_BINs[0]->setTitle(QApplication::translate("MenuBABBAGE", "RAM", 0)); + retranslateControlMenu("Reset with CD", true); + actionSpecial_Reset[0]->setText(QApplication::translate("Machine", "Reset with CD", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("Machine", "Reset and boot from CD-ROM", 0)); + for(int i = 1; i < 5; i++) { + QString tmps, tmps2, tmps3; + tmps.setNum(i - 1); + tmps2 = QApplication::translate("Machine", "Reset with F", 0); + tmps2 = tmps2 + tmps; + tmps3 = QApplication::translate("Machine", "Reset and boot from FLOPPY #", 0); + tmps3 = tmps3 + tmps; + actionSpecial_Reset[i]->setText(tmps2); + actionSpecial_Reset[i]->setToolTip(tmps3); + } + for(int i = 5; i < 10; i++) { + QString tmps, tmps2, tmps3; + tmps.setNum(i - 5); + tmps2 = QApplication::translate("Machine", "Reset with H", 0); + tmps2 = tmps2 + tmps; + tmps3 = QApplication::translate("Machine", "Reset and boot from HDD #", 0); + tmps3 = tmps3 + tmps; + actionSpecial_Reset[i]->setText(tmps2); + actionSpecial_Reset[i]->setToolTip(tmps3); + } + actionSpecial_Reset[10]->setText(QApplication::translate("Machine", "Reset with ICM", 0)); + actionSpecial_Reset[10]->setToolTip(QApplication::translate("Machine", "Reset with boot from IC CARD #0", 0)); + actionSpecial_Reset[11]->setText(QApplication::translate("Machine", "Reset with DEBUG", 0)); + actionSpecial_Reset[11]->setToolTip(QApplication::translate("Machine", "Reset with DEBUGGING MODE", 0)); +# if defined(USE_MOUSE_TYPE) + menuMouseType->setTitle(QApplication::translate("Machine", "Mouse", 0)); + menuMouseType->setToolTipsVisible(true); + actionMouseType[0]->setText(QApplication::translate("Machine", "none", 0)); + actionMouseType[0]->setToolTip(QApplication::translate("Machine", "Not connect mouse.", 0)); + actionMouseType[1]->setText(QApplication::translate("Machine", "PAD port1", 0)); + actionMouseType[1]->setToolTip(QApplication::translate("Machine", "Connect mouse to PAD port #1.", 0)); + actionMouseType[2]->setText(QApplication::translate("Machine", "PAD port2", 0)); + actionMouseType[2]->setToolTip(QApplication::translate("Machine", "Connect mouse to PAD port #2.", 0)); +# endif +#if defined(USE_JOYSTICK_TYPE) + actionJoystickType[0]->setText(QApplication::translate("Machine", "None", 0)); + actionJoystickType[0]->setToolTip(QApplication::translate("Machine", "NotConnected.", 0)); + actionJoystickType[1]->setText(QApplication::translate("Machine", "2 buttons", 0)); + actionJoystickType[1]->setToolTip(QApplication::translate("Machine", "Connect 2 buttons Towns PAD to PORTs.", 0)); + actionJoystickType[2]->setText(QApplication::translate("Machine", "6 buttons", 0)); + actionJoystickType[2]->setToolTip(QApplication::translate("Machine", "Connect 6 buttons Towns PAD to PORTs.", 0)); + menuJoystickType->setTitle(QApplication::translate("Machine", "Towns PAD", 0)); +#endif +#if defined(USE_CART) + if(menu_Cart[0] != NULL) { + menu_Cart[0]->setTitle(QApplication::translate("MainWindow", "IC1", 0)); + } + if(menu_Cart[1] != NULL) { + menu_Cart[1]->setTitle(QApplication::translate("MainWindow", "IC2", 0)); + } +#endif +// menu_BINs[0]->setTitle(QApplication::translate("MenuBABBAGE", "RAM", 0)); //menuMachine->setVisible(false); // Set Labels +#ifdef USE_DEBUGGER + actionDebugger[0]->setVisible(true); + actionDebugger[1]->setVisible(false); + actionDebugger[2]->setVisible(false); + actionDebugger[3]->setVisible(false); +#endif } // retranslateUi void META_MainWindow::setupUI_Emu(void) diff --git a/source/src/qt/machines/fmtowns/fmtowns.ja_JP.ts b/source/src/qt/machines/fmtowns/fmtowns.ja_JP.ts new file mode 100644 index 000000000..43d7e99d8 --- /dev/null +++ b/source/src/qt/machines/fmtowns/fmtowns.ja_JP.ts @@ -0,0 +1,67 @@ + + + + + Machine + + + Mouse + マウス + + + + none + なし + + + + Not connect mouse. + マウスをつなぎません + + + + PAD port1 + パッドポート1 + + + + Connect mouse to PAD port #1. + マウスをパッドポート1につなぎます + + + + PAD port2 + パッドポート2 + + + + Connect mouse to PAD port #2. + マウスをパッドポート2につなぎます。 + + + + 2 buttons + 2ボタンパッド + + + + Connect 2 buttons Towns PAD to PORTs. + 2ボタンのTownsパッドをポートにつなぎます。 + + + + 6 buttons + 6ボタンパッド + + + + Connect 6 buttons Towns PAD to PORTs. + 6ボタンのTownsパッドをつなぎます + + + + Towns PAD + Townsパッド + + + diff --git a/source/src/qt/machines/fp1100/CMakeLists.txt b/source/src/qt/machines/fp1100/CMakeLists.txt index 35927b3cd..d5fb71318 100644 --- a/source/src/qt/machines/fp1100/CMakeLists.txt +++ b/source/src/qt/machines/fp1100/CMakeLists.txt @@ -1,18 +1,13 @@ -message("* qt/fp1100") +message("* qt/emufp1100") set(s_qt_fp1100_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fp1100_headers_MOC ${s_qt_fp1100_headers}) -else() - QT4_WRAP_CPP(s_qt_fp1100_headers_MOC ${s_qt_fp1100_headers}) -endif() - -add_library(qt_fp1100 +QT5_WRAP_CPP(s_qt_emufp1100_headers_MOC ${s_qt_fp1100_headers}) +add_library(qt_emufp1100 MainWindow.cpp - ${s_qt_fp1100_headers_MOC} + ${s_qt_emufp1100_headers_MOC} ) diff --git a/source/src/qt/machines/fp1100/fp1100.ts b/source/src/qt/machines/fp1100/fp1100.ja_JP.ts similarity index 100% rename from source/src/qt/machines/fp1100/fp1100.ts rename to source/src/qt/machines/fp1100/fp1100.ja_JP.ts diff --git a/source/src/qt/machines/fp200/CMakeLists.txt b/source/src/qt/machines/fp200/CMakeLists.txt index b1cb9fb6e..ad84dba88 100644 --- a/source/src/qt/machines/fp200/CMakeLists.txt +++ b/source/src/qt/machines/fp200/CMakeLists.txt @@ -3,15 +3,12 @@ message("* qt/fp200") set(s_qt_fp200_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_fp200_headers_MOC ${s_qt_fp200_headers}) -else() - QT4_WRAP_CPP(s_qt_fp200_headers_MOC ${s_qt_fp200_headers}) -endif() -add_library(qt_fp200 +QT5_WRAP_CPP(s_qt_emufp200_headers_MOC ${s_qt_fp200_headers}) + +add_library(qt_emufp200 MainWindow.cpp - ${s_qt_fp200_headers_MOC} + ${s_qt_emufp200_headers_MOC} ) diff --git a/source/src/qt/machines/fp200/fp200.ts b/source/src/qt/machines/fp200/fp200.ja_JP.ts similarity index 100% rename from source/src/qt/machines/fp200/fp200.ts rename to source/src/qt/machines/fp200/fp200.ja_JP.ts diff --git a/source/src/qt/machines/gamegear/CMakeLists.txt b/source/src/qt/machines/gamegear/CMakeLists.txt index 7ec190188..2a2c0d036 100644 --- a/source/src/qt/machines/gamegear/CMakeLists.txt +++ b/source/src/qt/machines/gamegear/CMakeLists.txt @@ -1,18 +1,11 @@ -message("* qt/gamegear") +message("* qt/${EXE_NAME}") set(s_qt_gamegear_headers menuclasses.h - ) +) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_gamegear_headers_MOC ${s_qt_gamegear_headers}) -else() - QT4_WRAP_CPP(s_qt_gamegear_headers_MOC ${s_qt_gamegear_headers}) -endif() - -add_library(qt_gamegear +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_gamegear_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_gamegear_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) - - diff --git a/source/src/qt/machines/gamegear/gamegear.ts b/source/src/qt/machines/gamegear/gamegear.ja_JP.ts similarity index 100% rename from source/src/qt/machines/gamegear/gamegear.ts rename to source/src/qt/machines/gamegear/gamegear.ja_JP.ts diff --git a/source/src/qt/machines/hc20/CMakeLists.txt b/source/src/qt/machines/hc20/CMakeLists.txt index 24684400a..909fc9e46 100644 --- a/source/src/qt/machines/hc20/CMakeLists.txt +++ b/source/src/qt/machines/hc20/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/hc20") +message("* qt/${EXE_NAME}") set(s_qt_hc20_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_hc20_headers_MOC ${s_qt_hc20_headers}) -else() - QT4_WRAP_CPP(s_qt_hc20_headers_MOC ${s_qt_hc20_headers}) -endif() -add_library(qt_hc20 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_hc20_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_hc20_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/hc20/hc20.ts b/source/src/qt/machines/hc20/hc20.ja_JP.ts similarity index 100% rename from source/src/qt/machines/hc20/hc20.ts rename to source/src/qt/machines/hc20/hc20.ja_JP.ts diff --git a/source/src/qt/machines/hc40/CMakeLists.txt b/source/src/qt/machines/hc40/CMakeLists.txt index 4483c24a0..80b16152e 100644 --- a/source/src/qt/machines/hc40/CMakeLists.txt +++ b/source/src/qt/machines/hc40/CMakeLists.txt @@ -1,17 +1,14 @@ -message("* qt/hc40") +message("* qt/${EXE_NAME}") set(s_qt_hc40_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_hc40_headers_MOC ${s_qt_hc40_headers}) -else() - QT4_WRAP_CPP(s_qt_hc40_headers_MOC ${s_qt_hc40_headers}) -endif() -add_library(qt_hc40 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_hc40_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_hc40_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) + diff --git a/source/src/qt/machines/hc40/MainWindow.cpp b/source/src/qt/machines/hc40/MainWindow.cpp index fd5682211..891b781cf 100644 --- a/source/src/qt/machines/hc40/MainWindow.cpp +++ b/source/src/qt/machines/hc40/MainWindow.cpp @@ -26,7 +26,8 @@ void META_MainWindow::retranslateUi(void) { Ui_MainWindowBase::retranslateUi(); retranslateControlMenu("System Reset", true); - actionSpecial_Reset->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); + actionSpecial_Reset[0]->setText(QApplication::translate("MainWindow", "System Reset", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); #ifdef USE_DEBUGGER actionDebugger[0]->setVisible(true); diff --git a/source/src/qt/machines/hc40/hc40.ts b/source/src/qt/machines/hc40/hc40.ja_JP.ts similarity index 100% rename from source/src/qt/machines/hc40/hc40.ts rename to source/src/qt/machines/hc40/hc40.ja_JP.ts diff --git a/source/src/qt/machines/hc80/CMakeLists.txt b/source/src/qt/machines/hc80/CMakeLists.txt index 38bc3adfc..1426f3202 100644 --- a/source/src/qt/machines/hc80/CMakeLists.txt +++ b/source/src/qt/machines/hc80/CMakeLists.txt @@ -1,18 +1,11 @@ -message("* qt/hc80") +message("* qt/${EXE_NAME}") set(s_qt_hc80_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_hc80_headers_MOC ${s_qt_hc80_headers}) -else() - QT4_WRAP_CPP(s_qt_hc80_headers_MOC ${s_qt_hc80_headers}) -endif() - -add_library(qt_hc80 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_hc80_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_hc80_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) - - diff --git a/source/src/qt/machines/hc80/MainWindow.cpp b/source/src/qt/machines/hc80/MainWindow.cpp index 220a7a464..420760134 100644 --- a/source/src/qt/machines/hc80/MainWindow.cpp +++ b/source/src/qt/machines/hc80/MainWindow.cpp @@ -25,7 +25,8 @@ void META_MainWindow::retranslateUi(void) Ui_MainWindowBase::retranslateUi(); retranslateControlMenu("System Reset", true); - actionSpecial_Reset->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); + actionSpecial_Reset[0]->setText(QApplication::translate("MainWindow", "System Reset", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); menuDeviceType->setTitle(QApplication::translate("Machine", "Option Cartridge", 0)); menuDeviceType->setToolTipsVisible(true); actionDeviceType[0]->setText(QApplication::translate("Machine", "None", 0)); diff --git a/source/src/qt/machines/hc80/hc80.ts b/source/src/qt/machines/hc80/hc80.ja_JP.ts similarity index 100% rename from source/src/qt/machines/hc80/hc80.ts rename to source/src/qt/machines/hc80/hc80.ja_JP.ts diff --git a/source/src/qt/machines/j3100/CMakeLists.txt b/source/src/qt/machines/j3100/CMakeLists.txt index 3c4b45693..e0d1b35fb 100644 --- a/source/src/qt/machines/j3100/CMakeLists.txt +++ b/source/src/qt/machines/j3100/CMakeLists.txt @@ -1,18 +1,13 @@ -message("* qt/j3100") +message("* qt/${EXE_NAME}") set(s_qt_j3100_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_j3100_headers_MOC ${s_qt_j3100_headers}) -else() - QT4_WRAP_CPP(s_qt_j3100_headers_MOC ${s_qt_j3100_headers}) -endif() - -add_library(qt_j3100 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_j3100_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_j3100_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/j3100/j3100.ts b/source/src/qt/machines/j3100/j3100.ja_JP.ts similarity index 100% rename from source/src/qt/machines/j3100/j3100.ts rename to source/src/qt/machines/j3100/j3100.ja_JP.ts diff --git a/source/src/qt/machines/jr100/CMakeLists.txt b/source/src/qt/machines/jr100/CMakeLists.txt index 55ab7bdf6..8e892f309 100644 --- a/source/src/qt/machines/jr100/CMakeLists.txt +++ b/source/src/qt/machines/jr100/CMakeLists.txt @@ -1,18 +1,13 @@ -message("* qt/jr100") +message("* qt/${EXE_NAME}") set(s_qt_jr100_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_jr100_headers_MOC ${s_qt_jr100_headers}) -else() - QT4_WRAP_CPP(s_qt_jr100_headers_MOC ${s_qt_jr100_headers}) -endif() - -add_library(qt_jr100 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_jr100_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_jr100_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/jr100/jr100.ts b/source/src/qt/machines/jr100/jr100.ja_JP.ts similarity index 100% rename from source/src/qt/machines/jr100/jr100.ts rename to source/src/qt/machines/jr100/jr100.ja_JP.ts diff --git a/source/src/qt/machines/jr800/CMakeLists.txt b/source/src/qt/machines/jr800/CMakeLists.txt index 7b66a24bc..e580a3794 100644 --- a/source/src/qt/machines/jr800/CMakeLists.txt +++ b/source/src/qt/machines/jr800/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/jr800") +message("* qt/${EXE_NAME}") set(s_qt_jr800_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_jr800_headers_MOC ${s_qt_jr800_headers}) -else() - QT4_WRAP_CPP(s_qt_jr800_headers_MOC ${s_qt_jr800_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_jr800_headers}) -add_library(qt_jr800 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_jr800_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/jr800/jr800.ts b/source/src/qt/machines/jr800/jr800.ja_JP.ts similarity index 100% rename from source/src/qt/machines/jr800/jr800.ts rename to source/src/qt/machines/jr800/jr800.ja_JP.ts diff --git a/source/src/qt/machines/jx/CMakeLists.txt b/source/src/qt/machines/jx/CMakeLists.txt index 4538c7eaa..32be2a185 100644 --- a/source/src/qt/machines/jx/CMakeLists.txt +++ b/source/src/qt/machines/jx/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/jx") +message("* qt/${EXE_NAME}") set(s_qt_jx_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_jx_headers_MOC ${s_qt_jx_headers}) -else() - QT4_WRAP_CPP(s_qt_jx_headers_MOC ${s_qt_jx_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_jx_headers}) -add_library(qt_jx +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_jx_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/jx/jx.ts b/source/src/qt/machines/jx/jx.ja_JP.ts similarity index 100% rename from source/src/qt/machines/jx/jx.ts rename to source/src/qt/machines/jx/jx.ja_JP.ts diff --git a/source/src/qt/machines/m5/CMakeLists.txt b/source/src/qt/machines/m5/CMakeLists.txt index b0b418996..a2dd14ec1 100644 --- a/source/src/qt/machines/m5/CMakeLists.txt +++ b/source/src/qt/machines/m5/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/m5") +message("* qt/${EXE_NAME}") set(s_qt_m5_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_m5_headers_MOC ${s_qt_m5_headers}) -else() - QT4_WRAP_CPP(s_qt_m5_headers_MOC ${s_qt_m5_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_m5_headers}) -add_library(qt_m5 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_m5_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/m5/m5.ts b/source/src/qt/machines/m5/m5.ja_JP.ts similarity index 100% rename from source/src/qt/machines/m5/m5.ts rename to source/src/qt/machines/m5/m5.ja_JP.ts diff --git a/source/src/qt/machines/micom_mahjong/CMakeLists.txt b/source/src/qt/machines/micom_mahjong/CMakeLists.txt new file mode 100644 index 000000000..ae0643420 --- /dev/null +++ b/source/src/qt/machines/micom_mahjong/CMakeLists.txt @@ -0,0 +1,14 @@ +message("* qt/${EXE_NAME}") + +set(s_qt_micom_mahjong_headers_${EXE_NAME} + menuclasses.h +) + +QT5_WRAP_CPP(s_qt_micom_mahjong_headers_${EXE_NAME}_MOC ${s_qt_micom_mahjong_headers_${EXE_NAME}}) + +add_library(qt_${EXE_NAME} + MainWindow.cpp + ${s_qt_micom_mahjong_headers_${EXE_NAME}_MOC} +) + + diff --git a/source/src/qt/machines/micom_mahjong/MainWindow.cpp b/source/src/qt/machines/micom_mahjong/MainWindow.cpp new file mode 100644 index 000000000..e1db3a47d --- /dev/null +++ b/source/src/qt/machines/micom_mahjong/MainWindow.cpp @@ -0,0 +1,56 @@ +/* + * Common Source code Project: + * Ui->Qt->MainWindow for Babbage2nd . + * (C) 2015 K.Ohta + * License : GPLv2 + * History : + * Jan 14, 2015 : Initial, many of constructors were moved to qt/gui/menu_main.cpp. + */ + +#include +#include +#include +#include "menuclasses.h" +#include "commonclasses.h" + +#include "emu.h" +#include "qt_main.h" +#include "vm.h" + +//QT_BEGIN_NAMESPACE + + +void META_MainWindow::retranslateUi(void) +{ + Ui_MainWindowBase::retranslateUi(); + retranslateControlMenu("", false); + // Set Labels +#ifdef USE_DEBUGGER + actionDebugger[0]->setVisible(true); + actionDebugger[1]->setVisible(false); + actionDebugger[2]->setVisible(false); + actionDebugger[3]->setVisible(false); +#endif + +} // retranslateUi + +void META_MainWindow::setupUI_Emu(void) +{ +} + + +META_MainWindow::META_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent) : Ui_MainWindow(p, logger, parent) +{ + setupUI_Emu(); + retranslateUi(); +} + + +META_MainWindow::~META_MainWindow() +{ +} + +//QT_END_NAMESPACE + + + diff --git a/source/src/qt/machines/micom_mahjong/menuclasses.h b/source/src/qt/machines/micom_mahjong/menuclasses.h new file mode 100644 index 000000000..ee35813a9 --- /dev/null +++ b/source/src/qt/machines/micom_mahjong/menuclasses.h @@ -0,0 +1,26 @@ + +#ifndef _CSP_QT_MENUCLASSES_H +#define _CSP_QT_MENUCLASSES_H + +#include "mainwidget.h" +// This extends class CSP_MainWindow as Ui_MainWindow. +// You may use this as +QT_BEGIN_NAMESPACE + +class Ui_MainWindow; +class USING_FLAGS; +class CSP_Logger; +// wrote of Specific menu. +class META_MainWindow : public Ui_MainWindow { + Q_OBJECT +protected: + void setupUI_Emu(void); + void retranslateUi(void); +public: + META_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent = 0); + ~META_MainWindow(); +}; + +QT_END_NAMESPACE + +#endif // END diff --git a/source/src/qt/machines/micom_mahjong/micom_mahjong.ja_JP.ts b/source/src/qt/machines/micom_mahjong/micom_mahjong.ja_JP.ts new file mode 100644 index 000000000..0b5611e81 --- /dev/null +++ b/source/src/qt/machines/micom_mahjong/micom_mahjong.ja_JP.ts @@ -0,0 +1,4 @@ + + + + diff --git a/source/src/qt/machines/msx/CMakeLists.txt b/source/src/qt/machines/msx/CMakeLists.txt index 0ce562514..10eeba7fb 100644 --- a/source/src/qt/machines/msx/CMakeLists.txt +++ b/source/src/qt/machines/msx/CMakeLists.txt @@ -1,17 +1,14 @@ -message("* qt/msx1") +message("* qt/${EXE_NAME}") -set(s_qt_msx1_headers +set(s_qt_msx_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_msx1_headers_MOC ${s_qt_msx1_headers}) -else() - QT4_WRAP_CPP(s_qt_msx1_headers_MOC ${s_qt_msx1_headers}) -endif() -add_library(qt_msx +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_msx_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_msx1_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/msx/msx.ts b/source/src/qt/machines/msx/msx.ja_JP.ts similarity index 100% rename from source/src/qt/machines/msx/msx.ts rename to source/src/qt/machines/msx/msx.ja_JP.ts diff --git a/source/src/qt/machines/multi8/CMakeLists.txt b/source/src/qt/machines/multi8/CMakeLists.txt index 68217120a..0162aa09e 100644 --- a/source/src/qt/machines/multi8/CMakeLists.txt +++ b/source/src/qt/machines/multi8/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/multi8") +message("* qt/${EXE_NAME}") set(s_qt_multi8_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_multi8_headers_MOC ${s_qt_multi8_headers}) -else() - QT4_WRAP_CPP(s_qt_multi8_headers_MOC ${s_qt_multi8_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_multi8_headers}) -add_library(qt_multi8 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_multi8_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/multi8/multi8.ts b/source/src/qt/machines/multi8/multi8.ja_JP.ts similarity index 100% rename from source/src/qt/machines/multi8/multi8.ts rename to source/src/qt/machines/multi8/multi8.ja_JP.ts diff --git a/source/src/qt/machines/mycomz80a/CMakeLists.txt b/source/src/qt/machines/mycomz80a/CMakeLists.txt index 140cbaa42..914093163 100644 --- a/source/src/qt/machines/mycomz80a/CMakeLists.txt +++ b/source/src/qt/machines/mycomz80a/CMakeLists.txt @@ -1,17 +1,14 @@ -message("* qt/mycomz80") +message("* qt/${EXE_NAME}_") set(s_qt_mycomz80_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_mycomz80_headers_MOC ${s_qt_mycomz80_headers}) -else() - QT4_WRAP_CPP(s_qt_mycomz80_headers_MOC ${s_qt_mycomz80_headers}) -endif() -add_library(qt_mycomz80a +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_mycomz80_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_mycomz80_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/mycomz80a/mycomz80a.ts b/source/src/qt/machines/mycomz80a/mycomz80a.ja_JP.ts similarity index 100% rename from source/src/qt/machines/mycomz80a/mycomz80a.ts rename to source/src/qt/machines/mycomz80a/mycomz80a.ja_JP.ts diff --git a/source/src/qt/machines/mz2500/CMakeLists.txt b/source/src/qt/machines/mz2500/CMakeLists.txt index 1f4c8f566..8148d9adf 100644 --- a/source/src/qt/machines/mz2500/CMakeLists.txt +++ b/source/src/qt/machines/mz2500/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/mz2500") +message("* qt/${EXE_NAME}") set(s_qt_mz2500_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_mz2500_headers_MOC ${s_qt_mz2500_headers}) -else() - QT4_WRAP_CPP(s_qt_mz2500_headers_MOC ${s_qt_mz2500_headers}) -endif() -add_library(qt_mz2500 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_mz2500_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_mz2500_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/mz2500/MainWindow.cpp b/source/src/qt/machines/mz2500/MainWindow.cpp index 89172842c..8a88f09f0 100644 --- a/source/src/qt/machines/mz2500/MainWindow.cpp +++ b/source/src/qt/machines/mz2500/MainWindow.cpp @@ -51,8 +51,8 @@ void META_MainWindow::retranslateUi(void) retranslateControlMenu("Reset", true); actionReset->setText(QApplication::translate("MachineMZ2500", "IPL Reset", 0)); actionReset->setToolTip(QApplication::translate("MachineMZ2500", "Do IPL reset.", 0)); - actionSpecial_Reset->setText(QApplication::translate("MachineMZ2500", "Reset", 0)); - actionSpecial_Reset->setToolTip(QApplication::translate("MachineMZ2500", "Do system reset.", 0)); + actionSpecial_Reset[0]->setText(QApplication::translate("MachineMZ2500", "Reset", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MachineMZ2500", "Do system reset.", 0)); #ifdef USE_CPU_TYPE menuCpuType->setTitle(QApplication::translate("MachineMZ2500", "CPU Frequency", 0)); actionCpuType[0]->setText(QString::fromUtf8("4MHz")); diff --git a/source/src/qt/machines/mz2500/mz2500.ts b/source/src/qt/machines/mz2500/mz2500.ja_JP.ts similarity index 100% rename from source/src/qt/machines/mz2500/mz2500.ts rename to source/src/qt/machines/mz2500/mz2500.ja_JP.ts diff --git a/source/src/qt/machines/mz2800/CMakeLists.txt b/source/src/qt/machines/mz2800/CMakeLists.txt index 44dcee93b..854e553b1 100644 --- a/source/src/qt/machines/mz2800/CMakeLists.txt +++ b/source/src/qt/machines/mz2800/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/mz2800") +message("* qt/${EXE_NAME}") set(s_qt_mz2800_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_mz2800_headers_MOC ${s_qt_mz2800_headers}) -else() - QT4_WRAP_CPP(s_qt_mz2800_headers_MOC ${s_qt_mz2800_headers}) -endif() -add_library(qt_mz2800 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_mz2800_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_mz2800_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/mz2800/MainWindow.cpp b/source/src/qt/machines/mz2800/MainWindow.cpp index 9e95012d2..e5f864c3e 100644 --- a/source/src/qt/machines/mz2800/MainWindow.cpp +++ b/source/src/qt/machines/mz2800/MainWindow.cpp @@ -29,9 +29,10 @@ void META_MainWindow::retranslateUi(void) { Ui_MainWindowBase::retranslateUi(); retranslateControlMenu("Reset", true); - actionReset->setText(QApplication::translate("MainWindow", "IPL Reset", 0)); - actionReset->setToolTip(QApplication::translate("MainWindow", "Do IPL reset.", 0)); - //actionSpecial_Reset->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); + actionReset->setText(QApplication::translate("MainWindow", "Reset", 0)); + actionReset->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); +// actionSpecial_Reset[0]->setText(QApplication::translate("MainWindow", "Reset.", 0)); +// actionSpecial_Reset[0]->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); #if defined(USE_PRINTER) actionPrintDevice[1]->setText(QString::fromUtf8("MZ-1P17")); actionPrintDevice[1]->setToolTip(QApplication::translate("MainWindow", "Sharp MZ-1P17 kanji thermal printer.", 0)); diff --git a/source/src/qt/machines/mz2800/mz2800.ts b/source/src/qt/machines/mz2800/mz2800.ja_JP.ts similarity index 100% rename from source/src/qt/machines/mz2800/mz2800.ts rename to source/src/qt/machines/mz2800/mz2800.ja_JP.ts diff --git a/source/src/qt/machines/mz3500/CMakeLists.txt b/source/src/qt/machines/mz3500/CMakeLists.txt index c91457438..d6aa17f3e 100644 --- a/source/src/qt/machines/mz3500/CMakeLists.txt +++ b/source/src/qt/machines/mz3500/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/mz3500") +message("* qt/${EXE_NAME}") set(s_qt_mz3500_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_mz3500_headers_MOC ${s_qt_mz3500_headers}) -else() - QT4_WRAP_CPP(s_qt_mz3500_headers_MOC ${s_qt_mz3500_headers}) -endif() -add_library(qt_mz3500 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_mz3500_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_mz3500_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/mz3500/MainWindow.cpp b/source/src/qt/machines/mz3500/MainWindow.cpp index c858b5b17..b43e9cc2a 100644 --- a/source/src/qt/machines/mz3500/MainWindow.cpp +++ b/source/src/qt/machines/mz3500/MainWindow.cpp @@ -84,7 +84,8 @@ void META_MainWindow::retranslateUi(void) Ui_MainWindowBase::retranslateUi(); retranslateControlMenu("Halt", true); actionReset->setToolTip(QApplication::translate("MainWindow", "Do system reset.", 0)); - actionSpecial_Reset->setToolTip(QApplication::translate("MainWindow", "HALT a machine.", 0)); + actionSpecial_Reset[0]->setText(QApplication::translate("MainWindow", "Halt", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MainWindow", "HALT a machine.", 0)); this->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0)); menu_Emu_DipSw->setTitle(QApplication::translate("MainWindow", "Dip Switches", 0)); diff --git a/source/src/qt/machines/mz3500/mz3500.ts b/source/src/qt/machines/mz3500/mz3500.ja_JP.ts similarity index 100% rename from source/src/qt/machines/mz3500/mz3500.ts rename to source/src/qt/machines/mz3500/mz3500.ja_JP.ts diff --git a/source/src/qt/machines/mz5500/CMakeLists.txt b/source/src/qt/machines/mz5500/CMakeLists.txt index 2642561fe..0a5d974a0 100644 --- a/source/src/qt/machines/mz5500/CMakeLists.txt +++ b/source/src/qt/machines/mz5500/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/mz5500") +message("* qt/${EXE_NAME}") set(s_qt_mz5500_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_mz5500_headers_MOC ${s_qt_mz5500_headers}) -else() - QT4_WRAP_CPP(s_qt_mz5500_headers_MOC ${s_qt_mz5500_headers}) -endif() -add_library(qt_mz5500 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_mz5500_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_mz5500_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/mz5500/MainWindow.cpp b/source/src/qt/machines/mz5500/MainWindow.cpp index 7bdcbc4f7..f3806aa9f 100644 --- a/source/src/qt/machines/mz5500/MainWindow.cpp +++ b/source/src/qt/machines/mz5500/MainWindow.cpp @@ -39,8 +39,8 @@ void META_MainWindow::retranslateUi(void) #endif actionReset->setText(QApplication::translate("MainWindow", "Reset", 0)); - actionSpecial_Reset->setText(QApplication::translate("MainWindow", "NMI Reset", 0)); - actionSpecial_Reset->setToolTip(QApplication::translate("MainWindow", "Do NMI reset.", 0)); + actionSpecial_Reset[0]->setText(QApplication::translate("MainWindow", "NMI Reset", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MainWindow", "Do NMI reset.", 0)); #if defined(USE_DEBUGGER) actionDebugger[0]->setVisible(true); actionDebugger[1]->setVisible(false); diff --git a/source/src/qt/machines/mz5500/mz5500.ts b/source/src/qt/machines/mz5500/mz5500.ja_JP.ts similarity index 100% rename from source/src/qt/machines/mz5500/mz5500.ts rename to source/src/qt/machines/mz5500/mz5500.ja_JP.ts diff --git a/source/src/qt/machines/mz700/CMakeLists.txt b/source/src/qt/machines/mz700/CMakeLists.txt index 3d5edfa1b..677fcec98 100644 --- a/source/src/qt/machines/mz700/CMakeLists.txt +++ b/source/src/qt/machines/mz700/CMakeLists.txt @@ -1,17 +1,14 @@ -message("* qt/mz700") +message("* qt/${EXE_NAME}") set(s_qt_mz700_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_mz700_headers_MOC ${s_qt_mz700_headers}) -else() - QT4_WRAP_CPP(s_qt_mz700_headers_MOC ${s_qt_mz700_headers}) -endif() -add_library(qt_mz700 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_mz700_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_mz700_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/mz700/mz700.ts b/source/src/qt/machines/mz700/mz700.ja_JP.ts similarity index 100% rename from source/src/qt/machines/mz700/mz700.ts rename to source/src/qt/machines/mz700/mz700.ja_JP.ts diff --git a/source/src/qt/machines/mz80k/CMakeLists.txt b/source/src/qt/machines/mz80k/CMakeLists.txt index ba1592a3e..7dc7ad482 100644 --- a/source/src/qt/machines/mz80k/CMakeLists.txt +++ b/source/src/qt/machines/mz80k/CMakeLists.txt @@ -3,14 +3,11 @@ message("* qt/mz80k") set(s_qt_mz80_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_mz80_headers_MOC ${s_qt_mz80_headers}) -else() - QT4_WRAP_CPP(s_qt_mz80_headers_MOC ${s_qt_mz80_headers}) -endif() -add_library(qt_mz80k + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_mz80_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_mz80_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/mz80k/mz80k.ts b/source/src/qt/machines/mz80k/mz80k.ja_JP.ts similarity index 100% rename from source/src/qt/machines/mz80k/mz80k.ts rename to source/src/qt/machines/mz80k/mz80k.ja_JP.ts diff --git a/source/src/qt/machines/n5200/CMakeLists.txt b/source/src/qt/machines/n5200/CMakeLists.txt index 0e4373685..a2390fc0d 100644 --- a/source/src/qt/machines/n5200/CMakeLists.txt +++ b/source/src/qt/machines/n5200/CMakeLists.txt @@ -1,17 +1,12 @@ -message("* qt/n5200") +message("* qt/${EXE_NAME}") set(s_qt_n5200_headers menuclasses.h ) - -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_n5200_headers_MOC ${s_qt_n5200_headers}) -else() - QT4_WRAP_CPP(s_qt_n5200_headers_MOC ${s_qt_n5200_headers}) -endif() -add_library(qt_n5200 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_n5200_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_n5200_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/n5200/n5200.ts b/source/src/qt/machines/n5200/n5200.ja_JP.ts similarity index 100% rename from source/src/qt/machines/n5200/n5200.ts rename to source/src/qt/machines/n5200/n5200.ja_JP.ts diff --git a/source/src/qt/machines/pasopia/CMakeLists.txt b/source/src/qt/machines/pasopia/CMakeLists.txt index be6244ade..2bd7d8031 100644 --- a/source/src/qt/machines/pasopia/CMakeLists.txt +++ b/source/src/qt/machines/pasopia/CMakeLists.txt @@ -1,18 +1,13 @@ -message("* qt/pasopia") +message("* qt/${EXE_NAME}") set(s_qt_pasopia_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pasopia_headers_MOC ${s_qt_pasopia_headers}) -else() - QT4_WRAP_CPP(s_qt_pasopia_headers_MOC ${s_qt_pasopia_headers}) -endif() - -add_library(qt_pasopia +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pasopia_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pasopia_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pasopia/pasopia.ts b/source/src/qt/machines/pasopia/pasopia.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pasopia/pasopia.ts rename to source/src/qt/machines/pasopia/pasopia.ja_JP.ts diff --git a/source/src/qt/machines/pasopia7/CMakeLists.txt b/source/src/qt/machines/pasopia7/CMakeLists.txt index d4dc3379e..6bee53421 100644 --- a/source/src/qt/machines/pasopia7/CMakeLists.txt +++ b/source/src/qt/machines/pasopia7/CMakeLists.txt @@ -1,18 +1,11 @@ -message("* qt/pasopia7") +message("* qt/${EXE_NAME}") set(s_qt_pasopia7_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pasopia7_headers_MOC ${s_qt_pasopia7_headers}) -else() - QT4_WRAP_CPP(s_qt_pasopia7_headers_MOC ${s_qt_pasopia7_headers}) -endif() - -add_library(qt_pasopia7 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pasopia7_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pasopia7_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) - - diff --git a/source/src/qt/machines/pasopia7/pasopia7.ts b/source/src/qt/machines/pasopia7/pasopia7.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pasopia7/pasopia7.ts rename to source/src/qt/machines/pasopia7/pasopia7.ja_JP.ts diff --git a/source/src/qt/machines/pc100/CMakeLists.txt b/source/src/qt/machines/pc100/CMakeLists.txt index 41fb5edfa..a0aec5a31 100644 --- a/source/src/qt/machines/pc100/CMakeLists.txt +++ b/source/src/qt/machines/pc100/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/pc100") +message("* qt/${EXE_NAME}") set(s_qt_pc100_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pc100_headers_MOC ${s_qt_pc100_headers}) -else() - QT4_WRAP_CPP(s_qt_pc100_headers_MOC ${s_qt_pc100_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pc100_headers}) -add_library(qt_pc100 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pc100_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pc100/pc100.ts b/source/src/qt/machines/pc100/pc100.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pc100/pc100.ts rename to source/src/qt/machines/pc100/pc100.ja_JP.ts diff --git a/source/src/qt/machines/pc2001/CMakeLists.txt b/source/src/qt/machines/pc2001/CMakeLists.txt index 12eaead67..a41726092 100644 --- a/source/src/qt/machines/pc2001/CMakeLists.txt +++ b/source/src/qt/machines/pc2001/CMakeLists.txt @@ -1,17 +1,14 @@ -message("* qt/pc2001") +message("* qt/${EXE_NAME}") set(s_qt_pc2001_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pc2001_headers_MOC ${s_qt_pc2001_headers}) -else() - QT4_WRAP_CPP(s_qt_pc2001_headers_MOC ${s_qt_pc2001_headers}) -endif() -add_library(qt_pc2001 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pc2001_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pc2001_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pc2001/pc2001.ts b/source/src/qt/machines/pc2001/pc2001.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pc2001/pc2001.ts rename to source/src/qt/machines/pc2001/pc2001.ja_JP.ts diff --git a/source/src/qt/machines/pc6001/CMakeLists.txt b/source/src/qt/machines/pc6001/CMakeLists.txt index 2469f1ae7..64e434586 100644 --- a/source/src/qt/machines/pc6001/CMakeLists.txt +++ b/source/src/qt/machines/pc6001/CMakeLists.txt @@ -1,16 +1,14 @@ -message("* qt/pc6001") +message("* qt/${EXE_NAME}") set(s_qt_pc6001_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pc6001_headers_MOC ${s_qt_pc6001_headers}) -else() - QT4_WRAP_CPP(s_qt_pc6001_headers_MOC ${s_qt_pc6001_headers}) -endif() -add_library(qt_pc6001 + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pc6001_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pc6001_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pc6001/pc6001.ts b/source/src/qt/machines/pc6001/pc6001.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pc6001/pc6001.ts rename to source/src/qt/machines/pc6001/pc6001.ja_JP.ts diff --git a/source/src/qt/machines/pc8201/CMakeLists.txt b/source/src/qt/machines/pc8201/CMakeLists.txt index 4fc8391f5..69a089a36 100644 --- a/source/src/qt/machines/pc8201/CMakeLists.txt +++ b/source/src/qt/machines/pc8201/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/pc8201") +message("* qt/${EXE_NAME}") set(s_qt_pc8201_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pc8201_headers_MOC ${s_qt_pc8201_headers}) -else() - QT4_WRAP_CPP(s_qt_pc8201_headers_MOC ${s_qt_pc8201_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pc8201_headers}) -add_library(qt_pc8201 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pc8201_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pc8201/pc8201.ts b/source/src/qt/machines/pc8201/pc8201.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pc8201/pc8201.ts rename to source/src/qt/machines/pc8201/pc8201.ja_JP.ts diff --git a/source/src/qt/machines/pc8801/CMakeLists.txt b/source/src/qt/machines/pc8801/CMakeLists.txt index 089d469b6..b516bf632 100644 --- a/source/src/qt/machines/pc8801/CMakeLists.txt +++ b/source/src/qt/machines/pc8801/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/pc8801ma") +message("* qt/${EXE_NAME}") set(s_qt_pc8801ma_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pc8801ma_headers_MOC ${s_qt_pc8801ma_headers}) -else() - QT4_WRAP_CPP(s_qt_pc8801ma_headers_MOC ${s_qt_pc8801ma_headers}) -endif() -add_library(qt_pc8801 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pc8801ma_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pc8801ma_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pc8801/pc8801.ts b/source/src/qt/machines/pc8801/pc8801.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pc8801/pc8801.ts rename to source/src/qt/machines/pc8801/pc8801.ja_JP.ts diff --git a/source/src/qt/machines/pc9801/CMakeLists.txt b/source/src/qt/machines/pc9801/CMakeLists.txt index 57f08ec7f..0fb27edcf 100644 --- a/source/src/qt/machines/pc9801/CMakeLists.txt +++ b/source/src/qt/machines/pc9801/CMakeLists.txt @@ -1,16 +1,14 @@ -message("* qt/pc9801") +message("* qt/${EXE_NAME}") set(s_qt_pc9801_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pc9801_headers_MOC ${s_qt_pc9801_headers}) -else() - QT4_WRAP_CPP(s_qt_pc9801_headers_MOC ${s_qt_pc9801_headers}) -endif() -add_library(qt_pc9801 + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pc9801_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pc9801_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pc9801/MainWindow.cpp b/source/src/qt/machines/pc9801/MainWindow.cpp index 3b621e2e8..0c5ffe0fd 100644 --- a/source/src/qt/machines/pc9801/MainWindow.cpp +++ b/source/src/qt/machines/pc9801/MainWindow.cpp @@ -34,9 +34,25 @@ void Object_Menu_Control_98::do_set_memory_wait(bool flag) emit sig_set_dipsw(0, flag); } +void Object_Menu_Control_98::do_set_connect_2hd(bool flag) +{ + emit sig_set_dipsw(0, flag); +} + +void Object_Menu_Control_98::do_set_connect_2d(bool flag) +{ + emit sig_set_dipsw(2, flag); +} + +void Object_Menu_Control_98::do_set_connect_2dd(bool flag) +{ + emit sig_set_dipsw(1, flag); +} + + void Object_Menu_Control_98::do_set_enable_v30(bool flag) { - emit sig_set_dipsw(DIPSWITCH_POSITION_CPU_MODE, flag); + emit sig_set_dipsw(DIPSWITCH_POSITION_USE_V30, flag); } @@ -75,6 +91,16 @@ Action_Control_98::~Action_Control_98() delete pc98_binds; } +// DIPSW 3-8 +void META_MainWindow::do_use_ix86() +{ + set_dipsw(DIPSWITCH_POSITION_CPU_MODE, false); +} + +void META_MainWindow::do_use_v30() +{ + set_dipsw(DIPSWITCH_POSITION_CPU_MODE, true); +} void META_MainWindow::retranslateUi(void) { @@ -123,10 +149,12 @@ void META_MainWindow::retranslateUi(void) actionSoundDevice[2]->setVisible(false); actionSoundDevice[3]->setVisible(false); #endif -#if defined(HAS_I286) || defined(UPPER_I386) +#if !defined(SUPPORT_HIRESO) +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) actionSUB_V30->setText(QApplication::translate("MainWindow", "Enable V30 SUB CPU(need RESTART).", 0)); actionSUB_V30->setToolTip(QApplication::translate("MainWindow", "Enable emulation of V30 SUB CPU.\nThis may make emulation speed slower.\nYou must restart emulator after reboot.", 0)); #endif +#endif #ifdef USE_CPU_TYPE menuCpuType->setTitle(QApplication::translate("MainWindow", "CPU Frequency", 0)); @@ -142,29 +170,34 @@ void META_MainWindow::retranslateUi(void) # elif defined(_PC9801VM) actionCpuType[0]->setText(QString::fromUtf8("V30 10MHz")); actionCpuType[1]->setText(QString::fromUtf8("V30 8MHz")); -# elif defined(_PC9801VX) || defined(_PC98XL) +# elif defined(_PC9801VX) + actionCpuType[0]->setText(QString::fromUtf8("80286 10MHz / V30 10MHz")); + actionCpuType[1]->setText(QString::fromUtf8("80286 8MHz / V30 8MHz")); +# elif defined(_PC98XL) actionCpuType[0]->setText(QString::fromUtf8("80286 10MHz")); actionCpuType[1]->setText(QString::fromUtf8("80286 8MHz")); - actionCpuType[2]->setText(QString::fromUtf8("V30 8MHz")); - if((config.dipswitch & ((0x1) << DIPSWITCH_POSITION_CPU_MODE)) == 0) { - actionCpuType[2]->setEnabled(false); - } # elif defined(_PC9801RA) || defined(_PC98RL) // ToDo: PC98RL's display rotate. - actionCpuType[0]->setText(QString::fromUtf8("80386 20MHz")); - actionCpuType[1]->setText(QString::fromUtf8("80386 16MHz")); - actionCpuType[2]->setText(QString::fromUtf8("V30 8MHz")); - if((config.dipswitch & ((0x1) << DIPSWITCH_POSITION_CPU_MODE)) == 0) { - actionCpuType[2]->setEnabled(false); - } + actionCpuType[0]->setText(QString::fromUtf8("80386 20MHz / V30 10MHz")); + actionCpuType[1]->setText(QString::fromUtf8("80386 16MHz / V30 8MHz")); # elif defined(_PC98XA) actionCpuType[0]->setText(QString::fromUtf8("80286 8MHz")); actionCpuType[1]->setVisible(false); - actionCpuType[2]->setText(QString::fromUtf8("V30 8MHz")); - if((config.dipswitch & ((0x1) << DIPSWITCH_POSITION_CPU_MODE)) == 0) { - actionCpuType[2]->setEnabled(false); +# endif +#endif +#if !defined(SUPPORT_HIRESO) +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + if((config.dipswitch & ((0x1) << DIPSWITCH_POSITION_USE_V30)) == 0) { + actionRunSubCPU->setEnabled(false); } +# if defined(UPPER_I386) + actionRunMainCPU->setText(QString::fromUtf8("i386")); +# else + actionRunMainCPU->setText(QString::fromUtf8("i80286")); # endif + actionRunSubCPU->setText(QString::fromUtf8("V30")); + menuRunCpu->setTitle(QApplication::translate("MainWindow", "Running CPU (DIPSW 3-8)", 0)); +#endif #endif actionRAM_512K->setText(QApplication::translate("MainWindow", "512KB RAM", 0)); @@ -202,6 +235,14 @@ void META_MainWindow::retranslateUi(void) actionPrintDevice[1]->setText(QString::fromUtf8("PC-PR201")); actionPrintDevice[1]->setToolTip(QApplication::translate("MainWindow", "NEC PC-PR201 kanji serial printer.", 0)); actionPrintDevice[1]->setEnabled(false); +#endif + +#if defined(SUPPORT_320KB_FDD_IF) + actionConnect2D->setText(QApplication::translate("MainWindow", "Connect 320KB 2D Drive", 0)); +#endif +#if defined(_PC9801) || defined(_PC9801E) + actionConnect2DD->setText(QApplication::translate("MainWindow", "Connect 2DD Drive", 0)); + actionConnect2HD->setText(QApplication::translate("MainWindow", "Connect 2HD Drive", 0)); #endif // End. // Set Labels @@ -222,21 +263,19 @@ void META_MainWindow::retranslateUi(void) actionDebugger[2]->setVisible(true); #elif defined(HAS_I286) actionDebugger[0]->setText(QApplication::translate("MainWindow", "i80286 Main CPU", 0)); - actionDebugger[1]->setText(QApplication::translate("MainWindow", "V30 Sub CPU", 0)); - actionDebugger[1]->setVisible(true); #elif defined(HAS_I386) actionDebugger[0]->setText(QApplication::translate("MainWindow", "i80386 Main CPU", 0)); - actionDebugger[1]->setText(QApplication::translate("MainWindow", "V30 Sub CPU", 0)); - actionDebugger[1]->setVisible(true); #elif defined(HAS_I486) actionDebugger[0]->setText(QApplication::translate("MainWindow", "i80486 Main CPU", 0)); - actionDebugger[1]->setText(QApplication::translate("MainWindow", "V30 Sub CPU", 0)); - actionDebugger[1]->setVisible(true); #elif defined(UPPER_I386) actionDebugger[0]->setText(QApplication::translate("MainWindow", "i80x86 Main CPU", 0)); +#endif +#if !defined(SUPPORT_HIRESO) +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) actionDebugger[1]->setText(QApplication::translate("MainWindow", "V30 Sub CPU", 0)); actionDebugger[1]->setVisible(true); -#endif +#endif +#endif #endif #ifdef USE_MONITOR_TYPE actionMonitorType[0]->setText(QApplication::translate("MainWindow", "High Resolution", 0)); @@ -247,24 +286,48 @@ void META_MainWindow::retranslateUi(void) void META_MainWindow::setupUI_Emu(void) { #ifdef USE_CPU_TYPE - #if defined(HAS_I286) || defined(UPPER_I386) - ConfigCPUTypes(3); - #else ConfigCPUTypes(2); - #endif #endif -#if defined(HAS_I286) || defined(UPPER_I386) + +#if !defined(SUPPORT_HIRESO) +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) actionSUB_V30 = new Action_Control_98(this, using_flags); actionSUB_V30->setCheckable(true); actionSUB_V30->setVisible(true); menuMachine->addAction(actionSUB_V30); - if((config.dipswitch & ((0x1) << DIPSWITCH_POSITION_CPU_MODE)) != 0) actionSUB_V30->setChecked(true); // Emulation with V30 + if((config.dipswitch & ((0x1) << DIPSWITCH_POSITION_USE_V30)) != 0) actionSUB_V30->setChecked(true); // Emulation with V30 connect(actionSUB_V30, SIGNAL(toggled(bool)), actionSUB_V30->pc98_binds, SLOT(do_set_enable_v30(bool))); connect(actionSUB_V30->pc98_binds, SIGNAL(sig_set_dipsw(int, bool)), this, SLOT(set_dipsw(int, bool))); connect(actionSUB_V30->pc98_binds, SIGNAL(sig_emu_update_config()), this, SLOT(do_emu_update_config())); + + actionGroup_RunningCpu = new QActionGroup(this); + actionGroup_RunningCpu->setExclusive(true); + + actionRunMainCPU = new Action_Control_98(this, using_flags); + actionRunMainCPU->setCheckable(true); + actionRunMainCPU->setVisible(true); + actionGroup_RunningCpu->addAction(actionRunMainCPU); + connect(actionRunMainCPU, SIGNAL(triggered()), this, SLOT(do_use_ix86())); + + actionRunSubCPU = new Action_Control_98(this, using_flags); + actionRunSubCPU->setCheckable(true); + actionRunSubCPU->setVisible(true); + actionGroup_RunningCpu->addAction(actionRunSubCPU); + connect(actionRunSubCPU, SIGNAL(triggered()), this, SLOT(do_use_v30())); + + if((config.dipswitch & (1 << DIPSWITCH_POSITION_CPU_MODE)) != 0) { + actionRunSubCPU->setChecked(true); + } else { + actionRunMainCPU->setChecked(true); + } + menuRunCpu = new QMenu(menuMachine); + menuRunCpu->addAction(actionRunMainCPU); + menuRunCpu->addAction(actionRunSubCPU); + menuMachine->addAction(menuRunCpu->menuAction()); +#endif #endif actionRAM_512K = new Action_Control_98(this, using_flags); @@ -328,7 +391,38 @@ void META_MainWindow::setupUI_Emu(void) connect(actionMemoryWait->pc98_binds, SIGNAL(sig_set_dipsw(int, bool)), this, SLOT(set_dipsw(int, bool))); #endif +#if defined(SUPPORT_320KB_FDD_IF) + actionConnect2D = new Action_Control_98(this, using_flags); + actionConnect2D->setCheckable(true); + actionConnect2D->setVisible(true); + menuMachine->addAction(actionConnect2D); + if((config.dipswitch & 0x0004) != 0) actionConnect2D->setChecked(true); + connect(actionConnect2D, SIGNAL(toggled(bool)), + actionConnect2D->pc98_binds, SLOT(do_set_connect_2d(bool))); + connect(actionConnect2D->pc98_binds, SIGNAL(sig_set_dipsw(int, bool)), + this, SLOT(set_dipsw(int, bool))); +#endif +#if defined(_PC9801) || defined(_PC9801E) + actionConnect2DD = new Action_Control_98(this, using_flags); + actionConnect2DD->setCheckable(true); + actionConnect2DD->setVisible(true); + menuMachine->addAction(actionConnect2DD); + if((config.dipswitch & 0x0002) != 0) actionConnect2DD->setChecked(true); + connect(actionConnect2DD, SIGNAL(toggled(bool)), + actionConnect2DD->pc98_binds, SLOT(do_set_connect_2dd(bool))); + connect(actionConnect2DD->pc98_binds, SIGNAL(sig_set_dipsw(int, bool)), + this, SLOT(set_dipsw(int, bool))); + actionConnect2HD = new Action_Control_98(this, using_flags); + actionConnect2HD->setCheckable(true); + actionConnect2HD->setVisible(true); + menuMachine->addAction(actionConnect2HD); + if((config.dipswitch & 0x0001) != 0) actionConnect2HD->setChecked(true); + connect(actionConnect2HD, SIGNAL(toggled(bool)), + actionConnect2HD->pc98_binds, SLOT(do_set_connect_2hd(bool))); + connect(actionConnect2HD->pc98_binds, SIGNAL(sig_set_dipsw(int, bool)), + this, SLOT(set_dipsw(int, bool))); +#endif #ifdef USE_BOOT_MODE ConfigCPUBootMode(USE_BOOT_MODE); #endif diff --git a/source/src/qt/machines/pc9801/menuclasses.h b/source/src/qt/machines/pc9801/menuclasses.h index 6f852dd01..408b50f8c 100644 --- a/source/src/qt/machines/pc9801/menuclasses.h +++ b/source/src/qt/machines/pc9801/menuclasses.h @@ -26,6 +26,9 @@ public slots: void do_set_ram_512k(bool); void do_set_init_memsw(bool); void do_set_enable_v30(bool flag); + void do_set_connect_2d(bool flag); + void do_set_connect_2dd(bool flag); + void do_set_connect_2hd(bool flag); signals: int sig_emu_update_config(); }; @@ -51,20 +54,37 @@ class META_MainWindow : public Ui_MainWindow { Action_Control_98 *actionRAM_512K; Action_Control_98 *actionINIT_MEMSW; Action_Control_98 *actionGDC_FAST; -#if defined(HAS_I286) || defined(HAS_I386) || defined(HAS_I486) || defined(HAS_PENTIUM) - Action_Control_98 *actionSUB_V30; -#endif #if defined(SUPPORT_EGC) Action_Control_98 *actionEGC; #endif #if defined(_PC98DO) Action_Control_98 *actionMemoryWait; -#endif +#endif +#if defined(SUPPORT_320KB_FDD_IF) + Action_Control_98 *actionConnect2D; +#endif +#if defined(_PC9801) || defined(_PC9801E) + Action_Control_98 *actionConnect2DD; + Action_Control_98 *actionConnect2HD; +#endif +#if !defined(SUPPORT_HIRESO) +#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + Action_Control_98 *actionSUB_V30; + QActionGroup *actionGroup_RunningCpu; + QMenu *menuRunCpu; + Action_Control_98 *actionRunMainCPU; + Action_Control_98 *actionRunSubCPU; +#endif +#endif void setupUI_Emu(void); void retranslateUi(void); public: META_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent = 0); ~META_MainWindow(); +public slots: + void do_use_ix86(); + void do_use_v30(); + }; QT_END_NAMESPACE diff --git a/source/src/qt/machines/pc9801/pc9801.ja_JP.ts b/source/src/qt/machines/pc9801/pc9801.ja_JP.ts new file mode 100644 index 000000000..d12f71abe --- /dev/null +++ b/source/src/qt/machines/pc9801/pc9801.ja_JP.ts @@ -0,0 +1,347 @@ + + + + + MainWindow + + + 2DD-1 + + + + + 2DD-2 + + + + + 2D-1 + + + + + 2D-2 + + + + + PC98-1 + + + + + PC98-2 + + + + + PC88-1 + + + + + PC88-2 + + + + + Sound Card + サウンドカード + + + + PC-9801-86 (BIOS Enabled) + PC-9801-86(BIOS有効) + + + + PC-9801-86 (BIOS Disabled) + PC-9801-86(BIOS無効) + + + + PC-9801-26 (BIOS Enabled) + PC-9801-26(BIOS有効) + + + + PC-9801-26 (BIOS Disabled) + PC-9801-26(BIOS無効) + + + + PC-9801-14 (BIOS Enabled) + PC-9801-14(BIOS有効) + + + + PC-9801-14 (BIOS Disabled) + PC-9801-14(BIOS無効) + + + + None + なし + + + + PC-9801-86 sound board has connected. +This uses YAMAHA YM-2608 OPNA synthesizer chip. +On board BIOS is enabled. + PC-9801-86サウンドボードを挿します。 +ヤマハのOPNA FM音源チップが使用されています。 +ボード上のBIOSを有効にします。 + + + + PC-9801-86 sound board has connected. +This uses YAMAHA YM-2608 OPNA synthesizer chip. +On board BIOS is disabled. + PC-9801-86サウンドボードを挿します。 +ヤマハのOPNA FM音源チップが使用されています。 +ボード上のBIOSは無効です。 + + + + PC-9801-26 sound board has connected. +This uses YAMAHA YM-2203 OPN synthesizer chip. +On board BIOS is enabled. + PC-9801-26 サウンドボードを接続します。 +ヤマハYM-2203(OPN) FM音源を搭載しています。 +オンボードBIOSが使用できます。 + + + + PC-9801-26 sound board has connected. +This uses YAMAHA YM-2203 OPN synthesizer chip. +On board BIOS is disabled. + PC-9801-26 サウンドボードを接続します。 +ヤマハYM-2203(OPN) FM音源を搭載しています。 +オンボードBIOSは無効です。 + + + + PC-9801-14 sound board has connected. +This uses TI TMS3631-RI104 synthesizer chip. +On board BIOS is enabled. + PC-9801-14 サウンドボードを接続します。 +TI TMS3631-RI104 シンセサイザチップを搭載しています。 +オンボードBIOSが使用できます。 + + + + PC-9801-14 sound board has connected. +This uses TI TMS3631-RI104 synthesizer chip. +On board BIOS is disabled. + PC-9801-14 サウンドボードを接続します。 +TI TMS3631-RI104 シンセサイザチップを搭載しています。 +オンボードBIOSは無効です。 + + + + None sound devices has connected. + 拡張サウンドデバイスを接続しません。 + + + + Enable V30 SUB CPU(need RESTART). + V30サブCPU有効(要再起動) + + + + Enable emulation of V30 SUB CPU. +This may make emulation speed slower. +You must restart emulator after reboot. + V30サブCPUを有効にしてエミュレートします。 +有効にすることで、エミュレーション速度が低下するかも知れません。 +変更したら、エミュレータを動かし直す必要があります(リセットではなく)。 + + + + CPU Frequency + CPU周波数 + + + + Running CPU (DIPSW 3-8) + 動かすCPU(DIPSW 3-8) + + + + 512KB RAM + + + + + Set lower RAM size to 512KB(not 640KB). +Maybe for backward compatibility. + 低いアドレスのRAM(コンベンショナルメモリ)の大きさを512KBにします(640KBではない)。 +後方互換性で有効なオプションかも知れません。 + + + + INIT MEMSW(need RESET) + メモリスイッチを初期化する(要リセット) + + + + Initialize memory switch. +Effects after resetting. + メモリスイッチを初期化します。 +リセット後に有効になります。 + + + + FAST GDC + 高速GDC + + + + Set GDC clock to 5MHz when checked. +Set to 2.5MHz wjhen not checked. + GDCクロックを5MHzに設定します。 +チェックしない場合、2.5MHzに設定されます。 + + + + USE EGC + EGCを使う + + + + Use Enhanced Graphic controller when checked. + チェックするとEGC(Enhanced Graphic Controller)を有効にします。 + + + + Machine Mode + 起動モード + + + + PC-9801 Mode. +You can run softwares of PC-9801 series. +May be earlier than PC-9801VM. + PC-9801モード。 +(たぶん)PC-9801VM以前のソフトウェアが実行可能です。 + + + + PC8801 V1(Standard) Mode. +You can run softwares of PC-8801/mk2. + PC-8801 V1(標準)モード。 +PC-8801/mk2のソフトウェアが実行可能です。 + + + + PC8801 V1(High Speed) Mode. +You can run softwares of PC-8801/mk2 faster. + PC-8801 V1(高速)モード。 +PC-8801/mk2のソフトウェアがより高速に実行可能です。 + + + + PC8801 V2 Mode. +You can run only softwares for PC-8801SR or later. + PC-8801 V2モード。 +PC-8801mk2SR以降専用のソフトウェアが実行できます。 + + + + PC8801 N Mode. +You can run softwares of PC-8001/mk2. + PC-8801 Nモード。 +PC-8001/mk2向けのソフトウェアが実行できます。 + + + + Memory Wait + メモリウェイト + + + + Simulate waiting memory. + メモリウェイトをシミュレートします。 + + + + NEC PC-PR201 kanji serial printer. + NEC PC-PR201漢字シリアルプリンタを接続します。 + + + + Connect 320KB 2D Drive + 320KBの2D FDDを接続する + + + + Connect 2DD Drive + 720KBの2DD FDDを接続する + + + + Connect 2HD Drive + 1.2MBの2HD FDDを接続する + + + + PC-80S31K CPU + PC-80S31K(外付けドライブ)のCPU + + + + PC-98 Main CPU + PC-98のメインCPU(ix86) + + + + PC-88 Main CPU + PC-88のメインCPU(Z80) + + + + PC-88 Sub CPU + PC-88のサブCPU(Z80) + + + + i80286 Main CPU + i80286メインCPU + + + + i80386 Main CPU + i80386メインCPU + + + + i80486 Main CPU + i80486メインCPU + + + + i80x86 Main CPU + i80x86メインCPU + + + + V30 Sub CPU + V30サブCPU + + + Display Mode + 表示モード + + + + High Resolution + ハイレゾ + + + + Standard Resolution + Standarsd Resolution + 標準 + + + diff --git a/source/src/qt/machines/pc9801/pc9801.ts b/source/src/qt/machines/pc9801/pc9801.ts deleted file mode 100644 index 7fb803b1b..000000000 --- a/source/src/qt/machines/pc9801/pc9801.ts +++ /dev/null @@ -1,302 +0,0 @@ - - - - - MainWindow - - - 2DD-1 - - - - - 2DD-2 - - - - - 2D-1 - - - - - 2D-2 - - - - - PC98-1 - - - - - PC98-2 - - - - - PC88-1 - - - - - PC88-2 - - - - - Sound Card - サウンドカード - - - - PC-9801-86 (BIOS Enabled) - PC-9801-86(BIOS有効) {9801-86 ?} - - - - PC-9801-86 (BIOS Disabled) - PC-9801-86(BIOS無効) {9801-86 ?} - - - - PC-9801-26 (BIOS Enabled) - PC-9801-26(BIOS有効) - - - - PC-9801-26 (BIOS Disabled) - PC-9801-26(BIOS無効) - - - - PC-9801-14 (BIOS Enabled) - PC-9801-14(BIOS有効) - - - - PC-9801-14 (BIOS Disabled) - PC-9801-14(BIOS無効) - - - - None - なし - - - - PC-9801-86 sound board has connected. -This uses YAMAHA YM-2608 OPNA synthesizer chip. -On board BIOS is enabled. - PC-9801-86サウンドボードを挿します。 -ヤマハのOPNA FM音源チップが使用されています。 -ボード上のBIOSを有効にします。 - - - - PC-9801-86 sound board has connected. -This uses YAMAHA YM-2608 OPNA synthesizer chip. -On board BIOS is disabled. - PC-9801-86サウンドボードを挿します。 -ヤマハのOPNA FM音源チップが使用されています。 -ボード上のBIOSは無効です。 - - - - PC-9801-26 sound board has connected. -This uses YAMAHA YM-2203 OPN synthesizer chip. -On board BIOS is enabled. - PC-9801-26 サウンドボードを接続します。 -ヤマハYM-2203(OPN) FM音源を搭載しています。 -オンボードBIOSが使用できます。 - - - - PC-9801-26 sound board has connected. -This uses YAMAHA YM-2203 OPN synthesizer chip. -On board BIOS is disabled. - PC-9801-26 サウンドボードを接続します。 -ヤマハYM-2203(OPN) FM音源を搭載しています。 -オンボードBIOSは無効です。 - - - - PC-9801-14 sound board has connected. -This uses TI TMS3631-RI104 synthesizer chip. -On board BIOS is enabled. - PC-9801-14 サウンドボードを接続します。 -TI TMS3631-RI104 シンセサイザチップを搭載しています。 -オンボードBIOSが使用できます。 - - - - PC-9801-14 sound board has connected. -This uses TI TMS3631-RI104 synthesizer chip. -On board BIOS is disabled. - PC-9801-14 サウンドボードを接続します。 -TI TMS3631-RI104 シンセサイザチップを搭載しています。 -オンボードBIOSは無効です。 - - - - None sound devices has connected. - 拡張サウンドデバイスを接続しません。 - - - - Enable V30 SUB CPU(need RESTART). - V30サブCPU有効(要再起動) - - - - Enable emulation of V30 SUB CPU. -This may make emulation speed slower. -You must restart emulator after reboot. - V30サブCPUを有効にしてエミュレートします。 -有効にすることで、エミュレーション速度が低下するかも知れません。 -変更したら、エミュレータを動かし直す必要があります(リセットではなく)。 - - - - CPU Frequency - CPU周波数 - - - - 512KB RAM - - - - - Set lower RAM size to 512KB(not 640KB). -Maybe for backward compatibility. - 低いアドレスのRAM(コンベンショナルメモリ)の大きさを512KBにします(640KBではない)。 -後方互換性で有効なオプションかも知れません。 - - - - INIT MEMSW(need RESET) - メモリスイッチを初期化する(要リセット) - - - - Initialize memory switch. -Effects after resetting. - メモリスイッチを初期化します。 -リセット後に有効になります。 - - - - FAST GDC - 高速GDC - - - - Set GDC clock to 5MHz when checked. -Set to 2.5MHz wjhen not checked. - GDCクロックを5MHzに設定します。 -チェックしない場合、2.5MHzに設定されます。 - - - - USE EGC - EGCを使う - - - - Use Enhanced Graphic controller when checked. - チェックするとEGC(Enhanced Graphic Controller)を有効にします。 - - - - Machine Mode - 起動モード - - - - PC-9801 Mode. -You can run softwares of PC-9801 series. -May be earlier than PC-9801VM. - PC-9801モード。 -(たぶん)PC-9801VM以前のソフトウェアが実行可能です。 - - - - PC8801 V1(Standard) Mode. -You can run softwares of PC-8801/mk2. - PC-8801 V1(標準)モード。 -PC-8801/mk2のソフトウェアが実行可能です。 - - - - PC8801 V1(High Speed) Mode. -You can run softwares of PC-8801/mk2 faster. - PC-8801 V1(高速)モード。 -PC-8801/mk2のソフトウェアがより高速に実行可能です。 - - - - PC8801 V2 Mode. -You can run only softwares for PC-8801SR or later. - PC-8801 V2モード。 -PC-8801mk2SR以降専用のソフトウェアが実行できます。 - - - - PC8801 N Mode. -You can run softwares of PC-8001/mk2. - PC-8801 Nモード。 -PC-8001/mk2向けのソフトウェアが実行できます。 - - - - Memory Wait - メモリウェイト - - - - Simulate waiting memory. - メモリウェイトをシミュレートします。 - - - - NEC PC-PR201 kanji serial printer. - NEC PC-PR201漢字シリアルプリンタを接続します。 - - - - PC-80S31K CPU - PC-80S31K(外付けドライブ)のCPU - - - - PC-98 Main CPU - PC-98のメインCPU(ix86) - - - - PC-88 Main CPU - PC-88のメインCPU(Z80) - - - - PC-88 Sub CPU - PC-88のサブCPU(Z80) - - - Display Mode - 表示モード - - - - High Resolution - ハイレゾ - - - - Standard Resolution - Standarsd Resolution - 標準 - - - diff --git a/source/src/qt/machines/pc98ha/CMakeLists.txt b/source/src/qt/machines/pc98ha/CMakeLists.txt index 6c54cb3c3..a247a9094 100644 --- a/source/src/qt/machines/pc98ha/CMakeLists.txt +++ b/source/src/qt/machines/pc98ha/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/pc98ha") +message("* qt/${EXE_NAME}") set(s_qt_pc98ha_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pc98ha_headers_MOC ${s_qt_pc98ha_headers}) -else() - QT4_WRAP_CPP(s_qt_pc98ha_headers_MOC ${s_qt_pc98ha_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pc98ha_headers}) -add_library(qt_pc98ha +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pc98ha_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pc98ha/pc98ha.ts b/source/src/qt/machines/pc98ha/pc98ha.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pc98ha/pc98ha.ts rename to source/src/qt/machines/pc98ha/pc98ha.ja_JP.ts diff --git a/source/src/qt/machines/pcengine/CMakeLists.txt b/source/src/qt/machines/pcengine/CMakeLists.txt index b96fdf515..368a89104 100644 --- a/source/src/qt/machines/pcengine/CMakeLists.txt +++ b/source/src/qt/machines/pcengine/CMakeLists.txt @@ -1,16 +1,14 @@ -message("* qt/pcengine") +message("* qt/${EXE_NAME}") set(s_qt_pce_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pce_headers_MOC ${s_qt_pce_headers}) -else() - QT4_WRAP_CPP(s_qt_pce_headers_MOC ${s_qt_pce_headers}) -endif() -add_library(qt_pcengine + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_pce_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_pce_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/pcengine/pcengine.ts b/source/src/qt/machines/pcengine/pcengine.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pcengine/pcengine.ts rename to source/src/qt/machines/pcengine/pcengine.ja_JP.ts diff --git a/source/src/qt/machines/phc20/CMakeLists.txt b/source/src/qt/machines/phc20/CMakeLists.txt index 9a18d1abb..201b0bb4e 100644 --- a/source/src/qt/machines/phc20/CMakeLists.txt +++ b/source/src/qt/machines/phc20/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/phc20") +message("* qt/${EXE_NAME}") set(s_qt_phc20_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_phc20_headers_MOC ${s_qt_phc20_headers}) -else() - QT4_WRAP_CPP(s_qt_phc20_headers_MOC ${s_qt_phc20_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_phc20_headers}) -add_library(qt_phc20 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_phc20_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/phc20/phc20.ts b/source/src/qt/machines/phc20/phc20.ja_JP.ts similarity index 100% rename from source/src/qt/machines/phc20/phc20.ts rename to source/src/qt/machines/phc20/phc20.ja_JP.ts diff --git a/source/src/qt/machines/phc25/CMakeLists.txt b/source/src/qt/machines/phc25/CMakeLists.txt index d0adf86b5..4a2ef3efc 100644 --- a/source/src/qt/machines/phc25/CMakeLists.txt +++ b/source/src/qt/machines/phc25/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/phc25") +message("* qt/${EXE_NAME}") set(s_qt_phc25_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_phc25_headers_MOC ${s_qt_phc25_headers}) -else() - QT4_WRAP_CPP(s_qt_phc25_headers_MOC ${s_qt_phc25_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_phc25_headers}) -add_library(qt_phc25 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_phc25_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/phc25/phc25.ts b/source/src/qt/machines/phc25/phc25.ja_JP.ts similarity index 100% rename from source/src/qt/machines/phc25/phc25.ts rename to source/src/qt/machines/phc25/phc25.ja_JP.ts diff --git a/source/src/qt/machines/pv1000/CMakeLists.txt b/source/src/qt/machines/pv1000/CMakeLists.txt index e0c25d3f5..219b4c510 100644 --- a/source/src/qt/machines/pv1000/CMakeLists.txt +++ b/source/src/qt/machines/pv1000/CMakeLists.txt @@ -1,18 +1,13 @@ -message("* qt/pv1000") +message("* qt/emupv1000") set(s_qt_pv1000_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pv1000_headers_MOC ${s_qt_pv1000_headers}) -else() - QT4_WRAP_CPP(s_qt_pv1000_headers_MOC ${s_qt_pv1000_headers}) -endif() - -add_library(qt_pv1000 +QT5_WRAP_CPP(s_qt_emupv1000_headers_MOC ${s_qt_pv1000_headers}) +add_library(qt_emupv1000 MainWindow.cpp - ${s_qt_pv1000_headers_MOC} + ${s_qt_emupv1000_headers_MOC} ) diff --git a/source/src/qt/machines/pv1000/pv1000.ts b/source/src/qt/machines/pv1000/pv1000.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pv1000/pv1000.ts rename to source/src/qt/machines/pv1000/pv1000.ja_JP.ts diff --git a/source/src/qt/machines/pv2000/CMakeLists.txt b/source/src/qt/machines/pv2000/CMakeLists.txt index 5b3b3ed00..8d069e0d5 100644 --- a/source/src/qt/machines/pv2000/CMakeLists.txt +++ b/source/src/qt/machines/pv2000/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/pv2000") +message("* qt/emupv2000") -set(s_qt_pv2000_headers +set(s_qt_emupv2000_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pv2000_headers_MOC ${s_qt_pv2000_headers}) -else() - QT4_WRAP_CPP(s_qt_pv2000_headers_MOC ${s_qt_pv2000_headers}) -endif() +QT5_WRAP_CPP(s_qt_emupv2000_headers_MOC ${s_qt_emupv2000_headers}) -add_library(qt_pv2000 +add_library(qt_emupv2000 MainWindow.cpp - ${s_qt_pv2000_headers_MOC} + ${s_qt_emupv2000_headers_MOC} ) diff --git a/source/src/qt/machines/pv2000/pv2000.ts b/source/src/qt/machines/pv2000/pv2000.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pv2000/pv2000.ts rename to source/src/qt/machines/pv2000/pv2000.ja_JP.ts diff --git a/source/src/qt/machines/pyuta/CMakeLists.txt b/source/src/qt/machines/pyuta/CMakeLists.txt index a0efc9350..7ca7e7394 100644 --- a/source/src/qt/machines/pyuta/CMakeLists.txt +++ b/source/src/qt/machines/pyuta/CMakeLists.txt @@ -3,14 +3,12 @@ message("* qt/pyuta") set(s_qt_pyuta_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_pyuta_headers_MOC ${s_qt_pyuta_headers}) -else() - QT4_WRAP_CPP(s_qt_pyuta_headers_MOC ${s_qt_pyuta_headers}) -endif() -add_library(qt_pyuta + +QT5_WRAP_CPP(s_qt_emupyuta_headers_MOC ${s_qt_pyuta_headers}) + +add_library(qt_emupyuta MainWindow.cpp - ${s_qt_pyuta_headers_MOC} + ${s_qt_emupyuta_headers_MOC} ) diff --git a/source/src/qt/machines/pyuta/pyuta.ts b/source/src/qt/machines/pyuta/pyuta.ja_JP.ts similarity index 100% rename from source/src/qt/machines/pyuta/pyuta.ts rename to source/src/qt/machines/pyuta/pyuta.ja_JP.ts diff --git a/source/src/qt/machines/qc10/CMakeLists.txt b/source/src/qt/machines/qc10/CMakeLists.txt index 3019d2ddd..46561848d 100644 --- a/source/src/qt/machines/qc10/CMakeLists.txt +++ b/source/src/qt/machines/qc10/CMakeLists.txt @@ -1,18 +1,11 @@ -message("* qt/qc10") +message("* qt/${EXE_NAME}") set(s_qt_qc10_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_qc10_headers_MOC ${s_qt_qc10_headers}) -else() - QT4_WRAP_CPP(s_qt_qc10_headers_MOC ${s_qt_qc10_headers}) -endif() - -add_library(qt_qc10 +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_qc10_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_qc10_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) - - diff --git a/source/src/qt/machines/qc10/qc10.ts b/source/src/qt/machines/qc10/qc10.ja_JP.ts similarity index 100% rename from source/src/qt/machines/qc10/qc10.ts rename to source/src/qt/machines/qc10/qc10.ja_JP.ts diff --git a/source/src/qt/machines/rx78/CMakeLists.txt b/source/src/qt/machines/rx78/CMakeLists.txt index 607234187..40b893d11 100644 --- a/source/src/qt/machines/rx78/CMakeLists.txt +++ b/source/src/qt/machines/rx78/CMakeLists.txt @@ -1,18 +1,14 @@ -message("* qt/rx78") +message("* qt/${EXE_NAME}") set(s_qt_rx78_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_rx78_headers_MOC ${s_qt_rx78_headers}) -else() - QT4_WRAP_CPP(s_qt_rx78_headers_MOC ${s_qt_rx78_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_rx78_headers}) -add_library(qt_rx78 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_rx78_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/rx78/rx78.ts b/source/src/qt/machines/rx78/rx78.ja_JP.ts similarity index 100% rename from source/src/qt/machines/rx78/rx78.ts rename to source/src/qt/machines/rx78/rx78.ja_JP.ts diff --git a/source/src/qt/machines/sc3000/CMakeLists.txt b/source/src/qt/machines/sc3000/CMakeLists.txt index 5ffeff046..5f05ee75b 100644 --- a/source/src/qt/machines/sc3000/CMakeLists.txt +++ b/source/src/qt/machines/sc3000/CMakeLists.txt @@ -4,15 +4,16 @@ set(s_qt_sc3000_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_sc3000_headers_MOC ${s_qt_sc3000_headers}) -else() - QT4_WRAP_CPP(s_qt_sc3000_headers_MOC ${s_qt_sc3000_headers}) -endif() +message("* qt/${EXE_NAME}") -add_library(qt_sc3000 +set(s_qt_gamegear_headers + menuclasses.h +) + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_sc3000_headers}) +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_sc3000_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/sc3000/sc3000.ts b/source/src/qt/machines/sc3000/sc3000.ja_JP.ts similarity index 100% rename from source/src/qt/machines/sc3000/sc3000.ts rename to source/src/qt/machines/sc3000/sc3000.ja_JP.ts diff --git a/source/src/qt/machines/scv/CMakeLists.txt b/source/src/qt/machines/scv/CMakeLists.txt index 37a45c0ad..b7c228b0f 100644 --- a/source/src/qt/machines/scv/CMakeLists.txt +++ b/source/src/qt/machines/scv/CMakeLists.txt @@ -3,14 +3,12 @@ message("* qt/scv") set(s_qt_scv_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_scv_headers_MOC ${s_qt_scv_headers}) -else() - QT4_WRAP_CPP(s_qt_scv_headers_MOC ${s_qt_scv_headers}) -endif() -add_library(qt_scv + +QT5_WRAP_CPP(s_qt_emuscv_headers_MOC ${s_qt_scv_headers}) + +add_library(qt_emuscv MainWindow.cpp - ${s_qt_scv_headers_MOC} + ${s_qt_emuscv_headers_MOC} ) diff --git a/source/src/qt/machines/scv/scv.ts b/source/src/qt/machines/scv/scv.ja_JP.ts similarity index 100% rename from source/src/qt/machines/scv/scv.ts rename to source/src/qt/machines/scv/scv.ja_JP.ts diff --git a/source/src/qt/machines/smb80te/CMakeLists.txt b/source/src/qt/machines/smb80te/CMakeLists.txt index 18605f15f..8fd7723ff 100644 --- a/source/src/qt/machines/smb80te/CMakeLists.txt +++ b/source/src/qt/machines/smb80te/CMakeLists.txt @@ -3,12 +3,10 @@ message("* qt/smb80te") set(s_qt_smb80te_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_smb80te_headers_MOC ${s_qt_smb80te_headers}) -else() - QT4_WRAP_CPP(s_qt_smb80te_headers_MOC ${s_qt_smb80te_headers}) -endif() -add_library(qt_smb80te + +QT5_WRAP_CPP(s_qt_smb80te_headers_MOC ${s_qt_smb80te_headers}) + +add_library(qt_emusmb80te MainWindow.cpp ${s_qt_smb80te_headers_MOC} ) diff --git a/source/src/qt/machines/smb80te/smb80te.ts b/source/src/qt/machines/smb80te/smb80te.ja_JP.ts similarity index 100% rename from source/src/qt/machines/smb80te/smb80te.ts rename to source/src/qt/machines/smb80te/smb80te.ja_JP.ts diff --git a/source/src/qt/machines/smc777/CMakeLists.txt b/source/src/qt/machines/smc777/CMakeLists.txt index fd429b812..3d92f20a0 100644 --- a/source/src/qt/machines/smc777/CMakeLists.txt +++ b/source/src/qt/machines/smc777/CMakeLists.txt @@ -1,17 +1,13 @@ -message("* qt/smc777") +message("* qt/${EXE_NAME}") set(s_qt_smc777_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_smc777_headers_MOC ${s_qt_smc777_headers}) -else() - QT4_WRAP_CPP(s_qt_smc777_headers_MOC ${s_qt_smc777_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_smc777_headers}) -add_library(qt_smc777 +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_smc777_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/smc777/MainWindow.cpp b/source/src/qt/machines/smc777/MainWindow.cpp index 1d2f9a00b..d8e5ddc7c 100644 --- a/source/src/qt/machines/smc777/MainWindow.cpp +++ b/source/src/qt/machines/smc777/MainWindow.cpp @@ -31,7 +31,8 @@ void META_MainWindow::retranslateUi(void) Ui_MainWindowBase::retranslateUi(); retranslateControlMenu("RESET", true); actionReset->setVisible(false); - actionSpecial_Reset->setToolTip(QApplication::translate("MainWindow", "Do reset.", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MainWindow", "RESET", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MainWindow", "Do reset.", 0)); #if defined(_SMC70) menuBootMode->setTitle(QApplication::translate("MainWindow", "Auto Start SW:", 0)); diff --git a/source/src/qt/machines/smc777/smc777.ts b/source/src/qt/machines/smc777/smc777.ja_JP.ts similarity index 100% rename from source/src/qt/machines/smc777/smc777.ts rename to source/src/qt/machines/smc777/smc777.ja_JP.ts diff --git a/source/src/qt/machines/svi3x8/CMakeLists.txt b/source/src/qt/machines/svi3x8/CMakeLists.txt new file mode 100644 index 000000000..31aa49d7d --- /dev/null +++ b/source/src/qt/machines/svi3x8/CMakeLists.txt @@ -0,0 +1,14 @@ +message("* qt/${EXE_NAME}") + +set(s_qt_svi3x8_headers_${EXE_NAME} + menuclasses.h +) + +QT5_WRAP_CPP(s_qt_svi3x8_headers_${EXE_NAME}_MOC ${s_qt_svi3x8_headers_${EXE_NAME}}) + +add_library(qt_${EXE_NAME} + MainWindow.cpp + ${s_qt_svi3x8_headers_${EXE_NAME}_MOC} +) + + diff --git a/source/src/qt/machines/svi3x8/MainWindow.cpp b/source/src/qt/machines/svi3x8/MainWindow.cpp new file mode 100644 index 000000000..3aa363f37 --- /dev/null +++ b/source/src/qt/machines/svi3x8/MainWindow.cpp @@ -0,0 +1,64 @@ +/* + * Common Source code Project: + * Ui->Qt->MainWindow for Babbage2nd . + * (C) 2015 K.Ohta + * License : GPLv2 + * History : + * Jan 14, 2015 : Initial, many of constructors were moved to qt/gui/menu_main.cpp. + */ + +#include +#include +#include +#include "menuclasses.h" +#include "commonclasses.h" + +#include "emu.h" +#include "qt_main.h" +#include "vm.h" + +//QT_BEGIN_NAMESPACE + + +void META_MainWindow::retranslateUi(void) +{ + Ui_MainWindowBase::retranslateUi(); + retranslateControlMenu("", false); + // Set Labels +#if defined(USE_PRINTER) + actionPrintDevice[1]->setText(QString::fromUtf8("MSX Printer")); + actionPrintDevice[2]->setText(QString::fromUtf8("PC-PR201")); + actionPrintDevice[1]->setToolTip(QApplication::translate("MachineSvi3x8", "Use MSX spec. printer.", 0)); + actionPrintDevice[2]->setToolTip(QApplication::translate("MachineSvi3x8", "Use NEC PC-PR201 kanji serial printer.", 0)); + actionPrintDevice[1]->setEnabled(false); + actionPrintDevice[2]->setEnabled(false); +#endif +#ifdef USE_DEBUGGER + actionDebugger[0]->setVisible(true); + actionDebugger[1]->setVisible(false); + actionDebugger[2]->setVisible(false); + actionDebugger[3]->setVisible(false); +#endif + +} // retranslateUi + +void META_MainWindow::setupUI_Emu(void) +{ +} + + +META_MainWindow::META_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent) : Ui_MainWindow(p, logger, parent) +{ + setupUI_Emu(); + retranslateUi(); +} + + +META_MainWindow::~META_MainWindow() +{ +} + +//QT_END_NAMESPACE + + + diff --git a/source/src/qt/machines/svi3x8/menuclasses.h b/source/src/qt/machines/svi3x8/menuclasses.h new file mode 100644 index 000000000..ee35813a9 --- /dev/null +++ b/source/src/qt/machines/svi3x8/menuclasses.h @@ -0,0 +1,26 @@ + +#ifndef _CSP_QT_MENUCLASSES_H +#define _CSP_QT_MENUCLASSES_H + +#include "mainwidget.h" +// This extends class CSP_MainWindow as Ui_MainWindow. +// You may use this as +QT_BEGIN_NAMESPACE + +class Ui_MainWindow; +class USING_FLAGS; +class CSP_Logger; +// wrote of Specific menu. +class META_MainWindow : public Ui_MainWindow { + Q_OBJECT +protected: + void setupUI_Emu(void); + void retranslateUi(void); +public: + META_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent = 0); + ~META_MainWindow(); +}; + +QT_END_NAMESPACE + +#endif // END diff --git a/source/src/qt/machines/svi3x8/svi3x8.ja_JP.ts b/source/src/qt/machines/svi3x8/svi3x8.ja_JP.ts new file mode 100644 index 000000000..5234f6142 --- /dev/null +++ b/source/src/qt/machines/svi3x8/svi3x8.ja_JP.ts @@ -0,0 +1,17 @@ + + + + + MachineSvi3x8 + + + Use MSX spec. printer. + MSX標準のプリンターを使います。 + + + + Use NEC PC-PR201 kanji serial printer. + NEC PC-PR201漢字シリアルプリンターを使います。 + + + diff --git a/source/src/qt/machines/tk80bs/CMakeLists.txt b/source/src/qt/machines/tk80bs/CMakeLists.txt index 35ed8862e..5eaea64ff 100644 --- a/source/src/qt/machines/tk80bs/CMakeLists.txt +++ b/source/src/qt/machines/tk80bs/CMakeLists.txt @@ -1,16 +1,14 @@ -message("* qt/tk80bs") +message("* qt/${EXE_NAME}") set(s_qt_tk80bs_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_tk80bs_headers_MOC ${s_qt_tk80bs_headers}) -else() - QT4_WRAP_CPP(s_qt_tk80bs_headers_MOC ${s_qt_tk80bs_headers}) -endif() -add_library(qt_tk80bs + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_tk80bs_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_tk80bs_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/tk80bs/tk80bs.ts b/source/src/qt/machines/tk80bs/tk80bs.ja_JP.ts similarity index 100% rename from source/src/qt/machines/tk80bs/tk80bs.ts rename to source/src/qt/machines/tk80bs/tk80bs.ja_JP.ts diff --git a/source/src/qt/machines/tvboy/CMakeLists.txt b/source/src/qt/machines/tvboy/CMakeLists.txt new file mode 100644 index 000000000..345238620 --- /dev/null +++ b/source/src/qt/machines/tvboy/CMakeLists.txt @@ -0,0 +1,14 @@ +message("* qt/${EXE_NAME}") + +set(s_qt_tvboy_headers_${EXE_NAME} + menuclasses.h +) + +QT5_WRAP_CPP(s_qt_tvboy_headers_${EXE_NAME}_MOC ${s_qt_tvboy_headers_${EXE_NAME}}) + +add_library(qt_${EXE_NAME} + MainWindow.cpp + ${s_qt_tvboy_headers_${EXE_NAME}_MOC} +) + + diff --git a/source/src/qt/machines/tvboy/MainWindow.cpp b/source/src/qt/machines/tvboy/MainWindow.cpp new file mode 100644 index 000000000..e1db3a47d --- /dev/null +++ b/source/src/qt/machines/tvboy/MainWindow.cpp @@ -0,0 +1,56 @@ +/* + * Common Source code Project: + * Ui->Qt->MainWindow for Babbage2nd . + * (C) 2015 K.Ohta + * License : GPLv2 + * History : + * Jan 14, 2015 : Initial, many of constructors were moved to qt/gui/menu_main.cpp. + */ + +#include +#include +#include +#include "menuclasses.h" +#include "commonclasses.h" + +#include "emu.h" +#include "qt_main.h" +#include "vm.h" + +//QT_BEGIN_NAMESPACE + + +void META_MainWindow::retranslateUi(void) +{ + Ui_MainWindowBase::retranslateUi(); + retranslateControlMenu("", false); + // Set Labels +#ifdef USE_DEBUGGER + actionDebugger[0]->setVisible(true); + actionDebugger[1]->setVisible(false); + actionDebugger[2]->setVisible(false); + actionDebugger[3]->setVisible(false); +#endif + +} // retranslateUi + +void META_MainWindow::setupUI_Emu(void) +{ +} + + +META_MainWindow::META_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent) : Ui_MainWindow(p, logger, parent) +{ + setupUI_Emu(); + retranslateUi(); +} + + +META_MainWindow::~META_MainWindow() +{ +} + +//QT_END_NAMESPACE + + + diff --git a/source/src/qt/machines/tvboy/menuclasses.h b/source/src/qt/machines/tvboy/menuclasses.h new file mode 100644 index 000000000..ee35813a9 --- /dev/null +++ b/source/src/qt/machines/tvboy/menuclasses.h @@ -0,0 +1,26 @@ + +#ifndef _CSP_QT_MENUCLASSES_H +#define _CSP_QT_MENUCLASSES_H + +#include "mainwidget.h" +// This extends class CSP_MainWindow as Ui_MainWindow. +// You may use this as +QT_BEGIN_NAMESPACE + +class Ui_MainWindow; +class USING_FLAGS; +class CSP_Logger; +// wrote of Specific menu. +class META_MainWindow : public Ui_MainWindow { + Q_OBJECT +protected: + void setupUI_Emu(void); + void retranslateUi(void); +public: + META_MainWindow(USING_FLAGS *p, CSP_Logger *logger, QWidget *parent = 0); + ~META_MainWindow(); +}; + +QT_END_NAMESPACE + +#endif // END diff --git a/source/src/qt/machines/tvboy/tvboy.ja_JP.ts b/source/src/qt/machines/tvboy/tvboy.ja_JP.ts new file mode 100644 index 000000000..0b5611e81 --- /dev/null +++ b/source/src/qt/machines/tvboy/tvboy.ja_JP.ts @@ -0,0 +1,4 @@ + + + + diff --git a/source/src/qt/machines/x07/CMakeLists.txt b/source/src/qt/machines/x07/CMakeLists.txt index f3930178a..3702f3b04 100644 --- a/source/src/qt/machines/x07/CMakeLists.txt +++ b/source/src/qt/machines/x07/CMakeLists.txt @@ -1,16 +1,14 @@ -message("* qt/x07") +message("* qt/emux07") set(s_qt_x07_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_x07_headers_MOC ${s_qt_x07_headers}) -else() - QT4_WRAP_CPP(s_qt_x07_headers_MOC ${s_qt_x07_headers}) -endif() -add_library(qt_x07 + +QT5_WRAP_CPP(s_qt_emux07_headers_MOC ${s_qt_x07_headers}) + +add_library(qt_emux07 MainWindow.cpp - ${s_qt_x07_headers_MOC} + ${s_qt_emux07_headers_MOC} ) diff --git a/source/src/qt/machines/x07/x07.ts b/source/src/qt/machines/x07/x07.ja_JP.ts similarity index 100% rename from source/src/qt/machines/x07/x07.ts rename to source/src/qt/machines/x07/x07.ja_JP.ts diff --git a/source/src/qt/machines/x1/CMakeLists.txt b/source/src/qt/machines/x1/CMakeLists.txt index 3a2603d89..f89f7231a 100644 --- a/source/src/qt/machines/x1/CMakeLists.txt +++ b/source/src/qt/machines/x1/CMakeLists.txt @@ -1,16 +1,14 @@ -message("* qt/x1turboz") +message("* qt/${EXE_NAME}") set(s_qt_x1turboz_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_x1turboz_headers_MOC ${s_qt_x1turboz_headers}) -else() - QT4_WRAP_CPP(s_qt_x1turboz_headers_MOC ${s_qt_x1turboz_headers}) -endif() -add_library(qt_x1 + +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_x1turboz_headers}) + +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_x1turboz_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/x1/MainWindow.cpp b/source/src/qt/machines/x1/MainWindow.cpp index 4f41bac92..477a699bb 100644 --- a/source/src/qt/machines/x1/MainWindow.cpp +++ b/source/src/qt/machines/x1/MainWindow.cpp @@ -50,8 +50,8 @@ void META_MainWindow::retranslateUi(void) retranslateFloppyMenu(0, 0, QApplication::translate("MachineX1", "FDD", 0)); retranslateFloppyMenu(1, 1, QApplication::translate("MachineX1", "FDD", 0)); - actionSpecial_Reset->setText(QApplication::translate("Machine", "NMI Reset", 0)); - actionSpecial_Reset->setToolTip(QApplication::translate("MachineX1", "Do NMI reset.", 0)); + actionSpecial_Reset[0]->setText(QApplication::translate("Machine", "NMI Reset", 0)); + actionSpecial_Reset[0]->setToolTip(QApplication::translate("MachineX1", "Do NMI reset.", 0)); // Set Labels menuSoundDevice->setTitle(QApplication::translate("MachineX1", "Sound Device", 0)); diff --git a/source/src/qt/machines/x1/x1.ts b/source/src/qt/machines/x1/x1.ja_JP.ts similarity index 100% rename from source/src/qt/machines/x1/x1.ts rename to source/src/qt/machines/x1/x1.ja_JP.ts diff --git a/source/src/qt/machines/yalky/CMakeLists.txt b/source/src/qt/machines/yalky/CMakeLists.txt index ef99e9bd5..3687846e3 100644 --- a/source/src/qt/machines/yalky/CMakeLists.txt +++ b/source/src/qt/machines/yalky/CMakeLists.txt @@ -4,14 +4,9 @@ set(s_qt_yalky_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_yalky_headers_MOC ${s_qt_yalky_headers}) -# QT5_ADD_RESOURCES(s_qt_fm7_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_yalky_headers_MOC ${s_qt_yalky_headers}) -endif() +QT5_WRAP_CPP(s_qt_yalky_headers_MOC ${s_qt_yalky_headers}) -add_library(qt_yalky +add_library(qt_emuyalky MainWindow.cpp ${s_qt_yalky_headers_MOC} ) diff --git a/source/src/qt/machines/yalky/yalky.ts b/source/src/qt/machines/yalky/yalky.ja_JP.ts similarity index 100% rename from source/src/qt/machines/yalky/yalky.ts rename to source/src/qt/machines/yalky/yalky.ja_JP.ts diff --git a/source/src/qt/machines/yis/CMakeLists.txt b/source/src/qt/machines/yis/CMakeLists.txt index 7be4fe63c..5e1e1ef04 100644 --- a/source/src/qt/machines/yis/CMakeLists.txt +++ b/source/src/qt/machines/yis/CMakeLists.txt @@ -1,19 +1,14 @@ -message("* qt/yis") +message("* qt/emuyis") set(s_qt_yis_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_yis_headers_MOC ${s_qt_yis_headers}) -# QT5_ADD_RESOURCES(s_qt_fm7_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_yis_headers_MOC ${s_qt_yis_headers}) -endif() +QT5_WRAP_CPP(s_qt_emuyis_headers_MOC ${s_qt_yis_headers}) -add_library(qt_yis +add_library(qt_emuyis MainWindow.cpp - ${s_qt_yis_headers_MOC} + ${s_qt_emuyis_headers_MOC} ) diff --git a/source/src/qt/machines/yis/yis.ts b/source/src/qt/machines/yis/yis.ja_JP.ts similarity index 100% rename from source/src/qt/machines/yis/yis.ts rename to source/src/qt/machines/yis/yis.ja_JP.ts diff --git a/source/src/qt/machines/ys6464a/CMakeLists.txt b/source/src/qt/machines/ys6464a/CMakeLists.txt index ce5836d32..430f9c182 100644 --- a/source/src/qt/machines/ys6464a/CMakeLists.txt +++ b/source/src/qt/machines/ys6464a/CMakeLists.txt @@ -4,14 +4,9 @@ set(s_qt_ys6464a_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_ys6464a_headers_MOC ${s_qt_ys6464a_headers}) -# QT5_ADD_RESOURCES(s_qt_fm7_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_ys6464a_headers_MOC ${s_qt_ys6464a_headers}) -endif() +QT5_WRAP_CPP(s_qt_ys6464a_headers_MOC ${s_qt_ys6464a_headers}) -add_library(qt_ys6464a +add_library(qt_emuys6464a MainWindow.cpp ${s_qt_ys6464a_headers_MOC} ) diff --git a/source/src/qt/machines/ys6464a/ys6464a.ts b/source/src/qt/machines/ys6464a/ys6464a.ja_JP.ts similarity index 100% rename from source/src/qt/machines/ys6464a/ys6464a.ts rename to source/src/qt/machines/ys6464a/ys6464a.ja_JP.ts diff --git a/source/src/qt/machines/z80tvgame/CMakeLists.txt b/source/src/qt/machines/z80tvgame/CMakeLists.txt index b8ab5bf0d..3f9b75a84 100644 --- a/source/src/qt/machines/z80tvgame/CMakeLists.txt +++ b/source/src/qt/machines/z80tvgame/CMakeLists.txt @@ -1,19 +1,14 @@ -message("* qt/z80tvgame") +message("* qt/${EXE_NAME}") set(s_qt_z80tvgame_headers menuclasses.h ) -if(USE_QT_5) - QT5_WRAP_CPP(s_qt_z80tvgame_headers_MOC ${s_qt_z80tvgame_headers}) -# QT5_ADD_RESOURCES(s_qt_fm7_headers_RCC ${RESOURCE}) -else() - QT4_WRAP_CPP(s_qt_z80tvgame_headers_MOC ${s_qt_z80tvgame_headers}) -endif() +QT5_WRAP_CPP(s_qt_${EXE_NAME}_headers_MOC ${s_qt_z80tvgame_headers}) -add_library(qt_z80tvgame +add_library(qt_${EXE_NAME} MainWindow.cpp - ${s_qt_z80tvgame_headers_MOC} + ${s_qt_${EXE_NAME}_headers_MOC} ) diff --git a/source/src/qt/machines/z80tvgame/z80tvgame.ts b/source/src/qt/machines/z80tvgame/z80tvgame.ja_JP.ts similarity index 100% rename from source/src/qt/machines/z80tvgame/z80tvgame.ts rename to source/src/qt/machines/z80tvgame/z80tvgame.ja_JP.ts diff --git a/source/src/qt/osd.cpp b/source/src/qt/osd.cpp index 5ebb429d2..126721961 100644 --- a/source/src/qt/osd.cpp +++ b/source/src/qt/osd.cpp @@ -32,17 +32,6 @@ OSD::~OSD() { } -void OSD::debug_log(int level, int domain_num, char *strbuf) -{ - if(p_logger != NULL) p_logger->debug_log(level, domain_num, strbuf); -} - - -void OSD::set_device_name(int id, char *name) -{ - if(p_logger != NULL) p_logger->set_device_name(id, (char *)name); -} - void OSD::set_features_machine(void) { // GIJUTSU-HYORON-SHA Babbase-2nd @@ -608,15 +597,24 @@ void OSD::set_features_cpu(void) #ifdef HAS_I386 add_feature(_T("HAS_I386"), 1); #endif +#ifdef HAS_I386DX + add_feature(_T("HAS_I386DX"), 1); +#endif +#ifdef HAS_I386SX + add_feature(_T("HAS_I386SX"), 1); +#endif #ifdef HAS_I486 add_feature(_T("HAS_I486"), 1); #endif +#ifdef HAS_I486SX + add_feature(_T("HAS_I486SX"), 1); +#endif +#ifdef HAS_I486DX + add_feature(_T("HAS_I486DX"), 1); +#endif #ifdef HAS_PENTIUM add_feature(_T("HAS_PENTIUM"), 1); #endif -#ifdef HAS_MEDIAGX - add_feature(_T("HAS_MEDIAGX"), 1); -#endif #ifdef HAS_PENTIUM_PRO add_feature(_T("HAS_PENTIUM_PRO"), 1); #endif @@ -1040,6 +1038,9 @@ void OSD::set_features_vm(void) #ifdef _X1TURBO_FEATURE add_feature(_T("_X1TURBO_FEATURE"), 1); #endif +#ifdef MEMORY_DISABLE_DMA_MMIO + add_feature(_T("MEMORY_DISABLE_DMA_MMIO"), 1); +#endif } void OSD::set_features_debug(void) @@ -1063,6 +1064,9 @@ void OSD::set_features_debug(void) #ifdef _SCSI_DEBUG_LOG add_feature(_T("_SCSI_DEBUG_LOG"), 1); #endif +#ifdef _CDROM_DEBUG_LOG + add_feature(_T("_CDROM_DEBUG_LOG"), 1); +#endif #ifdef _DEBUG_PC80S31K add_feature(_T("_DEBUG_PC80S31K"), 1); #endif @@ -1083,10 +1087,10 @@ void OSD::set_features_misc(void) add_feature(_T("SINGLE_MODE_DMA"), 1); #endif #ifdef MEMORY_ADDR_MAX - add_feature(_T("MEMORY_ADDR_MAX"), (uint32_t)MEMORY_ADDR_MAX); + add_feature(_T("MEMORY_ADDR_MAX"), (uint64_t)MEMORY_ADDR_MAX); #endif #ifdef MEMORY_BANK_SIZE - add_feature(_T("MEMORY_BANK_SIZE"), (uint32_t)MEMORY_BANK_SIZE); + add_feature(_T("MEMORY_BANK_SIZE"), (uint64_t)MEMORY_BANK_SIZE); #endif #ifdef IOBUS_RETURN_ADDR add_feature(_T("IOBUS_RETURN_ADDR"), 1); @@ -1150,13 +1154,9 @@ void OSD::set_features(void) set_features_debug(); __USE_AUTO_KEY = false; - __USE_SHIFT_NUMPAD_KEY = false; #ifdef USE_AUTO_KEY __USE_AUTO_KEY = true; #endif -#ifdef USE_SHIFT_NUMPAD_KEY - __USE_SHIFT_NUMPAD_KEY = true; -#endif } extern std::string cpp_homedir; @@ -1188,9 +1188,6 @@ void OSD::initialize(int rate, int samples, int* presented_rate, int* presented_ initialize_printer(); initialize_screen(); initialize_sound(rate, samples, presented_rate, presented_samples); -#if defined(USE_SOUND_FILES) - init_sound_files(); -#endif if(get_use_movie_player() || get_use_video_capture()) initialize_video(); if(get_use_socket()) initialize_socket(); @@ -1204,13 +1201,5 @@ void OSD::release() release_sound(); if(get_use_movie_player() || get_use_video_capture()) release_video(); if(get_use_socket()) release_socket(); -#if defined(USE_SOUND_FILES) - release_sound_files(); -#endif -} - -void OSD::power_off() -{ - emit sig_close_window(); } diff --git a/source/src/qt/osd.h b/source/src/qt/osd.h index 0b0c9db9a..7d3c265d9 100644 --- a/source/src/qt/osd.h +++ b/source/src/qt/osd.h @@ -12,6 +12,7 @@ #include "osd_base.h" #include "gui/qt_input.h" // Key code table (VK_foo). +#include "../vm/vm.h" class GLDrawClass; class EmuThreadClass; @@ -41,8 +42,6 @@ class OSD : public OSD_BASE protected: GLDrawClass *p_glv; - void vm_draw_screen(void); - Sint16* create_sound(int *extra_frames); bool get_use_socket(void); bool get_use_auto_key(void); bool get_dont_keeep_key_pressed(void); @@ -50,9 +49,6 @@ class OSD : public OSD_BASE bool get_use_screen_rotate(void); bool get_use_movie_player(void); bool get_use_video_capture(void); - void vm_key_down(int code, bool flag); - void vm_key_up(int code); - void vm_reset(void); void update_buttons(bool press_flag, bool release_flag); int get_screen_width(void); int get_screen_height(void); @@ -67,26 +63,11 @@ class OSD : public OSD_BASE QTcpSocket2 *tcp_socket[SOCKET_MAX]; QUdpSocket2 *udp_socket[SOCKET_MAX]; -#ifdef USE_SOUND_FILES - SOUND_LOADER *tail_sound_file; - SOUND_LOADER *sound_file_obj[USE_SOUND_FILES]; - - void init_sound_files(); - void release_sound_files(); -#endif public: OSD(USING_FLAGS *p, CSP_Logger *logger); ~OSD(); void initialize(int rate, int samples, int* presented_rate, int* presented_samples); void release(); - void power_off(); - - // Wrapper - // Locker - void lock_vm(void); - void unlock_vm(void); - void force_unlock_vm(void); - bool is_vm_locked(void); // Screen void set_draw_thread(DrawThreadClass *handler); @@ -96,7 +77,8 @@ class OSD : public OSD_BASE int get_window_mode_height(int mode); double get_window_mode_power(int mode); QString get_vm_config_name(void); - double vm_frame_rate(void); + void reset_vm_node(void); + const _TCHAR *get_lib_common_vm_version(); // Movie/Video void get_video_buffer(); @@ -106,22 +88,12 @@ class OSD : public OSD_BASE void close_movie_file(); uint32_t get_cur_movie_frame(); int get_movie_sound_rate(); - int draw_screen(); bool set_glview(GLDrawClass *glv); GLDrawClass *get_gl_view() { return p_glv; } int add_video_frames(); - // Misc - void reset_vm_node(void); - const _TCHAR *get_lib_common_vm_version(); - const _TCHAR *get_lib_common_vm_git_version(); - int get_key_name_table_size(void); - uint32_t get_scancode_by_vk(uint32_t vk); - uint32_t get_vk_by_scancode(uint32_t scancode); - const _TCHAR *get_key_name_by_scancode(uint32_t scancode); - const _TCHAR *get_key_name_by_vk(uint32_t vk); // Socket void initialize_socket(); @@ -138,14 +110,12 @@ class OSD : public OSD_BASE void send_socket_data_udp(int ch, uint32_t ipaddr, int port); void send_socket_data(int ch); void recv_socket_data(int ch); - int get_socket(int ch); + SOCKET get_socket(int ch); - // Sound -#ifdef USE_SOUND_FILES - void load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size); - void free_sound_file(int id, int16_t **data); -#endif - void debug_log(int level, int domain_num, char *strbuf); + // Misc + double get_vm_current_usec(); + uint64_t get_vm_current_clock_uint64(); + public slots: void do_decode_movie(int frames); void do_run_movie_audio_callback(uint8_t *data, long len); diff --git a/source/src/qt/osd_base.cpp b/source/src/qt/osd_base.cpp index 2b5619122..fdb9800bb 100644 --- a/source/src/qt/osd_base.cpp +++ b/source/src/qt/osd_base.cpp @@ -36,17 +36,23 @@ #include "../config.h" #include "../fileio.h" #include "../fifo.h" +#include "../vm/device.h" + #include "qt_input.h" //#include "qt_main.h" //#include "csp_logger.h" #include "osd_base.h" +#include "gui/dock_disks.h" +#include "../vm/vm_template.h" -OSD_BASE::OSD_BASE(USING_FLAGS *p, CSP_Logger *logger) : QThread(0) +OSD_BASE::OSD_BASE(USING_FLAGS *p, CSP_Logger *logger) : QObject(0) { using_flags = p; vm_mutex = new QMutex(QMutex::Recursive); locked_vm = false; screen_mutex = new QMutex(QMutex::Recursive); + mouse_mutex = new QMutex(QMutex::Recursive); + device_node_list.clear(); max_vm_nodes = 0; p_logger = logger; @@ -65,6 +71,7 @@ OSD_BASE::OSD_BASE(USING_FLAGS *p, CSP_Logger *logger) : QThread(0) OSD_BASE::~OSD_BASE() { + delete mouse_mutex; delete vm_mutex; delete screen_mutex; } @@ -106,10 +113,6 @@ void OSD_BASE::release() { } -void OSD_BASE::power_off() -{ -} - void OSD_BASE::suspend() { if(get_use_movie_player()) { @@ -153,10 +156,6 @@ void OSD_BASE::debug_log(int level, int domain_num, const char *fmt, ...) va_end(ap); } -void OSD_BASE::debug_log(int level, int domain_num, char *strbuf) -{ -} - _TCHAR *OSD_BASE::get_app_path(void) { return app_path; @@ -208,21 +207,6 @@ _TCHAR* OSD_BASE::application_path() return app_path; } -void OSD_BASE::vm_draw_screen(void) -{ - -} - -double OSD_BASE::vm_frame_rate(void) -{ - return 59.94; -} - -Sint16* OSD_BASE::create_sound(int *extra_frames) -{ - return (Sint16 *)NULL; -} - bool OSD_BASE::get_use_socket(void) { @@ -259,17 +243,26 @@ bool OSD_BASE::get_use_video_capture(void) return false; } + void OSD_BASE::vm_key_down(int code, bool flag) { + if(vm != NULL) { + vm->key_down(code, flag); + } } void OSD_BASE::vm_key_up(int code) { + if(vm != NULL) { + vm->key_up(code); + } } void OSD_BASE::vm_reset(void) { - + if(vm != NULL) { + vm->reset(); + } } int OSD_BASE::get_vm_buttons_code(int num) @@ -299,10 +292,16 @@ int OSD_BASE::get_screen_height(void) void OSD_BASE::lock_vm(void) { locked_vm = true; + if(vm_mutex != NULL) { + vm_mutex->lock(); + } } void OSD_BASE::unlock_vm(void) { + if(vm_mutex != NULL) { + vm_mutex->unlock(); + } locked_vm = false; } @@ -314,6 +313,10 @@ bool OSD_BASE::is_vm_locked(void) void OSD_BASE::force_unlock_vm(void) { + if(vm_mutex != NULL) { + vm_mutex->unlock(); + } + locked_vm = false; } void OSD_BASE::set_draw_thread(DrawThreadClass *handler) @@ -353,13 +356,21 @@ double OSD_BASE::get_window_mode_power(int mode) void OSD_BASE::reset_vm_node(void) { + device_node_t sp; device_node_list.clear(); -// p_logger->reset(); + p_logger->reset(); max_vm_nodes = 0; } +void OSD_BASE::debug_log(int level, int domain_num, char *strbuf) +{ + if(p_logger != NULL) p_logger->debug_log(level, domain_num, strbuf); +} + + void OSD_BASE::set_device_name(int id, char *name) { + if(p_logger != NULL) p_logger->set_device_name(id, (char *)name); } void OSD_BASE::set_vm_node(int id, const _TCHAR *name) @@ -403,6 +414,7 @@ int OSD_BASE::get_vm_node_size(void) return max_vm_nodes; } + void OSD_BASE::add_feature(const _TCHAR *key, double value) { QString tmps; @@ -414,6 +426,7 @@ void OSD_BASE::add_feature(const _TCHAR *key, double value) SupportedFeatures.append(l); } } + void OSD_BASE::add_feature(const _TCHAR *key, int64_t value) { QString tmps; @@ -426,6 +439,18 @@ void OSD_BASE::add_feature(const _TCHAR *key, int64_t value) } } +void OSD_BASE::add_feature(const _TCHAR *key, uint64_t value) +{ + QString tmps; + supportedlist_t l; + tmps = QString::fromUtf8(key); + if(!check_feature(key)) { + l.string = tmps; + l.v.uvalue = value; + SupportedFeatures.append(l); + } +} + void OSD_BASE::add_feature(const _TCHAR *key, float value) { add_feature(key, (double)value); @@ -436,19 +461,30 @@ void OSD_BASE::add_feature(const _TCHAR *key, int value) add_feature(key, (int64_t)value); } + +void OSD_BASE::add_feature(const _TCHAR *key, int16_t value) +{ + add_feature(key, (int64_t)value); +} + +void OSD_BASE::add_feature(const _TCHAR *key, int8_t value) +{ + add_feature(key, (int64_t)value); +} + void OSD_BASE::add_feature(const _TCHAR *key, uint32_t value) { - add_feature(key, (int64_t)(value & 0xffffffff)); + add_feature(key, (uint64_t)(value & 0xffffffff)); } void OSD_BASE::add_feature(const _TCHAR *key, uint16_t value) { - add_feature(key, (int64_t)(value & 0xffff)); + add_feature(key, (uint64_t)(value & 0xffff)); } void OSD_BASE::add_feature(const _TCHAR *key, uint8_t value) { - add_feature(key, (int64_t)(value & 0xff)); + add_feature(key, (uint64_t)(value & 0xff)); } @@ -480,7 +516,7 @@ double OSD_BASE::get_feature_double_value(const _TCHAR *key) return std::numeric_limits::quiet_NaN(); // You don't use (0.0 / 0.0). } -int64_t OSD_BASE::get_feature_int_value(const _TCHAR *key) +int64_t OSD_BASE::get_feature_int64_value(const _TCHAR *key) { QString tmps; supportedlist_t l; @@ -494,19 +530,54 @@ int64_t OSD_BASE::get_feature_int_value(const _TCHAR *key) return 0; } +int OSD_BASE::get_feature_int_value(const _TCHAR *key) +{ + return (int)get_feature_int64_value(key); +} + +int32_t OSD_BASE::get_feature_int32_value(const _TCHAR *key) +{ + return (int32_t)get_feature_int64_value(key); +} + +int16_t OSD_BASE::get_feature_int16_value(const _TCHAR *key) +{ + return (int16_t)get_feature_int64_value(key); +} + +int8_t OSD_BASE::get_feature_int8_value(const _TCHAR *key) +{ + return (int8_t)get_feature_int64_value(key); +} + + +uint64_t OSD_BASE::get_feature_uint64_value(const _TCHAR *key) +{ + QString tmps; + supportedlist_t l; + tmps = QString::fromUtf8(key); + for(int i = 0; i < SupportedFeatures.size(); i++) { + l = SupportedFeatures.at(i); + if(l.string == tmps) { + return l.v.uvalue; + } + } + return 0; +} + uint32_t OSD_BASE::get_feature_uint32_value(const _TCHAR *key) { - return (uint32_t)(get_feature_int_value(key) & 0xffffffff); + return (uint32_t)(get_feature_uint64_value(key) & 0xffffffff); } uint16_t OSD_BASE::get_feature_uint16_value(const _TCHAR *key) { - return (uint16_t)(get_feature_uint32_value(key) & 0xffff); + return (uint16_t)(get_feature_uint64_value(key) & 0xffff); } uint8_t OSD_BASE::get_feature_uint8_value(const _TCHAR *key) { - return (uint8_t)(get_feature_uint32_value(key) & 0xff); + return (uint8_t)(get_feature_uint64_value(key) & 0xff); } void OSD_BASE::start_waiting_in_debugger() @@ -524,7 +595,7 @@ void OSD_BASE::finish_waiting_in_debugger() void OSD_BASE::process_waiting_in_debugger() { // ToDo: Check sequence - this->msleep(10); + QThread::msleep(10); } void OSD_BASE::set_dbg_completion_list(std::list *p) @@ -543,3 +614,39 @@ void OSD_BASE::clear_dbg_completion_list(void) emit sig_clear_dbg_completion_list(); emit sig_apply_dbg_completion_list(); } + +// Belows are API for GUI STATUS BAR. +void OSD_BASE::set_hdd_image_name(int drv, _TCHAR *filename) +{ + QString _n = QString::fromLocal8Bit(filename); + emit sig_change_virtual_media(CSP_DockDisks_Domain_HD, drv, _n); +} + +// Moved from OSD_WRAPPER. +const _TCHAR *OSD_BASE::get_lib_common_vm_version() +{ + return (const _TCHAR *)"\0"; +} + +const _TCHAR *OSD_BASE::get_lib_common_vm_git_version() +{ + return vm->get_vm_git_version(); +} + + +// Screen +void OSD_BASE::vm_draw_screen(void) +{ + vm->draw_screen(); +} + +double OSD_BASE::vm_frame_rate(void) +{ + return vm->get_frame_rate(); +} + +Sint16* OSD_BASE::create_sound(int *extra_frames) +{ + return (Sint16 *)vm->create_sound(extra_frames); +} + diff --git a/source/src/qt/osd_base.h b/source/src/qt/osd_base.h index 63c81a143..bcbe2f2d2 100644 --- a/source/src/qt/osd_base.h +++ b/source/src/qt/osd_base.h @@ -12,7 +12,7 @@ #include -#include +#include #include #include #include @@ -92,6 +92,7 @@ typedef struct { QString string; union { int64_t ivalue; + uint64_t uvalue; double fvalue; } v; } supportedlist_t; @@ -152,7 +153,7 @@ typedef struct { uint8_t *out_buffer; } osd_snd_capture_desc_t; -class DLL_PREFIX OSD_BASE : public QThread +class DLL_PREFIX OSD_BASE : public QObject { Q_OBJECT protected: @@ -172,7 +173,6 @@ class DLL_PREFIX OSD_BASE : public QThread QList SupportedFeatures; bool __USE_AUTO_KEY; - bool __USE_SHIFT_NUMPAD_KEY; _TCHAR app_path[_MAX_PATH]; QElapsedTimer osd_timer; @@ -214,8 +214,6 @@ class DLL_PREFIX OSD_BASE : public QThread int mouse_button; int mouse_oldx; int mouse_oldy; - int delta_x; - int delta_y; //Qt::CursorShape mouse_shape; QImage background_image; @@ -227,6 +225,7 @@ class DLL_PREFIX OSD_BASE : public QThread // screen void initialize_screen(); void release_screen(); + virtual void initialize_screen_buffer(bitmap_t *buffer, int width, int height, int mode); void release_screen_buffer(bitmap_t *buffer); void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest); @@ -332,8 +331,9 @@ class DLL_PREFIX OSD_BASE : public QThread // wrapper int max_vm_nodes; QList device_node_list; - virtual void vm_draw_screen(void); - virtual Sint16* create_sound(int *extra_frames); + void vm_draw_screen(void); + Sint16* create_sound(int *extra_frames); + virtual bool get_use_socket(void); virtual bool get_use_auto_key(void); virtual bool get_dont_keeep_key_pressed(void); @@ -341,16 +341,14 @@ class DLL_PREFIX OSD_BASE : public QThread virtual bool get_use_screen_rotate(void); virtual bool get_use_movie_player(void); virtual bool get_use_video_capture(void); - virtual void vm_key_down(int code, bool flag); - virtual void vm_key_up(int code); - virtual void vm_reset(void); + void vm_key_down(int code, bool flag); + void vm_key_up(int code); + void vm_reset(void); virtual void update_buttons(bool press_flag, bool release_flag); virtual int get_screen_width(void); virtual int get_screen_height(void); virtual int get_vm_buttons_code(int num); - virtual void init_sound_files(); - virtual void release_sound_files(); public: OSD_BASE(USING_FLAGS *p, CSP_Logger *logger); ~OSD_BASE(); @@ -362,6 +360,7 @@ class DLL_PREFIX OSD_BASE : public QThread QMutex *screen_mutex; QMutex *vm_mutex; QMutex *debug_mutex; + QMutex *mouse_mutex; int host_cpus; bool now_auto_key; @@ -410,7 +409,7 @@ class DLL_PREFIX OSD_BASE : public QThread } virtual void release(); - virtual void power_off(); + void power_off(); void suspend(); void restore(); _TCHAR* application_path(); @@ -478,6 +477,11 @@ class DLL_PREFIX OSD_BASE : public QThread int get_vm_window_width_aspect(); int get_vm_window_height_aspect(); scrntype_t* get_vm_screen_buffer(int y); + void reset_screen_buffer() + { + // It's ugly hack for screen. + emit sig_resize_vm_screen((QImage*)NULL, -1, -1); + } //int draw_screen(); //int no_draw_screen(); void reload_bitmap(); @@ -512,10 +516,6 @@ class DLL_PREFIX OSD_BASE : public QThread bool open_sound_capture_device(int num, int req_rate, int req_channels); bool close_sound_capture_device(int num, bool force); - // Wrapper : Sound - virtual void load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size); - virtual void free_sound_file(int id, int16_t **data); - // common video device virtual void get_video_buffer(); void mute_video_dev(bool l, bool r); @@ -557,9 +557,10 @@ class DLL_PREFIX OSD_BASE : public QThread void stretch_bitmap(bitmap_t *dest, int dest_x, int dest_y, int dest_width, int dest_height, bitmap_t *source, int source_x, int source_y, int source_width, int source_height); void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path); + double vm_frame_rate(void); // common socket - virtual int get_socket(int ch); + virtual SOCKET get_socket(int ch); virtual void notify_socket_connected(int ch); virtual void notify_socket_disconnected(int ch); virtual void update_socket(); @@ -580,30 +581,31 @@ class DLL_PREFIX OSD_BASE : public QThread _TCHAR *console_input_string(void); void clear_console_input_string(void); + + void lock_vm(void); + void unlock_vm(void); + void force_unlock_vm(void); + bool is_vm_locked(void); + virtual const _TCHAR *get_lib_common_vm_version(); + const _TCHAR *get_lib_common_vm_git_version(); + const _TCHAR *get_lib_osd_version(); + // Wrapper - virtual void lock_vm(void); - virtual void unlock_vm(void); - virtual void force_unlock_vm(void); - virtual bool is_vm_locked(void); virtual void set_draw_thread(DrawThreadClass *handler); virtual QString get_vm_config_name(void); - virtual double vm_frame_rate(void); virtual void reset_vm_node(void); - virtual const _TCHAR *get_lib_common_vm_version() { return (const _TCHAR *)"\0"; } - virtual const _TCHAR *get_lib_common_vm_git_version() { return (const _TCHAR *)"\0"; } - const _TCHAR *get_lib_osd_version(); - virtual void set_device_name(int id, char *name); + void set_device_name(int id, char *name); - virtual void set_vm_node(int id, const _TCHAR *name); - virtual const _TCHAR *get_vm_node_name(int id); - virtual int get_vm_node_size(void); + void set_vm_node(int id, const _TCHAR *name); + const _TCHAR *get_vm_node_name(int id); + int get_vm_node_size(void); - virtual int get_key_name_table_size(void); - virtual uint32_t get_scancode_by_vk(uint32_t vk); - virtual uint32_t get_vk_by_scancode(uint32_t scancode); - virtual const _TCHAR *get_key_name_by_scancode(uint32_t scancode); - virtual const _TCHAR *get_key_name_by_vk(uint32_t vk); + int get_key_name_table_size(void); + uint32_t get_scancode_by_vk(uint32_t vk); + uint32_t get_vk_by_scancode(uint32_t scancode); + const _TCHAR *get_key_name_by_scancode(uint32_t scancode); + const _TCHAR *get_key_name_by_vk(uint32_t vk); // Get #define S to value.You may use inside of VM/ . virtual void set_features(void) {} @@ -611,19 +613,31 @@ class DLL_PREFIX OSD_BASE : public QThread void add_feature(const _TCHAR *key, float value); void add_feature(const _TCHAR *key, int value = 1); void add_feature(const _TCHAR *key, int64_t value); + void add_feature(const _TCHAR *key, int16_t value); + void add_feature(const _TCHAR *key, int8_t value); + void add_feature(const _TCHAR *key, uint64_t value); void add_feature(const _TCHAR *key, uint32_t value); void add_feature(const _TCHAR *key, uint16_t value); void add_feature(const _TCHAR *key, uint8_t value); bool check_feature(const _TCHAR *key); double get_feature_double_value(const _TCHAR *key); - int64_t get_feature_int_value(const _TCHAR *key); + int get_feature_int_value(const _TCHAR *key); + int64_t get_feature_int64_value(const _TCHAR *key); + int32_t get_feature_int32_value(const _TCHAR *key); + int16_t get_feature_int16_value(const _TCHAR *key); + int8_t get_feature_int8_value(const _TCHAR *key); + + uint64_t get_feature_uint64_value(const _TCHAR *key); uint32_t get_feature_uint32_value(const _TCHAR *key); uint16_t get_feature_uint16_value(const _TCHAR *key); uint8_t get_feature_uint8_value(const _TCHAR *key); void debug_log(int level, const char *fmt, ...); void debug_log(int level, int domain_num, const char *fmt, ...); - virtual void debug_log(int level, int domain_num, char *strbuf); + void debug_log(int level, int domain_num, char *strbuf); + virtual double get_vm_current_usec() { return 0.0; } + virtual uint64_t get_vm_current_clock_uint64() { return 0;} + USING_FLAGS *get_config_flags(void) { return using_flags; } @@ -657,6 +671,7 @@ public slots: void set_dbg_completion_list(std::list *p); void clear_dbg_completion_list(void); + void set_hdd_image_name(int drv, _TCHAR *filename); signals: int sig_update_screen(void *, bool); @@ -693,6 +708,8 @@ public slots: int sig_clear_keyname_table(void); int sig_add_keyname_table(uint32_t, QString); + + int sig_change_virtual_media(int, int, QString); }; QT_END_NAMESPACE diff --git a/source/src/qt/osd_input.cpp b/source/src/qt/osd_input.cpp index bf9ffcfc1..bc684626c 100644 --- a/source/src/qt/osd_input.cpp +++ b/source/src/qt/osd_input.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include //#include "../emu.h" #include "../fifo.h" @@ -58,8 +60,6 @@ void OSD_BASE::initialize_input() mouse_enabled = false; mouse_ptrx = mouse_oldx = get_screen_width() / 2; mouse_ptry = mouse_oldy = get_screen_height() / 2; - delta_x = 0; - delta_y = 0; // initialize keycode convert table FILEIO* fio = new FILEIO(); if(fio->Fopen(bios_path(_T("keycode.cfg")), FILEIO_READ_BINARY)) { @@ -257,11 +257,15 @@ void OSD_BASE::update_input() memset(mouse_status, 0, sizeof(mouse_status)); //bool hid = false; if(mouse_enabled) { - mouse_status[0] = delta_x; - mouse_status[1] = delta_y; + QMutexLocker n(mouse_mutex); + int xx = (p_config->mouse_sensitivity_x & ((1 << 16) - 1)) * mouse_ptrx; + int yy = (p_config->mouse_sensitivity_y & ((1 << 16) - 1)) * mouse_ptry; + mouse_status[0] = (xx - mouse_oldx) >> 12; + mouse_status[1] = (yy - mouse_oldy) >> 12; mouse_status[2] = mouse_button; //printf("Mouse delta(%d, %d)\n", delta_x, delta_y); - delta_x = delta_y = 0; + mouse_oldx = xx; + mouse_oldy = yy; } //} // move mouse cursor to the center of window @@ -277,26 +281,29 @@ void OSD_BASE::key_down(int code, bool extended, bool repeat) //csp_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_OSD, "KEY DOWN %d", code); //if(!dinput_key_available) { if(code == VK_SHIFT) { + if(!(key_status[VK_RSHIFT] & 0x80) && (GetAsyncKeyState(VK_RSHIFT) & 0x8000)) { + key_down_native(VK_RSHIFT, repeat); + } if(!(key_status[VK_LSHIFT] & 0x80) && (GetAsyncKeyState(VK_LSHIFT) & 0x8000)) { code = VK_LSHIFT; - } else if(!(key_status[VK_RSHIFT] & 0x80) && (GetAsyncKeyState(VK_RSHIFT) & 0x8000)) { - code = VK_RSHIFT; } else { return; } } else if(code == VK_CONTROL) { + if(!(key_status[VK_RCONTROL] & 0x80) && (GetAsyncKeyState(VK_RCONTROL) & 0x8000)) { + key_down_native(VK_RCONTROL, repeat); + } if(!(key_status[VK_LCONTROL] & 0x80) && (GetAsyncKeyState(VK_LCONTROL) & 0x8000)) { code = VK_LCONTROL; - } else if(!(key_status[VK_RCONTROL] & 0x80) && (GetAsyncKeyState(VK_RCONTROL) & 0x8000)) { - code = VK_RCONTROL; } else { return; } } else if(code == VK_MENU) { + if(!(key_status[VK_RMENU] & 0x80) && (GetAsyncKeyState(VK_RMENU) & 0x8000)) { + key_down_native(VK_RMENU, repeat); + } if(!(key_status[VK_LMENU] & 0x80) && (GetAsyncKeyState(VK_LMENU) & 0x8000)) { code = VK_LMENU; - } else if(!(key_status[VK_RMENU] & 0x80) && (GetAsyncKeyState(VK_RMENU) & 0x8000)) { - code = VK_RMENU; } else { return; } @@ -331,8 +338,6 @@ void OSD_BASE::key_down(int code, bool extended, bool repeat) break; } -//#ifdef USE_SHIFT_NUMPAD_KEY - if(__USE_SHIFT_NUMPAD_KEY) { // if(code == VK_LSHIFT || code == VK_RSHIFT) { if(code == VK_LSHIFT) { key_shift_pressed = true; @@ -402,9 +407,6 @@ void OSD_BASE::key_down(int code, bool extended, bool repeat) break; } } - } - -//#endif key_down_native(code, repeat); //} else { // if(repeat || code == 0xf0 || code == 0xf1 || code == 0xf2 || code == 0xf3 || code == 0xf4) { @@ -478,9 +480,6 @@ void OSD_BASE::key_up(int code, bool extended) break; } -//#ifdef USE_SHIFT_NUMPAD_KEY - if(__USE_SHIFT_NUMPAD_KEY) { - // if(code == VK_LSHIFT || code == VK_RSHIFT) { if(code == VK_LSHIFT) { key_shift_pressed = false; @@ -532,13 +531,8 @@ void OSD_BASE::key_up(int code, bool extended) return; } } - } -//#endif key_up_native(code); - } -//#ifdef USE_AUTO_KEY -//} -//#endif + } } @@ -556,14 +550,14 @@ void OSD_BASE::key_down_native(int code, bool repeat) code = VK_KANJI; keep_frames = true; } - if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) { + if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU || code == VK_MENU)) { code = keycode_conv[code]; } if(key_status[code] == 0 || keep_frames) { repeat = false; } if(get_dont_keeep_key_pressed()) { - if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) { + if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU || code == VK_MENU)) { key_status[code] = KEY_KEEP_FRAMES; } else { key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80; @@ -597,7 +591,7 @@ void OSD_BASE::key_down_native(int code, bool repeat) void OSD_BASE::key_up_native(int code) { - if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) { + if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU || code == VK_MENU)) { code = keycode_conv[code]; } if(key_status[code] == 0) { @@ -645,13 +639,13 @@ void OSD_BASE::key_down_sub(int code, bool repeat) code = VK_KANJI; keep_frames = true; } - if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) { + if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU || code == VK_MENU)) { code = keycode_conv[code]; } if(get_dont_keeep_key_pressed()) { - if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) { + if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU || code == VK_MENU)) { key_status[code] = KEY_KEEP_FRAMES; } else { key_status[code] = keep_frames ? KEY_KEEP_FRAMES : 0x80; @@ -702,7 +696,7 @@ void OSD_BASE::key_down_sub(int code, bool repeat) void OSD_BASE::key_up_sub(int code) { - if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU)) { + if(!(code == VK_LSHIFT || code == VK_RSHIFT || code == VK_LCONTROL || code == VK_RCONTROL || code == VK_LMENU || code == VK_RMENU || code == VK_MENU)) { code = keycode_conv[code]; } if(key_status[code] == 0) { @@ -776,6 +770,7 @@ uint32_t* OSD_BASE::get_joy_buffer() int32_t* OSD_BASE::get_mouse_buffer() { + QMutexLocker n(mouse_mutex); return mouse_status; } @@ -799,10 +794,14 @@ void OSD_BASE::enable_mouse() { // enable mouse emulation if(!mouse_enabled) { - mouse_oldx = mouse_ptrx = get_screen_width() / 2; - mouse_oldy = mouse_ptry = get_screen_height() / 2; - delta_x = 0; - delta_y = 0; + QMutexLocker n(mouse_mutex); + int xx = (p_config->mouse_sensitivity_x & ((1 << 16) - 1)) * get_screen_width() / 2; + int yy = (p_config->mouse_sensitivity_y & ((1 << 16) - 1)) * get_screen_height() / 2; + + mouse_oldx = xx; + mouse_oldy = yy; + mouse_ptrx = get_screen_width() / 2; + mouse_ptry = get_screen_height() / 2; mouse_status[0] = 0; mouse_status[1] = 0; mouse_status[2] = mouse_button; @@ -838,42 +837,34 @@ bool OSD_BASE::is_mouse_enabled() void OSD_BASE::set_mouse_pointer(int x, int y) { if(mouse_enabled) { - int32_t dw = get_screen_width(); - int32_t dh = get_screen_height(); + QMutexLocker n(mouse_mutex); + mouse_ptrx = x; mouse_ptry = y; - //delta_x = x - (dw / 2); - //delta_y = y - (dh / 2); - delta_x += (mouse_ptrx - mouse_oldx); - delta_y += (mouse_ptry - mouse_oldy); - if(delta_x > (dw / 2)) { - delta_x = dw / 2; - } else if(delta_x < -(dw / 2)) { - delta_x = -dw / 2; - } - if(delta_y > (dh / 2)) { - delta_y = dh / 2; - } else if(delta_y < -(dh / 2)) { - delta_y = -dh / 2; - } - mouse_oldx = mouse_ptrx; - mouse_oldy = mouse_ptry; + +// mouse_oldx = mouse_ptrx; +// mouse_oldy = mouse_ptry; //printf("Mouse Moved: (%d, %d) -> delta(%d, %d)\n", mouse_ptrx, mouse_ptry, delta_x, delta_y); } } void OSD_BASE::set_mouse_button(int button) { + QMutexLocker n(mouse_mutex); mouse_button = button; } int OSD_BASE::get_mouse_button() { + QMutexLocker n(mouse_mutex); return mouse_button; } int OSD_BASE::get_key_name_table_size(void) { + if(vm != NULL) { + return vm->get_key_name_table_size(); + } return 0; } @@ -893,21 +884,33 @@ void OSD_BASE::update_keyname_table(void) const _TCHAR *OSD_BASE::get_key_name_by_scancode(uint32_t scancode) { + if(vm != NULL) { + return vm->get_phy_key_name_by_scancode(scancode); + } return (const _TCHAR *)NULL; } const _TCHAR *OSD_BASE::get_key_name_by_vk(uint32_t vk) { + if(vm != NULL) { + return vm->get_phy_key_name_by_vk(vk); + } return (const _TCHAR *)NULL; } uint32_t OSD_BASE::get_scancode_by_vk(uint32_t vk) { + if(vm != NULL) { + return vm->get_scancode_by_vk(vk); + } return 0xffffffff; } uint32_t OSD_BASE::get_vk_by_scancode(uint32_t scancode) { + if(vm != NULL) { + return vm->get_vk_by_scancode(scancode); + } return 0xffffffff; } diff --git a/source/src/qt/osd_screen.cpp b/source/src/qt/osd_screen.cpp index 778c898ef..dfdac6524 100644 --- a/source/src/qt/osd_screen.cpp +++ b/source/src/qt/osd_screen.cpp @@ -134,7 +134,7 @@ void OSD_BASE::initialize_screen_buffer(bitmap_t *buffer, int width, int height, buffer->pImage = QImage(width, height, QImage::Format_ARGB32); buffer->pImage.fill(col); } - printf("%dx%d NULL=%d\n", buffer->pImage.width(), buffer->pImage.height(), buffer->pImage.isNull() ? 1 : 0); +// printf("%dx%d NULL=%d\n", buffer->pImage.width(), buffer->pImage.height(), buffer->pImage.isNull() ? 1 : 0); QColor fillcolor; fillcolor.setRgb(0, 0, 0, 255); buffer->pImage.fill(fillcolor); @@ -464,3 +464,8 @@ void OSD_BASE::reload_bitmap() first_invalidate = true; } +void OSD_BASE::power_off() +{ + emit sig_close_window(); +} + diff --git a/source/src/qt/osd_socket.cpp b/source/src/qt/osd_socket.cpp index f2c77ef34..aeffbab92 100644 --- a/source/src/qt/osd_socket.cpp +++ b/source/src/qt/osd_socket.cpp @@ -86,7 +86,8 @@ void OSD_BASE::recv_socket_data(int ch) { } -int OSD_BASE::get_socket(int ch) +SOCKET OSD_BASE::get_socket(int ch) { - return ch; + return (SOCKET)0; } + diff --git a/source/src/qt/osd_socket.h b/source/src/qt/osd_socket.h index 05cf89677..0526e854b 100644 --- a/source/src/qt/osd_socket.h +++ b/source/src/qt/osd_socket.h @@ -17,12 +17,11 @@ #include "osd_base.h" -#if defined(USE_SOCKET) #include #include QT_BEGIN_NAMESPACE -class QTcpSocket2 : public QTcpSocket +class DLL_PREFIX QTcpSocket2 : public QTcpSocket { Q_OBJECT protected: @@ -40,7 +39,7 @@ public slots: int sig_disconnected(int); }; -class QUdpSocket2 : public QUdpSocket +class DLL_PREFIX QUdpSocket2 : public QUdpSocket { Q_OBJECT protected: @@ -60,4 +59,3 @@ public slots: QT_END_NAMESPACE #endif -#endif diff --git a/source/src/qt/osd_sound.cpp b/source/src/qt/osd_sound.cpp index bf6515b5d..cc48dfcf1 100644 --- a/source/src/qt/osd_sound.cpp +++ b/source/src/qt/osd_sound.cpp @@ -162,7 +162,8 @@ const _TCHAR *OSD_BASE::get_sound_device_name(int num) if(num >= sound_device_list.count()) return NULL; QString sdev = sound_device_list.value(num); sdev.truncate(64); - return (const _TCHAR*)(sdev.toUtf8().constData()); + static QByteArray _n = sdev.toUtf8(); + return (const _TCHAR*)(_n.constData()); } int OSD_BASE::get_sound_device_num() @@ -271,13 +272,29 @@ void OSD_BASE::initialize_sound(int rate, int samples, int* presented_rate, int* //QString sdev = QString::fromUtf8("\"") + sound_device_list.at(audio_dev_id) + QString::fromUtf8("\""); //audio_dev_id = SDL_OpenAudioDevice(NULL, 0, &snd_spec_req, &snd_spec_presented, SDL_AUDIO_ALLOW_ANY_CHANGE); - QString sdev; - sdev = sound_device_list.at(p_config->sound_device_num); - audio_dev_id = SDL_OpenAudioDevice(sdev.toUtf8().constData(), 0, - &snd_spec_req, &snd_spec_presented, - 0); - debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Try to open DEVICE #%d: %s -> %s: DEVID=%d\n", - p_config->sound_device_num, sdev.toUtf8().constData(), (audio_dev_id <= 0) ? "FAIL" : "SUCCESS", audio_dev_id); + audio_dev_id = 0; + if(!(sound_device_list.isEmpty())) { + QString sdev; + if(p_config->sound_device_num >= sound_device_list.count()) { + p_config->sound_device_num = sound_device_list.count() - 1; + } + if(p_config->sound_device_num <= 0) { + p_config->sound_device_num = 0; + } + sdev = sound_device_list.at(p_config->sound_device_num); + audio_dev_id = SDL_OpenAudioDevice(sdev.toUtf8().constData(), 0, + &snd_spec_req, &snd_spec_presented, + 0); + debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Try to open DEVICE #%d: %s -> %s: DEVID=%d\n", + p_config->sound_device_num, sdev.toUtf8().constData(), (audio_dev_id <= 0) ? "FAIL" : "SUCCESS", audio_dev_id); + } else { + audio_dev_id = SDL_OpenAudioDevice("", 0, + &snd_spec_req, &snd_spec_presented, + 0); + debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SOUND, "Try to open DEVICE #%d: %s: DEVID=%d\n", + p_config->sound_device_num, (audio_dev_id <= 0) ? "FAIL" : "SUCCESS", audio_dev_id); + + } #else audio_dev_id = 1; SDL_OpenAudio(&snd_spec_req, &snd_spec_presented); @@ -932,24 +949,6 @@ int OSD_BASE::get_sound_rate() return snd_spec_presented.freq; } -void OSD_BASE::load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size) -{ - if(data != NULL) *data = NULL; - if(dst_size != NULL) *dst_size = 0; -} - -void OSD_BASE::free_sound_file(int id, int16_t **data) -{ -} - -void OSD_BASE::init_sound_files() -{ -} - -void OSD_BASE::release_sound_files() -{ -} - void OSD_BASE::close_capture_sound_emu(int ch) { diff --git a/source/src/qt/osd_wrapper.cpp b/source/src/qt/osd_wrapper.cpp index d2e687f5f..4bcf9c503 100644 --- a/source/src/qt/osd_wrapper.cpp +++ b/source/src/qt/osd_wrapper.cpp @@ -46,171 +46,10 @@ #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE) #include "avio/movie_loader.h" #endif -#if defined(USE_SOUND_FILES) -#include "avio/sound_loader.h" -#endif #include "qt_gldraw.h" #include "csp_logger.h" -int OSD::get_key_name_table_size(void) -{ -#ifdef SUPPORT_QUERY_PHY_KEY_NAME - if(vm != NULL) { - return vm->get_key_name_table_size(); - } -#endif - return 0; -} - -const _TCHAR *OSD::get_key_name_by_scancode(uint32_t scancode) -{ -#ifdef SUPPORT_QUERY_PHY_KEY_NAME - if(vm != NULL) { - return vm->get_phy_key_name_by_scancode(scancode); - } -#endif - return (const _TCHAR *)NULL; -} - -const _TCHAR *OSD::get_key_name_by_vk(uint32_t vk) -{ -#ifdef SUPPORT_QUERY_PHY_KEY_NAME - if(vm != NULL) { - return vm->get_phy_key_name_by_vk(vk); - } -#endif - return (const _TCHAR *)NULL; -} - -uint32_t OSD::get_scancode_by_vk(uint32_t vk) -{ -#ifdef SUPPORT_QUERY_PHY_KEY_NAME - if(vm != NULL) { - return vm->get_scancode_by_vk(vk); - } -#endif - return 0xffffffff; -} - -uint32_t OSD::get_vk_by_scancode(uint32_t scancode) -{ -#ifdef SUPPORT_QUERY_PHY_KEY_NAME - if(vm != NULL) { - return vm->get_vk_by_scancode(scancode); - } -#endif - return 0xffffffff; -} - -const _TCHAR *OSD::get_lib_common_vm_version() -{ - if(vm->first_device != NULL) { - return vm->first_device->get_lib_common_vm_version(); - } else { - return (const _TCHAR *)"\0"; - } -} - -const _TCHAR *OSD::get_lib_common_vm_git_version() -{ - return vm->get_vm_git_version(); -} - - -// Screen -void OSD::vm_draw_screen(void) -{ - vm->draw_screen(); -} - -double OSD::vm_frame_rate(void) -{ - return vm->get_frame_rate(); -} - -Sint16* OSD::create_sound(int *extra_frames) -{ - return (Sint16 *)vm->create_sound(extra_frames); -} - - -#ifdef USE_SOUND_FILES -void OSD::load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size) -{ - int i = 0; - if(data != NULL) *data = NULL; - if(dst_size != NULL) *dst_size = 0; - if(id <= 0) return; - - for(i = 0; i < USE_SOUND_FILES; i++) { - SOUND_LOADER *p = sound_file_obj[i]; - if(p != NULL) { - if(p->get_id() == id) break; - } - } - - if(i >= USE_SOUND_FILES) { - for(i = 0; i < USE_SOUND_FILES; i++) { - SOUND_LOADER *p = sound_file_obj[i]; - if(p != NULL) { - if(p->get_id() < 0) { - p->set_id(id); - break; - } - } - } - } - if(i >= USE_SOUND_FILES) return; - SOUND_LOADER *p = sound_file_obj[i]; - if(p != NULL) { - p->free_sound_buffer(NULL); - p->set_sound_rate(this->get_sound_rate()); - if(p->open(id, QString::fromUtf8(name))) { - p->do_decode_frames(); - p->close(); - if(data != NULL) *data = (int16_t *)(p->get_sound_buffer()); - if(dst_size != NULL) *dst_size = p->get_dst_size(); - } - } -} - -void OSD::free_sound_file(int id, int16_t **data) -{ - if(data == NULL) return; - for(int i = 0; i < USE_SOUND_FILES; i++) { - SOUND_LOADER *p = sound_file_obj[i]; - if(p != NULL) { - if(p->get_id() == id) { - p->free_sound_buffer(*data); - *data = NULL; - break; - } - } - } -} - -void OSD::init_sound_files() -{ - for(int i = 0; i < USE_SOUND_FILES; i++) { - sound_file_obj[i] = NULL; - SOUND_LOADER *p = new SOUND_LOADER((void *)tail_sound_file, p_logger); - if(p != NULL) { - sound_file_obj[i] = p; - } - tail_sound_file = p; - } -} - -void OSD::release_sound_files() -{ - for(int i = 0; i < USE_SOUND_FILES; i++) { - SOUND_LOADER *p = sound_file_obj[i]; - if(p != NULL) delete p; - sound_file_obj[i] = NULL; - } -} -#endif bool OSD::get_use_socket(void) { #ifdef USE_SOCKET @@ -275,20 +114,6 @@ bool OSD::get_use_video_capture(void) #endif } -void OSD::vm_key_down(int code, bool flag) -{ - vm->key_down(code, flag); -} - -void OSD::vm_key_up(int code) -{ - vm->key_up(code); -} - -void OSD::vm_reset(void) -{ - vm->reset(); -} int OSD::get_vm_buttons_code(int num) { @@ -343,41 +168,6 @@ int OSD::get_screen_height(void) return SCREEN_HEIGHT; } -void OSD::lock_vm(void) -{ - locked_vm = true; - vm_mutex->lock(); - //if(parent_thread != NULL) { - //if(!parent_thread->now_debugging()) VMSemaphore->acquire(1); - //VMSemaphore->acquire(1); - //} else { - // VMSemaphore->acquire(1); - //} -} - -void OSD::unlock_vm(void) -{ - vm_mutex->unlock(); - //if(parent_thread != NULL) { - // //if(!parent_thread->now_debugging()) VMSemaphore->release(1); - // VMSemaphore->release(1); - //} else { - // VMSemaphore->release(1); - //} - locked_vm = false; -} - - -bool OSD::is_vm_locked(void) -{ - return locked_vm; -} - -void OSD::force_unlock_vm(void) -{ - vm_mutex->unlock(); - locked_vm = false; -} void OSD::set_draw_thread(DrawThreadClass *handler) { @@ -559,27 +349,11 @@ int OSD::get_movie_sound_rate() return 44100; } -void OSD::reset_vm_node() -{ - device_node_t sp; - device_node_list.clear(); - p_logger->reset(); - max_vm_nodes = 0; - for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) { - sp.id = p->this_device_id; - sp.name = p->this_device_name; - p_logger->set_device_name(sp.id, (char *)sp.name); - p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Device %d :%s", sp.id, sp.name); - device_node_list.append(sp); - if(max_vm_nodes <= p->this_device_id) max_vm_nodes = p->this_device_id + 1; - } - for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) { - emit sig_update_device_node_name(p->this_device_id, p->this_device_name); - } -} - #if defined(USE_SOCKET) #include +#include +#include + #include "osd_socket.h" #endif // Socket @@ -876,78 +650,21 @@ void OSD::recv_socket_data(int ch) // This is dummy. } -int OSD::get_socket(int ch) +SOCKET OSD::get_socket(int ch) { #ifdef USE_SOCKET if(is_tcp[ch]) { - if(tcp_socket[ch] == NULL) return -1; + if(tcp_socket[ch] == NULL) return (SOCKET)0; + return (SOCKET)tcp_socket[ch]; } else { - if(udp_socket[ch] == NULL) return -1; + if(udp_socket[ch] == NULL) return (SOCKET)0; + return (SOCKET)udp_socket[ch]; } -#endif - return ch; +#endif + return (SOCKET)0; } // -#if defined(USE_SOCKET) -QTcpSocket2::QTcpSocket2(int channel, QObject *parent) : QTcpSocket(parent) -{ - ch = channel; -} - -QTcpSocket2::~QTcpSocket2() -{ -} - -void QTcpSocket2::do_connected(void) -{ - emit sig_connected(ch); -} - -void QTcpSocket2::do_disconnected(void) -{ - emit sig_disconnected(ch); -} - -void QTcpSocket2::setChannel(int channel) -{ - ch = channel; -} - -int QTcpSocket2::getChannel(void) -{ - return ch; -} - -QUdpSocket2::QUdpSocket2(int channel, QObject *parent) : QUdpSocket(parent) -{ - ch = channel; -} - -QUdpSocket2::~QUdpSocket2() -{ -} - -void QUdpSocket2::do_connected(void) -{ - emit sig_connected(ch); -} - -void QUdpSocket2::do_disconnected(void) -{ - emit sig_disconnected(ch); -} - -void QUdpSocket2::setChannel(int channel) -{ - ch = channel; -} - -int QUdpSocket2::getChannel(void) -{ - return ch; -} -#endif // Screen scrntype_t* OSD::get_buffer(bitmap_t *p, int y) @@ -1119,23 +836,8 @@ int OSD::add_video_frames() } else { //int size = vm_screen_buffer.pImage.byteCount(); int i = counter; - if(p_glv->is_ready_to_map_vram_texture()) { - vm_screen_buffer.is_mapped = true; - vm_screen_buffer.glv = p_glv; - for(int y = 0; y < vm_screen_buffer.pImage.height(); y++) { - scrntype_t *p = vm_screen_buffer.get_buffer(y); - if(p != NULL) { - if(p != (scrntype_t*)(vm_screen_buffer.pImage.scanLine(y))) { - memcpy(vm_screen_buffer.pImage.scanLine(y), p, vm_screen_buffer.pImage.width() * sizeof(scrntype_t)); - } - } else { - if(vm_screen_buffer.pImage.scanLine(y) != NULL) { - memset(vm_screen_buffer.pImage.scanLine(y), 0x00, vm_screen_buffer.pImage.width() * sizeof(scrntype_t)); - } - } - } - } - QImage video_result = QImage(vm_screen_buffer.pImage); + QImage video_result; + video_result = QImage(vm_screen_buffer.pImage); // Rescaling if(i > 0) { // Enqueue to frame. @@ -1146,3 +848,45 @@ int OSD::add_video_frames() } return counter; } + +double OSD::get_vm_current_usec() +{ + if(vm == NULL) return 0.0; + return vm->get_current_usec(); +} + +uint64_t OSD::get_vm_current_clock_uint64() +{ + if(vm == NULL) return (uint64_t)0; + return vm->get_current_clock_uint64(); +} + +const _TCHAR *OSD::get_lib_common_vm_version() +{ + if(vm->first_device != NULL) { + return vm->first_device->get_lib_common_vm_version(); + } else { + return (const _TCHAR *)"\0"; + } +} + +void OSD::reset_vm_node(void) +{ + device_node_t sp; + device_node_list.clear(); + p_logger->reset(); + max_vm_nodes = 0; + if(vm == NULL) return; + for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) { + sp.id = p->this_device_id; + sp.name = p->this_device_name; + p_logger->set_device_name(sp.id, (char *)sp.name); + p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL, "Device %d :%s", sp.id, sp.name); + device_node_list.append(sp); + if(max_vm_nodes <= p->this_device_id) max_vm_nodes = p->this_device_id + 1; + } + for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) { + emit sig_update_device_node_name(p->this_device_id, p->this_device_name); + } +} + diff --git a/source/src/qt/qtcpsocket2.cpp b/source/src/qt/qtcpsocket2.cpp new file mode 100644 index 000000000..89206425d --- /dev/null +++ b/source/src/qt/qtcpsocket2.cpp @@ -0,0 +1,34 @@ + +#include +#include "./osd_socket.h" + +QTcpSocket2::QTcpSocket2(int channel, QObject *parent) : QTcpSocket(parent) +{ + ch = channel; +} + +QTcpSocket2::~QTcpSocket2() +{ +} + +void QTcpSocket2::do_connected(void) +{ + emit sig_connected(ch); +} + +void QTcpSocket2::do_disconnected(void) +{ + emit sig_disconnected(ch); +} + +void QTcpSocket2::setChannel(int channel) +{ + ch = channel; +} + +int QTcpSocket2::getChannel(void) +{ + return ch; +} + + diff --git a/source/src/qt/qudpsocket2.cpp b/source/src/qt/qudpsocket2.cpp new file mode 100644 index 000000000..bb73a4afd --- /dev/null +++ b/source/src/qt/qudpsocket2.cpp @@ -0,0 +1,33 @@ + +#include +#include "./osd_socket.h" + + +QUdpSocket2::QUdpSocket2(int channel, QObject *parent) : QUdpSocket(parent) +{ + ch = channel; +} + +QUdpSocket2::~QUdpSocket2() +{ +} + +void QUdpSocket2::do_connected(void) +{ + emit sig_connected(ch); +} + +void QUdpSocket2::do_disconnected(void) +{ + emit sig_disconnected(ch); +} + +void QUdpSocket2::setChannel(int channel) +{ + ch = channel; +} + +int QUdpSocket2::getChannel(void) +{ + return ch; +} diff --git a/source/src/res/bmjr.rc b/source/src/res/bmjr.rc index 7f36e2bae..91ae79e54 100644 --- a/source/src/res/bmjr.rc +++ b/source/src/res/bmjr.rc @@ -195,6 +195,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/bubcom80.rc b/source/src/res/bubcom80.rc index d182f8abd..6ad4095d5 100644 --- a/source/src/res/bubcom80.rc +++ b/source/src/res/bubcom80.rc @@ -274,6 +274,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/cefucom21.rc b/source/src/res/cefucom21.rc index 027e22abf..bb35cd0a8 100644 --- a/source/src/res/cefucom21.rc +++ b/source/src/res/cefucom21.rc @@ -201,6 +201,7 @@ BEGIN MENUITEM "Joystick #2", ID_INPUT_JOYSTICK1 END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/colecovision.rc b/source/src/res/colecovision.rc index 853800c4c..583a8ce85 100644 --- a/source/src/res/colecovision.rc +++ b/source/src/res/colecovision.rc @@ -184,6 +184,7 @@ BEGIN MENUITEM "Joystick #2", ID_INPUT_JOYSTICK1 END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/credits.html b/source/src/res/credits.html index ba2a87f3e..cff49d7b3 100644 --- a/source/src/res/credits.html +++ b/source/src/res/credits.html @@ -7,68 +7,161 @@

Common Source Code Project

-
-Upstream Version: 2019-04-30
-Qt Port and FM7 series 2019-08-16
-FFMPEG 4.1 + liblame 3.99 + libx264-157
+ +
+

Renderer Type:

+
+

+@@RendererType@@ +

+
+
+ +
+Upstream Version: 2020-08-16
+Qt Port and FM7 series 2020-09-26
+FFMPEG 4.3 + liblame 3.100 + libx264-161
@@RevisionString@@

-
-

Upstream Author:

-2006,2015 ©TAKEDA Toshiya
-HP:
http://takeda-toshiya.my.coocan.jp/common/index.html
-

Porting to Qt:

-2015 ©Kyuma Ohta
-HP1:
https://github.com/Artanejp/common_source_project-fm7
-HP2:
https://osdn.jp/projects/csp-qt/
+ +
+

Upstream Author:
+      2006,2015,2020 ©TAKEDA Toshiya

+
+
+HP: +
+ +
+

Porting to Qt:
+      2015-2020 ©Kyuma Ohta

+
+
+ +
+HP1: +
+ +
+HP2: +
+
+https://osdn.jp/projects/csp-qt/
E-Mail: whatisthis.sowhat _at_ gmail.com
Twitter: @Artanejp
-
+
+ +

Thanks to:

-Ryu Takegami for FM-7/8/77/AV/40/EX
-HP:
http://xm7.la.coocan.jp/xm7/
-はせりん for FM-7/8/77/AV/40/EX
-HP:
http://www.mindspring.com/~thasegaw/rpcg/index.html
+
+
+

+- Ryu Takegami for FM-7/8/77/AV/40/EX
+

+
+
+HP: +
+ +
+

+- はせりん for FM-7/8/77/AV/40/EX +

+
+
+HP: +
+ -

PC-6001 Series , SEGA Master System/Game Gear, MSX1 and MSX2:

-2015 ©tanam
-HP:
http://www.geocities.jp/parallel_computer_inc/android.html
+
+

PC-6001 Series , SEGA Master System/Game Gear, MSX1 and MSX2:

+
+
+

      2015 ©tanam

+
+HP: +
+ -

MSX1 and MSX2:

-2015 ©umaiboux
-HP:
http://umaiboux.k-free.net/
+
+

MSX1 and MSX2:
      2015 ©umaiboux

+
+
+HP: +
+ -

MZ-80A:

-2014,2015 ©hideki suga
-HP:
http://www.ne.jp/asahi/suga/junkyard/
+
+

MZ-80A:
      2014,2015 ©hideki suga

+
+
+HP: +
+ -

Z80 TV Game:

-2014,2015 ©Isizu
-HP:
http://w01.tp1.jp/~a571632211/index.html
-http://w01.tp1.jp/~a571632211/z80tvgame/index.html
+
+

Z80 TV Game:
      2014,2015 ©Isizu

+
+
+HP: +
+ -

FM-7/8/77/AV Series:

-2015 ©Kyuma Ohta
-HP:
+
+

FM-7/8/77/AV Series:
      2015 ©Kyuma Ohta

+
+
+HP: +
+ +
Secondary:
+
+
+ https://github.com/Artanejp/common_source_project-fm7

+E-Mail: whatisthis.sowhat _at_ gmail.com +

-E-Mail: whatisthis.sowhat _at_ gmail.com
-
-
+
All of distributing are published under Gnu Public License version 2.
You must publish sourcecodes to users of binaries, you must publish changes of source codes to users.

See also:
-https://www.gnu.org/licenses/gpl-2.0.html .
+ +

+
+
Last modified: @@BuildDateAt@@ +
diff --git a/source/src/res/familybasic.rc b/source/src/res/familybasic.rc index 668791ee4..307aec01b 100644 --- a/source/src/res/familybasic.rc +++ b/source/src/res/familybasic.rc @@ -213,6 +213,7 @@ BEGIN MENUITEM "Joystick #2", ID_INPUT_JOYSTICK1 END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm16beta.rc b/source/src/res/fm16beta.rc index 1fe17e91b..08cadb778 100644 --- a/source/src/res/fm16beta.rc +++ b/source/src/res/fm16beta.rc @@ -230,6 +230,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm16pi.rc b/source/src/res/fm16pi.rc index 2feaba7aa..41e73c64a 100644 --- a/source/src/res/fm16pi.rc +++ b/source/src/res/fm16pi.rc @@ -205,6 +205,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm7.rc b/source/src/res/fm7.rc index e50f72947..c9bbafa53 100644 --- a/source/src/res/fm7.rc +++ b/source/src/res/fm7.rc @@ -280,6 +280,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm77.rc b/source/src/res/fm77.rc index 68d98d28b..0df763f3b 100644 --- a/source/src/res/fm77.rc +++ b/source/src/res/fm77.rc @@ -282,6 +282,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm77av.rc b/source/src/res/fm77av.rc index 4da2e511f..f6e528603 100644 --- a/source/src/res/fm77av.rc +++ b/source/src/res/fm77av.rc @@ -275,6 +275,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm77av40.rc b/source/src/res/fm77av40.rc index 64c285c80..5a3400724 100644 --- a/source/src/res/fm77av40.rc +++ b/source/src/res/fm77av40.rc @@ -277,6 +277,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm77av40ex.rc b/source/src/res/fm77av40ex.rc index 75bf762d2..e4e34d364 100644 --- a/source/src/res/fm77av40ex.rc +++ b/source/src/res/fm77av40ex.rc @@ -277,6 +277,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm77l4.rc b/source/src/res/fm77l4.rc index fc7d91d59..6715feab5 100644 --- a/source/src/res/fm77l4.rc +++ b/source/src/res/fm77l4.rc @@ -282,6 +282,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fm8.rc b/source/src/res/fm8.rc index 622af6bee..995793881 100644 --- a/source/src/res/fm8.rc +++ b/source/src/res/fm8.rc @@ -290,6 +290,7 @@ BEGIN MENUITEM "Joystick To Keyboard", ID_INPUT_JOYTOKEY END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fmr30.rc b/source/src/res/fmr30.rc index 9304bb200..66cfa460f 100644 --- a/source/src/res/fmr30.rc +++ b/source/src/res/fmr30.rc @@ -157,6 +157,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD1 MENUITEM "Unmount", ID_CLOSE_HD1 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD1 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD1 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD1 END @@ -164,6 +166,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD2 MENUITEM "Unmount", ID_CLOSE_HD2 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD2 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD2 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD2 END @@ -171,6 +175,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD3 MENUITEM "Unmount", ID_CLOSE_HD3 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD3 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD3 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD3 END @@ -178,6 +184,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD4 MENUITEM "Unmount", ID_CLOSE_HD4 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD4 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD4 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD4 END @@ -234,6 +242,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fmr50_i286.rc b/source/src/res/fmr50_i286.rc index 846069c14..75cf8388c 100644 --- a/source/src/res/fmr50_i286.rc +++ b/source/src/res/fmr50_i286.rc @@ -183,6 +183,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD1 MENUITEM "Unmount", ID_CLOSE_HD1 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD1 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD1 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD1 END @@ -190,6 +192,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD2 MENUITEM "Unmount", ID_CLOSE_HD2 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD2 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD2 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD2 END @@ -197,6 +201,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD3 MENUITEM "Unmount", ID_CLOSE_HD3 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD3 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD3 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD3 END @@ -204,6 +210,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD4 MENUITEM "Unmount", ID_CLOSE_HD4 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD4 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD4 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD4 END @@ -274,6 +282,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fmr50_i386.rc b/source/src/res/fmr50_i386.rc index 103048bfe..d35e32845 100644 --- a/source/src/res/fmr50_i386.rc +++ b/source/src/res/fmr50_i386.rc @@ -183,6 +183,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD1 MENUITEM "Unmount", ID_CLOSE_HD1 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD1 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD1 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD1 END @@ -190,6 +192,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD2 MENUITEM "Unmount", ID_CLOSE_HD2 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD2 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD2 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD2 END @@ -197,6 +201,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD3 MENUITEM "Unmount", ID_CLOSE_HD3 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD3 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD3 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD3 END @@ -204,6 +210,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD4 MENUITEM "Unmount", ID_CLOSE_HD4 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD4 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD4 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD4 END @@ -274,6 +282,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fmr50_i486.rc b/source/src/res/fmr50_i486.rc index 2aba854b5..e79d953af 100644 --- a/source/src/res/fmr50_i486.rc +++ b/source/src/res/fmr50_i486.rc @@ -183,6 +183,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD1 MENUITEM "Unmount", ID_CLOSE_HD1 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD1 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD1 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD1 END @@ -190,6 +192,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD2 MENUITEM "Unmount", ID_CLOSE_HD2 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD2 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD2 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD2 END @@ -197,6 +201,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD3 MENUITEM "Unmount", ID_CLOSE_HD3 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD3 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD3 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD3 END @@ -204,6 +210,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD4 MENUITEM "Unmount", ID_CLOSE_HD4 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD4 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD4 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD4 END @@ -274,6 +282,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fmr60.rc b/source/src/res/fmr60.rc index 2b7b6d566..1e118b75f 100644 --- a/source/src/res/fmr60.rc +++ b/source/src/res/fmr60.rc @@ -183,6 +183,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD1 MENUITEM "Unmount", ID_CLOSE_HD1 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD1 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD1 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD1 END @@ -190,6 +192,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD2 MENUITEM "Unmount", ID_CLOSE_HD2 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD2 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD2 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD2 END @@ -197,6 +201,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD3 MENUITEM "Unmount", ID_CLOSE_HD3 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD3 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD3 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD3 END @@ -204,6 +210,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD4 MENUITEM "Unmount", ID_CLOSE_HD4 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD4 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD4 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD4 END @@ -274,6 +282,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fmr70.rc b/source/src/res/fmr70.rc index 25c3b6b98..9f9c4f618 100644 --- a/source/src/res/fmr70.rc +++ b/source/src/res/fmr70.rc @@ -183,6 +183,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD1 MENUITEM "Unmount", ID_CLOSE_HD1 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD1 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD1 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD1 END @@ -190,6 +192,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD2 MENUITEM "Unmount", ID_CLOSE_HD2 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD2 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD2 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD2 END @@ -197,6 +201,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD3 MENUITEM "Unmount", ID_CLOSE_HD3 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD3 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD3 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD3 END @@ -204,6 +210,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD4 MENUITEM "Unmount", ID_CLOSE_HD4 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD4 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD4 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD4 END @@ -274,6 +282,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fmr80.rc b/source/src/res/fmr80.rc index 3566a8741..5d42ef803 100644 --- a/source/src/res/fmr80.rc +++ b/source/src/res/fmr80.rc @@ -183,6 +183,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD1 MENUITEM "Unmount", ID_CLOSE_HD1 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD1 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD1 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD1 END @@ -190,6 +192,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD2 MENUITEM "Unmount", ID_CLOSE_HD2 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD2 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD2 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD2 END @@ -197,6 +201,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD3 MENUITEM "Unmount", ID_CLOSE_HD3 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD3 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD3 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD3 END @@ -204,6 +210,8 @@ BEGIN BEGIN MENUITEM "Mount", ID_OPEN_HD4 MENUITEM "Unmount", ID_CLOSE_HD4 + MENUITEM "Mount Blank 20MB Disk", ID_OPEN_BLANK_20MB_HD4 + MENUITEM "Mount Blank 40MB Disk", ID_OPEN_BLANK_40MB_HD4 MENUITEM SEPARATOR MENUITEM "Recent", ID_RECENT_HD4 END @@ -274,6 +282,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fp1100.rc b/source/src/res/fp1100.rc index d0e1a5af9..cbaa4d7ed 100644 --- a/source/src/res/fp1100.rc +++ b/source/src/res/fp1100.rc @@ -237,6 +237,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fp200.ico b/source/src/res/fp200.ico index f48334b7a..f614a53ad 100644 Binary files a/source/src/res/fp200.ico and b/source/src/res/fp200.ico differ diff --git a/source/src/res/fp200.rc b/source/src/res/fp200.rc index b42ed0b57..dbd71cd38 100644 --- a/source/src/res/fp200.rc +++ b/source/src/res/fp200.rc @@ -200,6 +200,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/fsa1.rc b/source/src/res/fsa1.rc index 76cc46031..7f0b528d4 100644 --- a/source/src/res/fsa1.rc +++ b/source/src/res/fsa1.rc @@ -225,6 +225,7 @@ BEGIN MENUITEM "Joystick #2", ID_INPUT_JOYSTICK1 END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/gamegear.rc b/source/src/res/gamegear.rc index 0a0276b6d..7123312ae 100644 --- a/source/src/res/gamegear.rc +++ b/source/src/res/gamegear.rc @@ -193,6 +193,7 @@ BEGIN MENUITEM "Joystick #2", ID_INPUT_JOYSTICK1 END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/hc20.rc b/source/src/res/hc20.rc index 4787d9fe4..f68fc0ba5 100644 --- a/source/src/res/hc20.rc +++ b/source/src/res/hc20.rc @@ -221,6 +221,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/hc40.rc b/source/src/res/hc40.rc index cd2c18ad8..dd5274852 100644 --- a/source/src/res/hc40.rc +++ b/source/src/res/hc40.rc @@ -241,6 +241,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/hc80.rc b/source/src/res/hc80.rc index 7d8edea5f..031a0cbd7 100644 --- a/source/src/res/hc80.rc +++ b/source/src/res/hc80.rc @@ -230,6 +230,7 @@ BEGIN MENUITEM "Volume", ID_SOUND_VOLUME END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/hx20.rc b/source/src/res/hx20.rc index 10181b408..0ee4697ad 100644 --- a/source/src/res/hx20.rc +++ b/source/src/res/hx20.rc @@ -251,6 +251,7 @@ BEGIN MENUITEM "Joystick #2", ID_INPUT_JOYSTICK1 END MENUITEM SEPARATOR + MENUITEM "Use Direct2D1", ID_HOST_USE_D2D1 MENUITEM "Use Direct3D9", ID_HOST_USE_D3D9 MENUITEM "Wait Vsync", ID_HOST_WAIT_VSYNC MENUITEM "Use DirectInput", ID_HOST_USE_DINPUT diff --git a/source/src/res/i18n/ja/babbage2nd.qm b/source/src/res/i18n/ja/babbage2nd.ja_JP.qm similarity index 100% rename from source/src/res/i18n/ja/babbage2nd.qm rename to source/src/res/i18n/ja/babbage2nd.ja_JP.qm diff --git a/source/src/res/i18n/ja/jr800.qm b/source/src/res/i18n/ja/bmjr.ja_JP.qm similarity index 100% rename from source/src/res/i18n/ja/jr800.qm rename to source/src/res/i18n/ja/bmjr.ja_JP.qm diff --git a/source/src/res/i18n/ja/bubcom80.qm b/source/src/res/i18n/ja/bubcom80.ja_JP.qm similarity index 100% rename from source/src/res/i18n/ja/bubcom80.qm rename to source/src/res/i18n/ja/bubcom80.ja_JP.qm diff --git a/source/src/res/i18n/ja/cefucom21.ja_JP.qm b/source/src/res/i18n/ja/cefucom21.ja_JP.qm new file mode 100644 index 000000000..be651eede --- /dev/null +++ b/source/src/res/i18n/ja/cefucom21.ja_JP.qm @@ -0,0 +1 @@ +set_device_name(_T("Z80 PIO (LEDs)")); pio2 = new Z80PIO(this, emu); pio2->set_device_name(_T("Z80 PIO (7-Seg/Keyboard)")); - + display = new DISPLAY(this, emu); keyboard = new KEYBOARD(this, emu); @@ -232,6 +233,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -244,7 +257,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/babbage2nd/babbage2nd.h b/source/src/vm/babbage2nd/babbage2nd.h index 394294484..762368eff 100644 --- a/source/src/vm/babbage2nd/babbage2nd.h +++ b/source/src/vm/babbage2nd/babbage2nd.h @@ -125,7 +125,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -156,12 +156,15 @@ class VM : public VM_TEMPLATE // notify key void key_down(int code, bool repeat); void key_up(int code); - + // user interface void load_binary(int drv, const _TCHAR* file_path); void save_binary(int drv, const _TCHAR* file_path); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/babbage2nd/display.h b/source/src/vm/babbage2nd/display.h index 13c255ef9..9ceb61a17 100644 --- a/source/src/vm/babbage2nd/display.h +++ b/source/src/vm/babbage2nd/display.h @@ -29,7 +29,7 @@ class DISPLAY : public DEVICE uint8_t pio_8bit; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("7-Segment LEDs")); } diff --git a/source/src/vm/babbage2nd/keyboard.h b/source/src/vm/babbage2nd/keyboard.h index 4b587a9e6..f446bbf81 100644 --- a/source/src/vm/babbage2nd/keyboard.h +++ b/source/src/vm/babbage2nd/keyboard.h @@ -21,7 +21,7 @@ class KEYBOARD : public DEVICE DEVICE *d_pio; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/beep.h b/source/src/vm/beep.h index 0f9f410d1..272de1ce2 100644 --- a/source/src/vm/beep.h +++ b/source/src/vm/beep.h @@ -17,9 +17,9 @@ #define SIG_BEEP_ON 0 #define SIG_BEEP_MUTE 1 -class VM; -class EMU; -class BEEP : public DEVICE +class VM_TEMPLATE; +class EMU_TEMPLATE; +class DLL_PREFIX BEEP : public DEVICE { private: int gen_rate; @@ -34,7 +34,7 @@ class BEEP : public DEVICE bool mute; public: - BEEP(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + BEEP(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("Beep Generator")); @@ -44,7 +44,7 @@ class BEEP : public DEVICE // common functions void reset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); bool is_debugger_available() diff --git a/source/src/vm/bmjr/CMakeLists.txt b/source/src/vm/bmjr/CMakeLists.txt index f8c99a85f..0dbecc8f7 100644 --- a/source/src/vm/bmjr/CMakeLists.txt +++ b/source/src/vm/bmjr/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/bmjr") +message("* vm/${EXE_NAME}") -add_library(vm_bmjr +add_library(vm_${EXE_NAME} bmjr.cpp memory.cpp -) \ No newline at end of file +) diff --git a/source/src/vm/bmjr/bmjr.cpp b/source/src/vm/bmjr/bmjr.cpp index e02f534f5..644c0d87c 100644 --- a/source/src/vm/bmjr/bmjr.cpp +++ b/source/src/vm/bmjr/bmjr.cpp @@ -28,7 +28,7 @@ // ---------------------------------------------------------------------------- using BMJR::MEMORY; -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -110,7 +110,7 @@ void VM::reset() } } -void VM::special_reset() +void VM::special_reset(int num) { // reset all devices for(DEVICE* device = first_device; device; device = device->next_device) { @@ -199,6 +199,7 @@ void VM::key_down(int code, bool repeat) void VM::key_up(int code) { + memory->key_up(code); } // ---------------------------------------------------------------------------- @@ -296,8 +297,19 @@ void VM::update_config() } } -#define STATE_VERSION 3 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -309,7 +321,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/bmjr/bmjr.h b/source/src/vm/bmjr/bmjr.h index 899e53caa..a086cbcb3 100644 --- a/source/src/vm/bmjr/bmjr.h +++ b/source/src/vm/bmjr/bmjr.h @@ -72,7 +72,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -81,7 +81,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -122,6 +122,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/bmjr/memory.cpp b/source/src/vm/bmjr/memory.cpp index 8bd248fcc..808ddf688 100644 --- a/source/src/vm/bmjr/memory.cpp +++ b/source/src/vm/bmjr/memory.cpp @@ -142,8 +142,9 @@ void MEMORY::write_data8(uint32_t addr, uint32_t data) d_drec->write_signal(SIG_DATAREC_MIC, ~data, 0x01); break; case 0xeec0: + // From BM2/bm2mem.c key_column = data & 0x0f; - nmi_enb = ((data & 0x80) != 0); + nmi_enb = ((data & 0xff) == 0xf0); event_frame(); // update keyboard break; case 0xefd0: @@ -203,11 +204,7 @@ uint32_t MEMORY::read_data8(uint32_t addr) // unknown (timer) break; case 0xef80: - if(break_pressed) { - break_pressed = false; - return 0x80; - } - return 0x00; + return 0xff; // from BM2 ; OK? 20200114 K.O case 0xefd0: return memory_bank; } @@ -261,14 +258,18 @@ void MEMORY::event_frame() if(key_stat[key_table[key_column][1]]) key_data &= ~0x02; if(key_stat[key_table[key_column][2]]) key_data &= ~0x04; if(key_stat[key_table[key_column][3]]) key_data &= ~0x08; + if(key_column == 12) { // MAP Back Space to Delete. 20200114 K.O + if(key_stat[0x08]) key_data &= ~0x04; + } } #if defined(_USE_QT) // If same as bm2, not effect below keys at Qt version. if(key_stat[VK_LCONTROL]) key_data &= ~0x10; // 英数 -> LCTRL if(key_stat[VK_LSHIFT ]) key_data &= ~0x20; // 英記号 -> L-SHIFT - if(key_stat[VK_RWIN ]) key_data &= ~0x40; // カナ記号 -> R-Win + if(key_stat[VK_RSHIFT ]) key_data &= ~0x40; // カナ記号 -> R-SHIFT if(key_stat[VK_KANA ]) key_data &= ~0x80; // カナ -> カタカナひらがな + if(key_stat[VK_RCONTROL]) key_data &= ~0x80; // カナ -> R-CTRL #else // this is same as "日立ベーシックマスターJr.(MB-6885)エミュレータ bm2" if(key_stat[0xa2]) key_data &= ~0x10; // 英数 -> L-CTRL @@ -276,19 +277,35 @@ void MEMORY::event_frame() if(key_stat[0xa1]) key_data &= ~0x40; // カナ記号 -> R-SHIFT if(key_stat[0xa3]) key_data &= ~0x80; // カナ -> R-CTRL #endif + if((break_pressed) && (nmi_enb)) { + break_pressed = false; + d_cpu->write_signal(SIG_CPU_NMI, 1, 1); + //printf("NMI\n"); + } + // from BM2: 20200114 K.O + if((break_pressed) && ((key_data & 0x40) == 0)) { + d_cpu->reset(); + } } void MEMORY::key_down(int code) { // pause -> break - if(code == 0x13) { - if(nmi_enb) { - d_cpu->write_signal(SIG_CPU_NMI, 1, 1); - } + // esc -> break + if((code == 0x13) || (code == 0x1b)) { break_pressed = true; } } +void MEMORY::key_up(int code) +{ + // pause -> break + // esc -> break + if((code == 0x13) || (code == 0x1b)) { + break_pressed = false; + } +} + void MEMORY::update_bank() { if(memory_bank & 1) { diff --git a/source/src/vm/bmjr/memory.h b/source/src/vm/bmjr/memory.h index 18ed55345..3562a5ac8 100644 --- a/source/src/vm/bmjr/memory.h +++ b/source/src/vm/bmjr/memory.h @@ -60,7 +60,7 @@ class MEMORY : public DEVICE _bit_trans_table_t bit_table; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("Memory Bus")); @@ -74,7 +74,7 @@ class MEMORY : public DEVICE uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_frame(); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); @@ -92,6 +92,7 @@ class MEMORY : public DEVICE d_pia = device; } void key_down(int code); + void key_up(int code); void draw_screen(); }; } diff --git a/source/src/vm/bubcom80/CMakeLists.txt b/source/src/vm/bubcom80/CMakeLists.txt index 037a35545..76544480c 100644 --- a/source/src/vm/bubcom80/CMakeLists.txt +++ b/source/src/vm/bubcom80/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/bubcom80") +message("* vm/${EXE_NAME}") -add_library(vm_bubcom80 +add_library(vm_${EXE_NAME} bubblecasette.cpp cmt.cpp display.cpp diff --git a/source/src/vm/bubcom80/bubblecasette.h b/source/src/vm/bubcom80/bubblecasette.h index a4104fa8e..f83cce895 100644 --- a/source/src/vm/bubcom80/bubblecasette.h +++ b/source/src/vm/bubcom80/bubblecasette.h @@ -104,7 +104,7 @@ class BUBBLECASETTE: public DEVICE bool write_one_page(void); public: - BUBBLECASETTE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + BUBBLECASETTE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { fio = NULL; memset(image_path, 0x00, _MAX_PATH * sizeof(_TCHAR)); @@ -126,7 +126,7 @@ class BUBBLECASETTE: public DEVICE uint32_t __FASTCALL read_signal(int id); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/bubcom80/bubcom80.cpp b/source/src/vm/bubcom80/bubcom80.cpp index 982bc3890..ba65ae4fe 100644 --- a/source/src/vm/bubcom80/bubcom80.cpp +++ b/source/src/vm/bubcom80/bubcom80.cpp @@ -47,7 +47,7 @@ using BUBCOM80::KEYBOARD; using BUBCOM80::MEMBUS; using BUBCOM80::RTC; -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -87,6 +87,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) floppy = new FLOPPY(this, emu); keyboard = new KEYBOARD(this, emu); membus = new MEMBUS(this, emu); + rtc = new RTC(this, emu); // set contexts @@ -367,6 +368,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 1 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -379,7 +392,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/bubcom80/bubcom80.h b/source/src/vm/bubcom80/bubcom80.h index 4858ff916..cf691ab9e 100644 --- a/source/src/vm/bubcom80/bubcom80.h +++ b/source/src/vm/bubcom80/bubcom80.h @@ -108,7 +108,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -154,6 +154,9 @@ class VM : public VM_TEMPLATE void is_bubble_casette_protected(int drv, bool flag); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/bubcom80/cmt.h b/source/src/vm/bubcom80/cmt.h index 415bdf4b9..88123f53e 100644 --- a/source/src/vm/bubcom80/cmt.h +++ b/source/src/vm/bubcom80/cmt.h @@ -35,7 +35,7 @@ class CMT : public DEVICE void release_tape(); public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } @@ -45,6 +45,7 @@ class CMT : public DEVICE void initialize(); void release(); void reset(); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/bubcom80/display.h b/source/src/vm/bubcom80/display.h index 33ca7d7c3..c518b1b26 100644 --- a/source/src/vm/bubcom80/display.h +++ b/source/src/vm/bubcom80/display.h @@ -112,7 +112,7 @@ class DISPLAY : public DEVICE void draw_graph(); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 4; i++) { dmac.ch[i].io = parent_vm->dummy; @@ -130,7 +130,7 @@ class DISPLAY : public DEVICE uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_frame(); void event_vline(int v, int clock); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/bubcom80/floppy.h b/source/src/vm/bubcom80/floppy.h index 0855f7578..c50e8423d 100644 --- a/source/src/vm/bubcom80/floppy.h +++ b/source/src/vm/bubcom80/floppy.h @@ -21,7 +21,7 @@ class FLOPPY : public DEVICE DEVICE* d_fdc; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/bubcom80/keyboard.h b/source/src/vm/bubcom80/keyboard.h index 31a1c3438..d18901cb5 100644 --- a/source/src/vm/bubcom80/keyboard.h +++ b/source/src/vm/bubcom80/keyboard.h @@ -22,7 +22,7 @@ class KEYBOARD : public DEVICE const uint32_t* joy_stat; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/bubcom80/membus.h b/source/src/vm/bubcom80/membus.h index 74e5d31d2..e13d03b5f 100644 --- a/source/src/vm/bubcom80/membus.h +++ b/source/src/vm/bubcom80/membus.h @@ -10,6 +10,7 @@ #ifndef _MEMBUS_H_ #define _MEMBUS_H_ +#include "../vm.h" #include "../memory.h" namespace BUBCOM80 { @@ -29,7 +30,7 @@ class MEMBUS : public MEMORY void update_bank(); public: - MEMBUS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu) + MEMBUS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MEMORY(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/bubcom80/rtc.h b/source/src/vm/bubcom80/rtc.h index 8e2b87697..97f8f7d35 100644 --- a/source/src/vm/bubcom80/rtc.h +++ b/source/src/vm/bubcom80/rtc.h @@ -23,7 +23,7 @@ class RTC : public DEVICE uint8_t ctrl; public: - RTC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RTC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RTC")); } @@ -34,7 +34,7 @@ class RTC : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); }; } diff --git a/source/src/vm/cefucom21/CMakeLists.txt b/source/src/vm/cefucom21/CMakeLists.txt index c5961d7a6..86d9c005a 100644 --- a/source/src/vm/cefucom21/CMakeLists.txt +++ b/source/src/vm/cefucom21/CMakeLists.txt @@ -2,9 +2,10 @@ cmake_minimum_required (VERSION 2.6) message("* vm/cefucom21") -add_library(vm_cefucom21 +add_library(vm_emucefucom21 cefucom21.cpp mcu.cpp pcu.cpp + ../mc6847.cpp ) diff --git a/source/src/vm/cefucom21/cefucom21.cpp b/source/src/vm/cefucom21/cefucom21.cpp index a6d40cce6..981233a12 100644 --- a/source/src/vm/cefucom21/cefucom21.cpp +++ b/source/src/vm/cefucom21/cefucom21.cpp @@ -38,7 +38,7 @@ // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -56,6 +56,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) mcu_io = new IO(this, emu); mcu_vdp = new MC6847(this, emu); mcu_mem = new MEMORY(this, emu); + mcu_not = new NOT(this, emu); mcu_cpu = new Z80(this, emu); mcu_pio = new Z80PIO(this, emu); @@ -66,6 +67,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pcu_pio3 = new I8255(this, emu); pcu_io = new IO(this, emu); pcu_mem = new MEMORY(this, emu); + pcu_rtc = new RP5C01(this, emu); pcu_cpu = new Z80(this, emu); pcu_ctc1 = new Z80CTC(this, emu); @@ -412,6 +414,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 5 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -421,7 +435,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) } for(DEVICE* device = first_device; device; device = device->next_device) { const char *name = typeid(*device).name() + 6; // skip "class " - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { return false; diff --git a/source/src/vm/cefucom21/cefucom21.h b/source/src/vm/cefucom21/cefucom21.h index 05f29d97b..405430ba8 100644 --- a/source/src/vm/cefucom21/cefucom21.h +++ b/source/src/vm/cefucom21/cefucom21.h @@ -124,7 +124,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -172,6 +172,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/cefucom21/mcu.h b/source/src/vm/cefucom21/mcu.h index 1157d5b4a..675a7bcd5 100644 --- a/source/src/vm/cefucom21/mcu.h +++ b/source/src/vm/cefucom21/mcu.h @@ -25,7 +25,7 @@ class MCU : public DEVICE uint8_t system_port; public: - MCU(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MCU(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MCU02")); } diff --git a/source/src/vm/cefucom21/pcu.h b/source/src/vm/cefucom21/pcu.h index 9be4eb6ec..0b264a7e6 100644 --- a/source/src/vm/cefucom21/pcu.h +++ b/source/src/vm/cefucom21/pcu.h @@ -19,7 +19,7 @@ class PCU : public DEVICE private: public: - PCU(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PCU(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("PCU-I")); } diff --git a/source/src/vm/colecovision/CMakeLists.txt b/source/src/vm/colecovision/CMakeLists.txt index 53a02cd24..1e2d499d4 100644 --- a/source/src/vm/colecovision/CMakeLists.txt +++ b/source/src/vm/colecovision/CMakeLists.txt @@ -1,10 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/colecovision") +message("* vm/emucolecovision") -add_library(vm_colecovision - colecovision.cpp - - memory.cpp +add_library(vm_emucolecovision + ./memory.cpp keyboard.cpp + + colecovision.cpp ) diff --git a/source/src/vm/colecovision/colecovision.cpp b/source/src/vm/colecovision/colecovision.cpp index 23f435703..c67dcabf5 100644 --- a/source/src/vm/colecovision/colecovision.cpp +++ b/source/src/vm/colecovision/colecovision.cpp @@ -30,7 +30,7 @@ using COLECOVISION::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -216,6 +216,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -228,7 +240,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/colecovision/colecovision.h b/source/src/vm/colecovision/colecovision.h index 2ac52f28c..f91cb9883 100644 --- a/source/src/vm/colecovision/colecovision.h +++ b/source/src/vm/colecovision/colecovision.h @@ -77,7 +77,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -110,6 +110,9 @@ class VM : public VM_TEMPLATE bool is_cart_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/colecovision/keyboard.h b/source/src/vm/colecovision/keyboard.h index 7282066cf..17ce1a3b9 100644 --- a/source/src/vm/colecovision/keyboard.h +++ b/source/src/vm/colecovision/keyboard.h @@ -24,7 +24,7 @@ class KEYBOARD : public DEVICE const uint32_t* joy_stat; bool tenkey; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/colecovision/memory.h b/source/src/vm/colecovision/memory.h index a808cf3ec..7c0655c20 100644 --- a/source/src/vm/colecovision/memory.h +++ b/source/src/vm/colecovision/memory.h @@ -31,7 +31,7 @@ class MEMORY : public DEVICE bool inserted; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/common_vm/CMakeLists.txt b/source/src/vm/common_vm/CMakeLists.txt index 434834427..96168a9b8 100644 --- a/source/src/vm/common_vm/CMakeLists.txt +++ b/source/src/vm/common_vm/CMakeLists.txt @@ -1,6 +1,6 @@ message("* vm/common_vm") -SET(THIS_LIB_VERSION 2.19.1) +SET(THIS_LIB_VERSION 3.2.0) #include(cotire) set(s_vm_common_vm_srcs @@ -19,7 +19,8 @@ set(s_vm_common_vm_srcs ../hd63484.cpp ../huc6280_base.cpp ../i286.cpp - ../i386.cpp +# ../i386.cpp + ../i386_dasm.cpp ../i8080_base.cpp ../i8155.cpp @@ -29,7 +30,7 @@ set(s_vm_common_vm_srcs ../i8255.cpp ../i8259.cpp ../i86.cpp -# ../io.cpp + ../io.cpp # ../ld700.cpp ../ls244.cpp ../ls393.cpp @@ -40,14 +41,15 @@ set(s_vm_common_vm_srcs ../mc6801.cpp ../hd6301.cpp ../mb8861.cpp - # MC6809 is temporally. - ../mc6809_base.cpp + ../mc6809.cpp ../mc6820.cpp ../mc6840.cpp ../mc6844.cpp ../mc6847_base.cpp ../mc6850.cpp ../mcs48_base.cpp + + ../memory.cpp ../msm5205.cpp ../msm58321_base.cpp ../midi_redirector.cpp @@ -65,9 +67,9 @@ set(s_vm_common_vm_srcs ../prnfile.cpp ../ptf20.cpp ../rp5c01.cpp -# ../scsi_cdrom.cpp -# ../scsi_dev_base.cpp -# ../scsi_hdd.cpp + ../scsi_cdrom.cpp + ../scsi_dev.cpp + ../scsi_hdd.cpp # ../scsi_host.cpp ../sio_redirector.cpp @@ -89,7 +91,7 @@ set(s_vm_common_vm_srcs ../upd7810.cpp ../upd7907.cpp - ../v30.cpp + ../v30_dasm.cpp # 20170518/MSX: Use v9938.cpp and define "-D_MSX_VDP_MESS" instead of v99x8.cpp . ../v9938.cpp ## ../v99x8.cpp @@ -97,7 +99,7 @@ set(s_vm_common_vm_srcs ../ym2151.cpp ../ym2203.cpp ../ym2413.cpp - ../z80_base.cpp + ../z80.cpp ../z80ctc.cpp ../z80dma.cpp ../z80pio.cpp @@ -107,7 +109,62 @@ set(s_vm_common_vm_srcs ../fm7/hd6844.cpp ../fm7/mb61vh010.cpp # ../fm7/dummydevice.cpp +# ../fmtowns/ym2612.cpp +# ../i286_np21.cpp +# ../np21/i286c/cpumem.cpp +# ../np21/i286c/i286c.cpp +# ../np21/i286c/i286c_0f.cpp +# ../np21/i286c/i286c_8x.cpp +# ../np21/i286c/i286c_ea.cpp +# ../np21/i286c/i286c_f6.cpp +# ../np21/i286c/i286c_fe.cpp +# ../np21/i286c/i286c_mn.cpp +# ../np21/i286c/i286c_rp.cpp +# ../np21/i286c/i286c_sf.cpp +# ../np21/i286c/v30patch.cpp + + ../i386_np21.cpp + ../np21/i386c/cpucore.cpp + ../np21/i386c/cpumem.cpp + ../np21/i386c/ia32/cpu.cpp + ../np21/i386c/ia32/cpu_io.cpp + ../np21/i386c/ia32/cpu_mem.cpp + ../np21/i386c/ia32/ctrlxfer.cpp + ../np21/i386c/ia32/debug.cpp + ../np21/i386c/ia32/exception.cpp + ../np21/i386c/ia32/groups.cpp + ../np21/i386c/ia32/ia32.cpp + ../np21/i386c/ia32/inst_table.cpp + ../np21/i386c/ia32/interface.cpp + ../np21/i386c/ia32/paging.cpp + ../np21/i386c/ia32/resolve.cpp + ../np21/i386c/ia32/segments.cpp + ../np21/i386c/ia32/task.cpp + ../np21/i386c/ia32/instructions/bin_arith.cpp + ../np21/i386c/ia32/instructions/bit_byte.cpp + ../np21/i386c/ia32/instructions/ctrl_trans.cpp + ../np21/i386c/ia32/instructions/data_trans.cpp + ../np21/i386c/ia32/instructions/dec_arith.cpp + ../np21/i386c/ia32/instructions/flag_ctrl.cpp + ../np21/i386c/ia32/instructions/fpu.cpp + ../np21/i386c/ia32/instructions/logic_arith.cpp + ../np21/i386c/ia32/instructions/misc_inst.cpp + ../np21/i386c/ia32/instructions/seg_reg.cpp + ../np21/i386c/ia32/instructions/shift_rotate.cpp + ../np21/i386c/ia32/instructions/string_inst.cpp + ../np21/i386c/ia32/instructions/system_inst.cpp + ../np21/i386c/ia32/instructions/fpu/fpdummy.cpp + ../np21/i386c/ia32/instructions/fpu/fpemul_dosbox.cpp + ../np21/i386c/ia32/instructions/fpu/fpemul_dosbox2.cpp + ../np21/i386c/ia32/instructions/fpu/fpemul_softfloat.cpp + ../np21/i386c/ia32/instructions/fpu/softfloat/softfloat.cpp + + ../np21/i386c/ia32/instructions/mmx/3dnow.cpp + ../np21/i386c/ia32/instructions/mmx/mmx.cpp + ../np21/i386c/ia32/instructions/sse/sse.cpp + ../np21/i386c/ia32/instructions/sse2/sse2.cpp + ../np21/i386c/ia32/instructions/sse3/sse3.cpp ../libcpu_newdev/device.cpp ) @@ -119,33 +176,37 @@ add_definitions(-D__LIBRARY_NAME=\"libCSPcommon_vm.${THIS_LIB_VERSION}\") if(WIN32) include (GenerateExportHeader) -#add_library(CSPcommon_vm SHARED -# ${s_vm_common_vm_srcs} -# ) +add_library(CSPcommon_vm SHARED + ${s_vm_common_vm_srcs} + ) -#target_link_libraries(CSPcommon_vm PUBLIC +target_link_libraries(CSPcommon_vm PRIVATE + CSPosd + CSPemu_utils + CSPfmgen # ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPosd.dll.a # ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPemu_utils.dll.a # Qt5::Core # Qt5::Gui # Qt5::OpenGL # Qt5::Widgets -# ${SDL2_LIBRARIES} -# ) -#set_target_properties(CSPcommon_vm PROPERTIES -# SOVERSION ${THIS_LIB_VERSION} -# VERSION ${THIS_LIB_VERSION} -# LINK_INTERFACE_LIBRARIES "" -# ) -#generate_export_header(CSPcommon_vm -# BASE_NAME CSPcommon_vm -# EXPORT_MACRO_NAME CSPcommon_vm_EXPORT -# EXPORT_FILE_NAME CSPcommon_vm_Export.h -# STATIC_DEFINE CSPcommon_vm_BUILT_AS_STATIC -#) -add_library(vm_common_vm - ${s_vm_common_vm_srcs} - ) + ${SDL2_LIBRARIES} + ) +set_target_properties(CSPcommon_vm PROPERTIES + SOVERSION ${THIS_LIB_VERSION} + VERSION ${THIS_LIB_VERSION} + LINK_INTERFACE_LIBRARIES "" + ) + set_std(CSPcommon_vm) +generate_export_header(CSPcommon_vm + BASE_NAME CSPcommon_vm + EXPORT_MACRO_NAME CSPcommon_vm_EXPORT + EXPORT_FILE_NAME CSPcommon_vm_Export.h + STATIC_DEFINE CSPcommon_vm_BUILT_AS_STATIC +) +#add_library(vm_common_vm +# ${s_vm_common_vm_srcs} +# ) else() add_library(CSPcommon_vm SHARED @@ -155,6 +216,8 @@ else() SOVERSION ${THIS_LIB_VERSION} VERSION ${THIS_LIB_VERSION} ) + set_std(CSPcommon_vm) # cotire(CSPcommon_vm) INSTALL(TARGETS CSPcommon_vm DESTINATION ${LIBCSP_INSTALL_DIR}) endif() + diff --git a/source/src/vm/datarec.h b/source/src/vm/datarec.h index 760681b74..20da6c784 100644 --- a/source/src/vm/datarec.h +++ b/source/src/vm/datarec.h @@ -21,7 +21,7 @@ class FILEIO; class NOISE; -class DATAREC : public DEVICE +class DLL_PREFIX DATAREC : public DEVICE { private: // output signals @@ -106,7 +106,7 @@ class DATAREC : public DEVICE int load_msx_cas_image(); public: - DATAREC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DATAREC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_ear); initialize_output_signals(&outputs_remote); @@ -144,8 +144,8 @@ class DATAREC : public DEVICE return in_signal ? 1 : 0; } void event_frame(); - void event_callback(int event_id, int err); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int event_id, int err); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/debugger.h b/source/src/vm/debugger.h index bf9ac8552..c26c301e5 100644 --- a/source/src/vm/debugger.h +++ b/source/src/vm/debugger.h @@ -21,8 +21,7 @@ #define MAX_COMMAND_HISTORY 32 //#define MAX_CPU_TRACE 0x01000000 /* 16Msteps */ #define MAX_CPU_TRACE 0x00100000 /* 1Msteps */ - - +#define TRACE_TYPE_CALL 0x00000000 typedef struct { struct { uint32_t addr, mask; @@ -81,7 +80,7 @@ class DEBUGGER : public DEVICE } } public: - DEBUGGER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DEBUGGER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { memset(&bp, 0, sizeof(bp)); memset(&rbp, 0, sizeof(rbp)); @@ -100,10 +99,13 @@ class DEBUGGER : public DEVICE memset(cpu_trace_exp, 0x00, sizeof(cpu_trace_exp)); memset(cpu_trace_exp_map, 0x00, sizeof(cpu_trace_exp_map)); memset(cpu_trace_userdata, 0x00, sizeof(cpu_trace_userdata)); + memset(cpu_trace_call_type, 0x00, sizeof(cpu_trace_call_type)); + memset(cpu_trace_call, 0x00, sizeof(cpu_trace_call)); exception_happened = false; stop_on_exception = true; prev_cpu_trace = 0xffffffff; cpu_trace_ptr = 0; + cpu_trace_call_ptr = 0; cpu_trace_overwrap = false; set_device_name(_T("Debugger")); } @@ -499,17 +501,39 @@ class DEBUGGER : public DEVICE } first_symbol = last_symbol = NULL; } - void add_cpu_trace_exception(uint64_t exception_code) + void __FASTCALL add_cpu_trace_exception(uint64_t exception_code) { cpu_trace_exp[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] = exception_code; cpu_trace_exp_map[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] = true; } // Userdata should after executing instruction. - void add_cpu_trace_userdata(uint32_t data, uint32_t mask) + void __FASTCALL add_cpu_trace_userdata(uint32_t data, uint32_t mask) { cpu_trace_userdata[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] &= ~mask; cpu_trace_userdata[(cpu_trace_ptr - 1) & (MAX_CPU_TRACE - 1)] |= (data & mask); } + void __FASTCALL add_cpu_trace_irq(uint32_t pc, uint32_t irq) + { + cpu_trace_call[cpu_trace_call_ptr] = pc; + cpu_trace_call_type[cpu_trace_call_ptr] = ((uint64_t)irq << 32); + cpu_trace_call_ptr++; + cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1); + } + void __FASTCALL add_cpu_trace_call(uint32_t pc, uint32_t target) + { + cpu_trace_call[cpu_trace_call_ptr] = pc; + cpu_trace_call_type[cpu_trace_call_ptr] = (uint64_t)target; + cpu_trace_call_ptr++; + cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1); + } + void __FASTCALL add_cpu_trace_return(uint32_t pc) + { + cpu_trace_call[cpu_trace_call_ptr] = pc; + cpu_trace_call_type[cpu_trace_call_ptr] = (uint64_t)0x80000000 << 32; + cpu_trace_call_ptr++; + cpu_trace_call_ptr &= (MAX_CPU_TRACE - 1); + } + void add_cpu_trace(uint32_t pc) { if(prev_cpu_trace != pc) { @@ -536,9 +560,12 @@ class DEBUGGER : public DEVICE uint32_t cpu_trace[MAX_CPU_TRACE], prev_cpu_trace; uint64_t cpu_trace_exp[MAX_CPU_TRACE]; uint32_t cpu_trace_userdata[MAX_CPU_TRACE]; // ToDo: Is need larger userdata? + uint32_t cpu_trace_call[MAX_CPU_TRACE]; // ToDo: Is need larger userdata? + uint64_t cpu_trace_call_type[MAX_CPU_TRACE]; // ToDo: Is need larger userdata? bool cpu_trace_exp_map[MAX_CPU_TRACE]; int cpu_trace_ptr; + int cpu_trace_call_ptr; bool cpu_trace_overwrap; }; diff --git a/source/src/vm/device.h b/source/src/vm/device.h index 4da47846c..d395c83b4 100644 --- a/source/src/vm/device.h +++ b/source/src/vm/device.h @@ -11,10 +11,10 @@ #define _DEVICE_H_ #include -#include "vm.h" -#include "../emu.h" +#include "vm_template.h" +#include "../emu_template.h" #if defined(_USE_QT) -#include "osd.h" +#include "osd_base.h" #include "csp_logger.h" #define USE_DEVICE_NAME #endif @@ -45,16 +45,18 @@ #define SIG_PRINTER_ACK 205 #define SIG_PRINTER_SELECT 206 -#define SIG_SCSI_DAT 301 -#define SIG_SCSI_BSY 302 -#define SIG_SCSI_CD 303 -#define SIG_SCSI_IO 304 -#define SIG_SCSI_MSG 305 -#define SIG_SCSI_REQ 306 -#define SIG_SCSI_SEL 307 -#define SIG_SCSI_ATN 308 -#define SIG_SCSI_ACK 309 -#define SIG_SCSI_RST 310 +#define SIG_SCSI_DAT 301 +#define SIG_SCSI_BSY 302 +#define SIG_SCSI_CD 303 +#define SIG_SCSI_IO 304 +#define SIG_SCSI_MSG 305 +#define SIG_SCSI_REQ 306 +#define SIG_SCSI_SEL 307 +#define SIG_SCSI_ATN 308 +#define SIG_SCSI_ACK 309 +#define SIG_SCSI_RST 310 +#define SIG_SCSI_16BIT_BUS 311 +#define SIG_SCSI_CLEAR_QUEUE 312 #if defined(_USE_QT) class CSP_Logger; @@ -65,13 +67,13 @@ class DEVICE { protected: VM_TEMPLATE* vm; - EMU* emu; - OSD* osd; + EMU_TEMPLATE* emu; + OSD_BASE* osd; #if defined(_USE_QT) CSP_Logger *p_logger; #endif public: - DEVICE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : vm(parent_vm), emu(parent_emu) + DEVICE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : vm(parent_vm), emu(parent_emu) { #if defined(_USE_QT) osd = emu->get_osd(); @@ -133,7 +135,7 @@ class DEVICE } return event_manager->is_sound_in_source_exists(bank); } - virtual int increment_sound_in_passed_data(int bank, double passed_usec) { + virtual int __FASTCALL increment_sound_in_passed_data(int bank, double passed_usec) { if(event_manager == NULL) { return 0; } @@ -145,26 +147,26 @@ class DEVICE } return event_manager->get_sound_in_buffers_count(); } - virtual int get_sound_in_samples(int bank) { + virtual int __FASTCALL get_sound_in_samples(int bank) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; } return event_manager->get_sound_in_samples(bank); } - virtual int get_sound_in_rate(int bank) { + virtual int __FASTCALL get_sound_in_rate(int bank) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; } return event_manager->get_sound_in_rate(bank); } - virtual int get_sound_in_channels(int bank) { + virtual int __FASTCALL get_sound_in_channels(int bank) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; } return event_manager->get_sound_in_channels(bank); } // this function may be before (or after) initialize(). - virtual int16_t* get_sound_in_buf_ptr(int bank) { + virtual int16_t* __FASTCALL get_sound_in_buf_ptr(int bank) { if(event_manager == NULL) return NULL; return event_manager->get_sound_in_buf_ptr(bank); } @@ -177,11 +179,11 @@ class DEVICE } // Add sampled values to sample buffer;value may be -32768 to +32767. // this function may be before (or after) initialize(). - virtual int get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels) { + virtual int __FASTCALL get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels) { if(event_manager == NULL) return 0; return event_manager->get_sound_in_latest_data(bank, dst, expect_channels); } - virtual int get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels) { + virtual int __FASTCALL get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels) { if(event_manager == NULL) return -1; return event_manager->get_sound_in_data(bank, dst, expect_samples, expect_rate, expect_channels); } @@ -197,7 +199,7 @@ class DEVICE } // control virtual void reset() {} - virtual void special_reset() + virtual void special_reset(int num) { reset(); } @@ -223,25 +225,41 @@ class DEVICE } virtual void __FASTCALL write_data16(uint32_t addr, uint32_t data) { - write_data8(addr, data & 0xff); + write_data8(addr, (data ) & 0xff); write_data8(addr + 1, (data >> 8) & 0xff); } virtual uint32_t __FASTCALL read_data16(uint32_t addr) { - uint32_t val = read_data8(addr); + uint32_t val; + val = read_data8(addr ); val |= read_data8(addr + 1) << 8; return val; } virtual void __FASTCALL write_data32(uint32_t addr, uint32_t data) { - write_data16(addr, data & 0xffff); - write_data16(addr + 2, (data >> 16) & 0xffff); + if(!(addr & 1)) { + write_data16(addr, (data ) & 0xffff); + write_data16(addr + 2, (data >> 16) & 0xffff); + } else { + write_data8 (addr, (data ) & 0x00ff); + write_data16(addr + 1, (data >> 8) & 0xffff); + write_data8 (addr + 3, (data >> 24) & 0x00ff); + } } virtual uint32_t __FASTCALL read_data32(uint32_t addr) { - uint32_t val = read_data16(addr); - val |= read_data16(addr + 2) << 16; - return val; + if(!(addr & 1)) { + uint32_t val; + val = read_data16(addr ); + val |= read_data16(addr + 2) << 16; + return val; + } else { + uint32_t val; + val = read_data8 (addr ); + val |= read_data16(addr + 1) << 8; + val |= read_data8 (addr + 3) << 24; + return val; + } } virtual void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait) { @@ -255,33 +273,53 @@ class DEVICE } virtual void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_data8w(addr, data & 0xff, &wait_l); - write_data8w(addr + 1, (data >> 8) & 0xff, &wait_h); - *wait = wait_l + wait_h; + int wait_0, wait_1; + write_data8w(addr, (data ) & 0xff, &wait_0); + write_data8w(addr + 1, (data >> 8) & 0xff, &wait_1); + *wait = wait_0 + wait_1; } virtual uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_data8w(addr, &wait_l); - val |= read_data8w(addr + 1, &wait_h) << 8; - *wait = wait_l + wait_h; + int wait_0, wait_1; + uint32_t val; + val = read_data8w(addr, &wait_0); + val |= read_data8w(addr + 1, &wait_1) << 8; + *wait = wait_0 + wait_1; return val; } virtual void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_data16w(addr, data & 0xffff, &wait_l); - write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_h); - *wait = wait_l + wait_h; + if(!(addr & 1)) { + int wait_0, wait_1; + write_data16w(addr, (data ) & 0xffff, &wait_0); + write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_1); + *wait = wait_0 + wait_1; + } else { + int wait_0, wait_1, wait_2; + write_data8w (addr, (data ) & 0x00ff, &wait_0); + write_data16w(addr + 1, (data >> 8) & 0xffff, &wait_1); + write_data8w (addr + 3, (data >> 24) & 0x00ff, &wait_2); + *wait = wait_0 + wait_1 + wait_2; + } } virtual uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_data16w(addr, &wait_l); - val |= read_data16w(addr + 2, &wait_h) << 16; - *wait = wait_l + wait_h; - return val; + if(!(addr & 1)) { + int wait_0, wait_1; + uint32_t val; + val = read_data16w(addr, &wait_0); + val |= read_data16w(addr + 2, &wait_1) << 16; + *wait = wait_0 + wait_1; + return val; + } else { + int wait_0, wait_1, wait_2; + uint32_t val; + val = read_data8w (addr, &wait_0); + val |= read_data16w(addr + 1, &wait_1) << 8; + val |= read_data8w (addr + 3, &wait_2) << 24; + *wait = wait_0 + wait_1 + wait_2; + return val; + } } virtual uint32_t __FASTCALL fetch_op(uint32_t addr, int *wait) { @@ -348,25 +386,41 @@ class DEVICE } virtual void __FASTCALL write_io16(uint32_t addr, uint32_t data) { - write_io8(addr, data & 0xff); + write_io8(addr , (data ) & 0xff); write_io8(addr + 1, (data >> 8) & 0xff); } virtual uint32_t __FASTCALL read_io16(uint32_t addr) { - uint32_t val = read_io8(addr); + uint32_t val; + val = read_io8(addr ); val |= read_io8(addr + 1) << 8; return val; } virtual void __FASTCALL write_io32(uint32_t addr, uint32_t data) { - write_io16(addr, data & 0xffff); - write_io16(addr + 2, (data >> 16) & 0xffff); + if(!(addr & 1)) { + write_io16(addr, (data ) & 0xffff); + write_io16(addr + 2, (data >> 16) & 0xffff); + } else { + write_io8 (addr, (data ) & 0x00ff); + write_io16(addr + 1, (data >> 8) & 0xffff); + write_io8 (addr + 3, (data >> 24) & 0x00ff); + } } virtual uint32_t __FASTCALL read_io32(uint32_t addr) { - uint32_t val = read_io16(addr); - val |= read_io16(addr + 2) << 16; - return val; + if(!(addr & 1)) { + uint32_t val; + val = read_io16(addr ); + val |= read_io16(addr + 2) << 16; + return val; + } else { + uint32_t val; + val = read_io8 (addr ); + val |= read_io16(addr + 1) << 8; + val |= read_io8 (addr + 3) << 24; + return val; + } } virtual void __FASTCALL write_io8w(uint32_t addr, uint32_t data, int* wait) { @@ -380,33 +434,53 @@ class DEVICE } virtual void __FASTCALL write_io16w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_io8w(addr, data & 0xff, &wait_l); - write_io8w(addr + 1, (data >> 8) & 0xff, &wait_h); - *wait = wait_l + wait_h; + int wait_0, wait_1; + write_io8w(addr, (data ) & 0xff, &wait_0); + write_io8w(addr + 1, (data >> 8) & 0xff, &wait_1); + *wait = wait_0 + wait_1; } virtual uint32_t __FASTCALL read_io16w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_io8w(addr, &wait_l); - val |= read_io8w(addr + 1, &wait_h) << 8; - *wait = wait_l + wait_h; + int wait_0, wait_1; + uint32_t val; + val = read_io8w(addr, &wait_0); + val |= read_io8w(addr + 1, &wait_1) << 8; + *wait = wait_0 + wait_1; return val; } virtual void __FASTCALL write_io32w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_io16w(addr, data & 0xffff, &wait_l); - write_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h); - *wait = wait_l + wait_h; + if(!(addr & 1)) { + int wait_0, wait_1; + write_io16w(addr, (data ) & 0xffff, &wait_0); + write_io16w(addr + 2, (data >> 16) & 0xffff, &wait_1); + *wait = wait_0 + wait_1; + } else { + int wait_0, wait_1, wait_2; + write_io8w (addr, (data ) & 0x00ff, &wait_0); + write_io16w(addr + 1, (data >> 8) & 0xffff, &wait_1); + write_io8w (addr + 3, (data >> 24) & 0x00ff, &wait_2); + *wait = wait_0 + wait_1 + wait_2; + } } virtual uint32_t __FASTCALL read_io32w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_io16w(addr, &wait_l); - val |= read_io16w(addr + 2, &wait_h) << 16; - *wait = wait_l + wait_h; - return val; + if(!(addr & 1)) { + int wait_0, wait_1; + uint32_t val; + val = read_io16w(addr, &wait_0); + val |= read_io16w(addr + 2, &wait_1) << 16; + *wait = wait_0 + wait_1; + return val; + } else { + int wait_0, wait_1, wait_2; + uint32_t val; + val = read_io8w (addr, &wait_0); + val |= read_io16w(addr + 1, &wait_1) << 8; + val |= read_io8w (addr + 3, &wait_2) << 24; + *wait = wait_0 + wait_1 + wait_2; + return val; + } } virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data) { @@ -468,25 +542,41 @@ class DEVICE } virtual void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data) { - write_memory_mapped_io8(addr, data & 0xff); + write_memory_mapped_io8(addr, (data ) & 0xff); write_memory_mapped_io8(addr + 1, (data >> 8) & 0xff); } virtual uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr) { - uint32_t val = read_memory_mapped_io8(addr); + uint32_t val; + val = read_memory_mapped_io8(addr ); val |= read_memory_mapped_io8(addr + 1) << 8; return val; } virtual void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data) { - write_memory_mapped_io16(addr, data & 0xffff); - write_memory_mapped_io16(addr + 2, (data >> 16) & 0xffff); + if(!(addr & 1)) { + write_memory_mapped_io16(addr, (data ) & 0xffff); + write_memory_mapped_io16(addr + 2, (data >> 16) & 0xffff); + } else { + write_memory_mapped_io8 (addr, (data ) & 0x00ff); + write_memory_mapped_io16(addr + 1, (data >> 8) & 0xffff); + write_memory_mapped_io8 (addr + 3, (data >> 24) & 0x00ff); + } } virtual uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr) { - uint32_t val = read_memory_mapped_io16(addr); - val |= read_memory_mapped_io16(addr + 2) << 16; - return val; + if(!(addr & 1)) { + uint32_t val; + val = read_memory_mapped_io16(addr ); + val |= read_memory_mapped_io16(addr + 2) << 16; + return val; + } else { + uint32_t val; + val = read_memory_mapped_io8 (addr ); + val |= read_memory_mapped_io16(addr + 1) << 8; + val |= read_memory_mapped_io8 (addr + 3) << 24; + return val; + } } virtual void __FASTCALL write_memory_mapped_io8w(uint32_t addr, uint32_t data, int* wait) { @@ -500,33 +590,53 @@ class DEVICE } virtual void __FASTCALL write_memory_mapped_io16w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_memory_mapped_io8w(addr, data & 0xff, &wait_l); - write_memory_mapped_io8w(addr + 1, (data >> 8) & 0xff, &wait_h); - *wait = wait_l + wait_h; + int wait_0, wait_1; + write_memory_mapped_io8w(addr, (data ) & 0xff, &wait_0); + write_memory_mapped_io8w(addr + 1, (data >> 8) & 0xff, &wait_1); + *wait = wait_0 + wait_1; } virtual uint32_t __FASTCALL read_memory_mapped_io16w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_memory_mapped_io8w(addr, &wait_l); - val |= read_memory_mapped_io8w(addr + 1, &wait_h) << 8; - *wait = wait_l + wait_h; + int wait_0, wait_1; + uint32_t val; + val = read_memory_mapped_io8w(addr, &wait_0); + val |= read_memory_mapped_io8w(addr + 1, &wait_1) << 8; + *wait = wait_0 + wait_1; return val; } virtual void __FASTCALL write_memory_mapped_io32w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_memory_mapped_io16w(addr, data & 0xffff, &wait_l); - write_memory_mapped_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h); - *wait = wait_l + wait_h; + if(!(addr & 1)) { + int wait_0, wait_1; + write_memory_mapped_io16w(addr, (data ) & 0xffff, &wait_0); + write_memory_mapped_io16w(addr + 2, (data >> 16) & 0xffff, &wait_1); + *wait = wait_0 + wait_1; + } else { + int wait_0, wait_1, wait_2; + write_memory_mapped_io8w (addr, (data ) & 0x00ff, &wait_0); + write_memory_mapped_io16w(addr + 1, (data >> 8) & 0xffff, &wait_1); + write_memory_mapped_io8w (addr + 3, (data >> 24) & 0x00ff, &wait_2); + *wait = wait_0 + wait_1 + wait_2; + } } virtual uint32_t __FASTCALL read_memory_mapped_io32w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_memory_mapped_io16w(addr, &wait_l); - val |= read_memory_mapped_io16w(addr + 2, &wait_h) << 16; - *wait = wait_l + wait_h; - return val; + if(!(addr & 1)) { + int wait_0, wait_1; + uint32_t val; + val = read_memory_mapped_io16w(addr, &wait_0); + val |= read_memory_mapped_io16w(addr + 2, &wait_1) << 16; + *wait = wait_0 + wait_1; + return val; + } else { + int wait_0, wait_1, wait_2; + uint32_t val; + val = read_memory_mapped_io8w (addr, &wait_0); + val |= read_memory_mapped_io16w(addr + 1, &wait_1) << 8; + val |= read_memory_mapped_io8w (addr + 3, &wait_2) << 24; + *wait = wait_0 + wait_1 + wait_2; + return val; + } } // device to device @@ -572,6 +682,19 @@ class DEVICE item->device->write_signal(item->id, val, mask); } }; + virtual void update_signal_mask(outputs_t *items, DEVICE *device, uint32_t mask) + { + if(items == NULL) return; + int c = items->count; + if(c <= 0) return; + if(c >= MAX_OUTPUT) c = MAX_OUTPUT - 1; + // if (ARG:device == NULL) apply to all devices. + for(int i = 0; i < c; i++) { + if((device == NULL) || (device == items->item[i].device)) { + items->item[i].mask = mask; + } + } + } virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask) {} virtual uint32_t __FASTCALL read_signal(int ch) { @@ -587,16 +710,17 @@ class DEVICE } // interrupt device to device - virtual void set_intr_iei(bool val) {} + virtual void __FASTCALL set_intr_iei(bool val) {} // interrupt device to cpu - virtual void set_intr_line(bool line, bool pending, uint32_t bit) {} + virtual void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit) {} // interrupt cpu to device virtual uint32_t get_intr_ack() { return 0xff; } + virtual void update_intr() {} virtual void notify_intr_reti() {} virtual void notify_intr_ei() {} @@ -609,7 +733,7 @@ class DEVICE // when clock == -1, run one opecode return (clock == -1 ? 1 : clock); } - virtual void set_extra_clock(int clock) {} + virtual void __FASTCALL set_extra_clock(int clock) {} virtual int get_extra_clock() { return 0; @@ -624,15 +748,15 @@ class DEVICE } // bios - virtual bool bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) + virtual bool bios_call_far_i86(uint32_t PC, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { return false; } - virtual bool bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) + virtual bool bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { return false; } - virtual bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) + virtual bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { return false; } @@ -664,6 +788,13 @@ class DEVICE } return event_manager->this_device_id; } + virtual uint32_t get_event_clocks() + { + if(event_manager == NULL) { + event_manager = vm->first_device->next_device; + } + return event_manager->get_event_clocks(); + } virtual bool is_primary_cpu(DEVICE* device) { if(event_manager == NULL) { @@ -671,7 +802,14 @@ class DEVICE } return event_manager->is_primary_cpu(device); } - virtual void update_extra_event(int clock) + virtual uint32_t get_cpu_clocks(DEVICE* device) + { + if(event_manager == NULL) { + event_manager = vm->first_device->next_device; + } + return event_manager->get_cpu_clocks(device); + } + virtual void __FASTCALL update_extra_event(int clock) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; @@ -699,6 +837,39 @@ class DEVICE } event_manager->cancel_event(device, register_id); } + // Clear and DE-Register EVENT at slot evid. + virtual void clear_event(DEVICE* dev, int& evid) + { + if(evid > -1) { + cancel_event(dev, evid); + } + evid = -1; + } + // Register a EVENT to evid (and update evid) , even if evid's slot is used. + virtual void force_register_event(DEVICE* dev, int event_num, double usec, bool loop, int& evid) + { + clear_event(dev, evid); + register_event(dev, event_num, usec, loop, &evid); + } + virtual void force_register_event_by_clock(DEVICE* dev, int event_num, uint64_t clock, bool loop, int& evid) + { + clear_event(dev, evid); + register_event_by_clock(dev, event_num, clock, loop, &evid); + } + + // Register a EVENT to evid , if evid slot isn't used. + virtual void check_and_update_event(DEVICE* dev, int event_num, double usec, bool loop, int& evid) + { + if(evid > -1) return; + register_event(dev, event_num, usec, loop, &evid); + } + virtual void check_and_update_event_by_clock(DEVICE* dev, int event_num, uint64_t clock, bool loop, int& evid) + { + if(evid > -1) return; + register_event_by_clock(dev, event_num, clock, loop, &evid); + } + + virtual void register_frame_event(DEVICE* device) { if(event_manager == NULL) { @@ -713,14 +884,14 @@ class DEVICE } event_manager->register_vline_event(device); } - virtual uint32_t get_event_remaining_clock(int register_id) + virtual uint32_t __FASTCALL get_event_remaining_clock(int register_id) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; } return event_manager->get_event_remaining_clock(register_id); } - virtual double get_event_remaining_usec(int register_id) + virtual double __FASTCALL get_event_remaining_usec(int register_id) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; @@ -734,14 +905,14 @@ class DEVICE } return event_manager->get_current_clock(); } - virtual uint32_t get_passed_clock(uint32_t prev) + virtual uint32_t __FASTCALL get_passed_clock(uint32_t prev) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; } return event_manager->get_passed_clock(prev); } - virtual double get_passed_usec(uint32_t prev) + virtual double __FASTCALL get_passed_usec(uint32_t prev) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; @@ -776,7 +947,7 @@ class DEVICE } return event_manager->get_cur_vline_clocks(); } - virtual uint32_t get_cpu_pc(int index) + virtual uint32_t __FASTCALL get_cpu_pc(int index) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; @@ -790,7 +961,7 @@ class DEVICE } return event_manager->get_current_clock_uint64(); } - virtual uint32_t get_cpu_clock(int index) + virtual uint32_t __FASTCALL get_cpu_clock(int index) { if(event_manager == NULL) { event_manager = vm->first_device->next_device; @@ -854,14 +1025,14 @@ class DEVICE virtual void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) {} // event callback - virtual void event_callback(int event_id, int err) {} + virtual void __FASTCALL event_callback(int event_id, int err) {} virtual void event_pre_frame() {} // this event is to update timing settings virtual void event_frame() {} virtual void event_vline(int v, int clock) {} virtual void event_hsync(int v, int h, int clock) {} // sound - virtual void mix(int32_t* buffer, int cnt) {} + virtual void __FASTCALL mix(int32_t* buffer, int cnt) {} virtual void set_volume(int ch, int decibel_l, int decibel_r) {} // +1 equals +0.5dB (same as fmgen) virtual void set_device_name(const _TCHAR *format, ...) { @@ -968,6 +1139,28 @@ class DEVICE emu->out_debug_log("%s", strbuf); va_end(ap); } + virtual void DEVICE::out_debug_log_with_switch(bool logging, const char *fmt, ...) + { + if(!(logging)) return; +#if defined(_USE_QT) + if(p_logger == NULL) return; + char strbuf[4096]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(strbuf, 4095, fmt, ap); + p_logger->debug_log(CSP_LOG_DEBUG, this_device_id + CSP_LOG_TYPE_VM_DEVICE_0, "%s", strbuf); + va_end(ap); +#else + char strbuf[4096]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(strbuf, 4095, fmt, ap); + emu->out_debug_log("%s", strbuf); + va_end(ap); +#endif + } virtual void force_out_debug_log(const char *fmt, ...) { char strbuf[4096]; @@ -1084,6 +1277,10 @@ class DEVICE { return false; } + virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len) + { + return false; + } virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) { return debug_dasm_with_userdata(pc, buffer, buffer_len, 0); @@ -1092,6 +1289,11 @@ class DEVICE { return 0; } + virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0) + { + size = 0; + return false; + } #endif _TCHAR this_device_name[128]; diff --git a/source/src/vm/disk.cpp b/source/src/vm/disk.cpp index ededa0400..ac1be2888 100644 --- a/source/src/vm/disk.cpp +++ b/source/src/vm/disk.cpp @@ -8,7 +8,7 @@ */ #ifndef _ANY2D88 -#include "../emu.h" +#include "../emu_template.h" #endif #include "disk.h" diff --git a/source/src/vm/disk.h b/source/src/vm/disk.h index 6359a345d..ed01f7461 100644 --- a/source/src/vm/disk.h +++ b/source/src/vm/disk.h @@ -58,12 +58,12 @@ typedef struct { class CSP_Logger; class FILEIO; class OSD; -class DISK +class DLL_PREFIX DISK { #ifndef _ANY2D88 protected: - EMU* emu; - OSD* osd; + EMU_TEMPLATE* emu; + OSD_BASE* osd; #endif private: uint8_t buffer[DISK_BUFFER_SIZE + TRACK_BUFFER_SIZE]; @@ -127,7 +127,7 @@ class DISK public: #ifndef _ANY2D88 - DISK(EMU* parent_emu) : emu(parent_emu) + DISK(EMU_TEMPLATE* parent_emu) : emu(parent_emu) #else DISK() #endif diff --git a/source/src/vm/event.cpp b/source/src/vm/event.cpp index 6e06c2015..e4c2449fd 100644 --- a/source/src/vm/event.cpp +++ b/source/src/vm/event.cpp @@ -11,85 +11,8 @@ * BELOW INCLUDES ARE for run_cpu(). * ToDo: Minimum include. */ -#include "vm.h" - -#if defined(USE_CPU_HD6301) -#include "hd6301.h" -#endif - -#if defined(USE_CPU_HUC6280) -#include "huc6280.h" -#endif - -#if defined(USE_CPU_I86) || defined(USE_CPU_I186) || defined(USE_CPU_I88) -#include "i86.h" -#endif - -#if defined(USE_CPU_V30) -#include "v30.h" -#endif - -#if defined(USE_CPU_I286) -#if defined(_JX) -#include "jx/i286.h" -#else -#include "i286.h" -#endif -#endif - -#if defined(USE_CPU_I386) || defined(USE_CPU_I486) || defined(USE_CPU_PENTIUM) -#include "i386.h" -#endif - -#if defined(USE_CPU_I8080) -#include "i8080.h" -#endif - -#if defined(USE_CPU_M6502) || defined(USE_CPU_N2A03) -#include "m6502.h" -#endif - -#if defined(USE_CPU_MB8861) -#include "mb8861.h" -#endif - -#if defined(USE_CPU_MC6800) -#include "mc6800.h" -#endif - -#if defined(USE_CPU_MC6801) -#include "mc6801.h" -#endif - -#if defined(USE_CPU_MC6809) -#include "mc6809.h" -#endif - -#if defined(USE_CPU_MCS48) -#include "mcs48.h" -#endif - -#if defined(USE_CPU_TMS9995) -#include "tms9995.h" -#endif - -#if defined(USE_CPU_UPD7801) -#include "upd7801.h" -#endif - -#if defined(USE_CPU_UPD7810) -#include "upd7810.h" -#endif - -#if defined(USE_CPU_UPD7907) -#include "upd7907.h" -#endif - -#if defined(USE_CPU_Z80) -#include "z80.h" -#endif - #include "event.h" +#include "vm.h" #define EVENT_MIX 0 #define EVENT_VLINE 1 @@ -240,143 +163,15 @@ void EVENT::reset() memset(sound_tmp, 0, sound_tmp_samples * sizeof(int32_t) * 2); } // buffer_ptr = 0; - + event_half = false; #ifdef _DEBUG_LOG initialize_done = true; #endif } -#define RUN_CPU_N(num, _class, arg) \ - return static_cast<_class *>(d_cpu[num].device)->run(arg) - -#define RUN_CPU_GENERIC(num, arg) \ - return d_cpu[num].device->run(arg) - - -int __FASTCALL EVENT::run_cpu(uint32_t num, int cycles) -{ -#if defined(USE_SUPRESS_VTABLE) - if(num < MAX_CPU) { - uint32_t dom_num = cpu_type[num]; - switch(dom_num) { -#if defined(USE_CPU_HD6301) - case EVENT_CPUTYPE_HD6301: - RUN_CPU_N(num, HD6301, cycles); - break; -#endif -#if defined(USE_CPU_HUC6280) - case EVENT_CPUTYPE_HUC6280: - RUN_CPU_N(num, HUC6280, cycles); - break; -#endif -#if defined(USE_CPU_V30) - case EVENT_CPUTYPE_V30: - RUN_CPU_N(num, V30, cycles); - break; -#endif -#if defined(USE_CPU_I286) - case EVENT_CPUTYPE_I286: - #if defined(_JX) - RUN_CPU_N(num, JX::I286, cycles); - #else - RUN_CPU_N(num, I80286, cycles); - #endif - break; -#endif -#if defined(USE_CPU_I86) || defined(USE_CPU_I186) || defined(USE_CPU_I88) - case EVENT_CPUTYPE_I86: - RUN_CPU_N(num, I8086, cycles); - break; -#endif -#if defined(USE_CPU_I386) - case EVENT_CPUTYPE_I386: - RUN_CPU_N(num, I386, cycles); - break; -#endif -#if defined(USE_CPU_I8080) - case EVENT_CPUTYPE_I8080: - RUN_CPU_N(num, I8080, cycles); - break; -#endif -#if defined(USE_CPU_M6502) - case EVENT_CPUTYPE_M6502: - RUN_CPU_N(num, M6502, cycles); - break; -#endif -#if defined(USE_CPU_N2A03) - case EVENT_CPUTYPE_N2A03: - RUN_CPU_N(num, N2A03, cycles); - break; -#endif -#if defined(USE_CPU_MB8861) - case EVENT_CPUTYPE_MB8861: - RUN_CPU_N(num, MB8861, cycles); - break; -#endif -#if defined(USE_CPU_MC6800) - case EVENT_CPUTYPE_MC6800: - RUN_CPU_N(num, MC6800, cycles); - break; -#endif -#if defined(USE_CPU_MC6801) - case EVENT_CPUTYPE_MC6801: - RUN_CPU_N(num, MC6801, cycles); - break; -#endif -#if defined(USE_CPU_MC6809) - case EVENT_CPUTYPE_MC6809: - RUN_CPU_N(num, MC6809, cycles); - break; -#endif -#if defined(USE_CPU_MCS48) - case EVENT_CPUTYPE_MCS48: - RUN_CPU_N(num, MCS48, cycles); - break; -#endif -#if defined(USE_CPU_TMS9995) - case EVENT_CPUTYPE_TMS9995: - RUN_CPU_N(num, TMS9995, cycles); - break; -#endif -#if defined(USE_CPU_UPD7801) - case EVENT_CPUTYPE_UPD7801: - RUN_CPU_N(num, UPD7801, cycles); - break; -#endif -#if defined(USE_CPU_UPD7907) - case EVENT_CPUTYPE_UPD7907: - RUN_CPU_N(num, UPD7907, cycles); - break; -#endif -#if defined(USE_CPU_UPD7810) - case EVENT_CPUTYPE_UPD7810: - RUN_CPU_N(num, UPD7810, cycles); - break; -#endif -#if defined(USE_CPU_Z80) - case EVENT_CPUTYPE_Z80: - RUN_CPU_N(num, Z80, cycles); - break; -#endif - case EVENT_CPUTYPE_GENERIC: - default: - RUN_CPU_GENERIC(num, cycles); - break; - } - } -#endif - if(cycles <= 0) { - return 1; - } else { - return cycles; - } - - -} - -//#define USE_SUPRESS_VTABLE void EVENT::drive() { + if(event_half) goto skip1; // raise pre frame events to update timing settings for(int i = 0; i < frame_event_count; i++) { frame_event[i]->event_pre_frame(); @@ -402,6 +197,7 @@ void EVENT::drive() } for(int i = 1; i < dcount_cpu; i++) { d_cpu[i].update_clocks = (int)(1024.0 * (double)d_cpu[i].cpu_clocks / (double)d_cpu[0].cpu_clocks + 0.5); + //d_cpu[i].update_clocks = (int)(4096.0 * (double)d_cpu[i].cpu_clocks / (double)d_cpu[0].cpu_clocks + 0.5); } for(DEVICE* device = vm->first_device; device; device = device->next_device) { if(device->get_event_manager_id() == this_device_id) { @@ -409,7 +205,7 @@ void EVENT::drive() } } } - + // run virtual machine for 1 frame period for(int i = 0; i < frame_event_count; i++) { frame_event[i]->event_frame(); @@ -430,8 +226,18 @@ void EVENT::drive() update_event(-event_remain); } } - event_remain += frame_clocks; - cpu_remain += frame_clocks << power; +skip1: + int _fclocks; + if(event_half) { + _fclocks = frame_clocks - (frame_clocks / 2); + } else { + _fclocks = frame_clocks / 2; + } + event_half = !(event_half); +// event_remain += frame_clocks; +// cpu_remain += frame_clocks << power; + event_remain += _fclocks; + cpu_remain += _fclocks << power; while(event_remain > 0) { int event_done = event_remain; @@ -440,36 +246,62 @@ void EVENT::drive() int cpu_done_tmp; if(dcount_cpu == 1) { // run one opecode on primary cpu +// cpu_done_tmp = d_cpu[0].device->run(-1); cpu_done_tmp = d_cpu[0].device->run(-1); } else { // sync to sub cpus if(cpu_done == 0) { // run one opecode on primary cpu -#if !defined(USE_SUPRESS_VTABLE) cpu_done = d_cpu[0].device->run(-1); -#else - cpu_done = run_cpu(0, -1); -#endif } // sub cpu runs continuously and no events will be fired while the given clocks, // so I need to give small enough clocks... +#if 1 +// cpu_done_tmp = (event_extra > 0 || cpu_done < 256) ? cpu_done : 256; +// cpu_done -= cpu_done_tmp; + cpu_done_tmp = cpu_done; + cpu_done = 0; ; + for(int i = 1; i < dcount_cpu; i++) { + // run sub cpus + int clock_result = d_cpu[i].update_clocks * cpu_done_tmp; + int sub_clock = 0; + int sub_clock2 = 0; + if(clock_result > 0) { + if(clock_result >= 0x400) { // OVER 1 clocks with HOST, to reduce risk of overflow@accum_clocks. + // Upper clocks are not to need to add accum_clocks, + // accum_clocks may be effected by lower value of clock_result, + // *excepts multiply value (of adding value to accum_clocks) isn't 2^x*. + // 20191013 K.O + sub_clock = (int)(clock_result >> 10); + // Update only execution clocks (executing later) + //d_cpu[i].device->run(sub_clock); // Execute over 1 host clocks. + clock_result -= (sub_clock << 10); + } + d_cpu[i].accum_clocks += clock_result; // At most, 1 host clocks.Guranteed maximum at 1 host clocks. + sub_clock2 = (int)(d_cpu[i].accum_clocks >> 10); + sub_clock += sub_clock2; + if(sub_clock > 0) { + d_cpu[i].accum_clocks -= sub_clock2 << 10; + d_cpu[i].device->run(sub_clock); + } + } + } +#else cpu_done_tmp = (event_extra > 0 || cpu_done < 4) ? cpu_done : 4; cpu_done -= cpu_done_tmp; - for(int i = 1; i < dcount_cpu; i++) { // run sub cpus - d_cpu[i].accum_clocks += d_cpu[i].update_clocks * cpu_done_tmp; - int sub_clock = d_cpu[i].accum_clocks >> 10; - if(sub_clock) { + int clock_result = d_cpu[i].update_clocks * cpu_done_tmp; + int sub_clock; + d_cpu[i].accum_clocks += clock_result; // At most, 16 host clocks.Guranteed maximum at 16 host clocks. + sub_clock = (int)(d_cpu[i].accum_clocks >> 10); + if(sub_clock > 0) { d_cpu[i].accum_clocks -= sub_clock << 10; -#if !defined(USE_SUPRESS_VTABLE) d_cpu[i].device->run(sub_clock); -#else - run_cpu(i, sub_clock); -#endif } } +#endif } cpu_remain -= cpu_done_tmp; cpu_accum += cpu_done_tmp; @@ -547,6 +379,15 @@ uint64_t EVENT::get_current_clock_uint64() return event_clocks; } +double EVENT::get_current_usec() +{ + double clock = (double)(d_cpu[0].cpu_clocks); + if(clock <= 0.0) return 0.0; + + double usec = ((double)event_clocks / clock) * 1.0e6; + return usec; +} + uint32_t EVENT::get_cpu_clock(int index) { if((index < 0) || (index >= MAX_CPU)) return 0; @@ -888,7 +729,7 @@ uint16_t* EVENT::create_sound(int* extra_frames) // drive extra frames to fill the sound buffer while(sound_samples > buffer_ptr) { drive(); - frames++; + if(!(event_half)) frames++; } #ifdef LOW_PASS_FILTER // low-pass filter @@ -1297,7 +1138,8 @@ void EVENT::update_config() } } -#define STATE_VERSION 4 +// Revert clock ratio to 1024 (2^10).STATE_VERSION to 4; 20191013 K.O +#define STATE_VERSION 5 bool EVENT::process_state(FILEIO* state_fio, bool loading) { @@ -1355,6 +1197,7 @@ bool EVENT::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(next_lines_per_frame); state_fio->StateArray(dev_need_mix, sizeof(dev_need_mix), 1); state_fio->StateValue(need_mix); + state_fio->StateValue(event_half); // post process if(loading) { diff --git a/source/src/vm/event.h b/source/src/vm/event.h index dd10d94c5..2b21af45f 100644 --- a/source/src/vm/event.h +++ b/source/src/vm/event.h @@ -10,8 +10,9 @@ #ifndef _EVENT_H_ #define _EVENT_H_ -#include "vm.h" -#include "../emu.h" +//#include "vm_template.h" +//#include "../emu_template.h" +#include "./vm.h" #include "device.h" #include @@ -30,29 +31,6 @@ #endif #endif -enum { - EVENT_CPUTYPE_GENERIC = 0, - EVENT_CPUTYPE_HD6301, - EVENT_CPUTYPE_HUC6280, - EVENT_CPUTYPE_I286, - EVENT_CPUTYPE_I386, - EVENT_CPUTYPE_I8080, - EVENT_CPUTYPE_M6502, - EVENT_CPUTYPE_N2A03, - EVENT_CPUTYPE_MB8861, - EVENT_CPUTYPE_MC6800, - EVENT_CPUTYPE_MC6801, - EVENT_CPUTYPE_MC6809, - EVENT_CPUTYPE_MCS48, - EVENT_CPUTYPE_TMS9995, - EVENT_CPUTYPE_UPD7801, - EVENT_CPUTYPE_Z80, - EVENT_CPUTYPE_I86, - EVENT_CPUTYPE_V30, - EVENT_CPUTYPE_UPD7810, - EVENT_CPUTYPE_UPD7907, -}; - class EVENT : public DEVICE { @@ -67,10 +45,9 @@ class EVENT : public DEVICE cpu_t d_cpu[MAX_CPU]; uint32_t cpu_update_clocks[MAX_CPU][6]; - uint32_t cpu_type[MAX_CPU]; - int dcount_cpu; - + + bool event_half; int frame_clocks; int vline_clocks[MAX_LINES]; int power; @@ -134,127 +111,14 @@ class EVENT : public DEVICE bool dev_need_mix[MAX_DEVICE]; int need_mix; - void mix_sound(int samples); - void* get_event(int index); - int __FASTCALL run_cpu(uint32_t num, int cycles); + void __FASTCALL mix_sound(int samples); + void* __FASTCALL get_event(int index); #ifdef _DEBUG_LOG bool initialize_done; #endif - template - void set_cpu_type(T *p, int num) - { -#if defined(USE_SUPRESS_VTABLE) - if((num < 0) || (num >= MAX_CPU)) return; -#if defined(USE_CPU_HD6301) - if(typeid(T) == typeid(HD6301)) { - cpu_type[num] = EVENT_CPUTYPE_HD6301; - } else -#endif -#if defined(USE_CPU_HUC6280) - if(typeid(T) == typeid(HUC6280)) { - cpu_type[num] = EVENT_CPUTYPE_HUC6280; - } else -#endif -#if defined(USE_CPU_I86) || defined(USE_CPU_I186) || defined(USE_CPU_I88) - if(typeid(T) == typeid(I8086)) { - cpu_type[num] = EVENT_CPUTYPE_I86; - } else -#endif -#if defined(USE_CPU_V30) - if(typeid(T) == typeid(V30)) { - cpu_type[num] = EVENT_CPUTYPE_V30; - } else -#endif - -#if defined(USE_CPU_I286) - #if defined(_JX) - if(typeid(T) == typeid(JX::I286)) { - cpu_type[num] = EVENT_CPUTYPE_I286; - } else - #else - if(typeid(T) == typeid(I80286)) { - cpu_type[num] = EVENT_CPUTYPE_I286; - } else - #endif -#endif -#if defined(USE_CPU_I386) || defined(USE_CPU_I486) || defined(USE_CPU_PENTIUM) - if(typeid(T) == typeid(I386)) { - cpu_type[num] = EVENT_CPUTYPE_I386; - } else -#endif -#if defined(USE_CPU_I8080) - if(typeid(T) == typeid(I8080)) { - cpu_type[num] = EVENT_CPUTYPE_I8080; - } else -#endif -#if defined(USE_CPU_M6502) - if(typeid(T) == typeid(M6502)) { - cpu_type[num] = EVENT_CPUTYPE_M6502; - } else -#endif -#if defined(USE_CPU_N2A03) - if(typeid(T) == typeid(N2A03)) { - cpu_type[num] = EVENT_CPUTYPE_N2A03; - } else -#endif -#if defined(USE_CPU_MB8861) - if(typeid(T) == typeid(MB8861)) { - cpu_type[num] = EVENT_CPUTYPE_MB8861; - } else -#endif -#if defined(USE_CPU_MC6800) - if(typeid(T) == typeid(MC6800)) { - cpu_type[num] = EVENT_CPUTYPE_MC6800; - } else -#endif -#if defined(USE_CPU_MC6801) - if(typeid(T) == typeid(MC6801)) { - cpu_type[num] = EVENT_CPUTYPE_MC6801; - } else -#endif -#if defined(USE_CPU_MC6809) - if(typeid(T) == typeid(MC6809)) { - cpu_type[num] = EVENT_CPUTYPE_MC6809; - } else -#endif -#if defined(USE_CPU_MCS48) - if(typeid(T) == typeid(MCS48)) { - cpu_type[num] = EVENT_CPUTYPE_MCS48; - } else -#endif -#if defined(USE_CPU_TMS9995) - if(typeid(T) == typeid(TMS9995)) { - cpu_type[num] = EVENT_CPUTYPE_TMS9995; - } else -#endif -#if defined(USE_CPU_UPD7801) - if(typeid(T) == typeid(UPD7801)) { - cpu_type[num] = EVENT_CPUTYPE_UPD7801; - } else -#endif -#if defined(USE_CPU_UPD7810) - if(typeid(T) == typeid(UPD7810)) { - cpu_type[num] = EVENT_CPUTYPE_UPD7810; - } else -#endif -#if defined(USE_CPU_UPD7907) - if(typeid(T) == typeid(UPD7907)) { - cpu_type[num] = EVENT_CPUTYPE_UPD7907; - } else -#endif -#if defined(USE_CPU_Z80) - if(typeid(T) == typeid(Z80)) { - cpu_type[num] = EVENT_CPUTYPE_Z80; - } else -#endif - { - cpu_type[num] = EVENT_CPUTYPE_GENERIC; - } -#endif - } public: - EVENT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + EVENT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { dcount_cpu = dcount_sound = 0; frame_event_count = vline_event_count = 0; @@ -294,9 +158,6 @@ class EVENT : public DEVICE #ifdef _DEBUG_LOG initialize_done = false; #endif - for(int i = 0; i < MAX_CPU; i++) { - cpu_type[i] = EVENT_CPUTYPE_GENERIC; - } set_device_name(_T("Event Manager")); } ~EVENT() {} @@ -305,7 +166,7 @@ class EVENT : public DEVICE void initialize(); void release(); void reset(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_config(); bool process_state(FILEIO* state_fio, bool loading); @@ -314,6 +175,23 @@ class EVENT : public DEVICE { return this_device_id; } + uint32_t get_event_clocks() + { + return d_cpu[0].cpu_clocks; + } + bool is_primary_cpu(DEVICE* device) + { + return (d_cpu[0].device == device); + } + uint32_t __FASTCALL get_cpu_clocks(DEVICE* device) + { + for(int index = 0; index < dcount_cpu; index++) { + if(d_cpu[index].device == device) { + return d_cpu[index].cpu_clocks; + } + } + return CPU_CLOCKS; + } void set_frames_per_sec(double new_frames_per_sec) { next_frames_per_sec = new_frames_per_sec; @@ -328,21 +206,17 @@ class EVENT : public DEVICE { return next_lines_per_frame; } - bool is_primary_cpu(DEVICE* device) - { - return (d_cpu[0].device == device); - } - void update_extra_event(int clock); + void __FASTCALL update_extra_event(int clock); void register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id); void register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id); void cancel_event(DEVICE* device, int register_id); void register_frame_event(DEVICE* device); void register_vline_event(DEVICE* device); - uint32_t get_event_remaining_clock(int register_id); - double get_event_remaining_usec(int register_id); + uint32_t __FASTCALL get_event_remaining_clock(int register_id); + double __FASTCALL get_event_remaining_usec(int register_id); uint32_t get_current_clock(); - uint32_t get_passed_clock(uint32_t prev); - double get_passed_usec(uint32_t prev); + uint32_t __FASTCALL get_passed_clock(uint32_t prev); + double __FASTCALL get_passed_usec(uint32_t prev); uint32_t get_passed_clock_since_vline(); double get_passed_usec_since_vline(); int get_cur_vline() @@ -353,12 +227,13 @@ class EVENT : public DEVICE { return vline_clocks[cur_vline]; } - uint32_t get_cpu_pc(int index); + uint32_t __FASTCALL get_cpu_pc(int index); void request_skip_frames(); void touch_sound(); void set_realtime_render(DEVICE* device, bool flag); uint64_t get_current_clock_uint64(); - uint32_t get_cpu_clock(int index); + double get_current_usec(); + uint32_t __FASTCALL get_cpu_clock(int index); // unique functions double get_frame_rate() { @@ -367,7 +242,7 @@ class EVENT : public DEVICE void drive(); void initialize_sound(int rate, int samples); - uint16_t* create_sound(int* extra_frames); + uint16_t* __FASTCALL create_sound(int* extra_frames); int get_sound_buffer_ptr(); // Sound input functions void clear_sound_in_source(int bank); @@ -375,32 +250,29 @@ class EVENT : public DEVICE int release_sound_in_source(int bank); bool is_sound_in_source_exists(int bank); - int increment_sound_in_passed_data(int bank, double passed_usec); + int __FASTCALL increment_sound_in_passed_data(int bank, double passed_usec); int get_sound_in_buffers_count(); - int get_sound_in_samples(int bank); - int get_sound_in_rate(int bank); - int get_sound_in_channels(int bank); + int __FASTCALL get_sound_in_samples(int bank); + int __FASTCALL get_sound_in_rate(int bank); + int __FASTCALL get_sound_in_channels(int bank); int16_t* get_sound_in_buf_ptr(int bank); int write_sound_in_buffer(int bank, int32_t* src, int samples); // Add sampled values to sample buffer;value may be -32768 to +32767. - int get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels); - int get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels); + int __FASTCALL get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels); + int __FASTCALL get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels); int rechannel_sound_in_data(int32_t*dst, int16_t* src, int dst_channels, int src_channels, int samples); - template - int set_context_cpu(T* device, uint32_t clocks = CPU_CLOCKS) + int set_context_cpu(DEVICE* device, uint32_t clocks = CPU_CLOCKS) { assert(dcount_cpu < MAX_CPU); int index = dcount_cpu++; d_cpu[index].device = (DEVICE *)device; d_cpu[index].cpu_clocks = clocks; d_cpu[index].accum_clocks = 0; - set_cpu_type(device, index); for(int k = 0; k < 6; k++) cpu_update_clocks[index][k] = d_cpu[index].update_clocks * k; return index; } - template - bool remove_context_cpu(T* device, int num) + bool remove_context_cpu(DEVICE* device, int num) { if(num <= 0) return false; // Number one must not be removed. if(num >= MAX_CPU) return false; @@ -413,7 +285,6 @@ class EVENT : public DEVICE d_cpu[1].device = (DEVICE *)NULL; d_cpu[1].cpu_clocks = 0; d_cpu[1].accum_clocks = 0; - cpu_type[1] = EVENT_CPUTYPE_GENERIC; dcount_cpu = 1; for(int k = 0; k < 6; k++) cpu_update_clocks[1][k] = d_cpu[1].update_clocks * k; } else { @@ -421,13 +292,11 @@ class EVENT : public DEVICE d_cpu[i].device = d_cpu[i + 1].device; d_cpu[i].cpu_clocks = d_cpu[i + 1].cpu_clocks; d_cpu[i].accum_clocks = d_cpu[i + 1].accum_clocks; - cpu_type[i] = cpu_type[i + 1]; } int n = dcount_cpu - 1; d_cpu[n].device = (DEVICE *)NULL; d_cpu[n].cpu_clocks = 0; d_cpu[n].accum_clocks = 0; - cpu_type[n] = EVENT_CPUTYPE_GENERIC; for(int i = 1; i < dcount_cpu; i++) { for(int k = 0; k < 6; k++) cpu_update_clocks[i][k] = d_cpu[i].update_clocks * k; } diff --git a/source/src/vm/ex80/CMakeLists.txt b/source/src/vm/ex80/CMakeLists.txt index e3147aea8..b33857f14 100644 --- a/source/src/vm/ex80/CMakeLists.txt +++ b/source/src/vm/ex80/CMakeLists.txt @@ -2,10 +2,12 @@ cmake_minimum_required (VERSION 2.6) message("* vm/ex80") -add_library(vm_ex80 +add_library(vm_emuex80 + ../i8080.cpp + cmt.cpp display.cpp - ex80.cpp keyboard.cpp - memory.cpp + ./memory.cpp + ex80.cpp ) diff --git a/source/src/vm/ex80/cmt.h b/source/src/vm/ex80/cmt.h index 814aefdb0..33f025425 100644 --- a/source/src/vm/ex80/cmt.h +++ b/source/src/vm/ex80/cmt.h @@ -34,7 +34,7 @@ class CMT : public DEVICE void release_tape(); public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } diff --git a/source/src/vm/ex80/display.h b/source/src/vm/ex80/display.h index d5fffd837..721626cf2 100644 --- a/source/src/vm/ex80/display.h +++ b/source/src/vm/ex80/display.h @@ -30,7 +30,7 @@ class DISPLAY : public DEVICE bool dma; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } @@ -41,7 +41,7 @@ class DISPLAY : public DEVICE void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_frame(); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/ex80/ex80.cpp b/source/src/vm/ex80/ex80.cpp index 05d8bd49b..54c3169b6 100644 --- a/source/src/vm/ex80/ex80.cpp +++ b/source/src/vm/ex80/ex80.cpp @@ -36,7 +36,7 @@ using EX80::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -251,6 +251,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -263,7 +275,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/ex80/ex80.h b/source/src/vm/ex80/ex80.h index 5722c1b41..030ca474d 100644 --- a/source/src/vm/ex80/ex80.h +++ b/source/src/vm/ex80/ex80.h @@ -152,7 +152,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -193,6 +193,9 @@ class VM : public VM_TEMPLATE bool is_tape_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/ex80/keyboard.h b/source/src/vm/ex80/keyboard.h index 9787a2366..5606d0247 100644 --- a/source/src/vm/ex80/keyboard.h +++ b/source/src/vm/ex80/keyboard.h @@ -27,7 +27,7 @@ class KEYBOARD : public DEVICE void update_kb(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/ex80/memory.h b/source/src/vm/ex80/memory.h index 1a9971870..6abb25c1a 100644 --- a/source/src/vm/ex80/memory.h +++ b/source/src/vm/ex80/memory.h @@ -31,7 +31,7 @@ class MEMORY : public DEVICE uint8_t* rbank[64]; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/familybasic/CMakeLists.txt b/source/src/vm/familybasic/CMakeLists.txt index c5bbf3b83..74d52a1a4 100644 --- a/source/src/vm/familybasic/CMakeLists.txt +++ b/source/src/vm/familybasic/CMakeLists.txt @@ -1,10 +1,12 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/familybasic") +message("* vm/${EXE_NAME}") -add_library(vm_familybasic - familybasic.cpp - memory.cpp +add_library(vm_${EXE_NAME} + ../n2a03.cpp + apu.cpp + memory.cpp ppu.cpp -) \ No newline at end of file + familybasic.cpp +) diff --git a/source/src/vm/familybasic/apu.h b/source/src/vm/familybasic/apu.h index 37943689d..ab685bc9d 100644 --- a/source/src/vm/familybasic/apu.h +++ b/source/src/vm/familybasic/apu.h @@ -160,7 +160,7 @@ class APU : public DEVICE int volume_l, volume_r; public: - APU(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + APU(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("APU")); @@ -174,7 +174,7 @@ class APU : public DEVICE uint32_t __FASTCALL read_data8(uint32_t addr); void event_frame(); void event_vline(int v, int clock); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/familybasic/familybasic.cpp b/source/src/vm/familybasic/familybasic.cpp index d048bd7b4..f38fea83e 100644 --- a/source/src/vm/familybasic/familybasic.cpp +++ b/source/src/vm/familybasic/familybasic.cpp @@ -35,7 +35,7 @@ using FAMILYBASIC::PPU; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // check configs // boot_mode = config.boot_mode; @@ -326,6 +326,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 6 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -338,7 +350,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/familybasic/familybasic.h b/source/src/vm/familybasic/familybasic.h index 67a0e94ff..43197596c 100644 --- a/source/src/vm/familybasic/familybasic.h +++ b/source/src/vm/familybasic/familybasic.h @@ -30,7 +30,7 @@ #define USE_BOOT_MODE 6 #define USE_TAPE 1 #define USE_AUTO_KEY 5 -#define USE_AUTO_KEY_RELEASE 6 +#define USE_AUTO_KEY_RELEASE 8 #define USE_AUTO_KEY_NO_CAPS #define USE_SOUND_VOLUME 4 #define USE_JOYSTICK @@ -38,6 +38,9 @@ #define USE_DEBUGGER #define USE_STATE #define USE_CPU_N2A03 +#define USE_VM_AUTO_KEY_TABLE +#define USE_TWO_STROKE_AUTOKEY_HANDAKUON +#define USE_TWO_STROKE_AUTOKEY_DAKUON #include "../../common.h" #include "../../fileio.h" @@ -62,6 +65,129 @@ static const _TCHAR *joy_button_captions[] = { }; #endif +#ifdef USE_VM_AUTO_KEY_TABLE +static const int vm_auto_key_table_base[][2] = { + // A,I,U,E,O -> 1,2,3,4,5 + {0xb1, 0x200 | 0x31}, + {0xb2, 0x200 | 0x32}, + {0xb3, 0x200 | 0x33}, + {0xb4, 0x200 | 0x34}, + {0xb5, 0x200 | 0x35}, + // KA,KI,KU,KE,KO -> Q,W,E,R,T + {0xb6, 0x200 | ((int)'Q')}, + {0xb7, 0x200 | ((int)'W')}, + {0xb8, 0x200 | ((int)'E')}, + {0xb9, 0x200 | ((int)'R')}, + {0xba, 0x200 | ((int)'T')}, + // SA,SI,SU,SE,SO -> A,S,D,F,G + {0xbb, 0x200 | ((int)'A')}, + {0xbc, 0x200 | ((int)'S')}, + {0xbd, 0x200 | ((int)'D')}, + {0xbe, 0x200 | ((int)'F')}, + {0xbf, 0x200 | ((int)'G')}, + // TA,TI,TU,TE,TO -> Z, X, C, V, B + {0xc0, 0x200 | ((int)'Z')}, + {0xc1, 0x200 | ((int)'X')}, + {0xc2, 0x200 | ((int)'C')}, + {0xc3, 0x200 | ((int)'V')}, + {0xc4, 0x200 | ((int)'B')}, + // NA,NI,NU,NE,NO -> 6,7,8,9,0 + {0xc5, 0x200 | 0x36}, + {0xc6, 0x200 | 0x37}, + {0xc7, 0x200 | 0x38}, + {0xc8, 0x200 | 0x39}, + {0xc9, 0x200 | 0x30}, + // HA,HI,HU,HE,HO -> Y,U,I,O,P + {0xca, 0x200 | ((int)'Y')}, + {0xcb, 0x200 | ((int)'U')}, + {0xcc, 0x200 | ((int)'I')}, + {0xcd, 0x200 | ((int)'O')}, + {0xce, 0x200 | ((int)'P')}, + // MA,MI,MU,ME,MO -> H,J,K,L,; + {0xcf, 0x200 | ((int)'H')}, + {0xd0, 0x200 | ((int)'J')}, + {0xd1, 0x200 | ((int)'K')}, + {0xd2, 0x200 | ((int)'L')}, + {0xd3, 0x200 | ((int)';')}, + // YA,YU,YO,WA,W0,NN -> N,M,,,.,/,_ + {0xd4, 0x200 | ((int)'N')}, + {0xd5, 0x200 | ((int)'M')}, + {0xd6, 0x200 | 0xbc}, + {0xdc, 0x200 | 0xbe}, + {0xa6, 0x200 | 0xbf}, + {0xdd, 0x200 | 0xe2}, + // RA,RI,RU,RE,RO -> -, ^, ¥, @, [ + {0xd7, 0x200 | 0xbd}, + {0xd8, 0x200 | 0xde}, + {0xd9, 0x200 | 0xdc}, + {0xda, 0x200 | 0xc0}, + {0xdb, 0x200 | 0xdb}, + // XA,XI,XU,XE,XO -> SHIFT+1, SHIFT+2, SHIFT+3, SHIFT+4, SHIFT+5 + {0xa7, 0x300 | 0x31}, + {0xa8, 0x300 | 0x32}, + {0xa9, 0x300 | 0x33}, + {0xaa, 0x300 | 0x34}, + {0xab, 0x300 | 0x35}, + // XYA,XYU,XYO -> SHIFT+N,SHIFT+M,SHIFT+, + {0xac, 0x300 | ((int)'N')}, + {0xad, 0x300 | ((int)'M')}, + {0xae, 0x300 | 0xbc}, + // XTU -> SHIFT + C + {0xaf, 0x300 | ((int)'C')}, + // ONBIKI -> - + {0xb0, 0x000 | 0xbd}, + // _, MARU -> :, ] + {0x5f, 0x200 | 0xbd}, + {0xa1, 0x200 | 0xdd}, + // KAGIKAKKO + {0xa2, 0x300 | 0xbd}, + {0xa3, 0x300 | 0xdd}, + // '゙' -> Double Quotation +// {0xde, 0x100 | 0x32}, + {-1, -1} +}; +#endif +#ifdef USE_TWO_STROKE_AUTOKEY_HANDAKUON +static const int kana_handakuon_keyboard_table[][6] = { + // PA,PI,PU,PE,PO -> Y,U,I,O,P + {0xca, 0x300 | ((int)'Y'), 0x00, 0x00, 0x00, 0x00}, + {0xcb, 0x300 | ((int)'U'), 0x00, 0x00, 0x00, 0x00}, + {0xcc, 0x300 | ((int)'I'), 0x00, 0x00, 0x00, 0x00}, + {0xcd, 0x300 | ((int)'O'), 0x00, 0x00, 0x00, 0x00}, + {0xce, 0x300 | ((int)'P'), 0x00, 0x00, 0x00, 0x00}, + {-1, -1} +}; +#endif +#ifdef USE_TWO_STROKE_AUTOKEY_DAKUON +static const int kana_dakuon_keyboard_table[][6] = { + // GA,GI,GU,GE,GO -> Q,W,E,R,T + {0xb6, 0x1000 | 0xa4, 0x200 | ((int)'Q'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xb7, 0x1000 | 0xa4, 0x200 | ((int)'W'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xb8, 0x1000 | 0xa4, 0x200 | ((int)'E'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xb9, 0x1000 | 0xa4, 0x200 | ((int)'R'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xba, 0x1000 | 0xa4, 0x200 | ((int)'T'), 0x2000 | 0xa4, 0x00, 0x00}, + // ZA,ZI,ZU,ZE,ZO -> A,S,D,F,G + {0xbb, 0x1000 | 0xa4, 0x200 | ((int)'A'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xbc, 0x1000 | 0xa4, 0x200 | ((int)'S'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xbd, 0x1000 | 0xa4, 0x200 | ((int)'D'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xbe, 0x1000 | 0xa4, 0x200 | ((int)'F'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xbf, 0x1000 | 0xa4, 0x200 | ((int)'G'), 0x2000 | 0xa4, 0x00, 0x00}, + // DA,DI,DU,DE,DO -> Z, X, C, V, B + {0xc0, 0x1000 | 0xa4, 0x200 | ((int)'Z'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xc1, 0x1000 | 0xa4, 0x200 | ((int)'X'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xc2, 0x1000 | 0xa4, 0x200 | ((int)'C'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xc3, 0x1000 | 0xa4, 0x200 | ((int)'V'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xc4, 0x1000 | 0xa4, 0x200 | ((int)'B'), 0x2000 | 0xa4, 0x00, 0x00}, + // BA,BI,BU,BE,BO -> Y,U,I,O,P + {0xca, 0x1000 | 0xa4, 0x200 | ((int)'Y'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xcb, 0x1000 | 0xa4, 0x200 | ((int)'U'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xcc, 0x1000 | 0xa4, 0x200 | ((int)'I'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xcd, 0x1000 | 0xa4, 0x200 | ((int)'O'), 0x2000 | 0xa4, 0x00, 0x00}, + {0xce, 0x1000 | 0xa4, 0x200 | ((int)'P'), 0x2000 | 0xa4, 0x00, 0x00}, + {-1, -1} +}; +#endif + typedef struct header_s { uint8_t id[3]; // 'NES' uint8_t ctrl_z; // control-z @@ -122,7 +248,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -170,6 +296,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/familybasic/memory.cpp b/source/src/vm/familybasic/memory.cpp index 9ffcaf978..1d38d5d2e 100644 --- a/source/src/vm/familybasic/memory.cpp +++ b/source/src/vm/familybasic/memory.cpp @@ -298,7 +298,11 @@ uint32_t MEMORY::read_data8(uint32_t addr) switch(kb_scan) { case 1: if(key_stat[0x15]) val &= ~0x02; // KANA +#if 0 // if(key_stat[0x10]) val &= ~0x04; // RSHIFT +#else + if(key_stat[VK_RSHIFT]) val &= ~0x04; // RSHIFT +#endif if(key_stat[0xdc]) val &= ~0x08; // '\\' if(key_stat[0x23]) val &= ~0x10; // STOP break; @@ -339,7 +343,11 @@ uint32_t MEMORY::read_data8(uint32_t addr) if(key_stat[0x33]) val &= ~0x10; // 3 break; case 8: +#if 0 if(key_stat[0x10]) val &= ~0x02; // LSHIFT +#else + if(key_stat[VK_LSHIFT]) val &= ~0x02; // LSHIFT +#endif if(key_stat[0x12]) val &= ~0x04; // GRAPH if(key_stat[0x31]) val &= ~0x08; // 1 if(key_stat[0x32]) val &= ~0x10; // 2 diff --git a/source/src/vm/familybasic/memory.h b/source/src/vm/familybasic/memory.h index b7ffa54c3..b49011ac8 100644 --- a/source/src/vm/familybasic/memory.h +++ b/source/src/vm/familybasic/memory.h @@ -100,7 +100,7 @@ class MEMORY : public DEVICE void __FASTCALL vrc7_hsync(int v); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } @@ -113,7 +113,7 @@ class MEMORY : public DEVICE void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/familybasic/ppu.h b/source/src/vm/familybasic/ppu.h index 48506903a..537641458 100644 --- a/source/src/vm/familybasic/ppu.h +++ b/source/src/vm/familybasic/ppu.h @@ -65,7 +65,7 @@ class PPU : public DEVICE void update_palette(); public: - PPU(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PPU(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("PPU")); } diff --git a/source/src/vm/fm16beta/CMakeLists.txt b/source/src/vm/fm16beta/CMakeLists.txt index 3db477dd8..3696d14a2 100644 --- a/source/src/vm/fm16beta/CMakeLists.txt +++ b/source/src/vm/fm16beta/CMakeLists.txt @@ -1,34 +1,27 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/fm16beta") +message("* vm/${EXE_NAME}") set(VM_FM16BETA_LIB_SRCS + ../i8237.cpp + ../msm58321.cpp + cmos.cpp keyboard.cpp mainbus.cpp sub.cpp + fm16beta.cpp ) -if(USE_DEVICES_SHARED_LIB) -else() - set(VM_FM16BETA_LIB_SRCS ${VM_FM16BETA_LIB_SRCS} - hd46505.cpp - i8237.cpp - i8251.cpp - i8259.cpp - mb8877.cpp - mc6809.cpp - mc6840.cpp - msm58321.cpp - pcm1bit.cpp - - disk.cpp - - memory.cpp - io.cpp - ) -endif() -add_library(vm_fm16beta +add_library(vm_${EXE_NAME} ${VM_FM16BETA_LIB_SRCS} ) + +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +if("${U_EXE_NAME}" STREQUAL "EMUFM16BETA_186") + target_compile_definitions(vm_emufm16beta_186 PRIVATE -DHAS_I186) +elseif("${U_EXE_NAME}" STREQUAL "EMUFM16BETA_286") + target_compile_definitions(vm_emufm16beta_286 PRIVATE -DHAS_I286) +endif() diff --git a/source/src/vm/fm16beta/cmos.h b/source/src/vm/fm16beta/cmos.h index 9ede81600..2c08dc301 100644 --- a/source/src/vm/fm16beta/cmos.h +++ b/source/src/vm/fm16beta/cmos.h @@ -23,7 +23,7 @@ class CMOS : public DEVICE bool modified; public: - CMOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMOS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMOS RAM")); } diff --git a/source/src/vm/fm16beta/fm16beta.cpp b/source/src/vm/fm16beta/fm16beta.cpp index 49eb5a4e1..f1ba0680e 100644 --- a/source/src/vm/fm16beta/fm16beta.cpp +++ b/source/src/vm/fm16beta/fm16beta.cpp @@ -17,10 +17,10 @@ #include "../i8237.h" #include "../i8251.h" #include "../i8259.h" -#ifdef HAS_I286 -#include "../i286.h" -#else +#if defined(HAS_I186) #include "../i86.h" +#elif defined(HAS_I286) +#include "../i286.h" #endif #include "../io.h" #include "../mb8877.h" @@ -48,7 +48,7 @@ using FM16BETA::SUB; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -56,10 +56,11 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) event = new EVENT(this, emu); // must be 2nd device crtc = new HD46505(this, emu); -#if defined(HAS_I286) - cpu = new I80286(this, emu); -#else - cpu = new I8086(this, emu); +#if defined(HAS_I186) + cpu = new I86(this, emu); + cpu->device_model = INTEL_80186; +#elif defined(HAS_I286) + cpu = new I286(this, emu); #endif io = new IO(this, emu); dma = new I8237(this, emu); @@ -93,8 +94,12 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) cmos = new CMOS(this, emu); keyboard = new KEYBOARD(this, emu); mainbus = new MAINBUS(this, emu); - subbus = new SUB(this, emu); + subbus = new SUB(this, emu); + // MUST set MEMORY SIZE before use. + subbus->set_addr_max(0x10000); + subbus->set_bank_size(0x80); + // set contexts event->set_context_cpu(cpu, 8000000); event->set_context_cpu(subcpu, 2000000); @@ -107,7 +112,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) event->set_context_sound(fdc_2d->get_context_noise_head_up()); keyboard->set_context_main(mainbus); -#ifdef HAS_I286 +#if defined(HAS_I286) mainbus->set_context_cpu(cpu); #endif mainbus->set_context_dma(dma); @@ -148,8 +153,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) crtc->set_context_disp(subbus, SIG_SUB_DISP, 1); crtc->set_context_vsync(subbus, SIG_SUB_VSYNC, 1); - subbus->addr_max = 0x10000; - subbus->bank_size = 0x80; +// subbus->addr_max = 0x10000; +// subbus->bank_size = 0x80; subbus->set_context_crtc(crtc); subbus->set_chregs_ptr(crtc->get_regs()); subbus->set_context_pcm(pcm); @@ -175,7 +180,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io->set_iomap_range_rw(0x0000, 0x0001, pic); io->set_iomap_range_rw(0x0010, 0x001f, dma); io->set_iomap_range_w(0x0020, 0x0023, mainbus); // dma bank regs -#ifdef HAS_I286 +#if defined(HAS_I286) io->set_iomap_single_rw(0x0060, mainbus); // reset #endif @@ -412,7 +417,19 @@ void VM::update_config() } } -#define STATE_VERSION 2 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -424,7 +441,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/fm16beta/fm16beta.h b/source/src/vm/fm16beta/fm16beta.h index 24ec5639e..e357f7668 100644 --- a/source/src/vm/fm16beta/fm16beta.h +++ b/source/src/vm/fm16beta/fm16beta.h @@ -10,15 +10,12 @@ #ifndef _FM16BETA_H_ #define _FM16BETA_H_ -#if defined(HAS_I286) -#define DEVICE_NAME "FUJITSU FM16beta (i286)" -#define CONFIG_NAME "fm16beta_i286" -#else -#ifndef HAS_I186 -#define HAS_I186 -#endif +#if defined(HAS_I186) #define DEVICE_NAME "FUJITSU FM16beta (i186)" #define CONFIG_NAME "fm16beta_i186" +#elif defined(HAS_I286) +#define DEVICE_NAME "FUJITSU FM16beta (i286)" +#define CONFIG_NAME "fm16beta_i286" #endif // device informations for virtual machine @@ -38,10 +35,10 @@ #define SINGLE_MODE_DMA //#define MB8877_NO_BUSY_AFTER_SEEK -#if defined(HAS_I286) -#define MEMORY_ADDR_MAX 0x1000000 // 16MB -#else +#if defined(HAS_I186) #define MEMORY_ADDR_MAX 0x100000 // 1MB +#elif defined(HAS_I286) +#define MEMORY_ADDR_MAX 0x1000000 // 16MB #endif #define MEMORY_BANK_SIZE 0x4000 @@ -81,8 +78,11 @@ class HD46505; class I8237; class I8251; class I8259; -class I80286; -class I8086; +#if defined(HAS_I186) +class I86; +#elif defined(HAS_I286) +class I286; +#endif class IO; class MB8877; class MC6809; @@ -110,11 +110,11 @@ class VM : public VM_TEMPLATE I8237* dma; I8251* sio; I8259* pic; -#ifdef HAS_I286 - I80286* cpu; -#else - I8086* cpu; -#endif +#if defined(HAS_I186) + I86* cpu; +#elif defined(HAS_I286) + I286* cpu; +#endif IO* io; MB8877* fdc_2hd; MB8877* fdc_2d; @@ -133,7 +133,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -174,6 +174,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/fm16beta/keyboard.h b/source/src/vm/fm16beta/keyboard.h index a883adca8..ee6cd49e6 100644 --- a/source/src/vm/fm16beta/keyboard.h +++ b/source/src/vm/fm16beta/keyboard.h @@ -64,7 +64,7 @@ class KEYBOARD : public DEVICE uint8_t table[256]; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/fm16beta/main.cpp b/source/src/vm/fm16beta/main.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/source/src/vm/fm16beta/mainbus.cpp b/source/src/vm/fm16beta/mainbus.cpp index 7b0cc2296..d0025c3f0 100644 --- a/source/src/vm/fm16beta/mainbus.cpp +++ b/source/src/vm/fm16beta/mainbus.cpp @@ -333,26 +333,26 @@ this->out_debug_log("SUB -> MAIN: SUB BUSY = %d\n", sub_busy); /* IRQ8 -> INT0 - IRQ8: ^C}[ + IRQ8: タイマー IRQ1 + FIRQ1 -> INT1 - IRQ1: L[{[h - FIRQ1: BREAKL[ + IRQ1: キーボード + FIRQ1: BREAKキー IRQ5 + IRQ6 -> INT2 - IRQ5: IMBtbsBfBXN - IRQ6: n[hfBXN + IRQ5: IMBフロッピィディスク + IRQ6: ハードディスク FIRQ0 + FIRQ2 + FIRQ3 -> INT3 - FIRQ0: SUBAeV - FIRQ2: g - FIRQ3: [Up + FIRQ0: SUBアテンション + FIRQ2: 拡張 + FIRQ3: ユーザ用 IRQ0 -> INT4 IRQ0: RS-232C IRQ2 + IRQ9 + INTNDP -> INT5 - IRQ2: g - IRQ9: [Up + IRQ2: 拡張 + IRQ9: ユーザ用 IRQ4 -> INT6 - IRQ4: 320KBtbsBfBXN + IRQ4: 320KBフロッピィディスク IRQ7 -> INT7 - IRQ7: v^ + IRQ7: プリンタ */ void MAINBUS::update_int0() diff --git a/source/src/vm/fm16beta/mainbus.h b/source/src/vm/fm16beta/mainbus.h index 3a5e7a21f..3d2e12dca 100644 --- a/source/src/vm/fm16beta/mainbus.h +++ b/source/src/vm/fm16beta/mainbus.h @@ -10,6 +10,7 @@ #ifndef _MAINBUS_H_ #define _MAINBUS_H_ +#include "../vm.h" #include "../memory.h" #define SIG_MAIN_IRQ0_TX 0 // RS-232C @@ -38,7 +39,7 @@ #define SIG_MAIN_RTC_BUSY 20 #ifdef HAS_I286 -class I80286; +class I286; #else class I8086; #endif @@ -53,7 +54,7 @@ class MAINBUS : public MEMORY //csp_state_utils *state_entry; #ifdef HAS_I286 - I80286 *d_cpu; + I286 *d_cpu; uint8_t rst; #endif I8237 *d_dma; @@ -100,7 +101,7 @@ class MAINBUS : public MEMORY void update_int7(); public: - MAINBUS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu) + MAINBUS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MEMORY(parent_vm, parent_emu) { set_device_name(_T("Main System")); } @@ -117,7 +118,7 @@ class MAINBUS : public MEMORY // unique functions #ifdef HAS_I286 - void set_context_cpu(I80286* device) + void set_context_cpu(I286* device) { d_cpu = device; } diff --git a/source/src/vm/fm16beta/sub.h b/source/src/vm/fm16beta/sub.h index f4d26febf..df6180c93 100644 --- a/source/src/vm/fm16beta/sub.h +++ b/source/src/vm/fm16beta/sub.h @@ -10,6 +10,7 @@ #ifndef _SUB_H_ #define _SUB_H_ +#include "../vm.h" #include "../memory.h" #define SIG_SUB_DISP 0 @@ -91,7 +92,7 @@ class SUB : public MEMORY uint32_t __FASTCALL read_memory(uint32_t addr); public: - SUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu) + SUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MEMORY(parent_vm, parent_emu) { set_device_name(_T("Sub System")); } diff --git a/source/src/vm/fm16pi/CMakeLists.txt b/source/src/vm/fm16pi/CMakeLists.txt index c5a442922..aa1c315ed 100644 --- a/source/src/vm/fm16pi/CMakeLists.txt +++ b/source/src/vm/fm16pi/CMakeLists.txt @@ -1,11 +1,12 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pc16pi") +message("* vm/emufm16pi") -set(BASIC_VM_FILES - fm16pi.cpp - sub.cpp - ) - +set(BASIC_VM_FILES + ../msm58321.cpp + + sub.cpp + fm16pi.cpp +) -add_library(vm_fm16pi ${BASIC_VM_FILES}) +add_library(vm_emufm16pi ${BASIC_VM_FILES}) diff --git a/source/src/vm/fm16pi/fm16pi.cpp b/source/src/vm/fm16pi/fm16pi.cpp index 7982e3b8b..c9fb452db 100644 --- a/source/src/vm/fm16pi/fm16pi.cpp +++ b/source/src/vm/fm16pi/fm16pi.cpp @@ -38,7 +38,7 @@ using FM16PI::SUB; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -49,13 +49,15 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pit = new I8253(this, emu); pio = new I8255(this, emu); // for system port pic = new I8259(this, emu); - cpu = new I8086(this, emu); + cpu = new I86(this, emu); + cpu->device_model = INTEL_8086; io = new IO(this, emu); fdc = new MB8877(this, emu); fdc->set_context_noise_seek(new NOISE(this, emu)); fdc->set_context_noise_head_down(new NOISE(this, emu)); fdc->set_context_noise_head_up(new NOISE(this, emu)); memory = new MEMORY(this, emu); + rtc = new MSM58321(this, emu); not_pit = new NOT(this, emu); pcm = new PCM1BIT(this, emu); @@ -419,7 +421,19 @@ void VM::update_config() } } -#define STATE_VERSION 3 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -431,7 +445,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/fm16pi/fm16pi.h b/source/src/vm/fm16pi/fm16pi.h index 030421649..fcf5b745f 100644 --- a/source/src/vm/fm16pi/fm16pi.h +++ b/source/src/vm/fm16pi/fm16pi.h @@ -22,7 +22,6 @@ #define SCREEN_WIDTH 640 #define SCREEN_HEIGHT 200 #define MAX_DRIVE 4 -#define HAS_I86 #define I8259_MAX_CHIPS 1 #define MEMORY_ADDR_MAX 0x100000 #define MEMORY_BANK_SIZE 0x4000 @@ -30,6 +29,7 @@ // device informations for win32 #define USE_FLOPPY_DISK 2 +#define USE_FLOPPY_TYPE_BIT 0x0003 /* 3.5, 3.5 */ #define USE_AUTO_KEY 5 #define USE_AUTO_KEY_RELEASE 6 #define USE_NOTIFY_POWER_OFF @@ -58,7 +58,7 @@ class I8251; class I8253; class I8255; class I8259; -class I8086; +class I86; class IO; class MB8877; class MEMORY; @@ -83,7 +83,7 @@ class VM : public VM_TEMPLATE I8253* pit; I8255* pio; I8259* pic; - I8086* cpu; + I86* cpu; IO* io; MB8877* fdc; MEMORY* memory; @@ -103,7 +103,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -148,6 +148,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/fm16pi/sub.h b/source/src/vm/fm16pi/sub.h index 6953694dc..612f73b80 100644 --- a/source/src/vm/fm16pi/sub.h +++ b/source/src/vm/fm16pi/sub.h @@ -33,7 +33,7 @@ class SUB : public DEVICE uint8_t *vram; public: - SUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Sub System")); } @@ -46,7 +46,7 @@ class SUB : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/fm7/CMakeLists.txt b/source/src/vm/fm7/CMakeLists.txt index cbe1b4cbf..0cfa7c1b3 100644 --- a/source/src/vm/fm7/CMakeLists.txt +++ b/source/src/vm/fm7/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/fm7") -#include(cotire) - +message("* vm/${EXE_NAME}") set(VM_FM7_LIB_SRCS display.cpp vram.cpp @@ -22,41 +20,65 @@ set(VM_FM7_LIB_SRCS fm7.cpp ) -if(BUILD_FM8) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} fm_bubblecasette.cpp fm8_mainio.cpp) -elseif(BUILD_FM7) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp) -elseif(BUILD_FMNEW7) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp) -elseif(BUILD_FM77) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp floppy_2HD.cpp) -elseif(BUILD_FM77L2) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp floppy_2HD.cpp) -elseif(BUILD_FM77L4) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp floppy_2HD.cpp) -elseif(BUILD_FM77AV) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp) +if(${EXE_NAME} STREQUAL emufm8) + add_library(vm_emufm8 + ${VM_FM7_LIB_SRCS} + fm_bubblecasette.cpp + fm8_mainio.cpp + ) +elseif(${EXE_NAME} STREQUAL emufm7) + add_library(vm_emufm7 + ${VM_FM7_LIB_SRCS} + jcommcard.cpp + ) +elseif(${EXE_NAME} STREQUAL emufm77) + add_library(vm_emufm77 + ${VM_FM7_LIB_SRCS} + jcommcard.cpp + floppy_2HD.cpp + ) +elseif(${EXE_NAME} STREQUAL emufm77l2) + add_library(vm_emufm77l2 + ${VM_FM7_LIB_SRCS} + jcommcard.cpp + floppy_2HD.cpp + ) +elseif(${EXE_NAME} STREQUAL emufm77l4) + add_library(vm_emufm77l4 + ${VM_FM7_LIB_SRCS} + jcommcard.cpp + floppy_2HD.cpp + ) +elseif(${EXE_NAME} STREQUAL emufm77av) + add_library(vm_emufm77av + ${VM_FM7_LIB_SRCS} + jcommcard.cpp + ) +else() + add_library(vm_${EXE_NAME} + ${VM_FM7_LIB_SRCS} + ) endif() -if(USE_DEVICES_SHARED_LIB) -else() +if(NOT USE_DEVICES_SHARED_LIB) set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} dummydevice.cpp) - if(FM77AV_VARIANTS) + if(${EXE_NAME} STREQUAL emufm77av) set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} mb61vh010.cpp) endif() - - if(BUILD_FM77AV20EX) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} hd6844.cpp) - elseif(BUILD_FM77AV40) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} hd6844.cpp) - elseif(BUILD_FM77AV40EX) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} hd6844.cpp) - elseif(BUILD_FM77AV40SX) - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} hd6844.cpp) + if(${EXE_NAME} STREQUAL emufm77av20) + set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} mb61vh010.cpp) + endif() + if(${EXE_NAME} STREQUAL emufm77av20ex) + set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} mb61vh010.cpp hd6844.cpp) + endif() + if(${EXE_NAME} STREQUAL emufm77av40) + set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} mb61vh010.cpp hd6844.cpp) + endif() + if(${EXE_NAME} STREQUAL emufm77av40ex) + set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} mb61vh010.cpp hd6844.cpp) + endif() + if(${EXE_NAME} STREQUAL emufm77av40sx) + set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} mb61vh010.cpp hd6844.cpp) endif() - set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} dummydevice.cpp) endif() -add_library(vm_fm7 - ${VM_FM7_LIB_SRCS} -) -#cotire(vm_fm7) \ No newline at end of file + diff --git a/source/src/vm/fm7/bubblecasette.h b/source/src/vm/fm7/bubblecasette.h index eb8abb56a..272e1241b 100644 --- a/source/src/vm/fm7/bubblecasette.h +++ b/source/src/vm/fm7/bubblecasette.h @@ -10,12 +10,11 @@ #ifndef _VM_FM_BUBBLECASETTE_H_ #define _VM_FM_BUBBLECASETTE_H_ - #include "device.h" #include "common.h" -class EMU; -class VM; +class EMU_TEMPLATE; +class VM_TEMPLATE; class FILEIO; namespace FM7 { @@ -102,7 +101,7 @@ class BUBBLECASETTE: public DEVICE { bool read_one_page(void); bool write_one_page(void); public: - BUBBLECASETTE(VM_TEMPLATE* parent_vm, EMU* parent_emu); + BUBBLECASETTE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~BUBBLECASETTE(); void initialize(); @@ -115,7 +114,7 @@ class BUBBLECASETTE: public DEVICE { void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool open(_TCHAR* file_path, int bank); void close(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO *state_fio, bool loading); bool is_bubble_inserted() diff --git a/source/src/vm/fm7/display.cpp b/source/src/vm/fm7/display.cpp index 97b6ac7e3..67ba1333f 100644 --- a/source/src/vm/fm7/display.cpp +++ b/source/src/vm/fm7/display.cpp @@ -6,7 +6,7 @@ */ #include "vm.h" -#include "emu.h" +#include "emu_template.h" #include "../../fileio.h" #include "fm7_display.h" #if defined(_FM77AV_VARIANTS) @@ -22,7 +22,7 @@ namespace FM7 { -DISPLAY::DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) +DISPLAY::DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { ins_led = NULL; kana_led = NULL; @@ -172,9 +172,11 @@ void DISPLAY::reset_some_devices() #endif for(i = 0; i < 8; i++) set_dpalette(i, i); #if defined(USE_GREEN_DISPLAY) - memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); + //memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); + for(i = 0; i < 8; i++) dpalette_pixel_green[i] = dpalette_green_tmp[i]; #endif - memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); + //memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); + for(i = 0; i < 8; i++) dpalette_pixel[i] = dpalette_pixel_tmp[i]; //do_firq(!firq_mask && key_firq_req); #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS) @@ -284,13 +286,13 @@ void DISPLAY::reset() power_on_reset = false; for(i = 0; i < 411 * 5; i++) vram_wrote_table[i] = false; nmi_enable = true; -#else -# if defined(_FM8) - for(i = 0; i < 8; i++) set_dpalette(i, i); -# endif +// for(i = 0; i < 8; i++) set_dpalette(i, i); #endif + + for(i = 0; i < 8; i++) set_dpalette(i, i); #if defined(USE_GREEN_DISPLAY) && defined(USE_MONITOR_TYPE) - memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); + for(i = 0; i < 8; i++) dpalette_pixel_green[i] = dpalette_green_tmp[i]; +// memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); switch(config.monitor_type) { case FM7_MONITOR_GREEN: use_green_monitor = true; @@ -305,7 +307,8 @@ void DISPLAY::reset() #endif force_update = true; - memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); + //memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); + for(i = 0; i < 8; i++) dpalette_pixel[i] = dpalette_pixel_tmp[i]; //enter_display(); if(nmi_event_id >= 0) cancel_event(this, nmi_event_id); @@ -463,7 +466,7 @@ void DISPLAY::set_dpalette(uint32_t addr, uint8_t val) { scrntype_t r, g, b; addr &= 7; - if(dpalette_data[addr] != (val | 0xf8)) { +// if(dpalette_data[addr] != (val | 0xf8)) { dpalette_data[addr] = val | 0xf8; //0b11111000; b = ((val & 0x01) != 0x00)? 255 : 0x00; r = ((val & 0x02) != 0x00)? 255 : 0x00; @@ -477,7 +480,7 @@ void DISPLAY::set_dpalette(uint32_t addr, uint8_t val) dpalette_green_tmp[addr] = RGB_COLOR(r, g, b); #endif palette_changed = true; - } +// } } uint8_t DISPLAY::get_dpalette(uint32_t addr) @@ -1476,9 +1479,11 @@ void DISPLAY::event_callback_vsync(void) memcpy(analog_palette_pixel, analog_palette_pixel_tmp, sizeof(analog_palette_pixel)); #endif #if defined(USE_GREEN_DISPLAY) - memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); + //memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); + for(int i = 0; i < 8; i++) dpalette_green_tmp[i] = dpalette_pixel_green[i]; #endif - memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); + //memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); + for(int i = 0; i < 8; i++) dpalette_pixel[i] = dpalette_pixel_tmp[i]; vram_wrote_shadow = true; for(int yy = 0; yy < 400; yy++) { vram_draw_table[yy] = true; @@ -3461,11 +3466,13 @@ void DISPLAY::initialize() #endif for(i = 0; i < 8; i++) set_dpalette(i, i); #if defined(USE_GREEN_DISPLAY) - memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); + for(i = 0; i < 8; i++) dpalette_pixel_green[i] = dpalette_green_tmp[i]; + //memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); use_green_monitor = false; #endif - memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); + for(i = 0; i < 8; i++) dpalette_pixel[i] = dpalette_pixel_tmp[i]; + //memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); //#if defined(_FM77AV_VARIANTS) hblank_event_id = -1; hdisp_event_id = -1; @@ -3680,26 +3687,22 @@ bool DISPLAY::process_state(FILEIO *state_fio, bool loading) for(i = 0; i < 411; i++) vram_draw_table[i] = true; #if defined(_FM8) for(addr = 0; addr < 8; addr++) set_dpalette(addr, addr); - memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); - #if defined(USE_GREEN_DISPLAY) - memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); - #endif + //memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); #else - for(addr = 0; addr < 8; addr++) set_dpalette(addr, dpalette_data[addr]); - memcpy(dpalette_pixel, dpalette_pixel_tmp, sizeof(dpalette_pixel)); -#if defined(USE_GREEN_DISPLAY) - memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); -#endif for(i = 0; i < 4; i++) { multimode_accessflags[i] = ((multimode_accessmask & (1 << i)) != 0) ? true : false; multimode_dispflags[i] = ((multimode_dispmask & (1 << i)) != 0) ? true : false; } #endif -#if defined(_FM77_VARIANTS) -# if defined(_FM77L4) -# endif -#elif defined(_FM77AV_VARIANTS) + + for(i = 0; i < 8; i++) dpalette_pixel[i] = dpalette_pixel_tmp[i]; +#if defined(USE_GREEN_DISPLAY) + //memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); + for(i = 0; i < 8; i++) dpalette_pixel_green[i] = dpalette_green_tmp[i]; +#endif + +#if defined(_FM77AV_VARIANTS) #if defined(_FM77AV40) || defined(_FM77AV40SX)|| defined(_FM77AV40SX) || \ defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) #endif @@ -3716,7 +3719,6 @@ bool DISPLAY::process_state(FILEIO *state_fio, bool loading) frame_skip_count_transfer = 3; need_transfer_line = true; #if defined(USE_GREEN_DISPLAY) && defined(USE_MONITOR_TYPE) - memcpy(dpalette_pixel_green, dpalette_green_tmp, sizeof(dpalette_pixel_green)); switch(config.monitor_type) { case FM7_MONITOR_GREEN: use_green_monitor = true; diff --git a/source/src/vm/fm7/dummydevice.h b/source/src/vm/fm7/dummydevice.h index 32bfe43d7..6022e519f 100644 --- a/source/src/vm/fm7/dummydevice.h +++ b/source/src/vm/fm7/dummydevice.h @@ -50,15 +50,15 @@ enum { SIG_DUMMYDEVICE_CLEAR_ON_RESET, SIG_DUMMYDEVICE_CLEAR_WITH_ZERO, }; -class VM; -class EMU; +class VM_TEMPLATE; +class EMU_TEMPLATE; class DUMMYDEVICE : public DEVICE { private: uint32_t status; bool clear_on_reset; bool clear_with_zero; public: - DUMMYDEVICE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DUMMYDEVICE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { status = 0x00000000; clear_on_reset = true; diff --git a/source/src/vm/fm7/fm7.cpp b/source/src/vm/fm7/fm7.cpp index 0ef51083e..7e09184a1 100644 --- a/source/src/vm/fm7/fm7.cpp +++ b/source/src/vm/fm7/fm7.cpp @@ -81,7 +81,7 @@ using FM7::JOYSTICK; using FM7::KEYBOARD; using FM7::KANJIROM; -VM::VM(EMU* parent_emu): VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu): VM_TEMPLATE(parent_emu) { first_device = last_device = NULL; @@ -261,7 +261,7 @@ VM::VM(EMU* parent_emu): VM_TEMPLATE(parent_emu) keyboard = new KEYBOARD(this, emu); - //display = new DISPLAY(this, emu); +// display = new DISPLAY(this, emu); #if defined(_FM8) mainio = new FM8_MAINIO(this, emu); #else @@ -778,7 +778,7 @@ void VM::reset() //display->reset(); // 20180618 K.O for RELICS } -void VM::special_reset() +void VM::special_reset(int num) { // BREAK + RESET mainio->reset(); @@ -1298,6 +1298,18 @@ void VM::set_vm_frame_rate(double fps) if(event != NULL) event->set_frames_per_sec(fps); } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 12 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -1310,7 +1322,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/fm7/fm7.h b/source/src/vm/fm7/fm7.h index 107614762..f4c7ca4fd 100644 --- a/source/src/vm/fm7/fm7.h +++ b/source/src/vm/fm7/fm7.h @@ -15,7 +15,7 @@ #define USE_SCANLINE #define USE_DIPSWITCH #define USE_CPU_TYPE 2 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_LED_DEVICE 3 #define USE_MINIMUM_RENDERING 1 #define USE_MOUSE @@ -302,10 +302,8 @@ #endif #define BASE_FLOPPY_DISK_NUM 0 -#ifdef BUILD_Z80 -# ifdef CAPABLE_Z80 +#ifdef CAPABLE_Z80 # define WITH_Z80 -# endif #endif // DIP Switch description @@ -341,7 +339,11 @@ #define MB8877_NO_BUSY_AFTER_SEEK //#define ENABLE_OPENCL // If OpenCL renderer is enabled, define here. - +#if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS) + #define USE_FLOPPY_TYPE_BIT 0x0003 /* 5.0, 5.0, 3.5, 3.5 */ +#else + #define USE_FLOPPY_TYPE_BIT 0x0000 /* 5.0, 5.0, 5.0, 5.0 */ +#endif //#include "../../config.h" #include "../../common.h" #include "../../fileio.h" @@ -545,7 +547,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -554,7 +556,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -631,6 +633,8 @@ class VM : public VM_TEMPLATE #if defined(USE_MINIMUM_RENDERING) bool is_screen_changed(void); #endif + double get_current_usec(); + uint64_t get_current_clock_uint64(); // ---------------------------------------- // for each device // ---------------------------------------- diff --git a/source/src/vm/fm7/fm7_display.h b/source/src/vm/fm7/fm7_display.h index f1ccaf6e9..00cf53314 100644 --- a/source/src/vm/fm7/fm7_display.h +++ b/source/src/vm/fm7/fm7_display.h @@ -8,6 +8,7 @@ #ifndef _CSP_FM7_DISPLAY_H #define _CSP_FM7_DISPLAY_H +#include "../vm.h" #include "../../common.h" #include "../device.h" #include "../mc6809.h" @@ -43,7 +44,6 @@ namespace FM7 { class DISPLAY: public DEVICE { private: - __DECL_ALIGNED(16) uint16_t bit_trans_table_0[256][8]; __DECL_ALIGNED(16) uint16_t bit_trans_table_1[256][8]; __DECL_ALIGNED(16) uint16_t bit_trans_table_2[256][8]; @@ -52,11 +52,14 @@ class DISPLAY: public DEVICE __DECL_ALIGNED(16) uint16_t bit_trans_table_4[256][8]; __DECL_ALIGNED(16) uint16_t bit_trans_table_5[256][8]; #endif + + uint32_t yoff_d1, yoff_d2; + uint32_t yoff_d; protected: - uint32_t (__FASTCALL DISPLAY::*read_cpu_func_table[512])(uint32_t); - uint32_t (__FASTCALL DISPLAY::*read_dma_func_table[512])(uint32_t); - void (__FASTCALL DISPLAY::*write_cpu_func_table[512])(uint32_t, uint8_t); - void (__FASTCALL DISPLAY::*write_dma_func_table[512])(uint32_t, uint8_t); + __DECL_ALIGNED(32) uint32_t (__FASTCALL DISPLAY::*read_cpu_func_table[512])(uint32_t); + __DECL_ALIGNED(32) uint32_t (__FASTCALL DISPLAY::*read_dma_func_table[512])(uint32_t); + __DECL_ALIGNED(32) void (__FASTCALL DISPLAY::*write_cpu_func_table[512])(uint32_t, uint8_t); + __DECL_ALIGNED(32) void (__FASTCALL DISPLAY::*write_dma_func_table[512])(uint32_t, uint8_t); bool delay_busy; bool screen_update_flag; @@ -66,14 +69,14 @@ class DISPLAY: public DEVICE void halt_subcpu(); void setup_display_mode(void); - void do_nmi(bool); - void do_irq(bool); - void do_firq(bool); - void set_multimode(uint8_t val); + void __FASTCALL do_nmi(bool); + void __FASTCALL do_irq(bool); + void __FASTCALL do_firq(bool); + void __FASTCALL set_multimode(uint8_t val); uint8_t get_multimode(void); uint8_t get_cpuaccessmask(void); - void set_dpalette(uint32_t addr, uint8_t val); - uint8_t get_dpalette(uint32_t addr); + void __FASTCALL set_dpalette(uint32_t addr, uint8_t val); + uint8_t __FASTCALL get_dpalette(uint32_t addr); void enter_display(void); void leave_display(void); void halt_subsystem(void); @@ -83,7 +86,7 @@ class DISPLAY: public DEVICE uint8_t acknowledge_irq(void); uint8_t beep(void); uint8_t attention_irq(void); - void set_cyclesteal(uint8_t val); + void __FASTCALL set_cyclesteal(uint8_t val); uint8_t set_vramaccess(void); void reset_vramaccess(void); uint8_t reset_subbusy(void); @@ -93,34 +96,35 @@ class DISPLAY: public DEVICE void setup_400linemode(uint8_t val); #if defined(_FM77AV_VARIANTS) - void alu_write_cmdreg(uint32_t val); - void alu_write_logical_color(uint8_t val); - void alu_write_mask_reg(uint8_t val); - void alu_write_cmpdata_reg(int addr, uint8_t val); - void alu_write_disable_reg(uint8_t val); - void alu_write_tilepaint_data(uint32_t addr, uint8_t val); - void alu_write_offsetreg_hi(uint8_t val); - void alu_write_offsetreg_lo(uint8_t val); - void alu_write_linepattern_hi(uint8_t val); - void alu_write_linepattern_lo(uint8_t val); - void alu_write_line_position(int addr, uint8_t val); + void __FASTCALL alu_write_cmdreg(uint32_t val); + void __FASTCALL alu_write_logical_color(uint8_t val); + void __FASTCALL alu_write_mask_reg(uint8_t val); + void __FASTCALL alu_write_cmpdata_reg(int addr, uint8_t val); + void __FASTCALL alu_write_disable_reg(uint8_t val); + void __FASTCALL alu_write_tilepaint_data(uint32_t addr, uint8_t val); + void __FASTCALL alu_write_offsetreg_hi(uint8_t val); + void __FASTCALL alu_write_offsetreg_lo(uint8_t val); + void __FASTCALL alu_write_linepattern_hi(uint8_t val); + void __FASTCALL alu_write_linepattern_lo(uint8_t val); + void __FASTCALL alu_write_line_position(int addr, uint8_t val); uint8_t get_miscreg(void); - void set_miscreg(uint8_t val); - void set_monitor_bank(uint8_t var); - void set_apalette_index_hi(uint8_t val); - void set_apalette_index_lo(uint8_t val); - void set_apalette_b(uint8_t val); - void set_apalette_r(uint8_t val); - void set_apalette_g(uint8_t val); - void calc_apalette(uint16_t idx); + void __FASTCALL set_miscreg(uint8_t val); + void __FASTCALL set_monitor_bank(uint8_t var); + void __FASTCALL set_apalette_index_hi(uint8_t val); + void __FASTCALL set_apalette_index_lo(uint8_t val); + void __FASTCALL set_apalette_b(uint8_t val); + void __FASTCALL set_apalette_r(uint8_t val); + void __FASTCALL set_apalette_g(uint8_t val); + void __FASTCALL calc_apalette(uint16_t idx); #endif // _FM77AV_VARIANTS void copy_vram_all(); void copy_vram_per_line(int begin, int end); void copy_vram_blank_area(void); - + void __FASTCALL draw_window(int dmode, int y, int begin, int bytes, bool window_inv, bool scan_line); + void __FASTCALL clear_display(int dmode, int w, int h); private: bool sub_busy; bool firq_mask; @@ -233,8 +237,8 @@ class DISPLAY: public DEVICE #endif uint8_t multimode_accessmask; uint8_t multimode_dispmask; - bool multimode_accessflags[4]; - bool multimode_dispflags[4]; + __DECL_ALIGNED(8) bool multimode_accessflags[4]; + __DECL_ALIGNED(8) bool multimode_dispflags[4]; uint32_t offset_point; pair32_t tmp_offset_point[2]; @@ -258,9 +262,9 @@ class DISPLAY: public DEVICE __DECL_ALIGNED(16) uint8_t gvram[__FM7_GVRAM_PAG_SIZE]; __DECL_ALIGNED(16) uint8_t gvram_shadow[__FM7_GVRAM_PAG_SIZE]; - uint8_t console_ram[0x1000]; - uint8_t work_ram[0x380]; - uint8_t shared_ram[0x80]; + __DECL_ALIGNED(16) uint8_t console_ram[0x1000]; + __DECL_ALIGNED(16) uint8_t work_ram[0x380]; + __DECL_ALIGNED(16) uint8_t shared_ram[0x80]; uint8_t subsys_c[0x2800]; #if defined(_FM77AV_VARIANTS) @@ -274,9 +278,9 @@ class DISPLAY: public DEVICE bool vram_accessflag; bool is_cyclesteal; #if defined(_FM77L4) - uint8_t subsys_cg_l4[0x1000]; + __DECL_ALIGNED(16) uint8_t subsys_cg_l4[0x1000]; uint8_t subsys_l4[0x4800]; - uint8_t text_vram[0x1000]; + __DECL_ALIGNED(16) uint8_t text_vram[0x1000]; uint8_t crtc_regs[18]; uint8_t text_scroll_count; bool workram_l4; @@ -301,9 +305,9 @@ class DISPLAY: public DEVICE #endif #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) - uint8_t submem_cgram[0x4000]; - uint8_t submem_console_av40[0x2000]; - uint8_t subsys_ram[0x2000]; + __DECL_ALIGNED(16) uint8_t submem_cgram[0x4000]; + __DECL_ALIGNED(16) uint8_t submem_console_av40[0x2000]; + __DECL_ALIGNED(16) uint8_t subsys_ram[0x2000]; uint8_t cgram_bank; bool kanji_level2; FM7::KANJIROM *kanjiclass1; @@ -313,11 +317,11 @@ class DISPLAY: public DEVICE #endif bool force_update; bool vram_wrote_shadow; - bool vram_wrote_table[411 * 5]; - bool vram_draw_table[411]; + __DECL_ALIGNED(16) bool vram_wrote_table[411 * 5]; + __DECL_ALIGNED(16) bool vram_draw_table[411]; //uint8_t vram_wrote_pages[411]; - uint32_t vram_wrote_addr_1[411]; - uint32_t vram_wrote_addr_2[411]; + __DECL_ALIGNED(16) uint32_t vram_wrote_addr_1[411]; + __DECL_ALIGNED(16) uint32_t vram_wrote_addr_2[411]; #if defined(_FM77AV_VARIANTS) bool use_alu; MB61VH010 *alu; @@ -380,7 +384,6 @@ class DISPLAY: public DEVICE void __FASTCALL write_dummy(uint32_t addr, uint8_t data); uint32_t read_bios(const _TCHAR *name, uint8_t *ptr, uint32_t size); - void draw_screen2(); void event_callback_vstart(void); void event_callback_vsync(void); @@ -388,7 +391,7 @@ class DISPLAY: public DEVICE void event_callback_hblank(void); template - void call_write_signal(T *np, int id, uint32_t data, uint32_t mask) + void __FASTCALL call_write_signal(T *np, int id, uint32_t data, uint32_t mask) { //T *nnp = static_cast(np); static_cast(np)->write_signal(id, data, mask); @@ -418,10 +421,13 @@ class DISPLAY: public DEVICE return static_cast(np)->read_dma_data8(addr); } +#if defined(_FM77L4) + void __FASTCALL draw_77l4_400l(bool ff); +#endif public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU *parent_emu); + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~DISPLAY(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int id); diff --git a/source/src/vm/fm7/fm7_keyboard.h b/source/src/vm/fm7/fm7_keyboard.h index 1d600b497..0984770b9 100644 --- a/source/src/vm/fm7/fm7_keyboard.h +++ b/source/src/vm/fm7/fm7_keyboard.h @@ -12,6 +12,7 @@ #define _VM_FM7_KEYBOARD_H_ #include "../device.h" +#include "../vm.h" #include "../memory.h" #include "../../fileio.h" @@ -93,14 +94,14 @@ class KEYBOARD : public DEVICE { FIFO *key_fifo; int event_int; - uint16_t vk2scancode(uint32_t vk); - bool isModifier(uint8_t sc); - void set_modifiers(uint8_t sc, bool flag); - uint16_t scan2fmkeycode(uint8_t sc); - void do_repeatkey(uint8_t sc); + uint16_t __FASTCALL vk2scancode(uint32_t vk); + bool __FASTCALL isModifier(uint8_t sc); + void __FASTCALL set_modifiers(uint8_t sc, bool flag); + uint16_t __FASTCALL scan2fmkeycode(uint8_t sc); + void __FASTCALL do_repeatkey(uint8_t sc); void reset_unchange_mode(void); - void key_down_main(bool repeat_auto_key); - void key_up_main(uint8_t bak_scancode); + void __FASTCALL key_down_main(bool repeat_auto_key); + void __FASTCALL key_up_main(uint8_t bak_scancode); #if defined(_FM77AV_VARIANTS) void set_mode(void); @@ -123,7 +124,7 @@ class KEYBOARD : public DEVICE { int repeat_time_long; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU *parent_emu); + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~KEYBOARD(); void key_up(uint32_t vk); @@ -143,7 +144,7 @@ class KEYBOARD : public DEVICE { uint32_t get_scancode_by_vk(uint32_t vk); uint32_t get_vk_by_scancode(uint32_t scancode); #endif - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int id); diff --git a/source/src/vm/fm7/fm7_mainio.cpp b/source/src/vm/fm7/fm7_mainio.cpp index 87283ae57..5c6bc9d81 100644 --- a/source/src/vm/fm7/fm7_mainio.cpp +++ b/source/src/vm/fm7/fm7_mainio.cpp @@ -32,7 +32,7 @@ #endif namespace FM7 { -FM7_MAINIO::FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) +FM7_MAINIO::FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { int i; for(i = 0; i < 3; i++) { diff --git a/source/src/vm/fm7/fm7_mainio.h b/source/src/vm/fm7/fm7_mainio.h index 0c2e2b59a..98a57d23b 100644 --- a/source/src/vm/fm7/fm7_mainio.h +++ b/source/src/vm/fm7/fm7_mainio.h @@ -11,6 +11,7 @@ #ifndef _VM_FM7_MAINIO_H_ #define _VM_FM7_MAINIO_H_ +#include "../vm.h" #include "./fm7.h" #include "fm7_common.h" @@ -469,41 +470,36 @@ class FM7_MAINIO : public DEVICE { #if defined(CAPABLE_JCOMMCARD) FM7::FM7_JCOMMCARD *jcommcard; #endif - template - void call_write_signal(T *np, int id, uint32_t data, uint32_t mask) + void __FASTCALL call_write_signal(DEVICE *np, int id, uint32_t data, uint32_t mask) { //T *nnp = static_cast(np); - static_cast(np)->write_signal(id, data, mask); + np->write_signal(id, data, mask); } - template - void call_write_data8(T *np, uint32_t addr, uint32_t data) + void __FASTCALL call_write_data8(DEVICE *np, uint32_t addr, uint32_t data) { //T *nnp = static_cast(np); - static_cast(np)->write_data8(addr, data); + np->write_data8(addr, data); } - template - uint32_t call_read_data8(T *np, uint32_t addr) + uint32_t __FASTCALL call_read_data8(DEVICE *np, uint32_t addr) { //T *nnp = static_cast(np); - return static_cast(np)->read_data8(addr); + return np->read_data8(addr); } - template - void call_write_dma_data8(T *np, uint32_t addr, uint32_t data) + void __FASTCALL call_write_dma_data8(DEVICE *np, uint32_t addr, uint32_t data) { //T *nnp = static_cast(np); - static_cast(np)->write_dma_data8(addr, data); + np->write_dma_data8(addr, data); } - template - uint32_t call_read_dma_data8(T *np, uint32_t addr) + uint32_t __FASTCALL call_read_dma_data8(DEVICE *np, uint32_t addr) { //T *nnp = static_cast(np); - return static_cast(np)->read_dma_data8(addr); + return np->read_dma_data8(addr); } bool load_state_opn(FILEIO *state_fio, bool loading); public: - FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu); + FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~FM7_MAINIO(); void event_vline(int v, int clock); @@ -523,7 +519,7 @@ class FM7_MAINIO : public DEVICE { virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); virtual uint32_t __FASTCALL read_signal(int id); - virtual void event_callback(int event_id, int err); + virtual void __FASTCALL event_callback(int event_id, int err); virtual void reset(); virtual void update_config(); virtual bool process_state(FILEIO *state_fio, bool loading); diff --git a/source/src/vm/fm7/fm7_mainmem.cpp b/source/src/vm/fm7/fm7_mainmem.cpp index 1743852e0..133b9b50a 100644 --- a/source/src/vm/fm7/fm7_mainmem.cpp +++ b/source/src/vm/fm7/fm7_mainmem.cpp @@ -6,7 +6,7 @@ * */ #include "vm.h" -#include "emu.h" +#include "emu_template.h" #include "fm7_mainmem.h" #include "fm7_mainio.h" #include "fm7_display.h" @@ -16,11 +16,8 @@ namespace FM7 { -FM7_MAINMEM::FM7_MAINMEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) +FM7_MAINMEM::FM7_MAINMEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { -#if !defined(_FM77AV_VARIANTS) - for(int i = 0; i < 8; i++) fm7_bootroms[i] = (uint8_t *)malloc(0x200); -#endif mainio = NULL; display = NULL; maincpu = NULL; @@ -38,9 +35,6 @@ FM7_MAINMEM::FM7_MAINMEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(paren FM7_MAINMEM::~FM7_MAINMEM() { -#if !defined(_FM77AV_VARIANTS) - for(int i = 0; i < 8; i++) if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]); -#endif } void FM7_MAINMEM::reset() @@ -521,7 +515,7 @@ void FM7_MAINMEM::update_config() setclock(config.cpu_type); } -#define STATE_VERSION 8 +#define STATE_VERSION 9 bool FM7_MAINMEM::process_state(FILEIO *state_fio, bool loading) { @@ -553,8 +547,6 @@ bool FM7_MAINMEM::process_state(FILEIO *state_fio, bool loading) state_fio->StateArray(fm7_mainmem_bootrom_vector, sizeof(fm7_mainmem_bootrom_vector), 1); state_fio->StateArray(fm7_mainmem_reset_vector, sizeof(fm7_mainmem_reset_vector), 1); - state_fio->StateArray(fm7_mainmem_null, sizeof(fm7_mainmem_null), 1); - #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS) state_fio->StateArray(fm7_bootram, sizeof(fm7_bootram), 1); #endif diff --git a/source/src/vm/fm7/fm7_mainmem.h b/source/src/vm/fm7/fm7_mainmem.h index a896797ec..e265b4a0c 100644 --- a/source/src/vm/fm7/fm7_mainmem.h +++ b/source/src/vm/fm7/fm7_mainmem.h @@ -8,6 +8,7 @@ #ifndef _FM7_MAINMEM_H_ #define _FM7_MAINMEM_H_ +#include "../vm.h" #include "fm7_common.h" #include "../device.h" @@ -42,6 +43,7 @@ class FM7_MAINMEM : public DEVICE } data_func_table_t; data_func_table_t data_table[ADDRESS_SPACE / 0x80]; + //data_func_table_t data_table[0x100000 / 0x80]; #if defined(HAS_MMR) # if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) data_func_table_t mmr_update_table_ext[(0x80 * 0x1000) / 0x80]; @@ -87,11 +89,10 @@ class FM7_MAINMEM : public DEVICE uint8_t fm7_mainmem_basicrom[0x7c00]; uint8_t fm7_mainmem_bioswork[0x80]; #if !defined(_FM77AV) - uint8_t *fm7_bootroms[8]; + uint8_t fm7_bootroms[8][0x200]; #endif uint8_t fm7_mainmem_bootrom_vector[0x1e]; // Without uint8_t fm7_mainmem_reset_vector[2]; // Without - uint8_t fm7_mainmem_null[1]; #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS) uint8_t fm7_bootram[0x200]; // $00000-$0ffff #endif @@ -226,7 +227,7 @@ class FM7_MAINMEM : public DEVICE return static_cast(np)->read_dma_data8(addr); } public: - FM7_MAINMEM(VM_TEMPLATE* parent_vm, EMU* parent_emu); + FM7_MAINMEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~FM7_MAINMEM(); uint32_t __FASTCALL read_data8(uint32_t addr); uint32_t __FASTCALL read_dma_data8(uint32_t addr); diff --git a/source/src/vm/fm7/fm8_mainio.cpp b/source/src/vm/fm7/fm8_mainio.cpp index e8d7b92e3..4621514e9 100644 --- a/source/src/vm/fm7/fm8_mainio.cpp +++ b/source/src/vm/fm7/fm8_mainio.cpp @@ -28,7 +28,7 @@ #include "./bubblecasette.h" namespace FM7 { -FM8_MAINIO::FM8_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : FM7_MAINIO(parent_vm, parent_emu) +FM8_MAINIO::FM8_MAINIO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : FM7_MAINIO(parent_vm, parent_emu) { psg = NULL; bubble_casette[0] = NULL; @@ -62,6 +62,7 @@ void FM8_MAINIO::reset() { FM7_MAINIO::reset(); cancel_event(this, event_timerirq); + event_timerirq = -1; } uint8_t FM8_MAINIO::get_port_fd00(void) diff --git a/source/src/vm/fm7/fm8_mainio.h b/source/src/vm/fm7/fm8_mainio.h index bcdbadd54..3505be546 100644 --- a/source/src/vm/fm7/fm8_mainio.h +++ b/source/src/vm/fm7/fm8_mainio.h @@ -48,14 +48,14 @@ class FM8_MAINIO : public FM7_MAINIO { uint8_t get_extirq_whg(void) override; uint8_t get_extirq_thg(void) override; public: - FM8_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu); + FM8_MAINIO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~FM8_MAINIO(); void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void reset() override; void initialize(); void update_config(); diff --git a/source/src/vm/fm7/fm_bubblecasette.cpp b/source/src/vm/fm7/fm_bubblecasette.cpp index f89b0f0a9..9c4c39e28 100644 --- a/source/src/vm/fm7/fm_bubblecasette.cpp +++ b/source/src/vm/fm7/fm_bubblecasette.cpp @@ -13,7 +13,7 @@ namespace FM7 { -BUBBLECASETTE::BUBBLECASETTE(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu) +BUBBLECASETTE::BUBBLECASETTE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE *parent_emu) : DEVICE(parent_vm, parent_emu) { fio = NULL; memset(image_path, 0x00, _MAX_PATH * sizeof(_TCHAR)); diff --git a/source/src/vm/fm7/hd6844.h b/source/src/vm/fm7/hd6844.h index 0925c256b..a011774df 100644 --- a/source/src/vm/fm7/hd6844.h +++ b/source/src/vm/fm7/hd6844.h @@ -14,8 +14,6 @@ #include "../device.h" -class EMU; -class VM; enum { HD6844_EVENT_START_TRANSFER = 0, HD6844_EVENT_DO_TRANSFER = 4, @@ -51,9 +49,9 @@ enum { HD6844_ACK_BUSREQ_HOST, }; -class VM; -class EMU; -class HD6844: public DEVICE { +class VM_TEMPLATE; +class EMU_TEMPLATE; +class DLL_PREFIX HD6844: public DEVICE { protected: // HACKs bool __USE_CHAINING; @@ -92,7 +90,7 @@ class HD6844: public DEVICE { void do_transfer_end(int ch); void do_irq(void); public: - HD6844(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu) + HD6844(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { int i; for(i = 0; i < 4; i++) { @@ -103,7 +101,7 @@ class HD6844: public DEVICE { set_device_name(_T("HD6844 DMAC")); } ~HD6844(){} - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_data8(uint32_t id, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); diff --git a/source/src/vm/fm7/jcommcard.cpp b/source/src/vm/fm7/jcommcard.cpp index 7cfa31ec7..ec80242ad 100644 --- a/source/src/vm/fm7/jcommcard.cpp +++ b/source/src/vm/fm7/jcommcard.cpp @@ -5,9 +5,9 @@ * Based on XM7 L70 , with permittion from Ryu Takegami. */ -#include "vm.h" + #include "../../fileio.h" -#include "emu.h" +#include "emu_template.h" #include "fm7_common.h" @@ -16,7 +16,7 @@ namespace FM7 { -FM7_JCOMMCARD::FM7_JCOMMCARD(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu) +FM7_JCOMMCARD::FM7_JCOMMCARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { n_bank = 0; rcb_address = 0; diff --git a/source/src/vm/fm7/jcommcard.h b/source/src/vm/fm7/jcommcard.h index df32624db..5d9d296ec 100644 --- a/source/src/vm/fm7/jcommcard.h +++ b/source/src/vm/fm7/jcommcard.h @@ -36,7 +36,7 @@ class FM7_JCOMMCARD : public DEVICE { uint8_t p_ram[0x2000]; public: - FM7_JCOMMCARD(VM_TEMPLATE* parent_vm, EMU *parent_emu); + FM7_JCOMMCARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~FM7_JCOMMCARD(); void initialize(void); void release(void); diff --git a/source/src/vm/fm7/joystick.cpp b/source/src/vm/fm7/joystick.cpp index d73766a13..d357c080b 100644 --- a/source/src/vm/fm7/joystick.cpp +++ b/source/src/vm/fm7/joystick.cpp @@ -13,12 +13,12 @@ #include "../ym2203.h" #include "./joystick.h" #include "../../config.h" -#include "../../emu.h" +//#include "../../emu.h" namespace FM7 { -JOYSTICK::JOYSTICK(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu) +JOYSTICK::JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { rawdata = NULL; mouse_state = NULL; diff --git a/source/src/vm/fm7/joystick.h b/source/src/vm/fm7/joystick.h index 6ab9987c0..ff9816667 100644 --- a/source/src/vm/fm7/joystick.h +++ b/source/src/vm/fm7/joystick.h @@ -40,7 +40,7 @@ class JOYSTICK : public DEVICE { void update_strobe(bool flag); uint32_t mouse_type; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU *parent_emu); + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~JOYSTICK(); void initialize(void); @@ -50,7 +50,7 @@ class JOYSTICK : public DEVICE { uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_data8(uint32_t addr, uint32_t data); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void reset(void); void update_config(); diff --git a/source/src/vm/fm7/kanjirom.cpp b/source/src/vm/fm7/kanjirom.cpp index 32584eaaa..2e8decf96 100644 --- a/source/src/vm/fm7/kanjirom.cpp +++ b/source/src/vm/fm7/kanjirom.cpp @@ -6,15 +6,13 @@ * Feb 11, 2015 : Initial */ -#include "vm.h" #include "../../fileio.h" -#include "emu.h" #include "fm7_common.h" #include "kanjirom.h" namespace FM7 { -KANJIROM::KANJIROM(VM_TEMPLATE* parent_vm, EMU* parent_emu, bool type_2std): DEVICE(parent_vm, parent_emu) +KANJIROM::KANJIROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu, bool type_2std): DEVICE(parent_vm, parent_emu) { FILEIO *fio; read_ok = false; diff --git a/source/src/vm/fm7/kanjirom.h b/source/src/vm/fm7/kanjirom.h index 90d5d555e..6fa9b41a1 100644 --- a/source/src/vm/fm7/kanjirom.h +++ b/source/src/vm/fm7/kanjirom.h @@ -13,8 +13,8 @@ #include "fm7_common.h" #include "../device.h" -class EMU; -class VM; +class EMU_TEMPLATE; +class VM_TEMPLATE; namespace FM7 { @@ -26,7 +26,7 @@ class KANJIROM: public DEVICE { pair32_t kanjiaddr; public: - KANJIROM(VM_TEMPLATE* parent_vm, EMU* parent_emu, bool type_2std); + KANJIROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu, bool type_2std); ~KANJIROM(); void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); diff --git a/source/src/vm/fm7/keyboard.cpp b/source/src/vm/fm7/keyboard.cpp index 3dad36c52..c6b795bde 100644 --- a/source/src/vm/fm7/keyboard.cpp +++ b/source/src/vm/fm7/keyboard.cpp @@ -7,7 +7,6 @@ */ #include "vm.h" -#include "emu.h" #include "../../fifo.h" #include "../device.h" @@ -1212,7 +1211,7 @@ uint32_t KEYBOARD::get_vk_by_scancode(uint32_t scancode) } #endif -KEYBOARD::KEYBOARD(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu) +KEYBOARD::KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { #if defined(_FM77AV_VARIANTS) beep = NULL; diff --git a/source/src/vm/fm7/mainmem_mmr.cpp b/source/src/vm/fm7/mainmem_mmr.cpp index 351ac1390..ead55ba62 100644 --- a/source/src/vm/fm7/mainmem_mmr.cpp +++ b/source/src/vm/fm7/mainmem_mmr.cpp @@ -6,7 +6,6 @@ * */ #include "vm.h" -#include "emu.h" #include "fm7_mainmem.h" namespace FM7 { diff --git a/source/src/vm/fm7/mainmem_page2.cpp b/source/src/vm/fm7/mainmem_page2.cpp index 1c41d790e..4168c94cd 100644 --- a/source/src/vm/fm7/mainmem_page2.cpp +++ b/source/src/vm/fm7/mainmem_page2.cpp @@ -6,7 +6,6 @@ * */ #include "vm.h" -#include "emu.h" #include "fm7_mainmem.h" #include "./kanjirom.h" diff --git a/source/src/vm/fm7/mainmem_readseq.cpp b/source/src/vm/fm7/mainmem_readseq.cpp index f87867ca4..1c4b0582e 100644 --- a/source/src/vm/fm7/mainmem_readseq.cpp +++ b/source/src/vm/fm7/mainmem_readseq.cpp @@ -6,7 +6,6 @@ * */ #include "vm.h" -#include "emu.h" #include "fm7_mainmem.h" #include "fm7_mainio.h" #include "fm7_display.h" diff --git a/source/src/vm/fm7/mainmem_utils.cpp b/source/src/vm/fm7/mainmem_utils.cpp index 2f2d47aaf..a690bccf6 100644 --- a/source/src/vm/fm7/mainmem_utils.cpp +++ b/source/src/vm/fm7/mainmem_utils.cpp @@ -6,7 +6,6 @@ * */ #include "vm.h" -#include "emu.h" #include "fm7_mainmem.h" namespace FM7 { @@ -405,13 +404,6 @@ void FM7_MAINMEM::release() defined(_FM77_VARIANTS) if(fm7_mainmem_extram != NULL) free(fm7_mainmem_extram); #endif -#if !defined(_FM77AV_VARIANTS) - int i; - for(i = 0; i < 4; i++) { - if(fm7_bootroms[i] != NULL) free(fm7_bootroms[i]); - fm7_bootroms[i] = NULL; - } -#endif #if defined(CAPABLE_DICTROM) write_bios(_T("USERDIC.DAT"), fm7_mainmem_learndata, 0x2000); #endif diff --git a/source/src/vm/fm7/mainmem_writeseq.cpp b/source/src/vm/fm7/mainmem_writeseq.cpp index 0136f5e99..82a2491f6 100644 --- a/source/src/vm/fm7/mainmem_writeseq.cpp +++ b/source/src/vm/fm7/mainmem_writeseq.cpp @@ -6,7 +6,6 @@ * */ #include "vm.h" -#include "emu.h" #include "fm7_mainmem.h" #include "fm7_mainio.h" #include "fm7_display.h" diff --git a/source/src/vm/fm7/mb61vh010.h b/source/src/vm/fm7/mb61vh010.h index 69e79e222..d2c6ce401 100644 --- a/source/src/vm/fm7/mb61vh010.h +++ b/source/src/vm/fm7/mb61vh010.h @@ -55,10 +55,7 @@ enum { EVENT_MB61VH010_BUSY_OFF }; -class VM; -class EMU; - -class MB61VH010: public DEVICE { +class DLL_PREFIX MB61VH010: public DEVICE { protected: DEVICE *target; @@ -111,7 +108,7 @@ class MB61VH010: public DEVICE { // LINE void __FASTCALL do_line(void); public: - MB61VH010(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu) + MB61VH010(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { target = NULL; direct_access_offset = 0; @@ -121,7 +118,7 @@ class MB61VH010: public DEVICE { bool process_state(FILEIO *state_fio, bool loading); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_data8(uint32_t id, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); uint32_t __FASTCALL read_signal(int id); diff --git a/source/src/vm/fm7/vram.cpp b/source/src/vm/fm7/vram.cpp index 5783300f7..373cc9c34 100644 --- a/source/src/vm/fm7/vram.cpp +++ b/source/src/vm/fm7/vram.cpp @@ -6,116 +6,82 @@ */ #include "vm.h" -#include "emu.h" #include "fm7_display.h" #if defined(_FM77L4) #include "../hd46505.h" #endif +#include "../../config.h" -extern config_t config; +//extern config_t config; namespace FM7 { -void DISPLAY::draw_screen() +void DISPLAY::clear_display(int dmode, int w, int h) { -//#if !defined(_FM77AV_VARIANTS) - this->draw_screen2(); -//#endif +#if defined(FIXED_FRAMEBUFFER_SIZE) + if((dmode != DISPLAY_MODE_8_400L) && (dmode != DISPLAY_MODE_1_400L)) { + h = h * 2; + } +#endif + for(int yy = 0; yy < h; yy++) { + scrntype_t *p; + p = emu->get_screen_buffer(yy); + if(p != NULL) { + memset(p, 0x00, sizeof(scrntype_t) * w); + } + } } -void DISPLAY::draw_screen2() +void DISPLAY::draw_window(int dmode, int y, int begin, int bytes, bool window_inv, bool scan_line) { - int y; - int x; - scrntype_t *p, *pp, *p2; - int yoff; - int yy; - int k; - //uint32_t rgbmask; - uint32_t yoff_d1, yoff_d2; - uint16_t wx_begin, wx_end, wy_low, wy_high; - bool scan_line = config.scan_line; - bool ff = force_update; - -#if defined(_FM77AV40EX) || defined(_FM77AV40SX) - { - wx_begin = window_xbegin; - wx_end = window_xend; - wy_low = window_low; - wy_high = window_high; - bool _flag = window_opened; - if((wx_begin < wx_end) && (wy_low < wy_high)) { - window_opened = true; - } else { - window_opened = false; - } - if(_flag != window_opened) { - vram_wrote_shadow = true; - } - } -#endif -// frame_skip_count_draw++; -#if defined(_FM77AV_VARIANTS) - yoff_d2 = 0; - yoff_d1 = 0; -#else - //if(!(vram_wrote_shadow)) return; - yoff_d1 = yoff_d2 = offset_point; -#endif - // Set blank - int ylines; - int xpixels; - switch(display_mode) { + _render_command_data_t cmd; + bool use_cmd = false; + int xzoom = 1; + uint32_t _offset_base = 0x4000; + int planes; + int shift; + int width; + switch(dmode) { case DISPLAY_MODE_8_200L: - xpixels = 640; - ylines = 200; + _offset_base = 0x4000; + use_cmd = true; + planes = 3; + shift = 5; + width = 80; break; +#if defined(_FM77AV_VARIANTS) + case DISPLAY_MODE_4096: + _offset_base = 0x2000; + xzoom = 2; + planes = 12; + shift = 5; + width = 40; + break; +# if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40) case DISPLAY_MODE_8_400L: - xpixels = 640; - ylines = 400; + _offset_base = 0x8000; + use_cmd = true; + planes = 3; + shift = 5; + width = 80; break; - default: - xpixels = 320; - ylines = 200; +# if defined(_FM77AV40EX) || defined(_FM77AV40SX) + case DISPLAY_MODE_256k: + _offset_base = 0x2000; + xzoom = 2; + planes = 20; + shift = 5; + width = 40; break; - } -# if !defined(FIXED_FRAMEBUFFER_SIZE) - emu->set_vm_screen_size(xpixels, ylines, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT); -# endif - emu->set_vm_screen_lines(ylines); - if(!crt_flag) { - if(crt_flag_bak) { - scrntype_t *ppp; -#if !defined(FIXED_FRAMEBUFFER_SIZE) - for(y = 0; y < ylines; y += 8) { - for(yy = 0; yy < 8; yy++) { - vram_draw_table[y + yy] = false; - ppp = emu->get_screen_buffer(y + yy); - if(ppp != NULL) memset(ppp, 0x00, xpixels * sizeof(scrntype_t)); - } - } -#else - for(y = 0; y < 400; y += 8) { - for(yy = 0; yy < 8; yy++) { - vram_draw_table[y + yy] = false; - ppp = emu->get_screen_buffer(y + yy); - if(ppp != NULL) memset(ppp, 0x00, 640 * sizeof(scrntype_t)); - } - } +# endif +# endif #endif - - } - crt_flag_bak = crt_flag; + default: return; + break; } - crt_flag_bak = crt_flag; - if(!(vram_wrote_shadow | ff)) return; - vram_wrote_shadow = false; - if(display_mode == DISPLAY_MODE_8_200L) { - _render_command_data_t cmd; - uint32_t yoff_d = 0; - int ii; - yoff = 0; + if(use_cmd) { + memset(&cmd, 0x00, sizeof(_render_command_data_t)); #if defined(USE_GREEN_DISPLAY) if(use_green_monitor) { cmd.palette = dpalette_pixel_green; @@ -125,524 +91,363 @@ void DISPLAY::draw_screen2() #else cmd.palette = dpalette_pixel; #endif - for(int i = 0; i < 3; i++) { - cmd.data[i] = gvram_shadow; - cmd.baseaddress[i] = i * 0x4000; - cmd.voffset[i] = yoff; - cmd.is_render[i] = false; - } if(!multimode_dispflags[0]) cmd.is_render[0] = true; if(!multimode_dispflags[1]) cmd.is_render[1] = true; if(!multimode_dispflags[2]) cmd.is_render[2] = true; cmd.bit_trans_table[0] = (_bit_trans_table_t*)(&(bit_trans_table_2[0][0])); // B cmd.bit_trans_table[1] = (_bit_trans_table_t*)(&(bit_trans_table_1[0][0])); // R cmd.bit_trans_table[2] = (_bit_trans_table_t*)(&(bit_trans_table_0[0][0])); // G - cmd.xzoom = 1; - cmd.addrmask = 0x3fff; - cmd.addrmask2 = 0x3fff; - cmd.begin_pos = 0; - cmd.shift = 5; - cmd.render_width = 80; - for(y = 0; y < 200; y += 8) { - for(yy = 0; yy < 8; yy++) { - - if(!(vram_draw_table[y + yy] | ff)) continue; - vram_draw_table[y + yy] = false; + for(int i = 0; i < 3; i++) { + cmd.data[i] = gvram_shadow; + cmd.baseaddress[i] = (i * _offset_base) + yoff_d; + cmd.voffset[i] = y * width; + } + cmd.xzoom = xzoom; + cmd.addrmask = _offset_base - 1; + cmd.addrmask2 = _offset_base - 1; + cmd.render_width = bytes; + cmd.begin_pos = begin; + cmd.shift = shift; + } + scrntype_t *p; + scrntype_t *pp; + if(dmode == DISPLAY_MODE_8_400L) { +#if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40) + p = emu->get_screen_buffer(y); + if(p == NULL) return; + Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false); +#endif + } else { #if !defined(FIXED_FRAMEBUFFER_SIZE) - p = emu->get_screen_buffer(y + yy); - p2 = NULL; + p = emu->get_screen_buffer(y); + pp = NULL; #else - p = emu->get_screen_buffer((y + yy) * 2); - p2 = emu->get_screen_buffer((y + yy) * 2 + 1); + p = emu->get_screen_buffer(y << 1); + pp = emu->get_screen_buffer((y << 1) + 1); #endif - if(p == NULL) continue; - yoff = (y + yy) * 80; - for(int i = 0; i < 3; i++) { - cmd.voffset[i] = yoff; + if(p == NULL) return; + switch(dmode) { + case DISPLAY_MODE_8_200L: + { + if(pp != NULL) { + Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(pp[cmd.begin_pos * 8]), scan_line); + } else { + Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false); } - -# if defined(_FM77AV40EX) || defined(_FM77AV40SX) - int dpage; - dpage = vram_display_block; - bool window_inv = false; - if(window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy))) { - if((wx_begin > 0) && (wx_begin < wx_end) && (wx_begin < 80)) { - // Window : left - cmd.begin_pos = 0; - window_inv = false; - int _wend = wx_end; - if(_wend >= 80) _wend = 80; - cmd.render_width = wx_begin; - yoff_d = (dpage != 0) ? 0x18000 : 0x00000; -#if defined(_FM77AV_VARIANTS) - if(display_page_bak == 1) yoff_d += 0xc000; -#endif - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x4000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, p, p2, scan_line); - - // Center - cmd.begin_pos = wx_begin; - cmd.render_width = _wend - wx_begin; - yoff_d = (dpage != 0) ? 0x00000 : 0x18000; -#if defined(_FM77AV_VARIANTS) - if(display_page_bak == 1) yoff_d += 0xc000; -#endif - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x4000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]) , scan_line); - // Right - if(wx_end < 80) { - cmd.begin_pos = wx_end; - cmd.render_width = 80 - wx_end; - yoff_d = (dpage != 0) ? 0x18000 : 0x00000; -#if defined(_FM77AV_VARIANTS) - if(display_page_bak == 1) yoff_d += 0xc000; -#endif - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x4000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]), scan_line); - } -#if defined(FIXED_FRAMEBUFFER_SIZE) - //CopyDrawnData(p, p2, 80, scan_line); -#endif - continue; - } else if((wx_begin <= 0) && (wx_begin < wx_end) && (wx_end >= 0)) { - // Left - cmd.begin_pos = 0; - cmd.render_width = wx_end; - yoff_d = (dpage != 0) ? 0x00000 : 0x18000; -#if defined(_FM77AV_VARIANTS) - if(display_page_bak == 1) yoff_d += 0xc000; -#endif - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x4000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - if(cmd.render_width > 0) Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]), scan_line); - // Right - if(wx_end < 80) { - cmd.begin_pos = wx_end; - cmd.render_width = 80 - wx_end; - yoff_d = (dpage != 0) ? 0x18000 : 0x00000; + } + break; #if defined(_FM77AV_VARIANTS) - if(display_page_bak == 1) yoff_d += 0xc000; -#endif - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x4000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), &(p2[cmd.begin_pos * 8]), scan_line); - } -#if defined(FIXED_FRAMEBUFFER_SIZE) -// CopyDrawnData(p, p2, 80, scan_line); -#endif - continue; - } + case DISPLAY_MODE_4096: + { + uint32_t mask = 0x000; + if(!multimode_dispflags[0]) mask = 0x00f; + if(!multimode_dispflags[1]) mask = mask | 0x0f0; + if(!multimode_dispflags[2]) mask = mask | 0xf00; + if(pp != NULL) pp = &(pp[begin]); + p = &(p[begin]); + uint32_t yoff = y * 40 + begin; + for(int x = begin; x < (begin + bytes); x++) { + GETVRAM_4096(yoff, p, pp, mask, window_inv, scan_line); +# if defined(FIXED_FRAMEBUFFER_SIZE) + p += 16; + if(pp != NULL) pp += 16; +# else + p += 8; +# endif + yoff++; } -#endif - //cmd.begin_pos = 0; - //cmd.render_width = 80; -# if defined(_FM77AV40EX) || defined(_FM77AV40SX) - yoff_d = (dpage != 0) ? 0x18000 : 0x00000; -#else -// yoff_d = 0; -#endif -#if defined(_FM77AV_VARIANTS) - if(display_page_bak == 1) yoff_d += 0xc000; - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x4000); + } + break; +# if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40) + case DISPLAY_MODE_256k: + { + uint32_t yoff = y * 40; + if(pp != NULL) pp = &(pp[begin]); + p = &(p[begin]); + for(int x = begin; x < (begin + bytes); x++) { + GETVRAM_256k(yoff + x, p, pp, scan_line); +# if defined(FIXED_FRAMEBUFFER_SIZE) + p += 16; + if(pp != NULL) pp += 16; +# else + p += 8; +# endif } -#else -// for(int i = 0; i < 3; i++) { -// cmd.baseaddress[i] = i * 0x4000; -// } -#endif - - Render8Colors_Line(&cmd, p, p2, scan_line); -#if defined(FIXED_FRAMEBUFFER_SIZE) - //CopyDrawnData(p, p2, 80, scan_line); -#endif } + break; +# endif +# endif + default: + break; } - if(ff) force_update = false; - return; - } + } +} + #if defined(_FM77L4) - if(display_mode == DISPLAY_MODE_1_400L) { - int ii; - uint8_t *regs = l4crtc->get_regs(); - cursor_start = (int)(regs[10] & 0x1f); - cursor_end = (int)(regs[11] & 0x1f); - cursor_type = (int)((regs[10] & 0x60) >> 5); - text_xmax = (int)((uint16_t)regs[1] << 1); - text_lines = (int)((regs[9] & 0x1f) + 1); - text_ymax = (int)(regs[6] & 0x7f); - yoff = 0; - // Green display had only connected to FM-8, FM-7/NEW7 and FM-77. - for(y = 0; y < 400; y += 8) { - bool renderf = false; - uint32_t naddr; - uint8_t bitcode; - uint8_t charcode; - uint8_t attr_code; - scrntype_t on_color; - int xlim, ylim; - bool do_green; - if((y & 0x0f) == 0) { - for(yy = 0; yy < 16; yy++) renderf |= vram_draw_table[y + yy]; - renderf = renderf | ff; - if(renderf) { - for(yy = 0; yy < 16; yy++) vram_draw_table[y + yy] = true; - } +void DISPLAY::draw_77l4_400l(bool ff) +{ + bool renderf = false; + uint32_t naddr; + uint8_t bitcode; + uint8_t charcode; + uint8_t attr_code; + scrntype_t on_color; + int xlim, ylim; + bool do_green; + uint8_t *regs = l4crtc->get_regs(); + cursor_start = (int)(regs[10] & 0x1f); + cursor_end = (int)(regs[11] & 0x1f); + cursor_type = (int)((regs[10] & 0x60) >> 5); + text_xmax = (int)((uint16_t)regs[1] << 1); + text_lines = (int)((regs[9] & 0x1f) + 1); + text_ymax = (int)(regs[6] & 0x7f); + int yoff = 0; + scrntype_t *p; + for(int y =0; y < 400; y+= 8) { + renderf = false; + if((y & 0x0f) == 0) { + for(int yy = 0; yy < 16; yy++) renderf |= vram_draw_table[y + yy]; + renderf = renderf | ff; + if(renderf) { + for(int yy = 0; yy < 16; yy++) vram_draw_table[y + yy] = true; } - if(use_green_monitor) { - for(yy = 0; yy < 8; yy++) { - if(!(vram_draw_table[y + yy] | ff)) continue; - vram_draw_table[y + yy] = false; - p = emu->get_screen_buffer(y + yy); - if(p == NULL) continue; - yoff = (y + yy) * 80; - for(x = 0; x < 10; x++) { - for(ii = 0; ii < 8; ii++) { - GETVRAM_1_400L_GREEN(yoff + ii, p); - p += 8; - } - yoff += 8; + } + if(use_green_monitor) { + for(int yy = 0; yy < 8; yy++) { + if(!(vram_draw_table[y + yy] | ff)) continue; + vram_draw_table[y + yy] = false; + p = emu->get_screen_buffer(y + yy); + if(p == NULL) continue; + yoff = (y + yy) * 80; + for(int x = 0; x < 10; x++) { + for(int ii = 0; ii < 8; ii++) { + GETVRAM_1_400L_GREEN(yoff + ii, p); + p += 8; } + yoff += 8; } - do_green = true; - } else { - for(yy = 0; yy < 8; yy++) { - if(!(vram_draw_table[y + yy] | ff)) continue; - vram_draw_table[y + yy] = false; - p = emu->get_screen_buffer(y + yy); - if(p == NULL) continue; - yoff = (y + yy) * 80; - for(x = 0; x < 10; x++) { - for(ii = 0; ii < 8; ii++) { - GETVRAM_1_400L(yoff + ii, p); - p += 8; - } - yoff += 8; + } + do_green = true; + } else { + for(int yy = 0; yy < 8; yy++) { + if(!(vram_draw_table[y + yy] | ff)) continue; + vram_draw_table[y + yy] = false; + p = emu->get_screen_buffer(y + yy); + if(p == NULL) continue; + yoff = (y + yy) * 80; + for(int x = 0; x < 10; x++) { + for(int ii = 0; ii < 8; ii++) { + GETVRAM_1_400L(yoff + ii, p); + p += 8; } + yoff += 8; } - do_green = false; } - // Draw Text - if(renderf) { - bool reverse; - bool display_char; - int raster; - bool cursor_rev; - uint8_t bitdata; - if(text_width40) { - xlim = 40; - } else { - xlim = 80; - } + do_green = false; + } + // Draw Text + if(renderf) { + bool reverse; + bool display_char; + int raster; + bool cursor_rev; + uint8_t bitdata; + if(text_width40) { + xlim = 40; + } else { + xlim = 80; + } - for(x = 0; x < xlim; x++) { - naddr = (text_start_addr.w.l + ((y / text_lines) * text_xmax + x) * 2) & 0x0ffe; - charcode = text_vram[naddr]; - attr_code = text_vram[naddr + 1]; + for(int x = 0; x < xlim; x++) { + naddr = (text_start_addr.w.l + ((y / text_lines) * text_xmax + x) * 2) & 0x0ffe; + charcode = text_vram[naddr]; + attr_code = text_vram[naddr + 1]; - on_color = GETVRAM_TEXTCOLOR(attr_code, do_green); + on_color = GETVRAM_TEXTCOLOR(attr_code, do_green); - display_char = ((attr_code & 0x10) == 0); - reverse = ((attr_code & 0x08) != 0); + display_char = ((attr_code & 0x10) == 0); + reverse = ((attr_code & 0x08) != 0); - for(yy = 0; yy < 16; yy++) { - raster = y % text_lines; - bitdata = 0x00; - p = emu->get_screen_buffer(y + yy); - if(p == NULL) continue; - if((raster < 16) && (display_char || text_blink)) { - bitdata = subsys_cg_l4[(uint32_t)charcode * 16 + (uint32_t)raster]; - } - cursor_rev = false; - if((naddr == (uint32_t)(cursor_addr.w.l)) && (cursor_type != 1) && - (text_blink || (cursor_type == 0))) { - if((raster >= cursor_start) && (raster <= cursor_end)) { - cursor_rev = true; - } + for(int yy = 0; yy < 16; yy++) { + raster = y % text_lines; + bitdata = 0x00; + p = emu->get_screen_buffer(y + yy); + if(p == NULL) continue; + if((raster < 16) && (display_char || text_blink)) { + bitdata = subsys_cg_l4[(uint32_t)charcode * 16 + (uint32_t)raster]; + } + cursor_rev = false; + if((naddr == (uint32_t)(cursor_addr.w.l)) && (cursor_type != 1) && + (text_blink || (cursor_type == 0))) { + if((raster >= cursor_start) && (raster <= cursor_end)) { + cursor_rev = true; } - bitdata = GETVRAM_TEXTPIX(bitdata, reverse, cursor_rev); - if(bitdata != 0) { - if(text_width40) { - scrntype_t *pp = &(p[x * 2]); - for(ii = 0; ii < 8; ii++) { - if((bitdata & 0x80) != 0) { - p[0] = on_color; - p[1] = on_color; - } - bitdata <<= 1; - p += 2; - } - } else { - scrntype_t *pp = &(p[x * 2]); - for(ii = 0; ii < 8; ii++) { - if((bitdata & 0x80) != 0) { - p[0] = on_color; - } - bitdata <<= 1; - p += 1; - } - } + } + bitdata = GETVRAM_TEXTPIX(bitdata, reverse, cursor_rev); + if(bitdata != 0) { + if(text_width40) { + scrntype_t *pp = &(p[x * 2]); + for(int ii = 0; ii < 8; ii++) { + if((bitdata & 0x80) != 0) { + p[0] = on_color; + p[1] = on_color; + } + bitdata <<= 1; + p += 2; + } + } else { + scrntype_t *pp = &(p[x * 2]); + for(int ii = 0; ii < 8; ii++) { + if((bitdata & 0x80) != 0) { + p[0] = on_color; + } + bitdata <<= 1; + p += 1; + } } } } } } - if(ff) force_update = false; - return; } +} #endif -# if defined(_FM77AV_VARIANTS) - if(display_mode == DISPLAY_MODE_4096) { - uint32_t mask = 0; - int ii; - yoff = 0; - if(!multimode_dispflags[0]) mask = 0x00f; - if(!multimode_dispflags[1]) mask = mask | 0x0f0; - if(!multimode_dispflags[2]) mask = mask | 0xf00; - for(y = 0; y < 200; y += 4) { - for(yy = 0; yy < 4; yy++) { - if(!(vram_draw_table[y + yy] | ff)) continue; - vram_draw_table[y + yy] = false; -#if !defined(FIXED_FRAMEBUFFER_SIZE) - p = emu->get_screen_buffer(y + yy); - p2 = NULL; -#else - p = emu->get_screen_buffer((y + yy) * 2 ); - p2 = emu->get_screen_buffer((y + yy) * 2 + 1); -#endif - if(p == NULL) continue; - yoff = (y + yy) * 40; -# if defined(_FM77AV40EX) || defined(_FM77AV40SX) - if(window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy))) { - for(x = 0; x < 40; x++) { - if((x >= wx_begin) && (x < wx_end)) { - GETVRAM_4096(yoff, p, p2, mask, true, scan_line); - } else { - GETVRAM_4096(yoff, p, p2, mask, false, scan_line); - } -#if defined(FIXED_FRAMEBUFFER_SIZE) - p2 += 16; - p += 16; -#else - p += 8; +void DISPLAY::draw_screen() +{ + uint16_t wx_begin = -1, wx_end = -1, wy_low = 1024, wy_high = -1; + bool scan_line = config.scan_line; + bool ff = force_update; + int dmode = display_mode; + yoff_d = 0; +#if defined(_FM77AV40EX) || defined(_FM77AV40SX) + { + wx_begin = window_xbegin; + wx_end = window_xend; + wy_low = window_low; + wy_high = window_high; + bool _flag = window_opened; + if((wx_begin < wx_end) && (wy_low < wy_high)) { + window_opened = true; + } else { + window_opened = false; + } + if(_flag != window_opened) { + vram_wrote_shadow = true; + } + } #endif - yoff++; - } - } else -# endif - { - for(x = 0; x < 5; x++) { - for(ii = 0; ii < 8; ii++) { - GETVRAM_4096(yoff + ii, p, p2, mask, false, scan_line); -#if defined(FIXED_FRAMEBUFFER_SIZE) - p2 += 16; - p += 16; +#if defined(_FM77AV_VARIANTS) + yoff_d2 = 0; + yoff_d1 = 0; #else - p += 8; + //if(!(vram_wrote_shadow)) return; + yoff_d1 = yoff_d2 = offset_point; #endif - } - yoff += 8; - } - } - } - + int ylines; + int xpixels; + switch(dmode) { + case DISPLAY_MODE_8_200L: + xpixels = 640; + ylines = 200; + break; + case DISPLAY_MODE_1_400L: + case DISPLAY_MODE_8_400L: + xpixels = 640; + ylines = 400; + break; + default: + xpixels = 320; + ylines = 200; + break; + } +# if !defined(FIXED_FRAMEBUFFER_SIZE) + emu->set_vm_screen_size(xpixels, ylines, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT); +# endif + emu->set_vm_screen_lines(ylines); + if(!crt_flag) { + if(crt_flag_bak) { + clear_display(dmode, xpixels, ylines); } + crt_flag_bak = crt_flag; if(ff) force_update = false; return; } -# if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) - else if(display_mode == DISPLAY_MODE_8_400L) { - _render_command_data_t cmd; - int ii; - yoff = 0; - cmd.palette = dpalette_pixel; - for(int i = 0; i < 3; i++) { - cmd.data[i] = gvram_shadow; - cmd.baseaddress[i] = i * 0x8000; - cmd.voffset[i] = yoff; - cmd.is_render[i] = false; - } - if(!multimode_dispflags[0]) cmd.is_render[0] = true; - if(!multimode_dispflags[1]) cmd.is_render[1] = true; - if(!multimode_dispflags[2]) cmd.is_render[2] = true; - cmd.bit_trans_table[0] = (_bit_trans_table_t*)(&(bit_trans_table_2[0][0])); // B - cmd.bit_trans_table[1] = (_bit_trans_table_t*)(&(bit_trans_table_1[0][0])); // R - cmd.bit_trans_table[2] = (_bit_trans_table_t*)(&(bit_trans_table_0[0][0])); // G - cmd.xzoom = 1; - cmd.addrmask = 0x7fff; - cmd.addrmask2 = 0x7fff; - cmd.begin_pos = 0; - cmd.shift = 5; - cmd.render_width = 80; - for(y = 0; y < 400; y += 8) { - for(yy = 0; yy < 8; yy++) { - if(!(vram_draw_table[y + yy] | ff)) continue; - vram_draw_table[y + yy] = false; + crt_flag_bak = crt_flag; + if(!(vram_wrote_shadow | ff)) return; + vram_wrote_shadow = false; - p = emu->get_screen_buffer(y + yy); - if(p == NULL) continue; - pp = p; - yoff = (y + yy) * 80; - for(int i = 0; i < 3; i++) { - cmd.voffset[i] = yoff; - } + int wpixels = xpixels >> 3; +#if defined(_FM77L4) + if(dmode == DISPLAY_MODE_1_400L) { + draw_77l4_400l(ff); + if(ff) force_update = false; + return; + } +#endif + for(int y = 0; y < ylines; y += 8) { + for(int yy = 0; yy < 8; yy++) { + if(!(vram_draw_table[y + yy] | ff)) continue; + vram_draw_table[y + yy] = false; +# if defined(_FM77AV40EX) || defined(_FM77AV40SX) || defined(_FM77AV40) int dpage; - bool window_inv = false; - uint32_t yoff_d; dpage = vram_display_block; + bool window_inv = false; # if defined(_FM77AV40EX) || defined(_FM77AV40SX) - if(window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy))) { - if((wx_begin > 0) && (wx_begin < wx_end) && (wx_begin < 80)) { - // Window : left - cmd.begin_pos = 0; - window_inv = false; - int _wend = wx_end; - if(_wend >= 80) _wend = 80; - cmd.render_width = wx_begin; + if((window_opened && (wy_low <= (y + yy)) && (wy_high > (y + yy))) + && (dmode != DISPLAY_MODE_256k)) { + if((wx_begin > 0) && (wx_begin < wx_end) && (wx_begin < wpixels)) { yoff_d = (dpage != 0) ? 0x18000 : 0x00000; - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x8000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, p, NULL, false); - - // Center - cmd.begin_pos = wx_begin; - cmd.render_width = _wend - wx_begin; + if(display_page_bak == 1) yoff_d += 0xc000; + draw_window(dmode, yy + y, 0, wx_begin, + false, scan_line); yoff_d = (dpage != 0) ? 0x00000 : 0x18000; if(display_page_bak == 1) yoff_d += 0xc000; - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x8000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false); - // Right - if(wx_end < 80) { - cmd.begin_pos = wx_end; - cmd.render_width = 80 - wx_end; + draw_window(dmode, yy + y, + wx_begin, ((wx_end >= wpixels) ? wpixels : wx_end) - wx_begin, + true, scan_line); + if(wx_end < wpixels) { yoff_d = (dpage != 0) ? 0x18000 : 0x00000; - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x8000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false); + if(display_page_bak == 1) yoff_d += 0xc000; + draw_window(dmode, yy + y, wx_end, wpixels - wx_end, + false, scan_line); } - continue; - } else if((wx_begin <= 0) && (wx_begin < wx_end) && (wx_end >= 0)) { - // Left - cmd.begin_pos = 0; - cmd.render_width = wx_end; + } else { yoff_d = (dpage != 0) ? 0x00000 : 0x18000; - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x8000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - if(cmd.render_width > 0) Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false); - // Right - if(wx_end < 80) { - cmd.begin_pos = wx_end; - cmd.render_width = 80 - wx_end; + if(display_page_bak == 1) yoff_d += 0xc000; + draw_window(dmode, yy + y, 0, wx_end, + false, scan_line); + if(wx_end < wpixels) { yoff_d = (dpage != 0) ? 0x18000 : 0x00000; - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x8000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false); + if(display_page_bak == 1) yoff_d += 0xc000; + draw_window(dmode, yy + y, wx_end , wpixels - wx_end, + true, scan_line); } - continue; - } - } + } + } else # endif - // Not Opened - cmd.begin_pos = 0; - cmd.render_width = 80; - yoff_d = (dpage != 0) ? 0x18000 : 0x00000; - for(int i = 0; i < 3; i++) { - cmd.baseaddress[i] = yoff_d + (i * 0x8000); - } - if(cmd.render_width > 0) { - if(cmd.render_width > 80) cmd.render_width = 80; - } - Render8Colors_Line(&cmd, &(p[cmd.begin_pos * 8]), NULL, false); - } - } - if(ff) force_update = false; - return; - } else if(display_mode == DISPLAY_MODE_256k) { - int ii; - //rgbmask = ~multimode_dispmask; - // - for(y = 0; y < 200; y += 4) { - for(yy = 0; yy < 4; yy++) { - if(!(vram_draw_table[y + yy] | ff)) continue; - vram_draw_table[y + yy] = false; -#if !defined(FIXED_FRAMEBUFFER_SIZE) - p = emu->get_screen_buffer(y + yy); - p2 = NULL; -#else - p = emu->get_screen_buffer((y + yy) * 2 ); - p2 = emu->get_screen_buffer((y + yy) * 2 + 1); -#endif - if(p == NULL) continue; - pp = p; - yoff = (y + yy) * 40; { - for(x = 0; x < 5; x++) { - for(ii = 0; ii < 8; ii++) { - GETVRAM_256k(yoff + ii, p, p2, scan_line); -#if !defined(FIXED_FRAMEBUFFER_SIZE) - p += 8; + + yoff_d = (dpage != 0) ? 0x18000 : 0x00000; + if(display_page_bak == 1) yoff_d += 0xc000; + draw_window(dmode, yy + y, 0, wpixels, false, scan_line); + } + // Copy line +#elif defined(_FM77AV_VARIANTS) + yoff_d = 0; + if(display_page_bak == 1) yoff_d += 0xc000; + draw_window(dmode, yy + y, 0, wpixels, false, scan_line); #else - p += 16; - p2 += 16; + yoff_d = 0; + draw_window(dmode, yy + y, 0, wpixels, false, scan_line); #endif - } - yoff += 8; - } - } - } } - if(ff) force_update = false; - return; } -# endif // _FM77AV40 -# endif //_FM77AV_VARIANTS + if(ff) force_update = false; + return; } + bool DISPLAY::screen_update(void) { if(crt_flag) { @@ -741,7 +546,6 @@ uint8_t DISPLAY::GETVRAM_TEXTPIX(uint8_t bitdata, bool reverse, bool cursor_rev) void DISPLAY::GETVRAM_1_400L(int yoff, scrntype_t *p) { uint8_t pixel; - uint32_t yoff_d; if(p == NULL) return; yoff_d = yoff & 0x7fff; pixel = gvram_shadow[yoff_d]; @@ -764,7 +568,6 @@ __DECL_VECTORIZED_LOOP void DISPLAY::GETVRAM_1_400L_GREEN(int yoff, scrntype_t *p) { uint8_t pixel; - uint32_t yoff_d; if(p == NULL) return; yoff_d = yoff & 0x7fff; pixel = gvram_shadow[yoff_d]; @@ -799,8 +602,6 @@ void DISPLAY::GETVRAM_4096(int yoff, scrntype_t *p, scrntype_t *px, scrntype_t b, r, g; uint32_t idx;; scrntype_t pixel; - uint32_t yoff_d1; - uint32_t yoff_d2; # if defined(_FM77AV40EX) || defined(_FM77AV40SX) int dpage = vram_display_block; # endif @@ -944,8 +745,6 @@ void DISPLAY::GETVRAM_256k(int yoff, scrntype_t *p, scrntype_t *px, bool scan_li uint32_t _bit; int _shift; int cp; - uint32_t yoff_d1; - uint32_t yoff_d2; if(p == NULL) return; r3 = g3 = b3 = 0; diff --git a/source/src/vm/fmgen/CMakeLists.txt b/source/src/vm/fmgen/CMakeLists.txt index 79e26eac4..b1f23dadd 100644 --- a/source/src/vm/fmgen/CMakeLists.txt +++ b/source/src/vm/fmgen/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 2.6) message("* vm/fmgen") -SET(THIS_LIB_VERSION 1.5.0) +SET(THIS_LIB_VERSION 1.10.1) add_definitions(-D__LIBFMGEN_VERSION=\"libCSPfmgen.${THIS_LIB_VERSION}\") SET(s_vm_fmgen_srcs @@ -14,28 +14,26 @@ SET(s_vm_fmgen_srcs ) if(WIN32) -#add_library(vm_fmgen -# ${s_vm_fmgen_srcs} -# ) + include (GenerateExportHeader) + add_library(CSPfmgen SHARED + ${s_vm_fmgen_srcs} + ) + target_link_libraries(CSPfmgen + PRIVATE CSPemu_utils + ) -include (GenerateExportHeader) -add_library(CSPfmgen SHARED - ${s_vm_fmgen_srcs} - ) -target_link_libraries(CSPfmgen - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPemu_utils.dll.a + set_target_properties(CSPfmgen PROPERTIES + SOVERSION ${THIS_LIB_VERSION} + VERSION ${THIS_LIB_VERSION} + LINK_INTERFACE_LIBRARIES "" ) -set_target_properties(CSPfmgen PROPERTIES - SOVERSION ${THIS_LIB_VERSION} - VERSION ${THIS_LIB_VERSION} - LINK_INTERFACE_LIBRARIES "" - ) -generate_export_header(CSPfmgen - BASE_NAME CSPfmgen - EXPORT_MACRO_NAME CSPfmgen_EXPORT - EXPORT_FILE_NAME CSPfmgen_Export.h - STATIC_DEFINE CSPfmgen_BUILT_AS_STATIC -) + generate_export_header(CSPfmgen + BASE_NAME CSPfmgen + EXPORT_MACRO_NAME CSPfmgen_EXPORT + EXPORT_FILE_NAME CSPfmgen_Export.h + STATIC_DEFINE CSPfmgen_BUILT_AS_STATIC + ) + set_std(CSPfmgen) else() if(USE_DEVICES_SHARED_LIB) @@ -47,9 +45,11 @@ else() VERSION ${THIS_LIB_VERSION} ) INSTALL(TARGETS CSPfmgen DESTINATION ${LIBCSP_INSTALL_DIR}) + set_std(CSPfmgen) else() add_library(fmgen STATIC ${s_vm_fmgen_srcs} ) + set_std(fmgen) endif() endif() diff --git a/source/src/vm/fmgen/opna.cpp b/source/src/vm/fmgen/opna.cpp index c75356062..c48cc018c 100644 --- a/source/src/vm/fmgen/opna.cpp +++ b/source/src/vm/fmgen/opna.cpp @@ -355,7 +355,6 @@ void OPN::SetReg(uint addr, uint data) ch[c].SetFB((data >> 3) & 7); ch[c].SetAlgorithm(data & 7); break; - default: if (c < 3) { @@ -2225,29 +2224,67 @@ void OPN2Base::Reset() { int i; + SetReg(0x27, 0x30); + prescale = 10; + SetPrescaler(0); OPNBase::Reset(); - for (i=0x20; i<0x28; i++) SetReg(i, 0); - for (i=0x30; i<0xc0; i++) SetReg(i, 0); - for (i=0x130; i<0x1c0; i++) SetReg(i, 0); - for (i=0x100; i<0x110; i++) SetReg(i, 0); - for (i=0x10; i<0x20; i++) SetReg(i, 0); + SetReg(0x27, 0x30); + SetReg(0x26, 0x00); + SetReg(0x25, 0x00); + SetReg(0x26, 0x00); + for (i=0; i<6; i++) { pan[i] = 3; ch[i].Reset(); } + // Reset sequence from Mame 0.216 + for(uint32_t ad = 0xb6; ad >= 0xb4; ad--) { + SetReg(ad, 0xc0); + SetReg(ad | 0x100, 0xc0); + } + for(uint32_t ad = 0xb2; ad >= 0x30; ad--) { + SetReg(ad, 0x00); + SetReg(ad | 0x100, 0x00); + } - stmask = ~0x1c; - statusnext = 0; + stmask = 0x7f; lfocount = 0; status = 0; + dac_enabled = false; + dac_data = 0; + UpdateStatus(); } +// vXP[ݒ +void OPN2Base::SetPrescaler(uint p) +{ + static const uint8 table2[8] = { 108, 77, 71, 67, 62, 44, 8, 5 }; + + prescale = 0; + uint fmclock = clock / 6 / 12; + rate = psgrate; + + // gƏo͎g̔ +// assert(fmclock < (0x80000000 >> FM_RATIOBITS)); + uint ratio = ((fmclock << FM_RATIOBITS) + rate/2) / rate; + + SetTimerPrescaler(6 * 12 * 2); +// MakeTimeTable(ratio); + chip.SetRatio(ratio); + psg.SetClock(clock / 4, psgrate); + + for (int i=0; i<8; i++) + { + lfotable[i] = (ratio << (2+FM_LFOCBITS-FM_RATIOBITS)) / table2[i]; + } +} + // --------------------------------------------------------------------------- // TvO[gύX // -bool OPN2Base::SetRate(uint c, uint r, bool) +bool OPN2Base::SetRate(uint c, uint r, bool b) { c /= 2; // ]łƂ̌݊dRgAEg悤 @@ -2275,42 +2312,56 @@ void OPN2Base::SetChannelMask(uint mask) void OPN2Base::SetReg(uint addr, uint data) { int c = addr & 3; + if(((addr & 0x0f0) >= 0x030) && (c == 3)) return; // NOOP switch (addr) { uint modified; - // Timer ----------------------------------------------------------------- - case 0x24: case 0x25: - SetTimerA(addr, data); - break; - - case 0x26: - SetTimerB(data); - break; - - case 0x27: - SetTimerControl(data); - break; + // LFO ------------------------------------------------------------------- + case 0x22: + modified = reg22 ^ data; + reg22 = data; + if (modified & 0x8) + lfocount = 0; + lfodcount = reg22 & 8 ? lfotable[reg22 & 7] : 0; + break; + // Timer ----------------------------------------------------------------- + case 0x24: case 0x25: + SetTimerA(addr, data); + break; + + case 0x26: + SetTimerB(data); + break; + + case 0x27: + SetTimerControl(data); + break; + // Misc ------------------------------------------------------------------ case 0x28: // Key On/Off - if ((data & 3) < 3) { - c = (data & 3) + (data & 4 ? 3 : 0); - ch[c].KeyControl(data >> 4); + uint8_t cc = data & 3; + if(cc == 3) break; + if((data & 0x04) != 0) cc += 3; + ch[cc].KeyControl(data >> 4); } break; // Status Mask ----------------------------------------------------------- case 0x29: - reg29 = data; +// reg29 = data; // UpdateStatus(); //? break; - + + // Prescaler ------------------------------------------------------------- + /* case 0x2d: case 0x2e: case 0x2f: SetPrescaler(addr-0x2d); break; + */ // F-Number -------------------------------------------------------------- case 0x1a0: case 0x1a1: case 0x1a2: @@ -2323,15 +2374,15 @@ void OPN2Base::SetReg(uint addr, uint data) case 0x1a4: case 0x1a5: case 0x1a6: c += 3; case 0xa4 : case 0xa5: case 0xa6: - fnum2[c] = uint8(data); + fnum2[c] = uint8(data) & 0x3f; break; case 0xa8: case 0xa9: case 0xaa: - fnum3[c] = data + fnum2[c+6] * 0x100; + fnum3[c] = ((fnum2[c + 6] & 0x07) * 0x100) + (data & 0xff); break; case 0xac : case 0xad: case 0xae: - fnum2[c+6] = uint8(data); + fnum2[c+6] = uint8(data) & 0x3f; break; // Algorithm ------------------------------------------------------------- @@ -2350,27 +2401,13 @@ void OPN2Base::SetReg(uint addr, uint data) ch[c].SetMS(data); break; - // LFO ------------------------------------------------------------------- - case 0x22: - modified = reg22 ^ data; - reg22 = data; - if (modified & 0x8) - lfocount = 0; - lfodcount = reg22 & 8 ? lfotable[reg22 & 7] : 0; - break; - - // PSG ------------------------------------------------------------------- - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: - break; - // F ------------------------------------------------------------------ default: if (c < 3) { if (addr & 0x100) c += 3; - OPNBase::SetParameter(&ch[c], addr, data); + OPNBase::SetParameter(&ch[c], addr & 0x2ff, data); } break; } @@ -2384,7 +2421,7 @@ void OPN2Base::SetStatus(uint bits) if (!(status & bits)) { // LOG2("SetStatus(%.2x %.2x)\n", bits, stmask); - status |= bits & stmask; + status |= (bits & stmask); UpdateStatus(); } // else @@ -2393,7 +2430,7 @@ void OPN2Base::SetStatus(uint bits) void OPN2Base::ResetStatus(uint bits) { - status &= ~bits; + status &= ~(bits & stmask); // LOG1("ResetStatus(%.2x)\n", bits); UpdateStatus(); } @@ -2401,7 +2438,7 @@ void OPN2Base::ResetStatus(uint bits) inline void OPN2Base::UpdateStatus() { // LOG2("%d:INT = %d\n", Diag::GetCPUTick(), (status & stmask & reg29) != 0); - Intr((status & stmask & reg29) != 0); + Intr((status & stmask) != 0); } // --------------------------------------------------------------------------- @@ -2425,8 +2462,8 @@ void OPN2Base::FMMix(Sample* buffer, int nsamples) } int act = (((ch[2].Prepare() << 2) | ch[1].Prepare()) << 2) | ch[0].Prepare(); - if (reg29 & 0x80) - act |= (ch[3].Prepare() | ((ch[4].Prepare() | (ch[5].Prepare() << 2)) << 2)) << 6; +// if (reg29 & 0x80) + act |= (ch[3].Prepare() | ((ch[4].Prepare() | (ch[5].Prepare() << 2)) << 2)) << 6; if (!(reg22 & 0x08)) act &= 0x555; @@ -2446,7 +2483,14 @@ void OPN2Base::MixSubSL(int activech, ISample** dest) if (activech & 0x010) (*dest[2] += ch[2].CalcL()); if (activech & 0x040) (*dest[3] += ch[3].CalcL()); if (activech & 0x100) (*dest[4] += ch[4].CalcL()); - if (activech & 0x400) (*dest[5] += ch[5].CalcL()); + if (activech & 0x400) { + ISample tmp = ((ISample) dac_data) << 5; + if ((dac_enabled)) { + (*dest[5] += tmp); + } else { + (*dest[5] += ch[5].CalcL()); + } + } } inline void OPN2Base::MixSubS(int activech, ISample** dest) @@ -2456,7 +2500,14 @@ inline void OPN2Base::MixSubS(int activech, ISample** dest) if (activech & 0x010) (*dest[2] += ch[2].Calc()); if (activech & 0x040) (*dest[3] += ch[3].Calc()); if (activech & 0x100) (*dest[4] += ch[4].Calc()); - if (activech & 0x400) (*dest[5] += ch[5].Calc()); + if (activech & 0x400) { + ISample tmp = ((ISample) dac_data) << 5; + if ((dac_enabled)) { + (*dest[5] += tmp); + } else { + (*dest[5] += ch[5].Calc()); + } + } } // --------------------------------------------------------------------------- @@ -2510,7 +2561,6 @@ void OPN2Base::Mix6(Sample* buffer, int nsamples, int activech) idest[3] = &ibuf[pan[3]]; idest[4] = &ibuf[pan[4]]; idest[5] = &ibuf[pan[5]]; - Sample* limit = buffer + nsamples * 2; for (Sample* dest = buffer; dest < limit; dest+=2) { @@ -2542,18 +2592,17 @@ bool OPN2Base::ProcessState(void *f, bool loading) state_fio->StateArray(fnum2, sizeof(fnum2), 1); state_fio->StateValue(reg22); state_fio->StateValue(reg29); + state_fio->StateValue(prescale); state_fio->StateValue(stmask); - state_fio->StateValue(statusnext); state_fio->StateValue(lfocount); state_fio->StateValue(lfodcount); state_fio->StateArray(fnum, sizeof(fnum), 1); state_fio->StateArray(fnum3, sizeof(fnum3), 1); if(loading) { - // Make force-restore around prescaler and timers. 20180625 K.O - uint bak = prescale; + uint8 v = prescale; prescale = 10; - SetPrescaler(bak); + SetPrescaler(v); // Re-Setting prescaler. } for(int i = 0; i < 6; i++) { if(!ch[i].ProcessState(f, loading)) { @@ -2629,14 +2678,23 @@ bool OPN2::SetRate(uint c, uint r, bool ipflag) void OPN2::SetReg(uint addr, uint data) { addr &= 0x1ff; +// printf("OPN2::SetReg(%.3x %.2x)\n", addr, data); switch (addr) { - case 0x29: - reg29 = data; -// UpdateStatus(); //? + case 0x2a: + { + int32 tmp = data & 0xff; + tmp = (tmp - 0x80) << 1; + dac_data = (dac_data & 1) | tmp; + } + break; + case 0x2b: + dac_enabled = ((data & 0x80) != 0); + break; + case 0x2c: // Test + dac_data = (dac_data & ~0x01) | (((data & 0x08) != 0) ? 1 : 0); break; - default: OPN2Base::SetReg(addr, data); break; diff --git a/source/src/vm/fmgen/opna.h b/source/src/vm/fmgen/opna.h index f72d3798b..158886c1d 100644 --- a/source/src/vm/fmgen/opna.h +++ b/source/src/vm/fmgen/opna.h @@ -106,7 +106,7 @@ namespace FM protected: void SetParameter(Channel4* ch, uint addr, uint data); - void SetPrescaler(uint p); + virtual void SetPrescaler(uint p); void RebuildTimeTable(); void Intr(bool value); @@ -248,8 +248,8 @@ namespace FM OPN2Base(); ~OPN2Base(); - uint ReadStatus() { return status & 0x03; } - uint ReadStatusEx(); + uint ReadStatus() { return status & 0x7f; } + uint ReadStatusEx() { return 0xff; } void SetChannelMask(uint mask); private: @@ -258,6 +258,7 @@ namespace FM protected: bool Init(uint c, uint r, bool); bool SetRate(uint c, uint r, bool); + virtual void SetPrescaler(uint p); void Reset(); void SetReg(uint addr, uint data); @@ -285,7 +286,6 @@ namespace FM uint reg29; // OPNA only? uint stmask; - uint statusnext; uint32 lfocount; uint32 lfodcount; @@ -294,6 +294,8 @@ namespace FM uint fnum3[3]; Channel4 ch[6]; + int32 dac_data; + bool dac_enabled; static void BuildLFOTable(); static int amtable[FM_LFOENTS]; @@ -453,7 +455,7 @@ namespace FM }; // YM2612/3438(OPN2) ---------------------------------------------------- - class OPN2 : public OPN2Base + class DLL_PREFIX OPN2 : public OPN2Base { public: OPN2(); @@ -476,7 +478,6 @@ namespace FM //void ResetStatus(uint bit); // `ԗp[N int32 mixc, mixc1; - }; } diff --git a/source/src/vm/fmr30/CMakeLists.txt b/source/src/vm/fmr30/CMakeLists.txt index 69e625568..c580431ce 100644 --- a/source/src/vm/fmr30/CMakeLists.txt +++ b/source/src/vm/fmr30/CMakeLists.txt @@ -1,16 +1,29 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/fmr30") +message("* vm/${EXE_NAME}") -add_library(vm_fmr30 - fmr30.cpp +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +add_library(vm_${EXE_NAME} + ../fmr50/bios.cpp + ../i8237.cpp + ../scsi_host.cpp + cmos.cpp floppy.cpp keyboard.cpp - memory.cpp + ./memory.cpp rtc.cpp serial.cpp system.cpp scsi.cpp timer.cpp -) \ No newline at end of file + + fmr30.cpp +) +if("${U_EXE_NAME}" STREQUAL "EMUFMR30_I86") + message("${U_EXE_NAME}") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I86) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR30_I286") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I286) +endif() diff --git a/source/src/vm/fmr30/cmos.h b/source/src/vm/fmr30/cmos.h index 1d13903d9..05934154a 100644 --- a/source/src/vm/fmr30/cmos.h +++ b/source/src/vm/fmr30/cmos.h @@ -23,7 +23,7 @@ class CMOS : public DEVICE bool modified; public: - CMOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMOS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMOS RAM")); } diff --git a/source/src/vm/fmr30/floppy.h b/source/src/vm/fmr30/floppy.h index 98f137c4f..5095b7b0d 100644 --- a/source/src/vm/fmr30/floppy.h +++ b/source/src/vm/fmr30/floppy.h @@ -32,7 +32,7 @@ class FLOPPY : public DEVICE void update_intr(); public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/fmr30/fmr30.cpp b/source/src/vm/fmr30/fmr30.cpp index 7f19f611e..001518335 100644 --- a/source/src/vm/fmr30/fmr30.cpp +++ b/source/src/vm/fmr30/fmr30.cpp @@ -17,9 +17,9 @@ #include "../i8251.h" #include "../i8253.h" #include "../i8259.h" -#if defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186) +#if defined(HAS_I86) #include "../i86.h" -#else +#elif defined(HAS_I286) #include "../i286.h" #endif #include "../io.h" @@ -60,7 +60,7 @@ using FMR30::TIMER; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -82,10 +82,11 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) sio_ch2->set_device_name(_T("8251 SIO (RS-232C #2)")); pit = new I8253(this, emu); pic = new I8259(this, emu); -#if defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) - cpu = new I8086(this, emu); -#else - cpu = new I80286(this, emu); +#if defined(HAS_I86) + cpu = new I86(this, emu); + cpu->device_model = INTEL_8086; +#elif defined(HAS_I286) + cpu = new I286(this, emu); #endif io = new IO(this, emu); fdc = new MB8877(this, emu); @@ -440,7 +441,19 @@ void VM::update_config() } } -#define STATE_VERSION 8 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 9 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -452,7 +465,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/fmr30/fmr30.h b/source/src/vm/fmr30/fmr30.h index a4f4fb8ed..bb3c0f833 100644 --- a/source/src/vm/fmr30/fmr30.h +++ b/source/src/vm/fmr30/fmr30.h @@ -37,6 +37,7 @@ // device informations for win32 #define USE_FLOPPY_DISK 2 +#define USE_FLOPPY_TYPE_BIT 0x0003 /* 3.5, 3.5 */ #define USE_HARD_DISK 7 #define USE_AUTO_KEY 5 #define USE_AUTO_KEY_RELEASE 6 @@ -67,10 +68,10 @@ class I8237; class I8251; class I8253; class I8259; -#if defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) -class I8086; -#else -class I80286; +#if defined(HAS_I86) +class I86; +#elif defined(HAS_I286) +class I286; #endif class IO; class MB8877; @@ -108,10 +109,10 @@ class VM : public VM_TEMPLATE I8251* sio_ch2; I8253* pit; I8259* pic; -#if defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) - I8086* cpu; -#else - I80286* cpu; +#if defined(HAS_I86) + I86* cpu; +#elif defined(HAS_I286) + I286* cpu; #endif IO* io; MB8877* fdc; @@ -135,7 +136,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -183,6 +184,9 @@ class VM : public VM_TEMPLATE uint32_t is_hard_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/fmr30/keyboard.h b/source/src/vm/fmr30/keyboard.h index 21443e7da..7cae230be 100644 --- a/source/src/vm/fmr30/keyboard.h +++ b/source/src/vm/fmr30/keyboard.h @@ -25,7 +25,7 @@ class KEYBOARD : public DEVICE uint8_t table[256]; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/fmr30/memory.cpp b/source/src/vm/fmr30/memory.cpp index ded9b3c02..8eaf16d51 100644 --- a/source/src/vm/fmr30/memory.cpp +++ b/source/src/vm/fmr30/memory.cpp @@ -11,7 +11,11 @@ #include "../../emu.h" #include "./memory.h" #include "../i8237.h" +#if defined(HAS_I86) +#include "../i86.h" +#elif defined(HAS_I286) #include "../i286.h" +#endif namespace FMR30 { diff --git a/source/src/vm/fmr30/memory.h b/source/src/vm/fmr30/memory.h index 908516e9d..c7fa4bea8 100644 --- a/source/src/vm/fmr30/memory.h +++ b/source/src/vm/fmr30/memory.h @@ -56,7 +56,7 @@ class MEMORY : public DEVICE void draw_cg(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/fmr30/rtc.h b/source/src/vm/fmr30/rtc.h index 9b1d8f9cd..7e6e790f3 100644 --- a/source/src/vm/fmr30/rtc.h +++ b/source/src/vm/fmr30/rtc.h @@ -27,12 +27,12 @@ class RTC : public DEVICE uint16_t rtcmr, rtdsr, rtadr, rtobr, rtibr; uint8_t regs[40]; - void __FASTCALL read_from_cur_time(); - void __FASTCALL write_to_cur_time(); - void __FASTCALL update_checksum(); - void __FASTCALL update_intr(); + void read_from_cur_time(); + void write_to_cur_time(); + void update_checksum(); + void update_intr(); public: - RTC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RTC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RTC")); } @@ -51,7 +51,7 @@ class RTC : public DEVICE } void __FASTCALL write_io16(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io16(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique function diff --git a/source/src/vm/fmr30/scsi.h b/source/src/vm/fmr30/scsi.h index 41b6076f6..1d0b29adf 100644 --- a/source/src/vm/fmr30/scsi.h +++ b/source/src/vm/fmr30/scsi.h @@ -29,7 +29,7 @@ class SCSI : public DEVICE bool phase_status, eop_status; public: - SCSI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + SCSI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("SCSI I/F")); } ~SCSI() {} diff --git a/source/src/vm/fmr30/serial.h b/source/src/vm/fmr30/serial.h index 7d6613943..025288473 100644 --- a/source/src/vm/fmr30/serial.h +++ b/source/src/vm/fmr30/serial.h @@ -39,10 +39,10 @@ class SERIAL : public DEVICE uint8_t intstat; } sioctrl[4]; - void __FASTCALL update_intr(int ch); + void update_intr(int ch); public: - SERIAL(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SERIAL(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Serial I/F")); } diff --git a/source/src/vm/fmr30/system.h b/source/src/vm/fmr30/system.h index f1a8c2ada..e8751ca6b 100644 --- a/source/src/vm/fmr30/system.h +++ b/source/src/vm/fmr30/system.h @@ -23,7 +23,7 @@ class SYSTEM : public DEVICE uint8_t nmistat, nmimask; public: - SYSTEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSTEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/fmr30/timer.h b/source/src/vm/fmr30/timer.h index 5b7544b99..1ac88e0e4 100644 --- a/source/src/vm/fmr30/timer.h +++ b/source/src/vm/fmr30/timer.h @@ -28,7 +28,7 @@ class TIMER : public DEVICE void update_intr(); public: - TIMER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TIMER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Timer I/F")); } diff --git a/source/src/vm/fmr50/CMakeLists.txt b/source/src/vm/fmr50/CMakeLists.txt index 69a7425b3..8b2db2763 100644 --- a/source/src/vm/fmr50/CMakeLists.txt +++ b/source/src/vm/fmr50/CMakeLists.txt @@ -1,8 +1,13 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/fmr50") +message("* vm/${EXE_NAME}") -add_library(vm_fmr50 +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +set(FMR50_BASE_FILES + ../scsi_host.cpp + ../msm58321.cpp + bios.cpp cmos.cpp floppy.cpp @@ -10,6 +15,28 @@ add_library(vm_fmr50 memory.cpp scsi.cpp timer.cpp - fmr50.cpp + fmr50.cpp ) + +add_library(vm_${EXE_NAME} + ${FMR50_BASE_FILES} +) + +if("${U_EXE_NAME}" STREQUAL "EMUFMR50_286") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I286) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR50_386") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I386) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR50_486") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I486) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR60") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I286) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR70") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I386) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR80") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_I486) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR250") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_PENTIUM) +elseif("${U_EXE_NAME}" STREQUAL "EMUFMR280") + target_compile_definitions(vm_${EXE_NAME} PRIVATE -DHAS_PENTIUM) +endif() diff --git a/source/src/vm/fmr50/bios.cpp b/source/src/vm/fmr50/bios.cpp index eb5b73842..218d1ad51 100644 --- a/source/src/vm/fmr50/bios.cpp +++ b/source/src/vm/fmr50/bios.cpp @@ -318,7 +318,7 @@ void BIOS::event_frame() } \ } -bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { if((PC == 0xfffc4) || (PC == 0xfffc9) || (PC == 0xfffd3)) { uint32_t regs32[10] = {0}; @@ -336,7 +336,7 @@ bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int return false; } -bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { pair32_t *regpair = (pair32_t *)regs; int drv = AL & 0xf; @@ -1249,7 +1249,7 @@ bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], in return false; } -bool BIOS::bios_int_ia32(int intnum, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_int_ia32(int intnum, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { if(intnum == 0x93) { // disk bios @@ -1258,7 +1258,7 @@ bool BIOS::bios_int_ia32(int intnum, uint32_t regs[], uint16_t sregs[], int32_t* return false; } -bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { if(intnum == 0x93) { // disk bios diff --git a/source/src/vm/fmr50/bios.h b/source/src/vm/fmr50/bios.h index c02853fed..c75db2b76 100644 --- a/source/src/vm/fmr50/bios.h +++ b/source/src/vm/fmr50/bios.h @@ -44,7 +44,7 @@ class BIOS : public DEVICE int scsi_blocks[USE_HARD_DISK]; public: - BIOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + BIOS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < MAX_DRIVE; i++) disk[i] = NULL; //for(int i = 0; i < USE_HARD_DISK; i++) harddisk[i] = NULL; set_device_name(_T("Pseudo BIOS")); @@ -55,10 +55,10 @@ class BIOS : public DEVICE void initialize(); void reset(); void event_frame(); - bool bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); - bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); - bool bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); - bool bios_int_ia32(int intnum, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + bool bios_call_far_i86(uint32_t PC, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + bool bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + bool bios_int_ia32(int intnum, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); uint32_t __FASTCALL read_signal(int ch); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/fmr50/cmos.h b/source/src/vm/fmr50/cmos.h index 8b70ab93c..aa61bdea7 100644 --- a/source/src/vm/fmr50/cmos.h +++ b/source/src/vm/fmr50/cmos.h @@ -29,7 +29,7 @@ class CMOS : public DEVICE uint8_t bank; public: - CMOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMOS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMOS RAM")); } diff --git a/source/src/vm/fmr50/floppy.h b/source/src/vm/fmr50/floppy.h index e3615fab6..b2e4be338 100644 --- a/source/src/vm/fmr50/floppy.h +++ b/source/src/vm/fmr50/floppy.h @@ -32,7 +32,7 @@ class FLOPPY : public DEVICE void update_intr(); public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/fmr50/fmr50.cpp b/source/src/vm/fmr50/fmr50.cpp index 252d6adfb..b4b87c37b 100644 --- a/source/src/vm/fmr50/fmr50.cpp +++ b/source/src/vm/fmr50/fmr50.cpp @@ -22,9 +22,10 @@ #include "../i8253.h" #include "../i8259.h" #if defined(HAS_I286) +//#include "../i286_np21.h" #include "../i286.h" #else -#include "../i386.h" +#include "../i386_np21.h" #endif #include "../io.h" #include "../mb8877.h" @@ -60,7 +61,7 @@ using FMR50::MEMORY; using FMR50::SCSI; using FMR50::TIMER; -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { /* Machine ID & CPU ID @@ -119,19 +120,23 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) dummy->set_device_name(_T("1st Dummy")); #if defined(HAS_I286) - cpu = new I80286(this, emu); -#else - cpu = new I386(this, emu); -#endif -#if defined(HAS_I286) - cpu->set_device_name(_T("CPU(i286)")); + cpu = new I286(this, emu); +// cpu->device_model = INTEL_80286; #elif defined(HAS_I386) - cpu->set_device_name(_T("CPU(i386)")); + cpu = new I386(this, emu); + cpu->device_model = INTEL_80386; #elif defined(HAS_I486) - cpu->set_device_name(_T("CPU(i486)")); + cpu = new I386(this, emu); +#if defined(HAS_I486DX) + cpu->device_model = INTEL_I486DX; +#else + cpu->device_model = INTEL_I486SX; +#endif #elif defined(HAS_PENTIUM) - cpu->set_device_name(_T("CPU(Pentium)")); + cpu = new I386(this, emu); + cpu->device_model = INTEL_PENTIUM; #endif + crtc = new HD46505(this, emu); #ifdef _FMR60 acrtc = new HD63484(this, emu); @@ -548,6 +553,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 7 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -560,7 +577,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/fmr50/fmr50.h b/source/src/vm/fmr50/fmr50.h index d41fa6f1a..f3d92a405 100644 --- a/source/src/vm/fmr50/fmr50.h +++ b/source/src/vm/fmr50/fmr50.h @@ -12,33 +12,43 @@ #define _FMR50_H_ #if defined(_FMR50) -#if defined(HAS_I286) -#define DEVICE_NAME "FUJITSU FMR-50 (i286)" -#define CONFIG_NAME "fmr50_i286" -#elif defined(HAS_I386) -#define DEVICE_NAME "FUJITSU FMR-50 (i386)" -#define CONFIG_NAME "fmr50_i386" -#elif defined(HAS_I486) -#define DEVICE_NAME "FUJITSU FMR-50 (i486)" -#define CONFIG_NAME "fmr50_i486" -#elif defined(HAS_PENTIUM) -#define DEVICE_NAME "FUJITSU FMR-250" -#define CONFIG_NAME "fmr250" -#endif + #if defined(HAS_I286) + #define DEVICE_NAME "FUJITSU FMR-50 (i286)" + #define CONFIG_NAME "fmr50_i286" + #elif defined(HAS_I386) + #define DEVICE_NAME "FUJITSU FMR-50 (i386)" + #define CONFIG_NAME "fmr50_i386" + #elif defined(HAS_I486) + #define DEVICE_NAME "FUJITSU FMR-50 (i486)" + #define CONFIG_NAME "fmr50_i486" + #elif defined(HAS_PENTIUM) + #define DEVICE_NAME "FUJITSU FMR-250" + #define CONFIG_NAME "fmr250" + #endif #elif defined(_FMR60) -#if defined(HAS_I286) -#define DEVICE_NAME "FUJITSU FMR-60" -#define CONFIG_NAME "fmr60" -#elif defined(HAS_I386) -#define DEVICE_NAME "FUJITSU FMR-70" -#define CONFIG_NAME "fmr70" -#elif defined(HAS_I486) -#define DEVICE_NAME "FUJITSU FMR-80" -#define CONFIG_NAME "fmr80" -#elif defined(HAS_PENTIUM) -#define DEVICE_NAME "FUJITSU FMR-280" -#define CONFIG_NAME "fmr280" + #if defined(HAS_I286) + #define DEVICE_NAME "FUJITSU FMR-60" + #define CONFIG_NAME "fmr60" + #elif defined(HAS_I386) + #define DEVICE_NAME "FUJITSU FMR-70" + #define CONFIG_NAME "fmr70" + #elif defined(HAS_I486) + #define DEVICE_NAME "FUJITSU FMR-80" + #define CONFIG_NAME "fmr80" + #elif defined(HAS_PENTIUM) + #define DEVICE_NAME "FUJITSU FMR-280" + #define CONFIG_NAME "fmr280" + #endif #endif +#if defined(HAS_I486) + #if !(defined(HAS_I486SX) || defined(HAS_I486DX)) + #define HAS_I486SX +// #define HAS_I486DX + #endif +#else + #if (defined(HAS_I486SX) || defined(HAS_I486DX)) + #define HAS_I486 + #endif #endif // device informations for virtual machine @@ -63,11 +73,7 @@ #endif #define MAX_DRIVE 4 #define MAX_MEMCARD 2 -#if defined(HAS_I286) #define I86_PSEUDO_BIOS -#else -#define I386_PSEUDO_BIOS -#endif #define I8259_MAX_CHIPS 2 #define SINGLE_MODE_DMA #define MB8877_NO_BUSY_AFTER_SEEK @@ -77,6 +83,8 @@ // device informations for win32 #define USE_CPU_TYPE 2 #define USE_FLOPPY_DISK 4 +#define USE_FLOPPY_TYPE_BIT 0x0003 /* 3.5, 3.5, 5.0, 5.0 */ + #define USE_HARD_DISK 7 #define USE_AUTO_KEY 5 #define USE_AUTO_KEY_RELEASE 6 @@ -112,7 +120,7 @@ class I8251; class I8253; class I8259; #if defined(HAS_I286) -class I80286; +class I286; #else class I386; #endif @@ -153,7 +161,7 @@ class VM : public VM_TEMPLATE I8253* pit1; I8259* pic; #if defined(HAS_I286) - I80286* cpu; + I286* cpu; #else I386* cpu; #endif @@ -179,7 +187,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -227,6 +235,9 @@ class VM : public VM_TEMPLATE uint32_t is_hard_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/fmr50/keyboard.h b/source/src/vm/fmr50/keyboard.h index 2de9d310f..eb5e1dfe3 100644 --- a/source/src/vm/fmr50/keyboard.h +++ b/source/src/vm/fmr50/keyboard.h @@ -65,7 +65,7 @@ class KEYBOARD : public DEVICE uint8_t table[256]; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/fmr50/memory.cpp b/source/src/vm/fmr50/memory.cpp index 1522039ec..193f4bbd7 100644 --- a/source/src/vm/fmr50/memory.cpp +++ b/source/src/vm/fmr50/memory.cpp @@ -12,7 +12,7 @@ #if defined(HAS_I286) #include "../i286.h" #else -#include "../i386.h" +#include "../i386_np21.h" #endif namespace FMR50 { diff --git a/source/src/vm/fmr50/memory.h b/source/src/vm/fmr50/memory.h index a59eeecf8..11a8d1e2a 100644 --- a/source/src/vm/fmr50/memory.h +++ b/source/src/vm/fmr50/memory.h @@ -19,7 +19,7 @@ #define SIG_MEMORY_VSYNC 1 #if defined(HAS_I286) -class I80286; +class I286; #else class I386; #endif @@ -30,7 +30,7 @@ class MEMORY : public DEVICE { private: #if defined(HAS_I286) - I80286 *d_cpu; + I286 *d_cpu; #else I386 *d_cpu; #endif @@ -113,7 +113,7 @@ class MEMORY : public DEVICE void draw_cg(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } @@ -134,7 +134,7 @@ class MEMORY : public DEVICE // unique functions #if defined(HAS_I286) - void set_context_cpu(I80286* device) + void set_context_cpu(I286* device) #else void set_context_cpu(I386* device) #endif diff --git a/source/src/vm/fmr50/scsi.h b/source/src/vm/fmr50/scsi.h index 25796a82a..9d5550fc9 100644 --- a/source/src/vm/fmr50/scsi.h +++ b/source/src/vm/fmr50/scsi.h @@ -29,7 +29,7 @@ class SCSI : public DEVICE bool irq_status; public: - SCSI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SCSI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("SCSI I/F")); diff --git a/source/src/vm/fmr50/timer.h b/source/src/vm/fmr50/timer.h index b15ffd7c0..cf9847b10 100644 --- a/source/src/vm/fmr50/timer.h +++ b/source/src/vm/fmr50/timer.h @@ -32,7 +32,7 @@ class TIMER : public DEVICE void update_intr(); public: - TIMER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TIMER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Timer I/F")); } diff --git a/source/src/vm/fmtowns/00_status.ja.md b/source/src/vm/fmtowns/00_status.ja.md new file mode 100644 index 000000000..e110859ee --- /dev/null +++ b/source/src/vm/fmtowns/00_status.ja.md @@ -0,0 +1,78 @@ +# eFMTOwns 現状 (Sorry, Written in Japanese Only) +# --- If you can translate to another language, please do and "PULL REQUEST" to my GITHUB. +## May 08, 2020 K.Ohta +## --- 追記 May 21, 2020 K.Ohta +## --- 追記 June 26, 2020 K.Ohta +## --- 追記 November 15, 2020 K.Ohta + +## 実装状況 +- 本体:i386周りはOK?ただし、パワー/リセット関係の実装が不十分? + - CPUID/MACHINE IDは実装した。 + - DMACはADDRESS BOUNDARYでHR以降の挙動が違うことはまだ実装してない。 + - ~~TownsOS (v2.1)で16bit DMA転送を使うと最初の1バイトが化けることが判明したので、当面使えなくした(I/O 0034h:bit7 = '1')~~**インチキ実装で凌ぐ。改善はToDo扱い**。 + - ウエイト設定及びクロック設定は実装してみてるが、AB.COMが動かない(Townsと認識してくれない)機種がある。 +- メモリ:Towns2H程度?可変拡張メモリやウエイト機能(i386も)は機能としては実装済み。 +- シリアルROM: **いい加減にしか実装してない** +- VRAM: **512KB部分とFM-R互換機能のみ実装。** + - 16色複数画面@MS-DOSで非表示がうまく出来てない。 + - ~~レンダリング周りは256色がダメっぽい?~~ +- CRTC: ほぼ実装。多分実装した。きっと実装したと思う。**多分実装したんじゃないかな**。 +- スプライト:**ほぼ大丈夫になった?**まだ高速化は必要(GPUオフロードできるといいのに…)。 +- CDROM: + - CD-DA: ほぼ実装 + - MODE1 READ: ほぼ実装 + - MODE2 READ: 一応実装 + - RAW READ : 一応実装 + - SUB FIELD (SUB CODE; 04CCH, 04CDh): レジスタは実装したがP-Wフィールド設定は殆ど未実装 + - ~~TownsOS 1.xをCDブートすると、なぜかハングアップ(BIOSが00007DD4hに落ちる)。~~HDDブートだと大丈夫? + - ~~TownsOS v1.xのCDブート(と言うか、v1.xについてるIO.SYS)で、CD-ROMコマンドA0h (80h+reply) PARAM=08 01 xx xx xx xx xx xxが期待する値を返さずブートが止まる。~~v2.1系は大丈夫っぽい。 + - ~~TownsOS 2.x系のCDからのブートは大丈夫っぽいが、挙動が不審。~~ + - **Towns OS v1.1L20/L30がブートできるようになりました(2020926)**。が、Towns Menuでアイコンクリックができない。 + - **Towns Linux (Slackware+JE4)のインストール中に、インストールファイル(*.tgzなど)が壊れる。** + - **TownsOS v2.1をCD-ROMからインストールすると、最終段階でconfig.sys等が壊れる&ブートセクタが不正になる** + - i486以降のマシンでTownsOS v2.1をインストールすると、最後のカスタマイズでハングアップする。 + - ~~MS-DOS+MSCDEXでも大体は動くが、時折転送に失敗する(解消した?) 。~~ + +- SCSI: 2バイトDMA転送を(**インチキで**)実装したので、殆どのものが動くはず。~~←書き込み時の最初の1バイトが壊れるケースが見つかったので、当面使わない~~ +- OPN2(YM2612): だいたい実装できたと思う。 +- ADPCM(RF5C68): だいたい実装できた。ローパスフィルタ絡みは要調整。 + - ~~スタークルーザーのデモでテストしたが、朗読もちゃんとするけどデモ途中でハングアップする。~~(解決した?) + - スタークルーザーでの**効果音部分や楽器部分はうまく鳴ってるっぽい**。 + - ~~スーパーリアル麻雀 PIVなどのPCMが途中からしか鳴らない(本当に途中からなのか?)~~。 +- BEEP: 実装したが、音がプチプチ言ってる(何故?) +- 電子ミキサー: 未実装 +- サンプリング用A/Dコンバータ: とりあえずの実装はしてあるが、まだ試験etcしてない。 +- キーボード: + - オートリピート関係が非実装。 + - リセット時の同時押し("CD"など)を実装する必要がある。 +- ジョイパッド: + - ~~2ボタンパッドのみ実装~~ + - ~~6ボタンパッドは実装していない~~ + - 電波新聞社のアナログスティックも実装したいけど、プロトコルがわからない。 +- マウス: 実装はしたが、まだ精度に問題あり。 + - ~~最悪の場合、取り込みタイミングが1frame (≒13mSec)単位なのを変える必要がある。~~ + - **event.cppに手を入れて、0.5frame単位でのエミュレーションにしてみた。** +- UART: 乗っけてはいるけど動作未確認。 +- MIDI: UARTだけ乗せてるのになぜかカードが認識されてる(??) + +## 動いてるっぽい(確認済み)ソフト +- Towns OS v2.1 (CD-ROMからでもOK) +- MS-DOS v6.2 +- MS-DOS v3.1 +- ランス2 +- Dr.STOP! +- ランス3 +- フラクタルエンジン・デモ +- スタークルーザー2(**ほぼ問題なく動いてる**が、画面の乱れが多少残ってる) +- ぷよぷよ(CDからのブート可能?CD-DAに問題あり) +- A4-Ayayo\'s\ Live\ Affection- (**文字表示やジョイスティック周りに問題あり**) +- Viper V10 RS +- スーパーリアル麻雀PIV +- 雷電伝説 +- 究極タイガー + +## 動かない(ブートしない)ソフト +- After Burnerなど、**CRI系のゲーム** +- ライザンバーなど、**データウェストのゲーム** +- その他は確認中 + diff --git a/source/src/vm/fmtowns/CMakeLists.txt b/source/src/vm/fmtowns/CMakeLists.txt index d93397067..0a00e8e29 100644 --- a/source/src/vm/fmtowns/CMakeLists.txt +++ b/source/src/vm/fmtowns/CMakeLists.txt @@ -2,26 +2,45 @@ cmake_minimum_required (VERSION 2.6) message("* vm/fm-towns") -add_library(vm_fmtowns - +set(VM_FMTOWNS_DEV_SRCS ad7820kr.cpp rf5c68.cpp + ym2612.cpp adpcm.cpp +# cdc.cpp floppy.cpp keyboard.cpp scsi.cpp timer.cpp - - serialrom.cpp - towns_sysrom.cpp - towns_dictionary.cpp - msdosrom.cpp + towns_dmac.cpp fontroms.cpp + iccard.cpp + joystick.cpp + joypad.cpp + msdosrom.cpp + serialrom.cpp + towns_dictionary.cpp + towns_cdrom.cpp towns_crtc.cpp towns_memory.cpp + towns_scsi_host.cpp towns_sprite.cpp + towns_sysrom.cpp towns_vram.cpp + towns_planevram.cpp + ../scsi_host.cpp + ../msm58321.cpp + fmtowns.cpp ) + +#ToDo +if(BUILD_WITH_20PIX) + set(VM_FMTOWNS_DEV_SRCS ${VM_FMTOWNS_DEV_SRCS} fontrom_20pix.cpp) +endif() + +add_library(vm_${EXE_NAME} + ${VM_FMTOWNS_DEV_SRCS} +) diff --git a/source/src/vm/fmtowns/ad7820kr.cpp b/source/src/vm/fmtowns/ad7820kr.cpp index 93488c4bb..fc2650121 100644 --- a/source/src/vm/fmtowns/ad7820kr.cpp +++ b/source/src/vm/fmtowns/ad7820kr.cpp @@ -106,7 +106,9 @@ void AD7820KR::start_sample(double usec) write_signals(&outputs_ready, 0x00000000); // IN SAMPLING write_signals(&outputs_intr, 0x00000000); // CLEAR INTRRUPT write_signals(&outputs_overflow, 0x00000000); // CLEAR OVERFLOW - register_event(this, EVENT_SAMPLE, usec, false, &event_sample); + if(usec > 0.0) { + register_event(this, EVENT_SAMPLE, usec, false, &event_sample); + } } void AD7820KR::write_signal(int ch, uint32_t data, uint32_t mask) diff --git a/source/src/vm/fmtowns/ad7820kr.h b/source/src/vm/fmtowns/ad7820kr.h index e8f8f63e7..272c25674 100644 --- a/source/src/vm/fmtowns/ad7820kr.h +++ b/source/src/vm/fmtowns/ad7820kr.h @@ -44,7 +44,7 @@ class AD7820KR : public DEVICE { void start_sample(double usec); public: - AD7820KR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + AD7820KR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_intr); initialize_output_signals(&outputs_overflow); @@ -68,7 +68,7 @@ class AD7820KR : public DEVICE { void release(); void reset(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); uint32_t __FASTCALL read_signal(int ch); void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); diff --git a/source/src/vm/fmtowns/adpcm.cpp b/source/src/vm/fmtowns/adpcm.cpp index e35699e72..9899620cd 100644 --- a/source/src/vm/fmtowns/adpcm.cpp +++ b/source/src/vm/fmtowns/adpcm.cpp @@ -8,8 +8,9 @@ */ #include "./adpcm.h" -#include "rf5c68.h" #include "ad7820kr.h" +#include "rf5c68.h" +#include "ym2612.h" #include "../i8259.h" namespace FMTOWNS { @@ -20,11 +21,8 @@ namespace FMTOWNS { void ADPCM::initialize() { adc_fifo = new FIFO(64); // OK? - for(int i = 0; i < 8; i++) { - dac_intr_mask[i] = true; // true = enable intrrupt. - dac_intr[i] = false; - } - intr_opx = false; + event_adc_clock = -1; + event_adpcm_clock = -1; } void ADPCM::release() @@ -37,6 +35,14 @@ void ADPCM::reset() { // Is clear FIFO? adc_fifo->clear(); + dac_intr_mask = 0x0000; // Disable + dac_intr = 0x0000; // OFF + latest_dac_intr = false; + + opx_intr = false; + adpcm_mute = false; + opn2_mute = false; + write_signals(&outputs_intr, 0x00000000); write_signals(&outputs_led_control, 0x00000000); write_signals(&outputs_allmute, 0xffffffff); // OK? @@ -45,7 +51,8 @@ void ADPCM::reset() if(event_adpcm_clock >= 0) { cancel_event(this, event_adpcm_clock); } - register_event(this, EVENT_ADPCM_CLOCK, 16.0e6 / (384.0 * 2.0), true, &event_adpcm_clock); // Is this true? + // Tick is (8.0e6 / 384.0)[Hz] .. Is this true? + register_event(this, EVENT_ADPCM_CLOCK, (384.0 * 2.0) / 16.0, true, &event_adpcm_clock); } void ADPCM::initialize_adc_clock(int freq) @@ -86,52 +93,39 @@ uint32_t ADPCM::read_io8(uint32_t addr) 0x04e9 - 0x04ec : DAC CONTROL 0x04f0 - 0x04f8 : DAC */ - uint8_t val = 0xff; - switch(addr & 0xff) { - case 0xe7: // ADC data register + uint8_t val = 0x00; + switch(addr) { + case 0x04d5: // Mute reg + val |= ((opn2_mute) ? 0 : 0x02); + val |= ((adpcm_mute) ? 0 : 0x01); + break; + case 0x04e7: // ADC data register if(!(adc_fifo->empty())) { val = (uint8_t)(adc_fifo->read() & 0xff); } else { val = 0x00; } break; - case 0xe8: // ADC flags + case 0x04e8: // ADC flags val = (!(adc_fifo->empty())) ? 0x01 : 0x00; break; - case 0xe9: // Int13 reason - { - bool intr_pcm = false; - for(int i = 0; i < 8; i++) { - if(dac_intr[i]) { - intr_pcm = true; - break; - } - } - val = 0xf6 | ((intr_pcm) ? 0x08 : 0x00) | ((intr_opx) ? 0x01 : 0x00); - } + case 0x04e9: // Int13 reason + val = 0x00 | ((dac_intr != 0) ? 0x08 : 0x00) | ((opx_intr) ? 0x01 : 0x00); +// write_signals(&outputs_intr, 0); // Clear Interrupt +// dac_intr = 0; +// opx_intr = false; break; - case 0xea: // PCM Interrupt mask - val = 0x00; - for(int i = 0; i < 8; i++) { - val = val | ((dac_intr_mask[i]) ? (0x01 << i) : 0); - } + case 0x04ea: // PCM Interrupt mask + val = dac_intr_mask; break; - case 0xeb: // PCM Interrupt status + case 0x04eb: // PCM Interrupt status { - bool _s = false; - val = 0x00; - for(int i = 0; i < 8; i++) { - val = val | ((dac_intr[i]) ? (0x01 << i) : 0); - } - for(int i = 0; i < 8; i++) { - if(dac_intr[i]) { - _s = true; - } - dac_intr[i] = false; - } - if(_s) { - d_pic->write_signal(SIG_I8259_IR5 | SIG_I8259_CHIP1, 0x00000000, 0xffffffff); + val = dac_intr; + dac_intr = 0x00; + if(latest_dac_intr) { + latest_dac_intr = false; } + if(!(opx_intr)) write_signals(&outputs_intr, 0); // Clear Interrupt } break; default: @@ -149,37 +143,26 @@ void ADPCM::write_io8(uint32_t addr, uint32_t data) 0x04e9 - 0x04ec : DAC CONTROL 0x04f0 - 0x04f8 : DAC */ - uint32_t naddr = addr & 0xff; - switch(naddr) { - case 0xd5: + switch(addr) { + case 0x04d5: opn2_mute = ((data & 0x02) == 0) ? true : false; adpcm_mute = ((data & 0x01) == 0) ? true : false; - //d_opn2->write_signal(SIG_YM2612_MUTE, (opn2_mute) ? 0xffffffff : 0x00000000, 0xffffffff); + d_opn2->write_signal(SIG_YM2612_MUTE, (opn2_mute) ? 0xffffffff : 0x00000000, 0xffffffff); d_rf5c68->write_signal(SIG_RF5C68_MUTE, (adpcm_mute) ? 0xffffffff : 0x00000000, 0xffffffff); break; - case 0xe8: + case 0x04e8: adc_fifo->clear(); break; - case 0xea: - { - uint32_t mask = 0x01; - for(int i = 0; i < 8; i++) { - if((data & mask) != 0) { - dac_intr_mask[i] = true; - } else { - dac_intr_mask[i] = false; - } - mask <<= 1; - } - } + case 0x04ea: + dac_intr_mask = data; break; - case 0xec: + case 0x04ec: write_signals(&outputs_led_control, ((data & 0x80) == 0) ? 0xffffffff : 0x00000000); write_signals(&outputs_allmute, ((data & 0x40) == 0) ? 0xffffffff : 0x00000000); break; default: - if(naddr >= 0xf0) { - d_rf5c68->write_io8(naddr & 0x0f, data); + if(addr >= 0x04f0) { + d_rf5c68->write_io8(addr & 0x0f, data); } break; } @@ -203,31 +186,44 @@ void ADPCM::write_data8(uint32_t addr, uint32_t data) void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask) { if(ch == SIG_ADPCM_WRITE_INTERRUPT) { +// out_debug_log(_T("SIG_ADPCM_WRITE_INTERRUPT val=%08X mask=%08X"), data ,mask); uint32_t n_ch = data & 0x07; bool n_onoff = (((data & mask) & 0x00000008) != 0) ? true : false; bool n_allset =(((data & mask) & 0x80000000) != 0) ? true : false; + bool _d = false; if(!(n_allset)) { - n_onoff = n_onoff & dac_intr_mask[n_ch]; - if(n_onoff != dac_intr[n_ch]) { // SET/RESET INT13 - write_signals(&outputs_intr, (n_onoff) ? 0xffffffff : 0x00000000); + _d = ((dac_intr_mask & (1 << n_ch)) != 0) ? true : false; + if(n_onoff) { + dac_intr = dac_intr | (1 << n_ch); + } else { + dac_intr = dac_intr & ~(1 << n_ch); } - dac_intr[n_ch] = n_onoff; } else { // ALLSET - bool n_backup; - bool _s = false; - for(int i = 0; i < 8; i++) { // SET/RESET INT13 - n_backup = dac_intr[i]; - dac_intr[i] = n_onoff & dac_intr_mask[i]; - if(n_backup != dac_intr[i]) _s = true; - } - if(_s) { - write_signals(&outputs_intr, (n_onoff) ? 0xffffffff : 0x00000000); - } - } + uint16_t intr_backup = dac_intr; + dac_intr = (n_onoff) ? 0xffff : 0x0000; + _d = true; +// _d = (dac_intr != intr_backup) ? true : false; + } + if((n_onoff) && (_d)) { // ON + write_signals(&outputs_intr, 0xffffffff); + latest_dac_intr = true; + } else if(!(n_onoff) || !(_d)) { + if(!(opx_intr)) { + write_signals(&outputs_intr, 0x00000000); + } + latest_dac_intr = false; + } } else if(ch == SIG_ADPCM_OPX_INTR) { // SET/RESET INT13 - intr_opx = ((data & mask) != 0); - write_signals(&outputs_intr, (intr_opx) ? 0xffffffff : 0x00000000); +// out_debug_log(_T("SIG_ADPCM_OPX_INTR val=%08X mask=%08X"), data ,mask); + opx_intr = ((data & mask) != 0); + if(opx_intr) { + write_signals(&outputs_intr, 0xffffffff); + } else { + if(!(latest_dac_intr)) { + write_signals(&outputs_intr, 0x00000000); + } + } } else if(ch == SIG_ADPCM_ADC_INTR) { // Push data to FIFO from ADC. if((data & mask) != 0) { uint32_t n_data = d_adc->read_signal(SIG_AD7820_DATA_REG); @@ -239,6 +235,10 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask) } } +uint32_t ADPCM::read_signal(int ch) +{ + return 0; +} #define STATE_VERSION 1 bool ADPCM::process_state(FILEIO* state_fio, bool loading) @@ -255,9 +255,10 @@ bool ADPCM::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(opn2_mute); state_fio->StateValue(adpcm_mute); - state_fio->StateValue(intr_opx); - state_fio->StateArray(dac_intr, sizeof(dac_intr), 1); - state_fio->StateArray(dac_intr_mask, sizeof(dac_intr_mask), 1); + state_fio->StateValue(opx_intr); + state_fio->StateValue(dac_intr); + state_fio->StateValue(dac_intr_mask); + state_fio->StateValue(latest_dac_intr); state_fio->StateValue(event_adc_clock); state_fio->StateValue(event_adpcm_clock); diff --git a/source/src/vm/fmtowns/adpcm.h b/source/src/vm/fmtowns/adpcm.h index 224a2b9b4..f31e3e90f 100644 --- a/source/src/vm/fmtowns/adpcm.h +++ b/source/src/vm/fmtowns/adpcm.h @@ -40,10 +40,11 @@ class ADPCM : public DEVICE { outputs_t outputs_allmute; FIFO* adc_fifo; - bool intr_opx; - bool dac_intr[8]; - bool dac_intr_mask[8]; - + bool opx_intr; + uint16_t dac_intr; + uint16_t dac_intr_mask; + bool latest_dac_intr; + bool opn2_mute; bool adpcm_mute; @@ -51,21 +52,16 @@ class ADPCM : public DEVICE { int event_adpcm_clock; void initialize_adc_clock(int freq); public: - ADPCM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + ADPCM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { adc_fifo = NULL; initialize_output_signals(&outputs_intr); initialize_output_signals(&outputs_led_control); initialize_output_signals(&outputs_allmute); - for(int i = 0; i < 8; i++) { - dac_intr[i] = false; - dac_intr_mask[i] = true; - } - intr_opx = false; - adpcm_mute = false; - opn2_mute = false; - event_adc_clock = -1; - event_adpcm_clock = -1; + d_rf5c68 = NULL; + d_opn2 = NULL; + d_pic = NULL; + d_adc = NULL; set_device_name(_T("FM-Towns ADPCM")); } ~ADPCM() {} @@ -73,7 +69,7 @@ class ADPCM : public DEVICE { void initialize(); void release(); void reset(); - void event_callback(int id, int err); + void __FASTCALL event_callback(int id, int err); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_io8(uint32_t addr, uint32_t data); diff --git a/source/src/vm/fmtowns/cdc.cpp b/source/src/vm/fmtowns/cdc.cpp deleted file mode 100644 index 50016235b..000000000 --- a/source/src/vm/fmtowns/cdc.cpp +++ /dev/null @@ -1,714 +0,0 @@ -/* - Author : Kyuma.Ohta - Date : 2019.01.29- - - [FM-Towns CD Controller] -*/ - -#include "cdc.h" -#include "towns_cdrom.h" -#include "../../fifo.h" -#include "../scsi_host.h" -#include "../scsi_dev.h" - -namespace FMTOWNS { - -void CDC::set_context_scsi_host(SCSI_HOST* dev) -{ - d_scsi_host = dev; - d_scsi_host->set_context_irq(this, SIG_TOWNS_CDC_IRQ, 0xffffffff); - d_scsi_host->set_context_drq(this, SIG_TOWNS_CDC_DRQ, 0xffffffff); - d_scsi_host->set_context_bsy(this, SIG_TOWNS_CDC_BUSY, 0xffffffff); - d_scsi_host->set_context_cd(this, SIG_TOWNS_CDC_CD, 0xffffffff); - d_scsi_host->set_context_io(this, SIG_TOWNS_CDC_IO, 0xffffffff); - d_scsi_host->set_context_msg(this, SIG_TOWNS_CDC_MSG, 0xffffffff); - d_scsi_host->set_context_req(this, SIG_TOWNS_CDC_REQ, 0xffffffff); - d_scsi_host->set_context_ack(this, SIG_TOWNS_CDC_ACK, 0xffffffff); -} - - -void CDC::set_context_cdrom(TOWNS_CDROM* dev) -{ - d_cdrom = dev; - d_cdrom->set_context_done(this, SIG_TOWNS_CDC_CDROM_DONE, 0xffffffff); -} - -void CDC::reset() -{ - param_fifo->clear(); - stat_fifo->clear(); - - has_status = false; - extra_status = 0; - submpu_ready = true; - software_transfer_phase = false; - - write_signals(&output_submpu_intr, 0x00000000); - write_signals(&output_dma_intr, 0x00000000); - write_signals(&output_dma_line, 0x00000000); - - dma_intr = false; - submpu_intr = false; - - dma_transfer = false; - pio_transfer = true; - d_scsi_host->reset(); -} - -void CDC::initialize() -{ - param_fifo = new FIFO(6); // - stat_fifo = new FIFO(4); - - submpu_ready = true; - - submpu_intr_mask = false; - dma_intr_mask = false; - memset(w_regs, 0x00, sizeof(w_regs)); - - dma_transfer = false; - pio_transfer = true; - - busy_status = false; - cd_status = false; - io_status = false; - msg_status = false; - req_status = false; - ack_status = false; -} - -void CDC::release() -{ - param_fifo->release(); - stat_fifo->release(); - - delete param_fifo; - delete stat_fifo; -} -void CDC::write_io8(uint32_t address, uint32_t data) -{ - /* - * 04C0h : Master control register - * 04C2h : Command register - * 04C4h : Parameter register - * 04C6h : Transfer control register. - */ - - switch(address & 0x0f) { - case 0x00: // Master control register - { - if((data & 0x80) != 0) { - if(submpu_intr) write_signals(&output_submpu_intr, 0x00000000); - submpu_intr = false; - } - if((data & 0x40) != 0) { - if(dma_intr) write_signals(&output_dma_intr, 0x00000000); - dma_intr = false; - } - if((data & 0x04) != 0) this->reset(); - submpu_intr_mask = ((data & 0x02) != 0) ? true : false; - dma_intr_mask = ((data & 0x01) != 0) ? true : false; - w_regs[address & 0x0f] = data; - } - break; - case 0x02: // Command register - if(submpu_ready) { - command_type_play = ((data & 0x80) != 0) ? false : true; // false = status command - stat_reply_intr = ((data & 0x40) != 0) ? true : false; - req_status = ((data & 0x20) != 0) ? true : false; - if(command_type_play) { - enqueue_command_play(data); - } else { - enqueue_command_status(data); - } - w_regs[address & 0x0f] = data; - } - break; - case 0x04: // Parameter register - if(submpu_ready) { - if(param_fifo->full()) { - param_fifo->read(); // Dummy read - } - param_fifo->write((int)(data & 0xff)); - w_regs[address & 0x0f] = data; - } - break; - case 0x06: - { - dma_transfer = ((data & 0x10) != 0) ? true : false; - pio_transfer = ((data & 0x08) != 0) ? true : false; - w_regs[address & 0x0f] = data; - } - break; - default: - if((addr & 0x01) == 0) { - w_regs[address & 0x0f] = data; - } - break; - } -} - -uint32_t CDC::read_io8(uint32_t address) -{ - /* - * 04C0h : Master status register - */ - uint32_t val = 0xff; - switch(addr & 0x0f) { - case 0x0: //Master status - { - val = 0x00; - val = val | ((submpu_intr) ? 0x80 : 0x00); - val = val | ((dma_intr) ? 0x40 : 0x00); - val = val | ((software_transfer_phase) ? 0x20 : 0x00); - val = val | ((d_dmac->read_signal(SIG_UPD71071_IS_TRANSFERING + 3) !=0) ? 0x10 : 0x00); // USING DMAC ch.3 - val = val | ((has_status) ? 0x02 : 0x00); - val = val | ((submpu_ready) ? 0x01 : 0x00); - } - break; - case 0x2: // Status register - val = (uint32_t)(stat_fifo->read() & 0xff); - if(stat_fifo->empty()) { - has_status = false; - if(extra_status != 0) { - uint8_t cmd = w_regs[0x02]; - switch(cmd & 0x9f) { - case 0x00: // Seek - write_status(0x04, 0x00, 0x00, 0x00); - extra_status = 0; - break; - case 0x02: // Read - if(extra_status == 2) { - write_status(0x22, 0x00, 0x00, 0x00); - } - extra_status = 0; - break; - case 0x04: // PLAY CDDA - write_status(0x07, 0x00, 0x00, 0x00); - has_status = false; - extra_status = 0; - break; - case 0x05: - { - switch(extra_status) { - case 1: - write_status(0x16, 0x00, 0xa0, 0x00); - extra_status++; - break; - case 2: // st1 = first_track_number - write_status(0x17, TO_BCD(0x01), 0x00, 0x00); - extra_status++; - break; - case 3: - write_status(0x16, 0x00, 0xa1, 0x00); - extra_status++; - break; - case 4: - write_status(0x17, d_cdrom->read_signal(SIG_TOWNS_CDROM_MAX_TRACK), 0x00, 0x00); - extra_status++; - break; - case 5: - write_status(0x16, 0x00, 0xa2, 0x00); - extra_status++; - break; - case 6: - uint32_t msf = d_cdrom->read_signal - { - uint32_t msf = d_cdrom->read_signal(SIG_TOWNS_CDROM_START_MSF_AA); - write_status(0x17, (msf & 0x00ff0000) >> 16, (msf & 0x0000ff00) >> 8, msf & 0x000000ff); - exra_status++; - } - break; - default: - if(extra_status == 7) { - d_cdrom->write_signal(SIG_TOWNS_CDROM_SET_STAT_TRACK, 0x01, 0x01); - } - if((extra_status & 0x01) != 0) { - uint32_t adr_control = d_cdrom->read_signal(SIG_TOWNS_CDROM_GET_ADR); - write_status(0x16, ((adr_control & 0x0f) << 4) | ((adr_control >> 4) & 0x0f), TO_BCD((extra_status / 2) - 2), 0x00); - extra_status++; - } else { - uint32_t msf = d_cdrom->read_signal(SIG_TOWNS_CDROM_START_MSF); - write_status(0x17, (msf & 0x00ff0000) >> 16, (msf & 0x0000ff00) >> 8, msf & 0x000000ff); - if(d_cdrom->read_signal(SIG_TOWNS_CDROM_REACHED_MAX_TRACK) == 0){ - extra_status++; - } else { - extra_status = 0; - } - } - break; - } - } - case 0x06: // CDDA status - { - switch(extra_status) { - case 1: // Get current track - write_status(0x18, 0x00, d_cdrom->read_signal(SIG_TOWNS_CDROM_CURRENT_TRACK), 0x00); - extra_status++; - break; - case 2: // Get current position - { - uint32_t msf = d_cdrom->read_signal(SIG_TOWNS_CDROM_RELATIVE_MSF); - write_status(0x19, (msf >> 16) & 0xff, (msf >> 8) & 0xff, msf & 0xff); - extra_status++; - } - break; - case 3: // Current_msf - { - uint32_t msf = d_cdrom->read_signal(SIG_TOWNS_CDROM_ABSOLUTE_MSF); - write_status(0x19, 0x00, (msf >> 16) & 0xff, (msf >> 8) & 0xff); - extra_status++; - } - break; - case 4: - { - uint32_t msf = d_cdrom->read_signal(SIG_TOWNS_CDROM_ABSOLUTE_MSF); - write_status(0x19, msf & 0xff, 0x00, 0x00); - extra_status = 0; - } - break; - } - break; - - } - case 0x84: - write_status(0x11, 0x00, 0x00, 0x00); - extra_status = 0; - break; - } - } - } - break; - case 0x4: // - if(pio_transfer) { - val = d_scsi_host->read_dma_io8(0); - } - break; - case 0xc: // Sub code status register - val = d_cdrom->get_subq_status(); - break; - case 0xd: - val = d_cdrom->read_subq(); - break; - } - return val; -} - -void CDC::read_cdrom(bool req_reply) -{ - uint8_t* command = d_cdrom->command; - extra_status = 0; - if(!(d_cdrom->is_device_ready())) { - if(req_reply) write_status(0x10, 0x00, 0x00, 0x00); - return; - } - - uint8_t m1, s1, f1; - uint8_t m2, s2, f2; - f2 = (uint8_t)(param_fifo->read() & 0xff); - s2 = (uint8_t)(param_fifo->read() & 0xff); - m2 = (uint8_t)(param_fifo->read() & 0xff); - - f1 = (uint8_t)(param_fifo->read() & 0xff); - s1 = (uint8_t)(param_fifo->read() & 0xff); - m1 = (uint8_t)(param_fifo->read() & 0xff); - - uint32_t lba1 = ((uint32_t)m1 & 0x1f) * 0x10000 + ((uint32_t)s1) * 0x100 + (uint32_t)f1; - uint32_t lba2 = ((uint32_t)m2 & 0x1f) * 0x10000 + ((uint32_t)s2) * 0x100 + (uint32_t)f2; - uint32_t __remain; - int track = get_track(lba1); - if(track < 2) { - if(lba1 >= 150) { - lba1 = lba1 - 150; - } else { - lba1 = 0; - } - if(lba2 >= 150) { - lba2 = lba2 - 150; - } else { - lba2 = 0; - } - } - set_cdda_status(CDDA_OFF); - if(lba1 > lba2) { // NOOP? - extra_status = 0; - write_status(0x01, 0x00, 0x00, 0x00); - return; - } - __remain = lba2 - lba1; - seek_time = get_seek_time(lba1); - - command[0] = SCSI_CMD_READ12; - command[1] = 0; // LUN = 0 - command[2] = 0; - command[3] = m2 & 0x1f; - command[4] = s2; - command[5] = f2; - - command[6] = 0; - command[7] = (uint8_t)((__remain / 0x10000) & 0xff); - command[8] = (uint8_t)((__remain / 0x100) & 0xff); - command[9] = (uint8_t) (__remain % 0x100); - - if(req_reply) { - extra_status = 2; - write_status(0x00, 0x00, 0x00, 0x00); - } else { - extra_status = 0; - if(pio_transfer) { - write_status(0x21, 0x00, 0x00, 0x00); - } else { - write_status(0x22, 0x00, 0x00, 0x00); - } - } - submpu_ready = false; - d_cdrom->start_command(); -} - -void CDC::stop_cdda(bool req_reply) -{ - uint8_t* command = d_cdrom->command; - if(!(d_cdrom->is_device_ready())) { - if(req_reply) write_status(0x10, 0x00, 0x00, 0x00); - return; - } - command[0] = TOWNS_CDROM_CDDA_STOP; - command[1] = 0; - command[2] = 0; - command[3] = (uint8_t)(param_fifo->read() & 0xff); - command[4] = (uint8_t)(param_fifo->read() & 0xff); - commadn[5] = (uint8_t)(param_fifo->read() & 0xff); - command[6] = 0; - command[7] = (uint8_t)(param_fifo->read() & 0xff); - command[8] = (uint8_t)(param_fifo->read() & 0xff); - command[9] = (uint8_t)(param_fifo->read() & 0xff); - if(req_reply) { - extra_status = 1; - write_status(0x00, 0x00, 0x00, 0x00); - } - submpu_ready = false; - d_cdrom->start_command(); -} - -void CDC::stop_cdda2(bool req_reply) -{ - uint8_t* command = d_cdrom->command; - if(!(d_cdrom->is_device_ready())) { - if(req_reply) write_status(0x10, 0x00, 0x00, 0x00); - return; - } - command[0] = TOWNS_CDROM_CDDA_STOP; - command[1] = 0; - command[2] = 0; - command[3] = (uint8_t)(param_fifo->read() & 0xff); - command[4] = (uint8_t)(param_fifo->read() & 0xff); - commadn[5] = (uint8_t)(param_fifo->read() & 0xff); - command[6] = 0; - command[7] = (uint8_t)(param_fifo->read() & 0xff); - command[8] = (uint8_t)(param_fifo->read() & 0xff); - command[9] = (uint8_t)(param_fifo->read() & 0xff); - if(req_reply) { - extra_status = 1; - write_status(0x00, 0x00, 0x00, 0x00); - } - submpu_ready = false; - d_cdrom->start_command(); -} - -void CDC::unpause_cdda(bool rea_reply) -{ - uint8_t* command = d_cdrom->command; - if(!(d_cdrom->is_device_ready())) { - if(req_reply) write_status(0x10, 0x00, 0x00, 0x00); - return; - } - command[0] = TOWNS_CDROM_CDDA_UNPAUSE; - command[1] = 0; - command[2] = 0; - command[3] = (uint8_t)(param_fifo->read() & 0xff); - command[4] = (uint8_t)(param_fifo->read() & 0xff); - commadn[5] = (uint8_t)(param_fifo->read() & 0xff); - command[6] = 0; - command[7] = (uint8_t)(param_fifo->read() & 0xff); - command[8] = (uint8_t)(param_fifo->read() & 0xff); - command[9] = (uint8_t)(param_fifo->read() & 0xff); - if(req_reply) { - extra_status = 1; - write_status(0x00, 0x03, 0x00, 0x00); - } - submpu_ready = false; - d_cdrom->start_command(); -} - -void CDC::play_cdda(bool req_reply) -{ - uint8_t* command = d_cdrom->command; - if(!(d_cdrom->is_device_ready())) { - if(req_reply) write_status(0x10, 0x00, 0x00, 0x00); - return; - } - command[0] = TOWNS_CDROM_CDDA_PLAY; - command[1] = 0; - command[2] = 0; - command[3] = (uint8_t)(param_fifo->read() & 0xff); - command[4] = (uint8_t)(param_fifo->read() & 0xff); - commadn[5] = (uint8_t)(param_fifo->read() & 0xff); - command[6] = 0; - command[7] = (uint8_t)(param_fifo->read() & 0xff); - command[8] = (uint8_t)(param_fifo->read() & 0xff); - command[9] = (uint8_t)(param_fifo->read() & 0xff); - - - if(req_reply) { - extra_status = 1; - write_status(0x00, 0x03, 0x00, 0x00); - } - submpu_ready = false; - d_cdrom->start_command(); - -} - -void CDC::write_status(uint8_t a, uint8_t b, uint8_t c, uint8_t d) -{ - has_status = true; - stat_fifo->clear(); - stat_fifo->write(a); - stat_fifo->write(b); - stat_fifo->write(c); - stat_fifo->write(d); - if(stat_reply_intr) { - submpu_intr = true; - if(!(submpu_intr_mask)) { - write_signals(&output_submpu_intr, 0xffffffff); - } - submpu_ready = true; - } -} - -void CDC::enqueue_command_play(uint8_t cmd) -{ - //write_signals(&output_submpu_intr, 0x00000000); - if((d_cdrom->read_signal(SIG_TOWNS_CDROM_IS_MEDIA_INSERTED) == 0x00000000) && (cmd != 0xa0)) { // Not Inserted - if(req_status) { - extra_status = 0; - write_status(0x10, 0x00, 0x00, 0x00); - } - } else { - has_status = false; - switch(cmd & 0x1f) { - case 0x00: // SEEK - if(req_status) { - extra_status = 1; - write_status(0x00, 0x00, 0x00, 0x00); - } - // ToDo: REAL SEEK - break; - case 0x01: // Unknown (from MAME) - if(req_status) { - extra_status = 0; - write_status(0x00, 0xff, 0xff, 0xff); - } - break; - case 0x02: // READ (Mode1) - read_cdrom(req_status); - break; - case 0x04: // PLAY CDDA - play_cdda(req_status); - break; - case 0x05: // Read TOC - if(req_status) { - extra_status = 1; - write_status(0x00, 0x00, 0x00, 0x00); - } else { - extra_status = 2; - write_status(0x16, 0x00, 0xa0, 0x00); - } - break; - case 0x06: // CD-DA Stats (?) - extra_status = 1; - write_status(0x00, 0x00, 0x00, 0x00); - break; - case 0x1f: // ?? - extra_status = 0; - write_status(0x00, 0x00, 0x00, 0x00); - break; - default: // Illegal command - extra_status = 0; - write_status(0x10, 0x00, 0x00, 0x00); - break; - } - } -} - -void CDC::enqueue_command_status(uint8_t cmd) -{ - //write_signals(&output_submpu_intr, 0x00000000); - if((d_cdrom->read_signal(SIG_TOWNS_CDROM_IS_MEDIA_INSERTED) == 0x00000000) && (cmd != 0xa0)) { // Not Inserted - if(req_status) { - extra_status = 0; - write_status(0x10, 0x00, 0x00, 0x00); - } - } else { - has_status = false; - switch(cmd & 0x1f) { - case 0x00: // set state - if(req_status) { - extra_status = 0; - if(d_cdrom->read_signal(SIG_SCSI_CDROM_PLAYING) != 0) { // Active() && !(paused) - write_status(0x00, 0x03, 0x00, 0x00); - } else { - write_status(0x00, 0x01, 0x00, 0x00); - } - } - break; - case 0x01: // set state (CDDASET) - if(req_status) { - extra_status = 0; - write_status(0x00, 0x00, 0x00, 0x00); - } - break; - case 0x04: // STOP CDDA - stop_cdda(req_status); - break; - case 0x05: // STOP CDDA (Difference from $84?) - stop_cdda2(req_status); - break; - case 0x07: // UNPAUSE CDDA - unpause_cdda(req_status); - break; - default: // Illegal command - extra_status = 0; - write_status(0x10, 0x00, 0x00, 0x00); - break; - } - } -} - -void CDC::write_signal(int ch, uint32_t data, uint32_t mask) -{ - switch(ch) { - case SIG_TOWNS_CDC_DRQ: - if((dma_transfer) && ((data & mask) != 0)) { - software_transfer_phase = false; - write_signals(&output_dma_line, 0xffffffff); // Indirect call do_dma(). - } else if((pio_transfer) && ((data & mask) != 0)) { - software_transfer_phase = true; - } else if(!((data & mask) != 0)) { - software_transfer_phase = false; - } - break; - case SIG_TOWNS_CDC_CDROM_DONE: - if((data & mask) != 0) { - submpu_intr = true; - if(!(submpu_intr_mask)) { - write_signals(&output_submpu_intr, 0xffffffff); - } - submpu_ready = true; - } - break; - case SIG_TOWNS_CDC_IRQ: - dma_intr = ((data & mask) != 0); - if((dma_intr & dma_intr_mask)) { - if(stat_reply_intr) { - write_signals(&output_dma_intr, 0xffffffff); - } - } else if(!(dma_intr) && (dma_intr_mask)) { - write_signals(&output_dma_intr, 0x00000000); - } - break; - case SIG_TOWNS_CDC_BSY: - busy_status = ((data & mask) != 0); - break; - case SIG_TOWNS_CDC_CD: - cd_status = ((data & mask) != 0); - if((cd_status) && !(msg_status)) { // SCSI_PHASE_STATUS or SCSI_PHASE_COMMAND - submpu_ready = true; - } - break; - case SIG_TOWNS_CDC_IO: - io_status = ((data & mask) != 0); - break; - case SIG_TOWNS_CDC_MSG: - msg_status = ((data & mask) != 0); - break; - case SIG_TOWNS_CDC_REQ: - req_status = ((data & mask) != 0); - break; - case SIG_TOWNS_CDC_ACK: - ack_status = ((data & mask) != 0); - break; - - } -} - -uint32_t CDC::read_dma_io8(uint32_t addr) -{ - return (uint32_t)(d_scsi_host->read_dma_io8(addr)); -} - -uint32_t CDC::read_dma_io16(uint32_t addr) -{ - pair16_t d; - d.b.l = d_scsi_host->read_dma_io8(addr); - d.b.h = d_scsi_host->read_dma_io8(addr); - return (uint32_t)(d.u16); -} - -void CDC::write_dma_io8(uint32_t addr, uint32_t data) -{ - d_scsi_host->write_dma_io8(addr, data); -} - -void CDC::write_dma_io16(uint32_t addr, uint32_t data) -{ - pair32_t _d; - _d.d = data; - d_scsi_host->write_dma_io8(addr, _d.b.l); - d_scsi_host->write_dma_io8(addr, _d.b.h); -} - - - -#define STATE_VERSION 1 - -bool CDC::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - if(!(param_fifo->process_state((void *)state_fio, loading))) { - return false; - } - if(!(stat_fifo->process_state((void *)state_fio, loading))) { - return false; - } - - state_fio->StateValue(has_status); - state_fio->StateValue(extra_status); - state_fio->StateValue(submpu_ready); - state_fio->StateValue(software_transfer_phase); - state_fio->StateValue(dma_transfer); - state_fio->StateValue(pio_transfer); - - state_fio->StateValue(dma_intr); - state_fio->StateValue(submpu_intr); - state_fio->StateValue(dma_intr_mask); - state_fio->StateValue(submpu_intr_mask); - - state_fio->StateBuffer(w_regs, sizeof(w_regs), 1); - - state_fio->StateValue(busy_status); - state_fio->StateValue(cd_status); - state_fio->StateValue(io_status); - state_fio->StateValue(msg_status); - state_fio->StateValue(req_status); - state_fio->StateValue(ack_status); - - return true; - -} - -} diff --git a/source/src/vm/fmtowns/cdc.h b/source/src/vm/fmtowns/cdc.h deleted file mode 100644 index ad557635b..000000000 --- a/source/src/vm/fmtowns/cdc.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - Author : Kyuma.Ohta - Date : 2019.01.29- - - [FM-Towns CD Controller] -*/ -#pragma once - -#include "../device.h" -#include "../../common.h" - - -#define SIG_TOWNS_CDC_DRQ 1 -#define SIG_TOWNS_CDC_IRQ 2 -#define SIG_TOWNS_CDC_BSY 3 -#define SIG_TOWNS_CDC_CD 4 -#define SIG_TOWNS_CDC_IO 5 -#define SIG_TOWNS_CDC_MSG 6 -#define SIG_TOWNS_CDC_REQ 7 -#define SIG_TOWNS_CDC_ACK 8 -#define SIG_TOWNS_CDC_CDROM_DONE 9 - -class SCSI_HOST; -class FIFO; -namespace TOWNS { - class TOWNS_CDROM; -} - -namespace TOWNS { -class CDC : public DEVICE { -protected: - outputs_t output_dma_line; - outputs_t output_dma_intr; - outputs_t output_submpu_intr; - - SCSI_HOST* d_scsi_host; - TOWNS_CDROM* d_cdrom; - - FIFO* param_fifo; - FIFO* stat_fifo; - - bool has_status; - int extra_status; - bool submpu_ready; - bool software_transfer_phase; - bool dma_transfer; - bool pio_transfer; - - bool dma_intr; - bool submpu_intr; - bool dma_intr_mask; - bool submpu_intr_mask; - - bool busy_status; - bool busy_status; - bool cd_status; - bool io_status; - bool msg_status; - bool req_status; - bool ack_status; - - uint8_t w_regs[16]; - - virtual void read_cdrom(bool req_reply); - virtual void stop_cdda(bool req_reply); - virtual void stop_cdda2(bool req_reply); - virtual void unpause_cdda(bool rea_reply); - virtual void play_cdda(bool req_reply); - virtual void write_status(uint8_t a, uint8_t b, uint8_t c, uint8_t d); - virtual void enqueue_command_play(uint8_t cmd); - virtual void enqueue_command_status(uint8_t cmd); - -public: - CDC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) - { - initialize_output_signals(&output_dma_line); - initialize_output_signals(&output_dma_intr); - initialize_output_signals(&output_submpu_intr); - - set_device_name(_T("FM-Towns CD-ROM controller")); - } - ~CDC() { } - - virtual void initialize(); - virtual void release(); - virtual void reset(); - - virtual void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); - - virtual void __FASTCALL write_io8(uint32_t address, uint32_t data); - virtual uint32_t __FASTCALL read_io8(uint32_t address); - - virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr); - virtual uint32_t __FASTCALL read_dma_io16(uint32_t addr); - virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); - virtual void __FASTCALL write_dma_io16(uint32_t addr, uint32_t data); - - virtual bool process_state(FILEIO* state_fio, bool loading); - - virtual void set_context_scsi_host(SCSI_HOST* dev); - virtual void set_context_cdrom(TOWNS_CDROM* dev); - - void set_context_dmareq_line(DEVICE* dev, int id, uint32_t mask) - { - register_output_signals(&output_dma_line, dev, id, mask); - } - - void set_context_dmaint_line(DEVICE* dev, int id, uint32_t mask) - { - register_output_signals(&output_dma_intr, dev, id, mask); - } - - void set_context_mpuint_line(DEVICE* dev, int id, uint32_t mask) - { - register_output_signals(&output_submpu_intr, dev, id, mask); - } -}; - -} diff --git a/source/src/vm/fmtowns/cmos.cpp b/source/src/vm/fmtowns/cmos.cpp deleted file mode 100644 index 75058babb..000000000 --- a/source/src/vm/fmtowns/cmos.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - FUJITSU FMR-50 Emulator 'eFMR-50' - FUJITSU FMR-60 Emulator 'eFMR-60' - - Author : Takeda.Toshiya - Date : 2008.05.01 - - - [ cmos ] -*/ - -#include "cmos.h" - -void CMOS::initialize() -{ - // load cmos image - memset(cmos, 0, sizeof(cmos)); - modified = false; - - FILEIO* fio = new FILEIO(); - if(fio->Fopen(create_local_path(_T("CMOS.BIN")), FILEIO_READ_BINARY)) { - fio->Fread(cmos, sizeof(cmos), 1); - fio->Fclose(); - } - delete fio; -} - -void CMOS::release() -{ - if(modified) { - FILEIO* fio = new FILEIO(); - if(fio->Fopen(create_local_path(_T("CMOS.BIN")), FILEIO_WRITE_BINARY)) { - fio->Fwrite(cmos, sizeof(cmos), 1); - fio->Fclose(); - } - delete fio; - } -} - -void CMOS::reset() -{ - bank = 0; -} - -void CMOS::write_io8(uint32_t addr, uint32_t data) -{ - switch(addr) { - case 0x90: - bank = data & 3; - break; - default: - if(!(addr & 1)) { - if(cmos[bank][(addr >> 1) & 0x7ff] != data) { - cmos[bank][(addr >> 1) & 0x7ff] = data; - modified = true; - } - } - break; - } -} - -uint32_t CMOS::read_io8(uint32_t addr) -{ - if(!(addr & 1)) { - return cmos[bank][(addr >> 1) & 0x7ff]; - } - return 0xff; -} - -#define STATE_VERSION 1 - -void CMOS::save_state(FILEIO* state_fio) -{ - state_fio->FputUint32(STATE_VERSION); - state_fio->FputInt32(this_device_id); - - state_fio->Fwrite(cmos, sizeof(cmos), 1); - state_fio->FputBool(modified); - state_fio->FputUint8(bank); -} - -bool CMOS::load_state(FILEIO* state_fio) -{ - if(state_fio->FgetUint32() != STATE_VERSION) { - return false; - } - if(state_fio->FgetInt32() != this_device_id) { - return false; - } - state_fio->Fread(cmos, sizeof(cmos), 1); - modified = state_fio->FgetBool(); - bank = state_fio->FgetUint8(); - return true; -} - diff --git a/source/src/vm/fmtowns/cmos.h b/source/src/vm/fmtowns/cmos.h deleted file mode 100644 index 68b9682d5..000000000 --- a/source/src/vm/fmtowns/cmos.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - FUJITSU FMR-50 Emulator 'eFMR-50' - FUJITSU FMR-60 Emulator 'eFMR-60' - - Author : Takeda.Toshiya - Date : 2008.05.01 - - - [ cmos ] -*/ - -#ifndef _CMOS_H_ -#define _CMOS_H_ - -#include "../vm.h" -#include "../../emu.h" -#include "../device.h" - -class CMOS : public DEVICE -{ -private: -#ifdef _FMRCARD - uint8_t cmos[4][0x800]; -#else - uint8_t cmos[1][0x800]; -#endif - bool modified; - uint8_t bank; - -public: - CMOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {} - ~CMOS() {} - - // common functions - void initialize(); - void release(); - void reset(); - void __FASTCALL write_io8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_io8(uint32_t addr); - void save_state(FILEIO* state_fio); - bool load_state(FILEIO* state_fio); - - // unique function - uint8_t* get_cmos() - { - return cmos[0]; - } -}; - -#endif - diff --git a/source/src/vm/fmtowns/floppy.cpp b/source/src/vm/fmtowns/floppy.cpp index ed0c4e3a8..98033dd54 100644 --- a/source/src/vm/fmtowns/floppy.cpp +++ b/source/src/vm/fmtowns/floppy.cpp @@ -9,14 +9,27 @@ */ #include "floppy.h" +#include "../disk.h" #include "../i8259.h" #include "../mb8877.h" - +namespace FMTOWNS { void FLOPPY::initialize() { - drvreg = drvsel = 0; + drive_swapped = false; // ToDo: implement via config; + for(int i = 0; i < 4; i++) { + is_inserted[i] = false; + } +} + +void FLOPPY::reset() +{ + drvreg = 0; irq = irqmsk = false; - changed[0] = changed[1] = changed[2] = changed[3] = false; + drvsel = (drive_swapped) ? 2 : 0; + + for(int i = 0; i < MAX_DRIVE; i++) { + d_fdc->set_drive_type(i, DRIVE_TYPE_2HD); + } } void FLOPPY::write_io8(uint32_t addr, uint32_t data) @@ -28,11 +41,73 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data) // drive control register irqmsk = ((data & 1) != 0); update_intr(); - d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10); + if((drvsel < 2) || (machine_id < 0x0200)) { + d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x10); + } else { + // 5 Inch + d_fdc->write_signal(SIG_MB8877_MOTOR, data, 0x40); + } d_fdc->write_signal(SIG_MB8877_SIDEREG, data, 4); - break; + // ToDo: Single dencity. + { + DISK *_disk = d_fdc->get_disk_handler(drvsel); + uint8_t _media = d_fdc->get_media_type(drvsel); + if((data & 0x02) != 0) { // DDEN=2D/2DD/2HD + if(_disk != NULL) { + _disk->track_mfm = true; + } + if((data & 0x20) == 0) { // 2HD or 144 + switch(_media) { + case MEDIA_TYPE_2HD: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2HD); + break; + case MEDIA_TYPE_144: // ToDo: Write failure, Read success. 20200925 K.O + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_144); + break; + default: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG. + break; + } + } else { + switch(_media) { + case MEDIA_TYPE_2DD: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D); + break; + case MEDIA_TYPE_2D: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D); + break; + default: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG. + break; + } + } + } else { // 2DD or 2D or 1D + if(_disk != NULL) { + _disk->track_mfm = false; + } + if((data & 0x20) == 0) { // 2HD or 144 + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG. + // And maybe single density of 2HD/144HD don't exist. + } else { + // OK. Now use single density disk. + switch(_media) { + case MEDIA_TYPE_2DD: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D); + break; + case MEDIA_TYPE_2D: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_2D); + break; + default: + d_fdc->set_drive_type(drvsel, DRIVE_TYPE_UNK); // CLOCK IS WRONG. + break; + } + } + } + } + break; case 0x20c: // drive select register + // ToDo: IN USE bit if(data & 1) { nextdrv = 0; } else if(data & 2) { @@ -42,26 +117,45 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data) } else if(data & 8) { nextdrv = 3; } + if(drive_swapped) { + nextdrv = (nextdrv + 2) & 3; + } if(drvsel != nextdrv) { d_fdc->write_signal(SIG_MB8877_DRIVEREG, drvsel = nextdrv, 3); } + d_fdc->set_drive_type(drvreg & 3, ((data & 0x40) != 0) ? DRIVE_TYPE_2HD : DRIVE_TYPE_2DD); drvreg = data; break; + case 0x20e: + drive_swapped = ((data & 0x01) != 0); + break; } } uint32_t FLOPPY::read_io8(uint32_t addr) { + uint8_t val; switch(addr & 0xffff) { case 0x208: - if(changed[drvsel]) { - changed[drvsel] = false; - return d_fdc->fdc_status() | 0xe1; // fdd*2 + if(machine_id >= 0x0200) { + if(is_inserted[drvsel]) { // OK? + val = 0x00; + } else { + val = 0x01; + } + } else { + val = 0x01; } -// return d_fdc->fdc_status() | 0x60; // fdd*1 - return d_fdc->fdc_status() | 0xe0; // fdd*2 + is_inserted[drvsel] = false; + if(d_fdc->is_disk_inserted(drvsel)) val |= 0x02; + val |= 0x04; // ToDo 5.25 inch + val |= 0x80; // 2 Drives (maybe default, will change) 20200925 K.O + return val; case 0x20c: return drvreg; + case 0x20e: + val = (drive_swapped) ? 1 : 0; + return val; } return 0xff; } @@ -76,36 +170,31 @@ void FLOPPY::write_signal(int id, uint32_t data, uint32_t mask) void FLOPPY::update_intr() { - d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR6, irq && irqmsk ? 1 : 0, 1); + write_signals(&output_intr_line, irq && irqmsk ? 1 : 0); } -#define STATE_VERSION 1 - -void FLOPPY::save_state(FILEIO* state_fio) -{ - state_fio->FputUint32(STATE_VERSION); - state_fio->FputInt32(this_device_id); - - state_fio->FputInt32(drvreg); - state_fio->FputInt32(drvsel); - state_fio->FputBool(irq); - state_fio->FputBool(irqmsk); - state_fio->Fwrite(changed, sizeof(changed), 1); -} +#define STATE_VERSION 2 -bool FLOPPY::load_state(FILEIO* state_fio) +bool FLOPPY::process_state(FILEIO* state_fio, bool loading) { - if(state_fio->FgetUint32() != STATE_VERSION) { + if(!state_fio->StateCheckUint32(STATE_VERSION)) { return false; } - if(state_fio->FgetInt32() != this_device_id) { + if(!state_fio->StateCheckInt32(this_device_id)) { return false; } - drvreg = state_fio->FgetInt32(); - drvsel = state_fio->FgetInt32(); - irq = state_fio->FgetBool(); - irqmsk = state_fio->FgetBool(); - state_fio->Fread(changed, sizeof(changed), 1); + + state_fio->StateValue(drvreg); + state_fio->StateValue(drvsel); + state_fio->StateValue(irq); + state_fio->StateValue(irqmsk); + state_fio->StateValue(drive_swapped); + + state_fio->StateValue(cpu_id); + state_fio->StateValue(machine_id); + state_fio->StateBuffer(is_inserted, sizeof(is_inserted), 1); + return true; } +} diff --git a/source/src/vm/fmtowns/floppy.h b/source/src/vm/fmtowns/floppy.h index 3a6da6c82..c56a5fad1 100644 --- a/source/src/vm/fmtowns/floppy.h +++ b/source/src/vm/fmtowns/floppy.h @@ -19,42 +19,63 @@ class MB8877; +namespace FMTOWNS { class FLOPPY : public DEVICE { private: MB8877 *d_fdc; - DEVICE *d_pic; - + outputs_t output_intr_line; int drvreg, drvsel; - bool irq, irqmsk, changed[4]; - void update_intr(); + bool irq, irqmsk; + bool drive_swapped; + uint16_t machine_id; + uint8_t cpu_id; + bool is_removed; + bool is_inserted[4]; + void update_intr(); + public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {} + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + initialize_output_signals(&output_intr_line); + machine_id = 0x0100; + cpu_id = 0x01; + } ~FLOPPY() {} // common functions void initialize(); + void reset(); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void save_state(FILEIO* state_fio); - bool load_state(FILEIO* state_fio); + bool process_state(FILEIO* state_fio, bool loading); // unique functions void set_context_fdc(MB8877* device) { d_fdc = device; } - void set_context_pic(DEVICE* device) + void set_context_intr_line(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&output_intr_line, dev, id, mask); + } + void set_machine_id(uint16_t val) + { + machine_id = val & 0xfff8; + } + void set_cpu_id(uint16_t val) { - d_pic = device; + cpu_id = val & 0x07; } void change_disk(int drv) { - changed[drv] = true; + is_inserted[drv] = true; } }; +} #endif diff --git a/source/src/vm/fmtowns/fmtowns.cpp b/source/src/vm/fmtowns/fmtowns.cpp index 25d63dfe9..d4b19bb68 100644 --- a/source/src/vm/fmtowns/fmtowns.cpp +++ b/source/src/vm/fmtowns/fmtowns.cpp @@ -1,8 +1,8 @@ /* - FUJITSU FM-Towns Emulator 'eFMR-60' + FUJITSU FM-Towns Emulator 'eFMTowns' Author : Kyuma Ohta - Date : 216.12.28 - + Date : 2016.12.28 - [ virtual machine ] History: @@ -19,17 +19,28 @@ #include "../i8253.h" #include "../i8259.h" -#include "../i386.h" +#include "../i386_np21.h" +//#include "../i386.h" #include "../io.h" #include "../mb8877.h" #include "../msm58321.h" +#include "../noise.h" #include "../pcm1bit.h" +#include "../harddisk.h" #include "../scsi_hdd.h" -#include "../scsi_host.h" +#include "./towns_scsi_host.h" #include "../upd71071.h" +#include "towns_cdrom.h" #include "towns_crtc.h" +#include "towns_dictionary.h" +#include "towns_dmac.h" +#include "towns_memory.h" +#include "towns_sprite.h" +#include "towns_sysrom.h" +#include "towns_vram.h" + // Electric Volume //#include "mb87078.h" //YM-2612 "OPN2" @@ -38,25 +49,57 @@ #include "rf5c68.h" //AD7820 ADC #include "ad7820kr.h" +#include "ym2612.h" // 80387? #ifdef USE_DEBUGGER #include "../debugger.h" #endif -#include "cmos.h" -#include "floppy.h" -#include "keyboard.h" -#include "memory.h" -#include "scsi.h" -//#include "serial.h" -#include "timer.h" +#include "./adpcm.h" +//#include "./cdc.h" +#include "./floppy.h" +#include "./fontroms.h" +#include "./joystick.h" +#include "./joypad.h" +#include "./keyboard.h" +#include "./msdosrom.h" +#include "./scsi.h" +#include "./serialrom.h" +#include "./timer.h" +#include "./iccard.h" + +#include "./towns_planevram.h" // ---------------------------------------------------------------------------- // initialize // ---------------------------------------------------------------------------- - -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +using FMTOWNS::ADPCM; +//using FMTOWNS::CDC; +using FMTOWNS::DICTIONARY; +using FMTOWNS::FLOPPY; +using FMTOWNS::FONT_ROMS; +using FMTOWNS::JOYSTICK; +using FMTOWNS::JOYPAD; +using FMTOWNS::KEYBOARD; +using FMTOWNS::MSDOSROM; +using FMTOWNS::SCSI; +using FMTOWNS::SERIAL_ROM; +using FMTOWNS::SYSROM; +using FMTOWNS::TIMER; +using FMTOWNS::TOWNS_ICCARD; + +using FMTOWNS::TOWNS_CDROM; +using FMTOWNS::TOWNS_CRTC; +using FMTOWNS::TOWNS_DMAC; +using FMTOWNS::TOWNS_MEMORY; +using FMTOWNS::TOWNS_SCSI_HOST; +using FMTOWNS::TOWNS_SPRITE; +using FMTOWNS::TOWNS_VRAM; +using FMTOWNS::PLANEVRAM; + + +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { /* Machine ID & CPU ID @@ -99,8 +142,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io = new IO(this, emu); crtc = new TOWNS_CRTC(this, emu); - cdc = new CDC(this, emu); - cdc_scsi = new SCSI_HOST(this, emu); cdrom = new TOWNS_CDROM(this, emu); memory = new TOWNS_MEMORY(this, emu); @@ -108,20 +149,22 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) sprite = new TOWNS_SPRITE(this, emu); sysrom = new SYSROM(this, emu); msdosrom = new MSDOSROM(this, emu); - fontrom = new FONT_ROM(this, emu); + fontrom = new FONT_ROMS(this, emu); dictionary = new DICTIONARY(this, emu); #if defined(HAS_20PIX_FONTS) fontrom_20pix = new FONT_ROM_20PIX(this, emu); #endif serialrom = new SERIAL_ROM(this, emu); + adpcm = new ADPCM(this, emu); - mixer = new MIXER(this, emu); // Pseudo mixer. - +// mixer = new MIXER(this, emu); // Pseudo mixer. + + planevram = new PLANEVRAM(this, emu); adc = new AD7820KR(this, emu); rf5c68 = new RF5C68(this, emu); - e_volume[0] = new MB87878(this, emu); - e_volume[1] = new MB87878(this, emu); +// e_volume[0] = new MB87878(this, emu); +// e_volume[1] = new MB87878(this, emu); sio = new I8251(this, emu); pit0 = new I8253(this, emu); @@ -131,31 +174,47 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) rtc = new MSM58321(this, emu); beep = new PCM1BIT(this, emu); opn2 = new YM2612(this, emu); + + seek_sound = new NOISE(this, emu); + head_up_sound = new NOISE(this, emu); + head_down_sound = new NOISE(this, emu); +// scsi_host = new TOWNS_SCSI_HOST(this, emu); scsi_host = new SCSI_HOST(this, emu); - scsi_host->set_device_name(_T("SCSI HOST")); + for(int i = 0; i < 7; i++) { - if(FILEIO::IsFileExisting(create_local_path(_T("SCSI%d.DAT"), i))) { - SCSI_HDD* scsi_hdd = new SCSI_HDD(this, emu); -#if defined(_USE_QT) - char d_name[64] = {0}; - snprintf(d_name, 64, "SCSI DISK #%d", i + 1); - scsi_hdd->set_device_name(d_name); -#endif - scsi_hdd->scsi_id = i; - scsi_hdd->set_context_interface(scsi_host); - scsi_host->set_context_target(scsi_hdd); - } + scsi_hdd[i] = NULL; + } +#if defined(USE_HARD_DISK) + for(int i = 0; i < USE_HARD_DISK; i++) { + scsi_hdd[i] = new SCSI_HDD(this, emu); + scsi_hdd[i]->set_device_name(_T("SCSI Hard Disk Drive #%d"), i + 1); + scsi_hdd[i]->scsi_id = i ; + scsi_hdd[i]->set_disk_handler(0, new HARDDISK(emu)); + scsi_hdd[i]->set_context_interface(scsi_host); + my_sprintf_s(scsi_hdd[i]->vendor_id, 9, "FUJITSU"); + my_sprintf_s(scsi_hdd[i]->product_id, 17, "SCSI-HDD"); + scsi_host->set_context_target(scsi_hdd[i]); } - dma = new UPD71071(this, emu); - extra_dma = new UPD71071(this, emu); +#endif + dma = new TOWNS_DMAC(this, emu); + extra_dma = new TOWNS_DMAC(this, emu); floppy = new FLOPPY(this, emu); keyboard = new KEYBOARD(this, emu); - memory = new TOWNS_MEMORY(this, emu); + joystick = new JOYSTICK(this, emu); scsi = new SCSI(this, emu); timer = new TIMER(this, emu); - + + iccard1 = new TOWNS_ICCARD(this, emu); +#if 0 + iccard2 = new TOWNS_ICCARD(this, emu); +#else + iccard2 = NULL; +#endif + joypad[0] = new JOYPAD(this, emu); + joypad[1] = new JOYPAD(this, emu); + uint16_t machine_id = 0x0100; // FM-Towns1 uint16_t cpu_id = 0x0001; // i386DX uint32_t cpu_clock = 16000 * 1000; // 16MHz @@ -208,8 +267,10 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #else // ToDo: Pentium Model (After HB). - #endif + event->set_frames_per_sec(FRAMES_PER_SEC); + event->set_lines_per_frame(LINES_PER_FRAME); + set_machine_type(machine_id, cpu_id); // set contexts event->set_context_cpu(cpu, cpu_clock); @@ -220,6 +281,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) mic_in_ch = -1; // Use pseudo mixer instead of event.Due to using ADC. +#if 0 line_mix_ch = -1; modem_mix_ch = -1; mic_mix_ch = -1; @@ -229,289 +291,369 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) beep_mix_ch = mixer->set_context_sound(beep); pcm_mix_ch = mixer->set_context_sound(rf5c68); opn2_mix_ch = mixer->set_context_sound(opn2); - cdc_mix_ch = mixer->set_context_sound(cdc); + cdc_mix_ch = mixer->set_context_sound(cdrom); mixer->set_interpolate_filter_freq(pcm_mix_ch, 4000); // channel, freq; disable if freq <= 0. - event->set_context_sound(mixer); +#else + // Temporally not use mixer. + event->set_context_sound(beep); + event->set_context_sound(opn2); + event->set_context_sound(rf5c68); + event->set_context_sound(cdrom); +#endif + fdc->set_context_noise_seek(seek_sound); + fdc->set_context_noise_head_down(head_down_sound); + fdc->set_context_noise_head_up(head_up_sound); + event->set_context_sound(seek_sound); + event->set_context_sound(head_down_sound); + event->set_context_sound(head_up_sound); - if(fdc->load_sound_data(MB8877_SND_TYPE_SEEK, _T("FDDSEEK.WAV"))) { - event->set_context_sound(fdc); - } - -/* pic 0 timer - 1 keyboard - 2 rs-232c - 3 ex rs-232c - 4 (option) - 5 (option) - 6 floppy drive or dma ??? - 7 (slave) - 8 scsi - 9 cd-rom controller - 10 (option) - 11 crtc vsync - 12 printer - 13 sound (OPN2 + ADPCM) - 14 (option) - 15 (reserve) - nmi 0 keyboard (RAS) - 1 extend slot - dma 0 floppy drive - 1 hard drive - 2 printer - 3 cd-rom controller - dma 4 extend slot - 5 (reserve) - 6 (reserve) - 7 (reserve) - - -*/ - - - +#ifdef USE_DEBUGGER + pit0->set_context_debugger(new DEBUGGER(this, emu)); + pit1->set_context_debugger(new DEBUGGER(this, emu)); +#endif pit0->set_context_ch0(timer, SIG_TIMER_CH0, 1); pit0->set_context_ch1(timer, SIG_TIMER_CH1, 1); - pit0->set_context_ch2(beep, SIG_PCM1BIT_SIGNAL, 1); + pit0->set_context_ch2(beep, SIG_PCM1BIT_SIGNAL, 1); pit0->set_constant_clock(0, 307200); pit0->set_constant_clock(1, 307200); pit0->set_constant_clock(2, 307200); - pit1->set_constant_clock(1, 1228800); - pic->set_context_cpu(cpu); - fdc->set_context_drq(dma, SIG_UPD71071_CH0, 1); + pit1->set_constant_clock(0, 1229900); + pit1->set_constant_clock(1, 1229900); + pit1->set_constant_clock(2, 1229900); +// pic->set_context_cpu(cpu); + pic->set_context_cpu(memory); fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1); rtc->set_context_data(timer, SIG_TIMER_RTC, 0x0f, 0); - rtc->set_context_busy(timer, SIG_TIMER_RTC, 0x80); + rtc->set_context_busy(timer, SIG_TIMER_RTC_BUSY, 0x80); scsi_host->set_context_irq(scsi, SIG_SCSI_IRQ, 1); scsi_host->set_context_drq(scsi, SIG_SCSI_DRQ, 1); + scsi_host->set_context_drq(keyboard, SIG_KEYBOARD_BOOTSEQ_END, 1); + dma->set_context_memory(memory); dma->set_context_ch0(fdc); dma->set_context_ch1(scsi_host); //dma->set_context_ch2(printer); - dma->set_context_ch3(cdc); + dma->set_context_ch3(cdrom); + dma->set_context_tc1(scsi, SIG_SCSI_EOT, 0xffffffff); + dma->set_context_tc3(cdrom, SIG_TOWNS_CDROM_DMAINT, 0xffffffff); + dma->set_context_ube1(scsi_host, SIG_SCSI_16BIT_BUS, 0x02); + dma->set_context_child_dma(extra_dma); floppy->set_context_fdc(fdc); - floppy->set_context_pic(pic); - keyboard->set_context_pic(pic); - sprite->set_context_vram(vram); + sprite->set_context_vram(vram); + sprite->set_context_font(fontrom); + sprite->set_context_crtc(crtc); +#ifdef USE_DEBUGGER + sprite->set_context_debugger(new DEBUGGER(this, emu)); +#endif + + vram->set_context_sprite(sprite); + vram->set_context_crtc(crtc); + + planevram->set_context_vram(vram); + planevram->set_context_sprite(sprite); + planevram->set_context_crtc(crtc); + + crtc->set_context_sprite(sprite); + crtc->set_context_vram(vram); + crtc->set_context_font(fontrom); //e_volume[0]->set_context_ch0(line_in, MB87878_VOLUME_LEFT); //e_volume[0]->set_context_ch1(line_in, MB87878_VOLUME_RIGHT); //e_volume[0]->set_context_ch2(NULL, MB87878_VOLUME_LEFT); //e_volume[0]->set_context_ch3(NULL, MB87878_VOLUME_RIGHT); - e_volume[1]->set_context_ch0(cdc, MB87878_VOLUME_LEFT); - e_volume[1]->set_context_ch1(cdc, MB87878_VOLUME_RIGHT); +// e_volume[1]->set_context_ch0(cdrom, MB87878_VOLUME_LEFT); +// e_volume[1]->set_context_ch1(cdrom, MB87878_VOLUME_RIGHT); //e_volume[1]->set_context_ch2(mic, MB87878_VOLUME_LEFT | MB87878_VOLUME_RIGHT); //e_volume[1]->set_context_ch3(modem, MB87878_VOLUME_LEFT | MB87878_VOLUME_RIGHT); + memory->set_context_cpu(cpu); + memory->set_context_dmac(dma); memory->set_context_vram(vram); - memory->set_context_rom(sys_rom); - memory->set_context_msdos(msdos_rom); - memory->set_context_dictionary(dict_rom); + memory->set_context_planevram(planevram); + memory->set_context_crtc(crtc); + memory->set_context_system_rom(sysrom); + memory->set_context_msdos(msdosrom); + memory->set_context_dictionary(dictionary); + memory->set_context_font_rom(fontrom); memory->set_context_beep(beep); - memory->set_context_serial_rom(serial_rom); + memory->set_context_serial_rom(serialrom); memory->set_context_sprite(sprite); - memory->set_context_machine_id(machine_id); - memory->set_context_cpu_id(cpu_id); - memory->set_context_cpu(cpu); + memory->set_context_pcm(rf5c68); + memory->set_context_iccard(iccard1, 0); + memory->set_context_iccard(iccard2, 1); - cdc->set_context_cdrom(cdrom); - cdc->set_context_scsi_host(cdc_scsi); - cdc->set_context_drq(dma, SIG_UPD71071_CH3, 0xff); - cdc->set_context_pic(pic, SIG_I8259_CHIP1 | SIG_I8259_IR1); - - crtc->set_context_vsync(pic, SIG_I8259_CHIP1 | SIG_I8259_IR3); // VSYNC - adpcm->set_context_pic(pic, SIG_I8259_CHIP1 | SIG_I8259_IR5); // ADPCM AND OPN2 adpcm->set_context_opn2(opn2); - adpcm->set_context_adpcm(rf5c68); + adpcm->set_context_rf5c68(rf5c68); adpcm->set_context_adc(adc); rf5c68->set_context_interrupt_boundary(adpcm, SIG_ADPCM_WRITE_INTERRUPT, 0xffffffff); - opn2->set_context_interrupt(adpcm, SIG_ADPCM_OPX_INTR, 0xffffffff); +#ifdef USE_DEBUGGER + rf5c68->set_context_debugger(new DEBUGGER(this, emu)); +#endif + opn2->set_context_irq(adpcm, SIG_ADPCM_OPX_INTR, 0xffffffff); adc->set_sample_rate(19200); adc->set_sound_bank(-1); adc->set_context_interrupt(adpcm, SIG_ADPCM_ADC_INTR, 0xffffffff); scsi->set_context_dma(dma); - scsi->set_context_pic(pic); scsi->set_context_host(scsi_host); + scsi->set_context_pic(pic); timer->set_context_pcm(beep); - timer->set_context_pic(pic); timer->set_context_rtc(rtc); + timer->set_context_halt_line(cpu, SIG_CPU_HALTREQ, 0xffffffff); + + joystick->set_context_enable0(joypad[0], SIG_JOYPAD_ENABLE, 0xffffffff); + joystick->set_context_enable1(joypad[1], SIG_JOYPAD_ENABLE, 0xffffffff); + joystick->set_context_mask(joypad[0], SIG_JOYPAD_SELECT_BUS, 0x10); // Mouse0 or joypad0 + joystick->set_context_mask(joypad[1], SIG_JOYPAD_SELECT_BUS, 0x20); // Mouse1 or joypad1 + joystick->set_context_query(joypad[0], SIG_JOYPAD_QUERY, 0x1); + joystick->set_context_query(joypad[1], SIG_JOYPAD_QUERY, 0x2); + + joypad[0]->set_context_port_num(0); + joypad[1]->set_context_port_num(1); + joypad[0]->set_context_data(joystick, SIG_JOYPORT_CH0 | SIG_JOYPORT_TYPE_2BUTTONS | SIG_JOYPORT_DATA, 0xffffffff); + joypad[1]->set_context_data(joystick, SIG_JOYPORT_CH1 | SIG_JOYPORT_TYPE_2BUTTONS | SIG_JOYPORT_DATA, 0xffffffff); + joypad[0]->set_context_com(joystick, SIG_JOYPORT_CH0 | SIG_JOYPORT_TYPE_2BUTTONS | SIG_JOYPORT_COM, 0xffffffff); + joypad[1]->set_context_com(joystick, SIG_JOYPORT_CH1 | SIG_JOYPORT_TYPE_2BUTTONS | SIG_JOYPORT_COM, 0xffffffff); // cpu bus cpu->set_context_mem(memory); cpu->set_context_io(io); cpu->set_context_intr(pic); cpu->set_context_dma(dma); - - + cpu->set_context_bios(NULL); + cpu->set_context_extreset(memory, SIG_FMTOWNS_NOTIFY_RESET, 0xffffffff); #ifdef USE_DEBUGGER cpu->set_context_debugger(new DEBUGGER(this, emu)); #endif + // Interrupts + // IRQ0 : TIMER + // IRQ1 : KEYBOARD + // IRQ2 : USART (ToDo) + // IRQ3 : EXTRA USART (ToDo) + // IRQ4 : EXTRA I/O (Maybe not implement) + // IRQ5 : EXTRA I/O (Maybe not implement) + // IRQ6 : FDC + // IRQ7 : Deisy chain (to IRQ8 - 15) + timer->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 0xffffffff); + keyboard->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 0xffffffff); + floppy->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR6, 0xffffffff); + // IRQ8 : SCSI (-> scsi.cpp) + // IRQ9 : CDC/CDROM + // IRQ10 : EXTRA I/O (Maybe not implement) + // IRQ11 : VSYNC + // IRQ12 : PRINTER (ToDo) + // IRQ13 : ADPCM AND OPN2 (Route to adpcm.cpp) + // IRQ14 : EXTRA I/O (Maybe not implement) + // IRQ15 : RESERVED. + cdrom->set_context_mpuint_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR1, 0xffffffff); + crtc->set_context_vsync(pic, SIG_I8259_CHIP1 | SIG_I8259_IR3, 0xffffffff); + adpcm->set_context_intr_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR5, 0xffffffff); + + // DMA0 : FDC/DRQ + // DMA1 : SCSI (-> scsi.cpp) + // DMA2 : PRINTER (ToDo) + // DMA3 : CDC/CDROM + // EXTRA DMA0 : EXTRA SLOT (Maybe not implement) + // EXTRA DMA1 : Reserved + // EXTRA DMA2 : Reserved + // EXTRA DMA3 : Reserved + fdc->set_context_drq(dma, SIG_UPD71071_CH0, 1); + fdc->set_context_drq(keyboard, SIG_KEYBOARD_BOOTSEQ_END, 1); + cdrom->set_context_drq_line(dma, SIG_UPD71071_CH3, 0xff); + cdrom->set_context_drq_line(keyboard, SIG_KEYBOARD_BOOTSEQ_END, 1); + + // NMI0 : KEYBOARD (RAS) + // NMI1 : Extra SLOT (Maybe not implement) + keyboard->set_context_nmi_line(memory, SIG_CPU_NMI, 0xffffffff); + + cdrom->set_context_dmac(dma); + // For Debugging, will remove 20200822 K.O + cdrom->set_context_cpu(cpu); + // i/o bus - io->set_iomap_alias_rw(0x00, pic, I8259_ADDR_CHIP0 | 0); - io->set_iomap_alias_rw(0x02, pic, I8259_ADDR_CHIP0 | 1); - io->set_iomap_alias_rw(0x10, pic, I8259_ADDR_CHIP1 | 0); - io->set_iomap_alias_rw(0x12, pic, I8259_ADDR_CHIP1 | 1); - io->set_iomap_single_rw(0x20, memory); // reset - io->set_iomap_single_r(0x21, memory); // cpu misc - io->set_iomap_single_w(0x22, memory); // power - //io->set_iomap_single_rw(0x24, memory); // dma - io->set_iomap_single_r(0x25, memory); // cpu_misc4 (after Towns2) - //io->set_iomap_single_r(0x26, timer); - //io->set_iomap_single_r(0x27, timer); - io->set_iomap_single_r(0x28, memory); // NMI MASK (after Towns2) - io->set_iomap_single_r(0x30, memory); // cpu id - io->set_iomap_single_r(0x31, memory); // cpu id - - io->set_iomap_single_rw(0x32, serial_rom); // serial rom - - io->set_iomap_alias_rw(0x40, pit0, 0); - io->set_iomap_alias_rw(0x42, pit0, 1); - io->set_iomap_alias_rw(0x44, pit0, 2); - io->set_iomap_alias_rw(0x46, pit0, 3); - io->set_iomap_alias_rw(0x50, pit1, 0); - io->set_iomap_alias_rw(0x52, pit1, 1); - io->set_iomap_alias_rw(0x54, pit1, 2); - io->set_iomap_alias_rw(0x56, pit1, 3); - - io->set_iomap_single_rw(0x60, timer); - io->set_iomap_single_rw(0x68, timer); // Interval timer register2 (after Towns 10F). - io->set_iomap_single_rw(0x6a, timer); // Interval timer register2 (after Towns 10F). - io->set_iomap_single_rw(0x6b, timer); // Interval timer register2 (after Towns 10F). - io->set_iomap_single_rw(0x6c, memory); // 1uS wait register (after Towns 10F). - - io->set_iomap_single_rw(0x70, timer); - io->set_iomap_single_w(0x80, timer); - - io->set_iomap_range_rw(0xa0, 0xaf, dma); - io->set_iomap_range_rw(0xb0, 0xbf, extra_dma); - - io->set_iomap_alias_rw(0x200, fdc, 0); - io->set_iomap_alias_rw(0x202, fdc, 1); - io->set_iomap_alias_rw(0x204, fdc, 2); - io->set_iomap_alias_rw(0x206, fdc, 3); - io->set_iomap_single_rw(0x208, floppy); - io->set_iomap_single_rw(0x20c, floppy); - io->set_iomap_single_rw(0x20e, floppy); // Towns drive SW - - io->set_iomap_single_rw(0x400, memory); // System Status - //io->set_iomap_single_rw(0x402, memory); - io->set_iomap_single_rw(0x404, memory); // System status - - io->set_iomap_range_rw(0x440, 0x443, crtc); // CRTC - io->set_iomap_range_rw(0x448, 0x44c, vram); // - io->set_iomap_single_rw(0x450, sprite); // - io->set_iomap_single_rw(0x452, sprite); // - - io->set_iomap_range_rw(0x458, 0x45f, vram); // CRTC - - io->set_iomap_single_rw(0x480, memory); // - io->set_iomap_single_rw(0x484, memory); // Dictionary - //io->set_iomap_alias_r(0x48a, memory_card, 0); // + io->set_iowait_range_rw(0x0000, 0xffff, 6); // ToDo: May variable wait. + + io->set_iomap_alias_rw (0x0000, pic, I8259_ADDR_CHIP0 | 0); + io->set_iomap_alias_rw (0x0002, pic, I8259_ADDR_CHIP0 | 1); + io->set_iomap_alias_rw (0x0010, pic, I8259_ADDR_CHIP1 | 0); + io->set_iomap_alias_rw (0x0012, pic, I8259_ADDR_CHIP1 | 1); + + io->set_iomap_range_rw (0x0020, 0x0025, memory); + io->set_iomap_range_rw (0x0026, 0x0027, timer); // Freerun counter + io->set_iomap_single_rw(0x0028, memory); + + io->set_iomap_range_r (0x0030, 0x0031, memory); // cpu id / machine id + io->set_iomap_single_rw(0x0032, memory); // serial rom (routed from memory) + io->set_iomap_single_r (0x0034, scsi); // ENABLE/ UNABLE to WORD DMA for SCSI + + io->set_iomap_alias_rw(0x0040, pit0, 0); + io->set_iomap_alias_rw(0x0042, pit0, 1); + io->set_iomap_alias_rw(0x0044, pit0, 2); + io->set_iomap_alias_rw(0x0046, pit0, 3); + io->set_iomap_alias_rw(0x0050, pit1, 0); + io->set_iomap_alias_rw(0x0052, pit1, 1); + io->set_iomap_alias_rw(0x0054, pit1, 2); + io->set_iomap_alias_rw(0x0056, pit1, 3); + + io->set_iomap_single_rw(0x0060, timer); // Beep and interrupts register + io->set_iomap_single_rw(0x0068, timer); // Interval timer register2 (after Towns 10F). + io->set_iomap_single_rw(0x006a, timer); // Interval timer register2 (after Towns 10F). + io->set_iomap_single_rw(0x006b, timer); // Interval timer register2 (after Towns 10F). + io->set_iomap_single_rw(0x006c, timer); // 1uS wait register (after Towns 10F). + + io->set_iomap_single_rw(0x0070, timer); // RTC DATA + io->set_iomap_single_w (0x0080, timer); // RTC COMMAND + + io->set_iomap_range_rw (0x00a0, 0x00af, dma); + io->set_iomap_range_rw (0x00b0, 0x00bf, extra_dma); + + io->set_iomap_alias_rw (0x0200, fdc, 0); // STATUS/COMMAND + io->set_iomap_alias_rw (0x0202, fdc, 1); // TRACK + io->set_iomap_alias_rw (0x0204, fdc, 2); // SECTOR + io->set_iomap_alias_rw (0x0206, fdc, 3); // DATA + io->set_iomap_single_rw(0x0208, floppy); // DRIVE STATUS / DRIVE CONTROL + io->set_iomap_single_rw(0x020c, floppy); // DRIVE SELECT + io->set_iomap_single_rw(0x020e, floppy); // Towns drive SW + + io->set_iomap_range_rw (0x0400, 0x0404, memory); // System Status + io->set_iomap_range_rw (0x0406, 0x403f, memory); // Reserved + + io->set_iomap_range_rw(0x0440, 0x0443, crtc); // CRTC + io->set_iomap_range_rw(0x0448, 0x044f, crtc); // VIDEO OUT (CRTC) + + io->set_iomap_range_rw(0x0450, 0x0452, sprite); // SPRITE + + io->set_iomap_single_rw(0x0458, vram); // VRAM ACCESS CONTROLLER (ADDRESS) + io->set_iomap_range_rw (0x045a, 0x045f, vram); // VRAM ACCESS CONTROLLER (DATA) + + io->set_iomap_single_rw(0x0480, memory); // MEMORY REGISTER + io->set_iomap_single_rw(0x0484, dictionary); // Dictionary + + io->set_iomap_alias_r(0x48a, iccard1, 0); // //io->set_iomap_alias_rw(0x490, memory_card); // After Towns2 //io->set_iomap_alias_rw(0x491, memory_card); // After Towns2 - io->set_iomap_range_rw(0x4c0, 0x4cf, cdc); // CDROM + io->set_iomap_range_rw(0x04c0, 0x04cf, cdrom); // CDROM // PAD, Sound - io->set_iomap_alias_r(0x4d0, pad, 0); // Pad1 - io->set_iomap_alias_r(0x4d2, pad, 1); // Pad 2 - io->set_iomap_single_rw(0x4d5, adpcm, 0); // mute - io->set_iomap_alias_w(0x4d6, pad, 3); // Pad out - + + io->set_iomap_single_r(0x04d0, joystick); // Pad1 + io->set_iomap_single_r(0x04d2, joystick); // Pad 2 + io->set_iomap_single_w(0x04d6, joystick); // Pad out + + io->set_iomap_single_rw(0x04d5, adpcm); // mute // OPN2(YM2612) - io->set_iomap_alias_rw(0x4d8, opn2, 0); // STATUS(R)/Addrreg 0(W) - io->set_iomap_alias_w(0x4da, opn2, 1); // Datareg 0(W) - io->set_iomap_alias_w(0x4dc, opn2, 2); // Addrreg 1(W) - io->set_iomap_alias_w(0x4de, opn2, 3); // Datareg 1(W) + io->set_iomap_alias_rw(0x04d8, opn2, 0); // STATUS(R)/Addrreg 0(W) + io->set_iomap_alias_w (0x04da, opn2, 1); // Datareg 0(W) + io->set_iomap_alias_w (0x04dc, opn2, 2); // Addrreg 1(W) + io->set_iomap_alias_w (0x04de, opn2, 3); // Datareg 1(W) // Electrical volume - io->set_iomap_alias_rw(0x4e0, e_volume[0], 0); - io->set_iomap_alias_rw(0x4e1, e_volume[0], 1); - io->set_iomap_alias_rw(0x4e2, e_volume[1], 0); - io->set_iomap_alias_rw(0x4e3, e_volume[1], 1); +// io->set_iomap_alias_rw(0x04e0, e_volume[0], 0); +// io->set_iomap_alias_rw(0x04e1, e_volume[0], 1); +// io->set_iomap_alias_rw(0x04e2, e_volume[1], 0); +// io->set_iomap_alias_rw(0x04e3, e_volume[1], 1); // ADPCM - io->set_iomap_range_w(0x4e7, 0x4ff, adpcm); // + io->set_iomap_range_rw(0x04e7, 0x04ef, adpcm); // A/D SAMPLING DATA REG + io->set_iomap_range_rw(0x04f0, 0x04f8, rf5c68); // A/D SAMPLING DATA REG + + io->set_iomap_single_rw(0x05c0, memory); // NMI MASK + io->set_iomap_single_r (0x05c2, memory); // NMI STATUS + io->set_iomap_single_r (0x05c8, sprite); // TVRAM EMULATION + io->set_iomap_single_w (0x05ca, crtc); // VSYNC INTERRUPT + if(machine_id < 0x0200) { + io->set_iomap_single_rw(0x05e0, memory); // MEMORY WAIT REGISTER ffrom AB.COM + } else { + io->set_iomap_single_rw(0x05e2, memory); // MEMORY WAIT REGISTER ffrom AB.COM + } + io->set_iomap_single_rw(0x05e8, memory); // RAM capacity register.(later Towns1H/2H/1F/2F). + io->set_iomap_single_rw(0x05ec, memory); // RAM Wait register , ofcially after Towns2, but exists after Towns1H. + io->set_iomap_single_r (0x05ed, memory); // RAM Wait register , ofcially after Towns2, but exists after Towns1H. + + io->set_iomap_single_rw(0x0600, keyboard); + io->set_iomap_single_rw(0x0602, keyboard); + io->set_iomap_single_rw(0x0604, keyboard); - io->set_iomap_single_rw(0x5c0, memory); // NMI MASK - io->set_iomap_single_r(0x5c2, memory); // NMI STATUS - io->set_iomap_single_r(0x5c8, vram); // TVRAM EMULATION - io->set_iomap_single_w(0x5ca, vram); // VSYNC INTERRUPT + //io->set_iomap_single_rw(0x0800, printer); + //io->set_iomap_single_rw(0x0802, printer); + //io->set_iomap_single_rw(0x0804, printer); - io->set_iomap_single_r(0x5e8, memory); // RAM capacity register.(later Towns1H/2H/1F/2F). - io->set_iomap_single_r(0x5ec, memory); // RAM Wait register , ofcially after Towns2, but exists after Towns1H. + io->set_iomap_alias_rw (0x0a00, sio, 0); + io->set_iomap_alias_rw (0x0a02, sio, 1); +// io->set_iomap_single_r (0x0a04, serial); +// io->set_iomap_single_r (0x0a06, serial); +// io->set_iomap_single_w (0x0a08, serial); +// io->set_iomap_single_rw(0x0a0a, modem); - io->set_iomap_single_rw(0x600, keyboard); - io->set_iomap_single_rw(0x602, keyboard); - io->set_iomap_single_rw(0x604, keyboard); - //io->set_iomap_single_r(0x606, keyboard); // BufFul (After Towns2) + io->set_iomap_single_rw(0x0c30, scsi); + io->set_iomap_single_rw(0x0c32, scsi); - //io->set_iomap_single_rw(0x800, printer); - //io->set_iomap_single_rw(0x802, printer); - //io->set_iomap_single_rw(0x804, printer); + io->set_iomap_range_rw (0x3000, 0x3fff, dictionary); // CMOS - io->set_iomap_alias_rw(0xa00, sio, 0); - io->set_iomap_alias_rw(0xa02, sio, 1); -// io->set_iomap_single_r(0xa04, serial); -// io->set_iomap_single_r(0xa06, serial); -// io->set_iomap_single_w(0xa08, serial); -// io->set_iomap_single_rw(0xa0a, modem); + io->set_iomap_range_rw (0xfd90, 0xfda2, crtc); // Palette and CRTC + io->set_iomap_single_rw(0xfda4, memory); // memory - io->set_iomap_single_rw(0xc30, scsi); - io->set_iomap_single_rw(0xc32, scsi); - + io->set_iomap_range_rw (0xff80, 0xff83, planevram); // MMIO + io->set_iomap_single_r (0xff84, planevram); // MMIO + io->set_iomap_single_rw(0xff86, planevram); // MMIO + io->set_iomap_single_rw(0xff88, memory); // MMIO + io->set_iomap_range_rw (0xff94, 0xff99, memory); // MMIO + io->set_iomap_range_r (0xff9c, 0xff9d, memory); // MMIO + io->set_iomap_single_rw(0xff9e, memory); // MMIO + io->set_iomap_single_rw(0xffa0, planevram); // MMIO - io->set_iomap_range_rw(0x3000, 0x3fff, memory); // CMOS - io->set_iomap_range_rw(0xfd90, 0xfda0, vram); // Palette and CRTC +// io->set_iomap_range_w (0xff94, 0xff95, fontrom); +// io->set_iomap_range_r (0xff96, 0xff97, fontrom); // Vram allocation may be before initialize(). - bool alloc_failed = false; - for(int bank = 0; bank < 2; bank++) { - if(alloc_failed) break; - for(int layer = 0; layer < 2; layer++) { - d_renderbuffer[bank][layer] = NULL; - renderbuffer_size[bank][layer] = 0; - - uint32_t initial_width = 640; - uint32_t initial_height = 480; - uint32_t initial_stride = 640; - uint32_t __size = initial_stride * initial_height * sizeof(scrntype_t); - scrntype_t *p = (scrntype_t*)malloc(__size); - if(p == NULL) { - alloc_faled = true; - break; - } else { - memset(p, 0x00, __size); - renderbuffer_size[bank][layer] = __size; - d_renderbuffer[bank][layer] = p; - d_vram->set_context_renderbuffer(p, layer, bank, width, height, stride); - } - } - } - if(alloc_failed) { - for(int bank = 0; bank < 2; bank++) { - for(int layer = 0; layer < 2; layer++) { - renderbuffer_size[bank][layer] = 0; - if(d_renderbuffer[bank][layer] != NULL) { - free((void *)(d_renderbuffer[bank][layer])); - } - d_renderbuffer[bank][layer] = NULL; - d_vram->set_context_renderbuffer(NULL, layer, bank, 0, 0, 0); - } - } - } // initialize all devices #if defined(__GIT_REPO_VERSION) strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1); #endif + // ToDo : Use config framework + int exram_size = config.current_ram_size; + if(exram_size < 1) { + if(machine_id < 0x0200) { // Model1 - 2H + exram_size = 6; + } else if(machine_id == 0x0500) { // CX + exram_size = 15; + } else if(machine_id < 0x0700) { // 10F,20H + exram_size = 8; + } else if(machine_id == 0x0800) { // HG + exram_size = 15; + } else { + exram_size = 31; + } + } + if(exram_size < MIN_RAM_SIZE) { + exram_size = MIN_RAM_SIZE; + } + + memory->set_extra_ram_size(exram_size); + +#if defined(WITH_I386SX) + cpu->device_model = INTEL_80386; +#elif defined(WITH_I486SX) + cpu->device_model = INTEL_I486SX; +#elif defined(WITH_I486DX) + cpu->device_model = INTEL_I486DX; +#elif defined(WITH_PENTIUM) + cpu->device_model = INTEL_PENTIUM; +#else + // I386 + cpu->device_model = INTEL_80386; +#endif + for(DEVICE* device = first_device; device; device = device->next_device) { device->initialize(); } +// cpu->set_address_mask(0xffffffff); } VM::~VM() @@ -519,6 +661,7 @@ VM::~VM() // delete all devices for(DEVICE* device = first_device; device;) { DEVICE *next_device = device->next_device; +// printf("DEVID=%d\n", device->this_device_id); device->release(); delete device; device = next_device; @@ -541,41 +684,29 @@ void VM::set_machine_type(uint16_t machine_id, uint16_t cpu_id) memory->set_cpu_id(cpu_id); memory->set_machine_id(machine_id); } - if(vram != NULL) { - vram->set_cpu_id(cpu_id); - vram->set_machine_id(machine_id); - } - if(sprite != NULL) { - sprite->set_cpu_id(cpu_id); - sprite->set_machine_id(machine_id); - } - if(sys_rom != NULL) { - sysrom->set_cpu_id(cpu_id); - sysrom->set_machine_id(machine_id); + if(crtc != NULL) { + crtc->set_cpu_id(cpu_id); + crtc->set_machine_id(machine_id); } - if(msdos_rom != NULL) { - msdosrom->set_cpu_id(cpu_id); - msdosrom->set_machine_id(machine_id); + if(timer != NULL) { + timer->set_cpu_id(cpu_id); + timer->set_machine_id(machine_id); } - if(dictinoary != NULL) { - dictionary->set_cpu_id(cpu_id); - dictionary->set_machine_id(machine_id); + if(cdrom != NULL) { + cdrom->set_cpu_id(cpu_id); + cdrom->set_machine_id(machine_id); } - if(fontrom != NULL) { - fontrom->set_cpu_id(cpu_id); - fontrom->set_machine_id(machine_id); + if(scsi != NULL) { + scsi->set_cpu_id(cpu_id); + scsi->set_machine_id(machine_id); } if(serialrom != NULL) { serialrom->set_cpu_id(cpu_id); serialrom->set_machine_id(machine_id); } - if(crtc != NULL) { - crtc->set_cpu_id(cpu_id); - crtc->set_machine_id(machine_id); - } - if(cdc != NULL) { - cdc->set_cpu_id(cpu_id); - cdc->set_machine_id(machine_id); + if(floppy != NULL) { + floppy->set_cpu_id(cpu_id); + floppy->set_machine_id(machine_id); } #if defined(HAS_20PIX_FONTS) if(fontrom_20pix != NULL) { @@ -594,13 +725,24 @@ void VM::set_machine_type(uint16_t machine_id, uint16_t cpu_id) void VM::reset() { // reset all devices + boot_seq = true; for(DEVICE* device = first_device; device; device = device->next_device) { device->reset(); } - // temporary fix... +// cpu->set_address_mask(0xffffffff); +} + +void VM::special_reset(int num) +{ + // reset all devices + boot_seq = true; + for(DEVICE* device = first_device; device; device = device->next_device) { device->reset(); } + keyboard->special_reset(num); + +// cpu->set_address_mask(0xffffffff); } void VM::run() @@ -628,12 +770,19 @@ DEVICE *VM::get_cpu(int index) void VM::draw_screen() { - memory->draw_screen(); + crtc->draw_screen(); } uint32_t VM::is_floppy_disk_accessed() { - return fdc->read_signal(0); + uint32_t val = fdc->read_signal(0); + if(boot_seq) { + if(val != 0) { + keyboard->write_signal(SIG_KEYBOARD_BOOTSEQ_END, 0xffffffff, 0xffffffff); + boot_seq = false; + } + } + return val; } // ---------------------------------------------------------------------------- @@ -649,19 +798,30 @@ void VM::initialize_sound(int rate, int samples) // init sound gen beep->initialize_sound(rate, 8000); + // init OPN2 + // MASTER CLOCK MAYBE 600KHz * 12 = 7200KHz . + // From FM-Towns Technical Databook (Rev.2), Page 201 + opn2->initialize_sound(rate, (int)(600.0e3 * 12.0) , samples, 0.0, 0.0); + //opn2->initialize_sound(rate, (int)(8000.0e3) , samples, 0.0, 0.0); + //opn2->initialize_sound(rate, (int)(600.0e3 * 6.0) , samples, 0.0, 0.0); + + // init PCM + rf5c68->initialize_sound(rate, samples); + // add_sound_in_source() must add after per initialize_sound(). adc_in_ch = event->add_sound_in_source(rate, samples, 2); - mixer->set_context_out_line(adc_in_ch); adc->set_sample_rate(19200); adc->set_sound_bank(adc_in_ch); +#if 0 + mixer->set_context_out_line(adc_in_ch); mixer->set_context_sample_out(adc_in_ch, rate, samples); // Must be 2ch. - // ToDo: Check recording sample rate & channels. mic_in_ch = event->add_sound_in_source(rate, samples, 2); mixer->set_context_mic_in(mic_in_ch, rate, samples); line_in_ch = event->add_sound_in_source(rate, samples, 2); mixer->set_context_line_in(line_in_ch, rate, samples); +#endif emu->unlock_vm(); } @@ -686,7 +846,7 @@ void VM::clear_sound_in() int VM::get_sound_in_data(int ch, int32_t* dst, int expect_samples, int expect_rate, int expect_channels) { if(dst == NULL) return 0; - if(samples <= 0) return 0; + if(expect_samples <= 0) return 0; int n_ch = -1; switch(ch) { case 0x00: @@ -700,7 +860,7 @@ int VM::get_sound_in_data(int ch, int32_t* dst, int expect_samples, int expect_r break; } if(n_ch < 0) return 0; - samples = event->get_sound_in_data(n_ch, dst, expect_samples, expect_rate, expect_channels); + int samples = event->get_sound_in_data(n_ch, dst, expect_samples, expect_rate, expect_channels); return samples; } @@ -732,21 +892,99 @@ int VM::sound_in(int ch, int32_t* src, int samples) return ss; } +#if defined(USE_HARD_DISK) +void VM::open_hard_disk(int drv, const _TCHAR* file_path) +{ + if((drv < USE_HARD_DISK) && (drv < 8) && (drv >= 0)) { + if(scsi_hdd[drv] != NULL) { + scsi_hdd[drv]->open(0, file_path, 512); + } + } +} + +void VM::close_hard_disk(int drv) +{ + if((drv < USE_HARD_DISK) && (drv < 8) && (drv >= 0)) { + if(scsi_hdd[drv] != NULL) { + scsi_hdd[drv]->close(0); + } + } +} + +bool VM::is_hard_disk_inserted(int drv) +{ + if((drv < USE_HARD_DISK) && (drv < 8) && (drv >= 0)) { + if(scsi_hdd[drv] != NULL) { + return scsi_hdd[drv]->mounted(0); + } + } + return false; +} + +uint32_t VM::is_hard_disk_accessed() +{ + uint32_t status = 0; + + for(int drv = 0; drv < USE_HARD_DISK; drv++) { + if(scsi_hdd[drv] != NULL) { + if(scsi_hdd[drv]->accessed(0)) { + status |= 1 << drv; + } + } + } + if(boot_seq) { + if(status != 0) { + keyboard->write_signal(SIG_KEYBOARD_BOOTSEQ_END, 0xffffffff, 0xffffffff); + boot_seq = false; + } + } + return status; +} +#endif // USE_HARD_DISK + +void VM::open_compact_disc(int drv, const _TCHAR* file_path) +{ + cdrom->open(file_path); +} + +void VM::close_compact_disc(int drv) +{ + cdrom->close(); +} + +bool VM::is_compact_disc_inserted(int drv) +{ + return cdrom->mounted(); +} + +uint32_t VM::is_compact_disc_accessed() +{ + uint32_t status = cdrom->accessed(); + if(boot_seq) { + if(status != 0) { + keyboard->write_signal(SIG_KEYBOARD_BOOTSEQ_END, 0xffffffff, 0xffffffff); + boot_seq = false; + } + } + return status; +} + #ifdef USE_SOUND_VOLUME void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r) { #ifndef HAS_LINEIN_SOUND - if(ch >= 4) ch++; +// if(ch >= 7) ch++; #endif #ifndef HAS_MIC_SOUND - if(ch >= 5) ch++; +// if(ch >= 8) ch++; #endif #ifndef HAS_MODEM_SOUND - if(ch >= 6) ch++; +// if(ch >= 9) ch++; #endif #ifndef HAS_2ND_ADPCM - if(ch >= 7) ch++; +// if(ch >= 10) ch++; #endif +#if 0 if(ch == 0) { // BEEP mixer->set_volume(beep_mix_ch, decibel_l, decibel_r); } @@ -781,7 +1019,26 @@ void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r) else if(ch == 9) { // HDD(ToDo) fdc->set_volume(0, decibel_l, decibel_r); } - +#else + if(ch == 0) { // BEEP + beep->set_volume(0, decibel_l, decibel_r); + } + else if(ch == 1) { // CD-ROM + cdrom->set_volume(0, decibel_l, decibel_r); + } + else if(ch == 2) { // OPN2 + opn2->set_volume(0, decibel_l, decibel_r); + } + else if(ch == 3) { // ADPCM + rf5c68->set_volume(0, decibel_l, decibel_r); + } + else if(ch == 4) { // SEEK, HEAD UP / DOWN + seek_sound->set_volume(0, decibel_l, decibel_r); + head_up_sound->set_volume(0, decibel_l, decibel_r); + head_down_sound->set_volume(0, decibel_l, decibel_r); + } + +#endif } #endif @@ -802,11 +1059,62 @@ void VM::key_up(int code) // ---------------------------------------------------------------------------- // user interface // ---------------------------------------------------------------------------- +void VM::open_cart(int drv, const _TCHAR* file_path) +{ + switch(drv) { + case 0: + if(iccard1 != NULL) { + iccard1->open_cart(file_path); + } + break; + case 1: + if(iccard2 != NULL) { + iccard2->open_cart(file_path); + } + break; + } +} + +void VM::close_cart(int drv) +{ + switch(drv) { + case 0: + if(iccard1 != NULL) { + iccard1->close_cart(); + } + break; + case 1: + if(iccard2 != NULL) { + iccard2->close_cart(); + } + break; + } +} + +bool VM::is_cart_inserted(int drv) +{ + switch(drv) { + case 0: + if(iccard1 != NULL) { + return iccard1->is_cart_inserted(); + } + break; + case 1: + if(iccard2 != NULL) { + return iccard2->is_cart_inserted(); + } + break; + } + return false; +} void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank) { + fdc->open_disk(drv, file_path, bank); - floppy->change_disk(drv); + if(fdc->is_disk_inserted(drv)) { + floppy->change_disk(drv); + } } void VM::close_floppy_disk(int drv) @@ -841,6 +1149,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -853,7 +1173,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { return false; } @@ -868,13 +1188,16 @@ bool VM::process_state(FILEIO* state_fio, bool loading) } } // Machine specified. + state_fio->StateValue(beep_mix_ch); + state_fio->StateValue(cdc_mix_ch); + state_fio->StateValue(opn2_mix_ch); + state_fio->StateValue(pcm_mix_ch); state_fio->StateValue(line_mix_ch); state_fio->StateValue(modem_mix_ch); state_fio->StateValue(mic_mix_ch); - state_fio->StateValue(beep_mix_ch); - state_fio->StateValue(pcm_mix_ch); - state_fio->StateValue(opn2_mix_ch); - state_fio->StateValue(cdc_mix_ch); + + state_fio->StateValue(boot_seq); + return true; } diff --git a/source/src/vm/fmtowns/fmtowns.h b/source/src/vm/fmtowns/fmtowns.h index e385bdf07..12446e19c 100644 --- a/source/src/vm/fmtowns/fmtowns.h +++ b/source/src/vm/fmtowns/fmtowns.h @@ -9,126 +9,286 @@ #undef WITH_386SX -#undef WITH_486 +#undef WITH_I486DX +#undef WITH_I486SX #undef WITH_PENTIUM #undef TYPE_TOWNS_X0 #undef TYPE_TOWNS2_UX #undef TYPE_TOWNS2_CX + +#define HAS_MB89311 + +#define RAM_SIZE_ORDER (1024*1024) + #if defined(_FMTOWNS_1) #define DEVICE_NAME "FUJITSU FM-Towns Model 1" -#define CONFIG_NAME "fmtowns_1" +#define CONFIG_NAME "fmtowns1" #define MAX_DRIVE 1 -#define _HAS_HDD 1 +#define _HAS_HDD 4 +#undef HAS_MB89311 +#define USE_VARIABLE_MEMORY 6 +#define MIN_RAM_SIZE 1 #elif defined(_FMTOWNS_2) #define DEVICE_NAME "FUJITSU FM-Towns Model 2" -#define CONFIG_NAME "fmtowns_2" +#define CONFIG_NAME "fmtowns2" #define MAX_DRIVE 2 -#define _HAS_HDD 1 +#define _HAS_HDD 4 +#undef HAS_MB89311 +#define USE_VARIABLE_MEMORY 6 +#define MIN_RAM_SIZE 1 + #elif defined(_FMTOWNS_2F) #define DEVICE_NAME "FUJITSU FM-Towns 2F" -#define CONFIG_NAME "fmtowns_2f" +#define CONFIG_NAME "fmtowns2F" #define MAX_DRIVE 2 #undef _HAS_HDD +#define _FMTOWNS1_2ND_GEN +#define USE_VARIABLE_MEMORY 8 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS_2H) #define DEVICE_NAME "FUJITSU FM-Towns 2H" -#define CONFIG_NAME "fmtowns_2h" +#define CONFIG_NAME "fmtowns2H" #define MAX_DRIVE 2 -#define _HAS_HDD 2 +#define _HAS_HDD 4 +#define _FMTOWNS1_2ND_GEN +#define USE_VARIABLE_MEMORY 8 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS_20F) #define DEVICE_NAME "FUJITSU FM-Towns 20F" -#define CONFIG_NAME "fmtowns_20f" +#define CONFIG_NAME "fmtowns20F" #define MAX_DRIVE 2 #undef _HAS_HDD #define TYPE_TOWNS_X0 1 +#define _FMTOWNS1_3RD_GEN +#define USE_VARIABLE_MEMORY 8 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS_40H) #define DEVICE_NAME "FUJITSU FM-Towns 40H" -#define CONFIG_NAME "fmtowns_20h" +#define CONFIG_NAME "fmtowns20H" #define MAX_DRIVE 2 -#define _HAS_HDD 2 +#define _HAS_HDD 4 #define TYPE_TOWNS_X0 1 +#define _FMTOWNS1_3RD_GEN +#define USE_VARIABLE_MEMORY 8 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS2_UX20) #define DEVICE_NAME "FUJITSU FM-Towns II UX20" -#define CONFIG_NAME "fmtowns2_ux20" +#define CONFIG_NAME "fmtowns2UX20" #define MAX_DRIVE 2 #undef _HAS_HDD #define WITH_386SX 1 #define TYPE_TOWNS2_UX 1 +#define _FMTOWNS_UX_VARIANTS +#define USE_VARIABLE_MEMORY 9 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS2_UX40) #define DEVICE_NAME "FUJITSU FM-Towns II UX40" -#define CONFIG_NAME "fmtowns2_ux20" +#define CONFIG_NAME "fmtowns2UX40" #define MAX_DRIVE 2 -#define _HAS_HDD 1 +#define _HAS_HDD 4 #define WITH_386SX 1 #define TYPE_TOWNS2_UX 1 +#define _FMTOWNS_UX_VARIANTS +#define USE_VARIABLE_MEMORY 9 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS2_CX20) #define DEVICE_NAME "FUJITSU FM-Towns II CX20" -#define CONFIG_NAME "fmtowns2_cx20" +#define CONFIG_NAME "fmtowns2CX20" #define MAX_DRIVE 2 #undef _HAS_HDD #define TYPE_TOWNS2_CX 1 +#define _FMTOWNS2_CX_VARIANTS +#define USE_VARIABLE_MEMORY 15 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS2_CX40) #define DEVICE_NAME "FUJITSU FM-Towns II CX40" -#define CONFIG_NAME "fmtowns2_cx40" +#define CONFIG_NAME "fmtowns2CX40" #define MAX_DRIVE 2 #define _HAS_HDD 4 #define TYPE_TOWNS2_CX 1 +#define _FMTOWNS2_CX_VARIANTS +#define USE_VARIABLE_MEMORY 15 +#define MIN_RAM_SIZE 2 #elif defined(_FMTOWNS2_CX100) #define DEVICE_NAME "FUJITSU FM-Towns II CX40" -#define CONFIG_NAME "fmtowns2_cx100" +#define CONFIG_NAME "fmtowns2CX100" #define MAX_DRIVE 2 #define _HAS_HDD 4 #define TYPE_TOWNS2_CX 1 +#define USE_VARIABLE_MEMORY 15 +#define MIN_RAM_SIZE 2 +#define _FMTOWNS2_CX_VARIANTS + +#elif defined(_FMTOWNS2_UG10) +#define DEVICE_NAME "FUJITSU FM-Towns II UG10" +#define CONFIG_NAME "fmtowns2UG1" +#define MAX_DRIVE 2 +#undef _HAS_HDD +#define WITH_386SX 1 +#define USE_VARIABLE_MEMORY 9 +#define MIN_RAM_SIZE 2 + +#define _FMTOWNS_UG_VARIANTS + +#elif defined(_FMTOWNS2_UG20) +#define DEVICE_NAME "FUJITSU FM-Towns II UG20" +#define CONFIG_NAME "fmtowns2UG20" +#define MAX_DRIVE 2 +#undef _HAS_HDD +#define WITH_386SX 1 +#define USE_VARIABLE_MEMORY 9 +#define MIN_RAM_SIZE 2 + +#define _FMTOWNS_UG_VARIANTS + +#elif defined(_FMTOWNS2_UG40) +#define DEVICE_NAME "FUJITSU FM-Towns II UG40" +#define CONFIG_NAME "fmtowns2UG40" +#define MAX_DRIVE 2 +#define _HAS_HDD 4 +#define WITH_386SX 1 +#define USE_VARIABLE_MEMORY 9 +#define MIN_RAM_SIZE 2 + +#define _FMTOWNS_UG_VARIANTS + +#elif defined(_FMTOWNS2_UG80) +#define DEVICE_NAME "FUJITSU FM-Towns II UG80" +#define CONFIG_NAME "fmtowns2UG80" +#define MAX_DRIVE 2 +#define _HAS_HDD 1 +#define WITH_386SX 1 +#define USE_VARIABLE_MEMORY 9 +#define MIN_RAM_SIZE 2 + +#define _FMTOWNS_UG_VARIANTS + +#elif defined(_FMTOWNS2_HG20) +#define DEVICE_NAME "FUJITSU FM-Towns II HG20" +#define CONFIG_NAME "fmtowns2HG20" +#define MAX_DRIVE 2 +#undef _HAS_HDD +#define USE_VARIABLE_MEMORY 15 +#define MIN_RAM_SIZE 2 + +#define _FMTOWNS_HG_VARIANTS +#elif defined(_FMTOWNS2_HG40) +#define DEVICE_NAME "FUJITSU FM-Towns II HG40" +#define CONFIG_NAME "fmtowns2HG40" +#define MAX_DRIVE 2 +#define _HAS_HDD 4 + +#define USE_VARIABLE_MEMORY 15 +#define MIN_RAM_SIZE 2 + +#define _FMTOWNS_HG_VARIANTS + +#elif defined(_FMTOWNS2_HR20) +#define DEVICE_NAME "FUJITSU FM-Towns II HR20" +#define CONFIG_NAME "fmtowns2HR20" +#define MAX_DRIVE 2 +#define _HAS_HDD 4 +#define _FMTOWNS_HR_VARIANTS + +#define USE_VARIABLE_MEMORY 31 +#define MIN_RAM_SIZE 2 + +#define WITH_I486SX +#elif defined(_FMTOWNS2_HR100) +#define DEVICE_NAME "FUJITSU FM-Towns II HR100" +#define CONFIG_NAME "fmtowns2HR100" +#define MAX_DRIVE 2 +#define _HAS_HDD 4 + +#define USE_VARIABLE_MEMORY 31 +#define MIN_RAM_SIZE 2 + +#define _FMTOWNS_HR_VARIANTS +#define WITH_I486SX + +#elif defined(_FMTOWNS2_HR200) +#define DEVICE_NAME "FUJITSU FM-Towns II HR200" +#define CONFIG_NAME "fmtowns2HR200" +#define MAX_DRIVE 2 +#define _HAS_HDD 4 +#define _FMTOWNS_HR_VARIANTS +#define WITH_I486SX + +#define USE_VARIABLE_MEMORY 31 +#define MIN_RAM_SIZE 2 + +#endif + +#if defined(WITH_386SX) +#define MEMORY_ADDR_MAX 0x001000000 /* 16MB */ +#else +#define MEMORY_ADDR_MAX 0x100000000 /* 4GiB */ #endif +#define MEMORY_BANK_SIZE 1024 // device informations for virtual machine #define FRAMES_PER_SEC 55.4 // OK? #define LINES_PER_FRAME 784 // OK? -#define CPU_CLOCKS 16000000 +#define CPU_CLOCKS 16000000 // This maybe dummy value, see VM::VM(). -#if defined(_FMR60) -#define SCREEN_WIDTH 1024 -#define SCREEN_HEIGHT 768 -#define WINDOW_HEIGHT_ASPECT 840 -#else -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 400 -#define WINDOW_HEIGHT_ASPECT 480 -#endif +#undef FIXED_FRAMEBUFFER_SIZE +#define SCREEN_WIDTH 1024 +#define SCREEN_HEIGHT 768 +#define WINDOW_WIDTH_ASPECT 1024 +#define WINDOW_HEIGHT_ASPECT 768 #if defined(_HAS_HDD) #define MAX_SCSI 8 +#define USE_HARD_DISK _HAS_HDD #endif +#define USE_COMPACT_DISC 1 #define MAX_MEMCARD 2 #define I8259_MAX_CHIPS 2 +//#define I8259_PC98_HACK -#define SINGLE_MODE_DMA +//#define SINGLE_MODE_DMA #define MB8877_NO_BUSY_AFTER_SEEK #define IO_ADDR_MAX 0x10000 #define SCSI_HOST_AUTO_ACK +//#define SCSI_HOST_WIDE +//#define _SCSI_DEBUG_LOG +//#define SCSI_DEV_IMMEDIATE_SELECT +//#define _CDROM_DEBUG_LOG +//#define _IO_DEBUG_LOG // device informations for win32 #define USE_CPU_TYPE 2 #define USE_FLOPPY_DISK 4 // ?? +#define USE_CART 2 +#define USE_SPECIAL_RESET 12 /* 'CD' 'F0' - 'F3' 'H0' - 'H4' 'ICM' 'DEBUG' */ +#define USE_FLOPPY_TYPE_BIT 0x0003 /* 5.0, 5.0, 3.5, 3.5 */ + #define NOTIFY_KEY_DOWN -#define USE_SHIFT_NUMPAD_KEY #define USE_ALT_F10_KEY #define USE_AUTO_KEY 5 #define USE_AUTO_KEY_RELEASE 6 #define USE_CRT_FILTER #define USE_SOUND_FILES 1 #define USE_SOUND_FILES_FDD +#define USE_JOYSTICK +#define USE_JOY_BUTTON_CAPTIONS +#define USE_JOYSTICK_TYPE 3 +#define JOYSTICK_TYPE_DEFAULT 0 +#define USE_MOUSE +#define USE_MOUSE_TYPE 3 +#define USE_CUSTOM_SCREEN_ZOOM_FACTOR 1.25 #if defined(USE_SOUND_FILES) #define USE_SOUND_VOLUME 5 @@ -139,6 +299,9 @@ #define USE_DEBUGGER #define USE_STATE #define USE_CPU_I386 +#define HAS_I386 +#define BASE_FLOPPY_DISK_NUM 0 +//#define USE_QUEUED_SCSI_TRANSFER #include "../../common.h" #include "../../fileio.h" @@ -146,12 +309,24 @@ #ifdef USE_SOUND_VOLUME static const _TCHAR *sound_device_caption[] = { - _T("Beep"), _T("FM SSG"), _T("FM OPNB"), _T("PCM"), _T("CD-DA"), + _T("Beep"), _T("CD-DA"), _T("FM OPN2"), _T("ADPCM"), #if defined(USE_SOUND_FILES) _T("FDD SEEK"), #endif }; #endif +#ifdef USE_JOY_BUTTON_CAPTIONS +static const _TCHAR *joy_button_captions[] = { + _T("Up"), + _T("Down"), + _T("Left"), + _T("Right"), + _T("Button #1"), + _T("Button #2"), + _T("RUN"), + _T("SELECT"), +}; +#endif class EMU; class DEVICE; @@ -161,18 +336,18 @@ class I8251; class I8253; class I8259; class I386; +class NOISE; class IO; class RF5C68; // DAC class YM2612; // OPNB -class MB87078; // VOLUME +//class MB87078; // VOLUME class AD7820KR; // A/D Converter. class PCM1BIT; class MB8877; // FDC class MSM58321; // RTC class RF5C68; // ADPCM -class UPD71071; // DMAC class SCSI_HOST; class SCSI_DEV; @@ -181,8 +356,9 @@ class SCSI_CDROM; namespace FMTOWNS { class ADPCM; - class CDC; +// class CDC; class FLOPPY; + class JOYSTICK; class KEYBOARD; class SERIAL_ROM; class SCSI; @@ -196,11 +372,15 @@ namespace FMTOWNS { class FONT_ROM_20PIX; #endif class TOWNS_CRTC; - class TOWNS_VRAM; - class TOWNS_MEMORY; - class TOWNS_CDROM; - class SPRITE; + class TOWNS_DMAC; // DMAC + class TOWNS_ICCARD; + class TOWNS_MEMORY; + class TOWNS_SCSI_HOST; + class TOWNS_SPRITE; + class TOWNS_VRAM; + class PLANEVRAM; + class JOYPAD; class JOYSTICK; // Mouse and Joystick. } @@ -213,52 +393,79 @@ class VM : public VM_TEMPLATE I8253* pit0; I8253* pit1; - I8259* pic0; - I8259* pic1; + I8259* pic; I386* cpu; // i386DX/SX/486DX/486SX?/Pentium with FPU? IO* io; MB8877* fdc; MSM58321* rtc; - UPD71071* dma; - UPD71071* extra_dma; - RF5C68* dac; - MB87078* e_volumes; + FMTOWNS::TOWNS_DMAC* dma; + FMTOWNS::TOWNS_DMAC* extra_dma; + NOISE* seek_sound; + NOISE* head_up_sound; + NOISE* head_down_sound; + + RF5C68* rf5c68; +// MB87078* e_volumes; AD7820KR* adc; - RF5C68* adpcm; PCM1BIT* beep; + YM2612* opn2; + FMTOWNS::ADPCM* adpcm; FMTOWNS::TOWNS_CRTC* crtc; FMTOWNS::FLOPPY* floppy; + FMTOWNS::JOYSTICK* joystick; + FMTOWNS::JOYPAD* joypad[2]; FMTOWNS::KEYBOARD* keyboard; FMTOWNS::TIMER* timer; - FMTOWNS::TOWNS_VRAM* sprite; + FMTOWNS::TOWNS_VRAM* vram; + FMTOWNS::PLANEVRAM* planevram; + FMTOWNS::TOWNS_SPRITE* sprite; FMTOWNS::TOWNS_MEMORY* memory; FMTOWNS::DICTIONARY* dictionary; FMTOWNS::SYSROM* sysrom; FMTOWNS::MSDOSROM* msdosrom; FMTOWNS::FONT_ROMS* fontrom; + FMTOWNS::TOWNS_ICCARD* iccard1; + FMTOWNS::TOWNS_ICCARD* iccard2; #if defined(HAS_20PIX_FONTS) FMTOWNS::FONT_ROM_20PIX* fontrom_20pix; #endif FMTOWNS::SERIAL_ROM* serialrom; - FMTOWNS::CDC* cdc; - SCSI_HOST* cdc_scsi; +// FMTOWNS::CDC* cdc; +// FMTOWNS::TOWNS_SCSI_HOST* cdc_scsi; FMTOWNS::TOWNS_CDROM* cdrom; FMTOWNS::SCSI* scsi; - SCSI_HOST* scsi_host; - SCSI_HDD* hdd[4]; // + //FMTOWNS::TOWNS_SCSI_HOST* scsi_host; + SCSI_HOST* scsi_host; + SCSI_HDD* scsi_hdd[8]; // + bool boot_seq; + + int adc_in_ch; + int line_in_ch; + int modem_in_ch; + int mic_in_ch; + + int beep_mix_ch; + int cdc_mix_ch; + int opn2_mix_ch; + int pcm_mix_ch; + int line_mix_ch; + int modem_mix_ch; + int mic_mix_ch; +/* scrntype_t *d_renderbuffer[2][2]; // [bank][layer] uint32_t renderbuffer_size[2][2]; +*/ public: // ---------------------------------------- // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -267,6 +474,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); + void special_reset(int num); void run(); #ifdef USE_DEBUGGER @@ -290,16 +498,40 @@ class VM : public VM_TEMPLATE void key_up(int code); // user interface + // CARTs are IC CARD.Will implement something :-) + void open_cart(int drv, const _TCHAR* file_path); + void close_cart(int drv); + bool is_cart_inserted(int drv); + void open_floppy_disk(int drv, const _TCHAR* file_path, int bank); void close_floppy_disk(int drv); + uint32_t is_floppy_disk_accessed(); bool is_floppy_disk_inserted(int drv); void is_floppy_disk_protected(int drv, bool value); bool is_floppy_disk_protected(int drv); bool is_frame_skippable(); + + void open_compact_disc(int drv, const _TCHAR* file_path); + void close_compact_disc(int drv); + bool is_compact_disc_inserted(int drv); + uint32_t is_compact_disc_accessed(); +#if defined(USE_HARD_DISK) + void open_hard_disk(int drv, const _TCHAR* file_path); + void close_hard_disk(int drv); + bool is_hard_disk_inserted(int drv); + uint32_t is_hard_disk_accessed(); +#endif + void set_machine_type(uint16_t machine_id, uint16_t cpu_id); + + void clear_sound_in(); + int get_sound_in_data(int ch, int32_t* dst, int expect_samples, int expect_rate, int expect_channels); + int sound_in(int ch, int32_t* src, int samples); + + double get_current_usec(); + uint64_t get_current_clock_uint64(); void update_config(); - void save_state(FILEIO* state_fio); - bool load_state(FILEIO* state_fio); + bool process_state(FILEIO* state_fio, bool loading); // ---------------------------------------- // for each device diff --git a/source/src/vm/fmtowns/fontrom_20pix.h b/source/src/vm/fmtowns/fontrom_20pix.h index c2b61bef0..a74b0f69b 100644 --- a/source/src/vm/fmtowns/fontrom_20pix.h +++ b/source/src/vm/fmtowns/fontrom_20pix.h @@ -18,7 +18,7 @@ class FONT_ROM_20PIX : public DEVICE protected: uint8_t font_kanji20[0x40000]; public: - FONT_ROM_20PIX(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FONT_ROM_20PIX(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name("Font Roms(20pix)"); } diff --git a/source/src/vm/fmtowns/fontroms.cpp b/source/src/vm/fmtowns/fontroms.cpp index e937f972e..60880e7ca 100644 --- a/source/src/vm/fmtowns/fontroms.cpp +++ b/source/src/vm/fmtowns/fontroms.cpp @@ -14,7 +14,8 @@ namespace FMTOWNS { void FONT_ROMS::initialize() { - memset(font_kanji16, sizeof(font_kanji16), 0xff); + memset(font_kanji16, 0xff, sizeof(font_kanji16)); +// memset(ram, 0x00, sizeof(ram)); FILEIO* fio = new FILEIO(); if(fio->Fopen(create_local_path(_T("FMT_FNT.ROM")), FILEIO_READ_BINARY)) { // FONT fio->Fread(font_kanji16, sizeof(font_kanji16), 1); @@ -24,16 +25,160 @@ void FONT_ROMS::initialize() delete fio; } -uint32_t FONT_ROMS::read_data8(uint32_t addr) +void FONT_ROMS::reset() +{ +// dma_is_vram = true; + kanji_code.w = 0; + kanji_address = 0; +} + +uint8_t FONT_ROMS::read_direct_data8(uint32_t addr) +{ + return font_kanji16[addr & 0x3ffff]; +} + +uint32_t FONT_ROMS::read_memory_mapped_io8(uint32_t addr) { if((addr >= 0xc2100000) && (addr < 0xc2140000)) { return (uint32_t)(font_kanji16[addr & 0x3ffff]); } else if((addr >= 0x000ca000) && (addr < 0x000ca800)) { - return (uint32_t)(font_kanji16[0x1e800 + (addr & 0x7ff)]); + return (uint32_t)(font_kanji16[0x3d000 + (addr & 0x7ff)]); } else if((addr >= 0x000cb000) && (addr < 0x000cc000)) { - return (uint32_t)(font_kanji16[0x1f000 + (addr & 0x7ff)]); + return (uint32_t)(font_kanji16[0x3d800 + (addr & 0xfff)]); } return 0xff; } +void FONT_ROMS::write_memory_mapped_io8(uint32_t addr, uint32_t data) +{ +} +// From MAME 0.216 +void FONT_ROMS::calc_kanji_offset() +{ + uint8_t kanji_bank = (kanji_code.b.h & 0xf0) >> 4; + uint32_t low_addr = (uint32_t)(kanji_code.b.l & 0x1f); + uint32_t mid_addr = (uint32_t)(kanji_code.b.l - 0x20); + uint32_t high_addr = (uint32_t)(kanji_code.b.h); + + switch(kanji_bank) { + case 0: + case 1: + case 2: + kanji_address = + (low_addr << 4) | ((mid_addr & 0x20) << 8) | + ((mid_addr & 0x40) << 6) | + ((high_addr & 0x07) << 9); +// kanji_address >>= 1; + break; + case 3: + case 4: + case 5: + case 6: + kanji_address = + (low_addr << 5) + + ((mid_addr & 0x60) << 9) + + ((high_addr & 0x0f) << 10) + + (((high_addr - 0x30) & 0x70) * 0xc00) + 0x8000; + kanji_address >>= 1; + break; + default: + kanji_address = + (low_addr << 4) | ((mid_addr & 0x20) << 8) | + ((mid_addr & 0x40) << 6) | + ((high_addr & 0x07) << 9); + kanji_address |= (0x38000 >> 1); +// kanji_address >>= 1; + break; + } +} + +void FONT_ROMS::write_io8(uint32_t addr, uint32_t data) +{ + switch(addr & 0xffff) { + case 0xff94: // hidden register + kanji_code.b.h = data; + calc_kanji_offset(); + break; + case 0xff95: // hidden register + kanji_code.b.l = data; + calc_kanji_offset(); + break; + } +} + +uint32_t FONT_ROMS::read_io8(uint32_t addr) +{ + uint32_t val = 0x00; + switch(addr) { + case 0xff96: // LOW + val = font_kanji16[(kanji_address << 1) + 0]; + break; + case 0xff97: // High + val = font_kanji16[(kanji_address << 1) + 1]; + kanji_address++; + break; + } + return val; +} + + +void FONT_ROMS::write_signal(int ch, uint32_t data, uint32_t mask) +{ + if(ch == SIG_TOWNS_FONT_KANJI_LOW) { // write CFF15 + kanji_code.b.l = data & 0x7f; + calc_kanji_offset(); + } else if(ch == SIG_TOWNS_FONT_KANJI_HIGH) { // write CFF14 + kanji_code.b.h = data & 0x7f; + calc_kanji_offset(); + } /*else if(ch == SIG_TOWNS_FONT_DMA_IS_VRAM) { + dma_is_vram = ((data & mask) != 0); + } */else if(ch == SIG_TOWNS_FONT_KANJI_ROW) { // write CFF9E + kanji_address = (kanji_address & 0xfffffff0) | (data & 0x0f); + } +} + +uint32_t FONT_ROMS::read_signal(int ch) +{ + /*if(ch == SIG_TOWNS_FONT_DMA_IS_VRAM) { + return (dma_is_vram) ? 0xffffffff : 0x00000000; + } else */ + if(ch == SIG_TOWNS_FONT_KANJI_DATA_HIGH) { // read CFF97 + uint8_t val = font_kanji16[(kanji_address << 1) + 1]; + kanji_address++; + return val; + } else if(ch == SIG_TOWNS_FONT_KANJI_DATA_LOW) { // read CFF96 + uint8_t val = font_kanji16[(kanji_address << 1) + 0]; + return val; + } else if(ch == SIG_TOWNS_FONT_KANJI_LOW) { // write CFF94 + return kanji_code.b.l; + } else if(ch == SIG_TOWNS_FONT_KANJI_HIGH) { // write CFF95 + return kanji_code.b.h; + } else if(ch == SIG_TOWNS_FONT_KANJI_ROW) { // write CFF9E + return (kanji_address & 0x0f); + } else if(ch >= SIG_TOWNS_FONT_PEEK_DATA) { + int offset = ch - SIG_TOWNS_FONT_PEEK_DATA; + if((offset >= 0) && (offset < 0x40000)) { + return font_kanji16[offset]; + } + } + return 0; +} + +#define STATE_VERSION 1 + +bool FONT_ROMS::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } +// state_fio->StateValue(dma_is_vram); + state_fio->StateValue(kanji_code); + state_fio->StateValue(kanji_address); + +// state_fio->StateArray(ram, sizeof(ram), 1); + return true; +} } diff --git a/source/src/vm/fmtowns/fontroms.h b/source/src/vm/fmtowns/fontroms.h index 1c260b7bd..0dac2c1da 100644 --- a/source/src/vm/fmtowns/fontroms.h +++ b/source/src/vm/fmtowns/fontroms.h @@ -12,21 +12,49 @@ #include "../vm.h" #include "../device.h" +#define SIG_TOWNS_FONT_DMA_IS_VRAM 2 +#define SIG_TOWNS_FONT_KANJI_LOW 4 +#define SIG_TOWNS_FONT_KANJI_HIGH 5 +#define SIG_TOWNS_FONT_KANJI_DATA_LOW 8 +#define SIG_TOWNS_FONT_KANJI_DATA_HIGH 9 +#define SIG_TOWNS_FONT_KANJI_ROW 10 +#define SIG_TOWNS_FONT_PEEK_DATA 0x10000 namespace FMTOWNS { class FONT_ROMS : public DEVICE { protected: uint8_t font_kanji16[0x40000]; +// uint8_t ram[0x1000]; + +// bool dma_is_vram; + pair16_t kanji_code; + uint32_t kanji_address; + + void calc_kanji_offset(); public: - FONT_ROMS(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FONT_ROMS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name("Font Roms"); } ~FONT_ROMS() {} void initialize(); - uint32_t read_data8(uint32_t addr); + void reset(); + + uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + + void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_signal(int ch); + + bool process_state(FILEIO *state_fio, bool loading); + + /* Unique function(s) */ + uint8_t __FASTCALL read_direct_data8(uint32_t addr); }; } diff --git a/source/src/vm/fmtowns/iccard.cpp b/source/src/vm/fmtowns/iccard.cpp new file mode 100644 index 000000000..d88d9d1da --- /dev/null +++ b/source/src/vm/fmtowns/iccard.cpp @@ -0,0 +1,231 @@ +/* + Author : Kyuma.Ohta + Date : 2020.08.10- + + [FM-Towns IC CARD] + + I/O: + 048Ah: R: IC CARD STATUS. +*/ + +#include "./iccard.h" +#include "fileio.h" + +namespace FMTOWNS { + +void TOWNS_ICCARD::initialize() +{ + DEVICE::initialize(); + memset(filename, 0x00, sizeof(filename) / sizeof(_TCHAR)); + + card_changed = false; // 048Ah: bit7 (R) + batt_level = 0x00; // 048Ah: bit 5-4 (R) + eeprom_ready = false; // 048Ah: bit 3 (R) + card_state = 0x03; // 048Ah: bit2-1 (R) : 00=exists, 01,02=imcomplete, 03=none. + write_protect = true; // 048Ah: bit0 (R) + is_rom = true; // ToDo: Will implement RAM. + + is_dirty = false; + if(limit_size == 0) limit_size = 0x01000000; // Default limit is 16MB +} + +void TOWNS_ICCARD::release() +{ + if(!(is_rom) && (is_dirty) && (card_state == 0x00)) { + close_cart(); + } + if(mem != NULL) { + free(mem); + mem = NULL; + } +} + +bool TOWNS_ICCARD::open_cart(const _TCHAR *file_path) +{ + if(file_path == NULL) return false; + if(strlen(file_path) <= 0) return false; + FILEIO* fio = new FILEIO(); + uint32_t file_size; + + if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { + fio->Fseek(0, FILEIO_SEEK_SET); + file_size = fio->Ftell(); + if(new_alloc(file_size)) { + if(fio->Fread(mem, mem_size, 1) == mem_size) { + fio->Fclose(); + delete fio; + // Update filename + strncpy(filename, file_path, sizeof(filename) / sizeof(_TCHAR)); + // ToDo: Implement RAM + write_protect = true; + is_rom = true; + is_dirty = false; + card_state = 0x00; + card_changed = true; + return true; + } else { + if(mem != NULL) free(mem); + mem = NULL; + } + } + is_dirty = false; + mem_size = 0; + } + fio->Fclose(); + delete fio; + return false; // file not exists, keep data. +} + +bool TOWNS_ICCARD::close_cart() +{ + if((mem == NULL) || (mem_size == 0)) return false; // Nothing to save. + if(card_state != 0x00) return false; // Not using card. + + FILEIO* fio = new FILEIO(); + + card_changed = true; + if((is_dirty) && !(is_rom)) { + if(fio->Fopen(filename, FILEIO_WRITE_BINARY)) { + fio->Fwrite(mem, mem_size, 1); + is_dirty = false; + free(mem); + mem = NULL; + mem_size = 0; + memset(filename, 0x00, sizeof(filename)); + fio->Fclose(); + delete fio; + return true; + } + } else { + // Discard only + is_dirty = false; + free(mem); + mem = NULL; + mem_size = 0; + memset(filename, 0x00, sizeof(filename)); + return true; + } + delete fio; + return false; +} + +bool TOWNS_ICCARD::new_alloc(uint32_t new_size) +{ + if(((mem_size != new_size) || (mem == NULL)) && (new_size > 0)) { + if(mem != NULL) free(mem); + mem_size = 0; + if(new_size > limit_size) new_size = limit_size; + mem = (uint8_t*)malloc(new_size); + if(mem != NULL) { // Maybe Alloc + mem_size = new_size; + memset(mem, 0x00, mem_size); // Re-Initialize. + return true; // Success + } + } + return false; +} + +uint32_t TOWNS_ICCARD::read_memory_mapped_io8(uint32_t addr) +{ + if(addr < 0xc0000000) return 0xff; + if(addr >= 0xc2000000) return 0xff; + addr = addr & 0x00ffffff; // Map 16M + if((addr >= mem_size) || (addr >= 0x01000000)) return 0xff; + if(mem == NULL) return 0xff; + + // ToDo: Bank register. + return mem[addr]; +} + +void TOWNS_ICCARD::write_memory_mapped_io8(uint32_t addr, uint32_t data) +{ + if(addr < 0xc0000000) return; + if(addr >= 0xc2000000) return; + addr = addr & 0x00ffffff; // Map 16M + if((addr >= mem_size) || (addr >= 0x01000000)) return; + if(mem == NULL) return; + if(!(is_rom) && !(write_protect) && (card_state == 0x00)) { + // ToDo: Bank register. + uint8_t bak = mem[addr]; + mem[addr] = data; + is_dirty |= ((bak != (uint8_t)data) ? true : false); + } +} + +uint32_t TOWNS_ICCARD::read_io8(uint32_t addr) +{ + // ToDo: Bank register. + uint8_t val = 0xff; + switch(addr) { + case 0: + val = 0x00; + val |= ((card_changed) ? 0x80 : 0x00); + val |= (((batt_level) & 0x03) << 4); + val |= ((eeprom_ready) ? 0x08 : 0x00); + val |= ((card_state & 0x03) << 1); + val |= ((write_protect) ? 0x01 : 0x00); + card_changed = false; + break; + } + return val; +} + +void TOWNS_ICCARD::write_io8(uint32_t addr, uint32_t data) +{ + // ToDo: Bank register. +} + +#define STATE_VERSION 1 + +bool TOWNS_ICCARD::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + + state_fio->StateValue(limit_size); + if(loading) { + uint32_t tmplen = state_fio->FgetUint32_LE(); + if(tmplen == 0) { + if(mem != NULL) free(mem); + mem = NULL; + mem_size = 0; + } else { + if(!(new_alloc(tmplen))) { + // Alloc failed + return false; + } else { + mem_size = tmplen; + state_fio->Fread(mem, (size_t)mem_size, 1); + } + } + } else { + // saving + if(mem == NULL) { + state_fio->FputUint32_LE(0); + } else { + state_fio->FputUint32_LE(mem_size); + state_fio->Fwrite(mem, (size_t)mem_size, 1); + } + } + state_fio->StateBuffer(filename, sizeof(filename), 1); + + state_fio->StateValue(is_rom); + state_fio->StateValue(is_dirty); + + // 048Ah + state_fio->StateValue(card_changed); + state_fio->StateValue(batt_level); + state_fio->StateValue(eeprom_ready); + state_fio->StateValue(card_state); + state_fio->StateValue(write_protect); + + return true; +} + +} + diff --git a/source/src/vm/fmtowns/iccard.h b/source/src/vm/fmtowns/iccard.h new file mode 100644 index 000000000..105197f70 --- /dev/null +++ b/source/src/vm/fmtowns/iccard.h @@ -0,0 +1,66 @@ +/* + Author : Kyuma.Ohta + Date : 2020.08.10- + + [FM-Towns IC CARD] +*/ + +#pragma once + +#include "device.h" + +class FILEIO; + +namespace FMTOWNS { + +class TOWNS_ICCARD: public DEVICE { +protected: + uint32_t limit_size; + bool is_rom; // + bool is_dirty; + + // 048Ah + bool card_changed; + uint8_t batt_level; + bool eeprom_ready; + uint8_t card_state; + bool write_protect; + + _TCHAR filename[_MAX_PATH]; + + uint8_t *mem; + uint32_t mem_size; + bool new_alloc(uint32_t new_size); + +public: + TOWNS_ICCARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + memset(filename, 0x00, sizeof(filename)); + limit_size = 16 * 0x100000; // 16MB + mem_size = 0; + mem = NULL; + set_device_name(_T("TOWNS IC CARD")); + } + ~TOWNS_ICCARD() {} + + virtual void initialize(); + virtual void release(); + + virtual uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + virtual void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + + virtual bool open_cart(const _TCHAR *file_path); + virtual bool close_cart(); + + virtual bool process_state(FILEIO* state_fio, bool loading); + + bool is_cart_inserted() + { + return (card_state == 0x00) ? true : false; + } +}; + +} + diff --git a/source/src/vm/fmtowns/joypad.cpp b/source/src/vm/fmtowns/joypad.cpp new file mode 100644 index 000000000..89c3d90fd --- /dev/null +++ b/source/src/vm/fmtowns/joypad.cpp @@ -0,0 +1,142 @@ +/* + FUJITSU FM Towns Emulator 'eFMTowns' + + Author : Kyuma.Ohta + Date : 2020.00.26 - + History : 2020.09.26 Separate from joystick.cpp/joystick.h . + [ Towns PAD ] + +*/ + +#include "./joystick.h" +#include "./joypad.h" + +namespace FMTOWNS { +void JOYPAD::initialize() +{ + DEVICE::initialize(); + _TCHAR tmps[128] = {0}; + my_stprintf_s(tmps, sizeof(tmps), _T("FM-Towns JOY PAD #%d"), pad_num); + set_device_name(_T("%s"), tmps); +// rawdata = emu->get_joy_buffer(); + register_frame_event(this); +} + +void JOYPAD::reset() +{ + sel_line = true; +// write_signals(&line_dat, 0); + query_joystick(); + write_signals(&line_com, (enabled) ? 0xffffffff : 0x00000000); +} + + +void JOYPAD::event_pre_frame(void) +{ +} + +void JOYPAD::event_frame(void) +{ +} + +void JOYPAD::query_joystick(void) +{ + // enabled + rawdata = emu->get_joy_buffer(); + uint32_t stat = 0; + if((rawdata != NULL) && (enabled)) { + uint32_t d = rawdata[pad_num]; + if((type_6buttons) && (sel_line)) { // 6Buttons Multiplied + // If COM == 1 THEN CHECK BUTTONS + // 6Buttons PAD is seems to be this schematic: + // http://www.awa.or.jp/home/shimojo/towpadx.htm + // RIGHT <-> C / LEFT <-> X / UP <-> Z / DOWN <->Y + uint8_t buttons = (rawdata[pad_num] >> 8) & 0x0f; + if((buttons & 0x01) != 0) stat |= LINE_JOYPORT_RIGHT; + if((buttons & 0x02) != 0) stat |= LINE_JOYPORT_LEFT; + if((buttons & 0x04) != 0) stat |= LINE_JOYPORT_DOWN; + if((buttons & 0x08) != 0) stat |= LINE_JOYPORT_UP; + } else { + // If ((COM != 0) OR (PAD IS 2BUTTONS)) THEN CHECK AXIS + uint8_t axis = rawdata[pad_num] & 0x0f; + if((axis & 0x01) != 0) stat |= LINE_JOYPORT_UP; + if((axis & 0x02) != 0) stat |= LINE_JOYPORT_DOWN; + if((axis & 0x04) != 0) stat |= LINE_JOYPORT_LEFT; + if((axis & 0x08) != 0) stat |= LINE_JOYPORT_RIGHT; + } + if((rawdata[pad_num] & 0x10) != 0) stat |= LINE_JOYPORT_A; + if((rawdata[pad_num] & 0x20) != 0) stat |= LINE_JOYPORT_B; + // SEL = UP + DOWN, RUN = LEFT + RIGHT + if((rawdata[pad_num] & 0x40) != 0) stat |= (LINE_JOYPORT_LEFT | LINE_JOYPORT_RIGHT); + if((rawdata[pad_num] & 0x80) != 0) stat |= (LINE_JOYPORT_UP | LINE_JOYPORT_DOWN); + } else { + // None Connected + stat = 0x00; + } + write_signals(&line_dat, stat); +} + +void JOYPAD::write_signal(int id, uint32_t data, uint32_t mask) +{ + uint32_t ndata = data & mask; + + switch(id) { + case SIG_JOYPAD_QUERY: + if(ndata == (1 << pad_num)) { + if(enabled) query_joystick(); + } + break; + case SIG_JOYPAD_ENABLE: + if((ndata & (1 << SIG_JOYPORT_TYPE_2BUTTONS)) != 0) { + out_debug_log(_T("SELECT 2BUTTONS PAD")); + enabled = true; + type_6buttons = false; + reset(); + } else if((ndata & (1 << SIG_JOYPORT_TYPE_6BUTTONS)) != 0) { + out_debug_log(_T("SELECT 6BUTTONS PAD")); + enabled = true; + type_6buttons = true; + reset(); + } else { + out_debug_log(_T("DISCONNECTED")); + enabled = false; + type_6buttons = false; + sel_line = false; + reset(); + } + break; + case SIG_JOYPAD_SELECT_BUS: +// out_debug_log(_T("SIG_JOYPAD_SELECT_BUS, VALUE=%08X"), ndata); + if(ndata != 0) { + sel_line = true; + } else { + sel_line = false; + } + write_signals(&line_com, (sel_line) ? 0xffffffff : 0x00000000); + break; + } +} + + +void JOYPAD::update_config() +{ +} + + +#define STATE_VERSION 3 + +bool JOYPAD::process_state(FILEIO *state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(sel_line); + state_fio->StateValue(type_6buttons); + state_fio->StateValue(pad_num); + state_fio->StateValue(enabled); + return true; +} +} diff --git a/source/src/vm/fmtowns/joypad.h b/source/src/vm/fmtowns/joypad.h new file mode 100644 index 000000000..7fe9c1f23 --- /dev/null +++ b/source/src/vm/fmtowns/joypad.h @@ -0,0 +1,74 @@ +/* + FUJITSU FM Towns Emulator 'eFMTowns' + + Author : Kyuma.Ohta + Date : 2020.09.26 - + History : 2020.09.26 Separate from joystick.cpp/joystick.h . + [ Towns PAD ] + +*/ +#pragma once + +#include "device.h" + +#define SIG_JOYPAD_SELECT_BUS 1 +#define SIG_JOYPAD_ENABLE 2 +#define SIG_JOYPAD_QUERY 3 + +namespace FMTOWNS { + +class JOYPAD : public DEVICE { +protected: + outputs_t line_dat; + outputs_t line_com; + + bool sel_line; + bool type_6buttons; + int pad_num; + bool enabled; + + const uint32_t* rawdata; + virtual void query_joystick(); +public: + JOYPAD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + sel_line = false; + type_6buttons = false; + enabled = true; + pad_num = 0; + + initialize_output_signals(&line_dat); + initialize_output_signals(&line_com); + rawdata = NULL; + //set_device name moved to initialize(). + } + ~JOYPAD() {} + + virtual void reset(void); + virtual void initialize(void); + virtual void event_pre_frame(void); + virtual void event_frame(void); + + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + + virtual void update_config(); + virtual bool process_state(FILEIO* state_fio, bool loading); + + // Unique functions + void set_context_port_num(int num) + { + if((num >= 0) && (num <= 1)) { + pad_num = num; + } + } + void set_context_data(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&line_dat, dev, id, mask); + } + void set_context_com(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&line_com, dev, id, mask); + } + +}; +} diff --git a/source/src/vm/fmtowns/joystick.cpp b/source/src/vm/fmtowns/joystick.cpp new file mode 100644 index 000000000..408f2b999 --- /dev/null +++ b/source/src/vm/fmtowns/joystick.cpp @@ -0,0 +1,356 @@ +/* + FUJITSU FM Towns Emulator 'eFMTowns' + + Author : Kyuma.Ohta + Date : 2020.01.28 - + History : 2020.01.28 Initial from FM7. + [ Towns Joystick ports] + +*/ + +#include "./joystick.h" + +namespace FMTOWNS { +#define EVENT_MOUSE_TIMEOUT 1 +#define EVENT_MOUSE_SAMPLING 2 + +void JOYSTICK::reset() +{ + joydata[0] = joydata[1] = 0x00; + stat_com[0] = stat_com[1] = false; + dx = dy = 0; + lx = ly = 0; + mouse_state = emu->get_mouse_buffer(); + mask = 0x00; + mouse_type = -1; // Force update data. + mouse_phase = 0; + mouse_strobe = false; + mouse_data = 0x00; + clear_event(this, mouse_timeout_event); + + // Force reset pads. + connected_type[0] = 0xffffffff; + connected_type[1] = 0xffffffff; + + update_config(); // Update MOUSE PORT. + +// if(mouse_sampling_event >= 0) { +// cancel_event(this, mouse_sampling_event); +// } +// register_event(this, EVENT_MOUSE_SAMPLING, 16.7e3, true, &mouse_sampling_event); +} + +void JOYSTICK::initialize() +{ + rawdata = emu->get_joy_buffer(); + mouse_state = emu->get_mouse_buffer(); + joydata[0] = joydata[1] = 0x00; + dx = dy = 0; + lx = ly = 0; + mouse_button = 0x00; + mouse_timeout_event = -1; + mouse_sampling_event = -1; + set_emulate_mouse(); + mouse_type = config.mouse_type; + register_frame_event(this); +} + +void JOYSTICK::release() +{ +} + +void JOYSTICK::event_frame() +{ + event_callback(EVENT_MOUSE_SAMPLING, 0); +} + +void JOYSTICK::write_io8(uint32_t address, uint32_t data) +{ + // ToDo: Mouse + if(address == 0x04d6) { + if(emulate_mouse[0]) { + update_strobe(((data & 0x10) != 0)); + } else if(emulate_mouse[1]) { + update_strobe(((data & 0x20) != 0)); + } + mask = data; + write_signals(&outputs_mask, data); + } +} + +uint32_t JOYSTICK::read_io8(uint32_t address) +{ + // ToDo: Implement 6 buttons pad. & mouse + uint8_t retval = 0; + uint8_t port_num = (address & 0x02) >> 1; + switch(address) { + case 0x04d0: + case 0x04d2: + if(emulate_mouse[port_num]) { + uint8_t trig = (mask >> (port_num << 1)) & 0x03; + uint8_t mask2 = (mask >> (port_num + 4)) & 0x01; + uint8_t rval = 0x70; + rval |= (update_mouse() & 0x0f); + mouse_state = emu->get_mouse_buffer(); + if(mouse_state != NULL) { + uint32_t stat = mouse_state[2]; + mouse_button = 0x00; + if((stat & 0x01) == 0) mouse_button |= 0x10; // left + if((stat & 0x02) == 0) mouse_button |= 0x20; // right + } + if((mask2 & 0x01) == 0) { // COM + rval = rval & ~0x40; + } + if((trig & 0x02) == 0) { // TRIG2 + rval = rval & ~0x20; + } + if((trig & 0x01) == 0) { // TRIG1 + rval = rval & ~0x10; + } + if((mouse_button & 0x10) != 0) { + rval &= ~0x10; // Button LEFT + } + if((mouse_button & 0x20) != 0) { + rval &= ~0x20; // Button RIGHT + } + retval = rval; + } else { + write_signals(&outputs_query, 1 << (port_num + 0)); + uint8_t trig = (mask >> (port_num << 1)) & 0x03; + uint8_t mask2 = (mask >> (port_num + 4)) & 0x01; + retval = 0x7f; + if((mask2 & 0x01) == 0) { // COM + retval = retval & ~0x40; + } + if((trig & 0x02) == 0) { // TRIG2 + retval = retval & ~0x20; + } + if((trig & 0x01) == 0) { // TRIG1 + retval = retval & ~0x10; + } + if(connected_type[port_num] == SIG_JOYPORT_TYPE_NULL) { + // None Connected + return retval; + } + // Trigger independents from direction keys. + if((joydata[port_num] & LINE_JOYPORT_B) != 0) { + retval = retval & ~0x20; + } + if((joydata[port_num] & LINE_JOYPORT_A) != 0) { + retval = retval & ~0x10; + } + //if((mask & (0x10 << port_num)) == 0) { + if((joydata[port_num] & LINE_JOYPORT_LEFT) != 0) { // LEFT + retval = retval & ~0x04; // LEFT + } + if((joydata[port_num] & LINE_JOYPORT_RIGHT) != 0) { // RIGHT + retval = retval & ~0x08; // RIGHT + } + if((joydata[port_num] & LINE_JOYPORT_UP) != 0) { // UP + retval = retval & ~0x01; // FWD + } + if((joydata[port_num] & LINE_JOYPORT_DOWN) != 0) { // DOWN + retval = retval & ~0x02; // BACK + } + } + return retval; + break; + default: + break; + } + return 0xff; +} + +void JOYSTICK::event_callback(int event_id, int err) +{ + switch(event_id) { + case EVENT_MOUSE_TIMEOUT: + mouse_phase = 0; + mouse_timeout_event = -1; + dx = dy = 0; + lx = ly = 0; + mouse_data = 0x00; + break; + case EVENT_MOUSE_SAMPLING: + if((emulate_mouse[0]) || (emulate_mouse[1])) { + mouse_state = emu->get_mouse_buffer(); + if(mouse_state != NULL) { + dx += mouse_state[0]; + dy += mouse_state[1]; + if(dx < -127) { + dx = -127; + } else if(dx > 127) { + dx = 127; + } + if(dy < -127) { + dy = -127; + } else if(dy > 127) { + dy = 127; + } + } + } + break; + } +} + +void JOYSTICK::write_signal(int id, uint32_t data, uint32_t _mask) +{ + int ch = (id >> 24) & 1; + int bustype = id & 0x300; + int num = id & 0xff; + //out_debug_log(_T("SIGNAL SENT, CH=%d TYPE=%d VALUE=%08X"), ch, num, data); + if(num == connected_type[ch]) { + switch(bustype) { + case SIG_JOYPORT_DATA: + joydata[ch] = data; + break; + case SIG_JOYPORT_COM: + stat_com[ch] = ((data & mask) != 0) ? true : false; + break; + } + } + //if(type != connected_type[num]) return; +} + +void JOYSTICK::update_config(void) +{ + uint32_t ntype[2] = {0}; + for(int i = 0; i < 2; i++) { + switch(config.joystick_type) { + case 0: + ntype[i] = SIG_JOYPORT_TYPE_NULL; + break; + case 1: + ntype[i] = SIG_JOYPORT_TYPE_2BUTTONS; + break; + case 2: + ntype[i] = SIG_JOYPORT_TYPE_6BUTTONS; + break; + } + } + set_emulate_mouse(); + if(emulate_mouse[0]) { + ntype[0] = SIG_JOYPORT_TYPE_MOUSE; + } + if(emulate_mouse[1]) { + ntype[1] = SIG_JOYPORT_TYPE_MOUSE; + } + for(int i = 0; i < 2; i++) { +// if(connected_type[i] != ntype[i]) { + write_signals(&outputs_enable[i], 1 << ntype[i]); +// } + switch(ntype[i]) { + case SIG_JOYPORT_TYPE_2BUTTONS: + case SIG_JOYPORT_TYPE_6BUTTONS: + connected_type[i] = SIG_JOYPORT_TYPE_2BUTTONS; + break; + default: + connected_type[i] = ntype[i]; + break; + } + } + mouse_type = config.mouse_type; +} + +void JOYSTICK::set_emulate_mouse() +{ + switch(config.mouse_type & 0x03){ + case 1: + emulate_mouse[0] = true; + emulate_mouse[1] = false; + break; + case 2: + emulate_mouse[0] = false; + emulate_mouse[1] = true; + break; + default: + emulate_mouse[0] = false; + emulate_mouse[1] = false; + break; + } +} + +void JOYSTICK::update_strobe(bool flag) +{ + bool _bak = mouse_strobe; + mouse_strobe = flag; + if((_bak != mouse_strobe)/* && (flag)*/) { + if((mouse_phase == 0)) { + // Sample data from MOUSE to registers. + lx = -dx; + ly = -dy; + dx = 0; + dy = 0; + clear_event(this, mouse_timeout_event); + register_event(this, EVENT_MOUSE_TIMEOUT, 600.0, false, &mouse_timeout_event); + if(mouse_strobe) { + mouse_phase = 1; // SYNC from MAME 0.225. 20201126 K.O + } + } + mouse_phase++; +// if(mouse_phase > 5) { +// mouse_phase = 0; +// mouse_strobe = false; +// clear_event(this, mouse_timeout_event); +// } + } +} + +uint32_t JOYSTICK::update_mouse() +{ + switch(mouse_phase) { +// case 1: // SYNC +// mouse_data = 0x0f; +// break; + case 2: // X_HIGH + mouse_data = (lx >> 0) & 0x0f; + break; + case 3: // X_LOW + mouse_data = (lx >> 4) & 0x0f; + break; + case 4: // Y_HIGH + mouse_data = (ly >> 0) & 0x0f; + break; + case 5: // Y_LOW + mouse_data = (ly >> 4) & 0x0f; + break; + default: + mouse_data = 0x0f; + break; + } +// out_debug_log(_T("READ MOUSE DATA=%01X PHASE=%d STROBE=%d"), mouse_data, mouse_phase, (mouse_strobe) ? 1 : 0); + return mouse_data; +} + +#define STATE_VERSION 5 + +bool JOYSTICK::process_state(FILEIO *state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(mask); + state_fio->StateArray(joydata, sizeof(joydata), 1); + state_fio->StateArray(connected_type, sizeof(connected_type), 1); + + state_fio->StateArray(emulate_mouse, sizeof(emulate_mouse), 1); + state_fio->StateArray(stat_com, sizeof(stat_com), 1); + state_fio->StateValue(dx); + state_fio->StateValue(dy); + state_fio->StateValue(lx); + state_fio->StateValue(ly); + state_fio->StateValue(mouse_button); + state_fio->StateValue(mouse_type); + state_fio->StateValue(mouse_strobe); + state_fio->StateValue(mouse_phase); + state_fio->StateValue(mouse_data); + state_fio->StateValue(mouse_timeout_event); + state_fio->StateValue(mouse_sampling_event); + + return true; +} + +} diff --git a/source/src/vm/fmtowns/joystick.h b/source/src/vm/fmtowns/joystick.h new file mode 100644 index 000000000..353cc6a65 --- /dev/null +++ b/source/src/vm/fmtowns/joystick.h @@ -0,0 +1,125 @@ +/* + FUJITSU FM Towns Emulator 'eFMTowns' + + Author : Kyuma.Ohta + Date : 2020.01.28 - + History : 2020.01.28 Initial from FM7. + [ Towns Joystick ports] + +*/ + +#pragma once +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" + +#define SIG_JOYPORT_CH0 0 +#define SIG_JOYPORT_CH1 (65536 * 256) +#define SIG_JOYPORT_DATA 256 +#define SIG_JOYPORT_COM 512 + +#define SIG_JOYPORT_TYPE_NULL 0 +#define SIG_JOYPORT_TYPE_2BUTTONS 1 +#define SIG_JOYPORT_TYPE_6BUTTONS 2 +#define SIG_JOYPORT_TYPE_ANALOG 3 /* ToDo: For CYBER STICK */ +#define SIG_JOYPORT_TYPE_MOUSE 4 +#define SIG_JOYPORT_TYPE_TWIN_2B_0 5 /* ToDo: For RIBBLE RABBLE */ +#define SIG_JOYPORT_TYPE_TWIN_2B_1 6 /* ToDo: For RIBBLE RABBLE */ +#define SIG_JOYPORT_CONNECT 7 /* ToDo: RESET */ + +// MSX RELATED PORT CONFIGURATION +// https://www.msx.org/wiki/General_Purpose_port +#define LINE_JOYPORT_UP (1 << 0) /* IN 1 */ +#define LINE_JOYPORT_DOWN (1 << 1) /* IN 2 */ +#define LINE_JOYPORT_LEFT (1 << 2) /* IN 3 */ +#define LINE_JOYPORT_RIGHT (1 << 3) /* IN 4 */ +#define LINE_JOYPORT_A (1 << 4) /* IN 6 */ +#define LINE_JOYPORT_B (1 << 5) /* IN 7 */ +#define LINE_JOYPORT_TRIGGER (1 << 6) /* OUT 8 */ +#define LINE_JOYPORT_DUMMY (1 << 7) /* DUMMY */ +// Belows are dummy define +#define LINE_JOYPORT_POW_PLUS (1 << 8) /* +5V PIN 5*/ +#define LINE_JOYPORT_POW_GND (1 << 9) /* GND PIN 8*/ + +namespace FMTOWNS { +class JOYSTICK : public DEVICE +{ +private: + outputs_t outputs_mask; + outputs_t outputs_query; + outputs_t outputs_enable[2]; + bool emulate_mouse[2]; + uint32_t joydata[2]; + bool stat_com[2]; + + const uint32_t *rawdata; + const int32_t *mouse_state; + int dx, dy; + int lx, ly; + uint32_t mouse_button; + int mouse_phase; + bool mouse_strobe; + uint8_t mouse_data; + + int mouse_timeout_event; + int mouse_sampling_event; + int mouse_type; + uint8_t mask; + uint32_t connected_type[2]; + + void set_emulate_mouse(); + virtual void update_strobe(bool flag); + uint32_t update_mouse(); + +public: + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + mouse_timeout_event = -1; + mouse_sampling_event = -1; + initialize_output_signals(&outputs_query); + initialize_output_signals(&outputs_mask); + initialize_output_signals(&outputs_enable[0]); + initialize_output_signals(&outputs_enable[1]); + connected_type[0] = SIG_JOYPORT_CH0 | SIG_JOYPORT_TYPE_NULL; + connected_type[1] = SIG_JOYPORT_CH1 | SIG_JOYPORT_TYPE_NULL; + set_device_name(_T("FM-Towns PAD Port and MOUSE (JIS)")); + } + ~JOYSTICK() {} + + // common functions + void initialize(void); + void event_frame(void); + void release(); + void reset(); + + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void __FASTCALL event_callback(int event_id, int err); + void update_config(); + + bool process_state(FILEIO* state_fio, bool loading); + + // unique functions + void set_context_enable0(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&outputs_enable[0], dev, id, mask); + } + void set_context_enable1(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&outputs_enable[1], dev, id, mask); + } + void set_context_mask(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&outputs_mask, dev, id, mask); + } + void set_context_query(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&outputs_query, dev, id, mask); + } + + +}; +} + + diff --git a/source/src/vm/fmtowns/keyboard.cpp b/source/src/vm/fmtowns/keyboard.cpp index 68bbfa06e..8483e9323 100644 --- a/source/src/vm/fmtowns/keyboard.cpp +++ b/source/src/vm/fmtowns/keyboard.cpp @@ -12,34 +12,249 @@ #include "../i8259.h" #include "../../fifo.h" +#define EVENT_KEY_CODE 1 +#define EVENT_DELAY_PUSH 2 +#define EVENT_BOOT_TIMEOUT 3 +#define EVENT_REPEAT1 4 +#define EVENT_REPEAT2 5 + +namespace FMTOWNS { void KEYBOARD::initialize() { + DEVICE::initialize(); key_buf = new FIFO(64); - register_frame_event(this); + cmd_buf = new FIFO(16); + event_keycode = -1; + event_key_reset = -1; + event_repeat = -1; + + memset(table, 0, sizeof(table)); + memset(boot_code, 0x00, sizeof(boot_code)); + boot_ptr = 0; + boot_seq = false; + boot_code_ptr = 0; + repeat_start_ms = 400; + repeat_tick_ms = 30; + + special_boot_num = -1; } void KEYBOARD::release() { + cmd_buf->release(); key_buf->release(); + delete key_buf; + delete cmd_buf; } - + void KEYBOARD::reset() { + boot_seq = false; + reset_device(); +} + +void KEYBOARD::reset_device() +{ + out_debug_log("RESET\n"); + + last_cmd = 0x00; memset(table, 0, sizeof(table)); key_buf->clear(); + cmd_buf->clear(); + kbstat = kbdata = kbint = kbmsk = 0; + device_order = false; + enable_double_pressed_cursor = true; + nmi_status = false; + reserved_key_num = -1; + if(event_keycode > -1) { + cancel_event(this, event_keycode); + } + if(event_key_reset > -1) { + cancel_event(this, event_key_reset); + } + if(event_keycode > -1) { + cancel_event(this, event_keycode); + } + event_key_reset = -1; + event_repeat = -1; + event_keycode = -1; + write_signals(&output_intr_line, 0); + write_signals(&output_nmi_line, 0); + memset(boot_code, 0x00, sizeof(boot_code)); + boot_seq = false; + boot_code_ptr = 0; +} + +void KEYBOARD::enqueue_key(uint8_t code) +{ + key_buf->write(0xa0); + key_buf->write(code); } +void KEYBOARD::enqueue_key2(uint8_t code) +{ + key_buf->write(0xf0); + key_buf->write(code); +} + +void KEYBOARD::special_reset(int num) +{ + out_debug_log("SPECIAL RESET %d\n", num); + if(num < 0) return; + if(num >= 12) return; + reset_device(); + special_boot_num = num; + boot_seq = true; +// kbstat |= 1; + + static const uint8_t bootcode_debug[] = {0x20, 0x13, 0x2E, 0x17, 0x22}; + static const uint8_t bootcode_cd[] = {0x2C, 0x20}; + static const uint8_t bootcode_icm[] = {0x18, 0x2C, 0x30, 0x18, 0x2C}; + static const uint8_t dnum[] = {0x0B, 0x02, 0x03, 0x04, 0x05}; + switch(num) { + case 0: // CD +// enqueue_key(0x7f); + memcpy(boot_code, bootcode_cd, sizeof(bootcode_cd)); + break; + case 1: + case 2: + case 3: + case 4: +// enqueue_key(0x7f); + boot_code[0] = 0x21; + boot_code[1] = dnum[num - 1]; + break; + case 5: + case 6: + case 7: + case 8: + case 9: + boot_code[0] = 0x23; + boot_code[1] = dnum[num - 5]; + break; + case 10: // ICM +// enqueue_key(0x7f); + memcpy(boot_code, bootcode_icm, sizeof(bootcode_icm)); + break;; + case 11: // DEBUG +// enqueue_key(0x7f); + memcpy(boot_code, bootcode_debug, sizeof(bootcode_debug)); + break;; + } + if((num >= 0) && (num < 12)) { +// register_event(this, EVENT_REPEAT1, (double)repeat_start_ms * 1.0e3, false, &event_repeat); + register_key_interrupt(false); // NEXT BYTE + } +// register_event(this, EVENT_BOOT_TIMEOUT, 30.0e6, false, &event_key_reset); +} + +void KEYBOARD::register_key_interrupt(bool first) +{ + double usec = (first) ? 1000.0 : 50.0; + if(event_keycode > -1) { + cancel_event(this, event_keycode); + } + event_keycode = -1; + register_event(this, EVENT_KEY_CODE, usec, false, &event_keycode); +} + +void KEYBOARD::do_common_command(uint8_t cmd) +{ + static const int type_start_ms[] = {400, 500, 300}; + static const int type_repeat_ms[] = {50, 30, 20}; + out_debug_log(_T("CMD %02X"), cmd); + switch(cmd) { + case 0xa0: + this->reset_device(); // RESET + special_boot_num = -1; + // From Tsugaru + boot_seq = false; + boot_code_ptr = 0; + break; + case 0xa1: + if(last_cmd != 0xa0) { + this->reset_device(); // RESET + special_boot_num = -1; + memset(boot_code, 0x00, sizeof(boot_code)); + boot_ptr = 0; + boot_seq = false; + boot_code_ptr = 0; + } + break; + case 0xa4: + // Check double press (for OYAYUBI-Shift) + break; + case 0xa5: + // Don't check double press (for OYAYUBI-Shift) + break; + case 0xa9: + case 0xaa: + case 0xab: + repeat_start_ms = type_start_ms[cmd - 0xa9]; + break; + case 0xac: + case 0xad: + case 0xae: + repeat_tick_ms = type_repeat_ms[cmd - 0xac]; + break; + case 0xb0: + enable_double_pressed_cursor = true; + break; + case 0xb1: + enable_double_pressed_cursor = false; + break; + case 0xb2: + write_signals(&output_nmi_line, 0); + nmi_status = false; + break; + default: + break; + } + last_cmd = cmd; +} + +// Mame 0.216 void KEYBOARD::write_io8(uint32_t addr, uint32_t data) { +// out_debug_log(_T("WRITE I/O ADDR=%04X VAL=%02X"), addr, data); switch(addr) { case 0x600: // data -// kbstat |= 2; + kbstat &= ~0x08; + kbstat |= 1; break; case 0x602: // command + if((data & 0x80) == 0x00) { + // Second byte + if((device_order) && (cmd_buf->count() > 0)) { + cmd_buf->write(data & 0x7f); + } else { + // Illegal + cmd_buf->clear(); + device_order = false; + } + kbstat |= 0x08; + } else if(data & 0xe0 == 0xc0) { + // Device order + if((cmd_buf->count() > 0) && (device_order)){ + // DO DEVICE ORDER + } + cmd_buf->clear(); + cmd_buf->write(data & 0xff); + device_order = false; + kbstat |= 0x08; + } else if(data & 0xe0 == 0xa0) { + // Common order + if((cmd_buf->count() > 0) && (device_order)){ + // DO DEVICE ORDER + } + device_order = false; + kbstat |= 0x08; + do_common_command(data); + } break; case 0x604: kbmsk = data; @@ -49,87 +264,291 @@ void KEYBOARD::write_io8(uint32_t addr, uint32_t data) uint32_t KEYBOARD::read_io8(uint32_t addr) { + uint8_t kbtmp; + kbtmp = kbdata; + switch(addr) { case 0x600: kbint &= ~1; - d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, 0, 0); - kbstat &= ~1; - return kbdata; + write_signals(&output_intr_line, 0); + if((key_buf->empty()) && !(boot_seq)) { + kbstat &= ~1; + } else { + register_key_interrupt(false); // NEXT BYTE + } + out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbdata); + return kbtmp; case 0x602: +// out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbstat); return kbstat; case 0x604: - return kbint | 0xfc; +// out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbint); + return (((kbint & 1) != 0) ? 1 : 0) | ((nmi_status) ? 2 : 0); + break; } return 0; } -void KEYBOARD::event_frame() +void KEYBOARD::event_callback(int event_id, int err) { - if(!(kbstat & 1) && !key_buf->empty()) { + switch(event_id) { + case EVENT_KEY_CODE: + if(boot_seq) { + if((boot_code_ptr & 1) == 0) { + kbdata = (boot_code_ptr < 12) ? 0xA0 : 0xF0; + if(boot_code_ptr >= 12) { + //boot_seq = false; + } + } else { + if(((boot_code_ptr >> 1) == 0) || (boot_code_ptr >= 12)) { + kbdata = 0x7F; + } else { + switch(special_boot_num) { + case 0: // CD + case 1: // F0 + case 2: // F1 + case 3: // F2 + case 4: // F3 + case 5: // H0 + case 6: // H1 + case 7: // H2 + case 8: // H3 + case 9: // H4 + kbdata = boot_code[(boot_code_ptr >> 1) % 2]; + break; + case 10: // ICM + kbdata = boot_code[(boot_code_ptr >> 1) % 3]; + break; + case 11: // DEBUG + kbdata = boot_code[(boot_code_ptr >> 1) % 5]; + break; + default: + kbdata = key_buf->read(); + break; + } + } + } + boot_code_ptr++; + } else { + kbdata = key_buf->read(); + } kbstat |= 1; - kbdata = key_buf->read(); - } - if((kbstat & 1) && (kbmsk & 1) && !(kbint & 1)) { - kbint |= 1; - d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR1, 1, 1); + if(kbmsk & 1) { + kbint |= 1; + write_signals(&output_intr_line, 0xffffffff); + } + event_keycode = -1; + break; + case EVENT_REPEAT1: + event_repeat = -1; + if(boot_seq) { + /*if(is_repeat)*/ { + register_event(this, EVENT_REPEAT2, (double)repeat_tick_ms * 1.0e3, true, &event_repeat); + out_debug_log("REPEAT"); + for(int i = 0; i < 256; i++) { + if((table[i] != 0) && (key_table[i] >= 0x5b) && (key_table[i] < 0x52)) { + key_up2(i); + key_down2(i); + } + } + } + } + break; + case EVENT_REPEAT2: + { + if(!(boot_seq)) { + if(event_repeat > -1) { + cancel_event(this, event_repeat); + event_repeat = -1; + } + } else { + for(int i = 0; i < 256; i++) { + if((table[i] != 0) && (key_table[i] >= 0x5b) && (key_table[i] < 0x52)) { + key_up2(i); + key_down2(i); + } + } + } + } + break; + case EVENT_BOOT_TIMEOUT: + event_key_reset = -1; + boot_seq = false; + break; } -// kbstat &= ~2; } - + void KEYBOARD::key_down(int code) { -// if(!table[code]) { + if(!table[code]) { table[code] = 1; - if(code = key_table[code]) { - // $11:CTRL, $10:SHIFT - key_buf->write(0xa0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0)); - key_buf->write(code); + key_down2(code); + } +} + +void KEYBOARD::key_down2(int code) +{ + if(code = key_table[code]) { + // $11:CTRL, $10:SHIFT + if((code >= 0x70) && (code < 0x7a)) { + // If PFkey, press with /*SHIFT or */RALT, PF += 10. + if((table[0xa5]) /*|| (table[0x10])*/) { // RALT /*or SHIFT*/ + static const int pf1xtbl[] = { 0x69, 0x5b, 0x74, 0x75, 0x76, + 0x77, 0x78, 0x79, 0x7a, 0x7b}; + code = pf1xtbl[code - 0x70]; + } + } else if((code == 0x7d)) { // Print Screen + RALT -> Kanji Jisho + if(table[0xa5]) { // RALT + code = 0x6b; + } + } else if((code == 0x7c)) { // Pause Break + RALT -> Tango Touroku + if(table[0xa5]) { // RALT + code = 0x6d; + } + } else if((code == 0x6c)) { // Scroll Lock + RALT -> Tango Massyou. + if(table[0xa5]) { // RALT + code = 0x6c; + } } -// } + if(boot_seq) { + key_buf->write(0xa0); + } else { + key_buf->write(0xc0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0)); + } + key_buf->write(code & 0x7f); + register_key_interrupt(true); + } } + void KEYBOARD::key_up(int code) +{ + table[code] = 0; + key_up2(code); +} + +void KEYBOARD::key_up2(int code) { // if(table[code]) { - table[code] = 0; if(code = key_table[code]) { - key_buf->write(0xb0); - key_buf->write(code); + if((code >= 0x70) && (code < 0x7a)) { + // If PFkey, press with /*SHIFT or */RALT, PF += 10. + if((table[0xa5]) /*|| (table[0x10])*/) { // RALT /*or SHIFT*/ + static const int pf1xtbl[] = { 0x69, 0x5b, 0x74, 0x75, 0x76, + 0x77, 0x78, 0x79, 0x7a, 0x7b}; + code = pf1xtbl[code - 0x70]; + } + } else if((code == 0x7d)) { // Print Screen + RALT -> Kanji Jisho + if(table[0xa5]) { // RALT + code = 0x6b; + } + } else if((code == 0x7c)) { // Pause Break + RALT -> Tango Touroku + if(table[0xa5]) { // RALT + code = 0x6d; + } + } else if((code == 0x6c)) { // Scroll Lock + RALT -> Tango Massyou. + if(table[0xa5]) { // RALT + code = 0x6c; + } + } + key_buf->write(0xd0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0)); + key_buf->write(code & 0x7f); + register_key_interrupt(true); } // } } -#define STATE_VERSION 1 - -void KEYBOARD::save_state(FILEIO* state_fio) +void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask) { - state_fio->FputUint32(STATE_VERSION); - state_fio->FputInt32(this_device_id); - - key_buf->save_state((void *)state_fio); - state_fio->FputUint8(kbstat); - state_fio->FputUint8(kbdata); - state_fio->FputUint8(kbint); - state_fio->FputUint8(kbmsk); - state_fio->Fwrite(table, sizeof(table), 1); + switch(id) { + case SIG_KEYBOARD_BOOTSEQ_END: + if(((data & mask) != 0) && (boot_seq)) { + out_debug_log(_T("SIG_KEYBOARD_BOOTSEQ_END")); +/* switch(special_boot_num) { + case 0: // CD +// memcpy(boot_code, bootcode_cd, sizeof(bootcode_cd)); + key_up('C'); + key_up('D'); + break; + case 1: + case 2: + case 3: + case 4: + key_up('F'); + key_up('0' + special_boot_num - 1); + break; + case 5: + case 6: + case 7: + case 8: + case 9: + key_up('F'); + key_up('0' + special_boot_num - 5); + break; + case 10: + key_up('I'); + key_up('C'); + key_up('M'); + break; + case 11: + key_up('D'); + key_up('E'); + key_up('B'); + key_up('U'); + key_up('G'); + break; + } +*/ + boot_seq = false; + } + break; + } } + +#define STATE_VERSION 3 -bool KEYBOARD::load_state(FILEIO* state_fio) +bool KEYBOARD::process_state(FILEIO* state_fio, bool loading) { - if(state_fio->FgetUint32() != STATE_VERSION) { - return false; - } - if(state_fio->FgetInt32() != this_device_id) { + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + if(!(key_buf->process_state((void *)state_fio, loading))) { return false; } - if(!key_buf->load_state((void *)state_fio)) { + if(!(cmd_buf->process_state((void *)state_fio, loading))) { return false; } - kbstat = state_fio->FgetUint8(); - kbdata = state_fio->FgetUint8(); - kbint = state_fio->FgetUint8(); - kbmsk = state_fio->FgetUint8(); - state_fio->Fread(table, sizeof(table), 1); + + state_fio->StateValue(last_cmd); + state_fio->StateValue(kbstat); + state_fio->StateValue(kbdata); + state_fio->StateValue(kbint); + state_fio->StateValue(kbmsk); + + state_fio->StateValue(nmi_status); + state_fio->StateValue(repeat_start_ms); + state_fio->StateValue(repeat_tick_ms); + state_fio->StateValue(enable_double_pressed_cursor); + state_fio->StateValue(device_order); + + state_fio->StateArray(table, sizeof(table), 1); + state_fio->StateValue(reserved_key_num); + state_fio->StateValue(key_count_phase); + state_fio->StateValue(special_boot_num); + + state_fio->StateArray(boot_code, sizeof(boot_code), 1); + state_fio->StateValue(boot_ptr); + state_fio->StateValue(boot_seq); + state_fio->StateValue(boot_code_ptr); + + state_fio->StateValue(event_keycode); + state_fio->StateValue(event_key_reset); + state_fio->StateValue(event_repeat); return true; } +} + diff --git a/source/src/vm/fmtowns/keyboard.h b/source/src/vm/fmtowns/keyboard.h index 47306a3ac..57664a2e0 100644 --- a/source/src/vm/fmtowns/keyboard.h +++ b/source/src/vm/fmtowns/keyboard.h @@ -14,72 +14,161 @@ #include "../vm.h" #include "../../emu.h" #include "../device.h" +#include "../../fifo.h" /* - Ђ炪/[} Ђ炪 - p/Sp p/Sp - ϊ ϊ - ϊ ϊ - / - J^Ji - Os PgUp - s PgDn - s F12 - F11 - COPY + BREAK Pause Break + ひらがな/ローマ字 ひらがな + 半角/全角 半角/全角 + 変換 変換 + 無変換 無変換 + かな/漢字 F11 + カタカナ F12 + 前行 PgUp + 次行 PgDn + 実行 Right WIN + 取消 Left WIN + 漢字 辞書 RALT + Print Screen + 単語 抹消 RALT + Scroll Lock + 単語 登録 RALT + Pause + COPY Print Screen + PF11 RALT + F1 + PF12 RALT + F2 + PF13 RALT + F3 + PF14 RALT + F4 + PF15 RALT + F5 + PF16 RALT + F6 + PF17 RALT + F7 + PF18 RALT + F8 + PF19 RALT + F9 + PF20 RALT + F10 + ALT LALT +*/ +namespace FMTOWNS { +/* + * From + * http://www.nurs.or.jp/~kurati/towns/scancode.html + * and http://m0115.web.fc2.com/fmr60kb212.jpg : + * TOWNS の ScanCode + +0 +1 +2 +3 +4 +5 +6 +7 +0x00 ESC 1 2 3 4 5 6 +0x08 7 8 9 0 - = \ 後退 +0x10 TAB Q W E R T Y U +0x18 I O P @ [ 改行 A S +0x20 D F G H J K L : +0x28 ; ] Z X C V B N +0x30 M , . / " 空白 [KP]* [KP]/ +0x38 [KP]+ [KP]- [KP]7 [KP]8 [KP]9 [KP]= [KP]4 [KP]5 +0x40 [KP]6 --- [KP]1 [KP]2 [KP]3 [KP]改行[KP]0 [KP]. +0x48 INS --- [KP]0 DEL --- ↑ HOME ← +0x50 ↓ → CTRL SHIFT --- CAPS LANG ALT +0x58 CTRL SPACE LANG F12 ALT F1 F2 F3 +0x60 F4 F5 F6 F7 F8 F9 F10 --- +0x68 --- F11 英字 辞書 抹消 登録 前行 --- +0x70 次行 半/全 END 実行 F13 F14 F15 F16 +0x78 F17 F18 F19 F20 */ - static const int key_table[256] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x10,0x00,0x00,0x00,0x1D,0x00,0x00, - 0x53,0x52,0x00,0x7C,0x55,0x52,0x00,0x00,0x00,0x71,0x00,0x01,0x58,0x57,0x00,0x00, - 0x35,0x6E,0x70,0x00,0x4E,0x4F,0x4D,0x51,0x50,0x00,0x00,0x00,0x00,0x48,0x4B,0x00, - 0x0B,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x1E,0x2E,0x2C,0x20,0x13,0x21,0x22,0x23,0x18,0x24,0x25,0x26,0x30,0x2F,0x19, - 0x1A,0x11,0x14,0x1F,0x15,0x17,0x2D,0x12,0x2B,0x16,0x2A,0x00,0x00,0x00,0x00,0x00, - 0x46,0x42,0x43,0x44,0x3E,0x3F,0x40,0x3A,0x3B,0x3C,0x36,0x38,0x00,0x39,0x47,0x37, - 0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x72,0x73,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x7D,0x6B,0x6C,0x6D,0x57,0x58,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,0x00,0x00,0x28,0x27,0x31,0x0C,0x32,0x33, - 0x28,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,0x1C,0x0E,0x29,0x0D,0x00, - 0x00,0x00,0x34,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 +/* VK -> RAW code table +8 */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x10,0x00,0x00,0x00,0x1D,0x00,0x00,/*0x*/ + 0x53,0x52,0x00,0x7C,0x55,0x56,0x00,0x00,0x00,0x71,0x00,0x01,0x58,0x57,0x00,0x00,/*1x*/ + 0x35,0x70,0x6E,0x00,0x4E,0x4F,0x4D,0x51,0x50,0x00,0x7D,0x00,0x00,0x48,0x4B,0x00,/*2x*/ + 0x0B,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,/*3x*/ + 0x00,0x1E,0x2E,0x2C,0x20,0x13,0x21,0x22,0x23,0x18,0x24,0x25,0x26,0x30,0x2F,0x19,/*4x*/ + 0x1A,0x11,0x14,0x1F,0x15,0x17,0x2D,0x12,0x2B,0x16,0x2A,0x72,0x73,0x00,0x00,0x00,/*5x*/ + 0x46,0x42,0x43,0x44,0x3E,0x3F,0x40,0x3A,0x3B,0x3C,0x36,0x38,0x00,0x39,0x47,0x37,/*6x*/ + 0x5D,0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x59,0x5a,0x74,0x75,0x76,0x77,/*7x*/ + 0x78,0x79,0x7A,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*8x*/ + 0x00,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*9x*/ + 0x00,0x00,0x00,0x00,0x5C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*ax*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x27,0x31,0x0C,0x32,0x33,/*bx*/ + 0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*cx*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x0E,0x29,0x0D,0x00,/*dx*/ + 0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*ex*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f /*fx*/ }; +} +#define SIG_KEYBOARD_BOOTSEQ_END 1 class FIFO; +namespace FMTOWNS { class KEYBOARD : public DEVICE { -private: - DEVICE* d_pic; +protected: + outputs_t output_intr_line; + outputs_t output_nmi_line; FIFO *key_buf; + FIFO *cmd_buf; + uint8_t kbstat, kbdata, kbint, kbmsk; + int repeat_start_ms; + int repeat_tick_ms; + bool enable_double_pressed_cursor; + bool device_order; + + bool nmi_status; uint8_t table[256]; + + uint8_t last_cmd; + + uint8_t boot_code[8]; + bool boot_seq; + int boot_code_ptr; + int boot_ptr; + int special_boot_num; + + int event_keycode; + int event_key_reset; + int event_repeat; + int reserved_key_num; + int key_count_phase; + virtual void do_common_command(uint8_t cmd); + void register_key_interrupt(bool first); + void enqueue_key(uint8_t code); + void enqueue_key2(uint8_t code); + void reset_device(); + void key_down2(int code); + void key_up2(int code); + public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {} + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + key_buf = NULL; + cmd_buf = NULL; + + initialize_output_signals(&output_intr_line); + initialize_output_signals(&output_nmi_line); + set_device_name(_T("FM-Towns Keyboard (JIS)")); + } ~KEYBOARD() {} // common functions void initialize(); void release(); void reset(); - void write_io8(uint32_t addr, uint32_t data); - uint32_t read_io8(uint32_t addr); - void event_frame(); - void save_state(FILEIO* state_fio); - bool load_state(FILEIO* state_fio); + void special_reset(int num); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + + void __FASTCALL event_callback(int event_id, int err); + bool process_state(FILEIO* state_fio, bool loading); // unique functions - void set_context_pic(DEVICE* device) + void set_context_intr_line(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&output_intr_line, dev, id, mask); + } + void set_context_nmi_line(DEVICE* dev, int id, uint32_t mask) { - d_pic = device; + register_output_signal(&output_nmi_line, dev, id, mask); } void key_down(int code); void key_up(int code); }; +} #endif diff --git a/source/src/vm/fmtowns/msdosrom.cpp b/source/src/vm/fmtowns/msdosrom.cpp index a41d7b4ea..24b7387e1 100644 --- a/source/src/vm/fmtowns/msdosrom.cpp +++ b/source/src/vm/fmtowns/msdosrom.cpp @@ -6,7 +6,7 @@ [MSDOS ROM] */ - +#include "../../fileio.h" #include "./msdosrom.h" namespace FMTOWNS { @@ -14,7 +14,7 @@ namespace FMTOWNS { void MSDOSROM::initialize() { memset(rom, 0xff, sizeof(rom)); - FILEIO *fio; + FILEIO *fio = new FILEIO(); if(fio->Fopen(create_local_path(_T("FMT_DOS.ROM")), FILEIO_READ_BINARY)) { // MSDOS fio->Fread(rom, sizeof(rom), 1); fio->Fclose(); @@ -22,11 +22,13 @@ void MSDOSROM::initialize() delete fio; } -uint32_t MSDOSROM::read_data8(uint32_t addr) +uint32_t MSDOSROM::read_memory_mapped_io8(uint32_t addr) { uint8_t d = 0xff; if((addr >= 0xc2000000) && (addr < 0xc2080000)) { d = rom[addr & 0x7ffff]; + } else if((addr >= 0x000b0000) && (addr < 0x000c0000)) { + d = rom[addr & 0x0ffff]; } return (uint32_t)d; } diff --git a/source/src/vm/fmtowns/msdosrom.h b/source/src/vm/fmtowns/msdosrom.h index c4011371b..dce35dfd9 100644 --- a/source/src/vm/fmtowns/msdosrom.h +++ b/source/src/vm/fmtowns/msdosrom.h @@ -17,13 +17,13 @@ class MSDOSROM : public DEVICE private: uint8_t rom[0x80000]; // 0xc2000000 - 0xc207ffff public: - MSDOSROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + MSDOSROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MSDOS ROM")); } ~MSDOSROM() {} void initialize(); - uint32_t read_data8(uint32_t addr); + uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); }; } diff --git a/source/src/vm/fmtowns/rf5c68.cpp b/source/src/vm/fmtowns/rf5c68.cpp index 2c6a998d0..952c3818e 100644 --- a/source/src/vm/fmtowns/rf5c68.cpp +++ b/source/src/vm/fmtowns/rf5c68.cpp @@ -7,35 +7,39 @@ #include "../../common.h" #include "./rf5c68.h" - -#define EVENT_DAC_SAMPLE 1 +#include "../debugger.h" void RF5C68::initialize() { // DAC memset(wave_memory, 0x00, sizeof(wave_memory)); - - - dac_on = false; dac_bank = 0; dac_ch = 0; for(int i = 0; i < 8; i++) { dac_addr_st[i].d = 0x00; - dac_env[i] = 0x0000000; - dac_lpan[i] = 0x000000f; - dac_rpan[i] = 0x000000f; - dac_tmpval_l[i] = 0x00000000; - dac_tmpval_r[i] = 0x00000000; + dac_env[i] = 0x0000080; + dac_pan[(i << 1) + 0] = 0x000000f; + dac_pan[(i << 1) + 1] = 0x000000f; dac_ls[i].d = 0x0000; dac_fd[i].d = 0x0000; dac_onoff[i] = false; dac_addr[i] = 0x00000000; - dac_force_load[i] = true; + dac_force_load[i] = false; } - dac_on = false; dac_bank = 0; dac_ch = 0; + sample_buffer = NULL; + if(d_debugger != NULL) { + d_debugger->set_device_name(_T("Debugger (RICOH RF5C68)")); + d_debugger->set_context_mem(this); + d_debugger->set_context_io(vm->dummy); + } +} +void RF5C68::release() +{ + if(sample_buffer != NULL) free(sample_buffer); + sample_buffer = NULL; } void RF5C68::reset() @@ -43,31 +47,33 @@ void RF5C68::reset() is_mute = true; // OK? for(int i = 0; i < 8; i++) { dac_addr_st[i].d = 0x00; - dac_env[i] = 0x0000000; - dac_lpan[i] = 0x000000f; - dac_rpan[i] = 0x000000f; - dac_tmpval_l[i] = 0x00000000; - dac_tmpval_r[i] = 0x00000000; + dac_env[i] = 0x0000080; + dac_pan[(i << 1) + 0] = 0x0000008; + dac_pan[(i << 1) + 1] = 0x0000008; dac_ls[i].d = 0x0000; dac_fd[i].d = 0x0000; dac_onoff[i] = false; dac_addr[i] = 0x00000000; - dac_force_load[i] = true; + dac_force_load[i] = false; + } + for(int i = 0; i < 16; i++) { + dac_tmpval[i] = 0x00000000; } if((sample_buffer != NULL) && (sample_length > 0)) { memset(sample_buffer, 0x00, sample_length * sizeof(int32_t) * 2); } - if(event_dac_sample != -1) { - cancel_event(this, event_dac_sample); - event_dac_sample = -1; - } + read_pointer = 0; + sample_pointer = 0; + sample_words = 0; + if(mix_rate > 0) { sample_tick_us = 1.0e6 / ((double)mix_rate); - register_event(this, EVENT_DAC_SAMPLE, sample_tick_us, true, &event_dac_sample); } else { sample_tick_us = 0; } - sample_count = 0; + mix_factor = (int)(dac_rate * 4096.0 / (double)mix_rate); + mix_count = 0; + dac_on = false; } uint32_t RF5C68::read_signal(int ch) @@ -87,10 +93,10 @@ uint32_t RF5C68::read_signal(int ch) return dac_env[local_ch]; break; case SIG_RF5C68_REG_LPAN: - return dac_lpan[local_ch]; + return dac_pan[(local_ch << 1) + 0]; break; case SIG_RF5C68_REG_RPAN: - return dac_rpan[local_ch]; + return dac_pan[(local_ch << 1) + 1]; break; case SIG_RF5C68_REG_LS: return dac_ls[local_ch].d; @@ -131,66 +137,95 @@ void RF5C68::write_signal(int ch, uint32_t data, uint32_t mask) { case SIG_RF5C68_DAC_PERIOD: if(dac_on) { + __DECL_ALIGNED(16) uint8_t tmpval[8] = {0}; +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + dac_tmpval[i] = 0; + } for(int ch = 0; ch < 8; ch++) { if(dac_onoff[ch]) { - uint32_t addr_old = (dac_addr[ch] & 0x7fffffff) >> 11; + uint32_t addr_old = (dac_addr[ch] >> 11) & 0xffff; uint32_t addr_new; + if((addr_old & 0x0fff) == 0x0fff) { + // Will beyond of boundary + write_signals(&interrupt_boundary, ((addr_old & 0xe000) >> 13) | 0x00000008); +// out_debug_log(_T("PCM INTERRUPT CH=%d ADDR=%04X"), ch, addr_old & 0xffff); + } + + int chd = ch << 1; + tmpval[ch] = wave_memory[addr_old & 0xffff]; + if(tmpval[ch] == 0xff) { + // Loop + dac_addr[ch] = ((uint32_t)(dac_ls[ch].w.l)) << 11; + addr_old = ((uint32_t)(dac_ls[ch].w.l)); + tmpval[ch] = wave_memory[addr_old & 0xffff]; + if(tmpval[ch] == 0xff) { + tmpval[ch] = 0x00; + dac_onoff[ch] = false; // STOP + continue; // This channel will stop + } + } dac_addr[ch] += dac_fd[ch].d; - dac_addr[ch] = dac_addr[ch] & 0x7fffffff; - addr_new = dac_addr[ch] >> 11; - if((addr_old != addr_new) || (dac_force_load[ch])) { - pair32_t tmpval; - tmpval.b.l = wave_memory[addr_new & 0xffff]; - if((addr_new & 0xf000) != (addr_old & 0xf000)) { // Boundary - if((addr_new & 0x1000) != 0) { - write_signals(&interrupt_boundary, ((addr_new & 0xe000) >> 13) | 0x00000008); - } - } - if(dac_force_load[ch]) { - dac_addr[ch] = (uint32_t)(dac_addr_st[ch].w.l) << 11; - addr_new = dac_addr[ch] >> 11; - tmpval.b.l = wave_memory[addr_new & 0xffff]; - } - dac_force_load[ch] = false; - - if(tmpval.b.l == 0xff) { - // Skip - dac_force_load[ch] = true; - // Q: Is clear data reg? - dac_tmpval_l[ch] = 0; - dac_tmpval_r[ch] = 0; - } else { // Normal OP - uint32_t sign = tmpval.d & 0x80; - uint32_t val = tmpval.d & 0x7f; - uint32_t lval, rval; - val = val * dac_env[ch]; - lval = val * dac_lpan[ch]; - rval = val * dac_rpan[ch]; - if(sign != 0) { // ADD - dac_tmpval_l[ch] += lval; - dac_tmpval_r[ch] += rval; - } else { // SUB - dac_tmpval_l[ch] -= lval; - dac_tmpval_r[ch] -= rval; - } - // Limiter - if(dac_tmpval_l[ch] >= (127 << 6)) { - dac_tmpval_l[ch] = 127 << 6; - } else if(dac_tmpval_l[ch] < -(127 << 6)) { - dac_tmpval_l[ch] = -(127 << 6); - } - if(dac_tmpval_r[ch] >= (127 << 6)) { - dac_tmpval_r[ch] = 127 << 6; - } else if(dac_tmpval_r[ch] < -(127 << 6)) { - dac_tmpval_r[ch] = -(127 << 6); - } - } +// dac_addr[ch] = dac_addr[ch] & ((1 << 28) - 1); + } + } + __DECL_ALIGNED(16) bool sign[16] = {false}; + __DECL_ALIGNED(16) int32_t val[16] = {0}; +__DECL_VECTORIZED_LOOP + for(int ch = 0; ch < 8; ch++) { + int chd = ch << 1; + sign[chd + 0] = (dac_onoff[ch]) ? ((tmpval[ch] & 0x80) == 0) : false; // 0 = minus + sign[chd + 1] = sign[chd + 0]; + val[chd + 0] = (dac_onoff[ch]) ? (tmpval[ch] & 0x7f) : 0; + val[chd + 1] = val[chd + 0]; + } + // VAL = VAL * ENV * PAN +__DECL_VECTORIZED_LOOP + for(int chd = 0; chd < 16; chd++) { + val[chd] = val[chd] * dac_env[chd >> 1]; + val[chd] = val[chd] * dac_pan[chd]; + } + // Sign +__DECL_VECTORIZED_LOOP + for(int chd = 0; chd < 16; chd++) { + dac_tmpval[chd] = (sign[chd]) ? -val[chd] : val[chd]; + } + // Re-Init sample buffer + if((sample_buffer != NULL) /*&& (sample_words < sample_length)*/){ + int32_t* np = &(sample_buffer[sample_pointer << 1]); + __DECL_ALIGNED(8) int32_t lr[2]; + for(int i = 0; i < 2; i++) { + lr[i] = 0; + } + // ADD or SUB +__DECL_VECTORIZED_LOOP + for(int chd = 0; chd < 16; chd++) { + lr[chd & 1] += dac_tmpval[chd]; + } +/* + static const int32_t uplimit = 127 << 6; + static const int32_t lowlimit = -(127 << 6); +__DECL_VECTORIZED_LOOP + for(int chd = 0; chd < 2; chd++) { + if(lr[chd] > uplimit) { + lr[chd] = uplimit; } - } else { - dac_tmpval_l[ch] = 0; - dac_tmpval_r[ch] = 0; + if(lr[chd] < lowlimit) { + lr[chd] = lowlimit; + } + lr[chd] >>= 2; + } +*/ +__DECL_VECTORIZED_LOOP + for(int chd = 0; chd < 2; chd++) { + lr[chd] >>= 2; } + np[0] = lr[0]; + np[1] = lr[1]; } + sample_pointer = (sample_pointer + 1) % sample_length; + sample_words++; + sample_words = (sample_words >= sample_length) ? sample_length : sample_words; } break; case SIG_RF5C68_CLEAR_INTR: @@ -200,7 +235,18 @@ void RF5C68::write_signal(int ch, uint32_t data, uint32_t mask) write_signals(&interrupt_boundary, 0x80000008); break; case SIG_RF5C68_MUTE: - is_mute = ((data & mask) != 0) ? true : false; + { + bool old_is_mute = is_mute; + is_mute = ((data & mask) != 0) ? true : false; + if((is_mute != old_is_mute) && !(is_mute)) { + sample_words = 0; + sample_pointer = 0; + read_pointer = 0; + if((sample_buffer != NULL) && (sample_length > 0)) { + memset(sample_buffer, 0x00, sizeof(int32_t) * 2 * sample_length); + } + } + } break; default: break; @@ -213,51 +259,83 @@ void RF5C68::write_io8(uint32_t addr, uint32_t data) switch(naddr) { case 0x00: // ENV dac_env[dac_ch] = data & 0xff; +// out_debug_log(_T("DAC REG 00 (ENV) CH=%d RAW=%02X"), +// dac_ch, data); break; case 0x01: // PAN - dac_lpan[dac_ch] = data & 0x0f; - dac_rpan[dac_ch] = (data & 0xf0) >> 4; + dac_pan[(dac_ch << 1) + 0] = data & 0x0f; + dac_pan[(dac_ch << 1) + 1] = (data & 0xf0) >> 4; +// out_debug_log(_T("DAC REG 01 (PAN) CH=%d L=%01X R=%01X"), +// dac_ch, data & 0x0f, (data & 0xf0) >> 4); break; case 0x02: // FDL dac_fd[dac_ch].b.l = data & 0xff; +// out_debug_log(_T("DAC REG 02 (FD LOW) CH=%d RAW=%02X"), +// dac_ch, data); break; case 0x03: // FDH dac_fd[dac_ch].b.h = data & 0xff; +// out_debug_log(_T("DAC REG 03 (FD HIGH) CH=%d RAW=%02X"), +// dac_ch, data); break; case 0x04: // LSL dac_ls[dac_ch].b.l = data & 0xff; +// out_debug_log(_T("DAC REG 04 (LS) CH=%d RAW=%02X"), +// dac_ch, data); break; case 0x05: // LSH dac_ls[dac_ch].b.h = data & 0xff; +// out_debug_log(_T("DAC REG 05 (ADDR STEP HIGH) CH=%d RAW=%02X"), +// dac_ch, data); break; case 0x06: // ST dac_addr_st[dac_ch].d = 0; dac_addr_st[dac_ch].b.h = data & 0xff; + dac_addr[dac_ch] = (uint32_t)(dac_addr_st[dac_ch].w.l) << 11; +// out_debug_log(_T("DAC REG 06 (ADDR STEP HIGH) CH=%d RAW=%02X"), +// dac_ch, data); break; case 0x07: // Control - dac_on = ((data & 0x80) != 0) ? true : false; - if((data & 0x40) != 0) { // CB2-0 - dac_ch = data & 0x07; - } else { // WB3-0 - dac_bank = ((data & 0x0cf) << 12); + { + bool old_dac_on = dac_on; + dac_on = ((data & 0x80) != 0) ? true : false; + if((data & 0x40) != 0) { // CB2-0 + dac_ch = data & 0x07; + } else { // WB3-0 + dac_bank = ((data & 0x0f) << 12); + } + if((dac_on != old_dac_on) && !(dac_on)) { + sample_pointer = 0; + sample_words = 0; + read_pointer = 0; + if((sample_buffer != NULL) && (sample_length > 0)) { + memset(sample_buffer, 0x00, sizeof(int32_t) * 2 * sample_length); + } + } } +// out_debug_log(_T("DAC REG 07 RAW=%02X ON=%s CH=%d BANK=%04X"), +// data, +// (dac_on) ? _T("ON ") :_T("OFF"), +// dac_ch, dac_bank); break; case 0x08: // ON/OFF per CH { uint32_t mask = 0x01; for(int i = 0; i < 8; i++) { bool onoff = dac_onoff[i]; - if((mask & data) != 0) { + if((mask & data) == 0) { dac_onoff[i] = true; } else { dac_onoff[i] = false; } - if(onoff != dac_onoff[i]) { - dac_force_load[i] = true; + if(!(onoff) && (dac_onoff[i])) { // Force reload + dac_addr[i] = (uint32_t)(dac_addr_st[i].w.l) << 11; } + mask <<= 1; } - mask <<= 1; } +// out_debug_log(_T("DAC REG 08 (DAC/ONOFF) RAW=%02X"), +// data); break; default: break; @@ -270,74 +348,201 @@ uint32_t RF5C68::read_io8(uint32_t addr) } // Read PCM memory -uint32_t RF5C68::read_data8(uint32_t addr) +uint32_t RF5C68::read_memory_mapped_io8(uint32_t addr) +{ + addr = (addr & 0xfff) | dac_bank; + if(d_debugger != NULL && d_debugger->now_device_debugging) { + return d_debugger->read_via_debugger_data8(addr); + } else { + if(dac_on) { + return 0xff; + } + return read_via_debugger_data8(addr); + } + return 0xff; +} + +uint32_t RF5C68::read_memory_mapped_io16(uint32_t addr) { - if(dac_on) { - return 0xff; + addr = (addr & 0xfff) | dac_bank; + if(d_debugger != NULL && d_debugger->now_device_debugging) { + return d_debugger->read_via_debugger_data16(addr); + } else { + if(dac_on) { + return 0xffff; + } + return read_via_debugger_data16(addr); } - // dac_off - return wave_memory[(addr & 0x0fff) | dac_bank]; + return 0xffff; } -void RF5C68::write_data8(uint32_t addr, uint32_t data) +void RF5C68::write_memory_mapped_io8(uint32_t addr, uint32_t data) { + addr = (addr & 0xfff) | dac_bank; // if(dac_on) don't write <- Is correct? - if(!dac_on) { - wave_memory[(addr & 0x0fff) | dac_bank] = (uint8_t)data; + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data8(addr, data); + } else { +// if(!dac_on) { + write_via_debugger_data8(addr, data); +// return; +// } } } +void RF5C68::write_memory_mapped_io16(uint32_t addr, uint32_t data) +{ + addr = (addr & 0xfff) | dac_bank; + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data16(addr, data); + } else { +// if(!dac_on) { + write_via_debugger_data16(addr, data); +// return; +// } + } +} + void RF5C68::set_volume(int ch, int decibel_l, int decibel_r) { - volume_l = decibel_to_volume(decibel_l); - volume_r = decibel_to_volume(decibel_r); + volume_l = decibel_to_volume(decibel_l - 4); + volume_r = decibel_to_volume(decibel_r - 4); } -void RF5C68::event_callback(int id, int err) + +void RF5C68::get_sample(int32_t *v, int words) { - if(id == EVENT_DAC_SAMPLE) { - int32_t lval, rval; - lval = 0; - rval = 0; - if(sample_count < sample_length) { - if(dac_on) { - for(int ch = 0; ch < 8; ch++) { - if(dac_onoff[ch]) { - lval = lval + (dac_tmpval_l[ch] << 0); - rval = rval + (dac_tmpval_r[ch] << 0); - } - } + if(words > sample_words) words = sample_words; + if(words <= 0) return; + if(v == NULL) return; + switch(words) { + case 1: + v[2] = sample_buffer[(read_pointer << 1) + 0]; + v[3] = sample_buffer[(read_pointer << 1) + 1]; + break; + default: + { + int nptr = read_pointer - words + 1; + int nwords = words << 1; + if(nptr < 0) nptr = read_pointer + sample_length - words; + for(int i = 0; i < nwords; i += 2) { + v[i + 0] = sample_buffer[(nptr << 1) + 0]; + v[i + 1] = sample_buffer[(nptr << 1) + 1]; + nptr = (nptr + 1) % sample_length; } - sample_buffer[sample_count << 1] = lval; - sample_buffer[(sample_count << 1) + 1] = rval; - sample_count++; } - } + break; + } +} + +void RF5C68::lpf_threetap(int32_t *v, int &lval, int &rval) +{ + if(v == NULL) return ; + static const int fact2 = 1800; + static const int fact0 = 450; + static const int fact4 = 4096 - (fact2 + fact0); + lval = (v[4] * fact4 + v[2] * fact2 + v[0] * fact0) >> 12; + rval = (v[5] * fact4 + v[3] * fact2 + v[1] * fact0) >> 12; } void RF5C68::mix(int32_t* buffer, int cnt) { - int32_t lval, rval; + int32_t lval, rval = 0; + int32_t lval2, rval2 = 0; // ToDo: supress pop noise. - if(sample_length < cnt) cnt = sample_length; - if(sample_length < sample_count) sample_count = sample_length; if(cnt <= 0) return; if(is_mute) return; - if(sample_buffer != NULL) { - for(int i = 0; i < (cnt << 1); i += 2) { - // ToDo: interpoolate. - buffer[i] += apply_volume(sample_buffer[i], volume_l); - buffer[i + 1] += apply_volume(sample_buffer[i + 1], volume_r); - } - if(sample_count > cnt) { - sample_count -= cnt; - memcpy(&(sample_buffer[0]), &(sample_buffer[cnt * 2]), sample_count * sizeof(int32_t) * 2); - memset(&(sample_buffer[cnt * 2]), 0x00, (sample_length - sample_count) * sizeof(int32_t) * 2); - } else { - memset(&(sample_buffer[0]), 0x00, sample_length * sizeof(int32_t) * 2); - sample_count = 0; + if((sample_buffer != NULL) && (sample_length > 0)) { + __DECL_ALIGNED(16) int32_t val[16] = {0}; // 0,1 : before / 2,3 : after + // ToDo: mix_freq <= dac_freq ; mix_factor >= 4096. + if(mix_factor < 4096) { + get_sample(val, 3); + lpf_threetap(val, lval, rval); + for(int i = 0; i < (cnt << 1); i += 2) { + int32_t interp_p = mix_count; + int32_t interp_n = 4096 - mix_count; + lval2 = (interp_p * (val[4] - lval)) >> 12; + rval2 = (interp_p * (val[5] - rval)) >> 12; + lval2 = lval + lval2; + rval2 = rval + rval2; + lval2 = apply_volume(lval2, volume_l) >> 1; + rval2 = apply_volume(rval2, volume_r) >> 1; + // ToDo: interpoolate. + buffer[i] += lval2; + buffer[i + 1] += rval2; + mix_count += mix_factor; + if(mix_count >= 4096) { +// out_debug_log(_T("MIX COUNT=%d FACTOR=%d"), mix_count, mix_factor); + int n = mix_count >> 12; + int old_rptr = read_pointer; + read_pointer += n; + if((old_rptr < sample_pointer) && (read_pointer >= sample_pointer)) { + // Overshoot read opinter + read_pointer = sample_pointer - 1; + if(read_pointer < 0) read_pointer = sample_length - 1; + if(read_pointer <= 0) read_pointer = 0; + } else if((old_rptr >= sample_pointer)) { + if(old_rptr < (sample_pointer + sample_length - sample_words)) { + read_pointer = (sample_pointer + sample_length - sample_words); + } + } + read_pointer = read_pointer % sample_length; + if(sample_words > 0) { + // Reload data + memset(val, 0x00, sizeof(val)); + get_sample(val, 3); + } else { + val[0] = val[2]; + val[1] = val[3]; + val[2] = 0; + val[3] = 0; + } + lpf_threetap(val, lval, rval); +// if(sample_words < 0) sample_words = 0; + mix_count -= (n << 12); + } + } + } else if(mix_factor == 4096) { + // ToDo: Interpoolate + get_sample(val, 4); + lpf_threetap(val, lval, rval); + for(int i = 0; i < (cnt << 1); i += 2) { + lval2 = apply_volume(lval, volume_l) >> 1; + rval2 = apply_volume(rval, volume_r) >> 1; + buffer[i] += lval2; + buffer[i + 1] += rval2; + read_pointer = (read_pointer + 1) % sample_length; + get_sample(val, 4); + lpf_threetap(val, lval, rval); + } + } else { // MIX_FACTOR > 1.0 + // ToDo: Correct downsampling. + get_sample(val, 8); + lpf_threetap(val, lval, rval); + for(int i = 0; i < (cnt << 1); i += 2) { + lval2 = apply_volume(lval, volume_l) >> 1; + rval2 = apply_volume(rval, volume_r) >> 1; + buffer[i] += lval2; + buffer[i + 1] += rval2; + + int n = mix_count >> 12; + read_pointer += n; + read_pointer = read_pointer % sample_length; + if(sample_words > 0) { + // Reload data + memset(val, 0x00, sizeof(val)); + get_sample(val, 8); + } else { + val[0] = val[2]; + val[1] = val[3]; + val[2] = 0; + val[3] = 0; + } + mix_count -= (n << 12); + lpf_threetap(val, lval, rval); + } } } } @@ -347,35 +552,88 @@ void RF5C68::initialize_sound(int sample_rate, int samples) if((sample_rate > 0) && (samples > 0)) { mix_rate = sample_rate; sample_length = samples; - if(sample_buffer != NULL) { - free(sample_buffer); - } + mix_factor = (int)(dac_rate * 4096.0 / (double)mix_rate); + mix_count = 0; + read_pointer = 0; + sample_pointer = 0; + sample_words = 0; + + if(sample_buffer != NULL) free(sample_buffer); sample_buffer = (int32_t*)malloc(sample_length * sizeof(int32_t) * 2); if(sample_buffer != NULL) { memset(sample_buffer, 0x00, sample_length * sizeof(int32_t) * 2); } - if(event_dac_sample != -1) { - cancel_event(this, event_dac_sample); - event_dac_sample = -1; - } - if(mix_rate > 0) { - sample_tick_us = 1.0e6 / ((double)mix_rate); - register_event(this, EVENT_DAC_SAMPLE, sample_tick_us, true, &event_dac_sample); - } + sample_tick_us = 1.0e6 / ((double)mix_rate); } else { if(sample_buffer != NULL) { free(sample_buffer); } sample_buffer = NULL; sample_length = 0; - mix_rate = 0; - if(event_dac_sample != -1) { - cancel_event(this, event_dac_sample); - event_dac_sample = -1; - } + mix_rate = 1; sample_tick_us = 0.0; } - sample_count = 0; +} + +void RF5C68::write_debug_data8(uint32_t addr, uint32_t data) +{ + wave_memory[addr & 0xffff] = data; +} + +uint32_t RF5C68::read_debug_data8(uint32_t addr) +{ + return wave_memory[addr & 0xffff]; +} + +void RF5C68::write_via_debugger_data8(uint32_t addr, uint32_t data) +{ + wave_memory[addr] = data; +} + +void RF5C68::write_via_debugger_data16(uint32_t addr, uint32_t data) +{ + pair32_t _b; + _b.d = data; + wave_memory[addr + 0] = _b.b.l; + wave_memory[(addr + 1) & 0xffff] = _b.b.h; +} + + +uint32_t RF5C68::read_via_debugger_data8(uint32_t addr) +{ + return wave_memory[addr]; +} + +uint32_t RF5C68::read_via_debugger_data16(uint32_t addr) +{ + pair16_t _b; + _b.b.l = wave_memory[addr + 0]; + _b.b.h = wave_memory[(addr + 1) & 0xffff]; + return _b.w; +} + +bool RF5C68::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + _TCHAR sbuf[8][512] = {0}; + _TCHAR sbuf2[4096] = {0}; + for(int i = 0; i < 8; i++) { + my_stprintf_s(sbuf[i], sizeof(sbuf[i]), + _T("CH%d: %s: ENV=%02X LPAN=%02X RPAN=%02X FD=%04X LS=%04X ADDR=%08X ADDR_ST=%08X\n") + , i, (dac_onoff[i]) ? _T("ON ") : _T("OFF") + , dac_env[i], dac_pan[(i << 1) + 0], dac_pan[(i << 1) + 1] + , dac_fd[i].w.l, dac_ls[i].w.l + , dac_addr[i], dac_addr_st[i].w.l + ); + } + for(int i = 0; i < 8; i++) { + my_tcscat_s(sbuf2, sizeof(sbuf2), sbuf[i]); + } + my_stprintf_s(buffer, buffer_len, + _T("DAC %s BANK=%01X CH=%d MUTE=%s\n") + _T("%s") + , (dac_on) ? _T("ON ") : _T("OFF"), dac_bank, dac_ch, (is_mute) ? _T("ON ") : _T("OFF") + , sbuf2); + return true; } #define STATE_VERSION 1 @@ -391,36 +649,56 @@ bool RF5C68::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(dac_on); state_fio->StateValue(dac_bank); state_fio->StateValue(dac_ch); - state_fio->StateValue(dac_on); state_fio->StateValue(is_mute); state_fio->StateArray(dac_onoff, sizeof(dac_onoff), 1); state_fio->StateArray(dac_addr_st, sizeof(dac_addr_st), 1); state_fio->StateArray(dac_addr, sizeof(dac_addr), 1); state_fio->StateArray(dac_env, sizeof(dac_env), 1); - state_fio->StateArray(dac_lpan, sizeof(dac_lpan), 1); - state_fio->StateArray(dac_rpan, sizeof(dac_rpan), 1); + state_fio->StateArray(dac_pan, sizeof(dac_pan), 1); state_fio->StateArray(dac_ls, sizeof(dac_ls), 1); state_fio->StateArray(dac_fd, sizeof(dac_fd), 1); state_fio->StateArray(dac_force_load, sizeof(dac_force_load), 1); - state_fio->StateArray(dac_tmpval_l, sizeof(dac_tmpval_l), 1); - state_fio->StateArray(dac_tmpval_r, sizeof(dac_tmpval_r), 1); + state_fio->StateArray(dac_tmpval, sizeof(dac_tmpval), 1); + +// state_fio->StateValue(sample_words); +// state_fio->StateValue(sample_pointer); +// state_fio->StateValue(read_pointer); +// int sample_length_old = sample_length; +// state_fio->StateValue(sample_length); + +// state_fio->StateValue(mix_factor); +// state_fio->StateValue(mix_count); + state_fio->StateValue(dac_rate); state_fio->StateArray(wave_memory, sizeof(wave_memory), 1); - state_fio->StateValue(event_dac_sample); + // ToDo: Save/Load sample_buffer. // Post Process if(loading) { - if(event_dac_sample != -1) { - cancel_event(this, event_dac_sample); - event_dac_sample = -1; - } + // ToDo: load sample_length & sample_buffer. if(mix_rate > 0) { sample_tick_us = 1.0e6 / ((double)mix_rate); - register_event(this, EVENT_DAC_SAMPLE, sample_tick_us, true, &event_dac_sample); + mix_factor = (int)(dac_rate * 4096.0 / (double)mix_rate); + mix_count = 0; } else { sample_tick_us = 0; + mix_count = 0; + mix_factor = 0; + } + read_pointer = 0; + sample_pointer = 0; + sample_words = 0; + + if(sample_buffer != NULL) free(sample_buffer); + sample_buffer = NULL; + if(sample_length > 0) { + sample_buffer = (int32_t*)malloc(sample_length * sizeof(int32_t) * 2); + if(sample_buffer != NULL) { + memset(sample_buffer, 0x00, sample_length * sizeof(int32_t) * 2); + } } - sample_count = 0; + } else { // Saving + // ToDo: save sample_length & sample_buffer. } return true; } diff --git a/source/src/vm/fmtowns/rf5c68.h b/source/src/vm/fmtowns/rf5c68.h index 4986553f2..ca2c2529f 100644 --- a/source/src/vm/fmtowns/rf5c68.h +++ b/source/src/vm/fmtowns/rf5c68.h @@ -30,76 +30,127 @@ #define SIG_RF5C68_REG_FD 0x58 #define SIG_RF5C68_FORCE_LOAD 0x60 +class DEBUGGER; class RF5C68 : public DEVICE { protected: + DEBUGGER *d_debugger; outputs_t interrupt_boundary; // DAC uint8_t wave_memory[0x10000]; // DAC REGISTERS bool dac_on; - uint8_t dac_bank; + uint16_t dac_bank; uint8_t dac_ch; bool is_mute; + + double dac_rate; + int mix_factor; + int mix_count; + int sample_words; + int sample_pointer; + int read_pointer; - bool dac_onoff[8]; - pair32_t dac_addr_st[8]; - uint32_t dac_addr[8]; - uint32_t dac_env[8]; - uint32_t dac_lpan[8]; - uint32_t dac_rpan[8]; - pair32_t dac_ls[8]; - pair32_t dac_fd[8]; + __DECL_ALIGNED(16) bool dac_onoff[8]; + __DECL_ALIGNED(16) pair32_t dac_addr_st[8]; + __DECL_ALIGNED(16) uint32_t dac_addr[8]; + __DECL_ALIGNED(16) uint32_t dac_env[8]; + __DECL_ALIGNED(16) uint32_t dac_pan[16]; + __DECL_ALIGNED(16) pair32_t dac_ls[8]; + __DECL_ALIGNED(16) pair32_t dac_fd[8]; // TMP Values bool dac_force_load[8]; - int32_t dac_tmpval_l[8]; - int32_t dac_tmpval_r[8]; + __DECL_ALIGNED(16) int32_t dac_tmpval[16]; int volume_l, volume_r; int32_t* sample_buffer; - int event_dac_sample; int sample_length; - int sample_count; int mix_rate; double sample_tick_us; + + // ToDo: Work correct LPF. + + void __FASTCALL get_sample(int32_t *v, int words); + void __FASTCALL lpf_threetap(int32_t *v, int &lval, int &rval); + public: - RF5C68(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RF5C68(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; sample_buffer = NULL; sample_length = 0; - sample_count = 0; - mix_rate = 0; - event_dac_sample = -1; + mix_rate = 1; // For Error sample_tick_us = 0.0; is_mute = true; initialize_output_signals(&interrupt_boundary); + d_debugger = NULL; + + dac_rate = 8.0e6 / 384; set_device_name(_T("ADPCM RF5C68")); } ~RF5C68() {} void initialize(); + void release(); void reset(); - uint32_t read_data8(uint32_t addr); - void write_data8(uint32_t addr, uint32_t data); - uint32_t read_io8(uint32_t addr); - void write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr); + void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data); - uint32_t read_signal(int ch); - void write_signal(int ch, uint32_t data, uint32_t mask); - - void event_callback(int id, int err); + uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + + uint32_t __FASTCALL read_io8(uint32_t addr); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); - void mix(int32_t* buffer, int cnt); + uint32_t __FASTCALL read_signal(int ch); + void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); + + void __FASTCALL mix(int32_t* buffer, int cnt); void initialize_sound(int sample_rate, int samples); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); + + virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + void __FASTCALL write_via_debugger_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_via_debugger_data8(uint32_t addr); + void __FASTCALL write_via_debugger_data16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_via_debugger_data16(uint32_t addr); + + void set_dac_rate(double freq) + { + dac_rate = freq; + sample_words = 0; + sample_pointer = 0; + mix_factor = (int)(dac_rate * 4096.0 / (double)mix_rate); + mix_count = 0; + if((sample_buffer != NULL) && (sample_length > 0)) { + memset(sample_buffer, 0x00, sample_length * sizeof(int32_t) * 2); + } + } + void *get_debugger() + { + return d_debugger; + } + bool is_debugger_available() + { + return ((d_debugger != NULL) ? true : false); + } + void set_context_debugger(DEBUGGER* device) + { + d_debugger = device; + } + virtual uint32_t get_debug_data_addr_mask() + { + return 0xffff; + } void set_context_interrupt_boundary(DEVICE* device, int id, uint32_t mask) { diff --git a/source/src/vm/fmtowns/scsi.cpp b/source/src/vm/fmtowns/scsi.cpp index 7d07d17f8..2e342ba98 100644 --- a/source/src/vm/fmtowns/scsi.cpp +++ b/source/src/vm/fmtowns/scsi.cpp @@ -11,8 +11,9 @@ #include "scsi.h" #include "../i8259.h" #include "../scsi_host.h" -#include "../upd71071.h" +#include "./towns_dmac.h" +#undef _SCSI_DEBUG_LOG // control register #define CTRL_WEN 0x80 #define CTRL_IMSK 0x40 @@ -29,36 +30,53 @@ #define STATUS_INT 0x02 #define STATUS_PERR 0x01 +namespace FMTOWNS { + void SCSI::reset() { ctrl_reg = CTRL_IMSK; irq_status = false; + irq_status_bak = false; + exirq_status = false; + ex_int_enable = false; + dma_enabled = true; } void SCSI::write_io8(uint32_t addr, uint32_t data) { +// out_debug_log(_T("Write I/O %04X %02X"), addr, data); switch(addr & 0xffff) { - case 0xc30: + case 0x0c30: // data register #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SCSI] out %04X %02X\n"), addr, data); #endif +// d_host->write_signal(SIG_SCSI_REQ, 0, 0); if(ctrl_reg & CTRL_WEN) { +// if((ctrl_reg & CTRL_WEN) && !(ctrl_reg & CTRL_DMAE)) { d_host->write_dma_io8(addr, data); } break; - case 0xc32: + case 0x0c32: // control register #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SCSI] out %04X %02X\n"), addr, data); #endif - ctrl_reg = data; +// ctrl_reg = data; +// if((data & CTRL_DMAE) != 0) dma_enabled = true; + if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX + ex_int_enable = ((data & 0x20) != 0) ? true : false; + // Set host to 16bit bus width. BIT3 ,= '1'. + } if(ctrl_reg & CTRL_WEN) { d_host->write_signal(SIG_SCSI_RST, data, CTRL_RST); - d_host->write_signal(SIG_SCSI_SEL, data, CTRL_SEL); d_host->write_signal(SIG_SCSI_ATN, data, CTRL_ATN); + d_host->write_signal(SIG_SCSI_SEL, data, CTRL_SEL); + d_host->write_signal(SIG_SCSI_HOST_DMAE, data, CTRL_DMAE); } + ctrl_reg = data; + if((data & CTRL_DMAE) != 0) dma_enabled = true; break; } } @@ -68,71 +86,120 @@ uint32_t SCSI::read_io8(uint32_t addr) uint32_t value = 0; switch(addr & 0xffff) { - case 0xc30: + case 0x0034: + if(machine_id >= 0x0600) { // After UG + value = 0x7f; // Ready to transfer 16bit width DMA, excepts CX/UX. + } else { + value = 0xff; + } + break; + case 0x0c30: // data register +// d_host->write_signal(SIG_SCSI_REQ, 0, 0); +// if((ctrl_reg & CTRL_WEN) && !(ctrl_reg & CTRL_DMAE)) { if(ctrl_reg & CTRL_WEN) { value = d_host->read_dma_io8(addr); } #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SCSI] in %04X %02X\n"), addr, value); #endif - return value; - - case 0xc32: +// return value; + break; + case 0x0c32: // status register value = (d_host->read_signal(SIG_SCSI_REQ) ? STATUS_REQ : 0) | (d_host->read_signal(SIG_SCSI_IO ) ? STATUS_IO : 0) | (d_host->read_signal(SIG_SCSI_MSG) ? STATUS_MSG : 0) | - (d_host->read_signal(SIG_SCSI_CD ) ? STATUS_CD : 0) | - (d_host->read_signal(SIG_SCSI_BSY) ? STATUS_BSY : 0) | + (d_host->read_signal(SIG_SCSI_CD ) ? STATUS_CD : 0) | + (d_host->read_signal(SIG_SCSI_BSY) ? STATUS_BSY : 0) | (irq_status ? STATUS_INT : 0); + if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX + value = value | 0x00; + } else { + value = value | 0x04; // Disable EX-Int. + } #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SCSI] in %04X %02X\n"), addr, value); #endif - return value; +// irq_status = false; +// return value; + break; + case 0xc34: + // From MAME 0.216 + // Linux uses this port to detect the ability to do word transfers. We'll tell it that it doesn't for now. + value = 0x80; + break; } - return 0xff; +// out_debug_log(_T("[SCSI] READ I/O %04X %02X\n"), addr, value); + return value; } void SCSI::write_signal(int id, uint32_t data, uint32_t mask) { switch(id) { case SIG_SCSI_IRQ: - if(ctrl_reg & CTRL_IMSK) { - d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR0, data, mask); + if((ctrl_reg & CTRL_IMSK)) { +// if(irq_status_bak != ((data & mask) != 0)) { + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR0, data, mask); + //out_debug_log(_T("[SCSI] IRQ %04X %02X\n"), data, mask); +// } + irq_status_bak = ((data & mask) != 0); + } + if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX + if(!(exirq_status)) { + irq_status = ((data & mask) != 0); + } else { + irq_status = true; + } + } else { + irq_status = ((data & mask) != 0); } - irq_status = ((data & mask) != 0); break; case SIG_SCSI_DRQ: - if(ctrl_reg & CTRL_DMAE) { + if(((ctrl_reg & CTRL_DMAE) != 0) /*&& (dma_enabled)*/) { d_dma->write_signal(SIG_UPD71071_CH1, data, mask); } +/* if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX + if(ex_int_enable) { + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR0, data, mask); + exirq_status = ((data & mask) != 0); + if(exirq_status) { + irq_status = true; + } else if(!(irq_status_bak)) { + irq_status = false; + } + } + }*/ + break; + case SIG_SCSI_EOT: + dma_enabled = ((data & mask) == 0) ? true : false; break; } } -#define STATE_VERSION 1 - -void SCSI::save_state(FILEIO* state_fio) -{ - state_fio->FputUint32(STATE_VERSION); - state_fio->FputInt32(this_device_id); - - state_fio->FputUint8(ctrl_reg); - state_fio->FputBool(irq_status); -} +#define STATE_VERSION 4 -bool SCSI::load_state(FILEIO* state_fio) +bool SCSI::process_state(FILEIO* state_fio, bool loading) { - if(state_fio->FgetUint32() != STATE_VERSION) { + if(!state_fio->StateCheckUint32(STATE_VERSION)) { return false; } - if(state_fio->FgetInt32() != this_device_id) { + if(!state_fio->StateCheckInt32(this_device_id)) { return false; } - ctrl_reg = state_fio->FgetUint8(); - irq_status = state_fio->FgetBool(); + state_fio->StateValue(machine_id); + state_fio->StateValue(cpu_id); + + state_fio->StateValue(ctrl_reg); + state_fio->StateValue(irq_status); + state_fio->StateValue(irq_status_bak); + state_fio->StateValue(dma_enabled); + + if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX + state_fio->StateValue(ex_int_enable); + state_fio->StateValue(exirq_status); + } return true; } - +} diff --git a/source/src/vm/fmtowns/scsi.h b/source/src/vm/fmtowns/scsi.h index 3f27b110a..139a64deb 100644 --- a/source/src/vm/fmtowns/scsi.h +++ b/source/src/vm/fmtowns/scsi.h @@ -15,9 +15,12 @@ #include "../../emu.h" #include "../device.h" -#define SIG_SCSI_IRQ 0 -#define SIG_SCSI_DRQ 1 +#define SIG_SCSI_IRQ 0 +#define SIG_SCSI_DRQ 1 +#define SIG_SCSI_16BIT_TRANSFER 2 +#define SIG_SCSI_EOT 3 +namespace FMTOWNS { class SCSI : public DEVICE { private: @@ -25,18 +28,25 @@ class SCSI : public DEVICE uint8_t ctrl_reg; bool irq_status; + bool irq_status_bak; + bool exirq_status; + bool ex_int_enable; + bool dma_enabled; + + uint16_t machine_id; + uint8_t cpu_id; public: - SCSI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { - set_device_name(_T("FMR50 SCSI")); + SCSI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { + set_device_name(_T("FM Towns SCSI")); } ~SCSI() {} // common functions void reset(); - void write_io8(uint32_t addr, uint32_t data); - uint32_t read_io8(uint32_t addr); - void write_signal(int id, uint32_t data, uint32_t mask); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); // unique functions void set_context_dma(DEVICE* device) @@ -51,9 +61,17 @@ class SCSI : public DEVICE { d_host = device; } - void save_state(FILEIO* state_fio); - bool load_state(FILEIO* state_fio); + void set_machine_id(uint16_t val) + { + machine_id = val & 0xfff8; + } + void set_cpu_id(uint16_t val) + { + cpu_id = val & 0x07; + } + bool process_state(FILEIO* state_fio, bool loading); }; +} #endif diff --git a/source/src/vm/fmtowns/serialrom.cpp b/source/src/vm/fmtowns/serialrom.cpp index c327bed0e..899a6d4fc 100644 --- a/source/src/vm/fmtowns/serialrom.cpp +++ b/source/src/vm/fmtowns/serialrom.cpp @@ -8,12 +8,19 @@ */ #include "../../fileio.h" -#include "./towns_memory.h" #include "./serialrom.h" -#include "../i386.h" namespace FMTOWNS { - + + +uint8_t SERIAL_ROM::read_rom_bits(uint8_t pos) +{ + uint8_t bytepos = 31 - (pos >> 3); + uint8_t bit = 1 << (pos & 7); + uint8_t val = ((rom[bytepos] & bit) != 0) ? 1 : 0; + return val; +} + void SERIAL_ROM::initialize() { cs = true; @@ -23,68 +30,35 @@ void SERIAL_ROM::initialize() rom_addr = 0; memset(rom, 0xff, sizeof(rom)); + uint8_t tmprom[256]; + memset(tmprom, 0xff, sizeof(tmprom)); + bool loaded = false; FILEIO *fio = new FILEIO(); + + // Default values are from Tsugaru, physmem.cpp. + unsigned char defSerialROM[32]= + { + 0x04,0x65,0x54,0xA4,0x95,0x45,0x35,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x0C,0x02,0x00,0x00,0x00,0x15,0xE0,0x00,0x00, + }; + memcpy(tmprom, defSerialROM, + (sizeof(tmprom) > sizeof(defSerialROM)) ? sizeof(defSerialROM) : sizeof(tmprom)); + + // Q: Is override machineid? 20200627 K.O + tmprom[24] = (machine_id >> 8); + tmprom[25] = (machine_id & 0xf8) | (cpu_id & 0x07); + if(fio->Fopen(create_local_path(_T("MYTOWNS.ROM")), FILEIO_READ_BINARY)) { // FONT - fio->Fread(rom, sizeof(rom), 1); + fio->Fread(tmprom, sizeof(tmprom), 1); fio->Fclose(); + loaded = true; } else if(fio->Fopen(create_local_path(_T("SERIAL.ROM")), FILEIO_READ_BINARY)) { // FONT - fio->Fread(rom, sizeof(rom), 1); + fio->Fread(tmprom, sizeof(tmprom), 1); fio->Fclose(); - } else { - // Header - const _TCHAR *id = _T("FUJITSU"); - int _len = strlen(id); - if(_len < 0) _len = 0; // Bit 251 - 72 - if(_len >= 22) _len = 21; // Bit 251 - 72 - for(int i = 0; i < (_len + 1); i++) { - rom[32 - i] = 0x00; - } - for(int i = 0; i < _len; i++) { - uint8_t _c = (uint8_t)id[i]; - uint8_t _revc = 0x00; - uint8_t val = 0x80; - for(int j = 0; j < 8; j++) { - if((_c & 0x01) != 0) _revc = _revc | val; - val >>= 1; - _c >>= 1; - } - rom[31 - i] = rom[31 - i] | ((_revc & 0xf0) >> 4); // High - rom[31 - (i + 1)] = rom[31 - (i + 1)] | ((_revc & 0x0f) << 4); // Low - } - rom[31 - _len] = rom[31 - _len] | 0x0f; // Last bit - // Machine ID (bit 71 - bit 56) must be dummy. - - // Serial (bit 55 - bit20) - auto serial = static_cast(0x00000123); - auto nmask = static_cast(0x0f); - nmask = nmask << 32; - int nibblepos = 8; - // Initialize footer and serial ID. - for(int i = 0; i < 7; i++) { - rom[7 - i] = 0x00; - } - - for(int i = 0; i < 9; i++) { - uint64_t nval = (nmask & serial) >> 32; - uint8_t _c = ((uint8_t)nval) & 0x0f; - uint8_t _revc = 0x00; - uint8_t val = 0x08; - for(int j = 0; j < 4; j++) { - if((_c & 0x01) != 0) _revc = _revc | val; - val >>= 1; - _c >>= 1; - } - serial <<= 4; - // High - if((i & 1) == 0) { // Lower - rom[6 - (i / 2)] = rom[6 - (i / 2)] | (_revc << 4); - } else { // Lower - rom[6 - (i / 2)] = rom[6 - (i / 2)] | _revc; - } - } + loaded = true; } } - + void SERIAL_ROM::reset() { // cs = true; @@ -93,19 +67,19 @@ void SERIAL_ROM::reset() // rom_addr = 0; } -void SERIAL_ROM::write_signal(int ch, uint32_t data, uint32_t mask) +void SERIAL_ROM::write_signal(int id, uint32_t data, uint32_t mask) { - switch(ch) { + switch(id) { case SIG_SERIALROM_CLK: { bool oldclk = clk; - bool newclk = clk; if(cs) { - newclk = ((data & mask) != 0); + clk = ((data & mask) != 0); + } else { + return; } - if((oldclk != newclk) && !(reset_reg)) { - clk = newclk; - if(!(oldclk)) { + if((oldclk != clk) && !(reset_reg)) { + if(clk) { // Rise up rom_addr = (rom_addr + 1) & 0xff; } @@ -120,19 +94,26 @@ void SERIAL_ROM::write_signal(int ch, uint32_t data, uint32_t mask) if((cs) && (clk)) { switch(reset_state) { case 0: - if(reset_reg) reset_state++; + if(!(reset_reg)) reset_state++; break; case 1: + if(reset_reg) reset_state++; + break; + case 2: if(!(reset_reg)) { // Do Reset rom_addr = 0; reset_state = 0; + reset_reg = false; } break; default: + reset_state = 0; // ToDo break; } - + } else { + // Reset reset state? + reset_state = 0; } break; } @@ -145,32 +126,89 @@ uint32_t SERIAL_ROM::read_signal(int ch) return ((clk) ? 0xffffffff : 0x00000000); break; case SIG_SERIALROM_CS: - return 0; + return ((cs) ? 0xffffffff : 0x00000000);; break; case SIG_SERIALROM_RESET: return ((reset_reg) ? 0xffffffff : 0x00000000); break; + case SIG_SERIALROM_RESET_STATE: + return reset_state; + break; case SIG_SERIALROM_DATA: - { - if((rom_addr >= 56) && (rom_addr < 72)) { - // Serial id - uint32_t machine_id = d_mem->read_signal(SIG_FMTOWNS_MACHINE_ID); - uint32_t bitaddr = 15 - (rom_addr - 56); - uint32_t bitmask = 0x8000 >> bitaddr; - return (((bitmask & machine_id) != 0) ? 0xffffffff : 0x00000000); - } else { - uint32_t localaddr = (rom_addr & 0xff) >> 3; - uint32_t localbit = (rom_addr & 0xff) & 0x07; - uint8_t _c = rom[localaddr]; - uint8_t _bmask = 0x01 << localbit; - return (((_c & _bmask) != 0) ? 0xffffffff : 0x00000000); - } + if(cs) { + return (read_rom_bits(rom_addr) == 0x00) ? 0x00000000 : 0xffffffff; + } else { + return 0x00000000; } break; } return 0; } +uint32_t SERIAL_ROM::read_io8(uint32_t addr) +{ + uint8_t val = 0x00; + if(cs) { + val = (rom[rom_addr >> 3] >> (rom_addr & 7)) & 0x01; + } else { + val = 0x01; + } + val = val | 0x3e; + if(clk) val = val | 0x40; + if(reset_reg) val = val | 0x80; + return val; +} + +void SERIAL_ROM::write_io8(uint32_t addr, uint32_t data) +{ + this->write_signal(SIG_SERIALROM_CS, data, 0x20); + + reset_reg = ((data & 0x80) != 0); + this->write_signal(SIG_SERIALROM_CLK, data, 0x40); + this->write_signal(SIG_SERIALROM_RESET, data, 0x80); +} + +bool SERIAL_ROM::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + _TCHAR numseg[8] = {'\0'}; + int noff = 0; + // ToDo: Implement + return false; +} + +bool SERIAL_ROM::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + + // Dump raw value + my_tcscat_s(buffer, buffer_len, _T("** INFO:\n")); + my_tcscat_s(buffer, buffer_len, _T("ROM value is enable to modify, \n")); + my_tcscat_s(buffer, buffer_len, _T(" R00-R32 : Overwrite rom raw value by byte\n")); + my_tcscat_s(buffer, buffer_len, _T(" B000-B256 : Overwrite bit foo to (value != 0) ? 1 : 0\n")); + + my_tcscat_s(buffer, buffer_len, _T("** STATS:\n")); + my_tcscat_s(buffer, buffer_len, + create_string(_T(" CS=%s CLK=%d RESET REG=%d RESET STATE=%d\n ROM BIT POSITION=%03d(0x%02X)\n\n"), + (cs) ? _T("ON ") : _T("OFF"), + (clk) ? 1 : 0, + (reset_reg) ? 1 : 0, + reset_state, + rom_addr, rom_addr) + ); + + my_tcscat_s(buffer, buffer_len, _T("** RAW MEMORY VALUE:\n")); + my_tcscat_s(buffer, buffer_len, _T(" +0 +1 +2 +3 +4 +5 +6 +7\n")); + my_tcscat_s(buffer, buffer_len, _T(" ------------------------------\n")); + for(int n = 0; n < 4; n++) { + my_tcscat_s(buffer, buffer_len, + create_string(_T("+%02X %02X %02X %02X %02X %02X %02X %02X %02X\n"), + n * 4, + rom[n * 4 + 0], rom[n * 4 + 1], rom[n * 4 + 2], rom[n * 4 + 3], + rom[n * 4 + 4], rom[n * 4 + 5], rom[n * 4 + 6], rom[n * 4 + 7]) + ); + } + return true; +} + #define STATE_VERSION 1 bool SERIAL_ROM::process_state(FILEIO* state_fio, bool loading) @@ -181,6 +219,8 @@ bool SERIAL_ROM::process_state(FILEIO* state_fio, bool loading) if(!state_fio->StateCheckInt32(this_device_id)) { return false; } + state_fio->StateValue(machine_id); + state_fio->StateValue(cpu_id); state_fio->StateValue(cs); state_fio->StateValue(clk); state_fio->StateValue(reset_reg); diff --git a/source/src/vm/fmtowns/serialrom.h b/source/src/vm/fmtowns/serialrom.h index 5f804b769..51a700e3e 100644 --- a/source/src/vm/fmtowns/serialrom.h +++ b/source/src/vm/fmtowns/serialrom.h @@ -11,43 +11,59 @@ #include "../device.h" -#define SIG_SERIALROM_CLK 1 -#define SIG_SERIALROM_CS 2 -#define SIG_SERIALROM_RESET 3 -#define SIG_SERIALROM_DATA 4 +#define SIG_SERIALROM_CLK 1 +#define SIG_SERIALROM_CS 2 +#define SIG_SERIALROM_RESET 3 +#define SIG_SERIALROM_DATA 4 +#define SIG_SERIALROM_RESET_STATE 5 namespace FMTOWNS { class SERIAL_ROM : public DEVICE { +private: + uint8_t read_rom_bits(uint8_t pos); protected: - DEVICE* d_mem; - bool cs; bool clk; bool reset_reg; int reset_state; + uint8_t rom_addr; uint8_t rom[32]; + uint16_t machine_id; + uint8_t cpu_id; public: - SERIAL_ROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + SERIAL_ROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + machine_id = 0x0100; + cpu_id = 0x01; set_device_name(_T("FMTOWNS_SERIAL_ROM")); - d_mem = NULL; } ~SERIAL_ROM() {} void initialize(); void reset(); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); - void write_signal(int ch, uint32_t data, uint32_t mask); - uint32_t read_signal(int ch); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_signal(int ch); + + bool write_debug_reg(const _TCHAR *reg, uint32_t data); + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); bool process_state(FILEIO* state_fio, bool loading); - void set_context_mem(DEVICE* dev) + // unique function + void set_machine_id(uint16_t val) + { + machine_id = val & 0xfff8; + } + void set_cpu_id(uint16_t val) { - d_mem = dev; + cpu_id = val & 0x07; } }; diff --git a/source/src/vm/fmtowns/testcode/README.md b/source/src/vm/fmtowns/testcode/README.md new file mode 100644 index 000000000..0bbdca97a --- /dev/null +++ b/source/src/vm/fmtowns/testcode/README.md @@ -0,0 +1,21 @@ +

Testing bootroms for emufmtowns

+
+

Jan 27-, 2020
+K.Ohta

+
+ +** Sorry, this article is written in Japanese *** + +概要 +===== + + このディレクトリィは、Common Source Code Project (CSP)をFM-Towns +に加えるにあたって利用した、テストコードを収録していこうと思います。 + + 「互換ROM」のソースコードとYASMが +必要になります。 + +ビルド法など +===== + +あとでかく(^_^; diff --git a/source/src/vm/fmtowns/testcode/about.txt b/source/src/vm/fmtowns/testcode/about.txt new file mode 100644 index 000000000..c4fa5e482 --- /dev/null +++ b/source/src/vm/fmtowns/testcode/about.txt @@ -0,0 +1,113 @@ +--------------------------------------------------------------------- + FM TOWNS ݊ROM V[Y : FMT_SYS.ROM +--------------------------------------------------------------------- + +͉H +-------------- +FM TOWNSG~[^ÂŎgp”\Ȍ݊ROMC[ŴЂƂ‚ŁA@ +璊oROMC[Wł͂ȂAƎɍ쐬ꂽROMC[WłB +@璊oROMC[ẂARȂlp͈̔͂𒴂Ďg +͂ł܂BA{A[JCuɊ܂܂݊ROMC[ẂA@ +̂̂悤Ȓ쌠ɔ邱ƂȂzzsƂł܂B +FM TOWNS@LĂȂgĂA͂܂B + +@ +---------- +A[JCuɂ́Ã\[XR[h琶ꂽ FMT_SYS.ROM +܂܂Ă܂B +Ō݊ROMC[W𐶐ꍇ́A̗v̂ōsĂB + +1.ɕKvȃt@C +݊ FMT_SYS.ROM ́Ãt@CQ邱ƂŐ܂B +̂ƂɂĂBYt makesys.bat gƊȒPɌ +邱Ƃł܂B + + FMT_SYS0.F12 (131072oCg) : 12hbgtHg + FMT_SYS1.EXB ( 32768oCg) : EXT-BOOT(_~[) + FMT_SYS2.ICN ( 32768oCg) : VXeACR + FMT_SYS3.DMY ( 32768oCg) : _~[ + FMT_SYS4.LGO ( 15360oCg) : NS + FMT_SYS5.IC2 ( 1024oCg) : NɎgACR + FMT_SYS6.PRG ( 16384oCg) : u[gR[h + +2.e\t@C̍쐬@ +L̃t@CŚAꂼȉ̎菇ō쐬ĂB + +EFMT_SYS0.F12 + {A[JCu 0xFF Ŗ߂_~[t@C܂܂Ă܂B + t@CgB + +EFMT_SYS1.EXB + {A[JCu 0xFF Ŗ߂_~[t@C܂܂Ă܂B + t@CgB + +EFMT_SYS2.ICN FMT_SYS5.IC2 + BMP2ICN.EXE gāAICON.BMP ϊ邱Ƃɂ쐬܂B + g̓R}hvvgA + + bmp2icn icon.bmp + + ƎsĂB + +EFMT_SYS3.DMY + {A[JCu 0xFF Ŗ߂_~[t@C܂܂Ă܂B + t@CgB + +EFMT_SYS4.LGO + BMP2LOGO.EXE gāALOGO.BMP ϊ邱Ƃɂ쐬܂B + g̓R}hvvgA + + bmp2logo logo.bmp + + ƎsĂB + +EFMT_SYS6.PRG + \[XR[hNASMŃAZu܂BR}hvvgA + + nasmw -f bin sys.asm -o fmt_sys6.prg + + ƎsĂBNASM̎gp@́ANASM̃}jA + B + + +ӎ +---------- +E{A[JCuɊ܂܂vÓAׂăt[\tgłB + +E{A[JCuɊ܂܂t@C̎gp琶Ȃ鑹Qɂ‚ + A҂͈ؐӔC𕉂܂B + +E͌݊ROMłāA@Ƃ܂邱Ƃۏ؂ + ̂ł͂܂B삪@ƈقȂAʂ̌ڂႤ̖ + ͕sł͂܂B + +EÂN邽߂ɕKvROMC[W͕܂B{݊ + ROMt@Ĉ݂ł͋N邱Ƃ͂ł܂B + +E{݊ROMɂ‚āAFM TOWNS̔łxmʊЂւ̂₢ + 킹͂B + + +쌠 +-------- +쌠 Kasanova (kasanova@retropc.net) ۗL܂BAL +̏ɂƂÂĉςꂽɊւĂ͂̌ł͂܂B + + +ρEĔzz +------------------ +{A[JCuɊ܂܂t@ĆAꕔ܂͑SρEĔzz邱 +Ƃł܂BAȉ̏čsĂB + +EςčĔzzꍇ́Aςs҂Ɖϕ킩悤 + ɂĂB + +Eꂽ FMT_SYS.ROM zzꍇ́A@璊oꂽ + Ƃ͈قȂ ROM C[Wł|𖾋L镶KYtĂ + B + ݊ROMC[Wł邱Ƃ̒fȂ FMT_SYS.ROM ݂̂zz + ͂B + +ȂAĔzzɍۂĂ͂ł邾 Kasanova ܂ł񂭂΍K +łB + diff --git a/source/src/vm/fmtowns/testcode/assemble_sys.sh b/source/src/vm/fmtowns/testcode/assemble_sys.sh new file mode 100644 index 000000000..532e45057 --- /dev/null +++ b/source/src/vm/fmtowns/testcode/assemble_sys.sh @@ -0,0 +1,2 @@ +#!/bin/sh +yasm -f bin sys.asm -o fmt_sys6.prg diff --git a/source/src/vm/fmtowns/testcode/bmp2icn.c b/source/src/vm/fmtowns/testcode/bmp2icn.c new file mode 100644 index 000000000..739dab803 --- /dev/null +++ b/source/src/vm/fmtowns/testcode/bmp2icn.c @@ -0,0 +1,231 @@ +/* +version 2003.03.04.1 + BMP to TOWNS System Icon Data Converter + + by Kasanova +*/ + +/* + VXeACR쐬pBMP̃tH[}bg + + EBMP̃TCY512x544(ɑ傫Ԃɂ͖Ȃ) + E256FBMP̂ݑΉ + EFԍ01AȊO̐Fԍׂ͂02lϊ + E32x32hbg̃ACR 8xc16 Ŕzu + Eԉ̗ɂ32x32hbg̋NpACR8”zu + E[p^[][}XNp^[]2‚ɕׂĔzu邱 + ENpACRɃ}XNp^[͂Ȃ + Eĉ̂悤ȍ\ɂȂ + + ----- 64hbg ----- + [p^[0][}XN0] [p^[1][}XN1] [p^[2][}XN2] [p^[3][}XN3]EEE + [p^[8][}XN8] [p^[9][}XN9] [p^[a][}XNa] [p^[b][}XNb]EEE + E + E + E + [p^[0][p^[1][p^[2][p^[3][p^[4][p^[5][p^[6][p^[7] +*/ + +#include +#include +#include + +#define BMPHEADERSIZE 14 +#define ICONMAX 128 +#define ICONBOOTMAX 8 +#define ICONPATTERNSIZE 256 +#define ICON_W 32 +#define ICON_H 32 +#define ICONPITCH (ICON_W/8) + +#define ICONMATRIX_W 8 +#define ICONMATRIX_H (16+1) + +char srcfile[128]; +char dstfile[] = "fmt_sys2.icn"; +char dstfile2[] = "fmt_sys5.ic2"; +char buffer[2048]; +char iconbuffer [ ICONPATTERNSIZE*ICONMAX ]; /* 32768 */ +char icon2buffer[ (ICONPATTERNSIZE/2)*ICONBOOTMAX ]; +FILE *fp, *fpw, *fpw2; + + +void pack8dot( unsigned int bmpptr, unsigned int iconptr ) +{ + int i; + char c; + + c = 0; + for( i=0 ; i<8 ; i++ ) + { + c <<= 1; + c |= buffer[bmpptr+i]==0 ? 1 : 0; + } + iconbuffer[iconptr] = c; +} + + +int do_convert() +{ + int readsiz, w,h, x,y,yy, pitch; + unsigned int ptr; + + if( fread( buffer, 1, BMPHEADERSIZE, fp) != BMPHEADERSIZE ) + { + puts( "wb_ǂݍݎs(1)\n" ); + return( 1 ); + } + + if( (buffer[0]!='B')||(buffer[1]!='M') ) + { + puts( "BMPt@Cł͂܂\n" ); + return( 1 ); + } + + /* BMPINFOHEADER */ + readsiz = *(int*)(buffer+10); + readsiz -= BMPHEADERSIZE; + if( fread( buffer, 1, readsiz, fp) != readsiz ) + { + puts( "wb_ǂݍݎs(2)\n" ); + return( 1 ); + } + + if( buffer[14] != 8 ) + { + puts( "256FBMPȊOɂ͑ΉĂ܂\n" ); + return( 1 ); + } + + w = *(int*)(buffer+4); + h = *(int*)(buffer+8); + pitch = w; + + if( w < ICON_W*ICONMATRIX_W ) + { + puts( "BMP̐TCY܂\n" ); + return( 1 ); + } + + if( h < ICON_H*ICONMATRIX_H ) + { + puts( "BMP̐TCY܂\n" ); + return( 1 ); + } + + if( pitch > sizeof(buffer) ) + { + puts( "BMP̐TCY傫܂\n" ); + return( 1 ); + } + + /* s܂ */ + /* u[gACR */ + for( yy=ICON_H-1 ; yy>=0 ; yy-- ) + { + if( fread( buffer, 1, pitch, fp) != pitch ) + { + puts( "ǂݍݎs\n" ); + return( 1 ); + } + + for( x=0 ; x=0 ; y-- ) + { + for( yy=ICON_H-1 ; yy>=0 ; yy-- ) + { + if( fread( buffer, 1, pitch, fp) != pitch ) + { + puts( "ǂݍݎs\n" ); + return( 1 ); + } + + for( x=0 ; x +#include +#include + +#define BMPHEADERSIZE 14 + +#define LOGO_USEPLANES 4 +#define LOGO_W 264 +#define LOGO_H 115 +#define LOGO_PITCH ((LOGO_W/8)*LOGO_USEPLANES) +#define LOGO_PITCH_PLANE (LOGO_W/8) + +#if LOGO_USEPLANES==4 +#define PAL_OFFSET 0x3b80 +#else +#define PAL_OFFSET 0x2f00 +#endif + +char srcfile[128]; +char dstfile[] = "fmt_sys4.lgo"; +char buffer[2048]; +char logobuffer[ (0x1000*4)-0x400 ]; +FILE *fp, *fpw; + + +void pack8dot( unsigned int bmpptr, unsigned int brgptr ) +{ + int j; + char b,r,g; + +#if LOGO_USEPLANES==4 + char i; + i = 0; +#endif + + b = 0; + r = 0; + g = 0; + + for( j=0 ; j<4 ; j++ ) + { + b <<= 1; + r <<= 1; + g <<= 1; + b |= buffer[bmpptr+j]&0x10 ? 1 : 0; + r |= buffer[bmpptr+j]&0x20 ? 1 : 0; + g |= buffer[bmpptr+j]&0x40 ? 1 : 0; + b <<= 1; + r <<= 1; + g <<= 1; + b |= buffer[bmpptr+j]&0x1 ? 1 : 0; + r |= buffer[bmpptr+j]&0x2 ? 1 : 0; + g |= buffer[bmpptr+j]&0x4 ? 1 : 0; + +#if LOGO_USEPLANES==4 + i <<= 1; + i |= buffer[bmpptr+j]&0x80 ? 1 : 0; + i <<= 1; + i |= buffer[bmpptr+j]&0x8 ? 1 : 0; +#endif + + } + + logobuffer[4+ brgptr] = b; + logobuffer[4+ brgptr+LOGO_PITCH_PLANE] = r; + logobuffer[4+ brgptr+LOGO_PITCH_PLANE*2] = g; + +#if LOGO_USEPLANES==4 + logobuffer[4+ brgptr+LOGO_PITCH_PLANE*3] = i; +#endif + +} + + +int do_convert() +{ + int readsiz, w,h, x,y, pitch; + unsigned int ptr; + + if( fread( buffer, 1, BMPHEADERSIZE, fp) != BMPHEADERSIZE ) + { + puts( "wb_ǂݍݎs(1)\n" ); + return( 1 ); + } + + if( (buffer[0]!='B')||(buffer[1]!='M') ) + { + puts( "BMPt@Cł͂܂\n" ); + return( 1 ); + } + + /* BMPINFOHEADER */ + readsiz = *(int*)(buffer+10); + readsiz -= BMPHEADERSIZE; + if( fread( buffer, 1, readsiz, fp) != readsiz ) + { + puts( "wb_ǂݍݎs(2)\n" ); + return( 1 ); + } + + if( buffer[14] != 4 ) + { + puts( "16FBMPȊOɂ͑ΉĂ܂\n" ); + return( 1 ); + } + + w = *(int*)(buffer+4); + h = *(int*)(buffer+8); + pitch = w/2; + + if( w != LOGO_W ) + { + puts( "BMP̐TCYsł\n" ); + return( 1 ); + } + + if( h != LOGO_H ) + { + puts( "BMP̐TCYsł\n" ); + return( 1 ); + } + + /* 摜TCYRs[ */ + *(int*)logobuffer = w; + *(int*)(logobuffer+2) = h; + + /* pbgRs[(@ɂ݂͑܂) */ + ptr = *(unsigned int*)buffer; + for( y=0 ; y<16 ; y++ ) + { + logobuffer[PAL_OFFSET+y*3 ] = buffer[ptr ]; /* B */ + logobuffer[PAL_OFFSET+y*3+1] = buffer[ptr+2]; /* R */ + logobuffer[PAL_OFFSET+y*3+2] = buffer[ptr+1]; /* G */ + ptr += 4; + } + + /* s܂ */ + for( y=LOGO_H-1 ; y>=0 ; y-- ) + { + if( fread( buffer, 1, pitch, fp) != pitch ) + { + puts( "ǂݍݎs\n" ); + return( 1 ); + } + + ptr = LOGO_PITCH*y; + for( x=0 ; x FMT_SYS.ROM diff --git a/source/src/vm/fmtowns/testcode/sys.asm b/source/src/vm/fmtowns/testcode/sys.asm new file mode 100644 index 000000000..bc2df0b99 --- /dev/null +++ b/source/src/vm/fmtowns/testcode/sys.asm @@ -0,0 +1,852 @@ +; nasmw -O3 -f bin sys.asm -o fmt_sys6.prg +; modified by K.Ohta from 2020-01-27 from comp_sysrom/sys.asm, . +; version 2003.03.04.1 by Kasanova. +; http://townsemu.world.coocan.jp/compatiroms.html +;--------------------------------------------------------------------- +; +; FM TOWNS ݊ ROM V[Y +; +; FMT_SYS.ROM : Cp[g +; 0FFFFC000h - 0FFFFFFFFh +; +; by Kasanova +; +;--------------------------------------------------------------------- +; FMT_SYS.ROM ̍\({) +; 0FFFC0000h - 0FFFDFFFFh : 12hbgtHg +; @ɂĂALL FFhANS(pbNh +; sNZ)@ +; 0FFFE0000h - 0FFFE7FFFh : EXT-BOOT(32rbgvO) +; 0FFFE8000h - 0FFFEFFFFh : VXeACR +; 0FFFF0000h - 0FFFF7FFFh : ̃p^[? +; 0FFFF8000h - 0FFFFAFFFh ; NS(v[) +; @ɂĂ Extention BIOS +; 0FFFFB000h - 0FFFFBFFFh : u[gɎgACR +; 0FFFFC000h - 0FFFFFFFFh ; 16rbgvO +;--------------------------------------------------------------------- +; FMT_SYS.ROM ̍\(̌݊ROM) +; 0FFFC0000h - 0FFFDFFFFh : 12hbgtHg +; 0FFFE0000h - 0FFFE7FFFh : EXT-BOOT(32rbgvO)A܂gĂȂ +; 0FFFE8000h - 0FFFEFFFFh : VXeACR +; 0FFFF0000h - 0FFFF7FFFh : _~[f[^(0ffh) +; 0FFFF8000h - 0FFFFBBFFh ; NS(v[A4v[) +; 0FFFFBC00h - 0FFFFBFFFh : u[gɎgACR +; 0FFFFC000h - 0FFFFFFFFh ; 16rbg+32rbgvO +;--------------------------------------------------------------------- + +%define BOOTCODE_BASE 0ffffc000h + +%define BOOT_SS 0f7a0h +%define BOOT_SP 057eh +%define LOCAL_SP 05feh + +%define VRAM_PITCH 50h + +%define LOGO_ADDRESS 0ffff8000h +%define LOGO_USEPLANES 4 +%if(LOGO_USEPLANES==3) +%define LOGO_PAL_ADDRESS 0ffffaf00h +%else +%define LOGO_PAL_ADDRESS 0ffffbb80h +%endif + +%define ICON_WAIT 81 +%define ICON_FDD 64 +%define ICON_CD 67 +%define ICON_HDD 71 + +%define PMODE_PUTICON 0 +%define PMODE_MEMORYCHECK 1 +%define PMODE_DRAWLOGO 2 +%define PMODE_SETPALETTE 3 +%define PMODE_TRANSFERMEM 4 + +;--------------------------------------------------------------------- + +%macro JMPFAR 1 + db 0eah + dw %1 + dw 0fc00h +%endmacro + + +%macro CALLFAR 1 + db 09ah + dw %1 + dw 0fc00h +%endmacro + + +%macro SAVEREG_TO_CMOS 2 + mov dx,%1 +%ifidn %2,ax +%else + mov ax,%2 +%endif + out dx,al + mov dx,%1+2 + mov al,ah + out dx,al +%endmacro + + +%macro LOADREG_FROM_CMOS 2 + mov dx,%1+2 + in al,dx + mov ah,al + mov dx,%1 + in al,dx +%ifidn %2,ax +%else + mov %2,ax +%endif +%endmacro + +;--------------------------------------------------------------------- + +; ₵wb_ + dd 0,0,0,0, 0,0,0,0 +; + +[BITS 16] + +startall: + cli + cld + mov ax,dx + mov dx,3c26h + out dx,al + mov al,ah + sub dl,2 + out dx,al + + ; disable & reset DMAC + mov al,0fh + out 0afh,al + mov al,3 + out 0a0h,al + + in al,28h + or al,1 + out 28h,al + + ; select ROM + mov dx,404h + xor al,al + out dx,al + + mov cx,BOOT_SS + mov ss,cx + mov sp,BOOT_SP + + push cs + pop ds + + ; set local stack address + SAVEREG_TO_CMOS 31a8h, LOCAL_SP + + mov dx,3c22h + xor al,al + out dx,al ; non 386SX + + mov dx,31b8h + out dx,al + mov dx,31b2h + out dx,al + mov dx,31cch + out dx,al + + call set_gdt + call init_pic + call init_keyboard + call init_crtc + + ; CMOS񂪐H + mov ah,20h + CALLFAR cmos_bios + jnc .noinitcmos + ; CMOS + mov ah,0 + CALLFAR cmos_bios +.noinitcmos: + + mov al,PMODE_SETPALETTE + call call_pmode + + mov al,PMODE_DRAWLOGO + call call_pmode + + mov al,PMODE_MEMORYCHECK + call call_pmode + + ; CDǂ߂邩H + mov ah,0eh + CALLFAR disk_bios + jnc .cdok + + ; 蔲(^^; + mov cl,ICON_CD + mov dx, (VRAM_PITCH*368)+(VRAM_PITCH-4) + call call_pmode + mov si,mes_cantboot + mov di,VRAM_PITCH*384 + call textout + jmp $ + +.cdok: + ; IPLǂݍ + push ds + mov cx,0 + mov dx,0 + mov ax,0b000h + mov ds,ax + mov di,0 + mov ax,05c0h ; read command + media no. + mov bx,1 + CALLFAR disk_bios + pop ds + + mov cl,ICON_WAIT + mov al,PMODE_PUTICON + mov dx, (VRAM_PITCH*368)+(VRAM_PITCH-4) + call call_pmode + + mov si,mes_reading + mov di,VRAM_PITCH*384 + call textout + + call check_iplvalidity + jc .wrongipl + + mov ax,0ffffh + mov bx,0008h + call far [cs:si] + +.wrongipl: + ; NɎsƖ߂Ă + ; ꍇ͂QxƖ߂ĂȂ + mov si,mes_wrongipl + mov di,VRAM_PITCH*384 + call textout + + ; + jmp $ + +mes_reading: + db 'VXeǂݍݒł@@@@',0 +mes_wrongipl: + db 'VXeႢ܂@@@@@@',0 +mes_setsys: + db 'VXeZbgĂ@',0 +mes_cantboot: + db 'bcZbgăZbgĂ',0 + +;--------------------------------------------------------------------- +; IPL̃o[W`FbN + +check_iplvalidity: + push es + mov si,0b000h + mov es,si + + mov si,.ipl_type1 + cmp dword [es:0],'IPL4' + jz .goodipl + + mov si,.ipl_type2 + cmp dword [es:3],'IPL4' + jz .goodipl + + stc +.goodipl: + pop es + ret + +.ipl_type1: + dw 4,0b000h +.ipl_type2: + dw 0,0b000h +; dw 0,0c200h + +;--------------------------------------------------------------------- +; GDTZbg + +set_gdt: + lgdt [cs:.lgdtr] + ret + + align 8 + dw 0 +.lgdtr: dw 002fh ; GDT limit + dd 0fc000h+.gdtentry + +.gdtentry: db 00h, 00h,00h, 00h,00h,00h, 00h,00h +; db 0ffh,0ffh,00h, 00h,00h,9bh,0c0h,00h + db 0ffh,0ffh,00h, 00h,00h,9bh,0cfh,00h + db 0ffh,0ffh,00h, 00h,00h,93h,0cfh,00h + db 0ffh,0ffh,00h,0c0h,0fh,9bh,000h,00h + db 0ffh,0ffh,00h,0c0h,0fh,93h,000h,00h + db 0ffh,000h,00h,0c0h,0fh,9bh,0c0h,00h +; db 0ffh,0ffh,00h,0c0h,0fh,9bh,0cfh,00h + + +;--------------------------------------------------------------------- +; veNg[hEvVWĂ + +call_pmode: + push ds + push es + push gs + mov bx,ss + mov gs,bx + mov bx,ax + + mov eax,cr0 + or al,1 + mov cr0,eax + jmp short $+2 + + db 0eah + dw .goto_pmode + dw 28h +.goto_pmode: + + db 0eah + dd BOOTCODE_BASE+pmode_entry + dw 8 + +return_from_pmode: + mov bx,gs + mov ss,bx + + pop gs + pop es + pop ds + ret + +;--------------------------------------------------------------------- +; PIC +; EFCgĂȂ̂ŁA@ł͓삵Ȃ + +init_pic: + mov al,19h + out 0,al + mov al,40h + out 2,al + mov al,80h + out 2,al + mov al,1dh + out 2,al + mov al,0feh + out 2,al + mov al,19h + out 10h,al + mov al,48h + out 12h,al + mov al,87h + out 12h,al + mov al,9 + out 12h,al + mov al,0ffh + out 12h,al + ret + +;--------------------------------------------------------------------- +; L[{[h + +init_keyboard: + mov dx,602h + mov al,0a1h ; reset + out dx,al + + ; obt@ɂȂ܂ő҂ +.loop: + mov dx,602h + in al,dx + test al,1 + jz .exit + sub dx,2 + in al,dx + jmp .loop +.exit: + ret + +;--------------------------------------------------------------------- +; CRTCAFMR݊̉ʃ[h + +init_crtc: + mov dx,0fda0h + xor al,al + out dx,al + + mov si,crtcinitdata + mov cx,32 +.loop: + mov al,32 + sub al,cl + mov dx,440h + out dx,al + mov ax,[si] + add dx,2 + out dx,ax + add si,2 + loop .loop + + mov dx,448h + xor al,al + out dx,al + add dx,2 + mov al,15h + out dx,al + + mov dx,448h + mov al,1 + out dx,al + add dx,2 + mov al,8 + out dx,al + + mov dx,0fda0h + mov al,8 + out dx,al + + ; Sv[ݑΏۂɐݒ + mov dx,0ff81h + mov al,0fh + out dx,al + + ; Sv[\ + mov dx,0ff82h + mov al,67h + out dx,al + + ; `Ώۃv[I + mov dx,0ff83h + xor al,al + out dx,al + + ret + + +crtcinitdata: + dw 0040h, 0320h, 0000h, 0000h, 035fh, 0000h, 0010h, 0000h + dw 036fh, 009ch, 031ch, 009ch, 031ch, 0040h, 0360h, 0040h + dw 0360h, 0000h, 009ch, 0000h, 0050h, 0000h, 009ch, 0000h + dw 0050h, 004ah, 0001h, 0000h, 003fh, 0003h, 0000h, 0150h + +;--------------------------------------------------------------------- +; \ +; +; si = +; di = \VRAMAhX + +textout: + push es + push bx + mov ax,0c000h + mov es,ax + mov bx,0ff94h + +.textoutloop: + mov cx,[si] + or cl,cl + jz .exit + + call sjistojis + mov [es:bx],cl + mov [es:bx+1],ch + mov cx,16 +.onecharloop: + mov al,[es:bx+2] + mov ah,[es:bx+3] + mov [es:di],ax + add di,VRAM_PITCH + loop .onecharloop + + sub di,VRAM_PITCH*16-2 + add si,2 + jmp .textoutloop +.exit: + pop bx + pop es + ret + +; VtgJISJISϊ +sjistojis: + cmp cl,0e0h + jc .j1 + sub cl,40h +.j1: + sub cl,81h + shl cl,1 + add cl,21h + mov al,ch + cmp ch,9fh + jc .j2 + inc cl + sub ch,5eh +.j2: + sub ch,20h + cmp al,7eh + ja .j3 + test cl,1 + jz .j3 + inc ch +.j3: + ret + +;--------------------------------------------------------------------- +; DISK-BIOS(ƏɌĂł) +; ahɉĎ̋@\񋟂(ah = 2-0x11) + align 2 +disk_command_table: + dw disk_command_02 ; 2 : + dw disk_command_03 ; 3 : fBA擪փV[NH + dw disk_command_04 ; 4 : + dw disk_command_05 ; 5 : [h + dw disk_command_06 ; 6 : Cg + dw disk_command_xx ; 7 : + dw disk_command_08 ; 8 : hCuZbg(FDD & HDD) + dw disk_command_xx ; 9 : + dw disk_command_xx ; a : + dw disk_command_xx ; b : + dw disk_command_xx ; c : + dw disk_command_xx ; d : + dw disk_command_0e ; e : hCu`FbN + dw disk_command_xx ; f : + dw disk_command_xx ;10 : + dw disk_command_11 ;11 : +; +; ^[R[h: ah(0:I)AG[̗L̓L[tOɃZbg + +disk_bios: + ; ߂ǂBtOςȂ悤 + push dx + push ax ; ꂪ^[R[hɂȂ + + ; ܂A[JX^bNɐ؂ւ + ; ݂ SS:SP ޔ + SAVEREG_TO_CMOS 319ch, ss + SAVEREG_TO_CMOS 31a0h, sp + LOADREG_FROM_CMOS 31a8h, sp + mov ax,BOOT_SS + mov ss,ax + ; [JX^bNɐ؂ւ + + ; ďo SS:SP push + LOADREG_FROM_CMOS 319ch, ax ; ss + push ax + LOADREG_FROM_CMOS 31a0h, ax ; sp + push ax + + push es + push ds + push di + push si + push bp + + LOADREG_FROM_CMOS 31a8h, bp + + ; DS:SI ŌĂяoX^bN悤ɂ + LOADREG_FROM_CMOS 319ch, ds + LOADREG_FROM_CMOS 31a0h, si + + push cx + push bx + clc + pushf + + cli + cld + mov ax,ss + mov es,ax + mov di,sp + push bp + + ; ԍŏ push WX^[h + mov ax,[si] + mov dx,[si+2] + + ; {Ȃ͈͔肪邪ȗ + + ; Ă + mov al,ah + xor ah,ah + sub ax,2 + add ax,ax + mov bx,ax + call [cs:disk_command_table+bx] + + ; ʂi[ + or ah,ah + setnz al + mov [si+1],ah + or [es:di],al ; CF + + pop ax + popf + pop bx + pop cx + pop bp + pop si + pop di + pop ds + pop es + + mov dx,bx + pop bx + mov ax,bx + pop bx + mov ss,bx + mov sp,ax + mov bx,dx + pop ax + pop dx + retf + + +disk_command_xx: + jmp $ + +disk_command_02: + jmp $ + +disk_command_03: + call cd_command_0e ; ꉞő + ret + +disk_command_04: + jmp $ + +disk_command_05: + mov al,[si] + and al,0f0h + cmp al,040h + jz .rom + call cd_command_05 + ret +.rom: + call osrom_command_05 + ret + +disk_command_06: + mov al,[si] + and al,0f0h + cmp al,040h + jz .rom + jmp $ + ret +.rom: + call osrom_command_06 + ret + +disk_command_08: + jmp $ + +disk_command_0e: + call cd_command_0e + ret + +disk_command_11: + jmp $ + + +;--------------------------------------------------------------------- +; CMOS-BIOS(ƏɌĂł) +; ahɉĎ̋@\񋟂(ah = -3(0xfd)-0x20) + align 2 + dw cmos_command_fd ;fd : + dw cmos_command_xx ;fe : + dw cmos_command_xx ;ff : +cmos_command_table: + dw cmos_command_00 ; 0 : CjVCY + dw cmos_command_01 ; 1 : + dw cmos_command_02 ; 2 : + dw cmos_command_03 ; 3 : + dw cmos_command_04 ; 4 : + dw cmos_command_05 ; 5 : + dw cmos_command_06 ; 6 : + dw cmos_command_xx ; 7 : + dw cmos_command_xx ; 8 : + dw cmos_command_xx ; 9 : + dw cmos_command_xx ; a : + dw cmos_command_xx ; b : + dw cmos_command_xx ; c : + dw cmos_command_xx ; d : + dw cmos_command_xx ; e : + dw cmos_command_xx ; f : + dw cmos_command_10 ;10 : ubN + dw cmos_command_11 ;11 : ubNǂݏo + dw cmos_command_xx ;12 : + dw cmos_command_xx ;13 : + dw cmos_command_xx ;14 : + dw cmos_command_xx ;15 : + dw cmos_command_xx ;16 : + dw cmos_command_xx ;17 : + dw cmos_command_xx ;18 : + dw cmos_command_xx ;19 : + dw cmos_command_xx ;1a : + dw cmos_command_xx ;1b : + dw cmos_command_xx ;1c : + dw cmos_command_xx ;1d : + dw cmos_command_xx ;1e : + dw cmos_command_xx ;1f : + dw cmos_command_20 ;20 : wb_킩`FbN +; +; ^[R[h: ah(0:I)AG[̗L̓L[tOɃZbg + +cmos_bios: + ; ܂߂ǂBtO͕ςĂ݂ + push bp + mov bp,dx + + ; ܂Aaxޔ + SAVEREG_TO_CMOS 319ch,ax + + ; [JX^bNɐ؂ւ + ; ݂ SS:SP ޔ + SAVEREG_TO_CMOS 31a0h, ss + SAVEREG_TO_CMOS 31a4h, sp + LOADREG_FROM_CMOS 31a8h, sp + mov ax,BOOT_SS + mov ss,ax + ; [JX^bNɐ؂ւ + + ; ďo SS:SP push + LOADREG_FROM_CMOS 31a0h, ax ; ss + push ax + LOADREG_FROM_CMOS 31a4h, ax ; sp + push ax + + ; ޔĂax𕜌 + LOADREG_FROM_CMOS 319ch,ax + + mov dx,bp + push es ; [bp+12] + push ds ; [bp+10] + push di ; [bp+e] + push si ; [bp+c] + push bp ; [bp+a] + push dx ; [bp+8] + push cx ; [bp+6] + push bx ; [bp+4] + push ax ; [bp+2] + clc + pushf + + cli + cld + mov bp,sp + + ; ͈̓`FbNāAĂ + mov al,[bp+3] + mov ah,1 + + cmp al,21h + jnl .error + cmp al,0fch + jng .error + + movsx bx,al + add bx,bx + call [cs:cmos_command_table+bx] + + ; ʂi[ + or ah,ah + setnz al + jns .noerror +.error: + mov [bp+6],cx +.noerror: + mov [bp+3],ah + or [bp],al ; CF + + popf + pop ax + pop bx + pop cx + pop dx + pop bp + pop si + pop di + pop ds + pop es + + mov bp,dx + + SAVEREG_TO_CMOS 319ch,ax + + ; ďoSS:SP̕ + pop ax ; sp + SAVEREG_TO_CMOS 31a0h,ax + pop ax ; ss + mov ss,ax + LOADREG_FROM_CMOS 31a0h,ax + mov sp,ax + + LOADREG_FROM_CMOS 319ch,ax + mov dx,bp + pop bp + retf + + +;--------------------------------------------------------------------- +; efoCXL̏LqR[hCN[h + +%include "sys_cd.asm" +%include "sys_fd.asm" +%include "sys_hd.asm" +%include "sys_osr.asm" + +%include "sys_cmos.asm" + +%include "sys_p32.asm" + +;--------------------------------------------------------------------- +; EFCg(Âł͂܂Ӗ̂ŏȗ) + +waitloop: + retf + +;--------------------------------------------------------------------- + +invalid1: + jmp invalid1 + +invalid2: + jmp invalid2 + +invalid3: + jmp invalid3 + +invalid4: + jmp invalid4 + +invalid5: + jmp invalid5 + + +;--------------------------------------------------------------------- + + align 3000h, db 0 + +%rep 0fb0h + db 0 +%endrep + + JMPFAR invalid1 ; ffG[? + JMPFAR invalid2 ; ffG[? + JMPFAR invalid3 ; ? + JMPFAR invalid4 ; \() + JMPFAR disk_bios + JMPFAR cmos_bios + JMPFAR invalid5 ; \() + JMPFAR waitloop + + dd 0,0, 0,0,0,0 + + JMPFAR startall ; 炷ׂĂn܂ + + db 0,0,0 + dd 0,0 + diff --git a/source/src/vm/fmtowns/testcode/sys_cd.asm b/source/src/vm/fmtowns/testcode/sys_cd.asm new file mode 100644 index 000000000..c1171c32d --- /dev/null +++ b/source/src/vm/fmtowns/testcode/sys_cd.asm @@ -0,0 +1,392 @@ +; version 2003.03.04.1 +;--------------------------------------------------------------------- +; +; FM TOWNS ݊ ROM V[Y +; +; FMT_SYS.ROM : CDANZX +; +; by Kasanova +; +;--------------------------------------------------------------------- +; PƂł̓AZu܂ + + +%define CD_CMOS_PARA 3b60h +%define CD_CMOS_DATA 3b70h +%define CD_CMOS_DATA0 3b70h +%define CD_CMOS_DATA1 3b72h +%define CD_CMOS_DATA2 3b74h +%define CD_CMOS_DATA3 3b78h + +;--------------------------------------------------------------------- +; ǂݍ +; cl+dx : ǂݍ݊JnZN^ԍ(16i) +; bx : ǂݍރZN^ +; ds:di : ]AhX +; [^[R[h] +; ah : 0(I)Abx : ǂݎcZN^ + +cd_command_05: + call cd_test_ready + jc .error1 ; ANZXłԂłȂ + cmp word [es:di+2],0 ; bx + jz .error2 ; ǂݍރZN^sK + + ; ǂݍ݊JnZN^Zbg + mov bx,CD_CMOS_PARA + movzx dx,byte [es:di+4] ; cl + mov ax,[si+2] ; dx + call cd_set_sectorno + + ; ǂݍݏIZN^vZAZbg + movzx dx,byte [es:di+4] ; cl + mov ax,[si+2] ; dx + mov bx,[es:di+2] ; bx + dec bx + add ax,bx + adc dx,0 + mov bx,CD_CMOS_PARA+6 + call cd_set_sectorno + + ; DMA + call cd_init_dma + mov ax,[es:di+0ah] ; di + mov dx,[es:di+0ch] ; es + push dx + shl dx,4 + add ax,dx + pop dx + shr dx,12 + call cd_dma_setaddress + mov ax,7ffh + call cd_dma_setlength + in al,0afh + and al,7 + out 0afh,al + + ; ǂݍ݊Jn + mov al,022h + call cd_sendcommand + call cd_recieve4byte + + mov dx,CD_CMOS_DATA0 + in al,dx + or al,al + jnz .error3 ; R}hsG[ + +.readloop: + call cd_recieve4byte + mov dx,CD_CMOS_DATA0 + in al,dx + cmp al,22h + jz .transfer + cmp al,6 + jz .exit + jmp .error3 ; G[Aُȃ^[R[h + +.transfer: + call cd_dma_transfer + call cd_dma_getaddress + call cd_dma_setaddress + dec word [es:di+2] ; bx ǂݎcZN^炷 + jmp .readloop + +.exit: + in al,0afh + or al,8 + out 0afh,al + xor ah,ah + call cd_store_result + ret + +.error3: + in al,0afh + or al,8 + out 0afh,al +.error2: + mov ah,80h + mov cx,2 +.error1: + call cd_store_result + ret + + +;--------------------------------------------------------------------- + +; hCȕԂ`FbN +cd_command_0e: + call cd_test_ready + call cd_store_result + ret + + +;--------------------------------------------------------------------- +; + +; R}hsʂi[ +cd_store_result: + mov [si+1],ah + or ah,ah + jns .noerrorcode + mov [es:di+4],cx +.noerrorcode: + ret + +;---------- + +; CDǂݍ݉”\`FbN +cd_test_ready: + call cd_recieve + call cd_clear_parabuffer + mov al,0a0h + call cd_sendcommand + call cd_recieve4byte + + mov dx,CD_CMOS_DATA1 + in al,dx + and al,0fh + + mov ah,80h + cmp al,9 ; mbgfB + jnz .j1 + mov cx,1 + stc + ret +.j1: + xor ah,ah + clc + ret + +;---------- + +; p[^i[obt@NA +cd_clear_parabuffer: + push cx + push dx + mov dx,CD_CMOS_PARA + xor al,al + mov cx,8 +.loop: + out dx,al + add dx,2 + loop .loop + pop dx + pop cx + ret + +;---------- + +; CDCR}hs +cd_sendcommand: + push bx + push cx + push dx + mov ah,al + mov dx,4c0h +.waitready: + in al,dx + test al,1 + jz .waitready + + mov bx,CD_CMOS_PARA + mov cx,8 +.commandloop: + mov dx,bx + in al,dx + mov dx,4c4h + out dx,al + add bx,2 + loop .commandloop + + mov al,ah + mov dx,4c2h + out dx,al + pop dx + pop cx + pop bx + ret + +;---------- + +; CDC4oCg̃Xe[^X擾 +cd_recieve4byte: + push ax + push dx + mov dx,4c0h +.loop: + in al,dx + test al,2 + jz .loop + + or al,al + + mov dx,4c2h + in al,dx + mov dx,CD_CMOS_DATA0 + out dx,al + mov dx,4c2h + in al,dx + mov dx,CD_CMOS_DATA1 + out dx,al + mov dx,4c2h + in al,dx + mov dx,CD_CMOS_DATA2 + out dx,al + mov dx,4c2h + in al,dx + mov dx,CD_CMOS_DATA3 + out dx,al + + jns .exit + + mov dx,4c0h ; clear irq + mov al,80h + out dx,al + +.exit: + pop dx + pop ax + ret + +;---------- + +; H׎cNA +cd_recieve: + push dx + mov dx,4c0h + in al,dx + test al,2 + jz .exit + +.loop: + call cd_recieve4byte + in al,dx + test al,2 + jnz .loop +.exit: + pop dx + ret + +;---------- + +; 10iϊ +cd_hextodecimal: + push cx + mov ch,ah + xor ah,ah + mov cl,10 + div cl + shl al,4 + add al,ah + mov ah,ch + pop cx + ret + +;---------- + +; CD̃ZN^ԍ10iɕϊĕۊ +cd_set_sectorno: + push bx + push cx + push dx + add ax,150 ; CD̐擪ZN^̓ZN^150 + adc dx,0 + mov cx,75*60 ; M-S-F M + div cx + xchg ax,dx + ; dx = M, ax = S-F + mov cl,75 ; S + div cl + mov cl,dl + xchg al,ah + + ; cl-ah-al : M-S-F + + lea dx,[bx+4] + call cd_hextodecimal + out dx,al + sub dx,2 + mov al,ah + call cd_hextodecimal + out dx,al + sub dx,2 + mov al,cl + call cd_hextodecimal + out dx,al + pop dx + pop cx + pop bx + ret + +;---------- + +cd_init_dma: + ; Zbg + mov al,3 + out 0a0h,al + + ; `l CD ɃZbg + mov al,3 + out 0a1h,al + + ; DMA֎~ + mov al,24h + out 0a8h,al + + ; foCXRg[ + xor al,al + out 0a9h,al + + ; [hRg[ + mov al,54h + out 0aah,al + ret + +;---------- + +cd_dma_setlength: + out 0a2h,ax + ret + +;---------- + +cd_dma_setaddress: + out 0a4h,ax + mov ax,dx + out 0a6h,ax + ret + +;---------- + +cd_dma_getaddress: + in ax,0a6h + mov dx,ax + in ax,0a4h + ret + +;---------- + +; DMA]s +cd_dma_transfer: + push dx + ; DMA싖 + mov al,20h + out 0a8h,al + + ; ]Jn + mov dx,4c6h + mov al,10h + out dx,al + + ; ]I܂ő҂ + mov dx,4c0h +.loop: + in al,dx + test al,10h + jnz .loop + + ; DMA֎~ + mov al,24h + out 0a8h,al + pop dx + ret diff --git a/source/src/vm/fmtowns/testcode/sys_cmos.asm b/source/src/vm/fmtowns/testcode/sys_cmos.asm new file mode 100644 index 000000000..ff620a725 --- /dev/null +++ b/source/src/vm/fmtowns/testcode/sys_cmos.asm @@ -0,0 +1,569 @@ +; version 2003.03.04.1 +;--------------------------------------------------------------------- +; +; FM TOWNS ݊ ROM V[Y +; +; FMT_SYS.ROM : CMOS BIOS +; +; by Kasanova +; +;--------------------------------------------------------------------- +; PƂł̓AZu܂ + + +;--------------------------------------------------------------------- + +cmos_command_xx: + jmp $ + +;--------------------------------------------------------------------- + +cmos_command_fd: + jmp $ + +;--------------------------------------------------------------------- + +; init. cmos +cmos_command_00: + mov ax,cs + mov ds,ax + + ; ܂NA + xor dx,dx + xor al,al + mov cx,0a8h +.loop1: + call cmos_write1byte + inc dx + loop .loop1 + + ; f[^] + xor dx,dx + mov si,.initdata + mov cx,.initdata_end-.initdata +.loop2: + lodsb + call cmos_write1byte + inc dx + loop .loop2 + + mov dx,0a0h + mov si,.initdata2 + mov cx,8 +.loop3: + lodsb + call cmos_write1byte + inc dx + loop .loop3 + + mov dx,0a0h + call cmos_read2byte + mov dx,ax +.loop4: + push dx + xor ax,ax + call cmos_write1byte + pop dx + inc dx + cmp dx,7c1h + jc .loop4 + + call cmos_init_blocknotable + + call cmos_get_cmosheadersum + mov dx,0a4h + call cmos_write2byte + + ; `FbNTe[u + xor ax,ax + xor cl,cl +.loop5: + push ax + call cmos_write_3f82 + pop ax + inc al + cmp al,10h + jc .loop5 + + xor ah,ah + ret + + ; cmos̃f[^ubN`f[^ +.initdata: + db 1,0ffh ; ubN݃tO{ubNԍH + db 'BOOT' ; ʎq + dw 00a8h, 0040h ; cmos̃AhXƃTCY + + db 1,0feh + db 'SETU' + dw 00e8h, 0100h + + db 1,0fdh + db 'LOG ' + dw 01e8h, 0310h + + db 1,0fch + db 'OASY' + dw 04f8h, 0020h + + db 1,0fbh + db 'XENI' + dw 0518h, 0010h + + db 1,0fah + db 'TOWN' + dw 0528h, 0100h +.initdata_end: + +.initdata2: + db 28h,06h,99h,01h, 00h,00h,79h,41h + +;--------------------------------------------------------------------- + +cmos_command_01: + jmp $ + +;--------------------------------------------------------------------- + +cmos_command_02: + jmp $ + +;--------------------------------------------------------------------- + +cmos_command_03: + jmp $ + +;--------------------------------------------------------------------- + +cmos_command_04: + jmp $ + +;--------------------------------------------------------------------- + +; CMOSa2hԒn̏bxɕԂ +cmos_command_05: + mov dx,0a2h + call cmos_read2byte + mov [bp+4],ax ; bx + xor ah,ah + ret + +;--------------------------------------------------------------------- + +cmos_command_06: + jmp $ + +;--------------------------------------------------------------------- + +; transfer block to cmos +cmos_command_10: + ; ͈̓`FbN + mov cl,[bp+6] ; cl + mov al,[bp+2] ; al + call cmos_check_blockvalidity + or ah,ah + jnz .exit1 + call cmos_check_transferrange + or ah,ah + jnz .exit1 + + ; ]ʂ 0 Ȃ牽Ȃ + or bx,bx + jnz .starttransfer +.exit1: + ret + +.starttransfer: + mov si,[bp+0eh] ; di + mov ds,[bp+10h] ; ds + mov cx,bx +.loop: + lodsb + call cmos_write1byte + inc dx + loop .loop + + movzx ax,byte [bp+2] + mov dx,ax + add dx,dx ; dx<-ax*10 + add dx,dx + add dx,dx + add dx,ax + add dx,ax + call cmos_read1byte + or al,al + jns .exit2 + + call cmos_calc_checksum + mov cl,al + mov al,[bp+2] + call cmos_write_3f82 +.exit2: + xor ah,ah + ret + +;--------------------------------------------------------------------- + +; transfer block from cmos +cmos_command_11: + ; ͈̓`FbN + mov cl,[bp+6] ; cl + mov al,[bp+2] ; al + call cmos_check_blockvalidity + or ah,ah + jnz .exit1 + call cmos_check_transferrange + or ah,ah + jnz .exit1 + + ; ]ʂ 0 Ȃ牽Ȃ + or bx,bx + jnz .starttransfer +.exit1: + ret + +.starttransfer: + mov di,[bp+0eh] ; di + mov es,[bp+10h] ; ds + mov cx,bx +.loop: + call cmos_read1byte + stosb + inc dx + loop .loop + xor ah,ah + ret + +;--------------------------------------------------------------------- +; cmoswb_ƊeubÑ`FbN +; out: ah != 0 : wb_ُ +; ah == 0 : wb_AbxɃ`FbNTȂ +; ubNrbgPʂŃZbg +cmos_command_20: + mov dx,0a6h + call cmos_read2byte + cmp ax,4179h ; wb_̎ʎqHl̂ɈӖ邩s + jz .next + mov ah,3 + ret +.next: + call cmos_get_cmosheadersum + mov bx,ax + mov dx,0a4h + call cmos_read2byte + cmp bx,ax + mov cx,20h + mov ah,80h + jnz .j1 + call cmos_check_allblocks +.j1: + mov [bp+4],bx ; bx + ret + +;--------------------------------------------------------------------- +; CMOS BIOS + +; CMOSAhXI/OAhXɕϊ +; in dx:cmos address -> out dx:i/o address +cmos_getaddress: + cmp dx,7c0h + ja .over + + add dx,dx + add dx,3000h + xor ax,ax + ret +.over: + push cx + sub dx,7c1h + mov cx,800h + mov ax,dx + xor dx,dx + div cx + inc ax + add dx,dx + add dx,3000h + pop cx + ret + +;-------------------------------------- + +cmos_read1byte: + push dx + call cmos_getaddress + in al,dx + pop dx + ret + +;-------------------------------------- + +cmos_read2byte: + push cx + push dx + call cmos_read1byte + mov cl,al + inc dx + call cmos_read1byte + mov ah,cl + xchg al,ah + pop dx + pop cx + ret + +;-------------------------------------- + +cmos_write1byte: + push dx + push ax + call cmos_getaddress + pop ax + out dx,al + pop dx + ret + +;-------------------------------------- + +cmos_write2byte: + push dx + push ax + call cmos_write1byte + inc dx + mov al,ah + call cmos_write1byte + + pop ax + pop dx + ret + +;-------------------------------------- +; `FbNTe[uǂݍ + +cmos_read_3f82: + movsx dx,al + add dx,dx + add dx,3f82h + in al,dx + mov cl,al + ret + +;-------------------------------------- +; `FbNTe[u + +cmos_write_3f82: + movsx dx,al + add dx,dx + add dx,3f82h + mov al,cl + out dx,al + ret + +;-------------------------------------- +; ubNԍe[uǂݍ + +cmos_read_3fa2: + push dx + add dx,dx + add dx,3fa2h + in al,dx + pop dx + ret + +;-------------------------------------- +; ubNԍe[u + +cmos_write_3fa2: + push dx + add dx,dx + add dx,3fa2h + out dx,al + pop dx + ret + +;-------------------------------------- + +; w肳ꂽcmosubÑ`FbNTԂ +; in al: block no +cmos_calc_checksum: + push bx + call cmos_getaddlength + xor bl,bl +.loop: + call cmos_read1byte + add bl,al + inc dx + loop .loop + xor ax,ax + sub al,bl + pop bx + ret + +;-------------------------------------- + +; w肳ꂽcmosubÑAhXƒԂ +; in : al: no +; out: cx:length, dx:cmos address +cmos_getaddlength: + xor ah,ah ; dx<-ax*10 + mov dx,ax + add dx,dx + add dx,dx + add dx,dx + add dx,ax + add dx,ax + + add dx,8 + call cmos_read2byte + mov cx,ax ; length + + sub dx,2 + call cmos_read2byte + mov dx,ax ; address + ret + +;-------------------------------------- + +cmos_check_blockrange: + cmp al,10h + jc .j1 + mov ah,2 + ret +.j1: + xor ah,ah + ret + +;-------------------------------------- + +; ubN̗L`FbN +; in: al, cl +cmos_check_blockvalidity: + call cmos_check_blockrange + or ah,ah + jz .j1 + ret +.j1: + xor ah,ah ; dx<-ax*10 + mov dx,ax + add dx,dx + add dx,dx + add dx,dx + add dx,ax + add dx,ax + + mov bl,cl + push dx + call cmos_read2byte + ; ubNLH + test al,1 + jz .error + + mov cx,8 + cmp ah,bl + jnz .error + + xor ah,ah + pop dx + ret +.error: + mov cx,40h + mov ah,80h + pop dx + ret + +;-------------------------------------- + +; ]͈̗͂L`FbN +cmos_check_transferrange: + mov al,[bp+2] ; al + call cmos_getaddlength + mov di,[bp+8] ; dx + add di,[bp+4] ; bx + jc .error + cmp cx,di + jc .error + mov ax,[bp+8] ; dx + add dx,ax + mov bx,[bp+4] ; bx + xor ah,ah + ret +.error: + mov cx,4 + mov ah,80h + ret + +;-------------------------------------- + +; ubNԍe[u +cmos_init_blocknotable: + mov si,.initdata + xor dx,dx +.loop: + lodsb + call cmos_write_3fa2 + inc dx + cmp dx,10h + jc .loop + ret + +.initdata: + db 0,1,2,3,4, 255,255,255 + db 255,255,255,255, 255,255,255,255 + +;-------------------------------------- + +; 0-a4܂ł̒lZl𓾂 +cmos_get_cmosheadersum: + xor dx,dx + mov cx,52h + xor bx,bx +.loop: + push cx + call cmos_read2byte + pop cx + add bx,ax + add dx,2 + loop .loop + mov ax,bx + ret + +;-------------------------------------- + +; SubN`FbN +cmos_check_allblocks: + xor ax,ax + xor di,di + xor si,si +.loop: + mov dx,si + add dx,dx + add dx,dx + add dx,dx + add dx,si + add dx,si + call cmos_read1byte + or al,al + jns .next + + mov ax,si + call cmos_read_3f82 + mov ax,si + push cx + call cmos_calc_checksum + pop cx + + cmp al,cl + jz .next + + ; `FbNTG[̂ubNbiton + mov cx,si + mov ax,1 + shl ax,cl + or di,ax +.next: + inc si + cmp si,10h + jc .loop + mov bx,di + xor ah,ah + ret + + diff --git a/source/src/vm/fmtowns/testcode/sys_fd.asm b/source/src/vm/fmtowns/testcode/sys_fd.asm new file mode 100644 index 000000000..b3da3a5e0 --- /dev/null +++ b/source/src/vm/fmtowns/testcode/sys_fd.asm @@ -0,0 +1,29 @@ +; version 2003.03.04.1 +;--------------------------------------------------------------------- +; +; FM TOWNS ݊ ROM V[Y +; +; FMT_SYS.ROM : FDANZX +; +; by Kasanova +; +;--------------------------------------------------------------------- +; PƂł̓AZu܂ + +;--------------------------------------------------------------------- +; ǂݍ +; cl+dx : ǂݍ݊JnZN^ԍ(16i) +; bx : ǂݍރZN^ +; ds:di : ]AhX +; [^[R[h] +; ah : 0(I)Abx : ǂݎcZN^ + +fd_command_05: + ret + +;--------------------------------------------------------------------- +; hCȕԂ`FbN + +fd_command_0e: + ret + diff --git a/source/src/vm/fmtowns/testcode/sys_hd.asm b/source/src/vm/fmtowns/testcode/sys_hd.asm new file mode 100644 index 000000000..726ee2bbc --- /dev/null +++ b/source/src/vm/fmtowns/testcode/sys_hd.asm @@ -0,0 +1,32 @@ +; version 2003.03.04.1 +;--------------------------------------------------------------------- +; +; FM TOWNS ݊ ROM V[Y +; +; FMT_SYS.ROM : HDANZX +; +; by Kasanova +; +;--------------------------------------------------------------------- +; PƂł̓AZu܂ + +; SCSIRg[͖ʓ|̂ŁAHDANZX͂Âɓ +; 悤ɂ\ + +;--------------------------------------------------------------------- +; ǂݍ +; cl+dx : ǂݍ݊JnZN^ԍ(16i) +; bx : ǂݍރZN^ +; ds:di : ]AhX +; [^[R[h] +; ah : 0(I)Abx : ǂݎcZN^ + +hd_command_05: + ret + +;--------------------------------------------------------------------- +; hCȕԂ`FbN + +hd_command_0e: + ret + diff --git a/source/src/vm/fmtowns/testcode/sys_osr.asm b/source/src/vm/fmtowns/testcode/sys_osr.asm new file mode 100644 index 000000000..37b870d92 --- /dev/null +++ b/source/src/vm/fmtowns/testcode/sys_osr.asm @@ -0,0 +1,80 @@ +; version 2003.03.04.1 +;--------------------------------------------------------------------- +; +; FM TOWNS ݊ ROM V[Y +; +; FMT_SYS.ROM : RAM/ROMhCuANZX +; +; by Kasanova +; +;--------------------------------------------------------------------- +; PƂł̓AZu܂ + +;--------------------------------------------------------------------- +;l +; EfBAԍ 0x40 RAM邢ROMɐUꂽfBAԍł +; EANZX̕AhX́AfBAԍ̉4rbgɂČ܂ +; EIɂ386SXñ}bvl邱 +; +; 0: 00000000h- 7fffffffh +; 1: +; 2: c2000000h- c207ffffh (݋֎~) +; 3: +; 4: +; 5: +; 6: +; 7: 00000000h- ffffffffh (BYTEANZX) +; 8: 00000000h- ffffffffh (DWORDANZX) +; 9: c2000000h- c207ffffh (݋֎~) +; a: c0000000h- c007ffffh IC݃`FbN +; b: fffc0000h- ffffffffh (݋֎~) +; c: 80000000h- 8007ffffh +; d: 80100000h- 8017ffffh +; e: c2140000h- c2141fffh +; f: +; +;--------------------------------------------------------------------- + +;--------------------------------------------------------------------- +; ǂݍ݁ + +osrom_command_05: +osrom_command_06: + mov al,[si] + and al,0fh + + cmp al,8 ; Ƃ肠AꂾΉ + jz .ok + jmp $ +.ok: + ; WX^̏16rbgύXĂ͂Ȃ + pushad + + xor edx,edx + movzx esi,si + mov dx,ds + shl edx,4 + add esi,edx + + xor edx,edx + movzx edi,di + mov dx,es + shl edx,4 + add edi,edx + + ; X}[gȕ@l܂傤 + mov ax,PMODE_TRANSFERMEM + sub sp,6 + mov bp,sp + sgdt [bp] + push bp + call set_gdt + call call_pmode + pop bp + lgdt [bp] + add sp,6 + + popad + ret + + diff --git a/source/src/vm/fmtowns/testcode/sys_p32.asm b/source/src/vm/fmtowns/testcode/sys_p32.asm new file mode 100644 index 000000000..31aa256ad --- /dev/null +++ b/source/src/vm/fmtowns/testcode/sys_p32.asm @@ -0,0 +1,296 @@ +; version 2003.03.04.1 +;--------------------------------------------------------------------- +; +; FM TOWNS ݊ ROM V[Y +; +; FMT_SYS.ROM : veNg[hEvVW(EXT-BOOTɑ) +; +; by Kasanova +; +;--------------------------------------------------------------------- +; PƂł̓AZu܂ + +; R[hȂĂA@Ɠl 0xFFFE0000-0xFFFE7FFF +; ڂĂ + +[BITS 32] +pmode_entry: + movzx esp,sp + mov ebp,esp + mov ax,ss + movzx eax,ax + shl eax,4 + add esp,eax + + mov ax,10h + mov ss,ax + mov ds,ax + mov es,ax + + push ebp + movzx eax,bl + call [cs:pmode_jmptable+BOOTCODE_BASE+eax*4] + pop ebp + + mov esp,ebp + mov ax,20h + mov ds,ax + mov es,ax + mov ss,ax + + db 0eah + dd .flush + dw 18h +.flush: + +[BITS 16] + mov eax,cr0 + and al,0xfe + mov cr0,eax + jmp short $+2 + + db 0eah + dw return_from_pmode + dw 0fc00h + + +pmode_jmptable: + dd BOOTCODE_BASE+ pm_puticon + dd BOOTCODE_BASE+ pm_memorycheck + dd BOOTCODE_BASE+ pm_drawlogo + dd BOOTCODE_BASE+ pm_setpalette + dd BOOTCODE_BASE+ pm_transfermemory + + +[BITS 32] + +;--------------------------------------------------------------------- +; 32x32ACR\ +; +; cl = 0-127 : VXeACR +; cl = 128- : NpACR +pm_puticon: + movzx ecx,cl + cmp cl,128 + jc .sysicon + + ; NpACȐꍇ + sub ecx,128 + shl ecx,7 + lea esi,[0ffffbc00h+ecx] + jmp .draw + + ; VXeACȐꍇ +.sysicon: + shl ecx,8 + lea esi,[0fffe8000h+ecx] +.draw: + movzx edi,dx + add edi,0c0000h + mov ecx,20h +.loop: + movsd + add edi,VRAM_PITCH-4 + loop .loop + ret + + +;--------------------------------------------------------------------- +; `FbNCMOSւ̏o +; +; JEgōs悤ɁA32rbgR[hŏĂ܂ +pm_memorycheck: + ; 3150h-317eh́A̎Ԃ炵 + xor al,al + mov dx,3150h + mov ecx,30h/2 +.loop: + out dx,al + add dx,2 + loop .loop + + ; 5e8h́AÂł͕Kp”\ + mov dx,5e8h + in al,dx + and al,7fh + mov dx,3a5ch + out dx,al + movzx ecx,al + + mov al,1 + mov dx,3186h + out dx,al + + mov eax,ecx + shl eax,4 + dec eax + mov dx,318ah + out dx,al + sub dx,2 + mov al,ah + out dx,al + + dec ecx + jz .zero ; 1MBȂI + + mov al,0ffh + mov dx,3150h +.loop2: + out dx,al + dec ecx + jz .zero + add dx,2 + cmp dx,3180h + jc .loop2 +.zero: + mov dx,31ach + out dx,al + add dx,2 + out dx,al + + ; TOWNSJEgȂA + + ret + + +;--------------------------------------------------------------------- +; NS\ +pm_drawlogo: + ; ds = es + mov esi,LOGO_ADDRESS + mov edi,0c0000h+VRAM_PITCH*130 + movzx ebx,word [esi] ; hbg + add ebx,7 + shr ebx,3 + mov ecx,VRAM_PITCH ; \ʒuʒ + sub ecx,ebx + shr ecx,1 + add edi,ecx + movzx ecx,word [esi+2] ; hbg + + add esi,4 + + mov edx,0cff81h + mov al,[edx] + and al,0cfh +.loop: + push ecx + ; plane B + push edi + mov ecx,ebx + mov byte [edx],1 + rep movsb + pop edi + + ; plane R + push edi + mov ecx,ebx + mov byte [edx],2 + rep movsb + pop edi + + ; plane G + push edi + mov ecx,ebx + mov byte [edx],4 + rep movsb + pop edi + +%if(LOGO_USEPLANES==4) + ; plane I + push edi + mov ecx,ebx + mov byte [edx],8 + rep movsb + pop edi +%endif + + lea edi,[edi+VRAM_PITCH] + pop ecx + loop .loop + + mov [edx],al + ret + +;--------------------------------------------------------------------- +; pbg +; +; {̊G̃pbĝŁAftHgŒɂق +; ȂEEE + +pm_setpalette: + mov esi,LOGO_PAL_ADDRESS + cmp dword [esi], 0ffffffffh ; ÓL̃pbg邩H + jnz .palexist + mov esi,pm_def_palette+BOOTCODE_BASE +.palexist: + mov ecx,16 +.loop: + mov al,16 + sub al,cl + mov dx,0fd90h + out dx,al + mov al,[esi] + add dx,2 + out dx,al + mov al,[esi+1] + add dx,2 + out dx,al + mov al,[esi+2] + add dx,2 + out dx,al + add esi,3 + loop .loop + ret + +pm_def_palette: ; B - R - G B - R - G + db 0h, 0h, 0h, 80h, 0h, 0h + db 0h, 80h, 0h, 80h, 80h, 0h + db 0h, 0h, 80h, 80h, 0h, 80h + db 0h, 80h, 80h, 80h, 80h, 80h + + db 0h, 0h, 0h, 0ffh, 0h, 0h + db 0h,0ffh, 0h, 0ffh,0ffh, 0h + db 0h, 0h,0ffh, 0ffh, 0h,0ffh + db 0h,0ffh,0ffh, 0ffh,0ffh,0ffh + + +;--------------------------------------------------------------------- +; ԓ](sys_osr.asmĂ΂) +pm_transfermemory: + movzx ebp, byte [esi+1] ; ah̒lB]Ŕ肷 + + movzx ebx,word [edi+4] + shl ebx,16 + mov bx,[esi+2] + shl ebx,10 ; source + + push esi + push edi + + movzx esi,word [edi+0ch] + shl esi,4 + movzx ecx,word [edi+0ah] + add esi,ecx ; dest. + + mov ecx,400h + movzx eax,word [edi+2] ; block count + mul ecx + mov ecx,eax + + mov edi,esi + mov esi,ebx + + cmp ebp,5 + jz .noxchg + xchg esi,edi ; ݃R}hȂ]Ɠ]ւ +.noxchg: + + ; ]ۂ́AoCgANZX̂݉”\ȗ̈l邱 + rep movsb + + pop edi + pop esi + ret + + diff --git a/source/src/vm/fmtowns/timer.cpp b/source/src/vm/fmtowns/timer.cpp index 4afc0438d..509e0c3a8 100644 --- a/source/src/vm/fmtowns/timer.cpp +++ b/source/src/vm/fmtowns/timer.cpp @@ -8,33 +8,98 @@ [ timer ] */ -#include "timer.h" +#include "./timer.h" #include "../i8259.h" #include "../msm58321.h" #include "../pcm1bit.h" +#define EVENT_1US_WAIT 1 +#define EVENT_INTERVAL_US 2 + +namespace FMTOWNS { + void TIMER::initialize() { free_run_counter = 0; intr_reg = rtc_data = 0; tmout0 = tmout1 = false; + event_interval_us = -1; + event_wait_1us = -1; + rtc_busy = false; +} + +void TIMER::reset() +{ + interval_enabled = false; + interval_us.w = 0; + intv_i = false; + intv_ov = false; + + if(event_wait_1us >= 0) { + cancel_event(this, event_wait_1us); + event_wait_1us = -1; + } +// do_interval(); +} +void TIMER::write_io16(uint32_t addr, uint32_t data) +{ + switch(addr & 0xfffe) { + case 0x006a: // Interval control + interval_us.w = data; + do_interval(); + break; + default: + write_io8(addr, data); + break; + } } void TIMER::write_io8(uint32_t addr, uint32_t data) { switch(addr) { - case 0x60: + case 0x0060: if(data & 0x80) { tmout0 = false; } intr_reg = data; - update_intr(); d_pcm->write_signal(SIG_PCM1BIT_ON, data, 4); + update_intr(); break; - case 0x70: + case 0x0068: // Interval control + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + /* + if(!(interval_enabled)) {// OK? + intv_ov = false; + intv_i = false; + }*/ + interval_enabled = ((data & 0x80) == 0); + do_interval(); + } + break; + case 0x006a: // Interval control + case 0x006b: // Interval control + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + // Q: Do reset intv_i and intv_ov? 20200124 K.O + bool highaddress = (addr == 0x6b); + if(highaddress) { + interval_us.b.h = data; + } else { + interval_us.b.l = data; + } + do_interval(); + } + break; + case 0x006c: // Wait register. + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + if(event_wait_1us != -1) cancel_event(this, event_wait_1us); + register_event(this, EVENT_1US_WAIT, 1.0, false, &event_wait_1us); + write_signals(&outputs_halt_line, 0xffffffff); + } + break; + case 0x0070: d_rtc->write_signal(SIG_MSM58321_DATA, data, 0x0f); break; - case 0x80: + case 0x0080: d_rtc->write_signal(SIG_MSM58321_CS, data, 0x80); d_rtc->write_signal(SIG_MSM58321_READ, data, 0x04); d_rtc->write_signal(SIG_MSM58321_WRITE, data, 0x02); @@ -43,18 +108,91 @@ void TIMER::write_io8(uint32_t addr, uint32_t data) } } +void TIMER::do_interval(void) +{ + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + if(interval_enabled) { + uint32_t interval = interval_us.w; + if(interval == 0) interval = 65536; + // Update interval + if(event_interval_us >= 0) cancel_event(this, event_interval_us); + register_event(this, EVENT_INTERVAL_US, 1.0 * (double)interval, true, &event_interval_us); + } else { + if(event_interval_us >= 0) cancel_event(this, event_interval_us); + event_interval_us = -1; + } + } +} + +uint32_t TIMER::read_io16(uint32_t addr) +{ + switch(addr & 0xfffe) { + case 0x0026: + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + free_run_counter = (uint16_t)get_passed_usec(0); + return free_run_counter & 0xffff; + } else { + return 0xffff; + } + break; + case 0x006a: // Interval control + return interval_us.w; + break; + } + return read_io8(addr); +} + uint32_t TIMER::read_io8(uint32_t addr) { switch(addr) { - case 0x26: - free_run_counter = (uint16_t)get_passed_usec(0); - return free_run_counter & 0xff; - case 0x27: - return free_run_counter >> 8; - case 0x60: - return (tmout0 ? 1 : 0) | (tmout1 ? 2 : 0) | ((intr_reg & 7) << 2) | 0xe0; - case 0x70: - return rtc_data; + case 0x0026: + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + free_run_counter = (uint16_t)get_passed_usec(0); + return free_run_counter & 0xff; + } else { + return 0xff; + } + break; + case 0x0027: + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + return free_run_counter >> 8; + } else { + return 0xff; + } + break; + case 0x0060: + return (tmout0 ? 1 : 0) | (tmout1 ? 2 : 0) | ((intr_reg & 7) << 2) | 0x00; + case 0x0068: // + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + uint8_t val = (interval_enabled) ? 0x1f : 0x9f; + if(intv_i) val |= 0x40; + if(intv_ov) val |= 0x20; + intv_i = false; + intv_ov = false; + return val; + } + break; + case 0x006a: // Interval control + case 0x006b: // Interval control + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + bool highaddress = (addr == 0x6b); + if(highaddress) { + return interval_us.b.h; + } else { + return interval_us.b.l; + } + } + break; + case 0x006c: // Wait register. + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + //if(event_wait_1us != -1) cancel_event(this, event_wait_1us); + //register_event(this, EVENT_1US_WAIT, 1.0, false, &event_wait_1us); + //write_signals(&outputs_halt_line, 0xffffffff); + return 0x00; + } + break; + case 0x0070: + return (rtc_data & 0x7f) | ((rtc_busy) ? 0x80 : 0x00); } return 0xff; } @@ -69,47 +207,75 @@ void TIMER::write_signal(int id, uint32_t data, uint32_t mask) } else if(id == SIG_TIMER_CH1) { tmout1 = ((data & mask) != 0); update_intr(); + } else if(id == SIG_TIMER_CH2) { + //if((intr_reg & 4) != 0) { + // d_pcm->write_signal(SIG_PCM1BIT_SIGNAL, ((data & mask) != 0) ? 1 : 0, 1); + //} } else if(id == SIG_TIMER_RTC) { - rtc_data = (data & mask) | (rtc_data & ~mask); + rtc_data = data & mask; + } else if(id == SIG_TIMER_RTC_BUSY) { + rtc_busy = ((data & mask) == 0); } } void TIMER::update_intr() { - if((tmout0 && (intr_reg & 1)) || (tmout1 && (intr_reg & 2))) { - d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR0, 1, 1); + if((tmout0 && (intr_reg & 1)) || (tmout1 && (intr_reg & 2)) || (intv_i)) { + write_signals(&outputs_intr_line, 1); } else { - d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR0, 0, 1); + write_signals(&outputs_intr_line, 0); + } +} + +void TIMER::event_callback(int id, int err) +{ + switch(id) { + case EVENT_1US_WAIT: + event_wait_1us = -1; + if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H + write_signals(&outputs_halt_line, 0); + } + break; + case EVENT_INTERVAL_US: + if(interval_enabled) { + if(intv_i) intv_ov = true; + intv_i = true; + update_intr(); + } + break; } } #define STATE_VERSION 1 -void TIMER::save_state(FILEIO* state_fio) +bool TIMER::process_state(FILEIO* state_fio, bool loading) { - state_fio->FputUint32(STATE_VERSION); - state_fio->FputInt32(this_device_id); + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(machine_id); + state_fio->StateValue(cpu_id); + state_fio->StateValue(free_run_counter); + state_fio->StateValue(intr_reg); + state_fio->StateValue(rtc_data); + state_fio->StateValue(rtc_busy); - state_fio->FputUint16(free_run_counter); - state_fio->FputUint8(intr_reg); - state_fio->FputUint8(rtc_data); - state_fio->FputBool(tmout0); - state_fio->FputBool(tmout1); -} + state_fio->StateValue(tmout0); + state_fio->StateValue(tmout1); -bool TIMER::load_state(FILEIO* state_fio) -{ - if(state_fio->FgetUint32() != STATE_VERSION) { - return false; - } - if(state_fio->FgetInt32() != this_device_id) { - return false; - } - free_run_counter = state_fio->FgetUint16(); - intr_reg = state_fio->FgetUint8(); - rtc_data = state_fio->FgetUint8(); - tmout0 = state_fio->FgetBool(); - tmout1 = state_fio->FgetBool(); + state_fio->StateValue(interval_enabled); + state_fio->StateValue(interval_us); + state_fio->StateValue(intv_i); + state_fio->StateValue(intv_ov); + + state_fio->StateValue(event_wait_1us); + state_fio->StateValue(event_interval_us); + return true; } +} + diff --git a/source/src/vm/fmtowns/timer.h b/source/src/vm/fmtowns/timer.h index 1fbbd52ac..c6f9be1ff 100644 --- a/source/src/vm/fmtowns/timer.h +++ b/source/src/vm/fmtowns/timer.h @@ -15,46 +15,88 @@ #include "../../emu.h" #include "../device.h" -#define SIG_TIMER_CH0 0 -#define SIG_TIMER_CH1 1 -#define SIG_TIMER_RTC 2 +#define SIG_TIMER_CH0 0 +#define SIG_TIMER_CH1 1 +#define SIG_TIMER_CH2 2 +#define SIG_TIMER_RTC 3 +#define SIG_TIMER_RTC_BUSY 4 +namespace FMTOWNS { class TIMER : public DEVICE { private: - DEVICE *d_pcm, *d_pic, *d_rtc; + DEVICE *d_pcm, *d_rtc; + outputs_t outputs_intr_line; + outputs_t outputs_halt_line; uint16_t free_run_counter; uint8_t intr_reg, rtc_data; + bool rtc_busy; bool tmout0, tmout1; - void update_intr(); + + bool interval_enabled; + pair16_t interval_us; + bool intv_i; + bool intv_ov; + + int event_wait_1us; + int event_interval_us; + + uint16_t machine_id; + uint8_t cpu_id; + virtual void update_intr(); + virtual void do_interval(void); public: - TIMER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {} + TIMER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + machine_id = 0x0100; // FM-Towns 1,2 + initialize_output_signals(&outputs_intr_line); + initialize_output_signals(&outputs_halt_line); + } ~TIMER() {} // common functions - void initialize(); - void write_io8(uint32_t addr, uint32_t data); - uint32_t read_io8(uint32_t addr); - void write_signal(int id, uint32_t data, uint32_t mask); - void save_state(FILEIO* state_fio); - bool load_state(FILEIO* state_fio); + virtual void initialize(); + virtual void reset(); + virtual void __FASTCALL event_callback(int id, int err); + + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + void __FASTCALL write_io16(uint32_t addr, uint32_t data); + + uint32_t __FASTCALL read_io8(uint32_t addr); + uint32_t __FASTCALL read_io16(uint32_t addr); + + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + bool process_state(FILEIO* state_fio, bool loading); // unique functions - void set_context_pcm(DEVICE* device) + void set_machine_id(uint16_t val) { - d_pcm = device; + machine_id = val & 0xfff8; } - void set_context_pic(DEVICE* device) + void set_cpu_id(uint16_t val) { - d_pic = device; + cpu_id = val & 0x07; + } + void set_context_pcm(DEVICE* device) + { + d_pcm = device; } void set_context_rtc(DEVICE* device) { d_rtc = device; } + void set_context_intr_line(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&outputs_intr_line, dev, id, mask); + } + void set_context_halt_line(DEVICE *dev, int id, uint32_t mask) + { + register_output_signal(&outputs_halt_line, dev, id, mask); + } }; +} #endif diff --git a/source/src/vm/fmtowns/towns_cdrom.cpp b/source/src/vm/fmtowns/towns_cdrom.cpp index 285067b6a..eea02d0b9 100644 --- a/source/src/vm/fmtowns/towns_cdrom.cpp +++ b/source/src/vm/fmtowns/towns_cdrom.cpp @@ -7,430 +7,3401 @@ [FM-Towns CD-ROM based on SCSI CDROM] */ - +/* + * Note: Re-Write CD-ROM from SCSI_CDROM, but not related from SCSI_DEV. + * -- 20200411 K.O + */ #include "./towns_cdrom.h" +#include "./towns_dmac.h" #include "../../fifo.h" #include "../../fileio.h" -#include "../scsi_host.h" +#include "../debugger.h" + +//#include +//#include // SAME AS SCSI_CDROM:: -#define CDDA_OFF 0 +#define CDDA_OFF 0 #define CDDA_PLAYING 1 -#define CDDA_PAUSED 2 +#define CDDA_PAUSED 2 +#define CDDA_ENDED 3 // 0-99 is reserved for SCSI_DEV class -#define EVENT_CDDA 100 -#define EVENT_CDDA_DELAY_PLAY 101 -#define EVENT_CDROM_SEEK_SCSI 102 -#define EVENT_CDROM_DELAY_INTERRUPT_ON 103 -#define EVENT_CDROM_DELAY_INTERRUPT_OFF 104 -#define EVENT_CDDA_DELAY_STOP 105 +#define EVENT_CDDA 100 +#define EVENT_CDDA_DELAY_PLAY 101 +#define EVENT_CDROM_SEEK 102 +#define EVENT_CDROM_DELAY_INTERRUPT_ON 103 +#define EVENT_CDROM_DELAY_INTERRUPT_OFF 104 +#define EVENT_CDDA_DELAY_STOP 105 +#define EVENT_CDROM_SEEK_COMPLETED 106 +#define EVENT_CDROM_DRQ 107 +#define EVENT_CDROM_NEXT_SECTOR 108 +#define EVENT_CDROM_DELAY_READY 109 +#define EVENT_CDROM_READY_NOSTATUS 110 + +#define EVENT_CDROM_EOT 112 +#define EVENT_CDROM_RESTORE 113 +#define EVENT_CDROM_WAIT 114 +#define EVENT_CDROM_TIMEOUT 115 +#define EVENT_CDROM_READY_EOT 116 +#define EVENT_CDROM_READY_CDDAREPLY 117 -#define _SCSI_DEBUG_LOG -#define _CDROM_DEBUG_LOG +//#define _CDROM_DEBUG_LOG // Event must be larger than 116. + namespace FMTOWNS { -void TOWNS_CDROM::initialize() + +// crc table from vm/disk.cpp +const uint16_t TOWNS_CDROM::crc_table[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; + + + +uint16_t TOWNS_CDROM::calc_subc_crc16(uint8_t *databuf, int bytes, uint16_t initval) { - subq_buffer = new FIFO(32); // OK? - subq_overrun = false; - stat_track = 0; - SCSI_CDROM::initialize(); + uint16_t crc16 = initval; + for(int i = 0; i < bytes ; i++) { + crc16 = (uint16_t)((crc16 << 8) ^ crc_table[(uint8_t)(crc16 >> 8) ^ databuf[i]]); + } + return crc16; } - -void TOWNS_CDROM::release() + +void TOWNS_CDROM::cdrom_debug_log(const char *fmt, ...) { - subq_buffer->release(); - delete subq_buffer; - SCSI_CDROM::release(); + char strbuf[4096]; + va_list ap; + va_start(ap, fmt); + vsnprintf(strbuf, 4095, fmt, ap); + out_debug_log_with_switch(((__CDROM_DEBUG_LOG) || (force_logging)), + "%s", + strbuf); + va_end(ap); } -void TOWNS_CDROM::reset() +void TOWNS_CDROM::initialize() { - subq_buffer->clear(); + DEVICE::initialize(); +// __CDROM_DEBUG_LOG = osd->check_feature(_T("_CDROM_DEBUG_LOG")); + __CDROM_DEBUG_LOG = true; + _USE_CDROM_PREFETCH = osd->check_feature(_T("USE_CDROM_PREFETCH")); + force_logging = false; + subq_overrun = false; - stat_track = current_track; - SCSI_CDROM::reset(); + stat_track = 0; + status_queue = new FIFO(4); // 4 * (6 + 100 + 2) // With PAD + // ToDo: MasterDevice::initialize() + fio_img = new FILEIO(); + + memset(img_file_path_bak, 0x00, sizeof(img_file_path_bak)); + + if(44100 % emu->get_sound_rate() == 0) { + mix_loop_num = 44100 / emu->get_sound_rate(); + } else { + mix_loop_num = 0; + } + event_cdda = -1; + event_cdda_delay_play = -1; + event_delay_interrupt = -1; + event_drq = -1; + + event_next_sector = -1; + event_seek_completed = -1; + event_seek = -1; + event_delay_ready = -1; + event_cdda_delay_stop = -1; + event_time_out = -1; + event_eot = -1; + + // ToDo: larger buffer for later VMs. + max_fifo_length = ((machine_id == 0x0700) || (machine_id >= 0x0900)) ? 65536 : 8192; + fifo_length = 8192; +// fifo_length = 65536; + databuffer = new FIFO(max_fifo_length); + + cdda_status = CDDA_OFF; + is_cue = false; + is_iso = false; + current_track = 0; + read_sector = 0; + + transfer_speed = 1; + for(int i = 0; i < 99; i++) { + memset(track_data_path[i], 0x00, _MAX_PATH * sizeof(_TCHAR)); + } } -void TOWNS_CDROM::write_signal(int id, uint32_t data, uint32_t mask) +void TOWNS_CDROM::release() { - if(id == SIG_TOWNS_CDROM_SET_TRACK) { - if(((data < 100) && (data >= 0)) || (data == 0xaa)) { - stat_track = data; + if(fio_img != NULL) { + if(fio_img->IsOpened()) { + fio_img->Fclose(); } - return; + fio_img = NULL; + delete fio_img; + } + if(databuffer != NULL) { + databuffer->release(); + delete databuffer; + databuffer = NULL; } - SCSI_CDROM::write_signal(id, data, mask); + if(status_queue != NULL) { + status_queue->release(); + delete status_queue; + status_queue = NULL; + } + } -uint32_t TOWNS_CDROM::read_signal(int id) +void TOWNS_CDROM::reset() { - if(id == SIG_TOWNS_CDROM_IS_MEDIA_INSERTED) { - return ((is_device_ready()) ? 0xffffffff : 0x00000000); - } else if(id == SIG_TOWNS_CDROM_MAX_TRACK) { - if(track_num <= 0) { - return (uint32_t)(TO_BCD(0x00)); - } else { - return (uint32_t)(TO_BCD(track_num)); - } - } else if(id == SIG_TOWNS_CDROM_REACHED_MAX_TRACK) { - if(track_num <= 0) { - return 0xffffffff; - } else { - if(current_track >= track_num) { - return 0xffffffff; - } else { - return 0x00000000; - } - } - } else if(id == SIG_TOWNS_CDROM_CURRENT_TRACK) { - if(current_track > track_num) { - return 0x00000000; - } else { - return TO_BCD(current_track); - } - } else if(id == SIG_TOWNS_CDROM_START_MSF) { - int trk = stat_track; - if(trk <= 0) { - return 0xffffffff; - } - if(trk == 0xaa) { - trk = track_num; - } - int index0 = toc_table[trk].index0; - int index1 = toc_table[trk].index1 - int pregap = toc_table[trk].pregap - uint32_t lba = (uint32_t)index0; - if(pregap > 0) lba = lba - pregap; - if(lba < 150) lba = 150; - uint32_t msf = lba_to_msf(lba); // Q:lba + 150? - stat_track++; - return msf; - } eise if(id == SIG_TOWNS_CDROM_START_MSF_AA) { - trk = track_num; - int index0 = toc_table[trk].index0; - int index1 = toc_table[trk].index1 - int pregap = toc_table[trk].pregap - uint32_t lba = (uint32_t)index0; - if(pregap > 0) lba = lba - pregap; - if(lba < 150) lba = 150; - uint32_t msf = lba_to_msf(lba); // Q:lba + 150? - return msf; - } else if(id == SIG_TOWNS_CDROM_RELATIVE_MSF) { - if(toc_table[current_track].is_audio) { - if(!(is_device_ready())) { - return 0; - } - if(cdda_playing_frame <= cdda_start_frame) { - return 0; - } - uint32_t msf; - if(cdda_playing_frame >= cdda_end_frame) { - if(cdda_repeat) { - return 0; - } else { - msf = lba_to_msf(cdda_end_frame - cdda_start_frame); - return msf; - } - } - msf = lba_to_msf(cdda_playing_frame - cdda_start_frame); - return msf; - } else { - if(!(is_device_ready())) { - return 0; - } - if(fio_img->IsOpened()) { - uint32_t cur_position = (uint32_t)fio_img->Ftell(); - cur_position = cur_position / logical_block_size(); - if(cur_position >= max_logical_block) { - cur_position = max_logical_block; - } - uint32_t msf = lba_to_msf(cur_position); - return msf; - } - return 0; - } - } else if(id == SIG_TOWNS_CDROM_ABSOLUTE_MSF) { - if(toc_table[current_track].is_audio) { - if(!(is_device_ready())) { - return 0; + cdrom_debug_log("RESET"); + reset_device(); + // Q: Does not seek to track 0? 20181118 K.O +} + +void TOWNS_CDROM::set_dma_intr(bool val) +{ +// cdrom_debug_log(_T("set_dma_intr(%s) MASK=%s stat_reply_intr = %s"), +// (val) ? _T("true ") : _T("false"), +// (dma_intr_mask) ? _T("ON ") : _T("OFF"), +// (stat_reply_intr) ? _T("ON ") : _T("OFF")); + if(val) { + // At least, DMA interrupt mask is needed (by TownsOS v.1.1) 20200511 K.O + if(stat_reply_intr) { + dma_intr = true; + if(!(dma_intr_mask)) { +// if(mcu_intr) write_signals(&outputs_mcuint, 0x0); + write_mcuint_signals(0xffffffff); } - uint32_t msf; - msf = lba_to_msf(cdda_playing_frame); - return msf; } else { - if(!(is_device_ready())) { - return 0; - } - if(fio_img->IsOpened()) { - uint32_t cur_position = (uint32_t)fio_img->Ftell(); - cur_position = cur_position / logical_block_size(); - if(cur_position >= max_logical_block) { - cur_position = max_logical_block; - } - uint32_t msf = lba_to_msf(cur_position + toc_table[current_track].lba_offset); - return msf; - } - return 0; + dma_intr = true; } - } else if(id == SIG_TOWNS_CDROM_GET_ADR) { - int trk = stat_track; - if(!(is_device_ready())) { - return 0xffffffff; // OK? - } - if(trk == 0xaa) { - return 0x10; // AUDIO SUBQ - } - if(trk > track_num) { - return 0xffffffff; // OK? - } - if(toc_table[trk].is_audio) { - return 0x10; - } - return 0x14; // return as data - } - return SCSI_CDROM::read_signal(id); + } else { + dma_intr = false; + write_mcuint_signals(0x0); + } } -void TOWNS_CDROM::event_callback(int event_id, int err) +void TOWNS_CDROM::set_mcu_intr(bool val) { - SCSI_CDROM::event_callback(event_id, err); - if(event_id == EVENT_CDDA) { - // Post process - if(((cdda_buffer_ptr % 2352) == 0) && (cdda_status == CDDA_PLAYING)) { - set_subq(); - } +// cdrom_debug_log(_T("set_mcu_intr(%s) MASK=%s stat_reply_intr = %s"), +// (val) ? _T("true ") : _T("false"), +// (mcu_intr_mask) ? _T("ON ") : _T("OFF"), +// (stat_reply_intr) ? _T("ON ") : _T("OFF")); + if(stat_reply_intr) { + mcu_intr = val; + write_mcuint_signals((val) ? 0xffffffff : 0); + } else { + mcu_intr = val; } } -int TOWNS_CDROM::get_command_length(int value) +void TOWNS_CDROM::do_dma_eot(bool by_signal) { - switch(value) { - case TOWNS_CDROM_CDDA_PLAY: - return 10; - break; - case TOWNS_CDROM_CDDA_PAUSE: - return 4; - break; - case TOWNS_CDROM_CDDA_UNPAUSE: - return 4; - break; - case TOWNS_CDROM_CDDA_STOP: - return 4; - break; + static const _TCHAR by_dma[] = _T("SIGNAL"); + static const _TCHAR by_event[] = _T("EVENT"); + + dma_transfer_phase = false; + dma_transfer = false; + mcu_ready = false; + + dma_intr = true; +// mcu_intr = false; + + + clear_event(this, event_time_out); + clear_event(this, event_drq); + clear_event(this, event_eot); + + if((read_length <= 0) && (databuffer->empty())) { + clear_event(this, event_next_sector); + clear_event(this, event_seek_completed); + status_read_done(false); + cdrom_debug_log(_T("EOT(%s/DMA)"), (by_signal) ? by_dma : by_event); + } else { + cdrom_debug_log(_T("NEXT(%s/DMA)"), (by_signal) ? by_dma : by_event); + // TRY: Register after EOT. 20201123 K.O +// status_seek = true; +// register_event(this, EVENT_CDROM_SEEK_COMPLETED, +// 1000.0, +// false, +// &event_seek_completed); +// status_data_ready(false); } - - return SCSI_CDROM::get_command_length(value); + write_signals(&outputs_drq, 0x00000000); + if(!(dma_intr_mask) && (stat_reply_intr)) { + write_mcuint_signals(0xffffffff); + } + } -void TOWNS_CDROM::start_command() +void TOWNS_CDROM::write_signal(int id, uint32_t data, uint32_t mask) { - touch_sound(); - switch(command[0]) { - case TOWNS_CDROM_CDDA_PLAY: - play_cdda_from_cmd(); - return; + bool _b = ((data & mask) != 0); + + switch(id) { + case SIG_TOWNS_CDROM_CDDA_STOP: + if(cdda_status != CDDA_OFF) { + if(_b) set_cdda_status(CDDA_OFF); + } break; - case TOWNS_CDROM_CDDA_PAUSE: - pause_cdda_from_cmd(); - return; + case SIG_TOWNS_CDROM_CDDA_PLAY: + if(cdda_status != CDDA_PLAYING) { + if(_b) set_cdda_status(CDDA_PLAYING); + } break; - case TOWNS_CDROM_CDDA_UNPAUSE: - unpause_cdda_from_cmd(); - return; + case SIG_TOWNS_CDROM_CDDA_PAUSE: + if(cdda_status != CDDA_PAUSED) { + if(_b) set_cdda_status(CDDA_PAUSED); + } break; - case TOWNS_CDROM_CDDA_STOP: - stop_cdda_from_cmd(); - return; + case SIG_TOWNS_CDROM_SET_TRACK: + if(((data < 100) && (data >= 0)) || (data == 0xaa)) { + stat_track = data; + } break; - case SCSI_CMD_TST_U_RDY: - case SCSI_CMD_INQUIRY: - case SCSI_CMD_REQ_SENSE: - case SCSI_CMD_RD_DEFECT: - case SCSI_CMD_RD_CAPAC: - case SCSI_CMD_MODE_SEL6: // OK? - case SCSI_CMD_READ6: - case SCSI_CMD_READ10: - case SCSI_CMD_READ12: - SCSI_CDROM::start_command(); - set_subq(); // First - return; + case SIG_TOWNS_CDROM_RESET: + if((data & mask) != 0) { + reset_device(); + } break; - case 0xff: - // End of List - set_dat(SCSI_STATUS_CHKCOND); - return; + // By DMA/TC, EOT. + case SIG_TOWNS_CDROM_DMAINT: + if(((data & mask) != 0) && (dma_transfer_phase)) { + do_dma_eot(true); + } break; default: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Unknown %02X\n"), scsi_id, command[0]); - #endif - set_dat(SCSI_STATUS_GOOD); - set_phase_delay(SCSI_PHASE_STATUS, 10.0); + // ToDo: Implement master devices. + break; } + } - -// From MAME 0203's fmtowns.cpp . -void TOWNS_CDROM::pause_cdda_from_cmd() +void TOWNS_CDROM::status_not_ready(bool forceint) { - if(cdda_status == CDDA_PLAYING) { - set_cdda_status(CDDA_PAUSED); - //set_subq(); - } + cdrom_debug_log(_T("CMD (%02X) BUT DISC NOT ACTIVE"), latest_command); + set_status((forceint) ? true : req_status, 0, + TOWNS_CD_STATUS_CMD_ABEND, TOWNS_CD_ABEND_DRIVE_NOT_READY, 0, 0); } -void TOWNS_CDROM::unpause_cdda_from_cmd() +void TOWNS_CDROM::status_media_changed(bool forceint) { - if(cdda_status == CDDA_PAUSED) { - set_cdda_status(CDDA_PLAYING); - //set_subq(); + if(media_changed) { + set_status((forceint) ? true : req_status, 0, + TOWNS_CD_STATUS_CMD_ABEND, TOWNS_CD_ABEND_MEDIA_CHANGED, 0, 0); } + media_changed = false; } -void TOWNS_CDROM::stop_cdda_from_cmd() +void TOWNS_CDROM::status_hardware_error(bool forceint) { - set_cdda_status(CDDA_OFF); - set_subq(); + set_status((forceint) ? true : req_status, 0, + TOWNS_CD_STATUS_CMD_ABEND, TOWNS_CD_ABEND_HARDWARE_ERROR_04, 0, 0); } +void TOWNS_CDROM::status_parameter_error(bool forceint) +{ + set_status((forceint) ? true : req_status, 0, + TOWNS_CD_STATUS_CMD_ABEND, TOWNS_CD_ABEND_PARAMETER_ERROR, 0, 0); +} +void TOWNS_CDROM::status_read_done(bool forceint) +{ + if(forceint) stat_reply_intr = true; + set_status_read_done(req_status, 0, TOWNS_CD_STATUS_READ_DONE, 0, 0, 0); +// cdrom_debug_log(_T("READ DONE")); +} -void TOWNS_CDROM::play_cdda_from_cmd() +void TOWNS_CDROM::status_data_ready(bool forceint) { - uint8_t m_start = command[3]; - uint8_t s_start = command[4]; - uint8_t f_start = command[5]; - uint8_t m_end = command[7]; - uint8_t s_end = command[8]; - uint8_t f_end = command[9]; - if(is_device_ready()) { - cdda_start_frame = FROM_BCD(f_start) + (FROM_BCD(s_start) + FROM_BCD(m_start) * 60) * 75; - cdda_end_frame = FROM_BCD(f_end) + (FROM_BCD(s_end) + FROM_BCD(m_end) * 60) * 75; - int track = get_track(cdda_start_frame); - if(cdda_start_frame >= toc_table[track].pregap) { - cdda_start_frame -= toc_table[track].pregap; - } - if(cdda_start_frame < toc_table[track].index0) { - cdda_start_frame = toc_table[track].index0; // don't play pregap - } else if(cdda_start_frame > max_logical_block) { - cdda_start_frame = 0; + set_status((forceint) ? true : req_status, 0, TOWNS_CD_STATUS_DATA_READY, 0, 0, 0); +// cdrom_debug_log(_T("DATA READY")); +} + +void TOWNS_CDROM::status_illegal_lba(int extra, uint8_t s1, uint8_t s2, uint8_t s3) +{ + cdrom_debug_log(_T("Error on reading (ILLGLBLKADDR): EXTRA=%d s1=%02X s2=%02X s3=%02X LBA=%d POSITION=%d\n"), extra, s1, s2, s3, read_sector, position); + set_status(req_status, extra, TOWNS_CD_STATUS_CMD_ABEND, s1, s2, s3); +} + +void TOWNS_CDROM::status_accept(int extra, uint8_t s3, uint8_t s4) +{ + // Note: 2020-05-29 K.O + // Second byte (ARG s1) may below value (Thanks to Soji Yamakawa-San). + // 00h : NOT PLAYING CDDA + // 01h : DATA TRACK? (from Towns Linux) + // 03h : PLAYING CDDA + // 09h : MEDIA CHANGED? (from Towns Linux) + // 0Dh : After STOPPING CD-DA.Will clear. + // 01h and 09h maybe incorrect. + uint8_t playcode = TOWNS_CD_ACCEPT_DATA_TRACK; // OK? +// uint8_t playcode = next_status_byte; + + if((toc_table[current_track].is_audio) && (mounted())) { + if(cdda_status == CDDA_PLAYING) { + playcode = TOWNS_CD_ACCEPT_CDDA_PLAYING; + } else if(cdda_status == CDDA_ENDED) { + playcode = TOWNS_CD_ACCEPT_WAIT; + } else if(cdda_stopped) { + playcode = TOWNS_CD_ACCEPT_WAIT; + } else if(media_changed) { + playcode = TOWNS_CD_ACCEPT_MEDIA_CHANGED; + } else { + playcode = TOWNS_CD_ACCEPT_NOERROR; } - int track = current_track; - cdda_playing_frame = cdda_start_frame; - if(cdda_end_frame > toc_table[track + 1].index1 && (cdda_end_frame - toc_table[track].pregap) <= toc_table[track + 1].index1) { - auto_increment_track = true; + } else if(!(toc_table[current_track].is_audio) && (mounted())) { + if(media_changed) { + playcode = TOWNS_CD_ACCEPT_MEDIA_CHANGED; + } else if(((latest_command & 0xa0) == 0xa0) && (param_queue[0] == 0x08)) { +// playcode = TOWNS_CD_ACCEPT_08H_FOR_CMD_A0H; + playcode = TOWNS_CD_ACCEPT_NOERROR; +// playcode = 0x06; + } else if(((latest_command & 0xa0) == 0xa0) && (param_queue[0] == 0x04)) { + playcode = TOWNS_CD_ACCEPT_04H_FOR_CMD_A0H; + } else { + playcode = TOWNS_CD_ACCEPT_NOERROR; } - if(event_cdda_delay_play >= 0) { - cancel_event(this, event_cdda_delay_play); - event_cdda_delay_play = -1; + } else { + if(media_changed) { + playcode = TOWNS_CD_ACCEPT_MEDIA_CHANGED; } - register_event(this, EVENT_CDDA_DELAY_PLAY, 10.0, false, &event_cdda_delay_play); - } - set_subq(); // First -} -void TOWNS_CDROM::set_subq(void) + cdda_stopped = false; + media_changed = false; + set_status(req_status, extra, + TOWNS_CD_STATUS_ACCEPT, playcode, s3, s4); + next_status_byte = 0x00; +} + +void TOWNS_CDROM::send_mcu_ready() { - if(is_device_ready()) { - // create track info - int track = current_track; - uint32_t frame; - uint32_t msf_abs; - uint32_t msf_rel; - if(toc_table[track].is_audio) { // OK? (or force ERROR) 20181120 K.O - frame = (cdda_status == CDDA_OFF) ? cdda_start_frame : cdda_playing_frame; - msf_rel = lba_to_msf_alt(frame - toc_table[track].index0); - } else { // Data - if(fio_img->IsOpened()) { - uint32_t cur_position = (uint32_t)(fio_img->Ftell()); - if(is_cue) { - frame = (cur_position / physical_block_size()) + toc_table[track].lba_offset; - msf_rel = lba_to_msf_alt(frame - toc_table[track].lba_offset); - } else { - frame = cur_position / physical_block_size(); - if(frame > toc_table[track].lba_offset) { - msf_rel = lba_to_msf_alt(frame - toc_table[track].lba_offset); - } else { - msf_rel = lba_to_msf_alt(0); - } - } - } else { - frame = toc_table[track].lba_offset; - msf_rel = 0; - } - } - uint32_t msf_abs = lba_to_msf_alt(frame); - subq_overrun = !(subq_buffer->empty()); - subq_buffer->clear(); - // http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf - subq_buffer->write(0x01 | (toc_table[track].is_audio ? 0x00 : 0x40)); - - subq_buffer->write(TO_BCD(track + 1)); // TNO - subq_buffer->write(TO_BCD((cdda_status == CDDA_PLAYING) ? 0x00 : ((cdda_status == CDDA_PAUSED) ? 0x00 : 0x01))); // INDEX - subq_buffer->write(TO_BCD((msf_rel >> 16) & 0xff)); // M (relative) - subq_buffer->write(TO_BCD((msf_rel >> 8) & 0xff)); // S (relative) - subq_buffer->write(TO_BCD((msf_rel >> 0) & 0xff)); // F (relative) - subq_buffer->write(TO_BCD(0x00)); // Zero (relative) - subq_buffer->write(TO_BCD((msf_abs >> 16) & 0xff)); // M (absolute) - subq_buffer->write(TO_BCD((msf_abs >> 8) & 0xff)); // S (absolute) - subq_buffer->write(TO_BCD((msf_abs >> 0) & 0xff)); // F (absolute) - // transfer length - remain = subq_buffer->count(); - // set first data - // change to data in phase - //set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); - } else { - //write_signals(&output_subq_overrun, (subq_buffer->empty()) ? 0x00000000 : 0xffffffff); // OK? - subq_buffer->clear(); - // transfer length - remain = subq_buffer->count(); - set_dat(is_device_ready() ? SCSI_STATUS_GOOD : SCSI_STATUS_CHKCOND); - //set_phase_delay(SCSI_PHASE_STATUS, 10.0); - } - return; + mcu_ready = true; + set_mcu_intr(true); } -uint8_t TOWNS_CDROM::get_subq_status() +void TOWNS_CDROM::set_delay_ready() { - uint8_t val = 0x00; - val = val | ((subq_buffer->empty()) ? 0x00 : 0x01); - val = val | ((subq_overrun) ? 0x02 : 0x00); - return val; + // From Towns Linux 2.2 + // But, some software (i.e. Star Cruiser II) failes to loading at 300uS. + // May need *at least* 1000uS. - 20200517 K.O + force_register_event(this, EVENT_CDROM_DELAY_READY, 1000.0, false, event_delay_ready); } -uint8_t TOWNS_CDROM::read_subq() +void TOWNS_CDROM::set_delay_ready_nostatus() { - uint8_t val; -// if(subq_buffer->empty()) { -// set_subq(); -// } - val = (uint8_t)(subq_buffer->read() & 0xff); - return val; + // From Towns Linux 2.2 + // But, some software (i.e. Star Cruiser II) failes to loading at 300uS. + // May need *at least* 1000uS. - 20200517 K.O + force_register_event(this, EVENT_CDROM_READY_NOSTATUS, 1000.0, false, event_delay_ready); } -#define STATE_VERSION 1 +void TOWNS_CDROM::set_delay_ready_eot() +{ + force_register_event(this, EVENT_CDROM_READY_EOT, 1000.0, false, event_delay_ready); +} -bool TOWNS_CDROM::process_state(FILEIO* state_fio, bool loading) +void TOWNS_CDROM::set_delay_ready_cddareply() { - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - if(!(subq_buffer->process_state((void *)state_fio, loading))) { - return false; - } - state_fio->StateValue(subq_overrun); - state_fio->StateValue(stat_track); - - return SCSI_CDROM::process_state(state_fio, loading); + force_register_event(this, EVENT_CDROM_READY_CDDAREPLY, 100.0, false, event_delay_ready); } - - + +void TOWNS_CDROM::status_not_accept(int extra, uint8_t s1, uint8_t s2, uint8_t s3) +{ + set_status(req_status, extra, TOWNS_CD_STATUS_NOT_ACCEPT, s1, s2, s3); +} + +/*! + * @brief Execute CD-ROM command. + * @arg command CD-ROM command. + * @note structure of comman is below: + * @note Bit7 and Bit4-0 : command code + * @note Bit6 : Interrupt on status at '1' + * @note Bit5 : Require status (must read from queue).. + */ +void TOWNS_CDROM::execute_command(uint8_t command) +{ + set_mcu_intr(false); + clear_event(this, event_time_out); + latest_command = command; + + switch(command & 0x9f) { + case CDROM_COMMAND_SEEK: // 00h (RESTORE?) + { +// set_cdda_status(CDDA_OFF); + uint8_t m, s, f; + m = FROM_BCD(param_queue[0]); + s = FROM_BCD(param_queue[1]); + f = FROM_BCD(param_queue[2]); + int32_t lba = ((m * (60 * 75)) + (s * 75) + f) - 150; + if(lba < 0) lba = 0; + next_seek_lba = lba; + cdrom_debug_log(_T("CMD SEEK(%02X) M/S/F = %d/%d/%d M2/S2/F2 = %d/%d/%d LBA=%d"), command, + TO_BCD(m), TO_BCD(s), TO_BCD(f), + TO_BCD(param_queue[3]), TO_BCD(param_queue[4]), TO_BCD(param_queue[5]), + lba + ); + double usec = get_seek_time(0); // At first, seek to track 0. + if(usec < 10.0) usec = 10.0; + usec *= 2.0; + // 20200626 K.O + // At first, SEEK to LBA0. + // Next, SEEK TO ARG's LBA. + // Then, If set status to queue if (CMD & 20h) == 20h. + // Last, *FORCE TO MAKE* interrupt even (CMD & 20h) != 20h.. + // See event_callback(EVENT_CDROM_RESTORE, foo). + force_register_event(this, + EVENT_CDROM_RESTORE, + usec, false, event_seek); + } + break; + case CDROM_COMMAND_READ_MODE2: // 01h + cdrom_debug_log(_T("CMD READ MODE2(%02X)"), command); + read_cdrom_mode2(); +// status_not_accept(0, 0xff, 0xff, 0xff); + break; + case CDROM_COMMAND_READ_MODE1: // 02h + cdrom_debug_log(_T("CMD READ MODE1(%02X)"), command); + read_cdrom_mode1(); + break; + case CDROM_COMMAND_READ_RAW: // 03h + cdrom_debug_log(_T("CMD READ RAW(%02X)"), command); + read_cdrom_raw(); + break; + case CDROM_COMMAND_PLAY_TRACK: // 04h + cdrom_debug_log(_T("CMD PLAY TRACK(%02X)"), command); + play_cdda_from_cmd(); // ToDo : Re-Implement. +// play_cdda(req_status); + break; + case CDROM_COMMAND_READ_TOC: // 05h + cdrom_debug_log(_T("CMD READ TOC(%02X)"), command); + if(req_status) { + if(!(mounted())) { + status_not_ready(false); + break; + } + if((media_changed)) { + status_media_changed(false); + break; + } + status_accept(1, 0x00, 0x00); +// set_status(true, 1, TOWNS_CD_STATUS_ACCEPT, 0, 0, 0); + } else { + set_status(true, 2, TOWNS_CD_STATUS_TOC_ADDR, 0, 0xa0, 0); + } + // TOC READING + break; + case CDROM_COMMAND_READ_CDDA_STATE: // 06h + if(req_status) { + if(!(mounted())) { + status_not_ready(false); + break; + } + if((media_changed)) { + status_media_changed(false); + break; + } + status_accept(1, 0x00, 0x00); + } + cdrom_debug_log(_T("CMD SET CDDA STATE(%02X)"), command); + break; + case CDROM_COMMAND_1F: + cdrom_debug_log(_T("CMD UNKNOWN 1F(%02X)"), command); + if(req_status) { + if(!(mounted())) { + status_not_ready(false); + break; + } + if((media_changed)) { + status_media_changed(false); + break; + } + status_accept(0, 0x00, 0x00); + } + break; + case CDROM_COMMAND_SET_STATE: // 80h + cdrom_debug_log(_T("CMD SET STATE(%02X) PARAM=%02X %02X %02X %02X %02X %02X %02X %02X"), + command, + param_queue[0], + param_queue[1], + param_queue[2], + param_queue[3], + param_queue[4], + param_queue[5], + param_queue[6], + param_queue[7] + ); + if(req_status) { + // ToDo: + if(!(mounted())) { + status_not_ready(false); + break; + } + if((media_changed)) { + status_media_changed(false); + break;; + } + if(((cdda_status == CDDA_ENDED) || (cdda_status == CDDA_OFF)) + && ((prev_command & 0x9f) == CDROM_COMMAND_STOP_CDDA)) { + /// @note RANCEIII (and maybe others) polls until below status. + /// @note 20201110 K.O + set_status(req_status, 0, TOWNS_CD_STATUS_ACCEPT, TOWNS_CD_ACCEPT_WAIT, 0x00, 0x00); + if((cdda_status == CDDA_ENDED)) { + set_cdda_status(CDDA_OFF); + } + break; + } else if(cdda_status == CDDA_PLAYING) { + status_accept(1, 0x00, 0x00); + //set_status(req_status, 1, 0x00, TOWNS_CD_ACCEPT_CDDA_PLAYING, 0x00, 0x00); + break; + } if((cdda_status == CDDA_PAUSED) && + ((prev_command & 0x9f) == CDROM_COMMAND_PAUSE_CDDA)) { + /// @note SUPER READ MAHJONG PIV (and maybe others) polls until below status. + /// @note 20201110 K.O + set_status(req_status, 0, TOWNS_CD_STATUS_ACCEPT, TOWNS_CD_ACCEPT_WAIT, 0x00, 0x00); + break; + } + if(status_seek) { + if(!(toc_table[current_track].is_audio)) { + // @note In SUPER REAL MAHJONG PIV, maybe check below. + // @note 20201110 K.O + set_status(req_status, 0, TOWNS_CD_STATUS_ACCEPT, TOWNS_CD_ACCEPT_DATA_TRACK, 0x00, 0x00); + } else { + set_status(req_status, 0, TOWNS_CD_STATUS_ACCEPT, TOWNS_CD_ACCEPT_WAIT, 0x00, 0x00); + } + break; + } + status_accept(0, 0x00, 0x00); + } + break; + case CDROM_COMMAND_SET_CDDASET: // 81h +// stat_reply_intr = true; // OK? + cdrom_debug_log(_T("CMD CDDA SET(%02X)"), command); + if(req_status) { + if(!(mounted())) { + status_not_ready(false); + break; + } + if((media_changed)) { + status_media_changed(false); + break;; + } + status_accept(0, 0x00, 0x00); + } + break; + case CDROM_COMMAND_STOP_CDDA: // 84h + cdrom_debug_log(_T("CMD STOP CDDA(%02X)"), command); + ///@note From Tsugaru : 20200530 K.O + if((cdda_status != CDDA_ENDED) && (cdda_status != CDDA_OFF)) { + force_register_event(this, EVENT_CDDA_DELAY_STOP, 1000.0, false, event_cdda_delay_stop); + } else { + clear_event(this, event_cdda_delay_stop); + stop_cdda_from_cmd(); + next_status_byte = 0x0d; + } + break; + case CDROM_COMMAND_PAUSE_CDDA: // 85h + cdrom_debug_log(_T("CMD PAUSE CDDA2(%02X)"), command); + pause_cdda_from_cmd(); // ToDo : Re-Implement. + break; + case CDROM_COMMAND_RESUME_CDDA: // 87h + cdrom_debug_log(_T("CMD RESUME CDDA(%02X)"), command); + unpause_cdda_from_cmd(); + break; + default: + cdrom_debug_log(_T("CMD Illegal(%02X)"), command); + stat_reply_intr = true; // OK? + status_not_accept(0, 0x00, 0x00, 0x00); // ToDo: Will implement + break; + } +} + +void TOWNS_CDROM::set_status_extra(uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3) +{ + status_queue->write(s0); + status_queue->write(s1); + status_queue->write(s2); + status_queue->write(s3); + //cdrom_debug_log(_T("SET EXTRA STATUS %02x: %02x %02x %02x %02x EXTRA COUNT=%d"), latest_command, s0, s1, s2, s3, extra_status); + set_delay_ready(); +} + +void TOWNS_CDROM::set_status_extra_toc_addr(uint8_t s1, uint8_t s2, uint8_t s3) +{ + set_status_extra(TOWNS_CD_STATUS_TOC_ADDR, s1, s2, s3); + extra_status++; +} + +void TOWNS_CDROM::set_status_extra_toc_data(uint8_t s1, uint8_t s2, uint8_t s3) +{ + set_status_extra(TOWNS_CD_STATUS_TOC_DATA, s1, s2, s3); + extra_status++; +} + +uint8_t TOWNS_CDROM::read_status() +{ + uint8_t val = 0x00; + if(status_queue->empty()) { + return val; + } + val = status_queue->read(); + if(status_queue->empty()) { + has_status = false; + } + if((latest_command & 0x9f) == 0x80) { + cdrom_debug_log(_T("STAT: %02X"), val); + } + if((status_queue->empty()) && (extra_status > 0)) { + set_extra_status(); + } + return val; +} + +uint32_t TOWNS_CDROM::read_dma_io8(uint32_t addr) +{ + data_reg = (uint8_t)(databuffer->read() & 0xff); + if((databuffer->empty()) && (read_length <= 0)) { + //cdrom_debug_log(_T("EOT(DMA) by read_dma_io8()")); + read_length_bak = 0; + // Fallback + register_event(this, EVENT_CDROM_EOT, +// 0.2 * 1.0e6 / ((double)transfer_speed * 150.0e3 ), + 1.0e3, + false, &event_eot); + } + return data_reg; +} + +void TOWNS_CDROM::write_dma_io8(uint32_t addr, uint32_t data) +{ + // data_reg = data; + return; // OK? +} + +void TOWNS_CDROM::read_cdrom() +{ +// read_pos = 0; + if((cdda_status != CDDA_OFF) && (cdda_status != CDDA_ENDED)) { + // @note In SUPER REAL MAHJONG PIV, use PAUSE (A5h) command before reading. + // @note 20201110 K.O + set_cdda_status(CDDA_ENDED); + } else { + set_cdda_status(CDDA_OFF); + } + if(!(is_device_ready())) { + cdrom_debug_log(_T("DEVICE NOT READY")); + status_not_ready(false); + return; + } + + uint8_t m1, s1, f1; + uint8_t m2, s2, f2; +// uint8_t pad1, dcmd; + + m1 = FROM_BCD(param_queue[0]); + s1 = FROM_BCD(param_queue[1]); + f1 = FROM_BCD(param_queue[2]); + + m2 = FROM_BCD(param_queue[3]); + s2 = FROM_BCD(param_queue[4]); + f2 = FROM_BCD(param_queue[5]); + uint8_t pad1 = param_queue[6]; + uint8_t dcmd = param_queue[7]; + + int32_t lba1 = ((m1 * (60 * 75)) + (s1 * 75) + f1) - 150; + int32_t lba2 = ((m2 * (60 * 75)) + (s2 * 75) + f2) - 150; + + uint32_t __remain; + int track = 0; + extra_status = 0; + read_length = 0; + read_length_bak = 0; + + if((lba1 > lba2) || (lba1 < 0) || (lba2 < 0)) { // NOOP? + status_parameter_error(false); + return; + } + set_cdda_status(CDDA_OFF); + track = get_track(lba1); + + if((track <= 0) || (track >= track_num)) { + status_parameter_error(false); + return; + } + databuffer->clear(); + cdrom_debug_log(_T("READ_CDROM TRACK=%d LBA1=%d LBA2=%d M1/S1/F1=%02X/%02X/%02X M2/S2/F2=%02X/%02X/%02X PAD=%02X DCMD=%02X"), track, lba1, lba2, + param_queue[0], param_queue[1], param_queue[2], + param_queue[3], param_queue[4], param_queue[5], + pad1, dcmd); + position = lba1 * ((is_iso) ? 2048 : physical_block_size()); + __remain = (lba2 - lba1 + 1); + read_length = __remain * logical_block_size(); + read_length_bak = read_length; + read_sector = lba1; +// dma_transfer_phase = dma_transfer; + pio_transfer_phase = pio_transfer; + clear_event(this, event_drq); + clear_event(this, event_next_sector); + clear_event(this, event_seek_completed); + + // Kick a first + double usec = get_seek_time(lba1); + status_seek = true; + register_event(this, EVENT_CDROM_SEEK_COMPLETED, usec, false, &event_seek_completed); + if(req_status) { + // May not need extra status, integrated after reading. 20200906 K.O +// set_status(req_status, 0, 0x00, 0x00, 0x00, 0x00); + set_status(req_status, 2, 0x00, 0x00, 0x00, 0x00); + } else { + if(pio_transfer) { + set_status(true, 0, TOWNS_CD_STATUS_CMD_ABEND, 0x00, 0x00, 0x00); // OK? + } else { + set_status(true, 0, TOWNS_CD_STATUS_DATA_READY, 0x00, 0x00, 0x00); + } + } +} + +void TOWNS_CDROM::read_cdrom_mode1() +{ + read_mode = CDROM_READ_MODE1; + read_cdrom(); +} + +void TOWNS_CDROM::read_cdrom_mode2() +{ + read_mode = CDROM_READ_MODE2; + read_cdrom(); +} + +void TOWNS_CDROM::read_cdrom_raw() +{ + read_mode = CDROM_READ_RAW; + read_cdrom(); +} + +void TOWNS_CDROM::set_status(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3) +{ + status_queue->clear(); + extra_status = 0; + if(_req_status) { + if(extra > 0) extra_status = extra; + status_queue->write(s0); + status_queue->write(s1); + status_queue->write(s2); + status_queue->write(s3); + set_delay_ready(); + } else { + set_delay_ready_nostatus(); + } +} + +void TOWNS_CDROM::set_status_read_done(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3) +{ + status_queue->clear(); + extra_status = 0; +// if(_req_status) { + if(extra > 0) extra_status = extra; + status_queue->write(s0); + status_queue->write(s1); + status_queue->write(s2); + status_queue->write(s3); +// } else { +// set_delay_ready_eot(); +// } + set_delay_ready_eot(); + +} + +void TOWNS_CDROM::set_status_cddareply(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3) +{ + status_queue->clear(); + extra_status = 0; + if(_req_status) { + if(extra > 0) extra_status = extra; + status_queue->write(s0); + status_queue->write(s1); + status_queue->write(s2); + status_queue->write(s3); + } + set_delay_ready_cddareply(); +} + +void TOWNS_CDROM::set_status_immediate(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3) +{ + status_queue->clear(); + extra_status = 0; + if(_req_status) { + if(extra > 0) extra_status = extra; + status_queue->write(s0); + status_queue->write(s1); + status_queue->write(s2); + status_queue->write(s3); + } + if((_req_status) && (stat_reply_intr) && !(mcu_intr_mask)) { + write_mcuint_signals(0xffffffff); + } + mcu_ready = true; + mcu_intr = false; + dma_intr = false; +// dma_transfer_phase = true; +// pio_transfer_phase = false; +// cdrom_debug_log(_T("SET STATUS %02x: %02x %02x %02x %02x EXTRA=%d"), latest_command, s0, s1, s2, s3, extra_status); +} + +void TOWNS_CDROM::set_extra_status() +{ + switch(latest_command & 0x9f) { + case CDROM_COMMAND_SEEK: // seek + set_status_extra(TOWNS_CD_STATUS_SEEK_COMPLETED, 0x00, 0x00, 0x00); + extra_status = 0; + break; + case CDROM_COMMAND_READ_MODE1: + case CDROM_COMMAND_READ_MODE2: + case CDROM_COMMAND_READ_RAW: + if(extra_status == 2) { + set_status_extra(TOWNS_CD_STATUS_DATA_READY, 0, 0, 0); + } + extra_status = 0; + break; + case CDROM_COMMAND_PLAY_TRACK: // PLAY CDDA + set_status_extra(TOWNS_CD_STATUS_PLAY_DONE, 0, 0, 0); + extra_status = 0; + break; + case CDROM_COMMAND_READ_TOC: // 0x05 + switch(extra_status) { + case 1: + set_status_extra_toc_addr(0x00, 0xa0, 0x00); + break; + case 2: // st1 = first_track_number + set_status_extra_toc_data(TO_BCD(0x01), 0x00, 0x00); + break; + case 3: + set_status_extra_toc_addr(0x00, 0xa1, 0x00); + break; + case 4: + set_status_extra_toc_data(TO_BCD(track_num - 1), 0x00, 0x00); // OK? + break; + case 5: + set_status_extra_toc_addr(0x00, 0xa2, 0x00); + break; + case 6: + { + pair32_t msf; + msf.d= read_signal(SIG_TOWNS_CDROM_START_MSF_AA); + set_status_extra_toc_data(msf.b.h2, msf.b.h, msf.b.l); // OK? + stat_track = 1; + } + break; + default: + if((extra_status & 0x01) != 0) { +// stat_track = (extra_status - 2) >> 1; + uint32_t adr_control = cdrom_get_adr(stat_track); + set_status_extra_toc_addr(((adr_control & 0x0f) << 4) | ((adr_control >> 4) & 0x0f), TO_BCD((extra_status / 2) - 2), 0x00); + } else { + pair32_t msf; + msf.d = read_signal(SIG_TOWNS_CDROM_START_MSF); + cdrom_debug_log(_T("TRACK=%d M:S:F=%02X:%02X:%02X"), stat_track - 1, msf.b.h2, msf.b.h, msf.b.l); + set_status_extra_toc_data(msf.b.h2, msf.b.h, msf.b.l); // OK? + if((track_num <= 0) || (stat_track >= track_num)) { + extra_status = 0; // It's end. + } + } + break; + } + break; + case CDROM_COMMAND_SET_STATE: // 80h Thank to Yamakawa-San.20200626 K.O + if(extra_status > 0) { + set_status_extra(TOWNS_CD_STATUS_PLAY_DONE, 0x00, 0x00, 0x00); + extra_status = 0; + } + break; + case CDROM_COMMAND_READ_CDDA_STATE: // READ CDDA status + switch(extra_status) { + case 1: // Get current track + set_status_extra(TOWNS_CD_STATUS_SUBQ_READ, 0x00, read_signal(SIG_TOWNS_CDROM_CURRENT_TRACK), 0x00); + extra_status++; + break; + case 2: // Get current position + { + uint32_t msf = read_signal(SIG_TOWNS_CDROM_RELATIVE_MSF); + set_status_extra(0x19, (msf >> 16) & 0xff, (msf >> 8) & 0xff, msf & 0xff); + extra_status++; + } + break; + case 3: // Current_msf + { + uint32_t msf = read_signal(SIG_TOWNS_CDROM_ABSOLUTE_MSF); + set_status_extra(0x19, 0x00, (msf >> 16) & 0xff, (msf >> 8) & 0xff); + extra_status++; + } + break; + case 4: + { + uint32_t msf = read_signal(SIG_TOWNS_CDROM_ABSOLUTE_MSF); + set_status_extra(0x20, msf & 0xff, 0x00, 0x00); + extra_status = 0; + } + break; + } + break; + case CDROM_COMMAND_STOP_CDDA: + switch(extra_status) { + case 1: + set_status_extra(TOWNS_CD_STATUS_STOP_DONE, 0x00, 0x00, 0x00); + extra_status++; + break; + case 2: + set_status_extra(0x00, TOWNS_CD_ACCEPT_WAIT, 0x00, 0x00); + extra_status = 0; + break; + } + break; + case CDROM_COMMAND_PAUSE_CDDA: + if(extra_status == 1) { + set_status_extra(TOWNS_CD_STATUS_ACCEPT, 0x01, 0x00, 0x00); // From Tsugaru + extra_status++; + } else if(extra_status == 2) { + set_status_extra(TOWNS_CD_STATUS_PAUSE_DONE, 0x00, 0x00, 0x00); + extra_status = 0; + } + break; + case CDROM_COMMAND_RESUME_CDDA: + if(extra_status == 1) { + set_status_extra(TOWNS_CD_STATUS_ACCEPT, 0x00, 0x00, 0x00); // From Tsugaru + extra_status++; + } else if(extra_status == 2) { + set_status_extra(TOWNS_CD_STATUS_RESUME_DONE, 0x00, 0x00, 0x00); + extra_status = 0; + } + break; + } +} + +uint32_t TOWNS_CDROM::read_signal(int id) +{ + switch(id) { + case SIG_TOWNS_CDROM_READ_DATA: + return data_reg; + break; + case SIG_TOWNS_CDROM_PLAYING: + return (cdda_status == CDDA_PLAYING && cdda_interrupt) ? 0xffffffff : 0; + break; + case SIG_TOWNS_CDROM_SAMPLE_L: + return (uint32_t)abs(cdda_sample_l); + break; + case SIG_TOWNS_CDROM_SAMPLE_R: + return (uint32_t)abs(cdda_sample_r); + break; + case SIG_TOWNS_CDROM_IS_MEDIA_INSERTED: + return ((is_device_ready()) ? 0xffffffff : 0x00000000); + break; + case SIG_TOWNS_CDROM_MAX_TRACK: + if(track_num <= 0) { + return (uint32_t)(TO_BCD(0x00)); + } else { + return (uint32_t)(TO_BCD(track_num)); + } + break; + /* + case SIG_TOWNS_CDROM_REACHED_MAX_TRACK: + if(track_num <= 0) { + return 0xffffffff; + } else { + if(current_track >= track_num) { + return 0xffffffff; + } else { + return 0x00000000; + } + } + break; + */ + case SIG_TOWNS_CDROM_CURRENT_TRACK: + if(current_track > track_num) { + return 0x00000000; + } else { + return TO_BCD(current_track); + } + break; + case SIG_TOWNS_CDROM_START_MSF: + { + int trk = stat_track; + if(trk <= 0) { + return 0xffffffff; + } + if(trk == 0xaa) { + trk = track_num; + } + int index0 = toc_table[trk].index0; + int index1 = toc_table[trk].index1; + int pregap = toc_table[trk].pregap; + //if(pregap > 0) index0 = index0 + pregap; + //if(index0 < 150) index0 = 150; + uint32_t lba = (uint32_t)index0; + uint32_t msf = lba_to_msf(lba); // Q:lba + 150? + stat_track++; + return msf; + } + break; + case SIG_TOWNS_CDROM_START_MSF_AA: + { + int trk = track_num; + int index0 = toc_table[trk].index0; + int index1 = toc_table[trk].index1; + int pregap = toc_table[trk].pregap; + uint32_t lba = (uint32_t)index0; + if(pregap > 0) lba = lba + pregap; + if(lba < 150) lba = 150; + uint32_t msf = lba_to_msf(lba); // Q:lba + 150? + return msf; + } + break; + case SIG_TOWNS_CDROM_RELATIVE_MSF: + if(toc_table[current_track].is_audio) { + if(!(is_device_ready())) { + return 0; + } + if(cdda_playing_frame <= cdda_start_frame) { + return 0; + } + uint32_t msf; + if(cdda_playing_frame >= cdda_end_frame) { + if(cdda_repeat_count >= 0) { + return 0; + } else { + msf = lba_to_msf(cdda_end_frame - cdda_start_frame); + return msf; + } + } + msf = lba_to_msf(cdda_playing_frame - cdda_start_frame); + return msf; + } else { + if(!(is_device_ready())) { + return 0; + } + if(fio_img->IsOpened()) { + uint32_t cur_position = (uint32_t)fio_img->Ftell(); + cur_position = cur_position / (is_iso) ? 2048 : physical_block_size(); + if(cur_position >= max_logical_block) { + cur_position = max_logical_block; + } + uint32_t msf = lba_to_msf(cur_position); + return msf; + } + return 0; + } + break; + case SIG_TOWNS_CDROM_ABSOLUTE_MSF: + if(!(is_device_ready())) { + return 75 * 2; + } + if(cdda_status == CDDA_PLAYING) { + uint32_t msf; + if(cdda_end_frame > max_logical_block) { + msf = lba_to_msf(cdda_end_frame + 75 * 2); // With start gap + } else { + msf = lba_to_msf(cdda_playing_frame + 75 * 2); // With start gap + } + return msf; + } else { + return lba_to_msf(cdda_end_frame + 75 * 2); // With start gap + } + break; + case SIG_TOWNS_CDROM_GET_ADR: + return cdrom_get_adr(stat_track); + break; + default: + // ToDo: Implement master DEV + //return SCSI_DEV::read_signal(id); + break; + } + return 0; // END TRAM +} + +uint32_t TOWNS_CDROM::cdrom_get_adr(int trk) +{ + if(!(is_device_ready())) { + return 0xffffffff; // OK? + } + if(trk == 0xaa) { + return 0x10; // AUDIO SUBQ + } + if(trk > track_num) { + return 0xffffffff; // OK? + } + if(toc_table[trk].is_audio) { + return 0x10; + } + return 0x14; // return as data +} + +const int TOWNS_CDROM::physical_block_size() +{ + if(current_track <= 0) return 2352; // PAD + if(!mounted()) return 2352; // PAD + if(is_iso) return 2352; + switch(toc_table[current_track].type) { + case MODE_AUDIO: + return 2352; + case MODE_MODE1_2048: + return 2048; + case MODE_MODE1_2352: + case MODE_MODE2_2352: + case MODE_CDI_2352: + return 2352; + case MODE_MODE2_2336: + case MODE_CDI_2336: + return 2336; + case MODE_CD_G: + return 2448; + default: + break; + } + // OK? + return 2352; +} + +const int TOWNS_CDROM::logical_block_size() +{ + if(current_track <= 0) return 2352; // PAD + if(!mounted()) return 2352; // PAD + if(is_iso) return 2048; + switch(toc_table[current_track].type) { + case MODE_AUDIO: + return 2352; + case MODE_MODE1_2048: + case MODE_MODE1_2352: + return 2048; + case MODE_MODE2_2336: + case MODE_MODE2_2352: + case MODE_CDI_2336: + case MODE_CDI_2352: + return 2336; + case MODE_CD_G: + return 2448; + default: + break; + } + // OK? + return 2048; +} + + +void TOWNS_CDROM::event_callback(int event_id, int err) +{ + switch (event_id) { + case EVENT_CDROM_DELAY_INTERRUPT_ON: + write_mcuint_signals(0xffffffff); + event_delay_interrupt = -1; + break; + case EVENT_CDROM_DELAY_INTERRUPT_OFF: + write_mcuint_signals(0x0); + event_delay_interrupt = -1; + break; + case EVENT_CDROM_DELAY_READY: + event_delay_ready = -1; + has_status = true; + mcu_ready = true; + set_mcu_intr(true); + break; + case EVENT_CDROM_READY_NOSTATUS: // WITHOUT STATUS + event_delay_ready = -1; + mcu_ready = true; + set_mcu_intr(true); + break; + case EVENT_CDROM_READY_EOT: + event_delay_ready = -1; + mcu_ready = true; + has_status = true; +// has_status = (req_status) ? true : false; + if(/*(req_status) && */(stat_reply_intr)) { + set_mcu_intr(true); + } + break; + case EVENT_CDROM_READY_CDDAREPLY: + event_delay_ready = -1; + mcu_ready = true; + has_status = true; + mcu_intr = true; + if(stat_reply_intr) set_mcu_intr(true); + break; + case EVENT_CDDA_DELAY_PLAY: + status_seek = false; + if(cdda_status != CDDA_PLAYING) { + set_cdda_status(CDDA_PLAYING); + } + event_cdda_delay_play = -1; + access = true; + databuffer->clear(); + if(prefetch_audio_sectors(1) != 1) { + set_cdda_status(CDDA_OFF); + set_subq(); + access = false; + return; + } + break; + case EVENT_CDDA: + read_a_cdda_sample(); + return; + break; + case EVENT_CDDA_DELAY_STOP: + event_cdda_delay_stop = -1; + stop_cdda_from_cmd(); + next_status_byte = 0x0d; + break; + case EVENT_CDROM_RESTORE: + // Seek0 + event_seek = -1; + status_seek = true; + if(next_seek_lba <= 2) { + next_seek_lba = 2; + } + { + double usec = get_seek_time(next_seek_lba); + if(usec < 10.0) usec = 10.0; + usec *= 2.0; + register_event(this, + EVENT_CDROM_SEEK, + usec, false, &event_seek); + } + break; + case EVENT_CDROM_SEEK: + event_seek = -1; +// stat_reply_intr = true; + status_seek = false; + if(req_status) { + status_accept(1, 0x00, 0x00); + } + if((cdda_status != CDDA_OFF) && (mounted())) { + if((current_track >= 0) && (current_track < track_num) + && (toc_table[current_track].is_audio)) { // OK? + next_status_byte |= 0x03; + set_cdda_status(CDDA_OFF); + } + set_subq(); + } + if(!(req_status)) { + mcu_ready = true; + mcu_intr = true; + write_mcuint_signals(0xffffffff); + } + break; + case EVENT_CDROM_TIMEOUT: + status_seek = false; + event_time_out = -1; + set_status_immediate(req_status, 0, TOWNS_CD_STATUS_CMD_ABEND, TOWNS_CD_ABEND_RETRY, 0x00, 0x00); + cdrom_debug_log(_T("READ TIME OUT")); + break; + + case EVENT_CDROM_SEEK_COMPLETED: + event_seek_completed = -1; + status_seek = false; + //read_pos = 0; + clear_event(this, event_next_sector); + clear_event(this, event_time_out); + // ToDo: Prefetch 20201116 +// if((databuffer->left() < logical_block_size()) && (read_length > 0)) { +// if(!(databuffer->empty()) && (read_length > 0)) { +// register_event(this, EVENT_CDROM_SEEK_COMPLETED, +// (1.0e6 / ((double)transfer_speed * 150.0e3)) * +// 2.0, +// false, +// &event_seek_completed); +// break; // EXIT +// } + if(read_length > 0) { + mcu_ready = false; + bool stat = false; +// cdrom_debug_log(_T("READ DATA SIZE=%d BUFFER COUNT=%d"), logical_block_size(), databuffer->count()); + /// Below has already resolved! Issue of DMAC.20201114 K.O + // Note: Still error with reading D000h at TownsOS v1.1L30. + // Maybe data has changed to 1Fh from 8Eh. + /// 20200926 K.O + stat = read_buffer(1); + if((stat)) { +#if 1 + register_event(this, EVENT_CDROM_NEXT_SECTOR, + (1.0e6 / ((double)transfer_speed * 150.0e3)) * + ((double)(physical_block_size())) * + 1.0, // OK? + false, &event_next_sector); +#else + register_event(this, EVENT_CDROM_NEXT_SECTOR, + 5.0e3, // From TSUGARU + false, &event_next_sector); +#endif + } + //register_event(this, EVENT_CDROM_TIMEOUT, 1000.0e3, false, &event_time_out); + } /*else { + status_read_done(false); + }*/ + + break; + case EVENT_CDROM_NEXT_SECTOR: + event_next_sector = -1; + // BIOS FDDFCh(0FC0h:01FCh)- + if(pio_transfer) { + set_status(true, 0, TOWNS_CD_STATUS_CMD_ABEND, 0x00, 0x00, 0x00); // OK? + set_dma_intr(true); + } else { + status_data_ready(false); + } + // ToDo: Prefetch + status_seek = true; + register_event(this, EVENT_CDROM_SEEK_COMPLETED, + 100.0, + false, + &event_seek_completed); + break; + case EVENT_CDROM_DRQ: + // ToDo: Buffer OVERFLOW at PIO mode. + + if((dma_transfer_phase) && !(databuffer->empty())) { + write_signals(&outputs_drq, /*(drq_tick) ? 0xffffffff : 0x00000000*/ 0xffffffff); + } + //read_pos++; + break; + case EVENT_CDROM_EOT: + event_eot = -1; + clear_event(this, event_time_out); + if(dma_transfer_phase) { + do_dma_eot(false); + } + break; + default: + // ToDo: Another events. + //SCSI_DEV::event_callback(event_id, err); + break; + } +} + +bool TOWNS_CDROM::read_mode1_iso(int sectors) +{ + while(sectors > 0) { + cd_data_iso_t tmpbuf; + memset(&tmpbuf, 0x00, sizeof(tmpbuf)); + int tmp_length = sizeof(cd_data_iso_t); + if(!(seek_relative_frame_in_image(read_sector))) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + if(fio_img->Fread(&tmpbuf, tmp_length, 1) != 1) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + for(int i = 0; i < sizeof(tmpbuf.data); i++) { +// if(read_length < 0) { + // ToDo: Change to sector error. +// status_illegal_lba(0, 0x00, 0x00, 0x00); +// return false; +// } +// if(databuffer->full()) { + // ToDo: Change to buffer overflow +// status_illegal_lba(0, 0x00, 0x00, 0x00); +// return false; +// } + uint8_t value = tmpbuf.data[i]; + write_a_byte(value); + read_length--; + } + position += 2048; + read_sector++; + sectors--; + access = true; + } + return true; +} + +bool TOWNS_CDROM::read_mode1(int sectors) +{ + while(sectors > 0) { + cd_data_mode1_t tmpbuf; + int tmp_length = sizeof(cd_data_mode1_t); + memset(&tmpbuf, 0x00, sizeof(tmpbuf)); + if(!(seek_relative_frame_in_image(read_sector))) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + if(fio_img->Fread(&tmpbuf, tmp_length, 1) != 1) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + //! ToDo: Check header address. + pair32_t msf; + msf.d = lba_to_msf(read_sector + toc_table[current_track].pregap); + if((tmpbuf.header.addr_m != msf.b.h2) || + (tmpbuf.header.addr_s != msf.b.h) || + (tmpbuf.header.addr_f != msf.b.l)) { + out_debug_log(_T("WARNING: Reading from different sector MSF\nEXPECTED=%02X/%02X/%02X\nREAD =%02X/%02X/%02X"), + tmpbuf.header.addr_m, tmpbuf.header.addr_s, tmpbuf.header.addr_f, + msf.b.h2, msf.b.h, msf.b.l); + } + for(int i = 0; i < sizeof(tmpbuf.data); i++) { + if(read_length < 0) { + // ToDo: Change to sector error. + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + if(databuffer->full()) { + // ToDo: Change to buffer overflow + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + uint8_t value = tmpbuf.data[i]; + write_a_byte(value); + read_length--; + } + position += physical_block_size(); + read_sector++; + sectors--; + access = true; + } + return true; +} + +bool TOWNS_CDROM::read_mode2(int sectors) +{ + while(sectors > 0) { + cd_data_mode2_t tmpbuf; + memset(&tmpbuf, 0x00, sizeof(tmpbuf)); + int tmp_length = sizeof(cd_data_mode2_t); + if(!(seek_relative_frame_in_image(read_sector))) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + if(fio_img->Fread(&tmpbuf, tmp_length, 1) != 1) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + //! ToDo: Check header address. + pair32_t msf; + msf.d = lba_to_msf(read_sector + toc_table[current_track].pregap); + if((tmpbuf.header.addr_m != msf.b.h2) || + (tmpbuf.header.addr_s != msf.b.h) || + (tmpbuf.header.addr_f != msf.b.l)) { + out_debug_log(_T("WARNING: Reading from different sector MSF\nEXPECTED=%02X/%02X/%02X\nREAD =%02X/%02X/%02X"), + tmpbuf.header.addr_m, tmpbuf.header.addr_s, tmpbuf.header.addr_f, + msf.b.h2, msf.b.h, msf.b.l); + } + for(int i = 0; i < sizeof(tmpbuf.data); i++) { + if(read_length < 0) { + // ToDo: Change to sector error. + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + if(databuffer->full()) { + // ToDo: Change to buffer overflow + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + uint8_t value = tmpbuf.data[i]; + write_a_byte(value); + read_length--; + } + position += physical_block_size(); + read_sector++; + sectors--; + access = true; + } + return true; +} + + +bool TOWNS_CDROM::read_raw(int sectors) +{ + while(sectors > 0) { + uint8_t tmpbuf[2352]; + int tmp_length = 2352; + memset(tmpbuf, 0x00, sizeof(tmpbuf)); + if(!(seek_relative_frame_in_image(read_sector))) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + if(fio_img->Fread(tmpbuf, tmp_length, 1) != 1) { + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + for(int i = 0; i < 2352; i++) { + if(read_length < 0) { + // ToDo: Change to sector error. + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + if(databuffer->full()) { + // ToDo: Change to buffer overflow + status_illegal_lba(0, 0x00, 0x00, 0x00); + return false; + } + uint8_t value = tmpbuf[i]; + write_a_byte(value); + read_length--; + } + position += physical_block_size(); + read_sector++; + sectors--; + access = true; + } + return true; +} + +bool TOWNS_CDROM::read_buffer(int sectors) +{ + if(!(mounted())) { + status_not_ready(false); + return false; + } + if(media_changed) { + status_media_changed(false); + return false; + } + if(is_iso) return read_mode1_iso(sectors); + switch(read_mode) { + case CDROM_READ_MODE1: + return read_mode1(sectors); + break; // Below + case CDROM_READ_MODE2: + return read_mode2(sectors); + break; // Below + case CDROM_READ_RAW: + return read_raw(sectors); + break; // Below + default: + return false; + break; + } + return false; +} + +void TOWNS_CDROM::read_a_cdda_sample() +{ + if(event_cdda_delay_play > -1) { + // Post process + if(((cdda_buffer_ptr % 2352) == 0) && (cdda_status == CDDA_PLAYING)) { + set_subq(); +// return; // WAIT for SEEK COMPLETED + } + return; // WAIT for SEEK COMPLETED + } + // read 16bit 2ch samples in the cd-da buffer, called 44100 times/sec + pair16_t sample_l, sample_r; + if(databuffer->count() >= 4) { + sample_l.b.l = databuffer->read(); + sample_l.b.h = databuffer->read(); + sample_r.b.l = databuffer->read(); + sample_r.b.h = databuffer->read(); + cdda_sample_l = sample_l.sw; + cdda_sample_r = sample_r.sw; + } else { + return; + } + + cdda_buffer_ptr = cdda_buffer_ptr + 4; + bool force_seek = false; + if((cdda_buffer_ptr % 2352) == 0) { + // one frame finished + cdda_playing_frame++; + cdda_buffer_ptr = 0; + + if(cdda_playing_frame >= cdda_end_frame) { + if(cdda_repeat_count < 0) { + // Infinity Loop (from Towns Linux v2.2.26) + cdda_playing_frame = cdda_start_frame; + cdda_loading_frame = cdda_start_frame; + force_seek = true; + } else if(cdda_repeat_count == 0) { + set_cdda_status(CDDA_ENDED); + set_subq(); + access = false; + return; + } else { + cdda_playing_frame = cdda_start_frame; + cdda_loading_frame = cdda_start_frame; + force_seek = true; + cdda_repeat_count--; + if(cdda_repeat_count == 0) { + set_cdda_status(CDDA_ENDED); + set_subq(); + access = false; + return; + } + } + } + check_cdda_track_boundary(cdda_loading_frame); + if(force_seek) { + seek_relative_frame_in_image(cdda_loading_frame); + } + cdda_playing_frame = cdda_loading_frame; + if(databuffer->count() <= physical_block_size()) { + // Kick prefetch + if(event_next_sector < 0) { + // TMP: prefetch 2 sectors + prefetch_audio_sectors(2); + } + } + } + // Post process + if(((cdda_buffer_ptr % 2352) == 0) && (cdda_status == CDDA_PLAYING)) { + set_subq(); + } +} + +// -1 = End of sector. +int TOWNS_CDROM::prefetch_audio_sectors(int sectors) +{ + if(!(mounted())) { + status_not_ready(false); + return -1; + } + if(media_changed) { + status_media_changed(false); + return -1; + } + if(sectors < 1) { + return -1; + } + uint8_t tmpbuf[sectors * 2448 + 8]; + int n_sectors = 0; + int m_sectors = 0; + bool last_read = false; + while(sectors > 0) { + n_sectors = 0; + for(int i = 0; i < sectors; i++) { + cdda_loading_frame++; + if(cdda_loading_frame >= cdda_end_frame) { + last_read = true; + break; // OK? + } + if(check_cdda_track_boundary(cdda_loading_frame)) { + last_read = true; + break; // OK? + } + n_sectors++; + } + if(n_sectors >= 1) { + //access = true; + if(fio_img->Fread(tmpbuf, 2352 * n_sectors * sizeof(uint8_t), 1) != 1) { + set_cdda_status(CDDA_OFF); + set_subq(); + access = false; + return 0; + } + int bytes = 0; + if(config.swap_audio_byteorder[0]) { + int ip = 0; + for(int i = 0; i < n_sectors; i++) { + uint8_t tn[2352]; + for(int j = 0; j < 2352; j += 2) { + tn[j + 0] = tmpbuf[j + ip + 1]; + tn[j + 1] = tmpbuf[j + ip + 0]; + } + if(!(write_bytes(tn, 2352))) break; + ip += 2352; + bytes += 2352; + } + } else { + int ip = 0; + for(int i = 0; i < n_sectors; i++) { + if(!(write_bytes(&(tmpbuf[ip]), 2352))) break; + ip += 2352; + bytes += 2352; + } + } + if(bytes < (2352 * n_sectors)) { + return (bytes / 2352); + } + } + m_sectors += n_sectors; + if(last_read) { + break; + } + sectors -= n_sectors; + } + return m_sectors; +} + +void TOWNS_CDROM::set_cdda_status(uint8_t status) +{ + if(status == CDDA_PLAYING) { + if(mix_loop_num == 0) { + if(event_cdda < 0) { + register_event(this, EVENT_CDDA, 1.0e6 / 44100.0, true, &event_cdda); + } + } + if(cdda_status != CDDA_PLAYING) { + //// Notify to release bus. + write_mcuint_signals(0x0); + if((cdda_status == CDDA_OFF) || (cdda_status == CDDA_ENDED)) { + //get_track_by_track_num(current_track); // Re-Play + cdda_playing_frame = cdda_start_frame; + current_track = get_track(cdda_playing_frame); + seek_relative_frame_in_image(cdda_playing_frame); + cdda_buffer_ptr = 0; + access = false; + } else if(cdda_status == CDDA_PAUSED) { + // Unpause + //access = true; + } + touch_sound(); + set_realtime_render(this, true); + _TCHAR *pp = _T(""); + switch(cdda_status) { + case CDDA_OFF: + pp = _T("STOP"); + break; + case CDDA_PLAYING: + pp = _T("PLAY"); + break; + case CDDA_PAUSED: + pp = _T("PAUSE"); + break; + case CDDA_ENDED: + pp = _T("END"); + break; + } + cdrom_debug_log(_T("Play CDDA from %s.\n"), pp); + } + cdda_stopped = false; + } else { + clear_event(this, event_cdda); + if((cdda_status == CDDA_PLAYING) || (cdda_status == CDDA_ENDED)) { + // Notify to release bus. + write_mcuint_signals(0x0); + if(status == CDDA_OFF) { + databuffer->clear(); + cdda_buffer_ptr = 0; + read_sector = 0; + cdda_repeat_count = -1; // OK? + get_track_by_track_num(0); + cdda_stopped = true; + } + touch_sound(); + set_realtime_render(this, false); + _TCHAR *sp = _T(""); + _TCHAR *pp = _T(""); + + switch(status) { + case CDDA_OFF: + sp = _T("->STOP"); + break; + case CDDA_PLAYING: + sp = _T("->PLAY"); + break; + case CDDA_PAUSED: + sp = _T("->PAUSE"); + break; + case CDDA_ENDED: + sp = _T("->END"); + break; + } + switch(cdda_status) { + case CDDA_OFF: + pp = _T("STOP"); + break; + case CDDA_PLAYING: + pp = _T("PLAY"); + break; + case CDDA_PAUSED: + pp = _T("PAUSE"); + break; + case CDDA_ENDED: + pp = _T("END"); + break; + } + cdrom_debug_log(_T("Change CDDA status: %s%s"), pp, sp); + } + } + cdda_status = status; +} + +void TOWNS_CDROM::reset_device() +{ + set_cdda_status(CDDA_OFF); + memset(subq_buffer, 0x00, sizeof(subq_buffer)); + memset(param_queue, 0x00, sizeof(param_queue)); + memset(w_regs, 0x00, sizeof(w_regs)); + status_seek = false; + cdrom_prefetch = false; + + param_ptr = 0; + subq_overrun = false; + stat_track = current_track; + next_seek_lba = 0; + + extra_status = 0; + data_reg = 0x00; + position = 0; + mcu_ready = true; + has_status = false; + req_status = false; + next_status_byte = 0x00; + + cdda_repeat_count = -1; + touch_sound(); + clear_event(this, event_cdda); + clear_event(this, event_cdda_delay_play); + clear_event(this, event_cdda_delay_stop); + clear_event(this, event_delay_interrupt); + clear_event(this, event_seek_completed); + clear_event(this, event_drq); + clear_event(this, event_next_sector); + clear_event(this, event_seek); + clear_event(this, event_delay_ready); + clear_event(this, event_time_out); + clear_event(this, event_eot); + + read_length = 0; + read_length_bak = 0; + + media_changed = false; + + databuffer->clear(); + status_queue->clear(); + latest_command = 0x00; + prev_command = 0x00; + if(is_cue) { + if(fio_img->IsOpened()) { + fio_img->Fclose(); + } + } else { + if(fio_img->IsOpened()) { + fio_img->Fseek(0, FILEIO_SEEK_SET); + } + } + current_track = 0; + cdda_start_frame = 0; + cdda_end_frame = 0; + cdda_playing_frame = 0; + cdda_loading_frame = 0; + + read_sector = 0; + write_signals(&outputs_drq, 0); + mcu_intr = false; + dma_intr = false; + mcu_intr_mask = false; + dma_intr_mask = false; +// dma_transfer = true; + dma_transfer = false; + pio_transfer = false; + dma_transfer_phase = false; + pio_transfer_phase = false; + stat_reply_intr = false; + cdda_stopped = false; + write_mcuint_signals(0x0); + // Will Implement +} + +bool TOWNS_CDROM::is_device_ready() +{ + return mounted(); +} + + +void TOWNS_CDROM::get_track_by_track_num(int track) +{ + if((track <= 0) || (track >= track_num)) { + if(is_cue) { + if(fio_img->IsOpened()) fio_img->Fclose(); + } + current_track = 0; + return; + } + if(is_cue) { + // ToDo: Apply audio with some codecs. + if((current_track != track) || !(fio_img->IsOpened())){ + if(fio_img->IsOpened()) { + fio_img->Fclose(); + } + cdrom_debug_log(_T("LOAD TRK #%02d from %s\n"), track, track_data_path[track - 1]); + + if((track > 0) && (track < 100) && (track < track_num)) { + if((strlen(track_data_path[track - 1]) <= 0) || + !(fio_img->Fopen(track_data_path[track - 1], FILEIO_READ_BINARY))) { + track = 0; + } + } else { + track = 0; + } + } + } + current_track = track; +} + +// Detect only track num. +int TOWNS_CDROM::get_track_noop(uint32_t lba) +{ + int track = 0; + for(int i = 0; i < track_num; i++) { + if(lba >= toc_table[i].index0) { + track = i; + } else { + break; + } + } + return track; +} + +int TOWNS_CDROM::get_track(uint32_t lba) +{ + int track = 0; + track = get_track_noop(lba); + if(is_cue) { + get_track_by_track_num(track); + } else { + current_track = track; + } + return track; +} + +double TOWNS_CDROM::get_seek_time(uint32_t lba) +{ + if(fio_img->IsOpened()) { + uint32_t cur_position = (uint32_t)fio_img->Ftell(); + int distance; + if(is_cue) { + int track = 0; + for(int i = 0; i < track_num; i++) { + if(lba >= toc_table[i].index0) { + track = i; + } else { + break; + } + } + distance = abs((int)lba - (int)(cur_position / ((is_iso) ? 2048 : physical_block_size()) + toc_table[current_track].index0)); + if(track != current_track) { + current_track = get_track(lba); + } + } else { + distance = abs((int)lba - (int)(cur_position / ((is_iso) ? 2048 : physical_block_size()))); + } +// if(distance < 100) { +// distance = 100; // Seek penalty. +// } + if(distance < 4) { + distance = 4; // Seek penalty. + } + double _seek = (double)distance / 333000.0 ; // 333000: sectors in media + _seek = 400.0e3 * _seek; + return _seek; + } else { + return 400000; // 400msec + } +} + +uint32_t TOWNS_CDROM::lba_to_msf(uint32_t lba) +{ + uint8_t m = lba / (60 * 75); + lba -= m * (60 * 75); + uint8_t s = lba / 75; + uint8_t f = lba % 75; + + return ((m / 10) << 20) | ((m % 10) << 16) | ((s / 10) << 12) | ((s % 10) << 8) | ((f / 10) << 4) | ((f % 10) << 0); +} + +uint32_t TOWNS_CDROM::lba_to_msf_alt(uint32_t lba) +{ + uint32_t ret = 0; + ret |= ((lba / (60 * 75)) & 0xff) << 16; + ret |= (((lba / 75) % 60) & 0xff) << 8; + ret |= ((lba % 75) & 0xff) << 0; + return ret; +} + +void TOWNS_CDROM::unpause_cdda_from_cmd() +{ + if((cdda_status == CDDA_PAUSED) && + (current_track >= 0) && (current_track < track_num) + /*&& (toc_table[current_track].is_audio)*/) { // OK? + set_cdda_status(CDDA_PLAYING); + /*! + * @note This may solve halt incident of Kyukyoku Tiger, but something are wrong. + * @note 20201113 K.O + */ + if((stat_reply_intr) && !(req_status)) { + set_subq(); +// set_status_cddareply(true, 1, 0x00, 0, 0x00, 0x00); + set_status_cddareply(true, 0, TOWNS_CD_STATUS_RESUME_DONE, 0, 0x00, 0x00); + return; + } + } + set_subq(); + status_accept(1, 0x00, 0x00); +} + +void TOWNS_CDROM::stop_cdda_from_cmd() +{ + if(!(mounted())) { + status_not_ready(false); + return; + } + if(media_changed) { + status_media_changed(false); + //next_status_byte = 0x0d; + return; + } +// if(/*(status != CDDA_OFF) && */ +// (current_track >= 0) && (current_track < track_num) +// && (toc_table[current_track].is_audio)) { // OK? + /// @note Even make additional status even stop.Workaround for RANCEIII. + /// @note - 20201110 K.O + set_cdda_status(CDDA_ENDED); + set_subq(); + status_accept(1, 0x00, 0x00); + return; +// } +// set_subq(); +// status_accept(0, 0x00, 0x00); +} + +void TOWNS_CDROM::pause_cdda_from_cmd() +{ + if(!(mounted())) { + status_not_ready(false); + return; + } + if((media_changed)) { + status_media_changed(false); + return; + } + if((cdda_status == CDDA_PLAYING)) { + set_cdda_status(CDDA_PAUSED); + /*! + * @note This may solve halt incident of Kyukyoku Tiger, but something are wrong. + * @note 20201113 K.O + */ + if((stat_reply_intr) && !(req_status)) { + set_subq(); +// status_accept(0, 0x00, 0x00); + set_status_cddareply(true, 1, TOWNS_CD_STATUS_ACCEPT, 0, 0x00, 0x00); + return; + } + } + set_subq(); + status_accept(1, 0x00, 0x00); + return; +} + +bool TOWNS_CDROM::seek_relative_frame_in_image(uint32_t frame_no) +{ + int phys_size = (is_iso) ? 2048 : physical_block_size(); + if(frame_no >= toc_table[current_track].lba_offset) { + if(fio_img->IsOpened()) { + if(fio_img->Fseek( + (frame_no - toc_table[current_track].lba_offset) * phys_size, + FILEIO_SEEK_SET) != 0) { + return false; + } + } + } + return true; +} + + +bool TOWNS_CDROM::check_cdda_track_boundary(uint32_t &frame_no) +{ + if((frame_no >= toc_table[current_track + 1].index0) || + (frame_no < toc_table[current_track].index0)) { + current_track = get_track(frame_no); + cdrom_debug_log(_T("CDDA: BEYOND OF TRACK BOUNDARY, FRAME=%d"), frame_no); + if(frame_no < toc_table[current_track].index0) { + frame_no = toc_table[current_track].index0; + } + seek_relative_frame_in_image(frame_no); + return true; + } + return false; +} + +void TOWNS_CDROM::play_cdda_from_cmd() +{ + uint8_t m_start = param_queue[0]; + uint8_t s_start = param_queue[1]; + uint8_t f_start = param_queue[2]; + uint8_t m_end = param_queue[3]; + uint8_t s_end = param_queue[4]; + uint8_t f_end = param_queue[5]; + uint8_t is_repeat = param_queue[6]; // From Towns Linux v1.1/towns_cd.c + uint8_t repeat_count = param_queue[7]; + cdda_repeat_count = -1; + if(!(mounted())) { + status_not_ready(false); + return; + } + if((media_changed)) { + status_media_changed(false); + return; + } + uint32_t start_tmp = FROM_BCD(f_start) + (FROM_BCD(s_start) + FROM_BCD(m_start) * 60) * 75; + uint32_t end_tmp = FROM_BCD(f_end) + (FROM_BCD(s_end) + FROM_BCD(m_end) * 60) * 75; + /*! + * @note Workaround for command SPAM, i.e. Puyo Puyo. + * @note 20201115 K.O + */ + { + int track; + track = get_track_noop(start_tmp); + if(start_tmp >= toc_table[track].pregap) { + start_tmp -= toc_table[track].pregap; + } + if(start_tmp < toc_table[track].index1) { + start_tmp = toc_table[track].index1; // don't play pregap + } else if(start_tmp >= max_logical_block) { + start_tmp = max_logical_block - 1; + } + if(end_tmp >= toc_table[track + 1].index0) { + end_tmp = toc_table[track + 1].index0 - 1; + } else if(end_tmp >= max_logical_block) { + end_tmp = max_logical_block - 1; + } else if(end_tmp == 0) { //! Workaround of Puyo Puyo 20201116 K.O + end_tmp = toc_table[track + 1].index0 - 1; + } + if(cdda_status == CDDA_PLAYING) { + if((start_tmp == cdda_start_frame) && (end_tmp == cdda_end_frame)) { + // Dummy + set_status_cddareply(true, 1, TOWNS_CD_STATUS_ACCEPT, 0, 0x00, 0x00); + return; + } + } + cdda_start_frame = start_tmp; + cdda_end_frame = end_tmp; + + track = get_track(cdda_start_frame); + if(!(toc_table[track].is_audio)) { + status_hardware_error(false); // OK? +// status_not_accept(0, 0x0, 0x00, 0x00); + return; + } + if(is_repeat == 1) { + cdda_repeat_count = -1; + } else { + // Maybe is_repeat == 9 + cdda_repeat_count = repeat_count; + cdda_repeat_count++; + } + track = current_track; + cdda_playing_frame = cdda_start_frame; + cdda_loading_frame = cdda_start_frame; + status_seek = true; + seek_relative_frame_in_image(cdda_playing_frame); + cdrom_debug_log(_T("PLAY_CDROM TRACK=%d START=%02X:%02X:%02X(%d) END=%02X:%02X:%02X(%d) IS_REPEAT=%d REPEAT_COUNT=%d"), + track, + m_start, s_start, f_start, cdda_start_frame, + m_end, s_end, f_end, cdda_end_frame, + is_repeat, repeat_count); + double usec = get_seek_time(cdda_playing_frame); + if(usec < 10.0) usec = 10.0; + set_cdda_status(CDDA_PLAYING); + force_register_event(this, EVENT_CDDA_DELAY_PLAY, usec, false, event_cdda_delay_play); +// register_event(this, EVENT_CDDA_DELAY_PLAY, 100.0, false, &event_cdda_delay_play); + } + set_subq(); // First + /*! + * @note This may solve halt incident of Kyukyoku Tiger, but something are wrong. + * @note 20201113 K.O + */ + set_status_cddareply(true, 1, TOWNS_CD_STATUS_ACCEPT, 0, 0x00, 0x00); +// status_accept(1, 0x00, 0x00); +} + +void TOWNS_CDROM::make_bitslice_subc_q(uint8_t *data, int bitwidth) +{ + int nbit = 0; + if(bitwidth > (sizeof(subq_buffer) / sizeof(SUBC_t))) { + bitwidth = (sizeof(subq_buffer) / sizeof(SUBC_t)); + } else if(bitwidth < 0) { + bitwidth = 0; + } + // Set Q field + // Q: IS set SYNC CODE?. + for(int bp = 0; bp < bitwidth; bp++) { + subq_buffer[bp].bit.Q = + ((data[nbit >> 3] & (1 << (7 - (nbit & 7)))) != 0) ? 1 : 0; + nbit++; + } +} + +void TOWNS_CDROM::set_subq(void) +{ + if(is_device_ready()) { + // create track info + int track = current_track; + uint32_t frame; + uint32_t msf_abs; + uint32_t msf_rel; + if(toc_table[track].is_audio) { // OK? (or force ERROR) 20181120 K.O + frame = ((cdda_status == CDDA_OFF) || (cdda_status == CDDA_ENDED)) ? cdda_start_frame : cdda_playing_frame; + msf_rel = lba_to_msf_alt(frame - toc_table[track].index0); + } else { // Data + if(fio_img->IsOpened()) { + uint32_t cur_position = (uint32_t)(fio_img->Ftell()); + if(is_cue) { + frame = (cur_position / ((is_iso) ? 2048 : physical_block_size())) + toc_table[track].lba_offset; + msf_rel = lba_to_msf_alt(frame - toc_table[track].lba_offset); + } else { + frame = cur_position / ((is_iso) ? 2048 : physical_block_size()); + if(frame > toc_table[track].lba_offset) { + msf_rel = lba_to_msf_alt(frame - toc_table[track].lba_offset); + } else { + msf_rel = lba_to_msf_alt(0); + } + } + } else { + frame = toc_table[track].lba_offset; + msf_rel = 0; + } + } + if(subq_bitptr < subq_bitwidth) { + subq_overrun = true; + } + msf_abs = lba_to_msf_alt(frame); + uint8_t subq_bytes[12] = {0}; + // ToDo: POINT=0xA0-0xA2 + { + subq_bytes[0] = ((toc_table[track].is_audio) ? 0x40 : 0x00) | 0x01; // (CNT << 4) | ADR + subq_bytes[1] = 0x00; // TNO + subq_bytes[2] = TO_BCD(track + 1); // POINT(Track) + subq_bytes[3] = TO_BCD((msf_abs >> 16) & 0xff); // M (absolute) + subq_bytes[4] = TO_BCD((msf_abs >> 8) & 0xff); // S (absolute) + subq_bytes[5] = TO_BCD((msf_abs >> 0) & 0xff); // F (absolute) + subq_bytes[6] = 0x00; // Zero + subq_bytes[7] = TO_BCD((msf_rel >> 16) & 0xff); // M (relative) + subq_bytes[8] = TO_BCD((msf_rel >> 8) & 0xff); // S (relative) + subq_bytes[9] = TO_BCD((msf_rel >> 0) & 0xff); // F (relative) + } + // Post Process1: Calculate CRC16 + uint16_t crc = calc_subc_crc16(subq_bytes, 10, 0xffff); // OK? + subq_bytes[10] = (crc >> 8) & 0xff; + subq_bytes[11] = (crc >> 0) & 0xff; + // Post process 2: push bytes to Bit slice + memset(subq_buffer, 0x00, sizeof(subq_buffer)); + // ToDo: P field; + make_bitslice_subc_q(subq_bytes, 96); + // ToDo: R-W field (a.k.a. CD-TEXT/CD-G); + subq_bitptr = 0; + subq_bitwidth = 96; + } else { + // OK? + if(subq_bitptr < subq_bitwidth) { + subq_overrun = true; // !:Not Needed? + } + memset(subq_buffer, 0x00, sizeof(subq_buffer)); + uint8_t subq_bytes[12] = {0}; + uint16_t crc = calc_subc_crc16(subq_bytes, 10, 0xffff); // OK? + subq_bytes[10] = (crc >> 8) & 0xff; + subq_bytes[11] = (crc >> 0) & 0xff; + // Post process 2: push bytes to Bit slice + memset(subq_buffer, 0x00, sizeof(subq_buffer)); + // ToDo: P field; + make_bitslice_subc_q(subq_bytes, 96); + // ToDo: R-W field (a.k.a. CD-TEXT/CD-G); + subq_bitptr = 0; + subq_bitwidth = 96; + } +// mcu_ready = true; + return; +} + +uint8_t TOWNS_CDROM::get_subq_status() +{ + uint8_t val = 0x00; + val = val | ((subq_bitwidth > 0) ? 0x01 : 0x00); + val = val | ((subq_overrun) ? 0x02 : 0x00); + return val; +} + +uint8_t TOWNS_CDROM::read_subq() +{ + uint8_t val = 0x00; + if(subq_bitptr < subq_bitwidth) { + val = subq_buffer[subq_bitptr].byte; + subq_bitptr++; + } + return val; +} + +int TOWNS_CDROM::get_frames_from_msf(const char *s) +{ + const char *ptr = s; + int frames[3] = {0}; + int index = 0; + + while(1) { + if(*ptr >= '0' && *ptr <= '9') { + frames[index] = frames[index] * 10 + (*ptr - '0'); + } else if(*ptr == ':') { + if(++index == 3) { + // abnormal data + break; + } + } else if(*ptr == '\r' || *ptr == '\n' || *ptr == '\0') { + // end of line + break; + } + ptr++; + } + return (frames[0] * 60 + frames[1]) * 75 + frames[2]; // 75frames/sec +} + +int TOWNS_CDROM::hexatoi(const char *s) +{ + const char *ptr = s; + int value = 0; + + while(1) { + if(*ptr >= '0' && *ptr <= '9') { + value = value * 16 + (*ptr - '0'); + } else if(*ptr >= 'a' && *ptr <= 'f') { + value = value * 16 + (*ptr - 'a' + 10); + } else if(*ptr >= 'A' && *ptr <= 'F') { + value = value * 16 + (*ptr - 'A' + 10); + } else if(*ptr == '\r' || *ptr == '\n' || *ptr == '\0') { + break; + } + ptr++; + } + return value; +} + +#include +#include + +enum { + CUE_NONE = 0, + CUE_REM, + CUE_FILE, + CUE_TRACK, + CUE_INDEX, + CUE_PREGAP, +}; + +bool TOWNS_CDROM::parse_cue_file_args(std::string& _arg2, const _TCHAR *parent_dir, std::string& imgpath) +{ + size_t _arg2_ptr; + size_t _arg3_ptr; + std::string _arg3; + + _arg2_ptr = _arg2.find_first_of((const char *)"\"") + 1; + if(_arg2_ptr == std::string::npos) return false; + + _arg2 = _arg2.substr(_arg2_ptr); + _arg3_ptr = _arg2.find_first_of((const char *)"\""); + if(_arg3_ptr == std::string::npos) return false; + _arg2 = _arg2.substr(0, _arg3_ptr); + + imgpath.clear(); + imgpath = std::string(parent_dir); + imgpath.append(_arg2); + +// cdrom_debug_log(_T("**FILE %s\n"), imgpath.c_str()); + + return true; +} + +void TOWNS_CDROM::parse_cue_track(std::string &_arg2, int& nr_current_track, std::string imgpath) +{ + size_t _arg2_ptr_s; + size_t _arg2_ptr; + _arg2_ptr_s = _arg2.find_first_of((const char *)" \t"); + + std::string _arg3 = _arg2.substr(_arg2_ptr_s); + _arg2 = _arg2.substr(0, _arg2_ptr_s); + size_t _arg3_ptr = _arg3.find_first_not_of((const char *)" \t"); + size_t _arg3_ptr_s; + int _nr_num = atoi(_arg2.c_str()); + + // Set image file + if((_nr_num > 0) && (_nr_num < 100) && (_arg3_ptr != std::string::npos)) { + std::map cue_type; + cue_type.insert(std::make_pair("AUDIO", MODE_AUDIO)); + cue_type.insert(std::make_pair("MODE1/2048", MODE_MODE1_2048)); + cue_type.insert(std::make_pair("MODE1/2352", MODE_MODE1_2352)); + cue_type.insert(std::make_pair("MODE2/2336", MODE_MODE2_2336)); + cue_type.insert(std::make_pair("MODE2/2352", MODE_MODE2_2352)); + cue_type.insert(std::make_pair("CDI/2336", MODE_CDI_2336)); + cue_type.insert(std::make_pair("CDI/2352", MODE_CDI_2352)); + cue_type.insert(std::make_pair("CDG", MODE_CD_G)); + + nr_current_track = _nr_num; + _arg3 = _arg3.substr(_arg3_ptr); + + memset(track_data_path[_nr_num - 1], 0x00, sizeof(_TCHAR) * _MAX_PATH); + strncpy((char *)(track_data_path[_nr_num - 1]), imgpath.c_str(), _MAX_PATH - 1); +// image_tmp_data_path.clear(); +// with_filename[_nr_num - 1] = have_filename; +// have_filename = false; + _arg3_ptr_s = _arg3.find_first_of((const char *)" \t\n"); + _arg3.substr(0, _arg3_ptr_s); + + std::transform(_arg3.begin(), _arg3.end(), _arg3.begin(), + [](unsigned char c) -> unsigned char{ return std::toupper(c); }); + + toc_table[nr_current_track].is_audio = false; + toc_table[nr_current_track].index0 = 0; + toc_table[nr_current_track].index1 = 0; + toc_table[nr_current_track].pregap = 0; + toc_table[nr_current_track].physical_size = 2352; + toc_table[nr_current_track].logical_size = 2048; + int track_type; + try { + track_type = cue_type.at(_arg3); + } catch (std::out_of_range &e) { + track_type = MODE_NONE; + } + toc_table[nr_current_track].type = track_type; + + switch(track_type) { + case MODE_AUDIO: + toc_table[nr_current_track].is_audio = true; + toc_table[nr_current_track].logical_size = 2352; + break; + case MODE_MODE1_2048: + toc_table[nr_current_track].logical_size = 2048; + toc_table[nr_current_track].physical_size = 2048; + break; + case MODE_MODE1_2352: + toc_table[nr_current_track].logical_size = 2048; + break; + case MODE_MODE2_2336: + toc_table[nr_current_track].logical_size = 2336; + toc_table[nr_current_track].physical_size = 2336; + break; + case MODE_MODE2_2352: + toc_table[nr_current_track].logical_size = 2336; + break; + case MODE_CDI_2336: + toc_table[nr_current_track].logical_size = 2336; + toc_table[nr_current_track].physical_size = 2336; + break; + case MODE_CDI_2352: + toc_table[nr_current_track].logical_size = 2336; + break; + case MODE_CD_G: + toc_table[nr_current_track].logical_size = 2448; + toc_table[nr_current_track].physical_size = 2448; + break; + // ToDo: Set data size. + } + if(track_num < (_nr_num + 1)) track_num = _nr_num + 1; + } else { + // ToDo: 20181118 K.Ohta + nr_current_track = 0; + } + +} + +int TOWNS_CDROM::parse_cue_index(std::string &_arg2, int nr_current_track) +{ + int index = -1; + std::string _arg3; + size_t _arg2_ptr_s; + size_t _arg3_ptr_s; + size_t _arg3_ptr; + if((nr_current_track > 0) && (nr_current_track < 100)) { + _arg2_ptr_s = _arg2.find_first_of((const char *)" \t"); + if(_arg2_ptr_s == std::string::npos) return -1;; + + _arg3 = _arg2.substr(_arg2_ptr_s); + _arg2 = _arg2.substr(0, _arg2_ptr_s); + _arg3_ptr = _arg3.find_first_not_of((const char *)" \t"); + if(_arg3_ptr == std::string::npos) return -1; + + _arg3 = _arg3.substr(_arg3_ptr); + _arg3_ptr_s = _arg3.find_first_of((const char *)" \t"); + _arg3.substr(0, _arg3_ptr_s); + index = atoi(_arg2.c_str()); + + switch(index) { + case 0: + toc_table[nr_current_track].index0 = get_frames_from_msf(_arg3.c_str()); + break; + case 1: + toc_table[nr_current_track].index1 = get_frames_from_msf(_arg3.c_str()); + break; + default: + index = -1; + break; + } + } + return index; +} + +bool TOWNS_CDROM::open_iso_file(const _TCHAR* file_path) +{ + _TCHAR full_path_iso[_MAX_PATH] = {0}; + + int nr_current_track = 0; + FILEIO* fio = new FILEIO(); + if(fio == NULL) return false; + + get_long_full_path_name(file_path, full_path_iso, sizeof(full_path_iso)); + const _TCHAR *parent_dir = get_parent_dir((const _TCHAR *)full_path_iso); + memset(track_data_path[0], 0x00, _MAX_PATH * sizeof(_TCHAR)); + + if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { // + uint64_t total_size = (uint64_t)fio->FileLength(); + uint64_t sectors = total_size / 2048; //! @note Support only MODE1/2352. + toc_table[0].lba_offset = 0; + toc_table[0].lba_size = 0; + toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; + if(sectors > 1) { + track_num = 2; + max_logical_block = sectors - 1; + + toc_table[1].lba_offset = 0; + toc_table[1].lba_size = sectors - 1; + toc_table[1].is_audio = false; + toc_table[1].index0 = 0; + toc_table[1].index1 = 0; + toc_table[1].pregap = 150; + toc_table[1].physical_size = 2352; + toc_table[1].logical_size = 2048; + + toc_table[2].lba_offset = sectors; + toc_table[2].lba_size = 0; + toc_table[2].is_audio = false; + toc_table[2].index0 = sectors; + toc_table[2].index1 = sectors; + toc_table[2].pregap = 150; + toc_table[2].physical_size = 0; + toc_table[2].logical_size = 0; + with_filename[1] = true; + strncpy(track_data_path[0], full_path_iso, _MAX_PATH - 1); + } else { + track_num = 0; + max_logical_block = 0; + with_filename[1] = false; + } + fio->Fclose(); + } else { + delete fio; + return false; + } + delete fio; + return true; +} + +bool TOWNS_CDROM::open_ccd_file(const _TCHAR* file_path, _TCHAR* img_file_path) +{ + my_stprintf_s(img_file_path, _MAX_PATH, _T("%s.img"), get_file_path_without_extensiton(file_path)); + if(!FILEIO::IsFileExisting(img_file_path)) { + my_stprintf_s(img_file_path, _MAX_PATH, _T("%s.gz"), get_file_path_without_extensiton(file_path)); + if(!FILEIO::IsFileExisting(img_file_path)) { + my_stprintf_s(img_file_path, _MAX_PATH, _T("%s.img.gz"), get_file_path_without_extensiton(file_path)); + } + if(!FILEIO::IsFileExisting(img_file_path)) { + memset(img_file_path, 0x00, _MAX_PATH); + return false; + } + } + if(fio_img->Fopen(img_file_path, FILEIO_READ_BINARY)) { + is_cue = false; + is_iso = false; + current_track = 0; + // get image file size + if((max_logical_block = fio_img->FileLength() / 2352) > 0) { + // read cue file + FILEIO* fio = new FILEIO(); + if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { + char line[1024] = {0}; + char *ptr; + int track = -1; + while(fio->Fgets(line, 1024) != NULL) { + if(strstr(line, "[Session ") != NULL) { + track = -1; + } else if((ptr = strstr(line, "Point=0x")) != NULL) { + if((track = hexatoi(ptr + 8)) > 0 && track < 0xa0) { + if((track + 1) > track_num) { + track_num = track + 1; + } + } + } else if((ptr = strstr(line, "Control=0x")) != NULL) { + if(track > 0 && track < 0xa0) { + toc_table[track].is_audio = (hexatoi(ptr + 10) != 4); + } + } else if((ptr = strstr(line, "ALBA=-")) != NULL) { + if(track > 0 && track < 0xa0) { + toc_table[track].pregap = atoi(ptr + 6); + } + } else if((ptr = strstr(line, "PLBA=")) != NULL) { + if(track > 0 && track < 0xa0) { + toc_table[track + 1].index0 = atoi(ptr + 5); + } + } else if((ptr = strstr(line, "[TRACK ")) != NULL) { + char* ptr2 = ptr; + if((ptr2 = strstr(ptr + 7, "]")) != NULL) { + uintptr_t n = (uintptr_t)ptr2; + uintptr_t m = (uintptr_t)ptr; + n = n - m; + if(n > 2) n = 2; + char numbuf[3] = {0}; + strncpy(numbuf, ptr + 7, (size_t)n); + track = atoi(numbuf); + if((track + 1) > track_num) { + track_num = track + 1; + } + } + } else if((ptr = strstr(line, "INDEX 0=")) != NULL) { + if(track > 0 && track < 0xa0) { + toc_table[track].index0 = atoi(ptr + 8); + } + } else if((ptr = strstr(line, "INDEX 1=")) != NULL) { + if(track > 0 && track < 0xa0) { + toc_table[track].index1 = atoi(ptr + 8); + } + } else if((ptr = strstr(line, "MODE=")) != NULL) { + if(track > 0 && track < 0xa0) { + int mode; + mode = atoi(ptr + 5); + switch(mode) { + case 0: + toc_table[track].type = MODE_AUDIO; + toc_table[track].is_audio = true; + toc_table[track].logical_size = 2352; + break; + case 1: + toc_table[track].type = MODE_MODE1_2352; + toc_table[track].is_audio = false; + toc_table[track].logical_size = 2048; + break; + case 2: + toc_table[track].type = MODE_MODE2_2336; + toc_table[track].is_audio = false; + toc_table[track].logical_size = 2336; + break; + default: // ??? + toc_table[track].type = MODE_AUDIO; + toc_table[track].is_audio = true; + toc_table[track].logical_size = 2352; + break; + } + } + } + } + toc_table[0].lba_offset = 0; + toc_table[0].lba_size = 0; + toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; + toc_table[0].physical_size = 0; + toc_table[0].logical_size = 0; + if(track_num > 0) { + for(int i = 1; i < track_num; i++) { + // ToDo: Some types. + toc_table[i].physical_size = 2352; + + if(toc_table[i].index0 == 0) { + toc_table[i].index0 = toc_table[i].index1; + } + if(toc_table[i].pregap == 0) { + toc_table[i].pregap = toc_table[i].index1 - toc_table[i].index0; + } + if(toc_table[i].pregap <= 150) toc_table[i].pregap = 150; + } + toc_table[track_num].index0 = toc_table[track_num].index1 = max_logical_block; + for(int i = 1; i < track_num; i++) { + toc_table[i].lba_offset = toc_table[i].index1; + toc_table[i].lba_size = toc_table[i + 1].index1 - toc_table[i].index1; + if(toc_table[i].lba_size > 0) toc_table[i].lba_size -= 1; + } + toc_table[track_num].lba_size = 0; + toc_table[track_num].physical_size = 0; + toc_table[track_num].logical_size = 0; + } else { + fio_img->Fclose(); + fio->Fclose(); + delete fio; + return false; + } + fio->Fclose(); + } + delete fio; + return true; + } + } + return false; +} + +bool TOWNS_CDROM::open_cue_file(const _TCHAR* file_path) +{ + std::string line_buf; + std::string line_buf_shadow; + std::string image_tmp_data_path; + + _TCHAR full_path_cue[_MAX_PATH]; + size_t ptr; + int line_count = 0; + int slen; + int nr_current_track = 0; + FILEIO* fio = new FILEIO(); + if(fio == NULL) return false; + + memset(full_path_cue, 0x00, sizeof(full_path_cue)); + image_tmp_data_path.clear(); + + get_long_full_path_name(file_path, full_path_cue, sizeof(full_path_cue)); + + const _TCHAR *parent_dir = get_parent_dir((const _TCHAR *)full_path_cue); + + size_t _arg1_ptr; + size_t _arg2_ptr; + size_t _arg2_ptr_s; + size_t _arg3_ptr; + size_t _arg3_ptr_s; + + std::string _arg1; + std::string _arg2; + std::string _arg3; + + std::map cue_enum; + + // Initialize + cue_enum.insert(std::make_pair("REM", CUE_REM)); + cue_enum.insert(std::make_pair("FILE", CUE_FILE)); + cue_enum.insert(std::make_pair("TRACK", CUE_TRACK)); + cue_enum.insert(std::make_pair("INDEX", CUE_INDEX)); + cue_enum.insert(std::make_pair("PREGAP", CUE_PREGAP)); + + + if(fio->Fopen(file_path, FILEIO_READ_ASCII)) { // ToDo: Support not ASCII cue file (i.e. SJIS/UTF8).20181118 K.O + line_buf.clear(); + for(int i = 0; i < 100; i++) { + memset(&(track_data_path[i][0]), 0x00, _MAX_PATH * sizeof(_TCHAR)); + with_filename[i] = false; + } + int _c; + bool is_eof = false; + int sptr = 0; + bool have_filename = false; +// int _nr_num = 0; + while(1) { + line_buf.clear(); + int _np = 0; + _c = EOF; + do { + _c = fio->Fgetc(); + if((_c == '\0') || (_c == '\n') || (_c == EOF)) break;; + if(_c != '\r') line_buf.push_back((char)_c); + } while(1); + if(_c == EOF) is_eof = true; + slen = (int)line_buf.length(); + if(slen <= 0) goto _n_continue; + // Trim head of Space or TAB + ptr = 0; + sptr = 0; + // Tokenize + _arg1.clear(); + _arg2.clear(); + _arg3.clear(); + + ptr = line_buf.find_first_not_of((const char*)" \t"); + if(ptr == std::string::npos) { + goto _n_continue; + } + // Token1 + line_buf_shadow = line_buf.substr(ptr); + + _arg1_ptr = line_buf_shadow.find_first_of((const char *)" \t"); + _arg1 = line_buf_shadow.substr(0, _arg1_ptr); + _arg2 = line_buf_shadow.substr(_arg1_ptr); + std::transform(_arg1.begin(), _arg1.end(), _arg1.begin(), + [](unsigned char c) -> unsigned char{ return std::toupper(c); }); + + _arg2_ptr = _arg2.find_first_not_of((const char *)" \t"); + + if(_arg2_ptr != std::string::npos) { + _arg2 = _arg2.substr(_arg2_ptr); + } + int typeval; + try { + typeval = cue_enum.at(_arg1); + } catch (std::out_of_range &e) { + typeval = CUE_NONE; + } + switch(typeval) { + case CUE_REM: + break; + case CUE_FILE: + { + if(!(parse_cue_file_args(_arg2, parent_dir, image_tmp_data_path))) break; + with_filename[nr_current_track + 1] = true; + } + break; + case CUE_TRACK: + { + parse_cue_track(_arg2, nr_current_track, image_tmp_data_path); + } + break; + case CUE_INDEX: + parse_cue_index(_arg2, nr_current_track); + break; + case CUE_PREGAP: + if((nr_current_track > 0) && (nr_current_track < 100)) { + _arg2_ptr_s = _arg2.find_first_of((const char *)" \t"); + _arg2 = _arg2.substr(0, _arg2_ptr_s - 1); + + toc_table[nr_current_track].pregap = get_frames_from_msf(_arg2.c_str()); + } + break; + } + _n_continue: + if(is_eof) break; + line_buf.clear(); + continue; + } + // Finish + max_logical_block = 0; + uint32_t pt_lba_ptr = 0; + if(track_num > 0) { + toc_table[0].lba_offset = 0; + toc_table[0].lba_size = 0; + toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; + // P1: Calc + int _n = 0; + int vnptr = 0; + for(int i = 1; i < track_num; i++) { + + if(fio_img->IsOpened()) { + fio_img->Fclose(); + } + // Even... + //if(toc_table[i].pregap <= 0) { + // toc_table[i].pregap = 150; // Default PREGAP must be 2Sec. From OoTake.(Only with PCE? Not with FM-Towns?) + //} + if((strlen(track_data_path[i - 1]) > 0) && (with_filename[i])) { + if(fio_img->Fopen(track_data_path[i - 1], FILEIO_READ_BINARY)) { + if((_n = fio_img->FileLength() / physical_block_size()) > 0) { + max_logical_block += _n; + } else { + _n = 0; + } + fio_img->Fclose(); + } + toc_table[i].lba_size = _n; + } + toc_table[i].lba_offset = max_logical_block - _n; + if(!(with_filename[i + 1]) && (toc_table[i + 1].index1 > toc_table[i].index1)) { + toc_table[i].lba_size = toc_table[i + 1].index1 - toc_table[i].index0; + } + if(toc_table[i].index0 == 0) { + toc_table[i].index0 = toc_table[i].index1; + } + if(toc_table[i].pregap == 0) { + toc_table[i].pregap = toc_table[i].index1 - toc_table[i].index0; + } + // Even... + if(toc_table[i].pregap <= 150) { + toc_table[i].pregap = 150; // Default PREGAP must be 2Sec. From OoTake.(Only with PCE? Not with FM-Towns?) + } + } + if((track_num == 2) && (max_logical_block > 0)) { + toc_table[track_num - 1].lba_size -= 1; + max_logical_block--; + } + for(int i = 1; i < track_num; i++) { + toc_table[i].index0 += toc_table[i].lba_offset; + toc_table[i].index1 += toc_table[i].lba_offset; + cdrom_debug_log(_T("TRACK#%02d TYPE=%s PREGAP=%d INDEX0=%d INDEX1=%d LBA_SIZE=%d LBA_OFFSET=%d PATH=%s\n"), + i, (toc_table[i].is_audio) ? _T("AUDIO") : _T("MODE1/2352"), + toc_table[i].pregap, toc_table[i].index0, toc_table[i].index1, + toc_table[i].lba_size, toc_table[i].lba_offset, track_data_path[i - 1]); + //#endif + } + toc_table[0].index0 = toc_table[0].index1 = toc_table[0].pregap = 0; + toc_table[0].physical_size = 2352; + toc_table[0].logical_size = 2048; + toc_table[track_num].index0 = toc_table[track_num].index1 = max_logical_block; + toc_table[track_num].lba_offset = max_logical_block; + toc_table[track_num].lba_size = 0; + } + fio->Fclose(); + } + delete fio; + + is_cue = false; + if(track_num > 0) is_cue = true; + // Not Cue FILE. + return is_cue; +} + +void TOWNS_CDROM::open(const _TCHAR* file_path) +{ + media_changed = true; + open_from_cmd(file_path); +// set_status(true, 0, TOWNS_CD_STATUS_DOOR_CLOSE_DONE, 0x00, 0x00, 0x00); +// status_accept(0, 0x09, 0x00, 0x00); // Disc changed +} + +void TOWNS_CDROM::open_from_cmd(const _TCHAR* file_path) +{ + _TCHAR img_file_path[_MAX_PATH] = {0}; + memset(img_file_path_bak, 0x00, sizeof(img_file_path_bak)); + + close_from_cmd(); + access = false; + + if(check_file_extension(file_path, _T(".cue"))) { + is_cue = false; + current_track = 0; + if(open_cue_file(file_path)) { + strncpy(img_file_path_bak, file_path, _MAX_PATH - 1); + } + } else if(check_file_extension(file_path, _T(".iso"))) { + is_cue = false; + current_track = 0; + if(open_iso_file(file_path)) { + strncpy(img_file_path, file_path, _MAX_PATH - 1); + strncpy(img_file_path_bak, file_path, _MAX_PATH - 1); + } + if(fio_img->Fopen(img_file_path, FILEIO_READ_BINARY)) { + is_cue = false; + current_track = 0; + is_iso = true; + } + } else if(check_file_extension(file_path, _T(".ccd"))) { + // get image file name + if(open_ccd_file(file_path, img_file_path)) { + strncpy(img_file_path_bak, img_file_path, _MAX_PATH - 1); + } + } + + if(mounted() /*&& (__SCSI_DEBUG_LOG)*/) { + for(int i = 1; i < track_num + 1; i++) { + uint32_t idx0_msf = lba_to_msf(toc_table[i].index0); + uint32_t idx1_msf = lba_to_msf(toc_table[i].index1); + uint32_t pgap_msf = lba_to_msf(toc_table[i].pregap); + this->cdrom_debug_log(_T("Track%02d: Index0=%02x:%02x:%02x Index1=%02x:%02x:%02x PreGap=%02x:%02x:%02x\n"), i, + (idx0_msf >> 16) & 0xff, (idx0_msf >> 8) & 0xff, idx0_msf & 0xff, + (idx1_msf >> 16) & 0xff, (idx1_msf >> 8) & 0xff, idx1_msf & 0xff, + (pgap_msf >> 16) & 0xff, (pgap_msf >> 8) & 0xff, pgap_msf & 0xff); + } + } +} + +void TOWNS_CDROM::close() +{ +// status_accept(0, 0x09, 0x00, 0x00, 0x00); // Disc changed +// req_status = true; +// set_status(true, 0, TOWNS_CD_STATUS_DOOR_OPEN_DONE, 0x00, 0x00, 0x00); +// media_changed = true; + close_from_cmd(); +} + +void TOWNS_CDROM::close_from_cmd() +{ + if(fio_img->IsOpened()) { + fio_img->Fclose(); + } + memset(toc_table, 0, sizeof(toc_table)); + memset(img_file_path_bak, 0x00, sizeof(img_file_path_bak)); + track_num = 0; + is_cue = false; + current_track = 0; + set_cdda_status(CDDA_OFF); + is_iso = false; + read_mode = CDROM_READ_NONE; +} + +bool TOWNS_CDROM::mounted() +{ + if(is_cue) return true; + return fio_img->IsOpened(); +} + +bool TOWNS_CDROM::accessed() +{ + bool value = access; + access = false; + return value; +} + +void TOWNS_CDROM::mix(int32_t* buffer, int cnt) +{ + if(cdda_status == CDDA_PLAYING) { + if(mix_loop_num != 0) { + int tmp_l = 0, tmp_r = 0; + for(int i = 0; i < mix_loop_num; i++) { + event_callback(EVENT_CDDA, 0); + tmp_l += cdda_sample_l; + tmp_r += cdda_sample_r; + } + cdda_sample_l = tmp_l / mix_loop_num; + cdda_sample_r = tmp_r / mix_loop_num; + } +// int32_t val_l = apply_volume(apply_volume(cdda_sample_l, volume_m), volume_l); +// int32_t val_r = apply_volume(apply_volume(cdda_sample_r, volume_m), volume_r); + int32_t val_l = apply_volume(cdda_sample_l, volume_l); + int32_t val_r = apply_volume(cdda_sample_r, volume_r); + + for(int i = 0; i < cnt; i++) { + *buffer++ += val_l; // L + *buffer++ += val_r; // R + } + } +} + +void TOWNS_CDROM::set_volume(int ch, int decibel_l, int decibel_r) +{ + volume_l = decibel_to_volume(decibel_l + 3.0); + volume_r = decibel_to_volume(decibel_r + 3.0); +} + +void TOWNS_CDROM::set_volume(int volume) +{ + volume_m = (int)(1024.0 * (max(0, min(100, volume)) / 100.0)); +} + +uint32_t TOWNS_CDROM::read_io8(uint32_t addr) +{ + /* + * 04C0h : Master status + * 04C2h : CDC status + * 04C4h : DATA + * 04CCh : SUBQ CODE + * 04CDh : SUBQ STATUS + */ + uint32_t val = 0; + switch(addr & 0x0f) { + case 0x00: + val = val | ((mcu_intr) ? 0x80 : 0x00); + val = val | ((dma_intr) ? 0x40 : 0x00); + val = val | ((pio_transfer_phase) ? 0x20 : 0x00); + val = val | ((dma_transfer_phase) ? 0x10 : 0x00); // USING DMAC ch.3 + val = val | ((has_status) ? 0x02 : 0x00); + val = val | ((mcu_ready) ? 0x01 : 0x00); +// if((mcu_intr) || (dma_intr)) { +// mcu_intr = false; +// dma_intr = false; +// write_signals(&outputs_mcuint, 0x00000000); +// cdrom_debug_log(_T("FALL DOWN INTs@04C0h")); +// } + break; + case 0x02: + val = read_status(); + break; + case 0x04: + if((pio_transfer_phase) && (pio_transfer)) { + if(databuffer->left() == logical_block_size()) { + cdrom_debug_log(_T("PIO READ START FROM 04C4h")); + } + val = (databuffer->read() & 0xff); + data_reg = val; + if((read_length <= 0) && (databuffer->empty())) { + pio_transfer_phase = false; + mcu_ready = false; + clear_event(this, event_next_sector); + clear_event(this, event_seek_completed); + clear_event(this, event_time_out); + status_read_done(false); + cdrom_debug_log(_T("EOT(PIO)")); + if((stat_reply_intr) || !(dma_intr_mask)) { + //if((stat_reply_intr) && !(dma_intr_mask)) { + write_mcuint_signals(0xffffffff); + } + } else if(databuffer->empty()) { + pio_transfer_phase = false; + mcu_ready = false; + clear_event(this, event_time_out); + cdrom_debug_log(_T("NEXT(PIO)")); + if((stat_reply_intr) || !(dma_intr_mask)) { + //if((stat_reply_intr) && !(dma_intr_mask)) { + write_mcuint_signals(0xffffffff); + } + } + } + break; + case 0x0c: // Subq code + val = read_subq(); + break; + case 0x0d: // Subq status + val = get_subq_status(); + break; + } + + return val; +} + +void TOWNS_CDROM::write_io8(uint32_t addr, uint32_t data) +{ + /* + * 04C0h : Master control register + * 04C2h : Command register + * 04C4h : Parameter register + * 04C6h : Transfer control register. + */ + w_regs[addr & 0x0f] = data; + switch(addr & 0x0f) { + case 0x00: // Master control register + //cdrom_debug_log(_T("PORT 04C0h <- %02X"), data); + mcu_intr_mask = ((data & 0x02) == 0) ? true : false; + dma_intr_mask = ((data & 0x01) == 0) ? true : false; + if((data & 0x80) != 0) { + /*if(mcu_intr) */set_mcu_intr(false); + } + if((data & 0x40) != 0) { + /*if(dma_intr) */set_dma_intr(false); + } + if((data & 0x04) != 0) { + cdrom_debug_log(_T("RESET FROM CMDREG: 04C0h")); + reset_device(); +// break; + } + break; + case 0x02: // Command + //cdrom_debug_log(_T("PORT 04C2h <- %02X"), data); + if(mcu_ready) { + stat_reply_intr = ((data & 0x40) != 0) ? true : false; + req_status = ((data & 0x20) != 0) ? true : false; + param_ptr = 0; + mcu_ready = false; + extra_status = 0; + //dma_transfer_phase = false; + //pio_transfer_phase = false; + if(d_cpu == NULL) { + cdrom_debug_log(_T("CMD=%02X"), data); + } else { + cdrom_debug_log(_T("CMD=%02X from PC=%08X"), data, d_cpu->get_pc()); + } + prev_command = latest_command; + execute_command(data); + } + break; + case 0x04: // Param + param_queue[param_ptr] = data; + param_ptr = (param_ptr + 1) & 0x07; + break; + case 0x06: + if((data & 0x08) != 0) { + dma_transfer = false; + pio_transfer = true; + } + if((data & 0x10) != 0) { + dma_transfer = true; + pio_transfer = false; + } + if((dma_transfer) /*&& !(dma_transfer_phase)*/) { + dma_transfer_phase = true; + force_register_event(this, EVENT_CDROM_DRQ, /*0.25 * 1.0e6 / ((double)transfer_speed * 150.0e3 ) */ 1.0 / 8.0, true, event_drq); + } else if((pio_transfer) && !(pio_transfer_phase)) { + pio_transfer_phase = true; + } + cdrom_debug_log(_T("SET TRANSFER MODE to %02X"), data); + break; + } +} + +void TOWNS_CDROM::write_debug_data8(uint32_t addr, uint32_t data) +{ + databuffer->write_not_push(addr % max_fifo_length, data & 0xff); +} + +uint32_t TOWNS_CDROM::read_debug_data8(uint32_t addr) +{ + return databuffer->read_not_remove(addr % max_fifo_length) & 0xff; +} + + +bool TOWNS_CDROM::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + return false; +} + + +bool TOWNS_CDROM::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + if(buffer == NULL) return false; + _TCHAR regs[256] = {0}; + for(int i = 0; i < 16; i += 2) { + _TCHAR tmps[16] = {0}; + my_stprintf_s(tmps, 16, _T("%02X "), w_regs[i]); + my_tcscat_s(regs, sizeof(regs) / sizeof(_TCHAR), tmps); + } + _TCHAR stat[256] = {0}; + for(int i = 0; i < 4; i++) { + _TCHAR tmps[16] = {0}; + my_stprintf_s(tmps, 16, _T("%02X "), status_queue->read_not_remove(i) & 0xff); + my_tcscat_s(stat, sizeof(regs) / sizeof(_TCHAR), tmps); + } + _TCHAR param[256] = {0}; + for(int i = 0; i < 8; i++) { + _TCHAR tmps[16] = {0}; + my_stprintf_s(tmps, 16, _T("%02X "), param_queue[i]); + my_tcscat_s(param, sizeof(param) / sizeof(_TCHAR), tmps); + } + + my_stprintf_s(buffer, buffer_len, + _T("TRANSFER MODE=%s %s\n") + _T("MCU INT=%s DMA INT=%s TRANSFER PHASE:%s %s HAS_STATUS=%s MCU=%s\n") + _T("TRACK=%d LBA=%d READ LENGTH=%d DATA QUEUE=%d\n") + _T("CMD=%02X PARAM=%s PTR=%d\n") + _T("EXTRA STATUS=%d STATUS COUNT=%d QUEUE_VALUE=%s\n") + _T("REGS RAW VALUES=%s\n") + , (pio_transfer) ? _T("PIO") : _T(" ") + , (dma_transfer) ? _T("DMA") : _T(" ") + , (mcu_intr) ? _T("ON ") : _T("OFF"), (dma_intr) ? _T("ON ") : _T("OFF") + , (pio_transfer_phase) ? _T("PIO") : _T(" ") + , (dma_transfer_phase) ? _T("DMA") : _T(" ") + , (has_status) ? _T("ON ") : _T("OFF"), (mcu_ready) ? _T("ON ") : _T("OFF") + , current_track, position / physical_block_size(), read_length, databuffer->count() + , latest_command, param, param_ptr + , extra_status, status_queue->count(), stat + , regs + ); + return true; +} + + +/* + * Note: 20200428 K.O: DO NOT USE STATE SAVE, STILL don't implement completely yet. + */ +#define STATE_VERSION 7 + +bool TOWNS_CDROM::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + if(!(databuffer->process_state((void *)state_fio, loading))) { + return false; + } + if(!(status_queue->process_state((void *)state_fio, loading))) { + return false; + } + state_fio->StateArray(w_regs, sizeof(w_regs), 1); + for(int i = 0; i < (sizeof(subq_buffer) / sizeof(SUBC_t)); i++) { + state_fio->StateValue(subq_buffer[i].byte); + } + state_fio->StateValue(machine_id); + state_fio->StateValue(cpu_id); + state_fio->StateValue(max_fifo_length); + state_fio->StateValue(fifo_length); + + state_fio->StateValue(data_reg); + state_fio->StateValue(req_status); + state_fio->StateValue(stat_reply_intr); + state_fio->StateValue(latest_command); + + state_fio->StateValue(mcu_intr); + state_fio->StateValue(dma_intr); + state_fio->StateValue(pio_transfer); + state_fio->StateValue(dma_transfer); + state_fio->StateValue(pio_transfer_phase); + state_fio->StateValue(dma_transfer_phase); + state_fio->StateValue(mcu_ready); + state_fio->StateValue(has_status); + state_fio->StateValue(mcu_intr_mask); + state_fio->StateValue(dma_intr_mask); + state_fio->StateValue(transfer_speed); + state_fio->StateValue(read_length); + state_fio->StateValue(read_length_bak); + state_fio->StateValue(next_seek_lba); + + state_fio->StateValue(mcuint_val); + + state_fio->StateValue(param_ptr); + state_fio->StateArray(param_queue, sizeof(param_queue), 1); + state_fio->StateValue(extra_status); + + state_fio->StateValue(subq_bitwidth); + state_fio->StateValue(subq_bitptr); + state_fio->StateValue(subq_overrun); + state_fio->StateValue(stat_track); + state_fio->StateValue(media_changed); + state_fio->StateValue(next_status_byte); + + state_fio->StateValue(force_logging); + // SCSI_CDROM + uint32_t offset = 0; + state_fio->StateValue(read_sector); + state_fio->StateValue(mix_loop_num); + + state_fio->StateArray(img_file_path_bak, sizeof(img_file_path_bak), 1); + state_fio->StateValue(is_cue); + state_fio->StateValue(current_track); + state_fio->StateValue(track_num); + state_fio->StateValue(status_seek); + + state_fio->StateValue(cdrom_prefetch); + + state_fio->StateValue(cdda_start_frame); + state_fio->StateValue(cdda_end_frame); + state_fio->StateValue(cdda_playing_frame); + state_fio->StateValue(cdda_loading_frame); + state_fio->StateValue(cdda_status); + state_fio->StateValue(cdda_repeat_count); + state_fio->StateValue(cdda_interrupt); + state_fio->StateValue(cdda_buffer_ptr); + state_fio->StateValue(cdda_sample_l); + state_fio->StateValue(cdda_sample_r); + state_fio->StateValue(cdda_stopped); + + state_fio->StateValue(volume_l); + state_fio->StateValue(volume_r); + state_fio->StateValue(volume_m); + + if(loading) { + offset = state_fio->FgetUint32_LE(); + } else { + if(fio_img->IsOpened()) { + offset = fio_img->Ftell(); + } + state_fio->FputUint32_LE(offset); + } + // ToDo: Re-Open Image.20181118 K.O + // post process + if(loading) { + if(fio_img->IsOpened()) { + close_from_cmd(); + } + bool is_cue_bak = is_cue; + int track_num_bak = track_num; + if(strlen(img_file_path_bak) > 0) { + open_from_cmd(img_file_path_bak); + } + if((is_cue_bak == is_cue) && (track_num_bak == track_num)) { + if((current_track > 0) && (current_track < 100)) { + get_track_by_track_num(current_track); // Re-Play + } + if(fio_img->IsOpened()) { + fio_img->Fseek(offset, FILEIO_SEEK_SET); + } + } else { + close_from_cmd(); + } + } + state_fio->StateValue(event_seek); + state_fio->StateValue(event_cdda); + state_fio->StateValue(event_cdda_delay_play); + state_fio->StateValue(event_delay_interrupt); + state_fio->StateValue(event_drq); + state_fio->StateValue(event_next_sector); + state_fio->StateValue(event_seek_completed); + state_fio->StateValue(event_delay_ready); + state_fio->StateValue(event_time_out); + state_fio->StateValue(event_eot); + + // SCSI_DEV + state_fio->StateValue(position); + return true; +} + + + } diff --git a/source/src/vm/fmtowns/towns_cdrom.h b/source/src/vm/fmtowns/towns_cdrom.h index 9bd60b301..b1a31715f 100644 --- a/source/src/vm/fmtowns/towns_cdrom.h +++ b/source/src/vm/fmtowns/towns_cdrom.h @@ -9,75 +9,581 @@ #pragma once #include "../../common.h" -#include "../scsi_dev.h" -#include "../scsi_cdrom.h" +#include "../device.h" + // 0 - 9 : SCSI_CDROM:: // 100 - : SCSI_DEV:: -#define SIG_TOWNS_CDROM_SET_TRACK 10 - -// Virtual (pseudo) SCSI command. -#define TOWNS_CDROM_CDDA_PLAY 0xf0 -#define TOWNS_CDROM_CDDA_PAUSE 0xf1 -#define TOWNS_CDROM_CDDA_UNPAUSE 0xf2 -#define TOWNS_CDROM_CDDA_STOP 0xf3 +#define SIG_TOWNS_CDROM_PLAYING 0 +#define SIG_TOWNS_CDROM_SAMPLE_L 1 +#define SIG_TOWNS_CDROM_SAMPLE_R 2 +#define SIG_TOWNS_CDROM_CDDA_PLAY 3 +#define SIG_TOWNS_CDROM_CDDA_STOP 4 +#define SIG_TOWNS_CDROM_CDDA_PAUSE 5 +#define SIG_TOWNS_CDROM_SET_TRACK 0x10 +#define SIG_TOWNS_CDROM_MAX_TRACK 0x11 +#define SIG_TOWNS_CDROM_IS_MEDIA_INSERTED 0x12 +#define SIG_TOWNS_CDROM_REACHED_MAX_TRACK 0x13 +#define SIG_TOWNS_CDROM_CURRENT_TRACK 0x14 +#define SIG_TOWNS_CDROM_START_MSF 0x15 +#define SIG_TOWNS_CDROM_START_MSF_AA 0x16 +#define SIG_TOWNS_CDROM_GET_ADR 0x17 +#define SIG_TOWNS_CDROM_SET_STAT_TRACK 0x18 +#define SIG_TOWNS_CDROM_RELATIVE_MSF 0x20 +#define SIG_TOWNS_CDROM_ABSOLUTE_MSF 0x21 +#define SIG_TOWNS_CDROM_READ_DATA 0x22 +#define SIG_TOWNS_CDROM_RESET 0x23 +#define SIG_TOWNS_CDROM_DMAINT 0x24 class SCSI_HOST; class FIFO; class FILEIO; +class DEBUGGER; -namespace TOWNS { - class CDC; -} +namespace FMTOWNS { + #pragma pack(1) + typedef union { + struct { + uint8_t P:1; + uint8_t Q:1; + uint8_t R:1; + uint8_t S:1; + uint8_t T:1; + uint8_t U:1; + uint8_t V:1; + uint8_t W:1; + } bit; + uint8_t byte; + } SUBC_t; +#pragma pack() + /*! + * @note Belows are CD-ROM sector structuer. + * @note See https://en.wikipedia.org/wiki/CD-ROM#Sector_structure . + */ +#pragma pack(1) + typedef struct { + uint8_t sync[12]; + uint8_t addr_m; + uint8_t addr_s; + uint8_t addr_f; + uint8_t sector_type; //! 1 = MODE1, 2=MODE2 + } cd_data_head_t; +#pragma pack() +#pragma pack(1) + /*! + * @note ToDo: Still not implement crc32 and ecc. + * @note 20201116 K.O + */ + typedef struct { + cd_data_head_t header; + uint8_t data[2048]; + uint8_t crc32[4]; //! CRC32 checksum. + uint8_t reserved[8]; + uint8_t ecc[276]; //! ERROR CORRECTIOM DATA; by read solomon code. + } cd_data_mode1_t; +#pragma pack() +#pragma pack(1) + /*! + * + * + */ + typedef struct { + cd_data_head_t header; + uint8_t data[2336]; + } cd_data_mode2_t; +#pragma pack() +#pragma pack(1) + typedef struct { + uint8_t data[2352]; + } cd_audio_sector_t; +#pragma pack() +#pragma pack(1) + /*! + * @note ToDo: Add fake header and crc and ecc. + * @note 20201116 K.O + */ + typedef struct { + uint8_t data[2048]; + } cd_data_iso_t; +#pragma pack() +// From Towns Linux : include/linux/towns_cd.h +enum { + MODE_AUDIO = 0, + MODE_MODE1_2352, + MODE_MODE1_2048, + MODE_CD_G, + MODE_MODE2_2336, + MODE_MODE2_2352, + MODE_CDI_2336, + MODE_CDI_2352, + MODE_NONE +}; +enum { + CDROM_READ_MODE1 = 1, + CDROM_READ_MODE2 = 2, + CDROM_READ_RAW = 3, + CDROM_READ_NONE = 0 +}; +enum { + CDROM_COMMAND_SEEK = 0x00, + CDROM_COMMAND_READ_MODE2 = 0x01, + CDROM_COMMAND_READ_MODE1 = 0x02, + CDROM_COMMAND_READ_RAW = 0x03, + CDROM_COMMAND_PLAY_TRACK = 0x04, + CDROM_COMMAND_READ_TOC = 0x05, + CDROM_COMMAND_READ_CDDA_STATE = 0x06, + CDROM_COMMAND_1F = 0x1f, + CDROM_COMMAND_SET_STATE = 0x80, + CDROM_COMMAND_SET_CDDASET = 0x81, + CDROM_COMMAND_STOP_CDDA = 0x84, + CDROM_COMMAND_PAUSE_CDDA = 0x85, + CDROM_COMMAND_RESUME_CDDA = 0x87, +}; -namespace TOWNS { -class TOWNS_CDROM : public SCSI_CDROM { +// STATUS[0]. +// Update from Tsugaru Thanks to Yamakawa-San. +enum { + TOWNS_CD_STATUS_ACCEPT = 0x00, + TOWNS_CD_STATUS_NOT_ACCEPT = 0x01, + TOWNS_CD_STATUS_SEEK_COMPLETED = 0x04, + TOWNS_CD_STATUS_READ_DONE = 0x06, + TOWNS_CD_STATUS_PLAY_DONE = 0x07, + TOWNS_CD_STATUS_DOOR_OPEN_DONE = 0x09, + TOWNS_CD_STATUS_DISC_NOT_READY = 0x10, + TOWNS_CD_STATUS_DOOR_CLOSE_DONE = 0x10, + TOWNS_CD_STATUS_STOP_DONE = 0x11, + TOWNS_CD_STATUS_PAUSE_DONE = 0x12, + TOWNS_CD_STATUS_RESUME_DONE = 0x13, + TOWNS_CD_STATUS_TOC_ADDR = 0x16, + TOWNS_CD_STATUS_TOC_DATA = 0x17, + TOWNS_CD_STATUS_SUBQ_READ = 0x18, + TOWNS_CD_STATUS_SUBQ_READ2 = 0x18, + TOWNS_CD_STATUS_SUBQ_READ3 = 0x18, + TOWNS_CD_STATUS_CMD_ABEND = 0x21, + TOWNS_CD_STATUS_DATA_READY = 0x22, + TOWNS_CD_STATUS_UNKNOWN = 0xff, +}; + +// status[1] @ status[0] == 00h +// From Tsugaru Thanks to Yamakawa-San. +// Belows are quote from cdrom/cdrom.h for Tsugaru. +//00H 04H xx xx CDROM BIOS re-shoots command A0H if CDROM returns this code. (0b00000100) +//00H 08H xx xx CDROM BIOS re-shoots command A0H if CDROM returns this code. (0b00001000) +//00H 0DH xx xx CDROM BIOS Checking (2ndByte)&0x0D and wait for it to be non zero. (0b00001101) +enum { + TOWNS_CD_ACCEPT_NOERROR = 0x00, + TOWNS_CD_ACCEPT_DATA_TRACK = 0x01, + TOWNS_CD_ACCEPT_CDDA_PLAYING = 0x03, + TOWNS_CD_ACCEPT_04H_FOR_CMD_A0H = 0x04, + TOWNS_CD_ACCEPT_08H_FOR_CMD_A0H = 0x08, + TOWNS_CD_ACCEPT_MEDIA_CHANGED = 0x09, + TOWNS_CD_ACCEPT_WAIT = 0x0d, +}; + +// status[1] @ status[0] == 21h +// From Tsugaru Thanks to Yamakawa-San. +enum { + TOWNS_CD_ABEND_PARAMETER_ERROR = 0x01, + TOWNS_CD_ABEND_ERR02 = 0x02, + TOWNS_CD_ABEND_HARDWARE_ERROR_03 = 0x03, + TOWNS_CD_ABEND_HARDWARE_ERROR_04 = 0x04, + TOWNS_CD_ABEND_READ_AUDIO_TRACK = 0x05, + TOWNS_CD_ABEND_MEDIA_ERROR_06 = 0x06, + TOWNS_CD_ABEND_DRIVE_NOT_READY = 0x07, + TOWNS_CD_ABEND_MEDIA_CHANGED = 0x08, + TOWNS_CD_ABEND_HARDWARE_ERROR_09 = 0x09, + TOWNS_CD_ABEND_ERROR_0C = 0x0c, + TOWNS_CD_ABEND_HARDWARE_ERROR_0D = 0x0d, + TOWNS_CD_ABEND_RETRY = 0x0f, // Indicate RETRY ? +}; + +enum { + TOWNS_CD_READ_NONE = 0, + TOWNS_CD_READ_MODE1, + TOWNS_CD_READ_MODE2, + TOWNS_CD_READ_RAW, + TOWNS_CD_READ_CDDA, + TOWNS_CD_STOP_CDDA, + TOWNS_CD_PAUSE_CDDA, + TOWNS_CD_UNPAUSE_CDDA, +}; + +/*class TOWNS_CDROM : public SCSI_CDROM */ +class TOWNS_CDROM: public DEVICE { protected: - FIFO* subq_buffer; + outputs_t outputs_drq; + outputs_t outputs_mcuint; + FILEIO* fio_img; +// FIFO* subq_buffer; + FIFO* databuffer; + FIFO* status_queue; + + // For Debugging, will remove 20200822 K.O + DEVICE* d_cpu; + DEVICE* d_dmac; + + uint32_t max_fifo_length; + uint32_t fifo_length; + + uint16_t cpu_id; + uint16_t machine_id; + + uint8_t data_reg; + bool dma_transfer; + bool pio_transfer; + bool dma_transfer_phase; + bool pio_transfer_phase; + + bool cdrom_halted; + bool status_seek; + + SUBC_t subq_buffer[98]; // OK? + int subq_bitptr; + int subq_bitwidth; bool subq_overrun; + bool is_playing; + uint8_t next_status_byte; + int stat_track; + + bool is_cue; + bool is_iso; + struct { + uint8_t type; + int32_t index0, index1, pregap; + uint32_t lba_offset; + uint32_t lba_size; + bool is_audio; + int physical_size; + int logical_size; + } toc_table[1024]; + _TCHAR track_data_path[100][_MAX_PATH]; + _TCHAR img_file_path_bak[_MAX_PATH]; + bool with_filename[100]; + + uint32_t cdda_start_frame; + uint32_t cdda_end_frame; + uint32_t cdda_playing_frame; + uint32_t cdda_loading_frame; + int cdda_status; + int cdda_repeat_count; + bool cdda_interrupt; + int cdda_buffer_ptr; + + int mix_loop_num; + int current_track; + int read_sector; + int transfer_speed; + int read_length; + int read_length_bak; + int next_seek_lba; + int read_mode; + int position; - virtual void play_cdda_from_cmd(); - virtual void pause_cdda_from_cmd(); - virtual void unpause_cdda_from_cmd(); - virtual void stop_cdda_from_cmd(); + uint8_t prev_command; + uint8_t latest_command; + uint8_t reserved_command; + bool req_status; + bool stat_reply_intr; + bool mcu_ready; + bool has_status; + bool mcu_intr; + bool dma_intr; + bool mcu_intr_mask; + bool dma_intr_mask; + bool mcuint_val; + + int event_drq; + int event_seek; + int event_next_sector; + int event_seek_completed; + int event_cdda; + int event_cdda_delay_play; + int event_cdda_delay_stop; + int event_delay_interrupt; + int event_delay_ready; + int event_halt; + int event_delay_command; + int event_time_out; + int event_eot; + + int cdda_sample_l; + int cdda_sample_r; + + int volume_l; + int volume_r; + int volume_m; + + uint8_t w_regs[16]; + static const uint16_t crc_table[256]; + + int param_ptr; + bool command_entered; + bool param_filled; + uint8_t param_pre_queue[8]; + uint8_t param_queue[8]; + + double seek_time; + int track_num; + uint32_t max_logical_block; + int bytes_per_sec; + bool access; + bool media_changed; + bool cdda_stopped; + uint32_t read_lba; + + bool cdrom_prefetch; + + int extra_status; + void play_cdda_from_cmd(); + void unpause_cdda_from_cmd(); + void stop_cdda_from_cmd(); + void pause_cdda_from_cmd(); + + bool is_device_ready(); + void reset_device(); + void read_a_cdda_sample(); + + void send_mcu_ready(); + void set_extra_status(); + + void set_status(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3); + void set_status_read_done(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3); + void set_status_cddareply(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3); + void set_status_immediate(bool _req_status, int extra, uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3); + void set_status_extra(uint8_t s0, uint8_t s1, uint8_t s2, uint8_t s3); + void set_status_extra_toc_addr(uint8_t s1, uint8_t s2, uint8_t s3); + void set_status_extra_toc_data(uint8_t s1, uint8_t s2, uint8_t s3); + bool __FASTCALL check_cdda_track_boundary(uint32_t &frame_no); + bool seek_relative_frame_in_image(uint32_t frame_no); + int prefetch_audio_sectors(int read_secs); + void read_cdrom(); + void read_cdrom_mode1(); + void read_cdrom_mode2(); + void read_cdrom_raw(); + bool check_notready_and_changed(bool force_int); + + virtual void execute_command(uint8_t command); + + void __FASTCALL status_not_ready(bool forceint); + void __FASTCALL status_media_changed(bool forceint); + void __FASTCALL status_hardware_error(bool forceint); + void __FASTCALL status_parameter_error(bool forceint); + void __FASTCALL status_read_done(bool forceint); + void __FASTCALL status_data_ready(bool forceint); + + void __FASTCALL status_accept(int extra, uint8_t s2, uint8_t s3); + void __FASTCALL status_not_accept(int extra, uint8_t s1, uint8_t s2, uint8_t s3); + + void __FASTCALL status_illegal_lba(int extra, uint8_t s1, uint8_t s2, uint8_t s3); + void set_delay_ready(); + void set_delay_ready_nostatus(); + void set_delay_ready_eot(); + void set_delay_ready_cddareply(); + + uint32_t cdrom_get_adr(int trk); + + void __FASTCALL set_dma_intr(bool val); + void __FASTCALL set_mcu_intr(bool val); + + void __FASTCALL make_bitslice_subc_q(uint8_t *data, int bitwidth); + uint16_t __FASTCALL calc_subc_crc16(uint8_t *databuf, int bytes, uint16_t initval); + + bool open_cue_file(const _TCHAR* file_path); + bool parse_cue_file_args(std::string& _arg2, const _TCHAR *parent_dir, std::string& imgpath); + void parse_cue_track(std::string &_arg2, int& nr_current_track, std::string imgpath); + int parse_cue_index(std::string &_arg2, int nr_current_track); + + virtual bool open_iso_file(const _TCHAR* file_path); + virtual bool open_ccd_file(const _TCHAR* file_path, _TCHAR* img_file_path); + + virtual uint8_t read_subq(); + virtual uint8_t get_subq_status(); + virtual void set_subq(void); + + int get_track_noop(uint32_t lba); + void get_track_by_track_num(int track); + + uint32_t __FASTCALL lba_to_msf(uint32_t lba); + uint32_t __FASTCALL lba_to_msf_alt(uint32_t lba); + int __FASTCALL get_frames_from_msf(const char *s); + int __FASTCALL hexatoi(const char *s); + + virtual void open_from_cmd(const _TCHAR* file_path); + virtual void close_from_cmd(); + virtual void do_dma_eot(bool by_signal); + + void __FASTCALL write_mcuint_signals(uint32_t val) + { + mcuint_val = (val != 0) ? true : false; + write_signals(&outputs_mcuint, val); + } + void cdrom_debug_log(const char *fmt, ...); + + bool __CDROM_DEBUG_LOG; + bool _USE_CDROM_PREFETCH; + bool force_logging; public: - TOWNS_CDROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : SCSI_CDROM(parent_vm, parent_emu) + TOWNS_CDROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { - my_sprintf_s(vendor_id, 9, "FUJITSU"); - my_sprintf_s(product_id, 17, "CDROM"); - device_type = 0x05; // CD-ROM drive - is_removable = true; - is_hot_swappable = false; // seek_time = 400000; // 400msec (temporary) seek_time = 10.0; bytes_per_sec = 2048 * 75; // speed x1 max_logical_block = 0; access = false; + databuffer = NULL; + status_queue = NULL; + memset(subq_buffer, 0x00, sizeof(subq_buffer)); + + initialize_output_signals(&outputs_drq); + initialize_output_signals(&outputs_mcuint); set_device_name(_T("FM-Towns CD-ROM drive")); + d_dmac = NULL; + // For Debugging, will remove 20200822 K.O + d_cpu = NULL; } ~TOWNS_CDROM() { } virtual void initialize(); virtual void release(); virtual void reset(); - virtual void write_signal(int id, uint32_t data, uint32_t mask); - virtual uint32_t read_signal(int id); + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr); + virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); + + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + virtual uint32_t __FASTCALL read_signal(int id); + + virtual void __FASTCALL event_callback(int event_id, int err); + virtual void __FASTCALL mix(int32_t* buffer, int cnt); - virtual void event_callback(int event_id, int err); - virtual bool process_state(FILEIO* state_fio, bool loading); - // SCSI SPECIFIC COMMANDS - virtual int get_command_length(int value); - virtual void start_command(); + virtual bool mounted(); + virtual bool accessed(); + virtual void open(const _TCHAR* file_path); + virtual void close(); + // for debug + virtual void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_debug_data8(uint32_t addr); + virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data); + bool is_debugger_available() + { + return true; + } + uint64_t get_debug_data_addr_space() + { + return 0x1fff; // Will change + } + + + virtual void set_volume(int volume); + virtual void set_volume(int ch, int decibel_l, int decibel_r); + virtual bool read_buffer(int sectors); + + virtual bool read_raw(int sectors); + virtual bool read_mode1(int sectors); + virtual bool read_mode2(int sectors); + virtual bool read_mode1_iso(int sectors); + + // unique functions // Towns specified command - virtual void set_subq(void); - virtual uint8_t get_subq_status(); - virtual uint8_t read_subq(); + virtual void set_cdda_status(uint8_t status); + int get_track(uint32_t lba); + virtual double get_seek_time(uint32_t lba); + virtual uint8_t read_status(); + virtual const int logical_block_size(); + virtual const int physical_block_size(); + virtual bool write_a_byte(uint8_t val) + { + uint32_t n = val; + n = n & 0xff; +// if(databuffer->count() >= fifo_length) { +// return false; +// } + databuffer->write((int)n); + return true; + } + virtual bool write_bytes(uint8_t* val, int bytes) + { + int n_count = databuffer->count(); + if((val == NULL) || + (n_count >= max_fifo_length) || ((n_count + bytes) >= fifo_length)) { + return false; + } + for(int i = 0; i < bytes; i++) { + int d = ((int)val[i]) & 0xff ; + databuffer->write(d); + } + return true; + } + virtual bool change_buffer_size(int size) + { + if((size <= 0) || (size >= max_fifo_length) || (databuffer == NULL)) return false; + uint8_t tbuf[size]; + if(fifo_length > size) { // truncate + // Dummy read + for(int i = 0; i < (fifo_length - size); i++) { + uint8_t dummy = (uint8_t)(databuffer->read() & 0xff); + } + for(int i = 0; i < size; i++) { + tbuf[i] = (uint8_t)(databuffer->read() & 0xff); + } + databuffer->clear(); + for(int i = 0; i < size; i++) { + databuffer->write(tbuf[i]); + } + } else if(fifo_length < size) { + for(int i = 0; i < fifo_length; i++) { + tbuf[i] = (uint8_t)(databuffer->read() & 0xff); + } + databuffer->clear(); + for(int i = 0; i < fifo_length; i++) { + databuffer->write(tbuf[i]); + } +// for(int i = 0; i < (size - fifo_size); i++) { +// databuffer->write(0); +// } + } + fifo_length = size; + return true; + } + uint8_t get_cdda_status() + { + return cdda_status; + } + + void set_machine_id(uint16_t val) + { + machine_id = val & 0xfff8; + } + void set_cpu_id(uint16_t val) + { + cpu_id = val & 0x07; + } + + void set_context_mpuint_line(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&outputs_mcuint, dev, id, mask); + } + void set_context_drq_line(DEVICE* dev, int id, uint32_t mask) + { + register_output_signal(&outputs_drq, dev, id, mask); + } + void set_context_dmac(DEVICE* d) + { + d_dmac = d; + } + // For Debugging, will remove 20200822 K.O + void set_context_cpu(DEVICE* d) + { + d_cpu = d; + } }; } diff --git a/source/src/vm/fmtowns/towns_common.h b/source/src/vm/fmtowns/towns_common.h new file mode 100644 index 000000000..c5b7465e6 --- /dev/null +++ b/source/src/vm/fmtowns/towns_common.h @@ -0,0 +1,18 @@ +/* + FUJITSU FM Towns Emulator 'eFMTowns' + + Author : Kyuma.Ohta + Date : 2019.12.01 - + + [ common definitions ] +*/ +#pragma once + +// These are common definitions for FM-Towns. +#define SIG_FMTOWNS_RAM_WAIT 0x10000000 +#define SIG_FMTOWNS_ROM_WAIT 0x10000001 +#define SIG_FMTOWNS_VRAM_WAIT 0x10000002 +#define SIG_FMTOWNS_NOTIFY_RESET 0x10000003 +#define TOWNS_CRTC_MAX_LINES 1024 +#define TOWNS_CRTC_MAX_PIXELS 1024 + diff --git a/source/src/vm/fmtowns/towns_crtc.cpp b/source/src/vm/fmtowns/towns_crtc.cpp index b51449dba..ba784533a 100644 --- a/source/src/vm/fmtowns/towns_crtc.cpp +++ b/source/src/vm/fmtowns/towns_crtc.cpp @@ -7,10 +7,13 @@ [ FM-Towns CRTC ] History: 2016.12.28 Initial from HD46505 . */ +#include "../../common.h" #include "towns_crtc.h" #include "towns_vram.h" #include "towns_sprite.h" +#include "fontroms.h" +#include "../debugger.h" namespace FMTOWNS { enum { @@ -44,7 +47,6 @@ void TOWNS_CRTC::initialize() event_id_vsync = -1; event_id_vst1 = -1; event_id_vst2 = -1; - event_id_vblank = -1; event_id_vstart = -1; event_id_hstart = -1; for(int i = 0; i < 2; i++) { @@ -55,7 +57,7 @@ void TOWNS_CRTC::initialize() } for(int i = 0; i < 4; i++) { // ToDo: Allocate at external buffer (when using compute shaders). - linebuffers[i] = malloc(sizeof(linebuffer_t ) * TOWNS_CRTC_MAX_LINES); + linebuffers[i] = (linebuffer_t *)malloc(sizeof(linebuffer_t ) * TOWNS_CRTC_MAX_LINES); if(linebuffers[i] != NULL) { for(int l = 0; l < TOWNS_CRTC_MAX_LINES; l++) { memset(&(linebuffers[i][l]), 0x00, sizeof(linebuffer_t)); @@ -66,10 +68,11 @@ void TOWNS_CRTC::initialize() set_lines_per_frame(512); //set_pixels_per_line(640); - crtc_clock = 28.6363e6; + crtc_clock = 1.0e6 / 28.6363e6; set_frames_per_sec(FRAMES_PER_SEC); // Its dummy. register_frame_event(this); - + voutreg_ctrl = 0x15; + voutreg_prio = 0x00; } void TOWNS_CRTC::release() @@ -77,65 +80,134 @@ void TOWNS_CRTC::release() for(int i = 0; i < 4; i++) { // ToDo: Allocate at external buffer (when using compute shaders). if(linebuffers[i] != NULL) free(linebuffers[i]); + linebuffers[i] = NULL; } } void TOWNS_CRTC::reset() { // initialize - display = false; - vblank = vsync = hsync = true; - + display_enabled = true; + vsync = hsync = false; + fo1_offset_value = 0; // memset(regs, 0, sizeof(regs)); - ch = 0; - + crtc_ch = 0; + sprite_offset = 0x00000; + is_sprite = false; // initial settings for 1st frame req_recalc = false; - timing_changed = false; - disp_end_clock = 0; - sprite_disp_page = 0; // OK? - sprite_enabled = false; // crtc_clock = 28.6363e6; // OK? - + interlace_field = false; + is_compatible = true; + line_count[0] = line_count[1] = 0; vert_line_count = -1; display_linebuf = 0; + + r50_planemask = 0x0f; + r50_pagesel = 0; + dpalette_changed = true; + for(int i = 0; i < 8; i++) { + dpalette_regs[i] = i; + } + apalette_code = 0; + apalette_b = 0; + apalette_r = 0; + apalette_g = 0; + for(int i = 0; i < 16; i++) { + uint16_t r = ((i & 2) != 0) ? 0x7f : 0; + uint16_t g = ((i & 4) != 0) ? 0x7f : 0; + uint16_t b = ((i & 1) != 0) ? 0x7f : 0; + + if((i & 8) != 0) { + r <<= 1; + b <<= 1; + g <<= 1; + if(r != 0) { + r |= 0x1; + } + if(g != 0) { + g |= 0x1; + } + if(b != 0) { + b |= 0x1; + } + } + apalette_16_rgb[0][i][TOWNS_CRTC_PALETTE_R] = r; + apalette_16_rgb[0][i][TOWNS_CRTC_PALETTE_G] = g; + apalette_16_rgb[0][i][TOWNS_CRTC_PALETTE_B] = b; + + apalette_16_rgb[1][i][TOWNS_CRTC_PALETTE_R] = r; + apalette_16_rgb[1][i][TOWNS_CRTC_PALETTE_G] = g; + apalette_16_rgb[1][i][TOWNS_CRTC_PALETTE_B] = b; + if(i == 0) { + apalette_16_pixel[0][0] = RGBA_COLOR(0, 0, 0, 0); + apalette_16_pixel[1][0] = RGBA_COLOR(0, 0, 0, 0); + } else { + apalette_16_pixel[0][i] = RGBA_COLOR(r, g, b, 0xff); + apalette_16_pixel[1][i] = RGBA_COLOR(r, g, b, 0xff); + } + } + for(int i = 0; i < 256; i++) { + uint8_t r = (i & 0x38) << 2; + uint8_t g = i & 0xc0; + uint8_t b = (i & 0x07) << 5; + if(r != 0) r |= 0x1f; + if(b != 0) b |= 0x1f; + if(g != 0) g |= 0x3f; + apalette_256_rgb[i][TOWNS_CRTC_PALETTE_B] = b; + apalette_256_rgb[i][TOWNS_CRTC_PALETTE_R] = r; + apalette_256_rgb[i][TOWNS_CRTC_PALETTE_G] = g; + apalette_256_pixel[i] = RGBA_COLOR(r, g, b, 0xff); + } + for(int i = 0; i < TOWNS_CRTC_MAX_LINES; i++) { line_changed[0][i] = true; - line_rendered[0][i] = false; line_changed[1][i] = true; - line_rendered[1][i] = false; } - - if(event_id_hsync >= 0) cancel_event(this, event_id_hsync); - if(event_id_hsw >= 0) cancel_event(this, event_id_hsw); - if(event_id_vsync >= 0) cancel_event(this, event_id_vsync); - if(event_id_vstart >= 0) cancel_event(this, event_id_vstart); - if(event_id_vst1 >= 0) cancel_event(this, event_id_vst1); - if(event_id_vst2 >= 0) cancel_event(this, event_id_vst2); - if(event_id_vblank >= 0) cancel_event(this, event_id_vblank); - if(event_id_hstart >= 0) cancel_event(this, event_id_hstart); + for(int i = 0; i < 2; i++) { + timing_changed[i] = true; + address_changed[i] = true; + mode_changed[i] = true; + impose_mode[i] = false; // OK? + carry_enable[i] = false; //OK? + } + for(int i = 0; i < 2; i++) { + zoom_factor_vert[i] = 1; + zoom_factor_horiz[i] = 1; + zoom_count_vert[i] = 1; + } for(int i = 0; i < 2; i++) { - if(event_id_vds[i] >= 0) cancel_event(this, event_id_vds[i]); - if(event_id_hds[i] >= 0) cancel_event(this, event_id_hds[i]); - if(event_id_vde[i] >= 0) cancel_event(this, event_id_vde[i]); - if(event_id_hde[i] >= 0) cancel_event(this, event_id_hde[i]); + crtout[i] = true; + crtout_top[i] = true; + } + crtout_reg = 0x0f; + for(int i = 0; i < 4; i++) { + frame_offset[i] = 0; + line_offset[i] = 80; } - event_id_hsw = -1; - event_id_vsync = -1; - event_id_vstart = -1; - event_id_vst1 = -1; - event_id_vst2 = -1; - event_id_vblank = -1; - event_id_hstart = -1; for(int i = 0; i < 2; i++) { - event_id_vds[i] = -1; - event_id_hds[i] = -1; - event_id_vde[i] = -1; - event_id_hde[i] = -1; + vstart_addr[i] = 0; + hstart_words[i] = 0; + head_address[i] = 0; + vert_offset_tmp[i] = 0; + horiz_offset_tmp[i] = 0; } + cancel_event_by_id(event_id_hsync); + cancel_event_by_id(event_id_hsw); + cancel_event_by_id(event_id_vsync); + cancel_event_by_id(event_id_vstart); + cancel_event_by_id(event_id_vst1); + cancel_event_by_id(event_id_vst2); + cancel_event_by_id(event_id_hstart); + for(int i = 0; i < 2; i++) { + cancel_event_by_id(event_id_vds[i]); + cancel_event_by_id(event_id_hds[i]); + cancel_event_by_id(event_id_vde[i]); + cancel_event_by_id(event_id_hde[i]); + } // Register vstart pixels_per_line = 640; lines_per_frame = 400; @@ -143,9 +215,221 @@ void TOWNS_CRTC::reset() set_lines_per_frame(512); //set_pixels_per_line(640); + write_signals(&outputs_int_vsync, 0x0); + + hst_tmp = 640; + vst_tmp = 400; + for(int i = 0; i < 4; i++) { + hst[i] = hst_tmp; + vst[i] = vst_tmp; + } + memset(tvram_snapshot, 0x00, sizeof(tvram_snapshot)); + //osd->set_vm_screen_size((hst <= SCREEN_WIDTH) ? hst : SCREEN_WIDTH, (vst <= SCREEN_HEIGHT) ? vst : SCREEN_HEIGHT, -1, -1, WINDOW_WIDTH_ASPECT, WINDOW_HEIGHT_ASPECT); + //emu->set_vm_screen_lines(vst); + // For DEBUG Only + // Mode 19 +#if 0 + const uint16_t reg_default[] = + { 0x0060, 0x02c0, 0x0000, 0x0000, 0x031f, 0x0000, 0x0004, 0x0000, + 0x0419, 0x008a, 0x018a, 0x008a, 0x030a, 0x0046, 0x0246, 0x0046, + 0x0406, 0x0000, 0x008a, 0x0000, 0x0080, 0x0000, 0x008a, 0x0000, + 0x0080, 0x0058, 0x0001, 0x0000, 0x000d, 0x0002, 0x0000, 0x0192}; + for(int i = 0; i < 32; i++) { + write_io16(0x0440, i); + write_io16(0x0442, reg_default[i]); + } + write_io16(0x0440, 0); +#else force_recalc_crtc_param(); +#endif // register_event(this, EVENT_CRTC_VSTART, vstart_us, false, &event_id_vstart); } + +void TOWNS_CRTC::cancel_event_by_id(int& event_num) +{ + if(event_num > -1) cancel_event(this, event_num); + event_num = -1; +} + +void TOWNS_CRTC::set_vsync(bool val, bool force) +{ + if((vsync != val) || (force)) { + vsync = val; + write_signals(&outputs_int_vsync, (val) ? 0x00000000 : 0xffffffff); +// if(!(val)) write_signals(&outputs_int_vsync, 0xffffffff); + } +} +void TOWNS_CRTC::restart_display() +{ + // ToDo +} + +void TOWNS_CRTC::stop_display() +{ + // ToDo +} + +void TOWNS_CRTC::notify_mode_changed(int layer, uint8_t mode) +{ + // ToDo +} + +// I/Os +// Palette. +void TOWNS_CRTC::calc_apalette(int index) +{ + int layer = 0; + switch(voutreg_prio & 0x30) { + case 0x00: + calc_apalette16(0, index & 0x0f); + break; + case 0x20: + calc_apalette16(1, index & 0x0f); + break; + default: + calc_apalette256(index & 0xff); + break; + } +} + +void TOWNS_CRTC::calc_apalette16(int layer, int index) +{ + index = index & 0x0f; + apalette_r = apalette_16_rgb[layer][index][TOWNS_CRTC_PALETTE_R] & 0xf0; + apalette_g = apalette_16_rgb[layer][index][TOWNS_CRTC_PALETTE_G] & 0xf0; + apalette_b = apalette_16_rgb[layer][index][TOWNS_CRTC_PALETTE_B] & 0xf0; + + if(index == 0) { + apalette_16_pixel[layer][index] = RGBA_COLOR(0, 0, 0, 0); // ?? + } else { + apalette_16_pixel[layer][index] = RGBA_COLOR(apalette_r, apalette_g , apalette_b, 0xff); + } +} + +void TOWNS_CRTC::calc_apalette256(int index) +{ + index = index & 255; + apalette_r = apalette_256_rgb[index][TOWNS_CRTC_PALETTE_R]; + apalette_g = apalette_256_rgb[index][TOWNS_CRTC_PALETTE_G]; + apalette_b = apalette_256_rgb[index][TOWNS_CRTC_PALETTE_B]; + if(index == 0) { + apalette_256_pixel[index] = RGBA_COLOR(0, 0, 0, 0); // ?? + } else { + apalette_256_pixel[index] = RGBA_COLOR(apalette_r, apalette_g, apalette_b, 0xff); + } +} + +void TOWNS_CRTC::set_apalette_r(uint8_t val) +{ + switch(voutreg_prio & 0x30) { + case 0x00: + apalette_16_rgb[0][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_R] = val; + calc_apalette16(0, (int)apalette_code); + break; + case 0x20: + apalette_16_rgb[1][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_R] = val; + calc_apalette16(1, (int)apalette_code); + break; + default: + apalette_256_rgb[apalette_code & 0xff][TOWNS_CRTC_PALETTE_R] = val; + calc_apalette256((int)apalette_code % 256); + break; + } +} + +void TOWNS_CRTC::set_apalette_g(uint8_t val) +{ + switch(voutreg_prio & 0x30) { + case 0x00: + apalette_16_rgb[0][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_G] = val; + calc_apalette16(0, (int)apalette_code); + break; + case 0x20: + apalette_16_rgb[1][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_G] = val; + calc_apalette16(1, (int)apalette_code); + break; + default: + apalette_256_rgb[apalette_code & 0xff][TOWNS_CRTC_PALETTE_G] = val; + calc_apalette256((int)apalette_code % 256); + break; + } +} + +void TOWNS_CRTC::set_apalette_b(uint8_t val) +{ + switch(voutreg_prio & 0x30) { + case 0x00: + apalette_16_rgb[0][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_B] = val; + calc_apalette16(0, (int)apalette_code); + break; + case 0x20: + apalette_16_rgb[1][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_B] = val; + calc_apalette16(1, (int)apalette_code); + break; + default: + apalette_256_rgb[apalette_code & 0xff][TOWNS_CRTC_PALETTE_B] = val; + calc_apalette256((int)apalette_code % 256); + break; + } +} + +uint8_t TOWNS_CRTC::get_apalette_r() +{ + uint8_t val = 0x00; + switch(voutreg_prio & 0x30) { + case 0x00: + val = apalette_16_rgb[0][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_R]; + break; + case 0x20: + val = apalette_16_rgb[1][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_R]; + break; + default: + val = apalette_256_rgb[apalette_code & 0xff][TOWNS_CRTC_PALETTE_R]; + break; + } + return val; +} + +uint8_t TOWNS_CRTC::get_apalette_g() +{ + uint8_t val = 0x00; + switch(voutreg_prio & 0x30) { + case 0x00: + val = apalette_16_rgb[0][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_G]; + break; + case 0x02: + val = apalette_16_rgb[1][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_G]; + break; + default: + val = apalette_256_rgb[apalette_code & 0xff][TOWNS_CRTC_PALETTE_G]; + break; + } + return val; +} + +uint8_t TOWNS_CRTC::get_apalette_b() +{ + uint8_t val = 0x00; + switch(voutreg_prio & 0x30) { + case 0x00: + val = apalette_16_rgb[0][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_B]; + break; + case 0x02: + val = apalette_16_rgb[1][apalette_code & 0x0f][TOWNS_CRTC_PALETTE_B]; + break; + default: + val = apalette_256_rgb[apalette_code & 0xff][TOWNS_CRTC_PALETTE_B]; + break; + } + return val; +} + + +void TOWNS_CRTC::set_apalette_num(uint8_t val) +{ + apalette_code = ((int)val) % 256; +} + // CRTC register #29 void TOWNS_CRTC::set_crtc_clock(uint16_t val) { @@ -154,19 +438,20 @@ void TOWNS_CRTC::set_crtc_clock(uint16_t val) static const double clocks[] = { 28.6363e6, 24.5454e6, 25.175e6, 21.0525e6 }; - if(crtc_clock[clksel] != crtc_clock) { - crtc_clock = crtc_clock[clksel]; + if((1.0e6 / clocks[clksel]) != crtc_clock) { + crtc_clock = 1.0e6 / clocks[clksel]; req_recalc = true; } } void TOWNS_CRTC::force_recalc_crtc_param(void) { + int hst_bak = hst_tmp; + int vst_bak = vst_tmp; horiz_width_posi_us = crtc_clock * ((double)(regs[0] & 0x00fe)); // HSW1 horiz_width_nega_us = crtc_clock * ((double)(regs[1] & 0x00fe)); // HSW2 horiz_us = crtc_clock * ((double)((regs[4] & 0x07fe) + 1)); // HST - vsync_pre_us = ((double)(regs[5] & 0x1f)) * horiz_us; // VST1 - + vst1_us = ((double)(regs[5] & 0x1f)) * horiz_us; // VST1 double horiz_ref = horiz_us / 2.0; vst2_us = ((double)(regs[6] & 0x1f)) * horiz_ref; // VST2 @@ -175,21 +460,71 @@ void TOWNS_CRTC::force_recalc_crtc_param(void) if(frame_us > 0.0) { set_frames_per_sec(1.0e6 / frame_us); // Its dummy. } else { + frame_us = 1.0e6 / FRAMES_PER_SEC; set_frames_per_sec(FRAMES_PER_SEC); // Its dummy. } - +// out_debug_log(_T("RECALC PARAM: horiz_us=%f frame_us=%f"), horiz_us, frame_us); for(int layer = 0; layer < 2; layer++) { + vert_offset_tmp[layer] = (int)(regs[(layer << 1) + 13] & 0x07ff) - (int)(regs[6] & 0x1f); + horiz_offset_tmp[layer] = (int)(regs[(layer << 1) + 9] & 0x07ff) - (int)(regs[0] & 0x00fe); vert_start_us[layer] = ((double)(regs[(layer << 1) + 13] & 0x07ff)) * horiz_ref; // VDSx vert_end_us[layer] = ((double)(regs[(layer << 1) + 13 + 1] & 0x07ff)) * horiz_ref; // VDEx horiz_start_us[layer] = ((double)(regs[(layer << 1) + 9] & 0x07ff)) * crtc_clock ; // HDSx horiz_end_us[layer] = ((double)(regs[(layer << 1) + 9 + 1] & 0x07ff)) * crtc_clock ; // HDEx } +#if 0 +// out_debug_log(_T("RECALC: CRTC_CLOCK=%f MHz FPS=%f"), 1.0 / crtc_clock, 1.0e6 / frame_us); + _TCHAR sdata[32 * 5]; + _TCHAR sdata2[8]; + for(int q = 0; q < 4; q++) { + memset(sdata, 0x00, sizeof(sdata)); + for(int r = 0; r < 8; r++) { + my_sprintf_s(sdata2, 8, "%04X ", regs[r + q * 8]); + my_tcscat_s(sdata, sizeof(sdata) / sizeof(_TCHAR), sdata2); + } +// out_debug_log(_T("RECALC: regs[%02d..%02d]= %s"), q * 8, q * 8 + 7, sdata); + } +// out_debug_log(_T("RECALC: HORIZ_us=%f HORIZ_WIDTH_P_us=%f HORIZ_WIDTH_N_us=%f"), horiz_us, horiz_width_posi_us, horiz_width_nega_us); +// out_debug_log(_T("RECALC: VST1_us=%f VST2_us=%f EET_us=%f frame_us=%f"), vst1_us, vst2_us, eet_us, frame_us); + for(int q = 0; q < 2; q++) { +// out_debug_log(_T("RECALC: LAYER%d: VERT_START_us=%f VERT_END_us=%f HORIZ_START_us=%f HORIZ_END_us=%f"), q, vert_start_us[q], vert_end_us[q], horiz_start_us[q], horiz_end_us[q]); + } +#endif + hst_tmp = (regs[4] & 0x7fe) + 1; + vst_tmp = (regs[8] & 0x7ff) + 1; + if((voutreg_ctrl & 0x10) == 0) { + // Single layer + uint32_t vst_an = (int)(regs[14] & 0x07ff) - (int)(regs[13] & 0x07ff); + if(vst_an <= 1) vst_an = 2; + uint32_t hst_an = (int)(regs[10] & 0x07ff) - (int)(regs[9] & 0x07ff); + if(hst_an <= 8) hst_an = 8; + if(vst_an > 768) vst_an >>= 1; +// hst_tmp = (hst_tmp < hst_an) ? hst_tmp : hst_an; +// vst_tmp = (vst_tmp < vst_an) ? vst_tmp : vst_an; + hst_tmp = hst_an; + vst_tmp = vst_an; + } else { + uint32_t vst_an = (int)(regs[14] & 0x07ff) - (int)(regs[13] & 0x07ff); + if(vst_an <= 1) vst_an = 2; + uint32_t hst_an = (int)(regs[10] & 0x07ff) - (int)(regs[9] & 0x07ff); + if(hst_an <= 8) hst_an = 8; + uint32_t vst_an2 = (int)(regs[16] & 0x07ff) - (int)(regs[15] & 0x07ff); + if(vst_an2 <= 1) vst_an2 = 2; + uint32_t hst_an2 = (int)(regs[12] & 0x07ff) - (int)(regs[11] & 0x07ff); + if(hst_an2 <= 8) hst_an2 = 8; + if(vst_an < vst_an2) vst_an = vst_an2; + if(hst_an < hst_an2) hst_an = hst_an2; + vst_an >>= 1; + /*if(vst_tmp > vst_an) */ vst_tmp = vst_an; + /*if(hst_tmp > hst_an) */ hst_tmp = hst_an; + } req_recalc = false; } -void TONWS_CRTC::write_io8(uint32_t addr, uint32_t data) +void TOWNS_CRTC::write_io8(uint32_t addr, uint32_t data) { +// out_debug_log(_T("WRITE8 ADDR=%04x DATA=%04x"), addr, data); switch(addr) { case 0x0440: crtc_ch = data & 0x1f; @@ -198,7 +533,7 @@ void TONWS_CRTC::write_io8(uint32_t addr, uint32_t data) { pair16_t rdata; rdata.w = regs[crtc_ch]; - rdata.l = (uint8_t)data; + rdata.b.l = (uint8_t)data; write_io16(addr, rdata.w); } break; @@ -206,12 +541,46 @@ void TONWS_CRTC::write_io8(uint32_t addr, uint32_t data) { pair16_t rdata; rdata.w = regs[crtc_ch]; - rdata.h = (uint8_t)data; + rdata.b.h = (uint8_t)data; write_io16(addr, rdata.w); } break; + case 0x0448: + voutreg_num = data & 0x01; + break; case 0x044a: + if(voutreg_num == 0) { + voutreg_ctrl = data; + } else if(voutreg_num == 1) { + voutreg_prio = data; + } + break; + case 0x044c: + break; + case 0x05ca: + write_signals(&outputs_int_vsync, 0x00000000); // Clear VSYNC + break; + case 0xfd90: + set_apalette_num(data); + break; + case 0xfd91: + break; + case 0xfd92: + set_apalette_b(data); + break; + case 0xfd93: + break; + case 0xfd94: + set_apalette_r(data); + break; + case 0xfd95: + break; + case 0xfd96: + set_apalette_g(data); + break; + case 0xfd97: + break; case 0xfd98: case 0xfd99: case 0xfd9a: @@ -220,21 +589,31 @@ void TONWS_CRTC::write_io8(uint32_t addr, uint32_t data) case 0xfd9d: case 0xfd9e: case 0xfd9f: + { + pair32_t n; + n.d = data; + if(addr == 0xfd9f) { + dpalette_regs[7] = n.b.l & 0x0f; + } else { + dpalette_regs[addr & 7] = n.b.l & 0x0f; + dpalette_regs[(addr + 1) & 7] = n.b.h & 0x0f; + } + dpalette_changed = true; + } + break; case 0xfda0: - write_io16(addr, data); + crtout[0] = ((data & 0x0c) != 0) ? true : false; + crtout[1] = ((data & 0x03) != 0) ? true : false; + crtout_reg = data & 0x0f; break; } } void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data) { - switch(addr) { - case 0x0440: - case 0x0441: - crtc_ch = data & 0x1f; - break; +// out_debug_log(_T("WRITE16 ADDR=%04x DATA=%04x"), addr, data); + switch(addr & 0xfffe) { case 0x0442: - case 0x0443: { if(crtc_ch < 32) { if((crtc_ch < 0x09) && ((crtc_ch >= 0x04) || (crtc_ch <= 0x01))) { // HSW1..VST @@ -251,7 +630,7 @@ void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data) }else if(crtc_ch < 0x19) { // FA0..LO1 uint8_t localch = (crtc_ch - 0x11) / 4; uint8_t localreg = (crtc_ch - 0x11) & 3; - if(regs[crtc_ch] != (uint16_t)data) { +// if(regs[crtc_ch] != (uint16_t)data) { address_changed[localch] = true; switch(localreg) { case 0: // FAx @@ -261,15 +640,15 @@ void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data) hstart_words[localch] = (uint32_t)(data & 0x07ff); break; case 2: // FOx - frame_offet[localch] = (uint32_t)(data & 0xffff); + frame_offset[localch] = (uint32_t)(data & 0xffff); break; case 3: // LOx - line_offet[localch] = (uint32_t)(data & 0xffff); + line_offset[localch] = (uint32_t)(data & 0xffff); break; } - } +// } } else { // All reg - if(regs[crtc_ch] != (uint16_t)data) { +// if(regs[crtc_ch] != (uint16_t)data) { switch(crtc_ch - 0x19) { case 0: // EHAJ case 1: // EVAJ @@ -281,28 +660,33 @@ void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data) uint8_t zfh[2]; pair16_t pd; pd.w = (uint16_t)data; - zfv[0] = ((pd.l & 0xf0) >> 4) + 1; - zfh[0] = (pd.l & 0x0f) + 1; - zfv[1] = ((pd.h & 0xf0) >> 4) + 1; - zfh[1] = (pd.h & 0x0f) + 1; + zfv[0] = ((pd.b.l & 0xf0) >> 4) + 1; + zfh[0] = (pd.b.l & 0x0f) + 1; + zfv[1] = ((pd.b.h & 0xf0) >> 4) + 1; + zfh[1] = (pd.b.h & 0x0f) + 1; + /* if((zfv[0] != zoom_factor_vert[0]) || (zfh[0] != zoom_factor_horiz[0])) { timing_changed[0] = true; address_changed[0] = true; if(zfv[0] != zoom_factor_vert[0]) zoom_count_vert[0] = zfv[0]; } if((zfv[1] != zoom_factor_vert[1]) || (zfh[1] != zoom_factor_horiz[1])) { - timing_changed[0] = true; - address_changed[0] = true; + timing_changed[1] = true; + address_changed[1] = true; if(zfv[1] != zoom_factor_vert[1]) zoom_count_vert[1] = zfv[1]; } - zoom_factor_vert[0] = zfv[0]; - zoom_factor_horiz[0] = zfh[0]; - zoom_factor_vert[1] = zfv[1]; - zoom_factor_horiz[1] = zfh[1]; - } + */ + for(int i = 0; i < 2; i++) { + zoom_factor_vert[i] = zfv[i]; + zoom_factor_horiz[i] = zfh[i]; + zoom_count_vert[i] = zfv[i]; + timing_changed[i] = true; + address_changed[i] = true; + } +// } break; case 3: // CR0 - if(regs[crtc_ch] != data) { +// if(regs[crtc_ch] != data) { if((data & 0x8000) == 0) { // START BIT restart_display(); @@ -329,7 +713,7 @@ void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data) } display_mode[i] = dmode[i]; } - } +// } break; case 4: // CR1 set_crtc_clock((uint16_t)data); @@ -346,117 +730,62 @@ void TOWNS_CRTC::write_io16(uint32_t addr, uint32_t data) } } break; - case 0x0448: - case 0x0449: - voutreg_num = data & 0x01; - break; - case 0x044a: - case 0x044b: - if(voutreg_num == 0) { - voutreg_ctrl = data & 0x10; - } else if(voutreg_num == 1) { - voutreg_prio = data & 0x10; - } - break; - case 0xfd98: - case 0xfd99: - case 0xfd9a: - case 0xfd9b: - case 0xfd9c: - case 0xfd9d: - case 0xfd9e: - case 0xfd9f: - { - pair16_t n; - n.d = data; - if(addr == 0xfd9f) { - dpalette_regs[7] = n.l & 0x0f; - } else { - dpalette_regs[addr & 7] = n.l & 0x0f; - dpalette_regs[(addr + 1) & 7] = n.h & 0x0f; - } - dpalette_changed = true; - } - break; - case 0xfda0: - crtout[0] = ((data & 0x0c) != 0) ? true : false; - crtout[1] = ((data & 0x03) != 0) ? true : false; - break; + default: + write_io8(addr & 0xfffe, data); } } uint16_t TOWNS_CRTC::read_reg30() { uint16_t data = 0x00f0; - data |= ((frame_in[1]) ? 0x8000 : 0); - data |= ((frame_in[0]) ? 0x4000 : 0); - data |= ((hdisp[1]) ? 0x2000 : 0); - data |= ((hdisp[0]) ? 0x1000 : 0); - //data |= ((eet) ? 0x0800 : 0); - data |= ((vsync) ? 0x0400 : 0); - data |= (!(hsync) ? 0x0200 : 0); + data |= ((frame_in[1]) ? 0x8000 : 0); + data |= ((frame_in[0]) ? 0x4000 : 0); + data |= ((hdisp[1]) ? 0x2000 : 0); + data |= ((hdisp[0]) ? 0x1000 : 0); + data |= ((interlace_field) ? 0x0800 : 0); + data |= ((vsync) ? 0x0400 : 0); + data |= ((hsync) ? 0x0200 : 0); //data |= ((video_in) ? 0x0100 : 0); //data |= ((half_tone) ? 0x0008 : 0); //data |= ((sync_enable) ? 0x0004 : 0); //data |= ((vcard_enable) ? 0x0002 : 0); //data |= ((sub_carry) ? 0x0001 : 0); - + data = (data & 0xff00 ) | (regs[30] & 0x00ff); + return data; } uint32_t TOWNS_CRTC::read_io16(uint32_t addr) { - switch(addr) { - case 0x0440: - case 0x0441: - return (uint32_t)crtc_ch; - break; +// out_debug_log(_T("READ16 ADDR=%04x"), addr); + if((addr >= 0xfd90) && (addr <= 0xfd97)) { + switch(addr) { + case 0xfd90: + return apalette_code; + break; + case 0xfd92: + return get_apalette_b(); + break; + case 0xfd94: + return get_apalette_r(); + break; + case 0xfd96: + return get_apalette_g(); + break; + } + return 0xff; + } + switch(addr & 0xfffe) { case 0x0442: - case 0x0443: - if(crtc_ch == 30) { + if(crtc_ch == 21) { // FO1 + return ((regs[21] & 0x7fff) + fo1_offset_value); + } else if(crtc_ch == 30) { return (uint32_t)read_reg30(); } else { return regs[crtc_ch]; } break; - case 0x044c: - case 0x044d: - { - uint16_t d = 0xff7c; - d = d | ((dpalette_changed) ? 0x80 : 0x00); - if(d_sprite != NULL) { - d = d | ((d_sprite->read_signal(SIG_TOWNS_SPRITE_BUSY) != 0) ? 0x02 : 0x00); - } - d = d | ((sprite_disp_page != 0) ? 0x01 : 0x00); - dpalette_changed = false; - return d; - } - case 0xfd98: - case 0xfd99: - case 0xfd9a: - case 0xfd9b: - case 0xfd9c: - case 0xfd9d: - case 0xfd9e: - case 0xfd9f: - { - pair16_t n; - if(addr == 0xfd9f) { - n.l = dpalette_regs[7]; - n.h = 0xff; - } else { - n.l = dpalette_regs[addr & 0x07]; - n.h = dpalette_regs[(addr + 1) & 0x07]; - } - return n.w; - } - break; - case 0xfda0: - { - uint16_t d = 0xfffc; - d = d | ((vsync) ? 0x01 : 0); - d = d | ((hsync) ? 0x02 : 0); - return d; - } + default: + return read_io8(addr & 0xfffe); break; } return 0xffff; @@ -464,6 +793,7 @@ uint32_t TOWNS_CRTC::read_io16(uint32_t addr) uint32_t TOWNS_CRTC::read_io8(uint32_t addr) { +// out_debug_log(_T("READ8 ADDR=%04x"), addr); switch(addr) { case 0x0440: return (uint32_t)crtc_ch; @@ -472,24 +802,59 @@ uint32_t TOWNS_CRTC::read_io8(uint32_t addr) { pair16_t d; if(crtc_ch == 30) { - d.w = read_reg32(); + d.w = read_reg30(); } else { d.w = regs[crtc_ch]; } - return (uint32_t)(d.l); + return (uint32_t)(d.b.l); } break; case 0x0443: { pair16_t d; if(crtc_ch == 30) { - d.w = read_reg32(); + d.w = read_reg30(); } else { d.w = regs[crtc_ch]; } - return (uint32_t)(d.h); + return (uint32_t)(d.b.h); + } + break; + case 0x0448: + return voutreg_num; + break; + case 0x044a: + if(voutreg_num == 0) { + return voutreg_ctrl; + } else if(voutreg_num == 1) { + return voutreg_prio; + } + break; + case 0x044c: + { +// uint16_t d = 0x7c; + uint16_t d = 0x00; + d = d | ((dpalette_changed) ? 0x80 : 0x00); + if(d_sprite != NULL) { + d = d | ((d_sprite->read_signal(SIG_TOWNS_SPRITE_BUSY) != 0) ? 0x02 : 0x00); + d = d | ((d_sprite->read_signal(SIG_TOWNS_SPRITE_DISP_PAGE1) != 0) ? 0x01 : 0x00); + } + dpalette_changed = false; + return d; } break; + case 0xfd90: + return apalette_code; + break; + case 0xfd92: + return get_apalette_b(); + break; + case 0xfd94: + return get_apalette_r(); + break; + case 0xfd96: + return get_apalette_g(); + break; case 0xfd98: case 0xfd99: case 0xfd9a: @@ -502,34 +867,51 @@ uint32_t TOWNS_CRTC::read_io8(uint32_t addr) break; case 0xfda0: { - uint8_t d = 0xfc; - d = d | ((vsync) ? 0x01 : 0); - d = d | ((hsync) ? 0x02 : 0); + uint8_t d = 0x00; + d = d | ((vsync) ? 0x01 : 0x00); + d = d | ((hsync) ? 0x02 : 0x00); return d; } break; + case 0xfda2: + if(machine_id >= 0x0700) { // After HR/HG + return (crtout_reg & 0x0f); + } + break; } return 0xff; } -bool TOWND_CRTC::render_32768(scrntype_t* dst, scrntype_t *mask, int y, int width, int layer, bool do_alpha) +bool TOWNS_CRTC::render_32768(scrntype_t* dst, scrntype_t *mask, int y, int layer, bool do_alpha) { if(dst == NULL) return false; - int trans = display_linebuf & 3; + int trans = (display_linebuf == 0) ? 3 : ((display_linebuf - 1) & 3); +// int trans = display_linebuf & 3; int magx = linebuffers[trans][y].mag[layer]; int pwidth = linebuffers[trans][y].pixels[layer]; int num = linebuffers[trans][y].num[layer]; uint8_t *p = linebuffers[trans][y].pixels_layer[layer]; scrntype_t *q = dst; - scrntype_t *r = mask; + scrntype_t *r2 = mask; + if(pwidth <= 0) return false; if(magx < 1) return false; + const int width = ((hst[trans] + 16 * magx) > TOWNS_CRTC_MAX_PIXELS) ? TOWNS_CRTC_MAX_PIXELS : (hst[trans] + 16 * magx); if((pwidth * magx) > width) { pwidth = width / magx; if((width % magx) != 0) { pwidth++; } + } else { + if((pwidth % magx) != 0) { + pwidth = pwidth / magx + 1; + } else { + pwidth = pwidth / magx; + } } +// if(y == 128) { +// out_debug_log("RENDER_32768 Y=%d LAYER=%d WIDTH=%d DST=%08X MASK=%08X ALPHA=%d", y, layer, pwidth, dst, mask, do_alpha); +// } __DECL_ALIGNED(16) uint16_t pbuf[8]; __DECL_ALIGNED(16) uint16_t rbuf[8]; __DECL_ALIGNED(16) uint16_t gbuf[8]; @@ -537,27 +919,37 @@ bool TOWND_CRTC::render_32768(scrntype_t* dst, scrntype_t *mask, int y, int widt __DECL_ALIGNED(32) scrntype_t sbuf[8]; __DECL_ALIGNED(32) scrntype_t abuf[8]; __DECL_ALIGNED(32) uint8_t a2buf[8]; + pair16_t ptmp16; + int rwidth = pwidth & 7; int k = 0; - for(x = 0; x < (pwidth >> 3); x++) { + for(int x = 0; x < (pwidth >> 3); x++) { +__DECL_VECTORIZED_LOOP for(int i = 0; i < 8; i++) { - pbuf[i] = read_2bytes_le_from(p); - p += 2; +// ptmp16.read_2bytes_le_from(p); + ptmp16.b.l = *p++; + ptmp16.b.h = *p++; + pbuf[i] = ptmp16.w; +// p += 2; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < 8; i++) { rbuf[i] = pbuf[i]; gbuf[i] = pbuf[i]; bbuf[i] = pbuf[i]; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < 8; i++) { rbuf[i] = rbuf[i] >> 5; gbuf[i] = gbuf[i] >> 10; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < 8; i++) { rbuf[i] = rbuf[i] & 0x1f; gbuf[i] = gbuf[i] & 0x1f; bbuf[i] = bbuf[i] & 0x1f; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < 8; i++) { rbuf[i] <<= 3; gbuf[i] <<= 3; @@ -565,7 +957,6 @@ bool TOWND_CRTC::render_32768(scrntype_t* dst, scrntype_t *mask, int y, int widt } if(do_alpha) { for(int i = 0; i < 8; i++) { - abuf[i] = (pbuf[i] & 0x8000) ? 0 : (scrntype_t)(-1); a2buf[i] = (pbuf[i] & 0x8000) ? 0 : 255; } for(int i = 0; i < 8; i++) { @@ -573,7 +964,7 @@ bool TOWND_CRTC::render_32768(scrntype_t* dst, scrntype_t *mask, int y, int widt } } else { for(int i = 0; i < 8; i++) { - abuf[i] = (pbuf[i] & 0x8000) ? 0 : (scrntype_t)(-1); + abuf[i] = (pbuf[i] & 0x8000) ? RGBA_COLOR(0, 0, 0, 0) : RGBA_COLOR(255, 255, 255, 255); } for(int i = 0; i < 8; i++) { sbuf[i] = RGBA_COLOR(rbuf[i], gbuf[i], bbuf[i], 255); @@ -583,24 +974,48 @@ bool TOWND_CRTC::render_32768(scrntype_t* dst, scrntype_t *mask, int y, int widt for(int i = 0; i < 8; i++) { *q++ = sbuf[i]; } - if(r != NULL) { + if(r2 != NULL) { for(int i = 0; i < rwidth; i++) { - *r++ = abuf[i]; + *r2++ = abuf[i]; } } k += 8; if(k >= width) break; + } else if(magx == 2) { + int j = pwidth - (k + 16); + if(j < 0) { + j = pwidth - k; + } else if(j > 16) { + j = 16; + } + j >>= 1; +__DECL_VECTORIZED_LOOP + for(int i = 0; i < j; i++) { + q[0] = sbuf[i]; + q[1] = sbuf[i]; + q += 2; + } + if(r2 != NULL) { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < j; i++) { + r2[0] = abuf[i]; + r2[1] = abuf[i]; + r2 += 2; + } + } } else { for(int i = 0; i < 8; i++) { int kbak = k; - for(j = 0; j < magx; j++) { +__DECL_VECTORIZED_LOOP + for(int j = 0; j < magx; j++) { *q++ = sbuf[i]; k++; if(k >= width) break; } - if(r != NULL) { - for(j = 0; j < magx; j++) { - *r++ = abuf[i]; + if(r2 != NULL) { +__DECL_VECTORIZED_LOOP + for(int j = 0; j < magx; j++) { + *r2++ = abuf[i]; kbak++; if(kbak >= width) break; } @@ -610,410 +1025,822 @@ bool TOWND_CRTC::render_32768(scrntype_t* dst, scrntype_t *mask, int y, int widt } } if(k >= width) return true; + if((pwidth & 7) != 0) { - int rwidth = pwidth & 7; +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { - pbuf[i] = read_2bytes_le_from(p); + ptmp16.read_2bytes_le_from(p); + pbuf[i] = ptmp16.w; p += 2; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { rbuf[i] = pbuf[i]; gbuf[i] = pbuf[i]; bbuf[i] = pbuf[i]; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { rbuf[i] = (rbuf[i] >> 5) & 0x1f; gbuf[i] = (gbuf[i] >> 10) & 0x1f; bbuf[i] = bbuf[i] & 0x1f; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { rbuf[i] <<= 3; gbuf[i] <<= 3; bbuf[i] <<= 3; } if(do_alpha) { +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { - abuf[i] = (pbuf[i] & 0x8000) ? 0 : (scrntype_t)(-1); a2buf[i] = (pbuf[i] & 0x8000) ? 0 : 255; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { sbuf[i] = RGBA_COLOR(rbuf[i], gbuf[i], bbuf[i], a2buf[i]); } } else { +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { - abuf[i] = (pbuf[i] & 0x8000) ? 0 : (scrntype_t)(-1); + abuf[i] = (pbuf[i] & 0x8000) ? RGBA_COLOR(0, 0, 0, 0) : RGBA_COLOR(255, 255, 255, 255); } +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { sbuf[i] = RGBA_COLOR(rbuf[i], gbuf[i], bbuf[i], 255); } } if(magx == 1) { +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { *q++ = sbuf[i]; } - if(r != NULL) { + if(r2 != NULL) { +__DECL_VECTORIZED_LOOP for(int i = 0; i < rwidth; i++) { - *r++ = abuf[i]; + *r2++ = abuf[i]; } } k += 8; - if(k >= width) break; + if(k >= width) return true; + } else if(magx == 2) { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < rwidth; i++) { + q[0] = sbuf[i]; + q[1] = sbuf[i]; + q += 2; + } + if(r2 != NULL) { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < rwidth; i++) { + r2[0] = abuf[i]; + r2[1] = abuf[i]; + r2 += 2; + } + } + k += 16; + if(k >= width) return true; } else { for(int i = 0; i < rwidth; i++) { - if(j = 0; j < magx; j++) { +__DECL_VECTORIZED_LOOP + for(int j = 0; j < magx; j++) { *q++ = sbuf[i]; - if(r != NULL) { - *r++ = abuf[i]; + if(r2 != NULL) { + *r2++ = abuf[i]; } k++; if(k >= width) break; } - if(k >= width) break; + if(k >= width) return true; } } } return true; } -bool TOWND_CRTC::render_16(scrntype_t* dst, scrntype_t *mask, scrntype_t* pal, int y, int width, int layer, bool do_alpha) +bool TOWNS_CRTC::render_256(scrntype_t* dst, int y) { - if(dst == NULL) return; + // 256 colors + if(dst == NULL) return false; + int trans = (display_linebuf == 0) ? 3 : ((display_linebuf - 1) & 3); +// int trans = display_linebuf & 3; + int magx = linebuffers[trans][y].mag[0]; + int pwidth = linebuffers[trans][y].pixels[0]; + int num = linebuffers[trans][y].num[0]; + uint8_t *p = linebuffers[trans][y].pixels_layer[0]; + int bitshift0 = linebuffers[trans][y].bitshift[0]; + if(pwidth <= 0) return false; + const int width = ((hst[trans] + 16 * magx) > TOWNS_CRTC_MAX_PIXELS) ? TOWNS_CRTC_MAX_PIXELS : (hst[trans] + 16 * magx); + if((pwidth * magx) > width) { + pwidth = width / magx; + if((width % magx) != 0) { + pwidth++; + } + } else { + if((pwidth % magx) != 0) { + pwidth = pwidth / magx + 1; + } else { + pwidth = pwidth / magx; + } + } - int trans = display_linebuf & 3; + __DECL_ALIGNED(32) scrntype_t apal256[256]; + my_memcpy(apal256, apalette_256_pixel, sizeof(scrntype_t) * 256); + + __DECL_ALIGNED(16) uint8_t pbuf[16]; + __DECL_ALIGNED(32) scrntype_t sbuf[16]; +// out_debug_log(_T("Y=%d MAGX=%d WIDTH=%d pWIDTH=%d"), y, magx, width, pwidth); + if(magx < 1) { + return false; + } + if(magx == 1) { +// if(pwidth < width) pwidth = width; + if(pwidth < 1) pwidth = 1; + int xx = 0; + for(int x = 0; x < (pwidth >> 4); x++) { + // ToDo: Start position + for(int i = 0; i < 16; i++) { + pbuf[i] = *p++; + } + for(int i = 0; i < 16; i++) { + dst[xx++] = apal256[pbuf[i]]; + } + } + if((pwidth & 15) != 0) { + int w = pwidth & 15; + for(int i = 0; i < w; i++) { + pbuf[i] = *p++; + } + for(int i = 0; i < w; i++) { + dst[xx++] = apal256[pbuf[i]]; + } + } + } else { + int k = 0; + for(int x = 0; x < (pwidth >> 4); x++) { + // ToDo: Start position +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + pbuf[i] = p[i]; + } + p += 16; +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + sbuf[i] = apal256[pbuf[i]]; + } +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + scrntype_t s = sbuf[i]; + for(int j = 0; j < magx; j++) { + lbuffer0[k++] = s; + if(k >= width) break; + } + if(k >= width) break; + } + if(k >= width) break; + } + if((pwidth & 15) != 0) { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < (pwidth & 15); i++) { + pbuf[i] = p[i]; + } +__DECL_VECTORIZED_LOOP + for(int i = 0; i < (pwidth & 15); i++) { + sbuf[i] = apal256[pbuf[i]]; + } +__DECL_VECTORIZED_LOOP + for(int i = 0; i < (pwidth & 15); i++) { + scrntype_t s = sbuf[i]; + for(int j = 0; j < magx; j++) { + lbuffer0[k++] = s; + if(k >= width) break; + } + if(k >= width) break; + } + } + } + return true; +} +bool TOWNS_CRTC::render_16(scrntype_t* dst, scrntype_t *mask, scrntype_t* pal, int y, int layer, bool do_alpha) +{ + if(dst == NULL) return false; + + int trans = (display_linebuf == 0) ? 3 : ((display_linebuf - 1) & 3); +// int trans = display_linebuf & 3; int magx = linebuffers[trans][y].mag[layer]; int pwidth = linebuffers[trans][y].pixels[layer]; - int num = linebuffers[trans][y].num[layer]; + //int num = linebuffers[trans][y].num[layer]; uint8_t *p = linebuffers[trans][y].pixels_layer[layer]; scrntype_t *q = dst; - scrntype_t *r = mask; - + scrntype_t *r2 = mask; + if(pwidth <= 0) return false; if(magx < 1) return false; + const int width = ((hst[trans] + 16 * magx) > TOWNS_CRTC_MAX_PIXELS) ? TOWNS_CRTC_MAX_PIXELS : (hst[trans] + 16 * magx); if((pwidth * magx) > width) { pwidth = width / magx; if((width % magx) != 0) { pwidth++; } + } else { + if((pwidth % magx) != 0) { + pwidth = pwidth / magx + 1; + } else { + pwidth = pwidth / magx; + } } __DECL_ALIGNED(16) uint8_t pbuf[8]; __DECL_ALIGNED(16) uint8_t hlbuf[16]; + __DECL_ALIGNED(16) uint8_t mbuf[16]; __DECL_ALIGNED(32) scrntype_t sbuf[16]; __DECL_ALIGNED(32) scrntype_t abuf[16]; - scrntype_t palbuf[16]; + __DECL_ALIGNED(32) scrntype_t a2buf[16]; + + __DECL_ALIGNED(32) scrntype_t palbuf[16]; + uint8_t pmask = linebuffers[trans][y].r50_planemask & 0x0f; +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + mbuf[i] = pmask; + } if(pal == NULL) { - for(int i = 1; i < 16; i++) { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { uint8_t r, g,b; r = ((i & 2) != 0) ? (((i & 8) != 0) ? 255 : 128) : 0; g = ((i & 4) != 0) ? (((i & 8) != 0) ? 255 : 128) : 0; b = ((i & 1) != 0) ? (((i & 8) != 0) ? 255 : 128) : 0; palbuf[i] = RGBA_COLOR(r, g, b, 255); } - palbuf[0] = 0; - pal = palbuf; + } else { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + palbuf[i] = pal[i]; + } } + palbuf[0] = RGBA_COLOR(0, 0, 0, 0); + static const __DECL_ALIGNED(32) scrntype_t maskdata[16] = + { + RGBA_COLOR(0, 0, 0, 0), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255), + RGBA_COLOR(255, 255, 255, 255) + }; + + int k = 0; - for(x = 0; x < (pwidth >> 3); x++) { + for(int x = 0; x < (pwidth >> 3); x++) { +__DECL_VECTORIZED_LOOP for(int i = 0; i < 8; i++) { pbuf[i] = *p++; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < 16; i += 2) { hlbuf[i] = pbuf[i >> 1]; - hlbuf[i + 1] = pbuf[i >> 1]; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < 16; i += 2) { - hlbuf[i] >>= 4;; - hlbuf[i + 1] = hlbuf[i + 1] & 15; - } - for(int i = 0; i < 16; i++) { - abuf[i] = (hlbuf[ii] == 0) ? 0 : (scrntype_t)(-1); + hlbuf[i + 1] = hlbuf[i]; + } +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i += 2) { + hlbuf[i + 1] >>= 4; } +__DECL_VECTORIZED_LOOP for(int i = 0; i < 16; i++) { - sbuf[i] = (hlbuf[i] == 0) ? RGBA_COLOR(0, 0, 0, 0) : pal[hlbuf[i]]; + hlbuf[i] &= mbuf[i]; } - if(magx == 1) { + if(do_alpha) { +__DECL_VECTORIZED_LOOP for(int i = 0; i < 16; i++) { - *q++ = sbuf[i]; + sbuf[i] = palbuf[hlbuf[i]]; + } + } else { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { +// abuf[i] = (hlbuf[i] == 0) ? RGBA_COLOR(0, 0, 0, 0): RGBA_COLOR(255, 255, 255, 255); + abuf[i] = maskdata[hlbuf[i]]; + } +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + sbuf[i] = palbuf[hlbuf[i]]; } - if(r != NULL) { + } + + if(do_alpha) { + if(magx == 1) { +__DECL_VECTORIZED_LOOP for(int i = 0; i < 16; i++) { - *r++ = abuf[i]; + q[i] = sbuf[i]; } + k += 16; + q += 16; + if(k >= width) break; + } else { + for(int i = 0; i < 16; i++) { +__DECL_VECTORIZED_LOOP + for(int j = 0; j < magx; j++) { + q[j] = sbuf[i]; + k++; + if(k >= width) break; + } + q += magx; + } + if(k >= width) break; } - k += 16; - if(k >= width) break; } else { - for(int i = 0; i < 16; i++) { - int kbak = k; - if(j = 0; j < magx; j++) { - *q++ = sbuf[i]; - k++; - if(k >= width) break; + if(magx == 1) { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + q[i] = sbuf[i]; } - if(r != NULL) { - for(j = 0; j < magx; j++) { - *r++ = abuf[i]; - kbak++; - if(kbak >= width) break; + q += 16; + if(r2 != NULL) { +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + r2[i] = abuf[i]; + } + r2 += 16; + } + k += 16; + if(k >= width) break; + } else { + for(int i = 0; i < 16; i++) { + int kbak = k; +__DECL_VECTORIZED_LOOP + for(int j = 0; j < magx; j++) { + q[j] = sbuf[i]; + k++; + if(k >= width) break; + } + q += magx; + if(r2 != NULL) { +__DECL_VECTORIZED_LOOP + for(int j = 0; j < magx; j++) { + r2[j] = abuf[i]; + kbak++; + if(kbak >= width) break; + } + r2 += magx; } + if(k >= width) break; } - if(k >= width) break; } } } if(k >= width) return true; - int rwidth = pwidth & 7; uint8_t tmpp; uint8_t tmph; uint8_t tmpl; + scrntype_t ah, al; + int rwidth = pwidth & 7; if(rwidth > 0) { - for(x = 0; x < rwidth; x++) { + for(int x = 0; x < rwidth; x++) { tmpp = *p++; tmph = tmpp >> 4; tmpl = tmpp & 0x0f; - ah = (tmph == 0) ? 0 : (scrntype_t)(-1); - al = (tmpl == 0) ? 0 : (scrntype_t)(-1); - sbuf[0] = (tmph == 0) ? RGBA_COLOR(0, 0, 0, 0) : pal[tmph]; - sbuf[1] = (tmpl == 0) ? RGBA_COLOR(0, 0, 0, 0) : pal[tmpl]; + sbuf[0] = palbuf[tmph]; + sbuf[1] = palbuf[tmpl]; - if(magx == 1) { - *q++ = sbuf[0]; - if(r != NULL) { - *r++ = ah; - } - k++; - if(k >= width) break; - *q++ = sbuf[1]; - if(r != NULL) { - *r++ = al; - } - k++; - if(k >= width) break; - } else { - for(int j = 0; j < magx; j++) { + if(do_alpha) { + if(magx == 1) { + *q++ = sbuf[0]; + k++; + if(k >= width) break; + *q++ = sbuf[1]; + k++; + if(k >= width) break; + } else { + for(int xx = 0; xx < magx; xx++) { + *q++ = sbuf[0]; + k++; + if(k >= width) break; + } + if(k >= width) break; + for(int xx = 0; xx < magx; xx++) { + *q++ = sbuf[1]; + k++; + if(k >= width) break; + } + if(k >= width) break; + } + } else { + ah = (tmph == 0) ? RGBA_COLOR(0, 0, 0, 0) : RGBA_COLOR(255, 255, 255, 255); + al = (tmpl == 0) ? RGBA_COLOR(0, 0, 0, 0) : RGBA_COLOR(255, 255, 255, 255); + if(magx == 1) { *q++ = sbuf[0]; - if(r != NULL) { - *r++ = ah; + if(r2 != NULL) { + *r2++ = ah; } k++; if(k >= width) break; - } - if(k >= width) break; - for(int j = 0; j < magx; j++) { *q++ = sbuf[1]; - if(r != NULL) { - *r++ = al; + if(r2 != NULL) { + *r2++ = al; } k++; if(k >= width) break; + } else { + for(int j = 0; j < magx; j++) { + *q++ = sbuf[0]; + if(r2 != NULL) { + *r2++ = ah; + } + k++; + if(k >= width) break; + } + for(int j = 0; j < magx; j++) { + *q++ = sbuf[1]; + if(r2 != NULL) { + *r2++ = al; + } + k++; + if(k >= width) break; + } + if(k >= width) break; } - if(k >= width) break; } } } return true; } +inline void TOWNS_CRTC::transfer_pixels(scrntype_t* dst, scrntype_t* src, int w) +{ + if((dst == NULL) || (src == NULL) || (w <= 0)) return; +// for(int i = 0; i < w; i++) { +// dst[i] = src[i]; +// } + my_memcpy(dst, src, w * sizeof(scrntype_t)); +} +// This function does alpha-blending. +// If CSP support hardware-accelalations, will support. +// (i.e: Hardware Alpha blending, Hardware rendaring...) +void TOWNS_CRTC::mix_screen(int y, int width, bool do_mix0, bool do_mix1) +{ + if(width >= TOWNS_CRTC_MAX_PIXELS) return; + if(width <= 0) return; + + int trans = (display_linebuf == 0) ? 3 : ((display_linebuf - 1) & 3); + + int bitshift0 = linebuffers[trans][y].bitshift[0]; + int bitshift1 = linebuffers[trans][y].bitshift[1]; + scrntype_t *pp = osd->get_vm_screen_buffer(y); +// out_debug_log(_T("MIX_SCREEN Y=%d DST=%08X"), y, pp); + /* + if(width < -(bitshift0)) { + do_mix0 = false; + } else if(width < bitshift0) { + do_mix0 = false; + } + if(width < -(bitshift1)) { + do_mix1 = false; + } else if(width < bitshift1) { + do_mix1 = false; + } + */ + if(pp != NULL) { + if((do_mix0) && (do_mix1)) { + // alpha blending + __DECL_ALIGNED(32) scrntype_t pixbuf0[8]; + __DECL_ALIGNED(32) scrntype_t pixbuf1[8]; + __DECL_ALIGNED(32) scrntype_t maskbuf_front[8]; + __DECL_ALIGNED(32) scrntype_t maskbuf_back[8]; + int of0 = 0; + int of1 = 0; + if(bitshift0 < 0) { + of0 = -bitshift0; + } else if(bitshift0 > 0) { + of0 = bitshift0; + } + if(bitshift1 < 0) { + of1 = -bitshift1; + } else if(bitshift0 > 0) { + of1 = bitshift1; + } + for(int xx = 0; xx < width; xx += 8) { +__DECL_VECTORIZED_LOOP + for(int ii = 0; ii < 8; ii++) { + pixbuf1[ii] = 0; + pixbuf0[ii] = 0; + maskbuf_front[ii] = 0; + } + scrntype_t *px1 = &(lbuffer1[xx + of1]); +__DECL_VECTORIZED_LOOP + for(int ii = 0; ii < 8; ii++) { + pixbuf1[ii] = px1[ii]; + } + scrntype_t *px0 = &(lbuffer0[xx + of0]); + scrntype_t *ax = &(abuffer0[xx + of0]); + for(int ii = 0; ii < 8; ii++) { + pixbuf0[ii] = px0[ii]; + maskbuf_front[ii] = ax[ii]; + } +__DECL_VECTORIZED_LOOP + for(int ii = 0; ii < 8; ii++) { + maskbuf_back[ii] = ~maskbuf_front[ii]; + } +__DECL_VECTORIZED_LOOP + for(int ii = 0; ii < 8; ii++) { + pixbuf1[ii] = pixbuf1[ii] & maskbuf_back[ii]; + pixbuf0[ii] = pixbuf0[ii] & maskbuf_front[ii]; + } +__DECL_VECTORIZED_LOOP + for(int ii = 0; ii < 8; ii++) { + pixbuf0[ii] = pixbuf0[ii] | pixbuf1[ii]; + } +__DECL_VECTORIZED_LOOP + for(int ii = 0; ii < 8; ii++) { + pp[ii] = pixbuf0[ii]; + } + pp += 8; + } + int rrwidth = width & 7; + if(rrwidth > 0) { + scrntype_t pix0, pix1, mask0, mask1; + int xptr = width & 0x7f8; // Maximum 2048 pixs + scrntype_t *px1 = &(lbuffer1[xptr + of1]); + scrntype_t *px0 = &(lbuffer0[xptr + of0]); + scrntype_t *ax = &(abuffer0[xptr + of0]); +__DECL_VECTORIZED_LOOP + for(int ii = 0; ii < rrwidth; ii++) { + pix0 = px0[ii]; + mask0 = ax[ii]; + pix1 = px1[ii]; + mask1 = ~mask0; + pix0 = pix0 & mask0; + pix1 = pix1 & mask1; + pix0 = pix0 | pix1; + pp[ii] = pix0; + } + } + } else if(do_mix0) { + if(bitshift0 < 0) { + if(-(bitshift0) < width) { + transfer_pixels(pp, &(lbuffer0[-bitshift0]), width); + } + } else if(bitshift0 > 0) { + transfer_pixels(pp, &(lbuffer1[bitshift0]), width); + } else { + transfer_pixels(pp, lbuffer0, width); + } + } else if(do_mix1) { + if(bitshift1 < 0) { + if(-(bitshift1) < width) { + transfer_pixels(pp, &(lbuffer1[-bitshift1]), width); + } + } else if(bitshift1 > 0) { + transfer_pixels(pp, &(lbuffer1[bitshift1]), width); + } else { + transfer_pixels(pp, lbuffer1, width); + } + } else { + memset(pp, 0x00, width * sizeof(scrntype_t)); + } + } +} + void TOWNS_CRTC::draw_screen() { int trans = (display_linebuf == 0) ? 3 : ((display_linebuf - 1) & 3); + int trans2 = ((display_linebuf - 2) & 3); bool do_alpha = false; // ToDo: Hardware alpha rendaring. if((linebuffers[trans] == NULL) || (d_vram == NULL)) { - //display_linebuf = (display_linebuf + 1) & 3; return; } + int lines = vst[trans]; + int width = hst[trans]; + // Will remove. + if(lines <= 0) lines = 1; + if(width <= 16) width = 16; - __DECL_ALIGNED(32) scrntype_t apal16[2][16]; - __DECL_ALIGNED(32) scrntype_t apal256[256]; - - { - vm->lock_vm(); - d_vram->get_analog_palette(0, &(apal16[0][0])); - d_vram->get_analog_palette(0, &(apal16[1][0])); - d_vram->get_analog_palette(2, apal256); - vm->unlock_vm(); - } - - int lines = lines_per_frame; - int width = pixels_per_line; if(lines > TOWNS_CRTC_MAX_LINES) lines = TOWNS_CRTC_MAX_LINES; if(width > TOWNS_CRTC_MAX_PIXELS) width = TOWNS_CRTC_MAX_PIXELS; - // ToDo: faster alpha blending. - __DECL_ALIGNED(32) scrntype_t lbuffer0[TOWNS_CRTC_MAX_PIXELS + 16]; - __DECL_ALIGNED(32) scrntype_t lbuffer1[TOWNS_CRTC_MAX_PIXELS + 16]; - __DECL_ALIGNED(32) scrntype_t abuffer0[TOWNS_CRTC_MAX_PIXELS + 16]; - __DECL_ALIGNED(32) scrntype_t abuffer1[TOWNS_CRTC_MAX_PIXELS + 16]; + osd->set_vm_screen_size(width, lines, SCREEN_WIDTH, SCREEN_HEIGHT, -1, -1); + osd->set_vm_screen_lines(lines); +// if((lines != vst[trans2]) || (width != hst[trans])) { +// return; // Wait (a frame) if surface attributes are changed +// } + memset(lbuffer1, 0x00, sizeof(lbuffer1)); - memset(abuffer1, 0x00, sizeof(abuffer1)); + memset(abuffer1, 0xff, sizeof(abuffer1)); memset(lbuffer0, 0x00, sizeof(lbuffer0)); - memset(abuffer0, 0x00, sizeof(abuffer0)); - - scrntype_t *dst; + memset(abuffer0, 0xff, sizeof(abuffer0)); + bool is_single = false; + if((voutreg_ctrl & 0x10) == 0) is_single = true; + for(int y = 0; y < lines; y++) { bool do_mix0 = false; bool do_mix1 = false; - if(linebuffers[trans].mode[0] == DISPMODE_256) { - // 256 colors - do_mix0 = true; - int magx = linebuffers[trans].mag[0]; - int pwidth = linebuffers[trans].pixels[0]; - int num = linebuffers[trans].num[0]; - uint8_t *p = linebuffers[trans].pixels_layer[0]; - __DECL_ALIGNED(16) uint8_t pbuf[16]; - __DECL_ALIGNED(32) scrntype_t sbuf[16]; - if(magx < 1) { - continue; - } - if(magx == 1) { - if(pwidth > width) pwidth = width; - for(int x = 0; x < (pwidth >> 4); x++) { - // ToDo: Start position - for(int i = 0; i < 16; i++) { - pbuf[i] = *p++; - } - int xx = x << 4; - for(int i = 0; i < 16; i++) { - lbuffer1[xx++] = apal256[pbuf[i]]; - } - } - if((pwidth & 15) != 0) { - int xx = pwidth & ~15; - int w = pwidth & 15; - for(int i = 0; i < w; i++) { - pbuf[i] = p++; - } - for(int i = 0; i < w; i++) { - lbuffer1[xx++] = apal256[pbuf[i]]; - } - } - } else { - if((pwidth * magx) > width) { - pwidth = width / magx; - if((width % magx) != 0) pwidth++; - } - int k = 0; - for(int x = 0; x < (pwidth >> 4); x++) { - // ToDo: Start position - for(int i = 0; i < 16; i++) { - pbuf[i] = *p++; - } - for(int i = 0; i < 16; i++) { - sbuf[i] = apal256[pbuf[i]]; - } - for(int i = 0; i < 16; i++) { - scrntype_t s = sbuf[i]; - for(int j = 0; j < magx; j++) { - lbuffer1[k++] = s; - } - } - } - if((pwidth & 15) != 0) { - for(int i = 0; i < (pwidth & 15); i++) { - pbuf[i] = *p++; - } - for(int i = 0; i < (pwidth & 15); i++) { - sbuf[i] = apal256[pbuf[i]]; - } - for(int i = 0; i < (pwidth & 15); i++) { - scrntype_t s = sbuf[i]; - for(int j = 0; j < magx; j++) { - lbuffer1[k++] = s; - if(k >= width) break; - } - if(k > width) break; - } + if(is_single) { + if(linebuffers[trans][y].crtout[0] != 0) { + switch(linebuffers[trans][y].mode[0]) { + case DISPMODE_256: + do_mix0 = render_256(lbuffer0, y); + break; + case DISPMODE_32768: + do_mix0 = render_32768(lbuffer0, abuffer0, y, 0, do_alpha); + break; + default: // 16 Colors mode don't allow with single layer mode. + break; } } + } else { - if(linebuffers[trans].mode[1] == DISPMODE_16) { // Lower layer - do_mix1 = render_16(lbuffer1, abuffer1, &(apal16[linebuffers[trans].num[1]][0]), y, width, 1, do_alpha); - } else if(linebuffers[trans].mode[1] == DISPMODE_32768) { // Lower layer - do_mix1 = render_32768(lbuffer1, abuffer1, y, width, 1, do_alpha); + + __DECL_ALIGNED(32) scrntype_t apal16[2][16]; + my_memcpy(apal16[0], apalette_16_pixel[0], sizeof(scrntype_t) * 16); + my_memcpy(apal16[1], apalette_16_pixel[1], sizeof(scrntype_t) * 16); + int prio0 = linebuffers[trans][y].num[0]; + int prio1 = linebuffers[trans][y].num[1]; + if(linebuffers[trans][y].crtout[prio1] != 0) { + switch(linebuffers[trans][y].mode[prio1]) { + case DISPMODE_16: + do_mix1 = render_16(lbuffer1, abuffer1, &(apal16[prio1][0]), y, linebuffers[trans][y].num[1], do_alpha); + break; + case DISPMODE_32768: + do_mix1 = render_32768(lbuffer1, abuffer1, y, prio1, do_alpha); + break; + default: // 256 Colors mode don't allow in 2 layers mode. + do_mix1 = false; + break; + } } // Upper layer - if(linebuffers[trans].mode[0] == DISPMODE_16) { // Lower layer - do_mix0 = render_16(lbuffer0, abuffer0, &(apal16[linebuffers[trans].num[0]][0]), y, width, 0, do_alpha); - } else if(linebuffers[trans].mode[1] == DISPMODE_32768) { // Lower layer - do_mix0 = render_32768(lbuffer0, abuffer0, y, width, 1, do_alpha); + if(linebuffers[trans][y].crtout[prio0] != 0){ + switch(linebuffers[trans][y].mode[prio0]) { + case DISPMODE_16: + do_mix0 = render_16(lbuffer0, abuffer0, &(apal16[prio0][0]), y, prio0, do_alpha); + break; + case DISPMODE_32768: + do_mix0 = render_32768(lbuffer0, abuffer0, y, prio0, do_alpha); + break; + default: // 256 Colors mode don't allow in 2 layers mode. + do_mix0 = false; + break; + } } } - // ToDo: alpha blending + mix_screen(y, width, do_mix0, do_mix1); + } + + //display_linebuf = (display_linebuf + 1) & 3; + return; +} + +// From MAME 0.216 +// ToDo: Will refine. +uint32_t TOWNS_CRTC::get_font_address(uint32_t c, uint8_t &attr) +{ + static const uint32_t addr_base_jis = 0x00000; + static const uint32_t addr_base_ank = 0x3d800; + uint32_t romaddr = 0; + attr = tvram_snapshot[c + 1]; + switch(attr & 0xc0) { + case 0x00: { - vm->lock_vm(); - scrntype_t *pp = emu->get_screen_buffer(y); - if(pp != NULL) { - if((do_mix0) && (do_mix1)) { - // alpha blending - __DECL_ALIGNED(32) scrntype_t pixbuf0[8]; - __DECL_ALIGNED(32) scrntype_t pixbuf1[8]; - __DECL_ALIGNED(32) scrntype_t maskbuf[8]; - for(int xx = 0; xx < width; xx += 8) { - scrntype_t *px1 = &(lbuffer1[xx]); - scrntype_t *ax = &(abuffer0[xx]); - for(int ii = 0; ii < 8; ii++) { - pixbuf1[ii] = px1[ii]; - maskbuf[ii] = ax[ii]; - } - scrntype_t *px0 = &(lbuffer0[xx]); - - for(int ii = 0; ii < 8; ii++) { - pixbuf0[ii] = px0[ii]; - } - for(int ii = 0; ii < 8; ii++) { - pixbuf1[ii] = pixbuf1[ii] & ~(abuffer0[xx]); - pixbuf0[ii] = pixbuf0[ii] & abuffer0[xx]; - } - for(int ii = 0; ii < 8; ii++) { - pixbuf0[ii] = pixbuf0[ii] | pixbuf1[ii]; - } - for(int ii = 0; ii < 8; ii++) { - *pp++ = pixbuf0[ii]; - } + uint8_t ank = tvram_snapshot[c]; + romaddr = addr_base_ank + (ank * 16); + } + break; + case 0x40: + { // KANJI LEFT + pair32_t jis; + jis.b.h = tvram_snapshot[c + 0x2000]; // CA000-CAFFF + jis.b.l = tvram_snapshot[c + 0x2001]; // CA000-CAFFF + if(jis.b.h < 0x30) { + romaddr = + (((uint32_t)(jis.b.l & 0x1f)) << 4) | + ((uint32_t)((jis.b.l - 0x20) & 0x20) << 8) | + ((uint32_t)((jis.b.l - 0x20) & 0x40) << 6) | + (((uint32_t)(jis.b.h & 0x07)) << 9); + romaddr <<= 1; + } else if(jis.b.h < 0x70) { + romaddr = + (((uint32_t)(jis.b.l & 0x1f)) << 5) + + ((uint32_t)((jis.b.l - 0x20) & 0x60) << 9) + + ((uint32_t)((jis.b.h & 0x0f)) << 10) + + ((uint32_t)((jis.b.h - 0x30) & 0x70) * 0xc00) + + 0x8000; + } else { + romaddr = + (((uint32_t)(jis.b.l & 0x1f)) << 4) | + ((uint32_t)((jis.b.l - 0x20) & 0x20) << 8) | + ((uint32_t)((jis.b.l - 0x20) & 0x40) << 6) | + (((uint32_t)(jis.b.h & 0x07)) << 9); + romaddr <<= 1; + romaddr |= 0x38000; + } + romaddr = addr_base_jis + romaddr; + } + break; + default: // KANJI RIGHT or ILLEGAL + return 0; + } + return romaddr; +} + +void TOWNS_CRTC::render_text() +{ +// uint32_t linesize = regs[24] * 4; + int c = 0; + uint32_t plane_offset = 0x40000 + ((r50_pagesel != 0) ? 0x20000 : 0x00000); + for(int y = 0; y < 25; y++) { + uint32_t linesize = regs[24] * 4; + uint32_t addr_of = y * (linesize * 16); + if(c >= 0x1000) break; + uint32_t romaddr = 0; + for(int x = 0; x < 80; x++) { + uint8_t attr; + uint32_t t = get_font_address(c, attr); + if(((attr & 0xc0) == 0) || ((attr & 0xc0) == 0x40)) { + // ANK OR KANJI LEFT + romaddr = t; + } else if((attr & 0xc0) == 0x80) { + // KANJI RIGHT + romaddr = romaddr + 1; + } else { + // Illegal + addr_of = (addr_of + 4) & 0x3ffff; + c += 2; + continue; + } + // Get data + uint32_t color = attr & 0x07; + uint8_t tmpdata = 0; + if(attr & 0x20) color |= 0x08; + + // Do render +// out_debug_log("ROMADDR=%08X", romaddr); + uint32_t of = addr_of; + for(int column = 0; column < 16; column++) { + if(d_font != NULL) { + if((attr & 0xc0) == 0) { + // ANK + tmpdata = d_font->read_direct_data8(column + romaddr); + } else { + tmpdata = d_font->read_direct_data8(column * 2 + romaddr); } - scrntype_t pix0, pix1, mask0; - int xptr = width & 0x7f8; - for(int ii = 0; ii < (width & 7); ii++) { - pix0 = lbuffer0[ii + xptr]; - pix1 = lbuffer1[ii + xptr]; - mask0 = abuffer0[ii + xptr]; - pix0 = pix0 & mask0; - pix1 = pix1 & ~(mask0); - pix0 = pix0 | pix1; - *pp++ = pix0; + } + if(attr & 0x08) + { + tmpdata = ~tmpdata; + } + uint32_t pix = 0; + uint8_t *p = d_vram->get_vram_address(of + plane_offset); + if(p != NULL) { +__DECL_VECTORIZED_LOOP + for(int nb = 0; nb < 8; nb += 2) { +// pix = 0; + pix = ((tmpdata & 0x80) != 0) ? color : 0; + pix = pix | (((tmpdata & 0x40) != 0) ? (color << 4) : 0); + tmpdata <<= 2; + *p++ = pix; } - } else if(do_mix0) { - my_memcpy(pp, lbuffer0, width * sizeof(scrntype_t)); - } else if(do_mix1) { - my_memcpy(pp, lbuffer1, width * sizeof(scrntype_t)); - } else { - memset(pp, 0x00, width * sizeof(scrntype_t)); } + of = (of + linesize) & 0x3ffff; } - vm->unlock_vm(); +// _leave0: + addr_of = (addr_of + 4) & 0x3ffff; + c += 2; } } - //display_linebuf = (display_linebuf + 1) & 3; - return; } - -void TOWNS_CRTC::transfer_line() +void TOWNS_CRTC::transfer_line(int line) { - int line = vert_line_count; if(line < 0) return; if(line >= TOWNS_CRTC_MAX_LINES) return; if(d_vram == NULL) return; uint8_t ctrl, prio; ctrl = voutreg_ctrl; prio = voutreg_prio; - + //int trans = (display_linebuf - 1) & 3; int trans = display_linebuf & 3; if(linebuffers[trans] == NULL) return; + for(int i = 0; i < 4; i++) { linebuffers[trans][line].mode[i] = 0; linebuffers[trans][line].pixels[i] = 0; linebuffers[trans][line].mag[i] = 0; linebuffers[trans][line].num[i] = -1; } + int page0, page1; + linebuffers[trans][line].r50_planemask = r50_planemask; linebuffers[trans][line].prio = prio; if((prio & 0x01) == 0) { page0 = 0; // Front @@ -1022,155 +1849,289 @@ void TOWNS_CRTC::transfer_line() page0 = 1; page1 = 0; } - if((ctrl & 0x10) == 0) { // One layer mode - bool to_disp = false; - linebuffers[trans][line].num[0] = 0; - if(!(frame_in[0])) return; - if((horiz_end_us[0] <= 0.0) || (horiz_end_us[0] <= horiz_start_us[0])) return; - switch(ctrl & 0x0f) { - case 0x0a: - linebuffers[trans][line].mode[0] = DISPMODE_256; - to_disp = true; - break; - case 0x0f: - linebuffers[trans][line].mode[0] = DISPMODE_32768; - to_disp = true; - break; - } - if(to_disp) { - // ToDo: Sprite mode. - uint32_t offset = vstart_addr[0]; - offset = offset + head_address[0]; - if(hstart_words[0] >= regs[9]) { - offset = offset + hstart_words[0] - regs[9]; - } - offset <<= 3; - offset = offset & 0x7ffff; // OK? - // ToDo: HAJ0, LO0 - uint16_t _begin = regs[9]; // HDS0 - uint16_t _end = regs[10]; // HDE0 - if(_begin < _end) { - int words = _end - _begin; - if(hstart_words[0] >= regs[9]) { - words = words - (hstart_words[0] - regs[9]); - } - uint8_t magx = zoom_factor_horiz[0]; - uint8_t *p = d_vram->get_vram_address(offset); - if((p != NULL) && (words >= magx) && (magx != 0)){ - memcpy(linebuffers[trans][line].pixels_layer[0], p, words / magx); - switch(linebuffers[trans][line].mode[0]) { - case DISPMODE_32768: - linebuffers[trans][line].pixels[0] = words / (magx * 2); - linebuffers[trans][line].mag[0] = magx; - break; - case DISPMODE_256: - linebuffers[trans][line].pixels[0] = words / (magx * 1); - linebuffers[trans][line].mag[0] = magx; - break; - } +// out_debug_log("LINE %d CTRL=%02X \n", line, ctrl); + bool did_transfer[2] = { false, false }; + bool to_disp[2] = { false, false}; + uint32_t address_shift[2] = { 0, 0}; + uint32_t address_mask[2] = {0x0003ffff, 0x0003ffff}; + static const uint32_t address_add[2] = {0x00000000, 0x00040000}; + uint8_t ctrl_b = ctrl; + linebuffers[trans][line].num[0] = page0; + linebuffers[trans][line].num[1] = page1; + linebuffers[trans][line].mode[0] = DISPMODE_16; + linebuffers[trans][line].mode[1] = DISPMODE_16; + uint8_t page_16mode = r50_pagesel; + + for(int l = 0; l < 2; l++) { + if((ctrl & 0x10) == 0) { // One layer mode + linebuffers[trans][line].num[0] = 0; + linebuffers[trans][line].num[1] = 0; + linebuffers[trans][line].crtout[0] = (crtout_top[0]) ? 0xff : 0x00; + linebuffers[trans][line].crtout[1] = 0; + bool disp = frame_in[0]; + if((horiz_end_us[0] <= 0.0) || (horiz_end_us[0] <= horiz_start_us[0])) { + disp = false; + } +// if(vert_offset_tmp[0] > line) { +// disp = false; +// } + if(disp) { + switch(ctrl & 0x0f) { + case 0x0a: + linebuffers[trans][line].mode[0] = DISPMODE_256; + address_shift[0] = 3; // FM-Towns Manual P.145 + to_disp[0] = true; + address_mask[0] = 0x7ffff; + break; + case 0x0f: + linebuffers[trans][line].mode[0] = DISPMODE_32768; + to_disp[0] = true; + address_shift[0] = 3; // FM-Towns Manual P.145 + address_mask[0] = 0x7ffff; + break; + default: + linebuffers[trans][line].mode[0] = DISPMODE_NONE; + to_disp[0] = false; + break; } } - } - if(zoom_count_vert[0] > 0) { - zoom_count_vert[0]--; - } - if(zoom_count_vert[0] == 0) { - zoom_count_vert[0] = zoom_factor_vert[0]; - head_address[0] += frame_offset[0]; - } - } else { // Two layers. - bool to_disp[2] = {false, false}; - uint8_t ctrl_b = ctrl; - linebuffers[trans][line].num[0] = page0; - linebuffers[trans][line].num[1] = page1; - // ToDo: Sprite mode. - for(int l = 0; l < 2; l++) { + if(l == 0) break; + } else { // Two layer mode + linebuffers[trans][line].num[0] = page0; + linebuffers[trans][line].num[1] = page1; + linebuffers[trans][line].crtout[page0] = (crtout_top[page0]) ? 0xff : 0x00; + linebuffers[trans][line].crtout[page1] = (crtout_top[page1]) ? 0xff : 0x00; bool disp = frame_in[l]; if((horiz_end_us[l] <= 0.0) || (horiz_end_us[l] <= horiz_start_us[l])) { disp = false; } +// if(vert_offset_tmp[l] > line) { +// disp = false; +// } +// out_debug_log("LAYER=%d CTRL_B=%02X DISP=%d START=%f END=%f", l, ctrl_b, disp, horiz_start_us[l], horiz_end_us[l]); if(disp) { switch(ctrl_b & 0x03) { case 0x01: linebuffers[trans][line].mode[l] = DISPMODE_16; to_disp[l] = true; + address_shift[l] = 2; // FM-Towns Manual P.145 break; - case 0x03: + case 0x03: linebuffers[trans][line].mode[l] = DISPMODE_32768; to_disp[l] = true; + address_shift[l] = 2; // FM-Towns Manual P.145 + break; + default: + linebuffers[trans][line].mode[l] = DISPMODE_NONE; + to_disp[l] = false; break; } } ctrl_b >>= 2; } - for(int l = 0; l < 2; l++) { - if(to_disp[l]) { - uint32_t offset = vstart_addr[l]; - offset = offset + head_address[l]; - if(hstart_words[l] >= regs[9 + l * 2]) { - offset = offset + (hstart_words[l] - regs[9 + l * 2]); + } + /* + if(linebuffers[trans][line].crtout[0] == 0) { + linebuffers[trans][line].mode[page0] = DISPMODE_NONE; + to_disp[0] = false; + } + if(linebuffers[trans][line].crtout[1] == 0) { + linebuffers[trans][line].mode[page1] = DISPMODE_NONE; + to_disp[1] = false; + }*/ + // Fill by skelton colors; + for(int l = 0; l < 2; l++) { + uint32_t *p = (uint32_t*)(&(linebuffers[trans][line].pixels_layer[l][0])); + uint32_t pix = 0x00000000; + if(!(to_disp[l])) { + if(linebuffers[trans][line].mode[l] == DISPMODE_32768) { + pix = 0x80008000; + } +__DECL_VECTORIZED_LOOP + for(int x = 0; x < (TOWNS_CRTC_MAX_PIXELS >> 1); x++) { + p[x] = pix; // Clear color + } + } + } + + for(int l = 0; l < 2; l++) { + if(to_disp[l]) { + uint16_t _begin = regs[9 + l * 2] & 0x7ff; // HDSx + uint16_t _end = regs[10 + l * 2] & 0x7ff; // HDEx + int ashift = address_shift[l]; + uint32_t shift_mask = (1 << ashift) - 1; + + int bit_shift = 0; + uint16_t haj = hstart_words[l]; + // FAx + int offset = (int)vstart_addr[l]; // ToDo: Larger VRAM + bit_shift = (int)haj - (int)_begin; + if(horiz_us >= (1.0e6 / 16.6e3)) { + // Maybe LOW RESOLUTION, Will fix.20201115 K.O + bit_shift >>= 1; + } + offset = (offset + ((-bit_shift) >> ashift)) & (((ctrl & 0x10) == 0) ? 0x7ffff : 0x3ffff); +#if 0 + int _x = (int)max((unsigned int)_begin, (unsigned int)haj); + int _y = (int)(regs[13 + l * 2] & 0x3ff); // VDSx + switch(clksel) { + case 0: + _x = (_x - 0x129) >> 1; + _y = (_y - 0x2a) >> 1; + break; + case 1: + if((regs[4] & 0x3ff) == 0x31f) { // HST + _x = _x - 0x8a; + } else { + _x = (_x - 0xe7) >> 1; + } + _y = (_y - 0x2a) >> 1; + break; + case 2: + _x = _x - 0x8a; + _y = (_y - 0x46) >> 1; + break; + case 3: + if((regs[4] & 0x3ff) != 0x29d) { // HST + _x = _x - 0x9c; + _y = (_y - 0x40) >> 1; + } else { + _x = _x - 0x8a; + _y = (_y - 0x46) >> 1; + } + break; + default: + _x = 0; + _y = 0; + break; + } + if(_x < 0) _x = 0; + if(_y < 0) _y = 0; +#endif + offset = offset + (int)head_address[l]; + offset <<= ashift; +// bit_shift = _x >> ashift; + if((trans & 1) != 0) offset = offset + (frame_offset[l] <<= ashift); + if(l == 1) { + offset = offset + (fo1_offset_value <<= ashift); + } + if(linebuffers[trans][line].mode[l] == DISPMODE_16) { + offset += ((page_16mode != 0) ? 0x20000 : 0); + } + if(l == 1) { + if((is_sprite) && (linebuffers[trans][line].mode[l] == DISPMODE_32768)) { + offset += sprite_offset; } - offset <<= 2; - offset = offset & 0x3ffff; // OK? - if(l != 0) offset += 0x40000; - // ToDo: HAJ0, LO0 - uint16_t _begin = regs[9 + l * 2]; // HDSx - uint16_t _end = regs[10 + l * 2]; // HDEx - if(_begin < _end) { - int words = _end - _begin; - if(hstart_words[l] >= regs[9 + l * 2]) { - words = words - (hstart_words[l] - regs[9 + l * 2]); + } + offset = offset & address_mask[l]; // OK? + offset += address_add[l]; +// out_debug_log(_T("LINE=%d BEGIN=%d END=%d"), line, _begin, _end); + if(_begin < _end) { + int pixels = _end - _begin; + uint8_t magx = zoom_factor_horiz[l]; + uint8_t *p = d_vram->get_vram_address(offset); + int npixels = pixels; +// if((npixels % magx) != 0) npixels++; + if((p != NULL) && (pixels >= magx) && (magx != 0)){ + if(bit_shift < 0) { +// pixels += (-bit_shift * magx); + bit_shift = 0; + } else if(bit_shift > 0) { + //pixels += (bit_shift * magx); + bit_shift = 0; } - uint8_t magx = zoom_factor_horiz[l]; - uint8_t *p = d_vram->get_vram_address(offset); - if((p != NULL) && (words >= magx) && (magx != 0)){ - memcpy(linebuffers[trans][line].pixels_layer[l], p, words / magx); - switch(linebuffers[trans][line].mode[l]) { - case DISPMODE_32768: - linebuffers[trans][line].pixels[l] = words / (magx * 2); - linebuffers[trans][line].mag[l] = magx; - break; - case DISPMODE_16: - linebuffers[trans][line].pixels[l] = (words * 2) / (magx * 1); - linebuffers[trans][line].mag[l] = magx; - break; + if(pixels >= TOWNS_CRTC_MAX_PIXELS) pixels = TOWNS_CRTC_MAX_PIXELS; + linebuffers[trans][line].bitshift[l] = bit_shift * magx; + linebuffers[trans][line].pixels[l] = pixels; + linebuffers[trans][line].mag[l] = magx; // ToDo: Real magnif + if((pixels % magx) != 0) { + npixels = pixels / magx + 2; + } else { + npixels = pixels / magx; + } +// if(npixels >= TOWNS_CRTC_MAX_PIXELS) npixels = TOWNS_CRTC_MAX_PIXELS; + bool is_256 = false; + uint32_t tr_bytes = 0; + switch(linebuffers[trans][line].mode[l]) { + case DISPMODE_32768: + tr_bytes = npixels << 1; + break; + case DISPMODE_16: + tr_bytes = npixels >> 1; + break; + case DISPMODE_256: + is_256 = true; + tr_bytes = npixels; + break; + } + if(is_256) { + linebuffers[trans][line].pixels[0] = pixels; + linebuffers[trans][line].mag[0] = magx; // ToDo: Real magnif + } + if(tr_bytes > 0) { + if(((offset & address_mask[l]) + tr_bytes) > address_mask[l]) { + // Wrap + int __left = (address_mask[l] + 1 - (offset & address_mask[l])); + my_memcpy(&(linebuffers[trans][line].pixels_layer[(is_256) ? 0 : l][0]) + , p + , __left); + offset = ((page_16mode != 0) ? 0x20000 : 0); + offset += address_add[l]; + uint8_t *p = d_vram->get_vram_address(offset); + my_memcpy(&(linebuffers[trans][line].pixels_layer[(is_256) ? 0 : l][__left]) + , p + , tr_bytes - __left); + } else { + my_memcpy(&(linebuffers[trans][line].pixels_layer[(is_256) ? 0 : l][0]), p, tr_bytes); } } + did_transfer[l] = true; } } - if(frame_in[l]) { - if(zoom_count_vert[l] > 0) { - zoom_count_vert[l]--; - } - if(zoom_count_vert[l] == 0) { - zoom_count_vert[l] = zoom_factor_vert[l]; - head_address[l] += frame_offset[l]; + if(zoom_count_vert[l] > 0) { + zoom_count_vert[l]--; + } + if(zoom_count_vert[l] <= 0) { + zoom_count_vert[l] = zoom_factor_vert[l]; + // ToDo: Interlace + if(to_disp[l]) { + head_address[l] += line_offset[l]; } } } + if((l >= 0) && ((ctrl & 0x10) == 0)) break; // Single layers. } } void TOWNS_CRTC::update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) { + max_lines = new_lines_per_frame; + frames_per_sec = new_frames_per_sec; + cpu_clocks = new_clocks; req_recalc = true; } void TOWNS_CRTC::event_pre_frame() { - if(req_recalc) { - force_recalc_crtc_param(); + interlace_field = !interlace_field; + for(int i = 0; i < 2; i++) { + crtout_top[i] = crtout[i]; + hdisp[i] = false; + zoom_count_vert[i] = zoom_factor_vert[i]; } +// if(req_recalc) { + force_recalc_crtc_param(); +// } int pb = pixels_per_line; int lb = lines_per_frame; if((voutreg_ctrl & 0x10) == 0) { // Single layer lines_per_frame = (int)(regs[14] & 0x07ff) - (int)(regs[13] & 0x07ff); - if(lines_per_frame < 0) lines_per_frame = 0; + if(lines_per_frame <= 1) lines_per_frame = 2; pixels_per_line = (int)(regs[10] & 0x07ff) - (int)(regs[9] & 0x07ff); - if(pixels_per_line < 0) pixels_per_line = 0; + if(pixels_per_line <= 8) pixels_per_line = 8; lines_per_frame >>= 1; } else { int l0 = (int)(regs[14] & 0x07ff) - (int)(regs[13] & 0x07ff); @@ -1187,9 +2148,12 @@ void TOWNS_CRTC::event_pre_frame() } else { pixels_per_line = w1; } - if(lines_per_frame < 0) lines_per_frame = 0; - if(pixels_per_line < 0) pixels_per_line = 0; + if(lines_per_frame <= 1) lines_per_frame = 1; + if(pixels_per_line <= 8) pixels_per_line = 8; + lines_per_frame >>= 1; } + if(pixels_per_line >= TOWNS_CRTC_MAX_PIXELS) pixels_per_line = TOWNS_CRTC_MAX_PIXELS; + if(lines_per_frame >= TOWNS_CRTC_MAX_LINES) lines_per_frame = TOWNS_CRTC_MAX_LINES; if(lb != lines_per_frame) { set_lines_per_frame(lines_per_frame); } @@ -1197,49 +2161,52 @@ void TOWNS_CRTC::event_pre_frame() // ToDo: Resize texture. //set_pixels_per_line(pixels_per_line); } + // Render VRAM + if(d_sprite->read_signal(SIG_TOWNS_SPRITE_TVRAM_ENABLED) != 0) { + d_sprite->get_tvram_snapshot(tvram_snapshot); + render_text(); + } } void TOWNS_CRTC::event_frame() { display_linebuf = (display_linebuf + 1) & 3; // Incremant per vstart -// if(req_recalc) { -// force_recalc_crtc_param(); -// } + hst[display_linebuf] = hst_tmp; + vst[display_linebuf] = vst_tmp; + lines_per_frame = max_lines; + line_count[0] = line_count[1] = 0; vert_line_count = -1; - if((horiz_us != next_horiz_us) || (vert_us != next_vert_us)) { - horiz_us = next_horiz_us; - vert_us = next_vert_us; - } hsync = false; - for(int i = 0; i < 2; i++) { - hdisp[i] = false; - zoom_count_vert[i] = zoom_factor_vert[i]; + //! @note at event_pre_frame() at SPRITE, clear VRAM if enabled. + is_sprite = (d_sprite->read_signal(SIG_TOWNS_SPRITE_ENABLED) != 0) ? true : false; + if(is_sprite) { + sprite_offset = (d_sprite->read_signal(SIG_TOWNS_SPRITE_DISP_PAGE1) != 0) ? 0x20000 : 0x00000; + } else { + sprite_offset = 0x00000; } // ToDo: EET //register_event(this, EVENT_CRTC_VSTART, frame_us, false, &event_id_frame); // EVENT_VSTART MOVED TO event_frame(). - if(d_sprite != NULL) { - d_sprite->write_signal(SIG_TOWNS_SPRITE_CALL_VSTART, 0xffffffff, 0xffffffff); + cancel_event_by_id(event_id_vst1); + cancel_event_by_id(event_id_vst2); + + set_vsync(true, true); + + if(vst1_us > 0.0) { + register_event(this, EVENT_CRTC_VST1, vst1_us, false, &event_id_vst1); // VST1 } - if(vert_sync_pre_us >= 0.0) { - vsync = false; - register_event(this, EVENT_CRTC_VST1, vert_sync_pre_us, false, &event_id_vst1); // VST1 - } else { - vsync = true; + if((vst2_us > 0.0) && (vst2_us > vst1_us)) { + register_event(this, EVENT_CRTC_VST2, vst2_us, false, &event_id_vst2); + } else if((vst1_us <= 0.0) && (vst2_us <= 0.0)) { + set_vsync(false, true); } - register_event(this, EVENT_CRTC_VST2, vst2_us, false, &event_id_vst2); + for(int i = 0; i < 2; i++) { frame_in[i] = false; - if(event_id_vds[i] != -1) { - cancel_event(this, event_id_vds[i]); - } - if(event_id_vde[i] != -1) { - cancel_event(this, event_id_vde[i]); - } + cancel_event_by_id(event_id_vds[i]); + cancel_event_by_id(event_id_vde[i]); if(vert_start_us[i] > 0.0) { register_event(this, EVENT_CRTC_VDS + i, vert_start_us[i], false, &event_id_vds[i]); // VDSx - } else { - frame_in[i] = true; } if(vert_end_us[i] > 0.0) { register_event(this, EVENT_CRTC_VDE + i, vert_end_us[i], false, &event_id_vde[i]); // VDEx @@ -1247,17 +2214,92 @@ void TOWNS_CRTC::event_frame() head_address[i] = 0; } - if(event_id_hstart != -1) { - cancel_event(this, event_id_hstart); - event_id_hstart = -1; - } - if(event_id_hsw != -1) { - cancel_event(this, event_id_hsw); - event_id_hsw = -1; + cancel_event_by_id(event_id_hstart); + cancel_event_by_id(event_id_hsw); + if(horiz_us > 0.0) { + register_event(this, EVENT_CRTC_HSTART, horiz_us, false, &event_id_hstart); // HSTART } - register_event(this, EVENT_CRTC_HSTART, horiz_us, false, &event_id_hstart); // HSTART } +bool TOWNS_CRTC::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + return false; +} + +bool TOWNS_CRTC::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + if(buffer == NULL) return false; + + _TCHAR paramstr[2048] = {0}; + my_stprintf_s(paramstr, sizeof(paramstr) / sizeof(_TCHAR), + _T("\n") + _T("DISPLAY: %s / VCOUNT=%d / FRAMES PER SEC=%6g / FRAME uS=%6g / CLOCK=%6gMHz\n") + _T("LINES PER FRAME=%d / PIXELS PER LINE=%d / MAX LINE=%d\n") + _T("EET uS=%6g /") + _T("VST1 uS=%6g / VST2 uS=%6g\n") + _T("HORIZ uS=%6g / POSI uS=%6g / NEGA uS=%6g\n") + _T("VERT START uS [0]=%6g [1]=%6g / END uS [0]=%6g [1]=%6g\n") + _T("HORIZ START uS [0]=%6g [1]=%6g / END uS [0]=%6g [1]=%6g\n\n") + , (display_enabled) ? _T("ON ") : _T("OFF"), vert_line_count + , frames_per_sec, frame_us, 1.0 / crtc_clock + , lines_per_frame, pixels_per_line, max_lines + , eet_us + , vst1_us, vst2_us + , horiz_us, horiz_width_posi_us, horiz_width_nega_us + , vert_start_us[0], vert_start_us[1], vert_end_us[0], vert_end_us[1] + , horiz_start_us[0], horiz_start_us[1], horiz_end_us[0], horiz_end_us[1] + ); + + _TCHAR regstr[1024] = {0}; + my_stprintf_s(regstr, sizeof(regstr) / sizeof(_TCHAR), + _T("REGS: +0 +1 +2 +3 +4 +5 +6 +7\n") + _T("------------------------------------------------------\n") + ); + + for(int r = 0; r < 32; r += 8) { + _TCHAR tmps[32] = {0}; + my_stprintf_s(tmps, sizeof(tmps) / sizeof(_TCHAR), "+%02d: ", r); + my_tcscat_s(regstr, sizeof(regstr) / sizeof(_TCHAR), tmps); + for(int q = 0; q < 8; q++) { + my_stprintf_s(tmps, sizeof(tmps) / sizeof(_TCHAR), _T("%04X "), regs[r + q]); + my_tcscat_s(regstr, sizeof(regstr) / sizeof(_TCHAR), tmps); + } + my_tcscat_s(regstr, sizeof(regstr) / sizeof(_TCHAR), _T("\n")); + } + _TCHAR regstr2[1024] = {0}; + my_stprintf_s(regstr2, sizeof(regstr2) / sizeof(_TCHAR), + _T("R50: PAGESEL=%d PLANEMASK=%01X DPALETTE CHANGED=%s\n") + _T("CRT: OUT0=%s OUT1=%s ") + _T("OUTREG: CTRL=%02X PRIO=%02X\n") + _T("CRTC CH=%d\n") + , r50_pagesel, r50_planemask, (dpalette_changed) ? _T("YES") : _T("NO ") + , (crtout[0]) ? _T("ON ") : _T("OFF"), (crtout[1]) ? _T("ON ") : _T("OFF") + , voutreg_ctrl, voutreg_prio + , crtc_ch + ); + + my_stprintf_s(buffer, buffer_len, + _T("%s") + _T("ZOOM[0] V=%d H=%d VCOUNT=%d / ZOOM[1] V=%d H=%d VCOUNT=%d\n") + _T("VSYNC=%s / FRAME IN[0]=%s / [1]=%s\n") + _T("HSYNC=%s / HDISP[0]=%s / [1]=%s\n\n") + _T("%s") + _T("%s") + , paramstr +// , line_count[0], line_count[1] + , zoom_factor_vert[0], zoom_factor_horiz[0], zoom_count_vert[0] + , zoom_factor_vert[1], zoom_factor_horiz[1], zoom_count_vert[1] + , (vsync) ? _T("YES") : _T("NO ") + , (frame_in[0]) ? _T("YES") : _T("NO ") + , (frame_in[1]) ? _T("YES") : _T("NO ") + , (hsync) ? _T("YES") : _T("NO ") + , (hdisp[0]) ? _T("YES") : _T("NO ") + , (hdisp[1]) ? _T("YES") : _T("NO ") + , regstr2 + , regstr + ); + return true; +} void TOWNS_CRTC::event_callback(int event_id, int err) { /* @@ -1274,10 +2316,10 @@ void TOWNS_CRTC::event_callback(int event_id, int err) int eid2 = (event_id / 2) * 2; // EVENT_VSTART MOVED TO event_frame(). if(event_id == EVENT_CRTC_VST1) { // VSYNC - vsync = true; + set_vsync(false, false); event_id_vst1 = -1; } else if (event_id == EVENT_CRTC_VST2) { - vsync = false; + set_vsync(false, false); event_id_vst2 = -1; } else if(eid2 == EVENT_CRTC_VDS) { // Display start int layer = event_id & 1; @@ -1289,37 +2331,33 @@ void TOWNS_CRTC::event_callback(int event_id, int err) int layer = event_id & 1; frame_in[layer] = false; event_id_vde[layer] = -1; + // DO ofset line? } else if(event_id == EVENT_CRTC_HSTART) { // Do render event_id_hstart = -1; - transfer_line(); // Tranfer before line. - vert_line_count++; if(d_sprite != NULL) { - d_sprite->write_signal(SIG_TOWNS_SPRITE_CALL_HSYNC, vert_line_count, 0xffffffff); + d_sprite->write_signal(SIG_TOWNS_SPRITE_HOOK_VLINE, vert_line_count, 0xffffffff); + } + if(frame_in[0] || frame_in[1]) { + vert_line_count++; + if(vert_line_count < lines_per_frame) { + transfer_line(vert_line_count); // Tranfer before line. + } } hdisp[0] = false; hdisp[1] = false; - if(event_id_hsw != -1) { - cancel_event(this, event_id_hsw); - event_id_hsw = -1; - } + cancel_event_by_id(event_id_hsw); +// hsync = false; + hsync = true; if(!vsync) { - hsync = true; register_event(this, EVENT_CRTC_HSW, horiz_width_posi_us, false, &event_id_hsw); // VDEx } else { - hsync = true; register_event(this, EVENT_CRTC_HSW, horiz_width_nega_us, false, &event_id_hsw); // VDEx } for(int i = 0; i < 2; i++) { - if(event_id_hds[i] != -1) { - cancel_event(this, event_id_hds[i]); - } - event_id_hds[i] = -1; - if(event_id_hde[i] != -1) { - cancel_event(this, event_id_hde[i]); - } - event_id_hde[i] = -1; + cancel_event_by_id(event_id_hds[i]); + cancel_event_by_id(event_id_hde[i]); if(horiz_start_us[i] > 0.0) { register_event(this, EVENT_CRTC_HDS + i, horiz_start_us[i], false, &event_id_hds[i]); // HDS0 @@ -1337,13 +2375,14 @@ void TOWNS_CRTC::event_callback(int event_id, int err) } else if(eid2 == EVENT_CRTC_HDS) { int layer = event_id & 1; hdisp[layer] = true; - if((horiz_end_us[i] <= 0.0) || (horiz_end_us[i] <= horiz_start_us[i])) { + if((horiz_end_us[layer] <= 0.0) || (horiz_end_us[layer] <= horiz_start_us[layer])) { hdisp[layer] = false; } event_id_hds[layer] = -1; } else if(eid2 == EVENT_CRTC_HDE) { int layer = event_id & 1; - hdisp[layer] = false; + hdisp[layer] = false; +// if(!(hdisp[0]) && !(hdisp[1])) hsync = false; event_id_hde[layer] = -1; } @@ -1373,7 +2412,7 @@ uint32_t TOWNS_CRTC::read_signal(int ch) case SIG_TOWNS_CRTC_HDISP1: return (hdisp[1]) ? 0xffffffff : 0; break; - case SIG_TOWNS_CRTC_MMIO_CF882H: + case SIG_TOWNS_CRTC_MMIO_CFF82H: { uint8_t d; d = ((r50_planemask & 0x08) != 0) ? 0x60 : 0x40; @@ -1382,23 +2421,28 @@ uint32_t TOWNS_CRTC::read_signal(int ch) return d; } break; + case SIG_TOWNS_CRTC_COMPATIBLE_MMIO: + return (is_compatible) ? 0xffffffff : 0x00000000; + break; } return 0; } void TOWNS_CRTC::write_signal(int ch, uint32_t data, uint32_t mask) { - if(ch == SIG_TOWNS_CRTC_MMIO_CF882H) { + if(ch == SIG_TOWNS_CRTC_MMIO_CFF82H) { +// out_debug_log(_T("CF882H=%02X"), data & 0xff); r50_planemask = ((data & 0x20) >> 2) | (data & 0x07); r50_pagesel = ((data & 0x10) != 0) ? 1 : 0; - } else if(ch == SIG_TOWNS_CRTC_SPRITE_DISP) { - sprite_disp_page = data & 1; // OK? - } else if(ch == SIG_TOWNS_CRTC_SPRITE_USING) { - sprite_enabled = ((data & mask) != 0) ? true : false; // OK? + } else if(ch == SIG_TOWNS_CRTC_COMPATIBLE_MMIO) { + is_compatible = ((data & mask) != 0) ? true : false; + } else if(ch == SIG_TOWNS_CRTC_ADD_VAL_FO1) { + fo1_offset_value = data & 0xffff; } } -#define STATE_VERSION 1 + +#define STATE_VERSION 4 bool TOWNS_CRTC::process_state(FILEIO* state_fio, bool loading) { @@ -1408,9 +2452,15 @@ bool TOWNS_CRTC::process_state(FILEIO* state_fio, bool loading) if(!state_fio->StateCheckInt32(this_device_id)) { return false; } + state_fio->StateValue(machine_id); + state_fio->StateValue(cpu_id); + state_fio->StateValue(is_compatible); + state_fio->StateArray(regs, sizeof(regs), 1); state_fio->StateArray(regs_written, sizeof(regs_written), 1); state_fio->StateValue(crtc_ch); + state_fio->StateValue(interlace_field); + state_fio->StateArray(timing_changed, sizeof(timing_changed), 1); state_fio->StateArray(address_changed, sizeof(address_changed), 1); state_fio->StateArray(mode_changed, sizeof(mode_changed), 1); @@ -1420,24 +2470,27 @@ bool TOWNS_CRTC::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(crtc_clock); state_fio->StateValue(max_lines); state_fio->StateValue(frames_per_sec); + state_fio->StateValue(cpu_clocks); state_fio->StateArray(vstart_addr, sizeof(vstart_addr), 1); state_fio->StateArray(hstart_words, sizeof(hstart_words), 1); state_fio->StateArray(hend_words, sizeof(hend_words), 1); state_fio->StateArray(vstart_lines, sizeof(vstart_lines), 1); state_fio->StateArray(vend_lines, sizeof(vend_lines), 1); + state_fio->StateArray(line_offset, sizeof(line_offset), 1); state_fio->StateArray(frame_offset, sizeof(frame_offset), 1); state_fio->StateArray(head_address, sizeof(head_address), 1); + state_fio->StateArray(impose_mode, sizeof(impose_mode), 1); + state_fio->StateArray(carry_enable, sizeof(carry_enable), 1); state_fio->StateArray(zoom_factor_vert, sizeof(zoom_factor_vert), 1); state_fio->StateArray(zoom_factor_horiz, sizeof(zoom_factor_horiz), 1); state_fio->StateArray(zoom_count_vert, sizeof(zoom_count_vert), 1); state_fio->StateArray(line_count, sizeof(line_count), 1); + state_fio->StateValue(fo1_offset_value); state_fio->StateValue(vert_line_count); - state_fio->StateValue(vdisp); - state_fio->StateValue(vblank); state_fio->StateValue(vsync); state_fio->StateValue(hsync); state_fio->StateArray(hdisp, sizeof(hdisp), 1); @@ -1454,20 +2507,39 @@ bool TOWNS_CRTC::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(voutreg_ctrl); state_fio->StateValue(voutreg_prio); state_fio->StateArray(video_out_regs, sizeof(video_out_regs), 1); + state_fio->StateValue(crtout_reg); state_fio->StateArray(crtout, sizeof(crtout), 1); + state_fio->StateArray(crtout_top, sizeof(crtout_top), 1); - state_fio->StateValue(sprite_disp_page); - state_fio->StateValue(sprite_enabled); state_fio->StateValue(pixels_per_line); state_fio->StateValue(lines_per_frame); + state_fio->StateValue(apalette_code); + state_fio->StateValue(apalette_b); + state_fio->StateValue(apalette_r); + state_fio->StateValue(apalette_g); + for(int l = 0; l < 2; l++) { + for(int i = 0; i < 16; i++) { + state_fio->StateValue(apalette_16_rgb[l][i][TOWNS_CRTC_PALETTE_R]); + state_fio->StateValue(apalette_16_rgb[l][i][TOWNS_CRTC_PALETTE_G]); + state_fio->StateValue(apalette_16_rgb[l][i][TOWNS_CRTC_PALETTE_B]); + } + } + for(int i = 0; i < 256; i++) { + state_fio->StateValue(apalette_256_rgb[i][TOWNS_CRTC_PALETTE_R]); + state_fio->StateValue(apalette_256_rgb[i][TOWNS_CRTC_PALETTE_G]); + state_fio->StateValue(apalette_256_rgb[i][TOWNS_CRTC_PALETTE_B]); + } + + state_fio->StateValue(is_sprite); + state_fio->StateValue(sprite_offset); + state_fio->StateValue(event_id_hsync); state_fio->StateValue(event_id_hsw); state_fio->StateValue(event_id_vsync); state_fio->StateValue(event_id_vst1); state_fio->StateValue(event_id_vst2); - state_fio->StateValue(event_id_vblank); state_fio->StateValue(event_id_vstart); state_fio->StateValue(event_id_hstart); @@ -1479,13 +2551,24 @@ bool TOWNS_CRTC::process_state(FILEIO* state_fio, bool loading) //state_fio->StateValue(display_linebuf); if(loading) { + for(int i = 0; i < 16; i++) { + calc_apalette16(0, i); + calc_apalette16(1, i); + } + for(int i = 0; i < 256; i++) { + calc_apalette256(i); + } + vst_tmp = 400; + hst_tmp = 640; for(int i = 0; i < 4; i++) { if(linebuffers[i] == NULL) { - linebuffers[i] = malloc(sizeof(linebuffer_t ) * TOWNS_CRTC_MAX_LINES); + linebuffers[i] = (linebuffer_t*)malloc(sizeof(linebuffer_t ) * TOWNS_CRTC_MAX_LINES); } for(int l = 0; l < TOWNS_CRTC_MAX_LINES; l++) { memset(&(linebuffers[i][l]), 0x00, sizeof(linebuffer_t)); } + vst[i] = vst_tmp; + hst[i] = hst_tmp; } display_linebuf = 0; req_recalc = false; diff --git a/source/src/vm/fmtowns/towns_crtc.h b/source/src/vm/fmtowns/towns_crtc.h index cf2ad9080..80178c107 100644 --- a/source/src/vm/fmtowns/towns_crtc.h +++ b/source/src/vm/fmtowns/towns_crtc.h @@ -15,6 +15,7 @@ #include "../emu.h" #include "device.h" +#include "towns_common.h" /* * I/O Address : * 0440H : Register address (8bit W/O : bit7 to 5 must be '0'). @@ -86,22 +87,28 @@ * #00 : Control registers. * #01 : Priority registers. */ -#define TOWNS_CRTC_MAX_LINES 1024 -#define TOWNS_CRTC_MAX_PIXELS 1024 -#define SIG_TOWNS_CRTC_HSYNC 1 -#define SIG_TOWNS_CRTC_VSYNC 2 -#define SIG_TOWNS_CRTC_FIELD 3 -#define SIG_TOWNS_CRTC_VDISP0 4 -#define SIG_TOWNS_CRTC_VDISP1 5 -#define SIG_TOWNS_CRTC_HDISP0 6 -#define SIG_TOWNS_CRTC_HDISP1 7 -#define SIG_TOWNS_CRTC_MMIO_CF882H 8 -#define SIG_TOWNS_CRTC_SPRITE_BUFFER 9 -#define SIG_TOWNS_CRTC_SPRITE_DISP 10 +#define SIG_TOWNS_CRTC_HSYNC 1 +#define SIG_TOWNS_CRTC_VSYNC 2 +#define SIG_TOWNS_CRTC_FIELD 3 +#define SIG_TOWNS_CRTC_VDISP0 4 +#define SIG_TOWNS_CRTC_VDISP1 5 +#define SIG_TOWNS_CRTC_HDISP0 6 +#define SIG_TOWNS_CRTC_HDISP1 7 +#define SIG_TOWNS_CRTC_MMIO_CFF82H 8 +#define SIG_TOWNS_CRTC_SPRITE_BUFFER 9 +#define SIG_TOWNS_CRTC_COMPATIBLE_MMIO 10 +#define SIG_TOWNS_CRTC_ADD_VAL_FO1 11 +class DEBUGGER; namespace FMTOWNS { + enum { + TOWNS_CRTC_PALETTE_R = 0, + TOWNS_CRTC_PALETTE_G, + TOWNS_CRTC_PALETTE_B, + TOWNS_CRTC_PALETTE_I + }; enum { TOWNS_CRTC_REG_HSW1 = 0, TOWNS_CRTC_REG_HSW2 = 1, @@ -147,24 +154,41 @@ namespace FMTOWNS { } namespace FMTOWNS { - + +// May align to be faster. +#pragma pack(push, 4) typedef struct { - int32_t mode[2]; - int32_t pixels[2]; - int32_t mag[2]; - int32_t num[2]; + int32_t mode[4]; + int32_t pixels[4]; + int32_t mag[4]; + int32_t num[4]; uint32_t prio; - uint32_t pad[7]; - uint8_t pixels_layer[2][TOWNS_CRTC_MAX_PIXELS]; // RAW VALUE +#pragma pack(push, 1) + uint8_t r50_planemask; // MMIO 000CF882h : BIT 5(C0) and BIT2 to 0 + uint8_t crtout[2]; + uint8_t r50_pad; +#pragma pack(pop) + int32_t bitshift[2]; + uint32_t pad; + // Align of 4 * (4 + 1 + 3) = 4 * 8 [bytes] = 256 [bits] + uint8_t pixels_layer[2][TOWNS_CRTC_MAX_PIXELS * sizeof(uint16_t)]; // RAW VALUE + // pixels_lauyer[][] : 1024 * 2 * 8 = 1024 * 16 [bytes] } linebuffer_t; +#pragma pack(pop) class TOWNS_VRAM; class TOWNS_SPRITE; +class FONT_ROMS; class TOWNS_CRTC : public DEVICE { protected: TOWNS_VRAM* d_vram; TOWNS_SPRITE* d_sprite; + FONT_ROMS* d_font; + + uint16_t machine_id; + uint8_t cpu_id; + bool is_compatible; // output signals outputs_t outputs_int_vsync; // Connect to int 11. uint16_t regs[32]; // I/O 0442H, 0443H @@ -173,39 +197,64 @@ class TOWNS_CRTC : public DEVICE bool timing_changed[2]; bool address_changed[2]; bool mode_changed[2]; + uint32_t fo1_offset_value; - uint8_t display_mode[2]; + uint8_t display_mode[2]; + bool line_changed[2][TOWNS_CRTC_MAX_LINES]; bool display_enabled; - double crtc_clock; // + double crtc_clock; // + int cpu_clocks; + // They are not saved.Must be calculate when loading. - double horiz_us, next_horiz_us; // (HST + 1) * clock + double horiz_us; // (HST + 1) * clock double horiz_width_posi_us, horiz_width_nega_us; // HSW1, HSW2 - double vert_us, next_vert_us; // (VST +1) * horiz_us / 2.0 - double vstart_us; - double vert_sync_pre_us; // VST1 * horiz_us / 2.0 + double vert_us; // (VST +1) * horiz_us / 2.0 double vert_sync_end_us; // VST2 * horiz_us / 2.0 double eet_us; double frame_us; + double vst1_us; // VST1 * horiz_us / 2.0 + double vst2_us; + int hst[4], vst[4]; + int vst_tmp, hst_tmp; + + double vert_start_us[2]; + double vert_end_us[2]; + double horiz_start_us[2]; + double horiz_end_us[2]; bool req_recalc; // End double frames_per_sec; - uint32_t vstart_addr[2]; // VSTART ADDRESS - uint32_t hstart_words[2]; // HSTART ((HDS[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0. - uint32_t hend_words[2]; // HEND ((HDE[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0. + uint32_t vstart_addr[4]; // VSTART ADDRESS + uint32_t hstart_words[4]; // HSTART ((HDS[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0. + uint32_t hend_words[4]; // HEND ((HDE[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0. uint32_t vstart_lines[2]; // VSTART ((VDS[01] * clock) : Horizonal offset words (Related by VH[01]). - uint32_t vend_lines[2]; // VEND ((VDE[01] * clock) : Horizonal offset words (Related by VH[01]). - uint32_t frame_offset[2]; // FO. + uint32_t vend_lines[4]; // VEND ((VDE[01] * clock) : Horizonal offset words (Related by VH[01]). + uint32_t frame_offset[4]; // FO. + uint32_t line_offset[4]; // FO. uint32_t head_address[2]; + int horiz_offset_tmp[2]; + int vert_offset_tmp[2]; + bool impose_mode[2]; // OK? + bool carry_enable[2]; //OK? + + bool is_sprite; + uint32_t sprite_offset; uint8_t zoom_factor_vert[2]; // Related display resolutions of two layers and zoom factors. uint8_t zoom_factor_horiz[2]; // Related display resolutions of two layers and zoom factors. uint8_t zoom_count_vert[2]; - uint32_t line_count[2]; // Separate per layer. + + uint8_t scsel; + uint8_t clksel; + + int pixels_per_line; + int lines_per_frame; + int max_lines; int vert_line_count; // Not separate per layer.Total count. // Note: To display to real screen, use blending of OpenGL/DirectX @@ -216,12 +265,21 @@ class TOWNS_CRTC : public DEVICE // Not Saved?. // End. + bool vsync, hsync, hdisp[2], frame_in[2]; + bool interlace_field; + - bool vdisp, vblank, vsync, hsync, hdisp[2], frame_in[2]; + // Around Analog palette. + uint8_t apalette_code; // I/O FD90H (RW). 16 or 256 colors. + uint8_t apalette_b; // I/O FD92H (RW). + uint8_t apalette_r; // I/O FD94H (RW). + uint8_t apalette_g; // I/O FD96H (RW). + uint8_t apalette_16_rgb[2][16][4]; // R * 256 + G * 16 + B + scrntype_t apalette_16_pixel[2][16]; // Not saved. Must be calculated. + uint8_t apalette_256_rgb[256][4]; // R * 65536 + G * 256 + B + scrntype_t apalette_256_pixel[256]; // Not saved. Must be calculated. - // around sprite - uint8_t sprite_disp_page; - bool sprite_enabled; + uint8_t tvram_snapshot[0x4000]; // FM-R50 emulation uint8_t r50_planemask; // MMIO 000CF882h : BIT 5(C0) and BIT2 to 0 @@ -241,6 +299,8 @@ class TOWNS_CRTC : public DEVICE uint8_t voutreg_prio; // I/O 044Ah : voutreg_num = 1. uint8_t video_out_regs[2]; bool crtout[2]; // I/O FDA0H WRITE + bool crtout_top[2]; // I/O FDA0H WRITE(AT once frame) + uint8_t crtout_reg; // End. @@ -254,7 +314,6 @@ class TOWNS_CRTC : public DEVICE int event_id_vstart; int event_id_vst1; int event_id_vst2; - int event_id_vblank; int event_id_hstart; int event_id_vds[2]; int event_id_vde[2]; @@ -263,22 +322,49 @@ class TOWNS_CRTC : public DEVICE int display_linebuf; linebuffer_t *linebuffers[4]; - - void set_display(bool val); - void set_vblank(bool val); - void set_vsync(bool val); - void set_hsync(bool val); - void transfer_line(int line); -protected: - bool render_a_line(int layer, int linenum, int xoffset, uint8_t *vramptr, uint32_t words); - void render_line_16(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words); - void render_line_256(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words); - void render_line_32768(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words); - void render_clear(int layer, scrntype_t *framebuffer); + // Render buffer + // ToDo: faster alpha blending. + __DECL_ALIGNED(16) scrntype_t lbuffer0[TOWNS_CRTC_MAX_PIXELS + 16]; + __DECL_ALIGNED(16) scrntype_t lbuffer1[TOWNS_CRTC_MAX_PIXELS + 16]; + __DECL_ALIGNED(16) scrntype_t abuffer0[TOWNS_CRTC_MAX_PIXELS + 16]; + __DECL_ALIGNED(16) scrntype_t abuffer1[TOWNS_CRTC_MAX_PIXELS + 16]; + + void __FASTCALL set_vsync(bool val, bool force); + void force_recalc_crtc_param(void); + void restart_display(); + void stop_display(); + void notify_mode_changed(int layer, uint8_t mode); + + void cancel_event_by_id(int& event_num); + + void set_crtc_clock(uint16_t val); + uint16_t read_reg30(); + uint32_t __FASTCALL get_font_address(uint32_t c, uint8_t &attr); + + virtual void __FASTCALL calc_apalette16(int layer, int index); + virtual void __FASTCALL calc_apalette256(int index); + virtual void __FASTCALL calc_apalette(int index); + virtual void __FASTCALL set_apalette_r(uint8_t val); + virtual void __FASTCALL set_apalette_g(uint8_t val); + virtual void __FASTCALL set_apalette_b(uint8_t val); + virtual void __FASTCALL set_apalette_num(uint8_t val); + virtual uint8_t __FASTCALL get_apalette_b(); + virtual uint8_t __FASTCALL get_apalette_r(); + virtual uint8_t __FASTCALL get_apalette_g(); + + bool __FASTCALL render_16(scrntype_t* dst, scrntype_t *mask, scrntype_t* pal, int y, int layer, bool do_alpha); + bool __FASTCALL render_256(scrntype_t* dst, int y); + bool __FASTCALL render_32768(scrntype_t* dst, scrntype_t *mask, int y, int layer, bool do_alpha); + void __FASTCALL transfer_line(int line); + inline void __FASTCALL transfer_pixels(scrntype_t* dst, scrntype_t* src, int w); + + virtual void __FASTCALL mix_screen(int y, int width, bool do_mix0, bool do_mix1); + virtual void render_text(); + public: - TOWNS_CRTC(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu) + TOWNS_CRTC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_int_vsync); for(int i = 0; i < 4; i++) { @@ -286,36 +372,44 @@ class TOWNS_CRTC : public DEVICE } d_sprite = NULL; d_vram = NULL; + d_font = NULL; + is_sprite = false; set_device_name(_T("FM-Towns CRTC")); } ~TOWNS_CRTC() {} void initialize(); + void release(); void reset(); + void draw_screen(); + void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); + void event_pre_frame(); + void event_frame(); - void write_signal(int id, uint32_t data, uint32_t mask); - uint32_t read_signal(int ch); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_signal(int ch); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); - void write_io8(uint32_t addr, uint32_t data); - uint32_t read_io8(uint32_t addr); - - void write_io16(uint32_t addr, uint32_t data); - uint32_t read_io16(uint32_t addr); - - uint32_t read_data8(uint32_t addr); - uint32_t read_data16(uint32_t addr); - uint32_t read_data32(uint32_t addr); - - void write_data8(uint32_t addr, uint32_t data); - void write_data16(uint32_t addr, uint32_t data); - void write_data32(uint32_t addr, uint32_t data); - void event_callback(int event_id, int err); - //void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); - void save_state(FILEIO* state_fio); - bool load_state(FILEIO* state_fio); + void __FASTCALL write_io16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io16(uint32_t addr); + void __FASTCALL event_callback(int event_id, int err); + bool process_state(FILEIO* state_fio, bool loading); + + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + bool write_debug_reg(const _TCHAR *reg, uint32_t data); + + bool is_debugger_available() + { + return true; + } + uint64_t get_debug_data_addr_space() + { + return 0x1; + } // unique function - linebuffer_t* get_line_buffer(int page, int line) + linebuffer_t* __FASTCALL get_line_buffer(int page, int line) { page = page & 1; if(line < 0) return NULL; @@ -332,6 +426,18 @@ class TOWNS_CRTC : public DEVICE { d_vram = (TOWNS_VRAM*)dev; } + void set_context_font(FONT_ROMS* dev) + { + d_font = dev; + } + void set_machine_id(uint16_t val) + { + machine_id = val & 0xfff8; + } + void set_cpu_id(uint16_t val) + { + cpu_id = val & 0x07; + } void set_context_vsync(DEVICE* device, int id, uint32_t mask) { diff --git a/source/src/vm/fmtowns/towns_dictionary.cpp b/source/src/vm/fmtowns/towns_dictionary.cpp index a6bbf36e7..775cf78aa 100644 --- a/source/src/vm/fmtowns/towns_dictionary.cpp +++ b/source/src/vm/fmtowns/towns_dictionary.cpp @@ -4,11 +4,20 @@ Author : Kyuma.Ohta Date : 2019.01.09- - [ dictionary rom/ram & cmos & RAM area 0x000d0000 - 0x000effff] + [ dictionary rom/ram & cmos & RAM area 0x000d0000 - 0x000dffff] + * MEMORY : + * 0x000d0000 - 0x000d7fff : DICTIONARY ROM (BANKED) + * 0x000d8000 - 0x000d9fff : DICTIONARY RAM / GAIJI RAM + * 0x000da000 - 0x000dffff : RESERVED + * 0xc2080000 - 0xc20fffff : DICTIONARY ROM (NOT BANKED) + * 0xc2140000 - 0xc2141fff : DICTIONARY RAM + * I/O : + * 0x0484 : DICTIONARY BANK (for 0xd0000 - 0xd7ffff) + * 0x3000 - 0x3ffe (even address) : DICTIONARY RAM */ +#include "./towns_common.h" #include "./towns_dictionary.h" -#include "./towns_sysrom.h" #include "../../fileio.h" namespace FMTOWNS { @@ -16,22 +25,22 @@ void DICTIONARY::initialize() { memset(dict_rom, 0xff, sizeof(dict_rom)); memset(dict_ram, 0x00, sizeof(dict_ram)); - memset(ram_0d0, 0x00, sizeof(ram_0d0)); FILEIO* fio = new FILEIO(); if(fio->Fopen(create_local_path(_T("FMT_DIC.ROM")), FILEIO_READ_BINARY)) { // DICTIONARIES fio->Fread(dict_rom, sizeof(dict_rom), 1); fio->Fclose(); } - + + cmos_dirty = true; if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_READ_BINARY)) { - fio->Fread(dict_ram, sizeof(dict_ram), 1); + if(fio->Fread(dict_ram, sizeof(dict_ram), 1) == 1) { + cmos_dirty = false; + } fio->Fclose(); - //cmos_dirty = true; - } else { - cmos_dirty = true; } delete fio; + } void DICTIONARY::release() @@ -49,121 +58,118 @@ void DICTIONARY::release() void DICTIONARY::reset() { dict_bank = 0; - bankd0_dict = false; - + // Write CMOD every resetting. 20200511 K.O + if(cmos_dirty) { + FILEIO* fio = new FILEIO(); + if(fio->Fopen(create_local_path(_T("FMT_CMOS.BIN")), FILEIO_WRITE_BINARY)) { + fio->Fwrite(dict_ram, sizeof(dict_ram), 1); + fio->Fclose(); + } + delete fio; + cmos_dirty = false; + } } -uint32_t DICTIONARY::read_data8(uint32_t addr) + +uint32_t DICTIONARY::read_memory_mapped_io8(uint32_t addr) { uint8_t n_data = 0xff; - if((addr < 0x000f0000) && (addr >= 0x000d0000)) { - if(bankd0_dict) { - if(addr < 0x000d8000) { - n_data = dict_rom[(addr & 0x7fff) + (((uint32_t)(dict_bank & 0x0f)) << 15)]; - } else if(addr < 0x000da000) { - n_data = dict_ram[addr & 0x1fff]; - }/* else { // ToDo: Check correctness - n_data = 0xff; - }*/ + // 0xd0000 - 0xdffff : primary is VRAM, secondary is DICTIONARY. + if((addr < 0x000e0000) && (addr >= 0x000d0000)) { + if(addr < 0xd8000) { + return dict_rom[(((uint32_t)dict_bank) << 15) | (addr & 0x7fff)]; + } else if(addr < 0xda000) { + return dict_ram[addr & 0x1fff]; } else { - n_data = ram_0d0[addr & 0x1ffff]; - } - } else if((addr >= 0xc20800000) && (addr < 0xc2100000)) { + return 0x00; + } + } else if((addr >= 0xc2080000) && (addr < 0xc2100000)) { n_data = dict_rom[addr & 0x7ffff]; - } else if((addr >= 0xc21400000) && (addr < 0xc2142000)) { + } else if((addr >= 0xc2140000) && (addr < 0xc2142000)) { n_data = dict_ram[addr & 0x1fff]; } return n_data; } -void DICTIONARY::write_data8(uint32_t addr, uint32_t data) +void DICTIONARY::write_memory_mapped_io8(uint32_t addr, uint32_t data) { - if((addr < 0x000f0000) && (addr >= 0x000d0000)) { - if(bankd0_dict) { - if((addr >= 0x000d8000) && (addr < 0x000da000)) { - cmos_dirty = true; - dict_ram[addr & 0x1fff] = data; // ToDo: Check correctness - } /* else { // ToDo: Check correctness - - }*/ - } else { - ram_0d0[addr & 0x1ffff] = (uint8_t)data; + if((addr < 0x000e0000) && (addr >= 0x000d0000)) { + if(addr < 0xd8000) { + return; + } else if(addr < 0xda000) { + cmos_dirty = true; + dict_ram[addr & 0x1fff] = data; + return; } - } else if((addr >= 0xc21400000) && (addr < 0xc2142000)) { - dict_ram[addr & 0x1fff] = (uint8_t)data; + // ToDo: address >= 0xda000 + return; + } else if((addr >= 0xc2080000) && (addr < 0xc2100000)) { + return; + } else if((addr >= 0xc2140000) && (addr < 0xc2142000)) { + cmos_dirty = true; + dict_ram[addr & 0x1fff] = data; + return; } } -uint32_t DICTIONARY::read_data16(uint32_t addr) +uint32_t DICTIONARY::read_memory_mapped_io16(uint32_t addr) { pair16_t n; addr = addr & 0xfffffffe; - n.b.l = (uint8_t)read_data8(addr + 0); - n.b.h = (uint8_t)read_data8(addr + 1); - return (uint32_t)(n.u16); + n.b.l = (uint8_t)read_memory_mapped_io8(addr + 0); + n.b.h = (uint8_t)read_memory_mapped_io8(addr + 1); + return (uint32_t)(n.w); } -uint32_t DICTIONARY::read_data32(uint32_t addr) +uint32_t DICTIONARY::read_memory_mapped_io32(uint32_t addr) { pair32_t n; addr = addr & 0xfffffffc; - n.b.l = (uint8_t)read_data8(addr + 0); - n.b.h = (uint8_t)read_data8(addr + 1); - n.b.h2 = (uint8_t)read_data8(addr + 2); - n.b.h3 = (uint8_t)read_data8(addr + 3); + n.b.l = (uint8_t)read_memory_mapped_io8(addr + 0); + n.b.h = (uint8_t)read_memory_mapped_io8(addr + 1); + n.b.h2 = (uint8_t)read_memory_mapped_io8(addr + 2); + n.b.h3 = (uint8_t)read_memory_mapped_io8(addr + 3); return n.d; } -void DICTIONARY::write_data16(uint32_t addr, uint32_t data) +void DICTIONARY::write_memory_mapped_io16(uint32_t addr, uint32_t data) { pair16_t n; addr = addr & 0xfffffffe; - n.u16 = (uint16_t)data; - write_data8(addr + 0, n.b.l); - write_data8(addr + 1, n.b.h); + n.w = (uint16_t)data; + write_memory_mapped_io8(addr + 0, n.b.l); + write_memory_mapped_io8(addr + 1, n.b.h); + return; } -void DICTIONARY::write_data32(uint32_t addr, uint32_t data) +void DICTIONARY::write_memory_mapped_io32(uint32_t addr, uint32_t data) { pair32_t n; addr = addr & 0xfffffffc; n.d = data; - write_data8(addr + 0, n.b.l); - write_data8(addr + 1, n.b.h); - write_data8(addr + 2, n.b.h2); - write_data8(addr + 3, n.b.h3); + write_memory_mapped_io8(addr + 0, n.b.l); + write_memory_mapped_io8(addr + 1, n.b.h); + write_memory_mapped_io8(addr + 2, n.b.h2); + write_memory_mapped_io8(addr + 3, n.b.h3); } void DICTIONARY::write_io8(uint32_t addr, uint32_t data) { - if(addr == 0x0480) { - bankd0_dict = ((data & 0x01) != 0); - d_sysrom->write_signal(SIG_FMTOWNS_SYSROMSEL, data, 0x02); - } else if(addr == 0x0484) { + if(addr == 0x0484) { dict_bank = data & 0x0f; } else if((addr >= 0x3000) && (addr < 0x4000)) { - if((addr & 0x0001) == 0) { // OK? - uint32_t naddr = (addr >> 1) & 0x7ff; - cmos_dirty = true; - dict_ram[naddr] = (uint8_t)data; - } + cmos_dirty = true; + dict_ram[((addr - 0x3000) >> 1) & 0x7ff] = (uint8_t)data; } } uint32_t DICTIONARY::read_io8(uint32_t addr) { uint32_t data; - if(addr == 0x0480) { - data = ((bankd0_dict) ? 0x01 : 0x00) | ((d_sysrom->read_signal(SIG_FMTOWNS_SYSROMSEL) == 0) ? 0x02 : 0x00); - } else if(addr == 0x0484) { + if(addr == 0x0484) { data = dict_bank & 0x0f; } else if((addr >= 0x3000) && (addr < 0x4000)) { - if((addr & 0x0001) == 0) { // OK? - uint32_t naddr = (addr >> 1) & 0x7ff; - data = dict_ram[naddr]; - } else { - data = 0xff; - } + data = dict_ram[((addr - 0x3000) >> 1) & 0x07ff]; } else { data = 0xff; } @@ -173,10 +179,7 @@ uint32_t DICTIONARY::read_io8(uint32_t addr) void DICTIONARY::write_signal(int ch, uint32_t data, uint32_t mask) { switch(ch) { - case SIG_FMTOWNS_DICTSEL: - bankd0_dict = ((data & mask) != 0); - break; - case SIG_FMTOWNS_DICTBANK: + case SIG_FMTOWNS_DICT_BANK: dict_bank = (uint8_t)(data & 0x0f); break; } @@ -185,15 +188,44 @@ void DICTIONARY::write_signal(int ch, uint32_t data, uint32_t mask) uint32_t DICTIONARY::read_signal(int ch) { switch(ch) { - case SIG_FMTOWNS_DICTSEL: - return ((bankd0_dict) ? 0xffffffff : 0x00000000); - break; - case SIG_FMTOWNS_DICTBANK: + case SIG_FMTOWNS_DICT_BANK: return (uint32_t)(dict_bank & 0x0f); break; } return 0x00; } + +uint32_t DICTIONARY::read_debug_data8(uint32_t addr) +{ + // May read ram only + return dict_ram[addr & 0x1fff]; +} + +void DICTIONARY::write_debug_data8(uint32_t addr, uint32_t data) +{ + // May read ram only + dict_ram[addr & 0x1fff] = data; +} + +bool DICTIONARY::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + if(reg == NULL) return false; + if(strcasecmp(reg, _T("bank")) == 0) { + dict_bank = data & 0x0f; + return true; + } + return false; +} + +bool DICTIONARY::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + if(buffer == NULL) return false; + if(buffer_len <= 1) return false; + my_stprintf_s(buffer, buffer_len - 1, + _T("BANK=%02X WROTE=%s\n"), + dict_bank, (cmos_dirty) ? _T("Yes") : _T("No ")); + return true; +} #define STATE_VERSION 1 @@ -206,9 +238,7 @@ bool DICTIONARY::process_state(FILEIO* state_fio, bool loading) return false; } state_fio->StateValue(dict_bank); - state_fio->StateValue(bankd0_dict); state_fio->StateArray(dict_ram, sizeof(dict_ram), 1); - state_fio->StateArray(ram_0d0, sizeof(ram_0d0), 1); if(loading) { cmos_dirty = true; diff --git a/source/src/vm/fmtowns/towns_dictionary.h b/source/src/vm/fmtowns/towns_dictionary.h index cb58b3f48..f8b0d8a48 100644 --- a/source/src/vm/fmtowns/towns_dictionary.h +++ b/source/src/vm/fmtowns/towns_dictionary.h @@ -4,7 +4,16 @@ Author : Kyuma.Ohta Date : 2019.01.09- - [ dictionary rom/ram & cmos & RAM area 0x000d0000 - 0x000effff] + [ dictionary rom/ram & cmos & RAM area 0x000d0000 - 0x000dffff] + * MEMORY : + * 0x000d0000 - 0x000d7fff : DICTIONARY ROM (BANKED) + * 0x000d8000 - 0x000d9fff : DICTIONARY RAM / GAIJI RAM + * 0x000da000 - 0x000dffff : RESERVED + * 0xc2080000 - 0xc20fffff : DICTIONARY ROM (NOT BANKED) + * 0xc2140000 - 0xc2141fff : DICTIONARY RAM + * I/O : + * 0x0484 : DICTIONARY BANK (for 0xd0000 - 0xd7ffff) + * 0x3000 - 0x3ffe (even address) : DICTIONARY RAM */ #pragma once @@ -12,59 +21,61 @@ #include "../../common.h" #include "../device.h" -#define SIG_FMTOWNS_DICTSEL 0x1000 -#define SIG_FMTOWNS_DICTBANK 0x1001 +#define SIG_FMTOWNS_DICT_BANK 1 namespace FMTOWNS { class DICTIONARY : public DEVICE { protected: - DEVICE *d_sysrom; - uint8_t dict_rom[0x80000]; // 512KB uint8_t dict_ram[0x2000]; // 2 + 6KB - uint8_t ram_0d0[0x20000]; // 128KB - bool bankd0_dict; uint8_t dict_bank; - bool cmos_dirty; public: - DICTIONARY(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DICTIONARY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { - bankd0_dict = false; dict_bank = 0x00; cmos_dirty = false; - d_sysrom = NULL; - set_device_name("FM-Towns Dictionary ROM/RAM 0x000d0000 - 0x000effff with CMOS RAM"); + set_device_name("FM-Towns Dictionary ROM/RAM 0x000d0000 - 0x000dffff with CMOS RAM"); } ~DICTIONARY() {} void initialize(); void release(); void reset(); - uint32_t read_data8(uint32_t addr); - uint32_t read_data16(uint32_t addr); - uint32_t read_data32(uint32_t addr); - - void write_data8(uint32_t addr, uint32_t data); - void write_data16(uint32_t addr, uint32_t data); - void write_data32(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr); + uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr); + + void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data); + void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data); - void write_io8(uint32_t addr, uint32_t data); - uint32_t read_io8(uint32_t addr); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); - void write_signal(int ch, uint32_t data, uint32_t mask); - uint32_t read_signal(int ch); + void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_signal(int ch); bool process_state(FILEIO* state_fio, bool loading); - void set_context_sysrom(DEVICE* dev) + bool is_debugger_available() { - d_sysrom = dev; + return true; } + uint64_t get_debug_data_addr_space() + { + return 0x2000; + } + uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + + bool write_debug_reg(const _TCHAR *reg, uint32_t data); + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + }; } diff --git a/source/src/vm/fmtowns/towns_dmac.cpp b/source/src/vm/fmtowns/towns_dmac.cpp new file mode 100644 index 000000000..260ba3a71 --- /dev/null +++ b/source/src/vm/fmtowns/towns_dmac.cpp @@ -0,0 +1,384 @@ + +#include "./towns_dmac.h" +#include "debugger.h" + +namespace FMTOWNS { +void TOWNS_DMAC::initialize() +{ + UPD71071::initialize(); +} + +void TOWNS_DMAC::reset() +{ + UPD71071::reset(); + dma_wrap_reg = 0; + dma_addr_reg = 0; + dma_addr_mask = 0xffffffff; // OK? +// dma_addr_mask = 0x000fffff; // OK? + for(int i = 0; i < 4; i++) { + dma_high_address[i] = 0x00000000; + dma_high_address_bak[i] = 0x00000000; + creg_set[i] = false; + bcreg_set[i] = false; + } +// b16 = 2; // Fixed 16bit. +} + +void TOWNS_DMAC::write_io8(uint32_t addr, uint32_t data) +{ +// if((addr & 0x0f) == 0x0c) out_debug_log("WRITE REG: %08X %08X", addr, data); +// out_debug_log("WRITE REG: %04X %02X", addr, data); + uint naddr; + switch(addr & 0x0f) { + case 0x00: +// out_debug_log(_T("RESET REG(00h) to %02X"), data); + break; + case 0x02: + case 0x03: + // Note: This is *temporaly* workaround for 16bit transfer mode with 8bit bus. + // 20200318 K.O + if(base == 0) { + creg_set[selch] = true; + } + bcreg_set[selch] = true; + break; + case 0x07: + if(base == 0) { + dma_high_address[selch] = (data & 0xff) << 24; + } + dma_high_address_bak[selch] = (data & 0xff) << 24; + return; + break; + case 0x08: + if(((data & 0x04) != (cmd & 0x04)) && (selch == 3)) { + if((data & 0x04) != 0) break; + out_debug_log(_T("TRANSFER: CMD=%04X -> %04X CH=%d\nADDR=%08X"), cmd, (cmd & 0xff00) | (data & 0xff), selch, (dma[selch].areg & 0x00ffffff) | (dma_high_address[selch])); + } + break; + case 0x0a: + if((selch == 3)) { + out_debug_log(_T("SET MODE[%d] to %02X"), selch, data); + } + break; + case 0x0e: + if(((data | req) & 0x08) != 0) { + // out_debug_log(_T("TRANSFER ENABLE@REG0E DATA=%02X"), data); + } + break; + case 0x0f: + // Note: This is *temporaly* workaround for 16bit transfer mode with 8bit bus. + // 20200318 K.O +#if !defined(USE_QUEUED_SCSI_TRANSFER) + if((dma[selch].is_16bit) && (b16)) { + if(creg_set[selch]) { + dma[selch].creg <<= 1; + dma[selch].creg++; + creg_set[selch] = false; + } + if(bcreg_set[selch]) { + dma[selch].bcreg <<= 1; + dma[selch].bcreg++; + bcreg_set[selch] = false; + } + } + bcreg_set[selch] = false; + creg_set[selch] = false; +#endif +#if 0 + if((data & 0x08) == 0) { + out_debug_log(_T("START CDROM DMA MODE=%02X ADDR=%08X COUNT=%04X"), + dma[3].mode, (dma[3].areg & 0xffffff) | dma_high_address[3], + dma[3].creg); + } +#endif + break; + default: + break; + } + UPD71071::write_io8(addr, data); +} +uint32_t TOWNS_DMAC::read_io8(uint32_t addr) +{ + uint32_t val; + pair32_t nval; + switch(addr & 0x0f) { + case 0x01: + return (base << 3) | (1 << (selch & 3)); + break; + case 0x07: + if(base == 0) { + return (dma_high_address[selch] >> 24); + } + return (dma_high_address_bak[selch] >> 24); + break; + } + return UPD71071::read_io8(addr); +} + +void TOWNS_DMAC::do_dma_inc_dec_ptr_8bit(int c) +{ + // Note: FM-Towns may extend to 32bit. + if(dma[c].mode & 0x20) { + dma[c].areg = (((dma[c].areg - 1) & 0x00ffffff) | dma_high_address[c]) & dma_addr_mask; + } else { + dma[c].areg = (((dma[c].areg + 1) & 0x00ffffff) | dma_high_address[c]) & dma_addr_mask; + } +} + +void TOWNS_DMAC::do_dma_inc_dec_ptr_16bit(int c) +{ + // Note: FM-Towns may extend to 32bit. + if(dma[c].mode & 0x20) { + dma[c].areg = (((dma[c].areg - 2) & 0x00ffffff) | dma_high_address[c]) & dma_addr_mask; + } else { + dma[c].areg = (((dma[c].areg + 2) & 0x00ffffff) | dma_high_address[c]) & dma_addr_mask; + } +} + +bool TOWNS_DMAC::do_dma_epilogue(int c) +{ + if(dma[c].creg == 0) { // OK? + // TC + if(c == 3) { + out_debug_log(_T("TRANSFER COMPLETED CH.3: AREG=%08X BAREG=%08X CREG=%08X BCREG=%08X"), + (dma[c].areg & 0x00ffffff) | (dma_high_address[c] & 0xff000000), + (dma[c].bareg & 0x00ffffff) | (dma_high_address_bak[c] & 0xff000000), + dma[c].creg & 0x00ffffff, + dma[c].bcreg & 0x00ffffff + ); + + } + if(dma[c].mode & 0x10) { + dma_high_address[c] = dma_high_address_bak[c]; + } + } + return UPD71071::do_dma_epilogue(c); +} + +uint32_t TOWNS_DMAC::read_signal(int id) +{ + if(id == SIG_TOWNS_DMAC_ADDR_REG) { + return dma_addr_reg; + } else if(SIG_TOWNS_DMAC_WRAP_REG) { + return dma_wrap_reg; + } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) { + return dma_addr_mask; + } else if((id >= SIG_TOWNS_DMAC_HIGH_ADDRESS) && (id <= (SIG_TOWNS_DMAC_HIGH_ADDRESS + 3))) { + int ch = id - SIG_TOWNS_DMAC_HIGH_ADDRESS; + return dma_high_address[ch]; + } + return UPD71071::read_signal(id); +} + +void TOWNS_DMAC::write_signal(int id, uint32_t data, uint32_t _mask) +{ + if(id == SIG_TOWNS_DMAC_ADDR_REG) { + dma_addr_reg = data & 3; +// this->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, data, mask); + } else if(id == SIG_TOWNS_DMAC_WRAP_REG) { + dma_wrap_reg = data; +// this->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, data, mask); + } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) { + // From eFMR50 / memory.cpp / update_dma_addr_mask() + +#if 0 + switch(dma_addr_reg & 3) { + case 0: + dma_addr_mask = data; + break; + case 1: + if(!(dma_wrap_reg & 1) && (data == 0x000fffff)) { + dma_addr_mask = 0x000fffff; + } else { + dma_addr_mask = 0x00ffffff; + } + break; + default: + if(!(dma_wrap_reg & 1) && (data == 0x000fffff)) { + dma_addr_mask = 0x000fffff; + } else { + dma_addr_mask = 0xffffffff; + } + break; + } +#else + dma_addr_mask = data; +#endif + } else { + // Fallthrough. +// if(id == SIG_UPD71071_CH1) { +// out_debug_log(_T("DRQ from SCSI %02X %02X"), data, mask); +// } + UPD71071::write_signal(id, data, _mask); + } +} + +void TOWNS_DMAC::do_dma_dev_to_mem_8bit(int c) +{ + // io -> memory + uint32_t val; + uint32_t addr = (dma_high_address[c] & 0xff000000) | (dma[c].areg & 0x00ffffff); + reset_ube(c); + val = dma[c].dev->read_dma_io8(0); + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data8(addr, val); + } else { + write_via_debugger_data8(addr, val); + } + } else { + write_via_debugger_data8(addr, val); + } + // update temporary register + tmp = (tmp >> 8) | (val << 8); + +} + +void TOWNS_DMAC::do_dma_mem_to_dev_8bit(int c) +{ + // memory -> io + uint32_t val; + uint32_t addr = (dma_high_address[c] & 0xff000000) | (dma[c].areg & 0x00ffffff); + reset_ube(c); + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + val = d_debugger->read_via_debugger_data8(addr); + } else { + val = read_via_debugger_data8(addr); + } + } else { + val = read_via_debugger_data8(addr); + } + dma[c].dev->write_dma_io8(0, val); + // update temporary register + tmp = (tmp >> 8) | (val << 8); +} + +void TOWNS_DMAC::do_dma_dev_to_mem_16bit(int c) +{ + // io -> memory + uint32_t val; + uint32_t addr = (dma_high_address[c] & 0xff000000) | (dma[c].areg & 0x00ffffff); + set_ube(c); + val = dma[c].dev->read_dma_io16(0); + if((addr & 1) != 0) { + // If odd address, write a byte. + uint32_t tval = (val >> 8) & 0xff; + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data8(addr, tval); + } else { + write_via_debugger_data8(addr, tval); + } + } else { + write_via_debugger_data8(addr, tval); + } + } else { + // 16bit + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data16(addr, val); + } else { + write_via_debugger_data16(addr, val); + } + } else { + write_via_debugger_data16(addr, val); + } + } + // update temporary register + tmp = val; +} + +void TOWNS_DMAC::do_dma_mem_to_dev_16bit(int c) +{ + // memory -> io + uint32_t val; + uint32_t addr = (dma_high_address[c] & 0xff000000) | (dma[c].areg & 0x00ffffff); + set_ube(c); + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + val = d_debugger->read_via_debugger_data16(addr); + } else { + val = this->read_via_debugger_data16(addr); + } + } else { + val = this->read_via_debugger_data16(addr); + } + if((addr & 1) != 0) { + // If odd address, read a high byte. + val = (val >> 8) & 0xff; + } + dma[c].dev->write_dma_io16(0, val); + // update temporary register + tmp = val; +} + + +// note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle +bool TOWNS_DMAC::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + static const _TCHAR *dir[4] = { + _T("VERIFY"), _T("I/O->MEM"), _T("MEM->I/O"), _T("INVALID") + }; + if(buffer == NULL) return false; + _TCHAR sbuf[4][512] = {0}; + for(int i = 0; i < 4; i++) { + my_stprintf_s(sbuf[i], 512, + _T("CH%d AREG=%08X CREG=%04X BAREG=%08X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n"), + i, + (dma_high_address[i] & 0xff000000) | (dma[i].areg & 0x00ffffff), + dma[i].creg, + (dma_high_address[i] & 0xff000000) | (dma[i].bareg & 0x00ffffff), + dma[i].bcreg, + ((req | sreq) >> 0) & 1, + (mask >> 0) & 1, + dma[i].mode, + dir[(dma[i].mode >> 2) & 3] + ); + } + { + my_stprintf_s(buffer, buffer_len, + _T("16Bit=%s ADDR_MASK=%08X ADDR_REG=%02X ADDR_WRAP=%02X \n") + _T("SELECT CH=%d BASE=%02X REQ=%02X SREQ=%02X MASK=%02X TC=%02X ") + _T("CMD=%04X TMP=%04X\n") + _T("%s") + _T("%s") + _T("%s") + _T("%s"), + (b16) ? _T("YES") : _T("NO"), dma_addr_mask, dma_addr_reg, dma_wrap_reg, + selch, base, req, sreq, mask, tc, + cmd, tmp, + sbuf[0], + sbuf[1], + sbuf[2], + sbuf[3]); + return true; + } + return false; +} + +#define STATE_VERSION 2 + +bool TOWNS_DMAC::process_state(FILEIO *state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + if(!(UPD71071::process_state(state_fio, loading))) { + return false; + } + state_fio->StateValue(dma_addr_reg); + state_fio->StateValue(dma_wrap_reg); + state_fio->StateValue(dma_addr_mask); + state_fio->StateArray(dma_high_address, sizeof(dma_high_address), 1); + state_fio->StateArray(dma_high_address_bak, sizeof(dma_high_address_bak), 1); + + state_fio->StateArray(creg_set, sizeof(creg_set), 1); + state_fio->StateArray(bcreg_set, sizeof(bcreg_set), 1); + + return true; +} +} diff --git a/source/src/vm/fmtowns/towns_dmac.h b/source/src/vm/fmtowns/towns_dmac.h new file mode 100644 index 000000000..d9b954f3e --- /dev/null +++ b/source/src/vm/fmtowns/towns_dmac.h @@ -0,0 +1,55 @@ +#pragma once + +#include "../vm.h" +#include "../upd71071.h" + +// Using original signal using after 1 << 12. +#define SIG_TOWNS_DMAC_ADDR_REG 4096 +#define SIG_TOWNS_DMAC_WRAP_REG 4100 +#define SIG_TOWNS_DMAC_ADDR_MASK 4104 +#define SIG_TOWNS_DMAC_HIGH_ADDRESS 4108 /* 4108 - 4111 */ + +namespace FMTOWNS { +class TOWNS_DMAC : public UPD71071 +{ +protected: + uint8_t dma_addr_reg; + uint8_t dma_wrap_reg; + uint32_t dma_addr_mask; + uint32_t dma_high_address[4]; + uint32_t dma_high_address_bak[4]; + + // Temporally workaround for SCSI.20200318 K.O + bool creg_set[4]; + bool bcreg_set[4]; + virtual void __FASTCALL do_dma_inc_dec_ptr_8bit(int c); + virtual void __FASTCALL do_dma_inc_dec_ptr_16bit(int c); + virtual bool __FASTCALL do_dma_epilogue(int c); + + virtual void __FASTCALL do_dma_dev_to_mem_8bit(int c); + virtual void __FASTCALL do_dma_mem_to_dev_8bit(int c); + virtual void __FASTCALL do_dma_dev_to_mem_16bit(int c); + virtual void __FASTCALL do_dma_mem_to_dev_16bit(int c); + +public: + TOWNS_DMAC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : UPD71071(parent_vm, parent_emu) + { + set_device_name(_T("FM-Towns uPD71071 DMAC")); + } + ~TOWNS_DMAC() {} + // common functions + virtual void initialize(); + virtual void reset(); + + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t _mask); + virtual uint32_t __FASTCALL read_signal(int id); + + virtual bool process_state(FILEIO* state_fio, bool loading); + + virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); +}; + +} diff --git a/source/src/vm/fmtowns/towns_memory.cpp b/source/src/vm/fmtowns/towns_memory.cpp index 858fd9624..d3d1a9b9d 100644 --- a/source/src/vm/fmtowns/towns_memory.cpp +++ b/source/src/vm/fmtowns/towns_memory.cpp @@ -9,87 +9,196 @@ #include "../../fileio.h" #include "./towns_memory.h" +#include "./towns_dmac.h" #include "./towns_vram.h" -#include "../i386.h" +#include "./towns_planevram.h" +#include "./towns_sprite.h" +#include "./fontroms.h" +#include "./serialrom.h" +#include "./towns_crtc.h" + +#include "../i386_np21.h" +//#include "../i386.h" +#include "../pcm1bit.h" + +#include namespace FMTOWNS { + +#define ADDR_MASK (addr_max - 1) +#define BANK_MASK (bank_size - 1) + +void TOWNS_MEMORY::config_page00() +{ + if(dma_is_vram) { + // OK? From TSUGARU + set_memory_mapped_io_rw(0x000c0000, 0x000c7fff, d_planevram); + set_memory_mapped_io_rw(0x000c8000, 0x000cbfff, d_sprite); + set_memory_mapped_io_rw(0x000ca000, 0x000cafff, d_sprite); + if(ankcg_enabled) { + set_memory_mapped_io_r(0x000ca000, 0x000ca7ff, d_font); + set_memory_r (0x000ca800, 0x000cafff, rd_dummy); + set_memory_mapped_io_r(0x000cb000, 0x000cbfff, d_font); + } + set_memory_rw (0x000cc000, 0x000cffff, &(ram_pagec[0xc000])); + set_memory_mapped_io_rw(0x000cfc00, 0x000cffff, this); // MMIO + } else { + set_memory_rw (0x000c0000, 0x000cffff, ram_pagec); + } + if((select_d0_rom) && (select_d0_dict)) { + set_memory_mapped_io_rw(0x000d0000, 0x000dffff, d_dictionary); + } else { + set_memory_rw (0x000d0000, 0x000dffff, ram_paged); + } + if(select_d0_rom) { + set_memory_mapped_io_r (0x000f8000, 0x000fffff, d_sysrom); +// set_memory_w (0x000f8000, 0x000fffff, &(ram_pagef[0x8000])); +// set_memory_mapped_io_rw(0x000f8000, 0x000fffff, d_sysrom); + set_memory_w (0x000f8000, 0x000fffff, wr_dummy); + } else { + set_memory_rw (0x000f8000, 0x000fffff, &(ram_pagef[0x8000])); + } + if(dma_is_vram) { + set_wait_rw(0x000c0000, 0x000cffff, vram_wait_val); + } else { + set_wait_rw(0x000c0000, 0x000cffff, mem_wait_val); + } + +} void TOWNS_MEMORY::initialize() { +// if(initialized) return; MEMORY::initialize(); +// DEVICE::initialize(); extra_nmi_mask = true; extra_nmi_val = false; - + poff_status = false; + +// vram_wait_val = 6; +// mem_wait_val = 3; vram_wait_val = 6; mem_wait_val = 3; + if((cpu_id == 0x01) || (cpu_id == 0x03)) { + wait_register = 0x03; + } else { + wait_register = 0x83; + } +// mem_wait_val >>= 1; +// vram_wait_val >>= 1; + cpu_clock_val = 16000 * 1000; - set_memory_rw(0x00000000, 0x000bffff, ram_page0); - set_memory_mapped_io_rw(0x000c0000, 0x000c7fff, d_vram); // PLANE ACCESSED VRAM(EMULATED) - set_memory_mapped_io_rw(0x000c8000, 0x000c8fff, d_vram); // TEXT VRAM (EMULATED) - set_memory_mapped_io_rw(0x000c9000, 0x000c9fff, d_vram); // VRAM RESERVED - set_memory_mapped_io_rw(0x000ca000, 0x000cafff, d_vram); // ANKCG1 / IO / RAM - set_memory_mapped_io_rw(0x000cb000, 0x000cbfff, d_cgrom); // ANKCG1 / IO / RAM - set_memory_mapped_io_rw(0x000cc000, 0x000cffff, d_vram); // MMIO / RAM - set_memory_mapped_io_rw(0x000d0000, 0x000d7fff, d_dictionary); // DICTIONARY (BANKED) - set_memory_mapped_io_rw(0x000d8000, 0x000d9fff, d_sram); // SRAM (LEARN/GAIJI) - unset_memory_rw(0x000da000, 0x000effff); // RESERVED - - set_memory_rw(0x000f0000, 0x000f7fff, ram_pagef); - set_memory_mapped_io_rw(0x000f8000, 0x000fffff, d_sysrom); // SYSROM / RAM - - unset_memory_rw(0x00100000, 0x3fffffff); - extra_ram_size = extra_ram_size & 0x3ff00000; - if(extra_ram_size >= 0x00100000) { - extra_ram = malloc(extra_ram_size); + // Initialize R/W table + _MEMORY_DISABLE_DMA_MMIO = osd->check_feature(_T("MEMORY_DISABLE_DMA_MMIO")); + if(!(addr_max_was_set) && osd->check_feature(_T("MEMORY_ADDR_MAX"))) { + addr_max = osd->get_feature_uint64_value(_T("MEMORY_ADDR_MAX")); + } + if(!(bank_size_was_set) && osd->check_feature(_T("MEMORY_BANK_SIZE"))) { + bank_size = osd->get_feature_uint64_value(_T("MEMORY_BANK_SIZE")); + } + + bank_mask = BANK_MASK; + addr_mask = ADDR_MASK; + + initialized = true; + extram_size = extram_size & 0x3ff00000; + set_extra_ram_size(extram_size >> 20); // Check extra ram size. + if(extram_size >= 0x00100000) { + extra_ram = (uint8_t*)malloc(extram_size); if(extra_ram != NULL) { - set_memory_rw(0x00100000, (extra_ram_size + 0x00100000) - 1, extra_ram); - memset(extra_ram, 0x00, extra_ram_size); + set_memory_rw(0x00100000, (extram_size + 0x00100000) - 1, extra_ram); + memset(extra_ram, 0x00, extram_size); } } memset(ram_page0, 0x00, sizeof(ram_page0)); + memset(ram_pagec, 0x00, sizeof(ram_pagec)); + memset(ram_paged, 0x00, sizeof(ram_paged)); + memset(ram_pagee, 0x00, sizeof(ram_pagee)); memset(ram_pagef, 0x00, sizeof(ram_pagef)); + + select_d0_dict = false; + select_d0_rom = true; + + dma_is_vram = true; + // Lower 100000h + set_memory_rw (0x00000000, 0x000bffff, ram_page0); + set_memory_rw (0x000d0000, 0x000dffff, ram_paged); + set_memory_rw (0x000e0000, 0x000effff, ram_pagee); + set_memory_rw (0x000f0000, 0x000f7fff, ram_pagef); + set_memory_mapped_io_rw(0x000f8000, 0x000fffff, d_sysrom); + config_page00(); + + set_memory_mapped_io_rw(0x80000000, 0x8007ffff, d_vram); + set_memory_mapped_io_rw(0x80100000, 0x8017ffff, d_vram); + set_memory_mapped_io_rw(0x81000000, 0x8101ffff, d_sprite); + +// set_memory_mapped_io_rw(0xc0000000, 0xc0ffffff, d_iccard[0]); +// set_memory_mapped_io_rw(0xc1000000, 0xc1ffffff, d_iccard[1]); + set_wait_rw(0x00000000, 0xffffffff, vram_wait_val); - unset_memory_rw(0x40000000, 0x7fffffff); // EXTRA SLOT - set_memory_mapped_io_rw(0x80000000, 0x8007ffff, d_display); // VRAM - unset_memory_rw(0x80080000, 0x800fffff); // RESERVED VRAM - set_memory_mapped_io_rw(0x80100000, 0x8017ffff, d_display); // VRAM - unset_memory_rw(0x80180000, 0x801fffff); // RESERVED VRAM - unset_memory_rw(0x80200000, 0x80ffffff); // RESERVED VRAM - set_memory_mapped_io_rw(0x81000000, 0x8101ffff, d_sprite); // SPRITE PATTERN - - unset_memory_rw(0xc0000000, 0xc1ffffff); // Reserved - if(d_romcard[0] != NULL) { - set_memory_mapped_io_rw(0xc0000000, 0xc0ffffff, d_romcard[0]); // DICTIONARY ROM - } -#if 0 - if(d_romcard[1] != NULL) { - set_memory_mapped_io_rw(0xc1000000, 0xc1ffffff, d_romcard[1]); // DICTIONARY ROM + set_memory_mapped_io_rw(0xc0000000, 0xc0ffffff, d_iccard[0]); + set_memory_mapped_io_rw(0xc1000000, 0xc1ffffff, d_iccard[1]); + + set_memory_mapped_io_r (0xc2000000, 0xc207ffff, d_msdos); + set_memory_mapped_io_r (0xc2080000, 0xc20fffff, d_dictionary); + set_memory_mapped_io_r (0xc2100000, 0xc213ffff, d_font); + set_memory_mapped_io_rw(0xc2140000, 0xc2141fff, d_dictionary); + if(d_font_20pix != NULL) { + set_memory_mapped_io_r (0xc2180000, 0xc21fffff, d_font_20pix); } -#endif - set_memory_mapped_io_rw(0xc2000000, 0xc207ffff, d_msdos); // MSDOS - set_memory_mapped_io_rw(0xc2080000, 0xc20fffff, d_dictionary); // DICTIONARY ROM - set_memory_mapped_io_rw(0xc2100000, 0xc213ffff, d_font); // FONT ROM - set_memory_mapped_io_rw(0xc2140000, 0xc2141fff, d_sram); // LEARN RAM - unset_memory_rw(0xc2142000, 0xc21ffffff); // Reserved + set_memory_mapped_io_rw(0xc2200000, 0xc2200fff, d_pcm); + set_memory_mapped_io_r (0xfffc0000, 0xffffffff, d_sysrom); - set_memory_mapped_io_rw(0xc2200000, 0xc2200fff, d_pcm); // PCM RAM (ToDo:) - - unset_memory_rw(0xc2201000, 0xfffbffff); // Reserved - set_memory_mapped_io_rw(0xfffc0000, 0xffffffff, d_sysrom); + set_wait_values(); + // Another devices are blank // load rom image // ToDo: More smart. vram_size = 0x80000; // OK? +} + - //dma_addr_reg = dma_wrap_reg = 0; - dma_addr_mask = 0x00ffffff; // ToDo +void TOWNS_MEMORY::set_wait_values() +{ + uint32_t waitfactor = 1 << 16; + if(cpu_clock_val < get_cpu_clocks(d_cpu)) { + waitfactor = (uint32_t)(((double)get_cpu_clocks(d_cpu) / (double)cpu_clock_val) * 65536.0); + } + d_cpu->write_signal(SIG_CPU_WAIT_FACTOR, waitfactor, 0xffffffff); - initialize_tables(); + set_wait_rw(0x00000000, 0x000bffff, mem_wait_val); + set_wait_rw(0x000d0000, 0x000fffff, mem_wait_val); + if(dma_is_vram) { + set_wait_rw(0x000c0000, 0x000cffff, vram_wait_val); + } else { + set_wait_rw(0x000c0000, 0x000cffff, mem_wait_val); + } + set_wait_rw(0x00100000, 0x00100000 + (extram_size & 0x3ff00000) - 1, mem_wait_val); + + // ToDo: Extend I/O Slots + set_wait_rw(0x80000000, 0x800fffff, vram_wait_val); + set_wait_rw(0x80100000, 0x801fffff, vram_wait_val); + set_wait_rw(0x81000000, 0x8101ffff, vram_wait_val); + // ToDo: ROM CARDS + if(d_iccard[0] != NULL) { + set_wait_rw(0xc0000000, 0xc0ffffff, mem_wait_val); // OK? + } + if(d_iccard[0] != NULL) { + set_wait_rw(0xc1000000, 0xc1ffffff, mem_wait_val); // OK? + } + set_wait_rw(0xc2000000, 0xc2141fff, mem_wait_val); + set_wait_rw(0xc2200000, 0xc2200fff, mem_wait_val); + set_wait_rw(0xfffc0000, 0xffffffff, mem_wait_val); } void TOWNS_MEMORY::release() { + if(rd_table != NULL) free(rd_table); + if(rd_dummy != NULL) free(rd_dummy); + if(wr_table != NULL) free(wr_table); + if(wr_dummy != NULL) free(wr_dummy); + if(extra_ram != NULL) { free(extra_ram); extra_ram = NULL; @@ -98,67 +207,138 @@ void TOWNS_MEMORY::release() void TOWNS_MEMORY::reset() { // reset memory - protect = rst = 0; // ToDo - dma_addr_reg = dma_wrap_reg = 0; - dma_addr_mask = 0x00ffffff; - d_cpu->set_address_mask(0xffffffff); + is_compatible = true; + reset_happened = false; +#if 1 + if(d_cpu != NULL) { + d_cpu->set_address_mask(0xffffffff); + } + if(d_dmac != NULL) { + d_dmac->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, 0xffffffff, 0xffffffff); + } +#endif + dma_is_vram = true; + nmi_vector_protect = false; + ankcg_enabled = false; + nmi_mask = false; + select_d0_dict = false; + select_d0_rom = true; + config_page00(); +// cpu_clock_val = 16000 * 1000; + set_wait_values(); } - // Address (TOWNS BASIC): // 0x0020 - 0x0022, 0x0030-0x0031, // 0x0400 - 0x0404, // 0x0480 - 0x0484 // 0x05c0 - 0x05c2 // 0x05ec (Wait register) +// 0x05ed (CPU SPEED REGISTER) // Is set extra NMI (0x05c0 - 0x05c2)? + uint32_t TOWNS_MEMORY::read_io8(uint32_t addr) { - uint32_t val = 0xff; + uint32_t val = 0x00; // MAY NOT FILL to "1" for unused bit 20200129 K.O switch(addr & 0xffff) { case 0x0020: // Software reset ETC. // reset cause register - val = ((software_reset) ? 1 : 0) | ((d_cpu->get_shutdown_flag() != 0) ? 2 : 0); + if(d_cpu != NULL) { + val = ((software_reset) ? 1 : 0) | ((reset_happened) ? 2 : 0); + reset_happened = false; + } software_reset = false; - d_cpu->set_shutdown_flag(0); - val = val | 0x7c; + if(d_cpu != NULL) { + d_cpu->set_shutdown_flag(0); + } + if((machine_id >= 0x0300) & ((machine_id & 0xff00) != 0x0400)) { // After UX + val = val | ((poff_status) ? 0x04 : 0x00); + } break; case 0x0022: - // Power register val = 0xff; +// if(d_dmac != NULL) { +// val = d_dmac->read_signal(SIG_TOWNS_DMAC_ADDR_REG); +// } + break; + case 0x0024: + // CPU MISC3 + val = 0xff; + if(machine_id >= 0x0700) { // After HR/HG + val &= ~0x08; // POFFEN ( + } + if(machine_id >= 0x0700) { // After HR/HG + val &= ~0x10; // Free run counter + } + if(machine_id >= 0x0700) { // After HR/HG + val &= ~0x20; // CRTPOWOFF (0022h) + } + if(machine_id >= 0x0700) { // After HR/HG + val &= ~0x40; // RCREN + } + if(machine_id >= 0x0700) { // After HR/HG + val &= ~0x80; // ENPOFF + } + break; + case 0x0025: + // CPU MISC4 + if(machine_id >= 0x0500) { // After CX + val = 0x7f; + } else { + val = 0xff; + } + break; + case 0x0028: + // NMI MASK + if(machine_id >= 0x0500) { // After CX + val = (nmi_mask) ? 0x01 : 0x00; + } break; case 0x0030: - val = (((machine_id & 0x1f) << 3) | (cpu_id & 7)); + val = ((machine_id & 0xf8) | (cpu_id & 7)); // SPEED: bit0/Write break; case 0x0031: - val = ((machine_id >> 5) & 0xff); + val = ((machine_id >> 8) & 0xff); break; case 0x0032: { - //bool __cs = (d_serialrom->read_data8(SIG_SERIALROM_CS) == 0); - bool __clk = (d_serialrom->read_data8(SIG_SERIALROM_CLK) != 0); - bool __reset = (d_serialrom->read_data8(SIG_SERIALROM_RESET) != 0); - bool __dat = (d_serialrom->read_data8(SIG_SERIALROM_DATA) != 0); + //bool __cs = (d_serialrom->read_signal(SIG_SERIALROM_CS) == 0); + bool __clk = (d_serialrom->read_signal(SIG_SERIALROM_CLK) != 0); + bool __reset = (d_serialrom->read_signal(SIG_SERIALROM_RESET) != 0); + bool __dat = (d_serialrom->read_signal(SIG_SERIALROM_DATA) != 0); val = ((__reset) ? 0x80 : 0x00) | ((__clk) ? 0x40 : 0x00) | 0x3e | ((__dat) ? 0x01 : 0x00); } break; - case 0x006c: // Wait register. - if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H - val = 0x7f; - } - break; case 0x0400: // Resolution: - val = 0xfe; +// val = 0xfe; + val = 0x00; break; case 0x0404: // System Status Reg. - val = (bankc0_vram) ? 0x7f : 0xff; +// val = (dma_is_vram) ? 0x7f : 0xff; + val = (dma_is_vram) ? 0x00 : 0x80; + break; + case 0x0480: + val = (select_d0_dict) ? 0x01 : 0x00; + val |= ((select_d0_rom) ? 0x00 : 0x02); break; case 0x05c0: - val = (extra_nmi_mask) ? 0xf7 : 0xff; +// val = (extra_nmi_mask) ? 0xf7 : 0xff; + val = (extra_nmi_mask) ? 0x00 : 0x08; break; case 0x05c2: - val = (extra_nmi_val) ? 0xff : 0xf7; +// val = (extra_nmi_val) ? 0xff : 0xf7; + val = (extra_nmi_val) ? 0x08 : 0x00; + break; + case 0x05e0: + if(machine_id < 0x0200) { // Towns 1/2 + return wait_register; + } + break; + case 0x05e2: + if(machine_id >= 0x0200) { // i386 + return wait_register; + } break; case 0x05e8: // After Towns1F/2F/1H/2H @@ -185,23 +365,122 @@ uint32_t TOWNS_MEMORY::read_io8(uint32_t addr) val = ((extram_size >> 20) & 0x7f); break; default: - val = 0xff; // ??? + val = 0x00; // ??? break; } } break; case 0x05ec: - if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H? - val = 0x00 | ((mem_wait_val > 0) ? 0x01 : 0x00); + if(machine_id >= 0x0200) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H? -> Yes + val = 0x00; + if(mem_wait_val < 1) val |= 0x01; + } else { + val = 0xff; + } + break; + case 0x05ed: + if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H? -> Yes + uint32_t clk = get_cpu_clocks(d_cpu); + clk = clk / (1000 * 1000); + if(clk < 16) clk = 16; + if(clk > 127) clk = 127; // ToDo + val = 0x00 | clk; + } else { + val = 0xff; + } + break; + case 0xfda4: + if(machine_id >= 0x0700) { // After HR/HG + return (is_compatible) ? 0x00 : 0x01; + } else { + return 0x00; + } + break; + case 0xff88: + if((machine_id >= 0x0600) && !(is_compatible)) { // After UG + if(d_crtc != NULL) { + val = d_crtc->read_signal(SIG_TOWNS_CRTC_MMIO_CFF82H); + } + } else if(d_planevram != NULL) { + val = d_planevram->read_io8(addr); + } + break; + case 0xff94: + return 0x80; + break; + case 0xff95: + break; + case 0xff96: + if(d_font != NULL) { + return d_font->read_signal(SIG_TOWNS_FONT_KANJI_DATA_LOW); + } + break; + case 0xff97: + if(d_font != NULL) { + return d_font->read_signal(SIG_TOWNS_FONT_KANJI_DATA_HIGH); + } + break; + case 0xff98: + if(d_beep != NULL) { + d_beep->write_signal(SIG_PCM1BIT_ON, 1, 1); + } + break; + case 0xff99: + if((machine_id >= 0x0600) && !(is_compatible)) { // After UG + val = (ankcg_enabled) ? 0x01 : 0x00; + } else if(d_planevram != NULL) { + val = d_planevram->read_memory_mapped_io8(addr); + } + break; + case 0xff9c: + if((machine_id >= 0x0600) && !(is_compatible)) { // After UG + if(d_font != NULL) { + val = d_font->read_signal(SIG_TOWNS_FONT_KANJI_HIGH); + } + } else if(d_planevram != NULL) { + val = d_planevram->read_io8(addr); + } + break; + case 0xff9d: + if((machine_id >= 0x0600) && !(is_compatible)) { // After UG + if(d_font != NULL) { + val = d_font->read_signal(SIG_TOWNS_FONT_KANJI_LOW); + } + } else if(d_planevram != NULL) { + val = d_planevram->read_io8(addr); + } + break; + case 0xff9e: + if((machine_id >= 0x0600) && !(is_compatible)) { // After UG + if(d_font != NULL) { + val = d_font->read_signal(SIG_TOWNS_FONT_KANJI_ROW); + } + } else if(d_planevram != NULL) { + val = d_planevram->read_io8(addr); } break; default: + if(d_planevram != NULL) { + val = d_planevram->read_io8(addr); + } break; } return val; } +uint32_t TOWNS_MEMORY::read_io16(uint32_t addr) +{ + { + // OK? + pair16_t n; + n.b.l = read_io8((addr & 0xfffe) + 0); + n.b.h = read_io8((addr & 0xfffe) + 1); + return n.w; + } + return 0xffff; +} + void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data) { @@ -218,232 +497,540 @@ void TOWNS_MEMORY::write_io8(uint32_t addr, uint32_t data) } else { software_reset = false; } + if((data & 0x40) != 0) { - d_cpu->set_shutdown_flag(1); - emu->power_off(); + poff_status = true; + if(d_cpu != NULL) { + d_cpu->set_shutdown_flag(1); + } + // Todo: Implement true power off. +// emu->power_off(); + } else { + poff_status = false; + if(d_cpu != NULL) { + d_cpu->set_shutdown_flag(0); + } } + if(software_reset) { - d_cpu->reset(); + if(d_cpu != NULL) { + d_cpu->reset(); + } + //dma_is_vram = false; + //d_sysrom->reset(); + //config_page00(); + } + // Towns SEEMS to not set addreess mask (a.k.a A20 mask). 20200131 K.O + if(d_dmac != NULL) { + d_dmac->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, 0xffffffff, 0xffffffff); } break; case 0x0022: if((data & 0x40) != 0) { - d_cpu->set_shutdown_flag(1); - emu->power_off(); + if(d_cpu != NULL) { + d_cpu->set_shutdown_flag(1); + } + // Todo: Implement true power off. +// emu->power_off(); + } + if(d_dmac != NULL) { + d_dmac->write_signal(SIG_TOWNS_DMAC_ADDR_REG, data, 0xff); } // Power register break; + case 0x0024: +// if(d_dmac != NULL) { +// d_dmac->write_signal(SIG_TOWNS_DMAC_WRAP_REG, data, 0xff); +// } + break; case 0x0032: { - d_serialrom->write_data8(SIG_SERIALROM_CS, ~data, 0x20); - d_serialrom->write_data8(SIG_SERIALROM_CLK, data, 0x40); - d_serialrom->write_data8(SIG_SERIALROM_RESET, data, 0x80); - } - break; - case 0x006c: // Wait register. - if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H - if(event_wait_1us != -1) cancel_event(this, event_wait_1us); - register_event(this, EVENT_1US_WAIT, 1.0, false, &event_wait_1us); - d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); + d_serialrom->write_signal(SIG_SERIALROM_CS, ~data, 0x20); + d_serialrom->write_signal(SIG_SERIALROM_CLK, data, 0x40); + d_serialrom->write_signal(SIG_SERIALROM_RESET, data, 0x80); } break; case 0x0404: // System Status Reg. - bankc0_vram = ((data & 0x80) != 0); + dma_is_vram = ((data & 0x80) == 0); + config_page00(); + break; + case 0x0480: + select_d0_dict = ((data & 0x01) != 0) ? true : false; + select_d0_rom = ((data & 0x02) == 0) ? true : false; + config_page00(); break; case 0x05c0: extra_nmi_mask = ((data & 0x08) == 0); break; - case 0x05ec: - if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H? - vram_wait_val = ((data & 0x01) != 0) ? 3 : 6; - mem_wait_val = ((data & 0x01) != 0) ? 0 : 3; - this->write_signal(SIG_FMTOWNS_SET_VRAMWAIT, vram_wait_val, 0xff); - this->write_signal(SIG_FMTOWNS_SET_MEMWAIT, mem_wait_val, 0xff); + case 0x05e0: + // From AB.COM + if(machine_id < 0x0200) { // Towns 1/2 + uint8_t nval = data & 7; + if(nval < 1) nval = 1; + if(nval > 5) nval = 5; + mem_wait_val = nval + 1; + vram_wait_val = nval + 3 + 1; + wait_register = nval; + set_wait_values(); } break; - default: - break; - } - return; -} - -void TOWNS_MEMORY::event_callback(int id, int err) -{ - switch(id) { - case EVENT_1US_WAIT: - cvent_wait_1us = -1; - if(machine_id >= 0x0300) { // After UX*/10F/20F/40H/80H - d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1); + case 0x05e2: + if(machine_id >= 0x0200) { // After Towns 1H/2F. + if(data != 0x83) { + uint8_t nval = data & 7; + if(machine_id <= 0x0200) { // Towns 1H/2F. + if(nval < 1) nval = 1; + } + if(nval > 5) nval = 5; + mem_wait_val = nval; + vram_wait_val = nval + 3; + wait_register = nval; + } else { + mem_wait_val = 3; + vram_wait_val = 6; + wait_register = data; + } + set_wait_values(); } break; - default: - break; - } - -} - -uint32_t TOWNS_MEMORY::read_mmio(uint32_t addr, int *wait, bool *hit) -{ - if(hit != NULL) *hit = false; - if(wait != NULL) *wait = 0; // OK? - if(addr >= 0x000d0000) return 0xffffffff; - if(addr < 0x000cff80) return 0xffffffff; - uint32_t val = 0xff; - bool found = false; - switch(addr & 0x7f) { - case 0x00: - if(d_vram != NULL) { - val = d_vram->read_io8(FMTOWNS_VRAM_IO_CURSOR); - found = true; + case 0x05ec: + if(machine_id >= 0x0500) { // Towns2 CX : Is this hidden register after Towns 1F/2F/1H/2H? -> Yes + vram_wait_val = ((data & 0x01) != 0) ? 3 : 6; + mem_wait_val = ((data & 0x01) != 0) ? 0 : 3; +// mem_wait_val >>= 1; +// vram_wait_val >>= 1; + cpu_clock_val = ((data & 0x01) != 0) ? (get_cpu_clocks(d_cpu)) : (16 * 1000 * 1000); } + set_wait_values(); break; - case 0x01: - if(d_vram != NULL) { - val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_RAMSELECT); - found = true; + case 0xfda4: + if(machine_id >= 0x0700) { // After HR/HG + is_compatible = ((data & 0x01) == 0x00) ? true : false; + if(d_crtc != NULL) { + d_crtc->write_signal(SIG_TOWNS_CRTC_COMPATIBLE_MMIO, (is_compatible) ? 0xffffffff : 0x00000000, 0xffffffff); + } } break; - case 0x02: - if(d_vram != NULL) { - val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_DISPMODE); - found = true; + case 0xff94: + if(d_font != NULL) { + d_font->write_signal(SIG_TOWNS_FONT_KANJI_HIGH, data, 0xff); } break; - case 0x03: - if(d_vram != NULL) { - val = d_vram->read_io8(FMTOWNS_VRAM_IO_FMR_PAGESEL); - found = true; + case 0xff95: + if(d_font != NULL) { + d_font->write_signal(SIG_TOWNS_FONT_KANJI_LOW, data, 0xff); } break; - case 0x04: - val = 0x7f; // Reserve.FIRQ - found = true; + case 0xff96: break; - case 0x06: - if(d_vram != NULL) { - val = d_vram->read_io8(FMTOWNS_VRAM_IO_SYNC_STATUS); - found = true; - } - break; - //case 0x14: - //case 0x15: - case 0x16: - case 0x17: - if(d_vram != NULL) { - val = d_vram->read_io8(FMTOWNS_VRAM_KANJICG + (addr & 3)); - found = true; - } + case 0xff97: break; - case 0x18: + case 0xff98: if(d_beep != NULL) { - d_beep->write_signal(SIG_BEEP_ON, 1, 1); - found = true; + d_beep->write_signal(SIG_PCM1BIT_ON, 0, 1); } break; - case 0x19: - val = val & ((ankcg_enabled) ? 0x00 : 0x01); - found = true; + case 0xff99: + ankcg_enabled = ((data & 1) != 0) ? true : false; + config_page00(); break; - case 0x20: - val = 0xff; - val = val & 0x7f; - found = true; + case 0xff9e: + if((machine_id >= 0x0600) && !(is_compatible)) { // After UG + if(d_font != NULL) { + d_font->write_signal(SIG_TOWNS_FONT_KANJI_ROW, data, 0xff); + } + } else if(d_planevram != NULL) { + d_planevram->write_io8(addr , data); + } break; default: + if(d_planevram != NULL) { + d_planevram->write_io8(addr , data); + } break; } - if(hit != NULL) *hit = found; - return (uint32_t)val; + return; +} +/* +// At page 000C0000h - 000CFFFFh : Maybe return real memory for word/dword access. +uint32_t TOWNS_MEMORY::read_memory_mapped_io16(uint32_t addr) +{ + if((addr >= 0xc0000) && (addr <= 0xcffff)) { + pair32_t n; + n.d = 0; + n.b.l = ram_pagec[(addr & 0xffff) + 0]; + n.b.h = ram_pagec[(addr & 0xffff) + 1]; + return n.d; + } + return 0xffff; } -void TOWNS_MEMORY::write_mmio(uint32_t addr, uint32_t data, int *wait, bool *hit) +uint32_t TOWNS_MEMORY::read_memory_mapped_io32(uint32_t addr) +{ + if((addr >= 0xc0000) && (addr <= 0xcffff)) { + pair32_t n; + n.d = 0; + n.b.l = ram_pagec[(addr & 0xffff) + 0]; + n.b.h = ram_pagec[(addr & 0xffff) + 1]; + n.b.h2 = ram_pagec[(addr & 0xffff) + 2]; + n.b.h3 = ram_pagec[(addr & 0xffff) + 3]; + return n.d; + } + return 0xffffffff; +} +*/ +uint32_t TOWNS_MEMORY::read_memory_mapped_io8(uint32_t addr) { - if(hit != NULL) *hit = false; - if(wait != NULL) *wait = 0; // OK? - if(addr >= 0x000d0000) return; - if(addr < 0x000cff80) return; - bool found = false; - switch(addr & 0x7f) { - case 0x00: - if(d_vram != NULL) { - d_vram->write_io8(FMTOWNS_VRAM_IO_CURSOR, data); - found = true; + uint32_t val = 0xff; + if((addr >= 0xc0000) && (addr <= 0xc7fff)) { + if(d_planevram != NULL) { + return d_planevram->read_memory_mapped_io8(addr); } - break; - case 0x01: - if(d_vram != NULL) { - d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_RAMSELECT, data); - found = true; + return 0xff; + } else if((addr >= 0xc8000) && (addr <= 0xc9fff)) { + if(d_sprite != NULL) { + d_sprite->read_memory_mapped_io8(addr); + } else { + return 0xff; } - break; - case 0x02: - if(d_vram != NULL) { - d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_DISPMODE, data); - found = true; + } else if((addr >= 0xca000) && (addr <= 0xcbfff)) { + if(ankcg_enabled) { + if((addr >= 0xca000) && (addr <= 0xca7ff)) { + if(d_font != NULL) { + d_font->read_memory_mapped_io8(addr); + } else { + return 0xff; + } + } else if((addr >= 0xcb000) && (addr <= 0xcbfff)) { + if(d_font != NULL) { + d_font->read_memory_mapped_io8(addr); + } else { + return 0xff; + } + } else if((addr >= 0xca800) && (addr <= 0xcafff)) { + return 0xff; + } } - break; - case 0x03: - if(d_vram != NULL) { - d_vram->write_io8(FMTOWNS_VRAM_IO_FMR_PAGESEL, data); - found = true; + if(d_sprite != NULL) { + d_sprite->read_memory_mapped_io8(addr); + } else { + return 0xff; } + } + + if((addr < 0xcfc00) || (addr >= 0xd0000)) return 0xff; + switch(addr) { + case 0xcff88: + case 0xcff94: + case 0xcff96: + case 0xcff97: + case 0xcff98: + case 0xcff99: + case 0xcff9c: + case 0xcff9d: + case 0xcff9e: + val = read_io8(addr & 0xffff); break; - case 0x04: - found = true; - break; - case 0x06: - found = true; - break; - case 0x14: - case 0x15: - case 0x16: - case 0x17: - if(d_vram != NULL) { - d_vram->write_io8(FMTOWNS_VRAM_KANJICG + (addr & 3), data); - found = true; + default: + if((addr < 0xcff80) || (addr > 0xcffbb)) { + return ram_pagec[addr & 0xffff]; } - break; - case 0x18: - if(d_beep != NULL) { - d_beep->write_signal(SIG_BEEP_ON, 0, 1); - found = true; + if(d_planevram != NULL) { + val = d_planevram->read_io8(addr & 0xffff); } break; - case 0x19: - ankcg_enabled = ((data & 1) == 0); - found = true; - break; - case 0x20: - found = true; + } + return (uint32_t)val; +} +/* +void TOWNS_MEMORY::write_memory_mapped_io16(uint32_t addr, uint32_t data) +{ + if((addr >= 0xc0000) && (addr <= 0xcffff)) { + pair16_t n; + n.w = data; + ram_pagec[(addr & 0xffff) + 0] = n.b.l; + ram_pagec[(addr & 0xffff) + 1] = n.b.h; + } +} + +void TOWNS_MEMORY::write_memory_mapped_io32(uint32_t addr, uint32_t data) +{ + if((addr >= 0xc0000) && (addr <= 0xcffff)) { + pair32_t n; + n.d = data; + ram_pagec[(addr & 0xffff) + 0] = n.b.l; + ram_pagec[(addr & 0xffff) + 1] = n.b.h; + ram_pagec[(addr & 0xffff) + 2] = n.b.h2; + ram_pagec[(addr & 0xffff) + 3] = n.b.h3; + } +} +*/ + +void TOWNS_MEMORY::write_memory_mapped_io8(uint32_t addr, uint32_t data) +{ + if((addr >= 0xc0000) && (addr <= 0xc7fff)) { + if(d_planevram != NULL) { + d_planevram->write_memory_mapped_io8(addr, data); + } + return; + } else if((addr >= 0xc8000) && (addr <= 0xc9fff)) { + if(d_sprite != NULL) { + d_sprite->write_memory_mapped_io8(addr, data); + } + return; + } else if((addr >= 0xca000) && (addr <= 0xcbfff)) { + if(d_sprite != NULL) { + d_sprite->write_memory_mapped_io8(addr, data); + } + return; + } + if((addr < 0xcfc00) || (addr >= 0xd0000)) return; + switch(addr) { + case 0xcff94: + case 0xcff95: + case 0xcff98: + case 0xcff99: + case 0xcff9e: + write_io8(addr & 0xffff, data); break; default: + if((addr < 0xcff80) || (addr > 0xcffbb)) { + ram_pagec[addr & 0xffff] = data; + return; + } + if(d_planevram != NULL) { + d_planevram->write_io8(addr & 0xffff, data); + } break; } - if(hit != NULL) *hit = found; return; } + +void TOWNS_MEMORY::write_data8(uint32_t addr, uint32_t data) +{ + write_primitive_byte(addr, data); +} + +void TOWNS_MEMORY::write_data16(uint32_t addr, uint32_t data) +{ + write_primitive_word(addr, data); +} + +void TOWNS_MEMORY::write_data32(uint32_t addr, uint32_t data) +{ + write_primitive_dword(addr, data); +} + +uint32_t TOWNS_MEMORY::read_data8(uint32_t addr) +{ + return read_primitive_byte(addr); +} + +uint32_t TOWNS_MEMORY::read_data16(uint32_t addr) +{ + return read_primitive_word(addr); +} + +uint32_t TOWNS_MEMORY::read_data32(uint32_t addr) +{ + return read_primitive_dword(addr); +} + +void TOWNS_MEMORY::write_data8w(uint32_t addr, uint32_t data, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = wr_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + write_primitive_byte(addr, data); +} + +void TOWNS_MEMORY::write_data16w(uint32_t addr, uint32_t data, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = wr_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + write_primitive_word(addr, data); +} + +void TOWNS_MEMORY::write_data32w(uint32_t addr, uint32_t data, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = wr_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + write_primitive_dword(addr, data); +} + +uint32_t TOWNS_MEMORY::read_data8w(uint32_t addr, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = rd_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + return read_primitive_byte(addr); +} + +uint32_t TOWNS_MEMORY::read_data16w(uint32_t addr, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = rd_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + return read_primitive_word(addr); +} + +uint32_t TOWNS_MEMORY::read_data32w(uint32_t addr, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = rd_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + return read_primitive_dword(addr); +} + +void TOWNS_MEMORY::write_dma_data8(uint32_t addr, uint32_t data) +{ + write_primitive_byte(addr, data); +} + +void TOWNS_MEMORY::write_dma_data16(uint32_t addr, uint32_t data) +{ + write_primitive_word(addr, data); +} + +void TOWNS_MEMORY::write_dma_data32(uint32_t addr, uint32_t data) +{ + write_primitive_dword(addr, data); +} + +uint32_t TOWNS_MEMORY::read_dma_data8(uint32_t addr) +{ + return read_primitive_byte(addr); +} + +uint32_t TOWNS_MEMORY::read_dma_data16(uint32_t addr) +{ + return read_primitive_word(addr); +} + +uint32_t TOWNS_MEMORY::read_dma_data32(uint32_t addr) +{ + return read_primitive_dword(addr); +} + + +void TOWNS_MEMORY::write_dma_data8w(uint32_t addr, uint32_t data, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = wr_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + write_primitive_byte(addr, data); +} + +void TOWNS_MEMORY::write_dma_data16w(uint32_t addr, uint32_t data, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = wr_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + write_primitive_word(addr, data); +} + +void TOWNS_MEMORY::write_dma_data32w(uint32_t addr, uint32_t data, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = wr_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + write_primitive_dword(addr, data); +} + +uint32_t TOWNS_MEMORY::read_dma_data8w(uint32_t addr, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = rd_table[bank].wait; + } + return read_primitive_byte(addr); +} + +uint32_t TOWNS_MEMORY::read_dma_data16w(uint32_t addr, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = rd_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + return read_primitive_word(addr); +} + +uint32_t TOWNS_MEMORY::read_dma_data32w(uint32_t addr, int* wait) +{ + int bank = (addr & addr_mask) >> addr_shift; + if(wait != NULL) { + *wait = rd_table[bank].wait; // OK? AT BOUNDARY 20200906 K.O + } + return read_primitive_dword(addr); +} + void TOWNS_MEMORY::write_signal(int ch, uint32_t data, uint32_t mask) { if(ch == SIG_MEMORY_EXTNMI) { extra_nmi_val = ((data & mask) != 0); + if(!(extra_nmi_mask)) { + // Not MASK + if(d_cpu != NULL) { + d_cpu->write_signal(SIG_CPU_NMI, data, mask); + } + } } else if(ch == SIG_CPU_NMI) { // Check protect - d_cpu->write_signal(SIG_CPU_NMI, data, mask); + if(!(nmi_mask)) { + if(d_cpu != NULL) { + d_cpu->write_signal(SIG_CPU_NMI, data, mask); + } + } } else if(ch == SIG_CPU_IRQ) { - d_cpu->write_signal(SIG_CPU_IRQ, data, mask); + if(d_cpu != NULL) { + d_cpu->write_signal(SIG_CPU_IRQ, data, mask); + } } else if(ch == SIG_CPU_BUSREQ) { - d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask); + if(d_cpu != NULL) { + d_cpu->write_signal(SIG_CPU_BUSREQ, data, mask); + } } else if(ch == SIG_I386_A20) { - d_cpu->write_signal(SIG_I386_A20, data, mask); - } else if(ch == SIG_FMTOWNS_SET_MEMWAIT) { + if(d_cpu != NULL) { + d_cpu->write_signal(SIG_I386_A20, data, mask); + } + } else if(ch == SIG_FMTOWNS_NOTIFY_RESET) { + out_debug_log("RESET FROM CPU!!!\n"); + reset_happened = true; + dma_is_vram = true; + nmi_vector_protect = false; + ankcg_enabled = false; + nmi_mask = false; + select_d0_dict = false; + select_d0_rom = true; + config_page00(); + set_wait_values(); + + if(d_cpu != NULL) { + d_cpu->set_address_mask(0xffffffff); + } + if(d_dmac != NULL) { + d_dmac->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, 0xffffffff, 0xffffffff); + } + } else if(ch == SIG_FMTOWNS_RAM_WAIT) { mem_wait_val = (int)data; - d_sysrom->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask); - d_dictionary->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask); - d_msdos->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask); - d_fonts->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask); - } else if(ch == SIG_FMTOWNS_SET_VRAMWAIT) { + set_wait_values(); + } else if(ch == SIG_FMTOWNS_ROM_WAIT) { +// mem_wait_val = (int)data; + set_wait_values(); + } else if(ch == SIG_FMTOWNS_VRAM_WAIT) { vram_wait_val = (int)data; - d_vram->write_signal(SIG_FMTOWNS_SET_MEMWAIT, data, mask); + set_wait_values(); } } @@ -452,36 +1039,69 @@ uint32_t TOWNS_MEMORY::read_signal(int ch) if(ch == SIG_FMTOWNS_MACHINE_ID) { uint16_t d = (machine_id & 0xfff8) | ((uint16_t)(cpu_id & 0x07)); return (uint32_t)d; - } else if(ch == SIG_FMTOWNS_SET_MEMWAIT) { + } else if(ch == SIG_FMTOWNS_RAM_WAIT) { return (uint32_t)mem_wait_val; - } else if(ch == SIG_FMTOWNS_SET_VRAMWAIT) { + } else if(ch == SIG_FMTOWNS_ROM_WAIT) { + return 6; // OK? + } else if(ch == SIG_FMTOWNS_VRAM_WAIT) { return (uint32_t)vram_wait_val; } return 0; } + +void TOWNS_MEMORY::set_intr_line(bool line, bool pending, uint32_t bit) +{ + if(d_cpu != NULL) { + d_cpu->set_intr_line(line, pending, bit); + } +} + // ToDo: DMA -#define STATE_VERSION 1 +#define STATE_VERSION 5 bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading) { if(!state_fio->StateCheckUint32(STATE_VERSION)) { return false; } + if(!state_fio->StateCheckInt32(this_device_id)) { return false; } - state_fio->StateValue(bankc0_vram); - state_fio->StateValue(ankcg_enabled); state_fio->StateValue(machine_id); state_fio->StateValue(cpu_id); + state_fio->StateValue(is_compatible); + + state_fio->StateValue(mem_wait_val); + state_fio->StateValue(vram_wait_val); + state_fio->StateValue(wait_register); + + state_fio->StateValue(dma_is_vram); + state_fio->StateValue(nmi_vector_protect); + state_fio->StateValue(software_reset); + state_fio->StateValue(poff_status); + state_fio->StateValue(reset_happened); + + state_fio->StateValue(extra_nmi_val); + state_fio->StateValue(extra_nmi_mask); + state_fio->StateValue(nmi_mask); + + state_fio->StateArray(ram_page0, sizeof(ram_page0), 1); + state_fio->StateArray(ram_pagec, sizeof(ram_pagec), 1); + state_fio->StateArray(ram_paged, sizeof(ram_paged), 1); + state_fio->StateArray(ram_pagee, sizeof(ram_pagee), 1); + state_fio->StateArray(ram_pagef, sizeof(ram_pagef), 1); - state_fio->StateValue(dma_addr_mask); - //state_fio->StateValue(dma_addr_reg); - //state_fio->StateValue(dma_wrap_reg); + state_fio->StateValue(select_d0_rom); + state_fio->StateValue(select_d0_dict); + state_fio->StateValue(ankcg_enabled); - state_fio->StateArray(ram_page0, sizeof(ram_page0), 1); - state_fio->StateArray(ram_pagef, sizeof(ram_pagef), 1); + state_fio->StateValue(vram_wait_val); + state_fio->StateValue(mem_wait_val); + state_fio->StateValue(vram_size); + state_fio->StateValue(cpu_clock_val); + if(loading) { uint32_t length_tmp = state_fio->FgetUint32_LE(); if(extra_ram != NULL) { @@ -489,37 +1109,31 @@ bool TOWNS_MEMORY::process_state(FILEIO* state_fio, bool loading) extra_ram = NULL; } length_tmp = length_tmp & 0x3ff00000; - extra_ram_size = length_tmp; + extram_size = length_tmp; if(length_tmp > 0) { extra_ram = (uint8_t*)malloc(length_tmp); } unset_memory_rw(0x00100000, 0x3fffffff); if(extra_ram == NULL) { - extra_ram_size = 0; + extram_size = 0; return false; } else { - state_fio->Fread(extra_ram, extra_ram_size, 1); - set_memory_rw(0x00100000, (extra_ram_size + 0x00100000) - 1, extra_ram); + state_fio->Fread(extra_ram, extram_size, 1); + set_memory_rw(0x00100000, (extram_size + 0x00100000) - 1, extra_ram); } - + set_wait_values(); + config_page00(); } else { + // At saving if(extra_ram == NULL) { state_fio->FputUint32_LE(0); } else { - state_fio->FputUint32_LE(extra_ram_size & 0x3ff00000); - state_fio->Fwrite(extra_ram, extra_ram_size, 1); + state_fio->FputUint32_LE(extram_size & 0x3ff00000); + state_fio->Fwrite(extra_ram, extram_size, 1); } } - - state_fio->StateValue(vram_wait_val); - state_fio->StateValue(mem_wait_val); - state_fio->StateValue(vram_size); // ToDo: Do save ROMs? - - if(loading) { - initialize_tables(); - } return true; } diff --git a/source/src/vm/fmtowns/towns_memory.h b/source/src/vm/fmtowns/towns_memory.h index 6a67d704e..8a644d8ab 100644 --- a/source/src/vm/fmtowns/towns_memory.h +++ b/source/src/vm/fmtowns/towns_memory.h @@ -10,24 +10,15 @@ #ifndef _TOWNS_MEMORY_H_ #define _TOWNS_MEMORY_H_ -//#include "../vm.h" -//#include "../../emu.h" -#include "../device.h" +#include "../vm.h" +#include "../../emu.h" +#include "device.h" +#include "../../common.h" #include "../memory.h" +#include "./towns_common.h" #define SIG_FMTOWNS_MACHINE_ID 1 - -class I80386; -// Bank size = 1GB / 1MB. -// Page 0 (0000:00000 - 0000:fffff) is another routine. -#define TOWNS_BANK_SIZE 1024 -// Page0 size is 1MB / 2KB. -#define TOWNS_BANK000_BANK_SIZE 512 - -// C000:00000 - C1f0:fffff is 32MB / 32KB -#define TOWNS_BANKC0x_BANK_SIZE 1024 -// C200:00000 - C230:fffff is 4MB / 2KB -#define TOWNS_BANKC2x_BANK_SIZE 2048 +#define SIG_MEMORY_EXTNMI 2 // MAP: // 00000000 - 000fffff : SYSTEM RAM PAGE 0 (Similar to FMR-50). @@ -58,87 +49,280 @@ enum { // Please set from config #define TOWNS_EXTRAM_PAGES 6 -class I386; class BEEP; namespace FMTOWNS { class TOWNS_VRAM; class TOWNS_SPRITE; class TOWNS_ROM_CARD; - class ADPCM; } namespace FMTOWNS { -class TOWNS_MEMORY : public DEVICE +class TOWNS_MEMORY : public MEMORY { protected: - I386 *d_cpu; - - TOWNS_VRAM* d_vram; - TOWNS_SPRITE* d_sprite; // 0x81000000 - 0x8101ffff ? - TOWNS_ROM_CARD* d_romcard[2]; // 0xc0000000 - 0xc0ffffff / 0xc1000000 - 0xc1ffffff - FMTOWNS::ADPCM* d_pcm; // 0xc2200000 - 0xc2200fff + DEVICE* d_vram; + DEVICE* d_sprite; // 0x81000000 - 0x8101ffff ? + DEVICE* d_romcard[2]; // 0xc0000000 - 0xc0ffffff / 0xc1000000 - 0xc1ffffff + DEVICE* d_pcm; // 0xc2200000 - 0xc2200fff DEVICE* d_beep; - + DEVICE* d_dmac; + DEVICE* d_crtc; + DEVICE* d_planevram; + I386* d_cpu; + DEVICE* d_dictionary; DEVICE* d_sysrom; DEVICE* d_msdos; DEVICE* d_serialrom; + DEVICE* d_font; + DEVICE* d_font_20pix; + + DEVICE* d_iccard[2]; + + outputs_t outputs_ram_wait; + outputs_t outputs_rom_wait; bool bankc0_vram; bool ankcg_enabled; - + bool select_d0_rom; + bool select_d0_dict; + uint16_t machine_id; uint8_t cpu_id; + bool is_compatible; + bool dma_is_vram; - // ToDo: around DMA - uint32_t dma_addr_mask; - //uint8_t dma_addr_reg; - //uint8_t dma_wrap_reg; - // RAM uint8_t ram_page0[0xc0000]; // 0x00000000 - 0x000bffff : RAM - uint8_t ram_pagef[0x08000]; // 0x000f0000 - 0x000f7fff : RAM + uint8_t ram_pagec[0x10000]; // 0x000c0000 - 0x000cffff : URA? RAM + uint8_t ram_paged[0x10000]; // 0x000d0000 - 0x000dffff : RAM + uint8_t ram_pagee[0x10000]; // 0x000e0000 - 0x000effff : RAM + uint8_t ram_pagef[0x10000]; // 0x000f0000 - 0x000f8fff : RAM uint8_t *extra_ram; // 0x00100000 - (0x3fffffff) : Size is defined by extram_size; - uint32_t extra_ram_size; - + uint32_t extram_size; + uint32_t cpu_clock_val; uint32_t vram_wait_val; uint32_t mem_wait_val; - // ROM - uint8_t rom_font1[0x40000]; // 0xc2100000 - 0xc23f0000 -#if 0 - uint8_t rom_font20[0x80000]; -#endif + uint8_t wait_register; + + bool extra_nmi_mask; + bool extra_nmi_val; + bool nmi_mask; + bool software_reset; + bool nmi_vector_protect; + bool poff_status; + bool reset_happened; + // misc uint32_t vram_size; // Normally 512KB. + bool initialized; - uint8_t* read_bank_adrs_cx[0x100000]; // Per 4KB. - uint8_t* write_bank_adrs_cx[0x100000]; // Per 4KB. - DEVICE* device_bank_adrs_cx[0x100000]; // Per 4KB. - uint32_t type_bank_adrs_cx[0x100000]; // Per 4KB. + virtual void set_wait_values(); + virtual void config_page00(); - void write_data_base(uint32_t addr, uint32_t data, int* wait, int wordsize); - uint32_t read_data_base(uint32_t addr, int* wait, int wordsize); - bool check_bank(uint32_t addr, uint32_t *mask, uint32_t *offset, void** readfn, void** writefn, void** readp, void** writep); - virtual void initialize_tables(void); + inline uint32_t __FASTCALL read_primitive_byte(uint32_t addr) + { + int bank = (addr & addr_mask) >> addr_shift; + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io8(addr); + } else { + return rd_table[bank].memory[addr & bank_mask]; + } + } - virtual uint32_t read_mmio(uint32_t addr, int *wait, bool *hit); - virtual void write_mmio(uint32_t addr, uint32_t data, int *wait, bool *hit); + inline uint32_t __FASTCALL read_primitive_word(uint32_t addr) + { + int bank = (addr & addr_mask) >> addr_shift; + pair32_t n; + uint32_t naddr = addr & bank_mask; + n.d = 0; + if((addr & bank_mask) == bank_mask) { + if(rd_table[bank].device != NULL) { + n.b.l = rd_table[bank].device->read_memory_mapped_io8(addr); + } else { + n.b.l = rd_table[bank].memory[naddr + 0]; + } + n.b.h = read_primitive_byte(addr + 1); + } else { + if(rd_table[bank].device != NULL) { + n.w.l = rd_table[bank].device->read_memory_mapped_io16(addr); + } else { + n.b.l = rd_table[bank].memory[naddr + 0]; + n.b.h = rd_table[bank].memory[naddr + 1]; + } + } + return n.d; + } + inline uint32_t __FASTCALL read_primitive_dword(uint32_t addr) + { + int bank = (addr & addr_mask) >> addr_shift; + pair32_t n; + uint32_t naddr = addr & bank_mask; + n.d = 0; + if((addr & bank_mask) > (bank_mask - 3)) { + switch(addr & 3) { + case 0: + n.w.l = read_primitive_word(addr + 0); + n.w.h = read_primitive_word(addr + 2); + break; + case 1: + n.b.l = read_primitive_byte(addr + 0); + n.b.h = read_primitive_byte(addr + 1); + n.b.h2 = read_primitive_byte(addr + 2); + n.b.h3 = read_primitive_byte(addr + 3); + break; + case 2: + n.w.l = read_primitive_word(addr + 0); + n.w.h = read_primitive_word(addr + 2); + break; + case 3: + n.b.l = read_primitive_byte(addr + 0); + n.b.h = read_primitive_byte(addr + 1); + n.b.h2 = read_primitive_byte(addr + 2); + n.b.h3 = read_primitive_byte(addr + 3); + break; + } + return n.d; + } else { // Inside of boundary + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io32(addr); + } else { + n.b.l = rd_table[bank].memory[naddr + 0]; + n.b.h = rd_table[bank].memory[naddr + 1]; + n.b.h2 = rd_table[bank].memory[naddr + 2]; + n.b.h3 = rd_table[bank].memory[naddr + 3]; + } + return n.d; + } + } + inline void __FASTCALL write_primitive_byte(uint32_t addr, uint32_t data) + { + int bank = (addr & addr_mask) >> addr_shift; +// if(addr == 0xd000) { +// out_debug_log(_T("WRITE %02X to D000 / DEV=%08X"), data, wr_table[bank].device); +// } + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io8(addr, data); + } else { + wr_table[bank].memory[addr & bank_mask] = data; + } + } + + inline void __FASTCALL write_primitive_word(uint32_t addr, uint32_t data) + { + int bank = (addr & addr_mask) >> addr_shift; + + if(wr_table[bank].device != NULL) { + if((addr & bank_mask) == bank_mask) { + pair32_t n; + n.d = data; + wr_table[bank].device->write_memory_mapped_io8(addr + 0, n.b.l); + write_primitive_byte(addr + 1, n.b.h); + } else { + wr_table[bank].device->write_memory_mapped_io16(addr, data); + } + } else { + pair32_t n; + uint32_t naddr = addr & bank_mask; + n.d = data; + if((addr & bank_mask) == bank_mask) { + wr_table[bank].memory[naddr + 0] = n.b.l; + write_primitive_byte(addr + 1, n.b.h); + } else { + wr_table[bank].memory[naddr + 0] = n.b.l; + wr_table[bank].memory[naddr + 1] = n.b.h; + } + } + } + inline void __FASTCALL write_primitive_dword(uint32_t addr, uint32_t data) + { + int bank = (addr & addr_mask) >> addr_shift; + uint32_t naddr = addr & bank_mask; + pair32_t n; + n.d = data; + if((addr & bank_mask) <= (bank_mask - 3)) { + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io32(addr, data); + } else { + wr_table[bank].memory[naddr + 0] = n.b.l; + wr_table[bank].memory[naddr + 1] = n.b.h; + wr_table[bank].memory[naddr + 2] = n.b.h2; + wr_table[bank].memory[naddr + 3] = n.b.h3; + } + } else { + // BEYOND BOUNDARY + switch(addr & 3) { + case 0: + write_primitive_word(addr + 0, n.w.l); + write_primitive_word(addr + 2, n.w.h); + break; + case 1: + { + write_primitive_byte(addr + 0, n.b.l); + pair16_t nn; + nn.b.l = n.b.h; + nn.b.h = n.b.h2; + write_primitive_word(addr + 1, nn.w); + write_primitive_byte(addr + 3, n.b.h3); + } + break; + case 2: + write_primitive_word(addr + 0, n.w.l); + write_primitive_word(addr + 2, n.w.h); + break; + case 3: + { + write_primitive_byte(addr + 0, n.b.l); + pair16_t nn; + nn.b.l = n.b.h; + nn.b.h = n.b.h2; + write_primitive_word(addr + 1, nn.w); + write_primitive_word(addr + 3, n.b.h3); + } + break; + } + } + } public: - TOWNS_MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu) { + TOWNS_MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MEMORY(parent_vm, parent_emu) { set_device_name(_T("FMTOWNS_MEMORY")); + addr_max = 0x100000000; // 4GiB + bank_size = 1024; // 1024 + addr_shift = 10; + bank_size_was_set = false; + addr_max_was_set = false; + + _MEMORY_DISABLE_DMA_MMIO = false; + + extram_size = 0x00200000; // Basically 2MB + d_cpu = NULL; + d_vram = NULL; - d_pcm = NULL; d_sprite = NULL; d_romcard[0] = d_romcard[1] = NULL; + d_pcm = NULL; d_beep = NULL; - d_sysrom = NULL; + d_dmac = NULL; + d_crtc = NULL; + d_planevram = NULL; + d_iccard[0] = NULL; + d_iccard[1] = NULL; + d_dictionary = NULL; + d_sysrom = NULL; d_msdos = NULL; + d_serialrom = NULL; + d_font = NULL; + d_font_20pix = NULL; + initialized = false; + + initialize_output_signals(&outputs_ram_wait); + initialize_output_signals(&outputs_rom_wait); // Note: machine id must set before initialize() from set_context_machine_id() by VM::VM(). // machine_id = 0x0100; // FM-Towns 1,2 // machine_id = 0x0200 // FM-Towns 1F/2F/1H/2H @@ -167,45 +351,100 @@ class TOWNS_MEMORY : public DEVICE // common functions void initialize(); + void release(); void reset(); + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + virtual uint32_t __FASTCALL read_io16(uint32_t addr); + + uint32_t __FASTCALL read_data8(uint32_t addr); + uint32_t __FASTCALL read_data16(uint32_t addr); + uint32_t __FASTCALL read_data32(uint32_t addr); + void __FASTCALL write_data8(uint32_t addr, uint32_t data); + void __FASTCALL write_data16(uint32_t addr, uint32_t data); + void __FASTCALL write_data32(uint32_t addr, uint32_t data); + + uint32_t __FASTCALL read_data8w(uint32_t addr, int* wait); + uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait); + uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait); + void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait); + void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait); + void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait); + + uint32_t __FASTCALL read_dma_data8w(uint32_t addr, int* wait); + uint32_t __FASTCALL read_dma_data16w(uint32_t addr, int* wait); + uint32_t __FASTCALL read_dma_data32w(uint32_t addr, int* wait); + void __FASTCALL write_dma_data8w(uint32_t addr, uint32_t data, int* wait); + void __FASTCALL write_dma_data16w(uint32_t addr, uint32_t data, int* wait); + void __FASTCALL write_dma_data32w(uint32_t addr, uint32_t data, int* wait); + + uint32_t __FASTCALL read_dma_data8(uint32_t addr); + uint32_t __FASTCALL read_dma_data16(uint32_t addr); + uint32_t __FASTCALL read_dma_data32(uint32_t addr); + void __FASTCALL write_dma_data8(uint32_t addr, uint32_t data); + void __FASTCALL write_dma_data16(uint32_t addr, uint32_t data); + void __FASTCALL write_dma_data32(uint32_t addr, uint32_t data); + + virtual void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); +// virtual void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data); +// virtual void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); +// virtual uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr); +// virtual uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr); + - void write_data8(uint32_t addr, uint32_t data); - uint32_t read_data8(uint32_t addr); - // Using [read|write]_data[16|32] to be faster memory access. - void write_data16(uint32_t addr, uint32_t data); - uint32_t read_data16(uint32_t addr); - void write_data32(uint32_t addr, uint32_t data); - uint32_t read_data32(uint32_t addr); - // With Wait - void write_data8w(uint32_t addr, uint32_t data, int* wait); - uint32_t write_data8w(uint32_t addr, int* wait); - void write_data16w(uint32_t addr, uint32_t data, int* wait); - uint32_t write_data16w(uint32_t addr, int* wait); - void write_data32w(uint32_t addr, uint32_t data, int* wait); - uint32_t write_data32w(uint32_t addr, int* wait); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_signal(int ch); - void write_dma_data8(uint32_t addr, uint32_t data); - uint32_t read_dma_data8(uint32_t addr); - // Using [read|write]_dma_data16 for DMAC 16bit mode (SCSI/CDROM?). - void write_dma_data16(uint32_t addr, uint32_t data); - uint32_t read_dma_data16(uint32_t addr); + //void event_frame(); + virtual void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); - virtual void write_io8(uint32_t addr, uint32_t data); - virtual uint32_t read_io8(uint32_t addr); - void write_signal(int id, uint32_t data, uint32_t mask); - void event_frame(); bool process_state(FILEIO* state_fio, bool loading); // unique functions + void set_extra_ram_size(uint32_t megabytes) + { + uint32_t limit = 5; + uint32_t minimum = 2; + switch(machine_id & 0xff00) { + case 0x0000: // ??? + case 0x0100: // Towns Model 1/2 + minimum = 1; + break; + case 0x0200: // TOWNS 2F/2H + case 0x0400: // TOWNS 10F/10H/20F/20H + limit = 8; // 2MB + 2MB x 3 + break; + case 0x0300: // TOWNS2 UX + case 0x0600: // TOWNS2 UG + limit = 9; // 2MB + 4MB x 2? - 1MB + break; + case 0x0500: // TOWNS2 CX + case 0x0800: // TOWNS2 HG + limit = 15; // 8MB x 2 - 1MB? + break; + case 0x0700: // TOWNS2 HR + case 0x0900: // TOWNS2 UR + case 0x0B00: // TOWNS2 MA + case 0x0C00: // TOWNS2 MX + case 0x0D00: // TOWNS2 ME + case 0x0F00: // TOWNS2 MF/Fresh + limit = 31; // 16MB x 2 - 1MB? + break; + } + if(megabytes > limit) megabytes = limit; + if(megabytes < minimum) megabytes = minimum; + extram_size = megabytes << 20; + } void set_context_cpu(I386* device) { d_cpu = device; } - void set_machine_id(uint8_t id) + void set_context_dmac(DEVICE* device) { - machine_id = id; + d_dmac = device; } - void set_context_vram(TOWNS_VRAM* device) + void set_context_vram(DEVICE* device) { d_vram = device; } @@ -213,6 +452,14 @@ class TOWNS_MEMORY : public DEVICE { d_sysrom = device; } + void set_context_font_rom(DEVICE* device) + { + d_font = device; + } + void set_context_font_20pix_rom(DEVICE* device) + { + d_font_20pix = device; + } void set_context_dictionary(DEVICE* device) { d_dictionary = device; @@ -225,15 +472,19 @@ class TOWNS_MEMORY : public DEVICE { d_beep = device; } - void set_context_sprite(TOWNS_SPRITE* device) + void set_context_sprite(DEVICE* device) { d_sprite = device; } - void set_context_romcard(TOWNS_ROM_CARD* device, int num) + void set_context_crtc(DEVICE* device) + { + d_crtc = device; + } + void set_context_romcard(DEVICE* device, int num) { d_romcard[num & 1] = device; } - void set_context_pcm(FMTOWNS::ADPCM* device) + void set_context_pcm(DEVICE* device) { d_pcm = device; } @@ -241,7 +492,17 @@ class TOWNS_MEMORY : public DEVICE { d_serialrom = device; } - void set_context_machine_id(uint16_t val) + void set_context_planevram(DEVICE *dev) + { + d_planevram = dev; + } + void set_context_iccard(DEVICE* device, int num) + { + if((num >= 0) && (num < 2)) { + d_iccard[num] = device; + } + } + void set_machine_id(uint16_t val) { machine_id = val & 0xfff8; } diff --git a/source/src/vm/fmtowns/towns_planevram.cpp b/source/src/vm/fmtowns/towns_planevram.cpp new file mode 100644 index 000000000..387ea6201 --- /dev/null +++ b/source/src/vm/fmtowns/towns_planevram.cpp @@ -0,0 +1,217 @@ + +#include "./towns_planevram.h" +#include "./towns_vram.h" + +#include "./towns_crtc.h" +#include "./towns_sprite.h" + +#include "../../fileio.h" + +namespace FMTOWNS { + +void PLANEVRAM::initialize() +{ + DEVICE::initialize(); +} + +void PLANEVRAM::reset() +{ + mix_reg = 0xff; + r50_readplane = 0x0; // OK? + r50_ramsel = 0x0; // OK? + r50_gvramsel = 0x0; // OK? +} + +void PLANEVRAM::write_io8(uint32_t addr, uint32_t data) +{ + switch(addr) { + case 0xff80: + mix_reg = data & 0x28; + break; + case 0xff81: +// out_debug_log(_T("0xCFF81=%02X"), data & 0xff); + r50_readplane = (data & 0xc0) >> 6; + r50_ramsel = data & 0x0f; + break; + case 0xff82: + if(d_crtc != NULL) { + d_crtc->write_signal(SIG_TOWNS_CRTC_MMIO_CFF82H, data, 0xffffffff); +// out_debug_log(_T("WRITE CFF82h <- %02X"), data); + } + break; + case 0xff83: +// out_debug_log(_T("0xCFF83=%02X"), data & 0xff); + r50_gvramsel = (data & 0x10) >> 4; + break; + case 0xff86: + break; + case 0xffa0: + break; + default: + if(d_sprite != NULL) { + d_sprite->write_data8(addr & 0x7fff, data); + } + break; + } +} + +uint32_t PLANEVRAM::read_io8(uint32_t addr) +{ + switch(addr) { + case 0xff80: + return mix_reg; + break; + case 0xff81: + return ((r50_readplane << 6) | r50_ramsel); + break; + case 0xff82: + return d_crtc->read_signal(SIG_TOWNS_CRTC_MMIO_CFF82H); + break; + case 0xff83: + return (r50_gvramsel << 4); + break; + case 0xff84: + return 0x7f; // Reserve.FIRQ + break; + case 0xff86: + { + uint8_t d; + d = (d_crtc->read_signal(SIG_TOWNS_CRTC_VSYNC) != 0) ? 0x04 : 0; + d = d | ((d_crtc->read_signal(SIG_TOWNS_CRTC_HSYNC) != 0) ? 0x80 : 0); + d = d | 0x10; + return d; + } + break; + case 0xffa0: + { + uint8_t val; + val = 0xff; + val = val & 0x7f; + return val; + } + break; + default: + if(d_sprite != NULL) { + return d_sprite->read_data8(addr & 0x7fff); + } + break; + } + return 0xff; +} + +uint32_t PLANEVRAM::read_memory_mapped_io8(uint32_t addr) +{ + // Plane Access + uint32_t x_addr = 0x00000; + // ToDo: Writing plane. +// if(r50_gvramsel != 0) x_addr = 0x20000; //? + if(r50_gvramsel != 0) x_addr = 0x20000; //? + addr = (addr & 0x7fff) << 2; + if(d_vram == NULL) return 0xff; + + uint8_t *p = d_vram->get_vram_address(x_addr + addr); + if(p == NULL) return 0xff; +// p = &(p[x_addr + addr]); + + // 8bit -> 32bit + uint8_t tmp = 0; + uint8_t val = 0; + uint8_t nmask[4] = {0x11, 0x22, 0x44, 0x88}; + uint8_t hmask = nmask[r50_readplane & 3] & 0xf0; + uint8_t lmask = nmask[r50_readplane & 3] & 0x0f; + uint8_t hval = 0x80; + uint8_t lval = 0x40; +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 4; i++) { + val |= ((p[i] & hmask) != 0) ? hval : 0x00; + val |= ((p[i] & lmask) != 0) ? lval : 0x00; + hval >>= 2; + lval >>= 2; + } + return val; +} + + +void PLANEVRAM::write_memory_mapped_io8(uint32_t addr, uint32_t data) +{ + // Plane Access + uint32_t x_addr = 0x00000; + + // ToDo: Writing plane. +// if(r50_gvramsel != 0) x_addr = 0x20000; //? + if(r50_gvramsel != 0) x_addr = 0x20000; //? + addr = (addr & 0x7fff) << 2; + + if(d_vram == NULL) return; + uint8_t *p = d_vram->get_vram_address(x_addr + addr); + if(p == NULL) return; + + // 8bit -> 32bit + uint32_t *pp = (uint32_t *)p; + uint32_t tmp = 0; + uint32_t tmp_d = data & 0xff; + uint8_t ntmp = r50_ramsel & 0x0f; +#ifdef __LITTLE_ENDIAN__ + uint32_t tmp_m1 = 0xf0000000/* & write_plane_mask*/; + uint32_t tmp_m2 = 0x0f000000/* & write_plane_mask*/; + tmp_m1 &= (((uint32_t)ntmp) << 28); + tmp_m2 &= (((uint32_t)ntmp) << 24); + +#else + uint32_t tmp_m1 = 0x0000000f/* & write_plane_mask*/; + uint32_t tmp_m2 = 0x000000f0/* & write_plane_mask*/; + tmp_m1 &= (((uint32_t)ntmp) << 0); + tmp_m2 &= (((uint32_t)ntmp) << 4); +#endif + uint32_t tmp_r1; + uint32_t tmp_r2; + uint32_t mask = 0; + +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 4; i++) { +#ifdef __LITTLE_ENDIAN__ + tmp = tmp >> 8; + mask = mask >> 8; +#else + tmp = tmp << 8; + mask = mask << 8; +#endif + tmp = tmp | (((tmp_d & 0x80) != 0) ? tmp_m2 : 0x00); + tmp = tmp | (((tmp_d & 0x40) != 0) ? tmp_m1 : 0x00); + mask = mask | (tmp_m1 | tmp_m2); + tmp_d <<= 2; + } +// uint32_t mask2 = packed_pixel_mask_reg.d; +// tmp &= mask2; +// mask = mask & mask2; + tmp_r1 = *pp; + tmp_r2 = tmp_r1; + tmp_r1 = tmp_r1 & ~mask; + tmp_r1 = tmp | tmp_r1; +// if(tmp_r2 != tmp_r1) { + *pp = tmp_r1; +// d_vram->make_dirty_vram(x_addr + addr, 4); +// } +} + +#define STATE_VERSION 1 + +bool PLANEVRAM::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + + state_fio->StateValue(mix_reg); + state_fio->StateValue(r50_readplane); + state_fio->StateValue(r50_ramsel); + state_fio->StateValue(r50_gvramsel); + + return true; +} + +} diff --git a/source/src/vm/fmtowns/towns_planevram.h b/source/src/vm/fmtowns/towns_planevram.h new file mode 100644 index 000000000..4bea95846 --- /dev/null +++ b/source/src/vm/fmtowns/towns_planevram.h @@ -0,0 +1,56 @@ +#pragma once + +#include "device.h" +#include "../../common.h" +#include "towns_common.h" + +namespace FMTOWNS { +class TOWNS_VRAM; + +class PLANEVRAM : public DEVICE +{ +protected: + DEVICE* d_crtc; + DEVICE* d_sprite; + TOWNS_VRAM* d_vram; + + uint8_t mix_reg; // MMIO 000CH:FF80H + uint8_t r50_readplane; // MMIO 000CH:FF81H : BIT 7 and 6. + uint8_t r50_ramsel; // MMIO 000CH:FF81H : BIT 3 to 0. + uint8_t r50_gvramsel; // MMIO 000CH:FF83H : bit4 (and 3). + +public: + PLANEVRAM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE*parent_emu) : DEVICE(parent_vm, parent_emu) + { + d_crtc = NULL; + d_sprite = NULL; + d_vram = NULL; + } + + void initialize(); + void reset(); + + virtual uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + virtual void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + + virtual bool process_state(FILEIO* state_fio, bool loading); + + // unique functions + void set_context_crtc(DEVICE* dev) + { + d_crtc = dev; + } + void set_context_sprite(DEVICE* dev) + { + d_sprite = dev; + } + void set_context_vram(TOWNS_VRAM* dev) + { + d_vram = dev; + } + +}; +} diff --git a/source/src/vm/fmtowns/towns_scsi_host.cpp b/source/src/vm/fmtowns/towns_scsi_host.cpp new file mode 100644 index 000000000..12b64e7b4 --- /dev/null +++ b/source/src/vm/fmtowns/towns_scsi_host.cpp @@ -0,0 +1,151 @@ + +#include "../../fifo.h" +#include "./towns_scsi_host.h" + +namespace FMTOWNS +{ +void TOWNS_SCSI_HOST::initialize() +{ + SCSI_HOST::initialize(); +} + +void TOWNS_SCSI_HOST::release() +{ +} + +void TOWNS_SCSI_HOST::reset() +{ + SCSI_HOST::reset(); + selected = false; + + write_signals(&outputs_sel, 0); + write_signals(&outputs_req, 0); + write_signals(&outputs_atn, 0); + write_signals(&outputs_io, 0); + write_signals(&outputs_cd, 0); + write_signals(&outputs_drq, 0); + write_signals(&outputs_bsy, 0); + write_signals(&outputs_msg, 0); + write_signals(&outputs_rst, 0); +// write_signals(&outputs_dat, 0); + + write_signals(&outputs_irq, 0); +} + +void TOWNS_SCSI_HOST::write_dma_io16(uint32_t addr, uint32_t data) +{ + SCSI_HOST::write_dma_io8(addr, data); +} + +void TOWNS_SCSI_HOST::write_dma_io8(uint32_t addr, uint32_t data) +{ + SCSI_HOST::write_dma_io8(addr, data); +} + +uint32_t TOWNS_SCSI_HOST::read_dma_io16(uint32_t addr) +{ + uint8_t val = SCSI_HOST::read_dma_io8(addr); +// out_debug_log(_T("DMA READ8 DATA: %02X"), val); + return val; +} + +uint32_t TOWNS_SCSI_HOST::read_dma_io8(uint32_t addr) +{ +// out_debug_log(_T("READ DMA8")); + return SCSI_HOST::read_dma_io8(addr); +} + +uint32_t TOWNS_SCSI_HOST::read_signal(int ch) +{ + return SCSI_HOST::read_signal(ch); +} + +void TOWNS_SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask) +{ +#if 0 + switch(id) { + case SIG_SCSI_REQ: + { + uint32_t prev_status = req_status; + prev_status &= mask; + req_status &= ~mask; + req_status |= (data & mask); + if((prev_status == 0) && ((data & mask) != 0)) { + // L -> H +// if(bsy_status) { + if(!cd_status && !msg_status) { + // data phase + set_drq(true); +// set_irq(false); + access = true; + } else if(cd_status) { + // command/status/message phase + set_irq(true); + } +// } + } else if((prev_status != 0) && ((data & mask) == 0)) { + // H -> L + if(!cd_status && !msg_status) { + set_drq(false); // Data phase + } else if(cd_status) { + // command/status/message phase + set_irq(false); +// set_drq(false); + } else { + // set_drq(false); // Data phase + } + #ifdef SCSI_HOST_AUTO_ACK + this->write_signal(SIG_SCSI_ACK, 0, 1); + #endif + } + if(prev_status != req_status) { + write_signals(&outputs_req, (req_status != 0) ? 0xffffffff : 0); + } + } + return; + break; +#if 0 + case SIG_SCSI_SEL: + { + #ifdef _SCSI_DEBUG_LOG + this->out_debug_log(_T("[SCSI_HOST] SEL = %d\n"), (data & mask) ? 1 : 0); + #endif + bool prev_selected = selected; +// if(prev_selected = !(data & mask)) { + selected = ((data & mask) != 0); + write_signals(&outputs_sel, (selected) ? 0xffffffff : 0); + if(selected) { + data_reg = 0x08; + } +// } + } + return; + break; +#endif + } +#endif + SCSI_HOST::write_signal(id, data, mask); +} + +void TOWNS_SCSI_HOST::event_callback(int event_id, int err) +{ + SCSI_HOST::event_callback(event_id, err); +} + +#define STATE_VERSION 1 + +bool TOWNS_SCSI_HOST::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + if(!(SCSI_HOST::process_state(state_fio, loading))) { + return false; + } + state_fio->StateValue(selected); + return true; +} +} diff --git a/source/src/vm/fmtowns/towns_scsi_host.h b/source/src/vm/fmtowns/towns_scsi_host.h new file mode 100644 index 000000000..caea8129c --- /dev/null +++ b/source/src/vm/fmtowns/towns_scsi_host.h @@ -0,0 +1,51 @@ +/* + Skelton for retropc emulator + + Author : Takeda.Toshiya + Date : 2016.03.01- + + [ SCSI base initiator ] +*/ + +#ifndef _TOWNS_SCSI_HOST_H_ +#define _TOWNS_SCSI_HOST_H_ + +#include "../scsi_host.h" + +class FIFO; +namespace FMTOWNS { +class TOWNS_SCSI_HOST : public SCSI_HOST +{ +protected: + FIFO *read_queue; + FIFO *write_queue; + int event_read_queue; + int event_write_queue; + + bool selected; +public: + TOWNS_SCSI_HOST(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : SCSI_HOST(parent_vm, parent_emu) + { + set_device_name(_T("FM-Towns SCSI HOST")); + read_queue = NULL; + write_queue = NULL; + } + ~TOWNS_SCSI_HOST() {} + + // common functions + virtual void reset(); + virtual void initialize(); + virtual void release(); + virtual void __FASTCALL event_callback(int event_id, int err); + + virtual void __FASTCALL write_dma_io16(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_io16(uint32_t addr); + virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr); + + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + virtual uint32_t __FASTCALL read_signal(int ch); + virtual bool process_state(FILEIO* state_fio, bool loading); +}; +} +#endif diff --git a/source/src/vm/fmtowns/towns_sprite.cpp b/source/src/vm/fmtowns/towns_sprite.cpp index 8892b4a0f..c55b2d250 100644 --- a/source/src/vm/fmtowns/towns_sprite.cpp +++ b/source/src/vm/fmtowns/towns_sprite.cpp @@ -8,46 +8,36 @@ */ #include "../../common.h" +#include "./towns_vram.h" #include "./towns_sprite.h" +#include "./towns_crtc.h" + +#define EVENT_FALL_DOWN 1 +#define EVENT_BUSY_OFF 2 +#define EVENT_RENDER 3 namespace FMTOWNS { - + void TOWNS_SPRITE::initialize(void) { - memset(index_ram, 0x00, sizeof(index_ram)); memset(pattern_ram, 0x00, sizeof(pattern_ram)); - memset(color_ram, 0x00, sizeof(color_ram)); - - for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) { - memset(&(cache_pixels[i][0]) , 0x00, sizeof(uint16_t) * 16 * 16); - memset(&(cache_masks[i][0]) , 0x00, sizeof(uint16_t) * 16 * 16); - memset(&(cache_index[i]), 0x00, sizeof(sprite_cache_t)); - cache_index[i].is_use = false; - cache_index[i].pixels = &(cache_pixels[i][0]); - cache_index[i].masks = &(cache_masks[i][0]); - } - last_put_cache_num = 0; reg_ctrl = 0x0000; // REG#00, #01 reg_voffset = 0x0000; // REG#02, #03 reg_hoffset = 0x0000; // REG#04, #05 + reg_index = 0x0000; disp_page1 = false; + draw_page1 = false; disp_page0 = false; reg_spen = false; reg_addr = 0; memset(reg_data, 0x00, sizeof(reg_data)); - for(int i = 0; i < (sizeof(pattern_cached) / sizeof(bool)); i++) { - pattern_cached[i] = false; - } - for(int i = 0; i < 256; i++) { - color_cached[i] = false; - } - use_cache = false; // ToDo: Enable cache. - render_num = 0; - render_mod = 0; - render_lines = 0; - split_rendering = false; - vram_buffer = NULL; - mask_buffer = NULL; + + max_sprite_per_frame = 224; + event_busy = -1; + page_changed = true; + + register_frame_event(this); + register_vline_event(this); } void TOWNS_SPRITE::reset() @@ -56,364 +46,738 @@ void TOWNS_SPRITE::reset() reg_ctrl = 0x0000; // REG#00, #01 reg_voffset = 0x0000; // REG#02, #03 reg_hoffset = 0x0000; // REG#04, #05 + reg_index = 0x0000; disp_page1 = false; + draw_page1 = false; disp_page0 = false; reg_spen = false; reg_addr = 0; - render_num = 0; - render_mod = 0; - render_lines = 0; - memset(reg_data, 0x00, sizeof(reg_data)); // OK? - // ToDo: Is these right? - write_page = 1; - display_page = 0; - // Is clear cache? - // Is clear buffers? -} -void TOWNS_SPRITE::clear_cache(int num) -{ - if(num >= TOWNS_SPRITE_CACHE_NUM) return; - if(num < 0) return; - memset(&(cache_index[num]), 0x00, sizeof(sprite_cache_t)); - memset(&(cache_pixels[num][0]) , 0x00, sizeof(uint16_t) * 16 * 16); - memset(&(cache_masks[num][0]) , 0x00, sizeof(uint16_t) * 16 * 16); - cache_index[num].is_use = false; - cache_index[num].pixels = &(cache_pixels[num][0]); - cache_index[num].masks = &(cache_masks[num][0]); -} + render_num = 1024; -void TOWNS_SPRITE::set_sprite_attribute(int table_num, uint16_t num_attr) -{ - if((table_num < 0) || (table_num > 1023)) return; - uint16_t num = num_attr & 0x3ff; - uint8_t rotate_type = (uint8_t)((num_attr & 0x7000) >> 12); - bool halfx = ((num_attr & 0x0400) != 0); - bool halfy = ((num_attr & 0x0800) != 0); - bool enable_offset = ((num_attr & 0x8000) != 0); - - sprite_table[table_num].num = num; - sprite_table[table_num].rotate_type = rotate_type; - sprite_table[table_num].is_halfx = halfx; - sprite_table[table_num].is_halfy = halfy; - sprite_table[table_num].offset = enable_offset; - sprite_table[table_num].attribute = num_attr & 0x7fff; -} + sprite_enabled = false; -void TOWNS_SPRITE::set_sprite_color(int table_num, uint16_t color_table_num) -{ - if((table_num < 0) || (table_num > 1023)) return; - sprite_table[table_num].color = color_table_num & 0x0fff; - sprite_table[table_num].is_32768 = ((color_table_num & 0x8000) == 0); - sprite_table[table_num].is_impose = ((color_table_num & 0x4000) != 0); - sprite_table[table_num].is_disp = ((color_table_num & 0x2000) != 0); -} + max_sprite_per_frame = 224; + tvram_enabled = false; + tvram_enabled_bak = false; -void TOWNS_SPRITE::build_sprite_table(void) -{ - uint16_t* p = index_ram; - for(int i = 0; i < 1024; i++) { - set_sprite_attribute(i, p[3]); - set_sprite_color(i, p[3]); - p = p + 4; - } -} + sprite_busy = false; + page_changed = true; -bool TOWNS_SPRITE::check_cache(int num, sprite_cache_t** p) -{ - sprite_cache_t* q; - sprite_table_t* t; - if(p != NULL) *p = NULL; - - t = &(sprite_table[num]); - if(use_cache) { - for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) { - q = &(cache_index[i]); - if(!(q->is_use)) continue; - if(q->attribute == t->attribute) { - if(q->is_32768 == t->is_32768) { - if((q->is_halfy == t->is_halfy) && (q->is_halfx == t->is_halfx)) { - if(p != NULL) *p = q; - return true; - } - } - } - } + memset(reg_data, 0x00, sizeof(reg_data)); // OK? + + if(event_busy > -1) { + cancel_event(this, event_busy); + event_busy = -1; } - return false; + +// ankcg_enabled = false; } - -void TOWNS_SPRITE::render_sprite(int num, uint16* dst_pixel, uint16_t* dst_mask, int x, int y) + // Still don't use cache. +void TOWNS_SPRITE::render_sprite(int num, int x, int y, uint16_t attr, uint16_t color) { - uint16_t sprite_limit = reg_index & 0x3ff; - if(sprite_limit == 0) sprite_limit = 1024; - if(num < 0) return; - if(num >= sprite_limit) return; - if(num >= 1024) return; - if(stride <= 0) return; - if(stride > 512) return; - if(!(sprite_table[num].is_disp)) return; - - sprite_cache_t *cacheptr; - bool c_stat = false; - c_stat = check_cache(num, &cacheptr); - if((c_stat) && (cacheptr != NULL)) { - if((cacheptr->pixels != NULL) && (cacheptr->masks != NULL)) { - render_zoomed_pixels(x, y, cacheptr->pixels, cacheptr->masks, cacheptr->is_halfx, cacheptr->is_halfy, dst_pixel, dst_mask); - return; - } - } - // Cache Not hit - // ToDo: Implement Link counter. - int target_num = -1; - for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) { - if(!(cache_index[i].is_use)) { - target_num = i; - break; - } - } - if((target_num < 0) || (target_num >= TOWNS_SPRITE_CACHE_NUM)) { - // Force erace a cache. - target_num = (last_put_cache_num + 1) % TOWNS_SPRITE_CACHE_NUM; - } - last_put_cache_num = target_num; +// uint16_t lot = reg_index & 0x3ff; +// if(lot == 0) lot = 1024; +// if(num < 0) return; +// if(num >= lot) return; +// if(/*!(reg_spen) || */!(sprite_enabled)) return; - cacheptr = &(cache_index[target_num]); - - memset(cacheptr, 0x00, sizeof(sprite_cache_t)); - cacheptr->is_use = true; - cacheptr->attribute = sprite_table[num].attribute; - cacheptr->is_32768 = sprite_table[num].is_32768; - cacheptr->is_halfx = sprite_table[num].is_halfx; - cacheptr->is_halfy = sprite_table[num].is_halfy; - cacheptr->pixels = (uint16_t*)(&(cache_pixels[target_num][0])); - cacheptr->masks = (uint16_t*)(&(cache_masks[target_num][0])); - cacheptr->color = sprite_table[num].color; - cacheptr->num = sprite_table[num].num; - cacheptr->rotate_type = sprite_table[num].rotate_type; - - if(!(cacheptr->is_32768)) { - // ToDo - color_cached[(cacheptr->color) & 0xff] = true; + bool is_32768 = ((color & 0x8000) == 0); // CTEN + // ToDo: SPYS + if((color & 0x2000) != 0) return; // DISP +// out_debug_log(_T("RENDER #%d"), render_num); + uint32_t color_offset = ((uint32_t)((color & 0xfff) << 5)) & 0x1ffff; // COL11 - COL0 + + int xoffset = 0; + int yoffset = 0; + if((attr & 0x8000) != 0) { // OFFS + xoffset = reg_hoffset & 0x1ff; + yoffset = reg_voffset & 0x1ff; + } + bool swap_v_h = false; + if((attr & 0x4000) != 0) { // ROT2 + swap_v_h = true; } - pattern_cached[sprite_table[num].num] = true; // OK? + uint8_t rot = attr >> 12; + bool is_halfy = ((attr & 0x0800) != 0); + bool is_halfx = ((attr & 0x0400) != 0); // SUX + // From MAME 0.209, mame/drivers/video/fmtowns.cpp + uint32_t ram_offset = ((uint32_t)(attr & 0x3ff) << 7) & 0x1ffff; // PAT9 - PAT0 - switch((sprite_table[num].rotate) & 7) { + int xbegin, xend; + int ybegin, yend; + int xinc, yinc; + bool is_mirror; + switch(rot & 3) { // ROT1, ROT0 case 0: - rot_type = ROT_FMTOWNS_SPRITE_0; + // 0deg, not mirror + xbegin = 0; + xend = 15; + ybegin = 0; + yend = 15; + xinc = 1; + yinc = 1; is_mirror = false; break; case 1: - rot_type = ROT_FMTOWNS_SPRITE_180; + // 180deg, mirror + xbegin = 0; + xend = 15; + ybegin = 15; + yend = 0; + xinc = 1; + yinc = -1; is_mirror = true; break; case 2: - rot_type = ROT_FMTOWNS_SPRITE_180; - is_mirror = false; + // 0deg, mirror + xbegin = 15; + xend = 0; + ybegin = 0; + yend = 15; + xinc = -1; + yinc = 1; + is_mirror = true; break; case 3: - rot_type = ROT_FMTOWNS_SPRITE_0; - is_mirror = true; + // 180deg, not mirror + xbegin = 15; + xend = 0; + ybegin = 15; + yend = 0; + xinc = -1; + yinc = -1; + is_mirror = false; break; + /* case 4: - rot_type = ROT_FMTOWNS_SPRITE_270; - is_mirror = true; + // 270deg, mirror break; case 5: - rot_type = ROT_FMTOWNS_SPRITE_90; - is_mirror = false; + // 90deg, not mirror break; case 6: - rotate = false; - rot_type = ROT_FMTOWNS_SPRITE_270; - is_mirror = false; + // 270deg, not mirror break; case 7: - rot_type = ROT_FMTOWNS_SPRITE_90; - is_mirror = true; + // 90deg, mirror break; + */ } - uint32_t index_num = cacheptr->attribute & 0x3ff; - if(index_num < 128) return; - - uint8_t* src = &(pattern_ram[index_num << 7]); - bool is_32768 = cacheptr->is_32768; - bool is_halfx = cacheptr->is_halfx; - bool is_halfy = cacheptr->is_halfy; - - if((cacheptr->pixels != NULL) || (cacheptr->masks != NULL)) return; - switch(rot_type) { - case ROT_FMTOWNS_SPRITE_00: - rot_data_0(src, is_mirror, cacheptr->pixels, cacheptr->masks, is_32768, is_halfx, is_halfy); - break; - case ROT_FMTOWNS_SPRITE_90: - rot_data_0(src, is_mirror, cacheptr->pixels, cacheptr->masks, is_32768, is_halfx, is_halfy); - break; - case ROT_FMTOWNS_SPRITE_180: - rot_data_0(src, is_mirror, cacheptr->pixels, cacheptr->masks, is_32768, is_halfx, is_halfy); - break; - case ROT_FMTOWNS_SPRITE_270: - rot_data_0(src, is_mirror, cacheptr->pixels, cacheptr->masks, is_32768, is_halfx, is_halfy); - break; + if(swap_v_h) is_mirror = !(is_mirror); + int rx = (x + xoffset) & 0x1ff; + int ry = (y + yoffset) & 0x1ff; + int ww = (is_halfx) ? 8 : 16; + int hh = (is_halfy) ? 8 : 16; + if((rx >= 256) && ((rx + ww) < 512)) return; + if((ry >= 256) && ((ry + hh) < 512)) return; + __DECL_ALIGNED(32) uint16_t sbuf[16][16] = {0}; + __DECL_ALIGNED(16) union { + pair16_t pw[16]; + uint8_t b[32]; + } lbuf; + __DECL_ALIGNED(16) union { + pair16_t pw[16]; + uint8_t b[32]; + } mbuf; + __DECL_ALIGNED(16) uint16_t pixel_h[8]; + __DECL_ALIGNED(16) uint16_t pixel_l[8]; + __DECL_ALIGNED(16) uint16_t color_table[16] = {0}; + if(!(swap_v_h)) { + if(is_32768) { + // get from ram. + for(int yy = 0; yy < 16; yy++) { + uint32_t addr = ((ybegin + yy * yinc) << 5) + (xbegin << 1) + ram_offset; + __DECL_ALIGNED(16) union { + pair16_t pw[16]; + uint8_t b[32]; + } nnw; + if(xinc > 0) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + nnw.b[xx] = pattern_ram[(addr + xx) & 0x1ffff]; + } + } else { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + nnw.b[xx] = pattern_ram[(addr - xx) & 0x1ffff]; + } + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + sbuf[yy][xx] = nnw.pw[xx].w; + } + } + } else { // 16 colors + __DECL_ALIGNED(16) union { + pair16_t pw[16]; + uint8_t b[32]; + } nnw; +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 32; i++) { + nnw.b[i] = pattern_ram[(color_offset + i) & 0x1ffff]; +// color_offset += 2; + } +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + color_table[i] = nnw.pw[i].w; + } + color_table[0] = 0x8000; // Clear color + for(int yy = 0; yy < 16; yy++) { + uint32_t addr = ((ybegin + yy * yinc) << 3) + (xbegin >> 1) + ram_offset; + uint8_t nnh, nnl; + __DECL_ALIGNED(8) uint8_t nnb[8]; + if(xinc > 0) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnb[xx] = pattern_ram[(addr + xx) & 0x1ffff]; + } + } else { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnb[xx] = pattern_ram[(addr - xx) & 0x1ffff]; + } + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnh = nnb[xx] & 0x0f; + pixel_h[xx] = color_table[nnh]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnh = nnb[xx] & 0x0f; + pixel_h[xx] = color_table[nnh]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnh = nnb[xx] & 0x0f; + pixel_h[xx] = color_table[nnh]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnl = nnb[xx] >> 4; + pixel_l[xx] = color_table[nnl]; + } + if(xinc < 0) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx += 2 ) { + sbuf[yy][xx ] = pixel_l[xx >> 1]; + sbuf[yy][xx + 1] = pixel_h[xx >> 1]; + } + } else { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx += 2 ) { + sbuf[yy][xx ] = pixel_h[xx >> 1]; + sbuf[yy][xx + 1] = pixel_l[xx >> 1]; + } + } + } + } + } else { // swap v and h + if(is_32768) { + // get from ram. + for(int yy = 0; yy < 16; yy++) { + uint32_t addr = ((ybegin + yy * yinc) << 5) + (xbegin << 1) + ram_offset; + __DECL_ALIGNED(16) union { + pair16_t pw[16]; + uint8_t b[32]; + } nnw; + if(xinc > 0) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + nnw.b[xx] = pattern_ram[(addr + xx) & 0x1ffff]; + } + } else { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + nnw.b[xx] = pattern_ram[(addr - xx) & 0x1ffff]; + } + } + if(yinc > 0) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + sbuf[xx][yy] = nnw.pw[xx].w; + } + } else { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + sbuf[15 - xx][yy] = nnw.pw[xx].w; + } + } + } + } else { // 16 colors + pair16_t nnp; +__DECL_VECTORIZED_LOOP + for(int i = 0; i < 16; i++) { + nnp.b.l = pattern_ram[(color_offset + 0) & 0x1ffff]; + nnp.b.h = pattern_ram[(color_offset + 1) & 0x1ffff]; + color_offset += 2; + color_table[i] = nnp.w; + } + color_table[0] = 0x8000; // Clear color + for(int yy = 0; yy < 16; yy++) { + uint32_t addr = ((ybegin + yy * yinc) << 3) + (xbegin >> 1) + ram_offset; + uint8_t nnh, nnl; + uint8_t nnb; + if(xinc > 0) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnb = pattern_ram[(addr + xx) & 0x1ffff]; + nnh = nnb & 0x0f; + nnl = nnb >> 4; + pixel_h[xx] = color_table[nnh]; + pixel_l[xx] = color_table[nnl]; + } + } else { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++ ) { + nnb = pattern_ram[(addr - xx) & 0x1ffff]; + nnh = nnb & 0x0f; + nnl = nnb >> 4; + pixel_h[xx] = color_table[nnh]; + pixel_l[xx] = color_table[nnl]; + } + } + if(yinc < 0) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx += 2 ) { + sbuf[xx ][yy] = pixel_l[xx >> 1]; + sbuf[xx + 1][yy] = pixel_h[xx >> 1]; + } + } else { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx += 2 ) { + sbuf[xx ][yy] = pixel_h[xx >> 1]; + sbuf[xx + 1][yy] = pixel_l[xx >> 1]; + } + } + } + } } - // ToDo: wrap round.This is still bogus implement. - // ToDo: Separate writing buffer and integrate cache. - // copy cache to buffer - render_zoomed_pixels(x, y, cacheptr->pixels, cacheptr->masks, cacheptr->is_halfx, cacheptr->is_halfy, dst_pixel, dst_mask); - return; -} + uint32_t noffset = (draw_page1) ? 0x40000 : 0x60000; + uint32_t vpaddr = ((rx + (ry * 256)) << 1) & 0x1ffff; + if(!(is_halfx) && !(is_halfy)) { // not halfed + int __xstart = rx; + int __xend = 16; + int __ystart = 0; + int __yend = 16; + int __xstart2 = 0; + if((rx + __xend) > 512) { + __xstart = 0; + __xstart2 = 512 - rx; + __xend = (rx + __xend) - 512; + } else if(rx > (256 - __xend)) { + __xend = 256 - rx; + } + if(__xend <= 0) return; + for(int yy = 0; yy < 16; yy++) { + int yoff = (yy + ry) & 0x1ff; + if((d_vram != NULL) && (yoff < 256)) { + vpaddr = ((__xstart + (yoff << 8)) << 1) & 0x1ffff; + __DECL_ALIGNED(32) uint8_t source[32] = {0}; + d_vram->get_vram_to_buffer(vpaddr + noffset, source, __xend); +__DECL_VECTORIZED_LOOP + for(int xx = 0, xx2 = __xstart2; xx < __xend; xx++, xx2++) { + lbuf.pw[xx].w = sbuf[yy][xx2]; + } + __DECL_ALIGNED(16) uint16_t mbuf2[16] = {0}; +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf2[xx] = (lbuf.pw[xx].w >> 15); // All values are either 1 or 0. + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf2[xx] = mbuf2[xx] * 0xffff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf.pw[xx].w = mbuf2[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { +// lbuf.pw[xx].w &= 0x7fff; + lbuf.pw[xx].w &= (~(mbuf2[xx]) & 0x7fff); // OK? + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + source[xx] &= mbuf.b[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + source[xx] |= lbuf.b[xx]; + } + d_vram->set_buffer_to_vram(vpaddr + noffset, source, __xend); + } + } + } else if((is_halfx) && !(is_halfy)) { // halfx only + int __xstart = rx; + int __xend = 8; + int __ystart = 0; + int __yend = 16; + int __xstart2 = 0; -void TOWNS_SPRITE::render_zoomed_pixels(int x, int y, int uint16_t* pixels, uint16_t* masks, bool is_halfx, bool is_halfy, uint16_t* dst_pixel, uint16_t* dst_mask) -{ - static const int stride = 256; - uint16_t* pp = cache_index[target_num].pixels; - uint16_t* pq = cache_index[target_num].masks; - uint16_t* pd; - uint16_t* pm; - int w, h; - int beginx, beginy; - bool is_wrapx = false; - bool is_wrapy = false; - int offset; - int ww, hh; - w = 16; - h = 16; - beginx = 0; - beginy = 0; - if(is_halfx) { - w = 8; - } - if(is_halfy) { - h = 8; - } - if((x < 0) || (y < 0)) return; - if((x > 511) || (y > 511)) return; - if((x >= (512 - w)) && (x < 512)) { - beginx = x - (512 - 16); - ww = w - beginx; - is_wrapx = true; - } else if((x >= (256 - w)) && (x < 256)) { - beginx = 0; - ww = 256 - x; - } else { - ww = w; - } - if((y >= (512 - h)) && (y < 512)) { - beginy = y - (512 - 16); - hh = h - beginy; - is_wrapy = true; - } else if((y >= 256 - h) && (y < 256)) { - beginy = 0; - hh = 256 - y; - } else { - hh = h; - } - if(!(is_wrapx) && !(is_wrapy)) { - if((hh <= 0) || (ww <= 0)) return; - } - if(is_wrapx) { // Check Y - if(y >= 256) return; - } - if(is_wrapy) { // Check Y - if(x >= 256) return; - } - if(is_wrapy) { - offset = 0 + (is_wrapx) ? 0 : x; - } else if(is_wrapx) { - offset = (y * stride) + 0; - } else { - if((x >= 256) || (y >= 256)) return; - offset = (y * stride) + x; - } - // ToDo: Add offset registers. - - uint16_t cacheline[16]; - uint16_t mcacheline[16]; - uint16_t pcacheline[16]; - uint16_t mcacheline2[16]; - int cache_stride = (is_halfx) ? 3 : 4; - - pd = &(dst_pixels[offset]); - pm = &(dst_mask[offset]); - for(int y = beginy; y < (hh + beginy); y++) { - uint16_t* rp = &(pp[(y << cache_stride) + beginx]); - uint16_t* rq = &(pq[(y << cache_stride) + beginx]); -__DECL_VECTORIZED_LOOP - for(int x = 0; x < ww; x++) { - cacheline[x] = rp[x]; - mcacheline[x] = rq[x]; - pcacheline[x] = pd[x]; + if((rx + __xend) > 512) { + __xstart = 0; + __xstart2 = 512 - rx; + __xend = (rx + __xend) - 512; + } else if(rx > (256 - __xend)) { + __xend = 256 - rx; } -__DECL_VECTORIZED_LOOP - for(int x = 0; x < ww; x++) { - pm[x] = pm[x] | mcacheline[x]; // Fill mask what pixel is drawn. - - cacheline[x] = cacheline[x] & mcacheline[x]; - mcacheline[x] = ~mcacheline[x]; // Invert mask - pcacheline[x] = pcacheline[x] & mcacheline[x]; - pd[x] = cacheline[x] | pcacheline[x]; + if(__xend <= 0) return; + for(int yy = 0; yy < 16; yy++) { + int yoff = (yy + ry) & 0x1ff; + if((d_vram != NULL) && (yoff < 256)) { + vpaddr = ((__xstart + (yoff << 8)) << 1) & 0x1ffff; + __DECL_ALIGNED(16) uint8_t source[16] = {0}; + d_vram->get_vram_to_buffer(vpaddr + noffset, source, __xend); +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + lbuf.pw[xx].w = 0x0; + mbuf.pw[xx].w = 0; + } + __DECL_ALIGNED(16) uint16_t sbuf2[16] = {0}; + __DECL_ALIGNED(16) uint16_t sbuf3[16]; +__DECL_VECTORIZED_LOOP + for(int xx = 0, xx2 = __xstart2; xx < __xend; xx++, xx2++) { + sbuf2[xx] = sbuf[yy][xx2]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + sbuf3[xx] = sbuf2[xx] & 0x8000; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + sbuf2[xx] = sbuf2[xx] & 0x7fff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + lbuf.pw[xx >> 1].w += sbuf2[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf.pw[xx >> 1].w |= sbuf3[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w = (lbuf.pw[xx].w >> 1); + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w &= 0x7fff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w |= mbuf.pw[xx].w; + } + __DECL_ALIGNED(16) uint16_t mbuf2[8]; +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf2[xx] = mbuf.pw[xx].w; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf2[xx] = (lbuf.pw[xx].w >> 15); // All values are either 1 or 0. + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf2[xx] = mbuf2[xx] * 0xffff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf.pw[xx].w = mbuf2[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w &= (~(mbuf2[xx])); + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w &= 0x7fff; +// lbuf.pw[xx].w &= ~(mbuf.pw[xx].w); + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + source[xx] &= mbuf.b[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + source[xx] |= lbuf.b[xx]; + } + d_vram->set_buffer_to_vram(vpaddr + noffset, source, __xend); + } } - pd = pd + stride; - } -} + } else if(is_halfy) { // halfy only + int __xstart = rx; + int __xend = 16; + int __ystart = 0; + int __yend = 8; + int __xstart2 = 0; + if((rx + __xend) > 512) { + __xstart = 0; + __xstart2 = 512 - rx; + __xend = (rx + __xend) - 512; + } else if(rx > (256 - __xend)) { + __xend = 256 - rx; + } + if(__xend <= 0) return; + for(int yy = (__ystart << 1); yy < (__yend << 1); yy += 2) { + int yoff = (yy + ry) & 0x1ff; + if((d_vram != NULL) && (yoff < 256)) { + vpaddr = ((__xstart + (yoff << 8)) << 1) & 0x1ffff; + __DECL_ALIGNED(32) uint8_t source[32] = {0}; + d_vram->get_vram_to_buffer(vpaddr + noffset, source, __xend); +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + lbuf.pw[xx].w = 0x0; + mbuf.pw[xx].w = 0; + } + __DECL_ALIGNED(32) uint16_t sbuf2[32] = {0}; + __DECL_ALIGNED(32) uint16_t sbuf3[32]; +__DECL_VECTORIZED_LOOP + for(int xx = 0, xx2 = __xstart2; xx < __xend; xx++, xx2++) { + sbuf2[xx] = sbuf[yy][xx2]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 16, xx2 = (__xstart2 + 16); xx < (16 + __xend); xx++, xx2++) { + sbuf2[xx] = sbuf[yy + 1][xx2]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + sbuf3[xx] = sbuf2[xx] & 0x8000; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + sbuf2[xx] = sbuf2[xx] & 0x7fff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + lbuf.pw[xx >> 1].w += sbuf2[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + mbuf.pw[xx >> 1].w |= sbuf3[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + lbuf.pw[xx].w = ((lbuf.pw[xx].w >> 1) & 0x7fff) | mbuf.pw[xx].w; + } + __DECL_ALIGNED(16) uint16_t mbuf2[16]; +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf2[xx] = mbuf.pw[xx].w; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf2[xx] = (lbuf.pw[xx].w >> 15); // All values are either 1 or 0. + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf2[xx] = mbuf2[xx] * 0xffff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + mbuf.pw[xx].w = mbuf2[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { +// lbuf.pw[xx].w &= (~(mbuf.pw[xx].w) & 0x7fff); + lbuf.pw[xx].w &= (~mbuf2[xx] & 0x7fff); + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + source[xx] &= mbuf.b[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + source[xx] |= lbuf.b[xx]; + } + d_vram->set_buffer_to_vram(vpaddr + noffset, source, __xend); + } + } + } else { //halfx &&halfy + int __xstart = rx; + int __xend = 8; + int __ystart = 0; + int __yend = 8; + int __xstart2 = 0; + if((rx + __xend) > 512) { + __xstart = 0; + __xstart2 = 512 - rx; + __xend = (rx + __xend) - 512; + } else if(rx > (256 - __xend)) { + __xend = 256 - rx; + } + if(__xend <= 0) return; + for(int yy = (__ystart << 1); yy < (__yend << 1); yy += 2) { + int yoff = (yy + ry) & 0x1ff; + if((d_vram != NULL) && (yoff < 256)) { + vpaddr = ((__xstart + (yoff << 8)) << 1) & 0x1ffff; + __DECL_ALIGNED(16) uint8_t source[16] = {0}; + d_vram->get_vram_to_buffer(vpaddr + noffset, source, __xend); + __DECL_ALIGNED(32) uint16_t sbuf2[32] = {0}; + __DECL_ALIGNED(32) uint16_t sbuf3[32]; + __DECL_ALIGNED(16) uint16_t lbuf4[16]; + __DECL_ALIGNED(16) uint16_t mbuf5[16]; -// Q: Does split rendering per vline? -void TOWNS_SPRITE::render(uint16_t *buffer, uint16_t* mask) -{ - // ToDo: Implement Register #2-5 - uint16_t lot = reg_index & 0x3ff; - if(lot == 0) lot = 1024; - // Clear buffer? - if((buffer == NULL) || (mask == NULL)) return; - //memset(buffer, 0x00, 256 * 256 * sizeof(uint16_t)); - //memset(mask, 0x00, 256 * 256 * sizeof(uint16_t)); - // ToDo: Implement registers. - if(reg_spen) { - for(render_num = 0; render_num < (int)lot; render_num++) { - uint16_t* index_base = &(index_ram[render_num << 2]); - uint16_t xaddr = index_base[0] & 0x1ff; - uint16_t yaddr = index_base[1] & 0x1ff; - // ToDo: wrap round.This is still bogus implement. - render_sprite(render_num, buffer, mask, (int)xaddr, (int)yaddr); +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + lbuf4[xx] = 0x0000; + mbuf5[xx] = 0; + + } + // Phase.1 Get RAW DATA + // Get Column 0 +__DECL_VECTORIZED_LOOP + for(int xx = 0, xx2 = __xstart2; xx < __xend; xx++, xx2++) { + sbuf2[xx] = sbuf[yy][xx2]; + } + // Get Column 1 +__DECL_VECTORIZED_LOOP + for(int xx = 16, xx2 = (__xstart + 16); xx < (16 + __xend); xx++, xx2++) { + sbuf2[xx] = sbuf[yy + 1][xx2]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + sbuf3[xx] = sbuf2[xx] & 0x8000; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + sbuf2[xx] = sbuf2[xx] & 0x7fff; + } + // Phase.2 Shrink X +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + lbuf4[xx >> 1] += sbuf2[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + lbuf4[xx] >>= 1; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + lbuf4[xx] &= 0x7fff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 32; xx++) { + mbuf5[xx >> 1] |= sbuf3[xx]; + } + + // Phase.3 Shrink Y +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w = lbuf4[xx] + lbuf4[xx + 8]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w >>= 1; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w &= 0x7fff; + } + +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf.pw[xx].w = mbuf5[xx] | mbuf5[xx + 8]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w |= mbuf.pw[xx].w; + } + __DECL_ALIGNED(16) uint16_t mbuf2[8]; +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf2[xx] = mbuf.pw[xx].w; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf2[xx] = (lbuf.pw[xx].w >> 15); // All values are either 1 or 0. + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf2[xx] = mbuf2[xx] * 0xffff; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + mbuf.pw[xx].w = mbuf2[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 8; xx++) { + lbuf.pw[xx].w &= (~mbuf2[xx] & 0x7fff); + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + source[xx] &= mbuf.b[xx]; + } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 16; xx++) { + source[xx] |= lbuf.b[xx]; + } + d_vram->set_buffer_to_vram(vpaddr + noffset, source, __xend); + } } } } - -void TOWNS_SPRITE::render_part(uint16_t *buffer, uint16_t* mask, int start, int end) + +void TOWNS_SPRITE::render_part() { // ToDo: Implement Register #2-5 - uint16_t lot = reg_index & 0x3ff; - if(lot == 0) lot = 1024; - if((start < 0) || (end < 0)) return; - if(end > lot) end = lot; - if(start > end) return; - // Clear buffer? - if((buffer == NULL) || (mask == NULL)) return; +// if((start < 0) || (end < 0)) return; +// if(start > end) return; +// out_debug_log(_T("VLINE NUM=%d"),render_num); // ToDo: Implement registers. - if(reg_spen) { - for(render_num = start; render_num < end; render_num++) { - uint16_t* index_base = &(index_ram[render_num << 2]); - uint16_t xaddr = index_base[0] & 0x1ff; - uint16_t yaddr = index_base[1] & 0x1ff; +// if(reg_spen) { +// if((frame_sprite_count >= max_sprite_per_frame) && (max_sprite_per_frame > 0)) return; + /*for(render_num = start; render_num < end; render_num++) */ + { + uint32_t addr = render_num << 3; + pair16_t _nx, _ny, _nattr, _ncol; + _nx.b.l = pattern_ram[addr + 0]; + _nx.b.h = pattern_ram[addr + 1]; + _ny.b.l = pattern_ram[addr + 2]; + _ny.b.h = pattern_ram[addr + 3]; + _nattr.b.l = pattern_ram[addr + 4]; + _nattr.b.h = pattern_ram[addr + 5]; + _ncol.b.l = pattern_ram[addr + 6]; + _ncol.b.h = pattern_ram[addr + 7]; + + int xaddr = _nx.w & 0x1ff; + int yaddr = _ny.w & 0x1ff; + // ToDo: wrap round.This is still bogus implement. // ToDo: wrap round.This is still bogus implement. - render_sprite(render_num, buffer, mask, (int)xaddr, (int)yaddr); +// out_debug_log(_T("RENDER %d X=%d Y=%d ATTR=%04X COLOR=%04X"), render_num, xaddr, yaddr, _nattr.w, _ncol.w); + + render_sprite(render_num, xaddr, yaddr, _nattr.w, _ncol.w); } - } +// } } // ToDo: Discard cache(s) if dirty color index and if used this cache at 16 colors. // ToDo: Discard cache(s) if dirty void TOWNS_SPRITE::write_io8(uint32_t addr, uint32_t data) { - reg_addr = addr & 7; - reg_data[reg_addr] = (uint8_t)data; + if(addr == 0x0450) { + reg_addr = data & 7; + } else if(addr != 0x0452) { + return; + } else { +// if(!sprite_enabled) { + write_reg(reg_addr, data); +// } + } +} - switch(reg_addr) { +void TOWNS_SPRITE::write_reg(uint32_t addr, uint32_t data) +{ + reg_data[addr] = (uint8_t)data; + + switch(addr) { case 0: reg_index = ((uint16_t)(reg_data[0]) + (((uint16_t)(reg_data[1] & 0x03)) << 8)); break; case 1: reg_index = ((uint16_t)(reg_data[0]) + (((uint16_t)(reg_data[1] & 0x03)) << 8)); reg_spen = ((reg_data[1] & 0x80) != 0) ? true : false; + reg_data[1] = reg_data[1] & 0x7f; // From Tsugaru break; case 2: case 3: @@ -424,8 +788,13 @@ void TOWNS_SPRITE::write_io8(uint32_t addr, uint32_t data) reg_voffset = ((uint16_t)(reg_data[4]) + (((uint16_t)(reg_data[5] & 0x01)) << 8)); break; case 6: - disp_page0 = ((data & 0x01) != 0) ? true : false; - disp_page1 = ((data & 0x10) != 0) ? true : false; + { + // From Tsugaru + bool _bak = disp_page1; + disp_page0 = ((data & 0x08) != 0) ? true : false; + disp_page1 = ((data & 0x80) != 0) ? true : false; + /*if(_bak != disp_page1) */page_changed = true; + } break; default: break; @@ -435,9 +804,18 @@ void TOWNS_SPRITE::write_io8(uint32_t addr, uint32_t data) uint32_t TOWNS_SPRITE::read_io8(uint32_t addr) { uint32_t val = 0xff; - reg_addr = addr & 7; + + if(addr == 0x05c8) { + val = (tvram_enabled) ? 0x80 : 0; + tvram_enabled = false; + return val; + } else if(addr == 0x0450) { + return (reg_addr & 0x07); + } else if(addr != 0x0452) { + return 0xff; + } switch(reg_addr) { - case 0: +/* case 0: val = reg_index & 0xff; break; case 1: @@ -456,374 +834,279 @@ uint32_t TOWNS_SPRITE::read_io8(uint32_t addr) case 5: val = (reg_voffset & 0x0100) >> 8; break; +*/ + case 1: + val = reg_data[reg_addr] & 0x7f; // From Tsugaru + val = val | ((sprite_enabled) ? 0x80 : 0x00); break; case 6: - val = (disp_page0) ? 0x08 : 0x00; - val = val | ((disp_page1) ? 0x80 : 0x00); + // From Tsugaru + val = (disp_page0) ? 0x01 : 0x00; + val = val | ((disp_page1) ? 0x10 : 0x00); break; default: - val = 0x00; +// val = 0x00; + val = reg_data[reg_addr]; // From Tsugaru break; } return val; } -uint32_t TOWNS_SPRITE::read_data8(uint32_t addr) +uint32_t TOWNS_SPRITE::read_memory_mapped_io8(uint32_t addr) { - uint32_t nbank; - uint8_t* p8; - uint16_t val; - pair_t tval; if((addr >= 0x81000000) && (addr < 0x81020000)) { - nbank = (addr & 0x1e000) >> 12; - } else { - nbank = 0; // OK? + return pattern_ram[addr & 0x1ffff]; + }/* else if((addr >= 0xc8000) && (addr < 0xc9000)) { + return pattern_ram[addr - 0xc8000]; + } else if((addr >= 0xca000) && (addr < 0xcb000)) { + return pattern_ram[addr - 0xc8000]; + }*/ + else if((addr >= 0xc8000) && (addr < 0xcb000)) { // OK? From TSUGARU + return pattern_ram[addr - 0xc8000]; } - switch(nbank) { - case 0: - case 1: - tval.w.l = index_ram[(addr & 0x1ffe) >> 1]; - if((addr & 1) == 0) { // Lo - val = (uint16_t)(tval.b.l); - } else { - val = (uint16_t)(tval.b.h); - } - break; - case 2: - case 3: - tval.w.l = color_ram[(addr & 0x1ffe) >> 1]; - if((addr & 1) == 0) { // Lo - val = (uint16_t)(tval.b.l); - } else { - val = (uint16_t)(tval.b.h); - } - break; - default: - p8 = &(pattern_ram[(addr & 0x1fffe) - 0x4000]); - if((addr & 1) == 0) { // Lo - val = p8[0]; - } else { - val = p8[1]; - } - break; - } - return (uint32_t)val; + return 0x00; } -uint32_t TOWNS_SPRITE::read_data16(uint32_t addr) + +void TOWNS_SPRITE::write_memory_mapped_io8(uint32_t addr, uint32_t data) { - uint32_t nbank; - uint8_t* p8; - pair_t tval; - uint16_t val; if((addr >= 0x81000000) && (addr < 0x81020000)) { - nbank = (addr & 0x1e000) >> 12; - } else { - nbank = 0; // OK? - } - switch(nbank) { - case 0: - case 1: - val = (uint32_t)(index_ram[(addr & 0x1ffe) >> 1]); - break; - case 2: - case 3: - val = (uint32_t)(color_ram[(addr & 0x1ffe) >> 1]); - break; - default: - p8 = &(pattern_ram[(addr & 0x1fffe) - 0x4000]); - tval.b.l = p8[0]; - tval.b.h = p8[1]; - val = (uint32_t)(tval.w.l); - break; - } - return (uint32_t)val; + pattern_ram[addr & 0x1ffff] = data; + } /*else if((addr >= 0xc8000) && (addr < 0xc9000)) { + tvram_enabled = true; + tvram_enabled_bak = true; + pattern_ram[addr - 0xc8000] = data; + } else if((addr >= 0xca000) && (addr < 0xcb000)) { + tvram_enabled = true; + tvram_enabled_bak = true; + pattern_ram[addr - 0xc8000] = data; + }*/ + else if((addr >= 0xc8000) && (addr < 0xcb000)) { // OK? From TSUGARU + tvram_enabled = true; + tvram_enabled_bak = true; + pattern_ram[addr - 0xc8000] = data; + } + return; } -uint32_t TOWNS_SPRITE::read_data32(uint32_t addr) +bool TOWNS_SPRITE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) { - uint32_t hi, lo = 0; - lo = read_data16(addr); - if(addr < 0x8101fffe) hi = read_data16(addr + 2); - return ((hi << 16) & 0xffff0000) | (lo & 0x0000ffff); + _TCHAR regstr[1024] = {0}; + _TCHAR sstr[128] = {0}; + my_stprintf_s(sstr, 127, _T("TEXT VRAM:%s \n\n"), ((tvram_enabled) || (tvram_enabled_bak)) ? _T("WROTE") : _T("NOT WROTE")); + my_tcscat_s(regstr, 1024, sstr); + + memset(sstr, 0x00, sizeof(sstr)); + my_stprintf_s(sstr, 127, _T("SPRITE:%s LOT=%d NUM=%d\nHOFFSET=%d VOFFSET=%d DISP0=%d DISP1=%d\n") + , (reg_spen) ? _T("ENABLED ") : _T("DISABLED") + , ((reg_index & 0x3ff) == 0) ? 1024 : (reg_index & 0x3ff) + , render_num + , reg_hoffset + , reg_voffset + , (disp_page0) ? 1 : 0 + , (disp_page1) ? 1 : 0 + ); + my_tcscat_s(regstr, 1024, sstr); + + memset(sstr, 0x00, sizeof(sstr)); + my_stprintf_s(sstr, 127, _T("TRANSFER:%s (%s)\n") + , (sprite_enabled) ? _T("ON ") : _T("OFF") + , (sprite_busy) ? _T("BUSY") : _T("IDLE") + ); + my_tcscat_s(regstr, 1024, sstr); + + + memset(sstr, 0x00, sizeof(sstr)); + my_stprintf_s(sstr, 127, _T("REGISTER ADDRESS:%02X \n"), reg_addr & 0x07); + my_tcscat_s(regstr, 1024, sstr); + + for(int r = 0; r < 8; r++) { + memset(sstr, 0x00, sizeof(sstr)); + my_stprintf_s(sstr, 127, _T("R%d:%02X "), r, reg_data[r]); + my_tcscat_s(regstr, 1024, sstr); + if((r & 3) == 3) { + my_tcscat_s(regstr, 1024, _T("\n")); + } + } + my_tcscpy_s(buffer, (buffer_len >= 1024) ? 1023 : buffer_len, regstr); + return true; } -void TOWNS_SPRITE::write_data8(uint32_t addr, uint32_t data) +bool TOWNS_SPRITE::write_debug_reg(const _TCHAR *reg, uint32_t data) { - uint32_t nbank; - uint32_t uaddr; - uint16_t tmp16; - uint8_t tmp8; - uint8_t* p8; - pair_t tval; - if((addr >= 0x81000000) && (addr < 0x81020000)) { - nbank = (addr & 0x1e000) >> 12; - } else { - nbank = 0; // OK? + if(reg == NULL) return false; + if((reg[0] == 'R') || (reg[0] == 'r')) { + if((reg[1] >= '0') && (reg[1] <= '7')) { + if(reg[2] != '\0') return false; + int rnum = reg[1] - '0'; + write_reg(rnum, data); + return true; + } + } else if((reg[0] == 'A') || (reg[0] == 'a')) { + if(reg[1] != '\0') return false; + reg_addr = data & 7; + return true; } - - switch(nbank) { - case 0: - case 1: - uaddr = (addr & 0x1ffe) >> 1; - tval.w.l = index_ram[uaddr]; - tmp16 = tval.w.l; - if((addr & 1) == 0) { // Lo - tval.b.l = (uint8_t)(data & 0xff); - } else { - tval.b.h = (uint8_t)(data & 0xff); + return false; +} + +void TOWNS_SPRITE::event_callback(int id, int err) +{ + switch(id) { + case EVENT_FALL_DOWN: +// sprite_enabled = false; + disp_page1 = !(disp_page1); // Change page + break; + case EVENT_BUSY_OFF: + event_busy = -1; + sprite_busy = false; + /*if(render_num >= 1024) */{ + int lot = reg_index & 0x3ff; + if(lot == 0) lot = 1024; + render_num = lot; + disp_page1 = !(disp_page1); } - if(use_cache) { - if(uaddr == 2) { // ATTR - if((tmp16 & 0x7c00) != (tval.w.l & 0x7c00)) { - // Search cache and Discard cache - } - } else if(uaddr == 3) { - if((tmp16 & 0x8fff) != (tval.w.l & 0x8fff)) { - // Search cache and Discard cache - } + break; + case EVENT_RENDER: + event_busy = -1; + if((sprite_enabled) /*&& (render_num < 1024) */&& (sprite_busy)) { +// sprite_busy = true; + int _bak = render_num; +// for(; render_num < 1024; ){ + render_part(); + render_num++; +// } +// if(_bak >= 1024) { +// _bak = 1023; +// } +// register_event(this, EVENT_BUSY_OFF, 75.0 * (1024 - _bak), false, &event_busy); + if(render_num >= 1024) { + register_event(this, EVENT_BUSY_OFF, 75.0 / 2, false, &event_busy); + } else { + register_event(this, EVENT_RENDER, 75.0 / 2, false, &event_busy); } } - index_ram[uaddr] = tval.w.l; break; - case 2: - case 3: - // ToDO: Discard cache - uaddr = (addr & 0x1ffe) >> 1; - tval.w.l = color_ram[uaddr]; - tmp16 = tval.w.l; - if((addr & 1) == 0) { // Lo - tval.b.l = (uint8_t)(data & 0xff); - } else { - tval.b.h = (uint8_t)(data & 0xff); - } - if(use_cache) { - if(tmp16 != tval.w.l) { // Dirty color table - uint32_t nnum = uaddr >> 4; - color_ram[uaddr] = tval.w.l; - if(color_cached[nnum]) { - for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) { - if(cache_index[i].color == (uint16_t)(nnum + 256)) { - if((cache_index[i].is_use) && !(cache_index[i].is_32768)) { - clear_cache(i); - } - } - } - color_cached[nnum] = false; + } +} - } - } else { - color_ram[uaddr] = tval.w.l; - } - break; - default: - // ToDO: Discard cache - uaddr = (addr & 0x1ffff) - 0x4000; - p8 = &(pattern_ram[uaddr]); - tmp8 = *p8; - if(use_cache) { - if((uint8_t)(data & 0xff) != tmp8) { // Dirty pattern memory. - *p8 = (uint8_t)(data & 0xff); - uint32_t nnum = uaddr >> 7; - uint32_t nnum_bak = nnum; - if(pattern_cached[nnum]) { // ToDo: Search another number. - for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) { - if(cache_index[i].is_32768) { - if(cache_index[i].num == (uint16_t)nnum) { - if(cache_index[i].is_use) { - clear_cache(i); - } - } - } else { - uint32_t begin; - uint32_t end; - uint32_t clen = 0; - // OK? - begin = (nnum <= (128 + 3)) ? (128 + 3) : nnum - 3; - end = (nnum <= 128) ? 128 : nnum + 3; - if(begin < 1024) { - if(end > 1023) end = 1023; - if((cache_index[i].num >= begin) && (cache_index[i].num <= end)) { - clen = end - begin + 1; - for(uint32_t j = 0; j < clen; j++) { - if(cache_index[i].num == (uint16_t)(begin + j)) { - if(cache_index[i].is_use) { - clear_cache(i); - } - } - } - } - } - } - } - pattern_cached[nnum] = false; +void TOWNS_SPRITE::check_and_clear_vram() +{ + if(sprite_enabled != reg_spen) { + clear_event(this, event_busy); + sprite_busy = false; + } + sprite_enabled = reg_spen; + if(!(sprite_busy) && (sprite_enabled)) { + uint16_t lot = reg_index & 0x3ff; + if(lot == 0) lot = 1024; + render_num = lot; + sprite_busy = true; + clear_event(this, event_busy); + { + uint32_t noffset = (disp_page1) ? 0x40000 : 0x60000; + draw_page1 = disp_page1; + if((d_vram != NULL) && (render_num < 1024)) { + pair16_t *p = (pair16_t*)(d_vram->get_vram_address(noffset)); + if(p != NULL) { + for(int x = 0; x < 0x10000; x++) { + p[x].w = 0x8000; // } - } - } else { - *p8 = (uint8_t)(data & 0xff); - } + } + page_changed = false; + register_event(this, EVENT_RENDER, 32.0, false, &event_busy); } - break; } - return; } -void TOWNS_SPRITE::write_data16(uint32_t addr, uint32_t data) +void TOWNS_SPRITE::event_pre_frame() { - pair_t t; - t.d = data; - write_data8(addr, (uint32_t)(t.b.l)); - write_data8(addr + 1, (uint32_t)(t.b.h)); + check_and_clear_vram(); } - -void TOWNS_SPRITE::write_data32(uint32_t addr, uint32_t data) + +void TOWNS_SPRITE::event_vline(int v, int clock) { - pair_t t; - t.d = data; - write_data8(addr, (uint32_t)(t.b.l)); - write_data8(addr + 1, (uint32_t)(t.b.h)); - if(addr < 0x8101fffe) { - write_data8(addr + 2, (uint32_t)(t.b.h2)); - write_data8(addr + 3, (uint32_t)(t.b.h3)); - } +// check_and_clear_vram(); } -void FMTOWNS_SPRITE::event_frame() +// Q: Is changing pages syncing to Frame? +// ToDo: Implement VRAM. +void TOWNS_SPRITE::write_signal(int id, uint32_t data, uint32_t mask) { - write_page = display_page & 1; - display_page = (displae_page + 1) & 1; - render_num = 0; - render_mod = 0; - render_lines = 0; - - // Set split_rendering from DIPSW. - // Set cache_enabled from DIPSW. - if(vram_head != NULL) { - vram_buffer = vram_head->get_vram_buffer_sprite(write_page); - mask_buffer = vram_head->get_mask_buffer_sprite(write_page); - render_lines = vram_head->get_sprite_display_lines(); + /*else if(id == SIG_TOWNS_SPRITE_ANKCG) { // write CFF19 + ankcg_enabled = ((data & mask) != 0); + } else */if(id == SIG_TOWNS_SPRITE_TVRAM_ENABLED) { // write CFF19 + tvram_enabled = ((data & mask) != 0); + tvram_enabled_bak = tvram_enabled; } - memset(vram_buffer, 0x00, w * h * sizeof(uint16_t)); - memset(vram_mask, 0x00, w * h * sizeof(uint16_t)); - if(!split_rendering) render(vram_buffer, mask_buffer); } -void FMTOWNS_SPRITE::event_vline(int v, int clock) +uint32_t TOWNS_SPRITE::read_signal(int id) { - int lot = reg_index & 0x3ff; - if(!split_rendering) return; - if(lot == 0) lot = 1024; - if((sprite_enabled) && (render_lines > 0)) { - int nf = lot / render_lines; - int nm = lot % render_lines; - render_mod += nm; - if(render_mod >= render_lines) { - nf++; - render_mod -= render_lines; + /*if(id == SIG_TOWNS_SPRITE_ANKCG) { // write CFF19 + return ((ankcg_enabled) ? 0xffffffff : 0); + } else */ + if(id == SIG_TOWNS_SPRITE_RENDER_ENABLED) { + return ((sprite_enabled) && (sprite_busy)) ? 0xffffffff : 0; + } else if(id == SIG_TOWNS_SPRITE_ENABLED) { + return (sprite_enabled) ? 0xffffffff : 0; + } else if(id == SIG_TOWNS_SPRITE_BUSY) { + return (sprite_busy) ? 0xffffffff : 0; + } else if(id == SIG_TOWNS_SPRITE_TVRAM_ENABLED) { + uint32_t v = ((tvram_enabled_bak) ? 0xffffffff : 0); + tvram_enabled_bak = false; + return v; + } else if(id == SIG_TOWNS_SPRITE_DISP_PAGE0) { + return (disp_page0) ? 0xffffffff : 0; + } else if(id == SIG_TOWNS_SPRITE_DISP_PAGE1) { + return (disp_page1) ? 0xffffffff : 0; + } else if(id >= SIG_TOWNS_SPRITE_PEEK_TVRAM) { + id = id - SIG_TOWNS_SPRITE_PEEK_TVRAM; + if((id < 0x1ffff) && (id>= 0)) { + return pattern_ram[id]; } - if((nf > 1) && (render_num < lot)) render_part(vram_buffer, mask_buffer, render_num, render_num + nf); - } -} -// Q: Is changing pages syncing to Frame? -// ToDo: Implement VRAM. -void FMTOWNS_SPRITE::write_signal(int id, uint32_t data, uint32_t mask) -{ - if(id == SIG_FMTOWNS_SPRITE_CACHE_ENABLE) { - cache_enabled = ((data & mask) != 0); - } else if(id == SIG_FMTOWNS_SPRITE_SWAP_BUFFER) { - write_page = display_page & 1; - display_page = (displae_page + 1) & 1; } - + return 0; } -#define STATE_VERSION 1 -#include "../../statesub.h" +#define STATE_VERSION 4 -void TOWNS_SPRITE::decl_state() +bool TOWNS_SPRITE::process_state(FILEIO* state_fio, bool loading) { - enter_decl_state(STATE_VERSION); - - DECL_STATE_ENTRY_UINT8(reg_addr); - DECL_STATE_ENTRY_1D_ARRAY(reg_data, 8); - - DECL_STATE_ENTRY_BOOL(reg_spen); - DECL_STATE_ENTRY_UINT16(reg_index); - DECL_STATE_ENTRY_UINT16(reg_voffset); - DECL_STATE_ENTRY_UINT16(reg_hoffset); - DECL_STATE_ENTRY_BOOL(disp_page0); - DECL_STATE_ENTRY_BOOL(disp_page1); - - DECL_STATE_ENTRY_BOOL(sprite_enabled); - DECL_STATE_ENTRY_BOOL(use_cache); - DECL_STATE_ENTRY_UINT8(write_page); - DECL_STATE_ENTRY_UINT8(display_page); + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } - DECL_STATE_ENTRY_BOOL(split_rendering); - DECL_STATE_ENTRY_INT32(render_num); - DECL_STATE_ENTRY_INT32(render_mod); - DECL_STATE_ENTRY_INT32(render_lines); - - + state_fio->StateValue(reg_addr); + state_fio->StateValue(reg_ctrl); + state_fio->StateArray(reg_data, sizeof(reg_data), 1); // RAMs - DECL_STATE_ENTRY_1D_ARRAY(index_ram, sizeof(index_ram) / sizeof(uint16_t)); - DECL_STATE_ENTRY_1D_ARRAY(pattern_ram, sizeof(pattern_ram) / sizeof(uint8_t)); - DECL_STATE_ENTRY_1D_ARRAY(color_ram, sizeof(color_ram) / sizeof(uint16_t)); - - // Q: Is save/load caches? - // Flags around cache. - DECL_STATE_ENTRY_1D_ARRAY(pattern_cached, (sizeof(pattern_cached) / sizeof(bool))); - DECL_STATE_ENTRY_1D_ARRAY(color_cached, (sizeof(pattern_cached) / sizeof(bool))); - - // Around cache. - DECL_STATE_ENTRY_INT32(last_put_cache_num); - - DECL_STATE_ENTRY_2D_ARRAY(cache_pixels, TOWNS_SPRITE_CACHE_NUM, 16 * 16); - DECL_STATE_ENTRY_2D_ARRAY(cache_masks, TOWNS_SPRITE_CACHE_NUM, 16 * 16); + state_fio->StateArray(pattern_ram, sizeof(pattern_ram), 1); - DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_use), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); - DECL_STATE_ENTRY_UINT16_STRIDE((cache_index[0].num), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); - DECL_STATE_ENTRY_UINT16_STRIDE((cache_index[0].attribute), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); - DECL_STATE_ENTRY_UINT8_STRIDE((cache_index[0].rotate_type), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); - DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_32768), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); - DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_halfx), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); - DECL_STATE_ENTRY_BOOL_STRIDE((cache_index[0].is_halfy), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); - DECL_STATE_ENTRY_UINT16_STRIDE((cache_index[0].color), TOWNS_SPRITE_CACHE_NUM, sizeof(sprite_cache_t)); + state_fio->StateValue(reg_spen); + state_fio->StateValue(reg_index); + state_fio->StateValue(reg_voffset); + state_fio->StateValue(reg_hoffset); + state_fio->StateValue(disp_page0); + state_fio->StateValue(disp_page1); + state_fio->StateValue(draw_page1); + + state_fio->StateValue(sprite_busy); + state_fio->StateValue(sprite_enabled); + state_fio->StateValue(page_changed); - leave_decl_state(); + state_fio->StateValue(render_num); -} -bool TOWNS_SPRITE::save_state(FILEIO *state_fio) -{ - if(state_entry != NULL) { - state_entry->save_state(state_fio); - } -} + state_fio->StateValue(max_sprite_per_frame); + state_fio->StateValue(tvram_enabled); + state_fio->StateValue(tvram_enabled_bak); + + state_fio->StateValue(event_busy); -bool TOWNS_SPRITE::load_state(FILEIO *state_fio) -{ - bool mb = false; - if(state_entry != NULL) { - mb = state_entry->load_state(state_fio); - this->out_debug_log(_T("Load State: SPRITE: id=%d stat=%s\n"), this_device_id, (mb) ? _T("OK") : _T("NG")); - if(!mb) return false; - } - // Post Process - build_sprite_table(); - // Render? - if(vram_head != NULL) { - write_page = vram_head->get_sprite_write_page(); - display_page = (write_page + 1) & 1; - // Restore cache buffer. - for(int i = 0; i < TOWNS_SPRITE_CACHE_NUM; i++) { - cache_index[i].pixels = &(cache_pixels[i][0]); - cache_index[i].masks = &(cache_masks[i][0]); - } - vram_buffer = vram_head->get_vram_buffer_sprite(write_page); - mask_buffer = vram_head->get_mask_buffer_sprite(write_page); - render(vram_buffer, mask_buffer); - } return true; } diff --git a/source/src/vm/fmtowns/towns_sprite.h b/source/src/vm/fmtowns/towns_sprite.h index e89a6068f..75958451a 100644 --- a/source/src/vm/fmtowns/towns_sprite.h +++ b/source/src/vm/fmtowns/towns_sprite.h @@ -1,487 +1,163 @@ -#ifndef _TOWNS_SPRITE_H_ -#define _TOWNS_SPRITE_H_ +#pragma once #include "../vm.h" #include "../../emu.h" #include "../device.h" -#define SIG_FMTOWNS_SPRITE_RENDER 256 -#define SIG_FMTOWNS_SPRITE_UPDATE_FRAMEBUFFER 257 -#define SIG_FMTOWNS_RENDER_SPRITE_CHANGE_BANK 258 -#define SIG_FMTOWNS_RENDER_SPRITE_ENABLED 259 -#define SIG_FMTOWNS_RENDER_SPRITE_RESET 260 -#define SIG_FMTOWNS_RENDER_SPRITE_SET_LIMIT 261 -#define SIG_FMTOWNS_RENDER_SPRITE_SET_NUM 262 -#define SIG_FMTOWNS_RENDER_SPRITE_CLEAR_VRAM 263 - - -namespace FMTOWNS { - enum { - ROT_FMTOWNS_SPRITE_0 = 0, - ROT_FMTOWNS_SPRITE_90, - ROT_FMTOWNS_SPRITE_180, - ROT_FMTOWNS_SPRITE_270 - }; -} - -#define TOWNS_SPRITE_CACHE_NUM 512 - -namespace FMTOWNS { - typedef struct { - uint16_t num; - uint8_t rotate_type; - uint16_t attribute; - uint16_t color; - - bool is_halfx; - bool is_halfy; - bool enable_offset; - bool is_32768; - bool is_impose; - bool is_disp; - } sprite_table_t; - - typedef struct { - bool is_use; - uint16_t num; - uint16_t attribute; - uint8_t rotate_type; - bool is_32768; - bool is_halfx; - bool is_halfy; - uint16_t* pixels; - uint16_t* masks; - uint16_t color; - } sprite_cache_t; -} - +#define SIG_TOWNS_SPRITE_HOOK_VLINE 256 +#define SIG_TOWNS_SPRITE_SET_LINES 257 +#define SIG_TOWNS_SPRITE_TVRAM_ENABLED 258 +//#define SIG_TOWNS_SPRITE_ANKCG 259 +#define SIG_TOWNS_SPRITE_ENABLED 262 +#define SIG_TOWNS_SPRITE_BUSY 263 +#define SIG_TOWNS_SPRITE_DISP_PAGE0 264 +#define SIG_TOWNS_SPRITE_DISP_PAGE1 265 +// Belows are reserved values. +#define SIG_TOWNS_SPRITE_CALL_HSYNC 266 +#define SIG_TOWNS_SPRITE_CALL_VSTART 267 +#define SIG_TOWNS_SPRITE_RENDER_ENABLED 268 +#define SIG_TOWNS_SPRITE_PEEK_TVRAM 0x00010000 namespace FMTOWNS { class TOWNS_VRAM; } +class DEBUGGER; namespace FMTOWNS { class TOWNS_SPRITE : public DEVICE { protected: - TOWNS_VRAM *vram_head; - uint16_t* vram_buffer; // uint16_t[256][256] - uint16_t* mask_buffer; // uint16_t[256][256] + TOWNS_VRAM *d_vram; + DEVICE *d_font; + DEVICE *d_crtc; + DEBUGGER *d_debugger; // REGISTERS uint8_t reg_addr; uint8_t reg_data[8]; // #0, #1 + uint16_t reg_ctrl; + bool reg_spen; uint16_t reg_index; + uint8_t pattern_ram[0x20000]; +// uint8_t ram[0x3000]; uint16_t reg_voffset; uint16_t reg_hoffset; bool disp_page0; bool disp_page1; - uint8_t display_page; - uint8_t write_page; - int render_num; - int render_mod; - int render_lines; - bool split_rendering; - - uint16_t index_ram[4096]; // 1024 * 4 - uint16_t color_ram[4096]; // 16 * 256 - uint8_t pattern_ram[(65536 - (4096 * 2)) * 2]; - - bool pattern_cached[((65536 - (4096 * 2)) * 2) / (8 * 16)]; - bool color_cached[256]; + bool draw_page1; bool sprite_enabled; - bool use_cache; - int32_t last_put_cache_num; - - sprite_table_t sprite_table[1024]; - sprite_cache_t cache_index[TOWNS_SPRITE_CACHE_NUM]; - uint16_t cache_pixels[TOWNS_SPRITE_CACHE_NUM][16 * 16]; - uint16_t cache_masks[TOWNS_SPRITE_CACHE_NUM][16 * 16]; + bool sprite_busy; + bool page_changed; - inline void take_data_32768(uint16_t* src, uint16_t* dst, uint16_t* mask); - inline void take_data_32768_mirror(uint16_t* src, uint16_t* dst, uint16_t* mask); - inline void take_data_16(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask); - inline void take_data_16_mirror(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask); - inline void zoom_data(uint16_t* cache, uint16_t* maskcache, bool is_halfx, bool is_halfy, uint16_t* dstcache, uint16_t* dstmask); + int render_num; + int max_sprite_per_frame; - void rotate_data_0(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy); - void rotate_data_90(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy); - void rotate_data_180(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy); - void rotate_data_270(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy); + bool tvram_enabled; + bool tvram_enabled_bak; - void clear_cache(int num); - void build_sprite_table(void); + bool ankcg_enabled; + int event_busy; - void set_sprite_attribute(int table_num, uint16_t num_attr); - void set_sprite_color(int table_num, uint16_t color_table_num); - bool check_cache(int num, sprite_cache_t** p); - void render_zoomed_pixels(int x, int y, int uint16_t* pixels, uint16_t* masks, bool is_halfx, bool is_halfy, uint16_t* dst_pixel, uint16_t* dst_mask); - void render_sprite(int num, uint16* dst_pixel, uint16_t* dst_mask, int x, int y); - void render(uint16_t *buffer, uint16_t* mask); + void __FASTCALL render_sprite(int num, int x, int y, uint16_t attr, uint16_t color); + void render_part(); + virtual void __FASTCALL write_reg(uint32_t addr, uint32_t data); + void check_and_clear_vram(); public: - TOWNS_SPRITE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + TOWNS_SPRITE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + d_vram = NULL; + d_font = NULL; + d_crtc = NULL; set_device_name(_T("SPRITE")); - vram_head = NULL; - framebuffer = NULL; - } ~TOWNS_SPRITE() {} - void write_io8(uint32_t addr, uint32_t data); - uint32_t read_io8(uint32_t addr); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); - void write_data8(uint32_t addr, uint32_t data); - void write_data16(uint32_t addr, uint32_t data); - void write_data32(uint32_t addr, uint32_t data); - - uint32_t read_data8(uint32_t addr); - uint32_t read_data16(uint32_t addr); - uint32_t read_data32(uint32_t addr); - - void reset(); - void write_signal(int id, uint32_t data, uint32_t mask); - void initialize(); - void event_frame(); - void event_vline(int v, int clock); - - void set_context_vram(TOWNS_VRAM *p) + void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + uint32_t __FASTCALL read_via_debugger_data8(uint32_t addr) { - vram_head = p; - } - void save_state(FILEIO *fio); - bool load_stste(FILEIO *fio); -}; - -inline void TOWNS_SPRITE::take_data_32768(uint16_t* src, uint16_t* dst, uint16_t* mask) -{ - uint16_t* p = src; - uint16_t* q = dst; - uint16_t* r = mask; - for(int y = 0; y < 16; y++) { - for(int x = 0; x < 16; x++) { - q[x] = p[x]; - } - for(int x = 0; x < 16; x++) { - r[x] = ((q[x] & 0x8000) != 0) ? 0 : 0xffff; + if(addr >= 0x20000) { + return 0x00; } - r += 16; - q += 16; - p += 16; + return pattern_ram[addr]; } -} - -inline void TOWNS_SPRITE::take_data_32768_mirror(uint16_t* src, uint16_t* dst, uint16_t* mask) -{ - uint16_t* p = src; - uint16_t* q = dst; - uint16_t* r = mask; - for(int y = 0; y < 16; y++) { - for(int x = 0; x < 16; x++) { - q[x] = p[15 - x]; + void __FASTCALL write_via_debugger_data8(uint32_t addr, uint32_t data) + { + if(addr >= 0x20000) { + return; } - for(int x = 0; x < 16; x++) { - r[x] = ((q[x] & 0x8000) != 0) ? 0 : 0xffff; + if(addr < 0x1000) { + tvram_enabled = true; + tvram_enabled_bak = true; + } else if((addr >= 0x2000) && (addr < 0x3000)) { + tvram_enabled = true; + tvram_enabled_bak = true; } - r += 16; - q += 16; - p += 16; + pattern_ram[addr] = (uint8_t)data; } -} - - -inline void TOWNS_SPRITE::take_data_16(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask) -{ - uint8_t* p = src; - uint16_t* q = dst; - uint16_t* r = mask; - uint8_t cache[16]; - for(int y = 0; y < 16; y++) { - for(int x = 0; x < 16; x += 2) { - cache[x] = p[x >> 1]; - cache[x + 1] = cache[x]; - } - for(int x = 0; x < 16; x += 2) { - cache[x] = cache[x] >> 4; - } - for(int x = 0; x < 16; x++) { - cache[x] = cache[x] & 0x0f; - r[x] = (cache[x] == 0) ? 0x0000 : 0xffff; - q[x] = color_table[cache[x]]; - } - r += 16; - q += 16; - p += 8; + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + bool write_debug_reg(const _TCHAR *reg, uint32_t data); + uint32_t __FASTCALL read_debug_data8(uint32_t addr) + { + return read_via_debugger_data8(addr); } -} - -inline void TOWNS_SPRITE::take_data_16_mirror(uint8_t* src, uint16_t* color_table, uint16_t* dst, uint16_t* mask) -{ - uint8_t* p = src; - uint16_t* q = dst; - uint16_t* r = mask; - uint8_t cache[16]; - for(int y = 0; y < 16; y++) { - for(int x = 0; x < 16; x += 2) { - cache[x] = p[(15 - x) >> 1]; - cache[x + 1] = cache[x]; - } - for(int x = 1; x < 16; x += 2) { - cache[x] = cache[x] >> 4; - } - for(int x = 0; x < 16; x++) { - cache[x] = cache[x] & 0x0f; - r[x] = (cache[x] == 0) ? 0x0000 : 0xffff; - q[x] = color_table[cache[x]]; - } - r += 16; - q += 16; - p += 8; + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data) + { + write_via_debugger_data8(addr, data); + } + + bool is_debugger_available() + { + return true; + } + void *get_debugger() + { + return d_debugger; + } + uint64_t get_debug_data_addr_space() + { + return 0x20000; } -} + void reset(); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_signal(int id); + void initialize(); + void event_pre_frame(); + void event_vline(int v, int clk); + void __FASTCALL event_callback(int id, int err); -void TOWNS_SPRITE::rotate_data_0(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy) -{ - uint16_t cache[16 * 16]; - if(!is_32768) { - if(is_mirror) { - take_data_16_mirror(src, color_table, cache, mask); - } else { - take_data_16(src, color_table, cache, mask); - } - - } else { - if(is_mirror) { - take_data_32768_mirror((uint16_t*)src, cache, mask); - } else { - take_data_16((uint16_t*)src, cache, mask); - } + bool process_state(FILEIO* state_fio, bool loading); + + void set_context_vram(TOWNS_VRAM *p) + { + d_vram = p; } - // Rotate - // Zoom - uint16_t maskcache[16 * 16]; - memcpy(maskcache, mask, sizeof(maskcache)); - zoom_data(cache, maskcache, is_halfx, is_halfy, dstcache, mask); -} - -void TOWNS_SPRITE::rotate_data_90(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy) -{ - uint16_t cache[16 * 16]; - if(!is_32768) { - if(is_mirror) { - take_data_16_mirror(src, color_table, cache, mask); - } else { - take_data_16(src, color_table, cache, mask); - } - - } else { - if(is_mirror) { - take_data_32768_mirror((uint16_t*)src, cache, mask); - } else { - take_data_16((uint16_t*)src, cache, mask); - } + void set_context_font(DEVICE *p) + { + d_font = p; } - // Rotate - uint16_t maskcache[16][16]; - uint16_t cache2[16][16]; - if(is_mirror) { - // q[x][y] = p[15 - y][15 - x] -__DECL_VECTORIZED_LOOP - for(y = 0; y < 16; y++) { - uint16_t* p = &(cache[15 - y]); - uint16_t* q = &(mask[15 - y]); - for(x = 0; x < 16; x++) { - cache2[y][x] = p[(15 - x) << 4]; - maskcache[y][x] = q[(15 - x) << 4]; - } - } - } else { - // q[x][y] = p[15 - y][x] - for(y = 0; y < 16; y++) { - uint16_t* p = &(cache[15 - y]); - uint16_t* q = &(mask[15 - y]); -__DECL_VECTORIZED_LOOP - for(x = 0; x < 16; x++) { - cache2[y][x] = p[x << 4]; - maskcache[y][x] = q[x << 4]; - } - } - } - zoom_data((uint16_t*)(&(cache2[0][0])), (uint16_t*)(&(maskcache[0][0])), is_halfx, is_halfy, dstcache, mask); -} - -void TOWNS_SPRITE::rotate_data_180(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768, bool is_halfx, bool is_halfy) -{ - uint16_t cache[16 * 16]; - if(!is_32768) { - if(is_mirror) { - take_data_16_mirror(src, color_table, cache, mask); - } else { - take_data_16(src, color_table, cache, mask); - } - - } else { - if(is_mirror) { - take_data_32768_mirror((uint16_t*)src, cache, mask); - } else { - take_data_16((uint16_t*)src, cache, mask); - } + void set_context_crtc(DEVICE *p) + { + d_crtc = p; } - // Rotate - uint16_t maskcache[16][16]; - uint16_t cache2[16][16]; - if(is_mirror) { - // q[x][y] = p[x][15 - y] - for(y = 0; y < 16; y++) { - uint16_t* p = &(cache[(15 - y) << 4]); - uint16_t* q = &(mask[(15 - y) << 4]); -__DECL_VECTORIZED_LOOP - for(x = 0; x < 16; x++) { - cache2[y][x] = p[x]; - maskcache[y][x] = q[x]; - } - } - } else { - // q[x][y] = p[15 - x][15 - y] - for(y = 0; y < 16; y++) { - uint16_t* p = &(cache[15 - y] << 4); - uint16_t* q = &(mask[15 - y] << 4); -__DECL_VECTORIZED_LOOP - for(x = 0; x < 16; x++) { - cache2[y][x] = p[15 - x]; - maskcache[y][x] = q[15 - x]; - } - } - } - zoom_data((uint16_t*)(&(cache2[0][0])), (uint16_t*)(&(maskcache[0][0])), is_halfx, is_halfy, dstcache, mask); -} - -void TOWNS_SPRITE::rotate_data_270(uint16_t* src, bool is_mirror, uint16_t* color_table, uint16_t* dstcache, uint16_t* mask, bool is_32768,bool is_halfx, bool is_halfy) -{ - uint16_t cache[16 * 16]; - if(!is_32768) { - if(is_mirror) { - take_data_16_mirror(src, color_table, cache, mask); - } else { - take_data_16(src, color_table, cache, mask); - } - - } else { - if(is_mirror) { - take_data_32768_mirror((uint16_t*)src, cache, mask); - } else { - take_data_16((uint16_t*)src, cache, mask); - } + void set_context_debugger(DEBUGGER *p) + { + d_debugger = p; } - // Rotate - uint16_t maskcache[16][16]; - uint16_t cache2[16][16]; - if(is_mirror) { - // q[x][y] = p[y][x] - - for(y = 0; y < 16; y++) { - uint16_t* p = &(cache[y]); - uint16_t* q = &(mask[y]); -__DECL_VECTORIZED_LOOP - for(x = 0; x < 16; x++) { - cache2[y][x] = p[x << 4]; - maskcache[y][x] = q[x << 4]; - } - } - } else { - // q[x][y] = p[y][15 - x] - for(y = 0; y < 16; y++) { - uint16_t* p = &(cache[15 - y]); - uint16_t* q = &(mask[15 - y]); -__DECL_VECTORIZED_LOOP - for(x = 0; x < 16; x++) { - cache2[y][x] = p[x << 4]; - maskcache[y][x] = q[x << 4]; - } - } - } - zoom_data((uint16_t*)(&(cache2[0][0])), (uint16_t*)(&(maskcache[0][0])), is_halfx, is_halfy, dstcache, mask); -} - -inline void TOWNS_SPRITE::zoom_data(uint16_t* cache, uint16_t* maskcache, bool is_halfx, bool is_halfy, uint16_t* dstcache, uint16_t* dstmask) -{ - if(is_halfx) { - if(is_halfy) { - uint16_t cache2[8][8]; - uint16_t maskcache2[8][8]; - for(int y = 0; y < 16; y += 2) { - uint16_t cacheline[8]; - uint16_t *pp = &(cache[y << 4]); - uint16_t maskcacheline[8]; - uint16_t *pq = &(maskcache[y << 4]); -__DECL_VECTORIZED_LOOP - for(int x = 0; x < 8; x++) { - cacheline[x] = pp[x << 1]; - maskcacheline[x] = pq[x << 1]; - } -__DECL_VECTORIZED_LOOP - for(int x = 0; x < 8; x++) { - cache2[y >> 1][x] = cacheline[x]; - maskcache2[y >> 1][x] = maskcacheline[x]; - } - } - memcpy(dstcache, &(cache2[0][0]), 8 * 8 * sizeof(uint16_t)); - memcpy(dstmask, &(maskcache2[0][0]), 8 * 8 * sizeof(uint16_t)); - } else { // halfx only, not halfy - uint16_t cache2[16][8]; - uint16_t maskcache2[16][8]; - for(int y = 0; y < 16; y++) { - uint16_t cacheline[8]; - uint16_t *pp = &(cache[y << 4]); - uint16_t maskcacheline[8]; - uint16_t *pq = &(maskcache[y << 4]); -__DECL_VECTORIZED_LOOP - for(int x = 0; x < 8; x++) { - cacheline[x] = pp[x << 1]; - maskcacheline[x] = pq[x << 1]; - } -__DECL_VECTORIZED_LOOP - for(int x = 0; x < 8; x++) { - cache2[y][x] = cacheline[x]; - maskcache2[y][x] = maskcacheline[x]; - } - } - memcpy(dstcache, &(cache2[0][0]), 16 * 8 * sizeof(uint16_t)); - memcpy(mask, &(maskcache2[0][0]), 16 * 8 * sizeof(uint16_t)); - } - } else { - if(is_halfy) { // halfx only, not halfx - uint16_t cache2[16][8]; - uint16_t maskcache2[16][8]; - for(int y = 0; y < 16; y += 2) { - uint16_t cacheline[16]; - uint16_t *pp = &(cache[y << 4]); - uint16_t maskcacheline[16]; - uint16_t *pq = &(maskcache[y << 4]); -__DECL_VECTORIZED_LOOP - for(int x = 0; x < 16; x++) { - cacheline[x] = pp[x]; - maskcacheline[x] = pq[x]; - } -__DECL_VECTORIZED_LOOP - for(int x = 0; x < 16; x++) { - cache2[y >> 1][x] = cacheline[x]; - maskcache2[y >> 1][x] = maskcacheline[x]; - } - } - memcpy(dstcache, &(cache2[0][0]), 8 * 16 * sizeof(uint16_t)); - memcpy(dstmask, &(maskcache2[0][0]), 8 * 16 * sizeof(uint16_t)); - } else { // 1x1 - memcpy(dstcache, cache, 16 * 16 * sizeof(uint16_t)); - memcpy(dstmask, maskcache, 16 * 16 * sizeof(uint16_t)); + void get_tvram_snapshot(uint8_t *p) + { + if(p != NULL) { + memcpy(&(p[0x0000]), &(pattern_ram[0x0000]), 0x4000); } } +}; } -} - -#endif /* _TOWNS_SPRITE_H */ diff --git a/source/src/vm/fmtowns/towns_sysrom.cpp b/source/src/vm/fmtowns/towns_sysrom.cpp index 1af10fc09..ec5c718d9 100644 --- a/source/src/vm/fmtowns/towns_sysrom.cpp +++ b/source/src/vm/fmtowns/towns_sysrom.cpp @@ -4,95 +4,98 @@ Author : Kyuma.Ohta Date : 2019.01.09- - [ system rom & RAM area 0x000f0000 - 0x000fffff] + [ SYSTEM rom & RAM area 0x000f8000 - 0x000fffff] + * MEMORY : + * 0x000f8000 - 0x000fffff : RAM / DICTIONARY (BANKED) + * 0xfffc0000 - 0xffffffff : SYSTEM ROM + * I/O : + * 0x0480 : F8 BANK */ +#include "./towns_common.h" #include "./towns_sysrom.h" +#include "./towns_dictionary.h" #include "../../fileio.h" namespace FMTOWNS { void SYSROM::initialize() { memset(rom, 0xff, sizeof(rom)); - memset(ram, 0x00, sizeof(ram)); FILEIO* fio = new FILEIO(); if(fio->Fopen(create_local_path(_T("FMT_SYS.ROM")), FILEIO_READ_BINARY)) { // DICTIONARIES fio->Fread(rom, sizeof(rom), 1); fio->Fclose(); } - map_dos = true; + } void SYSROM::reset() { - //map_dos = true; } - -uint32_t SYSROM::read_data8(uint32_t addr) + +uint32_t SYSROM::read_memory_mapped_io8(uint32_t addr) { uint8_t n_data = 0xff; - if(addr < 0xfffc0000) { // Banked (from MSDOS/i86 compatible mode) + if(addr < 0xfffc0000) { // Banked (from MSDOS/i86 compatible mode) if((addr >= 0x000f8000) && (addr < 0x00100000)) { - if(map_dos) { - n_data = rom[(addr & 0x7fff) + 0x38000]; - } else { - n_data = ram[addr & 0xffff]; - } - } else if((addr >= 0x000f0000) && (addr < 0x00100000)) { - n_data = ram[addr & 0xffff]; + n_data = rom[(addr & 0x7fff) + 0x38000]; } } else { n_data = rom[addr & 0x3ffff]; } return (uint32_t)n_data; } - -void SYSROM::write_data8(uint32_t addr, uint32_t data) + +uint32_t SYSROM::read_memory_mapped_io16(uint32_t addr) { - if(addr < 0xfffc0000) { - if((addr >= 0x000f8000) && (addr < 0x00100000)) { - if(!(map_dos)) { - ram[addr & 0xffff] = (uint8_t)data; - } - } else if((addr >= 0x000f0000) && (addr < 0x00100000)) { - ram[addr & 0xffff] = (uint8_t)data; - } - } + pair16_t nd; + int dummy; + nd.w = 0x00; + // OK? + nd.b.l = read_memory_mapped_io8(addr + 0); + nd.b.h = read_memory_mapped_io8(addr + 1); + return nd.w; } -void SYSROM::write_signal(int ch, uint32_t data, uint32_t mask) +uint32_t SYSROM::read_memory_mapped_io32(uint32_t addr) { - switch(ch) { - case SIG_FMTOWNS_SYSROMSEL: - map_dos = ((data & mask) == 0); - break; - } + pair32_t nd; + nd.d = 0x00; + // OK? + nd.b.l = read_memory_mapped_io8(addr + 0); + nd.b.h = read_memory_mapped_io8(addr + 1); + nd.b.h2 = read_memory_mapped_io8(addr + 2); + nd.b.h3 = read_memory_mapped_io8(addr + 3); + return nd.d; } - -uint32_t SYSROM::read_signal(int ch) + +void SYSROM::write_memory_mapped_io8(uint32_t addr, uint32_t data) { - switch(ch) { - case SIG_FMTOWNS_SYSROMSEL: - return ((map_dos) ? 0x00 : 0x02); - break; - } - return 0x00; + // ADDR >= 0xfffc0000 + return; } -#define STATE_VERSION 1 -bool SYSROM::process_state(FILEIO* state_fio, bool loading) +void SYSROM::write_memory_mapped_io16(uint32_t addr, uint32_t data) { - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - state_fio->StateValue(map_dos); - state_fio->StateArray(ram, sizeof(ram), 1); - return true; -} + pair16_t nd; + nd.w = (uint16_t)data; + // OK? + write_memory_mapped_io8(addr + 0, nd.b.l); + write_memory_mapped_io8(addr + 1, nd.b.h); +} + +void SYSROM::write_memory_mapped_io32(uint32_t addr, uint32_t data) +{ + pair32_t nd; + nd.d = data; + write_memory_mapped_io8(addr + 0, nd.b.l); + write_memory_mapped_io8(addr + 1, nd.b.h); + write_memory_mapped_io8(addr + 2, nd.b.h2); + write_memory_mapped_io8(addr + 3, nd.b.h3); +} + + } diff --git a/source/src/vm/fmtowns/towns_sysrom.h b/source/src/vm/fmtowns/towns_sysrom.h index b3b33d8f4..99b9c3d22 100644 --- a/source/src/vm/fmtowns/towns_sysrom.h +++ b/source/src/vm/fmtowns/towns_sysrom.h @@ -4,7 +4,15 @@ Author : Kyuma.Ohta Date : 2019.01.09- - [ SYSTEM rom & RAM area 0x000f0000 - 0x000fffff] + [ SYSTEM rom & RAM area 0x000f8000 - 0x000fffff] + * MEMORY : + * 0x000d0000 - 0x000d7fff : RAM / DICTIONARY (BANKED) + * 0x000d8000 - 0x000d9fff : RAM / CMOS + * 0x000da000 - 0x000dffff : RAM / RESERVED + * 0x000f8000 - 0x000fffff : RAM / SYSTEM + * 0xfffc0000 - 0xffffffff : SYSTEM ROM + * I/O : + * 0x0480 : F8 BANK */ #pragma once @@ -12,36 +20,32 @@ #include "common.h" #include "device.h" -#define SIG_FMTOWNS_SYSROMSEL 0x1000 +#define SIG_FMTOWNS_SYSROMSEL 1 +#define SIG_FMTOWNS_F8_DICTRAM 2 namespace FMTOWNS { - +class DICTIONARY; class SYSROM : public DEVICE { protected: uint8_t rom[0x40000]; // 256KB - uint8_t ram[0x10000]; // 64KB - bool map_dos; - public: - SYSROM(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { - set_device_name("FM-Towns SYSTEM ROM/RAM 0x000fxxxx"); + set_device_name("FM-Towns SYSTEM ROM"); } ~SYSROM() {} void initialize(); void reset(); - uint32_t read_data8(uint32_t addr); - - void write_data8(uint32_t addr, uint32_t data); - - void write_signal(int ch, uint32_t data, uint32_t mask); - uint32_t read_signal(int ch); - - bool process_state(FILEIO* state_fio, bool loading); - + uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr); + uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr); + void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data); + void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data); + }; } diff --git a/source/src/vm/fmtowns/towns_vram.cpp b/source/src/vm/fmtowns/towns_vram.cpp index ffad1e2a9..699c7c4f9 100644 --- a/source/src/vm/fmtowns/towns_vram.cpp +++ b/source/src/vm/fmtowns/towns_vram.cpp @@ -8,10 +8,14 @@ History: 2017.01.16 Initial. */ + #include "common.h" +#include "./towns_common.h" +#include "./towns_crtc.h" #include "./towns_vram.h" +#include "./towns_planevram.h" -#define CLEAR_COLOR RGBA_COLOR(0,0,0,0) +#define _CLEAR_COLOR RGBA_COLOR(0,0,0,0) #if defined(_RGB888) #define _USE_ALPHA_CHANNEL @@ -21,828 +25,519 @@ namespace FMTOWNS { void TOWNS_VRAM::initialize() { - for(int i = 0; i < 32768; i++) { - uint8_t g = (i / (32 * 32)) & 0x1f; - uint8_t r = (i / 32) & 0x1f; - uint8_t b = i & 0x1f; - table_32768c[i] = RGBA_COLOR(r << 3, g << 3, b << 3, 0xff); - table_32768c[i + 32768] = table_32768c[i]; - alpha_32768c[i] = RGBA_COLOR(255, 255, 255, 255); - alpha_32768c[i + 32768] = RGBA_COLOR(0, 0, 0, 0); - mask_32768c[i] = 0xffff; - mask_32768c[i + 32768] = 0x0000; - } - for(int i = 0; i < 256; i++) { - int chigh = i & 0xf0; - int clow = i & 0x0f; - uint8_t alpha; - alpha_16c[ i << 2 ] = (chigh == 0) ? RGBA_COLOR(0, 0, 0, 0) : RGBA_COLOR(255, 255, 255, 255); - alpha_16c[(i << 2) + 1] = (clow == 0) ? RGBA_COLOR(0, 0, 0, 0) : RGBA_COLOR(255, 255, 255, 255); - mask_16c[i] = ((chigh == 0) ? 0x00: 0xf0) | ((clow == 0) ? 0x00 : 0x0f); - } - for(int i = 0; i < TOWNS_CRTC_MAX_LINES; i++) { - line_rendered[0][i] = false; - line_rendered[1][i] = false; - } - + memset(vram, 0x00, sizeof(vram)); } -void TOWNS_VRAM::write_memory_mapped_io8(uint32_t addr, uint32_t data) +void TOWNS_VRAM::reset() { - uint32_t naddr = addr & 0xfff80000; - switch(naddr) { - case 0x80000000: - case 0x80100000: - // ToDo: Upper 0x80x80000 - // Main VRAM - write_raw_vram8(addr, data); - return; - break; - case 0x00080000: - switch(addr & 0x000ff000) { - case 0xc0000: - case 0xc1000: - case 0xc2000: - case 0xc3000: - case 0xc4000: - case 0xc5000: - case 0xc6000: - case 0xc7000: - write_plane_data8(addr, data); // Plane access by I/O FF81h - return; - break; - case 0xc8000: - case 0xc9000: - case 0xca000: - case 0xcb000: - case 0xcc000: - case 0xcd000: - case 0xce000: - case 0xcf000: - // Reserved - if((addr < 0xcff80) && (addr >= 0xcff88)) { - d_sprite->write_data8(addr & 0x7fff, data); - } else { - write_mmio8(addr, data); - } - break; - default: - return; - break; - } - break; - default: - return; - break; - } + for(int i = 0; i < (sizeof(dirty_flag) / sizeof(bool)); i++) { + dirty_flag[i] = true; + } + packed_pixel_mask_reg.d = 0xffffffff; + vram_access_reg_addr = 0; + sprite_busy = false; + sprite_disp_page = false; + layer_display_flags[0] = layer_display_flags[1] = 0; } - -void TOWNS_VRAM::write_memory_mapped_io16(uint32_t addr, uint32_t data) + +void TOWNS_VRAM::make_dirty_vram(uint32_t addr, int bytes) { - uint32_t naddr = addr & 0xfff80000; - switch(naddr) { - case 0x80000000: - case 0x80100000: - // ToDo: Upper 0x80x80000 - // Main VRAM - write_raw_vram16(addr, data); - return; + uint32_t amask = 0x7ffff; + uint32_t naddr1 = (addr & amask) >> 3; + switch(bytes) { + case 1: + dirty_flag[naddr1] = true; break; - case 0x00080000: - switch(addr & 0x000ff000) { - case 0xc0000: - case 0xc1000: - case 0xc2000: - case 0xc3000: - case 0xc4000: - case 0xc5000: - case 0xc6000: - case 0xc7000: - write_plane_data16(addr, data); // Plane access by I/O FF81h - return; - break; - case 0xc8000: - case 0xc9000: - case 0xca000: - case 0xcb000: - case 0xcc000: - case 0xcd000: - case 0xce000: - case 0xcf000: - // Reserved - if((addr < (0xcff80 - 1)) && (addr >= 0xcff88)) { - d_sprite->write_data16(addr & 0x7fff, data); - } else { - pair16_t d; - d.2 = data; - write_mmio8(addr, d.b.l); - write_mmio8(addr + 1, d.b.h); - } - break; - default: - return; - break; + case 2: + case 3: + case 4: + { + uint32_t naddr2 = ((addr + bytes - 1) & amask) >> 3; + dirty_flag[naddr1] = true; + dirty_flag[naddr2] = true; } break; - default: - return; - break; - } - + } } void TOWNS_VRAM::write_memory_mapped_io8(uint32_t addr, uint32_t data) { - uint32_t naddr = addr & 0xfff80000; - switch(naddr) { - case 0x80000000: - case 0x80100000: - // ToDo: Upper 0x80x80000 - // Main VRAM - write_raw_vram32(addr, data); - return; - break; - case 0x00080000: - switch(addr & 0x000ff000) { - case 0xc0000: - case 0xc1000: - case 0xc2000: - case 0xc3000: - case 0xc4000: - case 0xc5000: - case 0xc6000: - case 0xc7000: - write_plane_data32(addr, data); // Plane access by I/O FF81h - return; - break; - case 0xc8000: - case 0xc9000: - case 0xca000: - case 0xcb000: - case 0xcc000: - case 0xcd000: - case 0xce000: - case 0xcf000: - // Reserved - if((addr < (0xcff80 - 3)) && (addr >= 0xcff88)) { - d_sprite->write_data32(addr & 0x7fff, data); - } else { - pair32_t d; - d.d = data; - write_mmio8(addr, d.b.l); - write_mmio8(addr + 1, d.b.h); - write_mmio8(addr + 2, d.b.h2); - write_mmio8(addr + 3, d.b.h3); - } - break; - default: - return; - break; - } - break; - default: - return; - break; - } - + __DECL_ALIGNED(8) uint8_t mask[4]; + packed_pixel_mask_reg.write_4bytes_le_to(mask); + uint8_t rmask = mask[addr & 3]; + uint32_t naddr = addr & 0x7ffff; + uint8_t nd = vram[naddr]; + data = data & rmask; + nd = nd & ~rmask; + vram[naddr] = nd | data; } -uint32_t TOWNS_VRAM::read_memory_mapped_io8(uint32_t addr) +void TOWNS_VRAM::write_memory_mapped_io16(uint32_t addr, uint32_t data) { - uint32_t naddr = addr & 0xfff80000; - switch(naddr) { - case 0x80000000: - case 0x80100000: - // ToDo: Upper 0x80x80000 - // Main VRAM - return read_raw_vram8(addr); - break; - case 0x00080000: - switch(addr & 0x000ff000) { - case 0xc0000: - case 0xc1000: - case 0xc2000: - case 0xc3000: - case 0xc4000: - case 0xc5000: - case 0xc6000: - case 0xc7000: - // Plane access by I/O FF81h - return read_plane_data8(addr); // Plane access by I/O FF81h - break; - case 0xc8000: - case 0xc9000: - case 0xca000: - case 0xcb000: - case 0xcc000: - case 0xcd000: - case 0xce000: - case 0xcf000: - // Reserved - if((addr < 0xcff80) && (addr >= 0xcff88)) { - return d_sprite->read_data8(addr & 0x7fff); - } else { - return read_mmio8(addr); - } - break; - default: - return 0xff; - } - break; - default: - return 0xff; - break; - } -} + uint32_t naddr1 = addr & 0x7ffff; + uint32_t naddr2 = (addr + 1) & 0x7ffff;; + pair16_t nd, md; + pair16_t xmask; -uint32_t TOWNS_VRAM::read_memory_mapped_io16(uint32_t addr) -{ - uint32_t naddr = addr & 0xfff80000; - switch(naddr) { - case 0x80000000: - case 0x80100000: - // ToDo: Upper 0x80x80000 - // Main VRAM - return read_raw_vram16(addr); - break; - case 0x00080000: - switch(addr & 0x000ff000) { - case 0xc0000: - case 0xc1000: - case 0xc2000: - case 0xc3000: - case 0xc4000: - case 0xc5000: - case 0xc6000: - case 0xc7000: - // Plane access by I/O FF81h - return read_plane_data16(addr); // Plane access by I/O FF81h - break; - case 0xc8000: - case 0xc9000: - case 0xca000: - case 0xcb000: - case 0xcc000: - case 0xcd000: - case 0xce000: - case 0xcf000: - // Reserved - if((addr < (0xcff80 - 1)) && (addr >= 0xcff88)) { - return d_sprite->read_data16(addr & 0x7fff); - } else { - pair16_t d; - d.l = read_mmio8(addr); - d.h = read_mmio8(addr + 1); - return d.w; - } - break; - default: - return 0xffff; - } - break; - default: - return 0xffff; + switch(naddr1 & 3) { + case 0: + xmask.w = packed_pixel_mask_reg.w.l; break; - } - return 0xffff; -} - -uint32_t TOWNS_VRAM::read_memory_mapped_io32(uint32_t addr) -{ - uint32_t naddr = addr & 0xfff80000; - switch(naddr) { - case 0x80000000: - case 0x80100000: - // ToDo: Upper 0x80x80000 - // Main VRAM - return read_raw_vram32(addr); + case 1: + xmask.b.l = packed_pixel_mask_reg.b.h; + xmask.b.h = packed_pixel_mask_reg.b.h2; break; - case 0x00080000: - switch(addr & 0x000ff000) { - case 0xc0000: - case 0xc1000: - case 0xc2000: - case 0xc3000: - case 0xc4000: - case 0xc5000: - case 0xc6000: - case 0xc7000: - // Plane access by I/O FF81h - return read_plane_data32(addr); // Plane access by I/O FF81h - break; - case 0xc8000: - case 0xc9000: - case 0xca000: - case 0xcb000: - case 0xcc000: - case 0xcd000: - case 0xce000: - case 0xcf000: - // Reserved - if((addr < (0xcff80 - 3)) && (addr >= 0xcff88)) { - return d_sprite->read_data16(addr & 0x7fff); - } else { - pair32_t d; - d.l = read_mmio8(addr); - d.h = read_mmio8(addr + 1); - d.h2 = read_mmio8(addr + 2); - d.h3 = read_mmio8(addr + 3); - return d.d; - } - break; - default: - return 0xffffffff; - } + case 2: + xmask.w = packed_pixel_mask_reg.w.h; break; - default: - return 0xffffffff; + case 3: + xmask.b.l = packed_pixel_mask_reg.b.h3; + xmask.b.h = packed_pixel_mask_reg.b.l; +// if((addr == 0x8003ffff) || (addr == 0x8007ffff)) { // Wrap1 +// naddr2 = (addr == 0x8003ffff) ? 0x00000 : 0x40000; +// } else if(addr == 0x8017ffff) { // wrap 2 +// naddr2 = 0x00000; +// } break; - } - return 0xffffffff; -} - -uint32_t TOWNS_VRAM::read_raw_vram8(uint32_t addr) -{ - return vram[addr]; -} - -uint32_t TOWNS_VRAM::read_raw_vram16(uint32_t addr) -{ - pair16_t a; - bool is_wrap = false; - uint32_t wrap_addr; - if((addr & 0x3ffff) == 0x3ffff) { - if(addr != 0x8013ffff) { - is_wrap = true; - wrap_addr = (addr == 0x8007ffff) ? 0x40000 : 0; - } } - addr = addr & 0x7ffff; - if(is_wrap) { - pair16_t a; - a.b.l = vram[addr]; - a.b.h = vram[wrap_addr]; - } else { -#ifdef __LITTLE_ENDIAN__ - // SAME endian - uint16_t* p = (uint16_t *)(&vram[addr]); - a.w = *p; -#else - a.read_2bytes_le_from(&vram[addr]); -#endif - } - return (uint32_t)(a.w); -} -uint32_t TOWNS_VRAM::read_raw_vram32(uint32_t addr) -{ - pair32_t a; - bool is_wrap = false; - uint32_t wrap_addr = 0; - uint32_t wrap_mask; - - if((addr & 0x3ffff) > 0x3fffc) { - if((addr < 0x8013fffd) && (addr > 0x8013ffff)) { - is_wrap = true; - wrap_addr = ((addr <= 0x8007ffff) && (addr > 0x8007fffc)) ? 0x40000 : 0; - wrap_mask = (addr >= 0x80100000) ? 0x7ffff : 0x3ffff; - } - } - addr = addr & 0x7ffff; - if(is_wrap) { - a.b.l = vram[addr]; - a.b.h = vram[((addr + 1) & wrap_mask) | wrap_addr]; - a.b.h2 = vram[((addr + 2) & wrap_mask) | wrap_addr]; - a.b.h3 = vram[((addr + 3) & wrap_mask) | wrap_addr]; + if(naddr1 == 0x7ffff) { // Wrap + nd.w = (uint16_t)data; + md.b.l = vram[naddr1]; + nd.w = nd.w & xmask.w; + md.w = md.w & ~(xmask.w); + md.w = md.w | nd.w; + vram[naddr1] = md.b.l; } else { -#ifdef __LITTLE_ENDIAN__ - uint32_t* p = (uint32_t)(&vram[addr]); - a.d = *p; -#else - a.read_4bytes_le_from(&vram[addr]); -#endif + md.read_2bytes_le_from(&(vram[naddr1])); + + nd.w = (uint16_t)data; + + nd.w = nd.w & xmask.w; + md.w = md.w & ~(xmask.w); + md.w = md.w | nd.w; + + md.write_2bytes_le_to(&(vram[naddr1])); } - return a.d; + return; } - -void TOWNS_VRAM::write_raw_vram8(uint32_t addr, uint32_t data) + +void TOWNS_VRAM::write_memory_mapped_io32(uint32_t addr, uint32_t data) { - uint8_t mask; - uint8_t d1; - uint8_t d2; - uint8_t d3; - switch(addr & 0x03) { + + __DECL_ALIGNED(8) uint8_t mask[4]; + uint32_t naddr = addr & 0x7ffff; + pair32_t nd, md; + pair32_t xmask; + + nd.d = data; + switch(naddr & 3) { case 0: - mask = packed_pixel_mask_reg.b.l; + xmask.d = packed_pixel_mask_reg.d; break; case 1: - mask = packed_pixel_mask_reg.b.h; + xmask.b.l = packed_pixel_mask_reg.b.h; + xmask.b.h = packed_pixel_mask_reg.b.h2; + xmask.b.h2 = packed_pixel_mask_reg.b.h3; + xmask.b.h3 = packed_pixel_mask_reg.b.l; break; case 2: - mask = packed_pixel_mask_reg.b.h2; + xmask.b.l = packed_pixel_mask_reg.b.h2; + xmask.b.h = packed_pixel_mask_reg.b.h3; + xmask.b.h2 = packed_pixel_mask_reg.b.l; + xmask.b.h3 = packed_pixel_mask_reg.b.h; break; case 3: - mask = packed_pixel_mask_reg.b.h3; + xmask.b.l = packed_pixel_mask_reg.b.h3; + xmask.b.h = packed_pixel_mask_reg.b.l; + xmask.b.h2 = packed_pixel_mask_reg.b.h; + xmask.b.h3 = packed_pixel_mask_reg.b.h2; break; } - addr = addr & 0x7ffff; // ToDo - d1 = vram[addr]; - d2 = data; - if(mask != 0xff) { - d2 = d2 & mask; - d3 = d1 & ~(mask); - d2 = d2 | d3; - } - if(d1 != d2) { - make_dirty_vram(addr, 1); - vram[addr] = d2; - } -} - -void TOWNS_VRAM::write_raw_vram16(uint32_t addr, uint32_t data) -{ - pair16_t a; - pair16_t b; - pair16_t c; - uint16_t mask; - bool is_wrap = false; - uint32_t wrap_addr = 0; - mask = ((addr & 0x02) == 0) ? packed_pixel_mask_reg.w.l : packed_pixel_mask_reg.w.h; - a.w = data; - if((addr & 0x3ffff) == 0x3ffff) { - if(addr != 0x8013ffff) { - is_wrap = true; - wrap_addr = (addr == 0x8007ffff) ? 0x40000 : 0; - } - } - addr = addr & 0x7ffff; - if(is_wrap) { - b.b.l = vram[addr]; - b.b.h = vram[wrap_addr]; - c.w = b.w; - if(mask != 0xffff) { - b.w = b.w & ~(mask); - a.w = a.w & mask; - a.w = a.w | b.w; - } - if(a.w != c.w) { - make_dirty_vram(addr, 1); - make_dirty_vram(wrap_addr, 1); - vram[addr] = a.b.l; - vram[wrap_addr] = a.b.h; + if((addr & 3) != 0) { + if(naddr <= 0x7fffc) { + md.read_4bytes_le_from(&(vram[naddr])); + nd.d = nd.d & xmask.d; + md.d = md.d & ~(xmask.d); + md.d = md.d | nd.d; + md.write_4bytes_le_to(&(vram[naddr])); + } else { + switch(naddr & 3) { + case 1: // 7fffd + md.b.l = vram[naddr]; + md.b.h = vram[naddr + 1]; + md.b.h2 = vram[naddr + 2]; + break; + case 2: // 7fffe + md.b.l = vram[naddr]; + md.b.h = vram[naddr + 1]; + break; + case 3: // 7fffe + md.b.l = vram[naddr]; + break; + } + nd.d = nd.d & xmask.d; + md.d = md.d & ~(xmask.d); + md.d = md.d | nd.d; + switch(naddr & 3) { + case 1: // 7fffd + vram[naddr] = md.b.l; + vram[naddr + 1] = md.b.h; + vram[naddr + 2] = md.b.h2; + break; + case 2: // 7fffe + vram[naddr] = md.b.l; + vram[naddr + 1] = md.b.h; + break; + case 3: // 7fffe + vram[naddr] = md.b.l; + break; + } } +// uint32_t xaddr = addr & 0x0017ffff; +// uint32_t naddr2 = naddr + 1; +// uint32_t naddr3 = naddr + 2; +// uint32_t naddr4 = naddr + 3; +// uint32_t offmask; +// if((addr & 0x3ffff) < 0x3fffd) { +// // Maybe not wrapped. +// md.read_4bytes_le_from(&(vram[naddr])); +// +// nd.d = nd.d & xmask.d; +// md.d = md.d & ~(xmask.d); +// md.d = md.d | nd.d; +// +// md.write_4bytes_le_to(&(vram[naddr])); +// } else { + // Maybe not wrapped. +// switch(xaddr) { +// case 0x17fffd: +// case 0x17fffe: +// case 0x17ffff: +// naddr2 = naddr2 & 0x7ffff; +// naddr3 = naddr3 & 0x7ffff; +// naddr4 = naddr4 & 0x7ffff; +/// +// md.b.l = vram[naddr]; +// md.b.h = vram[naddr2]; +// md.b.h2 = vram[naddr3]; +// md.b.h3 = vram[naddr4]; + +// nd.d = nd.d & xmask.d; +// md.d = md.d & ~(xmask.d); +// md.d = md.d | nd.d; + +// vram[naddr] = md.b.l; +// vram[naddr2] = md.b.h; +// vram[naddr3] = md.b.h2; +// vram[naddr4] = md.b.h3; +// break; +// case 0x03fffd: +// case 0x03fffe: +// case 0x03ffff: +// case 0x07fffd: +// case 0x07fffe: +// case 0x07ffff: +// offmask = ((addr & 0x00040000) != 0) ? 0x40000 : 0x00000; +// naddr2 = (naddr2 & 0x3ffff) + offmask; +// naddr3 = (naddr3 & 0x3ffff) + offmask; +// naddr4 = (naddr4 & 0x3ffff) + offmask; +// +// md.b.l = vram[naddr]; +// md.b.h = vram[naddr2]; +// md.b.h2 = vram[naddr3]; +// md.b.h3 = vram[naddr4]; + +// nd.d = nd.d & xmask.d; +// md.d = md.d & ~(xmask.d); +// md.d = md.d | nd.d; + +// vram[naddr] = md.b.l; +// vram[naddr2] = md.b.h; +// vram[naddr3] = md.b.h2; +// vram[naddr4] = md.b.h3; +// break; +// default: +// md.read_4bytes_le_from(&(vram[naddr])); +// +// nd.d = nd.d & xmask.d; +// md.d = md.d & ~(xmask.d); +// md.d = md.d | nd.d; +// +// md.write_4bytes_le_to(&(vram[naddr])); +// break; +// } +// } } else { -#ifdef __LITTLE_ENDIAN__ - uint16_t* p = (uint16_t)(&vram[addr]); - b.w = *p; -#else - b.read_2bytes_le_from(&vram[addr]); -#endif - c.w = b.w; - if(mask != 0xffff) { - b.w = b.w & ~(mask.w); - a.w = a.w & mask.w; - a.w = a.w | b.w; - } - if(a.w != c.w) { - make_dirty_vram(addr, 2); -#ifdef __LITTLE_ENDIAN__ - *p = a.w; -#else - a.write_2bytes_le_to(&vram[addr]); -#endif - } - } - return; -} - -void TOWNS_VRAM::write_raw_vram32(uint32_t addr, uint32_t data) -{ - pair32_t a; - pair32_t b; - pair32_t c; - uint32_t mask; - bool is_wrap = false; - uint32_t wrap_addr = 0; - uint32_t wrap_mask; - mask = ((addr & 0x02) == 0) ? packed_pixel_mask_reg.w.l : packed_pixel_mask_reg.w.h; - a.d = data; - - if((addr & 0x3ffff) > 0x3fffc) { - if((addr < 0x80100000) || (addr >= 0x80140000)) { - is_wrap = true; - wrap_addr = ((addr <= 0x8007ffff) && (addr > 0x8008fffc)) ? 0x40000 : 0; - wrap_mask = (addr >= 0x80100000) ? 0x7ffff : 0x3ffff; - } - } - addr = addr & 0x7ffff; - if(is_wrap) { - b.b.l = vram[addr]; - b.b.h = vram[((addr + 1) & wrap_mask) | wrap_addr]; - b.b.h2 = vram[((addr + 2) & wrap_mask) | wrap_addr]; - b.b.h3 = vram[((addr + 3) & wrap_mask) | wrap_addr]; + // Aligned + md.read_4bytes_le_from(&(vram[naddr])); - c.d = b.d; - if(mask != 0xffffffff) { - b.d = b.d & ~(mask); - a.d = a.d & mask; - a.d = a.d | b.d; - } - if(a.d != c.d) { - int leftbytes = 0x40000 - (addr & 0x3ffff); - make_dirty_vram(addr, leftbytes); - make_dirty_vram(wrap_addr, 4 - leftbytes); - vram[addr] = a.b.l; - vram[((addr + 1) & wrap_mask) | wrap_addr] = a.b.h; - vram[((addr + 2) & wrap_mask) | wrap_addr] = a.b.h2; - vram[((addr + 3) & wrap_mask) | wrap_addr] = a.b.h3; - } - } else { -#ifdef __LITTLE_ENDIAN__ - uint32_t* p = (uint32_t)(&vram[addr]); - b.d = *p; -#else - b.read_4bytes_le_from(&vram[addr]); -#endif - c.d = b.d; - if(mask != 0xffffffff) { - b.d = b.d & ~(mask); - a.d = a.d & mask; - a.d = a.d | b.d; - } - if(a.d != c.d) { - make_dirty_vram(addr, 4); -#ifdef __LITTLE_ENDIAN__ - *p = a.d; -#else - d.write_4bytes_le_to(&vram[addr]); -#endif - } + nd.d = nd.d & xmask.d; + md.d = md.d & (~(xmask.d)); + md.d = md.d | nd.d; + + md.write_4bytes_le_to(&(vram[naddr])); } return; } -void TOWNS_CRTC::write_mmio8(uint32_t addr, uint32_t data) +uint32_t TOWNS_VRAM::read_memory_mapped_io8(uint32_t addr) { - if((addr < 0xcff80) || (addr >= 0xcff88)) { - d_sprite->write_data8(addr & 0x7fff, data); - return; - } - switch(addr) { - case 0xcff80: - mix_reg = data & 0x28; - break; - case 0xcff81: - r50_readplane = (data & 0xc0) >> 6; - r50_ramsel = data & 0x0f; - break; - case 0xcff82: - d_crtc->write_signal(SIG_TOWNS_CRTC_MMIO_CF882H, data); - break; - case 0xcff83: - r50_gvramset = (data & 0x10) >> 4; - break; - case 0xcff86: - break; - default: - break; - } + return vram[addr & 0x7ffff]; } -uint32_t TOWNS_CRTC::read_mmio8(uint32_t addr) +uint32_t TOWNS_VRAM::read_memory_mapped_io16(uint32_t addr) { - if((addr < 0xcff80) || (addr >= 0xcff88)) { - return d_sprite->read_data8(addr & 0x7fff); - } - switch(addr) { - case 0xcff80: - return mix_reg; - break; - case 0xcff81: - return ((r50_readplane << 6) | r50_ramsel); - break; - case 0xcff82: - return d_crtc->read_signal(SIG_TOWNS_CRTC_MMIO_CF882H); - break; - case 0xcff83: - return (r50_gvramset << 4); - break; - case 0xcff86: - { - uint8_t d; - d = (d_crtc->read_signal(SIG_TOWNS_CRTC_VSYNC) != 0) ? 0x04 : 0; - d = d | ((d_crtc->read_signal(SIG_TOWNS_CRTC_HSYNC) != 0) ? 0x80 : 0); - d = d | 0x10; - return d; + pair16_t a; + + uint32_t naddr = addr & 0x7ffff; + if((addr & 1) == 0) { // Aligned + a.read_2bytes_le_from(&(vram[naddr])); + } else { + /* + switch(addr) { + case 0x8003ffff: + a.b.l = vram[0x3ffff]; + a.b.h = vram[0x00000]; + break; + case 0x8007ffff: + a.b.l = vram[0x7ffff]; + a.b.h = vram[0x40000]; + break; + case 0x8017ffff: + a.b.l = vram[0x7ffff]; + a.b.h = vram[0x00000]; + break; + default: + a.read_2bytes_le_from(&(vram[naddr])); + break; + } + */ + if(naddr == 0x7ffff) { + a.b.l = vram[naddr]; + a.b.h = 0xff; + } else { + a.b.l = vram[naddr]; + a.b.h = vram[naddr + 1]; } - break; - default: - break; } - return 0xff; + return (uint32_t)(a.w); } -uint32_t TOWNS_VRAM::read_plane_data8(uint32_t addr) +uint32_t TOWNS_VRAM::read_memory_mapped_io32(uint32_t addr) { - // Plane Access - pair_t data_p; - uint32_t x_addr = 0; - uint8_t *p = (uint8_t*)vram; - uint32_t mod_pos; - - // ToDo: Writing plane. - if(access_page1) x_addr = 0x40000; //? - addr = (addr & 0x7fff) << 3; - p = &(p[x_addr + addr]); - - // 8bit -> 32bit - uint32_t *pp = (uint32_t *)p; - uint8_t tmp = 0; - uint32_t tmp_d = *pp; - -#ifdef __LITTLE_ENDIAN__ - uint32_t tmp_m1 = 0x000000f0; - uint32_t tmp_m2 = 0x0000000f; -#else - uint32_t tmp_m1 = 0xf0000000; - uint32_t tmp_m2 = 0x0f000000; -#endif - uint32_t tmp_r; - tmp_d = tmp_d & write_plane_mask; - - for(int i = 0; i < 4; i++) { - tmp <<= 2; - tmp = tmp | (((tmp_d & tmp_m1) != 0) ? 0x02 : 0x00); - tmp = tmp | (((tmp_d & tmp_m2) != 0) ? 0x01 : 0x00); - -#ifdef __LITTLE_ENDIAN__ - tmp_d <<= 8; -#else - tmp_d >>= 8; -#endif - } - return tmp; -} + pair32_t a; -uint32_t TOWNS_VRAM::read_plane_data16(uint32_t addr) -{ - pair16_t d; - d.b.l = (uint8_t)(read_plane_data8(addr + 0)); - d.b.h = (uint8_t)(read_plane_data8(addr + 1)); - return (uint32_t)(d.w); + uint32_t naddr = addr & 0x7ffff; + if((addr & 3) == 0) { // Aligned + a.read_4bytes_le_from(&(vram[naddr])); + } else { // Unaligned + if((addr & 0x7ffff) < 0x7fffd) { + // Maybe not wrapped. + a.read_4bytes_le_from(&(vram[naddr])); + } else { + a.d = 0xffffffff; + switch(naddr & 3) { + case 1: + a.b.l = vram[naddr]; + a.b.h = vram[naddr + 1]; + a.b.h2 = vram[naddr + 2]; + break; + case 2: + a.b.l = vram[naddr]; + a.b.h = vram[naddr + 1]; + break; + case 3: + a.b.l = vram[naddr]; + break; + + } + /* + uint32_t xaddr = addr & 0x0017ffff; + uint32_t naddr2 = naddr + 1; + uint32_t naddr3 = naddr + 2; + uint32_t naddr4 = naddr + 3; + uint32_t offmask; + switch(xaddr) { + case 0x17fffd: + case 0x17fffe: + case 0x17ffff: + naddr2 = naddr2 & 0x7ffff; + naddr3 = naddr3 & 0x7ffff; + naddr4 = naddr4 & 0x7ffff; + + a.b.l = vram[naddr]; + a.b.h = vram[naddr2]; + a.b.h2 = vram[naddr3]; + a.b.h3 = vram[naddr4]; + break; + case 0x03fffd: + case 0x03fffe: + case 0x03ffff: + case 0x07fffd: + case 0x07fffe: + case 0x07ffff: + offmask = ((addr & 0x00040000) != 0) ? 0x40000 : 0x00000; + naddr2 = (naddr2 & 0x3ffff) + offmask; + naddr3 = (naddr3 & 0x3ffff) + offmask; + naddr4 = (naddr4 & 0x3ffff) + offmask; + + a.b.l = vram[naddr]; + a.b.h = vram[naddr2]; + a.b.h2 = vram[naddr3]; + a.b.h3 = vram[naddr4]; + break; + default: + // Maybe not wrapped. + a.read_4bytes_le_from(&(vram[naddr])); + break; + } + */ + } + } + return a.d; } -uint32_t TOWNS_VRAM::read_plane_data32(uint32_t addr) +void TOWNS_VRAM::write_signal(int id, uint32_t data, uint32_t mask) { - pair32_t d; - d.b.l = (uint8_t)(read_plane_data8(addr + 0)); - d.b.h = (uint8_t)(read_plane_data8(addr + 1)); - d.b.h2 = (uint8_t)(read_plane_data8(addr + 2)); - d.b.h3 = (uint8_t)(read_plane_data8(addr + 3)); - return d.d; + // ToDo } +// Renderers -void TOWNS_VRAM::write_plane_data8(uint32_t addr, uint32_t data) +void TOWNS_VRAM::write_io8(uint32_t address, uint32_t data) { - // Plane Access - pair_t data_p; - uint32_t x_addr = 0; - uint8_t *p = (uint8_t*)vram; - uint32_t mod_pos; - - // ToDo: Writing plane. - if(access_page1) x_addr = 0x40000; //? - addr = (addr & 0x7fff) << 3; - x_addr = x_addr + addr; - p = &(p[x_addr]); - - // 8bit -> 32bit - uint32_t *pp = (uint32_t *)p; - uint32_t tmp = 0; - uint32_t tmp_d = data & 0xff; -#ifdef __LITTLE_ENDIAN__ - uint32_t tmp_m1 = 0xf0000000 & write_plane_mask; - uint32_t tmp_m2 = 0x0f000000 & write_plane_mask; -#else - uint32_t tmp_m1 = 0x000000f0 & write_plane_mask; - uint32_t tmp_m2 = 0x0000000f & write_plane_mask; -#endif - uint32_t tmp_r1; - uint32_t tmp_r2; - - for(int i = 0; i < 4; i++) { -#ifdef __LITTLE_ENDIAN__ - tmp = tmp >> 8; -#else - tmp = tmp << 8; -#endif - tmp = tmp | (((tmp_d & 0x02) != 0) ? tmp_m1 : 0x00); - tmp = tmp | (((tmp_d & 0x01) != 0) ? tmp_m2 : 0x00); - tmp_d >>= 2; - } - tmp_r1 = *pp; - tmp_r2 = tmp_r1; - tmp_r1 = tmp_r1 & ~write_plane_mask; - tmp_r1 = tmp_d | tmp_r1; - if(tmp_r2 != tmp_r1) { - *pp = tmp_r1; - dirty_flag[x_addr >> 3] = true; + switch(address & 0xffff) { + case 0x0458: + vram_access_reg_addr = data & 3; +// out_debug_log(_T("VRAM ACCESS(0458h)=%02X"), data); + break; + case 0x045a: + switch(vram_access_reg_addr) { + case 0: + packed_pixel_mask_reg.b.l = data; + break; + case 1: + packed_pixel_mask_reg.b.h2 = data; + break; + } +// out_debug_log(_T("VRAM MASK(045Ah)=%08X"), packed_pixel_mask_reg.d); + break; + case 0x045b: + switch(vram_access_reg_addr) { + case 0: + packed_pixel_mask_reg.b.h = data; + break; + case 1: + packed_pixel_mask_reg.b.h3 = data; + break; + } +// out_debug_log(_T("VRAM MASK(045Bh)=%08X"), packed_pixel_mask_reg.d); + break; } } -void TOWNS_VRAM::write_plane_data16(uint32_t addr, uint32_t data) -{ - pair16_t d; - d.w = (uint16_t)data; - write_plane_data8(addr + 0, d.b.l); - write_plane_data8(addr + 1, d.b.h); -} - - -void TOWNS_VRAM::write_plane_data32(uint32_t addr, uint32_t data) +void TOWNS_VRAM::write_io16(uint32_t address, uint32_t data) { pair32_t d; d.d = data; - write_plane_data8(addr + 0, d.b.l); - write_plane_data8(addr + 1, d.b.h); - write_plane_data8(addr + 2, d.b.h2); - write_plane_data8(addr + 3, d.b.h3); -} - - -// I/Os -// Palette. -void TOWNS_CRTC::calc_apalette16(int layer, int index) -{ - if(index < 0) return; - if(index > 15) return; - apalette_16_rgb[layer][index] = - ((uint16_t)(apalette_b & 0x0f)) | - ((uint16_t)(apalette_r & 0x0f) << 4) | - ((uint16_t)(apalette_g & 0x0f) << 8); - if(index == 0) { - apalette_16_pixel[layer][index] = _CLEAR_COLOR; // ?? - } else { - apalette_16_pixel[layer][index] = RGBA_COLOR((apalette_r & 0x0f) << 4, (apalette_g & 0x0f) << 4, (apalette_b & 0x0f) << 4, 0xff); - } -} - -void TOWNS_CRTC::calc_apalette256(int index) -{ - if(index < 0) return; - if(index > 255) return; - apalette_256_rgb[layer][index] = - ((uint32_t)apalette_b) | - ((uint32_t)apalette_r << 8) | - ((uint32_t)apalette_g << 16); - if(index == 0) { - apalette_256_pixel[index] = _CLEAR_COLOR; // ?? - } else { - apalette_256_pixel[index] = RGBA_COLOR(apalette_r, apalette_g, apalette_b, 0xff); + switch(address & 0xffff) { + case 0x0458: + vram_access_reg_addr = data & 3; +// out_debug_log(_T("VRAM ACCESS(0458h)=%02X"), data); + break; + case 0x045a: + switch(vram_access_reg_addr) { + case 0: + packed_pixel_mask_reg.w.l = d.w.l; + break; + case 1: + packed_pixel_mask_reg.w.h = d.w.l; + break; + } +// out_debug_log(_T("VRAM MASK(045Ah)=%08X"), packed_pixel_mask_reg.d); + break; } } -void TOWNS_CRTC::set_apalette_r(int layer, uint8_t val) +uint32_t TOWNS_VRAM::read_io8(uint32_t address) { - apalette_r = val; - if(apalette_code < 16) { - calc_apalette16(layer, (int)apalette_code); + switch(address & 0xffff) { + case 0x0458: + return vram_access_reg_addr; + break; + case 0x045a: + switch(vram_access_reg_addr) { + case 0: + return packed_pixel_mask_reg.b.l; + break; + case 1: + return packed_pixel_mask_reg.b.h2; + break; + } + break; + case 0x045b: + switch(vram_access_reg_addr) { + case 0: + return packed_pixel_mask_reg.b.h; + break; + case 1: + return packed_pixel_mask_reg.b.h3; + break; + } + break; } - // if layer == 0 ? - calc_apalette256((int)apalette_code % 256); + return 0xff; } -void TOWNS_CRTC::set_apalette_g(int layer, uint8_t val) +uint32_t TOWNS_VRAM::read_io16(uint32_t address) { - apalette_g = val; - if(apalette_code < 16) { - calc_apalette16(layer, (int)apalette_code); + switch(address & 0xffff) { + case 0x0458: + return vram_access_reg_addr; + break; + case 0x045a: + switch(vram_access_reg_addr) { + case 0: + return packed_pixel_mask_reg.w.l; + break; + case 1: + return packed_pixel_mask_reg.w.h; + break; + } + break; } - // if layer == 0 ? - calc_apalette256((int)apalette_code % 256); + return 0xffff; } -void TOWNS_CRTC::set_apalette_b(int layer, uint8_t val) -{ - apalette_b = val; - if(apalette_code < 16) { - calc_apalette16(layer, (int)apalette_code); - } - // if layer == 0 ? - calc_apalette256((int)apalette_code % 256); -} +#define STATE_VERSION 1 -void TOWNS_CRTC::set_apalette_num(int layer, uint8_t val) +bool TOWNS_VRAM::process_state(FILEIO* state_fio, bool loading) { - apalette_code = ((int)val) % 256; -} + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } -// Renderers + state_fio->StateValue(access_page1); + state_fio->StateArray(dirty_flag, sizeof(dirty_flag), 1); + state_fio->StateArray(layer_display_flags, sizeof(layer_display_flags), 1); + state_fio->StateValue(sprite_busy); + state_fio->StateValue(sprite_disp_page); + state_fio->StateValue(vram_access_reg_addr); + state_fio->StateValue(packed_pixel_mask_reg); + state_fio->StateArray(vram, sizeof(vram), 1); + + return true; } -#undef _CLEAR_COLOR + +#undef _CLEAR_COLOR +} diff --git a/source/src/vm/fmtowns/towns_vram.h b/source/src/vm/fmtowns/towns_vram.h index b06b2d7bc..8835a78cf 100644 --- a/source/src/vm/fmtowns/towns_vram.h +++ b/source/src/vm/fmtowns/towns_vram.h @@ -12,9 +12,10 @@ #define _TOWNS_VRAM_H_ #include "../vm.h" -#include "../emu.h" +#include "../../emu.h" #include "device.h" #include "../../common.h" +#include "towns_common.h" #if defined(_USE_QT) #include @@ -24,65 +25,44 @@ #define TOWNS_VRAM_ADDR_MASK 0x7ffff // VRAM DIRECT ACCESS: For Sprite. You should access with 16bit // You can write raw data, drawing with colorkey is automatically. -#define SIG_TOWNS_TRANSFER_SPRITE_DATA 0x100000 -#define SIG_TOWNS_SET_SPRITE_BANK 0x140000 -#define SIG_TOWNS_CLEAR_SPRITE_BUFFER 0x140001 +#define SIG_TOWNS_TRANSFER_SPRITE_DATA 0x100000 +#define SIG_TOWNS_SET_SPRITE_BANK 0x140000 +#define SIG_TOWNS_CLEAR_SPRITE_BUFFER 0x140001 // Do render with any mode. You should set vline to arg. -#define SIG_TOWNS_RENDER_RASTER 0x01 -#define SIG_TOWNS_RENDER_FULL 0x02 -#define SIG_TOWNS_VRAM_VSTART 0x03 -#define SIG_TOWNS_VRAM_VBLANK 0x04 -#define SIG_TOWNS_VRAM_VSYNC 0x05 -#define SIG_TOWNS_VRAM_HSYNC 0x06 -#define SIG_TOWNS_VRAM_SET_VLINE 0x07 -#define SIG_TOWNS_RENDER_FLAG 0x08 +#define SIG_TOWNS_RENDER_RASTER 0x01 +#define SIG_TOWNS_RENDER_FULL 0x02 +#define SIG_TOWNS_VRAM_VSTART 0x03 +#define SIG_TOWNS_VRAM_VBLANK 0x04 +#define SIG_TOWNS_VRAM_VSYNC 0x05 +#define SIG_TOWNS_VRAM_HSYNC 0x06 +#define SIG_TOWNS_VRAM_SET_VLINE 0x07 +#define SIG_TOWNS_RENDER_FLAG 0x08 +#define SIG_TOWNS_VRAM_FRAMEBUFFER_READY 0x10 +#define SIG_TOWNS_VRAM_SWAP_FRAMEBUFFER 0x11 namespace FMTOWNS { class TOWNS_VRAM : public DEVICE { protected: - uint32_t page_modes[4]; - bool line_rendered[2][TOWNS_CRTC_MAX_LINES]; + DEVICE* d_sprite; + DEVICE* d_crtc; - uint16_t *vram_ptr[2]; // Layer [01] address. - uint32_t vram_size[2]; // Layer [01] size [bytes]. - uint32_t vram_offset[2]; // Layer [01] address offset. #if defined(_USE_QT) // If you use other framework, place mutex lock. QMutex vram_lock[2][2]; // [bank][layer]; #endif bool access_page1; - uint32_t write_plane_mask; // for plane-access. - uint8_t packed_access_mask_lo; - uint8_t packed_access_mask_hi; bool dirty_flag[0x80000 >> 3]; // Per 8bytes : 16pixels(16colors) / 8pixels(256) / 4pixels(32768) - - // FMR50 Compatible registers. They are mostly dummy. // Digital paletts. I/O FD98H - FD9FH. - uint8_t r50_digital_palette[8]; bool layer_display_flags[2]; // I/O FDA0H (WO) : bit3-2 (Layer1) or bit1-0 (Layer0).Not 0 is true. - bool r50_dpalette_updated; // I/O 044CH (RO) : bit7 bool sprite_busy; // I/O 044CH (RO) : bit1. Must update from write_signal(). - bool splite_disp_page; // I/O 044CH (RO) : bit0. Must update from write_signal(). - uint8_t mix_reg; // MMIO 000CH:FF80H - uint8_t r50_readplane; // MMIO 000CH:FF81H : BIT 7 and 6. - uint8_t r50_ramsel; // MMIO 000CH:FF81H : BIT 3 to 0. - uint8_t r50_gvramsel; // MMIO 000CH:FF83H : bit4 (and 3). - // Around Analog palette. - uint8_t apalette_code; // I/O FD90H (RW). 16 or 256 colors. - uint8_t apalette_b; // I/O FD92H (RW). - uint8_t apalette_r; // I/O FD94H (RW). - uint8_t apalette_g; // I/O FD96H (RW). - uint16_t apalette_16_rgb[2][16]; // R * 256 + G * 16 + B - scrntype_t apalette_16_pixel[2][16]; // Not saved. Must be calculated. - uint32_t apalette_256_rgb[256]; // R * 65536 + G * 256 + B - scrntype_t apalette_256_pixel[256]; // Not saved. Must be calculated. + bool sprite_disp_page; // I/O 044CH (RO) : bit0. Must update from write_signal(). // Accessing VRAM. Will be separated. // Memory description: // All of accessing must be little endian. @@ -96,6 +76,7 @@ class TOWNS_VRAM : public DEVICE // I/O 0458H (RW) : VRAM ACCESS CONTROLLER reg address. // I/O 045AH (RW) : VRAM ACCESS CONTROLLER reg data (LOW). // I/O 045BH (RW) : VRAM ACCESS CONTROLLER reg data (HIGH). + uint8_t vram_access_reg_addr; pair32_t packed_pixel_mask_reg; // '1' = Write. I/O 0458H - 045BH. uint8_t vram[0x80000]; // Related by machine. // End. @@ -105,50 +86,102 @@ class TOWNS_VRAM : public DEVICE bool has_hardware_blending; // End. - public: - TOWNS_VRAM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TOWNS_VRAM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { memset(vram, 0x00, sizeof(vram)); + d_sprite = NULL; + d_crtc = NULL; + set_device_name(_T("FM-Towns VRAM")); } ~TOWNS_VRAM() {} - - virtual uint32_t read_memory_mapped_io8(uint32_t addr); - virtual uint32_t read_memory_mapped_io16(uint32_t addr); - virtual uint32_t read_memory_mapped_io32(uint32_t addr); - virtual void write_memory_mapped_io8(uint32_t addr, uint32_t data); - virtual void write_memory_mapped_io16(uint32_t addr, uint32_t data); - virtual void write_memory_mapped_io32(uint32_t addr, uint32_t data); - - uint32_t read_io8(uint32_t addr); - void write_io8(uint32_t addr, uint32_t data); + virtual void initialize(); + virtual void reset(); - void write_signal(int id, uint32_t data, uint32_t mask); // Do render + virtual uint32_t __FASTCALL read_memory_mapped_io8(uint32_t addr); + virtual uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr); + virtual uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr); + virtual void __FASTCALL write_memory_mapped_io8(uint32_t addr, uint32_t data); + virtual void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data); + virtual void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data); + + virtual void __FASTCALL write_io8(uint32_t address, uint32_t data); + virtual void __FASTCALL write_io16(uint32_t address, uint32_t data); + + virtual uint32_t __FASTCALL read_io8(uint32_t address); + virtual uint32_t __FASTCALL read_io16(uint32_t address); + + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); // Do render + virtual bool process_state(FILEIO* state_fio, bool loading); // Unique Functions - uint8_t* get_vram_address(uint32_t offset) + virtual uint8_t* __FASTCALL get_vram_address(uint32_t offset) { if(offset >= 0x80000) return NULL; // ToDo return &(vram[offset]); } - uint32_t get_vram_size() + virtual bool __FASTCALL set_buffer_to_vram(uint32_t offset, uint8_t *buf, int words) + { + offset &= 0x7ffff; +// if(words > 16) return false; + if(words <= 0) return false; + uint8_t* p = &(vram[offset]); + if((offset + (words << 1)) <= 0x80000) { + memcpy(p, buf, words << 1); + } else { + int nb = 0x80000 - offset; + memcpy(p, buf, nb); + int nnb = (words << 1) - nb; + if(nnb > 0) { + memcpy(vram, &(buf[nb]), nnb); + } + } + return true; + } + virtual bool __FASTCALL get_vram_to_buffer(uint32_t offset, uint8_t *buf, int words) + { + offset &= 0x7ffff; +// if(words > 16) return false; + if(words <= 0) return false; + uint8_t* p = &(vram[offset]); + if((offset + (words << 1)) <= 0x80000) { + memcpy(buf, p, words << 1); + } else { + uint32_t nb = 0x80000 - offset; + memcpy(buf, p, nb); + int nnb = (words << 1) - nb; + if(nnb > 0) { + memcpy(&(buf[nb]), vram, nnb); + } + } + return true; + } + virtual void __FASTCALL make_dirty_vram(uint32_t addr, int bytes); + virtual uint32_t __FASTCALL get_vram_size() { return 0x80000; // ToDo } - void lock_framebuffer(int layer, int bank) + virtual void __FASTCALL lock_framebuffer(int layer, int bank) { #if defined(_USE_QT) vram_lock[bank][layer].lock(); #endif } - void unlock_framebuffer(int layer, int bank) + virtual void __FASTCALL unlock_framebuffer(int layer, int bank) { #if defined(_USE_QT) vram_lock[bank][layer].unlock(); #endif } - + void set_context_sprite(DEVICE *dev) + { + d_sprite = dev; + } + void set_context_crtc(DEVICE *dev) + { + d_crtc = dev; + } // New APIs? // End. }; diff --git a/source/src/vm/fmtowns/ym2612.cpp b/source/src/vm/fmtowns/ym2612.cpp new file mode 100644 index 000000000..d9bc7967f --- /dev/null +++ b/source/src/vm/fmtowns/ym2612.cpp @@ -0,0 +1,581 @@ +/* + Skelton for retropc emulator + + Author : Takeda.Toshiya + Date : 2006.09.15- + + [ YM2203 / YM2608 ] +*/ + + +#include "ym2612.h" +#include "debugger.h" +#include + +#define EVENT_FM_TIMER 0 + +#ifdef SUPPORT_MAME_FM_DLL +// thanks PC8801MA改 +#include "fmdll/fmdll.h" +static CFMDLL* fmdll = NULL; +static int chip_reference_counter = 0; +static bool dont_create_multiple_chips = false; +#else +#endif + +void YM2612::initialize() +{ + DEVICE::initialize(); + // ToDo: Set type via software interface for AY-3-891x. + if(this_device_name[0] == _T('\0')) { + set_device_name(_T("YM2612 OPN2")); + } + opn2 = new FM::OPN2; + +#ifdef SUPPORT_MAME_FM_DLL + if(!fmdll) { + fmdll = new CFMDLL(config.mame2608_dll_path); + } + dllchip = NULL; +#endif + register_vline_event(this); + left_volume = right_volume = 256; + v_left_volume = v_right_volume = 256; + mute = false; + clock_prev = clock_accum = clock_busy = 0; + ch = 0; + addr_A1 = false; + + if(d_debugger != NULL) { + d_debugger->set_device_name(_T("Debugger (YM2612 OPN2)")); + d_debugger->set_context_mem(this); + d_debugger->set_context_io(vm->dummy); + } +} + +void YM2612::release() +{ + delete opn2; +#ifdef SUPPORT_MAME_FM_DLL + if(dllchip) { + fmdll->Release(dllchip); + dllchip = NULL; + chip_reference_counter--; + } + if(fmdll && !chip_reference_counter) { + delete fmdll; + fmdll = NULL; + } +#endif +} + +void YM2612::reset() +{ + touch_sound(); + opn2->Reset(); +#ifdef SUPPORT_MAME_FM_DLL + if(dllchip) { + fmdll->Reset(dllchip); + } +#endif + memset(port_log, 0, sizeof(port_log)); + fnum2 = 0; + fnum21 = 0; + // stop timer + timer_event_id = -1; + this->set_reg(0x27, 0); + + port[0].first = port[1].first = true; + port[0].wreg = port[1].wreg = 0;//0xff; + mode = 0; + irq_prev = busy = false; +} + + +void YM2612::write_io8(uint32_t addr, uint32_t data) +{ + switch(addr & 3) { + case 0: + // write dummy data for prescaler + ch = data; + addr_A1 = false; + /* + if(0x2d <= ch && ch <= 0x2f) { + update_count(); + this->set_reg(ch, 0); + update_interrupt(); + clock_busy = get_current_clock(); + busy = true; + } + */ + break; + case 1: + if(!(addr_A1)) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data8(ch, data); + } else { + this->write_via_debugger_data8(ch, data); + } + } + break; + case 2: + ch1 = data1 = data; + addr_A1 = true; + break; + case 3: + if(addr_A1) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data8(0x100 | ch1, data); + } else { + this->write_via_debugger_data8(0x100 | ch1, data); + } + } + break; + default: + break; + } +} + +uint32_t YM2612::read_io8(uint32_t addr) +{ + switch(addr & 3) { + case 0: + case 1: + case 2: + case 3: + { + /* BUSY : x : x : x : x : x : FLAGB : FLAGA */ + update_count(); + update_interrupt(); + uint32_t status; + status = opn2->ReadStatus() & ~0x80; + if(busy) { + if(get_passed_usec(clock_busy) < 1.0) { + status |= 0x80; + } else { + busy = false; + } + } + return status; + } + break; + default: + break; + } + return 0xff; +} + +void YM2612::write_via_debugger_data8(uint32_t addr, uint32_t data) +{ + if(addr < 0x100) { + // YM2612 + if(0x2d <= addr && addr <= 0x2f) { + // don't write again for prescaler + } else if(0xa4 <= addr && addr <= 0xa6) { + // XM8 version 1.20 + fnum2 = data; + } else { + update_count(); + // XM8 version 1.20 + if(0xa0 <= addr && addr <= 0xa2) { + this->set_reg(addr + 4, fnum2); + } + this->set_reg(addr, data); + if(addr == 0x27) { + update_event(); + } + update_interrupt(); + clock_busy = get_current_clock(); + busy = true; + } + } else if(addr < 0x200) { + // YM2608 + if(0x1a4 <= addr && addr <= 0x1a6) { + // XM8 version 1.20 + fnum21 = data; + } else { + update_count(); + // XM8 version 1.20 + if(0x1a0 <= addr && addr <= 0x1a2) { + this->set_reg(addr + 4, fnum21); + } + this->set_reg(addr, data); + data1 = data; + update_interrupt(); + clock_busy = get_current_clock(); + busy = true; + } + } +} + +uint32_t YM2612::read_via_debugger_data8(uint32_t addr) +{ + if(addr < 0x100) { + // YM2612 + return opn2->GetReg(addr); + } else if(addr < 0x200) { + // YM2608 + return port_log[addr].data; + } + return 0; +} + +void YM2612::write_signal(int id, uint32_t data, uint32_t mask) +{ + if(id == SIG_YM2612_MUTE) { + mute = ((data & mask) != 0); + } +} + +uint32_t YM2612::read_signal(int id) +{ + return 0x00; +} + +void YM2612::event_vline(int v, int clock) +{ + update_count(); + update_interrupt(); +} + +void YM2612::event_callback(int event_id, int error) +{ + update_count(); + update_interrupt(); + timer_event_id = -1; + update_event(); +} + +void YM2612::update_count() +{ + clock_accum += clock_const * get_passed_clock(clock_prev); + uint32_t count = clock_accum >> 20; + if(count) { + opn2->Count(count); + clock_accum -= count << 20; + } + clock_prev = get_current_clock(); +} + +void YM2612::update_event() +{ + if(timer_event_id != -1) { + cancel_event(this, timer_event_id); + timer_event_id = -1; + } + + int count; + count = opn2->GetNextEvent(); + if(count > 0) { + register_event(this, EVENT_FM_TIMER, 1000000.0 / (double)chip_clock * (double)count * 2.0, false, &timer_event_id); + } +} + +void YM2612::update_interrupt() +{ + bool irq; + irq = opn2->ReadIRQ(); + if(!irq_prev && irq) { + write_signals(&outputs_irq, 0xffffffff); + } else if(irq_prev && !irq) { + write_signals(&outputs_irq, 0); + } + irq_prev = irq; +} + +#define VCALC(x, y) { \ + x = (x * y) >> 8; \ + } + +#define SATURATION_ADD(x, y) { \ + x = x + y; \ + if(x < -0x8000) x = -0x8000; \ + if(x > 0x7fff) x = 0x7fff; \ + } + +#if 0 +static inline __FASTCALL int32_t VCALC(int32_t x, int32_t y) +{ + x = x * y; + x = x >> 8; + return x; +} + +static inline __FASTCALL int32_t SATURATION_ADD(int32_t x, int32_t y) +{ + x = x + y; + if(x < -0x8000) x = -0x8000; + if(x > 0x7fff) x = 0x7fff; + return x; +} +#endif + +void YM2612::mix(int32_t* buffer, int cnt) +{ + if(cnt > 0 && !mute) { + int32_t *dbuffer = (int32_t *)malloc((cnt * 2 + 2) * sizeof(int32_t)); + memset((void *)dbuffer, 0x00, (cnt * 2 + 2) * sizeof(int32_t)); + opn2->Mix(dbuffer, cnt); +#ifdef SUPPORT_MAME_FM_DLL + if(dllchip) { + fmdll->Mix(dllchip, dbuffer, cnt); + } +#endif + int32_t *p = dbuffer; + int32_t *q = buffer; + __DECL_ALIGNED(32) int32_t tmpp[8]; + __DECL_ALIGNED(32) int32_t tmpq[8]; + const __DECL_ALIGNED(32) int32_t tvol[8] = + {v_left_volume, v_right_volume, + v_left_volume, v_right_volume, + v_left_volume, v_right_volume, + v_left_volume, v_right_volume}; + + for(int i = 0; i < cnt / 4; i++) { +__DECL_VECTORIZED_LOOP + for(int j = 0; j < 8; j++) { + tmpp[j] = p[j]; + tmpq[j] = q[j]; + } +__DECL_VECTORIZED_LOOP + for(int j = 0; j < 8; j++) { + VCALC(tmpp[j], tvol[j]); + } +__DECL_VECTORIZED_LOOP + for(int j = 0; j < 8; j++) { + SATURATION_ADD(tmpq[j], tmpp[j]); + } +__DECL_VECTORIZED_LOOP + for(int j = 0; j < 8; j++) { + q[j] = tmpq[j]; + } + q += 8; + p += 8; + } + if((cnt & 3) != 0) { + for(int i = 0; i < (cnt & 3); i++) { +__DECL_VECTORIZED_LOOP + for(int j = 0; j < 2; j++) { + tmpp[j] = p[j]; + } +__DECL_VECTORIZED_LOOP + for(int j = 0; j < 2; j++) { + VCALC(tmpp[j], tvol[j]); + } +__DECL_VECTORIZED_LOOP + for(int j = 0; j < 2; j++) { + SATURATION_ADD(q[j], tmpp[j]); + } + q += 2; + p += 2; + } + } + free(dbuffer); + } +} + +void YM2612::set_volume(int _ch, int decibel_l, int decibel_r) +{ + v_right_volume = (int)(pow(10.0, (double)decibel_vol / 10.0) * (double)right_volume); + v_left_volume = (int)(pow(10.0, (double)decibel_vol / 10.0) * (double)left_volume); + opn2->SetVolumeFM(base_decibel_fm + decibel_l, base_decibel_fm + decibel_r); +#ifdef SUPPORT_MAME_FM_DLL + if(dllchip) { + fmdll->SetVolumeFM(dllchip, base_decibel_fm + decibel_l); + } +#endif +} + +void YM2612::initialize_sound(int rate, int clock, int samples, int decibel_fm, int decibel_psg) +{ + // Note: Clock may set to real value, not multiplied by 2. + opn2->Init(clock, rate, false, get_application_path()); + opn2->SetVolumeFM(decibel_fm, decibel_fm); + opn2->SetVolumePSG(decibel_psg, decibel_psg); + base_decibel_fm = decibel_fm; + base_decibel_psg = decibel_psg; + +#ifdef SUPPORT_MAME_FM_DLL + if(!dont_create_multiple_chips) { + fmdll->Create((LPVOID*)&dllchip, clock, rate); + if(dllchip) { + chip_reference_counter++; + + fmdll->SetVolumeFM(dllchip, decibel_fm); + fmdll->SetVolumePSG(dllchip, decibel_psg); + + DWORD mask = 0; + DWORD dwCaps = fmdll->GetCaps(dllchip); + if((dwCaps & SUPPORT_MULTIPLE) != SUPPORT_MULTIPLE) { + dont_create_multiple_chips = true; + } + if((dwCaps & SUPPORT_FM_A) == SUPPORT_FM_A) { + mask = 0x07; + } + if((dwCaps & SUPPORT_FM_B) == SUPPORT_FM_B) { + mask |= 0x38; + } + if((dwCaps & SUPPORT_PSG) == SUPPORT_PSG) { + mask |= 0x1c0; + } + if((dwCaps & SUPPORT_ADPCM_B) == SUPPORT_ADPCM_B) { + mask |= 0x200; + } + if((dwCaps & SUPPORT_RHYTHM) == SUPPORT_RHYTHM) { + mask |= 0xfc00; + } + opn2->SetChannelMask(mask); + fmdll->SetChannelMask(dllchip, ~mask); + } + } +#endif + chip_clock = clock; +} + +void YM2612::set_reg(uint32_t addr, uint32_t data) +{ + touch_sound(); + if((addr & 0x1f0) <= 0x010) { + return; + } + opn2->SetReg(addr, data); +#ifdef SUPPORT_MAME_FM_DLL + if(dllchip) { + fmdll->SetReg(dllchip, addr, data); + } + if(0x2d <= addr && addr <= 0x2f) { + port_log[0x2d].written = port_log[0x2e].written = port_log[0x2f].written = false; + } +#endif + port_log[addr].written = true; + port_log[addr].data = data; +} + +void YM2612::update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) +{ + clock_const = (uint32_t)((double)chip_clock * 1024.0 * 1024.0 / (double)new_clocks + 0.5); +} + +bool YM2612::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + if((reg[0] == 'R') || (reg[0] == 'r')) { + if(strlen(reg) >= 2) { + _TCHAR *eptr; + int regnum = _tcstol(&(reg[1]), &eptr, 16); + if(regnum < 0x200) { + set_reg((uint32_t)regnum, data); + } else { + return false; + } + return true; + } + return false; + } else if(_tcsicmp(reg, _T("CH")) == 0) { + ch = data; + return true; + } else if(_tcsicmp(reg, _T("CH1")) == 0) { + ch1 = data; + return true; + } else if(_tcsicmp(reg, _T("FNUM2")) == 0) { + fnum2 = data; + return true; + } else if(_tcsicmp(reg, _T("DATA1")) == 0) { + data1 = data; + return true; + } else if(_tcsicmp(reg, _T("FNUM21")) == 0) { + fnum21 = data; + return true; + } + return false; +} + +bool YM2612::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + _TCHAR tmps[512] = {0}; + _TCHAR tmps2[32 * 0x200] = {0}; + _TCHAR tmps3[16]; + int rows = 0x200 / 16; + for(uint32_t i = 0; i < rows; i++) { + memset(tmps3, 0x00, sizeof(tmps3)); + my_stprintf_s(tmps3, 15, _T("+%02X :"), i * 16); + _tcsncat(tmps2, tmps3, sizeof(tmps2) - 1); + for(uint32_t j = 0; j < 16; j++) { + memset(tmps3, 0x00, sizeof(tmps3)); + if(i == 0) { + my_stprintf_s(tmps3, 7, _T(" %02X"), opn2->GetReg(j)); + } else { + if((i * 16 + j) == 0xff) { + my_stprintf_s(tmps3, 7, _T(" %02X"), opn2->GetReg(i * 16 + j)); + } else { + my_stprintf_s(tmps3, 7, _T(" %02X"), port_log[i * 16 + j].data); + } + } + _tcsncat(tmps2, tmps3, sizeof(tmps2) - 1); + } + _tcsncat(tmps2, "\n", sizeof(tmps2) - 1); + } + bool irqflag; + irqflag = opn2->ReadIRQ(); + my_stprintf_s(buffer, buffer_len - 1, _T("%sCH=%02X FNUM2=%02X CH1=%02X DATA1=%02X FNUM21=%02X\nIRQ=%s BUSY=%s CHIP_CLOCK=%d\nREG : +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F\n%s"), + tmps, ch, fnum2, ch1, data1, fnum21, + (irqflag) ? _T("Y") : _T("N"), (busy) ? _T("Y") : _T("N"), chip_clock, tmps2); + return true; +} + +#define STATE_VERSION 1 + +bool YM2612::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + if(!opn2->ProcessState((void *)state_fio, loading)) { + return false; + } + for(int i = 0; i < array_length(port_log); i++) { + state_fio->StateValue(port_log[i].written); + state_fio->StateValue(port_log[i].data); + } + state_fio->StateValue(ch); + state_fio->StateValue(fnum2); + state_fio->StateValue(ch1); + state_fio->StateValue(data1); + state_fio->StateValue(fnum21); + for(int i = 0; i < 2; i++) { + state_fio->StateValue(port[i].wreg); + state_fio->StateValue(port[i].rreg); + state_fio->StateValue(port[i].first); + } + state_fio->StateValue(mode); + state_fio->StateValue(chip_clock); + state_fio->StateValue(irq_prev); + state_fio->StateValue(mute); + state_fio->StateValue(clock_prev); + state_fio->StateValue(clock_accum); + state_fio->StateValue(clock_const); + state_fio->StateValue(clock_busy); + state_fio->StateValue(timer_event_id); + state_fio->StateValue(busy); + state_fio->StateValue(addr_A1); + +#ifdef SUPPORT_MAME_FM_DLL + // post process + if(loading && dllchip) { + fmdll->Reset(dllchip); + for(int i = 0; i < 0x200; i++) { + // write fnum2 before fnum1 + int _ch = ((i >= 0xa0 && i <= 0xaf) || (i >= 0x1a0 && i <= 0x1a7)) ? (i ^ 4) : i; + if(port_log[ch].written) { + fmdll->SetReg(dllchip, _ch, port_log[ch].data); + } + } + } +#endif + return true; +} + + diff --git a/source/src/vm/fmtowns/ym2612.h b/source/src/vm/fmtowns/ym2612.h new file mode 100644 index 000000000..4dfd1eca5 --- /dev/null +++ b/source/src/vm/fmtowns/ym2612.h @@ -0,0 +1,148 @@ +/* + Skelton for retropc emulator + + Author : Takeda.Toshiya + Date : 2006.09.15- + + [ YM2612 ] +*/ + +#ifndef _YM2612_H_ +#define _YM2612_H_ + +#include "device.h" +#include "fmgen/opna.h" + +#ifdef SUPPORT_WIN32_DLL +#define SUPPORT_MAME_FM_DLL +//#include "fmdll/fmdll.h" +#endif +#define SIG_YM2612_MUTE 2 + +class DEBUGGER; + +class YM2612 : public DEVICE +{ +protected: + DEBUGGER *d_debugger; + FM::OPN2* opn2; +#ifdef SUPPORT_MAME_FM_DLL +// CFMDLL* fmdll; + LPVOID* dllchip; +#endif + struct { + bool written; + uint8_t data; + } port_log[0x200]; + int base_decibel_fm, base_decibel_psg; + int decibel_vol; + + uint8_t ch; + uint8_t fnum2; + uint8_t ch1, data1; + uint8_t fnum21; + + int32_t right_volume; + int32_t left_volume; + int32_t v_right_volume; + int32_t v_left_volume; + struct { + uint8_t wreg; + uint8_t rreg; + bool first; + // output signals + outputs_t outputs; + } port[2]; + uint8_t mode; + + int chip_clock; + bool irq_prev, mute; + + uint32_t clock_prev; + uint32_t clock_accum; + uint32_t clock_const; + int timer_event_id; + + uint32_t clock_busy; + bool busy; + bool addr_A1; + + virtual void update_count(); + virtual void update_event(); + virtual void update_interrupt(); + outputs_t outputs_irq; +public: + YM2612(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + base_decibel_fm = base_decibel_psg = 0; + decibel_vol = 0 + 5; + for(int i = 0; i < 2; i++) { + initialize_output_signals(&port[i].outputs); + port[i].wreg = port[i].rreg = 0;//0xff; + } + d_debugger = NULL; + initialize_output_signals(&outputs_irq); + set_device_name(_T("YM2612 OPN2")); + } + ~YM2612() {} + + // common functions + virtual void initialize(); + virtual void release(); + virtual void reset(); + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + virtual uint32_t __FASTCALL read_signal(int id); + virtual void event_vline(int v, int clock); + virtual void __FASTCALL event_callback(int event_id, int error); + virtual void __FASTCALL mix(int32_t* buffer, int cnt); + virtual void set_volume(int _ch, int decibel_l, int decibel_r); + virtual void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); + // for debugging + virtual void __FASTCALL write_via_debugger_data8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_via_debugger_data8(uint32_t addr); + bool is_debugger_available() + { + return true; + } + void *get_debugger() + { + return d_debugger; + } + virtual uint64_t get_debug_data_addr_space() + { + return 0x200; + } + virtual void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data) + { + if(addr < 0x200) { + write_via_debugger_data8(addr, data); + } + } + virtual uint32_t __FASTCALL read_debug_data8(uint32_t addr) + { + if(addr < 0x200) { + return read_via_debugger_data8(addr); + } + return 0; + } + virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data); + virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + + virtual bool process_state(FILEIO* state_fio, bool loading); + // unique functions + void set_context_irq(DEVICE* device, int id, uint32_t mask) + { + register_output_signal(&outputs_irq, device, id, mask); + } + virtual void set_context_debugger(DEBUGGER* device) + { + d_debugger = device; + } + virtual void initialize_sound(int rate, int clock, int samples, int decibel_fm, int decibel_psg); + virtual void set_reg(uint32_t addr, uint32_t data); // for patch +}; + +#endif + diff --git a/source/src/vm/fp1100/CMakeLists.txt b/source/src/vm/fp1100/CMakeLists.txt index 14f7a79c6..a2a61e766 100644 --- a/source/src/vm/fp1100/CMakeLists.txt +++ b/source/src/vm/fp1100/CMakeLists.txt @@ -1,8 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/fp1100") +message("* vm/emufp1100") -add_library(vm_fp1100 +add_library(vm_emufp1100 + ../upd7801.cpp + fdcpack.cpp fp1100.cpp main.cpp @@ -10,4 +12,4 @@ add_library(vm_fp1100 rompack.cpp sub.cpp -) \ No newline at end of file +) diff --git a/source/src/vm/fp1100/fdcpack.h b/source/src/vm/fp1100/fdcpack.h index 48f6b701b..6580b64ac 100644 --- a/source/src/vm/fp1100/fdcpack.h +++ b/source/src/vm/fp1100/fdcpack.h @@ -23,7 +23,7 @@ class FDCPACK : public DEVICE DEVICE *d_fdc; public: - FDCPACK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FDCPACK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("FDC Pack")); } diff --git a/source/src/vm/fp1100/fp1100.cpp b/source/src/vm/fp1100/fp1100.cpp index 40eaa25e8..620096736 100644 --- a/source/src/vm/fp1100/fp1100.cpp +++ b/source/src/vm/fp1100/fp1100.cpp @@ -41,7 +41,7 @@ using FP1100::FDCPACK; using FP1100::RAMPACK; using FP1100::ROMPACK; -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -402,6 +402,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -414,7 +426,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/fp1100/fp1100.h b/source/src/vm/fp1100/fp1100.h index 5bf478763..87162c72c 100644 --- a/source/src/vm/fp1100/fp1100.h +++ b/source/src/vm/fp1100/fp1100.h @@ -32,7 +32,6 @@ #define USE_TAPE 1 #define USE_FLOPPY_DISK 2 #define NOTIFY_KEY_DOWN -#define USE_SHIFT_NUMPAD_KEY #define USE_ALT_F10_KEY #define USE_AUTO_KEY_SHIFT 2 #define USE_AUTO_KEY 5 @@ -108,7 +107,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -163,6 +162,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/fp1100/main.h b/source/src/vm/fp1100/main.h index 81c27a256..9bbb8c683 100644 --- a/source/src/vm/fp1100/main.h +++ b/source/src/vm/fp1100/main.h @@ -50,11 +50,11 @@ class MAIN : public DEVICE uint8_t intr_request; uint8_t intr_in_service; - void __FASTCALL update_memory_map(); - void __FASTCALL update_intr(); + void update_memory_map(); + void update_intr(); public: - MAIN(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MAIN(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { intr_mask = intr_request = intr_in_service = 0; set_device_name(_T("Main CPU Bus")); diff --git a/source/src/vm/fp1100/rampack.h b/source/src/vm/fp1100/rampack.h index 5182a38c7..be21e2f5a 100644 --- a/source/src/vm/fp1100/rampack.h +++ b/source/src/vm/fp1100/rampack.h @@ -23,7 +23,7 @@ class RAMPACK : public DEVICE bool modified; public: - RAMPACK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RAMPACK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RAM Pack")); } diff --git a/source/src/vm/fp1100/rompack.h b/source/src/vm/fp1100/rompack.h index c95eee59d..5537feacd 100644 --- a/source/src/vm/fp1100/rompack.h +++ b/source/src/vm/fp1100/rompack.h @@ -22,7 +22,7 @@ class ROMPACK : public DEVICE uint8_t rom[0x8000]; public: - ROMPACK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + ROMPACK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("ROM Pack")); } diff --git a/source/src/vm/fp1100/sub.h b/source/src/vm/fp1100/sub.h index 7451eb841..c971044c0 100644 --- a/source/src/vm/fp1100/sub.h +++ b/source/src/vm/fp1100/sub.h @@ -175,7 +175,7 @@ class SUB : public DEVICE void key_update(); public: - SUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Sub CPU Bus")); } @@ -190,7 +190,7 @@ class SUB : public DEVICE uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_frame(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/fp200/CMakeLists.txt b/source/src/vm/fp200/CMakeLists.txt index 25cd872c7..9c738031f 100644 --- a/source/src/vm/fp200/CMakeLists.txt +++ b/source/src/vm/fp200/CMakeLists.txt @@ -1,8 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/fp200") +message("* vm/emufp200") -add_library(vm_fp200 +add_library(vm_emufp200 + ../i8080.cpp + io.cpp fp200.cpp -) \ No newline at end of file +) diff --git a/source/src/vm/fp200/fp200.cpp b/source/src/vm/fp200/fp200.cpp index 5afd76fbd..a4a40a294 100644 --- a/source/src/vm/fp200/fp200.cpp +++ b/source/src/vm/fp200/fp200.cpp @@ -29,7 +29,7 @@ // ---------------------------------------------------------------------------- using FP200::IO; -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -43,6 +43,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) drec->set_context_noise_fast(new NOISE(this, emu)); cpu = new I8080(this, emu); // i8085 memory = new MEMORY(this, emu); + rtc = new RP5C01(this, emu); io = new IO(this, emu); @@ -333,6 +334,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -345,7 +358,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/fp200/fp200.h b/source/src/vm/fp200/fp200.h index f2b517e7c..66d188401 100644 --- a/source/src/vm/fp200/fp200.h +++ b/source/src/vm/fp200/fp200.h @@ -84,7 +84,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -136,6 +136,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/fp200/io.h b/source/src/vm/fp200/io.h index 698574c22..f1e0b78fc 100644 --- a/source/src/vm/fp200/io.h +++ b/source/src/vm/fp200/io.h @@ -148,7 +148,7 @@ class IO : public DEVICE _TCHAR cmt_rec_file_path[_MAX_PATH]; int cmt_bufcnt; uint8_t cmt_buffer[0x10000]; - void cmt_write_buffer(uint8_t value, int samples); + void __FASTCALL cmt_write_buffer(uint8_t value, int samples); // from FP-1100 uint8_t cmt_clock; @@ -164,7 +164,7 @@ class IO : public DEVICE void update_sid(); public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } @@ -179,7 +179,7 @@ class IO : public DEVICE void __FASTCALL write_io8w(uint32_t addr, uint32_t data, int* wait); uint32_t __FASTCALL read_io8w(uint32_t addr, int* wait); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/gamegear/CMakeLists.txt b/source/src/vm/gamegear/CMakeLists.txt index 9da1d2a28..927f49f34 100644 --- a/source/src/vm/gamegear/CMakeLists.txt +++ b/source/src/vm/gamegear/CMakeLists.txt @@ -1,20 +1,28 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/fm7") +message("* vm/${EXE_NAME}") +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) -if(BUILD_GAMEGEAR) -add_library(vm_gamegear - gamegear.cpp - keyboard.cpp - memory.cpp - system.cpp -) -else() -add_library(vm_gamegear - mastersystem.cpp - keyboard.cpp - memory.cpp - system.cpp -) +if("${U_EXE_NAME}" STREQUAL "EMUGAMEGEAR") + add_library(vm_${EXE_NAME} + keyboard.cpp + ./memory.cpp + system.cpp + gamegear.cpp + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUMARK3") + add_library(vm_${EXE_NAME} + keyboard.cpp + ./memory.cpp + system.cpp + mastersystem.cpp + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUMASTERSYSTEM") + add_library(vm_${EXE_NAME} + keyboard.cpp + ./memory.cpp + system.cpp + mastersystem.cpp + ) endif() diff --git a/source/src/vm/gamegear/gamegear.cpp b/source/src/vm/gamegear/gamegear.cpp index 03ea85ec5..6b6961d7c 100644 --- a/source/src/vm/gamegear/gamegear.cpp +++ b/source/src/vm/gamegear/gamegear.cpp @@ -38,7 +38,7 @@ using GAMEGEAR::KEYBOARD; using GAMEGEAR::MEMORY; using GAMEGEAR::SYSTEM; -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -404,6 +404,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 1 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -416,7 +428,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/gamegear/gamegear.h b/source/src/vm/gamegear/gamegear.h index b98f5542b..85a3f5ac5 100644 --- a/source/src/vm/gamegear/gamegear.h +++ b/source/src/vm/gamegear/gamegear.h @@ -91,7 +91,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -148,6 +148,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/gamegear/keyboard.h b/source/src/vm/gamegear/keyboard.h index a9c4fd00f..58d0caca7 100644 --- a/source/src/vm/gamegear/keyboard.h +++ b/source/src/vm/gamegear/keyboard.h @@ -31,7 +31,7 @@ class KEYBOARD : public DEVICE void update_keyboard(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/gamegear/mastersystem.cpp b/source/src/vm/gamegear/mastersystem.cpp index 311805f53..c38238c59 100644 --- a/source/src/vm/gamegear/mastersystem.cpp +++ b/source/src/vm/gamegear/mastersystem.cpp @@ -40,7 +40,7 @@ using GAMEGEAR::KEYBOARD; using GAMEGEAR::MEMORY; using GAMEGEAR::SYSTEM; -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -408,6 +408,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 1 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -420,7 +432,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/gamegear/mastersystem.h b/source/src/vm/gamegear/mastersystem.h index e96da417f..8408abae3 100644 --- a/source/src/vm/gamegear/mastersystem.h +++ b/source/src/vm/gamegear/mastersystem.h @@ -94,7 +94,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -151,6 +151,9 @@ class VM : public VM_TEMPLATE /// void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/gamegear/memory.h b/source/src/vm/gamegear/memory.h index 6aa138c71..fc9cc8ba7 100644 --- a/source/src/vm/gamegear/memory.h +++ b/source/src/vm/gamegear/memory.h @@ -38,7 +38,7 @@ class MEMORY : public DEVICE void sms_mapper_w(uint32_t addr, uint32_t data); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/gamegear/system.h b/source/src/vm/gamegear/system.h index b58d6aa35..5341aedab 100644 --- a/source/src/vm/gamegear/system.h +++ b/source/src/vm/gamegear/system.h @@ -23,7 +23,7 @@ class SYSTEM : public DEVICE bool tenkey; public: - SYSTEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSTEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/harddisk.cpp b/source/src/vm/harddisk.cpp index 6cb962315..5e56f815f 100644 --- a/source/src/vm/harddisk.cpp +++ b/source/src/vm/harddisk.cpp @@ -44,7 +44,7 @@ void HARDDISK::open(const _TCHAR* file_path, int default_sector_size) sector_size = 256; sector_num = cylinders * surfaces * sectors; } else if(check_file_extension(file_path, _T(".nhd")) && memcmp(header, sig_nhd, 15) == 0) { - // T98Next + // T98-Next /* typedef struct nhd_header_s { char sig[16]; @@ -122,16 +122,42 @@ void HARDDISK::open(const _TCHAR* file_path, int default_sector_size) tmp.read_4bytes_le_from(header + 148); sector_num = tmp.sd; // sector_num = cylinders * surfaces * sectors; - } else { - // solid - header_size = 0; - // sectors = 33, surfaces = 4, cylinders = 153, sector_size = 256 // 5MB - // sectors = 33, surfaces = 8, cylinders = 310, sector_size = 256 // 10MB - surfaces = (default_sector_size == 256 && fio->FileLength() <= 33 * 4 * 310 * 256) ? 4 : 8; - cylinders = (surfaces == 4) ? 153 : 310; - sectors = 33; - sector_size = default_sector_size; - sector_num = fio->FileLength() / sector_size; + } else { + + bool is_hx = false; + for(int i = 0; i < 9; i++) { + _TCHAR _tmps[6] = {0}; + my_stprintf_s(_tmps, 6, _T("h%d"), i); + if(check_file_extension(file_path, _tmps)) { + is_hx = true; + break; + } + } + if(is_hx) { + // *.H0 .. *.H9 : Variable cylinders + header_size = 0; + surfaces = 8; + sectors = 63; + cylinders = (fio->FileLength() / default_sector_size) / (sectors * surfaces); + sector_size = default_sector_size; + sector_num = fio->FileLength() / sector_size; + return; + } else { + // solid + header_size = 0; + // sectors = 33/17, surfaces = 4, cylinders = 153, sector_size = 256/512 // 5MB + // sectors = 33/17, surfaces = 4, cylinders = 310, sector_size = 256/512 // 10MB + // sectors = 33/17, surfaces = 4, cylinders = 615, sector_size = 256/512 // 20MB + // sectors = 33/17, surfaces = 8, cylinders = 615, sector_size = 256/512 // 40MB +#if 0 + surfaces = (fio->FileLength() <= 17 * 4 * 615 * 512) ? 4 : 8; +#else + surfaces = ((int)(fio->FileLength() / 1024 / 1024) < 24) ? 4 : 8; +#endif + sectors = (default_sector_size == 1024) ? 8 : (default_sector_size == 512) ? 17 : 33; + sector_size = default_sector_size; + sector_num = fio->FileLength() / sector_size; + } } } } diff --git a/source/src/vm/harddisk.h b/source/src/vm/harddisk.h index 3f7cb6434..bc9008e7c 100644 --- a/source/src/vm/harddisk.h +++ b/source/src/vm/harddisk.h @@ -15,17 +15,17 @@ //#include "../emu.h" class FILEIO; -class EMU; -class HARDDISK +class EMU_TEMPLATE; +class DLL_PREFIX HARDDISK { protected: - EMU* emu; + EMU_TEMPLATE* emu; private: FILEIO *fio; int header_size; public: - HARDDISK(EMU* parent_emu) + HARDDISK(EMU_TEMPLATE* parent_emu) { emu = parent_emu; fio = NULL; diff --git a/source/src/vm/hc20/CMakeLists.txt b/source/src/vm/hc20/CMakeLists.txt index d49f37af7..763f9dc99 100644 --- a/source/src/vm/hc20/CMakeLists.txt +++ b/source/src/vm/hc20/CMakeLists.txt @@ -1,8 +1,9 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/hc20") +message("* vm/${EXE_NAME}") -add_library(vm_hc20 - memory.cpp - hc20.cpp +add_library(vm_${EXE_NAME} + ./memory.cpp + + ./hc20.cpp ) diff --git a/source/src/vm/hc20/hc20.cpp b/source/src/vm/hc20/hc20.cpp index 4723695d6..3b9f5e548 100644 --- a/source/src/vm/hc20/hc20.cpp +++ b/source/src/vm/hc20/hc20.cpp @@ -36,7 +36,7 @@ using HC20::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -114,7 +114,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) cpu->set_context_port3(memory, SIG_MEMORY_PORT_3, 0xff, 0); cpu->set_context_port4(memory, SIG_MEMORY_PORT_4, 0xff, 0); cpu->set_context_sio(memory, SIG_MEMORY_SIO_MAIN); - rtc->set_context_intr(memory, SIG_MEMORY_RTC_IRQ, 1); + rtc->set_context_intr_line(memory, SIG_MEMORY_RTC_IRQ, 1); memory->set_context_beep(beep); memory->set_context_cpu(cpu); @@ -347,6 +347,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -359,7 +371,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/hc20/hc20.h b/source/src/vm/hc20/hc20.h index 45729870d..b5f786783 100644 --- a/source/src/vm/hc20/hc20.h +++ b/source/src/vm/hc20/hc20.h @@ -95,7 +95,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -144,6 +144,9 @@ class VM : public VM_TEMPLATE bool is_tape_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/hc20/memory.h b/source/src/vm/hc20/memory.h index 37fa71c42..29e655fe9 100644 --- a/source/src/vm/hc20/memory.h +++ b/source/src/vm/hc20/memory.h @@ -90,11 +90,11 @@ class MEMORY : public DEVICE void update_sound(); void update_keyboard(); void update_intr(); - void send_to_slave(uint8_t val); - void send_to_main(uint8_t val); + void __FASTCALL send_to_slave(uint8_t val); + void __FASTCALL send_to_main(uint8_t val); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } @@ -107,7 +107,7 @@ class MEMORY : public DEVICE void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/hc40/CMakeLists.txt b/source/src/vm/hc40/CMakeLists.txt index 0fe43d5ff..3214b4412 100644 --- a/source/src/vm/hc40/CMakeLists.txt +++ b/source/src/vm/hc40/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/hc40") +message("* vm/${EXE_NAME}") -add_library(vm_hc40 - memory.cpp +add_library(vm_${EXE_NAME} + ./io.cpp + ./memory.cpp hc40.cpp - io.cpp ) diff --git a/source/src/vm/hc40/hc40.cpp b/source/src/vm/hc40/hc40.cpp index 12c97ab92..f495dc28c 100644 --- a/source/src/vm/hc40/hc40.cpp +++ b/source/src/vm/hc40/hc40.cpp @@ -32,7 +32,7 @@ using HC40::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -120,7 +120,7 @@ void VM::reset() } } -void VM::special_reset() +void VM::special_reset(int num) { // system reset for(DEVICE* device = first_device; device; device = device->next_device) { @@ -334,6 +334,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -346,7 +358,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/hc40/hc40.h b/source/src/vm/hc40/hc40.h index 1ba01c31c..e8a7aa176 100644 --- a/source/src/vm/hc40/hc40.h +++ b/source/src/vm/hc40/hc40.h @@ -23,7 +23,7 @@ // device informations for win32 #define WINDOW_MODE_BASE 3 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_FLOPPY_DISK 4 #define USE_TAPE 1 #define NOTIFY_KEY_DOWN @@ -80,7 +80,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -89,7 +89,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate() { @@ -139,6 +139,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/hc40/io.h b/source/src/vm/hc40/io.h index f2939335d..8324f6028 100644 --- a/source/src/vm/hc40/io.h +++ b/source/src/vm/hc40/io.h @@ -39,7 +39,7 @@ class IO : public DEVICE uint8_t vadr, yoff; // sub cpu - void send_to_7508(uint8_t val); + void __FASTCALL send_to_7508(uint8_t val); uint8_t rec_from_7508(); FIFO *cmd_buf, *rsp_buf; // rtc @@ -49,7 +49,7 @@ class IO : public DEVICE bool alarm_intr, alarm_intr_enb; uint8_t alarm[6]; // keyboard - void update_key(int code); + void __FASTCALL update_key(int code); FIFO *key_buf; bool kb_intr_enb; bool kb_rep_enb, kb_caps; @@ -73,7 +73,7 @@ class IO : public DEVICE scrntype_t pd, pb; public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } @@ -86,7 +86,7 @@ class IO : public DEVICE void sysreset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_frame(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); uint32_t get_intr_ack(); diff --git a/source/src/vm/hc40/memory.h b/source/src/vm/hc40/memory.h index 85700d382..0c243dc42 100644 --- a/source/src/vm/hc40/memory.h +++ b/source/src/vm/hc40/memory.h @@ -34,7 +34,7 @@ class MEMORY : public DEVICE void set_bank(uint32_t val); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/hc80/CMakeLists.txt b/source/src/vm/hc80/CMakeLists.txt index 2de898112..079c2b66d 100644 --- a/source/src/vm/hc80/CMakeLists.txt +++ b/source/src/vm/hc80/CMakeLists.txt @@ -1,9 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/hc80") +message("* vm/${EXE_NAME}") -add_library(vm_hc80 - memory.cpp +add_library(vm_${EXE_NAME} + ./io.cpp + ./memory.cpp + hc80.cpp - io.cpp ) diff --git a/source/src/vm/hc80/hc80.cpp b/source/src/vm/hc80/hc80.cpp index e8c03eefc..b80067c71 100644 --- a/source/src/vm/hc80/hc80.cpp +++ b/source/src/vm/hc80/hc80.cpp @@ -31,7 +31,7 @@ using HC80::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -111,7 +111,7 @@ void VM::reset() } } -void VM::special_reset() +void VM::special_reset(int num) { // system reset for(DEVICE* device = first_device; device; device = device->next_device) { @@ -240,6 +240,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -252,7 +264,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/hc80/hc80.h b/source/src/vm/hc80/hc80.h index 8f3e40dcb..6d21e101d 100644 --- a/source/src/vm/hc80/hc80.h +++ b/source/src/vm/hc80/hc80.h @@ -22,7 +22,7 @@ #define MAX_DRIVE 4 // device informations for win32 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_DEVICE_TYPE 3 // Nonintelligent ram disk #define DEVICE_TYPE_DEFAULT 2 @@ -79,7 +79,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -88,7 +88,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate() { @@ -124,6 +124,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/hc80/io.cpp b/source/src/vm/hc80/io.cpp index a5a618867..5d0dc9b01 100644 --- a/source/src/vm/hc80/io.cpp +++ b/source/src/vm/hc80/io.cpp @@ -353,7 +353,7 @@ void IO::write_io8(uint32_t addr, uint32_t data) cmd6303 = data; psr |= BIT_OBF; #ifdef OUT_CMD_LOG - this->out_debug_log(_T("\n%4x\tCMD %2x\n"), vm->get_cpu_pc(), data); + this->out_debug_log(_T("\n%4x\tCMD %2x\n"), get_cpu_pc(0), data); #endif break; case 0x80: @@ -451,7 +451,7 @@ uint32_t IO::read_io8(uint32_t addr) psr &= ~BIT_F1; } #ifdef OUT_CMD_LOG - this->out_debug_log(_T("%4x\tRCV %2x\n"), vm->get_cpu_pc(), val); + this->out_debug_log(_T("%4x\tRCV %2x\n"), get_cpu_pc(0), val); #endif return val; case 0x80: diff --git a/source/src/vm/hc80/io.h b/source/src/vm/hc80/io.h index 18ddf5bcd..222f2703f 100644 --- a/source/src/vm/hc80/io.h +++ b/source/src/vm/hc80/io.h @@ -38,7 +38,7 @@ class IO : public DEVICE uint8_t vadr, yoff; // 7508 - void send_to_7508(uint8_t val); + void __FASTCALL send_to_7508(uint8_t val); uint8_t rec_from_7508(); FIFO *cmd7508_buf, *rsp7508_buf; // rtc @@ -48,7 +48,7 @@ class IO : public DEVICE bool alarm_intr, alarm_intr_enb; uint8_t alarm[6]; // keyboard - void update_key(int code); + void __FASTCALL update_key(int code); FIFO *key_buf; bool kb_intr_enb; bool kb_rep_enb, kb_caps; @@ -60,9 +60,9 @@ class IO : public DEVICE // 6303 void process_6303(); - uint8_t get_point(int x, int y); - void draw_point(int x, int y, uint16_t dot); - void draw_line(int sx, int sy, int ex, int ey, uint16_t ope, uint8_t mode); + uint8_t __FASTCALL get_point(int x, int y); + void __FASTCALL draw_point(int x, int y, uint16_t dot); + void __FASTCALL draw_line(int sx, int sy, int ex, int ey, uint16_t ope, uint8_t mode); uint8_t cmd6303, psr; FIFO *cmd6303_buf, *rsp6303_buf; uint8_t ram[0x10000]; @@ -113,7 +113,7 @@ class IO : public DEVICE uint8_t *iramdisk_ptr; public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } @@ -126,7 +126,7 @@ class IO : public DEVICE void sysreset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_frame(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); uint32_t get_intr_ack(); diff --git a/source/src/vm/hc80/memory.h b/source/src/vm/hc80/memory.h index 0ea05bdb1..3599c5659 100644 --- a/source/src/vm/hc80/memory.h +++ b/source/src/vm/hc80/memory.h @@ -32,7 +32,7 @@ class MEMORY : public DEVICE void set_bank(uint32_t val); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/hd146818p.h b/source/src/vm/hd146818p.h index c053296c7..6e7c2a23d 100644 --- a/source/src/vm/hd146818p.h +++ b/source/src/vm/hd146818p.h @@ -14,9 +14,7 @@ //#include "../emu.h" #include "device.h" -class VM; -class EMU; -class HD146818P : public DEVICE +class DLL_PREFIX HD146818P : public DEVICE { private: // output signals @@ -36,7 +34,7 @@ class HD146818P : public DEVICE void update_intr(); public: - HD146818P(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + HD146818P(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_intr); initialize_output_signals(&outputs_sqw); @@ -50,11 +48,11 @@ class HD146818P : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions - void set_context_intr(DEVICE* device, int id, uint32_t mask) + void set_context_intr_line(DEVICE* device, int id, uint32_t mask) { register_output_signal(&outputs_intr, device, id, mask); } diff --git a/source/src/vm/hd44102.h b/source/src/vm/hd44102.h index 8e06f1db3..8333b0437 100644 --- a/source/src/vm/hd44102.h +++ b/source/src/vm/hd44102.h @@ -17,7 +17,7 @@ //#define SIG_HD44102_CS2 0 -class HD44102 : public DEVICE +class DLL_PREFIX HD44102 : public DEVICE { private: uint8_t m_ram[4][50]; // display memory @@ -42,7 +42,7 @@ class HD44102 : public DEVICE inline void count_up_or_down(); public: - HD44102(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + HD44102(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { _SCREEN_WIDTH = 192; _SCREEN_HEIGHT = 64; diff --git a/source/src/vm/hd46505.h b/source/src/vm/hd46505.h index c743718cb..ab2481b23 100644 --- a/source/src/vm/hd46505.h +++ b/source/src/vm/hd46505.h @@ -14,7 +14,7 @@ //#include "../emu.h" #include "device.h" -class HD46505 : public DEVICE +class DLL_PREFIX HD46505 : public DEVICE { private: @@ -57,13 +57,13 @@ class HD46505 : public DEVICE double _HD46505_CHAR_CLOCK; double _HD46505_HORIZ_FREQ; - void set_display(bool val); - void set_vblank(bool val); - void set_vsync(bool val); - void set_hsync(bool val); + void __FASTCALL set_display(bool val); + void __FASTCALL set_vblank(bool val); + void __FASTCALL set_vsync(bool val); + void __FASTCALL set_hsync(bool val); public: - HD46505(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + HD46505(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_disp); initialize_output_signals(&outputs_vblank); @@ -89,7 +89,7 @@ class HD46505 : public DEVICE void event_pre_frame(); void event_frame(); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/hd6301.h b/source/src/vm/hd6301.h index 02cc07698..fb1a4a54b 100644 --- a/source/src/vm/hd6301.h +++ b/source/src/vm/hd6301.h @@ -7,7 +7,7 @@ class DEBUGGER; class FIFO; //#endif -class HD6301 : public MC6801 +class DLL_PREFIX HD6301 : public MC6801 { protected: #define XX 5 @@ -54,7 +54,7 @@ class HD6301 : public MC6801 void __FASTCALL illegal() override; public: - HD6301(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MC6801(parent_vm, parent_emu) + HD6301(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MC6801(parent_vm, parent_emu) { set_device_name(_T("HD6301 MPU")); } diff --git a/source/src/vm/hd63484.h b/source/src/vm/hd63484.h index 11f00ee1f..e59a1f0f6 100644 --- a/source/src/vm/hd63484.h +++ b/source/src/vm/hd63484.h @@ -15,9 +15,7 @@ //#include "../emu.h" #include "device.h" -class VM; -class EMU; -class HD63484 : public DEVICE +class DLL_PREFIX HD63484 : public DEVICE { private: // vram @@ -50,7 +48,7 @@ class HD63484 : public DEVICE void paint(int sx, int sy, int col); public: - HD63484(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + HD63484(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("HD63484 ACRTC")); } ~HD63484() {} diff --git a/source/src/vm/huc6280.h b/source/src/vm/huc6280.h index 2a2e060a7..2c7c2395e 100644 --- a/source/src/vm/huc6280.h +++ b/source/src/vm/huc6280.h @@ -11,15 +11,13 @@ #ifndef _HUC6280_H_ #define _HUC6280_H_ -#include "vm.h" -#include "../emu.h" #include "device.h" //#ifdef USE_DEBUGGER class DEBUGGER; //#endif -class HUC6280_BASE : public DEVICE +class DLL_PREFIX HUC6280_BASE : public DEVICE { protected: DEVICE *d_mem, *d_io; @@ -37,7 +35,7 @@ class HUC6280_BASE : public DEVICE virtual int __FASTCALL run_one_opecode(); public: - HUC6280_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + HUC6280_BASE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { total_icount = prev_total_icount = 0; d_debugger = NULL; set_device_name(_T("HuC6280 CPU")); @@ -103,7 +101,7 @@ class HUC6280 : public HUC6280_BASE protected: int __FASTCALL run_one_opecode() override; public: - HUC6280(VM_TEMPLATE* parent_vm, EMU* parent_emu) : HUC6280_BASE(parent_vm, parent_emu) { + HUC6280(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : HUC6280_BASE(parent_vm, parent_emu) { set_device_name(_T("HuC6280 CPU")); } ~HUC6280() {} diff --git a/source/src/vm/huc6280_base.cpp b/source/src/vm/huc6280_base.cpp index 2270d1c7e..1d1295c6a 100644 --- a/source/src/vm/huc6280_base.cpp +++ b/source/src/vm/huc6280_base.cpp @@ -38,7 +38,7 @@ #define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate) #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) +#define CPU_DISASSEMBLE(name) int DLL_PREFIX CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, opram, d_debugger->first_symbol) #define READ8_HANDLER(name) UINT8 name(h6280_Regs *cpustate, offs_t offset) diff --git a/source/src/vm/i286.cpp b/source/src/vm/i286.cpp index d4cbd9533..4e15df594 100644 --- a/source/src/vm/i286.cpp +++ b/source/src/vm/i286.cpp @@ -3,14 +3,15 @@ Origin : MAME i286 core Author : Takeda.Toshiya - Date : 2012.10.18- + Date : 2012.10.18- - [ i286 ] + [ 80286 ] */ #include "i286.h" //#ifdef USE_DEBUGGER #include "debugger.h" +#include "i386_dasm.h" //#endif #include "i80x86_commondefs.h" @@ -18,15 +19,12 @@ #define cpu_state i80286_state #define CPU_MODEL i80286 #include "mame/emu/cpu/i86/i286.c" - #include "mame/emu/cpu/i386/i386dasm.c" +// #include "mame/emu/cpu/i386/i386dasm.c" //} -void I80286::initialize() +void I286::initialize() { DEVICE::initialize(); - _HAS_i80286 = false; - _HAS_v30 = true; - n_cpu_type = N_CPU_TYPE_I80286; opaque = CPU_INIT_CALL(i80286); cpu_state *cpustate = (cpu_state *)opaque; @@ -46,12 +44,12 @@ void I80286::initialize() } } -void I80286::release() +void I286::release() { free(opaque); } -void I80286::reset() +void I286::reset() { cpu_state *cpustate = (cpu_state *)opaque; int busreq = cpustate->busreq; @@ -72,13 +70,13 @@ void I80286::reset() cpustate->haltreq = haltreq; } -int I80286::run(int icount) +int I286::run(int icount) { cpu_state *cpustate = (cpu_state *)opaque; return CPU_EXECUTE_CALL( i80286 ); } -uint32_t I80286::read_signal(int id) +uint32_t I286::read_signal(int id) { if((id == SIG_CPU_TOTAL_CYCLE_HI) || (id == SIG_CPU_TOTAL_CYCLE_LO)) { cpu_state *cpustate = (cpu_state *)opaque; @@ -100,7 +98,7 @@ uint32_t I80286::read_signal(int id) return 0; } -void I80286::write_signal(int id, uint32_t data, uint32_t mask) +void I286::write_signal(int id, uint32_t data, uint32_t mask) { cpu_state *cpustate = (cpu_state *)opaque; @@ -122,89 +120,91 @@ void I80286::write_signal(int id, uint32_t data, uint32_t mask) } } -void I80286::set_intr_line(bool line, bool pending, uint32_t bit) +void I286::set_intr_line(bool line, bool pending, uint32_t bit) { cpu_state *cpustate = (cpu_state *)opaque; set_irq_line(cpustate, INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE); } -void I80286::set_extra_clock(int icount) +void I286::set_extra_clock(int icount) { cpu_state *cpustate = (cpu_state *)opaque; cpustate->extra_cycles += icount; } -int I80286::get_extra_clock() +int I286::get_extra_clock() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->extra_cycles; } -uint32_t I80286::get_pc() +uint32_t I286::get_pc() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->prevpc; } -uint32_t I80286::get_next_pc() +uint32_t I286::get_next_pc() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->pc; } -uint32_t I80286::translate_address(int segment, uint32_t offset) +uint32_t I286::translate_address(int segment, uint32_t offset) { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->base[segment] + offset; } -void I80286::write_debug_data8(uint32_t addr, uint32_t data) +void I286::write_debug_data8(uint32_t addr, uint32_t data) { int wait; d_mem->write_data8w(addr, data, &wait); } -uint32_t I80286::read_debug_data8(uint32_t addr) +uint32_t I286::read_debug_data8(uint32_t addr) { int wait; return d_mem->read_data8w(addr, &wait); } -void I80286::write_debug_data16(uint32_t addr, uint32_t data) +void I286::write_debug_data16(uint32_t addr, uint32_t data) { int wait; d_mem->write_data16w(addr, data, &wait); } -uint32_t I80286::read_debug_data16(uint32_t addr) +uint32_t I286::read_debug_data16(uint32_t addr) { int wait; return d_mem->read_data16w(addr, &wait); } -void I80286::write_debug_io8(uint32_t addr, uint32_t data) +void I286::write_debug_io8(uint32_t addr, uint32_t data) { int wait; d_io->write_io8w(addr, data, &wait); } -uint32_t I80286::read_debug_io8(uint32_t addr) { +uint32_t I286::read_debug_io8(uint32_t addr) +{ int wait; return d_io->read_io8w(addr, &wait); } -void I80286::write_debug_io16(uint32_t addr, uint32_t data) +void I286::write_debug_io16(uint32_t addr, uint32_t data) { int wait; d_io->write_io16w(addr, data, &wait); } -uint32_t I80286::read_debug_io16(uint32_t addr) { +uint32_t I286::read_debug_io16(uint32_t addr) +{ int wait; return d_io->read_io16w(addr, &wait); } -bool I80286::write_debug_reg(const _TCHAR *reg, uint32_t data) +bool I286::write_debug_reg(const _TCHAR *reg, uint32_t data) { cpu_state *cpustate = (cpu_state *)opaque; if(_tcsicmp(reg, _T("IP")) == 0) { @@ -248,7 +248,7 @@ bool I80286::write_debug_reg(const _TCHAR *reg, uint32_t data) return true; } -uint32_t I80286::read_debug_reg(const _TCHAR *reg) +uint32_t I286::read_debug_reg(const _TCHAR *reg) { cpu_state *cpustate = (cpu_state *)opaque; if(_tcsicmp(reg, _T("IP")) == 0) { @@ -289,7 +289,7 @@ uint32_t I80286::read_debug_reg(const _TCHAR *reg) return 0; } -bool I80286::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +bool I286::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) { cpu_state *cpustate = (cpu_state *)opaque; my_stprintf_s(buffer, buffer_len, @@ -306,48 +306,46 @@ bool I80286::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) return true; } -int I80286::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) +int I286::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) { cpu_state *cpustate = (cpu_state *)opaque; - UINT64 eip = pc - cpustate->base[CS]; - UINT8 ops[16]; + uint32_t eip = pc - cpustate->base[CS]; + uint8_t oprom[16]; for(int i = 0; i < 16; i++) { int wait; - ops[i] = d_mem->read_data8w(pc + i, &wait); + oprom[i] = d_mem->read_data8w((pc + i) & AMASK, &wait); } - UINT8 *oprom = ops; - - return CPU_DISASSEMBLE_CALL(x86_16) & DASMFLAG_LENGTHMASK; + return i386_dasm(oprom, eip, false, buffer, buffer_len); } -void I80286::set_address_mask(uint32_t mask) +void I286::set_address_mask(uint32_t mask) { cpu_state *cpustate = (cpu_state *)opaque; cpustate->amask = mask; } -uint32_t I80286::get_address_mask() +uint32_t I286::get_address_mask() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->amask; } -void I80286::set_shutdown_flag(int shutdown) +void I286::set_shutdown_flag(int shutdown) { cpu_state *cpustate = (cpu_state *)opaque; cpustate->shutdown = shutdown; } -int I80286::get_shutdown_flag() +int I286::get_shutdown_flag() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->shutdown; } -#define STATE_VERSION 8 +#define STATE_VERSION 9 -bool I80286::process_state(FILEIO* state_fio, bool loading) +bool I286::process_state(FILEIO* state_fio, bool loading) { cpu_state *cpustate = (cpu_state *)opaque; @@ -389,7 +387,9 @@ bool I80286::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(cpustate->ParityVal); state_fio->StateValue(cpustate->TF); state_fio->StateValue(cpustate->IF); +#if 0 state_fio->StateValue(cpustate->MF); +#endif state_fio->StateValue(cpustate->nmi_state); state_fio->StateValue(cpustate->irq_state); state_fio->StateValue(cpustate->test_state); diff --git a/source/src/vm/i286.h b/source/src/vm/i286.h index 30056e3af..e93115a32 100644 --- a/source/src/vm/i286.h +++ b/source/src/vm/i286.h @@ -3,27 +3,51 @@ Origin : MAME i286 core Author : Takeda.Toshiya - Date : 2012.10.18- + Date : 2012.10.18- - [ i286 ] + [ 80286 ] */ -#ifndef _I286_H_ +#ifndef _I286_H_ #define _I286_H_ -#include "./i86.h" +#include "vm_template.h" +#include "./device.h" + +#define SIG_I86_TEST 0 #define SIG_I286_A20 1 class DEBUGGER; -class I80286 : public I8086 +class DLL_PREFIX I286 : public DEVICE { +private: + DEVICE *d_mem, *d_io, *d_pic; +//#ifdef I86_PSEUDO_BIOS + DEVICE *d_bios; +//#endif +//#ifdef SINGLE_MODE_DMA + DEVICE *d_dma; +//#endif +//#ifdef USE_DEBUGGER + DEBUGGER *d_debugger; +//#endif + void *opaque; + public: - I80286(VM_TEMPLATE* parent_vm, EMU* parent_emu) : I8086(parent_vm, parent_emu) + I286(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { + d_mem = NULL; + d_io = NULL; + d_pic = NULL; + d_bios = NULL; + d_dma = NULL; + d_debugger = NULL; + opaque = NULL; + set_device_name(_T("80286 CPU")); } - ~I80286() {} + ~I286() {} // common functions void initialize(); @@ -32,14 +56,26 @@ class I80286 : public I8086 int __FASTCALL run(int icount); uint32_t __FASTCALL read_signal(int id); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void set_intr_line(bool line, bool pending, uint32_t bit); - void set_extra_clock(int icount); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); + void __FASTCALL set_extra_clock(int icount); int get_extra_clock(); uint32_t get_pc(); uint32_t get_next_pc(); + uint32_t __FASTCALL translate_address(int segment, uint32_t offset); - + bool is_cpu() + { + return true; + } + bool is_debugger_available() + { + return true; + } + void *get_debugger() + { + return d_debugger; + } uint32_t get_debug_prog_addr_mask() { return 0xffffff; @@ -64,6 +100,35 @@ class I80286 : public I8086 bool process_state(FILEIO* state_fio, bool loading); // unique function + void set_context_mem(DEVICE* device) + { + d_mem = device; + } + void set_context_io(DEVICE* device) + { + d_io = device; + } + void set_context_intr(DEVICE* device, uint32_t bit = 0xfffffffff) + { + d_pic = device; + } +//#ifdef I86_PSEUDO_BIOS + void set_context_bios(DEVICE* device) + { + d_bios = device; + } +//#endif +//#ifdef SINGLE_MODE_DMA + void set_context_dma(DEVICE* device) + { + d_dma = device; + } +//#endif +//#ifdef USE_DEBUGGER + void set_context_debugger(DEBUGGER* device) + { + d_debugger = device; + } void set_address_mask(uint32_t mask); uint32_t get_address_mask(); void set_shutdown_flag(int shutdown); diff --git a/source/src/vm/i286_np21.cpp b/source/src/vm/i286_np21.cpp new file mode 100644 index 000000000..f833b1a4e --- /dev/null +++ b/source/src/vm/i286_np21.cpp @@ -0,0 +1,506 @@ +/* + Skelton for retropc emulator + + Origin : np21/w i386c core + Author : Takeda.Toshiya + Date : 2020.02.02- + + [ i286 ] +*/ + +#include "i286_np21.h" +//#ifdef USE_DEBUGGER +#include "debugger.h" +#include "i386_dasm.h" +#include "v30_dasm.h" +//#endif +namespace I286_NP21 { + #include "np21/i286c/cpucore.h" + #include "np21/i286c/v30patch.h" +} + + +void I286::initialize() +{ + DEVICE::initialize(); + _SINGLE_MODE_DMA = osd->check_feature("SINGLE_MODE_DMA"); + _USE_DEBUGGER = osd->check_feature("USE_DEBUGGER"); + I286_NP21::device_cpu = this; +//#ifdef USE_DEBUGGER + I286_NP21::device_mem_stored = device_mem; + I286_NP21::device_io_stored = device_io; + I286_NP21::device_debugger->set_context_mem(device_mem); + I286_NP21::device_debugger->set_context_io(device_io); +//#endif + CPU_INITIALIZE(); + CPU_ADRSMASK = 0x000fffff; + nmi_pending = irq_pending = false; + waitfactor = 65536; + I286_NP21::_SINGLE_MODE_DMA = _SINGLE_MODE_DMA; +} + +void I286::release() +{ + CPU_DEINITIALIZE(); +} + +void I286::reset() +{ + UINT32 PREV_CPU_ADRSMASK = CPU_ADRSMASK; + CPU_RESET(); + if(device_model == NEC_V30) { + CPU_TYPE = CPUTYPE_V30; + v30cinit(); + set_device_name(_T("V30 CPU")); + } else if(device_model == INTEL_8086) { + CPU_TYPE = CPUTYPE_I8086; + i86cinit(); + set_device_name(_T("8086 CPU")); + } else if(device_model == INTEL_80186) { + CPU_TYPE = CPUTYPE_I80186; + i186cinit(); + set_device_name(_T("80186 CPU")); + } else { + CPU_TYPE = 0; + device_model = INTEL_80286; + set_device_name(_T("80286 CPU")); + } + CS_BASE = PREV_CS_BASE = 0xf0000; + CPU_CS = 0xf000; + CPU_IP = CPU_PREV_IP = 0xfff0; + CPU_ADRSMASK = PREV_CPU_ADRSMASK; + CPU_CLEARPREFETCH(); + i286_memory_wait = 0; + waitcount = 0; + remained_cycles = extra_cycles = 0; +} + +void I286::cpu_wait(int clocks) +{ + if(clocks <= 0) clocks = 1; + int64_t wfactor = waitfactor; + int64_t wcount = waitcount; + int64_t mwait = i286_memory_wait; + int64_t ncount; + if(wfactor > 65536) { + wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock. + } + wcount += (wfactor * mwait); // memory wait + if(wcount >= 65536) { + ncount = wcount >> 16; + wcount = wcount - (ncount << 16); + extra_cycles += (int)ncount; + } else if(wcount < 0) { + wcount = 0; + } + waitcount = wcount; + i286_memory_wait = 0; +} + +int I286::run_one_opecode() +{ +//#ifdef USE_DEBUGGER + bool now_debugging = device_debugger->now_debugging; + if(now_debugging) { + device_debugger->check_break_points(get_next_pc()); + if(device_debugger->now_suspended) { + device_debugger->now_waiting = true; + emu->start_waiting_in_debugger(); + while(device_debugger->now_debugging && device_debugger->now_suspended) { + emu->process_waiting_in_debugger(); + } + emu->finish_waiting_in_debugger(); + device_debugger->now_waiting = false; + } + if(device_debugger->now_debugging) { + device_mem = device_io = device_debugger; + } else { + now_debugging = false; + } + + PREV_CS_BASE = CS_BASE; + CPU_PREV_IP = CPU_IP; + CPU_REMCLOCK = CPU_BASECLOCK = 1; + if(CPU_TYPE) { + CPU_EXECV30(); + } else { + CPU_EXEC(); + } + if(nmi_pending) { + CPU_INTERRUPT(2, 0); + nmi_pending = false; + } else if(irq_pending && CPU_isEI) { + CPU_INTERRUPT(device_pic->get_intr_ack(), 0); + irq_pending = false; + device_pic->update_intr(); + } + if(now_debugging) { + if(!device_debugger->now_going) { + device_debugger->now_suspended = true; + } + device_mem = device_mem_stored; + device_io = device_io_stored; + } + return CPU_BASECLOCK - CPU_REMCLOCK; + } else { +//#endif + PREV_CS_BASE = CS_BASE; + CPU_PREV_IP = CPU_IP; + CPU_REMCLOCK = CPU_BASECLOCK = 1; + if(CPU_TYPE) { + CPU_EXECV30(); + } else { + CPU_EXEC(); + } + if(nmi_pending) { + CPU_INTERRUPT(2, 0); + nmi_pending = false; + } else if(irq_pending && CPU_isEI) { + CPU_INTERRUPT(device_pic->get_intr_ack(), 0); + irq_pending = false; + device_pic->update_intr(); + } + return CPU_BASECLOCK - CPU_REMCLOCK; +//#ifdef USE_DEBUGGER + } +//#endif +} + +int I286::run(int cycles) +{ + if(cycles == -1) { + int passed_cycles; + if(busreq) { + // don't run cpu! +//#ifdef SINGLE_MODE_DMA + if(_SINGLE_MODE_DMA) { + if(device_dma != NULL) device_dma->do_dma(); + } +//#endif + passed_cycles = max(5, extra_cycles); // 80286 CPI: 4.8 + extra_cycles = 0; + } else { + // run only one opcode + passed_cycles = extra_cycles; + extra_cycles = 0; + passed_cycles += run_one_opecode(); + } +//#ifdef USE_DEBUGGER + total_cycles += passed_cycles; +//#endif + return passed_cycles; + } else { + remained_cycles += cycles + extra_cycles; + extra_cycles = 0; + int first_cycles = remained_cycles; + + // run cpu while given clocks + while(remained_cycles > 0 && !busreq) { + remained_cycles -= run(-1); + } + // if busreq is raised, spin cpu while remained clock + if(remained_cycles > 0 && busreq) { +//#ifdef USE_DEBUGGER + total_cycles += remained_cycles; +//#endif + remained_cycles = 0; + } + return first_cycles - remained_cycles; + } +} + +void I286::write_signal(int id, uint32_t data, uint32_t mask) +{ + if(id == SIG_CPU_NMI) { + nmi_pending = ((data & mask) != 0); + } else if(id == SIG_CPU_IRQ) { + irq_pending = ((data & mask) != 0); + } else if(id == SIG_CPU_BUSREQ) { + busreq = ((data & mask) != 0); + } else if(id == SIG_I286_A20) { + CPU_ADRSMASK = (data & mask) ? 0x00ffffff : 0x000fffff; + } else if(id == SIG_CPU_WAIT_FACTOR) { + waitfactor = data; // 65536. + waitcount = 0; // 65536. + } +} + +void I286::set_intr_line(bool line, bool pending, uint32_t bit) +{ + irq_pending = line; +} + +void I286::set_extra_clock(int cycles) +{ + extra_cycles += cycles; +} + +int I286::get_extra_clock() +{ + return extra_cycles; +} + +uint32_t I286::get_pc() +{ + return PREV_CS_BASE + CPU_PREV_IP; +} + +uint32_t I286::get_next_pc() +{ + return CS_BASE + CPU_IP; +} + +//#ifdef USE_DEBUGGER +void I286::write_debug_data8(uint32_t addr, uint32_t data) +{ + int wait; + device_mem->write_data8w(addr, data, &wait); +} + +uint32_t I286::read_debug_data8(uint32_t addr) +{ + int wait; + return device_mem->read_data8w(addr, &wait); +} + +void I286::write_debug_data16(uint32_t addr, uint32_t data) +{ + int wait; + device_mem->write_data16w(addr, data, &wait); +} + +uint32_t I286::read_debug_data16(uint32_t addr) +{ + int wait; + return device_mem->read_data16w(addr, &wait); +} + +void I286::write_debug_io8(uint32_t addr, uint32_t data) +{ + int wait; + device_io->write_io8w(addr, data, &wait); +} + +uint32_t I286::read_debug_io8(uint32_t addr) +{ + int wait; + return device_io->read_io8w(addr, &wait); +} + +void I286::write_debug_io16(uint32_t addr, uint32_t data) +{ + int wait; + device_io->write_io16w(addr, data, &wait); +} + +uint32_t I286::read_debug_io16(uint32_t addr) +{ + int wait; + return device_io->read_io16w(addr, &wait); +} + +bool I286::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + if(_tcsicmp(reg, _T("IP")) == 0) { + CPU_IP = data; + } else if(_tcsicmp(reg, _T("AX")) == 0) { + CPU_AX = data; + } else if(_tcsicmp(reg, _T("BX")) == 0) { + CPU_BX = data; + } else if(_tcsicmp(reg, _T("CX")) == 0) { + CPU_CX = data; + } else if(_tcsicmp(reg, _T("DX")) == 0) { + CPU_DX = data; + } else if(_tcsicmp(reg, _T("SP")) == 0) { + CPU_SP = data; + } else if(_tcsicmp(reg, _T("BP")) == 0) { + CPU_BP = data; + } else if(_tcsicmp(reg, _T("SI")) == 0) { + CPU_SI = data; + } else if(_tcsicmp(reg, _T("DI")) == 0) { + CPU_DI = data; + } else if(_tcsicmp(reg, _T("AL")) == 0) { + CPU_AL = data; + } else if(_tcsicmp(reg, _T("AH")) == 0) { + CPU_AH = data; + } else if(_tcsicmp(reg, _T("BL")) == 0) { + CPU_BL = data; + } else if(_tcsicmp(reg, _T("BH")) == 0) { + CPU_BH = data; + } else if(_tcsicmp(reg, _T("CL")) == 0) { + CPU_CL = data; + } else if(_tcsicmp(reg, _T("CH")) == 0) { + CPU_CH = data; + } else if(_tcsicmp(reg, _T("DL")) == 0) { + CPU_DL = data; + } else if(_tcsicmp(reg, _T("DH")) == 0) { + CPU_DH = data; + } else { + return false; + } + return true; +} + +uint32_t I286::read_debug_reg(const _TCHAR *reg) +{ + if(_tcsicmp(reg, _T("IP")) == 0) { + return CPU_IP; + } else if(_tcsicmp(reg, _T("AX")) == 0) { + return CPU_AX; + } else if(_tcsicmp(reg, _T("BX")) == 0) { + return CPU_BX; + } else if(_tcsicmp(reg, _T("CX")) == 0) { + return CPU_CX; + } else if(_tcsicmp(reg, _T("DX")) == 0) { + return CPU_DX; + } else if(_tcsicmp(reg, _T("SP")) == 0) { + return CPU_SP; + } else if(_tcsicmp(reg, _T("BP")) == 0) { + return CPU_BP; + } else if(_tcsicmp(reg, _T("SI")) == 0) { + return CPU_SI; + } else if(_tcsicmp(reg, _T("DI")) == 0) { + return CPU_DI; + } else if(_tcsicmp(reg, _T("AL")) == 0) { + return CPU_AL; + } else if(_tcsicmp(reg, _T("AH")) == 0) { + return CPU_AH; + } else if(_tcsicmp(reg, _T("BL")) == 0) { + return CPU_BL; + } else if(_tcsicmp(reg, _T("BH")) == 0) { + return CPU_BH; + } else if(_tcsicmp(reg, _T("CL")) == 0) { + return CPU_CL; + } else if(_tcsicmp(reg, _T("CH")) == 0) { + return CPU_CH; + } else if(_tcsicmp(reg, _T("DL")) == 0) { + return CPU_DL; + } else if(_tcsicmp(reg, _T("DH")) == 0) { + return CPU_DH; + } + return 0; +} + +bool I286::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + my_stprintf_s(buffer, buffer_len, + _T("AX=%04X BX=%04X CX=%04X DX=%04X SP=%04X BP=%04X SI=%04X DI=%04X\n") + _T("DS=%04X ES=%04X SS=%04X CS=%04X IP=%04X FLAG=[%c%c%c%c%c%c%c%c%c]\n") + _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), + CPU_AX, CPU_BX, CPU_CX, CPU_DX, CPU_SP, CPU_BP, CPU_SI, CPU_DI, + CPU_DS, CPU_ES, CPU_SS, CPU_CS, CPU_IP, + (CPU_FLAG & O_FLAG) ? _T('O') : _T('-'), (CPU_FLAG & D_FLAG) ? _T('D') : _T('-'), (CPU_FLAG & I_FLAG) ? _T('I') : _T('-'), (CPU_FLAG & T_FLAG) ? _T('T') : _T('-'), (CPU_FLAG & S_FLAG) ? _T('S') : _T('-'), + (CPU_FLAG & Z_FLAG) ? _T('Z') : _T('-'), (CPU_FLAG & A_FLAG) ? _T('A') : _T('-'), (CPU_FLAG & P_FLAG) ? _T('P') : _T('-'), (CPU_FLAG & C_FLAG) ? _T('C') : _T('-'), + total_cycles, total_cycles - prev_total_cycles, + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + prev_total_cycles = total_cycles; + return true; +} + +int I286::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) +{ + uint32_t eip = pc - (CPU_CS << 4); + uint8_t oprom[16]; + + for(int i = 0; i < 16; i++) { + int wait; + oprom[i] = device_mem->read_data8w((pc + i) & CPU_ADRSMASK, &wait); + } + if(device_model == NEC_V30) { + return v30_dasm(oprom, eip, buffer, buffer_len); + } else { + return i386_dasm(oprom, eip, false, buffer, buffer_len); + } +} +#endif + +void I286::set_address_mask(uint32_t mask) +{ + CPU_ADRSMASK = mask; +} + +uint32_t I286::get_address_mask() +{ + return CPU_ADRSMASK; +} + +void I286::set_shutdown_flag(int shutdown) +{ + // FIXME: shutdown just now + if(shutdown) CPU_SHUT(); +} + +int I286::get_shutdown_flag() +{ + // FIXME: shutdown already done + return 0; +} + +void I286::set_context_mem(DEVICE* device) +{ + device_mem = device; +} + +void I286::set_context_io(DEVICE* device) +{ + device_io = device; +} + +//#ifdef I86_PSEUDO_BIOS +void I286::set_context_bios(DEVICE* device) +{ + device_bios = device; +} +//#endif + +//#ifdef SINGLE_MODE_DMA +void I286::set_context_dma(DEVICE* device) +{ + device_dma = device; +} +//#endif + +//#ifdef USE_DEBUGGER +void I286::set_context_debugger(DEBUGGER* device) +{ + device_debugger = device; +} + +void *I286::get_debugger() +{ + return device_debugger; +} +//#endif + +#define STATE_VERSION 2 + +bool I286::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + // FIXME + state_fio->StateBuffer(&CPU_STATSAVE, sizeof(CPU_STATSAVE), 1); +//#ifdef USE_DEBUGGER + if(_USE_DEBUGGER) { + state_fio->StateValue(total_cycles); + state_fio->StateValue(prev_total_cycles); + } +//#endif + state_fio->StateValue(remained_cycles); + state_fio->StateValue(extra_cycles); + state_fio->StateValue(busreq); + state_fio->StateValue(nmi_pending); + state_fio->StateValue(irq_pending); + state_fio->StateValue(PREV_CS_BASE); + state_fio->StateValue(CPU_PREV_IP); + + state_fio->StateValue(waitfactor); + state_fio->StateValue(waitcount); + state_fio->StateValue(i286_memory_wait); + return true; +} + diff --git a/source/src/vm/i286_np21.h b/source/src/vm/i286_np21.h new file mode 100644 index 000000000..58bffb6a7 --- /dev/null +++ b/source/src/vm/i286_np21.h @@ -0,0 +1,156 @@ +/* + Skelton for retropc emulator + + Origin : np21/w i386c core + Author : Takeda.Toshiya + Date : 2020.02.02- + + [ i286 ] +*/ + +#ifndef _I286_NP21_H_ +#define _I286_NP21_H_ + +#include "vm_template.h" +//#include "../emu.h" +#include "device.h" + +#define SIG_I286_A20 0 + +enum { + INTEL_80286 = 0, + NEC_V30, + INTEL_8086, + INTEL_80186, +}; + +//#ifdef USE_DEBUGGER +class DEBUGGER; +//#endif + +class DLL_PREFIX I286 : public DEVICE +{ +private: + bool _SINGLE_MODE_DMA; + bool _USE_DEBUGGER; + DEVICE *device_pic; +//#ifdef USE_DEBUGGER +// DEBUGGER *device_debugger; + DEVICE *device_mem_stored; + DEVICE *device_io_stored; + uint64_t total_cycles; + uint64_t prev_total_cycles; +//#endif + int remained_cycles, extra_cycles; + bool busreq; + bool nmi_pending, irq_pending; + uint32_t PREV_CS_BASE; + uint16_t CPU_PREV_IP; + uint32_t waitfactor; + int64_t waitcount; + + int run_one_opecode(); + void cpu_wait(int clocks); + +public: + I286(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { +//#ifdef USE_DEBUGGER + total_cycles = prev_total_cycles = 0; +//#endif + busreq = false; + device_model = INTEL_80286; + } + ~I286() {} + + // common functions + void initialize(); + void release(); + void reset(); + int __FASTCALL run(int cycles); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); + void __FASTCALL set_extra_clock(int cycles); + int get_extra_clock(); + uint32_t get_pc(); + uint32_t get_next_pc(); +//#ifdef USE_DEBUGGER + bool is_cpu() + { + return true; + } + bool is_debugger_available() + { + return true; + } + void *get_debugger(); + uint32_t get_debug_prog_addr_mask() + { + if(device_model == INTEL_80286) { + return 0xffffff; + } else { + return 0xfffff; + } + } + uint32_t get_debug_data_addr_mask() + { + if(device_model == INTEL_80286) { + return 0xffffff; + } else { + return 0xfffff; + } + } + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data16(uint32_t addr); + void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io8(uint32_t addr); + void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io16(uint32_t addr); + bool __FASTCALL write_debug_reg(const _TCHAR *reg, uint32_t data); + uint32_t read_debug_reg(const _TCHAR *reg); + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len); +//#endif + bool process_state(FILEIO* state_fio, bool loading); + + // unique function + void set_context_mem(DEVICE* device); +// { +// device_mem = device; +// } + void set_context_io(DEVICE* device); +// { +// device_io = device; +// } + void set_context_intr(DEVICE* device, uint32_t bit = 0xfffffffff) + { + device_pic = device; + } +//#ifdef I86_PSEUDO_BIOS + void set_context_bios(DEVICE* device); +// { +// device_bios = device; +// } +//#endif +//#ifdef SINGLE_MODE_DMA + void set_context_dma(DEVICE* device); +// { +// device_dma = device; +// } +//#endif +//#ifdef USE_DEBUGGER + void set_context_debugger(DEBUGGER* device); +// { +// device_debugger = device; +// } +//#endif + void set_address_mask(uint32_t mask); + uint32_t get_address_mask(); + void set_shutdown_flag(int shutdown); + int get_shutdown_flag(); + int device_model; +}; + +#endif diff --git a/source/src/vm/i386.cpp b/source/src/vm/i386.cpp index b545f9033..0cbfb5b34 100644 --- a/source/src/vm/i386.cpp +++ b/source/src/vm/i386.cpp @@ -3,7 +3,7 @@ Origin : MAME i386 core Author : Takeda.Toshiya - Date : 2009.06.08- + Date : 2009.06.08- [ i386/i486/Pentium/MediaGX ] */ @@ -11,6 +11,7 @@ #include "i386.h" //#ifdef USE_DEBUGGER #include "debugger.h" +#include "i386_dasm.h" //#endif /* ---------------------------------------------------------------------------- @@ -111,28 +112,13 @@ #define CPU_RESET_CALL(name) CPU_RESET_NAME(name)(cpustate) #define CPU_EXECUTE_NAME(name) cpu_execute_##name -#define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(i386_state *cpustate, int cycles) +#define CPU_EXECUTE(name) int __FASTCALL CPU_EXECUTE_NAME(name)(i386_state *cpustate, int cycles) #define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate, cycles) #define CPU_TRANSLATE_NAME(name) cpu_translate_##name #define CPU_TRANSLATE(name) int CPU_TRANSLATE_NAME(name)(void *cpudevice, address_spacenum space, int intention, offs_t *address) #define CPU_TRANSLATE_CALL(name) CPU_TRANSLATE_NAME(name)(cpudevice, space, intention, address) -#define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom) -#define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, eip, oprom) - -/*****************************************************************************/ -/* src/emu/didisasm.h */ - -// Disassembler constants -const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported? -const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence -const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards -const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over -const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value -const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length - /*****************************************************************************/ /* src/emu/diexec.h */ @@ -221,13 +207,9 @@ enum address_spacenum // offsets and addresses are 32-bit (for now...) typedef UINT32 offs_t; -/*****************************************************************************/ -/* src/osd/osdcomm.h */ - -/* Highly useful macro for compile-time knowledge of an array size */ -#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0])) -//#ifdef I386_PSEUDO_BIOS +////#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS #define BIOS_INT(num) if(cpustate->bios != NULL) { \ /*if(((cpustate->cr[0] & 0x0001) == 0) || (cpustate->VM != 0)) */{ /* VM8086 or Not Protected */ \ uint16_t regs[10], sregs[4]; \ @@ -342,9 +324,6 @@ void terminate() #include "mame/lib/softfloat/fsincos.c" #include "mame/emu/cpu/vtlb.c" #include "mame/emu/cpu/i386/i386.c" -//#ifdef USE_DEBUGGER -#include "mame/emu/cpu/i386/i386dasm.c" -//#endif void I386::initialize() { @@ -416,7 +395,7 @@ void I386::initialize() cpustate->pic = d_pic; cpustate->program = d_mem; cpustate->io = d_io; -//#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS cpustate->bios = d_bios; //#endif //#ifdef SINGLE_MODE_DMA @@ -494,7 +473,7 @@ void I386::write_signal(int id, uint32_t data, uint32_t mask) } else if(id == SIG_I386_A20) { i386_set_a20_line(cpustate, data & mask); } else if(id == SIG_I386_NOTIFY_RESET) { - write_signals(&outputs_extreset, ((data & mask == 0) ? 0x00000000 : 0xffffffff)); + write_signals(&outputs_extreset, (((data & mask) == 0) ? 0x00000000 : 0xffffffff)); } else if(id == SIG_CPU_WAIT_FACTOR) { cpustate->waitfactor = data; // 65536. cpustate->waitcount = 0; // 65536. @@ -585,7 +564,8 @@ void I386::write_debug_io8(uint32_t addr, uint32_t data) d_io->write_io8w(addr, data, &wait); } -uint32_t I386::read_debug_io8(uint32_t addr) { +uint32_t I386::read_debug_io8(uint32_t addr) +{ int wait; return d_io->read_io8w(addr, &wait); } @@ -596,7 +576,8 @@ void I386::write_debug_io16(uint32_t addr, uint32_t data) d_io->write_io16w(addr, data, &wait); } -uint32_t I386::read_debug_io16(uint32_t addr) { +uint32_t I386::read_debug_io16(uint32_t addr) +{ int wait; return d_io->read_io16w(addr, &wait); } @@ -607,7 +588,8 @@ void I386::write_debug_io32(uint32_t addr, uint32_t data) d_io->write_io32w(addr, data, &wait); } -uint32_t I386::read_debug_io32(uint32_t addr) { +uint32_t I386::read_debug_io32(uint32_t addr) +{ int wait; return d_io->read_io32w(addr, &wait); } @@ -734,75 +716,157 @@ uint32_t I386::read_debug_reg(const _TCHAR *reg) return 0; } -bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +void I386::get_debug_gregs_info(_TCHAR *buffer, size_t buffer_len) +{ + i386_state *cpustate = (i386_state *)opaque; + _TCHAR gprstr[64][256]; // Reserve for Rxx etc + static const int gprlist_i[] = {EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI, -1}; + static const _TCHAR *gprlist_s[] = {_T("EAX"), _T("EBX"), _T("ECX"), _T("EDX"), _T("ESP"), _T("EBP"), _T("ESI"), _T("EDI"), NULL}; + int regnum = 0; + while(gprlist_i[regnum] >= 0) { + memset(gprstr[regnum], 0x00, sizeof(_TCHAR) * 256); + my_stprintf_s(gprstr[regnum], 255, _T("%s=%08X "), gprlist_s[regnum], REG32(gprlist_i[regnum])); + regnum++; + if(regnum >= 64) break; + } + regnum = 0; + if(buffer != NULL) { + while(gprlist_i[regnum] >= 0) { + my_tcscat_s(buffer, buffer_len, gprstr[regnum]); + regnum++; + if(regnum >= 64) break; + } + my_tcscat_s(buffer, buffer_len, _T("\n")); + } +} + +void I386::get_debug_sregs_info(_TCHAR *buffer, size_t buffer_len) { i386_state *cpustate = (i386_state *)opaque; + _TCHAR segstr[8][256]; + static const int seglist_i[] = {CS, SS, DS, ES, FS, GS, -1}; + static const _TCHAR *seglist_s[] = {_T("CS"), _T("SS"), _T("DS"), _T("ES"), _T("FS"), _T("GS"), NULL}; + int segnum = 0; + while(seglist_i[segnum] >= 0) { + memset(segstr[segnum], 0x00, sizeof(_TCHAR) * 256); + int realseg = seglist_i[segnum]; + my_stprintf_s(segstr[segnum], 255, + _T("%s : SELECTOR=%04X BASE=%08X LIMIT=%08X FLAGS=%04X D=%d %s\n") + , + seglist_s[segnum], + cpustate->sreg[realseg].selector, + cpustate->sreg[realseg].base, + cpustate->sreg[realseg].limit, + cpustate->sreg[realseg].flags, + cpustate->sreg[realseg].d, + (cpustate->sreg[realseg].valid) ? _T("VALID") : _T("INVALID") + ); + segnum++; + if(segnum >= 8) break; + } + segnum = 0; + if(buffer != NULL) { + while(seglist_i[segnum] >= 0) { + my_tcscat_s(buffer, buffer_len, segstr[segnum]); + segnum++; + if(segnum >= 8) break; + } + } +} +bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + i386_state *cpustate = (i386_state *)opaque; + _TCHAR segstr[256 * 12] = {0}; + _TCHAR gprstr[256 * 64] = {0}; + get_debug_sregs_info(segstr, sizeof(segstr) / sizeof(_TCHAR)); + get_debug_gregs_info(gprstr, sizeof(gprstr) / sizeof(_TCHAR)); + if(cpustate->operand_size) { my_stprintf_s(buffer, buffer_len, _T("MODE=%s PC=%08X PREV_PC=%08X SP(REAL)=%08X\n") _T("CR[0-4]=%08X %08X %08X %08X %08X IOPL=%d CPL=%d\n") - _T("EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESP=%08X EBP=%08X ESI=%08X EDI=%08X\n") - _T("DS=%04X ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X\n") + _T("%s") + _T("%s") _T("A20_MASK=%08X EIP=%08X EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n") + _T("GDTR: BASE=%08X LIMIT=%08X LDTR: BASE=%08X LIMIT=%08X\n") _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), (PROTECTED_MODE != 0) ? ((V8086_MODE) ? _T("PROTECTED V8086(32bit)") : _T("PROTECTED 32bit")) : ((V8086_MODE) ? _T("V8086(32bit)") : _T("32bit")), cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG32(ESP)), cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL, - REG32(EAX), REG32(EBX), REG32(ECX), REG32(EDX), REG32(ESP), REG32(EBP), REG32(ESI), REG32(EDI), - cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip, cpustate->eflags, + gprstr, + segstr, + cpustate->a20_mask, cpustate->eip, cpustate->eflags, cpustate->OF ? _T('O') : _T('-'), cpustate->DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), cpustate->SF ? _T('S') : _T('-'), cpustate->ZF ? _T('Z') : _T('-'), cpustate->AF ? _T('A') : _T('-'), cpustate->PF ? _T('P') : _T('-'), cpustate->CF ? _T('C') : _T('-'), + cpustate->gdtr.base, cpustate->gdtr.limit, + cpustate->ldtr.base, cpustate->ldtr.limit, cpustate->total_cycles, cpustate->total_cycles - cpustate->prev_total_cycles, - get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame() + ); } else { if((PROTECTED_MODE) != 0) { if((V8086_MODE)) { my_stprintf_s(buffer, buffer_len, _T("MODE=V8086 (PROTECTED) PC=%08X PREV_PC=%08X SP(REAL)=%08X\n") _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n") - _T("AX=%04X BX=%04X CX=%04X DX=%04X SP=%04X BP=%04X SI=%04X DI=%04X\n") - _T("DS=%04X ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X A20_MASK=%08X IP=%04X FLAG=[%c%c%c%c%c%c%c%c%c]\n") + _T("%s") + _T("%s") + _T("A20_MASK=%08X IP=%04X FLAG=[%c%c%c%c%c%c%c%c%c]\n") + _T("GDTR: BASE=%08X LIMIT=%08X LDTR: BASE=%08X LIMIT=%08X\n") _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG32(ESP) & 0xffff), cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL, - REG16(AX), REG16(BX), REG16(CX), REG16(DX), REG16(SP), REG16(BP), REG16(SI), REG16(DI), - cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip, + gprstr, + segstr, + cpustate->a20_mask, cpustate->eip, cpustate->OF ? _T('O') : _T('-'), cpustate->DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), cpustate->SF ? _T('S') : _T('-'), cpustate->ZF ? _T('Z') : _T('-'), cpustate->AF ? _T('A') : _T('-'), cpustate->PF ? _T('P') : _T('-'), cpustate->CF ? _T('C') : _T('-'), + cpustate->gdtr.base, cpustate->gdtr.limit, + cpustate->ldtr.base, cpustate->ldtr.limit, cpustate->total_cycles, cpustate->total_cycles - cpustate->prev_total_cycles, get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); } else { my_stprintf_s(buffer, buffer_len, - _T("MODE=PROTECTED 16bit PC=%08X PREV_PC=%08X SP(REAL)=%08X\n") - _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n") - _T("AX=%04X BX=%04X CX=%04X DX=%04X SP=%04X BP=%04X SI=%04X DI=%04X\n") - _T("DS=%04X ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X A20_MASK=%08X IP=%04X EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n") - _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), + _T("MODE=PROTECTED 16bit PC=%08X PREV_PC=%08X SP(REAL)=%08X\n") + _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n") + _T("%s") + _T("%s") + _T("A20_MASK=%08X IP=%04X EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n") + _T("GDTR: BASE=%08X LIMIT=%08X LDTR: BASE=%08X LIMIT=%08X\n") + _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG32(ESP)), - cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL, - REG16(AX), REG16(BX), REG16(CX), REG16(DX), REG16(SP), REG16(BP), REG16(SI), REG16(DI), - cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip, cpustate->eflags, - cpustate->OF ? _T('O') : _T('-'), cpustate->DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), - cpustate->SF ? _T('S') : _T('-'), cpustate->ZF ? _T('Z') : _T('-'), cpustate->AF ? _T('A') : _T('-'), cpustate->PF ? _T('P') : _T('-'), cpustate->CF ? _T('C') : _T('-'), - cpustate->total_cycles, cpustate->total_cycles - cpustate->prev_total_cycles, - get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL, + gprstr, + segstr, + cpustate->a20_mask, cpustate->eip, cpustate->eflags, + cpustate->OF ? _T('O') : _T('-'), cpustate->DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), + cpustate->SF ? _T('S') : _T('-'), cpustate->ZF ? _T('Z') : _T('-'), cpustate->AF ? _T('A') : _T('-'), cpustate->PF ? _T('P') : _T('-'), cpustate->CF ? _T('C') : _T('-'), + cpustate->gdtr.base, cpustate->gdtr.limit, + cpustate->ldtr.base, cpustate->ldtr.limit, + cpustate->total_cycles, cpustate->total_cycles - cpustate->prev_total_cycles, + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); } } else { my_stprintf_s(buffer, buffer_len, - _T("MODE=16bit PC=%08X PREV_PC=%08X SP(REAL)=%08X\n") - _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n") - _T("AX=%04X BX=%04X CX=%04X DX=%04X SP=%04X BP=%04X SI=%04X DI=%04X\n") - _T("DS=%04X ES=%04X SS=%04X CS=%04X FS=%04X GS=%04X A20_MASK=%08X IP=%04X EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n") - _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), + _T("MODE=16bit PC=%08X PREV_PC=%08X SP(REAL)=%08X\n") + _T("CR[0-4]=%08X %08X %08X %08X %08X IOP=%d CPL=%d\n") + _T("%s") + _T("%s") + _T("A20_MASK=%08X IP=%04X EFLAGS=%08X FLAG=[%c%c%c%c%c%c%c%c%c]\n") + _T("GDTR: BASE=%08X LIMIT=%08X LDTR: BASE=%08X LIMIT=%08X\n") + _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), cpustate->pc, cpustate->prev_pc, cpustate->sreg[SS].base + ((uint32_t)REG16(SP) & 0xffff), - cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL, - REG16(AX), REG16(BX), REG16(CX), REG16(DX), REG16(SP), REG16(BP), REG16(SI), REG16(DI), - cpustate->sreg[DS].selector, cpustate->sreg[ES].selector, cpustate->sreg[SS].selector, cpustate->sreg[CS].selector, cpustate->sreg[FS].selector, cpustate->sreg[GS].selector, cpustate->a20_mask, cpustate->eip, cpustate->eflags, - cpustate->OF ? _T('O') : _T('-'), cpustate->DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), - cpustate->SF ? _T('S') : _T('-'), cpustate->ZF ? _T('Z') : _T('-'), cpustate->AF ? _T('A') : _T('-'), cpustate->PF ? _T('P') : _T('-'), cpustate->CF ? _T('C') : _T('-'), - cpustate->total_cycles, cpustate->total_cycles - cpustate->prev_total_cycles, - get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + cpustate->cr[0] ,cpustate->cr[1], cpustate->cr[2], cpustate->cr[3], cpustate->cr[4], (cpustate->IOP1) | (cpustate->IOP2 << 1), cpustate->CPL, + gprstr, + segstr, + cpustate->a20_mask, cpustate->eip, cpustate->eflags, + cpustate->OF ? _T('O') : _T('-'), cpustate->DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), + cpustate->SF ? _T('S') : _T('-'), cpustate->ZF ? _T('Z') : _T('-'), cpustate->AF ? _T('A') : _T('-'), cpustate->PF ? _T('P') : _T('-'), cpustate->CF ? _T('C') : _T('-'), + cpustate->gdtr.base, cpustate->gdtr.limit, + cpustate->ldtr.base, cpustate->ldtr.limit, + cpustate->total_cycles, cpustate->total_cycles - cpustate->prev_total_cycles, + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); } } cpustate->prev_total_cycles = cpustate->total_cycles; @@ -812,17 +876,16 @@ int I386::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_le { i386_state *cpustate = (i386_state *)opaque; UINT64 eip = pc - cpustate->sreg[CS].base; - UINT8 ops[16]; + UINT8 oprom[16]; for(int i = 0; i < 16; i++) { int wait; - ops[i] = d_mem->read_data8w(pc + i, &wait); + oprom[i] = d_mem->read_data8w((pc + i) & cpustate->a20_mask, &wait); } - UINT8 *oprom = ops; bool __op32 = (userdata & I386_TRACE_DATA_BIT_USERDATA_SET) ? ((userdata & I386_TRACE_DATA_BIT_OP32) ? true : false) : ((cpustate->operand_size != 0) ? true : false); if(__op32) { - return CPU_DISASSEMBLE_CALL(x86_32) & DASMFLAG_LENGTHMASK; + return i386_dasm(oprom, eip, true, buffer, buffer_len); } else { - return CPU_DISASSEMBLE_CALL(x86_16) & DASMFLAG_LENGTHMASK; + return i386_dasm(oprom, eip, false, buffer, buffer_len); } } //#endif diff --git a/source/src/vm/i386.h b/source/src/vm/i386.h index 91db02a33..8949ff900 100644 --- a/source/src/vm/i386.h +++ b/source/src/vm/i386.h @@ -3,12 +3,12 @@ Origin : MAME i386 core Author : Takeda.Toshiya - Date : 2009.06.08- + Date : 2009.06.08- [ i386/i486/Pentium/MediaGX ] */ -#ifndef _I386_H_ +#ifndef _I386_H_ #define _I386_H_ //#if defined(USE_SHARED_DLL) //#if 0 @@ -27,11 +27,11 @@ class DEBUGGER; //#endif -class I386 : public DEVICE +class DLL_PREFIX I386 : public DEVICE { -private: +protected: DEVICE *d_mem, *d_io, *d_pic; -//#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS DEVICE *d_bios; //#endif //#ifdef SINGLE_MODE_DMA @@ -42,10 +42,12 @@ class I386 : public DEVICE //#endif void *opaque; outputs_t outputs_extreset; + void get_debug_sregs_info(_TCHAR *buffer, size_t buffer_len); + void get_debug_gregs_info(_TCHAR *buffer, size_t buffer_len); public: - I386(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I386(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { -//#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS d_bios = NULL; //#endif //#ifdef SINGLE_MODE_DMA @@ -82,8 +84,8 @@ class I386 : public DEVICE int __FASTCALL run(int cycles); uint32_t __FASTCALL read_signal(int id); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void set_intr_line(bool line, bool pending, uint32_t bit); - void set_extra_clock(int cycles); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); + void __FASTCALL set_extra_clock(int cycles); int get_extra_clock(); uint32_t get_pc(); uint32_t get_next_pc(); @@ -146,7 +148,7 @@ class I386 : public DEVICE { d_pic = device; } -//#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS void set_context_bios(DEVICE* device) { d_bios = device; diff --git a/source/src/vm/i386_dasm.cpp b/source/src/vm/i386_dasm.cpp new file mode 100644 index 000000000..b20db8f86 --- /dev/null +++ b/source/src/vm/i386_dasm.cpp @@ -0,0 +1,59 @@ +/* + Skelton for retropc emulator + + Origin : MAME i386 core + Author : Takeda.Toshiya + Date : 2020.02.02- + + [ i386 disassembler ] +*/ + +#include "i386_dasm.h" + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning( disable : 4146 ) +#pragma warning( disable : 4244 ) +#endif + +/*****************************************************************************/ +/* src/emu/devcpu.h */ + +// CPU interface functions +#define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name +#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom) +#define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, eip, oprom) + +/*****************************************************************************/ +/* src/emu/didisasm.h */ + +// Disassembler constants +const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported? +const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence +const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards +const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over +const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value +const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length + +// offsets and addresses are 32-bit (for now...) +typedef UINT32 offs_t; + +/*****************************************************************************/ +/* src/osd/osdcomm.h */ + +/* Highly useful macro for compile-time knowledge of an array size */ +#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0])) + +#ifndef INLINE +#define INLINE inline +#endif + +#include "mame/emu/cpu/i386/i386dasm.c" + +int i386_dasm(uint8_t *oprom, uint32_t eip, bool is_ia32, _TCHAR *buffer, size_t buffer_len) +{ + if(is_ia32) { + return CPU_DISASSEMBLE_CALL(x86_32) & DASMFLAG_LENGTHMASK; + } else { + return CPU_DISASSEMBLE_CALL(x86_16) & DASMFLAG_LENGTHMASK; + } +} diff --git a/source/src/vm/i386_dasm.h b/source/src/vm/i386_dasm.h new file mode 100644 index 000000000..eceb724aa --- /dev/null +++ b/source/src/vm/i386_dasm.h @@ -0,0 +1,18 @@ +/* + Skelton for retropc emulator + + Origin : MAME i386 core + Author : Takeda.Toshiya + Date : 2020.02.02- + + [ i386 disassembler ] +*/ + +#ifndef _I386_DASM_H_ +#define _I386_DASM_H_ + +#include "../common.h" + +int DLL_PREFIX i386_dasm(uint8_t *oprom, uint32_t eip, bool is_ia32, _TCHAR *buffer, size_t buffer_len); + +#endif diff --git a/source/src/vm/i386_np21.cpp b/source/src/vm/i386_np21.cpp new file mode 100644 index 000000000..0062c6233 --- /dev/null +++ b/source/src/vm/i386_np21.cpp @@ -0,0 +1,1010 @@ +/* + Skelton for retropc emulator + + Origin : np21/w i386c core + Author : Takeda.Toshiya + Date : 2020.01.25- + + [ i386/i486/Pentium ] +*/ + +#include "i386_np21.h" +//#ifdef USE_DEBUGGER +#include "debugger.h" +#include "i386_dasm.h" +//#endif +#include "np21/i386c/cpucore.h" +#include "np21/i386c/ia32/instructions/fpu/fp.h" + +void I386::initialize() +{ + DEVICE::initialize(); + _I86_PSEUDO_BIOS = osd->check_feature("I86_PSEUDO_BIOS"); + _SINGLE_MODE_DMA = osd->check_feature("SINGLE_MODE_DMA"); + _USE_DEBUGGER = osd->check_feature("USE_DEBUGGER"); +// realclock = get_cpu_clocks(this); + device_cpu = this; + +//#ifdef USE_DEBUGGER + if(_USE_DEBUGGER) { + device_mem_stored = device_mem; + device_io_stored = device_io; + device_debugger->set_context_mem(device_mem); + device_debugger->set_context_io(device_io); + } else { + device_debugger = NULL; + } +//#endif + if(!(_I86_PSEUDO_BIOS)) { + device_bios = NULL; + } + if(!(_SINGLE_MODE_DMA)) { + device_dma = NULL; + } + waitfactor = 65536; + CPU_INITIALIZE(); + CPU_ADRSMASK = 0x000fffff; + realclock = get_cpu_clocks(this); + nmi_pending = irq_pending = false; +} + +void I386::release() +{ + CPU_DEINITIALIZE(); +} + +void I386::reset() +{ +//#if defined(HAS_I386) + out_debug_log(_T("RESET")); + switch(device_model) { + case INTEL_80386: + i386cpuid.cpu_family = CPU_80386_FAMILY; + i386cpuid.cpu_model = CPU_80386_MODEL; + i386cpuid.cpu_stepping = CPU_80386_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_80386; +// i386cpuid.cpu_feature = CPU_FEATURES_80386 | CPU_FEATURE_FPU; // 20200501 TMP K.O + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_80386; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_80386; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_80386; + i386cpuid.cpu_brandid = CPU_BRAND_ID_80386; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_80386); + set_device_name(_T("80386 CPU")); + break; + case INTEL_I486SX: + i386cpuid.cpu_family = CPU_I486SX_FAMILY; + i386cpuid.cpu_model = CPU_I486SX_MODEL; + i386cpuid.cpu_stepping = CPU_I486SX_STEPPING; +// i386cpuid.cpu_feature = CPU_FEATURES_I486SX; + i386cpuid.cpu_feature = CPU_FEATURES_I486SX | CPU_FEATURE_FPU; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_I486SX; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_I486SX; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_I486SX; + i386cpuid.cpu_brandid = CPU_BRAND_ID_I486SX; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_I486SX); + set_device_name(_T("80486SX CPU")); + break; + case INTEL_I486DX: + i386cpuid.cpu_family = CPU_I486DX_FAMILY; + i386cpuid.cpu_model = CPU_I486DX_MODEL; + i386cpuid.cpu_stepping = CPU_I486DX_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_I486DX; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_I486DX; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_I486DX; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_I486DX; + i386cpuid.cpu_brandid = CPU_BRAND_ID_I486DX; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_I486DX); + set_device_name(_T("80486DX CPU")); + break; + case INTEL_PENTIUM: + i386cpuid.cpu_family = CPU_PENTIUM_FAMILY; + i386cpuid.cpu_model = CPU_PENTIUM_MODEL; + i386cpuid.cpu_stepping = CPU_PENTIUM_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_PENTIUM; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_PENTIUM; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_PENTIUM; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_PENTIUM; + i386cpuid.cpu_brandid = CPU_BRAND_ID_PENTIUM; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_PENTIUM); + set_device_name(_T("Pentium CPU")); + break; + case INTEL_MMX_PENTIUM: + i386cpuid.cpu_family = CPU_MMX_PENTIUM_FAMILY; + i386cpuid.cpu_model = CPU_MMX_PENTIUM_MODEL; + i386cpuid.cpu_stepping = CPU_MMX_PENTIUM_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_MMX_PENTIUM; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_MMX_PENTIUM; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_MMX_PENTIUM; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_MMX_PENTIUM; + i386cpuid.cpu_brandid = CPU_BRAND_ID_MMX_PENTIUM; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_MMX_PENTIUM); + set_device_name(_T("MMX Pentium CPU")); + break; + case INTEL_PENTIUM_PRO: + i386cpuid.cpu_family = CPU_PENTIUM_PRO_FAMILY; + i386cpuid.cpu_model = CPU_PENTIUM_PRO_MODEL; + i386cpuid.cpu_stepping = CPU_PENTIUM_PRO_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_PENTIUM_PRO; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_PENTIUM_PRO; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_PENTIUM_PRO; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_PENTIUM_PRO; + i386cpuid.cpu_brandid = CPU_BRAND_ID_PENTIUM_PRO; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_PENTIUM_PRO); + set_device_name(_T("Pentium Pro CPU")); + break; + case INTEL_PENTIUM_II: + i386cpuid.cpu_family = CPU_PENTIUM_II_FAMILY; + i386cpuid.cpu_model = CPU_PENTIUM_II_MODEL; + i386cpuid.cpu_stepping = CPU_PENTIUM_II_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_PENTIUM_II; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_PENTIUM_II; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_PENTIUM_II; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_PENTIUM_II; + i386cpuid.cpu_brandid = CPU_BRAND_ID_PENTIUM_II; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_PENTIUM_II); + set_device_name(_T("Pentium II CPU")); + break; + case INTEL_PENTIUM_III: + i386cpuid.cpu_family = CPU_PENTIUM_III_FAMILY; + i386cpuid.cpu_model = CPU_PENTIUM_III_MODEL; + i386cpuid.cpu_stepping = CPU_PENTIUM_III_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_PENTIUM_III; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_PENTIUM_III; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_PENTIUM_III; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_PENTIUM_III; + i386cpuid.cpu_brandid = CPU_BRAND_ID_PENTIUM_III; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_PENTIUM_III); + set_device_name(_T("Pentium III CPU")); + break; + case INTEL_PENTIUM_M: + i386cpuid.cpu_family = CPU_PENTIUM_M_FAMILY; + i386cpuid.cpu_model = CPU_PENTIUM_M_MODEL; + i386cpuid.cpu_stepping = CPU_PENTIUM_M_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_PENTIUM_M; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_PENTIUM_M; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_PENTIUM_M; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_PENTIUM_M; + i386cpuid.cpu_brandid = CPU_BRAND_ID_PENTIUM_M; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_PENTIUM_M); + set_device_name(_T("Pentium M CPU")); + break; + case INTEL_PENTIUM_4: + i386cpuid.cpu_family = CPU_PENTIUM_4_FAMILY; + i386cpuid.cpu_model = CPU_PENTIUM_4_MODEL; + i386cpuid.cpu_stepping = CPU_PENTIUM_4_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_PENTIUM_4; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_PENTIUM_4; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_PENTIUM_4; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_PENTIUM_4; + i386cpuid.cpu_brandid = CPU_BRAND_ID_PENTIUM_4; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_INTEL); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_PENTIUM_4); + set_device_name(_T("Pentium 4 CPU")); + break; + case AMD_K6_2: + i386cpuid.cpu_family = CPU_AMD_K6_2_FAMILY; + i386cpuid.cpu_model = CPU_AMD_K6_2_MODEL; + i386cpuid.cpu_stepping = CPU_AMD_K6_2_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_AMD_K6_2; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_AMD_K6_2; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_AMD_K6_2; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_AMD_K6_2; + i386cpuid.cpu_brandid = CPU_BRAND_ID_AMD_K6_2; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_AMD); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_AMD_K6_2); + set_device_name(_T("AMD-K6 3D CPU")); + break; + case AMD_K6_III: + i386cpuid.cpu_family = CPU_AMD_K6_III_FAMILY; + i386cpuid.cpu_model = CPU_AMD_K6_III_MODEL; + i386cpuid.cpu_stepping = CPU_AMD_K6_III_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_AMD_K6_III; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_AMD_K6_III; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_AMD_K6_III; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_AMD_K6_III; + i386cpuid.cpu_brandid = CPU_BRAND_ID_AMD_K6_III; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_AMD); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_AMD_K6_III); + set_device_name(_T("AMD-K6 3D+ CPU")); + break; + case AMD_K7_ATHLON: + i386cpuid.cpu_family = CPU_AMD_K7_ATHLON_FAMILY; + i386cpuid.cpu_model = CPU_AMD_K7_ATHLON_MODEL; + i386cpuid.cpu_stepping = CPU_AMD_K7_ATHLON_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_AMD_K7_ATHLON; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_AMD_K7_ATHLON; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_AMD_K7_ATHLON; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_AMD_K7_ATHLON; + i386cpuid.cpu_brandid = CPU_BRAND_ID_AMD_K7_ATHLON; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_AMD); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_AMD_K7_ATHLON); + set_device_name(_T("AMD-K7 CPU")); + break; + case AMD_K7_ATHLON_XP: + i386cpuid.cpu_family = CPU_AMD_K7_ATHLON_XP_FAMILY; + i386cpuid.cpu_model = CPU_AMD_K7_ATHLON_XP_MODEL; + i386cpuid.cpu_stepping = CPU_AMD_K7_ATHLON_XP_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_AMD_K7_ATHLON_XP; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_AMD_K7_ATHLON_XP; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_AMD_K7_ATHLON_XP; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK_AMD_K7_ATHLON_XP; + i386cpuid.cpu_brandid = CPU_BRAND_ID_AMD_K7_ATHLON_XP; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_AMD); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_AMD_K7_ATHLON_XP); + set_device_name(_T("AMD Athlon XP CPU")); + break; + default: + i386cpuid.cpu_family = CPU_FAMILY; + i386cpuid.cpu_model = CPU_MODEL; + i386cpuid.cpu_stepping = CPU_STEPPING; + i386cpuid.cpu_feature = CPU_FEATURES_ALL; + i386cpuid.cpu_feature_ex = CPU_FEATURES_EX_ALL; + i386cpuid.cpu_feature_ecx = CPU_FEATURES_ECX_ALL; + i386cpuid.cpu_eflags_mask = CPU_EFLAGS_MASK; + i386cpuid.cpu_brandid = CPU_BRAND_ID_NEKOPRO2; + strcpy(i386cpuid.cpu_vendor, CPU_VENDOR_NEKOPRO); + strcpy(i386cpuid.cpu_brandstring, CPU_BRAND_STRING_NEKOPRO2); + set_device_name(_T("Neko Processor II CPU")); + break; + } + osd->set_vm_node(this_device_id, (char *)this_device_name); + + i386cpuid.fpu_type = FPU_TYPE_SOFTFLOAT; +// i386cpuid.fpu_type = FPU_TYPE_DOSBOX; +// i386cpuid.fpu_type = FPU_TYPE_DOSBOX2; + fpu_initialize(); + + UINT32 PREV_CPU_ADRSMASK = CPU_ADRSMASK; + + CPU_RESET(); +// CPU_ADRSMASK = address_mask; + CPU_TYPE = 0; + CS_BASE = PREV_CS_BASE = 0xf0000; + CPU_CS = 0xf000; + CPU_IP = 0xfff0; + CPU_ADRSMASK = PREV_CPU_ADRSMASK; + CPU_CLEARPREFETCH(); + + remained_cycles = extra_cycles = 0; + i386_memory_wait = 0; + waitcount = 0; + write_signals(&outputs_extreset, 0xffffffff); +} + +void I386::cpu_wait(int clocks) +{ + if(clocks <= 0) clocks = 1; + int64_t wfactor = waitfactor; + int64_t wcount = waitcount; + int64_t mwait = i386_memory_wait; + int64_t ncount; + if(wfactor > 65536) { + wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock. + } + wcount += (wfactor * mwait); // memory wait + if(wcount >= 65536) { + ncount = wcount >> 16; + wcount = wcount - (ncount << 16); + extra_cycles += (int)ncount; + } else if(wcount < 0) { + wcount = 0; + } + waitcount = wcount; + i386_memory_wait = 0; +} + +bool I386::check_interrupts() +{ + if(nmi_pending) { + return true; + } else if(irq_pending && CPU_isEI) { + return true; + } + return false; +} + +int I386::run_one_opecode() +{ +//#ifdef USE_DEBUGGER + + bool now_debugging = false; + if((_USE_DEBUGGER) && (device_debugger != NULL)) { + now_debugging = device_debugger->now_debugging; + } + if((now_debugging)) { + device_debugger->check_break_points(get_next_pc()); + if(device_debugger->now_suspended) { + device_debugger->now_waiting = true; + emu->start_waiting_in_debugger(); + while(device_debugger->now_debugging && device_debugger->now_suspended) { + emu->process_waiting_in_debugger(); + } + emu->finish_waiting_in_debugger(); + device_debugger->now_waiting = false; + } + if(device_debugger->now_debugging) { + device_mem = device_io = device_debugger; + } else { + now_debugging = false; + } + + PREV_CS_BASE = CS_BASE; + CPU_REMCLOCK = CPU_BASECLOCK = 1; + CPU_EXEC(); + if(nmi_pending) { + CPU_INTERRUPT(2, 0); + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(get_pc(), 2); + } + nmi_pending = false; + } else if(irq_pending && CPU_isEI) { + uint32_t intr_level = device_pic->get_intr_ack(); + CPU_INTERRUPT(intr_level, 0); + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(get_pc(), intr_level); + } + irq_pending = false; + device_pic->update_intr(); + } + check_interrupts(); + if(now_debugging) { + if(!device_debugger->now_going) { + device_debugger->now_suspended = true; + } + device_mem = device_mem_stored; + device_io = device_io_stored; + } + return CPU_BASECLOCK - CPU_REMCLOCK; + } else { +//#endif + PREV_CS_BASE = CS_BASE; + CPU_REMCLOCK = CPU_BASECLOCK = 1; + CPU_EXEC(); + if(nmi_pending) { + CPU_INTERRUPT(2, 0); + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(get_pc(), 2); + } + nmi_pending = false; + } else if(irq_pending && CPU_isEI) { + // ToDo: Multiple interrupt within rep prefix. + uint32_t intr_level = device_pic->get_intr_ack(); + CPU_INTERRUPT(intr_level, 0); + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(get_pc(), intr_level); + } + irq_pending = false; + device_pic->update_intr(); + } + return CPU_BASECLOCK - CPU_REMCLOCK; +//#ifdef USE_DEBUGGER + } +//#endif +} + +int I386::run(int cycles) +{ + if(cycles == -1) { + int passed_cycles; + if(busreq) { + // don't run cpu! +//#ifdef SINGLE_MODE_DMA + if(_SINGLE_MODE_DMA) { + if(device_dma != NULL) device_dma->do_dma(); + } +//#endif + passed_cycles = max(5, extra_cycles); // 80386 CPI: 4.9 + extra_cycles = 0; + } else { + // run only one opcode + passed_cycles = extra_cycles; + extra_cycles = 0; + passed_cycles += run_one_opecode(); + } +//#ifdef USE_DEBUGGER + if(_USE_DEBUGGER) { + total_cycles += passed_cycles; + } +//#endif + cpu_wait(passed_cycles); + return passed_cycles; + } else { + remained_cycles += cycles + extra_cycles; + extra_cycles = 0; + int first_cycles = remained_cycles; + + // run cpu while given clocks + while(remained_cycles > 0 && !busreq) { + remained_cycles -= run_one_opecode(); +// remained_cycles -= run(-1); + } + // if busreq is raised, spin cpu while remained clock + if(remained_cycles > 0 && busreq) { +//#ifdef USE_DEBUGGER + if(_USE_DEBUGGER) { + total_cycles += remained_cycles; + } +//#endif + remained_cycles = 0; + } + int passed_cycles = first_cycles - remained_cycles; + cpu_wait(passed_cycles); + return passed_cycles; + } +} + +void I386::write_signal(int id, uint32_t data, uint32_t mask) +{ + if(id == SIG_CPU_NMI) { + nmi_pending = ((data & mask) != 0); + } else if(id == SIG_CPU_IRQ) { + irq_pending = ((data & mask) != 0); + } else if(id == SIG_CPU_BUSREQ) { + busreq = ((data & mask) != 0); + } else if(id == SIG_I386_A20) { + CPU_ADRSMASK = (data & mask) ? ~0 : ~(1 << 20); + //CPU_ADRSMASK = data & mask; + ia32a20enable((data & mask) != 0); + } else if(id == SIG_I386_NOTIFY_RESET) { + write_signals(&outputs_extreset, (((data & mask) == 0) ? 0x00000000 : 0xffffffff)); + } else if(id == SIG_CPU_WAIT_FACTOR) { + waitfactor = data; // 65536. + waitcount = 0; // 65536. + } +} + +void I386::set_intr_line(bool line, bool pending, uint32_t bit) +{ + irq_pending = line; +} + +void I386::set_extra_clock(int cycles) +{ + extra_cycles += cycles; +} + +int I386::get_extra_clock() +{ + return extra_cycles; +} + +// from convert_address() in np21/i386c/ia32/disasm.cpp + +uint32_t I386::convert_address(uint32_t cs_base, uint32_t eip) +{ + if(CPU_STAT_PM) { + uint32_t addr = cs_base + eip; + + if(CPU_STAT_PAGING) { + uint32_t pde_addr = CPU_STAT_PDE_BASE + ((addr >> 20) & 0xffc); + uint32_t pde = device_mem->read_data32(pde_addr); + /* XXX: check */ + uint32_t pte_addr = (pde & CPU_PDE_BASEADDR_MASK) + ((addr >> 10) & 0xffc); + uint32_t pte = device_mem->read_data32(pte_addr); + /* XXX: check */ + addr = (pte & CPU_PTE_BASEADDR_MASK) + (addr & CPU_PAGE_MASK); + } + return addr; + } + return cs_base + (eip & 0xffff); +} + +uint32_t I386::get_pc() +{ + return convert_address(PREV_CS_BASE, CPU_PREV_EIP); +} + +uint32_t I386::get_next_pc() +{ + return convert_address(CS_BASE, CPU_EIP); +} + +//#ifdef USE_DEBUGGER +void I386::write_debug_data8(uint32_t addr, uint32_t data) +{ + int wait; + device_mem->write_data8w(addr, data, &wait); +} + +uint32_t I386::read_debug_data8(uint32_t addr) +{ + int wait; + return device_mem->read_data8w(addr, &wait); +} + +void I386::write_debug_data16(uint32_t addr, uint32_t data) +{ + int wait; + device_mem->write_data16w(addr, data, &wait); +} + +uint32_t I386::read_debug_data16(uint32_t addr) +{ + int wait; + return device_mem->read_data16w(addr, &wait); +} + +void I386::write_debug_data32(uint32_t addr, uint32_t data) +{ + int wait; + device_mem->write_data32w(addr, data, &wait); +} + +uint32_t I386::read_debug_data32(uint32_t addr) +{ + int wait; + return device_mem->read_data32w(addr, &wait); +} + +void I386::write_debug_io8(uint32_t addr, uint32_t data) +{ + int wait; + device_io->write_io8w(addr, data, &wait); +} + +uint32_t I386::read_debug_io8(uint32_t addr) +{ + int wait; + return device_io->read_io8w(addr, &wait); +} + +void I386::write_debug_io16(uint32_t addr, uint32_t data) +{ + int wait; + device_io->write_io16w(addr, data, &wait); +} + +uint32_t I386::read_debug_io16(uint32_t addr) +{ + int wait; + return device_io->read_io16w(addr, &wait); +} + +void I386::write_debug_io32(uint32_t addr, uint32_t data) +{ + int wait; + device_io->write_io32w(addr, data, &wait); +} + +uint32_t I386::read_debug_io32(uint32_t addr) +{ + int wait; + return device_io->read_io32w(addr, &wait); +} + +bool I386::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + if(_tcsicmp(reg, _T("EIP")) == 0) { + CPU_EIP = data; + } else if(_tcsicmp(reg, _T("EAX")) == 0) { + CPU_EAX = data; + } else if(_tcsicmp(reg, _T("EBX")) == 0) { + CPU_EBX = data; + } else if(_tcsicmp(reg, _T("ECX")) == 0) { + CPU_ECX = data; + } else if(_tcsicmp(reg, _T("EDX")) == 0) { + CPU_EDX = data; + } else if(_tcsicmp(reg, _T("ESP")) == 0) { + CPU_ESP = data; + } else if(_tcsicmp(reg, _T("EBP")) == 0) { + CPU_EBP = data; + } else if(_tcsicmp(reg, _T("ESI")) == 0) { + CPU_ESI = data; + } else if(_tcsicmp(reg, _T("EDI")) == 0) { + CPU_EDI = data; + } else if(_tcsicmp(reg, _T("IP")) == 0) { + CPU_IP = data; + } else if(_tcsicmp(reg, _T("AX")) == 0) { + CPU_AX = data; + } else if(_tcsicmp(reg, _T("BX")) == 0) { + CPU_BX = data; + } else if(_tcsicmp(reg, _T("CX")) == 0) { + CPU_CX = data; + } else if(_tcsicmp(reg, _T("DX")) == 0) { + CPU_DX = data; + } else if(_tcsicmp(reg, _T("SP")) == 0) { + CPU_SP = data; + } else if(_tcsicmp(reg, _T("BP")) == 0) { + CPU_BP = data; + } else if(_tcsicmp(reg, _T("SI")) == 0) { + CPU_SI = data; + } else if(_tcsicmp(reg, _T("DI")) == 0) { + CPU_DI = data; + } else if(_tcsicmp(reg, _T("AL")) == 0) { + CPU_AL = data; + } else if(_tcsicmp(reg, _T("AH")) == 0) { + CPU_AH = data; + } else if(_tcsicmp(reg, _T("BL")) == 0) { + CPU_BL = data; + } else if(_tcsicmp(reg, _T("BH")) == 0) { + CPU_BH = data; + } else if(_tcsicmp(reg, _T("CL")) == 0) { + CPU_CL = data; + } else if(_tcsicmp(reg, _T("CH")) == 0) { + CPU_CH = data; + } else if(_tcsicmp(reg, _T("DL")) == 0) { + CPU_DL = data; + } else if(_tcsicmp(reg, _T("DH")) == 0) { + CPU_DH = data; + } else { + return false; + } + return true; +} + +uint32_t I386::read_debug_reg(const _TCHAR *reg) +{ + if(_tcsicmp(reg, _T("EIP")) == 0) { + return CPU_EIP; + } else if(_tcsicmp(reg, _T("EAX")) == 0) { + return CPU_EAX; + } else if(_tcsicmp(reg, _T("EBX")) == 0) { + return CPU_EBX; + } else if(_tcsicmp(reg, _T("ECX")) == 0) { + return CPU_ECX; + } else if(_tcsicmp(reg, _T("EDX")) == 0) { + return CPU_EDX; + } else if(_tcsicmp(reg, _T("ESP")) == 0) { + return CPU_ESP; + } else if(_tcsicmp(reg, _T("EBP")) == 0) { + return CPU_EBP; + } else if(_tcsicmp(reg, _T("ESI")) == 0) { + return CPU_ESI; + } else if(_tcsicmp(reg, _T("EDI")) == 0) { + return CPU_EDI; + } else if(_tcsicmp(reg, _T("IP")) == 0) { + return CPU_IP; + } else if(_tcsicmp(reg, _T("AX")) == 0) { + return CPU_AX; + } else if(_tcsicmp(reg, _T("BX")) == 0) { + return CPU_BX; + } else if(_tcsicmp(reg, _T("CX")) == 0) { + return CPU_CX; + } else if(_tcsicmp(reg, _T("DX")) == 0) { + return CPU_DX; + } else if(_tcsicmp(reg, _T("SP")) == 0) { + return CPU_SP; + } else if(_tcsicmp(reg, _T("BP")) == 0) { + return CPU_BP; + } else if(_tcsicmp(reg, _T("SI")) == 0) { + return CPU_SI; + } else if(_tcsicmp(reg, _T("DI")) == 0) { + return CPU_DI; + } else if(_tcsicmp(reg, _T("AL")) == 0) { + return CPU_AL; + } else if(_tcsicmp(reg, _T("AH")) == 0) { + return CPU_AH; + } else if(_tcsicmp(reg, _T("BL")) == 0) { + return CPU_BL; + } else if(_tcsicmp(reg, _T("BH")) == 0) { + return CPU_BH; + } else if(_tcsicmp(reg, _T("CL")) == 0) { + return CPU_CL; + } else if(_tcsicmp(reg, _T("CH")) == 0) { + return CPU_CH; + } else if(_tcsicmp(reg, _T("DL")) == 0) { + return CPU_DL; + } else if(_tcsicmp(reg, _T("DH")) == 0) { + return CPU_DH; + } else if(_tcsicmp(reg, _T("ES")) == 0) { + return CPU_REGS_SREG(CPU_ES_INDEX); + } else if(_tcsicmp(reg, _T("CS")) == 0) { + return CPU_REGS_SREG(CPU_CS_INDEX); + } else if(_tcsicmp(reg, _T("SS")) == 0) { + return CPU_REGS_SREG(CPU_SS_INDEX); + } else if(_tcsicmp(reg, _T("DS")) == 0) { + return CPU_REGS_SREG(CPU_DS_INDEX); + } else if(_tcsicmp(reg, _T("FS")) == 0) { + return CPU_REGS_SREG(CPU_FS_INDEX); + } else if(_tcsicmp(reg, _T("GS")) == 0) { + return CPU_REGS_SREG(CPU_GS_INDEX); + } else if(_tcsicmp(reg, _T("ES.LIMIT")) == 0) { + return CPU_STAT_SREGLIMIT(CPU_ES_INDEX); + } else if(_tcsicmp(reg, _T("CS.LIMIT")) == 0) { + return CPU_STAT_SREGLIMIT(CPU_CS_INDEX); + } else if(_tcsicmp(reg, _T("SS.LIMIT")) == 0) { + return CPU_STAT_SREGLIMIT(CPU_SS_INDEX); + } else if(_tcsicmp(reg, _T("DS.LIMIT")) == 0) { + return CPU_STAT_SREGLIMIT(CPU_DS_INDEX); + } else if(_tcsicmp(reg, _T("FS.LIMIT")) == 0) { + return CPU_STAT_SREGLIMIT(CPU_FS_INDEX); + } else if(_tcsicmp(reg, _T("GS.LIMIT")) == 0) { + return CPU_STAT_SREGLIMIT(CPU_GS_INDEX); + } else if(_tcsicmp(reg, _T("ES.BASE")) == 0) { + return CPU_STAT_SREGBASE(CPU_ES_INDEX); + } else if(_tcsicmp(reg, _T("CS.BASE")) == 0) { + return CPU_STAT_SREGBASE(CPU_CS_INDEX); + } else if(_tcsicmp(reg, _T("SS.BASE")) == 0) { + return CPU_STAT_SREGBASE(CPU_SS_INDEX); + } else if(_tcsicmp(reg, _T("DS.BASE")) == 0) { + return CPU_STAT_SREGBASE(CPU_DS_INDEX); + } else if(_tcsicmp(reg, _T("FS.BASE")) == 0) { + return CPU_STAT_SREGBASE(CPU_FS_INDEX); + } else if(_tcsicmp(reg, _T("GS.BASE")) == 0) { + return CPU_STAT_SREGBASE(CPU_GS_INDEX); + } + return 0; +} + +bool I386::get_debug_regs_description(_TCHAR *buffer, size_t buffer_len) +{ + my_stprintf_s(buffer, buffer_len, + _T("(E)IP : Instruction pointer\n") + _T("(E)FLAGS : FLAGs\n") + _T("CS : Code SEGMENT\n") + _T("SS : Stack SEGMENT\n") + _T("DS ES FS GS : Data SEGMENT\n") + _T("(E)SP : Stack pointer\n") + _T("(E)BP : Base pointer (sometimes using local stack pointer)\n") + _T("(E)SI : SOURCE INDEX\n") + _T("(E)DI : DESTINATION INDEX\n") + _T("EAX EBX ECX EDX : 32bit ACCUMERATORS\n") + _T("AX BX CX DX : 16bit ACCUMERATORS\n") + _T("AH AL BH BL CH CL DH DL : 8bit ACCUMERATORS\n") + _T("*** ExX is same as xX, split into xH and xL\n") + _T("LDTR : LOCAL SEGMENT ADDRESS TABLE\n") + _T("GDTR : GLOBAL SEGMENT ADDRESS TABLE\n") + _T("IDTR : INTERRUPT SEGMENT ADDRESS TABLE\n") + _T("TRx : TEST REGISTERs\n") + _T("DRx : DEBUG REGISTERs\n") + _T("CR0-CR4 : SYSTEM REGISTERs\n") + _T("MXCSR : \n") + _T("\n") + ); + return true; +} +bool I386::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + const _TCHAR sregname[][8] = + { _T("ES"), _T("CS"), + _T("SS"), _T("DS"), + _T("FS"), _T("GS")} + ; + _TCHAR sregstr[512] = {0}; + _TCHAR dbgregstr[512] = {0}; + _TCHAR testregstr[512] = {0}; + for(int i = 0; i < 6; i++) { + _TCHAR segdesc[128] = {0}; + my_stprintf_s(segdesc, 127, _T("%s: %04X BASE=%08X LIMIT=%08X"), + sregname[i], + CPU_REGS_SREG(i), + (CPU_STAT_PM) ? CPU_STAT_SREGBASE(i) : (CPU_STAT_SREGBASE(i) & 0xfffff), + (CPU_STAT_PM) ? CPU_STAT_SREGLIMIT(i) : (CPU_STAT_SREGLIMIT(i) & 0xffff) + ); + my_tcscat_s(sregstr, 511, segdesc); + if((i & 1) == 0) { + my_tcscat_s(sregstr, 511, _T(" / ")); + } else { + my_tcscat_s(sregstr, 511, _T("\n")); + } + } + my_stprintf_s(dbgregstr, 511, _T("DEBUG REG:")); + for(int i = 0; i < CPU_DEBUG_REG_NUM; i++) { + _TCHAR ddesc[128] = {0}; + my_stprintf_s(ddesc, 31, _T(" %08X"), CPU_DR(i)); + my_tcscat_s(dbgregstr, 511, ddesc); + } + my_stprintf_s(testregstr, 511, _T("TEST REG:")); + for(int i = 0; i < CPU_TEST_REG_NUM; i++) { + _TCHAR tdesc[32] = {0}; + my_stprintf_s(tdesc, 31, _T(" %08X"), CPU_STATSAVE.cpu_regs.tr[i]); + my_tcscat_s(testregstr, 511, tdesc); + } + + if(CPU_STAT_PM) { + my_stprintf_s(buffer, buffer_len, + _T("PM %s %s %s %s MODE=%01X CPL=%02X\n") + _T("EFLAGS=%08X FLAG=[%s%s%s%s][%c%c%c%c%c%c%c%c%c]\n") + _T("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\n") + _T("ESP=%08X EBP=%08X ESI=%08X EDI=%08X\n") + _T("%s") + _T("PC=%08X ") + _T("EIP=%08X PREV_EIP=%08X PREV_ESP=%08X\n") + _T("CRx=%08X %08X %08X %08X %08X MXCSR=%08X\n") + _T("GDTR: BASE=%08X LIMIT=%08X / LDTR: BASE=%08X LIMIT=%08X\n") + _T("IDTR: BASE=%08X LIMIT=%08X / TR: BASE=%08X LIMIT=%08X\n") + _T("%s\n%s\n") + _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), + (CPU_STAT_VM86) ? _T("VM86") : _T(" "), + (CPU_STAT_PAGING) ? _T("PAGE") : _T(" "), + (CPU_STAT_SS32) ? _T("SS32") : _T(" "), + (CPU_STAT_WP) ? _T("WP") : _T(" "), + CPU_STAT_USER_MODE, CPU_STAT_CPL, + CPU_EFLAG, + (CPU_EFLAG & RF_FLAG) ? _T("RF ") : _T(" "), + (CPU_EFLAG & VM_FLAG) ? _T("VM ") : _T(" "), + (CPU_EFLAG & VIF_FLAG) ? _T("VIF ") : _T(" "), + (CPU_EFLAG & VIP_FLAG) ? _T("VIP ") : _T(" "), + (CPU_FLAG & O_FLAG) ? _T('O') : _T('-'), + (CPU_FLAG & D_FLAG) ? _T('D') : _T('-'), + (CPU_FLAG & I_FLAG) ? _T('I') : _T('-'), + (CPU_FLAG & T_FLAG) ? _T('T') : _T('-'), + (CPU_FLAG & S_FLAG) ? _T('S') : _T('-'), + (CPU_FLAG & Z_FLAG) ? _T('Z') : _T('-'), + (CPU_FLAG & A_FLAG) ? _T('A') : _T('-'), + (CPU_FLAG & P_FLAG) ? _T('P') : _T('-'), + (CPU_FLAG & C_FLAG) ? _T('C') : _T('-'), + + CPU_EAX, CPU_EBX, CPU_ECX, CPU_EDX, CPU_ESP, CPU_EBP, CPU_ESI, CPU_EDI, + sregstr, + ((CPU_STAT_SREGBASE(CPU_CS_INDEX) + CPU_EIP) & 0xffffffff), + CPU_EIP, CPU_PREV_EIP, CPU_PREV_ESP, + CPU_CR0, CPU_CR1, CPU_CR2, CPU_CR3, CPU_CR4, CPU_MXCSR, + CPU_GDTR_BASE, CPU_GDTR_LIMIT, CPU_LDTR_BASE, CPU_LDTR_LIMIT, + CPU_IDTR_BASE, CPU_IDTR_LIMIT, CPU_TR_BASE, CPU_TR_LIMIT, + dbgregstr, testregstr, + total_cycles, total_cycles - prev_total_cycles, + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + } else { + my_stprintf_s(buffer, buffer_len, + _T("-- %s %s %s %s MODE=%01X CPL=%02X\n") + _T("EFLAGS=%08X FLAG=[%s%s%s%s][%c%c%c%c%c%c%c%c%c]\n") + _T("EAX=%08X EBX=%08X ECX=%08X EDX=%08X \nESP=%08X EBP=%08X ESI=%08X EDI=%08X\n") + _T("%s") + _T("PC=%08X ") + _T("IP=%04X PREV_IP=%04X PREV_SP=%04X\n") + _T("CRx=%08X %08X %08X %08X %08X MXCSR=%08X\n") + _T("%s\n%s\n") + _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), + (CPU_STAT_VM86) ? _T("VM86 ") : _T(" "), + (CPU_STAT_PAGING) ? _T("PAGE ") : _T(" "), + (CPU_STAT_SS32) ? _T("SS32 ") : _T(" "), + (CPU_STAT_WP) ? _T("WP ") : _T(" "), + CPU_STAT_USER_MODE, CPU_STAT_CPL, + CPU_EFLAG, + (CPU_EFLAG & RF_FLAG) ? _T("RF ") : _T(" "), (CPU_EFLAG & VM_FLAG) ? _T("VM ") : _T(" "), (CPU_EFLAG & VIF_FLAG) ? _T("VIF ") : _T(" "), (CPU_EFLAG & VIP_FLAG) ? _T("VIP ") : _T(" "), + (CPU_FLAG & O_FLAG) ? _T('O') : _T('-'), (CPU_FLAG & D_FLAG) ? _T('D') : _T('-'), (CPU_FLAG & I_FLAG) ? _T('I') : _T('-'), (CPU_FLAG & T_FLAG) ? _T('T') : _T('-'), (CPU_FLAG & S_FLAG) ? _T('S') : _T('-'), + (CPU_FLAG & Z_FLAG) ? _T('Z') : _T('-'), (CPU_FLAG & A_FLAG) ? _T('A') : _T('-'), (CPU_FLAG & P_FLAG) ? _T('P') : _T('-'), (CPU_FLAG & C_FLAG) ? _T('C') : _T('-'), + CPU_EAX, CPU_EBX, CPU_ECX, CPU_EDX, CPU_ESP, CPU_EBP, CPU_ESI, CPU_EDI, + sregstr, + (((CPU_STAT_SREGBASE(CPU_CS_INDEX) & 0xfffff ) + CPU_IP) & 0x000fffff), + CPU_IP, CPU_STATSAVE.cpu_regs.prev_eip.w.w, CPU_STATSAVE.cpu_regs.prev_esp.w.w, + CPU_CR0, CPU_CR1, CPU_CR2, CPU_CR3, CPU_CR4, CPU_MXCSR, + dbgregstr, testregstr, + total_cycles, total_cycles - prev_total_cycles, + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + } + prev_total_cycles = total_cycles; + return true; +} + +bool I386::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata) +{ + size = 0; + _TCHAR prefix[128] = {0}; + if((userdata & ((uint64_t)0xffffffff << 32)) == ((uint64_t)0x80000000 << 32)) { + my_stprintf_s(prefix, 127, _T("*RETURN*")); + } else if((userdata & (uint64_t)0xffffffff00000000) != 0) { + my_stprintf_s(prefix, 127, _T("*IRQ %X HAPPENED*"), (uint32_t)(userdata >> 32)); + } else { + my_stprintf_s(prefix, 127, _T("*CALL TO %08X*"), (uint32_t)userdata); + } + _TCHAR dasmbuf[1024] = {0}; + size = debug_dasm_with_userdata(pc, dasmbuf, 1023, userdata); + if(size <= 0) { + my_tcscpy_s(dasmbuf, 1023, _T("**UNDEFINED BEHAVIOR**")); + } + my_stprintf_s(buffer, buffer_len, _T("HIT %s @%08X %s\n"), + prefix, pc, dasmbuf); + return true; +} +int I386::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) +{ + uint32_t eip = pc - (CPU_CS << 4); + uint8_t oprom[16]; + + for(int i = 0; i < 16; i++) { + int wait; + oprom[i] = device_mem->read_data8w((pc + i) & CPU_ADRSMASK, &wait); + } + bool __op32 = (userdata & I386_TRACE_DATA_BIT_USERDATA_SET) ? ((userdata & I386_TRACE_DATA_BIT_OP32) ? true : false) : ((CPU_INST_OP32 != 0) ? true : false); + return i386_dasm(oprom, eip, __op32, buffer, buffer_len); +} + +//#endif + +void I386::set_address_mask(uint32_t mask) +{ + CPU_ADRSMASK = mask; + address_mask = mask; +} + +uint32_t I386::get_address_mask() +{ + return CPU_ADRSMASK; +} + +void I386::set_shutdown_flag(int shutdown) +{ + // FIXME: shutdown just now + if(shutdown) CPU_SHUT(); +} + +int I386::get_shutdown_flag() +{ + // FIXME: shutdown already done + return 0; +} + +void I386::set_context_mem(DEVICE* device) +{ + device_mem = device; +} + +void I386::set_context_io(DEVICE* device) +{ + device_io = device; +} + +//#ifdef I86_PSEUDO_BIOS +void I386::set_context_bios(DEVICE* device) +{ + device_bios = device; +} +//#endif + +//#ifdef SINGLE_MODE_DMA +void I386::set_context_dma(DEVICE* device) +{ + device_dma = device; +} +//#endif +void I386::set_context_intr(DEVICE* device, uint32_t bit) +{ + device_pic = device; +} + +void I386::set_context_debugger(DEBUGGER* deb) +{ + device_debugger = deb; +} + +void *I386::get_debugger() +{ + return device_debugger; +} + +#define STATE_VERSION 2 + +bool I386::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + // FIXME + state_fio->StateBuffer(&CPU_STATSAVE, sizeof(CPU_STATSAVE), 1); + state_fio->StateBuffer(&i386cpuid, sizeof(i386cpuid), 1); + state_fio->StateBuffer(&i386msr, sizeof(i386msr), 1); +//#ifdef USE_DEBUGGER + if(_USE_DEBUGGER) { + state_fio->StateValue(total_cycles); + state_fio->StateValue(prev_total_cycles); + } +//#endif + state_fio->StateValue(remained_cycles); + state_fio->StateValue(extra_cycles); + state_fio->StateValue(busreq); + state_fio->StateValue(nmi_pending); + state_fio->StateValue(irq_pending); + state_fio->StateValue(PREV_CS_BASE); + + state_fio->StateValue(waitfactor); + state_fio->StateValue(waitcount); + state_fio->StateValue(i386_memory_wait); + state_fio->StateValue(address_mask); + + return true; +} + diff --git a/source/src/vm/i386_np21.h b/source/src/vm/i386_np21.h new file mode 100644 index 000000000..9b6dc100e --- /dev/null +++ b/source/src/vm/i386_np21.h @@ -0,0 +1,190 @@ +/* + Skelton for retropc emulator + + Origin : np21/w i386c core + Author : Takeda.Toshiya + Date : 2020.01.25- + + [ i386/i486/Pentium ] +*/ + +#ifndef _I386_NP21_H_ +#define _I386_NP21_H_ + +#include "vm_template.h" +//#include "../emu.h" +#include "device.h" + +#define SIG_I386_A20 1 +#define SIG_I386_NOTIFY_RESET 2 + +#define I386_TRACE_DATA_BIT_USERDATA_SET 0x80000000 +#define I386_TRACE_DATA_BIT_OP32 0x00000001 +#define I386_TRACE_DATA_BIT_RET 0x00000040 +#define I386_TRACE_DATA_BIT_RETF 0x00000050 +#define I386_TRACE_DATA_BIT_IRET 0x00000060 +#define I386_TRACE_DATA_BIT_JMP 0x00000080 +#define I386_TRACE_DATA_BIT_JMP_COND 0x00000090 +#define I386_TRACE_DATA_BIT_CALL 0x00000100 +#define I386_TRACE_DATA_BIT_INT 0x10000000 +#define I386_TRACE_DATA_BIT_IRQ 0x20000000 +#define I386_TRACE_DATA_BIT_EXCEPTION 0x40000000 + +enum { + DEFAULT = -1, + INTEL_80386 = 0, + INTEL_I486SX, + INTEL_I486DX, + INTEL_PENTIUM, + INTEL_MMX_PENTIUM, + INTEL_PENTIUM_PRO, + INTEL_PENTIUM_II, + INTEL_PENTIUM_III, + INTEL_PENTIUM_M, + INTEL_PENTIUM_4, + AMD_K6_2, + AMD_K6_III, + AMD_K7_ATHLON, + AMD_K7_ATHLON_XP, +}; + +//#ifdef USE_DEBUGGER +class DEBUGGER; +//#endif +class DLL_PREFIX I386 : public DEVICE +{ +private: + DEVICE *device_pic; + outputs_t outputs_extreset; + +//#ifdef USE_DEBUGGER +// DEBUGGER *device_debugger; + DEVICE *device_mem_stored; + DEVICE *device_io_stored; + uint64_t total_cycles; + uint64_t prev_total_cycles; +//#endif + int remained_cycles, extra_cycles; + bool busreq; + bool nmi_pending, irq_pending; + uint32_t PREV_CS_BASE; + uint32_t waitfactor; + int64_t waitcount; + + bool _USE_DEBUGGER; + bool _I86_PSEUDO_BIOS; + bool _SINGLE_MODE_DMA; + uint32_t address_mask; + + int run_one_opecode(); + uint32_t __FASTCALL convert_address(uint32_t cs, uint32_t eip); + void __FASTCALL cpu_wait(int clocks); + +public: + I386(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { +//#ifdef USE_DEBUGGER + total_cycles = prev_total_cycles = 0; +//#endif + busreq = false; + initialize_output_signals(&outputs_extreset); + _USE_DEBUGGER = false; + _I86_PSEUDO_BIOS = false; + _SINGLE_MODE_DMA = false; + address_mask = 0x000fffff; // OK? + device_model = DEFAULT; + } + ~I386() {} + + // common functions + void initialize(); + void release(); + void reset(); + int __FASTCALL run(int cycles); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); + void __FASTCALL set_extra_clock(int cycles); + int get_extra_clock(); + uint32_t get_pc(); + uint32_t get_next_pc(); +//#ifdef USE_DEBUGGER + bool is_cpu() + { + return true; + } + bool is_debugger_available() + { + return true; + } + void *get_debugger(); +// { +// return device_debugger; +// } + uint32_t get_debug_prog_addr_mask() + { + return 0xffffffff; + } + uint32_t get_debug_data_addr_mask() + { + return 0xffffffff; + } + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data16(uint32_t addr); + void __FASTCALL write_debug_data32(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data32(uint32_t addr); + void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io8(uint32_t addr); + void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io32(uint32_t addr); + void __FASTCALL write_debug_io32(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io16(uint32_t addr); + virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data); + uint32_t __FASTCALL read_debug_reg(const _TCHAR *reg); + virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len); + int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); + virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0); +//#endif + bool process_state(FILEIO* state_fio, bool loading); + + // unique function + void set_context_mem(DEVICE* device); +// { +// device_mem = device; +// } + void set_context_io(DEVICE* device); +// { +// device_io = device; +// } + void set_context_intr(DEVICE* device, uint32_t bit = 0xffffffff); +//#ifdef I386_PSEUDO_BIOS + void set_context_bios(DEVICE* device); +// { +// device_bios = device; +// } +//#endif +//#ifdef SINGLE_MODE_DMA + void set_context_dma(DEVICE* device); +// { +// device_dma = device; +// } +//#endif +//#ifdef USE_DEBUGGER + void set_context_debugger(DEBUGGER* device); +//#endif + void set_context_extreset(DEVICE *dev, int id, uint32_t mask) + { + register_output_signal(&outputs_extreset, dev, id, mask); + } + bool check_interrupts(); + + void set_address_mask(uint32_t mask); + uint32_t get_address_mask(); + void set_shutdown_flag(int shutdown); + int get_shutdown_flag(); + int device_model; +}; + +#endif diff --git a/source/src/vm/i8080.h b/source/src/vm/i8080.h index 622f209f5..22a6afe38 100644 --- a/source/src/vm/i8080.h +++ b/source/src/vm/i8080.h @@ -182,7 +182,7 @@ class I8080 : public I8080_BASE void check_interrupt(); //void OP(uint8_t code); public: - I8080(VM_TEMPLATE* parent_vm, EMU* parent_emu) : I8080_BASE(parent_vm, parent_emu) + I8080(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : I8080_BASE(parent_vm, parent_emu) { #ifdef HAS_I8085 set_device_name(_T("i8085 CPU")); diff --git a/source/src/vm/i8080_base.cpp b/source/src/vm/i8080_base.cpp index 26a25126c..812324aa1 100644 --- a/source/src/vm/i8080_base.cpp +++ b/source/src/vm/i8080_base.cpp @@ -213,6 +213,7 @@ const uint16_t I8080_BASE::DAA[2048] = { void I8080_BASE::initialize() { DEVICE::initialize(); + _HAS_I8085 = osd->check_feature("HAS_I8085"); } void I8080_BASE::reset() @@ -1352,7 +1353,7 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0x05: my_stprintf_s(buffer, buffer_len, _T("dcr b")); break; case 0x06: my_stprintf_s(buffer, buffer_len, _T("mvi b,$%02x"), ops[ptr++]); break; case 0x07: my_stprintf_s(buffer, buffer_len, _T("rlc")); break; - case 0x08: my_stprintf_s(buffer, buffer_len, _T("dsub (*)")); break; + case 0x08: my_stprintf_s(buffer, buffer_len, (_HAS_I8085) ? _T("dsub") : _T("nop")); break; case 0x09: my_stprintf_s(buffer, buffer_len, _T("dad b")); break; case 0x0a: my_stprintf_s(buffer, buffer_len, _T("ldax b")); break; case 0x0b: my_stprintf_s(buffer, buffer_len, _T("dcx b")); break; @@ -1360,7 +1361,7 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0x0d: my_stprintf_s(buffer, buffer_len, _T("dcr c")); break; case 0x0e: my_stprintf_s(buffer, buffer_len, _T("mvi c,$%02x"), ops[ptr++]); break; case 0x0f: my_stprintf_s(buffer, buffer_len, _T("rrc")); break; - case 0x10: my_stprintf_s(buffer, buffer_len, _T("asrh (*)")); break; + case 0x10: my_stprintf_s(buffer, buffer_len, (_HAS_I8085) ? _T("asrh") : _T("nop")); break; case 0x11: my_stprintf_s(buffer, buffer_len, _T("lxi d,%s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; case 0x12: my_stprintf_s(buffer, buffer_len, _T("stax d")); break; case 0x13: my_stprintf_s(buffer, buffer_len, _T("inx d")); break; @@ -1368,7 +1369,7 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0x15: my_stprintf_s(buffer, buffer_len, _T("dcr d")); break; case 0x16: my_stprintf_s(buffer, buffer_len, _T("mvi d,$%02x"), ops[ptr++]); break; case 0x17: my_stprintf_s(buffer, buffer_len, _T("ral")); break; - case 0x18: my_stprintf_s(buffer, buffer_len, _T("rlde (*)")); break; + case 0x18: my_stprintf_s(buffer, buffer_len, (_HAS_I8085) ? _T("rlde") : _T("nop")); case 0x19: my_stprintf_s(buffer, buffer_len, _T("dad d")); break; case 0x1a: my_stprintf_s(buffer, buffer_len, _T("ldax d")); break; case 0x1b: my_stprintf_s(buffer, buffer_len, _T("dcx d")); break; @@ -1384,7 +1385,12 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0x25: my_stprintf_s(buffer, buffer_len, _T("dcr h")); break; case 0x26: my_stprintf_s(buffer, buffer_len, _T("mvi h,$%02x"), ops[ptr++]); break; case 0x27: my_stprintf_s(buffer, buffer_len, _T("daa")); break; - case 0x28: my_stprintf_s(buffer, buffer_len, _T("ldeh $%02x (*)"), ops[ptr++]); break; + case 0x28: if(_HAS_I8085) { + my_stprintf_s(buffer, buffer_len, _T("ldeh $%02x"), ops[ptr++]); + } else { + my_stprintf_s(buffer, buffer_len, _T("nop")); + } + break; case 0x29: my_stprintf_s(buffer, buffer_len, _T("dad h")); break; case 0x2a: my_stprintf_s(buffer, buffer_len, _T("lhld %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; case 0x2b: my_stprintf_s(buffer, buffer_len, _T("dcx h")); break; @@ -1547,7 +1553,12 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0xc8: my_stprintf_s(buffer, buffer_len, _T("rz")); break; case 0xc9: my_stprintf_s(buffer, buffer_len, _T("ret")); break; case 0xca: my_stprintf_s(buffer, buffer_len, _T("jz %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; - case 0xcb: my_stprintf_s(buffer, buffer_len, _T("rstv 8 (*)")); break; + case 0xcb: if(_HAS_I8085) { + my_stprintf_s(buffer, buffer_len, _T("rstv 8 (*)")); + } else { + my_stprintf_s(buffer, buffer_len, _T("jmp %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; + } + break; case 0xcc: my_stprintf_s(buffer, buffer_len, _T("cz %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; case 0xcd: my_stprintf_s(buffer, buffer_len, _T("call %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; case 0xce: my_stprintf_s(buffer, buffer_len, _T("aci $%02x"), ops[ptr++]); break; @@ -1561,11 +1572,16 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0xd6: my_stprintf_s(buffer, buffer_len, _T("sui $%02x"), ops[ptr++]); break; case 0xd7: my_stprintf_s(buffer, buffer_len, _T("rst 2")); break; case 0xd8: my_stprintf_s(buffer, buffer_len, _T("rc")); break; - case 0xd9: my_stprintf_s(buffer, buffer_len, _T("shlx d (*)")); break; + case 0xd9: my_stprintf_s(buffer, buffer_len, (_HAS_I8085) ? _T("shlx d") : _T("nop")); break; case 0xda: my_stprintf_s(buffer, buffer_len, _T("jc %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; case 0xdb: my_stprintf_s(buffer, buffer_len, _T("in $%02x"), ops[ptr++]); break; case 0xdc: my_stprintf_s(buffer, buffer_len, _T("cc %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; - case 0xdd: my_stprintf_s(buffer, buffer_len, _T("jnx %s (*)"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; + case 0xdd: if(_HAS_I8085) { + my_stprintf_s(buffer, buffer_len, _T("jnx %s (*)"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; + } else { + my_stprintf_s(buffer, buffer_len, _T("call %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; + } + break; case 0xde: my_stprintf_s(buffer, buffer_len, _T("sbi $%02x"), ops[ptr++]); break; case 0xdf: my_stprintf_s(buffer, buffer_len, _T("rst 3")); break; case 0xe0: my_stprintf_s(buffer, buffer_len, _T("rpo")); break; @@ -1581,7 +1597,12 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0xea: my_stprintf_s(buffer, buffer_len, _T("jpe %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; case 0xeb: my_stprintf_s(buffer, buffer_len, _T("xchg")); break; case 0xec: my_stprintf_s(buffer, buffer_len, _T("cpe %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; - case 0xed: my_stprintf_s(buffer, buffer_len, _T("lhlx d (*)")); break; + case 0xed: if(_HAS_I8085) { + my_stprintf_s(buffer, buffer_len, _T("lhlx d"));; + } else { + my_stprintf_s(buffer, buffer_len, _T("call %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; + } + break; case 0xee: my_stprintf_s(buffer, buffer_len, _T("xri $%02x"), ops[ptr++]); break; case 0xef: my_stprintf_s(buffer, buffer_len, _T("rst 5")); break; case 0xf0: my_stprintf_s(buffer, buffer_len, _T("rp")); break; @@ -1597,7 +1618,12 @@ int I8080_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buf case 0xfa: my_stprintf_s(buffer, buffer_len, _T("jm %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; case 0xfb: my_stprintf_s(buffer, buffer_len, _T("ei")); break; case 0xfc: my_stprintf_s(buffer, buffer_len, _T("cm %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; - case 0xfd: my_stprintf_s(buffer, buffer_len, _T("jx %s (*)"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; break; + case 0xfd: if(_HAS_I8085) { + my_stprintf_s(buffer, buffer_len, _T("jx %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; + } else { + my_stprintf_s(buffer, buffer_len, _T("cm %s"), get_value_or_symbol(d_debugger->first_symbol, _T("$%04x"), ops[ptr] | (ops[ptr + 1] << 8))); ptr += 2; + } + break; case 0xfe: my_stprintf_s(buffer, buffer_len, _T("cpi $%02x"), ops[ptr++]); break; case 0xff: my_stprintf_s(buffer, buffer_len, _T("rst 7")); break; } diff --git a/source/src/vm/i8080_base.h b/source/src/vm/i8080_base.h index a9bbed227..ad2994272 100644 --- a/source/src/vm/i8080_base.h +++ b/source/src/vm/i8080_base.h @@ -28,9 +28,10 @@ class DEBUGGER; //#endif -class I8080_BASE : public DEVICE +class DLL_PREFIX I8080_BASE : public DEVICE { protected: + bool _HAS_I8085; /* --------------------------------------------------------------------------- contexts --------------------------------------------------------------------------- */ @@ -110,7 +111,7 @@ class I8080_BASE : public DEVICE uint64_t total_count; uint64_t prev_total_count; public: - I8080_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I8080_BASE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { BUSREQ = false; SID = true; @@ -128,7 +129,7 @@ class I8080_BASE : public DEVICE virtual __FASTCALL int run(int clock); virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); - void set_intr_line(bool line, bool pending, uint32_t bit); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); uint32_t get_pc() { return prevPC; @@ -175,7 +176,7 @@ class I8080_BASE : public DEVICE { d_io = device; } - void set_context_intr(DEVICE* device) + void set_context_intr(DEVICE* device, uint32_t bit = 0xfffffffff) { d_pic = device; } diff --git a/source/src/vm/i80x86_commondefs.h b/source/src/vm/i80x86_commondefs.h index 65ed8108d..145884c8b 100644 --- a/source/src/vm/i80x86_commondefs.h +++ b/source/src/vm/i80x86_commondefs.h @@ -45,21 +45,6 @@ #define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(cpu_state *cpustate, int icount) #define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate, icount) -#define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom) -#define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, eip, oprom) - -/*****************************************************************************/ -/* src/emu/didisasm.h */ - -// Disassembler constants -const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported? -const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence -const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards -const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over -const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value -const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length - /*****************************************************************************/ /* src/emu/diexec.h */ diff --git a/source/src/vm/i8155.h b/source/src/vm/i8155.h index 1b3bbd768..49f3d480f 100644 --- a/source/src/vm/i8155.h +++ b/source/src/vm/i8155.h @@ -19,9 +19,7 @@ #define SIG_I8155_PORT_C 2 #define SIG_I8155_CLOCK 3 -class VM; -class EMU; -class I8155 : public DEVICE +class DLL_PREFIX I8155 : public DEVICE { private: uint16_t count, countreg; @@ -58,7 +56,7 @@ class I8155 : public DEVICE void set_pio(int ch, uint8_t data); public: - I8155(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I8155(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 3; i++) { initialize_output_signals(&pio[i].outputs); @@ -78,7 +76,7 @@ class I8155 : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) { cpu_clocks = new_clocks; diff --git a/source/src/vm/i8237.cpp b/source/src/vm/i8237.cpp index 86d0e8f86..8a61909b5 100644 --- a/source/src/vm/i8237.cpp +++ b/source/src/vm/i8237.cpp @@ -9,7 +9,6 @@ */ #include "vm.h" -#include "../emu.h" #include "i8237.h" #ifdef USE_DEBUGGER #include "debugger.h" @@ -28,7 +27,7 @@ void I8237::initialize() } -I8237::I8237(VM_TEMPLATE* parent_vm, EMU* parent_emu) : I8237_BASE(parent_vm, parent_emu) +I8237::I8237(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : I8237_BASE(parent_vm, parent_emu) { for(int i = 0; i < 4; i++) { dma[i].dev = vm->dummy; diff --git a/source/src/vm/i8237.h b/source/src/vm/i8237.h index 58ab0c9ee..ab67873ba 100644 --- a/source/src/vm/i8237.h +++ b/source/src/vm/i8237.h @@ -29,7 +29,7 @@ #define SIG_I8237_MASK3 11 class DEBUGGER; -class I8237_BASE : public DEVICE +class DLL_PREFIX I8237_BASE : public DEVICE { protected: DEVICE* d_mem; @@ -65,7 +65,7 @@ class I8237_BASE : public DEVICE uint32_t __FASTCALL read_io(int ch); public: - I8237_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I8237_BASE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 4; i++) { //dma[i].dev = vm->dummy; @@ -160,7 +160,7 @@ class I8237 : public I8237_BASE { DEVICE* d_dma; #endif public: - I8237(VM_TEMPLATE* parent_vm, EMU* parent_emu); + I8237(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~I8237(); void initialize(); diff --git a/source/src/vm/i8251.h b/source/src/vm/i8251.h index 63f6e2c91..d784df201 100644 --- a/source/src/vm/i8251.h +++ b/source/src/vm/i8251.h @@ -21,9 +21,7 @@ #define SIG_I8251_LOOPBACK 4 class FIFO; -class VM; -class EMU; -class I8251 : public DEVICE +class DLL_PREFIX I8251 : public DEVICE { private: // i8251 @@ -45,7 +43,7 @@ class I8251 : public DEVICE int recv_id, send_id; public: - I8251(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I8251(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_out); initialize_output_signals(&outputs_rxrdy); @@ -65,7 +63,7 @@ class I8251 : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/i8253.cpp b/source/src/vm/i8253.cpp index 4a7795c4c..0830655bc 100644 --- a/source/src/vm/i8253.cpp +++ b/source/src/vm/i8253.cpp @@ -414,6 +414,30 @@ int I8253::get_next_count(int ch) return counter[ch].count; } +bool I8253::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + _TCHAR regs1[3][1024]; + for(int ch = 0; ch < 3; ch++) { + memset(regs1[ch], 0x00, sizeof(_TCHAR) * 1024); + my_sprintf_s(regs1[ch], 1024 -1, + _T("CH%d: FREQ=%d ") + _T("MODE=%d DELAY=%s START=%s ") + _T("CTRL=%02X COUNT_REG=%04X COUNT=%d ") + _T("GATE=%s PREV_IN=%s PREV_OUT=%s ") + _T("\n") + , + ch, counter[ch].freq, + counter[ch].mode, (counter[ch].delay) ? _T("YES") : _T("NO "), (counter[ch].start) ? _T("YES") : _T("NO "), + counter[ch].ctrl_reg, counter[ch].count_reg, counter[ch].count, + (counter[ch].gate) ? _T("YES") : _T("NO "), (counter[ch].prev_in) ? _T("YES") : _T("NO "), (counter[ch].prev_out) ? _T("YES") : _T("NO ")); + } + my_sprintf_s(buffer, buffer_len, _T("TYPE=%s\n%s%s%s"), + (__HAS_I8254) ? _T("i8254") : _T("i8253"), + regs1[0], regs1[1], regs1[2] + ); + return true; +} + #define STATE_VERSION 1 bool I8253::process_state(FILEIO* state_fio, bool loading) diff --git a/source/src/vm/i8253.h b/source/src/vm/i8253.h index cb5473438..8910e352c 100644 --- a/source/src/vm/i8253.h +++ b/source/src/vm/i8253.h @@ -21,7 +21,9 @@ #define SIG_I8253_GATE_1 4 #define SIG_I8253_GATE_2 5 -class I8253 : public DEVICE +class DEBUGGER; + +class DLL_PREFIX I8253 : public DEVICE { private: struct { @@ -52,6 +54,7 @@ class I8253 : public DEVICE // output signals outputs_t outputs; } counter[3]; + DEBUGGER* d_debugger; uint64_t cpu_clocks; bool __HAS_I8254; @@ -65,13 +68,14 @@ class I8253 : public DEVICE int __FASTCALL get_next_count(int ch); public: - I8253(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I8253(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 3; i++) { initialize_output_signals(&counter[i].outputs); counter[i].freq = 0; } __HAS_I8254 = false; + d_debugger = NULL; set_device_name(_T("8253 PIT")); } ~I8253() {} @@ -81,7 +85,7 @@ class I8253 : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) { @@ -89,6 +93,21 @@ class I8253 : public DEVICE } bool process_state(FILEIO* state_fio, bool loading); + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); +// bool write_debug_reg(const _TCHAR *reg, uint32_t data); + + bool is_debugger_available() + { + return (d_debugger != NULL) ? true : false; + } + void *get_debugger() + { + return d_debugger; + } + uint64_t get_debug_data_addr_space() + { + return 0x1; + } // unique functions void set_context_ch0(DEVICE* device, int id, uint32_t mask) { @@ -106,6 +125,10 @@ class I8253 : public DEVICE { counter[ch].freq = hz; } + void set_context_debugger(DEBUGGER* p) + { + d_debugger = p; + } }; #endif diff --git a/source/src/vm/i8255.h b/source/src/vm/i8255.h index 6a2b64431..5fb0b6c7e 100644 --- a/source/src/vm/i8255.h +++ b/source/src/vm/i8255.h @@ -18,7 +18,7 @@ #define SIG_I8255_PORT_B 1 #define SIG_I8255_PORT_C 2 -class I8255 : public DEVICE +class DLL_PREFIX I8255 : public DEVICE { private: struct { @@ -33,7 +33,7 @@ class I8255 : public DEVICE bool __I8255_AUTO_HAND_SHAKE; public: - I8255(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I8255(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 3; i++) { initialize_output_signals(&port[i].outputs); diff --git a/source/src/vm/i8259.cpp b/source/src/vm/i8259.cpp index 9a1a46a7e..13664eb3d 100644 --- a/source/src/vm/i8259.cpp +++ b/source/src/vm/i8259.cpp @@ -33,7 +33,28 @@ void I8259::initialize() void I8259::reset() { for(uint32_t c = 0; c < __I8259_MAX_CHIPS; c++) { + pic[c].imr = 0xff; + pic[c].isr = 0; + pic[c].irr = 0; pic[c].irr_tmp = 0; + pic[c].prio = 0; + + pic[c].icw1 = 0; + pic[c].icw2 = 0; + pic[c].icw3 = 0; + pic[c].icw4 = 0; + if(__I8259_PC98_HACK) { + pic[c].icw4 = 0x01; + } + pic[c].ocw3 = 2; + + pic[c].icw2_r = 0; + pic[c].icw3_r = 0; + pic[c].icw4_r = 0; + + if(pic[c].irr_tmp_id != -1) { + cancel_event(this, pic[c].irr_tmp_id); + } pic[c].irr_tmp_id = -1; } } @@ -47,7 +68,7 @@ void I8259::write_io8(uint32_t addr, uint32_t data) // icw2 pic[c].icw2 = data; pic[c].icw2_r = 0; - out_debug_log("Set ICW2 to %02X\n", data); +// out_debug_log("Set ICW2 to %02X\n", data); } else if(pic[c].icw3_r) { // icw3 pic[c].icw3 = data; @@ -228,6 +249,9 @@ uint32_t I8259::read_io8(uint32_t addr) void I8259::write_signal(int id, uint32_t data, uint32_t mask) { +// if((id & 0x0f) == 0x09) { +// out_debug_log(_T("CDC INTR %02X"), data & mask); +// } if(data & mask) { pic[id >> 3].irr |= 1 << (id & 7); update_intr(); diff --git a/source/src/vm/i8259.h b/source/src/vm/i8259.h index 0f13f53b6..0289b8655 100644 --- a/source/src/vm/i8259.h +++ b/source/src/vm/i8259.h @@ -43,7 +43,7 @@ struct i8259_pic_t { int irr_tmp_id; }; -class I8259 : public DEVICE +class DLL_PREFIX I8259 : public DEVICE { private: DEVICE* d_cpu; @@ -54,15 +54,17 @@ class I8259 : public DEVICE uint32_t __I8259_MAX_CHIPS; uint32_t __CHIP_MASK; bool __I8259_PC98_HACK; - void __FASTCALL update_intr(); - public: - I8259(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I8259(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_cpu = NULL; __I8259_MAX_CHIPS = 0; __CHIP_MASK = 0xffffffff; __I8259_PC98_HACK = false; + for(int c = 0; c < 2; c++) { + memset(&(pic[c]), 0x00, sizeof(struct i8259_pic_t)); + pic[c].irr_tmp_id = -1; + } set_device_name(_T("i8259 PIC")); } ~I8259() {} @@ -74,17 +76,18 @@ class I8259 : public DEVICE uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int id); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // interrupt common functions - void set_intr_line(bool line, bool pending, uint32_t bit) + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit) { // request from Z80 familly write_signal(bit, line ? 1 : 0, 1); } uint32_t get_intr_ack(); + void update_intr(); - // unique functions + // unique function void set_context_cpu(DEVICE* device) { d_cpu = device; diff --git a/source/src/vm/i86.cpp b/source/src/vm/i86.cpp index dfbb3ffcf..aa87856e4 100644 --- a/source/src/vm/i86.cpp +++ b/source/src/vm/i86.cpp @@ -3,71 +3,132 @@ Origin : MAME i286 core Author : Takeda.Toshiya - Date : 2012.10.18- + Date : 2012.10.18- - [ i286 ] + [ 8086/8088/80186/V30 ] */ #include "i86.h" +//#ifdef USE_DEBUGGER #include "debugger.h" - -#include "i80x86_commondefs.h" +#include "i386_dasm.h" +#include "v30_dasm.h" +//#endif /* ---------------------------------------------------------------------------- - MAME i86 + MAME i286 ---------------------------------------------------------------------------- */ -// Note: -// API of bios_int_i86() / bios_caii_i86() has changed. -// regs[8] regs[9] are added.These entries set redirect-address by PSEUDO-BIOS. -// If need, will add more entries for cycle#. -// - 20181126 K.O +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning( disable : 4018 ) +#pragma warning( disable : 4146 ) +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4996 ) +#endif +#ifndef __BIG_ENDIAN__ +#define LSB_FIRST +#endif +#ifndef INLINE +#define INLINE inline +#endif -//#if defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186) || defined(HAS_V30) - #define cpu_state i8086_state - #include "mame/emu/cpu/i86/i86.c" - #include "mame/emu/cpu/i386/i386dasm.c" -//#elif defined(HAS_I286) -//#define cpu_state i80286_state -//#include "mame/emu/cpu/i86/i286.c" -//#endif -//#ifdef USE_DEBUGGER -//#ifdef HAS_V30 -//#include "mame/emu/cpu/nec/necdasm.c" -//#else -//#endif -//#endif +#define logerror(...) + +/*****************************************************************************/ +/* src/emu/devcpu.h */ + +// CPU interface functions +#define CPU_INIT_NAME(name) cpu_init_##name +#define CPU_INIT(name) void* CPU_INIT_NAME(name)() +#define CPU_INIT_CALL(name) CPU_INIT_NAME(name)() -void I8086::initialize() +#define CPU_RESET_NAME(name) cpu_reset_##name +#define CPU_RESET(name) void CPU_RESET_NAME(name)(cpu_state *cpustate) +#define CPU_RESET_CALL(name) CPU_RESET_NAME(name)(cpustate) + +#define CPU_EXECUTE_NAME(name) cpu_execute_##name +#define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(cpu_state *cpustate, int icount) +#define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate, icount) + +/*****************************************************************************/ +/* src/emu/diexec.h */ + +// I/O line states +enum line_state +{ + CLEAR_LINE = 0, // clear (a fired or held) line + ASSERT_LINE, // assert an interrupt immediately + HOLD_LINE, // hold interrupt line until acknowledged + PULSE_LINE // pulse interrupt line instantaneously (only for NMI, RESET) +}; + +enum +{ + INPUT_LINE_IRQ = 0, + INPUT_LINE_NMI +}; + +/*****************************************************************************/ +/* src/emu/emucore.h */ + +// constants for expression endianness +enum endianness_t +{ + ENDIANNESS_LITTLE, + ENDIANNESS_BIG +}; + +// declare native endianness to be one or the other +#ifdef LSB_FIRST +const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE; +#else +const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG; +#endif +// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian +#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval)) +// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian +#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval) +// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native +#define ENDIAN_VALUE_NE_NNE(endian,leval,beval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval)) + +/*****************************************************************************/ +/* src/emu/memory.h */ + +// offsets and addresses are 32-bit (for now...) +typedef UINT32 offs_t; + +#define cpu_state i8086_state +#include "mame/emu/cpu/i86/i86.c" + +void I86::initialize() { DEVICE::initialize(); - n_cpu_type = N_CPU_TYPE_I8086; - _HAS_i80286 = false; - _HAS_v30 = false; - if(osd->check_feature("HAS_I86")) { - n_cpu_type = N_CPU_TYPE_I8086; - } else if(osd->check_feature("HAS_I88")) { - n_cpu_type = N_CPU_TYPE_I8088; - } else if(osd->check_feature("HAS_I186")) { - n_cpu_type = N_CPU_TYPE_I80186; - } - switch(n_cpu_type) { - case N_CPU_TYPE_I8086: - set_device_name(_T("i8086 CPU")); - opaque = CPU_INIT_CALL( i8086 ); + _SINGLE_MODE_DMA = osd->check_feature("SINGLE_MODE_DMA"); + _USE_DEBUGGER = osd->check_feature("USE_DEBUGGER"); + switch(device_model) { + case INTEL_8086: + opaque = CPU_INIT_CALL(i8086); + set_device_name(_T("8086 CPU")); break; - case N_CPU_TYPE_I8088: - set_device_name(_T("i8088 CPU")); - opaque = CPU_INIT_CALL( i8088 ); + case INTEL_8088: + opaque = CPU_INIT_CALL(i8088); + set_device_name(_T("8088 CPU")); break; - case N_CPU_TYPE_I80186: - set_device_name(_T("i80186 CPU")); - opaque = CPU_INIT_CALL( i80186 ); + case INTEL_80186: + opaque = CPU_INIT_CALL(i80186); + set_device_name(_T("80186 CPU")); break; - } - + case NEC_V30: + opaque = CPU_INIT_CALL(v30); + set_device_name(_T("V30 CPU")); + break; + default: + opaque = CPU_INIT_CALL(i8086); + set_device_name(_T("8086 CPU")); + break; + } cpu_state *cpustate = (cpu_state *)opaque; cpustate->pic = d_pic; cpustate->program = d_mem; @@ -76,48 +137,45 @@ void I8086::initialize() cpustate->bios = d_bios; //#endif //#ifdef SINGLE_MODE_DMA - cpustate->dma = d_dma; + if(_SINGLE_MODE_DMA) { + cpustate->dma = d_dma; + } //#endif //#ifdef USE_DEBUGGER cpustate->emu = emu; cpustate->debugger = d_debugger; cpustate->program_stored = d_mem; cpustate->io_stored = d_io; - - if(d_debugger != NULL) { - d_debugger->set_context_mem(d_mem); - d_debugger->set_context_io(d_io); - } + + d_debugger->set_context_mem(d_mem); + d_debugger->set_context_io(d_io); +//#endif } -void I8086::release() +void I86::release() { free(opaque); } -void I8086::cpu_reset_generic() -{ - cpu_state *cpustate = (cpu_state *)opaque; - switch(n_cpu_type) { - case N_CPU_TYPE_I8086: - CPU_RESET_CALL( i8086 ); - break; - case N_CPU_TYPE_I8088: - CPU_RESET_CALL( i8088 ); - break; - case N_CPU_TYPE_I80186: - CPU_RESET_CALL( i80186 ); - break; - } -} -void I8086::reset() +void I86::reset() { cpu_state *cpustate = (cpu_state *)opaque; int busreq = cpustate->busreq; - int haltreq = cpustate->haltreq; - - cpu_reset_generic(); + switch(device_model) { + case INTEL_8086: + CPU_RESET_CALL(i8086); + break; + case INTEL_8088: + CPU_RESET_CALL(i8088); + break; + case INTEL_80186: + CPU_RESET_CALL(i80186); + break; + case NEC_V30: + CPU_RESET_CALL(v30); + break; + } cpustate->pic = d_pic; cpustate->program = d_mem; cpustate->io = d_io; @@ -125,7 +183,9 @@ void I8086::reset() cpustate->bios = d_bios; //#endif //#ifdef SINGLE_MODE_DMA - cpustate->dma = d_dma; + if(_SINGLE_MODE_DMA) { + cpustate->dma = d_dma; + } //#endif //#ifdef USE_DEBUGGER cpustate->emu = emu; @@ -134,45 +194,26 @@ void I8086::reset() cpustate->io_stored = d_io; //#endif cpustate->busreq = busreq; - cpustate->haltreq = haltreq; } -int I8086::run(int icount) +int I86::run(int icount) { cpu_state *cpustate = (cpu_state *)opaque; - int ret = 0; - switch(n_cpu_type) { - case N_CPU_TYPE_I8086: - case N_CPU_TYPE_I8088: - ret = CPU_EXECUTE_CALL( i8086 ); - break; - case N_CPU_TYPE_I80186: - ret = CPU_EXECUTE_CALL( i80186 ); - break; - } - return ret; -} - -uint32_t I8086::read_signal(int id) -{ - if((id == SIG_CPU_TOTAL_CYCLE_HI) || (id == SIG_CPU_TOTAL_CYCLE_LO)) { - cpu_state *cpustate = (cpu_state *)opaque; - pair64_t n; - if(cpustate != NULL) { - n.q = cpustate->total_icount; - } else { - n.q = 0; - } - if(id == SIG_CPU_TOTAL_CYCLE_HI) { - return n.d.h; - } else { - return n.d.l; - } + + switch(device_model) { + case INTEL_8086: + return CPU_EXECUTE_CALL(i8086); + case INTEL_8088: + return CPU_EXECUTE_CALL(i8088); + case INTEL_80186: + return CPU_EXECUTE_CALL(i80186); + case NEC_V30: + return CPU_EXECUTE_CALL(v30); } return 0; } -void I8086::write_signal(int id, uint32_t data, uint32_t mask) +void I86::write_signal(int id, uint32_t data, uint32_t mask) { cpu_state *cpustate = (cpu_state *)opaque; @@ -182,99 +223,91 @@ void I8086::write_signal(int id, uint32_t data, uint32_t mask) set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE); } else if(id == SIG_CPU_BUSREQ) { cpustate->busreq = (data & mask) ? 1 : 0; - } else if(id == SIG_CPU_HALTREQ) { - cpustate->haltreq = (data & mask) ? 1 : 0; } else if(id == SIG_I86_TEST) { cpustate->test_state = (data & mask) ? 1 : 0; - } else if(id == SIG_CPU_WAIT_FACTOR) { - cpustate->waitfactor = data; // 65536. - cpustate->waitcount = 0; // 65536. } } -void I8086::set_intr_line(bool line, bool pending, uint32_t bit) +void I86::set_intr_line(bool line, bool pending, uint32_t bit) { cpu_state *cpustate = (cpu_state *)opaque; set_irq_line(cpustate, INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE); } -void I8086::set_extra_clock(int icount) +void I86::set_extra_clock(int icount) { cpu_state *cpustate = (cpu_state *)opaque; cpustate->extra_cycles += icount; } -int I8086::get_extra_clock() +int I86::get_extra_clock() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->extra_cycles; } -uint32_t I8086::get_pc() +uint32_t I86::get_pc() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->prevpc; } -uint32_t I8086::get_next_pc() +uint32_t I86::get_next_pc() { cpu_state *cpustate = (cpu_state *)opaque; return cpustate->pc; } -uint32_t I8086::translate_address(int segment, uint32_t offset) -{ - cpu_state *cpustate = (cpu_state *)opaque; - return cpustate->base[segment] + offset; -} - -void I8086::write_debug_data8(uint32_t addr, uint32_t data) +//#ifdef USE_DEBUGGER +void I86::write_debug_data8(uint32_t addr, uint32_t data) { int wait; d_mem->write_data8w(addr, data, &wait); } -uint32_t I8086::read_debug_data8(uint32_t addr) +uint32_t I86::read_debug_data8(uint32_t addr) { int wait; return d_mem->read_data8w(addr, &wait); } -void I8086::write_debug_data16(uint32_t addr, uint32_t data) +void I86::write_debug_data16(uint32_t addr, uint32_t data) { int wait; d_mem->write_data16w(addr, data, &wait); } -uint32_t I8086::read_debug_data16(uint32_t addr) +uint32_t I86::read_debug_data16(uint32_t addr) { int wait; return d_mem->read_data16w(addr, &wait); } -void I8086::write_debug_io8(uint32_t addr, uint32_t data) +void I86::write_debug_io8(uint32_t addr, uint32_t data) { int wait; d_io->write_io8w(addr, data, &wait); } -uint32_t I8086::read_debug_io8(uint32_t addr) { +uint32_t I86::read_debug_io8(uint32_t addr) +{ int wait; return d_io->read_io8w(addr, &wait); } -void I8086::write_debug_io16(uint32_t addr, uint32_t data) +void I86::write_debug_io16(uint32_t addr, uint32_t data) { int wait; d_io->write_io16w(addr, data, &wait); } -uint32_t I8086::read_debug_io16(uint32_t addr) { +uint32_t I86::read_debug_io16(uint32_t addr) +{ int wait; return d_io->read_io16w(addr, &wait); } -bool I8086::write_debug_reg(const _TCHAR *reg, uint32_t data) +bool I86::write_debug_reg(const _TCHAR *reg, uint32_t data) { cpu_state *cpustate = (cpu_state *)opaque; if(_tcsicmp(reg, _T("IP")) == 0) { @@ -318,7 +351,7 @@ bool I8086::write_debug_reg(const _TCHAR *reg, uint32_t data) return true; } -uint32_t I8086::read_debug_reg(const _TCHAR *reg) +uint32_t I86::read_debug_reg(const _TCHAR *reg) { cpu_state *cpustate = (cpu_state *)opaque; if(_tcsicmp(reg, _T("IP")) == 0) { @@ -359,7 +392,7 @@ uint32_t I8086::read_debug_reg(const _TCHAR *reg) return 0; } -bool I8086::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +bool I86::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) { cpu_state *cpustate = (cpu_state *)opaque; my_stprintf_s(buffer, buffer_len, @@ -376,34 +409,36 @@ bool I8086::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) return true; } -int I8086::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) +int I86::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) { cpu_state *cpustate = (cpu_state *)opaque; - UINT64 eip = pc - cpustate->base[CS]; - UINT8 ops[16]; + uint32_t eip = pc - cpustate->base[CS]; + uint8_t oprom[16]; + for(int i = 0; i < 16; i++) { int wait; - ops[i] = d_mem->read_data8w(pc + i, &wait); + oprom[i] = d_mem->read_data8w((pc + i) & AMASK, &wait); + } + switch(device_model) { + case NEC_V30: + return v30_dasm(cpustate->debugger, oprom, eip, (cpustate->MF == 0), buffer, buffer_len); + default: + return i386_dasm(oprom, eip, false, buffer, buffer_len); } - UINT8 *oprom = ops; - - return CPU_DISASSEMBLE_CALL(x86_16) & DASMFLAG_LENGTHMASK; } +#define STATE_VERSION 1 -#define STATE_VERSION 8 - -bool I8086::process_state(FILEIO* state_fio, bool loading) +bool I86::process_state(FILEIO* state_fio, bool loading) { cpu_state *cpustate = (cpu_state *)opaque; if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } + return false; + } if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } -//#if defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186) || defined(HAS_V30) + return false; + } state_fio->StateArray(cpustate->regs.w, sizeof(cpustate->regs.w), 1); state_fio->StateValue(cpustate->pc); state_fio->StateValue(cpustate->prevpc); @@ -420,6 +455,8 @@ bool I8086::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(cpustate->TF); state_fio->StateValue(cpustate->IF); state_fio->StateValue(cpustate->MF); + state_fio->StateValue(cpustate->MF_WriteDisabled); + state_fio->StateValue(cpustate->NF); state_fio->StateValue(cpustate->int_vector); state_fio->StateValue(cpustate->nmi_state); state_fio->StateValue(cpustate->irq_state); @@ -431,7 +468,9 @@ bool I8086::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(cpustate->ip); state_fio->StateValue(cpustate->sp); //#ifdef USE_DEBUGGER - state_fio->StateValue(cpustate->total_icount); + if(_USE_DEBUGGER) { + state_fio->StateValue(cpustate->total_icount); + } //#endif state_fio->StateValue(cpustate->icount); state_fio->StateValue(cpustate->seg_prefix); @@ -439,14 +478,15 @@ bool I8086::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(cpustate->ea); state_fio->StateValue(cpustate->eo); state_fio->StateValue(cpustate->ea_seg); - state_fio->StateValue(cpustate->waitfactor); - state_fio->StateValue(cpustate->waitcount); - state_fio->StateValue(cpustate->memory_wait); -//#endif - - // post process - if(loading) { - cpustate->prev_total_icount = cpustate->total_icount; + +//#ifdef USE_DEBUGGER + // post process + if(_USE_DEBUGGER) { + if(loading) { + cpustate->prev_total_icount = cpustate->total_icount; + } } - return true; +//#endif + return true; } + diff --git a/source/src/vm/i86.h b/source/src/vm/i86.h index 821b67046..0fbbf5361 100644 --- a/source/src/vm/i86.h +++ b/source/src/vm/i86.h @@ -3,69 +3,70 @@ Origin : MAME i286 core Author : Takeda.Toshiya - Date : 2012.10.18- + Date : 2012.10.18- - [ i286 ] + [ 8086/8088/80186/V30 ] */ -#pragma once -#ifndef _I86_H_ + +#ifndef _I86_H_ #define _I86_H_ -//#include "fileio.h" -//#include "vm_template.h" -//#include "../emu.h" #include "device.h" #define SIG_I86_TEST 0 +//#ifdef USE_DEBUGGER class DEBUGGER; +//#endif enum { - N_CPU_TYPE_I8086 = 0, - N_CPU_TYPE_I8088, - N_CPU_TYPE_I80186, - N_CPU_TYPE_V30, - N_CPU_TYPE_I80286, -}; - + INTEL_8086 = 0, + INTEL_8088, + INTEL_80186, + NEC_V30, +}; -class I8086 : public DEVICE +class DLL_PREFIX I86 : public DEVICE { -protected: +private: + bool _SINGLE_MODE_DMA; + bool _USE_DEBUGGER; DEVICE *d_mem, *d_io, *d_pic; +//#ifdef I86_PSEUDO_BIOS DEVICE *d_bios; +//#endif +//#ifdef SINGLE_MODE_DMA DEVICE *d_dma; +//#endif +//#ifdef USE_DEBUGGER DEBUGGER *d_debugger; +//#endif void *opaque; - int n_cpu_type; - bool _HAS_i80286; - bool _HAS_v30; - void cpu_reset_generic(); - + public: - I8086(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + I86(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { +//#ifdef I86_PSEUDO_BIOS d_bios = NULL; +//#endif +//#ifdef SINGLE_MODE_DMA d_dma = NULL; - d_debugger = NULL;; +//#endif } - ~I8086() {} + ~I86() {} // common functions - virtual void initialize(); - virtual void release(); - virtual void reset(); - virtual int __FASTCALL run(int icount); - virtual uint32_t __FASTCALL read_signal(int id); - virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - virtual void set_intr_line(bool line, bool pending, uint32_t bit); - virtual void set_extra_clock(int icount); - virtual int get_extra_clock(); - virtual uint32_t get_pc(); - virtual uint32_t get_next_pc(); - virtual uint32_t __FASTCALL translate_address(int segment, uint32_t offset); - - + void initialize(); + void release(); + void reset(); + int __FASTCALL run(int icount); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); + void __FASTCALL set_extra_clock(int icount); + int get_extra_clock(); + uint32_t get_pc(); + uint32_t get_next_pc(); +//#ifdef USE_DEBUGGER bool is_cpu() { return true; @@ -78,27 +79,28 @@ class I8086 : public DEVICE { return d_debugger; } - virtual uint32_t get_debug_prog_addr_mask() + uint32_t get_debug_prog_addr_mask() { return 0xfffff; } - virtual uint32_t get_debug_data_addr_mask() + uint32_t get_debug_data_addr_mask() { return 0xfffff; } - virtual void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); - virtual uint32_t __FASTCALL read_debug_data8(uint32_t addr); - virtual void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data); - virtual uint32_t __FASTCALL read_debug_data16(uint32_t addr); - virtual void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); - virtual uint32_t __FASTCALL read_debug_io8(uint32_t addr); - virtual void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data); - virtual uint32_t __FASTCALL read_debug_io16(uint32_t addr); - virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data); - virtual uint32_t __FASTCALL read_debug_reg(const _TCHAR *reg); - virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); - virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); - virtual bool process_state(FILEIO* state_fio, bool loading); + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data16(uint32_t addr); + void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io8(uint32_t addr); + void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io16(uint32_t addr); + bool write_debug_reg(const _TCHAR *reg, uint32_t data); + uint32_t __FASTCALL read_debug_reg(const _TCHAR *reg); + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len); +//#endif + bool process_state(FILEIO* state_fio, bool loading); // unique function void set_context_mem(DEVICE* device) @@ -109,23 +111,29 @@ class I8086 : public DEVICE { d_io = device; } - void set_context_intr(DEVICE* device, uint32_t bit = 0xffffffff) + void set_context_intr(DEVICE* device, uint32_t bit = 0xfffffffff) { d_pic = device; } +//#ifdef I86_PSEUDO_BIOS void set_context_bios(DEVICE* device) { d_bios = device; } +//#endif +//#ifdef SINGLE_MODE_DMA void set_context_dma(DEVICE* device) { d_dma = device; } +//#endif +//#ifdef USE_DEBUGGER void set_context_debugger(DEBUGGER* device) { d_debugger = device; } - +//#endif + int device_model; }; #endif diff --git a/source/src/vm/io.cpp b/source/src/vm/io.cpp index 2ede417ba..10f104c6c 100644 --- a/source/src/vm/io.cpp +++ b/source/src/vm/io.cpp @@ -9,10 +9,16 @@ #include "io.h" -#define IO_ADDR_MASK (addr_max - 1) +//#define IO_ADDR_MASK (addr_max - 1) void IO::initialize() { + DEVICE::initialize(); + __IO_DEBUG_LOG = osd->check_feature(_T("_IO_DEBUG_LOG")); + if(osd->check_feature("IO_ADDR_MAX") && !(addr_max_was_set)) { + addr_max = osd->get_feature_uint32_value(_T("IO_ADDR_MAX")); + } + IO_ADDR_MASK = addr_max - 1; // allocate tables here to support multiple instances with different address range if(wr_table == NULL) { wr_table = (wr_bank_t *)calloc(addr_max, sizeof(wr_bank_t)); @@ -133,15 +139,17 @@ void IO::write_port8(uint32_t addr, uint32_t data, bool is_dma) { uint32_t laddr = addr & IO_ADDR_MASK, haddr = addr & ~IO_ADDR_MASK; uint32_t addr2 = haddr | wr_table[laddr].addr; -#ifdef _IO_DEBUG_LOG - if(!wr_table[laddr].dev->this_device_id && !wr_table[laddr].is_flipflop) { - this->out_debug_log(_T("UNKNOWN:\t")); - } - if(cpu_index != 0) { - this->out_debug_log(_T("CPU=%d\t"), cpu_index); +//#ifdef _IO_DEBUG_LOG + if(__IO_DEBUG_LOG) { + if(!wr_table[laddr].dev->this_device_id && !wr_table[laddr].is_flipflop) { + this->out_debug_log(_T("UNKNOWN:\t")); + } + if(cpu_index != 0) { + this->out_debug_log(_T("CPU=%d\t"), cpu_index); + } + this->out_debug_log(_T("%06x\tOUT8\t%04x,%02x\n"), get_cpu_pc(cpu_index), addr, data & 0xff); } - this->out_debug_log(_T("%06x\tOUT8\t%04x,%02x\n"), get_cpu_pc(cpu_index), addr, data & 0xff); -#endif +//#endif if(wr_table[laddr].is_flipflop) { rd_table[laddr].value = data & 0xff; } else if(is_dma) { @@ -156,15 +164,17 @@ uint32_t IO::read_port8(uint32_t addr, bool is_dma) uint32_t laddr = addr & IO_ADDR_MASK, haddr = addr & ~IO_ADDR_MASK; uint32_t addr2 = haddr | rd_table[laddr].addr; uint32_t val = rd_table[laddr].value_registered ? rd_table[laddr].value : is_dma ? rd_table[laddr].dev->read_dma_io8(addr2) : rd_table[laddr].dev->read_io8(addr2); -#ifdef _IO_DEBUG_LOG - if(!rd_table[laddr].dev->this_device_id && !rd_table[laddr].value_registered) { - this->out_debug_log(_T("UNKNOWN:\t")); - } - if(cpu_index != 0) { - this->out_debug_log(_T("CPU=%d\t"), cpu_index); +//#ifdef _IO_DEBUG_LOG + if(__IO_DEBUG_LOG) { + if(!rd_table[laddr].dev->this_device_id && !rd_table[laddr].value_registered) { + this->out_debug_log(_T("UNKNOWN:\t")); + } + if(cpu_index != 0) { + this->out_debug_log(_T("CPU=%d\t"), cpu_index); + } + this->out_debug_log(_T("%06x\tIN8\t%04x = %02x\n"), get_cpu_pc(cpu_index), addr, val & 0xff); } - this->out_debug_log(_T("%06x\tIN8\t%04x = %02x\n"), get_cpu_pc(cpu_index), addr, val & 0xff); -#endif +//#endif return val & 0xff; } @@ -172,15 +182,17 @@ void IO::write_port16(uint32_t addr, uint32_t data, bool is_dma) { uint32_t laddr = addr & IO_ADDR_MASK, haddr = addr & ~IO_ADDR_MASK; uint32_t addr2 = haddr | wr_table[laddr].addr; -#ifdef _IO_DEBUG_LOG - if(!wr_table[laddr].dev->this_device_id && !wr_table[laddr].is_flipflop) { - this->out_debug_log(_T("UNKNOWN:\t")); - } - if(cpu_index != 0) { - this->out_debug_log(_T("CPU=%d\t"), cpu_index); +//#ifdef _IO_DEBUG_LOG + if(__IO_DEBUG_LOG) { + if(!wr_table[laddr].dev->this_device_id && !wr_table[laddr].is_flipflop) { + this->out_debug_log(_T("UNKNOWN:\t")); + } + if(cpu_index != 0) { + this->out_debug_log(_T("CPU=%d\t"), cpu_index); + } + this->out_debug_log(_T("%06x\tOUT16\t%04x,%04x\n"), get_cpu_pc(cpu_index), addr, data & 0xffff); } - this->out_debug_log(_T("%06x\tOUT16\t%04x,%04x\n"), get_cpu_pc(cpu_index), addr, data & 0xffff); -#endif +//#endif if(wr_table[laddr].is_flipflop) { rd_table[laddr].value = data & 0xffff; } else if(is_dma) { @@ -195,15 +207,17 @@ uint32_t IO::read_port16(uint32_t addr, bool is_dma) uint32_t laddr = addr & IO_ADDR_MASK, haddr = addr & ~IO_ADDR_MASK; uint32_t addr2 = haddr | rd_table[laddr].addr; uint32_t val = rd_table[laddr].value_registered ? rd_table[laddr].value : is_dma ? rd_table[laddr].dev->read_dma_io16(addr2) : rd_table[laddr].dev->read_io16(addr2); -#ifdef _IO_DEBUG_LOG - if(!rd_table[laddr].dev->this_device_id && !rd_table[laddr].value_registered) { - this->out_debug_log(_T("UNKNOWN:\t")); - } - if(cpu_index != 0) { - this->out_debug_log(_T("CPU=%d\t"), cpu_index); +//#ifdef _IO_DEBUG_LOG + if(__IO_DEBUG_LOG) { + if(!rd_table[laddr].dev->this_device_id && !rd_table[laddr].value_registered) { + this->out_debug_log(_T("UNKNOWN:\t")); + } + if(cpu_index != 0) { + this->out_debug_log(_T("CPU=%d\t"), cpu_index); + } + this->out_debug_log(_T("%06x\tIN16\t%04x = %04x\n"), get_cpu_pc(cpu_index), addr, val & 0xffff); } - this->out_debug_log(_T("%06x\tIN16\t%04x = %04x\n"), get_cpu_pc(cpu_index), addr, val & 0xffff); -#endif +//#endif return val & 0xffff; } @@ -211,15 +225,17 @@ void IO::write_port32(uint32_t addr, uint32_t data, bool is_dma) { uint32_t laddr = addr & IO_ADDR_MASK, haddr = addr & ~IO_ADDR_MASK; uint32_t addr2 = haddr | wr_table[laddr].addr; -#ifdef _IO_DEBUG_LOG - if(!wr_table[laddr].dev->this_device_id && !wr_table[laddr].is_flipflop) { - this->out_debug_log(_T("UNKNOWN:\t")); - } - if(cpu_index != 0) { - this->out_debug_log(_T("CPU=%d\t"), cpu_index); +//#ifdef _IO_DEBUG_LOG + if(__IO_DEBUG_LOG) { + if(!wr_table[laddr].dev->this_device_id && !wr_table[laddr].is_flipflop) { + this->out_debug_log(_T("UNKNOWN:\t")); + } + if(cpu_index != 0) { + this->out_debug_log(_T("CPU=%d\t"), cpu_index); + } + this->out_debug_log(_T("%06x\tOUT32\t%04x,%08x\n"), get_cpu_pc(cpu_index), addr, data); } - this->out_debug_log(_T("%06x\tOUT32\t%04x,%08x\n"), get_cpu_pc(cpu_index), addr, data); -#endif +//#endif if(wr_table[laddr].is_flipflop) { rd_table[laddr].value = data; } else if(is_dma) { @@ -234,15 +250,17 @@ uint32_t IO::read_port32(uint32_t addr, bool is_dma) uint32_t laddr = addr & IO_ADDR_MASK, haddr = addr & ~IO_ADDR_MASK; uint32_t addr2 = haddr | rd_table[laddr].addr; uint32_t val = rd_table[laddr].value_registered ? rd_table[laddr].value : is_dma ? rd_table[laddr].dev->read_dma_io32(addr2) : rd_table[laddr].dev->read_io32(addr2); -#ifdef _IO_DEBUG_LOG - if(!rd_table[laddr].dev->this_device_id && !rd_table[laddr].value_registered) { - this->out_debug_log(_T("UNKNOWN:\t")); - } - if(cpu_index != 0) { - this->out_debug_log(_T("CPU=%d\t"), cpu_index); +//#ifdef _IO_DEBUG_LOG + if(__IO_DEBUG_LOG) { + if(!rd_table[laddr].dev->this_device_id && !rd_table[laddr].value_registered) { + this->out_debug_log(_T("UNKNOWN:\t")); + } + if(cpu_index != 0) { + this->out_debug_log(_T("CPU=%d\t"), cpu_index); + } + this->out_debug_log(_T("%06x\tIN32\t%04x = %08x\n"), get_cpu_pc(cpu_index), laddr | haddr, val); } - this->out_debug_log(_T("%06x\tIN32\t%04x = %08x\n"), get_cpu_pc(cpu_index), laddr | haddr, val); -#endif +//#endif return val; } diff --git a/source/src/vm/io.h b/source/src/vm/io.h index 00e8caa75..35acf9ad6 100644 --- a/source/src/vm/io.h +++ b/source/src/vm/io.h @@ -10,15 +10,13 @@ #ifndef _IO_H_ #define _IO_H_ -#include "vm.h" -#include "../emu.h" #include "device.h" -#ifndef IO_ADDR_MAX -#define IO_ADDR_MAX 0x100 -#endif +//#ifndef IO_ADDR_MAX +//#define IO_ADDR_MAX 0x100 +//#endif -class IO : public DEVICE +class DLL_PREFIX IO : public DEVICE { private: // i/o map @@ -39,6 +37,12 @@ class IO : public DEVICE wr_bank_t *wr_table; rd_bank_t *rd_table; + + bool __IO_DEBUG_LOG; + uint32_t IO_ADDR_MASK; + bool addr_max_was_set; + // You should set addr_max via #define or set_addr_max() before initialize();. + uint32_t addr_max; void __FASTCALL write_port8(uint32_t addr, uint32_t data, bool is_dma); uint32_t __FASTCALL read_port8(uint32_t addr, bool is_dma); @@ -48,13 +52,15 @@ class IO : public DEVICE uint32_t __FASTCALL read_port32(uint32_t addr, bool is_dma); public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { -#ifdef _IO_DEBUG_LOG + __IO_DEBUG_LOG = false; +//#ifdef _IO_DEBUG_LOG cpu_index = 0; -#endif - addr_max = IO_ADDR_MAX; - +//#endif + addr_max = 0x100; + IO_ADDR_MASK = addr_max - 1; + addr_max_was_set = false; wr_table = NULL; rd_table = NULL; @@ -108,10 +114,22 @@ class IO : public DEVICE void set_iowait_range_w(uint32_t s, uint32_t e, int wait); void set_iowait_range_rw(uint32_t s, uint32_t e, int wait); -#ifdef _IO_DEBUG_LOG +//#ifdef _IO_DEBUG_LOG int cpu_index; -#endif - int addr_max; +//#endif + void set_addr_max(uint32_t val) + { + // Allow to modify before initialize() or set_foo_r|w|rw().. + if(rd_table == NULL) { + addr_max_was_set = true; + addr_max = val; +// IO_ADDR_MASK = addr_max - 1; + } + } + uint32_t get_addr_max() + { + return addr_max; + } }; #endif diff --git a/source/src/vm/j3100/CMakeLists.txt b/source/src/vm/j3100/CMakeLists.txt index 296889f5f..70febd8a1 100644 --- a/source/src/vm/j3100/CMakeLists.txt +++ b/source/src/vm/j3100/CMakeLists.txt @@ -1,30 +1,51 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/j3100") +message("* vm/${EXE_NAME}") set(VM_J3100_LIB_SRCS +# ../i286.cpp + ../i8237.cpp + ../scsi_host.cpp + display.cpp dmareg.cpp floppy.cpp - j3100.cpp sasi.cpp + + j3100.cpp ) -if(BUILD_J3100GT) - set(VM_J3100_LIB_SRCS ${VM_J3100_LIB_SRCS} - memory.cpp - system.cpp - keyboard.cpp - ) -elseif(BUILD_J3100SL) - set(VM_J3100_LIB_SRCS ${VM_J3100_LIB_SRCS} - slmemory.cpp - slsystem.cpp - slkeyboard.cpp - ) -endif() +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) +if("${U_EXE_NAME}" STREQUAL "EMUJ3100GT") + add_library(vm_${EXE_NAME} + ./memory.cpp + ./system.cpp + ./keyboard.cpp + ${VM_J3100_LIB_SRCS} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUJ3100SL") + add_library(vm_${EXE_NAME} + + slmemory.cpp + slsystem.cpp + slkeyboard.cpp + ${VM_J3100_LIB_SRCS} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUJ3100SS") + add_library(vm_${EXE_NAME} -add_library(vm_j3100 - ${VM_J3100_LIB_SRCS} -) \ No newline at end of file + ./memory.cpp + system.cpp + keyboard.cpp + ${VM_J3100_LIB_SRCS} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUJ3100SE") + add_library(vm_${EXE_NAME} + + ./memory.cpp + system.cpp + keyboard.cpp + ${VM_J3100_LIB_SRCS} + ) +endif() diff --git a/source/src/vm/j3100/display.h b/source/src/vm/j3100/display.h index 0dbc0f614..fe8515bf3 100644 --- a/source/src/vm/j3100/display.h +++ b/source/src/vm/j3100/display.h @@ -43,7 +43,7 @@ class DISPLAY : public DEVICE void draw_graph_640x400(); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/j3100/dmareg.h b/source/src/vm/j3100/dmareg.h index 870fec2f6..b202a9363 100644 --- a/source/src/vm/j3100/dmareg.h +++ b/source/src/vm/j3100/dmareg.h @@ -26,7 +26,7 @@ class DMAREG : public DEVICE #endif public: - DMAREG(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DMAREG(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("DMA Register")); } diff --git a/source/src/vm/j3100/floppy.h b/source/src/vm/j3100/floppy.h index 4519e7630..aed143099 100644 --- a/source/src/vm/j3100/floppy.h +++ b/source/src/vm/j3100/floppy.h @@ -27,7 +27,7 @@ class FLOPPY : public DEVICE uint8_t ctrl_reg; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/j3100/j3100.cpp b/source/src/vm/j3100/j3100.cpp index c07d932e3..597455ef5 100644 --- a/source/src/vm/j3100/j3100.cpp +++ b/source/src/vm/j3100/j3100.cpp @@ -18,18 +18,15 @@ //#include "../i8250.h" #include "../i8253.h" #include "../i8259.h" -#if defined(HAS_I286) -#include "../i286.h" -#else -#include "../i86.h" -#endif #include "../io.h" #include "../noise.h" #include "../pcm1bit.h" #include "../upd765a.h" #ifdef TYPE_SL +#include "../i86.h" #include "../rp5c01.h" #else +#include "../i286.h" #include "../hd146818p.h" #endif @@ -70,7 +67,7 @@ using J3100::SYSTEM; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -96,10 +93,11 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // sio = new I8250(this, emu); pit = new I8253(this, emu); // i8254 pic = new I8259(this, emu); -#if defined(HAS_I286) - cpu = new I80286(this, emu); +#ifdef TYPE_SL + cpu = new I86(this, emu); + cpu->device_model = INTEL_8086; #else - cpu = new I8086(this, emu); + cpu = new I286(this, emu); #endif io = new IO(this, emu); pcm = new PCM1BIT(this, emu); @@ -185,7 +183,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #else io->set_iomap_alias_w(0x70, rtc, 1); // bit7 = nmi mask io->set_iomap_alias_rw(0x71, rtc, 0); - rtc->set_context_intr(pic, SIG_I8259_IR0 | SIG_I8259_CHIP1, 1); // to PIC#1 IR0 (IR8) + rtc->set_context_intr_line(pic, SIG_I8259_IR0 | SIG_I8259_CHIP1, 1); // to PIC#1 IR0 (IR8) #endif // nmi mask register @@ -441,7 +439,19 @@ void VM::update_config() } } -#define STATE_VERSION 2 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -453,7 +463,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/j3100/j3100.h b/source/src/vm/j3100/j3100.h index fe99d6f41..2f3a095ce 100644 --- a/source/src/vm/j3100/j3100.h +++ b/source/src/vm/j3100/j3100.h @@ -37,10 +37,8 @@ #define UPD765A_SENCE_INTSTAT_RESULT #define UPD765A_EXT_DRVSEL #ifdef TYPE_SL -#define HAS_I86 #define I8259_MAX_CHIPS 1 #else -#define HAS_I286 #define I8259_MAX_CHIPS 2 #endif #if !(defined(_J3100SS) || defined(_J3100SE)) @@ -80,10 +78,10 @@ class I8237; //class I8250; class I8253; class I8259; -#if defined(HAS_I286) -class I80286; +#ifdef TYPE_SL +class I86; #else -class I8086; +class I286; #endif class IO; class PCM1BIT; @@ -127,10 +125,10 @@ class VM : public VM_TEMPLATE // I8250* sio; I8253* pit; I8259* pic; -#if defined(HAS_I286) - I80286* cpu; +#ifdef TYPE_SL + I86* cpu; #else - I8086* cpu; + I286* cpu; #endif IO* io; PCM1BIT* pcm; @@ -161,7 +159,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -202,6 +200,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/j3100/keyboard.h b/source/src/vm/j3100/keyboard.h index e6b60863c..57508937d 100644 --- a/source/src/vm/j3100/keyboard.h +++ b/source/src/vm/j3100/keyboard.h @@ -36,7 +36,7 @@ class KEYBOARD : public DEVICE void process_cmd(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/j3100/memory.h b/source/src/vm/j3100/memory.h index 0124b48ef..8a1aeb30a 100644 --- a/source/src/vm/j3100/memory.h +++ b/source/src/vm/j3100/memory.h @@ -35,7 +35,7 @@ class MEMORY : public DEVICE void update_ems(int page); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/j3100/sasi.h b/source/src/vm/j3100/sasi.h index a08cfd47c..756533caf 100644 --- a/source/src/vm/j3100/sasi.h +++ b/source/src/vm/j3100/sasi.h @@ -54,7 +54,7 @@ class SASI : public DEVICE drive_t drive[2]; public: - SASI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SASI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("SASI I/F")); } @@ -69,7 +69,7 @@ class SASI : public DEVICE void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_dma_io8(uint32_t addr); uint32_t __FASTCALL read_signal(int ch); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); // unique function void set_context_pic(DEVICE* device) diff --git a/source/src/vm/j3100/slkeyboard.h b/source/src/vm/j3100/slkeyboard.h index 7cf0a4057..0bd3914e0 100644 --- a/source/src/vm/j3100/slkeyboard.h +++ b/source/src/vm/j3100/slkeyboard.h @@ -30,7 +30,7 @@ class KEYBOARD : public DEVICE bool key_read; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } @@ -43,7 +43,7 @@ class KEYBOARD : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void event_frame(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); // unique functions void set_context_pic(DEVICE* device) diff --git a/source/src/vm/j3100/slmemory.h b/source/src/vm/j3100/slmemory.h index 7a687e91a..2b61e7be1 100644 --- a/source/src/vm/j3100/slmemory.h +++ b/source/src/vm/j3100/slmemory.h @@ -48,7 +48,7 @@ class MEMORY : public DEVICE void __FASTCALL update_ems(int page); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/j3100/slsystem.h b/source/src/vm/j3100/slsystem.h index f4f326c3a..1d7834782 100644 --- a/source/src/vm/j3100/slsystem.h +++ b/source/src/vm/j3100/slsystem.h @@ -22,7 +22,7 @@ class SYSTEM : public DEVICE int nmi_mask; public: - SYSTEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSTEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/j3100/system.h b/source/src/vm/j3100/system.h index 1c2a481aa..db9f0a495 100644 --- a/source/src/vm/j3100/system.h +++ b/source/src/vm/j3100/system.h @@ -26,7 +26,7 @@ class SYSTEM : public DEVICE uint8_t status; public: - SYSTEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSTEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/jr100/CMakeLists.txt b/source/src/vm/jr100/CMakeLists.txt index 7194dad6f..6d4191b50 100644 --- a/source/src/vm/jr100/CMakeLists.txt +++ b/source/src/vm/jr100/CMakeLists.txt @@ -1,11 +1,12 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/jr100") +message("* vm/emujr100") -set(BASIC_VM_FILES - jr100.cpp - memory.cpp - ) +set(BASIC_VM_FILES + ../sy6522.cpp + + ./memory.cpp + jr100.cpp +) - -add_library(vm_jr100 ${BASIC_VM_FILES}) +add_library(vm_emujr100 ${BASIC_VM_FILES}) diff --git a/source/src/vm/jr100/jr100.cpp b/source/src/vm/jr100/jr100.cpp index e113729ad..2185edfc2 100644 --- a/source/src/vm/jr100/jr100.cpp +++ b/source/src/vm/jr100/jr100.cpp @@ -31,7 +31,7 @@ using JR100::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -125,7 +125,7 @@ void VM::reset() } } -void VM::special_reset() +void VM::special_reset(int num) { // reset all devices for(DEVICE* device = first_device; device; device = device->next_device) { @@ -299,6 +299,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -311,7 +323,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/jr100/jr100.h b/source/src/vm/jr100/jr100.h index ed92acdfd..ccfd443ef 100644 --- a/source/src/vm/jr100/jr100.h +++ b/source/src/vm/jr100/jr100.h @@ -146,7 +146,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -155,7 +155,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -196,6 +196,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/jr100/memory.h b/source/src/vm/jr100/memory.h index 1743d2f68..db958b34d 100644 --- a/source/src/vm/jr100/memory.h +++ b/source/src/vm/jr100/memory.h @@ -42,7 +42,7 @@ class MEMORY : public DEVICE scrntype_t palette_pc[2]; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/jr800/CMakeLists.txt b/source/src/vm/jr800/CMakeLists.txt index 36b60a604..ce7e2d87c 100644 --- a/source/src/vm/jr800/CMakeLists.txt +++ b/source/src/vm/jr800/CMakeLists.txt @@ -1,8 +1,9 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/jr800") +message("* vm/emujr800") -add_library(vm_jr800 - io.cpp +add_library(vm_emujr800 + + ./io.cpp jr800.cpp ) diff --git a/source/src/vm/jr800/io.h b/source/src/vm/jr800/io.h index 8483e2595..0b224efe9 100644 --- a/source/src/vm/jr800/io.h +++ b/source/src/vm/jr800/io.h @@ -25,7 +25,7 @@ class IO : public DEVICE HD44102 *d_lcd[8]; public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Mapped I/O")); } diff --git a/source/src/vm/jr800/jr800.cpp b/source/src/vm/jr800/jr800.cpp index da6002ce5..a16dfb91a 100644 --- a/source/src/vm/jr800/jr800.cpp +++ b/source/src/vm/jr800/jr800.cpp @@ -31,7 +31,7 @@ using JR800::IO; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -48,6 +48,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // cpu = new MC6800(this, emu); cpu = new HD6301(this, emu); memory = new MEMORY(this, emu); + pcm = new PCM1BIT(this, emu); io = new IO(this, emu); @@ -297,6 +298,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -309,7 +322,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/jr800/jr800.h b/source/src/vm/jr800/jr800.h index 1d1405caa..4455d2cb7 100644 --- a/source/src/vm/jr800/jr800.h +++ b/source/src/vm/jr800/jr800.h @@ -84,7 +84,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -132,6 +132,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/jx/CMakeLists.txt b/source/src/vm/jx/CMakeLists.txt index 9e1c81ec0..5813968ec 100644 --- a/source/src/vm/jx/CMakeLists.txt +++ b/source/src/vm/jx/CMakeLists.txt @@ -1,15 +1,14 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/jx") +message("* vm/emujx") set(BASIC_VM_FILES - jx.cpp - display.cpp - floppy.cpp - keyboard.cpp - speaker.cpp - - ./i286.cpp - ) + ./i86.cpp + display.cpp + floppy.cpp + keyboard.cpp + speaker.cpp + jx.cpp +) -add_library(vm_jx ${BASIC_VM_FILES}) +add_library(vm_emujx ${BASIC_VM_FILES}) diff --git a/source/src/vm/jx/display.h b/source/src/vm/jx/display.h index ef2fee400..2faab192a 100644 --- a/source/src/vm/jx/display.h +++ b/source/src/vm/jx/display.h @@ -59,7 +59,7 @@ class DISPLAY : public DEVICE void draw_graph_360x512_4col(); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/jx/floppy.h b/source/src/vm/jx/floppy.h index 2f77208e7..caee714fd 100644 --- a/source/src/vm/jx/floppy.h +++ b/source/src/vm/jx/floppy.h @@ -24,7 +24,7 @@ class FLOPPY : public DEVICE int register_id; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } @@ -33,7 +33,7 @@ class FLOPPY : public DEVICE // common functions void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/jx/i286.cpp b/source/src/vm/jx/i286.cpp deleted file mode 100644 index 2949f9895..000000000 --- a/source/src/vm/jx/i286.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* - Skelton for retropc emulator - - Author : Takeda.Toshiya - Date : 2012.10.18- - - [ i286 ] -*/ - -#include "i286.h" -#ifdef USE_DEBUGGER -#include "../debugger.h" -#endif - -/* ---------------------------------------------------------------------------- - MAME i286 ----------------------------------------------------------------------------- */ - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#pragma warning( disable : 4018 ) -#pragma warning( disable : 4146 ) -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4996 ) -#endif - -namespace JX { - -#if defined(HAS_I86) - #define CPU_MODEL i8086 -#elif defined(HAS_I88) - #define CPU_MODEL i8088 -#elif defined(HAS_I186) - #define CPU_MODEL i80186 -#elif defined(HAS_V30) - #define CPU_MODEL v30 -#elif defined(HAS_I286) - #define CPU_MODEL i80286 -#endif - -#ifndef __BIG_ENDIAN__ -#define LSB_FIRST -#endif - -#ifndef INLINE -#define INLINE inline -#endif - -#define logerror(...) - -/*****************************************************************************/ -/* src/emu/devcpu.h */ - -// CPU interface functions -#define CPU_INIT_NAME(name) cpu_init_##name -#define CPU_INIT(name) void* CPU_INIT_NAME(name)() -#define CPU_INIT_CALL(name) CPU_INIT_NAME(name)() - -#define CPU_RESET_NAME(name) cpu_reset_##name -#define CPU_RESET(name) void CPU_RESET_NAME(name)(cpu_state *cpustate) -#define CPU_RESET_CALL(name) CPU_RESET_NAME(name)(cpustate) - -#define CPU_EXECUTE_NAME(name) cpu_execute_##name -#define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(cpu_state *cpustate, int icount) -#define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate, icount) - -#define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom) -#define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, eip, oprom) - -/*****************************************************************************/ -/* src/emu/didisasm.h */ - -// Disassembler constants -const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported? -const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence -const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards -const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over -const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value -const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length - -/*****************************************************************************/ -/* src/emu/diexec.h */ - -// I/O line states -enum line_state -{ - CLEAR_LINE = 0, // clear (a fired or held) line - ASSERT_LINE, // assert an interrupt immediately - HOLD_LINE, // hold interrupt line until acknowledged - PULSE_LINE // pulse interrupt line instantaneously (only for NMI, RESET) -}; - -enum -{ - INPUT_LINE_IRQ = 0, - INPUT_LINE_NMI -}; - -/*****************************************************************************/ -/* src/emu/emucore.h */ - -// constants for expression endianness -enum endianness_t -{ - ENDIANNESS_LITTLE, - ENDIANNESS_BIG -}; - -// declare native endianness to be one or the other -#ifdef LSB_FIRST -const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE; -#else -const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG; -#endif -// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian -#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval)) -// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian -#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval) -// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native -#define ENDIAN_VALUE_NE_NNE(endian,leval,beval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval)) - -/*****************************************************************************/ -/* src/emu/memory.h */ - -// offsets and addresses are 32-bit (for now...) -typedef UINT32 offs_t; - -/*****************************************************************************/ -/* src/osd/osdcomm.h */ - -/* Highly useful macro for compile-time knowledge of an array size */ -#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0])) - -#if defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186) || defined(HAS_V30) -#define cpu_state i8086_state -#include "../mame/emu/cpu/i86/i86.c" -#elif defined(HAS_I286) -#define cpu_state i80286_state -#include "../mame/emu/cpu/i86/i286.c" -#endif -#ifdef USE_DEBUGGER -#ifdef HAS_V30 -#include "../mame/emu/cpu/nec/necdasm.c" -#else -#include "../mame/emu/cpu/i386/i386dasm.c" -#endif -#endif - -void I286::initialize() -{ - opaque = CPU_INIT_CALL(CPU_MODEL); - - cpu_state *cpustate = (cpu_state *)opaque; - cpustate->pic = d_pic; - cpustate->program = d_mem; - cpustate->io = d_io; -#ifdef I86_PSEUDO_BIOS - cpustate->bios = d_bios; -#endif -#ifdef SINGLE_MODE_DMA - cpustate->dma = d_dma; -#endif -#ifdef USE_DEBUGGER - cpustate->emu = emu; - cpustate->debugger = d_debugger; - cpustate->program_stored = d_mem; - cpustate->io_stored = d_io; - - d_debugger->set_context_mem(d_mem); - d_debugger->set_context_io(d_io); -#endif -} - -void I286::release() -{ - free(opaque); -} - -void I286::reset() -{ - cpu_state *cpustate = (cpu_state *)opaque; - int busreq = cpustate->busreq; - int haltreq = cpustate->haltreq; - - CPU_RESET_CALL(CPU_MODEL); - - cpustate->pic = d_pic; - cpustate->program = d_mem; - cpustate->io = d_io; -#ifdef I86_PSEUDO_BIOS - cpustate->bios = d_bios; -#endif -#ifdef SINGLE_MODE_DMA - cpustate->dma = d_dma; -#endif -#ifdef USE_DEBUGGER - cpustate->emu = emu; - cpustate->debugger = d_debugger; - cpustate->program_stored = d_mem; - cpustate->io_stored = d_io; -#endif - cpustate->busreq = busreq; - cpustate->haltreq = haltreq; -} - -int I286::run(int icount) -{ - cpu_state *cpustate = (cpu_state *)opaque; -#ifdef _JX - // ugly patch for PC/JX hardware diagnostics :-( -#ifdef TIMER_HACK - if(cpustate->pc == 0xff040) cpustate->pc = 0xff04a; - if(cpustate->pc == 0xff17d) cpustate->pc = 0xff18f; -#endif -#ifdef KEYBOARD_HACK - if(cpustate->pc == 0xfa909) { cpustate->regs.b[BH] = read_port_byte(cpustate, 0xa1); cpustate->pc = 0xfa97c; } - if(cpustate->pc == 0xff6e1) { cpustate->regs.b[AL] = 0x0d; cpustate->pc += 2; } -#endif -#endif - return CPU_EXECUTE_CALL(CPU_MODEL); -} - -uint32_t I286::read_signal(int id) -{ - if((id == SIG_CPU_TOTAL_CYCLE_HI) || (id == SIG_CPU_TOTAL_CYCLE_LO)) { - cpu_state *cpustate = (cpu_state *)opaque; - pair64_t n; - if(cpustate != NULL) { - n.q = cpustate->total_icount; - } else { - n.q = 0; - } - if(id == SIG_CPU_TOTAL_CYCLE_HI) { - return n.d.h; - } else { - return n.d.l; - } - } - return 0; -} - -void I286::write_signal(int id, uint32_t data, uint32_t mask) -{ - cpu_state *cpustate = (cpu_state *)opaque; - - if(id == SIG_CPU_NMI) { - set_irq_line(cpustate, INPUT_LINE_NMI, (data & mask) ? HOLD_LINE : CLEAR_LINE); - } else if(id == SIG_CPU_IRQ) { - set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE); - } else if(id == SIG_CPU_BUSREQ) { - cpustate->busreq = (data & mask) ? 1 : 0; - } else if(id == SIG_CPU_HALTREQ) { - cpustate->haltreq = (data & mask) ? 1 : 0; - } else if(id == SIG_I86_TEST) { - cpustate->test_state = (data & mask) ? 1 : 0; -#ifdef HAS_I286 - } else if(id == SIG_I286_A20) { - i80286_set_a20_line(cpustate, data & mask); -#endif - } else if(id == SIG_CPU_WAIT_FACTOR) { - cpustate->waitfactor = data; // 65536. - cpustate->waitcount = 0; // 65536. - } -} - -void I286::set_intr_line(bool line, bool pending, uint32_t bit) -{ - cpu_state *cpustate = (cpu_state *)opaque; - set_irq_line(cpustate, INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE); -} - -void I286::set_extra_clock(int icount) -{ - cpu_state *cpustate = (cpu_state *)opaque; - cpustate->extra_cycles += icount; -} - -int I286::get_extra_clock() -{ - cpu_state *cpustate = (cpu_state *)opaque; - return cpustate->extra_cycles; -} - -uint32_t I286::get_pc() -{ - cpu_state *cpustate = (cpu_state *)opaque; - return cpustate->prevpc; -} - -uint32_t I286::get_next_pc() -{ - cpu_state *cpustate = (cpu_state *)opaque; - return cpustate->pc; -} - -uint32_t I286::translate_address(int segment, uint32_t offset) -{ - cpu_state *cpustate = (cpu_state *)opaque; - return cpustate->base[segment] + offset; -} - -#ifdef USE_DEBUGGER -void I286::write_debug_data8(uint32_t addr, uint32_t data) -{ - int wait; - d_mem->write_data8w(addr, data, &wait); -} - -uint32_t I286::read_debug_data8(uint32_t addr) -{ - int wait; - return d_mem->read_data8w(addr, &wait); -} - -void I286::write_debug_data16(uint32_t addr, uint32_t data) -{ - int wait; - d_mem->write_data16w(addr, data, &wait); -} - -uint32_t I286::read_debug_data16(uint32_t addr) -{ - int wait; - return d_mem->read_data16w(addr, &wait); -} - -void I286::write_debug_io8(uint32_t addr, uint32_t data) -{ - int wait; - d_io->write_io8w(addr, data, &wait); -} - -uint32_t I286::read_debug_io8(uint32_t addr) { - int wait; - return d_io->read_io8w(addr, &wait); -} - -void I286::write_debug_io16(uint32_t addr, uint32_t data) -{ - int wait; - d_io->write_io16w(addr, data, &wait); -} - -uint32_t I286::read_debug_io16(uint32_t addr) { - int wait; - return d_io->read_io16w(addr, &wait); -} - -bool I286::write_debug_reg(const _TCHAR *reg, uint32_t data) -{ - cpu_state *cpustate = (cpu_state *)opaque; - if(_tcsicmp(reg, _T("IP")) == 0) { - cpustate->pc = ((data & 0xffff) + cpustate->base[CS]) & AMASK; - CHANGE_PC(cpustate->pc); - } else if(_tcsicmp(reg, _T("AX")) == 0) { - cpustate->regs.w[AX] = data; - } else if(_tcsicmp(reg, _T("BX")) == 0) { - cpustate->regs.w[BX] = data; - } else if(_tcsicmp(reg, _T("CX")) == 0) { - cpustate->regs.w[CX] = data; - } else if(_tcsicmp(reg, _T("DX")) == 0) { - cpustate->regs.w[DX] = data; - } else if(_tcsicmp(reg, _T("SP")) == 0) { - cpustate->regs.w[SP] = data; - } else if(_tcsicmp(reg, _T("BP")) == 0) { - cpustate->regs.w[BP] = data; - } else if(_tcsicmp(reg, _T("SI")) == 0) { - cpustate->regs.w[SI] = data; - } else if(_tcsicmp(reg, _T("DI")) == 0) { - cpustate->regs.w[DI] = data; - } else if(_tcsicmp(reg, _T("AL")) == 0) { - cpustate->regs.b[AL] = data; - } else if(_tcsicmp(reg, _T("AH")) == 0) { - cpustate->regs.b[AH] = data; - } else if(_tcsicmp(reg, _T("BL")) == 0) { - cpustate->regs.b[BL] = data; - } else if(_tcsicmp(reg, _T("BH")) == 0) { - cpustate->regs.b[BH] = data; - } else if(_tcsicmp(reg, _T("CL")) == 0) { - cpustate->regs.b[CL] = data; - } else if(_tcsicmp(reg, _T("CH")) == 0) { - cpustate->regs.b[CH] = data; - } else if(_tcsicmp(reg, _T("DL")) == 0) { - cpustate->regs.b[DL] = data; - } else if(_tcsicmp(reg, _T("DH")) == 0) { - cpustate->regs.b[DH] = data; - } else { - return false; - } - return true; -} - -bool I286::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) -{ - cpu_state *cpustate = (cpu_state *)opaque; - my_stprintf_s(buffer, buffer_len, - _T("AX=%04X BX=%04X CX=%04X DX=%04X SP=%04X BP=%04X SI=%04X DI=%04X\n") - _T("DS=%04X ES=%04X SS=%04X CS=%04X IP=%04X FLAG=[%c%c%c%c%c%c%c%c%c]\n") - _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), - cpustate->regs.w[AX], cpustate->regs.w[BX], cpustate->regs.w[CX], cpustate->regs.w[DX], cpustate->regs.w[SP], cpustate->regs.w[BP], cpustate->regs.w[SI], cpustate->regs.w[DI], - cpustate->sregs[DS], cpustate->sregs[ES], cpustate->sregs[SS], cpustate->sregs[CS], cpustate->pc - cpustate->base[CS], - OF ? _T('O') : _T('-'), DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), - SF ? _T('S') : _T('-'), ZF ? _T('Z') : _T('-'), AF ? _T('A') : _T('-'), PF ? _T('P') : _T('-'), CF ? _T('C') : _T('-'), - cpustate->total_icount, cpustate->total_icount - cpustate->prev_total_icount, - get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); - cpustate->prev_total_icount = cpustate->total_icount; - return true; -} - -int I286::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) -{ - cpu_state *cpustate = (cpu_state *)opaque; - UINT64 eip = pc - cpustate->base[CS]; - UINT8 ops[16]; - for(int i = 0; i < 16; i++) { - int wait; - ops[i] = d_mem->read_data8w(pc + i, &wait); - } - UINT8 *oprom = ops; - -#ifdef HAS_V30 - return CPU_DISASSEMBLE_CALL(nec_generic) & DASMFLAG_LENGTHMASK; -#else - return CPU_DISASSEMBLE_CALL(x86_16) & DASMFLAG_LENGTHMASK; -#endif -} -#endif - -#ifdef HAS_I286 -void I286::set_address_mask(uint32_t mask) -{ - cpu_state *cpustate = (cpu_state *)opaque; - cpustate->amask = mask; -} - -uint32_t I286::get_address_mask() -{ - cpu_state *cpustate = (cpu_state *)opaque; - return cpustate->amask; -} - -void I286::set_shutdown_flag(int shutdown) -{ - cpu_state *cpustate = (cpu_state *)opaque; - cpustate->shutdown = shutdown; -} - -int I286::get_shutdown_flag() -{ - cpu_state *cpustate = (cpu_state *)opaque; - return cpustate->shutdown; -} -#endif - -#define STATE_VERSION 8 - -bool I286::process_state(FILEIO* state_fio, bool loading) -{ - cpu_state *cpustate = (cpu_state *)opaque; - - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - state_fio->StateArray(cpustate->regs.w, sizeof(cpustate->regs.w), 1); - state_fio->StateValue(cpustate->pc); - state_fio->StateValue(cpustate->prevpc); - state_fio->StateArray(cpustate->base, sizeof(cpustate->base), 1); - state_fio->StateArray(cpustate->sregs, sizeof(cpustate->sregs), 1); - state_fio->StateValue(cpustate->flags); - state_fio->StateValue(cpustate->AuxVal); - state_fio->StateValue(cpustate->OverVal); - state_fio->StateValue(cpustate->SignVal); - state_fio->StateValue(cpustate->ZeroVal); - state_fio->StateValue(cpustate->CarryVal); - state_fio->StateValue(cpustate->DirVal); - state_fio->StateValue(cpustate->ParityVal); - state_fio->StateValue(cpustate->TF); - state_fio->StateValue(cpustate->IF); - state_fio->StateValue(cpustate->MF); - state_fio->StateValue(cpustate->int_vector); - state_fio->StateValue(cpustate->nmi_state); - state_fio->StateValue(cpustate->irq_state); - state_fio->StateValue(cpustate->test_state); - state_fio->StateValue(cpustate->rep_in_progress); - state_fio->StateValue(cpustate->extra_cycles); - state_fio->StateValue(cpustate->halted); - state_fio->StateValue(cpustate->busreq); - state_fio->StateValue(cpustate->haltreq); - state_fio->StateValue(cpustate->ip); - state_fio->StateValue(cpustate->sp); -//#ifdef USE_DEBUGGER - state_fio->StateValue(cpustate->total_icount); -//#endif - state_fio->StateValue(cpustate->icount); - state_fio->StateValue(cpustate->seg_prefix); - state_fio->StateValue(cpustate->prefix_seg); - state_fio->StateValue(cpustate->ea); - state_fio->StateValue(cpustate->eo); - state_fio->StateValue(cpustate->ea_seg); - state_fio->StateValue(cpustate->waitfactor); - state_fio->StateValue(cpustate->waitcount); - state_fio->StateValue(cpustate->memory_wait); - -//#ifdef USE_DEBUGGER - // post process - if(loading) { - cpustate->prev_total_icount = cpustate->total_icount; - } -//#endif - return true; -} - -} diff --git a/source/src/vm/jx/i286.h b/source/src/vm/jx/i286.h deleted file mode 100644 index 10efb74a8..000000000 --- a/source/src/vm/jx/i286.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - Skelton for retropc emulator - - Author : Takeda.Toshiya - Date : 2012.10.18- - - [ i286 ] -*/ - -#ifndef _I286_H_ -#define _I286_H_ - -#include "../vm.h" -#include "../../emu.h" -#include "../device.h" - -#define SIG_I86_TEST 0 -#define SIG_I286_A20 1 - -#ifdef USE_DEBUGGER -class DEBUGGER; -#endif - -namespace JX { - -class I286 : public DEVICE -{ -private: - DEVICE *d_mem, *d_io, *d_pic; -#ifdef I86_PSEUDO_BIOS - DEVICE *d_bios; -#endif -#ifdef SINGLE_MODE_DMA - DEVICE *d_dma; -#endif -#ifdef USE_DEBUGGER - DEBUGGER *d_debugger; -#endif - void *opaque; - -public: - I286(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) - { -#ifdef I86_PSEUDO_BIOS - d_bios = NULL; -#endif -#ifdef SINGLE_MODE_DMA - d_dma = NULL; -#endif -#ifdef USE_DEBUGGER - d_debugger = NULL; -#endif -#if defined(HAS_I86) - set_device_name(_T("8086 CPU")); -#elif defined(HAS_I88) - set_device_name(_T("8088 CPU")); -#elif defined(HAS_I186) - set_device_name(_T("80186 CPU")); -#elif defined(HAS_V30) - set_device_name(_T("V30 CPU")); -#elif defined(HAS_I286) - set_device_name(_T("80286 CPU")); -#endif - } - ~I286() {} - - // common functions - void initialize(); - void release(); - void reset(); - int __FASTCALL run(int icount); - uint32_t __FASTCALL read_signal(int id); - void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void set_intr_line(bool line, bool pending, uint32_t bit); - void set_extra_clock(int icount); - int get_extra_clock(); - uint32_t get_pc(); - uint32_t get_next_pc(); - uint32_t __FASTCALL translate_address(int segment, uint32_t offset); -#ifdef USE_DEBUGGER - bool is_cpu() - { - return true; - } - bool is_debugger_available() - { - return true; - } - void *get_debugger() - { - return d_debugger; - } - uint32_t get_debug_prog_addr_mask() - { -#ifdef HAS_I286 - return 0xffffff; -#else - return 0xfffff; -#endif - } - uint32_t get_debug_data_addr_mask() - { -#ifdef HAS_I286 - return 0xffffff; -#else - return 0xfffff; -#endif - } - void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_data8(uint32_t addr); - void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_data16(uint32_t addr); - void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_io8(uint32_t addr); - void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_io16(uint32_t addr); - bool write_debug_reg(const _TCHAR *reg, uint32_t data); - bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); - int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); - -#endif - bool process_state(FILEIO* state_fio, bool loading); - - // unique function - void set_context_mem(DEVICE* device) - { - d_mem = device; - } - void set_context_io(DEVICE* device) - { - d_io = device; - } - void set_context_intr(DEVICE* device) - { - d_pic = device; - } -#ifdef I86_PSEUDO_BIOS - void set_context_bios(DEVICE* device) - { - d_bios = device; - } -#endif -#ifdef SINGLE_MODE_DMA - void set_context_dma(DEVICE* device) - { - d_dma = device; - } -#endif -#ifdef USE_DEBUGGER - void set_context_debugger(DEBUGGER* device) - { - d_debugger = device; - } -#endif -#ifdef HAS_I286 - void set_address_mask(uint32_t mask); - uint32_t get_address_mask(); - void set_shutdown_flag(int shutdown); - int get_shutdown_flag(); -#endif -}; - -} -#endif diff --git a/source/src/vm/jx/i86.cpp b/source/src/vm/jx/i86.cpp new file mode 100644 index 000000000..2df255a3e --- /dev/null +++ b/source/src/vm/jx/i86.cpp @@ -0,0 +1,489 @@ +/* + Skelton for retropc emulator + + Origin : MAME i286 core + Author : Takeda.Toshiya + Date : 2012.10.18- + + [ i86 ] +*/ + +#include "./i86.h" +#ifdef USE_DEBUGGER +#include "../debugger.h" +#include "../i386_dasm.h" +//#include "../v30_dasm.h" +#endif +namespace JX { +/* ---------------------------------------------------------------------------- + MAME i286 +---------------------------------------------------------------------------- */ + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning( disable : 4018 ) +#pragma warning( disable : 4146 ) +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4996 ) +#endif + +#ifndef __BIG_ENDIAN__ +#define LSB_FIRST +#endif + +#ifndef INLINE +#define INLINE inline +#endif + +#define logerror(...) + +/*****************************************************************************/ +/* src/emu/devcpu.h */ + +// CPU interface functions +#define CPU_INIT_NAME(name) cpu_init_##name +#define CPU_INIT(name) void* CPU_INIT_NAME(name)() +#define CPU_INIT_CALL(name) CPU_INIT_NAME(name)() + +#define CPU_RESET_NAME(name) cpu_reset_##name +#define CPU_RESET(name) void CPU_RESET_NAME(name)(cpu_state *cpustate) +#define CPU_RESET_CALL(name) CPU_RESET_NAME(name)(cpustate) + +#define CPU_EXECUTE_NAME(name) cpu_execute_##name +#define CPU_EXECUTE(name) int CPU_EXECUTE_NAME(name)(cpu_state *cpustate, int icount) +#define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(cpustate, icount) + +/*****************************************************************************/ +/* src/emu/diexec.h */ + +// I/O line states +enum line_state +{ + CLEAR_LINE = 0, // clear (a fired or held) line + ASSERT_LINE, // assert an interrupt immediately + HOLD_LINE, // hold interrupt line until acknowledged + PULSE_LINE // pulse interrupt line instantaneously (only for NMI, RESET) +}; + +enum +{ + INPUT_LINE_IRQ = 0, + INPUT_LINE_NMI +}; + +/*****************************************************************************/ +/* src/emu/emucore.h */ + +// constants for expression endianness +enum endianness_t +{ + ENDIANNESS_LITTLE, + ENDIANNESS_BIG +}; + +// declare native endianness to be one or the other +#ifdef LSB_FIRST +const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE; +#else +const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG; +#endif +// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian +#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval)) +// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian +#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval) +// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native +#define ENDIAN_VALUE_NE_NNE(endian,leval,beval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval)) + +/*****************************************************************************/ +/* src/emu/memory.h */ + +// offsets and addresses are 32-bit (for now...) +typedef UINT32 offs_t; + +#define cpu_state i8086_state +#include "../mame/emu/cpu/i86/i86.c" + +void I86::initialize() +{ +// switch(device_model) { +// case INTEL_8086: +// opaque = CPU_INIT_CALL(i8086); +// set_device_name(_T("8086 CPU")); +// break; +// case INTEL_8088: + opaque = CPU_INIT_CALL(i8088); + set_device_name(_T("8088 CPU")); +// break; +// case INTEL_80186: +// opaque = CPU_INIT_CALL(i80186); +// set_device_name(_T("80186 CPU")); +// break; +// case NEC_V30: +// opaque = CPU_INIT_CALL(v30); +// set_device_name(_T("V30 CPU")); +// break; +// } + cpu_state *cpustate = (cpu_state *)opaque; + cpustate->pic = d_pic; + cpustate->program = d_mem; + cpustate->io = d_io; +#ifdef I86_PSEUDO_BIOS + cpustate->bios = d_bios; +#endif +#ifdef SINGLE_MODE_DMA + cpustate->dma = d_dma; +#endif +#ifdef USE_DEBUGGER + cpustate->emu = emu; + cpustate->debugger = d_debugger; + cpustate->program_stored = d_mem; + cpustate->io_stored = d_io; + + d_debugger->set_context_mem(d_mem); + d_debugger->set_context_io(d_io); +#endif +} + +void I86::release() +{ + free(opaque); +} + +void I86::reset() +{ + cpu_state *cpustate = (cpu_state *)opaque; + int busreq = cpustate->busreq; + +// switch(device_model) { +// case INTEL_8086: +// CPU_RESET_CALL(i8086); +// break; +// case INTEL_8088: + CPU_RESET_CALL(i8088); +// break; +// case INTEL_80186: +// CPU_RESET_CALL(i80186); +// break; +// case NEC_V30: +// CPU_RESET_CALL(v30); +// break; +// } + cpustate->pic = d_pic; + cpustate->program = d_mem; + cpustate->io = d_io; +#ifdef I86_PSEUDO_BIOS + cpustate->bios = d_bios; +#endif +#ifdef SINGLE_MODE_DMA + cpustate->dma = d_dma; +#endif +#ifdef USE_DEBUGGER + cpustate->emu = emu; + cpustate->debugger = d_debugger; + cpustate->program_stored = d_mem; + cpustate->io_stored = d_io; +#endif + cpustate->busreq = busreq; +} + +int I86::run(int icount) +{ + cpu_state *cpustate = (cpu_state *)opaque; +#ifdef _JX + // ugly patch for PC/JX hardware diagnostics :-( +#ifdef TIMER_HACK + if(cpustate->pc == 0xff040) cpustate->pc = 0xff04a; + if(cpustate->pc == 0xff17d) cpustate->pc = 0xff18f; +#endif +#ifdef KEYBOARD_HACK + if(cpustate->pc == 0xfa909) { cpustate->regs.b[BH] = read_port_byte(cpustate, 0xa1); cpustate->pc = 0xfa97c; } + if(cpustate->pc == 0xff6e1) { cpustate->regs.b[AL] = 0x0d; cpustate->pc += 2; } +#endif +#endif +// switch(device_model) { +// case INTEL_8086: +// return CPU_EXECUTE_CALL(i8086); +// case INTEL_8088: + return CPU_EXECUTE_CALL(i8088); +// case INTEL_80186: +// return CPU_EXECUTE_CALL(i80186); +// case NEC_V30: +// return CPU_EXECUTE_CALL(v30); +// } +// return 0; +} + +void I86::write_signal(int id, uint32_t data, uint32_t mask) +{ + cpu_state *cpustate = (cpu_state *)opaque; + + if(id == SIG_CPU_NMI) { + set_irq_line(cpustate, INPUT_LINE_NMI, (data & mask) ? HOLD_LINE : CLEAR_LINE); + } else if(id == SIG_CPU_IRQ) { + set_irq_line(cpustate, INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE); + } else if(id == SIG_CPU_BUSREQ) { + cpustate->busreq = (data & mask) ? 1 : 0; + } else if(id == SIG_I86_TEST) { + cpustate->test_state = (data & mask) ? 1 : 0; + } +} + +void I86::set_intr_line(bool line, bool pending, uint32_t bit) +{ + cpu_state *cpustate = (cpu_state *)opaque; + set_irq_line(cpustate, INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE); +} + +void I86::set_extra_clock(int icount) +{ + cpu_state *cpustate = (cpu_state *)opaque; + cpustate->extra_cycles += icount; +} + +int I86::get_extra_clock() +{ + cpu_state *cpustate = (cpu_state *)opaque; + return cpustate->extra_cycles; +} + +uint32_t I86::get_pc() +{ + cpu_state *cpustate = (cpu_state *)opaque; + return cpustate->prevpc; +} + +uint32_t I86::get_next_pc() +{ + cpu_state *cpustate = (cpu_state *)opaque; + return cpustate->pc; +} + +#ifdef USE_DEBUGGER +void I86::write_debug_data8(uint32_t addr, uint32_t data) +{ + int wait; + d_mem->write_data8w(addr, data, &wait); +} + +uint32_t I86::read_debug_data8(uint32_t addr) +{ + int wait; + return d_mem->read_data8w(addr, &wait); +} + +void I86::write_debug_data16(uint32_t addr, uint32_t data) +{ + int wait; + d_mem->write_data16w(addr, data, &wait); +} + +uint32_t I86::read_debug_data16(uint32_t addr) +{ + int wait; + return d_mem->read_data16w(addr, &wait); +} + +void I86::write_debug_io8(uint32_t addr, uint32_t data) +{ + int wait; + d_io->write_io8w(addr, data, &wait); +} + +uint32_t I86::read_debug_io8(uint32_t addr) +{ + int wait; + return d_io->read_io8w(addr, &wait); +} + +void I86::write_debug_io16(uint32_t addr, uint32_t data) +{ + int wait; + d_io->write_io16w(addr, data, &wait); +} + +uint32_t I86::read_debug_io16(uint32_t addr) +{ + int wait; + return d_io->read_io16w(addr, &wait); +} + +bool I86::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + cpu_state *cpustate = (cpu_state *)opaque; + if(_tcsicmp(reg, _T("IP")) == 0) { + cpustate->pc = ((data & 0xffff) + cpustate->base[CS]) & AMASK; + CHANGE_PC(cpustate->pc); + } else if(_tcsicmp(reg, _T("AX")) == 0) { + cpustate->regs.w[AX] = data; + } else if(_tcsicmp(reg, _T("BX")) == 0) { + cpustate->regs.w[BX] = data; + } else if(_tcsicmp(reg, _T("CX")) == 0) { + cpustate->regs.w[CX] = data; + } else if(_tcsicmp(reg, _T("DX")) == 0) { + cpustate->regs.w[DX] = data; + } else if(_tcsicmp(reg, _T("SP")) == 0) { + cpustate->regs.w[SP] = data; + } else if(_tcsicmp(reg, _T("BP")) == 0) { + cpustate->regs.w[BP] = data; + } else if(_tcsicmp(reg, _T("SI")) == 0) { + cpustate->regs.w[SI] = data; + } else if(_tcsicmp(reg, _T("DI")) == 0) { + cpustate->regs.w[DI] = data; + } else if(_tcsicmp(reg, _T("AL")) == 0) { + cpustate->regs.b[AL] = data; + } else if(_tcsicmp(reg, _T("AH")) == 0) { + cpustate->regs.b[AH] = data; + } else if(_tcsicmp(reg, _T("BL")) == 0) { + cpustate->regs.b[BL] = data; + } else if(_tcsicmp(reg, _T("BH")) == 0) { + cpustate->regs.b[BH] = data; + } else if(_tcsicmp(reg, _T("CL")) == 0) { + cpustate->regs.b[CL] = data; + } else if(_tcsicmp(reg, _T("CH")) == 0) { + cpustate->regs.b[CH] = data; + } else if(_tcsicmp(reg, _T("DL")) == 0) { + cpustate->regs.b[DL] = data; + } else if(_tcsicmp(reg, _T("DH")) == 0) { + cpustate->regs.b[DH] = data; + } else { + return false; + } + return true; +} + +uint32_t I86::read_debug_reg(const _TCHAR *reg) +{ + cpu_state *cpustate = (cpu_state *)opaque; + if(_tcsicmp(reg, _T("IP")) == 0) { + return cpustate->pc - cpustate->base[CS]; + } else if(_tcsicmp(reg, _T("AX")) == 0) { + return cpustate->regs.w[AX]; + } else if(_tcsicmp(reg, _T("BX")) == 0) { + return cpustate->regs.w[BX]; + } else if(_tcsicmp(reg, _T("CX")) == 0) { + return cpustate->regs.w[CX]; + } else if(_tcsicmp(reg, _T("DX")) == 0) { + return cpustate->regs.w[DX]; + } else if(_tcsicmp(reg, _T("SP")) == 0) { + return cpustate->regs.w[SP]; + } else if(_tcsicmp(reg, _T("BP")) == 0) { + return cpustate->regs.w[BP]; + } else if(_tcsicmp(reg, _T("SI")) == 0) { + return cpustate->regs.w[SI]; + } else if(_tcsicmp(reg, _T("DI")) == 0) { + return cpustate->regs.w[DI]; + } else if(_tcsicmp(reg, _T("AL")) == 0) { + return cpustate->regs.b[AL]; + } else if(_tcsicmp(reg, _T("AH")) == 0) { + return cpustate->regs.b[AH]; + } else if(_tcsicmp(reg, _T("BL")) == 0) { + return cpustate->regs.b[BL]; + } else if(_tcsicmp(reg, _T("BH")) == 0) { + return cpustate->regs.b[BH]; + } else if(_tcsicmp(reg, _T("CL")) == 0) { + return cpustate->regs.b[CL]; + } else if(_tcsicmp(reg, _T("CH")) == 0) { + return cpustate->regs.b[CH]; + } else if(_tcsicmp(reg, _T("DL")) == 0) { + return cpustate->regs.b[DL]; + } else if(_tcsicmp(reg, _T("DH")) == 0) { + return cpustate->regs.b[DH]; + } + return 0; +} + +bool I86::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ + cpu_state *cpustate = (cpu_state *)opaque; + my_stprintf_s(buffer, buffer_len, + _T("AX=%04X BX=%04X CX=%04X DX=%04X SP=%04X BP=%04X SI=%04X DI=%04X\n") + _T("DS=%04X ES=%04X SS=%04X CS=%04X IP=%04X FLAG=[%c%c%c%c%c%c%c%c%c]\n") + _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), + cpustate->regs.w[AX], cpustate->regs.w[BX], cpustate->regs.w[CX], cpustate->regs.w[DX], cpustate->regs.w[SP], cpustate->regs.w[BP], cpustate->regs.w[SI], cpustate->regs.w[DI], + cpustate->sregs[DS], cpustate->sregs[ES], cpustate->sregs[SS], cpustate->sregs[CS], cpustate->pc - cpustate->base[CS], + OF ? _T('O') : _T('-'), DF ? _T('D') : _T('-'), cpustate->IF ? _T('I') : _T('-'), cpustate->TF ? _T('T') : _T('-'), + SF ? _T('S') : _T('-'), ZF ? _T('Z') : _T('-'), AF ? _T('A') : _T('-'), PF ? _T('P') : _T('-'), CF ? _T('C') : _T('-'), + cpustate->total_icount, cpustate->total_icount - cpustate->prev_total_icount, + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + cpustate->prev_total_icount = cpustate->total_icount; + return true; +} + +int I86::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) +{ + cpu_state *cpustate = (cpu_state *)opaque; + uint32_t eip = pc - cpustate->base[CS]; + uint8_t oprom[16]; + + for(int i = 0; i < 16; i++) { + int wait; + oprom[i] = d_mem->read_data8w((pc + i) & AMASK, &wait); + } +// switch(device_model) { +// case NEC_V30: +// return v30_dasm(cpustate->debugger, oprom, eip, (cpustate->MF == 0), buffer, buffer_len); +// default: + return i386_dasm(oprom, eip, false, buffer, buffer_len); +// } +} +#endif + +#define STATE_VERSION 1 + +bool I86::process_state(FILEIO* state_fio, bool loading) +{ + cpu_state *cpustate = (cpu_state *)opaque; + + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateArray(cpustate->regs.w, sizeof(cpustate->regs.w), 1); + state_fio->StateValue(cpustate->pc); + state_fio->StateValue(cpustate->prevpc); + state_fio->StateArray(cpustate->base, sizeof(cpustate->base), 1); + state_fio->StateArray(cpustate->sregs, sizeof(cpustate->sregs), 1); + state_fio->StateValue(cpustate->flags); + state_fio->StateValue(cpustate->AuxVal); + state_fio->StateValue(cpustate->OverVal); + state_fio->StateValue(cpustate->SignVal); + state_fio->StateValue(cpustate->ZeroVal); + state_fio->StateValue(cpustate->CarryVal); + state_fio->StateValue(cpustate->DirVal); + state_fio->StateValue(cpustate->ParityVal); + state_fio->StateValue(cpustate->TF); + state_fio->StateValue(cpustate->IF); + state_fio->StateValue(cpustate->MF); + state_fio->StateValue(cpustate->MF_WriteDisabled); + state_fio->StateValue(cpustate->NF); + state_fio->StateValue(cpustate->int_vector); + state_fio->StateValue(cpustate->nmi_state); + state_fio->StateValue(cpustate->irq_state); + state_fio->StateValue(cpustate->test_state); + state_fio->StateValue(cpustate->rep_in_progress); + state_fio->StateValue(cpustate->extra_cycles); + state_fio->StateValue(cpustate->halted); + state_fio->StateValue(cpustate->busreq); + state_fio->StateValue(cpustate->ip); + state_fio->StateValue(cpustate->sp); +#ifdef USE_DEBUGGER + state_fio->StateValue(cpustate->total_icount); +#endif + state_fio->StateValue(cpustate->icount); + state_fio->StateValue(cpustate->seg_prefix); + state_fio->StateValue(cpustate->prefix_seg); + state_fio->StateValue(cpustate->ea); + state_fio->StateValue(cpustate->eo); + state_fio->StateValue(cpustate->ea_seg); + +#ifdef USE_DEBUGGER + // post process + if(loading) { + cpustate->prev_total_icount = cpustate->total_icount; + } +#endif + return true; +} + +} diff --git a/source/src/vm/jx/i86.h b/source/src/vm/jx/i86.h new file mode 100644 index 000000000..4f973db9e --- /dev/null +++ b/source/src/vm/jx/i86.h @@ -0,0 +1,140 @@ +/* + Skelton for retropc emulator + + Origin : MAME i286 core + Author : Takeda.Toshiya + Date : 2012.10.18- + + [ i86 ] +*/ + +#ifndef _I86_H_ +#define _I86_H_ + +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" + +#define SIG_I86_TEST 0 + +#ifdef USE_DEBUGGER +class DEBUGGER; +#endif + +namespace JX { +//enum { +// INTEL_8086 = 0, +// INTEL_8088, +// INTEL_80186, +// NEC_V30, +//}; + +class I86 : public DEVICE +{ +private: + DEVICE *d_mem, *d_io, *d_pic; +#ifdef I86_PSEUDO_BIOS + DEVICE *d_bios; +#endif +#ifdef SINGLE_MODE_DMA + DEVICE *d_dma; +#endif +#ifdef USE_DEBUGGER + DEBUGGER *d_debugger; +#endif + void *opaque; + +public: + I86(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { +#ifdef I86_PSEUDO_BIOS + d_bios = NULL; +#endif +#ifdef SINGLE_MODE_DMA + d_dma = NULL; +#endif + } + ~I86() {} + + // common functions + void initialize(); + void release(); + void reset(); + int __FASTCALL run(int icount); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); + void __FASTCALL set_extra_clock(int icount); + int get_extra_clock(); + uint32_t get_pc(); + uint32_t get_next_pc(); +#ifdef USE_DEBUGGER + bool is_cpu() + { + return true; + } + bool is_debugger_available() + { + return true; + } + void *get_debugger() + { + return d_debugger; + } + uint32_t get_debug_prog_addr_mask() + { + return 0xfffff; + } + uint32_t get_debug_data_addr_mask() + { + return 0xfffff; + } + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data16(uint32_t addr); + void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io8(uint32_t addr); + void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io16(uint32_t addr); + bool write_debug_reg(const _TCHAR *reg, uint32_t data); + uint32_t __FASTCALL read_debug_reg(const _TCHAR *reg); + bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len); +#endif + bool process_state(FILEIO* state_fio, bool loading); + + // unique function + void set_context_mem(DEVICE* device) + { + d_mem = device; + } + void set_context_io(DEVICE* device) + { + d_io = device; + } + void set_context_intr(DEVICE* device, uint32_t bit = 0xfffffffff) + { + d_pic = device; + } +#ifdef I86_PSEUDO_BIOS + void set_context_bios(DEVICE* device) + { + d_bios = device; + } +#endif +#ifdef SINGLE_MODE_DMA + void set_context_dma(DEVICE* device) + { + d_dma = device; + } +#endif +#ifdef USE_DEBUGGER + void set_context_debugger(DEBUGGER* device) + { + d_debugger = device; + } +#endif +// int device_model; +}; +} +#endif diff --git a/source/src/vm/jx/jx.cpp b/source/src/vm/jx/jx.cpp index 156fb6d6c..afe25b1c4 100644 --- a/source/src/vm/jx/jx.cpp +++ b/source/src/vm/jx/jx.cpp @@ -18,8 +18,7 @@ #include "../i8253.h" #include "../i8255.h" #include "../i8259.h" -//#include "../i286.h" -#include "./i286.h" +#include "./i86.h" #include "../io.h" #include "../memory.h" #include "../noise.h" @@ -36,7 +35,7 @@ #include "keyboard.h" #include "speaker.h" -using JX::I286; +using JX::I86; using JX::DISPLAY; using JX::FLOPPY; using JX::KEYBOARD; @@ -45,7 +44,7 @@ using JX::SPEAKER; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -58,9 +57,11 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pit = new I8253(this, emu); pio = new I8255(this, emu); pic = new I8259(this, emu); - cpu = new I286(this, emu); // 8088 + cpu = new I86(this, emu); +// cpu->device_model = INTEL_8088; io = new IO(this, emu); mem = new MEMORY(this, emu); + pcm = new PCM1BIT(this, emu); psg = new SN76489AN(this, emu); // SN76496N fdc = new UPD765A(this, emu); @@ -355,7 +356,19 @@ void VM::update_config() } } -#define STATE_VERSION 1 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -367,7 +380,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/jx/jx.h b/source/src/vm/jx/jx.h index d5cd353af..37a0749ea 100644 --- a/source/src/vm/jx/jx.h +++ b/source/src/vm/jx/jx.h @@ -26,7 +26,6 @@ #define WINDOW_HEIGHT_ASPECT 480 #define MAX_DRIVE 2 #define UPD765A_SENCE_INTSTAT_RESULT -#define HAS_I86 #define I8259_MAX_CHIPS 1 #define MEMORY_ADDR_MAX 0x100000 #define MEMORY_BANK_SIZE 0x4000 @@ -73,7 +72,7 @@ class SN76489AN; class UPD765A; namespace JX { - class I286; + class I86; class DISPLAY; class FLOPPY; class KEYBOARD; @@ -92,7 +91,7 @@ class VM : public VM_TEMPLATE I8253* pit; I8255* pio; I8259* pic; - JX::I286* cpu; + JX::I86* cpu; IO* io; MEMORY* mem; PCM1BIT* pcm; @@ -115,7 +114,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -156,6 +155,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/jx/keyboard.h b/source/src/vm/jx/keyboard.h index 9c035b544..2bf00dc63 100644 --- a/source/src/vm/jx/keyboard.h +++ b/source/src/vm/jx/keyboard.h @@ -35,7 +35,7 @@ class KEYBOARD : public DEVICE uint8_t nmi_reg; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } @@ -47,7 +47,7 @@ class KEYBOARD : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/jx/speaker.h b/source/src/vm/jx/speaker.h index ba79d01fe..8cbd59bae 100644 --- a/source/src/vm/jx/speaker.h +++ b/source/src/vm/jx/speaker.h @@ -24,7 +24,7 @@ class SPEAKER : public DEVICE DEVICE *d_pcm, *d_psg; public: - SPEAKER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SPEAKER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Speaker")); } diff --git a/source/src/vm/ld700.h b/source/src/vm/ld700.h index 83ef83012..85bfc1d0c 100644 --- a/source/src/vm/ld700.h +++ b/source/src/vm/ld700.h @@ -10,8 +10,6 @@ #ifndef _LD700_H_ #define _LD700_H_ -#include "vm.h" -#include "../emu.h" #include "device.h" #define SIG_LD700_REMOTE 0 @@ -62,7 +60,7 @@ class LD700 : public DEVICE void set_cur_track(int track); public: - LD700(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + LD700(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_exv); initialize_output_signals(&outputs_ack); @@ -79,8 +77,8 @@ class LD700 : public DEVICE void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int id); void event_frame(); - void event_callback(int event_id, int err); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int event_id, int err); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); // unique functions diff --git a/source/src/vm/libcpu_newdev/address_spacenum.h b/source/src/vm/libcpu_newdev/address_spacenum.h deleted file mode 100644 index 3d933c205..000000000 --- a/source/src/vm/libcpu_newdev/address_spacenum.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - - -enum address_spacenum -{ - AS_0, // first address space - AS_1, // second address space - AS_2, // third address space - AS_3, // fourth address space - ADDRESS_SPACES, // maximum number of address spaces - - // alternate address space names for common use - AS_PROGRAM = AS_0, // program address space - AS_DATA = AS_1, // data address space - AS_IO = AS_2 // I/O address space -}; diff --git a/source/src/vm/libcpu_newdev/device.cpp b/source/src/vm/libcpu_newdev/device.cpp index 321d1871d..cbecfbc1e 100644 --- a/source/src/vm/libcpu_newdev/device.cpp +++ b/source/src/vm/libcpu_newdev/device.cpp @@ -9,14 +9,14 @@ #include "common.h" #include "../vm.h" -#include "../..//emu.h" +#include "../../emu.h" #include "device.h" #if defined(_USE_QT) #include "../qt/gui/csp_logger.h" extern DLL_PREFIX_I CSP_Logger *csp_logger; #endif -DEVICE::DEVICE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : vm(parent_vm), emu(parent_emu) +DEVICE::DEVICE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : vm(parent_vm), emu(parent_emu) { vm = parent_vm; emu = parent_emu; @@ -171,6 +171,15 @@ int DEVICE::get_event_manager_id() } return event_manager->this_device_id; } + +uint32_t DEVICE::get_event_clocks() +{ + if(event_manager == NULL) { + event_manager = vm->first_device->next_device; + } + return event_manager->get_event_clocks(); +} + bool DEVICE::is_primary_cpu(DEVICE* device) { if(event_manager == NULL) { @@ -178,6 +187,14 @@ bool DEVICE::is_primary_cpu(DEVICE* device) } return event_manager->is_primary_cpu(device); } + +uint32_t DEVICE::get_cpu_clocks(DEVICE* device) +{ + if(event_manager == NULL) { + event_manager = vm->first_device->next_device; + } + return event_manager->get_cpu_clocks(device); +} void DEVICE::update_extra_event(int clock) { if(event_manager == NULL) { @@ -185,6 +202,7 @@ void DEVICE::update_extra_event(int clock) } event_manager->update_extra_event(clock); } + void DEVICE::register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id) { if(event_manager == NULL) { @@ -201,6 +219,41 @@ void DEVICE::register_event_by_clock(DEVICE* device, int event_id, uint64_t cloc event_manager->register_event_by_clock(device, event_id, clock, loop, register_id); } +// Clear and DE-Register EVENT at slot evid. +void DEVICE::clear_event(DEVICE* dev, int& evid) +{ + if(evid > -1) { + cancel_event(dev, evid); + } + evid = -1; +} + +// Register a EVENT to evid (and update evid) , even if evid's slot is used. +void DEVICE::force_register_event(DEVICE* dev, int event_num, double usec, bool loop, int& evid) +{ + clear_event(dev, evid); + register_event(dev, event_num, usec, loop, &evid); +} + +void DEVICE::force_register_event_by_clock(DEVICE* dev, int event_num, uint64_t clock, bool loop, int& evid) +{ + clear_event(dev, evid); + register_event_by_clock(dev, event_num, clock, loop, &evid); +} + +// Register a EVENT to evid , if evid slot isn't used. +void DEVICE::check_and_update_event(DEVICE* dev, int event_num, double usec, bool loop, int& evid) +{ + if(evid > -1) return; + register_event(dev, event_num, usec, loop, &evid); +} + +void DEVICE::check_and_update_event_by_clock(DEVICE* dev, int event_num, uint64_t clock, bool loop, int& evid) +{ + if(evid > -1) return; + register_event_by_clock(dev, event_num, clock, loop, &evid); +} + void DEVICE::cancel_event(DEVICE* device, int register_id) { if(event_manager == NULL) { @@ -412,6 +465,29 @@ void DEVICE::out_debug_log(const char *fmt, ...) #endif } +void DEVICE::out_debug_log_with_switch(bool logging, const char *fmt, ...) +{ + if(!(logging)) return; +#if defined(_USE_QT) + if(p_logger == NULL) return; + char strbuf[4096]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(strbuf, 4095, fmt, ap); + p_logger->debug_log(CSP_LOG_DEBUG, this_device_id + CSP_LOG_TYPE_VM_DEVICE_0, "%s", strbuf); + va_end(ap); +#else + char strbuf[4096]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(strbuf, 4095, fmt, ap); + emu->out_debug_log("%s", strbuf); + va_end(ap); +#endif +} + void DEVICE::force_out_debug_log(const char *fmt, ...) { char strbuf[4096]; @@ -529,6 +605,10 @@ bool DEVICE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) { return false; } +bool DEVICE::get_debug_regs_description(_TCHAR *buffer, size_t buffer_len) +{ + return false; +} int DEVICE::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) { return debug_dasm_with_userdata(pc, buffer, buffer_len, 0); @@ -538,6 +618,12 @@ int DEVICE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_ { return 0; } +bool DEVICE::debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata) +{ + size = 0; + return false; +} + /* These functions are used for debugging non-cpu device Insert debugger between standard read/write functions and these functions for checking breakpoints diff --git a/source/src/vm/libcpu_newdev/device.h b/source/src/vm/libcpu_newdev/device.h index 6916e1ea8..5f3a971c1 100644 --- a/source/src/vm/libcpu_newdev/device.h +++ b/source/src/vm/libcpu_newdev/device.h @@ -11,13 +11,8 @@ #define _LIBCPU_NEWDEV_DEVICE_H_ #include -#include "vm.h" -#include "../emu.h" -#if defined(_USE_QT) -#include "osd.h" - -//#define USE_DEVICE_NAME -#endif +//#include "vm_template.h" +#include "../../emu_template.h" // max devices connected to the output port #define MAX_OUTPUT 16 @@ -40,32 +35,34 @@ #define SIG_PRINTER_ACK 205 #define SIG_PRINTER_SELECT 206 -#define SIG_SCSI_DAT 301 -#define SIG_SCSI_BSY 302 -#define SIG_SCSI_CD 303 -#define SIG_SCSI_IO 304 -#define SIG_SCSI_MSG 305 -#define SIG_SCSI_REQ 306 -#define SIG_SCSI_SEL 307 -#define SIG_SCSI_ATN 308 -#define SIG_SCSI_ACK 309 -#define SIG_SCSI_RST 310 +#define SIG_SCSI_DAT 301 +#define SIG_SCSI_BSY 302 +#define SIG_SCSI_CD 303 +#define SIG_SCSI_IO 304 +#define SIG_SCSI_MSG 305 +#define SIG_SCSI_REQ 306 +#define SIG_SCSI_SEL 307 +#define SIG_SCSI_ATN 308 +#define SIG_SCSI_ACK 309 +#define SIG_SCSI_RST 310 +#define SIG_SCSI_16BIT_BUS 311 +#define SIG_SCSI_CLEAR_QUEUE 312 #include "vm_template.h" class CSP_Logger; class VM_TEMPLATE; -class EMU; +class EMU_TEMPLATE; class OSD; -class DEVICE +class DLL_PREFIX DEVICE { protected: VM_TEMPLATE* vm; - EMU* emu; - OSD* osd; + EMU_TEMPLATE* emu; + OSD_BASE* osd; CSP_Logger *p_logger; public: - DEVICE(VM_TEMPLATE* parent_vm, EMU* parent_emu); + DEVICE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~DEVICE() {} virtual void initialize() { } @@ -77,19 +74,19 @@ class DEVICE // this function may be before (or after) initialize(). virtual int release_sound_in_source(int bank); virtual bool is_sound_in_source_exists(int bank); - virtual int increment_sound_in_passed_data(int bank, double passed_usec); + virtual int __FASTCALL increment_sound_in_passed_data(int bank, double passed_usec); virtual int get_sound_in_buffers_count(); - virtual int get_sound_in_samples(int bank); - virtual int get_sound_in_rate(int bank); - virtual int get_sound_in_channels(int bank); + virtual int __FASTCALL get_sound_in_samples(int bank); + virtual int __FASTCALL get_sound_in_rate(int bank); + virtual int __FASTCALL get_sound_in_channels(int bank); // this function may be before (or after) initialize(). virtual int16_t* get_sound_in_buf_ptr(int bank); virtual int write_sound_in_buffer(int bank, int32_t* src, int samples); // Add sampled values to sample buffer;value may be -32768 to +32767. // this function may be before (or after) initialize(). - virtual int get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels); - virtual int get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels); + virtual int __FASTCALL get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels); + virtual int __FASTCALL get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels); virtual void set_high_pass_filter_freq(int freq, double quality) { } // If freq < 0 disable HPF. virtual void set_low_pass_filter_freq(int freq, double quality) { } // If freq <= 0 disable LPF. @@ -97,7 +94,7 @@ class DEVICE // control virtual void reset() {} - virtual void special_reset() + virtual void special_reset(int num) { reset(); } @@ -127,25 +124,41 @@ class DEVICE } virtual void __FASTCALL write_data16(uint32_t addr, uint32_t data) { - write_data8(addr, data & 0xff); + write_data8(addr, (data ) & 0xff); write_data8(addr + 1, (data >> 8) & 0xff); } virtual uint32_t __FASTCALL read_data16(uint32_t addr) { - uint32_t val = read_data8(addr); + uint32_t val; + val = read_data8(addr ); val |= read_data8(addr + 1) << 8; return val; } virtual void __FASTCALL write_data32(uint32_t addr, uint32_t data) { - write_data16(addr, data & 0xffff); - write_data16(addr + 2, (data >> 16) & 0xffff); + if(!(addr & 1)) { + write_data16(addr, (data ) & 0xffff); + write_data16(addr + 2, (data >> 16) & 0xffff); + } else { + write_data8 (addr, (data ) & 0x00ff); + write_data16(addr + 1, (data >> 8) & 0xffff); + write_data8 (addr + 3, (data >> 24) & 0x00ff); + } } virtual uint32_t __FASTCALL read_data32(uint32_t addr) { - uint32_t val = read_data16(addr); - val |= read_data16(addr + 2) << 16; - return val; + if(!(addr & 1)) { + uint32_t val; + val = read_data16(addr ); + val |= read_data16(addr + 2) << 16; + return val; + } else { + uint32_t val; + val = read_data8 (addr ); + val |= read_data16(addr + 1) << 8; + val |= read_data8 (addr + 3) << 24; + return val; + } } virtual void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait) { @@ -159,33 +172,53 @@ class DEVICE } virtual void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_data8w(addr, data & 0xff, &wait_l); - write_data8w(addr + 1, (data >> 8) & 0xff, &wait_h); - *wait = wait_l + wait_h; + int wait_0, wait_1; + write_data8w(addr, (data ) & 0xff, &wait_0); + write_data8w(addr + 1, (data >> 8) & 0xff, &wait_1); + *wait = wait_0 + wait_1; } virtual uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_data8w(addr, &wait_l); - val |= read_data8w(addr + 1, &wait_h) << 8; - *wait = wait_l + wait_h; + int wait_0, wait_1; + uint32_t val; + val = read_data8w(addr, &wait_0); + val |= read_data8w(addr + 1, &wait_1) << 8; + *wait = wait_0 + wait_1; return val; } virtual void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_data16w(addr, data & 0xffff, &wait_l); - write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_h); - *wait = wait_l + wait_h; + if(!(addr & 1)) { + int wait_0, wait_1; + write_data16w(addr, (data ) & 0xffff, &wait_0); + write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_1); + *wait = wait_0 + wait_1; + } else { + int wait_0, wait_1, wait_2; + write_data8w (addr, (data ) & 0x00ff, &wait_0); + write_data16w(addr + 1, (data >> 8) & 0xffff, &wait_1); + write_data8w (addr + 3, (data >> 24) & 0x00ff, &wait_2); + *wait = wait_0 + wait_1 + wait_2; + } } virtual uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_data16w(addr, &wait_l); - val |= read_data16w(addr + 2, &wait_h) << 16; - *wait = wait_l + wait_h; - return val; + if(!(addr & 1)) { + int wait_0, wait_1; + uint32_t val; + val = read_data16w(addr, &wait_0); + val |= read_data16w(addr + 2, &wait_1) << 16; + *wait = wait_0 + wait_1; + return val; + } else { + int wait_0, wait_1, wait_2; + uint32_t val; + val = read_data8w (addr, &wait_0); + val |= read_data16w(addr + 1, &wait_1) << 8; + val |= read_data8w (addr + 3, &wait_2) << 24; + *wait = wait_0 + wait_1 + wait_2; + return val; + } } virtual uint32_t __FASTCALL fetch_op(uint32_t addr, int *wait) { @@ -245,25 +278,41 @@ class DEVICE virtual uint32_t __FASTCALL read_io8(uint32_t addr); virtual void __FASTCALL write_io16(uint32_t addr, uint32_t data) { - write_io8(addr, data & 0xff); + write_io8(addr, (data ) & 0xff); write_io8(addr + 1, (data >> 8) & 0xff); } virtual uint32_t __FASTCALL read_io16(uint32_t addr) { - uint32_t val = read_io8(addr); + uint32_t val; + val = read_io8(addr ); val |= read_io8(addr + 1) << 8; return val; } virtual void __FASTCALL write_io32(uint32_t addr, uint32_t data) { - write_io16(addr, data & 0xffff); - write_io16(addr + 2, (data >> 16) & 0xffff); + if(!(addr & 1)) { + write_io16(addr, (data ) & 0xffff); + write_io16(addr + 2, (data >> 16) & 0xffff); + } else { + write_io8 (addr, (data ) & 0x00ff); + write_io16(addr + 1, (data >> 8) & 0xffff); + write_io8 (addr + 3, (data >> 24) & 0x00ff); + } } virtual uint32_t __FASTCALL read_io32(uint32_t addr) { - uint32_t val = read_io16(addr); - val |= read_io16(addr + 2) << 16; - return val; + if(!(addr & 1)) { + uint32_t val; + val = read_io16(addr ); + val |= read_io16(addr + 2) << 16; + return val; + } else { + uint32_t val; + val = read_io8 (addr ); + val |= read_io16(addr + 1) << 8; + val |= read_io8 (addr + 3) << 24; + return val; + } } virtual void __FASTCALL write_io8w(uint32_t addr, uint32_t data, int* wait) { @@ -277,33 +326,53 @@ class DEVICE } virtual void __FASTCALL write_io16w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_io8w(addr, data & 0xff, &wait_l); - write_io8w(addr + 1, (data >> 8) & 0xff, &wait_h); - *wait = wait_l + wait_h; + int wait_0, wait_1; + write_io8w(addr, (data ) & 0xff, &wait_0); + write_io8w(addr + 1, (data >> 8) & 0xff, &wait_1); + *wait = wait_0 + wait_1; } virtual uint32_t __FASTCALL read_io16w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_io8w(addr, &wait_l); - val |= read_io8w(addr + 1, &wait_h) << 8; - *wait = wait_l + wait_h; + int wait_0, wait_1; + uint32_t val; + val = read_io8w(addr, &wait_0); + val |= read_io8w(addr + 1, &wait_1) << 8; + *wait = wait_0 + wait_1; return val; } virtual void __FASTCALL write_io32w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_io16w(addr, data & 0xffff, &wait_l); - write_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h); - *wait = wait_l + wait_h; + if(!(addr & 1)) { + int wait_0, wait_1; + write_io16w(addr, (data ) & 0xffff, &wait_0); + write_io16w(addr + 2, (data >> 16) & 0xffff, &wait_1); + *wait = wait_0 + wait_1; + } else { + int wait_0, wait_1, wait_2; + write_io8w (addr, (data ) & 0x00ff, &wait_0); + write_io16w(addr + 1, (data >> 8) & 0xffff, &wait_1); + write_io8w (addr + 3, (data >> 24) & 0x00ff, &wait_2); + *wait = wait_0 + wait_1 + wait_2; + } } virtual uint32_t __FASTCALL read_io32w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_io16w(addr, &wait_l); - val |= read_io16w(addr + 2, &wait_h) << 16; - *wait = wait_l + wait_h; - return val; + if(!(addr & 1)) { + int wait_0, wait_1; + uint32_t val; + val = read_io16w(addr, &wait_0); + val |= read_io16w(addr + 2, &wait_1) << 16; + *wait = wait_0 + wait_1; + return val; + } else { + int wait_0, wait_1, wait_2; + uint32_t val; + val = read_io8w (addr, &wait_0); + val |= read_io16w(addr + 1, &wait_1) << 8; + val |= read_io8w (addr + 3, &wait_2) << 24; + *wait = wait_0 + wait_1 + wait_2; + return val; + } } virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data) { @@ -365,25 +434,41 @@ class DEVICE } virtual void __FASTCALL write_memory_mapped_io16(uint32_t addr, uint32_t data) { - write_memory_mapped_io8(addr, data & 0xff); + write_memory_mapped_io8(addr, (data ) & 0xff); write_memory_mapped_io8(addr + 1, (data >> 8) & 0xff); } virtual uint32_t __FASTCALL read_memory_mapped_io16(uint32_t addr) { - uint32_t val = read_memory_mapped_io8(addr); + uint32_t val; + val = read_memory_mapped_io8(addr ); val |= read_memory_mapped_io8(addr + 1) << 8; return val; } virtual void __FASTCALL write_memory_mapped_io32(uint32_t addr, uint32_t data) { - write_memory_mapped_io16(addr, data & 0xffff); - write_memory_mapped_io16(addr + 2, (data >> 16) & 0xffff); + if(!(addr & 1)) { + write_memory_mapped_io16(addr, (data ) & 0xffff); + write_memory_mapped_io16(addr + 2, (data >> 16) & 0xffff); + } else { + write_memory_mapped_io8 (addr, (data ) & 0x00ff); + write_memory_mapped_io16(addr + 1, (data >> 8) & 0xffff); + write_memory_mapped_io8 (addr + 3, (data >> 24) & 0x00ff); + } } virtual uint32_t __FASTCALL read_memory_mapped_io32(uint32_t addr) { - uint32_t val = read_memory_mapped_io16(addr); - val |= read_memory_mapped_io16(addr + 2) << 16; - return val; + if(!(addr & 1)) { + uint32_t val; + val = read_memory_mapped_io16(addr ); + val |= read_memory_mapped_io16(addr + 2) << 16; + return val; + } else { + uint32_t val; + val = read_memory_mapped_io8 (addr ); + val |= read_memory_mapped_io16(addr + 1) << 8; + val |= read_memory_mapped_io8 (addr + 3) << 24; + return val; + } } virtual void __FASTCALL write_memory_mapped_io8w(uint32_t addr, uint32_t data, int* wait) { @@ -397,33 +482,53 @@ class DEVICE } virtual void __FASTCALL write_memory_mapped_io16w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_memory_mapped_io8w(addr, data & 0xff, &wait_l); - write_memory_mapped_io8w(addr + 1, (data >> 8) & 0xff, &wait_h); - *wait = wait_l + wait_h; + int wait_0, wait_1; + write_memory_mapped_io8w(addr, (data ) & 0xff, &wait_0); + write_memory_mapped_io8w(addr + 1, (data >> 8) & 0xff, &wait_1); + *wait = wait_0 + wait_1; } virtual uint32_t __FASTCALL read_memory_mapped_io16w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_memory_mapped_io8w(addr, &wait_l); - val |= read_memory_mapped_io8w(addr + 1, &wait_h) << 8; - *wait = wait_l + wait_h; + int wait_0, wait_1; + uint32_t val; + val = read_memory_mapped_io8w(addr, &wait_0); + val |= read_memory_mapped_io8w(addr + 1, &wait_1) << 8; + *wait = wait_0 + wait_1; return val; } virtual void __FASTCALL write_memory_mapped_io32w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_memory_mapped_io16w(addr, data & 0xffff, &wait_l); - write_memory_mapped_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h); - *wait = wait_l + wait_h; + if(!(addr & 1)) { + int wait_0, wait_1; + write_memory_mapped_io16w(addr, (data ) & 0xffff, &wait_0); + write_memory_mapped_io16w(addr + 2, (data >> 16) & 0xffff, &wait_1); + *wait = wait_0 + wait_1; + } else { + int wait_0, wait_1, wait_2; + write_memory_mapped_io8w (addr, (data ) & 0x00ff, &wait_0); + write_memory_mapped_io16w(addr + 1, (data >> 8) & 0xffff, &wait_1); + write_memory_mapped_io8w (addr + 3, (data >> 24) & 0x00ff, &wait_2); + *wait = wait_0 + wait_1 + wait_2; + } } virtual uint32_t __FASTCALL read_memory_mapped_io32w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_memory_mapped_io16w(addr, &wait_l); - val |= read_memory_mapped_io16w(addr + 2, &wait_h) << 16; - *wait = wait_l + wait_h; - return val; + if(!(addr & 1)) { + int wait_0, wait_1; + uint32_t val; + val = read_memory_mapped_io16w(addr, &wait_0); + val |= read_memory_mapped_io16w(addr + 2, &wait_1) << 16; + *wait = wait_0 + wait_1; + return val; + } else { + int wait_0, wait_1, wait_2; + uint32_t val; + val = read_memory_mapped_io8w (addr, &wait_0); + val |= read_memory_mapped_io16w(addr + 1, &wait_1) << 8; + val |= read_memory_mapped_io8w (addr + 3, &wait_2) << 24; + *wait = wait_0 + wait_1 + wait_2; + return val; + } } // device to device @@ -459,6 +564,19 @@ class DEVICE items->item[c].mask = mask; items->item[c].shift = 0; } + virtual void update_signal_mask(outputs_t *items, DEVICE *device, uint32_t mask) + { + if(items == NULL) return; + int c = items->count; + if(c <= 0) return; + if(c >= MAX_OUTPUT) c = MAX_OUTPUT - 1; + // if (ARG:device == NULL) apply to all devices. + for(int i = 0; i < c; i++) { + if((device == NULL) || (device == items->item[i].device)) { + items->item[i].mask = mask; + } + } + } virtual void __FASTCALL write_signals(outputs_t *items, uint32_t data) { for(int i = 0; i < items->count; i++) { @@ -484,16 +602,17 @@ class DEVICE } // interrupt device to device - virtual void set_intr_iei(bool val) {} + virtual void __FASTCALL set_intr_iei(bool val) {} // interrupt device to cpu - virtual void set_intr_line(bool line, bool pending, uint32_t bit) {} + virtual void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit) {} // interrupt cpu to device virtual uint32_t get_intr_ack() { return 0xff; } + virtual void update_intr() {} virtual void notify_intr_reti() {} virtual void notify_intr_ei() {} @@ -506,7 +625,7 @@ class DEVICE // when clock == -1, run one opecode return (clock == -1 ? 1 : clock); } - virtual void set_extra_clock(int clock) {} + virtual void __FASTCALL set_extra_clock(int clock) {} virtual int get_extra_clock() { return 0; @@ -521,19 +640,19 @@ class DEVICE } // bios - virtual bool bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) + virtual bool bios_call_far_i86(uint32_t PC, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { return false; } - virtual bool bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) + virtual bool bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { return false; } - virtual bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) + virtual bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { return false; } - virtual bool bios_int_ia32(int intnum, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) + virtual bool bios_int_ia32(int intnum, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { return false; } @@ -545,7 +664,7 @@ class DEVICE { return (const _TCHAR *)this_device_name; } - virtual bool address_translate(int space, int intention, uint64_t &taddress); + virtual bool __FASTCALL address_translate(int space, int intention, uint64_t &taddress); // event manager DEVICE* event_manager; @@ -555,28 +674,41 @@ class DEVICE event_manager = device; } virtual int get_event_manager_id(); + virtual uint32_t get_event_clocks(); virtual bool is_primary_cpu(DEVICE* device); - virtual void update_extra_event(int clock); + virtual uint32_t __FASTCALL get_cpu_clocks(DEVICE* device); + virtual void __FASTCALL update_extra_event(int clock); virtual void register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id); virtual void register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id); virtual void cancel_event(DEVICE* device, int register_id); + + // Clear and DE-Register EVENT at slot evid. + virtual void clear_event(DEVICE* device, int& evid); + // Register a EVENT to evid (and update evid) , even if evid's slot is used. + virtual void force_register_event(DEVICE* device, int event_num, double usec, bool loop, int& evid); + virtual void force_register_event_by_clock(DEVICE* device, int event_num, uint64_t clock, bool loop, int& evid); + // Register a EVENT to evid , if evid slot isn't used. + virtual void check_and_update_event(DEVICE* device, int event_num, double usec, bool loop, int& evid); + virtual void check_and_update_event_by_clock(DEVICE* device, int event_num, uint64_t clock, bool loop, int& evid); + virtual void register_frame_event(DEVICE* device); virtual void register_vline_event(DEVICE* device); - virtual uint32_t get_event_remaining_clock(int register_id); - virtual double get_event_remaining_usec(int register_id); + virtual uint32_t __FASTCALL get_event_remaining_clock(int register_id); + virtual double __FASTCALL get_event_remaining_usec(int register_id); virtual uint32_t get_current_clock(); - virtual uint32_t get_passed_clock(uint32_t prev); - virtual double get_passed_usec(uint32_t prev); + virtual uint32_t __FASTCALL get_passed_clock(uint32_t prev); + virtual double __FASTCALL get_passed_usec(uint32_t prev); virtual uint32_t get_passed_clock_since_vline(); virtual double get_passed_usec_since_vline(); virtual int get_cur_vline(); virtual int get_cur_vline_clocks(); - virtual uint32_t get_cpu_pc(int index); + virtual uint32_t __FASTCALL get_cpu_pc(int index); virtual uint64_t get_current_clock_uint64(); - virtual uint32_t get_cpu_clock(int index); + virtual uint32_t __FASTCALL get_cpu_clock(int index); virtual void request_skip_frames(); virtual void set_frames_per_sec(double frames); + virtual void set_lines_per_frame(int lines); virtual int get_lines_per_frame(void); // Force render sound immediately when device's status has changed. @@ -596,14 +728,14 @@ class DEVICE virtual void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) {} // event callback - virtual void event_callback(int event_id, int err) {} + virtual void __FASTCALL event_callback(int event_id, int err) {} virtual void event_pre_frame() {} // this event is to update timing settings virtual void event_frame() {} virtual void event_vline(int v, int clock) {} virtual void event_hsync(int v, int h, int clock) {} // sound - virtual void mix(int32_t* buffer, int cnt) {} + virtual void __FASTCALL mix(int32_t* buffer, int cnt) {} virtual void set_volume(int ch, int decibel_l, int decibel_r) {} // +1 equals +0.5dB (same as fmgen) virtual void set_device_name(const _TCHAR *format, ...); @@ -631,8 +763,10 @@ class DEVICE virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data); virtual uint32_t __FASTCALL read_debug_reg(const _TCHAR *reg); virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len); virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len); virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); + virtual bool debug_rewind_call_trace(uint32_t pc, int &size, _TCHAR* buffer, size_t buffer_len, uint64_t userdata = 0); /* These functions are used for debugging non-cpu device Insert debugger between standard read/write functions and these functions for checking breakpoints @@ -677,6 +811,7 @@ class DEVICE virtual void __FASTCALL write_via_debugger_io32w(uint32_t addr, uint32_t data, int* wait); virtual uint32_t __FASTCALL read_via_debugger_io32w(uint32_t addr, int* wait); virtual void out_debug_log(const char *fmt, ...); + virtual void out_debug_log_with_switch(bool logging, const char *fmt, ...); virtual void force_out_debug_log(const char *fmt, ...); // misc diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86.cpp deleted file mode 100644 index 0045394a3..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86.cpp +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include "dosbox.h" - -#if (C_DYNAMIC_X86) - -#include -#include -#include -#include -#include -#include - -#if defined (WIN32) -#include -#include -#endif - -#if (C_HAVE_MPROTECT) -#include - -#include -#ifndef PAGESIZE -#define PAGESIZE 4096 -#endif -#endif /* C_HAVE_MPROTECT */ - -#include "callback.h" -#include "regs.h" -#include "mem.h" -#include "cpu.h" -#include "debug.h" -#include "paging.h" -#include "inout.h" -#include "fpu.h" - -#define CACHE_MAXSIZE (4096*3) -#define CACHE_TOTAL (1024*1024*8) -#define CACHE_PAGES (512) -#define CACHE_BLOCKS (64*1024) -#define CACHE_ALIGN (16) -#define DYN_HASH_SHIFT (4) -#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) -#define DYN_LINKS (16) - -//#define DYN_LOG 1 //Turn logging on - - -#if C_FPU -#define CPU_FPU 1 //Enable FPU escape instructions -#endif - -enum { - G_EAX,G_ECX,G_EDX,G_EBX, - G_ESP,G_EBP,G_ESI,G_EDI, - G_ES,G_CS,G_SS,G_DS,G_FS,G_GS, - G_FLAGS,G_NEWESP,G_EIP, - G_EA,G_STACK,G_CYCLES, - G_TMPB,G_TMPW,G_SHIFT, - G_EXIT, - G_MAX, -}; - -enum SingleOps { - SOP_INC,SOP_DEC, - SOP_NOT,SOP_NEG, -}; - -enum DualOps { - DOP_ADD,DOP_ADC, - DOP_SUB,DOP_SBB, - DOP_CMP,DOP_XOR, - DOP_AND,DOP_OR, - DOP_TEST, - DOP_MOV, - DOP_XCHG, -}; - -enum ShiftOps { - SHIFT_ROL,SHIFT_ROR, - SHIFT_RCL,SHIFT_RCR, - SHIFT_SHL,SHIFT_SHR, - SHIFT_SAL,SHIFT_SAR, -}; - -enum BranchTypes { - BR_O,BR_NO,BR_B,BR_NB, - BR_Z,BR_NZ,BR_BE,BR_NBE, - BR_S,BR_NS,BR_P,BR_NP, - BR_L,BR_NL,BR_LE,BR_NLE -}; - - -enum BlockReturn { - BR_Normal=0, - BR_Cycles, - BR_Link1,BR_Link2, - BR_Opcode, -#if (C_DEBUG) - BR_OpcodeFull, -#endif - BR_Iret, - BR_CallBack, - BR_SMCBlock -}; - -#define SMC_CURRENT_BLOCK 0xffff - - -#define DYNFLG_HAS16 0x1 //Would like 8-bit host reg support -#define DYNFLG_HAS8 0x2 //Would like 16-bit host reg support -#define DYNFLG_LOAD 0x4 //Load value when accessed -#define DYNFLG_SAVE 0x8 //Needs to be saved back at the end of block -#define DYNFLG_CHANGED 0x10 //Value is in a register and changed from load -#define DYNFLG_ACTIVE 0x20 //Register has an active value - -class GenReg; -class CodePageHandler; - -struct DynReg { - Bitu flags; - GenReg * genreg; - void * data; -}; - -enum DynAccess { - DA_d,DA_w, - DA_bh,DA_bl -}; - -enum ByteCombo { - BC_ll,BC_lh, - BC_hl,BC_hh, -}; - -static DynReg DynRegs[G_MAX]; -#define DREG(_WHICH_) &DynRegs[G_ ## _WHICH_ ] - -static struct { - Bitu ea,tmpb,tmpd,stack,shift,newesp; -} extra_regs; - -static void IllegalOption(const char* msg) { - E_Exit("DynCore: illegal option in %s",msg); -} - -#include "core_dyn_x86/cache.h" - -static struct { - Bitu callback; - Bit32u readdata; -} core_dyn; - -static struct { - Bit32u state[32]; - FPU_P_Reg temp,temp2; - Bit32u dh_fpu_enabled; - Bit32u state_used; - Bit32u cw,host_cw; - Bit8u temp_state[128]; -} dyn_dh_fpu; - - -#include "core_dyn_x86/risc_x86.h" - -struct DynState { - DynReg regs[G_MAX]; -}; - -static void dyn_flags_host_to_gen(void) { - gen_dop_word(DOP_MOV,true,DREG(EXIT),DREG(FLAGS)); - gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST); - gen_load_flags(DREG(EXIT)); - gen_releasereg(DREG(EXIT)); - gen_releasereg(DREG(FLAGS)); -} - -static void dyn_flags_gen_to_host(void) { - gen_save_flags(DREG(EXIT)); - gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST); - gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FMASK_TEST); - gen_dop_word(DOP_OR,true,DREG(FLAGS),DREG(EXIT)); //flags are marked for save - gen_releasereg(DREG(EXIT)); - gen_releasereg(DREG(FLAGS)); -} - -static void dyn_savestate(DynState * state) { - for (Bitu i=0;iregs[i].flags=DynRegs[i].flags; - state->regs[i].genreg=DynRegs[i].genreg; - } -} - -static void dyn_loadstate(DynState * state) { - for (Bitu i=0;iregs[i]); - } -} - -static void dyn_synchstate(DynState * state) { - for (Bitu i=0;iregs[i]); - } -} - -static void dyn_saveregister(DynReg * src_reg, DynReg * dst_reg) { - dst_reg->flags=src_reg->flags; - dst_reg->genreg=src_reg->genreg; -} - -static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) { - dst_reg->flags=src_reg->flags; - dst_reg->genreg=src_reg->genreg; - dst_reg->genreg->dynreg=dst_reg; // necessary when register has been released -} - -#include "core_dyn_x86/decoder.h" - -#if defined (_MSC_VER) -#define DH_FPU_SAVE_REINIT \ -{ \ - __asm { \ - __asm fnsave dyn_dh_fpu.state[0] \ - } \ - dyn_dh_fpu.state_used=false; \ - dyn_dh_fpu.state[0]|=0x3f; \ -} -#else -#define DH_FPU_SAVE_REINIT \ -{ \ - __asm__ volatile ( \ - "fnsave %0 \n" \ - : "=m" (dyn_dh_fpu.state[0]) \ - : \ - : "memory" \ - ); \ - dyn_dh_fpu.state_used=false; \ - dyn_dh_fpu.state[0]|=0x3f; \ -} -#endif - - -Bits CPU_Core_Dyn_X86_Run(void) { - /* Determine the linear address of CS:EIP */ -restart_core: - PhysPt ip_point=SegPhys(cs)+reg_eip; -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif -#endif - CodePageHandler * chandler=0; - if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) { - CPU_Exception(cpu.exception.which,cpu.exception.error); - goto restart_core; - } - if (!chandler) { - if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT - return CPU_Core_Normal_Run(); - } - /* Find correct Dynamic Block to run */ - CacheBlock * block=chandler->FindCacheBlock(ip_point&4095); - if (!block) { - if (!chandler->invalidation_map || (chandler->invalidation_map[ip_point&4095]<4)) { - block=CreateCacheBlock(chandler,ip_point,32); - } else { - Bitu old_cycles=CPU_Cycles; - CPU_Cycles=1; - Bits nc_retcode=CPU_Core_Normal_Run(); - if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT - if (!nc_retcode) { - CPU_Cycles=old_cycles-1; - goto restart_core; - } - CPU_CycleLeft+=old_cycles; - return nc_retcode; - } - } -run_block: - cache.block.running=0; - BlockReturn ret=gen_runcode(block->cache.start); - switch (ret) { - case BR_Iret: -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT - return debugCallback; - } -#endif -#endif - if (!GETFLAG(TF)) { - if (GETFLAG(IF) && PIC_IRQCheck) { - if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT - return CBRET_NONE; - } - goto restart_core; - } - cpudecoder=CPU_Core_Dyn_X86_Trap_Run; - if (!dyn_dh_fpu.state_used) return CBRET_NONE; - DH_FPU_SAVE_REINIT - return CBRET_NONE; - case BR_Normal: - /* Maybe check if we staying in the same page? */ -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif -#endif - goto restart_core; - case BR_Cycles: -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif -#endif - if (!dyn_dh_fpu.state_used) return CBRET_NONE; - DH_FPU_SAVE_REINIT - return CBRET_NONE; - case BR_CallBack: - if (!dyn_dh_fpu.state_used) return core_dyn.callback; - DH_FPU_SAVE_REINIT - return core_dyn.callback; - case BR_SMCBlock: -// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip); - cpu.exception.which=0; - // fallthrough, let the normal core handle the block-modifying instruction - case BR_Opcode: - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=1; - if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT - return CPU_Core_Normal_Run(); -#if (C_DEBUG) - case BR_OpcodeFull: - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=1; - if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT - return CPU_Core_Full_Run(); -#endif - case BR_Link1: - case BR_Link2: - { - Bitu temp_ip=SegPhys(cs)+reg_eip; - CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip); - if (temp_handler->flags & PFLAG_HASCODE) { - block=temp_handler->FindCacheBlock(temp_ip & 4095); - if (!block) goto restart_core; - cache.block.running->LinkTo(ret==BR_Link2,block); - goto run_block; - } - } - goto restart_core; - } - if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT - return CBRET_NONE; -} - -Bits CPU_Core_Dyn_X86_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - cpu.trap_skip = false; - - Bits ret=CPU_Core_Normal_Run(); - if (!cpu.trap_skip) CPU_HW_Interrupt(1); - CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Dyn_X86_Run; - - return ret; -} - -void CPU_Core_Dyn_X86_Init(void) { - Bits i; - /* Setup the global registers and their flags */ - for (i=0;i&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/cpu/core_dyn_x86 -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -WINDRES = @WINDRES@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \ - dyn_fpu.h dyn_fpu_dh.h - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/cpu/core_dyn_x86/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/cpu/core_dyn_x86/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - cscopelist-am ctags ctags-am distclean distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/cache.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/cache.h deleted file mode 100644 index 23b6a53e9..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/cache.h +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -class CacheBlock { -public: - void Clear(void); - void LinkTo(Bitu index,CacheBlock * toblock) { - assert(toblock); - link[index].to=toblock; - link[index].next=toblock->link[index].from; - toblock->link[index].from=this; - } - struct { - Bit16u start,end; //Where the page is the original code - CodePageHandler * handler; //Page containing this code - } page; - struct { - Bit8u * start; //Where in the cache are we - Bitu size; - CacheBlock * next; - Bit8u * wmapmask; - Bit16u maskstart; - Bit16u masklen; - } cache; - struct { - Bitu index; - CacheBlock * next; - } hash; - struct { - CacheBlock * to; - CacheBlock * next; - CacheBlock * from; - } link[2]; - CacheBlock * crossblock; -}; - -static struct { - struct { - CacheBlock * first; - CacheBlock * active; - CacheBlock * free; - CacheBlock * running; - } block; - Bit8u * pos; - CodePageHandler * free_pages; - CodePageHandler * used_pages; - CodePageHandler * last_page; -} cache; - -static CacheBlock link_blocks[2]; - -class CodePageHandler : public PageHandler { -public: - CodePageHandler() { - invalidation_map=NULL; - } - void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) { - phys_page=_phys_page; - old_pagehandler=_old_pagehandler; - flags=old_pagehandler->flags|PFLAG_HASCODE; - flags&=~PFLAG_WRITEABLE; - active_blocks=0; - active_count=16; - memset(&hash_map,0,sizeof(hash_map)); - memset(&write_map,0,sizeof(write_map)); - if (invalidation_map!=NULL) { - free(invalidation_map); - invalidation_map=NULL; - } - } - bool InvalidateRange(Bitu start,Bitu end) { - Bits index=1+(end>>DYN_HASH_SHIFT); - bool is_current_block=false; - Bit32u ip_point=SegPhys(cs)+reg_eip; - ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff); - while (index>=0) { - Bitu map=0; - for (Bitu count=start;count<=end;count++) map+=write_map[count]; - if (!map) return is_current_block; - CacheBlock * block=hash_map[index]; - while (block) { - CacheBlock * nextblock=block->hash.next; - if (start<=block->page.end && end>=block->page.start) { - if (ip_point<=block->page.end && ip_point>=block->page.start) is_current_block=true; - block->Clear(); - } - block=nextblock; - } - index--; - } - return is_current_block; - } - void writeb(PhysPt addr,Bitu val){ - if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return; - if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { - E_Exit("wb:non-readable code page found that is no ROM page"); - } - addr&=4095; - if (host_readb(hostmem+addr)==(Bit8u)val) return; - host_writeb(hostmem+addr,val); - if (!*(Bit8u*)&write_map[addr]) { - if (active_blocks) return; - active_count--; - if (!active_count) Release(); - return; - } else if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - invalidation_map[addr]++; - InvalidateRange(addr,addr); - } - void writew(PhysPt addr,Bitu val){ - if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return; - if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { - E_Exit("ww:non-readable code page found that is no ROM page"); - } - addr&=4095; - if (host_readw(hostmem+addr)==(Bit16u)val) return; - host_writew(hostmem+addr,val); - if (!*(Bit16u*)&write_map[addr]) { - if (active_blocks) return; - active_count--; - if (!active_count) Release(); - return; - } else if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - (*(Bit16u*)&invalidation_map[addr])+=0x101; - InvalidateRange(addr,addr+1); - } - void writed(PhysPt addr,Bitu val){ - if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return; - if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { - E_Exit("wd:non-readable code page found that is no ROM page"); - } - addr&=4095; - if (host_readd(hostmem+addr)==(Bit32u)val) return; - host_writed(hostmem+addr,val); - if (!*(Bit32u*)&write_map[addr]) { - if (active_blocks) return; - active_count--; - if (!active_count) Release(); - return; - } else if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - (*(Bit32u*)&invalidation_map[addr])+=0x1010101; - InvalidateRange(addr,addr+3); - } - bool writeb_checked(PhysPt addr,Bitu val) { - if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false; - if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { - E_Exit("cb:non-readable code page found that is no ROM page"); - } - addr&=4095; - if (host_readb(hostmem+addr)==(Bit8u)val) return false; - if (!*(Bit8u*)&write_map[addr]) { - if (!active_blocks) { - active_count--; - if (!active_count) Release(); - } - } else { - if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - invalidation_map[addr]++; - if (InvalidateRange(addr,addr)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; - } - } - host_writeb(hostmem+addr,val); - return false; - } - bool writew_checked(PhysPt addr,Bitu val) { - if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false; - if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { - E_Exit("cw:non-readable code page found that is no ROM page"); - } - addr&=4095; - if (host_readw(hostmem+addr)==(Bit16u)val) return false; - if (!*(Bit16u*)&write_map[addr]) { - if (!active_blocks) { - active_count--; - if (!active_count) Release(); - } - } else { - if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - (*(Bit16u*)&invalidation_map[addr])+=0x101; - if (InvalidateRange(addr,addr+1)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; - } - } - host_writew(hostmem+addr,val); - return false; - } - bool writed_checked(PhysPt addr,Bitu val) { - if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false; - if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) { - E_Exit("cd:non-readable code page found that is no ROM page"); - } - addr&=4095; - if (host_readd(hostmem+addr)==(Bit32u)val) return false; - if (!*(Bit32u*)&write_map[addr]) { - if (!active_blocks) { - active_count--; - if (!active_count) Release(); - } - } else { - if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - (*(Bit32u*)&invalidation_map[addr])+=0x1010101; - if (InvalidateRange(addr,addr+3)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; - } - } - host_writed(hostmem+addr,val); - return false; - } - void AddCacheBlock(CacheBlock * block) { - Bitu index=1+(block->page.start>>DYN_HASH_SHIFT); - block->hash.next=hash_map[index]; - block->hash.index=index; - hash_map[index]=block; - block->page.handler=this; - active_blocks++; - } - void AddCrossBlock(CacheBlock * block) { - block->hash.next=hash_map[0]; - block->hash.index=0; - hash_map[0]=block; - block->page.handler=this; - active_blocks++; - } - void DelCacheBlock(CacheBlock * block) { - active_blocks--; - active_count=16; - CacheBlock * * where=&hash_map[block->hash.index]; - while (*where!=block) { - where=&((*where)->hash.next); - //Will crash if a block isn't found, which should never happen. - } - *where=block->hash.next; - if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) { - for (Bitu i=block->page.start;icache.maskstart;i++) { - if (write_map[i]) write_map[i]--; - } - Bitu maskct=0; - for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) { - if (write_map[i]) { - if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--; - } - } - free(block->cache.wmapmask); - block->cache.wmapmask=NULL; - } else { - for (Bitu i=block->page.start;i<=block->page.end;i++) { - if (write_map[i]) write_map[i]--; - } - } - } - void Release(void) { - MEM_SetPageHandler(phys_page,1,old_pagehandler); - PAGING_ClearTLB(); - if (prev) prev->next=next; - else cache.used_pages=next; - if (next) next->prev=prev; - else cache.last_page=prev; - next=cache.free_pages; - cache.free_pages=this; - prev=0; - } - void ClearRelease(void) { - for (Bitu index=0;index<(1+DYN_PAGE_HASH);index++) { - CacheBlock * block=hash_map[index]; - while (block) { - CacheBlock * nextblock=block->hash.next; - block->page.handler=0; //No need, full clear - block->Clear(); - block=nextblock; - } - } - Release(); - } - CacheBlock * FindCacheBlock(Bitu start) { - CacheBlock * block=hash_map[1+(start>>DYN_HASH_SHIFT)]; - while (block) { - if (block->page.start==start) return block; - block=block->hash.next; - } - return 0; - } - HostPt GetHostReadPt(Bitu phys_page) { - hostmem=old_pagehandler->GetHostReadPt(phys_page); - return hostmem; - } - HostPt GetHostWritePt(Bitu phys_page) { - return GetHostReadPt( phys_page ); - } -public: - Bit8u write_map[4096]; - Bit8u * invalidation_map; - CodePageHandler * next, * prev; -private: - PageHandler * old_pagehandler; - CacheBlock * hash_map[1+DYN_PAGE_HASH]; - Bitu active_blocks; - Bitu active_count; - HostPt hostmem; - Bitu phys_page; -}; - - -static INLINE void cache_addunsedblock(CacheBlock * block) { - block->cache.next=cache.block.free; - cache.block.free=block; -} - -static CacheBlock * cache_getblock(void) { - CacheBlock * ret=cache.block.free; - if (!ret) E_Exit("Ran out of CacheBlocks" ); - cache.block.free=ret->cache.next; - ret->cache.next=0; - return ret; -} - -void CacheBlock::Clear(void) { - Bitu ind; - /* Check if this is not a cross page block */ - if (hash.index) for (ind=0;ind<2;ind++) { - CacheBlock * fromlink=link[ind].from; - link[ind].from=0; - while (fromlink) { - CacheBlock * nextlink=fromlink->link[ind].next; - fromlink->link[ind].next=0; - fromlink->link[ind].to=&link_blocks[ind]; - fromlink=nextlink; - } - if (link[ind].to!=&link_blocks[ind]) { - CacheBlock * * wherelink=&link[ind].to->link[ind].from; - while (*wherelink != this && *wherelink) { - wherelink = &(*wherelink)->link[ind].next; - } - if(*wherelink) - *wherelink = (*wherelink)->link[ind].next; - else - LOG(LOG_CPU,LOG_ERROR)("Cache anomaly. please investigate"); - } - } else - cache_addunsedblock(this); - if (crossblock) { - crossblock->crossblock=0; - crossblock->Clear(); - crossblock=0; - } - if (page.handler) { - page.handler->DelCacheBlock(this); - page.handler=0; - } - if (cache.wmapmask){ - free(cache.wmapmask); - cache.wmapmask=NULL; - } -} - - -static CacheBlock * cache_openblock(void) { - CacheBlock * block=cache.block.active; - /* check for enough space in this block */ - Bitu size=block->cache.size; - CacheBlock * nextblock=block->cache.next; - if (block->page.handler) - block->Clear(); - while (sizecache.size; - CacheBlock * tempblock=nextblock->cache.next; - if (nextblock->page.handler) - nextblock->Clear(); - cache_addunsedblock(nextblock); - nextblock=tempblock; - } -skipresize: - block->cache.size=size; - block->cache.next=nextblock; - cache.pos=block->cache.start; - return block; -} - -static void cache_closeblock(void) { - CacheBlock * block=cache.block.active; - block->link[0].to=&link_blocks[0]; - block->link[1].to=&link_blocks[1]; - block->link[0].from=0; - block->link[1].from=0; - block->link[0].next=0; - block->link[1].next=0; - /* Close the block with correct alignments */ - Bitu written=cache.pos-block->cache.start; - if (written>block->cache.size) { - if (!block->cache.next) { - if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun 1 %d",written-block->cache.size); - } else E_Exit("CacheBlock overrun 2 written %d size %d",written,block->cache.size); - } else { - Bitu new_size; - Bitu left=block->cache.size-written; - /* Smaller than cache align then don't bother to resize */ - if (left>CACHE_ALIGN) { - new_size=((written-1)|(CACHE_ALIGN-1))+1; - CacheBlock * newblock=cache_getblock(); - newblock->cache.start=block->cache.start+new_size; - newblock->cache.size=block->cache.size-new_size; - newblock->cache.next=block->cache.next; - block->cache.next=newblock; - block->cache.size=new_size; - } - } - /* Advance the active block pointer */ - if (!block->cache.next) { -// LOG_MSG("Cache full restarting"); - cache.block.active=cache.block.first; - } else { - cache.block.active=block->cache.next; - } -} - -static INLINE void cache_addb(Bit8u val) { - *cache.pos++=val; -} - -static INLINE void cache_addw(Bit16u val) { - *(Bit16u*)cache.pos=val; - cache.pos+=2; -} - -static INLINE void cache_addd(Bit32u val) { - *(Bit32u*)cache.pos=val; - cache.pos+=4; -} - - -static void gen_return(BlockReturn retcode); - -static Bit8u * cache_code_start_ptr=NULL; -static Bit8u * cache_code=NULL; -static Bit8u * cache_code_link_blocks=NULL; -static CacheBlock * cache_blocks=NULL; - -/* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */ -#if (C_HAVE_MPROTECT) -#define PAGESIZE_TEMP PAGESIZE -#else -#define PAGESIZE_TEMP 4096 -#endif - -static bool cache_initialized = false; - -static void cache_init(bool enable) { - Bits i; - if (enable) { - if (cache_initialized) return; - cache_initialized = true; - if (cache_blocks == NULL) { - cache_blocks=(CacheBlock*)malloc(CACHE_BLOCKS*sizeof(CacheBlock)); - if(!cache_blocks) E_Exit("Allocating cache_blocks has failed"); - memset(cache_blocks,0,sizeof(CacheBlock)*CACHE_BLOCKS); - cache.block.free=&cache_blocks[0]; - for (i=0;icache.start=&cache_code[0]; - block->cache.size=CACHE_TOTAL; - block->cache.next=0; //Last block in the list - } - /* Setup the default blocks for block linkage returns */ - cache.pos=&cache_code_link_blocks[0]; - link_blocks[0].cache.start=cache.pos; - gen_return(BR_Link1); - cache.pos=&cache_code_link_blocks[32]; - link_blocks[1].cache.start=cache.pos; - gen_return(BR_Link2); - cache.free_pages=0; - cache.last_page=0; - cache.used_pages=0; - /* Setup the code pages */ - for (i=0;inext=cache.free_pages; - cache.free_pages=newpage; - } - } -} - -static void cache_close(void) { -/* for (;;) { - if (cache.used_pages) { - CodePageHandler * cpage=cache.used_pages; - CodePageHandler * npage=cache.used_pages->next; - cpage->ClearRelease(); - delete cpage; - cache.used_pages=npage; - } else break; - } - if (cache_blocks != NULL) { - free(cache_blocks); - cache_blocks = NULL; - } - if (cache_code_start_ptr != NULL) { - ### care: under windows VirtualFree() has to be used if - ### VirtualAlloc was used for memory allocation - free(cache_code_start_ptr); - cache_code_start_ptr = NULL; - } - cache_code = NULL; - cache_code_link_blocks = NULL; - cache_initialized = false; */ -} - -static void cache_reset(void) { - if (cache_initialized) { - for (;;) { - if (cache.used_pages) { - CodePageHandler * cpage=cache.used_pages; - CodePageHandler * npage=cache.used_pages->next; - cpage->ClearRelease(); - delete cpage; - cache.used_pages=npage; - } else break; - } - - if (cache_blocks == NULL) { - cache_blocks=(CacheBlock*)malloc(CACHE_BLOCKS*sizeof(CacheBlock)); - if(!cache_blocks) E_Exit("Allocating cache_blocks has failed"); - } - memset(cache_blocks,0,sizeof(CacheBlock)*CACHE_BLOCKS); - cache.block.free=&cache_blocks[0]; - for (Bits i=0;icache.start=&cache_code[0]; - block->cache.size=CACHE_TOTAL; - block->cache.next=0; //Last block in the list - - /* Setup the default blocks for block linkage returns */ - cache.pos=&cache_code_link_blocks[0]; - link_blocks[0].cache.start=cache.pos; - gen_return(BR_Link1); - cache.pos=&cache_code_link_blocks[32]; - link_blocks[1].cache.start=cache.pos; - gen_return(BR_Link2); - cache.free_pages=0; - cache.last_page=0; - cache.used_pages=0; - /* Setup the code pages */ - for (Bitu i=0;inext=cache.free_pages; - cache.free_pages=newpage; - } - } -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/decoder.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/decoder.h deleted file mode 100644 index 18bf1e111..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/decoder.h +++ /dev/null @@ -1,2713 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#define X86_DYNFPU_DH_ENABLED -#define X86_INLINED_MEMACCESS - - -enum REP_Type { - REP_NONE=0,REP_NZ,REP_Z -}; - -static struct DynDecode { - PhysPt code; - PhysPt code_start; - PhysPt op_start; - bool big_op; - bool big_addr; - REP_Type rep; - Bitu cycles; - CacheBlock * block; - CacheBlock * active_block; - struct { - CodePageHandler * code; - Bitu index; - Bit8u * wmap; - Bit8u * invmap; - Bitu first; - } page; - struct { - Bitu val; - Bitu mod; - Bitu rm; - Bitu reg; - } modrm; - DynReg * segprefix; -} decode; - -static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { - Bit8u rdval; - //Ensure page contains memory: - if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - PageHandler * handler=get_tlb_readhandler(lin_addr); - if (handler->flags & PFLAG_HASCODE) { - cph=( CodePageHandler *)handler; - return false; - } - if (handler->flags & PFLAG_NOCODE) { - if (PAGING_ForcePageInit(lin_addr)) { - handler=get_tlb_readhandler(lin_addr); - if (handler->flags & PFLAG_HASCODE) { - cph=( CodePageHandler *)handler; - return false; - } - } - if (handler->flags & PFLAG_NOCODE) { - LOG_MSG("DYNX86:Can't run code in this page!"); - cph=0; return false; - } - } - Bitu lin_page=lin_addr >> 12; - Bitu phys_page=lin_page; - if (!PAGING_MakePhysPage(phys_page)) { - LOG_MSG("DYNX86:Can't find physpage"); - cph=0; return false; - } - /* Find a free CodePage */ - if (!cache.free_pages) { - if (cache.used_pages!=decode.page.code) cache.used_pages->ClearRelease(); - else { - if ((cache.used_pages->next) && (cache.used_pages->next!=decode.page.code)) - cache.used_pages->next->ClearRelease(); - else { - LOG_MSG("DYNX86:Invalid cache links"); - cache.used_pages->ClearRelease(); - } - } - } - CodePageHandler * cpagehandler=cache.free_pages; - cache.free_pages=cache.free_pages->next; - cpagehandler->prev=cache.last_page; - cpagehandler->next=0; - if (cache.last_page) cache.last_page->next=cpagehandler; - cache.last_page=cpagehandler; - if (!cache.used_pages) cache.used_pages=cpagehandler; - cpagehandler->SetupAt(phys_page,handler); - MEM_SetPageHandler(phys_page,1,cpagehandler); - PAGING_UnlinkPages(lin_page,1); - cph=cpagehandler; - return false; -} - -static Bit8u decode_fetchb(void) { - if (GCC_UNLIKELY(decode.page.index>=4096)) { - /* Advance to the next page */ - decode.active_block->page.end=4095; - /* trigger possible page fault here */ - decode.page.first++; - Bitu fetchaddr=decode.page.first << 12; - mem_readb(fetchaddr); - MakeCodePage(fetchaddr,decode.page.code); - CacheBlock * newblock=cache_getblock(); - decode.active_block->crossblock=newblock; - newblock->crossblock=decode.active_block; - decode.active_block=newblock; - decode.active_block->page.start=0; - decode.page.code->AddCrossBlock(decode.active_block); - decode.page.wmap=decode.page.code->write_map; - decode.page.invmap=decode.page.code->invalidation_map; - decode.page.index=0; - } - decode.page.wmap[decode.page.index]+=0x01; - decode.page.index++; - decode.code+=1; - return mem_readb(decode.code-1); -} -static Bit16u decode_fetchw(void) { - if (GCC_UNLIKELY(decode.page.index>=4095)) { - Bit16u val=decode_fetchb(); - val|=decode_fetchb() << 8; - return val; - } - *(Bit16u *)&decode.page.wmap[decode.page.index]+=0x0101; - decode.code+=2;decode.page.index+=2; - return mem_readw(decode.code-2); -} -static Bit32u decode_fetchd(void) { - if (GCC_UNLIKELY(decode.page.index>=4093)) { - Bit32u val=decode_fetchb(); - val|=decode_fetchb() << 8; - val|=decode_fetchb() << 16; - val|=decode_fetchb() << 24; - return val; - /* Advance to the next page */ - } - *(Bit32u *)&decode.page.wmap[decode.page.index]+=0x01010101; - decode.code+=4;decode.page.index+=4; - return mem_readd(decode.code-4); -} - -#define START_WMMEM 64 - -static INLINE void decode_increase_wmapmask(Bitu size) { - Bitu mapidx; - CacheBlock* activecb=decode.active_block; - if (GCC_UNLIKELY(!activecb->cache.wmapmask)) { - activecb->cache.wmapmask=(Bit8u*)malloc(START_WMMEM); - memset(activecb->cache.wmapmask,0,START_WMMEM); - activecb->cache.maskstart=decode.page.index; - activecb->cache.masklen=START_WMMEM; - mapidx=0; - } else { - mapidx=decode.page.index-activecb->cache.maskstart; - if (GCC_UNLIKELY(mapidx+size>=activecb->cache.masklen)) { - Bitu newmasklen=activecb->cache.masklen*4; - if (newmasklencache.wmapmask,activecb->cache.masklen); - free(activecb->cache.wmapmask); - activecb->cache.wmapmask=tempmem; - activecb->cache.masklen=newmasklen; - } - } - switch (size) { - case 1 : activecb->cache.wmapmask[mapidx]+=0x01; break; - case 2 : (*(Bit16u*)&activecb->cache.wmapmask[mapidx])+=0x0101; break; - case 4 : (*(Bit32u*)&activecb->cache.wmapmask[mapidx])+=0x01010101; break; - } -} - -static bool decode_fetchb_imm(Bitu & val) { - if (decode.page.index<4096) { - if (decode.page.invmap != NULL) { - if (decode.page.invmap[decode.page.index] == 0) { - val=(Bit32u)decode_fetchb(); - return false; - } - HostPt tlb_addr=get_tlb_read(decode.code); - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(1); - decode.code++; - decode.page.index++; - return true; - } - } - } - val=(Bit32u)decode_fetchb(); - return false; -} -static bool decode_fetchw_imm(Bitu & val) { - if (decode.page.index<4095) { - if (decode.page.invmap != NULL) { - if ((decode.page.invmap[decode.page.index] == 0) && - (decode.page.invmap[decode.page.index + 1] == 0) - ) { - val=decode_fetchw(); - return false; - } - HostPt tlb_addr=get_tlb_read(decode.code); - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(2); - decode.code+=2; - decode.page.index+=2; - return true; - } - } - } - val=decode_fetchw(); - return false; -} -static bool decode_fetchd_imm(Bitu & val) { - if (decode.page.index<4093) { - if (decode.page.invmap != NULL) { - if ((decode.page.invmap[decode.page.index] == 0) && - (decode.page.invmap[decode.page.index + 1] == 0) && - (decode.page.invmap[decode.page.index + 2] == 0) && - (decode.page.invmap[decode.page.index + 3] == 0) - ) { - val=decode_fetchd(); - return false; - } - HostPt tlb_addr=get_tlb_read(decode.code); - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(4); - decode.code+=4; - decode.page.index+=4; - return true; - } - } - } - val=decode_fetchd(); - return false; -} - - -static void dyn_reduce_cycles(void) { - gen_protectflags(); - if (!decode.cycles) decode.cycles++; - gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles); -} - -static void dyn_save_noncritical_regs(void) { - gen_releasereg(DREG(EAX)); - gen_releasereg(DREG(ECX)); - gen_releasereg(DREG(EDX)); - gen_releasereg(DREG(EBX)); - gen_releasereg(DREG(ESP)); - gen_releasereg(DREG(EBP)); - gen_releasereg(DREG(ESI)); - gen_releasereg(DREG(EDI)); -} - -static void dyn_save_critical_regs(void) { - dyn_save_noncritical_regs(); - gen_releasereg(DREG(FLAGS)); - gen_releasereg(DREG(EIP)); - gen_releasereg(DREG(CYCLES)); -} - -static void dyn_set_eip_last_end(DynReg * endreg) { - gen_protectflags(); - gen_lea(endreg,DREG(EIP),0,0,decode.code-decode.code_start); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start); -} - -static INLINE void dyn_set_eip_end(void) { - gen_protectflags(); - gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.code-decode.code_start); -} - -static INLINE void dyn_set_eip_end(DynReg * endreg) { - gen_protectflags(); - if (cpu.code.big) gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EIP)); - else gen_extend_word(false,DREG(TMPW),DREG(EIP)); - gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(TMPW),decode.code-decode.code_start); -} - -static INLINE void dyn_set_eip_last(void) { - gen_protectflags(); - gen_dop_word_imm(DOP_ADD,cpu.code.big,DREG(EIP),decode.op_start-decode.code_start); -} - - -enum save_info_type {db_exception, cycle_check, normal, fpu_restore}; - - -static struct { - save_info_type type; - DynState state; - Bit8u * branch_pos; - Bit32u eip_change; - Bitu cycles; - Bit8u * return_pos; -} save_info[512]; - -Bitu used_save_info=0; - - -static BlockReturn DynRunException(Bit32u eip_add,Bit32u cycle_sub,Bit32u dflags) { - reg_flags=(dflags&FMASK_TEST) | (reg_flags&(~FMASK_TEST)); - reg_eip+=eip_add; - CPU_Cycles-=cycle_sub; - if (cpu.exception.which==SMC_CURRENT_BLOCK) return BR_SMCBlock; - CPU_Exception(cpu.exception.which,cpu.exception.error); - return BR_Normal; -} - -static void dyn_check_bool_exception(DynReg * check) { - gen_dop_byte(DOP_OR,check,0,check,0); - save_info[used_save_info].branch_pos=gen_create_branch_long(BR_NZ); - dyn_savestate(&save_info[used_save_info].state); - if (!decode.cycles) decode.cycles++; - save_info[used_save_info].cycles=decode.cycles; - save_info[used_save_info].eip_change=decode.op_start-decode.code_start; - if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; - save_info[used_save_info].type=db_exception; - used_save_info++; -} - -static void dyn_check_bool_exception_al(void) { - cache_addw(0xc00a); // or al, al - save_info[used_save_info].branch_pos=gen_create_branch_long(BR_NZ); - dyn_savestate(&save_info[used_save_info].state); - if (!decode.cycles) decode.cycles++; - save_info[used_save_info].cycles=decode.cycles; - save_info[used_save_info].eip_change=decode.op_start-decode.code_start; - if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; - save_info[used_save_info].type=db_exception; - used_save_info++; -} - -#include "pic.h" - -static void dyn_check_irqrequest(void) { - gen_load_host(&PIC_IRQCheck,DREG(TMPB),4); - gen_dop_word(DOP_OR,true,DREG(TMPB),DREG(TMPB)); - save_info[used_save_info].branch_pos=gen_create_branch_long(BR_NZ); - gen_releasereg(DREG(TMPB)); - dyn_savestate(&save_info[used_save_info].state); - if (!decode.cycles) decode.cycles++; - save_info[used_save_info].cycles=decode.cycles; - save_info[used_save_info].eip_change=decode.code-decode.code_start; - if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; - save_info[used_save_info].type=normal; - used_save_info++; -} - -static void dyn_check_bool_exception_ne(void) { - save_info[used_save_info].branch_pos=gen_create_branch_long(BR_Z); - dyn_savestate(&save_info[used_save_info].state); - if (!decode.cycles) decode.cycles++; - save_info[used_save_info].cycles=decode.cycles; - save_info[used_save_info].eip_change=decode.op_start-decode.code_start; - if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; - save_info[used_save_info].type=db_exception; - used_save_info++; -} - -static void dyn_fill_blocks(void) { - for (Bitu sct=0; sctindex<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.state_used))); - gen_releasereg(DREG(TMPB)); - dyn_synchstate(&save_info[sct].state); - gen_create_jump(save_info[sct].return_pos); - break; - } - } - used_save_info=0; -} - - -#if !defined(X86_INLINED_MEMACCESS) -static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { - gen_protectflags(); - gen_call_function((void *)&mem_readb_checked,"%Dd%Id",addr,&core_dyn.readdata); - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dst,1,high); -} -static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { - gen_protectflags(); - if (high) gen_call_function((void *)&mem_writeb_checked,"%Dd%Dh",addr,val); - else gen_call_function((void *)&mem_writeb_checked,"%Dd%Dd",addr,val); - dyn_check_bool_exception_al(); -} -static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { - gen_protectflags(); - if (dword) gen_call_function((void *)&mem_readd_checked,"%Dd%Id",addr,&core_dyn.readdata); - else gen_call_function((void *)&mem_readw_checked,"%Dd%Id",addr,&core_dyn.readdata); - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dst,dword?4:2); -} -static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { - gen_protectflags(); - if (dword) gen_call_function((void *)&mem_writed_checked,"%Dd%Dd",addr,val); - else gen_call_function((void *)&mem_writew_checked,"%Dd%Dd",addr,val); - dyn_check_bool_exception_al(); -} -static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { - gen_protectflags(); - gen_call_function((void *)&mem_readb_checked,"%Ddr%Id",addr,&core_dyn.readdata); - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dst,1,high); -} -static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { - gen_protectflags(); - if (high) gen_call_function((void *)&mem_writeb_checked,"%Ddr%Dh",addr,val); - else gen_call_function((void *)&mem_writeb_checked,"%Ddr%Dd",addr,val); - dyn_check_bool_exception_al(); -} -static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { - gen_protectflags(); - if (dword) gen_call_function((void *)&mem_readd_checked,"%Ddr%Id",addr,&core_dyn.readdata); - else gen_call_function((void *)&mem_readw_checked,"%Ddr%Id",addr,&core_dyn.readdata); - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dst,dword?4:2); -} -static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { - gen_protectflags(); - if (dword) gen_call_function((void *)&mem_writed_checked,"%Ddr%Dd",addr,val); - else gen_call_function((void *)&mem_writew_checked,"%Ddr%Dd",addr,val); - dyn_check_bool_exception_al(); -} - -#else - -static void dyn_read_intro(DynReg * addr,bool release_addr=true) { - gen_protectflags(); - - if (addr->genreg) { - // addr already in a register - Bit8u reg_idx=(Bit8u)addr->genreg->index; - x86gen.regs[X86_REG_ECX]->Clear(); - if (reg_idx!=1) { - cache_addw(0xc88b+(reg_idx<<8)); //Mov ecx,reg - } - x86gen.regs[X86_REG_EAX]->Clear(); - if (release_addr) gen_releasereg(addr); - } else { - // addr still in memory, directly move into ecx - x86gen.regs[X86_REG_EAX]->Clear(); - x86gen.regs[X86_REG_ECX]->Clear(); - cache_addw(0x0d8b); //Mov ecx,[data] - cache_addd((Bit32u)addr->data); - } - x86gen.regs[X86_REG_EDX]->Clear(); - - cache_addw(0xc18b); // mov eax,ecx -} - -bool mem_readb_checked_dcx86(PhysPt address) { - return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); -} - -static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { - dyn_read_intro(addr,false); - - cache_addw(0xe8c1); // shr eax,0x0c - cache_addb(0x0c); - cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] - cache_addb(0x85); - cache_addd((Bit32u)(&paging.tlb.read[0])); - cache_addw(0xc085); // test eax,eax - Bit8u* je_loc=gen_create_branch(BR_Z); - - - cache_addw(0x048a); // mov al,[eax+ecx] - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(je_loc); - cache_addb(0x51); // push ecx - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,4 - cache_addb(0x04); - cache_addw(0x012c); // sub al,1 - - dyn_check_bool_exception_ne(); - - cache_addw(0x058a); //mov al,[] - cache_addd((Bit32u)(&core_dyn.readdata)); - - gen_fill_jump(jmp_loc); - - x86gen.regs[X86_REG_EAX]->notusable=true; - GenReg * genreg=FindDynReg(dst); - x86gen.regs[X86_REG_EAX]->notusable=false; - cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); - dst->flags|=DYNFLG_CHANGED; -} - -static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { - dyn_read_intro(addr); - - cache_addw(0xe8c1); // shr eax,0x0c - cache_addb(0x0c); - cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] - cache_addb(0x85); - cache_addd((Bit32u)(&paging.tlb.read[0])); - cache_addw(0xc085); // test eax,eax - Bit8u* je_loc=gen_create_branch(BR_Z); - - - cache_addw(0x048a); // mov al,[eax+ecx] - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(je_loc); - cache_addb(0x51); // push ecx - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,4 - cache_addb(0x04); - cache_addw(0x012c); // sub al,1 - - dyn_check_bool_exception_ne(); - - cache_addw(0x058a); //mov al,[] - cache_addd((Bit32u)(&core_dyn.readdata)); - - gen_fill_jump(jmp_loc); - - x86gen.regs[X86_REG_EAX]->notusable=true; - GenReg * genreg=FindDynReg(dst); - x86gen.regs[X86_REG_EAX]->notusable=false; - cache_addw(0xc08a+(genreg->index<<11)+(high?0x2000:0)); - dst->flags|=DYNFLG_CHANGED; -} - -bool mem_readd_checked_dcx86(PhysPt address) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - core_dyn.readdata=host_readd(tlb_addr+address); - return false; - } else { - return get_tlb_readhandler(address)->readd_checked(address, &core_dyn.readdata); - } - } else return mem_unalignedreadd_checked(address, &core_dyn.readdata); -} - -static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { - if (dword) { - dyn_read_intro(addr,false); - - cache_addw(0xe8d1); // shr eax,0x1 - Bit8u* jb_loc1=gen_create_branch(BR_B); - cache_addw(0xe8d1); // shr eax,0x1 - Bit8u* jb_loc2=gen_create_branch(BR_B); - cache_addw(0xe8c1); // shr eax,0x0a - cache_addb(0x0a); - cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] - cache_addb(0x85); - cache_addd((Bit32u)(&paging.tlb.read[0])); - cache_addw(0xc085); // test eax,eax - Bit8u* je_loc=gen_create_branch(BR_Z); - - GenReg * genreg=FindDynReg(dst,true); - - cache_addw(0x048b+(genreg->index <<(8+3))); // mov dest,[eax+ecx] - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(jb_loc1); - gen_fill_branch(jb_loc2); - gen_fill_branch(je_loc); - cache_addb(0x51); // push ecx - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,4 - cache_addb(0x04); - cache_addw(0x012c); // sub al,1 - - dyn_check_bool_exception_ne(); - - gen_mov_host(&core_dyn.readdata,dst,4); - dst->flags|=DYNFLG_CHANGED; - - gen_fill_jump(jmp_loc); - } else { - gen_protectflags(); - gen_call_function((void *)&mem_readw_checked,"%Dd%Id",addr,&core_dyn.readdata); - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dst,2); - } -} - -static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { - if (dword) { - dyn_read_intro(addr); - - cache_addw(0xe8d1); // shr eax,0x1 - Bit8u* jb_loc1=gen_create_branch(BR_B); - cache_addw(0xe8d1); // shr eax,0x1 - Bit8u* jb_loc2=gen_create_branch(BR_B); - cache_addw(0xe8c1); // shr eax,0x0a - cache_addb(0x0a); - cache_addw(0x048b); // mov eax,paging.tlb.read[eax*TYPE Bit32u] - cache_addb(0x85); - cache_addd((Bit32u)(&paging.tlb.read[0])); - cache_addw(0xc085); // test eax,eax - Bit8u* je_loc=gen_create_branch(BR_Z); - - GenReg * genreg=FindDynReg(dst,true); - - cache_addw(0x048b+(genreg->index <<(8+3))); // mov dest,[eax+ecx] - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(jb_loc1); - gen_fill_branch(jb_loc2); - gen_fill_branch(je_loc); - cache_addb(0x51); // push ecx - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,4 - cache_addb(0x04); - cache_addw(0x012c); // sub al,1 - - dyn_check_bool_exception_ne(); - - gen_mov_host(&core_dyn.readdata,dst,4); - dst->flags|=DYNFLG_CHANGED; - - gen_fill_jump(jmp_loc); - } else { - gen_protectflags(); - gen_call_function((void *)&mem_readw_checked,"%Ddr%Id",addr,&core_dyn.readdata); - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dst,2); - } -} - -static void dyn_write_intro(DynReg * addr,bool release_addr=true) { - gen_protectflags(); - - if (addr->genreg) { - // addr in a register - Bit8u reg_idx_addr=(Bit8u)addr->genreg->index; - - x86gen.regs[X86_REG_EAX]->Clear(); - x86gen.regs[X86_REG_EAX]->notusable=true; - x86gen.regs[X86_REG_ECX]->Clear(); - x86gen.regs[X86_REG_ECX]->notusable=true; - - if (reg_idx_addr) { - // addr!=eax - cache_addb(0x8b); //Mov eax,reg - cache_addb(0xc0+reg_idx_addr); - } - if (release_addr) gen_releasereg(addr); - } else { - // addr still in memory, directly move into eax - x86gen.regs[X86_REG_EAX]->Clear(); - x86gen.regs[X86_REG_EAX]->notusable=true; - x86gen.regs[X86_REG_ECX]->Clear(); - x86gen.regs[X86_REG_ECX]->notusable=true; - cache_addb(0xa1); //Mov eax,[data] - cache_addd((Bit32u)addr->data); - } - - cache_addw(0xc88b); // mov ecx,eax -} - -static void dyn_write_byte(DynReg * addr,DynReg * val,bool high) { - dyn_write_intro(addr,false); - - GenReg * genreg=FindDynReg(val); - cache_addw(0xe9c1); // shr ecx,0x0c - cache_addb(0x0c); - cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] - cache_addb(0x8d); - cache_addd((Bit32u)(&paging.tlb.write[0])); - cache_addw(0xc985); // test ecx,ecx - Bit8u* je_loc=gen_create_branch(BR_Z); - - cache_addw(0x0488+(genreg->index<<11)+(high?0x2000:0)); // mov [eax+ecx],reg - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(je_loc); - - if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); - cache_addb(0x52); // push edx - cache_addb(0x50+genreg->index); - cache_addb(0x50); // push eax - if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,8 - cache_addb(0x08); - cache_addw(0x012c); // sub al,1 - cache_addb(0x5a); // pop edx - - // Restore registers to be used again - x86gen.regs[X86_REG_EAX]->notusable=false; - x86gen.regs[X86_REG_ECX]->notusable=false; - - dyn_check_bool_exception_ne(); - - gen_fill_jump(jmp_loc); -} - -static void dyn_write_byte_release(DynReg * addr,DynReg * val,bool high) { - dyn_write_intro(addr); - - GenReg * genreg=FindDynReg(val); - cache_addw(0xe9c1); // shr ecx,0x0c - cache_addb(0x0c); - cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] - cache_addb(0x8d); - cache_addd((Bit32u)(&paging.tlb.write[0])); - cache_addw(0xc985); // test ecx,ecx - Bit8u* je_loc=gen_create_branch(BR_Z); - - cache_addw(0x0488+(genreg->index<<11)+(high?0x2000:0)); // mov [eax+ecx],reg - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(je_loc); - - cache_addb(0x52); // push edx - if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); - cache_addb(0x50+genreg->index); - cache_addb(0x50); // push eax - if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,8 - cache_addb(0x08); - cache_addw(0x012c); // sub al,1 - cache_addb(0x5a); // pop edx - - // Restore registers to be used again - x86gen.regs[X86_REG_EAX]->notusable=false; - x86gen.regs[X86_REG_ECX]->notusable=false; - - dyn_check_bool_exception_ne(); - - gen_fill_jump(jmp_loc); -} - -static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { - if (dword) { - dyn_write_intro(addr,false); - - GenReg * genreg=FindDynReg(val); - cache_addw(0xe9d1); // shr ecx,0x1 - Bit8u* jb_loc1=gen_create_branch(BR_B); - cache_addw(0xe9d1); // shr ecx,0x1 - Bit8u* jb_loc2=gen_create_branch(BR_B); - cache_addw(0xe9c1); // shr ecx,0x0a - cache_addb(0x0a); - cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] - cache_addb(0x8d); - cache_addd((Bit32u)(&paging.tlb.write[0])); - cache_addw(0xc985); // test ecx,ecx - Bit8u* je_loc=gen_create_branch(BR_Z); - - cache_addw(0x0489+(genreg->index <<(8+3))); // mov [eax+ecx],reg - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(jb_loc1); - gen_fill_branch(jb_loc2); - gen_fill_branch(je_loc); - - cache_addb(0x52); // push edx - cache_addb(0x50+genreg->index); - cache_addb(0x50); // push eax - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,8 - cache_addb(0x08); - cache_addw(0x012c); // sub al,1 - cache_addb(0x5a); // pop edx - - // Restore registers to be used again - x86gen.regs[X86_REG_EAX]->notusable=false; - x86gen.regs[X86_REG_ECX]->notusable=false; - - dyn_check_bool_exception_ne(); - - gen_fill_jump(jmp_loc); - } else { - gen_protectflags(); - gen_call_function((void *)&mem_writew_checked,"%Dd%Dd",addr,val); - dyn_check_bool_exception_al(); - } -} - -static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { - if (dword) { - dyn_write_intro(addr); - - GenReg * genreg=FindDynReg(val); - cache_addw(0xe9d1); // shr ecx,0x1 - Bit8u* jb_loc1=gen_create_branch(BR_B); - cache_addw(0xe9d1); // shr ecx,0x1 - Bit8u* jb_loc2=gen_create_branch(BR_B); - cache_addw(0xe9c1); // shr ecx,0x0a - cache_addb(0x0a); - cache_addw(0x0c8b); // mov ecx,paging.tlb.read[ecx*TYPE Bit32u] - cache_addb(0x8d); - cache_addd((Bit32u)(&paging.tlb.write[0])); - cache_addw(0xc985); // test ecx,ecx - Bit8u* je_loc=gen_create_branch(BR_Z); - - cache_addw(0x0489+(genreg->index <<(8+3))); // mov [eax+ecx],reg - cache_addb(0x08); - - Bit8u* jmp_loc=gen_create_jump(); - gen_fill_branch(jb_loc1); - gen_fill_branch(jb_loc2); - gen_fill_branch(je_loc); - - cache_addb(0x52); // push edx - cache_addb(0x50+genreg->index); - cache_addb(0x50); // push eax - cache_addb(0xe8); - cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4); - cache_addw(0xc483); // add esp,8 - cache_addb(0x08); - cache_addw(0x012c); // sub al,1 - cache_addb(0x5a); // pop edx - - // Restore registers to be used again - x86gen.regs[X86_REG_EAX]->notusable=false; - x86gen.regs[X86_REG_ECX]->notusable=false; - - dyn_check_bool_exception_ne(); - - gen_fill_jump(jmp_loc); - } else { - gen_protectflags(); - gen_call_function((void *)&mem_writew_checked,"%Ddr%Dd",addr,val); - dyn_check_bool_exception_al(); - } -} - -#endif - - -static void dyn_push_unchecked(DynReg * dynreg) { - gen_protectflags(); - gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2)); - gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); - gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask); - gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK)); - gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); - if (decode.big_op) { - gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg); - } else { - //Can just push the whole 32-bit word as operand - gen_call_function((void *)&mem_writew,"%Drd%Dd",DREG(STACK),dynreg); - } -} - -static void dyn_push(DynReg * dynreg) { - gen_protectflags(); - gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2)); - gen_dop_word(DOP_MOV,true,DREG(NEWESP),DREG(ESP)); - gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); - gen_dop_word_var(DOP_AND,true,DREG(NEWESP),&cpu.stack.notmask); - gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK)); - gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); - if (decode.big_op) { - gen_call_function((void *)&mem_writed_checked,"%Drd%Dd",DREG(STACK),dynreg); - } else { - //Can just push the whole 32-bit word as operand - gen_call_function((void *)&mem_writew_checked,"%Drd%Dd",DREG(STACK),dynreg); - } - dyn_check_bool_exception_al(); - /* everything was ok, change register now */ - gen_dop_word(DOP_MOV,true,DREG(ESP),DREG(NEWESP)); - gen_releasereg(DREG(NEWESP)); -} - -static void dyn_pop(DynReg * dynreg,bool checked=true) { - gen_protectflags(); - gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP)); - gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); - gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); - if (checked) { - if (decode.big_op) { - gen_call_function((void *)&mem_readd_checked,"%Drd%Id",DREG(STACK),&core_dyn.readdata); - } else { - gen_call_function((void *)&mem_readw_checked,"%Drd%Id",DREG(STACK),&core_dyn.readdata); - } - dyn_check_bool_exception_al(); - gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2); - } else { - if (decode.big_op) { - gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK)); - } else { - gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK)); - } - } - if (dynreg!=DREG(ESP)) { - gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?4:2); - gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask); - gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask); - gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK)); - } -} - -static INLINE void dyn_get_modrm(void) { - decode.modrm.val=decode_fetchb(); - decode.modrm.mod=(decode.modrm.val >> 6) & 3; - decode.modrm.reg=(decode.modrm.val >> 3) & 7; - decode.modrm.rm=(decode.modrm.val & 7); -} - -static void dyn_fill_ea(bool addseg=true, DynReg * reg_ea=DREG(EA)) { - DynReg * segbase; - if (!decode.big_addr) { - Bits imm; - switch (decode.modrm.mod) { - case 0:imm=0;break; - case 1:imm=(Bit8s)decode_fetchb();break; - case 2:imm=(Bit16s)decode_fetchw();break; - } - DynReg * extend_src=reg_ea; - switch (decode.modrm.rm) { - case 0:/* BX+SI */ - gen_lea(reg_ea,DREG(EBX),DREG(ESI),0,imm); - segbase=DREG(DS); - break; - case 1:/* BX+DI */ - gen_lea(reg_ea,DREG(EBX),DREG(EDI),0,imm); - segbase=DREG(DS); - break; - case 2:/* BP+SI */ - gen_lea(reg_ea,DREG(EBP),DREG(ESI),0,imm); - segbase=DREG(SS); - break; - case 3:/* BP+DI */ - gen_lea(reg_ea,DREG(EBP),DREG(EDI),0,imm); - segbase=DREG(SS); - break; - case 4:/* SI */ - if (imm) gen_lea(reg_ea,DREG(ESI),0,0,imm); - else extend_src=DREG(ESI); - segbase=DREG(DS); - break; - case 5:/* DI */ - if (imm) gen_lea(reg_ea,DREG(EDI),0,0,imm); - else extend_src=DREG(EDI); - segbase=DREG(DS); - break; - case 6:/* imm/BP */ - if (!decode.modrm.mod) { - imm=decode_fetchw(); - gen_dop_word_imm(DOP_MOV,true,reg_ea,imm); - segbase=DREG(DS); - goto skip_extend_word; - } else { - gen_lea(reg_ea,DREG(EBP),0,0,imm); - segbase=DREG(SS); - } - break; - case 7: /* BX */ - if (imm) gen_lea(reg_ea,DREG(EBX),0,0,imm); - else extend_src=DREG(EBX); - segbase=DREG(DS); - break; - } - gen_extend_word(false,reg_ea,extend_src); -skip_extend_word: - if (addseg) { - gen_lea(reg_ea,reg_ea,decode.segprefix ? decode.segprefix : segbase,0,0); - } - } else { - Bits imm=0; - DynReg * base=0;DynReg * scaled=0;Bitu scale=0; - switch (decode.modrm.rm) { - case 0:base=DREG(EAX);segbase=DREG(DS);break; - case 1:base=DREG(ECX);segbase=DREG(DS);break; - case 2:base=DREG(EDX);segbase=DREG(DS);break; - case 3:base=DREG(EBX);segbase=DREG(DS);break; - case 4: /* SIB */ - { - Bitu sib=decode_fetchb(); - static DynReg * scaledtable[8]={ - DREG(EAX),DREG(ECX),DREG(EDX),DREG(EBX), - 0,DREG(EBP),DREG(ESI),DREG(EDI), - }; - scaled=scaledtable[(sib >> 3) &7]; - scale=(sib >> 6); - switch (sib & 7) { - case 0:base=DREG(EAX);segbase=DREG(DS);break; - case 1:base=DREG(ECX);segbase=DREG(DS);break; - case 2:base=DREG(EDX);segbase=DREG(DS);break; - case 3:base=DREG(EBX);segbase=DREG(DS);break; - case 4:base=DREG(ESP);segbase=DREG(SS);break; - case 5: - if (decode.modrm.mod) { - base=DREG(EBP);segbase=DREG(SS); - } else { - segbase=DREG(DS); - Bitu val; - if (decode_fetchd_imm(val)) { - gen_mov_host((void*)val,DREG(EA),4); - if (!addseg) { - gen_lea(reg_ea,DREG(EA),scaled,scale,0); - } else { - DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; - gen_lea(DREG(EA),DREG(EA),scaled,scale,0); - gen_lea(reg_ea,DREG(EA),*seg,0,0); - } - return; - } - imm=(Bit32s)val; - } - break; - case 6:base=DREG(ESI);segbase=DREG(DS);break; - case 7:base=DREG(EDI);segbase=DREG(DS);break; - } - } - break; /* SIB Break */ - case 5: - if (decode.modrm.mod) { - base=DREG(EBP);segbase=DREG(SS); - } else { - imm=(Bit32s)decode_fetchd();segbase=DREG(DS); - } - break; - case 6:base=DREG(ESI);segbase=DREG(DS);break; - case 7:base=DREG(EDI);segbase=DREG(DS);break; - } - switch (decode.modrm.mod) { - case 1:imm=(Bit8s)decode_fetchb();break; - case 2: { - Bitu val; - if (decode_fetchd_imm(val)) { - gen_mov_host((void*)val,DREG(EA),4); - if (!addseg) { - gen_lea(DREG(EA),DREG(EA),scaled,scale,0); - gen_lea(reg_ea,DREG(EA),base,0,0); - } else { - DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; - if (!base) { - gen_lea(DREG(EA),DREG(EA),scaled,scale,0); - gen_lea(reg_ea,DREG(EA),*seg,0,0); - } else if (!scaled) { - gen_lea(DREG(EA),DREG(EA),*seg,0,0); - gen_lea(reg_ea,DREG(EA),base,0,0); - } else { - gen_lea(DREG(EA),DREG(EA),scaled,scale,0); - gen_lea(DREG(EA),DREG(EA),base,0,0); - gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); - } - } - return; - } - - imm=(Bit32s)val; - break; - } - } - if (!addseg) { - gen_lea(reg_ea,base,scaled,scale,imm); - } else { - DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase; - if (!base) gen_lea(reg_ea,*seg,scaled,scale,imm); - else if (!scaled) gen_lea(reg_ea,base,*seg,0,imm); - else { - gen_lea(DREG(EA),base,scaled,scale,imm); - gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0); - } - } - } -} - - -static void dyn_dop_word_imm(DualOps op,bool dword,DynReg * dr1) { - Bitu val; - if (dword) { - if (decode_fetchd_imm(val)) { - gen_dop_word_imm_mem(op,true,dr1,(void*)val); - return; - } - } else { - if (decode_fetchw_imm(val)) { - gen_dop_word_imm_mem(op,false,dr1,(void*)val); - return; - } - } - gen_dop_word_imm(op,dword,dr1,val); -} - -static void dyn_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1) { - Bitu val; - if (decode_fetchb_imm(val)) { - gen_dop_byte_imm_mem(op,dr1,di1,(void*)val); - } else { - gen_dop_byte_imm(op,dr1,di1,(Bit8u)val); - } -} - - -#include "helpers.h" -#include "string.h" - - -static void dyn_dop_ebgb(DualOps op) { - dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); - dyn_read_byte(DREG(EA),DREG(TMPB),false); - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else set_skipflags(false); - } - gen_dop_byte(op,DREG(TMPB),0,rm_reg,decode.modrm.reg&4); - if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false); - else gen_releasereg(DREG(EA)); - gen_releasereg(DREG(TMPB)); - } else { - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else gen_discardflags(); - } - gen_dop_byte(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,decode.modrm.reg&4); - } -} - - -static void dyn_dop_gbeb(DualOps op) { - dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); - dyn_read_byte_release(DREG(EA),DREG(TMPB),false); - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else set_skipflags(false); - } - gen_dop_byte(op,rm_reg,decode.modrm.reg&4,DREG(TMPB),0); - gen_releasereg(DREG(TMPB)); - } else { - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else gen_discardflags(); - } - gen_dop_byte(op,rm_reg,decode.modrm.reg&4,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - } -} - -static void dyn_mov_ebib(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(); - gen_call_write(DREG(EA),decode_fetchb(),1); - dyn_check_bool_exception_al(); - } else { - gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb()); - } -} - -static void dyn_mov_ebgb(void) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_write_byte_release(DREG(EA),rm_reg,rm_regi==4); - } else { - gen_dop_byte(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,rm_regi); - } -} - -static void dyn_mov_gbeb(void) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_byte_release(DREG(EA),rm_reg,rm_regi); - } else { - gen_dop_byte(DOP_MOV,rm_reg,rm_regi,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - } -} - -static void dyn_dop_evgv(DualOps op) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else set_skipflags(false); - } - gen_dop_word(op,decode.big_op,DREG(TMPW),rm_reg); - if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); - else gen_releasereg(DREG(EA)); - gen_releasereg(DREG(TMPW)); - } else { - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else gen_discardflags(); - } - gen_dop_word(op,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); - } -} - -static void dyn_imul_gvev(Bitu immsize) { - dyn_get_modrm();DynReg * src; - DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea();dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); - src=DREG(TMPW); - } else { - src=&DynRegs[decode.modrm.rm]; - } - gen_needflags(); - switch (immsize) { - case 0:gen_imul_word(decode.big_op,rm_reg,src);break; - case 1:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit8s)decode_fetchb());break; - case 2:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit16s)decode_fetchw());break; - case 4:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit32s)decode_fetchd());break; - } - gen_releasereg(DREG(TMPW)); -} - -static void dyn_dop_gvev(DualOps op) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); - dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else set_skipflags(false); - } - gen_dop_word(op,decode.big_op,rm_reg,DREG(TMPW)); - gen_releasereg(DREG(TMPW)); - } else { - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else gen_discardflags(); - } - gen_dop_word(op,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); - } -} - -static void dyn_mov_evgv(void) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_write_word_release(DREG(EA),rm_reg,decode.big_op); - } else { - gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); - } -} - -static void dyn_mov_gvev(void) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_word_release(DREG(EA),rm_reg,decode.big_op); - } else { - gen_dop_word(DOP_MOV,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm]); - } -} -static void dyn_mov_eviv(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(); - gen_call_write(DREG(EA),decode.big_op ? decode_fetchd() : decode_fetchw(),decode.big_op?4:2); - dyn_check_bool_exception_al(); - } else { - gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],decode.big_op ? decode_fetchd() : decode_fetchw()); - } -} - -static void dyn_mov_ev_gb(bool sign) { - dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_byte_release(DREG(EA),DREG(TMPB),false); - gen_extend_byte(sign,decode.big_op,rm_reg,DREG(TMPB),0); - gen_releasereg(DREG(TMPB)); - } else { - gen_extend_byte(sign,decode.big_op,rm_reg,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - } -} - -static void dyn_mov_ev_gw(bool sign) { - if (!decode.big_op) { - dyn_mov_gvev(); - return; - } - dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_word_release(DREG(EA),DREG(TMPW),false); - gen_extend_word(sign,rm_reg,DREG(TMPW)); - gen_releasereg(DREG(TMPW)); - } else { - gen_extend_word(sign,rm_reg,&DynRegs[decode.modrm.rm]); - } -} - -static void dyn_cmpxchg_evgv(void) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - gen_protectflags(); - if (decode.modrm.mod<3) { - gen_releasereg(DREG(EAX)); - gen_releasereg(DREG(TMPB)); - gen_releasereg(rm_reg); - - dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(TMPB),decode.big_op); - gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),DREG(TMPB)); - Bit8u * branch=gen_create_branch(BR_NZ); - - // eax==mem -> mem:=rm_reg - dyn_write_word_release(DREG(EA),rm_reg,decode.big_op); - gen_setzeroflag(); - gen_releasereg(DREG(EAX)); - gen_releasereg(DREG(TMPB)); - gen_releasereg(rm_reg); - - Bit8u * jump=gen_create_jump(); - - gen_fill_branch(branch); - // eax!=mem -> eax:=mem - dyn_write_word_release(DREG(EA),DREG(TMPB),decode.big_op); // cmpxchg always issues write - gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),DREG(TMPB)); - gen_clearzeroflag(); - gen_releasereg(DREG(EAX)); - gen_releasereg(DREG(TMPB)); - gen_releasereg(rm_reg); - - gen_fill_jump(jump); - } else { - gen_releasereg(DREG(EAX)); - gen_releasereg(&DynRegs[decode.modrm.rm]); - gen_releasereg(rm_reg); - - gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]); - Bit8u * branch=gen_create_branch(BR_NZ); - - // eax==rm -> rm:=rm_reg - gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg); - gen_setzeroflag(); - gen_releasereg(DREG(EAX)); - gen_releasereg(&DynRegs[decode.modrm.rm]); - gen_releasereg(rm_reg); - - Bit8u * jump=gen_create_jump(); - - gen_fill_branch(branch); - // eax!=rm -> eax:=rm - gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]); - gen_clearzeroflag(); - gen_releasereg(DREG(EAX)); - gen_releasereg(&DynRegs[decode.modrm.rm]); - gen_releasereg(rm_reg); - - gen_fill_jump(jump); - } -} - -static void dyn_dshift_ev_gv(bool left,bool immediate) { - dyn_get_modrm(); - DynReg * rm_reg=&DynRegs[decode.modrm.reg]; - DynReg * ea_reg; - if (decode.modrm.mod<3) { - dyn_fill_ea();ea_reg=DREG(TMPW); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - } else ea_reg=&DynRegs[decode.modrm.rm]; - gen_needflags(); - if (immediate) gen_dshift_imm(decode.big_op,left,ea_reg,rm_reg,decode_fetchb()); - else gen_dshift_cl(decode.big_op,left,ea_reg,rm_reg,DREG(ECX)); - if (decode.modrm.mod<3) { - dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(TMPW)); - } -} - - -static DualOps grp1_table[8]={DOP_ADD,DOP_OR,DOP_ADC,DOP_SBB,DOP_AND,DOP_SUB,DOP_XOR,DOP_CMP}; -static void dyn_grp1_eb_ib(void) { - dyn_get_modrm(); - DualOps op=grp1_table[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); - dyn_read_byte(DREG(EA),DREG(TMPB),false); - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else set_skipflags(false); - } - gen_dop_byte_imm(op,DREG(TMPB),0,decode_fetchb()); - if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false); - else gen_releasereg(DREG(EA)); - gen_releasereg(DREG(TMPB)); - } else { - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else gen_discardflags(); - } - dyn_dop_byte_imm(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - } -} - -static void dyn_grp1_ev_ivx(bool withbyte) { - dyn_get_modrm(); - DualOps op=grp1_table[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else set_skipflags(false); - } - if (!withbyte) { - dyn_dop_word_imm(op,decode.big_op,DREG(TMPW)); - } else { - gen_dop_word_imm(op,decode.big_op,DREG(TMPW),(Bit8s)decode_fetchb()); - } - if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); - else gen_releasereg(DREG(EA)); - gen_releasereg(DREG(TMPW)); - } else { - if (op<=DOP_TEST) { - if (op==DOP_ADC || op==DOP_SBB) gen_needcarry(); - else gen_discardflags(); - } - if (!withbyte) { - dyn_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm]); - } else { - gen_dop_word_imm(op,decode.big_op,&DynRegs[decode.modrm.rm],(Bit8s)decode_fetchb()); - } - } -} - -enum grp2_types { - grp2_1,grp2_imm,grp2_cl, -}; - -static void dyn_grp2_eb(grp2_types type) { - dyn_get_modrm();DynReg * src;Bit8u src_i; - if (decode.modrm.mod<3) { - dyn_fill_ea();dyn_read_byte(DREG(EA),DREG(TMPB),false); - src=DREG(TMPB); - src_i=0; - } else { - src=&DynRegs[decode.modrm.rm&3]; - src_i=decode.modrm.rm&4; - } - switch (type) { - case grp2_1: - /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ - if (decode.modrm.reg < 4) gen_needflags(); - else gen_discardflags(); - gen_shift_byte_imm(decode.modrm.reg,src,src_i,1); - break; - case grp2_imm: { - Bit8u imm=decode_fetchb(); - if (imm) { - /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ - if (decode.modrm.reg < 4) gen_needflags(); - else gen_discardflags(); - gen_shift_byte_imm(decode.modrm.reg,src,src_i,imm); - } else return; - } - break; - case grp2_cl: - gen_needflags(); /* flags must not be changed on ecx==0 */ - gen_shift_byte_cl (decode.modrm.reg,src,src_i,DREG(ECX)); - break; - } - if (decode.modrm.mod<3) { - dyn_write_byte_release(DREG(EA),src,false); - gen_releasereg(src); - } -} - -static void dyn_grp2_ev(grp2_types type) { - dyn_get_modrm();DynReg * src; - if (decode.modrm.mod<3) { - dyn_fill_ea();dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - src=DREG(TMPW); - } else { - src=&DynRegs[decode.modrm.rm]; - } - switch (type) { - case grp2_1: - /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ - if (decode.modrm.reg < 4) gen_needflags(); - else gen_discardflags(); - gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,1); - break; - case grp2_imm: { - Bitu val; - if (decode_fetchb_imm(val)) { - if (decode.modrm.reg < 4) gen_needflags(); - else gen_discardflags(); - gen_load_host((void*)val,DREG(TMPB),1); - gen_shift_word_cl(decode.modrm.reg,decode.big_op,src,DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - break; - } - Bit8u imm=(Bit8u)val; - if (imm) { - /* rotates (first 4 ops) alter cf/of only; shifts (last 4 ops) alter all flags */ - if (decode.modrm.reg < 4) gen_needflags(); - else gen_discardflags(); - gen_shift_word_imm(decode.modrm.reg,decode.big_op,src,imm); - } else return; - } - break; - case grp2_cl: - gen_needflags(); /* flags must not be changed on ecx==0 */ - gen_shift_word_cl (decode.modrm.reg,decode.big_op,src,DREG(ECX)); - break; - } - if (decode.modrm.mod<3) { - dyn_write_word_release(DREG(EA),src,decode.big_op); - gen_releasereg(src); - } -} - -static void dyn_grp3_eb(void) { - dyn_get_modrm();DynReg * src;Bit8u src_i; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - if ((decode.modrm.reg==0) || (decode.modrm.reg==3)) set_skipflags(true); - dyn_read_byte(DREG(EA),DREG(TMPB),false); - src=DREG(TMPB);src_i=0; - } else { - src=&DynRegs[decode.modrm.rm&3]; - src_i=decode.modrm.rm&4; - } - switch (decode.modrm.reg) { - case 0x0: /* test eb,ib */ - set_skipflags(false);gen_dop_byte_imm(DOP_TEST,src,src_i,decode_fetchb()); - goto skipsave; - case 0x2: /* NOT Eb */ - gen_sop_byte(SOP_NOT,src,src_i); - break; - case 0x3: /* NEG Eb */ - set_skipflags(false);gen_sop_byte(SOP_NEG,src,src_i); - break; - case 0x4: /* mul Eb */ - gen_needflags();gen_mul_byte(false,DREG(EAX),src,src_i); - goto skipsave; - case 0x5: /* imul Eb */ - gen_needflags();gen_mul_byte(true,DREG(EAX),src,src_i); - goto skipsave; - case 0x6: /* div Eb */ - case 0x7: /* idiv Eb */ - /* EAX could be used, so precache it */ - if (decode.modrm.mod==3) - gen_dop_byte(DOP_MOV,DREG(TMPB),0,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - gen_releasereg(DREG(EAX)); - gen_call_function((decode.modrm.reg==6) ? (void *)&dyn_helper_divb : (void *)&dyn_helper_idivb, - "%Rd%Dd",DREG(TMPB),DREG(TMPB)); - dyn_check_bool_exception(DREG(TMPB)); - goto skipsave; - } - /* Save the result if memory op */ - if (decode.modrm.mod<3) dyn_write_byte_release(DREG(EA),src,false); -skipsave: - gen_releasereg(DREG(TMPB));gen_releasereg(DREG(EA)); -} - -static void dyn_grp3_ev(void) { - dyn_get_modrm();DynReg * src; - if (decode.modrm.mod<3) { - dyn_fill_ea();src=DREG(TMPW); - if ((decode.modrm.reg==0) || (decode.modrm.reg==3)) set_skipflags(true); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - } else src=&DynRegs[decode.modrm.rm]; - switch (decode.modrm.reg) { - case 0x0: /* test ev,iv */ - set_skipflags(false);gen_dop_word_imm(DOP_TEST,decode.big_op,src,decode.big_op ? decode_fetchd() : decode_fetchw()); - goto skipsave; - case 0x2: /* NOT Ev */ - gen_sop_word(SOP_NOT,decode.big_op,src); - break; - case 0x3: /* NEG Eb */ - set_skipflags(false);gen_sop_word(SOP_NEG,decode.big_op,src); - break; - case 0x4: /* mul Eb */ - gen_needflags();gen_mul_word(false,DREG(EAX),DREG(EDX),decode.big_op,src); - goto skipsave; - case 0x5: /* imul Eb */ - gen_needflags();gen_mul_word(true,DREG(EAX),DREG(EDX),decode.big_op,src); - goto skipsave; - case 0x6: /* div Eb */ - case 0x7: /* idiv Eb */ - /* EAX could be used, so precache it */ - if (decode.modrm.mod==3) - gen_dop_word(DOP_MOV,decode.big_op,DREG(TMPW),&DynRegs[decode.modrm.rm]); - gen_releasereg(DREG(EAX));gen_releasereg(DREG(EDX)); - void * func=(decode.modrm.reg==6) ? - (decode.big_op ? (void *)&dyn_helper_divd : (void *)&dyn_helper_divw) : - (decode.big_op ? (void *)&dyn_helper_idivd : (void *)&dyn_helper_idivw); - gen_call_function(func,"%Rd%Dd",DREG(TMPB),DREG(TMPW)); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - goto skipsave; - } - /* Save the result if memory op */ - if (decode.modrm.mod<3) dyn_write_word_release(DREG(EA),src,decode.big_op); -skipsave: - gen_releasereg(DREG(TMPW));gen_releasereg(DREG(EA)); -} - -static void dyn_mov_ev_seg(void) { - dyn_get_modrm(); - gen_load_host(&Segs.val[decode.modrm.reg],DREG(TMPW),2); - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_write_word_release(DREG(EA),DREG(TMPW),false); - } else { - gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); - } - gen_releasereg(DREG(TMPW)); -} - -static void dyn_load_seg(SegNames seg,DynReg * src) { - gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - gen_releasereg(&DynRegs[G_ES+seg]); -} - -static void dyn_load_seg_off_ea(SegNames seg) { - if (decode.modrm.mod<3) { - dyn_fill_ea(); - gen_lea(DREG(TMPB),DREG(EA),0,0,decode.big_op ? 4:2); - dyn_read_word(DREG(TMPB),DREG(TMPB),false); - dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op); - dyn_load_seg(seg,DREG(TMPB));gen_releasereg(DREG(TMPB)); - gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.reg],DREG(TMPW)); - } else { - IllegalOption("dyn_load_seg_off_ea"); - } -} - -static void dyn_mov_seg_ev(void) { - dyn_get_modrm(); - SegNames seg=(SegNames)decode.modrm.reg; - if (GCC_UNLIKELY(seg==cs)) IllegalOption("dyn_mov_seg_ev"); - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(EA),false); - dyn_load_seg(seg,DREG(EA)); - gen_releasereg(DREG(EA)); - } else { - dyn_load_seg(seg,&DynRegs[decode.modrm.rm]); - } -} - -static void dyn_push_seg(SegNames seg) { - gen_load_host(&Segs.val[seg],DREG(TMPW),2); - dyn_push(DREG(TMPW)); - gen_releasereg(DREG(TMPW)); -} - -static void dyn_pop_seg(SegNames seg) { - gen_releasereg(DREG(ESP)); - gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - gen_releasereg(&DynRegs[G_ES+seg]); - gen_releasereg(DREG(ESP)); -} - -static void dyn_pop_ev(void) { - dyn_pop(DREG(TMPW)); - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(); -// dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); - if (decode.big_op) gen_call_function((void *)&mem_writed_inline,"%Ddr%Dd",DREG(EA),DREG(TMPW)); - else gen_call_function((void *)&mem_writew_inline,"%Ddr%Dd",DREG(EA),DREG(TMPW)); - } else { - gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); - } - gen_releasereg(DREG(TMPW)); -} - -static void dyn_enter(void) { - gen_releasereg(DREG(ESP)); - gen_releasereg(DREG(EBP)); - Bitu bytes=decode_fetchw(); - Bitu level=decode_fetchb(); - gen_call_function((void *)&CPU_ENTER,"%Id%Id%Id",decode.big_op,bytes,level); -} - -static void dyn_leave(void) { - gen_protectflags(); - gen_dop_word_var(DOP_MOV,true,DREG(TMPW),&cpu.stack.mask); - gen_sop_word(SOP_NOT,true,DREG(TMPW)); - gen_dop_word(DOP_AND,true,DREG(ESP),DREG(TMPW)); - gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(EBP)); - gen_dop_word_var(DOP_AND,true,DREG(TMPW),&cpu.stack.mask); - gen_dop_word(DOP_OR,true,DREG(ESP),DREG(TMPW)); - dyn_pop(DREG(EBP),false); - gen_releasereg(DREG(TMPW)); -} - -static void dyn_segprefix(SegNames seg) { -// if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption("dyn_segprefix"); - decode.segprefix=&DynRegs[G_ES+seg]; -} - -static void dyn_closeblock(void) { - //Shouldn't create empty block normally but let's do it like this - gen_protectflags(); - dyn_fill_blocks(); - cache_closeblock(); -} - -static void dyn_normal_exit(BlockReturn code) { - gen_protectflags(); - dyn_reduce_cycles(); - dyn_set_eip_last(); - dyn_save_critical_regs(); - gen_return(code); - dyn_closeblock(); -} - -static void dyn_exit_link(Bits eip_change) { - gen_protectflags(); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),(decode.code-decode.code_start)+eip_change); - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); - dyn_closeblock(); -} - -static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) { - Bitu eip_base=decode.code-decode.code_start; - gen_needflags(); - gen_protectflags(); - dyn_save_noncritical_regs(); - gen_releasereg(DREG(FLAGS)); - gen_releasereg(DREG(EIP)); - - gen_preloadreg(DREG(CYCLES)); - gen_preloadreg(DREG(EIP)); - DynReg save_cycles,save_eip; - dyn_saveregister(DREG(CYCLES),&save_cycles); - dyn_saveregister(DREG(EIP),&save_eip); - Bit8u * data=gen_create_branch(btype); - - /* Branch not taken */ - dyn_reduce_cycles(); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base); - gen_releasereg(DREG(CYCLES)); - gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); - gen_fill_branch(data); - - /* Branch taken */ - dyn_restoreregister(&save_cycles,DREG(CYCLES)); - dyn_restoreregister(&save_eip,DREG(EIP)); - dyn_reduce_cycles(); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base+eip_add); - gen_releasereg(DREG(CYCLES)); - gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); - dyn_closeblock(); -} - -enum LoopTypes { - LOOP_NONE,LOOP_NE,LOOP_E,LOOP_JCXZ -}; - -static void dyn_loop(LoopTypes type) { - dyn_reduce_cycles(); - Bits eip_add=(Bit8s)decode_fetchb(); - Bitu eip_base=decode.code-decode.code_start; - Bit8u * branch1=0;Bit8u * branch2=0; - dyn_save_critical_regs(); - switch (type) { - case LOOP_E: - gen_needflags(); - branch1=gen_create_branch(BR_NZ); - break; - case LOOP_NE: - gen_needflags(); - branch1=gen_create_branch(BR_Z); - break; - } - gen_protectflags(); - switch (type) { - case LOOP_E: - case LOOP_NE: - case LOOP_NONE: - gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); - gen_releasereg(DREG(ECX)); - branch2=gen_create_branch(BR_Z); - break; - case LOOP_JCXZ: - gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX)); - gen_releasereg(DREG(ECX)); - branch2=gen_create_branch(BR_NZ); - break; - } - gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add); - gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); - if (branch1) { - gen_fill_branch(branch1); - gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); - gen_releasereg(DREG(ECX)); - } - /* Branch taken */ - gen_fill_branch(branch2); - gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base); - gen_releasereg(DREG(EIP)); - gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); - dyn_closeblock(); -} - -static void dyn_ret_near(Bitu bytes) { - gen_protectflags(); - dyn_reduce_cycles(); - dyn_pop(DREG(EIP)); - if (bytes) gen_dop_word_imm(DOP_ADD,true,DREG(ESP),bytes); - dyn_save_critical_regs(); - gen_return(BR_Normal); - dyn_closeblock(); -} - -static void dyn_call_near_imm(void) { - Bits imm; - if (decode.big_op) imm=(Bit32s)decode_fetchd(); - else imm=(Bit16s)decode_fetchw(); - dyn_set_eip_end(DREG(TMPW)); - dyn_push(DREG(TMPW)); - gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(TMPW),imm); - if (cpu.code.big) gen_dop_word(DOP_MOV,true,DREG(EIP),DREG(TMPW)); - else gen_extend_word(false,DREG(EIP),DREG(TMPW)); - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); - dyn_closeblock(); -} - -static void dyn_ret_far(Bitu bytes) { - gen_protectflags(); - dyn_reduce_cycles(); - dyn_set_eip_last_end(DREG(TMPW)); - dyn_flags_gen_to_host(); - dyn_save_critical_regs(); - gen_call_function((void*)&CPU_RET,"%Id%Id%Drd",decode.big_op,bytes,DREG(TMPW)); - gen_return_fast(BR_Normal); - dyn_closeblock(); -} - -static void dyn_call_far_imm(void) { - Bitu sel,off; - off=decode.big_op ? decode_fetchd() : decode_fetchw(); - sel=decode_fetchw(); - dyn_reduce_cycles(); - dyn_set_eip_last_end(DREG(TMPW)); - dyn_flags_gen_to_host(); - dyn_save_critical_regs(); - gen_call_function((void*)&CPU_CALL,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW)); - gen_return_fast(BR_Normal); - dyn_closeblock(); -} - -static void dyn_jmp_far_imm(void) { - Bitu sel,off; - gen_protectflags(); - off=decode.big_op ? decode_fetchd() : decode_fetchw(); - sel=decode_fetchw(); - dyn_reduce_cycles(); - dyn_set_eip_last_end(DREG(TMPW)); - dyn_flags_gen_to_host(); - dyn_save_critical_regs(); - gen_call_function((void*)&CPU_JMP,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW)); - gen_return_fast(BR_Normal); - dyn_closeblock(); -} - -static void dyn_iret(void) { - gen_protectflags(); - dyn_flags_gen_to_host(); - dyn_reduce_cycles(); - dyn_set_eip_last_end(DREG(TMPW)); - dyn_save_critical_regs(); - gen_call_function((void*)&CPU_IRET,"%Id%Drd",decode.big_op,DREG(TMPW)); - gen_return_fast(BR_Iret); - dyn_closeblock(); -} - -static void dyn_interrupt(Bitu num) { - gen_protectflags(); - dyn_flags_gen_to_host(); - dyn_reduce_cycles(); - dyn_set_eip_last_end(DREG(TMPW)); - dyn_save_critical_regs(); - gen_call_function((void*)&CPU_Interrupt,"%Id%Id%Drd",num,CPU_INT_SOFTWARE,DREG(TMPW)); - gen_return_fast(BR_Normal); - dyn_closeblock(); -} - -static void dyn_add_iocheck(Bitu access_size) { - gen_call_function((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size); - dyn_check_bool_exception_al(); -} - -static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { - gen_call_function((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size); - dyn_check_bool_exception_al(); -} - -#ifdef X86_DYNFPU_DH_ENABLED -#include "dyn_fpu_dh.h" -#define dh_fpu_startup() { \ - fpu_used=true; \ - gen_protectflags(); \ - gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4); \ - gen_dop_word_imm(DOP_CMP,true,DREG(TMPB),0); \ - gen_releasereg(DREG(TMPB)); \ - save_info[used_save_info].branch_pos=gen_create_branch_long(BR_Z); \ - dyn_savestate(&save_info[used_save_info].state); \ - save_info[used_save_info].return_pos=cache.pos; \ - save_info[used_save_info].type=fpu_restore; \ - used_save_info++; \ -} -#endif -#include "dyn_fpu.h" - -static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) { - Bits i; -/* Init a load of variables */ - decode.code_start=start; - decode.code=start; - Bitu cycles=0; - decode.page.code=codepage; - decode.page.index=start&4095; - decode.page.wmap=codepage->write_map; - decode.page.invmap=codepage->invalidation_map; - decode.page.first=start >> 12; - decode.active_block=decode.block=cache_openblock(); - decode.block->page.start=decode.page.index; - codepage->AddCacheBlock(decode.block); - - gen_save_host_direct(&cache.block.running,(Bit32u)decode.block); - for (i=0;i=4)) goto illegalopcode; - opcode=decode_fetchb(); - } else { - opcode=decode_fetchb(); - if (GCC_UNLIKELY(decode.page.invmap && - (decode.page.invmap[decode.page.index-1]>=4))) goto illegalopcode; - } - } - switch (opcode) { - - case 0x00:dyn_dop_ebgb(DOP_ADD);break; - case 0x01:dyn_dop_evgv(DOP_ADD);break; - case 0x02:dyn_dop_gbeb(DOP_ADD);break; - case 0x03:dyn_dop_gvev(DOP_ADD);break; - case 0x04:gen_discardflags();gen_dop_byte_imm(DOP_ADD,DREG(EAX),0,decode_fetchb());break; - case 0x05:gen_discardflags();dyn_dop_word_imm(DOP_ADD,decode.big_op,DREG(EAX));break; - case 0x06:dyn_push_seg(es);break; - case 0x07:dyn_pop_seg(es);break; - - case 0x08:dyn_dop_ebgb(DOP_OR);break; - case 0x09:dyn_dop_evgv(DOP_OR);break; - case 0x0a:dyn_dop_gbeb(DOP_OR);break; - case 0x0b:dyn_dop_gvev(DOP_OR);break; - case 0x0c:gen_discardflags();gen_dop_byte_imm(DOP_OR,DREG(EAX),0,decode_fetchb());break; - case 0x0d:gen_discardflags();gen_dop_word_imm(DOP_OR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x0e:dyn_push_seg(cs);break; - case 0x0f: - { - Bitu dual_code=decode_fetchb(); - switch (dual_code) { - /* Short conditional jumps */ - case 0x80:case 0x81:case 0x82:case 0x83:case 0x84:case 0x85:case 0x86:case 0x87: - case 0x88:case 0x89:case 0x8a:case 0x8b:case 0x8c:case 0x8d:case 0x8e:case 0x8f: - dyn_branched_exit((BranchTypes)(dual_code&0xf), - decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); - goto finish_block; - /* PUSH/POP FS */ - case 0xa0:dyn_push_seg(fs);break; - case 0xa1:dyn_pop_seg(fs);break; - /* SHLD Imm/cl*/ - case 0xa4:dyn_dshift_ev_gv(true,true);break; - case 0xa5:dyn_dshift_ev_gv(true,false);break; - /* PUSH/POP GS */ - case 0xa8:dyn_push_seg(gs);break; - case 0xa9:dyn_pop_seg(gs);break; - /* SHRD Imm/cl*/ - case 0xac:dyn_dshift_ev_gv(false,true);break; - case 0xad:dyn_dshift_ev_gv(false,false);break; - /* Imul Ev,Gv */ - case 0xaf:dyn_imul_gvev(0);break; - /* CMPXCHG */ - case 0xb1:dyn_cmpxchg_evgv();break; - /* LFS,LGS */ - case 0xb4: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(fs); - break; - case 0xb5: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(gs); - break; - /* MOVZX Gv,Eb/Ew */ - case 0xb6:dyn_mov_ev_gb(false);break; - case 0xb7:dyn_mov_ev_gw(false);break; - /* MOVSX Gv,Eb/Ew */ - case 0xbe:dyn_mov_ev_gb(true);break; - case 0xbf:dyn_mov_ev_gw(true);break; - - default: -#if DYN_LOG - LOG_MSG("Unhandled dual opcode 0F%02X",dual_code); -#endif - goto illegalopcode; - } - }break; - - case 0x10:dyn_dop_ebgb(DOP_ADC);break; - case 0x11:dyn_dop_evgv(DOP_ADC);break; - case 0x12:dyn_dop_gbeb(DOP_ADC);break; - case 0x13:dyn_dop_gvev(DOP_ADC);break; - case 0x14:gen_needcarry();gen_dop_byte_imm(DOP_ADC,DREG(EAX),0,decode_fetchb());break; - case 0x15:gen_needcarry();gen_dop_word_imm(DOP_ADC,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x16:dyn_push_seg(ss);break; - case 0x17:dyn_pop_seg(ss);break; - - case 0x18:dyn_dop_ebgb(DOP_SBB);break; - case 0x19:dyn_dop_evgv(DOP_SBB);break; - case 0x1a:dyn_dop_gbeb(DOP_SBB);break; - case 0x1b:dyn_dop_gvev(DOP_SBB);break; - case 0x1c:gen_needcarry();gen_dop_byte_imm(DOP_SBB,DREG(EAX),0,decode_fetchb());break; - case 0x1d:gen_needcarry();gen_dop_word_imm(DOP_SBB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x1e:dyn_push_seg(ds);break; - case 0x1f:dyn_pop_seg(ds);break; - case 0x20:dyn_dop_ebgb(DOP_AND);break; - case 0x21:dyn_dop_evgv(DOP_AND);break; - case 0x22:dyn_dop_gbeb(DOP_AND);break; - case 0x23:dyn_dop_gvev(DOP_AND);break; - case 0x24:gen_discardflags();gen_dop_byte_imm(DOP_AND,DREG(EAX),0,decode_fetchb());break; - case 0x25:gen_discardflags();dyn_dop_word_imm(DOP_AND,decode.big_op,DREG(EAX));break; - case 0x26:dyn_segprefix(es);goto restart_prefix; - - case 0x28:dyn_dop_ebgb(DOP_SUB);break; - case 0x29:dyn_dop_evgv(DOP_SUB);break; - case 0x2a:dyn_dop_gbeb(DOP_SUB);break; - case 0x2b:dyn_dop_gvev(DOP_SUB);break; - case 0x2c:gen_discardflags();gen_dop_byte_imm(DOP_SUB,DREG(EAX),0,decode_fetchb());break; - case 0x2d:gen_discardflags();gen_dop_word_imm(DOP_SUB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x2e:dyn_segprefix(cs);goto restart_prefix; - - case 0x30:dyn_dop_ebgb(DOP_XOR);break; - case 0x31:dyn_dop_evgv(DOP_XOR);break; - case 0x32:dyn_dop_gbeb(DOP_XOR);break; - case 0x33:dyn_dop_gvev(DOP_XOR);break; - case 0x34:gen_discardflags();gen_dop_byte_imm(DOP_XOR,DREG(EAX),0,decode_fetchb());break; - case 0x35:gen_discardflags();gen_dop_word_imm(DOP_XOR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x36:dyn_segprefix(ss);goto restart_prefix; - - case 0x38:dyn_dop_ebgb(DOP_CMP);break; - case 0x39:dyn_dop_evgv(DOP_CMP);break; - case 0x3a:dyn_dop_gbeb(DOP_CMP);break; - case 0x3b:dyn_dop_gvev(DOP_CMP);break; - case 0x3c:gen_discardflags();gen_dop_byte_imm(DOP_CMP,DREG(EAX),0,decode_fetchb());break; - case 0x3d:gen_discardflags();gen_dop_word_imm(DOP_CMP,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x3e:dyn_segprefix(ds);goto restart_prefix; - - /* INC/DEC general register */ - case 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47: - gen_needcarry();gen_sop_word(SOP_INC,decode.big_op,&DynRegs[opcode&7]); - break; - case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: - gen_needcarry();gen_sop_word(SOP_DEC,decode.big_op,&DynRegs[opcode&7]); - break; - /* PUSH/POP General register */ - case 0x50:case 0x51:case 0x52:case 0x53:case 0x55:case 0x56:case 0x57: - dyn_push(&DynRegs[opcode&7]); - break; - case 0x54: /* PUSH SP is special */ - gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(ESP)); - dyn_push(DREG(TMPW)); - gen_releasereg(DREG(TMPW)); - break; - case 0x58:case 0x59:case 0x5a:case 0x5b:case 0x5c:case 0x5d:case 0x5e:case 0x5f: - dyn_pop(&DynRegs[opcode&7]); - break; - case 0x60: /* PUSHA */ - gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(ESP)); - for (i=G_EAX;i<=G_EDI;i++) { - dyn_push_unchecked((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW)); - } - gen_releasereg(DREG(TMPW)); - break; - case 0x61: /* POPA */ - for (i=G_EDI;i>=G_EAX;i--) { - dyn_pop((i!=G_ESP) ? &DynRegs[i] : DREG(TMPW),false); - } - gen_releasereg(DREG(TMPW)); - break; - //segprefix FS,GS - case 0x64:dyn_segprefix(fs);goto restart_prefix; - case 0x65:dyn_segprefix(gs);goto restart_prefix; - //Push immediates - //Operand size - case 0x66:decode.big_op=!cpu.code.big;goto restart_prefix; - //Address size - case 0x67:decode.big_addr=!cpu.code.big;goto restart_prefix; - case 0x68: /* PUSH Iv */ - gen_dop_word_imm(DOP_MOV,decode.big_op,DREG(TMPW),decode.big_op ? decode_fetchd() : decode_fetchw()); - dyn_push(DREG(TMPW)); - gen_releasereg(DREG(TMPW)); - break; - /* Imul Ivx */ - case 0x69:dyn_imul_gvev(decode.big_op ? 4 : 2);break; - case 0x6a: /* PUSH Ibx */ - gen_dop_word_imm(DOP_MOV,true,DREG(TMPW),(Bit8s)decode_fetchb()); - dyn_push(DREG(TMPW)); - gen_releasereg(DREG(TMPW)); - break; - /* Imul Ibx */ - case 0x6b:dyn_imul_gvev(1);break; - /* Short conditional jumps */ - case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76:case 0x77: - case 0x78:case 0x79:case 0x7a:case 0x7b:case 0x7c:case 0x7d:case 0x7e:case 0x7f: - dyn_branched_exit((BranchTypes)(opcode&0xf),(Bit8s)decode_fetchb()); - goto finish_block; - /* Group 1 */ - case 0x80:dyn_grp1_eb_ib();break; - case 0x81:dyn_grp1_ev_ivx(false);break; - case 0x82:dyn_grp1_eb_ib();break; - case 0x83:dyn_grp1_ev_ivx(true);break; - /* TEST Gb,Eb Gv,Ev */ - case 0x84:dyn_dop_gbeb(DOP_TEST);break; - case 0x85:dyn_dop_gvev(DOP_TEST);break; - /* XCHG Eb,Gb Ev,Gv */ - case 0x86:dyn_dop_ebgb(DOP_XCHG);break; - case 0x87:dyn_dop_evgv(DOP_XCHG);break; - /* MOV e,g and g,e */ - case 0x88:dyn_mov_ebgb();break; - case 0x89:dyn_mov_evgv();break; - case 0x8a:dyn_mov_gbeb();break; - case 0x8b:dyn_mov_gvev();break; - /* MOV ev,seg */ - case 0x8c:dyn_mov_ev_seg();break; - /* LEA Gv */ - case 0x8d: - dyn_get_modrm(); - if (decode.big_op) { - dyn_fill_ea(false,&DynRegs[decode.modrm.reg]); - } else { - dyn_fill_ea(false); - gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.reg],DREG(EA)); - gen_releasereg(DREG(EA)); - } - break; - /* Mov seg,ev */ - case 0x8e:dyn_mov_seg_ev();break; - /* POP Ev */ - case 0x8f:dyn_pop_ev();break; - case 0x90: //NOP - case 0x9b: //WAIT/FWAIT - break; - //XCHG ax,reg - case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97: - gen_dop_word(DOP_XCHG,decode.big_op,DREG(EAX),&DynRegs[opcode&07]); - break; - /* CBW/CWDE */ - case 0x98: - gen_cbw(decode.big_op,DREG(EAX)); - break; - /* CWD/CDQ */ - case 0x99: - gen_cwd(decode.big_op,DREG(EAX),DREG(EDX)); - break; - /* CALL FAR Ip */ - case 0x9a:dyn_call_far_imm();goto finish_block; - case 0x9c: //PUSHF - gen_protectflags(); - gen_releasereg(DREG(ESP)); - dyn_flags_gen_to_host(); - gen_call_function((void *)&CPU_PUSHF,"%Rd%Id",DREG(TMPB),decode.big_op); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - break; - case 0x9d: //POPF - gen_releasereg(DREG(ESP)); - gen_releasereg(DREG(FLAGS)); - gen_call_function((void *)&CPU_POPF,"%Rd%Id",DREG(TMPB),decode.big_op); - dyn_check_bool_exception(DREG(TMPB)); - dyn_flags_host_to_gen(); - gen_releasereg(DREG(TMPB)); - dyn_check_irqrequest(); - break; - /* MOV AL,direct addresses */ - case 0xa0: - gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, - decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_read_byte_release(DREG(EA),DREG(EAX),false); - break; - /* MOV AX,direct addresses */ - case 0xa1: - gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, - decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_read_word_release(DREG(EA),DREG(EAX),decode.big_op); - break; - /* MOV direct address,AL */ - case 0xa2: - if (decode.big_addr) { - Bitu val; - if (decode_fetchd_imm(val)) { - gen_lea_imm_mem(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),(void*)val); - } else { - gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0,(Bits)val); - } - dyn_write_byte_release(DREG(EA),DREG(EAX),false); - } else { - gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0,decode_fetchw()); - dyn_write_byte_release(DREG(EA),DREG(EAX),false); - } - break; - /* MOV direct addresses,AX */ - case 0xa3: - gen_lea(DREG(EA),decode.segprefix ? decode.segprefix : DREG(DS),0,0, - decode.big_addr ? decode_fetchd() : decode_fetchw()); - dyn_write_word_release(DREG(EA),DREG(EAX),decode.big_op); - break; - /* MOVSB/W/D*/ - case 0xa4:dyn_string(STR_MOVSB);break; - case 0xa5:dyn_string(decode.big_op ? STR_MOVSD : STR_MOVSW);break; - /* TEST AL,AX Imm */ - case 0xa8:gen_discardflags();gen_dop_byte_imm(DOP_TEST,DREG(EAX),0,decode_fetchb());break; - case 0xa9:gen_discardflags();gen_dop_word_imm(DOP_TEST,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() : decode_fetchw());break; - /* STOSB/W/D*/ - case 0xaa:dyn_string(STR_STOSB);break; - case 0xab:dyn_string(decode.big_op ? STR_STOSD : STR_STOSW);break; - /* LODSB/W/D*/ - case 0xac:dyn_string(STR_LODSB);break; - case 0xad:dyn_string(decode.big_op ? STR_LODSD : STR_LODSW);break; - //Mov Byte reg,Imm byte - case 0xb0:case 0xb1:case 0xb2:case 0xb3:case 0xb4:case 0xb5:case 0xb6:case 0xb7: - gen_dop_byte_imm(DOP_MOV,&DynRegs[opcode&3],opcode&4,decode_fetchb()); - break; - //Mov word reg imm byte,word, - case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf: - if (decode.big_op) { - dyn_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7]);break; - } else { - gen_dop_word_imm(DOP_MOV,decode.big_op,&DynRegs[opcode&7],decode_fetchw());break; - } - break; - //GRP2 Eb/Ev,Ib - case 0xc0:dyn_grp2_eb(grp2_imm);break; - case 0xc1:dyn_grp2_ev(grp2_imm);break; - //RET near Iw / Ret - case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block; - case 0xc3:dyn_ret_near(0);goto finish_block; - //LES - case 0xc4: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(es); - break; - //LDS - case 0xc5: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(ds); - break; - // MOV Eb/Ev,Ib/Iv - case 0xc6:dyn_mov_ebib();break; - case 0xc7:dyn_mov_eviv();break; - //ENTER and LEAVE - case 0xc8:dyn_enter();break; - case 0xc9:dyn_leave();break; - //RET far Iw / Ret - case 0xca:dyn_ret_far(decode_fetchw());goto finish_block; - case 0xcb:dyn_ret_far(0);goto finish_block; - /* Interrupt */ -// case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; - /* IRET */ - case 0xcf:dyn_iret();goto finish_block; - - //GRP2 Eb/Ev,1 - case 0xd0:dyn_grp2_eb(grp2_1);break; - case 0xd1:dyn_grp2_ev(grp2_1);break; - //GRP2 Eb/Ev,CL - case 0xd2:dyn_grp2_eb(grp2_cl);break; - case 0xd3:dyn_grp2_ev(grp2_cl);break; - //FPU -#ifdef CPU_FPU - case 0xd8: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc0(); - else { - dh_fpu_startup(); - dh_fpu_esc0(); - } - } else -#endif - dyn_fpu_esc0(); - break; - case 0xd9: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc1(); - else { - dh_fpu_startup(); - dh_fpu_esc1(); - } - } else -#endif - dyn_fpu_esc1(); - break; - case 0xda: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc2(); - else { - dh_fpu_startup(); - dh_fpu_esc2(); - } - } else -#endif - dyn_fpu_esc2(); - break; - case 0xdb: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc3(); - else { - dh_fpu_startup(); - dh_fpu_esc3(); - } - } else -#endif - dyn_fpu_esc3(); - break; - case 0xdc: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc4(); - else { - dh_fpu_startup(); - dh_fpu_esc4(); - } - } else -#endif - dyn_fpu_esc4(); - break; - case 0xdd: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc5(); - else { - dh_fpu_startup(); - dh_fpu_esc5(); - } - } else -#endif - dyn_fpu_esc5(); - break; - case 0xde: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc6(); - else { - dh_fpu_startup(); - dh_fpu_esc6(); - } - } else -#endif - dyn_fpu_esc6(); - break; - case 0xdf: -#ifdef X86_DYNFPU_DH_ENABLED - if (dyn_dh_fpu.dh_fpu_enabled) { - if (fpu_used) dh_fpu_esc7(); - else { - dh_fpu_startup(); - dh_fpu_esc7(); - } - } else -#endif - dyn_fpu_esc7(); - break; -#endif - //Loops - case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; - case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; - //IN AL/AX,imm - case 0xe4: { - Bitu port=decode_fetchb(); - dyn_add_iocheck_var(port,1); - gen_call_function((void*)&IO_ReadB,"%Id%Rl",port,DREG(EAX)); - } break; - case 0xe5: { - Bitu port=decode_fetchb(); - dyn_add_iocheck_var(port,decode.big_op?4:2); - if (decode.big_op) { - gen_call_function((void*)&IO_ReadD,"%Id%Rd",port,DREG(EAX)); - } else { - gen_call_function((void*)&IO_ReadW,"%Id%Rw",port,DREG(EAX)); - } - } break; - //OUT imm,AL - case 0xe6: { - Bitu port=decode_fetchb(); - dyn_add_iocheck_var(port,1); - gen_call_function((void*)&IO_WriteB,"%Id%Dl",port,DREG(EAX)); - } break; - case 0xe7: { - Bitu port=decode_fetchb(); - dyn_add_iocheck_var(port,decode.big_op?4:2); - if (decode.big_op) { - gen_call_function((void*)&IO_WriteD,"%Id%Dd",port,DREG(EAX)); - } else { - gen_call_function((void*)&IO_WriteW,"%Id%Dw",port,DREG(EAX)); - } - } break; - case 0xe8: /* CALL Ivx */ - dyn_call_near_imm(); - goto finish_block; - case 0xe9: /* Jmp Ivx */ - dyn_exit_link(decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); - goto finish_block; - case 0xea: /* JMP FAR Ip */ - dyn_jmp_far_imm(); - goto finish_block; - /* Jmp Ibx */ - case 0xeb:dyn_exit_link((Bit8s)decode_fetchb());goto finish_block; - /* IN AL/AX,DX*/ - case 0xec: - dyn_add_iocheck(1); - gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),DREG(EAX)); - break; - case 0xed: - dyn_add_iocheck(decode.big_op?4:2); - if (decode.big_op) { - gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),DREG(EAX)); - } else { - gen_call_function((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),DREG(EAX)); - } - break; - /* OUT DX,AL/AX */ - case 0xee: - dyn_add_iocheck(1); - gen_call_function((void*)&IO_WriteB,"%Dw%Dl",DREG(EDX),DREG(EAX)); - break; - case 0xef: - dyn_add_iocheck(decode.big_op?4:2); - if (decode.big_op) { - gen_call_function((void*)&IO_WriteD,"%Dw%Dd",DREG(EDX),DREG(EAX)); - } else { - gen_call_function((void*)&IO_WriteW,"%Dw%Dw",DREG(EDX),DREG(EAX)); - } - break; - case 0xf0: //LOCK - break; - case 0xf2: //REPNE/NZ - decode.rep=REP_NZ; - goto restart_prefix; - case 0xf3: //REPE/Z - decode.rep=REP_Z; - goto restart_prefix; - /* Change carry flag */ - case 0xf5: //CMC - case 0xf8: //CLC - case 0xf9: //STC - gen_needflags(); - cache_addb(opcode);break; - /* GRP 3 Eb/EV */ - case 0xf6:dyn_grp3_eb();break; - case 0xf7:dyn_grp3_ev();break; - /* Change interrupt flag */ - case 0xfa: //CLI - gen_releasereg(DREG(FLAGS)); - gen_call_function((void *)&CPU_CLI,"%Rd",DREG(TMPB)); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - break; - case 0xfb: //STI - gen_releasereg(DREG(FLAGS)); - gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB)); - dyn_check_bool_exception(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - dyn_check_irqrequest(); - if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode - break; - case 0xfc: //CLD - gen_protectflags(); - gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FLAG_DF); - gen_save_host_direct(&cpu.direction,1); - break; - case 0xfd: //STD - gen_protectflags(); - gen_dop_word_imm(DOP_OR,true,DREG(FLAGS),FLAG_DF); - gen_save_host_direct(&cpu.direction,-1); - break; - /* GRP 4 Eb and callback's */ - case 0xfe: - dyn_get_modrm(); - switch (decode.modrm.reg) { - case 0x0://INC Eb - case 0x1://DEC Eb - if (decode.modrm.mod<3) { - dyn_fill_ea();dyn_read_byte(DREG(EA),DREG(TMPB),false); - gen_needcarry(); - gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,DREG(TMPB),0); - dyn_write_byte_release(DREG(EA),DREG(TMPB),false); - gen_releasereg(DREG(TMPB)); - } else { - gen_needcarry(); - gen_sop_byte(decode.modrm.reg==0 ? SOP_INC : SOP_DEC, - &DynRegs[decode.modrm.rm&3],decode.modrm.rm&4); - } - break; - case 0x7: //CALBACK Iw - gen_save_host_direct(&core_dyn.callback,decode_fetchw()); - dyn_set_eip_end(); - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_return(BR_CallBack); - dyn_closeblock(); - goto finish_block; - } - break; - - case 0xff: - { - dyn_get_modrm();DynReg * src; - if (decode.modrm.mod<3) { - dyn_fill_ea(); - dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op); - src=DREG(TMPW); - } else src=&DynRegs[decode.modrm.rm]; - switch (decode.modrm.reg) { - case 0x0://INC Ev - case 0x1://DEC Ev - gen_needcarry(); - gen_sop_word(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,decode.big_op,src); - if (decode.modrm.mod<3){ - dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); - gen_releasereg(DREG(TMPW)); - } - break; - case 0x2: /* CALL Ev */ - gen_lea(DREG(TMPB),DREG(EIP),0,0,decode.code-decode.code_start); - dyn_push(DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),src); - goto core_close_block; - case 0x4: /* JMP Ev */ - gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),src); - goto core_close_block; - case 0x3: /* CALL Ep */ - case 0x5: /* JMP Ep */ - gen_protectflags(); - dyn_flags_gen_to_host(); - gen_lea(DREG(EA),DREG(EA),0,0,decode.big_op ? 4: 2); - dyn_read_word(DREG(EA),DREG(EA),false); - dyn_set_eip_last_end(DREG(TMPB)); - dyn_save_critical_regs(); - gen_call_function( - decode.modrm.reg == 3 ? (void*)&CPU_CALL : (void*)&CPU_JMP, - decode.big_op ? "%Id%Drw%Drd%Drd" : "%Id%Drw%Drw%Drd", - decode.big_op,DREG(EA),DREG(TMPW),DREG(TMPB)); - dyn_flags_host_to_gen(); - goto core_close_block; - case 0x6: /* PUSH Ev */ - gen_releasereg(DREG(EA)); - dyn_push(src); - break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal opcode 0xff"); - goto illegalopcode; - }} - break; - default: -#if DYN_LOG -// LOG_MSG("Dynamic unhandled opcode %X",opcode); -#endif - goto illegalopcode; - } - } - // link to next block because the maximum number of opcodes has been reached - dyn_set_eip_end(); - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); - dyn_closeblock(); - goto finish_block; -core_close_block: - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_return(BR_Normal); - dyn_closeblock(); - goto finish_block; -illegalopcode: - dyn_set_eip_last(); - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_return(BR_Opcode); - dyn_closeblock(); - goto finish_block; -#if (C_DEBUG) - dyn_set_eip_last(); - dyn_reduce_cycles(); - dyn_save_critical_regs(); - gen_return(BR_OpcodeFull); - dyn_closeblock(); - goto finish_block; -#endif -finish_block: - /* Setup the correct end-address */ - decode.active_block->page.end=--decode.page.index; -// LOG_MSG("Created block size %d start %d end %d",decode.block->cache.size,decode.block->page.start,decode.block->page.end); - return decode.block; -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/dyn_fpu.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/dyn_fpu.h deleted file mode 100644 index 6534b70ba..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/dyn_fpu.h +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include "dosbox.h" -#if C_FPU - -#include -#include -#include "cross.h" -#include "mem.h" -#include "fpu.h" -#include "cpu.h" - - -static void FPU_FDECSTP(){ - TOP = (TOP - 1) & 7; -} - -static void FPU_FINCSTP(){ - TOP = (TOP + 1) & 7; -} - -static void FPU_FNSTCW(PhysPt addr){ - mem_writew(addr,fpu.cw); -} - -static void FPU_FFREE(Bitu st) { - fpu.tags[st]=TAG_Empty; -} - - -#if C_FPU_X86 -#include "../../fpu/fpu_instructions_x86.h" -#else -#include "../../fpu/fpu_instructions.h" -#endif - - -#define dyn_fpu_top() { \ - gen_protectflags(); \ - gen_load_host(&TOP,DREG(EA),4); \ - gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm); \ - gen_dop_word_imm(DOP_AND,true,DREG(EA),7); \ - gen_load_host(&TOP,DREG(TMPB),4); \ -} - -static void dyn_eatree() { - Bitu group=(decode.modrm.val >> 3) & 7; - switch (group){ - case 0x00: /* FADD ST,STi */ - gen_call_function((void*)&FPU_FADD_EA,"%Ddr",DREG(TMPB)); - break; - case 0x01: /* FMUL ST,STi */ - gen_call_function((void*)&FPU_FMUL_EA,"%Ddr",DREG(TMPB)); - break; - case 0x02: /* FCOM STi */ - gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); - break; - case 0x03: /* FCOMP STi */ - gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: /* FSUB ST,STi */ - gen_call_function((void*)&FPU_FSUB_EA,"%Ddr",DREG(TMPB)); - break; - case 0x05: /* FSUBR ST,STi */ - gen_call_function((void*)&FPU_FSUBR_EA,"%Ddr",DREG(TMPB)); - break; - case 0x06: /* FDIV ST,STi */ - gen_call_function((void*)&FPU_FDIV_EA,"%Ddr",DREG(TMPB)); - break; - case 0x07: /* FDIVR ST,STi */ - gen_call_function((void*)&FPU_FDIVR_EA,"%Ddr",DREG(TMPB)); - break; - default: - break; - } -} - -static void dyn_fpu_esc0(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - dyn_fpu_top(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - switch (group){ - case 0x00: //FADD ST,STi / - gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x01: // FMUL ST,STi / - gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x02: // FCOM STi / - gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x03: // FCOMP STi / - gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: // FSUB ST,STi / - gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x05: // FSUBR ST,STi / - gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x06: // FDIV ST,STi / - gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x07: // FDIVR ST,STi / - gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - default: - break; - } - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_F32_EA,"%Ddr",DREG(EA)); - gen_load_host(&TOP,DREG(TMPB),4); - dyn_eatree(); - } -} - -static void dyn_fpu_esc1(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - switch (group){ - case 0x00: /* FLD STi */ - gen_protectflags(); - gen_load_host(&TOP,DREG(EA),4); - gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm); - gen_dop_word_imm(DOP_AND,true,DREG(EA),7); - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x01: /* FXCH STi */ - dyn_fpu_top(); - gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x02: /* FNOP */ - gen_call_function((void*)&FPU_FNOP,""); - break; - case 0x03: /* FSTP STi */ - dyn_fpu_top(); - gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: - switch(sub){ - case 0x00: /* FCHS */ - gen_call_function((void*)&FPU_FCHS,""); - break; - case 0x01: /* FABS */ - gen_call_function((void*)&FPU_FABS,""); - break; - case 0x02: /* UNKNOWN */ - case 0x03: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - case 0x04: /* FTST */ - gen_call_function((void*)&FPU_FTST,""); - break; - case 0x05: /* FXAM */ - gen_call_function((void*)&FPU_FXAM,""); - break; - case 0x06: /* FTSTP (cyrix)*/ - case 0x07: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x05: - switch(sub){ - case 0x00: /* FLD1 */ - gen_call_function((void*)&FPU_FLD1,""); - break; - case 0x01: /* FLDL2T */ - gen_call_function((void*)&FPU_FLDL2T,""); - break; - case 0x02: /* FLDL2E */ - gen_call_function((void*)&FPU_FLDL2E,""); - break; - case 0x03: /* FLDPI */ - gen_call_function((void*)&FPU_FLDPI,""); - break; - case 0x04: /* FLDLG2 */ - gen_call_function((void*)&FPU_FLDLG2,""); - break; - case 0x05: /* FLDLN2 */ - gen_call_function((void*)&FPU_FLDLN2,""); - break; - case 0x06: /* FLDZ*/ - gen_call_function((void*)&FPU_FLDZ,""); - break; - case 0x07: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x06: - switch(sub){ - case 0x00: /* F2XM1 */ - gen_call_function((void*)&FPU_F2XM1,""); - break; - case 0x01: /* FYL2X */ - gen_call_function((void*)&FPU_FYL2X,""); - break; - case 0x02: /* FPTAN */ - gen_call_function((void*)&FPU_FPTAN,""); - break; - case 0x03: /* FPATAN */ - gen_call_function((void*)&FPU_FPATAN,""); - break; - case 0x04: /* FXTRACT */ - gen_call_function((void*)&FPU_FXTRACT,""); - break; - case 0x05: /* FPREM1 */ - gen_call_function((void*)&FPU_FPREM1,""); - break; - case 0x06: /* FDECSTP */ - gen_call_function((void*)&FPU_FDECSTP,""); - break; - case 0x07: /* FINCSTP */ - gen_call_function((void*)&FPU_FINCSTP,""); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x07: - switch(sub){ - case 0x00: /* FPREM */ - gen_call_function((void*)&FPU_FPREM,""); - break; - case 0x01: /* FYL2XP1 */ - gen_call_function((void*)&FPU_FYL2XP1,""); - break; - case 0x02: /* FSQRT */ - gen_call_function((void*)&FPU_FSQRT,""); - break; - case 0x03: /* FSINCOS */ - gen_call_function((void*)&FPU_FSINCOS,""); - break; - case 0x04: /* FRNDINT */ - gen_call_function((void*)&FPU_FRNDINT,""); - break; - case 0x05: /* FSCALE */ - gen_call_function((void*)&FPU_FSCALE,""); - break; - case 0x06: /* FSIN */ - gen_call_function((void*)&FPU_FSIN,""); - break; - case 0x07: /* FCOS */ - gen_call_function((void*)&FPU_FCOS,""); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - } else { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - dyn_fill_ea(); - switch(group){ - case 0x00: /* FLD float*/ - gen_protectflags(); - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_FLD_F32,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x01: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST float*/ - gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA)); - break; - case 0x03: /* FSTP float*/ - gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: /* FLDENV */ - gen_call_function((void*)&FPU_FLDENV,"%Ddr",DREG(EA)); - break; - case 0x05: /* FLDCW */ - gen_call_function((void *)&FPU_FLDCW,"%Ddr",DREG(EA)); - break; - case 0x06: /* FSTENV */ - gen_call_function((void *)&FPU_FSTENV,"%Ddr",DREG(EA)); - break; - case 0x07: /* FNSTCW*/ - gen_call_function((void *)&FPU_FNSTCW,"%Ddr",DREG(EA)); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - } - } -} - -static void dyn_fpu_esc2(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - switch(group){ - case 0x05: - switch(sub){ - case 0x01: /* FUCOMPP */ - gen_protectflags(); - gen_load_host(&TOP,DREG(EA),4); - gen_dop_word_imm(DOP_ADD,true,DREG(EA),1); - gen_dop_word_imm(DOP_AND,true,DREG(EA),7); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void *)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void *)&FPU_FPOP,""); - gen_call_function((void *)&FPU_FPOP,""); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); - break; - } - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_I32_EA,"%Ddr",DREG(EA)); - gen_load_host(&TOP,DREG(TMPB),4); - dyn_eatree(); - } -} - -static void dyn_fpu_esc3(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - switch (group) { - case 0x04: - switch (sub) { - case 0x00: //FNENI - case 0x01: //FNDIS - LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub); - break; - case 0x02: //FNCLEX FCLEX - gen_call_function((void*)&FPU_FCLEX,""); - break; - case 0x03: //FNINIT FINIT - gen_call_function((void*)&FPU_FINIT,""); - break; - case 0x04: //FNSETPM - case 0x05: //FRSTPM -// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); - break; - default: - E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub); - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); - break; - } - } else { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - dyn_fill_ea(); - switch(group){ - case 0x00: /* FILD */ - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_protectflags(); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_FLD_I32,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x01: /* FISTTP */ - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST */ - gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA)); - break; - case 0x03: /* FISTP */ - gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x05: /* FLD 80 Bits Real */ - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_call_function((void*)&FPU_FLD_F80,"%Ddr",DREG(EA)); - break; - case 0x07: /* FSTP 80 Bits Real */ - gen_call_function((void*)&FPU_FST_F80,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - } - } -} - -static void dyn_fpu_esc4(){ - dyn_get_modrm(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - if (decode.modrm.val >= 0xc0) { - dyn_fpu_top(); - switch(group){ - case 0x00: /* FADD STi,ST*/ - gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x01: /* FMUL STi,ST*/ - gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x02: /* FCOM*/ - gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x03: /* FCOMP*/ - gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: /* FSUBR STi,ST*/ - gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x05: /* FSUB STi,ST*/ - gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x06: /* FDIVR STi,ST*/ - gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x07: /* FDIV STi,ST*/ - gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - default: - break; - } - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_F64_EA,"%Ddr",DREG(EA)); - gen_load_host(&TOP,DREG(TMPB),4); - dyn_eatree(); - } -} - -static void dyn_fpu_esc5(){ - dyn_get_modrm(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - if (decode.modrm.val >= 0xc0) { - dyn_fpu_top(); - switch(group){ - case 0x00: /* FFREE STi */ - gen_call_function((void*)&FPU_FFREE,"%Ddr",DREG(EA)); - break; - case 0x01: /* FXCH STi*/ - gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x02: /* FST STi */ - gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x03: /* FSTP STi*/ - gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: /* FUCOM STi */ - gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x05: /*FUCOMP STi */ - gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub); - break; - } - gen_releasereg(DREG(EA)); - gen_releasereg(DREG(TMPB)); - } else { - dyn_fill_ea(); - switch(group){ - case 0x00: /* FLD double real*/ - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_protectflags(); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_FLD_F64,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x01: /* FISTTP longint*/ - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST double real*/ - gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA)); - break; - case 0x03: /* FSTP double real*/ - gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: /* FRSTOR */ - gen_call_function((void*)&FPU_FRSTOR,"%Ddr",DREG(EA)); - break; - case 0x06: /* FSAVE */ - gen_call_function((void*)&FPU_FSAVE,"%Ddr",DREG(EA)); - break; - case 0x07: /*FNSTSW */ - gen_protectflags(); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_SET_TOP,"%Dd",DREG(TMPB)); - gen_load_host(&fpu.sw,DREG(TMPB),4); - gen_call_function((void*)&mem_writew,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - } - } -} - -static void dyn_fpu_esc6(){ - dyn_get_modrm(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - if (decode.modrm.val >= 0xc0) { - dyn_fpu_top(); - switch(group){ - case 0x00: /*FADDP STi,ST*/ - gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x01: /* FMULP STi,ST*/ - gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x02: /* FCOMP5*/ - gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; /* TODO IS THIS ALLRIGHT ????????? */ - case 0x03: /*FCOMPP*/ - if(sub != 1) { - LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); - return; - } - gen_load_host(&TOP,DREG(EA),4); - gen_dop_word_imm(DOP_ADD,true,DREG(EA),1); - gen_dop_word_imm(DOP_AND,true,DREG(EA),7); - gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); /* extra pop at the bottom*/ - break; - case 0x04: /* FSUBRP STi,ST*/ - gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x05: /* FSUBP STi,ST*/ - gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x06: /* FDIVRP STi,ST*/ - gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x07: /* FDIVP STi,ST*/ - gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - default: - break; - } - gen_call_function((void*)&FPU_FPOP,""); - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_I16_EA,"%Ddr",DREG(EA)); - gen_load_host(&TOP,DREG(TMPB),4); - dyn_eatree(); - } -} - -static void dyn_fpu_esc7(){ - dyn_get_modrm(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - if (decode.modrm.val >= 0xc0) { - switch (group){ - case 0x00: /* FFREEP STi*/ - dyn_fpu_top(); - gen_call_function((void*)&FPU_FFREE,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x01: /* FXCH STi*/ - dyn_fpu_top(); - gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - break; - case 0x02: /* FSTP STi*/ - case 0x03: /* FSTP STi*/ - dyn_fpu_top(); - gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: - switch(sub){ - case 0x00: /* FNSTSW AX*/ - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_SET_TOP,"%Ddr",DREG(TMPB)); - gen_mov_host(&fpu.sw,DREG(EAX),2); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } - } else { - dyn_fill_ea(); - switch(group){ - case 0x00: /* FILD Bit16s */ - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_FLD_I16,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x01: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST Bit16s */ - gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA)); - break; - case 0x03: /* FISTP Bit16s */ - gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x04: /* FBLD packed BCD */ - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_FBLD,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x05: /* FILD Bit64s */ - gen_call_function((void*)&FPU_PREP_PUSH,""); - gen_load_host(&TOP,DREG(TMPB),4); - gen_call_function((void*)&FPU_FLD_I64,"%Ddr%Ddr",DREG(EA),DREG(TMPB)); - break; - case 0x06: /* FBSTP packed BCD */ - gen_call_function((void*)&FPU_FBST,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - case 0x07: /* FISTP Bit64s */ - gen_call_function((void*)&FPU_FST_I64,"%Ddr",DREG(EA)); - gen_call_function((void*)&FPU_FPOP,""); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - } - } -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/dyn_fpu_dh.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/dyn_fpu_dh.h deleted file mode 100644 index 23870452e..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/dyn_fpu_dh.h +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include "dosbox.h" -#if C_FPU - -static void FPU_FLD_16(PhysPt addr) { - dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw(addr); -} - -static void FPU_FST_16(PhysPt addr) { - mem_writew(addr,(Bit16u)dyn_dh_fpu.temp.m1); -} - -static void FPU_FLD_32(PhysPt addr) { - dyn_dh_fpu.temp.m1 = mem_readd(addr); -} - -static void FPU_FST_32(PhysPt addr) { - mem_writed(addr,dyn_dh_fpu.temp.m1); -} - -static void FPU_FLD_64(PhysPt addr) { - dyn_dh_fpu.temp.m1 = mem_readd(addr); - dyn_dh_fpu.temp.m2 = mem_readd(addr+4); -} - -static void FPU_FST_64(PhysPt addr) { - mem_writed(addr,dyn_dh_fpu.temp.m1); - mem_writed(addr+4,dyn_dh_fpu.temp.m2); -} - -static void FPU_FLD_80(PhysPt addr) { - dyn_dh_fpu.temp.m1 = mem_readd(addr); - dyn_dh_fpu.temp.m2 = mem_readd(addr+4); - dyn_dh_fpu.temp.m3 = mem_readw(addr+8); -} - -static void FPU_FST_80(PhysPt addr) { - mem_writed(addr,dyn_dh_fpu.temp.m1); - mem_writed(addr+4,dyn_dh_fpu.temp.m2); - mem_writew(addr+8,dyn_dh_fpu.temp.m3); -} - -static void FPU_FLDCW_DH(PhysPt addr){ - dyn_dh_fpu.cw = mem_readw(addr); - dyn_dh_fpu.temp.m1 = (Bit32u)(dyn_dh_fpu.cw|0x3f); -} - -static void FPU_FNSTCW_DH(PhysPt addr){ - mem_writew(addr,(Bit16u)(dyn_dh_fpu.cw&0xffff)); -} - -static void FPU_FNINIT_DH(void){ - dyn_dh_fpu.cw = 0x37f; -} - -static void FPU_FSTENV_DH(PhysPt addr){ - if(!cpu.code.big) { - mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw); - mem_writew(addr+2,(Bit16u)dyn_dh_fpu.temp.m2); - mem_writew(addr+4,dyn_dh_fpu.temp.m3); - } else { - mem_writed(addr+0,dyn_dh_fpu.temp.m1); - mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw); - mem_writed(addr+4,dyn_dh_fpu.temp.m2); - mem_writed(addr+8,dyn_dh_fpu.temp.m3); - } -} - -static void FPU_FLDENV_DH(PhysPt addr){ - if(!cpu.code.big) { - dyn_dh_fpu.cw = (Bit32u)mem_readw(addr); - dyn_dh_fpu.temp.m1 = dyn_dh_fpu.cw|0x3f; - dyn_dh_fpu.temp.m2 = (Bit32u)mem_readw(addr+2); - dyn_dh_fpu.temp.m3 = mem_readw(addr+4); - } else { - dyn_dh_fpu.cw = (Bit32u)mem_readw(addr); - dyn_dh_fpu.temp.m1 = mem_readd(addr)|0x3f; - dyn_dh_fpu.temp.m2 = mem_readd(addr+4); - dyn_dh_fpu.temp.m3 = mem_readw(addr+8); - dyn_dh_fpu.temp.d1 = mem_readw(addr+10); - } -} - -static void FPU_FSAVE_DH(PhysPt addr){ - if (!cpu.code.big) { - mem_writew(addr,(Bit16u)dyn_dh_fpu.cw); - addr+=2; - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x04]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x05]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x08]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x09]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0c]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0d]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x10]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x11]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x14]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x15]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x18]); - mem_writeb(addr++,dyn_dh_fpu.temp_state[0x19]); - for(Bitu i=28;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]); - } else { - mem_writew(addr,(Bit16u)dyn_dh_fpu.cw); - addr+=2; - for(Bitu i=2;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]); - } -} - -static void FPU_FRSTOR_DH(PhysPt addr){ - if (!cpu.code.big) { - dyn_dh_fpu.cw = (Bit32u)mem_readw(addr); - dyn_dh_fpu.temp_state[0x00] = mem_readb(addr++)|0x3f; - dyn_dh_fpu.temp_state[0x01] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x04] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x05] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x08] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x09] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x0c] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x0d] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x10] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x11] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x14] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x15] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x18] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0x19] = mem_readb(addr++); - for(Bitu i=28;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++); - } else { - dyn_dh_fpu.cw = (Bit32u)mem_readw(addr); - for(Bitu i=0;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++); - dyn_dh_fpu.temp_state[0]|=0x3f; - } -} - -static void dh_fpu_esc0(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - cache_addb(0xd8); - cache_addb(decode.modrm.val); - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA)); - cache_addb(0xd8); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - } -} - -static void dh_fpu_esc1(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - cache_addb(0xd9); - cache_addb(decode.modrm.val); - } else { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - dyn_fill_ea(); - switch(group){ - case 0x00: /* FLD float*/ - gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA)); - cache_addb(0xd9); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x01: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST float*/ - cache_addb(0xd9); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA)); - break; - case 0x03: /* FSTP float*/ - cache_addb(0xd9); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA)); - break; - case 0x04: /* FLDENV */ - gen_call_function((void*)&FPU_FLDENV_DH,"%Ddr",DREG(EA)); - cache_addb(0xd9); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x05: /* FLDCW */ - gen_call_function((void *)&FPU_FLDCW_DH,"%Ddr",DREG(EA)); - cache_addb(0xd9); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x06: /* FSTENV */ - cache_addb(0xd9); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FSTENV_DH,"%Ddr",DREG(EA)); - break; - case 0x07: /* FNSTCW*/ - gen_call_function((void*)&FPU_FNSTCW_DH,"%Ddr",DREG(EA)); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - } - } -} - -static void dh_fpu_esc2(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - cache_addb(0xda); - cache_addb(decode.modrm.val); - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA)); - cache_addb(0xda); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - } -} - -static void dh_fpu_esc3(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - switch (group) { - case 0x04: - switch (sub) { - case 0x00: //FNENI - case 0x01: //FNDIS - LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub); - break; - case 0x02: //FNCLEX FCLEX - cache_addb(0xdb); - cache_addb(decode.modrm.val); - break; - case 0x03: //FNINIT FINIT - gen_call_function((void*)&FPU_FNINIT_DH,""); - cache_addb(0xdb); - cache_addb(decode.modrm.val); - break; - case 0x04: //FNSETPM - case 0x05: //FRSTPM -// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); - break; - default: - E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub); - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); - break; - } - } else { - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - dyn_fill_ea(); - switch(group){ - case 0x00: /* FILD */ - gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA)); - cache_addb(0xdb); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x01: /* FISTTP */ - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST */ - cache_addb(0xdb); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA)); - break; - case 0x03: /* FISTP */ - cache_addb(0xdb); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA)); - break; - case 0x05: /* FLD 80 Bits Real */ - gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA)); - cache_addb(0xdb); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x07: /* FSTP 80 Bits Real */ - cache_addb(0xdb); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA)); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - } - } -} - -static void dh_fpu_esc4(){ - dyn_get_modrm(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - if (decode.modrm.val >= 0xc0) { - cache_addb(0xdc); - cache_addb(decode.modrm.val); - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA)); - cache_addb(0xdc); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - } -} - -static void dh_fpu_esc5(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - cache_addb(0xdd); - cache_addb(decode.modrm.val); - } else { - dyn_fill_ea(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - switch(group){ - case 0x00: /* FLD double real*/ - gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA)); - cache_addb(0xdd); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x01: /* FISTTP longint*/ - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST double real*/ - cache_addb(0xdd); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA)); - break; - case 0x03: /* FSTP double real*/ - cache_addb(0xdd); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA)); - break; - case 0x04: /* FRSTOR */ - gen_call_function((void*)&FPU_FRSTOR_DH,"%Ddr",DREG(EA)); - cache_addb(0xdd); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0]))); - break; - case 0x06: /* FSAVE */ - cache_addb(0xdd); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0]))); - gen_call_function((void*)&FPU_FSAVE_DH,"%Ddr",DREG(EA)); - cache_addb(0xdb); - cache_addb(0xe3); - break; - case 0x07: /* FNSTSW */ - cache_addb(0xdd); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA)); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - } - } -} - -static void dh_fpu_esc6(){ - dyn_get_modrm(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - if (decode.modrm.val >= 0xc0) { - cache_addb(0xde); - cache_addb(decode.modrm.val); - } else { - dyn_fill_ea(); - gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA)); - cache_addb(0xde); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - } -} - -static void dh_fpu_esc7(){ - dyn_get_modrm(); - Bitu group=(decode.modrm.val >> 3) & 7; - Bitu sub=(decode.modrm.val & 7); - if (decode.modrm.val >= 0xc0) { - switch (group){ - case 0x00: /* FFREEP STi*/ - cache_addb(0xdf); - cache_addb(decode.modrm.val); - break; - case 0x01: /* FXCH STi*/ - cache_addb(0xdf); - cache_addb(decode.modrm.val); - break; - case 0x02: /* FSTP STi*/ - case 0x03: /* FSTP STi*/ - cache_addb(0xdf); - cache_addb(decode.modrm.val); - break; - case 0x04: - switch(sub){ - case 0x00: /* FNSTSW AX*/ - cache_addb(0xdd); - cache_addb(0x05|(0x07<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_load_host(&(dyn_dh_fpu.temp.m1),DREG(TMPB),4); - gen_dop_word(DOP_MOV,false,DREG(EAX),DREG(TMPB)); - gen_releasereg(DREG(TMPB)); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } - } else { - dyn_fill_ea(); - switch(group){ - case 0x00: /* FILD Bit16s */ - gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA)); - cache_addb(0xdf); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x01: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST Bit16s */ - cache_addb(0xdf); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA)); - break; - case 0x03: /* FISTP Bit16s */ - cache_addb(0xdf); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA)); - break; - case 0x04: /* FBLD packed BCD */ - gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA)); - cache_addb(0xdf); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x05: /* FILD Bit64s */ - gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA)); - cache_addb(0xdf); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - break; - case 0x06: /* FBSTP packed BCD */ - cache_addb(0xdf); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA)); - break; - case 0x07: /* FISTP Bit64s */ - cache_addb(0xdf); - cache_addb(0x05|(decode.modrm.reg<<3)); - cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1))); - gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA)); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - } - } -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/helpers.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/helpers.h deleted file mode 100644 index 022e6780d..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/helpers.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -static bool dyn_helper_divb(Bit8u val) { - if (!val) return CPU_PrepareException(0,0); - Bitu quo=reg_ax / val; - Bit8u rem=(Bit8u)(reg_ax % val); - Bit8u quo8=(Bit8u)(quo&0xff); - if (quo>0xff) return CPU_PrepareException(0,0); - reg_ah=rem; - reg_al=quo8; - return false; -} - -static bool dyn_helper_idivb(Bit8s val) { - if (!val) return CPU_PrepareException(0,0); - Bits quo=(Bit16s)reg_ax / val; - Bit8s rem=(Bit8s)((Bit16s)reg_ax % val); - Bit8s quo8s=(Bit8s)(quo&0xff); - if (quo!=(Bit16s)quo8s) return CPU_PrepareException(0,0); - reg_ah=rem; - reg_al=quo8s; - return false; -} - -static bool dyn_helper_divw(Bit16u val) { - if (!val) return CPU_PrepareException(0,0); - Bitu num=(reg_dx<<16)|reg_ax; - Bitu quo=num/val; - Bit16u rem=(Bit16u)(num % val); - Bit16u quo16=(Bit16u)(quo&0xffff); - if (quo!=(Bit32u)quo16) return CPU_PrepareException(0,0); - reg_dx=rem; - reg_ax=quo16; - return false; -} - -static bool dyn_helper_idivw(Bit16s val) { - if (!val) return CPU_PrepareException(0,0); - Bits num=(reg_dx<<16)|reg_ax; - Bits quo=num/val; - Bit16s rem=(Bit16s)(num % val); - Bit16s quo16s=(Bit16s)quo; - if (quo!=(Bit32s)quo16s) return CPU_PrepareException(0,0); - reg_dx=rem; - reg_ax=quo16s; - return false; -} - -static bool dyn_helper_divd(Bit32u val) { - if (!val) return CPU_PrepareException(0,0); - Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; - Bit64u quo=num/val; - Bit32u rem=(Bit32u)(num % val); - Bit32u quo32=(Bit32u)(quo&0xffffffff); - if (quo!=(Bit64u)quo32) return CPU_PrepareException(0,0); - reg_edx=rem; - reg_eax=quo32; - return false; -} - -static bool dyn_helper_idivd(Bit32s val) { - if (!val) return CPU_PrepareException(0,0); - Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; - Bit64s quo=num/val; - Bit32s rem=(Bit32s)(num % val); - Bit32s quo32s=(Bit32s)(quo&0xffffffff); - if (quo!=(Bit64s)quo32s) return CPU_PrepareException(0,0); - reg_edx=rem; - reg_eax=quo32s; - return false; -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/risc_x86.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/risc_x86.h deleted file mode 100644 index 74c85366a..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/risc_x86.h +++ /dev/null @@ -1,1071 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -static void gen_init(void); - -/* End of needed */ - -#define X86_REGS 7 -#define X86_REG_EAX 0x00 -#define X86_REG_ECX 0x01 -#define X86_REG_EDX 0x02 -#define X86_REG_EBX 0x03 -#define X86_REG_EBP 0x04 -#define X86_REG_ESI 0x05 -#define X86_REG_EDI 0x06 - -#define X86_REG_MASK(_REG_) (1 << X86_REG_ ## _REG_) - -static struct { - bool flagsactive; - Bitu last_used; - GenReg * regs[X86_REGS]; -} x86gen; - -class GenReg { -public: - GenReg(Bit8u _index) { - index=_index; - notusable=false;dynreg=0; - } - DynReg * dynreg; - Bitu last_used; //Keeps track of last assigned regs - Bit8u index; - bool notusable; - void Load(DynReg * _dynreg,bool stale=false) { - if (!_dynreg) return; - if (GCC_UNLIKELY((Bitu)dynreg)) Clear(); - dynreg=_dynreg; - last_used=x86gen.last_used; - dynreg->flags&=~DYNFLG_CHANGED; - dynreg->genreg=this; - if ((!stale) && (dynreg->flags & (DYNFLG_LOAD|DYNFLG_ACTIVE))) { - cache_addw(0x058b+(index << (8+3))); //Mov reg,[data] - cache_addd((Bit32u)dynreg->data); - } - dynreg->flags|=DYNFLG_ACTIVE; - } - void Save(void) { - if (GCC_UNLIKELY(!((Bitu)dynreg))) IllegalOption("GenReg->Save"); - dynreg->flags&=~DYNFLG_CHANGED; - cache_addw(0x0589+(index << (8+3))); //Mov [data],reg - cache_addd((Bit32u)dynreg->data); - } - void Release(void) { - if (GCC_UNLIKELY(!((Bitu)dynreg))) return; - if (dynreg->flags&DYNFLG_CHANGED && dynreg->flags&DYNFLG_SAVE) { - Save(); - } - dynreg->flags&=~(DYNFLG_CHANGED|DYNFLG_ACTIVE); - dynreg->genreg=0;dynreg=0; - } - void Clear(void) { - if (!dynreg) return; - if (dynreg->flags&DYNFLG_CHANGED) { - Save(); - } - dynreg->genreg=0;dynreg=0; - } -}; - -static BlockReturn gen_runcode(Bit8u * code) { - BlockReturn retval; -#if defined (_MSC_VER) - __asm { -/* Prepare the flags */ - mov eax,[code] - push ebx - push ebp - push esi - push edi - mov ebx,[reg_flags] - and ebx,FMASK_TEST - push offset(return_address) - push ebx - jmp eax -/* Restore the flags */ -return_address: - /* return here with flags in ecx */ - and dword ptr [reg_flags],~FMASK_TEST - and ecx,FMASK_TEST - or [reg_flags],ecx - pop edi - pop esi - pop ebp - pop ebx - mov [retval],eax - } -#elif defined (MACOSX) - register Bit32u tempflags=reg_flags & FMASK_TEST; - __asm__ volatile ( - "pushl %%ebx \n" - "pushl %%ebp \n" - "pushl $(run_return_adress) \n" - "pushl %2 \n" - "jmp *%3 \n" - "run_return_adress: \n" - "popl %%ebp \n" - "popl %%ebx \n" - :"=a" (retval), "=c" (tempflags) - :"r" (tempflags),"r" (code) - :"%edx","%edi","%esi","cc","memory" - ); - reg_flags=(reg_flags & ~FMASK_TEST) | (tempflags & FMASK_TEST); -#else - register Bit32u tempflags=reg_flags & FMASK_TEST; - __asm__ volatile ( - "pushl %%ebp \n" - "pushl $(run_return_adress) \n" - "pushl %2 \n" - "jmp *%3 \n" - "run_return_adress: \n" - "popl %%ebp \n" - :"=a" (retval), "=c" (tempflags) - :"r" (tempflags),"r" (code) - :"%edx","%ebx","%edi","%esi","cc","memory" - ); - reg_flags=(reg_flags & ~FMASK_TEST) | (tempflags & FMASK_TEST); -#endif - return retval; -} - -static GenReg * FindDynReg(DynReg * dynreg,bool stale=false) { - x86gen.last_used++; - if (dynreg->genreg) { - dynreg->genreg->last_used=x86gen.last_used; - return dynreg->genreg; - } - /* Find best match for selected global reg */ - Bits i; - Bits first_used,first_index; - first_used=-1; - if (dynreg->flags & DYNFLG_HAS8) { - /* Has to be eax,ebx,ecx,edx */ - for (i=first_index=0;i<=X86_REG_EBX;i++) { - GenReg * genreg=x86gen.regs[i]; - if (genreg->notusable) continue; - if (!(genreg->dynreg)) { - genreg->Load(dynreg,stale); - return genreg; - } - if (genreg->last_used<(Bitu)first_used) { - first_used=genreg->last_used; - first_index=i; - } - } - } else { - for (i=first_index=X86_REGS-1;i>=0;i--) { - GenReg * genreg=x86gen.regs[i]; - if (genreg->notusable) continue; - if (!(genreg->dynreg)) { - genreg->Load(dynreg,stale); - return genreg; - } - if (genreg->last_used<(Bitu)first_used) { - first_used=genreg->last_used; - first_index=i; - } - } - } - /* No free register found use earliest assigned one */ - GenReg * newreg=x86gen.regs[first_index]; - newreg->Load(dynreg,stale); - return newreg; -} - -static GenReg * ForceDynReg(GenReg * genreg,DynReg * dynreg) { - genreg->last_used=++x86gen.last_used; - if (dynreg->genreg==genreg) return genreg; - if (genreg->dynreg) genreg->Clear(); - if (dynreg->genreg) dynreg->genreg->Clear(); - genreg->Load(dynreg); - return genreg; -} - -static void gen_preloadreg(DynReg * dynreg) { - FindDynReg(dynreg); -} - -static void gen_releasereg(DynReg * dynreg) { - GenReg * genreg=dynreg->genreg; - if (genreg) genreg->Release(); - else dynreg->flags&=~(DYNFLG_ACTIVE|DYNFLG_CHANGED); -} - -static void gen_setupreg(DynReg * dnew,DynReg * dsetup) { - dnew->flags=dsetup->flags; - if (dnew->genreg==dsetup->genreg) return; - /* Not the same genreg must be wrong */ - if (dnew->genreg) { - /* Check if the genreg i'm changing is actually linked to me */ - if (dnew->genreg->dynreg==dnew) dnew->genreg->dynreg=0; - } - dnew->genreg=dsetup->genreg; - if (dnew->genreg) dnew->genreg->dynreg=dnew; -} - -static void gen_synchreg(DynReg * dnew,DynReg * dsynch) { - /* First make sure the registers match */ - if (dnew->genreg!=dsynch->genreg) { - if (dnew->genreg) dnew->genreg->Clear(); - if (dsynch->genreg) { - dsynch->genreg->Load(dnew); - } - } - /* Always use the loadonce flag from either state */ - dnew->flags|=(dsynch->flags & dnew->flags&DYNFLG_ACTIVE); - if ((dnew->flags ^ dsynch->flags) & DYNFLG_CHANGED) { - /* Ensure the changed value gets saved */ - if (dnew->flags & DYNFLG_CHANGED) { - dnew->genreg->Save(); - } else dnew->flags|=DYNFLG_CHANGED; - } -} - -static void gen_needflags(void) { - if (!x86gen.flagsactive) { - x86gen.flagsactive=true; - cache_addb(0x9d); //POPFD - } -} - -static void gen_protectflags(void) { - if (x86gen.flagsactive) { - x86gen.flagsactive=false; - cache_addb(0x9c); //PUSHFD - } -} - -static void gen_discardflags(void) { - if (!x86gen.flagsactive) { - x86gen.flagsactive=true; - cache_addw(0xc483); //ADD ESP,4 - cache_addb(0x4); - } -} - -static void gen_needcarry(void) { - if (!x86gen.flagsactive) { - x86gen.flagsactive=true; - cache_addw(0x2cd1); //SHR DWORD [ESP],1 - cache_addb(0x24); - cache_addd(0x0424648d); //LEA ESP,[ESP+4] - } -} - -static void gen_setzeroflag(void) { - if (x86gen.flagsactive) IllegalOption("gen_setzeroflag"); - cache_addw(0x0c83); //OR DWORD [ESP],0x40 - cache_addw(0x4024); -} - -static void gen_clearzeroflag(void) { - if (x86gen.flagsactive) IllegalOption("gen_clearzeroflag"); - cache_addw(0x2483); //AND DWORD [ESP],~0x40 - cache_addw(0xbf24); -} - -static bool skip_flags=false; - -static void set_skipflags(bool state) { - if (!state) gen_discardflags(); - skip_flags=state; -} - -static void gen_reinit(void) { - x86gen.last_used=0; - x86gen.flagsactive=false; - for (Bitu i=0;idynreg=0; - } -} - - -static void gen_load_host(void * data,DynReg * dr1,Bitu size) { - GenReg * gr1=FindDynReg(dr1,true); - switch (size) { - case 1:cache_addw(0xb60f);break; //movzx byte - case 2:cache_addw(0xb70f);break; //movzx word - case 4:cache_addb(0x8b);break; //mov - default: - IllegalOption("gen_load_host"); - } - cache_addb(0x5+(gr1->index<<3)); - cache_addd((Bit32u)data); - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_mov_host(void * data,DynReg * dr1,Bitu size,Bit8u di1=0) { - GenReg * gr1=FindDynReg(dr1,(size==4)); - switch (size) { - case 1:cache_addb(0x8a);break; //mov byte - case 2:cache_addb(0x66); //mov word - case 4:cache_addb(0x8b);break; //mov - default: - IllegalOption("gen_load_host"); - } - cache_addb(0x5+((gr1->index+(di1?4:0))<<3)); - cache_addd((Bit32u)data); - dr1->flags|=DYNFLG_CHANGED; -} - - -static void gen_dop_byte(DualOps op,DynReg * dr1,Bit8u di1,DynReg * dr2,Bit8u di2) { - GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); - Bit8u tmp; - switch (op) { - case DOP_ADD: tmp=0x02; break; - case DOP_ADC: tmp=0x12; break; - case DOP_SUB: tmp=0x2a; break; - case DOP_SBB: tmp=0x1a; break; - case DOP_CMP: tmp=0x3a; goto nochange; - case DOP_XOR: tmp=0x32; break; - case DOP_AND: tmp=0x22; if ((dr1==dr2) && (di1==di2)) goto nochange; break; - case DOP_OR: tmp=0x0a; if ((dr1==dr2) && (di1==di2)) goto nochange; break; - case DOP_TEST: tmp=0x84; goto nochange; - case DOP_MOV: if ((dr1==dr2) && (di1==di2)) return; tmp=0x8a; break; - case DOP_XCHG: tmp=0x86; dr2->flags|=DYNFLG_CHANGED; break; - default: - IllegalOption("gen_dop_byte"); - } - dr1->flags|=DYNFLG_CHANGED; -nochange: - cache_addw(tmp|(0xc0+((gr1->index+di1)<<3)+gr2->index+di2)<<8); -} - -static void gen_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1,Bitu imm) { - GenReg * gr1=FindDynReg(dr1); - Bit16u tmp; - switch (op) { - case DOP_ADD: tmp=0xc080; break; - case DOP_ADC: tmp=0xd080; break; - case DOP_SUB: tmp=0xe880; break; - case DOP_SBB: tmp=0xd880; break; - case DOP_CMP: tmp=0xf880; goto nochange; //Doesn't change - case DOP_XOR: tmp=0xf080; break; - case DOP_AND: tmp=0xe080; break; - case DOP_OR: tmp=0xc880; break; - case DOP_TEST: tmp=0xc0f6; goto nochange; //Doesn't change - case DOP_MOV: cache_addb(0xb0+gr1->index+di1); - dr1->flags|=DYNFLG_CHANGED; - goto finish; - default: - IllegalOption("gen_dop_byte_imm"); - } - dr1->flags|=DYNFLG_CHANGED; -nochange: - cache_addw(tmp+((gr1->index+di1)<<8)); -finish: - cache_addb(imm); -} - -static void gen_dop_byte_imm_mem(DualOps op,DynReg * dr1,Bit8u di1,void* data) { - GenReg * gr1=FindDynReg(dr1); - Bit16u tmp; - switch (op) { - case DOP_ADD: tmp=0x0502; break; - case DOP_ADC: tmp=0x0512; break; - case DOP_SUB: tmp=0x052a; break; - case DOP_SBB: tmp=0x051a; break; - case DOP_CMP: tmp=0x053a; goto nochange; //Doesn't change - case DOP_XOR: tmp=0x0532; break; - case DOP_AND: tmp=0x0522; break; - case DOP_OR: tmp=0x050a; break; - case DOP_TEST: tmp=0x0584; goto nochange; //Doesn't change - case DOP_MOV: tmp=0x0585; break; - default: - IllegalOption("gen_dop_byte_imm_mem"); - } - dr1->flags|=DYNFLG_CHANGED; -nochange: - cache_addw(tmp+((gr1->index+di1)<<11)); - cache_addd((Bit32u)data); -} - -static void gen_sop_byte(SingleOps op,DynReg * dr1,Bit8u di1) { - GenReg * gr1=FindDynReg(dr1); - Bit16u tmp; - switch (op) { - case SOP_INC: tmp=0xc0FE; break; - case SOP_DEC: tmp=0xc8FE; break; - case SOP_NOT: tmp=0xd0f6; break; - case SOP_NEG: tmp=0xd8f6; break; - default: - IllegalOption("gen_sop_byte"); - } - cache_addw(tmp + ((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; -} - - -static void gen_extend_word(bool sign,DynReg * ddr,DynReg * dsr) { - GenReg * gsr=FindDynReg(dsr); - GenReg * gdr=FindDynReg(ddr,true); - if (sign) cache_addw(0xbf0f); - else cache_addw(0xb70f); - cache_addb(0xc0+(gdr->index<<3)+(gsr->index)); - ddr->flags|=DYNFLG_CHANGED; -} - -static void gen_extend_byte(bool sign,bool dword,DynReg * ddr,DynReg * dsr,Bit8u dsi) { - GenReg * gsr=FindDynReg(dsr); - GenReg * gdr=FindDynReg(ddr,dword); - if (!dword) cache_addb(0x66); - if (sign) cache_addw(0xbe0f); - else cache_addw(0xb60f); - cache_addb(0xc0+(gdr->index<<3)+(gsr->index+dsi)); - ddr->flags|=DYNFLG_CHANGED; -} - -static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm) { - GenReg * gdr=FindDynReg(ddr); - Bitu imm_size; - Bit8u rm_base=(gdr->index << 3); - if (dsr1) { - GenReg * gsr1=FindDynReg(dsr1); - if (!imm && (gsr1->index!=0x5)) { - imm_size=0; rm_base+=0x0; //no imm - } else if ((imm>=-128 && imm<=127)) { - imm_size=1;rm_base+=0x40; //Signed byte imm - } else { - imm_size=4;rm_base+=0x80; //Signed dword imm - } - if (dsr2) { - GenReg * gsr2=FindDynReg(dsr2); - cache_addb(0x8d); //LEA - cache_addb(rm_base+0x4); //The sib indicator - Bit8u sib=(gsr1->index)+(gsr2->index<<3)+(scale<<6); - cache_addb(sib); - } else { - if ((ddr==dsr1) && !imm_size) return; - cache_addb(0x8d); //LEA - cache_addb(rm_base+gsr1->index); - } - } else { - if (dsr2) { - GenReg * gsr2=FindDynReg(dsr2); - cache_addb(0x8d); //LEA - cache_addb(rm_base+0x4); //The sib indicator - Bit8u sib=(5+(gsr2->index<<3)+(scale<<6)); - cache_addb(sib); - imm_size=4; - } else { - cache_addb(0x8d); //LEA - cache_addb(rm_base+0x05); //dword imm - imm_size=4; - } - } - switch (imm_size) { - case 0: break; - case 1:cache_addb(imm);break; - case 4:cache_addd(imm);break; - } - ddr->flags|=DYNFLG_CHANGED; -} - -static void gen_lea_imm_mem(DynReg * ddr,DynReg * dsr,void* data) { - GenReg * gdr=FindDynReg(ddr); - Bit8u rm_base=(gdr->index << 3); - cache_addw(0x058b+(rm_base<<8)); - cache_addd((Bit32u)data); - GenReg * gsr=FindDynReg(dsr); - cache_addb(0x8d); //LEA - cache_addb(rm_base+0x44); - cache_addb(rm_base+gsr->index); - cache_addb(0x00); - ddr->flags|=DYNFLG_CHANGED; -} - -static void gen_dop_word(DualOps op,bool dword,DynReg * dr1,DynReg * dr2) { - GenReg * gr2=FindDynReg(dr2); - GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); - Bit8u tmp; - switch (op) { - case DOP_ADD: tmp=0x03; break; - case DOP_ADC: tmp=0x13; break; - case DOP_SUB: tmp=0x2b; break; - case DOP_SBB: tmp=0x1b; break; - case DOP_CMP: tmp=0x3b; goto nochange; - case DOP_XOR: tmp=0x33; break; - case DOP_AND: tmp=0x23; if (dr1==dr2) goto nochange; break; - case DOP_OR: tmp=0x0b; if (dr1==dr2) goto nochange; break; - case DOP_TEST: tmp=0x85; goto nochange; - case DOP_MOV: if (dr1==dr2) return; tmp=0x8b; break; - case DOP_XCHG: - dr2->flags|=DYNFLG_CHANGED; - if (dword && !((dr1->flags&DYNFLG_HAS8) ^ (dr2->flags&DYNFLG_HAS8))) { - dr1->genreg=gr2;dr1->genreg->dynreg=dr1; - dr2->genreg=gr1;dr2->genreg->dynreg=dr2; - dr1->flags|=DYNFLG_CHANGED; - return; - } - tmp=0x87; - break; - default: - IllegalOption("gen_dop_word"); - } - dr1->flags|=DYNFLG_CHANGED; -nochange: - if (!dword) cache_addb(0x66); - cache_addw(tmp|(0xc0+(gr1->index<<3)+gr2->index)<<8); -} - -static void gen_dop_word_imm(DualOps op,bool dword,DynReg * dr1,Bits imm) { - GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); - Bit16u tmp; - if (!dword) cache_addb(0x66); - switch (op) { - case DOP_ADD: tmp=0xc081; break; - case DOP_ADC: tmp=0xd081; break; - case DOP_SUB: tmp=0xe881; break; - case DOP_SBB: tmp=0xd881; break; - case DOP_CMP: tmp=0xf881; goto nochange; //Doesn't change - case DOP_XOR: tmp=0xf081; break; - case DOP_AND: tmp=0xe081; break; - case DOP_OR: tmp=0xc881; break; - case DOP_TEST: tmp=0xc0f7; goto nochange; //Doesn't change - case DOP_MOV: cache_addb(0xb8+(gr1->index)); dr1->flags|=DYNFLG_CHANGED; goto finish; - default: - IllegalOption("gen_dop_word_imm"); - } - dr1->flags|=DYNFLG_CHANGED; -nochange: - cache_addw(tmp+(gr1->index<<8)); -finish: - if (dword) cache_addd(imm); - else cache_addw(imm); -} - -static void gen_dop_word_imm_mem(DualOps op,bool dword,DynReg * dr1,void* data) { - GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); - Bit16u tmp; - switch (op) { - case DOP_ADD: tmp=0x0503; break; - case DOP_ADC: tmp=0x0513; break; - case DOP_SUB: tmp=0x052b; break; - case DOP_SBB: tmp=0x051b; break; - case DOP_CMP: tmp=0x053b; goto nochange; //Doesn't change - case DOP_XOR: tmp=0x0533; break; - case DOP_AND: tmp=0x0523; break; - case DOP_OR: tmp=0x050b; break; - case DOP_TEST: tmp=0x0585; goto nochange; //Doesn't change - case DOP_MOV: - gen_mov_host(data,dr1,dword?4:2); - dr1->flags|=DYNFLG_CHANGED; - return; - default: - IllegalOption("gen_dop_word_imm_mem"); - } - dr1->flags|=DYNFLG_CHANGED; -nochange: - if (!dword) cache_addb(0x66); - cache_addw(tmp+(gr1->index<<11)); - cache_addd((Bit32u)data); -} - -static void gen_dop_word_var(DualOps op,bool dword,DynReg * dr1,void* drd) { - GenReg * gr1=FindDynReg(dr1,dword && op==DOP_MOV); - Bit8u tmp; - switch (op) { - case DOP_ADD: tmp=0x03; break; - case DOP_ADC: tmp=0x13; break; - case DOP_SUB: tmp=0x2b; break; - case DOP_SBB: tmp=0x1b; break; - case DOP_CMP: tmp=0x3b; break; - case DOP_XOR: tmp=0x33; break; - case DOP_AND: tmp=0x23; break; - case DOP_OR: tmp=0x0b; break; - case DOP_TEST: tmp=0x85; break; - case DOP_MOV: tmp=0x8b; break; - case DOP_XCHG: tmp=0x87; break; - default: - IllegalOption("gen_dop_word_var"); - } - if (!dword) cache_addb(0x66); - cache_addw(tmp|(0x05+((gr1->index)<<3))<<8); - cache_addd((Bit32u)drd); -} - -static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) { - GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); - dr1->flags|=DYNFLG_CHANGED; - if (!dword) { - cache_addd(0xaf0f66|(0xc0+(gr1->index<<3)+gr2->index)<<24); - } else { - cache_addw(0xaf0f); - cache_addb(0xc0+(gr1->index<<3)+gr2->index); - } -} - -static void gen_imul_word_imm(bool dword,DynReg * dr1,DynReg * dr2,Bits imm) { - GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2); - if (!dword) cache_addb(0x66); - if ((imm>=-128 && imm<=127)) { - cache_addb(0x6b); - cache_addb(0xc0+(gr1->index<<3)+gr2->index); - cache_addb(imm); - } else { - cache_addb(0x69); - cache_addb(0xc0+(gr1->index<<3)+gr2->index); - if (dword) cache_addd(imm); - else cache_addw(imm); - } - dr1->flags|=DYNFLG_CHANGED; -} - - -static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) { - GenReg * gr1=FindDynReg(dr1); - if (!dword) cache_addb(0x66); - switch (op) { - case SOP_INC:cache_addb(0x40+gr1->index);break; - case SOP_DEC:cache_addb(0x48+gr1->index);break; - case SOP_NOT:cache_addw(0xd0f7+(gr1->index<<8));break; - case SOP_NEG:cache_addw(0xd8f7+(gr1->index<<8));break; - default: - IllegalOption("gen_sop_word"); - } - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_shift_byte_cl(Bitu op,DynReg * dr1,Bit8u di1,DynReg * drecx) { - ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); - GenReg * gr1=FindDynReg(dr1); - cache_addw(0xc0d2+(((Bit16u)op) << 11)+ ((gr1->index+di1)<<8)); - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_shift_byte_imm(Bitu op,DynReg * dr1,Bit8u di1,Bit8u imm) { - GenReg * gr1=FindDynReg(dr1); - cache_addw(0xc0c0+(((Bit16u)op) << 11) + ((gr1->index+di1)<<8)); - cache_addb(imm); - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_shift_word_cl(Bitu op,bool dword,DynReg * dr1,DynReg * drecx) { - ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); - GenReg * gr1=FindDynReg(dr1); - if (!dword) cache_addb(0x66); - cache_addw(0xc0d3+(((Bit16u)op) << 11) + ((gr1->index)<<8)); - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_shift_word_imm(Bitu op,bool dword,DynReg * dr1,Bit8u imm) { - GenReg * gr1=FindDynReg(dr1); - dr1->flags|=DYNFLG_CHANGED; - if (!dword) { - cache_addd(0x66|((0xc0c1+((Bit16u)op << 11) + (gr1->index<<8))|imm<<16)<<8); - } else { - cache_addw(0xc0c1+((Bit16u)op << 11) + (gr1->index<<8)); - cache_addb(imm); - } -} - -static void gen_cbw(bool dword,DynReg * dyn_ax) { - ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); - if (!dword) cache_addb(0x66); - cache_addb(0x98); - dyn_ax->flags|=DYNFLG_CHANGED; -} - -static void gen_cwd(bool dword,DynReg * dyn_ax,DynReg * dyn_dx) { - ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); - ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); - dyn_ax->flags|=DYNFLG_CHANGED; - dyn_dx->flags|=DYNFLG_CHANGED; - if (!dword) cache_addw(0x9966); - else cache_addb(0x99); -} - -static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) { - ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); - GenReg * gr1=FindDynReg(dr1); - if (imul) cache_addw(0xe8f6+((gr1->index+di1)<<8)); - else cache_addw(0xe0f6+((gr1->index+di1)<<8)); - dyn_ax->flags|=DYNFLG_CHANGED; -} - -static void gen_mul_word(bool imul,DynReg * dyn_ax,DynReg * dyn_dx,bool dword,DynReg * dr1) { - ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax); - ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx); - GenReg * gr1=FindDynReg(dr1); - if (!dword) cache_addb(0x66); - if (imul) cache_addw(0xe8f7+(gr1->index<<8)); - else cache_addw(0xe0f7+(gr1->index<<8)); - dyn_ax->flags|=DYNFLG_CHANGED; - dyn_dx->flags|=DYNFLG_CHANGED; -} - -static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) { - GenReg * gr1=FindDynReg(dr1); - GenReg * gr2=FindDynReg(dr2); - if (!dword) cache_addb(0x66); - if (left) cache_addw(0xa40f); //SHLD IMM - else cache_addw(0xac0f); //SHRD IMM - cache_addb(0xc0+gr1->index+(gr2->index<<3)); - cache_addb(imm); - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg * drecx) { - ForceDynReg(x86gen.regs[X86_REG_ECX],drecx); - GenReg * gr1=FindDynReg(dr1); - GenReg * gr2=FindDynReg(dr2); - if (!dword) cache_addb(0x66); - if (left) cache_addw(0xa50f); //SHLD CL - else cache_addw(0xad0f); //SHRD CL - cache_addb(0xc0+gr1->index+(gr2->index<<3)); - dr1->flags|=DYNFLG_CHANGED; -} - -static void gen_call_function(void * func,char const* ops,...) { - Bits paramcount=0; - bool release_flags=false; - struct ParamInfo { - const char * line; - Bitu value; - } pinfo[32]; - ParamInfo * retparam=0; - /* Clear the EAX Genreg for usage */ - x86gen.regs[X86_REG_EAX]->Clear(); - x86gen.regs[X86_REG_EAX]->notusable=true; - /* Save the flags */ - if (GCC_UNLIKELY(!skip_flags)) gen_protectflags(); - /* Scan for the amount of params */ - if (ops) { - va_list params; - va_start(params,ops); -#if defined (MACOSX) - Bitu stack_used=0; - bool free_flags=false; -#endif - Bits pindex=0; - while (*ops) { - if (*ops=='%') { - pinfo[pindex].line=ops+1; - pinfo[pindex].value=va_arg(params,Bitu); -#if defined (MACOSX) - const char * scan=pinfo[pindex].line; - if ((*scan=='I') || (*scan=='D')) stack_used+=4; - else if (*scan=='F') free_flags=true; -#endif - pindex++; - } - ops++; - } - -#if defined (MACOSX) - /* align stack */ - stack_used+=4; // saving esp on stack as well - - cache_addw(0xc48b); // mov eax,esp - cache_addb(0x2d); // sub eax,stack_used - cache_addd(stack_used); - cache_addw(0xe083); // and eax,0xfffffff0 - cache_addb(0xf0); - cache_addb(0x05); // sub eax,stack_used - cache_addd(stack_used); - cache_addb(0x94); // xchg eax,esp - if (free_flags) { - cache_addw(0xc083); // add eax,4 - cache_addb(0x04); - } - cache_addb(0x50); // push eax (==old esp) -#endif - - paramcount=0; - while (pindex) { - pindex--; - const char * scan=pinfo[pindex].line; - switch (*scan++) { - case 'I': /* immediate value */ - paramcount++; - cache_addb(0x68); //Push immediate - cache_addd(pinfo[pindex].value); //Push value - break; - case 'D': /* Dynamic register */ - { - bool release=false; - paramcount++; - DynReg * dynreg=(DynReg *)pinfo[pindex].value; - GenReg * genreg=FindDynReg(dynreg); - scanagain: - switch (*scan++) { - case 'd': - cache_addb(0x50+genreg->index); //Push reg - break; - case 'w': - cache_addw(0xb70f); //MOVZX EAX,reg - cache_addb(0xc0+genreg->index); - cache_addb(0x50); //Push EAX - break; - case 'l': - cache_addw(0xb60f); //MOVZX EAX,reg[0] - cache_addb(0xc0+genreg->index); - cache_addb(0x50); //Push EAX - break; - case 'h': - cache_addw(0xb60f); //MOVZX EAX,reg[1] - cache_addb(0xc4+genreg->index); - cache_addb(0x50); //Push EAX - break; - case 'r': /* release the reg afterwards */ - release=true; - goto scanagain; - default: - IllegalOption("gen_call_function param:DREG"); - } - if (release) gen_releasereg(dynreg); - } - break; - case 'R': /* Dynamic register to get the return value */ - retparam =&pinfo[pindex]; - pinfo[pindex].line=scan; - break; - case 'F': /* Release flags from stack */ - release_flags=true; - break; - default: - IllegalOption("gen_call_function unknown param"); - } - } -#if defined (MACOSX) - if (free_flags) release_flags=false; - } else { - /* align stack */ - Bit32u stack_used=8; // saving esp and return address on the stack - - cache_addw(0xc48b); // mov eax,esp - cache_addb(0x2d); // sub eax,stack_used - cache_addd(stack_used); - cache_addw(0xe083); // and eax,0xfffffff0 - cache_addb(0xf0); - cache_addb(0x05); // sub eax,stack_used - cache_addd(stack_used); - cache_addb(0x94); // xchg eax,esp - cache_addb(0x50); // push esp (==old esp) -#endif - } - - /* Clear some unprotected registers */ - x86gen.regs[X86_REG_ECX]->Clear(); - x86gen.regs[X86_REG_EDX]->Clear(); - /* Do the actual call to the procedure */ - cache_addb(0xe8); - cache_addd((Bit32u)func - (Bit32u)cache.pos-4); - /* Restore the params of the stack */ - if (paramcount) { - cache_addw(0xc483); //add ESP,imm byte - cache_addb(paramcount*4+(release_flags?4:0)); - } else if (release_flags) { - cache_addw(0xc483); //add ESP,imm byte - cache_addb(4); - } - /* Save the return value in correct register */ - if (retparam) { - DynReg * dynreg=(DynReg *)retparam->value; - GenReg * genreg=FindDynReg(dynreg); - if (genreg->index) // test for (e)ax/al - switch (*retparam->line) { - case 'd': - cache_addw(0xc08b+(genreg->index <<(8+3))); //mov reg,eax - break; - case 'w': - cache_addb(0x66); - cache_addw(0xc08b+(genreg->index <<(8+3))); //mov reg,eax - break; - case 'l': - cache_addw(0xc08a+(genreg->index <<(8+3))); //mov reg,eax - break; - case 'h': - cache_addw(0xc08a+((genreg->index+4) <<(8+3))); //mov reg,eax - break; - } - dynreg->flags|=DYNFLG_CHANGED; - } - /* Restore EAX registers to be used again */ - x86gen.regs[X86_REG_EAX]->notusable=false; - -#if defined (MACOSX) - /* restore stack */ - cache_addb(0x5c); // pop esp -#endif -} - -static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) { - /* Clear the EAX Genreg for usage */ - x86gen.regs[X86_REG_EAX]->Clear(); - x86gen.regs[X86_REG_EAX]->notusable=true; - gen_protectflags(); - -#if defined (MACOSX) - /* align stack */ - Bitu stack_used=12; - - cache_addw(0xc48b); // mov eax,esp - cache_addb(0x2d); // sub eax,stack_used - cache_addd(stack_used); - cache_addw(0xe083); // and eax,0xfffffff0 - cache_addb(0xf0); - cache_addb(0x05); // sub eax,stack_used - cache_addd(stack_used); - cache_addb(0x94); // xchg eax,esp - cache_addb(0x50); // push eax (==old esp) -#endif - - cache_addb(0x68); //PUSH val - cache_addd(val); - GenReg * genreg=FindDynReg(dr); - cache_addb(0x50+genreg->index); //PUSH reg - - /* Clear some unprotected registers */ - x86gen.regs[X86_REG_ECX]->Clear(); - x86gen.regs[X86_REG_EDX]->Clear(); - /* Do the actual call to the procedure */ - cache_addb(0xe8); - switch (write_size) { - case 1: cache_addd((Bit32u)mem_writeb_checked - (Bit32u)cache.pos-4); break; - case 2: cache_addd((Bit32u)mem_writew_checked - (Bit32u)cache.pos-4); break; - case 4: cache_addd((Bit32u)mem_writed_checked - (Bit32u)cache.pos-4); break; - default: IllegalOption("gen_call_write"); - } - - cache_addw(0xc483); //ADD ESP,8 - cache_addb(2*4); - x86gen.regs[X86_REG_EAX]->notusable=false; - gen_releasereg(dr); - -#if defined (MACOSX) - /* restore stack */ - cache_addb(0x5c); // pop esp -#endif -} - -static Bit8u * gen_create_branch(BranchTypes type) { - /* First free all registers */ - cache_addw(0x70+type); - return (cache.pos-1); -} - -static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) { -#if C_DEBUG - Bits len=from-data; - if (len<0) len=-len; - if (len>126) LOG_MSG("Big jump %d",len); -#endif - *data=(from-data-1); -} - -static Bit8u * gen_create_branch_long(BranchTypes type) { - cache_addw(0x800f+(type<<8)); - cache_addd(0); - return (cache.pos-4); -} - -static void gen_fill_branch_long(Bit8u * data,Bit8u * from=cache.pos) { - *(Bit32u*)data=(from-data-4); -} - -static Bit8u * gen_create_jump(Bit8u * to=0) { - /* First free all registers */ - cache_addb(0xe9); - cache_addd(to-(cache.pos+4)); - return (cache.pos-4); -} - -static void gen_fill_jump(Bit8u * data,Bit8u * to=cache.pos) { - *(Bit32u*)data=(to-data-4); -} - - -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - cache_addb(0xa1); - cache_addd((Bit32u)ptr); - cache_addb(0xff); //JMP EA - if (!imm) { //NO EBP - cache_addb(0x20); - } else if ((imm>=-128 && imm<=127)) { - cache_addb(0x60); - cache_addb(imm); - } else { - cache_addb(0xa0); - cache_addd(imm); - } -} - -static void gen_save_flags(DynReg * dynreg) { - if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_save_flags"); - GenReg * genreg=FindDynReg(dynreg); - cache_addb(0x8b); //MOV REG,[esp] - cache_addw(0x2404+(genreg->index << 3)); - dynreg->flags|=DYNFLG_CHANGED; -} - -static void gen_load_flags(DynReg * dynreg) { - if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_load_flags"); - cache_addw(0xc483); //ADD ESP,4 - cache_addb(0x4); - GenReg * genreg=FindDynReg(dynreg); - cache_addb(0x50+genreg->index); //PUSH 32 -} - -static void gen_save_host_direct(void * data,Bits imm) { - cache_addw(0x05c7); //MOV [],dword - cache_addd((Bit32u)data); - cache_addd(imm); -} - -static void gen_return(BlockReturn retcode) { - gen_protectflags(); - cache_addb(0x59); //POP ECX, the flags - if (retcode==0) cache_addw(0xc033); //MOV EAX, 0 - else { - cache_addb(0xb8); //MOV EAX, retcode - cache_addd(retcode); - } - cache_addb(0xc3); //RET -} - -static void gen_return_fast(BlockReturn retcode,bool ret_exception=false) { - if (GCC_UNLIKELY(x86gen.flagsactive)) IllegalOption("gen_return_fast"); - cache_addw(0x0d8b); //MOV ECX, the flags - cache_addd((Bit32u)&cpu_regs.flags); - if (!ret_exception) { - cache_addw(0xc483); //ADD ESP,4 - cache_addb(0x4); - if (retcode==0) cache_addw(0xc033); //MOV EAX, 0 - else { - cache_addb(0xb8); //MOV EAX, retcode - cache_addd(retcode); - } - } - cache_addb(0xc3); //RET -} - -static void gen_init(void) { - x86gen.regs[X86_REG_EAX]=new GenReg(0); - x86gen.regs[X86_REG_ECX]=new GenReg(1); - x86gen.regs[X86_REG_EDX]=new GenReg(2); - x86gen.regs[X86_REG_EBX]=new GenReg(3); - x86gen.regs[X86_REG_EBP]=new GenReg(5); - x86gen.regs[X86_REG_ESI]=new GenReg(6); - x86gen.regs[X86_REG_EDI]=new GenReg(7); -} - - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/string.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/string.h deleted file mode 100644 index 93f69e4ed..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dyn_x86/string.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -enum STRING_OP { - STR_OUTSB=0,STR_OUTSW,STR_OUTSD, - STR_INSB=4,STR_INSW,STR_INSD, - STR_MOVSB=8,STR_MOVSW,STR_MOVSD, - STR_LODSB=12,STR_LODSW,STR_LODSD, - STR_STOSB=16,STR_STOSW,STR_STOSD, - STR_SCASB=20,STR_SCASW,STR_SCASD, - STR_CMPSB=24,STR_CMPSW,STR_CMPSD -}; - -static void dyn_string(STRING_OP op) { - DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS); - DynReg * di_base=DREG(ES); - DynReg * tmp_reg;bool usesi;bool usedi; - gen_protectflags(); - if (decode.rep) { - gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles); - gen_releasereg(DREG(CYCLES)); - decode.cycles=0; - } - /* Check what each string operation will be using */ - switch (op) { - case STR_MOVSB: case STR_MOVSW: case STR_MOVSD: - case STR_CMPSB: case STR_CMPSW: case STR_CMPSD: - tmp_reg=DREG(TMPB);usesi=true;usedi=true;break; - case STR_LODSB: case STR_LODSW: case STR_LODSD: - tmp_reg=DREG(EAX);usesi=true;usedi=false;break; - case STR_OUTSB: case STR_OUTSW: case STR_OUTSD: - tmp_reg=DREG(TMPB);usesi=true;usedi=false;break; - case STR_SCASB: case STR_SCASW: case STR_SCASD: - case STR_STOSB: case STR_STOSW: case STR_STOSD: - tmp_reg=DREG(EAX);usesi=false;usedi=true;break; - case STR_INSB: case STR_INSW: case STR_INSD: - tmp_reg=DREG(TMPB);usesi=false;usedi=true;break; - default: - IllegalOption("dyn_string op"); - } - gen_load_host(&cpu.direction,DREG(TMPW),4); - switch (op & 3) { - case 0:break; - case 1:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),1);break; - case 2:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),2);break; - default: - IllegalOption("dyn_string shift"); - - } - if (usesi) { - gen_preloadreg(DREG(ESI)); - DynRegs[G_ESI].flags|=DYNFLG_CHANGED; - gen_preloadreg(si_base); - } - if (usedi) { - gen_preloadreg(DREG(EDI)); - DynRegs[G_EDI].flags|=DYNFLG_CHANGED; - gen_preloadreg(di_base); - } - if (decode.rep) { - gen_preloadreg(DREG(ECX)); - DynRegs[G_ECX].flags|=DYNFLG_CHANGED; - } - DynState rep_state; - dyn_savestate(&rep_state); - Bit8u * rep_start=cache.pos; - Bit8u * rep_ecx_jmp; - /* Check if ECX!=zero */ - if (decode.rep) { - gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX)); - rep_ecx_jmp=gen_create_branch_long(BR_Z); - } - if (usesi) { - if (!decode.big_addr) { - gen_extend_word(false,DREG(EA),DREG(ESI)); - gen_lea(DREG(EA),si_base,DREG(EA),0,0); - } else { - gen_lea(DREG(EA),si_base,DREG(ESI),0,0); - } - switch (op&3) { - case 0:dyn_read_byte(DREG(EA),tmp_reg,false);break; - case 1:dyn_read_word(DREG(EA),tmp_reg,false);break; - case 2:dyn_read_word(DREG(EA),tmp_reg,true);break; - } - switch (op) { - case STR_OUTSB: - gen_call_function((void*)&IO_WriteB,"%Id%Dl",DREG(EDX),tmp_reg);break; - case STR_OUTSW: - gen_call_function((void*)&IO_WriteW,"%Id%Dw",DREG(EDX),tmp_reg);break; - case STR_OUTSD: - gen_call_function((void*)&IO_WriteD,"%Id%Dd",DREG(EDX),tmp_reg);break; - } - } - if (usedi) { - if (!decode.big_addr) { - gen_extend_word(false,DREG(EA),DREG(EDI)); - gen_lea(DREG(EA),di_base,DREG(EA),0,0); - } else { - gen_lea(DREG(EA),di_base,DREG(EDI),0,0); - } - /* Maybe something special to be done to fill the value */ - switch (op) { - case STR_INSB: - gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),tmp_reg); - case STR_MOVSB: - case STR_STOSB: - dyn_write_byte(DREG(EA),tmp_reg,false); - break; - case STR_INSW: - gen_call_function((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),tmp_reg); - case STR_MOVSW: - case STR_STOSW: - dyn_write_word(DREG(EA),tmp_reg,false); - break; - case STR_INSD: - gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),tmp_reg); - case STR_MOVSD: - case STR_STOSD: - dyn_write_word(DREG(EA),tmp_reg,true); - break; - default: - IllegalOption("dyn_string op"); - } - } - gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB)); - - /* update registers */ - if (usesi) gen_dop_word(DOP_ADD,decode.big_addr,DREG(ESI),DREG(TMPW)); - if (usedi) gen_dop_word(DOP_ADD,decode.big_addr,DREG(EDI),DREG(TMPW)); - - if (decode.rep) { - gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX)); - gen_sop_word(SOP_DEC,true,DREG(CYCLES)); - gen_releasereg(DREG(CYCLES)); - dyn_savestate(&save_info[used_save_info].state); - save_info[used_save_info].branch_pos=gen_create_branch_long(BR_LE); - save_info[used_save_info].eip_change=decode.op_start-decode.code_start; - save_info[used_save_info].type=normal; - used_save_info++; - - /* Jump back to start of ECX check */ - dyn_synchstate(&rep_state); - gen_create_jump(rep_start); - - dyn_loadstate(&rep_state); - gen_fill_branch_long(rep_ecx_jmp); - } - gen_releasereg(DREG(TMPW)); -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec.cpp deleted file mode 100644 index 1571fb43a..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include "dosbox.h" - -#if (C_DYNREC) - -#include -#include -#include -#include -#include -#include - -#if defined (WIN32) -#include -#include -#endif - -#if (C_HAVE_MPROTECT) -#include - -#include -#ifndef PAGESIZE -#define PAGESIZE 4096 -#endif -#endif /* C_HAVE_MPROTECT */ - -#include "callback.h" -#include "regs.h" -#include "mem.h" -#include "cpu.h" -#include "debug.h" -#include "paging.h" -#include "inout.h" -#include "lazyflags.h" -#include "pic.h" - -#define CACHE_MAXSIZE (4096*2) -#define CACHE_TOTAL (1024*1024*8) -#define CACHE_PAGES (512) -#define CACHE_BLOCKS (128*1024) -#define CACHE_ALIGN (16) -#define DYN_HASH_SHIFT (4) -#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT) -#define DYN_LINKS (16) - - -//#define DYN_LOG 1 //Turn Logging on. - - -#if C_FPU -#define CPU_FPU 1 //Enable FPU escape instructions -#endif - - -// the emulated x86 registers -#define DRC_REG_EAX 0 -#define DRC_REG_ECX 1 -#define DRC_REG_EDX 2 -#define DRC_REG_EBX 3 -#define DRC_REG_ESP 4 -#define DRC_REG_EBP 5 -#define DRC_REG_ESI 6 -#define DRC_REG_EDI 7 - -// the emulated x86 segment registers -#define DRC_SEG_ES 0 -#define DRC_SEG_CS 1 -#define DRC_SEG_SS 2 -#define DRC_SEG_DS 3 -#define DRC_SEG_FS 4 -#define DRC_SEG_GS 5 - - -// access to a general register -#define DRCD_REG_VAL(reg) (&cpu_regs.regs[reg].dword) -// access to a segment register -#define DRCD_SEG_VAL(seg) (&Segs.val[seg]) -// access to the physical value of a segment register/selector -#define DRCD_SEG_PHYS(seg) (&Segs.phys[seg]) - -// access to an 8bit general register -#define DRCD_REG_BYTE(reg,idx) (&cpu_regs.regs[reg].byte[idx?BH_INDEX:BL_INDEX]) -// access to 16/32bit general registers -#define DRCD_REG_WORD(reg,dwrd) ((dwrd)?((void*)(&cpu_regs.regs[reg].dword[DW_INDEX])):((void*)(&cpu_regs.regs[reg].word[W_INDEX]))) - - -enum BlockReturn { - BR_Normal=0, - BR_Cycles, - BR_Link1,BR_Link2, - BR_Opcode, -#if (C_DEBUG) - BR_OpcodeFull, -#endif - BR_Iret, - BR_CallBack, - BR_SMCBlock -}; - -// identificator to signal self-modification of the currently executed block -#define SMC_CURRENT_BLOCK 0xffff - - -static void IllegalOptionDynrec(const char* msg) { - E_Exit("DynrecCore: illegal option in %s",msg); -} - -static struct { - BlockReturn (*runcode)(Bit8u*); // points to code that can start a block - Bitu callback; // the occurred callback - Bitu readdata; // spare space used when reading from memory - Bit32u protected_regs[8]; // space to save/restore register values -} core_dynrec; - - -#include "core_dynrec/cache.h" - -#define X86 0x01 -#define X86_64 0x02 -#define MIPSEL 0x03 -#define ARMV4LE 0x04 -#define ARMV7LE 0x05 -#define POWERPC 0x04 - -#if C_TARGETCPU == X86_64 -#include "core_dynrec/risc_x64.h" -#elif C_TARGETCPU == X86 -#include "core_dynrec/risc_x86.h" -#elif C_TARGETCPU == MIPSEL -#include "core_dynrec/risc_mipsel32.h" -#elif (C_TARGETCPU == ARMV4LE) || (C_TARGETCPU == ARMV7LE) -#include "core_dynrec/risc_armv4le.h" -#elif C_TARGETCPU == POWERPC -#include "core_dynrec/risc_ppc.h" -#endif - -#include "core_dynrec/decoder.h" - -CacheBlockDynRec * LinkBlocks(BlockReturn ret) { - CacheBlockDynRec * block=NULL; - // the last instruction was a control flow modifying instruction - Bitu temp_ip=SegPhys(cs)+reg_eip; - CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_readhandler(temp_ip); - if (temp_handler->flags & PFLAG_HASCODE) { - // see if the target is an already translated block - block=temp_handler->FindCacheBlock(temp_ip & 4095); - if (!block) return NULL; - - // found it, link the current block to - cache.block.running->LinkTo(ret==BR_Link2,block); - return block; - } - return NULL; -} - -/* - The core tries to find the block that should be executed next. - If such a block is found, it is run, otherwise the instruction - stream starting at ip_point is translated (see decoder.h) and - makes up a new code block that will be run. - When control is returned to CPU_Core_Dynrec_Run (which might - be right after the block is run, or somewhen long after that - due to the direct cacheblock linking) the returncode decides - the next action. This might be continuing the translation and - execution process, or returning from the core etc. -*/ - -Bits CPU_Core_Dynrec_Run(void) { - for (;;) { - // Determine the linear address of CS:EIP - PhysPt ip_point=SegPhys(cs)+reg_eip; - #if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; - #endif - - CodePageHandlerDynRec * chandler=0; - // see if the current page is present and contains code - if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) { - // page not present, throw the exception - CPU_Exception(cpu.exception.which,cpu.exception.error); - continue; - } - - // page doesn't contain code or is special - if (GCC_UNLIKELY(!chandler)) return CPU_Core_Normal_Run(); - - // find correct Dynamic Block to run - CacheBlockDynRec * block=chandler->FindCacheBlock(ip_point&4095); - if (!block) { - // no block found, thus translate the instruction stream - // unless the instruction is known to be modified - if (!chandler->invalidation_map || (chandler->invalidation_map[ip_point&4095]<4)) { - // translate up to 32 instructions - block=CreateCacheBlock(chandler,ip_point,32); - } else { - // let the normal core handle this instruction to avoid zero-sized blocks - Bitu old_cycles=CPU_Cycles; - CPU_Cycles=1; - Bits nc_retcode=CPU_Core_Normal_Run(); - if (!nc_retcode) { - CPU_Cycles=old_cycles-1; - continue; - } - CPU_CycleLeft+=old_cycles; - return nc_retcode; - } - } - -run_block: - cache.block.running=0; - // now we're ready to run the dynamic code block -// BlockReturn ret=((BlockReturn (*)(void))(block->cache.start))(); - BlockReturn ret=core_dynrec.runcode(block->cache.start); - - switch (ret) { - case BR_Iret: -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif -#endif - if (!GETFLAG(TF)) { - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; - break; - } - // trapflag is set, switch to the trap-aware decoder - cpudecoder=CPU_Core_Dynrec_Trap_Run; - return CBRET_NONE; - - case BR_Normal: - // the block was exited due to a non-predictable control flow - // modifying instruction (like ret) or some nontrivial cpu state - // changing instruction (for example switch to/from pmode), - // or the maximum number of instructions to translate was reached -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif -#endif - break; - - case BR_Cycles: - // cycles went negative, return from the core to handle - // external events, schedule the pic... -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) return debugCallback; -#endif -#endif - return CBRET_NONE; - - case BR_CallBack: - // the callback code is executed in dosbox.conf, return the callback number - FillFlags(); - return core_dynrec.callback; - - case BR_SMCBlock: -// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip); - cpu.exception.which=0; - // fallthrough, let the normal core handle the block-modifying instruction - case BR_Opcode: - // some instruction has been encountered that could not be translated - // (thus it is not part of the code block), the normal core will - // handle this instruction - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=1; - return CPU_Core_Normal_Run(); - -#if (C_DEBUG) - case BR_OpcodeFull: - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=1; - return CPU_Core_Full_Run(); -#endif - - case BR_Link1: - case BR_Link2: - block=LinkBlocks(ret); - if (block) goto run_block; - break; - - default: - E_Exit("Invalid return code %d", ret); - } - } - return CBRET_NONE; -} - -Bits CPU_Core_Dynrec_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - cpu.trap_skip = false; - - // let the normal core execute the next (only one!) instruction - Bits ret=CPU_Core_Normal_Run(); - - // trap to int1 unless the last instruction deferred this - // (allows hardware interrupts to be served without interaction) - if (!cpu.trap_skip) CPU_HW_Interrupt(1); - - CPU_Cycles = oldCycles-1; - // continue (either the trapflag was clear anyways, or the int1 cleared it) - cpudecoder = &CPU_Core_Dynrec_Run; - - return ret; -} - -void CPU_Core_Dynrec_Init(void) { -} - -void CPU_Core_Dynrec_Cache_Init(bool enable_cache) { - // Initialize code cache and dynamic blocks - cache_init(enable_cache); -} - -void CPU_Core_Dynrec_Cache_Close(void) { - cache_close(); -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/Makefile.am b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/Makefile.am deleted file mode 100644 index 288b9154f..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \ - dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h \ - risc_armv4le.h risc_armv4le-common.h \ - risc_armv4le-o3.h risc_armv4le-thumb.h \ - risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/Makefile.in b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/Makefile.in deleted file mode 100644 index 513aafc72..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/Makefile.in +++ /dev/null @@ -1,494 +0,0 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/cpu/core_dynrec -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -WINDRES = @WINDRES@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \ - dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h \ - risc_armv4le.h risc_armv4le-common.h \ - risc_armv4le-o3.h risc_armv4le-thumb.h \ - risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/cpu/core_dynrec/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/cpu/core_dynrec/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - cscopelist-am ctags ctags-am distclean distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/cache.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/cache.h deleted file mode 100644 index 7d7a6efd6..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/cache.h +++ /dev/null @@ -1,665 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -class CodePageHandlerDynRec; // forward - -// basic cache block representation -class CacheBlockDynRec { -public: - void Clear(void); - // link this cache block to another block, index specifies the code - // path (always zero for unconditional links, 0/1 for conditional ones - void LinkTo(Bitu index,CacheBlockDynRec * toblock) { - assert(toblock); - link[index].to=toblock; - link[index].next=toblock->link[index].from; // set target block - toblock->link[index].from=this; // remember who links me - } - struct { - Bit16u start,end; // where in the page is the original code - CodePageHandlerDynRec * handler; // page containing this code - } page; - struct { - Bit8u * start; // where in the cache are we - Bitu size; - CacheBlockDynRec * next; - // writemap masking maskpointer/start/length - // to allow holes in the writemap - Bit8u * wmapmask; - Bit16u maskstart; - Bit16u masklen; - } cache; - struct { - Bitu index; - CacheBlockDynRec * next; - } hash; - struct { - CacheBlockDynRec * to; // this block can transfer control to the to-block - CacheBlockDynRec * next; - CacheBlockDynRec * from; // the from-block can transfer control to this block - } link[2]; // maximum two links (conditional jumps) - CacheBlockDynRec * crossblock; -}; - -static struct { - struct { - CacheBlockDynRec * first; // the first cache block in the list - CacheBlockDynRec * active; // the current cache block - CacheBlockDynRec * free; // pointer to the free list - CacheBlockDynRec * running; // the last block that was entered for execution - } block; - Bit8u * pos; // position in the cache block - CodePageHandlerDynRec * free_pages; // pointer to the free list - CodePageHandlerDynRec * used_pages; // pointer to the list of used pages - CodePageHandlerDynRec * last_page; // the last used page -} cache; - - -// cache memory pointers, to be malloc'd later -static Bit8u * cache_code_start_ptr=NULL; -static Bit8u * cache_code=NULL; -static Bit8u * cache_code_link_blocks=NULL; - -static CacheBlockDynRec * cache_blocks=NULL; -static CacheBlockDynRec link_blocks[2]; // default linking (specially marked) - - -// the CodePageHandlerDynRec class provides access to the contained -// cache blocks and intercepts writes to the code for special treatment -class CodePageHandlerDynRec : public PageHandler { -public: - CodePageHandlerDynRec() { - invalidation_map=NULL; - } - - void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) { - // initialize this codepage handler - phys_page=_phys_page; - // save the old pagehandler to provide direct read access to the memory, - // and to be able to restore it later on - old_pagehandler=_old_pagehandler; - - // adjust flags - flags=old_pagehandler->flags|PFLAG_HASCODE; - flags&=~PFLAG_WRITEABLE; - - active_blocks=0; - active_count=16; - - // initialize the maps with zero (no cache blocks as well as code present) - memset(&hash_map,0,sizeof(hash_map)); - memset(&write_map,0,sizeof(write_map)); - if (invalidation_map!=NULL) { - free(invalidation_map); - invalidation_map=NULL; - } - } - - // clear out blocks that contain code which has been modified - bool InvalidateRange(Bitu start,Bitu end) { - Bits index=1+(end>>DYN_HASH_SHIFT); - bool is_current_block=false; // if the current block is modified, it has to be exited as soon as possible - - Bit32u ip_point=SegPhys(cs)+reg_eip; - ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff); - while (index>=0) { - Bitu map=0; - // see if there is still some code in the range - for (Bitu count=start;count<=end;count++) map+=write_map[count]; - if (!map) return is_current_block; // no more code, finished - - CacheBlockDynRec * block=hash_map[index]; - while (block) { - CacheBlockDynRec * nextblock=block->hash.next; - // test if this block is in the range - if (start<=block->page.end && end>=block->page.start) { - if (ip_point<=block->page.end && ip_point>=block->page.start) is_current_block=true; - block->Clear(); // clear the block, decrements the write_map accordingly - } - block=nextblock; - } - index--; - } - return is_current_block; - } - - // the following functions will clean all cache blocks that are invalid now due to the write - void writeb(PhysPt addr,Bitu val){ - addr&=4095; - if (host_readb(hostmem+addr)==(Bit8u)val) return; - host_writeb(hostmem+addr,val); - // see if there's code where we are writing to - if (!host_readb(&write_map[addr])) { - if (active_blocks) return; // still some blocks in this page - active_count--; - if (!active_count) Release(); // delay page releasing until active_count is zero - return; - } else if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - invalidation_map[addr]++; - InvalidateRange(addr,addr); - } - void writew(PhysPt addr,Bitu val){ - addr&=4095; - if (host_readw(hostmem+addr)==(Bit16u)val) return; - host_writew(hostmem+addr,val); - // see if there's code where we are writing to - if (!host_readw(&write_map[addr])) { - if (active_blocks) return; // still some blocks in this page - active_count--; - if (!active_count) Release(); // delay page releasing until active_count is zero - return; - } else if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - host_writew(&invalidation_map[addr], - host_readw(&invalidation_map[addr])+0x101); -#else - (*(Bit16u*)&invalidation_map[addr])+=0x101; -#endif - InvalidateRange(addr,addr+1); - } - void writed(PhysPt addr,Bitu val){ - addr&=4095; - if (host_readd(hostmem+addr)==(Bit32u)val) return; - host_writed(hostmem+addr,val); - // see if there's code where we are writing to - if (!host_readd(&write_map[addr])) { - if (active_blocks) return; // still some blocks in this page - active_count--; - if (!active_count) Release(); // delay page releasing until active_count is zero - return; - } else if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - host_writed(&invalidation_map[addr], - host_readd(&invalidation_map[addr])+0x1010101); -#else - (*(Bit32u*)&invalidation_map[addr])+=0x1010101; -#endif - InvalidateRange(addr,addr+3); - } - bool writeb_checked(PhysPt addr,Bitu val) { - addr&=4095; - if (host_readb(hostmem+addr)==(Bit8u)val) return false; - // see if there's code where we are writing to - if (!host_readb(&write_map[addr])) { - if (!active_blocks) { - // no blocks left in this page, still delay the page releasing a bit - active_count--; - if (!active_count) Release(); - } - } else { - if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } - invalidation_map[addr]++; - if (InvalidateRange(addr,addr)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; - } - } - host_writeb(hostmem+addr,val); - return false; - } - bool writew_checked(PhysPt addr,Bitu val) { - addr&=4095; - if (host_readw(hostmem+addr)==(Bit16u)val) return false; - // see if there's code where we are writing to - if (!host_readw(&write_map[addr])) { - if (!active_blocks) { - // no blocks left in this page, still delay the page releasing a bit - active_count--; - if (!active_count) Release(); - } - } else { - if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - host_writew(&invalidation_map[addr], - host_readw(&invalidation_map[addr])+0x101); -#else - (*(Bit16u*)&invalidation_map[addr])+=0x101; -#endif - if (InvalidateRange(addr,addr+1)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; - } - } - host_writew(hostmem+addr,val); - return false; - } - bool writed_checked(PhysPt addr,Bitu val) { - addr&=4095; - if (host_readd(hostmem+addr)==(Bit32u)val) return false; - // see if there's code where we are writing to - if (!host_readd(&write_map[addr])) { - if (!active_blocks) { - // no blocks left in this page, still delay the page releasing a bit - active_count--; - if (!active_count) Release(); - } - } else { - if (!invalidation_map) { - invalidation_map=(Bit8u*)malloc(4096); - memset(invalidation_map,0,4096); - } -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - host_writed(&invalidation_map[addr], - host_readd(&invalidation_map[addr])+0x1010101); -#else - (*(Bit32u*)&invalidation_map[addr])+=0x1010101; -#endif - if (InvalidateRange(addr,addr+3)) { - cpu.exception.which=SMC_CURRENT_BLOCK; - return true; - } - } - host_writed(hostmem+addr,val); - return false; - } - - // add a cache block to this page and note it in the hash map - void AddCacheBlock(CacheBlockDynRec * block) { - Bitu index=1+(block->page.start>>DYN_HASH_SHIFT); - block->hash.next=hash_map[index]; // link to old block at index from the new block - block->hash.index=index; - hash_map[index]=block; // put new block at hash position - block->page.handler=this; - active_blocks++; - } - // there's a block whose code started in a different page - void AddCrossBlock(CacheBlockDynRec * block) { - block->hash.next=hash_map[0]; - block->hash.index=0; - hash_map[0]=block; - block->page.handler=this; - active_blocks++; - } - // remove a cache block - void DelCacheBlock(CacheBlockDynRec * block) { - active_blocks--; - active_count=16; - CacheBlockDynRec * * bwhere=&hash_map[block->hash.index]; - while (*bwhere!=block) { - bwhere=&((*bwhere)->hash.next); - //Will crash if a block isn't found, which should never happen. - } - *bwhere=block->hash.next; - - // remove the cleared block from the write map - if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) { - // first part is not influenced by the mask - for (Bitu i=block->page.start;icache.maskstart;i++) { - if (write_map[i]) write_map[i]--; - } - Bitu maskct=0; - // last part sticks to the writemap mask - for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) { - if (write_map[i]) { - // only adjust writemap if it isn't masked - if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--; - } - } - free(block->cache.wmapmask); - block->cache.wmapmask=NULL; - } else { - for (Bitu i=block->page.start;i<=block->page.end;i++) { - if (write_map[i]) write_map[i]--; - } - } - } - - void Release(void) { - MEM_SetPageHandler(phys_page,1,old_pagehandler); // revert to old handler - PAGING_ClearTLB(); - - // remove page from the lists - if (prev) prev->next=next; - else cache.used_pages=next; - if (next) next->prev=prev; - else cache.last_page=prev; - next=cache.free_pages; - cache.free_pages=this; - prev=0; - } - void ClearRelease(void) { - // clear out all cache blocks in this page - for (Bitu index=0;index<(1+DYN_PAGE_HASH);index++) { - CacheBlockDynRec * block=hash_map[index]; - while (block) { - CacheBlockDynRec * nextblock=block->hash.next; - block->page.handler=0; // no need, full clear - block->Clear(); - block=nextblock; - } - } - Release(); // now can release this page - } - - CacheBlockDynRec * FindCacheBlock(Bitu start) { - CacheBlockDynRec * block=hash_map[1+(start>>DYN_HASH_SHIFT)]; - // see if there's a cache block present at the start address - while (block) { - if (block->page.start==start) return block; // found - block=block->hash.next; - } - return 0; // none found - } - - HostPt GetHostReadPt(Bitu phys_page) { - hostmem=old_pagehandler->GetHostReadPt(phys_page); - return hostmem; - } - HostPt GetHostWritePt(Bitu phys_page) { - return GetHostReadPt( phys_page ); - } -public: - // the write map, there are write_map[i] cache blocks that cover the byte at address i - Bit8u write_map[4096]; - Bit8u * invalidation_map; - CodePageHandlerDynRec * next, * prev; // page linking -private: - PageHandler * old_pagehandler; - - // hash map to quickly find the cache blocks in this page - CacheBlockDynRec * hash_map[1+DYN_PAGE_HASH]; - - Bitu active_blocks; // the number of cache blocks in this page - Bitu active_count; // delaying parameter to not immediately release a page - HostPt hostmem; - Bitu phys_page; -}; - - -static INLINE void cache_addunusedblock(CacheBlockDynRec * block) { - // block has become unused, add it to the freelist - block->cache.next=cache.block.free; - cache.block.free=block; -} - -static CacheBlockDynRec * cache_getblock(void) { - // get a free cache block and advance the free pointer - CacheBlockDynRec * ret=cache.block.free; - if (!ret) E_Exit("Ran out of CacheBlocks" ); - cache.block.free=ret->cache.next; - ret->cache.next=0; - return ret; -} - -void CacheBlockDynRec::Clear(void) { - Bitu ind; - // check if this is not a cross page block - if (hash.index) for (ind=0;ind<2;ind++) { - CacheBlockDynRec * fromlink=link[ind].from; - link[ind].from=0; - while (fromlink) { - CacheBlockDynRec * nextlink=fromlink->link[ind].next; - // clear the next-link and let the block point to the standard linkcode - fromlink->link[ind].next=0; - fromlink->link[ind].to=&link_blocks[ind]; - - fromlink=nextlink; - } - if (link[ind].to!=&link_blocks[ind]) { - // not linked to the standard linkcode, find the block that links to this block - CacheBlockDynRec * * wherelink=&link[ind].to->link[ind].from; - while (*wherelink != this && *wherelink) { - wherelink = &(*wherelink)->link[ind].next; - } - // now remove the link - if(*wherelink) - *wherelink = (*wherelink)->link[ind].next; - else { - LOG(LOG_CPU,LOG_ERROR)("Cache anomaly. please investigate"); - } - } - } else - cache_addunusedblock(this); - if (crossblock) { - // clear out the crossblock (in the page before) as well - crossblock->crossblock=0; - crossblock->Clear(); - crossblock=0; - } - if (page.handler) { - // clear out the code page handler - page.handler->DelCacheBlock(this); - page.handler=0; - } - if (cache.wmapmask){ - free(cache.wmapmask); - cache.wmapmask=NULL; - } -} - - -static CacheBlockDynRec * cache_openblock(void) { - CacheBlockDynRec * block=cache.block.active; - // check for enough space in this block - Bitu size=block->cache.size; - CacheBlockDynRec * nextblock=block->cache.next; - if (block->page.handler) - block->Clear(); - // block size must be at least CACHE_MAXSIZE - while (sizecache.size; - CacheBlockDynRec * tempblock=nextblock->cache.next; - if (nextblock->page.handler) - nextblock->Clear(); - // block is free now - cache_addunusedblock(nextblock); - nextblock=tempblock; - } -skipresize: - // adjust parameters and open this block - block->cache.size=size; - block->cache.next=nextblock; - cache.pos=block->cache.start; - return block; -} - -static void cache_closeblock(void) { - CacheBlockDynRec * block=cache.block.active; - // links point to the default linking code - block->link[0].to=&link_blocks[0]; - block->link[1].to=&link_blocks[1]; - block->link[0].from=0; - block->link[1].from=0; - block->link[0].next=0; - block->link[1].next=0; - // close the block with correct alignment - Bitu written=(Bitu)(cache.pos-block->cache.start); - if (written>block->cache.size) { - if (!block->cache.next) { - if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun 1 %d",written-block->cache.size); - } else E_Exit("CacheBlock overrun 2 written %d size %d",written,block->cache.size); - } else { - Bitu new_size; - Bitu left=block->cache.size-written; - // smaller than cache align then don't bother to resize - if (left>CACHE_ALIGN) { - new_size=((written-1)|(CACHE_ALIGN-1))+1; - CacheBlockDynRec * newblock=cache_getblock(); - // align block now to CACHE_ALIGN - newblock->cache.start=block->cache.start+new_size; - newblock->cache.size=block->cache.size-new_size; - newblock->cache.next=block->cache.next; - block->cache.next=newblock; - block->cache.size=new_size; - } - } - // advance the active block pointer - if (!block->cache.next || (block->cache.next->cache.start>(cache_code_start_ptr + CACHE_TOTAL - CACHE_MAXSIZE))) { -// LOG_MSG("Cache full restarting"); - cache.block.active=cache.block.first; - } else { - cache.block.active=block->cache.next; - } -} - - -// place an 8bit value into the cache -static INLINE void cache_addb(Bit8u val) { - *cache.pos++=val; -} - -// place a 16bit value into the cache -static INLINE void cache_addw(Bit16u val) { - *(Bit16u*)cache.pos=val; - cache.pos+=2; -} - -// place a 32bit value into the cache -static INLINE void cache_addd(Bit32u val) { - *(Bit32u*)cache.pos=val; - cache.pos+=4; -} - -// place a 64bit value into the cache -static INLINE void cache_addq(Bit64u val) { - *(Bit64u*)cache.pos=val; - cache.pos+=8; -} - - -static void dyn_return(BlockReturn retcode,bool ret_exception); -static void dyn_run_code(void); - - -/* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */ -#if (C_HAVE_MPROTECT) -#define PAGESIZE_TEMP PAGESIZE -#else -#define PAGESIZE_TEMP 4096 -#endif - -static bool cache_initialized = false; - -static void cache_init(bool enable) { - Bits i; - if (enable) { - // see if cache is already initialized - if (cache_initialized) return; - cache_initialized = true; - if (cache_blocks == NULL) { - // allocate the cache blocks memory - cache_blocks=(CacheBlockDynRec*)malloc(CACHE_BLOCKS*sizeof(CacheBlockDynRec)); - if(!cache_blocks) E_Exit("Allocating cache_blocks has failed"); - memset(cache_blocks,0,sizeof(CacheBlockDynRec)*CACHE_BLOCKS); - cache.block.free=&cache_blocks[0]; - // initialize the cache blocks - for (i=0;icache.start=&cache_code[0]; - block->cache.size=CACHE_TOTAL; - block->cache.next=0; // last block in the list - } - // setup the default blocks for block linkage returns - cache.pos=&cache_code_link_blocks[0]; - link_blocks[0].cache.start=cache.pos; - // link code that returns with a special return code - dyn_return(BR_Link1,false); - cache.pos=&cache_code_link_blocks[32]; - link_blocks[1].cache.start=cache.pos; - // link code that returns with a special return code - dyn_return(BR_Link2,false); - - cache.pos=&cache_code_link_blocks[64]; - core_dynrec.runcode=(BlockReturn (*)(Bit8u*))cache.pos; -// link_blocks[1].cache.start=cache.pos; - dyn_run_code(); - - cache.free_pages=0; - cache.last_page=0; - cache.used_pages=0; - // setup the code pages - for (i=0;inext=cache.free_pages; - cache.free_pages=newpage; - } - } -} - -static void cache_close(void) { -/* for (;;) { - if (cache.used_pages) { - CodePageHandler * cpage=cache.used_pages; - CodePageHandler * npage=cache.used_pages->next; - cpage->ClearRelease(); - delete cpage; - cache.used_pages=npage; - } else break; - } - if (cache_blocks != NULL) { - free(cache_blocks); - cache_blocks = NULL; - } - if (cache_code_start_ptr != NULL) { - ### care: under windows VirtualFree() has to be used if - ### VirtualAlloc was used for memory allocation - free(cache_code_start_ptr); - cache_code_start_ptr = NULL; - } - cache_code = NULL; - cache_code_link_blocks = NULL; - cache_initialized = false; */ -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/decoder.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/decoder.h deleted file mode 100644 index 9c1fe4996..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/decoder.h +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -#include "decoder_basic.h" -#include "operators.h" -#include "decoder_opcodes.h" - -#include "dyn_fpu.h" - -/* - The function CreateCacheBlock translates the instruction stream - until either an unhandled instruction is found, the maximum - number of translated instructions is reached or some critical - instruction is encountered. -*/ - -static CacheBlockDynRec * CreateCacheBlock(CodePageHandlerDynRec * codepage,PhysPt start,Bitu max_opcodes) { - // initialize a load of variables - decode.code_start=start; - decode.code=start; - decode.page.code=codepage; - decode.page.index=start&4095; - decode.page.wmap=codepage->write_map; - decode.page.invmap=codepage->invalidation_map; - decode.page.first=start >> 12; - decode.active_block=decode.block=cache_openblock(); - decode.block->page.start=(Bit16u)decode.page.index; - codepage->AddCacheBlock(decode.block); - - InitFlagsOptimization(); - - // every codeblock that is run sets cache.block.running to itself - // so the block linking knows the last executed block - gen_mov_direct_ptr(&cache.block.running,(DRC_PTR_SIZE_IM)decode.block); - - // start with the cycles check - gen_mov_word_to_reg(FC_RETOP,&CPU_Cycles,true); - save_info_dynrec[used_save_info_dynrec].branch_pos=gen_create_branch_long_leqzero(FC_RETOP); - save_info_dynrec[used_save_info_dynrec].type=cycle_check; - used_save_info_dynrec++; - - decode.cycles=0; - while (max_opcodes--) { - // Init prefixes - decode.big_addr=cpu.code.big; - decode.big_op=cpu.code.big; - decode.seg_prefix=0; - decode.seg_prefix_used=false; - decode.rep=REP_NONE; - decode.cycles++; - decode.op_start=decode.code; -restart_prefix: - Bitu opcode; - if (!decode.page.invmap) opcode=decode_fetchb(); - else { - // some entries in the invalidation map, see if the next - // instruction is known to be modified a lot - if (decode.page.index<4096) { - if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode; - opcode=decode_fetchb(); - } else { - // switch to the next page - opcode=decode_fetchb(); - if (GCC_UNLIKELY(decode.page.invmap && - (decode.page.invmap[decode.page.index-1]>=4))) goto illegalopcode; - } - } - switch (opcode) { - // instructions 'op reg8,reg8' and 'op [],reg8' - case 0x00:dyn_dop_ebgb(DOP_ADD);break; - case 0x08:dyn_dop_ebgb(DOP_OR);break; - case 0x10:dyn_dop_ebgb(DOP_ADC);break; - case 0x18:dyn_dop_ebgb(DOP_SBB);break; - case 0x20:dyn_dop_ebgb(DOP_AND);break; - case 0x28:dyn_dop_ebgb(DOP_SUB);break; - case 0x30:dyn_dop_ebgb(DOP_XOR);break; - case 0x38:dyn_dop_ebgb(DOP_CMP);break; - - // instructions 'op reg8,reg8' and 'op reg8,[]' - case 0x02:dyn_dop_gbeb(DOP_ADD);break; - case 0x0a:dyn_dop_gbeb(DOP_OR);break; - case 0x12:dyn_dop_gbeb(DOP_ADC);break; - case 0x1a:dyn_dop_gbeb(DOP_SBB);break; - case 0x22:dyn_dop_gbeb(DOP_AND);break; - case 0x2a:dyn_dop_gbeb(DOP_SUB);break; - case 0x32:dyn_dop_gbeb(DOP_XOR);break; - case 0x3a:dyn_dop_gbeb(DOP_CMP);break; - - // instructions 'op reg16/32,reg16/32' and 'op [],reg16/32' - case 0x01:dyn_dop_evgv(DOP_ADD);break; - case 0x09:dyn_dop_evgv(DOP_OR);break; - case 0x11:dyn_dop_evgv(DOP_ADC);break; - case 0x19:dyn_dop_evgv(DOP_SBB);break; - case 0x21:dyn_dop_evgv(DOP_AND);break; - case 0x29:dyn_dop_evgv(DOP_SUB);break; - case 0x31:dyn_dop_evgv(DOP_XOR);break; - case 0x39:dyn_dop_evgv(DOP_CMP);break; - - // instructions 'op reg16/32,reg16/32' and 'op reg16/32,[]' - case 0x03:dyn_dop_gvev(DOP_ADD);break; - case 0x0b:dyn_dop_gvev(DOP_OR);break; - case 0x13:dyn_dop_gvev(DOP_ADC);break; - case 0x1b:dyn_dop_gvev(DOP_SBB);break; - case 0x23:dyn_dop_gvev(DOP_AND);break; - case 0x2b:dyn_dop_gvev(DOP_SUB);break; - case 0x33:dyn_dop_gvev(DOP_XOR);break; - case 0x3b:dyn_dop_gvev(DOP_CMP);break; - - // instructions 'op reg8,imm8' - case 0x04:dyn_dop_byte_imm(DOP_ADD,DRC_REG_EAX,0);break; - case 0x0c:dyn_dop_byte_imm(DOP_OR,DRC_REG_EAX,0);break; - case 0x14:dyn_dop_byte_imm(DOP_ADC,DRC_REG_EAX,0);break; - case 0x1c:dyn_dop_byte_imm(DOP_SBB,DRC_REG_EAX,0);break; - case 0x24:dyn_dop_byte_imm(DOP_AND,DRC_REG_EAX,0);break; - case 0x2c:dyn_dop_byte_imm(DOP_SUB,DRC_REG_EAX,0);break; - case 0x34:dyn_dop_byte_imm(DOP_XOR,DRC_REG_EAX,0);break; - case 0x3c:dyn_dop_byte_imm(DOP_CMP,DRC_REG_EAX,0);break; - - // instructions 'op reg16/32,imm16/32' - case 0x05:dyn_dop_word_imm(DOP_ADD,DRC_REG_EAX);break; - case 0x0d:dyn_dop_word_imm_old(DOP_OR,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x15:dyn_dop_word_imm_old(DOP_ADC,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x1d:dyn_dop_word_imm_old(DOP_SBB,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x25:dyn_dop_word_imm(DOP_AND,DRC_REG_EAX);break; - case 0x2d:dyn_dop_word_imm_old(DOP_SUB,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x35:dyn_dop_word_imm_old(DOP_XOR,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break; - case 0x3d:dyn_dop_word_imm_old(DOP_CMP,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break; - - // push segment register onto stack - case 0x06:dyn_push_seg(DRC_SEG_ES);break; - case 0x0e:dyn_push_seg(DRC_SEG_CS);break; - case 0x16:dyn_push_seg(DRC_SEG_SS);break; - case 0x1e:dyn_push_seg(DRC_SEG_DS);break; - - // pop segment register from stack - case 0x07:dyn_pop_seg(DRC_SEG_ES);break; - case 0x17:dyn_pop_seg(DRC_SEG_SS);break; - case 0x1f:dyn_pop_seg(DRC_SEG_DS);break; - - // segment prefixes - case 0x26:dyn_segprefix(DRC_SEG_ES);goto restart_prefix; - case 0x2e:dyn_segprefix(DRC_SEG_CS);goto restart_prefix; - case 0x36:dyn_segprefix(DRC_SEG_SS);goto restart_prefix; - case 0x3e:dyn_segprefix(DRC_SEG_DS);goto restart_prefix; - case 0x64:dyn_segprefix(DRC_SEG_FS);goto restart_prefix; - case 0x65:dyn_segprefix(DRC_SEG_GS);goto restart_prefix; - -// case 0x27: DAA missing -// case 0x2f: DAS missing -// case 0x37: AAA missing -// case 0x3f: AAS missing - - // dual opcodes - case 0x0f: - { - Bitu dual_code=decode_fetchb(); - switch (dual_code) { - case 0x00: - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; - dyn_grp6(); - break; - case 0x01: - if (dyn_grp7()) goto finish_block; - break; -/* case 0x02: - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; - dyn_larlsl(true); - break; - case 0x03: - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; - dyn_larlsl(false); - break; */ - - case 0x20:dyn_mov_from_crx();break; - case 0x22:dyn_mov_to_crx();goto finish_block; - - // short conditional jumps - case 0x80:case 0x81:case 0x82:case 0x83:case 0x84:case 0x85:case 0x86:case 0x87: - case 0x88:case 0x89:case 0x8a:case 0x8b:case 0x8c:case 0x8d:case 0x8e:case 0x8f: - dyn_branched_exit((BranchTypes)(dual_code&0xf), - decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); - goto finish_block; - - // conditional byte set instructions -/* case 0x90:case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97: - case 0x98:case 0x99:case 0x9a:case 0x9b:case 0x9c:case 0x9d:case 0x9e:case 0x9f: - dyn_set_byte_on_condition((BranchTypes)(dual_code&0xf)); - AcquireFlags(FMASK_TEST); - break; */ - - // push/pop segment registers - case 0xa0:dyn_push_seg(DRC_SEG_FS);break; - case 0xa1:dyn_pop_seg(DRC_SEG_FS);break; - case 0xa8:dyn_push_seg(DRC_SEG_GS);break; - case 0xa9:dyn_pop_seg(DRC_SEG_GS);break; - - // double shift instructions - case 0xa4:dyn_dshift_ev_gv(true,true);break; - case 0xa5:dyn_dshift_ev_gv(true,false);break; - case 0xac:dyn_dshift_ev_gv(false,true);break; - case 0xad:dyn_dshift_ev_gv(false,false);break; - - case 0xaf:dyn_imul_gvev(0);break; - - // lfs - case 0xb4: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(DRC_SEG_FS); - break; - // lgs - case 0xb5: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(DRC_SEG_GS); - break; - - // zero-extending moves - case 0xb6:dyn_movx_ev_gb(false);break; - case 0xb7:dyn_movx_ev_gw(false);break; - - // sign-extending moves - case 0xbe:dyn_movx_ev_gb(true);break; - case 0xbf:dyn_movx_ev_gw(true);break; - - default: -#if DYN_LOG -// LOG_MSG("Unhandled dual opcode 0F%02X",dual_code); -#endif - goto illegalopcode; - } - break; - } - - // 'inc/dec reg16/32' - case 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47: - dyn_sop_word(SOP_INC,opcode&7); - break; - case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: - dyn_sop_word(SOP_DEC,opcode&7); - break; - - // 'push/pop reg16/32' - case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56:case 0x57: - dyn_push_reg(opcode&7); - break; - case 0x58:case 0x59:case 0x5a:case 0x5b:case 0x5c:case 0x5d:case 0x5e:case 0x5f: - dyn_pop_reg(opcode&7); - break; - - case 0x60: - if (decode.big_op) gen_call_function_raw((void *)&dynrec_pusha_dword); - else gen_call_function_raw((void *)&dynrec_pusha_word); - break; - case 0x61: - if (decode.big_op) gen_call_function_raw((void *)&dynrec_popa_dword); - else gen_call_function_raw((void *)&dynrec_popa_word); - break; - -// case 0x62: BOUND missing -// case 0x61: ARPL missing - - case 0x66:decode.big_op=!cpu.code.big;goto restart_prefix; - case 0x67:decode.big_addr=!cpu.code.big;goto restart_prefix; - - // 'push imm8/16/32' - case 0x68: - dyn_push_word_imm(decode.big_op ? decode_fetchd() : decode_fetchw()); - break; - case 0x6a: - dyn_push_byte_imm((Bit8s)decode_fetchb()); - break; - - // signed multiplication - case 0x69:dyn_imul_gvev(decode.big_op ? 4 : 2);break; - case 0x6b:dyn_imul_gvev(1);break; - -// case 0x6c to 0x6f missing (ins/outs) - - // short conditional jumps - case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76:case 0x77: - case 0x78:case 0x79:case 0x7a:case 0x7b:case 0x7c:case 0x7d:case 0x7e:case 0x7f: - dyn_branched_exit((BranchTypes)(opcode&0xf),(Bit8s)decode_fetchb()); - goto finish_block; - - // 'op []/reg8,imm8' - case 0x80: - case 0x82:dyn_grp1_eb_ib();break; - - // 'op []/reg16/32,imm16/32' - case 0x81:dyn_grp1_ev_iv(false);break; - case 0x83:dyn_grp1_ev_iv(true);break; - - // 'test []/reg8/16/32,reg8/16/32' - case 0x84:dyn_dop_gbeb(DOP_TEST);break; - case 0x85:dyn_dop_gvev(DOP_TEST);break; - - // 'xchg reg8/16/32,[]/reg8/16/32' - case 0x86:dyn_dop_ebgb_xchg();break; - case 0x87:dyn_dop_evgv_xchg();break; - - // 'mov []/reg8/16/32,reg8/16/32' - case 0x88:dyn_dop_ebgb_mov();break; - case 0x89:dyn_dop_evgv_mov();break; - // 'mov reg8/16/32,[]/reg8/16/32' - case 0x8a:dyn_dop_gbeb_mov();break; - case 0x8b:dyn_dop_gvev_mov();break; - - // move segment register into memory or a 16bit register - case 0x8c:dyn_mov_ev_seg();break; - - // load effective address - case 0x8d:dyn_lea();break; - - // move a value from memory or a 16bit register into a segment register - case 0x8e:dyn_mov_seg_ev();break; - - // 'pop []' - case 0x8f:dyn_pop_ev();break; - - case 0x90: // nop - case 0x9b: // wait - case 0xf0: // lock - break; - - case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97: - dyn_xchg_ax(opcode&7); - break; - - // sign-extend al into ax/sign-extend ax into eax - case 0x98:dyn_cbw();break; - // sign-extend ax into dx:ax/sign-extend eax into edx:eax - case 0x99:dyn_cwd();break; - - case 0x9a:dyn_call_far_imm();goto finish_block; - - case 0x9c: // pushf - AcquireFlags(FMASK_TEST); - gen_call_function_I((void *)&CPU_PUSHF,decode.big_op); - dyn_check_exception(FC_RETOP); - break; - case 0x9d: // popf - gen_call_function_I((void *)&CPU_POPF,decode.big_op); - dyn_check_exception(FC_RETOP); - InvalidateFlags(); - break; - - case 0x9e:dyn_sahf();break; -// case 0x9f: LAHF missing - - // 'mov al/ax,[]' - case 0xa0: - dyn_mov_byte_al_direct(decode.big_addr ? decode_fetchd() : decode_fetchw()); - break; - case 0xa1: - dyn_mov_byte_ax_direct(decode.big_addr ? decode_fetchd() : decode_fetchw()); - break; - // 'mov [],al/ax' - case 0xa2: - dyn_mov_byte_direct_al(); - break; - case 0xa3: - dyn_mov_byte_direct_ax(decode.big_addr ? decode_fetchd() : decode_fetchw()); - break; - - -// case 0xa6 to 0xaf string operations, some missing - - // movsb/w/d - case 0xa4:dyn_string(STR_MOVSB);break; - case 0xa5:dyn_string(decode.big_op ? STR_MOVSD : STR_MOVSW);break; - - // stosb/w/d - case 0xaa:dyn_string(STR_STOSB);break; - case 0xab:dyn_string(decode.big_op ? STR_STOSD : STR_STOSW);break; - - // lodsb/w/d - case 0xac:dyn_string(STR_LODSB);break; - case 0xad:dyn_string(decode.big_op ? STR_LODSD : STR_LODSW);break; - - - // 'test reg8/16/32,imm8/16/32' - case 0xa8:dyn_dop_byte_imm(DOP_TEST,DRC_REG_EAX,0);break; - case 0xa9:dyn_dop_word_imm_old(DOP_TEST,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break; - - // 'mov reg8/16/32,imm8/16/32' - case 0xb0:case 0xb1:case 0xb2:case 0xb3:case 0xb4:case 0xb5:case 0xb6:case 0xb7: - dyn_mov_byte_imm(opcode&3,(opcode>>2)&1,decode_fetchb()); - break; - case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf: - dyn_mov_word_imm(opcode&7);break; - break; - - // 'shiftop []/reg8,imm8/1/cl' - case 0xc0:dyn_grp2_eb(grp2_imm);break; - case 0xd0:dyn_grp2_eb(grp2_1);break; - case 0xd2:dyn_grp2_eb(grp2_cl);break; - - // 'shiftop []/reg16/32,imm8/1/cl' - case 0xc1:dyn_grp2_ev(grp2_imm);break; - case 0xd1:dyn_grp2_ev(grp2_1);break; - case 0xd3:dyn_grp2_ev(grp2_cl);break; - - // retn [param] - case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block; - case 0xc3:dyn_ret_near(0);goto finish_block; - - // les - case 0xc4: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(DRC_SEG_ES); - break; - // lds - case 0xc5: - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode; - dyn_load_seg_off_ea(DRC_SEG_DS);break; - - // 'mov []/reg8/16/32,imm8/16/32' - case 0xc6:dyn_dop_ebib_mov();break; - case 0xc7:dyn_dop_eviv_mov();break; - - case 0xc8:dyn_enter();break; - case 0xc9:dyn_leave();break; - - // retf [param] - case 0xca:dyn_ret_far(decode_fetchw());goto finish_block; - case 0xcb:dyn_ret_far(0);goto finish_block; - - // int/iret - case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block; - case 0xcf:dyn_iret();goto finish_block; - -// case 0xd4: AAM missing -// case 0xd5: AAD missing - -// case 0xd6: SALC missing -// case 0xd7: XLAT missing - - -#ifdef CPU_FPU - // floating point instructions - case 0xd8: - dyn_fpu_esc0(); - break; - case 0xd9: - dyn_fpu_esc1(); - break; - case 0xda: - dyn_fpu_esc2(); - break; - case 0xdb: - dyn_fpu_esc3(); - break; - case 0xdc: - dyn_fpu_esc4(); - break; - case 0xdd: - dyn_fpu_esc5(); - break; - case 0xde: - dyn_fpu_esc6(); - break; - case 0xdf: - dyn_fpu_esc7(); - break; -#endif - - - // loop instructions - case 0xe0:dyn_loop(LOOP_NE);goto finish_block; - case 0xe1:dyn_loop(LOOP_E);goto finish_block; - case 0xe2:dyn_loop(LOOP_NONE);goto finish_block; - case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block; - - - // 'in al/ax/eax,port_imm' - case 0xe4:dyn_read_port_byte_direct(decode_fetchb());break; - case 0xe5:dyn_read_port_word_direct(decode_fetchb());break; - // 'out port_imm,al/ax/eax' - case 0xe6:dyn_write_port_byte_direct(decode_fetchb());break; - case 0xe7:dyn_write_port_word_direct(decode_fetchb());break; - - // 'in al/ax/eax,port_dx' - case 0xec:dyn_read_port_byte();break; - case 0xed:dyn_read_port_word();break; - // 'out port_dx,al/ax/eax' - case 0xee:dyn_write_port_byte();break; - case 0xef:dyn_write_port_word();break; - - - // 'call near imm16/32' - case 0xe8: - dyn_call_near_imm(); - goto finish_block; - // 'jmp near imm16/32' - case 0xe9: - dyn_exit_link(decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw()); - goto finish_block; - // 'jmp far' - case 0xea: - dyn_jmp_far_imm(); - goto finish_block; - // 'jmp short imm8' - case 0xeb: - dyn_exit_link((Bit8s)decode_fetchb()); - goto finish_block; - - - // repeat prefixes - case 0xf2: - decode.rep=REP_NZ; - goto restart_prefix; - case 0xf3: - decode.rep=REP_Z; - goto restart_prefix; - - case 0xf5: //CMC - gen_call_function_raw((void*)dynrec_cmc); - break; - case 0xf8: //CLC - gen_call_function_raw((void*)dynrec_clc); - break; - case 0xf9: //STC - gen_call_function_raw((void*)dynrec_stc); - break; - - case 0xf6:dyn_grp3_eb();break; - case 0xf7:dyn_grp3_ev();break; - - case 0xfa: //CLI - gen_call_function_raw((void *)&CPU_CLI); - dyn_check_exception(FC_RETOP); - break; - case 0xfb: //STI - gen_call_function_raw((void *)&CPU_STI); - dyn_check_exception(FC_RETOP); - if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode - break; - - case 0xfc: //CLD - gen_call_function_raw((void*)dynrec_cld); - break; - case 0xfd: //STD - gen_call_function_raw((void*)dynrec_std); - break; - - case 0xfe: - if (dyn_grp4_eb()) goto finish_block; - break; - case 0xff: - switch (dyn_grp4_ev()) { - case 0: - break; - case 1: - goto core_close_block; - case 2: - goto illegalopcode; - default: - break; - } - break; - - default: -#if DYN_LOG -// LOG_MSG("Dynrec unhandled opcode %X",opcode); -#endif - goto illegalopcode; - } - } - // link to next block because the maximum number of opcodes has been reached - dyn_set_eip_end(); - dyn_reduce_cycles(); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); - dyn_closeblock(); - goto finish_block; -core_close_block: - dyn_reduce_cycles(); - dyn_return(BR_Normal); - dyn_closeblock(); - goto finish_block; -illegalopcode: - // some unhandled opcode has been encountered - dyn_set_eip_last(); - dyn_reduce_cycles(); - dyn_return(BR_Opcode); // tell the core what happened - dyn_closeblock(); - goto finish_block; -finish_block: - - // setup the correct end-address - decode.page.index--; - decode.active_block->page.end=(Bit16u)decode.page.index; -// LOG_MSG("Created block size %d start %d end %d",decode.block->cache.size,decode.block->page.start,decode.block->page.end); - - return decode.block; -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/decoder_basic.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/decoder_basic.h deleted file mode 100644 index 61edc64b1..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/decoder_basic.h +++ /dev/null @@ -1,1267 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* - This file provides some definitions and basic level functions - that use code generating functions from risc_?.h - Important is the function call generation including parameter - loading, the effective address calculation and the memory - access functions. -*/ - - -// instructions that use one operand -enum SingleOps { - SOP_INC,SOP_DEC, - SOP_NOT,SOP_NEG -}; - -// instructions that use two operand -enum DualOps { - DOP_ADD,DOP_ADC, - DOP_SUB,DOP_SBB, - DOP_CMP,DOP_XOR, - DOP_AND,DOP_OR, - DOP_TEST, - DOP_MOV, - DOP_XCHG -}; - -// shift and rotate functions -enum ShiftOps { - SHIFT_ROL,SHIFT_ROR, - SHIFT_RCL,SHIFT_RCR, - SHIFT_SHL,SHIFT_SHR, - SHIFT_SAL,SHIFT_SAR -}; - -// branch conditions -enum BranchTypes { - BR_O,BR_NO,BR_B,BR_NB, - BR_Z,BR_NZ,BR_BE,BR_NBE, - BR_S,BR_NS,BR_P,BR_NP, - BR_L,BR_NL,BR_LE,BR_NLE -}; - -// string instructions -enum StringOps { - STR_OUTSB=0,STR_OUTSW,STR_OUTSD, - STR_INSB=4,STR_INSW,STR_INSD, - STR_MOVSB=8,STR_MOVSW,STR_MOVSD, - STR_LODSB=12,STR_LODSW,STR_LODSD, - STR_STOSB=16,STR_STOSW,STR_STOSD, - STR_SCASB=20,STR_SCASW,STR_SCASD, - STR_CMPSB=24,STR_CMPSW,STR_CMPSD -}; - -// repeat prefix type (for string operations) -enum REP_Type { - REP_NONE=0,REP_NZ,REP_Z -}; - -// loop type -enum LoopTypes { - LOOP_NONE,LOOP_NE,LOOP_E,LOOP_JCXZ -}; - -// rotate operand type -enum grp2_types { - grp2_1,grp2_imm,grp2_cl -}; - -// opcode mapping for group1 instructions -static DualOps grp1_table[8]={ - DOP_ADD,DOP_OR,DOP_ADC,DOP_SBB,DOP_AND,DOP_SUB,DOP_XOR,DOP_CMP -}; - - -// decoding information used during translation of a code block -static struct DynDecode { - PhysPt code; // pointer to next byte in the instruction stream - PhysPt code_start; // pointer to the start of the current code block - PhysPt op_start; // pointer to the start of the current instruction - bool big_op; // operand modifier - bool big_addr; // address modifier - REP_Type rep; // current repeat prefix - Bitu cycles; // number cycles used by currently translated code - bool seg_prefix_used; // segment overridden - Bit8u seg_prefix; // segment prefix (if seg_prefix_used==true) - - // block that contains the first instruction translated - CacheBlockDynRec * block; - // block that contains the current byte of the instruction stream - CacheBlockDynRec * active_block; - - // the active page (containing the current byte of the instruction stream) - struct { - CodePageHandlerDynRec * code; - Bitu index; // index to the current byte of the instruction stream - Bit8u * wmap; // write map that indicates code presence for every byte of this page - Bit8u * invmap; // invalidation map - Bitu first; // page number - } page; - - // modrm state of the current instruction (if used) - struct { - Bitu val; - Bitu mod; - Bitu rm; - Bitu reg; - } modrm; -} decode; - - -static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { - Bit8u rdval; - //Ensure page contains memory: - if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - - PageHandler * handler=get_tlb_readhandler(lin_addr); - if (handler->flags & PFLAG_HASCODE) { - // this is a codepage handler, and the one that we're looking for - cph=(CodePageHandlerDynRec *)handler; - return false; - } - if (handler->flags & PFLAG_NOCODE) { - if (PAGING_ForcePageInit(lin_addr)) { - handler=get_tlb_readhandler(lin_addr); - if (handler->flags & PFLAG_HASCODE) { - cph=(CodePageHandlerDynRec *)handler; - return false; - } - } - if (handler->flags & PFLAG_NOCODE) { - LOG_MSG("DYNREC:Can't run code in this page"); - cph=0; - return false; - } - } - Bitu lin_page=lin_addr>>12; - Bitu phys_page=lin_page; - // find the physical page that the linear page is mapped to - if (!PAGING_MakePhysPage(phys_page)) { - LOG_MSG("DYNREC:Can't find physpage"); - cph=0; - return false; - } - // find a free CodePage - if (!cache.free_pages) { - if (cache.used_pages!=decode.page.code) cache.used_pages->ClearRelease(); - else { - // try another page to avoid clearing our source-crosspage - if ((cache.used_pages->next) && (cache.used_pages->next!=decode.page.code)) - cache.used_pages->next->ClearRelease(); - else { - LOG_MSG("DYNREC:Invalid cache links"); - cache.used_pages->ClearRelease(); - } - } - } - CodePageHandlerDynRec * cpagehandler=cache.free_pages; - cache.free_pages=cache.free_pages->next; - - // adjust previous and next page pointer - cpagehandler->prev=cache.last_page; - cpagehandler->next=0; - if (cache.last_page) cache.last_page->next=cpagehandler; - cache.last_page=cpagehandler; - if (!cache.used_pages) cache.used_pages=cpagehandler; - - // initialize the code page handler and add the handler to the memory page - cpagehandler->SetupAt(phys_page,handler); - MEM_SetPageHandler(phys_page,1,cpagehandler); - PAGING_UnlinkPages(lin_page,1); - cph=cpagehandler; - return false; -} - -static void decode_advancepage(void) { - // Advance to the next page - decode.active_block->page.end=4095; - // trigger possible page fault here - decode.page.first++; - Bitu faddr=decode.page.first << 12; - mem_readb(faddr); - MakeCodePage(faddr,decode.page.code); - CacheBlockDynRec * newblock=cache_getblock(); - decode.active_block->crossblock=newblock; - newblock->crossblock=decode.active_block; - decode.active_block=newblock; - decode.active_block->page.start=0; - decode.page.code->AddCrossBlock(decode.active_block); - decode.page.wmap=decode.page.code->write_map; - decode.page.invmap=decode.page.code->invalidation_map; - decode.page.index=0; -} - -// fetch the next byte of the instruction stream -static Bit8u decode_fetchb(void) { - if (GCC_UNLIKELY(decode.page.index>=4096)) { - decode_advancepage(); - } - decode.page.wmap[decode.page.index]+=0x01; - decode.page.index++; - decode.code+=1; - return mem_readb(decode.code-1); -} -// fetch the next word of the instruction stream -static Bit16u decode_fetchw(void) { - if (GCC_UNLIKELY(decode.page.index>=4095)) { - Bit16u val=decode_fetchb(); - val|=decode_fetchb() << 8; - return val; - } - *(Bit16u *)&decode.page.wmap[decode.page.index]+=0x0101; - decode.code+=2;decode.page.index+=2; - return mem_readw(decode.code-2); -} -// fetch the next dword of the instruction stream -static Bit32u decode_fetchd(void) { - if (GCC_UNLIKELY(decode.page.index>=4093)) { - Bit32u val=decode_fetchb(); - val|=decode_fetchb() << 8; - val|=decode_fetchb() << 16; - val|=decode_fetchb() << 24; - return val; - /* Advance to the next page */ - } - *(Bit32u *)&decode.page.wmap[decode.page.index]+=0x01010101; - decode.code+=4;decode.page.index+=4; - return mem_readd(decode.code-4); -} - -#define START_WMMEM 64 - -// adjust writemap mask to care for map holes due to special -// codefetch functions -static void INLINE decode_increase_wmapmask(Bitu size) { - Bitu mapidx; - CacheBlockDynRec* activecb=decode.active_block; - if (GCC_UNLIKELY(!activecb->cache.wmapmask)) { - // no mask memory yet allocated, start with a small buffer - activecb->cache.wmapmask=(Bit8u*)malloc(START_WMMEM); - memset(activecb->cache.wmapmask,0,START_WMMEM); - activecb->cache.maskstart=decode.page.index; // start of buffer is current code position - activecb->cache.masklen=START_WMMEM; - mapidx=0; - } else { - mapidx=decode.page.index-activecb->cache.maskstart; - if (GCC_UNLIKELY(mapidx+size>=activecb->cache.masklen)) { - // mask buffer too small, increase - Bitu newmasklen=activecb->cache.masklen*4; - if (newmasklencache.wmapmask,activecb->cache.masklen); - free(activecb->cache.wmapmask); - activecb->cache.wmapmask=tempmem; - activecb->cache.masklen=newmasklen; - } - } - // update mask entries - switch (size) { - case 1 : activecb->cache.wmapmask[mapidx]+=0x01; break; - case 2 : (*(Bit16u*)&activecb->cache.wmapmask[mapidx])+=0x0101; break; - case 4 : (*(Bit32u*)&activecb->cache.wmapmask[mapidx])+=0x01010101; break; - } -} - -// fetch a byte, val points to the code location if possible, -// otherwise val contains the current value read from the position -static bool decode_fetchb_imm(Bitu & val) { - if (GCC_UNLIKELY(decode.page.index>=4096)) { - decode_advancepage(); - } - // see if position is directly accessible - if (decode.page.invmap != NULL) { - if (decode.page.invmap[decode.page.index] == 0) { - // position not yet modified - val=(Bit32u)decode_fetchb(); - return false; - } - - HostPt tlb_addr=get_tlb_read(decode.code); - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(1); - decode.code++; - decode.page.index++; - return true; - } - } - // first time decoding or not directly accessible, just fetch the value - val=(Bit32u)decode_fetchb(); - return false; -} - -// fetch a word, val points to the code location if possible, -// otherwise val contains the current value read from the position -static bool decode_fetchw_imm(Bitu & val) { - if (decode.page.index<4095) { - if (decode.page.invmap != NULL) { - if ((decode.page.invmap[decode.page.index] == 0) && - (decode.page.invmap[decode.page.index + 1] == 0)) { - // position not yet modified - val=decode_fetchw(); - return false; - } - - HostPt tlb_addr=get_tlb_read(decode.code); - // see if position is directly accessible - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(2); - decode.code+=2; - decode.page.index+=2; - return true; - } - } - } - // first time decoding or not directly accessible, just fetch the value - val=decode_fetchw(); - return false; -} - -// fetch a dword, val points to the code location if possible, -// otherwise val contains the current value read from the position -static bool decode_fetchd_imm(Bitu & val) { - if (decode.page.index<4093) { - if (decode.page.invmap != NULL) { - if ((decode.page.invmap[decode.page.index] == 0) && - (decode.page.invmap[decode.page.index + 1] == 0) && - (decode.page.invmap[decode.page.index + 2] == 0) && - (decode.page.invmap[decode.page.index + 3] == 0)) { - // position not yet modified - val=decode_fetchd(); - return false; - } - - HostPt tlb_addr=get_tlb_read(decode.code); - // see if position is directly accessible - if (tlb_addr) { - val=(Bitu)(tlb_addr+decode.code); - decode_increase_wmapmask(4); - decode.code+=4; - decode.page.index+=4; - return true; - } - } - } - // first time decoding or not directly accessible, just fetch the value - val=decode_fetchd(); - return false; -} - - -// modrm decoding helper -static void INLINE dyn_get_modrm(void) { - decode.modrm.val=decode_fetchb(); - decode.modrm.mod=(decode.modrm.val >> 6) & 3; - decode.modrm.reg=(decode.modrm.val >> 3) & 7; - decode.modrm.rm=(decode.modrm.val & 7); -} - - -#ifdef DRC_USE_SEGS_ADDR - -#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_seg16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_VAL(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) - -#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) -#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) - -#else - -#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_VAL(seg_index),false) - -#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_PHYS(seg_index),true) -#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add(host_reg,DRCD_SEG_PHYS(seg_index)) - -#endif - - -#ifdef DRC_USE_REGS_ADDR - -#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) -#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) - -#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_regval16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) -#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) -#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword) - -#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval16_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) -#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval32_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) -#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword) - -#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) -#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low_canuseword(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) -#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_from_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) - -#else - -#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_VAL(reg_index),true) -#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add(host_reg,DRCD_REG_VAL(reg_index)) - -#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,false),false) -#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,true),true) -#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword) - -#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,false),false) -#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,true),true) -#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword) - -#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) -#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low_canuseword(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) -#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_from_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) - -#endif - - -#define DYN_LEA_MEM_MEM(ea_reg, op1, op2, scale, imm) dyn_lea_mem_mem(ea_reg,op1,op2,scale,imm) - -#if defined(DRC_USE_REGS_ADDR) && defined(DRC_USE_SEGS_ADDR) - -#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_regval(ea_reg,op1_index,op2_index,scale,imm) -#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm) -#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm) - -#elif defined(DRC_USE_REGS_ADDR) - -#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,DRCD_SEG_PHYS(op1_index),op2_index,scale,imm) -#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm) -#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm) - -#elif defined(DRC_USE_SEGS_ADDR) - -#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_mem(ea_reg,op1_index,DRCD_REG_VAL(op2_index),scale,imm) -#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm) -#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm) - -#else - -#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_SEG_PHYS(op1_index),DRCD_REG_VAL(op2_index),scale,imm) -#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm) -#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm) - -#endif - - - -// adjust CPU_Cycles value -static void dyn_reduce_cycles(void) { - if (!decode.cycles) decode.cycles++; - gen_sub_direct_word(&CPU_Cycles,decode.cycles,true); -} - - -// set reg to the start of the next instruction -// set reg_eip to the start of the current instruction -static INLINE void dyn_set_eip_last_end(HostReg reg) { - gen_mov_word_to_reg(reg,®_eip,true); - gen_add_imm(reg,(Bit32u)(decode.code-decode.code_start)); - gen_add_direct_word(®_eip,decode.op_start-decode.code_start,decode.big_op); -} - -// set reg_eip to the start of the current instruction -static INLINE void dyn_set_eip_last(void) { - gen_add_direct_word(®_eip,decode.op_start-decode.code_start,cpu.code.big); -} - -// set reg_eip to the start of the next instruction -static INLINE void dyn_set_eip_end(void) { - gen_add_direct_word(®_eip,decode.code-decode.code_start,cpu.code.big); -} - -// set reg_eip to the start of the next instruction plus an offset (imm) -static INLINE void dyn_set_eip_end(HostReg reg,Bit32u imm=0) { - gen_mov_word_to_reg(reg,®_eip,true); //get_extend_word will mask off the upper bits - //gen_mov_word_to_reg(reg,®_eip,decode.big_op); - gen_add_imm(reg,(Bit32u)(decode.code-decode.code_start+imm)); - if (!decode.big_op) gen_extend_word(false,reg); -} - - - -// the following functions generate function calls -// parameters are loaded by generating code using gen_load_param_ which -// is architecture dependent -// R=host register; I=32bit immediate value; A=address value; m=memory - -static DRC_PTR_SIZE_IM INLINE gen_call_function_R(void * func,Bitu op) { - gen_load_param_reg(op,0); - return gen_call_function_setup(func, 1); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_R3(void * func,Bitu op) { - gen_load_param_reg(op,2); - return gen_call_function_setup(func, 3, true); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_RI(void * func,Bitu op1,Bitu op2) { - gen_load_param_imm(op2,1); - gen_load_param_reg(op1,0); - return gen_call_function_setup(func, 2); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_RA(void * func,Bitu op1,DRC_PTR_SIZE_IM op2) { - gen_load_param_addr(op2,1); - gen_load_param_reg(op1,0); - return gen_call_function_setup(func, 2); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_RR(void * func,Bitu op1,Bitu op2) { - gen_load_param_reg(op2,1); - gen_load_param_reg(op1,0); - return gen_call_function_setup(func, 2); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_IR(void * func,Bitu op1,Bitu op2) { - gen_load_param_reg(op2,1); - gen_load_param_imm(op1,0); - return gen_call_function_setup(func, 2); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_I(void * func,Bitu op) { - gen_load_param_imm(op,0); - return gen_call_function_setup(func, 1); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_II(void * func,Bitu op1,Bitu op2) { - gen_load_param_imm(op2,1); - gen_load_param_imm(op1,0); - return gen_call_function_setup(func, 2); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_III(void * func,Bitu op1,Bitu op2,Bitu op3) { - gen_load_param_imm(op3,2); - gen_load_param_imm(op2,1); - gen_load_param_imm(op1,0); - return gen_call_function_setup(func, 3); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_IA(void * func,Bitu op1,DRC_PTR_SIZE_IM op2) { - gen_load_param_addr(op2,1); - gen_load_param_imm(op1,0); - return gen_call_function_setup(func, 2); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_IIR(void * func,Bitu op1,Bitu op2,Bitu op3) { - gen_load_param_reg(op3,2); - gen_load_param_imm(op2,1); - gen_load_param_imm(op1,0); - return gen_call_function_setup(func, 3); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_IIIR(void * func,Bitu op1,Bitu op2,Bitu op3,Bitu op4) { - gen_load_param_reg(op4,3); - gen_load_param_imm(op3,2); - gen_load_param_imm(op2,1); - gen_load_param_imm(op1,0); - return gen_call_function_setup(func, 4); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_IRRR(void * func,Bitu op1,Bitu op2,Bitu op3,Bitu op4) { - gen_load_param_reg(op4,3); - gen_load_param_reg(op3,2); - gen_load_param_reg(op2,1); - gen_load_param_imm(op1,0); - return gen_call_function_setup(func, 4); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_m(void * func,Bitu op) { - gen_load_param_mem(op,2); - return gen_call_function_setup(func, 3, true); -} - -static DRC_PTR_SIZE_IM INLINE gen_call_function_mm(void * func,Bitu op1,Bitu op2) { - gen_load_param_mem(op2,3); - gen_load_param_mem(op1,2); - return gen_call_function_setup(func, 4, true); -} - - - -enum save_info_type {db_exception, cycle_check, string_break}; - - -// function that is called on exceptions -static BlockReturn DynRunException(Bit32u eip_add,Bit32u cycle_sub) { - reg_eip+=eip_add; - CPU_Cycles-=cycle_sub; - if (cpu.exception.which==SMC_CURRENT_BLOCK) return BR_SMCBlock; - CPU_Exception(cpu.exception.which,cpu.exception.error); - return BR_Normal; -} - - -// array with information about code that is generated at the -// end of a cache block because it is rarely reached (like exceptions) -static struct { - save_info_type type; - DRC_PTR_SIZE_IM branch_pos; - Bit32u eip_change; - Bitu cycles; -} save_info_dynrec[512]; - -Bitu used_save_info_dynrec=0; - - -// return from current block, with returncode -static void dyn_return(BlockReturn retcode,bool ret_exception=false) { - if (!ret_exception) { - gen_mov_dword_to_reg_imm(FC_RETOP,retcode); - } - gen_return_function(); -} - -static void dyn_run_code(void) { - gen_run_code(); - gen_return_function(); -} - -// fill in code at the end of the block that contains rarely-executed code -// which is executed conditionally (like exceptions) -static void dyn_fill_blocks(void) { - for (Bitu sct=0; sctcache.start,decode.block->cache.size); -} - - -// add a check that can branch to the exception handling -static void dyn_check_exception(HostReg reg) { - save_info_dynrec[used_save_info_dynrec].branch_pos=gen_create_branch_long_nonzero(reg,false); - if (!decode.cycles) decode.cycles++; - save_info_dynrec[used_save_info_dynrec].cycles=decode.cycles; - // in case of an exception eip will point to the start of the current instruction - save_info_dynrec[used_save_info_dynrec].eip_change=decode.op_start-decode.code_start; - if (!cpu.code.big) save_info_dynrec[used_save_info_dynrec].eip_change&=0xffff; - save_info_dynrec[used_save_info_dynrec].type=db_exception; - used_save_info_dynrec++; -} - - - -bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC; -bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *((Bit8u*)(&core_dynrec.readdata))=host_readb(tlb_addr+address); - return false; - } else { - return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); - } -} - -bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) DRC_FC; -bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writeb(tlb_addr+address,val); - return false; - } else return get_tlb_writehandler(address)->writeb_checked(address,val); -} - -bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC; -bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *((Bit16u*)(&core_dynrec.readdata))=host_readw(tlb_addr+address); - return false; - } else return get_tlb_readhandler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); - } else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata))); -} - -bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) DRC_FC; -bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *((Bit32u*)(&core_dynrec.readdata))=host_readd(tlb_addr+address); - return false; - } else return get_tlb_readhandler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); - } else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata))); -} - -bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) DRC_FC; -bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writew(tlb_addr+address,val); - return false; - } else return get_tlb_writehandler(address)->writew_checked(address,val); - } else return mem_unalignedwritew_checked(address,val); -} - -bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) DRC_FC; -bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - host_writed(tlb_addr+address,val); - return false; - } else return get_tlb_writehandler(address)->writed_checked(address,val); - } else return mem_unalignedwrited_checked(address,val); -} - - -// functions that enable access to the memory - -// read a byte from a given address and store it in reg_dst -static void dyn_read_byte(HostReg reg_addr,HostReg reg_dst) { - gen_mov_regs(FC_OP1,reg_addr); - gen_call_function_raw((void *)&mem_readb_checked_drc); - dyn_check_exception(FC_RETOP); - gen_mov_byte_to_reg_low(reg_dst,&core_dynrec.readdata); -} -static void dyn_read_byte_canuseword(HostReg reg_addr,HostReg reg_dst) { - gen_mov_regs(FC_OP1,reg_addr); - gen_call_function_raw((void *)&mem_readb_checked_drc); - dyn_check_exception(FC_RETOP); - gen_mov_byte_to_reg_low_canuseword(reg_dst,&core_dynrec.readdata); -} - -// write a byte from reg_val into the memory given by the address -static void dyn_write_byte(HostReg reg_addr,HostReg reg_val) { - gen_mov_regs(FC_OP2,reg_val); - gen_mov_regs(FC_OP1,reg_addr); - gen_call_function_raw((void *)&mem_writeb_checked_drc); - dyn_check_exception(FC_RETOP); -} - -// read a 32bit (dword=true) or 16bit (dword=false) value -// from a given address and store it in reg_dst -static void dyn_read_word(HostReg reg_addr,HostReg reg_dst,bool dword) { - gen_mov_regs(FC_OP1,reg_addr); - if (dword) gen_call_function_raw((void *)&mem_readd_checked_drc); - else gen_call_function_raw((void *)&mem_readw_checked_drc); - dyn_check_exception(FC_RETOP); - gen_mov_word_to_reg(reg_dst,&core_dynrec.readdata,dword); -} - -// write a 32bit (dword=true) or 16bit (dword=false) value -// from reg_val into the memory given by the address -static void dyn_write_word(HostReg reg_addr,HostReg reg_val,bool dword) { -// if (!dword) gen_extend_word(false,reg_val); - gen_mov_regs(FC_OP2,reg_val); - gen_mov_regs(FC_OP1,reg_addr); - if (dword) gen_call_function_raw((void *)&mem_writed_checked_drc); - else gen_call_function_raw((void *)&mem_writew_checked_drc); - dyn_check_exception(FC_RETOP); -} - - - -// effective address calculation helper, op2 has to be present! -// loads op1 into ea_reg and adds the scaled op2 and the immediate to it -static void dyn_lea_mem_mem(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { - if (scale || imm) { - if (op1!=NULL) { - gen_mov_word_to_reg(ea_reg,op1,true); - gen_mov_word_to_reg(TEMP_REG_DRC,op2,true); - - gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); - } else { - gen_mov_word_to_reg(ea_reg,op2,true); - gen_lea(ea_reg,scale,imm); - } - } else { - gen_mov_word_to_reg(ea_reg,op2,true); - if (op1!=NULL) gen_add(ea_reg,op1); - } -} - -#ifdef DRC_USE_REGS_ADDR -// effective address calculation helper -// loads op1 into ea_reg and adds the scaled op2 and the immediate to it -// op1 is cpu_regs[op1_index], op2 is cpu_regs[op2_index] -static void dyn_lea_regval_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) { - if (scale || imm) { - MOV_REG_VAL_TO_HOST_REG(ea_reg,op1_index); - MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); - - gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); - } else { - MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); - ADD_REG_VAL_TO_HOST_REG(ea_reg,op1_index); - } -} - -// effective address calculation helper -// loads op1 into ea_reg and adds the scaled op2 and the immediate to it -// op2 is cpu_regs[op2_index] -static void dyn_lea_mem_regval(HostReg ea_reg,void* op1,Bitu op2_index,Bitu scale,Bits imm) { - if (scale || imm) { - if (op1!=NULL) { - gen_mov_word_to_reg(ea_reg,op1,true); - MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); - - gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); - } else { - MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); - gen_lea(ea_reg,scale,imm); - } - } else { - MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); - if (op1!=NULL) gen_add(ea_reg,op1); - } -} -#endif - -#ifdef DRC_USE_SEGS_ADDR -#ifdef DRC_USE_REGS_ADDR -// effective address calculation helper -// loads op1 into ea_reg and adds the scaled op2 and the immediate to it -// op1 is Segs[op1_index], op2 is cpu_regs[op2_index] -static void dyn_lea_segphys_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) { - if (scale || imm) { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); - MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); - - gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); - } else { - MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); - ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); - } -} - -#else - -// effective address calculation helper, op2 has to be present! -// loads op1 into ea_reg and adds the scaled op2 and the immediate to it -// op1 is Segs[op1_index] -static void dyn_lea_segphys_mem(HostReg ea_reg,Bitu op1_index,void* op2,Bitu scale,Bits imm) { - if (scale || imm) { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); - gen_mov_word_to_reg(TEMP_REG_DRC,op2,true); - - gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); - } else { - gen_mov_word_to_reg(ea_reg,op2,true); - ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); - } -} -#endif -#endif - -// calculate the effective address and store it in ea_reg -static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { - Bit8u seg_base=DRC_SEG_DS; - if (!decode.big_addr) { - Bits imm; - switch (decode.modrm.mod) { - case 0:imm=0;break; - case 1:imm=(Bit8s)decode_fetchb();break; - case 2:imm=(Bit16s)decode_fetchw();break; - } - switch (decode.modrm.rm) { - case 0:// BX+SI - DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_ESI,0,imm); - break; - case 1:// BX+DI - DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_EDI,0,imm); - break; - case 2:// BP+SI - DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_ESI,0,imm); - seg_base=DRC_SEG_SS; - break; - case 3:// BP+DI - DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_EDI,0,imm); - seg_base=DRC_SEG_SS; - break; - case 4:// SI - MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_ESI); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - break; - case 5:// DI - MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EDI); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - break; - case 6:// imm/BP - if (!decode.modrm.mod) { - imm=decode_fetchw(); - gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); - goto skip_extend_word; - } else { - MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBP); - gen_add_imm(ea_reg,(Bit32u)imm); - seg_base=DRC_SEG_SS; - } - break; - case 7: // BX - MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBX); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - break; - } - // zero out the high 16bit so ea_reg can be used as full register - gen_extend_word(false,ea_reg); -skip_extend_word: - if (addseg) { - // add the physical segment value if requested - ADD_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - } - } else { - Bits imm=0; - Bit8u base_reg; - Bit8u scaled_reg; - Bitu scale=0; - switch (decode.modrm.rm) { - case 0:base_reg=DRC_REG_EAX;break; - case 1:base_reg=DRC_REG_ECX;break; - case 2:base_reg=DRC_REG_EDX;break; - case 3:base_reg=DRC_REG_EBX;break; - case 4: // SIB - { - Bitu sib=decode_fetchb(); - bool scaled_reg_used=false; - static Bit8u scaledtable[8]={ - DRC_REG_EAX,DRC_REG_ECX,DRC_REG_EDX,DRC_REG_EBX, - 0,DRC_REG_EBP,DRC_REG_ESI,DRC_REG_EDI - }; - // see if scaling should be used and which register is to be scaled in this case - if (((sib >> 3) &7)!=4) scaled_reg_used=true; - scaled_reg=scaledtable[(sib >> 3) &7]; - scale=(sib >> 6); - - switch (sib & 7) { - case 0:base_reg=DRC_REG_EAX;break; - case 1:base_reg=DRC_REG_ECX;break; - case 2:base_reg=DRC_REG_EDX;break; - case 3:base_reg=DRC_REG_EBX;break; - case 4:base_reg=DRC_REG_ESP;seg_base=DRC_SEG_SS;break; - case 5: - if (decode.modrm.mod) { - base_reg=DRC_REG_EBP;seg_base=DRC_SEG_SS; - } else { - // no basereg, maybe scalereg - Bitu val; - // try to get a pointer to the next dword code position - if (decode_fetchd_imm(val)) { - // succeeded, use the pointer to avoid code invalidation - if (!addseg) { - if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,(void*)val,true); - } else { - DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,0); - gen_add(ea_reg,(void*)val); - } - } else { - if (!scaled_reg_used) { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - } else { - DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0); - } - gen_add(ea_reg,(void*)val); - } - return; - } - // couldn't get a pointer, use the current value - imm=(Bit32s)val; - - if (!addseg) { - if (!scaled_reg_used) { - gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); - } else { - DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,imm); - } - } else { - if (!scaled_reg_used) { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - } else { - DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm); - } - } - - return; - } - break; - case 6:base_reg=DRC_REG_ESI;break; - case 7:base_reg=DRC_REG_EDI;break; - } - // basereg, maybe scalereg - switch (decode.modrm.mod) { - case 1: - imm=(Bit8s)decode_fetchb(); - break; - case 2: { - Bitu val; - // try to get a pointer to the next dword code position - if (decode_fetchd_imm(val)) { - // succeeded, use the pointer to avoid code invalidation - if (!addseg) { - if (!scaled_reg_used) { - MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - gen_add(ea_reg,(void*)val); - } else { - DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,0); - gen_add(ea_reg,(void*)val); - } - } else { - if (!scaled_reg_used) { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - } else { - DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0); - } - ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - gen_add(ea_reg,(void*)val); - } - return; - } - // couldn't get a pointer, use the current value - imm=(Bit32s)val; - break; - } - } - - if (!addseg) { - if (!scaled_reg_used) { - MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - gen_add_imm(ea_reg,(Bit32u)imm); - } else { - DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,imm); - } - } else { - if (!scaled_reg_used) { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - } else { - DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm); - ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - } - } - - return; - } - break; // SIB Break - case 5: - if (decode.modrm.mod) { - base_reg=DRC_REG_EBP;seg_base=DRC_SEG_SS; - } else { - // no base, no scalereg - - imm=(Bit32s)decode_fetchd(); - if (!addseg) { - gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); - } else { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - } - - return; - } - break; - case 6:base_reg=DRC_REG_ESI;break; - case 7:base_reg=DRC_REG_EDI;break; - } - - // no scalereg, but basereg - - switch (decode.modrm.mod) { - case 1: - imm=(Bit8s)decode_fetchb(); - break; - case 2: { - Bitu val; - // try to get a pointer to the next dword code position - if (decode_fetchd_imm(val)) { - // succeeded, use the pointer to avoid code invalidation - if (!addseg) { - MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - gen_add(ea_reg,(void*)val); - } else { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - gen_add(ea_reg,(void*)val); - } - return; - } - // couldn't get a pointer, use the current value - imm=(Bit32s)val; - break; - } - } - - if (!addseg) { - MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - } else { - MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); - ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); - if (imm) gen_add_imm(ea_reg,(Bit32u)imm); - } - } -} - - - -// add code that checks if port access is allowed -// the port is given in a register -static void dyn_add_iocheck(HostReg reg_port,Bitu access_size) { - if (cpu.pmode) { - gen_call_function_RI((void *)&CPU_IO_Exception,reg_port,access_size); - dyn_check_exception(FC_RETOP); - } -} - -// add code that checks if port access is allowed -// the port is a constant -static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { - if (cpu.pmode) { - gen_call_function_II((void *)&CPU_IO_Exception,accessed_port,access_size); - dyn_check_exception(FC_RETOP); - } -} - - - -// save back the address register -static void gen_protect_addr_reg(void) { -#ifdef DRC_PROTECT_ADDR_REG - gen_mov_word_from_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); -#endif -} - -// restore the address register -static void gen_restore_addr_reg(void) { -#ifdef DRC_PROTECT_ADDR_REG - gen_mov_word_to_reg(FC_ADDR,&core_dynrec.protected_regs[FC_ADDR],true); -#endif -} - -// save back an arbitrary register -static void gen_protect_reg(HostReg reg) { - gen_mov_word_from_reg(reg,&core_dynrec.protected_regs[reg],true); -} - -// restore an arbitrary register -static void gen_restore_reg(HostReg reg) { - gen_mov_word_to_reg(reg,&core_dynrec.protected_regs[reg],true); -} - -// restore an arbitrary register into a different register -static void gen_restore_reg(HostReg reg,HostReg dest_reg) { - gen_mov_word_to_reg(dest_reg,&core_dynrec.protected_regs[reg],true); -} - - - -// flags optimization functions -// they try to find out if a function can be replaced by another -// one that does not generate any flags at all - -static Bitu mf_functions_num=0; -static struct { - Bit8u* pos; - void* fct_ptr; - Bitu ftype; -} mf_functions[64]; - -static void InitFlagsOptimization(void) { - mf_functions_num=0; -} - -// replace all queued functions with their simpler variants -// because the current instruction destroys all condition flags and -// the flags are not required before -static void InvalidateFlags(void) { -#ifdef DRC_FLAGS_INVALIDATION - for (Bitu ct=0; ct>2)&1); - dyn_dop_byte_gencall(op); - - if ((op!=DOP_CMP) && (op!=DOP_TEST)) { - gen_restore_addr_reg(); - dyn_write_byte(FC_ADDR,FC_RETOP); - } - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} - -static void dyn_dop_ebgb_mov(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - dyn_write_byte(FC_ADDR,FC_TMP_BA1); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} - -static void dyn_dop_ebib_mov(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb()); - dyn_write_byte(FC_ADDR,FC_TMP_BA1); - } else { - gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb()); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} - -static void dyn_dop_ebgb_xchg(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_byte(FC_ADDR,FC_TMP_BA1); - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - gen_restore_addr_reg(); - dyn_write_byte(FC_ADDR,FC_TMP_BA2); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} - -static void dyn_dop_gbeb(DualOps op) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_byte_canuseword(FC_ADDR,FC_OP2); - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - } -} - -static void dyn_dop_gbeb_mov(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_byte(FC_ADDR,FC_TMP_BA1); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - } -} - -static void dyn_dop_evgv(DualOps op) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_protect_addr_reg(); - MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) { - gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); - } - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); - } -} - -static void dyn_dop_evgv_mov(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } -} - -static void dyn_dop_eviv_mov(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd()); - else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw()); - dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); - } else { - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd()); - else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw()); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } -} - -static void dyn_dop_evgv_xchg(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - - gen_protect_reg(FC_OP1); - gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_OP2,decode.big_op); - gen_restore_reg(FC_OP1); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op); - } -} - -static void dyn_xchg_ax(Bit8u reg) { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); - MOV_REG_WORD_TO_HOST_REG(FC_OP2,reg,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP2,DRC_REG_EAX,decode.big_op); -} - -static void dyn_dop_gvev(DualOps op) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) { - gen_restore_addr_reg(); - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); - } - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op); - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); - } -} - -static void dyn_dop_gvev_mov(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - } -} - -static void dyn_dop_byte_imm(DualOps op,Bit8u reg,Bit8u idx) { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx); - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); - dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx); -} - -static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx); - Bitu val; - if (decode_fetchb_imm(val)) { - gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val); - } else { - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val); - } - dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx); -} - -static void dyn_prep_word_imm(Bit8u reg) { - Bitu val; - if (decode.big_op) { - if (decode_fetchd_imm(val)) { - gen_mov_word_to_reg(FC_OP2,(void*)val,true); - return; - } - } else { - if (decode_fetchw_imm(val)) { - gen_mov_word_to_reg(FC_OP2,(void*)val,false); - return; - } - } - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)val); - else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)val); -} - -static void dyn_dop_word_imm(DualOps op,Bit8u reg) { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); - dyn_prep_word_imm(reg); - dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); -} - -static void dyn_dop_word_imm_old(DualOps op,Bit8u reg,Bitu imm) { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); - else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm); - dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); -} - -static void dyn_mov_byte_imm(Bit8u reg,Bit8u idx,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,imm); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,reg,idx); -} - -static void dyn_mov_word_imm(Bit8u reg) { - Bitu val; - if (decode.big_op) { - if (decode_fetchd_imm(val)) { - gen_mov_word_to_reg(FC_OP1,(void*)val,true); - MOV_REG_WORD32_FROM_HOST_REG(FC_OP1,reg); - return; - } - } else { - if (decode_fetchw_imm(val)) { - gen_mov_word_to_reg(FC_OP1,(void*)val,false); - MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,reg); - return; - } - } - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)val); - else gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)val); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op); -} - - -static void dyn_sop_word(SingleOps op,Bit8u reg) { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); - dyn_sop_word_gencall(op,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); -} - - -static void dyn_mov_byte_al_direct(Bitu imm) { - MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); - gen_add_imm(FC_ADDR,imm); - dyn_read_byte(FC_ADDR,FC_TMP_BA1); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0); -} - -static void dyn_mov_byte_ax_direct(Bitu imm) { - MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); - gen_add_imm(FC_ADDR,imm); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); -} - -static void dyn_mov_byte_direct_al() { - MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); - if (decode.big_addr) { - Bitu val; - if (decode_fetchd_imm(val)) { - gen_add(FC_ADDR,(void*)val); - } else { - gen_add_imm(FC_ADDR,(Bit32u)val); - } - } else { - gen_add_imm(FC_ADDR,decode_fetchw()); - } - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0); - dyn_write_byte(FC_ADDR,FC_TMP_BA1); -} - -static void dyn_mov_byte_direct_ax(Bitu imm) { - MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); - gen_add_imm(FC_ADDR,imm); - MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); - dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); -} - - -static void dyn_movx_ev_gb(bool sign) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_byte(FC_ADDR,FC_TMP_BA1); - gen_extend_byte(sign,FC_TMP_BA1); - MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - gen_extend_byte(sign,FC_TMP_BA1); - MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op); - } -} - -static void dyn_movx_ev_gw(bool sign) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_OP1,false); - gen_extend_word(sign,FC_OP1); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - } else { - MOV_REG_WORD16_TO_HOST_REG(FC_OP1,decode.modrm.rm); - gen_extend_word(sign,FC_OP1); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - } -} - - -static void dyn_mov_ev_seg(void) { - dyn_get_modrm(); - MOV_SEG_VAL_TO_HOST_REG(FC_OP1,decode.modrm.reg); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_write_word(FC_ADDR,FC_OP1,false); - } else { - if (decode.big_op) gen_extend_word(false,FC_OP1); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } -} - - -static void dyn_lea(void) { - dyn_get_modrm(); - dyn_fill_ea(FC_ADDR,false); - MOV_REG_WORD_FROM_HOST_REG(FC_ADDR,decode.modrm.reg,decode.big_op); -} - - -static void dyn_push_seg(Bit8u seg) { - MOV_SEG_VAL_TO_HOST_REG(FC_OP1,seg); - if (decode.big_op) { - gen_extend_word(false,FC_OP1); - gen_call_function_raw((void*)&dynrec_push_dword); - } else { - gen_call_function_raw((void*)&dynrec_push_word); - } -} - -static void dyn_pop_seg(Bit8u seg) { - gen_call_function_II((void *)&CPU_PopSeg,seg,decode.big_op); - dyn_check_exception(FC_RETOP); -} - -static void dyn_push_reg(Bit8u reg) { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); - if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); - else gen_call_function_raw((void*)&dynrec_push_word); -} - -static void dyn_pop_reg(Bit8u reg) { - if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); - else gen_call_function_raw((void*)&dynrec_pop_word); - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); -} - -static void dyn_push_byte_imm(Bit8s imm) { - gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)imm); - if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); - else gen_call_function_raw((void*)&dynrec_push_word); -} - -static void dyn_push_word_imm(Bitu imm) { - if (decode.big_op) { - gen_mov_dword_to_reg_imm(FC_OP1,imm); - gen_call_function_raw((void*)&dynrec_push_dword); - } else { - gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)imm); - gen_call_function_raw((void*)&dynrec_push_word); - } -} - -static void dyn_pop_ev(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { -/* dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); // dummy read to trigger possible page faults */ - if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); - else gen_call_function_raw((void*)&dynrec_pop_word); - dyn_fill_ea(FC_ADDR); -// gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); - } else { - if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); - else gen_call_function_raw((void*)&dynrec_pop_word); - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); - } -} - - -static void dyn_segprefix(Bit8u seg) { -// if (GCC_UNLIKELY(decode.seg_prefix_used)) IllegalOptionDynrec("dyn_segprefix"); - decode.seg_prefix=seg; - decode.seg_prefix_used=true; -} - - static void dyn_mov_seg_ev(void) { - dyn_get_modrm(); - if (GCC_UNLIKELY(decode.modrm.reg==DRC_SEG_CS)) IllegalOptionDynrec("dyn_mov_seg_ev"); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_RETOP,false); - } else { - MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); - } - gen_call_function_IR((void *)&CPU_SetSegGeneral,decode.modrm.reg,FC_RETOP); - dyn_check_exception(FC_RETOP); -} - -static void dyn_load_seg_off_ea(Bit8u seg) { - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_protect_reg(FC_OP1); - - gen_restore_addr_reg(); - gen_add_imm(FC_ADDR,decode.big_op ? 4:2); - dyn_read_word(FC_ADDR,FC_RETOP,false); - - gen_call_function_IR((void *)&CPU_SetSegGeneral,seg,FC_RETOP); - dyn_check_exception(FC_RETOP); - - gen_restore_reg(FC_OP1); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); - } else { - IllegalOptionDynrec("dyn_load_seg_off_ea"); - } -} - - - -static void dyn_imul_gvev(Bitu immsize) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } - - switch (immsize) { - case 0: - MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - break; - case 1: - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb()); - else gen_mov_word_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb()); - break; - case 2: - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit16s)decode_fetchw()); - else gen_mov_word_to_reg_imm(FC_OP2,(Bit16s)decode_fetchw()); - break; - case 4: - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32s)decode_fetchd()); - else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)((Bit32s)decode_fetchd())); - break; - } - - if (decode.big_op) gen_call_function_raw((void*)dynrec_dimul_dword); - else gen_call_function_raw((void*)dynrec_dimul_word); - - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); -} - -static void dyn_dshift_ev_gv(bool left,bool immediate) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } - MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - if (immediate) gen_mov_byte_to_reg_low_imm(FC_OP3,decode_fetchb()); - else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_OP3,DRC_REG_ECX,0); - if (decode.big_op) dyn_dpshift_dword_gencall(left); - else dyn_dpshift_word_gencall(left); - - if (decode.modrm.mod<3) { - gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); - } else { - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); - } -} - - -static void dyn_grp1_eb_ib(void) { - dyn_get_modrm(); - DualOps op=grp1_table[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_byte_canuseword(FC_ADDR,FC_OP1); - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); - dyn_dop_byte_gencall(op); - - if ((op!=DOP_CMP) && (op!=DOP_TEST)) { - gen_restore_addr_reg(); - dyn_write_byte(FC_ADDR,FC_RETOP); - } - } else { - dyn_dop_byte_imm_mem(op,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} - -static void dyn_grp1_ev_iv(bool withbyte) { - dyn_get_modrm(); - DualOps op=grp1_table[decode.modrm.reg]; - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - - if (!withbyte) { - dyn_prep_word_imm(FC_OP2); - } else { - Bits imm=(Bit8s)decode_fetchb(); - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); - else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm); - } - - dyn_dop_word_gencall(op,decode.big_op); - - if ((op!=DOP_CMP) && (op!=DOP_TEST)) { - gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); - } - } else { - if (!withbyte) { - dyn_dop_word_imm(op,decode.modrm.rm); - } else { - Bits imm=withbyte ? (Bit8s)decode_fetchb() : (decode.big_op ? decode_fetchd(): decode_fetchw()); - dyn_dop_word_imm_old(op,decode.modrm.rm,imm); - } - } -} - - -static void dyn_grp2_eb(grp2_types type) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_byte_canuseword(FC_ADDR,FC_OP1); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } - switch (type) { - case grp2_1: - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1); - dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); - break; - case grp2_imm: { - Bit8u imm=decode_fetchb(); - if (imm) { - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f); - dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); - } else return; - } - break; - case grp2_cl: - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0); - gen_and_imm(FC_OP2,0x1f); - dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); - break; - } - if (decode.modrm.mod<3) { - gen_restore_addr_reg(); - dyn_write_byte(FC_ADDR,FC_RETOP); - } else { - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} - -static void dyn_grp2_ev(grp2_types type) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } - switch (type) { - case grp2_1: - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,1); - dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); - break; - case grp2_imm: { - Bitu val; - if (decode_fetchb_imm(val)) { - gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val); - gen_and_imm(FC_OP2,0x1f); - dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); - break; - } - Bit8u imm=(Bit8u)val; - if (imm) { - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,imm&0x1f); - dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); - } else return; - } - break; - case grp2_cl: - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0); - gen_and_imm(FC_OP2,0x1f); - dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); - break; - } - if (decode.modrm.mod<3) { - gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); - } else { - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); - } -} - - -static void dyn_grp3_eb(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); - dyn_read_byte_canuseword(FC_ADDR,FC_OP1); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } - switch (decode.modrm.reg) { - case 0x0: // test eb,ib - gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); - dyn_dop_byte_gencall(DOP_TEST); - return; - case 0x2: // NOT Eb - dyn_sop_byte_gencall(SOP_NOT); - break; - case 0x3: // NEG Eb - dyn_sop_byte_gencall(SOP_NEG); - break; - case 0x4: // mul Eb - gen_call_function_raw((void*)&dynrec_mul_byte); - return; - case 0x5: // imul Eb - gen_call_function_raw((void*)&dynrec_imul_byte); - return; - case 0x6: // div Eb - gen_call_function_raw((void*)&dynrec_div_byte); - dyn_check_exception(FC_RETOP); - return; - case 0x7: // idiv Eb - gen_call_function_raw((void*)&dynrec_idiv_byte); - dyn_check_exception(FC_RETOP); - return; - } - // Save the result if memory op - if (decode.modrm.mod<3) { - gen_restore_addr_reg(); - dyn_write_byte(FC_ADDR,FC_RETOP); - } else { - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} - -static void dyn_grp3_ev(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } - switch (decode.modrm.reg) { - case 0x0: // test ev,iv - if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,decode_fetchd()); - else gen_mov_word_to_reg_imm(FC_OP2,decode_fetchw()); - dyn_dop_word_gencall(DOP_TEST,decode.big_op); - return; - case 0x2: // NOT Ev - dyn_sop_word_gencall(SOP_NOT,decode.big_op); - break; - case 0x3: // NEG Eb - dyn_sop_word_gencall(SOP_NEG,decode.big_op); - break; - case 0x4: // mul Eb - if (decode.big_op) gen_call_function_raw((void*)&dynrec_mul_dword); - else gen_call_function_raw((void*)&dynrec_mul_word); - return; - case 0x5: // imul Eb - if (decode.big_op) gen_call_function_raw((void*)&dynrec_imul_dword); - else gen_call_function_raw((void*)&dynrec_imul_word); - return; - case 0x6: // div Eb - if (decode.big_op) gen_call_function_raw((void*)&dynrec_div_dword); - else gen_call_function_raw((void*)&dynrec_div_word); - dyn_check_exception(FC_RETOP); - return; - case 0x7: // idiv Eb - if (decode.big_op) gen_call_function_raw((void*)&dynrec_idiv_dword); - else gen_call_function_raw((void*)&dynrec_idiv_word); - dyn_check_exception(FC_RETOP); - return; - } - // Save the result if memory op - if (decode.modrm.mod<3) { - gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); - } else { - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); - } -} - - -static bool dyn_grp4_eb(void) { - dyn_get_modrm(); - switch (decode.modrm.reg) { - case 0x0://INC Eb - case 0x1://DEC Eb - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_byte_canuseword(FC_ADDR,FC_OP1); - dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC); - gen_restore_addr_reg(); - dyn_write_byte(FC_ADDR,FC_RETOP); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC); - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } - break; - case 0x7: //CALBACK Iw - gen_mov_direct_dword(&core_dynrec.callback,decode_fetchw()); - dyn_set_eip_end(); - dyn_reduce_cycles(); - dyn_return(BR_CallBack); - dyn_closeblock(); - return true; - default: - IllegalOptionDynrec("dyn_grp4_eb"); - break; - } - return false; -} - -static Bitu dyn_grp4_ev(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5)) gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - } else { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); - } - switch (decode.modrm.reg) { - case 0x0://INC Ev - case 0x1://DEC Ev - dyn_sop_word_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC,decode.big_op); - if (decode.modrm.mod<3) { - gen_restore_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); - } else { - MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); - } - break; - case 0x2: // CALL Ev - gen_mov_regs(FC_ADDR,FC_OP1); - gen_protect_addr_reg(); - gen_mov_word_to_reg(FC_OP1,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); - gen_add_imm(FC_OP1,(Bit32u)(decode.code-decode.code_start)); - if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); - else gen_call_function_raw((void*)&dynrec_push_word); - - gen_restore_addr_reg(); - gen_mov_word_from_reg(FC_ADDR,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); - return 1; - case 0x4: // JMP Ev - gen_mov_word_from_reg(FC_OP1,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); - return 1; - case 0x3: // CALL Ep - case 0x5: // JMP Ep - if (!decode.big_op) gen_extend_word(false,FC_OP1); - if (decode.modrm.mod<3) gen_restore_addr_reg(); - gen_protect_reg(FC_OP1); - gen_add_imm(FC_ADDR,decode.big_op?4:2); - dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); - gen_extend_word(false,FC_OP2); - - dyn_set_eip_last_end(FC_RETOP); - gen_restore_reg(FC_OP1,FC_ADDR); - gen_call_function_IRRR(decode.modrm.reg == 3 ? (void*)(&CPU_CALL) : (void*)(&CPU_JMP), - decode.big_op,FC_OP2,FC_ADDR,FC_RETOP); - return 1; - case 0x6: // PUSH Ev - if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); - else gen_call_function_raw((void*)&dynrec_push_word); - break; - default: -// IllegalOptionDynrec("dyn_grp4_ev"); - return 2; - } - return 0; -} - - -static bool dyn_grp6(void) { - dyn_get_modrm(); - switch (decode.modrm.reg) { - case 0x00: // SLDT - case 0x01: // STR - if (decode.modrm.reg==0) gen_call_function_raw((void*)CPU_SLDT); - else gen_call_function_raw((void*)CPU_STR); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_write_word(FC_ADDR,FC_RETOP,false); - } else { - MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm); - } - break; - case 0x02: // LLDT - case 0x03: // LTR - case 0x04: // VERR - case 0x05: // VERW - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_RETOP,false); - } else { - MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); - } - gen_extend_word(false,FC_RETOP); - switch (decode.modrm.reg) { - case 0x02: // LLDT -// if (cpu.cpl) return CPU_PrepareException(EXCEPTION_GP,0); - if (cpu.cpl) E_Exit("lldt cpl>0"); - gen_call_function_R((void*)CPU_LLDT,FC_RETOP); - dyn_check_exception(FC_RETOP); - break; - case 0x03: // LTR -// if (cpu.cpl) return CPU_PrepareException(EXCEPTION_GP,0); - if (cpu.cpl) E_Exit("ltr cpl>0"); - gen_call_function_R((void*)CPU_LTR,FC_RETOP); - dyn_check_exception(FC_RETOP); - break; - case 0x04: // VERR - gen_call_function_R((void*)CPU_VERR,FC_RETOP); - break; - case 0x05: // VERW - gen_call_function_R((void*)CPU_VERW,FC_RETOP); - break; - } - break; - default: IllegalOptionDynrec("dyn_grp6"); - } - return false; -} - -static bool dyn_grp7(void) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - switch (decode.modrm.reg) { - case 0x00: // SGDT - gen_call_function_raw((void*)CPU_SGDT_limit); - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,false); - gen_call_function_raw((void*)CPU_SGDT_base); - gen_restore_addr_reg(); - gen_add_imm(FC_ADDR,2); - dyn_write_word(FC_ADDR,FC_RETOP,true); - break; - case 0x01: // SIDT - gen_call_function_raw((void*)CPU_SIDT_limit); - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_write_word(FC_ADDR,FC_RETOP,false); - gen_call_function_raw((void*)CPU_SIDT_base); - gen_restore_addr_reg(); - gen_add_imm(FC_ADDR,2); - dyn_write_word(FC_ADDR,FC_RETOP,true); - break; - case 0x02: // LGDT - case 0x03: // LIDT -// if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (cpu.pmode && cpu.cpl) IllegalOptionDynrec("lgdt nonpriviledged"); - dyn_fill_ea(FC_ADDR); - gen_protect_addr_reg(); - dyn_read_word(FC_ADDR,FC_OP1,false); - gen_extend_word(false,FC_OP1); - gen_protect_reg(FC_OP1); - - gen_restore_addr_reg(); - gen_add_imm(FC_ADDR,2); - dyn_read_word(FC_ADDR,FC_OP2,true); - if (!decode.big_op) gen_and_imm(FC_OP2,0xffffff); - - gen_restore_reg(FC_OP1); - if (decode.modrm.reg==2) gen_call_function_RR((void*)CPU_LGDT,FC_OP1,FC_OP2); - else gen_call_function_RR((void*)CPU_LIDT,FC_OP1,FC_OP2); - break; - case 0x04: // SMSW - gen_call_function_raw((void*)CPU_SMSW); - dyn_fill_ea(FC_ADDR); - dyn_write_word(FC_ADDR,FC_RETOP,false); - break; - case 0x06: // LMSW - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_RETOP,false); - gen_call_function_R((void*)CPU_LMSW,FC_RETOP); - dyn_check_exception(FC_RETOP); - dyn_set_eip_end(); - dyn_reduce_cycles(); - dyn_return(BR_Normal); - dyn_closeblock(); - return true; - case 0x07: // INVLPG -// if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (cpu.pmode && cpu.cpl) IllegalOptionDynrec("invlpg nonpriviledged"); - gen_call_function_raw((void*)PAGING_ClearTLB); - break; - default: IllegalOptionDynrec("dyn_grp7_1"); - } - } else { - switch (decode.modrm.reg) { - case 0x04: // SMSW - gen_call_function_raw((void*)CPU_SMSW); - MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm); - break; - case 0x06: // LMSW - MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); - gen_call_function_R((void*)CPU_LMSW,FC_RETOP); - dyn_check_exception(FC_RETOP); - dyn_set_eip_end(); - dyn_reduce_cycles(); - dyn_return(BR_Normal); - dyn_closeblock(); - return true; - default: IllegalOptionDynrec("dyn_grp7_2"); - } - } - return false; -} - - -/* -static void dyn_larlsl(bool is_lar) { - dyn_get_modrm(); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_read_word(FC_ADDR,FC_RETOP,false); - } else { - MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); - } - gen_extend_word(false,FC_RETOP); - if (is_lar) gen_call_function((void*)CPU_LAR,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); - else gen_call_function((void*)CPU_LSL,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); - DRC_PTR_SIZE_IM brnz=gen_create_branch_on_nonzero(FC_RETOP,true); - gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); - MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); - gen_fill_branch(brnz); -} -*/ - - -static void dyn_mov_from_crx(void) { - dyn_get_modrm(); - gen_call_function_IA((void*)CPU_READ_CRX,decode.modrm.reg,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); - dyn_check_exception(FC_RETOP); - gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); - MOV_REG_WORD32_FROM_HOST_REG(FC_OP2,decode.modrm.rm); -} - -static void dyn_mov_to_crx(void) { - dyn_get_modrm(); - MOV_REG_WORD32_TO_HOST_REG(FC_RETOP,decode.modrm.rm); - gen_call_function_IR((void*)CPU_WRITE_CRX,decode.modrm.reg,FC_RETOP); - dyn_check_exception(FC_RETOP); - dyn_set_eip_end(); - dyn_reduce_cycles(); - dyn_return(BR_Normal); - dyn_closeblock(); -} - - -static void dyn_cbw(void) { - if (decode.big_op) { - MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX); - gen_call_function_raw((void *)&dynrec_cwde); - MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX); - } else { - MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,DRC_REG_EAX,0); - gen_call_function_raw((void *)&dynrec_cbw); - MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX); - } -} - -static void dyn_cwd(void) { - MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); - if (decode.big_op) { - gen_call_function_raw((void *)&dynrec_cdq); - MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX); - } else { - gen_call_function_raw((void *)&dynrec_cwd); - MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX); - } -} - -static void dyn_sahf(void) { - MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX); - gen_call_function_raw((void *)&dynrec_sahf); - InvalidateFlags(); -} - - -static void dyn_exit_link(Bits eip_change) { - gen_add_direct_word(®_eip,(decode.code-decode.code_start)+eip_change,decode.big_op); - dyn_reduce_cycles(); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); - dyn_closeblock(); -} - - -static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) { - Bitu eip_base=decode.code-decode.code_start; - dyn_reduce_cycles(); - - dyn_branchflag_to_reg(btype); - DRC_PTR_SIZE_IM data=gen_create_branch_on_nonzero(FC_RETOP,true); - - // Branch not taken - gen_add_direct_word(®_eip,eip_base,decode.big_op); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); - gen_fill_branch(data); - - // Branch taken - gen_add_direct_word(®_eip,eip_base+eip_add,decode.big_op); - gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlockDynRec,cache.start)); - dyn_closeblock(); -} - -/* -static void dyn_set_byte_on_condition(BranchTypes btype) { - dyn_get_modrm(); - dyn_branchflag_to_reg(btype); - gen_and_imm(FC_RETOP,1); - if (decode.modrm.mod<3) { - dyn_fill_ea(FC_ADDR); - dyn_write_byte(FC_ADDR,FC_RETOP); - } else { - MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); - } -} -*/ - -static void dyn_loop(LoopTypes type) { - dyn_reduce_cycles(); - Bits eip_add=(Bit8s)decode_fetchb(); - Bitu eip_base=decode.code-decode.code_start; - DRC_PTR_SIZE_IM branch1=0; - DRC_PTR_SIZE_IM branch2=0; - switch (type) { - case LOOP_E: - dyn_branchflag_to_reg(BR_NZ); - branch1=gen_create_branch_on_nonzero(FC_RETOP,true); - break; - case LOOP_NE: - dyn_branchflag_to_reg(BR_Z); - branch1=gen_create_branch_on_nonzero(FC_RETOP,true); - break; - } - switch (type) { - case LOOP_E: - case LOOP_NE: - case LOOP_NONE: - MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); - gen_add_imm(FC_OP1,(Bit32u)(-1)); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); - branch2=gen_create_branch_on_zero(FC_OP1,decode.big_addr); - break; - case LOOP_JCXZ: - MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); - branch2=gen_create_branch_on_nonzero(FC_OP1,decode.big_addr); - break; - } - gen_add_direct_word(®_eip,eip_base+eip_add,true); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); - if (branch1) { - gen_fill_branch(branch1); - MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); - gen_add_imm(FC_OP1,(Bit32u)(-1)); - MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); - } - // Branch taken - gen_fill_branch(branch2); - gen_add_direct_word(®_eip,eip_base,decode.big_op); - gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlockDynRec,cache.start)); - dyn_closeblock(); -} - - -static void dyn_ret_near(Bitu bytes) { - dyn_reduce_cycles(); - - if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); - else { - gen_call_function_raw((void*)&dynrec_pop_word); - gen_extend_word(false,FC_RETOP); - } - gen_mov_word_from_reg(FC_RETOP,decode.big_op?(void*)(®_eip):(void*)(®_ip),true); - - if (bytes) gen_add_direct_word(®_esp,bytes,true); - dyn_return(BR_Normal); - dyn_closeblock(); -} - -static void dyn_call_near_imm(void) { - Bits imm; - if (decode.big_op) imm=(Bit32s)decode_fetchd(); - else imm=(Bit16s)decode_fetchw(); - dyn_set_eip_end(FC_OP1); - if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); - else gen_call_function_raw((void*)&dynrec_push_word); - - dyn_set_eip_end(FC_OP1,imm); - gen_mov_word_from_reg(FC_OP1,decode.big_op?(void*)(®_eip):(void*)(®_ip),decode.big_op); - - dyn_reduce_cycles(); - gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); - dyn_closeblock(); -} - -static void dyn_ret_far(Bitu bytes) { - dyn_reduce_cycles(); - dyn_set_eip_last_end(FC_RETOP); - gen_call_function_IIR((void*)&CPU_RET,decode.big_op,bytes,FC_RETOP); - dyn_return(BR_Normal); - dyn_closeblock(); -} - -static void dyn_call_far_imm(void) { - Bitu sel,off; - off=decode.big_op ? decode_fetchd() : decode_fetchw(); - sel=decode_fetchw(); - dyn_reduce_cycles(); - dyn_set_eip_last_end(FC_RETOP); - gen_call_function_IIIR((void*)&CPU_CALL,decode.big_op,sel,off,FC_RETOP); - dyn_return(BR_Normal); - dyn_closeblock(); -} - -static void dyn_jmp_far_imm(void) { - Bitu sel,off; - off=decode.big_op ? decode_fetchd() : decode_fetchw(); - sel=decode_fetchw(); - dyn_reduce_cycles(); - dyn_set_eip_last_end(FC_RETOP); - gen_call_function_IIIR((void*)&CPU_JMP,decode.big_op,sel,off,FC_RETOP); - dyn_return(BR_Normal); - dyn_closeblock(); -} - -static void dyn_iret(void) { - dyn_reduce_cycles(); - dyn_set_eip_last_end(FC_RETOP); - gen_call_function_IR((void*)&CPU_IRET,decode.big_op,FC_RETOP); - dyn_return(BR_Iret); - dyn_closeblock(); -} - -static void dyn_interrupt(Bit8u num) { - dyn_reduce_cycles(); - dyn_set_eip_last_end(FC_RETOP); - gen_call_function_IIR((void*)&CPU_Interrupt,num,CPU_INT_SOFTWARE,FC_RETOP); - dyn_return(BR_Normal); - dyn_closeblock(); -} - - - -static void dyn_string(StringOps op) { - if (decode.rep) MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); - else gen_mov_dword_to_reg_imm(FC_OP1,1); - gen_mov_word_to_reg(FC_OP2,&cpu.direction,true); - Bit8u di_base_addr=decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS; - switch (op) { - case STR_MOVSB: - if (decode.big_addr) gen_call_function_mm((void*)&dynrec_movsb_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - else gen_call_function_mm((void*)&dynrec_movsb_word,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - break; - case STR_MOVSW: - if (decode.big_addr) gen_call_function_mm((void*)&dynrec_movsw_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - else gen_call_function_mm((void*)&dynrec_movsw_word,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - break; - case STR_MOVSD: - if (decode.big_addr) gen_call_function_mm((void*)&dynrec_movsd_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - else gen_call_function_mm((void*)&dynrec_movsd_word,(Bitu)DRCD_SEG_PHYS(di_base_addr),(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - break; - - case STR_LODSB: - if (decode.big_addr) gen_call_function_m((void*)&dynrec_lodsb_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr)); - else gen_call_function_m((void*)&dynrec_lodsb_word,(Bitu)DRCD_SEG_PHYS(di_base_addr)); - break; - case STR_LODSW: - if (decode.big_addr) gen_call_function_m((void*)&dynrec_lodsw_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr)); - else gen_call_function_m((void*)&dynrec_lodsw_word,(Bitu)DRCD_SEG_PHYS(di_base_addr)); - break; - case STR_LODSD: - if (decode.big_addr) gen_call_function_m((void*)&dynrec_lodsd_dword,(Bitu)DRCD_SEG_PHYS(di_base_addr)); - else gen_call_function_m((void*)&dynrec_lodsd_word,(Bitu)DRCD_SEG_PHYS(di_base_addr)); - break; - - case STR_STOSB: - if (decode.big_addr) gen_call_function_m((void*)&dynrec_stosb_dword,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - else gen_call_function_m((void*)&dynrec_stosb_word,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - break; - case STR_STOSW: - if (decode.big_addr) gen_call_function_m((void*)&dynrec_stosw_dword,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - else gen_call_function_m((void*)&dynrec_stosw_word,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - break; - case STR_STOSD: - if (decode.big_addr) gen_call_function_m((void*)&dynrec_stosd_dword,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - else gen_call_function_m((void*)&dynrec_stosd_word,(Bitu)DRCD_SEG_PHYS(DRC_SEG_ES)); - break; - default: IllegalOptionDynrec("dyn_string"); - } - if (decode.rep) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_ECX,decode.big_addr); - - if (op -#include -#include "cross.h" -#include "mem.h" -#include "fpu.h" -#include "cpu.h" - - -static void FPU_FDECSTP(){ - TOP = (TOP - 1) & 7; -} - -static void FPU_FINCSTP(){ - TOP = (TOP + 1) & 7; -} - -static void FPU_FNSTCW(PhysPt addr){ - mem_writew(addr,fpu.cw); -} - -static void FPU_FFREE(Bitu st) { - fpu.tags[st]=TAG_Empty; -} - - -#if C_FPU_X86 -#include "../../fpu/fpu_instructions_x86.h" -#else -#include "../../fpu/fpu_instructions.h" -#endif - - -static INLINE void dyn_fpu_top() { - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_add_imm(FC_OP2,decode.modrm.rm); - gen_and_imm(FC_OP2,7); - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); -} - -static INLINE void dyn_fpu_top_swapped() { - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - gen_add_imm(FC_OP1,decode.modrm.rm); - gen_and_imm(FC_OP1,7); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); -} - -static void dyn_eatree() { - Bitu group=(decode.modrm.val >> 3) & 7; - switch (group){ - case 0x00: // FADD ST,STi - gen_call_function_R((void*)&FPU_FADD_EA,FC_OP1); - break; - case 0x01: // FMUL ST,STi - gen_call_function_R((void*)&FPU_FMUL_EA,FC_OP1); - break; - case 0x02: // FCOM STi - gen_call_function_R((void*)&FPU_FCOM_EA,FC_OP1); - break; - case 0x03: // FCOMP STi - gen_call_function_R((void*)&FPU_FCOM_EA,FC_OP1); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: // FSUB ST,STi - gen_call_function_R((void*)&FPU_FSUB_EA,FC_OP1); - break; - case 0x05: // FSUBR ST,STi - gen_call_function_R((void*)&FPU_FSUBR_EA,FC_OP1); - break; - case 0x06: // FDIV ST,STi - gen_call_function_R((void*)&FPU_FDIV_EA,FC_OP1); - break; - case 0x07: // FDIVR ST,STi - gen_call_function_R((void*)&FPU_FDIVR_EA,FC_OP1); - break; - default: - break; - } -} - -static void dyn_fpu_esc0(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - dyn_fpu_top(); - switch (decode.modrm.reg){ - case 0x00: //FADD ST,STi - gen_call_function_RR((void*)&FPU_FADD,FC_OP1,FC_OP2); - break; - case 0x01: // FMUL ST,STi - gen_call_function_RR((void*)&FPU_FMUL,FC_OP1,FC_OP2); - break; - case 0x02: // FCOM STi - gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2); - break; - case 0x03: // FCOMP STi - gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: // FSUB ST,STi - gen_call_function_RR((void*)&FPU_FSUB,FC_OP1,FC_OP2); - break; - case 0x05: // FSUBR ST,STi - gen_call_function_RR((void*)&FPU_FSUBR,FC_OP1,FC_OP2); - break; - case 0x06: // FDIV ST,STi - gen_call_function_RR((void*)&FPU_FDIV,FC_OP1,FC_OP2); - break; - case 0x07: // FDIVR ST,STi - gen_call_function_RR((void*)&FPU_FDIVR,FC_OP1,FC_OP2); - break; - default: - break; - } - } else { - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FLD_F32_EA,FC_ADDR); - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - dyn_eatree(); - } -} - - -static void dyn_fpu_esc1(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - switch (decode.modrm.reg){ - case 0x00: /* FLD STi */ - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - gen_add_imm(FC_OP1,decode.modrm.rm); - gen_and_imm(FC_OP1,7); - gen_protect_reg(FC_OP1); - gen_call_function_raw((void*)&FPU_PREP_PUSH); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_restore_reg(FC_OP1); - gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2); - break; - case 0x01: /* FXCH STi */ - dyn_fpu_top(); - gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2); - break; - case 0x02: /* FNOP */ - gen_call_function_raw((void*)&FPU_FNOP); - break; - case 0x03: /* FSTP STi */ - dyn_fpu_top(); - gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: - switch(decode.modrm.rm){ - case 0x00: /* FCHS */ - gen_call_function_raw((void*)&FPU_FCHS); - break; - case 0x01: /* FABS */ - gen_call_function_raw((void*)&FPU_FABS); - break; - case 0x02: /* UNKNOWN */ - case 0x03: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm); - break; - case 0x04: /* FTST */ - gen_call_function_raw((void*)&FPU_FTST); - break; - case 0x05: /* FXAM */ - gen_call_function_raw((void*)&FPU_FXAM); - break; - case 0x06: /* FTSTP (cyrix)*/ - case 0x07: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm); - break; - } - break; - case 0x05: - switch(decode.modrm.rm){ - case 0x00: /* FLD1 */ - gen_call_function_raw((void*)&FPU_FLD1); - break; - case 0x01: /* FLDL2T */ - gen_call_function_raw((void*)&FPU_FLDL2T); - break; - case 0x02: /* FLDL2E */ - gen_call_function_raw((void*)&FPU_FLDL2E); - break; - case 0x03: /* FLDPI */ - gen_call_function_raw((void*)&FPU_FLDPI); - break; - case 0x04: /* FLDLG2 */ - gen_call_function_raw((void*)&FPU_FLDLG2); - break; - case 0x05: /* FLDLN2 */ - gen_call_function_raw((void*)&FPU_FLDLN2); - break; - case 0x06: /* FLDZ*/ - gen_call_function_raw((void*)&FPU_FLDZ); - break; - case 0x07: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm); - break; - } - break; - case 0x06: - switch(decode.modrm.rm){ - case 0x00: /* F2XM1 */ - gen_call_function_raw((void*)&FPU_F2XM1); - break; - case 0x01: /* FYL2X */ - gen_call_function_raw((void*)&FPU_FYL2X); - break; - case 0x02: /* FPTAN */ - gen_call_function_raw((void*)&FPU_FPTAN); - break; - case 0x03: /* FPATAN */ - gen_call_function_raw((void*)&FPU_FPATAN); - break; - case 0x04: /* FXTRACT */ - gen_call_function_raw((void*)&FPU_FXTRACT); - break; - case 0x05: /* FPREM1 */ - gen_call_function_raw((void*)&FPU_FPREM1); - break; - case 0x06: /* FDECSTP */ - gen_call_function_raw((void*)&FPU_FDECSTP); - break; - case 0x07: /* FINCSTP */ - gen_call_function_raw((void*)&FPU_FINCSTP); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm); - break; - } - break; - case 0x07: - switch(decode.modrm.rm){ - case 0x00: /* FPREM */ - gen_call_function_raw((void*)&FPU_FPREM); - break; - case 0x01: /* FYL2XP1 */ - gen_call_function_raw((void*)&FPU_FYL2XP1); - break; - case 0x02: /* FSQRT */ - gen_call_function_raw((void*)&FPU_FSQRT); - break; - case 0x03: /* FSINCOS */ - gen_call_function_raw((void*)&FPU_FSINCOS); - break; - case 0x04: /* FRNDINT */ - gen_call_function_raw((void*)&FPU_FRNDINT); - break; - case 0x05: /* FSCALE */ - gen_call_function_raw((void*)&FPU_FSCALE); - break; - case 0x06: /* FSIN */ - gen_call_function_raw((void*)&FPU_FSIN); - break; - case 0x07: /* FCOS */ - gen_call_function_raw((void*)&FPU_FCOS); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm); - break; - } - } else { - switch(decode.modrm.reg){ - case 0x00: /* FLD float*/ - gen_call_function_raw((void*)&FPU_PREP_PUSH); - dyn_fill_ea(FC_OP1); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_call_function_RR((void*)&FPU_FLD_F32,FC_OP1,FC_OP2); - break; - case 0x01: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - case 0x02: /* FST float*/ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_F32,FC_ADDR); - break; - case 0x03: /* FSTP float*/ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_F32,FC_ADDR); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: /* FLDENV */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FLDENV,FC_ADDR); - break; - case 0x05: /* FLDCW */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void *)&FPU_FLDCW,FC_ADDR); - break; - case 0x06: /* FSTENV */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void *)&FPU_FSTENV,FC_ADDR); - break; - case 0x07: /* FNSTCW*/ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void *)&FPU_FNSTCW,FC_ADDR); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - } -} - -static void dyn_fpu_esc2(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - switch(decode.modrm.reg){ - case 0x05: - switch(decode.modrm.rm){ - case 0x01: /* FUCOMPP */ - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_add_imm(FC_OP2,1); - gen_and_imm(FC_OP2,7); - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - gen_call_function_RR((void *)&FPU_FUCOM,FC_OP1,FC_OP2); - gen_call_function_raw((void *)&FPU_FPOP); - gen_call_function_raw((void *)&FPU_FPOP); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - } else { - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FLD_I32_EA,FC_ADDR); - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - dyn_eatree(); - } -} - -static void dyn_fpu_esc3(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - switch (decode.modrm.reg) { - case 0x04: - switch (decode.modrm.rm) { - case 0x00: //FNENI - case 0x01: //FNDIS - LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion: %d",decode.modrm.rm); - break; - case 0x02: //FNCLEX FCLEX - gen_call_function_raw((void*)&FPU_FCLEX); - break; - case 0x03: //FNINIT FINIT - gen_call_function_raw((void*)&FPU_FINIT); - break; - case 0x04: //FNSETPM - case 0x05: //FRSTPM -// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); - break; - default: - E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - } else { - switch(decode.modrm.reg){ - case 0x00: /* FILD */ - gen_call_function_raw((void*)&FPU_PREP_PUSH); - dyn_fill_ea(FC_OP1); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_call_function_RR((void*)&FPU_FLD_I32,FC_OP1,FC_OP2); - break; - case 0x01: /* FISTTP */ - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - case 0x02: /* FIST */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_I32,FC_ADDR); - break; - case 0x03: /* FISTP */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_I32,FC_ADDR); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x05: /* FLD 80 Bits Real */ - gen_call_function_raw((void*)&FPU_PREP_PUSH); - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FLD_F80,FC_ADDR); - break; - case 0x07: /* FSTP 80 Bits Real */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_F80,FC_ADDR); - gen_call_function_raw((void*)&FPU_FPOP); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - } - } -} - -static void dyn_fpu_esc4(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - switch(decode.modrm.reg){ - case 0x00: /* FADD STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FADD,FC_OP1,FC_OP2); - break; - case 0x01: /* FMUL STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FMUL,FC_OP1,FC_OP2); - break; - case 0x02: /* FCOM*/ - dyn_fpu_top(); - gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2); - break; - case 0x03: /* FCOMP*/ - dyn_fpu_top(); - gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: /* FSUBR STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FSUBR,FC_OP1,FC_OP2); - break; - case 0x05: /* FSUB STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FSUB,FC_OP1,FC_OP2); - break; - case 0x06: /* FDIVR STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FDIVR,FC_OP1,FC_OP2); - break; - case 0x07: /* FDIV STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FDIV,FC_OP1,FC_OP2); - break; - default: - break; - } - } else { - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FLD_F64_EA,FC_ADDR); - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - dyn_eatree(); - } -} - -static void dyn_fpu_esc5(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - dyn_fpu_top(); - switch(decode.modrm.reg){ - case 0x00: /* FFREE STi */ - gen_call_function_R((void*)&FPU_FFREE,FC_OP2); - break; - case 0x01: /* FXCH STi*/ - gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2); - break; - case 0x02: /* FST STi */ - gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2); - break; - case 0x03: /* FSTP STi*/ - gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: /* FUCOM STi */ - gen_call_function_RR((void*)&FPU_FUCOM,FC_OP1,FC_OP2); - break; - case 0x05: /*FUCOMP STi */ - gen_call_function_RR((void*)&FPU_FUCOM,FC_OP1,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - } else { - switch(decode.modrm.reg){ - case 0x00: /* FLD double real*/ - gen_call_function_raw((void*)&FPU_PREP_PUSH); - dyn_fill_ea(FC_OP1); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_call_function_RR((void*)&FPU_FLD_F64,FC_OP1,FC_OP2); - break; - case 0x01: /* FISTTP longint*/ - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - case 0x02: /* FST double real*/ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_F64,FC_ADDR); - break; - case 0x03: /* FSTP double real*/ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_F64,FC_ADDR); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: /* FRSTOR */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FRSTOR,FC_ADDR); - break; - case 0x06: /* FSAVE */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FSAVE,FC_ADDR); - break; - case 0x07: /*FNSTSW */ - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1); - dyn_fill_ea(FC_OP1); - gen_mov_word_to_reg(FC_OP2,(void*)(&fpu.sw),false); - gen_call_function_RR((void*)&mem_writew,FC_OP1,FC_OP2); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - } - } -} - -static void dyn_fpu_esc6(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - switch(decode.modrm.reg){ - case 0x00: /*FADDP STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FADD,FC_OP1,FC_OP2); - break; - case 0x01: /* FMULP STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FMUL,FC_OP1,FC_OP2); - break; - case 0x02: /* FCOMP5*/ - dyn_fpu_top(); - gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2); - break; /* TODO IS THIS ALLRIGHT ????????? */ - case 0x03: /*FCOMPP*/ - if(decode.modrm.rm != 1) { - LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - return; - } - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_add_imm(FC_OP2,1); - gen_and_imm(FC_OP2,7); - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); /* extra pop at the bottom*/ - break; - case 0x04: /* FSUBRP STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FSUBR,FC_OP1,FC_OP2); - break; - case 0x05: /* FSUBP STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FSUB,FC_OP1,FC_OP2); - break; - case 0x06: /* FDIVRP STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FDIVR,FC_OP1,FC_OP2); - break; - case 0x07: /* FDIVP STi,ST*/ - dyn_fpu_top_swapped(); - gen_call_function_RR((void*)&FPU_FDIV,FC_OP1,FC_OP2); - break; - default: - break; - } - gen_call_function_raw((void*)&FPU_FPOP); - } else { - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FLD_I16_EA,FC_ADDR); - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - dyn_eatree(); - } -} - -static void dyn_fpu_esc7(){ - dyn_get_modrm(); - if (decode.modrm.val >= 0xc0) { - switch (decode.modrm.reg){ - case 0x00: /* FFREEP STi */ - dyn_fpu_top(); - gen_call_function_R((void*)&FPU_FFREE,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x01: /* FXCH STi*/ - dyn_fpu_top(); - gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2); - break; - case 0x02: /* FSTP STi*/ - case 0x03: /* FSTP STi*/ - dyn_fpu_top(); - gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: - switch(decode.modrm.rm){ - case 0x00: /* FNSTSW AX*/ - gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); - gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1); - gen_mov_word_to_reg(FC_OP1,(void*)(&fpu.sw),false); - MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,DRC_REG_EAX); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - } else { - switch(decode.modrm.reg){ - case 0x00: /* FILD Bit16s */ - gen_call_function_raw((void*)&FPU_PREP_PUSH); - dyn_fill_ea(FC_OP1); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_call_function_RR((void*)&FPU_FLD_I16,FC_OP1,FC_OP2); - break; - case 0x01: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - case 0x02: /* FIST Bit16s */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_I16,FC_ADDR); - break; - case 0x03: /* FISTP Bit16s */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_I16,FC_ADDR); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x04: /* FBLD packed BCD */ - gen_call_function_raw((void*)&FPU_PREP_PUSH); - dyn_fill_ea(FC_OP1); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_call_function_RR((void*)&FPU_FBLD,FC_OP1,FC_OP2); - break; - case 0x05: /* FILD Bit64s */ - gen_call_function_raw((void*)&FPU_PREP_PUSH); - dyn_fill_ea(FC_OP1); - gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true); - gen_call_function_RR((void*)&FPU_FLD_I64,FC_OP1,FC_OP2); - break; - case 0x06: /* FBSTP packed BCD */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FBST,FC_ADDR); - gen_call_function_raw((void*)&FPU_FPOP); - break; - case 0x07: /* FISTP Bit64s */ - dyn_fill_ea(FC_ADDR); - gen_call_function_R((void*)&FPU_FST_I64,FC_ADDR); - gen_call_function_raw((void*)&FPU_FPOP); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); - break; - } - } -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/operators.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/operators.h deleted file mode 100644 index 18d174301..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/operators.h +++ /dev/null @@ -1,1996 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_add_byte(Bit8u op1,Bit8u op2) { - lf_var1b=op1; - lf_var2b=op2; - lf_resb=(Bit8u)(lf_var1b+lf_var2b); - lflags.type=t_ADDb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_add_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_add_byte_simple(Bit8u op1,Bit8u op2) { - return op1+op2; -} - -static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_adc_byte(Bit8u op1,Bit8u op2) { - lflags.oldcf=get_CF()!=0; - lf_var1b=op1; - lf_var2b=op2; - lf_resb=(Bit8u)(lf_var1b+lf_var2b+lflags.oldcf); - lflags.type=t_ADCb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_adc_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_adc_byte_simple(Bit8u op1,Bit8u op2) { - return (Bit8u)(op1+op2+(Bitu)(get_CF()!=0)); -} - -static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_sub_byte(Bit8u op1,Bit8u op2) { - lf_var1b=op1; - lf_var2b=op2; - lf_resb=(Bit8u)(lf_var1b-lf_var2b); - lflags.type=t_SUBb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_sub_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_sub_byte_simple(Bit8u op1,Bit8u op2) { - return op1-op2; -} - -static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_sbb_byte(Bit8u op1,Bit8u op2) { - lflags.oldcf=get_CF()!=0; - lf_var1b=op1; - lf_var2b=op2; - lf_resb=(Bit8u)(lf_var1b-(lf_var2b+lflags.oldcf)); - lflags.type=t_SBBb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_sbb_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_sbb_byte_simple(Bit8u op1,Bit8u op2) { - return (Bit8u)(op1-(op2+(Bitu)(get_CF()!=0))); -} - -static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_cmp_byte(Bit8u op1,Bit8u op2) { - lf_var1b=op1; - lf_var2b=op2; - lf_resb=(Bit8u)(lf_var1b-lf_var2b); - lflags.type=t_CMPb; -} - -static void DRC_CALL_CONV dynrec_cmp_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_cmp_byte_simple(Bit8u op1,Bit8u op2) { -} - -static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_xor_byte(Bit8u op1,Bit8u op2) { - lf_var1b=op1; - lf_var2b=op2; - lf_resb=lf_var1b ^ lf_var2b; - lflags.type=t_XORb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_xor_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_xor_byte_simple(Bit8u op1,Bit8u op2) { - return op1 ^ op2; -} - -static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_and_byte(Bit8u op1,Bit8u op2) { - lf_var1b=op1; - lf_var2b=op2; - lf_resb=lf_var1b & lf_var2b; - lflags.type=t_ANDb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_and_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_and_byte_simple(Bit8u op1,Bit8u op2) { - return op1 & op2; -} - -static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_or_byte(Bit8u op1,Bit8u op2) { - lf_var1b=op1; - lf_var2b=op2; - lf_resb=lf_var1b | lf_var2b; - lflags.type=t_ORb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_or_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_or_byte_simple(Bit8u op1,Bit8u op2) { - return op1 | op2; -} - -static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_test_byte(Bit8u op1,Bit8u op2) { - lf_var1b=op1; - lf_var2b=op2; - lf_resb=lf_var1b & lf_var2b; - lflags.type=t_TESTb; -} - -static void DRC_CALL_CONV dynrec_test_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_test_byte_simple(Bit8u op1,Bit8u op2) { -} - -static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_add_word(Bit16u op1,Bit16u op2) { - lf_var1w=op1; - lf_var2w=op2; - lf_resw=(Bit16u)(lf_var1w+lf_var2w); - lflags.type=t_ADDw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_add_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_add_word_simple(Bit16u op1,Bit16u op2) { - return op1+op2; -} - -static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_adc_word(Bit16u op1,Bit16u op2) { - lflags.oldcf=get_CF()!=0; - lf_var1w=op1; - lf_var2w=op2; - lf_resw=(Bit16u)(lf_var1w+lf_var2w+lflags.oldcf); - lflags.type=t_ADCw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_adc_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_adc_word_simple(Bit16u op1,Bit16u op2) { - return (Bit16u)(op1+op2+(Bitu)(get_CF()!=0)); -} - -static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_sub_word(Bit16u op1,Bit16u op2) { - lf_var1w=op1; - lf_var2w=op2; - lf_resw=(Bit16u)(lf_var1w-lf_var2w); - lflags.type=t_SUBw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_sub_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_sub_word_simple(Bit16u op1,Bit16u op2) { - return op1-op2; -} - -static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_sbb_word(Bit16u op1,Bit16u op2) { - lflags.oldcf=get_CF()!=0; - lf_var1w=op1; - lf_var2w=op2; - lf_resw=(Bit16u)(lf_var1w-(lf_var2w+lflags.oldcf)); - lflags.type=t_SBBw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_sbb_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_sbb_word_simple(Bit16u op1,Bit16u op2) { - return (Bit16u)(op1-(op2+(Bitu)(get_CF()!=0))); -} - -static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_cmp_word(Bit16u op1,Bit16u op2) { - lf_var1w=op1; - lf_var2w=op2; - lf_resw=(Bit16u)(lf_var1w-lf_var2w); - lflags.type=t_CMPw; -} - -static void DRC_CALL_CONV dynrec_cmp_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_cmp_word_simple(Bit16u op1,Bit16u op2) { -} - -static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_xor_word(Bit16u op1,Bit16u op2) { - lf_var1w=op1; - lf_var2w=op2; - lf_resw=lf_var1w ^ lf_var2w; - lflags.type=t_XORw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_xor_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_xor_word_simple(Bit16u op1,Bit16u op2) { - return op1 ^ op2; -} - -static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_and_word(Bit16u op1,Bit16u op2) { - lf_var1w=op1; - lf_var2w=op2; - lf_resw=lf_var1w & lf_var2w; - lflags.type=t_ANDw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_and_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_and_word_simple(Bit16u op1,Bit16u op2) { - return op1 & op2; -} - -static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_or_word(Bit16u op1,Bit16u op2) { - lf_var1w=op1; - lf_var2w=op2; - lf_resw=lf_var1w | lf_var2w; - lflags.type=t_ORw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_or_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_or_word_simple(Bit16u op1,Bit16u op2) { - return op1 | op2; -} - -static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_test_word(Bit16u op1,Bit16u op2) { - lf_var1w=op1; - lf_var2w=op2; - lf_resw=lf_var1w & lf_var2w; - lflags.type=t_TESTw; -} - -static void DRC_CALL_CONV dynrec_test_word_simple(Bit16u op1,Bit16u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_test_word_simple(Bit16u op1,Bit16u op2) { -} - -static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_add_dword(Bit32u op1,Bit32u op2) { - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d+lf_var2d; - lflags.type=t_ADDd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_add_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_add_dword_simple(Bit32u op1,Bit32u op2) { - return op1 + op2; -} - -static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_adc_dword(Bit32u op1,Bit32u op2) { - lflags.oldcf=get_CF()!=0; - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d+lf_var2d+lflags.oldcf; - lflags.type=t_ADCd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_adc_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_adc_dword_simple(Bit32u op1,Bit32u op2) { - return op1+op2+(Bitu)(get_CF()!=0); -} - -static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_sub_dword(Bit32u op1,Bit32u op2) { - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d-lf_var2d; - lflags.type=t_SUBd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_sub_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_sub_dword_simple(Bit32u op1,Bit32u op2) { - return op1-op2; -} - -static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_sbb_dword(Bit32u op1,Bit32u op2) { - lflags.oldcf=get_CF()!=0; - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); - lflags.type=t_SBBd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_sbb_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_sbb_dword_simple(Bit32u op1,Bit32u op2) { - return op1-(op2+(Bitu)(get_CF()!=0)); -} - -static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_cmp_dword(Bit32u op1,Bit32u op2) { - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d-lf_var2d; - lflags.type=t_CMPd; -} - -static void DRC_CALL_CONV dynrec_cmp_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_cmp_dword_simple(Bit32u op1,Bit32u op2) { -} - -static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_xor_dword(Bit32u op1,Bit32u op2) { - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d ^ lf_var2d; - lflags.type=t_XORd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_xor_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_xor_dword_simple(Bit32u op1,Bit32u op2) { - return op1 ^ op2; -} - -static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_and_dword(Bit32u op1,Bit32u op2) { - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d & lf_var2d; - lflags.type=t_ANDd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_and_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_and_dword_simple(Bit32u op1,Bit32u op2) { - return op1 & op2; -} - -static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_or_dword(Bit32u op1,Bit32u op2) { - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d | lf_var2d; - lflags.type=t_ORd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_or_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_or_dword_simple(Bit32u op1,Bit32u op2) { - return op1 | op2; -} - -static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_test_dword(Bit32u op1,Bit32u op2) { - lf_var1d=op1; - lf_var2d=op2; - lf_resd=lf_var1d & lf_var2d; - lflags.type=t_TESTd; -} - -static void DRC_CALL_CONV dynrec_test_dword_simple(Bit32u op1,Bit32u op2) DRC_FC; -static void DRC_CALL_CONV dynrec_test_dword_simple(Bit32u op1,Bit32u op2) { -} - - -static void dyn_dop_byte_gencall(DualOps op) { - switch (op) { - case DOP_ADD: - InvalidateFlags((void*)&dynrec_add_byte_simple,t_ADDb); - gen_call_function_raw((void*)&dynrec_add_byte); - break; - case DOP_ADC: - AcquireFlags(FLAG_CF); - InvalidateFlagsPartially((void*)&dynrec_adc_byte_simple,t_ADCb); - gen_call_function_raw((void*)&dynrec_adc_byte); - break; - case DOP_SUB: - InvalidateFlags((void*)&dynrec_sub_byte_simple,t_SUBb); - gen_call_function_raw((void*)&dynrec_sub_byte); - break; - case DOP_SBB: - AcquireFlags(FLAG_CF); - InvalidateFlagsPartially((void*)&dynrec_sbb_byte_simple,t_SBBb); - gen_call_function_raw((void*)&dynrec_sbb_byte); - break; - case DOP_CMP: - InvalidateFlags((void*)&dynrec_cmp_byte_simple,t_CMPb); - gen_call_function_raw((void*)&dynrec_cmp_byte); - break; - case DOP_XOR: - InvalidateFlags((void*)&dynrec_xor_byte_simple,t_XORb); - gen_call_function_raw((void*)&dynrec_xor_byte); - break; - case DOP_AND: - InvalidateFlags((void*)&dynrec_and_byte_simple,t_ANDb); - gen_call_function_raw((void*)&dynrec_and_byte); - break; - case DOP_OR: - InvalidateFlags((void*)&dynrec_or_byte_simple,t_ORb); - gen_call_function_raw((void*)&dynrec_or_byte); - break; - case DOP_TEST: - InvalidateFlags((void*)&dynrec_test_byte_simple,t_TESTb); - gen_call_function_raw((void*)&dynrec_test_byte); - break; - default: IllegalOptionDynrec("dyn_dop_byte_gencall"); - } -} - -static void dyn_dop_word_gencall(DualOps op,bool dword) { - if (dword) { - switch (op) { - case DOP_ADD: - InvalidateFlags((void*)&dynrec_add_dword_simple,t_ADDd); - gen_call_function_raw((void*)&dynrec_add_dword); - break; - case DOP_ADC: - AcquireFlags(FLAG_CF); - InvalidateFlagsPartially((void*)&dynrec_adc_dword_simple,t_ADCd); - gen_call_function_raw((void*)&dynrec_adc_dword); - break; - case DOP_SUB: - InvalidateFlags((void*)&dynrec_sub_dword_simple,t_SUBd); - gen_call_function_raw((void*)&dynrec_sub_dword); - break; - case DOP_SBB: - AcquireFlags(FLAG_CF); - InvalidateFlagsPartially((void*)&dynrec_sbb_dword_simple,t_SBBd); - gen_call_function_raw((void*)&dynrec_sbb_dword); - break; - case DOP_CMP: - InvalidateFlags((void*)&dynrec_cmp_dword_simple,t_CMPd); - gen_call_function_raw((void*)&dynrec_cmp_dword); - break; - case DOP_XOR: - InvalidateFlags((void*)&dynrec_xor_dword_simple,t_XORd); - gen_call_function_raw((void*)&dynrec_xor_dword); - break; - case DOP_AND: - InvalidateFlags((void*)&dynrec_and_dword_simple,t_ANDd); - gen_call_function_raw((void*)&dynrec_and_dword); - break; - case DOP_OR: - InvalidateFlags((void*)&dynrec_or_dword_simple,t_ORd); - gen_call_function_raw((void*)&dynrec_or_dword); - break; - case DOP_TEST: - InvalidateFlags((void*)&dynrec_test_dword_simple,t_TESTd); - gen_call_function_raw((void*)&dynrec_test_dword); - break; - default: IllegalOptionDynrec("dyn_dop_dword_gencall"); - } - } else { - switch (op) { - case DOP_ADD: - InvalidateFlags((void*)&dynrec_add_word_simple,t_ADDw); - gen_call_function_raw((void*)&dynrec_add_word); - break; - case DOP_ADC: - AcquireFlags(FLAG_CF); - InvalidateFlagsPartially((void*)&dynrec_adc_word_simple,t_ADCw); - gen_call_function_raw((void*)&dynrec_adc_word); - break; - case DOP_SUB: - InvalidateFlags((void*)&dynrec_sub_word_simple,t_SUBw); - gen_call_function_raw((void*)&dynrec_sub_word); - break; - case DOP_SBB: - AcquireFlags(FLAG_CF); - InvalidateFlagsPartially((void*)&dynrec_sbb_word_simple,t_SBBw); - gen_call_function_raw((void*)&dynrec_sbb_word); - break; - case DOP_CMP: - InvalidateFlags((void*)&dynrec_cmp_word_simple,t_CMPw); - gen_call_function_raw((void*)&dynrec_cmp_word); - break; - case DOP_XOR: - InvalidateFlags((void*)&dynrec_xor_word_simple,t_XORw); - gen_call_function_raw((void*)&dynrec_xor_word); - break; - case DOP_AND: - InvalidateFlags((void*)&dynrec_and_word_simple,t_ANDw); - gen_call_function_raw((void*)&dynrec_and_word); - break; - case DOP_OR: - InvalidateFlags((void*)&dynrec_or_word_simple,t_ORw); - gen_call_function_raw((void*)&dynrec_or_word); - break; - case DOP_TEST: - InvalidateFlags((void*)&dynrec_test_word_simple,t_TESTw); - gen_call_function_raw((void*)&dynrec_test_word); - break; - default: IllegalOptionDynrec("dyn_dop_word_gencall"); - } - } -} - - -static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_inc_byte(Bit8u op) { - LoadCF; - lf_var1b=op; - lf_resb=lf_var1b+1; - lflags.type=t_INCb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_inc_byte_simple(Bit8u op) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_inc_byte_simple(Bit8u op) { - return op+1; -} - -static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_dec_byte(Bit8u op) { - LoadCF; - lf_var1b=op; - lf_resb=lf_var1b-1; - lflags.type=t_DECb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_dec_byte_simple(Bit8u op) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_dec_byte_simple(Bit8u op) { - return op-1; -} - -static Bit8u DRC_CALL_CONV dynrec_not_byte(Bit8u op) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_not_byte(Bit8u op) { - return ~op; -} - -static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_neg_byte(Bit8u op) { - lf_var1b=op; - lf_resb=0-lf_var1b; - lflags.type=t_NEGb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_neg_byte_simple(Bit8u op) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_neg_byte_simple(Bit8u op) { - return 0-op; -} - -static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_inc_word(Bit16u op) { - LoadCF; - lf_var1w=op; - lf_resw=lf_var1w+1; - lflags.type=t_INCw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_inc_word_simple(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_inc_word_simple(Bit16u op) { - return op+1; -} - -static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_dec_word(Bit16u op) { - LoadCF; - lf_var1w=op; - lf_resw=lf_var1w-1; - lflags.type=t_DECw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_dec_word_simple(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_dec_word_simple(Bit16u op) { - return op-1; -} - -static Bit16u DRC_CALL_CONV dynrec_not_word(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_not_word(Bit16u op) { - return ~op; -} - -static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_neg_word(Bit16u op) { - lf_var1w=op; - lf_resw=0-lf_var1w; - lflags.type=t_NEGw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_neg_word_simple(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_neg_word_simple(Bit16u op) { - return 0-op; -} - -static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_inc_dword(Bit32u op) { - LoadCF; - lf_var1d=op; - lf_resd=lf_var1d+1; - lflags.type=t_INCd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_inc_dword_simple(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_inc_dword_simple(Bit32u op) { - return op+1; -} - -static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_dec_dword(Bit32u op) { - LoadCF; - lf_var1d=op; - lf_resd=lf_var1d-1; - lflags.type=t_DECd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_dec_dword_simple(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_dec_dword_simple(Bit32u op) { - return op-1; -} - -static Bit32u DRC_CALL_CONV dynrec_not_dword(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_not_dword(Bit32u op) { - return ~op; -} - -static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_neg_dword(Bit32u op) { - lf_var1d=op; - lf_resd=0-lf_var1d; - lflags.type=t_NEGd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_neg_dword_simple(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_neg_dword_simple(Bit32u op) { - return 0-op; -} - - -static void dyn_sop_byte_gencall(SingleOps op) { - switch (op) { - case SOP_INC: - InvalidateFlagsPartially((void*)&dynrec_inc_byte_simple,t_INCb); - gen_call_function_raw((void*)&dynrec_inc_byte); - break; - case SOP_DEC: - InvalidateFlagsPartially((void*)&dynrec_dec_byte_simple,t_DECb); - gen_call_function_raw((void*)&dynrec_dec_byte); - break; - case SOP_NOT: - gen_call_function_raw((void*)&dynrec_not_byte); - break; - case SOP_NEG: - InvalidateFlags((void*)&dynrec_neg_byte_simple,t_NEGb); - gen_call_function_raw((void*)&dynrec_neg_byte); - break; - default: IllegalOptionDynrec("dyn_sop_byte_gencall"); - } -} - -static void dyn_sop_word_gencall(SingleOps op,bool dword) { - if (dword) { - switch (op) { - case SOP_INC: - InvalidateFlagsPartially((void*)&dynrec_inc_dword_simple,t_INCd); - gen_call_function_raw((void*)&dynrec_inc_dword); - break; - case SOP_DEC: - InvalidateFlagsPartially((void*)&dynrec_dec_dword_simple,t_DECd); - gen_call_function_raw((void*)&dynrec_dec_dword); - break; - case SOP_NOT: - gen_call_function_raw((void*)&dynrec_not_dword); - break; - case SOP_NEG: - InvalidateFlags((void*)&dynrec_neg_dword_simple,t_NEGd); - gen_call_function_raw((void*)&dynrec_neg_dword); - break; - default: IllegalOptionDynrec("dyn_sop_dword_gencall"); - } - } else { - switch (op) { - case SOP_INC: - InvalidateFlagsPartially((void*)&dynrec_inc_word_simple,t_INCw); - gen_call_function_raw((void*)&dynrec_inc_word); - break; - case SOP_DEC: - InvalidateFlagsPartially((void*)&dynrec_dec_word_simple,t_DECw); - gen_call_function_raw((void*)&dynrec_dec_word); - break; - case SOP_NOT: - gen_call_function_raw((void*)&dynrec_not_word); - break; - case SOP_NEG: - InvalidateFlags((void*)&dynrec_neg_word_simple,t_NEGw); - gen_call_function_raw((void*)&dynrec_neg_word); - break; - default: IllegalOptionDynrec("dyn_sop_word_gencall"); - } - } -} - - -static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_rol_byte(Bit8u op1,Bit8u op2) { - if (!(op2&0x7)) { - if (op2&0x18) { - FillFlagsNoCFOF(); - SETFLAGBIT(CF,op1 & 1); - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); - } - return op1; - } - FillFlagsNoCFOF(); - lf_var1b=op1; - lf_var2b=op2&0x07; - lf_resb=(lf_var1b << lf_var2b) | (lf_var1b >> (8-lf_var2b)); - SETFLAGBIT(CF,lf_resb & 1); - SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) { - if (!(op2&0x7)) return op1; - return (op1 << (op2&0x07)) | (op1 >> (8-(op2&0x07))); -} - -static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) { - if (!(op2&0x7)) { - if (op2&0x18) { - FillFlagsNoCFOF(); - SETFLAGBIT(CF,op1>>7); - SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); - } - return op1; - } - FillFlagsNoCFOF(); - lf_var1b=op1; - lf_var2b=op2&0x07; - lf_resb=(lf_var1b >> lf_var2b) | (lf_var1b << (8-lf_var2b)); - SETFLAGBIT(CF,lf_resb & 0x80); - SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_ror_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_ror_byte_simple(Bit8u op1,Bit8u op2) { - if (!(op2&0x7)) return op1; - return (op1 >> (op2&0x07)) | (op1 << (8-(op2&0x07))); -} - -static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_rcl_byte(Bit8u op1,Bit8u op2) { - if (op2%9) { - Bit8u cf=(Bit8u)FillFlags()&0x1; - lf_var1b=op1; - lf_var2b=op2%9; - lf_resb=(lf_var1b << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1b >> (9-lf_var2b)); - SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7)); - return lf_resb; - } else return op1; -} - -static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_rcr_byte(Bit8u op1,Bit8u op2) { - if (op2%9) { - Bit8u cf=(Bit8u)FillFlags()&0x1; - lf_var1b=op1; - lf_var2b=op2%9; - lf_resb=(lf_var1b >> lf_var2b) | (cf << (8-lf_var2b)) | (lf_var1b << (9-lf_var2b)); \ - SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); - SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); - return lf_resb; - } else return op1; -} - -static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_shl_byte(Bit8u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1b=op1; - lf_var2b=op2; - lf_resb=lf_var1b << lf_var2b; - lflags.type=t_SHLb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_shl_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_shl_byte_simple(Bit8u op1,Bit8u op2) { - if (!op2) return op1; - return op1 << op2; -} - -static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_shr_byte(Bit8u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1b=op1; - lf_var2b=op2; - lf_resb=lf_var1b >> lf_var2b; - lflags.type=t_SHRb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_shr_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_shr_byte_simple(Bit8u op1,Bit8u op2) { - if (!op2) return op1; - return op1 >> op2; -} - -static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_sar_byte(Bit8u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1b=op1; - lf_var2b=op2; - if (lf_var2b>8) lf_var2b=8; - if (lf_var1b & 0x80) { - lf_resb=(lf_var1b >> lf_var2b)| (0xff << (8 - lf_var2b)); - } else { - lf_resb=lf_var1b >> lf_var2b; - } - lflags.type=t_SARb; - return lf_resb; -} - -static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) DRC_FC; -static Bit8u DRC_CALL_CONV dynrec_sar_byte_simple(Bit8u op1,Bit8u op2) { - if (!op2) return op1; - if (op2>8) op2=8; - if (op1 & 0x80) return (op1 >> op2) | (0xff << (8 - op2)); - else return op1 >> op2; -} - -static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_rol_word(Bit16u op1,Bit8u op2) { - if (!(op2&0xf)) { - if (op2&0x10) { - FillFlagsNoCFOF(); - SETFLAGBIT(CF,op1 & 1); - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); - } - return op1; - } - FillFlagsNoCFOF(); - lf_var1w=op1; - lf_var2b=op2&0xf; - lf_resw=(lf_var1w << lf_var2b) | (lf_var1w >> (16-lf_var2b)); - SETFLAGBIT(CF,lf_resw & 1); - SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_rol_word_simple(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_rol_word_simple(Bit16u op1,Bit8u op2) { - if (!(op2&0xf)) return op1; - return (op1 << (op2&0xf)) | (op1 >> (16-(op2&0xf))); -} - -static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_ror_word(Bit16u op1,Bit8u op2) { - if (!(op2&0xf)) { - if (op2&0x10) { - FillFlagsNoCFOF(); - SETFLAGBIT(CF,op1>>15); - SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); - } - return op1; - } - FillFlagsNoCFOF(); - lf_var1w=op1; - lf_var2b=op2&0xf; - lf_resw=(lf_var1w >> lf_var2b) | (lf_var1w << (16-lf_var2b)); - SETFLAGBIT(CF,lf_resw & 0x8000); - SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_ror_word_simple(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_ror_word_simple(Bit16u op1,Bit8u op2) { - if (!(op2&0xf)) return op1; - return (op1 >> (op2&0xf)) | (op1 << (16-(op2&0xf))); -} - -static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_rcl_word(Bit16u op1,Bit8u op2) { - if (op2%17) { - Bit16u cf=(Bit16u)FillFlags()&0x1; - lf_var1w=op1; - lf_var2b=op2%17; - lf_resw=(lf_var1w << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1w >> (17-lf_var2b)); - SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15)); - return lf_resw; - } else return op1; -} - -static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_rcr_word(Bit16u op1,Bit8u op2) { - if (op2%17) { - Bit16u cf=(Bit16u)FillFlags()&0x1; - lf_var1w=op1; - lf_var2b=op2%17; - lf_resw=(lf_var1w >> lf_var2b) | (cf << (16-lf_var2b)) | (lf_var1w << (17-lf_var2b)); - SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); - SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); - return lf_resw; - } else return op1; -} - -static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_shl_word(Bit16u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1w=op1; - lf_var2b=op2; - lf_resw=lf_var1w << lf_var2b; - lflags.type=t_SHLw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_shl_word_simple(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_shl_word_simple(Bit16u op1,Bit8u op2) { - if (!op2) return op1; - return op1 << op2; -} - -static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_shr_word(Bit16u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1w=op1; - lf_var2b=op2; - lf_resw=lf_var1w >> lf_var2b; - lflags.type=t_SHRw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_shr_word_simple(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_shr_word_simple(Bit16u op1,Bit8u op2) { - if (!op2) return op1; - return op1 >> op2; -} - -static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_sar_word(Bit16u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1w=op1; - lf_var2b=op2; - if (lf_var2b>16) lf_var2b=16; - if (lf_var1w & 0x8000) { - lf_resw=(lf_var1w >> lf_var2b) | (0xffff << (16 - lf_var2b)); - } else { - lf_resw=lf_var1w >> lf_var2b; - } - lflags.type=t_SARw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_sar_word_simple(Bit16u op1,Bit8u op2) { - if (!op2) return op1; - if (op2>16) op2=16; - if (op1 & 0x8000) return (op1 >> op2) | (0xffff << (16 - op2)); - else return op1 >> op2; -} - -static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_rol_dword(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - FillFlagsNoCFOF(); - lf_var1d=op1; - lf_var2b=op2; - lf_resd=(lf_var1d << lf_var2b) | (lf_var1d >> (32-lf_var2b)); - SETFLAGBIT(CF,lf_resd & 1); - SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31)); - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_rol_dword_simple(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - return (op1 << op2) | (op1 >> (32-op2)); -} - -static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_ror_dword(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - FillFlagsNoCFOF(); - lf_var1d=op1; - lf_var2b=op2; - lf_resd=(lf_var1d >> lf_var2b) | (lf_var1d << (32-lf_var2b)); - SETFLAGBIT(CF,lf_resd & 0x80000000); - SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_ror_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_ror_dword_simple(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - return (op1 >> op2) | (op1 << (32-op2)); -} - -static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_rcl_dword(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - Bit32u cf=(Bit32u)FillFlags()&0x1; - lf_var1d=op1; - lf_var2b=op2; - if (lf_var2b==1) { - lf_resd=(lf_var1d << 1) | cf; - } else { - lf_resd=(lf_var1d << lf_var2b) | (cf << (lf_var2b-1)) | (lf_var1d >> (33-lf_var2b)); - } - SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_rcr_dword(Bit32u op1,Bit8u op2) { - if (op2) { - Bit32u cf=(Bit32u)FillFlags()&0x1; - lf_var1d=op1; - lf_var2b=op2; - if (lf_var2b==1) { - lf_resd=lf_var1d >> 1 | cf << 31; - } else { - lf_resd=(lf_var1d >> lf_var2b) | (cf << (32-lf_var2b)) | (lf_var1d << (33-lf_var2b)); - } - SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); - return lf_resd; - } else return op1; -} - -static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_shl_dword(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1d=op1; - lf_var2b=op2; - lf_resd=lf_var1d << lf_var2b; - lflags.type=t_SHLd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_shl_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_shl_dword_simple(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - return op1 << op2; -} - -static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_shr_dword(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - lf_var1d=op1; - lf_var2b=op2; - lf_resd=lf_var1d >> lf_var2b; - lflags.type=t_SHRd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_shr_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_shr_dword_simple(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - return op1 >> op2; -} - -static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_sar_dword(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - lf_var2b=op2; - lf_var1d=op1; - if (lf_var1d & 0x80000000) { - lf_resd=(lf_var1d >> lf_var2b) | (0xffffffff << (32 - lf_var2b)); - } else { - lf_resd=lf_var1d >> lf_var2b; - } - lflags.type=t_SARd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_sar_dword_simple(Bit32u op1,Bit8u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_sar_dword_simple(Bit32u op1,Bit8u op2) { - if (!op2) return op1; - if (op1 & 0x80000000) return (op1 >> op2) | (0xffffffff << (32 - op2)); - else return op1 >> op2; -} - -static void dyn_shift_byte_gencall(ShiftOps op) { - switch (op) { - case SHIFT_ROL: - InvalidateFlagsPartially((void*)&dynrec_rol_byte_simple,t_ROLb); - gen_call_function_raw((void*)&dynrec_rol_byte); - break; - case SHIFT_ROR: - InvalidateFlagsPartially((void*)&dynrec_ror_byte_simple,t_RORb); - gen_call_function_raw((void*)&dynrec_ror_byte); - break; - case SHIFT_RCL: - AcquireFlags(FLAG_CF); - gen_call_function_raw((void*)&dynrec_rcl_byte); - break; - case SHIFT_RCR: - AcquireFlags(FLAG_CF); - gen_call_function_raw((void*)&dynrec_rcr_byte); - break; - case SHIFT_SHL: - case SHIFT_SAL: - InvalidateFlagsPartially((void*)&dynrec_shl_byte_simple,t_SHLb); - gen_call_function_raw((void*)&dynrec_shl_byte); - break; - case SHIFT_SHR: - InvalidateFlagsPartially((void*)&dynrec_shr_byte_simple,t_SHRb); - gen_call_function_raw((void*)&dynrec_shr_byte); - break; - case SHIFT_SAR: - InvalidateFlagsPartially((void*)&dynrec_sar_byte_simple,t_SARb); - gen_call_function_raw((void*)&dynrec_sar_byte); - break; - default: IllegalOptionDynrec("dyn_shift_byte_gencall"); - } -} - -static void dyn_shift_word_gencall(ShiftOps op,bool dword) { - if (dword) { - switch (op) { - case SHIFT_ROL: - InvalidateFlagsPartially((void*)&dynrec_rol_dword_simple,t_ROLd); - gen_call_function_raw((void*)&dynrec_rol_dword); - break; - case SHIFT_ROR: - InvalidateFlagsPartially((void*)&dynrec_ror_dword_simple,t_RORd); - gen_call_function_raw((void*)&dynrec_ror_dword); - break; - case SHIFT_RCL: - AcquireFlags(FLAG_CF); - gen_call_function_raw((void*)&dynrec_rcl_dword); - break; - case SHIFT_RCR: - AcquireFlags(FLAG_CF); - gen_call_function_raw((void*)&dynrec_rcr_dword); - break; - case SHIFT_SHL: - case SHIFT_SAL: - InvalidateFlagsPartially((void*)&dynrec_shl_dword_simple,t_SHLd); - gen_call_function_raw((void*)&dynrec_shl_dword); - break; - case SHIFT_SHR: - InvalidateFlagsPartially((void*)&dynrec_shr_dword_simple,t_SHRd); - gen_call_function_raw((void*)&dynrec_shr_dword); - break; - case SHIFT_SAR: - InvalidateFlagsPartially((void*)&dynrec_sar_dword_simple,t_SARd); - gen_call_function_raw((void*)&dynrec_sar_dword); - break; - default: IllegalOptionDynrec("dyn_shift_dword_gencall"); - } - } else { - switch (op) { - case SHIFT_ROL: - InvalidateFlagsPartially((void*)&dynrec_rol_word_simple,t_ROLw); - gen_call_function_raw((void*)&dynrec_rol_word); - break; - case SHIFT_ROR: - InvalidateFlagsPartially((void*)&dynrec_ror_word_simple,t_RORw); - gen_call_function_raw((void*)&dynrec_ror_word); - break; - case SHIFT_RCL: - AcquireFlags(FLAG_CF); - gen_call_function_raw((void*)&dynrec_rcl_word); - break; - case SHIFT_RCR: - AcquireFlags(FLAG_CF); - gen_call_function_raw((void*)&dynrec_rcr_word); - break; - case SHIFT_SHL: - case SHIFT_SAL: - InvalidateFlagsPartially((void*)&dynrec_shl_word_simple,t_SHLw); - gen_call_function_raw((void*)&dynrec_shl_word); - break; - case SHIFT_SHR: - InvalidateFlagsPartially((void*)&dynrec_shr_word_simple,t_SHRw); - gen_call_function_raw((void*)&dynrec_shr_word); - break; - case SHIFT_SAR: - InvalidateFlagsPartially((void*)&dynrec_sar_word_simple,t_SARw); - gen_call_function_raw((void*)&dynrec_sar_word); - break; - default: IllegalOptionDynrec("dyn_shift_word_gencall"); - } - } -} - -static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_dshl_word(Bit16u op1,Bit16u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - lf_var2b=val; - lf_var1d=(op1<<16)|op2; - Bit32u tempd=lf_var1d << lf_var2b; - if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); - lf_resw=(Bit16u)(tempd >> 16); - lflags.type=t_DSHLw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_dshl_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - Bit32u tempd=(Bit32u)((((Bit32u)op1)<<16)|op2) << val; - if (val>16) tempd |= (op2 << (val - 16)); - return (Bit16u)(tempd >> 16); -} - -static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_dshl_dword(Bit32u op1,Bit32u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - lf_var2b=val; - lf_var1d=op1; - lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); - lflags.type=t_DSHLd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_dshl_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_dshl_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - return (op1 << val) | (op2 >> (32-val)); -} - -static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_dshr_word(Bit16u op1,Bit16u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - lf_var2b=val; - lf_var1d=(op2<<16)|op1; - Bit32u tempd=lf_var1d >> lf_var2b; - if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b )); - lf_resw=(Bit16u)(tempd); - lflags.type=t_DSHRw; - return lf_resw; -} - -static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_dshr_word_simple(Bit16u op1,Bit16u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - Bit32u tempd=(Bit32u)((((Bit32u)op2)<<16)|op1) >> val; - if (val>16) tempd |= (op2 << (32-val)); - return (Bit16u)(tempd); -} - -static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_dshr_dword(Bit32u op1,Bit32u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - lf_var2b=val; - lf_var1d=op1; - lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); - lflags.type=t_DSHRd; - return lf_resd; -} - -static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_dshr_dword_simple(Bit32u op1,Bit32u op2,Bit8u op3) { - Bit8u val=op3 & 0x1f; - if (!val) return op1; - return (op1 >> val) | (op2 << (32-val)); -} - -static void dyn_dpshift_word_gencall(bool left) { - if (left) { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_word,FC_OP3); - InvalidateFlagsPartially((void*)&dynrec_dshl_word_simple,proc_addr,t_DSHLw); - } else { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_word,FC_OP3); - InvalidateFlagsPartially((void*)&dynrec_dshr_word_simple,proc_addr,t_DSHRw); - } -} - -static void dyn_dpshift_dword_gencall(bool left) { - if (left) { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshl_dword,FC_OP3); - InvalidateFlagsPartially((void*)&dynrec_dshl_dword_simple,proc_addr,t_DSHLd); - } else { - DRC_PTR_SIZE_IM proc_addr=gen_call_function_R3((void*)&dynrec_dshr_dword,FC_OP3); - InvalidateFlagsPartially((void*)&dynrec_dshr_dword_simple,proc_addr,t_DSHRd); - } -} - - - -static Bit32u DRC_CALL_CONV dynrec_get_of(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_of(void) { return TFLG_O; } -static Bit32u DRC_CALL_CONV dynrec_get_nof(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_nof(void) { return TFLG_NO; } -static Bit32u DRC_CALL_CONV dynrec_get_cf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_cf(void) { return TFLG_B; } -static Bit32u DRC_CALL_CONV dynrec_get_ncf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_ncf(void) { return TFLG_NB; } -static Bit32u DRC_CALL_CONV dynrec_get_zf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_zf(void) { return TFLG_Z; } -static Bit32u DRC_CALL_CONV dynrec_get_nzf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_nzf(void) { return TFLG_NZ; } -static Bit32u DRC_CALL_CONV dynrec_get_sf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_sf(void) { return TFLG_S; } -static Bit32u DRC_CALL_CONV dynrec_get_nsf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_nsf(void) { return TFLG_NS; } -static Bit32u DRC_CALL_CONV dynrec_get_pf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_pf(void) { return TFLG_P; } -static Bit32u DRC_CALL_CONV dynrec_get_npf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_npf(void) { return TFLG_NP; } - -static Bit32u DRC_CALL_CONV dynrec_get_cf_or_zf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_cf_or_zf(void) { return TFLG_BE; } -static Bit32u DRC_CALL_CONV dynrec_get_ncf_and_nzf(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_ncf_and_nzf(void) { return TFLG_NBE; } -static Bit32u DRC_CALL_CONV dynrec_get_sf_neq_of(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_sf_neq_of(void) { return TFLG_L; } -static Bit32u DRC_CALL_CONV dynrec_get_sf_eq_of(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_sf_eq_of(void) { return TFLG_NL; } -static Bit32u DRC_CALL_CONV dynrec_get_zf_or_sf_neq_of(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_zf_or_sf_neq_of(void) { return TFLG_LE; } -static Bit32u DRC_CALL_CONV dynrec_get_nzf_and_sf_eq_of(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_get_nzf_and_sf_eq_of(void) { return TFLG_NLE; } - - -static void dyn_branchflag_to_reg(BranchTypes btype) { - switch (btype) { - case BR_O:gen_call_function_raw((void*)&dynrec_get_of);break; - case BR_NO:gen_call_function_raw((void*)&dynrec_get_nof);break; - case BR_B:gen_call_function_raw((void*)&dynrec_get_cf);break; - case BR_NB:gen_call_function_raw((void*)&dynrec_get_ncf);break; - case BR_Z:gen_call_function_raw((void*)&dynrec_get_zf);break; - case BR_NZ:gen_call_function_raw((void*)&dynrec_get_nzf);break; - case BR_BE:gen_call_function_raw((void*)&dynrec_get_cf_or_zf);break; - case BR_NBE:gen_call_function_raw((void*)&dynrec_get_ncf_and_nzf);break; - - case BR_S:gen_call_function_raw((void*)&dynrec_get_sf);break; - case BR_NS:gen_call_function_raw((void*)&dynrec_get_nsf);break; - case BR_P:gen_call_function_raw((void*)&dynrec_get_pf);break; - case BR_NP:gen_call_function_raw((void*)&dynrec_get_npf);break; - case BR_L:gen_call_function_raw((void*)&dynrec_get_sf_neq_of);break; - case BR_NL:gen_call_function_raw((void*)&dynrec_get_sf_eq_of);break; - case BR_LE:gen_call_function_raw((void*)&dynrec_get_zf_or_sf_neq_of);break; - case BR_NLE:gen_call_function_raw((void*)&dynrec_get_nzf_and_sf_eq_of);break; - } -} - - -static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) DRC_FC; -static void DRC_CALL_CONV dynrec_mul_byte(Bit8u op) { - FillFlagsNoCFOF(); - reg_ax=reg_al*op; - SETFLAGBIT(ZF,reg_al == 0); - if (reg_ax & 0xff00) { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } else { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } -} - -static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) DRC_FC; -static void DRC_CALL_CONV dynrec_imul_byte(Bit8u op) { - FillFlagsNoCFOF(); - reg_ax=((Bit8s)reg_al) * ((Bit8s)op); - if ((reg_ax & 0xff80)==0xff80 || (reg_ax & 0xff80)==0x0000) { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } else { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } -} - -static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) DRC_FC; -static void DRC_CALL_CONV dynrec_mul_word(Bit16u op) { - FillFlagsNoCFOF(); - Bitu tempu=(Bitu)reg_ax*(Bitu)op; - reg_ax=(Bit16u)(tempu); - reg_dx=(Bit16u)(tempu >> 16); - SETFLAGBIT(ZF,reg_ax == 0); - if (reg_dx) { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } else { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } -} - -static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) DRC_FC; -static void DRC_CALL_CONV dynrec_imul_word(Bit16u op) { - FillFlagsNoCFOF(); - Bits temps=((Bit16s)reg_ax)*((Bit16s)op); - reg_ax=(Bit16s)(temps); - reg_dx=(Bit16s)(temps >> 16); - if (((temps & 0xffff8000)==0xffff8000 || (temps & 0xffff8000)==0x0000)) { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } else { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } -} - -static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) DRC_FC; -static void DRC_CALL_CONV dynrec_mul_dword(Bit32u op) { - FillFlagsNoCFOF(); - Bit64u tempu=(Bit64u)reg_eax*(Bit64u)op; - reg_eax=(Bit32u)(tempu); - reg_edx=(Bit32u)(tempu >> 32); - SETFLAGBIT(ZF,reg_eax == 0); - if (reg_edx) { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } else { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } -} - -static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) DRC_FC; -static void DRC_CALL_CONV dynrec_imul_dword(Bit32u op) { - FillFlagsNoCFOF(); - Bit64s temps=((Bit64s)((Bit32s)reg_eax))*((Bit64s)((Bit32s)op)); - reg_eax=(Bit32u)(temps); - reg_edx=(Bit32u)(temps >> 32); - if ((reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } else if ( (reg_edx==0x00000000) && (reg_eax< 0x80000000) ) { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } else { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } -} - - -static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) DRC_FC; -static bool DRC_CALL_CONV dynrec_div_byte(Bit8u op) { - Bitu val=op; - if (val==0) return CPU_PrepareException(0,0); - Bitu quo=reg_ax / val; - Bit8u rem=(Bit8u)(reg_ax % val); - Bit8u quo8=(Bit8u)(quo&0xff); - if (quo>0xff) return CPU_PrepareException(0,0); - reg_ah=rem; - reg_al=quo8; - return false; -} - -static bool DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) DRC_FC; -static bool DRC_CALL_CONV dynrec_idiv_byte(Bit8u op) { - Bits val=(Bit8s)op; - if (val==0) return CPU_PrepareException(0,0); - Bits quo=((Bit16s)reg_ax) / val; - Bit8s rem=(Bit8s)((Bit16s)reg_ax % val); - Bit8s quo8s=(Bit8s)(quo&0xff); - if (quo!=(Bit16s)quo8s) return CPU_PrepareException(0,0); - reg_ah=rem; - reg_al=quo8s; - return false; -} - -static bool DRC_CALL_CONV dynrec_div_word(Bit16u op) DRC_FC; -static bool DRC_CALL_CONV dynrec_div_word(Bit16u op) { - Bitu val=op; - if (val==0) return CPU_PrepareException(0,0); - Bitu num=((Bit32u)reg_dx<<16)|reg_ax; - Bitu quo=num/val; - Bit16u rem=(Bit16u)(num % val); - Bit16u quo16=(Bit16u)(quo&0xffff); - if (quo!=(Bit32u)quo16) return CPU_PrepareException(0,0); - reg_dx=rem; - reg_ax=quo16; - return false; -} - -static bool DRC_CALL_CONV dynrec_idiv_word(Bit16u op) DRC_FC; -static bool DRC_CALL_CONV dynrec_idiv_word(Bit16u op) { - Bits val=(Bit16s)op; - if (val==0) return CPU_PrepareException(0,0); - Bits num=(Bit32s)((reg_dx<<16)|reg_ax); - Bits quo=num/val; - Bit16s rem=(Bit16s)(num % val); - Bit16s quo16s=(Bit16s)quo; - if (quo!=(Bit32s)quo16s) return CPU_PrepareException(0,0); - reg_dx=rem; - reg_ax=quo16s; - return false; -} - -static bool DRC_CALL_CONV dynrec_div_dword(Bit32u op) DRC_FC; -static bool DRC_CALL_CONV dynrec_div_dword(Bit32u op) { - Bitu val=op; - if (val==0) return CPU_PrepareException(0,0); - Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; - Bit64u quo=num/val; - Bit32u rem=(Bit32u)(num % val); - Bit32u quo32=(Bit32u)(quo&0xffffffff); - if (quo!=(Bit64u)quo32) return CPU_PrepareException(0,0); - reg_edx=rem; - reg_eax=quo32; - return false; -} - -static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) DRC_FC; -static bool DRC_CALL_CONV dynrec_idiv_dword(Bit32u op) { - Bits val=(Bit32s)op; - if (val==0) return CPU_PrepareException(0,0); - Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; - Bit64s quo=num/val; - Bit32s rem=(Bit32s)(num % val); - Bit32s quo32s=(Bit32s)(quo&0xffffffff); - if (quo!=(Bit64s)quo32s) return CPU_PrepareException(0,0); - reg_edx=rem; - reg_eax=quo32s; - return false; -} - - -static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_dimul_word(Bit16u op1,Bit16u op2) { - FillFlagsNoCFOF(); - Bits res=((Bit16s)op1) * ((Bit16s)op2); - if ((res>-32768) && (res<32767)) { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } else { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } - return (Bit16u)(res & 0xffff); -} - -static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_dimul_dword(Bit32u op1,Bit32u op2) { - FillFlagsNoCFOF(); - Bit64s res=((Bit64s)((Bit32s)op1))*((Bit64s)((Bit32s)op2)); - if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) { - SETFLAGBIT(CF,false); - SETFLAGBIT(OF,false); - } else { - SETFLAGBIT(CF,true); - SETFLAGBIT(OF,true); - } - return (Bit32s)res; -} - - - -static Bit16u DRC_CALL_CONV dynrec_cbw(Bit8u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_cbw(Bit8u op) { - return (Bit8s)op; -} - -static Bit32u DRC_CALL_CONV dynrec_cwde(Bit16u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_cwde(Bit16u op) { - return (Bit16s)op; -} - -static Bit16u DRC_CALL_CONV dynrec_cwd(Bit16u op) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_cwd(Bit16u op) { - if (op & 0x8000) return 0xffff; - else return 0; -} - -static Bit32u DRC_CALL_CONV dynrec_cdq(Bit32u op) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_cdq(Bit32u op) { - if (op & 0x80000000) return 0xffffffff; - else return 0; -} - - -static void DRC_CALL_CONV dynrec_sahf(Bit16u op) DRC_FC; -static void DRC_CALL_CONV dynrec_sahf(Bit16u op) { - SETFLAGBIT(OF,get_OF()); - lflags.type=t_UNKNOWN; - CPU_SetFlags(op>>8,FMASK_NORMAL & 0xff); -} - - -static void DRC_CALL_CONV dynrec_cmc(void) DRC_FC; -static void DRC_CALL_CONV dynrec_cmc(void) { - FillFlags(); - SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); -} -static void DRC_CALL_CONV dynrec_clc(void) DRC_FC; -static void DRC_CALL_CONV dynrec_clc(void) { - FillFlags(); - SETFLAGBIT(CF,false); -} -static void DRC_CALL_CONV dynrec_stc(void) DRC_FC; -static void DRC_CALL_CONV dynrec_stc(void) { - FillFlags(); - SETFLAGBIT(CF,true); -} -static void DRC_CALL_CONV dynrec_cld(void) DRC_FC; -static void DRC_CALL_CONV dynrec_cld(void) { - SETFLAGBIT(DF,false); - cpu.direction=1; -} -static void DRC_CALL_CONV dynrec_std(void) DRC_FC; -static void DRC_CALL_CONV dynrec_std(void) { - SETFLAGBIT(DF,true); - cpu.direction=-1; -} - - -static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_movsb_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - for (;count>0;count--) { - mem_writeb(di_base+reg_di,mem_readb(si_base+reg_si)); - reg_si+=add_index; - reg_di+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_movsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - for (;count>0;count--) { - mem_writeb(di_base+reg_edi,mem_readb(si_base+reg_esi)); - reg_esi+=add_index; - reg_edi+=add_index; - } - return count_left; -} - -static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_movsw_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=1; - for (;count>0;count--) { - mem_writew(di_base+reg_di,mem_readw(si_base+reg_si)); - reg_si+=add_index; - reg_di+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_movsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=1; - for (;count>0;count--) { - mem_writew(di_base+reg_edi,mem_readw(si_base+reg_esi)); - reg_esi+=add_index; - reg_edi+=add_index; - } - return count_left; -} - -static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_movsd_word(Bit16u count,Bit16s add_index,PhysPt si_base,PhysPt di_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=2; - for (;count>0;count--) { - mem_writed(di_base+reg_di,mem_readd(si_base+reg_si)); - reg_si+=add_index; - reg_di+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_movsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base,PhysPt di_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=2; - for (;count>0;count--) { - mem_writed(di_base+reg_edi,mem_readd(si_base+reg_esi)); - reg_esi+=add_index; - reg_edi+=add_index; - } - return count_left; -} - - -static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_lodsb_word(Bit16u count,Bit16s add_index,PhysPt si_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - for (;count>0;count--) { - reg_al=mem_readb(si_base+reg_si); - reg_si+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_lodsb_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - for (;count>0;count--) { - reg_al=mem_readb(si_base+reg_esi); - reg_esi+=add_index; - } - return count_left; -} - -static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_lodsw_word(Bit16u count,Bit16s add_index,PhysPt si_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=1; - for (;count>0;count--) { - reg_ax=mem_readw(si_base+reg_si); - reg_si+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_lodsw_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=1; - for (;count>0;count--) { - reg_ax=mem_readw(si_base+reg_esi); - reg_esi+=add_index; - } - return count_left; -} - -static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,PhysPt si_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_lodsd_word(Bit16u count,Bit16s add_index,PhysPt si_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=2; - for (;count>0;count--) { - reg_eax=mem_readd(si_base+reg_si); - reg_si+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_lodsd_dword(Bit32u count,Bit32s add_index,PhysPt si_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=2; - for (;count>0;count--) { - reg_eax=mem_readd(si_base+reg_esi); - reg_esi+=add_index; - } - return count_left; -} - - -static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_stosb_word(Bit16u count,Bit16s add_index,PhysPt di_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - for (;count>0;count--) { - mem_writeb(di_base+reg_di,reg_al); - reg_di+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_stosb_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - for (;count>0;count--) { - mem_writeb(di_base+reg_edi,reg_al); - reg_edi+=add_index; - } - return count_left; -} - -static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_stosw_word(Bit16u count,Bit16s add_index,PhysPt di_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=1; - for (;count>0;count--) { - mem_writew(di_base+reg_di,reg_ax); - reg_di+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_stosw_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=1; - for (;count>0;count--) { - mem_writew(di_base+reg_edi,reg_ax); - reg_edi+=add_index; - } - return count_left; -} - -static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,PhysPt di_base) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_stosd_word(Bit16u count,Bit16s add_index,PhysPt di_base) { - Bit16u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=(Bit16u)(count-CPU_Cycles); - count=(Bit16u)CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=2; - for (;count>0;count--) { - mem_writed(di_base+reg_di,reg_eax); - reg_di+=add_index; - } - return count_left; -} - -static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,PhysPt di_base) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_stosd_dword(Bit32u count,Bit32s add_index,PhysPt di_base) { - Bit32u count_left; - if (count<(Bitu)CPU_Cycles) { - count_left=0; - } else { - count_left=count-CPU_Cycles; - count=CPU_Cycles; - CPU_Cycles=0; - } - add_index<<=2; - for (;count>0;count--) { - mem_writed(di_base+reg_edi,reg_eax); - reg_edi+=add_index; - } - return count_left; -} - - -static void DRC_CALL_CONV dynrec_push_word(Bit16u value) DRC_FC; -static void DRC_CALL_CONV dynrec_push_word(Bit16u value) { - Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); - mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask),value); - reg_esp=new_esp; -} - -static void DRC_CALL_CONV dynrec_push_dword(Bit32u value) DRC_FC; -static void DRC_CALL_CONV dynrec_push_dword(Bit32u value) { - Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask); - mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); - reg_esp=new_esp; -} - -static Bit16u DRC_CALL_CONV dynrec_pop_word(void) DRC_FC; -static Bit16u DRC_CALL_CONV dynrec_pop_word(void) { - Bit16u val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); - return val; -} - -static Bit32u DRC_CALL_CONV dynrec_pop_dword(void) DRC_FC; -static Bit32u DRC_CALL_CONV dynrec_pop_dword(void) { - Bit32u val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); - return val; -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-common.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-common.h deleted file mode 100644 index c6ab612f9..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-common.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* ARMv4 (little endian) backend by M-HT (common data/functions) */ - - -// some configuring defines that specify the capabilities of this architecture -// or aspects of the recompiling - -// protect FC_ADDR over function calls if necessaray -// #define DRC_PROTECT_ADDR_REG - -// try to use non-flags generating functions if possible -#define DRC_FLAGS_INVALIDATION -// try to replace _simple functions by code -#define DRC_FLAGS_INVALIDATION_DCODE - -// type with the same size as a pointer -#define DRC_PTR_SIZE_IM Bit32u - -// calling convention modifier -#define DRC_CALL_CONV /* nothing */ -#define DRC_FC /* nothing */ - -// use FC_REGS_ADDR to hold the address of "cpu_regs" and to access it using FC_REGS_ADDR -#define DRC_USE_REGS_ADDR -// use FC_SEGS_ADDR to hold the address of "Segs" and to access it using FC_SEGS_ADDR -#define DRC_USE_SEGS_ADDR - -// register mapping -typedef Bit8u HostReg; - -// "lo" registers -#define HOST_r0 0 -#define HOST_r1 1 -#define HOST_r2 2 -#define HOST_r3 3 -#define HOST_r4 4 -#define HOST_r5 5 -#define HOST_r6 6 -#define HOST_r7 7 -// "hi" registers -#define HOST_r8 8 -#define HOST_r9 9 -#define HOST_r10 10 -#define HOST_r11 11 -#define HOST_r12 12 -#define HOST_r13 13 -#define HOST_r14 14 -#define HOST_r15 15 - -// register aliases -// "lo" registers -#define HOST_a1 HOST_r0 -#define HOST_a2 HOST_r1 -#define HOST_a3 HOST_r2 -#define HOST_a4 HOST_r3 -#define HOST_v1 HOST_r4 -#define HOST_v2 HOST_r5 -#define HOST_v3 HOST_r6 -#define HOST_v4 HOST_r7 -// "hi" registers -#define HOST_v5 HOST_r8 -#define HOST_v6 HOST_r9 -#define HOST_v7 HOST_r10 -#define HOST_v8 HOST_r11 -#define HOST_ip HOST_r12 -#define HOST_sp HOST_r13 -#define HOST_lr HOST_r14 -#define HOST_pc HOST_r15 - - -static void cache_block_closing(Bit8u* block_start,Bitu block_size) { -#if (__ARM_EABI__) - //flush cache - eabi - register unsigned long _beg __asm ("a1") = (unsigned long)(block_start); // block start - register unsigned long _end __asm ("a2") = (unsigned long)(block_start+block_size); // block end - register unsigned long _flg __asm ("a3") = 0; - register unsigned long _par __asm ("r7") = 0xf0002; // sys_cacheflush - __asm __volatile ("swi 0x0" - : // no outputs - : "r" (_beg), "r" (_end), "r" (_flg), "r" (_par) - ); -#else -// GP2X BEGIN - //flush cache - old abi - register unsigned long _beg __asm ("a1") = (unsigned long)(block_start); // block start - register unsigned long _end __asm ("a2") = (unsigned long)(block_start+block_size); // block end - register unsigned long _flg __asm ("a3") = 0; - __asm __volatile ("swi 0x9f0002 @ sys_cacheflush" - : // no outputs - : "r" (_beg), "r" (_end), "r" (_flg) - ); -// GP2X END -#endif -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-o3.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-o3.h deleted file mode 100644 index 3596c48e8..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-o3.h +++ /dev/null @@ -1,1302 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* ARMv4/ARMv7 (little endian) backend by M-HT (arm version) */ - - -// temporary registers -#define temp1 HOST_ip -#define temp2 HOST_v3 -#define temp3 HOST_v4 - -// register that holds function return values -#define FC_RETOP HOST_a1 - -// register used for address calculations, -#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG - -// register that holds the first parameter -#define FC_OP1 HOST_a1 - -// register that holds the second parameter -#define FC_OP2 HOST_a2 - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_v2 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_a1 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_a2 - -// temporary register for LEA -#define TEMP_REG_DRC HOST_v2 - -// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code -#define FC_REGS_ADDR HOST_v7 - -// used to hold the address of "Segs" - preferably filled in function gen_run_code -#define FC_SEGS_ADDR HOST_v8 - -// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code -#define readdata_addr HOST_v5 - - -// helper macro -#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) ) - - -// instruction encodings - -// move -// mov dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define MOV_IMM(dst, imm, rimm) (0xe3a00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) -// mov dst, src, lsl #imm -#define MOV_REG_LSL_IMM(dst, src, imm) (0xe1a00000 + ((dst) << 12) + (src) + ((imm) << 7) ) -// movs dst, src, lsl #imm -#define MOVS_REG_LSL_IMM(dst, src, imm) (0xe1b00000 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, lsr #imm -#define MOV_REG_LSR_IMM(dst, src, imm) (0xe1a00020 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, asr #imm -#define MOV_REG_ASR_IMM(dst, src, imm) (0xe1a00040 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, lsl rreg -#define MOV_REG_LSL_REG(dst, src, rreg) (0xe1a00010 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, lsr rreg -#define MOV_REG_LSR_REG(dst, src, rreg) (0xe1a00030 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, asr rreg -#define MOV_REG_ASR_REG(dst, src, rreg) (0xe1a00050 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, ror rreg -#define MOV_REG_ROR_REG(dst, src, rreg) (0xe1a00070 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mvn dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define MVN_IMM(dst, imm, rimm) (0xe3e00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) -#if C_TARGETCPU == ARMV7LE -// movw dst, #imm @ 0 <= imm <= 65535 -#define MOVW(dst, imm) (0xe3000000 + ((dst) << 12) + (((imm) & 0xf000) << 4) + ((imm) & 0x0fff) ) -// movt dst, #imm @ 0 <= imm <= 65535 -#define MOVT(dst, imm) (0xe3400000 + ((dst) << 12) + (((imm) & 0xf000) << 4) + ((imm) & 0x0fff) ) -#endif - -// arithmetic -// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// add dst, src1, src2, lsl #imm -#define ADD_REG_LSL_IMM(dst, src1, src2, imm) (0xe0800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// sub dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define SUB_IMM(dst, src, imm, rimm) (0xe2400000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// sub dst, src1, src2, lsl #imm -#define SUB_REG_LSL_IMM(dst, src1, src2, imm) (0xe0400000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// rsb dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define RSB_IMM(dst, src, imm, rimm) (0xe2600000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// cmp src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define CMP_IMM(src, imm, rimm) (0xe3500000 + ((src) << 16) + (imm) + ((rimm) << 7) ) -// nop -#if C_TARGETCPU == ARMV7LE -#define NOP (0xe320f000) -#else -#define NOP MOV_REG_LSL_IMM(HOST_r0, HOST_r0, 0) -#endif - -// logical -// tst src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define TST_IMM(src, imm, rimm) (0xe3100000 + ((src) << 16) + (imm) + ((rimm) << 7) ) -// and dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define AND_IMM(dst, src, imm, rimm) (0xe2000000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// and dst, src1, src2, lsl #imm -#define AND_REG_LSL_IMM(dst, src1, src2, imm) (0xe0000000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// orr dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ORR_IMM(dst, src, imm, rimm) (0xe3800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// orr dst, src1, src2, lsl #imm -#define ORR_REG_LSL_IMM(dst, src1, src2, imm) (0xe1800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// orr dst, src1, src2, lsr #imm -#define ORR_REG_LSR_IMM(dst, src1, src2, imm) (0xe1800020 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// eor dst, src1, src2, lsl #imm -#define EOR_REG_LSL_IMM(dst, src1, src2, imm) (0xe0200000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// bic dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define BIC_IMM(dst, src, imm, rimm) (0xe3c00000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// bic dst, src1, src2, lsl #imm @ 0 <= imm <= 31 -#define BIC_REG_LSL_IMM(dst, src1, src2, imm) (0xe1c00000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 4096 -#define LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// ldr reg, [addr, #-(imm)] @ 0 <= imm < 4096 -#define LDR_IMM_M(reg, addr, imm) (0xe5100000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// ldrh reg, [addr, #imm] @ 0 <= imm < 256 -#define LDRH_IMM(reg, addr, imm) (0xe1d000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// ldrh reg, [addr, #-(imm)] @ 0 <= imm < 256 -#define LDRH_IMM_M(reg, addr, imm) (0xe15000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// ldrb reg, [addr, #imm] @ 0 <= imm < 4096 -#define LDRB_IMM(reg, addr, imm) (0xe5d00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// ldrb reg, [addr, #-(imm)] @ 0 <= imm < 4096 -#define LDRB_IMM_M(reg, addr, imm) (0xe5500000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// ldr reg, [addr1, addr2, lsl #imm] @ 0 <= imm < 31 -#define LDR_REG_LSL_IMM(reg, addr1, addr2, imm) (0xe7900000 + ((reg) << 12) + ((addr1) << 16) + (addr2) + ((imm) << 7) ) - -// store -// str reg, [addr, #imm] @ 0 <= imm < 4096 -#define STR_IMM(reg, addr, imm) (0xe5800000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// str reg, [addr, #-(imm)] @ 0 <= imm < 4096 -#define STR_IMM_M(reg, addr, imm) (0xe5000000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// strh reg, [addr, #imm] @ 0 <= imm < 256 -#define STRH_IMM(reg, addr, imm) (0xe1c000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// strh reg, [addr, #-(imm)] @ 0 <= imm < 256 -#define STRH_IMM_M(reg, addr, imm) (0xe14000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// strb reg, [addr, #imm] @ 0 <= imm < 4096 -#define STRB_IMM(reg, addr, imm) (0xe5c00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// strb reg, [addr, #-(imm)] @ 0 <= imm < 4096 -#define STRB_IMM_M(reg, addr, imm) (0xe5400000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// branch -// beq pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BEQ_FWD(imm) (0x0a000000 + ((imm) >> 2) ) -// bne pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BNE_FWD(imm) (0x1a000000 + ((imm) >> 2) ) -// ble pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BLE_FWD(imm) (0xda000000 + ((imm) >> 2) ) -// b pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define B_FWD(imm) (0xea000000 + ((imm) >> 2) ) -// bx reg -#define BX(reg) (0xe12fff10 + (reg) ) -#if C_TARGETCPU == ARMV7LE -// blx reg -#define BLX_REG(reg) (0xe12fff30 + (reg) ) - -// extend -// sxth dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 -#define SXTH(dst, src, rimm) (0xe6bf0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) -// sxtb dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 -#define SXTB(dst, src, rimm) (0xe6af0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) -// uxth dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 -#define UXTH(dst, src, rimm) (0xe6ff0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) -// uxtb dst, src, ror #rimm @ rimm = 0 | 8 | 16 | 24 -#define UXTB(dst, src, rimm) (0xe6ef0070 + ((dst) << 12) + (src) + (((rimm) & 24) << 7) ) - -// bit field -// bfi dst, src, #lsb, #width @ lsb >= 0, width >= 1, lsb+width <= 32 -#define BFI(dst, src, lsb, width) (0xe7c00010 + ((dst) << 12) + (src) + ((lsb) << 7) + (((lsb) + (width) - 1) << 16) ) -// bfc dst, #lsb, #width @ lsb >= 0, width >= 1, lsb+width <= 32 -#define BFC(dst, lsb, width) (0xe7c0001f + ((dst) << 12) + ((lsb) << 7) + (((lsb) + (width) - 1) << 16) ) -#endif - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - if(reg_src == reg_dst) return; - cache_addd( MOV_REG_LSL_IMM(reg_dst, reg_src, 0) ); // mov reg_dst, reg_src -} - -// helper function -static bool val_is_operand2(Bit32u value, Bit32u *val_shift) { - Bit32u shift; - - if (GCC_UNLIKELY(value == 0)) { - *val_shift = 0; - return true; - } - - shift = 0; - while ((value & 3) == 0) { - value>>=2; - shift+=2; - } - - if ((value >> 8) != 0) return false; - - *val_shift = shift; - return true; -} - -#if C_TARGETCPU != ARMV7LE -// helper function -static Bits get_imm_gen_len(Bit32u imm) { - Bits ret; - if (imm == 0) { - return 1; - } else { - ret = 0; - while (imm) { - while ((imm & 3) == 0) { - imm>>=2; - } - ret++; - imm>>=8; - } - return ret; - } -} - -// helper function -static Bits get_min_imm_gen_len(Bit32u imm) { - Bits num1, num2; - - num1 = get_imm_gen_len(imm); - num2 = get_imm_gen_len(~imm); - - return (num1 <= num2)?num1:num2; -} -#endif - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { -#if C_TARGETCPU == ARMV7LE - Bit32u scale; - - if ( val_is_operand2(imm, &scale) ) { - cache_addd( MOV_IMM(dest_reg, imm >> scale, ROTATE_SCALE(scale)) ); // mov dest_reg, #imm - } else if ( val_is_operand2(~imm, &scale) ) { - cache_addd( MVN_IMM(dest_reg, (~imm) >> scale, ROTATE_SCALE(scale)) ); // mvn dest_reg, #~imm - } else { - cache_addd( MOVW(dest_reg, imm & 0xffff) ); // movw dest_reg, #(imm & 0xffff) - - if (imm >= 0x10000) - { - cache_addd( MOVT(dest_reg, imm >> 16) ); // movt dest_reg, #(imm >> 16) - } - } -#else - Bit32u imm2, first, scale; - - scale = 0; - first = 1; - imm2 = ~imm; - - if (get_imm_gen_len(imm) <= get_imm_gen_len(imm2)) { - if (imm == 0) { - cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 - } else { - while (imm) { - while ((imm & 3) == 0) { - imm>>=2; - scale+=2; - } - if (first) { - cache_addd( MOV_IMM(dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // mov dest_reg, #((imm & 0xff) << scale) - first = 0; - } else { - cache_addd( ORR_IMM(dest_reg, dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) - } - imm>>=8; - scale+=8; - } - } - } else { - if (imm2 == 0) { - cache_addd( MVN_IMM(dest_reg, 0, 0) ); // mvn dest_reg, #0 - } else { - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; - } - if (first) { - cache_addd( MVN_IMM(dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // mvn dest_reg, #((imm2 & 0xff) << scale) - first = 0; - } else { - cache_addd( BIC_IMM(dest_reg, dest_reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // bic dest_reg, dest_reg, #((imm2 & 0xff) << scale) - } - imm2>>=8; - scale+=8; - } - } - } -#endif -} - -// helper function -static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 4096)) { - cache_addd( LDR_IMM(dest_reg, addr_reg, data - addr_data) ); // ldr dest_reg, [addr_reg, #(data - addr_data)] - return true; - } else if ((data < addr_data) && (data > addr_data - 4096)) { - cache_addd( LDR_IMM_M(dest_reg, addr_reg, addr_data - data) ); // ldr dest_reg, [addr_reg, #-(addr_data - data)] - return true; - } - } - break; - case 2: -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 256)) { - cache_addd( LDRH_IMM(dest_reg, addr_reg, data - addr_data) ); // ldrh dest_reg, [addr_reg, #(data - addr_data)] - return true; - } else if ((data < addr_data) && (data > addr_data - 256)) { - cache_addd( LDRH_IMM_M(dest_reg, addr_reg, addr_data - data) ); // ldrh dest_reg, [addr_reg, #-(addr_data - data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 4096)) { - cache_addd( LDRB_IMM(dest_reg, addr_reg, data - addr_data) ); // ldrb dest_reg, [addr_reg, #(data - addr_data)] - return true; - } else if ((data < addr_data) && (data > addr_data - 4096)) { - cache_addd( LDRB_IMM_M(dest_reg, addr_reg, addr_data - data) ); // ldrb dest_reg, [addr_reg, #-(addr_data - data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_to_reg -static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { - // alignment.... - if (dword) { -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((Bit32u)data & 3) { - if ( ((Bit32u)data & 3) == 2 ) { - cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - cache_addd( LDRH_IMM(temp2, data_reg, 2) ); // ldrh temp2, [data_reg, #2] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 16) ); // orr dest_reg, dest_reg, temp2, lsl #16 - } else { - cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addd( LDRH_IMM(temp2, data_reg, 1) ); // ldrh temp2, [data_reg, #1] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 - cache_addd( LDRB_IMM(temp2, data_reg, 3) ); // ldrb temp2, [data_reg, #3] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 24) ); // orr dest_reg, dest_reg, temp2, lsl #24 - } - } else -#endif - { - cache_addd( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] - } - } else { -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((Bit32u)data & 1) { - cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addd( LDRB_IMM(temp2, data_reg, 1) ); // ldrb temp2, [data_reg, #1] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 - } else -#endif - { - cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - } - } -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); - } -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); -} - -// helper function -static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 4096)) { - cache_addd( STR_IMM(src_reg, addr_reg, data - addr_data) ); // str src_reg, [addr_reg, #(data - addr_data)] - return true; - } else if ((data < addr_data) && (data > addr_data - 4096)) { - cache_addd( STR_IMM_M(src_reg, addr_reg, addr_data - data) ); // str src_reg, [addr_reg, #-(addr_data - data)] - return true; - } - } - break; - case 2: -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 256)) { - cache_addd( STRH_IMM(src_reg, addr_reg, data - addr_data) ); // strh src_reg, [addr_reg, #(data - addr_data)] - return true; - } else if ((data < addr_data) && (data > addr_data - 256)) { - cache_addd( STRH_IMM_M(src_reg, addr_reg, addr_data - data) ); // strh src_reg, [addr_reg, #-(addr_data - data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 4096)) { - cache_addd( STRB_IMM(src_reg, addr_reg, data - addr_data) ); // strb src_reg, [addr_reg, #(data - addr_data)] - return true; - } else if ((data < addr_data) && (data > addr_data - 4096)) { - cache_addd( STRB_IMM_M(src_reg, addr_reg, addr_data - data) ); // strb src_reg, [addr_reg, #-(addr_data - data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_from_reg -static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { - // alignment.... - if (dword) { -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((Bit32u)dest & 3) { - if ( ((Bit32u)dest & 3) == 2 ) { - cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 16) ); // mov temp2, src_reg, lsr #16 - cache_addd( STRH_IMM(temp2, data_reg, 2) ); // strh temp2, [data_reg, #2] - } else { - cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 - cache_addd( STRH_IMM(temp2, data_reg, 1) ); // strh temp2, [data_reg, #1] - cache_addd( MOV_REG_LSR_IMM(temp2, temp2, 16) ); // mov temp2, temp2, lsr #16 - cache_addd( STRB_IMM(temp2, data_reg, 3) ); // strb temp2, [data_reg, #3] - } - } else -#endif - { - cache_addd( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] - } - } else { -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - if ((Bit32u)dest & 1) { - cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 - cache_addd( STRB_IMM(temp2, data_reg, 1) ); // strb temp2, [data_reg, #1] - } else -#endif - { - cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - } - } -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_mov_byte_to_reg_low(dest_reg, data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addd( MOV_IMM(dest_reg, imm, 0) ); // mov dest_reg, #(imm) -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(dest_reg, imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] - } -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - if (sign) { -#if C_TARGETCPU == ARMV7LE - cache_addd( SXTB(reg, reg, 0) ); // sxtb reg, reg -#else - cache_addd( MOV_REG_LSL_IMM(reg, reg, 24) ); // mov reg, reg, lsl #24 - cache_addd( MOV_REG_ASR_IMM(reg, reg, 24) ); // mov reg, reg, asr #24 -#endif - } else { -#if C_TARGETCPU == ARMV7LE - cache_addd( UXTB(reg, reg, 0) ); // uxtb reg, reg -#else - cache_addd( AND_IMM(reg, reg, 0xff, 0) ); // and reg, reg, #0xff -#endif - } -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - if (sign) { -#if C_TARGETCPU == ARMV7LE - cache_addd( SXTH(reg, reg, 0) ); // sxth reg, reg -#else - cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 - cache_addd( MOV_REG_ASR_IMM(reg, reg, 16) ); // mov reg, reg, asr #16 -#endif - } else { -#if C_TARGETCPU == ARMV7LE - cache_addd( UXTH(reg, reg, 0) ); // uxth reg, reg -#else - cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 - cache_addd( MOV_REG_LSR_IMM(reg, reg, 16) ); // mov reg, reg, lsr #16 -#endif - } -} - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_mov_word_to_reg(temp3, op, 1); - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - if(!imm) return; - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if ( val_is_operand2(imm, &scale) ) { - cache_addd( ADD_IMM(reg, reg, imm >> scale, ROTATE_SCALE(scale)) ); // add reg, reg, #imm - } else if ( val_is_operand2(imm2, &scale) ) { - cache_addd( SUB_IMM(reg, reg, imm2 >> scale, ROTATE_SCALE(scale)) ); // sub reg, reg, #(-imm) -#if C_TARGETCPU == ARMV7LE - } else if (imm2 < 0x10000) { - cache_addd( MOVW(temp2, imm2) ); // movw temp2, #(-imm) - cache_addd( SUB_REG_LSL_IMM(reg, reg, temp2, 0) ); // sub reg, reg, temp2 -#endif - } else { -#if C_TARGETCPU != ARMV7LE - if (get_min_imm_gen_len(imm) <= get_min_imm_gen_len(imm2)) { -#endif - gen_mov_dword_to_reg_imm(temp2, imm); - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 -#if C_TARGETCPU != ARMV7LE - } else { - gen_mov_dword_to_reg_imm(temp2, imm2); - cache_addd( SUB_REG_LSL_IMM(reg, reg, temp2, 0) ); // sub reg, reg, temp2 - } -#endif - } -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - imm2 = ~imm; - if(!imm2) return; - - if (!imm) { - cache_addd( MOV_IMM(reg, 0, 0) ); // mov reg, #0 - } else if ( val_is_operand2(imm, &scale) ) { - cache_addd( AND_IMM(reg, reg, imm >> scale, ROTATE_SCALE(scale)) ); // and reg, reg, #imm - } else if ( val_is_operand2(imm2, &scale) ) { - cache_addd( BIC_IMM(reg, reg, imm2 >> scale, ROTATE_SCALE(scale)) ); // bic reg, reg, #(~imm) -#if C_TARGETCPU == ARMV7LE - } else if (imm2 < 0x10000) { - cache_addd( MOVW(temp2, imm2) ); // movw temp2, #(~imm) - cache_addd( BIC_REG_LSL_IMM(reg, reg, temp2, 0) ); // bic reg, reg, temp2 -#endif - } else { - gen_mov_dword_to_reg_imm(temp2, imm); - cache_addd( AND_REG_LSL_IMM(reg, reg, temp2, 0) ); // and reg, reg, temp2 - } -} - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_mov_dword_to_reg_imm(temp3, imm); - gen_mov_word_from_reg(temp3, dest, 1); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(temp3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - } - gen_add_imm(temp3, imm); - if (!gen_mov_memval_from_reg(temp3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); - } -} - -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - gen_add_direct_word(dest, (Bit32s)imm, 1); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - Bit32u imm2, scale; - - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(temp3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - } - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if ( val_is_operand2(imm, &scale) ) { - cache_addd( SUB_IMM(temp3, temp3, imm >> scale, ROTATE_SCALE(scale)) ); // sub temp3, temp3, #imm - } else if ( val_is_operand2(imm2, &scale) ) { - cache_addd( ADD_IMM(temp3, temp3, imm2 >> scale, ROTATE_SCALE(scale)) ); // add temp3, temp3, #(-imm) -#if C_TARGETCPU == ARMV7LE - } else if (imm2 < 0x10000) { - cache_addd( MOVW(temp2, imm2) ); // movw temp2, #(-imm) - cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 -#endif - } else { -#if C_TARGETCPU != ARMV7LE - if (get_min_imm_gen_len(imm) <= get_min_imm_gen_len(imm2)) { -#endif - gen_mov_dword_to_reg_imm(temp2, imm); - cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 -#if C_TARGETCPU != ARMV7LE - } else { - gen_mov_dword_to_reg_imm(temp2, imm2); - cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 - } -#endif - } - - if (!gen_mov_memval_from_reg(temp3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); - } -} - -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - gen_sub_direct_word(dest, (Bit32s)imm, 1); -} - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - cache_addd( ADD_REG_LSL_IMM(dest_reg, dest_reg, scale_reg, scale) ); // add dest_reg, dest_reg, scale_reg, lsl #(scale) - gen_add_imm(dest_reg, imm); -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - if (scale) { - cache_addd( MOV_REG_LSL_IMM(dest_reg, dest_reg, scale) ); // mov dest_reg, dest_reg, lsl #(scale) - } - gen_add_imm(dest_reg, imm); -} - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { -#if C_TARGETCPU == ARMV7LE - cache_addd( MOVW(temp1, ((Bit32u)func) & 0xffff) ); // movw temp1, #(func & 0xffff) - cache_addd( MOVT(temp1, ((Bit32u)func) >> 16) ); // movt temp1, #(func >> 16) - cache_addd( BLX_REG(temp1) ); // blx temp1 -#else - cache_addd( LDR_IMM(temp1, HOST_pc, 4) ); // ldr temp1, [pc, #4] - cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd( BX(temp1) ); // bx temp1 - cache_addd((Bit32u)func); // .int func -#endif -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - Bit32u proc_addr = (Bit32u)cache.pos; - gen_call_function_raw(func); - return proc_addr; -} - -#if (1) -// max of 4 parameters in a1-a4 - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - gen_mov_dword_to_reg_imm(param, imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - gen_mov_dword_to_reg_imm(param, addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - gen_mov_regs(param, reg); -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - gen_mov_word_to_reg(param, (void *)mem, 1); -} -#else - other arm abis -#endif - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - Bit32u scale; - - gen_mov_word_to_reg(temp3, ptr, 1); - -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) -// (*ptr) should be word aligned - if ((imm & 0x03) == 0) { -#endif - if ((imm >= 0) && (imm < 4096)) { - cache_addd( LDR_IMM(temp1, temp3, imm) ); // ldr temp1, [temp3, #imm] - } else { - gen_mov_dword_to_reg_imm(temp2, imm); - cache_addd( LDR_REG_LSL_IMM(temp1, temp3, temp2, 0) ); // ldr temp1, [temp3, temp2] - } -#if !(defined(C_UNALIGNED_MEMORY) || (C_TARGETCPU == ARMV7LE)) - } else { - gen_add_imm(temp3, imm); - - cache_addd( LDRB_IMM(temp1, temp3, 0) ); // ldrb temp1, [temp3] - cache_addd( LDRB_IMM(temp2, temp3, 1) ); // ldrb temp2, [temp3, #1] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 8) ); // orr temp1, temp1, temp2, lsl #8 - cache_addd( LDRB_IMM(temp2, temp3, 2) ); // ldrb temp2, [temp3, #2] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 16) ); // orr temp1, temp1, temp2, lsl #16 - cache_addd( LDRB_IMM(temp2, temp3, 3) ); // ldrb temp2, [temp3, #3] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 24) ); // orr temp1, temp1, temp2, lsl #24 - } -#endif - - cache_addd( BX(temp1) ); // bx temp1 -} - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { - if (dword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 - } - cache_addd( BEQ_FWD(0) ); // beq j - return ((Bit32u)cache.pos-4); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - if (dword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 - } - cache_addd( BNE_FWD(0) ); // bne j - return ((Bit32u)cache.pos-4); -} - -// calculate relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-(data+8); - if (len<0) len=-len; - if (len>0x02000000) LOG_MSG("Big jump %d",len); -#endif - *(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff ); -} - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - if (isdword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( TST_IMM(reg, 0xff, 0) ); // tst reg, #0xff - } - cache_addd( BNE_FWD(0) ); // bne j - return ((Bit32u)cache.pos-4); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - cache_addd( BLE_FWD(0) ); // ble j - return ((Bit32u)cache.pos-4); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - *(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff ); -} - -static void gen_run_code(void) { -#if C_TARGETCPU == ARMV7LE - cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} - - cache_addd( MOVW(FC_SEGS_ADDR, ((Bit32u)&Segs) & 0xffff) ); // movw FC_SEGS_ADDR, #(&Segs & 0xffff) - cache_addd( MOVT(FC_SEGS_ADDR, ((Bit32u)&Segs) >> 16) ); // movt FC_SEGS_ADDR, #(&Segs >> 16) - - cache_addd( MOVW(FC_REGS_ADDR, ((Bit32u)&cpu_regs) & 0xffff) ); // movw FC_REGS_ADDR, #(&cpu_regs & 0xffff) - cache_addd( MOVT(FC_REGS_ADDR, ((Bit32u)&cpu_regs) >> 16) ); // movt FC_REGS_ADDR, #(&cpu_regs >> 16) - - cache_addd( MOVW(readdata_addr, ((Bitu)&core_dynrec.readdata) & 0xffff) ); // movw readdata_addr, #(&core_dynrec.readdata & 0xffff) - cache_addd( MOVT(readdata_addr, ((Bitu)&core_dynrec.readdata) >> 16) ); // movt readdata_addr, #(&core_dynrec.readdata >> 16) - - cache_addd( BX(HOST_r0) ); // bx r0 -#else - Bit8u *pos1, *pos2, *pos3; - - cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} - - pos1 = cache.pos; - cache_addd( 0 ); - pos2 = cache.pos; - cache_addd( 0 ); - pos3 = cache.pos; - cache_addd( 0 ); - - cache_addd( BX(HOST_r0) ); // bx r0 - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } - - *(Bit32u*)pos1 = LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] - cache_addd((Bit32u)&Segs); // address of "Segs" - - *(Bit32u*)pos2 = LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" - - *(Bit32u*)pos3 = LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] - cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } -#endif -} - -// return from a function -static void gen_return_function(void) { - cache_addd(0xe8bd8df0); // ldmfd sp!, {v1-v5,v7,v8,pc} -} - -#ifdef DRC_FLAGS_INVALIDATION - -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { -#ifdef DRC_FLAGS_INVALIDATION_DCODE - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_SHRb: - *(Bit32u*)pos=NOP; // nop -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)(pos+4)=BFC(HOST_a1, 8, 24); // bfc a1, 8, 24 - *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 -#else - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff - *(Bit32u*)(pos+12)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 -#endif - break; - case t_SHRw: - *(Bit32u*)pos=NOP; // nop -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)(pos+4)=BFC(HOST_a1, 16, 16); // bfc a1, 16, 16 - *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 -#else - *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+8)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 -#endif - break; - case t_SHRd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_SARb: - *(Bit32u*)pos=NOP; // nop -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)(pos+4)=SXTB(FC_RETOP, HOST_a1, 0); // sxtb FC_RETOP, a1 - *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 -#else - *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+8)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 - *(Bit32u*)(pos+12)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 -#endif - break; - case t_SARw: - *(Bit32u*)pos=NOP; // nop -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)(pos+4)=SXTH(FC_RETOP, HOST_a1, 0); // sxth FC_RETOP, a1 - *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 -#else - *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+8)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 - *(Bit32u*)(pos+12)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 -#endif - break; - case t_SARd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_RORb: -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)pos=BFI(HOST_a1, HOST_a1, 8, 8); // bfi a1, a1, 8, 8 - *(Bit32u*)(pos+4)=BFI(HOST_a1, HOST_a1, 16, 16); // bfi a1, a1, 16, 16 - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 -#else - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 -#endif - break; - case t_RORw: - *(Bit32u*)pos=NOP; // nop -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)(pos+4)=BFI(HOST_a1, HOST_a1, 16, 16); // bfi a1, a1, 16, 16 - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 -#else - *(Bit32u*)(pos+4)=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 -#endif - break; - case t_RORd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - case t_ROLw: -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)pos=BFI(HOST_a1, HOST_a1, 16, 16); // bfi a1, a1, 16, 16 - *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 -#else - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 -#endif - break; - case t_ROLd: - *(Bit32u*)pos=NOP; // nop -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 -#else - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 -#endif - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit32u*)pos=NOP; // nop - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 -#if C_TARGETCPU != ARMV7LE - *(Bit32u*)(pos+12)=NOP; // nop -#endif - break; - default: -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)pos=MOVW(temp1, ((Bit32u)fct_ptr) & 0xffff); // movw temp1, #(fct_ptr & 0xffff) - *(Bit32u*)(pos+4)=MOVT(temp1, ((Bit32u)fct_ptr) >> 16); // movt temp1, #(fct_ptr >> 16) -#else - *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func -#endif - break; - - } -#else -#if C_TARGETCPU == ARMV7LE - *(Bit32u*)pos=MOVW(temp1, ((Bit32u)fct_ptr) & 0xffff); // movw temp1, #(fct_ptr & 0xffff) - *(Bit32u*)(pos+4)=MOVT(temp1, ((Bit32u)fct_ptr) >> 16); // movt temp1, #(fct_ptr >> 16) -#else - *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func -#endif -#endif -} -#endif - -static void cache_block_before_close(void) { } - -#ifdef DRC_USE_SEGS_ADDR - -// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDRH_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldrh dest_reg, [FC_SEGS_ADDR, #index] -} - -// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDR_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldr dest_reg, [FC_SEGS_ADDR, #index] -} - -// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_addd( LDR_IMM(temp1, FC_SEGS_ADDR, index) ); // ldr temp1, [FC_SEGS_ADDR, #index] - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp1, 0) ); // add reg, reg, temp1 -} - -#endif - -#ifdef DRC_USE_REGS_ADDR - -// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] -} - -// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { - if (dword) { - cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] - } else { - cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] - } -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] -} - - -// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_addd( LDR_IMM(temp2, FC_REGS_ADDR, index) ); // ldr temp2, [FC_REGS_ADDR, #index] - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 -} - - -// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) -static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] -} - -// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { - if (dword) { - cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] - } else { - cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] - } -} - -// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR -static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_addd( STRB_IMM(src_reg, FC_REGS_ADDR, index) ); // strb src_reg, [FC_REGS_ADDR, #index] -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-s3.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-s3.h deleted file mode 100644 index 869080250..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-s3.h +++ /dev/null @@ -1,919 +0,0 @@ -/* - * Copyright (C) 2002-2010 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* $Id: risc_armv4le-s3.h,v 1.6 2009-06-27 12:51:10 c2woody Exp $ */ - - -/* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */ - - -// temporary registers -#define temp1 HOST_ip -#define temp2 HOST_v3 -#define temp3 HOST_v4 - -// register that holds function return values -#define FC_RETOP HOST_a1 - -// register used for address calculations, -#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG - -// register that holds the first parameter -#define FC_OP1 HOST_a1 - -// register that holds the second parameter -#define FC_OP2 HOST_a2 - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_v2 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_a1 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_a2 - -// temporary register for LEA -#define TEMP_REG_DRC HOST_v2 - -#ifdef DRC_USE_REGS_ADDR -// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code -#define FC_REGS_ADDR HOST_v7 -#endif - -#ifdef DRC_USE_SEGS_ADDR -// used to hold the address of "Segs" - preferably filled in function gen_run_code -#define FC_SEGS_ADDR HOST_v8 -#endif - - -// helper macro -#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) ) - - -// instruction encodings - -// move -// mov dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define MOV_IMM(dst, imm, rimm) (0xe3a00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) -// mov dst, src, lsl #imm -#define MOV_REG_LSL_IMM(dst, src, imm) (0xe1a00000 + ((dst) << 12) + (src) + ((imm) << 7) ) -// movs dst, src, lsl #imm -#define MOVS_REG_LSL_IMM(dst, src, imm) (0xe1b00000 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, lsr #imm -#define MOV_REG_LSR_IMM(dst, src, imm) (0xe1a00020 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, asr #imm -#define MOV_REG_ASR_IMM(dst, src, imm) (0xe1a00040 + ((dst) << 12) + (src) + ((imm) << 7) ) -// mov dst, src, lsl rreg -#define MOV_REG_LSL_REG(dst, src, rreg) (0xe1a00010 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, lsr rreg -#define MOV_REG_LSR_REG(dst, src, rreg) (0xe1a00030 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, asr rreg -#define MOV_REG_ASR_REG(dst, src, rreg) (0xe1a00050 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mov dst, src, ror rreg -#define MOV_REG_ROR_REG(dst, src, rreg) (0xe1a00070 + ((dst) << 12) + (src) + ((rreg) << 8) ) -// mvn dst, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define MVN_IMM(dst, imm, rimm) (0xe3e00000 + ((dst) << 12) + (imm) + ((rimm) << 7) ) - -// arithmetic -// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// add dst, src1, src2, lsl #imm -#define ADD_REG_LSL_IMM(dst, src1, src2, imm) (0xe0800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// sub dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define SUB_IMM(dst, src, imm, rimm) (0xe2400000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// sub dst, src1, src2, lsl #imm -#define SUB_REG_LSL_IMM(dst, src1, src2, imm) (0xe0400000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// rsb dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define RSB_IMM(dst, src, imm, rimm) (0xe2600000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// cmp src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define CMP_IMM(src, imm, rimm) (0xe3500000 + ((src) << 16) + (imm) + ((rimm) << 7) ) -// nop -#define NOP MOV_REG_LSL_IMM(HOST_r0, HOST_r0, 0) - -// logical -// tst src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define TST_IMM(src, imm, rimm) (0xe3100000 + ((src) << 16) + (imm) + ((rimm) << 7) ) -// and dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define AND_IMM(dst, src, imm, rimm) (0xe2000000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// and dst, src1, src2, lsl #imm -#define AND_REG_LSL_IMM(dst, src1, src2, imm) (0xe0000000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// orr dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ORR_IMM(dst, src, imm, rimm) (0xe3800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) -// orr dst, src1, src2, lsl #imm -#define ORR_REG_LSL_IMM(dst, src1, src2, imm) (0xe1800000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// orr dst, src1, src2, lsr #imm -#define ORR_REG_LSR_IMM(dst, src1, src2, imm) (0xe1800020 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// eor dst, src1, src2, lsl #imm -#define EOR_REG_LSL_IMM(dst, src1, src2, imm) (0xe0200000 + ((dst) << 12) + ((src1) << 16) + (src2) + ((imm) << 7) ) -// bic dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define BIC_IMM(dst, src, imm, rimm) (0xe3c00000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 4096 -#define LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// ldrh reg, [addr, #imm] @ 0 <= imm < 256 -#define LDRH_IMM(reg, addr, imm) (0xe1d000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// ldrb reg, [addr, #imm] @ 0 <= imm < 4096 -#define LDRB_IMM(reg, addr, imm) (0xe5d00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// store -// str reg, [addr, #imm] @ 0 <= imm < 4096 -#define STR_IMM(reg, addr, imm) (0xe5800000 + ((reg) << 12) + ((addr) << 16) + (imm) ) -// strh reg, [addr, #imm] @ 0 <= imm < 256 -#define STRH_IMM(reg, addr, imm) (0xe1c000b0 + ((reg) << 12) + ((addr) << 16) + (((imm) & 0xf0) << 4) + ((imm) & 0x0f) ) -// strb reg, [addr, #imm] @ 0 <= imm < 4096 -#define STRB_IMM(reg, addr, imm) (0xe5c00000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// branch -// beq pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BEQ_FWD(imm) (0x0a000000 + ((imm) >> 2) ) -// bne pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BNE_FWD(imm) (0x1a000000 + ((imm) >> 2) ) -// bgt pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define BGT_FWD(imm) (0xca000000 + ((imm) >> 2) ) -// b pc+imm @ 0 <= imm < 32M & imm mod 4 = 0 -#define B_FWD(imm) (0xea000000 + ((imm) >> 2) ) -// bx reg -#define BX(reg) (0xe12fff10 + (reg) ) - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - if(reg_src == reg_dst) return; - cache_addd( MOV_REG_LSL_IMM(reg_dst, reg_src, 0) ); // mov reg_dst, reg_src -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - Bits first, scale; - if (imm == 0) { - cache_addd( MOV_IMM(dest_reg, 0, 0) ); // mov dest_reg, #0 - } else { - scale = 0; - first = 1; - while (imm) { - while ((imm & 3) == 0) { - imm>>=2; - scale+=2; - } - if (first) { - cache_addd( MOV_IMM(dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // mov dest_reg, #((imm & 0xff) << scale) - first = 0; - } else { - cache_addd( ORR_IMM(dest_reg, dest_reg, imm & 0xff, ROTATE_SCALE(scale)) ); // orr dest_reg, dest_reg, #((imm & 0xff) << scale) - } - imm>>=8; - scale+=8; - } - } -} - -// helper function for gen_mov_word_to_reg -static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { - // alignment.... - if (dword) { - if ((Bit32u)data & 3) { - if ( ((Bit32u)data & 3) == 2 ) { - cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - cache_addd( LDRH_IMM(temp2, data_reg, 2) ); // ldrh temp2, [data_reg, #2] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 16) ); // orr dest_reg, dest_reg, temp2, lsl #16 - } else { - cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addd( LDRH_IMM(temp2, data_reg, 1) ); // ldrh temp2, [data_reg, #1] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 - cache_addd( LDRB_IMM(temp2, data_reg, 3) ); // ldrb temp2, [data_reg, #3] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 24) ); // orr dest_reg, dest_reg, temp2, lsl #24 - } - } else { - cache_addd( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] - } - } else { - if ((Bit32u)data & 1) { - cache_addd( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addd( LDRB_IMM(temp2, data_reg, 1) ); // ldrb temp2, [data_reg, #1] - cache_addd( ORR_REG_LSL_IMM(dest_reg, dest_reg, temp2, 8) ); // orr dest_reg, dest_reg, temp2, lsl #8 - } else { - cache_addd( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - } - } -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1); -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); -} - -// helper function for gen_mov_word_from_reg -static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { - // alignment.... - if (dword) { - if ((Bit32u)dest & 3) { - if ( ((Bit32u)dest & 3) == 2 ) { - cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 16) ); // mov temp2, src_reg, lsr #16 - cache_addd( STRH_IMM(temp2, data_reg, 2) ); // strh temp2, [data_reg, #2] - } else { - cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 - cache_addd( STRH_IMM(temp2, data_reg, 1) ); // strh temp2, [data_reg, #1] - cache_addd( MOV_REG_LSR_IMM(temp2, temp2, 16) ); // mov temp2, temp2, lsr #16 - cache_addd( STRB_IMM(temp2, data_reg, 3) ); // strb temp2, [data_reg, #3] - } - } else { - cache_addd( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] - } - } else { - if ((Bit32u)dest & 1) { - cache_addd( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addd( MOV_REG_LSR_IMM(temp2, src_reg, 8) ); // mov temp2, src_reg, lsr #8 - cache_addd( STRB_IMM(temp2, data_reg, 1) ); // strb temp2, [data_reg, #1] - } else { - cache_addd( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - } - } -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1); -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)data); - cache_addd( LDRB_IMM(dest_reg, temp1, 0) ); // ldrb dest_reg, [temp1] -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_mov_byte_to_reg_low(dest_reg, data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addd( MOV_IMM(dest_reg, imm, 0) ); // mov dest_reg, #(imm) -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(dest_reg, imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - cache_addd( STRB_IMM(src_reg, temp1, 0) ); // strb src_reg, [temp1] -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - if (sign) { - cache_addd( MOV_REG_LSL_IMM(reg, reg, 24) ); // mov reg, reg, lsl #24 - cache_addd( MOV_REG_ASR_IMM(reg, reg, 24) ); // mov reg, reg, asr #24 - } else { - cache_addd( AND_IMM(reg, reg, 0xff, 0) ); // and reg, reg, #0xff - } -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - if (sign) { - cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 - cache_addd( MOV_REG_ASR_IMM(reg, reg, 16) ); // mov reg, reg, asr #16 - } else { - cache_addd( MOV_REG_LSL_IMM(reg, reg, 16) ); // mov reg, reg, lsl #16 - cache_addd( MOV_REG_LSR_IMM(reg, reg, 16) ); // mov reg, reg, lsr #16 - } -} - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_mov_word_to_reg(temp3, op, 1); - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp3, 0) ); // add reg, reg, temp3 -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - Bits scale; - if(!imm) return; - if (imm == 0xffffffff) { - cache_addd( SUB_IMM(reg, reg, 1, 0) ); // sub reg, reg, #1 - } else { - scale = 0; - while (imm) { - while ((imm & 3) == 0) { - imm>>=2; - scale+=2; - } - cache_addd( ADD_IMM(reg, reg, imm & 0xff, ROTATE_SCALE(scale)) ); // add reg, reg, #((imm & 0xff) << scale) - imm>>=8; - scale+=8; - } - } -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - Bits scale; - Bit32u imm2; - imm2 = ~imm; - if(!imm2) return; - if (!imm) { - cache_addd( MOV_IMM(reg, 0, 0) ); // mov reg, #0 - } else { - scale = 0; - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; - } - cache_addd( BIC_IMM(reg, reg, imm2 & 0xff, ROTATE_SCALE(scale)) ); // bic reg, reg, #((imm2 & 0xff) << scale) - imm2>>=8; - scale+=8; - } - } -} - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_mov_dword_to_reg_imm(temp3, imm); - gen_mov_word_from_reg(temp3, dest, 1); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); - if (imm >= 0) { - cache_addd( ADD_IMM(temp3, temp3, (Bit32s)imm, 0) ); // add temp3, temp3, #(imm) - } else { - cache_addd( SUB_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // sub temp3, temp3, #(-imm) - } - gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; - } - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - // maybe use function gen_add_imm - if (dword) { - gen_mov_dword_to_reg_imm(temp2, imm); - } else { - gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); - } - cache_addd( ADD_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // add temp3, temp3, temp2 - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); -} - -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - if(!imm) return; - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, 1, temp1); - if (imm >= 0) { - cache_addd( SUB_IMM(temp3, temp3, (Bit32s)imm, 0) ); // sub temp3, temp3, #(imm) - } else { - cache_addd( ADD_IMM(temp3, temp3, -((Bit32s)imm), 0) ); // add temp3, temp3, #(-imm) - } - gen_mov_word_from_reg_helper(temp3, dest, 1, temp1); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - if(!imm) return; - if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; - } - gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest); - gen_mov_word_to_reg_helper(temp3, dest, dword, temp1); - // maybe use function gen_add_imm/gen_sub_imm - if (dword) { - gen_mov_dword_to_reg_imm(temp2, imm); - } else { - gen_mov_word_to_reg_imm(temp2, (Bit16u)imm); - } - cache_addd( SUB_REG_LSL_IMM(temp3, temp3, temp2, 0) ); // sub temp3, temp3, temp2 - gen_mov_word_from_reg_helper(temp3, dest, dword, temp1); -} - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - cache_addd( ADD_REG_LSL_IMM(dest_reg, dest_reg, scale_reg, scale) ); // add dest_reg, dest_reg, scale_reg, lsl #(scale) - gen_add_imm(dest_reg, imm); -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - if (scale) { - cache_addd( MOV_REG_LSL_IMM(dest_reg, dest_reg, scale) ); // mov dest_reg, dest_reg, lsl #(scale) - } - gen_add_imm(dest_reg, imm); -} - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { - cache_addd( LDR_IMM(temp1, HOST_pc, 4) ); // ldr temp1, [pc, #4] - cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd( BX(temp1) ); // bx temp1 - cache_addd((Bit32u)func); // .int func -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - Bit32u proc_addr = (Bit32u)cache.pos; - gen_call_function_raw(func); - return proc_addr; -} - -#if (1) -// max of 4 parameters in a1-a4 - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - gen_mov_dword_to_reg_imm(param, imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - gen_mov_dword_to_reg_imm(param, addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - gen_mov_regs(param, reg); -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - gen_mov_word_to_reg(param, (void *)mem, 1); -} -#else - other arm abis -#endif - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - Bits scale; - Bitu imm2; - gen_mov_word_to_reg(temp3, ptr, 1); - - if (imm) { - scale = 0; - imm2 = (Bitu)imm; - while (imm2) { - while ((imm2 & 3) == 0) { - imm2>>=2; - scale+=2; - } - cache_addd( ADD_IMM(temp3, temp3, imm2 & 0xff, ROTATE_SCALE(scale)) ); // add temp3, temp3, #((imm2 & 0xff) << scale) - imm2>>=8; - scale+=8; - } - } - -#if (1) -// (*ptr) should be word aligned - if ((imm & 0x03) == 0) { - cache_addd( LDR_IMM(temp1, temp3, 0) ); // ldr temp1, [temp3] - } else -#endif - { - cache_addd( LDRB_IMM(temp1, temp3, 0) ); // ldrb temp1, [temp3] - cache_addd( LDRB_IMM(temp2, temp3, 1) ); // ldrb temp2, [temp3, #1] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 8) ); // orr temp1, temp1, temp2, lsl #8 - cache_addd( LDRB_IMM(temp2, temp3, 2) ); // ldrb temp2, [temp3, #2] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 16) ); // orr temp1, temp1, temp2, lsl #16 - cache_addd( LDRB_IMM(temp2, temp3, 3) ); // ldrb temp2, [temp3, #3] - cache_addd( ORR_REG_LSL_IMM(temp1, temp1, temp2, 24) ); // orr temp1, temp1, temp2, lsl #24 - } - - cache_addd( BX(temp1) ); // bx temp1 -} - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { - if (dword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 - } - cache_addd( BEQ_FWD(0) ); // beq j - return ((Bit32u)cache.pos-4); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - if (dword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( MOVS_REG_LSL_IMM(temp1, reg, 16) ); // movs temp1, reg, lsl #16 - } - cache_addd( BNE_FWD(0) ); // bne j - return ((Bit32u)cache.pos-4); -} - -// calculate relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-(data+8); - if (len<0) len=-len; - if (len>0x02000000) LOG_MSG("Big jump %d",len); -#endif - *(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff ); -} - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - if (isdword) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - } else { - cache_addd( TST_IMM(reg, 0xff, 0) ); // tst reg, #0xff - } - cache_addd( BEQ_FWD(8) ); // beq nobranch (pc +8) - cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] - cache_addd( BX(temp1) ); // bx temp1 - cache_addd(0); // fill j - // nobranch: - return ((Bit32u)cache.pos-4); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addd( CMP_IMM(reg, 0, 0) ); // cmp reg, #0 - cache_addd( BGT_FWD(8) ); // bgt nobranch (pc+8) - cache_addd( LDR_IMM(temp1, HOST_pc, 0) ); // ldr temp1, [pc, #0] - cache_addd( BX(temp1) ); // bx temp1 - cache_addd(0); // fill j - // nobranch: - return ((Bit32u)cache.pos-4); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - // this is an absolute branch - *(Bit32u*)data=(Bit32u)cache.pos; -} - -static void gen_run_code(void) { - cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd(0xe92d0cf0); // stmfd sp!, {v1-v4,v7,v8} - - // adr: 8 - cache_addd( LDR_IMM(FC_SEGS_ADDR, HOST_pc, 64 - (8 + 8)) ); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] - // adr: 12 - cache_addd( LDR_IMM(FC_REGS_ADDR, HOST_pc, 68 - (12 + 8)) ); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - - cache_addd( ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd(0xe92d4000); // stmfd sp!, {lr} - cache_addd( BX(HOST_r0) ); // bx r0 - - cache_addd(0xe8bd0cf0); // ldmfd sp!, {v1-v4,v7,v8} - - cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd( BX(HOST_lr) ); // bx lr - - // fill up to 64 bytes - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - cache_addd( NOP ); // nop - - // adr: 64 - cache_addd((Bit32u)&Segs); // address of "Segs" - // adr: 68 - cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" -} - -// return from a function -static void gen_return_function(void) { - cache_addd(0xe8bd4000); // ldmfd sp!, {lr} - cache_addd( BX(HOST_lr) ); // bx lr -} - -#ifdef DRC_FLAGS_INVALIDATION - -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { -#ifdef DRC_FLAGS_INVALIDATION_DCODE - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit32u*)pos=ADD_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // add FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit32u*)pos=ORR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // orr FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit32u*)pos=AND_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // and FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit32u*)pos=SUB_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // sub FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit32u*)pos=EOR_REG_LSL_IMM(FC_RETOP, HOST_a1, HOST_a2, 0); // eor FC_RETOP, a1, a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit32u*)pos=B_FWD(8); // b (pc+2*4) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit32u*)pos=ADD_IMM(FC_RETOP, HOST_a1, 1, 0); // add FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit32u*)pos=SUB_IMM(FC_RETOP, HOST_a1, 1, 0); // sub FC_RETOP, a1, #1 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit32u*)pos=MOV_REG_LSL_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsl a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHRb: - *(Bit32u*)pos=AND_IMM(FC_RETOP, HOST_a1, 0xff, 0); // and FC_RETOP, a1, #0xff - *(Bit32u*)(pos+4)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHRw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=MOV_REG_LSR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=MOV_REG_LSR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, lsr a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SHRd: - *(Bit32u*)pos=MOV_REG_LSR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, lsr a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SARb: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 24); // mov FC_RETOP, FC_RETOP, asr #24 - *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SARw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=MOV_REG_ASR_IMM(FC_RETOP, FC_RETOP, 16); // mov FC_RETOP, FC_RETOP, asr #16 - *(Bit32u*)(pos+8)=MOV_REG_ASR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, asr a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_SARd: - *(Bit32u*)pos=MOV_REG_ASR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, asr a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_RORb: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 24); // mov FC_RETOP, a1, lsl #24 - *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 8); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - break; - case t_RORw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+8)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_RORd: - *(Bit32u*)pos=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_ROLw: - *(Bit32u*)pos=MOV_REG_LSL_IMM(FC_RETOP, HOST_a1, 16); // mov FC_RETOP, a1, lsl #16 - *(Bit32u*)(pos+4)=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+8)=ORR_REG_LSR_IMM(FC_RETOP, FC_RETOP, FC_RETOP, 16); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16 - *(Bit32u*)(pos+12)=MOV_REG_ROR_REG(FC_RETOP, FC_RETOP, HOST_a2); // mov FC_RETOP, FC_RETOP, ror a2 - break; - case t_ROLd: - *(Bit32u*)pos=RSB_IMM(HOST_a2, HOST_a2, 32, 0); // rsb a2, a2, #32 - *(Bit32u*)(pos+4)=MOV_REG_ROR_REG(FC_RETOP, HOST_a1, HOST_a2); // mov FC_RETOP, a1, ror a2 - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit32u*)pos=RSB_IMM(FC_RETOP, HOST_a1, 0, 0); // rsb FC_RETOP, a1, #0 - *(Bit32u*)(pos+4)=NOP; // nop - *(Bit32u*)(pos+8)=NOP; // nop - *(Bit32u*)(pos+12)=NOP; // nop - break; - default: - *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func - break; - - } -#else - *(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func -#endif -} -#endif - -static void cache_block_before_close(void) { } - -#ifdef DRC_USE_SEGS_ADDR - -// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDRH_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldrh dest_reg, [FC_SEGS_ADDR, #index] -} - -// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDR_IMM(dest_reg, FC_SEGS_ADDR, index) ); // ldr dest_reg, [FC_SEGS_ADDR, #index] -} - -// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_addd( LDR_IMM(temp1, FC_SEGS_ADDR, index) ); // ldr temp1, [FC_SEGS_ADDR, #index] - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp1, 0) ); // add reg, reg, temp1 -} - -#endif - -#ifdef DRC_USE_REGS_ADDR - -// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] -} - -// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { - if (dword) { - cache_addd( LDR_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldr dest_reg, [FC_REGS_ADDR, #index] - } else { - cache_addd( LDRH_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrh dest_reg, [FC_REGS_ADDR, #index] - } -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_addd( LDRB_IMM(dest_reg, FC_REGS_ADDR, index) ); // ldrb dest_reg, [FC_REGS_ADDR, #index] -} - - -// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_addd( LDR_IMM(temp2, FC_REGS_ADDR, index) ); // ldr temp2, [FC_REGS_ADDR, #index] - cache_addd( ADD_REG_LSL_IMM(reg, reg, temp2, 0) ); // add reg, reg, temp2 -} - - -// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) -static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] -} - -// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { - if (dword) { - cache_addd( STR_IMM(src_reg, FC_REGS_ADDR, index) ); // str src_reg, [FC_REGS_ADDR, #index] - } else { - cache_addd( STRH_IMM(src_reg, FC_REGS_ADDR, index) ); // strh src_reg, [FC_REGS_ADDR, #index] - } -} - -// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR -static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_addd( STRB_IMM(src_reg, FC_REGS_ADDR, index) ); // strb src_reg, [FC_REGS_ADDR, #index] -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb-iw.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb-iw.h deleted file mode 100644 index 5d8f8b529..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb-iw.h +++ /dev/null @@ -1,1505 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* ARMv4 (little endian) backend by M-HT (thumb version with data pool, requires -mthumb-interwork switch when compiling dosbox) */ - - -// temporary "lo" registers -#define templo1 HOST_v3 -#define templo2 HOST_v4 -#define templo3 HOST_v2 - -// register that holds function return values -#define FC_RETOP HOST_a1 - -// register used for address calculations, -#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG - -// register that holds the first parameter -#define FC_OP1 HOST_a1 - -// register that holds the second parameter -#define FC_OP2 HOST_a2 - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_a4 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_a1 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_a2 - -// temporary register for LEA -#define TEMP_REG_DRC HOST_a4 - -// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code -#define FC_REGS_ADDR HOST_v7 - -// used to hold the address of "Segs" - preferably filled in function gen_run_code -#define FC_SEGS_ADDR HOST_v8 - -// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code -#define readdata_addr HOST_v5 - - -// instruction encodings - -// move -// mov dst, #imm @ 0 <= imm <= 255 -#define MOV_IMM(dst, imm) (0x2000 + ((dst) << 8) + (imm) ) -// mov dst, src -#define MOV_REG(dst, src) ADD_IMM3(dst, src, 0) -// mov dst, src -#define MOV_LO_HI(dst, src) (0x4640 + (dst) + (((src) - HOST_r8) << 3) ) -// mov dst, src -#define MOV_HI_LO(dst, src) (0x4680 + ((dst) - HOST_r8) + ((src) << 3) ) - -// arithmetic -// add dst, src, #imm @ 0 <= imm <= 7 -#define ADD_IMM3(dst, src, imm) (0x1c00 + (dst) + ((src) << 3) + ((imm) << 6) ) -// add dst, #imm @ 0 <= imm <= 255 -#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) -// add dst, src1, src2 -#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 -#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) -// sub dst, src1, src2 -#define SUB_REG(dst, src1, src2) (0x1a00 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// sub dst, src, #imm @ 0 <= imm <= 7 -#define SUB_IMM3(dst, src, imm) (0x1e00 + (dst) + ((src) << 3) + ((imm) << 6) ) -// sub dst, #imm @ 0 <= imm <= 255 -#define SUB_IMM8(dst, imm) (0x3800 + ((dst) << 8) + (imm) ) -// neg dst, src -#define NEG(dst, src) (0x4240 + (dst) + ((src) << 3) ) -// cmp dst, #imm @ 0 <= imm <= 255 -#define CMP_IMM(dst, imm) (0x2800 + ((dst) << 8) + (imm) ) -// nop -#define NOP (0x46c0) - -// logical -// and dst, src -#define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) -// bic dst, src -#define BIC(dst, src) (0x4380 + (dst) + ((src) << 3) ) -// eor dst, src -#define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) -// orr dst, src -#define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) -// mvn dst, src -#define MVN(dst, src) (0x43c0 + (dst) + ((src) << 3) ) - -// shift/rotate -// lsl dst, src, #imm -#define LSL_IMM(dst, src, imm) (0x0000 + (dst) + ((src) << 3) + ((imm) << 6) ) -// lsl dst, reg -#define LSL_REG(dst, reg) (0x4080 + (dst) + ((reg) << 3) ) -// lsr dst, src, #imm -#define LSR_IMM(dst, src, imm) (0x0800 + (dst) + ((src) << 3) + ((imm) << 6) ) -// lsr dst, reg -#define LSR_REG(dst, reg) (0x40c0 + (dst) + ((reg) << 3) ) -// asr dst, src, #imm -#define ASR_IMM(dst, src, imm) (0x1000 + (dst) + ((src) << 3) + ((imm) << 6) ) -// asr dst, reg -#define ASR_REG(dst, reg) (0x4100 + (dst) + ((reg) << 3) ) -// ror dst, reg -#define ROR_REG(dst, reg) (0x41c0 + (dst) + ((reg) << 3) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 -#define LDR_IMM(reg, addr, imm) (0x6800 + (reg) + ((addr) << 3) + ((imm) << 4) ) -// ldrh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 -#define LDRH_IMM(reg, addr, imm) (0x8800 + (reg) + ((addr) << 3) + ((imm) << 5) ) -// ldrb reg, [addr, #imm] @ 0 <= imm < 32 -#define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) -// ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 -#define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) -// ldr reg, [addr1, addr2] -#define LDR_REG(reg, addr1, addr2) (0x5800 + (reg) + ((addr1) << 3) + ((addr2) << 6) ) - -// store -// str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 -#define STR_IMM(reg, addr, imm) (0x6000 + (reg) + ((addr) << 3) + ((imm) << 4) ) -// strh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 -#define STRH_IMM(reg, addr, imm) (0x8000 + (reg) + ((addr) << 3) + ((imm) << 5) ) -// strb reg, [addr, #imm] @ 0 <= imm < 32 -#define STRB_IMM(reg, addr, imm) (0x7000 + (reg) + ((addr) << 3) + ((imm) << 6) ) - -// branch -// beq pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BEQ_FWD(imm) (0xd000 + ((imm) >> 1) ) -// bne pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BNE_FWD(imm) (0xd100 + ((imm) >> 1) ) -// bgt pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BGT_FWD(imm) (0xdc00 + ((imm) >> 1) ) -// b pc+imm @ 0 <= imm < 2048 & imm mod 2 = 0 -#define B_FWD(imm) (0xe000 + ((imm) >> 1) ) -// bx reg -#define BX(reg) (0x4700 + ((reg) << 3) ) - - -// arm instructions - -// arithmetic -// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ARM_ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 4096 -#define ARM_LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// store -// str reg, [addr, #-(imm)]! @ 0 <= imm < 4096 -#define ARM_STR_IMM_M_W(reg, addr, imm) (0xe5200000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// branch -// bx reg -#define ARM_BX(reg) (0xe12fff10 + (reg) ) - - -// data pool defines -#define CACHE_DATA_JUMP (2) -#define CACHE_DATA_ALIGN (32) -#define CACHE_DATA_MIN (32) -#define CACHE_DATA_MAX (288) - -// data pool variables -static Bit8u * cache_datapos = NULL; // position of data pool in the cache block -static Bit32u cache_datasize = 0; // total size of data pool -static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool - - -// forwarded function -static void INLINE gen_create_branch_short(void * func); - -// function to check distance to data pool -// if too close, then generate jump after data pool -static void cache_checkinstr(Bit32u size) { - if (cache_datasize == 0) { - if (cache_datapos != NULL) { - if (cache.pos + size + CACHE_DATA_JUMP >= cache_datapos) { - cache_datapos = NULL; - } - } - return; - } - - if (cache.pos + size + CACHE_DATA_JUMP <= cache_datapos) return; - - { - register Bit8u * newcachepos; - - newcachepos = cache_datapos + cache_datasize; - gen_create_branch_short(newcachepos); - cache.pos = newcachepos; - } - - if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && - cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) - { - cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); - } else { - register Bit32u cachemodsize; - - cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); - - if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || - cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) - { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); - } else { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); - } - } - - cache_datasize = 0; - cache_dataindex = 0; -} - -// function to reserve item in data pool -// returns address of item -static Bit8u * cache_reservedata(void) { - // if data pool not yet initialized, then initialize data pool - if (GCC_UNLIKELY(cache_datapos == NULL)) { - if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN < cache.block.active->cache.start + CACHE_DATA_MAX) { - cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); - } - } - - // if data pool not yet used, then set data pool - if (cache_datasize == 0) { - // set data pool address is too close (or behind) cache.pos then set new data pool size - if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_JUMP /*+ CACHE_DATA_ALIGN*/ > cache_datapos) { - if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && - cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) - { - cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); - } else { - register Bit32u cachemodsize; - - cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); - - if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || - cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) - { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); - } else { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); - } - } - } - // set initial data pool size - cache_datasize = CACHE_DATA_ALIGN; - } - - // if data pool is full, then enlarge data pool - if (cache_dataindex == cache_datasize) { - cache_datasize += CACHE_DATA_ALIGN; - } - - cache_dataindex += 4; - return (cache_datapos + (cache_dataindex - 4)); -} - -static void cache_block_before_close(void) { - // if data pool in use, then resize cache block to include the data pool - if (cache_datasize != 0) - { - cache.pos = cache_datapos + cache_dataindex; - } - - // clear the values before next use - cache_datapos = NULL; - cache_datasize = 0; - cache_dataindex = 0; -} - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - if(reg_src == reg_dst) return; - cache_checkinstr(2); - cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src -} - -// helper function -static bool val_single_shift(Bit32u value, Bit32u *val_shift) { - Bit32u shift; - - if (GCC_UNLIKELY(value == 0)) { - *val_shift = 0; - return true; - } - - shift = 0; - while ((value & 1) == 0) { - value>>=1; - shift+=1; - } - - if ((value >> 8) != 0) return false; - - *val_shift = shift; - return true; -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - Bit32u scale; - - if (imm < 256) { - cache_checkinstr(2); - cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) - } else if ((~imm) < 256) { - cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, ~imm) ); // mov dest_reg, #(~imm) - cache_addw( MVN(dest_reg, dest_reg) ); // mvn dest_reg, dest_reg - } else if (val_single_shift(imm, &scale)) { - cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> scale) ); // mov dest_reg, #(imm >> scale) - cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #scale - } else { - Bit32u diff; - - cache_checkinstr(4); - - diff = imm - ((Bit32u)cache.pos+4); - - if ((diff < 1024) && ((imm & 0x03) == 0)) { - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( ADD_LO_PC_IMM(dest_reg, diff >> 2) ); // add dest_reg, pc, #(diff >> 2) - } else { - cache_addw( NOP ); // nop - cache_addw( ADD_LO_PC_IMM(dest_reg, (diff - 2) >> 2) ); // add dest_reg, pc, #((diff - 2) >> 2) - } - } else { - Bit8u *datapos; - - datapos = cache_reservedata(); - *(Bit32u*)datapos=imm; - - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 4)) ); // ldr dest_reg, [pc, datapos] - } else { - cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 2)) ); // ldr dest_reg, [pc, datapos] - } - } - } -} - -// helper function -static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDR_IMM(dest_reg, templo2, data - addr_data) ); // ldr dest_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 2: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDRH_IMM(dest_reg, templo2, data - addr_data) ); // ldrh dest_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 32)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDRB_IMM(dest_reg, templo2, data - addr_data) ); // ldrb dest_reg, [templo2, #(data - addr_data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_to_reg -static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { - // alignment.... - if (dword) { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)data & 3) { - if ( ((Bit32u)data & 3) == 2 ) { - cache_checkinstr(8); - cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - cache_addw( LDRH_IMM(templo1, data_reg, 2) ); // ldrh templo1, [data_reg, #2] - cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else { - cache_checkinstr(16); - cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addw( ADD_IMM3(templo1, data_reg, 1) ); // add templo1, data_reg, #1 - cache_addw( LDRH_IMM(templo1, templo1, 0) ); // ldrh templo1, [templo1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - cache_addw( LDRB_IMM(templo1, data_reg, 3) ); // ldrb templo1, [data_reg, #3] - cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } - } else -#endif - { - cache_checkinstr(2); - cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] - } - } else { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)data & 1) { - cache_checkinstr(8); - cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else -#endif - { - cache_checkinstr(2); - cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - } - } -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); - } -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); -} - -// helper function -static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STR_IMM(src_reg, templo2, data - addr_data) ); // str src_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 2: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STRH_IMM(src_reg, templo2, data - addr_data) ); // strh src_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 32)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STRB_IMM(src_reg, templo2, data - addr_data) ); // strb src_reg, [templo2, #(data - addr_data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_from_reg -static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { - // alignment.... - if (dword) { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)dest & 3) { - if ( ((Bit32u)dest & 3) == 2 ) { - cache_checkinstr(8); - cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 - cache_addw( STRH_IMM(templo1, data_reg, 2) ); // strh templo1, [data_reg, #2] - } else { - cache_checkinstr(20); - cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 - cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 - cache_addw( STRB_IMM(templo1, data_reg, 2) ); // strb templo1, [data_reg, #2] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 - cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] - } - } else -#endif - { - cache_checkinstr(2); - cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] - } - } else { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)dest & 1) { - cache_checkinstr(8); - cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 - cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - } else -#endif - { - cache_checkinstr(2); - cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - } - } -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); - cache_checkinstr(2); - cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_mov_byte_to_reg_low(dest_reg, data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_checkinstr(2); - cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(dest_reg, imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); - cache_checkinstr(2); - cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] - } -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - cache_checkinstr(4); - cache_addw( LSL_IMM(reg, reg, 24) ); // lsl reg, reg, #24 - - if (sign) { - cache_addw( ASR_IMM(reg, reg, 24) ); // asr reg, reg, #24 - } else { - cache_addw( LSR_IMM(reg, reg, 24) ); // lsr reg, reg, #24 - } -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - cache_checkinstr(4); - cache_addw( LSL_IMM(reg, reg, 16) ); // lsl reg, reg, #16 - - if (sign) { - cache_addw( ASR_IMM(reg, reg, 16) ); // asr reg, reg, #16 - } else { - cache_addw( LSR_IMM(reg, reg, 16) ); // lsr reg, reg, #16 - } -} - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_mov_word_to_reg(templo3, op, 1); - cache_checkinstr(2); - cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3 -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - if(!imm) return; - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if (imm <= 255) { - cache_checkinstr(2); - cache_addw( ADD_IMM8(reg, imm) ); // add reg, #imm - } else if (imm2 <= 255) { - cache_checkinstr(2); - cache_addw( SUB_IMM8(reg, imm2) ); // sub reg, #(-imm) - } else { - if (val_single_shift(imm2, &scale)) { - cache_checkinstr((scale)?6:4); - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( SUB_REG(reg, reg, templo1) ); // sub reg, reg, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 - } - } -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - imm2 = ~imm; - if(!imm2) return; - - if (!imm) { - cache_checkinstr(2); - cache_addw( MOV_IMM(reg, 0) ); // mov reg, #0 - } else { - if (val_single_shift(imm2, &scale)) { - cache_checkinstr((scale)?6:4); - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( BIC(reg, templo1) ); // bic reg, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( AND(reg, templo1) ); // and reg, templo1 - } - } -} - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_mov_dword_to_reg_imm(templo3, imm); - gen_mov_word_from_reg(templo3, dest, 1); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - } - gen_add_imm(templo3, imm); - if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); - } -} - -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - gen_add_direct_word(dest, (Bit32s)imm, 1); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - Bit32u imm2, scale; - - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - } - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if (imm <= 255) { - cache_checkinstr(2); - cache_addw( SUB_IMM8(templo3, imm) ); // sub templo3, #imm - } else if (imm2 <= 255) { - cache_checkinstr(2); - cache_addw( ADD_IMM8(templo3, imm2) ); // add templo3, #(-imm) - } else { - if (val_single_shift(imm2, &scale)) { - cache_checkinstr((scale)?6:4); - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 - } - } - - if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); - } -} - -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - gen_sub_direct_word(dest, (Bit32s)imm, 1); -} - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - if (scale) { - cache_checkinstr(4); - cache_addw( LSL_IMM(templo1, scale_reg, scale) ); // lsl templo1, scale_reg, #(scale) - cache_addw( ADD_REG(dest_reg, dest_reg, templo1) ); // add dest_reg, dest_reg, templo1 - } else { - cache_checkinstr(2); - cache_addw( ADD_REG(dest_reg, dest_reg, scale_reg) ); // add dest_reg, dest_reg, scale_reg - } - gen_add_imm(dest_reg, imm); -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - if (scale) { - cache_checkinstr(2); - cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #(scale) - } - gen_add_imm(dest_reg, imm); -} - -// helper function for gen_call_function_raw and gen_call_function_setup -static void gen_call_function_helper(void * func) { - Bit8u *datapos; - - datapos = cache_reservedata(); - *(Bit32u*)datapos=(Bit32u)func; - - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] - cache_addw( ADD_LO_PC_IMM(templo2, 8) ); // adr templo2, after_call (add templo2, pc, #8) - cache_addw( ADD_IMM8(templo2, 1) ); // add templo2, #1 - cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 - cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state - cache_addw( NOP ); // nop - } else { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] - cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4) - cache_addw( ADD_IMM8(templo2, 1) ); // add templo2, #1 - cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 - cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state - } - // after_call: - - // thumb state from now on -} - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { - cache_checkinstr(12); - gen_call_function_helper(func); -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - cache_checkinstr(12); - Bit32u proc_addr = (Bit32u)cache.pos; - gen_call_function_helper(func); - return proc_addr; - // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) - // then length of generated code is 12 bytes - // otherwise length of generated code is 10 bytes -} - -#if (1) -// max of 4 parameters in a1-a4 - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - gen_mov_dword_to_reg_imm(param, imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - gen_mov_dword_to_reg_imm(param, addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - gen_mov_regs(param, reg); -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - gen_mov_word_to_reg(param, (void *)mem, 1); -} -#else - other arm abis -#endif - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - gen_mov_word_to_reg(templo3, ptr, 1); - -#if !defined(C_UNALIGNED_MEMORY) -// (*ptr) should be word aligned - if ((imm & 0x03) == 0) { -#endif - if ((imm >= 0) && (imm < 128) && ((imm & 3) == 0)) { - cache_checkinstr(6); - cache_addw( LDR_IMM(templo2, templo3, imm) ); // ldr templo2, [templo3, #imm] - } else { - gen_mov_dword_to_reg_imm(templo2, imm); - cache_checkinstr(6); - cache_addw( LDR_REG(templo2, templo3, templo2) ); // ldr templo2, [templo3, templo2] - } -#if !defined(C_UNALIGNED_MEMORY) - } else { - gen_add_imm(templo3, imm); - - cache_checkinstr(24); - cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] - cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2] - cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3] - cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - } -#endif - - // increase jmp address to keep thumb state - cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - - cache_addw( BX(templo2) ); // bx templo2 -} - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { - cache_checkinstr(4); - if (dword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 - } - cache_addw( BEQ_FWD(0) ); // beq j - return ((Bit32u)cache.pos-2); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - cache_checkinstr(4); - if (dword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 - } - cache_addw( BNE_FWD(0) ); // bne j - return ((Bit32u)cache.pos-2); -} - -// calculate relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-(data+4); - if (len<0) len=-len; - if (len>252) LOG_MSG("Big jump %d",len); -#endif - *(Bit8u*)data=(Bit8u)( ((Bit32u)cache.pos-(data+4)) >> 1 ); -} - - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - Bit8u *datapos; - - cache_checkinstr(8); - datapos = cache_reservedata(); - - if (isdword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo2, reg, 24) ); // lsl templo2, reg, #24 - } - cache_addw( BEQ_FWD(2) ); // beq nobranch (pc+2) - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] - } else { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] - } - cache_addw( BX(templo1) ); // bx templo1 - // nobranch: - return ((Bit32u)datapos); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - Bit8u *datapos; - - cache_checkinstr(8); - datapos = cache_reservedata(); - - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - cache_addw( BGT_FWD(2) ); // bgt nobranch (pc+2) - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] - } else { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] - } - cache_addw( BX(templo1) ); // bx templo1 - // nobranch: - return ((Bit32u)datapos); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - // this is an absolute branch - *(Bit32u*)data=((Bit32u)cache.pos) + 1; // add 1 to keep processor in thumb state -} - -static void gen_run_code(void) { - Bit8u *pos1, *pos2, *pos3; - -#if (__ARM_EABI__) - // 8-byte stack alignment - cache_addd(0xe92d4ff0); // stmfd sp!, {v1-v8,lr} -#else - cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} -#endif - - cache_addd( ARM_ADD_IMM(HOST_r0, HOST_r0, 1, 0) ); // add r0, r0, #1 - - pos1 = cache.pos; - cache_addd( 0 ); - pos2 = cache.pos; - cache_addd( 0 ); - pos3 = cache.pos; - cache_addd( 0 ); - - cache_addd( ARM_ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd( ARM_STR_IMM_M_W(HOST_lr, HOST_sp, 4) ); // str lr, [sp, #-4]! - cache_addd( ARM_BX(HOST_r0) ); // bx r0 - -#if (__ARM_EABI__) - cache_addd(0xe8bd4ff0); // ldmfd sp!, {v1-v8,lr} -#else - cache_addd(0xe8bd4df0); // ldmfd sp!, {v1-v5,v7,v8,lr} -#endif - cache_addd( ARM_BX(HOST_lr) ); // bx lr - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } - - *(Bit32u*)pos1 = ARM_LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] - cache_addd((Bit32u)&Segs); // address of "Segs" - - *(Bit32u*)pos2 = ARM_LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" - - *(Bit32u*)pos3 = ARM_LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] - cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } -} - -// return from a function -static void gen_return_function(void) { - cache_checkinstr(4); - cache_addw(0xbc08); // pop {r3} - cache_addw( BX(HOST_r3) ); // bx r3 -} - - -// short unconditional jump (over data pool) -// must emit at most CACHE_DATA_JUMP bytes -static void INLINE gen_create_branch_short(void * func) { - cache_addw( B_FWD((Bit32u)func - ((Bit32u)cache.pos + 4)) ); // b func -} - - -#ifdef DRC_FLAGS_INVALIDATION - -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { - if ((*(Bit16u*)pos & 0xf000) == 0xe000) { - if ((*(Bit16u*)pos & 0x0fff) >= ((CACHE_DATA_ALIGN / 2) - 1) && - (*(Bit16u*)pos & 0x0fff) < 0x0800) - { - pos = (Bit8u *) ( ( ( (Bit32u)(*(Bit16u*)pos & 0x0fff) ) << 1 ) + ((Bit32u)pos + 4) ); - } - } - -#ifdef DRC_FLAGS_INVALIDATION_DCODE - if (((Bit32u)pos & 0x03) == 0) - { - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit16u*)pos=B_FWD(8); // b after_call (pc+8) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_SHRb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+10)=NOP; // nop - break; - case t_SHRw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+10)=NOP; // nop - break; - case t_SHRd: - *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_SARb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+10)=NOP; // nop - break; - case t_SARw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+10)=NOP; // nop - break; - case t_SARd: - *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_RORb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_RORw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+4)=NOP; // nop - *(Bit16u*)(pos+6)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+8)=NOP; // nop - *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_RORd: - *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - case t_ROLw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_ROLd: - *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+10)=NOP; // nop - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 - *(Bit16u*)(pos+2)=B_FWD(6); // b after_call (pc+6) - break; - default: - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func - break; - } - } - else - { - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit16u*)pos=B_FWD(6); // b after_call (pc+6) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_SHRb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - break; - case t_SHRw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - break; - case t_SHRd: - *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_SARb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - break; - case t_SARw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - break; - case t_SARd: - *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_RORw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+4)=NOP; // nop - *(Bit16u*)(pos+6)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_RORd: - *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - case t_ROLd: - *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+2)=NOP; // nop - *(Bit16u*)(pos+4)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 - *(Bit16u*)(pos+2)=B_FWD(4); // b after_call (pc+4) - break; - default: - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func - break; - } - - } -#else - if (((Bit32u)pos & 0x03) == 0) - { - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func - } - else - { - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func - } -#endif -} -#endif - -#ifdef DRC_USE_SEGS_ADDR - -// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDRH_IMM(dest_reg, templo1, index) ); // ldrh dest_reg, [templo1, #index] -} - -// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDR_IMM(dest_reg, templo1, index) ); // ldr dest_reg, [templo1, #index] -} - -// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_checkinstr(6); - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDR_IMM(templo2, templo1, index) ); // ldr templo2, [templo1, #index] - cache_addw( ADD_REG(reg, reg, templo2) ); // add reg, reg, templo2 -} - -#endif - -#ifdef DRC_USE_REGS_ADDR - -// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] -} - -// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - if (dword) { - cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] - } else { - cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] - } -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] -} - - -// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_checkinstr(6); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDR_IMM(templo1, templo2, index) ); // ldr templo1, [templo2, #index] - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 -} - - -// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) -static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] -} - -// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - if (dword) { - cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] - } else { - cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] - } -} - -// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR -static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STRB_IMM(src_reg, templo1, index) ); // strb src_reg, [templo1, #index] -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb-niw.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb-niw.h deleted file mode 100644 index e4890c1b8..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb-niw.h +++ /dev/null @@ -1,1538 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */ - - -// temporary "lo" registers -#define templo1 HOST_v3 -#define templo2 HOST_v4 -#define templo3 HOST_v2 - -// register that holds function return values -#define FC_RETOP HOST_a1 - -// register used for address calculations, -#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG - -// register that holds the first parameter -#define FC_OP1 HOST_a1 - -// register that holds the second parameter -#define FC_OP2 HOST_a2 - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_a4 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_a1 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_a2 - -// temporary register for LEA -#define TEMP_REG_DRC HOST_a4 - -// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code -#define FC_REGS_ADDR HOST_v7 - -// used to hold the address of "Segs" - preferably filled in function gen_run_code -#define FC_SEGS_ADDR HOST_v8 - -// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code -#define readdata_addr HOST_v5 - - -// instruction encodings - -// move -// mov dst, #imm @ 0 <= imm <= 255 -#define MOV_IMM(dst, imm) (0x2000 + ((dst) << 8) + (imm) ) -// mov dst, src -#define MOV_REG(dst, src) ADD_IMM3(dst, src, 0) -// mov dst, src -#define MOV_LO_HI(dst, src) (0x4640 + (dst) + (((src) - HOST_r8) << 3) ) -// mov dst, src -#define MOV_HI_LO(dst, src) (0x4680 + ((dst) - HOST_r8) + ((src) << 3) ) - -// arithmetic -// add dst, src, #imm @ 0 <= imm <= 7 -#define ADD_IMM3(dst, src, imm) (0x1c00 + (dst) + ((src) << 3) + ((imm) << 6) ) -// add dst, #imm @ 0 <= imm <= 255 -#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) -// add dst, src1, src2 -#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 -#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) -// sub dst, src1, src2 -#define SUB_REG(dst, src1, src2) (0x1a00 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// sub dst, src, #imm @ 0 <= imm <= 7 -#define SUB_IMM3(dst, src, imm) (0x1e00 + (dst) + ((src) << 3) + ((imm) << 6) ) -// sub dst, #imm @ 0 <= imm <= 255 -#define SUB_IMM8(dst, imm) (0x3800 + ((dst) << 8) + (imm) ) -// neg dst, src -#define NEG(dst, src) (0x4240 + (dst) + ((src) << 3) ) -// cmp dst, #imm @ 0 <= imm <= 255 -#define CMP_IMM(dst, imm) (0x2800 + ((dst) << 8) + (imm) ) -// nop -#define NOP (0x46c0) - -// logical -// and dst, src -#define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) -// bic dst, src -#define BIC(dst, src) (0x4380 + (dst) + ((src) << 3) ) -// eor dst, src -#define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) -// orr dst, src -#define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) -// mvn dst, src -#define MVN(dst, src) (0x43c0 + (dst) + ((src) << 3) ) - -// shift/rotate -// lsl dst, src, #imm -#define LSL_IMM(dst, src, imm) (0x0000 + (dst) + ((src) << 3) + ((imm) << 6) ) -// lsl dst, reg -#define LSL_REG(dst, reg) (0x4080 + (dst) + ((reg) << 3) ) -// lsr dst, src, #imm -#define LSR_IMM(dst, src, imm) (0x0800 + (dst) + ((src) << 3) + ((imm) << 6) ) -// lsr dst, reg -#define LSR_REG(dst, reg) (0x40c0 + (dst) + ((reg) << 3) ) -// asr dst, src, #imm -#define ASR_IMM(dst, src, imm) (0x1000 + (dst) + ((src) << 3) + ((imm) << 6) ) -// asr dst, reg -#define ASR_REG(dst, reg) (0x4100 + (dst) + ((reg) << 3) ) -// ror dst, reg -#define ROR_REG(dst, reg) (0x41c0 + (dst) + ((reg) << 3) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 -#define LDR_IMM(reg, addr, imm) (0x6800 + (reg) + ((addr) << 3) + ((imm) << 4) ) -// ldrh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 -#define LDRH_IMM(reg, addr, imm) (0x8800 + (reg) + ((addr) << 3) + ((imm) << 5) ) -// ldrb reg, [addr, #imm] @ 0 <= imm < 32 -#define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) -// ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 -#define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) -// ldr reg, [addr1, addr2] -#define LDR_REG(reg, addr1, addr2) (0x5800 + (reg) + ((addr1) << 3) + ((addr2) << 6) ) - -// store -// str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 -#define STR_IMM(reg, addr, imm) (0x6000 + (reg) + ((addr) << 3) + ((imm) << 4) ) -// strh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 -#define STRH_IMM(reg, addr, imm) (0x8000 + (reg) + ((addr) << 3) + ((imm) << 5) ) -// strb reg, [addr, #imm] @ 0 <= imm < 32 -#define STRB_IMM(reg, addr, imm) (0x7000 + (reg) + ((addr) << 3) + ((imm) << 6) ) - -// branch -// beq pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BEQ_FWD(imm) (0xd000 + ((imm) >> 1) ) -// bne pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BNE_FWD(imm) (0xd100 + ((imm) >> 1) ) -// bgt pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BGT_FWD(imm) (0xdc00 + ((imm) >> 1) ) -// b pc+imm @ 0 <= imm < 2048 & imm mod 2 = 0 -#define B_FWD(imm) (0xe000 + ((imm) >> 1) ) -// bx reg -#define BX(reg) (0x4700 + ((reg) << 3) ) - - -// arm instructions - -// arithmetic -// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ARM_ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 4096 -#define ARM_LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// store -// str reg, [addr, #-(imm)]! @ 0 <= imm < 4096 -#define ARM_STR_IMM_M_W(reg, addr, imm) (0xe5200000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// branch -// bx reg -#define ARM_BX(reg) (0xe12fff10 + (reg) ) - - -// data pool defines -#define CACHE_DATA_JUMP (2) -#define CACHE_DATA_ALIGN (32) -#define CACHE_DATA_MIN (32) -#define CACHE_DATA_MAX (288) - -// data pool variables -static Bit8u * cache_datapos = NULL; // position of data pool in the cache block -static Bit32u cache_datasize = 0; // total size of data pool -static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool - - -// forwarded function -static void INLINE gen_create_branch_short(void * func); - -// function to check distance to data pool -// if too close, then generate jump after data pool -static void cache_checkinstr(Bit32u size) { - if (cache_datasize == 0) { - if (cache_datapos != NULL) { - if (cache.pos + size + CACHE_DATA_JUMP >= cache_datapos) { - cache_datapos = NULL; - } - } - return; - } - - if (cache.pos + size + CACHE_DATA_JUMP <= cache_datapos) return; - - { - register Bit8u * newcachepos; - - newcachepos = cache_datapos + cache_datasize; - gen_create_branch_short(newcachepos); - cache.pos = newcachepos; - } - - if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && - cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) - { - cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); - } else { - register Bit32u cachemodsize; - - cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); - - if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || - cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) - { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); - } else { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); - } - } - - cache_datasize = 0; - cache_dataindex = 0; -} - -// function to reserve item in data pool -// returns address of item -static Bit8u * cache_reservedata(void) { - // if data pool not yet initialized, then initialize data pool - if (GCC_UNLIKELY(cache_datapos == NULL)) { - if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN < cache.block.active->cache.start + CACHE_DATA_MAX) { - cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); - } - } - - // if data pool not yet used, then set data pool - if (cache_datasize == 0) { - // set data pool address is too close (or behind) cache.pos then set new data pool size - if (cache.pos + CACHE_DATA_MIN + CACHE_DATA_JUMP /*+ CACHE_DATA_ALIGN*/ > cache_datapos) { - if (cache.pos + CACHE_DATA_MAX + CACHE_DATA_ALIGN >= cache.block.active->cache.start + cache.block.active->cache.size && - cache.pos + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) < cache.block.active->cache.start + cache.block.active->cache.size) - { - cache_datapos = (Bit8u *) (((Bitu)cache.block.active->cache.start + cache.block.active->cache.size - CACHE_DATA_ALIGN) & ~(CACHE_DATA_ALIGN - 1)); - } else { - register Bit32u cachemodsize; - - cachemodsize = (cache.pos - cache.block.active->cache.start) & (CACHE_MAXSIZE - 1); - - if (cachemodsize + CACHE_DATA_MAX + CACHE_DATA_ALIGN <= CACHE_MAXSIZE || - cachemodsize + CACHE_DATA_MIN + CACHE_DATA_ALIGN + (CACHE_DATA_ALIGN - CACHE_ALIGN) > CACHE_MAXSIZE) - { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + CACHE_DATA_MAX) & ~(CACHE_DATA_ALIGN - 1)); - } else { - cache_datapos = (Bit8u *) (((Bitu)cache.pos + (CACHE_MAXSIZE - CACHE_DATA_ALIGN) - cachemodsize) & ~(CACHE_DATA_ALIGN - 1)); - } - } - } - // set initial data pool size - cache_datasize = CACHE_DATA_ALIGN; - } - - // if data pool is full, then enlarge data pool - if (cache_dataindex == cache_datasize) { - cache_datasize += CACHE_DATA_ALIGN; - } - - cache_dataindex += 4; - return (cache_datapos + (cache_dataindex - 4)); -} - -static void cache_block_before_close(void) { - // if data pool in use, then resize cache block to include the data pool - if (cache_datasize != 0) - { - cache.pos = cache_datapos + cache_dataindex; - } - - // clear the values before next use - cache_datapos = NULL; - cache_datasize = 0; - cache_dataindex = 0; -} - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - if(reg_src == reg_dst) return; - cache_checkinstr(2); - cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src -} - -// helper function -static bool val_single_shift(Bit32u value, Bit32u *val_shift) { - Bit32u shift; - - if (GCC_UNLIKELY(value == 0)) { - *val_shift = 0; - return true; - } - - shift = 0; - while ((value & 1) == 0) { - value>>=1; - shift+=1; - } - - if ((value >> 8) != 0) return false; - - *val_shift = shift; - return true; -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - Bit32u scale; - - if (imm < 256) { - cache_checkinstr(2); - cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) - } else if ((~imm) < 256) { - cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, ~imm) ); // mov dest_reg, #(~imm) - cache_addw( MVN(dest_reg, dest_reg) ); // mvn dest_reg, dest_reg - } else if (val_single_shift(imm, &scale)) { - cache_checkinstr(4); - cache_addw( MOV_IMM(dest_reg, imm >> scale) ); // mov dest_reg, #(imm >> scale) - cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #scale - } else { - Bit32u diff; - - cache_checkinstr(4); - - diff = imm - ((Bit32u)cache.pos+4); - - if ((diff < 1024) && ((imm & 0x03) == 0)) { - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( ADD_LO_PC_IMM(dest_reg, diff >> 2) ); // add dest_reg, pc, #(diff >> 2) - } else { - cache_addw( NOP ); // nop - cache_addw( ADD_LO_PC_IMM(dest_reg, (diff - 2) >> 2) ); // add dest_reg, pc, #((diff - 2) >> 2) - } - } else { - Bit8u *datapos; - - datapos = cache_reservedata(); - *(Bit32u*)datapos=imm; - - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 4)) ); // ldr dest_reg, [pc, datapos] - } else { - cache_addw( LDR_PC_IMM(dest_reg, datapos - (cache.pos + 2)) ); // ldr dest_reg, [pc, datapos] - } - } - } -} - -// helper function -static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDR_IMM(dest_reg, templo2, data - addr_data) ); // ldr dest_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 2: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDRH_IMM(dest_reg, templo2, data - addr_data) ); // ldrh dest_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 32)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDRB_IMM(dest_reg, templo2, data - addr_data) ); // ldrb dest_reg, [templo2, #(data - addr_data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_to_reg -static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { - // alignment.... - if (dword) { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)data & 3) { - if ( ((Bit32u)data & 3) == 2 ) { - cache_checkinstr(8); - cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - cache_addw( LDRH_IMM(templo1, data_reg, 2) ); // ldrh templo1, [data_reg, #2] - cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else { - cache_checkinstr(16); - cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addw( ADD_IMM3(templo1, data_reg, 1) ); // add templo1, data_reg, #1 - cache_addw( LDRH_IMM(templo1, templo1, 0) ); // ldrh templo1, [templo1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - cache_addw( LDRB_IMM(templo1, data_reg, 3) ); // ldrb templo1, [data_reg, #3] - cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } - } else -#endif - { - cache_checkinstr(2); - cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] - } - } else { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)data & 1) { - cache_checkinstr(8); - cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else -#endif - { - cache_checkinstr(2); - cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - } - } -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); - } -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); -} - -// helper function -static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STR_IMM(src_reg, templo2, data - addr_data) ); // str src_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 2: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STRH_IMM(src_reg, templo2, data - addr_data) ); // strh src_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 32)) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STRB_IMM(src_reg, templo2, data - addr_data) ); // strb src_reg, [templo2, #(data - addr_data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_from_reg -static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { - // alignment.... - if (dword) { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)dest & 3) { - if ( ((Bit32u)dest & 3) == 2 ) { - cache_checkinstr(8); - cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 - cache_addw( STRH_IMM(templo1, data_reg, 2) ); // strh templo1, [data_reg, #2] - } else { - cache_checkinstr(20); - cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 - cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 - cache_addw( STRB_IMM(templo1, data_reg, 2) ); // strb templo1, [data_reg, #2] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 - cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] - } - } else -#endif - { - cache_checkinstr(2); - cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] - } - } else { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)dest & 1) { - cache_checkinstr(8); - cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 - cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - } else -#endif - { - cache_checkinstr(2); - cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - } - } -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); - cache_checkinstr(2); - cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_mov_byte_to_reg_low(dest_reg, data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_checkinstr(2); - cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(dest_reg, imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); - cache_checkinstr(2); - cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] - } -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - cache_checkinstr(4); - cache_addw( LSL_IMM(reg, reg, 24) ); // lsl reg, reg, #24 - - if (sign) { - cache_addw( ASR_IMM(reg, reg, 24) ); // asr reg, reg, #24 - } else { - cache_addw( LSR_IMM(reg, reg, 24) ); // lsr reg, reg, #24 - } -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - cache_checkinstr(4); - cache_addw( LSL_IMM(reg, reg, 16) ); // lsl reg, reg, #16 - - if (sign) { - cache_addw( ASR_IMM(reg, reg, 16) ); // asr reg, reg, #16 - } else { - cache_addw( LSR_IMM(reg, reg, 16) ); // lsr reg, reg, #16 - } -} - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_mov_word_to_reg(templo3, op, 1); - cache_checkinstr(2); - cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3 -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - if(!imm) return; - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if (imm <= 255) { - cache_checkinstr(2); - cache_addw( ADD_IMM8(reg, imm) ); // add reg, #imm - } else if (imm2 <= 255) { - cache_checkinstr(2); - cache_addw( SUB_IMM8(reg, imm2) ); // sub reg, #(-imm) - } else { - if (val_single_shift(imm2, &scale)) { - cache_checkinstr((scale)?6:4); - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( SUB_REG(reg, reg, templo1) ); // sub reg, reg, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 - } - } -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - imm2 = ~imm; - if(!imm2) return; - - if (!imm) { - cache_checkinstr(2); - cache_addw( MOV_IMM(reg, 0) ); // mov reg, #0 - } else { - if (val_single_shift(imm2, &scale)) { - cache_checkinstr((scale)?6:4); - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( BIC(reg, templo1) ); // bic reg, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( AND(reg, templo1) ); // and reg, templo1 - } - } -} - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_mov_dword_to_reg_imm(templo3, imm); - gen_mov_word_from_reg(templo3, dest, 1); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - } - gen_add_imm(templo3, imm); - if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); - } -} - -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - gen_add_direct_word(dest, (Bit32s)imm, 1); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - Bit32u imm2, scale; - - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - } - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if (imm <= 255) { - cache_checkinstr(2); - cache_addw( SUB_IMM8(templo3, imm) ); // sub templo3, #imm - } else if (imm2 <= 255) { - cache_checkinstr(2); - cache_addw( ADD_IMM8(templo3, imm2) ); // add templo3, #(-imm) - } else { - if (val_single_shift(imm2, &scale)) { - cache_checkinstr((scale)?6:4); - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_checkinstr(2); - cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 - } - } - - if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); - } -} - -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - gen_sub_direct_word(dest, (Bit32s)imm, 1); -} - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - if (scale) { - cache_checkinstr(4); - cache_addw( LSL_IMM(templo1, scale_reg, scale) ); // lsl templo1, scale_reg, #(scale) - cache_addw( ADD_REG(dest_reg, dest_reg, templo1) ); // add dest_reg, dest_reg, templo1 - } else { - cache_checkinstr(2); - cache_addw( ADD_REG(dest_reg, dest_reg, scale_reg) ); // add dest_reg, dest_reg, scale_reg - } - gen_add_imm(dest_reg, imm); -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - if (scale) { - cache_checkinstr(2); - cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #(scale) - } - gen_add_imm(dest_reg, imm); -} - -// helper function for gen_call_function_raw and gen_call_function_setup -static void gen_call_function_helper(void * func) { - Bit8u *datapos; - - datapos = cache_reservedata(); - *(Bit32u*)datapos=(Bit32u)func; - - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] - cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4) - cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 - cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state - } else { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] - cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4) - cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 - cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state - cache_addw( NOP ); // nop - } - // after_call: - - // switch from arm to thumb state - cache_addd(0xe2800000 + (templo1 << 12) + (HOST_pc << 16) + (1)); // add templo1, pc, #1 - cache_addd(0xe12fff10 + (templo1)); // bx templo1 - - // thumb state from now on -} - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { - cache_checkinstr(18); - gen_call_function_helper(func); -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - cache_checkinstr(18); - Bit32u proc_addr = (Bit32u)cache.pos; - gen_call_function_helper(func); - return proc_addr; - // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) - // then length of generated code is 16 bytes - // otherwise length of generated code is 18 bytes -} - -#if (1) -// max of 4 parameters in a1-a4 - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - gen_mov_dword_to_reg_imm(param, imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - gen_mov_dword_to_reg_imm(param, addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - gen_mov_regs(param, reg); -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - gen_mov_word_to_reg(param, (void *)mem, 1); -} -#else - other arm abis -#endif - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - gen_mov_word_to_reg(templo3, ptr, 1); - -#if !defined(C_UNALIGNED_MEMORY) -// (*ptr) should be word aligned - if ((imm & 0x03) == 0) { -#endif - if ((imm >= 0) && (imm < 128) && ((imm & 3) == 0)) { - cache_checkinstr(6); - cache_addw( LDR_IMM(templo2, templo3, imm) ); // ldr templo2, [templo3, #imm] - } else { - gen_mov_dword_to_reg_imm(templo2, imm); - cache_checkinstr(6); - cache_addw( LDR_REG(templo2, templo3, templo2) ); // ldr templo2, [templo3, templo2] - } -#if !defined(C_UNALIGNED_MEMORY) - } else { - gen_add_imm(templo3, imm); - - cache_checkinstr(24); - cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] - cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2] - cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3] - cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - } -#endif - - // increase jmp address to keep thumb state - cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - - cache_addw( BX(templo2) ); // bx templo2 -} - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { - cache_checkinstr(4); - if (dword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 - } - cache_addw( BEQ_FWD(0) ); // beq j - return ((Bit32u)cache.pos-2); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - cache_checkinstr(4); - if (dword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 - } - cache_addw( BNE_FWD(0) ); // bne j - return ((Bit32u)cache.pos-2); -} - -// calculate relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-(data+4); - if (len<0) len=-len; - if (len>252) LOG_MSG("Big jump %d",len); -#endif - *(Bit8u*)data=(Bit8u)( ((Bit32u)cache.pos-(data+4)) >> 1 ); -} - - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - Bit8u *datapos; - - cache_checkinstr(8); - datapos = cache_reservedata(); - - if (isdword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo2, reg, 24) ); // lsl templo2, reg, #24 - } - cache_addw( BEQ_FWD(2) ); // beq nobranch (pc+2) - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] - } else { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] - } - cache_addw( BX(templo1) ); // bx templo1 - // nobranch: - return ((Bit32u)datapos); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - Bit8u *datapos; - - cache_checkinstr(8); - datapos = cache_reservedata(); - - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - cache_addw( BGT_FWD(2) ); // bgt nobranch (pc+2) - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos] - } else { - cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos] - } - cache_addw( BX(templo1) ); // bx templo1 - // nobranch: - return ((Bit32u)datapos); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - // this is an absolute branch - *(Bit32u*)data=((Bit32u)cache.pos) + 1; // add 1 to keep processor in thumb state -} - -static void gen_run_code(void) { - Bit8u *pos1, *pos2, *pos3; - -#if (__ARM_EABI__) - // 8-byte stack alignment - cache_addd(0xe92d4ff0); // stmfd sp!, {v1-v8,lr} -#else - cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} -#endif - - cache_addd( ARM_ADD_IMM(HOST_r0, HOST_r0, 1, 0) ); // add r0, r0, #1 - - pos1 = cache.pos; - cache_addd( 0 ); - pos2 = cache.pos; - cache_addd( 0 ); - pos3 = cache.pos; - cache_addd( 0 ); - - cache_addd( ARM_ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd( ARM_STR_IMM_M_W(HOST_lr, HOST_sp, 4) ); // str lr, [sp, #-4]! - cache_addd( ARM_BX(HOST_r0) ); // bx r0 - -#if (__ARM_EABI__) - cache_addd(0xe8bd4ff0); // ldmfd sp!, {v1-v8,lr} -#else - cache_addd(0xe8bd4df0); // ldmfd sp!, {v1-v5,v7,v8,lr} -#endif - cache_addd( ARM_BX(HOST_lr) ); // bx lr - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } - - *(Bit32u*)pos1 = ARM_LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] - cache_addd((Bit32u)&Segs); // address of "Segs" - - *(Bit32u*)pos2 = ARM_LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" - - *(Bit32u*)pos3 = ARM_LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] - cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } -} - -// return from a function -static void gen_return_function(void) { - cache_checkinstr(4); - cache_addw(0xbc08); // pop {r3} - cache_addw( BX(HOST_r3) ); // bx r3 -} - - -// short unconditional jump (over data pool) -// must emit at most CACHE_DATA_JUMP bytes -static void INLINE gen_create_branch_short(void * func) { - cache_addw( B_FWD((Bit32u)func - ((Bit32u)cache.pos + 4)) ); // b func -} - - -#ifdef DRC_FLAGS_INVALIDATION - -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { - if ((*(Bit16u*)pos & 0xf000) == 0xe000) { - if ((*(Bit16u*)pos & 0x0fff) >= ((CACHE_DATA_ALIGN / 2) - 1) && - (*(Bit16u*)pos & 0x0fff) < 0x0800) - { - pos = (Bit8u *) ( ( ( (Bit32u)(*(Bit16u*)pos & 0x0fff) ) << 1 ) + ((Bit32u)pos + 4) ); - } - } - -#ifdef DRC_FLAGS_INVALIDATION_DCODE - if (((Bit32u)pos & 0x03) == 0) - { - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit16u*)pos=B_FWD(12); // b after_call (pc+12) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_SHRb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) - break; - case t_SHRw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) - break; - case t_SHRd: - *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_SARb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) - break; - case t_SARw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) - break; - case t_SARd: - *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_RORb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+14)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_RORw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+8)=B_FWD(4); // b after_call (pc+4) - break; - case t_RORd: - *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - case t_ROLb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+14)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_ROLw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+14)=NOP; // nop - break; - case t_ROLd: - *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+6)=B_FWD(6); // b after_call (pc+6) - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 - *(Bit16u*)(pos+2)=B_FWD(10); // b after_call (pc+10) - break; - default: - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func - break; - } - } - else - { - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit16u*)pos=B_FWD(14); // b after_call (pc+14) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_SHRb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) - break; - case t_SHRw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) - break; - case t_SHRd: - *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_SARb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) - break; - case t_SARw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) - break; - case t_SARd: - *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_RORb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=NOP; // nop - *(Bit16u*)(pos+8)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_RORw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+8)=B_FWD(6); // b after_call (pc+6) - break; - case t_RORd: - *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - case t_ROLb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+12)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_ROLw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=NOP; // nop - break; - case t_ROLd: - *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+6)=B_FWD(8); // b after_call (pc+8) - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 - *(Bit16u*)(pos+2)=B_FWD(12); // b after_call (pc+12) - break; - default: - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func - break; - } - - } -#else - if (((Bit32u)pos & 0x03) == 0) - { - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 4) ) = (Bit32u)fct_ptr; // simple_func - } - else - { - *(Bit32u*)( ( ((Bit32u) (*pos)) << 2 ) + ((Bit32u)pos + 2) ) = (Bit32u)fct_ptr; // simple_func - } -#endif -} -#endif - -#ifdef DRC_USE_SEGS_ADDR - -// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDRH_IMM(dest_reg, templo1, index) ); // ldrh dest_reg, [templo1, #index] -} - -// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDR_IMM(dest_reg, templo1, index) ); // ldr dest_reg, [templo1, #index] -} - -// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_checkinstr(6); - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDR_IMM(templo2, templo1, index) ); // ldr templo2, [templo1, #index] - cache_addw( ADD_REG(reg, reg, templo2) ); // add reg, reg, templo2 -} - -#endif - -#ifdef DRC_USE_REGS_ADDR - -// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] -} - -// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - if (dword) { - cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] - } else { - cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] - } -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] -} - - -// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_checkinstr(6); - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDR_IMM(templo1, templo2, index) ); // ldr templo1, [templo2, #index] - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 -} - - -// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) -static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] -} - -// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - if (dword) { - cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] - } else { - cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] - } -} - -// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR -static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_checkinstr(4); - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STRB_IMM(src_reg, templo1, index) ); // strb src_reg, [templo1, #index] -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb.h deleted file mode 100644 index 126cdd116..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le-thumb.h +++ /dev/null @@ -1,1335 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* ARMv4 (little endian) backend by M-HT (thumb version) */ - - -// temporary "lo" registers -#define templo1 HOST_v3 -#define templo2 HOST_v4 -#define templo3 HOST_v2 - -// register that holds function return values -#define FC_RETOP HOST_a1 - -// register used for address calculations, -#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG - -// register that holds the first parameter -#define FC_OP1 HOST_a1 - -// register that holds the second parameter -#define FC_OP2 HOST_a2 - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_a4 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_a1 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_a2 - -// temporary register for LEA -#define TEMP_REG_DRC HOST_a4 - -// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code -#define FC_REGS_ADDR HOST_v7 - -// used to hold the address of "Segs" - preferably filled in function gen_run_code -#define FC_SEGS_ADDR HOST_v8 - -// used to hold the address of "core_dynrec.readdata" - filled in function gen_run_code -#define readdata_addr HOST_v5 - - -// instruction encodings - -// move -// mov dst, #imm @ 0 <= imm <= 255 -#define MOV_IMM(dst, imm) (0x2000 + ((dst) << 8) + (imm) ) -// mov dst, src -#define MOV_REG(dst, src) ADD_IMM3(dst, src, 0) -// mov dst, src -#define MOV_LO_HI(dst, src) (0x4640 + (dst) + (((src) - HOST_r8) << 3) ) -// mov dst, src -#define MOV_HI_LO(dst, src) (0x4680 + ((dst) - HOST_r8) + ((src) << 3) ) - -// arithmetic -// add dst, src, #imm @ 0 <= imm <= 7 -#define ADD_IMM3(dst, src, imm) (0x1c00 + (dst) + ((src) << 3) + ((imm) << 6) ) -// add dst, #imm @ 0 <= imm <= 255 -#define ADD_IMM8(dst, imm) (0x3000 + ((dst) << 8) + (imm) ) -// add dst, src1, src2 -#define ADD_REG(dst, src1, src2) (0x1800 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// add dst, pc, #imm @ 0 <= imm < 1024 & imm mod 4 = 0 -#define ADD_LO_PC_IMM(dst, imm) (0xa000 + ((dst) << 8) + ((imm) >> 2) ) -// sub dst, src1, src2 -#define SUB_REG(dst, src1, src2) (0x1a00 + (dst) + ((src1) << 3) + ((src2) << 6) ) -// sub dst, src, #imm @ 0 <= imm <= 7 -#define SUB_IMM3(dst, src, imm) (0x1e00 + (dst) + ((src) << 3) + ((imm) << 6) ) -// sub dst, #imm @ 0 <= imm <= 255 -#define SUB_IMM8(dst, imm) (0x3800 + ((dst) << 8) + (imm) ) -// neg dst, src -#define NEG(dst, src) (0x4240 + (dst) + ((src) << 3) ) -// cmp dst, #imm @ 0 <= imm <= 255 -#define CMP_IMM(dst, imm) (0x2800 + ((dst) << 8) + (imm) ) -// nop -#define NOP (0x46c0) - -// logical -// and dst, src -#define AND(dst, src) (0x4000 + (dst) + ((src) << 3) ) -// bic dst, src -#define BIC(dst, src) (0x4380 + (dst) + ((src) << 3) ) -// eor dst, src -#define EOR(dst, src) (0x4040 + (dst) + ((src) << 3) ) -// orr dst, src -#define ORR(dst, src) (0x4300 + (dst) + ((src) << 3) ) -// mvn dst, src -#define MVN(dst, src) (0x43c0 + (dst) + ((src) << 3) ) - -// shift/rotate -// lsl dst, src, #imm -#define LSL_IMM(dst, src, imm) (0x0000 + (dst) + ((src) << 3) + ((imm) << 6) ) -// lsl dst, reg -#define LSL_REG(dst, reg) (0x4080 + (dst) + ((reg) << 3) ) -// lsr dst, src, #imm -#define LSR_IMM(dst, src, imm) (0x0800 + (dst) + ((src) << 3) + ((imm) << 6) ) -// lsr dst, reg -#define LSR_REG(dst, reg) (0x40c0 + (dst) + ((reg) << 3) ) -// asr dst, src, #imm -#define ASR_IMM(dst, src, imm) (0x1000 + (dst) + ((src) << 3) + ((imm) << 6) ) -// asr dst, reg -#define ASR_REG(dst, reg) (0x4100 + (dst) + ((reg) << 3) ) -// ror dst, reg -#define ROR_REG(dst, reg) (0x41c0 + (dst) + ((reg) << 3) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 -#define LDR_IMM(reg, addr, imm) (0x6800 + (reg) + ((addr) << 3) + ((imm) << 4) ) -// ldrh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 -#define LDRH_IMM(reg, addr, imm) (0x8800 + (reg) + ((addr) << 3) + ((imm) << 5) ) -// ldrb reg, [addr, #imm] @ 0 <= imm < 32 -#define LDRB_IMM(reg, addr, imm) (0x7800 + (reg) + ((addr) << 3) + ((imm) << 6) ) -// ldr reg, [pc, #imm] @ 0 <= imm < 1024 & imm mod 4 = 0 -#define LDR_PC_IMM(reg, imm) (0x4800 + ((reg) << 8) + ((imm) >> 2) ) -// ldr reg, [addr1, addr2] -#define LDR_REG(reg, addr1, addr2) (0x5800 + (reg) + ((addr1) << 3) + ((addr2) << 6) ) - -// store -// str reg, [addr, #imm] @ 0 <= imm < 128 & imm mod 4 = 0 -#define STR_IMM(reg, addr, imm) (0x6000 + (reg) + ((addr) << 3) + ((imm) << 4) ) -// strh reg, [addr, #imm] @ 0 <= imm < 64 & imm mod 2 = 0 -#define STRH_IMM(reg, addr, imm) (0x8000 + (reg) + ((addr) << 3) + ((imm) << 5) ) -// strb reg, [addr, #imm] @ 0 <= imm < 32 -#define STRB_IMM(reg, addr, imm) (0x7000 + (reg) + ((addr) << 3) + ((imm) << 6) ) - -// branch -// beq pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BEQ_FWD(imm) (0xd000 + ((imm) >> 1) ) -// bne pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BNE_FWD(imm) (0xd100 + ((imm) >> 1) ) -// bgt pc+imm @ 0 <= imm < 256 & imm mod 2 = 0 -#define BGT_FWD(imm) (0xdc00 + ((imm) >> 1) ) -// b pc+imm @ 0 <= imm < 2048 & imm mod 2 = 0 -#define B_FWD(imm) (0xe000 + ((imm) >> 1) ) -// bx reg -#define BX(reg) (0x4700 + ((reg) << 3) ) - - -// arm instructions - -// arithmetic -// add dst, src, #(imm ror rimm) @ 0 <= imm <= 255 & rimm mod 2 = 0 -#define ARM_ADD_IMM(dst, src, imm, rimm) (0xe2800000 + ((dst) << 12) + ((src) << 16) + (imm) + ((rimm) << 7) ) - -// load -// ldr reg, [addr, #imm] @ 0 <= imm < 4096 -#define ARM_LDR_IMM(reg, addr, imm) (0xe5900000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// store -// str reg, [addr, #-(imm)]! @ 0 <= imm < 4096 -#define ARM_STR_IMM_M_W(reg, addr, imm) (0xe5200000 + ((reg) << 12) + ((addr) << 16) + (imm) ) - -// branch -// bx reg -#define ARM_BX(reg) (0xe12fff10 + (reg) ) - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - if(reg_src == reg_dst) return; - cache_addw( MOV_REG(reg_dst, reg_src) ); // mov reg_dst, reg_src -} - -// helper function -static bool val_single_shift(Bit32u value, Bit32u *val_shift) { - Bit32u shift; - - if (GCC_UNLIKELY(value == 0)) { - *val_shift = 0; - return true; - } - - shift = 0; - while ((value & 1) == 0) { - value>>=1; - shift+=1; - } - - if ((value >> 8) != 0) return false; - - *val_shift = shift; - return true; -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - Bit32u scale; - - if (imm < 256) { - cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #imm - } else if ((~imm) < 256) { - cache_addw( MOV_IMM(dest_reg, ~imm) ); // mov dest_reg, #(~imm) - cache_addw( MVN(dest_reg, dest_reg) ); // mvn dest_reg, dest_reg - } else if (val_single_shift(imm, &scale)) { - cache_addw( MOV_IMM(dest_reg, imm >> scale) ); // mov dest_reg, #(imm >> scale) - cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #scale - } else { - Bit32u diff; - - diff = imm - ((Bit32u)cache.pos+4); - - if ((diff < 1024) && ((imm & 0x03) == 0)) { - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( ADD_LO_PC_IMM(dest_reg, diff) ); // add dest_reg, pc, #(diff >> 2) - } else { - cache_addw( NOP ); // nop - cache_addw( ADD_LO_PC_IMM(dest_reg, diff - 2) ); // add dest_reg, pc, #((diff - 2) >> 2) - } - } else { - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(dest_reg, 0) ); // ldr dest_reg, [pc, #0] - cache_addw( B_FWD(2) ); // b next_code (pc+2) - cache_addd(imm); // .int imm - // next_code: - } else { - cache_addw( LDR_PC_IMM(dest_reg, 4) ); // ldr dest_reg, [pc, #4] - cache_addw( B_FWD(4) ); // b next_code (pc+4) - cache_addw( NOP ); // nop - cache_addd(imm); // .int imm - // next_code: - } - } - } -} - -// helper function -static bool gen_mov_memval_to_reg_helper(HostReg dest_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDR_IMM(dest_reg, templo2, data - addr_data) ); // ldr dest_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 2: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDRH_IMM(dest_reg, templo2, data - addr_data) ); // ldrh dest_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 32)) { - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( LDRB_IMM(dest_reg, templo2, data - addr_data) ); // ldrb dest_reg, [templo2, #(data - addr_data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_to_reg(HostReg dest_reg, void *data, Bitu size) { - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_to_reg_helper(dest_reg, (Bit32u)data, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_to_reg -static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) { - // alignment.... - if (dword) { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)data & 3) { - if ( ((Bit32u)data & 3) == 2 ) { - cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - cache_addw( LDRH_IMM(templo1, data_reg, 2) ); // ldrh templo1, [data_reg, #2] - cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else { - cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addw( ADD_IMM3(templo1, data_reg, 1) ); // add templo1, data_reg, #1 - cache_addw( LDRH_IMM(templo1, templo1, 0) ); // ldrh templo1, [templo1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - cache_addw( LDRB_IMM(templo1, data_reg, 3) ); // ldrb templo1, [data_reg, #3] - cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } - } else -#endif - { - cache_addw( LDR_IMM(dest_reg, data_reg, 0) ); // ldr dest_reg, [data_reg] - } - } else { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)data & 1) { - cache_addw( LDRB_IMM(dest_reg, data_reg, 0) ); // ldrb dest_reg, [data_reg] - cache_addw( LDRB_IMM(templo1, data_reg, 1) ); // ldrb templo1, [data_reg, #1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(dest_reg, templo1) ); // orr dest_reg, templo1 - } else -#endif - { - cache_addw( LDRH_IMM(dest_reg, data_reg, 0) ); // ldrh dest_reg, [data_reg] - } - } -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - if (!gen_mov_memval_to_reg(dest_reg, data, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)data); - gen_mov_word_to_reg_helper(dest_reg, data, dword, templo2); - } -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm); -} - -// helper function -static bool gen_mov_memval_from_reg_helper(HostReg src_reg, Bit32u data, Bitu size, HostReg addr_reg, Bit32u addr_data) { - switch (size) { - case 4: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 3) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 128) && (((data - addr_data) & 3) == 0)) { - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STR_IMM(src_reg, templo2, data - addr_data) ); // str src_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 2: -#if !defined(C_UNALIGNED_MEMORY) - if ((data & 1) == 0) -#endif - { - if ((data >= addr_data) && (data < addr_data + 64) && (((data - addr_data) & 1) == 0)) { - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STRH_IMM(src_reg, templo2, data - addr_data) ); // strh src_reg, [templo2, #(data - addr_data)] - return true; - } - } - break; - case 1: - if ((data >= addr_data) && (data < addr_data + 32)) { - cache_addw( MOV_LO_HI(templo2, addr_reg) ); // mov templo2, addr_reg - cache_addw( STRB_IMM(src_reg, templo2, data - addr_data) ); // strb src_reg, [templo2, #(data - addr_data)] - return true; - } - default: - break; - } - return false; -} - -// helper function -static bool gen_mov_memval_from_reg(HostReg src_reg, void *dest, Bitu size) { - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_REGS_ADDR, (Bit32u)&cpu_regs)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, readdata_addr, (Bit32u)&core_dynrec.readdata)) return true; - if (gen_mov_memval_from_reg_helper(src_reg, (Bit32u)dest, size, FC_SEGS_ADDR, (Bit32u)&Segs)) return true; - return false; -} - -// helper function for gen_mov_word_from_reg -static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) { - // alignment.... - if (dword) { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)dest & 3) { - if ( ((Bit32u)dest & 3) == 2 ) { - cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 - cache_addw( STRH_IMM(templo1, data_reg, 2) ); // strh templo1, [data_reg, #2] - } else { - cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 - cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 16) ); // lsr templo1, templo1, #16 - cache_addw( STRB_IMM(templo1, data_reg, 2) ); // strb templo1, [data_reg, #2] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 24) ); // lsr templo1, templo1, #24 - cache_addw( STRB_IMM(templo1, data_reg, 3) ); // strb templo1, [data_reg, #3] - } - } else -#endif - { - cache_addw( STR_IMM(src_reg, data_reg, 0) ); // str src_reg, [data_reg] - } - } else { -#if !defined(C_UNALIGNED_MEMORY) - if ((Bit32u)dest & 1) { - cache_addw( STRB_IMM(src_reg, data_reg, 0) ); // strb src_reg, [data_reg] - cache_addw( MOV_REG(templo1, src_reg) ); // mov templo1, src_reg - cache_addw( LSR_IMM(templo1, templo1, 8) ); // lsr templo1, templo1, #8 - cache_addw( STRB_IMM(templo1, data_reg, 1) ); // strb templo1, [data_reg, #1] - } else -#endif - { - cache_addw( STRH_IMM(src_reg, data_reg, 0) ); // strh src_reg, [data_reg] - } - } -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - if (!gen_mov_memval_from_reg(src_reg, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_from_reg_helper(src_reg, dest, dword, templo2); - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - if (!gen_mov_memval_to_reg(dest_reg, data, 1)) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)data); - cache_addw( LDRB_IMM(dest_reg, templo1, 0) ); // ldrb dest_reg, [templo1] - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_mov_byte_to_reg_low(dest_reg, data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addw( MOV_IMM(dest_reg, imm) ); // mov dest_reg, #(imm) -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(dest_reg, imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - if (!gen_mov_memval_from_reg(src_reg, dest, 1)) { - gen_mov_dword_to_reg_imm(templo1, (Bit32u)dest); - cache_addw( STRB_IMM(src_reg, templo1, 0) ); // strb src_reg, [templo1] - } -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - cache_addw( LSL_IMM(reg, reg, 24) ); // lsl reg, reg, #24 - - if (sign) { - cache_addw( ASR_IMM(reg, reg, 24) ); // asr reg, reg, #24 - } else { - cache_addw( LSR_IMM(reg, reg, 24) ); // lsr reg, reg, #24 - } -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - cache_addw( LSL_IMM(reg, reg, 16) ); // lsl reg, reg, #16 - - if (sign) { - cache_addw( ASR_IMM(reg, reg, 16) ); // asr reg, reg, #16 - } else { - cache_addw( LSR_IMM(reg, reg, 16) ); // lsr reg, reg, #16 - } -} - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_mov_word_to_reg(templo3, op, 1); - cache_addw( ADD_REG(reg, reg, templo3) ); // add reg, reg, templo3 -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - if(!imm) return; - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if (imm <= 255) { - cache_addw( ADD_IMM8(reg, imm) ); // add reg, #imm - } else if (imm2 <= 255) { - cache_addw( SUB_IMM8(reg, imm2) ); // sub reg, #(-imm) - } else { - if (val_single_shift(imm2, &scale)) { - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( SUB_REG(reg, reg, templo1) ); // sub reg, reg, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 - } - } -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - Bit32u imm2, scale; - - imm2 = ~imm; - if(!imm2) return; - - if (!imm) { - cache_addw( MOV_IMM(reg, 0) ); // mov reg, #0 - } else { - if (val_single_shift(imm2, &scale)) { - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( BIC(reg, templo1) ); // bic reg, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_addw( AND(reg, templo1) ); // and reg, templo1 - } - } -} - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_mov_dword_to_reg_imm(templo3, imm); - gen_mov_word_from_reg(templo3, dest, 1); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - } - gen_add_imm(templo3, imm); - if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); - } -} - -// add an 8bit constant value to a dword memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - gen_add_direct_word(dest, (Bit32s)imm, 1); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - Bit32u imm2, scale; - - if (!dword) imm &= 0xffff; - if(!imm) return; - - if (!gen_mov_memval_to_reg(templo3, dest, (dword)?4:2)) { - gen_mov_dword_to_reg_imm(templo2, (Bit32u)dest); - gen_mov_word_to_reg_helper(templo3, dest, dword, templo2); - } - - imm2 = (Bit32u) (-((Bit32s)imm)); - - if (imm <= 255) { - cache_addw( SUB_IMM8(templo3, imm) ); // sub templo3, #imm - } else if (imm2 <= 255) { - cache_addw( ADD_IMM8(templo3, imm2) ); // add templo3, #(-imm) - } else { - if (val_single_shift(imm2, &scale)) { - cache_addw( MOV_IMM(templo1, imm2 >> scale) ); // mov templo1, #(~imm >> scale) - if (scale) { - cache_addw( LSL_IMM(templo1, templo1, scale) ); // lsl templo1, templo1, #scale - } - cache_addw( ADD_REG(templo3, templo3, templo1) ); // add templo3, templo3, templo1 - } else { - gen_mov_dword_to_reg_imm(templo1, imm); - cache_addw( SUB_REG(templo3, templo3, templo1) ); // sub templo3, templo3, templo1 - } - } - - if (!gen_mov_memval_from_reg(templo3, dest, (dword)?4:2)) { - gen_mov_word_from_reg_helper(templo3, dest, dword, templo2); - } -} - -// subtract an 8bit constant value from a dword memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - gen_sub_direct_word(dest, (Bit32s)imm, 1); -} - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - if (scale) { - cache_addw( LSL_IMM(templo1, scale_reg, scale) ); // lsl templo1, scale_reg, #(scale) - cache_addw( ADD_REG(dest_reg, dest_reg, templo1) ); // add dest_reg, dest_reg, templo1 - } else { - cache_addw( ADD_REG(dest_reg, dest_reg, scale_reg) ); // add dest_reg, dest_reg, scale_reg - } - gen_add_imm(dest_reg, imm); -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - if (scale) { - cache_addw( LSL_IMM(dest_reg, dest_reg, scale) ); // lsl dest_reg, dest_reg, #(scale) - } - gen_add_imm(dest_reg, imm); -} - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( LDR_PC_IMM(templo1, 4) ); // ldr templo1, [pc, #4] - cache_addw( ADD_LO_PC_IMM(templo2, 8) ); // adr templo2, after_call (add templo2, pc, #8) - cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 - cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state - } else { - cache_addw( LDR_PC_IMM(templo1, 8) ); // ldr templo1, [pc, #8] - cache_addw( ADD_LO_PC_IMM(templo2, 8) ); // adr templo2, after_call (add templo2, pc, #8) - cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2 - cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state - cache_addw( NOP ); // nop - } - cache_addd((Bit32u)func); // .int func - // after_call: - - // switch from arm to thumb state - cache_addd(0xe2800000 + (templo1 << 12) + (HOST_pc << 16) + (1)); // add templo1, pc, #1 - cache_addd(0xe12fff10 + (templo1)); // bx templo1 - - // thumb state from now on -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - Bit32u proc_addr = (Bit32u)cache.pos; - gen_call_function_raw(func); - return proc_addr; - // if proc_addr is on word boundary ((proc_addr & 0x03) == 0) - // then length of generated code is 20 bytes - // otherwise length of generated code is 22 bytes -} - -#if (1) -// max of 4 parameters in a1-a4 - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - gen_mov_dword_to_reg_imm(param, imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - gen_mov_dword_to_reg_imm(param, addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - gen_mov_regs(param, reg); -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - gen_mov_word_to_reg(param, (void *)mem, 1); -} -#else - other arm abis -#endif - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - gen_mov_word_to_reg(templo3, ptr, 1); - -#if !defined(C_UNALIGNED_MEMORY) -// (*ptr) should be word aligned - if ((imm & 0x03) == 0) { -#endif - if ((imm >= 0) && (imm < 128) && ((imm & 3) == 0)) { - cache_addw( LDR_IMM(templo2, templo3, imm) ); // ldr templo2, [templo3, #imm] - } else { - gen_mov_dword_to_reg_imm(templo2, imm); - cache_addw( LDR_REG(templo2, templo3, templo2) ); // ldr templo2, [templo3, templo2] - } -#if !defined(C_UNALIGNED_MEMORY) - } else { - gen_add_imm(templo3, imm); - - cache_addw( LDRB_IMM(templo2, templo3, 0) ); // ldrb templo2, [templo3] - cache_addw( LDRB_IMM(templo1, templo3, 1) ); // ldrb templo1, [templo3, #1] - cache_addw( LSL_IMM(templo1, templo1, 8) ); // lsl templo1, templo1, #8 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templo3, 2) ); // ldrb templo1, [templo3, #2] - cache_addw( LSL_IMM(templo1, templo1, 16) ); // lsl templo1, templo1, #16 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - cache_addw( LDRB_IMM(templo1, templo3, 3) ); // ldrb templo1, [templo3, #3] - cache_addw( LSL_IMM(templo1, templo1, 24) ); // lsl templo1, templo1, #24 - cache_addw( ORR(templo2, templo1) ); // orr templo2, templo1 - } -#endif - - // increase jmp address to keep thumb state - cache_addw( ADD_IMM3(templo2, templo2, 1) ); // add templo2, templo2, #1 - - cache_addw( BX(templo2) ); // bx templo2 -} - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { - if (dword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 - } - cache_addw( BEQ_FWD(0) ); // beq j - return ((Bit32u)cache.pos-2); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - if (dword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo1, reg, 16) ); // lsl templo1, reg, #16 - } - cache_addw( BNE_FWD(0) ); // bne j - return ((Bit32u)cache.pos-2); -} - -// calculate relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-(data+4); - if (len<0) len=-len; - if (len>252) LOG_MSG("Big jump %d",len); -#endif - *(Bit8u*)data=(Bit8u)( ((Bit32u)cache.pos-(data+4)) >> 1 ); -} - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - if (isdword) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - } else { - cache_addw( LSL_IMM(templo2, reg, 24) ); // lsl templo2, reg, #24 - } - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( BEQ_FWD(8) ); // beq nobranch (pc+8) - cache_addw( LDR_PC_IMM(templo1, 4) ); // ldr templo1, [pc, #4] - cache_addw( BX(templo1) ); // bx templo1 - cache_addw( NOP ); // nop - } else { - cache_addw( BEQ_FWD(6) ); // beq nobranch (pc+6) - cache_addw( LDR_PC_IMM(templo1, 0) ); // ldr templo1, [pc, #0] - cache_addw( BX(templo1) ); // bx templo1 - } - cache_addd(0); // fill j - // nobranch: - return ((Bit32u)cache.pos-4); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addw( CMP_IMM(reg, 0) ); // cmp reg, #0 - if (((Bit32u)cache.pos & 0x03) == 0) { - cache_addw( BGT_FWD(8) ); // bgt nobranch (pc+8) - cache_addw( LDR_PC_IMM(templo1, 4) ); // ldr templo1, [pc, #4] - cache_addw( BX(templo1) ); // bx templo1 - cache_addw( NOP ); // nop - } else { - cache_addw( BGT_FWD(6) ); // bgt nobranch (pc+6) - cache_addw( LDR_PC_IMM(templo1, 0) ); // ldr templo1, [pc, #0] - cache_addw( BX(templo1) ); // bx templo1 - } - cache_addd(0); // fill j - // nobranch: - return ((Bit32u)cache.pos-4); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - // this is an absolute branch - *(Bit32u*)data=((Bit32u)cache.pos) + 1; // add 1 to keep processor in thumb state -} - -static void gen_run_code(void) { - Bit8u *pos1, *pos2, *pos3; - -#if (__ARM_EABI__) - // 8-byte stack alignment - cache_addd(0xe92d4ff0); // stmfd sp!, {v1-v8,lr} -#else - cache_addd(0xe92d4df0); // stmfd sp!, {v1-v5,v7,v8,lr} -#endif - - cache_addd( ARM_ADD_IMM(HOST_r0, HOST_r0, 1, 0) ); // add r0, r0, #1 - - pos1 = cache.pos; - cache_addd( 0 ); - pos2 = cache.pos; - cache_addd( 0 ); - pos3 = cache.pos; - cache_addd( 0 ); - - cache_addd( ARM_ADD_IMM(HOST_lr, HOST_pc, 4, 0) ); // add lr, pc, #4 - cache_addd( ARM_STR_IMM_M_W(HOST_lr, HOST_sp, 4) ); // str lr, [sp, #-4]! - cache_addd( ARM_BX(HOST_r0) ); // bx r0 - -#if (__ARM_EABI__) - cache_addd(0xe8bd4ff0); // ldmfd sp!, {v1-v8,lr} -#else - cache_addd(0xe8bd4df0); // ldmfd sp!, {v1-v5,v7,v8,lr} -#endif - cache_addd( ARM_BX(HOST_lr) ); // bx lr - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } - - *(Bit32u*)pos1 = ARM_LDR_IMM(FC_SEGS_ADDR, HOST_pc, cache.pos - (pos1 + 8)); // ldr FC_SEGS_ADDR, [pc, #(&Segs)] - cache_addd((Bit32u)&Segs); // address of "Segs" - - *(Bit32u*)pos2 = ARM_LDR_IMM(FC_REGS_ADDR, HOST_pc, cache.pos - (pos2 + 8)); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)] - cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" - - *(Bit32u*)pos3 = ARM_LDR_IMM(readdata_addr, HOST_pc, cache.pos - (pos3 + 8)); // ldr readdata_addr, [pc, #(&core_dynrec.readdata)] - cache_addd((Bit32u)&core_dynrec.readdata); // address of "core_dynrec.readdata" - - // align cache.pos to 32 bytes - if ((((Bitu)cache.pos) & 0x1f) != 0) { - cache.pos = cache.pos + (32 - (((Bitu)cache.pos) & 0x1f)); - } -} - -// return from a function -static void gen_return_function(void) { - cache_addw(0xbc08); // pop {r3} - cache_addw( BX(HOST_r3) ); // bx r3 -} - -#ifdef DRC_FLAGS_INVALIDATION - -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { -#ifdef DRC_FLAGS_INVALIDATION_DCODE - if (((Bit32u)pos & 0x03) == 0) - { - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit16u*)pos=B_FWD(16); // b after_call (pc+16) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_SHRb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) - break; - case t_SHRw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) - break; - case t_SHRd: - *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_SARb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) - break; - case t_SARw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) - break; - case t_SARd: - *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_RORb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) - break; - case t_RORw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+8)=B_FWD(8); // b after_call (pc+8) - break; - case t_RORd: - *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - case t_ROLb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+18)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_ROLw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+12)=B_FWD(4); // b after_call (pc+4) - break; - case t_ROLd: - *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+6)=B_FWD(10); // b after_call (pc+10) - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 - *(Bit16u*)(pos+2)=B_FWD(14); // b after_call (pc+14) - break; - default: - *(Bit32u*)(pos+8)=(Bit32u)fct_ptr; // simple_func - break; - } - } - else - { - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit16u*)pos=ADD_REG(HOST_a1, HOST_a1, HOST_a2); // add a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit16u*)pos=ORR(HOST_a1, HOST_a2); // orr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit16u*)pos=AND(HOST_a1, HOST_a2); // and a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit16u*)pos=SUB_REG(HOST_a1, HOST_a1, HOST_a2); // sub a1, a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit16u*)pos=EOR(HOST_a1, HOST_a2); // eor a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit16u*)pos=B_FWD(18); // b after_call (pc+18) - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit16u*)pos=ADD_IMM3(HOST_a1, HOST_a1, 1); // add a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit16u*)pos=SUB_IMM3(HOST_a1, HOST_a1, 1); // sub a1, a1, #1 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit16u*)pos=LSL_REG(HOST_a1, HOST_a2); // lsl a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_SHRb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 24); // lsr a1, a1, #24 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) - break; - case t_SHRw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(HOST_a1, HOST_a1, 16); // lsr a1, a1, #16 - *(Bit16u*)(pos+4)=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) - break; - case t_SHRd: - *(Bit16u*)pos=LSR_REG(HOST_a1, HOST_a2); // lsr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_SARb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 24); // asr a1, a1, #24 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) - break; - case t_SARw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=ASR_IMM(HOST_a1, HOST_a1, 16); // asr a1, a1, #16 - *(Bit16u*)(pos+4)=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) - break; - case t_SARd: - *(Bit16u*)pos=ASR_REG(HOST_a1, HOST_a2); // asr a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_RORb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) - break; - case t_RORw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+4)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+6)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+8)=B_FWD(10); // b after_call (pc+10) - break; - case t_RORd: - *(Bit16u*)pos=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - case t_ROLb: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 24); // lsl a1, a1, #24 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 8); // lsr templo1, a1, #8 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=NOP; // nop - *(Bit16u*)(pos+12)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+14)=NOP; // nop - *(Bit16u*)(pos+16)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+18)=NOP; // nop - *(Bit16u*)(pos+20)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - break; - case t_ROLw: - *(Bit16u*)pos=LSL_IMM(HOST_a1, HOST_a1, 16); // lsl a1, a1, #16 - *(Bit16u*)(pos+2)=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+4)=LSR_IMM(templo1, HOST_a1, 16); // lsr templo1, a1, #16 - *(Bit16u*)(pos+6)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+8)=ORR(HOST_a1, templo1); // orr a1, templo1 - *(Bit16u*)(pos+10)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+12)=B_FWD(6); // b after_call (pc+6) - break; - case t_ROLd: - *(Bit16u*)pos=NEG(HOST_a2, HOST_a2); // neg a2, a2 - *(Bit16u*)(pos+2)=ADD_IMM8(HOST_a2, 32); // add a2, #32 - *(Bit16u*)(pos+4)=ROR_REG(HOST_a1, HOST_a2); // ror a1, a2 - *(Bit16u*)(pos+6)=B_FWD(12); // b after_call (pc+12) - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit16u*)pos=NEG(HOST_a1, HOST_a1); // neg a1, a1 - *(Bit16u*)(pos+2)=B_FWD(16); // b after_call (pc+16) - break; - default: - *(Bit32u*)(pos+10)=(Bit32u)fct_ptr; // simple_func - break; - } - - } -#else - if (((Bit32u)pos & 0x03) == 0) - { - *(Bit32u*)(pos+8)=(Bit32u)fct_ptr; // simple_func - } - else - { - *(Bit32u*)(pos+10)=(Bit32u)fct_ptr; // simple_func - } -#endif -} -#endif - -static void cache_block_before_close(void) { - if ((((Bit32u)cache.pos) & 3) != 0) { - cache_addw( NOP ); // nop - } -} - -#ifdef DRC_USE_SEGS_ADDR - -// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDRH_IMM(dest_reg, templo1, index) ); // ldrh dest_reg, [templo1, #index] -} - -// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDR_IMM(dest_reg, templo1, index) ); // ldr dest_reg, [templo1, #index] -} - -// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { - cache_addw( MOV_LO_HI(templo1, FC_SEGS_ADDR) ); // mov templo1, FC_SEGS_ADDR - cache_addw( LDR_IMM(templo2, templo1, index) ); // ldr templo2, [templo1, #index] - cache_addw( ADD_REG(reg, reg, templo2) ); // add reg, reg, templo2 -} - -#endif - -#ifdef DRC_USE_REGS_ADDR - -// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] -} - -// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - if (dword) { - cache_addw( LDR_IMM(dest_reg, templo2, index) ); // ldr dest_reg, [templo2, #index] - } else { - cache_addw( LDRH_IMM(dest_reg, templo2, index) ); // ldrh dest_reg, [templo2, #index] - } -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDRB_IMM(dest_reg, templo2, index) ); // ldrb dest_reg, [templo2, #index] -} - - -// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { - cache_addw( MOV_LO_HI(templo2, FC_REGS_ADDR) ); // mov templo2, FC_REGS_ADDR - cache_addw( LDR_IMM(templo1, templo2, index) ); // ldr templo1, [templo2, #index] - cache_addw( ADD_REG(reg, reg, templo1) ); // add reg, reg, templo1 -} - - -// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) -static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] -} - -// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - if (dword) { - cache_addw( STR_IMM(src_reg, templo1, index) ); // str src_reg, [templo1, #index] - } else { - cache_addw( STRH_IMM(src_reg, templo1, index) ); // strh src_reg, [templo1, #index] - } -} - -// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR -static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { - cache_addw( MOV_LO_HI(templo1, FC_REGS_ADDR) ); // mov templo1, FC_REGS_ADDR - cache_addw( STRB_IMM(src_reg, templo1, index) ); // strb src_reg, [templo1, #index] -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le.h deleted file mode 100644 index 8a3b343b8..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_armv4le.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* ARMv4/ARMv7 (little endian) backend (switcher) by M-HT */ - -#include "risc_armv4le-common.h" - -// choose your destiny: -#if C_TARGETCPU == ARMV7LE - #include "risc_armv4le-o3.h" -#else - #if defined(__THUMB_INTERWORK__) - #include "risc_armv4le-thumb-iw.h" - #else - #include "risc_armv4le-o3.h" -// #include "risc_armv4le-thumb-niw.h" -// #include "risc_armv4le-thumb.h" - #endif -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_mipsel32.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_mipsel32.h deleted file mode 100644 index 0e7d47456..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_mipsel32.h +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -/* MIPS32 (little endian) backend by crazyc */ - - -// some configuring defines that specify the capabilities of this architecture -// or aspects of the recompiling - -// protect FC_ADDR over function calls if necessaray -// #define DRC_PROTECT_ADDR_REG - -// try to use non-flags generating functions if possible -#define DRC_FLAGS_INVALIDATION -// try to replace _simple functions by code -#define DRC_FLAGS_INVALIDATION_DCODE - -// type with the same size as a pointer -#define DRC_PTR_SIZE_IM Bit32u - -// calling convention modifier -#define DRC_CALL_CONV /* nothing */ -#define DRC_FC /* nothing */ - -// use FC_REGS_ADDR to hold the address of "cpu_regs" and to access it using FC_REGS_ADDR -//#define DRC_USE_REGS_ADDR -// use FC_SEGS_ADDR to hold the address of "Segs" and to access it using FC_SEGS_ADDR -//#define DRC_USE_SEGS_ADDR - -// register mapping -typedef Bit8u HostReg; - -#define HOST_v0 2 -#define HOST_v1 3 -#define HOST_a0 4 -#define HOST_a1 5 -#define HOST_t4 12 -#define HOST_t5 13 -#define HOST_t6 14 -#define HOST_t7 15 -#define HOST_s0 16 -#define HOST_t8 24 -#define HOST_t9 25 -#define temp1 HOST_v1 -#define temp2 HOST_t9 - -// register that holds function return values -#define FC_RETOP HOST_v0 - -// register used for address calculations, -#define FC_ADDR HOST_s0 // has to be saved across calls, see DRC_PROTECT_ADDR_REG - -// register that holds the first parameter -#define FC_OP1 HOST_a0 - -// register that holds the second parameter -#define FC_OP2 HOST_a1 - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_??? - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_t5 - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_t6 - -// temporary register for LEA -#define TEMP_REG_DRC HOST_t7 - -#ifdef DRC_USE_REGS_ADDR -// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code -#define FC_REGS_ADDR HOST_??? -#endif - -#ifdef DRC_USE_SEGS_ADDR -// used to hold the address of "Segs" - preferably filled in function gen_run_code -#define FC_SEGS_ADDR HOST_??? -#endif - -// save some state to improve code gen -static bool temp1_valid = false; -static Bit32u temp1_value; - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - if(reg_src == reg_dst) return; - cache_addw((reg_dst<<11)+0x21); // addu reg_dst, $0, reg_src - cache_addw(reg_src); -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - if(imm < 65536) { - cache_addw((Bit16u)imm); // ori dest_reg, $0, imm - cache_addw(0x3400+dest_reg); - } else if(((Bit32s)imm < 0) && ((Bit32s)imm >= -32768)) { - cache_addw((Bit16u)imm); // addiu dest_reg, $0, imm - cache_addw(0x2400+dest_reg); - } else if(!(imm & 0xffff)) { - cache_addw((Bit16u)(imm >> 16)); // lui dest_reg, %hi(imm) - cache_addw(0x3c00+dest_reg); - } else { - cache_addw((Bit16u)(imm >> 16)); // lui dest_reg, %hi(imm) - cache_addw(0x3c00+dest_reg); - cache_addw((Bit16u)imm); // ori dest_reg, dest_reg, %lo(imm) - cache_addw(0x3400+(dest_reg<<5)+dest_reg); - } -} - -// this is the only place temp1 should be modified -static void INLINE mov_imm_to_temp1(Bit32u imm) { - if (temp1_valid && (temp1_value == imm)) return; - gen_mov_dword_to_reg_imm(temp1, imm); - temp1_valid = true; - temp1_value = imm; -} - -static Bit16s gen_addr_temp1(Bit32u addr) { - Bit32u hihalf = addr & 0xffff0000; - Bit16s lohalf = addr & 0xffff; - if (lohalf > 32764) { // [l,s]wl will overflow - hihalf = addr; - lohalf = 0; - } else if(lohalf < 0) hihalf += 0x10000; - mov_imm_to_temp1(hihalf); - return lohalf; -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - Bit16s lohalf = gen_addr_temp1((Bit32u)data); - // alignment.... - if (dword) { - if ((Bit32u)data & 3) { - cache_addw(lohalf+3); // lwl dest_reg, 3(temp1) - cache_addw(0x8800+(temp1<<5)+dest_reg); - cache_addw(lohalf); // lwr dest_reg, 0(temp1) - cache_addw(0x9800+(temp1<<5)+dest_reg); - } else { - cache_addw(lohalf); // lw dest_reg, 0(temp1) - cache_addw(0x8C00+(temp1<<5)+dest_reg); - } - } else { - if ((Bit32u)data & 1) { - cache_addw(lohalf); // lbu dest_reg, 0(temp1) - cache_addw(0x9000+(temp1<<5)+dest_reg); - cache_addw(lohalf+1); // lbu temp2, 1(temp1) - cache_addw(0x9000+(temp1<<5)+temp2); -#if (_MIPS_ISA==MIPS32R2) || defined(PSP) - cache_addw(0x7a04); // ins dest_reg, temp2, 8, 8 - cache_addw(0x7c00+(temp2<<5)+dest_reg); -#else - cache_addw((temp2<<11)+0x200); // sll temp2, temp2, 8 - cache_addw(temp2); - cache_addw((dest_reg<<11)+0x25); // or dest_reg, temp2, dest_reg - cache_addw((temp2<<5)+dest_reg); -#endif - } else { - cache_addw(lohalf); // lhu dest_reg, 0(temp1); - cache_addw(0x9400+(temp1<<5)+dest_reg); - } - } -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - cache_addw(imm); // ori dest_reg, $0, imm - cache_addw(0x3400+dest_reg); -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - Bit16s lohalf = gen_addr_temp1((Bit32u)dest); - // alignment.... - if (dword) { - if ((Bit32u)dest & 3) { - cache_addw(lohalf+3); // swl src_reg, 3(temp1) - cache_addw(0xA800+(temp1<<5)+src_reg); - cache_addw(lohalf); // swr src_reg, 0(temp1) - cache_addw(0xB800+(temp1<<5)+src_reg); - } else { - cache_addw(lohalf); // sw src_reg, 0(temp1) - cache_addw(0xAC00+(temp1<<5)+src_reg); - } - } else { - if((Bit32u)dest & 1) { - cache_addw(lohalf); // sb src_reg, 0(temp1) - cache_addw(0xA000+(temp1<<5)+src_reg); - cache_addw((temp2<<11)+0x202); // srl temp2, src_reg, 8 - cache_addw(src_reg); - cache_addw(lohalf+1); // sb temp2, 1(temp1) - cache_addw(0xA000+(temp1<<5)+temp2); - } else { - cache_addw(lohalf); // sh src_reg, 0(temp1); - cache_addw(0xA400+(temp1<<5)+src_reg); - } - } -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - Bit16s lohalf = gen_addr_temp1((Bit32u)data); - cache_addw(lohalf); // lbu dest_reg, 0(temp1) - cache_addw(0x9000+(temp1<<5)+dest_reg); -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_mov_byte_to_reg_low(dest_reg, data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - gen_mov_word_to_reg_imm(dest_reg, imm); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - gen_mov_byte_to_reg_low_imm(dest_reg, imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - Bit16s lohalf = gen_addr_temp1((Bit32u)dest); - cache_addw(lohalf); // sb src_reg, 0(temp1) - cache_addw(0xA000+(temp1<<5)+src_reg); -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - if (sign) { -#if (_MIPS_ISA==MIPS32R2) || defined(PSP) - cache_addw((reg<<11)+0x420); // seb reg, reg - cache_addw(0x7c00+reg); -#else - arch that lacks seb -#endif - } else { - cache_addw(0xff); // andi reg, reg, 0xff - cache_addw(0x3000+(reg<<5)+reg); - } -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - if (sign) { -#if (_MIPS_ISA==MIPS32R2) || defined(PSP) - cache_addw((reg<<11)+0x620); // seh reg, reg - cache_addw(0x7c00+reg); -#else - arch that lacks seh -#endif - } else { - cache_addw(0xffff); // andi reg, reg, 0xffff - cache_addw(0x3000+(reg<<5)+reg); - } -} - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_mov_word_to_reg(temp2, op, 1); - cache_addw((reg<<11)+0x21); // addu reg, reg, temp2 - cache_addw((reg<<5)+temp2); -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - if(!imm) return; - if(((Bit32s)imm >= -32768) && ((Bit32s)imm < 32768)) { - cache_addw((Bit16u)imm); // addiu reg, reg, imm - cache_addw(0x2400+(reg<<5)+reg); - } else { - mov_imm_to_temp1(imm); - cache_addw((reg<<11)+0x21); // addu reg, reg, temp1 - cache_addw((reg<<5)+temp1); - } -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - if(imm < 65536) { - cache_addw((Bit16u)imm); // andi reg, reg, imm - cache_addw(0x3000+(reg<<5)+reg); - } else { - mov_imm_to_temp1((Bit32u)imm); - cache_addw((reg<<11)+0x24); // and reg, temp1, reg - cache_addw((temp1<<5)+reg); - } -} - - -// move a 32bit constant value into memory -static void INLINE gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_mov_dword_to_reg_imm(temp2, imm); - gen_mov_word_from_reg(temp2, dest, 1); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void INLINE gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if(!imm) return; - gen_mov_word_to_reg(temp2, dest, dword); - gen_add_imm(temp2, imm); - gen_mov_word_from_reg(temp2, dest, dword); -} - -// add an 8bit constant value to a dword memory value -static void INLINE gen_add_direct_byte(void* dest,Bit8s imm) { - gen_add_direct_word(dest, (Bit32s)imm, 1); -} - -// subtract an 8bit constant value from a dword memory value -static void INLINE gen_sub_direct_byte(void* dest,Bit8s imm) { - gen_add_direct_word(dest, -((Bit32s)imm), 1); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void INLINE gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - gen_add_direct_word(dest, -(Bit32s)imm, dword); -} - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - if (scale) { - cache_addw((scale_reg<<11)+(scale<<6)); // sll scale_reg, scale_reg, scale - cache_addw(scale_reg); - } - cache_addw((dest_reg<<11)+0x21); // addu dest_reg, dest_reg, scale_reg - cache_addw((dest_reg<<5)+scale_reg); - gen_add_imm(dest_reg, imm); -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - if (scale) { - cache_addw((dest_reg<<11)+(scale<<6)); // sll dest_reg, dest_reg, scale - cache_addw(dest_reg); - } - gen_add_imm(dest_reg, imm); -} - -#define DELAY cache_addd(0) // nop - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { -#if C_DEBUG - if ((cache.pos ^ func) & 0xf0000000) LOG_MSG("jump overflow\n"); -#endif - temp1_valid = false; - cache_addd(0x0c000000+(((Bit32u)func>>2)&0x3ffffff)); // jal func - DELAY; -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - Bit32u proc_addr = (Bit32u)cache.pos; - gen_call_function_raw(func); - return proc_addr; -} - -#ifdef __mips_eabi -// max of 8 parameters in $a0-$a3 and $t0-$t3 - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - gen_mov_dword_to_reg_imm(param+4, imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - gen_mov_dword_to_reg_imm(param+4, addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - gen_mov_regs(param+4, reg); -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - gen_mov_word_to_reg(param+4, (void *)mem, 1); -} -#else - other mips abis -#endif - -// jump to an address pointed at by ptr, offset is in imm -static void INLINE gen_jmp_ptr(void * ptr,Bits imm=0) { - gen_mov_word_to_reg(temp2, ptr, 1); - if((imm < -32768) || (imm >= 32768)) { - gen_add_imm(temp2, imm); - imm = 0; - } - temp1_valid = false; - cache_addw((Bit16u)imm); // lw temp2, imm(temp2) - cache_addw(0x8C00+(temp2<<5)+temp2); - cache_addd((temp2<<21)+8); // jr temp2 - DELAY; -} - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { - temp1_valid = false; - if(!dword) { - cache_addw(0xffff); // andi temp1, reg, 0xffff - cache_addw(0x3000+(reg<<5)+temp1); - } - cache_addw(0); // beq $0, reg, 0 - cache_addw(0x1000+(dword?reg:temp1)); - DELAY; - return ((Bit32u)cache.pos-8); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { - temp1_valid = false; - if(!dword) { - cache_addw(0xffff); // andi temp1, reg, 0xffff - cache_addw(0x3000+(reg<<5)+temp1); - } - cache_addw(0); // bne $0, reg, 0 - cache_addw(0x1400+(dword?reg:temp1)); - DELAY; - return ((Bit32u)cache.pos-8); -} - -// calculate relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-data; - if (len<0) len=-len; - if (len>126) LOG_MSG("Big jump %d",len); -#endif - temp1_valid = false; // this is a branch target - *(Bit16u*)data=((Bit16u)((Bit32u)cache.pos-data-4)>>2); -} - -#if 0 // assume for the moment no branch will go farther then +/- 128KB - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - temp1_valid = false; - if (!isdword) { - cache_addw(0xff); // andi temp1, reg, 0xff - cache_addw(0x3000+(reg<<5)+temp1); - } - cache_addw(3); // beq $0, reg, +12 - cache_addw(0x1000+(isdword?reg:temp1)); - DELAY; - cache_addd(0x00000000); // fill j - DELAY; - return ((Bit32u)cache.pos-8); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { - temp1_valid = false; - cache_addw(3); // bgtz reg, +12 - cache_addw(0x1c00+(reg<<5)); - DELAY; - cache_addd(0x00000000); // fill j - DELAY; - return ((Bit32u)cache.pos-8); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - temp1_valid = false; - // this is an absolute branch - *(Bit32u*)data=0x08000000+(((Bit32u)cache.pos>>2)&0x3ffffff); -} -#else -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - temp1_valid = false; - if (!isdword) { - cache_addw(0xff); // andi temp1, reg, 0xff - cache_addw(0x3000+(reg<<5)+temp1); - } - cache_addw(0); // bne $0, reg, 0 - cache_addw(0x1400+(isdword?reg:temp1)); - DELAY; - return ((Bit32u)cache.pos-8); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { - temp1_valid = false; - cache_addw(0); // blez reg, 0 - cache_addw(0x1800+(reg<<5)); - DELAY; - return ((Bit32u)cache.pos-8); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void INLINE gen_fill_branch_long(Bit32u data) { - gen_fill_branch(data); -} -#endif - -static void gen_run_code(void) { - temp1_valid = false; - cache_addd(0x27bdfff0); // addiu $sp, $sp, -16 - cache_addd(0xafb00004); // sw $s0, 4($sp) - cache_addd(0x00800008); // jr $a0 - cache_addd(0xafbf0000); // sw $ra, 0($sp) -} - -// return from a function -static void gen_return_function(void) { - temp1_valid = false; - cache_addd(0x8fbf0000); // lw $ra, 0($sp) - cache_addd(0x8fb00004); // lw $s0, 4($sp) - cache_addd(0x03e00008); // jr $ra - cache_addd(0x27bd0010); // addiu $sp, $sp, 16 -} - -#ifdef DRC_FLAGS_INVALIDATION -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { -#ifdef DRC_FLAGS_INVALIDATION_DCODE - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit32u*)pos=0x00851021; // addu $v0, $a0, $a1 - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit32u*)pos=0x00851025; // or $v0, $a0, $a1 - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit32u*)pos=0x00851024; // and $v0, $a0, $a1 - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit32u*)pos=0x00851023; // subu $v0, $a0, $a1 - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit32u*)pos=0x00851026; // xor $v0, $a0, $a1 - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit32u*)pos=0; // nop - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit32u*)pos=0x24820001; // addiu $v0, $a0, 1 - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit32u*)pos=0x2482ffff; // addiu $v0, $a0, -1 - break; - case t_SHLb: - case t_SHLw: - case t_SHLd: - *(Bit32u*)pos=0x00a41004; // sllv $v0, $a0, $a1 - break; - case t_SHRb: - case t_SHRw: - case t_SHRd: - *(Bit32u*)pos=0x00a41006; // srlv $v0, $a0, $a1 - break; - case t_SARd: - *(Bit32u*)pos=0x00a41007; // srav $v0, $a0, $a1 - break; -#if (_MIPS_ISA==MIPS32R2) || defined(PSP) - case t_RORd: - *(Bit32u*)pos=0x00a41046; // rotr $v0, $a0, $a1 - break; -#endif - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit32u*)pos=0x00041023; // subu $v0, $0, $a0 - break; - default: - *(Bit32u*)pos=0x0c000000+((((Bit32u)fct_ptr)>>2)&0x3ffffff); // jal simple_func - break; - } -#else - *(Bit32u*)pos=0x0c000000+(((Bit32u)fct_ptr)>>2)&0x3ffffff); // jal simple_func -#endif -} -#endif - -static void cache_block_closing(Bit8u* block_start,Bitu block_size) { -#ifdef PSP -// writeback dcache and invalidate icache - Bit32u inval_start = ((Bit32u)block_start) & ~63; - Bit32u inval_end = (((Bit32u)block_start) + block_size + 64) & ~63; - for (;inval_start < inval_end; inval_start+=64) { - __builtin_allegrex_cache(0x1a, inval_start); - __builtin_allegrex_cache(0x08, inval_start); - } -#endif -} - -static void cache_block_before_close(void) { } - - -#ifdef DRC_USE_SEGS_ADDR - -// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { -// stub -} - -// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { -// stub -} - -// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) -static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { -// stub -} - -#endif - -#ifdef DRC_USE_REGS_ADDR - -// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { -// stub -} - -// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { -// stub -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { -// stub -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { -// stub -} - -// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { -// stub -} - - -// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { -// stub -} - - -// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) -static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { -// stub -} - -// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) -static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { -// stub -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) -static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { -// stub -} - -// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR -static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { -// stub -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_x64.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_x64.h deleted file mode 100644 index e293e95bc..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_x64.h +++ /dev/null @@ -1,746 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -// some configuring defines that specify the capabilities of this architecture -// or aspects of the recompiling - -// protect FC_ADDR over function calls if necessaray -// #define DRC_PROTECT_ADDR_REG - -// try to use non-flags generating functions if possible -#define DRC_FLAGS_INVALIDATION -// try to replace _simple functions by code -#define DRC_FLAGS_INVALIDATION_DCODE - -// type with the same size as a pointer -#define DRC_PTR_SIZE_IM Bit64u - -// calling convention modifier -#define DRC_CALL_CONV /* nothing */ -#define DRC_FC /* nothing */ - - -// register mapping -typedef Bit8u HostReg; - -#define HOST_EAX 0 -#define HOST_ECX 1 -#define HOST_EDX 2 -#define HOST_EBX 3 -#define HOST_ESI 6 -#define HOST_EDI 7 - - -// register that holds function return values -#define FC_RETOP HOST_EAX - -// register used for address calculations, if the ABI does not -// state that this register is preserved across function calls -// then define DRC_PROTECT_ADDR_REG above -#define FC_ADDR HOST_EBX - -// register that holds the first parameter -#define FC_OP1 HOST_EDI - -// register that holds the second parameter -#define FC_OP2 HOST_ESI - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_EAX - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_ECX - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_EDX - - -// temporary register for LEA -#define TEMP_REG_DRC HOST_ESI - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - cache_addb(0x8b); // mov reg_dst,reg_src - cache_addb(0xc0+(reg_dst<<3)+reg_src); -} - -// move a 64bit constant value into a full register -static void gen_mov_reg_qword(HostReg dest_reg,Bit64u imm) { - cache_addb(0x48); - cache_addb(0xb8+dest_reg); // mov dest_reg,imm - cache_addq(imm); -} - - -// This function generates an instruction with register addressing and a memory location -static INLINE void gen_reg_memaddr(HostReg reg,void* data,Bit8u op,Bit8u prefix=0) { - Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+(prefix?7:6)); -// if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { //clang messes itself up on this... - if ( (diff>>63) == (diff>>31) ) { //signed bit extend, test to see if value fits in a Bit32s - // mov reg,[rip+diff] (or similar, depending on the op) to fetch *data - if(prefix) cache_addb(prefix); - cache_addb(op); - cache_addb(0x05+(reg<<3)); - // RIP-relative addressing is offset after the instruction - cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); - } else if ((Bit64u)data<0x100000000LL) { - // mov reg,[data] (or similar, depending on the op) when absolute address of data is <4GB - if(prefix) cache_addb(prefix); - cache_addb(op); - cache_addw(0x2504+(reg<<3)); - cache_addd((Bit32u)(((Bit64u)data)&0xffffffffLL)); - } else { - // load 64-bit data into tmp_reg and do mov reg,[tmp_reg] (or similar, depending on the op) - HostReg tmp_reg = HOST_EAX; - if(reg == HOST_EAX) tmp_reg = HOST_ECX; - - cache_addb(0x50+tmp_reg); // push rax/rcx - gen_mov_reg_qword(tmp_reg,(Bit64u)data); - - if(prefix) cache_addb(prefix); - cache_addb(op); - cache_addb(tmp_reg+(reg<<3)); - - cache_addb(0x58+tmp_reg); // pop rax/rcx - } -} - -// Same as above, but with immediate addressing and a memory location -static INLINE void gen_memaddr(Bitu modreg,void* data,Bitu off,Bitu imm,Bit8u op,Bit8u prefix=0) { - Bit64s diff = (Bit64s)data-((Bit64s)cache.pos+off+(prefix?7:6)); -// if ((diff<0x80000000LL) && (diff>-0x80000000LL)) { - if ( (diff>>63) == (diff>>31) ) { - // RIP-relative addressing is offset after the instruction - if(prefix) cache_addb(prefix); - cache_addw(op+((modreg+1)<<8)); - cache_addd((Bit32u)(((Bit64u)diff)&0xffffffffLL)); - - switch(off) { - case 1: cache_addb(((Bit8u)imm&0xff)); break; - case 2: cache_addw(((Bit16u)imm&0xffff)); break; - case 4: cache_addd(((Bit32u)imm&0xffffffff)); break; - } - - } else if ((Bit64u)data<0x100000000LL) { - if(prefix) cache_addb(prefix); - cache_addw(op+(modreg<<8)); - cache_addb(0x25); - cache_addd((Bit32u)(((Bit64u)data)&0xffffffffLL)); - - switch(off) { - case 1: cache_addb(((Bit8u)imm&0xff)); break; - case 2: cache_addw(((Bit16u)imm&0xffff)); break; - case 4: cache_addd(((Bit32u)imm&0xffffffff)); break; - } - - } else { - HostReg tmp_reg = HOST_EAX; - - cache_addb(0x50+tmp_reg); // push rax - gen_mov_reg_qword(tmp_reg,(Bit64u)data); - - if(prefix) cache_addb(prefix); - cache_addw(op+((modreg-4+tmp_reg)<<8)); - - switch(off) { - case 1: cache_addb(((Bit8u)imm&0xff)); break; - case 2: cache_addw(((Bit16u)imm&0xffff)); break; - case 4: cache_addd(((Bit32u)imm&0xffffffff)); break; - } - - cache_addb(0x58+tmp_reg); // pop rax - } -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword,Bit8u prefix=0) { - if (!dword) gen_reg_memaddr(dest_reg,data,0xb7,0x0f); // movzx reg,[data] - zero extend data, fixes LLVM compile where the called function does not extend the parameters - else gen_reg_memaddr(dest_reg,data,0x8b,prefix); // mov reg,[data] -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addd((Bit32u)imm); -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addd(imm); -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword,Bit8u prefix=0) { - gen_reg_memaddr(src_reg,dest,0x89,(dword?prefix:0x66)); // mov [data],reg -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - gen_reg_memaddr(dest_reg,data,0xb6,0x0f); // movzx reg,[data] -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - gen_reg_memaddr(dest_reg,data,0xb6,0x0f); // movzx reg,[data] -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addd((Bit32u)imm); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addd((Bit32u)imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - gen_reg_memaddr(src_reg,dest,0x88); // mov byte [data],reg -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - cache_addw(0xb60f+(sign?0x800:0)); // movsx/movzx - cache_addb(0xc0+(reg<<3)+reg); -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - cache_addw(0xb70f+(sign?0x800:0)); // movsx/movzx - cache_addb(0xc0+(reg<<3)+reg); -} - - - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - gen_reg_memaddr(reg,op,0x03); // add reg,[data] -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - cache_addw(0xc081+(reg<<8)); // add reg,imm - cache_addd(imm); -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - cache_addw(0xe081+(reg<<8)); // and reg,imm - cache_addd(imm); -} - - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - gen_memaddr(0x4,dest,4,imm,0xc7); // mov [data],imm -} - - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_reg_qword(HOST_EAX,imm); - gen_mov_word_from_reg(HOST_EAX,dest,true,0x48); // 0x48 prefixes full 64-bit mov -} - - -// add an 8bit constant value to a memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - gen_memaddr(0x4,dest,1,imm,0x83); // add [data],imm -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if ((imm<128) && dword) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; - } - gen_memaddr(0x4,dest,(dword?4:2),imm,0x81,(dword?0:0x66)); // add [data],imm -} - -// subtract an 8bit constant value from a memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - gen_memaddr(0x2c,dest,1,imm,0x83); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - if ((imm<128) && dword) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; - } - gen_memaddr(0x2c,dest,(dword?4:2),imm,0x81,(dword?0:0x66)); // sub [data],imm -} - - - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - Bit8u rm_base; - Bitu imm_size; - if (!imm) { - imm_size=0; rm_base=0x0; //no imm - } else if ((imm>=-128 && imm<=127)) { - imm_size=1; rm_base=0x40; //Signed byte imm - } else { - imm_size=4; rm_base=0x80; //Signed dword imm - } - - // ea_reg := ea_reg+scale_reg*(2^scale)+imm - cache_addb(0x48); - cache_addb(0x8d); //LEA - cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator - cache_addb(dest_reg+(scale_reg<<3)+(scale<<6)); - - switch (imm_size) { - case 0: break; - case 1:cache_addb(imm);break; - case 4:cache_addd(imm);break; - } -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - // ea_reg := ea_reg*(2^scale)+imm - // ea_reg := op2 *(2^scale)+imm - cache_addb(0x48); - cache_addb(0x8d); //LEA - cache_addb(0x04+(dest_reg<<3)); - cache_addb(0x05+(dest_reg<<3)+(scale<<6)); - - cache_addd(imm); // always add dword immediate -} - - - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { - cache_addb(0x48); - cache_addw(0xec83); - cache_addb(0x08); // sub rsp,0x08 (align stack to 16 byte boundary) - - cache_addb(0x48); - cache_addb(0xb8); // mov reg,imm64 - cache_addq((Bit64u)func); - cache_addw(0xd0ff); - - cache_addb(0x48); - cache_addw(0xc483); - cache_addb(0x08); // add rsp,0x08 (reset alignment) -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit64u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - // align the stack - cache_addb(0x48); - cache_addw(0xc48b); // mov rax,rsp - - cache_addb(0x48); - cache_addw(0xec83); // sub rsp,0x08 - cache_addb(0x08); // 0x08==return address pushed onto stack by call - - cache_addb(0x48); - cache_addw(0xe483); // and esp,0xfffffffffffffff0 - cache_addb(0xf0); - - cache_addb(0x48); - cache_addw(0xc483); // add rsp,0x08 - cache_addb(0x08); - - // stack is 16 byte aligned now - - - cache_addb(0x50); // push rax (==old rsp) - - // returned address relates to where the address is stored in gen_call_function_raw - Bit64u proc_addr=(Bit64u)cache.pos-4; - - // Do the actual call to the procedure - cache_addb(0x48); - cache_addb(0xb8); // mov reg,imm64 - cache_addq((Bit64u)func); - - cache_addw(0xd0ff); - - // restore stack - cache_addb(0x5c); // pop rsp - - return proc_addr; -} - - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - // move an immediate 32bit value into a 64bit param reg - switch (param) { - case 0: // mov param1,imm32 - gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)imm); - break; - case 1: // mov param2,imm32 - gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); - break; -#if defined (_MSC_VER) - case 2: // mov r8,imm32 - cache_addw(0xb849); - cache_addq((Bit32u)imm); - break; - case 3: // mov r9,imm32 - cache_addw(0xb949); - cache_addq((Bit32u)imm); - break; -#else - case 2: // mov rdx,imm32 - gen_mov_dword_to_reg_imm(HOST_EDX,(Bit32u)imm); - break; - case 3: // mov rcx,imm32 - gen_mov_dword_to_reg_imm(HOST_ECX,(Bit32u)imm); - break; -#endif - default: - E_Exit("I(mm) >4 params unsupported"); - break; - } -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(DRC_PTR_SIZE_IM addr,Bitu param) { - // move an immediate 64bit value into a 64bit param reg - switch (param) { - case 0: // mov param1,addr64 - gen_mov_reg_qword(FC_OP1,addr); - break; - case 1: // mov param2,addr64 - gen_mov_reg_qword(FC_OP2,addr); - break; -#if defined (_MSC_VER) - case 2: // mov r8,addr64 - cache_addw(0xb849); - cache_addq(addr); - break; - case 3: // mov r9,addr64 - cache_addw(0xb949); - cache_addq(addr); - break; -#else - case 2: // mov rdx,addr64 - gen_mov_reg_qword(HOST_EDX,addr); - break; - case 3: // mov rcx,addr64 - gen_mov_reg_qword(HOST_ECX,addr); - break; -#endif - default: - E_Exit("A(ddr) >4 params unsupported"); - break; - } -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - // move a register into a 64bit param reg, {inputregs}!={outputregs} - switch (param) { - case 0: // mov param1,reg&7 - gen_mov_regs(FC_OP1,reg&7); - break; - case 1: // mov param2,reg&7 - gen_mov_regs(FC_OP2,reg&7); - break; -#if defined (_MSC_VER) - case 2: // mov r8,reg&7 - cache_addb(0x49); - gen_mov_regs(0,reg&7); - break; - case 3: // mov r9,reg&7 - cache_addb(0x49); - gen_mov_regs(1,reg&7); - break; -#else - case 2: // mov rdx,reg&7 - gen_mov_regs(HOST_EDX,reg&7); - break; - case 3: // mov rcx,reg&7 - gen_mov_regs(HOST_ECX,reg&7); - break; -#endif - default: - E_Exit("R(eg) >4 params unsupported"); - break; - } -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - // move memory content into a 64bit param reg - switch (param) { - case 0: // mov param1,[mem] - gen_mov_word_to_reg(FC_OP1,(void*)mem,true); - break; - case 1: // mov param2,[mem] - gen_mov_word_to_reg(FC_OP2,(void*)mem,true); - break; -#if defined (_MSC_VER) - case 2: // mov r8,[mem] - gen_mov_word_to_reg(0,(void*)mem,true,0x49); // 0x49, use x64 rX regs - break; - case 3: // mov r9,[mem] - gen_mov_word_to_reg(1,(void*)mem,true,0x49); // 0x49, use x64 rX regs - break; -#else - case 2: // mov rdx,[mem] - gen_mov_word_to_reg(HOST_EDX,(void*)mem,true); - break; - case 3: // mov rcx,[mem] - gen_mov_word_to_reg(HOST_ECX,(void*)mem,true); - break; -#endif - default: - E_Exit("R(eg) >4 params unsupported"); - break; - } -} - - - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - cache_addw(0xa148); // mov rax,[data] - cache_addq((Bit64u)ptr); - - cache_addb(0xff); // jmp [rax+imm] - if (!imm) { - cache_addb(0x20); - } else if ((imm>=-128 && imm<=127)) { - cache_addb(0x60); - cache_addb(imm); - } else { - cache_addb(0xa0); - cache_addd(imm); - } -} - - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit64u gen_create_branch_on_zero(HostReg reg,bool dword) { - if (!dword) cache_addb(0x66); - cache_addb(0x0b); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x0074); // jz addr - return ((Bit64u)cache.pos-1); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit64u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - if (!dword) cache_addb(0x66); - cache_addb(0x0b); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x0075); // jnz addr - return ((Bit64u)cache.pos-1); -} - -// calculate relative offset and fill it into the location pointed to by data -static void gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bit64s len=(Bit64u)cache.pos-data; - if (len<0) len=-len; - if (len>126) LOG_MSG("Big jump %d",len); -#endif - *(Bit8u*)data=(Bit8u)((Bit64u)cache.pos-data-1); -} - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit64u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - // isdword: cmp reg32,0 - // not isdword: cmp reg8,0 - cache_addb(0x0a+(isdword?1:0)); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x850f); // jnz - cache_addd(0); - return ((Bit64u)cache.pos-4); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit64u gen_create_branch_long_leqzero(HostReg reg) { - cache_addw(0xf883+(reg<<8)); - cache_addb(0x00); // cmp reg,0 - - cache_addw(0x8e0f); // jle - cache_addd(0); - return ((Bit64u)cache.pos-4); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void gen_fill_branch_long(Bit64u data) { - *(Bit32u*)data=(Bit32u)((Bit64u)cache.pos-data-4); -} - - -static void gen_run_code(void) { - cache_addb(0x53); // push rbx - cache_addw(0xd0ff+(FC_OP1<<8)); // call rdi - cache_addb(0x5b); // pop rbx -} - -// return from a function -static void gen_return_function(void) { - cache_addb(0xc3); // ret -} - -#ifdef DRC_FLAGS_INVALIDATION -// called when a call to a function can be replaced by a -// call to a simpler function -// check gen_call_function_raw and gen_call_function_setup -// for the targeted code -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { -#ifdef DRC_FLAGS_INVALIDATION_DCODE - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit32u*)(pos+0)=0xf001f889; // mov eax,edi; add eax,esi - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit32u*)(pos+0)=0xf009f889; // mov eax,edi; or eax,esi - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit32u*)(pos+0)=0xf021f889; // mov eax,edi; and eax,esi - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit32u*)(pos+0)=0xf029f889; // mov eax,edi; sub eax,esi - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit32u*)(pos+0)=0xf031f889; // mov eax,edi; xor eax,esi - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit32u*)(pos+0)=0x909012eb; // skip - *(Bit32u*)(pos+4)=0x90909090; - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit32u*)(pos+0)=0xc0fff889; // mov eax,edi; inc eax - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit32u*)(pos+0)=0xc8fff889; // mov eax,edi; dec eax - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit32u*)(pos+0)=0xd8f7f889; // mov eax,edi; neg eax - *(Bit32u*)(pos+4)=0x90900eeb; // skip - *(Bit32u*)(pos+8)=0x90909090; - *(Bit32u*)(pos+12)=0x90909090; - *(Bit32u*)(pos+16)=0x90909090; - break; - default: - *(Bit64u*)(pos+6)=(Bit64u)fct_ptr; // fill function pointer - break; - } -#else - *(Bit64u*)(pos+6)=(Bit64u)fct_ptr; // fill function pointer -#endif -} -#endif - -static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } - -static void cache_block_before_close(void) { } diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_x86.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_x86.h deleted file mode 100644 index 81cb03bc9..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_dynrec/risc_x86.h +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -// some configuring defines that specify the capabilities of this architecture -// or aspects of the recompiling - -// protect FC_ADDR over function calls if necessaray -// #define DRC_PROTECT_ADDR_REG - -// try to use non-flags generating functions if possible -#define DRC_FLAGS_INVALIDATION -// try to replace _simple functions by code -#define DRC_FLAGS_INVALIDATION_DCODE - -// type with the same size as a pointer -#define DRC_PTR_SIZE_IM Bit32u - -// calling convention modifier -#if defined (WIN32) -#define DRC_CALL_CONV _fastcall -#define DRC_FC /* nothing */ -#else -#define DRC_CALL_CONV /* nothing */ -#define DRC_FC GCC_ATTRIBUTE(fastcall) -#endif - - -// register mapping -enum HostReg { - HOST_EAX=0, - HOST_ECX, - HOST_EDX, - HOST_EBX, - HOST_ESP, - HOST_EBP, - HOST_ESI, - HOST_EDI -}; - - -// register that holds function return values -#define FC_RETOP HOST_EAX - -// register used for address calculations, if the ABI does not -// state that this register is preserved across function calls -// then define DRC_PROTECT_ADDR_REG above -#define FC_ADDR HOST_EBX - -// register that holds the first parameter -#define FC_OP1 HOST_ECX - -// register that holds the second parameter -#define FC_OP2 HOST_EDX - -// special register that holds the third parameter for _R3 calls (byte accessible) -#define FC_OP3 HOST_EAX - -// register that holds byte-accessible temporary values -#define FC_TMP_BA1 HOST_ECX - -// register that holds byte-accessible temporary values -#define FC_TMP_BA2 HOST_EDX - - -// temporary register for LEA -#define TEMP_REG_DRC HOST_ESI - - -// move a full register from reg_src to reg_dst -static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { - cache_addb(0x8b); // mov reg_dst,reg_src - cache_addb(0xc0+(reg_dst<<3)+reg_src); -} - -// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg -// 16bit moves may destroy the upper 16bit of the destination register -static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) { - if (!dword) cache_addb(0x66); - cache_addw(0x058b+(dest_reg<<11)); // mov reg,[data] - cache_addd((Bit32u)data); -} - -// move a 16bit constant value into dest_reg -// the upper 16bit of the destination register may be destroyed -static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) { - cache_addb(0x66); - cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addw(imm); -} - -// move a 32bit constant value into dest_reg -static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { - cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addd(imm); -} - -// move 32bit (dword==true) or 16bit (dword==false) of a register into memory -static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) { - if (!dword) cache_addb(0x66); - cache_addw(0x0589+(src_reg<<11)); // mov [data],reg - cache_addd((Bit32u)dest); -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) { - cache_addw(0x058a+(dest_reg<<11)); // mov reg,[data] - cache_addd((Bit32u)data); -} - -// move an 8bit value from memory into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) { - cache_addb(0x66); - cache_addw(0x058b+(dest_reg<<11)); // mov reg,[data] - cache_addd((Bit32u)data); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function does not use FC_OP1/FC_OP2 as dest_reg as these -// registers might not be directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) { - cache_addb(0xb0+dest_reg); // mov reg,imm - cache_addb(imm); -} - -// move an 8bit constant value into dest_reg -// the upper 24bit of the destination register can be destroyed -// this function can use FC_OP1/FC_OP2 as dest_reg which are -// not directly byte-accessible on some architectures -static void gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) { - cache_addb(0x66); - cache_addb(0xb8+dest_reg); // mov reg,imm - cache_addw(imm); -} - -// move the lowest 8bit of a register into memory -static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) { - cache_addw(0x0588+(src_reg<<11)); // mov [data],reg - cache_addd((Bit32u)dest); -} - - - -// convert an 8bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_byte(bool sign,HostReg reg) { - cache_addw(0xb60f+(sign?0x800:0)); // movsx/movzx - cache_addb(0xc0+(reg<<3)+reg); -} - -// convert a 16bit word to a 32bit dword -// the register is zero-extended (sign==false) or sign-extended (sign==true) -static void gen_extend_word(bool sign,HostReg reg) { - cache_addw(0xb70f+(sign?0x800:0)); // movsx/movzx - cache_addb(0xc0+(reg<<3)+reg); -} - - - -// add a 32bit value from memory to a full register -static void gen_add(HostReg reg,void* op) { - cache_addw(0x0503+(reg<<11)); // add reg,[data] - cache_addd((Bit32u)op); -} - -// add a 32bit constant value to a full register -static void gen_add_imm(HostReg reg,Bit32u imm) { - cache_addw(0xc081+(reg<<8)); // add reg,imm - cache_addd(imm); -} - -// and a 32bit constant value with a full register -static void gen_and_imm(HostReg reg,Bit32u imm) { - cache_addw(0xe081+(reg<<8)); // and reg,imm - cache_addd(imm); -} - - - -// move a 32bit constant value into memory -static void gen_mov_direct_dword(void* dest,Bit32u imm) { - cache_addw(0x05c7); // mov [data],imm - cache_addd((Bit32u)dest); - cache_addd(imm); -} - -// move an address into memory -static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) { - gen_mov_direct_dword(dest,(Bit32u)imm); -} - - -// add an 8bit constant value to a memory value -static void gen_add_direct_byte(void* dest,Bit8s imm) { - cache_addw(0x0583); // add [data],imm - cache_addd((Bit32u)dest); - cache_addb(imm); -} - -// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value -static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) { - if ((imm<128) && dword) { - gen_add_direct_byte(dest,(Bit8s)imm); - return; - } - if (!dword) cache_addb(0x66); - cache_addw(0x0581); // add [data],imm - cache_addd((Bit32u)dest); - if (dword) cache_addd((Bit32u)imm); - else cache_addw((Bit16u)imm); -} - -// subtract an 8bit constant value from a memory value -static void gen_sub_direct_byte(void* dest,Bit8s imm) { - cache_addw(0x2d83); // sub [data],imm - cache_addd((Bit32u)dest); - cache_addb(imm); -} - -// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value -static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) { - if ((imm<128) && dword) { - gen_sub_direct_byte(dest,(Bit8s)imm); - return; - } - if (!dword) cache_addb(0x66); - cache_addw(0x2d81); // sub [data],imm - cache_addd((Bit32u)dest); - if (dword) cache_addd((Bit32u)imm); - else cache_addw((Bit16u)imm); -} - - - -// effective address calculation, destination is dest_reg -// scale_reg is scaled by scale (scale_reg*(2^scale)) and -// added to dest_reg, then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) { - Bit8u rm_base; - Bitu imm_size; - if (!imm) { - imm_size=0; rm_base=0x0; //no imm - } else if ((imm>=-128 && imm<=127)) { - imm_size=1; rm_base=0x40; //Signed byte imm - } else { - imm_size=4; rm_base=0x80; //Signed dword imm - } - - // ea_reg := ea_reg+scale_reg*(2^scale)+imm - cache_addb(0x8d); //LEA - cache_addb(0x04+(dest_reg << 3)+rm_base); //The sib indicator - cache_addb(dest_reg+(scale_reg<<3)+(scale<<6)); - - switch (imm_size) { - case 0: break; - case 1:cache_addb(imm);break; - case 4:cache_addd(imm);break; - } -} - -// effective address calculation, destination is dest_reg -// dest_reg is scaled by scale (dest_reg*(2^scale)), -// then the immediate value is added -static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) { - // ea_reg := ea_reg*(2^scale)+imm - // ea_reg := op2 *(2^scale)+imm - cache_addb(0x8d); //LEA - cache_addb(0x04+(dest_reg<<3)); - cache_addb(0x05+(dest_reg<<3)+(scale<<6)); - - cache_addd(imm); // always add dword immediate -} - - - -// generate a call to a parameterless function -static void INLINE gen_call_function_raw(void * func) { - cache_addb(0xe8); - cache_addd((Bit32u)func - (Bit32u)cache.pos-4); -} - -// generate a call to a function with paramcount parameters -// note: the parameters are loaded in the architecture specific way -// using the gen_load_param_ functions below -static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) { - Bit32u proc_addr=(Bit32u)cache.pos; - // Do the actual call to the procedure - cache_addb(0xe8); - cache_addd((Bit32u)func - (Bit32u)cache.pos-4); - - // Restore the params of the stack - if (paramcount) { - cache_addw(0xc483); //add ESP,imm byte - cache_addb((!fastcall)?paramcount*4:0); - } - return proc_addr; -} - - -// load an immediate value as param'th function parameter -static void INLINE gen_load_param_imm(Bitu imm,Bitu param) { - cache_addb(0x68); // push immediate - cache_addd(imm); -} - -// load an address as param'th function parameter -static void INLINE gen_load_param_addr(Bitu addr,Bitu param) { - cache_addb(0x68); // push immediate (address) - cache_addd(addr); -} - -// load a host-register as param'th function parameter -static void INLINE gen_load_param_reg(Bitu reg,Bitu param) { - cache_addb(0x50+(reg&7)); // push reg -} - -// load a value from memory as param'th function parameter -static void INLINE gen_load_param_mem(Bitu mem,Bitu param) { - cache_addw(0x35ff); // push [] - cache_addd(mem); -} - - - -// jump to an address pointed at by ptr, offset is in imm -static void gen_jmp_ptr(void * ptr,Bits imm=0) { - gen_mov_word_to_reg(HOST_EAX,ptr,true); - cache_addb(0xff); // jmp [eax+imm] - if (!imm) { - cache_addb(0x20); - } else if ((imm>=-128 && imm<=127)) { - cache_addb(0x60); - cache_addb(imm); - } else { - cache_addb(0xa0); - cache_addd(imm); - } -} - - -// short conditional jump (+-127 bytes) if register is zero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { - if (!dword) cache_addb(0x66); - cache_addb(0x0b); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x0074); // jz addr - return ((Bit32u)cache.pos-1); -} - -// short conditional jump (+-127 bytes) if register is nonzero -// the destination is set by gen_fill_branch() later -static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { - if (!dword) cache_addb(0x66); - cache_addb(0x0b); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x0075); // jnz addr - return ((Bit32u)cache.pos-1); -} - -// calculate relative offset and fill it into the location pointed to by data -static void gen_fill_branch(DRC_PTR_SIZE_IM data) { -#if C_DEBUG - Bits len=(Bit32u)cache.pos-data; - if (len<0) len=-len; - if (len>126) LOG_MSG("Big jump %d",len); -#endif - *(Bit8u*)data=(Bit8u)((Bit32u)cache.pos-data-1); -} - -// conditional jump if register is nonzero -// for isdword==true the 32bit of the register are tested -// for isdword==false the lowest 8bit of the register are tested -static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { - // isdword: cmp reg32,0 - // not isdword: cmp reg8,0 - cache_addb(0x0a+(isdword?1:0)); // or reg,reg - cache_addb(0xc0+reg+(reg<<3)); - - cache_addw(0x850f); // jnz - cache_addd(0); - return ((Bit32u)cache.pos-4); -} - -// compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u gen_create_branch_long_leqzero(HostReg reg) { - cache_addw(0xf883+(reg<<8)); - cache_addb(0x00); // cmp reg,0 - - cache_addw(0x8e0f); // jle - cache_addd(0); - return ((Bit32u)cache.pos-4); -} - -// calculate long relative offset and fill it into the location pointed to by data -static void gen_fill_branch_long(Bit32u data) { - *(Bit32u*)data=((Bit32u)cache.pos-data-4); -} - - -static void gen_run_code(void) { - cache_addd(0x0424448b); // mov eax,[esp+4] - cache_addb(0x53); // push ebx - cache_addb(0x56); // push esi - cache_addw(0xd0ff); // call eax - cache_addb(0x5e); // pop esi - cache_addb(0x5b); // pop ebx -} - -// return from a function -static void gen_return_function(void) { - cache_addb(0xc3); // ret -} - -#ifdef DRC_FLAGS_INVALIDATION -// called when a call to a function can be replaced by a -// call to a simpler function -static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { -#ifdef DRC_FLAGS_INVALIDATION_DCODE - // try to avoid function calls but rather directly fill in code - switch (flags_type) { - case t_ADDb: - case t_ADDw: - case t_ADDd: - *(Bit32u*)pos=0xc203c18b; // mov eax,ecx; add eax,edx - *(pos+4)=0x90; - break; - case t_ORb: - case t_ORw: - case t_ORd: - *(Bit32u*)pos=0xc20bc18b; // mov eax,ecx; or eax,edx - *(pos+4)=0x90; - break; - case t_ANDb: - case t_ANDw: - case t_ANDd: - *(Bit32u*)pos=0xc223c18b; // mov eax,ecx; and eax,edx - *(pos+4)=0x90; - break; - case t_SUBb: - case t_SUBw: - case t_SUBd: - *(Bit32u*)pos=0xc22bc18b; // mov eax,ecx; sub eax,edx - *(pos+4)=0x90; - break; - case t_XORb: - case t_XORw: - case t_XORd: - *(Bit32u*)pos=0xc233c18b; // mov eax,ecx; xor eax,edx - *(pos+4)=0x90; - break; - case t_CMPb: - case t_CMPw: - case t_CMPd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - *(Bit32u*)pos=0x909003eb; // skip - *(pos+4)=0x90; - break; - case t_INCb: - case t_INCw: - case t_INCd: - *(Bit32u*)pos=0x9040c18b; // mov eax,ecx; inc eax - *(pos+4)=0x90; - break; - case t_DECb: - case t_DECw: - case t_DECd: - *(Bit32u*)pos=0x9048c18b; // mov eax,ecx; dec eax - *(pos+4)=0x90; - break; - case t_NEGb: - case t_NEGw: - case t_NEGd: - *(Bit32u*)pos=0xd8f7c18b; // mov eax,ecx; neg eax - *(pos+4)=0x90; - break; - default: - *(Bit32u*)(pos+1)=(Bit32u)((Bit8u*)fct_ptr - (pos+1+4)); // fill function pointer - break; - } -#else - *(Bit32u*)(pos+1)=(Bit32u)((Bit8u*)fct_ptr - (pos+1+4)); // fill function pointer -#endif -} -#endif - -static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } - -static void cache_block_before_close(void) { } diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/core_full.cpp deleted file mode 100644 index 7fd146956..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "dosbox.h" - -#include "pic.h" -#include "regs.h" -#include "cpu.h" -#include "lazyflags.h" -#include "paging.h" -#include "fpu.h" -#include "debug.h" -#include "inout.h" -#include "callback.h" - - -typedef PhysPt EAPoint; -#define SegBase(c) SegPhys(c) - -#define LoadMb(off) mem_readb_inline(off) -#define LoadMw(off) mem_readw_inline(off) -#define LoadMd(off) mem_readd_inline(off) - -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define SaveMb(off,val) mem_writeb_inline(off,val) -#define SaveMw(off,val) mem_writew_inline(off,val) -#define SaveMd(off,val) mem_writed_inline(off,val) - -#define LoadD(reg) reg -#define SaveD(reg,val) reg=val - - - -#include "core_full/loadwrite.h" -#include "core_full/support.h" -#include "core_full/optable.h" -#include "instructions.h" - -#define EXCEPTION(blah) \ - { \ - Bit8u new_num=blah; \ - CPU_Exception(new_num,0); \ - continue; \ - } - -Bits CPU_Core_Full_Run(void) { - FullData inst; - while (CPU_Cycles-->0) { -#if C_DEBUG - cycle_count++; -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - FillFlags(); - return debugCallback; - }; -#endif -#endif - LoadIP(); - inst.entry=cpu.code.big*0x200; - inst.prefix=cpu.code.big; -restartopcode: - inst.entry=(inst.entry & 0xffffff00) | Fetchb(); - inst.code=OpCodeTable[inst.entry]; - #include "core_full/load.h" - #include "core_full/op.h" - #include "core_full/save.h" -nextopcode:; - SaveIP(); - continue; -illegalopcode: - LOG(LOG_CPU,LOG_NORMAL)("Illegal opcode"); - CPU_Exception(0x6,0); - } - FillFlags(); - return CBRET_NONE; -} - - -void CPU_Core_Full_Init(void) { - -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/Makefile.am b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/Makefile.am deleted file mode 100644 index 41fbe6a2b..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ - -noinst_HEADERS = ea_lookup.h load.h loadwrite.h op.h optable.h save.h \ - string.h support.h diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/Makefile.in b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/Makefile.in deleted file mode 100644 index 450107cb8..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/Makefile.in +++ /dev/null @@ -1,491 +0,0 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/cpu/core_full -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -WINDRES = @WINDRES@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_HEADERS = ea_lookup.h load.h loadwrite.h op.h optable.h save.h \ - string.h support.h - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/cpu/core_full/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/cpu/core_full/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - cscopelist-am ctags ctags-am distclean distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/ea_lookup.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/ea_lookup.h deleted file mode 100644 index 6048a4300..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/ea_lookup.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -{ - EAPoint seg_base; - Bit16u off; - switch ((inst.rm_mod<<3)|inst.rm_eai) { - case 0x00: - off=reg_bx+reg_si; - seg_base=SegBase(ds); - break; - case 0x01: - off=reg_bx+reg_di; - seg_base=SegBase(ds); - break; - case 0x02: - off=reg_bp+reg_si; - seg_base=SegBase(ss); - break; - case 0x03: - off=reg_bp+reg_di; - seg_base=SegBase(ss); - break; - case 0x04: - off=reg_si; - seg_base=SegBase(ds); - break; - case 0x05: - off=reg_di; - seg_base=SegBase(ds); - break; - case 0x06: - off=Fetchw(); - seg_base=SegBase(ds); - break; - case 0x07: - off=reg_bx; - seg_base=SegBase(ds); - break; - - case 0x08: - off=reg_bx+reg_si+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x09: - off=reg_bx+reg_di+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0a: - off=reg_bp+reg_si+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0b: - off=reg_bp+reg_di+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0c: - off=reg_si+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0d: - off=reg_di+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0e: - off=reg_bp+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0f: - off=reg_bx+Fetchbs(); - seg_base=SegBase(ds); - break; - - case 0x10: - off=reg_bx+reg_si+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x11: - off=reg_bx+reg_di+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x12: - off=reg_bp+reg_si+Fetchws(); - seg_base=SegBase(ss); - break; - case 0x13: - off=reg_bp+reg_di+Fetchws(); - seg_base=SegBase(ss); - break; - case 0x14: - off=reg_si+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x15: - off=reg_di+Fetchws(); - seg_base=SegBase(ds); - break; - case 0x16: - off=reg_bp+Fetchws(); - seg_base=SegBase(ss); - break; - case 0x17: - off=reg_bx+Fetchws(); - seg_base=SegBase(ds); - break; - } - inst.rm_off=off; - if (inst.prefix & PREFIX_SEG) { - inst.rm_eaa=inst.seg.base+off; - } else { - inst.rm_eaa=seg_base+off; - } -} else { - - -#define SIB(MODE) { \ - Bitu sib=Fetchb(); \ - switch (sib&7) { \ - case 0:seg_base=SegBase(ds);off=reg_eax;break; \ - case 1:seg_base=SegBase(ds);off=reg_ecx;break; \ - case 2:seg_base=SegBase(ds);off=reg_edx;break; \ - case 3:seg_base=SegBase(ds);off=reg_ebx;break; \ - case 4:seg_base=SegBase(ss);off=reg_esp;break; \ - case 5:if (!MODE) { seg_base=SegBase(ds);off=Fetchd();break; \ - } else { seg_base=SegBase(ss);off=reg_ebp;break;} \ - case 6:seg_base=SegBase(ds);off=reg_esi;break; \ - case 7:seg_base=SegBase(ds);off=reg_edi;break; \ - } \ - off+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); \ -}; - static Bit32u SIBZero=0; - static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; - EAPoint seg_base; - Bit32u off; - switch ((inst.rm_mod<<3)|inst.rm_eai) { - case 0x00: - off=reg_eax; - seg_base=SegBase(ds); - break; - case 0x01: - off=reg_ecx; - seg_base=SegBase(ds); - break; - case 0x02: - off=reg_edx; - seg_base=SegBase(ds); - break; - case 0x03: - off=reg_ebx; - seg_base=SegBase(ds); - break; - case 0x04: - SIB(0); - break; - case 0x05: - off=Fetchd(); - seg_base=SegBase(ds); - break; - case 0x06: - off=reg_esi; - seg_base=SegBase(ds); - break; - case 0x07: - off=reg_edi; - seg_base=SegBase(ds); - break; - - case 0x08: - off=reg_eax+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x09: - off=reg_ecx+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0a: - off=reg_edx+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0b: - off=reg_ebx+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0c: - SIB(1); - off+=Fetchbs(); - break; - case 0x0d: - off=reg_ebp+Fetchbs(); - seg_base=SegBase(ss); - break; - case 0x0e: - off=reg_esi+Fetchbs(); - seg_base=SegBase(ds); - break; - case 0x0f: - off=reg_edi+Fetchbs(); - seg_base=SegBase(ds); - break; - - case 0x10: - off=reg_eax+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x11: - off=reg_ecx+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x12: - off=reg_edx+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x13: - off=reg_ebx+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x14: - SIB(1); - off+=Fetchds(); - break; - case 0x15: - off=reg_ebp+Fetchds(); - seg_base=SegBase(ss); - break; - case 0x16: - off=reg_esi+Fetchds(); - seg_base=SegBase(ds); - break; - case 0x17: - off=reg_edi+Fetchds(); - seg_base=SegBase(ds); - break; - } - inst.rm_off=off; - if (inst.prefix & PREFIX_SEG) { - inst.rm_eaa=inst.seg.base+off; - } else { - inst.rm_eaa=seg_base+off; - } -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/load.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/load.h deleted file mode 100644 index 699803cad..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/load.h +++ /dev/null @@ -1,514 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -switch (inst.code.load) { -/* General loading */ - case L_POPwRM: - inst_op1_w = Pop_16(); - goto case_L_MODRM; - case L_POPdRM: - inst_op1_d = Pop_32(); - goto case_L_MODRM; - case L_MODRM_NVM: - if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode; - goto case_L_MODRM; -case_L_MODRM: - case L_MODRM: - inst.rm=Fetchb(); - inst.rm_index=(inst.rm >> 3) & 7; - inst.rm_eai=inst.rm&07; - inst.rm_mod=inst.rm>>6; - /* Decode address of mod/rm if needed */ - if (inst.rm<0xc0) { - if (!(inst.prefix & PREFIX_ADDR)) - #include "ea_lookup.h" - } -l_MODRMswitch: - switch (inst.code.extra) { -/* Byte */ - case M_Ib: - inst_op1_d=Fetchb(); - break; - case M_Ebx: - if (inst.rm<0xc0) inst_op1_ds=(Bit8s)LoadMb(inst.rm_eaa); - else inst_op1_ds=(Bit8s)reg_8(inst.rm_eai); - break; - case M_EbIb: - inst_op2_d=Fetchb(); - case M_Eb: - if (inst.rm<0xc0) inst_op1_d=LoadMb(inst.rm_eaa); - else inst_op1_d=reg_8(inst.rm_eai); - break; - case M_EbGb: - if (inst.rm<0xc0) inst_op1_d=LoadMb(inst.rm_eaa); - else inst_op1_d=reg_8(inst.rm_eai); - inst_op2_d=reg_8(inst.rm_index); - break; - case M_GbEb: - if (inst.rm<0xc0) inst_op2_d=LoadMb(inst.rm_eaa); - else inst_op2_d=reg_8(inst.rm_eai); - case M_Gb: - inst_op1_d=reg_8(inst.rm_index);; - break; -/* Word */ - case M_Iw: - inst_op1_d=Fetchw(); - break; - case M_EwxGwx: - inst_op2_ds=(Bit16s)reg_16(inst.rm_index); - goto l_M_Ewx; - case M_EwxIbx: - inst_op2_ds=Fetchbs(); - goto l_M_Ewx; - case M_EwxIwx: - inst_op2_ds=Fetchws(); -l_M_Ewx: - case M_Ewx: - if (inst.rm<0xc0) inst_op1_ds=(Bit16s)LoadMw(inst.rm_eaa); - else inst_op1_ds=(Bit16s)reg_16(inst.rm_eai); - break; - case M_EwIb: - inst_op2_d=Fetchb(); - goto l_M_Ew; - case M_EwIbx: - inst_op2_ds=Fetchbs(); - goto l_M_Ew; - case M_EwIw: - inst_op2_d=Fetchw(); - goto l_M_Ew; - case M_EwGwCL: - inst_imm_d=reg_cl; - goto l_M_EwGw; - case M_EwGwIb: - inst_imm_d=Fetchb(); - goto l_M_EwGw; - case M_EwGwt: - inst_op2_d=reg_16(inst.rm_index); - inst.rm_eaa+=((Bit16s)inst_op2_d >> 4) * 2; - goto l_M_Ew; -l_M_EwGw: - case M_EwGw: - inst_op2_d=reg_16(inst.rm_index); -l_M_Ew: - case M_Ew: - if (inst.rm<0xc0) inst_op1_d=LoadMw(inst.rm_eaa); - else inst_op1_d=reg_16(inst.rm_eai); - break; - case M_GwEw: - if (inst.rm<0xc0) inst_op2_d=LoadMw(inst.rm_eaa); - else inst_op2_d=reg_16(inst.rm_eai); - case M_Gw: - inst_op1_d=reg_16(inst.rm_index);; - break; -/* DWord */ - case M_Id: - inst_op1_d=Fetchd(); - break; - case M_EdxGdx: - inst_op2_ds=(Bit32s)reg_32(inst.rm_index); - case M_Edx: - if (inst.rm<0xc0) inst_op1_d=(Bit32s)LoadMd(inst.rm_eaa); - else inst_op1_d=(Bit32s)reg_32(inst.rm_eai); - break; - case M_EdIb: - inst_op2_d=Fetchb(); - goto l_M_Ed; - case M_EdIbx: - inst_op2_ds=Fetchbs(); - goto l_M_Ed; - case M_EdId: - inst_op2_d=Fetchd(); - goto l_M_Ed; - case M_EdGdCL: - inst_imm_d=reg_cl; - goto l_M_EdGd; - case M_EdGdt: - inst_op2_d=reg_32(inst.rm_index); - inst.rm_eaa+=((Bit32s)inst_op2_d >> 5) * 4; - goto l_M_Ed; - case M_EdGdIb: - inst_imm_d=Fetchb(); - goto l_M_EdGd; -l_M_EdGd: - case M_EdGd: - inst_op2_d=reg_32(inst.rm_index); -l_M_Ed: - case M_Ed: - if (inst.rm<0xc0) inst_op1_d=LoadMd(inst.rm_eaa); - else inst_op1_d=reg_32(inst.rm_eai); - break; - case M_GdEd: - if (inst.rm<0xc0) inst_op2_d=LoadMd(inst.rm_eaa); - else inst_op2_d=reg_32(inst.rm_eai); - case M_Gd: - inst_op1_d=reg_32(inst.rm_index); - break; -/* Others */ - - case M_SEG: - //TODO Check for limit - inst_op1_d=SegValue((SegNames)inst.rm_index); - break; - case M_Efw: - if (inst.rm>=0xc0) goto illegalopcode; - inst_op1_d=LoadMw(inst.rm_eaa); - inst_op2_d=LoadMw(inst.rm_eaa+2); - break; - case M_Efd: - if (inst.rm>=0xc0) goto illegalopcode; - inst_op1_d=LoadMd(inst.rm_eaa); - inst_op2_d=LoadMw(inst.rm_eaa+4); - break; - case M_EA: - inst_op1_d=inst.rm_off; - break; - case M_POPw: - inst_op1_d = Pop_16(); - break; - case M_POPd: - inst_op1_d = Pop_32(); - break; - case M_GRP: - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case M_GRP_Ib: - inst_op2_d=Fetchb(); - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case M_GRP_CL: - inst_op2_d=reg_cl; - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case M_GRP_1: - inst_op2_d=1; - inst.code=Groups[inst.code.op][inst.rm_index]; - goto l_MODRMswitch; - case 0: - break; - default: - LOG(LOG_CPU,LOG_ERROR)("MODRM:Unhandled load %d entry %x",inst.code.extra,inst.entry); - break; - } - break; - case L_POPw: - inst_op1_d = Pop_16(); - break; - case L_POPd: - inst_op1_d = Pop_32(); - break; - case L_POPfw: - inst_op1_d = Pop_16(); - inst_op2_d = Pop_16(); - break; - case L_POPfd: - inst_op1_d = Pop_32(); - inst_op2_d = Pop_16(); - break; - case L_Ib: - inst_op1_d=Fetchb(); - break; - case L_Ibx: - inst_op1_ds=Fetchbs(); - break; - case L_Iw: - inst_op1_d=Fetchw(); - break; - case L_Iwx: - inst_op1_ds=Fetchws(); - break; - case L_Idx: - case L_Id: - inst_op1_d=Fetchd(); - break; - case L_Ifw: - inst_op1_d=Fetchw(); - inst_op2_d=Fetchw(); - break; - case L_Ifd: - inst_op1_d=Fetchd(); - inst_op2_d=Fetchw(); - break; -/* Direct load of registers */ - case L_REGbIb: - inst_op2_d=Fetchb(); - case L_REGb: - inst_op1_d=reg_8(inst.code.extra); - break; - case L_REGwIw: - inst_op2_d=Fetchw(); - case L_REGw: - inst_op1_d=reg_16(inst.code.extra); - break; - case L_REGdId: - inst_op2_d=Fetchd(); - case L_REGd: - inst_op1_d=reg_32(inst.code.extra); - break; - case L_SEG: - inst_op1_d=SegValue((SegNames)inst.code.extra); - break; -/* Depending on addressize */ - case L_OP: - if (inst.prefix & PREFIX_ADDR) { - inst.rm_eaa=Fetchd(); - } else { - inst.rm_eaa=Fetchw(); - } - if (inst.prefix & PREFIX_SEG) { - inst.rm_eaa+=inst.seg.base; - } else { - inst.rm_eaa+=SegBase(ds); - } - break; - /* Special cases */ - case L_DOUBLE: - inst.entry|=0x100; - goto restartopcode; - case L_PRESEG: - inst.prefix|=PREFIX_SEG; - inst.seg.base=SegBase((SegNames)inst.code.extra); - goto restartopcode; - case L_PREREPNE: - inst.prefix|=PREFIX_REP; - inst.repz=false; - goto restartopcode; - case L_PREREP: - inst.prefix|=PREFIX_REP; - inst.repz=true; - goto restartopcode; - case L_PREOP: - inst.entry=(cpu.code.big ^1) * 0x200; - goto restartopcode; - case L_PREADD: - inst.prefix=(inst.prefix & ~1) | (cpu.code.big ^ 1); - goto restartopcode; - case L_VAL: - inst_op1_d=inst.code.extra; - break; - case L_INTO: - if (!get_OF()) goto nextopcode; - inst_op1_d=4; - break; - case D_IRETw: - CPU_IRET(false,GetIP()); - if (GETFLAG(IF) && PIC_IRQCheck) { - return CBRET_NONE; - } - continue; - case D_IRETd: - CPU_IRET(true,GetIP()); - if (GETFLAG(IF) && PIC_IRQCheck) - return CBRET_NONE; - continue; - case D_RETFwIw: - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(false,words,GetIP()); - continue; - } - case D_RETFw: - FillFlags(); - CPU_RET(false,0,GetIP()); - continue; - case D_RETFdIw: - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(true,words,GetIP()); - continue; - } - case D_RETFd: - FillFlags(); - CPU_RET(true,0,GetIP()); - continue; -/* Direct operations */ - case L_STRING: - #include "string.h" - goto nextopcode; - case D_PUSHAw: - { - Bit16u old_sp=reg_sp; - Push_16(reg_ax);Push_16(reg_cx);Push_16(reg_dx);Push_16(reg_bx); - Push_16(old_sp);Push_16(reg_bp);Push_16(reg_si);Push_16(reg_di); - } - goto nextopcode; - case D_PUSHAd: - { - Bit32u old_esp=reg_esp; - Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx); - Push_32(old_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi); - } - goto nextopcode; - case D_POPAw: - reg_di=Pop_16();reg_si=Pop_16();reg_bp=Pop_16();Pop_16();//Don't save SP - reg_bx=Pop_16();reg_dx=Pop_16();reg_cx=Pop_16();reg_ax=Pop_16(); - goto nextopcode; - case D_POPAd: - reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP - reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32(); - goto nextopcode; - case D_POPSEGw: - if (CPU_PopSeg((SegNames)inst.code.extra,false)) RunException(); - goto nextopcode; - case D_POPSEGd: - if (CPU_PopSeg((SegNames)inst.code.extra,true)) RunException(); - goto nextopcode; - case D_SETALC: - reg_al = get_CF() ? 0xFF : 0; - goto nextopcode; - case D_XLAT: - if (inst.prefix & PREFIX_SEG) { - if (inst.prefix & PREFIX_ADDR) { - reg_al=LoadMb(inst.seg.base+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(inst.seg.base+(Bit16u)(reg_bx+reg_al)); - } - } else { - if (inst.prefix & PREFIX_ADDR) { - reg_al=LoadMb(SegBase(ds)+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al)); - } - } - goto nextopcode; - case D_CBW: - reg_ax=(Bit8s)reg_al; - goto nextopcode; - case D_CWDE: - reg_eax=(Bit16s)reg_ax; - goto nextopcode; - case D_CWD: - if (reg_ax & 0x8000) reg_dx=0xffff; - else reg_dx=0; - goto nextopcode; - case D_CDQ: - if (reg_eax & 0x80000000) reg_edx=0xffffffff; - else reg_edx=0; - goto nextopcode; - case D_CLI: - if (CPU_CLI()) RunException(); - goto nextopcode; - case D_STI: - if (CPU_STI()) RunException(); - goto nextopcode; - case D_STC: - FillFlags();SETFLAGBIT(CF,true); - goto nextopcode; - case D_CLC: - FillFlags();SETFLAGBIT(CF,false); - goto nextopcode; - case D_CMC: - FillFlags(); - SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); - goto nextopcode; - case D_CLD: - SETFLAGBIT(DF,false); - cpu.direction=1; - goto nextopcode; - case D_STD: - SETFLAGBIT(DF,true); - cpu.direction=-1; - goto nextopcode; - case D_PUSHF: - if (CPU_PUSHF(inst.code.extra)) RunException(); - goto nextopcode; - case D_POPF: - if (CPU_POPF(inst.code.extra)) RunException(); - if (GETFLAG(IF) && PIC_IRQCheck) { - SaveIP(); - return CBRET_NONE; - } - goto nextopcode; - case D_SAHF: - SETFLAGSb(reg_ah); - goto nextopcode; - case D_LAHF: - FillFlags(); - reg_ah=reg_flags&0xff; - goto nextopcode; - case D_WAIT: - case D_NOP: - goto nextopcode; - case D_LOCK: /* FIXME: according to intel, LOCK should raise an exception if it's not followed by one of a small set of instructions; - probably doesn't matter for our purposes as it is a pentium prefix anyhow */ - LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); - goto nextopcode; - case D_ENTERw: - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(false,bytes,level); - goto nextopcode; - } - case D_ENTERd: - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(true,bytes,level); - goto nextopcode; - } - case D_LEAVEw: - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_bp=Pop_16(); - goto nextopcode; - case D_LEAVEd: - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_ebp=Pop_32(); - goto nextopcode; - case D_DAA: - DAA(); - goto nextopcode; - case D_DAS: - DAS(); - goto nextopcode; - case D_AAA: - AAA(); - goto nextopcode; - case D_AAS: - AAS(); - goto nextopcode; - case D_CPUID: - if (!CPU_CPUID()) goto illegalopcode; - goto nextopcode; - case D_HLT: - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - FillFlags(); - CPU_HLT(GetIP()); - return CBRET_NONE; - case D_CLTS: - if (cpu.pmode && cpu.cpl) goto illegalopcode; - cpu.cr0&=(~CR0_TASKSWITCH); - goto nextopcode; - case D_ICEBP: - CPU_SW_Interrupt_NoIOPLCheck(1,GetIP()); - continue; - case D_RDTSC: { - if (CPU_ArchitectureType>32); - reg_eax=(Bit32u)(tsc&0xffffffff); - break; - } - default: - LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry); - goto illegalopcode; -} - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/loadwrite.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/loadwrite.h deleted file mode 100644 index b00ffb6c0..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/loadwrite.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#define SaveIP() reg_eip=(Bit32u)(inst.cseip-SegBase(cs)); -#define LoadIP() inst.cseip=SegBase(cs)+reg_eip; -#define GetIP() (inst.cseip-SegBase(cs)) - -#define RunException() { \ - CPU_Exception(cpu.exception.which,cpu.exception.error); \ - continue; \ -} - -static INLINE Bit8u the_Fetchb(EAPoint & loc) { - Bit8u temp=LoadMb(loc); - loc+=1; - return temp; -} - -static INLINE Bit16u the_Fetchw(EAPoint & loc) { - Bit16u temp=LoadMw(loc); - loc+=2; - return temp; -} -static INLINE Bit32u the_Fetchd(EAPoint & loc) { - Bit32u temp=LoadMd(loc); - loc+=4; - return temp; -} - -#define Fetchb() the_Fetchb(inst.cseip) -#define Fetchw() the_Fetchw(inst.cseip) -#define Fetchd() the_Fetchd(inst.cseip) - -#define Fetchbs() (Bit8s)the_Fetchb(inst.cseip) -#define Fetchws() (Bit16s)the_Fetchw(inst.cseip) -#define Fetchds() (Bit32s)the_Fetchd(inst.cseip) - -#define Push_16 CPU_Push16 -#define Push_32 CPU_Push32 -#define Pop_16 CPU_Pop16 -#define Pop_32 CPU_Pop32 - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/op.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/op.h deleted file mode 100644 index 14786b1f1..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/op.h +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Do the actual opcode */ -switch (inst.code.op) { - case t_ADDb: case t_ADDw: case t_ADDd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d + lf_var2d; - lflags.type=inst.code.op; - break; - case t_CMPb: case t_CMPw: case t_CMPd: - case t_SUBb: case t_SUBw: case t_SUBd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d - lf_var2d; - lflags.type=inst.code.op; - break; - case t_ORb: case t_ORw: case t_ORd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d | lf_var2d; - lflags.type=inst.code.op; - break; - case t_XORb: case t_XORw: case t_XORd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d ^ lf_var2d; - lflags.type=inst.code.op; - break; - case t_TESTb: case t_TESTw: case t_TESTd: - case t_ANDb: case t_ANDw: case t_ANDd: - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d & lf_var2d; - lflags.type=inst.code.op; - break; - case t_ADCb: case t_ADCw: case t_ADCd: - lflags.oldcf=(get_CF()!=0); - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf; - lflags.type=inst.code.op; - break; - case t_SBBb: case t_SBBw: case t_SBBd: - lflags.oldcf=(get_CF()!=0); - lf_var1d=inst_op1_d; - lf_var2d=inst_op2_d; - inst_op1_d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf; - lflags.type=inst.code.op; - break; - case t_INCb: case t_INCw: case t_INCd: - LoadCF; - lf_var1d=inst_op1_d; - inst_op1_d=lf_resd=inst_op1_d+1; - lflags.type=inst.code.op; - break; - case t_DECb: case t_DECw: case t_DECd: - LoadCF; - lf_var1d=inst_op1_d; - inst_op1_d=lf_resd=inst_op1_d-1; - lflags.type=inst.code.op; - break; -/* Using the instructions.h defines */ - case t_ROLb: - ROLB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_ROLw: - ROLW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_ROLd: - ROLD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_RORb: - RORB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_RORw: - RORW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_RORd: - RORD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_RCLb: - RCLB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_RCLw: - RCLW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_RCLd: - RCLD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_RCRb: - RCRB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_RCRw: - RCRW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_RCRd: - RCRD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_SHLb: - SHLB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_SHLw: - SHLW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_SHLd: - SHLD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_SHRb: - SHRB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_SHRw: - SHRW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_SHRd: - SHRD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case t_SARb: - SARB(inst_op1_b,inst_op2_b,LoadD,SaveD); - break; - case t_SARw: - SARW(inst_op1_w,inst_op2_b,LoadD,SaveD); - break; - case t_SARd: - SARD(inst_op1_d,inst_op2_b,LoadD,SaveD); - break; - - case O_DSHLw: - { - DSHLW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); - break; - } - case O_DSHRw: - { - DSHRW(inst_op1_w,inst_op2_w,inst_imm_b,LoadD,SaveD); - break; - } - case O_DSHLd: - { - DSHLD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); - break; - } - case O_DSHRd: - { - DSHRD(inst_op1_d,inst_op2_d,inst_imm_b,LoadD,SaveD); - break; - } - - case t_NEGb: - lf_var1b=inst_op1_b; - inst_op1_b=lf_resb=0-inst_op1_b; - lflags.type=t_NEGb; - break; - case t_NEGw: - lf_var1w=inst_op1_w; - inst_op1_w=lf_resw=0-inst_op1_w; - lflags.type=t_NEGw; - break; - case t_NEGd: - lf_var1d=inst_op1_d; - inst_op1_d=lf_resd=0-inst_op1_d; - lflags.type=t_NEGd; - break; - - case O_NOT: - inst_op1_d=~inst_op1_d; - break; - - /* Special instructions */ - case O_IMULRw: - DIMULW(inst_op1_ws,inst_op1_ws,inst_op2_ws,LoadD,SaveD); - break; - case O_IMULRd: - DIMULD(inst_op1_ds,inst_op1_ds,inst_op2_ds,LoadD,SaveD); - break; - case O_MULb: - MULB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_MULw: - MULW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_MULd: - MULD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_IMULb: - IMULB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_IMULw: - IMULW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_IMULd: - IMULD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_DIVb: - DIVB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_DIVw: - DIVW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_DIVd: - DIVD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_IDIVb: - IDIVB(inst_op1_b,LoadD,0); - goto nextopcode; - case O_IDIVw: - IDIVW(inst_op1_w,LoadD,0); - goto nextopcode; - case O_IDIVd: - IDIVD(inst_op1_d,LoadD,0); - goto nextopcode; - case O_AAM: - AAM(inst_op1_b); - goto nextopcode; - case O_AAD: - AAD(inst_op1_b); - goto nextopcode; - - case O_C_O: inst.cond=TFLG_O; break; - case O_C_NO: inst.cond=TFLG_NO; break; - case O_C_B: inst.cond=TFLG_B; break; - case O_C_NB: inst.cond=TFLG_NB; break; - case O_C_Z: inst.cond=TFLG_Z; break; - case O_C_NZ: inst.cond=TFLG_NZ; break; - case O_C_BE: inst.cond=TFLG_BE; break; - case O_C_NBE: inst.cond=TFLG_NBE; break; - case O_C_S: inst.cond=TFLG_S; break; - case O_C_NS: inst.cond=TFLG_NS; break; - case O_C_P: inst.cond=TFLG_P; break; - case O_C_NP: inst.cond=TFLG_NP; break; - case O_C_L: inst.cond=TFLG_L; break; - case O_C_NL: inst.cond=TFLG_NL; break; - case O_C_LE: inst.cond=TFLG_LE; break; - case O_C_NLE: inst.cond=TFLG_NLE; break; - - case O_ALOP: - reg_al=LoadMb(inst.rm_eaa); - goto nextopcode; - case O_AXOP: - reg_ax=LoadMw(inst.rm_eaa); - goto nextopcode; - case O_EAXOP: - reg_eax=LoadMd(inst.rm_eaa); - goto nextopcode; - case O_OPAL: - SaveMb(inst.rm_eaa,reg_al); - goto nextopcode; - case O_OPAX: - SaveMw(inst.rm_eaa,reg_ax); - goto nextopcode; - case O_OPEAX: - SaveMd(inst.rm_eaa,reg_eax); - goto nextopcode; - case O_SEGDS: - inst.code.extra=ds; - break; - case O_SEGES: - inst.code.extra=es; - break; - case O_SEGFS: - inst.code.extra=fs; - break; - case O_SEGGS: - inst.code.extra=gs; - break; - case O_SEGSS: - inst.code.extra=ss; - break; - - case O_LOOP: - if (inst.prefix & PREFIX_ADDR) { - if (--reg_ecx) break; - } else { - if (--reg_cx) break; - } - goto nextopcode; - case O_LOOPZ: - if (inst.prefix & PREFIX_ADDR) { - if (--reg_ecx && get_ZF()) break; - } else { - if (--reg_cx && get_ZF()) break; - } - goto nextopcode; - case O_LOOPNZ: - if (inst.prefix & PREFIX_ADDR) { - if (--reg_ecx && !get_ZF()) break; - } else { - if (--reg_cx && !get_ZF()) break; - } - goto nextopcode; - case O_JCXZ: - if (inst.prefix & PREFIX_ADDR) { - if (reg_ecx) goto nextopcode; - } else { - if (reg_cx) goto nextopcode; - } - break; - case O_XCHG_AX: - { - Bit16u temp=reg_ax; - reg_ax=inst_op1_w; - inst_op1_w=temp; - break; - } - case O_XCHG_EAX: - { - Bit32u temp=reg_eax; - reg_eax=inst_op1_d; - inst_op1_d=temp; - break; - } - case O_CALLNw: - SaveIP(); - Push_16(reg_ip); - break; - case O_CALLNd: - SaveIP(); - Push_32(reg_eip); - break; - case O_CALLFw: - FillFlags(); - CPU_CALL(false,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_CALLFd: - FillFlags(); - CPU_CALL(true,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_JMPFw: - FillFlags(); - CPU_JMP(false,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_JMPFd: - FillFlags(); - CPU_JMP(true,inst_op2_d,inst_op1_d,GetIP()); - continue; - case O_INT: -#if C_DEBUG - FillFlags(); - if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) - return debugCallback; - else if (DEBUG_IntBreakpoint(inst_op1_b)) - return debugCallback; -#endif - CPU_SW_Interrupt(inst_op1_b,GetIP()); - continue; - case O_INb: - if (CPU_IO_Exception(inst_op1_d,1)) RunException(); - reg_al=IO_ReadB(inst_op1_d); - goto nextopcode; - case O_INw: - if (CPU_IO_Exception(inst_op1_d,2)) RunException(); - reg_ax=IO_ReadW(inst_op1_d); - goto nextopcode; - case O_INd: - if (CPU_IO_Exception(inst_op1_d,4)) RunException(); - reg_eax=IO_ReadD(inst_op1_d); - goto nextopcode; - case O_OUTb: - if (CPU_IO_Exception(inst_op1_d,1)) RunException(); - IO_WriteB(inst_op1_d,reg_al); - goto nextopcode; - case O_OUTw: - if (CPU_IO_Exception(inst_op1_d,2)) RunException(); - IO_WriteW(inst_op1_d,reg_ax); - goto nextopcode; - case O_OUTd: - if (CPU_IO_Exception(inst_op1_d,4)) RunException(); - IO_WriteD(inst_op1_d,reg_eax); - goto nextopcode; - case O_CBACK: - FillFlags();SaveIP(); - return inst_op1_d; - case O_GRP6w: - case O_GRP6d: - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode; - switch (inst.rm_index) { - case 0x00: /* SLDT */ - inst_op1_d=(Bit32u)CPU_SLDT(); - break; - case 0x01: /* STR */ - inst_op1_d=(Bit32u)CPU_STR(); - break; - case 0x02: /* LLDT */ - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LLDT(inst_op1_d)) RunException(); - goto nextopcode; /* Else value will saved */ - case 0x03: /* LTR */ - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LTR(inst_op1_d)) RunException(); - goto nextopcode; /* Else value will saved */ - case 0x04: /* VERR */ - CPU_VERR(inst_op1_d); - goto nextopcode; /* Else value will saved */ - case 0x05: /* VERW */ - CPU_VERW(inst_op1_d); - goto nextopcode; /* Else value will saved */ - default: - LOG(LOG_CPU,LOG_ERROR)("Group 6 Illegal subfunction %X",inst.rm_index); - goto illegalopcode; - } - break; - case O_GRP7w: - case O_GRP7d: - switch (inst.rm_index) { - case 0: /* SGDT */ - SaveMw(inst.rm_eaa,CPU_SGDT_limit()); - SaveMd(inst.rm_eaa+2,CPU_SGDT_base()); - goto nextopcode; - case 1: /* SIDT */ - SaveMw(inst.rm_eaa,CPU_SIDT_limit()); - SaveMd(inst.rm_eaa+2,CPU_SIDT_base()); - goto nextopcode; - case 2: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LGDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); - goto nextopcode; - case 3: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LIDT(LoadMw(inst.rm_eaa),LoadMd(inst.rm_eaa+2)&((inst.code.op == O_GRP7w) ? 0xFFFFFF : 0xFFFFFFFF)); - goto nextopcode; - case 4: /* SMSW */ - inst_op1_d=CPU_SMSW(); - break; - case 6: /* LMSW */ - FillFlags(); - if (CPU_LMSW(inst_op1_w)) RunException(); - goto nextopcode; - case 7: /* INVLPG */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - FillFlags(); - PAGING_ClearTLB(); - goto nextopcode; - default: - LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index); - goto illegalopcode; - } - break; - case O_M_CRx_Rd: - if (CPU_WRITE_CRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_Rd_CRx: - if (CPU_READ_CRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_DRx_Rd: - if (CPU_WRITE_DRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_Rd_DRx: - if (CPU_READ_DRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_TRx_Rd: - if (CPU_WRITE_TRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_M_Rd_TRx: - if (CPU_READ_TRX(inst.rm_index,inst_op1_d)) RunException(); - break; - case O_LAR: - { - Bitu ar=inst_op2_d; - CPU_LAR(inst_op1_w,ar); - inst_op1_d=(Bit32u)ar; - } - break; - case O_LSL: - { - Bitu limit=inst_op2_d; - CPU_LSL(inst_op1_w,limit); - inst_op1_d=(Bit32u)limit; - } - break; - case O_ARPL: - { - Bitu new_sel=inst_op1_d; - CPU_ARPL(new_sel,inst_op2_d); - inst_op1_d=(Bit32u)new_sel; - } - break; - case O_BSFw: - { - FillFlags(); - if (!inst_op1_w) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=0; - while (1) { - if (inst_op1_w & 0x1) break; - count++;inst_op1_w>>=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BSFd: - { - FillFlags(); - if (!inst_op1_d) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=0; - while (1) { - if (inst_op1_d & 0x1) break; - count++;inst_op1_d>>=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BSRw: - { - FillFlags(); - if (!inst_op1_w) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=15; - while (1) { - if (inst_op1_w & 0x8000) break; - count--;inst_op1_w<<=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BSRd: - { - FillFlags(); - if (!inst_op1_d) { - SETFLAGBIT(ZF,true); - goto nextopcode; - } else { - Bitu count=31; - while (1) { - if (inst_op1_d & 0x80000000) break; - count--;inst_op1_d<<=1; - } - inst_op1_d=count; - SETFLAGBIT(ZF,false); - } - } - break; - case O_BTw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - break; - case O_BTSw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - inst_op1_d|=(1 << (inst_op2_d & 15)); - break; - case O_BTCw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - inst_op1_d^=(1 << (inst_op2_d & 15)); - break; - case O_BTRw: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 15)))); - inst_op1_d&=~(1 << (inst_op2_d & 15)); - break; - case O_BTd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - break; - case O_BTSd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - inst_op1_d|=(1 << (inst_op2_d & 31)); - break; - case O_BTCd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - inst_op1_d^=(1 << (inst_op2_d & 31)); - break; - case O_BTRd: - FillFlags(); - SETFLAGBIT(CF,(inst_op1_d & (1 << (inst_op2_d & 31)))); - inst_op1_d&=~(1 << (inst_op2_d & 31)); - break; - case O_BSWAPw: - if (CPU_ArchitectureType=0xc0) << 3) | inst.code.save) { - case 0x00: FPU_ESC0_EA(inst.rm,inst.rm_eaa);break; - case 0x01: FPU_ESC1_EA(inst.rm,inst.rm_eaa);break; - case 0x02: FPU_ESC2_EA(inst.rm,inst.rm_eaa);break; - case 0x03: FPU_ESC3_EA(inst.rm,inst.rm_eaa);break; - case 0x04: FPU_ESC4_EA(inst.rm,inst.rm_eaa);break; - case 0x05: FPU_ESC5_EA(inst.rm,inst.rm_eaa);break; - case 0x06: FPU_ESC6_EA(inst.rm,inst.rm_eaa);break; - case 0x07: FPU_ESC7_EA(inst.rm,inst.rm_eaa);break; - - case 0x08: FPU_ESC0_Normal(inst.rm);break; - case 0x09: FPU_ESC1_Normal(inst.rm);break; - case 0x0a: FPU_ESC2_Normal(inst.rm);break; - case 0x0b: FPU_ESC3_Normal(inst.rm);break; - case 0x0c: FPU_ESC4_Normal(inst.rm);break; - case 0x0d: FPU_ESC5_Normal(inst.rm);break; - case 0x0e: FPU_ESC6_Normal(inst.rm);break; - case 0x0f: FPU_ESC7_Normal(inst.rm);break; - } - goto nextopcode; -#else - LOG(LOG_CPU,LOG_ERROR)("Unhandled FPU ESCAPE %d",inst.code.save); - goto nextopcode; -#endif - case O_BOUNDw: - { - Bit16s bound_min, bound_max; - bound_min=LoadMw(inst.rm_eaa); - bound_max=LoadMw(inst.rm_eaa+2); - if ( (((Bit16s)inst_op1_w) < bound_min) || (((Bit16s)inst_op1_w) > bound_max) ) { - EXCEPTION(5); - } - } - break; - case 0: - break; - default: - LOG(LOG_CPU,LOG_ERROR)("OP:Unhandled code %d entry %X",inst.code.op,inst.entry); - -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/optable.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/optable.h deleted file mode 100644 index b5680e5d5..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/optable.h +++ /dev/null @@ -1,832 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Big ass opcode table normal,double, 66 normal, 66 double */ -static OpCode OpCodeTable[1024]={ -/* 0x00 - 0x07 */ -{L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADDw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,es },{D_POPSEGw,0 ,0 ,es }, -/* 0x08 - 0x0f */ -{L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ORb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ORw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,cs },{L_DOUBLE ,0 ,0 ,0 }, - -/* 0x10 - 0x17 */ -{L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADCw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ss },{D_POPSEGw,0 ,0 ,ss }, -/* 0x18 - 0x1f */ -{L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGwIw ,t_SBBw ,S_REGw ,REGI_AX }, -{L_SEG ,0 ,S_PUSHw,ds },{D_POPSEGw,0 ,0 ,ds }, - -/* 0x20 - 0x27 */ -{L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_ANDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ANDw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_ANDb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ANDw ,S_REGw ,REGI_AX }, -{L_PRESEG ,0 ,0 ,es },{D_DAA ,0 ,0 ,0 }, -/* 0x28 - 0x2f */ -{L_MODRM ,t_SUBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SUBw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_SUBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SUBw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_SUBb ,S_REGb ,REGI_AL },{L_REGwIw ,t_SUBw ,S_REGw ,REGI_AX }, -{L_PRESEG ,0 ,0 ,cs },{D_DAS ,0 ,0 ,0 }, - -/* 0x30 - 0x37 */ -{L_MODRM ,t_XORb ,S_Eb ,M_EbGb },{L_MODRM ,t_XORw ,S_Ew ,M_EwGw }, -{L_MODRM ,t_XORb ,S_Gb ,M_GbEb },{L_MODRM ,t_XORw ,S_Gw ,M_GwEw }, -{L_REGbIb ,t_XORb ,S_REGb ,REGI_AL },{L_REGwIw ,t_XORw ,S_REGw ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ss },{D_AAA ,0 ,0 ,0 }, -/* 0x38 - 0x3f */ -{L_MODRM ,t_CMPb ,0 ,M_EbGb },{L_MODRM ,t_CMPw ,0 ,M_EwGw }, -{L_MODRM ,t_CMPb ,0 ,M_GbEb },{L_MODRM ,t_CMPw ,0 ,M_GwEw }, -{L_REGbIb ,t_CMPb ,0 ,REGI_AL },{L_REGwIw ,t_CMPw ,0 ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ds },{D_AAS ,0 ,0 ,0 }, - -/* 0x40 - 0x47 */ -{L_REGw ,t_INCw ,S_REGw ,REGI_AX},{L_REGw ,t_INCw ,S_REGw ,REGI_CX}, -{L_REGw ,t_INCw ,S_REGw ,REGI_DX},{L_REGw ,t_INCw ,S_REGw ,REGI_BX}, -{L_REGw ,t_INCw ,S_REGw ,REGI_SP},{L_REGw ,t_INCw ,S_REGw ,REGI_BP}, -{L_REGw ,t_INCw ,S_REGw ,REGI_SI},{L_REGw ,t_INCw ,S_REGw ,REGI_DI}, -/* 0x48 - 0x4f */ -{L_REGw ,t_DECw ,S_REGw ,REGI_AX},{L_REGw ,t_DECw ,S_REGw ,REGI_CX}, -{L_REGw ,t_DECw ,S_REGw ,REGI_DX},{L_REGw ,t_DECw ,S_REGw ,REGI_BX}, -{L_REGw ,t_DECw ,S_REGw ,REGI_SP},{L_REGw ,t_DECw ,S_REGw ,REGI_BP}, -{L_REGw ,t_DECw ,S_REGw ,REGI_SI},{L_REGw ,t_DECw ,S_REGw ,REGI_DI}, - -/* 0x50 - 0x57 */ -{L_REGw ,0 ,S_PUSHw,REGI_AX},{L_REGw ,0 ,S_PUSHw,REGI_CX}, -{L_REGw ,0 ,S_PUSHw,REGI_DX},{L_REGw ,0 ,S_PUSHw,REGI_BX}, -{L_REGw ,0 ,S_PUSHw,REGI_SP},{L_REGw ,0 ,S_PUSHw,REGI_BP}, -{L_REGw ,0 ,S_PUSHw,REGI_SI},{L_REGw ,0 ,S_PUSHw,REGI_DI}, -/* 0x58 - 0x5f */ -{L_POPw ,0 ,S_REGw ,REGI_AX},{L_POPw ,0 ,S_REGw ,REGI_CX}, -{L_POPw ,0 ,S_REGw ,REGI_DX},{L_POPw ,0 ,S_REGw ,REGI_BX}, -{L_POPw ,0 ,S_REGw ,REGI_SP},{L_POPw ,0 ,S_REGw ,REGI_BP}, -{L_POPw ,0 ,S_REGw ,REGI_SI},{L_POPw ,0 ,S_REGw ,REGI_DI}, - - -/* 0x60 - 0x67 */ -{D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDw ,0 ,M_Gw },{L_MODRM_NVM ,O_ARPL ,S_Ew ,M_EwGw }, -{L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, -{L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, -/* 0x68 - 0x6f */ -{L_Iw ,0 ,S_PUSHw,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxIwx}, -{L_Ibx ,0 ,S_PUSHw,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxIbx}, -{L_STRING ,R_INSB ,0 ,0 },{L_STRING ,R_INSW ,0 ,0 }, -{L_STRING ,R_OUTSB ,0 ,0 },{L_STRING ,R_OUTSW ,0 ,0 }, - - -/* 0x70 - 0x77 */ -{L_Ibx ,O_C_O ,S_C_AIPw,0 },{L_Ibx ,O_C_NO ,S_C_AIPw,0 }, -{L_Ibx ,O_C_B ,S_C_AIPw,0 },{L_Ibx ,O_C_NB ,S_C_AIPw,0 }, -{L_Ibx ,O_C_Z ,S_C_AIPw,0 },{L_Ibx ,O_C_NZ ,S_C_AIPw,0 }, -{L_Ibx ,O_C_BE ,S_C_AIPw,0 },{L_Ibx ,O_C_NBE ,S_C_AIPw,0 }, -/* 0x78 - 0x7f */ -{L_Ibx ,O_C_S ,S_C_AIPw,0 },{L_Ibx ,O_C_NS ,S_C_AIPw,0 }, -{L_Ibx ,O_C_P ,S_C_AIPw,0 },{L_Ibx ,O_C_NP ,S_C_AIPw,0 }, -{L_Ibx ,O_C_L ,S_C_AIPw,0 },{L_Ibx ,O_C_NL ,S_C_AIPw,0 }, -{L_Ibx ,O_C_LE ,S_C_AIPw,0 },{L_Ibx ,O_C_NLE ,S_C_AIPw,0 }, - - -/* 0x80 - 0x87 */ -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,1 ,0 ,M_GRP }, -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,3 ,0 ,M_GRP }, -{L_MODRM ,t_TESTb ,0 ,M_EbGb },{L_MODRM ,t_TESTw ,0 ,M_EwGw }, -{L_MODRM ,0 ,S_EbGb ,M_GbEb },{L_MODRM ,0 ,S_EwGw ,M_GwEw }, -/* 0x88 - 0x8f */ -{L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ew ,M_Gw }, -{L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, -{L_MODRM ,0 ,S_Ew ,M_SEG },{L_MODRM ,0 ,S_Gw ,M_EA }, -{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPwRM ,0 ,S_Ew ,M_None }, - -/* 0x90 - 0x97 */ -{D_NOP ,0 ,0 ,0 },{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_CX}, -{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_DX},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_BX}, -{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_SP},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_BP}, -{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_SI},{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_DI}, -/* 0x98 - 0x9f */ -{D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 }, -{L_Ifw ,O_CALLFw ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, -{D_PUSHF ,0 ,0 ,0 },{D_POPF ,0 ,0 ,0 }, -{D_SAHF ,0 ,0 ,0 },{D_LAHF ,0 ,0 ,0 }, - - -/* 0xa0 - 0xa7 */ -{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_AXOP ,0 ,0 }, -{L_OP ,O_OPAL ,0 ,0 },{L_OP ,O_OPAX ,0 ,0 }, -{L_STRING ,R_MOVSB ,0 ,0 },{L_STRING ,R_MOVSW ,0 ,0 }, -{L_STRING ,R_CMPSB ,0 ,0 },{L_STRING ,R_CMPSW ,0 ,0 }, -/* 0xa8 - 0xaf */ -{L_REGbIb ,t_TESTb ,0 ,REGI_AL},{L_REGwIw ,t_TESTw ,0 ,REGI_AX}, -{L_STRING ,R_STOSB ,0 ,0 },{L_STRING ,R_STOSW ,0 ,0 }, -{L_STRING ,R_LODSB ,0 ,0 },{L_STRING ,R_LODSW ,0 ,0 }, -{L_STRING ,R_SCASB ,0 ,0 },{L_STRING ,R_SCASW ,0 ,0 }, - -/* 0xb0 - 0xb7 */ -{L_Ib ,0 ,S_REGb ,REGI_AL},{L_Ib ,0 ,S_REGb ,REGI_CL}, -{L_Ib ,0 ,S_REGb ,REGI_DL},{L_Ib ,0 ,S_REGb ,REGI_BL}, -{L_Ib ,0 ,S_REGb ,REGI_AH},{L_Ib ,0 ,S_REGb ,REGI_CH}, -{L_Ib ,0 ,S_REGb ,REGI_DH},{L_Ib ,0 ,S_REGb ,REGI_BH}, -/* 0xb8 - 0xbf */ -{L_Iw ,0 ,S_REGw ,REGI_AX},{L_Iw ,0 ,S_REGw ,REGI_CX}, -{L_Iw ,0 ,S_REGw ,REGI_DX},{L_Iw ,0 ,S_REGw ,REGI_BX}, -{L_Iw ,0 ,S_REGw ,REGI_SP},{L_Iw ,0 ,S_REGw ,REGI_BP}, -{L_Iw ,0 ,S_REGw ,REGI_SI},{L_Iw ,0 ,S_REGw ,REGI_DI}, - -/* 0xc0 - 0xc7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,6 ,0 ,M_GRP_Ib }, -{L_POPw ,0 ,S_IPIw ,0 },{L_POPw ,0 ,S_IP ,0 }, -{L_MODRM ,O_SEGES ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGDS ,S_SEGGw,M_Efw }, -{L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ew ,M_Iw }, -/* 0xc8 - 0xcf */ -{D_ENTERw ,0 ,0 ,0 },{D_LEAVEw ,0 ,0 ,0 }, -{D_RETFwIw ,0 ,0 ,0 },{D_RETFw ,0 ,0 ,0 }, -{L_VAL ,O_INT ,0 ,3 },{L_Ib ,O_INT ,0 ,0 }, -{L_INTO ,O_INT ,0 ,0 },{D_IRETw ,0 ,0 ,0 }, - -/* 0xd0 - 0xd7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,6 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,6 ,0 ,M_GRP_CL }, -{L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, -{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, -//TODO FPU -/* 0xd8 - 0xdf */ -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, -{L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 }, -{L_MODRM ,O_FPU ,4 ,0 },{L_MODRM ,O_FPU ,5 ,0 }, -{L_MODRM ,O_FPU ,6 ,0 },{L_MODRM ,O_FPU ,7 ,0 }, - -/* 0xe0 - 0xe7 */ -{L_Ibx ,O_LOOPNZ ,S_AIPw ,0 },{L_Ibx ,O_LOOPZ ,S_AIPw ,0 }, -{L_Ibx ,O_LOOP ,S_AIPw ,0 },{L_Ibx ,O_JCXZ ,S_AIPw ,0 }, -{L_Ib ,O_INb ,0 ,0 },{L_Ib ,O_INw ,0 ,0 }, -{L_Ib ,O_OUTb ,0 ,0 },{L_Ib ,O_OUTw ,0 ,0 }, -/* 0xe8 - 0xef */ -{L_Iw ,O_CALLNw ,S_AIPw ,0 },{L_Iwx ,0 ,S_AIPw ,0 }, -{L_Ifw ,O_JMPFw ,0 ,0 },{L_Ibx ,0 ,S_AIPw ,0 }, -{L_REGw ,O_INb ,0 ,REGI_DX},{L_REGw ,O_INw ,0 ,REGI_DX}, -{L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTw ,0 ,REGI_DX}, - -/* 0xf0 - 0xf7 */ -{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, -{L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, -{D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, -{L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,9 ,0 ,M_GRP }, -/* 0xf8 - 0xff */ -{D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 }, -{D_CLI ,0 ,0 ,0 },{D_STI ,0 ,0 ,0 }, -{D_CLD ,0 ,0 ,0 },{D_STD ,0 ,0 ,0 }, -{L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xc ,0 ,M_GRP }, - -/* 0x100 - 0x107 */ -{L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, -{L_MODRM_NVM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM_NVM ,O_LSL ,S_Gw ,M_EwGw }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x108 - 0x10f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x110 - 0x117 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x118 - 0x11f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x120 - 0x127 */ -{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, -{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, -{L_MODRM ,O_M_Rd_TRx ,S_Ed ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_M_TRx_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, - -/* 0x128 - 0x12f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x130 - 0x137 */ -{0 ,0 ,0 ,0 },{D_RDTSC ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x138 - 0x13f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x140 - 0x147 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x148 - 0x14f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x150 - 0x157 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x158 - 0x15f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x160 - 0x167 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x168 - 0x16f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - - -/* 0x170 - 0x177 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x178 - 0x17f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x180 - 0x187 */ -{L_Iwx ,O_C_O ,S_C_AIPw,0 },{L_Iwx ,O_C_NO ,S_C_AIPw,0 }, -{L_Iwx ,O_C_B ,S_C_AIPw,0 },{L_Iwx ,O_C_NB ,S_C_AIPw,0 }, -{L_Iwx ,O_C_Z ,S_C_AIPw,0 },{L_Iwx ,O_C_NZ ,S_C_AIPw,0 }, -{L_Iwx ,O_C_BE ,S_C_AIPw,0 },{L_Iwx ,O_C_NBE ,S_C_AIPw,0 }, -/* 0x188 - 0x18f */ -{L_Iwx ,O_C_S ,S_C_AIPw,0 },{L_Iwx ,O_C_NS ,S_C_AIPw,0 }, -{L_Iwx ,O_C_P ,S_C_AIPw,0 },{L_Iwx ,O_C_NP ,S_C_AIPw,0 }, -{L_Iwx ,O_C_L ,S_C_AIPw,0 },{L_Iwx ,O_C_NL ,S_C_AIPw,0 }, -{L_Iwx ,O_C_LE ,S_C_AIPw,0 },{L_Iwx ,O_C_NLE ,S_C_AIPw,0 }, - -/* 0x190 - 0x197 */ -{L_MODRM ,O_C_O ,S_C_Eb,0 },{L_MODRM ,O_C_NO ,S_C_Eb,0 }, -{L_MODRM ,O_C_B ,S_C_Eb,0 },{L_MODRM ,O_C_NB ,S_C_Eb,0 }, -{L_MODRM ,O_C_Z ,S_C_Eb,0 },{L_MODRM ,O_C_NZ ,S_C_Eb,0 }, -{L_MODRM ,O_C_BE ,S_C_Eb,0 },{L_MODRM ,O_C_NBE ,S_C_Eb,0 }, -/* 0x198 - 0x19f */ -{L_MODRM ,O_C_S ,S_C_Eb,0 },{L_MODRM ,O_C_NS ,S_C_Eb,0 }, -{L_MODRM ,O_C_P ,S_C_Eb,0 },{L_MODRM ,O_C_NP ,S_C_Eb,0 }, -{L_MODRM ,O_C_L ,S_C_Eb,0 },{L_MODRM ,O_C_NL ,S_C_Eb,0 }, -{L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, - -/* 0x1a0 - 0x1a7 */ -{L_SEG ,0 ,S_PUSHw ,fs },{D_POPSEGw,0 ,0 ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1a8 - 0x1af */ -{L_SEG ,0 ,S_PUSHw ,gs },{D_POPSEGw,0 ,0 ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx }, - -/* 0x1b0 - 0x1b7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw }, -{L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew }, -/* 0x1b8 - 0x1bf */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,S_Ew ,M_EwGwt }, -{L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew }, -{L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx }, - -/* 0x1c0 - 0x1cc */ -{L_MODRM ,t_ADDb ,S_EbGb ,M_GbEb },{L_MODRM ,t_ADDw ,S_EwGw ,M_GwEw }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1c8 - 0x1cf */ -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_AX},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_CX}, -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_DX},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_BX}, -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_SP},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_BP}, -{L_REGw ,O_BSWAPw ,S_REGw ,REGI_SI},{L_REGw ,O_BSWAPw ,S_REGw ,REGI_DI}, - -/* 0x1d0 - 0x1d7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1d8 - 0x1df */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x1e0 - 0x1ee */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1e8 - 0x1ef */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x1f0 - 0x1fc */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x1f8 - 0x1ff */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - - -/* 0x200 - 0x207 */ -{L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADDd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,es },{D_POPSEGd,0 ,0 ,es }, -/* 0x208 - 0x20f */ -{L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ORb ,S_REGb ,REGI_AL },{L_REGdId ,t_ORd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,cs },{L_DOUBLE ,0 ,0 ,0 }, - -/* 0x210 - 0x217 */ -{L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADCd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,ss },{D_POPSEGd,0 ,0 ,ss }, -/* 0x218 - 0x21f */ -{L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGdId ,t_SBBd ,S_REGd ,REGI_AX }, -{L_SEG ,0 ,S_PUSHd,ds },{D_POPSEGd,0 ,0 ,ds }, - -/* 0x220 - 0x227 */ -{L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_ANDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ANDd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_ANDb ,S_REGb ,REGI_AL },{L_REGdId ,t_ANDd ,S_REGd ,REGI_AX }, -{L_PRESEG ,0 ,0 ,es },{D_DAA ,0 ,0 ,0 }, -/* 0x228 - 0x22f */ -{L_MODRM ,t_SUBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SUBd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_SUBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SUBd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_SUBb ,S_REGb ,REGI_AL },{L_REGdId ,t_SUBd ,S_REGd ,REGI_AX }, -{L_PRESEG ,0 ,0 ,cs },{D_DAS ,0 ,0 ,0 }, - -/* 0x230 - 0x237 */ -{L_MODRM ,t_XORb ,S_Eb ,M_EbGb },{L_MODRM ,t_XORd ,S_Ed ,M_EdGd }, -{L_MODRM ,t_XORb ,S_Gb ,M_GbEb },{L_MODRM ,t_XORd ,S_Gd ,M_GdEd }, -{L_REGbIb ,t_XORb ,S_REGb ,REGI_AL },{L_REGdId ,t_XORd ,S_REGd ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ss },{D_AAA ,0 ,0 ,0 }, -/* 0x238 - 0x23f */ -{L_MODRM ,t_CMPb ,0 ,M_EbGb },{L_MODRM ,t_CMPd ,0 ,M_EdGd }, -{L_MODRM ,t_CMPb ,0 ,M_GbEb },{L_MODRM ,t_CMPd ,0 ,M_GdEd }, -{L_REGbIb ,t_CMPb ,0 ,REGI_AL },{L_REGdId ,t_CMPd ,0 ,REGI_AX }, -{L_PRESEG ,0 ,0 ,ds },{D_AAS ,0 ,0 ,0 }, - -/* 0x240 - 0x247 */ -{L_REGd ,t_INCd ,S_REGd ,REGI_AX},{L_REGd ,t_INCd ,S_REGd ,REGI_CX}, -{L_REGd ,t_INCd ,S_REGd ,REGI_DX},{L_REGd ,t_INCd ,S_REGd ,REGI_BX}, -{L_REGd ,t_INCd ,S_REGd ,REGI_SP},{L_REGd ,t_INCd ,S_REGd ,REGI_BP}, -{L_REGd ,t_INCd ,S_REGd ,REGI_SI},{L_REGd ,t_INCd ,S_REGd ,REGI_DI}, -/* 0x248 - 0x24f */ -{L_REGd ,t_DECd ,S_REGd ,REGI_AX},{L_REGd ,t_DECd ,S_REGd ,REGI_CX}, -{L_REGd ,t_DECd ,S_REGd ,REGI_DX},{L_REGd ,t_DECd ,S_REGd ,REGI_BX}, -{L_REGd ,t_DECd ,S_REGd ,REGI_SP},{L_REGd ,t_DECd ,S_REGd ,REGI_BP}, -{L_REGd ,t_DECd ,S_REGd ,REGI_SI},{L_REGd ,t_DECd ,S_REGd ,REGI_DI}, - -/* 0x250 - 0x257 */ -{L_REGd ,0 ,S_PUSHd,REGI_AX},{L_REGd ,0 ,S_PUSHd,REGI_CX}, -{L_REGd ,0 ,S_PUSHd,REGI_DX},{L_REGd ,0 ,S_PUSHd,REGI_BX}, -{L_REGd ,0 ,S_PUSHd,REGI_SP},{L_REGd ,0 ,S_PUSHd,REGI_BP}, -{L_REGd ,0 ,S_PUSHd,REGI_SI},{L_REGd ,0 ,S_PUSHd,REGI_DI}, -/* 0x258 - 0x25f */ -{L_POPd ,0 ,S_REGd ,REGI_AX},{L_POPd ,0 ,S_REGd ,REGI_CX}, -{L_POPd ,0 ,S_REGd ,REGI_DX},{L_POPd ,0 ,S_REGd ,REGI_BX}, -{L_POPd ,0 ,S_REGd ,REGI_SP},{L_POPd ,0 ,S_REGd ,REGI_BP}, -{L_POPd ,0 ,S_REGd ,REGI_SI},{L_POPd ,0 ,S_REGd ,REGI_DI}, - -/* 0x260 - 0x267 */ -{D_PUSHAd ,0 ,0 ,0 },{D_POPAd ,0 ,0 ,0 }, -{L_MODRM ,O_BOUNDd ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, -{L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, -/* 0x268 - 0x26f */ -{L_Id ,0 ,S_PUSHd,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdId}, -{L_Ibx ,0 ,S_PUSHd,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdIbx}, -{L_STRING ,R_INSB ,0 ,0 },{L_STRING ,R_INSD ,0 ,0 }, -{L_STRING ,R_OUTSB ,0 ,0 },{L_STRING ,R_OUTSD ,0 ,0 }, - -/* 0x270 - 0x277 */ -{L_Ibx ,O_C_O ,S_C_AIPd,0 },{L_Ibx ,O_C_NO ,S_C_AIPd,0 }, -{L_Ibx ,O_C_B ,S_C_AIPd,0 },{L_Ibx ,O_C_NB ,S_C_AIPd,0 }, -{L_Ibx ,O_C_Z ,S_C_AIPd,0 },{L_Ibx ,O_C_NZ ,S_C_AIPd,0 }, -{L_Ibx ,O_C_BE ,S_C_AIPd,0 },{L_Ibx ,O_C_NBE ,S_C_AIPd,0 }, -/* 0x278 - 0x27f */ -{L_Ibx ,O_C_S ,S_C_AIPd,0 },{L_Ibx ,O_C_NS ,S_C_AIPd,0 }, -{L_Ibx ,O_C_P ,S_C_AIPd,0 },{L_Ibx ,O_C_NP ,S_C_AIPd,0 }, -{L_Ibx ,O_C_L ,S_C_AIPd,0 },{L_Ibx ,O_C_NL ,S_C_AIPd,0 }, -{L_Ibx ,O_C_LE ,S_C_AIPd,0 },{L_Ibx ,O_C_NLE ,S_C_AIPd,0 }, - -/* 0x280 - 0x287 */ -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,2 ,0 ,M_GRP }, -{L_MODRM ,0 ,0 ,M_GRP },{L_MODRM ,4 ,0 ,M_GRP }, -{L_MODRM ,t_TESTb ,0 ,M_EbGb },{L_MODRM ,t_TESTd ,0 ,M_EdGd }, -{L_MODRM ,0 ,S_EbGb ,M_GbEb },{L_MODRM ,0 ,S_EdGd ,M_GdEd }, -/* 0x288 - 0x28f */ -{L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ed ,M_Gd }, -{L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ed }, -{L_MODRM ,0 ,S_EdMw ,M_SEG },{L_MODRM ,0 ,S_Gd ,M_EA }, -{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPdRM ,0 ,S_Ed ,M_None }, - -/* 0x290 - 0x297 */ -{D_NOP ,0 ,0 ,0 },{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_CX}, -{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DX},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_BX}, -{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SP},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_BP}, -{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_SI},{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_DI}, -/* 0x298 - 0x29f */ -{D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 }, -{L_Ifd ,O_CALLFd ,0 ,0 },{D_WAIT ,0 ,0 ,0 }, -{D_PUSHF ,0 ,0 ,true },{D_POPF ,0 ,0 ,true }, -{D_SAHF ,0 ,0 ,0 },{D_LAHF ,0 ,0 ,0 }, - -/* 0x2a0 - 0x2a7 */ -{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_EAXOP ,0 ,0 }, -{L_OP ,O_OPAL ,0 ,0 },{L_OP ,O_OPEAX ,0 ,0 }, -{L_STRING ,R_MOVSB ,0 ,0 },{L_STRING ,R_MOVSD ,0 ,0 }, -{L_STRING ,R_CMPSB ,0 ,0 },{L_STRING ,R_CMPSD ,0 ,0 }, -/* 0x2a8 - 0x2af */ -{L_REGbIb ,t_TESTb ,0 ,REGI_AL},{L_REGdId ,t_TESTd ,0 ,REGI_AX}, -{L_STRING ,R_STOSB ,0 ,0 },{L_STRING ,R_STOSD ,0 ,0 }, -{L_STRING ,R_LODSB ,0 ,0 },{L_STRING ,R_LODSD ,0 ,0 }, -{L_STRING ,R_SCASB ,0 ,0 },{L_STRING ,R_SCASD ,0 ,0 }, - -/* 0x2b0 - 0x2b7 */ -{L_Ib ,0 ,S_REGb ,REGI_AL},{L_Ib ,0 ,S_REGb ,REGI_CL}, -{L_Ib ,0 ,S_REGb ,REGI_DL},{L_Ib ,0 ,S_REGb ,REGI_BL}, -{L_Ib ,0 ,S_REGb ,REGI_AH},{L_Ib ,0 ,S_REGb ,REGI_CH}, -{L_Ib ,0 ,S_REGb ,REGI_DH},{L_Ib ,0 ,S_REGb ,REGI_BH}, -/* 0x2b8 - 0x2bf */ -{L_Id ,0 ,S_REGd ,REGI_AX},{L_Id ,0 ,S_REGd ,REGI_CX}, -{L_Id ,0 ,S_REGd ,REGI_DX},{L_Id ,0 ,S_REGd ,REGI_BX}, -{L_Id ,0 ,S_REGd ,REGI_SP},{L_Id ,0 ,S_REGd ,REGI_BP}, -{L_Id ,0 ,S_REGd ,REGI_SI},{L_Id ,0 ,S_REGd ,REGI_DI}, - -/* 0x2c0 - 0x2c7 */ -{L_MODRM ,5 ,0 ,M_GRP_Ib },{L_MODRM ,7 ,0 ,M_GRP_Ib }, -{L_POPd ,0 ,S_IPIw ,0 },{L_POPd ,0 ,S_IP ,0 }, -{L_MODRM ,O_SEGES ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGDS ,S_SEGGd,M_Efd }, -{L_MODRM ,0 ,S_Eb ,M_Ib },{L_MODRM ,0 ,S_Ed ,M_Id }, -/* 0x2c8 - 0x2cf */ -{D_ENTERd ,0 ,0 ,0 },{D_LEAVEd ,0 ,0 ,0 }, -{D_RETFdIw ,0 ,0 ,0 },{D_RETFd ,0 ,0 ,0 }, -{L_VAL ,O_INT ,0 ,3 },{L_Ib ,O_INT ,0 ,0 }, -{L_INTO ,O_INT ,0 ,0 },{D_IRETd ,0 ,0 ,0 }, - -/* 0x2d0 - 0x2d7 */ -{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 }, -{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,7 ,0 ,M_GRP_CL }, -{L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 }, -{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 }, -/* 0x2d8 - 0x2df */ -{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 }, -{L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 }, -{L_MODRM ,O_FPU ,4 ,0 },{L_MODRM ,O_FPU ,5 ,0 }, -{L_MODRM ,O_FPU ,6 ,0 },{L_MODRM ,O_FPU ,7 ,0 }, - -/* 0x2e0 - 0x2e7 */ -{L_Ibx ,O_LOOPNZ ,S_AIPd ,0 },{L_Ibx ,O_LOOPZ ,S_AIPd ,0 }, -{L_Ibx ,O_LOOP ,S_AIPd ,0 },{L_Ibx ,O_JCXZ ,S_AIPd ,0 }, -{L_Ib ,O_INb ,0 ,0 },{L_Ib ,O_INd ,0 ,0 }, -{L_Ib ,O_OUTb ,0 ,0 },{L_Ib ,O_OUTd ,0 ,0 }, -/* 0x2e8 - 0x2ef */ -{L_Id ,O_CALLNd ,S_AIPd ,0 },{L_Idx ,0 ,S_AIPd ,0 }, -{L_Ifd ,O_JMPFd ,0 ,0 },{L_Ibx ,0 ,S_AIPd ,0 }, -{L_REGw ,O_INb ,0 ,REGI_DX},{L_REGw ,O_INd ,0 ,REGI_DX}, -{L_REGw ,O_OUTb ,0 ,REGI_DX},{L_REGw ,O_OUTd ,0 ,REGI_DX}, - -/* 0x2f0 - 0x2f7 */ -{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, -{L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, -{D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, -{L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP }, -/* 0x2f8 - 0x2ff */ -{D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 }, -{D_CLI ,0 ,0 ,0 },{D_STI ,0 ,0 ,0 }, -{D_CLD ,0 ,0 ,0 },{D_STD ,0 ,0 ,0 }, -{L_MODRM ,0xb ,0 ,M_GRP },{L_MODRM ,0xd ,0 ,M_GRP }, - - -/* 0x300 - 0x307 */ -{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, -{L_MODRM_NVM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM_NVM ,O_LSL ,S_Gd ,M_EdGd }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x308 - 0x30f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x310 - 0x317 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x318 - 0x31f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x320 - 0x327 */ -{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 }, -{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed }, -{L_MODRM ,O_M_Rd_TRx ,S_Ed ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,O_M_TRx_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 }, - -/* 0x328 - 0x32f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x330 - 0x337 */ -{0 ,0 ,0 ,0 },{D_RDTSC ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x338 - 0x33f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x340 - 0x347 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x348 - 0x34f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x350 - 0x357 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x358 - 0x35f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x360 - 0x367 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x368 - 0x36f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - - -/* 0x370 - 0x377 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x378 - 0x37f */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x380 - 0x387 */ -{L_Idx ,O_C_O ,S_C_AIPd,0 },{L_Idx ,O_C_NO ,S_C_AIPd,0 }, -{L_Idx ,O_C_B ,S_C_AIPd,0 },{L_Idx ,O_C_NB ,S_C_AIPd,0 }, -{L_Idx ,O_C_Z ,S_C_AIPd,0 },{L_Idx ,O_C_NZ ,S_C_AIPd,0 }, -{L_Idx ,O_C_BE ,S_C_AIPd,0 },{L_Idx ,O_C_NBE ,S_C_AIPd,0 }, -/* 0x388 - 0x38f */ -{L_Idx ,O_C_S ,S_C_AIPd,0 },{L_Idx ,O_C_NS ,S_C_AIPd,0 }, -{L_Idx ,O_C_P ,S_C_AIPd,0 },{L_Idx ,O_C_NP ,S_C_AIPd,0 }, -{L_Idx ,O_C_L ,S_C_AIPd,0 },{L_Idx ,O_C_NL ,S_C_AIPd,0 }, -{L_Idx ,O_C_LE ,S_C_AIPd,0 },{L_Idx ,O_C_NLE ,S_C_AIPd,0 }, - -/* 0x390 - 0x397 */ -{L_MODRM ,O_C_O ,S_C_Eb,0 },{L_MODRM ,O_C_NO ,S_C_Eb,0 }, -{L_MODRM ,O_C_B ,S_C_Eb,0 },{L_MODRM ,O_C_NB ,S_C_Eb,0 }, -{L_MODRM ,O_C_Z ,S_C_Eb,0 },{L_MODRM ,O_C_NZ ,S_C_Eb,0 }, -{L_MODRM ,O_C_BE ,S_C_Eb,0 },{L_MODRM ,O_C_NBE ,S_C_Eb,0 }, -/* 0x398 - 0x39f */ -{L_MODRM ,O_C_S ,S_C_Eb,0 },{L_MODRM ,O_C_NS ,S_C_Eb,0 }, -{L_MODRM ,O_C_P ,S_C_Eb,0 },{L_MODRM ,O_C_NP ,S_C_Eb,0 }, -{L_MODRM ,O_C_L ,S_C_Eb,0 },{L_MODRM ,O_C_NL ,S_C_Eb,0 }, -{L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 }, - -/* 0x3a0 - 0x3a7 */ -{L_SEG ,0 ,S_PUSHd ,fs },{D_POPSEGd,0 ,0 ,fs }, -{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3a8 - 0x3af */ -{L_SEG ,0 ,S_PUSHd ,gs },{D_POPSEGd,0 ,0 ,gs }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL }, -{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, - -/* 0x3b0 - 0x3b7 */ -{0 ,0 ,0 ,0 },{L_MODRM ,O_CMPXCHG ,S_Ed ,M_Ed }, -{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, -{L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, -/* 0x3b8 - 0x3bf */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,S_Ed ,M_EdGdt }, -{L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed }, -{L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx }, - -/* 0x3c0 - 0x3cc */ -{L_MODRM ,t_ADDb ,S_EbGb ,M_GbEb },{L_MODRM ,t_ADDd ,S_EdGd ,M_GdEd }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3c8 - 0x3cf */ -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_AX},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_CX}, -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_DX},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_BX}, -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_SP},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_BP}, -{L_REGd ,O_BSWAPd ,S_REGd ,REGI_SI},{L_REGd ,O_BSWAPd ,S_REGd ,REGI_DI}, - -/* 0x3d0 - 0x3d7 */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3d8 - 0x3df */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x3e0 - 0x3ee */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3e8 - 0x3ef */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -/* 0x3f0 - 0x3fc */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -/* 0x3f8 - 0x3ff */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, - -}; - -static OpCode Groups[16][8]={ -{ /* 0x00 Group 1 Eb,Ib */ -{0 ,t_ADDb ,S_Eb ,M_EbIb },{0 ,t_ORb ,S_Eb ,M_EbIb }, -{0 ,t_ADCb ,S_Eb ,M_EbIb },{0 ,t_SBBb ,S_Eb ,M_EbIb }, -{0 ,t_ANDb ,S_Eb ,M_EbIb },{0 ,t_SUBb ,S_Eb ,M_EbIb }, -{0 ,t_XORb ,S_Eb ,M_EbIb },{0 ,t_CMPb ,0 ,M_EbIb }, -},{ /* 0x01 Group 1 Ew,Iw */ -{0 ,t_ADDw ,S_Ew ,M_EwIw },{0 ,t_ORw ,S_Ew ,M_EwIw }, -{0 ,t_ADCw ,S_Ew ,M_EwIw },{0 ,t_SBBw ,S_Ew ,M_EwIw }, -{0 ,t_ANDw ,S_Ew ,M_EwIw },{0 ,t_SUBw ,S_Ew ,M_EwIw }, -{0 ,t_XORw ,S_Ew ,M_EwIw },{0 ,t_CMPw ,0 ,M_EwIw }, -},{ /* 0x02 Group 1 Ed,Id */ -{0 ,t_ADDd ,S_Ed ,M_EdId },{0 ,t_ORd ,S_Ed ,M_EdId }, -{0 ,t_ADCd ,S_Ed ,M_EdId },{0 ,t_SBBd ,S_Ed ,M_EdId }, -{0 ,t_ANDd ,S_Ed ,M_EdId },{0 ,t_SUBd ,S_Ed ,M_EdId }, -{0 ,t_XORd ,S_Ed ,M_EdId },{0 ,t_CMPd ,0 ,M_EdId }, -},{ /* 0x03 Group 1 Ew,Ibx */ -{0 ,t_ADDw ,S_Ew ,M_EwIbx },{0 ,t_ORw ,S_Ew ,M_EwIbx }, -{0 ,t_ADCw ,S_Ew ,M_EwIbx },{0 ,t_SBBw ,S_Ew ,M_EwIbx }, -{0 ,t_ANDw ,S_Ew ,M_EwIbx },{0 ,t_SUBw ,S_Ew ,M_EwIbx }, -{0 ,t_XORw ,S_Ew ,M_EwIbx },{0 ,t_CMPw ,0 ,M_EwIbx }, -},{ /* 0x04 Group 1 Ed,Ibx */ -{0 ,t_ADDd ,S_Ed ,M_EdIbx },{0 ,t_ORd ,S_Ed ,M_EdIbx }, -{0 ,t_ADCd ,S_Ed ,M_EdIbx },{0 ,t_SBBd ,S_Ed ,M_EdIbx }, -{0 ,t_ANDd ,S_Ed ,M_EdIbx },{0 ,t_SUBd ,S_Ed ,M_EdIbx }, -{0 ,t_XORd ,S_Ed ,M_EdIbx },{0 ,t_CMPd ,0 ,M_EdIbx }, - -},{ /* 0x05 Group 2 Eb,XXX */ -{0 ,t_ROLb ,S_Eb ,M_Eb },{0 ,t_RORb ,S_Eb ,M_Eb }, -{0 ,t_RCLb ,S_Eb ,M_Eb },{0 ,t_RCRb ,S_Eb ,M_Eb }, -{0 ,t_SHLb ,S_Eb ,M_Eb },{0 ,t_SHRb ,S_Eb ,M_Eb }, -{0 ,t_SHLb ,S_Eb ,M_Eb },{0 ,t_SARb ,S_Eb ,M_Eb }, -},{ /* 0x06 Group 2 Ew,XXX */ -{0 ,t_ROLw ,S_Ew ,M_Ew },{0 ,t_RORw ,S_Ew ,M_Ew }, -{0 ,t_RCLw ,S_Ew ,M_Ew },{0 ,t_RCRw ,S_Ew ,M_Ew }, -{0 ,t_SHLw ,S_Ew ,M_Ew },{0 ,t_SHRw ,S_Ew ,M_Ew }, -{0 ,t_SHLw ,S_Ew ,M_Ew },{0 ,t_SARw ,S_Ew ,M_Ew }, -},{ /* 0x07 Group 2 Ed,XXX */ -{0 ,t_ROLd ,S_Ed ,M_Ed },{0 ,t_RORd ,S_Ed ,M_Ed }, -{0 ,t_RCLd ,S_Ed ,M_Ed },{0 ,t_RCRd ,S_Ed ,M_Ed }, -{0 ,t_SHLd ,S_Ed ,M_Ed },{0 ,t_SHRd ,S_Ed ,M_Ed }, -{0 ,t_SHLd ,S_Ed ,M_Ed },{0 ,t_SARd ,S_Ed ,M_Ed }, - - -},{ /* 0x08 Group 3 Eb */ -{0 ,t_TESTb ,0 ,M_EbIb },{0 ,t_TESTb ,0 ,M_EbIb }, -{0 ,O_NOT ,S_Eb ,M_Eb },{0 ,t_NEGb ,S_Eb ,M_Eb }, -{0 ,O_MULb ,0 ,M_Eb },{0 ,O_IMULb ,0 ,M_Eb }, -{0 ,O_DIVb ,0 ,M_Eb },{0 ,O_IDIVb ,0 ,M_Eb }, -},{ /* 0x09 Group 3 Ew */ -{0 ,t_TESTw ,0 ,M_EwIw },{0 ,t_TESTw ,0 ,M_EwIw }, -{0 ,O_NOT ,S_Ew ,M_Ew },{0 ,t_NEGw ,S_Ew ,M_Ew }, -{0 ,O_MULw ,0 ,M_Ew },{0 ,O_IMULw ,0 ,M_Ew }, -{0 ,O_DIVw ,0 ,M_Ew },{0 ,O_IDIVw ,0 ,M_Ew }, -},{ /* 0x0a Group 3 Ed */ -{0 ,t_TESTd ,0 ,M_EdId },{0 ,t_TESTd ,0 ,M_EdId }, -{0 ,O_NOT ,S_Ed ,M_Ed },{0 ,t_NEGd ,S_Ed ,M_Ed }, -{0 ,O_MULd ,0 ,M_Ed },{0 ,O_IMULd ,0 ,M_Ed }, -{0 ,O_DIVd ,0 ,M_Ed },{0 ,O_IDIVd ,0 ,M_Ed }, - -},{ /* 0x0b Group 4 Eb */ -{0 ,t_INCb ,S_Eb ,M_Eb },{0 ,t_DECb ,S_Eb ,M_Eb }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,O_CBACK ,0 ,M_Iw }, -},{ /* 0x0c Group 5 Ew */ -{0 ,t_INCw ,S_Ew ,M_Ew },{0 ,t_DECw ,S_Ew ,M_Ew }, -{0 ,O_CALLNw ,S_IP ,M_Ew },{0 ,O_CALLFw ,0 ,M_Efw }, -{0 ,0 ,S_IP ,M_Ew },{0 ,O_JMPFw ,0 ,M_Efw }, -{0 ,0 ,S_PUSHw,M_Ew },{0 ,0 ,0 ,0 }, -},{ /* 0x0d Group 5 Ed */ -{0 ,t_INCd ,S_Ed ,M_Ed },{0 ,t_DECd ,S_Ed ,M_Ed }, -{0 ,O_CALLNd ,S_IP ,M_Ed },{0 ,O_CALLFd ,0 ,M_Efd }, -{0 ,0 ,S_IP ,M_Ed },{0 ,O_JMPFd ,0 ,M_Efd }, -{0 ,0 ,S_PUSHd,M_Ed },{0 ,0 ,0 ,0 }, - - -},{ /* 0x0e Group 8 Ew */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,O_BTw ,S_Ew ,M_EwIb },{0 ,O_BTSw ,S_Ew ,M_EwIb }, -{0 ,O_BTRw ,S_Ew ,M_EwIb },{0 ,O_BTCw ,S_Ew ,M_EwIb }, -},{ /* 0x0f Group 8 Ed */ -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, -{0 ,O_BTd ,S_Ed ,M_EdIb },{0 ,O_BTSd ,S_Ed ,M_EdIb }, -{0 ,O_BTRd ,S_Ed ,M_EdIb },{0 ,O_BTCd ,S_Ed ,M_EdIb }, - - - -} -}; - - - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/save.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/save.h deleted file mode 100644 index 408ed6d88..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/save.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Write the data from the opcode */ -switch (inst.code.save) { -/* Byte */ - case S_C_Eb: - inst_op1_b=inst.cond ? 1 : 0; - case S_Eb: - if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst_op1_b); - else reg_8(inst.rm_eai)=inst_op1_b; - break; - case S_Gb: - reg_8(inst.rm_index)=inst_op1_b; - break; - case S_EbGb: - if (inst.rm<0xc0) SaveMb(inst.rm_eaa,inst_op1_b); - else reg_8(inst.rm_eai)=inst_op1_b; - reg_8(inst.rm_index)=inst_op2_b; - break; -/* Word */ - case S_Ew: - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); - else reg_16(inst.rm_eai)=inst_op1_w; - break; - case S_Gw: - reg_16(inst.rm_index)=inst_op1_w; - break; - case S_EwGw: - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); - else reg_16(inst.rm_eai)=inst_op1_w; - reg_16(inst.rm_index)=inst_op2_w; - break; -/* Dword */ - case S_Ed: - if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); - else reg_32(inst.rm_eai)=inst_op1_d; - break; - case S_EdMw: /* Special one 16 to memory, 32 zero extend to reg */ - if (inst.rm<0xc0) SaveMw(inst.rm_eaa,inst_op1_w); - else reg_32(inst.rm_eai)=inst_op1_d; - break; - case S_Gd: - reg_32(inst.rm_index)=inst_op1_d; - break; - case S_EdGd: - if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); - else reg_32(inst.rm_eai)=inst_op1_d; - reg_32(inst.rm_index)=inst_op2_d; - break; - - case S_REGb: - reg_8(inst.code.extra)=inst_op1_b; - break; - case S_REGw: - reg_16(inst.code.extra)=inst_op1_w; - break; - case S_REGd: - reg_32(inst.code.extra)=inst_op1_d; - break; - case S_SEGm: - if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst_op1_w)) RunException(); - break; - case S_SEGGw: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst_op2_w)) RunException(); - reg_16(inst.rm_index)=inst_op1_w; - break; - case S_SEGGd: - if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst_op2_w)) RunException(); - reg_32(inst.rm_index)=inst_op1_d; - break; - case S_PUSHw: - Push_16(inst_op1_w); - break; - case S_PUSHd: - Push_32(inst_op1_d); - break; - - case S_C_AIPw: - if (!inst.cond) goto nextopcode; - case S_AIPw: - SaveIP(); - reg_eip+=inst_op1_d; - reg_eip&=0xffff; - continue; - case S_C_AIPd: - if (!inst.cond) goto nextopcode; - case S_AIPd: - SaveIP(); - reg_eip+=inst_op1_d; - continue; - case S_IPIw: - reg_esp+=Fetchw(); - case S_IP: - SaveIP(); - reg_eip=inst_op1_d; - continue; - case 0: - break; - default: - LOG(LOG_CPU,LOG_ERROR)("SAVE:Unhandled code %d entry %X",inst.code.save,inst.entry); -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/string.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/string.h deleted file mode 100644 index 8cb6ec03c..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/string.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -{ - EAPoint si_base,di_base; - Bitu si_index,di_index; - Bitu add_mask; - Bitu count,count_left; - Bits add_index; - - if (inst.prefix & PREFIX_SEG) si_base=inst.seg.base; - else si_base=SegBase(ds); - di_base=SegBase(es); - if (inst.prefix & PREFIX_ADDR) { - add_mask=0xFFFFFFFF; - si_index=reg_esi; - di_index=reg_edi; - count=reg_ecx; - } else { - add_mask=0xFFFF; - si_index=reg_si; - di_index=reg_di; - count=reg_cx; - } - if (!(inst.prefix & PREFIX_REP)) { - count=1; - } else { - /* Calculate amount of ops to do before cycles run out */ - CPU_Cycles++; - if ((count>(Bitu)CPU_Cycles) && (inst.code.op0;count--) { - IO_WriteB(reg_dx,LoadMb(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSW: - add_index<<=1; - for (;count>0;count--) { - IO_WriteW(reg_dx,LoadMw(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSD: - add_index<<=2; - for (;count>0;count--) { - IO_WriteD(reg_dx,LoadMd(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_INSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,IO_ReadB(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_INSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,IO_ReadW(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_INSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,IO_ReadD(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,reg_al); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,reg_ax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,reg_eax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_MOVSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,LoadMb(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,LoadMw(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,LoadMd(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSB: - for (;count>0;count--) { - reg_al=LoadMb(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSW: - add_index<<=1; - for (;count>0;count--) { - reg_ax=LoadMw(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSD: - add_index<<=2; - for (;count>0;count--) { - reg_eax=LoadMd(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_SCASB: - { - Bit8u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMb(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_al==val2)!=inst.repz) break; - } - CMPB(reg_al,val2,LoadD,0); - } - break; - case R_SCASW: - { - add_index<<=1;Bit16u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMw(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_ax==val2)!=inst.repz) break; - } - CMPW(reg_ax,val2,LoadD,0); - } - break; - case R_SCASD: - { - add_index<<=2;Bit32u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMd(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_eax==val2)!=inst.repz) break; - } - CMPD(reg_eax,val2,LoadD,0); - } - break; - case R_CMPSB: - { - Bit8u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMb(si_base+si_index); - val2=LoadMb(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=inst.repz) break; - } - CMPB(val1,val2,LoadD,0); - } - break; - case R_CMPSW: - { - add_index<<=1;Bit16u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMw(si_base+si_index); - val2=LoadMw(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=inst.repz) break; - } - CMPW(val1,val2,LoadD,0); - } - break; - case R_CMPSD: - { - add_index<<=2;Bit32u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMd(si_base+si_index); - val2=LoadMd(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=inst.repz) break; - } - CMPD(val1,val2,LoadD,0); - } - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled string %d entry %X",inst.code.op,inst.entry); - } - /* Clean up after certain amount of instructions */ - reg_esi&=(~add_mask); - reg_esi|=(si_index & add_mask); - reg_edi&=(~add_mask); - reg_edi|=(di_index & add_mask); - if (inst.prefix & PREFIX_REP) { - count+=count_left; - reg_ecx&=(~add_mask); - reg_ecx|=(count & add_mask); - } -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/support.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_full/support.h deleted file mode 100644 index bdbe452ac..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_full/support.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -enum { - L_N=0, - L_SKIP, - /* Grouped ones using MOD/RM */ - L_MODRM,L_MODRM_NVM,L_POPwRM,L_POPdRM, - - L_Ib,L_Iw,L_Id, - L_Ibx,L_Iwx,L_Idx, //Sign extend - L_Ifw,L_Ifd, - L_OP, - - L_REGb,L_REGw,L_REGd, - L_REGbIb,L_REGwIw,L_REGdId, - L_POPw,L_POPd, - L_POPfw,L_POPfd, - L_SEG, - - L_INTO, - - L_VAL, - L_PRESEG, - L_DOUBLE, - L_PREOP,L_PREADD,L_PREREP,L_PREREPNE, - L_STRING, - -/* Direct ones */ - D_IRETw,D_IRETd, - D_PUSHAw,D_PUSHAd, - D_POPAw,D_POPAd, - D_POPSEGw,D_POPSEGd, - D_DAA,D_DAS, - D_AAA,D_AAS, - D_CBW,D_CWDE, - D_CWD,D_CDQ, - D_SETALC, - D_XLAT, - D_CLI,D_STI,D_STC,D_CLC,D_CMC,D_CLD,D_STD, - D_NOP,D_WAIT, - D_ENTERw,D_ENTERd, - D_LEAVEw,D_LEAVEd, - - D_RETFw,D_RETFd, - D_RETFwIw,D_RETFdIw, - D_POPF,D_PUSHF, - D_SAHF,D_LAHF, - D_CPUID, - D_HLT,D_CLTS, - D_LOCK,D_ICEBP, - D_RDTSC, - L_ERROR -}; - - -enum { - O_N=t_LASTFLAG, - O_COND, - O_XCHG_AX,O_XCHG_EAX, - O_IMULRw,O_IMULRd, - O_BOUNDw,O_BOUNDd, - O_CALLNw,O_CALLNd, - O_CALLFw,O_CALLFd, - O_JMPFw,O_JMPFd, - - O_OPAL,O_ALOP, - O_OPAX,O_AXOP, - O_OPEAX,O_EAXOP, - O_INT, - O_SEGDS,O_SEGES,O_SEGFS,O_SEGGS,O_SEGSS, - O_LOOP,O_LOOPZ,O_LOOPNZ,O_JCXZ, - O_INb,O_INw,O_INd, - O_OUTb,O_OUTw,O_OUTd, - - O_NOT,O_AAM,O_AAD, - O_MULb,O_MULw,O_MULd, - O_IMULb,O_IMULw,O_IMULd, - O_DIVb,O_DIVw,O_DIVd, - O_IDIVb,O_IDIVw,O_IDIVd, - O_CBACK, - - - O_DSHLw,O_DSHLd, - O_DSHRw,O_DSHRd, - O_C_O ,O_C_NO ,O_C_B ,O_C_NB ,O_C_Z ,O_C_NZ ,O_C_BE ,O_C_NBE, - O_C_S ,O_C_NS ,O_C_P ,O_C_NP ,O_C_L ,O_C_NL ,O_C_LE ,O_C_NLE, - - O_GRP6w,O_GRP6d, - O_GRP7w,O_GRP7d, - O_M_CRx_Rd,O_M_Rd_CRx, - O_M_DRx_Rd,O_M_Rd_DRx, - O_M_TRx_Rd,O_M_Rd_TRx, - O_LAR,O_LSL, - O_ARPL, - - O_BTw,O_BTSw,O_BTRw,O_BTCw, - O_BTd,O_BTSd,O_BTRd,O_BTCd, - O_BSFw,O_BSRw,O_BSFd,O_BSRd, - - O_BSWAPw, O_BSWAPd, - O_CMPXCHG, - O_FPU - - -}; - -enum { - S_N=0, - S_C_Eb, - S_Eb,S_Gb,S_EbGb, - S_Ew,S_Gw,S_EwGw, - S_Ed,S_Gd,S_EdGd,S_EdMw, - - - S_REGb,S_REGw,S_REGd, - S_PUSHw,S_PUSHd, - S_SEGm, - S_SEGGw,S_SEGGd, - - - S_AIPw,S_C_AIPw, - S_AIPd,S_C_AIPd, - - S_IP,S_IPIw -}; - -enum { - R_OUTSB,R_OUTSW,R_OUTSD, - R_INSB,R_INSW,R_INSD, - R_MOVSB,R_MOVSW,R_MOVSD, - R_LODSB,R_LODSW,R_LODSD, - R_STOSB,R_STOSW,R_STOSD, - R_SCASB,R_SCASW,R_SCASD, - R_CMPSB,R_CMPSW,R_CMPSD -}; - -enum { - M_None=0, - M_Ebx,M_Eb,M_Gb,M_EbGb,M_GbEb, - M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx,M_EwGwt, - M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx,M_EdGdt, - - M_EbIb,M_EwIb,M_EdIb, - M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx,M_EwGwIb,M_EwGwCL, - M_EdId,M_EdIbx,M_EdGdIb,M_EdGdCL, - - M_Efw,M_Efd, - - M_Ib,M_Iw,M_Id, - - - M_SEG,M_EA, - M_GRP, - M_GRP_Ib,M_GRP_CL,M_GRP_1, - - M_POPw,M_POPd -}; - -struct OpCode { - Bit8u load,op,save,extra; -}; - -struct FullData { - Bitu entry; - Bitu rm; - EAPoint rm_eaa; - Bitu rm_off; - Bitu rm_eai; - Bitu rm_index; - Bitu rm_mod; - OpCode code; - EAPoint cseip; -#ifdef WORDS_BIGENDIAN - union { - Bit32u dword[1]; - Bit32s dwords[1]; - Bit16u word[2]; - Bit16s words[2]; - Bit8u byte[4]; - Bit8s bytes[4]; - } blah1,blah2,blah_imm; -#else - union { - Bit8u b;Bit8s bs; - Bit16u w;Bit16s ws; - Bit32u d;Bit32s ds; - } op1,op2,imm; -#endif - Bitu new_flags; - struct { - EAPoint base; - } seg; - Bitu cond; - bool repz; - Bitu prefix; -}; - -/* Some defines to get the names correct. */ -#ifdef WORDS_BIGENDIAN - -#define inst_op1_b inst.blah1.byte[3] -#define inst_op1_bs inst.blah1.bytes[3] -#define inst_op1_w inst.blah1.word[1] -#define inst_op1_ws inst.blah1.words[1] -#define inst_op1_d inst.blah1.dword[0] -#define inst_op1_ds inst.blah1.dwords[0] - -#define inst_op2_b inst.blah2.byte[3] -#define inst_op2_bs inst.blah2.bytes[3] -#define inst_op2_w inst.blah2.word[1] -#define inst_op2_ws inst.blah2.words[1] -#define inst_op2_d inst.blah2.dword[0] -#define inst_op2_ds inst.blah2.dwords[0] - -#define inst_imm_b inst.blah_imm.byte[3] -#define inst_imm_bs inst.blah_imm.bytes[3] -#define inst_imm_w inst.blah_imm.word[1] -#define inst_imm_ws inst.blah_imm.words[1] -#define inst_imm_d inst.blah_imm.dword[0] -#define inst_imm_ds inst.blah_imm.dwords[0] - -#else - -#define inst_op1_b inst.op1.b -#define inst_op1_bs inst.op1.bs -#define inst_op1_w inst.op1.w -#define inst_op1_ws inst.op1.ws -#define inst_op1_d inst.op1.d -#define inst_op1_ds inst.op1.ds - -#define inst_op2_b inst.op2.b -#define inst_op2_bs inst.op2.bs -#define inst_op2_w inst.op2.w -#define inst_op2_ws inst.op2.ws -#define inst_op2_d inst.op2.d -#define inst_op2_ds inst.op2.ds - -#define inst_imm_b inst.imm.b -#define inst_imm_bs inst.imm.bs -#define inst_imm_w inst.imm.w -#define inst_imm_ws inst.imm.ws -#define inst_imm_d inst.imm.d -#define inst_imm_ds inst.imm.ds - -#endif - - -#define PREFIX_NONE 0x0 -#define PREFIX_ADDR 0x1 -#define PREFIX_SEG 0x2 -#define PREFIX_REP 0x4 - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal.cpp deleted file mode 100644 index f0525d537..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "device.h" -#include "./types_compat.h" -//#include - -//#include "dosbox.h" -//#include "mem.h" -#include "cpu.h" -#include "lazyflags.h" -//#include "inout.h" -//#include "callback.h" -//#include "pic.h" -#include "fpu.h" -#include "paging.h" - -//#if C_DEBUG -//#include "debug.h" -//#endif - -#if (!C_CORE_INLINE) -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) -#else -#include "paging.h" -#define LoadMb(off) mem_readb_inline(off) -#define LoadMw(off) mem_readw_inline(off) -#define LoadMd(off) mem_readd_inline(off) -#define SaveMb(off,val) mem_writeb_inline(off,val) -#define SaveMw(off,val) mem_writew_inline(off,val) -#define SaveMd(off,val) mem_writed_inline(off,val) -#endif - -extern Bitu cycle_count; - -#if C_FPU -#define CPU_FPU 1 //Enable FPU escape instructions -#endif - -#define CPU_PIC_CHECK 1 -#define CPU_TRAP_CHECK 1 - -#define OPCODE_NONE 0x000 -#define OPCODE_0F 0x100 -#define OPCODE_SIZE 0x200 - -#define PREFIX_ADDR 0x1 -#define PREFIX_REP 0x2 - -#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) -#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) - -#define DO_PREFIX_SEG(_SEG) \ - BaseDS=SegBase(_SEG); \ - BaseSS=SegBase(_SEG); \ - core.base_val_ds=_SEG; \ - goto restart_opcode; - -#define DO_PREFIX_ADDR() \ - core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ - (cpu.code.big ^ PREFIX_ADDR); \ - core.ea_table=&EATable[(core.prefixes&1) * 256]; \ - goto restart_opcode; - -#define DO_PREFIX_REP(_ZERO) \ - core.prefixes|=PREFIX_REP; \ - core.rep_zero=_ZERO; \ - goto restart_opcode; - -typedef PhysPt (*GetEAHandler)(void); - -static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; - -static struct { - Bitu opcode_index; - PhysPt cseip; - PhysPt base_ds,base_ss; - SegNames base_val_ds; - bool rep_zero; - Bitu prefixes; - GetEAHandler * ea_table; -} core; - -#define GETIP (core.cseip-SegBase(cs)) -#define SAVEIP reg_eip=GETIP; -#define LOADIP core.cseip=(SegBase(cs)+reg_eip); - -#define SegBase(c) SegPhys(c) -#define BaseDS core.base_ds -#define BaseSS core.base_ss - -static INLINE Bit8u Fetchb() { - Bit8u temp=LoadMb(core.cseip); - core.cseip+=1; - return temp; -} - -static INLINE Bit16u Fetchw() { - Bit16u temp=LoadMw(core.cseip); - core.cseip+=2; - return temp; -} -static INLINE Bit32u Fetchd() { - Bit32u temp=LoadMd(core.cseip); - core.cseip+=4; - return temp; -} - -#define Push_16 CPU_Push16 -#define Push_32 CPU_Push32 -#define Pop_16 CPU_Pop16 -#define Pop_32 CPU_Pop32 - -#include "instructions.h" -#include "core_normal/support.h" -#include "core_normal/string.h" - - -#define EALookupTable (core.ea_table) - -Bits CPU_Core_Normal_Run(void) { - while (CPU_Cycles-->0) { - LOADIP; - core.opcode_index=cpu.code.big*0x200; - core.prefixes=cpu.code.big; - core.ea_table=&EATable[cpu.code.big*256]; - BaseDS=SegBase(ds); - BaseSS=SegBase(ss); - core.base_val_ds=ds; -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - FillFlags(); - return debugCallback; - }; -#endif - cycle_count++; -#endif -restart_opcode: - switch (core.opcode_index+Fetchb()) { - #include "core_normal/prefix_none.h" - #include "core_normal/prefix_0f.h" - #include "core_normal/prefix_66.h" - #include "core_normal/prefix_66_0f.h" - default: - illegal_opcode: -#if C_DEBUG - { - Bitu len=(GETIP-reg_eip); - LOADIP; - if (len>16) len=16; - char tempcode[16*2+1];char * writecode=tempcode; - for (;len>0;len--) { - sprintf(writecode,"%02X",mem_readb(core.cseip++)); - writecode+=2; - } - LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); - } -#endif - CPU_Exception(6,0); - continue; - } - SAVEIP; - } - FillFlags(); - return CBRET_NONE; -decode_end: - SAVEIP; - FillFlags(); - return CBRET_NONE; -} - -Bits CPU_Core_Normal_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - cpu.trap_skip = false; - - Bits ret=CPU_Core_Normal_Run(); - if (!cpu.trap_skip) CPU_HW_Interrupt(1); - CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Normal_Run; - - return ret; -} - - - -void CPU_Core_Normal_Init(void) { - -} - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/Makefile.am b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/Makefile.am deleted file mode 100644 index 99f76f3d2..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ - -noinst_HEADERS = helpers.h prefix_none.h prefix_66.h prefix_0f.h support.h table_ea.h \ - prefix_66_0f.h string.h diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/Makefile.in b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/Makefile.in deleted file mode 100644 index 7e437c59f..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/Makefile.in +++ /dev/null @@ -1,491 +0,0 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/cpu/core_normal -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -WINDRES = @WINDRES@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_HEADERS = helpers.h prefix_none.h prefix_66.h prefix_0f.h support.h table_ea.h \ - prefix_66_0f.h string.h - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/cpu/core_normal/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/cpu/core_normal/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - cscopelist-am ctags ctags-am distclean distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/helpers.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/helpers.h deleted file mode 100644 index 13526f8b4..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/helpers.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#define GetEAa \ - PhysPt eaa=EALookupTable[rm](); - -#define GetRMEAa \ - GetRM; \ - GetEAa; - - -#define RMEbGb(inst) \ - { \ - GetRMrb; \ - if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \ - else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \ - } - -#define RMGbEb(inst) \ - { \ - GetRMrb; \ - if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \ - else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \ - } - -#define RMEb(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \ - else {GetEAa;inst(eaa,LoadMb,SaveMb);} \ - } - -#define RMEwGw(inst) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \ - } - -#define RMEwGwOp3(inst,op3) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \ - } - -#define RMGwEw(inst) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \ - } - -#define RMGwEwOp3(inst,op3) \ - { \ - GetRMrw; \ - if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \ - else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \ - } - -#define RMEw(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ - } - -#define RMEdGd(inst) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \ - } - -#define RMEdGdOp3(inst,op3) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \ - } - - -#define RMGdEd(inst) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \ - else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \ - } - -#define RMGdEdOp3(inst,op3) \ - { \ - GetRMrd; \ - if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \ - else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \ - } - - - - -#define RMEw(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \ - else {GetEAa;inst(eaa,LoadMw,SaveMw);} \ - } - -#define RMEd(inst) \ - { \ - if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \ - else {GetEAa;inst(eaa,LoadMd,SaveMd);} \ - } - -#define ALIb(inst) \ - { inst(reg_al,Fetchb(),LoadRb,SaveRb)} - -#define AXIw(inst) \ - { inst(reg_ax,Fetchw(),LoadRw,SaveRw);} - -#define EAXId(inst) \ - { inst(reg_eax,Fetchd(),LoadRd,SaveRd);} - -#define FPU_ESC(code) { \ - Bit8u rm=Fetchb(); \ - if (rm >= 0xc0) { \ - FPU_ESC ## code ## _Normal(rm); \ - } else { \ - GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \ - } \ -} - -#define CASE_W(_WHICH) \ - case (OPCODE_NONE+_WHICH): - -#define CASE_D(_WHICH) \ - case (OPCODE_SIZE+_WHICH): - -#define CASE_B(_WHICH) \ - CASE_W(_WHICH) \ - CASE_D(_WHICH) - -#define CASE_0F_W(_WHICH) \ - case ((OPCODE_0F|OPCODE_NONE)+_WHICH): - -#define CASE_0F_D(_WHICH) \ - case ((OPCODE_0F|OPCODE_SIZE)+_WHICH): - -#define CASE_0F_B(_WHICH) \ - CASE_0F_W(_WHICH) \ - CASE_0F_D(_WHICH) diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/prefix_0f.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/prefix_0f.h deleted file mode 100644 index 0fcf6b687..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/prefix_0f.h +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - CASE_0F_W(0x00) /* GRP 6 Exxx */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* SLDT */ - case 0x01: /* STR */ - { - Bitu saveval; - if (!which) saveval=CPU_SLDT(); - else saveval=CPU_STR(); - if (rm >= 0xc0) {GetEArw;*earw=saveval;} - else {GetEAa;SaveMw(eaa,saveval);} - } - break; - case 0x02:case 0x03:case 0x04:case 0x05: - { - Bitu loadval; - if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} - else {GetEAa;loadval=LoadMw(eaa);} - switch (which) { - case 0x02: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LLDT(loadval)) RUNEXCEPTION(); - break; - case 0x03: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LTR(loadval)) RUNEXCEPTION(); - break; - case 0x04: - CPU_VERR(loadval); - break; - case 0x05: - CPU_VERW(loadval); - break; - } - } - break; - default: - goto illegal_opcode; - } - } - break; - CASE_0F_W(0x01) /* Group 7 Ew */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit; - switch (which) { - case 0x00: /* SGDT */ - SaveMw(eaa,CPU_SGDT_limit()); - SaveMd(eaa+2,CPU_SGDT_base()); - break; - case 0x01: /* SIDT */ - SaveMw(eaa,CPU_SIDT_limit()); - SaveMd(eaa+2,CPU_SIDT_base()); - break; - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); - break; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF); - break; - case 0x04: /* SMSW */ - SaveMw(eaa,CPU_SMSW()); - break; - case 0x06: /* LMSW */ - limit=LoadMw(eaa); - if (CPU_LMSW(limit)) RUNEXCEPTION(); - break; - case 0x07: /* INVLPG */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - PAGING_ClearTLB(); - break; - } - } else { - GetEArw; - switch (which) { - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x04: /* SMSW */ - *earw=CPU_SMSW(); - break; - case 0x06: /* LMSW */ - if (CPU_LMSW(*earw)) RUNEXCEPTION(); - break; - default: - goto illegal_opcode; - } - } - } - break; - CASE_0F_W(0x02) /* LAR Gw,Ew */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw;Bitu ar=*rmrw; - if (rm >= 0xc0) { - GetEArw;CPU_LAR(*earw,ar); - } else { - GetEAa;CPU_LAR(LoadMw(eaa),ar); - } - *rmrw=(Bit16u)ar; - } - break; - CASE_0F_W(0x03) /* LSL Gw,Ew */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw;Bitu limit=*rmrw; - if (rm >= 0xc0) { - GetEArw;CPU_LSL(*earw,limit); - } else { - GetEAa;CPU_LSL(LoadMw(eaa),limit); - } - *rmrw=(Bit16u)limit; - } - break; - CASE_0F_B(0x06) /* CLTS */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - cpu.cr0&=(~CR0_TASKSWITCH); - break; - CASE_0F_B(0x08) /* INVD */ - CASE_0F_B(0x09) /* WBINVD */ - if (CPU_ArchitectureType> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",which); - } - GetEArd; - Bit32u crx_value; - if (CPU_READ_CRX(which,crx_value)) RUNEXCEPTION(); - *eard=crx_value; - } - break; - CASE_0F_B(0x21) /* MOV Rd,DRx */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR%u with non-register",which); - } - GetEArd; - Bit32u drx_value; - if (CPU_READ_DRX(which,drx_value)) RUNEXCEPTION(); - *eard=drx_value; - } - break; - CASE_0F_B(0x22) /* MOV CRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%u with non-register",which); - } - GetEArd; - if (CPU_WRITE_CRX(which,*eard)) RUNEXCEPTION(); - } - break; - CASE_0F_B(0x23) /* MOV DRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV DR%u,XXX with non-register",which); - } - GetEArd; - if (CPU_WRITE_DRX(which,*eard)) RUNEXCEPTION(); - } - break; - CASE_0F_B(0x24) /* MOV Rd,TRx */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV XXX,TR%u with non-register",which); - } - GetEArd; - Bit32u trx_value; - if (CPU_READ_TRX(which,trx_value)) RUNEXCEPTION(); - *eard=trx_value; - } - break; - CASE_0F_B(0x26) /* MOV TRx,Rd */ - { - GetRM; - Bitu which=(rm >> 3) & 7; - if (rm < 0xc0 ) { - rm |= 0xc0; - LOG(LOG_CPU,LOG_ERROR)("MOV TR%u,XXX with non-register",which); - } - GetEArd; - if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION(); - } - break; - CASE_0F_B(0x31) /* RDTSC */ - { - if (CPU_ArchitectureType>32); - reg_eax=(Bit32u)(tsc&0xffffffff); - } - break; - CASE_0F_W(0x80) /* JO */ - JumpCond16_w(TFLG_O);break; - CASE_0F_W(0x81) /* JNO */ - JumpCond16_w(TFLG_NO);break; - CASE_0F_W(0x82) /* JB */ - JumpCond16_w(TFLG_B);break; - CASE_0F_W(0x83) /* JNB */ - JumpCond16_w(TFLG_NB);break; - CASE_0F_W(0x84) /* JZ */ - JumpCond16_w(TFLG_Z);break; - CASE_0F_W(0x85) /* JNZ */ - JumpCond16_w(TFLG_NZ);break; - CASE_0F_W(0x86) /* JBE */ - JumpCond16_w(TFLG_BE);break; - CASE_0F_W(0x87) /* JNBE */ - JumpCond16_w(TFLG_NBE);break; - CASE_0F_W(0x88) /* JS */ - JumpCond16_w(TFLG_S);break; - CASE_0F_W(0x89) /* JNS */ - JumpCond16_w(TFLG_NS);break; - CASE_0F_W(0x8a) /* JP */ - JumpCond16_w(TFLG_P);break; - CASE_0F_W(0x8b) /* JNP */ - JumpCond16_w(TFLG_NP);break; - CASE_0F_W(0x8c) /* JL */ - JumpCond16_w(TFLG_L);break; - CASE_0F_W(0x8d) /* JNL */ - JumpCond16_w(TFLG_NL);break; - CASE_0F_W(0x8e) /* JLE */ - JumpCond16_w(TFLG_LE);break; - CASE_0F_W(0x8f) /* JNLE */ - JumpCond16_w(TFLG_NLE);break; - CASE_0F_B(0x90) /* SETO */ - SETcc(TFLG_O);break; - CASE_0F_B(0x91) /* SETNO */ - SETcc(TFLG_NO);break; - CASE_0F_B(0x92) /* SETB */ - SETcc(TFLG_B);break; - CASE_0F_B(0x93) /* SETNB */ - SETcc(TFLG_NB);break; - CASE_0F_B(0x94) /* SETZ */ - SETcc(TFLG_Z);break; - CASE_0F_B(0x95) /* SETNZ */ - SETcc(TFLG_NZ); break; - CASE_0F_B(0x96) /* SETBE */ - SETcc(TFLG_BE);break; - CASE_0F_B(0x97) /* SETNBE */ - SETcc(TFLG_NBE);break; - CASE_0F_B(0x98) /* SETS */ - SETcc(TFLG_S);break; - CASE_0F_B(0x99) /* SETNS */ - SETcc(TFLG_NS);break; - CASE_0F_B(0x9a) /* SETP */ - SETcc(TFLG_P);break; - CASE_0F_B(0x9b) /* SETNP */ - SETcc(TFLG_NP);break; - CASE_0F_B(0x9c) /* SETL */ - SETcc(TFLG_L);break; - CASE_0F_B(0x9d) /* SETNL */ - SETcc(TFLG_NL);break; - CASE_0F_B(0x9e) /* SETLE */ - SETcc(TFLG_LE);break; - CASE_0F_B(0x9f) /* SETNLE */ - SETcc(TFLG_NLE);break; - - CASE_0F_W(0xa0) /* PUSH FS */ - Push_16(SegValue(fs));break; - CASE_0F_W(0xa1) /* POP FS */ - if (CPU_PopSeg(fs,false)) RUNEXCEPTION(); - break; - CASE_0F_B(0xa2) /* CPUID */ - if (!CPU_CPUID()) goto illegal_opcode; - break; - CASE_0F_W(0xa3) /* BT Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - } - break; - } - CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */ - RMEwGwOp3(DSHLW,Fetchb()); - break; - CASE_0F_W(0xa5) /* SHLD Ew,Gw,CL */ - RMEwGwOp3(DSHLW,reg_cl); - break; - CASE_0F_W(0xa8) /* PUSH GS */ - Push_16(SegValue(gs));break; - CASE_0F_W(0xa9) /* POP GS */ - if (CPU_PopSeg(gs,false)) RUNEXCEPTION(); - break; - CASE_0F_W(0xab) /* BTS Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw|=mask; - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old | mask); - } - break; - } - CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */ - RMEwGwOp3(DSHRW,Fetchb()); - break; - CASE_0F_W(0xad) /* SHRD Ew,Gw,CL */ - RMEwGwOp3(DSHRW,reg_cl); - break; - CASE_0F_W(0xaf) /* IMUL Gw,Ew */ - RMGwEwOp3(DIMULW,*rmrw); - break; - CASE_0F_B(0xb0) /* cmpxchg Eb,Gb */ - { - if (CPU_ArchitectureType= 0xc0 ) { - GetEArb; - if (reg_al == *earb) { - *earb=*rmrb; - SETFLAGBIT(ZF,1); - } else { - reg_al = *earb; - SETFLAGBIT(ZF,0); - } - } else { - GetEAa; - Bit8u val = LoadMb(eaa); - if (reg_al == val) { - SaveMb(eaa,*rmrb); - SETFLAGBIT(ZF,1); - } else { - SaveMb(eaa,val); // cmpxchg always issues a write - reg_al = val; - SETFLAGBIT(ZF,0); - } - } - break; - } - CASE_0F_W(0xb1) /* cmpxchg Ew,Gw */ - { - if (CPU_ArchitectureType= 0xc0 ) { - GetEArw; - if(reg_ax == *earw) { - *earw = *rmrw; - SETFLAGBIT(ZF,1); - } else { - reg_ax = *earw; - SETFLAGBIT(ZF,0); - } - } else { - GetEAa; - Bit16u val = LoadMw(eaa); - if(reg_ax == val) { - SaveMw(eaa,*rmrw); - SETFLAGBIT(ZF,1); - } else { - SaveMw(eaa,val); // cmpxchg always issues a write - reg_ax = val; - SETFLAGBIT(ZF,0); - } - } - break; - } - - CASE_0F_W(0xb2) /* LSS Ew */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_0F_W(0xb3) /* BTR Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw&= ~mask; - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old & ~mask); - } - break; - } - CASE_0F_W(0xb4) /* LFS Ew */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_0F_W(0xb5) /* LGS Ew */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_0F_W(0xb6) /* MOVZX Gw,Eb */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;} - else {GetEAa;*rmrw=LoadMb(eaa);} - break; - } - CASE_0F_W(0xb7) /* MOVZX Gw,Ew */ - CASE_0F_W(0xbf) /* MOVSX Gw,Ew */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} - else {GetEAa;*rmrw=LoadMw(eaa);} - break; - } - CASE_0F_W(0xba) /* GRP8 Ew,Ib */ - { - FillFlags();GetRM; - if (rm >= 0xc0 ) { - GetEArw; - Bit16u mask=1 << (Fetchb() & 15); - SETFLAGBIT(CF,(*earw & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - *earw|=mask; - break; - case 0x30: /* BTR */ - *earw&= ~mask; - break; - case 0x38: /* BTC */ - *earw^=mask; - break; - default: - E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } else { - GetEAa;Bit16u old=LoadMw(eaa); - Bit16u mask=1 << (Fetchb() & 15); - SETFLAGBIT(CF,(old & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - SaveMw(eaa,old|mask); - break; - case 0x30: /* BTR */ - SaveMw(eaa,old & ~mask); - break; - case 0x38: /* BTC */ - SaveMw(eaa,old ^ mask); - break; - default: - E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } - break; - } - CASE_0F_W(0xbb) /* BTC Ew,Gw */ - { - FillFlags();GetRMrw; - Bit16u mask=1 << (*rmrw & 15); - if (rm >= 0xc0 ) { - GetEArw; - SETFLAGBIT(CF,(*earw & mask)); - *earw^=mask; - } else { - GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2; - Bit16u old=LoadMw(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMw(eaa,old ^ mask); - } - break; - } - CASE_0F_W(0xbc) /* BSF Gw,Ew */ - { - GetRMrw; - Bit16u result,value; - if (rm >= 0xc0) { GetEArw; value=*earw; } - else { GetEAa; value=LoadMw(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 0; - while ((value & 0x01)==0) { result++; value>>=1; } - SETFLAGBIT(ZF,false); - *rmrw = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_W(0xbd) /* BSR Gw,Ew */ - { - GetRMrw; - Bit16u result,value; - if (rm >= 0xc0) { GetEArw; value=*earw; } - else { GetEAa; value=LoadMw(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 15; // Operandsize-1 - while ((value & 0x8000)==0) { result--; value<<=1; } - SETFLAGBIT(ZF,false); - *rmrw = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_W(0xbe) /* MOVSX Gw,Eb */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;} - else {GetEAa;*rmrw=LoadMbs(eaa);} - break; - } - CASE_0F_B(0xc0) /* XADD Gb,Eb */ - { - if (CPU_ArchitectureType= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;} - else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);} - break; - } - CASE_0F_W(0xc1) /* XADD Gw,Ew */ - { - if (CPU_ArchitectureType= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;} - else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);} - break; - } - CASE_0F_W(0xc8) /* BSWAP AX */ - if (CPU_ArchitectureType bound_max) ) { - EXCEPTION(5); - } - } - break; - CASE_D(0x63) /* ARPL Ed,Rd */ - { - if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw; - if (rm >= 0xc0 ) { - GetEArd;Bitu new_sel=(Bit16u)*eard; - CPU_ARPL(new_sel,*rmrw); - *eard=(Bit32u)new_sel; - } else { - GetEAa;Bitu new_sel=LoadMw(eaa); - CPU_ARPL(new_sel,*rmrw); - SaveMd(eaa,(Bit32u)new_sel); - } - } - break; - CASE_D(0x68) /* PUSH Id */ - Push_32(Fetchd());break; - CASE_D(0x69) /* IMUL Gd,Ed,Id */ - RMGdEdOp3(DIMULD,Fetchds()); - break; - CASE_D(0x6a) /* PUSH Ib */ - Push_32(Fetchbs());break; - CASE_D(0x6b) /* IMUL Gd,Ed,Ib */ - RMGdEdOp3(DIMULD,Fetchbs()); - break; - CASE_D(0x6d) /* INSD */ - if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); - DoString(R_INSD);break; - CASE_D(0x6f) /* OUTSD */ - if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION(); - DoString(R_OUTSD);break; - CASE_D(0x70) /* JO */ - JumpCond32_b(TFLG_O);break; - CASE_D(0x71) /* JNO */ - JumpCond32_b(TFLG_NO);break; - CASE_D(0x72) /* JB */ - JumpCond32_b(TFLG_B);break; - CASE_D(0x73) /* JNB */ - JumpCond32_b(TFLG_NB);break; - CASE_D(0x74) /* JZ */ - JumpCond32_b(TFLG_Z);break; - CASE_D(0x75) /* JNZ */ - JumpCond32_b(TFLG_NZ);break; - CASE_D(0x76) /* JBE */ - JumpCond32_b(TFLG_BE);break; - CASE_D(0x77) /* JNBE */ - JumpCond32_b(TFLG_NBE);break; - CASE_D(0x78) /* JS */ - JumpCond32_b(TFLG_S);break; - CASE_D(0x79) /* JNS */ - JumpCond32_b(TFLG_NS);break; - CASE_D(0x7a) /* JP */ - JumpCond32_b(TFLG_P);break; - CASE_D(0x7b) /* JNP */ - JumpCond32_b(TFLG_NP);break; - CASE_D(0x7c) /* JL */ - JumpCond32_b(TFLG_L);break; - CASE_D(0x7d) /* JNL */ - JumpCond32_b(TFLG_NL);break; - CASE_D(0x7e) /* JLE */ - JumpCond32_b(TFLG_LE);break; - CASE_D(0x7f) /* JNLE */ - JumpCond32_b(TFLG_NLE);break; - CASE_D(0x81) /* Grpl Ed,Id */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm >= 0xc0) { - GetEArd;Bit32u id=Fetchd(); - switch (which) { - case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; - case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; - case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; - case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; - case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; - case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; - case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; - case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; - } - } else { - GetEAa;Bit32u id=Fetchd(); - switch (which) { - case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; - case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; - case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; - case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; - case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; - case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; - case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; - case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; - } - } - } - break; - CASE_D(0x83) /* Grpl Ed,Ix */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm >= 0xc0) { - GetEArd;Bit32u id=(Bit32s)Fetchbs(); - switch (which) { - case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break; - case 0x01: ORD(*eard,id,LoadRd,SaveRd);break; - case 0x02:ADCD(*eard,id,LoadRd,SaveRd);break; - case 0x03:SBBD(*eard,id,LoadRd,SaveRd);break; - case 0x04:ANDD(*eard,id,LoadRd,SaveRd);break; - case 0x05:SUBD(*eard,id,LoadRd,SaveRd);break; - case 0x06:XORD(*eard,id,LoadRd,SaveRd);break; - case 0x07:CMPD(*eard,id,LoadRd,SaveRd);break; - } - } else { - GetEAa;Bit32u id=(Bit32s)Fetchbs(); - switch (which) { - case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break; - case 0x01: ORD(eaa,id,LoadMd,SaveMd);break; - case 0x02:ADCD(eaa,id,LoadMd,SaveMd);break; - case 0x03:SBBD(eaa,id,LoadMd,SaveMd);break; - case 0x04:ANDD(eaa,id,LoadMd,SaveMd);break; - case 0x05:SUBD(eaa,id,LoadMd,SaveMd);break; - case 0x06:XORD(eaa,id,LoadMd,SaveMd);break; - case 0x07:CMPD(eaa,id,LoadMd,SaveMd);break; - } - } - } - break; - CASE_D(0x85) /* TEST Ed,Gd */ - RMEdGd(TESTD);break; - CASE_D(0x87) /* XCHG Ed,Gd */ - { - GetRMrd;Bit32u oldrmrd=*rmrd; - if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;} - else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);} - break; - } - CASE_D(0x89) /* MOV Ed,Gd */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;} - else {GetEAa;SaveMd(eaa,*rmrd);} - break; - } - CASE_D(0x8b) /* MOV Gd,Ed */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;} - else {GetEAa;*rmrd=LoadMd(eaa);} - break; - } - CASE_D(0x8c) /* Mov Ew,Sw */ - { - GetRM;Bit16u val;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* MOV Ew,ES */ - val=SegValue(es);break; - case 0x01: /* MOV Ew,CS */ - val=SegValue(cs);break; - case 0x02: /* MOV Ew,SS */ - val=SegValue(ss);break; - case 0x03: /* MOV Ew,DS */ - val=SegValue(ds);break; - case 0x04: /* MOV Ew,FS */ - val=SegValue(fs);break; - case 0x05: /* MOV Ew,GS */ - val=SegValue(gs);break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); - goto illegal_opcode; - } - if (rm >= 0xc0 ) {GetEArd;*eard=val;} - else {GetEAa;SaveMw(eaa,val);} - break; - } - CASE_D(0x8d) /* LEA Gd */ - { - //Little hack to always use segprefixed version - GetRMrd; - BaseDS=BaseSS=0; - if (TEST_PREFIX_ADDR) { - *rmrd=(Bit32u)(*EATable[256+rm])(); - } else { - *rmrd=(Bit32u)(*EATable[rm])(); - } - break; - } - CASE_D(0x8f) /* POP Ed */ - { - Bit32u val=Pop_32(); - GetRM; - if (rm >= 0xc0 ) {GetEArd;*eard=val;} - else {GetEAa;SaveMd(eaa,val);} - break; - } - CASE_D(0x91) /* XCHG ECX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp;break;} - CASE_D(0x92) /* XCHG EDX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp;break;} - break; - CASE_D(0x93) /* XCHG EBX,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp;break;} - break; - CASE_D(0x94) /* XCHG ESP,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp;break;} - break; - CASE_D(0x95) /* XCHG EBP,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp;break;} - break; - CASE_D(0x96) /* XCHG ESI,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp;break;} - break; - CASE_D(0x97) /* XCHG EDI,EAX */ - { Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp;break;} - break; - CASE_D(0x98) /* CWDE */ - reg_eax=(Bit16s)reg_ax;break; - CASE_D(0x99) /* CDQ */ - if (reg_eax & 0x80000000) reg_edx=0xffffffff; - else reg_edx=0; - break; - CASE_D(0x9a) /* CALL FAR Ad */ - { - Bit32u newip=Fetchd();Bit16u newcs=Fetchw(); - FillFlags(); - CPU_CALL(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_D(0x9c) /* PUSHFD */ - if (CPU_PUSHF(true)) RUNEXCEPTION(); - break; - CASE_D(0x9d) /* POPFD */ - if (CPU_POPF(true)) RUNEXCEPTION(); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - goto decode_end; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - CASE_D(0xa1) /* MOV EAX,Od */ - { - GetEADirect; - reg_eax=LoadMd(eaa); - } - break; - CASE_D(0xa3) /* MOV Od,EAX */ - { - GetEADirect; - SaveMd(eaa,reg_eax); - } - break; - CASE_D(0xa5) /* MOVSD */ - DoString(R_MOVSD);break; - CASE_D(0xa7) /* CMPSD */ - DoString(R_CMPSD);break; - CASE_D(0xa9) /* TEST EAX,Id */ - EAXId(TESTD);break; - CASE_D(0xab) /* STOSD */ - DoString(R_STOSD);break; - CASE_D(0xad) /* LODSD */ - DoString(R_LODSD);break; - CASE_D(0xaf) /* SCASD */ - DoString(R_SCASD);break; - CASE_D(0xb8) /* MOV EAX,Id */ - reg_eax=Fetchd();break; - CASE_D(0xb9) /* MOV ECX,Id */ - reg_ecx=Fetchd();break; - CASE_D(0xba) /* MOV EDX,Iw */ - reg_edx=Fetchd();break; - CASE_D(0xbb) /* MOV EBX,Id */ - reg_ebx=Fetchd();break; - CASE_D(0xbc) /* MOV ESP,Id */ - reg_esp=Fetchd();break; - CASE_D(0xbd) /* MOV EBP.Id */ - reg_ebp=Fetchd();break; - CASE_D(0xbe) /* MOV ESI,Id */ - reg_esi=Fetchd();break; - CASE_D(0xbf) /* MOV EDI,Id */ - reg_edi=Fetchd();break; - CASE_D(0xc1) /* GRP2 Ed,Ib */ - GRP2D(Fetchb());break; - CASE_D(0xc2) /* RETN Iw */ - reg_eip=Pop_32(); - reg_esp+=Fetchw(); - continue; - CASE_D(0xc3) /* RETN */ - reg_eip=Pop_32(); - continue; - CASE_D(0xc4) /* LES */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_D(0xc5) /* LDS */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_D(0xc7) /* MOV Ed,Id */ - { - GetRM; - if (rm >= 0xc0) {GetEArd;*eard=Fetchd();} - else {GetEAa;SaveMd(eaa,Fetchd());} - break; - } - CASE_D(0xc8) /* ENTER Iw,Ib */ - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(true,bytes,level); - } - break; - CASE_D(0xc9) /* LEAVE */ - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_ebp=Pop_32(); - break; - CASE_D(0xca) /* RETF Iw */ - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(true,words,GETIP); - continue; - } - CASE_D(0xcb) /* RETF */ - { - FillFlags(); - CPU_RET(true,0,GETIP); - continue; - } - CASE_D(0xcf) /* IRET */ - { - CPU_IRET(true,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; -#endif - continue; - } - CASE_D(0xd1) /* GRP2 Ed,1 */ - GRP2D(1);break; - CASE_D(0xd3) /* GRP2 Ed,CL */ - GRP2D(reg_cl);break; - CASE_D(0xe0) /* LOOPNZ */ - if (TEST_PREFIX_ADDR) { - JumpCond32_b(--reg_ecx && !get_ZF()); - } else { - JumpCond32_b(--reg_cx && !get_ZF()); - } - break; - CASE_D(0xe1) /* LOOPZ */ - if (TEST_PREFIX_ADDR) { - JumpCond32_b(--reg_ecx && get_ZF()); - } else { - JumpCond32_b(--reg_cx && get_ZF()); - } - break; - CASE_D(0xe2) /* LOOP */ - if (TEST_PREFIX_ADDR) { - JumpCond32_b(--reg_ecx); - } else { - JumpCond32_b(--reg_cx); - } - break; - CASE_D(0xe3) /* JCXZ */ - JumpCond32_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR])); - break; - CASE_D(0xe5) /* IN EAX,Ib */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,4)) RUNEXCEPTION(); - reg_eax=IO_ReadD(port); - break; - } - CASE_D(0xe7) /* OUT Ib,EAX */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,4)) RUNEXCEPTION(); - IO_WriteD(port,reg_eax); - break; - } - CASE_D(0xe8) /* CALL Jd */ - { - Bit32s addip=Fetchds(); - SAVEIP; - Push_32(reg_eip); - reg_eip+=addip; - continue; - } - CASE_D(0xe9) /* JMP Jd */ - { - Bit32s addip=Fetchds(); - SAVEIP; - reg_eip+=addip; - continue; - } - CASE_D(0xea) /* JMP Ad */ - { - Bit32u newip=Fetchd(); - Bit16u newcs=Fetchw(); - FillFlags(); - CPU_JMP(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_D(0xeb) /* JMP Jb */ - { - Bit32s addip=Fetchbs(); - SAVEIP; - reg_eip+=addip; - continue; - } - CASE_D(0xed) /* IN EAX,DX */ - reg_eax=IO_ReadD(reg_dx); - break; - CASE_D(0xef) /* OUT DX,EAX */ - IO_WriteD(reg_dx,reg_eax); - break; - CASE_D(0xf7) /* GRP3 Ed(,Id) */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* TEST Ed,Id */ - case 0x01: /* TEST Ed,Id Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);} - else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);} - break; - } - case 0x02: /* NOT Ed */ - { - if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;} - else {GetEAa;SaveMd(eaa,~LoadMd(eaa));} - break; - } - case 0x03: /* NEG Ed */ - { - lflags.type=t_NEGd; - if (rm >= 0xc0 ) { - GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d; - *eard=lf_resd; - } else { - GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d; - SaveMd(eaa,lf_resd); - } - break; - } - case 0x04: /* MUL EAX,Ed */ - RMEd(MULD); - break; - case 0x05: /* IMUL EAX,Ed */ - RMEd(IMULD); - break; - case 0x06: /* DIV Ed */ - RMEd(DIVD); - break; - case 0x07: /* IDIV Ed */ - RMEd(IDIVD); - break; - } - break; - } - CASE_D(0xff) /* GRP 5 Ed */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* INC Ed */ - RMEd(INCD); - break; - case 0x01: /* DEC Ed */ - RMEd(DECD); - break; - case 0x02: /* CALL NEAR Ed */ - if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} - else {GetEAa;reg_eip=LoadMd(eaa);} - Push_32(GETIP); - continue; - case 0x03: /* CALL FAR Ed */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit32u newip=LoadMd(eaa); - Bit16u newcs=LoadMw(eaa+4); - FillFlags(); - CPU_CALL(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - case 0x04: /* JMP NEAR Ed */ - if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;} - else {GetEAa;reg_eip=LoadMd(eaa);} - continue; - case 0x05: /* JMP FAR Ed */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit32u newip=LoadMd(eaa); - Bit16u newcs=LoadMw(eaa+4); - FillFlags(); - CPU_JMP(true,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - break; - case 0x06: /* Push Ed */ - if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);} - else {GetEAa;Push_32(LoadMd(eaa));} - break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:66:GRP5:Illegal call %2X",which); - goto illegal_opcode; - } - break; - } - - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/prefix_66_0f.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/prefix_66_0f.h deleted file mode 100644 index 8f41f9a89..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/prefix_66_0f.h +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - CASE_0F_D(0x00) /* GRP 6 Exxx */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* SLDT */ - case 0x01: /* STR */ - { - Bitu saveval; - if (!which) saveval=CPU_SLDT(); - else saveval=CPU_STR(); - if (rm >= 0xc0) {GetEArw;*earw=(Bit16u)saveval;} - else {GetEAa;SaveMw(eaa,saveval);} - } - break; - case 0x02:case 0x03:case 0x04:case 0x05: - { - /* Just use 16-bit loads since were only using selectors */ - Bitu loadval; - if (rm >= 0xc0 ) {GetEArw;loadval=*earw;} - else {GetEAa;loadval=LoadMw(eaa);} - switch (which) { - case 0x02: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LLDT(loadval)) RUNEXCEPTION(); - break; - case 0x03: - if (cpu.cpl) EXCEPTION(EXCEPTION_GP); - if (CPU_LTR(loadval)) RUNEXCEPTION(); - break; - case 0x04: - CPU_VERR(loadval); - break; - case 0x05: - CPU_VERW(loadval); - break; - } - } - break; - default: - LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which); - goto illegal_opcode; - } - } - break; - CASE_0F_D(0x01) /* Group 7 Ed */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm < 0xc0) { //First ones all use EA - GetEAa;Bitu limit; - switch (which) { - case 0x00: /* SGDT */ - SaveMw(eaa,(Bit16u)CPU_SGDT_limit()); - SaveMd(eaa+2,(Bit32u)CPU_SGDT_base()); - break; - case 0x01: /* SIDT */ - SaveMw(eaa,(Bit16u)CPU_SIDT_limit()); - SaveMd(eaa+2,(Bit32u)CPU_SIDT_base()); - break; - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2)); - break; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2)); - break; - case 0x04: /* SMSW */ - SaveMw(eaa,(Bit16u)CPU_SMSW()); - break; - case 0x06: /* LMSW */ - limit=LoadMw(eaa); - if (CPU_LMSW((Bit16u)limit)) RUNEXCEPTION(); - break; - case 0x07: /* INVLPG */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - PAGING_ClearTLB(); - break; - } - } else { - GetEArd; - switch (which) { - case 0x02: /* LGDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x03: /* LIDT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - goto illegal_opcode; - case 0x04: /* SMSW */ - *eard=(Bit32u)CPU_SMSW(); - break; - case 0x06: /* LMSW */ - if (CPU_LMSW(*eard)) RUNEXCEPTION(); - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which); - goto illegal_opcode; - break; - } - - } - } - break; - CASE_0F_D(0x02) /* LAR Gd,Ed */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrd;Bitu ar=*rmrd; - if (rm >= 0xc0) { - GetEArw;CPU_LAR(*earw,ar); - } else { - GetEAa;CPU_LAR(LoadMw(eaa),ar); - } - *rmrd=(Bit32u)ar; - } - break; - CASE_0F_D(0x03) /* LSL Gd,Ew */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrd;Bitu limit=*rmrd; - /* Just load 16-bit values for selectors */ - if (rm >= 0xc0) { - GetEArw;CPU_LSL(*earw,limit); - } else { - GetEAa;CPU_LSL(LoadMw(eaa),limit); - } - *rmrd=(Bit32u)limit; - } - break; - CASE_0F_D(0x80) /* JO */ - JumpCond32_d(TFLG_O);break; - CASE_0F_D(0x81) /* JNO */ - JumpCond32_d(TFLG_NO);break; - CASE_0F_D(0x82) /* JB */ - JumpCond32_d(TFLG_B);break; - CASE_0F_D(0x83) /* JNB */ - JumpCond32_d(TFLG_NB);break; - CASE_0F_D(0x84) /* JZ */ - JumpCond32_d(TFLG_Z);break; - CASE_0F_D(0x85) /* JNZ */ - JumpCond32_d(TFLG_NZ);break; - CASE_0F_D(0x86) /* JBE */ - JumpCond32_d(TFLG_BE);break; - CASE_0F_D(0x87) /* JNBE */ - JumpCond32_d(TFLG_NBE);break; - CASE_0F_D(0x88) /* JS */ - JumpCond32_d(TFLG_S);break; - CASE_0F_D(0x89) /* JNS */ - JumpCond32_d(TFLG_NS);break; - CASE_0F_D(0x8a) /* JP */ - JumpCond32_d(TFLG_P);break; - CASE_0F_D(0x8b) /* JNP */ - JumpCond32_d(TFLG_NP);break; - CASE_0F_D(0x8c) /* JL */ - JumpCond32_d(TFLG_L);break; - CASE_0F_D(0x8d) /* JNL */ - JumpCond32_d(TFLG_NL);break; - CASE_0F_D(0x8e) /* JLE */ - JumpCond32_d(TFLG_LE);break; - CASE_0F_D(0x8f) /* JNLE */ - JumpCond32_d(TFLG_NLE);break; - - CASE_0F_D(0xa0) /* PUSH FS */ - Push_32(SegValue(fs));break; - CASE_0F_D(0xa1) /* POP FS */ - if (CPU_PopSeg(fs,true)) RUNEXCEPTION(); - break; - CASE_0F_D(0xa3) /* BT Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - } - break; - } - CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */ - RMEdGdOp3(DSHLD,Fetchb()); - break; - CASE_0F_D(0xa5) /* SHLD Ed,Gd,CL */ - RMEdGdOp3(DSHLD,reg_cl); - break; - CASE_0F_D(0xa8) /* PUSH GS */ - Push_32(SegValue(gs));break; - CASE_0F_D(0xa9) /* POP GS */ - if (CPU_PopSeg(gs,true)) RUNEXCEPTION(); - break; - CASE_0F_D(0xab) /* BTS Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - *eard|=mask; - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMd(eaa,old | mask); - } - break; - } - - CASE_0F_D(0xac) /* SHRD Ed,Gd,Ib */ - RMEdGdOp3(DSHRD,Fetchb()); - break; - CASE_0F_D(0xad) /* SHRD Ed,Gd,CL */ - RMEdGdOp3(DSHRD,reg_cl); - break; - CASE_0F_D(0xaf) /* IMUL Gd,Ed */ - { - RMGdEdOp3(DIMULD,*rmrd); - break; - } - CASE_0F_D(0xb1) /* CMPXCHG Ed,Gd */ - { - if (CPU_ArchitectureType= 0xc0) { - GetEArd; - if (*eard==reg_eax) { - *eard=*rmrd; - SETFLAGBIT(ZF,1); - } else { - reg_eax=*eard; - SETFLAGBIT(ZF,0); - } - } else { - GetEAa; - Bit32u val=LoadMd(eaa); - if (val==reg_eax) { - SaveMd(eaa,*rmrd); - SETFLAGBIT(ZF,1); - } else { - SaveMd(eaa,val); // cmpxchg always issues a write - reg_eax=val; - SETFLAGBIT(ZF,0); - } - } - break; - } - CASE_0F_D(0xb2) /* LSS Ed */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ss,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_0F_D(0xb3) /* BTR Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - *eard&= ~mask; - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMd(eaa,old & ~mask); - } - break; - } - CASE_0F_D(0xb4) /* LFS Ed */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(fs,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_0F_D(0xb5) /* LGS Ed */ - { - GetRMrd; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(gs,LoadMw(eaa+4))) RUNEXCEPTION(); - *rmrd=LoadMd(eaa); - break; - } - CASE_0F_D(0xb6) /* MOVZX Gd,Eb */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;} - else {GetEAa;*rmrd=LoadMb(eaa);} - break; - } - CASE_0F_D(0xb7) /* MOVXZ Gd,Ew */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;} - else {GetEAa;*rmrd=LoadMw(eaa);} - break; - } - CASE_0F_D(0xba) /* GRP8 Ed,Ib */ - { - FillFlags();GetRM; - if (rm >= 0xc0 ) { - GetEArd; - Bit32u mask=1 << (Fetchb() & 31); - SETFLAGBIT(CF,(*eard & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - *eard|=mask; - break; - case 0x30: /* BTR */ - *eard&=~mask; - break; - case 0x38: /* BTC */ - if (GETFLAG(CF)) *eard&=~mask; - else *eard|=mask; - break; - default: - E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } else { - GetEAa;Bit32u old=LoadMd(eaa); - Bit32u mask=1 << (Fetchb() & 31); - SETFLAGBIT(CF,(old & mask)); - switch (rm & 0x38) { - case 0x20: /* BT */ - break; - case 0x28: /* BTS */ - SaveMd(eaa,old|mask); - break; - case 0x30: /* BTR */ - SaveMd(eaa,old & ~mask); - break; - case 0x38: /* BTC */ - if (GETFLAG(CF)) old&=~mask; - else old|=mask; - SaveMd(eaa,old); - break; - default: - E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38); - } - } - break; - } - CASE_0F_D(0xbb) /* BTC Ed,Gd */ - { - FillFlags();GetRMrd; - Bit32u mask=1 << (*rmrd & 31); - if (rm >= 0xc0 ) { - GetEArd; - SETFLAGBIT(CF,(*eard & mask)); - *eard^=mask; - } else { - GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4; - Bit32u old=LoadMd(eaa); - SETFLAGBIT(CF,(old & mask)); - SaveMd(eaa,old ^ mask); - } - break; - } - CASE_0F_D(0xbc) /* BSF Gd,Ed */ - { - GetRMrd; - Bit32u result,value; - if (rm >= 0xc0) { GetEArd; value=*eard; } - else { GetEAa; value=LoadMd(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 0; - while ((value & 0x01)==0) { result++; value>>=1; } - SETFLAGBIT(ZF,false); - *rmrd = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_D(0xbd) /* BSR Gd,Ed */ - { - GetRMrd; - Bit32u result,value; - if (rm >= 0xc0) { GetEArd; value=*eard; } - else { GetEAa; value=LoadMd(eaa); } - if (value==0) { - SETFLAGBIT(ZF,true); - } else { - result = 31; // Operandsize-1 - while ((value & 0x80000000)==0) { result--; value<<=1; } - SETFLAGBIT(ZF,false); - *rmrd = result; - } - lflags.type=t_UNKNOWN; - break; - } - CASE_0F_D(0xbe) /* MOVSX Gd,Eb */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;} - else {GetEAa;*rmrd=LoadMbs(eaa);} - break; - } - CASE_0F_D(0xbf) /* MOVSX Gd,Ew */ - { - GetRMrd; - if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;} - else {GetEAa;*rmrd=LoadMws(eaa);} - break; - } - CASE_0F_D(0xc1) /* XADD Gd,Ed */ - { - if (CPU_ArchitectureType= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;} - else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);} - break; - } - CASE_0F_D(0xc8) /* BSWAP EAX */ - if (CPU_ArchitectureType bound_max) ) { - EXCEPTION(5); - } - } - break; - CASE_W(0x63) /* ARPL Ew,Rw */ - { - if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode; - GetRMrw; - if (rm >= 0xc0 ) { - GetEArw;Bitu new_sel=*earw; - CPU_ARPL(new_sel,*rmrw); - *earw=(Bit16u)new_sel; - } else { - GetEAa;Bitu new_sel=LoadMw(eaa); - CPU_ARPL(new_sel,*rmrw); - SaveMw(eaa,(Bit16u)new_sel); - } - } - break; - CASE_B(0x64) /* SEG FS: */ - DO_PREFIX_SEG(fs);break; - CASE_B(0x65) /* SEG GS: */ - DO_PREFIX_SEG(gs);break; - CASE_B(0x66) /* Operand Size Prefix */ - core.opcode_index=(cpu.code.big^0x1)*0x200; - goto restart_opcode; - CASE_B(0x67) /* Address Size Prefix */ - DO_PREFIX_ADDR(); - CASE_W(0x68) /* PUSH Iw */ - Push_16(Fetchw());break; - CASE_W(0x69) /* IMUL Gw,Ew,Iw */ - RMGwEwOp3(DIMULW,Fetchws()); - break; - CASE_W(0x6a) /* PUSH Ib */ - Push_16(Fetchbs()); - break; - CASE_W(0x6b) /* IMUL Gw,Ew,Ib */ - RMGwEwOp3(DIMULW,Fetchbs()); - break; - CASE_B(0x6c) /* INSB */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - DoString(R_INSB);break; - CASE_W(0x6d) /* INSW */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - DoString(R_INSW);break; - CASE_B(0x6e) /* OUTSB */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - DoString(R_OUTSB);break; - CASE_W(0x6f) /* OUTSW */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - DoString(R_OUTSW);break; - CASE_W(0x70) /* JO */ - JumpCond16_b(TFLG_O);break; - CASE_W(0x71) /* JNO */ - JumpCond16_b(TFLG_NO);break; - CASE_W(0x72) /* JB */ - JumpCond16_b(TFLG_B);break; - CASE_W(0x73) /* JNB */ - JumpCond16_b(TFLG_NB);break; - CASE_W(0x74) /* JZ */ - JumpCond16_b(TFLG_Z);break; - CASE_W(0x75) /* JNZ */ - JumpCond16_b(TFLG_NZ);break; - CASE_W(0x76) /* JBE */ - JumpCond16_b(TFLG_BE);break; - CASE_W(0x77) /* JNBE */ - JumpCond16_b(TFLG_NBE);break; - CASE_W(0x78) /* JS */ - JumpCond16_b(TFLG_S);break; - CASE_W(0x79) /* JNS */ - JumpCond16_b(TFLG_NS);break; - CASE_W(0x7a) /* JP */ - JumpCond16_b(TFLG_P);break; - CASE_W(0x7b) /* JNP */ - JumpCond16_b(TFLG_NP);break; - CASE_W(0x7c) /* JL */ - JumpCond16_b(TFLG_L);break; - CASE_W(0x7d) /* JNL */ - JumpCond16_b(TFLG_NL);break; - CASE_W(0x7e) /* JLE */ - JumpCond16_b(TFLG_LE);break; - CASE_W(0x7f) /* JNLE */ - JumpCond16_b(TFLG_NLE);break; - CASE_B(0x80) /* Grpl Eb,Ib */ - CASE_B(0x82) /* Grpl Eb,Ib Mirror instruction*/ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm>= 0xc0) { - GetEArb;Bit8u ib=Fetchb(); - switch (which) { - case 0x00:ADDB(*earb,ib,LoadRb,SaveRb);break; - case 0x01: ORB(*earb,ib,LoadRb,SaveRb);break; - case 0x02:ADCB(*earb,ib,LoadRb,SaveRb);break; - case 0x03:SBBB(*earb,ib,LoadRb,SaveRb);break; - case 0x04:ANDB(*earb,ib,LoadRb,SaveRb);break; - case 0x05:SUBB(*earb,ib,LoadRb,SaveRb);break; - case 0x06:XORB(*earb,ib,LoadRb,SaveRb);break; - case 0x07:CMPB(*earb,ib,LoadRb,SaveRb);break; - } - } else { - GetEAa;Bit8u ib=Fetchb(); - switch (which) { - case 0x00:ADDB(eaa,ib,LoadMb,SaveMb);break; - case 0x01: ORB(eaa,ib,LoadMb,SaveMb);break; - case 0x02:ADCB(eaa,ib,LoadMb,SaveMb);break; - case 0x03:SBBB(eaa,ib,LoadMb,SaveMb);break; - case 0x04:ANDB(eaa,ib,LoadMb,SaveMb);break; - case 0x05:SUBB(eaa,ib,LoadMb,SaveMb);break; - case 0x06:XORB(eaa,ib,LoadMb,SaveMb);break; - case 0x07:CMPB(eaa,ib,LoadMb,SaveMb);break; - } - } - break; - } - CASE_W(0x81) /* Grpl Ew,Iw */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm>= 0xc0) { - GetEArw;Bit16u iw=Fetchw(); - switch (which) { - case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; - case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; - case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; - case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; - case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; - case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; - case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; - case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; - } - } else { - GetEAa;Bit16u iw=Fetchw(); - switch (which) { - case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; - case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; - case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; - case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; - case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; - case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; - case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; - case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; - } - } - break; - } - CASE_W(0x83) /* Grpl Ew,Ix */ - { - GetRM;Bitu which=(rm>>3)&7; - if (rm>= 0xc0) { - GetEArw;Bit16u iw=(Bit16s)Fetchbs(); - switch (which) { - case 0x00:ADDW(*earw,iw,LoadRw,SaveRw);break; - case 0x01: ORW(*earw,iw,LoadRw,SaveRw);break; - case 0x02:ADCW(*earw,iw,LoadRw,SaveRw);break; - case 0x03:SBBW(*earw,iw,LoadRw,SaveRw);break; - case 0x04:ANDW(*earw,iw,LoadRw,SaveRw);break; - case 0x05:SUBW(*earw,iw,LoadRw,SaveRw);break; - case 0x06:XORW(*earw,iw,LoadRw,SaveRw);break; - case 0x07:CMPW(*earw,iw,LoadRw,SaveRw);break; - } - } else { - GetEAa;Bit16u iw=(Bit16s)Fetchbs(); - switch (which) { - case 0x00:ADDW(eaa,iw,LoadMw,SaveMw);break; - case 0x01: ORW(eaa,iw,LoadMw,SaveMw);break; - case 0x02:ADCW(eaa,iw,LoadMw,SaveMw);break; - case 0x03:SBBW(eaa,iw,LoadMw,SaveMw);break; - case 0x04:ANDW(eaa,iw,LoadMw,SaveMw);break; - case 0x05:SUBW(eaa,iw,LoadMw,SaveMw);break; - case 0x06:XORW(eaa,iw,LoadMw,SaveMw);break; - case 0x07:CMPW(eaa,iw,LoadMw,SaveMw);break; - } - } - break; - } - CASE_B(0x84) /* TEST Eb,Gb */ - RMEbGb(TESTB); - break; - CASE_W(0x85) /* TEST Ew,Gw */ - RMEwGw(TESTW); - break; - CASE_B(0x86) /* XCHG Eb,Gb */ - { - GetRMrb;Bit8u oldrmrb=*rmrb; - if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb=oldrmrb;} - else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,oldrmrb);} - break; - } - CASE_W(0x87) /* XCHG Ew,Gw */ - { - GetRMrw;Bit16u oldrmrw=*rmrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw=oldrmrw;} - else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,oldrmrw);} - break; - } - CASE_B(0x88) /* MOV Eb,Gb */ - { - GetRMrb; - if (rm >= 0xc0 ) {GetEArb;*earb=*rmrb;} - else { - if (cpu.pmode) { - if (GCC_UNLIKELY((rm==0x05) && (!cpu.code.big))) { - Descriptor desc; - cpu.gdt.GetDescriptor(SegValue(core.base_val_ds),desc); - if ((desc.Type()==DESC_CODE_R_NC_A) || (desc.Type()==DESC_CODE_R_NC_NA)) { - CPU_Exception(EXCEPTION_GP,SegValue(core.base_val_ds) & 0xfffc); - continue; - } - } - } - GetEAa;SaveMb(eaa,*rmrb); - } - break; - } - CASE_W(0x89) /* MOV Ew,Gw */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*earw=*rmrw;} - else {GetEAa;SaveMw(eaa,*rmrw);} - break; - } - CASE_B(0x8a) /* MOV Gb,Eb */ - { - GetRMrb; - if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;} - else {GetEAa;*rmrb=LoadMb(eaa);} - break; - } - CASE_W(0x8b) /* MOV Gw,Ew */ - { - GetRMrw; - if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;} - else {GetEAa;*rmrw=LoadMw(eaa);} - break; - } - CASE_W(0x8c) /* Mov Ew,Sw */ - { - GetRM;Bit16u val;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* MOV Ew,ES */ - val=SegValue(es);break; - case 0x01: /* MOV Ew,CS */ - val=SegValue(cs);break; - case 0x02: /* MOV Ew,SS */ - val=SegValue(ss);break; - case 0x03: /* MOV Ew,DS */ - val=SegValue(ds);break; - case 0x04: /* MOV Ew,FS */ - val=SegValue(fs);break; - case 0x05: /* MOV Ew,GS */ - val=SegValue(gs);break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:8c:Illegal RM Byte"); - goto illegal_opcode; - } - if (rm >= 0xc0 ) {GetEArw;*earw=val;} - else {GetEAa;SaveMw(eaa,val);} - break; - } - CASE_W(0x8d) /* LEA Gw */ - { - //Little hack to always use segprefixed version - BaseDS=BaseSS=0; - GetRMrw; - if (TEST_PREFIX_ADDR) { - *rmrw=(Bit16u)(*EATable[256+rm])(); - } else { - *rmrw=(Bit16u)(*EATable[rm])(); - } - break; - } - CASE_B(0x8e) /* MOV Sw,Ew */ - { - GetRM;Bit16u val;Bitu which=(rm>>3)&7; - if (rm >= 0xc0 ) {GetEArw;val=*earw;} - else {GetEAa;val=LoadMw(eaa);} - switch (which) { - case 0x02: /* MOV SS,Ew */ - CPU_Cycles++; //Always do another instruction - case 0x00: /* MOV ES,Ew */ - case 0x03: /* MOV DS,Ew */ - case 0x05: /* MOV GS,Ew */ - case 0x04: /* MOV FS,Ew */ - if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION(); - break; - default: - goto illegal_opcode; - } - break; - } - CASE_W(0x8f) /* POP Ew */ - { - Bit16u val=Pop_16(); - GetRM; - if (rm >= 0xc0 ) {GetEArw;*earw=val;} - else {GetEAa;SaveMw(eaa,val);} - break; - } - CASE_B(0x90) /* NOP */ - break; - CASE_W(0x91) /* XCHG CX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_cx;reg_cx=temp; } - break; - CASE_W(0x92) /* XCHG DX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_dx;reg_dx=temp; } - break; - CASE_W(0x93) /* XCHG BX,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_bx;reg_bx=temp; } - break; - CASE_W(0x94) /* XCHG SP,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_sp;reg_sp=temp; } - break; - CASE_W(0x95) /* XCHG BP,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_bp;reg_bp=temp; } - break; - CASE_W(0x96) /* XCHG SI,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_si;reg_si=temp; } - break; - CASE_W(0x97) /* XCHG DI,AX */ - { Bit16u temp=reg_ax;reg_ax=reg_di;reg_di=temp; } - break; - CASE_W(0x98) /* CBW */ - reg_ax=(Bit8s)reg_al;break; - CASE_W(0x99) /* CWD */ - if (reg_ax & 0x8000) reg_dx=0xffff;else reg_dx=0; - break; - CASE_W(0x9a) /* CALL Ap */ - { - FillFlags(); - Bit16u newip=Fetchw();Bit16u newcs=Fetchw(); - CPU_CALL(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_B(0x9b) /* WAIT */ - break; /* No waiting here */ - CASE_W(0x9c) /* PUSHF */ - if (CPU_PUSHF(false)) RUNEXCEPTION(); - break; - CASE_W(0x9d) /* POPF */ - if (CPU_POPF(false)) RUNEXCEPTION(); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - goto decode_end; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - CASE_B(0x9e) /* SAHF */ - SETFLAGSb(reg_ah); - break; - CASE_B(0x9f) /* LAHF */ - FillFlags(); - reg_ah=reg_flags&0xff; - break; - CASE_B(0xa0) /* MOV AL,Ob */ - { - GetEADirect; - reg_al=LoadMb(eaa); - } - break; - CASE_W(0xa1) /* MOV AX,Ow */ - { - GetEADirect; - reg_ax=LoadMw(eaa); - } - break; - CASE_B(0xa2) /* MOV Ob,AL */ - { - GetEADirect; - SaveMb(eaa,reg_al); - } - break; - CASE_W(0xa3) /* MOV Ow,AX */ - { - GetEADirect; - SaveMw(eaa,reg_ax); - } - break; - CASE_B(0xa4) /* MOVSB */ - DoString(R_MOVSB);break; - CASE_W(0xa5) /* MOVSW */ - DoString(R_MOVSW);break; - CASE_B(0xa6) /* CMPSB */ - DoString(R_CMPSB);break; - CASE_W(0xa7) /* CMPSW */ - DoString(R_CMPSW);break; - CASE_B(0xa8) /* TEST AL,Ib */ - ALIb(TESTB);break; - CASE_W(0xa9) /* TEST AX,Iw */ - AXIw(TESTW);break; - CASE_B(0xaa) /* STOSB */ - DoString(R_STOSB);break; - CASE_W(0xab) /* STOSW */ - DoString(R_STOSW);break; - CASE_B(0xac) /* LODSB */ - DoString(R_LODSB);break; - CASE_W(0xad) /* LODSW */ - DoString(R_LODSW);break; - CASE_B(0xae) /* SCASB */ - DoString(R_SCASB);break; - CASE_W(0xaf) /* SCASW */ - DoString(R_SCASW);break; - CASE_B(0xb0) /* MOV AL,Ib */ - reg_al=Fetchb();break; - CASE_B(0xb1) /* MOV CL,Ib */ - reg_cl=Fetchb();break; - CASE_B(0xb2) /* MOV DL,Ib */ - reg_dl=Fetchb();break; - CASE_B(0xb3) /* MOV BL,Ib */ - reg_bl=Fetchb();break; - CASE_B(0xb4) /* MOV AH,Ib */ - reg_ah=Fetchb();break; - CASE_B(0xb5) /* MOV CH,Ib */ - reg_ch=Fetchb();break; - CASE_B(0xb6) /* MOV DH,Ib */ - reg_dh=Fetchb();break; - CASE_B(0xb7) /* MOV BH,Ib */ - reg_bh=Fetchb();break; - CASE_W(0xb8) /* MOV AX,Iw */ - reg_ax=Fetchw();break; - CASE_W(0xb9) /* MOV CX,Iw */ - reg_cx=Fetchw();break; - CASE_W(0xba) /* MOV DX,Iw */ - reg_dx=Fetchw();break; - CASE_W(0xbb) /* MOV BX,Iw */ - reg_bx=Fetchw();break; - CASE_W(0xbc) /* MOV SP,Iw */ - reg_sp=Fetchw();break; - CASE_W(0xbd) /* MOV BP.Iw */ - reg_bp=Fetchw();break; - CASE_W(0xbe) /* MOV SI,Iw */ - reg_si=Fetchw();break; - CASE_W(0xbf) /* MOV DI,Iw */ - reg_di=Fetchw();break; - CASE_B(0xc0) /* GRP2 Eb,Ib */ - GRP2B(Fetchb());break; - CASE_W(0xc1) /* GRP2 Ew,Ib */ - GRP2W(Fetchb());break; - CASE_W(0xc2) /* RETN Iw */ - reg_eip=Pop_16(); - reg_esp+=Fetchw(); - continue; - CASE_W(0xc3) /* RETN */ - reg_eip=Pop_16(); - continue; - CASE_W(0xc4) /* LES */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_W(0xc5) /* LDS */ - { - GetRMrw; - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION(); - *rmrw=LoadMw(eaa); - break; - } - CASE_B(0xc6) /* MOV Eb,Ib */ - { - GetRM; - if (rm >= 0xc0) {GetEArb;*earb=Fetchb();} - else {GetEAa;SaveMb(eaa,Fetchb());} - break; - } - CASE_W(0xc7) /* MOV EW,Iw */ - { - GetRM; - if (rm >= 0xc0) {GetEArw;*earw=Fetchw();} - else {GetEAa;SaveMw(eaa,Fetchw());} - break; - } - CASE_W(0xc8) /* ENTER Iw,Ib */ - { - Bitu bytes=Fetchw(); - Bitu level=Fetchb(); - CPU_ENTER(false,bytes,level); - } - break; - CASE_W(0xc9) /* LEAVE */ - reg_esp&=cpu.stack.notmask; - reg_esp|=(reg_ebp&cpu.stack.mask); - reg_bp=Pop_16(); - break; - CASE_W(0xca) /* RETF Iw */ - { - Bitu words=Fetchw(); - FillFlags(); - CPU_RET(false,words,GETIP); - continue; - } - CASE_W(0xcb) /* RETF */ - FillFlags(); - CPU_RET(false,0,GETIP); - continue; - CASE_B(0xcc) /* INT3 */ -#if C_DEBUG - FillFlags(); - if (DEBUG_Breakpoint()) - return debugCallback; -#endif - CPU_SW_Interrupt_NoIOPLCheck(3,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - CASE_B(0xcd) /* INT Ib */ - { - Bit8u num=Fetchb(); -#if C_DEBUG - FillFlags(); - if (DEBUG_IntBreakpoint(num)) { - return debugCallback; - } -#endif - CPU_SW_Interrupt(num,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - } - CASE_B(0xce) /* INTO */ - if (get_OF()) { - CPU_SW_Interrupt(4,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - } - break; - CASE_W(0xcf) /* IRET */ - { - CPU_IRET(false,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE; -#endif - continue; - } - CASE_B(0xd0) /* GRP2 Eb,1 */ - GRP2B(1);break; - CASE_W(0xd1) /* GRP2 Ew,1 */ - GRP2W(1);break; - CASE_B(0xd2) /* GRP2 Eb,CL */ - GRP2B(reg_cl);break; - CASE_W(0xd3) /* GRP2 Ew,CL */ - GRP2W(reg_cl);break; - CASE_B(0xd4) /* AAM Ib */ - AAM(Fetchb());break; - CASE_B(0xd5) /* AAD Ib */ - AAD(Fetchb());break; - CASE_B(0xd6) /* SALC */ - reg_al = get_CF() ? 0xFF : 0; - break; - CASE_B(0xd7) /* XLAT */ - if (TEST_PREFIX_ADDR) { - reg_al=LoadMb(BaseDS+(Bit32u)(reg_ebx+reg_al)); - } else { - reg_al=LoadMb(BaseDS+(Bit16u)(reg_bx+reg_al)); - } - break; -#ifdef CPU_FPU - CASE_B(0xd8) /* FPU ESC 0 */ - FPU_ESC(0);break; - CASE_B(0xd9) /* FPU ESC 1 */ - FPU_ESC(1);break; - CASE_B(0xda) /* FPU ESC 2 */ - FPU_ESC(2);break; - CASE_B(0xdb) /* FPU ESC 3 */ - FPU_ESC(3);break; - CASE_B(0xdc) /* FPU ESC 4 */ - FPU_ESC(4);break; - CASE_B(0xdd) /* FPU ESC 5 */ - FPU_ESC(5);break; - CASE_B(0xde) /* FPU ESC 6 */ - FPU_ESC(6);break; - CASE_B(0xdf) /* FPU ESC 7 */ - FPU_ESC(7);break; -#else - CASE_B(0xd8) /* FPU ESC 0 */ - CASE_B(0xd9) /* FPU ESC 1 */ - CASE_B(0xda) /* FPU ESC 2 */ - CASE_B(0xdb) /* FPU ESC 3 */ - CASE_B(0xdc) /* FPU ESC 4 */ - CASE_B(0xdd) /* FPU ESC 5 */ - CASE_B(0xde) /* FPU ESC 6 */ - CASE_B(0xdf) /* FPU ESC 7 */ - { - LOG(LOG_CPU,LOG_NORMAL)("FPU used"); - Bit8u rm=Fetchb(); - if (rm<0xc0) GetEAa; - } - break; -#endif - CASE_W(0xe0) /* LOOPNZ */ - if (TEST_PREFIX_ADDR) { - JumpCond16_b(--reg_ecx && !get_ZF()); - } else { - JumpCond16_b(--reg_cx && !get_ZF()); - } - break; - CASE_W(0xe1) /* LOOPZ */ - if (TEST_PREFIX_ADDR) { - JumpCond16_b(--reg_ecx && get_ZF()); - } else { - JumpCond16_b(--reg_cx && get_ZF()); - } - break; - CASE_W(0xe2) /* LOOP */ - if (TEST_PREFIX_ADDR) { - JumpCond16_b(--reg_ecx); - } else { - JumpCond16_b(--reg_cx); - } - break; - CASE_W(0xe3) /* JCXZ */ - JumpCond16_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR])); - break; - CASE_B(0xe4) /* IN AL,Ib */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); - reg_al=IO_ReadB(port); - break; - } - CASE_W(0xe5) /* IN AX,Ib */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); - reg_ax=IO_ReadW(port); - break; - } - CASE_B(0xe6) /* OUT Ib,AL */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,1)) RUNEXCEPTION(); - IO_WriteB(port,reg_al); - break; - } - CASE_W(0xe7) /* OUT Ib,AX */ - { - Bitu port=Fetchb(); - if (CPU_IO_Exception(port,2)) RUNEXCEPTION(); - IO_WriteW(port,reg_ax); - break; - } - CASE_W(0xe8) /* CALL Jw */ - { - Bit16u addip=Fetchws(); - SAVEIP; - Push_16(reg_eip); - reg_eip=(Bit16u)(reg_eip+addip); - continue; - } - CASE_W(0xe9) /* JMP Jw */ - { - Bit16u addip=Fetchws(); - SAVEIP; - reg_eip=(Bit16u)(reg_eip+addip); - continue; - } - CASE_W(0xea) /* JMP Ap */ - { - Bit16u newip=Fetchw(); - Bit16u newcs=Fetchw(); - FillFlags(); - CPU_JMP(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - CASE_W(0xeb) /* JMP Jb */ - { - Bit16s addip=Fetchbs(); - SAVEIP; - reg_eip=(Bit16u)(reg_eip+addip); - continue; - } - CASE_B(0xec) /* IN AL,DX */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - reg_al=IO_ReadB(reg_dx); - break; - CASE_W(0xed) /* IN AX,DX */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - reg_ax=IO_ReadW(reg_dx); - break; - CASE_B(0xee) /* OUT DX,AL */ - if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION(); - IO_WriteB(reg_dx,reg_al); - break; - CASE_W(0xef) /* OUT DX,AX */ - if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION(); - IO_WriteW(reg_dx,reg_ax); - break; - CASE_B(0xf0) /* LOCK */ - LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK"); /* FIXME: see case D_LOCK in core_full/load.h */ - break; - CASE_B(0xf1) /* ICEBP */ - CPU_SW_Interrupt_NoIOPLCheck(1,GETIP); -#if CPU_TRAP_CHECK - cpu.trap_skip=true; -#endif - continue; - CASE_B(0xf2) /* REPNZ */ - DO_PREFIX_REP(false); - break; - CASE_B(0xf3) /* REPZ */ - DO_PREFIX_REP(true); - break; - CASE_B(0xf4) /* HLT */ - if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); - FillFlags(); - CPU_HLT(GETIP); - return CBRET_NONE; //Needs to return for hlt cpu core - CASE_B(0xf5) /* CMC */ - FillFlags(); - SETFLAGBIT(CF,!(reg_flags & FLAG_CF)); - break; - CASE_B(0xf6) /* GRP3 Eb(,Ib) */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* TEST Eb,Ib */ - case 0x01: /* TEST Eb,Ib Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArb;TESTB(*earb,Fetchb(),LoadRb,0)} - else {GetEAa;TESTB(eaa,Fetchb(),LoadMb,0);} - break; - } - case 0x02: /* NOT Eb */ - { - if (rm >= 0xc0 ) {GetEArb;*earb=~*earb;} - else {GetEAa;SaveMb(eaa,~LoadMb(eaa));} - break; - } - case 0x03: /* NEG Eb */ - { - lflags.type=t_NEGb; - if (rm >= 0xc0 ) { - GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b; - *earb=lf_resb; - } else { - GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b; - SaveMb(eaa,lf_resb); - } - break; - } - case 0x04: /* MUL AL,Eb */ - RMEb(MULB); - break; - case 0x05: /* IMUL AL,Eb */ - RMEb(IMULB); - break; - case 0x06: /* DIV Eb */ - RMEb(DIVB); - break; - case 0x07: /* IDIV Eb */ - RMEb(IDIVB); - break; - } - break; - } - CASE_W(0xf7) /* GRP3 Ew(,Iw) */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* TEST Ew,Iw */ - case 0x01: /* TEST Ew,Iw Undocumented*/ - { - if (rm >= 0xc0 ) {GetEArw;TESTW(*earw,Fetchw(),LoadRw,SaveRw);} - else {GetEAa;TESTW(eaa,Fetchw(),LoadMw,SaveMw);} - break; - } - case 0x02: /* NOT Ew */ - { - if (rm >= 0xc0 ) {GetEArw;*earw=~*earw;} - else {GetEAa;SaveMw(eaa,~LoadMw(eaa));} - break; - } - case 0x03: /* NEG Ew */ - { - lflags.type=t_NEGw; - if (rm >= 0xc0 ) { - GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w; - *earw=lf_resw; - } else { - GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w; - SaveMw(eaa,lf_resw); - } - break; - } - case 0x04: /* MUL AX,Ew */ - RMEw(MULW); - break; - case 0x05: /* IMUL AX,Ew */ - RMEw(IMULW) - break; - case 0x06: /* DIV Ew */ - RMEw(DIVW) - break; - case 0x07: /* IDIV Ew */ - RMEw(IDIVW) - break; - } - break; - } - CASE_B(0xf8) /* CLC */ - FillFlags(); - SETFLAGBIT(CF,false); - break; - CASE_B(0xf9) /* STC */ - FillFlags(); - SETFLAGBIT(CF,true); - break; - CASE_B(0xfa) /* CLI */ - if (CPU_CLI()) RUNEXCEPTION(); - break; - CASE_B(0xfb) /* STI */ - if (CPU_STI()) RUNEXCEPTION(); -#if CPU_PIC_CHECK - if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end; -#endif - break; - CASE_B(0xfc) /* CLD */ - SETFLAGBIT(DF,false); - cpu.direction=1; - break; - CASE_B(0xfd) /* STD */ - SETFLAGBIT(DF,true); - cpu.direction=-1; - break; - CASE_B(0xfe) /* GRP4 Eb */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* INC Eb */ - RMEb(INCB); - break; - case 0x01: /* DEC Eb */ - RMEb(DECB); - break; - case 0x07: /* CallBack */ - { - Bitu cb=Fetchw(); - FillFlags();SAVEIP; - return cb; - } - default: - E_Exit("Illegal GRP4 Call %d",(rm>>3) & 7); - break; - } - break; - } - CASE_W(0xff) /* GRP5 Ew */ - { - GetRM;Bitu which=(rm>>3)&7; - switch (which) { - case 0x00: /* INC Ew */ - RMEw(INCW); - break; - case 0x01: /* DEC Ew */ - RMEw(DECW); - break; - case 0x02: /* CALL Ev */ - if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} - else {GetEAa;reg_eip=LoadMw(eaa);} - Push_16(GETIP); - continue; - case 0x03: /* CALL Ep */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit16u newip=LoadMw(eaa); - Bit16u newcs=LoadMw(eaa+2); - FillFlags(); - CPU_CALL(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - break; - case 0x04: /* JMP Ev */ - if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;} - else {GetEAa;reg_eip=LoadMw(eaa);} - continue; - case 0x05: /* JMP Ep */ - { - if (rm >= 0xc0) goto illegal_opcode; - GetEAa; - Bit16u newip=LoadMw(eaa); - Bit16u newcs=LoadMw(eaa+2); - FillFlags(); - CPU_JMP(false,newcs,newip,GETIP); -#if CPU_TRAP_CHECK - if (GETFLAG(TF)) { - cpudecoder=CPU_Core_Normal_Trap_Run; - return CBRET_NONE; - } -#endif - continue; - } - break; - case 0x06: /* PUSH Ev */ - if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);} - else {GetEAa;Push_16(LoadMw(eaa));} - break; - default: - LOG(LOG_CPU,LOG_ERROR)("CPU:GRP5:Illegal Call %2X",which); - goto illegal_opcode; - } - break; - } - - - - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/string.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/string.h deleted file mode 100644 index 2370264fe..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/string.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -namespace I386_DOSBOX { -enum STRING_OP { - R_OUTSB,R_OUTSW,R_OUTSD, - R_INSB,R_INSW,R_INSD, - R_MOVSB,R_MOVSW,R_MOVSD, - R_LODSB,R_LODSW,R_LODSD, - R_STOSB,R_STOSW,R_STOSD, - R_SCASB,R_SCASW,R_SCASD, - R_CMPSB,R_CMPSW,R_CMPSD -}; - -#define LoadD(_BLAH) _BLAH - -static void DoString(STRING_OP type) { - PhysPt si_base,di_base; - Bitu si_index,di_index; - Bitu add_mask; - Bitu count,count_left; - Bits add_index; - - si_base=BaseDS; - di_base=SegBase(es); - add_mask=AddrMaskTable[core.prefixes & PREFIX_ADDR]; - si_index=reg_esi & add_mask; - di_index=reg_edi & add_mask; - count=reg_ecx & add_mask; - if (!TEST_PREFIX_REP) { - count=1; - } else { - CPU_Cycles++; - /* Calculate amount of ops to do before cycles run out */ - if ((count>(Bitu)CPU_Cycles) && (type0;count--) { - IO_WriteB(reg_dx,LoadMb(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSW: - add_index<<=1; - for (;count>0;count--) { - IO_WriteW(reg_dx,LoadMw(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_OUTSD: - add_index<<=2; - for (;count>0;count--) { - IO_WriteD(reg_dx,LoadMd(si_base+si_index)); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_INSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,IO_ReadB(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_INSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,IO_ReadW(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_INSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,IO_ReadD(reg_dx)); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,reg_al); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,reg_ax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_STOSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,reg_eax); - di_index=(di_index+add_index) & add_mask; - } - break; - case R_MOVSB: - for (;count>0;count--) { - SaveMb(di_base+di_index,LoadMb(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSW: - add_index<<=1; - for (;count>0;count--) { - SaveMw(di_base+di_index,LoadMw(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_MOVSD: - add_index<<=2; - for (;count>0;count--) { - SaveMd(di_base+di_index,LoadMd(si_base+si_index)); - di_index=(di_index+add_index) & add_mask; - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSB: - for (;count>0;count--) { - reg_al=LoadMb(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSW: - add_index<<=1; - for (;count>0;count--) { - reg_ax=LoadMw(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_LODSD: - add_index<<=2; - for (;count>0;count--) { - reg_eax=LoadMd(si_base+si_index); - si_index=(si_index+add_index) & add_mask; - } - break; - case R_SCASB: - { - Bit8u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMb(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_al==val2)!=core.rep_zero) break; - } - CMPB(reg_al,val2,LoadD,0); - } - break; - case R_SCASW: - { - add_index<<=1;Bit16u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMw(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_ax==val2)!=core.rep_zero) break; - } - CMPW(reg_ax,val2,LoadD,0); - } - break; - case R_SCASD: - { - add_index<<=2;Bit32u val2; - for (;count>0;) { - count--;CPU_Cycles--; - val2=LoadMd(di_base+di_index); - di_index=(di_index+add_index) & add_mask; - if ((reg_eax==val2)!=core.rep_zero) break; - } - CMPD(reg_eax,val2,LoadD,0); - } - break; - case R_CMPSB: - { - Bit8u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMb(si_base+si_index); - val2=LoadMb(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=core.rep_zero) break; - } - CMPB(val1,val2,LoadD,0); - } - break; - case R_CMPSW: - { - add_index<<=1;Bit16u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMw(si_base+si_index); - val2=LoadMw(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=core.rep_zero) break; - } - CMPW(val1,val2,LoadD,0); - } - break; - case R_CMPSD: - { - add_index<<=2;Bit32u val1,val2; - for (;count>0;) { - count--;CPU_Cycles--; - val1=LoadMd(si_base+si_index); - val2=LoadMd(di_base+di_index); - si_index=(si_index+add_index) & add_mask; - di_index=(di_index+add_index) & add_mask; - if ((val1==val2)!=core.rep_zero) break; - } - CMPD(val1,val2,LoadD,0); - } - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled string op %d",type); - } - /* Clean up after certain amount of instructions */ - reg_esi&=(~add_mask); - reg_esi|=(si_index & add_mask); - reg_edi&=(~add_mask); - reg_edi|=(di_index & add_mask); - if (TEST_PREFIX_REP) { - count+=count_left; - reg_ecx&=(~add_mask); - reg_ecx|=(count & add_mask); - } -} - -}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/support.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/support.h deleted file mode 100644 index f52a3d6a4..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/support.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#pragma once -namespace I386_DOSBOX { - -#define LoadMbs(off) (Bit8s)(LoadMb(off)) -#define LoadMws(off) (Bit16s)(LoadMw(off)) -#define LoadMds(off) (Bit32s)(LoadMd(off)) - -#define LoadRb(reg) reg -#define LoadRw(reg) reg -#define LoadRd(reg) reg - -#define SaveRb(reg,val) reg=val -#define SaveRw(reg,val) reg=val -#define SaveRd(reg,val) reg=val - -static INLINE Bit8s Fetchbs() { - return Fetchb(); -} -static INLINE Bit16s Fetchws() { - return Fetchw(); -} - -static INLINE Bit32s Fetchds() { - return Fetchd(); -} - - -#define RUNEXCEPTION() { \ - CPU_Exception(cpu.exception.which,cpu.exception.error); \ - continue; \ -} - -#define EXCEPTION(blah) \ - { \ - CPU_Exception(blah); \ - continue; \ - } - -//TODO Could probably make all byte operands fast? -#define JumpCond16_b(COND) { \ - SAVEIP; \ - if (COND) reg_ip+=Fetchbs(); \ - reg_ip+=1; \ - continue; \ -} - -#define JumpCond16_w(COND) { \ - SAVEIP; \ - if (COND) reg_ip+=Fetchws(); \ - reg_ip+=2; \ - continue; \ -} - -#define JumpCond32_b(COND) { \ - SAVEIP; \ - if (COND) reg_eip+=Fetchbs(); \ - reg_eip+=1; \ - continue; \ -} - -#define JumpCond32_d(COND) { \ - SAVEIP; \ - if (COND) reg_eip+=Fetchds(); \ - reg_eip+=4; \ - continue; \ -} - - -#define SETcc(cc) \ - { \ - GetRM; \ - if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \ - else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \ - } -}; - -#include "helpers.h" -#include "table_ea.h" -#include "../modrm.h" - - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/table_ea.h b/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/table_ea.h deleted file mode 100644 index df641b780..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_normal/table_ea.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#pragma once -namespace I386_DOSBOX { - -typedef PhysPt (*EA_LookupHandler)(void); - -/* The MOD/RM Decoder for EA for this decoder's addressing modes */ -__OPCALL PhysPt EA_16_00_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si); } -__OPCALL PhysPt EA_16_01_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di); } -__OPCALL PhysPt EA_16_02_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si); } -__OPCALL PhysPt EA_16_03_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di); } -__OPCALL PhysPt EA_16_04_n(void) { return BaseDS+(Bit16u)(reg_si); } -__OPCALL PhysPt EA_16_05_n(void) { return BaseDS+(Bit16u)(reg_di); } -__OPCALL PhysPt EA_16_06_n(void) { return BaseDS+(Bit16u)(Fetchw());} -__OPCALL PhysPt EA_16_07_n(void) { return BaseDS+(Bit16u)(reg_bx); } - -__OPCALL PhysPt EA_16_40_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); } -__OPCALL PhysPt EA_16_41_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); } -__OPCALL PhysPt EA_16_42_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); } -__OPCALL PhysPt EA_16_43_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); } -__OPCALL PhysPt EA_16_44_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchbs()); } -__OPCALL PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchbs()); } -__OPCALL PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchbs()); } -__OPCALL PhysPt EA_16_47_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchbs()); } - -__OPCALL PhysPt EA_16_80_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); } -__OPCALL PhysPt EA_16_81_n(void) { return BaseDS+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); } -__OPCALL PhysPt EA_16_82_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); } -__OPCALL PhysPt EA_16_83_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); } -__OPCALL PhysPt EA_16_84_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchws()); } -__OPCALL PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchws()); } -__OPCALL PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchws()); } -__OPCALL PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); } - -__OPCALL Bit32u SIBZero=0; -__OPCALL Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi }; - -__OPCALL_INLINE PhysPt Sib(Bitu mode) { - Bit8u sib=Fetchb(); - PhysPt base; - switch (sib&7) { - case 0: /* EAX Base */ - base=BaseDS+reg_eax;break; - case 1: /* ECX Base */ - base=BaseDS+reg_ecx;break; - case 2: /* EDX Base */ - base=BaseDS+reg_edx;break; - case 3: /* EBX Base */ - base=BaseDS+reg_ebx;break; - case 4: /* ESP Base */ - base=BaseSS+reg_esp;break; - case 5: /* #1 Base */ - if (!mode) { - base=BaseDS+Fetchd();break; - } else { - base=BaseSS+reg_ebp;break; - } - case 6: /* ESI Base */ - base=BaseDS+reg_esi;break; - case 7: /* EDI Base */ - base=BaseDS+reg_edi;break; - } - base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); - return base; -} - -__OPCALL PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; } -__OPCALL PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; } -__OPCALL PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; } -__OPCALL PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; } -__OPCALL PhysPt EA_32_04_n(void) { return Sib(0);} -__OPCALL PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); } -__OPCALL PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; } -__OPCALL PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; } - -__OPCALL PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+Fetchbs(); } -__OPCALL PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+Fetchbs(); } -__OPCALL PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+Fetchbs(); } -__OPCALL PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+Fetchbs(); } -__OPCALL PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();} -//__OPCALL PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();} -__OPCALL PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+Fetchbs(); } -__OPCALL PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+Fetchbs(); } -__OPCALL PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+Fetchbs(); } - -__OPCALL PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+Fetchds(); } -__OPCALL PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+Fetchds(); } -__OPCALL PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+Fetchds(); } -__OPCALL PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+Fetchds(); } -__OPCALL PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();} -//__OPCALL PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();} -__OPCALL PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+Fetchds(); } -__OPCALL PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+Fetchds(); } -__OPCALL PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+Fetchds(); } - -__OPCALL GetEAHandler EATable[512]={ -/* 00 */ - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, - EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n, -/* 01 */ - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, - EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n, -/* 10 */ - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, - EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/* 00 */ - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, - EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n, -/* 01 */ - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, - EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n, -/* 10 */ - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, - EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n, -/* 11 These are illegal so make em 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -#define GetEADirect \ - PhysPt eaa; \ - if (TEST_PREFIX_ADDR) { \ - eaa=BaseDS+Fetchd(); \ - } else { \ - eaa=BaseDS+Fetchw(); \ - } \ - -}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_prefetch.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/core_prefetch.cpp deleted file mode 100644 index 47db2c11b..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_prefetch.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include - -#include "dosbox.h" -#include "mem.h" -#include "cpu.h" -#include "lazyflags.h" -#include "inout.h" -#include "callback.h" -#include "pic.h" -#include "fpu.h" -#include "paging.h" - -#if C_DEBUG -#include "debug.h" -#endif - -#if (!C_CORE_INLINE) -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) -#else -#include "paging.h" -#define LoadMb(off) mem_readb_inline(off) -#define LoadMw(off) mem_readw_inline(off) -#define LoadMd(off) mem_readd_inline(off) -#define SaveMb(off,val) mem_writeb_inline(off,val) -#define SaveMw(off,val) mem_writew_inline(off,val) -#define SaveMd(off,val) mem_writed_inline(off,val) -#endif - -extern Bitu cycle_count; - -#if C_FPU -#define CPU_FPU 1 //Enable FPU escape instructions -#endif - -#define CPU_PIC_CHECK 1 -#define CPU_TRAP_CHECK 1 - -#define OPCODE_NONE 0x000 -#define OPCODE_0F 0x100 -#define OPCODE_SIZE 0x200 - -#define PREFIX_ADDR 0x1 -#define PREFIX_REP 0x2 - -#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) -#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) - -#define DO_PREFIX_SEG(_SEG) \ - BaseDS=SegBase(_SEG); \ - BaseSS=SegBase(_SEG); \ - core.base_val_ds=_SEG; \ - goto restart_opcode; - -#define DO_PREFIX_ADDR() \ - core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ - (cpu.code.big ^ PREFIX_ADDR); \ - core.ea_table=&EATable[(core.prefixes&1) * 256]; \ - goto restart_opcode; - -#define DO_PREFIX_REP(_ZERO) \ - core.prefixes|=PREFIX_REP; \ - core.rep_zero=_ZERO; \ - goto restart_opcode; - -typedef PhysPt (*GetEAHandler)(void); - -static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; - -static struct { - Bitu opcode_index; - PhysPt cseip; - PhysPt base_ds,base_ss; - SegNames base_val_ds; - bool rep_zero; - Bitu prefixes; - GetEAHandler * ea_table; -} core; - -#define GETIP (core.cseip-SegBase(cs)) -#define SAVEIP reg_eip=GETIP; -#define LOADIP core.cseip=(SegBase(cs)+reg_eip); - -#define SegBase(c) SegPhys(c) -#define BaseDS core.base_ds -#define BaseSS core.base_ss - - -#define MAX_PQ_SIZE 32 -static Bit8u prefetch_buffer[MAX_PQ_SIZE]; -static bool pq_valid=false; -static Bitu pq_start; - -static Bit8u Fetchb() { - Bit8u temp; - if (pq_valid && (core.cseip>=pq_start) && (core.cseip=pq_start+CPU_PrefetchQueueSize-4) && - (core.cseip+1=pq_start) && (core.cseip+2=pq_start+CPU_PrefetchQueueSize-4) && - (core.cseip+2=pq_start) && (core.cseip+4=pq_start+CPU_PrefetchQueueSize-4) && - (core.cseip+40) { - if (invalidate_pq) { - pq_valid=false; - invalidate_pq=false; - } - LOADIP; - core.opcode_index=cpu.code.big*0x200; - core.prefixes=cpu.code.big; - core.ea_table=&EATable[cpu.code.big*256]; - BaseDS=SegBase(ds); - BaseSS=SegBase(ss); - core.base_val_ds=ds; -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - FillFlags(); - return debugCallback; - }; -#endif - cycle_count++; -#endif -restart_opcode: - Bit8u next_opcode=Fetchb(); - invalidate_pq=false; - if (core.opcode_index&OPCODE_0F) invalidate_pq=true; - else switch (next_opcode) { - case 0x70: case 0x71: case 0x72: case 0x73: - case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: - case 0x7c: case 0x7d: case 0x7e: case 0x7f: // jcc - case 0x9a: // call - case 0xc2: case 0xc3: // retn - case 0xc8: // enter - case 0xc9: // leave - case 0xca: case 0xcb: // retf - case 0xcc: // int3 - case 0xcd: // int - case 0xce: // into - case 0xcf: // iret - case 0xe0: // loopnz - case 0xe1: // loopz - case 0xe2: // loop - case 0xe3: // jcxz - case 0xe8: // call - case 0xe9: case 0xea: case 0xeb: // jmp - case 0xff: - invalidate_pq=true; - break; - default: - break; - } - switch (core.opcode_index+next_opcode) { - #include "core_normal/prefix_none.h" - #include "core_normal/prefix_0f.h" - #include "core_normal/prefix_66.h" - #include "core_normal/prefix_66_0f.h" - default: - illegal_opcode: -#if C_DEBUG - { - Bitu len=(GETIP-reg_eip); - LOADIP; - if (len>16) len=16; - char tempcode[16*2+1];char * writecode=tempcode; - for (;len>0;len--) { - sprintf(writecode,"%02X",mem_readb(core.cseip++)); - writecode+=2; - } - LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); - } -#endif - CPU_Exception(6,0); - invalidate_pq=true; - continue; - } - SAVEIP; - } - FillFlags(); - return CBRET_NONE; -decode_end: - SAVEIP; - FillFlags(); - return CBRET_NONE; -} - -Bits CPU_Core_Prefetch_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - cpu.trap_skip = false; - - Bits ret=CPU_Core_Prefetch_Run(); - if (!cpu.trap_skip) CPU_HW_Interrupt(1); - CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Prefetch_Run; - - return ret; -} - - - -void CPU_Core_Prefetch_Init(void) { - -} - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/core_simple.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/core_simple.cpp deleted file mode 100644 index d8fdb9eab..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/core_simple.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include - -#include "dosbox.h" -#include "mem.h" -#include "cpu.h" -#include "lazyflags.h" -#include "inout.h" -#include "callback.h" -#include "pic.h" -#include "fpu.h" - -#if C_DEBUG -#include "debug.h" -#endif - -#include "paging.h" -#define SegBase(c) SegPhys(c) -#define LoadMb(off) mem_readb(off) -#define LoadMw(off) mem_readw(off) -#define LoadMd(off) mem_readd(off) - -#define SaveMb(off,val) mem_writeb(off,val) -#define SaveMw(off,val) mem_writew(off,val) -#define SaveMd(off,val) mem_writed(off,val) - -extern Bitu cycle_count; - -#if C_FPU -#define CPU_FPU 1 //Enable FPU escape instructions -#endif - -#define CPU_PIC_CHECK 1 -#define CPU_TRAP_CHECK 1 - -#define OPCODE_NONE 0x000 -#define OPCODE_0F 0x100 -#define OPCODE_SIZE 0x200 - -#define PREFIX_ADDR 0x1 -#define PREFIX_REP 0x2 - -#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR) -#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP) - -#define DO_PREFIX_SEG(_SEG) \ - BaseDS=SegBase(_SEG); \ - BaseSS=SegBase(_SEG); \ - core.base_val_ds=_SEG; \ - goto restart_opcode; - -#define DO_PREFIX_ADDR() \ - core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \ - (cpu.code.big ^ PREFIX_ADDR); \ - core.ea_table=&EATable[(core.prefixes&1) * 256]; \ - goto restart_opcode; - -#define DO_PREFIX_REP(_ZERO) \ - core.prefixes|=PREFIX_REP; \ - core.rep_zero=_ZERO; \ - goto restart_opcode; - -typedef PhysPt (*GetEAHandler)(void); - -static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff}; - -static struct { - Bitu opcode_index; -#if defined (_MSC_VER) - volatile HostPt cseip; -#else - HostPt cseip; -#endif - PhysPt base_ds,base_ss; - SegNames base_val_ds; - bool rep_zero; - Bitu prefixes; - GetEAHandler * ea_table; -} core; - -#define GETIP (core.cseip-SegBase(cs)-MemBase) -#define SAVEIP reg_eip=GETIP; -#define LOADIP core.cseip=(MemBase+SegBase(cs)+reg_eip); - -#define SegBase(c) SegPhys(c) -#define BaseDS core.base_ds -#define BaseSS core.base_ss - -static INLINE Bit8u Fetchb() { - Bit8u temp=host_readb(core.cseip); - core.cseip+=1; - return temp; -} - -static INLINE Bit16u Fetchw() { - Bit16u temp=host_readw(core.cseip); - core.cseip+=2; - return temp; -} -static INLINE Bit32u Fetchd() { - Bit32u temp=host_readd(core.cseip); - core.cseip+=4; - return temp; -} - -#define Push_16 CPU_Push16 -#define Push_32 CPU_Push32 -#define Pop_16 CPU_Pop16 -#define Pop_32 CPU_Pop32 - -#include "instructions.h" -#include "core_normal/support.h" -#include "core_normal/string.h" - - -#define EALookupTable (core.ea_table) - -Bits CPU_Core_Simple_Run(void) { - while (CPU_Cycles-->0) { - LOADIP; - core.opcode_index=cpu.code.big*0x200; - core.prefixes=cpu.code.big; - core.ea_table=&EATable[cpu.code.big*256]; - BaseDS=SegBase(ds); - BaseSS=SegBase(ss); - core.base_val_ds=ds; -#if C_DEBUG -#if C_HEAVY_DEBUG - if (DEBUG_HeavyIsBreakpoint()) { - FillFlags(); - return debugCallback; - }; -#endif - cycle_count++; -#endif -restart_opcode: - switch (core.opcode_index+Fetchb()) { - - #include "core_normal/prefix_none.h" - #include "core_normal/prefix_0f.h" - #include "core_normal/prefix_66.h" - #include "core_normal/prefix_66_0f.h" - default: - illegal_opcode: -#if C_DEBUG - { - Bitu len=(GETIP-reg_eip); - LOADIP; - if (len>16) len=16; - char tempcode[16*2+1];char * writecode=tempcode; - for (;len>0;len--) { -// sprintf(writecode,"%X",mem_readb(core.cseip++)); - writecode+=2; - } - LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); - } -#endif - CPU_Exception(6,0); - continue; - } - SAVEIP; - } - FillFlags(); - return CBRET_NONE; -decode_end: - SAVEIP; - FillFlags(); - return CBRET_NONE; -} - -// not really used -Bits CPU_Core_Simple_Trap_Run(void) { - Bits oldCycles = CPU_Cycles; - CPU_Cycles = 1; - cpu.trap_skip = false; - - Bits ret=CPU_Core_Normal_Run(); - if (!cpu.trap_skip) CPU_HW_Interrupt(1); - CPU_Cycles = oldCycles-1; - cpudecoder = &CPU_Core_Simple_Run; - - return ret; -} - - - -void CPU_Core_Simple_Init(void) { - -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp deleted file mode 100644 index 12432b10a..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/cpu.cpp +++ /dev/null @@ -1,2379 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include -#include -#include -#include "dosbox.h" -#include "cpu.h" -#include "memory.h" -#include "debug.h" -#include "mapper.h" -#include "setup.h" -#include "programs.h" -#include "paging.h" -#include "lazyflags.h" -#include "support.h" - - - -Bitu TaskStateSegment::Get_back(void) { - d_cpu->cpu.mpl=0; - Bit16u backlink = d_cpu->mem_readw(base); - d_cpu->cpu.mpl=3; - return backlink; -} -void TaskStateSegment::SaveSelector(void) -{ - d_cpu->gdt.SetDescriptor(selector,desc); -} - -void TaskStateSegment::Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) { - d_cpu->cpu.mpl=0; - if (is386) { - PhysPt where = base+ offsetof(TSS_32,esp0)+level*8; - _esp = d_cpu->mem_readd(where); - _ss = d_cpu->mem_readw(where+4); - } else { - PhysPt where=base+offsetof(TSS_16,sp0)+level*4; - _esp = d_cpu->mem_readw(where); - _ss = d_cpu->mem_readw(where+2); - } - d_cpu->cpu.mpl=3; -} - -bool TaskStateSegment::SetSelector(Bitu new_sel) -{ - valid=false; - if ((new_sel & 0xfffc)==0) { - selector=0; - base=0; - limit=0; - is386=1; - return true; - } - if (new_sel&4) return false; - if (!d_cpu->cpu.gdt.GetDescriptor(new_sel,desc)) return false; - switch (desc.Type()) { - case DESC_286_TSS_A: case DESC_286_TSS_B: - case DESC_386_TSS_A: case DESC_386_TSS_B: - break; - default: - return false; - } - if (!desc.saved.seg.p) return false; - selector = new_sel; - valid=true; - base = desc.GetBase(); - limit = desc.GetLimit(); - is386 = desc.Is386(); - return true; -} - -namespace I386_DOSBOX { -Bitu DEBUG_EnableDebugger(void); -extern void GFX_SetTitle(Bit32s cycles ,Bits frameskip,bool paused); - -#if 1 -#undef LOG -#if defined (_MSC_VER) -#define LOG(X,Y) -#else -#define LOG(X,Y) CPU_LOG -#define CPU_LOG(...) -#endif -#endif - - - -/* In debug mode exceptions are tested and dosbox exits when - * a unhandled exception state is detected. - * USE CHECK_EXCEPT to raise an exception in that case to see if that exception - * solves the problem. - * - * In non-debug mode dosbox doesn't do detection (and hence doesn't crash at - * that point). (game might crash later due to the unhandled exception) */ - -#if C_DEBUG -// #define CPU_CHECK_EXCEPT 1 -// #define CPU_CHECK_IGNORE 1 - /* Use CHECK_EXCEPT when something doesn't work to see if a exception is - * needed that isn't enabled by default.*/ -#else -/* NORMAL NO CHECKING => More Speed */ -#define CPU_CHECK_IGNORE 1 -#endif /* C_DEBUG */ - -#if defined(CPU_CHECK_IGNORE) -#define CPU_CHECK_COND(cond,msg,exc,sel) { \ - if (cond) do {} while (0); \ -} -#elif defined(CPU_CHECK_EXCEPT) -#define CPU_CHECK_COND(cond,msg,exc,sel) { \ - if (cond) { \ - CPU_Exception(exc,sel); \ - return; \ - } \ -} -#else -#define CPU_CHECK_COND(cond,msg,exc,sel) { \ - if (cond) E_Exit(msg); \ -} -#endif - - -void Descriptor::Load(PhysPt address) { - cpu.mpl=0; - Bit32u* data = (Bit32u*)&saved; - *data = mem_readd(address); - *(data+1) = mem_readd(address+4); - cpu.mpl=3; -} -void Descriptor:: Save(PhysPt address) { - cpu.mpl=0; - Bit32u* data = (Bit32u*)&saved; - mem_writed(address,*data); - mem_writed(address+4,*(data+1)); - cpu.mpl=03; -} - - -void CPU_Push16(Bitu value) { - Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); - mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); - reg_esp=new_esp; -} - -void CPU_Push32(Bitu value) { - Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-4)&cpu.stack.mask); - mem_writed(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); - reg_esp=new_esp; -} - -Bitu CPU_Pop16(void) { - Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); - return val; -} - -Bitu CPU_Pop32(void) { - Bitu val=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); - return val; -} - -PhysPt SelBase(Bitu sel) { - if (cpu.cr0 & CR0_PROTECTION) { - Descriptor desc; - cpu.gdt.GetDescriptor(sel,desc); - return desc.GetBase(); - } else { - return sel<<4; - } -} - - -void CPU_SetFlags(Bitu word,Bitu mask) { - mask|=CPU_extflags_toggle; // ID-flag and AC-flag can be toggled on CPUID-supporting CPUs - reg_flags=(reg_flags & ~mask)|(word & mask)|2; - cpu.direction=1-((reg_flags & FLAG_DF) >> 9); -} - -bool CPU_PrepareException(Bitu which,Bitu error) { - cpu.exception.which=which; - cpu.exception.error=error; - return true; -} - -bool CPU_CLI(void) { - if (cpu.pmode && ((!GETFLAG(VM) && (GETFLAG_IOPL0)) mask &= (~FLAG_IOPL); - if (cpu.pmode && !GETFLAG(VM) && (GETFLAG_IOPLdesc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(es,0); - - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(ds),desc)) needs_invalidation=true; - else switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(ds,0); - - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(fs),desc)) needs_invalidation=true; - else switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(fs,0); - - needs_invalidation=false; - if (!cpu.gdt.GetDescriptor(SegValue(gs),desc)) needs_invalidation=true; - else switch (desc.Type()) { - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl>desc.DPL()) needs_invalidation=true; break; - default: break; } - if (needs_invalidation) CPU_SetSegGeneral(gs,0); -} - -enum TSwitchType { - TSwitch_JMP,TSwitch_CALL_INT,TSwitch_IRET -}; - -bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) { - FillFlags(); - TaskStateSegment new_tss; - new_tss.SetCpuDomain(this); - if (!new_tss.SetSelector(new_tss_selector)) - E_Exit("Illegal TSS for switch, selector=%x, switchtype=%x",new_tss_selector,tstype); - if (tstype==TSwitch_IRET) { - if (!new_tss.desc.IsBusy()) - E_Exit("TSS not busy for IRET"); - } else { - if (new_tss.desc.IsBusy()) - E_Exit("TSS busy for JMP/CALL/INT"); - } - Bitu new_cr3=0; - Bitu new_eax,new_ebx,new_ecx,new_edx,new_esp,new_ebp,new_esi,new_edi; - Bitu new_es,new_cs,new_ss,new_ds,new_fs,new_gs; - Bitu new_ldt,new_eip,new_eflags; - /* Read new context from new TSS */ - if (new_tss.is386) { - new_cr3=mem_readd(new_tss.base+offsetof(TSS_32,cr3)); - new_eip=mem_readd(new_tss.base+offsetof(TSS_32,eip)); - new_eflags=mem_readd(new_tss.base+offsetof(TSS_32,eflags)); - new_eax=mem_readd(new_tss.base+offsetof(TSS_32,eax)); - new_ecx=mem_readd(new_tss.base+offsetof(TSS_32,ecx)); - new_edx=mem_readd(new_tss.base+offsetof(TSS_32,edx)); - new_ebx=mem_readd(new_tss.base+offsetof(TSS_32,ebx)); - new_esp=mem_readd(new_tss.base+offsetof(TSS_32,esp)); - new_ebp=mem_readd(new_tss.base+offsetof(TSS_32,ebp)); - new_edi=mem_readd(new_tss.base+offsetof(TSS_32,edi)); - new_esi=mem_readd(new_tss.base+offsetof(TSS_32,esi)); - - new_es=mem_readw(new_tss.base+offsetof(TSS_32,es)); - new_cs=mem_readw(new_tss.base+offsetof(TSS_32,cs)); - new_ss=mem_readw(new_tss.base+offsetof(TSS_32,ss)); - new_ds=mem_readw(new_tss.base+offsetof(TSS_32,ds)); - new_fs=mem_readw(new_tss.base+offsetof(TSS_32,fs)); - new_gs=mem_readw(new_tss.base+offsetof(TSS_32,gs)); - new_ldt=mem_readw(new_tss.base+offsetof(TSS_32,ldt)); - } else { - E_Exit("286 task switch"); - new_cr3=0; - new_eip=0; - new_eflags=0; - new_eax=0; new_ecx=0; new_edx=0; new_ebx=0; - new_esp=0; new_ebp=0; new_edi=0; new_esi=0; - - new_es=0; new_cs=0; new_ss=0; new_ds=0; new_fs=0; new_gs=0; - new_ldt=0; - } - - /* Check if we need to clear busy bit of old TASK */ - if (tstype==TSwitch_JMP || tstype==TSwitch_IRET) { - cpu_tss.desc.SetBusy(false); - cpu_tss.SaveSelector(); - } - Bit32u old_flags = reg_flags; - if (tstype==TSwitch_IRET) old_flags &= (~FLAG_NT); - - /* Save current context in current TSS */ - if (cpu_tss.is386) { - mem_writed(cpu_tss.base+offsetof(TSS_32,eflags),old_flags); - mem_writed(cpu_tss.base+offsetof(TSS_32,eip),old_eip); - - mem_writed(cpu_tss.base+offsetof(TSS_32,eax),reg_eax); - mem_writed(cpu_tss.base+offsetof(TSS_32,ecx),reg_ecx); - mem_writed(cpu_tss.base+offsetof(TSS_32,edx),reg_edx); - mem_writed(cpu_tss.base+offsetof(TSS_32,ebx),reg_ebx); - mem_writed(cpu_tss.base+offsetof(TSS_32,esp),reg_esp); - mem_writed(cpu_tss.base+offsetof(TSS_32,ebp),reg_ebp); - mem_writed(cpu_tss.base+offsetof(TSS_32,esi),reg_esi); - mem_writed(cpu_tss.base+offsetof(TSS_32,edi),reg_edi); - - mem_writed(cpu_tss.base+offsetof(TSS_32,es),SegValue(es)); - mem_writed(cpu_tss.base+offsetof(TSS_32,cs),SegValue(cs)); - mem_writed(cpu_tss.base+offsetof(TSS_32,ss),SegValue(ss)); - mem_writed(cpu_tss.base+offsetof(TSS_32,ds),SegValue(ds)); - mem_writed(cpu_tss.base+offsetof(TSS_32,fs),SegValue(fs)); - mem_writed(cpu_tss.base+offsetof(TSS_32,gs),SegValue(gs)); - } else { - E_Exit("286 task switch"); - } - - /* Setup a back link to the old TSS in new TSS */ - if (tstype==TSwitch_CALL_INT) { - if (new_tss.is386) { - mem_writed(new_tss.base+offsetof(TSS_32,back),cpu_tss.selector); - } else { - mem_writew(new_tss.base+offsetof(TSS_16,back),cpu_tss.selector); - } - /* And make the new task's eflag have the nested task bit */ - new_eflags|=FLAG_NT; - } - /* Set the busy bit in the new task */ - if (tstype==TSwitch_JMP || tstype==TSwitch_CALL_INT) { - new_tss.desc.SetBusy(true); - new_tss.SaveSelector(); - } - -// cpu.cr0|=CR0_TASKSWITCHED; - if (new_tss_selector == cpu_tss.selector) { - reg_eip = old_eip; - new_cs = SegValue(cs); - new_ss = SegValue(ss); - new_ds = SegValue(ds); - new_es = SegValue(es); - new_fs = SegValue(fs); - new_gs = SegValue(gs); - } else { - - /* Setup the new cr3 */ - PAGING_SetDirBase(new_cr3); - - /* Load new context */ - if (new_tss.is386) { - reg_eip=new_eip; - CPU_SetFlags(new_eflags,FMASK_ALL | FLAG_VM); - reg_eax=new_eax; - reg_ecx=new_ecx; - reg_edx=new_edx; - reg_ebx=new_ebx; - reg_esp=new_esp; - reg_ebp=new_ebp; - reg_edi=new_edi; - reg_esi=new_esi; - -// new_cs=mem_readw(new_tss.base+offsetof(TSS_32,cs)); - } else { - E_Exit("286 task switch"); - } - } - /* Load the new selectors */ - if (reg_flags & FLAG_VM) { - SegSet16(cs,new_cs); - cpu.code.big=false; - cpu.cpl=3; //We don't have segment caches so this will do - } else { - /* Protected mode task */ - if (new_ldt!=0) CPU_LLDT(new_ldt); - /* Load the new CS*/ - Descriptor cs_desc; - cpu.cpl=new_cs & 3; - if (!cpu.gdt.GetDescriptor(new_cs,cs_desc)) - E_Exit("Task switch with CS beyond limits"); - if (!cs_desc.saved.seg.p) - E_Exit("Task switch with non present code-segment"); - switch (cs_desc.Type()) { - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cpu.cpl != cs_desc.DPL()) E_Exit("Task CS RPL != DPL"); - goto doconforming; - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - if (cpu.cpl < cs_desc.DPL()) E_Exit("Task CS RPL < DPL"); -doconforming: - Segs.phys[cs]=cs_desc.GetBase(); - cpu.code.big=cs_desc.Big()>0; - Segs.val[cs]=new_cs; - break; - default: - E_Exit("Task switch CS Type %d",cs_desc.Type()); - } - } - CPU_SetSegGeneral(es,new_es); - CPU_SetSegGeneral(ss,new_ss); - CPU_SetSegGeneral(ds,new_ds); - CPU_SetSegGeneral(fs,new_fs); - CPU_SetSegGeneral(gs,new_gs); - if (!cpu_tss.SetSelector(new_tss_selector)) { - LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); - } -// cpu_tss.desc.SetBusy(true); -// cpu_tss.SaveSelector(); -// LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); - return true; -} - -bool CPU_IO_Exception(Bitu port,Bitu size) { - if (cpu.pmode && ((GETFLAG_IOPLcpu_tss.limit) goto doexception; - bwhere=cpu_tss.base+ofs+(port/8); - Bitu map=mem_readw(bwhere); - Bitu mask=(0xffff>>(16-size)) << (port&7); - if (map & mask) goto doexception; - cpu.mpl=3; - } - return false; -doexception: - cpu.mpl=3; - LOG(LOG_CPU,LOG_NORMAL)("IO Exception port %X",port); - return CPU_PrepareException(EXCEPTION_GP,0); -} - -void CPU_Exception(Bitu which,Bitu error ) { -// LOG_MSG("Exception %d error %x",which,error); - cpu.exception.error=error; - CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip); -} - -Bit8u lastint; -void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) { - lastint=num; - FillFlags(); -#if C_DEBUG - switch (num) { - case 0xcd: -#if C_HEAVY_DEBUG - LOG(LOG_CPU,LOG_ERROR)("Call to interrupt 0xCD this is BAD"); - DEBUG_HeavyWriteLogInstruction(); - E_Exit("Call to interrupt 0xCD this is BAD"); -#endif - break; - case 0x03: - if (DEBUG_Breakpoint()) { - CPU_Cycles=0; - return; - } - }; -#endif - if (!cpu.pmode) { - /* Save everything on a 16-bit stack */ - CPU_Push16(reg_flags & 0xffff); - CPU_Push16(SegValue(cs)); - CPU_Push16(oldeip); - SETFLAGBIT(IF,false); - SETFLAGBIT(TF,false); - /* Get the new CS:IP from vector table */ - PhysPt base=cpu.idt.GetBase(); - reg_eip=mem_readw(base+(num << 2)); - Segs.val[cs]=mem_readw(base+(num << 2)+2); - Segs.phys[cs]=Segs.val[cs]<<4; - cpu.code.big=false; - return; - } else { - /* Protected Mode Interrupt */ - if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE) && !(type&CPU_INT_NOIOPLCHECK)) { -// LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12); - if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - CPU_Exception(EXCEPTION_GP,0); - return; - } - } - - Descriptor gate; - if (!cpu.idt.GetDescriptor(num<<3,gate)) { - // zone66 - CPU_Exception(EXCEPTION_GP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1); - return; - } - - if ((type&CPU_INT_SOFTWARE) && (gate.DPL()cpu.cpl, - "Interrupt to higher privilege", - EXCEPTION_GP,(gate_sel & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - switch (cs_desc.Type()) { - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (cs_dpl0", - EXCEPTION_GP,gate_sel & 0xfffc) - - Bitu n_ss,n_esp; - Bitu o_ss,o_esp; - o_ss=SegValue(ss); - o_esp=reg_esp; - cpu_tss.Get_SSx_ESPx(cs_dpl,n_ss,n_esp); - CPU_CHECK_COND((n_ss & 0xfffc)==0, - "INT:Gate with SS zero selector", - EXCEPTION_TS,(type&CPU_INT_SOFTWARE)?0:1) - Descriptor n_ss_desc; - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss,n_ss_desc), - "INT:Gate with SS beyond limit", - EXCEPTION_TS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - CPU_CHECK_COND(((n_ss & 3)!=cs_dpl) || (n_ss_desc.DPL()!=cs_dpl), - "INT:Inner level with CS_DPL!=SS_DPL and SS_RPL", - EXCEPTION_TS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - - // check if stack segment is a writable data segment - switch (n_ss_desc.Type()) { - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - break; - default: - E_Exit("INT:Inner level:Stack segment not writable."); // or #TS(ss_sel+EXT) - } - CPU_CHECK_COND(!n_ss_desc.saved.seg.p, - "INT:Inner level with nonpresent SS", - EXCEPTION_SS,(n_ss & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - - // commit point - Segs.phys[ss]=n_ss_desc.GetBase(); - Segs.val[ss]=n_ss; - if (n_ss_desc.Big()) { - cpu.stack.big=true; - cpu.stack.mask=0xffffffff; - cpu.stack.notmask=0; - reg_esp=n_esp; - } else { - cpu.stack.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - reg_sp=n_esp & 0xffff; - } - - cpu.cpl=cs_dpl; - if (gate.Type() & 0x8) { /* 32-bit Gate */ - if (reg_flags & FLAG_VM) { - CPU_Push32(SegValue(gs));SegSet16(gs,0x0); - CPU_Push32(SegValue(fs));SegSet16(fs,0x0); - CPU_Push32(SegValue(ds));SegSet16(ds,0x0); - CPU_Push32(SegValue(es));SegSet16(es,0x0); - } - CPU_Push32(o_ss); - CPU_Push32(o_esp); - } else { /* 16-bit Gate */ - if (reg_flags & FLAG_VM) E_Exit("V86 to 16-bit gate"); - CPU_Push16(o_ss); - CPU_Push16(o_esp); - } -// LOG_MSG("INT:Gate to inner level SS:%X SP:%X",n_ss,n_esp); - goto do_interrupt; - } - if (cs_dpl!=cpu.cpl) - E_Exit("Non-conforming intra privilege INT with DPL!=CPL"); - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - /* Prepare stack for gate to same priviledge */ - CPU_CHECK_COND(!cs_desc.saved.seg.p, - "INT:Same level:CS segment not present", - EXCEPTION_NP,(gate_sel & 0xfffc)+(type&CPU_INT_SOFTWARE)?0:1) - if ((reg_flags & FLAG_VM) && (cs_dpl0; - reg_eip=gate_off; - - if (!(gate.Type()&1)) { - SETFLAGBIT(IF,false); - } - SETFLAGBIT(TF,false); - SETFLAGBIT(NT,false); - SETFLAGBIT(VM,false); - LOG(LOG_CPU,LOG_NORMAL)("INT:Gate to %X:%X big %d %s",gate_sel,gate_off,cs_desc.Big(),gate.Type() & 0x8 ? "386" : "286"); - return; - } - case DESC_TASK_GATE: - CPU_CHECK_COND(!gate.saved.seg.p, - "INT:Gate segment not present", - EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1) - - CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT,oldeip); - if (type & CPU_INT_HAS_ERROR) { - //TODO Be sure about this, seems somewhat unclear - if (cpu_tss.is386) CPU_Push32(cpu.exception.error); - else CPU_Push16(cpu.exception.error); - } - return; - default: - E_Exit("Illegal descriptor type %X for int %X",gate.Type(),num); - } - } - assert(1); - return ; // make compiler happy -} - - -void CPU_IRET(bool use32,Bitu oldeip) { - if (!cpu.pmode) { /* RealMode IRET */ - if (use32) { - reg_eip=CPU_Pop32(); - SegSet16(cs,CPU_Pop32()); - CPU_SetFlags(CPU_Pop32(),FMASK_ALL); - } else { - reg_eip=CPU_Pop16(); - SegSet16(cs,CPU_Pop16()); - CPU_SetFlags(CPU_Pop16(),FMASK_ALL & 0xffff); - } - cpu.code.big=false; - DestroyConditionFlags(); - return; - } else { /* Protected mode IRET */ - if (reg_flags & FLAG_VM) { - if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) { - // win3.x e - CPU_Exception(EXCEPTION_GP,0); - return; - } else { - if (use32) { - Bit32u new_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); - Bit32u new_cs=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - Bit32u new_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); - reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - - reg_eip=new_eip; - SegSet16(cs,(Bit16u)(new_cs&0xffff)); - /* IOPL can not be modified in v86 mode by IRET */ - CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT); - } else { - Bit16u new_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); - Bit16u new_cs=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - Bit16u new_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - - reg_eip=(Bit32u)new_eip; - SegSet16(cs,new_cs); - /* IOPL can not be modified in v86 mode by IRET */ - CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT); - } - cpu.code.big=false; - DestroyConditionFlags(); - return; - } - } - /* Check if this is task IRET */ - if (GETFLAG(NT)) { - if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set"); - CPU_CHECK_COND(!cpu_tss.IsValid(), - "TASK Iret without valid TSS", - EXCEPTION_TS,cpu_tss.selector & 0xfffc) - if (!cpu_tss.desc.IsBusy()) { - LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy"); - } - Bitu back_link=cpu_tss.Get_back(); - CPU_SwitchTask(back_link,TSwitch_IRET,oldeip); - return; - } - Bitu n_cs_sel,n_eip,n_flags; - Bit32u tempesp; - if (use32) { - n_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask); - n_cs_sel=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)) & 0xffff; - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - n_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask); - - if ((n_flags & FLAG_VM) && (cpu.cpl==0)) { - // commit point - reg_esp=tempesp; - reg_eip=n_eip & 0xffff; - Bitu n_ss,n_esp,n_es,n_ds,n_fs,n_gs; - n_esp=CPU_Pop32(); - n_ss=CPU_Pop32() & 0xffff; - n_es=CPU_Pop32() & 0xffff; - n_ds=CPU_Pop32() & 0xffff; - n_fs=CPU_Pop32() & 0xffff; - n_gs=CPU_Pop32() & 0xffff; - - CPU_SetFlags(n_flags,FMASK_ALL | FLAG_VM); - DestroyConditionFlags(); - cpu.cpl=3; - - CPU_SetSegGeneral(ss,n_ss); - CPU_SetSegGeneral(es,n_es); - CPU_SetSegGeneral(ds,n_ds); - CPU_SetSegGeneral(fs,n_fs); - CPU_SetSegGeneral(gs,n_gs); - reg_esp=n_esp; - cpu.code.big=false; - SegSet16(cs,n_cs_sel); - LOG(LOG_CPU,LOG_NORMAL)("IRET:Back to V86: CS:%X IP %X SS:%X SP %X FLAGS:%X",SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); - return; - } - if (n_flags & FLAG_VM) E_Exit("IRET from pmode to v86 with CPL!=0"); - } else { - n_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask); - n_cs_sel=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - n_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask)); - n_flags|=(reg_flags & 0xffff0000); - tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask); - - if (n_flags & FLAG_VM) E_Exit("VM Flag in 16-bit iret"); - } - CPU_CHECK_COND((n_cs_sel & 0xfffc)==0, - "IRET:CS selector zero", - EXCEPTION_GP,0) - Bitu n_cs_rpl=n_cs_sel & 3; - Descriptor n_cs_desc; - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_cs_sel,n_cs_desc), - "IRET:CS selector beyond limits", - EXCEPTION_GP,n_cs_sel & 0xfffc) - CPU_CHECK_COND(n_cs_rpln_cs_rpl, - "IRET:C:DPL>RPL", - EXCEPTION_GP,n_cs_sel & 0xfffc) - break; - default: - E_Exit("IRET:Illegal descriptor type %X",n_cs_desc.Type()); - } - CPU_CHECK_COND(!n_cs_desc.saved.seg.p, - "IRET with nonpresent code segment", - EXCEPTION_NP,n_cs_sel & 0xfffc) - - if (n_cs_rpl==cpu.cpl) { - /* Return to same level */ - - // commit point - reg_esp=tempesp; - Segs.phys[cs]=n_cs_desc.GetBase(); - cpu.code.big=n_cs_desc.Big()>0; - Segs.val[cs]=n_cs_sel; - reg_eip=n_eip; - - Bitu mask=cpu.cpl ? (FMASK_NORMAL | FLAG_NT) : FMASK_ALL; - if (GETFLAG_IOPL0; - Segs.val[cs]=n_cs_sel; - - Bitu mask=cpu.cpl ? (FMASK_NORMAL | FLAG_NT) : FMASK_ALL; - if (GETFLAG_IOPLcpu.cpl, - "JMP:NC:RPL>CPL", - EXCEPTION_GP,selector & 0xfffc) - CPU_CHECK_COND(cpu.cpl!=desc.DPL(), - "JMP:NC:RPL != DPL", - EXCEPTION_GP,selector & 0xfffc) - LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big()); - goto CODE_jmp; - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:C to %X:%X big %d",selector,offset,desc.Big()); - CPU_CHECK_COND(cpu.cpl0; - Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; - reg_eip=offset; - return; - case DESC_386_TSS_A: - CPU_CHECK_COND(desc.DPL()cpu.cpl, - "CALL:CODE:NC:RPL>CPL", - EXCEPTION_GP,selector & 0xfffc) - CPU_CHECK_COND(call.DPL()!=cpu.cpl, - "CALL:CODE:NC:DPL!=CPL", - EXCEPTION_GP,selector & 0xfffc) - LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:NC to %X:%X",selector,offset); - goto call_code; - case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: - CPU_CHECK_COND(call.DPL()>cpu.cpl, - "CALL:CODE:C:DPL>CPL", - EXCEPTION_GP,selector & 0xfffc) - LOG(LOG_CPU,LOG_NORMAL)("CALL:CODE:C to %X:%X",selector,offset); -call_code: - if (!call.saved.seg.p) { - // borland extender (RTM) - CPU_Exception(EXCEPTION_NP,selector & 0xfffc); - return; - } - // commit point - if (!use32) { - CPU_Push16(SegValue(cs)); - CPU_Push16(oldeip); - reg_eip=offset & 0xffff; - } else { - CPU_Push32(SegValue(cs)); - CPU_Push32(oldeip); - reg_eip=offset; - } - Segs.phys[cs]=call.GetBase(); - cpu.code.big=call.Big()>0; - Segs.val[cs]=(selector & 0xfffc) | cpu.cpl; - return; - case DESC_386_CALL_GATE: - case DESC_286_CALL_GATE: - { - CPU_CHECK_COND(call.DPL()cpu.cpl, - "CALL:Gate:CS DPL>CPL", - EXCEPTION_GP,n_cs_sel & 0xfffc) - - CPU_CHECK_COND(!n_cs_desc.saved.seg.p, - "CALL:Gate:CS not present", - EXCEPTION_NP,n_cs_sel & 0xfffc) - - Bitu n_eip = call.GetOffset(); - switch (n_cs_desc.Type()) { - case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: - /* Check if we goto inner priviledge */ - if (n_cs_dpl < cpu.cpl) { - /* Get new SS:ESP out of TSS */ - Bitu n_ss_sel,n_esp; - Descriptor n_ss_desc; - cpu_tss.Get_SSx_ESPx(n_cs_dpl,n_ss_sel,n_esp); - CPU_CHECK_COND((n_ss_sel & 0xfffc)==0, - "CALL:Gate:NC:SS selector zero", - EXCEPTION_TS,0) - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss_sel,n_ss_desc), - "CALL:Gate:Invalid SS selector", - EXCEPTION_TS,n_ss_sel & 0xfffc) - CPU_CHECK_COND(((n_ss_sel & 3)!=n_cs_desc.DPL()) || (n_ss_desc.DPL()!=n_cs_desc.DPL()), - "CALL:Gate:Invalid SS selector privileges", - EXCEPTION_TS,n_ss_sel & 0xfffc) - - switch (n_ss_desc.Type()) { - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - // writable data segment - break; - default: - E_Exit("Call:Gate:SS no writable data segment"); // or #TS(ss_sel) - } - CPU_CHECK_COND(!n_ss_desc.saved.seg.p, - "CALL:Gate:Stack segment not present", - EXCEPTION_SS,n_ss_sel & 0xfffc) - - /* Load the new SS:ESP and save data on it */ - Bitu o_esp = reg_esp; - Bitu o_ss = SegValue(ss); - PhysPt o_stack = SegPhys(ss)+(reg_esp & cpu.stack.mask); - - - // catch pagefaults - if (call.saved.gate.paramcount&31) { - if (call.Type()==DESC_386_CALL_GATE) { - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - mem_readd(o_stack+i*4); - } else { - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - mem_readw(o_stack+i*2); - } - } - - // commit point - Segs.val[ss]=n_ss_sel; - Segs.phys[ss]=n_ss_desc.GetBase(); - if (n_ss_desc.Big()) { - cpu.stack.big=true; - cpu.stack.mask=0xffffffff; - cpu.stack.notmask=0; - reg_esp=n_esp; - } else { - cpu.stack.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - reg_sp=n_esp & 0xffff; - } - - cpu.cpl = n_cs_desc.DPL(); - Bit16u oldcs = SegValue(cs); - /* Switch to new CS:EIP */ - Segs.phys[cs] = n_cs_desc.GetBase(); - Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; - cpu.code.big = n_cs_desc.Big()>0; - reg_eip = n_eip; - if (!use32) reg_eip&=0xffff; - - if (call.Type()==DESC_386_CALL_GATE) { - CPU_Push32(o_ss); //save old stack - CPU_Push32(o_esp); - if (call.saved.gate.paramcount&31) - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - CPU_Push32(mem_readd(o_stack+i*4)); - CPU_Push32(oldcs); - CPU_Push32(oldeip); - } else { - CPU_Push16(o_ss); //save old stack - CPU_Push16(o_esp); - if (call.saved.gate.paramcount&31) - for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--) - CPU_Push16(mem_readw(o_stack+i*2)); - CPU_Push16(oldcs); - CPU_Push16(oldeip); - } - - break; - } else if (n_cs_dpl > cpu.cpl) - E_Exit("CALL:GATE:CS DPL>CPL"); // or #GP(sel) - case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: - // zrdx extender - - if (call.Type()==DESC_386_CALL_GATE) { - CPU_Push32(SegValue(cs)); - CPU_Push32(oldeip); - } else { - CPU_Push16(SegValue(cs)); - CPU_Push16(oldeip); - } - - /* Switch to new CS:EIP */ - Segs.phys[cs] = n_cs_desc.GetBase(); - Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl; - cpu.code.big = n_cs_desc.Big()>0; - reg_eip = n_eip; - if (!use32) reg_eip&=0xffff; - break; - default: - E_Exit("CALL:GATE:CS no executable segment"); - } - } /* Call Gates */ - break; - case DESC_386_TSS_A: - CPU_CHECK_COND(call.DPL()cpu.cpl, - "RET to C segment of higher privilege", - EXCEPTION_GP,selector & 0xfffc) - break; - default: - E_Exit("RET from illegal descriptor type %X",desc.Type()); - } -RET_same_level: - if (!desc.saved.seg.p) { - // borland extender (RTM) - CPU_Exception(EXCEPTION_NP,selector & 0xfffc); - return; - } - - // commit point - if (!use32) { - offset=CPU_Pop16(); - selector=CPU_Pop16(); - } else { - offset=CPU_Pop32(); - selector=CPU_Pop32() & 0xffff; - } - - Segs.phys[cs]=desc.GetBase(); - cpu.code.big=desc.Big()>0; - Segs.val[cs]=selector; - reg_eip=offset; - if (cpu.stack.big) { - reg_esp+=bytes; - } else { - reg_sp+=bytes; - } - LOG(LOG_CPU,LOG_NORMAL)("RET - Same level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); - return; - } else { - /* Return to outer level */ - switch (desc.Type()) { - case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: - CPU_CHECK_COND(desc.DPL()!=rpl, - "RET to outer NC segment with DPL!=RPL", - EXCEPTION_GP,selector & 0xfffc) - break; - case DESC_CODE_N_C_A:case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A:case DESC_CODE_R_C_NA: - CPU_CHECK_COND(desc.DPL()>rpl, - "RET to outer C segment with DPL>RPL", - EXCEPTION_GP,selector & 0xfffc) - break; - default: - E_Exit("RET from illegal descriptor type %X",desc.Type()); // or #GP(selector) - } - - CPU_CHECK_COND(!desc.saved.seg.p, - "RET:Outer level:CS not present", - EXCEPTION_NP,selector & 0xfffc) - - // commit point - Bitu n_esp,n_ss; - if (use32) { - offset=CPU_Pop32(); - selector=CPU_Pop32() & 0xffff; - reg_esp+=bytes; - n_esp = CPU_Pop32(); - n_ss = CPU_Pop32() & 0xffff; - } else { - offset=CPU_Pop16(); - selector=CPU_Pop16(); - reg_esp+=bytes; - n_esp = CPU_Pop16(); - n_ss = CPU_Pop16(); - } - - CPU_CHECK_COND((n_ss & 0xfffc)==0, - "RET to outer level with SS selector zero", - EXCEPTION_GP,0) - - Descriptor n_ss_desc; - CPU_CHECK_COND(!cpu.gdt.GetDescriptor(n_ss,n_ss_desc), - "RET:SS beyond limits", - EXCEPTION_GP,n_ss & 0xfffc) - - CPU_CHECK_COND(((n_ss & 3)!=rpl) || (n_ss_desc.DPL()!=rpl), - "RET to outer segment with invalid SS privileges", - EXCEPTION_GP,n_ss & 0xfffc) - switch (n_ss_desc.Type()) { - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - break; - default: - E_Exit("RET:SS selector type no writable data segment"); // or #GP(selector) - } - CPU_CHECK_COND(!n_ss_desc.saved.seg.p, - "RET:Stack segment not present", - EXCEPTION_SS,n_ss & 0xfffc) - - cpu.cpl = rpl; - Segs.phys[cs]=desc.GetBase(); - cpu.code.big=desc.Big()>0; - Segs.val[cs]=(selector&0xfffc) | cpu.cpl; - reg_eip=offset; - - Segs.val[ss]=n_ss; - Segs.phys[ss]=n_ss_desc.GetBase(); - if (n_ss_desc.Big()) { - cpu.stack.big=true; - cpu.stack.mask=0xffffffff; - cpu.stack.notmask=0; - reg_esp=n_esp+bytes; - } else { - cpu.stack.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - reg_sp=(n_esp & 0xffff)+bytes; - } - - CPU_CheckSegments(); - -// LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); - return; - } - LOG(LOG_CPU,LOG_NORMAL)("Prot ret %X:%X",selector,offset); - return; - } - assert(1); -} - - -Bitu CPU_SLDT(void) { - return cpu.gdt.SLDT(); -} - -bool CPU_LLDT(Bitu selector) { - if (!cpu.gdt.LLDT(selector)) { - LOG(LOG_CPU,LOG_ERROR)("LLDT failed, selector=%X",selector); - return true; - } - LOG(LOG_CPU,LOG_NORMAL)("LDT Set to %X",selector); - return false; -} - -Bitu CPU_STR(void) { - return cpu_tss.selector; -} - -bool CPU_LTR(Bitu selector) { - if ((selector & 0xfffc)==0) { - cpu_tss.SetSelector(selector); - return false; - } - TSS_Descriptor desc; - if ((selector & 4) || (!cpu.gdt.GetDescriptor(selector,desc))) { - LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X",selector); - return CPU_PrepareException(EXCEPTION_GP,selector); - } - - if ((desc.Type()==DESC_286_TSS_A) || (desc.Type()==DESC_386_TSS_A)) { - if (!desc.saved.seg.p) { - LOG(LOG_CPU,LOG_ERROR)("LTR failed, selector=%X (not present)",selector); - return CPU_PrepareException(EXCEPTION_NP,selector); - } - if (!cpu_tss.SetSelector(selector)) E_Exit("LTR failed, selector=%X",selector); - cpu_tss.desc.SetBusy(true); - cpu_tss.SaveSelector(); - } else { - /* Descriptor was no available TSS descriptor */ - LOG(LOG_CPU,LOG_NORMAL)("LTR failed, selector=%X (type=%X)",selector,desc.Type()); - return CPU_PrepareException(EXCEPTION_GP,selector); - } - return false; -} - -void CPU_LGDT(Bitu limit,Bitu base) { - LOG(LOG_CPU,LOG_NORMAL)("GDT Set to base:%X limit:%X",base,limit); - cpu.gdt.SetLimit(limit); - cpu.gdt.SetBase(base); -} - -void CPU_LIDT(Bitu limit,Bitu base) { - LOG(LOG_CPU,LOG_NORMAL)("IDT Set to base:%X limit:%X",base,limit); - cpu.idt.SetLimit(limit); - cpu.idt.SetBase(base); -} - -Bitu CPU_SGDT_base(void) { - return cpu.gdt.GetBase(); -} -Bitu CPU_SGDT_limit(void) { - return cpu.gdt.GetLimit(); -} - -Bitu CPU_SIDT_base(void) { - return cpu.idt.GetBase(); -} -Bitu CPU_SIDT_limit(void) { - return cpu.idt.GetLimit(); -} - -static bool printed_cycles_auto_info = false; -void CPU_SET_CRX(Bitu cr,Bitu value) { - switch (cr) { - case 0: - { - value|=CR0_FPUPRESENT; - Bitu changed=cpu.cr0 ^ value; - if (!changed) return; - cpu.cr0=value; - if (value & CR0_PROTECTION) { - cpu.pmode=true; - LOG(LOG_CPU,LOG_NORMAL)("Protected mode"); - PAGING_Enable((value & CR0_PAGING)>0); - - if (!(CPU_AutoDetermineMode&CPU_AUTODETERMINE_MASK)) break; - - if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CYCLES) { - CPU_CycleAutoAdjust=true; - CPU_CycleLeft=0; - CPU_Cycles=0; - CPU_OldCycleMax=CPU_CycleMax; - GFX_SetTitle(CPU_CyclePercUsed,-1,false); - if(!printed_cycles_auto_info) { - printed_cycles_auto_info = true; - LOG_MSG("DOSBox has switched to max cycles, because of the setting: cycles=auto.\nIf the game runs too fast, try a fixed cycles amount in DOSBox's options."); - } - } else { - GFX_SetTitle(-1,-1,false); - } -#if (C_DYNAMIC_X86) - if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { - CPU_Core_Dyn_X86_Cache_Init(true); - cpudecoder=&CPU_Core_Dyn_X86_Run; - } -#elif (C_DYNREC) - if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CORE) { - CPU_Core_Dynrec_Cache_Init(true); - cpudecoder=&CPU_Core_Dynrec_Run; - } -#endif - CPU_AutoDetermineMode<<=CPU_AUTODETERMINE_SHIFT; - } else { - cpu.pmode=false; - if (value & CR0_PAGING) LOG_MSG("Paging requested without PE=1"); - PAGING_Enable(false); - LOG(LOG_CPU,LOG_NORMAL)("Real mode"); - } - break; - } - case 2: - paging.cr2=value; - break; - case 3: - PAGING_SetDirBase(value); - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV CR%d,%X",cr,value); - break; - } -} - -bool CPU_WRITE_CRX(Bitu cr,Bitu value) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); - if (CPU_ArchitectureType=CPU_ARCHTYPE_PENTIUMSLOW) return cpu.cr0; - else if (CPU_ArchitectureType>=CPU_ARCHTYPE_486OLDSLOW) return (cpu.cr0 & 0xe005003f); - else return (cpu.cr0 | 0x7ffffff0); - case 2: - return paging.cr2; - case 3: - return PAGING_GetDirBase() & 0xfffff000; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, CR%d",cr); - break; - } - return 0; -} - -bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); - retvalue=CPU_GET_CRX(cr); - return false; -} - - -bool CPU_WRITE_DRX(Bitu dr,Bitu value) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (dr) { - case 0: - case 1: - case 2: - case 3: - cpu.drx[dr]=value; - break; - case 4: - case 6: - cpu.drx[6]=(value|0xffff0ff0) & 0xffffefff; - break; - case 5: - case 7: - if (CPU_ArchitectureType0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (dr) { - case 0: - case 1: - case 2: - case 3: - case 6: - case 7: - retvalue=cpu.drx[dr]; - break; - case 4: - retvalue=cpu.drx[6]; - break; - case 5: - retvalue=cpu.drx[7]; - break; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, DR%d",dr); - retvalue=0; - break; - } - return false; -} - -bool CPU_WRITE_TRX(Bitu tr,Bitu value) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (tr) { -// case 3: - case 6: - case 7: - cpu.trx[tr]=value; - return false; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV TR%d,%X",tr,value); - break; - } - return CPU_PrepareException(EXCEPTION_UD,0); -} - -bool CPU_READ_TRX(Bitu tr,Bit32u & retvalue) { - /* Check if privileged to access control registers */ - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - switch (tr) { -// case 3: - case 6: - case 7: - retvalue=cpu.trx[tr]; - return false; - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV XXX, TR%d",tr); - break; - } - return CPU_PrepareException(EXCEPTION_UD,0); -} - - -Bitu CPU_SMSW(void) { - return cpu.cr0; -} - -bool CPU_LMSW(Bitu word) { - if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); - word&=0xf; - if (cpu.cr0 & 1) word|=1; - word|=(cpu.cr0&0xfffffff0); - CPU_SET_CRX(0,word); - return false; -} - -void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) { - FillFlags(); - if ((dest_sel & 3) < (src_sel & 3)) { - dest_sel=(dest_sel & 0xfffc) + (src_sel & 3); -// dest_sel|=0xff3f0000; - SETFLAGBIT(ZF,true); - } else { - SETFLAGBIT(ZF,false); - } -} - -void CPU_LAR(Bitu selector,Bitu & ar) { - FillFlags(); - if (selector == 0) { - SETFLAGBIT(ZF,false); - return; - } - Descriptor desc;Bitu rpl=selector & 3; - if (!cpu.gdt.GetDescriptor(selector,desc)){ - SETFLAGBIT(ZF,false); - return; - } - switch (desc.Type()){ - case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA: - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - break; - - case DESC_286_INT_GATE: case DESC_286_TRAP_GATE: { - case DESC_386_INT_GATE: case DESC_386_TRAP_GATE: - SETFLAGBIT(ZF,false); - return; - } - - case DESC_LDT: - case DESC_TASK_GATE: - - case DESC_286_TSS_A: case DESC_286_TSS_B: - case DESC_286_CALL_GATE: - - case DESC_386_TSS_A: case DESC_386_TSS_B: - case DESC_386_CALL_GATE: - - - case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: - case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A: - case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: - case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A: - case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: - case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA: - if (desc.DPL()desc.DPL()) || (cpu.cpl>desc.DPL())) { - // extreme pinball - return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); - } - break; - case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA: - break; - default: - // gabriel knight - return CPU_PrepareException(EXCEPTION_GP,value & 0xfffc); - - } - if (!desc.saved.seg.p) { - // win - return CPU_PrepareException(EXCEPTION_NP,value & 0xfffc); - } - - Segs.val[seg]=value; - Segs.phys[seg]=desc.GetBase(); - } - - return false; - } -} - -bool CPU_PopSeg(SegNames seg,bool use32) { - Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask)); - if (CPU_SetSegGeneral(seg,val)) return true; - Bitu addsp=use32?0x04:0x02; - reg_esp=(reg_esp&cpu.stack.notmask)|((reg_esp+addsp)&cpu.stack.mask); - return false; -} - -bool CPU_CPUID(void) { - if (CPU_ArchitectureType105) CPU_CyclePercUsed=105; - LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed); - GFX_SetTitle(CPU_CyclePercUsed,-1,false); - } else { - Bit32s old_cycles=CPU_CycleMax; - if (CPU_CycleUp < 100) { - CPU_CycleMax = (Bit32s)(CPU_CycleMax * (1 + (float)CPU_CycleUp / 100.0)); - } else { - CPU_CycleMax = (Bit32s)(CPU_CycleMax + CPU_CycleUp); - } - - CPU_CycleLeft=0;CPU_Cycles=0; - if (CPU_CycleMax==old_cycles) CPU_CycleMax++; - if(CPU_CycleMax > 15000 ) - LOG_MSG("CPU speed: fixed %d cycles. If you need more than 20000, try core=dynamic in DOSBox's options.",CPU_CycleMax); - else - LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1,false); - } -} - -static void CPU_CycleDecrease(bool pressed) { - if (!pressed) return; - if (CPU_CycleAutoAdjust) { - CPU_CyclePercUsed-=5; - if (CPU_CyclePercUsed<=0) CPU_CyclePercUsed=1; - if(CPU_CyclePercUsed <=70) - LOG_MSG("CPU speed: max %d percent. If the game runs too fast, try a fixed cycles amount in DOSBox's options.",CPU_CyclePercUsed); - else - LOG_MSG("CPU speed: max %d percent.",CPU_CyclePercUsed); - GFX_SetTitle(CPU_CyclePercUsed,-1,false); - } else { - if (CPU_CycleDown < 100) { - CPU_CycleMax = (Bit32s)(CPU_CycleMax / (1 + (float)CPU_CycleDown / 100.0)); - } else { - CPU_CycleMax = (Bit32s)(CPU_CycleMax - CPU_CycleDown); - } - CPU_CycleLeft=0;CPU_Cycles=0; - if (CPU_CycleMax <= 0) CPU_CycleMax=1; - LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax); - GFX_SetTitle(CPU_CycleMax,-1,false); - } -} - -void CPU_Enable_SkipAutoAdjust(void) { - if (CPU_CycleAutoAdjust) { - CPU_CycleMax /= 2; - if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT) - CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT; - } - CPU_SkipCycleAutoAdjust=true; -} - -void CPU_Disable_SkipAutoAdjust(void) { - CPU_SkipCycleAutoAdjust=false; -} - - - -void CPU_Reset_AutoAdjust(void) { - CPU_IODelayRemoved = 0; - ticksDone = 0; - ticksScheduled = 0; -} -#if 0 -class CPU: public Module_base { -private: - static bool inited; -public: - CPU(Section* configuration):Module_base(configuration) { - if(inited) { - Change_Config(configuration); - return; - } -// Section_prop * section=static_cast(configuration); - inited=true; - reg_eax=0; - reg_ebx=0; - reg_ecx=0; - reg_edx=0; - reg_edi=0; - reg_esi=0; - reg_ebp=0; - reg_esp=0; - - SegSet16(cs,0); - SegSet16(ds,0); - SegSet16(es,0); - SegSet16(fs,0); - SegSet16(gs,0); - SegSet16(ss,0); - - CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts - cpu.cr0=0xffffffff; - CPU_SET_CRX(0,0); //Initialize - cpu.code.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - cpu.stack.big=false; - cpu.trap_skip=false; - cpu.idt.SetBase(0); - cpu.idt.SetLimit(1023); - - for (Bitu i=0; i<7; i++) { - cpu.drx[i]=0; - cpu.trx[i]=0; - } - if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) { - cpu.drx[6]=0xffff0ff0; - } else { - cpu.drx[6]=0xffff1ff0; - } - cpu.drx[7]=0x00000400; - - /* Init the cpu cores */ - CPU_Core_Normal_Init(); - CPU_Core_Simple_Init(); - CPU_Core_Full_Init(); -#if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Init(); -#elif (C_DYNREC) - CPU_Core_Dynrec_Init(); -#endif - MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); - MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); - Change_Config(configuration); - CPU_JMP(false,0,0,0); //Setup the first cpu core - } - bool Change_Config(Section* newconfig){ - Section_prop * section=static_cast(newconfig); - CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE; - //CPU_CycleLeft=0;//needed ? - CPU_Cycles=0; - CPU_SkipCycleAutoAdjust=false; - - Prop_multival* p = section->Get_multival("cycles"); - std::string type = p->GetSection()->Get_string("type"); - std::string str ; - CommandLine cmd(0,p->GetSection()->Get_string("parameters")); - if (type=="max") { - CPU_CycleMax=0; - CPU_CyclePercUsed=100; - CPU_CycleAutoAdjust=true; - CPU_CycleLimit=-1; - for (Bitu cmdnum=1; cmdnum<=cmd.GetCount(); cmdnum++) { - if (cmd.FindCommand(cmdnum,str)) { - if (str.find('%')==str.length()-1) { - str.erase(str.find('%')); - int percval=0; - std::istringstream stream(str); - stream >> percval; - if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval; - } else if (str=="limit") { - cmdnum++; - if (cmd.FindCommand(cmdnum,str)) { - int cyclimit=0; - std::istringstream stream(str); - stream >> cyclimit; - if (cyclimit>0) CPU_CycleLimit=cyclimit; - } - } - } - } - } else { - if (type=="auto") { - CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES; - CPU_CycleMax=3000; - CPU_OldCycleMax=3000; - CPU_CyclePercUsed=100; - for (Bitu cmdnum=0; cmdnum<=cmd.GetCount(); cmdnum++) { - if (cmd.FindCommand(cmdnum,str)) { - if (str.find('%')==str.length()-1) { - str.erase(str.find('%')); - int percval=0; - std::istringstream stream(str); - stream >> percval; - if ((percval>0) && (percval<=105)) CPU_CyclePercUsed=(Bit32s)percval; - } else if (str=="limit") { - cmdnum++; - if (cmd.FindCommand(cmdnum,str)) { - int cyclimit=0; - std::istringstream stream(str); - stream >> cyclimit; - if (cyclimit>0) CPU_CycleLimit=cyclimit; - } - } else { - int rmdval=0; - std::istringstream stream(str); - stream >> rmdval; - if (rmdval>0) { - CPU_CycleMax=(Bit32s)rmdval; - CPU_OldCycleMax=(Bit32s)rmdval; - } - } - } - } - } else if(type =="fixed") { - cmd.FindCommand(1,str); - int rmdval=0; - std::istringstream stream(str); - stream >> rmdval; - CPU_CycleMax=(Bit32s)rmdval; - } else { - std::istringstream stream(type); - int rmdval=0; - stream >> rmdval; - if(rmdval) CPU_CycleMax=(Bit32s)rmdval; - } - CPU_CycleAutoAdjust=false; - } - - CPU_CycleUp=section->Get_int("cycleup"); - CPU_CycleDown=section->Get_int("cycledown"); - std::string core(section->Get_string("core")); - cpudecoder=&CPU_Core_Normal_Run; - if (core == "normal") { - cpudecoder=&CPU_Core_Normal_Run; - } else if (core =="simple") { - cpudecoder=&CPU_Core_Simple_Run; - } else if (core == "full") { - cpudecoder=&CPU_Core_Full_Run; - } else if (core == "auto") { - cpudecoder=&CPU_Core_Normal_Run; -#if (C_DYNAMIC_X86) - CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; - } - else if (core == "dynamic") { - cpudecoder=&CPU_Core_Dyn_X86_Run; - CPU_Core_Dyn_X86_SetFPUMode(true); - } else if (core == "dynamic_nodhfpu") { - cpudecoder=&CPU_Core_Dyn_X86_Run; - CPU_Core_Dyn_X86_SetFPUMode(false); -#elif (C_DYNREC) - CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; - } - else if (core == "dynamic") { - cpudecoder=&CPU_Core_Dynrec_Run; -#else - -#endif - } - -#if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Cache_Init((core == "dynamic") || (core == "dynamic_nodhfpu")); -#elif (C_DYNREC) - CPU_Core_Dynrec_Cache_Init( core == "dynamic" ); -#endif - - CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; - std::string cputype(section->Get_string("cputype")); - if (cputype == "auto") { - CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; - } else if (cputype == "386") { - CPU_ArchitectureType = CPU_ARCHTYPE_386FAST; - } else if (cputype == "386_prefetch") { - CPU_ArchitectureType = CPU_ARCHTYPE_386FAST; - if (core == "normal") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 16; - } else if (core == "auto") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 16; - CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE); - } else { - E_Exit("prefetch queue emulation requires the normal core setting."); - } - } else if (cputype == "386_slow") { - CPU_ArchitectureType = CPU_ARCHTYPE_386SLOW; - } else if (cputype == "486_slow") { - CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW; - } else if (cputype == "486_prefetch") { - CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW; - if (core == "normal") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 32; - } else if (core == "auto") { - cpudecoder=&CPU_Core_Prefetch_Run; - CPU_PrefetchQueueSize = 32; - CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE); - } else { - E_Exit("prefetch queue emulation requires the normal core setting."); - } - } else if (cputype == "pentium_slow") { - CPU_ArchitectureType = CPU_ARCHTYPE_PENTIUMSLOW; - } - - if (CPU_ArchitectureType>=CPU_ARCHTYPE_486NEWSLOW) CPU_extflags_toggle=(FLAG_ID|FLAG_AC); - else if (CPU_ArchitectureType>=CPU_ARCHTYPE_486OLDSLOW) CPU_extflags_toggle=(FLAG_AC); - else CPU_extflags_toggle=0; - - - if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; - if(CPU_CycleUp <= 0) CPU_CycleUp = 500; - if(CPU_CycleDown <= 0) CPU_CycleDown = 20; - if (CPU_CycleAutoAdjust) GFX_SetTitle(CPU_CyclePercUsed,-1,false); - else GFX_SetTitle(CPU_CycleMax,-1,false); - return true; - } - ~CPU(){ /* empty */}; -}; -#endif -//static CPU * test; - -//void CPU_ShutDown(Section* sec) { -//#if (C_DYNAMIC_X86) -// CPU_Core_Dyn_X86_Cache_Close(); -//#elif (C_DYNREC) -// CPU_Core_Dynrec_Cache_Close(); -//#endif -// delete test; -//} - -//void CPU_Init(Section* sec) { -// test = new CPU(sec); -// sec->AddDestroyFunction(&CPU_ShutDown,true); -//} - -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp deleted file mode 100644 index b5cf940a7..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/flags.cpp +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - Lazy flag system was designed after the same kind of system used in Bochs. - Probably still some bugs left in here. -*/ - -//#include "dosbox.h" -#include "cpu.h" -#include "./lazyflags.h" -#include "pic.h" - -namespace I386_DOSBOX { - -/* CF Carry Flag -- Set on high-order bit carry or borrow; cleared - otherwise. -*/ -Bit32u get_CF(void) { - - switch (lflags.type) { - case t_UNKNOWN: - case t_INCb: - case t_INCw: - case t_INCd: - case t_DECb: - case t_DECw: - case t_DECd: - case t_MUL: - return GETFLAG(CF); - case t_ADDb: - return (lf_resb8) return false; - else return (lf_var1b >> (8-lf_var2b)) & 1; - case t_SHLw: - if (lf_var2b>16) return false; - else return (lf_var1w >> (16-lf_var2b)) & 1; - case t_SHLd: - case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ - case t_DSHLd: - return (lf_var1d >> (32 - lf_var2b)) & 1; - case t_RCRb: - case t_SHRb: - return (lf_var1b >> (lf_var2b - 1)) & 1; - case t_RCRw: - case t_SHRw: - return (lf_var1w >> (lf_var2b - 1)) & 1; - case t_RCRd: - case t_SHRd: - case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - case t_DSHRd: - return (lf_var1d >> (lf_var2b - 1)) & 1; - case t_SARb: - return (((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1; - case t_SARw: - return (((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1; - case t_SARd: - return (((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1; - case t_NEGb: - return lf_var1b; - case t_NEGw: - return lf_var1w; - case t_NEGd: - return lf_var1d; - case t_ORb: - case t_ORw: - case t_ORd: - case t_ANDb: - case t_ANDw: - case t_ANDd: - case t_XORb: - case t_XORw: - case t_XORd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - return false; /* Set to false */ - case t_DIV: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",lflags.type); - } - return 0; -} - -/* AF Adjust flag -- Set on carry from or borrow to the low order - four bits of AL; cleared otherwise. Used for decimal - arithmetic. -*/ -Bit32u get_AF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - return GETFLAG(AF); - case t_ADDb: - case t_ADCb: - case t_SBBb: - case t_SUBb: - case t_CMPb: - return ((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10; - case t_ADDw: - case t_ADCw: - case t_SBBw: - case t_SUBw: - case t_CMPw: - return ((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10; - case t_ADCd: - case t_ADDd: - case t_SBBd: - case t_SUBd: - case t_CMPd: - return ((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10; - case t_INCb: - return (lf_resb & 0x0f) == 0; - case t_INCw: - return (lf_resw & 0x0f) == 0; - case t_INCd: - return (lf_resd & 0x0f) == 0; - case t_DECb: - return (lf_resb & 0x0f) == 0x0f; - case t_DECw: - return (lf_resw & 0x0f) == 0x0f; - case t_DECd: - return (lf_resd & 0x0f) == 0x0f; - case t_NEGb: - return lf_var1b & 0x0f; - case t_NEGw: - return lf_var1w & 0x0f; - case t_NEGd: - return lf_var1d & 0x0f; - case t_SHLb: - case t_SHRb: - case t_SARb: - return lf_var2b & 0x1f; - case t_SHLw: - case t_SHRw: - case t_SARw: - return lf_var2w & 0x1f; - case t_SHLd: - case t_SHRd: - case t_SARd: - return lf_var2d & 0x1f; - case t_ORb: - case t_ORw: - case t_ORd: - case t_ANDb: - case t_ANDw: - case t_ANDd: - case t_XORb: - case t_XORw: - case t_XORd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - case t_DSHLw: - case t_DSHLd: - case t_DSHRw: - case t_DSHRd: - case t_DIV: - case t_MUL: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",lflags.type); - } - return 0; -} - -/* ZF Zero Flag -- Set if result is zero; cleared otherwise. -*/ - -Bit32u get_ZF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - return GETFLAG(ZF); - case t_ADDb: - case t_ORb: - case t_ADCb: - case t_SBBb: - case t_ANDb: - case t_XORb: - case t_SUBb: - case t_CMPb: - case t_INCb: - case t_DECb: - case t_TESTb: - case t_SHLb: - case t_SHRb: - case t_SARb: - case t_NEGb: - return (lf_resb==0); - case t_ADDw: - case t_ORw: - case t_ADCw: - case t_SBBw: - case t_ANDw: - case t_XORw: - case t_SUBw: - case t_CMPw: - case t_INCw: - case t_DECw: - case t_TESTw: - case t_SHLw: - case t_SHRw: - case t_SARw: - case t_DSHLw: - case t_DSHRw: - case t_NEGw: - return (lf_resw==0); - case t_ADDd: - case t_ORd: - case t_ADCd: - case t_SBBd: - case t_ANDd: - case t_XORd: - case t_SUBd: - case t_CMPd: - case t_INCd: - case t_DECd: - case t_TESTd: - case t_SHLd: - case t_SHRd: - case t_SARd: - case t_DSHLd: - case t_DSHRd: - case t_NEGd: - return (lf_resd==0); - case t_DIV: - case t_MUL: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",lflags.type); - } - return false; -} -/* SF Sign Flag -- Set equal to high-order bit of result (0 is - positive, 1 if negative). -*/ -Bit32u get_SF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - return GETFLAG(SF); - case t_ADDb: - case t_ORb: - case t_ADCb: - case t_SBBb: - case t_ANDb: - case t_XORb: - case t_SUBb: - case t_CMPb: - case t_INCb: - case t_DECb: - case t_TESTb: - case t_SHLb: - case t_SHRb: - case t_SARb: - case t_NEGb: - return (lf_resb&0x80); - case t_ADDw: - case t_ORw: - case t_ADCw: - case t_SBBw: - case t_ANDw: - case t_XORw: - case t_SUBw: - case t_CMPw: - case t_INCw: - case t_DECw: - case t_TESTw: - case t_SHLw: - case t_SHRw: - case t_SARw: - case t_DSHLw: - case t_DSHRw: - case t_NEGw: - return (lf_resw&0x8000); - case t_ADDd: - case t_ORd: - case t_ADCd: - case t_SBBd: - case t_ANDd: - case t_XORd: - case t_SUBd: - case t_CMPd: - case t_INCd: - case t_DECd: - case t_TESTd: - case t_SHLd: - case t_SHRd: - case t_SARd: - case t_DSHLd: - case t_DSHRd: - case t_NEGd: - return (lf_resd&0x80000000); - case t_DIV: - case t_MUL: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",lflags.type); - } - return false; - -} -Bit32u get_OF(void) { - Bitu type=lflags.type; - switch (type) { - case t_UNKNOWN: - case t_MUL: - return GETFLAG(OF); - case t_ADDb: - case t_ADCb: - return ((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var2b)) & 0x80; - case t_ADDw: - case t_ADCw: - return ((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var2w)) & 0x8000; - case t_ADDd: - case t_ADCd: - return ((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var2d)) & 0x80000000; - case t_SBBb: - case t_SUBb: - case t_CMPb: - return ((lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb)) & 0x80; - case t_SBBw: - case t_SUBw: - case t_CMPw: - return ((lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw)) & 0x8000; - case t_SBBd: - case t_SUBd: - case t_CMPd: - return ((lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd)) & 0x80000000; - case t_INCb: - return (lf_resb == 0x80); - case t_INCw: - return (lf_resw == 0x8000); - case t_INCd: - return (lf_resd == 0x80000000); - case t_DECb: - return (lf_resb == 0x7f); - case t_DECw: - return (lf_resw == 0x7fff); - case t_DECd: - return (lf_resd == 0x7fffffff); - case t_NEGb: - return (lf_var1b == 0x80); - case t_NEGw: - return (lf_var1w == 0x8000); - case t_NEGd: - return (lf_var1d == 0x80000000); - case t_SHLb: - return (lf_resb ^ lf_var1b) & 0x80; - case t_SHLw: - case t_DSHRw: - case t_DSHLw: - return (lf_resw ^ lf_var1w) & 0x8000; - case t_SHLd: - case t_DSHRd: - case t_DSHLd: - return (lf_resd ^ lf_var1d) & 0x80000000; - case t_SHRb: - if ((lf_var2b&0x1f)==1) return (lf_var1b > 0x80); - else return false; - case t_SHRw: - if ((lf_var2b&0x1f)==1) return (lf_var1w > 0x8000); - else return false; - case t_SHRd: - if ((lf_var2b&0x1f)==1) return (lf_var1d > 0x80000000); - else return false; - case t_ORb: - case t_ORw: - case t_ORd: - case t_ANDb: - case t_ANDw: - case t_ANDd: - case t_XORb: - case t_XORw: - case t_XORd: - case t_TESTb: - case t_TESTw: - case t_TESTd: - case t_SARb: - case t_SARw: - case t_SARd: - return false; /* Return false */ - case t_DIV: - return false; /* Unkown */ - default: - LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",lflags.type); - } - return false; -} - -Bit16u parity_lookup[256] = { - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, - FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF - }; - -Bit32u get_PF(void) { - switch (lflags.type) { - case t_UNKNOWN: - return GETFLAG(PF); - default: - return (parity_lookup[lf_resb]); - }; - return 0; -} - - -#if 0 - -Bitu FillFlags(void) { -// if (lflags.type==t_UNKNOWN) return reg_flags; - Bitu new_word=(reg_flags & ~FLAG_MASK); - if (get_CF()) new_word|=FLAG_CF; - if (get_PF()) new_word|=FLAG_PF; - if (get_AF()) new_word|=FLAG_AF; - if (get_ZF()) new_word|=FLAG_ZF; - if (get_SF()) new_word|=FLAG_SF; - if (get_OF()) new_word|=FLAG_OF; - reg_flags=new_word; - lflags.type=t_UNKNOWN; - return reg_flags; -} - -#else - -#define DOFLAG_PF reg_flags=(reg_flags & ~FLAG_PF) | parity_lookup[lf_resb]; - -#define DOFLAG_AF reg_flags=(reg_flags & ~FLAG_AF) | (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10); - -#define DOFLAG_ZFb SETFLAGBIT(ZF,lf_resb==0); -#define DOFLAG_ZFw SETFLAGBIT(ZF,lf_resw==0); -#define DOFLAG_ZFd SETFLAGBIT(ZF,lf_resd==0); - -#define DOFLAG_SFb reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resb & 0x80) >> 0); -#define DOFLAG_SFw reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resw & 0x8000) >> 8); -#define DOFLAG_SFd reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resd & 0x80000000) >> 24); - -#define SETCF(NEWBIT) reg_flags=(reg_flags & ~FLAG_CF)|(NEWBIT); - -#define SET_FLAG SETFLAGBIT - -Bitu FillFlags(void) { - switch (lflags.type) { - case t_UNKNOWN: - break; - case t_ADDb: - SET_FLAG(CF,(lf_resb8) SET_FLAG(CF,false); - else SET_FLAG(CF,(lf_var1b >> (8-lf_var2b)) & 1); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_resb ^ lf_var1b) & 0x80); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHLw: - if (lf_var2b>16) SET_FLAG(CF,false); - else SET_FLAG(CF,(lf_var1w >> (16-lf_var2b)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHLd: - SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHLw: - SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - DOFLAG_PF; - break; - case t_DSHLd: - SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - DOFLAG_PF; - break; - - - case t_SHRb: - SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); - DOFLAG_ZFb; - DOFLAG_SFb; - if ((lf_var2b&0x1f)==1) SET_FLAG(OF,(lf_var1b >= 0x80)); - else SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHRw: - SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - if ((lf_var2w&0x1f)==1) SET_FLAG(OF,(lf_var1w >= 0x8000)); - else SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHRd: - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - if ((lf_var2d&0x1f)==1) SET_FLAG(OF,(lf_var1d >= 0x80000000)); - else SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); - DOFLAG_PF; - break; - case t_DSHRd: - SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); - DOFLAG_PF; - break; - - - case t_SARb: - SET_FLAG(CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SARw: - SET_FLAG(CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SARd: - SET_FLAG(CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,false); - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - case t_INCb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_resb == 0x80)); - DOFLAG_PF; - break; - case t_INCw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw == 0x8000)); - DOFLAG_PF; - break; - case t_INCd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd == 0x80000000)); - DOFLAG_PF; - break; - - case t_DECb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_resb == 0x7f)); - DOFLAG_PF; - break; - case t_DECw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_resw == 0x7fff)); - DOFLAG_PF; - break; - case t_DECd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_resd == 0x7fffffff)); - DOFLAG_PF; - break; - - case t_NEGb: - SET_FLAG(CF,(lf_var1b!=0)); - SET_FLAG(AF,(lf_resb & 0x0f) != 0); - DOFLAG_ZFb; - DOFLAG_SFb; - SET_FLAG(OF,(lf_var1b == 0x80)); - DOFLAG_PF; - break; - case t_NEGw: - SET_FLAG(CF,(lf_var1w!=0)); - SET_FLAG(AF,(lf_resw & 0x0f) != 0); - DOFLAG_ZFw; - DOFLAG_SFw; - SET_FLAG(OF,(lf_var1w == 0x8000)); - DOFLAG_PF; - break; - case t_NEGd: - SET_FLAG(CF,(lf_var1d!=0)); - SET_FLAG(AF,(lf_resd & 0x0f) != 0); - DOFLAG_ZFd; - DOFLAG_SFd; - SET_FLAG(OF,(lf_var1d == 0x80000000)); - DOFLAG_PF; - break; - - - case t_DIV: - case t_MUL: - break; - - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); - return 0; - } - lflags.type=t_UNKNOWN; - return reg_flags; -} - -void FillFlagsNoCFOF(void) { - switch (lflags.type) { - case t_UNKNOWN: - return; - case t_ADDb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_ADDw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_ADDd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - case t_ADCb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_ADCw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_ADCd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SBBb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_SBBw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_SBBd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SUBb: - case t_CMPb: - DOFLAG_AF; - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_SUBw: - case t_CMPw: - DOFLAG_AF; - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_SUBd: - case t_CMPd: - DOFLAG_AF; - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_ORb: - SET_FLAG(AF,false); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_ORw: - SET_FLAG(AF,false); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_ORd: - SET_FLAG(AF,false); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_TESTb: - case t_ANDb: - SET_FLAG(AF,false); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_TESTw: - case t_ANDw: - SET_FLAG(AF,false); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_TESTd: - case t_ANDd: - SET_FLAG(AF,false); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_XORb: - SET_FLAG(AF,false); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_XORw: - SET_FLAG(AF,false); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_XORd: - SET_FLAG(AF,false); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SHLb: - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHLw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHLd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHLw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_DSHLd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SHRb: - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SHRw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SHRd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - - case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_DSHRd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_SARb: - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2b&0x1f)); - break; - case t_SARw: - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2w&0x1f)); - break; - case t_SARd: - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - SET_FLAG(AF,(lf_var2d&0x1f)); - break; - - case t_INCb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_INCw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_INCd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - case t_DECb: - SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_DECw: - SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_DECd: - SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - case t_NEGb: - SET_FLAG(AF,(lf_resb & 0x0f) != 0); - DOFLAG_ZFb; - DOFLAG_SFb; - DOFLAG_PF; - break; - case t_NEGw: - SET_FLAG(AF,(lf_resw & 0x0f) != 0); - DOFLAG_ZFw; - DOFLAG_SFw; - DOFLAG_PF; - break; - case t_NEGd: - SET_FLAG(AF,(lf_resd & 0x0f) != 0); - DOFLAG_ZFd; - DOFLAG_SFd; - DOFLAG_PF; - break; - - - case t_DIV: - case t_MUL: - break; - - default: - LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",lflags.type); - break; - } - lflags.type=t_UNKNOWN; -} - -void DestroyConditionFlags(void) { - lflags.type=t_UNKNOWN; -} - -#endif -}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/Makefile.am b/source/src/vm/libcpu_newdev/dosbox-i386/fpu/Makefile.am deleted file mode 100644 index 541d5a466..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/include - -noinst_LIBRARIES = libfpu.a -libfpu_a_SOURCES = fpu.cpp fpu_instructions.h \ - fpu_instructions_x86.h diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/Makefile.in b/source/src/vm/libcpu_newdev/dosbox-i386/fpu/Makefile.in deleted file mode 100644 index e9bdeeca6..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/Makefile.in +++ /dev/null @@ -1,573 +0,0 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = src/fpu -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LIBRARIES = $(noinst_LIBRARIES) -AR = ar -ARFLAGS = cru -AM_V_AR = $(am__v_AR_@AM_V@) -am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) -am__v_AR_0 = @echo " AR " $@; -am__v_AR_1 = -libfpu_a_AR = $(AR) $(ARFLAGS) -libfpu_a_LIBADD = -am_libfpu_a_OBJECTS = fpu.$(OBJEXT) -libfpu_a_OBJECTS = $(am_libfpu_a_OBJECTS) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/fpu.Po -am__mv = mv -f -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -AM_V_CXX = $(am__v_CXX_@AM_V@) -am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) -am__v_CXX_0 = @echo " CXX " $@; -am__v_CXX_1 = -CXXLD = $(CXX) -CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ - -o $@ -AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) -am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) -am__v_CXXLD_0 = @echo " CXXLD " $@; -am__v_CXXLD_1 = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libfpu_a_SOURCES) -DIST_SOURCES = $(libfpu_a_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -WINDRES = @WINDRES@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AM_CPPFLAGS = -I$(top_srcdir)/include -noinst_LIBRARIES = libfpu.a -libfpu_a_SOURCES = fpu.cpp fpu_instructions.h \ - fpu_instructions_x86.h - -all: all-am - -.SUFFIXES: -.SUFFIXES: .cpp .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/fpu/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/fpu/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) - -libfpu.a: $(libfpu_a_OBJECTS) $(libfpu_a_DEPENDENCIES) $(EXTRA_libfpu_a_DEPENDENCIES) - $(AM_V_at)-rm -f libfpu.a - $(AM_V_AR)$(libfpu_a_AR) libfpu.a $(libfpu_a_OBJECTS) $(libfpu_a_LIBADD) - $(AM_V_at)$(RANLIB) libfpu.a - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fpu.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.cpp.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< - -.cpp.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/fpu.Po - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/fpu.Po - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-noinstLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu.cpp deleted file mode 100644 index 1e561143e..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu.cpp +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include "dosbox.h" -#if C_FPU - -#include -#include -#include "cross.h" -#include "mem.h" -#include "fpu.h" -#include "cpu.h" - -FPU_rec fpu; - -void FPU_FLDCW(PhysPt addr){ - Bit16u temp = mem_readw(addr); - FPU_SetCW(temp); -} - -Bit16u FPU_GetTag(void){ - Bit16u tag=0; - for(Bitu i=0;i<8;i++) - tag |= ( (fpu.tags[i]&3) <<(2*i)); - return tag; -} - -#if C_FPU_X86 -#include "fpu_instructions_x86.h" -#else -#include "fpu_instructions.h" -#endif - -/* WATCHIT : ALWAYS UPDATE REGISTERS BEFORE AND AFTER USING THEM - STATUS WORD => FPU_SET_TOP(TOP) BEFORE a read - TOP=FPU_GET_TOP() after a write; - */ - -static void EATREE(Bitu _rm){ - Bitu group=(_rm >> 3) & 7; - switch(group){ - case 0x00: /* FADD */ - FPU_FADD_EA(TOP); - break; - case 0x01: /* FMUL */ - FPU_FMUL_EA(TOP); - break; - case 0x02: /* FCOM */ - FPU_FCOM_EA(TOP); - break; - case 0x03: /* FCOMP */ - FPU_FCOM_EA(TOP); - FPU_FPOP(); - break; - case 0x04: /* FSUB */ - FPU_FSUB_EA(TOP); - break; - case 0x05: /* FSUBR */ - FPU_FSUBR_EA(TOP); - break; - case 0x06: /* FDIV */ - FPU_FDIV_EA(TOP); - break; - case 0x07: /* FDIVR */ - FPU_FDIVR_EA(TOP); - break; - default: - break; - } -} - -void FPU_ESC0_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 32 BITS REALS */ - FPU_FLD_F32_EA(addr); - EATREE(rm); -} - -void FPU_ESC0_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group){ - case 0x00: /* FADD ST,STi */ - FPU_FADD(TOP,STV(sub)); - break; - case 0x01: /* FMUL ST,STi */ - FPU_FMUL(TOP,STV(sub)); - break; - case 0x02: /* FCOM STi */ - FPU_FCOM(TOP,STV(sub)); - break; - case 0x03: /* FCOMP STi */ - FPU_FCOM(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: /* FSUB ST,STi */ - FPU_FSUB(TOP,STV(sub)); - break; - case 0x05: /* FSUBR ST,STi */ - FPU_FSUBR(TOP,STV(sub)); - break; - case 0x06: /* FDIV ST,STi */ - FPU_FDIV(TOP,STV(sub)); - break; - case 0x07: /* FDIVR ST,STi */ - FPU_FDIVR(TOP,STV(sub)); - break; - default: - break; - } -} - -void FPU_ESC1_EA(Bitu rm,PhysPt addr) { -// floats - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FLD float*/ - FPU_PREP_PUSH(); - FPU_FLD_F32(addr,TOP); - break; - case 0x01: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST float*/ - FPU_FST_F32(addr); - break; - case 0x03: /* FSTP float*/ - FPU_FST_F32(addr); - FPU_FPOP(); - break; - case 0x04: /* FLDENV */ - FPU_FLDENV(addr); - break; - case 0x05: /* FLDCW */ - FPU_FLDCW(addr); - break; - case 0x06: /* FSTENV */ - FPU_FSTENV(addr); - break; - case 0x07: /* FNSTCW*/ - mem_writew(addr,fpu.cw); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub); - break; - } -} - -void FPU_ESC1_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group){ - case 0x00: /* FLD STi */ - { - Bitu reg_from=STV(sub); - FPU_PREP_PUSH(); - FPU_FST(reg_from, TOP); - break; - } - case 0x01: /* FXCH STi */ - FPU_FXCH(TOP,STV(sub)); - break; - case 0x02: /* FNOP */ - FPU_FNOP(); - break; - case 0x03: /* FSTP STi */ - FPU_FST(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: - switch(sub){ - case 0x00: /* FCHS */ - FPU_FCHS(); - break; - case 0x01: /* FABS */ - FPU_FABS(); - break; - case 0x02: /* UNKNOWN */ - case 0x03: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - case 0x04: /* FTST */ - FPU_FTST(); - break; - case 0x05: /* FXAM */ - FPU_FXAM(); - break; - case 0x06: /* FTSTP (cyrix)*/ - case 0x07: /* UNKNOWN */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x05: - switch(sub){ - case 0x00: /* FLD1 */ - FPU_FLD1(); - break; - case 0x01: /* FLDL2T */ - FPU_FLDL2T(); - break; - case 0x02: /* FLDL2E */ - FPU_FLDL2E(); - break; - case 0x03: /* FLDPI */ - FPU_FLDPI(); - break; - case 0x04: /* FLDLG2 */ - FPU_FLDLG2(); - break; - case 0x05: /* FLDLN2 */ - FPU_FLDLN2(); - break; - case 0x06: /* FLDZ*/ - FPU_FLDZ(); - break; - case 0x07: /* ILLEGAL */ - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x06: - switch(sub){ - case 0x00: /* F2XM1 */ - FPU_F2XM1(); - break; - case 0x01: /* FYL2X */ - FPU_FYL2X(); - break; - case 0x02: /* FPTAN */ - FPU_FPTAN(); - break; - case 0x03: /* FPATAN */ - FPU_FPATAN(); - break; - case 0x04: /* FXTRACT */ - FPU_FXTRACT(); - break; - case 0x05: /* FPREM1 */ - FPU_FPREM1(); - break; - case 0x06: /* FDECSTP */ - TOP = (TOP - 1) & 7; - break; - case 0x07: /* FINCSTP */ - TOP = (TOP + 1) & 7; - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - case 0x07: - switch(sub){ - case 0x00: /* FPREM */ - FPU_FPREM(); - break; - case 0x01: /* FYL2XP1 */ - FPU_FYL2XP1(); - break; - case 0x02: /* FSQRT */ - FPU_FSQRT(); - break; - case 0x03: /* FSINCOS */ - FPU_FSINCOS(); - break; - case 0x04: /* FRNDINT */ - FPU_FRNDINT(); - break; - case 0x05: /* FSCALE */ - FPU_FSCALE(); - break; - case 0x06: /* FSIN */ - FPU_FSIN(); - break; - case 0x07: /* FCOS */ - FPU_FCOS(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub); - } -} - - -void FPU_ESC2_EA(Bitu rm,PhysPt addr) { - /* 32 bits integer operants */ - FPU_FLD_I32_EA(addr); - EATREE(rm); -} - -void FPU_ESC2_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x05: - switch(sub){ - case 0x01: /* FUCOMPP */ - FPU_FUCOM(TOP,STV(1)); - FPU_FPOP(); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub); - break; - } -} - - -void FPU_ESC3_EA(Bitu rm,PhysPt addr) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FILD */ - FPU_PREP_PUSH(); - FPU_FLD_I32(addr,TOP); - break; - case 0x01: /* FISTTP */ - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST */ - FPU_FST_I32(addr); - break; - case 0x03: /* FISTP */ - FPU_FST_I32(addr); - FPU_FPOP(); - break; - case 0x05: /* FLD 80 Bits Real */ - FPU_PREP_PUSH(); - FPU_FLD_F80(addr); - break; - case 0x07: /* FSTP 80 Bits Real */ - FPU_FST_F80(addr); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub); - } -} - -void FPU_ESC3_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group) { - case 0x04: - switch (sub) { - case 0x00: //FNENI - case 0x01: //FNDIS - LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub); - break; - case 0x02: //FNCLEX FCLEX - FPU_FCLEX(); - break; - case 0x03: //FNINIT FINIT - FPU_FINIT(); - break; - case 0x04: //FNSETPM - case 0x05: //FRSTPM -// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done"); - FPU_FNOP(); - break; - default: - E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub); - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub); - break; - } - return; -} - - -void FPU_ESC4_EA(Bitu rm,PhysPt addr) { - /* REGULAR TREE WITH 64 BITS REALS */ - FPU_FLD_F64_EA(addr); - EATREE(rm); -} - -void FPU_ESC4_Normal(Bitu rm) { - /* LOOKS LIKE number 6 without popping */ - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FADD STi,ST*/ - FPU_FADD(STV(sub),TOP); - break; - case 0x01: /* FMUL STi,ST*/ - FPU_FMUL(STV(sub),TOP); - break; - case 0x02: /* FCOM*/ - FPU_FCOM(TOP,STV(sub)); - break; - case 0x03: /* FCOMP*/ - FPU_FCOM(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: /* FSUBR STi,ST*/ - FPU_FSUBR(STV(sub),TOP); - break; - case 0x05: /* FSUB STi,ST*/ - FPU_FSUB(STV(sub),TOP); - break; - case 0x06: /* FDIVR STi,ST*/ - FPU_FDIVR(STV(sub),TOP); - break; - case 0x07: /* FDIV STi,ST*/ - FPU_FDIV(STV(sub),TOP); - break; - default: - break; - } -} - -void FPU_ESC5_EA(Bitu rm,PhysPt addr) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FLD double real*/ - FPU_PREP_PUSH(); - FPU_FLD_F64(addr,TOP); - break; - case 0x01: /* FISTTP longint*/ - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FST double real*/ - FPU_FST_F64(addr); - break; - case 0x03: /* FSTP double real*/ - FPU_FST_F64(addr); - FPU_FPOP(); - break; - case 0x04: /* FRSTOR */ - FPU_FRSTOR(addr); - break; - case 0x06: /* FSAVE */ - FPU_FSAVE(addr); - break; - case 0x07: /*FNSTSW NG DISAGREES ON THIS*/ - FPU_SET_TOP(TOP); - mem_writew(addr,fpu.sw); - //seems to break all dos4gw games :) - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub); - } -} - -void FPU_ESC5_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FFREE STi */ - fpu.tags[STV(sub)]=TAG_Empty; - break; - case 0x01: /* FXCH STi*/ - FPU_FXCH(TOP,STV(sub)); - break; - case 0x02: /* FST STi */ - FPU_FST(TOP,STV(sub)); - break; - case 0x03: /* FSTP STi*/ - FPU_FST(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: /* FUCOM STi */ - FPU_FUCOM(TOP,STV(sub)); - break; - case 0x05: /*FUCOMP STi */ - FPU_FUCOM(TOP,STV(sub)); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub); - break; - } -} - -void FPU_ESC6_EA(Bitu rm,PhysPt addr) { - /* 16 bit (word integer) operants */ - FPU_FLD_I16_EA(addr); - EATREE(rm); -} - -void FPU_ESC6_Normal(Bitu rm) { - /* all P variants working only on registers */ - /* get top before switch and pop afterwards */ - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /*FADDP STi,ST*/ - FPU_FADD(STV(sub),TOP); - break; - case 0x01: /* FMULP STi,ST*/ - FPU_FMUL(STV(sub),TOP); - break; - case 0x02: /* FCOMP5*/ - FPU_FCOM(TOP,STV(sub)); - break; /* TODO IS THIS ALLRIGHT ????????? */ - case 0x03: /*FCOMPP*/ - if(sub != 1) { - LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub); - return; - } - FPU_FCOM(TOP,STV(1)); - FPU_FPOP(); /* extra pop at the bottom*/ - break; - case 0x04: /* FSUBRP STi,ST*/ - FPU_FSUBR(STV(sub),TOP); - break; - case 0x05: /* FSUBP STi,ST*/ - FPU_FSUB(STV(sub),TOP); - break; - case 0x06: /* FDIVRP STi,ST*/ - FPU_FDIVR(STV(sub),TOP); - break; - case 0x07: /* FDIVP STi,ST*/ - FPU_FDIV(STV(sub),TOP); - break; - default: - break; - } - FPU_FPOP(); -} - - -void FPU_ESC7_EA(Bitu rm,PhysPt addr) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch(group){ - case 0x00: /* FILD Bit16s */ - FPU_PREP_PUSH(); - FPU_FLD_I16(addr,TOP); - break; - case 0x01: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - case 0x02: /* FIST Bit16s */ - FPU_FST_I16(addr); - break; - case 0x03: /* FISTP Bit16s */ - FPU_FST_I16(addr); - FPU_FPOP(); - break; - case 0x04: /* FBLD packed BCD */ - FPU_PREP_PUSH(); - FPU_FBLD(addr,TOP); - break; - case 0x05: /* FILD Bit64s */ - FPU_PREP_PUSH(); - FPU_FLD_I64(addr,TOP); - break; - case 0x06: /* FBSTP packed BCD */ - FPU_FBST(addr); - FPU_FPOP(); - break; - case 0x07: /* FISTP Bit64s */ - FPU_FST_I64(addr); - FPU_FPOP(); - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub); - break; - } -} - -void FPU_ESC7_Normal(Bitu rm) { - Bitu group=(rm >> 3) & 7; - Bitu sub=(rm & 7); - switch (group){ - case 0x00: /* FFREEP STi*/ - fpu.tags[STV(sub)]=TAG_Empty; - FPU_FPOP(); - break; - case 0x01: /* FXCH STi*/ - FPU_FXCH(TOP,STV(sub)); - break; - case 0x02: /* FSTP STi*/ - case 0x03: /* FSTP STi*/ - FPU_FST(TOP,STV(sub)); - FPU_FPOP(); - break; - case 0x04: - switch(sub){ - case 0x00: /* FNSTSW AX*/ - FPU_SET_TOP(TOP); - reg_ax = fpu.sw; - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } - break; - default: - LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub); - break; - } -} - - -void FPU_Init(Section*) { - FPU_FINIT(); -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu_instructions.h b/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu_instructions.h deleted file mode 100644 index 54d0143cf..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu_instructions.h +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -static void FPU_FINIT(void) { - FPU_SetCW(0x37F); - fpu.sw = 0; - TOP=FPU_GET_TOP(); - fpu.tags[0] = TAG_Empty; - fpu.tags[1] = TAG_Empty; - fpu.tags[2] = TAG_Empty; - fpu.tags[3] = TAG_Empty; - fpu.tags[4] = TAG_Empty; - fpu.tags[5] = TAG_Empty; - fpu.tags[6] = TAG_Empty; - fpu.tags[7] = TAG_Empty; - fpu.tags[8] = TAG_Valid; // is only used by us -} - -static void FPU_FCLEX(void){ - fpu.sw &= 0x7f00; //should clear exceptions -} - -static void FPU_FNOP(void){ - return; -} - -static void FPU_PREP_PUSH(void){ - TOP = (TOP - 1) &7; - if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); - fpu.tags[TOP] = TAG_Valid; -} - -static void FPU_PUSH(double in){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = in; -// LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); - return; -} - - -static void FPU_FPOP(void){ - if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow"); - fpu.tags[TOP]=TAG_Empty; - //maybe set zero in it as well - TOP = ((TOP+1)&7); -// LOG(LOG_FPU,LOG_ERROR)("popped from %d %g off the stack",top,fpu.regs[top].d); - return; -} - -static double FROUND(double in){ - switch(fpu.round){ - case ROUND_Nearest: - if (in-floor(in)>0.5) return (floor(in)+1); - else if (in-floor(in)<0.5) return (floor(in)); - else return (((static_cast(floor(in)))&1)!=0)?(floor(in)+1):(floor(in)); - break; - case ROUND_Down: - return (floor(in)); - break; - case ROUND_Up: - return (ceil(in)); - break; - case ROUND_Chop: - return in; //the cast afterwards will do it right maybe cast here - break; - default: - return in; - break; - } -} - -#define BIAS80 16383 -#define BIAS64 1023 - -static Real64 FPU_FLD80(PhysPt addr) { - struct { - Bit16s begin; - FPU_Reg eind; - } test; - test.eind.l.lower = mem_readd(addr); - test.eind.l.upper = mem_readd(addr+4); - test.begin = mem_readw(addr+8); - - Bit64s exp64 = (((test.begin&0x7fff) - BIAS80)); - Bit64s blah = ((exp64 >0)?exp64:-exp64)&0x3ff; - Bit64s exp64final = ((exp64 >0)?blah:-blah) +BIAS64; - - Bit64s mant64 = (test.eind.ll >> 11) & LONGTYPE(0xfffffffffffff); - Bit64s sign = (test.begin&0x8000)?1:0; - FPU_Reg result; - result.ll = (sign <<63)|(exp64final << 52)| mant64; - - if(test.eind.l.lower == 0 && test.eind.l.upper == 0x80000000 && (test.begin&0x7fff) == 0x7fff) { - //Detect INF and -INF (score 3.11 when drawing a slur.) - result.d = sign?-HUGE_VAL:HUGE_VAL; - } - return result.d; - - //mant64= test.mant80/2***64 * 2 **53 -} - -static void FPU_ST80(PhysPt addr,Bitu reg) { - struct { - Bit16s begin; - FPU_Reg eind; - } test; - Bit64s sign80 = (fpu.regs[reg].ll&LONGTYPE(0x8000000000000000))?1:0; - Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000); - Bit64s exp80final = (exp80>>52); - Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff); - Bit64s mant80final = (mant80 << 11); - if(fpu.regs[reg].d != 0){ //Zero is a special case - // Elvira wants the 8 and tcalc doesn't - mant80final |= LONGTYPE(0x8000000000000000); - //Ca-cyber doesn't like this when result is zero. - exp80final += (BIAS80 - BIAS64); - } - test.begin = (static_cast(sign80)<<15)| static_cast(exp80final); - test.eind.ll = mant80final; - mem_writed(addr,test.eind.l.lower); - mem_writed(addr+4,test.eind.l.upper); - mem_writew(addr+8,test.begin); -} - - -static void FPU_FLD_F32(PhysPt addr,Bitu store_to) { - union { - float f; - Bit32u l; - } blah; - blah.l = mem_readd(addr); - fpu.regs[store_to].d = static_cast(blah.f); -} - -static void FPU_FLD_F64(PhysPt addr,Bitu store_to) { - fpu.regs[store_to].l.lower = mem_readd(addr); - fpu.regs[store_to].l.upper = mem_readd(addr+4); -} - -static void FPU_FLD_F80(PhysPt addr) { - fpu.regs[TOP].d = FPU_FLD80(addr); -} - -static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { - Bit16s blah = mem_readw(addr); - fpu.regs[store_to].d = static_cast(blah); -} - -static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { - Bit32s blah = mem_readd(addr); - fpu.regs[store_to].d = static_cast(blah); -} - -static void FPU_FLD_I64(PhysPt addr,Bitu store_to) { - FPU_Reg blah; - blah.l.lower = mem_readd(addr); - blah.l.upper = mem_readd(addr+4); - fpu.regs[store_to].d = static_cast(blah.ll); -} - -static void FPU_FBLD(PhysPt addr,Bitu store_to) { - Bit64u val = 0; - Bitu in = 0; - Bit64u base = 1; - for(Bitu i = 0;i < 9;i++){ - in = mem_readb(addr + i); - val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 - base *= 10; - val += ((( in>>4)&0xf) * base); - base *= 10; - } - - //last number, only now convert to float in order to get - //the best signification - Real64 temp = static_cast(val); - in = mem_readb(addr + 9); - temp += ( (in&0xf) * base ); - if(in&0x80) temp *= -1.0; - fpu.regs[store_to].d = temp; -} - - -static INLINE void FPU_FLD_F32_EA(PhysPt addr) { - FPU_FLD_F32(addr,8); -} -static INLINE void FPU_FLD_F64_EA(PhysPt addr) { - FPU_FLD_F64(addr,8); -} -static INLINE void FPU_FLD_I32_EA(PhysPt addr) { - FPU_FLD_I32(addr,8); -} -static INLINE void FPU_FLD_I16_EA(PhysPt addr) { - FPU_FLD_I16(addr,8); -} - - -static void FPU_FST_F32(PhysPt addr) { - union { - float f; - Bit32u l; - } blah; - //should depend on rounding method - blah.f = static_cast(fpu.regs[TOP].d); - mem_writed(addr,blah.l); -} - -static void FPU_FST_F64(PhysPt addr) { - mem_writed(addr,fpu.regs[TOP].l.lower); - mem_writed(addr+4,fpu.regs[TOP].l.upper); -} - -static void FPU_FST_F80(PhysPt addr) { - FPU_ST80(addr,TOP); -} - -static void FPU_FST_I16(PhysPt addr) { - mem_writew(addr,static_cast(FROUND(fpu.regs[TOP].d))); -} - -static void FPU_FST_I32(PhysPt addr) { - mem_writed(addr,static_cast(FROUND(fpu.regs[TOP].d))); -} - -static void FPU_FST_I64(PhysPt addr) { - FPU_Reg blah; - blah.ll = static_cast(FROUND(fpu.regs[TOP].d)); - mem_writed(addr,blah.l.lower); - mem_writed(addr+4,blah.l.upper); -} - -static void FPU_FBST(PhysPt addr) { - FPU_Reg val = fpu.regs[TOP]; - bool sign = false; - if(fpu.regs[TOP].ll & LONGTYPE(0x8000000000000000)) { //sign - sign=true; - val.d=-val.d; - } - //numbers from back to front - Real64 temp=val.d; - Bitu p; - for(Bitu i=0;i<9;i++){ - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p = static_cast(val.d - 10.0*temp); - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p |= (static_cast(val.d - 10.0*temp)<<4); - - mem_writeb(addr+i,p); - } - val.d=temp; - temp = static_cast(static_cast(floor(val.d/10.0))); - p = static_cast(val.d - 10.0*temp); - if(sign) - p|=0x80; - mem_writeb(addr+9,p); -} - -static void FPU_FADD(Bitu op1, Bitu op2){ - fpu.regs[op1].d+=fpu.regs[op2].d; - //flags and such :) - return; -} - -static void FPU_FSIN(void){ - fpu.regs[TOP].d = sin(fpu.regs[TOP].d); - FPU_SET_C2(0); - //flags and such :) - return; -} - -static void FPU_FSINCOS(void){ - Real64 temp = fpu.regs[TOP].d; - fpu.regs[TOP].d = sin(temp); - FPU_PUSH(cos(temp)); - FPU_SET_C2(0); - //flags and such :) - return; -} - -static void FPU_FCOS(void){ - fpu.regs[TOP].d = cos(fpu.regs[TOP].d); - FPU_SET_C2(0); - //flags and such :) - return; -} - -static void FPU_FSQRT(void){ - fpu.regs[TOP].d = sqrt(fpu.regs[TOP].d); - //flags and such :) - return; -} -static void FPU_FPATAN(void){ - fpu.regs[STV(1)].d = atan2(fpu.regs[STV(1)].d,fpu.regs[TOP].d); - FPU_FPOP(); - //flags and such :) - return; -} -static void FPU_FPTAN(void){ - fpu.regs[TOP].d = tan(fpu.regs[TOP].d); - FPU_PUSH(1.0); - FPU_SET_C2(0); - //flags and such :) - return; -} -static void FPU_FDIV(Bitu st, Bitu other){ - fpu.regs[st].d= fpu.regs[st].d/fpu.regs[other].d; - //flags and such :) - return; -} - -static void FPU_FDIVR(Bitu st, Bitu other){ - fpu.regs[st].d= fpu.regs[other].d/fpu.regs[st].d; - // flags and such :) - return; -} - -static void FPU_FMUL(Bitu st, Bitu other){ - fpu.regs[st].d*=fpu.regs[other].d; - //flags and such :) - return; -} - -static void FPU_FSUB(Bitu st, Bitu other){ - fpu.regs[st].d = fpu.regs[st].d - fpu.regs[other].d; - //flags and such :) - return; -} - -static void FPU_FSUBR(Bitu st, Bitu other){ - fpu.regs[st].d= fpu.regs[other].d - fpu.regs[st].d; - //flags and such :) - return; -} - -static void FPU_FXCH(Bitu st, Bitu other){ - FPU_Tag tag = fpu.tags[other]; - FPU_Reg reg = fpu.regs[other]; - fpu.tags[other] = fpu.tags[st]; - fpu.regs[other] = fpu.regs[st]; - fpu.tags[st] = tag; - fpu.regs[st] = reg; -} - -static void FPU_FST(Bitu st, Bitu other){ - fpu.tags[other] = fpu.tags[st]; - fpu.regs[other] = fpu.regs[st]; -} - - -static void FPU_FCOM(Bitu st, Bitu other){ - if(((fpu.tags[st] != TAG_Valid) && (fpu.tags[st] != TAG_Zero)) || - ((fpu.tags[other] != TAG_Valid) && (fpu.tags[other] != TAG_Zero))){ - FPU_SET_C3(1);FPU_SET_C2(1);FPU_SET_C0(1);return; - } - if(fpu.regs[st].d == fpu.regs[other].d){ - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0);return; - } - if(fpu.regs[st].d < fpu.regs[other].d){ - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(1);return; - } - // st > other - FPU_SET_C3(0);FPU_SET_C2(0);FPU_SET_C0(0);return; -} - -static void FPU_FUCOM(Bitu st, Bitu other){ - //does atm the same as fcom - FPU_FCOM(st,other); -} - -static void FPU_FRNDINT(void){ - Bit64s temp= static_cast(FROUND(fpu.regs[TOP].d)); - fpu.regs[TOP].d=static_cast(temp); -} - -static void FPU_FPREM(void){ - Real64 valtop = fpu.regs[TOP].d; - Real64 valdiv = fpu.regs[STV(1)].d; - Bit64s ressaved = static_cast( (valtop/valdiv) ); -// Some backups -// Real64 res=valtop - ressaved*valdiv; -// res= fmod(valtop,valdiv); - fpu.regs[TOP].d = valtop - ressaved*valdiv; - FPU_SET_C0(static_cast(ressaved&4)); - FPU_SET_C3(static_cast(ressaved&2)); - FPU_SET_C1(static_cast(ressaved&1)); - FPU_SET_C2(0); -} - -static void FPU_FPREM1(void){ - Real64 valtop = fpu.regs[TOP].d; - Real64 valdiv = fpu.regs[STV(1)].d; - double quot = valtop/valdiv; - double quotf = floor(quot); - Bit64s ressaved; - if (quot-quotf>0.5) ressaved = static_cast(quotf+1); - else if (quot-quotf<0.5) ressaved = static_cast(quotf); - else ressaved = static_cast((((static_cast(quotf))&1)!=0)?(quotf+1):(quotf)); - fpu.regs[TOP].d = valtop - ressaved*valdiv; - FPU_SET_C0(static_cast(ressaved&4)); - FPU_SET_C3(static_cast(ressaved&2)); - FPU_SET_C1(static_cast(ressaved&1)); - FPU_SET_C2(0); -} - -static void FPU_FXAM(void){ - if(fpu.regs[TOP].ll & LONGTYPE(0x8000000000000000)) //sign - { - FPU_SET_C1(1); - } - else - { - FPU_SET_C1(0); - } - if(fpu.tags[TOP] == TAG_Empty) - { - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); - return; - } - if(fpu.regs[TOP].d == 0.0) //zero or normalized number. - { - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0); - } - else - { - FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0); - } -} - - -static void FPU_F2XM1(void){ - fpu.regs[TOP].d = pow(2.0,fpu.regs[TOP].d) - 1; - return; -} - -static void FPU_FYL2X(void){ - fpu.regs[STV(1)].d*=log(fpu.regs[TOP].d)/log(static_cast(2.0)); - FPU_FPOP(); - return; -} - -static void FPU_FYL2XP1(void){ - fpu.regs[STV(1)].d*=log(fpu.regs[TOP].d+1.0)/log(static_cast(2.0)); - FPU_FPOP(); - return; -} - -static void FPU_FSCALE(void){ - fpu.regs[TOP].d *= pow(2.0,static_cast(static_cast(fpu.regs[STV(1)].d))); - return; //2^x where x is chopped. -} - -static void FPU_FSTENV(PhysPt addr){ - FPU_SET_TOP(TOP); - if(!cpu.code.big) { - mem_writew(addr+0,static_cast(fpu.cw)); - mem_writew(addr+2,static_cast(fpu.sw)); - mem_writew(addr+4,static_cast(FPU_GetTag())); - } else { - mem_writed(addr+0,static_cast(fpu.cw)); - mem_writed(addr+4,static_cast(fpu.sw)); - mem_writed(addr+8,static_cast(FPU_GetTag())); - } -} - -static void FPU_FLDENV(PhysPt addr){ - Bit16u tag; - Bit32u tagbig; - Bitu cw; - if(!cpu.code.big) { - cw = mem_readw(addr+0); - fpu.sw = mem_readw(addr+2); - tag = mem_readw(addr+4); - } else { - cw = mem_readd(addr+0); - fpu.sw = (Bit16u)mem_readd(addr+4); - tagbig = mem_readd(addr+8); - tag = static_cast(tagbig); - } - FPU_SetTag(tag); - FPU_SetCW(cw); - TOP = FPU_GET_TOP(); -} - -static void FPU_FSAVE(PhysPt addr){ - FPU_FSTENV(addr); - Bitu start = (cpu.code.big?28:14); - for(Bitu i = 0;i < 8;i++){ - FPU_ST80(addr+start,STV(i)); - start += 10; - } - FPU_FINIT(); -} - -static void FPU_FRSTOR(PhysPt addr){ - FPU_FLDENV(addr); - Bitu start = (cpu.code.big?28:14); - for(Bitu i = 0;i < 8;i++){ - fpu.regs[STV(i)].d = FPU_FLD80(addr+start); - start += 10; - } -} - -static void FPU_FXTRACT(void) { - // function stores real bias in st and - // pushes the significant number onto the stack - // if double ever uses a different base please correct this function - - FPU_Reg test = fpu.regs[TOP]; - Bit64s exp80 = test.ll&LONGTYPE(0x7ff0000000000000); - Bit64s exp80final = (exp80>>52) - BIAS64; - Real64 mant = test.d / (pow(2.0,static_cast(exp80final))); - fpu.regs[TOP].d = static_cast(exp80final); - FPU_PUSH(mant); -} - -static void FPU_FCHS(void){ - fpu.regs[TOP].d = -1.0*(fpu.regs[TOP].d); -} - -static void FPU_FABS(void){ - fpu.regs[TOP].d = fabs(fpu.regs[TOP].d); -} - -static void FPU_FTST(void){ - fpu.regs[8].d = 0.0; - FPU_FCOM(TOP,8); -} - -static void FPU_FLD1(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = 1.0; -} - -static void FPU_FLDL2T(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = L2T; -} - -static void FPU_FLDL2E(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = L2E; -} - -static void FPU_FLDPI(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = PI; -} - -static void FPU_FLDLG2(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = LG2; -} - -static void FPU_FLDLN2(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = LN2; -} - -static void FPU_FLDZ(void){ - FPU_PREP_PUSH(); - fpu.regs[TOP].d = 0.0; - fpu.tags[TOP] = TAG_Zero; -} - - -static INLINE void FPU_FADD_EA(Bitu op1){ - FPU_FADD(op1,8); -} -static INLINE void FPU_FMUL_EA(Bitu op1){ - FPU_FMUL(op1,8); -} -static INLINE void FPU_FSUB_EA(Bitu op1){ - FPU_FSUB(op1,8); -} -static INLINE void FPU_FSUBR_EA(Bitu op1){ - FPU_FSUBR(op1,8); -} -static INLINE void FPU_FDIV_EA(Bitu op1){ - FPU_FDIV(op1,8); -} -static INLINE void FPU_FDIVR_EA(Bitu op1){ - FPU_FDIVR(op1,8); -} -static INLINE void FPU_FCOM_EA(Bitu op1){ - FPU_FCOM(op1,8); -} - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu_instructions_x86.h b/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu_instructions_x86.h deleted file mode 100644 index d837850d6..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/fpu/fpu_instructions_x86.h +++ /dev/null @@ -1,1325 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -// #define WEAK_EXCEPTIONS - - -#if defined (_MSC_VER) - -#ifdef WEAK_EXCEPTIONS -#define clx -#else -#define clx fclex -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD(op,szI,szA) \ - __asm { \ - __asm mov ebx, store_to \ - __asm shl ebx, 4 \ - __asm op szI PTR fpu.p_regs[128].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } -#else -#define FPUD_LOAD(op,szI,szA) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, 8 \ - __asm shl eax, 4 \ - __asm mov ebx, store_to \ - __asm shl ebx, 4 \ - __asm fclex \ - __asm op szI PTR fpu.p_regs[eax].m1 \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD_EA(op,szI,szA) \ - __asm { \ - __asm op szI PTR fpu.p_regs[128].m1 \ - } -#else -#define FPUD_LOAD_EA(op,szI,szA) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, 8 \ - __asm shl eax, 4 \ - __asm fclex \ - __asm op szI PTR fpu.p_regs[eax].m1 \ - __asm fnstsw new_sw \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_STORE(op,szI,szA) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, TOP \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op szI PTR fpu.p_regs[128].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_STORE(op,szI,szA) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm mov ebx, 8 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op szI PTR fpu.p_regs[ebx].m1 \ - __asm fnstsw new_sw \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsin,fcos,f2xm1,fchs,fabs -#define FPUD_TRIG(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fsincos -#define FPUD_SINCOS() \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm fsincos \ - __asm fnstsw new_sw \ - __asm mov cx, new_sw \ - __asm and ch, 0x04 \ - __asm jnz argument_too_large1 \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm jmp end_sincos \ - __asm argument_too_large1: \ - __asm fstp st(0) \ - __asm end_sincos: \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fptan -#define FPUD_PTAN() \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm fptan \ - __asm fnstsw new_sw \ - __asm mov cx, new_sw \ - __asm and ch, 0x04 \ - __asm jnz argument_too_large2 \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm jmp end_ptan \ - __asm argument_too_large2: \ - __asm fstp st(0) \ - __asm end_ptan: \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fxtract -#ifdef WEAK_EXCEPTIONS -#define FPUD_XTRACT \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxtract \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - FPU_PREP_PUSH(); -#else -#define FPUD_XTRACT \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm dec ebx \ - __asm and ebx, 7 \ - __asm shl eax, 4 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm fxtract \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_PREP_PUSH(); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fldcw fpu.cw_mask_all \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH1(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm clx \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1_EA(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm op st(1), st(0) \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH1_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm clx \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsqrt,frndint -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH2(op) \ - Bit16u save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, TOP \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } -#else -#define FPUD_ARITH2(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fdiv,fdivr -// (This is identical to FPUD_ARITH1 but without a WEAK_EXCEPTIONS variant) -#define FPUD_ARITH3(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm fldcw fpu.cw_mask_all \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm mov ebx, op2 \ - __asm shl ebx, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fclex \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fdiv,fdivr -// (This is identical to FPUD_ARITH1_EA but without a WEAK_EXCEPTIONS variant) -#define FPUD_ARITH3_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm { \ - __asm fnstcw save_cw \ - __asm mov eax, op1 \ - __asm fldcw fpu.cw_mask_all \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fxch \ - __asm fclex \ - __asm op st(1), st(0) \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fldcw save_cw \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fprem,fprem1,fscale -#define FPUD_REMAINDER(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fstp st(0) \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fcom,fucom -#define FPUD_COMPARE(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov ebx, op2 \ - __asm mov eax, op1 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -#define FPUD_COMPARE_EA(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, op1 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fxam,ftst -#define FPUD_EXAMINE(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm clx \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp st(0) \ - } \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fpatan,fyl2xp1 -#ifdef WEAK_EXCEPTIONS -#define FPUD_WITH_POP(op) \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - FPU_FPOP(); -#else -#define FPUD_WITH_POP(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// handles fyl2x -#ifdef WEAK_EXCEPTIONS -#define FPUD_FYL2X(op) \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - FPU_FPOP(); -#else -#define FPUD_FYL2X(op) \ - Bit16u new_sw; \ - __asm { \ - __asm mov eax, TOP \ - __asm mov ebx, eax \ - __asm inc ebx \ - __asm and ebx, 7 \ - __asm shl ebx, 4 \ - __asm shl eax, 4 \ - __asm fld TBYTE PTR fpu.p_regs[ebx].m1 \ - __asm fld TBYTE PTR fpu.p_regs[eax].m1 \ - __asm fclex \ - __asm op \ - __asm fnstsw new_sw \ - __asm fstp TBYTE PTR fpu.p_regs[ebx].m1 \ - } \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// load math constants -#define FPUD_LOAD_CONST(op) \ - FPU_PREP_PUSH(); \ - __asm { \ - __asm mov eax, TOP \ - __asm shl eax, 4 \ - __asm clx \ - __asm op \ - __asm fstp TBYTE PTR fpu.p_regs[eax].m1 \ - } \ - -#else - -// !defined _MSC_VER - -#ifdef WEAK_EXCEPTIONS -#define clx -#else -#define clx "fclex" -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD(op,szI,szA) \ - __asm__ volatile ( \ - #op #szA " %1 \n" \ - "fstpt %0 " \ - : "=m" (fpu.p_regs[store_to]) \ - : "m" (fpu.p_regs[8]) \ - ); -#else -#define FPUD_LOAD(op,szI,szA) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fclex \n" \ - #op #szA " %2 \n" \ - "fnstsw %0 \n" \ - "fstpt %1 " \ - : "=&am" (new_sw), "=m" (fpu.p_regs[store_to]) \ - : "m" (fpu.p_regs[8]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_LOAD_EA(op,szI,szA) \ - __asm__ volatile ( \ - #op #szA " %0 \n" \ - : \ - : "m" (fpu.p_regs[8]) \ - ); -#else -#define FPUD_LOAD_EA(op,szI,szA) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fclex \n" \ - #op #szA " %1 \n" \ - "fnstsw %0 \n" \ - : "=&am" (new_sw) \ - : "m" (fpu.p_regs[8]) \ - : \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -#ifdef WEAK_EXCEPTIONS -#define FPUD_STORE(op,szI,szA) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "fldt %2 \n" \ - #op #szA " %1 \n" \ - "fldcw %0 " \ - : "=m" (save_cw), "=m" (fpu.p_regs[8]) \ - : "m" (fpu.p_regs[TOP]), "m" (fpu.cw_mask_all) \ - ); -#else -#define FPUD_STORE(op,szI,szA) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "fldt %3 \n" \ - "fclex \n" \ - #op #szA " %2 \n" \ - "fnstsw %0 \n" \ - "fldcw %1 " \ - : "=&am" (new_sw), "=m" (save_cw), "=m" (fpu.p_regs[8]) \ - : "m" (fpu.p_regs[TOP]), "m" (fpu.cw_mask_all) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsin,fcos,f2xm1,fchs,fabs -#define FPUD_TRIG(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %1 " \ - : "=&am" (new_sw), "+m" (fpu.p_regs[TOP]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fsincos -#define FPUD_SINCOS() \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - clx" \n" \ - "fsincos \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "movw %0, %%ax \n" \ - "sahf \n" \ - "jp 1f \n" \ - "fstpt %1 \n" \ - "1: " \ - : "=m" (new_sw), "+m" (fpu.p_regs[TOP]), \ - "=m" (fpu.p_regs[(TOP-1)&7]) \ - : \ - : "ax", "cc" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fptan -#define FPUD_PTAN() \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - clx" \n" \ - "fptan \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "movw %0, %%ax \n" \ - "sahf \n" \ - "jp 1f \n" \ - "fstpt %1 \n" \ - "1: " \ - : "=m" (new_sw), "+m" (fpu.p_regs[TOP]), \ - "=m" (fpu.p_regs[(TOP-1)&7]) \ - : \ - : "ax", "cc" \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - if ((new_sw&0x0400)==0) FPU_PREP_PUSH(); - -// handles fxtract -#ifdef WEAK_EXCEPTIONS -#define FPUD_XTRACT \ - __asm__ volatile ( \ - "fldt %0 \n" \ - "fxtract \n" \ - "fstpt %1 \n" \ - "fstpt %0 " \ - : "+m" (fpu.p_regs[TOP]), "=m" (fpu.p_regs[(TOP-1)&7]) \ - ); \ - FPU_PREP_PUSH(); -#else -#define FPUD_XTRACT \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - "fclex \n" \ - "fxtract \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "fstpt %1 " \ - : "=&am" (new_sw), "+m" (fpu.p_regs[TOP]), \ - "=m" (fpu.p_regs[(TOP-1)&7]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - FPU_PREP_PUSH(); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %3 \n" \ - "fldt %2 \n" \ - "fldt %1 \n" \ - #op" \n" \ - "fstpt %1 \n" \ - "fldcw %0 " \ - : "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ - : "m" (fpu.p_regs[op2]), "m" (fpu.cw_mask_all) \ - ); -#else -#define FPUD_ARITH1(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "fldt %3 \n" \ - "fldt %2 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "fldcw %1 " \ - : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ - : "m" (fpu.p_regs[op2]), "m" (fpu.cw_mask_all) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fadd,fmul,fsub,fsubr -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH1_EA(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %2 \n" \ - "fldt %1 \n" \ - #op" \n" \ - "fstpt %1 \n" \ - "fldcw %0 " \ - : "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ - : "m" (fpu.cw_mask_all) \ - ); -#else -#define FPUD_ARITH1_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %3 \n" \ - "fldt %2 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "fldcw %1 " \ - : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ - : "m" (fpu.cw_mask_all) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fsqrt,frndint -#ifdef WEAK_EXCEPTIONS -#define FPUD_ARITH2(op) \ - Bit16u save_cw; \ - __asm__ volatile ( \ - "fnstcw %0 \n" \ - "fldcw %2 \n" \ - "fldt %1 \n" \ - #op" \n" \ - "fstpt %1 \n" \ - "fldcw %0 " \ - : "=m" (save_cw), "+m" (fpu.p_regs[TOP]) \ - : "m" (fpu.cw_mask_all) \ - ); -#else -#define FPUD_ARITH2(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %3 \n" \ - "fldt %2 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "fldcw %1 " \ - : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[TOP]) \ - : "m" (fpu.cw_mask_all) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); -#endif - -// handles fdiv,fdivr -// (This is identical to FPUD_ARITH1 but without a WEAK_EXCEPTIONS variant) -#define FPUD_ARITH3(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %4 \n" \ - "fldt %3 \n" \ - "fldt %2 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "fldcw %1 " \ - : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ - : "m" (fpu.p_regs[op2]), "m" (fpu.cw_mask_all) \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fdiv,fdivr -// (This is identical to FPUD_ARITH1_EA but without a WEAK_EXCEPTIONS variant) -#define FPUD_ARITH3_EA(op) \ - Bit16u new_sw,save_cw; \ - __asm__ volatile ( \ - "fnstcw %1 \n" \ - "fldcw %3 \n" \ - "fldt %2 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %2 \n" \ - "fldcw %1 " \ - : "=&am" (new_sw), "=m" (save_cw), "+m" (fpu.p_regs[op1]) \ - : "m" (fpu.cw_mask_all) \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fprem,fprem1,fscale -#define FPUD_REMAINDER(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %2 \n" \ - "fldt %1 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %1 \n" \ - "fstp %%st(0) " \ - : "=&am" (new_sw), "+m" (fpu.p_regs[TOP]) \ - : "m" (fpu.p_regs[(TOP+1)&7]) \ - ); \ - fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff); - -// handles fcom,fucom -#define FPUD_COMPARE(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %2 \n" \ - "fldt %1 \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 " \ - : "=&am" (new_sw) \ - : "m" (fpu.p_regs[op1]), "m" (fpu.p_regs[op2]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fcom,fucom -#define FPUD_COMPARE_EA(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 " \ - : "=&am" (new_sw) \ - : "m" (fpu.p_regs[op1]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fxam,ftst -#define FPUD_EXAMINE(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - clx" \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstp %%st(0) " \ - : "=&am" (new_sw) \ - : "m" (fpu.p_regs[TOP]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); - -// handles fpatan,fyl2xp1 -#ifdef WEAK_EXCEPTIONS -#define FPUD_WITH_POP(op) \ - __asm__ volatile ( \ - "fldt %0 \n" \ - "fldt %1 \n" \ - #op" \n" \ - "fstpt %0 \n" \ - : "+m" (fpu.p_regs[(TOP+1)&7]) \ - : "m" (fpu.p_regs[TOP]) \ - ); \ - FPU_FPOP(); -#else -#define FPUD_WITH_POP(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - "fldt %2 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %1 \n" \ - : "=&am" (new_sw), "+m" (fpu.p_regs[(TOP+1)&7]) \ - : "m" (fpu.p_regs[TOP]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// handles fyl2x -#ifdef WEAK_EXCEPTIONS -#define FPUD_FYL2X(op) \ - __asm__ volatile ( \ - "fldt %0 \n" \ - "fldt %1 \n" \ - #op" \n" \ - "fstpt %0 \n" \ - : "+m" (fpu.p_regs[(TOP+1)&7]) \ - : "m" (fpu.p_regs[TOP]) \ - ); \ - FPU_FPOP(); -#else -#define FPUD_FYL2X(op) \ - Bit16u new_sw; \ - __asm__ volatile ( \ - "fldt %1 \n" \ - "fldt %2 \n" \ - "fclex \n" \ - #op" \n" \ - "fnstsw %0 \n" \ - "fstpt %1 \n" \ - : "=&am" (new_sw), "+m" (fpu.p_regs[(TOP+1)&7]) \ - : "m" (fpu.p_regs[TOP]) \ - ); \ - fpu.sw=(new_sw&exc_mask)|(fpu.sw&0x80ff); \ - FPU_FPOP(); -#endif - -// load math constants -#define FPUD_LOAD_CONST(op) \ - FPU_PREP_PUSH(); \ - __asm__ volatile ( \ - clx" \n" \ - #op" \n" \ - "fstpt %0 \n" \ - : "=m" (fpu.p_regs[TOP]) \ - ); - -#endif - -#ifdef WEAK_EXCEPTIONS -const Bit16u exc_mask=0x7f00; -#else -const Bit16u exc_mask=0xffbf; -#endif - -static void FPU_FINIT(void) { - FPU_SetCW(0x37F); - fpu.sw=0; - TOP=FPU_GET_TOP(); - fpu.tags[0]=TAG_Empty; - fpu.tags[1]=TAG_Empty; - fpu.tags[2]=TAG_Empty; - fpu.tags[3]=TAG_Empty; - fpu.tags[4]=TAG_Empty; - fpu.tags[5]=TAG_Empty; - fpu.tags[6]=TAG_Empty; - fpu.tags[7]=TAG_Empty; - fpu.tags[8]=TAG_Valid; // is only used by us -} - -static void FPU_FCLEX(void){ - fpu.sw&=0x7f00; //should clear exceptions -} - -static void FPU_FNOP(void){ -} - -static void FPU_PREP_PUSH(void){ - TOP = (TOP - 1) &7; - if (GCC_UNLIKELY(fpu.tags[TOP] != TAG_Empty)) E_Exit("FPU stack overflow"); - fpu.tags[TOP] = TAG_Valid; -} - -static void FPU_FPOP(void){ - if (GCC_UNLIKELY(fpu.tags[TOP] == TAG_Empty)) E_Exit("FPU stack underflow"); - fpu.tags[TOP] = TAG_Empty; - TOP = ((TOP+1)&7); -} - -static void FPU_FLD_F32(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD(fld,DWORD,s) -} - -static void FPU_FLD_F32_EA(PhysPt addr) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD_EA(fld,DWORD,s) -} - -static void FPU_FLD_F64(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - FPUD_LOAD(fld,QWORD,l) -} - -static void FPU_FLD_F64_EA(PhysPt addr) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - FPUD_LOAD_EA(fld,QWORD,l) -} - -static void FPU_FLD_F80(PhysPt addr) { - fpu.p_regs[TOP].m1 = mem_readd(addr); - fpu.p_regs[TOP].m2 = mem_readd(addr+4); - fpu.p_regs[TOP].m3 = mem_readw(addr+8); - FPU_SET_C1(0); -} - -static void FPU_FLD_I16(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); - FPUD_LOAD(fild,WORD,s) -} - -static void FPU_FLD_I16_EA(PhysPt addr) { - fpu.p_regs[8].m1 = (Bit32u)mem_readw(addr); - FPUD_LOAD_EA(fild,WORD,s) -} - -static void FPU_FLD_I32(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD(fild,DWORD,l) -} - -static void FPU_FLD_I32_EA(PhysPt addr) { - fpu.p_regs[8].m1 = mem_readd(addr); - FPUD_LOAD_EA(fild,DWORD,l) -} - -static void FPU_FLD_I64(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - FPUD_LOAD(fild,QWORD,q) -} - -static void FPU_FBLD(PhysPt addr,Bitu store_to) { - fpu.p_regs[8].m1 = mem_readd(addr); - fpu.p_regs[8].m2 = mem_readd(addr+4); - fpu.p_regs[8].m3 = mem_readw(addr+8); - FPUD_LOAD(fbld,TBYTE,) -} - -static void FPU_FST_F32(PhysPt addr) { - FPUD_STORE(fstp,DWORD,s) - mem_writed(addr,fpu.p_regs[8].m1); -} - -static void FPU_FST_F64(PhysPt addr) { - FPUD_STORE(fstp,QWORD,l) - mem_writed(addr,fpu.p_regs[8].m1); - mem_writed(addr+4,fpu.p_regs[8].m2); -} - -static void FPU_FST_F80(PhysPt addr) { - mem_writed(addr,fpu.p_regs[TOP].m1); - mem_writed(addr+4,fpu.p_regs[TOP].m2); - mem_writew(addr+8,fpu.p_regs[TOP].m3); - FPU_SET_C1(0); -} - -static void FPU_FST_I16(PhysPt addr) { - FPUD_STORE(fistp,WORD,s) - mem_writew(addr,(Bit16u)fpu.p_regs[8].m1); -} - -static void FPU_FST_I32(PhysPt addr) { - FPUD_STORE(fistp,DWORD,l) - mem_writed(addr,fpu.p_regs[8].m1); -} - -static void FPU_FST_I64(PhysPt addr) { - FPUD_STORE(fistp,QWORD,q) - mem_writed(addr,fpu.p_regs[8].m1); - mem_writed(addr+4,fpu.p_regs[8].m2); -} - -static void FPU_FBST(PhysPt addr) { - FPUD_STORE(fbstp,TBYTE,) - mem_writed(addr,fpu.p_regs[8].m1); - mem_writed(addr+4,fpu.p_regs[8].m2); - mem_writew(addr+8,fpu.p_regs[8].m3); -} - - -static void FPU_FSIN(void){ - FPUD_TRIG(fsin) -} - -static void FPU_FSINCOS(void){ - FPUD_SINCOS() -} - -static void FPU_FCOS(void){ - FPUD_TRIG(fcos) -} - -static void FPU_FSQRT(void){ - FPUD_ARITH2(fsqrt) -} - -static void FPU_FPATAN(void){ - FPUD_WITH_POP(fpatan) -} - -static void FPU_FPTAN(void){ - FPUD_PTAN() -} - - -static void FPU_FADD(Bitu op1, Bitu op2){ - FPUD_ARITH1(faddp) -} - -static void FPU_FADD_EA(Bitu op1){ - FPUD_ARITH1_EA(faddp) -} - -static void FPU_FDIV(Bitu op1, Bitu op2){ - FPUD_ARITH3(fdivp) -} - -static void FPU_FDIV_EA(Bitu op1){ - FPUD_ARITH3_EA(fdivp) -} - -static void FPU_FDIVR(Bitu op1, Bitu op2){ - FPUD_ARITH3(fdivrp) -} - -static void FPU_FDIVR_EA(Bitu op1){ - FPUD_ARITH3_EA(fdivrp) -} - -static void FPU_FMUL(Bitu op1, Bitu op2){ - FPUD_ARITH1(fmulp) -} - -static void FPU_FMUL_EA(Bitu op1){ - FPUD_ARITH1_EA(fmulp) -} - -static void FPU_FSUB(Bitu op1, Bitu op2){ - FPUD_ARITH1(fsubp) -} - -static void FPU_FSUB_EA(Bitu op1){ - FPUD_ARITH1_EA(fsubp) -} - -static void FPU_FSUBR(Bitu op1, Bitu op2){ - FPUD_ARITH1(fsubrp) -} - -static void FPU_FSUBR_EA(Bitu op1){ - FPUD_ARITH1_EA(fsubrp) -} - -static void FPU_FXCH(Bitu stv, Bitu other){ - FPU_Tag tag = fpu.tags[other]; - fpu.tags[other] = fpu.tags[stv]; - fpu.tags[stv] = tag; - - Bit32u m1s = fpu.p_regs[other].m1; - Bit32u m2s = fpu.p_regs[other].m2; - Bit16u m3s = fpu.p_regs[other].m3; - fpu.p_regs[other].m1 = fpu.p_regs[stv].m1; - fpu.p_regs[other].m2 = fpu.p_regs[stv].m2; - fpu.p_regs[other].m3 = fpu.p_regs[stv].m3; - fpu.p_regs[stv].m1 = m1s; - fpu.p_regs[stv].m2 = m2s; - fpu.p_regs[stv].m3 = m3s; - - FPU_SET_C1(0); -} - -static void FPU_FST(Bitu stv, Bitu other){ - fpu.tags[other] = fpu.tags[stv]; - - fpu.p_regs[other].m1 = fpu.p_regs[stv].m1; - fpu.p_regs[other].m2 = fpu.p_regs[stv].m2; - fpu.p_regs[other].m3 = fpu.p_regs[stv].m3; - - FPU_SET_C1(0); -} - - -static void FPU_FCOM(Bitu op1, Bitu op2){ - FPUD_COMPARE(fcompp) -} - -static void FPU_FCOM_EA(Bitu op1){ - FPUD_COMPARE_EA(fcompp) -} - -static void FPU_FUCOM(Bitu op1, Bitu op2){ - FPUD_COMPARE(fucompp) -} - -static void FPU_FRNDINT(void){ - FPUD_ARITH2(frndint) -} - -static void FPU_FPREM(void){ - FPUD_REMAINDER(fprem) -} - -static void FPU_FPREM1(void){ - FPUD_REMAINDER(fprem1) -} - -static void FPU_FXAM(void){ - FPUD_EXAMINE(fxam) - // handle empty registers (C1 set to sign in any way!) - if(fpu.tags[TOP] == TAG_Empty) { - FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); - return; - } -} - -static void FPU_F2XM1(void){ - FPUD_TRIG(f2xm1) -} - -static void FPU_FYL2X(void){ - FPUD_FYL2X(fyl2x) -} - -static void FPU_FYL2XP1(void){ - FPUD_WITH_POP(fyl2xp1) -} - -static void FPU_FSCALE(void){ - FPUD_REMAINDER(fscale) -} - - -static void FPU_FSTENV(PhysPt addr){ - FPU_SET_TOP(TOP); - if(!cpu.code.big) { - mem_writew(addr+0,static_cast(fpu.cw)); - mem_writew(addr+2,static_cast(fpu.sw)); - mem_writew(addr+4,static_cast(FPU_GetTag())); - } else { - mem_writed(addr+0,static_cast(fpu.cw)); - mem_writed(addr+4,static_cast(fpu.sw)); - mem_writed(addr+8,static_cast(FPU_GetTag())); - } -} - -static void FPU_FLDENV(PhysPt addr){ - Bit16u tag; - Bit32u tagbig; - Bitu cw; - if(!cpu.code.big) { - cw = mem_readw(addr+0); - fpu.sw = mem_readw(addr+2); - tag = mem_readw(addr+4); - } else { - cw = mem_readd(addr+0); - fpu.sw = (Bit16u)mem_readd(addr+4); - tagbig = mem_readd(addr+8); - tag = static_cast(tagbig); - } - FPU_SetTag(tag); - FPU_SetCW(cw); - TOP=FPU_GET_TOP(); -} - -static void FPU_FSAVE(PhysPt addr){ - FPU_FSTENV(addr); - Bitu start=(cpu.code.big?28:14); - for(Bitu i=0;i<8;i++){ - mem_writed(addr+start,fpu.p_regs[STV(i)].m1); - mem_writed(addr+start+4,fpu.p_regs[STV(i)].m2); - mem_writew(addr+start+8,fpu.p_regs[STV(i)].m3); - start+=10; - } - FPU_FINIT(); -} - -static void FPU_FRSTOR(PhysPt addr){ - FPU_FLDENV(addr); - Bitu start=(cpu.code.big?28:14); - for(Bitu i=0;i<8;i++){ - fpu.p_regs[STV(i)].m1 = mem_readd(addr+start); - fpu.p_regs[STV(i)].m2 = mem_readd(addr+start+4); - fpu.p_regs[STV(i)].m3 = mem_readw(addr+start+8); - start+=10; - } -} - - -static void FPU_FXTRACT(void) { - FPUD_XTRACT -} - -static void FPU_FCHS(void){ - FPUD_TRIG(fchs) -} - -static void FPU_FABS(void){ - FPUD_TRIG(fabs) -} - -static void FPU_FTST(void){ - FPUD_EXAMINE(ftst) -} - -static void FPU_FLD1(void){ - FPUD_LOAD_CONST(fld1) -} - -static void FPU_FLDL2T(void){ - FPUD_LOAD_CONST(fldl2t) -} - -static void FPU_FLDL2E(void){ - FPUD_LOAD_CONST(fldl2e) -} - -static void FPU_FLDPI(void){ - FPUD_LOAD_CONST(fldpi) -} - -static void FPU_FLDLG2(void){ - FPUD_LOAD_CONST(fldlg2) -} - -static void FPU_FLDLN2(void){ - FPUD_LOAD_CONST(fldln2) -} - -static void FPU_FLDZ(void){ - FPUD_LOAD_CONST(fldz) - fpu.tags[TOP]=TAG_Zero; -} diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/Makefile.am b/source/src/vm/libcpu_newdev/dosbox-i386/include/Makefile.am deleted file mode 100644 index c85d1567c..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -noinst_HEADERS = \ -bios.h \ -bios_disk.h \ -callback.h \ -cpu.h \ -cross.h \ -control.h \ -debug.h \ -dma.h \ -dos_inc.h \ -dos_system.h \ -dosbox.h \ -dosv.h \ -fpu.h \ -hardware.h \ -inout.h \ -ipx.h \ -ipxserver.h \ -j3.h \ -jega.h \ -jfont.h \ -joystick.h \ -keyboard.h \ -logging.h \ -mapper.h \ -mem.h \ -midi.h \ -mixer.h \ -modules.h \ -mouse.h \ -paging.h \ -pci_bus.h \ -pic.h \ -programs.h \ -render.h \ -regs.h \ -render.h \ -serialport.h \ -setup.h \ -shell.h \ -support.h \ -timer.h \ -vga.h \ -video.h - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/Makefile.in b/source/src/vm/libcpu_newdev/dosbox-i386/include/Makefile.in deleted file mode 100644 index 5b1cd3c21..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/Makefile.in +++ /dev/null @@ -1,533 +0,0 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2018 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = include -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -HEADERS = $(noinst_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALSA_CFLAGS = @ALSA_CFLAGS@ -ALSA_LIBS = @ALSA_LIBS@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -RANLIB = @RANLIB@ -SDL_CFLAGS = @SDL_CFLAGS@ -SDL_CONFIG = @SDL_CONFIG@ -SDL_LIBS = @SDL_LIBS@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -WINDRES = @WINDRES@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_HEADERS = \ -bios.h \ -bios_disk.h \ -callback.h \ -cpu.h \ -cross.h \ -control.h \ -debug.h \ -dma.h \ -dos_inc.h \ -dos_system.h \ -dosbox.h \ -dosv.h \ -fpu.h \ -hardware.h \ -inout.h \ -ipx.h \ -ipxserver.h \ -j3.h \ -jega.h \ -jfont.h \ -joystick.h \ -keyboard.h \ -logging.h \ -mapper.h \ -mem.h \ -midi.h \ -mixer.h \ -modules.h \ -mouse.h \ -paging.h \ -pci_bus.h \ -pic.h \ -programs.h \ -render.h \ -regs.h \ -render.h \ -serialport.h \ -setup.h \ -shell.h \ -support.h \ -timer.h \ -vga.h \ -video.h - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu include/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(HEADERS) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - cscopelist-am ctags ctags-am distclean distclean-generic \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/bios.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/bios.h deleted file mode 100644 index e4ed8db33..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/bios.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_BIOS_H -#define DOSBOX_BIOS_H - -#define BIOS_BASE_ADDRESS_COM1 0x400 -#define BIOS_BASE_ADDRESS_COM2 0x402 -#define BIOS_BASE_ADDRESS_COM3 0x404 -#define BIOS_BASE_ADDRESS_COM4 0x406 -#define BIOS_ADDRESS_LPT1 0x408 -#define BIOS_ADDRESS_LPT2 0x40a -#define BIOS_ADDRESS_LPT3 0x40c -/* 0x40e is reserved */ -#define BIOS_CONFIGURATION 0x410 -/* 0x412 is reserved */ -#define BIOS_MEMORY_SIZE 0x413 -#define BIOS_TRUE_MEMORY_SIZE 0x415 -/* #define bios_expansion_memory_size (*(unsigned int *) 0x415) */ -#define BIOS_KEYBOARD_STATE 0x417 -#define BIOS_KEYBOARD_FLAGS1 BIOS_KEYBOARD_STATE -#define BIOS_KEYBOARD_FLAGS2 0x418 -#define BIOS_KEYBOARD_TOKEN 0x419 -/* used for keyboard input with Alt-Number */ -#define BIOS_KEYBOARD_BUFFER_HEAD 0x41a -#define BIOS_KEYBOARD_BUFFER_TAIL 0x41c -#define BIOS_KEYBOARD_BUFFER 0x41e -/* #define bios_keyboard_buffer (*(unsigned int *) 0x41e) */ -#define BIOS_DRIVE_ACTIVE 0x43e -#define BIOS_DRIVE_RUNNING 0x43f -#define BIOS_DISK_MOTOR_TIMEOUT 0x440 -#define BIOS_DISK_STATUS 0x441 -/* #define bios_fdc_result_buffer (*(unsigned short *) 0x442) */ -#define BIOS_VIDEO_MODE 0x449 -#define BIOS_SCREEN_COLUMNS 0x44a -#define BIOS_VIDEO_MEMORY_USED 0x44c -#define BIOS_VIDEO_MEMORY_ADDRESS 0x44e -#define BIOS_VIDEO_CURSOR_POS 0x450 - - -#define BIOS_CURSOR_SHAPE 0x460 -#define BIOS_CURSOR_LAST_LINE 0x460 -#define BIOS_CURSOR_FIRST_LINE 0x461 -#define BIOS_CURRENT_SCREEN_PAGE 0x462 -#define BIOS_VIDEO_PORT 0x463 -#define BIOS_VDU_CONTROL 0x465 -#define BIOS_VDU_COLOR_REGISTER 0x466 -/* 0x467-0x468 is reserved */ -#define BIOS_LAST_UNEXPECTED_IRQ 0x46b -#define BIOS_TIMER 0x46c -#define BIOS_24_HOURS_FLAG 0x470 -#define BIOS_KEYBOARD_FLAGS 0x471 -#define BIOS_CTRL_ALT_DEL_FLAG 0x472 -#define BIOS_HARDDISK_COUNT 0x475 -/* 0x474, 0x476, 0x477 is reserved */ -#define BIOS_LPT1_TIMEOUT 0x478 -#define BIOS_LPT2_TIMEOUT 0x479 -#define BIOS_LPT3_TIMEOUT 0x47a -/* 0x47b is reserved */ -#define BIOS_COM1_TIMEOUT 0x47c -#define BIOS_COM2_TIMEOUT 0x47d -#define BIOS_COM3_TIMEOUT 0x47e -#define BIOS_COM4_TIMEOUT 0x47f -/* 0x47e is reserved */ //<- why that? -/* 0x47f-0x4ff is unknow for me */ -#define BIOS_KEYBOARD_BUFFER_START 0x480 -#define BIOS_KEYBOARD_BUFFER_END 0x482 - -#define BIOS_ROWS_ON_SCREEN_MINUS_1 0x484 -#define BIOS_FONT_HEIGHT 0x485 - -#define BIOS_VIDEO_INFO_0 0x487 -#define BIOS_VIDEO_INFO_1 0x488 -#define BIOS_VIDEO_INFO_2 0x489 -#define BIOS_VIDEO_COMBO 0x48a - -#define BIOS_KEYBOARD_FLAGS3 0x496 -#define BIOS_KEYBOARD_LEDS 0x497 - -#define BIOS_WAIT_FLAG_POINTER 0x498 -#define BIOS_WAIT_FLAG_COUNT 0x49c -#define BIOS_WAIT_FLAG_ACTIVE 0x4a0 -#define BIOS_WAIT_FLAG_TEMP 0x4a1 - - -#define BIOS_PRINT_SCREEN_FLAG 0x500 - -#define BIOS_VIDEO_SAVEPTR 0x4a8 - - -#define BIOS_DEFAULT_HANDLER_LOCATION (RealMake(0xf000,0xff53)) -#define BIOS_DEFAULT_INT5_LOCATION (RealMake(0xf000,0xff54)) -#define BIOS_DEFAULT_IRQ0_LOCATION (RealMake(0xf000,0xfea5)) -#define BIOS_DEFAULT_IRQ1_LOCATION (RealMake(0xf000,0xe987)) -#define BIOS_DEFAULT_IRQ2_LOCATION (RealMake(0xf000,0xff55)) -#define BIOS_DEFAULT_RESET_LOCATION (RealMake(0xf000,0xe05b)) - -/* maximum of scancodes handled by keyboard bios routines */ -//#define MAX_SCAN_CODE 0x7f -#define MAX_SCAN_CODE 0x93 - -/* The Section handling Bios Disk Access */ -//#define BIOS_MAX_DISK 10 - -//#define MAX_SWAPPABLE_DISKS 20 - -void BIOS_ZeroExtendedSize(bool in); -void char_out(Bit8u chr,Bit32u att,Bit8u page); -void INT10_StartUp(void); -void INT16_StartUp(void); -void INT2A_StartUp(void); -void INT2F_StartUp(void); -void INT33_StartUp(void); -void INT13_StartUp(void); - -bool BIOS_AddKeyToBuffer(Bit16u code); - -void INT10_ReloadRomFonts(); - -void BIOS_SetComPorts (Bit16u baseaddr[]); -void BIOS_SetLPTPort (Bitu port, Bit16u baseaddr); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/bios_disk.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/bios_disk.h deleted file mode 100644 index 0670ce059..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/bios_disk.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_BIOS_DISK_H -#define DOSBOX_BIOS_DISK_H - -#include -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif -#ifndef DOSBOX_DOS_INC_H -#include "dos_inc.h" -#endif -#ifndef DOSBOX_BIOS_H -#include "bios.h" -#endif - -/* The Section handling Bios Disk Access */ -#define BIOS_MAX_DISK 10 - -#define MAX_SWAPPABLE_DISKS 20 -struct diskGeo { - Bit32u ksize; /* Size in kilobytes */ - Bit16u secttrack; /* Sectors per track */ - Bit16u headscyl; /* Heads per cylinder */ - Bit16u cylcount; /* Cylinders per side */ - Bit16u biosval; /* Type to return from BIOS */ -}; -extern diskGeo DiskGeometryList[]; - -class imageDisk { -public: - Bit8u Read_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data); - Bit8u Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data); - Bit8u Read_AbsoluteSector(Bit32u sectnum, void * data); - Bit8u Write_AbsoluteSector(Bit32u sectnum, void * data); - - void Set_Geometry(Bit32u setHeads, Bit32u setCyl, Bit32u setSect, Bit32u setSectSize); - void Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit32u *getSectSize); - Bit8u GetBiosType(void); - Bit32u getSectSize(void); - imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHardDisk); - ~imageDisk() { if(diskimg != NULL) { fclose(diskimg); } }; - - bool hardDrive; - bool active; - FILE *diskimg; - Bit8u diskname[512]; - Bit8u floppytype; - - Bit32u sector_size; - Bit32u heads,cylinders,sectors; -private: - Bit32u current_fpos; - enum { NONE,READ,WRITE } last_action; -}; - -void updateDPT(void); -void incrementFDD(void); - -#define MAX_HDD_IMAGES 2 - -extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES]; -extern imageDisk *diskSwap[20]; -extern Bit32s swapPosition; -extern Bit16u imgDTASeg; /* Real memory location of temporary DTA pointer for fat image disk access */ -extern RealPt imgDTAPtr; /* Real memory location of temporary DTA pointer for fat image disk access */ -extern DOS_DTA *imgDTA; - -void swapInDisks(void); -void swapInNextDisk(void); -bool getSwapRequest(void); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/callback.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/callback.h deleted file mode 100644 index 44ebac2ae..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/callback.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_CALLBACK_H -#define DOSBOX_CALLBACK_H - -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -typedef Bitu (*CallBack_Handler)(void); -extern CallBack_Handler CallBack_Handlers[]; - -enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, - CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE, - CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET, - CB_INT21,CB_INT13, - CB_INT6F_ATOK }; - -#define CB_MAX 128 -#define CB_SIZE 32 -#define CB_SEG 0xF000 -#define CB_SOFFSET 0x1000 - -enum { - CBRET_NONE=0,CBRET_STOP=1 -}; - -extern Bit8u lastint; - -static INLINE RealPt CALLBACK_RealPointer(Bitu callback) { - return RealMake(CB_SEG,(Bit16u)(CB_SOFFSET+callback*CB_SIZE)); -} - -static INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { - return PhysMake(CB_SEG,(Bit16u)(CB_SOFFSET+callback*CB_SIZE)); -} - -static INLINE PhysPt CALLBACK_GetBase(void) { - return (CB_SEG << 4) + CB_SOFFSET; -} - -Bitu CALLBACK_Allocate(); - -void CALLBACK_Idle(void); - - -void CALLBACK_RunRealInt(Bit8u intnum); -void CALLBACK_RunRealFar(Bit16u seg,Bit16u off); - -bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr); -Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr); - -const char* CALLBACK_GetDescription(Bitu callback); -bool CALLBACK_Free(Bitu callback); - -void CALLBACK_SCF(bool val); -void CALLBACK_SZF(bool val); -void CALLBACK_SIF(bool val); - -extern Bitu call_priv_io; - - -class CALLBACK_HandlerObject{ -private: - bool installed; - Bitu m_callback; - enum {NONE,SETUP,SETUPAT} m_type; - struct { - RealPt old_vector; - Bit8u interrupt; - bool installed; - } vectorhandler; -public: - CALLBACK_HandlerObject():installed(false),m_type(NONE) { - vectorhandler.installed=false; - } - ~CALLBACK_HandlerObject(); - - //Install and allocate a callback. - void Install(CallBack_Handler handler,Bitu type,const char* description); - void Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description); - - void Uninstall(); - - //Only allocate a callback number - void Allocate(CallBack_Handler handler,const char* description=0); - Bit16u Get_callback() { - return (Bit16u)m_callback; - } - RealPt Get_RealPointer() { - return CALLBACK_RealPointer(m_callback); - } - void Set_RealVec(Bit8u vec); -}; -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/control.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/control.h deleted file mode 100644 index 4666a277c..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/control.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_CONTROL_H -#define DOSBOX_CONTROL_H - -#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) -#pragma warning ( disable : 4290 ) -#endif - -#ifndef DOSBOX_PROGRAMS_H -#include "programs.h" -#endif -#ifndef DOSBOX_SETUP_H -#include "setup.h" -#endif - -#ifndef CH_LIST -#define CH_LIST -#include -#endif - -#ifndef CH_VECTOR -#define CH_VECTOR -#include -#endif - -#ifndef CH_STRING -#define CH_STRING -#include -#endif - - - - -class Config{ -public: - CommandLine * cmdline; -private: - std::list sectionlist; - typedef std::list::iterator it; - typedef std::list::reverse_iterator reverse_it; - typedef std::list::const_iterator const_it; - typedef std::list::const_reverse_iterator const_reverse_it; - void (* _start_function)(void); - bool secure_mode; //Sandbox mode -public: - bool initialised; - std::vector startup_params; - std::vector configfiles; - Config(CommandLine * cmd):cmdline(cmd),secure_mode(false) { - startup_params.push_back(cmdline->GetFileName()); - cmdline->FillVector(startup_params); - initialised=false; - } - ~Config(); - - Section_line * AddSection_line(char const * const _name,void (*_initfunction)(Section*)); - Section_prop * AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange=false); - - Section* GetSection(int index); - Section* GetSection(std::string const&_sectionname) const; - Section* GetSectionFromProperty(char const * const prop) const; - - void SetStartUp(void (*_function)(void)); - void Init(); - void ShutDown(); - void StartUp(); - bool PrintConfig(char const * const configfilename) const; - bool ParseConfigFile(char const * const configfilename); - void ParseEnv(char ** envp); - bool SecureMode() const { return secure_mode; } - void SwitchToSecureMode() { secure_mode = true; }//can't be undone -}; - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/cpu.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/cpu.h deleted file mode 100644 index d3d4e0b06..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/cpu.h +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_CPU_H -#define DOSBOX_CPU_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_REGS_H -#include "regs.h" -#endif -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -#define CPU_AUTODETERMINE_NONE 0x00 -#define CPU_AUTODETERMINE_CORE 0x01 -#define CPU_AUTODETERMINE_CYCLES 0x02 - -#define CPU_AUTODETERMINE_SHIFT 0x02 -#define CPU_AUTODETERMINE_MASK 0x03 - -#define CPU_CYCLES_LOWER_LIMIT 200 - - -#define CPU_ARCHTYPE_MIXED 0xff -#define CPU_ARCHTYPE_386SLOW 0x30 -#define CPU_ARCHTYPE_386FAST 0x35 -#define CPU_ARCHTYPE_486OLDSLOW 0x40 -#define CPU_ARCHTYPE_486NEWSLOW 0x45 -#define CPU_ARCHTYPE_PENTIUMSLOW 0x50 - -/* CPU Cycle Timing */ -extern Bit32s CPU_Cycles; -extern Bit32s CPU_CycleLeft; -extern Bit32s CPU_CycleMax; -extern Bit32s CPU_OldCycleMax; -extern Bit32s CPU_CyclePercUsed; -extern Bit32s CPU_CycleLimit; -extern Bit64s CPU_IODelayRemoved; -extern bool CPU_CycleAutoAdjust; -extern bool CPU_SkipCycleAutoAdjust; -extern Bitu CPU_AutoDetermineMode; - -extern Bitu CPU_ArchitectureType; - -extern Bitu CPU_PrefetchQueueSize; - -/* Some common Defines */ -/* A CPU Handler */ -typedef Bits (CPU_Decoder)(void); -extern CPU_Decoder * cpudecoder; - -Bits CPU_Core_Normal_Run(void); -Bits CPU_Core_Normal_Trap_Run(void); -Bits CPU_Core_Simple_Run(void); -Bits CPU_Core_Full_Run(void); -Bits CPU_Core_Dyn_X86_Run(void); -Bits CPU_Core_Dyn_X86_Trap_Run(void); -Bits CPU_Core_Dynrec_Run(void); -Bits CPU_Core_Dynrec_Trap_Run(void); -Bits CPU_Core_Prefetch_Run(void); -Bits CPU_Core_Prefetch_Trap_Run(void); - -void CPU_Enable_SkipAutoAdjust(void); -void CPU_Disable_SkipAutoAdjust(void); -void CPU_Reset_AutoAdjust(void); - - -//CPU Stuff - -extern Bit16u parity_lookup[256]; - -bool CPU_LLDT(Bitu selector); -bool CPU_LTR(Bitu selector); -void CPU_LIDT(Bitu limit,Bitu base); -void CPU_LGDT(Bitu limit,Bitu base); - -Bitu CPU_STR(void); -Bitu CPU_SLDT(void); -Bitu CPU_SIDT_base(void); -Bitu CPU_SIDT_limit(void); -Bitu CPU_SGDT_base(void); -Bitu CPU_SGDT_limit(void); - -void CPU_ARPL(Bitu & dest_sel,Bitu src_sel); -void CPU_LAR(Bitu selector,Bitu & ar); -void CPU_LSL(Bitu selector,Bitu & limit); - -void CPU_SET_CRX(Bitu cr,Bitu value); -bool CPU_WRITE_CRX(Bitu cr,Bitu value); -Bitu CPU_GET_CRX(Bitu cr); -bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue); - -bool CPU_WRITE_DRX(Bitu dr,Bitu value); -bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue); - -bool CPU_WRITE_TRX(Bitu dr,Bitu value); -bool CPU_READ_TRX(Bitu dr,Bit32u & retvalue); - -Bitu CPU_SMSW(void); -bool CPU_LMSW(Bitu word); - -void CPU_VERR(Bitu selector); -void CPU_VERW(Bitu selector); - -void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip); -void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip); -void CPU_RET(bool use32,Bitu bytes,Bitu oldeip); -void CPU_IRET(bool use32,Bitu oldeip); -void CPU_HLT(Bitu oldeip); - -bool CPU_POPF(Bitu use32); -bool CPU_PUSHF(Bitu use32); -bool CPU_CLI(void); -bool CPU_STI(void); - -bool CPU_IO_Exception(Bitu port,Bitu size); -void CPU_RunException(void); - -void CPU_ENTER(bool use32,Bitu bytes,Bitu level); - -#define CPU_INT_SOFTWARE 0x1 -#define CPU_INT_EXCEPTION 0x2 -#define CPU_INT_HAS_ERROR 0x4 -#define CPU_INT_NOIOPLCHECK 0x8 - -void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip); -static INLINE void CPU_HW_Interrupt(Bitu num) { - CPU_Interrupt(num,0,reg_eip); -} -static INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { - CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip); -} -static INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) { - CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip); -} - -bool CPU_PrepareException(Bitu which,Bitu error); -void CPU_Exception(Bitu which,Bitu error=0); - -bool CPU_SetSegGeneral(SegNames seg,Bitu value); -bool CPU_PopSeg(SegNames seg,bool use32); - -bool CPU_CPUID(void); -Bitu CPU_Pop16(void); -Bitu CPU_Pop32(void); -void CPU_Push16(Bitu value); -void CPU_Push32(Bitu value); - -void CPU_SetFlags(Bitu word,Bitu mask); - - -#define EXCEPTION_UD 6 -#define EXCEPTION_TS 10 -#define EXCEPTION_NP 11 -#define EXCEPTION_SS 12 -#define EXCEPTION_GP 13 -#define EXCEPTION_PF 14 - -#define CR0_PROTECTION 0x00000001 -#define CR0_MONITORPROCESSOR 0x00000002 -#define CR0_FPUEMULATION 0x00000004 -#define CR0_TASKSWITCH 0x00000008 -#define CR0_FPUPRESENT 0x00000010 -#define CR0_PAGING 0x80000000 - - -// ********************************************************************* -// Descriptor -// ********************************************************************* - -#define DESC_INVALID 0x00 -#define DESC_286_TSS_A 0x01 -#define DESC_LDT 0x02 -#define DESC_286_TSS_B 0x03 -#define DESC_286_CALL_GATE 0x04 -#define DESC_TASK_GATE 0x05 -#define DESC_286_INT_GATE 0x06 -#define DESC_286_TRAP_GATE 0x07 - -#define DESC_386_TSS_A 0x09 -#define DESC_386_TSS_B 0x0b -#define DESC_386_CALL_GATE 0x0c -#define DESC_386_INT_GATE 0x0e -#define DESC_386_TRAP_GATE 0x0f - -/* EU/ED Expand UP/DOWN RO/RW Read Only/Read Write NA/A Accessed */ -#define DESC_DATA_EU_RO_NA 0x10 -#define DESC_DATA_EU_RO_A 0x11 -#define DESC_DATA_EU_RW_NA 0x12 -#define DESC_DATA_EU_RW_A 0x13 -#define DESC_DATA_ED_RO_NA 0x14 -#define DESC_DATA_ED_RO_A 0x15 -#define DESC_DATA_ED_RW_NA 0x16 -#define DESC_DATA_ED_RW_A 0x17 - -/* N/R Readable NC/C Confirming A/NA Accessed */ -#define DESC_CODE_N_NC_A 0x18 -#define DESC_CODE_N_NC_NA 0x19 -#define DESC_CODE_R_NC_A 0x1a -#define DESC_CODE_R_NC_NA 0x1b -#define DESC_CODE_N_C_A 0x1c -#define DESC_CODE_N_C_NA 0x1d -#define DESC_CODE_R_C_A 0x1e -#define DESC_CODE_R_C_NA 0x1f - -#ifdef _MSC_VER -#pragma pack (1) -#endif - -struct S_Descriptor { -#ifdef WORDS_BIGENDIAN - Bit32u base_0_15 :16; - Bit32u limit_0_15 :16; - Bit32u base_24_31 :8; - Bit32u g :1; - Bit32u big :1; - Bit32u r :1; - Bit32u avl :1; - Bit32u limit_16_19 :4; - Bit32u p :1; - Bit32u dpl :2; - Bit32u type :5; - Bit32u base_16_23 :8; -#else - Bit32u limit_0_15 :16; - Bit32u base_0_15 :16; - Bit32u base_16_23 :8; - Bit32u type :5; - Bit32u dpl :2; - Bit32u p :1; - Bit32u limit_16_19 :4; - Bit32u avl :1; - Bit32u r :1; - Bit32u big :1; - Bit32u g :1; - Bit32u base_24_31 :8; -#endif -}GCC_ATTRIBUTE(packed); - -struct G_Descriptor { -#ifdef WORDS_BIGENDIAN - Bit32u selector: 16; - Bit32u offset_0_15 :16; - Bit32u offset_16_31 :16; - Bit32u p :1; - Bit32u dpl :2; - Bit32u type :5; - Bit32u reserved :3; - Bit32u paramcount :5; -#else - Bit32u offset_0_15 :16; - Bit32u selector :16; - Bit32u paramcount :5; - Bit32u reserved :3; - Bit32u type :5; - Bit32u dpl :2; - Bit32u p :1; - Bit32u offset_16_31 :16; -#endif -} GCC_ATTRIBUTE(packed); - -struct TSS_16 { - Bit16u back; /* Back link to other task */ - Bit16u sp0; /* The CK stack pointer */ - Bit16u ss0; /* The CK stack selector */ - Bit16u sp1; /* The parent KL stack pointer */ - Bit16u ss1; /* The parent KL stack selector */ - Bit16u sp2; /* Unused */ - Bit16u ss2; /* Unused */ - Bit16u ip; /* The instruction pointer */ - Bit16u flags; /* The flags */ - Bit16u ax, cx, dx, bx; /* The general purpose registers */ - Bit16u sp, bp, si, di; /* The special purpose registers */ - Bit16u es; /* The extra selector */ - Bit16u cs; /* The code selector */ - Bit16u ss; /* The application stack selector */ - Bit16u ds; /* The data selector */ - Bit16u ldt; /* The local descriptor table */ -} GCC_ATTRIBUTE(packed); - -struct TSS_32 { - Bit32u back; /* Back link to other task */ - Bit32u esp0; /* The CK stack pointer */ - Bit32u ss0; /* The CK stack selector */ - Bit32u esp1; /* The parent KL stack pointer */ - Bit32u ss1; /* The parent KL stack selector */ - Bit32u esp2; /* Unused */ - Bit32u ss2; /* Unused */ - Bit32u cr3; /* The page directory pointer */ - Bit32u eip; /* The instruction pointer */ - Bit32u eflags; /* The flags */ - Bit32u eax, ecx, edx, ebx; /* The general purpose registers */ - Bit32u esp, ebp, esi, edi; /* The special purpose registers */ - Bit32u es; /* The extra selector */ - Bit32u cs; /* The code selector */ - Bit32u ss; /* The application stack selector */ - Bit32u ds; /* The data selector */ - Bit32u fs; /* And another extra selector */ - Bit32u gs; /* ... and another one */ - Bit32u ldt; /* The local descriptor table */ -} GCC_ATTRIBUTE(packed); - -#ifdef _MSC_VER -#pragma pack() -#endif -class Descriptor -{ -public: - Descriptor() { saved.fill[0]=saved.fill[1]=0; } - - void Load(PhysPt address); - void Save(PhysPt address); - - PhysPt GetBase (void) { - return (saved.seg.base_24_31<<24) | (saved.seg.base_16_23<<16) | saved.seg.base_0_15; - } - Bitu GetLimit (void) { - Bitu limit = (saved.seg.limit_16_19<<16) | saved.seg.limit_0_15; - if (saved.seg.g) return (limit<<12) | 0xFFF; - return limit; - } - Bitu GetOffset(void) { - return (saved.gate.offset_16_31 << 16) | saved.gate.offset_0_15; - } - Bitu GetSelector(void) { - return saved.gate.selector; - } - Bitu Type(void) { - return saved.seg.type; - } - Bitu Conforming(void) { - return saved.seg.type & 8; - } - Bitu DPL(void) { - return saved.seg.dpl; - } - Bitu Big(void) { - return saved.seg.big; - } -public: - union { - S_Descriptor seg; - G_Descriptor gate; - Bit32u fill[2]; - } saved; -}; - -class DescriptorTable { -public: - PhysPt GetBase (void) { return table_base; } - Bitu GetLimit (void) { return table_limit; } - void SetBase (PhysPt _base) { table_base = _base; } - void SetLimit (Bitu _limit) { table_limit= _limit; } - - bool GetDescriptor (Bitu selector, Descriptor& desc) { - selector&=~7; - if (selector>=table_limit) return false; - desc.Load(table_base+(selector)); - return true; - } -protected: - PhysPt table_base; - Bitu table_limit; -}; - -class GDTDescriptorTable : public DescriptorTable { -public: - bool GetDescriptor(Bitu selector, Descriptor& desc) { - Bitu address=selector & ~7; - if (selector & 4) { - if (address>=ldt_limit) return false; - desc.Load(ldt_base+address); - return true; - } else { - if (address>=table_limit) return false; - desc.Load(table_base+address); - return true; - } - } - bool SetDescriptor(Bitu selector, Descriptor& desc) { - Bitu address=selector & ~7; - if (selector & 4) { - if (address>=ldt_limit) return false; - desc.Save(ldt_base+address); - return true; - } else { - if (address>=table_limit) return false; - desc.Save(table_base+address); - return true; - } - } - Bitu SLDT(void) { - return ldt_value; - } - bool LLDT(Bitu value) { - if ((value&0xfffc)==0) { - ldt_value=0; - ldt_base=0; - ldt_limit=0; - return true; - } - Descriptor desc; - if (!GetDescriptor(value,desc)) return !CPU_PrepareException(EXCEPTION_GP,value); - if (desc.Type()!=DESC_LDT) return !CPU_PrepareException(EXCEPTION_GP,value); - if (!desc.saved.seg.p) return !CPU_PrepareException(EXCEPTION_NP,value); - ldt_base=desc.GetBase(); - ldt_limit=desc.GetLimit(); - ldt_value=value; - return true; - } -private: - PhysPt ldt_base; - Bitu ldt_limit; - Bitu ldt_value; -}; - -class TSS_Descriptor : public Descriptor { -public: - Bitu IsBusy(void) { - return saved.seg.type & 2; - } - Bitu Is386(void) { - return saved.seg.type & 8; - } - void SetBusy(bool busy) { - if (busy) saved.seg.type|=2; - else saved.seg.type&=~2; - } -}; - - -struct CPUBlock { - Bitu cpl; /* Current Privilege */ - Bitu mpl; - Bitu cr0; - bool pmode; /* Is Protected mode enabled */ - GDTDescriptorTable gdt; - DescriptorTable idt; - struct { - Bitu mask,notmask; - bool big; - } stack; - struct { - bool big; - } code; - struct { - Bitu cs,eip; - CPU_Decoder * old_decoder; - } hlt; - struct { - Bitu which,error; - } exception; - Bits direction; - bool trap_skip; - Bit32u drx[8]; - Bit32u trx[8]; -}; - -//extern CPUBlock cpu; - -INLINE void I386_DOSBOX::CPU_SetFlagsd(Bitu word) { - Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; - CPU_SetFlags(word,mask); -} - -INLINE void I386_DOSBOX::CPU_SetFlagsw(Bitu word) { - Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; - CPU_SetFlags(word,mask); -} - - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/cross.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/cross.h deleted file mode 100644 index bcc548430..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/cross.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2002-2017 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Wengier: LFN support - */ - - -#ifndef DOSBOX_CROSS_H -#define DOSBOX_CROSS_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -#include -#include -#include -#include - -#if defined (_MSC_VER) /* MS Visual C++ */ -#include -#include -#define LONGTYPE(a) a##i64 -#define snprintf _snprintf -#define vsnprintf _vsnprintf -#else /* LINUX / GCC */ -#include -#include -#define LONGTYPE(a) a##LL -#endif - -#define CROSS_LEN 512 /* Maximum filename size */ - - -#if defined (WIN32) || defined (OS2) /* Win 32 & OS/2*/ -#define CROSS_FILENAME(blah) -#define CROSS_FILESPLIT '\\' -#define F_OK 0 -#else -#define CROSS_FILENAME(blah) strreplace(blah,'\\','/') -#define CROSS_FILESPLIT '/' -#endif - -#define CROSS_NONE 0 -#define CROSS_FILE 1 -#define CROSS_DIR 2 -#if defined (WIN32) -#define ftruncate(blah,blah2) chsize(blah,blah2) -#endif - -//Solaris maybe others -#if defined (DB_HAVE_NO_POWF) -#include -static inline float powf (float x, float y) { return (float) pow (x,y); } -#endif - -class Cross { -public: - static void GetPlatformConfigDir(std::string& in); - static void GetPlatformConfigName(std::string& in); - static void CreatePlatformConfigDir(std::string& in); - static void ResolveHomedir(std::string & temp_line); - static void CreateDir(std::string const& temp); - static bool IsPathAbsolute(std::string const& in); -}; - - -#if defined (WIN32) - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from -#include - -typedef struct dir_struct { - HANDLE handle; - char base_path[MAX_PATH+4]; - WIN32_FIND_DATA search_data; -} dir_information; - -#else - -//#include //Included above -#include - -typedef struct dir_struct { - DIR* dir; - char base_path[CROSS_LEN]; -} dir_information; - -#endif - -dir_information* open_directory(const char* dirname); -bool read_directory_first(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory); -bool read_directory_next(dir_information* dirp, char* entry_name, char* entry_sname, bool& is_directory); -void close_directory(dir_information* dirp); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/debug.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/debug.h deleted file mode 100644 index 9e214629e..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/debug.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -void DEBUG_SetupConsole(void); -void DEBUG_DrawScreen(void); -bool DEBUG_Breakpoint(void); -bool DEBUG_IntBreakpoint(Bit8u intNum); -void DEBUG_Enable(bool pressed); -void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off); -bool DEBUG_ExitLoop(void); -void DEBUG_RefreshPage(char scroll); -Bitu DEBUG_EnableDebugger(void); - -extern Bitu cycle_count; -extern Bitu debugCallback; - -#ifdef C_HEAVY_DEBUG -bool DEBUG_HeavyIsBreakpoint(void); -void DEBUG_HeavyWriteLogInstruction(void); -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/dma.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/dma.h deleted file mode 100644 index 38531811c..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/dma.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_DMA_H -#define DOSBOX_DMA_H - -enum DMAEvent { - DMA_REACHED_TC, - DMA_MASKED, - DMA_UNMASKED, - DMA_TRANSFEREND -}; - -class DmaChannel; -typedef void (* DMA_CallBack)(DmaChannel * chan,DMAEvent event); - -class DmaChannel { -public: - Bit32u pagebase; - Bit16u baseaddr; - Bit32u curraddr; - Bit16u basecnt; - Bit16u currcnt; - Bit8u channum; - Bit8u pagenum; - Bit8u DMA16; - bool increment; - bool autoinit; - Bit8u trantype; - bool masked; - bool tcount; - bool request; - DMA_CallBack callback; - - DmaChannel(Bit8u num, bool dma16); - void DoCallBack(DMAEvent event) { - if (callback) (*callback)(this,event); - } - void SetMask(bool _mask) { - masked=_mask; - DoCallBack(masked ? DMA_MASKED : DMA_UNMASKED); - } - void Register_Callback(DMA_CallBack _cb) { - callback = _cb; - SetMask(masked); - if (callback) Raise_Request(); - else Clear_Request(); - } - void ReachedTC(void) { - tcount=true; - DoCallBack(DMA_REACHED_TC); - } - void SetPage(Bit8u val) { - pagenum=val; - pagebase=(pagenum >> DMA16) << (16+DMA16); - } - void Raise_Request(void) { - request=true; - } - void Clear_Request(void) { - request=false; - } - Bitu Read(Bitu size, Bit8u * buffer); - Bitu Write(Bitu size, Bit8u * buffer); -}; - -class DmaController { -private: - Bit8u ctrlnum; - bool flipflop; - DmaChannel *DmaChannels[4]; -public: - IO_ReadHandleObject DMA_ReadHandler[0x11]; - IO_WriteHandleObject DMA_WriteHandler[0x11]; - DmaController(Bit8u num) { - flipflop = false; - ctrlnum = num; /* first or second DMA controller */ - for(Bit8u i=0;i<4;i++) { - DmaChannels[i] = new DmaChannel(i+ctrlnum*4,ctrlnum==1); - } - } - ~DmaController(void) { - for(Bit8u i=0;i<4;i++) { - delete DmaChannels[i]; - } - } - DmaChannel * GetChannel(Bit8u chan) { - if (chan<4) return DmaChannels[chan]; - else return NULL; - } - void WriteControllerReg(Bitu reg,Bitu val,Bitu len); - Bitu ReadControllerReg(Bitu reg,Bitu len); -}; - -DmaChannel * GetDMAChannel(Bit8u chan); - -void CloseSecondDMAController(void); -bool SecondDMAControllerAvailable(void); - -void DMA_SetWrapping(Bitu wrap); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/dos_inc.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/dos_inc.h deleted file mode 100644 index 624dd89aa..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/dos_inc.h +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright (C) 2002-2017 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Wengier: LFN support - */ - - -#ifndef DOSBOX_DOS_INC_H -#define DOSBOX_DOS_INC_H - -#ifndef DOSBOX_DOS_SYSTEM_H -#include "dos_system.h" -#endif -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -#include //for offsetof -#define CTBUF 127 - -#ifdef _MSC_VER -#pragma pack (1) -#endif -struct CommandTail{ - Bit8u count; /* number of bytes returned */ - char buffer[CTBUF]; /* the buffer itself */ -} GCC_ATTRIBUTE(packed); -#ifdef _MSC_VER -#pragma pack () -#endif - -struct DOS_Date { - Bit16u year; - Bit8u month; - Bit8u day; -}; - -struct DOS_Version { - Bit8u major,minor,revision; -}; - - -#ifdef _MSC_VER -#pragma pack (1) -#endif -union bootSector { - struct entries { - Bit8u jump[3]; - Bit8u oem_name[8]; - Bit16u bytesect; - Bit8u sectclust; - Bit16u reserve_sect; - Bit8u misc[496]; - } bootdata; - Bit8u rawdata[512]; -} GCC_ATTRIBUTE(packed); -#ifdef _MSC_VER -#pragma pack () -#endif - - -enum { MCB_FREE=0x0000,MCB_DOS=0x0008 }; -enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; - -#define DOS_FILES 127 -#define DOS_DRIVES 26 -#define DOS_DEVICES 20 - - -// dos swappable area is 0x320 bytes beyond the sysvars table -// device driver chain is inside sysvars -#define DOS_INFOBLOCK_SEG 0x80 // sysvars (list of lists) -#define DOS_CONDRV_SEG 0xa0 -#define DOS_CONSTRING_SEG 0xa8 -#define DOS_SDA_SEG 0xb2 // dos swappable area -#define DOS_SDA_OFS 0 -#define DOS_CDS_SEG 0x108 -#define DOS_FIRST_SHELL 0x118 -#define DOS_MEM_START 0x16f //First Segment that DOS can use - -#define DOS_PRIVATE_SEGMENT 0xc800 -#define DOS_PRIVATE_SEGMENT_END 0xd000 - -/* internal Dos Tables */ - -extern DOS_File * Files[DOS_FILES]; -extern DOS_Drive * Drives[DOS_DRIVES]; -extern DOS_Device * Devices[DOS_DEVICES]; - -extern Bit8u dos_copybuf[0x10000]; - - -void DOS_SetError(Bit16u code); - -/* File Handling Routines */ - -enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDPRN=4}; -enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE}; - -/* Routines for File Class */ -void DOS_SetupFiles (void); -bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount, bool fcb = false); -bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount,bool fcb = false); -bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type,bool fcb = false); -bool DOS_CloseFile(Bit16u handle,bool fcb = false); -bool DOS_FlushFile(Bit16u handle); -bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); -bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry); -bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate); - -/* Routines for Drive Class */ -bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry,bool fcb = false); -bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status); -bool DOS_CreateFile(char const * name,Bit16u attribute,Bit16u * entry, bool fcb = false); -bool DOS_UnlinkFile(char const * const name); -bool DOS_GetSFNPath(char const * const path, char *SFNpath, bool LFN); -bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false); -bool DOS_FindNext(void); -bool DOS_Canonicalize(char const * const name,char * const big); -bool DOS_CreateTempFile(char * const name,Bit16u * entry); -bool DOS_FileExists(char const * const name); - -/* Helper Functions */ -bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive); -/* Drive Handing Routines */ -Bit8u DOS_GetDefaultDrive(void); -void DOS_SetDefaultDrive(Bit8u drive); -bool DOS_SetDrive(Bit8u drive); -bool DOS_GetCurrentDir(Bit8u drive,char * const buffer, bool LFN); -bool DOS_ChangeDir(char const * const dir); -bool DOS_MakeDir(char const * const dir); -bool DOS_RemoveDir(char const * const dir); -bool DOS_Rename(char const * const oldname,char const * const newname); -bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free); -bool DOS_GetFileAttr(char const * const name,Bit16u * attr); -bool DOS_SetFileAttr(char const * const name,Bit16u attr); -bool DOS_GetFileAttrEx(char const* const name, struct stat *status, Bit8u hdrive=-1); -DWORD DOS_GetCompressedFileSize(char const* const name); -HANDLE DOS_CreateOpenFile(char const* const name); - -/* IOCTL Stuff */ -bool DOS_IOCTL(void); -bool DOS_GetSTDINStatus(); -Bit8u DOS_FindDevice(char const * name); -void DOS_SetupDevices(void); -void DOS_ClearKeyMap(void); - -/* Execute and new process creation */ -bool DOS_NewPSP(Bit16u pspseg,Bit16u size); -bool DOS_ChildPSP(Bit16u pspseg,Bit16u size); -bool DOS_Execute(char * name,PhysPt block,Bit8u flags); -void DOS_Terminate(Bit16u pspseg,bool tsr,Bit8u exitcode); - -/* Memory Handling Routines */ -void DOS_SetupMemory(void); -bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks); -bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks); -bool DOS_FreeMemory(Bit16u segment); -void DOS_FreeProcessMemory(Bit16u pspseg); -Bit16u DOS_GetMemory(Bit16u pages); -bool DOS_SetMemAllocStrategy(Bit16u strat); -Bit16u DOS_GetMemAllocStrategy(void); -void DOS_BuildUMBChain(bool umb_active,bool ems_active); -bool DOS_LinkUMBsToMemChain(Bit16u linkstate); - -/* FCB stuff */ -bool DOS_FCBOpen(Bit16u seg,Bit16u offset); -bool DOS_FCBCreate(Bit16u seg,Bit16u offset); -bool DOS_FCBClose(Bit16u seg,Bit16u offset); -bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset); -bool DOS_FCBFindNext(Bit16u seg,Bit16u offset); -Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset, Bit16u numBlocks); -Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks); -Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore); -Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u * numRec,bool restore); -bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset); -bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset); -bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset); -void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset); -Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change); -bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters); - -/* Extra DOS Interrupts */ -void DOS_SetupMisc(void); - -/* The DOS Tables */ -void DOS_SetupTables(void); - -/* Internal DOS Setup Programs */ -void DOS_SetupPrograms(void); - -/* Initialize Keyboard Layout */ -void DOS_KeyboardLayout_Init(Section* sec); - -bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3); - -enum { - KEYB_NOERROR=0, - KEYB_FILENOTFOUND, - KEYB_INVALIDFILE, - KEYB_LAYOUTNOTFOUND, - KEYB_INVALIDCPFILE -}; - - -static INLINE Bit16u long2para(Bit32u size) { - if (size>0xFFFF0) return 0xffff; - if (size&0xf) return (Bit16u)((size>>4)+1); - else return (Bit16u)(size>>4); -} - - -static INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) { - return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f); -} - -static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { - return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f); -} - -/* Dos Error Codes */ -#define DOSERR_NONE 0 -#define DOSERR_FUNCTION_NUMBER_INVALID 1 -#define DOSERR_FILE_NOT_FOUND 2 -#define DOSERR_PATH_NOT_FOUND 3 -#define DOSERR_TOO_MANY_OPEN_FILES 4 -#define DOSERR_ACCESS_DENIED 5 -#define DOSERR_INVALID_HANDLE 6 -#define DOSERR_MCB_DESTROYED 7 -#define DOSERR_INSUFFICIENT_MEMORY 8 -#define DOSERR_MB_ADDRESS_INVALID 9 -#define DOSERR_ENVIRONMENT_INVALID 10 -#define DOSERR_FORMAT_INVALID 11 -#define DOSERR_ACCESS_CODE_INVALID 12 -#define DOSERR_DATA_INVALID 13 -#define DOSERR_RESERVED 14 -#define DOSERR_FIXUP_OVERFLOW 14 -#define DOSERR_INVALID_DRIVE 15 -#define DOSERR_REMOVE_CURRENT_DIRECTORY 16 -#define DOSERR_NOT_SAME_DEVICE 17 -#define DOSERR_NO_MORE_FILES 18 -#define DOSERR_WRITE_PROTECTED_DISK 19 -#define DOSERR_FILE_ALREADY_EXISTS 80 - - -/* Remains some classes used to access certain things */ -#define sOffset(s,m) ((char*)&(((s*)NULL)->m)-(char*)NULL) -#define sGet(s,m) GetIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m)) -#define sSave(s,m,val) SaveIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m),val) - -class MemStruct { -public: - Bitu GetIt(Bitu size,PhysPt addr) { - switch (size) { - case 1:return mem_readb(pt+addr); - case 2:return mem_readw(pt+addr); - case 4:return mem_readd(pt+addr); - } - return 0; - } - void SaveIt(Bitu size,PhysPt addr,Bitu val) { - switch (size) { - case 1:mem_writeb(pt+addr,(Bit8u)val);break; - case 2:mem_writew(pt+addr,(Bit16u)val);break; - case 4:mem_writed(pt+addr,(Bit32u)val);break; - } - } - void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} - void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);} - void SetPt(RealPt addr) { pt=Real2Phys(addr);} -protected: - PhysPt pt; -}; - -class DOS_PSP :public MemStruct { -public: - DOS_PSP (Bit16u segment) { SetPt(segment);seg=segment;}; - void MakeNew (Bit16u memSize); - void CopyFileTable (DOS_PSP* srcpsp,bool createchildpsp); - Bit16u FindFreeFileEntry (void); - void CloseFiles (void); - - void SaveVectors (void); - void RestoreVectors (void); - void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); }; - Bit16u GetSize (void) { return (Bit16u)sGet(sPSP,next_seg); }; - void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); }; - Bit16u GetEnvironment (void) { return (Bit16u)sGet(sPSP,environment); }; - Bit16u GetSegment (void) { return seg; }; - void SetFileHandle (Bit16u index, Bit8u handle); - Bit8u GetFileHandle (Bit16u index); - void SetParent (Bit16u parent) { sSave(sPSP,psp_parent,parent); }; - Bit16u GetParent (void) { return (Bit16u)sGet(sPSP,psp_parent); }; - void SetStack (RealPt stackpt) { sSave(sPSP,stack,stackpt); }; - RealPt GetStack (void) { return sGet(sPSP,stack); }; - void SetInt22 (RealPt int22pt) { sSave(sPSP,int_22,int22pt); }; - RealPt GetInt22 (void) { return sGet(sPSP,int_22); }; - void SetFCB1 (RealPt src); - void SetFCB2 (RealPt src); - void SetCommandTail (RealPt src); - void StoreCommandTail (void); - void RestoreCommandTail (void); - bool SetNumFiles (Bit16u fileNum); - Bit16u FindEntryByHandle (Bit8u handle); - -private: - #ifdef _MSC_VER - #pragma pack(1) - #endif - struct sPSP { - Bit8u exit[2]; /* CP/M-like exit poimt */ - Bit16u next_seg; /* Segment of first byte beyond memory allocated or program */ - Bit8u fill_1; /* single char fill */ - Bit8u far_call; /* far call opcode */ - RealPt cpm_entry; /* CPM Service Request address*/ - RealPt int_22; /* Terminate Address */ - RealPt int_23; /* Break Address */ - RealPt int_24; /* Critical Error Address */ - Bit16u psp_parent; /* Parent PSP Segment */ - Bit8u files[20]; /* File Table - 0xff is unused */ - Bit16u environment; /* Segment of evironment table */ - RealPt stack; /* SS:SP Save point for int 0x21 calls */ - Bit16u max_files; /* Maximum open files */ - RealPt file_table; /* Pointer to File Table PSP:0x18 */ - RealPt prev_psp; /* Pointer to previous PSP */ - Bit8u interim_flag; - Bit8u truename_flag; - Bit16u nn_flags; - Bit16u dos_version; - Bit8u fill_2[14]; /* Lot's of unused stuff i can't care aboue */ - Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */ - Bit8u fill_3[9]; /* This has some blocks with FCB info */ - Bit8u fcb1[16]; /* first FCB */ - Bit8u fcb2[16]; /* second FCB */ - Bit8u fill_4[4]; /* unused */ - CommandTail cmdtail; - } GCC_ATTRIBUTE(packed); - #ifdef _MSC_VER - #pragma pack() - #endif - Bit16u seg; -public: - static Bit16u rootpsp; -}; - -class DOS_ParamBlock:public MemStruct { -public: - DOS_ParamBlock(PhysPt addr) {pt=addr;} - void Clear(void); - void LoadData(void); - void SaveData(void); /* Save it as an exec block */ - #ifdef _MSC_VER - #pragma pack (1) - #endif - struct sOverlay { - Bit16u loadseg; - Bit16u relocation; - } GCC_ATTRIBUTE(packed); - struct sExec { - Bit16u envseg; - RealPt cmdtail; - RealPt fcb1; - RealPt fcb2; - RealPt initsssp; - RealPt initcsip; - }GCC_ATTRIBUTE(packed); - #ifdef _MSC_VER - #pragma pack() - #endif - sExec exec; - sOverlay overlay; -}; - -class DOS_InfoBlock:public MemStruct { -public: - DOS_InfoBlock () {}; - void SetLocation(Bit16u seg); - void SetFirstMCB(Bit16u _first_mcb); - void SetBuffers(Bit16u x,Bit16u y); - void SetCurDirStruct(Bit32u _curdirstruct); - void SetFCBTable(Bit32u _fcbtable); - void SetDeviceChainStart(Bit32u _devchain); - void SetDiskBufferHeadPt(Bit32u _dbheadpt); - void SetStartOfUMBChain(Bit16u _umbstartseg); - void SetUMBChainState(Bit8u _umbchaining); - Bit16u GetStartOfUMBChain(void); - Bit8u GetUMBChainState(void); - RealPt GetPointer(void); - Bit32u GetDeviceChain(void); - - #ifdef _MSC_VER - #pragma pack(1) - #endif - struct sDIB { - Bit8u unknown1[4]; - Bit16u magicWord; // -0x22 needs to be 1 - Bit8u unknown2[8]; - Bit16u regCXfrom5e; // -0x18 CX from last int21/ah=5e - Bit16u countLRUcache; // -0x16 LRU counter for FCB caching - Bit16u countLRUopens; // -0x14 LRU counter for FCB openings - Bit8u stuff[6]; // -0x12 some stuff, hopefully never used.... - Bit16u sharingCount; // -0x0c sharing retry count - Bit16u sharingDelay; // -0x0a sharing retry delay - RealPt diskBufPtr; // -0x08 pointer to disk buffer - Bit16u ptrCONinput; // -0x04 pointer to con input - Bit16u firstMCB; // -0x02 first memory control block - RealPt firstDPB; // 0x00 first drive parameter block - RealPt firstFileTable; // 0x04 first system file table - RealPt activeClock; // 0x08 active clock device header - RealPt activeCon; // 0x0c active console device header - Bit16u maxSectorLength; // 0x10 maximum bytes per sector of any block device; - RealPt diskInfoBuffer; // 0x12 pointer to disk info buffer - RealPt curDirStructure; // 0x16 pointer to current array of directory structure - RealPt fcbTable; // 0x1a pointer to system FCB table - Bit16u protFCBs; // 0x1e protected fcbs - Bit8u blockDevices; // 0x20 installed block devices - Bit8u lastdrive; // 0x21 lastdrive - Bit32u nulNextDriver; // 0x22 NUL driver next pointer - Bit16u nulAttributes; // 0x26 NUL driver aattributes - Bit32u nulStrategy; // 0x28 NUL driver strategy routine - Bit8u nulString[8]; // 0x2c NUL driver name string - Bit8u joindedDrives; // 0x34 joined drives - Bit16u specialCodeSeg; // 0x35 special code segment - RealPt setverPtr; // 0x37 pointer to setver - Bit16u a20FixOfs; // 0x3b a20 fix routine offset - Bit16u pspLastIfHMA; // 0x3d psp of last program (if dos in hma) - Bit16u buffers_x; // 0x3f x in BUFFERS x,y - Bit16u buffers_y; // 0x41 y in BUFFERS x,y - Bit8u bootDrive; // 0x43 boot drive - Bit8u useDwordMov; // 0x44 use dword moves - Bit16u extendedSize; // 0x45 size of extended memory - Bit32u diskBufferHeadPt; // 0x47 pointer to least-recently used buffer header - Bit16u dirtyDiskBuffers; // 0x4b number of dirty disk buffers - Bit32u lookaheadBufPt; // 0x4d pointer to lookahead buffer - Bit16u lookaheadBufNumber; // 0x51 number of lookahead buffers - Bit8u bufferLocation; // 0x53 workspace buffer location - Bit32u workspaceBuffer; // 0x54 pointer to workspace buffer - Bit8u unknown3[11]; // 0x58 - Bit8u chainingUMB; // 0x63 bit0: UMB chain linked to MCB chain - Bit16u minMemForExec; // 0x64 minimum paragraphs needed for current program - Bit16u startOfUMBChain; // 0x66 segment of first UMB-MCB - Bit16u memAllocScanStart; // 0x68 start paragraph for memory allocation - } GCC_ATTRIBUTE(packed); - #ifdef _MSC_VER - #pragma pack () - #endif - Bit16u seg; -}; - -class DOS_DTA:public MemStruct{ -public: - DOS_DTA(RealPt addr) { SetPt(addr); } - - void SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * _pattern); - void SetResult(const char * _name,const char * _lname,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr); - - int GetFindData(int fmt,char * finddata); - Bit8u GetSearchDrive(void); - void GetSearchParams(Bit8u & _sattr,char * _spattern,bool lfn); - void GetResult(char * _name,char * _lname,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr); - - void SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); }; - void SetDirIDCluster(Bit16u entry) { sSave(sDTA,dirCluster,entry); }; - Bit16u GetDirID(void) { return (Bit16u)sGet(sDTA,dirID); }; - Bit16u GetDirIDCluster(void) { return (Bit16u)sGet(sDTA,dirCluster); }; -private: - #ifdef _MSC_VER - #pragma pack(1) - #endif - struct sDTA { - Bit8u sdrive; /* The Drive the search is taking place */ - Bit8u spname[8]; /* The Search pattern for the filename */ - Bit8u spext[3]; /* The Search pattern for the extenstion */ - Bit8u sattr; /* The Attributes that need to be found */ - Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */ - Bit16u dirCluster; /* custom (drive_fat only): cluster number for multiple searches at the same time */ - Bit8u fill[4]; - Bit8u attr; - Bit16u time; - Bit16u date; - Bit32u size; - char name[DOS_NAMELENGTH_ASCII]; - } GCC_ATTRIBUTE(packed); - #ifdef _MSC_VER - #pragma pack() - #endif -}; - -class DOS_FCB: public MemStruct { -public: - DOS_FCB(Bit16u seg,Bit16u off,bool allow_extended=true); - void Create(bool _extended); - void SetName(Bit8u _drive,char * _fname,char * _ext); - void SetSizeDateTime(Bit32u _size, Bit16u _date, Bit16u _time, bool byFindFCB = false); - void GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time); - void GetName(char * fillname); - void FileOpen(Bit8u _fhandle); - void FileClose(Bit8u & _fhandle); - void GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec); - void SetRecord(Bit16u _cur_block,Bit8u _cur_rec); - void GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size); - void SetSeqData(Bit8u _fhandle,Bit16u _rec_size); - void GetRandom(Bit32u & _random); - void SetRandom(Bit32u _random); - Bit8u GetDrive(void); - bool Extended(void); - void GetAttr(Bit8u & attr); - void SetAttr(Bit8u attr, bool byFindFCB = false); - void SetResult(Bit32u size,Bit16u date,Bit16u time,Bit8u attr); - bool Valid(void); - void ClearBlockRecsize(void); -private: - bool extended; - PhysPt real_pt; - #ifdef _MSC_VER - #pragma pack (1) - #endif - struct sFCB { - Bit8u drive; /* Drive number 0=default, 1=A, etc */ - Bit8u filename[8]; /* Space padded name */ - Bit8u ext[3]; /* Space padded extension */ - Bit16u cur_block; /* Current Block */ - Bit16u rec_size; /* Logical record size */ - Bit32u filesize; /* File Size */ - Bit16u date; - Bit16u time; - /* Reserved Block should be 8 bytes */ - Bit8u sft_entries; - Bit8u share_attributes; - Bit8u extra_info; - /* Maybe swap file_handle and sft_entries now that fcbs - * aren't stored in the psp filetable anymore */ - Bit8u file_handle; - Bit8u reserved[4]; - /* end */ - Bit8u cur_rec; /* Current record in current block */ - Bit32u rndm; /* Current relative record number */ - } GCC_ATTRIBUTE(packed); - #ifdef _MSC_VER - #pragma pack () - #endif -}; - -class DOS_MCB : public MemStruct{ -public: - DOS_MCB(Bit16u seg) { SetPt(seg); } - void SetFileName(char const * const _name) { MEM_BlockWrite(pt+offsetof(sMCB,filename),_name,8); } - void GetFileName(char * const _name) { MEM_BlockRead(pt+offsetof(sMCB,filename),_name,8);_name[8]=0;} - void SetType(Bit8u _type) { sSave(sMCB,type,_type);} - void SetSize(Bit16u _size) { sSave(sMCB,size,_size);} - void SetPSPSeg(Bit16u _pspseg) { sSave(sMCB,psp_segment,_pspseg);} - Bit8u GetType(void) { return (Bit8u)sGet(sMCB,type);} - Bit16u GetSize(void) { return (Bit16u)sGet(sMCB,size);} - Bit16u GetPSPSeg(void) { return (Bit16u)sGet(sMCB,psp_segment);} -private: - #ifdef _MSC_VER - #pragma pack (1) - #endif - struct sMCB { - Bit8u type; - Bit16u psp_segment; - Bit16u size; - Bit8u unused[3]; - Bit8u filename[8]; - } GCC_ATTRIBUTE(packed); - #ifdef _MSC_VER - #pragma pack () - #endif -}; - -class DOS_SDA : public MemStruct { -public: - DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); } - void Init(); - void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); } - void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); } - void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); } - Bit8u GetDrive(void) { return (Bit8u)sGet(sSDA,current_drive); } - Bit16u GetPSP(void) { return (Bit16u)sGet(sSDA,current_psp); } - Bit32u GetDTA(void) { return (Bit32u)sGet(sSDA,current_dta); } - - -private: - #ifdef _MSC_VER - #pragma pack (1) - #endif - struct sSDA { - Bit8u crit_error_flag; /* 0x00 Critical Error Flag */ - Bit8u inDOS_flag; /* 0x01 InDOS flag (count of active INT 21 calls) */ - Bit8u drive_crit_error; /* 0x02 Drive on which current critical error occurred or FFh */ - Bit8u locus_of_last_error; /* 0x03 locus of last error */ - Bit16u extended_error_code; /* 0x04 extended error code of last error */ - Bit8u suggested_action; /* 0x06 suggested action for last error */ - Bit8u error_class; /* 0x07 class of last error*/ - Bit32u last_error_pointer; /* 0x08 ES:DI pointer for last error */ - Bit32u current_dta; /* 0x0C current DTA (Disk Transfer Address) */ - Bit16u current_psp; /* 0x10 current PSP */ - Bit16u sp_int_23; /* 0x12 stores SP across an INT 23 */ - Bit16u return_code; /* 0x14 return code from last process termination (zerod after reading with AH=4Dh) */ - Bit8u current_drive; /* 0x16 current drive */ - Bit8u extended_break_flag; /* 0x17 extended break flag */ - Bit8u fill[2]; /* 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort*/ - } GCC_ATTRIBUTE(packed); - #ifdef _MSC_VER - #pragma pack() - #endif -}; -extern DOS_InfoBlock dos_infoblock; - -struct DOS_Block { - DOS_Date date; - DOS_Version version; - Bit16u firstMCB; - Bit16u errorcode; - Bit16u psp(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();}; - void psp(Bit16u _seg){ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);}; - Bit16u env; - RealPt cpmentry; - RealPt dta(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();}; - void dta(RealPt _dta){DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);}; - Bit8u return_code,return_mode; - - Bit8u current_drive; - bool verify; - bool breakcheck; - bool echo; // if set to true dev_con::read will echo input - bool direct_output; - struct { - RealPt mediaid; - RealPt tempdta; - RealPt tempdta_fcbdelete; - RealPt dbcs; - RealPt filenamechar; - RealPt collatingseq; - RealPt upcase; - //Bit8u* country;//Will be copied to dos memory. resides in real mem - Bit16u dpb; //Fake Disk parameter system using only the first entry so the drive letter matches - Bit16u country_seg; - } tables; - Bit16u loaded_codepage; - - //for AX - bool set_ax_enabled; - - bool set_dosv_enabled; -}; - -extern DOS_Block dos; - -static INLINE Bit8u RealHandle(Bit16u handle) { - DOS_PSP psp(dos.psp()); - return psp.GetFileHandle(handle); -} - -#define IS_DOS_JAPANESE (real_readw(dos.tables.country_seg,5) == 932 && mem_readb(Real2Phys(dos.tables.dbcs) + 0x02) == 0x81) -#define IS_DOSV (dos.set_dosv_enabled) - -#define AUTORELOAD_CMD 0x01 -#define AUTORELOAD_DOS 0x02 -#define AUTORELOAD_ALL 0x03 - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/dos_system.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/dos_system.h deleted file mode 100644 index 1c2709f88..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/dos_system.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) 2002-2017 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Wengier: LFN support - */ - - -#ifndef DOSBOX_DOS_SYSTEM_H -#define DOSBOX_DOS_SYSTEM_H - -#include -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_CROSS_H -#include "cross.h" -#endif -#ifndef DOSBOX_SUPPORT_H -#include "support.h" -#endif -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -#define DOS_NAMELENGTH 12 -#define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1) -#define LFN_NAMELENGTH 255 -#define DOS_FCBNAME 15 -#define DOS_DIRDEPTH 8 -#define DOS_PATHLENGTH 255 -#define DOS_TEMPSIZE 1024 - -enum { - DOS_ATTR_READ_ONLY= 0x01, - DOS_ATTR_HIDDEN= 0x02, - DOS_ATTR_SYSTEM= 0x04, - DOS_ATTR_VOLUME= 0x08, - DOS_ATTR_DIRECTORY= 0x10, - DOS_ATTR_ARCHIVE= 0x20, - DOS_ATTR_DEVICE= 0x40 -}; - -struct FileStat_Block { - Bit32u size; - Bit16u time; - Bit16u date; - Bit16u attr; -}; - -class DOS_DTA; - -class DOS_File { -public: - DOS_File():flags(0) { name=0; refCtr = 0; hdrive=0xff; }; - DOS_File(const DOS_File& orig); - DOS_File & operator= (const DOS_File & orig); - virtual ~DOS_File(){if(name) delete [] name;}; - virtual bool Read(Bit8u * data,Bit16u * size)=0; - virtual bool Write(Bit8u * data,Bit16u * size)=0; - virtual bool Seek(Bit32u * pos,Bit32u type)=0; - virtual bool Close()=0; - virtual Bit16u GetInformation(void)=0; - virtual void SetName(const char* _name) { if (name) delete[] name; name = new char[strlen(_name)+1]; strcpy(name,_name); } - virtual char* GetName(void) { return name; }; - virtual bool IsOpen() { return open; }; - virtual bool IsName(const char* _name) { if (!name) return false; return strcasecmp(name,_name)==0; }; - virtual void AddRef() { refCtr++; }; - virtual Bits RemoveRef() { return --refCtr; }; - virtual bool UpdateDateTimeFromHost() { return true; } - void SetDrive(Bit8u drv) { hdrive=drv;} - Bit8u GetDrive(void) { return hdrive;} - Bit32u flags; - Bit16u time; - Bit16u date; - Bit16u attr; - Bits refCtr; - bool open; - char* name; -/* Some Device Specific Stuff */ -private: - Bit8u hdrive; -}; - -class DOS_Device : public DOS_File { -public: - DOS_Device(const DOS_Device& orig):DOS_File(orig) { - devnum=orig.devnum; - open=true; - } - DOS_Device & operator= (const DOS_Device & orig) { - DOS_File::operator=(orig); - devnum=orig.devnum; - open=true; - return *this; - } - DOS_Device():DOS_File(),devnum(0){}; - virtual bool Read(Bit8u * data,Bit16u * size); - virtual bool Write(Bit8u * data,Bit16u * size); - virtual bool Seek(Bit32u * pos,Bit32u type); - virtual bool Close(); - virtual Bit16u GetInformation(void); - virtual bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); - virtual bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode); - void SetDeviceNumber(Bitu num) { devnum=num;} -private: - Bitu devnum; -}; - -/* The following variable can be lowered to free up some memory. - * The negative side effect: The stored searches will be turned over faster. - * Should not have impact on systems with few directory entries. */ -#define MAX_OPENDIRS 2048 -//Can be high as it's only storage (16 bit variable) - -class DOS_Drive_Cache { -public: - DOS_Drive_Cache (void); - DOS_Drive_Cache (const char* path); - ~DOS_Drive_Cache (void); - - enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; - - void SetBaseDir (const char* path); - void SetDirSort (TDirSort sort) { sortDirType = sort; }; - bool OpenDir (const char* path, Bit16u& id); - bool ReadDir (Bit16u id, char* &result, char * &lresult); - - void ExpandName (char* path); - char* GetExpandName (const char* path); - bool GetShortName (const char* fullname, char* shortname); - - bool FindFirst (char* path, Bit16u& id); - bool FindNext (Bit16u id, char* &result, char* &lresult); - - void CacheOut (const char* path, bool ignoreLastDir = false); - void AddEntry (const char* path, bool checkExist = false); - void DeleteEntry (const char* path, bool ignoreLastDir = false); - - void EmptyCache (void); - void SetLabel (const char* name,bool cdrom,bool allowupdate); - char* GetLabel (void) { return label; }; - - class CFileInfo { - public: - CFileInfo(void) { - orgname[0] = shortname[0] = 0; - isDir = false; - id = MAX_OPENDIRS; - nextEntry = shortNr = 0; - } - ~CFileInfo(void) { - for (Bit32u i=0; i fileList; - std::vector longNameList; - }; - -private: - void ClearFileInfo(CFileInfo *dir); - void DeleteFileInfo(CFileInfo *dir); - - bool RemoveTrailingDot (char* shortname); - Bits GetLongName (CFileInfo* info, char* shortname); - void CreateShortName (CFileInfo* dir, CFileInfo* info); - Bitu CreateShortNameID (CFileInfo* dir, const char* name); - int CompareShortname (const char* compareName, const char* shortName); - bool SetResult (CFileInfo* dir, char * &result, char * &lresult, Bitu entryNr); - bool IsCachedIn (CFileInfo* dir); - CFileInfo* FindDirInfo (const char* path, char* expandedPath); - bool RemoveSpaces (char* str); - bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id); - void CreateEntry (CFileInfo* dir, const char* name, const char* sname, bool query_directory); - void CopyEntry (CFileInfo* dir, CFileInfo* from); - Bit16u GetFreeID (CFileInfo* dir); - void Clear (void); - - CFileInfo* dirBase; - char dirPath [CROSS_LEN]; - char basePath [CROSS_LEN]; - bool dirFirstTime; - TDirSort sortDirType; - CFileInfo* save_dir; - char save_path [CROSS_LEN]; - char save_expanded [CROSS_LEN]; - - Bit16u srchNr; - CFileInfo* dirSearch [MAX_OPENDIRS]; - char dirSearchName [MAX_OPENDIRS]; - CFileInfo* dirFindFirst [MAX_OPENDIRS]; - Bit16u nextFreeFindFirst; - - char label [CROSS_LEN]; - bool updatelabel; -}; - -class DOS_Drive { -public: - DOS_Drive(); - virtual ~DOS_Drive(){}; - virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags)=0; - virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes)=0; - virtual bool FileUnlink(char * _name)=0; - virtual bool RemoveDir(char * _dir)=0; - virtual bool MakeDir(char * _dir)=0; - virtual bool TestDir(char * _dir)=0; - virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false)=0; - virtual bool FindNext(DOS_DTA & dta)=0; - virtual bool GetFileAttr(char * name,Bit16u * attr)=0; - virtual bool GetFileAttrEx(char* name, struct stat *status)=0; - virtual DWORD GetCompressedSize(char* name)=0; - virtual HANDLE CreateOpenFile(char const* const name)=0; - virtual bool Rename(char * oldname,char * newname)=0; - virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters)=0; - virtual bool FileExists(const char* name)=0; - virtual bool FileStat(const char* name, FileStat_Block * const stat_block)=0; - virtual Bit8u GetMediaByte(void)=0; - virtual void SetDir(const char* path) { strcpy(curdir,path); }; - virtual void EmptyCache(void) { dirCache.EmptyCache(); }; - virtual bool isRemote(void)=0; - virtual bool isRemovable(void)=0; - virtual bool isWriteProtected(void) = 0; - virtual Bits UnMount(void)=0; - - char * GetInfo(void); - char curdir[DOS_PATHLENGTH]; - char info[256]; - /* Can be overridden for example in iso images */ - virtual char const * GetLabel(){return dirCache.GetLabel();}; - - DOS_Drive_Cache dirCache; - - // disk cycling functionality (request resources) - virtual void Activate(void) {}; -}; - -enum { OPEN_READ=0, OPEN_WRITE=1, OPEN_READWRITE=2, OPEN_READ_NO_MOD=4, DOS_NOT_INHERIT=128}; -enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2}; - - -/* - A multiplex handler should read the registers to check what function is being called - If the handler returns false dos will stop checking other handlers -*/ - -typedef bool (MultiplexHandler)(void); -void DOS_AddMultiplexHandler(MultiplexHandler * handler); -void DOS_DelMultiplexHandler(MultiplexHandler * handler); - -/* AddDevice stores the pointer to a created device */ -void DOS_AddDevice(DOS_Device * adddev); -/* DelDevice destroys the device that is pointed to. */ -void DOS_DelDevice(DOS_Device * dev); - -void VFILE_Register(const char * name,Bit8u * data,Bit32u size); -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/dosbox.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/dosbox.h deleted file mode 100644 index c2e20a6ff..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/dosbox.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2002-2017 The DOSBox Team - * Copyright (C) 2016 akm - * Copyright (C) 2019 takapyu - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_DOSBOX_H -#define DOSBOX_DOSBOX_H - -#include "config.h" - -#define BUILD_VERSION "JP190520" -#ifndef VERSION -#define VERSION BUILD_VERSION -#endif - -GCC_ATTRIBUTE(noreturn) void E_Exit(const char * message,...) GCC_ATTRIBUTE( __format__(__printf__, 1, 2)); - -void MSG_Add(const char*,const char*); //add messages to the internal languagefile -const char* MSG_Get(char const *); //get messages from the internal languagefile - -class Section; - -typedef Bitu (LoopHandler)(void); - -void DOSBOX_RunMachine(); -void DOSBOX_SetLoop(LoopHandler * handler); -void DOSBOX_SetNormalLoop(); - -void DOSBOX_Init(void); - -class Config; -extern Config * control; - -enum MachineType { - MCH_HERC, - MCH_CGA, - MCH_TANDY, - MCH_PCJR, - MCH_EGA, - MCH_DCGA, - MCH_VGA -}; - -enum SVGACards { - SVGA_None, - SVGA_S3Trio, - SVGA_TsengET4K, - SVGA_TsengET3K, - SVGA_ParadisePVGA1A -}; - -extern SVGACards svgaCard; -extern MachineType machine; -extern bool SDLNetInited, uselfn, autolfn;; - -#define IS_TANDY_ARCH ((machine==MCH_TANDY) || (machine==MCH_PCJR)) -#define IS_EGAVGA_ARCH ((machine==MCH_EGA) || (machine==MCH_VGA)) -#define IS_VGA_ARCH ((machine==MCH_VGA)) -#define TANDY_ARCH_CASE MCH_TANDY: case MCH_PCJR -#define EGAVGA_ARCH_CASE MCH_EGA: case MCH_VGA -#define VGA_ARCH_CASE MCH_VGA -#define IS_AX_ARCH (machine==MCH_EGA)// upper compatible with EGA -//#define IS_AX_ARCH (machine==MCH_AX) -#define IS_J3_ARCH (machine==MCH_DCGA) - -#ifndef DOSBOX_LOGGING_H -#include "logging.h" -#endif // the logging system. - -#if !defined (WIN32) - typedef unsigned int DWORD; - typedef signed int HANDLE; -#define INVALID_HANDLE_VALUE -1 -#endif - -#endif /* DOSBOX_DOSBOX_H */ diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/dosv.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/dosv.h deleted file mode 100644 index 0884f3e94..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/dosv.h +++ /dev/null @@ -1,38 +0,0 @@ - -#ifndef DOSBOX_DOSV -#define DOSBOX_DOSV - -#include "setup.h" - -enum DOSV_VTEXT_MODE { - DOSV_VGA, // 80x25 - DOSV_VTEXT_VGA, // 80x30 - DOSV_VTEXT_SVGA, // 100x37 - DOSV_VTEXT_XGA, // 128x48 - DOSV_VTEXT_XGA_24, // 85x32 - DOSV_VTEXT_SXGA, // 160x64 - DOSV_VTEXT_SXGA_24, // 106x42 -}; - -enum DOSV_FONT { - DOSV_FONT_8X16, - DOSV_FONT_8X19, - DOSV_FONT_16X16, - DOSV_FONT_12X24, - DOSV_FONT_24X24, - - DOSV_FONT_16X16_WRITE, - DOSV_FONT_24X24_WRITE, - - DOSV_FONT_MAX -}; - -bool INT10_DOSV_SetCRTBIOSMode(Bitu mode); -void DOSV_SetConfig(Section_prop *section); -void DOSV_Setup(); -void DOSV_OffCursor(); -void INT8_DOSV(); -Bit16u DOSV_GetFontHandlerOffset(enum DOSV_FONT font); -enum DOSV_VTEXT_MODE DOSV_GetVtextMode(Bitu no = 0); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/fpu.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/fpu.h deleted file mode 100644 index 67e10210c..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/fpu.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_FPU_H -#define DOSBOX_FPU_H - -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -void FPU_ESC0_Normal(Bitu rm); -void FPU_ESC0_EA(Bitu func,PhysPt ea); -void FPU_ESC1_Normal(Bitu rm); -void FPU_ESC1_EA(Bitu func,PhysPt ea); -void FPU_ESC2_Normal(Bitu rm); -void FPU_ESC2_EA(Bitu func,PhysPt ea); -void FPU_ESC3_Normal(Bitu rm); -void FPU_ESC3_EA(Bitu func,PhysPt ea); -void FPU_ESC4_Normal(Bitu rm); -void FPU_ESC4_EA(Bitu func,PhysPt ea); -void FPU_ESC5_Normal(Bitu rm); -void FPU_ESC5_EA(Bitu func,PhysPt ea); -void FPU_ESC6_Normal(Bitu rm); -void FPU_ESC6_EA(Bitu func,PhysPt ea); -void FPU_ESC7_Normal(Bitu rm); -void FPU_ESC7_EA(Bitu func,PhysPt ea); - - -typedef union { - double d; -#ifndef WORDS_BIGENDIAN - struct { - Bit32u lower; - Bit32s upper; - } l; -#else - struct { - Bit32s upper; - Bit32u lower; - } l; -#endif - Bit64s ll; -} FPU_Reg; - -typedef struct { - Bit32u m1; - Bit32u m2; - Bit16u m3; - - Bit16u d1; - Bit32u d2; -} FPU_P_Reg; - -enum FPU_Tag { - TAG_Valid = 0, - TAG_Zero = 1, - TAG_Weird = 2, - TAG_Empty = 3 -}; - -enum FPU_Round { - ROUND_Nearest = 0, - ROUND_Down = 1, - ROUND_Up = 2, - ROUND_Chop = 3 -}; - -typedef struct { - FPU_Reg regs[9]; - FPU_P_Reg p_regs[9]; - FPU_Tag tags[9]; - Bit16u cw,cw_mask_all; - Bit16u sw; - Bit32u top; - FPU_Round round; -} FPU_rec; - - -//get pi from a real library -#define PI 3.14159265358979323846 -#define L2E 1.4426950408889634 -#define L2T 3.3219280948873623 -#define LN2 0.69314718055994531 -#define LG2 0.3010299956639812 - - -extern FPU_rec fpu; - -#define TOP fpu.top -#define STV(i) ( (fpu.top+ (i) ) & 7 ) - - -Bit16u FPU_GetTag(void); -void FPU_FLDCW(PhysPt addr); - -static INLINE void FPU_SetTag(Bit16u tag){ - for(Bitu i=0;i<8;i++) - fpu.tags[i] = static_cast((tag >>(2*i))&3); -} - -static INLINE void FPU_SetCW(Bitu word){ - fpu.cw = (Bit16u)word; - fpu.cw_mask_all = (Bit16u)(word | 0x3f); - fpu.round = (FPU_Round)((word >> 10) & 3); -} - - -static INLINE Bitu FPU_GET_TOP(void) { - return (fpu.sw & 0x3800)>>11; -} - -static INLINE void FPU_SET_TOP(Bitu val){ - fpu.sw &= ~0x3800; - fpu.sw |= (val&7)<<11; -} - - -static INLINE void FPU_SET_C0(Bitu C){ - fpu.sw &= ~0x0100; - if(C) fpu.sw |= 0x0100; -} - -static INLINE void FPU_SET_C1(Bitu C){ - fpu.sw &= ~0x0200; - if(C) fpu.sw |= 0x0200; -} - -static INLINE void FPU_SET_C2(Bitu C){ - fpu.sw &= ~0x0400; - if(C) fpu.sw |= 0x0400; -} - -static INLINE void FPU_SET_C3(Bitu C){ - fpu.sw &= ~0x4000; - if(C) fpu.sw |= 0x4000; -} - - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/hardware.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/hardware.h deleted file mode 100644 index 26d3fde88..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/hardware.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_HARDWARE_H -#define DOSBOX_HARDWARE_H - -#include - -class Section; -enum OPL_Mode { - OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3,OPL_opl3gold -}; -#define CAPTURE_WAVE 0x01 -#define CAPTURE_OPL 0x02 -#define CAPTURE_MIDI 0x04 -#define CAPTURE_IMAGE 0x08 -#define CAPTURE_VIDEO 0x10 - -extern Bitu CaptureState; - -void OPL_Init(Section* sec,OPL_Mode mode); -void CMS_Init(Section* sec); -void OPL_ShutDown(Section* sec); -void CMS_ShutDown(Section* sec); - -bool SB_Get_Address(Bitu& sbaddr, Bitu& sbirq, Bitu& sbdma); -bool TS_Get_Address(Bitu& tsaddr, Bitu& tsirq, Bitu& tsdma); - -extern Bit8u adlib_commandreg; -FILE * OpenCaptureFile(const char * type,const char * ext); - -void CAPTURE_AddWave(Bit32u freq, Bit32u len, Bit16s * data); -#define CAPTURE_FLAG_DBLW 0x1 -#define CAPTURE_FLAG_DBLH 0x2 -void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal); -void CAPTURE_AddMidi(bool sysex, Bitu len, Bit8u * data); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/inout.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/inout.h deleted file mode 100644 index dd0dc1727..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/inout.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_INOUT_H -#define DOSBOX_INOUT_H - -#define IO_MAX (64*1024+3) - -#define IO_MB 0x1 -#define IO_MW 0x2 -#define IO_MD 0x4 -#define IO_MA (IO_MB | IO_MW | IO_MD ) - -typedef Bitu IO_ReadHandler(Bitu port,Bitu iolen); -typedef void IO_WriteHandler(Bitu port,Bitu val,Bitu iolen); - -extern IO_WriteHandler * io_writehandlers[3][IO_MAX]; -extern IO_ReadHandler * io_readhandlers[3][IO_MAX]; - -void IO_RegisterReadHandler(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1); -void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1); - -void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range=1); -void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=1); - -void IO_WriteB(Bitu port,Bitu val); -void IO_WriteW(Bitu port,Bitu val); -void IO_WriteD(Bitu port,Bitu val); - -Bitu IO_ReadB(Bitu port); -Bitu IO_ReadW(Bitu port); -Bitu IO_ReadD(Bitu port); - -/* Classes to manage the IO objects created by the various devices. - * The io objects will remove itself on destruction.*/ -class IO_Base{ -protected: - bool installed; - Bitu m_port, m_mask,m_range; -public: - IO_Base():installed(false){}; -}; -class IO_ReadHandleObject: private IO_Base{ -public: - void Install(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1); - void Uninstall(); - ~IO_ReadHandleObject(); -}; -class IO_WriteHandleObject: private IO_Base{ -public: - void Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1); - void Uninstall(); - ~IO_WriteHandleObject(); -}; - -static INLINE void IO_Write(Bitu port,Bit8u val) { - IO_WriteB(port,val); -} -static INLINE Bit8u IO_Read(Bitu port){ - return (Bit8u)IO_ReadB(port); -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/ipx.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/ipx.h deleted file mode 100644 index 6e87b1e93..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/ipx.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_IPX_H -#define DOSBOX_IPX_H - -// Uncomment this for a lot of debug messages: -//#define IPX_DEBUGMSG - -#ifdef IPX_DEBUGMSG -#define LOG_IPX LOG_MSG -#else -#if defined (_MSC_VER) -#define LOG_IPX -#else -#define LOG_IPX(...) -#endif -#endif - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -// In Use Flag codes -#define USEFLAG_AVAILABLE 0x00 -#define USEFLAG_AESTEMP 0xe0 -#define USEFLAG_IPXCRIT 0xf8 -#define USEFLAG_SPXLISTEN 0xf9 -#define USEFLAG_PROCESSING 0xfa -#define USEFLAG_HOLDING 0xfb -#define USEFLAG_AESWAITING 0xfc -#define USEFLAG_AESCOUNT 0xfd -#define USEFLAG_LISTENING 0xfe -#define USEFLAG_SENDING 0xff - -// Completion codes -#define COMP_SUCCESS 0x00 -#define COMP_REMOTETERM 0xec -#define COMP_DISCONNECT 0xed -#define COMP_INVALIDID 0xee -#define COMP_SPXTABLEFULL 0xef -#define COMP_EVENTNOTCANCELED 0xf9 -#define COMP_NOCONNECTION 0xfa -#define COMP_CANCELLED 0xfc -#define COMP_MALFORMED 0xfd -#define COMP_UNDELIVERABLE 0xfe -#define COMP_HARDWAREERROR 0xff - -#ifdef _MSC_VER -#pragma pack(1) -#endif - -// For Uint8 type -#include "SDL_net.h" - -struct PackedIP { - Uint32 host; - Uint16 port; -} GCC_ATTRIBUTE(packed); - -struct nodeType { - Uint8 node[6]; -} GCC_ATTRIBUTE(packed) ; - -struct IPXHeader { - Uint8 checkSum[2]; - Uint8 length[2]; - Uint8 transControl; // Transport control - Uint8 pType; // Packet type - - struct transport { - Uint8 network[4]; - union addrtype { - nodeType byNode; - PackedIP byIP ; - } GCC_ATTRIBUTE(packed) addr; - Uint8 socket[2]; - } dest, src; -} GCC_ATTRIBUTE(packed); - -struct fragmentDescriptor { - Bit16u offset; - Bit16u segment; - Bit16u size; -}; - -#define IPXBUFFERSIZE 1424 - -class ECBClass { -public: - RealPt ECBAddr; - bool isInESRList; - ECBClass *prevECB; // Linked List - ECBClass *nextECB; - - Bit8u iuflag; // Need to save data since we are not always in - Bit16u mysocket; // real mode - - Bit8u* databuffer; // received data is stored here until we get called - Bitu buflen; // by Interrupt - -#ifdef IPX_DEBUGMSG - Bitu SerialNumber; -#endif - - ECBClass(Bit16u segment, Bit16u offset); - Bit16u getSocket(void); - - Bit8u getInUseFlag(void); - - void setInUseFlag(Bit8u flagval); - - void setCompletionFlag(Bit8u flagval); - - Bit16u getFragCount(void); - - bool writeData(); - void writeDataBuffer(Bit8u* buffer, Bit16u length); - - void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc); - RealPt getESRAddr(void); - - void NotifyESR(void); - - void setImmAddress(Bit8u *immAddr); - void getImmAddress(Bit8u* immAddr); - - ~ECBClass(); -}; - -// The following routines may not be needed on all systems. On my build of SDL the IPaddress structure is 8 octects -// and therefore screws up my IPXheader structure since it needs to be packed. - -void UnpackIP(PackedIP ipPack, IPaddress * ipAddr); -void PackIP(IPaddress ipAddr, PackedIP *ipPack); - -#ifdef _MSC_VER -#pragma pack() -#endif - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/ipxserver.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/ipxserver.h deleted file mode 100644 index 1c6a294dc..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/ipxserver.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_IPXSERVER_H_ -#define DOSBOX_IPXSERVER_H_ - -#if C_IPX - -#include "SDL_net.h" - -struct packetBuffer { - Bit8u buffer[1024]; - Bit16s packetSize; // Packet size remaining in read - Bit16s packetRead; // Bytes read of total packet - bool inPacket; // In packet reception flag - bool connected; // Connected flag - bool waitsize; -}; - -#define SOCKETTABLESIZE 16 -#define CONVIP(hostvar) hostvar & 0xff, (hostvar >> 8) & 0xff, (hostvar >> 16) & 0xff, (hostvar >> 24) & 0xff -#define CONVIPX(hostvar) hostvar[0], hostvar[1], hostvar[2], hostvar[3], hostvar[4], hostvar[5] - - -void IPX_StopServer(); -bool IPX_StartServer(Bit16u portnum); -bool IPX_isConnectedToServer(Bits tableNum, IPaddress ** ptrAddr); - -Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize); - -#endif - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/j3.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/j3.h deleted file mode 100644 index 09affb536..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/j3.h +++ /dev/null @@ -1,36 +0,0 @@ - -#ifndef DOSBOX_J3_H -#define DOSBOX_J3_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -#include "control.h" - -/* AX Global Area */ -#define BIOSMEM_J3_SEG 0x40 - -#define BIOSMEM_J3_MODE 0xD0 -#define BIOSMEM_J3_LINE_COUNT 0xD4 -#define BIOSMEM_J3_GRAPH_ADDR 0xD6 -#define BIOSMEM_J3_CODE_SEG 0xDA -#define BIOSMEM_J3_CODE_OFFSET 0xD8 -#define BIOSMEM_J3_SCROLL 0xE2 -#define BIOSMEM_J3_BLINK 0xE9 - -#define GRAPH_J3_SEG 0xb800 - -//int10_j3.cpp -bool INT10_J3_SetCRTBIOSMode(Bitu mode); -Bitu INT60_Handler(void); -Bitu INT6F_Handler(void); -void INT60_J3_Setup(); -void INT8_J3(); -void J3_OffCursor(); -void J3_SetConfig(Section_prop *section); -void J3_GetPalette(Bit8u no, Bit8u &r, Bit8u &g, Bit8u &b); -Bit16u J3_GetMachineCode(); -bool J3_IsJapanese(); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/jega.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/jega.h deleted file mode 100644 index dc93e8c04..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/jega.h +++ /dev/null @@ -1,87 +0,0 @@ - -#ifndef DOSBOX_JEGA -#define DOSBOX_JEGA - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -/* AX Global Area */ -#define BIOSMEM_AX_SEG 0x40 - -#define BIOSMEM_AX_VTRAM_SEGADDR 0xE0 -#define BIOSMEM_AX_GRAPH_CHAR 0xE2 -#define BIOSMEM_AX_GRAPH_ATTR 0xE3 -#define BIOSMEM_AX_JPNSTATUS 0xE4 -#define BIOSMEM_AX_JEGA_RMOD1 0xE9 -#define BIOSMEM_AX_JEGA_RMOD2 0xEA -#define BIOSMEM_AX_KBDSTATUS 0xEB - -#define BIOS_KEYBOARD_AX_KBDSTATUS 0x4EB -/* 40h:EBh Keyboard Additional Status bits - bit 2 : Kana holding - bit 1 : Kana Lock key - bit 0 : Kana LED indicating -*/ - -/* JEGA internal registers */ -typedef struct { - Bitu RMOD1//b9: Mode register 1 - , RMOD2//ba: Mode register 2 - , RDAGS//bb: ANK Group sel (not implemented) - , RDFFB//bc: Font access first byte - , RDFSB//bd: Font access second byte - , RDFAP//be: Font Access Pattern - , RPESL//09: end scan line (superceded by EGA) - , RPULP//14: under scan line (superceded by EGA) - , RPSSC//db: DBCS start scan line - , RPSSU//d9: 2x DBCS upper start scan - , RPSSL//da: 2x DBCS lower start scan - , RPPAJ//dc: super imposed (only AX-2 system, not implemented) - , RCMOD//dd: Cursor Mode (not implemented) - , RCCLH//0e: Cursor location Upper bits (superceded by EGA) - , RCCLL//0f: Cursor location Lower bits (superceded by EGA) - , RCCSL//0a: Cursor Start Line (superceded by EGA) - , RCCEL//0b: Cursor End Line (superceded by EGA) - , RCSKW//de: Cursor Skew control (not implemented) - , ROMSL//df: Unused? - , RSTAT//bf: Font register accessible status - ; - Bitu fontIndex = 0; -} JEGA_DATA; - -extern JEGA_DATA jega; - -//jfontload.cpp -extern Bit8u jfont_sbcs_19[]; -extern Bit8u jfont_dbcs_16[]; -extern Bit8u jfont_cache_dbcs_16[]; -// for J-3100 -extern Bit8u jfont_sbcs_16[]; -extern Bit8u jfont_dbcs_24[]; -extern Bit8u jfont_sbcs_24[]; - -//vga_jega.cpp -void SVGA_Setup_JEGA(void);//Init JEGA and AX system area - -//int10_ax.cpp -bool INT10_AX_SetCRTBIOSMode(Bitu mode); -Bitu INT10_AX_GetCRTBIOSMode(void); -bool INT16_AX_SetKBDBIOSMode(Bitu mode); -Bitu INT16_AX_GetKBDBIOSMode(void); - -//int10_char.cpp -extern Bit8u prevchr; -void ReadVTRAMChar(Bit16u col, Bit16u row, Bit16u * result); -void SetVTRAMChar(Bit16u col, Bit16u row, Bit8u chr, Bit8u attr); -void WriteCharJ(Bit16u col, Bit16u row, Bit8u page, Bit8u chr, Bit8u attr, bool useattr); - -//inline functions -inline bool isKanji1(Bit8u chr) { return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); } -inline bool isKanji2(Bit8u chr) { return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc); } -inline bool isJEGAEnabled() { - if (!IS_AX_ARCH) return false; - return !(jega.RMOD1 & 0x40); -} - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/jfont.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/jfont.h deleted file mode 100644 index 80c034480..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/jfont.h +++ /dev/null @@ -1,39 +0,0 @@ - -#ifndef DOSBOX_JFONT_H -#define DOSBOX_JFONT_H - -#include "setup.h" - -#define VIRTUAL_TEXT_SIZE 0x500 - -void InitFontHandle(); -void QuitFont(); -bool GetWindowsFont(Bitu code, Bit8u *buff, int width, int height); -Bit16u GetTextSeg(); -void SetTextSeg(); -bool MakeSbcs19Font(); -bool MakeSbcs16Font(); -bool MakeSbcs24Font(); -Bit8u GetKanjiAttr(Bitu x, Bitu y); -Bit8u GetKanjiAttr(); -Bit8u *GetSbcsFont(Bitu code); -Bit8u *GetSbcs19Font(Bitu code); -Bit8u *GetSbcs24Font(Bitu code); -void SetFontName(const char *name); -void GetDbcsFrameFont(Bitu code, Bit8u *buff); -Bit8u *GetDbcsFont(Bitu code); -Bit8u *GetDbcs24Font(Bitu code); -bool CheckStayVz(); -bool CheckAnotherDisplayDriver(); -Bit16u GetGaijiSeg(); -void SetGaijiConfig(Section_prop *section); -bool SetGaijiData(Bit16u code, PhysPt data); -bool SetGaijiData24(Bit16u code, PhysPt data); - -#ifdef NDEBUG -#define JTrace -#else -void JTrace(const char *form , ...); -#endif - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/joystick.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/joystick.h deleted file mode 100644 index a51395843..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/joystick.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_JOYSTICK_H -#define DOSBOX_JOYSTICK_H -void JOYSTICK_Enable(Bitu which,bool enabled); - -void JOYSTICK_Button(Bitu which,Bitu num,bool pressed); - -void JOYSTICK_Move_X(Bitu which,float x); - -void JOYSTICK_Move_Y(Bitu which,float y); - -bool JOYSTICK_IsEnabled(Bitu which); - -bool JOYSTICK_GetButton(Bitu which, Bitu num); - -float JOYSTICK_GetMove_X(Bitu which); - -float JOYSTICK_GetMove_Y(Bitu which); - -enum JoystickType { - JOY_NONE, - JOY_AUTO, - JOY_2AXIS, - JOY_4AXIS, - JOY_4AXIS_2, - JOY_FCS, - JOY_CH -}; - -extern JoystickType joytype; -extern bool button_wrapping_enabled; -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/keyboard.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/keyboard.h deleted file mode 100644 index 125cfae69..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/keyboard.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * Copyright (C) 2016 akm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_KEYBOARD_H -#define DOSBOX_KEYBOARD_H - -enum KBD_KEYS { - KBD_NONE, - KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0, - KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p, - KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z, - KBD_x, KBD_c, KBD_v, KBD_b, KBD_n, KBD_m, - KBD_f1, KBD_f2, KBD_f3, KBD_f4, KBD_f5, KBD_f6, KBD_f7, KBD_f8, KBD_f9, KBD_f10,KBD_f11,KBD_f12, - - /*Now the weirder keys */ - - KBD_esc,KBD_tab,KBD_backspace,KBD_enter,KBD_space, - KBD_leftalt,KBD_rightalt,KBD_leftctrl,KBD_rightctrl,KBD_leftshift,KBD_rightshift, - KBD_capslock,KBD_scrolllock,KBD_numlock, - - KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket, - KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,KBD_extra_lt_gt, - - KBD_printscreen,KBD_pause, - KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown, - KBD_left,KBD_up,KBD_down,KBD_right, - - KBD_kp1,KBD_kp2,KBD_kp3,KBD_kp4,KBD_kp5,KBD_kp6,KBD_kp7,KBD_kp8,KBD_kp9,KBD_kp0, - KBD_kpdivide,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod, - KBD_yen, KBD_underscore,//JP layout - KBD_ax,KBD_conv,KBD_nconv, // for AX - - KBD_f13,KBD_f14,KBD_f15, - - KBD_LAST -}; - -void KEYBOARD_ClrBuffer(void); -void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/logging.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/logging.h deleted file mode 100644 index 049e504b2..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/logging.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_LOGGING_H -#define DOSBOX_LOGGING_H -enum LOG_TYPES { - LOG_ALL, - LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, - LOG_SB,LOG_DMACONTROL, - LOG_FPU,LOG_CPU,LOG_PAGING, - LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC, - LOG_PIT,LOG_KEYBOARD,LOG_PIC, - LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, - LOG_IO, - LOG_PCI, - LOG_MAX -}; - -enum LOG_SEVERITIES { - LOG_NORMAL, - LOG_WARN, - LOG_ERROR -}; - -#if C_DEBUG -class LOG -{ - LOG_TYPES d_type; - LOG_SEVERITIES d_severity; -public: - - LOG (LOG_TYPES type , LOG_SEVERITIES severity): - d_type(type), - d_severity(severity) - {} - void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_gui.cpp - -}; - -void DEBUG_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2)); -#define LOG_MSG DEBUG_ShowMsg - -#else //C_DEBUG - -struct LOG -{ - LOG(LOG_TYPES , LOG_SEVERITIES ) { } - void operator()(char const* ) { } - void operator()(char const* , double ) { } - void operator()(char const* , double , double ) { } - void operator()(char const* , double , double , double ) { } - void operator()(char const* , double , double , double , double ) { } - void operator()(char const* , double , double , double , double , double ) { } - void operator()(char const* , double , double , double , double , double , double ) { } - void operator()(char const* , double , double , double , double , double , double , double) { } - - - - void operator()(char const* , char const* ) { } - void operator()(char const* , char const* , double ) { } - void operator()(char const* , char const* , double ,double ) { } - void operator()(char const* , double , char const* ) { } - void operator()(char const* , double , double, char const* ) { } - void operator()(char const* , char const*, char const*) { } - - void operator()(char const* , double , double , double , char const* ) { } -}; //add missing operators to here - //try to avoid anything smaller than bit32... -void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2)); -#define LOG_MSG GFX_ShowMsg - -#endif //C_DEBUG - - -#endif //DOSBOX_LOGGING_H diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/mapper.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/mapper.h deleted file mode 100644 index 3ba648c49..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/mapper.h +++ /dev/null @@ -1,40 +0,0 @@ - /* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_MAPPER_H -#define DOSBOX_MAPPER_H - -enum MapKeys { - MK_f1,MK_f2,MK_f3,MK_f4,MK_f5,MK_f6,MK_f7,MK_f8,MK_f9,MK_f10,MK_f11,MK_f12, - MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause,MK_home - -}; - -typedef void (MAPPER_Handler)(bool pressed); -void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname); -void MAPPER_Init(void); -void MAPPER_StartUp(Section * sec); -void MAPPER_Run(bool pressed); -void MAPPER_RunInternal(); -void MAPPER_LosingFocus(void); - - -#define MMOD1 0x1 -#define MMOD2 0x2 - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/mem.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/mem.h deleted file mode 100644 index 3a4b28ca0..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/mem.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_MEM_H -#define DOSBOX_MEM_H - -#include "../types_compat.h" - -typedef Bit32u PhysPt; -typedef Bit8u * HostPt; -typedef Bit32u RealPt; - -typedef Bit32s MemHandle; - -#define MEM_PAGESIZE 4096 - -namespace DOSBOX_I386 { - -extern HostPt MemBase; -HostPt GetMemBase(void); - -bool MEM_A20_Enabled(void); -void MEM_A20_Enable(bool enable); - -/* Memory management / EMS mapping */ -HostPt MEM_GetBlockPage(void); -Bitu MEM_FreeTotal(void); //Free 4 kb pages -Bitu MEM_FreeLargest(void); //Largest free 4 kb pages block -Bitu MEM_TotalPages(void); //Total amount of 4 kb pages -Bitu MEM_AllocatedPages(MemHandle handle); // amount of allocated pages of handle -MemHandle MEM_AllocatePages(Bitu pages,bool sequence); -MemHandle MEM_GetNextFreePage(void); -PhysPt MEM_AllocatePage(void); -void MEM_ReleasePages(MemHandle handle); -bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence); - -MemHandle MEM_NextHandle(MemHandle handle); -MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where); - -/* - The folowing six functions are used everywhere in the end so these should be changed for - Working on big or little endian machines -*/ - -#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) - -static INLINE Bit8u host_readb(HostPt off) { - - return off[0]; -} -static INLINE Bit16u host_readw(HostPt off) { - return off[0] | (off[1] << 8); -} -static INLINE Bit32u host_readd(HostPt off) { - return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); -} -static INLINE void host_writeb(HostPt off,Bit8u val) { - off[0]=val; -} -static INLINE void host_writew(HostPt off,Bit16u val) { - off[0]=(Bit8u)(val); - off[1]=(Bit8u)(val >> 8); -} -static INLINE void host_writed(HostPt off,Bit32u val) { - off[0]=(Bit8u)(val); - off[1]=(Bit8u)(val >> 8); - off[2]=(Bit8u)(val >> 16); - off[3]=(Bit8u)(val >> 24); -} - -#else - -static INLINE Bit8u host_readb(HostPt off) { - return *(Bit8u *)off; -} -static INLINE Bit16u host_readw(HostPt off) { - return *(Bit16u *)off; -} -static INLINE Bit32u host_readd(HostPt off) { - return *(Bit32u *)off; -} -static INLINE void host_writeb(HostPt off,Bit8u val) { - *(Bit8u *)(off)=val; -} -static INLINE void host_writew(HostPt off,Bit16u val) { - *(Bit16u *)(off)=val; -} -static INLINE void host_writed(HostPt off,Bit32u val) { - *(Bit32u *)(off)=val; -} - -#endif - - -static INLINE void var_write(Bit8u * var, Bit8u val) { - host_writeb((HostPt)var, val); -} - -static INLINE void var_write(Bit16u * var, Bit16u val) { - host_writew((HostPt)var, val); -} - -static INLINE void var_write(Bit32u * var, Bit32u val) { - host_writed((HostPt)var, val); -} - -/* The Folowing six functions are slower but they recognize the paged memory system */ - -Bit8u mem_readb(PhysPt pt); -Bit16u mem_readw(PhysPt pt); -Bit32u mem_readd(PhysPt pt); - -void mem_writeb(PhysPt pt,Bit8u val); -void mem_writew(PhysPt pt,Bit16u val); -void mem_writed(PhysPt pt,Bit32u val); - -static INLINE void phys_writeb(PhysPt addr,Bit8u val) { - host_writeb(MemBase+addr,val); -} -static INLINE void phys_writew(PhysPt addr,Bit16u val){ - host_writew(MemBase+addr,val); -} -static INLINE void phys_writed(PhysPt addr,Bit32u val){ - host_writed(MemBase+addr,val); -} - -static INLINE Bit8u phys_readb(PhysPt addr) { - return host_readb(MemBase+addr); -} -static INLINE Bit16u phys_readw(PhysPt addr){ - return host_readw(MemBase+addr); -} -static INLINE Bit32u phys_readd(PhysPt addr){ - return host_readd(MemBase+addr); -} - -/* These don't check for alignment, better be sure it's correct */ - -void MEM_BlockWrite(PhysPt pt,void const * const data,Bitu size); -void MEM_BlockRead(PhysPt pt,void * data,Bitu size); -void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size); -void MEM_StrCopy(PhysPt pt,char * data,Bitu size); - -void mem_memcpy(PhysPt dest,PhysPt src,Bitu size); -Bitu mem_strlen(PhysPt pt); -void mem_strcpy(PhysPt dest,PhysPt src); - -/* The folowing functions are all shortcuts to the above functions using physical addressing */ - -static INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { - return mem_readb((seg<<4)+off); -} -static INLINE Bit16u real_readw(Bit16u seg,Bit16u off) { - return mem_readw((seg<<4)+off); -} -static INLINE Bit32u real_readd(Bit16u seg,Bit16u off) { - return mem_readd((seg<<4)+off); -} - -static INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) { - mem_writeb(((seg<<4)+off),val); -} -static INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) { - mem_writew(((seg<<4)+off),val); -} -static INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { - mem_writed(((seg<<4)+off),val); -} - - -static INLINE Bit16u RealSeg(RealPt pt) { - return (Bit16u)(pt>>16); -} - -static INLINE Bit16u RealOff(RealPt pt) { - return (Bit16u)(pt&0xffff); -} - -static INLINE PhysPt Real2Phys(RealPt pt) { - return (RealSeg(pt)<<4) +RealOff(pt); -} - -static INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) { - return (seg<<4)+off; -} - -static INLINE RealPt RealMake(Bit16u seg,Bit16u off) { - return (seg<<16)+off; -} - -static INLINE void RealSetVec(Bit8u vec,RealPt pt) { - mem_writed(vec<<2,pt); -} - -static INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) { - old = mem_readd(vec<<2); - mem_writed(vec<<2,pt); -} - -static INLINE RealPt RealGetVec(Bit8u vec) { - return mem_readd(vec<<2); -} -}; - -#endif - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/midi.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/midi.h deleted file mode 100644 index 86431dc80..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/midi.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_MIDI_H -#define DOSBOX_MIDI_H - -#ifndef DOSBOX_PROGRAMS_H -#include "programs.h" -#endif - -class MidiHandler { -public: - MidiHandler(); - virtual bool Open(const char * /*conf*/) { return true; }; - virtual void Close(void) {}; - virtual void PlayMsg(Bit8u * /*msg*/) {}; - virtual void PlaySysex(Bit8u * /*sysex*/,Bitu /*len*/) {}; - virtual const char * GetName(void) { return "none"; }; - virtual void ListAll(Program * base) {}; - virtual ~MidiHandler() { }; - MidiHandler * next; -}; - - -#define SYSEX_SIZE 8192 -struct DB_Midi { - Bitu status; - Bitu cmd_len; - Bitu cmd_pos; - Bit8u cmd_buf[8]; - Bit8u rt_buf[8]; - struct { - Bit8u buf[SYSEX_SIZE]; - Bitu used; - Bitu delay; - Bit32u start; - } sysex; - bool available; - MidiHandler * handler; -}; - -extern DB_Midi midi; - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/mixer.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/mixer.h deleted file mode 100644 index 94b806bef..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/mixer.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_MIXER_H -#define DOSBOX_MIXER_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); -typedef void (*MIXER_Handler)(Bitu len); - -enum BlahModes { - MIXER_8MONO,MIXER_8STEREO, - MIXER_16MONO,MIXER_16STEREO -}; - -enum MixerModes { - M_8M,M_8S, - M_16M,M_16S -}; - -#define MIXER_BUFSIZE (16*1024) -#define MIXER_BUFMASK (MIXER_BUFSIZE-1) -extern Bit8u MixTemp[MIXER_BUFSIZE]; - -#define MAX_AUDIO ((1<<(16-1))-1) -#define MIN_AUDIO -(1<<(16-1)) - -class MixerChannel { -public: - void SetVolume(float _left,float _right); - void SetScale( float f ); - void UpdateVolume(void); - void SetFreq(Bitu _freq); - void Mix(Bitu _needed); - void AddSilence(void); //Fill up until needed - - template - void AddSamples(Bitu len, const Type* data); - - void AddSamples_m8(Bitu len, const Bit8u * data); - void AddSamples_s8(Bitu len, const Bit8u * data); - void AddSamples_m8s(Bitu len, const Bit8s * data); - void AddSamples_s8s(Bitu len, const Bit8s * data); - void AddSamples_m16(Bitu len, const Bit16s * data); - void AddSamples_s16(Bitu len, const Bit16s * data); - void AddSamples_m16u(Bitu len, const Bit16u * data); - void AddSamples_s16u(Bitu len, const Bit16u * data); - void AddSamples_m32(Bitu len, const Bit32s * data); - void AddSamples_s32(Bitu len, const Bit32s * data); - void AddSamples_m16_nonnative(Bitu len, const Bit16s * data); - void AddSamples_s16_nonnative(Bitu len, const Bit16s * data); - void AddSamples_m16u_nonnative(Bitu len, const Bit16u * data); - void AddSamples_s16u_nonnative(Bitu len, const Bit16u * data); - void AddSamples_m32_nonnative(Bitu len, const Bit32s * data); - void AddSamples_s32_nonnative(Bitu len, const Bit32s * data); - - void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data - void FillUp(void); - void Enable(bool _yesno); - MIXER_Handler handler; - float volmain[2]; - float scale; - Bit32s volmul[2]; - Bitu freq_add,freq_index; - Bitu done,needed; - Bits last[2]; - const char * name; - bool enabled; - MixerChannel * next; -}; - -MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * name); -MixerChannel * MIXER_FindChannel(const char * name); -/* Find the device you want to delete with findchannel "delchan gets deleted" */ -void MIXER_DelChannel(MixerChannel* delchan); - -/* Object to maintain a mixerchannel; As all objects it registers itself with create - * and removes itself when destroyed. */ -class MixerObject{ -private: - bool installed; - char m_name[32]; -public: - MixerObject():installed(false){}; - MixerChannel* Install(MIXER_Handler handler,Bitu freq,const char * name); - ~MixerObject(); -}; - - -/* PC Speakers functions, tightly related to the timer functions */ -void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode); -void PCSPEAKER_SetType(Bitu mode); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/modules.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/modules.h deleted file mode 100644 index 6bbeffcaa..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/modules.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Standard data types used */ - -typedef unsigned char Bit8u; -typedef signed char Bit8s; -typedef unsigned short Bit16u; -typedef signed short Bit16s; -typedef unsigned long Bit32u; -typedef signed long Bit32s; -#if defined(_MSC_VER) -typedef unsigned __int64 Bit64u; -typedef signed __int64 Bit64s; -#else -typedef unsigned long long int Bit64u; -typedef signed long long int Bit64s; -#endif - - - -/* Setting up pointers to all subfunctions */ -#ifdef MODULE_WANT_IO_READ -typedef Bit8u (* IO_ReadHandler)(Bit32u port); -static void (* IO_RegisterReadHandler)(Bit32u port,IO_ReadHandler handler,char * name); -static void (* IO_FreeReadHandler)(Bit32u port); -#endif - -#ifdef MODULE_WANT_IO_WRITE -typedef void (* IO_WriteHandler)(Bit32u port,Bit8u value); -static void (* IO_RegisterWriteHandler)(Bit32u port,IO_WriteHandler handler,char * name); -static void (* IO_FreeWriteHandler)(Bit32u port); -#endif - -#ifdef MODULE_WANT_IRQ_EOI -typedef void (* IRQ_EOIHandler)(void); -static void (* IRQ_RegisterEOIHandler)(Bit32u irq,IRQ_EOIHandler handler,char * name); -static void (* IRQ_FreeEOIHandler)(Bit32u irq); -#endif - -#ifdef MODULE_WANT_IRQ -static void (* IRQ_Activate)(Bit32u irq); -static void (* IRQ_Deactivate)(Bit32u irq); -#endif - -#ifdef MODULE_WANT_TIMER -typedef void (* TIMER_MicroHandler)(void); -static void (* TIMER_RegisterMicroHandler)(TIMER_MicroHandler handler,Bit32u micro); -#endif - -#ifdef MODULE_WANT_TIMER_TICK -typedef void (* TIMER_TickHandler)(Bit32u ticks); -static void (* TIMER_RegisterTickHandler)(TIMER_TickHandler handler); -#endif - -/* - 4 8-bit and 4 16-bit channels you can read data from - 16-bit reads are word sized -*/ - -#ifdef MODULE_WANT_DMA_READ -static void (* DMA_8_Read)(Bit32u chan,Bit8u * data,Bit16u size); -static void (* DMA_16_Read)(Bit32u chan,Bit8u * data,Bit16u size); -#endif - -/* - 4 8-bit and 4 16-bit channels you can write data from - 16-bit writes are word sized -*/ - -#ifdef MODULE_WANT_DMA_READ -static void (* DMA_8_Write)(Bit32u chan,Bit8u * data,Bit16u size); -static void (* DMA_16_Write)(Bit32u chan,Bit8u * data,Bit16u size); -#endif - - -#ifdef MODULE_WANT_MIXER -/* The len here means the amount of samples needed not the buffersize it needed to fill */ -typedef void (* MIXER_MixHandler)(Bit8u * sampdate,Bit32u len); - -/* Different types if modes a mixer channel can work in */ -#define MIXER_8MONO 0 -#define MIXER_8STEREO 1 -#define MIXER_16MONO 2 -#define MIXER_16STEREO 3 -struct MIXER_Channel; - -#define MAX_AUDIO ((1<<(16-1))-1) -#define MIN_AUDIO -(1<<(16-1)) - -MIXER_Channel *(* MIXER_AddChannel)(MIXER_MixHandler handler,Bit32u freq,char * name); -void (* MIXER_SetVolume)(MIXER_Channel * chan,Bit8u vol); -void (* MIXER_SetFreq)(MIXER_Channel * chan,Bit32u freq); -void (* MIXER_SetMode)(MIXER_Channel * chan,Bit8u mode); -void (* MIXER_Enable)(MIXER_Channel * chan,bool enable); -#endif - -typedef bool (* MODULE_FindHandler)(char * name,void * * function); -typedef char *(* MODULE_StartHandler)(MODULE_FindHandler find_handler); - -#define MODULE_START_PROC "ModuleStart" - -#ifdef MODULE_START_FUNCTION -#include - -#define GET_FUNCTION(a) \ - if (!find_handler(#a ,(void * *) &a)) { \ - return "Can't find requested function"; \ - }; - - -#if defined (WIN32) -#include -BOOL APIENTRY DllMain( HANDLE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - return TRUE; -} - -extern "C" { -__declspec(dllexport) -#endif -char * ModuleStart (MODULE_FindHandler find_handler) { - -#ifdef MODULE_WANT_IRQ_EOI -GET_FUNCTION(IRQ_RegisterEOIHandler); -GET_FUNCTION(IRQ_FreeEOIHandler); -#endif - -#ifdef MODULE_WANT_IRQ -GET_FUNCTION(IRQ_Activate); -GET_FUNCTION(IRQ_Deactivate); -#endif - -#ifdef MODULE_WANT_IO_READ -GET_FUNCTION(IO_RegisterReadHandler); -GET_FUNCTION(IO_FreeReadHandler); -#endif - -#ifdef MODULE_WANT_IO_WRITE -GET_FUNCTION(IO_RegisterWriteHandler); -GET_FUNCTION(IO_FreeWriteHandler); -#endif - -#ifdef MODULE_WANT_TIMER -GET_FUNCTION(TIMER_RegisterMicroHandler); -#endif - -#ifdef MODULE_WANT_TIMER_TICKS -GET_FUNCTION(TIMER_RegisterTickHandler); -#endif - -#ifdef MODULE_WANT_DMA_READ -GET_FUNCTION(DMA_8_Read); -GET_FUNCTION(DMA_16_Read); -#endif - -#ifdef MODULE_WANT_DMA_WRITE -GET_FUNCTION(DMA_8_Write); -GET_FUNCTION(DMA_16_Write); -#endif - -#ifdef MODULE_WANT_MIXER -GET_FUNCTION(MIXER_AddChannel); -GET_FUNCTION(MIXER_SetVolume); -GET_FUNCTION(MIXER_SetFreq); -GET_FUNCTION(MIXER_SetMode); -GET_FUNCTION(MIXER_Enable); -#endif - -return MODULE_START_FUNCTION; - -} -#if defined (WIN32) -} -#endif - - - -#endif - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/mouse.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/mouse.h deleted file mode 100644 index 843039401..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/mouse.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2002-2017 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Wengier: MOUSE CLIPBOARD support - */ - -#ifndef DOSBOX_MOUSE_H -#define DOSBOX_MOUSE_H - - -void Mouse_ShowCursor(void); -void Mouse_HideCursor(void); - -bool Mouse_SetPS2State(bool use); - -void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs); - - -void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate); -#if C_CLIPBOARD -const char* Mouse_GetSelected(int x1, int y1, int x2, int y2, int w, int h); -void Mouse_Select(int x1, int y1, int x2, int y2, int w, int h); -void Restore_Text(int x1, int y1, int x2, int y2, int w, int h); -#endif -void Mouse_CursorSet(float x,float y); -void Mouse_ButtonPressed(Bit8u button); -void Mouse_ButtonReleased(Bit8u button); - -void Mouse_AutoLock(bool enable); -void Mouse_BeforeNewVideoMode(bool setmode); -void Mouse_AfterNewVideoMode(bool setmode); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/paging.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/paging.h deleted file mode 100644 index 8766238c7..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/paging.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_PAGING_H -#define DOSBOX_PAGING_H - - -// disable this to reduce the size of the TLB -// NOTE: does not work with the dynamic core (dynrec is fine) -#define USE_FULL_TLB - -#include "../types_compat.h" - -class I386_DOSBOX; -namespace I386_DOSBOX { - -class PageDirectory; - -#define MEM_PAGE_SIZE (4096) -#define XMS_START (0x110) - -#if defined(USE_FULL_TLB) -#define TLB_SIZE (1024*1024) -#else -#define TLB_SIZE 65536 // This must a power of 2 and greater then LINK_START -#define BANK_SHIFT 28 -#define BANK_MASK 0xffff // always the same as TLB_SIZE-1? -#define TLB_BANKS ((1024*1024/TLB_SIZE)-1) -#endif - -#define PFLAG_READABLE 0x1 -#define PFLAG_WRITEABLE 0x2 -#define PFLAG_HASROM 0x4 -#define PFLAG_HASCODE 0x8 //Page contains dynamic code -#define PFLAG_NOCODE 0x10 //No dynamic code can be generated here -#define PFLAG_INIT 0x20 //No dynamic code can be generated here - -#define LINK_START ((1024+64)/4) //Start right after the HMA - -//Allow 128 mb of memory to be linked -#define PAGING_LINKS (128*1024/4) - -#define LINK_TOTAL (64*1024) - -#define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3) - -struct PF_Entry { - Bitu cs; - Bitu eip; - Bitu page_addr; - Bitu mpl; -}; - -#define PF_QUEUESIZE 16 -static struct { - Bitu used; - PF_Entry entries[PF_QUEUESIZE]; -} pf_queue; - - -class PageHandler : public MinimumSkelton{ - I386_DOSBOX *d_parent; -public: - PageHandler(DEVICE *parent) : MinimumSkelton(parent) - { - d_parent = static_cast(parent); - } - virtual ~PageHandler() { } - virtual Bitu readb(PhysPt addr); - virtual Bitu readw(PhysPt addr); - virtual Bitu readd(PhysPt addr); - virtual void writeb(PhysPt addr,Bitu val); - virtual void writew(PhysPt addr,Bitu val); - virtual void writed(PhysPt addr,Bitu val); - virtual HostPt GetHostReadPt(Bitu phys_page); - virtual HostPt GetHostWritePt(Bitu phys_page); - virtual bool readb_checked(PhysPt addr,Bit8u * val); - virtual bool readw_checked(PhysPt addr,Bit16u * val); - virtual bool readd_checked(PhysPt addr,Bit32u * val); - virtual bool writeb_checked(PhysPt addr,Bitu val); - virtual bool writew_checked(PhysPt addr,Bitu val); - virtual bool writed_checked(PhysPt addr,Bitu val); - - inline Bit8u phys_readb(Bit32u addr); - inline Bit16u phys_readw(Bit32u addr); - inline Bit32u phys_readd(Bit32u addr); - - inline void phys_writeb(Bit32u addr, Bit8u val); - inline void phys_writew(Bit32u addr, Bit16u val); - inline void phys_writed(Bit32u addr, Bit32u val); - - INLINE void InitPageUpdateLink(Bitu relink,PhysPt addr); - INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry); - INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2); - INLINE void InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry); - - PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode); - Bits PageFaultCore(void); - Bitu flags; -}; - -inline Bit8u PageHandler::phys_readb(Bit32u addr) -{ - return d_parent->read_data8(addr); -} -inline Bit16u PageHandler::phys_readw(Bit32u addr) -{ - return d_parent->read_data16(addr); -} - -inline Bit32u PageHandler::phys_readd(Bit32u addr) -{ - return d_parent->read_data32(addr); -} - -inline void PageHandler::phys_writeb(Bit32u addr, Bit32u val) -{ - d_parent->write_data8(addr, val); -} - -inline void PageHandler::phys_writew(Bit32u addr, Bit32u val) -{ - d_parent->write_data16(addr, val); -} - -inline void PageHandler::phys_writed(Bit32u addr, Bit32u val) -{ - d_parent->write_data32(addr, val); -} -/* Some other functions */ -//void PAGING_Enable(bool enabled); -//bool PAGING_Enabled(void); - -//Bitu PAGING_GetDirBase(void); -//void PAGING_SetDirBase(Bitu cr3); -//void PAGING_InitTLB(void); -//void PAGING_ClearTLB(void); - -//void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); -//void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page); -//void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); -/* This maps the page directly, only use when paging is disabled */ -//void PAGING_MapPage(Bitu lin_page,Bitu phys_page); -//bool PAGING_MakePhysPage(Bitu & page); -//bool PAGING_ForcePageInit(Bitu lin_addr); - -//void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler); -//void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); -//void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); - - -#ifdef _MSC_VER -#pragma pack (1) -#endif -struct X86_PageEntryBlock{ -#ifdef WORDS_BIGENDIAN - Bit32u base:20; - Bit32u avl:3; - Bit32u g:1; - Bit32u pat:1; - Bit32u d:1; - Bit32u a:1; - Bit32u pcd:1; - Bit32u pwt:1; - Bit32u us:1; - Bit32u wr:1; - Bit32u p:1; -#else - Bit32u p:1; - Bit32u wr:1; - Bit32u us:1; - Bit32u pwt:1; - Bit32u pcd:1; - Bit32u a:1; - Bit32u d:1; - Bit32u pat:1; - Bit32u g:1; - Bit32u avl:3; - Bit32u base:20; -#endif -} GCC_ATTRIBUTE(packed); -#ifdef _MSC_VER -#pragma pack () -#endif - - -union X86PageEntry { - Bit32u load; - X86_PageEntryBlock block; -}; - -#if !defined(USE_FULL_TLB) -typedef struct { - HostPt read; - HostPt write; - PageHandler * readhandler; - PageHandler * writehandler; - Bit32u phys_page; -} tlb_entry; -#endif - -struct PagingBlock { - Bitu cr3; - Bitu cr2; - struct { - Bitu page; - PhysPt addr; - } base; -#if defined(USE_FULL_TLB) - struct { - HostPt read[TLB_SIZE]; - HostPt write[TLB_SIZE]; - PageHandler * readhandler[TLB_SIZE]; - PageHandler * writehandler[TLB_SIZE]; - Bit32u phys_page[TLB_SIZE]; - } tlb; -#else - tlb_entry tlbh[TLB_SIZE]; - tlb_entry *tlbh_banks[TLB_BANKS]; -#endif - struct { - Bitu used; - Bit32u entries[PAGING_LINKS]; - } links; - Bit32u firstmb[LINK_START]; - bool enabled; -}; - -//extern PagingBlock paging; - -/* Some support functions */ - -//PageHandler * MEM_GetPageHandler(Bitu phys_page); - - -/* Unaligned address handlers */ -//Bit16u mem_unalignedreadw(PhysPt address); -//Bit32u mem_unalignedreadd(PhysPt address); -//void mem_unalignedwritew(PhysPt address,Bit16u val); -//void mem_unalignedwrited(PhysPt address,Bit32u val); - -//bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val); -//bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val); -//bool mem_unalignedwritew_checked(PhysPt address,Bit16u val); -//bool mem_unalignedwrited_checked(PhysPt address,Bit32u val); - - -}; -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/pci_bus.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/pci_bus.h deleted file mode 100644 index f8b729e86..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/pci_bus.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_PCI_H -#define DOSBOX_PCI_H - -//#define PCI_FUNCTIONALITY_ENABLED 0 - -#if defined PCI_FUNCTIONALITY_ENABLED - -#define PCI_MAX_PCIDEVICES 10 -#define PCI_MAX_PCIFUNCTIONS 8 - - -class PCI_Device { -private: - Bits pci_id, pci_subfunction; - Bit16u vendor_id, device_id; - - // subdevices declarations, they will respond to pci functions 1 to 7 - // (main device is attached to function 0) - Bitu num_subdevices; - PCI_Device* subdevices[PCI_MAX_PCIFUNCTIONS-1]; - -public: - PCI_Device(Bit16u vendor, Bit16u device); - - Bits PCIId(void) { - return pci_id; - } - Bits PCISubfunction(void) { - return pci_subfunction; - } - Bit16u VendorID(void) { - return vendor_id; - } - Bit16u DeviceID(void) { - return device_id; - } - - void SetPCIId(Bitu number, Bits subfct); - - bool AddSubdevice(PCI_Device* dev); - void RemoveSubdevice(Bits subfct); - - PCI_Device* GetSubdevice(Bits subfct); - - Bit16u NumSubdevices(void) { - if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return (Bit16u)(PCI_MAX_PCIFUNCTIONS-1); - return (Bit16u)num_subdevices; - } - - Bits GetNextSubdeviceNumber(void) { - if (num_subdevices>=PCI_MAX_PCIFUNCTIONS-1) return -1; - return (Bits)num_subdevices+1; - } - - virtual Bits ParseReadRegister(Bit8u regnum)=0; - virtual bool OverrideReadRegister(Bit8u regnum, Bit8u* rval, Bit8u* rval_mask)=0; - virtual Bits ParseWriteRegister(Bit8u regnum,Bit8u value)=0; - virtual bool InitializeRegisters(Bit8u registers[256])=0; - -}; - -bool PCI_IsInitialized(); - -RealPt PCI_GetPModeInterface(void); - -#endif - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/pic.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/pic.h deleted file mode 100644 index 77691f2a9..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/pic.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_PIC_H -#define DOSBOX_PIC_H - - -/* CPU Cycle Timing */ -extern Bit32s CPU_Cycles; -extern Bit32s CPU_CycleLeft; -extern Bit32s CPU_CycleMax; - -typedef void (PIC_EOIHandler) (void); -typedef void (* PIC_EventHandler)(Bitu val); - - -extern Bitu PIC_IRQCheck; -extern Bitu PIC_Ticks; - -static INLINE float PIC_TickIndex(void) { - return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax; -} - -static INLINE Bits PIC_TickIndexND(void) { - return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles; -} - -static INLINE Bits PIC_MakeCycles(double amount) { - return (Bits)(CPU_CycleMax*amount); -} - -static INLINE double PIC_FullIndex(void) { - return PIC_Ticks+(double)PIC_TickIndex(); -} - -void PIC_ActivateIRQ(Bitu irq); -void PIC_DeActivateIRQ(Bitu irq); - -void PIC_runIRQs(void); -bool PIC_RunQueue(void); - -//Delay in milliseconds -void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0); -void PIC_RemoveEvents(PIC_EventHandler handler); -void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val); - -void PIC_SetIRQMask(Bitu irq, bool masked); -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/programs.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/programs.h deleted file mode 100644 index 04db83c17..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/programs.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_PROGRAMS_H -#define DOSBOX_PROGRAMS_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_DOS_INC_H -#include "dos_inc.h" -#endif - -#ifndef CH_LIST -#define CH_LIST -#include -#endif - -#ifndef CH_STRING -#define CH_STRING -#include -#endif - -class CommandLine { -public: - CommandLine(int argc,char const * const argv[]); - CommandLine(char const * const name,char const * const cmdline); - const char * GetFileName(){ return file_name.c_str();} - - bool FindExist(char const * const name,bool remove=false); - bool FindHex(char const * const name,int & value,bool remove=false); - bool FindInt(char const * const name,int & value,bool remove=false); - bool FindString(char const * const name,std::string & value,bool remove=false); - bool FindCommand(unsigned int which,std::string & value); - bool FindStringBegin(char const * const begin,std::string & value, bool remove=false); - bool FindStringRemain(char const * const name,std::string & value); - bool FindStringRemainBegin(char const * const name,std::string & value); - bool GetStringRemain(std::string & value); - int GetParameterFromList(const char* const params[], std::vector & output); - void FillVector(std::vector & vector); - unsigned int GetCount(void); - void Shift(unsigned int amount=1); - Bit16u Get_arglength(); - -private: - typedef std::list::iterator cmd_it; - std::list cmds; - std::string file_name; - bool FindEntry(char const * const name,cmd_it & it,bool neednext=false); -}; - -class Program { -public: - Program(); - virtual ~Program(){ - delete cmd; - delete psp; - } - std::string temp_line; - CommandLine * cmd; - DOS_PSP * psp; - virtual void Run(void)=0; - bool GetEnvStr(const char * entry,std::string & result); - bool GetEnvNum(Bitu num,std::string & result); - Bitu GetEnvCount(void); - bool SetEnv(const char * entry,const char * new_string); - void WriteOut(const char * format,...); /* Write to standard output */ - void WriteOut_NoParsing(const char * format); /* Write to standard output, no parsing */ - void ChangeToLongCmd(); - -}; - -typedef void (PROGRAMS_Main)(Program * * make); -void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/regs.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/regs.h deleted file mode 100644 index 259ab695d..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/regs.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_REGS_H -#define DOSBOX_REGS_H - -#ifndef DOSBOX_MEM_H -#include "mem.h" -#endif - -#define FLAG_CF 0x00000001 -#define FLAG_PF 0x00000004 -#define FLAG_AF 0x00000010 -#define FLAG_ZF 0x00000040 -#define FLAG_SF 0x00000080 -#define FLAG_OF 0x00000800 - -#define FLAG_TF 0x00000100 -#define FLAG_IF 0x00000200 -#define FLAG_DF 0x00000400 - -#define FLAG_IOPL 0x00003000 -#define FLAG_NT 0x00004000 -#define FLAG_VM 0x00020000 -#define FLAG_AC 0x00040000 -#define FLAG_ID 0x00200000 - -#define FMASK_TEST (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF) -#define FMASK_NORMAL (FMASK_TEST | FLAG_DF | FLAG_TF | FLAG_IF ) -#define FMASK_ALL (FMASK_NORMAL | FLAG_IOPL | FLAG_NT) - -#define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE - -#define GETFLAG(TYPE) (reg_flags & FLAG_ ## TYPE) -#define GETFLAGBOOL(TYPE) ((reg_flags & FLAG_ ## TYPE) ? true : false ) - -#define GETFLAG_IOPL ((reg_flags & FLAG_IOPL) >> 12) - -struct Segment { - Bit16u val; - PhysPt phys; /* The phyiscal address start in emulated machine */ -}; - -enum SegNames { es=0,cs,ss,ds,fs,gs}; - -struct Segments { - Bit16u val[8]; - PhysPt phys[8]; -}; - -union GenReg32 { - Bit32u dword[1]; - Bit16u word[2]; - Bit8u byte[4]; -}; - -#ifdef WORDS_BIGENDIAN - -#define DW_INDEX 0 -#define W_INDEX 1 -#define BH_INDEX 2 -#define BL_INDEX 3 - -#else - -#define DW_INDEX 0 -#define W_INDEX 0 -#define BH_INDEX 1 -#define BL_INDEX 0 - -#endif - -struct CPU_Regs { - GenReg32 regs[8],ip; - Bitu flags; -}; - -extern Segments Segs; -extern CPU_Regs cpu_regs; - -static INLINE PhysPt SegPhys(SegNames index) { - return Segs.phys[index]; -} - -static INLINE Bit16u SegValue(SegNames index) { - return (Bit16u)Segs.val[index]; -} - -static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { - return RealMake(SegValue(index),off); -} - - -static INLINE void SegSet16(Bitu index,Bit16u val) { - Segs.val[index]=val; - Segs.phys[index]=val << 4; -} - -enum { - REGI_AX, REGI_CX, REGI_DX, REGI_BX, - REGI_SP, REGI_BP, REGI_SI, REGI_DI -}; - -enum { - REGI_AL, REGI_CL, REGI_DL, REGI_BL, - REGI_AH, REGI_CH, REGI_DH, REGI_BH -}; - - -//macros to convert a 3-bit register index to the correct register -#define reg_8l(reg) (cpu_regs.regs[(reg)].byte[BL_INDEX]) -#define reg_8h(reg) (cpu_regs.regs[(reg)].byte[BH_INDEX]) -#define reg_8(reg) ((reg) & 4 ? reg_8h((reg) & 3) : reg_8l((reg) & 3)) -#define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX]) -#define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX]) - -#define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX] -#define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX] -#define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX] -#define reg_eax cpu_regs.regs[REGI_AX].dword[DW_INDEX] - -#define reg_bl cpu_regs.regs[REGI_BX].byte[BL_INDEX] -#define reg_bh cpu_regs.regs[REGI_BX].byte[BH_INDEX] -#define reg_bx cpu_regs.regs[REGI_BX].word[W_INDEX] -#define reg_ebx cpu_regs.regs[REGI_BX].dword[DW_INDEX] - -#define reg_cl cpu_regs.regs[REGI_CX].byte[BL_INDEX] -#define reg_ch cpu_regs.regs[REGI_CX].byte[BH_INDEX] -#define reg_cx cpu_regs.regs[REGI_CX].word[W_INDEX] -#define reg_ecx cpu_regs.regs[REGI_CX].dword[DW_INDEX] - -#define reg_dl cpu_regs.regs[REGI_DX].byte[BL_INDEX] -#define reg_dh cpu_regs.regs[REGI_DX].byte[BH_INDEX] -#define reg_dx cpu_regs.regs[REGI_DX].word[W_INDEX] -#define reg_edx cpu_regs.regs[REGI_DX].dword[DW_INDEX] - -#define reg_si cpu_regs.regs[REGI_SI].word[W_INDEX] -#define reg_esi cpu_regs.regs[REGI_SI].dword[DW_INDEX] - -#define reg_di cpu_regs.regs[REGI_DI].word[W_INDEX] -#define reg_edi cpu_regs.regs[REGI_DI].dword[DW_INDEX] - -#define reg_sp cpu_regs.regs[REGI_SP].word[W_INDEX] -#define reg_esp cpu_regs.regs[REGI_SP].dword[DW_INDEX] - -#define reg_bp cpu_regs.regs[REGI_BP].word[W_INDEX] -#define reg_ebp cpu_regs.regs[REGI_BP].dword[DW_INDEX] - -#define reg_ip cpu_regs.ip.word[W_INDEX] -#define reg_eip cpu_regs.ip.dword[DW_INDEX] - -#define reg_flags cpu_regs.flags - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/render.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/render.h deleted file mode 100644 index f2c53475e..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/render.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_RENDER_H -#define DOSBOX_RENDER_H - -// 0: complex scalers off, scaler cache off, some simple scalers off, memory requirements reduced -// 1: complex scalers off, scaler cache off, all simple scalers on -// 2: complex scalers off, scaler cache on -// 3: complex scalers on -#define RENDER_USE_ADVANCED_SCALERS 3 - -#include "../src/gui/render_scalers.h" - -#define RENDER_SKIP_CACHE 16 -//Enable this for scalers to support 0 input for empty lines -//#define RENDER_NULL_INPUT - -typedef struct { - struct { - Bit8u red; - Bit8u green; - Bit8u blue; - Bit8u unused; - } rgb[256]; - union { - Bit16u b16[256]; - Bit32u b32[256]; - } lut; - bool changed; - Bit8u modified[256]; - Bitu first; - Bitu last; -} RenderPal_t; - -typedef struct { - struct { - Bitu width, start; - Bitu height; - Bitu bpp; - bool dblw,dblh; - double ratio; - float fps; - } src; - struct { - Bitu count; - Bitu max; - Bitu index; - Bit8u hadSkip[RENDER_SKIP_CACHE]; - } frameskip; - struct { - Bitu size; - scalerMode_t inMode; - scalerMode_t outMode; - scalerOperation_t op; - bool clearCache; - bool forced; - ScalerLineHandler_t lineHandler; - ScalerLineHandler_t linePalHandler; - ScalerComplexHandler_t complexHandler; - Bitu blocks, lastBlock; - Bitu outPitch; - Bit8u *outWrite; - Bitu cachePitch; - Bit8u *cacheRead; - Bitu inHeight, inLine, outLine; - } scale; - RenderPal_t pal; - bool updating; - bool active; - bool aspect; - bool fullFrame; -} Render_t; - -extern Render_t render; -extern ScalerLineHandler_t RENDER_DrawLine; -void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh); -bool RENDER_StartUpdate(void); -void RENDER_EndUpdate(bool abort); -void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue); - - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/serialport.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/serialport.h deleted file mode 100644 index b4641cccd..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/serialport.h +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_SERIALPORT_H -#define DOSBOX_SERIALPORT_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_INOUT_H -#include "inout.h" -#endif -#ifndef DOSBOX_TIMER_H -#include "timer.h" -#endif -#ifndef DOSBOX_DOS_INC_H -#include "dos_inc.h" -#endif -#ifndef DOSBOX_PROGRAMS_H -#include "programs.h" -#endif - -// set this to 1 for serial debugging in release mode -#define SERIAL_DBG_FORCED 0 - -#if (C_DEBUG || SERIAL_DBG_FORCED) -#define SERIAL_DEBUG 1 -#endif - -#if SERIAL_DEBUG -#include "hardware.h" -#endif - -// Serial port interface - -class MyFifo { -public: - MyFifo(Bitu maxsize_) { - maxsize=size=maxsize_; - pos=used=0; - data=new Bit8u[size]; - } - ~MyFifo() { - delete[] data; - } - INLINE Bitu getFree(void) { - return size-used; - } - bool isEmpty() { - return used==0; - } - bool isFull() { - return (size-used)==0; - } - - INLINE Bitu getUsage(void) { - return used; - } - void setSize(Bitu newsize) - { - size=newsize; - pos=used=0; - } - void clear(void) { - pos=used=0; - data[0]=0; - } - - bool addb(Bit8u _val) { - Bitu where=pos+used; - if (where>=size) where-=size; - if(used>=size) { - // overwrite last byte - if(where==0) where=size-1; - else where--; - data[where]=_val; - return false; - } - data[where]=_val; - used++; - return true; - } - Bit8u getb() { - if (!used) return data[pos]; - Bitu where=pos; - used--; - if(used) pos++; - if (pos>=size) pos-=size; - return data[where]; - } - Bit8u getTop() { - Bitu where=pos+used; - if (where>=size) where-=size; - if(used>=size) { - if(where==0) where=size-1; - else where--; - } - return data[where]; - } - - Bit8u probeByte() { - return data[pos]; - } -private: - Bit8u * data; - Bitu maxsize,size,pos,used; -}; - -class CSerial { -public: - -#if SERIAL_DEBUG - FILE * debugfp; - bool dbg_modemcontrol; // RTS,CTS,DTR,DSR,RI,CD - bool dbg_serialtraffic; - bool dbg_register; - bool dbg_interrupt; - bool dbg_aux; - void log_ser(bool active, char const* format,...); -#endif - - static bool getBituSubstring(const char* name,Bitu* data, CommandLine* cmd); - - bool InstallationSuccessful;// check after constructing. If - // something was wrong, delete it right away. - - // Constructor takes com port number (0-3) - CSerial(Bitu id, CommandLine* cmd); - - virtual ~CSerial(); - - IO_ReadHandleObject ReadHandler[8]; - IO_WriteHandleObject WriteHandler[8]; - - float bytetime; // how long a byte takes to transmit/receive in milliseconds - void changeLineProperties(); - Bitu idnumber; - - void setEvent(Bit16u type, float duration); - void removeEvent(Bit16u type); - void handleEvent(Bit16u type); - virtual void handleUpperEvent(Bit16u type)=0; - - // defines for event type -#define SERIAL_TX_LOOPBACK_EVENT 0 -#define SERIAL_THR_LOOPBACK_EVENT 1 -#define SERIAL_ERRMSG_EVENT 2 - -#define SERIAL_TX_EVENT 3 -#define SERIAL_RX_EVENT 4 -#define SERIAL_POLLING_EVENT 5 -#define SERIAL_THR_EVENT 6 -#define SERIAL_RX_TIMEOUT_EVENT 7 - -#define SERIAL_BASE_EVENT_COUNT 7 - -#define COMNUMBER idnumber+1 - - Bitu irq; - - // CSerial requests an update of the input lines - virtual void updateMSR()=0; - - // Control lines from prepherial to serial port - bool getDTR(); - bool getRTS(); - - bool getRI(); - bool getCD(); - bool getDSR(); - bool getCTS(); - - void setRI(bool value); - void setDSR(bool value); - void setCD(bool value); - void setCTS(bool value); - - // From serial port to prepherial - // set output lines - virtual void setRTSDTR(bool rts, bool dtr)=0; - virtual void setRTS(bool val)=0; - virtual void setDTR(bool val)=0; - - // Register access - void Write_THR(Bit8u data); - void Write_IER(Bit8u data); - void Write_FCR(Bit8u data); - void Write_LCR(Bit8u data); - void Write_MCR(Bit8u data); - // Really old hardware seems to have the delta part of this register writable - void Write_MSR(Bit8u data); - void Write_SPR(Bit8u data); - void Write_reserved(Bit8u data, Bit8u address); - - Bitu Read_RHR(); - Bitu Read_IER(); - Bitu Read_ISR(); - Bitu Read_LCR(); - Bitu Read_MCR(); - Bitu Read_LSR(); - Bitu Read_MSR(); - Bitu Read_SPR(); - - // If a byte comes from loopback or prepherial, put it in here. - void receiveByte(Bit8u data); - void receiveByteEx(Bit8u data, Bit8u error); - - // If an error was received, put it here (in LSR register format) - void receiveError(Bit8u errorword); - - // depratched - // connected device checks, if port can receive data: - bool CanReceiveByte(); - - // when THR was shifted to TX - void ByteTransmitting(); - - // When done sending, notify here - void ByteTransmitted(); - - // Transmit byte to prepherial - virtual void transmitByte(Bit8u val, bool first)=0; - - // switch break state to the passed value - virtual void setBreak(bool value)=0; - - // change baudrate, number of bits, parity, word length al at once - virtual void updatePortConfig(Bit16u divider, Bit8u lcr)=0; - - void Init_Registers(); - - bool Putchar(Bit8u data, bool wait_dtr, bool wait_rts, Bitu timeout); - bool Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout); - - -private: - - DOS_Device* mydosdevice; - - // I used this spec: st16c450v420.pdf - - void ComputeInterrupts(); - - // a sub-interrupt is triggered - void rise(Bit8u priority); - - // clears the pending sub-interrupt - void clear(Bit8u priority); - - #define ERROR_PRIORITY 4 // overrun, parity error, frame error, break - #define RX_PRIORITY 1 // a byte has been received - #define TX_PRIORITY 2 // tx buffer has become empty - #define MSR_PRIORITY 8 // CRS, DSR, RI, DCD change - #define TIMEOUT_PRIORITY 0x10 - #define NONE_PRIORITY 0 - - Bit8u waiting_interrupts; // these are on, but maybe not enabled - - // 16C550 - // read/write name - - Bit16u baud_divider; - #define RHR_OFFSET 0 // r Receive Holding Register, also LSB of Divisor Latch (r/w) - // Data: whole byte - #define THR_OFFSET 0 // w Transmit Holding Register - // Data: whole byte - Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch - #define IER_OFFSET 1 - - bool irq_active; - - #define RHR_INT_Enable_MASK 0x1 - #define THR_INT_Enable_MASK 0x2 - #define Receive_Line_INT_Enable_MASK 0x4 - #define Modem_Status_INT_Enable_MASK 0x8 - - Bit8u ISR; // r Interrupt Status Register - #define ISR_OFFSET 2 - - #define ISR_CLEAR_VAL 0x1 - #define ISR_FIFOTIMEOUT_VAL 0xc - #define ISR_ERROR_VAL 0x6 - #define ISR_RX_VAL 0x4 - #define ISR_TX_VAL 0x2 - #define ISR_MSR_VAL 0x0 -public: - Bit8u LCR; // r/w Line Control Register -private: - #define LCR_OFFSET 3 - // bit0: word length bit0 - // bit1: word length bit1 - // bit2: stop bits - // bit3: parity enable - // bit4: even parity - // bit5: set parity - // bit6: set break - // bit7: divisor latch enable - - - #define LCR_BREAK_MASK 0x40 - #define LCR_DIVISOR_Enable_MASK 0x80 - #define LCR_PORTCONFIG_MASK 0x3F - - #define LCR_PARITY_NONE 0x0 - #define LCR_PARITY_ODD 0x8 - #define LCR_PARITY_EVEN 0x18 - #define LCR_PARITY_MARK 0x28 - #define LCR_PARITY_SPACE 0x38 - - #define LCR_DATABITS_5 0x0 - #define LCR_DATABITS_6 0x1 - #define LCR_DATABITS_7 0x2 - #define LCR_DATABITS_8 0x3 - - #define LCR_STOPBITS_1 0x0 - #define LCR_STOPBITS_MORE_THAN_1 0x4 - - // Modem Control Register - // r/w - #define MCR_OFFSET 4 - bool dtr; // bit0: DTR - bool rts; // bit1: RTS - bool op1; // bit2: OP1 - bool op2; // bit3: OP2 - bool loopback; // bit4: loop back enable - - #define MCR_DTR_MASK 0x1 - #define MCR_RTS_MASK 0x2 - #define MCR_OP1_MASK 0x4 - #define MCR_OP2_MASK 0x8 - #define MCR_LOOPBACK_Enable_MASK 0x10 -public: - Bit8u LSR; // r Line Status Register -private: - - #define LSR_OFFSET 5 - - #define LSR_RX_DATA_READY_MASK 0x1 - #define LSR_OVERRUN_ERROR_MASK 0x2 - #define LSR_PARITY_ERROR_MASK 0x4 - #define LSR_FRAMING_ERROR_MASK 0x8 - #define LSR_RX_BREAK_MASK 0x10 - #define LSR_TX_HOLDING_EMPTY_MASK 0x20 - #define LSR_TX_EMPTY_MASK 0x40 - - #define LSR_ERROR_MASK 0x1e - - // error printing - bool errormsg_pending; - Bitu framingErrors; - Bitu parityErrors; - Bitu overrunErrors; - Bitu txOverrunErrors; - Bitu overrunIF0; - Bitu breakErrors; - - - // Modem Status Register - // r - #define MSR_OFFSET 6 - bool d_cts; // bit0: deltaCTS - bool d_dsr; // bit1: deltaDSR - bool d_ri; // bit2: deltaRI - bool d_cd; // bit3: deltaCD - bool cts; // bit4: CTS - bool dsr; // bit5: DSR - bool ri; // bit6: RI - bool cd; // bit7: CD - - #define MSR_delta_MASK 0xf - #define MSR_LINE_MASK 0xf0 - - #define MSR_dCTS_MASK 0x1 - #define MSR_dDSR_MASK 0x2 - #define MSR_dRI_MASK 0x4 - #define MSR_dCD_MASK 0x8 - #define MSR_CTS_MASK 0x10 - #define MSR_DSR_MASK 0x20 - #define MSR_RI_MASK 0x40 - #define MSR_CD_MASK 0x80 - - Bit8u SPR; // r/w Scratchpad Register - #define SPR_OFFSET 7 - - - // For loopback purposes... - Bit8u loopback_data; - void transmitLoopbackByte(Bit8u val, bool value); - - // 16C550 (FIFO) - public: // todo remove - MyFifo* rxfifo; - private: - MyFifo* txfifo; - MyFifo* errorfifo; - Bitu errors_in_fifo; - Bitu rx_interrupt_threshold; - Bitu fifosize; - Bit8u FCR; - bool sync_guardtime; - #define FIFO_STATUS_ACTIVE 0xc0 // FIFO is active AND works ;) - #define FIFO_ERROR 0x80 - #define FCR_ACTIVATE 0x01 - #define FCR_CLEAR_RX 0x02 - #define FCR_CLEAR_TX 0x04 - #define FCR_OFFSET 2 - #define FIFO_FLOWCONTROL 0x20 -}; - -extern CSerial* serialports[]; -const Bit8u serial_defaultirq[] = { 4, 3, 4, 3 }; -const Bit16u serial_baseaddr[] = {0x3f8,0x2f8,0x3e8,0x2e8}; -const char* const serial_comname[]={"COM1","COM2","COM3","COM4"}; - -// the COM devices - -class device_COM : public DOS_Device { -public: - // Creates a COM device that communicates with the num-th parallel port, i.e. is LPTnum - device_COM(class CSerial* sc); - ~device_COM(); - bool Read(Bit8u * data,Bit16u * size); - bool Write(Bit8u * data,Bit16u * size); - bool Seek(Bit32u * pos,Bit32u type); - bool Close(); - Bit16u GetInformation(void); -private: - CSerial* sclass; -}; - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/setup.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/setup.h deleted file mode 100644 index 7dc9f401b..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/setup.h +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_SETUP_H -#define DOSBOX_SETUP_H - -#ifdef _MSC_VER -#pragma warning ( disable : 4786 ) -#pragma warning ( disable : 4290 ) -#endif - - -#ifndef CH_LIST -#define CH_LIST -#include -#endif - -#ifndef CH_VECTOR -#define CH_VECTOR -#include -#endif - -#ifndef CH_STRING -#define CH_STRING -#include -#endif - -#ifndef CH_CSTDIO -#define CH_CSTDIO -#include -#endif - - -class Hex { -private: - int _hex; -public: - Hex(int in):_hex(in) { }; - Hex():_hex(0) { }; - bool operator==(Hex const& other) {return _hex == other._hex;} - operator int () const { return _hex; } - -}; - -class Value { -/* - * Multitype storage container that is aware of the currently stored type in it. - * Value st = "hello"; - * Value in = 1; - * st = 12 //Exception - * in = 12 //works - */ -private: - Hex _hex; - bool _bool; - int _int; - std::string* _string; - double _double; -public: - class WrongType { }; // Conversion error class - enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type; - - /* Constructors */ - Value() :_string(0), type(V_NONE) { }; - Value(Hex in) :_hex(in), type(V_HEX) { }; - Value(int in) :_int(in), type(V_INT) { }; - Value(bool in) :_bool(in), type(V_BOOL) { }; - Value(double in) :_double(in), type(V_DOUBLE) { }; - Value(std::string const& in) :_string(new std::string(in)),type(V_STRING) { }; - Value(char const * const in) :_string(new std::string(in)),type(V_STRING) { }; - Value(Value const& in):_string(0) {plaincopy(in);} - ~Value() { destroy();}; - Value(std::string const& in,Etype _t) :_hex(0),_bool(false),_int(0),_string(0),_double(0),type(V_NONE) {SetValue(in,_t);} - - /* Assigment operators */ - Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));} - Value& operator= (int in) throw(WrongType) { return copy(Value(in));} - Value& operator= (bool in) throw(WrongType) { return copy(Value(in));} - Value& operator= (double in) throw(WrongType) { return copy(Value(in));} - Value& operator= (std::string const& in) throw(WrongType) { return copy(Value(in));} - Value& operator= (char const * const in) throw(WrongType) { return copy(Value(in));} - Value& operator= (Value const& in) throw(WrongType) { return copy(Value(in));} - - bool operator== (Value const & other); - operator bool () const throw(WrongType); - operator Hex () const throw(WrongType); - operator int () const throw(WrongType); - operator double () const throw(WrongType); - operator char const* () const throw(WrongType); - bool SetValue(std::string const& in,Etype _type = V_CURRENT) throw(WrongType); - std::string ToString() const; - -private: - void destroy() throw(); - Value& copy(Value const& in) throw(WrongType); - void plaincopy(Value const& in) throw(); - bool set_hex(std::string const& in); - bool set_int(std::string const&in); - bool set_bool(std::string const& in); - void set_string(std::string const& in); - bool set_double(std::string const& in); -}; - -class Property { -public: - struct Changeable { enum Value {Always, WhenIdle,OnlyAtStart};}; - const std::string propname; - - Property(std::string const& _propname, Changeable::Value when):propname(_propname),change(when) { } - void Set_values(const char * const * in); - void Set_help(std::string const& str); - char const* Get_help(); - virtual bool SetValue(std::string const& str)=0; - Value const& GetValue() const { return value;} - Value const& Get_Default_Value() const { return default_value; } - //CheckValue returns true, if value is in suggested_values; - //Type specific properties are encouraged to override this and check for type - //specific features. - virtual bool CheckValue(Value const& in, bool warn); -public: - virtual ~Property(){ } - virtual const std::vector& GetValues() const; - Value::Etype Get_type(){return default_value.type;} - Changeable::Value getChange() {return change;} - -protected: - //Set interval value to in or default if in is invalid. force always sets the value. - //Can be overriden to set a different value if invalid. - virtual bool SetVal(Value const& in, bool forced,bool warn=true) { - if(forced || CheckValue(in,warn)) { - value = in; return true; - } else { - value = default_value; return false; - } - } - Value value; - std::vector suggested_values; - typedef std::vector::iterator iter; - Value default_value; - const Changeable::Value change; -}; - -class Prop_int:public Property { -public: - Prop_int(std::string const& _propname,Changeable::Value when, int _value) - :Property(_propname,when) { - default_value = value = _value; - min = max = -1; - } - Prop_int(std::string const& _propname,Changeable::Value when, int _min,int _max,int _value) - :Property(_propname,when) { - default_value = value = _value; - min = _min; - max = _max; - } - int getMin() { return min;} - int getMax() { return max;} - void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;} - bool SetValue(std::string const& in); - ~Prop_int(){ } - virtual bool CheckValue(Value const& in, bool warn); - // Override SetVal, so it takes min,max in account when there are no suggested values - virtual bool SetVal(Value const& in, bool forced,bool warn=true); - -private: - Value min,max; -}; - -class Prop_double:public Property { -public: - Prop_double(std::string const & _propname, Changeable::Value when, double _value) - :Property(_propname,when){ - default_value = value = _value; - } - bool SetValue(std::string const& input); - ~Prop_double(){ } -}; - -class Prop_bool:public Property { -public: - Prop_bool(std::string const& _propname, Changeable::Value when, bool _value) - :Property(_propname,when) { - default_value = value = _value; - } - bool SetValue(std::string const& in); - ~Prop_bool(){ } -}; - -class Prop_string:public Property{ -public: - Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value) - :Property(_propname,when) { - default_value = value = _value; - } - bool SetValue(std::string const& in); - virtual bool CheckValue(Value const& in, bool warn); - ~Prop_string(){ } -}; -class Prop_path:public Prop_string{ -public: - std::string realpath; - Prop_path(std::string const& _propname, Changeable::Value when, char const * const _value) - :Prop_string(_propname,when,_value) { - default_value = value = _value; - realpath = _value; - } - bool SetValue(std::string const& in); - ~Prop_path(){ } -}; - -class Prop_hex:public Property { -public: - Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value) - :Property(_propname,when) { - default_value = value = _value; - } - bool SetValue(std::string const& in); - ~Prop_hex(){ } -}; - -#define NO_SUCH_PROPERTY "PROP_NOT_EXIST" -class Section { -private: - typedef void (*SectionFunction)(Section*); - /* Wrapper class around startup and shutdown functions. the variable - * canchange indicates it can be called on configuration changes */ - struct Function_wrapper { - SectionFunction function; - bool canchange; - Function_wrapper(SectionFunction const _fun,bool _ch){ - function=_fun; - canchange=_ch; - } - }; - std::list initfunctions; - std::list destroyfunctions; - std::string sectionname; -public: - Section(std::string const& _sectionname):sectionname(_sectionname) { } - - void AddInitFunction(SectionFunction func,bool canchange=false); - void AddDestroyFunction(SectionFunction func,bool canchange=false); - void ExecuteInit(bool initall=true); - void ExecuteDestroy(bool destroyall=true); - const char* GetName() const {return sectionname.c_str();} - - virtual std::string GetPropValue(std::string const& _property) const =0; - virtual bool HandleInputline(std::string const& _line)=0; - virtual void PrintData(FILE* outfile) const =0; - virtual ~Section() { /*Children must call executedestroy ! */} -}; - -class Prop_multival; -class Prop_multival_remain; -class Section_prop:public Section { -private: - std::list properties; - typedef std::list::iterator it; - typedef std::list::const_iterator const_it; - -public: - Section_prop(std::string const& _sectionname):Section(_sectionname){} - Prop_int* Add_int(std::string const& _propname, Property::Changeable::Value when, int _value=0); - Prop_string* Add_string(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL); - Prop_path* Add_path(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL); - Prop_bool* Add_bool(std::string const& _propname, Property::Changeable::Value when, bool _value=false); - Prop_hex* Add_hex(std::string const& _propname, Property::Changeable::Value when, Hex _value=0); -// void Add_double(char const * const _propname, double _value=0.0); - Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep); - Prop_multival_remain *Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep); - - Property* Get_prop(int index); - int Get_int(std::string const& _propname) const; - const char* Get_string(std::string const& _propname) const; - bool Get_bool(std::string const& _propname) const; - Hex Get_hex(std::string const& _propname) const; - double Get_double(std::string const& _propname) const; - Prop_path* Get_path(std::string const& _propname) const; - Prop_multival* Get_multival(std::string const& _propname) const; - Prop_multival_remain* Get_multivalremain(std::string const& _propname) const; - bool HandleInputline(std::string const& gegevens); - void PrintData(FILE* outfile) const; - virtual std::string GetPropValue(std::string const& _property) const; - //ExecuteDestroy should be here else the destroy functions use destroyed properties - virtual ~Section_prop(); -}; - -class Prop_multival:public Property{ -protected: - Section_prop* section; - std::string separator; - void make_default_value(); -public: - Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),separator(sep) { - default_value = value = ""; - } - Section_prop *GetSection() { return section; } - const Section_prop *GetSection() const { return section; } - virtual bool SetValue(std::string const& input); - virtual const std::vector& GetValues() const; - ~Prop_multival() { delete section; } -}; //value bevat totale string. setvalue zet elk van de sub properties en checked die. - -class Prop_multival_remain:public Prop_multival{ -public: - Prop_multival_remain(std::string const& _propname, Changeable::Value when,std::string const& sep):Prop_multival(_propname,when,sep){ } - - virtual bool SetValue(std::string const& input); -}; - - -class Section_line: public Section{ -public: - Section_line(std::string const& _sectionname):Section(_sectionname){} - ~Section_line(){ExecuteDestroy(true);} - bool HandleInputline(std::string const& gegevens); - void PrintData(FILE* outfile) const; - virtual std::string GetPropValue(std::string const& _property) const; - std::string data; -}; - -class Module_base { - /* Base for all hardware and software "devices" */ -protected: - Section* m_configuration; -public: - Module_base(Section* configuration){m_configuration=configuration;}; -// Module_base(Section* configuration, SaveState* state) {}; - virtual ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required - /* Returns true if succesful.*/ - virtual bool Change_Config(Section* /*newconfig*/) {return false;} ; -}; -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/shell.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/shell.h deleted file mode 100644 index 25c984feb..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/shell.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2002-2017 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_SHELL_H -#define DOSBOX_SHELL_H - -#include -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif -#ifndef DOSBOX_PROGRAMS_H -#include "programs.h" -#endif - -#include -#include - -#define CMD_MAXLINE 4096 -#define CMD_MAXCMDS 20 -#define CMD_OLDSIZE 4096 -extern Bitu call_shellstop; -/* first_shell is used to add and delete stuff from the shell env - * by "external" programs. (config) */ -extern Program * first_shell; - -class DOS_Shell; - -class BatchFile { -public: - BatchFile(DOS_Shell * host,char const* const resolved_name,char const* const entered_name, char const * const cmd_line); - virtual ~BatchFile(); - virtual bool ReadLine(char * line); - bool Goto(char * where); - void Shift(void); - Bit16u file_handle; - Bit32u location; - bool echo; - DOS_Shell * shell; - BatchFile * prev; - CommandLine * cmd; - std::string filename; -}; - -class AutoexecEditor; -class DOS_Shell : public Program { -private: - friend class AutoexecEditor; - std::list l_history, l_completion; - - char *completion_start; - Bit16u completion_index; - -public: - - DOS_Shell(); - - void Run(void); - void RunInternal(void); //for command /C -/* A load of subfunctions */ - void ParseLine(char * line); - Bitu GetRedirection(char *s, char **ifn, char **ofn, char **toc, bool * append); - void InputCommand(char * line); - void ShowPrompt(); - void DoCommand(char * cmd); - bool Execute(char * name,char * args); - /* Checks if it matches a hardware-property */ - bool CheckConfig(char* cmd_in,char*line); -/* Some internal used functions */ - char * Which(char * name); -/* Some supported commands */ - void CMD_HELP(char * args); - void CMD_CHCP(char * args); - void CMD_CLS(char * args); - void CMD_COPY(char * args); - void CMD_DATE(char * args); - void CMD_TIME(char * args); - void CMD_DIR(char * args); - void CMD_DELETE(char * args); - void CMD_ECHO(char * args); - void CMD_EXIT(char * args); - void CMD_MKDIR(char * args); - void CMD_CHDIR(char * args); - void CMD_RMDIR(char * args); - void CMD_SET(char * args); - void CMD_IF(char * args); - void CMD_FOR(char * args); - void CMD_GOTO(char * args); - void CMD_TYPE(char * args); - void CMD_REM(char * args); - void CMD_RENAME(char * args); - void CMD_CALL(char * args); - void SyntaxError(void); - void CMD_PAUSE(char * args); - void CMD_SUBST(char* args); - void CMD_LOADHIGH(char* args); - void CMD_CHOICE(char * args); - void CMD_ATTRIB(char * args); - void CMD_PROMPT(char * args); - void CMD_PATH(char * args); - void CMD_SHIFT(char * args); - void CMD_VER(char * args); - void CMD_CHEV(char * args); - /* The shell's variables */ - Bit16u input_handle; - BatchFile * bf; - bool echo; - bool exit; - bool call; -}; - -struct SHELL_Cmd { - const char * name; /* Command name*/ - Bit32u flags; /* Flags about the command */ - void (DOS_Shell::*handler)(char * args); /* Handler for this command */ - const char * help; /* String with command help */ -}; - -/* Object to manage lines in the autoexec.bat The lines get removed from - * the file if the object gets destroyed. The environment is updated - * as well if the line set a a variable */ -class AutoexecObject{ -private: - bool installed; - std::string buf; -public: - AutoexecObject():installed(false){ }; - void Install(std::string const &in); - void InstallBefore(std::string const &in); - ~AutoexecObject(); -private: - void CreateAutoexec(void); -}; - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/support.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/support.h deleted file mode 100644 index e02c3d3a6..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/support.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2002-2017 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Wengier: LFN support - */ - - -#ifndef DOSBOX_SUPPORT_H -#define DOSBOX_SUPPORT_H - -#include -#include -#include -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -#if defined (_MSC_VER) /* MS Visual C++ */ -#define strcasecmp(a,b) stricmp(a,b) -#define strncasecmp(a,b,n) _strnicmp(a,b,n) -#endif - -#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) - -#ifdef HAVE_STRINGS_H -#include -#endif - -void strreplace(char * str,char o,char n); -char *ltrim(char *str); -char *rtrim(char *str); -char *trim(char * str); -char * upcase(char * str); -char * lowcase(char * str); - -bool ScanCMDBool(char * cmd,char const * const check); -char * ScanCMDRemain(char * cmd); -char * StripWord(char *&cmd); -char * StripArg(char *&cmd); -bool IsDecWord(char * word); -bool IsHexWord(char * word); -Bits ConvDecWord(char * word); -Bits ConvHexWord(char * word); - -void upcase(std::string &str); -void lowcase(std::string &str); - -#if defined(LINUX) -void utf8_to_sjis_copy(char *dst, char *src, int len); -void sjis_to_utf8_copy(char *dst, char *src, int len); -void sjis_to_utf16_copy(char *dst, char *src, int len); -void ChangeUtf8FileName(char *fullname); -#endif - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/timer.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/timer.h deleted file mode 100644 index e8abf3231..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/timer.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_TIMER_H -#define DOSBOX_TIMER_H - -/* underlying clock rate in HZ */ -#include - -#define PIT_TICK_RATE 1193182 - -#define GetTicks() SDL_GetTicks() - -typedef void (*TIMER_TickHandler)(void); - -/* Register a function that gets called everytime if 1 or more ticks pass */ -void TIMER_AddTickHandler(TIMER_TickHandler handler); -void TIMER_DelTickHandler(TIMER_TickHandler handler); - -/* This will add 1 milliscond to all timers */ -void TIMER_AddTick(void); - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/vga.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/vga.h deleted file mode 100644 index 69edc3817..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/vga.h +++ /dev/null @@ -1,535 +0,0 @@ - /* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_VGA_H -#define DOSBOX_VGA_H - -#ifndef DOSBOX_DOSBOX_H -#include "dosbox.h" -#endif - -//Don't enable keeping changes and mapping lfb probably... -#define VGA_LFB_MAPPED -//#define VGA_KEEP_CHANGES -#define VGA_CHANGE_SHIFT 9 - -class PageHandler; - - -enum VGAModes { - M_CGA2, M_CGA4, - M_EGA, M_VGA, - M_LIN4, M_LIN8, M_LIN15, M_LIN16, M_LIN32, - M_TEXT, - M_HERC_GFX, M_HERC_TEXT, - M_CGA16, M_TANDY2, M_TANDY4, M_TANDY16, M_TANDY_TEXT, - M_DCGA, - M_ERROR -}; - - -#define CLK_25 25175 -#define CLK_28 28322 - -#define MIN_VCO 180000 -#define MAX_VCO 360000 - -#define S3_CLOCK_REF 14318 /* KHz */ -#define S3_CLOCK(_M,_N,_R) ((S3_CLOCK_REF * ((_M) + 2)) / (((_N) + 2) * (1 << (_R)))) -#define S3_MAX_CLOCK 150000 /* KHz */ - -#define S3_XGA_1024 0x00 -#define S3_XGA_1152 0x01 -#define S3_XGA_640 0x40 -#define S3_XGA_800 0x80 -#define S3_XGA_1280 0xc0 -#define S3_XGA_WMASK (S3_XGA_640|S3_XGA_800|S3_XGA_1024|S3_XGA_1152|S3_XGA_1280) - -#define S3_XGA_8BPP 0x00 -#define S3_XGA_16BPP 0x10 -#define S3_XGA_32BPP 0x30 -#define S3_XGA_CMASK (S3_XGA_8BPP|S3_XGA_16BPP|S3_XGA_32BPP) - -typedef struct { - bool attrindex; -} VGA_Internal; - -typedef struct { -/* Memory handlers */ - Bitu mh_mask; - -/* Video drawing */ - Bitu display_start; - Bitu real_start; - bool retrace; /* A retrace is active */ - Bitu scan_len; - Bitu cursor_start; - -/* Some other screen related variables */ - Bitu line_compare; - bool chained; /* Enable or Disabled Chain 4 Mode */ - bool compatible_chain4; - - /* Pixel Scrolling */ - Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */ - Bit8u hlines_skip; - Bit8u bytes_skip; - Bit8u addr_shift; - -/* Specific stuff memory write/read handling */ - - Bit8u read_mode; - Bit8u write_mode; - Bit8u read_map_select; - Bit8u color_dont_care; - Bit8u color_compare; - Bit8u data_rotate; - Bit8u raster_op; - - Bit32u full_bit_mask; - Bit32u full_map_mask; - Bit32u full_not_map_mask; - Bit32u full_set_reset; - Bit32u full_not_enable_set_reset; - Bit32u full_enable_set_reset; - Bit32u full_enable_and_set_reset; -} VGA_Config; - -typedef enum { - PART, - DRAWLINE, - EGALINE -} Drawmode; - -typedef struct { - bool resizing; - Bitu width; - Bitu height; - Bitu blocks; - Bitu address; - Bitu panning; - Bitu bytes_skip; - Bit8u *linear_base; - Bitu linear_mask; - Bitu address_add; - Bitu line_length; - Bitu address_line_total; - Bitu address_line; - Bitu lines_total; - Bitu vblank_skip; - Bitu lines_done; - Bitu lines_scaled; - Bitu split_line; - Bitu parts_total; - Bitu parts_lines; - Bitu parts_left; - Bitu byte_panning_shift; - struct { - double framestart; - double vrstart, vrend; // V-retrace - double hrstart, hrend; // H-retrace - double hblkstart, hblkend; // H-blanking - double vblkstart, vblkend; // V-Blanking - double vdend, vtotal; - double hdend, htotal; - double parts; - } delay; - Bitu bpp; - double aspect_ratio; - bool double_scan; - bool doublewidth,doubleheight; - Bit8u font[64*1024]; - Bit8u * font_tables[2]; - Bitu blinking; - bool blink; - bool char9dot; - struct { - Bitu address; - Bit8u sline,eline; - Bit8u count,delay; - Bit8u enabled; - } cursor; - Drawmode mode; - bool vret_triggered; - bool vga_override; -} VGA_Draw; - -typedef struct { - Bit8u curmode; - Bit16u originx, originy; - Bit8u fstackpos, bstackpos; - Bit8u forestack[4]; - Bit8u backstack[4]; - Bit16u startaddr; - Bit8u posx, posy; - Bit8u mc[64][64]; -} VGA_HWCURSOR; - -typedef struct { - Bit8u reg_lock1; - Bit8u reg_lock2; - Bit8u reg_31; - Bit8u reg_35; - Bit8u reg_36; // RAM size - Bit8u reg_3a; // 4/8/doublepixel bit in there - Bit8u reg_40; // 8415/A functionality register - Bit8u reg_41; // BIOS flags - Bit8u reg_43; - Bit8u reg_45; // Hardware graphics cursor - Bit8u reg_50; - Bit8u reg_51; - Bit8u reg_52; - Bit8u reg_55; - Bit8u reg_58; - Bit8u reg_6b; // LFB BIOS scratchpad - Bit8u ex_hor_overflow; - Bit8u ex_ver_overflow; - Bit16u la_window; - Bit8u misc_control_2; - Bit8u ext_mem_ctrl; - Bitu xga_screen_width; - VGAModes xga_color_mode; - struct { - Bit8u r; - Bit8u n; - Bit8u m; - } clk[4],mclk; - struct { - Bit8u lock; - Bit8u cmd; - } pll; - VGA_HWCURSOR hgc; -} VGA_S3; - -typedef struct { - Bit8u mode_control; - Bit8u enable_bits; -} VGA_HERC; - -typedef struct { - Bit8u index; - Bit8u htotal; - Bit8u hdend; - Bit8u hsyncp; - Bit8u hsyncw; - Bit8u vtotal; - Bit8u vdend; - Bit8u vadjust; - Bit8u vsyncp; - Bit8u vsyncw; - Bit8u max_scanline; - Bit16u lightpen; - bool lightpen_triggered; - Bit8u cursor_start; - Bit8u cursor_end; -} VGA_OTHER; - -typedef struct { - Bit8u pcjr_flipflop; - Bit8u mode_control; - Bit8u color_select; - Bit8u disp_bank; - Bit8u reg_index; - Bit8u gfx_control; - Bit8u palette_mask; - Bit8u extended_ram; - Bit8u border_color; - Bit8u line_mask, line_shift; - Bit8u draw_bank, mem_bank; - Bit8u *draw_base, *mem_base; - Bitu addr_mask; -} VGA_TANDY; - -typedef struct { - Bit8u index; - Bit8u reset; - Bit8u clocking_mode; - Bit8u map_mask; - Bit8u character_map_select; - Bit8u memory_mode; -} VGA_Seq; - -typedef struct { - Bit8u palette[16]; - Bit8u mode_control; - Bit8u horizontal_pel_panning; - Bit8u overscan_color; - Bit8u color_plane_enable; - Bit8u color_select; - Bit8u index; - Bit8u disabled; // Used for disabling the screen. - // Bit0: screen disabled by attribute controller index - // Bit1: screen disabled by sequencer index 1 bit 5 - // These are put together in one variable for performance reasons: - // the line drawing function is called maybe 60*480=28800 times/s, - // and we only need to check one variable for zero this way. -} VGA_Attr; - -typedef struct { - Bit8u horizontal_total; - Bit8u horizontal_display_end; - Bit8u start_horizontal_blanking; - Bit8u end_horizontal_blanking; - Bit8u start_horizontal_retrace; - Bit8u end_horizontal_retrace; - Bit8u vertical_total; - Bit8u overflow; - Bit8u preset_row_scan; - Bit8u maximum_scan_line; - Bit8u cursor_start; - Bit8u cursor_end; - Bit8u start_address_high; - Bit8u start_address_low; - Bit8u cursor_location_high; - Bit8u cursor_location_low; - Bit8u vertical_retrace_start; - Bit8u vertical_retrace_end; - Bit8u vertical_display_end; - Bit8u offset; - Bit8u underline_location; - Bit8u start_vertical_blanking; - Bit8u end_vertical_blanking; - Bit8u mode_control; - Bit8u line_compare; - - Bit8u index; - bool read_only; -} VGA_Crtc; - -typedef struct { - Bit8u index; - Bit8u set_reset; - Bit8u enable_set_reset; - Bit8u color_compare; - Bit8u data_rotate; - Bit8u read_map_select; - Bit8u mode; - Bit8u miscellaneous; - Bit8u color_dont_care; - Bit8u bit_mask; -} VGA_Gfx; - -typedef struct { - Bit8u red; - Bit8u green; - Bit8u blue; -} RGBEntry; - -typedef struct { - Bit8u bits; /* DAC bits, usually 6 or 8 */ - Bit8u pel_mask; - Bit8u pel_index; - Bit8u state; - Bit8u write_index; - Bit8u read_index; - Bitu first_changed; - Bit8u combine[16]; - RGBEntry rgb[0x100]; - Bit16u xlat16[256]; -} VGA_Dac; - -typedef struct { - Bitu readStart, writeStart; - Bitu bankMask; - Bitu bank_read_full; - Bitu bank_write_full; - Bit8u bank_read; - Bit8u bank_write; - Bitu bank_size; -} VGA_SVGA; - -typedef union { - Bit32u d; - Bit8u b[4]; -} VGA_Latch; - -typedef struct { - Bit8u* linear; - Bit8u* linear_orgptr; -} VGA_Memory; - -typedef struct { - //Add a few more just to be safe - Bit8u* map; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */ - Bit8u checkMask, frame, writeMask; - bool active; - Bit32u clearMask; - Bit32u start, last; - Bit32u lastAddress; -} VGA_Changes; - -typedef struct { - Bit32u page; - Bit32u addr; - Bit32u mask; - PageHandler *handler; -} VGA_LFB; - -typedef struct { - VGAModes mode; /* The mode the vga system is in */ - Bit8u misc_output; - VGA_Draw draw; - VGA_Config config; - VGA_Internal internal; -/* Internal module groups */ - VGA_Seq seq; - VGA_Attr attr; - VGA_Crtc crtc; - VGA_Gfx gfx; - VGA_Dac dac; - VGA_Latch latch; - VGA_S3 s3; - VGA_SVGA svga; - VGA_HERC herc; - VGA_TANDY tandy; - VGA_OTHER other; - VGA_Memory mem; - Bit32u vmemwrap; /* this is assumed to be power of 2 */ - Bit8u* fastmem; /* memory for fast (usually 16-color) rendering, always twice as big as vmemsize */ - Bit8u* fastmem_orgptr; - Bit32u vmemsize; -#ifdef VGA_KEEP_CHANGES - VGA_Changes changes; -#endif - VGA_LFB lfb; -} VGA_Type; - - -/* Hercules Palette function */ -void Herc_Palette(void); - -/* Functions for different resolutions */ -void VGA_SetMode(VGAModes mode); -void VGA_DetermineMode(void); -void VGA_SetupHandlers(void); -void VGA_StartResize(Bitu delay=50); -void VGA_SetupDrawing(Bitu val); -void VGA_CheckScanLength(void); -void VGA_ChangedBank(void); - -/* Some DAC/Attribute functions */ -void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); -void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue); -void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); - -typedef enum {CGA, EGA, MONO} EGAMonitorMode; - -void VGA_ATTR_SetEGAMonitorPalette(EGAMonitorMode m); - -/* The VGA Subfunction startups */ -void VGA_SetupAttr(void); -void VGA_SetupMemory(Section* sec); -void VGA_SetupDAC(void); -void VGA_SetupCRTC(void); -void VGA_SetupMisc(void); -void VGA_SetupGFX(void); -void VGA_SetupSEQ(void); -void VGA_SetupOther(void); -void VGA_SetupXGA(void); - -void JEGA_setupAX(void); - -/* Some Support Functions */ -void VGA_SetClock(Bitu which,Bitu target); -void VGA_DACSetEntirePalette(void); -void VGA_StartRetrace(void); -void VGA_StartUpdateLFB(void); -void VGA_SetBlinking(Bitu enabled); -void VGA_SetCGA2Table(Bit8u val0,Bit8u val1); -void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3); -void VGA_ActivateHardwareCursor(void); -void VGA_KillDrawing(void); - -void VGA_SetOverride(bool vga_override); - -extern VGA_Type vga; - -/* Support for modular SVGA implementation */ -/* Video mode extra data to be passed to FinishSetMode_SVGA(). - This structure will be in flux until all drivers (including S3) - are properly separated. Right now it contains only three overflow - fields in S3 format and relies on drivers re-interpreting those. - For reference: - ver_overflow:X|line_comp10|X|vretrace10|X|vbstart10|vdispend10|vtotal10 - hor_overflow:X|X|X|hretrace8|X|hblank8|hdispend8|htotal8 - offset is not currently used by drivers (useful only for S3 itself) - It also contains basic int10 mode data - number, vtotal, htotal - */ -typedef struct { - Bit8u ver_overflow; - Bit8u hor_overflow; - Bitu offset; - Bitu modeNo; - Bitu htotal; - Bitu vtotal; -} VGA_ModeExtraData; - -// Vector function prototypes -typedef void (*tWritePort)(Bitu reg,Bitu val,Bitu iolen); -typedef Bitu (*tReadPort)(Bitu reg,Bitu iolen); -typedef void (*tFinishSetMode)(Bitu crtc_base, VGA_ModeExtraData* modeData); -typedef void (*tDetermineMode)(); -typedef void (*tSetClock)(Bitu which,Bitu target); -typedef Bitu (*tGetClock)(); -typedef bool (*tHWCursorActive)(); -typedef bool (*tAcceptsMode)(Bitu modeNo); - -struct SVGA_Driver { - tWritePort write_p3d5; - tReadPort read_p3d5; - tWritePort write_p3c5; - tReadPort read_p3c5; - tWritePort write_p3c0; - tReadPort read_p3c1; - tWritePort write_p3cf; - tReadPort read_p3cf; - - tFinishSetMode set_video_mode; - tDetermineMode determine_mode; - tSetClock set_clock; - tGetClock get_clock; - tHWCursorActive hardware_cursor_active; - tAcceptsMode accepts_mode; -}; - -extern SVGA_Driver svga; - -void SVGA_Setup_S3Trio(void); -void SVGA_Setup_TsengET4K(void); -void SVGA_Setup_TsengET3K(void); -void SVGA_Setup_ParadisePVGA1A(void); -void SVGA_Setup_Driver(void); - -// Amount of video memory required for a mode, implemented in int10_modes.cpp -Bitu VideoModeMemSize(Bitu mode); - -extern Bit32u ExpandTable[256]; -extern Bit32u FillTable[16]; -extern Bit32u CGA_2_Table[16]; -extern Bit32u CGA_4_Table[256]; -extern Bit32u CGA_4_HiRes_Table[256]; -extern Bit32u CGA_16_Table[256]; -extern Bit32u TXT_Font_Table[16]; -extern Bit32u TXT_FG_Table[16]; -extern Bit32u TXT_BG_Table[16]; -extern Bit32u Expand16Table[4][16]; -extern Bit32u Expand16BigTable[0x10000]; - - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/include/video.h b/source/src/vm/libcpu_newdev/dosbox-i386/include/video.h deleted file mode 100644 index 11539aee6..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/include/video.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#ifndef DOSBOX_VIDEO_H -#define DOSBOX_VIDEO_H - -#define REDUCE_JOYSTICK_POLLING - -typedef enum { - GFX_CallBackReset, - GFX_CallBackStop, - GFX_CallBackRedraw -} GFX_CallBackFunctions_t; - -typedef void (*GFX_CallBack_t)( GFX_CallBackFunctions_t function ); - -struct GFX_PalEntry { - Bit8u r; - Bit8u g; - Bit8u b; - Bit8u unused; -}; - -#define GFX_CAN_8 0x0001 -#define GFX_CAN_15 0x0002 -#define GFX_CAN_16 0x0004 -#define GFX_CAN_32 0x0008 - -#define GFX_LOVE_8 0x0010 -#define GFX_LOVE_15 0x0020 -#define GFX_LOVE_16 0x0040 -#define GFX_LOVE_32 0x0080 - -#define GFX_RGBONLY 0x0100 - -#define GFX_SCALING 0x1000 -#define GFX_HARDWARE 0x2000 - -#define GFX_CAN_RANDOM 0x4000 //If the interface can also do random access surface - -void GFX_Events(void); -void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries); -Bitu GFX_GetBestMode(Bitu flags); -Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue); -Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t cb); - -void GFX_ResetScreen(void); -void GFX_Start(void); -void GFX_Stop(void); -void GFX_SwitchFullScreen(void); -bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch); -void GFX_EndUpdate( const Bit16u *changedLines ); -void GFX_GetSize(int &width, int &height, bool &fullscreen); -void GFX_LosingFocus(void); - -#if defined (WIN32) -bool GFX_SDLUsingWinDIB(void); -#endif - -#if defined (REDUCE_JOYSTICK_POLLING) -void MAPPER_UpdateJoysticks(void); -#endif - -/* Mouse related */ -void GFX_CaptureMouse(void); -extern bool mouselocked; //true if mouse is confined to window - -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/instructions.h b/source/src/vm/libcpu_newdev/dosbox-i386/instructions.h deleted file mode 100644 index 5c0fb47a0..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/instructions.h +++ /dev/null @@ -1,965 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#pragma once -/* Jumps */ -namespace I386_DOSBOX { -/* All Byte general instructions */ -#define ADDB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b+lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_ADDb; - -#define ADCB(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b+lf_var2b+lflags.oldcf; \ - save(op1,lf_resb); \ - lflags.type=t_ADCb; - -#define SBBB(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b-(lf_var2b+lflags.oldcf); \ - save(op1,lf_resb); \ - lflags.type=t_SBBb; - -#define SUBB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b-lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_SUBb; - -#define ORB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b | lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_ORb; - -#define XORB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b ^ lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_XORb; - -#define ANDB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b & lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_ANDb; - -#define CMPB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b-lf_var2b; \ - lflags.type=t_CMPb; - -#define TESTB(op1,op2,load,save) \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b & lf_var2b; \ - lflags.type=t_TESTb; - -/* All Word General instructions */ - -#define ADDW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w+lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_ADDw; - -#define ADCW(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w+lf_var2w+lflags.oldcf; \ - save(op1,lf_resw); \ - lflags.type=t_ADCw; - -#define SBBW(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \ - save(op1,lf_resw); \ - lflags.type=t_SBBw; - -#define SUBW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w-lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_SUBw; - -#define ORW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w | lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_ORw; - -#define XORW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w ^ lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_XORw; - -#define ANDW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w & lf_var2w; \ - save(op1,lf_resw); \ - lflags.type=t_ANDw; - -#define CMPW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w-lf_var2w; \ - lflags.type=t_CMPw; - -#define TESTW(op1,op2,load,save) \ - lf_var1w=load(op1);lf_var2w=op2; \ - lf_resw=lf_var1w & lf_var2w; \ - lflags.type=t_TESTw; - -/* All DWORD General Instructions */ - -#define ADDD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d+lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_ADDd; - -#define ADCD(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \ - save(op1,lf_resd); \ - lflags.type=t_ADCd; - -#define SBBD(op1,op2,load,save) \ - lflags.oldcf=get_CF()!=0; \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \ - save(op1,lf_resd); \ - lflags.type=t_SBBd; - -#define SUBD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d-lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_SUBd; - -#define ORD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d | lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_ORd; - -#define XORD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d ^ lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_XORd; - -#define ANDD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d & lf_var2d; \ - save(op1,lf_resd); \ - lflags.type=t_ANDd; - -#define CMPD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d-lf_var2d; \ - lflags.type=t_CMPd; - - -#define TESTD(op1,op2,load,save) \ - lf_var1d=load(op1);lf_var2d=op2; \ - lf_resd=lf_var1d & lf_var2d; \ - lflags.type=t_TESTd; - - - - -#define INCB(op1,load,save) \ - LoadCF;lf_var1b=load(op1); \ - lf_resb=lf_var1b+1; \ - save(op1,lf_resb); \ - lflags.type=t_INCb; \ - -#define INCW(op1,load,save) \ - LoadCF;lf_var1w=load(op1); \ - lf_resw=lf_var1w+1; \ - save(op1,lf_resw); \ - lflags.type=t_INCw; - -#define INCD(op1,load,save) \ - LoadCF;lf_var1d=load(op1); \ - lf_resd=lf_var1d+1; \ - save(op1,lf_resd); \ - lflags.type=t_INCd; - -#define DECB(op1,load,save) \ - LoadCF;lf_var1b=load(op1); \ - lf_resb=lf_var1b-1; \ - save(op1,lf_resb); \ - lflags.type=t_DECb; - -#define DECW(op1,load,save) \ - LoadCF;lf_var1w=load(op1); \ - lf_resw=lf_var1w-1; \ - save(op1,lf_resw); \ - lflags.type=t_DECw; - -#define DECD(op1,load,save) \ - LoadCF;lf_var1d=load(op1); \ - lf_resd=lf_var1d-1; \ - save(op1,lf_resd); \ - lflags.type=t_DECd; - - - -#define ROLB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 7)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (lf_var1b >> (8-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,lf_resb & 1); \ - SETFLAGBIT(OF,(lf_resb & 1) ^ (lf_resb >> 7)); - -#define ROLW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1 & 1); \ - SETFLAGBIT(OF,(op1 & 1) ^ (op1 >> 15)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1w=load(op1); \ - lf_var2b=op2&0xf; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (lf_var1w >> (16-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,lf_resw & 1); \ - SETFLAGBIT(OF,(lf_resw & 1) ^ (lf_resw >> 15)); - -#define ROLD(op1,op2,load,save) \ - if (!op2) break; \ - FillFlagsNoCFOF(); \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d << lf_var2b) | \ - (lf_var1d >> (32-lf_var2b)); \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,lf_resd & 1); \ - SETFLAGBIT(OF,(lf_resd & 1) ^ (lf_resd >> 31)); - - -#define RORB(op1,op2,load,save) \ - if (!(op2&0x7)) { \ - if (op2&0x18) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>7); \ - SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1b=load(op1); \ - lf_var2b=op2&0x07; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (lf_var1b << (8-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,lf_resb & 0x80); \ - SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); - -#define RORW(op1,op2,load,save) \ - if (!(op2&0xf)) { \ - if (op2&0x10) { \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(CF,op1>>15); \ - SETFLAGBIT(OF,(op1>>15) ^ ((op1>>14) & 1)); \ - } \ - break; \ - } \ - FillFlagsNoCFOF(); \ - lf_var1w=load(op1); \ - lf_var2b=op2&0xf; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (lf_var1w << (16-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,lf_resw & 0x8000); \ - SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); - -#define RORD(op1,op2,load,save) \ - if (!op2) break; \ - FillFlagsNoCFOF(); \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (lf_var1d << (32-lf_var2b)); \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,lf_resd & 0x80000000); \ - SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); - - -#define RCLB(op1,op2,load,save) \ - if (!(op2%9)) break; \ -{ Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lf_resb=(lf_var1b << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1b >> (9-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resb >> 7)); \ -} - -#define RCLW(op1,op2,load,save) \ - if (!(op2%17)) break; \ -{ Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lf_resw=(lf_var1w << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1w >> (17-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resw >> 15)); \ -} - -#define RCLD(op1,op2,load,save) \ - if (!op2) break; \ -{ Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - if (lf_var2b==1) { \ - lf_resd=(lf_var1d << 1) | cf; \ - } else { \ - lf_resd=(lf_var1d << lf_var2b) | \ - (cf << (lf_var2b-1)) | \ - (lf_var1d >> (33-lf_var2b)); \ - } \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \ - SETFLAGBIT(OF,(reg_flags & 1) ^ (lf_resd >> 31)); \ -} - - - -#define RCRB(op1,op2,load,save) \ - if (op2%9) { \ - Bit8u cf=(Bit8u)FillFlags()&0x1; \ - lf_var1b=load(op1); \ - lf_var2b=op2%9; \ - lf_resb=(lf_var1b >> lf_var2b) | \ - (cf << (8-lf_var2b)) | \ - (lf_var1b << (9-lf_var2b)); \ - save(op1,lf_resb); \ - SETFLAGBIT(CF,(lf_var1b >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resb ^ (lf_resb<<1)) & 0x80); \ - } - -#define RCRW(op1,op2,load,save) \ - if (op2%17) { \ - Bit16u cf=(Bit16u)FillFlags()&0x1; \ - lf_var1w=load(op1); \ - lf_var2b=op2%17; \ - lf_resw=(lf_var1w >> lf_var2b) | \ - (cf << (16-lf_var2b)) | \ - (lf_var1w << (17-lf_var2b)); \ - save(op1,lf_resw); \ - SETFLAGBIT(CF,(lf_var1w >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resw ^ (lf_resw<<1)) & 0x8000); \ - } - -#define RCRD(op1,op2,load,save) \ - if (op2) { \ - Bit32u cf=(Bit32u)FillFlags()&0x1; \ - lf_var1d=load(op1); \ - lf_var2b=op2; \ - if (lf_var2b==1) { \ - lf_resd=lf_var1d >> 1 | cf << 31; \ - } else { \ - lf_resd=(lf_var1d >> lf_var2b) | \ - (cf << (32-lf_var2b)) | \ - (lf_var1d << (33-lf_var2b)); \ - } \ - save(op1,lf_resd); \ - SETFLAGBIT(CF,(lf_var1d >> (lf_var2b - 1)) & 1); \ - SETFLAGBIT(OF,(lf_resd ^ (lf_resd<<1)) & 0x80000000); \ - } - - -#define SHLB(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b << lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_SHLb; - -#define SHLW(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1w=load(op1);lf_var2b=op2 ; \ - lf_resw=lf_var1w << lf_var2b; \ - save(op1,lf_resw); \ - lflags.type=t_SHLw; - -#define SHLD(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1d=load(op1);lf_var2b=op2; \ - lf_resd=lf_var1d << lf_var2b; \ - save(op1,lf_resd); \ - lflags.type=t_SHLd; - - -#define SHRB(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1b=load(op1);lf_var2b=op2; \ - lf_resb=lf_var1b >> lf_var2b; \ - save(op1,lf_resb); \ - lflags.type=t_SHRb; - -#define SHRW(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1w=load(op1);lf_var2b=op2; \ - lf_resw=lf_var1w >> lf_var2b; \ - save(op1,lf_resw); \ - lflags.type=t_SHRw; - -#define SHRD(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1d=load(op1);lf_var2b=op2; \ - lf_resd=lf_var1d >> lf_var2b; \ - save(op1,lf_resd); \ - lflags.type=t_SHRd; - - -#define SARB(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1b=load(op1);lf_var2b=op2; \ - if (lf_var2b>8) lf_var2b=8; \ - if (lf_var1b & 0x80) { \ - lf_resb=(lf_var1b >> lf_var2b)| \ - (0xff << (8 - lf_var2b)); \ - } else { \ - lf_resb=lf_var1b >> lf_var2b; \ - } \ - save(op1,lf_resb); \ - lflags.type=t_SARb; - -#define SARW(op1,op2,load,save) \ - if (!op2) break; \ - lf_var1w=load(op1);lf_var2b=op2; \ - if (lf_var2b>16) lf_var2b=16; \ - if (lf_var1w & 0x8000) { \ - lf_resw=(lf_var1w >> lf_var2b)| \ - (0xffff << (16 - lf_var2b)); \ - } else { \ - lf_resw=lf_var1w >> lf_var2b; \ - } \ - save(op1,lf_resw); \ - lflags.type=t_SARw; - -#define SARD(op1,op2,load,save) \ - if (!op2) break; \ - lf_var2b=op2;lf_var1d=load(op1); \ - if (lf_var1d & 0x80000000) { \ - lf_resd=(lf_var1d >> lf_var2b)| \ - (0xffffffff << (32 - lf_var2b)); \ - } else { \ - lf_resd=lf_var1d >> lf_var2b; \ - } \ - save(op1,lf_resd); \ - lflags.type=t_SARd; - - - -#define DAA() \ - if (((reg_al & 0x0F)>0x09) || get_AF()) { \ - if ((reg_al > 0x99) || get_CF()) { \ - reg_al+=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ - reg_al+=0x06; \ - SETFLAGBIT(AF,true); \ - } else { \ - if ((reg_al > 0x99) || get_CF()) { \ - reg_al+=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(SF,(reg_al&0x80)); \ - SETFLAGBIT(ZF,(reg_al==0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - lflags.type=t_UNKNOWN; - - -#define DAS() \ -{ \ - Bit8u osigned=reg_al & 0x80; \ - if (((reg_al & 0x0f) > 9) || get_AF()) { \ - if ((reg_al>0x99) || get_CF()) { \ - reg_al-=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,(reg_al<=0x05)); \ - } \ - reg_al-=6; \ - SETFLAGBIT(AF,true); \ - } else { \ - if ((reg_al>0x99) || get_CF()) { \ - reg_al-=0x60; \ - SETFLAGBIT(CF,true); \ - } else { \ - SETFLAGBIT(CF,false); \ - } \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(OF,osigned && ((reg_al&0x80)==0)); \ - SETFLAGBIT(SF,(reg_al&0x80)); \ - SETFLAGBIT(ZF,(reg_al==0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - lflags.type=t_UNKNOWN; \ -} - - -#define AAA() \ - SETFLAGBIT(SF,((reg_al>=0x7a) && (reg_al<=0xf9))); \ - if ((reg_al & 0xf) > 9) { \ - SETFLAGBIT(OF,(reg_al&0xf0)==0x70); \ - reg_ax += 0x106; \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(AF,true); \ - } else if (get_AF()) { \ - reg_ax += 0x106; \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(ZF,false); \ - SETFLAGBIT(AF,true); \ - } else { \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; - -#define AAS() \ - if ((reg_al & 0x0f)>9) { \ - SETFLAGBIT(SF,(reg_al>0x85)); \ - reg_ax -= 0x106; \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(AF,true); \ - } else if (get_AF()) { \ - SETFLAGBIT(OF,((reg_al>=0x80) && (reg_al<=0x85))); \ - SETFLAGBIT(SF,(reg_al<0x06) || (reg_al>0x85)); \ - reg_ax -= 0x106; \ - SETFLAGBIT(CF,true); \ - SETFLAGBIT(AF,true); \ - } else { \ - SETFLAGBIT(SF,(reg_al>=0x80)); \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(AF,false); \ - } \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - reg_al &= 0x0F; \ - lflags.type=t_UNKNOWN; - -#define AAM(op1) \ -{ \ - Bit8u dv=op1; \ - if (dv!=0) { \ - reg_ah=reg_al / dv; \ - reg_al=reg_al % dv; \ - SETFLAGBIT(SF,(reg_al & 0x80)); \ - SETFLAGBIT(ZF,(reg_al == 0)); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(AF,false); \ - lflags.type=t_UNKNOWN; \ - } else EXCEPTION(0); \ -} - - -//Took this from bochs, i seriously hate these weird bcd opcodes -#define AAD(op1) \ - { \ - Bit16u ax1 = reg_ah * op1; \ - Bit16u ax2 = ax1 + reg_al; \ - reg_al = (Bit8u) ax2; \ - reg_ah = 0; \ - SETFLAGBIT(CF,false); \ - SETFLAGBIT(OF,false); \ - SETFLAGBIT(AF,false); \ - SETFLAGBIT(SF,reg_al >= 0x80); \ - SETFLAGBIT(ZF,reg_al == 0); \ - SETFLAGBIT(PF,parity_lookup[reg_al]); \ - lflags.type=t_UNKNOWN; \ - } - -#define MULB(op1,load,save) \ - reg_ax=reg_al*load(op1); \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(ZF,reg_al == 0); \ - if (reg_ax & 0xff00) { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } else { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } - -#define MULW(op1,load,save) \ -{ \ - Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \ - reg_ax=(Bit16u)(tempu); \ - reg_dx=(Bit16u)(tempu >> 16); \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(ZF,reg_ax == 0); \ - if (reg_dx) { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } else { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } \ -} - -#define MULD(op1,load,save) \ -{ \ - Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \ - reg_eax=(Bit32u)(tempu); \ - reg_edx=(Bit32u)(tempu >> 32); \ - FillFlagsNoCFOF(); \ - SETFLAGBIT(ZF,reg_eax == 0); \ - if (reg_edx) { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } else { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } \ -} - -#define DIVB(op1,load,save) \ -{ \ - Bitu val=load(op1); \ - if (val==0) EXCEPTION(0); \ - Bitu quo=reg_ax / val; \ - Bit8u rem=(Bit8u)(reg_ax % val); \ - Bit8u quo8=(Bit8u)(quo&0xff); \ - if (quo>0xff) EXCEPTION(0); \ - reg_ah=rem; \ - reg_al=quo8; \ -} - - -#define DIVW(op1,load,save) \ -{ \ - Bitu val=load(op1); \ - if (val==0) EXCEPTION(0); \ - Bitu num=((Bit32u)reg_dx<<16)|reg_ax; \ - Bitu quo=num/val; \ - Bit16u rem=(Bit16u)(num % val); \ - Bit16u quo16=(Bit16u)(quo&0xffff); \ - if (quo!=(Bit32u)quo16) EXCEPTION(0); \ - reg_dx=rem; \ - reg_ax=quo16; \ -} - -#define DIVD(op1,load,save) \ -{ \ - Bitu val=load(op1); \ - if (val==0) EXCEPTION(0); \ - Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax; \ - Bit64u quo=num/val; \ - Bit32u rem=(Bit32u)(num % val); \ - Bit32u quo32=(Bit32u)(quo&0xffffffff); \ - if (quo!=(Bit64u)quo32) EXCEPTION(0); \ - reg_edx=rem; \ - reg_eax=quo32; \ -} - - -#define IDIVB(op1,load,save) \ -{ \ - Bits val=(Bit8s)(load(op1)); \ - if (val==0) EXCEPTION(0); \ - Bits quo=((Bit16s)reg_ax) / val; \ - Bit8s rem=(Bit8s)((Bit16s)reg_ax % val); \ - Bit8s quo8s=(Bit8s)(quo&0xff); \ - if (quo!=(Bit16s)quo8s) EXCEPTION(0); \ - reg_ah=rem; \ - reg_al=quo8s; \ -} - - -#define IDIVW(op1,load,save) \ -{ \ - Bits val=(Bit16s)(load(op1)); \ - if (val==0) EXCEPTION(0); \ - Bits num=(Bit32s)((reg_dx<<16)|reg_ax); \ - Bits quo=num/val; \ - Bit16s rem=(Bit16s)(num % val); \ - Bit16s quo16s=(Bit16s)quo; \ - if (quo!=(Bit32s)quo16s) EXCEPTION(0); \ - reg_dx=rem; \ - reg_ax=quo16s; \ -} - -#define IDIVD(op1,load,save) \ -{ \ - Bits val=(Bit32s)(load(op1)); \ - if (val==0) EXCEPTION(0); \ - Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax; \ - Bit64s quo=num/val; \ - Bit32s rem=(Bit32s)(num % val); \ - Bit32s quo32s=(Bit32s)(quo&0xffffffff); \ - if (quo!=(Bit64s)quo32s) EXCEPTION(0); \ - reg_edx=rem; \ - reg_eax=quo32s; \ -} - -#define IMULB(op1,load,save) \ -{ \ - reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \ - FillFlagsNoCFOF(); \ - if ((reg_ax & 0xff80)==0xff80 || \ - (reg_ax & 0xff80)==0x0000) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - - -#define IMULW(op1,load,save) \ -{ \ - Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \ - reg_ax=(Bit16s)(temps); \ - reg_dx=(Bit16s)(temps >> 16); \ - FillFlagsNoCFOF(); \ - if (((temps & 0xffff8000)==0xffff8000 || \ - (temps & 0xffff8000)==0x0000)) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define IMULD(op1,load,save) \ -{ \ - Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \ - ((Bit64s)((Bit32s)(load(op1)))); \ - reg_eax=(Bit32u)(temps); \ - reg_edx=(Bit32u)(temps >> 32); \ - FillFlagsNoCFOF(); \ - if ((reg_edx==0xffffffff) && \ - (reg_eax & 0x80000000) ) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else if ( (reg_edx==0x00000000) && \ - (reg_eax< 0x80000000) ) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define DIMULW(op1,op2,op3,load,save) \ -{ \ - Bits res=((Bit16s)op2) * ((Bit16s)op3); \ - save(op1,res & 0xffff); \ - FillFlagsNoCFOF(); \ - if ((res>= -32768) && (res<=32767)) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define DIMULD(op1,op2,op3,load,save) \ -{ \ - Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \ - save(op1,(Bit32s)res); \ - FillFlagsNoCFOF(); \ - if ((res>=-((Bit64s)(2147483647)+1)) && \ - (res<=(Bit64s)2147483647)) { \ - SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \ - } else { \ - SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \ - } \ -} - -#define GRP2B(blah) \ -{ \ - GetRM;Bitu which=(rm>>3)&7; \ - if (rm >= 0xc0) { \ - GetEArb; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \ - case 0x01:RORB(*earb,val,LoadRb,SaveRb);break; \ - case 0x02:RCLB(*earb,val,LoadRb,SaveRb);break; \ - case 0x03:RCRB(*earb,val,LoadRb,SaveRb);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLB(*earb,val,LoadRb,SaveRb);break; \ - case 0x05:SHRB(*earb,val,LoadRb,SaveRb);break; \ - case 0x07:SARB(*earb,val,LoadRb,SaveRb);break; \ - } \ - } else { \ - GetEAa; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \ - case 0x01:RORB(eaa,val,LoadMb,SaveMb);break; \ - case 0x02:RCLB(eaa,val,LoadMb,SaveMb);break; \ - case 0x03:RCRB(eaa,val,LoadMb,SaveMb);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLB(eaa,val,LoadMb,SaveMb);break; \ - case 0x05:SHRB(eaa,val,LoadMb,SaveMb);break; \ - case 0x07:SARB(eaa,val,LoadMb,SaveMb);break; \ - } \ - } \ -} - - - -#define GRP2W(blah) \ -{ \ - GetRM;Bitu which=(rm>>3)&7; \ - if (rm >= 0xc0) { \ - GetEArw; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \ - case 0x01:RORW(*earw,val,LoadRw,SaveRw);break; \ - case 0x02:RCLW(*earw,val,LoadRw,SaveRw);break; \ - case 0x03:RCRW(*earw,val,LoadRw,SaveRw);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLW(*earw,val,LoadRw,SaveRw);break; \ - case 0x05:SHRW(*earw,val,LoadRw,SaveRw);break; \ - case 0x07:SARW(*earw,val,LoadRw,SaveRw);break; \ - } \ - } else { \ - GetEAa; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \ - case 0x01:RORW(eaa,val,LoadMw,SaveMw);break; \ - case 0x02:RCLW(eaa,val,LoadMw,SaveMw);break; \ - case 0x03:RCRW(eaa,val,LoadMw,SaveMw);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLW(eaa,val,LoadMw,SaveMw);break; \ - case 0x05:SHRW(eaa,val,LoadMw,SaveMw);break; \ - case 0x07:SARW(eaa,val,LoadMw,SaveMw);break; \ - } \ - } \ -} - - -#define GRP2D(blah) \ -{ \ - GetRM;Bitu which=(rm>>3)&7; \ - if (rm >= 0xc0) { \ - GetEArd; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \ - case 0x01:RORD(*eard,val,LoadRd,SaveRd);break; \ - case 0x02:RCLD(*eard,val,LoadRd,SaveRd);break; \ - case 0x03:RCRD(*eard,val,LoadRd,SaveRd);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLD(*eard,val,LoadRd,SaveRd);break; \ - case 0x05:SHRD(*eard,val,LoadRd,SaveRd);break; \ - case 0x07:SARD(*eard,val,LoadRd,SaveRd);break; \ - } \ - } else { \ - GetEAa; \ - Bit8u val=blah & 0x1f; \ - switch (which) { \ - case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \ - case 0x01:RORD(eaa,val,LoadMd,SaveMd);break; \ - case 0x02:RCLD(eaa,val,LoadMd,SaveMd);break; \ - case 0x03:RCRD(eaa,val,LoadMd,SaveMd);break; \ - case 0x04:/* SHL and SAL are the same */ \ - case 0x06:SHLD(eaa,val,LoadMd,SaveMd);break; \ - case 0x05:SHRD(eaa,val,LoadMd,SaveMd);break; \ - case 0x07:SARD(eaa,val,LoadMd,SaveMd);break; \ - } \ - } \ -} - -/* let's hope bochs has it correct with the higher than 16 shifts */ -/* double-precision shift left has low bits in second argument */ -#define DSHLW(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=(load(op1)<<16)|op2; \ - Bit32u tempd=lf_var1d << lf_var2b; \ - if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); \ - lf_resw=(Bit16u)(tempd >> 16); \ - save(op1,lf_resw); \ - lflags.type=t_DSHLw; - -#define DSHLD(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=load(op1); \ - lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_DSHLd; - -/* double-precision shift right has high bits in second argument */ -#define DSHRW(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=(op2<<16)|load(op1); \ - Bit32u tempd=lf_var1d >> lf_var2b; \ - if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b )); \ - lf_resw=(Bit16u)(tempd); \ - save(op1,lf_resw); \ - lflags.type=t_DSHRw; - -#define DSHRD(op1,op2,op3,load,save) \ - Bit8u val=op3 & 0x1F; \ - if (!val) break; \ - lf_var2b=val;lf_var1d=load(op1); \ - lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); \ - save(op1,lf_resd); \ - lflags.type=t_DSHRd; - -#define BSWAPW(op1) \ - op1 = 0; - -#define BSWAPD(op1) \ - op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000); - -}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/lazyflags.h b/source/src/vm/libcpu_newdev/dosbox-i386/lazyflags.h deleted file mode 100644 index a5d310599..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/lazyflags.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DOSBOX_LAZYFLAGS_H -#define DOSBOX_LAZYFLAGS_H - -namespace I386_DOSBOX { -#define lf_var1b lflags.var1.byte[BL_INDEX] -#define lf_var2b lflags.var2.byte[BL_INDEX] -#define lf_resb lflags.res.byte[BL_INDEX] - -#define lf_var1w lflags.var1.word[W_INDEX] -#define lf_var2w lflags.var2.word[W_INDEX] -#define lf_resw lflags.res.word[W_INDEX] - -#define lf_var1d lflags.var1.dword[DW_INDEX] -#define lf_var2d lflags.var2.dword[DW_INDEX] -#define lf_resd lflags.res.dword[DW_INDEX] - - -#define SETFLAGSb(FLAGB) \ -{ \ - SETFLAGBIT(OF,get_OF()); \ - lflags.type=t_UNKNOWN; \ - CPU_SetFlags(FLAGB,FMASK_NORMAL & 0xff); \ -} - -#define SETFLAGSw(FLAGW) \ -{ \ - lflags.type=t_UNKNOWN; \ - CPU_SetFlagsw(FLAGW); \ -} - -#define SETFLAGSd(FLAGD) \ -{ \ - lflags.type=t_UNKNOWN; \ - CPU_SetFlagsd(FLAGD); \ -} - -#define LoadCF SETFLAGBIT(CF,get_CF()); -#define LoadZF SETFLAGBIT(ZF,get_ZF()); -#define LoadSF SETFLAGBIT(SF,get_SF()); -#define LoadOF SETFLAGBIT(OF,get_OF()); -#define LoadAF SETFLAGBIT(AF,get_AF()); - -#define TFLG_O (get_OF()) -#define TFLG_NO (!get_OF()) -#define TFLG_B (get_CF()) -#define TFLG_NB (!get_CF()) -#define TFLG_Z (get_ZF()) -#define TFLG_NZ (!get_ZF()) -#define TFLG_BE (get_CF() || get_ZF()) -#define TFLG_NBE (!get_CF() && !get_ZF()) -#define TFLG_S (get_SF()) -#define TFLG_NS (!get_SF()) -#define TFLG_P (get_PF()) -#define TFLG_NP (!get_PF()) -#define TFLG_L ((get_SF()!=0) != (get_OF()!=0)) -#define TFLG_NL ((get_SF()!=0) == (get_OF()!=0)) -#define TFLG_LE (get_ZF() || ((get_SF()!=0) != (get_OF()!=0))) -#define TFLG_NLE (!get_ZF() && ((get_SF()!=0) == (get_OF()!=0))) - -//Types of Flag changing instructions -enum { - t_UNKNOWN=0, - t_ADDb,t_ADDw,t_ADDd, - t_ORb,t_ORw,t_ORd, - t_ADCb,t_ADCw,t_ADCd, - t_SBBb,t_SBBw,t_SBBd, - t_ANDb,t_ANDw,t_ANDd, - t_SUBb,t_SUBw,t_SUBd, - t_XORb,t_XORw,t_XORd, - t_CMPb,t_CMPw,t_CMPd, - t_INCb,t_INCw,t_INCd, - t_DECb,t_DECw,t_DECd, - t_TESTb,t_TESTw,t_TESTd, - t_SHLb,t_SHLw,t_SHLd, - t_SHRb,t_SHRw,t_SHRd, - t_SARb,t_SARw,t_SARd, - t_ROLb,t_ROLw,t_ROLd, - t_RORb,t_RORw,t_RORd, - t_RCLb,t_RCLw,t_RCLd, - t_RCRb,t_RCRw,t_RCRd, - t_NEGb,t_NEGw,t_NEGd, - - t_DSHLw,t_DSHLd, - t_DSHRw,t_DSHRd, - t_MUL,t_DIV, - t_NOTDONE, - t_LASTFLAG -}; - -}; -#endif diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp deleted file mode 100644 index 88fdd7eb1..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/modrm.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "cpu.h" - -namespace DOSBOX_I386 { - -const Bit8u * lookupRMregb[]= -{ - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, - - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, - - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh, - - ®_al,®_al,®_al,®_al,®_al,®_al,®_al,®_al, - ®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl,®_cl, - ®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl,®_dl, - ®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl,®_bl, - ®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah,®_ah, - ®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch,®_ch, - ®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh,®_dh, - ®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh,®_bh -}; - -const Bit16u * lookupRMregw[]={ - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, - - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, - - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di, - - ®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax,®_ax, - ®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx,®_cx, - ®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx,®_dx, - ®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx,®_bx, - ®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp,®_sp, - ®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp,®_bp, - ®_si,®_si,®_si,®_si,®_si,®_si,®_si,®_si, - ®_di,®_di,®_di,®_di,®_di,®_di,®_di,®_di -}; - -const Bit32u * lookupRMregd[256]={ - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, - - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, - - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi, - - ®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax,®_eax, - ®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx,®_ecx, - ®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx,®_edx, - ®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx,®_ebx, - ®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp,®_esp, - ®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp,®_ebp, - ®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi,®_esi, - ®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi,®_edi -}; - - -const Bit8u * lookupRMEAregb[256]={ -/* 12 lines of 16*0 should give nice errors when used */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh, - ®_al,®_cl,®_dl,®_bl,®_ah,®_ch,®_dh,®_bh -}; - -const Bit16u * lookupRMEAregw[256]={ -/* 12 lines of 16*0 should give nice errors when used */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di, - ®_ax,®_cx,®_dx,®_bx,®_sp,®_bp,®_si,®_di -}; - -const Bit32u * lookupRMEAregd[256]={ -/* 12 lines of 16*0 should give nice errors when used */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi, - ®_eax,®_ecx,®_edx,®_ebx,®_esp,®_ebp,®_esi,®_edi -}; - - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/modrm.h b/source/src/vm/libcpu_newdev/dosbox-i386/modrm.h deleted file mode 100644 index 29656bfc0..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/modrm.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -extern Bit8u * lookupRMregb[]; -extern Bit16u * lookupRMregw[]; -extern Bit32u * lookupRMregd[]; -extern Bit8u * lookupRMEAregb[256]; -extern Bit16u * lookupRMEAregw[256]; -extern Bit32u * lookupRMEAregd[256]; - -#define GetRM \ - Bit8u rm=Fetchb(); - -#define Getrb \ - Bit8u * rmrb; \ - rmrb=lookupRMregb[rm]; - -#define Getrw \ - Bit16u * rmrw; \ - rmrw=lookupRMregw[rm]; - -#define Getrd \ - Bit32u * rmrd; \ - rmrd=lookupRMregd[rm]; - - -#define GetRMrb \ - GetRM; \ - Getrb; - -#define GetRMrw \ - GetRM; \ - Getrw; - -#define GetRMrd \ - GetRM; \ - Getrd; - - -#define GetEArb \ - Bit8u * earb=lookupRMEAregb[rm]; - -#define GetEArw \ - Bit16u * earw=lookupRMEAregw[rm]; - -#define GetEArd \ - Bit32u * eard=lookupRMEAregd[rm]; - - diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp b/source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp deleted file mode 100644 index 86168280a..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/paging.cpp +++ /dev/null @@ -1,883 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - -#include -#include -#include - -#include "dosbox.h" -#include "mem.h" -#include "./include/paging.h" -#include "./include/regs.h" -#include "./lazyflags.h" -#include "./include/cpu.h" -//#include "debug.h" -//#include "setup.h" - -namespace I386_DOSBOX { -PagingBlock paging; - - -Bitu PageHandler::readb(PhysPt addr) { - E_Exit("No byte handler for read from %d",addr); - return 0; -} -Bitu PageHandler::readw(PhysPt addr) { - Bitu ret = (readb(addr+0) << 0); - ret |= (readb(addr+1) << 8); - return ret; -} -Bitu PageHandler::readd(PhysPt addr) { - Bitu ret = (readb(addr+0) << 0); - ret |= (readb(addr+1) << 8); - ret |= (readb(addr+2) << 16); - ret |= (readb(addr+3) << 24); - return ret; -} - -void PageHandler::writeb(PhysPt addr,Bitu /*val*/) { - E_Exit("No byte handler for write to %d",addr); -} - -void PageHandler::writew(PhysPt addr,Bitu val) { - writeb(addr+0,(Bit8u) (val >> 0)); - writeb(addr+1,(Bit8u) (val >> 8)); -} -void PageHandler::writed(PhysPt addr,Bitu val) { - writeb(addr+0,(Bit8u) (val >> 0)); - writeb(addr+1,(Bit8u) (val >> 8)); - writeb(addr+2,(Bit8u) (val >> 16)); - writeb(addr+3,(Bit8u) (val >> 24)); -} - -HostPt PageHandler::GetHostReadPt(Bitu /*phys_page*/) { - return 0; -} - -HostPt PageHandler::GetHostWritePt(Bitu /*phys_page*/) { - return 0; -} - -bool PageHandler::readb_checked(PhysPt addr, Bit8u * val) { - *val=(Bit8u)readb(addr); return false; -} -bool PageHandler::readw_checked(PhysPt addr, Bit16u * val) { - *val=(Bit16u)readw(addr); return false; -} -bool PageHandler::readd_checked(PhysPt addr, Bit32u * val) { - *val=(Bit32u)readd(addr); return false; -} -bool PageHandler::writeb_checked(PhysPt addr,Bitu val) { - writeb(addr,val); return false; -} -bool PageHandler::writew_checked(PhysPt addr,Bitu val) { - writew(addr,val); return false; -} -bool PageHandler::writed_checked(PhysPt addr,Bitu val) { - writed(addr,val); return false; -} - - -Bits PageHandler::PageFaultCore(void) { - d_parent->CPU_CycleLeft += d_parent->CPU_Cycles; - d_parent->CPU_Cycles=1; - Bits ret= d_parent->CPU_Core_Full_Run(); - d_parent->CPU_CycleLeft += d_parent->CPU_Cycles; - if (ret<0) E_Exit("Got a dosbox close machine in pagefault core?"); - if (ret) - return ret; - if (!pf_queue.used) E_Exit("PF Core without PF"); - PF_Entry * entry=&(d_parent->pf_queue.entries[pf_queue.used-1]); - X86PageEntry pentry; - pentry.load = phys_readd(entry->page_addr); - if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) { - cpu.mpl=entry->mpl; - return -1; - } - return 0; -} -#if C_DEBUG -Bitu DEBUG_EnableDebugger(void); -#endif - -bool first=false; - -void PageHandler::PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) { - /* Save the state of the cpu cores */ - LazyFlags old_lflags; - memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); - CPU_Decoder * old_cpudecoder; - old_cpudecoder=cpudecoder; - cpudecoder=&PageFaultCore; - paging.cr2=lin_addr; - PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; - LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x] queue %d",lin_addr,faultcode,pf_queue.used); -// LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx); -// LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp); - entry->cs=SegValue(cs); - entry->eip=reg_eip; - entry->page_addr=page_addr; - entry->mpl=cpu.mpl; - cpu.mpl=3; - - CPU_Exception(EXCEPTION_PF,faultcode); -#if C_DEBUG -// DEBUG_EnableDebugger(); -#endif - DOSBOX_RunMachine(); - pf_queue.used--; - LOG(LOG_PAGING,LOG_NORMAL)("Left PageFault for %x queue %d",lin_addr,pf_queue.used); - memcpy(&lflags,&old_lflags,sizeof(LazyFlags)); - cpudecoder=old_cpudecoder; -// LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp); -} - -INLINE void PageHandler::InitPageUpdateLink(Bitu relink,PhysPt addr) { - if (relink==0) return; - if (paging.links.used) { - if (paging.links.entries[paging.links.used-1]==(addr>>12)) { - paging.links.used--; - PAGING_UnlinkPages(addr>>12,1); - } - } - if (relink>1) PAGING_LinkPage_ReadOnly(addr>>12,relink); -} - -INLINE void PageHandler::InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { - Bitu lin_page=lin_addr >> 12; - Bitu d_index=lin_page >> 10; - Bitu t_index=lin_page & 0x3ff; - Bitu table_addr=(paging.base.page<<12)+d_index*4; - table.load=phys_readd(table_addr); - if (!table.block.p) { - LOG(LOG_PAGING,LOG_NORMAL)("NP Table"); - PAGING_PageFault(lin_addr,table_addr, - (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); - table.load=phys_readd(table_addr); - if (GCC_UNLIKELY(!table.block.p)) - E_Exit("Pagefault didn't correct table"); - } - Bitu entry_addr=(table.block.base<<12)+t_index*4; - entry.load=phys_readd(entry_addr); - if (!entry.block.p) { -// LOG(LOG_PAGING,LOG_NORMAL)("NP Page"); - PAGING_PageFault(lin_addr,entry_addr, - (writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04)); - entry.load=phys_readd(entry_addr); - if (GCC_UNLIKELY(!entry.block.p)) - E_Exit("Pagefault didn't correct page"); - } -} - -INLINE bool PageHandler::InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) { - Bitu lin_page=lin_addr >> 12; - Bitu d_index=lin_page >> 10; - Bitu t_index=lin_page & 0x3ff; - Bitu table_addr=(paging.base.page<<12)+d_index*4; - table.load=phys_readd(table_addr); - if (!table.block.p) { - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); - return false; - } - Bitu entry_addr=(table.block.base<<12)+t_index*4; - entry.load=phys_readd(entry_addr); - if (!entry.block.p) { - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04); - return false; - } - return true; -} - -// check if a user-level memory access would trigger a privilege page fault -INLINE bool PageHandler::InitPage_CheckUseraccess(Bitu u1,Bitu u2) { - switch (CPU_ArchitectureType) { - case CPU_ARCHTYPE_MIXED: - case CPU_ARCHTYPE_386SLOW: - case CPU_ARCHTYPE_386FAST: - default: - return ((u1)==0) && ((u2)==0); - case CPU_ARCHTYPE_486OLDSLOW: - case CPU_ARCHTYPE_486NEWSLOW: - case CPU_ARCHTYPE_PENTIUMSLOW: - return ((u1)==0) || ((u2)==0); - } -} - - -class InitPageHandler : public PageHandler { -public: - InitPageHandler(DEVICE* parent) : PageHandler(parent) - { - flags=PFLAG_INIT|PFLAG_NOCODE; - } - Bitu readb(PhysPt addr) { - Bitu needs_reset=InitPage(addr,false); - Bit8u val=d_dev->read_data8(addr); - InitPageUpdateLink(needs_reset,addr); - return val; - } - Bitu readw(PhysPt addr) { - Bitu needs_reset=InitPage(addr,false); - Bit16u val=d_dev->read_data16(addr); - InitPageUpdateLink(needs_reset,addr); - return val; - } - Bitu readd(PhysPt addr) { - Bitu needs_reset=InitPage(addr,false); - Bit32u val=d_dev->read_data32(addr); - InitPageUpdateLink(needs_reset,addr); - return val; - } - void writeb(PhysPt addr,Bitu val) { - Bitu needs_reset=InitPage(addr,true); - d_dev->write_data8(addr, val); - InitPageUpdateLink(needs_reset,addr); - } - void writew(PhysPt addr,Bitu val) { - Bitu needs_reset=InitPage(addr,true); - d_dev->write_data16(addr, val); - InitPageUpdateLink(needs_reset,addr); - } - void writed(PhysPt addr,Bitu val) { - Bitu needs_reset=InitPage(addr,true); - d_dev->write_data32(addr, val); - InitPageUpdateLink(needs_reset,addr); - } - bool readb_checked(PhysPt addr, Bit8u * val) { - if (InitPageCheckOnly(addr,false)) { - *val=d_dev->read_data8(addr); - return false; - } else return true; - } - bool readw_checked(PhysPt addr, Bit16u * val) { - if (InitPageCheckOnly(addr,false)){ - *val=d_dev->read_data16(addr); - return false; - } else return true; - } - bool readd_checked(PhysPt addr, Bit32u * val) { - if (InitPageCheckOnly(addr,false)) { - *val=d_dev->read_data32(addr); - return false; - } else return true; - } - bool writeb_checked(PhysPt addr,Bitu val) { - if (InitPageCheckOnly(addr,true)) { - d_dev->write_data8(addr, val); - return false; - } else return true; - } - bool writew_checked(PhysPt addr,Bitu val) { - if (InitPageCheckOnly(addr,true)) { - d_dev->write_data16(addr, val); - return false; - } else return true; - } - bool writed_checked(PhysPt addr,Bitu val) { - if (InitPageCheckOnly(addr,true)) { - d_dev->write_data32(addr, val); - return false; - } else return true; - } - Bitu InitPage(Bitu lin_addr,bool writing) { - Bitu lin_page=lin_addr >> 12; - Bitu phys_page; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,writing,table,entry); - - // 0: no action - // 1: can (but currently does not) fail a user-level access privilege check - // 2: can (but currently does not) fail a write privilege check - // 3: fails a privilege check - Bitu priv_check=0; - if (InitPage_CheckUseraccess(entry.block.us,table.block.us)) { - if ((cpu.cpl&cpu.mpl)==3) priv_check=3; - else { - switch (CPU_ArchitectureType) { - case CPU_ARCHTYPE_MIXED: - case CPU_ARCHTYPE_386FAST: - default: -// priv_check=0; // default - break; - case CPU_ARCHTYPE_386SLOW: - case CPU_ARCHTYPE_486OLDSLOW: - case CPU_ARCHTYPE_486NEWSLOW: - case CPU_ARCHTYPE_PENTIUMSLOW: - priv_check=1; - break; - } - } - } - if ((entry.block.wr==0) || (table.block.wr==0)) { - // page is write-protected for user mode - if (priv_check==0) { - switch (CPU_ArchitectureType) { - case CPU_ARCHTYPE_MIXED: - case CPU_ARCHTYPE_386FAST: - default: -// priv_check=0; // default - break; - case CPU_ARCHTYPE_386SLOW: - case CPU_ARCHTYPE_486OLDSLOW: - case CPU_ARCHTYPE_486NEWSLOW: - case CPU_ARCHTYPE_PENTIUMSLOW: - priv_check=2; - break; - } - } - // check if actually failing the write-protected check - if (writing && USERWRITE_PROHIBITED) priv_check=3; - } - if (priv_check==3) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x05 | (writing?0x02:0x00)); - priv_check=0; - } - - if (!table.block.a) { - table.block.a=1; // set page table accessed - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if ((!entry.block.a) || (!entry.block.d)) { - entry.block.a=1; // set page accessed - - // page is dirty if we're writing to it, or if we're reading but the - // page will be fully linked so we can't track later writes - if (writing || (priv_check==0)) entry.block.d=1; // mark page as dirty - - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - - phys_page=entry.block.base; - - // now see how the page should be linked best, if we need to catch privilege - // checks later on it should be linked as read-only page - if (priv_check==0) { - // if reading we could link the page as read-only to later cacth writes, - // will slow down pretty much but allows catching all dirty events - PAGING_LinkPage(lin_page,phys_page); - } else { - if (priv_check==1) { - PAGING_LinkPage(lin_page,phys_page); - return 1; - } else if (writing) { - PageHandler * handler=MEM_GetPageHandler(phys_page); - PAGING_LinkPage(lin_page,phys_page); - if (!(handler->flags & PFLAG_READABLE)) return 1; - if (!(handler->flags & PFLAG_WRITEABLE)) return 1; - if (get_tlb_read(lin_addr)!=get_tlb_write(lin_addr)) return 1; - if (phys_page>1) return phys_page; - else return 1; - } else { - PAGING_LinkPage_ReadOnly(lin_page,phys_page); - } - } - } else { - if (lin_page> 12; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - if (!InitPageCheckPresence_CheckOnly(lin_addr,writing,table,entry)) return false; - - if (!USERWRITE_PROHIBITED) return true; - - if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || - (((entry.block.wr==0) || (table.block.wr==0)) && writing)) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=0x05 | (writing?0x02:0x00); - return false; - } - } else { - Bitu phys_page; - if (lin_page> 12; - Bitu phys_page; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,false,table,entry); - - if (!table.block.a) { - table.block.a=1; //Set access - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if (!entry.block.a) { - entry.block.a=1; //Set access - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - phys_page=entry.block.base; - // maybe use read-only page here if possible - } else { - if (lin_pagewrite_data8(get_tlb_read(addr)+addr,(Bit8u)(val&0xff)); - } - void writew(PhysPt addr,Bitu val) { - InitPage(addr,(Bit16u)(val&0xffff)); - d_dev->write_data16(get_tlb_read(addr)+addr,(Bit16u)(val&0xffff)); - } - void writed(PhysPt addr,Bitu val) { - InitPage(addr,(Bit32u)val); - d_dev->write_data32(get_tlb_read(addr)+addr,(Bit32u)val); - } - bool writeb_checked(PhysPt addr,Bitu val) { - Bitu writecode=InitPageCheckOnly(addr,(Bit8u)(val&0xff)); - if (writecode) { - HostPt tlb_addr; - if (writecode>1) tlb_addr=get_tlb_read(addr); - else tlb_addr=get_tlb_write(addr); - d_dev->write_data8(tlb_addr+addr,(Bit8u)(val&0xff)); - return false; - } - return true; - } - bool writew_checked(PhysPt addr,Bitu val) { - Bitu writecode=InitPageCheckOnly(addr,(Bit16u)(val&0xffff)); - if (writecode) { - HostPt tlb_addr; - if (writecode>1) tlb_addr=get_tlb_read(addr); - else tlb_addr=get_tlb_write(addr); - d_dev->write_data16(tlb_addr+addr,(Bit16u)(val&0xffff)); - return false; - } - return true; - } - bool writed_checked(PhysPt addr,Bitu val) { - Bitu writecode=InitPageCheckOnly(addr,(Bit32u)val); - if (writecode) { - HostPt tlb_addr; - if (writecode>1) tlb_addr=get_tlb_read(addr); - else tlb_addr=get_tlb_write(addr); - d_dev->write_data32(tlb_addr+addr,(Bit32u)val); - return false; - } - return true; - } - void InitPage(Bitu lin_addr,Bitu val) { - Bitu lin_page=lin_addr >> 12; - Bitu phys_page; - if (paging.enabled) { - if (!USERWRITE_PROHIBITED) return; - - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,true,table,entry); - - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x07); - - if (!table.block.a) { - table.block.a=1; //Set access - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if ((!entry.block.a) || (!entry.block.d)) { - entry.block.a=1; //Set access - entry.block.d=1; //Set dirty - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - phys_page=entry.block.base; - PAGING_LinkPage(lin_page,phys_page); - } else { - if (lin_page> 12; - if (paging.enabled) { - if (!USERWRITE_PROHIBITED) return 2; - - X86PageEntry table; - X86PageEntry entry; - if (!InitPageCheckPresence_CheckOnly(lin_addr,true,table,entry)) return 0; - - if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) { - LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x", - cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr); - paging.cr2=lin_addr; - cpu.exception.which=EXCEPTION_PF; - cpu.exception.error=0x07; - return 0; - } - PAGING_LinkPage(lin_page,entry.block.base); - } else { - Bitu phys_page; - if (lin_page> 12; - Bitu phys_page; - if (paging.enabled) { - X86PageEntry table; - X86PageEntry entry; - InitPageCheckPresence(lin_addr,true,table,entry); - - if (!table.block.a) { - table.block.a=1; //Set access - phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load); - } - if (!entry.block.a) { - entry.block.a=1; //Set access - phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load); - } - phys_page=entry.block.base; - } else { - if (lin_page> 10; - Bitu t_index=page & 0x3ff; - X86PageEntry table; - table.load=phys_readd((paging.base.page<<12)+d_index*4); - if (!table.block.p) return false; - X86PageEntry entry; - entry.load=phys_readd((table.block.base<<12)+t_index*4); - if (!entry.block.p) return false; - page=entry.block.base; - } else { - if (page>12,1); - init_page_handler_userro.InitPageForced(lin_addr); - return true; - } - return false; -} - -#if defined(USE_FULL_TLB) -INLINE void InitTLBInt(tlb_entry *bank) { -} - -void PAGING_InitTLB(void) { - for (Bitu i=0;i0;paging.links.used--) { - Bitu page=*entries++; - paging.tlb.read[page]=0; - paging.tlb.write[page]=0; - paging.tlb.readhandler[page]=&init_page_handler; - paging.tlb.writehandler[page]=&init_page_handler; - } - paging.links.used=0; -} - -void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { - for (;pages>0;pages--) { - paging.tlb.read[lin_page]=0; - paging.tlb.write[lin_page]=0; - paging.tlb.readhandler[lin_page]=&init_page_handler; - paging.tlb.writehandler[lin_page]=&init_page_handler; - lin_page++; - } -} - -void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { - if (lin_page=TLB_SIZE || phys_page>=TLB_SIZE) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - paging.tlb.phys_page[lin_page]=phys_page; - if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base; - else paging.tlb.read[lin_page]=0; - if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=handler->GetHostWritePt(phys_page)-lin_base; - else paging.tlb.write[lin_page]=0; - - paging.links.entries[paging.links.used++]=lin_page; - paging.tlb.readhandler[lin_page]=handler; - paging.tlb.writehandler[lin_page]=handler; -} - -void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) { - PageHandler * handler=MEM_GetPageHandler(phys_page); - Bitu lin_base=lin_page << 12; - if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - paging.tlb.phys_page[lin_page]=phys_page; - if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base; - else paging.tlb.read[lin_page]=0; - paging.tlb.write[lin_page]=0; - - paging.links.entries[paging.links.used++]=lin_page; - paging.tlb.readhandler[lin_page]=handler; - paging.tlb.writehandler[lin_page]=&init_page_handler_userro; -} - -#else - -INLINE void InitTLBInt(tlb_entry *bank) { - for (Bitu i=0;i0;paging.links.used--) { - Bitu page=*entries++; - tlb_entry *entry = get_tlb_entry(page<<12); - entry->read=0; - entry->write=0; - entry->readhandler=&init_page_handler; - entry->writehandler=&init_page_handler; - } - paging.links.used=0; -} - -void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { - for (;pages>0;pages--) { - tlb_entry *entry = get_tlb_entry(lin_page<<12); - entry->read=0; - entry->write=0; - entry->readhandler=&init_page_handler; - entry->writehandler=&init_page_handler; - lin_page++; - } -} - -void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { - if (lin_page=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - tlb_entry *entry = get_tlb_entry(lin_base); - entry->phys_page=phys_page; - if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base; - else entry->read=0; - if (handler->flags & PFLAG_WRITEABLE) entry->write=handler->GetHostWritePt(phys_page)-lin_base; - else entry->write=0; - - paging.links.entries[paging.links.used++]=lin_page; - entry->readhandler=handler; - entry->writehandler=handler; -} - -void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) { - PageHandler * handler=MEM_GetPageHandler(phys_page); - Bitu lin_base=lin_page << 12; - if (lin_page>=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) - E_Exit("Illegal page"); - - if (paging.links.used>=PAGING_LINKS) { - LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); - PAGING_ClearTLB(); - } - - tlb_entry *entry = get_tlb_entry(lin_base); - entry->phys_page=phys_page; - if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base; - else entry->read=0; - entry->write=0; - - paging.links.entries[paging.links.used++]=lin_page; - entry->readhandler=handler; - entry->writehandler=&init_page_handler_userro; -} - -#endif - - -void PAGING_SetDirBase(Bitu cr3) { - paging.cr3=cr3; - - paging.base.page=cr3 >> 12; - paging.base.addr=cr3 & ~4095; -// LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page); - if (paging.enabled) { - PAGING_ClearTLB(); - } -} - -void PAGING_Enable(bool enabled) { - /* If paging is disabled, we work from a default paging table */ - if (paging.enabled==enabled) return; - paging.enabled=enabled; - if (enabled) { - if (GCC_UNLIKELY(cpudecoder==CPU_Core_Simple_Run)) { -// LOG_MSG("CPU core simple won't run this game,switching to normal"); - cpudecoder=CPU_Core_Normal_Run; - CPU_CycleLeft+=CPU_Cycles; - CPU_Cycles=0; - } -// LOG(LOG_PAGING,LOG_NORMAL)("Enabled"); - PAGING_SetDirBase(paging.cr3); - } - PAGING_ClearTLB(); -} - -bool PAGING_Enabled(void) { - return paging.enabled; -} - -class PAGING:public MinimumSkelton{ - I386_DOSBOX *d_parent; -public: - PAGING(DEVICE* parent): MinimumSkelton(parent){ - /* Setup default Page Directory, force it to update */ - d_parent = static_cast(parent); - - d_parent->paging.enabled=false; - d_parent->PAGING_InitTLB(); - Bitu i; - for (i=0;ipaging.firstmb[i]=i; - } - d_parent->pf_queue.used=0; - - } - ~PAGING(){} -}; - -static PAGING* test; - -void PAGING_Init(Section * sec) { - test = new PAGING(this, sec); -} -}; diff --git a/source/src/vm/libcpu_newdev/dosbox-i386/types_compat.h b/source/src/vm/libcpu_newdev/dosbox-i386/types_compat.h deleted file mode 100644 index 34fc55406..000000000 --- a/source/src/vm/libcpu_newdev/dosbox-i386/types_compat.h +++ /dev/null @@ -1,575 +0,0 @@ -/* - Skelton for retropc emulator - - Origin : MAME i386 core - Author : Kyuma.Ohta - Date : 2019.05.21- - - [ i386-i586 core compatible header from DOSBOX] -*/ - - -#if !defined(__CSP_I386_DOSBOX_TYPES_COMPAT_H__) -#define __CSP_I386_DOSBOX_TYPES_COMPAT_H__ - -#ifndef __OPCALL -#define __OPCALL -#endif - -#ifndef __OPCALL_INLINE -#define __OPCALL_INLINE __inline__ -#endif - -#ifndef INLINE -#define INLINE __inline__ -#endif - -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif - -#if C_ATTRIBUTE_ALWAYS_INLINE -#define INLINE inline __attribute__((always_inline)) -#else -#define INLINE inline -#endif - -#if C_ATTRIBUTE_FASTCALL -#define DB_FASTCALL __attribute__((fastcall)) -#else -#define DB_FASTCALL -#endif - -#if C_HAS_ATTRIBUTE -#define GCC_ATTRIBUTE(x) __attribute__ ((x)) -#else -#define GCC_ATTRIBUTE(x) /* attribute not supported */ -#endif - -#if C_HAS_BUILTIN_EXPECT -#define GCC_UNLIKELY(x) __builtin_expect((x),0) -#define GCC_LIKELY(x) __builtin_expect((x),1) -#else -#define GCC_UNLIKELY(x) (x) -#define GCC_LIKELY(x) (x) -#endif - -typedef uint8_t Bit8u; -typedef uint16_t Bit16u; -typedef uint33_t Bit32u; -typedef uint64_t Bit64u; - -typedef int8_t Bit8s; -typedef int16_t Bit16s; -typedef int33_t Bit32s; -typedef int64_t Bit64s; - -typedef int32_t Bits; -typedef uint32_t Bitu; - -typedef double Real64; - - -#include "device.h" - -// Sorry, needs C++11 or later. 20190521 K.Ohta -namespace I386_DOSBOX { -class MinimumSkelton { -protected: - DEVICE* d_device; - boot verbose_log; -public: - void MinimumSkelton(DEVICE* parent) - { - d_device = parent; - verbose_log = false; // OK? - } - virtual void ~MinimumSkelton() { } - void set_logging(bool onoff) - { - verbose_log = onoff; - } - template - void E_Exit(Args... args) { - if((verbose_log) && (d_device != NULL)) { - d_device->out_debug_log(args...); - } - } -}; -}; - -#include "./include/paging.h" -#include "./include/regs.h" -#include "./lazyflags.h" - -class TaskStateSegment { - I386_DOSBOX *d_cpu; -public: - TaskStateSegment(I386_DOSBOX *parent = NULL) { - d_cpu = parent; - valid=false; - } - void SetCpuDomain(I386_DOSBOX *p) { - d_cpu = p; - } - bool IsValid(void) { - return valid; - } - Bitu Get_back(void); - void SaveSelector(void); - void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp); - bool SetSelector(Bitu new_sel); - TSS_Descriptor desc; - Bitu selector; - PhysPt base; - Bitu limit; - Bitu is386; - bool valid; -}; - -class I386_DOSBOX : public DEVICE -{ -protected: - struct LazyFlags { - GenReg32 var1,var2,res; - Bitu type; - Bitu prev_type; - Bitu oldcf; - } lflags; - - const Bit8u * lookupRMregb[]; - const Bit16u * lookupRMregw[]; - const Bit32u * lookupRMregd[256]; - - const Bit8u * lookupRMEAregb[256]; - const Bit16u * lookupRMEAregw[256]; - const Bit16u * lookupRMEAregd[256]; - - CPU_Regs cpu_regs; - CPUBlock cpu; - Segments Segs; - - Bit32s CPU_Cycles; - Bit32s CPU_CycleLeft; - Bit32s CPU_CycleMax; - Bit32s CPU_OldCycleMax; - Bit32s CPU_CyclePercUsed; - Bit32s CPU_CycleLimit; - Bit32s CPU_CycleUp; - Bit32s CPU_CycleDown; - Bit64s CPU_IODelayRemoved; - CPU_Decoder * cpudecoder; - bool CPU_CycleAutoAdjust; - bool CPU_SkipCycleAutoAdjust; - Bitu CPU_AutoDetermineMode; - Bitu CPU_ArchitectureType; - Bitu CPU_extflags_toggle; // ID and AC flags may be toggled depending on emulated CPU architecture - Bitu CPU_PrefetchQueueSize; - Bit32s ticksDone; - Bit32u ticksScheduled; - - bool verbose_log; - struct MemoryBlock { - Bitu pages; - PageHandler * * phandlers; - MemHandle * mhandles; - LinkBlock links; - struct { - Bitu start_page; - Bitu end_page; - Bitu pages; - PageHandler *handler; - PageHandler *mmiohandler; - } lfb; - struct { - bool enabled; - Bit8u controlport; - } a20; - } memory; - PagingBlock paging; - - TaskStateSegment cpu_tss; - - virtual void PAGING_Enable(bool enabled); - virtual bool PAGING_Enabled(void); - virtual Bitu PAGING_GetDirBase(void); - virtual void PAGING_SetDirBase(Bitu cr3); - virtual void PAGING_InitTLB(void); - virtual void PAGING_ClearTLB(void); - virtual void PAGING_InitTLBBank(tlb_entry **bank); - - virtual void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); - virtual void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page); - virtual void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); -/* This maps the page directly, only use when paging is disabled */ - virtual void PAGING_MapPage(Bitu lin_page,Bitu phys_page); - virtual bool PAGING_MakePhysPage(Bitu & page); - virtual bool PAGING_ForcePageInit(Bitu lin_addr); - - INLINE void InitTLBInt(tlb_entry *bank); - - virtual void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler); - virtual void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); - virtual void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); - virtual PageHandler * MEM_GetPageHandler(Bitu phys_page); - - virtual INLINE HostPt get_tlb_read(PhysPt address); - virtual INLINE HostPt get_tlb_write(PhysPt address); - virtual INLINE PageHandler* get_tlb_readhandler(PhysPt address); - virtual INLINE PageHandler* get_tlb_writehandler(PhysPt address); - virtual INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage); - virtual INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr); - virtual INLINE tlb_entry *get_tlb_entry(PhysPt address); - virtual INLINE Bit8u mem_readb_inline(PhysPt address); - - - virtual void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler); - virtual void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); - virtual void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); - - virtual Bit16u mem_unalignedreadw(PhysPt address); - virtual Bit32u mem_unalignedreadd(PhysPt address); - virtual void mem_unalignedwritew(PhysPt address,Bit16u val); - virtual void mem_unalignedwrited(PhysPt address,Bit32u val); - - virtual bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val); - virtual bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val); - virtual bool mem_unalignedwritew_checked(PhysPt address,Bit16u val); - virtual bool mem_unalignedwrited_checked(PhysPt address,Bit32u val); - - INLINE Bit8u mem_readb_inline(PhysPt address); - INLINE Bit16u mem_readw_inline(PhysPt address); - INLINE Bit32u mem_readd_inline(PhysPt address); - - INLINE void mem_writeb_inline(PhysPt address,Bit8u val); - INLINE void mem_writew_inline(PhysPt address,Bit16u val); - INLINE void mem_writed_inline(PhysPt address,Bit32u val); - - INLINE bool mem_readb_checked(PhysPt address, Bit8u * val); - INLINE bool mem_readw_checked(PhysPt address, Bit16u * val); - INLINE bool mem_readd_checked(PhysPt address, Bit32u * val); - - INLINE bool mem_writeb_checked(PhysPt address, Bit8u val); - INLINE bool mem_writew_checked(PhysPt address, Bit16u val); - INLINE bool mem_writed_checked(PhysPt address, Bit32u val); - void PAGING_Init(Section * sec); - - //Flag Handling - Bit32u get_CF(void); - Bit32u get_AF(void); - Bit32u get_ZF(void); - Bit32u get_SF(void); - Bit32u get_OF(void); - Bit32u get_PF(void); - - INLINE void CPU_SetFlagsd(Bitu word); - INLINE void CPU_SetFlagsw(Bitu word); - - Bitu FillFlags(void); - void FillFlagsNoCFOF(void); - void DestroyConditionFlags(void); - - void CPU_Core_Full_Init(void); - void CPU_Core_Normal_Init(void); - void CPU_Core_Simple_Init(void); -#if (C_DYNAMIC_X86) - void CPU_Core_Dyn_X86_Init(void); - void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache); - void CPU_Core_Dyn_X86_Cache_Close(void); - void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu); -#elif (C_DYNREC) - void CPU_Core_Dynrec_Init(void); - void CPU_Core_Dynrec_Cache_Init(bool enable_cache); - void CPU_Core_Dynrec_Cache_Close(void); -#endif - - // Within CPU - bool inited; - void CPU_Push16(Bitu value); - void CPU_Push32(Bitu value); - Bitu CPU_Pop16(); - Bitu CPU_Pop32(); - PhysPt SelBase(Bitu sel); - void CPU_SetFlags(Bitu word,Bitu mask); - bool CPU_PrepareException(Bitu which,Bitu error); - bool CPU_CLI(void); - bool CPU_STI(void); - bool CPU_POPF(Bitu use32); - bool CPU_PUSHF(Bitu use32); - void CPU_CheckSegments(void); - - void CPU_Reset_AutoAdjust(void); - void CPU_Disable_SkipAutoAdjust(void); - -public: - I386_DOSBOX(VM_TEMPLATE *parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) - { - CPU_Cycles = 0; - CPU_CycleLeft = 3000; - CPU_CycleMax = 3000; - CPU_OldCycleMax = 3000; - CPU_CyclePercUsed = 100; - CPU_CycleLimit = -1; - CPU_CycleUp = 0; - CPU_CycleDown = 0; - CPU_IODelayRemoved = 0; - CPU_CycleAutoAdjust = false; - CPU_SkipCycleAutoAdjust = false; - CPU_AutoDetermineMode = 0; - - CPU_ArchitectureType = CPU_ARCHTYPE_MIXED; - CPU_extflags_toggle=0; // ID and AC flags may be toggled depending on emulated CPU architecture - - CPU_PrefetchQueueSize=0; - - //initialize static members - inited=false; - verbose_log = false; - - cpu_tss.SetCpuDomain(this); - set_device_name(_T("I386(DOSBOX Variant)")); - } - ~I386_DOSBOX() { } - void set_logging(bool onoff) - { - verbose_log = onoff; - } - template - void E_Exit(Args... args) { - if((verbose_log) && (d_device != NULL)) { - d_device->out_debug_log(args...); - } - } - -}; - -void I386_DOSBOX::initialize() -{ -// if(inited) { -// Change_Config(); -// return; // OK? -// } - inited = true; - reg_eax=0; - reg_ebx=0; - reg_ecx=0; - reg_edx=0; - reg_edi=0; - reg_esi=0; - reg_ebp=0; - reg_esp=0; - - SegSet16(cs,0); - SegSet16(ds,0); - SegSet16(es,0); - SegSet16(fs,0); - SegSet16(gs,0); - SegSet16(ss,0); - - CPU_SetFlags(FLAG_IF,FMASK_ALL); //Enable interrupts - cpu.cr0=0xffffffff; - CPU_SET_CRX(0,0); //Initialize - cpu.code.big=false; - cpu.stack.mask=0xffff; - cpu.stack.notmask=0xffff0000; - cpu.stack.big=false; - cpu.trap_skip=false; - cpu.idt.SetBase(0); - cpu.idt.SetLimit(1023); - - for (Bitu i=0; i<7; i++) { - cpu.drx[i]=0; - cpu.trx[i]=0; - } - if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) { - cpu.drx[6]=0xffff0ff0; - } else { - cpu.drx[6]=0xffff1ff0; - } - cpu.drx[7]=0x00000400; - - /* Init the cpu cores */ - CPU_Core_Normal_Init(); - CPU_Core_Simple_Init(); - CPU_Core_Full_Init(); -#if (C_DYNAMIC_X86) - CPU_Core_Dyn_X86_Init(); -#elif (C_DYNREC) - CPU_Core_Dynrec_Init(); -#endif - //MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles"); - //MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles"); - //Change_Config(configuration); - CPU_JMP(false,0,0,0); //Setup the first cpu core -} - - -namespace I386_DOSBOX { - -#if defined(USE_FULL_TLB) - -INLINE HostPt get_tlb_read(PhysPt address) { - return paging.tlb.read[address>>12]; -} -INLINE HostPt get_tlb_write(PhysPt address) { - return paging.tlb.write[address>>12]; -} -INLINE PageHandler* get_tlb_readhandler(PhysPt address) { - return paging.tlb.readhandler[address>>12]; -} -INLINE PageHandler* get_tlb_writehandler(PhysPt address) { - return paging.tlb.writehandler[address>>12]; -} - -/* Use these helper functions to access linear addresses in readX/writeX functions */ -INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - return (paging.tlb.phys_page[linePage>>12]<<12); -} - -INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); -} - -#else - - -INLINE tlb_entry *get_tlb_entry(PhysPt address) { - Bitu index=(address>>12); - if (TLB_BANKS && (index > TLB_SIZE)) { - Bitu bank=(address>>BANK_SHIFT) - 1; - if (!paging.tlbh_banks[bank]) - PAGING_InitTLBBank(&paging.tlbh_banks[bank]); - return &paging.tlbh_banks[bank][index & BANK_MASK]; - } - return &paging.tlbh[index]; -} - -INLINE HostPt get_tlb_read(PhysPt address) { - return get_tlb_entry(address)->read; -} -INLINE HostPt get_tlb_write(PhysPt address) { - return get_tlb_entry(address)->write; -} -INLINE PageHandler* get_tlb_readhandler(PhysPt address) { - return get_tlb_entry(address)->readhandler; -} -INLINE PageHandler* get_tlb_writehandler(PhysPt address) { - return get_tlb_entry(address)->writehandler; -} - -/* Use these helper functions to access linear addresses in readX/writeX functions */ -INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - tlb_entry *entry = get_tlb_entry(linePage); - return (entry->phys_page<<12); -} - -INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - tlb_entry *entry = get_tlb_entry(linAddr); - return (entry->phys_page<<12)|(linAddr&0xfff); -} -#endif - -/* Special inlined memory reading/writing */ -INLINE Bit8u mem_readb_inline(PhysPt address) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return read_data8(tlb_addr+address); - else return (Bit8u)(get_tlb_readhandler(address))->readb(address); -} - -INLINE Bit16u mem_readw_inline(PhysPt address) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return read_data16(tlb_addr+address); - else return (Bit16u)(get_tlb_readhandler(address))->readw(address); - } else return mem_unalignedreadw(address); -} - -INLINE Bit32u mem_readd_inline(PhysPt address) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) return read_data32(tlb_addr+address); - else return (get_tlb_readhandler(address))->readd(address); - } else return mem_unalignedreadd(address); -} - -INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) write_data8(tlb_addr + address, val); - else (get_tlb_writehandler(address))->writeb(address,val); -} - -INLINE void mem_writew_inline(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) write_data16(tlb_addr+address,val); - else (get_tlb_writehandler(address))->writew(address,val); - } else mem_unalignedwritew(address,val); -} - -INLINE void mem_writed_inline(PhysPt address,Bit32u val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) write_data32(tlb_addr+address,val); - else (get_tlb_writehandler(address))->writed(address,val); - } else mem_unalignedwrited(address,val); -} - - -INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val=read_data8(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readb_checked(address, val); -} - -INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val = read_data16(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readw_checked(address, val); - } else return mem_unalignedreadw_checked(address, val); -} - -INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_read(address); - if (tlb_addr) { - *val= read_data32(tlb_addr+address); - return false; - } else return (get_tlb_readhandler(address))->readd_checked(address, val); - } else return mem_unalignedreadd_checked(address, val); -} - -INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - write_data8(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writeb_checked(address,val); -} - -INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { - if ((address & 0xfff)<0xfff) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - write_data16(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writew_checked(address,val); - } else return mem_unalignedwritew_checked(address,val); -} - -INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { - if ((address & 0xfff)<0xffd) { - HostPt tlb_addr=get_tlb_write(address); - if (tlb_addr) { - write_data32(tlb_addr+address,val); - return false; - } else return (get_tlb_writehandler(address))->writed_checked(address,val); - } else return mem_unalignedwrited_checked(address,val); -} - -}; -#endif // __CSP_I386_DOSBOX_TYPES_COMPAT_H__ diff --git a/source/src/vm/libcpu_newdev/i386/000_artane.txt b/source/src/vm/libcpu_newdev/i386/000_artane.txt deleted file mode 100644 index 8065b8626..000000000 --- a/source/src/vm/libcpu_newdev/i386/000_artane.txt +++ /dev/null @@ -1 +0,0 @@ -This source code from src/devices/cpu/i386, MAME 0.208. \ No newline at end of file diff --git a/source/src/vm/libcpu_newdev/i386/cache.h b/source/src/vm/libcpu_newdev/i386/cache.h deleted file mode 100644 index 371021fea..000000000 --- a/source/src/vm/libcpu_newdev/i386/cache.h +++ /dev/null @@ -1,258 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Samuele Zannoli - -#ifndef MAME_CPU_I386_CACHE_H -#define MAME_CPU_I386_CACHE_H - -#pragma once - -/* To test it outside of Mame -#include - -typedef unsigned char u8; -typedef unsigned int u32; -*/ - -enum { - CacheLineBytes16 = 4, - CacheLineBytes32 = 5, - CacheLineBytes64 = 6, - CacheLineBytes128 = 7, - CacheLineBytes256 = 8, -}; - -enum { - CacheDirectMapped = 0, - Cache2Way = 1, - Cache4Way = 2, - Cache8Way = 3, - Cache16Way = 4 -}; - -enum { - CacheRead = 0, - CacheWrite = 1 -}; - -template -class cpucache { -public: - // Constructor - cpucache(); - // Reset the cache - void reset(); - // Find the cacheline containing data at address - template uint8_t* search(uint32_t address); - // Allocate a cacheline for data at address - template bool allocate(uint32_t address, uint8_t **data); - // Get the address where the cacheline data should be written back to - uint32_t old(); - // Get the address of the first byte of the cacheline that contains data at address - uint32_t base(uint32_t address); - // Compose the cacheline parameters into an address - uint32_t address(uint32_t tag, uint32_t set, uint32_t offset); - // Get the data of the first cacheline marked as dirty - uint8_t* first_dirty(uint32_t &base, bool clean); - // Get the data of the next cacheline marked as dirty - uint8_t* next_dirty(uint32_t &base, bool clean); - -private: - static const int Ways = 1 << WayBits; - static const int LineBytes = 1 << LineBits; - static const int Sets = 1 << SetBits; - static const uint32_t LineMask = (1 << LineBits) - 1; - static const uint32_t SetMask = ((1 << SetBits) - 1) << LineBits; - static const uint32_t WayMask = (1 << WayBits) - 1; - static const int TagShift = LineBits + SetBits; - - struct cacheline { - uint8_t data[LineBytes]; - bool allocated; - bool dirty; - uint32_t tag; - uint32_t debug_address; - }; - - struct cacheset { - cacheline lines[Ways]; - int nextway; - }; - - cacheset sets[Sets]; - uint32_t writeback_base; - int last_set; - int last_way; -}; - -template -cpucache::cpucache() -{ - reset(); -} - -template -void cpucache::reset() -{ - for (int s = 0; s < Sets; s++) - for (int w = 0; w < Ways; w++) - { - sets[s].nextway = 0; - sets[s].lines[w].allocated = false; - sets[s].lines[w].dirty = false; - sets[s].lines[w].debug_address = 0; - } - last_set = -1; - last_way = -1; -} - -template -template -uint8_t* cpucache::search(uint32_t address) -{ - const int addresset = (address & SetMask) >> LineBits; - const int addrestag = address >> TagShift; - - for (int w = 0; w < Ways; w++) - if ((sets[addresset].lines[w].allocated) && (sets[addresset].lines[w].tag == addrestag)) - { - if (ReadWrite != 0) - sets[addresset].lines[w].dirty = true; - return sets[addresset].lines[w].data; - } - return nullptr; -} - -template -template -bool cpucache::allocate(uint32_t address, uint8_t **data) -{ - const int addresset = (address & SetMask) >> LineBits; - const int addrestag = address >> TagShift; - const int victimway = sets[addresset].nextway; - bool old_allocated, old_dirty; - bool ret; - - sets[addresset].nextway = (victimway + 1) & WayMask; // decide wich way will be allocated next - old_allocated = sets[addresset].lines[victimway].allocated; - old_dirty = sets[addresset].lines[victimway].dirty; - writeback_base = (sets[addresset].lines[victimway].tag << TagShift) | (address & SetMask); - sets[addresset].lines[victimway].tag = addrestag; - sets[addresset].lines[victimway].allocated = true; - if (ReadWrite == 0) - sets[addresset].lines[victimway].dirty = false; // caller must write back the cacheline if told so - else - sets[addresset].lines[victimway].dirty = true; // line is allocated to write into it - *data = sets[addresset].lines[victimway].data; - sets[addresset].lines[victimway].debug_address = address; - ret = old_allocated; // ret = old_allocated && old_dirty - if (!old_dirty) - ret = false; - return ret; // true if caller must write back the cacheline -} - -template -uint32_t cpucache::old() -{ - return writeback_base; -} - -template -uint32_t cpucache::base(uint32_t address) -{ - return address & ~LineMask; -} - -template -uint32_t cpucache::address(uint32_t tag, uint32_t set, uint32_t offset) -{ - return (tag << TagShift) | (set << LineBits) | offset; -} - -template -uint8_t* cpucache::first_dirty(uint32_t &base, bool clean) -{ - for (int s = 0; s < Sets; s++) - for (int w = 0; w < Ways; w++) - if (sets[s].lines[w].dirty == true) - { - if (clean) - sets[s].lines[w].dirty = false; - last_set = s; - last_way = w; - base = address(sets[s].lines[w].tag, s, 0); - return sets[s].lines[w].data; - } - return nullptr; -} - -template -uint8_t* cpucache::next_dirty(uint32_t &base, bool clean) -{ - if (last_set < 0) - return nullptr; - while (true) - { - last_way++; - if (last_way == Ways) - { - last_way = 0; - last_set++; - if (last_set == Sets) - { - last_set = -1; - last_way = -1; - return nullptr; - } - } - if (sets[last_set].lines[last_way].dirty == true) - { - if (clean) - sets[last_set].lines[last_way].dirty = false; - base = address(sets[last_set].lines[last_way].tag, last_set, 0); - return sets[last_set].lines[last_way].data; - } - } -} - -#endif - -/* To test it outside of Mame -const int memorysize = 256 * 1024; -uint8_t memory[memorysize]; - -void readline(uint8_t *data, uint32_t address) -{ - for (int n = 0; n < 64; n++) - data[n] = memory[address + n]; -} - -void writeline(uint8_t *data, uint32_t address) -{ - for (int n = 0; n < 64; n++) - memory[address + n] = data[n]; -} - -void cache_tester() -{ - cpucache<18, 8, 6, 2> cache; - bool r; - uint8_t *data; - int address; - uint8_t value; - - for (int n = 0; n < memorysize; n++) - memory[n] = 0xaa ^ n; - address = std::rand() & (memorysize - 1); - r = cache.search(address, &data); - if (r == false) - { - r = cache.allocate(address, &data); - if (r == true) - writeline(data, cache.base(address)); - readline(data, cache.base(address)); - } - value = data[address & 63]; - if (value != memory[address]) - printf("Error reading address %d\n\r", address); -} -*/ diff --git a/source/src/vm/libcpu_newdev/i386/cpuidmsrs.hxx b/source/src/vm/libcpu_newdev/i386/cpuidmsrs.hxx deleted file mode 100644 index 7db7325f7..000000000 --- a/source/src/vm/libcpu_newdev/i386/cpuidmsrs.hxx +++ /dev/null @@ -1,452 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett, Samuele Zannoli - -uint64_t pentium_device::opcode_rdmsr(bool &valid_msr) -{ - uint32_t offset = REG32(ECX); - - switch (offset) - { - // Machine Check Exception (TODO) - case 0x00: - valid_msr = true; - popmessage("RDMSR: Reading P5_MC_ADDR"); - return 0; - case 0x01: - valid_msr = true; - popmessage("RDMSR: Reading P5_MC_TYPE"); - return 0; - // Time Stamp Counter - case 0x10: - valid_msr = true; - popmessage("RDMSR: Reading TSC"); - return m_tsc; - // Event Counters (TODO) - case 0x11: // CESR - valid_msr = true; - popmessage("RDMSR: Reading CESR"); - return 0; - case 0x12: // CTR0 - valid_msr = true; - return m_perfctr[0]; - case 0x13: // CTR1 - valid_msr = true; - return m_perfctr[1]; - default: - if (!(offset & ~0xf)) // 2-f are test registers - { - valid_msr = true; - logerror("RDMSR: Reading test MSR %x", offset); - return 0; - } - logerror("RDMSR: invalid P5 MSR read %08x at %08x\n", offset, m_pc - 2); - valid_msr = false; - return 0; - } - return -1; -} - -void pentium_device::opcode_wrmsr(uint64_t data, bool &valid_msr) -{ - uint32_t offset = REG32(ECX); - - switch (offset) - { - // Machine Check Exception (TODO) - case 0x00: - popmessage("WRMSR: Writing P5_MC_ADDR"); - valid_msr = true; - break; - case 0x01: - popmessage("WRMSR: Writing P5_MC_TYPE"); - valid_msr = true; - break; - // Time Stamp Counter - case 0x10: - m_tsc = data; - popmessage("WRMSR: Writing to TSC"); - valid_msr = true; - break; - // Event Counters (TODO) - case 0x11: // CESR - popmessage("WRMSR: Writing to CESR"); - valid_msr = true; - break; - case 0x12: // CTR0 - m_perfctr[0] = data; - valid_msr = true; - break; - case 0x13: // CTR1 - m_perfctr[1] = data; - valid_msr = true; - break; - default: - if (!(offset & ~0xf)) // 2-f are test registers - { - valid_msr = true; - logerror("WRMSR: Writing test MSR %x", offset); - break; - } - logerror("WRMSR: invalid MSR write %08x (%08x%08x) at %08x\n", offset, (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2); - valid_msr = false; - break; - } -} - -uint64_t pentium_pro_device::opcode_rdmsr(bool &valid_msr) -{ - uint32_t offset = REG32(ECX); - - switch (offset) - { - // Machine Check Exception (TODO) - case 0x00: - valid_msr = true; - popmessage("RDMSR: Reading P5_MC_ADDR"); - return 0; - case 0x01: - valid_msr = true; - popmessage("RDMSR: Reading P5_MC_TYPE"); - return 0; - // Time Stamp Counter - case 0x10: - valid_msr = true; - popmessage("RDMSR: Reading TSC"); - return m_tsc; - // Performance Counters (TODO) - case 0xc1: // PerfCtr0 - valid_msr = true; - return m_perfctr[0]; - case 0xc2: // PerfCtr1 - valid_msr = true; - return m_perfctr[1]; - default: - logerror("RDMSR: unimplemented register called %08x at %08x\n", offset, m_pc - 2); - valid_msr = true; - return 0; - } - return -1; -} - -void pentium_pro_device::opcode_wrmsr(uint64_t data, bool &valid_msr) -{ - uint32_t offset = REG32(ECX); - - switch (offset) - { - // Time Stamp Counter - case 0x10: - m_tsc = data; - popmessage("WRMSR: Writing to TSC"); - valid_msr = true; - break; - // Performance Counters (TODO) - case 0xc1: // PerfCtr0 - m_perfctr[0] = data; - valid_msr = true; - break; - case 0xc2: // PerfCtr1 - m_perfctr[1] = data; - valid_msr = true; - break; - default: - logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n", offset, (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2); - valid_msr = true; - break; - } -} - -uint64_t pentium4_device::opcode_rdmsr(bool &valid_msr) -{ - switch (REG32(ECX)) - { - default: - logerror("RDMSR: unimplemented register called %08x at %08x\n", REG32(ECX), m_pc - 2); - valid_msr = true; - return 0; - } - return -1; -} - -void pentium4_device::opcode_wrmsr(uint64_t data, bool &valid_msr) -{ - switch (REG32(ECX)) - { - default: - logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n", REG32(ECX), (uint32_t)(data >> 32), (uint32_t)data, m_pc - 2); - valid_msr = true; - break; - } -} -#if 0 -void athlonxp_device::opcode_cpuid() -{ - switch (REG32(EAX)) - { - case 0x80000000: - { - REG32(EAX) = 0x80000008; - REG32(EBX) = m_cpuid_id0; - REG32(ECX) = m_cpuid_id2; - REG32(EDX) = m_cpuid_id1; - CYCLES(CYCLES_CPUID); - break; - } - - case 0x80000001: - { - REG32(EAX) = m_cpu_version + 0x100; // family+1 as specified in AMD documentation - REG32(EDX) = m_feature_flags; - CYCLES(CYCLES_CPUID); - break; - } - - case 0x80000002: - case 0x80000003: - case 0x80000004: - { - int offset = (REG32(EAX) - 0x80000002) << 4; - uint8_t *b = m_processor_name_string + offset; - REG32(EAX) = b[ 0] + (b[ 1] << 8) + (b[ 2] << 16) + (b[ 3] << 24); - REG32(EBX) = b[ 4] + (b[ 5] << 8) + (b[ 6] << 16) + (b[ 7] << 24); - REG32(ECX) = b[ 8] + (b[ 9] << 8) + (b[10] << 16) + (b[11] << 24); - REG32(EDX) = b[12] + (b[13] << 8) + (b[14] << 16) + (b[15] << 24); - CYCLES(CYCLES_CPUID); - break; - } - - case 0x80000005: - { - REG32(EAX) = 0x0408FF08; // 2M/4M data tlb associativity 04 data tlb number of entries 08 instruction tlb associativity FF instruction tlb number of entries 08 - REG32(EBX) = 0xFF20FF10; // 4K data tlb associativity FF data tlb number of entries 20 instruction tlb associativity FF instruction tlb number of entries 10 - REG32(ECX) = 0x40020140; // L1 data cache size in K 40 associativity 02 lines per tag 01 line size in bytes 40 - REG32(EDX) = 0x40020140; // L1 instruction cache size in K 40 associativity 02 lines per tag 01 line size in bytes 40 - CYCLES(CYCLES_CPUID); - break; - } - - case 0x80000006: - { - REG32(EAX) = 0; - REG32(EBX) = 0x41004100; // 4 100 4 100 - REG32(ECX) = 0x01008140; // L2 cache size in K 0100 associativity 8=16-way lines per tag 1 line size in bytes 40 - CYCLES(CYCLES_CPUID); - break; - } - - case 0x80000007: - { - REG32(EDX) = 1; - CYCLES(CYCLES_CPUID); - break; - } - - case 0x80000008: - { - REG32(EAX) = 0x00002022; - CYCLES(CYCLES_CPUID); - break; - } - - default: - i386_device::opcode_cpuid(); - } -} - -uint64_t athlonxp_device::opcode_rdmsr(bool &valid_msr) -{ - uint64_t ret; - uint32_t offset = REG32(ECX); - - ret = 0; - switch (offset) - { - case 0x10: // TSC - break; - case 0x1b: // APIC_BASE - break; - case 0xfe: // MTRRcap - // 7-0 MTRRCapVCnt - Number of variable range MTRRs (8) - // 8 MtrrCapFix - Fixed range MTRRs available (1) - // 10 MtrrCapWc - Write combining memory type available (1) - ret = 0x508; - break; - case 0x17b: // MCG_CTL - break; - case 0x200: // MTRRphysBase0-7 - case 0x202: - case 0x204: - case 0x206: - case 0x208: - case 0x20a: - case 0x20c: - case 0x20e: - // 7-0 Type - Memory type for this memory range - // 39-12 PhyBase27-0 - Base address for this memory range - /* Format of type field: - Bits 2-0 specify the memory type with the following encoding - 0 UC Uncacheable - 1 WC Write Combining - 4 WT Write Through - 5 WP Write Protect - 6 WB Write Back - 7 UC Uncacheable used only in PAT register - Bit 3 WrMem 1 write to memory 0 write to mmio, present only in fixed range MTRRs - Bit 4 RdMem 1 read from memory 0 read from mmio, present only in fixed range MTRRs - Other bits are unused - */ - break; - case 0x201: // MTRRphysMask0-7 - case 0x203: - case 0x205: - case 0x207: - case 0x209: - case 0x20b: - case 0x20d: - case 0x20f: - // 11 Valid - Memory range active - // 39-12 PhyMask27-0 - Address mask - break; - case 0x2ff: // MTRRdefType - // 7-0 MtrrDefMemType - Default memory type - // 10 MtrrDefTypeFixEn - Enable fixed range MTRRs - // 11 MtrrDefTypeEn - Enable MTRRs - break; - case 0x250: // MTRRfix64K_00000 - // 8 bits for each 64k block starting at address 0 - ret = m_msr_mtrrfix[0]; - break; - case 0x258: // MTRRfix16K_80000 - // 8 bits for each 16k block starting at address 0x80000 - ret = m_msr_mtrrfix[1]; - break; - case 0x259: // MTRRfix16K_A0000 - // 8 bits for each 16k block starting at address 0xa0000 - ret = m_msr_mtrrfix[2]; - break; - case 0x268: // MTRRfix4K_C0000 - case 0x269: // MTRRfix4K_C8000 - case 0x26a: // MTRRfix4K_D0000 - case 0x26b: // MTRRfix4K_D8000 - case 0x26c: // MTRRfix4K_E0000 - case 0x26d: // MTRRfix4K_E8000 - case 0x26e: // MTRRfix4K_F0000 - case 0x26f: // MTRRfix4K_F8000 - // 8 bits for each 4k block - ret = m_msr_mtrrfix[3 + offset - 0x268]; - break; - case 0x400: // MC0_CTL - break; - case 0x404: // MC1_CTL - break; - case 0x408: // MC2_CTL - break; - case 0x40c: // MC3_CTL - break; - case 0xC0010010: // SYS_CFG - // 20 MtrrVarDramEn - Enable top of memory address and I/O range registers - // 19 MtrrFixDramModEn - Enable modification of RdDram and WrDram bits in fixed MTRRs - // 18 MtrrFixDramEn - Enable RdDram and WrDram attributes in fixed MTRRs - break; - case 0xC0010015: // HWCR - break; - case 0xC0010016: // IORRBase0-1 - case 0xC0010018: - // 39-12 Base27-0 - Base address for this memory range - // 4 RdDram - Read from DRAM - // 3 WrDram - Write to DRAM - break; - case 0xC0010017: // IORRMask0-1 - case 0xC0010019: - // 39-12 Mask27-0 - Address mask - // 11 V - Register enabled - break; - case 0xC001001A: // TOP_MEM - // 39-23 TOM16-0 - Top of Memory, accesses from this address onward are directed to mmio - break; - case 0xC001001D: // TOP_MEM2 - break; - case 0xC0010113: // SMM_MASK - break; - } - valid_msr = true; - return ret; -} - -void athlonxp_device::opcode_wrmsr(uint64_t data, bool &valid_msr) -{ - uint32_t offset = REG32(ECX); - - switch (offset) - { - case 0x1b: // APIC_BASE - break; - case 0x17b: // MCG_CTL - break; - case 0x200: // MTRRphysBase0-7 - case 0x201: // MTRRphysMask0-7 - case 0x202: - case 0x203: - case 0x204: - case 0x205: - case 0x206: - case 0x207: - case 0x208: - case 0x209: - case 0x20a: - case 0x20b: - case 0x20c: - case 0x20d: - case 0x20e: - case 0x20f: - break; - case 0x2ff: // MTRRdefType - break; - case 0x250: // MTRRfix64K_00000 - m_msr_mtrrfix[0] = data; - parse_mtrrfix(data, 0, 64); - break; - case 0x258: // MTRRfix16K_80000 - m_msr_mtrrfix[1] = data; - parse_mtrrfix(data, 0x80000, 16); - break; - case 0x259: // MTRRfix16K_A0000 - m_msr_mtrrfix[2] = data; - parse_mtrrfix(data, 0xa0000, 16); - break; - case 0x268: // MTRRfix4K_C0000-F8000 - case 0x269: - case 0x26a: - case 0x26b: - case 0x26c: - case 0x26d: - case 0x26e: - case 0x26f: - m_msr_mtrrfix[3 + offset - 0x268] = data; - parse_mtrrfix(data, 0xc0000 + (offset - 0x268) * 0x8000, 4); - break; - case 0x400: // MC0_CTL - break; - case 0x404: // MC1_CTL - break; - case 0x408: // MC2_CTL - break; - case 0x40c: // MC3_CTL - break; - case 0xC0010010: // SYS_CFG - break; - case 0xC0010015: // HWCR - break; - case 0xC0010016: // IORRBase - case 0xC0010017: // IORRMask - case 0xC0010018: - case 0xC0010019: - break; - case 0xC001001A: // TOP_MEM - break; - case 0xC0010113: // SMM_MASK - break; - } - valid_msr = true; -} -#endif diff --git a/source/src/vm/libcpu_newdev/i386/cycles.h b/source/src/vm/libcpu_newdev/i386/cycles.h deleted file mode 100644 index b63997068..000000000 --- a/source/src/vm/libcpu_newdev/i386/cycles.h +++ /dev/null @@ -1,676 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett - -#pragma once - -#ifndef __CYCLES_H__ -#define __CYCLES_H__ - -enum X86_CYCLES -{ - CYCLES_MOV_REG_REG, - CYCLES_MOV_REG_MEM, - CYCLES_MOV_MEM_REG, - CYCLES_MOV_IMM_REG, - CYCLES_MOV_IMM_MEM, - CYCLES_MOV_ACC_MEM, - CYCLES_MOV_MEM_ACC, - CYCLES_MOV_REG_SREG, - CYCLES_MOV_MEM_SREG, - CYCLES_MOV_SREG_REG, - CYCLES_MOV_SREG_MEM, - CYCLES_MOVSX_REG_REG, - CYCLES_MOVSX_MEM_REG, - CYCLES_MOVZX_REG_REG, - CYCLES_MOVZX_MEM_REG, - CYCLES_PUSH_RM, - CYCLES_PUSH_REG_SHORT, - CYCLES_PUSH_SREG, - CYCLES_PUSH_IMM, - CYCLES_PUSHA, - CYCLES_POP_RM, - CYCLES_POP_REG_SHORT, - CYCLES_POP_SREG, - CYCLES_POPA, - CYCLES_XCHG_REG_REG, - CYCLES_XCHG_REG_MEM, - CYCLES_IN, - CYCLES_IN_VAR, - CYCLES_OUT, - CYCLES_OUT_VAR, - CYCLES_LEA, - CYCLES_LDS, - CYCLES_LES, - CYCLES_LFS, - CYCLES_LGS, - CYCLES_LSS, - CYCLES_CLC, - CYCLES_CLD, - CYCLES_CLI, - CYCLES_CLTS, - CYCLES_CMC, - CYCLES_LAHF, - CYCLES_POPF, - CYCLES_PUSHF, - CYCLES_SAHF, - CYCLES_STC, - CYCLES_STD, - CYCLES_STI, - CYCLES_ALU_REG_REG, - CYCLES_ALU_REG_MEM, - CYCLES_ALU_MEM_REG, - CYCLES_ALU_IMM_REG, - CYCLES_ALU_IMM_MEM, - CYCLES_ALU_IMM_ACC, - CYCLES_INC_REG, - CYCLES_INC_MEM, - CYCLES_DEC_REG, - CYCLES_DEC_MEM, - CYCLES_CMP_REG_REG, - CYCLES_CMP_REG_MEM, - CYCLES_CMP_MEM_REG, - CYCLES_CMP_IMM_REG, - CYCLES_CMP_IMM_MEM, - CYCLES_CMP_IMM_ACC, - CYCLES_TEST_REG_REG, - CYCLES_TEST_REG_MEM, - CYCLES_TEST_IMM_REG, - CYCLES_TEST_IMM_MEM, - CYCLES_TEST_IMM_ACC, - CYCLES_NEG_REG, - CYCLES_NEG_MEM, - CYCLES_AAA, - CYCLES_AAS, - CYCLES_DAA, - CYCLES_DAS, - CYCLES_MUL8_ACC_REG, - CYCLES_MUL8_ACC_MEM, - CYCLES_MUL16_ACC_REG, - CYCLES_MUL16_ACC_MEM, - CYCLES_MUL32_ACC_REG, - CYCLES_MUL32_ACC_MEM, - CYCLES_IMUL8_ACC_REG, - CYCLES_IMUL8_ACC_MEM, - CYCLES_IMUL16_ACC_REG, - CYCLES_IMUL16_ACC_MEM, - CYCLES_IMUL32_ACC_REG, - CYCLES_IMUL32_ACC_MEM, - CYCLES_IMUL8_REG_REG, - CYCLES_IMUL8_REG_MEM, - CYCLES_IMUL16_REG_REG, - CYCLES_IMUL16_REG_MEM, - CYCLES_IMUL32_REG_REG, - CYCLES_IMUL32_REG_MEM, - CYCLES_IMUL16_REG_IMM_REG, - CYCLES_IMUL16_MEM_IMM_REG, - CYCLES_IMUL32_REG_IMM_REG, - CYCLES_IMUL32_MEM_IMM_REG, - CYCLES_DIV8_ACC_REG, - CYCLES_DIV8_ACC_MEM, - CYCLES_DIV16_ACC_REG, - CYCLES_DIV16_ACC_MEM, - CYCLES_DIV32_ACC_REG, - CYCLES_DIV32_ACC_MEM, - CYCLES_IDIV8_ACC_REG, - CYCLES_IDIV8_ACC_MEM, - CYCLES_IDIV16_ACC_REG, - CYCLES_IDIV16_ACC_MEM, - CYCLES_IDIV32_ACC_REG, - CYCLES_IDIV32_ACC_MEM, - CYCLES_AAD, - CYCLES_AAM, - CYCLES_CBW, - CYCLES_CWD, - CYCLES_ROTATE_REG, - CYCLES_ROTATE_MEM, - CYCLES_ROTATE_CARRY_REG, - CYCLES_ROTATE_CARRY_MEM, - CYCLES_SHLD_REG, - CYCLES_SHLD_MEM, - CYCLES_SHRD_REG, - CYCLES_SHRD_MEM, - CYCLES_NOT_REG, - CYCLES_NOT_MEM, - CYCLES_CMPS, - CYCLES_INS, - CYCLES_LODS, - CYCLES_MOVS, - CYCLES_OUTS, - CYCLES_SCAS, - CYCLES_STOS, - CYCLES_XLAT, - CYCLES_REP_CMPS_BASE, - CYCLES_REP_INS_BASE, - CYCLES_REP_LODS_BASE, - CYCLES_REP_MOVS_BASE, - CYCLES_REP_OUTS_BASE, - CYCLES_REP_SCAS_BASE, - CYCLES_REP_STOS_BASE, - CYCLES_REP_CMPS, - CYCLES_REP_INS, - CYCLES_REP_LODS, - CYCLES_REP_MOVS, - CYCLES_REP_OUTS, - CYCLES_REP_SCAS, - CYCLES_REP_STOS, - CYCLES_BSF_BASE, - CYCLES_BSF, - CYCLES_BSR_BASE, - CYCLES_BSR, - CYCLES_BT_IMM_REG, - CYCLES_BT_IMM_MEM, - CYCLES_BT_REG_REG, - CYCLES_BT_REG_MEM, - CYCLES_BTC_IMM_REG, - CYCLES_BTC_IMM_MEM, - CYCLES_BTC_REG_REG, - CYCLES_BTC_REG_MEM, - CYCLES_BTR_IMM_REG, - CYCLES_BTR_IMM_MEM, - CYCLES_BTR_REG_REG, - CYCLES_BTR_REG_MEM, - CYCLES_BTS_IMM_REG, - CYCLES_BTS_IMM_MEM, - CYCLES_BTS_REG_REG, - CYCLES_BTS_REG_MEM, - CYCLES_CALL, // E8 - CYCLES_CALL_REG, // FF /2 - CYCLES_CALL_MEM, // FF /2 - CYCLES_CALL_INTERSEG, // 9A - CYCLES_CALL_REG_INTERSEG, // FF /3 - CYCLES_CALL_MEM_INTERSEG, // FF /3 - CYCLES_JMP_SHORT, // EB - CYCLES_JMP, // E9 - CYCLES_JMP_REG, // FF /4 - CYCLES_JMP_MEM, // FF /4 - CYCLES_JMP_INTERSEG, // EA - CYCLES_JMP_REG_INTERSEG, // FF /5 - CYCLES_JMP_MEM_INTERSEG, // FF /5 - CYCLES_RET, // C3 - CYCLES_RET_IMM, // C2 - CYCLES_RET_INTERSEG, // CB - CYCLES_RET_IMM_INTERSEG, // CA - CYCLES_JCC_DISP8, - CYCLES_JCC_FULL_DISP, - CYCLES_JCC_DISP8_NOBRANCH, - CYCLES_JCC_FULL_DISP_NOBRANCH, - CYCLES_JCXZ, - CYCLES_JCXZ_NOBRANCH, - CYCLES_LOOP, - CYCLES_LOOPZ, - CYCLES_LOOPNZ, - CYCLES_SETCC_REG, - CYCLES_SETCC_MEM, - CYCLES_ENTER, - CYCLES_LEAVE, - CYCLES_INT, - CYCLES_INT3, - CYCLES_INTO_OF1, - CYCLES_INTO_OF0, - CYCLES_BOUND_IN_RANGE, - CYCLES_BOUND_OUT_RANGE, - CYCLES_IRET, - CYCLES_HLT, - CYCLES_MOV_REG_CR0, - CYCLES_MOV_REG_CR2, - CYCLES_MOV_REG_CR3, - CYCLES_MOV_CR_REG, - CYCLES_MOV_REG_DR0_3, - CYCLES_MOV_REG_DR6_7, - CYCLES_MOV_DR6_7_REG, - CYCLES_MOV_DR0_3_REG, - CYCLES_MOV_REG_TR6_7, - CYCLES_MOV_TR6_7_REG, - CYCLES_NOP, - CYCLES_WAIT, - CYCLES_ARPL_REG, - CYCLES_ARPL_MEM, - CYCLES_LAR_REG, - CYCLES_LAR_MEM, - CYCLES_LGDT, - CYCLES_LIDT, - CYCLES_LLDT_REG, - CYCLES_LLDT_MEM, - CYCLES_LMSW_REG, - CYCLES_LMSW_MEM, - CYCLES_LSL_REG, - CYCLES_LSL_MEM, - CYCLES_LTR_REG, - CYCLES_LTR_MEM, - CYCLES_SGDT, - CYCLES_SIDT, - CYCLES_SLDT_REG, - CYCLES_SLDT_MEM, - CYCLES_SMSW_REG, - CYCLES_SMSW_MEM, - CYCLES_STR_REG, - CYCLES_STR_MEM, - CYCLES_VERR_REG, - CYCLES_VERR_MEM, - CYCLES_VERW_REG, - CYCLES_VERW_MEM, - CYCLES_LOCK, - - CYCLES_BSWAP, - CYCLES_CMPXCHG8B, - CYCLES_CMPXCHG, - CYCLES_CPUID, - CYCLES_CPUID_EAX1, - CYCLES_INVD, - CYCLES_XADD, - CYCLES_RDTSC, - CYCLES_RSM, - CYCLES_RDMSR, - - CYCLES_FABS, - CYCLES_FADD, - CYCLES_FBLD, - CYCLES_FBSTP, - CYCLES_FCHS, - CYCLES_FCLEX, - CYCLES_FCOM, - CYCLES_FCOS, - CYCLES_FDECSTP, - CYCLES_FDISI, - CYCLES_FDIV, - CYCLES_FDIVR, - CYCLES_FENI, - CYCLES_FFREE, - CYCLES_FIADD, - CYCLES_FICOM, - CYCLES_FIDIV, - CYCLES_FILD, - CYCLES_FIMUL, - CYCLES_FINCSTP, - CYCLES_FINIT, - CYCLES_FIST, - CYCLES_FISUB, - CYCLES_FLD, - CYCLES_FLDZ, - CYCLES_FLD1, - CYCLES_FLDL2E, - CYCLES_FLDL2T, - CYCLES_FLDLG2, - CYCLES_FLDLN2, - CYCLES_FLDPI, - CYCLES_FLDCW, - CYCLES_FLDENV, - CYCLES_FMUL, - CYCLES_FNOP, - CYCLES_FPATAN, - CYCLES_FPREM, - CYCLES_FPREM1, - CYCLES_FPTAN, - CYCLES_FRNDINT, - CYCLES_FRSTOR, - CYCLES_FSAVE, - CYCLES_FSCALE, - CYCLES_FSETPM, - CYCLES_FSIN, - CYCLES_FSINCOS, - CYCLES_FSQRT, - CYCLES_FST, - CYCLES_FSTCW, - CYCLES_FSTENV, - CYCLES_FSTSW, - CYCLES_FSUB, - CYCLES_FSUBR, - CYCLES_FTST, - CYCLES_FUCOM, - CYCLES_FXAM, - CYCLES_FXCH, - CYCLES_FXTRACT, - CYCLES_FYL2X, - CYCLES_FYL2XPI, - CYCLES_CMPXCHG_REG_REG_T, - CYCLES_CMPXCHG_REG_REG_F, - CYCLES_CMPXCHG_REG_MEM_T, - CYCLES_CMPXCHG_REG_MEM_F, - CYCLES_XADD_REG_REG, - CYCLES_XADD_REG_MEM, - - CYCLES_NUM_OPCODES -}; - - -#define CPU_CYCLES_I386 0 -#define CPU_CYCLES_I486 1 -#define CPU_CYCLES_PENTIUM 2 -#define CPU_CYCLES_MEDIAGX 3 - - -struct X86_CYCLE_TABLE -{ - X86_CYCLES op; - uint8_t cpu_cycles[X86_NUM_CPUS][2]; -}; - -static const X86_CYCLE_TABLE x86_cycle_table[] = -{ - // opcode rm/pmode - // i386 i486 pentium mediagx - { CYCLES_MOV_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_MOV_REG_MEM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_MOV_MEM_REG, { { 4, 4 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_MOV_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_MOV_IMM_MEM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_MOV_ACC_MEM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_MOV_MEM_ACC, { { 4, 4 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_MOV_REG_SREG, { { 2, 18 }, { 3, 3 }, { 2, 2 }, { 1, 6 } } }, - { CYCLES_MOV_MEM_SREG, { { 5, 19 }, { 9, 9 }, { 3, 3 }, { 1, 6 } } }, - { CYCLES_MOV_SREG_REG, { { 2, 2 }, { 3, 3 }, { 1, 1 }, { 1, 6 } } }, - { CYCLES_MOV_SREG_MEM, { { 2, 2 }, { 3, 3 }, { 1, 1 }, { 1, 6 } } }, - { CYCLES_MOVSX_REG_REG, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_MOVSX_MEM_REG, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_MOVZX_REG_REG, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_MOVZX_MEM_REG, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_PUSH_RM, { { 5, 5 }, { 4, 4 }, { 2, 2 }, { 3, 3 } } }, - { CYCLES_PUSH_REG_SHORT, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_PUSH_SREG, { { 2, 2 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_PUSH_IMM, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_PUSHA, { { 18, 18 }, { 11, 11 }, { 5, 5 }, { 11, 11 } } }, - { CYCLES_POP_RM, { { 5, 5 }, { 4, 4 }, { 3, 3 }, { 4, 4 } } }, - { CYCLES_POP_REG_SHORT, { { 4, 4 }, { 4, 4 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_POP_SREG, { { 7, 21 }, { 3, 3 }, { 3, 3 }, { 1, 6 } } }, - { CYCLES_POPA, { { 24, 24 }, { 9, 9 }, { 5, 5 }, { 9, 9 } } }, - { CYCLES_XCHG_REG_REG, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_XCHG_REG_MEM, { { 5, 5 }, { 5, 5 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_IN, { { 12, 26 }, { 14, 27 }, { 7, 19 }, { 8, 8 } } }, - { CYCLES_IN_VAR, { { 13, 27 }, { 14, 27 }, { 7, 19 }, { 8, 8 } } }, - { CYCLES_OUT, { { 10, 24 }, { 16, 29 }, { 12, 24 }, { 14, 14 } } }, - { CYCLES_OUT_VAR, { { 11, 25 }, { 16, 29 }, { 12, 24 }, { 14, 14 } } }, - { CYCLES_LEA, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_LDS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } }, - { CYCLES_LES, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } }, - { CYCLES_LFS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } }, - { CYCLES_LGS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 9 } } }, - { CYCLES_LSS, { { 7, 22 }, { 6, 12 }, { 4, 4 }, { 4, 10 } } }, - { CYCLES_CLC, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_CLD, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 4, 4 } } }, - { CYCLES_CLI, { { 8, 8 }, { 5, 5 }, { 7, 7 }, { 6, 6 } } }, - { CYCLES_CLTS, { { 6, 6 }, { 7, 7 }, { 10, 10 }, { 7, 7 } } }, - { CYCLES_CMC, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 3, 3 } } }, - { CYCLES_LAHF, { { 2, 2 }, { 3, 3 }, { 2, 2 }, { 2, 2 } } }, - { CYCLES_POPF, { { 5, 5 }, { 9, 9 }, { 6, 6 }, { 8, 8 } } }, - { CYCLES_PUSHF, { { 4, 4 }, { 4, 4 }, { 9, 9 }, { 2, 2 } } }, - { CYCLES_SAHF, { { 3, 3 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_STC, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_STD, { { 2, 2 }, { 2, 2 }, { 2, 2 }, { 4, 4 } } }, - { CYCLES_STI, { { 8, 8 }, { 5, 5 }, { 7, 7 }, { 6, 6 } } }, - { CYCLES_ALU_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_ALU_REG_MEM, { { 7, 7 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_ALU_MEM_REG, { { 6, 6 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_ALU_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_ALU_IMM_MEM, { { 7, 7 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_ALU_IMM_ACC, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_INC_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_INC_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_DEC_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_DEC_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_CMP_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_CMP_REG_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_CMP_MEM_REG, { { 6, 6 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_CMP_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_CMP_IMM_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_CMP_IMM_ACC, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_TEST_REG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_TEST_REG_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_TEST_IMM_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_TEST_IMM_MEM, { { 5, 5 }, { 2, 2 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_TEST_IMM_ACC, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_NEG_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_NEG_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_AAA, { { 4, 4 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } }, - { CYCLES_AAS, { { 4, 4 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } }, - { CYCLES_DAA, { { 4, 4 }, { 2, 2 }, { 3, 3 }, { 2, 2 } } }, - { CYCLES_DAS, { { 4, 4 }, { 2, 2 }, { 3, 3 }, { 2, 2 } } }, - { CYCLES_MUL8_ACC_REG, { { 17, 17 }, { 13, 13 }, { 11, 11 }, { 4, 4 } } }, - { CYCLES_MUL8_ACC_MEM, { { 20, 20 }, { 13, 13 }, { 11, 11 }, { 4, 4 } } }, - { CYCLES_MUL16_ACC_REG, { { 25, 25 }, { 13, 13 }, { 11, 11 }, { 5, 5 } } }, - { CYCLES_MUL16_ACC_MEM, { { 28, 28 }, { 13, 13 }, { 11, 11 }, { 5, 5 } } }, - { CYCLES_MUL32_ACC_REG, { { 41, 41 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } }, - { CYCLES_MUL32_ACC_MEM, { { 44, 44 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } }, - { CYCLES_IMUL8_ACC_REG, { { 17, 17 }, { 18, 18 }, { 11, 11 }, { 4, 4 } } }, - { CYCLES_IMUL8_ACC_MEM, { { 20, 20 }, { 18, 18 }, { 11, 11 }, { 4, 4 } } }, - { CYCLES_IMUL16_ACC_REG, { { 25, 25 }, { 26, 26 }, { 11, 11 }, { 5, 5 } } }, - { CYCLES_IMUL16_ACC_MEM, { { 28, 28 }, { 26, 26 }, { 11, 11 }, { 5, 5 } } }, - { CYCLES_IMUL32_ACC_REG, { { 41, 41 }, { 42, 42 }, { 10, 10 }, { 15, 15 } } }, - { CYCLES_IMUL32_ACC_MEM, { { 44, 44 }, { 42, 42 }, { 10, 10 }, { 15, 15 } } }, - { CYCLES_IMUL8_REG_REG, { { 17, 17 }, { 13, 13 }, { 10, 10 }, { 4, 4 } } }, - { CYCLES_IMUL8_REG_MEM, { { 20, 20 }, { 13, 13 }, { 10, 10 }, { 4, 4 } } }, - { CYCLES_IMUL16_REG_REG, { { 25, 25 }, { 13, 13 }, { 10, 10 }, { 5, 5 } } }, - { CYCLES_IMUL16_REG_MEM, { { 28, 28 }, { 13, 13 }, { 10, 10 }, { 5, 5 } } }, - { CYCLES_IMUL32_REG_REG, { { 41, 41 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } }, - { CYCLES_IMUL32_REG_MEM, { { 44, 44 }, { 13, 13 }, { 10, 10 }, { 15, 15 } } }, - { CYCLES_IMUL16_REG_IMM_REG,{ { 26, 26 }, { 26, 26 }, { 10, 10 }, { 6, 6 } } }, - { CYCLES_IMUL16_MEM_IMM_REG,{ { 27, 27 }, { 26, 26 }, { 10, 10 }, { 6, 6 } } }, - { CYCLES_IMUL32_REG_IMM_REG,{ { 42, 42 }, { 42, 42 }, { 10, 10 }, { 16, 16 } } }, - { CYCLES_IMUL32_MEM_IMM_REG,{ { 43, 43 }, { 42, 42 }, { 10, 10 }, { 16, 16 } } }, - { CYCLES_DIV8_ACC_REG, { { 14, 14 }, { 16, 16 }, { 17, 17 }, { 20, 20 } } }, - { CYCLES_DIV8_ACC_MEM, { { 17, 17 }, { 16, 16 }, { 17, 17 }, { 20, 20 } } }, - { CYCLES_DIV16_ACC_REG, { { 22, 22 }, { 24, 24 }, { 25, 25 }, { 29, 29 } } }, - { CYCLES_DIV16_ACC_MEM, { { 25, 25 }, { 24, 24 }, { 25, 25 }, { 29, 29 } } }, - { CYCLES_DIV32_ACC_REG, { { 38, 38 }, { 40, 40 }, { 41, 41 }, { 45, 45 } } }, - { CYCLES_DIV32_ACC_MEM, { { 41, 41 }, { 40, 40 }, { 41, 41 }, { 45, 45 } } }, - { CYCLES_IDIV8_ACC_REG, { { 19, 19 }, { 19, 19 }, { 22, 22 }, { 20, 20 } } }, - { CYCLES_IDIV8_ACC_MEM, { { 22, 22 }, { 20, 20 }, { 22, 22 }, { 20, 20 } } }, - { CYCLES_IDIV16_ACC_REG, { { 27, 27 }, { 27, 27 }, { 30, 30 }, { 29, 29 } } }, - { CYCLES_IDIV16_ACC_MEM, { { 30, 30 }, { 28, 28 }, { 30, 30 }, { 29, 29 } } }, - { CYCLES_IDIV32_ACC_REG, { { 43, 43 }, { 43, 43 }, { 46, 46 }, { 45, 45 } } }, - { CYCLES_IDIV32_ACC_MEM, { { 46, 46 }, { 44, 44 }, { 46, 46 }, { 45, 45 } } }, - { CYCLES_AAD, { { 19, 19 }, { 14, 14 }, { 10, 10 }, { 7, 7 } } }, - { CYCLES_AAM, { { 17, 17 }, { 15, 15 }, { 18, 18 }, { 19, 19 } } }, - { CYCLES_CBW, { { 3, 3 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } }, - { CYCLES_CWD, { { 2, 2 }, { 3, 3 }, { 2, 2 }, { 2, 2 } } }, - { CYCLES_ROTATE_REG, { { 3, 3 }, { 3, 3 }, { 1, 1 }, { 2, 2 } } }, - { CYCLES_ROTATE_MEM, { { 7, 7 }, { 4, 4 }, { 3, 3 }, { 2, 2 } } }, - { CYCLES_ROTATE_CARRY_REG, { { 9, 9 }, { 8, 8 }, { 7, 7 }, { 8, 8 } } }, - { CYCLES_ROTATE_CARRY_MEM, { { 10, 10 }, { 9, 9 }, { 8, 8 }, { 8, 8 } } }, - { CYCLES_SHLD_REG, { { 3, 3 }, { 2, 2 }, { 4, 4 }, { 3, 3 } } }, - { CYCLES_SHLD_MEM, { { 7, 7 }, { 3, 3 }, { 4, 4 }, { 6, 6 } } }, - { CYCLES_SHRD_REG, { { 3, 3 }, { 2, 2 }, { 4, 4 }, { 3, 3 } } }, - { CYCLES_SHRD_MEM, { { 7, 7 }, { 3, 3 }, { 4, 4 }, { 6, 6 } } }, - { CYCLES_NOT_REG, { { 2, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_NOT_MEM, { { 6, 6 }, { 3, 3 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_CMPS, { { 10, 10 }, { 8, 8 }, { 5, 5 }, { 6, 6 } } }, - { CYCLES_INS, { { 15, 29 }, { 17, 30 }, { 9, 22 }, { 11, 11 } } }, - { CYCLES_LODS, { { 5, 5 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } }, - { CYCLES_MOVS, { { 8, 8 }, { 7, 7 }, { 4, 4 }, { 6, 6 } } }, - { CYCLES_OUTS, { { 14, 28 }, { 17, 30 }, { 13, 25 }, { 15, 15 } } }, - { CYCLES_SCAS, { { 8, 8 }, { 6, 6 }, { 4, 4 }, { 2, 2 } } }, - { CYCLES_STOS, { { 5, 5 }, { 5, 5 }, { 3, 3 }, { 2, 2 } } }, - { CYCLES_XLAT, { { 5, 5 }, { 4, 4 }, { 4, 4 }, { 5, 5 } } }, - { CYCLES_REP_CMPS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 11, 11 } } }, - { CYCLES_REP_INS_BASE, { { 14, 8 }, { 0, 0 }, { 0, 0 }, { 17, 17 } } }, - { CYCLES_REP_LODS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 9, 9 } } }, - { CYCLES_REP_MOVS_BASE, { { 8, 8 }, { 0, 0 }, { 0, 0 }, { 12, 12 } } }, - { CYCLES_REP_OUTS_BASE, { { 12, 6 }, { 0, 0 }, { 0, 0 }, { 24, 24 } } }, - { CYCLES_REP_SCAS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 9, 9 } } }, - { CYCLES_REP_STOS_BASE, { { 5, 5 }, { 0, 0 }, { 0, 0 }, { 9, 9 } } }, - { CYCLES_REP_CMPS, { { 5, 5 }, { 8, 8 }, { 5, 5 }, { 4, 4 } } }, - { CYCLES_REP_INS, { { 14, 8 }, { 17, 30 }, { 9, 22 }, { 4, 4 } } }, - { CYCLES_REP_LODS, { { 5, 5 }, { 5, 5 }, { 2, 2 }, { 2, 2 } } }, - { CYCLES_REP_MOVS, { { 8, 8 }, { 7, 7 }, { 4, 4 }, { 2, 2 } } }, - { CYCLES_REP_OUTS, { { 12, 6 }, { 17, 30 }, { 13, 25 }, { 4, 4 } } }, - { CYCLES_REP_SCAS, { { 5, 5 }, { 6, 6 }, { 4, 4 }, { 3, 3 } } }, - { CYCLES_REP_STOS, { { 5, 5 }, { 5, 5 }, { 3, 3 }, { 2, 2 } } }, - { CYCLES_BSF_BASE, { { 11, 11 }, { 6, 6 }, { 6, 6 }, { 4, 4 } } }, - { CYCLES_BSF, { { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_BSR_BASE, { { 9, 9 }, { 6, 6 }, { 7, 7 }, { 4, 4 } } }, - { CYCLES_BSR, { { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_BT_IMM_REG, { { 3, 3 }, { 3, 3 }, { 4, 4 }, { 1, 1 } } }, - { CYCLES_BT_IMM_MEM, { { 6, 6 }, { 6, 6 }, { 4, 4 }, { 1, 1 } } }, - { CYCLES_BT_REG_REG, { { 3, 3 }, { 3, 3 }, { 4, 4 }, { 1, 1 } } }, - { CYCLES_BT_REG_MEM, { { 12, 12 }, { 12, 12 }, { 9, 9 }, { 7, 7 } } }, - { CYCLES_BTC_IMM_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } }, - { CYCLES_BTC_IMM_MEM, { { 8, 8 }, { 8, 8 }, { 8, 8 }, { 2, 2 } } }, - { CYCLES_BTC_REG_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } }, - { CYCLES_BTC_REG_MEM, { { 13, 13 }, { 13, 13 }, { 13, 13 }, { 8, 8 } } }, - { CYCLES_BTR_IMM_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } }, - { CYCLES_BTR_IMM_MEM, { { 8, 8 }, { 8, 8 }, { 8, 8 }, { 2, 2 } } }, - { CYCLES_BTR_REG_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } }, - { CYCLES_BTR_REG_MEM, { { 13, 13 }, { 13, 13 }, { 13, 13 }, { 8, 8 } } }, - { CYCLES_BTS_IMM_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } }, - { CYCLES_BTS_IMM_MEM, { { 8, 8 }, { 8, 8 }, { 8, 8 }, { 2, 2 } } }, - { CYCLES_BTS_REG_REG, { { 6, 6 }, { 6, 6 }, { 7, 7 }, { 2, 2 } } }, - { CYCLES_BTS_REG_MEM, { { 13, 13 }, { 13, 13 }, { 13, 13 }, { 8, 8 } } }, - { CYCLES_CALL, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 3, 3 } } }, - { CYCLES_CALL_REG, { { 7, 7 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } }, - { CYCLES_CALL_MEM, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 4, 4 } } }, - { CYCLES_CALL_INTERSEG, { { 17, 34 }, { 18, 20 }, { 4, 13 }, { 9, 14 } } }, - { CYCLES_CALL_REG_INTERSEG, { { 22, 38 }, { 17, 20 }, { 4, 14 }, { 11, 15 } } }, - { CYCLES_CALL_MEM_INTERSEG, { { 22, 38 }, { 17, 20 }, { 4, 14 }, { 11, 15 } } }, - { CYCLES_JMP_SHORT, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_JMP, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_JMP_REG, { { 7, 7 }, { 5, 5 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_JMP_MEM, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } }, - { CYCLES_JMP_INTERSEG, { { 12, 27 }, { 17, 19 }, { 3, 3 }, { 8, 12 } } }, - { CYCLES_JMP_REG_INTERSEG, { { 17, 31 }, { 13, 18 }, { 4, 4 }, { 10, 10 } } }, - { CYCLES_JMP_MEM_INTERSEG, { { 17, 31 }, { 13, 18 }, { 4, 4 }, { 10, 13 } } }, - { CYCLES_RET, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } }, - { CYCLES_RET_IMM, { { 10, 10 }, { 5, 5 }, { 2, 2 }, { 3, 3 } } }, - { CYCLES_RET_INTERSEG, { { 18, 32 }, { 13, 13 }, { 4, 4 }, { 10, 13 } } }, - { CYCLES_RET_IMM_INTERSEG, { { 18, 32 }, { 14, 14 }, { 4, 4 }, { 10, 13 } } }, - { CYCLES_JCC_DISP8, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_JCC_FULL_DISP, { { 7, 7 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_JCC_DISP8_NOBRANCH,{ { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_JCC_FULL_DISP_NOBRANCH,{ { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_JCXZ, { { 9, 9 }, { 1, 1 }, { 1, 1 }, { 2, 2 } } }, - { CYCLES_JCXZ_NOBRANCH, { { 5, 5 }, { 1, 1 }, { 1, 1 }, { 2, 2 } } }, - { CYCLES_LOOP, { { 11, 11 }, { 6, 6 }, { 5, 5 }, { 2, 2 } } }, - { CYCLES_LOOPZ, { { 11, 11 }, { 9, 9 }, { 8, 8 }, { 2, 2 } } }, - { CYCLES_LOOPNZ, { { 11, 11 }, { 9, 9 }, { 8, 8 }, { 2, 2 } } }, - { CYCLES_SETCC_REG, { { 4, 4 }, { 3, 3 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_SETCC_MEM, { { 5, 5 }, { 4, 4 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_ENTER, { { 10, 10 }, { 14, 14 }, { 11, 11 }, { 13, 13 } } }, - { CYCLES_LEAVE, { { 4, 4 }, { 5, 5 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_INT, { { 37, 37 }, { 30, 30 }, { 16, 16 }, { 19, 19 } } }, - { CYCLES_INT3, { { 33, 33 }, { 26, 26 }, { 13, 13 }, { 19, 19 } } }, - { CYCLES_INTO_OF1, { { 35, 35 }, { 28, 28 }, { 13, 13 }, { 19, 19 } } }, - { CYCLES_INTO_OF0, { { 3, 3 }, { 3, 3 }, { 4, 4 }, { 4, 4 } } }, - { CYCLES_BOUND_IN_RANGE, { { 10, 10 }, { 7, 7 }, { 8, 8 }, { 7, 7 } } }, - { CYCLES_BOUND_OUT_RANGE, { { 44, 44 }, { 7, 7 }, { 8, 8 }, { 8, 8 } } }, - { CYCLES_IRET, { { 22, 22 }, { 15, 15 }, { 8, 8 }, { 13, 13 } } }, - { CYCLES_HLT, { { 5, 5 }, { 4, 4 }, { 4, 4 }, { 10, 10 } } }, - { CYCLES_MOV_REG_CR0, { { 11, 11 }, { 16, 16 }, { 16, 16 }, { 20, 18 } } }, - { CYCLES_MOV_REG_CR2, { { 4, 4 }, { 4, 4 }, { 4, 4 }, { 5, 5 } } }, - { CYCLES_MOV_REG_CR3, { { 5, 5 }, { 4, 4 }, { 4, 4 }, { 5, 6 } } }, - { CYCLES_MOV_CR_REG, { { 6, 6 }, { 4, 4 }, { 4, 4 }, { 6, 6 } } }, - { CYCLES_MOV_REG_DR0_3, { { 22, 22 }, { 10, 10 }, { 10, 10 }, { 10, 10 } } }, - { CYCLES_MOV_REG_DR6_7, { { 16, 16 }, { 10, 10 }, { 10, 10 }, { 10, 10 } } }, - { CYCLES_MOV_DR6_7_REG, { { 14, 14 }, { 11, 11 }, { 11, 11 }, { 9, 9 } } }, - { CYCLES_MOV_DR0_3_REG, { { 22, 22 }, { 11, 11 }, { 11, 11 }, { 9, 9 } } }, - { CYCLES_MOV_REG_TR6_7, { { 12, 12 }, { 4, 4 }, { 4, 4 }, { 11, 11 } } }, - { CYCLES_MOV_TR6_7_REG, { { 12, 12 }, { 3, 3 }, { 3, 3 }, { 3, 3 } } }, - { CYCLES_NOP, { { 3, 3 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_WAIT, { { 7, 7 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_ARPL_REG, { { 0, 20 }, { 0, 9 }, { 0, 7 }, { 0, 9 } } }, - { CYCLES_ARPL_MEM, { { 0, 21 }, { 0, 9 }, { 0, 7 }, { 0, 9 } } }, - { CYCLES_LAR_REG, { { 0, 15 }, { 11, 11 }, { 8, 8 }, { 0, 9 } } }, - { CYCLES_LAR_MEM, { { 0, 16 }, { 11, 11 }, { 8, 8 }, { 0, 9 } } }, - { CYCLES_LGDT, { { 11, 11 }, { 11, 11 }, { 6, 6 }, { 10, 10 } } }, - { CYCLES_LIDT, { { 11, 11 }, { 11, 11 }, { 6, 6 }, { 10, 10 } } }, - { CYCLES_LLDT_REG, { { 0, 20 }, { 11, 11 }, { 9, 9 }, { 0, 8 } } }, - { CYCLES_LLDT_MEM, { { 0, 24 }, { 11, 11 }, { 9, 9 }, { 0, 8 } } }, - { CYCLES_LMSW_REG, { { 11, 11 }, { 13, 13 }, { 8, 8 }, { 11, 11 } } }, - { CYCLES_LMSW_MEM, { { 14, 14 }, { 13, 13 }, { 8, 8 }, { 11, 11 } } }, - { CYCLES_LSL_REG, { { 0, 21 }, { 10, 10 }, { 8, 8 }, { 0, 9 } } }, - { CYCLES_LSL_MEM, { { 0, 22 }, { 10, 10 }, { 8, 8 }, { 0, 9 } } }, - { CYCLES_LTR_REG, { { 0, 23 }, { 20, 20 }, { 10, 10 }, { 0, 9 } } }, - { CYCLES_LTR_MEM, { { 0, 27 }, { 20, 20 }, { 10, 10 }, { 0, 9 } } }, - { CYCLES_SGDT, { { 9, 9 }, { 10, 10 }, { 4, 4 }, { 6, 6 } } }, - { CYCLES_SIDT, { { 9, 9 }, { 10, 10 }, { 4, 4 }, { 6, 6 } } }, - { CYCLES_SLDT_REG, { { 0, 2 }, { 2, 2 }, { 2, 2 }, { 0, 1 } } }, - { CYCLES_SLDT_MEM, { { 0, 2 }, { 3, 3 }, { 2, 2 }, { 0, 1 } } }, - { CYCLES_SMSW_REG, { { 2, 2 }, { 2, 2 }, { 4, 4 }, { 4, 4 } } }, - { CYCLES_SMSW_MEM, { { 2, 2 }, { 3, 3 }, { 4, 4 }, { 4, 4 } } }, - { CYCLES_STR_REG, { { 0, 2 }, { 2, 2 }, { 2, 2 }, { 0, 3 } } }, - { CYCLES_STR_MEM, { { 0, 2 }, { 3, 3 }, { 2, 2 }, { 0, 3 } } }, - { CYCLES_VERR_REG, { { 0, 10 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } }, - { CYCLES_VERR_MEM, { { 0, 11 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } }, - { CYCLES_VERW_REG, { { 0, 15 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } }, - { CYCLES_VERW_MEM, { { 0, 16 }, { 11, 11 }, { 7, 7 }, { 0, 8 } } }, - { CYCLES_LOCK, { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 1, 1 } } }, - - // i486+ - { CYCLES_BSWAP, { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 6, 6 } } }, - { CYCLES_CMPXCHG, { { 0, 0 }, { 6, 6 }, { 5, 5 }, { 6, 6 } } }, - { CYCLES_INVD, { { 0, 0 }, { 4, 4 }, { 15, 15 }, { 20, 20 } } }, - { CYCLES_XADD, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 2, 2 } } }, - - // Pentium+ - { CYCLES_CMPXCHG8B, { { 0, 0 }, { 0, 0 }, { 10, 10 }, { 6, 6 } } }, - { CYCLES_CPUID, { { 0, 0 }, { 0, 0 }, { 14, 14 }, { 12, 12 } } }, - { CYCLES_CPUID_EAX1, { { 0, 0 }, { 0, 0 }, { 14, 14 }, { 12, 12 } } }, - { CYCLES_RDTSC, { { 0, 0 }, { 0, 0 }, { 20, 20 }, { 1, 1 } } }, - { CYCLES_RSM, { { 0, 0 }, { 0, 0 }, { 82, 82 }, { 57, 57 } } }, - { CYCLES_RDMSR, { { 0, 0 }, { 0, 0 }, { 20, 20 }, { 1, 1 } } }, - - // FPU - { CYCLES_FABS, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FADD, { { 0, 0 }, { 8, 8 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_FBLD, { { 0, 0 }, { 70, 70 }, { 48, 48 }, { 1, 1 } } }, - { CYCLES_FBSTP, { { 0, 0 }, {172,172 }, {148,148 }, { 1, 1 } } }, - { CYCLES_FCHS, { { 0, 0 }, { 6, 6 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FCLEX, { { 0, 0 }, { 7, 7 }, { 9, 9 }, { 1, 1 } } }, - { CYCLES_FCOM, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 1, 1 } } }, - { CYCLES_FCOS, { { 0, 0 }, {255,255 }, {124,124 }, { 1, 1 } } }, - { CYCLES_FDECSTP, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FDISI, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FDIV, { { 0, 0 }, { 73, 73 }, { 39, 39 }, { 1, 1 } } }, - { CYCLES_FDIVR, { { 0, 0 }, { 73, 73 }, { 39, 39 }, { 1, 1 } } }, - { CYCLES_FENI, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FFREE, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FIADD, { { 0, 0 }, { 20, 20 }, { 7, 7 }, { 1, 1 } } }, - { CYCLES_FICOM, { { 0, 0 }, { 16, 16 }, { 8, 8 }, { 1, 1 } } }, - { CYCLES_FIDIV, { { 0, 0 }, { 85, 85 }, { 42, 42 }, { 1, 1 } } }, - { CYCLES_FILD, { { 0, 0 }, { 13, 13 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_FIMUL, { { 0, 0 }, { 23, 23 }, { 7, 7 }, { 1, 1 } } }, - { CYCLES_FINCSTP, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FINIT, { { 0, 0 }, { 17, 17 }, { 16, 16 }, { 1, 1 } } }, - { CYCLES_FIST, { { 0, 0 }, { 29, 29 }, { 6, 6 }, { 1, 1 } } }, - { CYCLES_FISUB, { { 0, 0 }, { 20, 20 }, { 7, 7 }, { 1, 1 } } }, - { CYCLES_FLD, { { 0, 0 }, { 4, 4 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FLDZ, { { 0, 0 }, { 4, 4 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_FLD1, { { 0, 0 }, { 4, 4 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_FLDL2E, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } }, - { CYCLES_FLDL2T, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } }, - { CYCLES_FLDLG2, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } }, - { CYCLES_FLDLN2, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } }, - { CYCLES_FLDPI, { { 0, 0 }, { 8, 8 }, { 5, 5 }, { 1, 1 } } }, - { CYCLES_FLDCW, { { 0, 0 }, { 4, 4 }, { 7, 7 }, { 1, 1 } } }, - { CYCLES_FLDENV, { { 0, 0 }, { 44, 44 }, { 37, 37 }, { 1, 1 } } }, - { CYCLES_FMUL, { { 0, 0 }, { 16, 16 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_FNOP, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FPATAN, { { 0, 0 }, {218,218 }, {173,173 }, { 1, 1 } } }, - { CYCLES_FPREM, { { 0, 0 }, { 70, 70 }, { 16, 16 }, { 1, 1 } } }, - { CYCLES_FPREM1, { { 0, 0 }, { 72, 72 }, { 20, 20 }, { 1, 1 } } }, - { CYCLES_FPTAN, { { 0, 0 }, {200,200 }, {173,173 }, { 1, 1 } } }, - { CYCLES_FRNDINT, { { 0, 0 }, { 21, 21 }, { 9, 9 }, { 1, 1 } } }, - { CYCLES_FRSTOR, { { 0, 0 }, {131,131 }, { 75, 75 }, { 1, 1 } } }, - { CYCLES_FSAVE, { { 0, 0 }, {154,154 }, {127,127 }, { 1, 1 } } }, - { CYCLES_FSCALE, { { 0, 0 }, { 30, 30 }, { 20, 20 }, { 1, 1 } } }, - { CYCLES_FSETPM, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FSIN, { { 0, 0 }, {255,255 }, {126,126 }, { 1, 1 } } }, - { CYCLES_FSINCOS, { { 0, 0 }, {255,255 }, {137,137 }, { 1, 1 } } }, - { CYCLES_FSQRT, { { 0, 0 }, { 83, 83 }, { 70, 70 }, { 1, 1 } } }, - { CYCLES_FST, { { 0, 0 }, { 3, 3 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FSTCW, { { 0, 0 }, { 3, 3 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_FSTENV, { { 0, 0 }, { 67, 67 }, { 48, 48 }, { 1, 1 } } }, - { CYCLES_FSTSW, { { 0, 0 }, { 3, 3 }, { 2, 2 }, { 1, 1 } } }, - { CYCLES_FSUB, { { 0, 0 }, { 8, 8 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_FSUBR, { { 0, 0 }, { 8, 8 }, { 3, 3 }, { 1, 1 } } }, - { CYCLES_FTST, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 1, 1 } } }, - { CYCLES_FUCOM, { { 0, 0 }, { 4, 4 }, { 4, 4 }, { 1, 1 } } }, - { CYCLES_FXAM, { { 0, 0 }, { 8, 8 }, { 21, 21 }, { 1, 1 } } }, - { CYCLES_FXCH, { { 0, 0 }, { 4, 4 }, { 1, 1 }, { 1, 1 } } }, - { CYCLES_FXTRACT, { { 0, 0 }, { 16, 16 }, { 13, 13 }, { 1, 1 } } }, - { CYCLES_FYL2X, { { 0, 0 }, {196,196 }, {111,111 }, { 1, 1 } } }, - { CYCLES_FYL2XPI, { { 0, 0 }, {171,171 }, {103,103 }, { 1, 1 } } }, - { CYCLES_CMPXCHG_REG_REG_T, { { 0, 0 }, { 6, 6 }, { 6, 6 }, { 6, 6 } } }, - { CYCLES_CMPXCHG_REG_REG_F, { { 0, 0 }, { 9, 9 }, { 9, 9 }, { 9, 9 } } }, - { CYCLES_CMPXCHG_REG_MEM_T, { { 0, 0 }, { 7, 7 }, { 7, 7 }, { 7, 7 } } }, - { CYCLES_CMPXCHG_REG_MEM_F, { { 0, 0 }, { 10, 10 }, { 10, 10 }, { 10, 10 } } }, -}; - -#endif /* __CYCLES_H__ */ diff --git a/source/src/vm/libcpu_newdev/i386/i386_device.cpp b/source/src/vm/libcpu_newdev/i386/i386_device.cpp deleted file mode 100644 index e8ecfe378..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386_device.cpp +++ /dev/null @@ -1,5612 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -/* - Intel 386 emulator - - Written by Ville Linde - - Currently supports: - Intel 386 - Intel 486 - Intel Pentium - Cyrix MediaGX - Intel Pentium MMX - Intel Pentium Pro - Intel Pentium II - Intel Pentium III - Amd Athlon XP - Intel Pentium 4 -*/ - -#include "emu.h" -#include "vm_template.h" -#include "./i386_device.h" -#include "./i386priv.h" -#include "./x87priv.h" -#include "./cycles.h" -#include "./i386ops.h" - -#include "debugger.h" -#include "debug/debugcpu.h" - -/* seems to be defined on mingw-gcc */ -#undef i386 - -/* -DEFINE_DEVICE_TYPE(I386, i386_device, "i386", "Intel I386") -DEFINE_DEVICE_TYPE(I386SX, i386sx_device, "i386sx", "Intel I386SX") -DEFINE_DEVICE_TYPE(I486, i486_device, "i486", "Intel I486") -DEFINE_DEVICE_TYPE(I486DX4, i486dx4_device, "i486dx4", "Intel I486DX4") -DEFINE_DEVICE_TYPE(PENTIUM, pentium_device, "pentium", "Intel Pentium") -DEFINE_DEVICE_TYPE(PENTIUM_MMX, pentium_mmx_device, "pentium_mmx", "Intel Pentium MMX") -DEFINE_DEVICE_TYPE(MEDIAGX, mediagx_device, "mediagx", "Cyrix MediaGX") -DEFINE_DEVICE_TYPE(PENTIUM_PRO, pentium_pro_device, "pentium_pro", "Intel Pentium Pro") -DEFINE_DEVICE_TYPE(PENTIUM2, pentium2_device, "pentium2", "Intel Pentium II") -DEFINE_DEVICE_TYPE(PENTIUM3, pentium3_device, "pentium3", "Intel Pentium III") -DEFINE_DEVICE_TYPE(ATHLONXP, athlonxp_device, "athlonxp", "Amd Athlon XP") -DEFINE_DEVICE_TYPE(PENTIUM4, pentium4_device, "pentium4", "Intel Pentium 4") -*/ - -i386_device::i386_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : DEVICE(parent_vm, parent_emu) -{ - // 32 unified - d_vtlb = new device_vtlb_interface(parent_vm, parent_emu, this, AS_PROGRAM); - m_smiact = this; - m_ferr_handler = this; - m_smiact_enabled = false; - - initialize_output_signals(&outputs_reset); - d_debugger = NULL; - d_dma = NULL; - d_mem = NULL; - d_io = NULL; - d_bios = NULL; - d_pic = NULL; - d_program_stored = NULL; - d_io_stored = NULL; - - d_vtlb->set_vtlb_dynamic_entries(32); - d_vtlb->set_vtlb_page_shift(12); - d_vtlb->set_vtlb_addr_width(32); - - m_ferr_err_value = 0; - data_width = 32; - -// cache_data.clear(); - set_device_name(_T("i386 DX CPU")); -} - -i386_device::~i386_device() -{ - if(d_vtlb != NULL) delete d_vtlb; -} - -i386sx_device::i386sx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : i386_device(parent_vm, parent_emu) -{ - data_width = 16; - set_device_name(_T("i386 SX CPU")); -} - -i486_device::i486_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : i386_device(parent_vm, parent_emu) -{ - set_device_name(_T("Intel i486")); -} - -i486dx4_device::i486dx4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : i486_device(parent_vm, parent_emu) -{ - set_device_name(_T("Intel i486 DX4")); -} - -pentium_device::pentium_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : i386_device(parent_vm, parent_emu) -{ - // 64 dtlb small, 8 dtlb large, 32 itlb - d_vtlb->set_vtlb_dynamic_entries(96); - set_device_name(_T("Intel Pentium(i586)")); -} - -mediagx_device::mediagx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : i386_device(parent_vm, parent_emu) -{ - set_device_name(_T("Cyrix MediaGX")); -} - - -pentium_pro_device::pentium_pro_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : pentium_device(parent_vm, parent_emu) -{ - set_device_name(_T("Intel Pentium Pro(i686)")); -} - -pentium_mmx_device::pentium_mmx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : pentium_device(parent_vm, parent_emu) -{ - // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large - d_vtlb->set_vtlb_dynamic_entries(96); - set_device_name(_T("Intel Pentium MMX")); -} - -pentium2_device::pentium2_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : pentium_pro_device(parent_vm, parent_emu) -{ - // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large - d_vtlb->set_vtlb_dynamic_entries(96); - set_device_name(_T("Intel Pentium2")); -} - -pentium3_device::pentium3_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : pentium_pro_device(parent_vm, parent_emu) -{ - // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large - d_vtlb->set_vtlb_dynamic_entries(96); - set_device_name(_T("Intel Pentium3")); -} - -// ToDo: AthlonXP -#if 0 -athlonxp_device::athlonxp_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : pentium_device(parent_vm, parent_emu) -{ - // TODO: put correct value - d_vtlb->set_vtlb_dynamic_entries(256); - set_device_name(_T("AMD AthlonXP")); -} -#endif - -pentium4_device::pentium4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) - : pentium_device(parent_vm, parent_emu) -{ - // 128 dtlb, 64 itlb - d_vtlb->set_vtlb_dynamic_entries(196); - set_device_name(_T("Intel Pentium4")); -} - -int i386_parity_table[256]; -MODRM_TABLE i386_MODRM_table[256]; - -/*************************************************************************/ - -uint32_t i386_device::i386_translate(int segment, uint32_t ip, int rwn) -{ - // TODO: segment limit access size, execution permission, handle exception thrown from exception handler - if (PROTECTED_MODE && !V8086_MODE && (rwn != -1)) - { - if (!(m_sreg[segment].valid)) - FAULT_THROW((segment == SS) ? FAULT_SS : FAULT_GP, 0); - if (i386_limit_check(segment, ip)) - FAULT_THROW((segment == SS) ? FAULT_SS : FAULT_GP, 0); - if ((rwn == 0) && ((m_sreg[segment].flags & 8) && !(m_sreg[segment].flags & 2))) - FAULT_THROW(FAULT_GP, 0); - if ((rwn == 1) && ((m_sreg[segment].flags & 8) || !(m_sreg[segment].flags & 2))) - FAULT_THROW(FAULT_GP, 0); - } - return m_sreg[segment].base + ip; -} - -vtlb_entry i386_device::get_permissions(uint32_t pte, int wp) -{ - vtlb_entry ret = VTLB_READ_ALLOWED | ((pte & 4) ? VTLB_USER_READ_ALLOWED : 0); - if (!wp) - ret |= VTLB_WRITE_ALLOWED; - if (pte & 2) - ret |= VTLB_WRITE_ALLOWED | ((pte & 4) ? VTLB_USER_WRITE_ALLOWED : 0); - return ret; -} - -bool i386_device::i386_translate_address(int intention, offs_t *address, vtlb_entry *entry) -{ - uint32_t a = *address; - uint32_t pdbr = m_cr[3] & 0xfffff000; - uint32_t directory = (a >> 22) & 0x3ff; - uint32_t table = (a >> 12) & 0x3ff; - vtlb_entry perm = 0; - bool ret; - bool user = (intention & TRANSLATE_USER_MASK) ? true : false; - bool write = (intention & TRANSLATE_WRITE) ? true : false; - bool debug = (intention & TRANSLATE_DEBUG_MASK) ? true : false; - - if (!(m_cr[0] & 0x80000000)) - { - if (entry) - *entry = 0x77; - return true; - } - - uint32_t page_dir = m_program->read_dword(pdbr + directory * 4); - if (page_dir & 1) - { - if ((page_dir & 0x80) && (m_cr[4] & 0x10)) - { - a = (page_dir & 0xffc00000) | (a & 0x003fffff); - if (debug) - { - *address = a; - return true; - } - perm = get_permissions(page_dir, WP); - if (write && (!(perm & VTLB_WRITE_ALLOWED) || (user && !(perm & VTLB_USER_WRITE_ALLOWED)))) - ret = false; - else if (user && !(perm & VTLB_USER_READ_ALLOWED)) - ret = false; - else - { - if (write) - perm |= VTLB_FLAG_DIRTY; - if (!(page_dir & 0x40) && write) - m_program->write_dword(pdbr + directory * 4, page_dir | 0x60); - else if (!(page_dir & 0x20)) - m_program->write_dword(pdbr + directory * 4, page_dir | 0x20); - ret = true; - } - } - else - { - uint32_t page_entry = m_program->read_dword((page_dir & 0xfffff000) + (table * 4)); - if (!(page_entry & 1)) - ret = false; - else - { - a = (page_entry & 0xfffff000) | (a & 0xfff); - if (debug) - { - *address = a; - return true; - } - perm = get_permissions(page_entry, WP); - if (write && (!(perm & VTLB_WRITE_ALLOWED) || (user && !(perm & VTLB_USER_WRITE_ALLOWED)))) - ret = false; - else if (user && !(perm & VTLB_USER_READ_ALLOWED)) - ret = false; - else - { - if (write) - perm |= VTLB_FLAG_DIRTY; - if (!(page_dir & 0x20)) - m_program->write_dword(pdbr + directory * 4, page_dir | 0x20); - if (!(page_entry & 0x40) && write) - m_program->write_dword((page_dir & 0xfffff000) + (table * 4), page_entry | 0x60); - else if (!(page_entry & 0x20)) - m_program->write_dword((page_dir & 0xfffff000) + (table * 4), page_entry | 0x20); - ret = true; - } - } - } - } - else - ret = false; - if (entry) - *entry = perm; - if (ret) - *address = a; - return ret; -} - -//#define TEST_TLB - -bool i386_device::translate_address(int pl, int type, uint32_t *address, uint32_t *error) -{ - if (!(m_cr[0] & 0x80000000)) // Some (very few) old OS's won't work with this - return true; - - const vtlb_entry *table = d_vtlb->vtlb_table(); - uint32_t index = *address >> 12; - vtlb_entry entry = table[index]; - if (type == TRANSLATE_FETCH) - type = TRANSLATE_READ; - if (pl == 3) - type |= TRANSLATE_USER_MASK; -#ifdef TEST_TLB - uint32_t test_addr = *address; -#endif - - if (!(entry & VTLB_FLAG_VALID) || ((type & TRANSLATE_WRITE) && !(entry & VTLB_FLAG_DIRTY))) - { - if (!i386_translate_address(type, address, &entry)) - { - *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((m_CPL == 3) ? 4 : 0); - if (entry) - *error |= 1; - return false; - } - d_vtlb->vtlb_dynload(index, *address, entry); - return true; - } - if (!(entry & (1 << type))) - { - *error = ((type & TRANSLATE_WRITE) ? 2 : 0) | ((m_CPL == 3) ? 4 : 0) | 1; - return false; - } - *address = (entry & 0xfffff000) | (*address & 0xfff); -#ifdef TEST_TLB - int test_ret = i386_translate_address(type | TRANSLATE_DEBUG_MASK, &test_addr, nullptr); - if (!test_ret || (test_addr != *address)) - logerror("TLB-PTE mismatch! %06X %06X %06x\n", *address, test_addr, m_pc); -#endif - return true; -} - -uint32_t i386_device::i386_load_protected_mode_segment(I386_SREG *seg, uint64_t *desc ) -{ - uint32_t v1,v2; - uint32_t base, limit; - int entry; - - if(!seg->selector) - { - seg->flags = 0; - seg->base = 0; - seg->limit = 0; - seg->d = 0; - seg->valid = false; - return 0; - } - - if ( seg->selector & 0x4 ) - { - base = m_ldtr.base; - limit = m_ldtr.limit; - } else { - base = m_gdtr.base; - limit = m_gdtr.limit; - } - - entry = seg->selector & ~0x7; - if (limit == 0 || entry + 7 > limit) - return 0; - - v1 = READ32PL0(base + entry ); - v2 = READ32PL0(base + entry + 4 ); - - seg->flags = (v2 >> 8) & 0xf0ff; - seg->base = (v2 & 0xff000000) | ((v2 & 0xff) << 16) | ((v1 >> 16) & 0xffff); - seg->limit = (v2 & 0xf0000) | (v1 & 0xffff); - if (seg->flags & 0x8000) - seg->limit = (seg->limit << 12) | 0xfff; - seg->d = (seg->flags & 0x4000) ? 1 : 0; - seg->valid = true; - - if(desc) - *desc = ((uint64_t)v2<<32)|v1; - return 1; -} - -void i386_device::i386_load_call_gate(I386_CALL_GATE *gate) -{ - uint32_t v1,v2; - uint32_t base,limit; - int entry; - - if ( gate->segment & 0x4 ) - { - base = m_ldtr.base; - limit = m_ldtr.limit; - } else { - base = m_gdtr.base; - limit = m_gdtr.limit; - } - - entry = gate->segment & ~0x7; - if (limit == 0 || entry + 7 > limit) - return; - - v1 = READ32PL0(base + entry ); - v2 = READ32PL0(base + entry + 4 ); - - /* Note that for task gates, offset and dword_count are not used */ - gate->selector = (v1 >> 16) & 0xffff; - gate->offset = (v1 & 0x0000ffff) | (v2 & 0xffff0000); - gate->ar = (v2 >> 8) & 0xff; - gate->dword_count = v2 & 0x001f; - gate->present = (gate->ar >> 7) & 0x01; - gate->dpl = (gate->ar >> 5) & 0x03; -} - -void i386_device::i386_set_descriptor_accessed(uint16_t selector) -{ - // assume the selector is valid, we don't need to check it again - uint32_t base, addr; - uint8_t rights; - if(!(selector & ~3)) - return; - - if ( selector & 0x4 ) - base = m_ldtr.base; - else - base = m_gdtr.base; - - addr = base + (selector & ~7) + 5; - i386_translate_address(TRANSLATE_READ, &addr, nullptr); - rights = m_program->read_byte(addr); - // Should a fault be thrown if the table is read only? - m_program->write_byte(addr, rights | 1); -} - -void i386_device::i386_load_segment_descriptor(int segment ) -{ - if (PROTECTED_MODE) - { - uint16_t old_flags = m_sreg[segment].flags; - if (!V8086_MODE) - { - i386_load_protected_mode_segment(&m_sreg[segment], nullptr); - if (m_sreg[segment].selector) - { - i386_set_descriptor_accessed(m_sreg[segment].selector); - m_sreg[segment].flags |= 0x0001; - } - } - else - { - m_sreg[segment].base = m_sreg[segment].selector << 4; - m_sreg[segment].limit = 0xffff; - m_sreg[segment].flags = (segment == CS) ? 0x00fb : 0x00f3; - m_sreg[segment].d = 0; - m_sreg[segment].valid = true; - } - if (segment == CS && m_sreg[segment].flags != old_flags) - debugger_privilege_hook(); - } - else - { - m_sreg[segment].base = m_sreg[segment].selector << 4; - m_sreg[segment].d = 0; - m_sreg[segment].valid = true; - - if (segment == CS) - { - if (!m_performed_intersegment_jump) - m_sreg[segment].base |= 0xfff00000; - if (m_cpu_version < 0x500) - m_sreg[segment].flags = 0x93; - } - } -} - -/* Retrieves the stack selector located in the current TSS */ -uint32_t i386_device::i386_get_stack_segment(uint8_t privilege) -{ - uint32_t ret; - if(privilege >= 3) - return 0; - - if(m_task.flags & 8) - ret = READ32PL0((m_task.base+8) + (8*privilege)); - else - ret = READ16PL0((m_task.base+4) + (4*privilege)); - - return ret; -} - -/* Retrieves the stack pointer located in the current TSS */ -uint32_t i386_device::i386_get_stack_ptr(uint8_t privilege) -{ - uint32_t ret; - if(privilege >= 3) - return 0; - - if(m_task.flags & 8) - ret = READ32PL0((m_task.base+4) + (8*privilege)); - else - ret = READ16PL0((m_task.base+2) + (4*privilege)); - - return ret; -} - -uint32_t i386_device::get_flags() const -{ - uint32_t f = 0x2; - f |= m_CF; - f |= m_PF << 2; - f |= m_AF << 4; - f |= m_ZF << 6; - f |= m_SF << 7; - f |= m_TF << 8; - f |= m_IF << 9; - f |= m_DF << 10; - f |= m_OF << 11; - f |= m_IOP1 << 12; - f |= m_IOP2 << 13; - f |= m_NT << 14; - f |= m_RF << 16; - f |= m_VM << 17; - f |= m_AC << 18; - f |= m_VIF << 19; - f |= m_VIP << 20; - f |= m_ID << 21; - return (m_eflags & ~m_eflags_mask) | (f & m_eflags_mask); -} - -void i386_device::set_flags(uint32_t f ) -{ - f &= m_eflags_mask; - m_CF = (f & 0x1) ? 1 : 0; - m_PF = (f & 0x4) ? 1 : 0; - m_AF = (f & 0x10) ? 1 : 0; - m_ZF = (f & 0x40) ? 1 : 0; - m_SF = (f & 0x80) ? 1 : 0; - m_TF = (f & 0x100) ? 1 : 0; - m_IF = (f & 0x200) ? 1 : 0; - m_DF = (f & 0x400) ? 1 : 0; - m_OF = (f & 0x800) ? 1 : 0; - m_IOP1 = (f & 0x1000) ? 1 : 0; - m_IOP2 = (f & 0x2000) ? 1 : 0; - m_NT = (f & 0x4000) ? 1 : 0; - m_RF = (f & 0x10000) ? 1 : 0; - m_VM = (f & 0x20000) ? 1 : 0; - m_AC = (f & 0x40000) ? 1 : 0; - m_VIF = (f & 0x80000) ? 1 : 0; - m_VIP = (f & 0x100000) ? 1 : 0; - m_ID = (f & 0x200000) ? 1 : 0; - m_eflags = f; -} - -void i386_device::sib_byte(uint8_t mod, uint32_t* out_ea, uint8_t* out_segment) -{ - uint32_t ea = 0; - uint8_t segment = 0; - uint8_t scale, i, base; - uint8_t sib = FETCH(); - scale = (sib >> 6) & 0x3; - i = (sib >> 3) & 0x7; - base = sib & 0x7; - - switch( base ) - { - case 0: ea = REG32(EAX); segment = DS; break; - case 1: ea = REG32(ECX); segment = DS; break; - case 2: ea = REG32(EDX); segment = DS; break; - case 3: ea = REG32(EBX); segment = DS; break; - case 4: ea = REG32(ESP); segment = SS; break; - case 5: - if( mod == 0 ) { - ea = FETCH32(); - segment = DS; - } else if( mod == 1 ) { - ea = REG32(EBP); - segment = SS; - } else if( mod == 2 ) { - ea = REG32(EBP); - segment = SS; - } - break; - case 6: ea = REG32(ESI); segment = DS; break; - case 7: ea = REG32(EDI); segment = DS; break; - } - switch( i ) - { - case 0: ea += REG32(EAX) * (1 << scale); break; - case 1: ea += REG32(ECX) * (1 << scale); break; - case 2: ea += REG32(EDX) * (1 << scale); break; - case 3: ea += REG32(EBX) * (1 << scale); break; - case 4: break; - case 5: ea += REG32(EBP) * (1 << scale); break; - case 6: ea += REG32(ESI) * (1 << scale); break; - case 7: ea += REG32(EDI) * (1 << scale); break; - } - *out_ea = ea; - *out_segment = segment; -} - -void i386_device::modrm_to_EA(uint8_t mod_rm, uint32_t* out_ea, uint8_t* out_segment) -{ - int8_t disp8; - int16_t disp16; - int32_t disp32; - uint8_t mod = (mod_rm >> 6) & 0x3; - uint8_t rm = mod_rm & 0x7; - uint32_t ea; - uint8_t segment; - - if( mod_rm >= 0xc0 ) - fatalerror("i386: Called modrm_to_EA with modrm value %02X!\n",mod_rm); - - - if( m_address_size ) { - switch( rm ) - { - default: - case 0: ea = REG32(EAX); segment = DS; break; - case 1: ea = REG32(ECX); segment = DS; break; - case 2: ea = REG32(EDX); segment = DS; break; - case 3: ea = REG32(EBX); segment = DS; break; - case 4: sib_byte(mod, &ea, &segment ); break; - case 5: - if( mod == 0 ) { - ea = FETCH32(); segment = DS; - } else { - ea = REG32(EBP); segment = SS; - } - break; - case 6: ea = REG32(ESI); segment = DS; break; - case 7: ea = REG32(EDI); segment = DS; break; - } - if( mod == 1 ) { - disp8 = FETCH(); - ea += (int32_t)disp8; - } else if( mod == 2 ) { - disp32 = FETCH32(); - ea += disp32; - } - - if( m_segment_prefix ) - segment = m_segment_override; - - *out_ea = ea; - *out_segment = segment; - - } else { - switch( rm ) - { - default: - case 0: ea = REG16(BX) + REG16(SI); segment = DS; break; - case 1: ea = REG16(BX) + REG16(DI); segment = DS; break; - case 2: ea = REG16(BP) + REG16(SI); segment = SS; break; - case 3: ea = REG16(BP) + REG16(DI); segment = SS; break; - case 4: ea = REG16(SI); segment = DS; break; - case 5: ea = REG16(DI); segment = DS; break; - case 6: - if( mod == 0 ) { - ea = FETCH16(); segment = DS; - } else { - ea = REG16(BP); segment = SS; - } - break; - case 7: ea = REG16(BX); segment = DS; break; - } - if( mod == 1 ) { - disp8 = FETCH(); - ea += (int32_t)disp8; - } else if( mod == 2 ) { - disp16 = FETCH16(); - ea += (int32_t)disp16; - } - - if( m_segment_prefix ) - segment = m_segment_override; - - *out_ea = ea & 0xffff; - *out_segment = segment; - } -} - -uint32_t i386_device::GetNonTranslatedEA(uint8_t modrm,uint8_t *seg) -{ - uint8_t segment; - uint32_t ea; - modrm_to_EA(modrm, &ea, &segment ); - if(seg) *seg = segment; - return ea; -} - -uint32_t i386_device::GetEA(uint8_t modrm, int rwn) -{ - uint8_t segment; - uint32_t ea; - modrm_to_EA(modrm, &ea, &segment ); - return i386_translate(segment, ea, rwn ); -} - -/* Check segment register for validity when changing privilege level after an RETF */ -void i386_device::i386_check_sreg_validity(int reg) -{ - uint16_t selector = m_sreg[reg].selector; - uint8_t CPL = m_CPL; - uint8_t DPL,RPL; - I386_SREG desc; - int invalid; - - memset(&desc, 0, sizeof(desc)); - desc.selector = selector; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - RPL = selector & 0x03; - - /* Must be within the relevant descriptor table limits */ - if(selector & 0x04) - { - if((selector & ~0x07) > m_ldtr.limit) - invalid = 1; - } - else - { - if((selector & ~0x07) > m_gdtr.limit) - invalid = 1; - } - - /* Must be either a data or readable code segment */ - if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0002)) || (desc.flags & 0x0018) == 0x0010) - invalid = 0; - else - invalid = 1; - - /* If a data segment or non-conforming code segment, then either DPL >= CPL or DPL >= RPL */ - if(((desc.flags & 0x0018) == 0x0018 && (desc.flags & 0x0004) == 0) || (desc.flags & 0x0018) == 0x0010) - { - if((DPL < CPL) || (DPL < RPL)) - invalid = 1; - } - - /* if segment is invalid, then segment register is nulled */ - if(invalid != 0) - { - m_sreg[reg].selector = 0; - i386_load_segment_descriptor(reg); - } -} - -int i386_device::i386_limit_check(int seg, uint32_t offset) -{ - if(PROTECTED_MODE && !V8086_MODE) - { - if((m_sreg[seg].flags & 0x0018) == 0x0010 && m_sreg[seg].flags & 0x0004) // if expand-down data segment - { - // compare if greater then 0xffffffff when we're passed the access size - if((offset <= m_sreg[seg].limit) || ((m_sreg[seg].d)?0:(offset > 0xffff))) - { - logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x (expand-down)\n",m_pc,m_sreg[seg].selector,m_sreg[seg].limit,offset); - return 1; - } - } - else - { - if(offset > m_sreg[seg].limit) - { - logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x\n",m_pc,m_sreg[seg].selector,m_sreg[seg].limit,offset); - return 1; - } - } - } - return 0; -} - -void i386_device::i386_sreg_load(uint16_t selector, uint8_t reg, bool *fault) -{ - // Checks done when MOV changes a segment register in protected mode - uint8_t CPL,RPL,DPL; - - CPL = m_CPL; - RPL = selector & 0x0003; - - if(!PROTECTED_MODE || V8086_MODE) - { - m_sreg[reg].selector = selector; - i386_load_segment_descriptor(reg); - if(fault) *fault = false; - return; - } - - if(fault) *fault = true; - if(reg == SS) - { - I386_SREG stack; - - memset(&stack, 0, sizeof(stack)); - stack.selector = selector; - i386_load_protected_mode_segment(&stack,nullptr); - DPL = (stack.flags >> 5) & 0x03; - - if((selector & ~0x0003) == 0) - { - logerror("SReg Load (%08x): Selector is null.\n",m_pc); - FAULT(FAULT_GP,0) - } - if(selector & 0x0004) // LDT - { - if((selector & ~0x0007) > m_ldtr.limit) - { - logerror("SReg Load (%08x): Selector is out of LDT bounds.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - } - else // GDT - { - if((selector & ~0x0007) > m_gdtr.limit) - { - logerror("SReg Load (%08x): Selector is out of GDT bounds.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - } - if (RPL != CPL) - { - logerror("SReg Load (%08x): Selector RPL does not equal CPL.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - if(((stack.flags & 0x0018) != 0x10) && (stack.flags & 0x0002) != 0) - { - logerror("SReg Load (%08x): Segment is not a writable data segment.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - if(DPL != CPL) - { - logerror("SReg Load (%08x): Segment DPL does not equal CPL.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - if(!(stack.flags & 0x0080)) - { - logerror("SReg Load (%08x): Segment is not present.\n",m_pc); - FAULT(FAULT_SS,selector & ~0x03) - } - } - if(reg == DS || reg == ES || reg == FS || reg == GS) - { - I386_SREG desc; - - if((selector & ~0x0003) == 0) - { - m_sreg[reg].selector = selector; - i386_load_segment_descriptor(reg ); - if(fault) *fault = false; - return; - } - - memset(&desc, 0, sizeof(desc)); - desc.selector = selector; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; - - if(selector & 0x0004) // LDT - { - if((selector & ~0x0007) > m_ldtr.limit) - { - logerror("SReg Load (%08x): Selector is out of LDT bounds.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - } - else // GDT - { - if((selector & ~0x0007) > m_gdtr.limit) - { - logerror("SReg Load (%08x): Selector is out of GDT bounds.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - } - if((desc.flags & 0x0018) != 0x10) - { - if((((desc.flags & 0x0002) != 0) && ((desc.flags & 0x0018) != 0x18)) || !(desc.flags & 0x10)) - { - logerror("SReg Load (%08x): Segment is not a data segment or readable code segment.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - } - if(((desc.flags & 0x0018) == 0x10) || ((!(desc.flags & 0x0004)) && ((desc.flags & 0x0018) == 0x18))) - { - // if data or non-conforming code segment - if((RPL > DPL) || (CPL > DPL)) - { - logerror("SReg Load (%08x): Selector RPL or CPL is not less or equal to segment DPL.\n",m_pc); - FAULT(FAULT_GP,selector & ~0x03) - } - } - if(!(desc.flags & 0x0080)) - { - logerror("SReg Load (%08x): Segment is not present.\n",m_pc); - FAULT(FAULT_NP,selector & ~0x03) - } - } - - m_sreg[reg].selector = selector; - i386_load_segment_descriptor(reg ); - if(fault) *fault = false; -} - -void i386_device::i386_trap(int irq, int irq_gate, int trap_level) -{ - /* I386 Interrupts/Traps/Faults: - * - * 0x00 Divide by zero - * 0x01 Debug exception - * 0x02 NMI - * 0x03 Int3 - * 0x04 Overflow - * 0x05 Array bounds check - * 0x06 Illegal Opcode - * 0x07 FPU not available - * 0x08 Double fault - * 0x09 Coprocessor segment overrun - * 0x0a Invalid task state - * 0x0b Segment not present - * 0x0c Stack exception - * 0x0d General Protection Fault - * 0x0e Page fault - * 0x0f Reserved - * 0x10 Coprocessor error - */ - uint32_t v1, v2; - uint32_t offset, oldflags = get_flags(); - uint16_t segment; - int entry = irq * (PROTECTED_MODE ? 8 : 4); - int SetRPL; - m_lock = false; - - if( !(PROTECTED_MODE) ) - { - /* 16-bit */ - PUSH16(oldflags & 0xffff ); - PUSH16(m_sreg[CS].selector ); - if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1) - PUSH16(m_eip ); - else - PUSH16(m_prev_eip ); - - m_sreg[CS].selector = READ16(m_idtr.base + entry + 2 ); - m_eip = READ16(m_idtr.base + entry ); - - m_TF = 0; - m_IF = 0; - } - else - { - int type; - uint16_t flags; - I386_SREG desc; - uint8_t CPL = m_CPL, DPL; //, RPL = 0; - - /* 32-bit */ - v1 = READ32PL0(m_idtr.base + entry ); - v2 = READ32PL0(m_idtr.base + entry + 4 ); - offset = (v2 & 0xffff0000) | (v1 & 0xffff); - segment = (v1 >> 16) & 0xffff; - type = (v2>>8) & 0x1F; - flags = (v2>>8) & 0xf0ff; - - if(trap_level == 2) - { - logerror("IRQ: Double fault.\n"); - FAULT_EXP(FAULT_DF,0); - } - if(trap_level >= 3) - { - logerror("IRQ: Triple fault. CPU reset.\n"); - //pulse_input_line(INPUT_LINE_RESET, attotime::zero); - m_shutdown = true; - write_signals(&outputs_reset, 0xffffffff); - reset(); - return; - } - - /* segment privilege checks */ - if(entry >= m_idtr.limit) - { - logerror("IRQ (%08x): Vector %02xh is past IDT limit.\n",m_pc,entry); - FAULT_EXP(FAULT_GP,entry+2) - } - /* segment must be interrupt gate, trap gate, or task gate */ - if(type != 0x05 && type != 0x06 && type != 0x07 && type != 0x0e && type != 0x0f) - { - logerror("IRQ#%02x (%08x): Vector segment %04x is not an interrupt, trap or task gate.\n",irq,m_pc,segment); - FAULT_EXP(FAULT_GP,entry+2) - } - - if(m_ext == 0) // if software interrupt (caused by INT/INTO/INT3) - { - if(((flags >> 5) & 0x03) < CPL) - { - logerror("IRQ (%08x): Software IRQ - gate DPL is less than CPL.\n",m_pc); - FAULT_EXP(FAULT_GP,entry+2) - } - if(V8086_MODE) - { - if((!m_IOP1 || !m_IOP2) && (m_opcode != 0xcc)) - { - logerror("IRQ (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",m_pc); - FAULT(FAULT_GP,0) - } - - } - } - - if((flags & 0x0080) == 0) - { - logerror("IRQ: Vector segment is not present.\n"); - FAULT_EXP(FAULT_NP,entry+2) - } - - if(type == 0x05) - { - /* Task gate */ - memset(&desc, 0, sizeof(desc)); - desc.selector = segment; - i386_load_protected_mode_segment(&desc,nullptr); - if(segment & 0x04) - { - logerror("IRQ: Task gate: TSS is not in the GDT.\n"); - FAULT_EXP(FAULT_TS,segment & ~0x03); - } - else - { - if(segment > m_gdtr.limit) - { - logerror("IRQ: Task gate: TSS is past GDT limit.\n"); - FAULT_EXP(FAULT_TS,segment & ~0x03); - } - } - if((desc.flags & 0x000f) != 0x09 && (desc.flags & 0x000f) != 0x01) - { - logerror("IRQ: Task gate: TSS is not an available TSS.\n"); - FAULT_EXP(FAULT_TS,segment & ~0x03); - } - if((desc.flags & 0x0080) == 0) - { - logerror("IRQ: Task gate: TSS is not present.\n"); - FAULT_EXP(FAULT_NP,segment & ~0x03); - } - if(!(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1)) - m_eip = m_prev_eip; - if(desc.flags & 0x08) - i386_task_switch(desc.selector,1); - else - i286_task_switch(desc.selector,1); - return; - } - else - { - /* Interrupt or Trap gate */ - memset(&desc, 0, sizeof(desc)); - desc.selector = segment; - i386_load_protected_mode_segment(&desc,nullptr); - CPL = m_CPL; // current privilege level - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level -// RPL = segment & 0x03; // requested privilege level - - if((segment & ~0x03) == 0) - { - logerror("IRQ: Gate segment is null.\n"); - FAULT_EXP(FAULT_GP,m_ext) - } - if(segment & 0x04) - { - if((segment & ~0x07) > m_ldtr.limit) - { - logerror("IRQ: Gate segment is past LDT limit.\n"); - FAULT_EXP(FAULT_GP,(segment & 0x03)+m_ext) - } - } - else - { - if((segment & ~0x07) > m_gdtr.limit) - { - logerror("IRQ: Gate segment is past GDT limit.\n"); - FAULT_EXP(FAULT_GP,(segment & 0x03)+m_ext) - } - } - if((desc.flags & 0x0018) != 0x18) - { - logerror("IRQ: Gate descriptor is not a code segment.\n"); - FAULT_EXP(FAULT_GP,(segment & 0x03)+m_ext) - } - if((desc.flags & 0x0080) == 0) - { - logerror("IRQ: Gate segment is not present.\n"); - FAULT_EXP(FAULT_NP,(segment & 0x03)+m_ext) - } - if((desc.flags & 0x0004) == 0 && (DPL < CPL)) - { - /* IRQ to inner privilege */ - I386_SREG stack; - uint32_t newESP,oldSS,oldESP; - - if(V8086_MODE && DPL) - { - logerror("IRQ: Gate to CPL>0 from VM86 mode.\n"); - FAULT_EXP(FAULT_GP,segment & ~0x03); - } - /* Check new stack segment in TSS */ - memset(&stack, 0, sizeof(stack)); - stack.selector = i386_get_stack_segment(DPL); - i386_load_protected_mode_segment(&stack,nullptr); - oldSS = m_sreg[SS].selector; - if(flags & 0x0008) - oldESP = REG32(ESP); - else - oldESP = REG16(SP); - if((stack.selector & ~0x03) == 0) - { - logerror("IRQ: New stack selector is null.\n"); - FAULT_EXP(FAULT_GP,m_ext) - } - if(stack.selector & 0x04) - { - if((stack.selector & ~0x07) > m_ldtr.base) - { - logerror("IRQ: New stack selector is past LDT limit.\n"); - FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+m_ext) - } - } - else - { - if((stack.selector & ~0x07) > m_gdtr.base) - { - logerror("IRQ: New stack selector is past GDT limit.\n"); - FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+m_ext) - } - } - if((stack.selector & 0x03) != DPL) - { - logerror("IRQ: New stack selector RPL is not equal to code segment DPL.\n"); - FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+m_ext) - } - if(((stack.flags >> 5) & 0x03) != DPL) - { - logerror("IRQ: New stack segment DPL is not equal to code segment DPL.\n"); - FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+m_ext) - } - if(((stack.flags & 0x0018) != 0x10) && (stack.flags & 0x0002) != 0) - { - logerror("IRQ: New stack segment is not a writable data segment.\n"); - FAULT_EXP(FAULT_TS,(stack.selector & ~0x03)+m_ext) // #TS(stack selector + EXT) - } - if((stack.flags & 0x0080) == 0) - { - logerror("IRQ: New stack segment is not present.\n"); - FAULT_EXP(FAULT_SS,(stack.selector & ~0x03)+m_ext) // #TS(stack selector + EXT) - } - newESP = i386_get_stack_ptr(DPL); - if(type & 0x08) // 32-bit gate - { - if(((newESP < (V8086_MODE?36:20)) && !(stack.flags & 0x4)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?36:20))) && (stack.flags & 0x4))) - { - logerror("IRQ: New stack has no space for return addresses.\n"); - FAULT_EXP(FAULT_SS,0) - } - } - else // 16-bit gate - { - newESP &= 0xffff; - if(((newESP < (V8086_MODE?18:10)) && !(stack.flags & 0x4)) || ((~stack.limit < (~(newESP - 1) + (V8086_MODE?18:10))) && (stack.flags & 0x4))) - { - logerror("IRQ: New stack has no space for return addresses.\n"); - FAULT_EXP(FAULT_SS,0) - } - } - if(offset > desc.limit) - { - logerror("IRQ: New EIP is past code segment limit.\n"); - FAULT_EXP(FAULT_GP,0) - } - /* change CPL before accessing the stack */ - m_CPL = DPL; - /* check for page fault at new stack TODO: check if stack frame crosses page boundary */ - WRITE_TEST(stack.base+newESP-1); - /* Load new stack segment descriptor */ - m_sreg[SS].selector = stack.selector; - i386_load_protected_mode_segment(&m_sreg[SS],nullptr); - i386_set_descriptor_accessed(stack.selector); - REG32(ESP) = newESP; - if(V8086_MODE) - { - //logerror("IRQ (%08x): Interrupt during V8086 task\n",m_pc); - if(type & 0x08) - { - PUSH32SEG(m_sreg[GS].selector & 0xffff); - PUSH32SEG(m_sreg[FS].selector & 0xffff); - PUSH32SEG(m_sreg[DS].selector & 0xffff); - PUSH32SEG(m_sreg[ES].selector & 0xffff); - } - else - { - PUSH16(m_sreg[GS].selector); - PUSH16(m_sreg[FS].selector); - PUSH16(m_sreg[DS].selector); - PUSH16(m_sreg[ES].selector); - } - m_sreg[GS].selector = 0; - m_sreg[FS].selector = 0; - m_sreg[DS].selector = 0; - m_sreg[ES].selector = 0; - m_VM = 0; - i386_load_segment_descriptor(GS); - i386_load_segment_descriptor(FS); - i386_load_segment_descriptor(DS); - i386_load_segment_descriptor(ES); - } - if(type & 0x08) - { - // 32-bit gate - PUSH32SEG(oldSS); - PUSH32(oldESP); - } - else - { - // 16-bit gate - PUSH16(oldSS); - PUSH16(oldESP); - } - SetRPL = 1; - } - else - { - int stack_limit; - if((desc.flags & 0x0004) || (DPL == CPL)) - { - /* IRQ to same privilege */ - if(V8086_MODE && !m_ext) - { - logerror("IRQ: Gate to same privilege from VM86 mode.\n"); - FAULT_EXP(FAULT_GP,segment & ~0x03); - } - if(type == 0x0e || type == 0x0f) // 32-bit gate - stack_limit = 10; - else - stack_limit = 6; - // TODO: Add check for error code (2 extra bytes) - if(REG32(ESP) < stack_limit) - { - logerror("IRQ: Stack has no space left (needs %i bytes).\n",stack_limit); - FAULT_EXP(FAULT_SS,0) - } - if(offset > desc.limit) - { - logerror("IRQ: Gate segment offset is past segment limit.\n"); - FAULT_EXP(FAULT_GP,0) - } - SetRPL = 1; - } - else - { - logerror("IRQ: Gate descriptor is non-conforming, and DPL does not equal CPL.\n"); - FAULT_EXP(FAULT_GP,segment) - } - } - } - uint32_t tempSP = REG32(ESP); - try - { - // this is ugly but the alternative is worse - if(type != 0x0e && type != 0x0f) // if not 386 interrupt or trap gate - { - PUSH16(oldflags & 0xffff ); - PUSH16(m_sreg[CS].selector ); - if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1) - PUSH16(m_eip ); - else - PUSH16(m_prev_eip ); - } - else - { - PUSH32(oldflags & 0x00ffffff ); - PUSH32SEG(m_sreg[CS].selector ); - if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1) - PUSH32(m_eip ); - else - PUSH32(m_prev_eip ); - } - } - catch(uint64_t e) - { - REG32(ESP) = tempSP; - throw e; - } - if(SetRPL != 0) - segment = (segment & ~0x03) | m_CPL; - m_sreg[CS].selector = segment; - m_eip = offset; - - if(type == 0x0e || type == 0x06) - m_IF = 0; - m_TF = 0; - m_NT = 0; - m_eflags = get_flags(); -#if 0 - if((irq >= 0x10) && (irq_gate == 1) && (m_ext == 0)) { - // Try to call pseudo bios - i386_load_segment_descriptor(CS); - uint32_t tmp_pc = i386_translate(CS, m_eip, -1, 1 ); - int stat = 0; - bios_trap_x86(tmp_pc, stat); - if(stat != 0) { // HIT - try { - // this is ugly but the alternative is worse - if(/*type != 0x0e && type != 0x0f*/ (type & 0x08) == 0) // if not 386 interrupt or trap gate - { - m_eip = POP16(); - m_sreg[CS].selector = POP16(); - UINT32 __flags = POP16(); - m_eflags = (get_flags() & 0xffff0000) | (__flags & 0x0000ffff); - set_flags(m_eflags); - } - else - { - m_eip = POP32(); - UINT32 sel; - sel = POP32(); - m_sreg[CS].selector = sel; // ToDo: POP32SEG() - UINT32 __flags = POP32(); - m_eflags = (get_flags() & 0xff000000) | (__flags & 0x00ffffff); - set_flags(m_eflags); - } - } - catch(UINT64 e) - { - REG32(ESP) = tempSP; - //logerror("THROWN EXCEPTION %08X at i386_trap() IRQ=%02x EIP=%08x V8086_MODE=%s line %d\n", e, irq, cpustate->eip, (V8086_MODE) ? "Yes" : "No", __LINE__); - throw e; - } - return; - } - CHANGE_PC(m_eip); - return; - } -#endif - } - i386_load_segment_descriptor(CS); - CHANGE_PC(m_eip); -} - -void i386_device::i386_trap_with_error(int irq, int irq_gate, int trap_level, uint32_t error) -{ - i386_trap(irq,irq_gate,trap_level); - if(irq == 8 || irq == 10 || irq == 11 || irq == 12 || irq == 13 || irq == 14) - { - // for these exceptions, an error code is pushed onto the stack by the processor. - // no error code is pushed for software interrupts, either. - if(PROTECTED_MODE) - { - uint32_t entry = irq * 8; - uint32_t v2,type; - v2 = READ32PL0(m_idtr.base + entry + 4 ); - type = (v2>>8) & 0x1F; - if(type == 5) - { - v2 = READ32PL0(m_idtr.base + entry); - v2 = READ32PL0(m_gdtr.base + ((v2 >> 16) & 0xfff8) + 4); - type = (v2>>8) & 0x1F; - } - if(type >= 9) - PUSH32(error); - else - PUSH16(error); - } - else - PUSH16(error); - } -} - - -void i386_device::i286_task_switch(uint16_t selector, uint8_t nested) -{ - uint32_t tss; - I386_SREG seg; - uint16_t old_task; - uint8_t ar_byte; // access rights byte - - /* TODO: Task State Segment privilege checks */ - - /* For tasks that aren't nested, clear the busy bit in the task's descriptor */ - if(nested == 0) - { - if(m_task.segment & 0x0004) - { - ar_byte = READ8(m_ldtr.base + (m_task.segment & ~0x0007) + 5); - WRITE8(m_ldtr.base + (m_task.segment & ~0x0007) + 5,ar_byte & ~0x02); - } - else - { - ar_byte = READ8(m_gdtr.base + (m_task.segment & ~0x0007) + 5); - WRITE8(m_gdtr.base + (m_task.segment & ~0x0007) + 5,ar_byte & ~0x02); - } - } - - /* Save the state of the current task in the current TSS (TR register base) */ - tss = m_task.base; - WRITE16(tss+0x0e,m_eip & 0x0000ffff); - WRITE16(tss+0x10,get_flags() & 0x0000ffff); - WRITE16(tss+0x12,REG16(AX)); - WRITE16(tss+0x14,REG16(CX)); - WRITE16(tss+0x16,REG16(DX)); - WRITE16(tss+0x18,REG16(BX)); - WRITE16(tss+0x1a,REG16(SP)); - WRITE16(tss+0x1c,REG16(BP)); - WRITE16(tss+0x1e,REG16(SI)); - WRITE16(tss+0x20,REG16(DI)); - WRITE16(tss+0x22,m_sreg[ES].selector); - WRITE16(tss+0x24,m_sreg[CS].selector); - WRITE16(tss+0x26,m_sreg[SS].selector); - WRITE16(tss+0x28,m_sreg[DS].selector); - - old_task = m_task.segment; - - /* Load task register with the selector of the incoming task */ - m_task.segment = selector; - memset(&seg, 0, sizeof(seg)); - seg.selector = m_task.segment; - i386_load_protected_mode_segment(&seg,nullptr); - m_task.limit = seg.limit; - m_task.base = seg.base; - m_task.flags = seg.flags; - - /* Set TS bit in CR0 */ - m_cr[0] |= 0x08; - - /* Load incoming task state from the new task's TSS */ - tss = m_task.base; - m_ldtr.segment = READ16(tss+0x2a) & 0xffff; - seg.selector = m_ldtr.segment; - i386_load_protected_mode_segment(&seg,nullptr); - m_ldtr.limit = seg.limit; - m_ldtr.base = seg.base; - m_ldtr.flags = seg.flags; - m_eip = READ16(tss+0x0e); - set_flags(READ16(tss+0x10)); - REG16(AX) = READ16(tss+0x12); - REG16(CX) = READ16(tss+0x14); - REG16(DX) = READ16(tss+0x16); - REG16(BX) = READ16(tss+0x18); - REG16(SP) = READ16(tss+0x1a); - REG16(BP) = READ16(tss+0x1c); - REG16(SI) = READ16(tss+0x1e); - REG16(DI) = READ16(tss+0x20); - m_sreg[ES].selector = READ16(tss+0x22) & 0xffff; - i386_load_segment_descriptor(ES); - m_sreg[CS].selector = READ16(tss+0x24) & 0xffff; - i386_load_segment_descriptor(CS); - m_sreg[SS].selector = READ16(tss+0x26) & 0xffff; - i386_load_segment_descriptor(SS); - m_sreg[DS].selector = READ16(tss+0x28) & 0xffff; - i386_load_segment_descriptor(DS); - - /* Set the busy bit in the new task's descriptor */ - if(selector & 0x0004) - { - ar_byte = READ8(m_ldtr.base + (selector & ~0x0007) + 5); - WRITE8(m_ldtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02); - } - else - { - ar_byte = READ8(m_gdtr.base + (selector & ~0x0007) + 5); - WRITE8(m_gdtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02); - } - - /* For nested tasks, we write the outgoing task's selector to the back-link field of the new TSS, - and set the NT flag in the EFLAGS register */ - if(nested != 0) - { - WRITE16(tss+0,old_task); - m_NT = 1; - } - CHANGE_PC(m_eip); - - m_CPL = (m_sreg[SS].flags >> 5) & 3; -// printf("286 Task Switch from selector %04x to %04x\n",old_task,selector); -} - -void i386_device::i386_task_switch(uint16_t selector, uint8_t nested) -{ - uint32_t tss; - I386_SREG seg; - uint16_t old_task; - uint8_t ar_byte; // access rights byte - uint32_t oldcr3 = m_cr[3]; - - /* TODO: Task State Segment privilege checks */ - - /* For tasks that aren't nested, clear the busy bit in the task's descriptor */ - if(nested == 0) - { - if(m_task.segment & 0x0004) - { - ar_byte = READ8(m_ldtr.base + (m_task.segment & ~0x0007) + 5); - WRITE8(m_ldtr.base + (m_task.segment & ~0x0007) + 5,ar_byte & ~0x02); - } - else - { - ar_byte = READ8(m_gdtr.base + (m_task.segment & ~0x0007) + 5); - WRITE8(m_gdtr.base + (m_task.segment & ~0x0007) + 5,ar_byte & ~0x02); - } - } - - /* Save the state of the current task in the current TSS (TR register base) */ - tss = m_task.base; - WRITE32(tss+0x1c,m_cr[3]); // correct? - WRITE32(tss+0x20,m_eip); - WRITE32(tss+0x24,get_flags()); - WRITE32(tss+0x28,REG32(EAX)); - WRITE32(tss+0x2c,REG32(ECX)); - WRITE32(tss+0x30,REG32(EDX)); - WRITE32(tss+0x34,REG32(EBX)); - WRITE32(tss+0x38,REG32(ESP)); - WRITE32(tss+0x3c,REG32(EBP)); - WRITE32(tss+0x40,REG32(ESI)); - WRITE32(tss+0x44,REG32(EDI)); - WRITE32(tss+0x48,m_sreg[ES].selector); - WRITE32(tss+0x4c,m_sreg[CS].selector); - WRITE32(tss+0x50,m_sreg[SS].selector); - WRITE32(tss+0x54,m_sreg[DS].selector); - WRITE32(tss+0x58,m_sreg[FS].selector); - WRITE32(tss+0x5c,m_sreg[GS].selector); - - old_task = m_task.segment; - - /* Load task register with the selector of the incoming task */ - m_task.segment = selector; - memset(&seg, 0, sizeof(seg)); - seg.selector = m_task.segment; - i386_load_protected_mode_segment(&seg,nullptr); - m_task.limit = seg.limit; - m_task.base = seg.base; - m_task.flags = seg.flags; - - /* Set TS bit in CR0 */ - m_cr[0] |= 0x08; - - /* Load incoming task state from the new task's TSS */ - tss = m_task.base; - m_ldtr.segment = READ32(tss+0x60) & 0xffff; - seg.selector = m_ldtr.segment; - i386_load_protected_mode_segment(&seg,nullptr); - m_ldtr.limit = seg.limit; - m_ldtr.base = seg.base; - m_ldtr.flags = seg.flags; - m_eip = READ32(tss+0x20); - set_flags(READ32(tss+0x24)); - REG32(EAX) = READ32(tss+0x28); - REG32(ECX) = READ32(tss+0x2c); - REG32(EDX) = READ32(tss+0x30); - REG32(EBX) = READ32(tss+0x34); - REG32(ESP) = READ32(tss+0x38); - REG32(EBP) = READ32(tss+0x3c); - REG32(ESI) = READ32(tss+0x40); - REG32(EDI) = READ32(tss+0x44); - m_sreg[ES].selector = READ32(tss+0x48) & 0xffff; - i386_load_segment_descriptor(ES); - m_sreg[CS].selector = READ32(tss+0x4c) & 0xffff; - i386_load_segment_descriptor(CS); - m_sreg[SS].selector = READ32(tss+0x50) & 0xffff; - i386_load_segment_descriptor(SS); - m_sreg[DS].selector = READ32(tss+0x54) & 0xffff; - i386_load_segment_descriptor(DS); - m_sreg[FS].selector = READ32(tss+0x58) & 0xffff; - i386_load_segment_descriptor(FS); - m_sreg[GS].selector = READ32(tss+0x5c) & 0xffff; - i386_load_segment_descriptor(GS); - /* For nested tasks, we write the outgoing task's selector to the back-link field of the new TSS, - and set the NT flag in the EFLAGS register before setting cr3 as the old tss address might be gone */ - if(nested != 0) - { - WRITE32(tss+0,old_task); - m_NT = 1; - } - m_cr[3] = READ32(tss+0x1c); // CR3 (PDBR) - if(oldcr3 != m_cr[3]) - d_vtlb->vtlb_flush_dynamic(); - - /* Set the busy bit in the new task's descriptor */ - if(selector & 0x0004) - { - ar_byte = READ8(m_ldtr.base + (selector & ~0x0007) + 5); - WRITE8(m_ldtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02); - } - else - { - ar_byte = READ8(m_gdtr.base + (selector & ~0x0007) + 5); - WRITE8(m_gdtr.base + (selector & ~0x0007) + 5,ar_byte | 0x02); - } - - CHANGE_PC(m_eip); - - m_CPL = (m_sreg[SS].flags >> 5) & 3; -// printf("386 Task Switch from selector %04x to %04x\n",old_task,selector); -} - -void i386_device::i386_check_irq_line() -{ - if(!m_smm && m_smi) - { - pentium_smi(); - return; - } - - /* Check if the interrupts are enabled */ - if ( (m_irq_state) && m_IF ) - { - m_cycles -= 2; - int irqnum = d_pic->get_intr_ack(); - try { - i386_trap(irqnum, 1, 0); - } catch(uint64_t e) { - //logdebug("EXCEPTION %08X VIA INTERRUPT/TRAP HANDLING IRQ=%02Xh(%d) ADDR=%08X\n", e, irqnum, irqnum, m_pc); - } - m_irq_state = 0; - } -} - -bool i386_device::bios_int_x86(int num) -{ - if(d_bios == NULL) return false; - uint16_t regs[10], sregs[4]; // ToDo: Full calling - regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); - regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); - regs[8] = 0x0000; regs[9] = 0x0000; - sregs[0] = m_sreg[ES].selector; sregs[1] = m_sreg[CS].selector; - sregs[2] = m_sreg[SS].selector; sregs[3] = m_sreg[DS].selector; - int32_t ZeroFlag = m_ZF, CarryFlag = m_CF; - if(d_bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag, &m_cycles, &total_cycles)) { - REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; - REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; - m_ZF = (UINT8)ZeroFlag; m_CF = (UINT8)CarryFlag; - CYCLES(CYCLES_IRET); - if((regs[8] != 0x0000) || (regs[9] != 0x0000)) { - uint32_t hi = regs[9]; - uint32_t lo = regs[8]; - uint32_t addr = (hi << 16) | lo; - m_eip = addr; - } - return true; - } - return false; -} - - -bool i386_device::bios_call_far_x86(uint32_t address) -{ - if(d_bios == NULL) return false; - if(((m_cr[0] & 0x0001) != 0) && (m_VM == 0)) return false; // Return if (!(VM8086) && (Protected)) - - uint16_t regs[10], sregs[4]; // ToDo: Full calling - regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); - regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); - regs[8] = 0x0000; regs[9] = 0x0000; - sregs[0] = m_sreg[ES].selector; sregs[1] = m_sreg[CS].selector; - sregs[2] = m_sreg[SS].selector; sregs[3] = m_sreg[DS].selector; - int32_t ZeroFlag = m_ZF, CarryFlag = m_CF; - if(d_bios->bios_call_far_i86(address, regs, sregs, &ZeroFlag, &CarryFlag, &m_cycles, &total_cycles)) { - REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; - REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; - m_ZF = (UINT8)ZeroFlag; m_CF = (UINT8)CarryFlag; - CYCLES(CYCLES_RET_INTERSEG); - if((regs[8] != 0x0000) || (regs[9] != 0x0000)) { - uint32_t hi = regs[9]; - uint32_t lo = regs[8]; - uint32_t addr = (hi << 16) | lo; - m_eip = addr; - } - return true; - } - return false; -} - -bool i386_device::bios_trap_x86(uint32_t address, int &stat) -{ - if(d_bios == NULL) return false; - if(((m_cr[0] & 0x0001) != 0) && (m_VM == 0)) return false; // Return if (!(VM8086) && (Protected)) - - uint16_t regs[10], sregs[4]; // ToDo: Full calling - regs[0] = REG16(AX); regs[1] = REG16(CX); regs[2] = REG16(DX); regs[3] = REG16(BX); - regs[4] = REG16(SP); regs[5] = REG16(BP); regs[6] = REG16(SI); regs[7] = REG16(DI); - regs[8] = 0x0000; regs[9] = 0x0000; - sregs[0] = m_sreg[ES].selector; sregs[1] = m_sreg[CS].selector; - sregs[2] = m_sreg[SS].selector; sregs[3] = m_sreg[DS].selector; - int32_t ZeroFlag = m_ZF, CarryFlag = m_CF; - stat = 0; - if(d_bios->bios_call_far_i86(address, regs, sregs, &ZeroFlag, &CarryFlag, &m_cycles, &total_cycles)) { - REG16(AX) = regs[0]; REG16(CX) = regs[1]; REG16(DX) = regs[2]; REG16(BX) = regs[3]; - REG16(SP) = regs[4]; REG16(BP) = regs[5]; REG16(SI) = regs[6]; REG16(DI) = regs[7]; - m_ZF = (UINT8)ZeroFlag; m_CF = (UINT8)CarryFlag; - CYCLES(CYCLES_RET_INTERSEG); - if((regs[8] != 0x0000) || (regs[9] != 0x0000)) { - uint32_t hi = regs[9]; - uint32_t lo = regs[8]; - uint32_t addr = (hi << 16) | lo; - m_eip = addr; - } - stat = 1; - return true; - } - return false; -} - -void i386_device::i386_protected_mode_jump(uint16_t seg, uint32_t off, int indirect, int operand32) -{ - I386_SREG desc; - I386_CALL_GATE call_gate; - uint8_t CPL,DPL,RPL; - uint8_t SetRPL; - uint16_t segment = seg; - uint32_t offset = off; - - /* Check selector is not null */ - if((segment & ~0x03) == 0) - { - logerror("JMP: Segment is null.\n"); - FAULT(FAULT_GP,0) - } - /* Selector is within descriptor table limit */ - if((segment & 0x04) == 0) - { - /* check GDT limit */ - if((segment & ~0x07) > (m_gdtr.limit)) - { - logerror("JMP: Segment is past GDT limit.\n"); - FAULT(FAULT_GP,segment & 0xfffc) - } - } - else - { - /* check LDT limit */ - if((segment & ~0x07) > (m_ldtr.limit)) - { - logerror("JMP: Segment is past LDT limit.\n"); - FAULT(FAULT_GP,segment & 0xfffc) - } - } - /* Determine segment type */ - memset(&desc, 0, sizeof(desc)); - desc.selector = segment; - i386_load_protected_mode_segment(&desc,nullptr); - CPL = m_CPL; // current privilege level - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - RPL = segment & 0x03; // requested privilege level - if((desc.flags & 0x0018) == 0x0018) - { - /* code segment */ - if((desc.flags & 0x0004) == 0) - { - /* non-conforming */ - if(RPL > CPL) - { - logerror("JMP: RPL %i is less than CPL %i\n",RPL,CPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - if(DPL != CPL) - { - logerror("JMP: DPL %i is not equal CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - } - else - { - /* conforming */ - if(DPL > CPL) - { - logerror("JMP: DPL %i is less than CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - } - SetRPL = 1; - if((desc.flags & 0x0080) == 0) - { - logerror("JMP: Segment is not present\n"); - FAULT(FAULT_NP,segment & 0xfffc) - } - if(offset > desc.limit) - { - logerror("JMP: Offset is past segment limit\n"); - FAULT(FAULT_GP,0) - } - } - else - { - if((desc.flags & 0x0010) != 0) - { - logerror("JMP: Segment is a data segment\n"); - FAULT(FAULT_GP,segment & 0xfffc) // #GP (cannot execute code in a data segment) - } - else - { - switch(desc.flags & 0x000f) - { - case 0x01: // 286 Available TSS - case 0x09: // 386 Available TSS - logerror("JMP: Available 386 TSS at %08x\n",m_pc); - memset(&desc, 0, sizeof(desc)); - desc.selector = segment; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - if(DPL < CPL) - { - logerror("JMP: TSS: DPL %i is less than CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - if(DPL < RPL) - { - logerror("JMP: TSS: DPL %i is less than TSS RPL %i\n",DPL,RPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - if((desc.flags & 0x0080) == 0) - { - logerror("JMP: TSS: Segment is not present\n"); - FAULT(FAULT_GP,segment & 0xfffc) - } - if(desc.flags & 0x0008) - i386_task_switch(desc.selector,0); - else - i286_task_switch(desc.selector,0); - return; - case 0x04: // 286 Call Gate - case 0x0c: // 386 Call Gate - //logerror("JMP: Call gate at %08x\n",m_pc); - SetRPL = 1; - memset(&call_gate, 0, sizeof(call_gate)); - call_gate.segment = segment; - i386_load_call_gate(&call_gate); - DPL = call_gate.dpl; - if(DPL < CPL) - { - logerror("JMP: Call Gate: DPL %i is less than CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - if(DPL < RPL) - { - logerror("JMP: Call Gate: DPL %i is less than RPL %i\n",DPL,RPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - if((desc.flags & 0x0080) == 0) - { - logerror("JMP: Call Gate: Segment is not present\n"); - FAULT(FAULT_NP,segment & 0xfffc) - } - /* Now we examine the segment that the call gate refers to */ - if(call_gate.selector == 0) - { - logerror("JMP: Call Gate: Gate selector is null\n"); - FAULT(FAULT_GP,0) - } - if(call_gate.selector & 0x04) - { - if((call_gate.selector & ~0x07) > m_ldtr.limit) - { - logerror("JMP: Call Gate: Gate Selector is past LDT segment limit\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - } - else - { - if((call_gate.selector & ~0x07) > m_gdtr.limit) - { - logerror("JMP: Call Gate: Gate Selector is past GDT segment limit\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - } - desc.selector = call_gate.selector; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; - if((desc.flags & 0x0018) != 0x18) - { - logerror("JMP: Call Gate: Gate does not point to a code segment\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - if((desc.flags & 0x0004) == 0) - { // non-conforming - if(DPL != CPL) - { - logerror("JMP: Call Gate: Gate DPL does not equal CPL\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - } - else - { // conforming - if(DPL > CPL) - { - logerror("JMP: Call Gate: Gate DPL is greater than CPL\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - } - if((desc.flags & 0x0080) == 0) - { - logerror("JMP: Call Gate: Gate Segment is not present\n"); - FAULT(FAULT_NP,call_gate.selector & 0xfffc) - } - if(call_gate.offset > desc.limit) - { - logerror("JMP: Call Gate: Gate offset is past Gate segment limit\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - segment = call_gate.selector; - offset = call_gate.offset; - break; - case 0x05: // Task Gate - logerror("JMP: Task gate at %08x\n",m_pc); - memset(&call_gate, 0, sizeof(call_gate)); - call_gate.segment = segment; - i386_load_call_gate(&call_gate); - DPL = call_gate.dpl; - if(DPL < CPL) - { - logerror("JMP: Task Gate: Gate DPL %i is less than CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - if(DPL < RPL) - { - logerror("JMP: Task Gate: Gate DPL %i is less than CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,segment & 0xfffc) - } - if(call_gate.present == 0) - { - logerror("JMP: Task Gate: Gate is not present.\n"); - FAULT(FAULT_GP,segment & 0xfffc) - } - /* Check the TSS that the task gate points to */ - desc.selector = call_gate.selector; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - RPL = call_gate.selector & 0x03; // requested privilege level - if(call_gate.selector & 0x04) - { - logerror("JMP: Task Gate TSS: TSS must be global.\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - else - { - if((call_gate.selector & ~0x07) > m_gdtr.limit) - { - logerror("JMP: Task Gate TSS: TSS is past GDT limit.\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - } - if((call_gate.ar & 0x000f) == 0x0009 || (call_gate.ar & 0x000f) == 0x0001) - { - logerror("JMP: Task Gate TSS: Segment is not an available TSS.\n"); - FAULT(FAULT_GP,call_gate.selector & 0xfffc) - } - if(call_gate.present == 0) - { - logerror("JMP: Task Gate TSS: TSS is not present.\n"); - FAULT(FAULT_NP,call_gate.selector & 0xfffc) - } - if(call_gate.ar & 0x08) - i386_task_switch(call_gate.selector,0); - else - i286_task_switch(call_gate.selector,0); - return; - default: // invalid segment type - logerror("JMP: Invalid segment type (%i) to jump to.\n",desc.flags & 0x000f); - FAULT(FAULT_GP,segment & 0xfffc) - } - } - } - - if(SetRPL != 0) - segment = (segment & ~0x03) | m_CPL; - if(operand32 == 0) - m_eip = offset & 0x0000ffff; - else - m_eip = offset; - m_sreg[CS].selector = segment; - m_performed_intersegment_jump = 1; - i386_load_segment_descriptor(CS); - CHANGE_PC(m_eip); -} - -void i386_device::i386_protected_mode_call(uint16_t seg, uint32_t off, int indirect, int operand32) -{ - I386_SREG desc; - I386_CALL_GATE gate; - uint8_t SetRPL; - uint8_t CPL, DPL, RPL; - uint16_t selector = seg; - uint32_t offset = off; - int x; - - if((selector & ~0x03) == 0) - { - logerror("CALL (%08x): Selector is null.\n",m_pc); - FAULT(FAULT_GP,0) // #GP(0) - } - if(selector & 0x04) - { - if((selector & ~0x07) > m_ldtr.limit) - { - logerror("CALL: Selector is past LDT limit.\n"); - FAULT(FAULT_GP,selector & ~0x03) // #GP(selector) - } - } - else - { - if((selector & ~0x07) > m_gdtr.limit) - { - logerror("CALL: Selector is past GDT limit.\n"); - FAULT(FAULT_GP,selector & ~0x03) // #GP(selector) - } - } - - /* Determine segment type */ - memset(&desc, 0, sizeof(desc)); - desc.selector = selector; - i386_load_protected_mode_segment(&desc,nullptr); - CPL = m_CPL; // current privilege level - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - RPL = selector & 0x03; // requested privilege level - if((desc.flags & 0x0018) == 0x18) // is a code segment - { - if(desc.flags & 0x0004) - { - /* conforming */ - if(DPL > CPL) - { - logerror("CALL: Code segment DPL %i is greater than CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,selector & ~0x03) // #GP(selector) - } - } - else - { - /* non-conforming */ - if(RPL > CPL) - { - logerror("CALL: RPL %i is greater than CPL %i\n",RPL,CPL); - FAULT(FAULT_GP,selector & ~0x03) // #GP(selector) - } - if(DPL != CPL) - { - logerror("CALL: Code segment DPL %i is not equal to CPL %i\n",DPL,CPL); - FAULT(FAULT_GP,selector & ~0x03) // #GP(selector) - } - } - SetRPL = 1; - if((desc.flags & 0x0080) == 0) - { - logerror("CALL (%08x): Code segment is not present.\n",m_pc); - FAULT(FAULT_NP,selector & ~0x03) // #NP(selector) - } - if (operand32 != 0) // if 32-bit - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) - 8 : (REG16(SP) - 8) & 0xffff); - if(i386_limit_check(SS, offset)) - { - logerror("CALL (%08x): Stack has no room for return address.\n",m_pc); - FAULT(FAULT_SS,0) // #SS(0) - } - } - else - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) - 4 : (REG16(SP) - 4) & 0xffff); - if(i386_limit_check(SS, offset)) - { - logerror("CALL (%08x): Stack has no room for return address.\n",m_pc); - FAULT(FAULT_SS,0) // #SS(0) - } - } - if(offset > desc.limit) - { - logerror("CALL: EIP is past segment limit.\n"); - FAULT(FAULT_GP,0) // #GP(0) - } - } - else - { - /* special segment type */ - if(desc.flags & 0x0010) - { - logerror("CALL: Segment is a data segment.\n"); - FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector) - } - else - { - switch(desc.flags & 0x000f) - { - case 0x01: // Available 286 TSS - case 0x09: // Available 386 TSS - logerror("CALL: Available TSS at %08x\n",m_pc); - if(DPL < CPL) - { - logerror("CALL: TSS: DPL is less than CPL.\n"); - FAULT(FAULT_TS,selector & ~0x03) // #TS(selector) - } - if(DPL < RPL) - { - logerror("CALL: TSS: DPL is less than RPL.\n"); - FAULT(FAULT_TS,selector & ~0x03) // #TS(selector) - } - if(desc.flags & 0x0002) - { - logerror("CALL: TSS: TSS is busy.\n"); - FAULT(FAULT_TS,selector & ~0x03) // #TS(selector) - } - if((desc.flags & 0x0080) == 0) - { - logerror("CALL: TSS: Segment %02x is not present.\n",selector); - FAULT(FAULT_NP,selector & ~0x03) // #NP(selector) - } - if(desc.flags & 0x08) - i386_task_switch(desc.selector,1); - else - i286_task_switch(desc.selector,1); - return; - case 0x04: // 286 call gate - case 0x0c: // 386 call gate - if((desc.flags & 0x000f) == 0x04) - operand32 = 0; - else - operand32 = 1; - memset(&gate, 0, sizeof(gate)); - gate.segment = selector; - i386_load_call_gate(&gate); - DPL = gate.dpl; - //logerror("CALL: Call gate at %08x (%i parameters)\n",m_pc,gate.dword_count); - if(DPL < CPL) - { - logerror("CALL: Call gate DPL %i is less than CPL %i.\n",DPL,CPL); - FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector) - } - if(DPL < RPL) - { - logerror("CALL: Call gate DPL %i is less than RPL %i.\n",DPL,RPL); - FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector) - } - if(gate.present == 0) - { - logerror("CALL: Call gate is not present.\n"); - FAULT(FAULT_NP,desc.selector & ~0x03) // #GP(selector) - } - desc.selector = gate.selector; - if((gate.selector & ~0x03) == 0) - { - logerror("CALL: Call gate: Segment is null.\n"); - FAULT(FAULT_GP,0) // #GP(0) - } - if(desc.selector & 0x04) - { - if((desc.selector & ~0x07) > m_ldtr.limit) - { - logerror("CALL: Call gate: Segment is past LDT limit\n"); - FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector) - } - } - else - { - if((desc.selector & ~0x07) > m_gdtr.limit) - { - logerror("CALL: Call gate: Segment is past GDT limit\n"); - FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector) - } - } - i386_load_protected_mode_segment(&desc,nullptr); - if((desc.flags & 0x0018) != 0x18) - { - logerror("CALL: Call gate: Segment is not a code segment.\n"); - FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector) - } - DPL = ((desc.flags >> 5) & 0x03); - if(DPL > CPL) - { - logerror("CALL: Call gate: Segment DPL %i is greater than CPL %i.\n",DPL,CPL); - FAULT(FAULT_GP,desc.selector & ~0x03) // #GP(selector) - } - if((desc.flags & 0x0080) == 0) - { - logerror("CALL (%08x): Code segment is not present.\n",m_pc); - FAULT(FAULT_NP,desc.selector & ~0x03) // #NP(selector) - } - if(DPL < CPL && (desc.flags & 0x0004) == 0) - { - I386_SREG stack; - I386_SREG temp; - uint32_t oldSS,oldESP; - /* more privilege */ - /* Check new SS segment for privilege level from TSS */ - memset(&stack, 0, sizeof(stack)); - stack.selector = i386_get_stack_segment(DPL); - i386_load_protected_mode_segment(&stack,nullptr); - if((stack.selector & ~0x03) == 0) - { - logerror("CALL: Call gate: TSS selector is null\n"); - FAULT(FAULT_TS,0) // #TS(0) - } - if(stack.selector & 0x04) - { - if((stack.selector & ~0x07) > m_ldtr.limit) - { - logerror("CALL: Call gate: TSS selector is past LDT limit\n"); - FAULT(FAULT_TS,stack.selector) // #TS(SS selector) - } - } - else - { - if((stack.selector & ~0x07) > m_gdtr.limit) - { - logerror("CALL: Call gate: TSS selector is past GDT limit\n"); - FAULT(FAULT_TS,stack.selector) // #TS(SS selector) - } - } - if((stack.selector & 0x03) != DPL) - { - logerror("CALL: Call gate: Stack selector RPL does not equal code segment DPL %i\n",DPL); - FAULT(FAULT_TS,stack.selector) // #TS(SS selector) - } - if(((stack.flags >> 5) & 0x03) != DPL) - { - logerror("CALL: Call gate: Stack DPL does not equal code segment DPL %i\n",DPL); - FAULT(FAULT_TS,stack.selector) // #TS(SS selector) - } - if((stack.flags & 0x0018) != 0x10 && (stack.flags & 0x0002)) - { - logerror("CALL: Call gate: Stack segment is not a writable data segment\n"); - FAULT(FAULT_TS,stack.selector) // #TS(SS selector) - } - if((stack.flags & 0x0080) == 0) - { - logerror("CALL: Call gate: Stack segment is not present\n"); - FAULT(FAULT_SS,stack.selector) // #SS(SS selector) - } - uint32_t newESP = i386_get_stack_ptr(DPL); - if(!stack.d) - { - newESP &= 0xffff; - } - if(operand32 != 0) - { - if(newESP < ((gate.dword_count & 0x1f) + 16)) - { - logerror("CALL: Call gate: New stack has no room for 32-bit return address and parameters.\n"); - FAULT(FAULT_SS,0) // #SS(0) - } - if(gate.offset > desc.limit) - { - logerror("CALL: Call gate: EIP is past segment limit.\n"); - FAULT(FAULT_GP,0) // #GP(0) - } - } - else - { - if(newESP < ((gate.dword_count & 0x1f) + 8)) - { - logerror("CALL: Call gate: New stack has no room for 16-bit return address and parameters.\n"); - FAULT(FAULT_SS,0) // #SS(0) - } - if((gate.offset & 0xffff) > desc.limit) - { - logerror("CALL: Call gate: IP is past segment limit.\n"); - FAULT(FAULT_GP,0) // #GP(0) - } - } - selector = gate.selector; - offset = gate.offset; - - m_CPL = (stack.flags >> 5) & 0x03; - /* check for page fault at new stack */ - WRITE_TEST(stack.base+newESP-1); - /* switch to new stack */ - oldSS = m_sreg[SS].selector; - m_sreg[SS].selector = i386_get_stack_segment(m_CPL); - if(operand32 != 0) - { - oldESP = REG32(ESP); - } - else - { - oldESP = REG16(SP); - } - i386_load_segment_descriptor(SS ); - REG32(ESP) = newESP; - - if(operand32 != 0) - { - PUSH32SEG(oldSS); - PUSH32(oldESP); - } - else - { - PUSH16(oldSS); - PUSH16(oldESP & 0xffff); - } - - memset(&temp, 0, sizeof(temp)); - temp.selector = oldSS; - i386_load_protected_mode_segment(&temp,nullptr); - /* copy parameters from old stack to new stack */ - for(x=(gate.dword_count & 0x1f)-1;x>=0;x--) - { - uint32_t addr = oldESP + (operand32?(x*4):(x*2)); - addr = temp.base + (temp.d?addr:(addr&0xffff)); - if(operand32) - PUSH32(READ32(addr)); - else - PUSH16(READ16(addr)); - } - SetRPL = 1; - } - else - { - /* same privilege */ - if (operand32 != 0) // if 32-bit - { - uint32_t stkoff = (STACK_32BIT ? REG32(ESP) - 8 : (REG16(SP) - 8) & 0xffff); - if(i386_limit_check(SS, stkoff)) - { - logerror("CALL: Stack has no room for return address.\n"); - FAULT(FAULT_SS,0) // #SS(0) - } - selector = gate.selector; - offset = gate.offset; - } - else - { - uint32_t stkoff = (STACK_32BIT ? REG32(ESP) - 4 : (REG16(SP) - 4) & 0xffff); - if(i386_limit_check(SS, stkoff)) - { - logerror("CALL: Stack has no room for return address.\n"); - FAULT(FAULT_SS,0) // #SS(0) - } - selector = gate.selector; - offset = gate.offset & 0xffff; - } - if(offset > desc.limit) - { - logerror("CALL: EIP is past segment limit.\n"); - FAULT(FAULT_GP,0) // #GP(0) - } - SetRPL = 1; - } - break; - case 0x05: // task gate - logerror("CALL: Task gate at %08x\n",m_pc); - memset(&gate, 0, sizeof(gate)); - gate.segment = selector; - i386_load_call_gate(&gate); - DPL = gate.dpl; - if(DPL < CPL) - { - logerror("CALL: Task Gate: Gate DPL is less than CPL.\n"); - FAULT(FAULT_TS,selector & ~0x03) // #TS(selector) - } - if(DPL < RPL) - { - logerror("CALL: Task Gate: Gate DPL is less than RPL.\n"); - FAULT(FAULT_TS,selector & ~0x03) // #TS(selector) - } - if((gate.ar & 0x0080) == 0) - { - logerror("CALL: Task Gate: Gate is not present.\n"); - FAULT(FAULT_NP,selector & ~0x03) // #NP(selector) - } - /* Check the TSS that the task gate points to */ - desc.selector = gate.selector; - i386_load_protected_mode_segment(&desc,nullptr); - if(gate.selector & 0x04) - { - logerror("CALL: Task Gate: TSS is not global.\n"); - FAULT(FAULT_TS,gate.selector & ~0x03) // #TS(selector) - } - else - { - if((gate.selector & ~0x07) > m_gdtr.limit) - { - logerror("CALL: Task Gate: TSS is past GDT limit.\n"); - FAULT(FAULT_TS,gate.selector & ~0x03) // #TS(selector) - } - } - if(desc.flags & 0x0002) - { - logerror("CALL: Task Gate: TSS is busy.\n"); - FAULT(FAULT_TS,gate.selector & ~0x03) // #TS(selector) - } - if((desc.flags & 0x0080) == 0) - { - logerror("CALL: Task Gate: TSS is not present.\n"); - FAULT(FAULT_NP,gate.selector & ~0x03) // #TS(selector) - } - if(desc.flags & 0x08) - i386_task_switch(desc.selector,1); // with nesting - else - i286_task_switch(desc.selector,1); - return; - default: - logerror("CALL: Invalid special segment type (%i) to jump to.\n",desc.flags & 0x000f); - FAULT(FAULT_GP,selector & ~0x07) // #GP(selector) - } - } - } - - if(SetRPL != 0) - selector = (selector & ~0x03) | m_CPL; - - uint32_t tempSP = REG32(ESP); - try - { - // this is ugly but the alternative is worse - if(operand32 == 0) - { - /* 16-bit operand size */ - PUSH16(m_sreg[CS].selector ); - PUSH16(m_eip & 0x0000ffff ); - m_sreg[CS].selector = selector; - m_performed_intersegment_jump = 1; - m_eip = offset; - i386_load_segment_descriptor(CS); - } - else - { - /* 32-bit operand size */ - PUSH32SEG(m_sreg[CS].selector ); - PUSH32(m_eip ); - m_sreg[CS].selector = selector; - m_performed_intersegment_jump = 1; - m_eip = offset; - i386_load_segment_descriptor(CS ); - } - } - catch(uint64_t e) - { - REG32(ESP) = tempSP; - throw e; - } - - CHANGE_PC(m_eip); -} - -void i386_device::i386_protected_mode_retf(uint8_t count, uint8_t operand32) -{ - uint32_t newCS, newEIP; - I386_SREG desc; - uint8_t CPL, RPL, DPL; - - uint32_t ea = i386_translate(SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0); - - if(operand32 == 0) - { - newEIP = READ16(ea) & 0xffff; - newCS = READ16(ea+2) & 0xffff; - } - else - { - newEIP = READ32(ea); - newCS = READ32(ea+4) & 0xffff; - } - - memset(&desc, 0, sizeof(desc)); - desc.selector = newCS; - i386_load_protected_mode_segment(&desc,nullptr); - CPL = m_CPL; // current privilege level - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - RPL = newCS & 0x03; - - if(RPL < CPL) - { - logerror("RETF (%08x): Return segment RPL is less than CPL.\n",m_pc); - FAULT(FAULT_GP,newCS & ~0x03) - } - - if(RPL == CPL) - { - /* same privilege level */ - if((newCS & ~0x03) == 0) - { - logerror("RETF: Return segment is null.\n"); - FAULT(FAULT_GP,0) - } - if(newCS & 0x04) - { - if((newCS & ~0x07) >= m_ldtr.limit) - { - logerror("RETF: Return segment is past LDT limit.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - else - { - if((newCS & ~0x07) >= m_gdtr.limit) - { - logerror("RETF: Return segment is past GDT limit.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - if((desc.flags & 0x0018) != 0x0018) - { - logerror("RETF: Return segment is not a code segment.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - if(desc.flags & 0x0004) - { - if(DPL > RPL) - { - logerror("RETF: Conforming code segment DPL is greater than CS RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - else - { - if(DPL != RPL) - { - logerror("RETF: Non-conforming code segment DPL does not equal CS RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - if((desc.flags & 0x0080) == 0) - { - logerror("RETF (%08x): Code segment is not present.\n",m_pc); - FAULT(FAULT_NP,newCS & ~0x03) - } - if(newEIP > desc.limit) - { - logerror("RETF: EIP is past code segment limit.\n"); - FAULT(FAULT_GP,0) - } - if(operand32 == 0) - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+count+3) != 0) - { - logerror("RETF (%08x): SP is past stack segment limit.\n",m_pc); - FAULT(FAULT_SS,0) - } - } - else - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+count+7) != 0) - { - logerror("RETF: ESP is past stack segment limit.\n"); - FAULT(FAULT_SS,0) - } - } - if(STACK_32BIT) - REG32(ESP) += (operand32 ? 8 : 4) + count; - else - REG16(SP) += (operand32 ? 8 : 4) + count; - } - else if(RPL > CPL) - { - uint32_t newSS, newESP; // when changing privilege - /* outer privilege level */ - if(operand32 == 0) - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+count+7) != 0) - { - logerror("RETF (%08x): SP is past stack segment limit.\n",m_pc); - FAULT(FAULT_SS,0) - } - } - else - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+count+15) != 0) - { - logerror("RETF: ESP is past stack segment limit.\n"); - FAULT(FAULT_SS,0) - } - } - /* Check CS selector and descriptor */ - if((newCS & ~0x03) == 0) - { - logerror("RETF: CS segment is null.\n"); - FAULT(FAULT_GP,0) - } - if(newCS & 0x04) - { - if((newCS & ~0x07) >= m_ldtr.limit) - { - logerror("RETF: CS segment selector is past LDT limit.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - else - { - if((newCS & ~0x07) >= m_gdtr.limit) - { - logerror("RETF: CS segment selector is past GDT limit.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - if((desc.flags & 0x0018) != 0x0018) - { - logerror("RETF: CS segment is not a code segment.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - if(desc.flags & 0x0004) - { - if(DPL > RPL) - { - logerror("RETF: Conforming CS segment DPL is greater than return selector RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - else - { - if(DPL != RPL) - { - logerror("RETF: Non-conforming CS segment DPL is not equal to return selector RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - if((desc.flags & 0x0080) == 0) - { - logerror("RETF: CS segment is not present.\n"); - FAULT(FAULT_NP,newCS & ~0x03) - } - if(newEIP > desc.limit) - { - logerror("RETF: EIP is past return CS segment limit.\n"); - FAULT(FAULT_GP,0) - } - - if(operand32 == 0) - { - ea += count+4; - newESP = READ16(ea) & 0xffff; - newSS = READ16(ea+2) & 0xffff; - } - else - { - ea += count+8; - newESP = READ32(ea); - newSS = READ32(ea+4) & 0xffff; - } - - /* Check SS selector and descriptor */ - desc.selector = newSS; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - if((newSS & ~0x07) == 0) - { - logerror("RETF: SS segment is null.\n"); - FAULT(FAULT_GP,0) - } - if(newSS & 0x04) - { - if((newSS & ~0x07) > m_ldtr.limit) - { - logerror("RETF (%08x): SS segment selector is past LDT limit.\n",m_pc); - FAULT(FAULT_GP,newSS & ~0x03) - } - } - else - { - if((newSS & ~0x07) > m_gdtr.limit) - { - logerror("RETF (%08x): SS segment selector is past GDT limit.\n",m_pc); - FAULT(FAULT_GP,newSS & ~0x03) - } - } - if((newSS & 0x03) != RPL) - { - logerror("RETF: SS segment RPL is not equal to CS segment RPL.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - if((desc.flags & 0x0018) != 0x0010 || (desc.flags & 0x0002) == 0) - { - logerror("RETF: SS segment is not a writable data segment.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - if(((desc.flags >> 5) & 0x03) != RPL) - { - logerror("RETF: SS DPL is not equal to CS segment RPL.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - if((desc.flags & 0x0080) == 0) - { - logerror("RETF: SS segment is not present.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - m_CPL = newCS & 0x03; - - /* Load new SS:(E)SP */ - if(operand32 == 0) - REG16(SP) = (newESP+count) & 0xffff; - else - REG32(ESP) = newESP+count; - m_sreg[SS].selector = newSS; - i386_load_segment_descriptor(SS ); - - /* Check that DS, ES, FS and GS are valid for the new privilege level */ - i386_check_sreg_validity(DS); - i386_check_sreg_validity(ES); - i386_check_sreg_validity(FS); - i386_check_sreg_validity(GS); - } - - /* Load new CS:(E)IP */ - if(operand32 == 0) - m_eip = newEIP & 0xffff; - else - m_eip = newEIP; - m_sreg[CS].selector = newCS; - i386_load_segment_descriptor(CS ); - CHANGE_PC(m_eip); -} - -void i386_device::i386_protected_mode_iret(int operand32) -{ - uint32_t newCS, newEIP; - uint32_t newSS, newESP; // when changing privilege - I386_SREG desc,stack; - uint8_t CPL, RPL, DPL; - uint32_t newflags; - uint8_t IOPL = m_IOP1 | (m_IOP2 << 1); - - CPL = m_CPL; - uint32_t ea = i386_translate(SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0); - if(operand32 == 0) - { - newEIP = READ16(ea) & 0xffff; - newCS = READ16(ea+2) & 0xffff; - newflags = READ16(ea+4) & 0xffff; - } - else - { - newEIP = READ32(ea); - newCS = READ32(ea+4) & 0xffff; - newflags = READ32(ea+8); - } - - if(V8086_MODE) - { - uint32_t oldflags = get_flags(); - if(IOPL != 3) - { - logerror("IRET (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",m_pc); - FAULT(FAULT_GP,0) - } - if(operand32 == 0) - { - m_eip = newEIP & 0xffff; - m_sreg[CS].selector = newCS & 0xffff; - newflags &= ~(3<<12); - newflags |= (((oldflags>>12)&3)<<12); // IOPL cannot be changed in V86 mode - set_flags((newflags & 0xffff) | (oldflags & ~0xffff)); - REG16(SP) += 6; - } - else - { - m_eip = newEIP; - m_sreg[CS].selector = newCS & 0xffff; - newflags &= ~(3<<12); - newflags |= 0x20000 | (((oldflags>>12)&3)<<12); // IOPL and VM cannot be changed in V86 mode - set_flags(newflags); - REG32(ESP) += 12; - } - } - else if(NESTED_TASK) - { - uint32_t task = READ32(m_task.base); - /* Task Return */ - logerror("IRET (%08x): Nested task return.\n",m_pc); - /* Check back-link selector in TSS */ - if(task & 0x04) - { - logerror("IRET: Task return: Back-linked TSS is not in GDT.\n"); - FAULT(FAULT_TS,task & ~0x03) - } - if((task & ~0x07) >= m_gdtr.limit) - { - logerror("IRET: Task return: Back-linked TSS is not in GDT.\n"); - FAULT(FAULT_TS,task & ~0x03) - } - memset(&desc, 0, sizeof(desc)); - desc.selector = task; - i386_load_protected_mode_segment(&desc,nullptr); - if((desc.flags & 0x001f) != 0x000b) - { - logerror("IRET (%08x): Task return: Back-linked TSS is not a busy TSS.\n",m_pc); - FAULT(FAULT_TS,task & ~0x03) - } - if((desc.flags & 0x0080) == 0) - { - logerror("IRET: Task return: Back-linked TSS is not present.\n"); - FAULT(FAULT_NP,task & ~0x03) - } - if(desc.flags & 0x08) - i386_task_switch(desc.selector,0); - else - i286_task_switch(desc.selector,0); - return; - } - else - { - if(newflags & 0x00020000) // if returning to virtual 8086 mode - { - // 16-bit iret can't reach here - newESP = READ32(ea+12); - newSS = READ32(ea+16) & 0xffff; - /* Return to v86 mode */ - //logerror("IRET (%08x): Returning to Virtual 8086 mode.\n",m_pc); - if(CPL != 0) - { - uint32_t oldflags = get_flags(); - newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000); - if(CPL > IOPL) - newflags = (newflags & ~0x200 ) | (oldflags & 0x200); - } - set_flags(newflags); - m_eip = POP32() & 0xffff; // high 16 bits are ignored - m_sreg[CS].selector = POP32() & 0xffff; - POP32(); // already set flags - newESP = POP32(); - newSS = POP32() & 0xffff; - m_sreg[ES].selector = POP32() & 0xffff; - m_sreg[DS].selector = POP32() & 0xffff; - m_sreg[FS].selector = POP32() & 0xffff; - m_sreg[GS].selector = POP32() & 0xffff; - REG32(ESP) = newESP; // all 32 bits are loaded - m_sreg[SS].selector = newSS; - i386_load_segment_descriptor(ES); - i386_load_segment_descriptor(DS); - i386_load_segment_descriptor(FS); - i386_load_segment_descriptor(GS); - i386_load_segment_descriptor(SS); - m_CPL = 3; // Virtual 8086 tasks are always run at CPL 3 - } - else - { - if(operand32 == 0) - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) != 0) - { - logerror("IRET: Data on stack is past SS limit.\n"); - FAULT(FAULT_SS,0) - } - } - else - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+7) != 0) - { - logerror("IRET: Data on stack is past SS limit.\n"); - FAULT(FAULT_SS,0) - } - } - RPL = newCS & 0x03; - if(RPL < CPL) - { - logerror("IRET (%08x): Return CS RPL is less than CPL.\n",m_pc); - FAULT(FAULT_GP,newCS & ~0x03) - } - if(RPL == CPL) - { - /* return to same privilege level */ - if(operand32 == 0) - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+5) != 0) - { - logerror("IRET (%08x): Data on stack is past SS limit.\n",m_pc); - FAULT(FAULT_SS,0) - } - } - else - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+11) != 0) - { - logerror("IRET (%08x): Data on stack is past SS limit.\n",m_pc); - FAULT(FAULT_SS,0) - } - } - if((newCS & ~0x03) == 0) - { - logerror("IRET: Return CS selector is null.\n"); - FAULT(FAULT_GP,0) - } - if(newCS & 0x04) - { - if((newCS & ~0x07) >= m_ldtr.limit) - { - logerror("IRET: Return CS selector (%04x) is past LDT limit.\n",newCS); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - else - { - if((newCS & ~0x07) >= m_gdtr.limit) - { - logerror("IRET: Return CS selector is past GDT limit.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - memset(&desc, 0, sizeof(desc)); - desc.selector = newCS; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - RPL = newCS & 0x03; - if((desc.flags & 0x0018) != 0x0018) - { - logerror("IRET (%08x): Return CS segment is not a code segment.\n",m_pc); - FAULT(FAULT_GP,newCS & ~0x07) - } - if(desc.flags & 0x0004) - { - if(DPL > RPL) - { - logerror("IRET: Conforming return CS DPL is greater than CS RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - else - { - if(DPL != RPL) - { - logerror("IRET: Non-conforming return CS DPL is not equal to CS RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - if((desc.flags & 0x0080) == 0) - { - logerror("IRET: (%08x) Return CS segment is not present.\n", m_pc); - FAULT(FAULT_NP,newCS & ~0x03) - } - if(newEIP > desc.limit) - { - logerror("IRET: Return EIP is past return CS limit.\n"); - FAULT(FAULT_GP,0) - } - - if(CPL != 0) - { - uint32_t oldflags = get_flags(); - newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000); - if(CPL > IOPL) - newflags = (newflags & ~0x200 ) | (oldflags & 0x200); - } - - if(operand32 == 0) - { - m_eip = newEIP; - m_sreg[CS].selector = newCS; - set_flags(newflags); - REG16(SP) += 6; - } - else - { - m_eip = newEIP; - m_sreg[CS].selector = newCS & 0xffff; - set_flags(newflags); - REG32(ESP) += 12; - } - } - else if(RPL > CPL) - { - /* return to outer privilege level */ - memset(&desc, 0, sizeof(desc)); - desc.selector = newCS; - i386_load_protected_mode_segment(&desc,nullptr); - DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level - RPL = newCS & 0x03; - if(operand32 == 0) - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+9) != 0) - { - logerror("IRET: SP is past SS limit.\n"); - FAULT(FAULT_SS,0) - } - } - else - { - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+19) != 0) - { - logerror("IRET: ESP is past SS limit.\n"); - FAULT(FAULT_SS,0) - } - } - /* Check CS selector and descriptor */ - if((newCS & ~0x03) == 0) - { - logerror("IRET: Return CS selector is null.\n"); - FAULT(FAULT_GP,0) - } - if(newCS & 0x04) - { - if((newCS & ~0x07) >= m_ldtr.limit) - { - logerror("IRET: Return CS selector is past LDT limit.\n"); - FAULT(FAULT_GP,newCS & ~0x03); - } - } - else - { - if((newCS & ~0x07) >= m_gdtr.limit) - { - logerror("IRET: Return CS selector is past GDT limit.\n"); - FAULT(FAULT_GP,newCS & ~0x03); - } - } - if((desc.flags & 0x0018) != 0x0018) - { - logerror("IRET: Return CS segment is not a code segment.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - if(desc.flags & 0x0004) - { - if(DPL > RPL) - { - logerror("IRET: Conforming return CS DPL is greater than CS RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - else - { - if(DPL != RPL) - { - logerror("IRET: Non-conforming return CS DPL does not equal CS RPL.\n"); - FAULT(FAULT_GP,newCS & ~0x03) - } - } - if((desc.flags & 0x0080) == 0) - { - logerror("IRET: Return CS segment is not present.\n"); - FAULT(FAULT_NP,newCS & ~0x03) - } - - /* Check SS selector and descriptor */ - if(operand32 == 0) - { - newESP = READ16(ea+6) & 0xffff; - newSS = READ16(ea+8) & 0xffff; - } - else - { - newESP = READ32(ea+12); - newSS = READ32(ea+16) & 0xffff; - } - memset(&stack, 0, sizeof(stack)); - stack.selector = newSS; - i386_load_protected_mode_segment(&stack,nullptr); - DPL = (stack.flags >> 5) & 0x03; - if((newSS & ~0x03) == 0) - { - logerror("IRET: Return SS selector is null.\n"); - FAULT(FAULT_GP,0) - } - if(newSS & 0x04) - { - if((newSS & ~0x07) >= m_ldtr.limit) - { - logerror("IRET: Return SS selector is past LDT limit.\n"); - FAULT(FAULT_GP,newSS & ~0x03); - } - } - else - { - if((newSS & ~0x07) >= m_gdtr.limit) - { - logerror("IRET: Return SS selector is past GDT limit.\n"); - FAULT(FAULT_GP,newSS & ~0x03); - } - } - if((newSS & 0x03) != RPL) - { - logerror("IRET: Return SS RPL is not equal to return CS RPL.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - if((stack.flags & 0x0018) != 0x0010) - { - logerror("IRET: Return SS segment is not a data segment.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - if((stack.flags & 0x0002) == 0) - { - logerror("IRET: Return SS segment is not writable.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - if(DPL != RPL) - { - logerror("IRET: Return SS DPL does not equal SS RPL.\n"); - FAULT(FAULT_GP,newSS & ~0x03) - } - if((stack.flags & 0x0080) == 0) - { - logerror("IRET: Return SS segment is not present.\n"); - FAULT(FAULT_NP,newSS & ~0x03) - } - if(newEIP > desc.limit) - { - logerror("IRET: EIP is past return CS limit.\n"); - FAULT(FAULT_GP,0) - } - -// if(operand32 == 0) -// REG16(SP) += 10; -// else -// REG32(ESP) += 20; - - // IOPL can only change if CPL is zero - if(CPL != 0) - { - uint32_t oldflags = get_flags(); - newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000); - if(CPL > IOPL) - newflags = (newflags & ~0x200 ) | (oldflags & 0x200); - } - - if(operand32 == 0) - { - m_eip = newEIP & 0xffff; - m_sreg[CS].selector = newCS; - set_flags(newflags); - REG16(SP) = newESP & 0xffff; - m_sreg[SS].selector = newSS; - } - else - { - m_eip = newEIP; - m_sreg[CS].selector = newCS & 0xffff; - set_flags(newflags); - REG32(ESP) = newESP; - m_sreg[SS].selector = newSS & 0xffff; - } - m_CPL = newCS & 0x03; - i386_load_segment_descriptor(SS); - - /* Check that DS, ES, FS and GS are valid for the new privilege level */ - i386_check_sreg_validity(DS); - i386_check_sreg_validity(ES); - i386_check_sreg_validity(FS); - i386_check_sreg_validity(GS); - } - } - } - - i386_load_segment_descriptor(CS); - CHANGE_PC(m_eip); -} - -void i386_device::build_cycle_table() -{ - int i, j; - for (j=0; j < X86_NUM_CPUS; j++) - { - cycle_table_rm[j] = std::make_unique(CYCLES_NUM_OPCODES); - cycle_table_pm[j] = std::make_unique(CYCLES_NUM_OPCODES); - - for (i=0; i < sizeof(x86_cycle_table)/sizeof(X86_CYCLE_TABLE); i++) - { - int opcode = x86_cycle_table[i].op; - cycle_table_rm[j][opcode] = x86_cycle_table[i].cpu_cycles[j][0]; - cycle_table_pm[j][opcode] = x86_cycle_table[i].cpu_cycles[j][1]; - } - } -} - -void i386_device::report_invalid_opcode() -{ -#ifndef DEBUG_MISSING_OPCODE - logerror("i386: Invalid opcode %02X at %08X %s\n", m_opcode, m_pc - 1, m_lock ? "with lock" : ""); -#else - logerror("i386: Invalid opcode"); - for (int a = 0; a < m_opcode_bytes_length; a++) - logerror(" %02X", m_opcode_bytes[a]); - logerror(" at %08X\n", m_opcode_pc); -#endif -} - -void i386_device::report_invalid_modrm(const char* opcode, uint8_t modrm) -{ -#ifndef DEBUG_MISSING_OPCODE - logerror("i386: Invalid %s modrm %01X at %08X\n", opcode, modrm, m_pc - 2); -#else - logerror("i386: Invalid %s modrm %01X", opcode, modrm); - for (int a = 0; a < m_opcode_bytes_length; a++) - logerror(" %02X", m_opcode_bytes[a]); - logerror(" at %08X\n", m_opcode_pc); -#endif - i386_trap(6, 0, 0); -} - - -#include "i386ops.hxx" -#include "i386op16.hxx" -#include "i386op32.hxx" -#include "i486ops.hxx" -#include "pentops.hxx" -#include "x87ops.hxx" -#include "cpuidmsrs.hxx" - - -void i386_device::i386_decode_opcode() -{ - m_opcode = FETCH(); - - if(m_lock && !m_lock_table[0][m_opcode]) - return i386_invalid(); - - if( m_operand_size ) - (this->*m_opcode_table1_32[m_opcode])(); - else - (this->*m_opcode_table1_16[m_opcode])(); -} - -/* Two-byte opcode 0f xx */ -void i386_device::i386_decode_two_byte() -{ - m_opcode = FETCH(); - - if(m_lock && !m_lock_table[1][m_opcode]) - return i386_invalid(); - - if( m_operand_size ) - (this->*m_opcode_table2_32[m_opcode])(); - else - (this->*m_opcode_table2_16[m_opcode])(); -} - -/* Three-byte opcode 0f 38 xx */ -void i386_device::i386_decode_three_byte38() -{ - m_opcode = FETCH(); - - if (m_operand_size) - (this->*m_opcode_table338_32[m_opcode])(); - else - (this->*m_opcode_table338_16[m_opcode])(); -} - -/* Three-byte opcode 0f 3a xx */ -void i386_device::i386_decode_three_byte3a() -{ - m_opcode = FETCH(); - - if (m_operand_size) - (this->*m_opcode_table33a_32[m_opcode])(); - else - (this->*m_opcode_table33a_16[m_opcode])(); -} - -/* Three-byte opcode prefix 66 0f xx */ -void i386_device::i386_decode_three_byte66() -{ - m_opcode = FETCH(); - if( m_operand_size ) - (this->*m_opcode_table366_32[m_opcode])(); - else - (this->*m_opcode_table366_16[m_opcode])(); -} - -/* Three-byte opcode prefix f2 0f xx */ -void i386_device::i386_decode_three_bytef2() -{ - m_opcode = FETCH(); - if( m_operand_size ) - (this->*m_opcode_table3f2_32[m_opcode])(); - else - (this->*m_opcode_table3f2_16[m_opcode])(); -} - -/* Three-byte opcode prefix f3 0f */ -void i386_device::i386_decode_three_bytef3() -{ - m_opcode = FETCH(); - if( m_operand_size ) - (this->*m_opcode_table3f3_32[m_opcode])(); - else - (this->*m_opcode_table3f3_16[m_opcode])(); -} - -/* Four-byte opcode prefix 66 0f 38 xx */ -void i386_device::i386_decode_four_byte3866() -{ - m_opcode = FETCH(); - if (m_operand_size) - (this->*m_opcode_table46638_32[m_opcode])(); - else - (this->*m_opcode_table46638_16[m_opcode])(); -} - -/* Four-byte opcode prefix 66 0f 3a xx */ -void i386_device::i386_decode_four_byte3a66() -{ - m_opcode = FETCH(); - if (m_operand_size) - (this->*m_opcode_table4663a_32[m_opcode])(); - else - (this->*m_opcode_table4663a_16[m_opcode])(); -} - -/* Four-byte opcode prefix f2 0f 38 xx */ -void i386_device::i386_decode_four_byte38f2() -{ - m_opcode = FETCH(); - if (m_operand_size) - (this->*m_opcode_table4f238_32[m_opcode])(); - else - (this->*m_opcode_table4f238_16[m_opcode])(); -} - -/* Four-byte opcode prefix f2 0f 3a xx */ -void i386_device::i386_decode_four_byte3af2() -{ - m_opcode = FETCH(); - if (m_operand_size) - (this->*m_opcode_table4f23a_32[m_opcode])(); - else - (this->*m_opcode_table4f23a_16[m_opcode])(); -} - -/* Four-byte opcode prefix f3 0f 38 xx */ -void i386_device::i386_decode_four_byte38f3() -{ - m_opcode = FETCH(); - if (m_operand_size) - (this->*m_opcode_table4f338_32[m_opcode])(); - else - (this->*m_opcode_table4f338_16[m_opcode])(); -} - - -/*************************************************************************/ - -uint8_t i386_device::read8_debug(uint32_t ea, uint8_t *data) -{ - uint32_t address = ea; - - if(!i386_translate_address(TRANSLATE_DEBUG_MASK,&address,nullptr)) - return 0; - - address &= m_a20_mask; - *data = this->read_debug_data8(address); - return 1; -} -#if 0 -uint32_t i386_device::i386_get_debug_desc(I386_SREG *seg) -{ - uint32_t base, limit, address; - union { uint8_t b[8]; uint32_t w[2]; } data; - uint8_t ret; - int entry; - - if ( seg->selector & 0x4 ) - { - base = m_ldtr.base; - limit = m_ldtr.limit; - } else { - base = m_gdtr.base; - limit = m_gdtr.limit; - } - - entry = seg->selector & ~0x7; - if (limit == 0 || entry + 7 > limit) - return 0; - - address = entry + base; - - // todo: bigendian - ret = read8_debug( address+0, &data.b[0] ); - ret += read8_debug( address+1, &data.b[1] ); - ret += read8_debug( address+2, &data.b[2] ); - ret += read8_debug( address+3, &data.b[3] ); - ret += read8_debug( address+4, &data.b[4] ); - ret += read8_debug( address+5, &data.b[5] ); - ret += read8_debug( address+6, &data.b[6] ); - ret += read8_debug( address+7, &data.b[7] ); - - if(ret != 8) - return 0; - - seg->flags = (data.w[1] >> 8) & 0xf0ff; - seg->base = (data.w[1] & 0xff000000) | ((data.w[1] & 0xff) << 16) | ((data.w[0] >> 16) & 0xffff); - seg->limit = (data.w[1] & 0xf0000) | (data.w[0] & 0xffff); - if (seg->flags & 0x8000) - seg->limit = (seg->limit << 12) | 0xfff; - seg->d = (seg->flags & 0x4000) ? 1 : 0; - seg->valid = (seg->selector & ~3)?(true):(false); - - return seg->valid; -} - -uint64_t i386_device::debug_segbase(symbol_table &table, int params, const uint64_t *param) -{ - uint32_t result; - I386_SREG seg; - - if(param[0] > 65535) - return 0; - - if (PROTECTED_MODE && !V8086_MODE) - { - memset(&seg, 0, sizeof(seg)); - seg.selector = param[0]; - if(!i386_get_debug_desc(&seg)) - return 0; - result = seg.base; - } - else - { - result = param[0] << 4; - } - return result; -} - -uint64_t i386_device::debug_seglimit(symbol_table &table, int params, const uint64_t *param) -{ - uint32_t result = 0; - I386_SREG seg; - - if (PROTECTED_MODE && !V8086_MODE) - { - memset(&seg, 0, sizeof(seg)); - seg.selector = param[0]; - if(!i386_get_debug_desc(&seg)) - return 0; - result = seg.limit; - } - return result; -} - -uint64_t i386_device::debug_segofftovirt(symbol_table &table, int params, const uint64_t *param) -{ - uint32_t result; - I386_SREG seg; - - if(param[0] > 65535) - return 0; - - if (PROTECTED_MODE && !V8086_MODE) - { - memset(&seg, 0, sizeof(seg)); - seg.selector = param[0]; - if(!i386_get_debug_desc(&seg)) - return 0; - if((seg.flags & 0x0090) != 0x0090) // not system and present - return 0; - if((seg.flags & 0x0018) == 0x0010 && seg.flags & 0x0004) // expand down - { - if(param[1] <= seg.limit) - return 0; - } - else - { - if(param[1] > seg.limit) - return 0; - } - result = seg.base+param[1]; - } - else - { - if(param[1] > 65535) - return 0; - - result = (param[0] << 4) + param[1]; - } - return result; -} - -uint64_t i386_device::debug_virttophys(symbol_table &table, int params, const uint64_t *param) -{ - uint32_t result = param[0]; - - if(!i386_translate_address(TRANSLATE_DEBUG_MASK,&result,nullptr)) - return 0; - return result; -} - -void i386_device::device_debug_setup() -{ - using namespace std::placeholders; - debug()->symtable().add("segbase", 1, 1, std::bind(&i386_device::debug_segbase, this, _1, _2, _3)); - debug()->symtable().add("seglimit", 1, 1, std::bind(&i386_device::debug_seglimit, this, _1, _2, _3)); - debug()->symtable().add("segofftovirt", 2, 2, std::bind(&i386_device::debug_segofftovirt, this, _1, _2, _3)); - debug()->symtable().add("virttophys", 1, 1, std::bind(&i386_device::debug_virttophys, this, _1, _2, _3)); -} -#endif -/*************************************************************************/ - -void i386_device::i386_postload() -{ - int i; - for (i = 0; i < 6; i++) - i386_load_segment_descriptor(i); - CHANGE_PC(m_eip); -} - -void i386_device::i386_common_init() -{ - DEVICE::initialize(); - int i, j; - static const int regs8[8] = {AL,CL,DL,BL,AH,CH,DH,BH}; - static const int regs16[8] = {AX,CX,DX,BX,SP,BP,SI,DI}; - static const int regs32[8] = {EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI}; - - assert((sizeof(XMM_REG)/sizeof(double)) == 2); - - build_cycle_table(); - - for( i=0; i < 256; i++ ) { - int c=0; - for( j=0; j < 8; j++ ) { - if( i & (1 << j) ) - c++; - } - i386_parity_table[i] = ~(c & 0x1) & 0x1; - } - - for( i=0; i < 256; i++ ) { - i386_MODRM_table[i].reg.b = regs8[(i >> 3) & 0x7]; - i386_MODRM_table[i].reg.w = regs16[(i >> 3) & 0x7]; - i386_MODRM_table[i].reg.d = regs32[(i >> 3) & 0x7]; - - i386_MODRM_table[i].rm.b = regs8[i & 0x7]; - i386_MODRM_table[i].rm.w = regs16[i & 0x7]; - i386_MODRM_table[i].rm.d = regs32[i & 0x7]; - } - -// m_program = &space(AS_PROGRAM); -// if(data_width == 16) { -// // for the 386sx -// macache16 = m_program->cache<1, 0, ENDIANNESS_LITTLE>(); -// } else { -// macache32 = m_program->cache<2, 0, ENDIANNESS_LITTLE>(); -// } -// cache_mem.clear(); - m_io = &space(AS_IO); - m_smi = false; - m_debugger_temp = 0; - m_lock = false; - - zero_state(); - - - //m_smiact.resolve_safe(); - //m_ferr_handler.resolve_safe(); - m_ferr_err_value =0; - - if((d_debugger != NULL) && (osd->check_feature(USE_DEBUGGER))) { - d_program_stored = d_mem; - d_io_stored = d_io; - } else { - d_debugger = NULL; - } - set_icountptr(m_cycles); -} - -void i386_device::initialize() -{ - i386_common_init(); - - build_opcode_table(OP_I386); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_I386].get(); - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_I386].get(); - -// register_state_i386(); -} - -#define STATE_VERSION 6 - -bool i386_device::process_state_segment(int num, FILEIO* state_fio, bool loading) -{ - state_fio->StateValue(m_sreg[num].selector); - state_fio->StateValue(m_sreg[num].base); - state_fio->StateValue(m_sreg[num].limit); - state_fio->StateValue(m_sreg[num].flags); - - return true; -} - -bool i386_device::process_state_i386(FILEIO* state_fio, bool loading) -{ - state_fio->StateValue(m_pc); - state_fio->StateValue(m_eip); - state_fio->StateValue(m_prev_eip); - state_fio->StateValue(m_reg.d[EAX]); - state_fio->StateValue(m_reg.d[EBX]); - state_fio->StateValue(m_reg.d[ECX]); - state_fio->StateValue(m_reg.d[EDX]); - state_fio->StateValue(m_reg.d[EBP]); - state_fio->StateValue(m_reg.d[ESP]); - state_fio->StateValue(m_reg.d[ESI]); - state_fio->StateValue(m_reg.d[EDI]); - - state_fio->StateValue(m_eflags); - state_fio->StateValue(m_eflags_mask); - - process_state_segment(CS, state_fio, loading); - process_state_segment(SS, state_fio, loading); - process_state_segment(DS, state_fio, loading); - process_state_segment(ES, state_fio, loading); - process_state_segment(FS, state_fio, loading); - process_state_segment(GS, state_fio, loading); - state_fio->StateArray(m_cr, sizeof(m_cr), 1); - state_fio->StateArray(m_dr, sizeof(m_dr), 1); - state_fio->StateArray(m_tr, sizeof(m_tr), 1); - - state_fio->StateValue(m_gdtr.base); - state_fio->StateValue(m_gdtr.limit); - - state_fio->StateValue(m_idtr.base); - state_fio->StateValue(m_idtr.limit); - - state_fio->StateValue(m_ldtr.segment); - state_fio->StateValue(m_ldtr.base); - state_fio->StateValue(m_ldtr.limit); - state_fio->StateValue(m_ldtr.flags); - - state_fio->StateValue(m_task.segment); - state_fio->StateValue(m_task.base); - state_fio->StateValue(m_task.limit); - state_fio->StateValue(m_task.flags); - - state_fio->StateValue(m_CF); - state_fio->StateValue(m_DF); - state_fio->StateValue(m_SF); - state_fio->StateValue(m_OF); - state_fio->StateValue(m_ZF); - state_fio->StateValue(m_PF); - state_fio->StateValue(m_AF); - state_fio->StateValue(m_IF); - state_fio->StateValue(m_TF); - state_fio->StateValue(m_IOP1); - state_fio->StateValue(m_IOP2); - state_fio->StateValue(m_NT); - state_fio->StateValue(m_RF); - state_fio->StateValue(m_VM); - state_fio->StateValue(m_AC); - state_fio->StateValue(m_VIF); - state_fio->StateValue(m_VIP); - state_fio->StateValue(m_ID); - - state_fio->StateValue(m_CPL); - - state_fio->StateValue(m_performed_intersegment_jump); - - state_fio->StateValue(m_segment_override); - state_fio->StateValue(m_irq_state); - state_fio->StateValue(m_a20_mask); - state_fio->StateValue(m_shutdown); - state_fio->StateValue(m_halted); - state_fio->StateValue(m_busreq); - - state_fio->StateValue(m_cycles); - state_fio->StateValue(extra_cycles); - state_fio->StateValue(total_cycles); - state_fio->StateValue(m_tsc); - - state_fio->StateValue(m_mxcsr); - state_fio->StateValue(m_smm); - state_fio->StateValue(m_smi); - state_fio->StateValue(m_smi_latched); - state_fio->StateValue(m_nmi_masked); - state_fio->StateValue(m_nmi_latched); - state_fio->StateValue(m_smbase); - state_fio->StateValue(m_lock); - state_fio->StateValue(m_ferr_err_value); - state_fio->StateValue(m_smiact_enabled); - - state_fio->StateValue(m_operand_size); - - state_fio->StateValue(icount); - if(loading) { - i386_postload(); - prev_total_cycles = total_cycles; - } - - //m_smiact.resolve_safe(); - //m_ferr_handler.resolve_safe(); - -// state_add( STATE_GENPC, "GENPC", m_pc).noshow(); -// state_add( STATE_GENPCBASE, "CURPC", m_pc).noshow(); -// state_add( STATE_GENFLAGS, "GENFLAGS", m_debugger_temp).formatstr("%8s").noshow(); -// state_add( STATE_GENSP, "GENSP", REG32(ESP)).noshow(); - return true; -} - -bool i386_device::process_state_i386_x87(FILEIO* state_fio, bool loading) -{ - if(!process_state_i386(state_fio, loading)) { - return false; - } - state_fio->StateValue(m_x87_cw); - state_fio->StateValue(m_x87_sw); - state_fio->StateValue(m_x87_tw); - state_fio->StateValue(m_x87_data_ptr); - state_fio->StateValue(m_x87_inst_ptr); - state_fio->StateValue(m_x87_opcode); - state_fio->StateValue(m_x87_operand_size); - for(int i = 0; i < 8; i++) { - state_fio->StateValue(m_x87_reg[i].high); - state_fio->StateValue(m_x87_reg[i].low); - } - return true; -} - -bool i386_device::process_state_i386_x87_xmm(FILEIO* state_fio, bool loading) -{ - if(!process_state_i386_x87(state_fio, loading)) { - return false; - } - for(int i = 0; i < 8; i++) { - for(int j = 0; j < 4; j++) { - state_fio->StateValue(m_sse_reg[i].d[j]); - } - } - state_fio->StateValue(m_xmm_operand_size); - return true; -} - -bool i386_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386(state_fio, loading); -} - -bool i486_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87(state_fio, loading); -} - -bool pentium_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87(state_fio, loading); -} - -bool mediagx_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87(state_fio, loading); -} - -bool pentium_pro_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87(state_fio, loading); -} - -bool pentium_mmx_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87(state_fio, loading); -} - -bool pentium2_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87(state_fio, loading); -} - -bool pentium3_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87_xmm(state_fio, loading); -} - -bool pentium4_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87_xmm(state_fio, loading); -} - -#if 0 -bool athlonxp_device::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - return process_state_i386_x87_xmm(state_fio, loading); -} -#endif -#if 0 -void i386_device::state_import(int index) -{ - switch (index) - { - case I386_EIP: - CHANGE_PC(m_eip); - break; - case I386_IP: - m_eip = ( m_eip & ~0xffff ) | ( m_debugger_temp & 0xffff); - CHANGE_PC(m_eip); - break; - case I386_CS: - i386_load_segment_descriptor(CS); - break; - case I386_SS: - i386_load_segment_descriptor(SS); - break; - case I386_DS: - i386_load_segment_descriptor(DS); - break; - case I386_ES: - i386_load_segment_descriptor(ES); - break; - case I386_FS: - i386_load_segment_descriptor(FS); - break; - case I386_GS: - i386_load_segment_descriptor(GS); - break; - } -} - -void i386_device::state_export(int index) -{ - switch (index()) - { - case I386_IP: - m_debugger_temp = m_eip & 0xffff; - break; - } -} -#endif - -void i386_device::build_opcode_table(uint32_t features) -{ - int i; - for (i=0; i < 256; i++) - { - m_opcode_table1_16[i] = &i386_device::i386_invalid; - m_opcode_table1_32[i] = &i386_device::i386_invalid; - m_opcode_table2_16[i] = &i386_device::i386_invalid; - m_opcode_table2_32[i] = &i386_device::i386_invalid; - m_opcode_table366_16[i] = &i386_device::i386_invalid; - m_opcode_table366_32[i] = &i386_device::i386_invalid; - m_opcode_table3f2_16[i] = &i386_device::i386_invalid; - m_opcode_table3f2_32[i] = &i386_device::i386_invalid; - m_opcode_table3f3_16[i] = &i386_device::i386_invalid; - m_opcode_table3f3_32[i] = &i386_device::i386_invalid; - m_lock_table[0][i] = false; - m_lock_table[1][i] = false; - } - - for (i=0; i < sizeof(s_x86_opcode_table)/sizeof(X86_OPCODE); i++) - { - const X86_OPCODE *op = &s_x86_opcode_table[i]; - - if ((op->flags & features)) - { - if (op->flags & OP_2BYTE) - { - m_opcode_table2_32[op->opcode] = op->handler32; - m_opcode_table2_16[op->opcode] = op->handler16; - m_opcode_table366_32[op->opcode] = op->handler32; - m_opcode_table366_16[op->opcode] = op->handler16; - m_lock_table[1][op->opcode] = op->lockable; - } - else if (op->flags & OP_3BYTE66) - { - m_opcode_table366_32[op->opcode] = op->handler32; - m_opcode_table366_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_3BYTEF2) - { - m_opcode_table3f2_32[op->opcode] = op->handler32; - m_opcode_table3f2_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_3BYTEF3) - { - m_opcode_table3f3_32[op->opcode] = op->handler32; - m_opcode_table3f3_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_3BYTE38) - { - m_opcode_table338_32[op->opcode] = op->handler32; - m_opcode_table338_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_3BYTE3A) - { - m_opcode_table33a_32[op->opcode] = op->handler32; - m_opcode_table33a_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_4BYTE3866) - { - m_opcode_table46638_32[op->opcode] = op->handler32; - m_opcode_table46638_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_4BYTE3A66) - { - m_opcode_table4663a_32[op->opcode] = op->handler32; - m_opcode_table4663a_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_4BYTE38F2) - { - m_opcode_table4f238_32[op->opcode] = op->handler32; - m_opcode_table4f238_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_4BYTE3AF2) - { - m_opcode_table4f23a_32[op->opcode] = op->handler32; - m_opcode_table4f23a_16[op->opcode] = op->handler16; - } - else if (op->flags & OP_4BYTE38F3) - { - m_opcode_table4f338_32[op->opcode] = op->handler32; - m_opcode_table4f338_16[op->opcode] = op->handler16; - } - else - { - m_opcode_table1_32[op->opcode] = op->handler32; - m_opcode_table1_16[op->opcode] = op->handler16; - m_lock_table[0][op->opcode] = op->lockable; - } - } - } -} - -void i386_device::zero_state() -{ - memset( &m_reg, 0, sizeof(m_reg) ); - memset( m_sreg, 0, sizeof(m_sreg) ); - m_eip = 0; - m_pc = 0; - m_prev_eip = 0; - m_eflags = 0; - m_eflags_mask = 0; - m_CF = 0; - m_DF = 0; - m_SF = 0; - m_OF = 0; - m_ZF = 0; - m_PF = 0; - m_AF = 0; - m_IF = 0; - m_TF = 0; - m_IOP1 = 0; - m_IOP2 = 0; - m_NT = 0; - m_RF = 0; - m_VM = 0; - m_AC = 0; - m_VIF = 0; - m_VIP = 0; - m_ID = 0; - m_CPL = 0; - m_performed_intersegment_jump = 0; - m_delayed_interrupt_enable = 0; - memset( m_cr, 0, sizeof(m_cr) ); - memset( m_dr, 0, sizeof(m_dr) ); - memset( m_tr, 0, sizeof(m_tr) ); - memset( &m_gdtr, 0, sizeof(m_gdtr) ); - memset( &m_idtr, 0, sizeof(m_idtr) ); - memset( &m_task, 0, sizeof(m_task) ); - memset( &m_ldtr, 0, sizeof(m_ldtr) ); - m_ext = 0; - m_halted = 0; - m_busreq = 0; - m_operand_size = 0; - m_xmm_operand_size = 0; - m_address_size = 0; - m_operand_prefix = 0; - m_address_prefix = 0; - m_segment_prefix = 0; - m_segment_override = 0; - m_cycles = 0; - m_base_cycles = 0; - m_opcode = 0; - m_irq_state = 0; - m_a20_mask = 0; - m_shutdown = false; - m_cpuid_max_input_value_eax = 0; - m_cpuid_id0 = 0; - m_cpuid_id1 = 0; - m_cpuid_id2 = 0; - m_cpu_version = 0; - m_feature_flags = 0; - m_tsc = 0; - total_cycles = 0; - prev_total_cycles = 0; - extra_cycles = 0; - m_perfctr[0] = m_perfctr[1] = 0; - memset( m_x87_reg, 0, sizeof(m_x87_reg) ); - m_x87_cw = 0; - m_x87_sw = 0; - m_x87_tw = 0; - m_x87_data_ptr = 0; - m_x87_inst_ptr = 0; - m_x87_opcode = 0; - memset( m_sse_reg, 0, sizeof(m_sse_reg) ); - m_mxcsr = 0; - m_smm = false; - m_smi = false; - m_smi_latched = false; - m_nmi_masked = false; - m_nmi_latched = false; - m_smbase = 0; - memset( m_opcode_bytes, 0, sizeof(m_opcode_bytes) ); - m_opcode_pc = 0; - m_opcode_bytes_length = 0; -} - -void i386_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x93; - m_sreg[CS].valid = true; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - m_sreg[DS].valid = m_sreg[ES].valid = m_sreg[FS].valid = m_sreg[GS].valid = m_sreg[SS].valid =true; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - m_smm = false; - m_smi_latched = false; - m_nmi_masked = false; - m_nmi_latched = false; - - m_a20_mask = ~0; - - m_cr[0] = 0x7fffffe0; // reserved bits set to 1 - m_eflags = 0; - m_eflags_mask = 0x00037fd7; - m_eip = 0xfff0; - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 3 (386), Model 0 (DX), Stepping 8 (D1) - REG32(EAX) = 0; - REG32(EDX) = (3 << 8) | (0 << 4) | (8); - m_cpu_version = REG32(EDX); - - m_CPL = 0; - - CHANGE_PC(m_eip); -} - -void i386_device::pentium_smi() -{ - uint32_t smram_state = m_smbase + 0xfe00; - uint32_t old_cr0 = m_cr[0]; - uint32_t old_flags = get_flags(); - - if(m_smm) - return; - - m_cr[0] &= ~(0x8000000d); - set_flags(2); - if(m_smiact != NULL) - m_smiact_enabled = true; - m_smm = true; - m_smi_latched = false; - - // save state - WRITE32(smram_state + SMRAM_SMBASE, m_smbase); - WRITE32(smram_state + SMRAM_IP5_CR4, m_cr[4]); - WRITE32(smram_state + SMRAM_IP5_ESLIM, m_sreg[ES].limit); - WRITE32(smram_state + SMRAM_IP5_ESBASE, m_sreg[ES].base); - WRITE32(smram_state + SMRAM_IP5_ESACC, m_sreg[ES].flags); - WRITE32(smram_state + SMRAM_IP5_CSLIM, m_sreg[CS].limit); - WRITE32(smram_state + SMRAM_IP5_CSBASE, m_sreg[CS].base); - WRITE32(smram_state + SMRAM_IP5_CSACC, m_sreg[CS].flags); - WRITE32(smram_state + SMRAM_IP5_SSLIM, m_sreg[SS].limit); - WRITE32(smram_state + SMRAM_IP5_SSBASE, m_sreg[SS].base); - WRITE32(smram_state + SMRAM_IP5_SSACC, m_sreg[SS].flags); - WRITE32(smram_state + SMRAM_IP5_DSLIM, m_sreg[DS].limit); - WRITE32(smram_state + SMRAM_IP5_DSBASE, m_sreg[DS].base); - WRITE32(smram_state + SMRAM_IP5_DSACC, m_sreg[DS].flags); - WRITE32(smram_state + SMRAM_IP5_FSLIM, m_sreg[FS].limit); - WRITE32(smram_state + SMRAM_IP5_FSBASE, m_sreg[FS].base); - WRITE32(smram_state + SMRAM_IP5_FSACC, m_sreg[FS].flags); - WRITE32(smram_state + SMRAM_IP5_GSLIM, m_sreg[GS].limit); - WRITE32(smram_state + SMRAM_IP5_GSBASE, m_sreg[GS].base); - WRITE32(smram_state + SMRAM_IP5_GSACC, m_sreg[GS].flags); - WRITE32(smram_state + SMRAM_IP5_LDTACC, m_ldtr.flags); - WRITE32(smram_state + SMRAM_IP5_LDTLIM, m_ldtr.limit); - WRITE32(smram_state + SMRAM_IP5_LDTBASE, m_ldtr.base); - WRITE32(smram_state + SMRAM_IP5_GDTLIM, m_gdtr.limit); - WRITE32(smram_state + SMRAM_IP5_GDTBASE, m_gdtr.base); - WRITE32(smram_state + SMRAM_IP5_IDTLIM, m_idtr.limit); - WRITE32(smram_state + SMRAM_IP5_IDTBASE, m_idtr.base); - WRITE32(smram_state + SMRAM_IP5_TRLIM, m_task.limit); - WRITE32(smram_state + SMRAM_IP5_TRBASE, m_task.base); - WRITE32(smram_state + SMRAM_IP5_TRACC, m_task.flags); - - WRITE32(smram_state + SMRAM_ES, m_sreg[ES].selector); - WRITE32(smram_state + SMRAM_CS, m_sreg[CS].selector); - WRITE32(smram_state + SMRAM_SS, m_sreg[SS].selector); - WRITE32(smram_state + SMRAM_DS, m_sreg[DS].selector); - WRITE32(smram_state + SMRAM_FS, m_sreg[FS].selector); - WRITE32(smram_state + SMRAM_GS, m_sreg[GS].selector); - WRITE32(smram_state + SMRAM_LDTR, m_ldtr.segment); - WRITE32(smram_state + SMRAM_TR, m_task.segment); - - WRITE32(smram_state + SMRAM_DR7, m_dr[7]); - WRITE32(smram_state + SMRAM_DR6, m_dr[6]); - WRITE32(smram_state + SMRAM_EAX, REG32(EAX)); - WRITE32(smram_state + SMRAM_ECX, REG32(ECX)); - WRITE32(smram_state + SMRAM_EDX, REG32(EDX)); - WRITE32(smram_state + SMRAM_EBX, REG32(EBX)); - WRITE32(smram_state + SMRAM_ESP, REG32(ESP)); - WRITE32(smram_state + SMRAM_EBP, REG32(EBP)); - WRITE32(smram_state + SMRAM_ESI, REG32(ESI)); - WRITE32(smram_state + SMRAM_EDI, REG32(EDI)); - WRITE32(smram_state + SMRAM_EIP, m_eip); - WRITE32(smram_state + SMRAM_EFLAGS, old_flags); - WRITE32(smram_state + SMRAM_CR3, m_cr[3]); - WRITE32(smram_state + SMRAM_CR0, old_cr0); - - m_sreg[DS].selector = m_sreg[ES].selector = m_sreg[FS].selector = m_sreg[GS].selector = m_sreg[SS].selector = 0; - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffffffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x8093; - m_sreg[DS].valid = m_sreg[ES].valid = m_sreg[FS].valid = m_sreg[GS].valid = m_sreg[SS].valid =true; - m_sreg[CS].selector = 0x3000; // pentium only, ppro sel = smbase >> 4 - m_sreg[CS].base = m_smbase; - m_sreg[CS].limit = 0xffffffff; - m_sreg[CS].flags = 0x8093; - m_sreg[CS].valid = true; - m_cr[4] = 0; - m_dr[7] = 0x400; - m_eip = 0x8000; - - m_nmi_masked = true; - CHANGE_PC(m_eip); -} - - -void pentium_device::write_signal(int id, uint32_t data, uint32_t mask) -{ - bool state = ((data & mask) != 0); - if ( id == SIG_I386_SMI ) - { - if ( !m_smi && state && m_smm ) - { - m_smi_latched = true; - } - m_smi = state; - } - else - { - i386_device::write_signal(id, data, mask); - } -} - -void i386_device::i386_set_a20_line(int state) -{ - if (state) - { - m_a20_mask = ~0; - } - else - { - m_a20_mask = ~(1 << 20); - } - // TODO: how does A20M and the tlb interact - d_vtlb->vtlb_flush_dynamic(); -} - -void i386_device::write_signal(int id, uint32_t data, uint32_t mask) -{ - if(id == SIG_CPU_NMI) { - i386_set_irq_line(INPUT_LINE_NMI, (data & mask) ? HOLD_LINE : CLEAR_LINE); - } else if(id == SIG_CPU_IRQ) { - i386_set_irq_line(INPUT_LINE_IRQ, (data & mask) ? HOLD_LINE : CLEAR_LINE); - } else if(id == SIG_CPU_BUSREQ) { - m_busreq = (data & mask) ? 1 : 0; - } else if(id == SIG_I386_A20) { - i386_set_a20_line(data & mask); - } else if(id == SIG_CPU_ADDRESS_DIRTY) { - // ToDo: clear cache. - uint32_t target_address = data; - uint32_t target_bytes = mask; - } -} - -int i386_device::run(int clocks) -{ - int cycles = m_cycles; - m_base_cycles = cycles; - CHANGE_PC(m_eip); - - if ((m_halted) || (m_busreq)) - { - if(d_dma != NULL) { - d_dma->do_dma(); - } - bool now_debugging = false; - if((d_debugger != NULL) && (d_emu != NULL)){ - now_debugging = d_debugger->now_debugging; - } - if(now_debugging) { - d_debugger->check_break_points(m_pc); - if(d_debugger->now_suspended) { - d_debugger->now_waiting = true; - emu->start_waiting_in_debugger(); - while(d_debugger->now_debugging && d_debugger->now_suspended) { - emu->process_waiting_in_debugger(); - } - emu->finish_waiting_in_debugger(); - d_debugger->now_waiting = false; - } - if(d_debugger->now_debugging) { - d_mem = d_io = d_debugger; - } else { - now_debugging = false; - } - if(now_debugging) { - if(!d_debugger->now_going) { - d_debugger->now_suspended = true; - } - d_mem = d_program_stored; - d_io = d_io_stored; - } - } - if(clocks < 0) { - int passed_cycles = max(1, extra_cycles); - extra_cycles = 0; - tsc += passed_cycles; - total_cycles += passed_cycles; - return passed_cycles; - } else { - m_cycles += clocks; - m_cycles -= extra_cycles; - extra_cycles = 0; - /* if busreq is raised, spin cpu while remained clock */ - if(m_cycles > 0) { - m_cycles = 0; - } - int passed_cycles = m_base_cycles - m_cycles; - tsc += passed_cycles; -//#ifdef USE_DEBUGGER - total_cycles += passed_cycles; -//#endif - return passed_cycles; - } - } - - if(clocks < 0) { - m_cycles = 1; - } else { - m_cycles += clocks; - } - m_base_cycles = m_cycles; - total_cycles += extra_cycles; - m_cycles -= extra_cycles; - extra_cycles - 0; - - while( (m_cycles > 0) && !(m_busreq) ) - { - bool now_debugging = false; - if((d_debugger != NULL) && (d_emu != NULL)){ - now_debugging = d_debugger->now_debugging; - } - if(now_debugging) { - d_debugger->check_break_points(m_pc); - if(d_debugger->now_suspended) { - d_debugger->now_waiting = true; - emu->start_waiting_in_debugger(); - while(d_debugger->now_debugging && d_debugger->now_suspended) { - emu->process_waiting_in_debugger(); - } - emu->finish_waiting_in_debugger(); - d_debugger->now_waiting = false; - } - if(d_debugger->now_debugging) { - d_mem = d_io = d_debugger; - } else { - now_debugging = false; - } - int first_cycles = m_cycles; - i386_check_irq_line(); - m_operand_size = m_sreg[CS].d; - m_xmm_operand_size = 0; - m_address_size = m_sreg[CS].d; - m_operand_prefix = 0; - m_address_prefix = 0; - - m_ext = 1; - int old_tf = m_TF; - - d_debugger->add_cpu_trace(m_pc); - m_segment_prefix = 0; - m_prev_eip = m_eip; - m_prev_pc = m_pc; - - if(m_delayed_interrupt_enable != 0) - { - m_IF = 1; - m_delayed_interrupt_enable = 0; - } -#ifdef DEBUG_MISSING_OPCODE - m_opcode_bytes_length = 0; - m_opcode_pc = m_pc; -#endif - try - { - i386_decode_opcode(); - if(m_TF && old_tf) - { - m_prev_eip = m_eip; - m_ext = 1; - i386_trap(1,0,0); - } - if(m_lock && (m_opcode != 0xf0)) - m_lock = false; - } - catch(uint64_t e) - { - m_ext = 1; - //logerror("Illegal instruction EIP=%08x VM8086=%s exception %08x irq=0 irq_gate=0 ERROR=%08x\n", cpustate->eip, (cpustate->VM) ? "YES" : "NO", e & 0xffffffff, e >> 32); - i386_trap_with_error(e&0xffffffff,0,0,e>>32, 1); - } - -//#ifdef SINGLE_MODE_DMA - if(d_dma != NULL) { - d_dma->do_dma(); - } -//#endif - /* adjust for any interrupts that came in */ - m_cycles -= extra_cycles; - extra_cycles = 0; - total_cycles += first_cycles - m_cycles; - - if(now_debugging) { - if(!d_debugger->now_going) { - d_debugger->now_suspended = true; - } - d_mem = d_program_stored; - d_io = d_io_stored; - } - } else { - int first_cycles = m_cycles; - - i386_check_irq_line(); - m_operand_size = m_sreg[CS].d; - m_xmm_operand_size = 0; - m_address_size = m_sreg[CS].d; - m_operand_prefix = 0; - m_address_prefix = 0; - - m_ext = 1; - int old_tf = m_TF; - - m_segment_prefix = 0; - m_prev_eip = m_eip; - - debugger_instruction_hook(m_pc); - - if(m_delayed_interrupt_enable != 0) - { - m_IF = 1; - m_delayed_interrupt_enable = 0; - } -#ifdef DEBUG_MISSING_OPCODE - m_opcode_bytes_length = 0; - m_opcode_pc = m_pc; -#endif - try - { - i386_decode_opcode(); - if(m_TF && old_tf) - { - m_prev_eip = m_eip; - m_ext = 1; - i386_trap(1,0,0); - } - if(m_lock && (m_opcode != 0xf0)) - m_lock = false; - } - catch(uint64_t e) - { - m_ext = 1; - i386_trap_with_error(e&0xffffffff,0,0,e>>32); - } - if(d_dma != NULL) { - d_dma->do_dma(); - } - } - if ((m_cycles > 0) && (m_busreq)) { - total_cycles += m_cycles; - m_cycles = 0; - } - } - int passed_cycles = m_base_cycles - m_cycles; - m_tsc += passed_cycles; - return passed_cycles; -} - -/*************************************************************************/ - -bool i386_device::memory_translate(int spacenum, int intention, offs_t &address) -{ - bool ret = true; - if(spacenum == AS_PROGRAM) - ret = i386_translate_address(intention, &address, nullptr); - address &= m_a20_mask; - return ret; -} - -void i386_device::set_intr_line(bool line, bool pending, uint32_t bit) -{ - i386_set_irq_line(INPUT_LINE_IRQ, line ? HOLD_LINE : CLEAR_LINE); -} - -void i386_device::set_extra_clock(int cycles) -{ - extra_cycles += cycles; -} - -int i386_device::get_extra_clock() -{ - return extra_cycles; -} - -uint32_t i386_device::get_pc() -{ - return m_prev_pc; -} - -uint32_t i386_device::get_next_pc() -{ - return m_pc; -} - -void i386_device::write_debug_data8(uint32_t addr, uint32_t data) -{ - int wait; - // ToDo: cache - d_mem->write_data8w(addr, data, &wait); -} - -void i386_device::write_debug_data16(uint32_t addr, uint32_t data) -{ - int wait; - // ToDo: cache - d_mem->write_data16w(addr, data, &wait); -} - -void i386_device::write_debug_data32(uint32_t addr, uint32_t data) -{ - int wait; - // ToDo: cache - d_mem->write_data32w(addr, data, &wait); -} - -uint32_t i386_device::read_debug_data8(uint32_t addr) -{ - int wait; - // ToDo: cache - return d_mem->read_data8w(addr, &wait); -} - -uint32_t i386_device::read_debug_data16(uint32_t addr) -{ - int wait; - // ToDo: cache - return d_mem->read_data16w(addr, &wait); -} - -uint32_t i386_device::read_debug_data32(uint32_t addr) -{ - int wait; - return d_mem->read_data32w(addr, &wait); -} - -void i386_device::write_debug_io8(uint32_t addr, uint32_t data) -{ - int wait; - d_io->write_io8w(addr, data, &wait); -} - -uint32_t i386_device::read_debug_io8(uint32_t addr) { - int wait; - return d_io->read_io8w(addr, &wait); -} - -void i386_device::write_debug_io16(uint32_t addr, uint32_t data) -{ - int wait; - d_io->write_io16w(addr, data, &wait); -} - -uint32_t i386_device::read_debug_io16(uint32_t addr) { - int wait; - return d_io->read_io16w(addr, &wait); -} - -void i386_device::write_debug_io32(uint32_t addr, uint32_t data) -{ - int wait; - d_io->write_io32w(addr, data, &wait); -} - -uint32_t i386_device::read_debug_io32(uint32_t addr) { - int wait; - return d_io->read_io32w(addr, &wait); -} - -int i386_device::get_mode() const -{ - return m_sreg[CS].d ? 32 : 16; -} -#if 0 -std::unique_ptr i386_device::create_disassembler() -{ - return std::make_unique(this); -} -#endif - -void i386_device::opcode_cpuid() -{ - logerror("CPUID called with unsupported EAX=%08x at %08x!\n", REG32(EAX), m_eip); -} - -uint64_t i386_device::opcode_rdmsr(bool &valid_msr) -{ - valid_msr = false; - logerror("RDMSR called with unsupported ECX=%08x at %08x!\n", REG32(ECX), m_eip); - return -1; -} - -void i386_device::opcode_wrmsr(uint64_t data, bool &valid_msr) -{ - valid_msr = false; - logerror("WRMSR called with unsupported ECX=%08x (%08x%08x) at %08x!\n", REG32(ECX), (uint32_t)(data >> 32), (uint32_t)data, m_eip); -} - -/*****************************************************************************/ -/* Intel 486 */ - - -void i486_device::initialize() -{ - i386_common_init(); - - build_opcode_table(OP_I386 | OP_FPU | OP_I486); - build_x87_opcode_table(); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_I486].get(); - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_I486].get(); - -// register_state_i386_x87(); -} - -void i486_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x00000010; - m_eflags = 0; - m_eflags_mask = 0x00077fd7; - m_eip = 0xfff0; - m_smm = false; - m_smi_latched = false; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 4 (486), Model 0/1 (DX), Stepping 3 - REG32(EAX) = 0; - REG32(EDX) = (4 << 8) | (0 << 4) | (3); - m_cpu_version = REG32(EDX); - - CHANGE_PC(m_eip); -} - -void i486dx4_device::reset() -{ - i486_device::reset(); - m_cpuid_id0 = 0x756e6547; // Genu - m_cpuid_id1 = 0x49656e69; // ineI - m_cpuid_id2 = 0x6c65746e; // ntel - - m_cpuid_max_input_value_eax = 0x01; - m_cpu_version = REG32(EDX); -} - -/*****************************************************************************/ -/* Pentium */ - - -void pentium_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87(); - - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM); - build_x87_opcode_table(); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM].get(); - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get(); -} - -void pentium_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x00000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x003f7fd7; - m_eip = 0xfff0; - m_mxcsr = 0x1f80; - m_smm = false; - m_smi_latched = false; - m_smbase = 0x30000; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 5 (Pentium), Model 2 (75 - 200MHz), Stepping 5 - REG32(EAX) = 0; - REG32(EDX) = (5 << 8) | (2 << 4) | (5); - - m_cpuid_id0 = 0x756e6547; // Genu - m_cpuid_id1 = 0x49656e69; // ineI - m_cpuid_id2 = 0x6c65746e; // ntel - - m_cpuid_max_input_value_eax = 0x01; - m_cpu_version = REG32(EDX); - - // [ 0:0] FPU on chip - // [ 2:2] I/O breakpoints - // [ 4:4] Time Stamp Counter - // [ 5:5] Pentium CPU style model specific registers - // [ 7:7] Machine Check Exception - // [ 8:8] CMPXCHG8B instruction - m_feature_flags = 0x000001bf; - - CHANGE_PC(m_eip); -} - - -/*****************************************************************************/ -/* Cyrix MediaGX */ - - -void mediagx_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87(); - - build_x87_opcode_table(); - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_CYRIX); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_MEDIAGX].get(); - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_MEDIAGX].get(); -} - -void mediagx_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x00000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x00277fd7; /* TODO: is this correct? */ - m_eip = 0xfff0; - m_smm = false; - m_smi_latched = false; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 4, Model 4 (MediaGX) - REG32(EAX) = 0; - REG32(EDX) = (4 << 8) | (4 << 4) | (1); /* TODO: is this correct? */ - - m_cpuid_id0 = 0x69727943; // Cyri - m_cpuid_id1 = 0x736e4978; // xIns - m_cpuid_id2 = 0x6d616574; // tead - - m_cpuid_max_input_value_eax = 0x01; - m_cpu_version = REG32(EDX); - - // [ 0:0] FPU on chip - m_feature_flags = 0x00000001; - - CHANGE_PC(m_eip); -} - -/*****************************************************************************/ -/* Intel Pentium Pro */ - -void pentium_pro_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87(); - - build_x87_opcode_table(); - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables -} - -void pentium_pro_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x60000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x00277fd7; /* TODO: is this correct? */ - m_eip = 0xfff0; - m_mxcsr = 0x1f80; - m_smm = false; - m_smi_latched = false; - m_smbase = 0x30000; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 6, Model 1 (Pentium Pro) - REG32(EAX) = 0; - REG32(EDX) = (6 << 8) | (1 << 4) | (1); /* TODO: is this correct? */ - - m_cpuid_id0 = 0x756e6547; // Genu - m_cpuid_id1 = 0x49656e69; // ineI - m_cpuid_id2 = 0x6c65746e; // ntel - - m_cpuid_max_input_value_eax = 0x02; - m_cpu_version = REG32(EDX); - - // [ 0:0] FPU on chip - // [ 2:2] I/O breakpoints - // [ 4:4] Time Stamp Counter - // [ 5:5] Pentium CPU style model specific registers - // [ 7:7] Machine Check Exception - // [ 8:8] CMPXCHG8B instruction - // [15:15] CMOV and FCMOV - // No MMX - m_feature_flags = 0x000081bf; - - CHANGE_PC(m_eip); -} - - -/*****************************************************************************/ -/* Intel Pentium MMX */ - -void pentium_mmx_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87(); - - build_x87_opcode_table(); - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_MMX); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables -} - -void pentium_mmx_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x60000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x00277fd7; /* TODO: is this correct? */ - m_eip = 0xfff0; - m_mxcsr = 0x1f80; - m_smm = false; - m_smi_latched = false; - m_smbase = 0x30000; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 5, Model 4 (P55C) - REG32(EAX) = 0; - REG32(EDX) = (5 << 8) | (4 << 4) | (1); - - m_cpuid_id0 = 0x756e6547; // Genu - m_cpuid_id1 = 0x49656e69; // ineI - m_cpuid_id2 = 0x6c65746e; // ntel - - m_cpuid_max_input_value_eax = 0x01; - m_cpu_version = REG32(EDX); - - // [ 0:0] FPU on chip - // [ 2:2] I/O breakpoints - // [ 4:4] Time Stamp Counter - // [ 5:5] Pentium CPU style model specific registers - // [ 7:7] Machine Check Exception - // [ 8:8] CMPXCHG8B instruction - // [23:23] MMX instructions - m_feature_flags = 0x008001bf; - - CHANGE_PC(m_eip); -} - -/*****************************************************************************/ -/* Intel Pentium II */ - -void pentium2_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87(); - - build_x87_opcode_table(); - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables -} - -void pentium2_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x60000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x00277fd7; /* TODO: is this correct? */ - m_eip = 0xfff0; - m_mxcsr = 0x1f80; - m_smm = false; - m_smi_latched = false; - m_smbase = 0x30000; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 6, Model 3 (Pentium II / Klamath) - REG32(EAX) = 0; - REG32(EDX) = (6 << 8) | (3 << 4) | (1); /* TODO: is this correct? */ - - m_cpuid_id0 = 0x756e6547; // Genu - m_cpuid_id1 = 0x49656e69; // ineI - m_cpuid_id2 = 0x6c65746e; // ntel - - m_cpuid_max_input_value_eax = 0x02; - m_cpu_version = REG32(EDX); - - // [ 0:0] FPU on chip - m_feature_flags = 0x008081bf; // TODO: enable relevant flags here - - CHANGE_PC(m_eip); -} - -/*****************************************************************************/ -/* Intel Pentium III */ - -void pentium3_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87_xmm(); - - build_x87_opcode_table(); - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables -} - -void pentium3_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x60000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x00277fd7; /* TODO: is this correct? */ - m_eip = 0xfff0; - m_mxcsr = 0x1f80; - m_smm = false; - m_smi_latched = false; - m_smbase = 0x30000; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 6, Model 8 (Pentium III / Coppermine) - REG32(EAX) = 0; - REG32(EDX) = (6 << 8) | (8 << 4) | (10); - - m_cpuid_id0 = 0x756e6547; // Genu - m_cpuid_id1 = 0x49656e69; // ineI - m_cpuid_id2 = 0x6c65746e; // ntel - - m_cpuid_max_input_value_eax = 0x03; - m_cpu_version = REG32(EDX); - - // [ 0:0] FPU on chip - // [ 4:4] Time Stamp Counter - // [ D:D] PTE Global Bit - m_feature_flags = 0x00002011; // TODO: enable relevant flags here - - CHANGE_PC(m_eip); -} -#if 0 -/*****************************************************************************/ -/* AMD Athlon XP - Model: Athlon XP 2400+ - Part number: AXDA2400DKV3C - Stepping code: AIUCP - Date code: 0240MPMW -*/ - -void athlonxp_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87_xmm(); - - build_x87_opcode_table(); - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables -} - -void athlonxp_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x60000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x00277fd7; /* TODO: is this correct? */ - m_eip = 0xfff0; - m_mxcsr = 0x1f80; - m_smm = false; - m_smi_latched = false; - m_smbase = 0x30000; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [11:8] Family - // [ 7:4] Model - // [ 3:0] Stepping ID - // Family 6, Model 8, Stepping 1 - REG32(EAX) = 0; - REG32(EDX) = (6 << 8) | (8 << 4) | (1); - - m_cpuid_id0 = ('h' << 24) | ('t' << 16) | ('u' << 8) | 'A'; // Auth - m_cpuid_id1 = ('i' << 24) | ('t' << 16) | ('n' << 8) | 'e'; // enti - m_cpuid_id2 = ('D' << 24) | ('M' << 16) | ('A' << 8) | 'c'; // cAMD - memset(m_processor_name_string, 0, 48); - strcpy((char *)m_processor_name_string, "AMD Athlon(tm) Processor"); - for (int n = 0; n < 11; n++) - m_msr_mtrrfix[n] = 0; - for (int n = 0; n < (1024 / 4); n++) - m_memory_ranges_1m[n] = 0; // change the 0 to 6 to test the cache just after reset - - m_cpuid_max_input_value_eax = 0x01; - m_cpu_version = REG32(EDX); - - // see FEATURE_FLAGS enum for bit names - m_feature_flags = 0x0383fbff; - - CHANGE_PC(m_eip); -} - -void athlonxp_device::parse_mtrrfix(u64 mtrr, offs_t base, int kblock) -{ - int nb = kblock / 4; - int range = (int)(base >> 12); // base must never be higher than 1 megabyte - - for (int n = 0; n < 8; n++) - { - uint8_t type = mtrr & 0xff; - - for (int b = 0; b < nb; b++) - { - m_memory_ranges_1m[range] = type; - range++; - } - mtrr = mtrr >> 8; - } -} - -int athlonxp_device::check_cacheable(offs_t address) -{ - offs_t block; - int disabled; - - disabled = 0; - if (m_cr[0] & (1 << 30)) - disabled = 128; - if (address >= 0x100000) - return disabled; - block = address >> 12; - return m_memory_ranges_1m[block] | disabled; -} - -template -dt athlonxp_device::opcode_read_cache(offs_t address) -{ - int mode = check_cacheable(address); - bool nocache = false; - u8 *data; - - if ((mode & 7) == 0) - nocache = true; - if (mode & 1) - nocache = true; - if (nocache == false) - { - int offset = (address & 63) ^ xorle; - data = cache.search(address); - if (data) - return *(dt *)(data + offset); - if (!(mode & 128)) - { - bool dirty = cache.allocate(address, &data); - address = cache.base(address); - if (dirty) - { - offs_t old_address = cache.old(); - - for (int w = 0; w < 64; w += 4) - macache32->write_data32(old_address + w, *(u32 *)(data + w)); - } - for (int r = 0; r < 64; r += 4) - *(u32 *)(data + r) = macache32->read_data32(address + r); - return *(dt *)(data + offset); - } - else - { - if (sizeof(dt) == 1) - return macache32->read_data8(address); - else if (sizeof(dt) == 2) - return macache32->read_data16(address); - else - return macache32->read_data32(address); - } - } - else - { - if (sizeof(dt) == 1) - return macache32->read_data8(address); - else if (sizeof(dt) == 2) - return macache32->read_data16(address); - else - return macache32->read_data32(address); - } -} - -template -dt athlonxp_device::program_read_cache(offs_t address) -{ - int mode = check_cacheable(address); - bool nocache = false; - u8 *data; - - if ((mode & 7) == 0) - nocache = true; - if (mode & 1) - nocache = true; - if (nocache == false) - { - int offset = (address & 63) ^ xorle; - data = cache.search(address); - if (data) - return *(dt *)(data + offset); - if (!(mode & 128)) - { - bool dirty = cache.allocate(address, &data); - address = cache.base(address); - if (dirty) - { - offs_t old_address = cache.old(); - - for (int w = 0; w < 64; w += 4) - m_program->write_dword(old_address + w, *(u32 *)(data + w)); - } - for (int r = 0; r < 64; r += 4) - *(u32 *)(data + r) = m_program->read_dword(address + r); - return *(dt *)(data + offset); - } - else - { - if (sizeof(dt) == 1) - return m_program->read_byte(address); - else if (sizeof(dt) == 2) - return m_program->read_word(address); - else - return m_program->read_dword(address); - } - } - else - { - if (sizeof(dt) == 1) - return m_program->read_byte(address); - else if (sizeof(dt) == 2) - return m_program->read_word(address); - else - return m_program->read_dword(address); - } -} - -template -void athlonxp_device::program_write_cache(offs_t address, dt data) -{ - int mode = check_cacheable(address); - bool nocache = false; - u8 *dataw; - - if ((mode & 7) == 0) - nocache = true; - if (mode & 1) - nocache = true; - if (nocache == false) - { - int offset = (address & 63) ^ xorle; - dataw = cache.search(address); - if (dataw) - { - *(dt *)(dataw + offset) = data; - return; - } - if (!(mode & 128)) - { - bool dirty = cache.allocate(address, &dataw); - address = cache.base(address); - if (dirty) - { - offs_t old_address = cache.old(); - - for (int w = 0; w < 64; w += 4) - m_program->write_dword(old_address + w, *(u32 *)(dataw + w)); - } - for (int r = 0; r < 64; r += 4) - *(u32 *)(dataw + r) = m_program->read_dword(address + r); - *(dt *)(dataw + offset) = data; - } - else - { - if (sizeof(dt) == 1) - m_program->write_byte(address, data); - else if (sizeof(dt) == 2) - m_program->write_word(address, data); - else - m_program->write_dword(address, data); - } - } - else - { - if (sizeof(dt) == 1) - m_program->write_byte(address, data); - else if (sizeof(dt) == 2) - m_program->write_word(address, data); - else - m_program->write_dword(address, data); - } -} - -void athlonxp_device::invalidate_cache(bool writeback) -{ - u32 base; - u8 *data; - - data = cache.first_dirty(base, true); - while (data != nullptr) - { - if (writeback) - for (int w = 0; w < 64; w += 4) - m_program->write_dword(base + w, *(u32 *)(data + w)); - data = cache.next_dirty(base, true); - } - cache.reset(); -} - -void athlonxp_device::opcode_invd() -{ - invalidate_cache(false); -} - -void athlonxp_device::opcode_wbinvd() -{ - invalidate_cache(true); -} -#endif - -/*****************************************************************************/ -/* Intel Pentium 4 */ - -void pentium4_device::initialize() -{ - i386_common_init(); -// register_state_i386_x87_xmm(); - - build_x87_opcode_table(); - build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM | OP_PPRO | OP_MMX | OP_SSE | OP_SSE2); - m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables - m_cycle_table_pm = cycle_table_pm[CPU_CYCLES_PENTIUM].get(); // TODO: generate own cycle tables -} - -void pentium4_device::reset() -{ - zero_state(); - - m_sreg[CS].selector = 0xf000; - m_sreg[CS].base = 0xffff0000; - m_sreg[CS].limit = 0xffff; - m_sreg[CS].flags = 0x0093; - - m_sreg[DS].base = m_sreg[ES].base = m_sreg[FS].base = m_sreg[GS].base = m_sreg[SS].base = 0x00000000; - m_sreg[DS].limit = m_sreg[ES].limit = m_sreg[FS].limit = m_sreg[GS].limit = m_sreg[SS].limit = 0xffff; - m_sreg[DS].flags = m_sreg[ES].flags = m_sreg[FS].flags = m_sreg[GS].flags = m_sreg[SS].flags = 0x0093; - - m_idtr.base = 0; - m_idtr.limit = 0x3ff; - - m_a20_mask = ~0; - - m_cr[0] = 0x60000010; - m_eflags = 0x00200000; - m_eflags_mask = 0x00277fd7; /* TODO: is this correct? */ - m_eip = 0xfff0; - m_mxcsr = 0x1f80; - m_smm = false; - m_smi_latched = false; - m_smbase = 0x30000; - m_nmi_masked = false; - m_nmi_latched = false; - - x87_reset(); - - // [27:20] Extended family - // [19:16] Extended model - // [13:12] Type - // [11: 8] Family - // [ 7: 4] Model - // [ 3: 0] Stepping ID - // Family 15, Model 0 (Pentium 4 / Willamette) - REG32(EAX) = 0; - REG32(EDX) = (0 << 20) | (0xf << 8) | (0 << 4) | (1); - - m_cpuid_id0 = 0x756e6547; // Genu - m_cpuid_id1 = 0x49656e69; // ineI - m_cpuid_id2 = 0x6c65746e; // ntel - - m_cpuid_max_input_value_eax = 0x02; - m_cpu_version = REG32(EDX); - - // [ 0:0] FPU on chip - m_feature_flags = 0x00000001; // TODO: enable relevant flags here - - CHANGE_PC(m_eip); -} - -bool i386_device::write_debug_reg(const _TCHAR *reg, uint32_t data) -{ - if(_tcsicmp(reg, _T("IP")) == 0) { - m_eip = data & 0xffff; - CHANGE_PC(m_eip); - } else if(_tcsicmp(reg, _T("EIP")) == 0) { - m_eip = data; - CHANGE_PC(m_eip); - } else if(_tcsicmp(reg, _T("EAX")) == 0) { - REG32(EAX) = data; - } else if(_tcsicmp(reg, _T("EBX")) == 0) { - REG32(EBX) = data; - } else if(_tcsicmp(reg, _T("ECX")) == 0) { - REG32(ECX) = data; - } else if(_tcsicmp(reg, _T("EDX")) == 0) { - REG32(EDX) = data; - } else if(_tcsicmp(reg, _T("ESP")) == 0) { - REG32(ESP) = data; - } else if(_tcsicmp(reg, _T("EBP")) == 0) { - REG32(EBP) = data; - } else if(_tcsicmp(reg, _T("ESI")) == 0) { - REG32(ESI) = data; - } else if(_tcsicmp(reg, _T("EDI")) == 0) { - REG32(EDI) = data; - } else if(_tcsicmp(reg, _T("AX")) == 0) { - REG16(AX) = data; - } else if(_tcsicmp(reg, _T("BX")) == 0) { - REG16(BX) = data; - } else if(_tcsicmp(reg, _T("CX")) == 0) { - REG16(CX) = data; - } else if(_tcsicmp(reg, _T("DX")) == 0) { - REG16(DX) = data; - } else if(_tcsicmp(reg, _T("SP")) == 0) { - REG16(SP) = data; - } else if(_tcsicmp(reg, _T("BP")) == 0) { - REG16(BP) = data; - } else if(_tcsicmp(reg, _T("SI")) == 0) { - REG16(SI) = data; - } else if(_tcsicmp(reg, _T("DI")) == 0) { - REG16(DI) = data; - } else if(_tcsicmp(reg, _T("AL")) == 0) { - REG8(AL) = data; - } else if(_tcsicmp(reg, _T("AH")) == 0) { - REG8(AH) = data; - } else if(_tcsicmp(reg, _T("BL")) == 0) { - REG8(BL) = data; - } else if(_tcsicmp(reg, _T("BH")) == 0) { - REG8(BH) = data; - } else if(_tcsicmp(reg, _T("CL")) == 0) { - REG8(CL) = data; - } else if(_tcsicmp(reg, _T("CH")) == 0) { - REG8(CH) = data; - } else if(_tcsicmp(reg, _T("DL")) == 0) { - REG8(DL) = data; - } else if(_tcsicmp(reg, _T("DH")) == 0) { - REG8(DH) = data; - } else { - return false; - } - return true; -} - -uint32_t i386_device::read_debug_reg(const _TCHAR *reg) -{ - if(_tcsicmp(reg, _T("EIP")) == 0) { - return m_eip; - } else if(_tcsicmp(reg, _T("IP")) == 0) { - return m_eip & 0xffff; - } else if(_tcsicmp(reg, _T("EAX")) == 0) { - return REG32(EAX); - } else if(_tcsicmp(reg, _T("EBX")) == 0) { - return REG32(EBX); - } else if(_tcsicmp(reg, _T("ECX")) == 0) { - return REG32(ECX); - } else if(_tcsicmp(reg, _T("EDX")) == 0) { - return REG32(EDX); - } else if(_tcsicmp(reg, _T("ESP")) == 0) { - return REG32(ESP); - } else if(_tcsicmp(reg, _T("EBP")) == 0) { - return REG32(EBP); - } else if(_tcsicmp(reg, _T("ESI")) == 0) { - return REG32(ESI); - } else if(_tcsicmp(reg, _T("EDI")) == 0) { - return REG32(EDI); - } else if(_tcsicmp(reg, _T("AX")) == 0) { - return REG16(AX); - } else if(_tcsicmp(reg, _T("BX")) == 0) { - return REG16(BX); - } else if(_tcsicmp(reg, _T("CX")) == 0) { - return REG16(CX); - } else if(_tcsicmp(reg, _T("DX")) == 0) { - return REG16(DX); - } else if(_tcsicmp(reg, _T("SP")) == 0) { - return REG16(SP); - } else if(_tcsicmp(reg, _T("BP")) == 0) { - return REG16(BP); - } else if(_tcsicmp(reg, _T("SI")) == 0) { - return REG16(SI); - } else if(_tcsicmp(reg, _T("DI")) == 0) { - return REG16(DI); - } else if(_tcsicmp(reg, _T("AL")) == 0) { - return REG8(AL); - } else if(_tcsicmp(reg, _T("AH")) == 0) { - return REG8(AH); - } else if(_tcsicmp(reg, _T("BL")) == 0) { - return REG8(BL); - } else if(_tcsicmp(reg, _T("BH")) == 0) { - return REG8(BH); - } else if(_tcsicmp(reg, _T("CL")) == 0) { - return REG8(CL); - } else if(_tcsicmp(reg, _T("CH")) == 0) { - return REG8(CH); - } else if(_tcsicmp(reg, _T("DL")) == 0) { - return REG8(DL); - } else if(_tcsicmp(reg, _T("DH")) == 0) { - return REG8(DH); - } - return 0; -} - -void i386_device::dump_segs(_TCHAR *buffer, _TCHAR* label, int segnum, size_t len) -{ - if((segnum < 0) || (segnum >= 6)) { - memset(buffer, 0x00, len); - return; - } - snprintf_s(buffer, len, "%s:%04X BASE=%08X LIMIT=%08X D=%d FLAGS=%04X VALID=%s\n", - label, - m_sreg[segnum].selector, m_sreg[segnum].base, m_sreg[segnum].limit, - m_sreg[segnum].d, m_sreg[segnum].flags, (m_sreg[segnum].valid) ? "YES" : "NO"); -} - -void i386_device::dump_regs(_TCHAR *buffer, size_t len) -{ - _TCHAR minibuffer[512]; - snprintf(minibuffer, 512, "PC=%08X EIP=%08X ", m_pc, m_eip); - strncat(buffer, minibuffer, len); - snprintf(minibuffer, 512, "PREV_PC=%08X PREV_EIP=%08X \n", m_prev_pc, m_prev_eip); - strncat(buffer, minibuffer, len); - dump_segs(minibuffer, "CS", CS, 512); - strncat(buffer, minibuffer, len); - dump_segs(minibuffer, "SS", SS, 512); - strncat(buffer, minibuffer, len); - dump_segs(minibuffer, "DS", DS, 512); - strncat(buffer, minibuffer, len); - dump_segs(minibuffer, "ES", ES, 512); - strncat(buffer, minibuffer, len); - dump_segs(minibuffer, "FS", FS, 512); - strncat(buffer, minibuffer, len); - dump_segs(minibuffer, "GS", GS, 512); - strncat(buffer, minibuffer, len); - - snprintf(minibuffer, 512, "IOPL=%d CPL=%d EFLAGS=%08X EFLAGS_MASK=%08X\n", ((m_IOP1) | (m_IOP2 << 1)), m_CPL, m_eflags, m_eflags_mask); - strncat(buffer, minibuffer, len); - snprintf(minibuffer, 512, "FLAGS: %s%s%s%s %s%s%s%s\n %s%s%s%s %s%s%s%s\n", - (m_CF == 0) ? "--" : "CF", (m_DF == 0) ? "--" : "CF", (m_SF == 0) ? "--" : "SF", (m_OF == 0) ? "--" : "OF", - (m_ZF == 0) ? "-- " : "ZF ", (m_PF == 0) ? "-- " : "PF ", (m_AF == 0) ? "-- " : "AF ", (m_IF == 0) ? "-- " : "IF ", - (m_TF == 0) ? "--" : "TF", (m_NT == 0) ? "--" : "NT", (m_RF == 0) ? "--" : "RF", (m_VM == 0) ? "--" : "VM", - (m_AC == 0) ? "-- " : "AC ", - (m_VIF == 0) ? "---" : "VIF", (m_VIP == 0) ? "---" : "VIP", (m_ID == 0) ? "-- " : "ID "); - strncat(buffer, minibuffer, len); - - snprintf(minibuffer, 512, "EAX=%08X ECX=%08X EDX=%08X EBX=%08X\n", REG32(EAX), REG32(ECX), REG32(EDX), REG32(EBX)); - strncat(buffer, minibuffer, len); - - snprintf(minibuffer, 512, "ESP=%08X EBP=%08X ESI=%08X EDI=%08X\n", REG32(ESP), REG32(EBP), REG32(ESI), REG32(EDI)); - strncat(buffer, minibuffer, len); -} - -bool i386_device::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) -{ - if(buffer == NULL) return false; - if(buffer_len <= 0) return false; - memset(buffer, 0x00, buffer_len * sizeof(_TCHAR)); - // ToDo: XMM, x87 - dump_regs(buffer, buffer_len); - if(buffer[buffer_len - 1] != '\0') return false; - return true; -} - -const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length - -int I386::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len) -{ -// UINT64 eip = pc - sreg[CS].base; -// UINT8 ops[16]; -// for(int i = 0; i < 16; i++) { -// int wait; -// ops[i] = d_mem->read_data8w(pc + i, &wait); -// } -// UINT8 *oprom = ops; - if(d_dasm == NULL) return 0; - if((buffer == NULL) || (buffer_len <= 0)) return 0; - int reply = d_dasm->disassemble(pc, buffer, buffer_len, this); - reply = reply & DASMFLAG_LENGTHMASK; - return reply; -} diff --git a/source/src/vm/libcpu_newdev/i386/i386_device.h b/source/src/vm/libcpu_newdev/i386/i386_device.h deleted file mode 100644 index 317f87941..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386_device.h +++ /dev/null @@ -1,1907 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -#ifndef MAME_CPU_I386_I386_H -#define MAME_CPU_I386_I386_H - -#pragma once - -// SoftFloat 2 lacks an include guard -#ifndef softfloat_h -#define softfloat_h 1 -#include "../softfloat/milieu.h" -#include "../softfloat/softfloat.h" -#endif - -#include "debug/debugger.h" -#include "../divtlb.h" - -#include "./i386dasm.h" -//#include "./cache.h" - -#define SIG_I386_A20 1 -#define SIG_I386_SMI 2 -enum -{ - INPUT_LINE_IRQ = 0, - INPUT_LINE_NMI -}; - -typedef u8 uint8_t; -typedef u16 uint16_t; -typedef u32 uint32_t; -typedef u64 uint64_t; - -// mingw has this defined for 32-bit compiles -#undef i386 - -#define X86_NUM_CPUS 4 - -#include "../address_spacenum.h" - -class VM_TEMPLATE; -class EMU; -class DEBUGGER; -class i386_device : public DEVICE -{ -protected: - outputs_t outputs_reset; - DEVICE* d_mem; - DEVICE* d_io; - DEVICE* d_dma; - DEVICE* d_pic; - DEVICE* d_bios; - - DEBUGGER* d_debugger; - DEVICE* d_program_stored, d_io_stored; - - int m_wait; -public: - // construction/destruction - i386_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - ~i386_device(); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; - virtual int __FASTCALL run(int clocks); - virtual uint32_t __FASTCALL read_signal(int ch); - virtual void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); - virtual void set_intr_line(bool line, bool pending, uint32_t bit); - virtual void set_extra_clock(int cycles); - virtual int get_extra_clock(); - uint32_t get_pc(); - uint32_t get_next_pc(); - uint32_t __FASTCALL translate_address(int segment, uint32_t offset); -//#ifdef USE_DEBUGGER - bool is_cpu() - { - return true; - } - bool is_debugger_available() - { - return true; - } - void *get_debugger() - { - return d_debugger; - } - uint32_t get_debug_prog_addr_mask() - { - return 0xffffffff; - } - uint32_t get_debug_data_addr_mask() - { - return 0xffffffff; - } - void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_data8(uint32_t addr); - void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_data16(uint32_t addr); - void __FASTCALL write_debug_data32(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_data32(uint32_t addr); - void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_io8(uint32_t addr); - void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_io32(uint32_t addr); - void __FASTCALL write_debug_io32(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_io16(uint32_t addr); - bool write_debug_reg(const _TCHAR *reg, uint32_t data); - uint32_t __FASTCALL read_debug_reg(const _TCHAR *reg); - bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); - int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); - - - void set_address_mask(uint32_t mask) - { - m_a20_mask = mask; - d_vtlb->vtlb_flush_dynamic(); - } - uint32_t get_address_mask() - { - return m_a20_mask; - } - void set_shutdown_flag(int shutdown) - { - m_shutdown = (shutdown != 0) ? true : false; - } - int set_shutdown_flag() - { - return (m_shutdown) ? 1 : 0; - } - - void set_context_mem(DEVICE* device) - { - d_mem = device; - } - void set_context_io(DEVICE* device) - { - d_io = device; - } - void set_context_intr(DEVICE* device) - { - d_pic = device; - } - void set_context_bios(DEVICE* device) - { - d_bios = device; - } - void set_context_dma(DEVICE* device) - { - d_dma = device; - } - void set_context_debugger(DEBUGGER* device) - { - d_debugger = device; - } - void set_reset_line(DEVICE* dev, int id, uint32_t mask) - { - register_output_signal(&outputs_reset, dev, id, mask); - } -#if 0 - void set_cachable_region(uint32_t start, uint32_t end, DEVICE* dev = NULL, int type = CACHE_LINE_READ_WRITE) - { - cache_line *p; - if(dev == NULL) { - p = new cache_line(start, end, d_device, type); - } else { - p = new cache_line(start, end, dev, type); - } - if(p != NULL) { - cache_mem.push_back(p); - } - } - void delete_cachable_region(uint32_t start, uint32_t end) - { - for(auto pp = cache_mem.begin(); pp != cache_mem.end(); ++pp) { - cache_line* p = *pp; - if(p != NULL) { - if((p->get_start_address() == start) && (p->get_end_address() == end)) { - delete p; - pcache_mem.erace(pp); - } - } - } - } - void change_cache_type(uint32_t start, uint32_t end, int new_mode) - { - for(auto pp = cache_mem.begin(); pp != cache_mem.end(); ++pp) { - cache_line* p = *pp; - if(p != NULL) { - if((p->get_start_address() == start) && (p->get_end_address() == end)) { - p->change_access_mode(new_mode); - } - } - } - } -#endif - // configuration helpers -#if 0 - uint64_t debug_segbase(symbol_table &table, int params, const uint64_t *param); - uint64_t debug_seglimit(symbol_table &table, int params, const uint64_t *param); - uint64_t debug_segofftovirt(symbol_table &table, int params, const uint64_t *param); - uint64_t debug_virttophys(symbol_table &table, int params, const uint64_t *param); -#endif -protected: - device_vtlb_interface* d_vtlb; - bool process_state_segment(int num, FILEIO* state_fio, bool loading); - bool process_state_i386(FILEIO* state_fio, bool loading); - bool process_state_i386_x87(FILEIO* state_fio, bool loading); - bool process_state_i386_xmm(FILEIO* state_fio, bool loading); - - bool bios_int_x86(int num); - bool bios_call_far_x86(uint32_t address); - bool bios_trap_x86(uint32_t address, int &stat); - - // device-level overrides - //virtual void device_debug_setup() override; - - // device_execute_interface overrides - virtual uint32_t execute_min_cycles() const override { return 1; } - virtual uint32_t execute_max_cycles() const override { return 40; } - virtual uint32_t execute_input_lines() const override { return 32; } - - // device_memory_interface overrides - virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; - - // device_state_interface overrides - //virtual void state_import(const device_state_entry &entry) override; - //virtual void state_export(const device_state_entry &entry) override; - //virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - - // device_disasm_interface overrides - //virtual std::unique_ptr create_disassembler() override; - virtual int get_mode() const override; - - // routines for opcodes whose operation can vary between cpu models - // default implementations usually just log an error message - virtual void opcode_cpuid(); - virtual __FASTCALL uint64_t opcode_rdmsr(bool &valid_msr); - virtual __FASTCALL void opcode_wrmsr(uint64_t data, bool &valid_msr); - virtual void opcode_invd() {} - virtual void opcode_wbinvd() {} - - // routine to access memory - // ToDo: Memory cache -#if 1 - virtual u8 __FASTCALL mem_pr8(offs_t address) { return d_mem->read_data8(address); } - virtual u16 __FASTCALL mem_pr16(offs_t address) { return d_mem->read_data16(address); } - virtual u32 __FASTCALL mem_pr32(offs_t address) { return d_mem->read_data32(address); } - - virtual u8 __FASTCALL mem_prd8(offs_t address) { return d_mem->read_data8(address); } - virtual u16 __FASTCALL mem_prd16(offs_t address) { return d_mem->read_data16(address); } - virtual u32 __FASTCALL mem_prd32(offs_t address) { return d_mem->read_data32(address); } - virtual void __FASTCALL mem_pwd8(offs_t address, u8 data) { d_mem->write_data8(address, data); } - virtual void __FASTCALL mem_pwd16(offs_t address, u16 data) { d_mem->write_data16(address, data); } - virtual void __FASTCALL mem_pwd32(offs_t address, u32 data) { d_mem->write_data32(address, data); } -#else - virtual u8 mem_pr8(offs_t address) { - int n = cache_mem.size(); - for(int i = 0; i < n; i++) { - cache_line* p = cache_mem[i]; - if(p != NULL) { - if(p->region_check(address)) { - return p->read_data8w(addr, &m_wait); - } - } - } - return d_device->read_data8w(address, &m_wait); - } - virtual u16 mem_pr16(offs_t address) { - int n = cache_mem.size(); - for(int i = 0; i < n; i++) { - cache_line* p = cache_mem[i]; - if(p != NULL) { - if(p->region_check_range(address, 2)) { - return p->read_data16w(addr, &m_wait); - } - } - } - return d_device->read_data16w(address, &m_wait); - } - virtual u32 mem_pr32(offs_t address) { - int n = cache_mem.size(); - for(int i = 0; i < n; i++) { - cache_line* p = cache_mem[i]; - if(p != NULL) { - if(p->region_check_range(address, 4)) { - return p->read_data32w(addr, &m_wait); - } - } - } - return d_device->read_data32w(address, &m_wait); - } - - virtual u8 mem_prd8(offs_t address) { return d_mem->read_data8(address); } - virtual u16 mem_prd16(offs_t address) { return d_mem->read_data16(address); } - virtual u32 mem_prd32(offs_t address) { return d_mem->read_data32(address); } - virtual void mem_pwd8(offs_t address, u8 data) { d_mem->write_data8(address, data); } - virtual void mem_pwd16(offs_t address, u16 data) { d_mem->write_data16(address, data); } - virtual void mem_pwd32(offs_t address, u32 data) { d_mem->write_data32(address, data); } -#endif - //address_space_config m_mem_config; - //address_space_config m_io_config; - - std::unique_ptr cycle_table_rm[X86_NUM_CPUS]; - std::unique_ptr cycle_table_pm[X86_NUM_CPUS]; - - - union I386_GPR { - uint32_t d[8]; - uint16_t w[16]; - uint8_t b[32]; - }; - - struct I386_SREG { - uint16_t selector; - uint16_t flags; - uint32_t base; - uint32_t limit; - int d; // Operand size - bool valid; - }; - - struct I386_SYS_TABLE { - uint32_t base; - uint16_t limit; - }; - - struct I386_SEG_DESC { - uint16_t segment; - uint16_t flags; - uint32_t base; - uint32_t limit; - }; - - union XMM_REG { - uint8_t b[16]; - uint16_t w[8]; - uint32_t d[4]; - uint64_t q[2]; - int8_t c[16]; - int16_t s[8]; - int32_t i[4]; - int64_t l[2]; - float f[4]; - double f64[2]; - }; - - union MMX_REG { - uint32_t d[2]; - int32_t i[2]; - uint16_t w[4]; - int16_t s[4]; - uint8_t b[8]; - int8_t c[8]; - float f[2]; - uint64_t q; - int64_t l; - }; - - struct I386_CALL_GATE - { - uint16_t segment; - uint16_t selector; - uint32_t offset; - uint8_t ar; // access rights - uint8_t dpl; - uint8_t dword_count; - uint8_t present; - }; - - enum FEATURE_FLAGS : uint32_t { - // returned in the EDX register - FF_PBE = (u32)1 << 31, // Pend. Brk. EN. - FF_TM = 1 << 29, // Thermal Monitor - FF_HTT = 1 << 28, // Multi-threading - FF_SS = 1 << 27, // Self Snoop - FF_SSE2 = 1 << 26, // SSE2 Extensions - FF_SSE = 1 << 25, // SSE Extensions - FF_FXSR = 1 << 24, // FXSAVE/FXRSTOR - FF_MMX = 1 << 23, // MMX Technology - FF_ACPI = 1 << 22, // Thermal Monitor and Clock Ctrl - FF_DS = 1 << 21, // Debug Store - FF_CLFSH = 1 << 19, // CLFLUSH instruction - FF_PSN = 1 << 18, // Processor Serial Number - FF_PSE36 = 1 << 17, // 36 Bit Page Size Extension - FF_PAT = 1 << 16, // Page Attribute Table - FF_CMOV = 1 << 15, // Conditional Move/Compare Instruction - FF_MCA = 1 << 14, // Machine Check Architecture - FF_PGE = 1 << 13, // PTE Global Bit - FF_MTRR = 1 << 12, // Memory Type Range Registers - FF_SEP = 1 << 11, // SYSENTER and SYSEXIT - FF_APIC = 1 << 9, // APIC on Chip - FF_CX8 = 1 << 8, // CMPXCHG8B Inst. - FF_MCE = 1 << 7, // Machine Check Exception - FF_PAE = 1 << 6, // Physical Address Extensions - FF_MSR = 1 << 5, // RDMSR and WRMSR Support - FF_TSC = 1 << 4, // Time Stamp Counter - FF_PSE = 1 << 3, // Page Size Extensions - FF_DE = 1 << 2, // Debugging Extensions - FF_VME = 1 << 1, // Virtual-8086 Mode Enhancement - FF_FPU = 1 << 0, // x87 FPU on Chip - // retuned in the ECX register - FF_RDRAND = 1 << 30, - FF_F16C = 1 << 29, - FF_AVX = 1 << 28, - FF_OSXSAVE = 1 << 27, - FF_XSAVE = 1 << 26, - FF_AES = 1 << 25, - FF_TSCD = 1 << 24, // Deadline - FF_POPCNT = 1 << 23, - FF_MOVBE = 1 << 22, - FF_x2APIC = 1 << 21, - FF_SSE4_2 = 1 << 20, // SSE4.2 - FF_SSE4_1 = 1 << 19, // SSE4.1 - FF_DCA = 1 << 18, // Direct Cache Access - FF_PCID = 1 << 17, // Process-context Identifiers - FF_PDCM = 1 << 15, // Perf/Debug Capability MSR - FF_xTPR = 1 << 14, // Update Control - FF_CMPXCHG16B = 1 << 13, - FF_FMA = 1 << 12, // Fused Multiply Add - FF_SDBG = 1 << 11, - FF_CNXT_ID = 1 << 10, // L1 Context ID - FF_SSSE3 = 1 << 9, // SSSE3 Extensions - FF_TM2 = 1 << 8, // Thermal Monitor 2 - FF_EIST = 1 << 7, // Enhanced Intel SpeedStep Technology - FF_SMX = 1 << 6, // Safer Mode Extensions - FF_VMX = 1 << 5, // Virtual Machine Extensions - FF_DS_CPL = 1 << 4, // CPL Qualified Debug Store - FF_MONITOR = 1 << 3, // MONITOR/MWAIT - FF_DTES64 = 1 << 2, // 64 Bit DS Area - FF_PCLMULQDQ = 1 << 1, // Carryless Multiplication - FF_SSE3 = 1 << 0, // SSE3 Extensions - }; - - typedef void (i386_device::*i386_modrm_func)(uint8_t modrm); - typedef void (i386_device::*i386_op_func)(); - struct X86_OPCODE { - uint8_t opcode; - uint32_t flags; - i386_op_func handler16; - i386_op_func handler32; - bool lockable; - }; - static const X86_OPCODE s_x86_opcode_table[]; - - I386_GPR m_reg; - I386_SREG m_sreg[6]; - uint32_t m_eip; - uint32_t m_pc; - uint32_t m_prev_eip; - uint32_t m_eflags; - uint32_t m_eflags_mask; - uint8_t m_CF; - uint8_t m_DF; - uint8_t m_SF; - uint8_t m_OF; - uint8_t m_ZF; - uint8_t m_PF; - uint8_t m_AF; - uint8_t m_IF; - uint8_t m_TF; - uint8_t m_IOP1; - uint8_t m_IOP2; - uint8_t m_NT; - uint8_t m_RF; - uint8_t m_VM; - uint8_t m_AC; - uint8_t m_VIF; - uint8_t m_VIP; - uint8_t m_ID; - - uint8_t m_CPL; // current privilege level - - uint8_t m_performed_intersegment_jump; - uint8_t m_delayed_interrupt_enable; - - uint32_t m_cr[5]; // Control registers - uint32_t m_dr[8]; // Debug registers - uint32_t m_tr[8]; // Test registers - - I386_SYS_TABLE m_gdtr; // Global Descriptor Table Register - I386_SYS_TABLE m_idtr; // Interrupt Descriptor Table Register - I386_SEG_DESC m_task; // Task register - I386_SEG_DESC m_ldtr; // Local Descriptor Table Register - - uint8_t m_ext; // external interrupt - - int m_halted; - int m_busreq; - - int m_operand_size; - int m_xmm_operand_size; - int m_address_size; - int m_operand_prefix; - int m_address_prefix; - - int m_segment_prefix; - int m_segment_override; - - int m_cycles; - int m_base_cycles; - int64_t total_cycles; - int64_t prev_total_cycles; - int extra_cycles; - - uint8_t m_opcode; - - uint8_t m_irq_state; - uint32_t m_a20_mask; - bool m_shutdown; - // ToDo: Memory Cache. - //memory_access_cache<1, 0, ENDIANNESS_LITTLE> *macache16; - //memory_access_cache<2, 0, ENDIANNESS_LITTLE> *macache32; -// std::vectorcache_data; - - int m_cpuid_max_input_value_eax; // Highest CPUID standard function available - uint32_t m_cpuid_id0, m_cpuid_id1, m_cpuid_id2; - uint32_t m_cpu_version; - uint32_t m_feature_flags; - uint64_t m_tsc; - uint64_t m_perfctr[2]; - - // FPU - floatx80 m_x87_reg[8]; - - uint16_t m_x87_cw; - uint16_t m_x87_sw; - uint16_t m_x87_tw; - uint64_t m_x87_data_ptr; - uint64_t m_x87_inst_ptr; - uint16_t m_x87_opcode; - - i386_modrm_func m_opcode_table_x87_d8[256]; - i386_modrm_func m_opcode_table_x87_d9[256]; - i386_modrm_func m_opcode_table_x87_da[256]; - i386_modrm_func m_opcode_table_x87_db[256]; - i386_modrm_func m_opcode_table_x87_dc[256]; - i386_modrm_func m_opcode_table_x87_dd[256]; - i386_modrm_func m_opcode_table_x87_de[256]; - i386_modrm_func m_opcode_table_x87_df[256]; - - // SSE - XMM_REG m_sse_reg[8]; - uint32_t m_mxcsr; - - i386_op_func m_opcode_table1_16[256]; - i386_op_func m_opcode_table1_32[256]; - i386_op_func m_opcode_table2_16[256]; - i386_op_func m_opcode_table2_32[256]; - i386_op_func m_opcode_table338_16[256]; - i386_op_func m_opcode_table338_32[256]; - i386_op_func m_opcode_table33a_16[256]; - i386_op_func m_opcode_table33a_32[256]; - i386_op_func m_opcode_table366_16[256]; - i386_op_func m_opcode_table366_32[256]; - i386_op_func m_opcode_table3f2_16[256]; - i386_op_func m_opcode_table3f2_32[256]; - i386_op_func m_opcode_table3f3_16[256]; - i386_op_func m_opcode_table3f3_32[256]; - i386_op_func m_opcode_table46638_16[256]; - i386_op_func m_opcode_table46638_32[256]; - i386_op_func m_opcode_table4f238_16[256]; - i386_op_func m_opcode_table4f238_32[256]; - i386_op_func m_opcode_table4f338_16[256]; - i386_op_func m_opcode_table4f338_32[256]; - i386_op_func m_opcode_table4663a_16[256]; - i386_op_func m_opcode_table4663a_32[256]; - i386_op_func m_opcode_table4f23a_16[256]; - i386_op_func m_opcode_table4f23a_32[256]; - - bool m_lock_table[2][256]; - - uint8_t *m_cycle_table_pm; - uint8_t *m_cycle_table_rm; - - bool m_smm; - bool m_smi; - bool m_smi_latched; - bool m_nmi_masked; - bool m_nmi_latched; - uint32_t m_smbase; - DEVICE* m_smiact; - DEVICE* m_ferr_handler; - bool m_smiact_enabled; - int m_ferr_err_value; - bool m_lock; - - // bytes in current opcode, debug only - uint8_t m_opcode_bytes[16]; - uint32_t m_opcode_pc; - int m_opcode_bytes_length; - - uint64_t m_debugger_temp; - - void register_state_i386(); - void register_state_i386_x87(); - void register_state_i386_x87_xmm(); - inline uint32_t __FASTCALL i386_translate(int segment, uint32_t ip, int rwn); - inline vtlb_entry __FASTCALL get_permissions(uint32_t pte, int wp); - bool __FASTCALL i386_translate_address(int intention, offs_t *address, vtlb_entry *entry); - inline bool __FASTCALL translate_address(int pl, int type, uint32_t *address, uint32_t *error); - inline void __FASTCALL CHANGE_PC(uint32_t pc); - inline void __FASTCALL NEAR_BRANCH(int32_t offs); - inline uint8_t FETCH(); - inline uint16_t FETCH16(); - inline uint32_t FETCH32(); - inline uint8_t __FASTCALL READ8(uint32_t ea); - inline uint16_t __FASTCALL READ16(uint32_t ea); - inline uint32_t __FASTCALL READ32(uint32_t ea); - inline uint64_t __FASTCALL READ64(uint32_t ea); - inline uint8_t __FASTCALL READ8PL0(uint32_t ea); - inline uint16_t __FASTCALL READ16PL0(uint32_t ea); - inline uint32_t __FASTCALL READ32PL0(uint32_t ea); - inline void __FASTCALL WRITE_TEST(uint32_t ea); - inline void __FASTCALL WRITE8(uint32_t ea, uint8_t value); - inline void __FASTCALL WRITE16(uint32_t ea, uint16_t value); - inline void __FASTCALL WRITE32(uint32_t ea, uint32_t value); - inline void __FASTCALL WRITE64(uint32_t ea, uint64_t value); - inline uint8_t __FASTCALL OR8(uint8_t dst, uint8_t src); - inline uint16_t __FASTCALL OR16(uint16_t dst, uint16_t src); - inline uint32_t __FASTCALL OR32(uint32_t dst, uint32_t src); - inline uint8_t __FASTCALL AND8(uint8_t dst, uint8_t src); - inline uint16_t __FASTCALL AND16(uint16_t dst, uint16_t src); - inline uint32_t __FASTCALL AND32(uint32_t dst, uint32_t src); - inline uint8_t __FASTCALL XOR8(uint8_t dst, uint8_t src); - inline uint16_t __FASTCALL XOR16(uint16_t dst, uint16_t src); - inline uint32_t __FASTCALL XOR32(uint32_t dst, uint32_t src); - inline uint8_t __FASTCALL SBB8(uint8_t dst, uint8_t src, uint8_t b); - inline uint16_t __FASTCALL SBB16(uint16_t dst, uint16_t src, uint16_t b); - inline uint32_t __FASTCALL SBB32(uint32_t dst, uint32_t src, uint32_t b); - inline uint8_t __FASTCALL ADC8(uint8_t dst, uint8_t src, uint8_t c); - inline uint16_t __FASTCALL ADC16(uint16_t dst, uint16_t src, uint8_t c); - inline uint32_t __FASTCALL ADC32(uint32_t dst, uint32_t src, uint32_t c); - inline uint8_t __FASTCALL INC8(uint8_t dst); - inline uint16_t __FASTCALL INC16(uint16_t dst); - inline uint32_t __FASTCALL INC32(uint32_t dst); - inline uint8_t DEC8(uint8_t dst); - inline uint16_t DEC16(uint16_t dst); - inline uint32_t DEC32(uint32_t dst); - inline void __FASTCALL PUSH16(uint16_t value); - inline void __FASTCALL PUSH32(uint32_t value); - inline void __FASTCALL PUSH32SEG(uint32_t value); - inline void __FASTCALL PUSH8(uint8_t value); - inline uint8_t POP8(); - inline uint16_t POP16(); - inline uint32_t POP32(); - inline void __FASTCALL BUMP_SI(int adjustment); - inline void __FASTCALL BUMP_DI(int adjustment); - inline void __FASTCALL check_ioperm(offs_t port, uint8_t mask); - inline uint8_t __FASTCALL READPORT8(offs_t port); - inline void __FASTCALL WRITEPORT8(offs_t port, uint8_t value); - inline uint16_t __FASTCALL READPORT16(offs_t port); - inline void __FASTCALL WRITEPORT16(offs_t port, uint16_t value); - inline uint32_t __FASTCALL READPORT32(offs_t port); - inline void WRITEPORT32(offs_t port, uint32_t value); - uint32_t __FASTCALL i386_load_protected_mode_segment(I386_SREG *seg, uint64_t *desc ); - void __FASTCALL i386_load_call_gate(I386_CALL_GATE *gate); - void __FASTCALL i386_set_descriptor_accessed(uint16_t selector); - void __FASTCALL i386_load_segment_descriptor(int segment ); - uint32_t __FASTCALL i386_get_stack_segment(uint8_t privilege); - uint32_t __FASTCALL i386_get_stack_ptr(uint8_t privilege); - uint32_t get_flags() const; - void __FASTCALL set_flags(uint32_t f ); - void __FASTCALL sib_byte(uint8_t mod, uint32_t* out_ea, uint8_t* out_segment); - void __FASTCALL modrm_to_EA(uint8_t mod_rm, uint32_t* out_ea, uint8_t* out_segment); - uint32_t __FASTCALL GetNonTranslatedEA(uint8_t modrm,uint8_t *seg); - uint32_t __FASTCALL GetEA(uint8_t modrm, int rwn); - void __FASTCALL i386_check_sreg_validity(int reg); - int __FASTCALL i386_limit_check(int seg, uint32_t offset); - void __FASTCALL i386_sreg_load(uint16_t selector, uint8_t reg, bool *fault); - void i386_trap(int irq, int irq_gate, int trap_level); - void i386_trap_with_error(int irq, int irq_gate, int trap_level, uint32_t error); - void i286_task_switch(uint16_t selector, uint8_t nested); - void i386_task_switch(uint16_t selector, uint8_t nested); - void i386_check_irq_line(); - void i386_protected_mode_jump(uint16_t seg, uint32_t off, int indirect, int operand32); - void i386_protected_mode_call(uint16_t seg, uint32_t off, int indirect, int operand32); - void i386_protected_mode_retf(uint8_t count, uint8_t operand32); - void i386_protected_mode_iret(int operand32); - void build_cycle_table(); - void report_invalid_opcode(); - void __FASTCALL report_invalid_modrm(const char* opcode, uint8_t modrm); - void i386_decode_opcode(); - void i386_decode_two_byte(); - void i386_decode_three_byte38(); - void i386_decode_three_byte3a(); - void i386_decode_three_byte66(); - void i386_decode_three_bytef2(); - void i386_decode_three_bytef3(); - void i386_decode_four_byte3866(); - void i386_decode_four_byte3a66(); - void i386_decode_four_byte38f2(); - void i386_decode_four_byte3af2(); - void i386_decode_four_byte38f3(); - uint8_t __FASTCALL read8_debug(uint32_t ea, uint8_t *data); - //uint32_t i386_get_debug_desc(I386_SREG *seg); - inline void __FASTCALL CYCLES(int x); - inline void __FASTCALL CYCLES_RM(int modrm, int r, int m); - uint8_t __FASTCALL i386_shift_rotate8(uint8_t modrm, uint32_t value, uint8_t shift); - void i386_adc_rm8_r8(); - void i386_adc_r8_rm8(); - void i386_adc_al_i8(); - void i386_add_rm8_r8(); - void i386_add_r8_rm8(); - void i386_add_al_i8(); - void i386_and_rm8_r8(); - void i386_and_r8_rm8(); - void i386_and_al_i8(); - void i386_clc(); - void i386_cld(); - void i386_cli(); - void i386_cmc(); - void i386_cmp_rm8_r8(); - void i386_cmp_r8_rm8(); - void i386_cmp_al_i8(); - void i386_cmpsb(); - void i386_in_al_i8(); - void i386_in_al_dx(); - void i386_ja_rel8(); - void i386_jbe_rel8(); - void i386_jc_rel8(); - void i386_jg_rel8(); - void i386_jge_rel8(); - void i386_jl_rel8(); - void i386_jle_rel8(); - void i386_jnc_rel8(); - void i386_jno_rel8(); - void i386_jnp_rel8(); - void i386_jns_rel8(); - void i386_jnz_rel8(); - void i386_jo_rel8(); - void i386_jp_rel8(); - void i386_js_rel8(); - void i386_jz_rel8(); - void i386_jmp_rel8(); - void i386_lahf(); - void i386_lodsb(); - void i386_mov_rm8_r8(); - void i386_mov_r8_rm8(); - void i386_mov_rm8_i8(); - void i386_mov_r32_cr(); - void i386_mov_r32_dr(); - void i386_mov_cr_r32(); - void i386_mov_dr_r32(); - void i386_mov_al_m8(); - void i386_mov_m8_al(); - void i386_mov_rm16_sreg(); - void i386_mov_sreg_rm16(); - void i386_mov_al_i8(); - void i386_mov_cl_i8(); - void i386_mov_dl_i8(); - void i386_mov_bl_i8(); - void i386_mov_ah_i8(); - void i386_mov_ch_i8(); - void i386_mov_dh_i8(); - void i386_mov_bh_i8(); - void i386_movsb(); - void i386_or_rm8_r8(); - void i386_or_r8_rm8(); - void i386_or_al_i8(); - void i386_out_al_i8(); - void i386_out_al_dx(); - void i386_arpl(); - void i386_push_i8(); - void __FASTCALL i386_ins_generic(int size); - void i386_insb(); - void i386_insw(); - void i386_insd(); - void __FASTCALL i386_outs_generic(int size); - void i386_outsb(); - void i386_outsw(); - void i386_outsd(); - void __FASTCALL i386_repeat(int invert_flag); - void i386_rep(); - void i386_repne(); - void i386_sahf(); - void i386_sbb_rm8_r8(); - void i386_sbb_r8_rm8(); - void i386_sbb_al_i8(); - void i386_scasb(); - void i386_setalc(); - void i386_seta_rm8(); - void i386_setbe_rm8(); - void i386_setc_rm8(); - void i386_setg_rm8(); - void i386_setge_rm8(); - void i386_setl_rm8(); - void i386_setle_rm8(); - void i386_setnc_rm8(); - void i386_setno_rm8(); - void i386_setnp_rm8(); - void i386_setns_rm8(); - void i386_setnz_rm8(); - void i386_seto_rm8(); - void i386_setp_rm8(); - void i386_sets_rm8(); - void i386_setz_rm8(); - void i386_stc(); - void i386_std(); - void i386_sti(); - void i386_stosb(); - void i386_sub_rm8_r8(); - void i386_sub_r8_rm8(); - void i386_sub_al_i8(); - void i386_test_al_i8(); - void i386_test_rm8_r8(); - void i386_xchg_r8_rm8(); - void i386_xor_rm8_r8(); - void i386_xor_r8_rm8(); - void i386_xor_al_i8(); - void i386_group80_8(); - void i386_groupC0_8(); - void i386_groupD0_8(); - void i386_groupD2_8(); - void i386_groupF6_8(); - void i386_groupFE_8(); - void i386_segment_CS(); - void i386_segment_DS(); - void i386_segment_ES(); - void i386_segment_FS(); - void i386_segment_GS(); - void i386_segment_SS(); - void i386_operand_size(); - void i386_address_size(); - void i386_nop(); - void i386_int3(); - void i386_int(); - void i386_into(); - void i386_escape(); - void i386_hlt(); - void __FASTCALL i386_decimal_adjust(int direction); - void i386_daa(); - void i386_das(); - void i386_aaa(); - void i386_aas(); - void i386_aad(); - void i386_aam(); - void i386_clts(); - void i386_wait(); - void i386_lock(); - void i386_mov_r32_tr(); - void i386_mov_tr_r32(); - void i386_loadall(); - void i386_invalid(); - void i386_xlat(); - uint16_t __FASTCALL i386_shift_rotate16(uint8_t modrm, uint32_t value, uint8_t shift); - void i386_adc_rm16_r16(); - void i386_adc_r16_rm16(); - void i386_adc_ax_i16(); - void i386_add_rm16_r16(); - void i386_add_r16_rm16(); - void i386_add_ax_i16(); - void i386_and_rm16_r16(); - void i386_and_r16_rm16(); - void i386_and_ax_i16(); - void i386_bsf_r16_rm16(); - void i386_bsr_r16_rm16(); - void i386_bt_rm16_r16(); - void i386_btc_rm16_r16(); - void i386_btr_rm16_r16(); - void i386_bts_rm16_r16(); - void i386_call_abs16(); - void i386_call_rel16(); - void i386_cbw(); - void i386_cmp_rm16_r16(); - void i386_cmp_r16_rm16(); - void i386_cmp_ax_i16(); - void i386_cmpsw(); - void i386_cwd(); - void i386_dec_ax(); - void i386_dec_cx(); - void i386_dec_dx(); - void i386_dec_bx(); - void i386_dec_sp(); - void i386_dec_bp(); - void i386_dec_si(); - void i386_dec_di(); - void i386_imul_r16_rm16(); - void i386_imul_r16_rm16_i16(); - void i386_imul_r16_rm16_i8(); - void i386_in_ax_i8(); - void i386_in_ax_dx(); - void i386_inc_ax(); - void i386_inc_cx(); - void i386_inc_dx(); - void i386_inc_bx(); - void i386_inc_sp(); - void i386_inc_bp(); - void i386_inc_si(); - void i386_inc_di(); - void i386_iret16(); - void i386_ja_rel16(); - void i386_jbe_rel16(); - void i386_jc_rel16(); - void i386_jg_rel16(); - void i386_jge_rel16(); - void i386_jl_rel16(); - void i386_jle_rel16(); - void i386_jnc_rel16(); - void i386_jno_rel16(); - void i386_jnp_rel16(); - void i386_jns_rel16(); - void i386_jnz_rel16(); - void i386_jo_rel16(); - void i386_jp_rel16(); - void i386_js_rel16(); - void i386_jz_rel16(); - void i386_jcxz16(); - void i386_jmp_rel16(); - void i386_jmp_abs16(); - void i386_lea16(); - void i386_enter16(); - void i386_leave16(); - void i386_lodsw(); - void i386_loop16(); - void i386_loopne16(); - void i386_loopz16(); - void i386_mov_rm16_r16(); - void i386_mov_r16_rm16(); - void i386_mov_rm16_i16(); - void i386_mov_ax_m16(); - void i386_mov_m16_ax(); - void i386_mov_ax_i16(); - void i386_mov_cx_i16(); - void i386_mov_dx_i16(); - void i386_mov_bx_i16(); - void i386_mov_sp_i16(); - void i386_mov_bp_i16(); - void i386_mov_si_i16(); - void i386_mov_di_i16(); - void i386_movsw(); - void i386_movsx_r16_rm8(); - void i386_movzx_r16_rm8(); - void i386_or_rm16_r16(); - void i386_or_r16_rm16(); - void i386_or_ax_i16(); - void i386_out_ax_i8(); - void i386_out_ax_dx(); - void i386_pop_ax(); - void i386_pop_cx(); - void i386_pop_dx(); - void i386_pop_bx(); - void i386_pop_sp(); - void i386_pop_bp(); - void i386_pop_si(); - void i386_pop_di(); - bool __FASTCALL i386_pop_seg16(int segment); - void i386_pop_ds16(); - void i386_pop_es16(); - void i386_pop_fs16(); - void i386_pop_gs16(); - void i386_pop_ss16(); - void i386_pop_rm16(); - void i386_popa(); - void i386_popf(); - void i386_push_ax(); - void i386_push_cx(); - void i386_push_dx(); - void i386_push_bx(); - void i386_push_sp(); - void i386_push_bp(); - void i386_push_si(); - void i386_push_di(); - void i386_push_cs16(); - void i386_push_ds16(); - void i386_push_es16(); - void i386_push_fs16(); - void i386_push_gs16(); - void i386_push_ss16(); - void i386_push_i16(); - void i386_pusha(); - void i386_pushf(); - void i386_ret_near16_i16(); - void i386_ret_near16(); - void i386_sbb_rm16_r16(); - void i386_sbb_r16_rm16(); - void i386_sbb_ax_i16(); - void i386_scasw(); - void i386_shld16_i8(); - void i386_shld16_cl(); - void i386_shrd16_i8(); - void i386_shrd16_cl(); - void i386_stosw(); - void i386_sub_rm16_r16(); - void i386_sub_r16_rm16(); - void i386_sub_ax_i16(); - void i386_test_ax_i16(); - void i386_test_rm16_r16(); - void i386_xchg_ax_cx(); - void i386_xchg_ax_dx(); - void i386_xchg_ax_bx(); - void i386_xchg_ax_sp(); - void i386_xchg_ax_bp(); - void i386_xchg_ax_si(); - void i386_xchg_ax_di(); - void i386_xchg_r16_rm16(); - void i386_xor_rm16_r16(); - void i386_xor_r16_rm16(); - void i386_xor_ax_i16(); - void i386_group81_16(); - void i386_group83_16(); - void i386_groupC1_16(); - void i386_groupD1_16(); - void i386_groupD3_16(); - void i386_groupF7_16(); - void i386_groupFF_16(); - void i386_group0F00_16(); - void i386_group0F01_16(); - void i386_group0FBA_16(); - void i386_lar_r16_rm16(); - void i386_lsl_r16_rm16(); - void i386_bound_r16_m16_m16(); - void i386_retf16(); - void i386_retf_i16(); - bool __FASTCALL i386_load_far_pointer16(int s); - void i386_lds16(); - void i386_lss16(); - void i386_les16(); - void i386_lfs16(); - void i386_lgs16(); - uint32_t __FASTCALL i386_shift_rotate32(uint8_t modrm, uint32_t value, uint8_t shift); - void i386_adc_rm32_r32(); - void i386_adc_r32_rm32(); - void i386_adc_eax_i32(); - void i386_add_rm32_r32(); - void i386_add_r32_rm32(); - void i386_add_eax_i32(); - void i386_and_rm32_r32(); - void i386_and_r32_rm32(); - void i386_and_eax_i32(); - void i386_bsf_r32_rm32(); - void i386_bsr_r32_rm32(); - void i386_bt_rm32_r32(); - void i386_btc_rm32_r32(); - void i386_btr_rm32_r32(); - void i386_bts_rm32_r32(); - void i386_call_abs32(); - void i386_call_rel32(); - void i386_cdq(); - void i386_cmp_rm32_r32(); - void i386_cmp_r32_rm32(); - void i386_cmp_eax_i32(); - void i386_cmpsd(); - void i386_cwde(); - void i386_dec_eax(); - void i386_dec_ecx(); - void i386_dec_edx(); - void i386_dec_ebx(); - void i386_dec_esp(); - void i386_dec_ebp(); - void i386_dec_esi(); - void i386_dec_edi(); - void i386_imul_r32_rm32(); - void i386_imul_r32_rm32_i32(); - void i386_imul_r32_rm32_i8(); - void i386_in_eax_i8(); - void i386_in_eax_dx(); - void i386_inc_eax(); - void i386_inc_ecx(); - void i386_inc_edx(); - void i386_inc_ebx(); - void i386_inc_esp(); - void i386_inc_ebp(); - void i386_inc_esi(); - void i386_inc_edi(); - void i386_iret32(); - void i386_ja_rel32(); - void i386_jbe_rel32(); - void i386_jc_rel32(); - void i386_jg_rel32(); - void i386_jge_rel32(); - void i386_jl_rel32(); - void i386_jle_rel32(); - void i386_jnc_rel32(); - void i386_jno_rel32(); - void i386_jnp_rel32(); - void i386_jns_rel32(); - void i386_jnz_rel32(); - void i386_jo_rel32(); - void i386_jp_rel32(); - void i386_js_rel32(); - void i386_jz_rel32(); - void i386_jcxz32(); - void i386_jmp_rel32(); - void i386_jmp_abs32(); - void i386_lea32(); - void i386_enter32(); - void i386_leave32(); - void i386_lodsd(); - void i386_loop32(); - void i386_loopne32(); - void i386_loopz32(); - void i386_mov_rm32_r32(); - void i386_mov_r32_rm32(); - void i386_mov_rm32_i32(); - void i386_mov_eax_m32(); - void i386_mov_m32_eax(); - void i386_mov_eax_i32(); - void i386_mov_ecx_i32(); - void i386_mov_edx_i32(); - void i386_mov_ebx_i32(); - void i386_mov_esp_i32(); - void i386_mov_ebp_i32(); - void i386_mov_esi_i32(); - void i386_mov_edi_i32(); - void i386_movsd(); - void i386_movsx_r32_rm8(); - void i386_movsx_r32_rm16(); - void i386_movzx_r32_rm8(); - void i386_movzx_r32_rm16(); - void i386_or_rm32_r32(); - void i386_or_r32_rm32(); - void i386_or_eax_i32(); - void i386_out_eax_i8(); - void i386_out_eax_dx(); - void i386_pop_eax(); - void i386_pop_ecx(); - void i386_pop_edx(); - void i386_pop_ebx(); - void i386_pop_esp(); - void i386_pop_ebp(); - void i386_pop_esi(); - void i386_pop_edi(); - bool __FASTCALL i386_pop_seg32(int segment); - void i386_pop_ds32(); - void i386_pop_es32(); - void i386_pop_fs32(); - void i386_pop_gs32(); - void i386_pop_ss32(); - void i386_pop_rm32(); - void i386_popad(); - void i386_popfd(); - void i386_push_eax(); - void i386_push_ecx(); - void i386_push_edx(); - void i386_push_ebx(); - void i386_push_esp(); - void i386_push_ebp(); - void i386_push_esi(); - void i386_push_edi(); - void i386_push_cs32(); - void i386_push_ds32(); - void i386_push_es32(); - void i386_push_fs32(); - void i386_push_gs32(); - void i386_push_ss32(); - void i386_push_i32(); - void i386_pushad(); - void i386_pushfd(); - void i386_ret_near32_i16(); - void i386_ret_near32(); - void i386_sbb_rm32_r32(); - void i386_sbb_r32_rm32(); - void i386_sbb_eax_i32(); - void i386_scasd(); - void i386_shld32_i8(); - void i386_shld32_cl(); - void i386_shrd32_i8(); - void i386_shrd32_cl(); - void i386_stosd(); - void i386_sub_rm32_r32(); - void i386_sub_r32_rm32(); - void i386_sub_eax_i32(); - void i386_test_eax_i32(); - void i386_test_rm32_r32(); - void i386_xchg_eax_ecx(); - void i386_xchg_eax_edx(); - void i386_xchg_eax_ebx(); - void i386_xchg_eax_esp(); - void i386_xchg_eax_ebp(); - void i386_xchg_eax_esi(); - void i386_xchg_eax_edi(); - void i386_xchg_r32_rm32(); - void i386_xor_rm32_r32(); - void i386_xor_r32_rm32(); - void i386_xor_eax_i32(); - void i386_group81_32(); - void i386_group83_32(); - void i386_groupC1_32(); - void i386_groupD1_32(); - void i386_groupD3_32(); - void i386_groupF7_32(); - void i386_groupFF_32(); - void i386_group0F00_32(); - void i386_group0F01_32(); - void i386_group0FBA_32(); - void i386_lar_r32_rm32(); - void i386_lsl_r32_rm32(); - void i386_bound_r32_m32_m32(); - void i386_retf32(); - void i386_retf_i32(); - void __FASTCALL i386_load_far_pointer32(int s); - void i386_lds32(); - void i386_lss32(); - void i386_les32(); - void i386_lfs32(); - void i386_lgs32(); - void i486_cpuid(); - void i486_invd(); - void i486_wbinvd(); - void i486_cmpxchg_rm8_r8(); - void i486_cmpxchg_rm16_r16(); - void i486_cmpxchg_rm32_r32(); - void i486_xadd_rm8_r8(); - void i486_xadd_rm16_r16(); - void i486_xadd_rm32_r32(); - void i486_group0F01_16(); - void i486_group0F01_32(); - void i486_bswap_eax(); - void i486_bswap_ecx(); - void i486_bswap_edx(); - void i486_bswap_ebx(); - void i486_bswap_esp(); - void i486_bswap_ebp(); - void i486_bswap_esi(); - void i486_bswap_edi(); - void i486_mov_cr_r32(); - inline void MMXPROLOG(); - inline void __FASTCALL READMMX(uint32_t ea,MMX_REG &r); - inline void __FASTCALL WRITEMMX(uint32_t ea,MMX_REG &r); - inline void __FASTCALL READXMM(uint32_t ea,XMM_REG &r); - inline void __FASTCALL WRITEXMM(uint32_t ea,XMM_REG &r); - inline void __FASTCALL READXMM_LO64(uint32_t ea,XMM_REG &r); - inline void __FASTCALL WRITEXMM_LO64(uint32_t ea,XMM_REG &r); - inline void __FASTCALL READXMM_HI64(uint32_t ea,XMM_REG &r); - inline void __FASTCALL WRITEXMM_HI64(uint32_t ea,XMM_REG &r); - void pentium_rdmsr(); - void pentium_wrmsr(); - void pentium_rdtsc(); - void pentium_ud2(); - void pentium_rsm(); - void pentium_prefetch_m8(); - void pentium_cmovo_r16_rm16(); - void pentium_cmovo_r32_rm32(); - void pentium_cmovno_r16_rm16(); - void pentium_cmovno_r32_rm32(); - void pentium_cmovb_r16_rm16(); - void pentium_cmovb_r32_rm32(); - void pentium_cmovae_r16_rm16(); - void pentium_cmovae_r32_rm32(); - void pentium_cmove_r16_rm16(); - void pentium_cmove_r32_rm32(); - void pentium_cmovne_r16_rm16(); - void pentium_cmovne_r32_rm32(); - void pentium_cmovbe_r16_rm16(); - void pentium_cmovbe_r32_rm32(); - void pentium_cmova_r16_rm16(); - void pentium_cmova_r32_rm32(); - void pentium_cmovs_r16_rm16(); - void pentium_cmovs_r32_rm32(); - void pentium_cmovns_r16_rm16(); - void pentium_cmovns_r32_rm32(); - void pentium_cmovp_r16_rm16(); - void pentium_cmovp_r32_rm32(); - void pentium_cmovnp_r16_rm16(); - void pentium_cmovnp_r32_rm32(); - void pentium_cmovl_r16_rm16(); - void pentium_cmovl_r32_rm32(); - void pentium_cmovge_r16_rm16(); - void pentium_cmovge_r32_rm32(); - void pentium_cmovle_r16_rm16(); - void pentium_cmovle_r32_rm32(); - void pentium_cmovg_r16_rm16(); - void pentium_cmovg_r32_rm32(); - void pentium_movnti_m16_r16(); - void pentium_movnti_m32_r32(); - void i386_cyrix_special(); - void i386_cyrix_unknown(); - void pentium_cmpxchg8b_m64(); - void pentium_movntq_m64_r64(); - void pentium_maskmovq_r64_r64(); - void pentium_popcnt_r16_rm16(); - void pentium_popcnt_r32_rm32(); - void pentium_tzcnt_r16_rm16(); - void pentium_tzcnt_r32_rm32(); - void mmx_group_0f71(); - void mmx_group_0f72(); - void mmx_group_0f73(); - void mmx_psrlw_r64_rm64(); - void mmx_psrld_r64_rm64(); - void mmx_psrlq_r64_rm64(); - void mmx_paddq_r64_rm64(); - void mmx_pmullw_r64_rm64(); - void mmx_psubusb_r64_rm64(); - void mmx_psubusw_r64_rm64(); - void mmx_pand_r64_rm64(); - void mmx_paddusb_r64_rm64(); - void mmx_paddusw_r64_rm64(); - void mmx_pandn_r64_rm64(); - void mmx_psraw_r64_rm64(); - void mmx_psrad_r64_rm64(); - void mmx_pmulhw_r64_rm64(); - void mmx_psubsb_r64_rm64(); - void mmx_psubsw_r64_rm64(); - void mmx_por_r64_rm64(); - void mmx_paddsb_r64_rm64(); - void mmx_paddsw_r64_rm64(); - void mmx_pxor_r64_rm64(); - void mmx_psllw_r64_rm64(); - void mmx_pslld_r64_rm64(); - void mmx_psllq_r64_rm64(); - void mmx_pmaddwd_r64_rm64(); - void mmx_psubb_r64_rm64(); - void mmx_psubw_r64_rm64(); - void mmx_psubd_r64_rm64(); - void mmx_paddb_r64_rm64(); - void mmx_paddw_r64_rm64(); - void mmx_paddd_r64_rm64(); - void mmx_emms(); - void i386_cyrix_svdc(); - void i386_cyrix_rsdc(); - void i386_cyrix_svldt(); - void i386_cyrix_rsldt(); - void i386_cyrix_svts(); - void i386_cyrix_rsts(); - void mmx_movd_r64_rm32(); - void mmx_movq_r64_rm64(); - void mmx_movd_rm32_r64(); - void mmx_movq_rm64_r64(); - void mmx_pcmpeqb_r64_rm64(); - void mmx_pcmpeqw_r64_rm64(); - void mmx_pcmpeqd_r64_rm64(); - void mmx_pshufw_r64_rm64_i8(); - void mmx_punpcklbw_r64_r64m32(); - void mmx_punpcklwd_r64_r64m32(); - void mmx_punpckldq_r64_r64m32(); - void mmx_packsswb_r64_rm64(); - void mmx_pcmpgtb_r64_rm64(); - void mmx_pcmpgtw_r64_rm64(); - void mmx_pcmpgtd_r64_rm64(); - void mmx_packuswb_r64_rm64(); - void mmx_punpckhbw_r64_rm64(); - void mmx_punpckhwd_r64_rm64(); - void mmx_punpckhdq_r64_rm64(); - void mmx_packssdw_r64_rm64(); - void sse_group_0fae(); - void sse_group_660f71(); - void sse_group_660f72(); - void sse_group_660f73(); - void sse_cvttps2dq_r128_rm128(); - void sse_cvtss2sd_r128_r128m32(); - void sse_cvttss2si_r32_r128m32(); - void sse_cvtss2si_r32_r128m32(); - void sse_cvtsi2ss_r128_rm32(); - void sse_cvtpi2ps_r128_rm64(); - void sse_cvttps2pi_r64_r128m64(); - void sse_cvtps2pi_r64_r128m64(); - void sse_cvtps2pd_r128_r128m64(); - void sse_cvtdq2ps_r128_rm128(); - void sse_cvtdq2pd_r128_r128m64(); - void sse_movss_r128_rm128(); - void sse_movss_rm128_r128(); - void sse_movsldup_r128_rm128(); - void sse_movshdup_r128_rm128(); - void sse_movaps_r128_rm128(); - void sse_movaps_rm128_r128(); - void sse_movups_r128_rm128(); - void sse_movups_rm128_r128(); - void sse_movlps_r128_m64(); - void sse_movlps_m64_r128(); - void sse_movhps_r128_m64(); - void sse_movhps_m64_r128(); - void sse_movntps_m128_r128(); - void sse_movmskps_r16_r128(); - void sse_movmskps_r32_r128(); - void sse_movq2dq_r128_r64(); - void sse_movdqu_r128_rm128(); - void sse_movdqu_rm128_r128(); - void sse_movd_m128_rm32(); - void sse_movdqa_m128_rm128(); - void sse_movq_r128_r128m64(); - void sse_movd_rm32_r128(); - void sse_movdqa_rm128_r128(); - void sse_pmovmskb_r16_r64(); - void sse_pmovmskb_r32_r64(); - void sse_xorps(); - void sse_addps(); - void sse_sqrtps_r128_rm128(); - void sse_rsqrtps_r128_rm128(); - void sse_rcpps_r128_rm128(); - void sse_andps_r128_rm128(); - void sse_andnps_r128_rm128(); - void sse_orps_r128_rm128(); - void sse_mulps(); - void sse_subps(); - void sse_minps(); - void sse_divps(); - void sse_maxps(); - void sse_maxss_r128_r128m32(); - void sse_addss(); - void sse_subss(); - void sse_mulss(); - void sse_divss(); - void sse_rcpss_r128_r128m32(); - void sse_sqrtss_r128_r128m32(); - void sse_rsqrtss_r128_r128m32(); - void sse_minss_r128_r128m32(); - void sse_comiss_r128_r128m32(); - void sse_ucomiss_r128_r128m32(); - void sse_shufps(); - void sse_punpcklbw_r128_rm128(); - void sse_punpcklwd_r128_rm128(); - void sse_punpckldq_r128_rm128(); - void sse_punpcklqdq_r128_rm128(); - void sse_unpcklps_r128_rm128(); - void sse_unpckhps_r128_rm128(); - void sse_cmpps_r128_rm128_i8(); - void sse_cmpss_r128_r128m32_i8(); - void sse_pinsrw_r64_r16m16_i8(); - void sse_pinsrw_r64_r32m16_i8(); - void sse_pinsrw_r128_r32m16_i8(); - void sse_pextrw_r16_r64_i8(); - void sse_pextrw_r32_r64_i8(); - void sse_pextrw_reg_r128_i8(); - void sse_pminub_r64_rm64(); - void sse_pmaxub_r64_rm64(); - void sse_pavgb_r64_rm64(); - void sse_pavgw_r64_rm64(); - void sse_pmulhuw_r64_rm64(); - void sse_pminsw_r64_rm64(); - void sse_pmaxsw_r64_rm64(); - void sse_pmuludq_r64_rm64(); - void sse_psadbw_r64_rm64(); - void sse_psubq_r64_rm64(); - void sse_pshufhw_r128_rm128_i8(); - void sse_packsswb_r128_rm128(); - void sse_packssdw_r128_rm128(); - void sse_pcmpgtb_r128_rm128(); - void sse_pcmpgtw_r128_rm128(); - void sse_pcmpgtd_r128_rm128(); - void sse_packuswb_r128_rm128(); - void sse_punpckhbw_r128_rm128(); - void sse_punpckhwd_r128_rm128(); - void sse_unpckhdq_r128_rm128(); - void sse_punpckhqdq_r128_rm128(); - void sse_pcmpeqb_r128_rm128(); - void sse_pcmpeqw_r128_rm128(); - void sse_pcmpeqd_r128_rm128(); - void sse_paddq_r128_rm128(); - void sse_pmullw_r128_rm128(); - void sse_pmuludq_r128_rm128(); - void sse_psubq_r128_rm128(); - void sse_paddb_r128_rm128(); - void sse_paddw_r128_rm128(); - void sse_paddd_r128_rm128(); - void sse_psubusb_r128_rm128(); - void sse_psubusw_r128_rm128(); - void sse_pminub_r128_rm128(); - void sse_pand_r128_rm128(); - void sse_pandn_r128_rm128(); - void sse_paddusb_r128_rm128(); - void sse_paddusw_r128_rm128(); - void sse_pmaxub_r128_rm128(); - void sse_pmulhuw_r128_rm128(); - void sse_pmulhw_r128_rm128(); - void sse_psubsw_r128_rm128(); - void sse_psubsb_r128_rm128(); - void sse_pminsw_r128_rm128(); - void sse_pmaxsw_r128_rm128(); - void sse_paddsb_r128_rm128(); - void sse_paddsw_r128_rm128(); - void sse_por_r128_rm128(); - void sse_pxor_r128_rm128(); - void sse_pmaddwd_r128_rm128(); - void sse_psubb_r128_rm128(); - void sse_psubw_r128_rm128(); - void sse_psubd_r128_rm128(); - void sse_psadbw_r128_rm128(); - void sse_pavgb_r128_rm128(); - void sse_pavgw_r128_rm128(); - void sse_pmovmskb_r32_r128(); - void sse_maskmovdqu_r128_r128(); - void sse_andpd_r128_rm128(); - void sse_andnpd_r128_rm128(); - void sse_orpd_r128_rm128(); - void sse_xorpd_r128_rm128(); - void sse_unpcklpd_r128_rm128(); - void sse_unpckhpd_r128_rm128(); - void sse_shufpd_r128_rm128_i8(); - void sse_pshufd_r128_rm128_i8(); - void sse_pshuflw_r128_rm128_i8(); - void sse_movmskpd_r32_r128(); - void sse_ucomisd_r128_r128m64(); - void sse_comisd_r128_r128m64(); - void sse_psrlw_r128_rm128(); - void sse_psrld_r128_rm128(); - void sse_psrlq_r128_rm128(); - void sse_psllw_r128_rm128(); - void sse_pslld_r128_rm128(); - void sse_psllq_r128_rm128(); - void sse_psraw_r128_rm128(); - void sse_psrad_r128_rm128(); - void sse_movntdq_m128_r128(); - void sse_cvttpd2dq_r128_rm128(); - void sse_movq_r128m64_r128(); - void sse_addsubpd_r128_rm128(); - void sse_cmppd_r128_rm128_i8(); - void sse_haddpd_r128_rm128(); - void sse_hsubpd_r128_rm128(); - void sse_sqrtpd_r128_rm128(); - void sse_cvtpi2pd_r128_rm64(); - void sse_cvttpd2pi_r64_rm128(); - void sse_cvtpd2pi_r64_rm128(); - void sse_cvtpd2ps_r128_rm128(); - void sse_cvtps2dq_r128_rm128(); - void sse_addpd_r128_rm128(); - void sse_mulpd_r128_rm128(); - void sse_subpd_r128_rm128(); - void sse_minpd_r128_rm128(); - void sse_divpd_r128_rm128(); - void sse_maxpd_r128_rm128(); - void sse_movntpd_m128_r128(); - void sse_movapd_r128_rm128(); - void sse_movapd_rm128_r128(); - void sse_movhpd_r128_m64(); - void sse_movhpd_m64_r128(); - void sse_movupd_r128_rm128(); - void sse_movupd_rm128_r128(); - void sse_movlpd_r128_m64(); - void sse_movlpd_m64_r128(); - void sse_movsd_r128_r128m64(); - void sse_movsd_r128m64_r128(); - void sse_movddup_r128_r128m64(); - void sse_cvtsi2sd_r128_rm32(); - void sse_cvttsd2si_r32_r128m64(); - void sse_cvtsd2si_r32_r128m64(); - void sse_sqrtsd_r128_r128m64(); - void sse_addsd_r128_r128m64(); - void sse_mulsd_r128_r128m64(); - void sse_cvtsd2ss_r128_r128m64(); - void sse_subsd_r128_r128m64(); - void sse_minsd_r128_r128m64(); - void sse_divsd_r128_r128m64(); - void sse_maxsd_r128_r128m64(); - void sse_haddps_r128_rm128(); - void sse_hsubps_r128_rm128(); - void sse_cmpsd_r128_r128m64_i8(); - void sse_addsubps_r128_rm128(); - void sse_movdq2q_r64_r128(); - void sse_cvtpd2dq_r128_rm128(); - void sse_lddqu_r128_m128(); - inline void __FASTCALL sse_predicate_compare_single(uint8_t imm8, XMM_REG d, XMM_REG s); - inline void __FASTCALL sse_predicate_compare_double(uint8_t imm8, XMM_REG d, XMM_REG s); - inline void __FASTCALL sse_predicate_compare_single_scalar(uint8_t imm8, XMM_REG d, XMM_REG s); - inline void __FASTCALL sse_predicate_compare_double_scalar(uint8_t imm8, XMM_REG d, XMM_REG s); - inline floatx80 __FASTCALL READ80(uint32_t ea); - inline void __FASTCALL WRITE80(uint32_t ea, floatx80 t); - inline void __FASTCALL x87_set_stack_top(int top); - inline void __FASTCALL x87_set_tag(int reg, int tag); - void __FASTCALL x87_write_stack(int i, floatx80 value, bool update_tag); - inline void x87_set_stack_underflow(); - inline void x87_set_stack_overflow(); - int x87_inc_stack(); - int x87_dec_stack(); - int x87_check_exceptions(); - inline __FASTCALL void x87_write_cw(uint16_t cw); - void x87_reset(); - floatx80 __FASTCALL x87_add(floatx80 a, floatx80 b); - floatx80 __FASTCALL x87_sub(floatx80 a, floatx80 b); - floatx80 __FASTCALL x87_mul(floatx80 a, floatx80 b); - floatx80 __FASTCALL x87_div(floatx80 a, floatx80 b); - void __FASTCALL x87_fadd_m32real(uint8_t modrm); - void x87_fadd_m64real(uint8_t modrm); - void x87_fadd_st_sti(uint8_t modrm); - void x87_fadd_sti_st(uint8_t modrm); - void x87_faddp(uint8_t modrm); - void x87_fiadd_m32int(uint8_t modrm); - void x87_fiadd_m16int(uint8_t modrm); - void x87_fsub_m32real(uint8_t modrm); - void x87_fsub_m64real(uint8_t modrm); - void x87_fsub_st_sti(uint8_t modrm); - void x87_fsub_sti_st(uint8_t modrm); - void x87_fsubp(uint8_t modrm); - void x87_fisub_m32int(uint8_t modrm); - void x87_fisub_m16int(uint8_t modrm); - void x87_fsubr_m32real(uint8_t modrm); - void x87_fsubr_m64real(uint8_t modrm); - void x87_fsubr_st_sti(uint8_t modrm); - void x87_fsubr_sti_st(uint8_t modrm); - void x87_fsubrp(uint8_t modrm); - void x87_fisubr_m32int(uint8_t modrm); - void x87_fisubr_m16int(uint8_t modrm); - void x87_fdiv_m32real(uint8_t modrm); - void x87_fdiv_m64real(uint8_t modrm); - void x87_fdiv_st_sti(uint8_t modrm); - void x87_fdiv_sti_st(uint8_t modrm); - void x87_fdivp(uint8_t modrm); - void x87_fidiv_m32int(uint8_t modrm); - void x87_fidiv_m16int(uint8_t modrm); - void x87_fdivr_m32real(uint8_t modrm); - void x87_fdivr_m64real(uint8_t modrm); - void x87_fdivr_st_sti(uint8_t modrm); - void x87_fdivr_sti_st(uint8_t modrm); - void x87_fdivrp(uint8_t modrm); - void x87_fidivr_m32int(uint8_t modrm); - void x87_fidivr_m16int(uint8_t modrm); - void x87_fmul_m32real(uint8_t modrm); - void x87_fmul_m64real(uint8_t modrm); - void x87_fmul_st_sti(uint8_t modrm); - void x87_fmul_sti_st(uint8_t modrm); - void x87_fmulp(uint8_t modrm); - void x87_fimul_m32int(uint8_t modrm); - void x87_fimul_m16int(uint8_t modrm); - void x87_fprem(uint8_t modrm); - void x87_fprem1(uint8_t modrm); - void x87_fsqrt(uint8_t modrm); - void x87_f2xm1(uint8_t modrm); - void x87_fyl2x(uint8_t modrm); - void x87_fyl2xp1(uint8_t modrm); - void x87_fptan(uint8_t modrm); - void x87_fpatan(uint8_t modrm); - void x87_fsin(uint8_t modrm); - void x87_fcos(uint8_t modrm); - void x87_fsincos(uint8_t modrm); - void x87_fld_m32real(uint8_t modrm); - void x87_fld_m64real(uint8_t modrm); - void x87_fld_m80real(uint8_t modrm); - void x87_fld_sti(uint8_t modrm); - void x87_fild_m16int(uint8_t modrm); - void x87_fild_m32int(uint8_t modrm); - void x87_fild_m64int(uint8_t modrm); - void x87_fbld(uint8_t modrm); - void x87_fst_m32real(uint8_t modrm); - void x87_fst_m64real(uint8_t modrm); - void x87_fst_sti(uint8_t modrm); - void x87_fstp_m32real(uint8_t modrm); - void x87_fstp_m64real(uint8_t modrm); - void x87_fstp_m80real(uint8_t modrm); - void x87_fstp_sti(uint8_t modrm); - void x87_fist_m16int(uint8_t modrm); - void x87_fist_m32int(uint8_t modrm); - void x87_fistp_m16int(uint8_t modrm); - void x87_fistp_m32int(uint8_t modrm); - void x87_fistp_m64int(uint8_t modrm); - void x87_fbstp(uint8_t modrm); - void x87_fld1(uint8_t modrm); - void x87_fldl2t(uint8_t modrm); - void x87_fldl2e(uint8_t modrm); - void x87_fldpi(uint8_t modrm); - void x87_fldlg2(uint8_t modrm); - void x87_fldln2(uint8_t modrm); - void x87_fldz(uint8_t modrm); - void x87_fnop(uint8_t modrm); - void x87_fchs(uint8_t modrm); - void x87_fabs(uint8_t modrm); - void x87_fscale(uint8_t modrm); - void x87_frndint(uint8_t modrm); - void x87_fxtract(uint8_t modrm); - void x87_ftst(uint8_t modrm); - void x87_fxam(uint8_t modrm); - void x87_fcmovb_sti(uint8_t modrm); - void x87_fcmove_sti(uint8_t modrm); - void x87_fcmovbe_sti(uint8_t modrm); - void x87_fcmovu_sti(uint8_t modrm); - void x87_fcmovnb_sti(uint8_t modrm); - void x87_fcmovne_sti(uint8_t modrm); - void x87_fcmovnbe_sti(uint8_t modrm); - void x87_fcmovnu_sti(uint8_t modrm); - void x87_ficom_m16int(uint8_t modrm); - void x87_ficom_m32int(uint8_t modrm); - void x87_ficomp_m16int(uint8_t modrm); - void x87_ficomp_m32int(uint8_t modrm); - void x87_fcom_m32real(uint8_t modrm); - void x87_fcom_m64real(uint8_t modrm); - void x87_fcom_sti(uint8_t modrm); - void x87_fcomp_m32real(uint8_t modrm); - void x87_fcomp_m64real(uint8_t modrm); - void x87_fcomp_sti(uint8_t modrm); - void x87_fcomi_sti(uint8_t modrm); - void x87_fcomip_sti(uint8_t modrm); - void x87_fucomi_sti(uint8_t modrm); - void x87_fucomip_sti(uint8_t modrm); - void x87_fcompp(uint8_t modrm); - void x87_fucom_sti(uint8_t modrm); - void x87_fucomp_sti(uint8_t modrm); - void x87_fucompp(uint8_t modrm); - void x87_fdecstp(uint8_t modrm); - void x87_fincstp(uint8_t modrm); - void x87_fclex(uint8_t modrm); - void x87_ffree(uint8_t modrm); - void x87_fdisi(uint8_t modrm); - void x87_feni(uint8_t modrm); - void x87_finit(uint8_t modrm); - void x87_fldcw(uint8_t modrm); - void x87_fstcw(uint8_t modrm); - void x87_fldenv(uint8_t modrm); - void x87_fstenv(uint8_t modrm); - void x87_fsave(uint8_t modrm); - void x87_frstor(uint8_t modrm); - void x87_fxch(uint8_t modrm); - void x87_fxch_sti(uint8_t modrm); - void x87_fstsw_ax(uint8_t modrm); - void x87_fstsw_m2byte(uint8_t modrm); - void x87_invalid(uint8_t modrm); - void i386_x87_group_d8(); - void i386_x87_group_d9(); - void i386_x87_group_da(); - void i386_x87_group_db(); - void i386_x87_group_dc(); - void i386_x87_group_dd(); - void i386_x87_group_de(); - void i386_x87_group_df(); - void build_x87_opcode_table_d8(); - void build_x87_opcode_table_d9(); - void build_x87_opcode_table_da(); - void build_x87_opcode_table_db(); - void build_x87_opcode_table_dc(); - void build_x87_opcode_table_dd(); - void build_x87_opcode_table_de(); - void build_x87_opcode_table_df(); - void build_x87_opcode_table(); - void i386_postload(); - void i386_common_init(); - void build_opcode_table(uint32_t features); - void pentium_smi(); - void zero_state(); - void i386_set_a20_line(int state); - -}; - - -class i386sx_device : public i386_device -{ -public: - // construction/destruction - i386sx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - -protected: -#if 0 - virtual u8 mem_pr8(offs_t address) override { return macache16->read_data8(address); }; - virtual u16 mem_pr16(offs_t address) override { return macache16->read_data16(address); }; - virtual u32 mem_pr32(offs_t address) override { return macache16->read_data32(address); }; -#else - virtual u8 __FASTCALL mem_pr8(offs_t address) override { return d_mem->read_data8(address); }; - virtual u16 __FASTCALL mem_pr16(offs_t address) override { return d_mem->read_data16(address); }; - virtual u32 __FASTCALL mem_pr32(offs_t address) override { return d_mem->read_data32(address); }; -#endif -}; - -class i486_device : public i386_device -{ -public: - // construction/destruction - i486_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; - -}; - -class i486dx4_device : public i486_device -{ -public: - // construction/destruction - i486dx4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual void reset() override; - -}; - - -class pentium_device : public i386_device -{ -public: - // construction/destruction - pentium_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; - -protected: - - virtual bool __FASTCALL execute_input_edge_triggered(int inputnum) const override { return inputnum == SIG_CPU_NMI || inputnum == SIG_CPU_SMI; } - virtual void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask) override; - virtual __FASTCALL uint64_t opcode_rdmsr(bool &valid_msr) override; - virtual __FASTCALL void opcode_wrmsr(uint64_t data, bool &valid_msr) override; -}; - - -class pentium_mmx_device : public pentium_device -{ -public: - // construction/destruction - pentium_mmx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; -}; - - -class mediagx_device : public i386_device -{ -public: - // construction/destruction - mediagx_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; -}; - - -class pentium_pro_device : public pentium_device -{ -public: - // construction/destruction - pentium_pro_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; - -protected: - virtual uint64_t __FASTCALL opcode_rdmsr(bool &valid_msr) override; - virtual void __FASTCALL opcode_wrmsr(uint64_t data, bool &valid_msr) override; -}; - - -class pentium2_device : public pentium_pro_device -{ -public: - // construction/destruction - pentium2_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; -}; - - -class pentium3_device : public pentium_pro_device -{ -public: - // construction/destruction - pentium3_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; -}; - -#if 0 -class athlonxp_device : public pentium_device -{ -public: - // construction/destruction - athlonxp_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; - -protected: - virtual void opcode_cpuid() override; - virtual uint64_t opcode_rdmsr(bool &valid_msr) override; - virtual void opcode_wrmsr(uint64_t data, bool &valid_msr) override; - virtual void opcode_invd() override; - virtual void opcode_wbinvd() override; - - virtual u8 mem_pr8(offs_t address) override { return opcode_read_cache(address); } - virtual u16 mem_pr16(offs_t address) override { return opcode_read_cache(address); } - virtual u32 mem_pr32(offs_t address) override { return opcode_read_cache(address); } - virtual u8 mem_prd8(offs_t address) override { return program_read_cache(address); } - virtual u16 mem_prd16(offs_t address) override { return program_read_cache(address); } - virtual u32 mem_prd32(offs_t address) override { return program_read_cache(address); } - virtual void mem_pwd8(offs_t address, u8 data) override { program_write_cache(address, data); } - virtual void mem_pwd16(offs_t address, u16 data) override { program_write_cache(address, data); } - virtual void mem_pwd32(offs_t address, u32 data) override { program_write_cache(address, data); } - -private: - void parse_mtrrfix(u64 mtrr, offs_t base, int kblock); - int check_cacheable(offs_t address); - void invalidate_cache(bool writeback); - - template dt opcode_read_cache(offs_t address); - template dt program_read_cache(offs_t address); - template void program_write_cache(offs_t address, dt data); - - uint8_t m_processor_name_string[48]; - uint64_t m_msr_mtrrfix[11]; - uint8_t m_memory_ranges_1m[1024 / 4]; - cpucache<17, 9, Cache2Way, CacheLineBytes64> cache; // 512 sets, 2 ways (cachelines per set), 64 bytes per cacheline -}; -#endif - -class pentium4_device : public pentium_device -{ -public: - // construction/destruction - pentium4_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); - virtual bool process_state(FILEIO* state_fio, bool loading); - virtual void initialize() override; - virtual void reset() override; - -protected: - virtual uint64_t __FASTCALL opcode_rdmsr(bool &valid_msr) override; - virtual void __FASTCALL opcode_wrmsr(uint64_t data, bool &valid_msr) override; -}; - -/* -DECLARE_DEVICE_TYPE(I386, i386_device) -DECLARE_DEVICE_TYPE(I386SX, i386sx_device) -DECLARE_DEVICE_TYPE(I486, i486_device) -DECLARE_DEVICE_TYPE(I486DX4, i486dx4_device) -DECLARE_DEVICE_TYPE(PENTIUM, pentium_device) -DECLARE_DEVICE_TYPE(PENTIUM_MMX, pentium_mmx_device) -DECLARE_DEVICE_TYPE(MEDIAGX, mediagx_device) -DECLARE_DEVICE_TYPE(PENTIUM_PRO, pentium_pro_device) -DECLARE_DEVICE_TYPE(PENTIUM2, pentium2_device) -DECLARE_DEVICE_TYPE(PENTIUM3, pentium3_device) -DECLARE_DEVICE_TYPE(ATHLONXP, athlonxp_device) -DECLARE_DEVICE_TYPE(PENTIUM4, pentium4_device) -*/ -#endif // MAME_CPU_I386_I386_H diff --git a/source/src/vm/libcpu_newdev/i386/i386dasm.cpp b/source/src/vm/libcpu_newdev/i386/i386dasm.cpp deleted file mode 100644 index 1f7199a2d..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386dasm.cpp +++ /dev/null @@ -1,2972 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Peter Ferrie -/* - i386 Disassembler - - Written by Ville Linde -*/ - -#include "emu.h" -#include "i386dasm.h" - -const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table1[256] = -{ - // 0x00 - {"add", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"add", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"add", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"add", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"add", 0, PARAM_AL, PARAM_UI8, 0 }, - {"add", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"push es", 0, 0, 0, 0 }, - {"pop es", 0, 0, 0, 0 }, - {"or", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"or", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"or", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"or", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"or", 0, PARAM_AL, PARAM_UI8, 0 }, - {"or", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"push cs", 0, 0, 0, 0 }, - {"two_byte", TWO_BYTE, 0, 0, 0 }, - // 0x10 - {"adc", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"adc", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"adc", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"adc", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"adc", 0, PARAM_AL, PARAM_UI8, 0 }, - {"adc", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"push ss", 0, 0, 0, 0 }, - {"pop ss", 0, 0, 0, 0 }, - {"sbb", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"sbb", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"sbb", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"sbb", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"sbb", 0, PARAM_AL, PARAM_UI8, 0 }, - {"sbb", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"push ds", 0, 0, 0, 0 }, - {"pop ds", 0, 0, 0, 0 }, - // 0x20 - {"and", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"and", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"and", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"and", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"and", 0, PARAM_AL, PARAM_UI8, 0 }, - {"and", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"seg_es", SEG_ES, 0, 0, 0 }, - {"daa", 0, 0, 0, 0 }, - {"sub", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"sub", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"sub", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"sub", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"sub", 0, PARAM_AL, PARAM_UI8, 0 }, - {"sub", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"seg_cs", SEG_CS, 0, 0, 0 }, - {"das", 0, 0, 0, 0 }, - // 0x30 - {"xor", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"xor", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"xor", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"xor", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"xor", 0, PARAM_AL, PARAM_UI8, 0 }, - {"xor", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"seg_ss", SEG_SS, 0, 0, 0 }, - {"aaa", 0, 0, 0, 0 }, - {"cmp", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"cmp", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"cmp", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"cmp", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmp", 0, PARAM_AL, PARAM_UI8, 0 }, - {"cmp", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"seg_ds", SEG_DS, 0, 0, 0 }, - {"aas", 0, 0, 0, 0 }, - // 0x40 - {"inc", ISREX, PARAM_EAX, 0, 0 }, - {"inc", ISREX, PARAM_ECX, 0, 0 }, - {"inc", ISREX, PARAM_EDX, 0, 0 }, - {"inc", ISREX, PARAM_EBX, 0, 0 }, - {"inc", ISREX, PARAM_ESP, 0, 0 }, - {"inc", ISREX, PARAM_EBP, 0, 0 }, - {"inc", ISREX, PARAM_ESI, 0, 0 }, - {"inc", ISREX, PARAM_EDI, 0, 0 }, - {"dec", ISREX, PARAM_EAX, 0, 0 }, - {"dec", ISREX, PARAM_ECX, 0, 0 }, - {"dec", ISREX, PARAM_EDX, 0, 0 }, - {"dec", ISREX, PARAM_EBX, 0, 0 }, - {"dec", ISREX, PARAM_ESP, 0, 0 }, - {"dec", ISREX, PARAM_EBP, 0, 0 }, - {"dec", ISREX, PARAM_ESI, 0, 0 }, - {"dec", ISREX, PARAM_EDI, 0, 0 }, - // 0x50 - {"push", ALWAYS64, PARAM_EAX, 0, 0 }, - {"push", ALWAYS64, PARAM_ECX, 0, 0 }, - {"push", ALWAYS64, PARAM_EDX, 0, 0 }, - {"push", ALWAYS64, PARAM_EBX, 0, 0 }, - {"push", ALWAYS64, PARAM_ESP, 0, 0 }, - {"push", ALWAYS64, PARAM_EBP, 0, 0 }, - {"push", ALWAYS64, PARAM_ESI, 0, 0 }, - {"push", ALWAYS64, PARAM_EDI, 0, 0 }, - {"pop", ALWAYS64, PARAM_EAX, 0, 0 }, - {"pop", ALWAYS64, PARAM_ECX, 0, 0 }, - {"pop", ALWAYS64, PARAM_EDX, 0, 0 }, - {"pop", ALWAYS64, PARAM_EBX, 0, 0 }, - {"pop", ALWAYS64, PARAM_ESP, 0, 0 }, - {"pop", ALWAYS64, PARAM_EBP, 0, 0 }, - {"pop", ALWAYS64, PARAM_ESI, 0, 0 }, - {"pop", ALWAYS64, PARAM_EDI, 0, 0 }, - // 0x60 - {"pusha\0pushad\0",VAR_NAME,0, 0, 0 }, - {"popa\0popad\0", VAR_NAME,0, 0, 0 }, - {"bound", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"arpl", MODRM | SPECIAL64_ENT(0),PARAM_RM, PARAM_REG16, 0 }, - {"seg_fs", SEG_FS, 0, 0, 0 }, - {"seg_gs", SEG_GS, 0, 0, 0 }, - {"op_size", OP_SIZE, 0, 0, 0 }, - {"addr_size", ADDR_SIZE, 0, 0, 0 }, - {"push", 0, PARAM_IMM, 0, 0 }, - {"imul", MODRM, PARAM_REG, PARAM_RM, PARAM_IMM }, - {"push", 0, PARAM_I8, 0, 0 }, - {"imul", MODRM, PARAM_REG, PARAM_RM, PARAM_I8 }, - {"insb", 0, 0, 0, 0 }, - {"insw\0insd\0insd",VAR_NAME, 0, 0, 0 }, - {"outsb", 0, PARAM_PREIMP, 0, 0 }, - {"outsw\0outsd\0outsd",VAR_NAME, PARAM_PREIMP, 0, 0 }, - // 0x70 - {"jo", 0, PARAM_REL8, 0, 0 }, - {"jno", 0, PARAM_REL8, 0, 0 }, - {"jb", 0, PARAM_REL8, 0, 0 }, - {"jae", 0, PARAM_REL8, 0, 0 }, - {"je", 0, PARAM_REL8, 0, 0 }, - {"jne", 0, PARAM_REL8, 0, 0 }, - {"jbe", 0, PARAM_REL8, 0, 0 }, - {"ja", 0, PARAM_REL8, 0, 0 }, - {"js", 0, PARAM_REL8, 0, 0 }, - {"jns", 0, PARAM_REL8, 0, 0 }, - {"jp", 0, PARAM_REL8, 0, 0 }, - {"jnp", 0, PARAM_REL8, 0, 0 }, - {"jl", 0, PARAM_REL8, 0, 0 }, - {"jge", 0, PARAM_REL8, 0, 0 }, - {"jle", 0, PARAM_REL8, 0, 0 }, - {"jg", 0, PARAM_REL8, 0, 0 }, - // 0x80 - {"group80", GROUP, 0, 0, 0 }, - {"group81", GROUP, 0, 0, 0 }, - {"group80", GROUP, 0, 0, 0 }, - {"group83", GROUP, 0, 0, 0 }, - {"test", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"test", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"xchg", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"xchg", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"mov", MODRM, PARAM_RM8, PARAM_REG8, 0 }, - {"mov", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"mov", MODRM, PARAM_REG8, PARAM_RM8, 0 }, - {"mov", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"mov", MODRM, PARAM_RM, PARAM_SREG, 0 }, - {"lea", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"mov", MODRM, PARAM_SREG, PARAM_RM, 0 }, - {"pop", MODRM, PARAM_RM, 0, 0 }, - // 0x90 - {"nop\0???\0???\0pause", VAR_NAME4, 0, 0, 0 }, - {"xchg", 0, PARAM_EAX, PARAM_ECX, 0 }, - {"xchg", 0, PARAM_EAX, PARAM_EDX, 0 }, - {"xchg", 0, PARAM_EAX, PARAM_EBX, 0 }, - {"xchg", 0, PARAM_EAX, PARAM_ESP, 0 }, - {"xchg", 0, PARAM_EAX, PARAM_EBP, 0 }, - {"xchg", 0, PARAM_EAX, PARAM_ESI, 0 }, - {"xchg", 0, PARAM_EAX, PARAM_EDI, 0 }, - {"cbw\0cwde\0cdqe", VAR_NAME, 0, 0, 0 }, - {"cwd\0cdq\0cqo", VAR_NAME, 0, 0, 0 }, - {"call", ALWAYS64, PARAM_ADDR, 0, 0, STEP_OVER}, - {"wait", 0, 0, 0, 0 }, - {"pushf\0pushfd\0pushfq",VAR_NAME, 0, 0, 0 }, - {"popf\0popfd\0popfq",VAR_NAME, 0, 0, 0 }, - {"sahf", 0, 0, 0, 0 }, - {"lahf", 0, 0, 0, 0 }, - // 0xa0 - {"mov", 0, PARAM_AL, PARAM_MEM_OFFS, 0 }, - {"mov", 0, PARAM_EAX, PARAM_MEM_OFFS, 0 }, - {"mov", 0, PARAM_MEM_OFFS, PARAM_AL, 0 }, - {"mov", 0, PARAM_MEM_OFFS, PARAM_EAX, 0 }, - {"movsb", 0, PARAM_PREIMP, 0, 0 }, - {"movsw\0movsd\0movsq",VAR_NAME, PARAM_PREIMP, 0, 0 }, - {"cmpsb", 0, PARAM_PREIMP, 0, 0 }, - {"cmpsw\0cmpsd\0cmpsq",VAR_NAME, PARAM_PREIMP, 0, 0 }, - {"test", 0, PARAM_AL, PARAM_UI8, 0 }, - {"test", 0, PARAM_EAX, PARAM_IMM, 0 }, - {"stosb", 0, 0, 0, 0 }, - {"stosw\0stosd\0stosq",VAR_NAME, 0, 0, 0 }, - {"lodsb", 0, PARAM_PREIMP, 0, 0 }, - {"lodsw\0lodsd\0lodsq",VAR_NAME, PARAM_PREIMP, 0, 0 }, - {"scasb", 0, 0, 0, 0 }, - {"scasw\0scasd\0scasq",VAR_NAME, 0, 0, 0 }, - // 0xb0 - {"mov", 0, PARAM_AL, PARAM_UI8, 0 }, - {"mov", 0, PARAM_CL, PARAM_UI8, 0 }, - {"mov", 0, PARAM_DL, PARAM_UI8, 0 }, - {"mov", 0, PARAM_BL, PARAM_UI8, 0 }, - {"mov", 0, PARAM_AH, PARAM_UI8, 0 }, - {"mov", 0, PARAM_CH, PARAM_UI8, 0 }, - {"mov", 0, PARAM_DH, PARAM_UI8, 0 }, - {"mov", 0, PARAM_BH, PARAM_UI8, 0 }, - {"mov", 0, PARAM_EAX, PARAM_IMM64, 0 }, - {"mov", 0, PARAM_ECX, PARAM_IMM64, 0 }, - {"mov", 0, PARAM_EDX, PARAM_IMM64, 0 }, - {"mov", 0, PARAM_EBX, PARAM_IMM64, 0 }, - {"mov", 0, PARAM_ESP, PARAM_IMM64, 0 }, - {"mov", 0, PARAM_EBP, PARAM_IMM64, 0 }, - {"mov", 0, PARAM_ESI, PARAM_IMM64, 0 }, - {"mov", 0, PARAM_EDI, PARAM_IMM64, 0 }, - // 0xc0 - {"groupC0", GROUP, 0, 0, 0 }, - {"groupC1", GROUP, 0, 0, 0 }, - {"ret", 0, PARAM_UI16, 0, 0, STEP_OUT}, - {"ret", 0, 0, 0, 0, STEP_OUT}, - {"les", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"lds", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"mov", MODRM, PARAM_RMPTR, PARAM_IMM, 0 }, - {"enter", 0, PARAM_UI16, PARAM_UI8, 0 }, - {"leave", 0, 0, 0, 0 }, - {"retf", 0, PARAM_UI16, 0, 0, STEP_OUT}, - {"retf", 0, 0, 0, 0, STEP_OUT}, - {"int 3", 0, 0, 0, 0, STEP_OVER}, - {"int", 0, PARAM_UI8, 0, 0, STEP_OVER}, - {"into", 0, 0, 0, 0 }, - {"iret", 0, 0, 0, 0, STEP_OUT}, - // 0xd0 - {"groupD0", GROUP, 0, 0, 0 }, - {"groupD1", GROUP, 0, 0, 0 }, - {"groupD2", GROUP, 0, 0, 0 }, - {"groupD3", GROUP, 0, 0, 0 }, - {"aam", 0, PARAM_UI8, 0, 0 }, - {"aad", 0, PARAM_UI8, 0, 0 }, - {"salc", 0, 0, 0, 0 }, //AMD docs name it - {"xlat", 0, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - {"escape", FPU, 0, 0, 0 }, - // 0xe0 - {"loopne", 0, PARAM_REL8, 0, 0, STEP_OVER}, - {"loopz", 0, PARAM_REL8, 0, 0, STEP_OVER}, - {"loop", 0, PARAM_REL8, 0, 0, STEP_OVER}, - {"jcxz\0jecxz\0jrcxz",VAR_NAME, PARAM_REL8, 0, 0 }, - {"in", 0, PARAM_AL, PARAM_UI8, 0 }, - {"in", 0, PARAM_EAX, PARAM_UI8, 0 }, - {"out", 0, PARAM_UI8, PARAM_AL, 0 }, - {"out", 0, PARAM_UI8, PARAM_EAX, 0 }, - {"call", 0, PARAM_REL, 0, 0, STEP_OVER}, - {"jmp", 0, PARAM_REL, 0, 0 }, - {"jmp", 0, PARAM_ADDR, 0, 0 }, - {"jmp", 0, PARAM_REL8, 0, 0 }, - {"in", 0, PARAM_AL, PARAM_DX, 0 }, - {"in", 0, PARAM_EAX, PARAM_DX, 0 }, - {"out", 0, PARAM_DX, PARAM_AL, 0 }, - {"out", 0, PARAM_DX, PARAM_EAX, 0 }, - // 0xf0 - {"lock", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"repne", PREFIX, 0, 0, 0, STEP_OVER}, - {"rep", PREFIX, 0, 0, 0, STEP_OVER}, - {"hlt", 0, 0, 0, 0 }, - {"cmc", 0, 0, 0, 0 }, - {"groupF6", GROUP, 0, 0, 0 }, - {"groupF7", GROUP, 0, 0, 0 }, - {"clc", 0, 0, 0, 0 }, - {"stc", 0, 0, 0, 0 }, - {"cli", 0, 0, 0, 0 }, - {"sti", 0, 0, 0, 0 }, - {"cld", 0, 0, 0, 0 }, - {"std", 0, 0, 0, 0 }, - {"groupFE", GROUP, 0, 0, 0 }, - {"groupFF", GROUP, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::x64_opcode_alt[] = -{ - {"movsxd", MODRM | ALWAYS64,PARAM_REG, PARAM_RMPTR32, 0 }, -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table2[256] = -{ - // 0x00 - {"group0F00", GROUP, 0, 0, 0 }, - {"group0F01", GROUP, 0, 0, 0 }, - {"lar", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"lsl", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"???", 0, 0, 0, 0 }, - {"syscall", 0, 0, 0, 0 }, - {"clts", 0, 0, 0, 0 }, - {"sysret", 0, 0, 0, 0 }, - {"invd", 0, 0, 0, 0 }, - {"wbinvd", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"ud2", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"group0F0D", GROUP, 0, 0, 0 }, //AMD only - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x10 - {"movups\0" - "movupd\0" - "movsd\0" - "movss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"movups\0" - "movupd\0" - "movsd\0" - "movss", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 }, - {"group0F12", GROUP|GROUP_MOD, 0, 0, 0 }, - {"movlps\0" - "movlpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 }, - {"unpcklps\0" - "unpcklpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"unpckhps\0" - "unpckhpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - { "group0F16", GROUP|GROUP_MOD, 0, 0, 0 }, - {"movhps\0" - "movhpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 }, - {"group0F18", GROUP, 0, 0, 0 }, - {"nop_hint", 0, PARAM_RMPTR8, 0, 0 }, - {"nop_hint", 0, PARAM_RMPTR8, 0, 0 }, - {"nop_hint", 0, PARAM_RMPTR8, 0, 0 }, - {"nop_hint", 0, PARAM_RMPTR8, 0, 0 }, - {"nop_hint", 0, PARAM_RMPTR8, 0, 0 }, - {"nop_hint", 0, PARAM_RMPTR8, 0, 0 }, - {"nop_hint", 0, PARAM_RMPTR8, 0, 0 }, - // 0x20 - {"mov", MODRM, PARAM_REG2_32, PARAM_CREG, 0 }, - {"mov", MODRM, PARAM_REG2_32, PARAM_DREG, 0 }, - {"mov", MODRM, PARAM_CREG, PARAM_REG2_32, 0 }, - {"mov", MODRM, PARAM_DREG, PARAM_REG2_32, 0 }, - {"mov", MODRM, PARAM_REG2_32, PARAM_TREG, 0 }, - {"???", 0, 0, 0, 0 }, - {"mov", MODRM, PARAM_TREG, PARAM_REG2_32, 0 }, - {"???", 0, 0, 0, 0 }, - {"movaps\0" - "movapd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"movaps\0" - "movapd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 }, - {"cvtpi2ps\0" - "cvtpi2pd\0" - "cvtsi2sd\0" - "cvtsi2ss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_RMXMM, 0 }, - {"movntps\0" - "movntpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMMM, PARAM_XMM, 0 }, - {"cvttps2pi\0" - "cvttpd2pi\0" - "cvttsd2si\0" - "cvttss2si", MODRM|VAR_NAME4,PARAM_REGORXMM, PARAM_XMMM, 0 }, - {"cvtps2pi\0" - "cvtpd2pi\0" - "cvtsd2si\0" - "cvtss2si", MODRM|VAR_NAME4,PARAM_REGORXMM, PARAM_XMMM, 0 }, - {"ucomiss\0" - "ucomisd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"comiss\0" - "comisd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - // 0x30 - {"wrmsr", 0, 0, 0, 0 }, - {"rdtsc", 0, 0, 0, 0 }, - {"rdmsr", 0, 0, 0, 0 }, - {"rdpmc", 0, 0, 0, 0 }, - {"sysenter", 0, 0, 0, 0 }, - {"sysexit", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"three_byte", THREE_BYTE, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"three_byte", THREE_BYTE, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x40 - {"cmovo", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovno", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovb", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovae", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmove", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovne", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovbe", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmova", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovs", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovns", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovpe", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovpo", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovl", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovge", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovle", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"cmovg", MODRM, PARAM_REG, PARAM_RM, 0 }, - // 0x50 - {"movmskps\0" - "movmskpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_REG3264, PARAM_XMMM, 0 }, - {"sqrtps\0" - "sqrtpd\0" - "sqrtsd\0" - "sqrtss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"rsqrtps\0" - "???\0" - "???\0" - "rsqrtss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"rcpps\0" - "???\0" - "???\0" - "rcpss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"andps\0" - "andpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"andnps\0" - "andnpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"orps\0" - "orpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"xorps\0" - "xorpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"addps\0" - "addpd\0" - "addsd\0" - "addss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"mulps\0" - "mulpd\0" - "mulsd\0" - "mulss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"cvtps2pd\0" - "cvtpd2ps\0" - "cvtsd2ss\0" - "cvtss2sd", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"cvtdq2ps\0" - "cvtps2dq\0" - "???\0" - "cvttps2dq", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"subps\0" - "subpd\0" - "subsd\0" - "subss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"minps\0" - "minpd\0" - "minsd\0" - "minss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"divps\0" - "divpd\0" - "divsd\0" - "divss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"maxps\0" - "maxpd\0" - "maxsd\0" - "maxss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - // 0x60 - {"punpcklbw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"punpcklwd", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"punpckldq", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"packsswb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pcmpgtb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pcmpgtw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pcmpgtd", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"packuswb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"punpckhbw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"punpckhwd", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"punpckhdq", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"packssdw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"???\0" - "punpcklqdq\0" - "???\0" - "???\0", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "punpckhqdq\0" - "???\0" - "???\0", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"movd", MODRM, PARAM_MMX, PARAM_RM, 0 }, - {"movq\0" - "movdqa\0" - "???\0" - "movdqu", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 }, - // 0x70 - {"pshufw\0" - "pshufd\0" - "pshuflw\0" - "pshufhw", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, PARAM_UI8 }, - {"group0F71", GROUP, 0, 0, 0 }, - {"group0F72", GROUP, 0, 0, 0 }, - {"group0F73", GROUP, 0, 0, 0 }, - {"pcmpeqb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pcmpeqw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pcmpeqd", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"emms", 0, 0, 0, 0 }, - {"vmread", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"vmwrite", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "haddpd\0" - "haddps\0" - "???", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 }, - {"???\0" - "hsubpd\0" - "hsubps\0" - "???", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 }, - {"movd\0" - "movd\0" - "???\0" - "movq", MODRM|VAR_NAME4,PARAM_RM, PARAM_MMX, 0 }, - {"movq\0" - "movdqa\0" - "???\0" - "movdqu", MODRM|VAR_NAME4,PARAM_MMXM, PARAM_MMX, 0 }, - // 0x80 - {"jo", 0, PARAM_REL, 0, 0 }, - {"jno", 0, PARAM_REL, 0, 0 }, - {"jb", 0, PARAM_REL, 0, 0 }, - {"jae", 0, PARAM_REL, 0, 0 }, - {"je", 0, PARAM_REL, 0, 0 }, - {"jne", 0, PARAM_REL, 0, 0 }, - {"jbe", 0, PARAM_REL, 0, 0 }, - {"ja", 0, PARAM_REL, 0, 0 }, - {"js", 0, PARAM_REL, 0, 0 }, - {"jns", 0, PARAM_REL, 0, 0 }, - {"jp", 0, PARAM_REL, 0, 0 }, - {"jnp", 0, PARAM_REL, 0, 0 }, - {"jl", 0, PARAM_REL, 0, 0 }, - {"jge", 0, PARAM_REL, 0, 0 }, - {"jle", 0, PARAM_REL, 0, 0 }, - {"jg", 0, PARAM_REL, 0, 0 }, - // 0x90 - {"seto", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setno", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setb", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setae", MODRM, PARAM_RMPTR8, 0, 0 }, - {"sete", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setne", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setbe", MODRM, PARAM_RMPTR8, 0, 0 }, - {"seta", MODRM, PARAM_RMPTR8, 0, 0 }, - {"sets", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setns", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setp", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setnp", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setl", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setge", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setle", MODRM, PARAM_RMPTR8, 0, 0 }, - {"setg", MODRM, PARAM_RMPTR8, 0, 0 }, - // 0xa0 - {"push fs", 0, 0, 0, 0 }, - {"pop fs", 0, 0, 0, 0 }, - {"cpuid", 0, 0, 0, 0 }, - {"bt", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"shld", MODRM, PARAM_RM, PARAM_REG, PARAM_UI8 }, - {"shld", MODRM, PARAM_RM, PARAM_REG, PARAM_CL }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"push gs", 0, 0, 0, 0 }, - {"pop gs", 0, 0, 0, 0 }, - {"rsm", 0, 0, 0, 0 }, - {"bts", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"shrd", MODRM, PARAM_RM, PARAM_REG, PARAM_UI8 }, - {"shrd", MODRM, PARAM_RM, PARAM_REG, PARAM_CL }, - {"group0FAE", GROUP, 0, 0, 0 }, - {"imul", MODRM, PARAM_REG, PARAM_RM, 0 }, - // 0xb0 - {"cmpxchg", MODRM, PARAM_RM8, PARAM_REG, 0 }, - {"cmpxchg", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"lss", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"btr", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"lfs", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"lgs", MODRM, PARAM_REG, PARAM_RM, 0 }, - {"movzx", MODRM, PARAM_REG, PARAM_RMPTR8, 0 }, - {"movzx", MODRM, PARAM_REG, PARAM_RMPTR16, 0 }, - {"???\0" - "???\0" - "???\0" - "popcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM16, 0 }, - {"ud2", 0, 0, 0, 0 }, - {"group0FBA", GROUP, 0, 0, 0 }, - {"btc", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"bsf\0" - "???\0" - "???\0" - "tzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0 }, - {"bsr\0" - "???\0" - "???\0" - "lzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0, STEP_OVER}, - {"movsx", MODRM, PARAM_REG, PARAM_RMPTR8, 0 }, - {"movsx", MODRM, PARAM_REG, PARAM_RMPTR16, 0 }, - // 0xc0 - {"xadd", MODRM, PARAM_RM8, PARAM_REG, 0 }, - {"xadd", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"cmpps\0" - "cmppd\0" - "cmpsd\0" - "cmpss", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"movnti", MODRM, PARAM_RM, PARAM_REG, 0 }, - {"pinsrw", MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 }, - {"pextrw", MODRM, PARAM_MMX, PARAM_RM, PARAM_UI8 }, - {"shufps\0" - "shufpd\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"group0FC7", GROUP, 0, 0, 0 }, - {"bswap", 0, PARAM_EAX, 0, 0 }, - {"bswap", 0, PARAM_ECX, 0, 0 }, - {"bswap", 0, PARAM_EDX, 0, 0 }, - {"bswap", 0, PARAM_EBX, 0, 0 }, - {"bswap", 0, PARAM_ESP, 0, 0 }, - {"bswap", 0, PARAM_EBP, 0, 0 }, - {"bswap", 0, PARAM_ESI, 0, 0 }, - {"bswap", 0, PARAM_EDI, 0, 0 }, - // 0xd0 - {"???\0" - "addsubpd\0" - "addsubps\0" - "???\0", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"psrlw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psrld", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psrlq", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddq", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pmullw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"???\0" - "movq\0" - "movdq2q\0" - "movq2dq", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 }, - {"pmovmskb", MODRM, PARAM_REG3264, PARAM_MMXM, 0 }, - {"psubusb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psubusw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pminub", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pand", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddusb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddusw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pmaxub", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pandn", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - // 0xe0 - {"pavgb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psraw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psrad", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pavgw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pmulhuw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pmulhw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"???\0" - "cvttpd2dq\0" - "cvtpd2dq\0" - "cvtdq2pd", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"movntq\0" - "movntdq\0" - "???\0" - "???\0", MODRM|VAR_NAME4, PARAM_M64, PARAM_MMX, 0 }, - {"psubsb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psubsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pminsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"por", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddsb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pmaxsw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pxor", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - // 0xf0 - {"???\0" - "???\0" - "lddqu\0" - "???", MODRM|VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - {"psllw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pslld", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psllq", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pmuludq", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"pmaddwd", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psadbw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"maskmovq\0" - "maskmovdqu\0" - "???\0" - "???", MODRM|VAR_NAME4,PARAM_MMX, PARAM_MMXM, 0 }, - {"psubb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psubw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psubd", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"psubq", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddb", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddw", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"paddd", MODRM, PARAM_MMX, PARAM_MMXM, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F38[256] = -{ - // 0x00 - {"pshufb\0" - "pshufb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"phaddw\0" - "phaddw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"phaddd\0" - "phadd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"phaddsw\0" - "phaddsw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"pmaddubsw\0" - "pmaddubsw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"phsubw\0" - "phsubw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"phsubd\0" - "phsubd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"phsubsw\0" - "phsubsw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"psignb\0" - "psignb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"psignw\0" - "psignw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"psignd\0" - "psignd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"pmulhrsw\0" - "pmulhrsw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x10 - {"???\0" - "pblendvb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "blendvps\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 }, - {"???\0" - "blendvpd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_XMM0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "ptest\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"pabsb\0" - "pabsb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"pabsw\0" - "pabsw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"pabsd\0" - "pabsd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x20 - {"???\0" - "pmovsxbw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 }, - {"???\0" - "pmovsxbd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 }, - {"???\0" - "pmovsxbq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM16, 0 }, - {"???\0" - "pmovsxwd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 }, - {"???\0" - "pmovsxwq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 }, - {"???\0" - "pmovsxdq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "pmuldq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pcmpeqq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "movntdqa\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "packusdw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x30 - {"???\0" - "pmovzxbw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 }, - {"???\0" - "pmovzxbd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 }, - {"???\0" - "pmovzxbq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM16, 0 }, - {"???\0" - "pmovzxwd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 }, - {"???\0" - "pmovzxwq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM32, 0 }, - {"???\0" - "pmovzxdq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMM64, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "pcmpgtq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pminsb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pminsd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pminuw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pminud\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pmaxsb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pmaxsd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pmaxuw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "pmaxud\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - // 0x40 - {"???\0" - "pmulld\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "phminposuw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x50 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x60 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x70 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x80 - {"???\0" - "invept\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 }, - {"???\0" - "invvpid\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 }, - {"???\0" - "invpcid\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_XMMM, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x90 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xa0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xb0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xc0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xd0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "aesimc\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "aesenc\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "aesenclast\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "aesdec\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - {"???\0" - "aesdeclast\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, 0 }, - // 0xe0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xf0 - {"movbe\0" - "???\0" - "crc32\0" - "???", MODRM|VAR_NAME4, PARAM_REG32, PARAM_RMPTR, 0 }, // not quite correct - {"movbe\0" - "???\0" - "crc32\0" - "???", MODRM|VAR_NAME4, PARAM_RMPTR, PARAM_REG32, 0 }, // not quite correct - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F3A[256] = -{ - // 0x00 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "roundps\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "roundpd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "roundss\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "roundsd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "blendps\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "blendpd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "pblendw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"palignr\0" - "palignr\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - // 0x10 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "pextrb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_RM8, PARAM_XMM, PARAM_UI8 }, - {"???\0" - "pextrw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_RM16, PARAM_XMM, PARAM_UI8 }, - {"???\0" - "pextrd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_RM8, PARAM_XMM, PARAM_UI8 }, - {"???\0" - "extractps\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_RM32, PARAM_XMM, PARAM_UI8 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x20 - {"???\0" - "pinsrb\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM8, PARAM_UI8 }, - {"???\0" - "insertps\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM8, PARAM_UI8 }, - {"???\0" - "pinsrd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_RM32, PARAM_UI8 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x30 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x40 - {"???\0" - "dpps\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "dppd\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "mpsadbw\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "pclmulqdq\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x50 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x60 - {"???\0" - "pcmestrm\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "pcmestri\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "pcmistrm\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???\0" - "pcmistri\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x70 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x80 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0x90 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xa0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xb0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xc0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xd0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???\0" - "aeskeygenassist\0" - "???\0" - "???", MODRM|VAR_NAME4, PARAM_XMM, PARAM_XMMM, PARAM_UI8 }, - // 0xe0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - // 0xf0 - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group80_table[8] = -{ - {"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"adc", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"sbb", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"and", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"sub", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"xor", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group81_table[8] = -{ - {"add", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"or", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"adc", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"sbb", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"and", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"sub", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"xor", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"cmp", 0, PARAM_RMPTR, PARAM_IMM, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group83_table[8] = -{ - {"add", 0, PARAM_RMPTR, PARAM_I8, 0 }, - {"or", 0, PARAM_RMPTR, PARAM_I8, 0 }, - {"adc", 0, PARAM_RMPTR, PARAM_I8, 0 }, - {"sbb", 0, PARAM_RMPTR, PARAM_I8, 0 }, - {"and", 0, PARAM_RMPTR, PARAM_I8, 0 }, - {"sub", 0, PARAM_RMPTR, PARAM_I8, 0 }, - {"xor", 0, PARAM_RMPTR, PARAM_I8, 0 }, - {"cmp", 0, PARAM_RMPTR, PARAM_I8, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupC0_table[8] = -{ - {"rol", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"ror", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"rcl", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"rcr", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"shl", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"shr", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"sal", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"sar", 0, PARAM_RMPTR8, PARAM_UI8, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupC1_table[8] = -{ - {"rol", 0, PARAM_RMPTR, PARAM_UI8, 0 }, - {"ror", 0, PARAM_RMPTR, PARAM_UI8, 0 }, - {"rcl", 0, PARAM_RMPTR, PARAM_UI8, 0 }, - {"rcr", 0, PARAM_RMPTR, PARAM_UI8, 0 }, - {"shl", 0, PARAM_RMPTR, PARAM_UI8, 0 }, - {"shr", 0, PARAM_RMPTR, PARAM_UI8, 0 }, - {"sal", 0, PARAM_RMPTR, PARAM_UI8, 0 }, - {"sar", 0, PARAM_RMPTR, PARAM_UI8, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupD0_table[8] = -{ - {"rol", 0, PARAM_RMPTR8, PARAM_1, 0 }, - {"ror", 0, PARAM_RMPTR8, PARAM_1, 0 }, - {"rcl", 0, PARAM_RMPTR8, PARAM_1, 0 }, - {"rcr", 0, PARAM_RMPTR8, PARAM_1, 0 }, - {"shl", 0, PARAM_RMPTR8, PARAM_1, 0 }, - {"shr", 0, PARAM_RMPTR8, PARAM_1, 0 }, - {"sal", 0, PARAM_RMPTR8, PARAM_1, 0 }, - {"sar", 0, PARAM_RMPTR8, PARAM_1, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupD1_table[8] = -{ - {"rol", 0, PARAM_RMPTR, PARAM_1, 0 }, - {"ror", 0, PARAM_RMPTR, PARAM_1, 0 }, - {"rcl", 0, PARAM_RMPTR, PARAM_1, 0 }, - {"rcr", 0, PARAM_RMPTR, PARAM_1, 0 }, - {"shl", 0, PARAM_RMPTR, PARAM_1, 0 }, - {"shr", 0, PARAM_RMPTR, PARAM_1, 0 }, - {"sal", 0, PARAM_RMPTR, PARAM_1, 0 }, - {"sar", 0, PARAM_RMPTR, PARAM_1, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupD2_table[8] = -{ - {"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 }, - {"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 }, - {"rcl", 0, PARAM_RMPTR8, PARAM_CL, 0 }, - {"rcr", 0, PARAM_RMPTR8, PARAM_CL, 0 }, - {"shl", 0, PARAM_RMPTR8, PARAM_CL, 0 }, - {"shr", 0, PARAM_RMPTR8, PARAM_CL, 0 }, - {"sal", 0, PARAM_RMPTR8, PARAM_CL, 0 }, - {"sar", 0, PARAM_RMPTR8, PARAM_CL, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupD3_table[8] = -{ - {"rol", 0, PARAM_RMPTR, PARAM_CL, 0 }, - {"ror", 0, PARAM_RMPTR, PARAM_CL, 0 }, - {"rcl", 0, PARAM_RMPTR, PARAM_CL, 0 }, - {"rcr", 0, PARAM_RMPTR, PARAM_CL, 0 }, - {"shl", 0, PARAM_RMPTR, PARAM_CL, 0 }, - {"shr", 0, PARAM_RMPTR, PARAM_CL, 0 }, - {"sal", 0, PARAM_RMPTR, PARAM_CL, 0 }, - {"sar", 0, PARAM_RMPTR, PARAM_CL, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupF6_table[8] = -{ - {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, - {"not", 0, PARAM_RMPTR8, 0, 0 }, - {"neg", 0, PARAM_RMPTR8, 0, 0 }, - {"mul", 0, PARAM_RMPTR8, 0, 0 }, - {"imul", 0, PARAM_RMPTR8, 0, 0 }, - {"div", 0, PARAM_RMPTR8, 0, 0 }, - {"idiv", 0, PARAM_RMPTR8, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupF7_table[8] = -{ - {"test", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"test", 0, PARAM_RMPTR, PARAM_IMM, 0 }, - {"not", 0, PARAM_RMPTR, 0, 0 }, - {"neg", 0, PARAM_RMPTR, 0, 0 }, - {"mul", 0, PARAM_RMPTR, 0, 0 }, - {"imul", 0, PARAM_RMPTR, 0, 0 }, - {"div", 0, PARAM_RMPTR, 0, 0 }, - {"idiv", 0, PARAM_RMPTR, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupFE_table[8] = -{ - {"inc", 0, PARAM_RMPTR8, 0, 0 }, - {"dec", 0, PARAM_RMPTR8, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::groupFF_table[8] = -{ - {"inc", 0, PARAM_RMPTR, 0, 0 }, - {"dec", 0, PARAM_RMPTR, 0, 0 }, - {"call", ALWAYS64, PARAM_RMPTR, 0, 0, STEP_OVER}, - {"call far ptr ",0, PARAM_RM, 0, 0, STEP_OVER}, - {"jmp", ALWAYS64, PARAM_RMPTR, 0, 0 }, - {"jmp far ptr ",0, PARAM_RM, 0, 0 }, - {"push", 0, PARAM_RMPTR, 0, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F00_table[8] = -{ - {"sldt", 0, PARAM_RM, 0, 0 }, - {"str", 0, PARAM_RM, 0, 0 }, - {"lldt", 0, PARAM_RM, 0, 0 }, - {"ltr", 0, PARAM_RM, 0, 0 }, - {"verr", 0, PARAM_RM, 0, 0 }, - {"verw", 0, PARAM_RM, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F01_table[8] = -{ - {"sgdt", 0, PARAM_RM, 0, 0 }, - {"sidt", 0, PARAM_RM, 0, 0 }, - {"lgdt", 0, PARAM_RM, 0, 0 }, - {"lidt", 0, PARAM_RM, 0, 0 }, - {"smsw", 0, PARAM_RM, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"lmsw", 0, PARAM_RM, 0, 0 }, - {"invlpg", 0, PARAM_RM, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F0D_table[8] = -{ - {"prefetch", 0, PARAM_RM8, 0, 0 }, - {"prefetchw", 0, PARAM_RM8, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F12_table[4] = -{ - { "movlps\0" - "movlpd\0" - "movddup\0" - "movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - { "movlps\0" - "movlpd\0" - "movddup\0" - "movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - { "movlps\0" - "movlpd\0" - "movddup\0" - "movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - { "movhlps\0" - "???\0" - "movddup\0" - "movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F16_table[4] = -{ - { "movhps\0" - "movhpd\0" - "???\0" - "movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - { "movhps\0" - "movhpd\0" - "???\0" - "movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - { "movhps\0" - "movhpd\0" - "???\0" - "movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 }, - { "movlhps\0" - "movhpd\0" - "???\0" - "movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F18_table[8] = -{ - {"prefetchnta", 0, PARAM_RM8, 0, 0 }, - {"prefetch0", 0, PARAM_RM8, 0, 0 }, - {"prefetch1", 0, PARAM_RM8, 0, 0 }, - {"prefetch2", 0, PARAM_RM8, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F71_table[8] = -{ - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"psrlw", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"???", 0, 0, 0, 0 }, - {"psraw", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"???", 0, 0, 0, 0 }, - {"psllw", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F72_table[8] = -{ - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"psrld", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"???", 0, 0, 0, 0 }, - {"psrad", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"???", 0, 0, 0, 0 }, - {"pslld", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"???", 0, 0, 0, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0F73_table[8] = -{ - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"psrlq", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"psrldq", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"psllq", 0, PARAM_MMX2, PARAM_UI8, 0 }, - {"pslldq", 0, PARAM_MMX2, PARAM_UI8, 0 }, -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0FAE_table[8] = -{ - {"fxsave", 0, PARAM_RM, 0, 0 }, - {"fxrstor", 0, PARAM_RM, 0, 0 }, - {"ldmxcsr", 0, PARAM_RM, 0, 0 }, - {"stmxscr", 0, PARAM_RM, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"lfence", 0, 0, 0, 0 }, - {"mfence", 0, 0, 0, 0 }, - {"sfence", 0, 0, 0, 0 } -}; - - -const i386_disassembler::I386_OPCODE i386_disassembler::group0FBA_table[8] = -{ - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"bt", 0, PARAM_RM, PARAM_UI8, 0 }, - {"bts", 0, PARAM_RM, PARAM_UI8, 0 }, - {"btr", 0, PARAM_RM, PARAM_UI8, 0 }, - {"btc", 0, PARAM_RM, PARAM_UI8, 0 } -}; - -const i386_disassembler::I386_OPCODE i386_disassembler::group0FC7_table[8] = -{ - {"???", 0, 0, 0, 0 }, - {"cmpxchg8b", MODRM, PARAM_M64PTR, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"???", 0, 0, 0, 0 }, - {"vmptrld\0" - "vmclear\0" - "???\0" - "vmxon", MODRM|VAR_NAME4, PARAM_M64PTR, 0, 0 }, - {"vmptrtst", MODRM, PARAM_M64PTR, 0, 0 } -}; - -const i386_disassembler::GROUP_OP i386_disassembler::group_op_table[] = -{ - { "group80", group80_table }, - { "group81", group81_table }, - { "group83", group83_table }, - { "groupC0", groupC0_table }, - { "groupC1", groupC1_table }, - { "groupD0", groupD0_table }, - { "groupD1", groupD1_table }, - { "groupD2", groupD2_table }, - { "groupD3", groupD3_table }, - { "groupF6", groupF6_table }, - { "groupF7", groupF7_table }, - { "groupFE", groupFE_table }, - { "groupFF", groupFF_table }, - { "group0F00", group0F00_table }, - { "group0F01", group0F01_table }, - { "group0F0D", group0F0D_table }, - { "group0F12", group0F12_table }, - { "group0F16", group0F16_table }, - { "group0F18", group0F18_table }, - { "group0F71", group0F71_table }, - { "group0F72", group0F72_table }, - { "group0F73", group0F73_table }, - { "group0FAE", group0FAE_table }, - { "group0FBA", group0FBA_table }, - { "group0FC7", group0FC7_table } -}; - - - -const char *const i386_disassembler::i386_reg[3][16] = -{ - {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w","r11w","r12w","r13w","r14w","r15w"}, - {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d","r11d","r12d","r13d","r14d","r15d"}, - {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"} -}; - -const char *const i386_disassembler::i386_reg8[8] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; -const char *const i386_disassembler::i386_reg8rex[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"}; -const char *const i386_disassembler::i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "???", "???"}; - -inline uint8_t i386_disassembler::FETCH(offs_t base_pc, offs_t &pc, i386_device* parent) -{ - if ((pc - base_pc) + 1 > max_length) - return 0xff; - uint8_t d = parent->read_debug_data8(pc); - pc++; - return d; -} - -inline uint16_t i386_disassembler::FETCH16(offs_t base_pc, offs_t &pc, i386_device* parent) -{ - if ((pc - base_pc) + 2 > max_length) - return 0xffff; - uint16_t d = parent->read_debug_data16(pc); - pc += 2; - return d; -} - -inline uint32_t i386_disassembler::FETCH32(offs_t base_pc, offs_t &pc, i386_device* parent) -{ - if ((pc - base_pc) + 4 > max_length) - return 0xffffffff; - uint32_t d = parent->read_debug_data32(pc); - pc += 4; - return d; -} - -inline uint8_t i386_disassembler::FETCHD(offs_t base_pc, offs_t &pc, i386_device* parent) -{ - return FETCH(base_pc, pc, parent); -} - -inline uint16_t i386_disassembler::FETCHD16(offs_t base_pc, offs_t &pc, i386_device* parent) -{ - return FETCH16(base_pc, pc, parent); -} - -inline uint32_t i386_disassembler::FETCHD32(offs_t base_pc, offs_t &pc, i386_device* parent) -{ - return FETCH32(base_pc, pc, parent); -} - -char *i386_disassembler::hexstring(uint32_t value, int digits) -{ - static char buffer[20]; - buffer[0] = '0'; - if (digits) - sprintf(&buffer[1], "%0*Xh", digits, value); - else - sprintf(&buffer[1], "%Xh", value); - return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; -} - -char *i386_disassembler::hexstring64(uint32_t lo, uint32_t hi) -{ - static char buffer[40]; - buffer[0] = '0'; - if (hi != 0) - sprintf(&buffer[1], "%X%08Xh", hi, lo); - else - sprintf(&buffer[1], "%Xh", lo); - return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; -} - -char *i386_disassembler::hexstringpc(uint64_t pc) -{ - if (m_config->get_mode() == 64) - return hexstring64((uint32_t)pc, (uint32_t)(pc >> 32)); - else - return hexstring((uint32_t)pc, 0); -} - -char *i386_disassembler::shexstring(uint32_t value, int digits, bool always) -{ - static char buffer[20]; - if (value >= 0x80000000) - sprintf(buffer, "-%s", hexstring(-value, digits)); - else if (always) - sprintf(buffer, "+%s", hexstring(value, digits)); - else - return hexstring(value, digits); - return buffer; -} - -void i386_disassembler::add_snprintf(_TCHAR* buffer, size_t len, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - int result = vsnprintf(buffer, len, format, ap); - va_end(ap); - return result; -} - -void i386_disassembler::handle_sib_byte(_TCHAR* buffer, size_t len, uint8_t mod, offs_t base_pc, offs_t &pc, i386_device* parent) -{ - uint32_t i32; - uint8_t scale, i, base; - uint8_t sib = FETCHD(base_pc, pc, parent); - - scale = (sib >> 6) & 0x3; - i = ((sib >> 3) & 0x7) | sibex; - base = (sib & 0x7) | rmex; - - if (base == 5 && mod == 0) { - i32 = FETCHD32(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstring(i32, 0)); - } else if (base != 5 || mod != 3) - add_snprintf(buffer, len, "%s", i386_reg[address_size][base]); - - if ( i != 4 ) { - add_snprintf(buffer, len, "+%s", i386_reg[address_size][i]); - if (scale) - add_snprintf(buffer, len, "*%d", 1 << scale); - } -} - -void i386_disassembler::handle_modrm(_TCHAR *buffer, size_t len, offs_t base_pc, offs_t &pc, i386_device* parent) -{ - int8_t disp8; - int16_t disp16; - int32_t disp32; - uint8_t mod, rm; - - modrm = FETCHD(base_pc, pc, parent); - mod = (modrm >> 6) & 0x3; - rm = (modrm & 0x7) | rmex; - - if( modrm >= 0xc0 ) - return; - - switch(segment) - { - case SEG_CS: add_snprintf(buffer, len, "cs:"); break; - case SEG_DS: add_snprintf(buffer, len, "ds:"); break; - case SEG_ES: add_snprintf(buffer, len, "es:"); break; - case SEG_FS: add_snprintf(buffer, len, "fs:"); break; - case SEG_GS: add_snprintf(buffer, len, "gs:"); break; - case SEG_SS: add_snprintf(buffer, len, "ss:"); break; - } - - add_snprintf(buffer, len, "[" ); - if( address_size == 2 ) { - if ((rm & 7) == 4) - handle_sib_byte(buffer, len, mod, base_pc, pc, parent); - else if ((rm & 7) == 5 && mod == 0) { - disp32 = FETCHD32(base_pc, pc, parent); - add_snprintf(buffer, len, "rip%s", shexstring(disp32, 0, true)); - } else - add_snprintf(buffer, len, "%s", i386_reg[2][rm]); - if( mod == 1 ) { - disp8 = FETCHD(base_pc, pc, parent); - if (disp8 != 0) - add_snprintf(buffer, len, "%s", shexstring((int32_t)disp8, 0, true) ); - } else if( mod == 2 ) { - disp32 = FETCHD32(base_pc, pc, oparent); - if (disp32 != 0) - add_snprintf(buffer, len, "%s", shexstring(disp32, 0, true) ); - } - } else if (address_size == 1) { - if ((rm & 7) == 4) - handle_sib_byte(buffer, len, mod, base_pc, pc, parent); - else if ((rm & 7) == 5 && mod == 0) { - disp32 = FETCHD32(base_pc, pc, parent); - if (m_config->get_mode() == 64) - add_snprintf(buffer, len, "eip%s", shexstring(disp32, 0, true) ); - else - add_snprintf(buffer, len, "%s", hexstring(disp32, 0) ); - } else - add_snprintf(buffer, len, "%s", i386_reg[1][rm]); - if( mod == 1 ) { - disp8 = FETCHD(base_pc, pc, parent); - if (disp8 != 0) - add_snprintf(buffer, len, "%s", shexstring((int32_t)disp8, 0, true) ); - } else if( mod == 2 ) { - disp32 = FETCHD32(base_pc, pc, parent); - if (disp32 != 0) - add_snprintf(buffer, len, "%s", shexstring(disp32, 0, true) ); - } - } else { - switch( rm ) - { - case 0: add_snprintf(buffer, len, "bx+si" ); break; - case 1: add_snprintf(buffer, len, "bx+di" ); break; - case 2: add_snprintf(buffer, len, "bp+si" ); break; - case 3: add_snprintf(buffer, len, "bp+di" ); break; - case 4: add_snprintf(buffer, len, "si" ); break; - case 5: add_snprintf(buffer, len, "di" ); break; - case 6: - if( mod == 0 ) { - disp16 = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstring((unsigned) (uint16_t) disp16, 0) ); - } else { - add_snprintf(buffer, len, "bp" ); - } - break; - case 7: add_snprintf(buffer, len, "bx" ); break; - } - if( mod == 1 ) { - disp8 = FETCHD(base_pc, pc, parent); - if (disp8 != 0) - add_snprintf(buffer, len, "%s", shexstring((int32_t)disp8, 0, true) ); - } else if( mod == 2 ) { - disp16 = FETCHD16(base_pc, pc, parent); - if (disp16 != 0) - add_snprintf(buffer, len, "%s", shexstring((int32_t)disp16, 0, true) ); - } - } - add_snprintf(buffer, len, "]" ); -} - -void i386_disassembler::handle_modrm(_TCHAR *buffer, size_t len, offs_t base_pc, offs_t &pc, i386_device* parent) -{ - handle_modrm(buffer, len, base_pc, pc, parent); -} - -void i386_disassembler::handle_param(_TCHAR *buffer, size_t len, uint32_t param, offs_t base_pc, offs_t &pc, i386_device* parent) -{ - uint8_t i8; - uint16_t i16; - uint32_t i32; - uint16_t ptr; - uint32_t addr; - int8_t d8; - int16_t d16; - int32_t d32; - - switch(param) - { - case PARAM_REG: - add_snprintf(buffer, len, "%s", i386_reg[operand_size][MODRM_REG1() | regex] ); - break; - - case PARAM_REG8: - add_snprintf(buffer, len, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1() | regex] ); - break; - - case PARAM_REG16: - add_snprintf(buffer, len, "%s", i386_reg[0][MODRM_REG1() | regex] ); - break; - - case PARAM_REG32: - add_snprintf(buffer, len, "%s", i386_reg[1][MODRM_REG1() | regex] ); - break; - - case PARAM_REG3264: - add_snprintf(buffer, len, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] ); - break; - - case PARAM_MMX: - if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - add_snprintf(buffer, len, "xmm%d", MODRM_REG1() | regex ); - else - add_snprintf(buffer, len, "mm%d", MODRM_REG1() | regex ); - break; - - case PARAM_MMX2: - if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | regex ); - else - add_snprintf(buffer, len, "mm%d", MODRM_REG2() | regex ); - break; - - case PARAM_XMM: - add_snprintf(buffer, len, "xmm%d", MODRM_REG1() | regex ); - break; - - case PARAM_REGORXMM: - if (pre0f != 0xf2 && pre0f != 0xf3) - add_snprintf(buffer, len, "xmm%d", MODRM_REG1() | regex ); - else - add_snprintf(buffer, len, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] ); - break; - - case PARAM_REG2_32: - add_snprintf(buffer, len, "%s", i386_reg[1][MODRM_REG2() | rmex] ); - break; - - case PARAM_RM: - case PARAM_RMPTR: - if( modrm >= 0xc0 ) { - add_snprintf(buffer, len, "%s", i386_reg[operand_size][MODRM_REG2() | rmex] ); - } else { - if (param == PARAM_RMPTR) - { - if( operand_size == 2 ) - add_snprintf(buffer, len, "qword ptr " ); - else if (operand_size == 1) - add_snprintf(buffer, len, "dword ptr " ); - else - add_snprintf(buffer, len, "word ptr " ); - } - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_RM8: - case PARAM_RMPTR8: - if( modrm >= 0xc0 ) { - add_snprintf(buffer, len, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2() | rmex] ); - } else { - if (param == PARAM_RMPTR8) - add_snprintf(buffer, len, "byte ptr " ); - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_RM16: - case PARAM_RMPTR16: - if( modrm >= 0xc0 ) { - add_snprintf(buffer, len, "%s", i386_reg[0][MODRM_REG2() | rmex] ); - } else { - if (param == PARAM_RMPTR16) - add_snprintf(buffer, len, "word ptr " ); - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_RM32: - case PARAM_RMPTR32: - if( modrm >= 0xc0 ) { - add_snprintf(buffer, len, "%s", i386_reg[1][MODRM_REG2() | rmex] ); - } else { - if (param == PARAM_RMPTR32) - add_snprintf(buffer, len, "dword ptr " ); - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_RMXMM: - if( modrm >= 0xc0 ) { - if (pre0f != 0xf2 && pre0f != 0xf3) - add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | rmex ); - else - add_snprintf(buffer, len, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2() | rmex] ); - } else { - if (param == PARAM_RMPTR32) - add_snprintf(buffer, len, "dword ptr " ); - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_M64: - case PARAM_M64PTR: - if( modrm >= 0xc0 ) { - add_snprintf(buffer, len, "???" ); - } else { - if (param == PARAM_M64PTR) - add_snprintf(buffer, len, "qword ptr " ); - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_MMXM: - if( modrm >= 0xc0 ) { - if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | rmex ); - else - add_snprintf(buffer, len, "mm%d", MODRM_REG2() | rmex ); - } else { - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_XMMM: - if( modrm >= 0xc0 ) { - add_snprintf(buffer, len, "xmm%d", MODRM_REG2() | rmex ); - } else { - add_snprintf(buffer, len, "%s", modrm_string ); - } - break; - - case PARAM_I4: - i8 = FETCHD(base_pc, pc, parent); - add_snprintf(buffer, len, "%d", i8 & 0x0f ); - break; - - case PARAM_I8: - i8 = FETCHD(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", shexstring((int8_t)i8, 0, false) ); - break; - - case PARAM_I16: - i16 = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", shexstring((int16_t)i16, 0, false) ); - break; - - case PARAM_UI8: - i8 = FETCHD(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", shexstring((uint8_t)i8, 0, false) ); - break; - - case PARAM_UI16: - i16 = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", shexstring((uint16_t)i16, 0, false) ); - break; - - case PARAM_IMM64: - if (operand_size == 2) { - uint32_t lo32 = FETCHD32(base_pc, pc, parent); - i32 = FETCHD32(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstring64(lo32, i32) ); - } else if( operand_size ) { - i32 = FETCHD32(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstring(i32, 0) ); - } else { - i16 = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstring(i16, 0) ); - } - break; - - case PARAM_IMM: - if( operand_size ) { - i32 = FETCHD32(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstring(i32, 0) ); - } else { - i16 = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstring(i16, 0) ); - } - break; - - case PARAM_ADDR: - if( operand_size ) { - addr = FETCHD32(base_pc, pc, parent); - ptr = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s:", hexstring(ptr, 4) ); - add_snprintf(buffer, len, "%s", hexstring(addr, 0) ); - } else { - addr = FETCHD16(base_pc, pc, parent); - ptr = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s:", hexstring(ptr, 4) ); - add_snprintf(buffer, len, "%s", hexstring(addr, 0) ); - } - break; - - case PARAM_REL: - if( operand_size ) { - d32 = FETCHD32(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstringpc(pc + d32) ); - } else { - /* make sure to keep the relative offset within the segment */ - d16 = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstringpc((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF)) ); - } - break; - - case PARAM_REL8: - d8 = FETCHD(base_pc, pc, parent); - add_snprintf(buffer, len, "%s", hexstringpc(pc + d8) ); - break; - - case PARAM_MEM_OFFS: - switch(segment) - { - case SEG_CS: add_snprintf(buffer, len, "cs:" ); break; - case SEG_DS: add_snprintf(buffer, len, "ds:" ); break; - case SEG_ES: add_snprintf(buffer, len, "es:" ); break; - case SEG_FS: add_snprintf(buffer, len, "fs:" ); break; - case SEG_GS: add_snprintf(buffer, len, "gs:" ); break; - case SEG_SS: add_snprintf(buffer, len, "ss:" ); break; - } - - if( address_size ) { - i32 = FETCHD32(base_pc, pc, parent); - add_snprintf(buffer, len, "[%s]", hexstring(i32, 0) ); - } else { - i16 = FETCHD16(base_pc, pc, parent); - add_snprintf(buffer, len, "[%s]", hexstring(i16, 0) ); - } - break; - - case PARAM_PREIMP: - switch(segment) - { - case SEG_CS: add_snprintf(buffer, len, "cs:" ); break; - case SEG_DS: add_snprintf(buffer, len, "ds:" ); break; - case SEG_ES: add_snprintf(buffer, len, "es:" ); break; - case SEG_FS: add_snprintf(buffer, len, "fs:" ); break; - case SEG_GS: add_snprintf(buffer, len, "gs:" ); break; - case SEG_SS: add_snprintf(buffer, len, "ss:" ); break; - } - break; - - case PARAM_SREG: - add_snprintf(buffer, len, "%s", i386_sreg[MODRM_REG1()] ); - break; - - case PARAM_CREG: - add_snprintf(buffer, len, "cr%d", MODRM_REG1() | regex ); - break; - - case PARAM_TREG: - add_snprintf(buffer, len, "tr%d", MODRM_REG1() | regex ); - break; - - case PARAM_DREG: - add_snprintf(buffer, len, "dr%d", MODRM_REG1() | regex ); - break; - - case PARAM_1: - add_snprintf(buffer, len, "1" ); - break; - - case PARAM_DX: - add_snprintf(buffer, len, "dx" ); - break; - - case PARAM_XMM0: - add_snprintf(buffer, len, "xmm0" ); - break; - - case PARAM_AL: add_snprintf(buffer, len, "al" ); break; - case PARAM_CL: add_snprintf(buffer, len, "cl" ); break; - case PARAM_DL: add_snprintf(buffer, len, "dl" ); break; - case PARAM_BL: add_snprintf(buffer, len, "bl" ); break; - case PARAM_AH: add_snprintf(buffer, len, "ah" ); break; - case PARAM_CH: add_snprintf(buffer, len, "ch" ); break; - case PARAM_DH: add_snprintf(buffer, len, "dh" ); break; - case PARAM_BH: add_snprintf(buffer, len, "bh" ); break; - - case PARAM_EAX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][0 | rmex] ); break; - case PARAM_ECX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][1 | rmex] ); break; - case PARAM_EDX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][2 | rmex] ); break; - case PARAM_EBX: add_snprintf(buffer, len, "%s", i386_reg[operand_size][3 | rmex] ); break; - case PARAM_ESP: add_snprintf(buffer, len, "%s", i386_reg[operand_size][4 | rmex] ); break; - case PARAM_EBP: add_snprintf(buffer, len, "%s", i386_reg[operand_size][5 | rmex] ); break; - case PARAM_ESI: add_snprintf(buffer, len, "%s", i386_reg[operand_size][6 | rmex] ); break; - case PARAM_EDI: add_snprintf(buffer, len, "%s", i386_reg[operand_size][7 | rmex] ); break; - } -} - -void i386_disassembler::handle_fpu(_TCHAR *buffer, size_t len, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, i386_device* parent) -{ - switch (op1 & 0x7) - { - case 0: // Group D8 - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fadd dword ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "fmul dword ptr %s", modrm_string); break; - case 2: add_snprintf(buffer, len, "fcom dword ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "fcomp dword ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "fsub dword ptr %s", modrm_string); break; - case 5: add_snprintf(buffer, len, "fsubr dword ptr %s", modrm_string); break; - case 6: add_snprintf(buffer, len, "fdiv dword ptr %s", modrm_string); break; - case 7: add_snprintf(buffer, len, "fdivr dword ptr %s", modrm_string); break; - } - } - else - { - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fadd st(0),st(%d)", op2 & 0x7); break; - case 1: add_snprintf(buffer, len, "fmul st(0),st(%d)", op2 & 0x7); break; - case 2: add_snprintf(buffer, len, "fcom st(0),st(%d)", op2 & 0x7); break; - case 3: add_snprintf(buffer, len, "fcomp st(0),st(%d)", op2 & 0x7); break; - case 4: add_snprintf(buffer, len, "fsub st(0),st(%d)", op2 & 0x7); break; - case 5: add_snprintf(buffer, len, "fsubr st(0),st(%d)", op2 & 0x7); break; - case 6: add_snprintf(buffer, len, "fdiv st(0),st(%d)", op2 & 0x7); break; - case 7: add_snprintf(buffer, len, "fdivr st(0),st(%d)", op2 & 0x7); break; - } - } - break; - } - - case 1: // Group D9 - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fld dword ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "??? (FPU)"); break; - case 2: add_snprintf(buffer, len, "fst dword ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "fstp dword ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "fldenv word ptr %s", modrm_string); break; - case 5: add_snprintf(buffer, len, "fldcw word ptr %s", modrm_string); break; - case 6: add_snprintf(buffer, len, "fstenv word ptr %s", modrm_string); break; - case 7: add_snprintf(buffer, len, "fstcw word ptr %s", modrm_string); break; - } - } - else - { - switch (op2 & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - add_snprintf(buffer, len, "fld st(0),st(%d)", op2 & 0x7); break; - - case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - add_snprintf(buffer, len, "fxch st(0),st(%d)", op2 & 0x7); break; - - case 0x10: add_snprintf(buffer, len, "fnop"); break; - case 0x20: add_snprintf(buffer, len, "fchs"); break; - case 0x21: add_snprintf(buffer, len, "fabs"); break; - case 0x24: add_snprintf(buffer, len, "ftst"); break; - case 0x25: add_snprintf(buffer, len, "fxam"); break; - case 0x28: add_snprintf(buffer, len, "fld1"); break; - case 0x29: add_snprintf(buffer, len, "fldl2t"); break; - case 0x2a: add_snprintf(buffer, len, "fldl2e"); break; - case 0x2b: add_snprintf(buffer, len, "fldpi"); break; - case 0x2c: add_snprintf(buffer, len, "fldlg2"); break; - case 0x2d: add_snprintf(buffer, len, "fldln2"); break; - case 0x2e: add_snprintf(buffer, len, "fldz"); break; - case 0x30: add_snprintf(buffer, len, "f2xm1"); break; - case 0x31: add_snprintf(buffer, len, "fyl2x"); break; - case 0x32: add_snprintf(buffer, len, "fptan"); break; - case 0x33: add_snprintf(buffer, len, "fpatan"); break; - case 0x34: add_snprintf(buffer, len, "fxtract"); break; - case 0x35: add_snprintf(buffer, len, "fprem1"); break; - case 0x36: add_snprintf(buffer, len, "fdecstp"); break; - case 0x37: add_snprintf(buffer, len, "fincstp"); break; - case 0x38: add_snprintf(buffer, len, "fprem"); break; - case 0x39: add_snprintf(buffer, len, "fyl2xp1"); break; - case 0x3a: add_snprintf(buffer, len, "fsqrt"); break; - case 0x3b: add_snprintf(buffer, len, "fsincos"); break; - case 0x3c: add_snprintf(buffer, len, "frndint"); break; - case 0x3d: add_snprintf(buffer, len, "fscale"); break; - case 0x3e: add_snprintf(buffer, len, "fsin"); break; - case 0x3f: add_snprintf(buffer, len, "fcos"); break; - - default: add_snprintf(buffer, len, "??? (FPU)"); break; - } - } - break; - } - - case 2: // Group DA - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fiadd dword ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "fimul dword ptr %s", modrm_string); break; - case 2: add_snprintf(buffer, len, "ficom dword ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "ficomp dword ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "fisub dword ptr %s", modrm_string); break; - case 5: add_snprintf(buffer, len, "fisubr dword ptr %s", modrm_string); break; - case 6: add_snprintf(buffer, len, "fidiv dword ptr %s", modrm_string); break; - case 7: add_snprintf(buffer, len, "fidivr dword ptr %s", modrm_string); break; - } - } - else - { - switch (op2 & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - add_snprintf(buffer, len, "fcmovb st(0),st(%d)", op2 & 0x7); break; - - case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - add_snprintf(buffer, len, "fcmove st(0),st(%d)", op2 & 0x7); break; - - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - add_snprintf(buffer, len, "fcmovbe st(0),st(%d)", op2 & 0x7); break; - - case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - add_snprintf(buffer, len, "fcmovu st(0),st(%d)", op2 & 0x7); break; - case 0x29: - add_snprintf(buffer, len, "fucompp"); break; - - default: add_snprintf(buffer, len, "??? (FPU)"); break; - - } - } - break; - } - - case 3: // Group DB - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fild dword ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "fisttp dword ptr %s", modrm_string); break; - case 2: add_snprintf(buffer, len, "fist dword ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "fistp dword ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "??? (FPU)"); break; - case 5: add_snprintf(buffer, len, "fld tword ptr %s", modrm_string); break; - case 6: add_snprintf(buffer, len, "??? (FPU)"); break; - case 7: add_snprintf(buffer, len, "fstp tword ptr %s", modrm_string); break; - } - } - else - { - switch (op2 & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - add_snprintf(buffer, len, "fcmovnb st(0),st(%d)", op2 & 0x7); break; - - case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - add_snprintf(buffer, len, "fcmovne st(0),st(%d)", op2 & 0x7); break; - - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - add_snprintf(buffer, len, "fcmovnbe st(0),st(%d)", op2 & 0x7); break; - - case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - add_snprintf(buffer, len, "fcmovnu st(0),st(%d)", op2 & 0x7); break; - - case 0x22: add_snprintf(buffer, len, "fclex"); break; - case 0x23: add_snprintf(buffer, len, "finit"); break; - - case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - add_snprintf(buffer, len, "fucomi st(0),st(%d)", op2 & 0x7); break; - - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - add_snprintf(buffer, len, "fcomi st(0),st(%d)", op2 & 0x7); break; - - default: add_snprintf(buffer, len, "??? (FPU)"); break; - } - } - break; - } - - case 4: // Group DC - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fadd qword ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "fmul qword ptr %s", modrm_string); break; - case 2: add_snprintf(buffer, len, "fcom qword ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "fcomp qword ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "fsub qword ptr %s", modrm_string); break; - case 5: add_snprintf(buffer, len, "fsubr qword ptr %s", modrm_string); break; - case 6: add_snprintf(buffer, len, "fdiv qword ptr %s", modrm_string); break; - case 7: add_snprintf(buffer, len, "fdivr qword ptr %s", modrm_string); break; - } - } - else - { - switch (op2 & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - add_snprintf(buffer, len, "fadd st(%d),st(0)", op2 & 0x7); break; - - case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - add_snprintf(buffer, len, "fmul st(%d),st(0)", op2 & 0x7); break; - - case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: - add_snprintf(buffer, len, "fsubr st(%d),st(0)", op2 & 0x7); break; - - case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - add_snprintf(buffer, len, "fsub st(%d),st(0)", op2 & 0x7); break; - - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - add_snprintf(buffer, len, "fdivr st(%d),st(0)", op2 & 0x7); break; - - case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - add_snprintf(buffer, len, "fdiv st(%d),st(0)", op2 & 0x7); break; - - default: add_snprintf(buffer, len, "??? (FPU)"); break; - } - } - break; - } - - case 5: // Group DD - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fld qword ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "fisttp qword ptr %s", modrm_string); break; - case 2: add_snprintf(buffer, len, "fst qword ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "fstp qword ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "frstor %s", modrm_string); break; - case 5: add_snprintf(buffer, len, "??? (FPU)"); break; - case 6: add_snprintf(buffer, len, "fsave %s", modrm_string); break; - case 7: add_snprintf(buffer, len, "fstsw word ptr %s", modrm_string); break; - } - } - else - { - switch (op2 & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - add_snprintf(buffer, len, "ffree st(%d)", op2 & 0x7); break; - - case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - add_snprintf(buffer, len, "fst st(%d)", op2 & 0x7); break; - - case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - add_snprintf(buffer, len, "fstp st(%d)", op2 & 0x7); break; - - case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: - add_snprintf(buffer, len, "fucom st(%d), st(0)", op2 & 0x7); break; - - case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - add_snprintf(buffer, len, "fucomp st(%d)", op2 & 0x7); break; - - default: add_snprintf(buffer, len, "??? (FPU)"); break; - } - } - break; - } - - case 6: // Group DE - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fiadd word ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "fimul word ptr %s", modrm_string); break; - case 2: add_snprintf(buffer, len, "ficom word ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "ficomp word ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "fisub word ptr %s", modrm_string); break; - case 5: add_snprintf(buffer, len, "fisubr word ptr %s", modrm_string); break; - case 6: add_snprintf(buffer, len, "fidiv word ptr %s", modrm_string); break; - case 7: add_snprintf(buffer, len, "fidivr word ptr %s", modrm_string); break; - } - } - else - { - switch (op2 & 0x3f) - { - case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: - add_snprintf(buffer, len, "faddp st(%d)", op2 & 0x7); break; - - case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - add_snprintf(buffer, len, "fmulp st(%d)", op2 & 0x7); break; - - case 0x19: add_snprintf(buffer, len, "fcompp"); break; - - case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: - add_snprintf(buffer, len, "fsubrp st(%d)", op2 & 0x7); break; - - case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - add_snprintf(buffer, len, "fsubp st(%d)", op2 & 0x7); break; - - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - add_snprintf(buffer, len, "fdivrp st(%d), st(0)", op2 & 0x7); break; - - case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - add_snprintf(buffer, len, "fdivp st(%d)", op2 & 0x7); break; - - default: add_snprintf(buffer, len, "??? (FPU)"); break; - } - } - break; - } - - case 7: // Group DF - { - if (op2 < 0xc0) - { - pc--; // adjust fetch pointer, so modrm byte read again - handle_modrm(modrm_string, base_pc, pc, parent); - switch ((op2 >> 3) & 0x7) - { - case 0: add_snprintf(buffer, len, "fild word ptr %s", modrm_string); break; - case 1: add_snprintf(buffer, len, "fisttp word ptr %s", modrm_string); break; - case 2: add_snprintf(buffer, len, "fist word ptr %s", modrm_string); break; - case 3: add_snprintf(buffer, len, "fistp word ptr %s", modrm_string); break; - case 4: add_snprintf(buffer, len, "fbld %s", modrm_string); break; - case 5: add_snprintf(buffer, len, "fild qword ptr %s", modrm_string); break; - case 6: add_snprintf(buffer, len, "fbstp %s", modrm_string); break; - case 7: add_snprintf(buffer, len, "fistp qword ptr %s", modrm_string); break; - } - } - else - { - switch (op2 & 0x3f) - { - case 0x20: add_snprintf(buffer, len, "fstsw ax"); break; - - case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - add_snprintf(buffer, len, "fucomip st(%d)", op2 & 0x7); break; - - case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - add_snprintf(buffer, len, "fcomip st(%d),st(0)", op2 & 0x7); break; - - default: add_snprintf(buffer, len, "??? (FPU)"); break; - } - } - break; - } - } -} - -void i386_disassembler::decode_opcode(_TCHAR *buffer, size_t len, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, i386_device* parent) -{ - int i; - uint8_t op2; - - if ((op->flags & SPECIAL64) && (address_size == 2)) - op = &x64_opcode_alt[op->flags >> 24]; - - switch( op->flags & FLAGS_MASK ) - { - case ISREX: - if (m_config->get_mode() == 64) - { - rex = op1; - operand_size = (op1 & 8) ? 2 : 1; - regex = (op1 << 1) & 8; - sibex = (op1 << 2) & 8; - rmex = (op1 << 3) & 8; - op2 = FETCH(base_pc, pc, parent); - decode_opcode(buffer, len, &i386_opcode_table1[op2], op1, base_pc, pc, parent); - return; - } - break; - - case OP_SIZE: - rex = regex = sibex = rmex = 0; - if (operand_size < 2 && operand_prefix == 0) - { - operand_size ^= 1; - operand_prefix = 1; - } - op2 = FETCH(base_pc, pc, parent); - decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent); - return; - - case ADDR_SIZE: - rex = regex = sibex = rmex = 0; - if(address_prefix == 0) - { - if (m_config->get_mode() != 64) - address_size ^= 1; - else - address_size ^= 3; - address_prefix = 1; - } - op2 = FETCH(base_pc, pc, parent); - decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent); - return; - - case TWO_BYTE: - if (pc - 2 >= base_pc) - pre0f = parent.r8(pc-2); - op2 = FETCHD(base_pc, pc, parent); - decode_opcode(buffer, len, &i386_opcode_table2[op2], op1, base_pc, pc, parent); - return; - - case THREE_BYTE: - op2 = FETCHD(base_pc, pc, parent); - if (parent.r8(pc-2) == 0x38) - decode_opcode(buffer, len, &i386_opcode_table0F38[op2], op1, base_pc, pc, parent); - else - decode_opcode(buffer, len, &i386_opcode_table0F3A[op2], op1, base_pc, pc, parent); - return; - - case SEG_CS: - case SEG_DS: - case SEG_ES: - case SEG_FS: - case SEG_GS: - case SEG_SS: - rex = regex = sibex = rmex = 0; - segment = op->flags; - op2 = FETCH(base_pc, pc, parent); - decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent); - return; - - case PREFIX: - op2 = FETCH(base_pc, pc, parent); - if ((op2 != 0x0f) && (op2 != 0x90)) - add_snprintf(buffer, len, "%-7s ", op->mnemonic ); - if ((op2 == 0x90) && !pre0f) - pre0f = op1; - decode_opcode(buffer, len, &i386_opcode_table1[op2], op2, base_pc, pc, parent); - dasm_flags |= op->dasm_flags; - return; - - case GROUP: - handle_modrm(modrm_string, base_pc, pc, parent); - for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) { - if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) { - if (op->flags & GROUP_MOD) - decode_opcode(buffer, len, &group_op_table[i].opcode[MODRM_MOD()], op1, base_pc, pc, parent); - else - decode_opcode(buffer, len, &group_op_table[i].opcode[MODRM_REG1()], op1, base_pc, pc, parent); - return; - } - } - goto handle_unknown; - - case FPU: - op2 = FETCHD(base_pc, pc, parent); - handle_fpu(buffer, len, op1, op2, base_pc, pc, parent); - return; - - case MODRM: - handle_modrm(modrm_string, base_pc, pc, parent); - break; - } - - if ((op->flags & ALWAYS64) && m_config->get_mode() == 64) - operand_size = 2; - - if ((op->flags & VAR_NAME) && operand_size > 0) - { - const char *mnemonic = op->mnemonic + strlen(op->mnemonic) + 1; - if (operand_size == 2) - mnemonic += strlen(mnemonic) + 1; - add_snprintf(buffer, len, "%-7s ", mnemonic ); - } - else if (op->flags & VAR_NAME4) - { - const char *mnemonic = op->mnemonic; - int which = (pre0f == 0xf3) ? 3 : (pre0f == 0xf2) ? 2 : (pre0f == 0x66) ? 1 : 0; - while (which--) - mnemonic += strlen(mnemonic) + 1; - add_snprintf(buffer, len, "%-7s ", mnemonic ); - } - else - add_snprintf(buffer, len, "%-7s ", op->mnemonic ); - dasm_flags = op->dasm_flags; - - if( op->param1 != 0 ) { - handle_param(buffer, len, op->param1, base_pc, pc, parent); - } - - if( op->param2 != 0 ) { - add_snprintf(buffer, len, "," ); - handle_param(buffer, len, op->param2, base_pc, pc, parent); - } - - if( op->param3 != 0 ) { - add_snprintf(buffer, len, "," ); - handle_param(buffer, len, op->param3, base_pc, pc, parent); - } - return; - -handle_unknown: - add_snprintf(buffer, len, "???"); -} - -uint32_t i386_disassembler::disassemble(_TCHAR* buffer, size_t len, uint32_t pc, i386_device* parent) -{ - uint32_t base_pc = pc; - uint8_t op; - - switch(m_config->get_mode()) - { - case 1: /* 8086/8088/80186/80188 */ - address_size = 0; - operand_size = 0; - max_length = 8; /* maximum without redundant prefixes - not enforced by chip */ - break; - case 2: /* 80286 */ - address_size = 0; - operand_size = 0; - max_length = 10; - break; - case 16: /* 80386+ 16-bit code segment */ - address_size = 0; - operand_size = 0; - max_length = 15; - break; - case 32: /* 80386+ 32-bit code segment */ - address_size = 1; - operand_size = 1; - max_length = 15; - break; - case 64: /* x86_64 */ - address_size = 2; - operand_size = 1; - max_length = 15; - break; - } - dasm_flags = 0; - segment = 0; - pre0f = 0; - rex = regex = sibex = rmex = 0; - address_prefix = 0; - operand_prefix = 0; - - op = FETCH(base_pc, pc, parent); - - decode_opcode(buffer, len, &i386_opcode_table1[op], op, base_pc, pc, parent); - return (pc-base_pc) | dasm_flags | DASMFLAG_SUPPORTED; -} - -i386_disassembler::i386_disassembler(config *conf) : m_config(conf) -{ -} - -u32 i386_disassembler::opcode_alignment() const -{ - return 1; -} diff --git a/source/src/vm/libcpu_newdev/i386/i386dasm.h b/source/src/vm/libcpu_newdev/i386/i386dasm.h deleted file mode 100644 index fa2210b75..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386dasm.h +++ /dev/null @@ -1,216 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Peter Ferrie - -#ifndef MAME_CPU_I386_I386DASM_H -#define MAME_CPU_I386_I386DASM_H - -#pragma once - -class i386_disassembler : public util::disasm_interface -{ -public: - class config { - public: - virtual ~config() = default; - virtual int get_mode() const = 0; - }; - - i386_disassembler(config *conf); - - virtual u32 opcode_alignment() const override; - virtual offs_t disassemble(uint32_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; - -private: - enum - { - PARAM_REG = 1, /* 16 or 32-bit register */ - PARAM_REG8, /* 8-bit register */ - PARAM_REG16, /* 16-bit register */ - PARAM_REG32, /* 32-bit register */ - PARAM_REG3264, /* 32-bit or 64-bit register */ - PARAM_REG2_32, /* 32-bit register */ - PARAM_MMX, /* MMX register */ - PARAM_MMX2, /* MMX register in modrm */ - PARAM_XMM, /* XMM register */ - PARAM_RM, /* 16 or 32-bit memory or register */ - PARAM_RM8, /* 8-bit memory or register */ - PARAM_RM16, /* 16-bit memory or register */ - PARAM_RM32, /* 32-bit memory or register */ - PARAM_RMPTR, /* 16 or 32-bit memory or register */ - PARAM_RMPTR8, /* 8-bit memory or register */ - PARAM_RMPTR16, /* 16-bit memory or register */ - PARAM_RMPTR32, /* 32-bit memory or register */ - PARAM_RMXMM, /* 32 or 64-bit memory or register */ - PARAM_REGORXMM, /* 32 or 64-bit register or XMM register */ - PARAM_M64, /* 64-bit memory */ - PARAM_M64PTR, /* 64-bit memory */ - PARAM_MMXM, /* 64-bit memory or MMX register */ - PARAM_XMMM, /* 128-bit memory or XMM register */ - PARAM_I4, /* 4-bit signed immediate */ - PARAM_I8, /* 8-bit signed immediate */ - PARAM_I16, /* 16-bit signed immediate */ - PARAM_UI8, /* 8-bit unsigned immediate */ - PARAM_UI16, /* 16-bit unsigned immediate */ - PARAM_IMM, /* 16 or 32-bit immediate */ - PARAM_IMM64, /* 16, 32 or 64-bit immediate */ - PARAM_ADDR, /* 16:16 or 16:32 address */ - PARAM_REL, /* 16 or 32-bit PC-relative displacement */ - PARAM_REL8, /* 8-bit PC-relative displacement */ - PARAM_MEM_OFFS, /* 16 or 32-bit mem offset */ - PARAM_PREIMP, /* prefix with implicit register */ - PARAM_SREG, /* segment register */ - PARAM_CREG, /* control register */ - PARAM_DREG, /* debug register */ - PARAM_TREG, /* test register */ - PARAM_1, /* used by shift/rotate instructions */ - PARAM_AL, - PARAM_CL, - PARAM_DL, - PARAM_BL, - PARAM_AH, - PARAM_CH, - PARAM_DH, - PARAM_BH, - PARAM_DX, - PARAM_EAX, /* EAX or AX */ - PARAM_ECX, /* ECX or CX */ - PARAM_EDX, /* EDX or DX */ - PARAM_EBX, /* EBX or BX */ - PARAM_ESP, /* ESP or SP */ - PARAM_EBP, /* EBP or BP */ - PARAM_ESI, /* ESI or SI */ - PARAM_EDI, /* EDI or DI */ - PARAM_XMM0, - PARAM_XMM64, /* 64-bit memory or XMM register */ - PARAM_XMM32, /* 32-bit memory or XMM register */ - PARAM_XMM16 /* 16-bit memory or XMM register */ - }; - - enum - { - MODRM = 1, - GROUP, - FPU, - OP_SIZE, - ADDR_SIZE, - TWO_BYTE, - PREFIX, - SEG_CS, - SEG_DS, - SEG_ES, - SEG_FS, - SEG_GS, - SEG_SS, - ISREX, - THREE_BYTE /* [prefix] 0f op1 op2 and then mod/rm */ - }; - - enum { - FLAGS_MASK = 0x0ff, - VAR_NAME = 0x100, - VAR_NAME4 = 0x200, - ALWAYS64 = 0x400, - SPECIAL64 = 0x800, - GROUP_MOD = 0x1000 - }; - - struct I386_OPCODE { - const char *mnemonic; - u32 flags; - u32 param1; - u32 param2; - u32 param3; - offs_t dasm_flags; - }; - - struct GROUP_OP { - char mnemonic[32]; - const I386_OPCODE *opcode; - }; - - static constexpr u32 SPECIAL64_ENT(u32 x) { - return SPECIAL64 | (x << 24); - } - - static const I386_OPCODE i386_opcode_table1[256]; - static const I386_OPCODE x64_opcode_alt[]; - static const I386_OPCODE i386_opcode_table2[256]; - static const I386_OPCODE i386_opcode_table0F38[256]; - static const I386_OPCODE i386_opcode_table0F3A[256]; - static const I386_OPCODE group80_table[8]; - static const I386_OPCODE group81_table[8]; - static const I386_OPCODE group83_table[8]; - static const I386_OPCODE groupC0_table[8]; - static const I386_OPCODE groupC1_table[8]; - static const I386_OPCODE groupD0_table[8]; - static const I386_OPCODE groupD1_table[8]; - static const I386_OPCODE groupD2_table[8]; - static const I386_OPCODE groupD3_table[8]; - static const I386_OPCODE groupF6_table[8]; - static const I386_OPCODE groupF7_table[8]; - static const I386_OPCODE groupFE_table[8]; - static const I386_OPCODE groupFF_table[8]; - static const I386_OPCODE group0F00_table[8]; - static const I386_OPCODE group0F01_table[8]; - static const I386_OPCODE group0F0D_table[8]; - static const I386_OPCODE group0F12_table[4]; - static const I386_OPCODE group0F16_table[4]; - static const I386_OPCODE group0F18_table[8]; - static const I386_OPCODE group0F71_table[8]; - static const I386_OPCODE group0F72_table[8]; - static const I386_OPCODE group0F73_table[8]; - static const I386_OPCODE group0FAE_table[8]; - static const I386_OPCODE group0FBA_table[8]; - static const I386_OPCODE group0FC7_table[8]; - static const GROUP_OP group_op_table[]; - static const char *const i386_reg[3][16]; - static const char *const i386_reg8[8]; - static const char *const i386_reg8rex[16]; - static const char *const i386_sreg[8]; - - config *m_config; - - int address_size; - int operand_size; - int address_prefix; - int operand_prefix; - int max_length; - uint8_t modrm; - uint32_t segment; - offs_t dasm_flags; - std::string modrm_string; - uint8_t rex, regex, sibex, rmex; - uint8_t pre0f; - - inline u8 MODRM_REG1() const { - return (modrm >> 3) & 0x7; - } - - inline u8 MODRM_REG2() const { - return modrm & 0x7; - } - - inline u8 MODRM_MOD() const { - return (modrm >> 6) & 0x7; - } - - inline uint8_t FETCH(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - inline uint16_t FETCH16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - inline uint32_t FETCH32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - inline uint8_t FETCHD(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - inline uint16_t FETCHD16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - inline uint32_t FETCHD32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - - char *hexstring(uint32_t value, int digits); - char *hexstring64(uint32_t lo, uint32_t hi); - char *hexstringpc(uint64_t pc); - char *shexstring(uint32_t value, int digits, bool always); - void handle_sib_byte(std::ostream &stream, uint8_t mod, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - void handle_modrm(std::ostream &stream, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - void handle_modrm(std::string &buffer, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - void handle_param(std::ostream &stream, uint32_t param, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); - void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); -}; - -#endif diff --git a/source/src/vm/libcpu_newdev/i386/i386op16.hxx b/source/src/vm/libcpu_newdev/i386/i386op16.hxx deleted file mode 100644 index 83a41acce..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386op16.hxx +++ /dev/null @@ -1,3798 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -uint16_t i386_device::i386_shift_rotate16(uint8_t modrm, uint32_t value, uint8_t shift) -{ - uint32_t src = value & 0xffff; - uint16_t dst = value; - - if( shift == 0 ) { - CYCLES_RM(modrm, 3, 7); - } else if( shift == 1 ) { - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* ROL rm16, 1 */ - m_CF = (src & 0x8000) ? 1 : 0; - dst = (src << 1) + m_CF; - m_OF = ((src ^ dst) & 0x8000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 1: /* ROR rm16, 1 */ - m_CF = (src & 0x1) ? 1 : 0; - dst = (m_CF << 15) | (src >> 1); - m_OF = ((src ^ dst) & 0x8000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 2: /* RCL rm16, 1 */ - dst = (src << 1) + m_CF; - m_CF = (src & 0x8000) ? 1 : 0; - m_OF = ((src ^ dst) & 0x8000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 3: /* RCR rm16, 1 */ - dst = (m_CF << 15) | (src >> 1); - m_CF = src & 0x1; - m_OF = ((src ^ dst) & 0x8000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 4: /* SHL/SAL rm16, 1 */ - case 6: - dst = src << 1; - m_CF = (src & 0x8000) ? 1 : 0; - m_OF = (((m_CF << 15) ^ dst) & 0x8000) ? 1 : 0; - SetSZPF16(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 5: /* SHR rm16, 1 */ - dst = src >> 1; - m_CF = src & 0x1; - m_OF = (dst & 0x8000) ? 1 : 0; - SetSZPF16(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 7: /* SAR rm16, 1 */ - dst = (int16_t)(src) >> 1; - m_CF = src & 0x1; - m_OF = 0; - SetSZPF16(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - } - } else { - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* ROL rm16, i8 */ - if(!(shift & 15)) - { - if(shift & 16) - { - m_CF = src & 1; - m_OF = (src & 1) ^ ((src >> 15) & 1); - } - break; - } - shift &= 15; - dst = ((src & ((uint16_t)0xffff >> shift)) << shift) | - ((src & ((uint16_t)0xffff << (16-shift))) >> (16-shift)); - m_CF = dst & 0x1; - m_OF = (dst & 1) ^ (dst >> 15); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 1: /* ROR rm16, i8 */ - if(!(shift & 15)) - { - if(shift & 16) - { - m_CF = (src >> 15) & 1; - m_OF = ((src >> 15) & 1) ^ ((src >> 14) & 1); - } - break; - } - shift &= 15; - dst = ((src & ((uint16_t)0xffff << shift)) >> shift) | - ((src & ((uint16_t)0xffff >> (16-shift))) << (16-shift)); - m_CF = (dst >> 15) & 1; - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 2: /* RCL rm16, i8 */ - shift %= 17; - dst = ((src & ((uint16_t)0xffff >> shift)) << shift) | - ((src & ((uint16_t)0xffff << (17-shift))) >> (17-shift)) | - (m_CF << (shift-1)); - if(shift) m_CF = (src >> (16-shift)) & 0x1; - m_OF = m_CF ^ ((dst >> 15) & 1); - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 3: /* RCR rm16, i8 */ - shift %= 17; - dst = ((src & ((uint16_t)0xffff << shift)) >> shift) | - ((src & ((uint16_t)0xffff >> (16-shift))) << (17-shift)) | - (m_CF << (16-shift)); - if(shift) m_CF = (src >> (shift-1)) & 0x1; - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 4: /* SHL/SAL rm16, i8 */ - case 6: - shift &= 31; - dst = src << shift; - m_CF = (shift <= 16) && (src & (1 << (16-shift))); - SetSZPF16(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 5: /* SHR rm16, i8 */ - shift &= 31; - dst = src >> shift; - m_CF = (src & (1 << (shift-1))) ? 1 : 0; - SetSZPF16(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 7: /* SAR rm16, i8 */ - shift &= 31; - dst = (int16_t)src >> shift; - m_CF = (src & (1 << (shift-1))) ? 1 : 0; - SetSZPF16(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - } - - } - return dst; -} - - - -void i386_device::i386_adc_rm16_r16() // Opcode 0x11 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = ADC16(dst, src, m_CF); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = ADC16(dst, src, m_CF); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_adc_r16_rm16() // Opcode 0x13 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - dst = ADC16(dst, src, m_CF); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - dst = ADC16(dst, src, m_CF); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_adc_ax_i16() // Opcode 0x15 -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - dst = ADC16(dst, src, m_CF); - REG16(AX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_add_rm16_r16() // Opcode 0x01 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = ADD16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = ADD16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_add_r16_rm16() // Opcode 0x03 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - dst = ADD16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - dst = ADD16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_add_ax_i16() // Opcode 0x05 -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - dst = ADD16(dst, src); - REG16(AX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_and_rm16_r16() // Opcode 0x21 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = AND16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = AND16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_and_r16_rm16() // Opcode 0x23 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - dst = AND16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - dst = AND16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_and_ax_i16() // Opcode 0x25 -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - dst = AND16(dst, src); - REG16(AX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_bsf_r16_rm16() // Opcode 0x0f bc -{ - uint16_t src, dst, temp; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - } - - dst = 0; - - if( src == 0 ) { - m_ZF = 1; - } else { - m_ZF = 0; - temp = 0; - while( (src & (1 << temp)) == 0 ) { - temp++; - dst = temp; - CYCLES(CYCLES_BSF); - } - STORE_REG16(modrm, dst); - } - CYCLES(CYCLES_BSF_BASE); -} - -void i386_device::i386_bsr_r16_rm16() // Opcode 0x0f bd -{ - uint16_t src, dst, temp; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - } - - dst = 0; - - if( src == 0 ) { - m_ZF = 1; - } else { - m_ZF = 0; - dst = temp = 15; - while( (src & (1 << temp)) == 0 ) { - temp--; - dst = temp; - CYCLES(CYCLES_BSR); - } - STORE_REG16(modrm, dst); - } - CYCLES(CYCLES_BSR_BASE); -} - - -void i386_device::i386_bt_rm16_r16() // Opcode 0x0f a3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t bit = LOAD_REG16(modrm); - - if( dst & (1 << (bit & 0xf)) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint16_t bit = LOAD_REG16(modrm); - ea += 2*(bit/16); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),0); - bit %= 16; - uint16_t dst = READ16(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_REG_MEM); - } -} - -void i386_device::i386_btc_rm16_r16() // Opcode 0x0f bb -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t bit = LOAD_REG16(modrm); - - if( dst & (1 << (bit & 0xf)) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << (bit & 0xf)); - - STORE_RM16(modrm, dst); - CYCLES(CYCLES_BTC_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint16_t bit = LOAD_REG16(modrm); - ea += 2*(bit/16); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1); - bit %= 16; - uint16_t dst = READ16(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << bit); - - WRITE16(ea, dst); - CYCLES(CYCLES_BTC_REG_MEM); - } -} - -void i386_device::i386_btr_rm16_r16() // Opcode 0x0f b3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t bit = LOAD_REG16(modrm); - - if( dst & (1 << (bit & 0xf)) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << (bit & 0xf)); - - STORE_RM16(modrm, dst); - CYCLES(CYCLES_BTR_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint16_t bit = LOAD_REG16(modrm); - ea += 2*(bit/16); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1); - bit %= 16; - uint16_t dst = READ16(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << bit); - - WRITE16(ea, dst); - CYCLES(CYCLES_BTR_REG_MEM); - } -} - -void i386_device::i386_bts_rm16_r16() // Opcode 0x0f ab -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t bit = LOAD_REG16(modrm); - - if( dst & (1 << (bit & 0xf)) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << (bit & 0xf)); - - STORE_RM16(modrm, dst); - CYCLES(CYCLES_BTS_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint16_t bit = LOAD_REG16(modrm); - ea += 2*(bit/16); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1); - bit %= 16; - uint16_t dst = READ16(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << bit); - - WRITE16(ea, dst); - CYCLES(CYCLES_BTS_REG_MEM); - } -} - -void i386_device::i386_call_abs16() // Opcode 0x9a -{ - uint16_t offset = FETCH16(); - uint16_t ptr = FETCH16(); - - if( PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_call(ptr,offset,0,0); - } - else - { - PUSH16(m_sreg[CS].selector ); - PUSH16(m_eip ); - m_sreg[CS].selector = ptr; - m_performed_intersegment_jump = 1; - m_eip = offset; - i386_load_segment_descriptor(CS); - //uint8_t IOPL = (m_IOP1 & 1) | ((m_IOP2 & 1) << 1); - if(bios_call_far_x86(( (((uint32_t)ptr) << 4) + ((uint32_t)offset)) & m_a20_mask)) { - m_eip = POP16(); - m_sreg[CS].selector = POP16(); - i386_load_segment_descriptor(CS); - CYCLES(CYCLES_CALL_INTERSEG + CYCLES_RET_INTERSEG); /* TODO: Timing = 17 + m */ - return; - } - } - CYCLES(CYCLES_CALL_INTERSEG); /* TODO: Timing = 17 + m */ - CHANGE_PC(m_eip); -} - -void i386_device::i386_call_rel16() // Opcode 0xe8 -{ - int16_t disp = FETCH16(); - - PUSH16(m_eip ); - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_CALL); /* TODO: Timing = 7 + m */ -} - -void i386_device::i386_cbw() // Opcode 0x98 -{ - REG16(AX) = (int16_t)((int8_t)REG8(AL)); - CYCLES(CYCLES_CBW); -} - -void i386_device::i386_cmp_rm16_r16() // Opcode 0x39 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - SUB16(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = LOAD_REG16(modrm); - dst = READ16(ea); - SUB16(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } -} - -void i386_device::i386_cmp_r16_rm16() // Opcode 0x3b -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - SUB16(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - SUB16(dst, src); - CYCLES(CYCLES_CMP_MEM_REG); - } -} - -void i386_device::i386_cmp_ax_i16() // Opcode 0x3d -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - SUB16(dst, src); - CYCLES(CYCLES_CMP_IMM_ACC); -} - -void i386_device::i386_cmpsw() // Opcode 0xa7 -{ - uint32_t eas, ead; - uint16_t src, dst; - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 ); - src = READ16(eas); - dst = READ16(ead); - SUB16(src,dst); - BUMP_SI(2); - BUMP_DI(2); - CYCLES(CYCLES_CMPS); -} - -void i386_device::i386_cwd() // Opcode 0x99 -{ - if( REG16(AX) & 0x8000 ) { - REG16(DX) = 0xffff; - } else { - REG16(DX) = 0x0000; - } - CYCLES(CYCLES_CWD); -} - -void i386_device::i386_dec_ax() // Opcode 0x48 -{ - REG16(AX) = DEC16(REG16(AX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_cx() // Opcode 0x49 -{ - REG16(CX) = DEC16(REG16(CX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_dx() // Opcode 0x4a -{ - REG16(DX) = DEC16(REG16(DX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_bx() // Opcode 0x4b -{ - REG16(BX) = DEC16(REG16(BX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_sp() // Opcode 0x4c -{ - REG16(SP) = DEC16(REG16(SP) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_bp() // Opcode 0x4d -{ - REG16(BP) = DEC16(REG16(BP) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_si() // Opcode 0x4e -{ - REG16(SI) = DEC16(REG16(SI) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_di() // Opcode 0x4f -{ - REG16(DI) = DEC16(REG16(DI) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_imul_r16_rm16() // Opcode 0x0f af -{ - uint8_t modrm = FETCH(); - int32_t result; - int32_t src, dst; - if( modrm >= 0xc0 ) { - src = (int32_t)(int16_t)LOAD_RM16(modrm); - CYCLES(CYCLES_IMUL16_REG_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = (int32_t)(int16_t)READ16(ea); - CYCLES(CYCLES_IMUL16_REG_MEM); /* TODO: Correct multiply timing */ - } - - dst = (int32_t)(int16_t)LOAD_REG16(modrm); - result = src * dst; - - STORE_REG16(modrm, (uint16_t)result); - - m_CF = m_OF = !(result == (int32_t)(int16_t)result); -} - -void i386_device::i386_imul_r16_rm16_i16() // Opcode 0x69 -{ - uint8_t modrm = FETCH(); - int32_t result; - int32_t src, dst; - if( modrm >= 0xc0 ) { - dst = (int32_t)(int16_t)LOAD_RM16(modrm); - CYCLES(CYCLES_IMUL16_REG_IMM_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - dst = (int32_t)(int16_t)READ16(ea); - CYCLES(CYCLES_IMUL16_MEM_IMM_REG); /* TODO: Correct multiply timing */ - } - - src = (int32_t)(int16_t)FETCH16(); - result = src * dst; - - STORE_REG16(modrm, (uint16_t)result); - - m_CF = m_OF = !(result == (int32_t)(int16_t)result); -} - -void i386_device::i386_imul_r16_rm16_i8() // Opcode 0x6b -{ - uint8_t modrm = FETCH(); - int32_t result; - int32_t src, dst; - if( modrm >= 0xc0 ) { - dst = (int32_t)(int16_t)LOAD_RM16(modrm); - CYCLES(CYCLES_IMUL16_REG_IMM_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - dst = (int32_t)(int16_t)READ16(ea); - CYCLES(CYCLES_IMUL16_MEM_IMM_REG); /* TODO: Correct multiply timing */ - } - - src = (int32_t)(int8_t)FETCH(); - result = src * dst; - - STORE_REG16(modrm, (uint16_t)result); - - m_CF = m_OF = !(result == (int32_t)(int16_t)result); -} - -void i386_device::i386_in_ax_i8() // Opcode 0xe5 -{ - uint16_t port = FETCH(); - uint16_t data = READPORT16(port); - REG16(AX) = data; - CYCLES(CYCLES_IN_VAR); -} - -void i386_device::i386_in_ax_dx() // Opcode 0xed -{ - uint16_t port = REG16(DX); - uint16_t data = READPORT16(port); - REG16(AX) = data; - CYCLES(CYCLES_IN); -} - -void i386_device::i386_inc_ax() // Opcode 0x40 -{ - REG16(AX) = INC16(REG16(AX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_cx() // Opcode 0x41 -{ - REG16(CX) = INC16(REG16(CX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_dx() // Opcode 0x42 -{ - REG16(DX) = INC16(REG16(DX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_bx() // Opcode 0x43 -{ - REG16(BX) = INC16(REG16(BX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_sp() // Opcode 0x44 -{ - REG16(SP) = INC16(REG16(SP) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_bp() // Opcode 0x45 -{ - REG16(BP) = INC16(REG16(BP) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_si() // Opcode 0x46 -{ - REG16(SI) = INC16(REG16(SI) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_di() // Opcode 0x47 -{ - REG16(DI) = INC16(REG16(DI) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_iret16() // Opcode 0xcf -{ - if( PROTECTED_MODE ) - { - i386_protected_mode_iret(0); - } - else - { - /* TODO: #SS(0) exception */ - /* TODO: #GP(0) exception */ - m_eip = POP16(); - m_sreg[CS].selector = POP16(); - set_flags(POP16() ); - i386_load_segment_descriptor(CS); - CHANGE_PC(m_eip); - } - CYCLES(CYCLES_IRET); -} - -void i386_device::i386_ja_rel16() // Opcode 0x0f 87 -{ - int16_t disp = FETCH16(); - if( m_CF == 0 && m_ZF == 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jbe_rel16() // Opcode 0x0f 86 -{ - int16_t disp = FETCH16(); - if( m_CF != 0 || m_ZF != 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jc_rel16() // Opcode 0x0f 82 -{ - int16_t disp = FETCH16(); - if( m_CF != 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jg_rel16() // Opcode 0x0f 8f -{ - int16_t disp = FETCH16(); - if( m_ZF == 0 && (m_SF == m_OF) ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jge_rel16() // Opcode 0x0f 8d -{ - int16_t disp = FETCH16(); - if(m_SF == m_OF) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jl_rel16() // Opcode 0x0f 8c -{ - int16_t disp = FETCH16(); - if( (m_SF != m_OF) ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jle_rel16() // Opcode 0x0f 8e -{ - int16_t disp = FETCH16(); - if( m_ZF != 0 || (m_SF != m_OF) ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jnc_rel16() // Opcode 0x0f 83 -{ - int16_t disp = FETCH16(); - if( m_CF == 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jno_rel16() // Opcode 0x0f 81 -{ - int16_t disp = FETCH16(); - if( m_OF == 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jnp_rel16() // Opcode 0x0f 8b -{ - int16_t disp = FETCH16(); - if( m_PF == 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jns_rel16() // Opcode 0x0f 89 -{ - int16_t disp = FETCH16(); - if( m_SF == 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jnz_rel16() // Opcode 0x0f 85 -{ - int16_t disp = FETCH16(); - if( m_ZF == 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jo_rel16() // Opcode 0x0f 80 -{ - int16_t disp = FETCH16(); - if( m_OF != 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jp_rel16() // Opcode 0x0f 8a -{ - int16_t disp = FETCH16(); - if( m_PF != 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_js_rel16() // Opcode 0x0f 88 -{ - int16_t disp = FETCH16(); - if( m_SF != 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jz_rel16() // Opcode 0x0f 84 -{ - int16_t disp = FETCH16(); - if( m_ZF != 0 ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jcxz16() // Opcode 0xe3 -{ - int8_t disp = FETCH(); - int val = (m_address_size)?(REG32(ECX) == 0):(REG16(CX) == 0); - if( val ) { - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCXZ); /* TODO: Timing = 9 + m */ - } else { - CYCLES(CYCLES_JCXZ_NOBRANCH); - } -} - -void i386_device::i386_jmp_rel16() // Opcode 0xe9 -{ - int16_t disp = FETCH16(); - - if (m_sreg[CS].d) - { - m_eip += disp; - } - else - { - m_eip = (m_eip + disp) & 0xffff; - } - CHANGE_PC(m_eip); - CYCLES(CYCLES_JMP); /* TODO: Timing = 7 + m */ -} - -void i386_device::i386_jmp_abs16() // Opcode 0xea -{ - uint16_t address = FETCH16(); - uint16_t segment = FETCH16(); - - if( PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_jump(segment,address,0,0); - } - else - { - m_eip = address; - m_sreg[CS].selector = segment; - m_performed_intersegment_jump = 1; - i386_load_segment_descriptor(CS); - CHANGE_PC(m_eip); - } - CYCLES(CYCLES_JMP_INTERSEG); -} - -void i386_device::i386_lea16() // Opcode 0x8d -{ - uint8_t modrm = FETCH(); - uint32_t ea = GetNonTranslatedEA(modrm,nullptr); - STORE_REG16(modrm, ea); - CYCLES(CYCLES_LEA); -} - -void i386_device::i386_enter16() // Opcode 0xc8 -{ - uint16_t framesize = FETCH16(); - uint8_t level = FETCH() % 32; - uint8_t x; - uint16_t frameptr; - PUSH16(REG16(BP)); - - if(!STACK_32BIT) - frameptr = REG16(SP); - else - frameptr = REG32(ESP); - - if(level > 0) - { - for(x=1;x= 0xc0 ) { - src = LOAD_REG16(modrm); - STORE_RM16(modrm, src); - CYCLES(CYCLES_MOV_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - WRITE16(ea, src); - CYCLES(CYCLES_MOV_REG_MEM); - } -} - -void i386_device::i386_mov_r16_rm16() // Opcode 0x8b -{ - uint16_t src; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - CYCLES(CYCLES_MOV_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - STORE_REG16(modrm, src); - CYCLES(CYCLES_MOV_MEM_REG); - } -} - -void i386_device::i386_mov_rm16_i16() // Opcode 0xc7 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t value = FETCH16(); - STORE_RM16(modrm, value); - CYCLES(CYCLES_MOV_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t value = FETCH16(); - WRITE16(ea, value); - CYCLES(CYCLES_MOV_IMM_MEM); - } -} - -void i386_device::i386_mov_ax_m16() // Opcode 0xa1 -{ - uint32_t offset, ea; - if( m_address_size ) { - offset = FETCH32(); - } else { - offset = FETCH16(); - } - /* TODO: Not sure if this is correct... */ - if( m_segment_prefix ) { - ea = i386_translate(m_segment_override, offset, 0 ); - } else { - ea = i386_translate(DS, offset, 0 ); - } - REG16(AX) = READ16(ea); - CYCLES(CYCLES_MOV_MEM_ACC); -} - -void i386_device::i386_mov_m16_ax() // Opcode 0xa3 -{ - uint32_t offset, ea; - if( m_address_size ) { - offset = FETCH32(); - } else { - offset = FETCH16(); - } - /* TODO: Not sure if this is correct... */ - if( m_segment_prefix ) { - ea = i386_translate(m_segment_override, offset, 1 ); - } else { - ea = i386_translate(DS, offset, 1 ); - } - WRITE16(ea, REG16(AX) ); - CYCLES(CYCLES_MOV_ACC_MEM); -} - -void i386_device::i386_mov_ax_i16() // Opcode 0xb8 -{ - REG16(AX) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_cx_i16() // Opcode 0xb9 -{ - REG16(CX) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_dx_i16() // Opcode 0xba -{ - REG16(DX) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_bx_i16() // Opcode 0xbb -{ - REG16(BX) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_sp_i16() // Opcode 0xbc -{ - REG16(SP) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_bp_i16() // Opcode 0xbd -{ - REG16(BP) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_si_i16() // Opcode 0xbe -{ - REG16(SI) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_di_i16() // Opcode 0xbf -{ - REG16(DI) = FETCH16(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_movsw() // Opcode 0xa5 -{ - uint32_t eas, ead; - uint16_t v; - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 ); - v = READ16(eas); - WRITE16(ead, v); - BUMP_SI(2); - BUMP_DI(2); - CYCLES(CYCLES_MOVS); -} - -void i386_device::i386_movsx_r16_rm8() // Opcode 0x0f be -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int16_t src = (int8_t)LOAD_RM8(modrm); - STORE_REG16(modrm, src); - CYCLES(CYCLES_MOVSX_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - int16_t src = (int8_t)READ8(ea); - STORE_REG16(modrm, src); - CYCLES(CYCLES_MOVSX_MEM_REG); - } -} - -void i386_device::i386_movzx_r16_rm8() // Opcode 0x0f b6 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t src = (uint8_t)LOAD_RM8(modrm); - STORE_REG16(modrm, src); - CYCLES(CYCLES_MOVZX_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint16_t src = (uint8_t)READ8(ea); - STORE_REG16(modrm, src); - CYCLES(CYCLES_MOVZX_MEM_REG); - } -} - -void i386_device::i386_or_rm16_r16() // Opcode 0x09 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = OR16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = OR16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_or_r16_rm16() // Opcode 0x0b -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - dst = OR16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - dst = OR16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_or_ax_i16() // Opcode 0x0d -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - dst = OR16(dst, src); - REG16(AX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_out_ax_i8() // Opcode 0xe7 -{ - uint16_t port = FETCH(); - uint16_t data = REG16(AX); - WRITEPORT16(port, data); - CYCLES(CYCLES_OUT_VAR); -} - -void i386_device::i386_out_ax_dx() // Opcode 0xef -{ - uint16_t port = REG16(DX); - uint16_t data = REG16(AX); - WRITEPORT16(port, data); - CYCLES(CYCLES_OUT); -} - -void i386_device::i386_pop_ax() // Opcode 0x58 -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(AX) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_cx() // Opcode 0x59 -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(CX) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_dx() // Opcode 0x5a -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(DX) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_bx() // Opcode 0x5b -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(BX) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_sp() // Opcode 0x5c -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(SP) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_bp() // Opcode 0x5d -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(BP) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_si() // Opcode 0x5e -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(SI) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_di() // Opcode 0x5f -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+1) == 0) - REG16(DI) = POP16(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -bool i386_device::i386_pop_seg16(int segment) -{ - uint32_t ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - uint16_t value; - bool fault; - if(i386_limit_check(SS,offset+1) == 0) - { - ea = i386_translate(SS, offset, 0); - value = READ16(ea); - i386_sreg_load(value, segment, &fault); - if(fault) return false; - if(STACK_32BIT) - REG32(ESP) = offset + 2; - else - REG16(SP) = offset + 2; - } - else - { - m_ext = 1; - i386_trap_with_error(FAULT_SS,0,0,0); - return false; - } - CYCLES(CYCLES_POP_SREG); - return true; -} - -void i386_device::i386_pop_ds16() // Opcode 0x1f -{ - i386_pop_seg16(DS); -} - -void i386_device::i386_pop_es16() // Opcode 0x07 -{ - i386_pop_seg16(ES); -} - -void i386_device::i386_pop_fs16() // Opcode 0x0f a1 -{ - i386_pop_seg16(FS); -} - -void i386_device::i386_pop_gs16() // Opcode 0x0f a9 -{ - i386_pop_seg16(GS); -} - -void i386_device::i386_pop_ss16() // Opcode 0x17 -{ - if(!i386_pop_seg16(SS)) return; - if(m_IF != 0) // if external interrupts are enabled - { - m_IF = 0; // reset IF for the next instruction - m_delayed_interrupt_enable = 1; - } -} - -void i386_device::i386_pop_rm16() // Opcode 0x8f -{ - uint8_t modrm = FETCH(); - uint16_t value; - uint32_t ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - - if(i386_limit_check(SS,offset+1) == 0) - { - uint32_t temp_sp = REG32(ESP); - value = POP16(); - - if( modrm >= 0xc0 ) { - STORE_RM16(modrm, value); - } else { - try - { - ea = GetEA(modrm,1); - WRITE16(ea, value); - } - catch(uint64_t e) - { - REG32(ESP) = temp_sp; - throw e; - } - } - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_RM); -} - -void i386_device::i386_popa() // Opcode 0x61 -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - - if(i386_limit_check(SS,offset+15) == 0) - { - REG16(DI) = POP16(); - REG16(SI) = POP16(); - REG16(BP) = POP16(); - REG16(SP) += 2; - REG16(BX) = POP16(); - REG16(DX) = POP16(); - REG16(CX) = POP16(); - REG16(AX) = POP16(); - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POPA); -} - -void i386_device::i386_popf() // Opcode 0x9d -{ - uint32_t value; - uint32_t current = get_flags(); - uint8_t IOPL = (current >> 12) & 0x03; - uint32_t mask = 0x7fd5; - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - - // IOPL can only change if CPL is 0 - if(m_CPL != 0) - mask &= ~0x00003000; - - // IF can only change if CPL is at least as privileged as IOPL - if(m_CPL > IOPL) - mask &= ~0x00000200; - - if(V8086_MODE) - { - if(IOPL < 3) - { - logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",m_pc); - FAULT(FAULT_GP,0) // #GP(0) - } - mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode - } - - if(i386_limit_check(SS,offset+1) == 0) - { - value = POP16(); - set_flags((current & ~mask) | (value & mask)); // mask out reserved bits - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POPF); -} - -void i386_device::i386_push_ax() // Opcode 0x50 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(AX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_cx() // Opcode 0x51 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(CX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_dx() // Opcode 0x52 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(DX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_bx() // Opcode 0x53 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(BX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_sp() // Opcode 0x54 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(SP) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_bp() // Opcode 0x55 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(BP) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_si() // Opcode 0x56 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(SI) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_di() // Opcode 0x57 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(REG16(DI) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_cs16() // Opcode 0x0e -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(m_sreg[CS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_ds16() // Opcode 0x1e -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(m_sreg[DS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_es16() // Opcode 0x06 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(m_sreg[ES].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_fs16() // Opcode 0x0f a0 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(m_sreg[FS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_gs16() // Opcode 0x0f a8 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(m_sreg[GS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_ss16() // Opcode 0x16 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(m_sreg[SS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_i16() // Opcode 0x68 -{ - uint16_t value = FETCH16(); - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(value); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_IMM); -} - -void i386_device::i386_pusha() // Opcode 0x60 -{ - uint16_t temp = REG16(SP); - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 16; - else - offset = (REG16(SP) - 16) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - { - PUSH16(REG16(AX) ); - PUSH16(REG16(CX) ); - PUSH16(REG16(DX) ); - PUSH16(REG16(BX) ); - PUSH16(temp ); - PUSH16(REG16(BP) ); - PUSH16(REG16(SI) ); - PUSH16(REG16(DI) ); - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSHA); -} - -void i386_device::i386_pushf() // Opcode 0x9c -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 2; - else - offset = (REG16(SP) - 2) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH16(get_flags() & 0xffff ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSHF); -} - -void i386_device::i386_ret_near16_i16() // Opcode 0xc2 -{ - int16_t disp = FETCH16(); - m_eip = POP16(); - REG16(SP) += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_RET_IMM); /* TODO: Timing = 10 + m */ -} - -void i386_device::i386_ret_near16() // Opcode 0xc3 -{ - m_eip = POP16(); - CHANGE_PC(m_eip); - CYCLES(CYCLES_RET); /* TODO: Timing = 10 + m */ -} - -void i386_device::i386_sbb_rm16_r16() // Opcode 0x19 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = SBB16(dst, src, m_CF); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = SBB16(dst, src, m_CF); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_sbb_r16_rm16() // Opcode 0x1b -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - dst = SBB16(dst, src, m_CF); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - dst = SBB16(dst, src, m_CF); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_sbb_ax_i16() // Opcode 0x1d -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - dst = SBB16(dst, src, m_CF); - REG16(AX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_scasw() // Opcode 0xaf -{ - uint32_t eas; - uint16_t src, dst; - eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 ); - src = READ16(eas); - dst = REG16(AX); - SUB16(dst, src); - BUMP_DI(2); - CYCLES(CYCLES_SCAS); -} - -void i386_device::i386_shld16_i8() // Opcode 0x0f a4 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0 ) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (16-shift))) ? 1 : 0; - // ppro and above should be (dst >> (32-shift)) - dst = (upper << (shift-16)) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (16-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (16-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } - STORE_RM16(modrm, dst); - CYCLES(CYCLES_SHLD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0 ) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (16-shift))) ? 1 : 0; - dst = (upper << (shift-16)) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (16-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (16-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } - WRITE16(ea, dst); - CYCLES(CYCLES_SHLD_MEM); - } -} - -void i386_device::i386_shld16_cl() // Opcode 0x0f a5 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0 ) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (16-shift))) ? 1 : 0; - dst = (upper << (shift-16)) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (16-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (16-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } - STORE_RM16(modrm, dst); - CYCLES(CYCLES_SHLD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0 ) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (16-shift))) ? 1 : 0; - dst = (upper << (shift-16)) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (16-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (16-shift)); - m_OF = m_CF ^ (dst >> 15); - SetSZPF16(dst); - } - WRITE16(ea, dst); - CYCLES(CYCLES_SHLD_MEM); - } -} - -void i386_device::i386_shrd16_i8() // Opcode 0x0f ac -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (shift-1))) ? 1 : 0; - dst = (upper >> (shift-16)) | (upper << (32-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (16-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } - STORE_RM16(modrm, dst); - CYCLES(CYCLES_SHRD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (shift-1))) ? 1 : 0; - dst = (upper >> (shift-16)) | (upper << (32-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (16-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } - WRITE16(ea, dst); - CYCLES(CYCLES_SHRD_MEM); - } -} - -void i386_device::i386_shrd16_cl() // Opcode 0x0f ad -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (shift-1))) ? 1 : 0; - dst = (upper >> (shift-16)) | (upper << (32-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (16-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } - STORE_RM16(modrm, dst); - CYCLES(CYCLES_SHRD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint16_t upper = LOAD_REG16(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0) { - } else if( shift > 15 ) { - m_CF = (upper & (1 << (shift-1))) ? 1 : 0; - dst = (upper >> (shift-16)) | (upper << (32-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (16-shift)); - m_OF = ((dst >> 15) ^ (dst >> 14)) & 1; - SetSZPF16(dst); - } - WRITE16(ea, dst); - CYCLES(CYCLES_SHRD_MEM); - } -} - -void i386_device::i386_stosw() // Opcode 0xab -{ - uint32_t ead; - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 ); - WRITE16(ead, REG16(AX)); - BUMP_DI(2); - CYCLES(CYCLES_STOS); -} - -void i386_device::i386_sub_rm16_r16() // Opcode 0x29 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = SUB16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = SUB16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_sub_r16_rm16() // Opcode 0x2b -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - dst = SUB16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - dst = SUB16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_sub_ax_i16() // Opcode 0x2d -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - dst = SUB16(dst, src); - REG16(AX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_test_ax_i16() // Opcode 0xa9 -{ - uint16_t src = FETCH16(); - uint16_t dst = REG16(AX); - dst = src & dst; - SetSZPF16(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_IMM_ACC); -} - -void i386_device::i386_test_rm16_r16() // Opcode 0x85 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = src & dst; - SetSZPF16(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = src & dst; - SetSZPF16(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_REG_MEM); - } -} - -void i386_device::i386_xchg_ax_cx() // Opcode 0x91 -{ - uint16_t temp; - temp = REG16(AX); - REG16(AX) = REG16(CX); - REG16(CX) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_ax_dx() // Opcode 0x92 -{ - uint16_t temp; - temp = REG16(AX); - REG16(AX) = REG16(DX); - REG16(DX) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_ax_bx() // Opcode 0x93 -{ - uint16_t temp; - temp = REG16(AX); - REG16(AX) = REG16(BX); - REG16(BX) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_ax_sp() // Opcode 0x94 -{ - uint16_t temp; - temp = REG16(AX); - REG16(AX) = REG16(SP); - REG16(SP) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_ax_bp() // Opcode 0x95 -{ - uint16_t temp; - temp = REG16(AX); - REG16(AX) = REG16(BP); - REG16(BP) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_ax_si() // Opcode 0x96 -{ - uint16_t temp; - temp = REG16(AX); - REG16(AX) = REG16(SI); - REG16(SI) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_ax_di() // Opcode 0x97 -{ - uint16_t temp; - temp = REG16(AX); - REG16(AX) = REG16(DI); - REG16(DI) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_r16_rm16() // Opcode 0x87 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t src = LOAD_RM16(modrm); - uint16_t dst = LOAD_REG16(modrm); - STORE_REG16(modrm, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_XCHG_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t src = READ16(ea); - uint16_t dst = LOAD_REG16(modrm); - STORE_REG16(modrm, src); - WRITE16(ea, dst); - CYCLES(CYCLES_XCHG_REG_MEM); - } -} - -void i386_device::i386_xor_rm16_r16() // Opcode 0x31 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - dst = XOR16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - dst = XOR16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_xor_r16_rm16() // Opcode 0x33 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - dst = LOAD_REG16(modrm); - dst = XOR16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - dst = LOAD_REG16(modrm); - dst = XOR16(dst, src); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_xor_ax_i16() // Opcode 0x35 -{ - uint16_t src, dst; - src = FETCH16(); - dst = REG16(AX); - dst = XOR16(dst, src); - REG16(AX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - - - -void i386_device::i386_group81_16() // Opcode 0x81 -{ - uint32_t ea; - uint16_t src, dst; - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: // ADD Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - dst = ADD16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = FETCH16(); - dst = ADD16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 1: // OR Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - dst = OR16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = FETCH16(); - dst = OR16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 2: // ADC Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - dst = ADC16(dst, src, m_CF); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = FETCH16(); - dst = ADC16(dst, src, m_CF); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 3: // SBB Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - dst = SBB16(dst, src, m_CF); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = FETCH16(); - dst = SBB16(dst, src, m_CF); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 4: // AND Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - dst = AND16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = FETCH16(); - dst = AND16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 5: // SUB Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - dst = SUB16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = FETCH16(); - dst = SUB16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 6: // XOR Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - dst = XOR16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = FETCH16(); - dst = XOR16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 7: // CMP Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = FETCH16(); - SUB16(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - ea = GetEA(modrm,0); - dst = READ16(ea); - src = FETCH16(); - SUB16(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } - break; - } -} - -void i386_device::i386_group83_16() // Opcode 0x83 -{ - uint32_t ea; - uint16_t src, dst; - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: // ADD Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = ADD16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = ADD16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 1: // OR Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = OR16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = OR16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 2: // ADC Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = ADC16(dst, src, m_CF); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = ADC16(dst, src, m_CF); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 3: // SBB Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = ((uint16_t)(int16_t)(int8_t)FETCH()); - dst = SBB16(dst, src, m_CF); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = ((uint16_t)(int16_t)(int8_t)FETCH()); - dst = SBB16(dst, src, m_CF); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 4: // AND Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = AND16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = AND16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 5: // SUB Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = SUB16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = SUB16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 6: // XOR Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = XOR16(dst, src); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ16(ea); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - dst = XOR16(dst, src); - WRITE16(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 7: // CMP Rm16, i16 - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - SUB16(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - ea = GetEA(modrm,0); - dst = READ16(ea); - src = (uint16_t)(int16_t)(int8_t)FETCH(); - SUB16(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } - break; - } -} - -void i386_device::i386_groupC1_16() // Opcode 0xc1 -{ - uint16_t dst; - uint8_t modrm = FETCH(); - uint8_t shift; - - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - shift = FETCH() & 0x1f; - dst = i386_shift_rotate16(modrm, dst, shift); - STORE_RM16(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ16(ea); - shift = FETCH() & 0x1f; - dst = i386_shift_rotate16(modrm, dst, shift); - WRITE16(ea, dst); - } -} - -void i386_device::i386_groupD1_16() // Opcode 0xd1 -{ - uint16_t dst; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - dst = i386_shift_rotate16(modrm, dst, 1); - STORE_RM16(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ16(ea); - dst = i386_shift_rotate16(modrm, dst, 1); - WRITE16(ea, dst); - } -} - -void i386_device::i386_groupD3_16() // Opcode 0xd3 -{ - uint16_t dst; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - dst = LOAD_RM16(modrm); - dst = i386_shift_rotate16(modrm, dst, REG8(CL)); - STORE_RM16(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ16(ea); - dst = i386_shift_rotate16(modrm, dst, REG8(CL)); - WRITE16(ea, dst); - } -} - -void i386_device::i386_groupF7_16() // Opcode 0xf7 -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* TEST Rm16, i16 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t src = FETCH16(); - dst &= src; - m_CF = m_OF = m_AF = 0; - SetSZPF16(dst); - CYCLES(CYCLES_TEST_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint16_t dst = READ16(ea); - uint16_t src = FETCH16(); - dst &= src; - m_CF = m_OF = m_AF = 0; - SetSZPF16(dst); - CYCLES(CYCLES_TEST_IMM_MEM); - } - break; - case 2: /* NOT Rm16 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - dst = ~dst; - STORE_RM16(modrm, dst); - CYCLES(CYCLES_NOT_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - dst = ~dst; - WRITE16(ea, dst); - CYCLES(CYCLES_NOT_MEM); - } - break; - case 3: /* NEG Rm16 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - dst = SUB16(0, dst ); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_NEG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - dst = SUB16(0, dst ); - WRITE16(ea, dst); - CYCLES(CYCLES_NEG_MEM); - } - break; - case 4: /* MUL AX, Rm16 */ - { - uint32_t result; - uint16_t src, dst; - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - CYCLES(CYCLES_MUL16_ACC_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - CYCLES(CYCLES_MUL16_ACC_MEM); /* TODO: Correct multiply timing */ - } - - dst = REG16(AX); - result = (uint32_t)src * (uint32_t)dst; - REG16(DX) = (uint16_t)(result >> 16); - REG16(AX) = (uint16_t)result; - - m_CF = m_OF = (REG16(DX) != 0); - } - break; - case 5: /* IMUL AX, Rm16 */ - { - int32_t result; - int32_t src, dst; - if( modrm >= 0xc0 ) { - src = (int32_t)(int16_t)LOAD_RM16(modrm); - CYCLES(CYCLES_IMUL16_ACC_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = (int32_t)(int16_t)READ16(ea); - CYCLES(CYCLES_IMUL16_ACC_MEM); /* TODO: Correct multiply timing */ - } - - dst = (int32_t)(int16_t)REG16(AX); - result = src * dst; - - REG16(DX) = (uint16_t)(result >> 16); - REG16(AX) = (uint16_t)result; - - m_CF = m_OF = !(result == (int32_t)(int16_t)result); - } - break; - case 6: /* DIV AX, Rm16 */ - { - uint32_t quotient, remainder, result; - uint16_t src; - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - CYCLES(CYCLES_DIV16_ACC_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - CYCLES(CYCLES_DIV16_ACC_MEM); - } - - quotient = ((uint32_t)(REG16(DX)) << 16) | (uint32_t)(REG16(AX)); - if( src ) { - remainder = quotient % (uint32_t)src; - result = quotient / (uint32_t)src; - if( result > 0xffff ) { - /* TODO: Divide error */ - } else { - REG16(DX) = (uint16_t)remainder; - REG16(AX) = (uint16_t)result; - - // this flag is actually undefined, enable on non-cyrix - if (m_cpuid_id0 != 0x69727943) - m_CF = 1; - } - } else { - i386_trap(0, 0, 0); - } - } - break; - case 7: /* IDIV AX, Rm16 */ - { - int32_t quotient, remainder, result; - uint16_t src; - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - CYCLES(CYCLES_IDIV16_ACC_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - CYCLES(CYCLES_IDIV16_ACC_MEM); - } - - quotient = (((int32_t)REG16(DX)) << 16) | ((uint32_t)REG16(AX)); - if( src ) { - remainder = quotient % (int32_t)(int16_t)src; - result = quotient / (int32_t)(int16_t)src; - if( result > 0xffff ) { - /* TODO: Divide error */ - } else { - REG16(DX) = (uint16_t)remainder; - REG16(AX) = (uint16_t)result; - - // this flag is actually undefined, enable on non-cyrix - if (m_cpuid_id0 != 0x69727943) - m_CF = 1; - } - } else { - i386_trap(0, 0, 0); - } - } - break; - } -} - -void i386_device::i386_groupFF_16() // Opcode 0xff -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* INC Rm16 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - dst = INC16(dst); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_INC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - dst = INC16(dst); - WRITE16(ea, dst); - CYCLES(CYCLES_INC_MEM); - } - break; - case 1: /* DEC Rm16 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - dst = DEC16(dst); - STORE_RM16(modrm, dst); - CYCLES(CYCLES_DEC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - dst = DEC16(dst); - WRITE16(ea, dst); - CYCLES(CYCLES_DEC_MEM); - } - break; - case 2: /* CALL Rm16 */ - { - uint16_t address; - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - CYCLES(CYCLES_CALL_REG); /* TODO: Timing = 7 + m */ - } else { - uint32_t ea = GetEA(modrm,0); - address = READ16(ea); - CYCLES(CYCLES_CALL_MEM); /* TODO: Timing = 10 + m */ - } - PUSH16(m_eip ); - m_eip = address; - CHANGE_PC(m_eip); - } - break; - case 3: /* CALL FAR Rm16 */ - { - uint16_t address, selector; - if( modrm >= 0xc0 ) - { - report_invalid_modrm("groupFF_16", modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - address = READ16(ea + 0); - selector = READ16(ea + 2); - CYCLES(CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */ - - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_call(selector,address,1,0); - } - else - { - PUSH16(m_sreg[CS].selector ); - PUSH16(m_eip ); - m_sreg[CS].selector = selector; - m_performed_intersegment_jump = 1; - i386_load_segment_descriptor(CS ); - if(bios_call_far_x86(( (((uint32_t)ptr) << 4) + ((uint32_t)offset)) & m_a20_mask)) { - m_eip = POP16(); - m_sreg[CS].selector = POP16(); - i386_load_segment_descriptor(CS); - CYCLES(CYCLES_CALL_INTERSEG + CYCLES_RET_INTERSEG); /* TODO: Timing = 17 + m */ - return; - } - m_eip = address; - CHANGE_PC(m_eip); - } - } - } - break; - case 4: /* JMP Rm16 */ - { - uint16_t address; - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - CYCLES(CYCLES_JMP_REG); /* TODO: Timing = 7 + m */ - } else { - uint32_t ea = GetEA(modrm,0); - address = READ16(ea); - CYCLES(CYCLES_JMP_MEM); /* TODO: Timing = 10 + m */ - } - m_eip = address; - CHANGE_PC(m_eip); - } - break; - case 5: /* JMP FAR Rm16 */ - { - uint16_t address, selector; - - if( modrm >= 0xc0 ) - { - report_invalid_modrm("groupFF_16", modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - address = READ16(ea + 0); - selector = READ16(ea + 2); - CYCLES(CYCLES_JMP_MEM_INTERSEG); /* TODO: Timing = 10 + m */ - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_jump(selector,address,1,0); - } - else - { - m_sreg[CS].selector = selector; - m_performed_intersegment_jump = 1; - i386_load_segment_descriptor(CS ); - m_eip = address; - CHANGE_PC(m_eip); - } - } - } - break; - case 6: /* PUSH Rm16 */ - { - uint16_t value; - if( modrm >= 0xc0 ) { - value = LOAD_RM16(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - value = READ16(ea); - } - PUSH16(value); - CYCLES(CYCLES_PUSH_RM); - } - break; - default: - report_invalid_modrm("groupFF_16", modrm); - break; - } -} - -void i386_device::i386_group0F00_16() // Opcode 0x0f 00 -{ - uint32_t address, ea; - uint8_t modrm = FETCH(); - I386_SREG seg; - uint8_t result; - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* SLDT */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if( modrm >= 0xc0 ) { - STORE_RM16(modrm, m_ldtr.segment); - CYCLES(CYCLES_SLDT_REG); - } else { - ea = GetEA(modrm,1); - WRITE16(ea, m_ldtr.segment); - CYCLES(CYCLES_SLDT_MEM); - } - } - else - { - i386_trap(6, 0, 0); - } - break; - case 1: /* STR */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if( modrm >= 0xc0 ) { - STORE_RM16(modrm, m_task.segment); - CYCLES(CYCLES_STR_REG); - } else { - ea = GetEA(modrm,1); - WRITE16(ea, m_task.segment); - CYCLES(CYCLES_STR_MEM); - } - } - else - { - i386_trap(6, 0, 0); - } - break; - case 2: /* LLDT */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if(m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - m_ldtr.segment = address; - CYCLES(CYCLES_LLDT_REG); - } else { - ea = GetEA(modrm,0); - m_ldtr.segment = READ16(ea); - CYCLES(CYCLES_LLDT_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = m_ldtr.segment; - i386_load_protected_mode_segment(&seg,nullptr); - m_ldtr.limit = seg.limit; - m_ldtr.base = seg.base; - m_ldtr.flags = seg.flags; - } - else - { - i386_trap(6, 0, 0); - } - break; - - case 3: /* LTR */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if(m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - m_task.segment = address; - CYCLES(CYCLES_LTR_REG); - } else { - ea = GetEA(modrm,0); - m_task.segment = READ16(ea); - CYCLES(CYCLES_LTR_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = m_task.segment; - i386_load_protected_mode_segment(&seg,nullptr); - - uint32_t addr = ((seg.selector & 4) ? m_ldtr.base : m_gdtr.base) + (seg.selector & ~7) + 5; - i386_translate_address(TRANSLATE_READ, &addr, nullptr); - m_program->write_byte(addr, (seg.flags & 0xff) | 2); - - m_task.limit = seg.limit; - m_task.base = seg.base; - m_task.flags = seg.flags | 2; - } - else - { - i386_trap(6, 0, 0); - } - break; - - case 4: /* VERR */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - result = 1; - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - CYCLES(CYCLES_VERR_REG); - } else { - ea = GetEA(modrm,0); - address = READ16(ea); - CYCLES(CYCLES_VERR_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = address; - result = i386_load_protected_mode_segment(&seg,nullptr); - // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...) - if(!(seg.flags & 0x10)) - result = 0; - // check that the segment is readable - if(seg.flags & 0x10) // is code or data segment - { - if(seg.flags & 0x08) // is code segment, so check if it's readable - { - if(!(seg.flags & 0x02)) - { - result = 0; - } - else - { // check if conforming, these are always readable, regardless of privilege - if(!(seg.flags & 0x04)) - { - // if not conforming, then we must check privilege levels (TODO: current privilege level check) - if(((seg.flags >> 5) & 0x03) < (address & 0x03)) - result = 0; - } - } - } - } - // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO) - SetZF(result); - } - else - { - i386_trap(6, 0, 0); - logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n"); - } - break; - - case 5: /* VERW */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - result = 1; - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - CYCLES(CYCLES_VERW_REG); - } else { - ea = GetEA(modrm,0); - address = READ16(ea); - CYCLES(CYCLES_VERW_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = address; - result = i386_load_protected_mode_segment(&seg,nullptr); - // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...) - if(!(seg.flags & 0x10)) - result = 0; - // check that the segment is writable - if(seg.flags & 0x10) // is code or data segment - { - if(seg.flags & 0x08) // is code segment (and thus, not writable) - { - result = 0; - } - else - { // is data segment - if(!(seg.flags & 0x02)) - result = 0; - } - } - // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO) - if(((seg.flags >> 5) & 0x03) < (address & 0x03)) - result = 0; - SetZF(result); - } - else - { - i386_trap(6, 0, 0); - logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n"); - } - break; - - default: - report_invalid_modrm("group0F00_16", modrm); - break; - } -} - -void i386_device::i386_group0F01_16() // Opcode 0x0f 01 -{ - uint8_t modrm = FETCH(); - uint16_t address; - uint32_t ea; - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* SGDT */ - { - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - ea = i386_translate(CS, address, 1 ); - } else { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_gdtr.limit); - WRITE32(ea + 2, m_gdtr.base); - CYCLES(CYCLES_SGDT); - break; - } - case 1: /* SIDT */ - { - if (modrm >= 0xc0) - { - address = LOAD_RM16(modrm); - ea = i386_translate(CS, address, 1 ); - } - else - { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_idtr.limit); - WRITE32(ea + 2, m_idtr.base); - CYCLES(CYCLES_SIDT); - break; - } - case 2: /* LGDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - ea = i386_translate(CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_gdtr.limit = READ16(ea); - m_gdtr.base = READ32(ea + 2) & 0xffffff; - CYCLES(CYCLES_LGDT); - break; - } - case 3: /* LIDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - ea = i386_translate(CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_idtr.limit = READ16(ea); - m_idtr.base = READ32(ea + 2) & 0xffffff; - CYCLES(CYCLES_LIDT); - break; - } - case 4: /* SMSW */ - { - if( modrm >= 0xc0 ) { - STORE_RM16(modrm, m_cr[0]); - CYCLES(CYCLES_SMSW_REG); - } else { - ea = GetEA(modrm,1); - WRITE16(ea, m_cr[0]); - CYCLES(CYCLES_SMSW_MEM); - } - break; - } - case 6: /* LMSW */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - uint16_t b; - if( modrm >= 0xc0 ) { - b = LOAD_RM16(modrm); - CYCLES(CYCLES_LMSW_REG); - } else { - ea = GetEA(modrm,0); - CYCLES(CYCLES_LMSW_MEM); - b = READ16(ea); - } - if(PROTECTED_MODE) - b |= 0x0001; // cannot return to real mode using this instruction. - m_cr[0] &= ~0x0000000f; - m_cr[0] |= b & 0x0000000f; - break; - } - default: - report_invalid_modrm("group0F01_16", modrm); - break; - } -} - -void i386_device::i386_group0FBA_16() // Opcode 0x0f ba -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 4: /* BT Rm16, i8 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint16_t dst = READ16(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_IMM_MEM); - } - break; - case 5: /* BTS Rm16, i8 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << bit); - - STORE_RM16(modrm, dst); - CYCLES(CYCLES_BTS_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << bit); - - WRITE16(ea, dst); - CYCLES(CYCLES_BTS_IMM_MEM); - } - break; - case 6: /* BTR Rm16, i8 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << bit); - - STORE_RM16(modrm, dst); - CYCLES(CYCLES_BTR_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << bit); - - WRITE16(ea, dst); - CYCLES(CYCLES_BTR_IMM_MEM); - } - break; - case 7: /* BTC Rm16, i8 */ - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << bit); - - STORE_RM16(modrm, dst); - CYCLES(CYCLES_BTC_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << bit); - - WRITE16(ea, dst); - CYCLES(CYCLES_BTC_IMM_MEM); - } - break; - default: - report_invalid_modrm("group0FBA_16", modrm); - break; - } -} - -void i386_device::i386_lar_r16_rm16() // Opcode 0x0f 0x02 -{ - uint8_t modrm = FETCH(); - I386_SREG seg; - uint8_t type; - - if(PROTECTED_MODE && !V8086_MODE) - { - memset(&seg,0,sizeof(seg)); - if(modrm >= 0xc0) - { - seg.selector = LOAD_RM16(modrm); - CYCLES(CYCLES_LAR_REG); - } - else - { - uint32_t ea = GetEA(modrm,0); - seg.selector = READ16(ea); - CYCLES(CYCLES_LAR_MEM); - } - if(seg.selector == 0) - { - SetZF(0); // not a valid segment - // logerror("i386 (%08x): LAR: Selector %04x is invalid type.\n",m_pc,seg.selector); - } - else - { - if(!i386_load_protected_mode_segment(&seg,nullptr)) - { - SetZF(0); - return; - } - uint8_t DPL = (seg.flags >> 5) & 3; - if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c)) - { - SetZF(0); - return; - } - if(!(seg.flags & 0x10)) // special segment - { - // check for invalid segment types - type = seg.flags & 0x000f; - if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d) - { - SetZF(0); // invalid segment type - } - else - { - STORE_REG16(modrm,(seg.flags << 8) & 0xff00); - SetZF(1); - } - } - else - { // data or code segment (both are valid for LAR) - STORE_REG16(modrm,(seg.flags << 8) & 0xff00); - SetZF(1); - } - } - } - else - { - // illegal opcode - i386_trap(6,0, 0); - logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n"); - } -} - -void i386_device::i386_lsl_r16_rm16() // Opcode 0x0f 0x03 -{ - uint8_t modrm = FETCH(); - uint32_t limit; - I386_SREG seg; - - if(PROTECTED_MODE && !V8086_MODE) - { - memset(&seg, 0, sizeof(seg)); - if(modrm >= 0xc0) - { - seg.selector = LOAD_RM16(modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - seg.selector = READ16(ea); - } - if(seg.selector == 0) - { - SetZF(0); // not a valid segment - } - else - { - uint8_t type; - if(!i386_load_protected_mode_segment(&seg,nullptr)) - { - SetZF(0); - return; - } - uint8_t DPL = (seg.flags >> 5) & 3; - if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c)) - { - SetZF(0); - return; - } - type = seg.flags & 0x1f; - switch(type) - { - case 0: - case 4: - case 5: - case 6: - case 7: - case 8: - case 10: - case 12: - case 13: - case 14: - case 15: - SetZF(0); - return; - default: - limit = seg.limit; - STORE_REG16(modrm,limit & 0x0000ffff); - SetZF(1); - } - } - } - else - i386_trap(6, 0, 0); -} - -void i386_device::i386_bound_r16_m16_m16() // Opcode 0x62 -{ - uint8_t modrm; - int16_t val, low, high; - - modrm = FETCH(); - - if (modrm >= 0xc0) - { - low = high = LOAD_RM16(modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - low = READ16(ea + 0); - high = READ16(ea + 2); - } - val = LOAD_REG16(modrm); - - if ((val < low) || (val > high)) - { - CYCLES(CYCLES_BOUND_OUT_RANGE); - i386_trap(5, 0, 0); - } - else - { - CYCLES(CYCLES_BOUND_IN_RANGE); - } -} - -void i386_device::i386_retf16() // Opcode 0xcb -{ - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_retf(0,0); - } - else - { - m_eip = POP16(); - m_sreg[CS].selector = POP16(); - i386_load_segment_descriptor(CS ); - CHANGE_PC(m_eip); - } - - CYCLES(CYCLES_RET_INTERSEG); -} - -void i386_device::i386_retf_i16() // Opcode 0xca -{ - uint16_t count = FETCH16(); - - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_retf(count,0); - } - else - { - m_eip = POP16(); - m_sreg[CS].selector = POP16(); - i386_load_segment_descriptor(CS ); - CHANGE_PC(m_eip); - REG16(SP) += count; - } - - CYCLES(CYCLES_RET_IMM_INTERSEG); -} - -bool i386_device::i386_load_far_pointer16(int s) -{ - uint8_t modrm = FETCH(); - uint16_t selector; - - if( modrm >= 0xc0 ) { - //logerror("i386: load_far_pointer16 NYI\n"); // don't log, NT will use this a lot - i386_trap(6, 0, 0); - return false; - } else { - uint32_t ea = GetEA(modrm,0); - STORE_REG16(modrm, READ16(ea + 0)); - selector = READ16(ea + 2); - i386_sreg_load(selector,s,nullptr); - } - return true; -} - -void i386_device::i386_lds16() // Opcode 0xc5 -{ - if(i386_load_far_pointer16(DS)) - CYCLES(CYCLES_LDS); -} - -void i386_device::i386_lss16() // Opcode 0x0f 0xb2 -{ - if(i386_load_far_pointer16(SS)) - CYCLES(CYCLES_LSS); -} - -void i386_device::i386_les16() // Opcode 0xc4 -{ - if(i386_load_far_pointer16(ES)) - CYCLES(CYCLES_LES); -} - -void i386_device::i386_lfs16() // Opcode 0x0f 0xb4 -{ - if(i386_load_far_pointer16(FS)) - CYCLES(CYCLES_LFS); -} - -void i386_device::i386_lgs16() // Opcode 0x0f 0xb5 -{ - if(i386_load_far_pointer16(GS)) - CYCLES(CYCLES_LGS); -} diff --git a/source/src/vm/libcpu_newdev/i386/i386op32.hxx b/source/src/vm/libcpu_newdev/i386/i386op32.hxx deleted file mode 100644 index 0d5db1771..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386op32.hxx +++ /dev/null @@ -1,3585 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -uint32_t i386_device::i386_shift_rotate32(uint8_t modrm, uint32_t value, uint8_t shift) -{ - uint32_t dst, src; - dst = value; - src = value; - - if( shift == 0 ) { - CYCLES_RM(modrm, 3, 7); - } else if( shift == 1 ) { - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* ROL rm32, 1 */ - m_CF = (src & 0x80000000) ? 1 : 0; - dst = (src << 1) + m_CF; - m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 1: /* ROR rm32, 1 */ - m_CF = (src & 0x1) ? 1 : 0; - dst = (m_CF << 31) | (src >> 1); - m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 2: /* RCL rm32, 1 */ - dst = (src << 1) + m_CF; - m_CF = (src & 0x80000000) ? 1 : 0; - m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 3: /* RCR rm32, 1 */ - dst = (m_CF << 31) | (src >> 1); - m_CF = src & 0x1; - m_OF = ((src ^ dst) & 0x80000000) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 4: /* SHL/SAL rm32, 1 */ - case 6: - dst = src << 1; - m_CF = (src & 0x80000000) ? 1 : 0; - m_OF = (((m_CF << 31) ^ dst) & 0x80000000) ? 1 : 0; - SetSZPF32(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 5: /* SHR rm32, 1 */ - dst = src >> 1; - m_CF = src & 0x1; - m_OF = (src & 0x80000000) ? 1 : 0; - SetSZPF32(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 7: /* SAR rm32, 1 */ - dst = (int32_t)(src) >> 1; - m_CF = src & 0x1; - m_OF = 0; - SetSZPF32(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - } - - } else { - shift &= 31; - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* ROL rm32, i8 */ - dst = ((src & ((uint32_t)0xffffffff >> shift)) << shift) | - ((src & ((uint32_t)0xffffffff << (32-shift))) >> (32-shift)); - m_CF = dst & 0x1; - m_OF = (dst & 1) ^ (dst >> 31); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 1: /* ROR rm32, i8 */ - dst = ((src & ((uint32_t)0xffffffff << shift)) >> shift) | - ((src & ((uint32_t)0xffffffff >> (32-shift))) << (32-shift)); - m_CF = (dst >> 31) & 0x1; - m_OF = ((dst >> 31) ^ (dst >> 30)) & 1; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 2: /* RCL rm32, i8 */ - dst = ((src & ((uint32_t)0xffffffff >> shift)) << shift) | - ((src & ((uint32_t)0xffffffff << (33-shift))) >> (33-shift)) | - (m_CF << (shift-1)); - m_CF = (src >> (32-shift)) & 0x1; - m_OF = m_CF ^ ((dst >> 31) & 1); - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 3: /* RCR rm32, i8 */ - dst = ((src & ((uint32_t)0xffffffff << shift)) >> shift) | - ((src & ((uint32_t)0xffffffff >> (32-shift))) << (33-shift)) | - (m_CF << (32-shift)); - m_CF = (src >> (shift-1)) & 0x1; - m_OF = ((dst >> 31) ^ (dst >> 30)) & 1; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 4: /* SHL/SAL rm32, i8 */ - case 6: - dst = src << shift; - m_CF = (src & (1 << (32-shift))) ? 1 : 0; - SetSZPF32(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 5: /* SHR rm32, i8 */ - dst = src >> shift; - m_CF = (src & (1 << (shift-1))) ? 1 : 0; - SetSZPF32(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 7: /* SAR rm32, i8 */ - dst = (int32_t)src >> shift; - m_CF = (src & (1 << (shift-1))) ? 1 : 0; - SetSZPF32(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - } - - } - return dst; -} - - - -void i386_device::i386_adc_rm32_r32() // Opcode 0x11 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = ADC32(dst, src, m_CF); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = ADC32(dst, src, m_CF); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_adc_r32_rm32() // Opcode 0x13 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - dst = ADC32(dst, src, m_CF); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - dst = ADC32(dst, src, m_CF); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_adc_eax_i32() // Opcode 0x15 -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - dst = ADC32(dst, src, m_CF); - REG32(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_add_rm32_r32() // Opcode 0x01 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = ADD32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = ADD32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_add_r32_rm32() // Opcode 0x03 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - dst = ADD32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - dst = ADD32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_add_eax_i32() // Opcode 0x05 -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - dst = ADD32(dst, src); - REG32(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_and_rm32_r32() // Opcode 0x21 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = AND32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = AND32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_and_r32_rm32() // Opcode 0x23 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - dst = AND32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - dst = AND32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_and_eax_i32() // Opcode 0x25 -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - dst = AND32(dst, src); - REG32(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_bsf_r32_rm32() // Opcode 0x0f bc -{ - uint32_t src, dst, temp; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - } - - dst = 0; - - if( src == 0 ) { - m_ZF = 1; - } else { - m_ZF = 0; - temp = 0; - while( (src & (1 << temp)) == 0 ) { - temp++; - dst = temp; - CYCLES(CYCLES_BSF); - } - STORE_REG32(modrm, dst); - } - CYCLES(CYCLES_BSF_BASE); -} - -void i386_device::i386_bsr_r32_rm32() // Opcode 0x0f bd -{ - uint32_t src, dst, temp; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - } - - dst = 0; - - if( src == 0 ) { - m_ZF = 1; - } else { - m_ZF = 0; - dst = temp = 31; - while( (src & (1U << temp)) == 0 ) { - temp--; - dst = temp; - CYCLES(CYCLES_BSR); - } - STORE_REG32(modrm, dst); - } - CYCLES(CYCLES_BSR_BASE); -} - -void i386_device::i386_bt_rm32_r32() // Opcode 0x0f a3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t bit = LOAD_REG32(modrm); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint32_t bit = LOAD_REG32(modrm); - ea += 4*(bit/32); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),0); - bit %= 32; - uint32_t dst = READ32(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_REG_MEM); - } -} - -void i386_device::i386_btc_rm32_r32() // Opcode 0x0f bb -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t bit = LOAD_REG32(modrm); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << bit); - - STORE_RM32(modrm, dst); - CYCLES(CYCLES_BTC_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint32_t bit = LOAD_REG32(modrm); - ea += 4*(bit/32); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1); - bit %= 32; - uint32_t dst = READ32(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << bit); - - WRITE32(ea, dst); - CYCLES(CYCLES_BTC_REG_MEM); - } -} - -void i386_device::i386_btr_rm32_r32() // Opcode 0x0f b3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t bit = LOAD_REG32(modrm); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << bit); - - STORE_RM32(modrm, dst); - CYCLES(CYCLES_BTR_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint32_t bit = LOAD_REG32(modrm); - ea += 4*(bit/32); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1); - bit %= 32; - uint32_t dst = READ32(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << bit); - - WRITE32(ea, dst); - CYCLES(CYCLES_BTR_REG_MEM); - } -} - -void i386_device::i386_bts_rm32_r32() // Opcode 0x0f ab -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t bit = LOAD_REG32(modrm); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << bit); - - STORE_RM32(modrm, dst); - CYCLES(CYCLES_BTS_REG_REG); - } else { - uint8_t segment; - uint32_t ea = GetNonTranslatedEA(modrm,&segment); - uint32_t bit = LOAD_REG32(modrm); - ea += 4*(bit/32); - ea = i386_translate(segment,(m_address_size)?ea:(ea&0xffff),1); - bit %= 32; - uint32_t dst = READ32(ea); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << bit); - - WRITE32(ea, dst); - CYCLES(CYCLES_BTS_REG_MEM); - } -} - -void i386_device::i386_call_abs32() // Opcode 0x9a -{ - uint32_t offset = FETCH32(); - uint16_t ptr = FETCH16(); - - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_call(ptr,offset,0,1); - } - else - { - PUSH32SEG(m_sreg[CS].selector ); - PUSH32(m_eip ); - m_sreg[CS].selector = ptr; - m_performed_intersegment_jump = 1; - m_eip = offset; - i386_load_segment_descriptor(CS); - } - CYCLES(CYCLES_CALL_INTERSEG); - CHANGE_PC(m_eip); -} - -void i386_device::i386_call_rel32() // Opcode 0xe8 -{ - int32_t disp = FETCH32(); - PUSH32(m_eip ); - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_CALL); /* TODO: Timing = 7 + m */ -} - -void i386_device::i386_cdq() // Opcode 0x99 -{ - if( REG32(EAX) & 0x80000000 ) { - REG32(EDX) = 0xffffffff; - } else { - REG32(EDX) = 0x00000000; - } - CYCLES(CYCLES_CWD); -} - -void i386_device::i386_cmp_rm32_r32() // Opcode 0x39 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - SUB32(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = LOAD_REG32(modrm); - dst = READ32(ea); - SUB32(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } -} - -void i386_device::i386_cmp_r32_rm32() // Opcode 0x3b -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - SUB32(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - SUB32(dst, src); - CYCLES(CYCLES_CMP_MEM_REG); - } -} - -void i386_device::i386_cmp_eax_i32() // Opcode 0x3d -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - SUB32(dst, src); - CYCLES(CYCLES_CMP_IMM_ACC); -} - -void i386_device::i386_cmpsd() // Opcode 0xa7 -{ - uint32_t eas, ead, src, dst; - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 ); - src = READ32(eas); - dst = READ32(ead); - SUB32(src,dst); - BUMP_SI(4); - BUMP_DI(4); - CYCLES(CYCLES_CMPS); -} - -void i386_device::i386_cwde() // Opcode 0x98 -{ - REG32(EAX) = (int32_t)((int16_t)REG16(AX)); - CYCLES(CYCLES_CBW); -} - -void i386_device::i386_dec_eax() // Opcode 0x48 -{ - REG32(EAX) = DEC32(REG32(EAX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_ecx() // Opcode 0x49 -{ - REG32(ECX) = DEC32(REG32(ECX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_edx() // Opcode 0x4a -{ - REG32(EDX) = DEC32(REG32(EDX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_ebx() // Opcode 0x4b -{ - REG32(EBX) = DEC32(REG32(EBX) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_esp() // Opcode 0x4c -{ - REG32(ESP) = DEC32(REG32(ESP) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_ebp() // Opcode 0x4d -{ - REG32(EBP) = DEC32(REG32(EBP) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_esi() // Opcode 0x4e -{ - REG32(ESI) = DEC32(REG32(ESI) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_dec_edi() // Opcode 0x4f -{ - REG32(EDI) = DEC32(REG32(EDI) ); - CYCLES(CYCLES_DEC_REG); -} - -void i386_device::i386_imul_r32_rm32() // Opcode 0x0f af -{ - uint8_t modrm = FETCH(); - int64_t result; - int64_t src, dst; - if( modrm >= 0xc0 ) { - src = (int64_t)(int32_t)LOAD_RM32(modrm); - CYCLES(CYCLES_IMUL32_REG_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = (int64_t)(int32_t)READ32(ea); - CYCLES(CYCLES_IMUL32_REG_REG); /* TODO: Correct multiply timing */ - } - - dst = (int64_t)(int32_t)LOAD_REG32(modrm); - result = src * dst; - - STORE_REG32(modrm, (uint32_t)result); - - m_CF = m_OF = !(result == (int64_t)(int32_t)result); -} - -void i386_device::i386_imul_r32_rm32_i32() // Opcode 0x69 -{ - uint8_t modrm = FETCH(); - int64_t result; - int64_t src, dst; - if( modrm >= 0xc0 ) { - dst = (int64_t)(int32_t)LOAD_RM32(modrm); - CYCLES(CYCLES_IMUL32_REG_IMM_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - dst = (int64_t)(int32_t)READ32(ea); - CYCLES(CYCLES_IMUL32_MEM_IMM_REG); /* TODO: Correct multiply timing */ - } - - src = (int64_t)(int32_t)FETCH32(); - result = src * dst; - - STORE_REG32(modrm, (uint32_t)result); - - m_CF = m_OF = !(result == (int64_t)(int32_t)result); -} - -void i386_device::i386_imul_r32_rm32_i8() // Opcode 0x6b -{ - uint8_t modrm = FETCH(); - int64_t result; - int64_t src, dst; - if( modrm >= 0xc0 ) { - dst = (int64_t)(int32_t)LOAD_RM32(modrm); - CYCLES(CYCLES_IMUL32_REG_IMM_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - dst = (int64_t)(int32_t)READ32(ea); - CYCLES(CYCLES_IMUL32_MEM_IMM_REG); /* TODO: Correct multiply timing */ - } - - src = (int64_t)(int8_t)FETCH(); - result = src * dst; - - STORE_REG32(modrm, (uint32_t)result); - - m_CF = m_OF = !(result == (int64_t)(int32_t)result); -} - -void i386_device::i386_in_eax_i8() // Opcode 0xe5 -{ - uint16_t port = FETCH(); - uint32_t data = READPORT32(port); - REG32(EAX) = data; - CYCLES(CYCLES_IN_VAR); -} - -void i386_device::i386_in_eax_dx() // Opcode 0xed -{ - uint16_t port = REG16(DX); - uint32_t data = READPORT32(port); - REG32(EAX) = data; - CYCLES(CYCLES_IN); -} - -void i386_device::i386_inc_eax() // Opcode 0x40 -{ - REG32(EAX) = INC32(REG32(EAX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_ecx() // Opcode 0x41 -{ - REG32(ECX) = INC32(REG32(ECX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_edx() // Opcode 0x42 -{ - REG32(EDX) = INC32(REG32(EDX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_ebx() // Opcode 0x43 -{ - REG32(EBX) = INC32(REG32(EBX) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_esp() // Opcode 0x44 -{ - REG32(ESP) = INC32(REG32(ESP) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_ebp() // Opcode 0x45 -{ - REG32(EBP) = INC32(REG32(EBP) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_esi() // Opcode 0x46 -{ - REG32(ESI) = INC32(REG32(ESI) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_inc_edi() // Opcode 0x47 -{ - REG32(EDI) = INC32(REG32(EDI) ); - CYCLES(CYCLES_INC_REG); -} - -void i386_device::i386_iret32() // Opcode 0xcf -{ - if( PROTECTED_MODE ) - { - i386_protected_mode_iret(1); - } - else - { - /* TODO: #SS(0) exception */ - /* TODO: #GP(0) exception */ - m_eip = POP32(); - m_sreg[CS].selector = POP32() & 0xffff; - set_flags(POP32() ); - i386_load_segment_descriptor(CS); - CHANGE_PC(m_eip); - } - CYCLES(CYCLES_IRET); -} - -void i386_device::i386_ja_rel32() // Opcode 0x0f 87 -{ - int32_t disp = FETCH32(); - if( m_CF == 0 && m_ZF == 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jbe_rel32() // Opcode 0x0f 86 -{ - int32_t disp = FETCH32(); - if( m_CF != 0 || m_ZF != 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jc_rel32() // Opcode 0x0f 82 -{ - int32_t disp = FETCH32(); - if( m_CF != 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jg_rel32() // Opcode 0x0f 8f -{ - int32_t disp = FETCH32(); - if( m_ZF == 0 && (m_SF == m_OF) ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jge_rel32() // Opcode 0x0f 8d -{ - int32_t disp = FETCH32(); - if(m_SF == m_OF) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jl_rel32() // Opcode 0x0f 8c -{ - int32_t disp = FETCH32(); - if( (m_SF != m_OF) ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jle_rel32() // Opcode 0x0f 8e -{ - int32_t disp = FETCH32(); - if( m_ZF != 0 || (m_SF != m_OF) ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jnc_rel32() // Opcode 0x0f 83 -{ - int32_t disp = FETCH32(); - if( m_CF == 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jno_rel32() // Opcode 0x0f 81 -{ - int32_t disp = FETCH32(); - if( m_OF == 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jnp_rel32() // Opcode 0x0f 8b -{ - int32_t disp = FETCH32(); - if( m_PF == 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jns_rel32() // Opcode 0x0f 89 -{ - int32_t disp = FETCH32(); - if( m_SF == 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jnz_rel32() // Opcode 0x0f 85 -{ - int32_t disp = FETCH32(); - if( m_ZF == 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jo_rel32() // Opcode 0x0f 80 -{ - int32_t disp = FETCH32(); - if( m_OF != 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jp_rel32() // Opcode 0x0f 8a -{ - int32_t disp = FETCH32(); - if( m_PF != 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_js_rel32() // Opcode 0x0f 88 -{ - int32_t disp = FETCH32(); - if( m_SF != 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jz_rel32() // Opcode 0x0f 84 -{ - int32_t disp = FETCH32(); - if( m_ZF != 0 ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCC_FULL_DISP); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_FULL_DISP_NOBRANCH); - } -} - -void i386_device::i386_jcxz32() // Opcode 0xe3 -{ - int8_t disp = FETCH(); - int val = (m_address_size)?(REG32(ECX) == 0):(REG16(CX) == 0); - if( val ) { - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JCXZ); /* TODO: Timing = 9 + m */ - } else { - CYCLES(CYCLES_JCXZ_NOBRANCH); - } -} - -void i386_device::i386_jmp_rel32() // Opcode 0xe9 -{ - uint32_t disp = FETCH32(); - /* TODO: Segment limit */ - m_eip += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_JMP); /* TODO: Timing = 7 + m */ -} - -void i386_device::i386_jmp_abs32() // Opcode 0xea -{ - uint32_t address = FETCH32(); - uint16_t segment = FETCH16(); - - if( PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_jump(segment,address,0,1); - } - else - { - m_eip = address; - m_sreg[CS].selector = segment; - m_performed_intersegment_jump = 1; - i386_load_segment_descriptor(CS); - CHANGE_PC(m_eip); - } - CYCLES(CYCLES_JMP_INTERSEG); -} - -void i386_device::i386_lea32() // Opcode 0x8d -{ - uint8_t modrm = FETCH(); - uint32_t ea = GetNonTranslatedEA(modrm,nullptr); - if (!m_address_size) - { - ea &= 0xffff; - } - STORE_REG32(modrm, ea); - CYCLES(CYCLES_LEA); -} - -void i386_device::i386_enter32() // Opcode 0xc8 -{ - uint16_t framesize = FETCH16(); - uint8_t level = FETCH() % 32; - uint8_t x; - uint32_t frameptr; - PUSH32(REG32(EBP)); - if(!STACK_32BIT) - frameptr = REG16(SP); - else - frameptr = REG32(ESP); - - if(level > 0) - { - for(x=1;x= 0xc0 ) { - src = LOAD_REG32(modrm); - STORE_RM32(modrm, src); - CYCLES(CYCLES_MOV_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - WRITE32(ea, src); - CYCLES(CYCLES_MOV_REG_MEM); - } -} - -void i386_device::i386_mov_r32_rm32() // Opcode 0x8b -{ - uint32_t src; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOV_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOV_MEM_REG); - } -} - -void i386_device::i386_mov_rm32_i32() // Opcode 0xc7 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t value = FETCH32(); - STORE_RM32(modrm, value); - CYCLES(CYCLES_MOV_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t value = FETCH32(); - WRITE32(ea, value); - CYCLES(CYCLES_MOV_IMM_MEM); - } -} - -void i386_device::i386_mov_eax_m32() // Opcode 0xa1 -{ - uint32_t offset, ea; - if( m_address_size ) { - offset = FETCH32(); - } else { - offset = FETCH16(); - } - if( m_segment_prefix ) { - ea = i386_translate(m_segment_override, offset, 0 ); - } else { - ea = i386_translate(DS, offset, 0 ); - } - REG32(EAX) = READ32(ea); - CYCLES(CYCLES_MOV_MEM_ACC); -} - -void i386_device::i386_mov_m32_eax() // Opcode 0xa3 -{ - uint32_t offset, ea; - if( m_address_size ) { - offset = FETCH32(); - } else { - offset = FETCH16(); - } - if( m_segment_prefix ) { - ea = i386_translate(m_segment_override, offset, 1 ); - } else { - ea = i386_translate(DS, offset, 1 ); - } - WRITE32(ea, REG32(EAX) ); - CYCLES(CYCLES_MOV_ACC_MEM); -} - -void i386_device::i386_mov_eax_i32() // Opcode 0xb8 -{ - REG32(EAX) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_ecx_i32() // Opcode 0xb9 -{ - REG32(ECX) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_edx_i32() // Opcode 0xba -{ - REG32(EDX) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_ebx_i32() // Opcode 0xbb -{ - REG32(EBX) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_esp_i32() // Opcode 0xbc -{ - REG32(ESP) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_ebp_i32() // Opcode 0xbd -{ - REG32(EBP) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_esi_i32() // Opcode 0xbe -{ - REG32(ESI) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_edi_i32() // Opcode 0xbf -{ - REG32(EDI) = FETCH32(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_movsd() // Opcode 0xa5 -{ - uint32_t eas, ead, v; - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 ); - v = READ32(eas); - WRITE32(ead, v); - BUMP_SI(4); - BUMP_DI(4); - CYCLES(CYCLES_MOVS); -} - -void i386_device::i386_movsx_r32_rm8() // Opcode 0x0f be -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int32_t src = (int8_t)LOAD_RM8(modrm); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVSX_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - int32_t src = (int8_t)READ8(ea); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVSX_MEM_REG); - } -} - -void i386_device::i386_movsx_r32_rm16() // Opcode 0x0f bf -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int32_t src = (int16_t)LOAD_RM16(modrm); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVSX_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - int32_t src = (int16_t)READ16(ea); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVSX_MEM_REG); - } -} - -void i386_device::i386_movzx_r32_rm8() // Opcode 0x0f b6 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t src = (uint8_t)LOAD_RM8(modrm); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVZX_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint32_t src = (uint8_t)READ8(ea); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVZX_MEM_REG); - } -} - -void i386_device::i386_movzx_r32_rm16() // Opcode 0x0f b7 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t src = (uint16_t)LOAD_RM16(modrm); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVZX_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint32_t src = (uint16_t)READ16(ea); - STORE_REG32(modrm, src); - CYCLES(CYCLES_MOVZX_MEM_REG); - } -} - -void i386_device::i386_or_rm32_r32() // Opcode 0x09 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = OR32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = OR32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_or_r32_rm32() // Opcode 0x0b -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - dst = OR32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - dst = OR32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_or_eax_i32() // Opcode 0x0d -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - dst = OR32(dst, src); - REG32(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_out_eax_i8() // Opcode 0xe7 -{ - uint16_t port = FETCH(); - uint32_t data = REG32(EAX); - WRITEPORT32(port, data); - CYCLES(CYCLES_OUT_VAR); -} - -void i386_device::i386_out_eax_dx() // Opcode 0xef -{ - uint16_t port = REG16(DX); - uint32_t data = REG32(EAX); - WRITEPORT32(port, data); - CYCLES(CYCLES_OUT); -} - -void i386_device::i386_pop_eax() // Opcode 0x58 -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(EAX) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_ecx() // Opcode 0x59 -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(ECX) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_edx() // Opcode 0x5a -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(EDX) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_ebx() // Opcode 0x5b -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(EBX) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_esp() // Opcode 0x5c -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(ESP) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_ebp() // Opcode 0x5d -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(EBP) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_esi() // Opcode 0x5e -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(ESI) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -void i386_device::i386_pop_edi() // Opcode 0x5f -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - REG32(EDI) = POP32(); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_REG_SHORT); -} - -bool i386_device::i386_pop_seg32(int segment) -{ - uint32_t ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - uint32_t value; - bool fault; - if(i386_limit_check(SS,offset+3) == 0) - { - ea = i386_translate(SS, offset, 0); - value = READ32(ea); - i386_sreg_load(value, segment, &fault); - if(fault) return false; - if(STACK_32BIT) - REG32(ESP) = offset + 4; - else - REG16(SP) = offset + 4; - } - else - { - m_ext = 1; - i386_trap_with_error(FAULT_SS,0,0,0); - return false; - } - CYCLES(CYCLES_POP_SREG); - return true; -} - -void i386_device::i386_pop_ds32() // Opcode 0x1f -{ - i386_pop_seg32(DS); -} - -void i386_device::i386_pop_es32() // Opcode 0x07 -{ - i386_pop_seg32(ES); -} - -void i386_device::i386_pop_fs32() // Opcode 0x0f a1 -{ - i386_pop_seg32(FS); -} - -void i386_device::i386_pop_gs32() // Opcode 0x0f a9 -{ - i386_pop_seg32(GS); -} - -void i386_device::i386_pop_ss32() // Opcode 0x17 -{ - if(!i386_pop_seg32(SS)) return; - if(m_IF != 0) // if external interrupts are enabled - { - m_IF = 0; // reset IF for the next instruction - m_delayed_interrupt_enable = 1; - } -} - -void i386_device::i386_pop_rm32() // Opcode 0x8f -{ - uint8_t modrm = FETCH(); - uint32_t value; - uint32_t ea, offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+3) == 0) - { - // be careful here, if the write references the esp register - // it expects the post-pop value but esp must be wound back - // if the write faults - uint32_t temp_sp = REG32(ESP); - value = POP32(); - - if( modrm >= 0xc0 ) { - STORE_RM32(modrm, value); - } else { - try - { - ea = GetEA(modrm,1); - WRITE32(ea, value); - } - catch(uint64_t e) - { - REG32(ESP) = temp_sp; - throw e; - } - } - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POP_RM); -} - -void i386_device::i386_popad() // Opcode 0x61 -{ - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - if(i386_limit_check(SS,offset+31) == 0) - { - REG32(EDI) = POP32(); - REG32(ESI) = POP32(); - REG32(EBP) = POP32(); - REG32(ESP) += 4; - REG32(EBX) = POP32(); - REG32(EDX) = POP32(); - REG32(ECX) = POP32(); - REG32(EAX) = POP32(); - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POPA); -} - -void i386_device::i386_popfd() // Opcode 0x9d -{ - uint32_t value; - uint32_t current = get_flags(); - uint8_t IOPL = (current >> 12) & 0x03; - uint32_t mask = 0x00257fd5; // VM, VIP and VIF cannot be set by POPF/POPFD - uint32_t offset = (STACK_32BIT ? REG32(ESP) : REG16(SP)); - - // IOPL can only change if CPL is 0 - if(m_CPL != 0) - mask &= ~0x00003000; - - // IF can only change if CPL is at least as privileged as IOPL - if(m_CPL > IOPL) - mask &= ~0x00000200; - - if(V8086_MODE) - { - if(IOPL < 3) - { - logerror("POPFD(%08x): IOPL < 3 while in V86 mode.\n",m_pc); - FAULT(FAULT_GP,0) // #GP(0) - } - mask &= ~0x00003000; // IOPL cannot be changed while in V8086 mode - } - - if(i386_limit_check(SS,offset+3) == 0) - { - value = POP32(); - value &= ~0x00010000; // RF will always return zero - set_flags((current & ~mask) | (value & mask)); // mask out reserved bits - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_POPF); -} - -void i386_device::i386_push_eax() // Opcode 0x50 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(EAX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_ecx() // Opcode 0x51 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(ECX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_edx() // Opcode 0x52 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(EDX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_ebx() // Opcode 0x53 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(EBX) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_esp() // Opcode 0x54 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(ESP) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_ebp() // Opcode 0x55 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(EBP) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_esi() // Opcode 0x56 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(ESI) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_edi() // Opcode 0x57 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(REG32(EDI) ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_REG_SHORT); -} - -void i386_device::i386_push_cs32() // Opcode 0x0e -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32SEG(m_sreg[CS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_ds32() // Opcode 0x1e -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32SEG(m_sreg[DS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_es32() // Opcode 0x06 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32SEG(m_sreg[ES].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_fs32() // Opcode 0x0f a0 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32SEG(m_sreg[FS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_gs32() // Opcode 0x0f a8 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32SEG(m_sreg[GS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_ss32() // Opcode 0x16 -{ - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32SEG(m_sreg[SS].selector ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_SREG); -} - -void i386_device::i386_push_i32() // Opcode 0x68 -{ - uint32_t value = FETCH32(); - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(value); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSH_IMM); -} - -void i386_device::i386_pushad() // Opcode 0x60 -{ - uint32_t temp = REG32(ESP); - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 32; - else - offset = (REG16(SP) - 32) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - { - PUSH32(REG32(EAX) ); - PUSH32(REG32(ECX) ); - PUSH32(REG32(EDX) ); - PUSH32(REG32(EBX) ); - PUSH32(temp ); - PUSH32(REG32(EBP) ); - PUSH32(REG32(ESI) ); - PUSH32(REG32(EDI) ); - } - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSHA); -} - -void i386_device::i386_pushfd() // Opcode 0x9c -{ - if(!m_IOP1 && !m_IOP2 && V8086_MODE) - FAULT(FAULT_GP,0) - uint32_t offset; - if(STACK_32BIT) - offset = REG32(ESP) - 4; - else - offset = (REG16(SP) - 4) & 0xffff; - if(i386_limit_check(SS,offset) == 0) - PUSH32(get_flags() & 0x00fcffff ); - else - FAULT(FAULT_SS,0) - CYCLES(CYCLES_PUSHF); -} - -void i386_device::i386_ret_near32_i16() // Opcode 0xc2 -{ - int16_t disp = FETCH16(); - m_eip = POP32(); - REG32(ESP) += disp; - CHANGE_PC(m_eip); - CYCLES(CYCLES_RET_IMM); /* TODO: Timing = 10 + m */ -} - -void i386_device::i386_ret_near32() // Opcode 0xc3 -{ - m_eip = POP32(); - CHANGE_PC(m_eip); - CYCLES(CYCLES_RET); /* TODO: Timing = 10 + m */ -} - -void i386_device::i386_sbb_rm32_r32() // Opcode 0x19 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = SBB32(dst, src, m_CF); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = SBB32(dst, src, m_CF); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_sbb_r32_rm32() // Opcode 0x1b -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - dst = SBB32(dst, src, m_CF); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - dst = SBB32(dst, src, m_CF); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_sbb_eax_i32() // Opcode 0x1d -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - dst = SBB32(dst, src, m_CF); - REG32(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_scasd() // Opcode 0xaf -{ - uint32_t eas, src, dst; - eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 ); - src = READ32(eas); - dst = REG32(EAX); - SUB32(dst, src); - BUMP_DI(4); - CYCLES(CYCLES_SCAS); -} - -void i386_device::i386_shld32_i8() // Opcode 0x0f a4 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (32-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 31); - SetSZPF32(dst); - } - STORE_RM32(modrm, dst); - CYCLES(CYCLES_SHLD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (32-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 31); - SetSZPF32(dst); - } - WRITE32(ea, dst); - CYCLES(CYCLES_SHLD_MEM); - } -} - -void i386_device::i386_shld32_cl() // Opcode 0x0f a5 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (32-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 31); - SetSZPF32(dst); - } - STORE_RM32(modrm, dst); - CYCLES(CYCLES_SHLD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (32-shift))) ? 1 : 0; - dst = (dst << shift) | (upper >> (32-shift)); - m_OF = m_CF ^ (dst >> 31); - SetSZPF32(dst); - } - WRITE32(ea, dst); - CYCLES(CYCLES_SHLD_MEM); - } -} - -void i386_device::i386_shrd32_i8() // Opcode 0x0f ac -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (32-shift)); - m_OF = ((dst >> 31) ^ (dst >> 30)) & 1; - SetSZPF32(dst); - } - STORE_RM32(modrm, dst); - CYCLES(CYCLES_SHRD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = FETCH(); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (32-shift)); - m_OF = ((dst >> 31) ^ (dst >> 30)) & 1; - SetSZPF32(dst); - } - WRITE32(ea, dst); - CYCLES(CYCLES_SHRD_MEM); - } -} - -void i386_device::i386_shrd32_cl() // Opcode 0x0f ad -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (32-shift)); - m_OF = ((dst >> 31) ^ (dst >> 30)) & 1; - SetSZPF32(dst); - } - STORE_RM32(modrm, dst); - CYCLES(CYCLES_SHRD_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint32_t upper = LOAD_REG32(modrm); - uint8_t shift = REG8(CL); - shift &= 31; - if( shift == 0 ) { - } else { - m_CF = (dst & (1 << (shift-1))) ? 1 : 0; - dst = (dst >> shift) | (upper << (32-shift)); - m_OF = ((dst >> 31) ^ (dst >> 30)) & 1; - SetSZPF32(dst); - } - WRITE32(ea, dst); - CYCLES(CYCLES_SHRD_MEM); - } -} - -void i386_device::i386_stosd() // Opcode 0xab -{ - uint32_t eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 ); - WRITE32(eas, REG32(EAX)); - BUMP_DI(4); - CYCLES(CYCLES_STOS); -} - -void i386_device::i386_sub_rm32_r32() // Opcode 0x29 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = SUB32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = SUB32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_sub_r32_rm32() // Opcode 0x2b -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - dst = SUB32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - dst = SUB32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_sub_eax_i32() // Opcode 0x2d -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - dst = SUB32(dst, src); - REG32(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_test_eax_i32() // Opcode 0xa9 -{ - uint32_t src = FETCH32(); - uint32_t dst = REG32(EAX); - dst = src & dst; - SetSZPF32(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_IMM_ACC); -} - -void i386_device::i386_test_rm32_r32() // Opcode 0x85 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = src & dst; - SetSZPF32(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = src & dst; - SetSZPF32(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_REG_MEM); - } -} - -void i386_device::i386_xchg_eax_ecx() // Opcode 0x91 -{ - uint32_t temp; - temp = REG32(EAX); - REG32(EAX) = REG32(ECX); - REG32(ECX) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_eax_edx() // Opcode 0x92 -{ - uint32_t temp; - temp = REG32(EAX); - REG32(EAX) = REG32(EDX); - REG32(EDX) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_eax_ebx() // Opcode 0x93 -{ - uint32_t temp; - temp = REG32(EAX); - REG32(EAX) = REG32(EBX); - REG32(EBX) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_eax_esp() // Opcode 0x94 -{ - uint32_t temp; - temp = REG32(EAX); - REG32(EAX) = REG32(ESP); - REG32(ESP) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_eax_ebp() // Opcode 0x95 -{ - uint32_t temp; - temp = REG32(EAX); - REG32(EAX) = REG32(EBP); - REG32(EBP) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_eax_esi() // Opcode 0x96 -{ - uint32_t temp; - temp = REG32(EAX); - REG32(EAX) = REG32(ESI); - REG32(ESI) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_eax_edi() // Opcode 0x97 -{ - uint32_t temp; - temp = REG32(EAX); - REG32(EAX) = REG32(EDI); - REG32(EDI) = temp; - CYCLES(CYCLES_XCHG_REG_REG); -} - -void i386_device::i386_xchg_r32_rm32() // Opcode 0x87 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t src = LOAD_RM32(modrm); - uint32_t dst = LOAD_REG32(modrm); - STORE_REG32(modrm, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_XCHG_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t src = READ32(ea); - uint32_t dst = LOAD_REG32(modrm); - WRITE32(ea, dst); - STORE_REG32(modrm, src); - CYCLES(CYCLES_XCHG_REG_MEM); - } -} - -void i386_device::i386_xor_rm32_r32() // Opcode 0x31 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG32(modrm); - dst = LOAD_RM32(modrm); - dst = XOR32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG32(modrm); - dst = READ32(ea); - dst = XOR32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_xor_r32_rm32() // Opcode 0x33 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - dst = LOAD_REG32(modrm); - dst = XOR32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - dst = LOAD_REG32(modrm); - dst = XOR32(dst, src); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_xor_eax_i32() // Opcode 0x35 -{ - uint32_t src, dst; - src = FETCH32(); - dst = REG32(EAX); - dst = XOR32(dst, src); - REG32(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - - - -void i386_device::i386_group81_32() // Opcode 0x81 -{ - uint32_t ea; - uint32_t src, dst; - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: // ADD Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - dst = ADD32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = FETCH32(); - dst = ADD32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 1: // OR Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - dst = OR32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = FETCH32(); - dst = OR32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 2: // ADC Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - dst = ADC32(dst, src, m_CF); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = FETCH32(); - dst = ADC32(dst, src, m_CF); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 3: // SBB Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - dst = SBB32(dst, src, m_CF); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = FETCH32(); - dst = SBB32(dst, src, m_CF); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 4: // AND Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - dst = AND32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = FETCH32(); - dst = AND32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 5: // SUB Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - dst = SUB32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = FETCH32(); - dst = SUB32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 6: // XOR Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - dst = XOR32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = FETCH32(); - dst = XOR32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 7: // CMP Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = FETCH32(); - SUB32(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - ea = GetEA(modrm,0); - dst = READ32(ea); - src = FETCH32(); - SUB32(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } - break; - } -} - -void i386_device::i386_group83_32() // Opcode 0x83 -{ - uint32_t ea; - uint32_t src, dst; - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: // ADD Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = ADD32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = ADD32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 1: // OR Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = OR32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = OR32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 2: // ADC Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = ADC32(dst, src, m_CF); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = ADC32(dst, src, m_CF); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 3: // SBB Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = ((uint32_t)(int32_t)(int8_t)FETCH()); - dst = SBB32(dst, src, m_CF); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = ((uint32_t)(int32_t)(int8_t)FETCH()); - dst = SBB32(dst, src, m_CF); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 4: // AND Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = AND32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = AND32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 5: // SUB Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = SUB32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = SUB32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 6: // XOR Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = XOR32(dst, src); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ32(ea); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - dst = XOR32(dst, src); - WRITE32(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 7: // CMP Rm32, i32 - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - SUB32(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - ea = GetEA(modrm,0); - dst = READ32(ea); - src = (uint32_t)(int32_t)(int8_t)FETCH(); - SUB32(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } - break; - } -} - -void i386_device::i386_groupC1_32() // Opcode 0xc1 -{ - uint32_t dst; - uint8_t modrm = FETCH(); - uint8_t shift; - - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - shift = FETCH() & 0x1f; - dst = i386_shift_rotate32(modrm, dst, shift); - STORE_RM32(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ32(ea); - shift = FETCH() & 0x1f; - dst = i386_shift_rotate32(modrm, dst, shift); - WRITE32(ea, dst); - } -} - -void i386_device::i386_groupD1_32() // Opcode 0xd1 -{ - uint32_t dst; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - dst = i386_shift_rotate32(modrm, dst, 1); - STORE_RM32(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ32(ea); - dst = i386_shift_rotate32(modrm, dst, 1); - WRITE32(ea, dst); - } -} - -void i386_device::i386_groupD3_32() // Opcode 0xd3 -{ - uint32_t dst; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - dst = LOAD_RM32(modrm); - dst = i386_shift_rotate32(modrm, dst, REG8(CL)); - STORE_RM32(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ32(ea); - dst = i386_shift_rotate32(modrm, dst, REG8(CL)); - WRITE32(ea, dst); - } -} - -void i386_device::i386_groupF7_32() // Opcode 0xf7 -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* TEST Rm32, i32 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t src = FETCH32(); - dst &= src; - m_CF = m_OF = m_AF = 0; - SetSZPF32(dst); - CYCLES(CYCLES_TEST_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint32_t dst = READ32(ea); - uint32_t src = FETCH32(); - dst &= src; - m_CF = m_OF = m_AF = 0; - SetSZPF32(dst); - CYCLES(CYCLES_TEST_IMM_MEM); - } - break; - case 2: /* NOT Rm32 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - dst = ~dst; - STORE_RM32(modrm, dst); - CYCLES(CYCLES_NOT_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - dst = ~dst; - WRITE32(ea, dst); - CYCLES(CYCLES_NOT_MEM); - } - break; - case 3: /* NEG Rm32 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - dst = SUB32(0, dst ); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_NEG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - dst = SUB32(0, dst ); - WRITE32(ea, dst); - CYCLES(CYCLES_NEG_MEM); - } - break; - case 4: /* MUL EAX, Rm32 */ - { - uint64_t result; - uint32_t src, dst; - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - CYCLES(CYCLES_MUL32_ACC_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - CYCLES(CYCLES_MUL32_ACC_MEM); /* TODO: Correct multiply timing */ - } - - dst = REG32(EAX); - result = (uint64_t)src * (uint64_t)dst; - REG32(EDX) = (uint32_t)(result >> 32); - REG32(EAX) = (uint32_t)result; - - m_CF = m_OF = (REG32(EDX) != 0); - } - break; - case 5: /* IMUL EAX, Rm32 */ - { - int64_t result; - int64_t src, dst; - if( modrm >= 0xc0 ) { - src = (int64_t)(int32_t)LOAD_RM32(modrm); - CYCLES(CYCLES_IMUL32_ACC_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = (int64_t)(int32_t)READ32(ea); - CYCLES(CYCLES_IMUL32_ACC_MEM); /* TODO: Correct multiply timing */ - } - - dst = (int64_t)(int32_t)REG32(EAX); - result = src * dst; - - REG32(EDX) = (uint32_t)(result >> 32); - REG32(EAX) = (uint32_t)result; - - m_CF = m_OF = !(result == (int64_t)(int32_t)result); - } - break; - case 6: /* DIV EAX, Rm32 */ - { - uint64_t quotient, remainder, result; - uint32_t src; - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - CYCLES(CYCLES_DIV32_ACC_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - CYCLES(CYCLES_DIV32_ACC_MEM); - } - - quotient = ((uint64_t)(REG32(EDX)) << 32) | (uint64_t)(REG32(EAX)); - if( src ) { - remainder = quotient % (uint64_t)src; - result = quotient / (uint64_t)src; - if( result > 0xffffffff ) { - /* TODO: Divide error */ - } else { - REG32(EDX) = (uint32_t)remainder; - REG32(EAX) = (uint32_t)result; - } - } else { - i386_trap(0, 0, 0); - } - } - break; - case 7: /* IDIV EAX, Rm32 */ - { - int64_t quotient, remainder, result; - uint32_t src; - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - CYCLES(CYCLES_IDIV32_ACC_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - CYCLES(CYCLES_IDIV32_ACC_MEM); - } - - quotient = (((int64_t)REG32(EDX)) << 32) | ((uint64_t)REG32(EAX)); - if( src ) { - remainder = quotient % (int64_t)(int32_t)src; - result = quotient / (int64_t)(int32_t)src; - if( result > 0xffffffff ) { - /* TODO: Divide error */ - } else { - REG32(EDX) = (uint32_t)remainder; - REG32(EAX) = (uint32_t)result; - } - } else { - i386_trap(0, 0, 0); - } - } - break; - } -} - -void i386_device::i386_groupFF_32() // Opcode 0xff -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* INC Rm32 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - dst = INC32(dst); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_INC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - dst = INC32(dst); - WRITE32(ea, dst); - CYCLES(CYCLES_INC_MEM); - } - break; - case 1: /* DEC Rm32 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - dst = DEC32(dst); - STORE_RM32(modrm, dst); - CYCLES(CYCLES_DEC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - dst = DEC32(dst); - WRITE32(ea, dst); - CYCLES(CYCLES_DEC_MEM); - } - break; - case 2: /* CALL Rm32 */ - { - uint32_t address; - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - CYCLES(CYCLES_CALL_REG); /* TODO: Timing = 7 + m */ - } else { - uint32_t ea = GetEA(modrm,0); - address = READ32(ea); - CYCLES(CYCLES_CALL_MEM); /* TODO: Timing = 10 + m */ - } - PUSH32(m_eip ); - m_eip = address; - CHANGE_PC(m_eip); - } - break; - case 3: /* CALL FAR Rm32 */ - { - uint16_t selector; - uint32_t address; - - if( modrm >= 0xc0 ) - { - report_invalid_modrm("groupFF_32", modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - address = READ32(ea + 0); - selector = READ16(ea + 4); - CYCLES(CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */ - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_call(selector,address,1,1); - } - else - { - PUSH32SEG(m_sreg[CS].selector ); - PUSH32(m_eip ); - m_sreg[CS].selector = selector; - m_performed_intersegment_jump = 1; - i386_load_segment_descriptor(CS ); - m_eip = address; - CHANGE_PC(m_eip); - } - } - } - break; - case 4: /* JMP Rm32 */ - { - uint32_t address; - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - CYCLES(CYCLES_JMP_REG); /* TODO: Timing = 7 + m */ - } else { - uint32_t ea = GetEA(modrm,0); - address = READ32(ea); - CYCLES(CYCLES_JMP_MEM); /* TODO: Timing = 10 + m */ - } - m_eip = address; - CHANGE_PC(m_eip); - } - break; - case 5: /* JMP FAR Rm32 */ - { - uint16_t selector; - uint32_t address; - - if( modrm >= 0xc0 ) - { - report_invalid_modrm("groupFF_32", modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - address = READ32(ea + 0); - selector = READ16(ea + 4); - CYCLES(CYCLES_JMP_MEM_INTERSEG); /* TODO: Timing = 10 + m */ - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_jump(selector,address,1,1); - } - else - { - m_sreg[CS].selector = selector; - m_performed_intersegment_jump = 1; - i386_load_segment_descriptor(CS ); - m_eip = address; - CHANGE_PC(m_eip); - } - } - } - break; - case 6: /* PUSH Rm32 */ - { - uint32_t value; - if( modrm >= 0xc0 ) { - value = LOAD_RM32(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - value = READ32(ea); - } - PUSH32(value); - CYCLES(CYCLES_PUSH_RM); - } - break; - default: - report_invalid_modrm("groupFF_32", modrm); - break; - } -} - -void i386_device::i386_group0F00_32() // Opcode 0x0f 00 -{ - uint32_t address, ea; - uint8_t modrm = FETCH(); - I386_SREG seg; - uint8_t result; - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* SLDT */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if( modrm >= 0xc0 ) { - STORE_RM32(modrm, m_ldtr.segment); - CYCLES(CYCLES_SLDT_REG); - } else { - ea = GetEA(modrm,1); - WRITE16(ea, m_ldtr.segment); - CYCLES(CYCLES_SLDT_MEM); - } - } - else - { - i386_trap(6, 0, 0); - } - break; - case 1: /* STR */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if( modrm >= 0xc0 ) { - STORE_RM32(modrm, m_task.segment); - CYCLES(CYCLES_STR_REG); - } else { - ea = GetEA(modrm,1); - WRITE16(ea, m_task.segment); - CYCLES(CYCLES_STR_MEM); - } - } - else - { - i386_trap(6, 0, 0); - } - break; - case 2: /* LLDT */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if(m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - m_ldtr.segment = address; - CYCLES(CYCLES_LLDT_REG); - } else { - ea = GetEA(modrm,0); - m_ldtr.segment = READ32(ea); - CYCLES(CYCLES_LLDT_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = m_ldtr.segment; - i386_load_protected_mode_segment(&seg,nullptr); - m_ldtr.limit = seg.limit; - m_ldtr.base = seg.base; - m_ldtr.flags = seg.flags; - } - else - { - i386_trap(6, 0, 0); - } - break; - - case 3: /* LTR */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if(m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - m_task.segment = address; - CYCLES(CYCLES_LTR_REG); - } else { - ea = GetEA(modrm,0); - m_task.segment = READ32(ea); - CYCLES(CYCLES_LTR_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = m_task.segment; - i386_load_protected_mode_segment(&seg,nullptr); - - uint32_t addr = ((seg.selector & 4) ? m_ldtr.base : m_gdtr.base) + (seg.selector & ~7) + 5; - i386_translate_address(TRANSLATE_READ, &addr, nullptr); - m_program->write_byte(addr, (seg.flags & 0xff) | 2); - - m_task.limit = seg.limit; - m_task.base = seg.base; - m_task.flags = seg.flags | 2; - } - else - { - i386_trap(6, 0, 0); - } - break; - - case 4: /* VERR */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - CYCLES(CYCLES_VERR_REG); - } else { - ea = GetEA(modrm,0); - address = READ32(ea); - CYCLES(CYCLES_VERR_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = address; - result = i386_load_protected_mode_segment(&seg,nullptr); - // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...) - if(!(seg.flags & 0x10)) - result = 0; - // check that the segment is readable - if(seg.flags & 0x10) // is code or data segment - { - if(seg.flags & 0x08) // is code segment, so check if it's readable - { - if(!(seg.flags & 0x02)) - { - result = 0; - } - else - { // check if conforming, these are always readable, regardless of privilege - if(!(seg.flags & 0x04)) - { - // if not conforming, then we must check privilege levels (TODO: current privilege level check) - if(((seg.flags >> 5) & 0x03) < (address & 0x03)) - result = 0; - } - } - } - } - // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO) - SetZF(result); - } - else - { - i386_trap(6, 0, 0); - logerror("i386: VERR: Exception - Running in real mode or virtual 8086 mode.\n"); - } - break; - - case 5: /* VERW */ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - CYCLES(CYCLES_VERW_REG); - } else { - ea = GetEA(modrm,0); - address = READ16(ea); - CYCLES(CYCLES_VERW_MEM); - } - memset(&seg, 0, sizeof(seg)); - seg.selector = address; - result = i386_load_protected_mode_segment(&seg,nullptr); - // check if the segment is a code or data segment (not a special segment type, like a TSS, gate, LDT...) - if(!(seg.flags & 0x10)) - result = 0; - // check that the segment is writable - if(seg.flags & 0x10) // is code or data segment - { - if(seg.flags & 0x08) // is code segment (and thus, not writable) - { - result = 0; - } - else - { // is data segment - if(!(seg.flags & 0x02)) - result = 0; - } - } - // check that the descriptor privilege is greater or equal to the selector's privilege level and the current privilege (TODO) - if(((seg.flags >> 5) & 0x03) < (address & 0x03)) - result = 0; - SetZF(result); - } - else - { - i386_trap(6, 0, 0); - logerror("i386: VERW: Exception - Running in real mode or virtual 8086 mode.\n"); - } - break; - - default: - report_invalid_modrm("group0F00_32", modrm); - break; - } -} - -void i386_device::i386_group0F01_32() // Opcode 0x0f 01 -{ - uint8_t modrm = FETCH(); - uint32_t address, ea; - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* SGDT */ - { - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - ea = i386_translate(CS, address, 1 ); - } else { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_gdtr.limit); - WRITE32(ea + 2, m_gdtr.base); - CYCLES(CYCLES_SGDT); - break; - } - case 1: /* SIDT */ - { - if (modrm >= 0xc0) - { - address = LOAD_RM32(modrm); - ea = i386_translate(CS, address, 1 ); - } - else - { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_idtr.limit); - WRITE32(ea + 2, m_idtr.base); - CYCLES(CYCLES_SIDT); - break; - } - case 2: /* LGDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - ea = i386_translate(CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_gdtr.limit = READ16(ea); - m_gdtr.base = READ32(ea + 2); - CYCLES(CYCLES_LGDT); - break; - } - case 3: /* LIDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - ea = i386_translate(CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_idtr.limit = READ16(ea); - m_idtr.base = READ32(ea + 2); - CYCLES(CYCLES_LIDT); - break; - } - case 4: /* SMSW */ - { - if( modrm >= 0xc0 ) { - // smsw stores all of cr0 into register - STORE_RM32(modrm, m_cr[0]); - CYCLES(CYCLES_SMSW_REG); - } else { - /* always 16-bit memory operand */ - ea = GetEA(modrm,1); - WRITE16(ea, m_cr[0]); - CYCLES(CYCLES_SMSW_MEM); - } - break; - } - case 6: /* LMSW */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - uint16_t b; - if( modrm >= 0xc0 ) { - b = LOAD_RM16(modrm); - CYCLES(CYCLES_LMSW_REG); - } else { - ea = GetEA(modrm,0); - CYCLES(CYCLES_LMSW_MEM); - b = READ16(ea); - } - if(PROTECTED_MODE) - b |= 0x0001; // cannot return to real mode using this instruction. - m_cr[0] &= ~0x0000000f; - m_cr[0] |= b & 0x0000000f; - break; - } - default: - report_invalid_modrm("group0F01_32", modrm); - break; - } -} - -void i386_device::i386_group0FBA_32() // Opcode 0x0f ba -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 4: /* BT Rm32, i8 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint32_t dst = READ32(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - - CYCLES(CYCLES_BT_IMM_MEM); - } - break; - case 5: /* BTS Rm32, i8 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << bit); - - STORE_RM32(modrm, dst); - CYCLES(CYCLES_BTS_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst |= (1 << bit); - - WRITE32(ea, dst); - CYCLES(CYCLES_BTS_IMM_MEM); - } - break; - case 6: /* BTR Rm32, i8 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << bit); - - STORE_RM32(modrm, dst); - CYCLES(CYCLES_BTR_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst &= ~(1 << bit); - - WRITE32(ea, dst); - CYCLES(CYCLES_BTR_IMM_MEM); - } - break; - case 7: /* BTC Rm32, i8 */ - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << bit); - - STORE_RM32(modrm, dst); - CYCLES(CYCLES_BTC_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint8_t bit = FETCH(); - - if( dst & (1 << bit) ) - m_CF = 1; - else - m_CF = 0; - dst ^= (1 << bit); - - WRITE32(ea, dst); - CYCLES(CYCLES_BTC_IMM_MEM); - } - break; - default: - report_invalid_modrm("group0FBA_32", modrm); - break; - } -} - -void i386_device::i386_lar_r32_rm32() // Opcode 0x0f 0x02 -{ - uint8_t modrm = FETCH(); - I386_SREG seg; - uint8_t type; - - if(PROTECTED_MODE && !V8086_MODE) - { - memset(&seg,0,sizeof(seg)); - if(modrm >= 0xc0) - { - seg.selector = LOAD_RM32(modrm); - CYCLES(CYCLES_LAR_REG); - } - else - { - uint32_t ea = GetEA(modrm,0); - seg.selector = READ32(ea); - CYCLES(CYCLES_LAR_MEM); - } - if(seg.selector == 0) - { - SetZF(0); // not a valid segment - } - else - { - uint64_t desc; - if(!i386_load_protected_mode_segment(&seg,&desc)) - { - SetZF(0); - return; - } - uint8_t DPL = (seg.flags >> 5) & 3; - if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c)) - { - SetZF(0); - return; - } - if(!(seg.flags & 0x10)) // special segment - { - // check for invalid segment types - type = seg.flags & 0x000f; - if(type == 0x00 || type == 0x08 || type == 0x0a || type == 0x0d) - { - SetZF(0); // invalid segment type - } - else - { - STORE_REG32(modrm,(desc>>32) & 0x00ffff00); - SetZF(1); - } - } - else - { - STORE_REG32(modrm,(desc>>32) & 0x00ffff00); - SetZF(1); - } - } - } - else - { - // illegal opcode - i386_trap(6,0, 0); - logerror("i386: LAR: Exception - running in real mode or virtual 8086 mode.\n"); - } -} - -void i386_device::i386_lsl_r32_rm32() // Opcode 0x0f 0x03 -{ - uint8_t modrm = FETCH(); - uint32_t limit; - I386_SREG seg; - - if(PROTECTED_MODE && !V8086_MODE) - { - memset(&seg, 0, sizeof(seg)); - if(modrm >= 0xc0) - { - seg.selector = LOAD_RM32(modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - seg.selector = READ32(ea); - } - if(seg.selector == 0) - { - SetZF(0); // not a valid segment - } - else - { - uint8_t type; - if(!i386_load_protected_mode_segment(&seg,nullptr)) - { - SetZF(0); - return; - } - uint8_t DPL = (seg.flags >> 5) & 3; - if(((DPL < m_CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c)) - { - SetZF(0); - return; - } - type = seg.flags & 0x1f; - switch(type) - { - case 0: - case 4: - case 5: - case 6: - case 7: - case 8: - case 10: - case 12: - case 13: - case 14: - case 15: - SetZF(0); - return; - default: - limit = seg.limit; - STORE_REG32(modrm,limit); - SetZF(1); - } - } - } - else - i386_trap(6, 0, 0); -} - -void i386_device::i386_bound_r32_m32_m32() // Opcode 0x62 -{ - uint8_t modrm; - int32_t val, low, high; - - modrm = FETCH(); - - if (modrm >= 0xc0) - { - low = high = LOAD_RM32(modrm); - } - else - { - uint32_t ea = GetEA(modrm,0); - low = READ32(ea + 0); - high = READ32(ea + 4); - } - val = LOAD_REG32(modrm); - - if ((val < low) || (val > high)) - { - CYCLES(CYCLES_BOUND_OUT_RANGE); - i386_trap(5, 0, 0); - } - else - { - CYCLES(CYCLES_BOUND_IN_RANGE); - } -} - -void i386_device::i386_retf32() // Opcode 0xcb -{ - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_retf(0,1); - } - else - { - m_eip = POP32(); - m_sreg[CS].selector = POP32(); - i386_load_segment_descriptor(CS ); - CHANGE_PC(m_eip); - } - - CYCLES(CYCLES_RET_INTERSEG); -} - -void i386_device::i386_retf_i32() // Opcode 0xca -{ - uint16_t count = FETCH16(); - - if(PROTECTED_MODE && !V8086_MODE) - { - i386_protected_mode_retf(count,1); - } - else - { - m_eip = POP32(); - m_sreg[CS].selector = POP32(); - i386_load_segment_descriptor(CS ); - CHANGE_PC(m_eip); - REG32(ESP) += count; - } - - CYCLES(CYCLES_RET_IMM_INTERSEG); -} - -void i386_device::i386_load_far_pointer32(int s) -{ - uint8_t modrm = FETCH(); - uint16_t selector; - - if( modrm >= 0xc0 ) { - report_invalid_modrm("load_far_pointer32", modrm); - } else { - uint32_t ea = GetEA(modrm,0); - STORE_REG32(modrm, READ32(ea + 0)); - selector = READ16(ea + 4); - i386_sreg_load(selector,s,nullptr); - } -} - -void i386_device::i386_lds32() // Opcode 0xc5 -{ - i386_load_far_pointer32(DS); - CYCLES(CYCLES_LDS); -} - -void i386_device::i386_lss32() // Opcode 0x0f 0xb2 -{ - i386_load_far_pointer32(SS); - CYCLES(CYCLES_LSS); -} - -void i386_device::i386_les32() // Opcode 0xc4 -{ - i386_load_far_pointer32(ES); - CYCLES(CYCLES_LES); -} - -void i386_device::i386_lfs32() // Opcode 0x0f 0xb4 -{ - i386_load_far_pointer32(FS); - CYCLES(CYCLES_LFS); -} - -void i386_device::i386_lgs32() // Opcode 0x0f 0xb5 -{ - i386_load_far_pointer32(GS); - CYCLES(CYCLES_LGS); -} diff --git a/source/src/vm/libcpu_newdev/i386/i386ops.h b/source/src/vm/libcpu_newdev/i386/i386ops.h deleted file mode 100644 index 372b3127d..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386ops.h +++ /dev/null @@ -1,877 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -#define OP_I386 0x1 -#define OP_FPU 0x2 -#define OP_I486 0x4 -#define OP_PENTIUM 0x8 -#define OP_MMX 0x10 -#define OP_PPRO 0x20 -#define OP_SSE 0x40 -#define OP_SSE2 0x80 -#define OP_SSE3 0x100 -#define OP_CYRIX 0x8000 -#define OP_2BYTE 0x80000000 -#define OP_3BYTE66 0x40000000 -#define OP_3BYTEF2 0x20000000 -#define OP_3BYTEF3 0x10000000 -#define OP_3BYTE38 0x08000000 -#define OP_3BYTE3A 0x04000000 -#define OP_4BYTE3866 0x02000000 -#define OP_4BYTE3A66 0x01000000 -#define OP_4BYTE38F2 0x00800000 -#define OP_4BYTE3AF2 0x00400000 -#define OP_4BYTE38F3 0x00200000 - -const i386_device::X86_OPCODE i386_device::s_x86_opcode_table[] = -{ -// Opcode Flags 16-bit handler 32-bit handler - { 0x00, OP_I386, &i386_device::i386_add_rm8_r8, &i386_device::i386_add_rm8_r8, true }, - { 0x01, OP_I386, &i386_device::i386_add_rm16_r16, &i386_device::i386_add_rm32_r32, true }, - { 0x02, OP_I386, &i386_device::i386_add_r8_rm8, &i386_device::i386_add_r8_rm8, false}, - { 0x03, OP_I386, &i386_device::i386_add_r16_rm16, &i386_device::i386_add_r32_rm32, false}, - { 0x04, OP_I386, &i386_device::i386_add_al_i8, &i386_device::i386_add_al_i8, false}, - { 0x05, OP_I386, &i386_device::i386_add_ax_i16, &i386_device::i386_add_eax_i32, false}, - { 0x06, OP_I386, &i386_device::i386_push_es16, &i386_device::i386_push_es32, false}, - { 0x07, OP_I386, &i386_device::i386_pop_es16, &i386_device::i386_pop_es32, false}, - { 0x08, OP_I386, &i386_device::i386_or_rm8_r8, &i386_device::i386_or_rm8_r8, true }, - { 0x09, OP_I386, &i386_device::i386_or_rm16_r16, &i386_device::i386_or_rm32_r32, true }, - { 0x0A, OP_I386, &i386_device::i386_or_r8_rm8, &i386_device::i386_or_r8_rm8, false}, - { 0x0B, OP_I386, &i386_device::i386_or_r16_rm16, &i386_device::i386_or_r32_rm32, false}, - { 0x0C, OP_I386, &i386_device::i386_or_al_i8, &i386_device::i386_or_al_i8, false}, - { 0x0D, OP_I386, &i386_device::i386_or_ax_i16, &i386_device::i386_or_eax_i32, false}, - { 0x0E, OP_I386, &i386_device::i386_push_cs16, &i386_device::i386_push_cs32, false}, - { 0x0F, OP_I386, &i386_device::i386_decode_two_byte, &i386_device::i386_decode_two_byte, true }, - { 0x10, OP_I386, &i386_device::i386_adc_rm8_r8, &i386_device::i386_adc_rm8_r8, true }, - { 0x11, OP_I386, &i386_device::i386_adc_rm16_r16, &i386_device::i386_adc_rm32_r32, true }, - { 0x12, OP_I386, &i386_device::i386_adc_r8_rm8, &i386_device::i386_adc_r8_rm8, false}, - { 0x13, OP_I386, &i386_device::i386_adc_r16_rm16, &i386_device::i386_adc_r32_rm32, false}, - { 0x14, OP_I386, &i386_device::i386_adc_al_i8, &i386_device::i386_adc_al_i8, false}, - { 0x15, OP_I386, &i386_device::i386_adc_ax_i16, &i386_device::i386_adc_eax_i32, false}, - { 0x16, OP_I386, &i386_device::i386_push_ss16, &i386_device::i386_push_ss32, false}, - { 0x17, OP_I386, &i386_device::i386_pop_ss16, &i386_device::i386_pop_ss32, false}, - { 0x18, OP_I386, &i386_device::i386_sbb_rm8_r8, &i386_device::i386_sbb_rm8_r8, true }, - { 0x19, OP_I386, &i386_device::i386_sbb_rm16_r16, &i386_device::i386_sbb_rm32_r32, true }, - { 0x1A, OP_I386, &i386_device::i386_sbb_r8_rm8, &i386_device::i386_sbb_r8_rm8, false}, - { 0x1B, OP_I386, &i386_device::i386_sbb_r16_rm16, &i386_device::i386_sbb_r32_rm32, false}, - { 0x1C, OP_I386, &i386_device::i386_sbb_al_i8, &i386_device::i386_sbb_al_i8, false}, - { 0x1D, OP_I386, &i386_device::i386_sbb_ax_i16, &i386_device::i386_sbb_eax_i32, false}, - { 0x1E, OP_I386, &i386_device::i386_push_ds16, &i386_device::i386_push_ds32, false}, - { 0x1F, OP_I386, &i386_device::i386_pop_ds16, &i386_device::i386_pop_ds32, false}, - { 0x20, OP_I386, &i386_device::i386_and_rm8_r8, &i386_device::i386_and_rm8_r8, true }, - { 0x21, OP_I386, &i386_device::i386_and_rm16_r16, &i386_device::i386_and_rm32_r32, true }, - { 0x22, OP_I386, &i386_device::i386_and_r8_rm8, &i386_device::i386_and_r8_rm8, false}, - { 0x23, OP_I386, &i386_device::i386_and_r16_rm16, &i386_device::i386_and_r32_rm32, false}, - { 0x24, OP_I386, &i386_device::i386_and_al_i8, &i386_device::i386_and_al_i8, false}, - { 0x25, OP_I386, &i386_device::i386_and_ax_i16, &i386_device::i386_and_eax_i32, false}, - { 0x26, OP_I386, &i386_device::i386_segment_ES, &i386_device::i386_segment_ES, true}, - { 0x27, OP_I386, &i386_device::i386_daa, &i386_device::i386_daa, false}, - { 0x28, OP_I386, &i386_device::i386_sub_rm8_r8, &i386_device::i386_sub_rm8_r8, true }, - { 0x29, OP_I386, &i386_device::i386_sub_rm16_r16, &i386_device::i386_sub_rm32_r32, true }, - { 0x2A, OP_I386, &i386_device::i386_sub_r8_rm8, &i386_device::i386_sub_r8_rm8, false}, - { 0x2B, OP_I386, &i386_device::i386_sub_r16_rm16, &i386_device::i386_sub_r32_rm32, false}, - { 0x2C, OP_I386, &i386_device::i386_sub_al_i8, &i386_device::i386_sub_al_i8, false}, - { 0x2D, OP_I386, &i386_device::i386_sub_ax_i16, &i386_device::i386_sub_eax_i32, false}, - { 0x2E, OP_I386, &i386_device::i386_segment_CS, &i386_device::i386_segment_CS, true}, - { 0x2F, OP_I386, &i386_device::i386_das, &i386_device::i386_das, false}, - { 0x30, OP_I386, &i386_device::i386_xor_rm8_r8, &i386_device::i386_xor_rm8_r8, true }, - { 0x31, OP_I386, &i386_device::i386_xor_rm16_r16, &i386_device::i386_xor_rm32_r32, true }, - { 0x32, OP_I386, &i386_device::i386_xor_r8_rm8, &i386_device::i386_xor_r8_rm8, false}, - { 0x33, OP_I386, &i386_device::i386_xor_r16_rm16, &i386_device::i386_xor_r32_rm32, false}, - { 0x34, OP_I386, &i386_device::i386_xor_al_i8, &i386_device::i386_xor_al_i8, false}, - { 0x35, OP_I386, &i386_device::i386_xor_ax_i16, &i386_device::i386_xor_eax_i32, false}, - { 0x36, OP_I386, &i386_device::i386_segment_SS, &i386_device::i386_segment_SS, true}, - { 0x37, OP_I386, &i386_device::i386_aaa, &i386_device::i386_aaa, false}, - { 0x38, OP_I386, &i386_device::i386_cmp_rm8_r8, &i386_device::i386_cmp_rm8_r8, false}, - { 0x39, OP_I386, &i386_device::i386_cmp_rm16_r16, &i386_device::i386_cmp_rm32_r32, false}, - { 0x3A, OP_I386, &i386_device::i386_cmp_r8_rm8, &i386_device::i386_cmp_r8_rm8, false}, - { 0x3B, OP_I386, &i386_device::i386_cmp_r16_rm16, &i386_device::i386_cmp_r32_rm32, false}, - { 0x3C, OP_I386, &i386_device::i386_cmp_al_i8, &i386_device::i386_cmp_al_i8, false}, - { 0x3D, OP_I386, &i386_device::i386_cmp_ax_i16, &i386_device::i386_cmp_eax_i32, false}, - { 0x3E, OP_I386, &i386_device::i386_segment_DS, &i386_device::i386_segment_DS, true}, - { 0x3F, OP_I386, &i386_device::i386_aas, &i386_device::i386_aas, false}, - { 0x40, OP_I386, &i386_device::i386_inc_ax, &i386_device::i386_inc_eax, false}, - { 0x41, OP_I386, &i386_device::i386_inc_cx, &i386_device::i386_inc_ecx, false}, - { 0x42, OP_I386, &i386_device::i386_inc_dx, &i386_device::i386_inc_edx, false}, - { 0x43, OP_I386, &i386_device::i386_inc_bx, &i386_device::i386_inc_ebx, false}, - { 0x44, OP_I386, &i386_device::i386_inc_sp, &i386_device::i386_inc_esp, false}, - { 0x45, OP_I386, &i386_device::i386_inc_bp, &i386_device::i386_inc_ebp, false}, - { 0x46, OP_I386, &i386_device::i386_inc_si, &i386_device::i386_inc_esi, false}, - { 0x47, OP_I386, &i386_device::i386_inc_di, &i386_device::i386_inc_edi, false}, - { 0x48, OP_I386, &i386_device::i386_dec_ax, &i386_device::i386_dec_eax, false}, - { 0x49, OP_I386, &i386_device::i386_dec_cx, &i386_device::i386_dec_ecx, false}, - { 0x4A, OP_I386, &i386_device::i386_dec_dx, &i386_device::i386_dec_edx, false}, - { 0x4B, OP_I386, &i386_device::i386_dec_bx, &i386_device::i386_dec_ebx, false}, - { 0x4C, OP_I386, &i386_device::i386_dec_sp, &i386_device::i386_dec_esp, false}, - { 0x4D, OP_I386, &i386_device::i386_dec_bp, &i386_device::i386_dec_ebp, false}, - { 0x4E, OP_I386, &i386_device::i386_dec_si, &i386_device::i386_dec_esi, false}, - { 0x4F, OP_I386, &i386_device::i386_dec_di, &i386_device::i386_dec_edi, false}, - { 0x50, OP_I386, &i386_device::i386_push_ax, &i386_device::i386_push_eax, false}, - { 0x51, OP_I386, &i386_device::i386_push_cx, &i386_device::i386_push_ecx, false}, - { 0x52, OP_I386, &i386_device::i386_push_dx, &i386_device::i386_push_edx, false}, - { 0x53, OP_I386, &i386_device::i386_push_bx, &i386_device::i386_push_ebx, false}, - { 0x54, OP_I386, &i386_device::i386_push_sp, &i386_device::i386_push_esp, false}, - { 0x55, OP_I386, &i386_device::i386_push_bp, &i386_device::i386_push_ebp, false}, - { 0x56, OP_I386, &i386_device::i386_push_si, &i386_device::i386_push_esi, false}, - { 0x57, OP_I386, &i386_device::i386_push_di, &i386_device::i386_push_edi, false}, - { 0x58, OP_I386, &i386_device::i386_pop_ax, &i386_device::i386_pop_eax, false}, - { 0x59, OP_I386, &i386_device::i386_pop_cx, &i386_device::i386_pop_ecx, false}, - { 0x5A, OP_I386, &i386_device::i386_pop_dx, &i386_device::i386_pop_edx, false}, - { 0x5B, OP_I386, &i386_device::i386_pop_bx, &i386_device::i386_pop_ebx, false}, - { 0x5C, OP_I386, &i386_device::i386_pop_sp, &i386_device::i386_pop_esp, false}, - { 0x5D, OP_I386, &i386_device::i386_pop_bp, &i386_device::i386_pop_ebp, false}, - { 0x5E, OP_I386, &i386_device::i386_pop_si, &i386_device::i386_pop_esi, false}, - { 0x5F, OP_I386, &i386_device::i386_pop_di, &i386_device::i386_pop_edi, false}, - { 0x60, OP_I386, &i386_device::i386_pusha, &i386_device::i386_pushad, false}, - { 0x61, OP_I386, &i386_device::i386_popa, &i386_device::i386_popad, false}, - { 0x62, OP_I386, &i386_device::i386_bound_r16_m16_m16, &i386_device::i386_bound_r32_m32_m32, false}, - { 0x63, OP_I386, &i386_device::i386_arpl, &i386_device::i386_arpl, false}, - { 0x64, OP_I386, &i386_device::i386_segment_FS, &i386_device::i386_segment_FS, true}, - { 0x65, OP_I386, &i386_device::i386_segment_GS, &i386_device::i386_segment_GS, true}, - { 0x66, OP_I386, &i386_device::i386_operand_size, &i386_device::i386_operand_size, true}, - { 0x67, OP_I386, &i386_device::i386_address_size, &i386_device::i386_address_size, true}, - { 0x68, OP_I386, &i386_device::i386_push_i16, &i386_device::i386_push_i32, false}, - { 0x69, OP_I386, &i386_device::i386_imul_r16_rm16_i16, &i386_device::i386_imul_r32_rm32_i32, false}, - { 0x6A, OP_I386, &i386_device::i386_push_i8, &i386_device::i386_push_i8, false}, - { 0x6B, OP_I386, &i386_device::i386_imul_r16_rm16_i8, &i386_device::i386_imul_r32_rm32_i8, false}, - { 0x6C, OP_I386, &i386_device::i386_insb, &i386_device::i386_insb, false}, - { 0x6D, OP_I386, &i386_device::i386_insw, &i386_device::i386_insd, false}, - { 0x6E, OP_I386, &i386_device::i386_outsb, &i386_device::i386_outsb, false}, - { 0x6F, OP_I386, &i386_device::i386_outsw, &i386_device::i386_outsd, false}, - { 0x70, OP_I386, &i386_device::i386_jo_rel8, &i386_device::i386_jo_rel8, false}, - { 0x71, OP_I386, &i386_device::i386_jno_rel8, &i386_device::i386_jno_rel8, false}, - { 0x72, OP_I386, &i386_device::i386_jc_rel8, &i386_device::i386_jc_rel8, false}, - { 0x73, OP_I386, &i386_device::i386_jnc_rel8, &i386_device::i386_jnc_rel8, false}, - { 0x74, OP_I386, &i386_device::i386_jz_rel8, &i386_device::i386_jz_rel8, false}, - { 0x75, OP_I386, &i386_device::i386_jnz_rel8, &i386_device::i386_jnz_rel8, false}, - { 0x76, OP_I386, &i386_device::i386_jbe_rel8, &i386_device::i386_jbe_rel8, false}, - { 0x77, OP_I386, &i386_device::i386_ja_rel8, &i386_device::i386_ja_rel8, false}, - { 0x78, OP_I386, &i386_device::i386_js_rel8, &i386_device::i386_js_rel8, false}, - { 0x79, OP_I386, &i386_device::i386_jns_rel8, &i386_device::i386_jns_rel8, false}, - { 0x7A, OP_I386, &i386_device::i386_jp_rel8, &i386_device::i386_jp_rel8, false}, - { 0x7B, OP_I386, &i386_device::i386_jnp_rel8, &i386_device::i386_jnp_rel8, false}, - { 0x7C, OP_I386, &i386_device::i386_jl_rel8, &i386_device::i386_jl_rel8, false}, - { 0x7D, OP_I386, &i386_device::i386_jge_rel8, &i386_device::i386_jge_rel8, false}, - { 0x7E, OP_I386, &i386_device::i386_jle_rel8, &i386_device::i386_jle_rel8, false}, - { 0x7F, OP_I386, &i386_device::i386_jg_rel8, &i386_device::i386_jg_rel8, false}, - { 0x80, OP_I386, &i386_device::i386_group80_8, &i386_device::i386_group80_8, true }, - { 0x81, OP_I386, &i386_device::i386_group81_16, &i386_device::i386_group81_32, true }, - { 0x82, OP_I386, &i386_device::i386_group80_8, &i386_device::i386_group80_8, true }, - { 0x83, OP_I386, &i386_device::i386_group83_16, &i386_device::i386_group83_32, true }, - { 0x84, OP_I386, &i386_device::i386_test_rm8_r8, &i386_device::i386_test_rm8_r8, false}, - { 0x85, OP_I386, &i386_device::i386_test_rm16_r16, &i386_device::i386_test_rm32_r32, false}, - { 0x86, OP_I386, &i386_device::i386_xchg_r8_rm8, &i386_device::i386_xchg_r8_rm8, true }, - { 0x87, OP_I386, &i386_device::i386_xchg_r16_rm16, &i386_device::i386_xchg_r32_rm32, true }, - { 0x88, OP_I386, &i386_device::i386_mov_rm8_r8, &i386_device::i386_mov_rm8_r8, false}, - { 0x89, OP_I386, &i386_device::i386_mov_rm16_r16, &i386_device::i386_mov_rm32_r32, false}, - { 0x8A, OP_I386, &i386_device::i386_mov_r8_rm8, &i386_device::i386_mov_r8_rm8, false}, - { 0x8B, OP_I386, &i386_device::i386_mov_r16_rm16, &i386_device::i386_mov_r32_rm32, false}, - { 0x8C, OP_I386, &i386_device::i386_mov_rm16_sreg, &i386_device::i386_mov_rm16_sreg, false}, - { 0x8D, OP_I386, &i386_device::i386_lea16, &i386_device::i386_lea32, false}, - { 0x8E, OP_I386, &i386_device::i386_mov_sreg_rm16, &i386_device::i386_mov_sreg_rm16, false}, - { 0x8F, OP_I386, &i386_device::i386_pop_rm16, &i386_device::i386_pop_rm32, false}, - { 0x90, OP_I386, &i386_device::i386_nop, &i386_device::i386_nop, false}, - { 0x91, OP_I386, &i386_device::i386_xchg_ax_cx, &i386_device::i386_xchg_eax_ecx, false}, - { 0x92, OP_I386, &i386_device::i386_xchg_ax_dx, &i386_device::i386_xchg_eax_edx, false}, - { 0x93, OP_I386, &i386_device::i386_xchg_ax_bx, &i386_device::i386_xchg_eax_ebx, false}, - { 0x94, OP_I386, &i386_device::i386_xchg_ax_sp, &i386_device::i386_xchg_eax_esp, false}, - { 0x95, OP_I386, &i386_device::i386_xchg_ax_bp, &i386_device::i386_xchg_eax_ebp, false}, - { 0x96, OP_I386, &i386_device::i386_xchg_ax_si, &i386_device::i386_xchg_eax_esi, false}, - { 0x97, OP_I386, &i386_device::i386_xchg_ax_di, &i386_device::i386_xchg_eax_edi, false}, - { 0x98, OP_I386, &i386_device::i386_cbw, &i386_device::i386_cwde, false}, - { 0x99, OP_I386, &i386_device::i386_cwd, &i386_device::i386_cdq, false}, - { 0x9A, OP_I386, &i386_device::i386_call_abs16, &i386_device::i386_call_abs32, false}, - { 0x9B, OP_I386, &i386_device::i386_wait, &i386_device::i386_wait, false}, - { 0x9C, OP_I386, &i386_device::i386_pushf, &i386_device::i386_pushfd, false}, - { 0x9D, OP_I386, &i386_device::i386_popf, &i386_device::i386_popfd, false}, - { 0x9E, OP_I386, &i386_device::i386_sahf, &i386_device::i386_sahf, false}, - { 0x9F, OP_I386, &i386_device::i386_lahf, &i386_device::i386_lahf, false}, - { 0xA0, OP_I386, &i386_device::i386_mov_al_m8, &i386_device::i386_mov_al_m8, false}, - { 0xA1, OP_I386, &i386_device::i386_mov_ax_m16, &i386_device::i386_mov_eax_m32, false}, - { 0xA2, OP_I386, &i386_device::i386_mov_m8_al, &i386_device::i386_mov_m8_al, false}, - { 0xA3, OP_I386, &i386_device::i386_mov_m16_ax, &i386_device::i386_mov_m32_eax, false}, - { 0xA4, OP_I386, &i386_device::i386_movsb, &i386_device::i386_movsb, false}, - { 0xA5, OP_I386, &i386_device::i386_movsw, &i386_device::i386_movsd, false}, - { 0xA6, OP_I386, &i386_device::i386_cmpsb, &i386_device::i386_cmpsb, false}, - { 0xA7, OP_I386, &i386_device::i386_cmpsw, &i386_device::i386_cmpsd, false}, - { 0xA8, OP_I386, &i386_device::i386_test_al_i8, &i386_device::i386_test_al_i8, false}, - { 0xA9, OP_I386, &i386_device::i386_test_ax_i16, &i386_device::i386_test_eax_i32, false}, - { 0xAA, OP_I386, &i386_device::i386_stosb, &i386_device::i386_stosb, false}, - { 0xAB, OP_I386, &i386_device::i386_stosw, &i386_device::i386_stosd, false}, - { 0xAC, OP_I386, &i386_device::i386_lodsb, &i386_device::i386_lodsb, false}, - { 0xAD, OP_I386, &i386_device::i386_lodsw, &i386_device::i386_lodsd, false}, - { 0xAE, OP_I386, &i386_device::i386_scasb, &i386_device::i386_scasb, false}, - { 0xAF, OP_I386, &i386_device::i386_scasw, &i386_device::i386_scasd, false}, - { 0xB0, OP_I386, &i386_device::i386_mov_al_i8, &i386_device::i386_mov_al_i8, false}, - { 0xB1, OP_I386, &i386_device::i386_mov_cl_i8, &i386_device::i386_mov_cl_i8, false}, - { 0xB2, OP_I386, &i386_device::i386_mov_dl_i8, &i386_device::i386_mov_dl_i8, false}, - { 0xB3, OP_I386, &i386_device::i386_mov_bl_i8, &i386_device::i386_mov_bl_i8, false}, - { 0xB4, OP_I386, &i386_device::i386_mov_ah_i8, &i386_device::i386_mov_ah_i8, false}, - { 0xB5, OP_I386, &i386_device::i386_mov_ch_i8, &i386_device::i386_mov_ch_i8, false}, - { 0xB6, OP_I386, &i386_device::i386_mov_dh_i8, &i386_device::i386_mov_dh_i8, false}, - { 0xB7, OP_I386, &i386_device::i386_mov_bh_i8, &i386_device::i386_mov_bh_i8, false}, - { 0xB8, OP_I386, &i386_device::i386_mov_ax_i16, &i386_device::i386_mov_eax_i32, false}, - { 0xB9, OP_I386, &i386_device::i386_mov_cx_i16, &i386_device::i386_mov_ecx_i32, false}, - { 0xBA, OP_I386, &i386_device::i386_mov_dx_i16, &i386_device::i386_mov_edx_i32, false}, - { 0xBB, OP_I386, &i386_device::i386_mov_bx_i16, &i386_device::i386_mov_ebx_i32, false}, - { 0xBC, OP_I386, &i386_device::i386_mov_sp_i16, &i386_device::i386_mov_esp_i32, false}, - { 0xBD, OP_I386, &i386_device::i386_mov_bp_i16, &i386_device::i386_mov_ebp_i32, false}, - { 0xBE, OP_I386, &i386_device::i386_mov_si_i16, &i386_device::i386_mov_esi_i32, false}, - { 0xBF, OP_I386, &i386_device::i386_mov_di_i16, &i386_device::i386_mov_edi_i32, false}, - { 0xC0, OP_I386, &i386_device::i386_groupC0_8, &i386_device::i386_groupC0_8, false}, - { 0xC1, OP_I386, &i386_device::i386_groupC1_16, &i386_device::i386_groupC1_32, false}, - { 0xC2, OP_I386, &i386_device::i386_ret_near16_i16, &i386_device::i386_ret_near32_i16, false}, - { 0xC3, OP_I386, &i386_device::i386_ret_near16, &i386_device::i386_ret_near32, false}, - { 0xC4, OP_I386, &i386_device::i386_les16, &i386_device::i386_les32, false}, - { 0xC5, OP_I386, &i386_device::i386_lds16, &i386_device::i386_lds32, false}, - { 0xC6, OP_I386, &i386_device::i386_mov_rm8_i8, &i386_device::i386_mov_rm8_i8, false}, - { 0xC7, OP_I386, &i386_device::i386_mov_rm16_i16, &i386_device::i386_mov_rm32_i32, false}, - { 0xC8, OP_I386, &i386_device::i386_enter16, &i386_device::i386_enter32, false}, - { 0xC9, OP_I386, &i386_device::i386_leave16, &i386_device::i386_leave32, false}, - { 0xCA, OP_I386, &i386_device::i386_retf_i16, &i386_device::i386_retf_i32, false}, - { 0xCB, OP_I386, &i386_device::i386_retf16, &i386_device::i386_retf32, false}, - { 0xCC, OP_I386, &i386_device::i386_int3, &i386_device::i386_int3, false}, - { 0xCD, OP_I386, &i386_device::i386_int, &i386_device::i386_int, false}, - { 0xCE, OP_I386, &i386_device::i386_into, &i386_device::i386_into, false}, - { 0xCF, OP_I386, &i386_device::i386_iret16, &i386_device::i386_iret32, false}, - { 0xD0, OP_I386, &i386_device::i386_groupD0_8, &i386_device::i386_groupD0_8, false}, - { 0xD1, OP_I386, &i386_device::i386_groupD1_16, &i386_device::i386_groupD1_32, false}, - { 0xD2, OP_I386, &i386_device::i386_groupD2_8, &i386_device::i386_groupD2_8, false}, - { 0xD3, OP_I386, &i386_device::i386_groupD3_16, &i386_device::i386_groupD3_32, false}, - { 0xD4, OP_I386, &i386_device::i386_aam, &i386_device::i386_aam, false}, - { 0xD5, OP_I386, &i386_device::i386_aad, &i386_device::i386_aad, false}, - { 0xD6, OP_I386, &i386_device::i386_setalc, &i386_device::i386_setalc, false}, - { 0xD7, OP_I386, &i386_device::i386_xlat, &i386_device::i386_xlat, false}, - { 0xD8, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xD9, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xDA, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xDB, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xDC, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xDD, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xDE, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xDF, OP_I386, &i386_device::i386_escape, &i386_device::i386_escape, false}, - { 0xD8, OP_FPU, &i386_device::i386_x87_group_d8, &i386_device::i386_x87_group_d8, false}, - { 0xD9, OP_FPU, &i386_device::i386_x87_group_d9, &i386_device::i386_x87_group_d9, false}, - { 0xDA, OP_FPU, &i386_device::i386_x87_group_da, &i386_device::i386_x87_group_da, false}, - { 0xDB, OP_FPU, &i386_device::i386_x87_group_db, &i386_device::i386_x87_group_db, false}, - { 0xDC, OP_FPU, &i386_device::i386_x87_group_dc, &i386_device::i386_x87_group_dc, false}, - { 0xDD, OP_FPU, &i386_device::i386_x87_group_dd, &i386_device::i386_x87_group_dd, false}, - { 0xDE, OP_FPU, &i386_device::i386_x87_group_de, &i386_device::i386_x87_group_de, false}, - { 0xDF, OP_FPU, &i386_device::i386_x87_group_df, &i386_device::i386_x87_group_df, false}, - { 0xE0, OP_I386, &i386_device::i386_loopne16, &i386_device::i386_loopne32, false}, - { 0xE1, OP_I386, &i386_device::i386_loopz16, &i386_device::i386_loopz32, false}, - { 0xE2, OP_I386, &i386_device::i386_loop16, &i386_device::i386_loop32, false}, - { 0xE3, OP_I386, &i386_device::i386_jcxz16, &i386_device::i386_jcxz32, false}, - { 0xE4, OP_I386, &i386_device::i386_in_al_i8, &i386_device::i386_in_al_i8, false}, - { 0xE5, OP_I386, &i386_device::i386_in_ax_i8, &i386_device::i386_in_eax_i8, false}, - { 0xE6, OP_I386, &i386_device::i386_out_al_i8, &i386_device::i386_out_al_i8, false}, - { 0xE7, OP_I386, &i386_device::i386_out_ax_i8, &i386_device::i386_out_eax_i8, false}, - { 0xE8, OP_I386, &i386_device::i386_call_rel16, &i386_device::i386_call_rel32, false}, - { 0xE9, OP_I386, &i386_device::i386_jmp_rel16, &i386_device::i386_jmp_rel32, false}, - { 0xEA, OP_I386, &i386_device::i386_jmp_abs16, &i386_device::i386_jmp_abs32, false}, - { 0xEB, OP_I386, &i386_device::i386_jmp_rel8, &i386_device::i386_jmp_rel8, false}, - { 0xEC, OP_I386, &i386_device::i386_in_al_dx, &i386_device::i386_in_al_dx, false}, - { 0xED, OP_I386, &i386_device::i386_in_ax_dx, &i386_device::i386_in_eax_dx, false}, - { 0xEE, OP_I386, &i386_device::i386_out_al_dx, &i386_device::i386_out_al_dx, false}, - { 0xEF, OP_I386, &i386_device::i386_out_ax_dx, &i386_device::i386_out_eax_dx, false}, - { 0xF0, OP_I386, &i386_device::i386_lock, &i386_device::i386_lock, false}, - { 0xF1, OP_I386, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF2, OP_I386, &i386_device::i386_repne, &i386_device::i386_repne, false}, - { 0xF3, OP_I386, &i386_device::i386_rep, &i386_device::i386_rep, false}, - { 0xF4, OP_I386, &i386_device::i386_hlt, &i386_device::i386_hlt, false}, - { 0xF5, OP_I386, &i386_device::i386_cmc, &i386_device::i386_cmc, false}, - { 0xF6, OP_I386, &i386_device::i386_groupF6_8, &i386_device::i386_groupF6_8, true }, - { 0xF7, OP_I386, &i386_device::i386_groupF7_16, &i386_device::i386_groupF7_32, true }, - { 0xF8, OP_I386, &i386_device::i386_clc, &i386_device::i386_clc, false}, - { 0xF9, OP_I386, &i386_device::i386_stc, &i386_device::i386_stc, false}, - { 0xFA, OP_I386, &i386_device::i386_cli, &i386_device::i386_cli, false}, - { 0xFB, OP_I386, &i386_device::i386_sti, &i386_device::i386_sti, false}, - { 0xFC, OP_I386, &i386_device::i386_cld, &i386_device::i386_cld, false}, - { 0xFD, OP_I386, &i386_device::i386_std, &i386_device::i386_std, false}, - { 0xFE, OP_I386, &i386_device::i386_groupFE_8, &i386_device::i386_groupFE_8, true }, - { 0xFF, OP_I386, &i386_device::i386_groupFF_16, &i386_device::i386_groupFF_32, true }, - /* 0F ?? */ - { 0x00, OP_2BYTE|OP_I386, &i386_device::i386_group0F00_16, &i386_device::i386_group0F00_32, false}, - { 0x01, OP_2BYTE|OP_I386, &i386_device::i386_group0F01_16, &i386_device::i386_group0F01_32, false}, - { 0x01, OP_2BYTE|OP_I486, &i386_device::i486_group0F01_16, &i386_device::i486_group0F01_32, false}, - { 0x02, OP_2BYTE|OP_I386, &i386_device::i386_lar_r16_rm16, &i386_device::i386_lar_r32_rm32, false}, - { 0x03, OP_2BYTE|OP_I386, &i386_device::i386_lsl_r16_rm16, &i386_device::i386_lsl_r32_rm32, false}, - { 0x06, OP_2BYTE|OP_I386, &i386_device::i386_clts, &i386_device::i386_clts, false}, - { 0x07, OP_2BYTE|OP_I386, &i386_device::i386_loadall, &i386_device::i386_loadall, false}, - { 0x07, OP_2BYTE|OP_I486, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x08, OP_2BYTE|OP_I486, &i386_device::i486_invd, &i386_device::i486_invd, false}, - { 0x09, OP_2BYTE|OP_I486, &i386_device::i486_wbinvd, &i386_device::i486_wbinvd, false}, - { 0x0B, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_ud2, &i386_device::pentium_ud2, false}, - { 0x10, OP_2BYTE|OP_SSE, &i386_device::sse_movups_r128_rm128, &i386_device::sse_movups_r128_rm128, false}, - { 0x11, OP_2BYTE|OP_SSE, &i386_device::sse_movups_rm128_r128, &i386_device::sse_movups_rm128_r128, false}, - { 0x12, OP_2BYTE|OP_SSE, &i386_device::sse_movlps_r128_m64, &i386_device::sse_movlps_r128_m64, false}, - { 0x13, OP_2BYTE|OP_SSE, &i386_device::sse_movlps_m64_r128, &i386_device::sse_movlps_m64_r128, false}, - { 0x14, OP_2BYTE|OP_SSE, &i386_device::sse_unpcklps_r128_rm128, &i386_device::sse_unpcklps_r128_rm128, false}, - { 0x15, OP_2BYTE|OP_SSE, &i386_device::sse_unpckhps_r128_rm128, &i386_device::sse_unpckhps_r128_rm128, false}, - { 0x16, OP_2BYTE|OP_SSE, &i386_device::sse_movhps_r128_m64, &i386_device::sse_movhps_r128_m64, false}, - { 0x17, OP_2BYTE|OP_SSE, &i386_device::sse_movhps_m64_r128, &i386_device::sse_movhps_m64_r128, false}, - { 0x18, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_prefetch_m8, &i386_device::pentium_prefetch_m8, false}, - { 0x20, OP_2BYTE|OP_I386, &i386_device::i386_mov_r32_cr, &i386_device::i386_mov_r32_cr, false}, - { 0x21, OP_2BYTE|OP_I386, &i386_device::i386_mov_r32_dr, &i386_device::i386_mov_r32_dr, false}, - { 0x22, OP_2BYTE|OP_I386, &i386_device::i386_mov_cr_r32, &i386_device::i386_mov_cr_r32, false}, - { 0x22, OP_2BYTE|OP_I486, &i386_device::i486_mov_cr_r32, &i386_device::i486_mov_cr_r32, false}, - { 0x23, OP_2BYTE|OP_I386, &i386_device::i386_mov_dr_r32, &i386_device::i386_mov_dr_r32, false}, - { 0x24, OP_2BYTE|OP_I386, &i386_device::i386_mov_r32_tr, &i386_device::i386_mov_r32_tr, false}, - { 0x26, OP_2BYTE|OP_I386, &i386_device::i386_mov_tr_r32, &i386_device::i386_mov_tr_r32, false}, - { 0x28, OP_2BYTE|OP_SSE, &i386_device::sse_movaps_r128_rm128, &i386_device::sse_movaps_r128_rm128, false}, - { 0x29, OP_2BYTE|OP_SSE, &i386_device::sse_movaps_rm128_r128, &i386_device::sse_movaps_rm128_r128, false}, - { 0x2a, OP_2BYTE|OP_SSE, &i386_device::sse_cvtpi2ps_r128_rm64, &i386_device::sse_cvtpi2ps_r128_rm64, false}, - { 0x2b, OP_2BYTE|OP_SSE, &i386_device::sse_movntps_m128_r128, &i386_device::sse_movntps_m128_r128, false}, - { 0x2c, OP_2BYTE|OP_SSE, &i386_device::sse_cvttps2pi_r64_r128m64, &i386_device::sse_cvttps2pi_r64_r128m64,false}, - { 0x2d, OP_2BYTE|OP_SSE, &i386_device::sse_cvtps2pi_r64_r128m64, &i386_device::sse_cvtps2pi_r64_r128m64,false}, - { 0x2e, OP_2BYTE|OP_SSE, &i386_device::sse_ucomiss_r128_r128m32, &i386_device::sse_ucomiss_r128_r128m32,false}, - { 0x2f, OP_2BYTE|OP_SSE, &i386_device::sse_comiss_r128_r128m32, &i386_device::sse_comiss_r128_r128m32, false}, - { 0x30, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_wrmsr, &i386_device::pentium_wrmsr, false}, - { 0x31, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_rdtsc, &i386_device::pentium_rdtsc, false}, - { 0x32, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_rdmsr, &i386_device::pentium_rdmsr, false}, - { 0x38, OP_2BYTE|OP_PENTIUM, &i386_device::i386_decode_three_byte38, &i386_device::i386_decode_three_byte38,false}, - { 0x3A, OP_2BYTE|OP_PENTIUM, &i386_device::i386_decode_three_byte3a, &i386_device::i386_decode_three_byte3a,false}, - { 0x3A, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false}, - { 0x3B, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false}, - { 0x3C, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false}, - { 0x3D, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_special, &i386_device::i386_cyrix_special, false}, - { 0x40, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovo_r16_rm16, &i386_device::pentium_cmovo_r32_rm32, false}, - { 0x41, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovno_r16_rm16, &i386_device::pentium_cmovno_r32_rm32, false}, - { 0x42, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovb_r16_rm16, &i386_device::pentium_cmovb_r32_rm32, false}, - { 0x43, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovae_r16_rm16, &i386_device::pentium_cmovae_r32_rm32, false}, - { 0x44, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmove_r16_rm16, &i386_device::pentium_cmove_r32_rm32, false}, - { 0x45, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovne_r16_rm16, &i386_device::pentium_cmovne_r32_rm32, false}, - { 0x46, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovbe_r16_rm16, &i386_device::pentium_cmovbe_r32_rm32, false}, - { 0x47, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmova_r16_rm16, &i386_device::pentium_cmova_r32_rm32, false}, - { 0x48, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovs_r16_rm16, &i386_device::pentium_cmovs_r32_rm32, false}, - { 0x49, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovns_r16_rm16, &i386_device::pentium_cmovns_r32_rm32, false}, - { 0x4a, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovp_r16_rm16, &i386_device::pentium_cmovp_r32_rm32, false}, - { 0x4b, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovnp_r16_rm16, &i386_device::pentium_cmovnp_r32_rm32, false}, - { 0x4c, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovl_r16_rm16, &i386_device::pentium_cmovl_r32_rm32, false}, - { 0x4d, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovge_r16_rm16, &i386_device::pentium_cmovge_r32_rm32, false}, - { 0x4e, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovle_r16_rm16, &i386_device::pentium_cmovle_r32_rm32, false}, - { 0x4f, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmovg_r16_rm16, &i386_device::pentium_cmovg_r32_rm32, false}, - { 0x50, OP_2BYTE|OP_SSE, &i386_device::sse_movmskps_r16_r128, &i386_device::sse_movmskps_r32_r128, false}, - { 0x51, OP_2BYTE|OP_SSE, &i386_device::sse_sqrtps_r128_rm128, &i386_device::sse_sqrtps_r128_rm128, false}, - { 0x52, OP_2BYTE|OP_SSE, &i386_device::sse_rsqrtps_r128_rm128, &i386_device::sse_rsqrtps_r128_rm128, false}, - { 0x53, OP_2BYTE|OP_SSE, &i386_device::sse_rcpps_r128_rm128, &i386_device::sse_rcpps_r128_rm128, false}, - { 0x54, OP_2BYTE|OP_SSE, &i386_device::sse_andps_r128_rm128, &i386_device::sse_andps_r128_rm128, false}, - { 0x55, OP_2BYTE|OP_SSE, &i386_device::sse_andnps_r128_rm128, &i386_device::sse_andnps_r128_rm128, false}, - { 0x56, OP_2BYTE|OP_SSE, &i386_device::sse_orps_r128_rm128, &i386_device::sse_orps_r128_rm128, false}, - { 0x57, OP_2BYTE|OP_SSE, &i386_device::sse_xorps, &i386_device::sse_xorps, false}, - { 0x58, OP_2BYTE|OP_SSE, &i386_device::sse_addps, &i386_device::sse_addps, false}, - { 0x59, OP_2BYTE|OP_SSE, &i386_device::sse_mulps, &i386_device::sse_mulps, false}, - { 0x5a, OP_2BYTE|OP_SSE, &i386_device::sse_cvtps2pd_r128_r128m64, &i386_device::sse_cvtps2pd_r128_r128m64,false}, - { 0x5b, OP_2BYTE|OP_SSE, &i386_device::sse_cvtdq2ps_r128_rm128, &i386_device::sse_cvtdq2ps_r128_rm128, false}, - { 0x5c, OP_2BYTE|OP_SSE, &i386_device::sse_subps, &i386_device::sse_subps, false}, - { 0x5d, OP_2BYTE|OP_SSE, &i386_device::sse_minps, &i386_device::sse_minps, false}, - { 0x5e, OP_2BYTE|OP_SSE, &i386_device::sse_divps, &i386_device::sse_divps, false}, - { 0x5f, OP_2BYTE|OP_SSE, &i386_device::sse_maxps, &i386_device::sse_maxps, false}, - { 0x60, OP_2BYTE|OP_MMX, &i386_device::mmx_punpcklbw_r64_r64m32, &i386_device::mmx_punpcklbw_r64_r64m32,false}, - { 0x61, OP_2BYTE|OP_MMX, &i386_device::mmx_punpcklwd_r64_r64m32, &i386_device::mmx_punpcklwd_r64_r64m32,false}, - { 0x62, OP_2BYTE|OP_MMX, &i386_device::mmx_punpckldq_r64_r64m32, &i386_device::mmx_punpckldq_r64_r64m32,false}, - { 0x63, OP_2BYTE|OP_MMX, &i386_device::mmx_packsswb_r64_rm64, &i386_device::mmx_packsswb_r64_rm64, false}, - { 0x64, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpgtb_r64_rm64, &i386_device::mmx_pcmpgtb_r64_rm64, false}, - { 0x65, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpgtw_r64_rm64, &i386_device::mmx_pcmpgtw_r64_rm64, false}, - { 0x66, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpgtd_r64_rm64, &i386_device::mmx_pcmpgtd_r64_rm64, false}, - { 0x67, OP_2BYTE|OP_MMX, &i386_device::mmx_packuswb_r64_rm64, &i386_device::mmx_packuswb_r64_rm64, false}, - { 0x68, OP_2BYTE|OP_MMX, &i386_device::mmx_punpckhbw_r64_rm64, &i386_device::mmx_punpckhbw_r64_rm64, false}, - { 0x69, OP_2BYTE|OP_MMX, &i386_device::mmx_punpckhwd_r64_rm64, &i386_device::mmx_punpckhwd_r64_rm64, false}, - { 0x6a, OP_2BYTE|OP_MMX, &i386_device::mmx_punpckhdq_r64_rm64, &i386_device::mmx_punpckhdq_r64_rm64, false}, - { 0x6b, OP_2BYTE|OP_MMX, &i386_device::mmx_packssdw_r64_rm64, &i386_device::mmx_packssdw_r64_rm64, false}, - { 0x6e, OP_2BYTE|OP_MMX, &i386_device::mmx_movd_r64_rm32, &i386_device::mmx_movd_r64_rm32, false}, - { 0x6f, OP_2BYTE|OP_MMX, &i386_device::mmx_movq_r64_rm64, &i386_device::mmx_movq_r64_rm64, false}, - { 0x70, OP_2BYTE|OP_MMX, &i386_device::mmx_pshufw_r64_rm64_i8, &i386_device::mmx_pshufw_r64_rm64_i8, false}, - { 0x71, OP_2BYTE|OP_MMX, &i386_device::mmx_group_0f71, &i386_device::mmx_group_0f71, false}, - { 0x72, OP_2BYTE|OP_MMX, &i386_device::mmx_group_0f72, &i386_device::mmx_group_0f72, false}, - { 0x73, OP_2BYTE|OP_MMX, &i386_device::mmx_group_0f73, &i386_device::mmx_group_0f73, false}, - { 0x74, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_unknown, &i386_device::i386_cyrix_unknown, false}, - { 0x74, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpeqb_r64_rm64, &i386_device::mmx_pcmpeqb_r64_rm64, false}, - { 0x75, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpeqw_r64_rm64, &i386_device::mmx_pcmpeqw_r64_rm64, false}, - { 0x76, OP_2BYTE|OP_MMX, &i386_device::mmx_pcmpeqd_r64_rm64, &i386_device::mmx_pcmpeqd_r64_rm64, false}, - { 0x77, OP_2BYTE|OP_MMX, &i386_device::mmx_emms, &i386_device::mmx_emms, false}, - { 0x78, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_svdc, &i386_device::i386_cyrix_svdc, false}, - { 0x79, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_rsdc, &i386_device::i386_cyrix_rsdc, false}, - { 0x7a, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_svldt, &i386_device::i386_cyrix_svldt, false}, - { 0x7b, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_rsldt, &i386_device::i386_cyrix_rsldt, false}, - { 0x7c, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_svts, &i386_device::i386_cyrix_svts, false}, - { 0x7d, OP_2BYTE|OP_CYRIX, &i386_device::i386_cyrix_rsts, &i386_device::i386_cyrix_rsts, false}, - { 0x7e, OP_2BYTE|OP_MMX, &i386_device::mmx_movd_rm32_r64, &i386_device::mmx_movd_rm32_r64, false}, - { 0x7f, OP_2BYTE|OP_MMX, &i386_device::mmx_movq_rm64_r64, &i386_device::mmx_movq_rm64_r64, false}, - { 0x80, OP_2BYTE|OP_I386, &i386_device::i386_jo_rel16, &i386_device::i386_jo_rel32, false}, - { 0x81, OP_2BYTE|OP_I386, &i386_device::i386_jno_rel16, &i386_device::i386_jno_rel32, false}, - { 0x82, OP_2BYTE|OP_I386, &i386_device::i386_jc_rel16, &i386_device::i386_jc_rel32, false}, - { 0x83, OP_2BYTE|OP_I386, &i386_device::i386_jnc_rel16, &i386_device::i386_jnc_rel32, false}, - { 0x84, OP_2BYTE|OP_I386, &i386_device::i386_jz_rel16, &i386_device::i386_jz_rel32, false}, - { 0x85, OP_2BYTE|OP_I386, &i386_device::i386_jnz_rel16, &i386_device::i386_jnz_rel32, false}, - { 0x86, OP_2BYTE|OP_I386, &i386_device::i386_jbe_rel16, &i386_device::i386_jbe_rel32, false}, - { 0x87, OP_2BYTE|OP_I386, &i386_device::i386_ja_rel16, &i386_device::i386_ja_rel32, false}, - { 0x88, OP_2BYTE|OP_I386, &i386_device::i386_js_rel16, &i386_device::i386_js_rel32, false}, - { 0x89, OP_2BYTE|OP_I386, &i386_device::i386_jns_rel16, &i386_device::i386_jns_rel32, false}, - { 0x8A, OP_2BYTE|OP_I386, &i386_device::i386_jp_rel16, &i386_device::i386_jp_rel32, false}, - { 0x8B, OP_2BYTE|OP_I386, &i386_device::i386_jnp_rel16, &i386_device::i386_jnp_rel32, false}, - { 0x8C, OP_2BYTE|OP_I386, &i386_device::i386_jl_rel16, &i386_device::i386_jl_rel32, false}, - { 0x8D, OP_2BYTE|OP_I386, &i386_device::i386_jge_rel16, &i386_device::i386_jge_rel32, false}, - { 0x8E, OP_2BYTE|OP_I386, &i386_device::i386_jle_rel16, &i386_device::i386_jle_rel32, false}, - { 0x8F, OP_2BYTE|OP_I386, &i386_device::i386_jg_rel16, &i386_device::i386_jg_rel32, false}, - { 0x90, OP_2BYTE|OP_I386, &i386_device::i386_seto_rm8, &i386_device::i386_seto_rm8, false}, - { 0x91, OP_2BYTE|OP_I386, &i386_device::i386_setno_rm8, &i386_device::i386_setno_rm8, false}, - { 0x92, OP_2BYTE|OP_I386, &i386_device::i386_setc_rm8, &i386_device::i386_setc_rm8, false}, - { 0x93, OP_2BYTE|OP_I386, &i386_device::i386_setnc_rm8, &i386_device::i386_setnc_rm8, false}, - { 0x94, OP_2BYTE|OP_I386, &i386_device::i386_setz_rm8, &i386_device::i386_setz_rm8, false}, - { 0x95, OP_2BYTE|OP_I386, &i386_device::i386_setnz_rm8, &i386_device::i386_setnz_rm8, false}, - { 0x96, OP_2BYTE|OP_I386, &i386_device::i386_setbe_rm8, &i386_device::i386_setbe_rm8, false}, - { 0x97, OP_2BYTE|OP_I386, &i386_device::i386_seta_rm8, &i386_device::i386_seta_rm8, false}, - { 0x98, OP_2BYTE|OP_I386, &i386_device::i386_sets_rm8, &i386_device::i386_sets_rm8, false}, - { 0x99, OP_2BYTE|OP_I386, &i386_device::i386_setns_rm8, &i386_device::i386_setns_rm8, false}, - { 0x9A, OP_2BYTE|OP_I386, &i386_device::i386_setp_rm8, &i386_device::i386_setp_rm8, false}, - { 0x9B, OP_2BYTE|OP_I386, &i386_device::i386_setnp_rm8, &i386_device::i386_setnp_rm8, false}, - { 0x9C, OP_2BYTE|OP_I386, &i386_device::i386_setl_rm8, &i386_device::i386_setl_rm8, false}, - { 0x9D, OP_2BYTE|OP_I386, &i386_device::i386_setge_rm8, &i386_device::i386_setge_rm8, false}, - { 0x9E, OP_2BYTE|OP_I386, &i386_device::i386_setle_rm8, &i386_device::i386_setle_rm8, false}, - { 0x9F, OP_2BYTE|OP_I386, &i386_device::i386_setg_rm8, &i386_device::i386_setg_rm8, false}, - { 0xA0, OP_2BYTE|OP_I386, &i386_device::i386_push_fs16, &i386_device::i386_push_fs32, false}, - { 0xA1, OP_2BYTE|OP_I386, &i386_device::i386_pop_fs16, &i386_device::i386_pop_fs32, false}, - { 0xA2, OP_2BYTE|OP_I486, &i386_device::i486_cpuid, &i386_device::i486_cpuid, false}, - { 0xA3, OP_2BYTE|OP_I386, &i386_device::i386_bt_rm16_r16, &i386_device::i386_bt_rm32_r32, false}, - { 0xA4, OP_2BYTE|OP_I386, &i386_device::i386_shld16_i8, &i386_device::i386_shld32_i8, false}, - { 0xA5, OP_2BYTE|OP_I386, &i386_device::i386_shld16_cl, &i386_device::i386_shld32_cl, false}, - { 0xA8, OP_2BYTE|OP_I386, &i386_device::i386_push_gs16, &i386_device::i386_push_gs32, false}, - { 0xA9, OP_2BYTE|OP_I386, &i386_device::i386_pop_gs16, &i386_device::i386_pop_gs32, false}, - { 0xAA, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_rsm, &i386_device::pentium_rsm, false}, - { 0xAB, OP_2BYTE|OP_I386, &i386_device::i386_bts_rm16_r16, &i386_device::i386_bts_rm32_r32, true }, - { 0xAC, OP_2BYTE|OP_I386, &i386_device::i386_shrd16_i8, &i386_device::i386_shrd32_i8, false}, - { 0xAD, OP_2BYTE|OP_I386, &i386_device::i386_shrd16_cl, &i386_device::i386_shrd32_cl, false}, - { 0xAE, OP_2BYTE|OP_SSE, &i386_device::sse_group_0fae, &i386_device::sse_group_0fae, false}, - { 0xAF, OP_2BYTE|OP_I386, &i386_device::i386_imul_r16_rm16, &i386_device::i386_imul_r32_rm32, false}, - { 0xB0, OP_2BYTE|OP_I486, &i386_device::i486_cmpxchg_rm8_r8, &i386_device::i486_cmpxchg_rm8_r8, true }, - { 0xB1, OP_2BYTE|OP_I486, &i386_device::i486_cmpxchg_rm16_r16, &i386_device::i486_cmpxchg_rm32_r32, true }, - { 0xB2, OP_2BYTE|OP_I386, &i386_device::i386_lss16, &i386_device::i386_lss32, false}, - { 0xB3, OP_2BYTE|OP_I386, &i386_device::i386_btr_rm16_r16, &i386_device::i386_btr_rm32_r32, true }, - { 0xB4, OP_2BYTE|OP_I386, &i386_device::i386_lfs16, &i386_device::i386_lfs32, false}, - { 0xB5, OP_2BYTE|OP_I386, &i386_device::i386_lgs16, &i386_device::i386_lgs32, false}, - { 0xB6, OP_2BYTE|OP_I386, &i386_device::i386_movzx_r16_rm8, &i386_device::i386_movzx_r32_rm8, false}, - { 0xB7, OP_2BYTE|OP_I386, &i386_device::i386_invalid, &i386_device::i386_movzx_r32_rm16, false}, - { 0xBA, OP_2BYTE|OP_I386, &i386_device::i386_group0FBA_16, &i386_device::i386_group0FBA_32, true }, - { 0xBB, OP_2BYTE|OP_I386, &i386_device::i386_btc_rm16_r16, &i386_device::i386_btc_rm32_r32, true }, - { 0xBC, OP_2BYTE|OP_I386, &i386_device::i386_bsf_r16_rm16, &i386_device::i386_bsf_r32_rm32, false}, - { 0xBD, OP_2BYTE|OP_I386, &i386_device::i386_bsr_r16_rm16, &i386_device::i386_bsr_r32_rm32, false}, - { 0xBE, OP_2BYTE|OP_I386, &i386_device::i386_movsx_r16_rm8, &i386_device::i386_movsx_r32_rm8, false}, - { 0xBF, OP_2BYTE|OP_I386, &i386_device::i386_invalid, &i386_device::i386_movsx_r32_rm16, false}, - { 0xC0, OP_2BYTE|OP_I486, &i386_device::i486_xadd_rm8_r8, &i386_device::i486_xadd_rm8_r8, true }, - { 0xC1, OP_2BYTE|OP_I486, &i386_device::i486_xadd_rm16_r16, &i386_device::i486_xadd_rm32_r32, true }, - { 0xC2, OP_2BYTE|OP_SSE, &i386_device::sse_cmpps_r128_rm128_i8, &i386_device::sse_cmpps_r128_rm128_i8, false}, - { 0xC3, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_movnti_m16_r16, &i386_device::pentium_movnti_m32_r32, false}, - { 0xC4, OP_2BYTE|OP_SSE, &i386_device::sse_pinsrw_r64_r16m16_i8, &i386_device::sse_pinsrw_r64_r32m16_i8,false}, - { 0xC5, OP_2BYTE|OP_SSE, &i386_device::sse_pextrw_r16_r64_i8, &i386_device::sse_pextrw_r32_r64_i8, false}, - { 0xC6, OP_2BYTE|OP_SSE, &i386_device::sse_shufps, &i386_device::sse_shufps, false}, - { 0xC7, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_cmpxchg8b_m64, &i386_device::pentium_cmpxchg8b_m64, true }, - { 0xC8, OP_2BYTE|OP_I486, &i386_device::i486_bswap_eax, &i386_device::i486_bswap_eax, false}, - { 0xC9, OP_2BYTE|OP_I486, &i386_device::i486_bswap_ecx, &i386_device::i486_bswap_ecx, false}, - { 0xCA, OP_2BYTE|OP_I486, &i386_device::i486_bswap_edx, &i386_device::i486_bswap_edx, false}, - { 0xCB, OP_2BYTE|OP_I486, &i386_device::i486_bswap_ebx, &i386_device::i486_bswap_ebx, false}, - { 0xCC, OP_2BYTE|OP_I486, &i386_device::i486_bswap_esp, &i386_device::i486_bswap_esp, false}, - { 0xCD, OP_2BYTE|OP_I486, &i386_device::i486_bswap_ebp, &i386_device::i486_bswap_ebp, false}, - { 0xCE, OP_2BYTE|OP_I486, &i386_device::i486_bswap_esi, &i386_device::i486_bswap_esi, false}, - { 0xCF, OP_2BYTE|OP_I486, &i386_device::i486_bswap_edi, &i386_device::i486_bswap_edi, false}, - { 0xD1, OP_2BYTE|OP_MMX, &i386_device::mmx_psrlw_r64_rm64, &i386_device::mmx_psrlw_r64_rm64, false}, - { 0xD2, OP_2BYTE|OP_MMX, &i386_device::mmx_psrld_r64_rm64, &i386_device::mmx_psrld_r64_rm64, false}, - { 0xD3, OP_2BYTE|OP_MMX, &i386_device::mmx_psrlq_r64_rm64, &i386_device::mmx_psrlq_r64_rm64, false}, - { 0xD4, OP_2BYTE|OP_MMX, &i386_device::mmx_paddq_r64_rm64, &i386_device::mmx_paddq_r64_rm64, false}, - { 0xD5, OP_2BYTE|OP_MMX, &i386_device::mmx_pmullw_r64_rm64, &i386_device::mmx_pmullw_r64_rm64, false}, - { 0xD7, OP_2BYTE|OP_SSE, &i386_device::sse_pmovmskb_r16_r64, &i386_device::sse_pmovmskb_r32_r64, false}, - { 0xD8, OP_2BYTE|OP_MMX, &i386_device::mmx_psubusb_r64_rm64, &i386_device::mmx_psubusb_r64_rm64, false}, - { 0xD9, OP_2BYTE|OP_MMX, &i386_device::mmx_psubusw_r64_rm64, &i386_device::mmx_psubusw_r64_rm64, false}, - { 0xDA, OP_2BYTE|OP_SSE, &i386_device::sse_pminub_r64_rm64, &i386_device::sse_pminub_r64_rm64, false}, - { 0xDB, OP_2BYTE|OP_MMX, &i386_device::mmx_pand_r64_rm64, &i386_device::mmx_pand_r64_rm64, false}, - { 0xDC, OP_2BYTE|OP_MMX, &i386_device::mmx_paddusb_r64_rm64, &i386_device::mmx_paddusb_r64_rm64, false}, - { 0xDD, OP_2BYTE|OP_MMX, &i386_device::mmx_paddusw_r64_rm64, &i386_device::mmx_paddusw_r64_rm64, false}, - { 0xDE, OP_2BYTE|OP_SSE, &i386_device::sse_pmaxub_r64_rm64, &i386_device::sse_pmaxub_r64_rm64, false}, - { 0xDF, OP_2BYTE|OP_MMX, &i386_device::mmx_pandn_r64_rm64, &i386_device::mmx_pandn_r64_rm64, false}, - { 0xE0, OP_2BYTE|OP_SSE, &i386_device::sse_pavgb_r64_rm64, &i386_device::sse_pavgb_r64_rm64, false}, - { 0xE1, OP_2BYTE|OP_MMX, &i386_device::mmx_psraw_r64_rm64, &i386_device::mmx_psraw_r64_rm64, false}, - { 0xE2, OP_2BYTE|OP_MMX, &i386_device::mmx_psrad_r64_rm64, &i386_device::mmx_psrad_r64_rm64, false}, - { 0xE3, OP_2BYTE|OP_SSE, &i386_device::sse_pavgw_r64_rm64, &i386_device::sse_pavgw_r64_rm64, false}, - { 0xE4, OP_2BYTE|OP_SSE, &i386_device::sse_pmulhuw_r64_rm64, &i386_device::sse_pmulhuw_r64_rm64, false}, - { 0xE5, OP_2BYTE|OP_MMX, &i386_device::mmx_pmulhw_r64_rm64, &i386_device::mmx_pmulhw_r64_rm64, false}, - { 0xE7, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_movntq_m64_r64, &i386_device::pentium_movntq_m64_r64, false}, - { 0xE8, OP_2BYTE|OP_MMX, &i386_device::mmx_psubsb_r64_rm64, &i386_device::mmx_psubsb_r64_rm64, false}, - { 0xE9, OP_2BYTE|OP_MMX, &i386_device::mmx_psubsw_r64_rm64, &i386_device::mmx_psubsw_r64_rm64, false}, - { 0xEA, OP_2BYTE|OP_SSE, &i386_device::sse_pminsw_r64_rm64, &i386_device::sse_pminsw_r64_rm64, false}, - { 0xEB, OP_2BYTE|OP_MMX, &i386_device::mmx_por_r64_rm64, &i386_device::mmx_por_r64_rm64, false}, - { 0xEC, OP_2BYTE|OP_MMX, &i386_device::mmx_paddsb_r64_rm64, &i386_device::mmx_paddsb_r64_rm64, false}, - { 0xED, OP_2BYTE|OP_MMX, &i386_device::mmx_paddsw_r64_rm64, &i386_device::mmx_paddsw_r64_rm64, false}, - { 0xEE, OP_2BYTE|OP_SSE, &i386_device::sse_pmaxsw_r64_rm64, &i386_device::sse_pmaxsw_r64_rm64, false}, - { 0xEF, OP_2BYTE|OP_MMX, &i386_device::mmx_pxor_r64_rm64, &i386_device::mmx_pxor_r64_rm64, false}, - { 0xF1, OP_2BYTE|OP_MMX, &i386_device::mmx_psllw_r64_rm64, &i386_device::mmx_psllw_r64_rm64, false}, - { 0xF2, OP_2BYTE|OP_MMX, &i386_device::mmx_pslld_r64_rm64, &i386_device::mmx_pslld_r64_rm64, false}, - { 0xF3, OP_2BYTE|OP_MMX, &i386_device::mmx_psllq_r64_rm64, &i386_device::mmx_psllq_r64_rm64, false}, - { 0xF4, OP_2BYTE|OP_SSE, &i386_device::sse_pmuludq_r64_rm64, &i386_device::sse_pmuludq_r64_rm64, false}, - { 0xF5, OP_2BYTE|OP_MMX, &i386_device::mmx_pmaddwd_r64_rm64, &i386_device::mmx_pmaddwd_r64_rm64, false}, - { 0xF6, OP_2BYTE|OP_SSE, &i386_device::sse_psadbw_r64_rm64, &i386_device::sse_psadbw_r64_rm64, false}, - { 0xf7, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_maskmovq_r64_r64, &i386_device::pentium_maskmovq_r64_r64,false}, - { 0xF8, OP_2BYTE|OP_MMX, &i386_device::mmx_psubb_r64_rm64, &i386_device::mmx_psubb_r64_rm64, false}, - { 0xF9, OP_2BYTE|OP_MMX, &i386_device::mmx_psubw_r64_rm64, &i386_device::mmx_psubw_r64_rm64, false}, - { 0xFA, OP_2BYTE|OP_MMX, &i386_device::mmx_psubd_r64_rm64, &i386_device::mmx_psubd_r64_rm64, false}, - { 0xFB, OP_2BYTE|OP_SSE, &i386_device::sse_psubq_r64_rm64, &i386_device::sse_psubq_r64_rm64, false}, - { 0xFC, OP_2BYTE|OP_MMX, &i386_device::mmx_paddb_r64_rm64, &i386_device::mmx_paddb_r64_rm64, false}, - { 0xFD, OP_2BYTE|OP_MMX, &i386_device::mmx_paddw_r64_rm64, &i386_device::mmx_paddw_r64_rm64, false}, - { 0xFE, OP_2BYTE|OP_MMX, &i386_device::mmx_paddd_r64_rm64, &i386_device::mmx_paddd_r64_rm64, false}, - /* F3 0F ?? */ - { 0x10, OP_3BYTEF3|OP_SSE, &i386_device::sse_movss_r128_rm128, &i386_device::sse_movss_r128_rm128, false}, - { 0x11, OP_3BYTEF3|OP_SSE, &i386_device::sse_movss_rm128_r128, &i386_device::sse_movss_rm128_r128, false}, - { 0x12, OP_3BYTEF3|OP_SSE, &i386_device::sse_movsldup_r128_rm128, &i386_device::sse_movsldup_r128_rm128, false}, - { 0x16, OP_3BYTEF3|OP_SSE, &i386_device::sse_movshdup_r128_rm128, &i386_device::sse_movshdup_r128_rm128, false}, - { 0x2A, OP_3BYTEF3|OP_SSE, &i386_device::sse_cvtsi2ss_r128_rm32, &i386_device::sse_cvtsi2ss_r128_rm32, false}, - { 0x2C, OP_3BYTEF3|OP_SSE, &i386_device::sse_cvttss2si_r32_r128m32, &i386_device::sse_cvttss2si_r32_r128m32,false}, - { 0x2D, OP_3BYTEF3|OP_SSE, &i386_device::sse_cvtss2si_r32_r128m32, &i386_device::sse_cvtss2si_r32_r128m32,false}, - { 0x51, OP_3BYTEF3|OP_SSE, &i386_device::sse_sqrtss_r128_r128m32, &i386_device::sse_sqrtss_r128_r128m32, false}, - { 0x52, OP_3BYTEF3|OP_SSE, &i386_device::sse_rsqrtss_r128_r128m32, &i386_device::sse_rsqrtss_r128_r128m32,false}, - { 0x53, OP_3BYTEF3|OP_SSE, &i386_device::sse_rcpss_r128_r128m32, &i386_device::sse_rcpss_r128_r128m32, false}, - { 0x58, OP_3BYTEF3|OP_SSE, &i386_device::sse_addss, &i386_device::sse_addss, false}, - { 0x59, OP_3BYTEF3|OP_SSE, &i386_device::sse_mulss, &i386_device::sse_mulss, false}, - { 0x5A, OP_3BYTEF3|OP_SSE, &i386_device::sse_cvtss2sd_r128_r128m32, &i386_device::sse_cvtss2sd_r128_r128m32,false}, - { 0x5B, OP_3BYTEF3|OP_SSE, &i386_device::sse_cvttps2dq_r128_rm128, &i386_device::sse_cvttps2dq_r128_rm128,false}, - { 0x5C, OP_3BYTEF3|OP_SSE, &i386_device::sse_subss, &i386_device::sse_subss, false}, - { 0x5D, OP_3BYTEF3|OP_SSE, &i386_device::sse_minss_r128_r128m32, &i386_device::sse_minss_r128_r128m32, false}, - { 0x5E, OP_3BYTEF3|OP_SSE, &i386_device::sse_divss, &i386_device::sse_divss, false}, - { 0x5F, OP_3BYTEF3|OP_SSE, &i386_device::sse_maxss_r128_r128m32, &i386_device::sse_maxss_r128_r128m32, false}, - { 0x6F, OP_3BYTEF3|OP_SSE, &i386_device::sse_movdqu_r128_rm128, &i386_device::sse_movdqu_r128_rm128, false}, - { 0x70, OP_3BYTEF3|OP_SSE, &i386_device::sse_pshufhw_r128_rm128_i8, &i386_device::sse_pshufhw_r128_rm128_i8,false}, - { 0x7E, OP_3BYTEF3|OP_SSE, &i386_device::sse_movq_r128_r128m64, &i386_device::sse_movq_r128_r128m64, false}, - { 0x7F, OP_3BYTEF3|OP_SSE, &i386_device::sse_movdqu_rm128_r128, &i386_device::sse_movdqu_rm128_r128, false}, - { 0xAE, OP_3BYTE66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xB8, OP_3BYTEF3|OP_PENTIUM, &i386_device::pentium_popcnt_r16_rm16, &i386_device::pentium_popcnt_r32_rm32, false}, - { 0xBC, OP_3BYTEF3|OP_PENTIUM, &i386_device::pentium_tzcnt_r16_rm16, &i386_device::pentium_tzcnt_r32_rm32, false}, - { 0xC2, OP_3BYTEF3|OP_SSE, &i386_device::sse_cmpss_r128_r128m32_i8, &i386_device::sse_cmpss_r128_r128m32_i8,false}, - { 0xC7, OP_3BYTEF2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xD6, OP_3BYTEF3|OP_SSE, &i386_device::sse_movq2dq_r128_r64, &i386_device::sse_movq2dq_r128_r64, false}, - { 0xE6, OP_3BYTEF3|OP_SSE, &i386_device::sse_cvtdq2pd_r128_r128m64, &i386_device::sse_cvtdq2pd_r128_r128m64,false}, - /* F2 0F ?? */ - { 0x10, OP_3BYTEF2|OP_SSE, &i386_device::sse_movsd_r128_r128m64, &i386_device::sse_movsd_r128_r128m64, false}, - { 0x11, OP_3BYTEF2|OP_SSE, &i386_device::sse_movsd_r128m64_r128, &i386_device::sse_movsd_r128m64_r128, false}, - { 0x12, OP_3BYTEF2|OP_SSE, &i386_device::sse_movddup_r128_r128m64, &i386_device::sse_movddup_r128_r128m64,false}, - { 0x2A, OP_3BYTEF2|OP_SSE, &i386_device::sse_cvtsi2sd_r128_rm32, &i386_device::sse_cvtsi2sd_r128_rm32, false}, - { 0x2C, OP_3BYTEF2|OP_SSE, &i386_device::sse_cvttsd2si_r32_r128m64, &i386_device::sse_cvttsd2si_r32_r128m64,false}, - { 0x2D, OP_3BYTEF2|OP_SSE, &i386_device::sse_cvtsd2si_r32_r128m64, &i386_device::sse_cvtsd2si_r32_r128m64,false}, - { 0x51, OP_3BYTEF2|OP_SSE, &i386_device::sse_sqrtsd_r128_r128m64, &i386_device::sse_sqrtsd_r128_r128m64, false}, - { 0x58, OP_3BYTEF2|OP_SSE, &i386_device::sse_addsd_r128_r128m64, &i386_device::sse_addsd_r128_r128m64, false}, - { 0x59, OP_3BYTEF2|OP_SSE, &i386_device::sse_mulsd_r128_r128m64, &i386_device::sse_mulsd_r128_r128m64, false}, - { 0x5A, OP_3BYTEF2|OP_SSE, &i386_device::sse_cvtsd2ss_r128_r128m64, &i386_device::sse_cvtsd2ss_r128_r128m64,false}, - { 0x5C, OP_3BYTEF2|OP_SSE, &i386_device::sse_subsd_r128_r128m64, &i386_device::sse_subsd_r128_r128m64, false}, - { 0x5D, OP_3BYTEF2|OP_SSE, &i386_device::sse_minsd_r128_r128m64, &i386_device::sse_minsd_r128_r128m64, false}, - { 0x5E, OP_3BYTEF2|OP_SSE, &i386_device::sse_divsd_r128_r128m64, &i386_device::sse_divsd_r128_r128m64, false}, - { 0x5F, OP_3BYTEF2|OP_SSE, &i386_device::sse_maxsd_r128_r128m64, &i386_device::sse_maxsd_r128_r128m64, false}, - { 0x70, OP_3BYTEF2|OP_SSE, &i386_device::sse_pshuflw_r128_rm128_i8, &i386_device::sse_pshuflw_r128_rm128_i8,false}, - { 0x7C, OP_3BYTEF2|OP_SSE, &i386_device::sse_haddps_r128_rm128, &i386_device::sse_haddps_r128_rm128, false}, - { 0x7D, OP_3BYTEF2|OP_SSE, &i386_device::sse_hsubps_r128_rm128, &i386_device::sse_hsubps_r128_rm128, false}, - { 0xC2, OP_3BYTEF2|OP_SSE, &i386_device::sse_cmpsd_r128_r128m64_i8, &i386_device::sse_cmpsd_r128_r128m64_i8,false}, - { 0xD0, OP_3BYTEF2|OP_SSE, &i386_device::sse_addsubps_r128_rm128, &i386_device::sse_addsubps_r128_rm128, false}, - { 0xD6, OP_3BYTEF2|OP_SSE, &i386_device::sse_movdq2q_r64_r128, &i386_device::sse_movdq2q_r64_r128, false}, - { 0xE6, OP_3BYTEF2|OP_SSE, &i386_device::sse_cvtpd2dq_r128_rm128, &i386_device::sse_cvtpd2dq_r128_rm128, false}, - { 0xF0, OP_3BYTEF2|OP_SSE, &i386_device::sse_lddqu_r128_m128, &i386_device::sse_lddqu_r128_m128, false}, - /* 66 0F ?? */ - { 0x10, OP_3BYTE66|OP_SSE2, &i386_device::sse_movupd_r128_rm128, &i386_device::sse_movupd_r128_rm128, false}, - { 0x11, OP_3BYTE66|OP_SSE2, &i386_device::sse_movupd_rm128_r128, &i386_device::sse_movupd_rm128_r128, false}, - { 0x12, OP_3BYTE66|OP_SSE2, &i386_device::sse_movlpd_r128_m64, &i386_device::sse_movlpd_r128_m64, false}, - { 0x13, OP_3BYTE66|OP_SSE2, &i386_device::sse_movlpd_m64_r128, &i386_device::sse_movlpd_m64_r128, false}, - { 0x14, OP_3BYTE66|OP_SSE2, &i386_device::sse_unpcklpd_r128_rm128, &i386_device::sse_unpcklpd_r128_rm128, false}, - { 0x15, OP_3BYTE66|OP_SSE2, &i386_device::sse_unpckhpd_r128_rm128, &i386_device::sse_unpckhpd_r128_rm128, false}, - { 0x16, OP_3BYTE66|OP_SSE2, &i386_device::sse_movhpd_r128_m64, &i386_device::sse_movhpd_r128_m64, false}, - { 0x17, OP_3BYTE66|OP_SSE2, &i386_device::sse_movhpd_m64_r128, &i386_device::sse_movhpd_m64_r128, false}, - { 0x28, OP_3BYTE66|OP_SSE2, &i386_device::sse_movapd_r128_rm128, &i386_device::sse_movapd_r128_rm128, false}, - { 0x29, OP_3BYTE66|OP_SSE2, &i386_device::sse_movapd_rm128_r128, &i386_device::sse_movapd_rm128_r128, false}, - { 0x2A, OP_3BYTE66|OP_SSE2, &i386_device::sse_cvtpi2pd_r128_rm64, &i386_device::sse_cvtpi2pd_r128_rm64, false}, - { 0x2B, OP_3BYTE66|OP_SSE2, &i386_device::sse_movntpd_m128_r128, &i386_device::sse_movntpd_m128_r128, false}, - { 0x2C, OP_3BYTE66|OP_SSE2, &i386_device::sse_cvttpd2pi_r64_rm128, &i386_device::sse_cvttpd2pi_r64_rm128, false}, - { 0x2D, OP_3BYTE66|OP_SSE2, &i386_device::sse_cvtpd2pi_r64_rm128, &i386_device::sse_cvtpd2pi_r64_rm128, false}, - { 0x2E, OP_3BYTE66|OP_SSE2, &i386_device::sse_ucomisd_r128_r128m64, &i386_device::sse_ucomisd_r128_r128m64,false}, - { 0x2F, OP_3BYTE66|OP_SSE2, &i386_device::sse_comisd_r128_r128m64, &i386_device::sse_comisd_r128_r128m64, false}, - { 0x50, OP_3BYTE66|OP_SSE2, &i386_device::sse_movmskpd_r32_r128, &i386_device::sse_movmskpd_r32_r128, false}, - { 0x51, OP_3BYTE66|OP_SSE2, &i386_device::sse_sqrtpd_r128_rm128, &i386_device::sse_sqrtpd_r128_rm128, false}, - { 0x54, OP_3BYTE66|OP_SSE2, &i386_device::sse_andpd_r128_rm128, &i386_device::sse_andpd_r128_rm128, false}, - { 0x55, OP_3BYTE66|OP_SSE2, &i386_device::sse_andnpd_r128_rm128, &i386_device::sse_andnpd_r128_rm128, false}, - { 0x56, OP_3BYTE66|OP_SSE2, &i386_device::sse_orpd_r128_rm128, &i386_device::sse_orpd_r128_rm128, false}, - { 0x57, OP_3BYTE66|OP_SSE2, &i386_device::sse_xorpd_r128_rm128, &i386_device::sse_xorpd_r128_rm128, false}, - { 0x58, OP_3BYTE66|OP_SSE2, &i386_device::sse_addpd_r128_rm128, &i386_device::sse_addpd_r128_rm128, false}, - { 0x59, OP_3BYTE66|OP_SSE2, &i386_device::sse_mulpd_r128_rm128, &i386_device::sse_mulpd_r128_rm128, false}, - { 0x5A, OP_3BYTE66|OP_SSE2, &i386_device::sse_cvtpd2ps_r128_rm128, &i386_device::sse_cvtpd2ps_r128_rm128, false}, - { 0x5B, OP_3BYTE66|OP_SSE2, &i386_device::sse_cvtps2dq_r128_rm128, &i386_device::sse_cvtps2dq_r128_rm128, false}, - { 0x5C, OP_3BYTE66|OP_SSE2, &i386_device::sse_subpd_r128_rm128, &i386_device::sse_subpd_r128_rm128, false}, - { 0x5D, OP_3BYTE66|OP_SSE2, &i386_device::sse_minpd_r128_rm128, &i386_device::sse_minpd_r128_rm128, false}, - { 0x5E, OP_3BYTE66|OP_SSE2, &i386_device::sse_divpd_r128_rm128, &i386_device::sse_divpd_r128_rm128, false}, - { 0x5F, OP_3BYTE66|OP_SSE2, &i386_device::sse_maxpd_r128_rm128, &i386_device::sse_maxpd_r128_rm128, false}, - { 0x60, OP_3BYTE66|OP_SSE2, &i386_device::sse_punpcklbw_r128_rm128, &i386_device::sse_punpcklbw_r128_rm128,false}, - { 0x61, OP_3BYTE66|OP_SSE2, &i386_device::sse_punpcklwd_r128_rm128, &i386_device::sse_punpcklwd_r128_rm128,false}, - { 0x62, OP_3BYTE66|OP_SSE2, &i386_device::sse_punpckldq_r128_rm128, &i386_device::sse_punpckldq_r128_rm128,false}, - { 0x63, OP_3BYTE66|OP_SSE2, &i386_device::sse_packsswb_r128_rm128, &i386_device::sse_packsswb_r128_rm128, false}, - { 0x64, OP_3BYTE66|OP_SSE2, &i386_device::sse_pcmpgtb_r128_rm128, &i386_device::sse_pcmpgtb_r128_rm128, false}, - { 0x65, OP_3BYTE66|OP_SSE2, &i386_device::sse_pcmpgtw_r128_rm128, &i386_device::sse_pcmpgtw_r128_rm128, false}, - { 0x66, OP_3BYTE66|OP_SSE2, &i386_device::sse_pcmpgtd_r128_rm128, &i386_device::sse_pcmpgtd_r128_rm128, false}, - { 0x67, OP_3BYTE66|OP_SSE2, &i386_device::sse_packuswb_r128_rm128, &i386_device::sse_packuswb_r128_rm128, false}, - { 0x68, OP_3BYTE66|OP_SSE2, &i386_device::sse_punpckhbw_r128_rm128, &i386_device::sse_punpckhbw_r128_rm128,false}, - { 0x69, OP_3BYTE66|OP_SSE2, &i386_device::sse_punpckhwd_r128_rm128, &i386_device::sse_punpckhwd_r128_rm128,false}, - { 0x6A, OP_3BYTE66|OP_SSE2, &i386_device::sse_unpckhdq_r128_rm128, &i386_device::sse_unpckhdq_r128_rm128, false}, - { 0x6B, OP_3BYTE66|OP_SSE2, &i386_device::sse_packssdw_r128_rm128, &i386_device::sse_packssdw_r128_rm128, false}, - { 0x6C, OP_3BYTE66|OP_SSE2, &i386_device::sse_punpcklqdq_r128_rm128, &i386_device::sse_punpcklqdq_r128_rm128,false}, - { 0x6D, OP_3BYTE66|OP_SSE2, &i386_device::sse_punpckhqdq_r128_rm128, &i386_device::sse_punpckhqdq_r128_rm128,false}, - { 0x6E, OP_3BYTE66|OP_SSE2, &i386_device::sse_movd_m128_rm32, &i386_device::sse_movd_m128_rm32, false}, - { 0x6F, OP_3BYTE66|OP_SSE2, &i386_device::sse_movdqa_m128_rm128, &i386_device::sse_movdqa_m128_rm128, false}, - { 0x70, OP_3BYTE66|OP_SSE2, &i386_device::sse_pshufd_r128_rm128_i8, &i386_device::sse_pshufd_r128_rm128_i8,false}, - { 0x71, OP_3BYTE66|OP_SSE2, &i386_device::sse_group_660f71, &i386_device::sse_group_660f71, false}, - { 0x72, OP_3BYTE66|OP_SSE2, &i386_device::sse_group_660f72, &i386_device::sse_group_660f72, false}, - { 0x73, OP_3BYTE66|OP_SSE2, &i386_device::sse_group_660f73, &i386_device::sse_group_660f73, false}, - { 0x74, OP_3BYTE66|OP_SSE2, &i386_device::sse_pcmpeqb_r128_rm128, &i386_device::sse_pcmpeqb_r128_rm128, false}, - { 0x75, OP_3BYTE66|OP_SSE2, &i386_device::sse_pcmpeqw_r128_rm128, &i386_device::sse_pcmpeqw_r128_rm128, false}, - { 0x76, OP_3BYTE66|OP_SSE2, &i386_device::sse_pcmpeqd_r128_rm128, &i386_device::sse_pcmpeqd_r128_rm128, false}, - { 0x7C, OP_3BYTE66|OP_SSE3, &i386_device::sse_haddpd_r128_rm128, &i386_device::sse_haddpd_r128_rm128, false}, - { 0x7D, OP_3BYTE66|OP_SSE3, &i386_device::sse_hsubpd_r128_rm128, &i386_device::sse_hsubpd_r128_rm128, false}, - { 0x7E, OP_3BYTE66|OP_SSE2, &i386_device::sse_movd_rm32_r128, &i386_device::sse_movd_rm32_r128, false}, - { 0x7F, OP_3BYTE66|OP_SSE2, &i386_device::sse_movdqa_rm128_r128, &i386_device::sse_movdqa_rm128_r128, false}, - { 0xC2, OP_3BYTE66|OP_SSE2, &i386_device::sse_cmppd_r128_rm128_i8, &i386_device::sse_cmppd_r128_rm128_i8, false}, - { 0xC4, OP_3BYTE66|OP_SSE, &i386_device::sse_pinsrw_r128_r32m16_i8, &i386_device::sse_pinsrw_r128_r32m16_i8,false}, - { 0xC5, OP_3BYTE66|OP_SSE, &i386_device::sse_pextrw_reg_r128_i8, &i386_device::sse_pextrw_reg_r128_i8, false}, - { 0xC6, OP_3BYTE66|OP_SSE2, &i386_device::sse_shufpd_r128_rm128_i8, &i386_device::sse_shufpd_r128_rm128_i8,false}, - { 0xC7, OP_3BYTE66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xD0, OP_3BYTE66|OP_SSE3, &i386_device::sse_addsubpd_r128_rm128, &i386_device::sse_addsubpd_r128_rm128, false}, - { 0xD1, OP_3BYTE66|OP_SSE2, &i386_device::sse_psrlw_r128_rm128, &i386_device::sse_psrlw_r128_rm128, false}, - { 0xD2, OP_3BYTE66|OP_SSE2, &i386_device::sse_psrld_r128_rm128, &i386_device::sse_psrld_r128_rm128, false}, - { 0xD3, OP_3BYTE66|OP_SSE2, &i386_device::sse_psrlq_r128_rm128, &i386_device::sse_psrlq_r128_rm128, false}, - { 0xD4, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddq_r128_rm128, &i386_device::sse_paddq_r128_rm128, false}, - { 0xD5, OP_3BYTE66|OP_SSE2, &i386_device::sse_pmullw_r128_rm128, &i386_device::sse_pmullw_r128_rm128, false}, - { 0xD6, OP_3BYTE66|OP_SSE2, &i386_device::sse_movq_r128m64_r128, &i386_device::sse_movq_r128m64_r128, false}, - { 0xD7, OP_3BYTE66|OP_SSE, &i386_device::sse_pmovmskb_r32_r128, &i386_device::sse_pmovmskb_r32_r128, false}, - { 0xD8, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubusb_r128_rm128, &i386_device::sse_psubusb_r128_rm128, false}, - { 0xD9, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubusw_r128_rm128, &i386_device::sse_psubusw_r128_rm128, false}, - { 0xDA, OP_3BYTE66|OP_SSE2, &i386_device::sse_pminub_r128_rm128, &i386_device::sse_pminub_r128_rm128, false}, - { 0xDB, OP_3BYTE66|OP_SSE2, &i386_device::sse_pand_r128_rm128, &i386_device::sse_pand_r128_rm128, false}, - { 0xDC, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddusb_r128_rm128, &i386_device::sse_paddusb_r128_rm128, false}, - { 0xDD, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddusw_r128_rm128, &i386_device::sse_paddusw_r128_rm128, false}, - { 0xDE, OP_3BYTE66|OP_SSE, &i386_device::sse_pmaxub_r128_rm128, &i386_device::sse_pmaxub_r128_rm128, false}, - { 0xDF, OP_3BYTE66|OP_SSE2, &i386_device::sse_pandn_r128_rm128, &i386_device::sse_pandn_r128_rm128, false}, - { 0xE0, OP_3BYTE66|OP_SSE, &i386_device::sse_pavgb_r128_rm128, &i386_device::sse_pavgb_r128_rm128, false}, - { 0xE1, OP_3BYTE66|OP_SSE2, &i386_device::sse_psraw_r128_rm128, &i386_device::sse_psraw_r128_rm128, false}, - { 0xE2, OP_3BYTE66|OP_SSE2, &i386_device::sse_psrad_r128_rm128, &i386_device::sse_psrad_r128_rm128, false}, - { 0xE3, OP_3BYTE66|OP_SSE, &i386_device::sse_pavgw_r128_rm128, &i386_device::sse_pavgw_r128_rm128, false}, - { 0xE4, OP_3BYTE66|OP_SSE, &i386_device::sse_pmulhuw_r128_rm128, &i386_device::sse_pmulhuw_r128_rm128, false}, - { 0xE5, OP_3BYTE66|OP_SSE2, &i386_device::sse_pmulhw_r128_rm128, &i386_device::sse_pmulhw_r128_rm128, false}, - { 0xE6, OP_3BYTE66|OP_SSE2, &i386_device::sse_cvttpd2dq_r128_rm128, &i386_device::sse_cvttpd2dq_r128_rm128,false}, - { 0xE7, OP_3BYTE66|OP_SSE2, &i386_device::sse_movntdq_m128_r128, &i386_device::sse_movntdq_m128_r128, false}, - { 0xE8, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubsb_r128_rm128, &i386_device::sse_psubsb_r128_rm128, false}, - { 0xE9, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubsw_r128_rm128, &i386_device::sse_psubsw_r128_rm128, false}, - { 0xEA, OP_3BYTE66|OP_SSE, &i386_device::sse_pminsw_r128_rm128, &i386_device::sse_pminsw_r128_rm128, false}, - { 0xEB, OP_3BYTE66|OP_SSE2, &i386_device::sse_por_r128_rm128, &i386_device::sse_por_r128_rm128, false}, - { 0xEC, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddsb_r128_rm128, &i386_device::sse_paddsb_r128_rm128, false}, - { 0xED, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddsw_r128_rm128, &i386_device::sse_paddsw_r128_rm128, false}, - { 0xEE, OP_3BYTE66|OP_SSE, &i386_device::sse_pmaxsw_r128_rm128, &i386_device::sse_pmaxsw_r128_rm128, false}, - { 0xEF, OP_3BYTE66|OP_SSE2, &i386_device::sse_pxor_r128_rm128, &i386_device::sse_pxor_r128_rm128, false}, - { 0xF1, OP_3BYTE66|OP_SSE2, &i386_device::sse_psllw_r128_rm128, &i386_device::sse_psllw_r128_rm128, false}, - { 0xF2, OP_3BYTE66|OP_SSE2, &i386_device::sse_pslld_r128_rm128, &i386_device::sse_pslld_r128_rm128, false}, - { 0xF3, OP_3BYTE66|OP_SSE2, &i386_device::sse_psllq_r128_rm128, &i386_device::sse_psllq_r128_rm128, false}, - { 0xF4, OP_3BYTE66|OP_SSE2, &i386_device::sse_pmuludq_r128_rm128, &i386_device::sse_pmuludq_r128_rm128, false}, - { 0xF5, OP_3BYTE66|OP_SSE2, &i386_device::sse_pmaddwd_r128_rm128, &i386_device::sse_pmaddwd_r128_rm128, false}, - { 0xF6, OP_3BYTE66|OP_SSE, &i386_device::sse_psadbw_r128_rm128, &i386_device::sse_psadbw_r128_rm128, false}, - { 0xF7, OP_3BYTE66|OP_SSE2, &i386_device::sse_maskmovdqu_r128_r128, &i386_device::sse_maskmovdqu_r128_r128,false}, - { 0xF8, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubb_r128_rm128, &i386_device::sse_psubb_r128_rm128, false}, - { 0xF9, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubw_r128_rm128, &i386_device::sse_psubw_r128_rm128, false}, - { 0xFA, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubd_r128_rm128, &i386_device::sse_psubd_r128_rm128, false}, - { 0xFB, OP_3BYTE66|OP_SSE2, &i386_device::sse_psubq_r128_rm128, &i386_device::sse_psubq_r128_rm128, false}, - { 0xFC, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddb_r128_rm128, &i386_device::sse_paddb_r128_rm128, false}, - { 0xFD, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddw_r128_rm128, &i386_device::sse_paddw_r128_rm128, false}, - { 0xFE, OP_3BYTE66|OP_SSE2, &i386_device::sse_paddd_r128_rm128, &i386_device::sse_paddd_r128_rm128, false}, - /* 0F 38 ?? */ - { 0x00, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x01, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x02, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x03, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x04, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x05, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x06, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x07, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x08, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x09, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0A, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0B, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1C, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1D, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1E, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF0, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF1, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF2, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF3, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF5, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF7, OP_3BYTE38|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - /* 0F 3A ?? */ - { 0x0F, OP_3BYTE3A|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - /* 66 0F 38 ?? */ - { 0x00, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x01, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x02, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x03, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x04, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x05, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x06, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x07, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x08, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x09, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0A, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0B, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0C, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0D, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0E, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0F, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x10, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x13, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x14, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x15, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x16, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x17, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x18, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x19, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1A, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1C, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1D, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1E, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x20, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x21, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x22, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x23, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x24, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x25, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x28, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x29, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x2A, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x2B, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x2C, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x2D, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x2E, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x2F, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x30, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x31, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x32, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x33, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x34, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x35, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x36, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x37, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x38, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x39, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x3A, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x3B, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x3C, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x3D, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x3E, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x3F, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x40, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x41, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x45, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x46, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x47, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x58, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x59, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x5A, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x78, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x79, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x80, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x81, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x82, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x8C, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x8E, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x90, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x91, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x92, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x93, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x96, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x97, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x98, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x99, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x9A, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x9B, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x9C, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x9D, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x9E, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x9F, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xA6, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xA7, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xA8, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xA9, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xAA, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xAB, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xAC, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xAD, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xAE, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xAF, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xB6, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xB7, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xB8, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xB9, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xBA, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xBB, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xBC, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xBD, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xBE, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xBF, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xDB, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xDC, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xDD, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xDE, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xDF, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF0, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF1, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF3, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF6, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF7, OP_4BYTE3866|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - /* F2 0F 38 ?? */ - { 0xF0, OP_4BYTE38F2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF1, OP_4BYTE38F2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF3, OP_4BYTE38F2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF5, OP_4BYTE38F2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF6, OP_4BYTE38F2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF7, OP_4BYTE38F2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - /* F3 0F 38 ?? */ - { 0xF3, OP_4BYTE38F3|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF5, OP_4BYTE38F3|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF6, OP_4BYTE38F3|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xF7, OP_4BYTE38F3|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - /* 66 0F 3A ?? */ - { 0x00, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x01, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x02, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x04, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x05, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x06, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x08, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x09, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0A, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0B, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0C, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0D, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0E, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x0F, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x14, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x15, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x16, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x17, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x18, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x19, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x1D, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x20, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x21, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x22, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x38, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x39, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x40, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x41, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x42, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x44, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x46, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x4A, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x4B, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x4C, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x60, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x61, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x62, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0x63, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - { 0xDF, OP_4BYTE3A66|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false}, - /* F2 0F 3A ?? */ - { 0xF0, OP_4BYTE3AF2|OP_SSE, &i386_device::i386_invalid, &i386_device::i386_invalid, false} -}; diff --git a/source/src/vm/libcpu_newdev/i386/i386ops.hxx b/source/src/vm/libcpu_newdev/i386/i386ops.hxx deleted file mode 100644 index 9932057ce..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386ops.hxx +++ /dev/null @@ -1,2608 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -uint8_t i386_device::i386_shift_rotate8(uint8_t modrm, uint32_t value, uint8_t shift) -{ - uint32_t src = value & 0xff; - uint8_t dst = value; - - if( shift == 0 ) { - CYCLES_RM(modrm, 3, 7); - } else if( shift == 1 ) { - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* ROL rm8, 1 */ - m_CF = (src & 0x80) ? 1 : 0; - dst = (src << 1) + m_CF; - m_OF = ((src ^ dst) & 0x80) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 1: /* ROR rm8, 1 */ - m_CF = (src & 0x1) ? 1 : 0; - dst = (m_CF << 7) | (src >> 1); - m_OF = ((src ^ dst) & 0x80) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 2: /* RCL rm8, 1 */ - dst = (src << 1) + m_CF; - m_CF = (src & 0x80) ? 1 : 0; - m_OF = ((src ^ dst) & 0x80) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 3: /* RCR rm8, 1 */ - dst = (m_CF << 7) | (src >> 1); - m_CF = src & 0x1; - m_OF = ((src ^ dst) & 0x80) ? 1 : 0; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 4: /* SHL/SAL rm8, 1 */ - case 6: - dst = src << 1; - m_CF = (src & 0x80) ? 1 : 0; - m_OF = (((m_CF << 7) ^ dst) & 0x80) ? 1 : 0; - SetSZPF8(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 5: /* SHR rm8, 1 */ - dst = src >> 1; - m_CF = src & 0x1; - m_OF = (dst & 0x80) ? 1 : 0; - SetSZPF8(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 7: /* SAR rm8, 1 */ - dst = (int8_t)(src) >> 1; - m_CF = src & 0x1; - m_OF = 0; - SetSZPF8(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - } - - } else { - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* ROL rm8, i8 */ - if(!(shift & 7)) - { - if(shift & 0x18) - { - m_CF = src & 1; - m_OF = (src & 1) ^ ((src >> 7) & 1); - } - break; - } - shift &= 7; - dst = ((src & ((uint8_t)0xff >> shift)) << shift) | - ((src & ((uint8_t)0xff << (8-shift))) >> (8-shift)); - m_CF = dst & 0x1; - m_OF = (dst & 1) ^ (dst >> 7); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 1: /* ROR rm8, i8 */ - if(!(shift & 7)) - { - if(shift & 0x18) - { - m_CF = (src >> 7) & 1; - m_OF = ((src >> 7) & 1) ^ ((src >> 6) & 1); - } - break; - } - shift &= 7; - dst = ((src & ((uint8_t)0xff << shift)) >> shift) | - ((src & ((uint8_t)0xff >> (8-shift))) << (8-shift)); - m_CF = (dst >> 7) & 1; - m_OF = ((dst >> 7) ^ (dst >> 6)) & 1; - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 2: /* RCL rm8, i8 */ - shift %= 9; - dst = ((src & ((uint8_t)0xff >> shift)) << shift) | - ((src & ((uint8_t)0xff << (9-shift))) >> (9-shift)) | - (m_CF << (shift-1)); - if(shift) m_CF = (src >> (8-shift)) & 0x1; - m_OF = m_CF ^ ((dst >> 7) & 1); - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 3: /* RCR rm8, i8 */ - shift %= 9; - dst = ((src & ((uint8_t)0xff << shift)) >> shift) | - ((src & ((uint8_t)0xff >> (8-shift))) << (9-shift)) | - (m_CF << (8-shift)); - if(shift) m_CF = (src >> (shift-1)) & 0x1; - m_OF = ((dst >> 7) ^ (dst >> 6)) & 1; - CYCLES_RM(modrm, CYCLES_ROTATE_CARRY_REG, CYCLES_ROTATE_CARRY_MEM); - break; - case 4: /* SHL/SAL rm8, i8 */ - case 6: - shift &= 31; - dst = src << shift; - m_CF = (shift <= 8) && ((src >> (8 - shift)) & 1); - SetSZPF8(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 5: /* SHR rm8, i8 */ - shift &= 31; - dst = src >> shift; - m_CF = (src & (1 << (shift-1))) ? 1 : 0; - SetSZPF8(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - case 7: /* SAR rm8, i8 */ - shift &= 31; - dst = (int8_t)src >> shift; - m_CF = (src & (1 << (shift-1))) ? 1 : 0; - SetSZPF8(dst); - CYCLES_RM(modrm, CYCLES_ROTATE_REG, CYCLES_ROTATE_MEM); - break; - } - } - - return dst; -} - - - -void i386_device::i386_adc_rm8_r8() // Opcode 0x10 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = ADC8(dst, src, m_CF); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = ADC8(dst, src, m_CF); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_adc_r8_rm8() // Opcode 0x12 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - dst = ADC8(dst, src, m_CF); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - dst = ADC8(dst, src, m_CF); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_adc_al_i8() // Opcode 0x14 -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(AL); - dst = ADC8(dst, src, m_CF); - REG8(AL) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_add_rm8_r8() // Opcode 0x00 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = ADD8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = ADD8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_add_r8_rm8() // Opcode 0x02 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - dst = ADD8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - dst = ADD8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_add_al_i8() // Opcode 0x04 -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(AL); - dst = ADD8(dst, src); - REG8(AL) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_and_rm8_r8() // Opcode 0x20 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = AND8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = AND8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_and_r8_rm8() // Opcode 0x22 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - dst = AND8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - dst = AND8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_and_al_i8() // Opcode 0x24 -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(AL); - dst = AND8(dst, src); - REG8(AL) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_clc() // Opcode 0xf8 -{ - m_CF = 0; - CYCLES(CYCLES_CLC); -} - -void i386_device::i386_cld() // Opcode 0xfc -{ - m_DF = 0; - CYCLES(CYCLES_CLD); -} - -void i386_device::i386_cli() // Opcode 0xfa -{ - if(PROTECTED_MODE) - { - uint8_t IOPL = m_IOP1 | (m_IOP2 << 1); - if(m_CPL > IOPL) - FAULT(FAULT_GP,0); - } - m_IF = 0; - CYCLES(CYCLES_CLI); -} - -void i386_device::i386_cmc() // Opcode 0xf5 -{ - m_CF ^= 1; - CYCLES(CYCLES_CMC); -} - -void i386_device::i386_cmp_rm8_r8() // Opcode 0x38 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - SUB8(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = LOAD_REG8(modrm); - dst = READ8(ea); - SUB8(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } -} - -void i386_device::i386_cmp_r8_rm8() // Opcode 0x3a -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - SUB8(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - SUB8(dst, src); - CYCLES(CYCLES_CMP_MEM_REG); - } -} - -void i386_device::i386_cmp_al_i8() // Opcode 0x3c -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(AL); - SUB8(dst, src); - CYCLES(CYCLES_CMP_IMM_ACC); -} - -void i386_device::i386_cmpsb() // Opcode 0xa6 -{ - uint32_t eas, ead; - uint8_t src, dst; - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 ); - src = READ8(eas); - dst = READ8(ead); - SUB8(src, dst); - BUMP_SI(1); - BUMP_DI(1); - CYCLES(CYCLES_CMPS); -} - -void i386_device::i386_in_al_i8() // Opcode 0xe4 -{ - uint16_t port = FETCH(); - uint8_t data = READPORT8(port); - REG8(AL) = data; - CYCLES(CYCLES_IN_VAR); -} - -void i386_device::i386_in_al_dx() // Opcode 0xec -{ - uint16_t port = REG16(DX); - uint8_t data = READPORT8(port); - REG8(AL) = data; - CYCLES(CYCLES_IN); -} - -void i386_device::i386_ja_rel8() // Opcode 0x77 -{ - int8_t disp = FETCH(); - if( m_CF == 0 && m_ZF == 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jbe_rel8() // Opcode 0x76 -{ - int8_t disp = FETCH(); - if( m_CF != 0 || m_ZF != 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jc_rel8() // Opcode 0x72 -{ - int8_t disp = FETCH(); - if( m_CF != 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jg_rel8() // Opcode 0x7f -{ - int8_t disp = FETCH(); - if( m_ZF == 0 && (m_SF == m_OF) ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jge_rel8() // Opcode 0x7d -{ - int8_t disp = FETCH(); - if(m_SF == m_OF) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jl_rel8() // Opcode 0x7c -{ - int8_t disp = FETCH(); - if( (m_SF != m_OF) ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jle_rel8() // Opcode 0x7e -{ - int8_t disp = FETCH(); - if( m_ZF != 0 || (m_SF != m_OF) ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jnc_rel8() // Opcode 0x73 -{ - int8_t disp = FETCH(); - if( m_CF == 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jno_rel8() // Opcode 0x71 -{ - int8_t disp = FETCH(); - if( m_OF == 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jnp_rel8() // Opcode 0x7b -{ - int8_t disp = FETCH(); - if( m_PF == 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jns_rel8() // Opcode 0x79 -{ - int8_t disp = FETCH(); - if( m_SF == 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jnz_rel8() // Opcode 0x75 -{ - int8_t disp = FETCH(); - if( m_ZF == 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jo_rel8() // Opcode 0x70 -{ - int8_t disp = FETCH(); - if( m_OF != 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jp_rel8() // Opcode 0x7a -{ - int8_t disp = FETCH(); - if( m_PF != 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_js_rel8() // Opcode 0x78 -{ - int8_t disp = FETCH(); - if( m_SF != 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jz_rel8() // Opcode 0x74 -{ - int8_t disp = FETCH(); - if( m_ZF != 0 ) { - NEAR_BRANCH(disp); - CYCLES(CYCLES_JCC_DISP8); /* TODO: Timing = 7 + m */ - } else { - CYCLES(CYCLES_JCC_DISP8_NOBRANCH); - } -} - -void i386_device::i386_jmp_rel8() // Opcode 0xeb -{ - int8_t disp = FETCH(); - NEAR_BRANCH(disp); - CYCLES(CYCLES_JMP_SHORT); /* TODO: Timing = 7 + m */ -} - -void i386_device::i386_lahf() // Opcode 0x9f -{ - REG8(AH) = get_flags() & 0xd7; - CYCLES(CYCLES_LAHF); -} - -void i386_device::i386_lodsb() // Opcode 0xac -{ - uint32_t eas; - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - REG8(AL) = READ8(eas); - BUMP_SI(1); - CYCLES(CYCLES_LODS); -} - -void i386_device::i386_mov_rm8_r8() // Opcode 0x88 -{ - uint8_t src; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - STORE_RM8(modrm, src); - CYCLES(CYCLES_MOV_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - WRITE8(ea, src); - CYCLES(CYCLES_MOV_REG_MEM); - } -} - -void i386_device::i386_mov_r8_rm8() // Opcode 0x8a -{ - uint8_t src; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - STORE_REG8(modrm, src); - CYCLES(CYCLES_MOV_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - STORE_REG8(modrm, src); - CYCLES(CYCLES_MOV_MEM_REG); - } -} - -void i386_device::i386_mov_rm8_i8() // Opcode 0xc6 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t value = FETCH(); - STORE_RM8(modrm, value); - CYCLES(CYCLES_MOV_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint8_t value = FETCH(); - WRITE8(ea, value); - CYCLES(CYCLES_MOV_IMM_MEM); - } -} - -void i386_device::i386_mov_r32_cr() // Opcode 0x0f 20 -{ - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP, 0); - uint8_t modrm = FETCH(); - uint8_t cr = (modrm >> 3) & 0x7; - - STORE_RM32(modrm, m_cr[cr]); - CYCLES(CYCLES_MOV_CR_REG); -} - -void i386_device::i386_mov_r32_dr() // Opcode 0x0f 21 -{ - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP, 0); - uint8_t modrm = FETCH(); - uint8_t dr = (modrm >> 3) & 0x7; - - STORE_RM32(modrm, m_dr[dr]); - switch(dr) - { - case 0: - case 1: - case 2: - case 3: - CYCLES(CYCLES_MOV_REG_DR0_3); - break; - case 6: - case 7: - CYCLES(CYCLES_MOV_REG_DR6_7); - break; - } -} - -void i386_device::i386_mov_cr_r32() // Opcode 0x0f 22 -{ - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP, 0); - uint8_t modrm = FETCH(); - uint8_t cr = (modrm >> 3) & 0x7; - uint32_t data = LOAD_RM32(modrm); - switch(cr) - { - case 0: - data &= 0xfffeffff; // wp not supported on 386 - CYCLES(CYCLES_MOV_REG_CR0); - if (PROTECTED_MODE != BIT(data, 0)) - debugger_privilege_hook(); - break; - case 2: CYCLES(CYCLES_MOV_REG_CR2); break; - case 3: - CYCLES(CYCLES_MOV_REG_CR3); - d_vtlb->vtlb_flush_dynamic(); - break; - case 4: CYCLES(1); break; // TODO - default: - logerror("i386: mov_cr_r32 CR%d!\n", cr); - return; - } - m_cr[cr] = data; -} - -void i386_device::i386_mov_dr_r32() // Opcode 0x0f 23 -{ - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP, 0); - uint8_t modrm = FETCH(); - uint8_t dr = (modrm >> 3) & 0x7; - - m_dr[dr] = LOAD_RM32(modrm); - switch(dr) - { - case 0: - case 1: - case 2: - case 3: - CYCLES(CYCLES_MOV_DR0_3_REG); - break; - case 6: - case 7: - CYCLES(CYCLES_MOV_DR6_7_REG); - break; - default: - logerror("i386: mov_dr_r32 DR%d!\n", dr); - return; - } -} - -void i386_device::i386_mov_al_m8() // Opcode 0xa0 -{ - uint32_t offset, ea; - if( m_address_size ) { - offset = FETCH32(); - } else { - offset = FETCH16(); - } - /* TODO: Not sure if this is correct... */ - if( m_segment_prefix ) { - ea = i386_translate(m_segment_override, offset, 0 ); - } else { - ea = i386_translate(DS, offset, 0 ); - } - REG8(AL) = READ8(ea); - CYCLES(CYCLES_MOV_IMM_MEM); -} - -void i386_device::i386_mov_m8_al() // Opcode 0xa2 -{ - uint32_t offset, ea; - if( m_address_size ) { - offset = FETCH32(); - } else { - offset = FETCH16(); - } - /* TODO: Not sure if this is correct... */ - if( m_segment_prefix ) { - ea = i386_translate(m_segment_override, offset, 1 ); - } else { - ea = i386_translate(DS, offset, 1 ); - } - WRITE8(ea, REG8(AL) ); - CYCLES(CYCLES_MOV_MEM_ACC); -} - -void i386_device::i386_mov_rm16_sreg() // Opcode 0x8c -{ - uint8_t modrm = FETCH(); - int s = (modrm >> 3) & 0x7; - - if( modrm >= 0xc0 ) { - if(m_operand_size) - STORE_RM32(modrm, m_sreg[s].selector); - else - STORE_RM16(modrm, m_sreg[s].selector); - CYCLES(CYCLES_MOV_SREG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE16(ea, m_sreg[s].selector); - CYCLES(CYCLES_MOV_SREG_MEM); - } -} - -void i386_device::i386_mov_sreg_rm16() // Opcode 0x8e -{ - uint16_t selector; - uint8_t modrm = FETCH(); - bool fault; - int s = (modrm >> 3) & 0x7; - - if( modrm >= 0xc0 ) { - selector = LOAD_RM16(modrm); - CYCLES(CYCLES_MOV_REG_SREG); - } else { - uint32_t ea = GetEA(modrm,0); - selector = READ16(ea); - CYCLES(CYCLES_MOV_MEM_SREG); - } - - i386_sreg_load(selector,s,&fault); - if((s == SS) && !fault) - { - if(m_IF != 0) // if external interrupts are enabled - { - m_IF = 0; // reset IF for the next instruction - m_delayed_interrupt_enable = 1; - } - } -} - -void i386_device::i386_mov_al_i8() // Opcode 0xb0 -{ - REG8(AL) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_cl_i8() // Opcode 0xb1 -{ - REG8(CL) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_dl_i8() // Opcode 0xb2 -{ - REG8(DL) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_bl_i8() // Opcode 0xb3 -{ - REG8(BL) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_ah_i8() // Opcode 0xb4 -{ - REG8(AH) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_ch_i8() // Opcode 0xb5 -{ - REG8(CH) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_dh_i8() // Opcode 0xb6 -{ - REG8(DH) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_mov_bh_i8() // Opcode 0xb7 -{ - REG8(BH) = FETCH(); - CYCLES(CYCLES_MOV_IMM_REG); -} - -void i386_device::i386_movsb() // Opcode 0xa4 -{ - uint32_t eas, ead; - uint8_t v; - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 ); - v = READ8(eas); - WRITE8(ead, v); - BUMP_SI(1); - BUMP_DI(1); - CYCLES(CYCLES_MOVS); -} - -void i386_device::i386_or_rm8_r8() // Opcode 0x08 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = OR8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = OR8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_or_r8_rm8() // Opcode 0x0a -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - dst = OR8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - dst = OR8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_or_al_i8() // Opcode 0x0c -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(AL); - dst = OR8(dst, src); - REG8(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_out_al_i8() // Opcode 0xe6 -{ - uint16_t port = FETCH(); - uint8_t data = REG8(AL); - WRITEPORT8(port, data); - CYCLES(CYCLES_OUT_VAR); -} - -void i386_device::i386_out_al_dx() // Opcode 0xee -{ - uint16_t port = REG16(DX); - uint8_t data = REG8(AL); - WRITEPORT8(port, data); - CYCLES(CYCLES_OUT); -} - - -void i386_device::i386_arpl() // Opcode 0x63 -{ - uint16_t src, dst; - uint8_t modrm = FETCH(); - uint8_t flag = 0; - - if(PROTECTED_MODE && !V8086_MODE) - { - if( modrm >= 0xc0 ) { - src = LOAD_REG16(modrm); - dst = LOAD_RM16(modrm); - if( (dst&0x3) < (src&0x3) ) { - dst = (dst&0xfffc) | (src&0x3); - flag = 1; - STORE_RM16(modrm, dst); - } - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG16(modrm); - dst = READ16(ea); - if( (dst&0x3) < (src&0x3) ) { - dst = (dst&0xfffc) | (src&0x3); - flag = 1; - WRITE16(ea, dst); - } - } - SetZF(flag); - } - else - i386_trap(6, 0, 0); // invalid opcode in real mode or v8086 mode -} - -void i386_device::i386_push_i8() // Opcode 0x6a -{ - uint8_t value = FETCH(); - PUSH8(value); - CYCLES(CYCLES_PUSH_IMM); -} - -void i386_device::i386_ins_generic(int size) -{ - uint32_t ead; - uint8_t vb; - uint16_t vw; - uint32_t vd; - - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 ); - - switch(size) { - case 1: - vb = READPORT8(REG16(DX)); - WRITE8(ead, vb); - break; - case 2: - vw = READPORT16(REG16(DX)); - WRITE16(ead, vw); - break; - case 4: - vd = READPORT32(REG16(DX)); - WRITE32(ead, vd); - break; - } - - if(m_address_size) - REG32(EDI) += ((m_DF) ? -1 : 1) * size; - else - REG16(DI) += ((m_DF) ? -1 : 1) * size; - CYCLES(CYCLES_INS); // TODO: Confirm this value -} - -void i386_device::i386_insb() // Opcode 0x6c -{ - i386_ins_generic(1); -} - -void i386_device::i386_insw() // Opcode 0x6d -{ - i386_ins_generic(2); -} - -void i386_device::i386_insd() // Opcode 0x6d -{ - i386_ins_generic(4); -} - -void i386_device::i386_outs_generic(int size) -{ - uint32_t eas; - uint8_t vb; - uint16_t vw; - uint32_t vd; - - if( m_segment_prefix ) { - eas = i386_translate(m_segment_override, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } else { - eas = i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), 0 ); - } - - switch(size) { - case 1: - vb = READ8(eas); - WRITEPORT8(REG16(DX), vb); - break; - case 2: - vw = READ16(eas); - WRITEPORT16(REG16(DX), vw); - break; - case 4: - vd = READ32(eas); - WRITEPORT32(REG16(DX), vd); - break; - } - - if(m_address_size) - REG32(ESI) += ((m_DF) ? -1 : 1) * size; - else - REG16(SI) += ((m_DF) ? -1 : 1) * size; - CYCLES(CYCLES_OUTS); // TODO: Confirm this value -} - -void i386_device::i386_outsb() // Opcode 0x6e -{ - i386_outs_generic(1); -} - -void i386_device::i386_outsw() // Opcode 0x6f -{ - i386_outs_generic(2); -} - -void i386_device::i386_outsd() // Opcode 0x6f -{ - i386_outs_generic(4); -} - -void i386_device::i386_repeat(int invert_flag) -{ - uint32_t repeated_eip = m_eip; - uint32_t repeated_pc = m_pc; - uint8_t opcode; // = FETCH(); -// uint32_t eas, ead; - uint32_t count; - int32_t cycle_base = 0, cycle_adjustment = 0; - uint8_t prefix_flag=1; - uint8_t *flag = nullptr; - - - do { - repeated_eip = m_eip; - repeated_pc = m_pc; - opcode = FETCH(); - switch(opcode) { - case 0x0f: - if (invert_flag == 0) - i386_decode_three_bytef3(); // sse f3 0f - else - i386_decode_three_bytef2(); // sse f2 0f - return; - case 0x26: - m_segment_override=ES; - m_segment_prefix=1; - break; - case 0x2e: - m_segment_override=CS; - m_segment_prefix=1; - break; - case 0x36: - m_segment_override=SS; - m_segment_prefix=1; - break; - case 0x3e: - m_segment_override=DS; - m_segment_prefix=1; - break; - case 0x64: - m_segment_override=FS; - m_segment_prefix=1; - break; - case 0x65: - m_segment_override=GS; - m_segment_prefix=1; - break; - case 0x66: - m_operand_size ^= 1; - m_xmm_operand_size ^= 1; - break; - case 0x67: - m_address_size ^= 1; - break; - default: - prefix_flag=0; - } - } while (prefix_flag); - - - if( m_segment_prefix ) { - // FIXME: the following does not work if both address override and segment override are used - i386_translate(m_segment_override, m_sreg[m_segment_prefix].d ? REG32(ESI) : REG16(SI), -1 ); - } else { - //eas = - i386_translate(DS, m_address_size ? REG32(ESI) : REG16(SI), -1 ); - } - i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), -1 ); - - switch(opcode) - { - case 0x6c: - case 0x6d: - /* INSB, INSW, INSD */ - // TODO: cycle count - cycle_base = 8; - cycle_adjustment = -4; - flag = nullptr; - break; - - case 0x6e: - case 0x6f: - /* OUTSB, OUTSW, OUTSD */ - // TODO: cycle count - cycle_base = 8; - cycle_adjustment = -4; - flag = nullptr; - break; - - case 0xa4: - case 0xa5: - /* MOVSB, MOVSW, MOVSD */ - cycle_base = 8; - cycle_adjustment = -4; - flag = nullptr; - break; - - case 0xa6: - case 0xa7: - /* CMPSB, CMPSW, CMPSD */ - cycle_base = 5; - cycle_adjustment = -1; - flag = &m_ZF; - break; - - case 0xac: - case 0xad: - /* LODSB, LODSW, LODSD */ - cycle_base = 5; - cycle_adjustment = 1; - flag = nullptr; - break; - - case 0xaa: - case 0xab: - /* STOSB, STOSW, STOSD */ - cycle_base = 5; - cycle_adjustment = 0; - flag = nullptr; - break; - - case 0xae: - case 0xaf: - /* SCASB, SCASW, SCASD */ - cycle_base = 5; - cycle_adjustment = 0; - flag = &m_ZF; - break; - - case 0x90: - CYCLES(CYCLES_NOP); - return; - - case 0xc2: // sigh - case 0xc3: - m_pc--; - return; - - default: - logerror("i386: Invalid REP/opcode %02X combination at %08x\n",opcode, m_pc - 2); - m_pc--; - return; - } - - if( m_address_size ) { - if( REG32(ECX) == 0 ) - return; - } else { - if( REG16(CX) == 0 ) - return; - } - - /* now actually perform the repeat */ - CYCLES_NUM(cycle_base); - do - { - m_eip = repeated_eip; - m_pc = repeated_pc; - try - { - i386_decode_opcode(); - } - catch (uint64_t e) - { - m_eip = m_prev_eip; - throw e; - } - - CYCLES_NUM(cycle_adjustment); - - if (m_address_size) - count = --REG32(ECX); - else - count = --REG16(CX); - if (m_cycles <= 0) - goto outofcycles; - } - while( count && (!flag || (invert_flag ? !*flag : *flag)) ); - return; - -outofcycles: - /* if we run out of cycles to execute, and we are still in the repeat, we need - * to exit this instruction in such a way to go right back into it when we have - * time to execute cycles */ - if(flag && (invert_flag ? *flag : !*flag)) - return; - m_eip = m_prev_eip; - CHANGE_PC(m_eip); - CYCLES_NUM(-cycle_base); -} - -void i386_device::i386_rep() // Opcode 0xf3 -{ - i386_repeat(0); -} - -void i386_device::i386_repne() // Opcode 0xf2 -{ - i386_repeat(1); -} - -void i386_device::i386_sahf() // Opcode 0x9e -{ - set_flags((get_flags() & 0xffffff00) | (REG8(AH) & 0xd7) ); - CYCLES(CYCLES_SAHF); -} - -void i386_device::i386_sbb_rm8_r8() // Opcode 0x18 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = SBB8(dst, src, m_CF); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = SBB8(dst, src, m_CF); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_sbb_r8_rm8() // Opcode 0x1a -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - dst = SBB8(dst, src, m_CF); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - dst = SBB8(dst, src, m_CF); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_sbb_al_i8() // Opcode 0x1c -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(AL); - dst = SBB8(dst, src, m_CF); - REG8(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_scasb() // Opcode 0xae -{ - uint32_t eas; - uint8_t src, dst; - eas = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 0 ); - src = READ8(eas); - dst = REG8(AL); - SUB8(dst, src); - BUMP_DI(1); - CYCLES(CYCLES_SCAS); -} - -void i386_device::i386_setalc() // Opcode 0xd6 (undocumented) -{ - if( m_CF ) { - REG8(AL) = 0xff; - } else { - REG8(AL) = 0; - } - CYCLES(3); -} - -void i386_device::i386_seta_rm8() // Opcode 0x0f 97 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_CF == 0 && m_ZF == 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setbe_rm8() // Opcode 0x0f 96 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_CF != 0 || m_ZF != 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setc_rm8() // Opcode 0x0f 92 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_CF != 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setg_rm8() // Opcode 0x0f 9f -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_ZF == 0 && (m_SF == m_OF) ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setge_rm8() // Opcode 0x0f 9d -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if(m_SF == m_OF) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setl_rm8() // Opcode 0x0f 9c -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_SF != m_OF ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setle_rm8() // Opcode 0x0f 9e -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_ZF != 0 || (m_SF != m_OF) ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setnc_rm8() // Opcode 0x0f 93 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_CF == 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setno_rm8() // Opcode 0x0f 91 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_OF == 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setnp_rm8() // Opcode 0x0f 9b -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_PF == 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setns_rm8() // Opcode 0x0f 99 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_SF == 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setnz_rm8() // Opcode 0x0f 95 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_ZF == 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_seto_rm8() // Opcode 0x0f 90 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_OF != 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setp_rm8() // Opcode 0x0f 9a -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_PF != 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_sets_rm8() // Opcode 0x0f 98 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_SF != 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_setz_rm8() // Opcode 0x0f 94 -{ - uint8_t modrm = FETCH(); - uint8_t value = 0; - if( m_ZF != 0 ) { - value = 1; - } - if( modrm >= 0xc0 ) { - STORE_RM8(modrm, value); - CYCLES(CYCLES_SETCC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - WRITE8(ea, value); - CYCLES(CYCLES_SETCC_MEM); - } -} - -void i386_device::i386_stc() // Opcode 0xf9 -{ - m_CF = 1; - CYCLES(CYCLES_STC); -} - -void i386_device::i386_std() // Opcode 0xfd -{ - m_DF = 1; - CYCLES(CYCLES_STD); -} - -void i386_device::i386_sti() // Opcode 0xfb -{ - if(PROTECTED_MODE) - { - uint8_t IOPL = m_IOP1 | (m_IOP2 << 1); - if(m_CPL > IOPL) - FAULT(FAULT_GP,0); - } - m_delayed_interrupt_enable = 1; // IF is set after the next instruction. - CYCLES(CYCLES_STI); -} - -void i386_device::i386_stosb() // Opcode 0xaa -{ - uint32_t ead; - ead = i386_translate(ES, m_address_size ? REG32(EDI) : REG16(DI), 1 ); - WRITE8(ead, REG8(AL)); - BUMP_DI(1); - CYCLES(CYCLES_STOS); -} - -void i386_device::i386_sub_rm8_r8() // Opcode 0x28 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = SUB8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = SUB8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_sub_r8_rm8() // Opcode 0x2a -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - dst = SUB8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - dst = SUB8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_sub_al_i8() // Opcode 0x2c -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(EAX); - dst = SUB8(dst, src); - REG8(EAX) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_test_al_i8() // Opcode 0xa8 -{ - uint8_t src = FETCH(); - uint8_t dst = REG8(AL); - dst = src & dst; - SetSZPF8(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_ALU_IMM_ACC); -} - -void i386_device::i386_test_rm8_r8() // Opcode 0x84 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = src & dst; - SetSZPF8(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = src & dst; - SetSZPF8(dst); - m_CF = 0; - m_OF = 0; - CYCLES(CYCLES_TEST_REG_MEM); - } -} - -void i386_device::i386_xchg_r8_rm8() // Opcode 0x86 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t src = LOAD_RM8(modrm); - uint8_t dst = LOAD_REG8(modrm); - STORE_REG8(modrm, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_XCHG_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint8_t src = READ8(ea); - uint8_t dst = LOAD_REG8(modrm); - WRITE8(ea, dst); - STORE_REG8(modrm, src); - CYCLES(CYCLES_XCHG_REG_MEM); - } -} - -void i386_device::i386_xor_rm8_r8() // Opcode 0x30 -{ - uint8_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_REG8(modrm); - dst = LOAD_RM8(modrm); - dst = XOR8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - src = LOAD_REG8(modrm); - dst = READ8(ea); - dst = XOR8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } -} - -void i386_device::i386_xor_r8_rm8() // Opcode 0x32 -{ - uint32_t src, dst; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - dst = LOAD_REG8(modrm); - dst = XOR8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - dst = LOAD_REG8(modrm); - dst = XOR8(dst, src); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_ALU_MEM_REG); - } -} - -void i386_device::i386_xor_al_i8() // Opcode 0x34 -{ - uint8_t src, dst; - src = FETCH(); - dst = REG8(AL); - dst = XOR8(dst, src); - REG8(AL) = dst; - CYCLES(CYCLES_ALU_IMM_ACC); -} - - - -void i386_device::i386_group80_8() // Opcode 0x80 -{ - uint32_t ea; - uint8_t src, dst; - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: // ADD Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - dst = ADD8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,0); - dst = READ8(ea); - src = FETCH(); - dst = ADD8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 1: // OR Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - dst = OR8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ8(ea); - src = FETCH(); - dst = OR8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 2: // ADC Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - dst = ADC8(dst, src, m_CF); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ8(ea); - src = FETCH(); - dst = ADC8(dst, src, m_CF); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 3: // SBB Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - dst = SBB8(dst, src, m_CF); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ8(ea); - src = FETCH(); - dst = SBB8(dst, src, m_CF); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 4: // AND Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - dst = AND8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ8(ea); - src = FETCH(); - dst = AND8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 5: // SUB Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - dst = SUB8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ8(ea); - src = FETCH(); - dst = SUB8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 6: // XOR Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - dst = XOR8(dst, src); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_ALU_REG_REG); - } else { - ea = GetEA(modrm,1); - dst = READ8(ea); - src = FETCH(); - dst = XOR8(dst, src); - WRITE8(ea, dst); - CYCLES(CYCLES_ALU_REG_MEM); - } - break; - case 7: // CMP Rm8, i8 - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - src = FETCH(); - SUB8(dst, src); - CYCLES(CYCLES_CMP_REG_REG); - } else { - ea = GetEA(modrm,0); - dst = READ8(ea); - src = FETCH(); - SUB8(dst, src); - CYCLES(CYCLES_CMP_REG_MEM); - } - break; - } -} - -void i386_device::i386_groupC0_8() // Opcode 0xc0 -{ - uint8_t dst; - uint8_t modrm = FETCH(); - uint8_t shift; - - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - shift = FETCH() & 0x1f; - dst = i386_shift_rotate8(modrm, dst, shift); - STORE_RM8(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ8(ea); - shift = FETCH() & 0x1f; - dst = i386_shift_rotate8(modrm, dst, shift); - WRITE8(ea, dst); - } -} - -void i386_device::i386_groupD0_8() // Opcode 0xd0 -{ - uint8_t dst; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - dst = i386_shift_rotate8(modrm, dst, 1); - STORE_RM8(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ8(ea); - dst = i386_shift_rotate8(modrm, dst, 1); - WRITE8(ea, dst); - } -} - -void i386_device::i386_groupD2_8() // Opcode 0xd2 -{ - uint8_t dst; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) { - dst = LOAD_RM8(modrm); - dst = i386_shift_rotate8(modrm, dst, REG8(CL)); - STORE_RM8(modrm, dst); - } else { - uint32_t ea = GetEA(modrm,1); - dst = READ8(ea); - dst = i386_shift_rotate8(modrm, dst, REG8(CL)); - WRITE8(ea, dst); - } -} - -void i386_device::i386_groupF6_8() // Opcode 0xf6 -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* TEST Rm8, i8 */ - if( modrm >= 0xc0 ) { - uint8_t dst = LOAD_RM8(modrm); - uint8_t src = FETCH(); - dst &= src; - m_CF = m_OF = m_AF = 0; - SetSZPF8(dst); - CYCLES(CYCLES_TEST_IMM_REG); - } else { - uint32_t ea = GetEA(modrm,0); - uint8_t dst = READ8(ea); - uint8_t src = FETCH(); - dst &= src; - m_CF = m_OF = m_AF = 0; - SetSZPF8(dst); - CYCLES(CYCLES_TEST_IMM_MEM); - } - break; - case 2: /* NOT Rm8 */ - if( modrm >= 0xc0 ) { - uint8_t dst = LOAD_RM8(modrm); - dst = ~dst; - STORE_RM8(modrm, dst); - CYCLES(CYCLES_NOT_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint8_t dst = READ8(ea); - dst = ~dst; - WRITE8(ea, dst); - CYCLES(CYCLES_NOT_MEM); - } - break; - case 3: /* NEG Rm8 */ - if( modrm >= 0xc0 ) { - uint8_t dst = LOAD_RM8(modrm); - dst = SUB8(0, dst ); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_NEG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint8_t dst = READ8(ea); - dst = SUB8(0, dst ); - WRITE8(ea, dst); - CYCLES(CYCLES_NEG_MEM); - } - break; - case 4: /* MUL AL, Rm8 */ - { - uint16_t result; - uint8_t src, dst; - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - CYCLES(CYCLES_MUL8_ACC_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - CYCLES(CYCLES_MUL8_ACC_MEM); /* TODO: Correct multiply timing */ - } - - dst = REG8(AL); - result = (uint16_t)src * (uint16_t)dst; - REG16(AX) = (uint16_t)result; - - m_CF = m_OF = (REG16(AX) > 0xff); - } - break; - case 5: /* IMUL AL, Rm8 */ - { - int16_t result; - int16_t src, dst; - if( modrm >= 0xc0 ) { - src = (int16_t)(int8_t)LOAD_RM8(modrm); - CYCLES(CYCLES_IMUL8_ACC_REG); /* TODO: Correct multiply timing */ - } else { - uint32_t ea = GetEA(modrm,0); - src = (int16_t)(int8_t)READ8(ea); - CYCLES(CYCLES_IMUL8_ACC_MEM); /* TODO: Correct multiply timing */ - } - - dst = (int16_t)(int8_t)REG8(AL); - result = src * dst; - - REG16(AX) = (uint16_t)result; - - m_CF = m_OF = !(result == (int16_t)(int8_t)result); - } - break; - case 6: /* DIV AL, Rm8 */ - { - uint16_t quotient, remainder, result; - uint8_t src; - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - CYCLES(CYCLES_DIV8_ACC_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - CYCLES(CYCLES_DIV8_ACC_MEM); - } - - quotient = (uint16_t)REG16(AX); - if( src ) { - remainder = quotient % (uint16_t)src; - result = quotient / (uint16_t)src; - if( result > 0xff ) { - /* TODO: Divide error */ - } else { - REG8(AH) = (uint8_t)remainder & 0xff; - REG8(AL) = (uint8_t)result & 0xff; - - // this flag is actually undefined, enable on non-cyrix - if (m_cpuid_id0 != 0x69727943) - m_CF = 1; - } - } else { - i386_trap(0, 0, 0); - } - } - break; - case 7: /* IDIV AL, Rm8 */ - { - int16_t quotient, remainder, result; - uint8_t src; - if( modrm >= 0xc0 ) { - src = LOAD_RM8(modrm); - CYCLES(CYCLES_IDIV8_ACC_REG); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ8(ea); - CYCLES(CYCLES_IDIV8_ACC_MEM); - } - - quotient = (int16_t)REG16(AX); - if( src ) { - remainder = quotient % (int16_t)(int8_t)src; - result = quotient / (int16_t)(int8_t)src; - if( result > 0xff ) { - /* TODO: Divide error */ - } else { - REG8(AH) = (uint8_t)remainder & 0xff; - REG8(AL) = (uint8_t)result & 0xff; - - // this flag is actually undefined, enable on non-cyrix - if (m_cpuid_id0 != 0x69727943) - m_CF = 1; - } - } else { - i386_trap(0, 0, 0); - } - } - break; - } -} - -void i386_device::i386_groupFE_8() // Opcode 0xfe -{ - uint8_t modrm = FETCH(); - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* INC Rm8 */ - if( modrm >= 0xc0 ) { - uint8_t dst = LOAD_RM8(modrm); - dst = INC8(dst); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_INC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint8_t dst = READ8(ea); - dst = INC8(dst); - WRITE8(ea, dst); - CYCLES(CYCLES_INC_MEM); - } - break; - case 1: /* DEC Rm8 */ - if( modrm >= 0xc0 ) { - uint8_t dst = LOAD_RM8(modrm); - dst = DEC8(dst); - STORE_RM8(modrm, dst); - CYCLES(CYCLES_DEC_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint8_t dst = READ8(ea); - dst = DEC8(dst); - WRITE8(ea, dst); - CYCLES(CYCLES_DEC_MEM); - } - break; - case 6: /* PUSH Rm8*/ - { - uint8_t value; - if( modrm >= 0xc0 ) { - value = LOAD_RM8(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - value = READ8(ea); - } - if( m_operand_size ) { - PUSH32(value); - } else { - PUSH16(value); - } - CYCLES(CYCLES_PUSH_RM); - } - break; - default: - report_invalid_modrm("groupFE_8", modrm); - break; - } -} - - - -void i386_device::i386_segment_CS() // Opcode 0x2e -{ - m_segment_prefix = 1; - m_segment_override = CS; - - i386_decode_opcode(); -} - -void i386_device::i386_segment_DS() // Opcode 0x3e -{ - m_segment_prefix = 1; - m_segment_override = DS; - CYCLES(0); // TODO: Specify cycle count - i386_decode_opcode(); -} - -void i386_device::i386_segment_ES() // Opcode 0x26 -{ - m_segment_prefix = 1; - m_segment_override = ES; - CYCLES(0); // TODO: Specify cycle count - i386_decode_opcode(); -} - -void i386_device::i386_segment_FS() // Opcode 0x64 -{ - m_segment_prefix = 1; - m_segment_override = FS; - CYCLES(1); // TODO: Specify cycle count - i386_decode_opcode(); -} - -void i386_device::i386_segment_GS() // Opcode 0x65 -{ - m_segment_prefix = 1; - m_segment_override = GS; - CYCLES(1); // TODO: Specify cycle count - i386_decode_opcode(); -} - -void i386_device::i386_segment_SS() // Opcode 0x36 -{ - m_segment_prefix = 1; - m_segment_override = SS; - CYCLES(0); // TODO: Specify cycle count - i386_decode_opcode(); -} - -void i386_device::i386_operand_size() // Opcode prefix 0x66 -{ - if(m_operand_prefix == 0) - { - m_operand_size ^= 1; - m_xmm_operand_size ^= 1; - m_operand_prefix = 1; - } - m_opcode = FETCH(); - if (m_opcode == 0x0f) - i386_decode_three_byte66(); - else - { - if( m_operand_size ) - (this->*m_opcode_table1_32[m_opcode])(); - else - (this->*m_opcode_table1_16[m_opcode])(); - } -} - -void i386_device::i386_address_size() // Opcode 0x67 -{ - if(m_address_prefix == 0) - { - m_address_size ^= 1; - m_address_prefix = 1; - } - i386_decode_opcode(); -} - -void i386_device::i386_nop() // Opcode 0x90 -{ - CYCLES(CYCLES_NOP); -} - -void i386_device::i386_int3() // Opcode 0xcc -{ - CYCLES(CYCLES_INT3); - m_ext = 0; // not an external interrupt - i386_trap(3, 1, 0); - m_ext = 1; -} - -void i386_device::i386_int() // Opcode 0xcd -{ - int interrupt = FETCH(); - CYCLES(CYCLES_INT); - m_ext = 0; // not an external interrupt - if(bios_int_x86(interrupt)) { - m_ext = 1; - return; - } - i386_trap(interrupt, 1, 0); - m_ext = 1; -} - -void i386_device::i386_into() // Opcode 0xce -{ - if( m_OF ) { - m_ext = 0; - i386_trap(4, 1, 0); - m_ext = 1; - CYCLES(CYCLES_INTO_OF1); - } - else - { - CYCLES(CYCLES_INTO_OF0); - } -} - -static uint32_t i386_escape_ea; // hack around GCC 4.6 error because we need the side effects of GetEA() -void i386_device::i386_escape() // Opcodes 0xd8 - 0xdf -{ - uint8_t modrm = FETCH(); - if(modrm < 0xc0) - { - i386_escape_ea = GetEA(modrm,0); - } - CYCLES(3); // TODO: confirm this - (void) LOAD_RM8(modrm); -} - -void i386_device::i386_hlt() // Opcode 0xf4 -{ - if(PROTECTED_MODE && m_CPL != 0) - FAULT(FAULT_GP,0); - m_halted = 1; - CYCLES(CYCLES_HLT); - if (m_cycles > 0) - m_cycles = 0; -} - -void i386_device::i386_decimal_adjust(int direction) -{ - uint8_t tmpAL = REG8(AL); - uint8_t tmpCF = m_CF; - - if (m_AF || ((REG8(AL) & 0xf) > 9)) - { - uint16_t t= (uint16_t)REG8(AL) + (direction * 0x06); - REG8(AL) = (uint8_t)t&0xff; - m_AF = 1; - if (t & 0x100) - m_CF = 1; - if (direction > 0) - tmpAL = REG8(AL); - } - - if (tmpCF || (tmpAL > 0x99)) - { - REG8(AL) += (direction * 0x60); - m_CF = 1; - } - - SetSZPF8(REG8(AL)); -} - -void i386_device::i386_daa() // Opcode 0x27 -{ - i386_decimal_adjust(+1); - CYCLES(CYCLES_DAA); -} - -void i386_device::i386_das() // Opcode 0x2f -{ - i386_decimal_adjust(-1); - CYCLES(CYCLES_DAS); -} - -void i386_device::i386_aaa() // Opcode 0x37 -{ - if( ( (REG8(AL) & 0x0f) > 9) || (m_AF != 0) ) { - REG16(AX) = REG16(AX) + 6; - REG8(AH) = REG8(AH) + 1; - m_AF = 1; - m_CF = 1; - } else { - m_AF = 0; - m_CF = 0; - } - REG8(AL) = REG8(AL) & 0x0f; - CYCLES(CYCLES_AAA); -} - -void i386_device::i386_aas() // Opcode 0x3f -{ - if (m_AF || ((REG8(AL) & 0xf) > 9)) - { - REG16(AX) -= 6; - REG8(AH) -= 1; - m_AF = 1; - m_CF = 1; - } - else - { - m_AF = 0; - m_CF = 0; - } - REG8(AL) &= 0x0f; - CYCLES(CYCLES_AAS); -} - -void i386_device::i386_aad() // Opcode 0xd5 -{ - uint8_t tempAL = REG8(AL); - uint8_t tempAH = REG8(AH); - uint8_t i = FETCH(); - - REG8(AL) = (tempAL + (tempAH * i)) & 0xff; - REG8(AH) = 0; - SetSZPF8( REG8(AL) ); - CYCLES(CYCLES_AAD); -} - -void i386_device::i386_aam() // Opcode 0xd4 -{ - uint8_t tempAL = REG8(AL); - uint8_t i = FETCH(); - - if(!i) - { - i386_trap(0, 0, 0); - return; - } - REG8(AH) = tempAL / i; - REG8(AL) = tempAL % i; - SetSZPF8( REG8(AL) ); - CYCLES(CYCLES_AAM); -} - -void i386_device::i386_clts() // Opcode 0x0f 0x06 -{ - // Privileged instruction, CPL must be zero. Can be used in real or v86 mode. - if(PROTECTED_MODE && m_CPL != 0) - FAULT(FAULT_GP,0) - m_cr[0] &= ~0x08; /* clear TS bit */ - CYCLES(CYCLES_CLTS); -} - -void i386_device::i386_wait() // Opcode 0x9B -{ - // TODO -} - -void i386_device::i386_lock() // Opcode 0xf0 -{ - // lock doesn't depend on iopl on 386 - m_lock = true; - CYCLES(CYCLES_LOCK); // TODO: Determine correct cycle count - i386_decode_opcode(); -} - -void i386_device::i386_mov_r32_tr() // Opcode 0x0f 24 -{ - FETCH(); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::i386_mov_tr_r32() // Opcode 0x0f 26 -{ - FETCH(); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::i386_loadall() // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented -{ - if(PROTECTED_MODE && (m_CPL != 0)) - FAULT(FAULT_GP,0) - uint32_t ea = i386_translate(ES, REG32(EDI), 0); - m_cr[0] = READ32(ea) & 0xfffeffff; // wp not supported on 386 - set_flags(READ32(ea + 0x04)); - m_eip = READ32(ea + 0x08); - REG32(EDI) = READ32(ea + 0x0c); - REG32(ESI) = READ32(ea + 0x10); - REG32(EBP) = READ32(ea + 0x14); - REG32(ESP) = READ32(ea + 0x18); - REG32(EBX) = READ32(ea + 0x1c); - REG32(EDX) = READ32(ea + 0x20); - REG32(ECX) = READ32(ea + 0x24); - REG32(EAX) = READ32(ea + 0x28); - m_dr[6] = READ32(ea + 0x2c); - m_dr[7] = READ32(ea + 0x30); - m_task.segment = READ16(ea + 0x34); - m_ldtr.segment = READ16(ea + 0x38); - m_sreg[GS].selector = READ16(ea + 0x3c); - m_sreg[FS].selector = READ16(ea + 0x40); - m_sreg[DS].selector = READ16(ea + 0x44); - m_sreg[SS].selector = READ16(ea + 0x48); - m_sreg[CS].selector = READ16(ea + 0x4c); - m_sreg[ES].selector = READ16(ea + 0x50); - m_task.flags = READ32(ea + 0x54) >> 8; - m_task.base = READ32(ea + 0x58); - m_task.limit = READ32(ea + 0x5c); - m_idtr.base = READ32(ea + 0x64); - m_idtr.limit = READ32(ea + 0x68); - m_gdtr.base = READ32(ea + 0x70); - m_gdtr.limit = READ32(ea + 0x74); - logerror("LOADALL PC=%08X GDTR:BASE=%08X GDTR:LIMIT=%04X\n", cpustate->prev_pc, cpustate->gdtr.base, cpustate->gdtr.limit); - - m_ldtr.flags = READ32(ea + 0x78) >> 8; - m_ldtr.base = READ32(ea + 0x7c); - m_ldtr.limit = READ32(ea + 0x80); - m_sreg[GS].flags = READ32(ea + 0x84) >> 8; - m_sreg[GS].base = READ32(ea + 0x88); - m_sreg[GS].limit = READ32(ea + 0x8c); - m_sreg[FS].flags = READ32(ea + 0x90) >> 8; - m_sreg[FS].base = READ32(ea + 0x94); - m_sreg[FS].limit = READ32(ea + 0x98); - m_sreg[DS].flags = READ32(ea + 0x9c) >> 8; - m_sreg[DS].base = READ32(ea + 0xa0); - m_sreg[DS].limit = READ32(ea + 0xa4); - m_sreg[SS].flags = READ32(ea + 0xa8) >> 8; - m_sreg[SS].base = READ32(ea + 0xac); - m_sreg[SS].limit = READ32(ea + 0xb0); - m_sreg[CS].flags = READ32(ea + 0xb4) >> 8; - m_sreg[CS].base = READ32(ea + 0xb8); - m_sreg[CS].limit = READ32(ea + 0xbc); - m_sreg[ES].flags = READ32(ea + 0xc0) >> 8; - m_sreg[ES].base = READ32(ea + 0xc4); - m_sreg[ES].limit = READ32(ea + 0xc8); - m_CPL = (m_sreg[SS].flags >> 5) & 3; // cpl == dpl of ss - - for(int i = 0; i <= GS; i++) - { - m_sreg[i].valid = (m_sreg[i].flags & 0x80) ? true : false; - m_sreg[i].d = (m_sreg[i].flags & 0x4000) ? 1 : 0; - } - CHANGE_PC(m_eip); -} - -void i386_device::i386_invalid() -{ - report_invalid_opcode(); - i386_trap(6, 0, 0); -} - -void i386_device::i386_xlat() // Opcode 0xd7 -{ - uint32_t ea; - if( m_segment_prefix ) { - if(!m_address_size) - { - ea = i386_translate(m_segment_override, REG16(BX) + REG8(AL), 0 ); - } - else - { - ea = i386_translate(m_segment_override, REG32(EBX) + REG8(AL), 0 ); - } - } else { - if(!m_address_size) - { - ea = i386_translate(DS, REG16(BX) + REG8(AL), 0 ); - } - else - { - ea = i386_translate(DS, REG32(EBX) + REG8(AL), 0 ); - } - } - REG8(AL) = READ8(ea); - CYCLES(CYCLES_XLAT); -} diff --git a/source/src/vm/libcpu_newdev/i386/i386priv.h b/source/src/vm/libcpu_newdev/i386/i386priv.h deleted file mode 100644 index 0343cf74e..000000000 --- a/source/src/vm/libcpu_newdev/i386/i386priv.h +++ /dev/null @@ -1,1085 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -#pragma once - -#ifndef __I386_H__ -#define __I386_H__ - -#include "i386dasm.h" - -//#define DEBUG_MISSING_OPCODE - -#define I386OP(XX) i386_##XX -#define I486OP(XX) i486_##XX -#define PENTIUMOP(XX) pentium_##XX -#define MMXOP(XX) mmx_##XX -#define SSEOP(XX) sse_##XX - -enum SREGS { ES, CS, SS, DS, FS, GS }; - -enum BREGS -{ - AL = NATIVE_ENDIAN_VALUE_LE_BE(0,3), - AH = NATIVE_ENDIAN_VALUE_LE_BE(1,2), - CL = NATIVE_ENDIAN_VALUE_LE_BE(4,7), - CH = NATIVE_ENDIAN_VALUE_LE_BE(5,6), - DL = NATIVE_ENDIAN_VALUE_LE_BE(8,11), - DH = NATIVE_ENDIAN_VALUE_LE_BE(9,10), - BL = NATIVE_ENDIAN_VALUE_LE_BE(12,15), - BH = NATIVE_ENDIAN_VALUE_LE_BE(13,14) -}; - -enum WREGS -{ - AX = NATIVE_ENDIAN_VALUE_LE_BE(0,1), - CX = NATIVE_ENDIAN_VALUE_LE_BE(2,3), - DX = NATIVE_ENDIAN_VALUE_LE_BE(4,5), - BX = NATIVE_ENDIAN_VALUE_LE_BE(6,7), - SP = NATIVE_ENDIAN_VALUE_LE_BE(8,9), - BP = NATIVE_ENDIAN_VALUE_LE_BE(10,11), - SI = NATIVE_ENDIAN_VALUE_LE_BE(12,13), - DI = NATIVE_ENDIAN_VALUE_LE_BE(14,15) -}; - -enum DREGS { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI }; - -enum -{ - I386_PC = 0, - - /* 8-bit registers */ - I386_AL, - I386_AH, - I386_BL, - I386_BH, - I386_CL, - I386_CH, - I386_DL, - I386_DH, - - /* 16-bit registers */ - I386_AX, - I386_BX, - I386_CX, - I386_DX, - I386_BP, - I386_SP, - I386_SI, - I386_DI, - I386_IP, - - /* 32-bit registers */ - I386_EAX, - I386_ECX, - I386_EDX, - I386_EBX, - I386_EBP, - I386_ESP, - I386_ESI, - I386_EDI, - I386_EIP, - - /* segment registers */ - I386_CS, - I386_CS_BASE, - I386_CS_LIMIT, - I386_CS_FLAGS, - I386_SS, - I386_SS_BASE, - I386_SS_LIMIT, - I386_SS_FLAGS, - I386_DS, - I386_DS_BASE, - I386_DS_LIMIT, - I386_DS_FLAGS, - I386_ES, - I386_ES_BASE, - I386_ES_LIMIT, - I386_ES_FLAGS, - I386_FS, - I386_FS_BASE, - I386_FS_LIMIT, - I386_FS_FLAGS, - I386_GS, - I386_GS_BASE, - I386_GS_LIMIT, - I386_GS_FLAGS, - - /* other */ - I386_EFLAGS, - - I386_CR0, - I386_CR1, - I386_CR2, - I386_CR3, - I386_CR4, - - I386_DR0, - I386_DR1, - I386_DR2, - I386_DR3, - I386_DR4, - I386_DR5, - I386_DR6, - I386_DR7, - - I386_TR6, - I386_TR7, - - I386_GDTR_BASE, - I386_GDTR_LIMIT, - I386_IDTR_BASE, - I386_IDTR_LIMIT, - I386_TR, - I386_TR_BASE, - I386_TR_LIMIT, - I386_TR_FLAGS, - I386_LDTR, - I386_LDTR_BASE, - I386_LDTR_LIMIT, - I386_LDTR_FLAGS, - - I386_CPL, - - X87_CTRL, - X87_STATUS, - X87_TAG, - X87_ST0, - X87_ST1, - X87_ST2, - X87_ST3, - X87_ST4, - X87_ST5, - X87_ST6, - X87_ST7, - - SSE_XMM0, - SSE_XMM1, - SSE_XMM2, - SSE_XMM3, - SSE_XMM4, - SSE_XMM5, - SSE_XMM6, - SSE_XMM7 -}; - -enum -{ - /* mmx registers aliased to x87 ones */ - MMX_MM0=X87_ST0, - MMX_MM1=X87_ST1, - MMX_MM2=X87_ST2, - MMX_MM3=X87_ST3, - MMX_MM4=X87_ST4, - MMX_MM5=X87_ST5, - MMX_MM6=X87_ST6, - MMX_MM7=X87_ST7 -}; - -enum smram -{ - SMRAM_SMBASE = 0xF8, - SMRAM_SMREV = 0xFC, - SMRAM_IORSRT = 0x100, - SMRAM_AHALT = 0x102, - SMRAM_IOEDI = 0x104, - SMRAM_IOECX = 0x108, - SMRAM_IOESI = 0x10C, - - SMRAM_ES = 0x1A8, - SMRAM_CS = 0x1AC, - SMRAM_SS = 0x1B0, - SMRAM_DS = 0x1B4, - SMRAM_FS = 0x1B8, - SMRAM_GS = 0x1BC, - SMRAM_LDTR = 0x1C0, - SMRAM_TR = 0x1C4, - SMRAM_DR7 = 0x1C8, - SMRAM_DR6 = 0x1CC, - SMRAM_EAX = 0x1D0, - SMRAM_ECX = 0x1D4, - SMRAM_EDX = 0x1D8, - SMRAM_EBX = 0x1DC, - SMRAM_ESP = 0x1E0, - SMRAM_EBP = 0x1E4, - SMRAM_ESI = 0x1E8, - SMRAM_EDI = 0x1EC, - SMRAM_EIP = 0x1F0, - SMRAM_EFLAGS = 0x1F4, - SMRAM_CR3 = 0x1F8, - SMRAM_CR0 = 0x1FC -}; - -enum smram_intel_p5 -{ - SMRAM_IP5_IOEIP = 0x110, - SMRAM_IP5_CR4 = 0x128, - SMRAM_IP5_ESLIM = 0x130, - SMRAM_IP5_ESBASE = 0x134, - SMRAM_IP5_ESACC = 0x138, - SMRAM_IP5_CSLIM = 0x13C, - SMRAM_IP5_CSBASE = 0x140, - SMRAM_IP5_CSACC = 0x144, - SMRAM_IP5_SSLIM = 0x148, - SMRAM_IP5_SSBASE = 0x14C, - SMRAM_IP5_SSACC = 0x150, - SMRAM_IP5_DSLIM = 0x154, - SMRAM_IP5_DSBASE = 0x158, - SMRAM_IP5_DSACC = 0x15C, - SMRAM_IP5_FSLIM = 0x160, - SMRAM_IP5_FSBASE = 0x164, - SMRAM_IP5_FSACC = 0x168, - SMRAM_IP5_GSLIM = 0x16C, - SMRAM_IP5_GSBASE = 0x170, - SMRAM_IP5_GSACC = 0x174, - SMRAM_IP5_LDTLIM = 0x178, - SMRAM_IP5_LDTBASE = 0x17C, - SMRAM_IP5_LDTACC = 0x180, - SMRAM_IP5_GDTLIM = 0x184, - SMRAM_IP5_GDTBASE = 0x188, - SMRAM_IP5_GDTACC = 0x18C, - SMRAM_IP5_IDTLIM = 0x190, - SMRAM_IP5_IDTBASE = 0x194, - SMRAM_IP5_IDTACC = 0x198, - SMRAM_IP5_TRLIM = 0x19C, - SMRAM_IP5_TRBASE = 0x1A0, - SMRAM_IP5_TRACC = 0x1A4 -}; - -/* Protected mode exceptions */ -#define FAULT_UD 6 // Invalid Opcode -#define FAULT_NM 7 // Coprocessor not available -#define FAULT_DF 8 // Double Fault -#define FAULT_TS 10 // Invalid TSS -#define FAULT_NP 11 // Segment or Gate not present -#define FAULT_SS 12 // Stack fault -#define FAULT_GP 13 // General Protection Fault -#define FAULT_PF 14 // Page Fault -#define FAULT_MF 16 // Match (Coprocessor) Fault - -/* MXCSR Control and Status Register */ -#define MXCSR_IE (1<<0) // Invalid Operation Flag -#define MXCSR_DE (1<<1) // Denormal Flag -#define MXCSR_ZE (1<<2) // Divide-by-Zero Flag -#define MXCSR_OE (1<<3) // Overflow Flag -#define MXCSR_UE (1<<4) // Underflow Flag -#define MXCSR_PE (1<<5) // Precision Flag -#define MXCSR_DAZ (1<<6) // Denormals Are Zeros -#define MXCSR_IM (1<<7) // Invalid Operation Mask -#define MXCSR_DM (1<<8) // Denormal Operation Mask -#define MXCSR_ZM (1<<9) // Divide-by-Zero Mask -#define MXCSR_OM (1<<10) // Overflow Mask -#define MXCSR_UM (1<<11) // Underflow Mask -#define MXCSR_PM (1<<12) // Precision Mask -#define MXCSR_RC (3<<13) // Rounding Control -#define MXCSR_FZ (1<<15) // Flush to Zero - -union MMX_REG { - uint32_t d[2]; - int32_t i[2]; - uint16_t w[4]; - int16_t s[4]; - uint8_t b[8]; - int8_t c[8]; - float f[2]; - uint64_t q; - int64_t l; -}; - -extern int i386_parity_table[256]; - -#define FAULT_THROW(fault,error) { throw (uint64_t)(fault | (uint64_t)error << 32); } -#define PF_THROW(error) { m_cr[2] = address; FAULT_THROW(FAULT_PF,error); } - -#define PROTECTED_MODE (m_cr[0] & 0x1) -#define STACK_32BIT (m_sreg[SS].d) -#define V8086_MODE (m_VM) -#define NESTED_TASK (m_NT) -#define WP (m_cr[0] & 0x10000) - -#define SetOF_Add32(r,s,d) (m_OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80000000) ? 1: 0) -#define SetOF_Add16(r,s,d) (m_OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x8000) ? 1 : 0) -#define SetOF_Add8(r,s,d) (m_OF = (((r) ^ (s)) & ((r) ^ (d)) & 0x80) ? 1 : 0) - -#define SetOF_Sub32(r,s,d) (m_OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80000000) ? 1 : 0) -#define SetOF_Sub16(r,s,d) (m_OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x8000) ? 1 : 0) -#define SetOF_Sub8(r,s,d) (m_OF = (((d) ^ (s)) & ((d) ^ (r)) & 0x80) ? 1 : 0) - -#define SetCF8(x) {m_CF = ((x) & 0x100) ? 1 : 0; } -#define SetCF16(x) {m_CF = ((x) & 0x10000) ? 1 : 0; } -#define SetCF32(x) {m_CF = ((x) & (((uint64_t)1) << 32)) ? 1 : 0; } - -#define SetSF(x) (m_SF = (x)) -#define SetZF(x) (m_ZF = (x)) -#define SetAF(x,y,z) (m_AF = (((x) ^ ((y) ^ (z))) & 0x10) ? 1 : 0) -#define SetPF(x) (m_PF = i386_parity_table[(x) & 0xFF]) - -#define SetSZPF8(x) {m_ZF = ((uint8_t)(x)==0); m_SF = ((x)&0x80) ? 1 : 0; m_PF = i386_parity_table[x & 0xFF]; } -#define SetSZPF16(x) {m_ZF = ((uint16_t)(x)==0); m_SF = ((x)&0x8000) ? 1 : 0; m_PF = i386_parity_table[x & 0xFF]; } -#define SetSZPF32(x) {m_ZF = ((uint32_t)(x)==0); m_SF = ((x)&0x80000000) ? 1 : 0; m_PF = i386_parity_table[x & 0xFF]; } - -#define MMX(n) (*((MMX_REG *)(&m_x87_reg[(n)].low))) -#define XMM(n) m_sse_reg[(n)] - -#define VTLB_FLAG_DIRTY 0x100 -#define CYCLES_NUM(x) (m_cycles -= (x)) - -#define FAULT(fault,error) {m_ext = 1; i386_trap_with_error(fault,0,0,error); return;} -#define FAULT_EXP(fault,error) {m_ext = 1; i386_trap_with_error(fault,0,trap_level+1,error); return;} - -/***********************************************************************************/ - -struct MODRM_TABLE { - struct { - int b; - int w; - int d; - } reg; - struct { - int b; - int w; - int d; - } rm; -}; - -extern MODRM_TABLE i386_MODRM_table[256]; - -#define REG8(x) (m_reg.b[x]) -#define REG16(x) (m_reg.w[x]) -#define REG32(x) (m_reg.d[x]) - -#define LOAD_REG8(x) (REG8(i386_MODRM_table[x].reg.b)) -#define LOAD_REG16(x) (REG16(i386_MODRM_table[x].reg.w)) -#define LOAD_REG32(x) (REG32(i386_MODRM_table[x].reg.d)) -#define LOAD_RM8(x) (REG8(i386_MODRM_table[x].rm.b)) -#define LOAD_RM16(x) (REG16(i386_MODRM_table[x].rm.w)) -#define LOAD_RM32(x) (REG32(i386_MODRM_table[x].rm.d)) - -#define STORE_REG8(x, value) (REG8(i386_MODRM_table[x].reg.b) = value) -#define STORE_REG16(x, value) (REG16(i386_MODRM_table[x].reg.w) = value) -#define STORE_REG32(x, value) (REG32(i386_MODRM_table[x].reg.d) = value) -#define STORE_RM8(x, value) (REG8(i386_MODRM_table[x].rm.b) = value) -#define STORE_RM16(x, value) (REG16(i386_MODRM_table[x].rm.w) = value) -#define STORE_RM32(x, value) (REG32(i386_MODRM_table[x].rm.d) = value) - -#define SWITCH_ENDIAN_32(x) (((((x) << 24) & (0xff << 24)) | (((x) << 8) & (0xff << 16)) | (((x) >> 8) & (0xff << 8)) | (((x) >> 24) & (0xff << 0)))) - -/***********************************************************************************/ - -void i386_device::CHANGE_PC(uint32_t pc) -{ - m_pc = i386_translate(CS, pc, -1 ); -} - -void i386_device::NEAR_BRANCH(int32_t offs) -{ - /* TODO: limit */ - m_eip += offs; - m_pc += offs; -} - -uint8_t i386_device::FETCH() -{ - uint8_t value; - uint32_t address = m_pc, error; - - if(!translate_address(m_CPL,TRANSLATE_FETCH,&address,&error)) - PF_THROW(error); - - value = mem_pr8(address & m_a20_mask); -#ifdef DEBUG_MISSING_OPCODE - m_opcode_bytes[m_opcode_bytes_length] = value; - m_opcode_bytes_length = (m_opcode_bytes_length + 1) & 15; -#endif - m_eip++; - m_pc++; - return value; -} -uint16_t i386_device::FETCH16() -{ - uint16_t value; - uint32_t address = m_pc, error; - - if( !WORD_ALIGNED(address) ) { /* Unaligned read */ - value = (FETCH() << 0); - value |= (FETCH() << 8); - } else { - if(!translate_address(m_CPL,TRANSLATE_FETCH,&address,&error)) - PF_THROW(error); - address &= m_a20_mask; - value = mem_pr16(address); - m_eip += 2; - m_pc += 2; - } - return value; -} -uint32_t i386_device::FETCH32() -{ - uint32_t value; - uint32_t address = m_pc, error; - - if( !DWORD_ALIGNED(m_pc) ) { /* Unaligned read */ - value = (FETCH() << 0); - value |= (FETCH() << 8); - value |= (FETCH() << 16); - value |= (FETCH() << 24); - } else { - if(!translate_address(m_CPL,TRANSLATE_FETCH,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - value = mem_pr32(address); - m_eip += 4; - m_pc += 4; - } - return value; -} - -uint8_t i386_device::READ8(uint32_t ea) -{ - uint32_t address = ea, error; - - if(!translate_address(m_CPL,TRANSLATE_READ,&address, &error)) - PF_THROW(error); - - address &= m_a20_mask; - return mem_prd8(address); -} -uint16_t i386_device::READ16(uint32_t ea) -{ - uint16_t value; - uint32_t address = ea, error; - - if( !WORD_ALIGNED(ea) ) { /* Unaligned read */ - value = (READ8( address+0 ) << 0); - value |= (READ8( address+1 ) << 8); - } else { - if(!translate_address(m_CPL,TRANSLATE_READ,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - value = mem_prd16( address ); - } - return value; -} -uint32_t i386_device::READ32(uint32_t ea) -{ - uint32_t value; - uint32_t address = ea, error; - - if( !DWORD_ALIGNED(ea) ) { /* Unaligned read */ - value = (READ8( address+0 ) << 0); - value |= (READ8( address+1 ) << 8); - value |= (READ8( address+2 ) << 16), - value |= (READ8( address+3 ) << 24); - } else { - if(!translate_address(m_CPL,TRANSLATE_READ,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - value = mem_prd32( address ); - } - return value; -} - -uint64_t i386_device::READ64(uint32_t ea) -{ - uint64_t value; - uint32_t address = ea, error; - - if( !QWORD_ALIGNED(ea) ) { /* Unaligned read */ - value = (((uint64_t) READ8( address+0 )) << 0); - value |= (((uint64_t) READ8( address+1 )) << 8); - value |= (((uint64_t) READ8( address+2 )) << 16); - value |= (((uint64_t) READ8( address+3 )) << 24); - value |= (((uint64_t) READ8( address+4 )) << 32); - value |= (((uint64_t) READ8( address+5 )) << 40); - value |= (((uint64_t) READ8( address+6 )) << 48); - value |= (((uint64_t) READ8( address+7 )) << 56); - } else { - if(!translate_address(m_CPL,TRANSLATE_READ,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - value = (((uint64_t) mem_prd32( address+0 )) << 0); - value |= (((uint64_t) mem_prd32( address+4 )) << 32); - } - return value; -} -uint8_t i386_device::READ8PL0(uint32_t ea) -{ - uint32_t address = ea, error; - - if(!translate_address(0,TRANSLATE_READ,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - return mem_prd8(address); -} -uint16_t i386_device::READ16PL0(uint32_t ea) -{ - uint16_t value; - uint32_t address = ea, error; - - if( !WORD_ALIGNED(ea) ) { /* Unaligned read */ - value = (READ8PL0( address+0 ) << 0); - value |= (READ8PL0( address+1 ) << 8); - } else { - if(!translate_address(0,TRANSLATE_READ,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - value = mem_prd16( address ); - } - return value; -} - -uint32_t i386_device::READ32PL0(uint32_t ea) -{ - uint32_t value; - uint32_t address = ea, error; - - if( !DWORD_ALIGNED(ea) ) { /* Unaligned read */ - value = (READ8PL0( address+0 ) << 0); - value |= (READ8PL0( address+1 ) << 8); - value |= (READ8PL0( address+2 ) << 16); - value |= (READ8PL0( address+3 ) << 24); - } else { - if(!translate_address(0,TRANSLATE_READ,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - value = mem_prd32( address ); - } - return value; -} - -void i386_device::WRITE_TEST(uint32_t ea) -{ - uint32_t address = ea, error; - if(!translate_address(m_CPL,TRANSLATE_WRITE,&address,&error)) - PF_THROW(error); -} - -void i386_device::WRITE8(uint32_t ea, uint8_t value) -{ - uint32_t address = ea, error; - - if(!translate_address(m_CPL,TRANSLATE_WRITE,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - mem_pwd8(address, value); -} -void i386_device::WRITE16(uint32_t ea, uint16_t value) -{ - uint32_t address = ea, error; - - if( !WORD_ALIGNED(ea) ) { /* Unaligned write */ - WRITE8( address+0, value & 0xff ); - WRITE8( address+1, (value >> 8) & 0xff ); - } else { - if(!translate_address(m_CPL,TRANSLATE_WRITE,&address,&error)) - PF_THROW(error); - - address &= m_a20_mask; - mem_pwd16(address, value); - } -} -void i386_device::WRITE32(uint32_t ea, uint32_t value) -{ - uint32_t address = ea, error; - - if( !DWORD_ALIGNED(ea) ) { /* Unaligned write */ - WRITE8( address+0, value & 0xff ); - WRITE8( address+1, (value >> 8) & 0xff ); - WRITE8( address+2, (value >> 16) & 0xff ); - WRITE8( address+3, (value >> 24) & 0xff ); - } else { - if(!translate_address(m_CPL,TRANSLATE_WRITE,&address,&error)) - PF_THROW(error); - - ea &= m_a20_mask; - mem_pwd32(address, value); - } -} - -void i386_device::WRITE64(uint32_t ea, uint64_t value) -{ - uint32_t address = ea, error; - - if( !QWORD_ALIGNED(ea) ) { /* Unaligned write */ - WRITE8( address+0, value & 0xff ); - WRITE8( address+1, (value >> 8) & 0xff ); - WRITE8( address+2, (value >> 16) & 0xff ); - WRITE8( address+3, (value >> 24) & 0xff ); - WRITE8( address+4, (value >> 32) & 0xff ); - WRITE8( address+5, (value >> 40) & 0xff ); - WRITE8( address+6, (value >> 48) & 0xff ); - WRITE8( address+7, (value >> 56) & 0xff ); - } else { - if(!translate_address(m_CPL,TRANSLATE_WRITE,&address,&error)) - PF_THROW(error); - - ea &= m_a20_mask; - mem_pwd32(address+0, value & 0xffffffff); - mem_pwd32(address+4, (value >> 32) & 0xffffffff); - } -} - -/***********************************************************************************/ - -uint8_t i386_device::OR8(uint8_t dst, uint8_t src) -{ - uint8_t res = dst | src; - m_CF = m_OF = 0; - SetSZPF8(res); - return res; -} -uint16_t i386_device::OR16(uint16_t dst, uint16_t src) -{ - uint16_t res = dst | src; - m_CF = m_OF = 0; - SetSZPF16(res); - return res; -} -uint32_t i386_device::OR32(uint32_t dst, uint32_t src) -{ - uint32_t res = dst | src; - m_CF = m_OF = 0; - SetSZPF32(res); - return res; -} - -uint8_t i386_device::AND8(uint8_t dst, uint8_t src) -{ - uint8_t res = dst & src; - m_CF = m_OF = 0; - SetSZPF8(res); - return res; -} -uint16_t i386_device::AND16(uint16_t dst, uint16_t src) -{ - uint16_t res = dst & src; - m_CF = m_OF = 0; - SetSZPF16(res); - return res; -} -uint32_t i386_device::AND32(uint32_t dst, uint32_t src) -{ - uint32_t res = dst & src; - m_CF = m_OF = 0; - SetSZPF32(res); - return res; -} - -uint8_t i386_device::XOR8(uint8_t dst, uint8_t src) -{ - uint8_t res = dst ^ src; - m_CF = m_OF = 0; - SetSZPF8(res); - return res; -} -uint16_t i386_device::XOR16(uint16_t dst, uint16_t src) -{ - uint16_t res = dst ^ src; - m_CF = m_OF = 0; - SetSZPF16(res); - return res; -} -uint32_t i386_device::XOR32(uint32_t dst, uint32_t src) -{ - uint32_t res = dst ^ src; - m_CF = m_OF = 0; - SetSZPF32(res); - return res; -} - -#define SUB8(dst, src) SBB8(dst, src, 0) -uint8_t i386_device::SBB8(uint8_t dst, uint8_t src, uint8_t b) -{ - uint16_t res = (uint16_t)dst - (uint16_t)src - (uint8_t)b; - SetCF8(res); - SetOF_Sub8(res,src,dst); - SetAF(res,src,dst); - SetSZPF8(res); - return (uint8_t)res; -} - -#define SUB16(dst, src) SBB16(dst, src, 0) -uint16_t i386_device::SBB16(uint16_t dst, uint16_t src, uint16_t b) -{ - uint32_t res = (uint32_t)dst - (uint32_t)src - (uint32_t)b; - SetCF16(res); - SetOF_Sub16(res,src,dst); - SetAF(res,src,dst); - SetSZPF16(res); - return (uint16_t)res; -} - -#define SUB32(dst, src) SBB32(dst, src, 0) -uint32_t i386_device::SBB32(uint32_t dst, uint32_t src, uint32_t b) -{ - uint64_t res = (uint64_t)dst - (uint64_t)src - (uint64_t) b; - SetCF32(res); - SetOF_Sub32(res,src,dst); - SetAF(res,src,dst); - SetSZPF32(res); - return (uint32_t)res; -} - -#define ADD8(dst, src) ADC8(dst, src, 0) -uint8_t i386_device::ADC8(uint8_t dst, uint8_t src, uint8_t c) -{ - uint16_t res = (uint16_t)dst + (uint16_t)src + (uint16_t)c; - SetCF8(res); - SetOF_Add8(res,src,dst); - SetAF(res,src,dst); - SetSZPF8(res); - return (uint8_t)res; -} - -#define ADD16(dst, src) ADC16(dst, src, 0) -uint16_t i386_device::ADC16(uint16_t dst, uint16_t src, uint8_t c) -{ - uint32_t res = (uint32_t)dst + (uint32_t)src + (uint32_t)c; - SetCF16(res); - SetOF_Add16(res,src,dst); - SetAF(res,src,dst); - SetSZPF16(res); - return (uint16_t)res; -} - -#define ADD32(dst, src) ADC32(dst, src, 0) -uint32_t i386_device::ADC32(uint32_t dst, uint32_t src, uint32_t c) -{ - uint64_t res = (uint64_t)dst + (uint64_t)src + (uint64_t) c; - SetCF32(res); - SetOF_Add32(res,src,dst); - SetAF(res,src,dst); - SetSZPF32(res); - return (uint32_t)res; -} - -uint8_t i386_device::INC8(uint8_t dst) -{ - uint16_t res = (uint16_t)dst + 1; - SetOF_Add8(res,1,dst); - SetAF(res,1,dst); - SetSZPF8(res); - return (uint8_t)res; -} -uint16_t i386_device::INC16(uint16_t dst) -{ - uint32_t res = (uint32_t)dst + 1; - SetOF_Add16(res,1,dst); - SetAF(res,1,dst); - SetSZPF16(res); - return (uint16_t)res; -} -uint32_t i386_device::INC32(uint32_t dst) -{ - uint64_t res = (uint64_t)dst + 1; - SetOF_Add32(res,1,dst); - SetAF(res,1,dst); - SetSZPF32(res); - return (uint32_t)res; -} - -uint8_t i386_device::DEC8(uint8_t dst) -{ - uint16_t res = (uint16_t)dst - 1; - SetOF_Sub8(res,1,dst); - SetAF(res,1,dst); - SetSZPF8(res); - return (uint8_t)res; -} -uint16_t i386_device::DEC16(uint16_t dst) -{ - uint32_t res = (uint32_t)dst - 1; - SetOF_Sub16(res,1,dst); - SetAF(res,1,dst); - SetSZPF16(res); - return (uint16_t)res; -} -uint32_t i386_device::DEC32(uint32_t dst) -{ - uint64_t res = (uint64_t)dst - 1; - SetOF_Sub32(res,1,dst); - SetAF(res,1,dst); - SetSZPF32(res); - return (uint32_t)res; -} - - - -void i386_device::PUSH16(uint16_t value) -{ - uint32_t ea, new_esp; - if( STACK_32BIT ) { - new_esp = REG32(ESP) - 2; - ea = i386_translate(SS, new_esp, 1); - WRITE16(ea, value ); - REG32(ESP) = new_esp; - } else { - new_esp = (REG16(SP) - 2) & 0xffff; - ea = i386_translate(SS, new_esp, 1); - WRITE16(ea, value ); - REG16(SP) = new_esp; - } -} -void i386_device::PUSH32(uint32_t value) -{ - uint32_t ea, new_esp; - if( STACK_32BIT ) { - new_esp = REG32(ESP) - 4; - ea = i386_translate(SS, new_esp, 1); - WRITE32(ea, value ); - REG32(ESP) = new_esp; - } else { - new_esp = (REG16(SP) - 4) & 0xffff; - ea = i386_translate(SS, new_esp, 1); - WRITE32(ea, value ); - REG16(SP) = new_esp; - } -} - -void i386_device::PUSH32SEG(uint32_t value) -{ - uint32_t ea, new_esp; - if( STACK_32BIT ) { - new_esp = REG32(ESP) - 4; - ea = i386_translate(SS, new_esp, 1); - ((m_cpu_version & 0xf00) == 0x300) ? WRITE16(ea, value) : WRITE32(ea, value ); // 486 also? - REG32(ESP) = new_esp; - } else { - new_esp = (REG16(SP) - 4) & 0xffff; - ea = i386_translate(SS, new_esp, 1); - ((m_cpu_version & 0xf00) == 0x300) ? WRITE16(ea, value) : WRITE32(ea, value ); - REG16(SP) = new_esp; - } -} - -void i386_device::PUSH8(uint8_t value) -{ - if( m_operand_size ) { - PUSH32((int32_t)(int8_t)value); - } else { - PUSH16((int16_t)(int8_t)value); - } -} - -uint8_t i386_device::POP8() -{ - uint8_t value; - uint32_t ea, new_esp; - if( STACK_32BIT ) { - new_esp = REG32(ESP) + 1; - ea = i386_translate(SS, new_esp - 1, 0); - value = READ8(ea ); - REG32(ESP) = new_esp; - } else { - new_esp = REG16(SP) + 1; - ea = i386_translate(SS, (new_esp - 1) & 0xffff, 0); - value = READ8(ea ); - REG16(SP) = new_esp; - } - return value; -} -uint16_t i386_device::POP16() -{ - uint16_t value; - uint32_t ea, new_esp; - if( STACK_32BIT ) { - new_esp = REG32(ESP) + 2; - ea = i386_translate(SS, new_esp - 2, 0); - value = READ16(ea ); - REG32(ESP) = new_esp; - } else { - new_esp = REG16(SP) + 2; - ea = i386_translate(SS, (new_esp - 2) & 0xffff, 0); - value = READ16(ea ); - REG16(SP) = new_esp; - } - return value; -} -uint32_t i386_device::POP32() -{ - uint32_t value; - uint32_t ea, new_esp; - if( STACK_32BIT ) { - new_esp = REG32(ESP) + 4; - ea = i386_translate(SS, new_esp - 4, 0); - value = READ32(ea ); - REG32(ESP) = new_esp; - } else { - new_esp = REG16(SP) + 4; - ea = i386_translate(SS, (new_esp - 4) & 0xffff, 0); - value = READ32(ea ); - REG16(SP) = new_esp; - } - return value; -} - -void i386_device::BUMP_SI(int adjustment) -{ - if ( m_address_size ) - REG32(ESI) += ((m_DF) ? -adjustment : +adjustment); - else - REG16(SI) += ((m_DF) ? -adjustment : +adjustment); -} - -void i386_device::BUMP_DI(int adjustment) -{ - if ( m_address_size ) - REG32(EDI) += ((m_DF) ? -adjustment : +adjustment); - else - REG16(DI) += ((m_DF) ? -adjustment : +adjustment); -} - -void i386_device::CYCLES(int x) -{ - if (PROTECTED_MODE) - { - m_cycles -= m_cycle_table_pm[x]; - } - else - { - m_cycles -= m_cycle_table_rm[x]; - } -} - -void i386_device::CYCLES_RM(int modrm, int r, int m) -{ - if (modrm >= 0xc0) - { - if (PROTECTED_MODE) - { - m_cycles -= m_cycle_table_pm[r]; - } - else - { - m_cycles -= m_cycle_table_rm[r]; - } - } - else - { - if (PROTECTED_MODE) - { - m_cycles -= m_cycle_table_pm[m]; - } - else - { - m_cycles -= m_cycle_table_rm[m]; - } - } -} - - - -/*********************************************************************************** - I/O ACCESS -***********************************************************************************/ - -void i386_device::check_ioperm(offs_t port, uint8_t mask) -{ - uint8_t IOPL, map; - uint16_t IOPB; - uint32_t address; - - if(!PROTECTED_MODE) - return; - - IOPL = m_IOP1 | (m_IOP2 << 1); - if(!V8086_MODE && (m_CPL <= IOPL)) - return; - - if((m_task.limit < 0x67) || ((m_task.flags & 0xd) != 9)) - FAULT_THROW(FAULT_GP,0); - - address = m_task.base; - IOPB = READ16PL0(address+0x66); - if((IOPB+(port/8)) > m_task.limit) - FAULT_THROW(FAULT_GP,0); - - map = READ8PL0(address+IOPB+(port/8)); - map >>= (port%8); - if(map & mask) - FAULT_THROW(FAULT_GP,0); -} - -uint8_t i386_device::READPORT8(offs_t port) -{ - check_ioperm(port, 1); - return m_io->read_byte(port); -} - -void i386_device::WRITEPORT8(offs_t port, uint8_t value) -{ - check_ioperm(port, 1); - m_io->write_byte(port, value); -} - -uint16_t i386_device::READPORT16(offs_t port) -{ - if (port & 1) - { - uint16_t value = READPORT8(port); - value |= (READPORT8(port + 1) << 8); - return value; - } - else - { - check_ioperm(port, 3); - return m_io->read_word(port); - } -} - -void i386_device::WRITEPORT16(offs_t port, uint16_t value) -{ - if (port & 1) - { - WRITEPORT8(port, value & 0xff); - WRITEPORT8(port + 1, (value >> 8) & 0xff); - } - else - { - check_ioperm(port, 3); - m_io->write_word(port, value); - } -} - -uint32_t i386_device::READPORT32(offs_t port) -{ - if (port & 3) - { - uint32_t value = READPORT8(port); - value |= (READPORT8(port + 1) << 8); - value |= (READPORT8(port + 2) << 16); - value |= (READPORT8(port + 3) << 24); - return value; - } - else - { - check_ioperm(port, 0xf); - return m_io->read_dword(port); - } -} - -void i386_device::WRITEPORT32(offs_t port, uint32_t value) -{ - if (port & 3) - { - WRITEPORT8(port, value & 0xff); - WRITEPORT8(port + 1, (value >> 8) & 0xff); - WRITEPORT8(port + 2, (value >> 16) & 0xff); - WRITEPORT8(port + 3, (value >> 24) & 0xff); - } - else - { - check_ioperm(port, 0xf); - m_io->write_dword(port, value); - } -} - -#endif /* __I386_H__ */ diff --git a/source/src/vm/libcpu_newdev/i386/i486ops.hxx b/source/src/vm/libcpu_newdev/i386/i486ops.hxx deleted file mode 100644 index 052fdf4a3..000000000 --- a/source/src/vm/libcpu_newdev/i386/i486ops.hxx +++ /dev/null @@ -1,535 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett -// Intel 486+ specific opcodes - -void i386_device::i486_cpuid() // Opcode 0x0F A2 -{ - if (m_cpuid_id0 == 0) - { - // this 486 doesn't support the CPUID instruction - logerror("CPUID not supported at %08x!\n", m_eip); - i386_trap(6, 0, 0); - } - else - { - switch (REG32(EAX)) - { - case 0: - { - REG32(EAX) = m_cpuid_max_input_value_eax; - REG32(EBX) = m_cpuid_id0; - REG32(ECX) = m_cpuid_id2; - REG32(EDX) = m_cpuid_id1; - CYCLES(CYCLES_CPUID); - break; - } - - case 1: - { - REG32(EAX) = m_cpu_version; - REG32(EDX) = m_feature_flags; - CYCLES(CYCLES_CPUID_EAX1); - break; - } - - default: - { - // call the model specific implementation - opcode_cpuid(); - break; - } - } - } -} - -void i386_device::i486_invd() // Opcode 0x0f 08 -{ - // TODO: manage the cache if present - opcode_invd(); - CYCLES(CYCLES_INVD); -} - -void i386_device::i486_wbinvd() // Opcode 0x0f 09 -{ - // TODO: manage the cache if present - opcode_wbinvd(); -} - -void i386_device::i486_cmpxchg_rm8_r8() // Opcode 0x0f b0 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t dst = LOAD_RM8(modrm); - uint8_t src = LOAD_REG8(modrm); - - if( REG8(AL) == dst ) { - STORE_RM8(modrm, src); - m_ZF = 1; - CYCLES(CYCLES_CMPXCHG_REG_REG_T); - } else { - REG8(AL) = dst; - m_ZF = 0; - CYCLES(CYCLES_CMPXCHG_REG_REG_F); - } - } else { - // TODO: Check write if needed - uint32_t ea = GetEA(modrm,0); - uint8_t dst = READ8(ea); - uint8_t src = LOAD_REG8(modrm); - - if( REG8(AL) == dst ) { - WRITE8(ea, src); - m_ZF = 1; - CYCLES(CYCLES_CMPXCHG_REG_MEM_T); - } else { - REG8(AL) = dst; - m_ZF = 0; - CYCLES(CYCLES_CMPXCHG_REG_MEM_F); - } - } -} - -void i386_device::i486_cmpxchg_rm16_r16() // Opcode 0x0f b1 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t src = LOAD_REG16(modrm); - - if( REG16(AX) == dst ) { - STORE_RM16(modrm, src); - m_ZF = 1; - CYCLES(CYCLES_CMPXCHG_REG_REG_T); - } else { - REG16(AX) = dst; - m_ZF = 0; - CYCLES(CYCLES_CMPXCHG_REG_REG_F); - } - } else { - uint32_t ea = GetEA(modrm,0); - uint16_t dst = READ16(ea); - uint16_t src = LOAD_REG16(modrm); - - if( REG16(AX) == dst ) { - WRITE16(ea, src); - m_ZF = 1; - CYCLES(CYCLES_CMPXCHG_REG_MEM_T); - } else { - REG16(AX) = dst; - m_ZF = 0; - CYCLES(CYCLES_CMPXCHG_REG_MEM_F); - } - } -} - -void i386_device::i486_cmpxchg_rm32_r32() // Opcode 0x0f b1 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t src = LOAD_REG32(modrm); - - if( REG32(EAX) == dst ) { - STORE_RM32(modrm, src); - m_ZF = 1; - CYCLES(CYCLES_CMPXCHG_REG_REG_T); - } else { - REG32(EAX) = dst; - m_ZF = 0; - CYCLES(CYCLES_CMPXCHG_REG_REG_F); - } - } else { - uint32_t ea = GetEA(modrm,0); - uint32_t dst = READ32(ea); - uint32_t src = LOAD_REG32(modrm); - - if( REG32(EAX) == dst ) { - WRITE32(ea, src); - m_ZF = 1; - CYCLES(CYCLES_CMPXCHG_REG_MEM_T); - } else { - REG32(EAX) = dst; - m_ZF = 0; - CYCLES(CYCLES_CMPXCHG_REG_MEM_F); - } - } -} - -void i386_device::i486_xadd_rm8_r8() // Opcode 0x0f c0 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t dst = LOAD_RM8(modrm); - uint8_t src = LOAD_REG8(modrm); - uint8_t sum = ADD8(dst, src); - STORE_REG8(modrm, dst); - STORE_RM8(modrm, sum); - CYCLES(CYCLES_XADD_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint8_t dst = READ8(ea); - uint8_t src = LOAD_REG8(modrm); - uint8_t sum = ADD8(dst, src); - WRITE8(ea, sum); - STORE_REG8(modrm, dst); - CYCLES(CYCLES_XADD_REG_MEM); - } -} - -void i386_device::i486_xadd_rm16_r16() // Opcode 0x0f c1 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t dst = LOAD_RM16(modrm); - uint16_t src = LOAD_REG16(modrm); - uint16_t sum = ADD16(dst, src); - STORE_REG16(modrm, dst); - STORE_RM16(modrm, sum); - CYCLES(CYCLES_XADD_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint16_t dst = READ16(ea); - uint16_t src = LOAD_REG16(modrm); - uint16_t sum = ADD16(dst, src); - WRITE16(ea, sum); - STORE_REG16(modrm, dst); - CYCLES(CYCLES_XADD_REG_MEM); - } -} - -void i386_device::i486_xadd_rm32_r32() // Opcode 0x0f c1 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t dst = LOAD_RM32(modrm); - uint32_t src = LOAD_REG32(modrm); - uint32_t sum = ADD32(dst, src); - STORE_REG32(modrm, dst); - STORE_RM32(modrm, sum); - CYCLES(CYCLES_XADD_REG_REG); - } else { - uint32_t ea = GetEA(modrm,1); - uint32_t dst = READ32(ea); - uint32_t src = LOAD_REG32(modrm); - uint32_t sum = ADD32(dst, src); - WRITE32(ea, sum); - STORE_REG32(modrm, dst); - CYCLES(CYCLES_XADD_REG_MEM); - } -} - -void i386_device::i486_group0F01_16() // Opcode 0x0f 01 -{ - uint8_t modrm = FETCH(); - uint16_t address; - uint32_t ea; - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* SGDT */ - { - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - ea = i386_translate( CS, address, 1 ); - } else { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_gdtr.limit); - // Win32s requires all 32 bits to be stored here, despite various Intel docs - // claiming that the upper 8 bits are either zeroed or undefined in 16-bit mode - WRITE32(ea + 2, m_gdtr.base); - CYCLES(CYCLES_SGDT); - break; - } - case 1: /* SIDT */ - { - if (modrm >= 0xc0) - { - address = LOAD_RM16(modrm); - ea = i386_translate( CS, address, 1 ); - } - else - { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_idtr.limit); - WRITE32(ea + 2, m_idtr.base); - CYCLES(CYCLES_SIDT); - break; - } - case 2: /* LGDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - ea = i386_translate( CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_gdtr.limit = READ16(ea); - m_gdtr.base = READ32(ea + 2) & 0xffffff; - CYCLES(CYCLES_LGDT); - break; - } - case 3: /* LIDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM16(modrm); - ea = i386_translate( CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_idtr.limit = READ16(ea); - m_idtr.base = READ32(ea + 2) & 0xffffff; - CYCLES(CYCLES_LIDT); - break; - } - case 4: /* SMSW */ - { - if( modrm >= 0xc0 ) { - STORE_RM16(modrm, m_cr[0]); - CYCLES(CYCLES_SMSW_REG); - } else { - ea = GetEA(modrm,1); - WRITE16(ea, m_cr[0]); - CYCLES(CYCLES_SMSW_MEM); - } - break; - } - case 6: /* LMSW */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - uint16_t b; - if( modrm >= 0xc0 ) { - b = LOAD_RM16(modrm); - CYCLES(CYCLES_LMSW_REG); - } else { - ea = GetEA(modrm,0); - CYCLES(CYCLES_LMSW_MEM); - b = READ16(ea); - } - if(PROTECTED_MODE) - b |= 0x0001; // cannot return to real mode using this instruction. - m_cr[0] &= ~0x0000000f; - m_cr[0] |= b & 0x0000000f; - break; - } - case 7: /* INVLPG */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if(modrm >= 0xc0) - { - logerror("i486: invlpg with modrm %02X\n", modrm); - FAULT(FAULT_UD,0) - } - ea = GetEA(modrm,-1); - CYCLES(25); // TODO: add to cycles.h - d_vtlb->vtlb_flush_address(ea); - break; - } - default: - report_invalid_modrm("group0F01_16", modrm); - break; - } -} - -void i386_device::i486_group0F01_32() // Opcode 0x0f 01 -{ - uint8_t modrm = FETCH(); - uint32_t address, ea; - - switch( (modrm >> 3) & 0x7 ) - { - case 0: /* SGDT */ - { - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - ea = i386_translate( CS, address, 1 ); - } else { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_gdtr.limit); - WRITE32(ea + 2, m_gdtr.base); - CYCLES(CYCLES_SGDT); - break; - } - case 1: /* SIDT */ - { - if (modrm >= 0xc0) - { - address = LOAD_RM32(modrm); - ea = i386_translate( CS, address, 1 ); - } - else - { - ea = GetEA(modrm,1); - } - WRITE16(ea, m_idtr.limit); - WRITE32(ea + 2, m_idtr.base); - CYCLES(CYCLES_SIDT); - break; - } - case 2: /* LGDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - ea = i386_translate( CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_gdtr.limit = READ16(ea); - m_gdtr.base = READ32(ea + 2); - CYCLES(CYCLES_LGDT); - break; - } - case 3: /* LIDT */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if( modrm >= 0xc0 ) { - address = LOAD_RM32(modrm); - ea = i386_translate( CS, address, 0 ); - } else { - ea = GetEA(modrm,0); - } - m_idtr.limit = READ16(ea); - m_idtr.base = READ32(ea + 2); - CYCLES(CYCLES_LIDT); - break; - } - case 4: /* SMSW */ - { - if( modrm >= 0xc0 ) { - STORE_RM32(modrm, m_cr[0] & 0xffff); - CYCLES(CYCLES_SMSW_REG); - } else { - /* always 16-bit memory operand */ - ea = GetEA(modrm,1); - WRITE16(ea, m_cr[0]); - CYCLES(CYCLES_SMSW_MEM); - } - break; - } - case 6: /* LMSW */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - uint16_t b; - if( modrm >= 0xc0 ) { - b = LOAD_RM16(modrm); - CYCLES(CYCLES_LMSW_REG); - } else { - ea = GetEA(modrm,0); - CYCLES(CYCLES_LMSW_MEM); - b = READ16(ea); - } - if(PROTECTED_MODE) - b |= 0x0001; // cannot return to real mode using this instruction. - m_cr[0] &= ~0x0000000f; - m_cr[0] |= b & 0x0000000f; - break; - } - case 7: /* INVLPG */ - { - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP,0) - if(modrm >= 0xc0) - { - logerror("i486: invlpg with modrm %02X\n", modrm); - FAULT(FAULT_UD,0) - } - ea = GetEA(modrm,-1); - CYCLES(25); // TODO: add to cycles.h - d_vtlb->vtlb_flush_address(ea); - break; - } - default: - report_invalid_modrm("group0F01_32", modrm); - break; - } -} - -void i386_device::i486_bswap_eax() // Opcode 0x0f 38 -{ - REG32(EAX) = SWITCH_ENDIAN_32(REG32(EAX)); - CYCLES(1); // TODO -} - -void i386_device::i486_bswap_ecx() // Opcode 0x0f 39 -{ - REG32(ECX) = SWITCH_ENDIAN_32(REG32(ECX)); - CYCLES(1); // TODO -} - -void i386_device::i486_bswap_edx() // Opcode 0x0f 3A -{ - REG32(EDX) = SWITCH_ENDIAN_32(REG32(EDX)); - CYCLES(1); // TODO -} - -void i386_device::i486_bswap_ebx() // Opcode 0x0f 3B -{ - REG32(EBX) = SWITCH_ENDIAN_32(REG32(EBX)); - CYCLES(1); // TODO -} - -void i386_device::i486_bswap_esp() // Opcode 0x0f 3C -{ - REG32(ESP) = SWITCH_ENDIAN_32(REG32(ESP)); - CYCLES(1); // TODO -} - -void i386_device::i486_bswap_ebp() // Opcode 0x0f 3D -{ - REG32(EBP) = SWITCH_ENDIAN_32(REG32(EBP)); - CYCLES(1); // TODO -} - -void i386_device::i486_bswap_esi() // Opcode 0x0f 3E -{ - REG32(ESI) = SWITCH_ENDIAN_32(REG32(ESI)); - CYCLES(1); // TODO -} - -void i386_device::i486_bswap_edi() // Opcode 0x0f 3F -{ - REG32(EDI) = SWITCH_ENDIAN_32(REG32(EDI)); - CYCLES(1); // TODO -} - -void i386_device::i486_mov_cr_r32() // Opcode 0x0f 22 -{ - if(PROTECTED_MODE && m_CPL) - FAULT(FAULT_GP, 0); - uint8_t modrm = FETCH(); - uint8_t cr = (modrm >> 3) & 0x7; - uint32_t oldcr = m_cr[cr]; - uint32_t data = LOAD_RM32(modrm); - switch(cr) - { - case 0: - CYCLES(CYCLES_MOV_REG_CR0); - if((oldcr ^ m_cr[cr]) & 0x80010000) - d_vtlb->vtlb_flush_dynamic(); - if (PROTECTED_MODE != BIT(data, 0)) - debugger_privilege_hook(); - break; - case 2: CYCLES(CYCLES_MOV_REG_CR2); break; - case 3: - CYCLES(CYCLES_MOV_REG_CR3); - d_vtlb->vtlb_flush_dynamic(); - break; - case 4: CYCLES(1); break; // TODO - default: - logerror("i386: mov_cr_r32 CR%d!\n", cr); - return; - } - m_cr[cr] = data; -} diff --git a/source/src/vm/libcpu_newdev/i386/pentops.hxx b/source/src/vm/libcpu_newdev/i386/pentops.hxx deleted file mode 100644 index b44ce8c40..000000000 --- a/source/src/vm/libcpu_newdev/i386/pentops.hxx +++ /dev/null @@ -1,6659 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Ville Linde, Barry Rodewald, Carl, Philip Bennett, Samuele Zannoli -// Pentium+ specific opcodes - -extern flag float32_is_nan( float32 a ); // since its not defined in softfloat.h -extern flag float64_is_nan( float64 a ); // since its not defined in softfloat.h - -void i386_device::MMXPROLOG() -{ - //m_x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); // top = 0 - m_x87_tw = 0; // tag word = 0 -} - -void i386_device::READMMX(uint32_t ea,MMX_REG &r) -{ - r.q=READ64(ea); -} - -void i386_device::WRITEMMX(uint32_t ea,MMX_REG &r) -{ - WRITE64(ea, r.q); -} - -void i386_device::READXMM(uint32_t ea,XMM_REG &r) -{ - r.q[0]=READ64(ea); - r.q[1]=READ64(ea+8); -} - -void i386_device::WRITEXMM(uint32_t ea,i386_device::XMM_REG &r) -{ - WRITE64(ea, r.q[0]); - WRITE64(ea+8, r.q[1]); -} - -void i386_device::READXMM_LO64(uint32_t ea,i386_device::XMM_REG &r) -{ - r.q[0]=READ64(ea); -} - -void i386_device::WRITEXMM_LO64(uint32_t ea,i386_device::XMM_REG &r) -{ - WRITE64(ea, r.q[0]); -} - -void i386_device::READXMM_HI64(uint32_t ea,i386_device::XMM_REG &r) -{ - r.q[1]=READ64(ea); -} - -void i386_device::WRITEXMM_HI64(uint32_t ea,i386_device::XMM_REG &r) -{ - WRITE64(ea, r.q[1]); -} - -void i386_device::pentium_rdmsr() // Opcode 0x0f 32 -{ - uint64_t data; - bool valid_msr = false; - - // call the model specific implementation - data = opcode_rdmsr(valid_msr); - if (m_CPL != 0 || valid_msr == false) // if current privilege level isn't 0 or the register isn't recognized ... - FAULT(FAULT_GP, 0) // ... throw a general exception fault - else - { - REG32(EDX) = data >> 32; - REG32(EAX) = data & 0xffffffff; - } - - CYCLES(CYCLES_RDMSR); -} - -void i386_device::pentium_wrmsr() // Opcode 0x0f 30 -{ - uint64_t data; - bool valid_msr = false; - - data = (uint64_t)REG32(EAX); - data |= (uint64_t)(REG32(EDX)) << 32; - - // call the model specific implementation - opcode_wrmsr(data, valid_msr); - - if(m_CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized - FAULT(FAULT_GP,0) // ... throw a general exception fault - - CYCLES(1); // TODO: correct cycle count (~30-45) -} - -void i386_device::pentium_rdtsc() // Opcode 0x0f 31 -{ - uint64_t ts = m_tsc + (m_base_cycles - m_cycles); - REG32(EAX) = (uint32_t)(ts); - REG32(EDX) = (uint32_t)(ts >> 32); - - CYCLES(CYCLES_RDTSC); -} - -void i386_device::pentium_ud2() // Opcode 0x0f 0b -{ - i386_trap(6, 0, 0); -} - -void i386_device::pentium_rsm() -{ - uint32_t smram_state = m_smbase + 0xfe00; - if(!m_smm) - { - logerror("i386: Invalid RSM outside SMM at %08X\n", m_pc - 1); - i386_trap(6, 0, 0); - return; - } - - // load state, no sanity checks anywhere - m_smbase = READ32(smram_state+SMRAM_SMBASE); - m_cr[4] = READ32(smram_state+SMRAM_IP5_CR4); - m_sreg[ES].limit = READ32(smram_state+SMRAM_IP5_ESLIM); - m_sreg[ES].base = READ32(smram_state+SMRAM_IP5_ESBASE); - m_sreg[ES].flags = READ32(smram_state+SMRAM_IP5_ESACC); - m_sreg[CS].limit = READ32(smram_state+SMRAM_IP5_CSLIM); - m_sreg[CS].base = READ32(smram_state+SMRAM_IP5_CSBASE); - m_sreg[CS].flags = READ32(smram_state+SMRAM_IP5_CSACC); - m_sreg[SS].limit = READ32(smram_state+SMRAM_IP5_SSLIM); - m_sreg[SS].base = READ32(smram_state+SMRAM_IP5_SSBASE); - m_sreg[SS].flags = READ32(smram_state+SMRAM_IP5_SSACC); - m_sreg[DS].limit = READ32(smram_state+SMRAM_IP5_DSLIM); - m_sreg[DS].base = READ32(smram_state+SMRAM_IP5_DSBASE); - m_sreg[DS].flags = READ32(smram_state+SMRAM_IP5_DSACC); - m_sreg[FS].limit = READ32(smram_state+SMRAM_IP5_FSLIM); - m_sreg[FS].base = READ32(smram_state+SMRAM_IP5_FSBASE); - m_sreg[FS].flags = READ32(smram_state+SMRAM_IP5_FSACC); - m_sreg[GS].limit = READ32(smram_state+SMRAM_IP5_GSLIM); - m_sreg[GS].base = READ32(smram_state+SMRAM_IP5_GSBASE); - m_sreg[GS].flags = READ32(smram_state+SMRAM_IP5_GSACC); - m_ldtr.flags = READ32(smram_state+SMRAM_IP5_LDTACC); - m_ldtr.limit = READ32(smram_state+SMRAM_IP5_LDTLIM); - m_ldtr.base = READ32(smram_state+SMRAM_IP5_LDTBASE); - m_gdtr.limit = READ32(smram_state+SMRAM_IP5_GDTLIM); - m_gdtr.base = READ32(smram_state+SMRAM_IP5_GDTBASE); - m_idtr.limit = READ32(smram_state+SMRAM_IP5_IDTLIM); - m_idtr.base = READ32(smram_state+SMRAM_IP5_IDTBASE); - m_task.limit = READ32(smram_state+SMRAM_IP5_TRLIM); - m_task.base = READ32(smram_state+SMRAM_IP5_TRBASE); - m_task.flags = READ32(smram_state+SMRAM_IP5_TRACC); - - m_sreg[ES].selector = READ32(smram_state+SMRAM_ES); - m_sreg[CS].selector = READ32(smram_state+SMRAM_CS); - m_sreg[SS].selector = READ32(smram_state+SMRAM_SS); - m_sreg[DS].selector = READ32(smram_state+SMRAM_DS); - m_sreg[FS].selector = READ32(smram_state+SMRAM_FS); - m_sreg[GS].selector = READ32(smram_state+SMRAM_GS); - m_ldtr.segment = READ32(smram_state+SMRAM_LDTR); - m_task.segment = READ32(smram_state+SMRAM_TR); - - m_dr[7] = READ32(smram_state+SMRAM_DR7); - m_dr[6] = READ32(smram_state+SMRAM_DR6); - REG32(EAX) = READ32(smram_state+SMRAM_EAX); - REG32(ECX) = READ32(smram_state+SMRAM_ECX); - REG32(EDX) = READ32(smram_state+SMRAM_EDX); - REG32(EBX) = READ32(smram_state+SMRAM_EBX); - REG32(ESP) = READ32(smram_state+SMRAM_ESP); - REG32(EBP) = READ32(smram_state+SMRAM_EBP); - REG32(ESI) = READ32(smram_state+SMRAM_ESI); - REG32(EDI) = READ32(smram_state+SMRAM_EDI); - m_eip = READ32(smram_state+SMRAM_EIP); - m_eflags = READ32(smram_state+SMRAM_EFLAGS); - m_cr[3] = READ32(smram_state+SMRAM_CR3); - m_cr[0] = READ32(smram_state+SMRAM_CR0); - - m_CPL = (m_sreg[SS].flags >> 13) & 3; // cpl == dpl of ss - - for(int i = 0; i <= GS; i++) - { - if(PROTECTED_MODE && !V8086_MODE) - { - m_sreg[i].valid = m_sreg[i].selector ? true : false; - m_sreg[i].d = (m_sreg[i].flags & 0x4000) ? 1 : 0; - } - else - m_sreg[i].valid = true; - } - - if(!m_smiact.isnull()) - m_smiact(false); - m_smm = false; - - CHANGE_PC(m_eip); - m_nmi_masked = false; - if(m_smi_latched) - { - pentium_smi(); - return; - } - if(m_nmi_latched) - { - m_nmi_latched = false; - i386_trap(2, 1, 0); - } -} - -void i386_device::pentium_prefetch_m8() // Opcode 0x0f 18 -{ - uint8_t modrm = FETCH(); - uint32_t ea = GetEA(modrm,0); - // TODO: manage the cache if present - CYCLES(1+(ea & 1)); // TODO: correct cycle count -} - -void i386_device::pentium_cmovo_r16_rm16() // Opcode 0x0f 40 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_OF == 1) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_OF == 1) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovo_r32_rm32() // Opcode 0x0f 40 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_OF == 1) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_OF == 1) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovno_r16_rm16() // Opcode 0x0f 41 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_OF == 0) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_OF == 0) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovno_r32_rm32() // Opcode 0x0f 41 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_OF == 0) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_OF == 0) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovb_r16_rm16() // Opcode 0x0f 42 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_CF == 1) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_CF == 1) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovb_r32_rm32() // Opcode 0x0f 42 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_CF == 1) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_CF == 1) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovae_r16_rm16() // Opcode 0x0f 43 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_CF == 0) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_CF == 0) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovae_r32_rm32() // Opcode 0x0f 43 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_CF == 0) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_CF == 0) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmove_r16_rm16() // Opcode 0x0f 44 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_ZF == 1) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_ZF == 1) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmove_r32_rm32() // Opcode 0x0f 44 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_ZF == 1) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_ZF == 1) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovne_r16_rm16() // Opcode 0x0f 45 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_ZF == 0) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_ZF == 0) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovne_r32_rm32() // Opcode 0x0f 45 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_ZF == 0) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_ZF == 0) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovbe_r16_rm16() // Opcode 0x0f 46 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_CF == 1) || (m_ZF == 1)) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_CF == 1) || (m_ZF == 1)) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovbe_r32_rm32() // Opcode 0x0f 46 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_CF == 1) || (m_ZF == 1)) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_CF == 1) || (m_ZF == 1)) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmova_r16_rm16() // Opcode 0x0f 47 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_CF == 0) && (m_ZF == 0)) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_CF == 0) && (m_ZF == 0)) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmova_r32_rm32() // Opcode 0x0f 47 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_CF == 0) && (m_ZF == 0)) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_CF == 0) && (m_ZF == 0)) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovs_r16_rm16() // Opcode 0x0f 48 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF == 1) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF == 1) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovs_r32_rm32() // Opcode 0x0f 48 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF == 1) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF == 1) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovns_r16_rm16() // Opcode 0x0f 49 -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF == 0) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF == 0) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovns_r32_rm32() // Opcode 0x0f 49 -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF == 0) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF == 0) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovp_r16_rm16() // Opcode 0x0f 4a -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_PF == 1) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_PF == 1) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovp_r32_rm32() // Opcode 0x0f 4a -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_PF == 1) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_PF == 1) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovnp_r16_rm16() // Opcode 0x0f 4b -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_PF == 0) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_PF == 0) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovnp_r32_rm32() // Opcode 0x0f 4b -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_PF == 0) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_PF == 0) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovl_r16_rm16() // Opcode 0x0f 4c -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF != m_OF) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF != m_OF) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovl_r32_rm32() // Opcode 0x0f 4c -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF != m_OF) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF != m_OF) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovge_r16_rm16() // Opcode 0x0f 4d -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF == m_OF) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF == m_OF) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovge_r32_rm32() // Opcode 0x0f 4d -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if (m_SF == m_OF) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if (m_SF == m_OF) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovle_r16_rm16() // Opcode 0x0f 4e -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_ZF == 1) || (m_SF != m_OF)) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_ZF == 1) || (m_SF != m_OF)) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovle_r32_rm32() // Opcode 0x0f 4e -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_ZF == 1) || (m_SF != m_OF)) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_ZF == 1) || (m_SF != m_OF)) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovg_r16_rm16() // Opcode 0x0f 4f -{ - uint16_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_ZF == 0) && (m_SF == m_OF)) - { - src = LOAD_RM16(modrm); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_ZF == 0) && (m_SF == m_OF)) - { - src = READ16(ea); - STORE_REG16(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_cmovg_r32_rm32() // Opcode 0x0f 4f -{ - uint32_t src; - uint8_t modrm = FETCH(); - - if( modrm >= 0xc0 ) - { - if ((m_ZF == 0) && (m_SF == m_OF)) - { - src = LOAD_RM32(modrm); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } - else - { - uint32_t ea = GetEA(modrm,0); - if ((m_ZF == 0) && (m_SF == m_OF)) - { - src = READ32(ea); - STORE_REG32(modrm, src); - } - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_movnti_m16_r16() // Opcode 0f c3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - // TODO: manage the cache if present - uint32_t ea = GetEA(modrm, 0); - WRITE16(ea,LOAD_RM16(modrm)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_movnti_m32_r32() // Opcode 0f c3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - // TODO: manage the cache if present - uint32_t ea = GetEA(modrm, 0); - WRITE32(ea,LOAD_RM32(modrm)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::i386_cyrix_special() // Opcode 0x0f 3a-3d -{ -/* -0f 3a BB0_RESET (set BB0 pointer = base) -0f 3b BB1_RESET (set BB1 pointer = base) -0f 3c CPU_WRITE (write special CPU memory-mapped register, [ebx] = eax) -0f 3d CPU_READ (read special CPU memory-mapped register, eax, = [ebx]) -*/ - - CYCLES(1); -} - -void i386_device::i386_cyrix_unknown() // Opcode 0x0f 74 -{ - logerror("Unemulated 0x0f 0x74 opcode called\n"); - - CYCLES(1); -} - -void i386_device::pentium_cmpxchg8b_m64() // Opcode 0x0f c7 -{ - uint8_t modm = FETCH(); - if( modm >= 0xc0 ) { - report_invalid_modrm("cmpxchg8b_m64", modm); - } else { - uint32_t ea = GetEA(modm, 0); - uint64_t value = READ64(ea); - uint64_t edx_eax = (((uint64_t) REG32(EDX)) << 32) | REG32(EAX); - uint64_t ecx_ebx = (((uint64_t) REG32(ECX)) << 32) | REG32(EBX); - - if( value == edx_eax ) { - WRITE64(ea, ecx_ebx); - m_ZF = 1; - CYCLES(CYCLES_CMPXCHG_REG_MEM_T); - } else { - REG32(EDX) = (uint32_t) (value >> 32); - REG32(EAX) = (uint32_t) (value >> 0); - m_ZF = 0; - CYCLES(CYCLES_CMPXCHG_REG_MEM_F); - } - } -} - -void i386_device::pentium_movntq_m64_r64() // Opcode 0f e7 -{ - //MMXPROLOG(); // TODO: check if needed - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - CYCLES(1); // unsupported - } else { - // TODO: manage the cache if present - uint32_t ea = GetEA(modrm, 0); - WRITEMMX(ea, MMX((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::pentium_maskmovq_r64_r64() // Opcode 0f f7 -{ - int s,m,n; - uint8_t modm = FETCH(); - uint32_t ea = GetEA(7, 0); // ds:di/edi/rdi register - MMXPROLOG(); - s=(modm >> 3) & 7; - m=modm & 7; - for (n=0;n <= 7;n++) - if (MMX(m).b[n] & 127) - WRITE8(ea+n, MMX(s).b[n]); -} - -void i386_device::sse_maskmovdqu_r128_r128() // Opcode 66 0f f7 -{ - int s,m,n; - uint8_t modm = FETCH(); - uint32_t ea = GetEA(7, 0); // ds:di/edi/rdi register - s=(modm >> 3) & 7; - m=modm & 7; - for (n=0;n < 16;n++) - if (XMM(m).b[n] & 127) - WRITE8(ea+n, XMM(s).b[n]); -} - -void i386_device::pentium_popcnt_r16_rm16() // Opcode f3 0f b8 -{ - uint16_t src; - uint8_t modrm = FETCH(); - int n,count; - - if( modrm >= 0xc0 ) { - src = LOAD_RM16(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ16(ea); - } - count=0; - for (n=0;n < 16;n++) { - count=count+(src & 1); - src=src >> 1; - } - STORE_REG16(modrm, count); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::pentium_popcnt_r32_rm32() // Opcode f3 0f b8 -{ - uint32_t src; - uint8_t modrm = FETCH(); - int n,count; - - if( modrm >= 0xc0 ) { - src = LOAD_RM32(modrm); - } else { - uint32_t ea = GetEA(modrm,0); - src = READ32(ea); - } - count=0; - for (n=0;n < 32;n++) { - count=count+(src & 1); - src=src >> 1; - } - STORE_REG32(modrm, count); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::pentium_tzcnt_r16_rm16() -{ - // for CPUs that don't support TZCNT, fall back to BSF - i386_bsf_r16_rm16(); - // TODO: actually implement TZCNT -} - -void i386_device::pentium_tzcnt_r32_rm32() -{ - // for CPUs that don't support TZCNT, fall back to BSF - i386_bsf_r32_rm32(); - // TODO: actually implement TZCNT -} - -static inline int8_t SaturatedSignedWordToSignedByte(int16_t word) -{ - if (word > 127) - return 127; - if (word < -128) - return -128; - return (int8_t)word; -} - -static inline uint8_t SaturatedSignedWordToUnsignedByte(int16_t word) -{ - if (word > 255) - return 255; - if (word < 0) - return 0; - return (uint8_t)word; -} - -static inline int16_t SaturatedSignedDwordToSignedWord(int32_t dword) -{ - if (dword > 32767) - return 32767; - if (dword < -32768) - return -32768; - return (int16_t)dword; -} - -static inline uint16_t SaturatedSignedDwordToUnsignedWord(int32_t dword) -{ - if (dword > 65535) - return 65535; - if (dword < 0) - return 0; - return (uint16_t)dword; -} - -void i386_device::mmx_group_0f71() // Opcode 0f 71 -{ - uint8_t modm = FETCH(); - uint8_t imm8 = FETCH(); - MMXPROLOG(); - if( modm >= 0xc0 ) { - switch ( (modm & 0x38) >> 3 ) - { - case 2: // psrlw - MMX(modm & 7).w[0]=MMX(modm & 7).w[0] >> imm8; - MMX(modm & 7).w[1]=MMX(modm & 7).w[1] >> imm8; - MMX(modm & 7).w[2]=MMX(modm & 7).w[2] >> imm8; - MMX(modm & 7).w[3]=MMX(modm & 7).w[3] >> imm8; - break; - case 4: // psraw - MMX(modm & 7).s[0]=MMX(modm & 7).s[0] >> imm8; - MMX(modm & 7).s[1]=MMX(modm & 7).s[1] >> imm8; - MMX(modm & 7).s[2]=MMX(modm & 7).s[2] >> imm8; - MMX(modm & 7).s[3]=MMX(modm & 7).s[3] >> imm8; - break; - case 6: // psllw - MMX(modm & 7).w[0]=MMX(modm & 7).w[0] << imm8; - MMX(modm & 7).w[1]=MMX(modm & 7).w[1] << imm8; - MMX(modm & 7).w[2]=MMX(modm & 7).w[2] << imm8; - MMX(modm & 7).w[3]=MMX(modm & 7).w[3] << imm8; - break; - default: - report_invalid_modrm("mmx_group0f71", modm); - } - } -} - -void i386_device::sse_group_660f71() // Opcode 66 0f 71 -{ - uint8_t modm = FETCH(); - uint8_t imm8 = FETCH(); - if (modm >= 0xc0) { - switch ((modm & 0x38) >> 3) - { - case 2: // psrlw - for (int n = 0; n < 8;n++) - XMM(modm & 7).w[n] = XMM(modm & 7).w[n] >> imm8; - break; - case 4: // psraw - for (int n = 0; n < 8;n++) - XMM(modm & 7).s[n] = XMM(modm & 7).s[n] >> imm8; - break; - case 6: // psllw - for (int n = 0; n < 8;n++) - XMM(modm & 7).w[n] = XMM(modm & 7).w[n] << imm8; - break; - default: - report_invalid_modrm("mmx_group660f71", modm); - } - } -} - -void i386_device::mmx_group_0f72() // Opcode 0f 72 -{ - uint8_t modm = FETCH(); - uint8_t imm8 = FETCH(); - MMXPROLOG(); - if( modm >= 0xc0 ) { - switch ( (modm & 0x38) >> 3 ) - { - case 2: // psrld - MMX(modm & 7).d[0]=MMX(modm & 7).d[0] >> imm8; - MMX(modm & 7).d[1]=MMX(modm & 7).d[1] >> imm8; - break; - case 4: // psrad - MMX(modm & 7).i[0]=MMX(modm & 7).i[0] >> imm8; - MMX(modm & 7).i[1]=MMX(modm & 7).i[1] >> imm8; - break; - case 6: // pslld - MMX(modm & 7).d[0]=MMX(modm & 7).d[0] << imm8; - MMX(modm & 7).d[1]=MMX(modm & 7).d[1] << imm8; - break; - default: - report_invalid_modrm("mmx_group0f72", modm); - } - } -} - -void i386_device::sse_group_660f72() // Opcode 66 0f 72 -{ - uint8_t modm = FETCH(); - uint8_t imm8 = FETCH(); - if (modm >= 0xc0) { - switch ((modm & 0x38) >> 3) - { - case 2: // psrld - for (int n = 0; n < 4;n++) - XMM(modm & 7).d[n] = XMM(modm & 7).d[n] >> imm8; - break; - case 4: // psrad - for (int n = 0; n < 4;n++) - XMM(modm & 7).i[n] = XMM(modm & 7).i[n] >> imm8; - break; - case 6: // pslld - for (int n = 0; n < 4;n++) - XMM(modm & 7).d[n] = XMM(modm & 7).d[n] << imm8; - break; - default: - report_invalid_modrm("mmx_group660f72", modm); - } - } -} - -void i386_device::mmx_group_0f73() // Opcode 0f 73 -{ - uint8_t modm = FETCH(); - uint8_t imm8 = FETCH(); - MMXPROLOG(); - if( modm >= 0xc0 ) { - switch ( (modm & 0x38) >> 3 ) - { - case 2: // psrlq - MMX(modm & 7).q = imm8 > 63 ? 0 : MMX(modm & 7).q >> imm8; - break; - case 6: // psllq - MMX(modm & 7).q = imm8 > 63 ? 0 : MMX(modm & 7).q << imm8; - break; - default: - report_invalid_modrm("mmx_group0f73", modm); - } - } -} - -void i386_device::sse_group_660f73() // Opcode 66 0f 73 -{ - uint64_t t0; - uint8_t modm = FETCH(); - uint8_t imm8 = FETCH(); - if (modm >= 0xc0) { - switch ((modm & 0x38) >> 3) - { - case 2: // psrlq - XMM(modm & 7).q[0] = imm8 > 63 ? 0 : XMM(modm & 7).q[0] >> imm8; - XMM(modm & 7).q[1] = imm8 > 63 ? 0 : XMM(modm & 7).q[1] >> imm8; - break; - case 3: // psrldq - if (imm8 >= 16) - { - XMM(modm & 7).q[0] = 0; - XMM(modm & 7).q[1] = 0; - } - else if (imm8 >= 8) - { - imm8 = (imm8 & 7) << 3; - XMM(modm & 7).q[0] = XMM(modm & 7).q[1] >> imm8; - XMM(modm & 7).q[1] = 0; - } - else if (imm8) - { - t0 = XMM(modm & 7).q[0]; - imm8 = imm8 << 3; - XMM(modm & 7).q[0] = (XMM(modm & 7).q[1] << (64 - imm8)) | (t0 >> imm8); - XMM(modm & 7).q[1] = t0 >> imm8; - } - break; - case 6: // psllq - XMM(modm & 7).q[0] = imm8 > 63 ? 0 : XMM(modm & 7).q[0] << imm8; - XMM(modm & 7).q[1] = imm8 > 63 ? 0 : XMM(modm & 7).q[1] << imm8; - break; - case 7: // pslldq - if (imm8 >= 16) - { - XMM(modm & 7).q[0] = 0; - XMM(modm & 7).q[1] = 0; - } - else if (imm8 >= 8) - { - imm8 = (imm8 & 7) << 3; - XMM(modm & 7).q[1] = XMM(modm & 7).q[0] << imm8; - XMM(modm & 7).q[0] = 0; - } - else if (imm8) - { - imm8 = imm8 << 3; - XMM(modm & 7).q[1] = (XMM(modm & 7).q[0] >> (64 - imm8)) | (XMM(modm & 7).q[1] << imm8); - XMM(modm & 7).q[0] = XMM(modm & 7).q[0] << imm8; - } - break; - default: - report_invalid_modrm("sse_group660f73", modm); - } - } -} - -void i386_device::mmx_psrlw_r64_rm64() // Opcode 0f d1 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count; - MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count; - MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count; - MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - int count=(int)src.q; - MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] >> count; - MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] >> count; - MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] >> count; - MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psrld_r64_rm64() // Opcode 0f d2 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count; - MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - int count=(int)src.q; - MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] >> count; - MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psrlq_r64_rm64() // Opcode 0f d3 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - int count=(int)src.q; - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddq_r64_rm64() // Opcode 0f d4 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+MMX(modrm & 7).q; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q+src.q; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pmullw_r64_rm64() // Opcode 0f d5 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).w[0]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[0]*(int32_t)MMX(modrm & 7).s[0]) & 0xffff; - MMX((modrm >> 3) & 0x7).w[1]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[1]*(int32_t)MMX(modrm & 7).s[1]) & 0xffff; - MMX((modrm >> 3) & 0x7).w[2]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[2]*(int32_t)MMX(modrm & 7).s[2]) & 0xffff; - MMX((modrm >> 3) & 0x7).w[3]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[3]*(int32_t)MMX(modrm & 7).s[3]) & 0xffff; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - MMX((modrm >> 3) & 0x7).w[0]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[0]*(int32_t)src.s[0]) & 0xffff; - MMX((modrm >> 3) & 0x7).w[1]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[1]*(int32_t)src.s[1]) & 0xffff; - MMX((modrm >> 3) & 0x7).w[2]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[2]*(int32_t)src.s[2]) & 0xffff; - MMX((modrm >> 3) & 0x7).w[3]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[3]*(int32_t)src.s[3]) & 0xffff; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psubusb_r64_rm64() // Opcode 0f d8 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 7).b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-MMX(modrm & 7).b[n]; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] < src.b[n] ? 0 : MMX((modrm >> 3) & 0x7).b[n]-src.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psubusw_r64_rm64() // Opcode 0f d9 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < MMX(modrm & 7).w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-MMX(modrm & 7).w[n]; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] < src.w[n] ? 0 : MMX((modrm >> 3) & 0x7).w[n]-src.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pand_r64_rm64() // Opcode 0f db -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & MMX(modrm & 7).q; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q & src.q; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddusb_r64_rm64() // Opcode 0f dc -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-MMX(modrm & 7).b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+MMX(modrm & 7).b[n]; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] > (0xff-src.b[n]) ? 0xff : MMX((modrm >> 3) & 0x7).b[n]+src.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddusw_r64_rm64() // Opcode 0f dd -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-MMX(modrm & 7).w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+MMX(modrm & 7).w[n]; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] > (0xffff-src.w[n]) ? 0xffff : MMX((modrm >> 3) & 0x7).w[n]+src.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pandn_r64_rm64() // Opcode 0f df -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & MMX(modrm & 7).q; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - MMX((modrm >> 3) & 0x7).q=(~MMX((modrm >> 3) & 0x7).q) & src.q; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psraw_r64_rm64() // Opcode 0f e1 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count; - MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count; - MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count; - MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - int count=(int)src.q; - MMX((modrm >> 3) & 0x7).s[0]=MMX((modrm >> 3) & 0x7).s[0] >> count; - MMX((modrm >> 3) & 0x7).s[1]=MMX((modrm >> 3) & 0x7).s[1] >> count; - MMX((modrm >> 3) & 0x7).s[2]=MMX((modrm >> 3) & 0x7).s[2] >> count; - MMX((modrm >> 3) & 0x7).s[3]=MMX((modrm >> 3) & 0x7).s[3] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psrad_r64_rm64() // Opcode 0f e2 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count; - MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - int count=(int)src.q; - MMX((modrm >> 3) & 0x7).i[0]=MMX((modrm >> 3) & 0x7).i[0] >> count; - MMX((modrm >> 3) & 0x7).i[1]=MMX((modrm >> 3) & 0x7).i[1] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pmulhw_r64_rm64() // Opcode 0f e5 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).w[0]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[0]*(int32_t)MMX(modrm & 7).s[0]) >> 16; - MMX((modrm >> 3) & 0x7).w[1]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[1]*(int32_t)MMX(modrm & 7).s[1]) >> 16; - MMX((modrm >> 3) & 0x7).w[2]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[2]*(int32_t)MMX(modrm & 7).s[2]) >> 16; - MMX((modrm >> 3) & 0x7).w[3]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[3]*(int32_t)MMX(modrm & 7).s[3]) >> 16; - } else { - MMX_REG src; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, src); - MMX((modrm >> 3) & 0x7).w[0]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[0]*(int32_t)src.s[0]) >> 16; - MMX((modrm >> 3) & 0x7).w[1]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[1]*(int32_t)src.s[1]) >> 16; - MMX((modrm >> 3) & 0x7).w[2]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[2]*(int32_t)src.s[2]) >> 16; - MMX((modrm >> 3) & 0x7).w[3]=(uint32_t)((int32_t)MMX((modrm >> 3) & 0x7).s[3]*(int32_t)src.s[3]) >> 16; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psubsb_r64_rm64() // Opcode 0f e8 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)MMX((modrm >> 3) & 0x7).c[n] - (int16_t)MMX(modrm & 7).c[n]); - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)MMX((modrm >> 3) & 0x7).c[n] - (int16_t)s.c[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psubsw_r64_rm64() // Opcode 0f e9 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)MMX((modrm >> 3) & 0x7).s[n] - (int32_t)MMX(modrm & 7).s[n]); - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)MMX((modrm >> 3) & 0x7).s[n] - (int32_t)s.s[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_por_r64_rm64() // Opcode 0f eb -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | MMX(modrm & 7).q; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q | s.q; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddsb_r64_rm64() // Opcode 0f ec -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)MMX((modrm >> 3) & 0x7).c[n] + (int16_t)MMX(modrm & 7).c[n]); - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)MMX((modrm >> 3) & 0x7).c[n] + (int16_t)s.c[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddsw_r64_rm64() // Opcode 0f ed -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)MMX((modrm >> 3) & 0x7).s[n] + (int32_t)MMX(modrm & 7).s[n]); - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)MMX((modrm >> 3) & 0x7).s[n] + (int32_t)s.s[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pxor_r64_rm64() // Opcode 0f ef -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ MMX(modrm & 7).q; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q ^ s.q; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psllw_r64_rm64() // Opcode 0f f1 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count; - MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count; - MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count; - MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - int count=(int)s.q; - MMX((modrm >> 3) & 0x7).w[0]=MMX((modrm >> 3) & 0x7).w[0] << count; - MMX((modrm >> 3) & 0x7).w[1]=MMX((modrm >> 3) & 0x7).w[1] << count; - MMX((modrm >> 3) & 0x7).w[2]=MMX((modrm >> 3) & 0x7).w[2] << count; - MMX((modrm >> 3) & 0x7).w[3]=MMX((modrm >> 3) & 0x7).w[3] << count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pslld_r64_rm64() // Opcode 0f f2 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count; - MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - int count=(int)s.q; - MMX((modrm >> 3) & 0x7).d[0]=MMX((modrm >> 3) & 0x7).d[0] << count; - MMX((modrm >> 3) & 0x7).d[1]=MMX((modrm >> 3) & 0x7).d[1] << count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psllq_r64_rm64() // Opcode 0f f3 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)MMX(modrm & 7).q; - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - int count=(int)s.q; - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q << count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pmaddwd_r64_rm64() // Opcode 0f f5 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).i[0]=(int32_t)MMX((modrm >> 3) & 0x7).s[0]*(int32_t)MMX(modrm & 7).s[0]+ - (int32_t)MMX((modrm >> 3) & 0x7).s[1]*(int32_t)MMX(modrm & 7).s[1]; - MMX((modrm >> 3) & 0x7).i[1]=(int32_t)MMX((modrm >> 3) & 0x7).s[2]*(int32_t)MMX(modrm & 7).s[2]+ - (int32_t)MMX((modrm >> 3) & 0x7).s[3]*(int32_t)MMX(modrm & 7).s[3]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX((modrm >> 3) & 0x7).i[0]=(int32_t)MMX((modrm >> 3) & 0x7).s[0]*(int32_t)s.s[0]+ - (int32_t)MMX((modrm >> 3) & 0x7).s[1]*(int32_t)s.s[1]; - MMX((modrm >> 3) & 0x7).i[1]=(int32_t)MMX((modrm >> 3) & 0x7).s[2]*(int32_t)s.s[2]+ - (int32_t)MMX((modrm >> 3) & 0x7).s[3]*(int32_t)s.s[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psubb_r64_rm64() // Opcode 0f f8 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - MMX(modrm & 7).b[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] - s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psubw_r64_rm64() // Opcode 0f f9 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - MMX(modrm & 7).w[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] - s.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_psubd_r64_rm64() // Opcode 0f fa -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 2;n++) - MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - MMX(modrm & 7).d[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 2;n++) - MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] - s.d[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddb_r64_rm64() // Opcode 0f fc -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + MMX(modrm & 7).b[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n]=MMX((modrm >> 3) & 0x7).b[n] + s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddw_r64_rm64() // Opcode 0f fd -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + MMX(modrm & 7).w[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n]=MMX((modrm >> 3) & 0x7).w[n] + s.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_paddd_r64_rm64() // Opcode 0f fe -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 2;n++) - MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + MMX(modrm & 7).d[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 2;n++) - MMX((modrm >> 3) & 0x7).d[n]=MMX((modrm >> 3) & 0x7).d[n] + s.d[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_emms() // Opcode 0f 77 -{ - m_x87_tw = 0xffff; // tag word = 0xffff - // TODO - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::i386_cyrix_svdc() // Opcode 0f 78 -{ - uint8_t modrm = FETCH(); - - if( modrm < 0xc0 ) { - uint32_t ea = GetEA(modrm,0); - int index = (modrm >> 3) & 7; - int limit; - switch (index) - { - case 0: - { - index = ES; - break; - } - - case 2: - { - index = SS; - break; - } - - case 3: - { - index = DS; - break; - } - - case 4: - { - index = FS; - break; - } - - case 5: - { - index = GS; - break; - } - - default: - { - i386_trap(6, 0, 0); - } - } - - limit = m_sreg[index].limit; - - if (m_sreg[index].flags & 0x8000) //G bit - { - limit >>= 12; - } - - WRITE16(ea + 0, limit); - WRITE32(ea + 2, m_sreg[index].base); - WRITE16(ea + 5, m_sreg[index].flags); //replace top 8 bits of base - WRITE8(ea + 7, m_sreg[index].base >> 24); - WRITE16(ea + 8, m_sreg[index].selector); - } else { - i386_trap(6, 0, 0); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::i386_cyrix_rsdc() // Opcode 0f 79 -{ - uint8_t modrm = FETCH(); - - if( modrm < 0xc0 ) { - uint32_t ea = GetEA(modrm,0); - int index = (modrm >> 3) & 7; - uint16_t flags; - uint32_t base; - uint32_t limit; - switch (index) - { - case 0: - { - index = ES; - break; - } - - case 2: - { - index = SS; - break; - } - - case 3: - { - index = DS; - break; - } - - case 4: - { - index = FS; - break; - } - - case 5: - { - index = GS; - break; - } - - default: - { - i386_trap(6, 0, 0); - } - } - - base = (READ32(ea + 2) & 0x00ffffff) | (READ8(ea + 7) << 24); - flags = READ16(ea + 5); - limit = READ16(ea + 0) | ((flags & 3) << 16); - - if (flags & 0x8000) //G bit - { - limit = (limit << 12) | 0xfff; - } - - m_sreg[index].selector = READ16(ea + 8); - m_sreg[index].flags = flags; - m_sreg[index].base = base; - m_sreg[index].limit = limit; - } else { - i386_trap(6, 0, 0); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::i386_cyrix_svldt() // Opcode 0f 7a -{ - if ( PROTECTED_MODE && !V8086_MODE ) - { - uint8_t modrm = FETCH(); - - if( !(modrm & 0xf8) ) { - uint32_t ea = GetEA(modrm,0); - uint32_t limit = m_ldtr.limit; - - if (m_ldtr.flags & 0x8000) //G bit - { - limit >>= 12; - } - - WRITE16(ea + 0, limit); - WRITE32(ea + 2, m_ldtr.base); - WRITE16(ea + 5, m_ldtr.flags); //replace top 8 bits of base - WRITE8(ea + 7, m_ldtr.base >> 24); - WRITE16(ea + 8, m_ldtr.segment); - } else { - i386_trap(6, 0, 0); - } - } else { - i386_trap(6, 0, 0); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::i386_cyrix_rsldt() // Opcode 0f 7b -{ - if ( PROTECTED_MODE && !V8086_MODE ) - { - if(m_CPL) - FAULT(FAULT_GP,0) - - uint8_t modrm = FETCH(); - - if( !(modrm & 0xf8) ) { - uint32_t ea = GetEA(modrm,0); - uint16_t flags = READ16(ea + 5); - uint32_t base = (READ32(ea + 2) | 0x00ffffff) | (READ8(ea + 7) << 24); - uint32_t limit = READ16(ea + 0) | ((flags & 3) << 16); - I386_SREG seg; - - if (flags & 0x8000) //G bit - { - limit = (limit << 12) | 0xfff; - } - - memset(&seg, 0, sizeof(seg)); - seg.selector = READ16(ea + 8); - i386_load_protected_mode_segment(&seg,nullptr); - m_ldtr.limit = limit; - m_ldtr.base = base; - m_ldtr.flags = flags; - } else { - i386_trap(6, 0, 0); - } - } else { - i386_trap(6, 0, 0); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::i386_cyrix_svts() // Opcode 0f 7c -{ - if ( PROTECTED_MODE ) - { - uint8_t modrm = FETCH(); - - if( !(modrm & 0xf8) ) { - uint32_t ea = GetEA(modrm,0); - uint32_t limit = m_task.limit; - - if (m_task.flags & 0x8000) //G bit - { - limit >>= 12; - } - - WRITE16(ea + 0, limit); - WRITE32(ea + 2, m_task.base); - WRITE16(ea + 5, m_task.flags); //replace top 8 bits of base - WRITE8(ea + 7, m_task.base >> 24); - WRITE16(ea + 8, m_task.segment); - } else { - i386_trap(6, 0, 0); - } - } else { - i386_trap(6, 0, 0); - } -} - -void i386_device::i386_cyrix_rsts() // Opcode 0f 7d -{ - if ( PROTECTED_MODE ) - { - if(m_CPL) - FAULT(FAULT_GP,0) - - uint8_t modrm = FETCH(); - - if( !(modrm & 0xf8) ) { - uint32_t ea = GetEA(modrm,0); - uint16_t flags = READ16(ea + 5); - uint32_t base = (READ32(ea + 2) | 0x00ffffff) | (READ8(ea + 7) << 24); - uint32_t limit = READ16(ea + 0) | ((flags & 3) << 16); - - if (flags & 0x8000) //G bit - { - limit = (limit << 12) | 0xfff; - } - m_task.segment = READ16(ea + 8); - m_task.limit = limit; - m_task.base = base; - m_task.flags = flags; - } else { - i386_trap(6, 0, 0); - } - } else { - i386_trap(6, 0, 0); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_movd_r64_rm32() // Opcode 0f 6e -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).d[0]=LOAD_RM32(modrm); - } else { - uint32_t ea = GetEA(modrm, 0); - MMX((modrm >> 3) & 0x7).d[0]=READ32(ea); - } - MMX((modrm >> 3) & 0x7).d[1]=0; - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_movq_r64_rm64() // Opcode 0f 6f -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).l=MMX(modrm & 0x7).l; - } else { - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, MMX((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_movd_rm32_r64() // Opcode 0f 7e -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - STORE_RM32(modrm, MMX((modrm >> 3) & 0x7).d[0]); - } else { - uint32_t ea = GetEA(modrm, 0); - WRITE32(ea, MMX((modrm >> 3) & 0x7).d[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_movq_rm64_r64() // Opcode 0f 7f -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX(modrm & 0x7)=MMX((modrm >> 3) & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEMMX(ea, MMX((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pcmpeqb_r64_rm64() // Opcode 0f 74 -{ - int c; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (c=0;c <= 7;c++) - MMX(d).b[c]=(MMX(d).b[c] == MMX(s).b[c]) ? 0xff : 0; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (c=0;c <= 7;c++) - MMX(d).b[c]=(MMX(d).b[c] == s.b[c]) ? 0xff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pcmpeqw_r64_rm64() // Opcode 0f 75 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - MMX(d).w[0]=(MMX(d).w[0] == MMX(s).w[0]) ? 0xffff : 0; - MMX(d).w[1]=(MMX(d).w[1] == MMX(s).w[1]) ? 0xffff : 0; - MMX(d).w[2]=(MMX(d).w[2] == MMX(s).w[2]) ? 0xffff : 0; - MMX(d).w[3]=(MMX(d).w[3] == MMX(s).w[3]) ? 0xffff : 0; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX(d).w[0]=(MMX(d).w[0] == s.w[0]) ? 0xffff : 0; - MMX(d).w[1]=(MMX(d).w[1] == s.w[1]) ? 0xffff : 0; - MMX(d).w[2]=(MMX(d).w[2] == s.w[2]) ? 0xffff : 0; - MMX(d).w[3]=(MMX(d).w[3] == s.w[3]) ? 0xffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pcmpeqd_r64_rm64() // Opcode 0f 76 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - MMX(d).d[0]=(MMX(d).d[0] == MMX(s).d[0]) ? 0xffffffff : 0; - MMX(d).d[1]=(MMX(d).d[1] == MMX(s).d[1]) ? 0xffffffff : 0; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX(d).d[0]=(MMX(d).d[0] == s.d[0]) ? 0xffffffff : 0; - MMX(d).d[1]=(MMX(d).d[1] == s.d[1]) ? 0xffffffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pshufw_r64_rm64_i8() // Opcode 0f 70 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX_REG t; - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q=MMX(s).q; - MMX(d).w[0]=t.w[imm8 & 3]; - MMX(d).w[1]=t.w[(imm8 >> 2) & 3]; - MMX(d).w[2]=t.w[(imm8 >> 4) & 3]; - MMX(d).w[3]=t.w[(imm8 >> 6) & 3]; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - READMMX(ea, s); - MMX(d).w[0]=s.w[imm8 & 3]; - MMX(d).w[1]=s.w[(imm8 >> 2) & 3]; - MMX(d).w[2]=s.w[(imm8 >> 4) & 3]; - MMX(d).w[3]=s.w[(imm8 >> 6) & 3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_punpcklbw_r128_rm128() // Opcode 66 0f 60 -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM_REG xd,xs; - int s, d; - s = modrm & 0x7; - d = (modrm >> 3) & 0x7; - xd.l[0] = XMM(d).l[0]; - xs.l[0] = XMM(s).l[0]; - XMM(d).b[0] = xd.b[0]; - XMM(d).b[1] = xs.b[0]; - XMM(d).b[2] = xd.b[1]; - XMM(d).b[3] = xs.b[1]; - XMM(d).b[4] = xd.b[2]; - XMM(d).b[5] = xs.b[2]; - XMM(d).b[6] = xd.b[3]; - XMM(d).b[7] = xs.b[3]; - XMM(d).b[8] = xd.b[4]; - XMM(d).b[9] = xs.b[4]; - XMM(d).b[10] = xd.b[5]; - XMM(d).b[11] = xs.b[5]; - XMM(d).b[12] = xd.b[6]; - XMM(d).b[13] = xs.b[6]; - XMM(d).b[14] = xd.b[7]; - XMM(d).b[15] = xs.b[7]; - } - else { - XMM_REG xd, xs; - int d = (modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - xd.l[0] = XMM(d).l[0]; - xs.q[0] = READ64(ea); - for (int n = 0; n < 8; n++) { - XMM(d).b[n << 1] = xd.b[n]; - XMM(d).b[(n << 1) | 1] = xs.b[n]; - } - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_punpcklwd_r128_rm128() -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM_REG xd, xs; - int s, d; - s = modrm & 0x7; - d = (modrm >> 3) & 0x7; - xd.l[0] = XMM(d).l[0]; - xs.l[0] = XMM(s).l[0]; - for (int n = 0; n < 4; n++) { - XMM(d).w[n << 1] = xd.w[n]; - XMM(d).w[(n << 1) | 1] = xs.w[n]; - } - } - else { - XMM_REG xd, xs; - int d = (modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - xd.l[0] = XMM(d).l[0]; - xs.q[0] = READ64(ea); - for (int n = 0; n < 4; n++) { - XMM(d).w[n << 1] = xd.w[n]; - XMM(d).w[(n << 1) | 1] = xs.w[n]; - } - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_punpckldq_r128_rm128() -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM_REG xd, xs; - int s, d; - s = modrm & 0x7; - d = (modrm >> 3) & 0x7; - xd.l[0] = XMM(d).l[0]; - xs.l[0] = XMM(s).l[0]; - for (int n = 0; n < 2; n++) { - XMM(d).d[n << 1] = xd.d[n]; - XMM(d).d[(n << 1) | 1] = xs.d[n]; - } - } - else { - XMM_REG xd, xs; - int d = (modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - xd.l[0] = XMM(d).l[0]; - xs.q[0] = READ64(ea); - for (int n = 0; n < 2; n++) { - XMM(d).d[n << 1] = xd.d[n]; - XMM(d).d[(n << 1) | 1] = xs.d[n]; - } - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_punpcklqdq_r128_rm128() -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM_REG xd, xs; - int s, d; - s = modrm & 0x7; - d = (modrm >> 3) & 0x7; - xd.l[0] = XMM(d).l[0]; - xs.l[0] = XMM(s).l[0]; - XMM(d).q[0] = xd.q[0]; - XMM(d).q[1] = xs.q[0]; - } - else { - XMM_REG xd, xs; - int d = (modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - xd.l[0] = XMM(d).l[0]; - xs.q[0] = READ64(ea); - XMM(d).q[0] = xd.q[0]; - XMM(d).q[1] = xs.q[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_punpcklbw_r64_r64m32() // Opcode 0f 60 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t t; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t=MMX(d).d[0]; - MMX(d).b[0]=t & 0xff; - MMX(d).b[1]=MMX(s).b[0]; - MMX(d).b[2]=(t >> 8) & 0xff; - MMX(d).b[3]=MMX(s).b[1]; - MMX(d).b[4]=(t >> 16) & 0xff; - MMX(d).b[5]=MMX(s).b[2]; - MMX(d).b[6]=(t >> 24) & 0xff; - MMX(d).b[7]=MMX(s).b[3]; - } else { - uint32_t s,t; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - s = READ32(ea); - t=MMX(d).d[0]; - MMX(d).b[0]=t & 0xff; - MMX(d).b[1]=s & 0xff; - MMX(d).b[2]=(t >> 8) & 0xff; - MMX(d).b[3]=(s >> 8) & 0xff; - MMX(d).b[4]=(t >> 16) & 0xff; - MMX(d).b[5]=(s >> 16) & 0xff; - MMX(d).b[6]=(t >> 24) & 0xff; - MMX(d).b[7]=(s >> 24) & 0xff; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_punpcklwd_r64_r64m32() // Opcode 0f 61 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint16_t t; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t=MMX(d).w[1]; - MMX(d).w[0]=MMX(d).w[0]; - MMX(d).w[1]=MMX(s).w[0]; - MMX(d).w[2]=t; - MMX(d).w[3]=MMX(s).w[1]; - } else { - uint32_t s; - uint16_t t; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - s = READ32(ea); - t=MMX(d).w[1]; - MMX(d).w[0]=MMX(d).w[0]; - MMX(d).w[1]=s & 0xffff; - MMX(d).w[2]=t; - MMX(d).w[3]=(s >> 16) & 0xffff; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_punpckldq_r64_r64m32() // Opcode 0f 62 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - MMX(d).d[0]=MMX(d).d[0]; - MMX(d).d[1]=MMX(s).d[0]; - } else { - uint32_t s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - s = READ32(ea); - MMX(d).d[0]=MMX(d).d[0]; - MMX(d).d[1]=s; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_packsswb_r64_rm64() // Opcode 0f 63 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]); - MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]); - MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]); - MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]); - MMX(d).c[4]=SaturatedSignedWordToSignedByte(MMX(s).s[0]); - MMX(d).c[5]=SaturatedSignedWordToSignedByte(MMX(s).s[1]); - MMX(d).c[6]=SaturatedSignedWordToSignedByte(MMX(s).s[2]); - MMX(d).c[7]=SaturatedSignedWordToSignedByte(MMX(s).s[3]); - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX(d).c[0]=SaturatedSignedWordToSignedByte(MMX(d).s[0]); - MMX(d).c[1]=SaturatedSignedWordToSignedByte(MMX(d).s[1]); - MMX(d).c[2]=SaturatedSignedWordToSignedByte(MMX(d).s[2]); - MMX(d).c[3]=SaturatedSignedWordToSignedByte(MMX(d).s[3]); - MMX(d).c[4]=SaturatedSignedWordToSignedByte(s.s[0]); - MMX(d).c[5]=SaturatedSignedWordToSignedByte(s.s[1]); - MMX(d).c[6]=SaturatedSignedWordToSignedByte(s.s[2]); - MMX(d).c[7]=SaturatedSignedWordToSignedByte(s.s[3]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pcmpgtb_r64_rm64() // Opcode 0f 64 -{ - int c; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (c=0;c <= 7;c++) - MMX(d).b[c]=(MMX(d).c[c] > MMX(s).c[c]) ? 0xff : 0; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (c=0;c <= 7;c++) - MMX(d).b[c]=(MMX(d).c[c] > s.c[c]) ? 0xff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pcmpgtw_r64_rm64() // Opcode 0f 65 -{ - int c; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (c=0;c <= 3;c++) - MMX(d).w[c]=(MMX(d).s[c] > MMX(s).s[c]) ? 0xffff : 0; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (c=0;c <= 3;c++) - MMX(d).w[c]=(MMX(d).s[c] > s.s[c]) ? 0xffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_pcmpgtd_r64_rm64() // Opcode 0f 66 -{ - int c; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (c=0;c <= 1;c++) - MMX(d).d[c]=(MMX(d).i[c] > MMX(s).i[c]) ? 0xffffffff : 0; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (c=0;c <= 1;c++) - MMX(d).d[c]=(MMX(d).i[c] > s.i[c]) ? 0xffffffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_packuswb_r64_rm64() // Opcode 0f 67 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX_REG ds, sd; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - ds.q = MMX(d).q; - sd.q = MMX(s).q; - MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(ds.s[0]); - MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(ds.s[1]); - MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(ds.s[2]); - MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(ds.s[3]); - MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(sd.s[0]); - MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(sd.s[1]); - MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(sd.s[2]); - MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(sd.s[3]); - } else { - MMX_REG s,t; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - t.q = MMX(d).q; - MMX(d).b[0]=SaturatedSignedWordToUnsignedByte(t.s[0]); - MMX(d).b[1]=SaturatedSignedWordToUnsignedByte(t.s[1]); - MMX(d).b[2]=SaturatedSignedWordToUnsignedByte(t.s[2]); - MMX(d).b[3]=SaturatedSignedWordToUnsignedByte(t.s[3]); - MMX(d).b[4]=SaturatedSignedWordToUnsignedByte(s.s[0]); - MMX(d).b[5]=SaturatedSignedWordToUnsignedByte(s.s[1]); - MMX(d).b[6]=SaturatedSignedWordToUnsignedByte(s.s[2]); - MMX(d).b[7]=SaturatedSignedWordToUnsignedByte(s.s[3]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_punpckhbw_r64_rm64() // Opcode 0f 68 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - MMX(d).b[0]=MMX(d).b[4]; - MMX(d).b[1]=MMX(s).b[4]; - MMX(d).b[2]=MMX(d).b[5]; - MMX(d).b[3]=MMX(s).b[5]; - MMX(d).b[4]=MMX(d).b[6]; - MMX(d).b[5]=MMX(s).b[6]; - MMX(d).b[6]=MMX(d).b[7]; - MMX(d).b[7]=MMX(s).b[7]; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX(d).b[0]=MMX(d).b[4]; - MMX(d).b[1]=s.b[4]; - MMX(d).b[2]=MMX(d).b[5]; - MMX(d).b[3]=s.b[5]; - MMX(d).b[4]=MMX(d).b[6]; - MMX(d).b[5]=s.b[6]; - MMX(d).b[6]=MMX(d).b[7]; - MMX(d).b[7]=s.b[7]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_punpckhwd_r64_rm64() // Opcode 0f 69 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - MMX(d).w[0]=MMX(d).w[2]; - MMX(d).w[1]=MMX(s).w[2]; - MMX(d).w[2]=MMX(d).w[3]; - MMX(d).w[3]=MMX(s).w[3]; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX(d).w[0]=MMX(d).w[2]; - MMX(d).w[1]=s.w[2]; - MMX(d).w[2]=MMX(d).w[3]; - MMX(d).w[3]=s.w[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_punpckhdq_r64_rm64() // Opcode 0f 6a -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - MMX(d).d[0]=MMX(d).d[1]; - MMX(d).d[1]=MMX(s).d[1]; - } else { - MMX_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX(d).d[0]=MMX(d).d[1]; - MMX(d).d[1]=s.d[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::mmx_packssdw_r64_rm64() // Opcode 0f 6b -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - int32_t t1, t2, t3, t4; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t1 = MMX(d).i[0]; - t2 = MMX(d).i[1]; - t3 = MMX(s).i[0]; - t4 = MMX(s).i[1]; - MMX(d).s[0] = SaturatedSignedDwordToSignedWord(t1); - MMX(d).s[1] = SaturatedSignedDwordToSignedWord(t2); - MMX(d).s[2] = SaturatedSignedDwordToSignedWord(t3); - MMX(d).s[3] = SaturatedSignedDwordToSignedWord(t4); - } - else { - MMX_REG s; - int32_t t1, t2; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - t1 = MMX(d).i[0]; - t2 = MMX(d).i[1]; - MMX(d).s[0] = SaturatedSignedDwordToSignedWord(t1); - MMX(d).s[1] = SaturatedSignedDwordToSignedWord(t2); - MMX(d).s[2] = SaturatedSignedDwordToSignedWord(s.i[0]); - MMX(d).s[3] = SaturatedSignedDwordToSignedWord(s.i[1]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_group_0fae() // Opcode 0f ae -{ - uint8_t modm = FETCH(); - if( modm == 0xf8 ) { - logerror("Unemulated SFENCE opcode called\n"); - CYCLES(1); // sfence instruction - } else if( modm == 0xf0 ) { - CYCLES(1); // mfence instruction - } else if( modm == 0xe8 ) { - CYCLES(1); // lfence instruction - } else if( modm < 0xc0 ) { - uint32_t ea; - switch ( (modm & 0x38) >> 3 ) - { - case 2: // ldmxcsr m32 - ea = GetEA(modm, 0); - m_mxcsr = READ32(ea); - break; - case 3: // stmxcsr m32 - ea = GetEA(modm, 0); - WRITE32(ea, m_mxcsr); - break; - case 7: // clflush m8 - GetNonTranslatedEA(modm, nullptr); - break; - default: - report_invalid_modrm("sse_group_0fae", modm); - } - } else { - report_invalid_modrm("sse_group_0fae", modm); - } -} - -void i386_device::sse_cvttps2dq_r128_rm128() // Opcode f3 0f 5b -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).i[0]=(int32_t)XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).i[1]=(int32_t)XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).i[2]=(int32_t)XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).i[3]=(int32_t)XMM(modrm & 0x7).f[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).i[0]=(int32_t)src.f[0]; - XMM((modrm >> 3) & 0x7).i[1]=(int32_t)src.f[1]; - XMM((modrm >> 3) & 0x7).i[2]=(int32_t)src.f[2]; - XMM((modrm >> 3) & 0x7).i[3]=(int32_t)src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtss2sd_r128_r128m32() // Opcode f3 0f 5a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM(modrm & 0x7).f[0]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - s.d[0] = READ32(ea); - XMM((modrm >> 3) & 0x7).f64[0] = s.f[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvttss2si_r32_r128m32() // Opcode f3 0f 2c -{ - int32_t src; - uint8_t modrm = FETCH(); // get mordm byte - if( modrm >= 0xc0 ) { // if bits 7-6 are 11 the source is a xmm register (low doubleword) - src = (int32_t)XMM(modrm & 0x7).f[0^NATIVE_ENDIAN_VALUE_LE_BE(0,1)]; - } else { // otherwise is a memory address - XMM_REG t; - uint32_t ea = GetEA(modrm, 0); - t.d[0] = READ32(ea); - src = (int32_t)t.f[0]; - } - STORE_REG32(modrm, (uint32_t)src); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtss2si_r32_r128m32() // Opcode f3 0f 2d -{ - int32_t src; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = (int32_t)XMM(modrm & 0x7).f[0]; - } else { - XMM_REG t; - uint32_t ea = GetEA(modrm, 0); - t.d[0] = READ32(ea); - src = (int32_t)t.f[0]; - } - STORE_REG32(modrm, (uint32_t)src); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtsi2ss_r128_rm32() // Opcode f3 0f 2a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = (int32_t)LOAD_RM32(modrm); - } else { - uint32_t ea = GetEA(modrm, 0); - XMM((modrm >> 3) & 0x7).f[0] = (int32_t)READ32(ea); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtpi2ps_r128_rm64() // Opcode 0f 2a -{ - uint8_t modrm = FETCH(); - MMXPROLOG(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = (float)MMX(modrm & 0x7).i[0]; - XMM((modrm >> 3) & 0x7).f[1] = (float)MMX(modrm & 0x7).i[1]; - } else { - MMX_REG r; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, r); - XMM((modrm >> 3) & 0x7).f[0] = (float)r.i[0]; - XMM((modrm >> 3) & 0x7).f[1] = (float)r.i[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvttps2pi_r64_r128m64() // Opcode 0f 2c -{ - uint8_t modrm = FETCH(); - MMXPROLOG(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0]; - MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1]; - } else { - XMM_REG r; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, r); - XMM((modrm >> 3) & 0x7).i[0] = r.f[0]; - XMM((modrm >> 3) & 0x7).i[1] = r.f[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtps2pi_r64_r128m64() // Opcode 0f 2d -{ - uint8_t modrm = FETCH(); - MMXPROLOG(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0]; - MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1]; - } else { - XMM_REG r; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, r); - XMM((modrm >> 3) & 0x7).i[0] = r.f[0]; - XMM((modrm >> 3) & 0x7).i[1] = r.f[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtps2pd_r128_r128m64() // Opcode 0f 5a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).f[1]; - } else { - MMX_REG r; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, r); - XMM((modrm >> 3) & 0x7).f64[0] = (double)r.f[0]; - XMM((modrm >> 3) & 0x7).f64[1] = (double)r.f[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtdq2ps_r128_rm128() // Opcode 0f 5b -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = (float)XMM(modrm & 0x7).i[0]; - XMM((modrm >> 3) & 0x7).f[1] = (float)XMM(modrm & 0x7).i[1]; - XMM((modrm >> 3) & 0x7).f[2] = (float)XMM(modrm & 0x7).i[2]; - XMM((modrm >> 3) & 0x7).f[3] = (float)XMM(modrm & 0x7).i[3]; - } else { - XMM_REG r; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, r); - XMM((modrm >> 3) & 0x7).f[0] = (float)r.i[0]; - XMM((modrm >> 3) & 0x7).f[1] = (float)r.i[1]; - XMM((modrm >> 3) & 0x7).f[2] = (float)r.i[2]; - XMM((modrm >> 3) & 0x7).f[3] = (float)r.i[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtdq2pd_r128_r128m64() // Opcode f3 0f e6 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = (double)XMM(modrm & 0x7).i[0]; - XMM((modrm >> 3) & 0x7).f64[1] = (double)XMM(modrm & 0x7).i[1]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - XMM((modrm >> 3) & 0x7).f64[0] = (double)s.i[0]; - XMM((modrm >> 3) & 0x7).f64[1] = (double)s.i[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movss_r128_rm128() // Opcode f3 0f 10 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0]; - } else { - uint32_t ea = GetEA(modrm, 0); - XMM((modrm >> 3) & 0x7).d[0] = READ32(ea); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movss_rm128_r128() // Opcode f3 0f 11 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0]; - } else { - uint32_t ea = GetEA(modrm, 0); - WRITE32(ea, XMM((modrm >> 3) & 0x7).d[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movsldup_r128_rm128() // Opcode f3 0f 12 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[0]; - XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[0]; - XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[2]; - XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[2]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).d[0] = src.d[0]; - XMM((modrm >> 3) & 0x7).d[1] = src.d[0]; - XMM((modrm >> 3) & 0x7).d[2] = src.d[2]; - XMM((modrm >> 3) & 0x7).d[3] = src.d[2]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movshdup_r128_rm128() // Opcode f3 0f 16 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).d[0] = XMM(modrm & 0x7).d[1]; - XMM((modrm >> 3) & 0x7).d[1] = XMM(modrm & 0x7).d[1]; - XMM((modrm >> 3) & 0x7).d[2] = XMM(modrm & 0x7).d[3]; - XMM((modrm >> 3) & 0x7).d[3] = XMM(modrm & 0x7).d[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).d[0] = src.d[1]; - XMM((modrm >> 3) & 0x7).d[1] = src.d[1]; - XMM((modrm >> 3) & 0x7).d[2] = src.d[3]; - XMM((modrm >> 3) & 0x7).d[3] = src.d[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movaps_r128_rm128() // Opcode 0f 28 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movaps_rm128_r128() // Opcode 0f 29 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movups_r128_rm128() // Opcode 0f 10 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movupd_r128_rm128() // Opcode 66 0f 10 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movups_rm128_r128() // Opcode 0f 11 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movupd_rm128_r128() // Opcode 66 0f 11 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); // address does not need to be 16-byte aligned - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movlps_r128_m64() // Opcode 0f 12 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // MOVHLPS opcode - XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[1]; - CYCLES(1); // TODO: correct cycle count - } else { - // MOVLPS opcode - uint32_t ea = GetEA(modrm, 0); - READXMM_LO64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movlpd_r128_m64() // Opcode 66 0f 12 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - CYCLES(1); // TODO: correct cycle count - } else { - // MOVLPS opcode - uint32_t ea = GetEA(modrm, 0); - READXMM_LO64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movlps_m64_r128() // Opcode 0f 13 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM_LO64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movlpd_m64_r128() // Opcode 66 0f 13 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM_LO64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movhps_r128_m64() // Opcode 0f 16 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // MOVLHPS opcode - XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[0]; - CYCLES(1); // TODO: correct cycle count - } else { - // MOVHPS opcode - uint32_t ea = GetEA(modrm, 0); - READXMM_HI64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movhpd_r128_m64() // Opcode 66 0f 16 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - // MOVHPS opcode - uint32_t ea = GetEA(modrm, 0); - READXMM_HI64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movhps_m64_r128() // Opcode 0f 17 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM_HI64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movhpd_m64_r128() // Opcode 66 0f 17 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM_HI64(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movntps_m128_r128() // Opcode 0f 2b -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - // TODO: manage the cache if present - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movmskps_r16_r128() // Opcode 0f 50 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int b; - b=(XMM(modrm & 0x7).d[0] >> 31) & 1; - b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2); - b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4); - b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8); - STORE_REG16(modrm, b); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movmskps_r32_r128() // Opcode 0f 50 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int b; - b=(XMM(modrm & 0x7).d[0] >> 31) & 1; - b=b | ((XMM(modrm & 0x7).d[1] >> 30) & 2); - b=b | ((XMM(modrm & 0x7).d[2] >> 29) & 4); - b=b | ((XMM(modrm & 0x7).d[3] >> 28) & 8); - STORE_REG32(modrm, b); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movmskpd_r32_r128() // Opcode 66 0f 50 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int b; - b=(XMM(modrm & 0x7).q[0] >> 63) & 1; - b=b | ((XMM(modrm & 0x7).q[1] >> 62) & 2); - STORE_REG32(modrm, b); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movq2dq_r128_r64() // Opcode f3 0f d6 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = MMX(modrm & 7).q; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movdqu_r128_rm128() // Opcode f3 0f 6f -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[1]; - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movdqu_rm128_r128() // Opcode f3 0f 7f -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0]; - XMM(modrm & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1]; - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movd_m128_rm32() // Opcode 66 0f 6e -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM((modrm >> 3) & 0x7).d[0] = LOAD_RM32(modrm); - } - else { - uint32_t ea = GetEA(modrm, 0); - XMM((modrm >> 3) & 0x7).d[0] = READ32(ea); - } - XMM((modrm >> 3) & 0x7).d[1] = 0; - XMM((modrm >> 3) & 0x7).q[1] = 0; - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movdqa_m128_rm128() // Opcode 66 0f 6f -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM(modrm & 0x7).q[1]; - } - else { - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movq_r128_r128m64() // Opcode f3 0f 7e -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } else { - uint32_t ea = GetEA(modrm, 0); - XMM((modrm >> 3) & 0x7).q[0] = READ64(ea); - XMM((modrm >> 3) & 0x7).q[1] = 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movd_rm32_r128() // Opcode 66 0f 7e -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - STORE_RM32(modrm, XMM((modrm >> 3) & 0x7).d[0]); - } - else { - uint32_t ea = GetEA(modrm, 0); - WRITE32(ea, XMM((modrm >> 3) & 0x7).d[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movdqa_rm128_r128() // Opcode 66 0f 7f -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0]; - XMM(modrm & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1]; - } - else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmovmskb_r16_r64() // Opcode 0f d7 -{ - //MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int b; - b=(MMX(modrm & 0x7).b[0] >> 7) & 1; - b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2); - b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4); - b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8); - b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16); - b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32); - b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64); - b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128); - STORE_REG16(modrm, b); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmovmskb_r32_r64() // Opcode 0f d7 -{ - //MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int b; - b=(MMX(modrm & 0x7).b[0] >> 7) & 1; - b=b | ((MMX(modrm & 0x7).b[1] >> 6) & 2); - b=b | ((MMX(modrm & 0x7).b[2] >> 5) & 4); - b=b | ((MMX(modrm & 0x7).b[3] >> 4) & 8); - b=b | ((MMX(modrm & 0x7).b[4] >> 3) & 16); - b=b | ((MMX(modrm & 0x7).b[5] >> 2) & 32); - b=b | ((MMX(modrm & 0x7).b[6] >> 1) & 64); - b=b | ((MMX(modrm & 0x7).b[7] >> 0) & 128); - STORE_REG32(modrm, b); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmovmskb_r32_r128() // Opcode 66 0f d7 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint32_t b; - b=(XMM(modrm & 0x7).b[0] >> 7) & 1; - b=b | ((XMM(modrm & 0x7).b[1] >> 6) & 2); - b=b | ((XMM(modrm & 0x7).b[2] >> 5) & 4); - b=b | ((XMM(modrm & 0x7).b[3] >> 4) & 8); - b=b | ((XMM(modrm & 0x7).b[4] >> 3) & 16); - b=b | ((XMM(modrm & 0x7).b[5] >> 2) & 32); - b=b | ((XMM(modrm & 0x7).b[6] >> 1) & 64); - b=b | ((XMM(modrm & 0x7).b[7] >> 0) & 128); - b=b | ((XMM(modrm & 0x7).b[8] << 1) & 256); - b=b | ((XMM(modrm & 0x7).b[9] << 2) & 512); - b=b | ((XMM(modrm & 0x7).b[10] << 3) & 1024); - b=b | ((XMM(modrm & 0x7).b[11] << 4) & 2048); - b=b | ((XMM(modrm & 0x7).b[12] << 5) & 4096); - b=b | ((XMM(modrm & 0x7).b[13] << 6) & 8192); - b=b | ((XMM(modrm & 0x7).b[14] << 7) & 16384); - b=b | ((XMM(modrm & 0x7).b[15] << 8) & 32768); - STORE_REG32(modrm, b); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_xorps() // Opcode 0f 57 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ XMM(modrm & 0x7).d[0]; - XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ XMM(modrm & 0x7).d[1]; - XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ XMM(modrm & 0x7).d[2]; - XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ XMM(modrm & 0x7).d[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).d[0] = XMM((modrm >> 3) & 0x7).d[0] ^ src.d[0]; - XMM((modrm >> 3) & 0x7).d[1] = XMM((modrm >> 3) & 0x7).d[1] ^ src.d[1]; - XMM((modrm >> 3) & 0x7).d[2] = XMM((modrm >> 3) & 0x7).d[2] ^ src.d[2]; - XMM((modrm >> 3) & 0x7).d[3] = XMM((modrm >> 3) & 0x7).d[3] ^ src.d[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_xorpd_r128_rm128() // Opcode 66 0f 57 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] ^ XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] ^ XMM(modrm & 0x7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] ^ src.q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] ^ src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_addps() // Opcode 0f 58 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + XMM(modrm & 0x7).f[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] + src.f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] + src.f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] + src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_sqrtps_r128_rm128() // Opcode 0f 51 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]); - XMM((modrm >> 3) & 0x7).f[1] = sqrt(XMM(modrm & 0x7).f[1]); - XMM((modrm >> 3) & 0x7).f[2] = sqrt(XMM(modrm & 0x7).f[2]); - XMM((modrm >> 3) & 0x7).f[3] = sqrt(XMM(modrm & 0x7).f[3]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = sqrt(src.f[0]); - XMM((modrm >> 3) & 0x7).f[1] = sqrt(src.f[1]); - XMM((modrm >> 3) & 0x7).f[2] = sqrt(src.f[2]); - XMM((modrm >> 3) & 0x7).f[3] = sqrt(src.f[3]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_rsqrtps_r128_rm128() // Opcode 0f 52 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]); - XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(XMM(modrm & 0x7).f[1]); - XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(XMM(modrm & 0x7).f[2]); - XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(XMM(modrm & 0x7).f[3]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(src.f[0]); - XMM((modrm >> 3) & 0x7).f[1] = 1.0 / sqrt(src.f[1]); - XMM((modrm >> 3) & 0x7).f[2] = 1.0 / sqrt(src.f[2]); - XMM((modrm >> 3) & 0x7).f[3] = 1.0 / sqrt(src.f[3]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_rcpps_r128_rm128() // Opcode 0f 53 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = 1.0f / XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).f[1] = 1.0f / XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).f[2] = 1.0f / XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).f[3] = 1.0f / XMM(modrm & 0x7).f[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = 1.0f / src.f[0]; - XMM((modrm >> 3) & 0x7).f[1] = 1.0f / src.f[1]; - XMM((modrm >> 3) & 0x7).f[2] = 1.0f / src.f[2]; - XMM((modrm >> 3) & 0x7).f[3] = 1.0f / src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_andps_r128_rm128() // Opcode 0f 54 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 0x7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & src.q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_andpd_r128_rm128() // Opcode 66 0f 54 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 0x7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] & src.q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] & src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_andnps_r128_rm128() // Opcode 0f 55 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 0x7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & src.q[0]; - XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_andnpd_r128_rm128() // Opcode 66 0f 55 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 0x7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0] = ~(XMM((modrm >> 3) & 0x7).q[0]) & src.q[0]; - XMM((modrm >> 3) & 0x7).q[1] = ~(XMM((modrm >> 3) & 0x7).q[1]) & src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_orps_r128_rm128() // Opcode 0f 56 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 0x7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | src.q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_orpd_r128_rm128() // Opcode 66 0f 56 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 0x7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0] | src.q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[1] | src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_mulps() // Opcode 0f 59 ???? -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * XMM(modrm & 0x7).f[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] * src.f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] * src.f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] * src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_subps() // Opcode 0f 5c -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - XMM(modrm & 0x7).f[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] - src.f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] - src.f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] - src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -static inline float sse_min_single(float src1, float src2) -{ - /*if ((src1 == 0) && (src2 == 0)) - return src2; - if (src1 = SNaN) - return src2; - if (src2 = SNaN) - return src2;*/ - if (src1 < src2) - return src1; - return src2; -} - -static inline double sse_min_double(double src1, double src2) -{ - /*if ((src1 == 0) && (src2 == 0)) - return src2; - if (src1 = SNaN) - return src2; - if (src2 = SNaN) - return src2;*/ - if (src1 < src2) - return src1; - return src2; -} - -void i386_device::sse_minps() // Opcode 0f 5d -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]); - XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]); - XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]); - XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = sse_min_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]); - XMM((modrm >> 3) & 0x7).f[1] = sse_min_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]); - XMM((modrm >> 3) & 0x7).f[2] = sse_min_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]); - XMM((modrm >> 3) & 0x7).f[3] = sse_min_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_divps() // Opcode 0f 5e -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / XMM(modrm & 0x7).f[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0]; - XMM((modrm >> 3) & 0x7).f[1] = XMM((modrm >> 3) & 0x7).f[1] / src.f[1]; - XMM((modrm >> 3) & 0x7).f[2] = XMM((modrm >> 3) & 0x7).f[2] / src.f[2]; - XMM((modrm >> 3) & 0x7).f[3] = XMM((modrm >> 3) & 0x7).f[3] / src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -static inline float sse_max_single(float src1, float src2) -{ - /*if ((src1 == 0) && (src2 == 0)) - return src2; - if (src1 = SNaN) - return src2; - if (src2 = SNaN) - return src2;*/ - if (src1 > src2) - return src1; - return src2; -} - -static inline double sse_max_double(double src1, double src2) -{ - /*if ((src1 == 0) && (src2 == 0)) - return src2; - if (src1 = SNaN) - return src2; - if (src2 = SNaN) - return src2;*/ - if (src1 > src2) - return src1; - return src2; -} - -void i386_device::sse_maxps() // Opcode 0f 5f -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]); - XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], XMM(modrm & 0x7).f[1]); - XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], XMM(modrm & 0x7).f[2]); - XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], XMM(modrm & 0x7).f[3]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]); - XMM((modrm >> 3) & 0x7).f[1] = sse_max_single(XMM((modrm >> 3) & 0x7).f[1], src.f[1]); - XMM((modrm >> 3) & 0x7).f[2] = sse_max_single(XMM((modrm >> 3) & 0x7).f[2], src.f[2]); - XMM((modrm >> 3) & 0x7).f[3] = sse_max_single(XMM((modrm >> 3) & 0x7).f[3], src.f[3]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_maxss_r128_r128m32() // Opcode f3 0f 5f -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], XMM(modrm & 0x7).f[0]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - src.d[0]=READ32(ea); - XMM((modrm >> 3) & 0x7).f[0] = sse_max_single(XMM((modrm >> 3) & 0x7).f[0], src.f[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_addss() // Opcode f3 0f 58 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + XMM(modrm & 0x7).f[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] + src.f[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_subss() // Opcode f3 0f 5c -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] - src.f[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_mulss() // Opcode f3 0f 5e -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * XMM(modrm & 0x7).f[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] * src.f[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_divss() // Opcode 0f 59 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / XMM(modrm & 0x7).f[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] / src.f[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_rcpss_r128_r128m32() // Opcode f3 0f 53 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = 1.0f / XMM(modrm & 0x7).f[0]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - s.d[0]=READ32(ea); - XMM((modrm >> 3) & 0x7).f[0] = 1.0f / s.f[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_sqrtss_r128_r128m32() // Opcode f3 0f 51 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = sqrt(XMM(modrm & 0x7).f[0]); - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - s.d[0]=READ32(ea); - XMM((modrm >> 3) & 0x7).f[0] = sqrt(s.f[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_rsqrtss_r128_r128m32() // Opcode f3 0f 52 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(XMM(modrm & 0x7).f[0]); - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - s.d[0]=READ32(ea); - XMM((modrm >> 3) & 0x7).f[0] = 1.0 / sqrt(s.f[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_minss_r128_r128m32() // Opcode f3 0f 5d -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < XMM(modrm & 0x7).f[0] ? XMM((modrm >> 3) & 0x7).f[0] : XMM(modrm & 0x7).f[0]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - s.d[0] = READ32(ea); - XMM((modrm >> 3) & 0x7).f[0] = XMM((modrm >> 3) & 0x7).f[0] < s.f[0] ? XMM((modrm >> 3) & 0x7).f[0] : s.f[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_comiss_r128_r128m32() // Opcode 0f 2f -{ - float32 a,b; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - a = XMM((modrm >> 3) & 0x7).d[0]; - b = XMM(modrm & 0x7).d[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - a = XMM((modrm >> 3) & 0x7).d[0]; - b = src.d[0]; - } - m_OF=0; - m_SF=0; - m_AF=0; - if (float32_is_nan(a) || float32_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - if (float32_eq(a, b)) - m_ZF = 1; - if (float32_lt(a, b)) - m_CF = 1; - } - // should generate exception when at least one of the operands is either QNaN or SNaN - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_comisd_r128_r128m64() // Opcode 66 0f 2f -{ - float64 a,b; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - a = XMM((modrm >> 3) & 0x7).q[0]; - b = XMM(modrm & 0x7).q[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - a = XMM((modrm >> 3) & 0x7).q[0]; - b = src.q[0]; - } - m_OF=0; - m_SF=0; - m_AF=0; - if (float64_is_nan(a) || float64_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - if (float64_eq(a, b)) - m_ZF = 1; - if (float64_lt(a, b)) - m_CF = 1; - } - // should generate exception when at least one of the operands is either QNaN or SNaN - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_ucomiss_r128_r128m32() // Opcode 0f 2e -{ - float32 a,b; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - a = XMM((modrm >> 3) & 0x7).d[0]; - b = XMM(modrm & 0x7).d[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - a = XMM((modrm >> 3) & 0x7).d[0]; - b = src.d[0]; - } - m_OF=0; - m_SF=0; - m_AF=0; - if (float32_is_nan(a) || float32_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - if (float32_eq(a, b)) - m_ZF = 1; - if (float32_lt(a, b)) - m_CF = 1; - } - // should generate exception when at least one of the operands is SNaN - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_ucomisd_r128_r128m64() // Opcode 66 0f 2e -{ - float64 a,b; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - a = XMM((modrm >> 3) & 0x7).q[0]; - b = XMM(modrm & 0x7).q[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - a = XMM((modrm >> 3) & 0x7).q[0]; - b = src.q[0]; - } - m_OF=0; - m_SF=0; - m_AF=0; - if (float64_is_nan(a) || float64_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - if (float64_eq(a, b)) - m_ZF = 1; - if (float64_lt(a, b)) - m_CF = 1; - } - // should generate exception when at least one of the operands is SNaN - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_shufps() // Opcode 0f c6 -{ - uint8_t modrm = FETCH(); - uint8_t sel = FETCH(); - int m1,m2,m3,m4; - int s,d; - m1=sel & 3; - m2=(sel >> 2) & 3; - m3=(sel >> 4) & 3; - m4=(sel >> 6) & 3; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - if( modrm >= 0xc0 ) { - uint32_t t1,t2,t3,t4; - t1=XMM(d).d[m1]; - t2=XMM(d).d[m2]; - t3=XMM(s).d[m3]; - t4=XMM(s).d[m4]; - XMM(d).d[0]=t1; - XMM(d).d[1]=t2; - XMM(d).d[2]=t3; - XMM(d).d[3]=t4; - } else { - uint32_t t1,t2; - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - t1=XMM(d).d[m1]; - t2=XMM(d).d[m2]; - XMM(d).d[0]=t1; - XMM(d).d[1]=t2; - XMM(d).d[2]=src.d[m3]; - XMM(d).d[3]=src.d[m4]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_shufpd_r128_rm128_i8() // Opcode 66 0f c6 -{ - uint8_t modrm = FETCH(); - uint8_t sel = FETCH(); - int m1,m2; - int s,d; - m1=sel & 1; - m2=(sel >> 1) & 1; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - if( modrm >= 0xc0 ) { - uint64_t t1,t2; - t1=XMM(d).q[m1]; - t2=XMM(s).q[m2]; - XMM(d).q[0]=t1; - XMM(d).q[1]=t2; - } else { - uint64_t t1; - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - t1=XMM(d).q[m1]; - XMM(d).q[0]=t1; - XMM(d).q[1]=src.q[m2]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_unpcklps_r128_rm128() // Opcode 0f 14 -{ - uint8_t modrm = FETCH(); - int s,d; - uint32_t t1, t2, t3, t4; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - if( modrm >= 0xc0 ) { - t1 = XMM(s).d[1]; - t2 = XMM(d).d[1]; - t3 = XMM(s).d[0]; - t4 = XMM(d).d[0]; - XMM(d).d[3]=t1; - XMM(d).d[2]=t2; - XMM(d).d[1]=t3; - XMM(d).d[0]=t4; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - t2 = XMM(d).d[1]; - XMM(d).d[3]=src.d[1]; - XMM(d).d[2]=t2; - XMM(d).d[1]=src.d[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_unpcklpd_r128_rm128() // Opcode 66 0f 14 -{ - uint8_t modrm = FETCH(); - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - if( modrm >= 0xc0 ) { - XMM(d).q[1]=XMM(s).q[0]; - XMM(d).q[0]=XMM(d).q[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM(d).q[1]=src.q[0]; - XMM(d).q[0]=XMM(d).q[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_unpckhps_r128_rm128() // Opcode 0f 15 -{ - uint8_t modrm = FETCH(); - int s,d; - uint32_t t1, t2, t3, t4; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - if( modrm >= 0xc0 ) { - t1 = XMM(d).d[2]; - t2 = XMM(s).d[2]; - t3 = XMM(d).d[3]; - t4 = XMM(s).d[3]; - XMM(d).d[0]=t1; - XMM(d).d[1]=t2; - XMM(d).d[2]=t3; - XMM(d).d[3]=t4; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - t1 = XMM(d).d[2]; - t2 = XMM(d).d[3]; - XMM(d).d[0]=t1; - XMM(d).d[1]=src.d[2]; - XMM(d).d[2]=t2; - XMM(d).d[3]=src.d[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_unpckhpd_r128_rm128() // Opcode 66 0f 15 -{ - uint8_t modrm = FETCH(); - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - if( modrm >= 0xc0 ) { - XMM(d).q[0]=XMM(d).q[1]; - XMM(d).q[1]=XMM(s).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM(d).q[0]=XMM(d).q[1]; - XMM(d).q[1]=src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -static inline bool sse_issingleordered(float op1, float op2) -{ - // TODO: true when at least one of the two source operands being compared is a NaN - return (op1 != op1) || (op1 != op2); -} - -static inline bool sse_issingleunordered(float op1, float op2) -{ - // TODO: true when neither source operand is a NaN - return !((op1 != op1) || (op1 != op2)); -} - -static inline bool sse_isdoubleordered(double op1, double op2) -{ - // TODO: true when at least one of the two source operands being compared is a NaN - return (op1 != op1) || (op1 != op2); -} - -static inline bool sse_isdoubleunordered(double op1, double op2) -{ - // TODO: true when neither source operand is a NaN - return !((op1 != op1) || (op1 != op2)); -} - -void i386_device::sse_predicate_compare_single(uint8_t imm8, XMM_REG d, XMM_REG s) -{ - switch (imm8 & 7) - { - case 0: - d.d[0]=d.f[0] == s.f[0] ? 0xffffffff : 0; - d.d[1]=d.f[1] == s.f[1] ? 0xffffffff : 0; - d.d[2]=d.f[2] == s.f[2] ? 0xffffffff : 0; - d.d[3]=d.f[3] == s.f[3] ? 0xffffffff : 0; - break; - case 1: - d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0; - d.d[1]=d.f[1] < s.f[1] ? 0xffffffff : 0; - d.d[2]=d.f[2] < s.f[2] ? 0xffffffff : 0; - d.d[3]=d.f[3] < s.f[3] ? 0xffffffff : 0; - break; - case 2: - d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0; - d.d[1]=d.f[1] <= s.f[1] ? 0xffffffff : 0; - d.d[2]=d.f[2] <= s.f[2] ? 0xffffffff : 0; - d.d[3]=d.f[3] <= s.f[3] ? 0xffffffff : 0; - break; - case 3: - d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0; - d.d[1]=sse_issingleunordered(d.f[1], s.f[1]) ? 0xffffffff : 0; - d.d[2]=sse_issingleunordered(d.f[2], s.f[2]) ? 0xffffffff : 0; - d.d[3]=sse_issingleunordered(d.f[3], s.f[3]) ? 0xffffffff : 0; - break; - case 4: - d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0; - d.d[1]=d.f[1] != s.f[1] ? 0xffffffff : 0; - d.d[2]=d.f[2] != s.f[2] ? 0xffffffff : 0; - d.d[3]=d.f[3] != s.f[3] ? 0xffffffff : 0; - break; - case 5: - d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff; - d.d[1]=d.f[1] < s.f[1] ? 0 : 0xffffffff; - d.d[2]=d.f[2] < s.f[2] ? 0 : 0xffffffff; - d.d[3]=d.f[3] < s.f[3] ? 0 : 0xffffffff; - break; - case 6: - d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff; - d.d[1]=d.f[1] <= s.f[1] ? 0 : 0xffffffff; - d.d[2]=d.f[2] <= s.f[2] ? 0 : 0xffffffff; - d.d[3]=d.f[3] <= s.f[3] ? 0 : 0xffffffff; - break; - case 7: - d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0; - d.d[1]=sse_issingleordered(d.f[1], s.f[1]) ? 0xffffffff : 0; - d.d[2]=sse_issingleordered(d.f[2], s.f[2]) ? 0xffffffff : 0; - d.d[3]=sse_issingleordered(d.f[3], s.f[3]) ? 0xffffffff : 0; - break; - } -} - -void i386_device::sse_predicate_compare_double(uint8_t imm8, XMM_REG d, XMM_REG s) -{ - switch (imm8 & 7) - { - case 0: - d.q[0]=d.f64[0] == s.f64[0] ? 0xffffffffffffffffU : 0; - d.q[1]=d.f64[1] == s.f64[1] ? 0xffffffffffffffffU : 0; - break; - case 1: - d.q[0]=d.f64[0] < s.f64[0] ? 0xffffffffffffffffU : 0; - d.q[1]=d.f64[1] < s.f64[1] ? 0xffffffffffffffffU : 0; - break; - case 2: - d.q[0]=d.f64[0] <= s.f64[0] ? 0xffffffffffffffffU : 0; - d.q[1]=d.f64[1] <= s.f64[1] ? 0xffffffffffffffffU : 0; - break; - case 3: - d.q[0]=sse_isdoubleunordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffffU : 0; - d.q[1]=sse_isdoubleunordered(d.f64[1], s.f64[1]) ? 0xffffffffffffffffU : 0; - break; - case 4: - d.q[0]=d.f64[0] != s.f64[0] ? 0xffffffffffffffffU : 0; - d.q[1]=d.f64[1] != s.f64[1] ? 0xffffffffffffffffU : 0; - break; - case 5: - d.q[0]=d.f64[0] < s.f64[0] ? 0 : 0xffffffffffffffffU; - d.q[1]=d.f64[1] < s.f64[1] ? 0 : 0xffffffffffffffffU; - break; - case 6: - d.q[0]=d.f64[0] <= s.f64[0] ? 0 : 0xffffffffffffffffU; - d.q[1]=d.f64[1] <= s.f64[1] ? 0 : 0xffffffffffffffffU; - break; - case 7: - d.q[0]=sse_isdoubleordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffffU : 0; - d.q[1]=sse_isdoubleordered(d.f64[1], s.f64[1]) ? 0xffffffffffffffffU : 0; - break; - } -} - -void i386_device::sse_predicate_compare_single_scalar(uint8_t imm8, XMM_REG d, XMM_REG s) -{ - switch (imm8 & 7) - { - case 0: - d.d[0]=d.f[0] == s.f[0] ? 0xffffffff : 0; - break; - case 1: - d.d[0]=d.f[0] < s.f[0] ? 0xffffffff : 0; - break; - case 2: - d.d[0]=d.f[0] <= s.f[0] ? 0xffffffff : 0; - break; - case 3: - d.d[0]=sse_issingleunordered(d.f[0], s.f[0]) ? 0xffffffff : 0; - break; - case 4: - d.d[0]=d.f[0] != s.f[0] ? 0xffffffff : 0; - break; - case 5: - d.d[0]=d.f[0] < s.f[0] ? 0 : 0xffffffff; - break; - case 6: - d.d[0]=d.f[0] <= s.f[0] ? 0 : 0xffffffff; - break; - case 7: - d.d[0]=sse_issingleordered(d.f[0], s.f[0]) ? 0xffffffff : 0; - break; - } -} - -void i386_device::sse_predicate_compare_double_scalar(uint8_t imm8, XMM_REG d, XMM_REG s) -{ - switch (imm8 & 7) - { - case 0: - d.q[0]=d.f64[0] == s.f64[0] ? 0xffffffffffffffffU : 0; - break; - case 1: - d.q[0]=d.f64[0] < s.f64[0] ? 0xffffffffffffffffU : 0; - break; - case 2: - d.q[0]=d.f64[0] <= s.f64[0] ? 0xffffffffffffffffU : 0; - break; - case 3: - d.q[0]=sse_isdoubleunordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffffU : 0; - break; - case 4: - d.q[0]=d.f64[0] != s.f64[0] ? 0xffffffffffffffffU : 0; - break; - case 5: - d.q[0]=d.f64[0] < s.f64[0] ? 0 : 0xffffffffffffffffU; - break; - case 6: - d.q[0]=d.f64[0] <= s.f64[0] ? 0 : 0xffffffffffffffffU; - break; - case 7: - d.q[0]=sse_isdoubleordered(d.f64[0], s.f64[0]) ? 0xffffffffffffffffU : 0; - break; - } -} - -void i386_device::sse_cmpps_r128_rm128_i8() // Opcode 0f c2 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - sse_predicate_compare_single(imm8, XMM(d), XMM(s)); - } else { - int d; - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - READXMM(ea, s); - d=(modrm >> 3) & 0x7; - sse_predicate_compare_single(imm8, XMM(d), s); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cmppd_r128_rm128_i8() // Opcode 66 0f c2 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - sse_predicate_compare_double(imm8, XMM(d), XMM(s)); - } else { - int d; - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - READXMM(ea, s); - d=(modrm >> 3) & 0x7; - sse_predicate_compare_double(imm8, XMM(d), s); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cmpss_r128_r128m32_i8() // Opcode f3 0f c2 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - sse_predicate_compare_single_scalar(imm8, XMM(d), XMM(s)); - } else { - int d; - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - s.d[0]=READ32(ea); - d=(modrm >> 3) & 0x7; - sse_predicate_compare_single_scalar(imm8, XMM(d), s); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pinsrw_r64_r16m16_i8() // Opcode 0f c4, 16bit register -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t imm8 = FETCH(); - uint16_t v = LOAD_RM16(modrm); - if (m_xmm_operand_size) - XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; - else - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; - } else { - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - uint16_t v = READ16(ea); - if (m_xmm_operand_size) - XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; - else - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pinsrw_r64_r32m16_i8() // Opcode 0f c4, 32bit register -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t imm8 = FETCH(); - uint16_t v = (uint16_t)LOAD_RM32(modrm); - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; - } else { - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - uint16_t v = READ16(ea); - MMX((modrm >> 3) & 0x7).w[imm8 & 3] = v; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pinsrw_r128_r32m16_i8() // Opcode 66 0f c4 -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - uint8_t imm8 = FETCH(); - uint16_t v = (uint16_t)LOAD_RM32(modrm); - XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; - } - else { - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - uint16_t v = READ16(ea); - XMM((modrm >> 3) & 0x7).w[imm8 & 7] = v; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pextrw_r16_r64_i8() // Opcode 0f c5 -{ - //MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t imm8 = FETCH(); - if (m_xmm_operand_size) - STORE_REG16(modrm, XMM(modrm & 0x7).w[imm8 & 7]); - else - STORE_REG16(modrm, MMX(modrm & 0x7).w[imm8 & 3]); - } else { - //uint8_t imm8 = FETCH(); - report_invalid_modrm("pextrw_r16_r64_i8", modrm); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pextrw_r32_r64_i8() // Opcode 0f c5 -{ - //MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - uint8_t imm8 = FETCH(); - STORE_REG32(modrm, MMX(modrm & 0x7).w[imm8 & 3]); - } else { - //uint8_t imm8 = FETCH(); - report_invalid_modrm("pextrw_r32_r64_i8", modrm); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pextrw_reg_r128_i8() // Opcode 66 0f c5 -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - uint8_t imm8 = FETCH(); - STORE_REG32(modrm, XMM(modrm & 0x7).w[imm8 & 7]); - } - else { - //uint8_t imm8 = FETCH(); - report_invalid_modrm("sse_pextrw_reg_r128_i8", modrm); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pminub_r64_rm64() // Opcode 0f da -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] < s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pminub_r128_rm128() // Opcode 66 0f da -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] < XMM(modrm & 0x7).b[n] ? XMM((modrm >> 3) & 0x7).b[n] : XMM(modrm & 0x7).b[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] < s.b[n] ? XMM((modrm >> 3) & 0x7).b[n] : s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmaxub_r64_rm64() // Opcode 0f de -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > MMX(modrm & 0x7).b[n] ? MMX((modrm >> 3) & 0x7).b[n] : MMX(modrm & 0x7).b[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n] = MMX((modrm >> 3) & 0x7).b[n] > s.b[n] ? MMX((modrm >> 3) & 0x7).b[n] : s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pavgb_r64_rm64() // Opcode 0f e0 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n] = ((uint16_t)MMX((modrm >> 3) & 0x7).b[n] + (uint16_t)MMX(modrm & 0x7).b[n] + 1) >> 1; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 8;n++) - MMX((modrm >> 3) & 0x7).b[n] = ((uint16_t)MMX((modrm >> 3) & 0x7).b[n] + (uint16_t)s.b[n] + 1) >> 1; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pavgw_r64_rm64() // Opcode 0f e3 -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n] = ((uint32_t)MMX((modrm >> 3) & 0x7).w[n] + (uint32_t)MMX(modrm & 0x7).w[n] + 1) >> 1; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).w[n] = ((uint32_t)MMX((modrm >> 3) & 0x7).w[n] + (uint32_t)s.w[n] + 1) >> 1; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmulhuw_r64_rm64() // Opcode 0f e4 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).w[0]=((uint32_t)MMX((modrm >> 3) & 0x7).w[0]*(uint32_t)MMX(modrm & 7).w[0]) >> 16; - MMX((modrm >> 3) & 0x7).w[1]=((uint32_t)MMX((modrm >> 3) & 0x7).w[1]*(uint32_t)MMX(modrm & 7).w[1]) >> 16; - MMX((modrm >> 3) & 0x7).w[2]=((uint32_t)MMX((modrm >> 3) & 0x7).w[2]*(uint32_t)MMX(modrm & 7).w[2]) >> 16; - MMX((modrm >> 3) & 0x7).w[3]=((uint32_t)MMX((modrm >> 3) & 0x7).w[3]*(uint32_t)MMX(modrm & 7).w[3]) >> 16; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX((modrm >> 3) & 0x7).w[0]=((uint32_t)MMX((modrm >> 3) & 0x7).w[0]*(uint32_t)s.w[0]) >> 16; - MMX((modrm >> 3) & 0x7).w[1]=((uint32_t)MMX((modrm >> 3) & 0x7).w[1]*(uint32_t)s.w[1]) >> 16; - MMX((modrm >> 3) & 0x7).w[2]=((uint32_t)MMX((modrm >> 3) & 0x7).w[2]*(uint32_t)s.w[2]) >> 16; - MMX((modrm >> 3) & 0x7).w[3]=((uint32_t)MMX((modrm >> 3) & 0x7).w[3]*(uint32_t)s.w[3]) >> 16; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pminsw_r64_rm64() // Opcode 0f ea -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] < s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmaxsw_r64_rm64() // Opcode 0f ee -{ - int n; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > MMX(modrm & 0x7).s[n] ? MMX((modrm >> 3) & 0x7).s[n] : MMX(modrm & 0x7).s[n]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - for (n=0;n < 4;n++) - MMX((modrm >> 3) & 0x7).s[n] = MMX((modrm >> 3) & 0x7).s[n] > s.s[n] ? MMX((modrm >> 3) & 0x7).s[n] : s.s[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmuludq_r64_rm64() // Opcode 0f f4 -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q = (uint64_t)MMX((modrm >> 3) & 0x7).d[0] * (uint64_t)MMX(modrm & 0x7).d[0]; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX((modrm >> 3) & 0x7).q = (uint64_t)MMX((modrm >> 3) & 0x7).d[0] * (uint64_t)s.d[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmuludq_r128_rm128() // Opcode 66 0f f4 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = (uint64_t)XMM((modrm >> 3) & 0x7).d[0] * (uint64_t)XMM(modrm & 0x7).d[0]; - XMM((modrm >> 3) & 0x7).q[1] = (uint64_t)XMM((modrm >> 3) & 0x7).d[2] * (uint64_t)XMM(modrm & 0x7).d[2]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - XMM((modrm >> 3) & 0x7).q[0] = (uint64_t)XMM((modrm >> 3) & 0x7).d[0] * (uint64_t)s.d[0]; - XMM((modrm >> 3) & 0x7).q[1] = (uint64_t)XMM((modrm >> 3) & 0x7).d[2] * (uint64_t)s.d[2]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psadbw_r64_rm64() // Opcode 0f f6 -{ - int n; - int32_t temp; - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - temp=0; - for (n=0;n < 8;n++) - temp += abs((int32_t)MMX((modrm >> 3) & 0x7).b[n] - (int32_t)MMX(modrm & 0x7).b[n]); - MMX((modrm >> 3) & 0x7).l=(uint64_t)temp & 0xffff; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - temp=0; - for (n=0;n < 8;n++) - temp += abs((int32_t)MMX((modrm >> 3) & 0x7).b[n] - (int32_t)s.b[n]); - MMX((modrm >> 3) & 0x7).l=(uint64_t)temp & 0xffff; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubq_r64_rm64() // Opcode 0f fb -{ - MMXPROLOG(); - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - MMX(modrm & 7).q; - } else { - MMX_REG s; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, s); - MMX((modrm >> 3) & 0x7).q=MMX((modrm >> 3) & 0x7).q - s.q; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubq_r128_rm128() // Opcode 66 0f fb -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] - XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] - XMM(modrm & 7).q[1]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] - s.q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] - s.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pshufd_r128_rm128_i8() // Opcode 66 0f 70 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[0]=XMM(s).q[0]; - t.q[1]=XMM(s).q[1]; - XMM(d).d[0]=t.d[imm8 & 3]; - XMM(d).d[1]=t.d[(imm8 >> 2) & 3]; - XMM(d).d[2]=t.d[(imm8 >> 4) & 3]; - XMM(d).d[3]=t.d[(imm8 >> 6) & 3]; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - READXMM(ea, s); - XMM(d).d[0]=s.d[(imm8 & 3)]; - XMM(d).d[1]=s.d[((imm8 >> 2) & 3)]; - XMM(d).d[2]=s.d[((imm8 >> 4) & 3)]; - XMM(d).d[3]=s.d[((imm8 >> 6) & 3)]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pshuflw_r128_rm128_i8() // Opcode f2 0f 70 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[0]=XMM(s).q[0]; - XMM(d).q[1]=XMM(s).q[1]; - XMM(d).w[0]=t.w[imm8 & 3]; - XMM(d).w[1]=t.w[(imm8 >> 2) & 3]; - XMM(d).w[2]=t.w[(imm8 >> 4) & 3]; - XMM(d).w[3]=t.w[(imm8 >> 6) & 3]; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - READXMM(ea, s); - XMM(d).q[1]=s.q[1]; - XMM(d).w[0]=s.w[imm8 & 3]; - XMM(d).w[1]=s.w[(imm8 >> 2) & 3]; - XMM(d).w[2]=s.w[(imm8 >> 4) & 3]; - XMM(d).w[3]=s.w[(imm8 >> 6) & 3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pshufhw_r128_rm128_i8() // Opcode f3 0f 70 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[0]=XMM(s).q[1]; - XMM(d).q[0]=XMM(s).q[0]; - XMM(d).w[4]=t.w[imm8 & 3]; - XMM(d).w[5]=t.w[(imm8 >> 2) & 3]; - XMM(d).w[6]=t.w[(imm8 >> 4) & 3]; - XMM(d).w[7]=t.w[(imm8 >> 6) & 3]; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - READXMM(ea, s); - XMM(d).q[0]=s.q[0]; - XMM(d).w[4]=s.w[4 + (imm8 & 3)]; - XMM(d).w[5]=s.w[4 + ((imm8 >> 2) & 3)]; - XMM(d).w[6]=s.w[4 + ((imm8 >> 4) & 3)]; - XMM(d).w[7]=s.w[4 + ((imm8 >> 6) & 3)]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_packsswb_r128_rm128() // Opcode 66 0f 63 -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM_REG t; - int s, d; - s = modrm & 0x7; - d = (modrm >> 3) & 0x7; - t.q[0] = XMM(s).q[0]; - t.q[1] = XMM(s).q[1]; - for (int n = 0; n < 8; n++) - XMM(d).c[n] = SaturatedSignedWordToSignedByte(XMM(d).s[n]); - for (int n = 0; n < 8; n++) - XMM(d).c[n+8] = SaturatedSignedWordToSignedByte(t.s[n]); - } - else { - XMM_REG s; - int d = (modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n = 0; n < 8; n++) - XMM(d).c[n] = SaturatedSignedWordToSignedByte(XMM(d).s[n]); - for (int n = 0; n < 8; n++) - XMM(d).c[n + 8] = SaturatedSignedWordToSignedByte(s.s[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_packssdw_r128_rm128() // Opcode 66 0f 6b -{ - uint8_t modrm = FETCH(); - if (modrm >= 0xc0) { - XMM_REG t; - int s, d; - s = modrm & 0x7; - d = (modrm >> 3) & 0x7; - t.q[0] = XMM(s).q[0]; - t.q[1] = XMM(s).q[1]; - XMM(d).s[0] = SaturatedSignedDwordToSignedWord(XMM(d).i[0]); - XMM(d).s[1] = SaturatedSignedDwordToSignedWord(XMM(d).i[1]); - XMM(d).s[2] = SaturatedSignedDwordToSignedWord(XMM(d).i[2]); - XMM(d).s[3] = SaturatedSignedDwordToSignedWord(XMM(d).i[3]); - XMM(d).s[4] = SaturatedSignedDwordToSignedWord(t.i[0]); - XMM(d).s[5] = SaturatedSignedDwordToSignedWord(t.i[1]); - XMM(d).s[6] = SaturatedSignedDwordToSignedWord(t.i[2]); - XMM(d).s[7] = SaturatedSignedDwordToSignedWord(t.i[3]); - } - else { - XMM_REG s; - int d = (modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - XMM(d).s[0] = SaturatedSignedDwordToSignedWord(XMM(d).i[0]); - XMM(d).s[1] = SaturatedSignedDwordToSignedWord(XMM(d).i[1]); - XMM(d).s[2] = SaturatedSignedDwordToSignedWord(XMM(d).i[2]); - XMM(d).s[3] = SaturatedSignedDwordToSignedWord(XMM(d).i[3]); - XMM(d).s[4] = SaturatedSignedDwordToSignedWord(s.i[0]); - XMM(d).s[5] = SaturatedSignedDwordToSignedWord(s.i[1]); - XMM(d).s[6] = SaturatedSignedDwordToSignedWord(s.i[2]); - XMM(d).s[7] = SaturatedSignedDwordToSignedWord(s.i[3]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pcmpgtb_r128_rm128() // Opcode 66 0f 64 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (int c=0;c <= 15;c++) - XMM(d).b[c]=(XMM(d).c[c] > XMM(s).c[c]) ? 0xff : 0; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int c=0;c <= 15;c++) - XMM(d).b[c]=(XMM(d).c[c] > s.c[c]) ? 0xff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pcmpgtw_r128_rm128() // Opcode 66 0f 65 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (int c=0;c <= 7;c++) - XMM(d).w[c]=(XMM(d).s[c] > XMM(s).s[c]) ? 0xffff : 0; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int c=0;c <= 7;c++) - XMM(d).w[c]=(XMM(d).s[c] > s.s[c]) ? 0xffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pcmpgtd_r128_rm128() // Opcode 66 0f 66 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (int c=0;c <= 3;c++) - XMM(d).d[c]=(XMM(d).i[c] > XMM(s).i[c]) ? 0xffffffff : 0; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int c=0;c <= 3;c++) - XMM(d).d[c]=(XMM(d).i[c] > s.i[c]) ? 0xffffffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_packuswb_r128_rm128() // Opcode 66 0f 67 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[0] = XMM(s).q[0]; - t.q[1] = XMM(s).q[1]; - for (int n = 0; n < 8;n++) - XMM(d).b[n]=SaturatedSignedWordToUnsignedByte(XMM(d).s[n]); - for (int n = 0; n < 8;n++) - XMM(d).b[n+8]=SaturatedSignedWordToUnsignedByte(t.s[n]); - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n = 0; n < 8;n++) - XMM(d).b[n]=SaturatedSignedWordToUnsignedByte(XMM(d).s[n]); - for (int n = 0; n < 8;n++) - XMM(d).b[n+8]=SaturatedSignedWordToUnsignedByte(s.s[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_punpckhbw_r128_rm128() // Opcode 66 0f 68 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[1] = XMM(s).q[1]; - for (int n = 0; n < 16; n += 2) { - XMM(d).b[n]=XMM(d).b[8+(n >> 1)]; - XMM(d).b[n+1]=t.b[8+(n >> 1)]; - } - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n = 0; n < 16; n += 2) { - XMM(d).b[n]=XMM(d).b[8+(n >> 1)]; - XMM(d).b[n+1]=s.b[8+(n >> 1)]; - } - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_punpckhwd_r128_rm128() // Opcode 66 0f 69 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[1] = XMM(s).q[1]; - for (int n = 0; n < 8; n += 2) { - XMM(d).w[n]=XMM(d).w[4+(n >> 1)]; - XMM(d).w[n+1]=t.w[4+(n >> 1)]; - } - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n = 0; n < 8; n += 2) { - XMM(d).w[n]=XMM(d).w[4+(n >> 1)]; - XMM(d).w[n+1]=s.w[4+(n >> 1)]; - } - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_unpckhdq_r128_rm128() // Opcode 66 0f 6a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[1] = XMM(s).q[1]; - XMM(d).d[0]=XMM(d).d[2]; - XMM(d).d[1]=t.d[2]; - XMM(d).d[2]=XMM(d).d[3]; - XMM(d).d[3]=t.d[3]; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - XMM(d).d[0]=XMM(d).d[2]; - XMM(d).d[1]=s.d[2]; - XMM(d).d[2]=XMM(d).d[3]; - XMM(d).d[3]=s.d[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_punpckhqdq_r128_rm128() // Opcode 66 0f 6d -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM_REG t; - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - t.q[1] = XMM(s).q[1]; - XMM(d).q[0]=XMM(d).q[1]; - XMM(d).q[1]=t.q[1]; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - XMM(d).q[0]=XMM(d).q[1]; - XMM(d).q[1]=s.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pcmpeqb_r128_rm128() // Opcode 66 0f 74 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (int c=0;c <= 15;c++) - XMM(d).b[c]=(XMM(d).c[c] == XMM(s).c[c]) ? 0xff : 0; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int c=0;c <= 15;c++) - XMM(d).b[c]=(XMM(d).c[c] == s.c[c]) ? 0xff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pcmpeqw_r128_rm128() // Opcode 66 0f 75 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (int c=0;c <= 7;c++) - XMM(d).w[c]=(XMM(d).s[c] == XMM(s).s[c]) ? 0xffff : 0; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int c=0;c <= 7;c++) - XMM(d).w[c]=(XMM(d).s[c] == s.s[c]) ? 0xffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pcmpeqd_r128_rm128() // Opcode 66 0f 76 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (int c=0;c <= 3;c++) - XMM(d).d[c]=(XMM(d).i[c] == XMM(s).i[c]) ? 0xffffffff : 0; - } else { - XMM_REG s; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int c=0;c <= 3;c++) - XMM(d).d[c]=(XMM(d).i[c] == s.i[c]) ? 0xffffffff : 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddq_r128_rm128() // Opcode 66 0f d4 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - XMM(d).q[0]=XMM(d).q[0]+XMM(s).q[0]; - XMM(d).q[1]=XMM(d).q[1]+XMM(s).q[1]; - } else { - XMM_REG src; - int d=(modrm >> 3) & 0x7; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM(d).q[0]=XMM(d).q[0]+src.q[0]; - XMM(d).q[1]=XMM(d).q[1]+src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmullw_r128_rm128() // Opcode 66 0f d5 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - for (int n = 0; n < 8;n++) - XMM(d).w[n]=(uint32_t)((int32_t)XMM(d).s[n]*(int32_t)XMM(s).s[n]) & 0xffff; - } else { - XMM_REG src; - int d; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - d=(modrm >> 3) & 0x7; - for (int n = 0; n < 8;n++) - XMM(d).w[n]=(uint32_t)((int32_t)XMM(d).s[n]*(int32_t)src.s[n]) & 0xffff; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddb_r128_rm128() // Opcode 66 0f fc -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] + XMM(modrm & 7).b[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] + s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddw_r128_rm128() // Opcode 66 0f fd -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] + XMM(modrm & 7).w[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] + s.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddd_r128_rm128() // Opcode 66 0f fe -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 4;n++) - XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] + XMM(modrm & 7).d[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 4;n++) - XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] + s.d[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubusb_r128_rm128() // Opcode 66 0f d8 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] < XMM(modrm & 7).b[n] ? 0 : XMM((modrm >> 3) & 0x7).b[n]-XMM(modrm & 7).b[n]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] < src.b[n] ? 0 : XMM((modrm >> 3) & 0x7).b[n]-src.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubusw_r128_rm128() // Opcode 66 0f d9 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] < XMM(modrm & 7).w[n] ? 0 : XMM((modrm >> 3) & 0x7).w[n]-XMM(modrm & 7).w[n]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] < src.w[n] ? 0 : XMM((modrm >> 3) & 0x7).w[n]-src.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pand_r128_rm128() // Opcode 66 0f db -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] & XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] & XMM(modrm & 7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] & src.q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] & src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pandn_r128_rm128() // Opcode 66 0f df -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0]=(~XMM((modrm >> 3) & 0x7).q[0]) & XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).q[1]=(~XMM((modrm >> 3) & 0x7).q[1]) & XMM(modrm & 7).q[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).q[0]=(~XMM((modrm >> 3) & 0x7).q[0]) & src.q[0]; - XMM((modrm >> 3) & 0x7).q[1]=(~XMM((modrm >> 3) & 0x7).q[1]) & src.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddusb_r128_rm128() // Opcode 66 0f dc -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] > (0xff-XMM(modrm & 7).b[n]) ? 0xff : XMM((modrm >> 3) & 0x7).b[n]+XMM(modrm & 7).b[n]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] > (0xff-src.b[n]) ? 0xff : XMM((modrm >> 3) & 0x7).b[n]+src.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddusw_r128_rm128() // Opcode 66 0f dd -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] > (0xffff-XMM(modrm & 7).w[n]) ? 0xffff : XMM((modrm >> 3) & 0x7).w[n]+XMM(modrm & 7).w[n]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] > (0xffff-src.w[n]) ? 0xffff : XMM((modrm >> 3) & 0x7).w[n]+src.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmaxub_r128_rm128() // Opcode 66 0f de -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] > XMM(modrm & 0x7).b[n] ? XMM((modrm >> 3) & 0x7).b[n] : XMM(modrm & 0x7).b[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n] = XMM((modrm >> 3) & 0x7).b[n] > s.b[n] ? XMM((modrm >> 3) & 0x7).b[n] : s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmulhuw_r128_rm128() // Opcode 66 0f e4 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=((uint32_t)XMM((modrm >> 3) & 0x7).w[n]*(uint32_t)XMM(modrm & 7).w[n]) >> 16; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=((uint32_t)XMM((modrm >> 3) & 0x7).w[n]*(uint32_t)s.w[n]) >> 16; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmulhw_r128_rm128() // Opcode 66 0f e5 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=(uint32_t)((int32_t)XMM((modrm >> 3) & 0x7).s[n]*(int32_t)XMM(modrm & 7).s[n]) >> 16; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=(uint32_t)((int32_t)XMM((modrm >> 3) & 0x7).s[n]*(int32_t)src.s[n]) >> 16; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubsb_r128_rm128() // Opcode 66 0f e8 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)XMM((modrm >> 3) & 0x7).c[n] - (int16_t)XMM(modrm & 7).c[n]); - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)XMM((modrm >> 3) & 0x7).c[n] - (int16_t)s.c[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubsw_r128_rm128() // Opcode 66 0f e9 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)XMM((modrm >> 3) & 0x7).s[n] - (int32_t)XMM(modrm & 7).s[n]); - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)XMM((modrm >> 3) & 0x7).s[n] - (int32_t)s.s[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pminsw_r128_rm128() // Opcode 66 0f ea -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] < XMM(modrm & 0x7).s[n] ? XMM((modrm >> 3) & 0x7).s[n] : XMM(modrm & 0x7).s[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] < s.s[n] ? XMM((modrm >> 3) & 0x7).s[n] : s.s[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmaxsw_r128_rm128() // Opcode 66 0f ee -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] > XMM(modrm & 0x7).s[n] ? XMM((modrm >> 3) & 0x7).s[n] : XMM(modrm & 0x7).s[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n] = XMM((modrm >> 3) & 0x7).s[n] > s.s[n] ? XMM((modrm >> 3) & 0x7).s[n] : s.s[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddsb_r128_rm128() // Opcode 66 0f ec -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)XMM((modrm >> 3) & 0x7).c[n] + (int16_t)XMM(modrm & 7).c[n]); - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).c[n]=SaturatedSignedWordToSignedByte((int16_t)XMM((modrm >> 3) & 0x7).c[n] + (int16_t)s.c[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_paddsw_r128_rm128() // Opcode 66 0f ed -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)XMM((modrm >> 3) & 0x7).s[n] + (int32_t)XMM(modrm & 7).s[n]); - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n]=SaturatedSignedDwordToSignedWord((int32_t)XMM((modrm >> 3) & 0x7).s[n] + (int32_t)s.s[n]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_por_r128_rm128() // Opcode 66 0f eb -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] | XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] | XMM(modrm & 7).q[1]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] | s.q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] | s.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pxor_r128_rm128() // Opcode 66 0f ef -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] ^ XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] ^ XMM(modrm & 7).q[1]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] ^ s.q[0]; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] ^ s.q[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pmaddwd_r128_rm128() // Opcode 66 0f f5 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 4;n++) - XMM((modrm >> 3) & 0x7).i[n]=(int32_t)XMM((modrm >> 3) & 0x7).s[n]*(int32_t)XMM(modrm & 7).s[n]+ - (int32_t)XMM((modrm >> 3) & 0x7).s[n]*(int32_t)XMM(modrm & 7).s[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 4;n++) - XMM((modrm >> 3) & 0x7).i[n]=(int32_t)XMM((modrm >> 3) & 0x7).s[n]*(int32_t)s.s[n]+ - (int32_t)XMM((modrm >> 3) & 0x7).s[n]*(int32_t)s.s[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubb_r128_rm128() // Opcode 66 0f f8 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] - XMM(modrm & 7).b[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n]=XMM((modrm >> 3) & 0x7).b[n] - s.b[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubw_r128_rm128() // Opcode 66 0f f9 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] - XMM(modrm & 7).w[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] - s.w[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psubd_r128_rm128() // Opcode 66 0f fa -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 4;n++) - XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] - XMM(modrm & 7).d[n]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 4;n++) - XMM((modrm >> 3) & 0x7).d[n]=XMM((modrm >> 3) & 0x7).d[n] - s.d[n]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psadbw_r128_rm128() // Opcode 66 0f f6 -{ - int32_t temp; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - temp=0; - for (int n=0;n < 8;n++) - temp += abs((int32_t)XMM((modrm >> 3) & 0x7).b[n] - (int32_t)XMM(modrm & 0x7).b[n]); - XMM((modrm >> 3) & 0x7).l[0]=(uint64_t)temp & 0xffff; - temp=0; - for (int n=8;n < 16;n++) - temp += abs((int32_t)XMM((modrm >> 3) & 0x7).b[n] - (int32_t)XMM(modrm & 0x7).b[n]); - XMM((modrm >> 3) & 0x7).l[1]=(uint64_t)temp & 0xffff; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - temp=0; - for (int n=0;n < 8;n++) - temp += abs((int32_t)XMM((modrm >> 3) & 0x7).b[n] - (int32_t)s.b[n]); - XMM((modrm >> 3) & 0x7).l[0]=(uint64_t)temp & 0xffff; - temp=0; - for (int n=8;n < 16;n++) - temp += abs((int32_t)XMM((modrm >> 3) & 0x7).b[n] - (int32_t)s.b[n]); - XMM((modrm >> 3) & 0x7).l[1]=(uint64_t)temp & 0xffff; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pavgb_r128_rm128() // Opcode 66 0f e0 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n] = ((uint16_t)XMM((modrm >> 3) & 0x7).b[n] + (uint16_t)XMM(modrm & 0x7).b[n] + 1) >> 1; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 16;n++) - XMM((modrm >> 3) & 0x7).b[n] = ((uint16_t)XMM((modrm >> 3) & 0x7).b[n] + (uint16_t)s.b[n] + 1) >> 1; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pavgw_r128_rm128() // Opcode 66 0f e3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n] = ((uint32_t)XMM((modrm >> 3) & 0x7).w[n] + (uint32_t)XMM(modrm & 0x7).w[n] + 1) >> 1; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - for (int n=0;n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n] = ((uint32_t)XMM((modrm >> 3) & 0x7).w[n] + (uint32_t)s.w[n] + 1) >> 1; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psrlw_r128_rm128() // Opcode 66 0f d1 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - for (int n=0; n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] >> count; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - int count=(int)src.q[0]; - for (int n=0; n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psrld_r128_rm128() // Opcode 66 0f d2 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] >> count; - XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] >> count; - XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] >> count; - XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] >> count; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - int count=(int)src.q[0]; - XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] >> count; - XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] >> count; - XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] >> count; - XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psrlq_r128_rm128() // Opcode 66 0f d3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] >> count; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] >> count; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - int count=(int)src.q[0]; - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] >> count; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psllw_r128_rm128() // Opcode 66 0f f1 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - for (int n=0; n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] << count; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - int count=(int)s.q[0]; - for (int n=0; n < 8;n++) - XMM((modrm >> 3) & 0x7).w[n]=XMM((modrm >> 3) & 0x7).w[n] << count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_pslld_r128_rm128() // Opcode 66 0f f2 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] << count; - XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] << count; - XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] << count; - XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] << count; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - int count=(int)s.q[0]; - XMM((modrm >> 3) & 0x7).d[0]=XMM((modrm >> 3) & 0x7).d[0] << count; - XMM((modrm >> 3) & 0x7).d[1]=XMM((modrm >> 3) & 0x7).d[1] << count; - XMM((modrm >> 3) & 0x7).d[2]=XMM((modrm >> 3) & 0x7).d[2] << count; - XMM((modrm >> 3) & 0x7).d[3]=XMM((modrm >> 3) & 0x7).d[3] << count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psllq_r128_rm128() // Opcode 66 0f f3 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] << count; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] << count; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, s); - int count=(int)s.q[0]; - XMM((modrm >> 3) & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0] << count; - XMM((modrm >> 3) & 0x7).q[1]=XMM((modrm >> 3) & 0x7).q[1] << count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psraw_r128_rm128() // Opcode 66 0f e1 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - for (int n=0; n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n]=XMM((modrm >> 3) & 0x7).s[n] >> count; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - int count=(int)src.q[0]; - for (int n=0; n < 8;n++) - XMM((modrm >> 3) & 0x7).s[n]=XMM((modrm >> 3) & 0x7).s[n] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_psrad_r128_rm128() // Opcode 66 0f e2 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int count=(int)XMM(modrm & 7).q[0]; - XMM((modrm >> 3) & 0x7).i[0]=XMM((modrm >> 3) & 0x7).i[0] >> count; - XMM((modrm >> 3) & 0x7).i[1]=XMM((modrm >> 3) & 0x7).i[1] >> count; - XMM((modrm >> 3) & 0x7).i[2]=XMM((modrm >> 3) & 0x7).i[2] >> count; - XMM((modrm >> 3) & 0x7).i[3]=XMM((modrm >> 3) & 0x7).i[3] >> count; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - int count=(int)src.q[0]; - XMM((modrm >> 3) & 0x7).i[0]=XMM((modrm >> 3) & 0x7).i[0] >> count; - XMM((modrm >> 3) & 0x7).i[1]=XMM((modrm >> 3) & 0x7).i[1] >> count; - XMM((modrm >> 3) & 0x7).i[2]=XMM((modrm >> 3) & 0x7).i[2] >> count; - XMM((modrm >> 3) & 0x7).i[3]=XMM((modrm >> 3) & 0x7).i[3] >> count; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movntdq_m128_r128() // Opcode 66 0f e7 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - CYCLES(1); // unsupported - } else { - // TODO: manage the cache if present - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_cvttpd2dq_r128_rm128() // Opcode 66 0f e6 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).i[0]=(int32_t)XMM((modrm >> 3) & 0x7).f64[0]; - XMM((modrm >> 3) & 0x7).i[1]=(int32_t)XMM((modrm >> 3) & 0x7).f64[1]; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).i[0]=(int32_t)src.f64[0]; - XMM((modrm >> 3) & 0x7).i[1]=(int32_t)src.f64[1]; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movq_r128m64_r128() // Opcode 66 0f d6 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7).q[0]=XMM((modrm >> 3) & 0x7).q[0]; - XMM(modrm & 0x7).q[1] = 0; - } else { - uint32_t ea = GetEA(modrm, 0); - WRITE64(ea, XMM((modrm >> 3) & 0x7).q[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_addsubpd_r128_rm128() // Opcode 66 0f d0 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s, d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - XMM(d).f64[0]=XMM(d).f64[0]-XMM(s).f64[0]; - XMM(d).f64[1]=XMM(d).f64[1]+XMM(s).f64[1]; - } else { - XMM_REG src; - int d; - uint32_t ea = GetEA(modrm, 0); - d=(modrm >> 3) & 0x7; - READXMM(ea, src); - XMM(d).f64[0]=XMM(d).f64[0]-src.f64[0]; - XMM(d).f64[1]=XMM(d).f64[1]+src.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_haddpd_r128_rm128() // Opcode 66 0f 7c -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s, d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - XMM(d).f64[0]=XMM(d).f64[0]+XMM(d).f64[1]; - XMM(d).f64[1]=XMM(s).f64[0]+XMM(s).f64[1]; - } else { - XMM_REG src; - int d; - uint32_t ea = GetEA(modrm, 0); - d=(modrm >> 3) & 0x7; - READXMM(ea, src); - XMM(d).f64[0]=XMM(d).f64[0]+XMM(d).f64[1]; - XMM(d).f64[1]=src.f64[0]+src.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_hsubpd_r128_rm128() // Opcode 66 0f 7d -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s, d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - XMM(d).f64[0]=XMM(d).f64[0]-XMM(d).f64[1]; - XMM(d).f64[1]=XMM(s).f64[0]-XMM(s).f64[1]; - } else { - XMM_REG src; - int d; - uint32_t ea = GetEA(modrm, 0); - d=(modrm >> 3) & 0x7; - READXMM(ea, src); - XMM(d).f64[0]=XMM(d).f64[0]-XMM(d).f64[1]; - XMM(d).f64[1]=src.f64[0]-src.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_sqrtpd_r128_rm128() // Opcode 66 0f 51 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s, d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - XMM(d).f64[0]=sqrt(XMM(s).f64[0]); - XMM(d).f64[1]=sqrt(XMM(s).f64[1]); - } else { - XMM_REG src; - int d; - uint32_t ea = GetEA(modrm, 0); - d=(modrm >> 3) & 0x7; - READXMM(ea, src); - XMM(d).f64[0]=sqrt(src.f64[0]); - XMM(d).f64[1]=sqrt(src.f64[1]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtpi2pd_r128_rm64() // Opcode 66 0f 2a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - MMXPROLOG(); - XMM((modrm >> 3) & 0x7).f64[0] = (double)MMX(modrm & 0x7).i[0]; - XMM((modrm >> 3) & 0x7).f64[1] = (double)MMX(modrm & 0x7).i[1]; - } else { - MMX_REG r; - uint32_t ea = GetEA(modrm, 0); - READMMX(ea, r); - XMM((modrm >> 3) & 0x7).f64[0] = (double)r.i[0]; - XMM((modrm >> 3) & 0x7).f64[1] = (double)r.i[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvttpd2pi_r64_rm128() // Opcode 66 0f 2c -{ - uint8_t modrm = FETCH(); - MMXPROLOG(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f64[0]; - MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f64[1]; - } else { - XMM_REG r; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, r); - MMX((modrm >> 3) & 0x7).i[0] = r.f64[0]; - MMX((modrm >> 3) & 0x7).i[1] = r.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtpd2pi_r64_rm128() // Opcode 66 0f 2d -{ - uint8_t modrm = FETCH(); - MMXPROLOG(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f64[0]; - MMX((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f64[1]; - } else { - XMM_REG r; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, r); - MMX((modrm >> 3) & 0x7).i[0] = r.f64[0]; - MMX((modrm >> 3) & 0x7).i[1] = r.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtpd2ps_r128_rm128() // Opcode 66 0f 5a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = (float)XMM(modrm & 0x7).f64[0]; - XMM((modrm >> 3) & 0x7).f[1] = (float)XMM(modrm & 0x7).f64[1]; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } else { - XMM_REG r; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, r); - XMM((modrm >> 3) & 0x7).f[0] = (float)r.f64[0]; - XMM((modrm >> 3) & 0x7).f[1] = (float)r.f64[1]; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtps2dq_r128_rm128() // Opcode 66 0f 5b -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).i[0] = XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).i[1] = XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).i[2] = XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).i[3] = XMM(modrm & 0x7).f[3]; - } else { - XMM_REG r; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, r); - XMM((modrm >> 3) & 0x7).i[0] = r.f[0]; - XMM((modrm >> 3) & 0x7).i[1] = r.f[1]; - XMM((modrm >> 3) & 0x7).i[2] = r.f[2]; - XMM((modrm >> 3) & 0x7).i[3] = r.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_addpd_r128_rm128() // Opcode 66 0f 58 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + XMM(modrm & 0x7).f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] + XMM(modrm & 0x7).f64[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + src.f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] + src.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_mulpd_r128_rm128() // Opcode 66 0f 59 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * XMM(modrm & 0x7).f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] * XMM(modrm & 0x7).f64[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * src.f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] * src.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_subpd_r128_rm128() // Opcode 66 0f 5c -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - XMM(modrm & 0x7).f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] - XMM(modrm & 0x7).f64[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - src.f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] - src.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_minpd_r128_rm128() // Opcode 66 0f 5d -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]); - XMM((modrm >> 3) & 0x7).f64[1] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[1], XMM(modrm & 0x7).f64[1]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]); - XMM((modrm >> 3) & 0x7).f64[1] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[1], src.f64[1]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_divpd_r128_rm128() // Opcode 66 0f 5e -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / XMM(modrm & 0x7).f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] / XMM(modrm & 0x7).f64[1]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / src.f64[0]; - XMM((modrm >> 3) & 0x7).f64[1] = XMM((modrm >> 3) & 0x7).f64[1] / src.f64[1]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_maxpd_r128_rm128() // Opcode 66 0f 5f -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]); - XMM((modrm >> 3) & 0x7).f64[1] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[1], XMM(modrm & 0x7).f64[1]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]); - XMM((modrm >> 3) & 0x7).f64[1] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[1], src.f64[1]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movntpd_m128_r128() // Opcode 66 0f 2b -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - // TODO: manage the cache if present - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_movapd_r128_rm128() // Opcode 66 0f 28 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7) = XMM(modrm & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movapd_rm128_r128() // Opcode 66 0f 29 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7) = XMM((modrm >> 3) & 0x7); - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movsd_r128_r128m64() // Opcode f2 0f 10 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0]; - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM_LO64(ea, XMM((modrm >> 3) & 0x7)); - XMM((modrm >> 3) & 0x7).q[1] = 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movsd_r128m64_r128() // Opcode f2 0f 11 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM(modrm & 0x7).q[0] = XMM((modrm >> 3) & 0x7).q[0]; - } else { - uint32_t ea = GetEA(modrm, 0); - WRITEXMM_LO64(ea, XMM((modrm >> 3) & 0x7)); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movddup_r128_r128m64() // Opcode f2 0f 12 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).q[0] = XMM(modrm & 0x7).q[0]; - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[0]; - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM_LO64(ea, XMM((modrm >> 3) & 0x7)); - XMM((modrm >> 3) & 0x7).q[1] = XMM((modrm >> 3) & 0x7).q[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtsi2sd_r128_rm32() // Opcode f2 0f 2a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = (int32_t)LOAD_RM32(modrm); - } else { - uint32_t ea = GetEA(modrm, 0); - XMM((modrm >> 3) & 0x7).f64[0] = (int32_t)READ32(ea); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvttsd2si_r32_r128m64() // Opcode f2 0f 2c -{ - int32_t src; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = (int32_t)XMM(modrm & 0x7).f64[0]; - } else { // otherwise is a memory address - XMM_REG t; - uint32_t ea = GetEA(modrm, 0); - READXMM_LO64(ea, t); - src = (int32_t)t.f64[0]; - } - STORE_REG32(modrm, (uint32_t)src); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtsd2si_r32_r128m64() // Opcode f2 0f 2d -{ - int32_t src; - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - src = (int32_t)XMM(modrm & 0x7).f64[0]; - } else { // otherwise is a memory address - XMM_REG t; - uint32_t ea = GetEA(modrm, 0); - READXMM_LO64(ea, t); - src = (int32_t)t.f64[0]; - } - STORE_REG32(modrm, (uint32_t)src); - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_sqrtsd_r128_r128m64() // Opcode f2 0f 51 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s, d; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - XMM(d).f64[0]=sqrt(XMM(s).f64[0]); - } else { - XMM_REG src; - int d; - uint32_t ea = GetEA(modrm, 0); - d=(modrm >> 3) & 0x7; - READXMM(ea, src); - XMM(d).f64[0]=sqrt(src.f64[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_addsd_r128_r128m64() // Opcode f2 0f 58 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + XMM(modrm & 0x7).f64[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] + src.f64[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_mulsd_r128_r128m64() // Opcode f2 0f 59 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * XMM(modrm & 0x7).f64[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] * src.f64[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cvtsd2ss_r128_r128m64() // Opcode f2 0f 5a -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0] = XMM(modrm & 0x7).f64[0]; - } else { - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - READXMM_LO64(ea, s); - XMM((modrm >> 3) & 0x7).f[0] = s.f64[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_subsd_r128_r128m64() // Opcode f2 0f 5c -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - XMM(modrm & 0x7).f64[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] - src.f64[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_minsd_r128_r128m64() // Opcode f2 0f 5d -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = sse_min_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_divsd_r128_r128m64() // Opcode f2 0f 5e -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / XMM(modrm & 0x7).f64[0]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = XMM((modrm >> 3) & 0x7).f64[0] / src.f64[0]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_maxsd_r128_r128m64() // Opcode f2 0f 5f -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], XMM(modrm & 0x7).f64[0]); - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f64[0] = sse_max_double(XMM((modrm >> 3) & 0x7).f64[0], src.f64[0]); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_haddps_r128_rm128() // Opcode f2 0f 7c -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s, d; - float f1, f2, f3, f4; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - f1=XMM(d).f[0]+XMM(d).f[1]; - f2=XMM(d).f[2]+XMM(d).f[3]; - f3=XMM(s).f[0]+XMM(s).f[1]; - f4=XMM(s).f[2]+XMM(s).f[3]; - XMM(d).f[0]=f1; - XMM(d).f[1]=f2; - XMM(d).f[2]=f3; - XMM(d).f[3]=f4; - } else { - XMM_REG src; - int d; - float f1, f2; - uint32_t ea = GetEA(modrm, 0); - d=(modrm >> 3) & 0x7; - READXMM(ea, src); - f1=XMM(d).f[0]+XMM(d).f[1]; - f2=XMM(d).f[2]+XMM(d).f[3]; - XMM(d).f[0]=f1; - XMM(d).f[1]=f2; - XMM(d).f[2]=src.f[0]+src.f[1]; - XMM(d).f[3]=src.f[2]+src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_hsubps_r128_rm128() // Opcode f2 0f 7d -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s, d; - float f1, f2, f3, f4; - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - f1=XMM(d).f[0]-XMM(d).f[1]; - f2=XMM(d).f[2]-XMM(d).f[3]; - f3=XMM(s).f[0]-XMM(s).f[1]; - f4=XMM(s).f[2]-XMM(s).f[3]; - XMM(d).f[0]=f1; - XMM(d).f[1]=f2; - XMM(d).f[2]=f3; - XMM(d).f[3]=f4; - } else { - XMM_REG src; - int d; - float f1, f2; - uint32_t ea = GetEA(modrm, 0); - d=(modrm >> 3) & 0x7; - READXMM(ea, src); - f1=XMM(d).f[0]-XMM(d).f[1]; - f2=XMM(d).f[2]-XMM(d).f[3]; - XMM(d).f[0]=f1; - XMM(d).f[1]=f2; - XMM(d).f[2]=src.f[0]-src.f[1]; - XMM(d).f[3]=src.f[2]-src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_cmpsd_r128_r128m64_i8() // Opcode f2 0f c2 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - int s,d; - uint8_t imm8 = FETCH(); - s=modrm & 0x7; - d=(modrm >> 3) & 0x7; - sse_predicate_compare_double_scalar(imm8, XMM(d), XMM(s)); - } else { - int d; - XMM_REG s; - uint32_t ea = GetEA(modrm, 0); - uint8_t imm8 = FETCH(); - READXMM_LO64(ea, s); - d=(modrm >> 3) & 0x7; - sse_predicate_compare_double_scalar(imm8, XMM(d), s); - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_addsubps_r128_rm128() // Opcode f2 0f d0 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).f[0]=XMM((modrm >> 3) & 0x7).f[0] - XMM(modrm & 0x7).f[0]; - XMM((modrm >> 3) & 0x7).f[1]=XMM((modrm >> 3) & 0x7).f[1] + XMM(modrm & 0x7).f[1]; - XMM((modrm >> 3) & 0x7).f[2]=XMM((modrm >> 3) & 0x7).f[2] - XMM(modrm & 0x7).f[2]; - XMM((modrm >> 3) & 0x7).f[3]=XMM((modrm >> 3) & 0x7).f[3] + XMM(modrm & 0x7).f[3]; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).f[0]=XMM((modrm >> 3) & 0x7).f[0] - src.f[0]; - XMM((modrm >> 3) & 0x7).f[1]=XMM((modrm >> 3) & 0x7).f[1] + src.f[1]; - XMM((modrm >> 3) & 0x7).f[2]=XMM((modrm >> 3) & 0x7).f[2] - src.f[2]; - XMM((modrm >> 3) & 0x7).f[3]=XMM((modrm >> 3) & 0x7).f[3] + src.f[3]; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_movdq2q_r64_r128() // Opcode f2 0f d6 -{ - uint8_t modrm = FETCH(); - MMXPROLOG(); - if( modrm >= 0xc0 ) { - MMX((modrm >> 3) & 0x7).q = XMM(modrm & 0x7).q[0]; - CYCLES(1); // TODO: correct cycle count - } else { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } -} - -void i386_device::sse_cvtpd2dq_r128_rm128() // Opcode f2 0f e6 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - XMM((modrm >> 3) & 0x7).i[0]=(int32_t)XMM((modrm >> 3) & 0x7).f64[0]; - XMM((modrm >> 3) & 0x7).i[1]=(int32_t)XMM((modrm >> 3) & 0x7).f64[1]; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } else { - XMM_REG src; - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, src); - XMM((modrm >> 3) & 0x7).i[0]=(int32_t)src.f64[0]; - XMM((modrm >> 3) & 0x7).i[1]=(int32_t)src.f64[1]; - XMM((modrm >> 3) & 0x7).q[1] = 0; - } - CYCLES(1); // TODO: correct cycle count -} - -void i386_device::sse_lddqu_r128_m128() // Opcode f2 0f f0 -{ - uint8_t modrm = FETCH(); - if( modrm >= 0xc0 ) { - // unsupported by cpu - CYCLES(1); // TODO: correct cycle count - } else { - uint32_t ea = GetEA(modrm, 0); - READXMM(ea, XMM((modrm >> 3) & 0x7)); - } -} diff --git a/source/src/vm/libcpu_newdev/i386/x87ops.hxx b/source/src/vm/libcpu_newdev/i386/x87ops.hxx deleted file mode 100644 index a50db982b..000000000 --- a/source/src/vm/libcpu_newdev/i386/x87ops.hxx +++ /dev/null @@ -1,4983 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Philip Bennett -/*************************************************************************** - - x87 FPU emulation - - TODO: - - 80-bit precision for F2XM1, FYL2X, FPATAN - - Figure out why SoftFloat trig extensions produce bad values - - Cycle counts for all processors (currently using 486 counts) - - Precision-dependent cycle counts for divide instructions - - Last instruction, operand pointers etc. - - Fix FLDENV, FSTENV, FSAVE, FRSTOR and FPREM - - Status word C2 updates to reflect round up/down - - Handling of invalid and denormal numbers - - Remove redundant operand checks - - Exceptions - - Corrections and Additions [8-December-2017 Andrey Merkulov) - FXAM, FPREM - fixed - FINCSTP, FDECSTP - tags and exceptions corrected - Interrupt handling for 8087 added - FENI, FDISI opcodes added - -***************************************************************************/ - -/************************************* - * - * x87 stack handling - * - *************************************/ - -void i386_device::x87_set_stack_top(int top) -{ - m_x87_sw &= ~(X87_SW_TOP_MASK << X87_SW_TOP_SHIFT); - m_x87_sw |= (top << X87_SW_TOP_SHIFT); -} - -void i386_device::x87_set_tag(int reg, int tag) -{ - int shift = X87_TW_FIELD_SHIFT(reg); - - m_x87_tw &= ~(X87_TW_MASK << shift); - m_x87_tw |= (tag << shift); -} - -void i386_device::x87_write_stack(int i, floatx80 value, bool update_tag) -{ - ST(i) = value; - - if (update_tag) - { - int tag; - - if (floatx80_is_zero(value)) - { - tag = X87_TW_ZERO; - } - else if (floatx80_is_inf(value) || floatx80_is_nan(value)) - { - tag = X87_TW_SPECIAL; - } - else - { - tag = X87_TW_VALID; - } - - x87_set_tag(ST_TO_PHYS(i), tag); - } -} - -void i386_device::x87_set_stack_underflow() -{ - m_x87_sw &= ~X87_SW_C1; - m_x87_sw |= X87_SW_IE | X87_SW_SF; -} - -void i386_device::x87_set_stack_overflow() -{ - m_x87_sw |= X87_SW_C1 | X87_SW_IE | X87_SW_SF; -} - -int i386_device::x87_inc_stack() -{ - int ret = 1; - - // Check for stack underflow - if (X87_IS_ST_EMPTY(0)) - { - ret = 0; - x87_set_stack_underflow(); - - // Don't update the stack if the exception is unmasked - if (~m_x87_cw & X87_CW_IM) - return ret; - } - - x87_set_tag(ST_TO_PHYS(0), X87_TW_EMPTY); - x87_set_stack_top(ST_TO_PHYS(1)); - return ret; -} - -int i386_device::x87_dec_stack() -{ - int ret = 1; - - // Check for stack overflow - if (!X87_IS_ST_EMPTY(7)) - { - ret = 0; - x87_set_stack_overflow(); - - // Don't update the stack if the exception is unmasked - if (~m_x87_cw & X87_CW_IM) - return ret; - } - - x87_set_stack_top(ST_TO_PHYS(7)); - return ret; -} - - -/************************************* - * - * Exception handling - * - *************************************/ - -int i386_device::x87_check_exceptions() -{ - /* Update the exceptions from SoftFloat */ - if (float_exception_flags & float_flag_invalid) - { - m_x87_sw |= X87_SW_IE; - float_exception_flags &= ~float_flag_invalid; - } - if (float_exception_flags & float_flag_overflow) - { - m_x87_sw |= X87_SW_OE; - float_exception_flags &= ~float_flag_overflow; - } - if (float_exception_flags & float_flag_underflow) - { - m_x87_sw |= X87_SW_UE; - float_exception_flags &= ~float_flag_underflow; - } - if (float_exception_flags & float_flag_inexact) - { - m_x87_sw |= X87_SW_PE; - float_exception_flags &= ~float_flag_inexact; - } - - if ((m_x87_sw & ~m_x87_cw) & 0x3f) - { - // m_device->execute().set_input_line(INPUT_LINE_FERR, RAISE_LINE); - logerror("Unmasked x87 exception (CW:%.4x, SW:%.4x)\n", m_x87_cw, m_x87_sw); - // interrupt handler - if (!(m_x87_cw & X87_CW_IEM)) { m_x87_sw |= X87_SW_ES; m_ferr_handler(1); } - - if (m_cr[0] & 0x20) // FIXME: 486 and up only - { - m_ext = 1; - i386_trap(FAULT_MF, 0, 0); - } - return 0; - } - - return 1; -} - -void i386_device::x87_write_cw(uint16_t cw) -{ - m_x87_cw = cw; - - /* Update the SoftFloat rounding mode */ - float_rounding_mode = x87_to_sf_rc[(m_x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK]; -} - -void i386_device::x87_reset() -{ - x87_write_cw(0x0037f); - - m_x87_sw = 0; - m_x87_tw = 0xffff; - - // TODO: FEA=0, FDS=0, FIP=0 FOP=0 FCS=0 - m_x87_data_ptr = 0; - m_x87_inst_ptr = 0; - m_x87_opcode = 0; - - m_ferr_handler(0); -} - -/************************************* - * - * Core arithmetic - * - *************************************/ - -floatx80 i386_device::x87_add(floatx80 a, floatx80 b) -{ - floatx80 result = { 0 }; - - switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK) - { - case X87_CW_PC_SINGLE: - { - float32 a32 = floatx80_to_float32(a); - float32 b32 = floatx80_to_float32(b); - result = float32_to_floatx80(float32_add(a32, b32)); - break; - } - case X87_CW_PC_DOUBLE: - { - float64 a64 = floatx80_to_float64(a); - float64 b64 = floatx80_to_float64(b); - result = float64_to_floatx80(float64_add(a64, b64)); - break; - } - case X87_CW_PC_EXTEND: - { - result = floatx80_add(a, b); - break; - } - } - - return result; -} - -floatx80 i386_device::x87_sub(floatx80 a, floatx80 b) -{ - floatx80 result = { 0 }; - - switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK) - { - case X87_CW_PC_SINGLE: - { - float32 a32 = floatx80_to_float32(a); - float32 b32 = floatx80_to_float32(b); - result = float32_to_floatx80(float32_sub(a32, b32)); - break; - } - case X87_CW_PC_DOUBLE: - { - float64 a64 = floatx80_to_float64(a); - float64 b64 = floatx80_to_float64(b); - result = float64_to_floatx80(float64_sub(a64, b64)); - break; - } - case X87_CW_PC_EXTEND: - { - result = floatx80_sub(a, b); - break; - } - } - - return result; -} - -floatx80 i386_device::x87_mul(floatx80 a, floatx80 b) -{ - floatx80 val = { 0 }; - - switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK) - { - case X87_CW_PC_SINGLE: - { - float32 a32 = floatx80_to_float32(a); - float32 b32 = floatx80_to_float32(b); - val = float32_to_floatx80(float32_mul(a32, b32)); - break; - } - case X87_CW_PC_DOUBLE: - { - float64 a64 = floatx80_to_float64(a); - float64 b64 = floatx80_to_float64(b); - val = float64_to_floatx80(float64_mul(a64, b64)); - break; - } - case X87_CW_PC_EXTEND: - { - val = floatx80_mul(a, b); - break; - } - } - - return val; -} - - -floatx80 i386_device::x87_div(floatx80 a, floatx80 b) -{ - floatx80 val = { 0 }; - - switch ((m_x87_cw >> X87_CW_PC_SHIFT) & X87_CW_PC_MASK) - { - case X87_CW_PC_SINGLE: - { - float32 a32 = floatx80_to_float32(a); - float32 b32 = floatx80_to_float32(b); - val = float32_to_floatx80(float32_div(a32, b32)); - break; - } - case X87_CW_PC_DOUBLE: - { - float64 a64 = floatx80_to_float64(a); - float64 b64 = floatx80_to_float64(b); - val = float64_to_floatx80(float64_div(a64, b64)); - break; - } - case X87_CW_PC_EXTEND: - { - val = floatx80_div(a, b); - break; - } - } - return val; -} - - -/************************************* - * - * Instructions - * - *************************************/ - -/************************************* - * - * Add - * - *************************************/ - -void i386_device::x87_fadd_m32real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint32_t m32real = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = float32_to_floatx80(m32real); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_add(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fadd_m64real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint64_t m64real = READ64(ea); - - floatx80 a = ST(0); - floatx80 b = float64_to_floatx80(m64real); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_add(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fadd_st_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_add(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fadd_sti_st(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_add(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(i, result, true); - - CYCLES(8); -} - -void i386_device::x87_faddp(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_add(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - x87_inc_stack(); - } - - CYCLES(8); -} - -void i386_device::x87_fiadd_m32int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int32_t m32int = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m32int); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_add(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(19); -} - -void i386_device::x87_fiadd_m16int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int16_t m16int = READ16(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m16int); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_add(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(20); -} - - -/************************************* - * - * Subtract - * - *************************************/ - -void i386_device::x87_fsub_m32real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint32_t m32real = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = float32_to_floatx80(m32real); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsub_m64real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint64_t m64real = READ64(ea); - - floatx80 a = ST(0); - floatx80 b = float64_to_floatx80(m64real); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsub_st_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsub_sti_st(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(i); - floatx80 b = ST(0); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(i, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsubp(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(i); - floatx80 b = ST(0); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - x87_inc_stack(); - } - - CYCLES(8); -} - -void i386_device::x87_fisub_m32int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int32_t m32int = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m32int); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(19); -} - -void i386_device::x87_fisub_m16int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int16_t m16int = READ16(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m16int); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(20); -} - - -/************************************* - * - * Reverse Subtract - * - *************************************/ - -void i386_device::x87_fsubr_m32real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint32_t m32real = READ32(ea); - - floatx80 a = float32_to_floatx80(m32real); - floatx80 b = ST(0); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsubr_m64real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint64_t m64real = READ64(ea); - - floatx80 a = float64_to_floatx80(m64real); - floatx80 b = ST(0); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsubr_st_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(i); - floatx80 b = ST(0); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsubr_sti_st(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(i, result, true); - - CYCLES(8); -} - -void i386_device::x87_fsubrp(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - x87_inc_stack(); - } - - CYCLES(8); -} - -void i386_device::x87_fisubr_m32int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int32_t m32int = READ32(ea); - - floatx80 a = int32_to_floatx80(m32int); - floatx80 b = ST(0); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(19); -} - -void i386_device::x87_fisubr_m16int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int16_t m16int = READ16(ea); - - floatx80 a = int32_to_floatx80(m16int); - floatx80 b = ST(0); - - if ((floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - || (floatx80_is_inf(a) && floatx80_is_inf(b) && ((a.high ^ b.high) & 0x8000))) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_sub(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(20); -} - - -/************************************* - * - * Divide - * - *************************************/ - -void i386_device::x87_fdiv_m32real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint32_t m32real = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = float32_to_floatx80(m32real); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdiv_m64real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint64_t m64real = READ64(ea); - - floatx80 a = ST(0); - floatx80 b = float64_to_floatx80(m64real); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdiv_st_sti(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(0, result, true); - } - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdiv_sti_st(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(i); - floatx80 b = ST(0); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - } - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdivp(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(i); - floatx80 b = ST(0); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - x87_inc_stack(); - } - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fidiv_m32int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int32_t m32int = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m32int); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fidiv_m16int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int16_t m16int = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m16int); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - - -/************************************* - * - * Reverse Divide - * - *************************************/ - -void i386_device::x87_fdivr_m32real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint32_t m32real = READ32(ea); - - floatx80 a = float32_to_floatx80(m32real); - floatx80 b = ST(0); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdivr_m64real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint64_t m64real = READ64(ea); - - floatx80 a = float64_to_floatx80(m64real); - floatx80 b = ST(0); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdivr_st_sti(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(i); - floatx80 b = ST(0); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(0, result, true); - } - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdivr_sti_st(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - } - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fdivrp(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - x87_inc_stack(); - } - - // 73, 62, 35 - CYCLES(73); -} - - -void i386_device::x87_fidivr_m32int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int32_t m32int = READ32(ea); - - floatx80 a = int32_to_floatx80(m32int); - floatx80 b = ST(0); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - -void i386_device::x87_fidivr_m16int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int16_t m16int = READ32(ea); - - floatx80 a = int32_to_floatx80(m16int); - floatx80 b = ST(0); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_div(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - // 73, 62, 35 - CYCLES(73); -} - - -/************************************* - * - * Multiply - * - *************************************/ - -void i386_device::x87_fmul_m32real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint32_t m32real = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = float32_to_floatx80(m32real); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_mul(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(11); -} - -void i386_device::x87_fmul_m64real(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint64_t m64real = READ64(ea); - - floatx80 a = ST(0); - floatx80 b = float64_to_floatx80(m64real); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_mul(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(14); -} - -void i386_device::x87_fmul_st_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_mul(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(16); -} - -void i386_device::x87_fmul_sti_st(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_mul(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(i, result, true); - - CYCLES(16); -} - -void i386_device::x87_fmulp(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_mul(a, b); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, result, true); - x87_inc_stack(); - } - - CYCLES(16); -} - -void i386_device::x87_fimul_m32int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int32_t m32int = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m32int); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_mul(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(22); -} - -void i386_device::x87_fimul_m16int(uint8_t modrm) -{ - floatx80 result; - - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - int16_t m16int = READ16(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m16int); - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = x87_mul(a, b); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(22); -} - -/************************************* -* -* Conditional Move -* -*************************************/ - -void i386_device::x87_fcmovb_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (m_CF == 1) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -void i386_device::x87_fcmove_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (m_ZF == 1) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -void i386_device::x87_fcmovbe_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if ((m_CF | m_ZF) == 1) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -void i386_device::x87_fcmovu_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (m_PF == 1) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -void i386_device::x87_fcmovnb_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (m_CF == 0) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -void i386_device::x87_fcmovne_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (m_ZF == 0) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -void i386_device::x87_fcmovnbe_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if ((m_CF == 0) && (m_ZF == 0)) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -void i386_device::x87_fcmovnu_sti(uint8_t modrm) -{ - floatx80 result; - int i = modrm & 7; - - if (m_PF == 0) - { - if (X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - result = ST(i); - - if (x87_check_exceptions()) - { - ST(0) = result; - } - } - - CYCLES(4); -} - -/************************************* - * - * Miscellaneous arithmetic - * - *************************************/ -/* D9 F8 */ -void i386_device::x87_fprem(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a0 = ST(0); // dividend - floatx80 b1 = ST(1); // divider - - floatx80 a0_abs = packFloatx80(0, (a0.high & 0x7FFF), a0.low); - floatx80 b1_abs = packFloatx80(0, (b1.high & 0x7FFF), b1.low); - m_x87_sw &= ~X87_SW_C2; - - //int d=extractFloatx80Exp(a0)-extractFloatx80Exp(b1); - int d = (a0.high & 0x7FFF) - (b1.high & 0x7FFF); - if (d < 64) { - floatx80 t=floatx80_div(a0_abs, b1_abs); - int64 q = floatx80_to_int64_round_to_zero(t); - floatx80 qf = int64_to_floatx80(q); - floatx80 tt = floatx80_mul(b1_abs, qf); - result = floatx80_sub(a0_abs, tt); - result.high |= a0.high & 0x8000; - // C2 already 0 - m_x87_sw &= ~(X87_SW_C0|X87_SW_C3|X87_SW_C1); - if (q & 1) - m_x87_sw |= X87_SW_C1; - if (q & 2) - m_x87_sw |= X87_SW_C3; - if (q & 4) - m_x87_sw |= X87_SW_C0; - } - else { - m_x87_sw |= X87_SW_C2; - int n = 63; - int e = 1 << (d - n); - floatx80 ef = int32_to_floatx80(e); - floatx80 t=floatx80_div(a0, b1); - floatx80 td = floatx80_div(t, ef); - int64 qq = floatx80_to_int64_round_to_zero(td); - floatx80 qqf = int64_to_floatx80(qq); - floatx80 tt = floatx80_mul(b1, qqf); - floatx80 ttt = floatx80_mul(tt, ef); - result = floatx80_sub(a0, ttt); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(84); -} - -void i386_device::x87_fprem1(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 a = ST(0); - floatx80 b = ST(1); - - m_x87_sw &= ~X87_SW_C2; - - // TODO: Implement Cx bits - result = floatx80_rem(a, b); - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(94); -} - -void i386_device::x87_fsqrt(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 value = ST(0); - - if ((!floatx80_is_zero(value) && (value.high & 0x8000)) || - floatx80_is_denormal(value)) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - result = floatx80_sqrt(value); - } - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(8); -} - -/************************************* - * - * Trigonometric - * - *************************************/ - -void i386_device::x87_f2xm1(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - // TODO: Inaccurate - double x = fx80_to_double(ST(0)); - double res = pow(2.0, x) - 1; - result = double_to_fx80(res); - } - - if (x87_check_exceptions()) - { - x87_write_stack(0, result, true); - } - - CYCLES(242); -} - -void i386_device::x87_fyl2x(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 x = ST(0); - floatx80 y = ST(1); - - if (x.high & 0x8000) - { - m_x87_sw |= X87_SW_IE; - result = fx80_inan; - } - else - { - // TODO: Inaccurate - double d64 = fx80_to_double(x); - double l2x = log(d64)/log(2.0); - result = floatx80_mul(double_to_fx80(l2x), y); - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(1, result, true); - x87_inc_stack(); - } - - CYCLES(250); -} - -void i386_device::x87_fyl2xp1(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - floatx80 x = ST(0); - floatx80 y = ST(1); - - // TODO: Inaccurate - double d64 = fx80_to_double(x); - double l2x1 = log(d64 + 1.0)/log(2.0); - result = floatx80_mul(double_to_fx80(l2x1), y); - } - - if (x87_check_exceptions()) - { - x87_write_stack(1, result, true); - x87_inc_stack(); - } - - CYCLES(313); -} -/* D9 F2 if 8087 0 < angle < pi/4 */ -void i386_device::x87_fptan(uint8_t modrm) -{ - floatx80 result1, result2; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result1 = fx80_inan; - result2 = fx80_inan; - } - else if (!X87_IS_ST_EMPTY(7)) - { - x87_set_stack_overflow(); - result1 = fx80_inan; - result2 = fx80_inan; - } - else - { - result1 = ST(0); - result2 = fx80_one; - -#if 1 // TODO: Function produces bad values - if (floatx80_ftan(result1) != -1) - m_x87_sw &= ~X87_SW_C2; - else - m_x87_sw |= X87_SW_C2; -#else - double x = fx80_to_double(result1); - x = tan(x); - result1 = double_to_fx80(x); - - m_x87_sw &= ~X87_SW_C2; -#endif - } - - if (x87_check_exceptions()) - { - x87_write_stack(0, result1, true); - x87_dec_stack(); - x87_write_stack(0, result2, true); - } - - CYCLES(244); -} -/* D9 F3 */ -void i386_device::x87_fpatan(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - // TODO: Inaccurate - double val = atan2(fx80_to_double(ST(1)) , fx80_to_double(ST(0))); - result = double_to_fx80(val); - } - - if (x87_check_exceptions()) - { - x87_write_stack(1, result, true); - x87_inc_stack(); - } - - CYCLES(289); -} -/* D9 FE 387 only */ -void i386_device::x87_fsin(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - result = ST(0); - - -#if 1 // TODO: Function produces bad values Result checked - if (floatx80_fsin(result) != -1) - m_x87_sw &= ~X87_SW_C2; - else - m_x87_sw |= X87_SW_C2; -#else - double x = fx80_to_double(result); - x = sin(x); - result = double_to_fx80(x); - - m_x87_sw &= ~X87_SW_C2; -#endif - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(241); -} -/* D9 FF 387 only */ -void i386_device::x87_fcos(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - result = ST(0); - -#if 1 // TODO: Function produces bad values to check! - if (floatx80_fcos(result) != -1) - m_x87_sw &= ~X87_SW_C2; - else - m_x87_sw |= X87_SW_C2; -#else - double x = fx80_to_double(result); - x = cos(x); - result = double_to_fx80(x); - - m_x87_sw &= ~X87_SW_C2; -#endif - } - - if (x87_check_exceptions()) - x87_write_stack(0, result, true); - - CYCLES(241); -} -/* D9 FB 387 only */ -void i386_device::x87_fsincos(uint8_t modrm) -{ - floatx80 s_result, c_result; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - s_result = c_result = fx80_inan; - } - else if (!X87_IS_ST_EMPTY(7)) - { - x87_set_stack_overflow(); - s_result = c_result = fx80_inan; - } - else - { - extern int sf_fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a); - - s_result = c_result = ST(0); - -#if 0 // TODO: Function produces bad values - if (sf_fsincos(s_result, &s_result, &c_result) != -1) - m_x87_sw &= ~X87_SW_C2; - else - m_x87_sw |= X87_SW_C2; -#else - double s = fx80_to_double(s_result); - double c = fx80_to_double(c_result); - s = sin(s); - c = cos(c); - - s_result = double_to_fx80(s); - c_result = double_to_fx80(c); - - m_x87_sw &= ~X87_SW_C2; -#endif - } - - if (x87_check_exceptions()) - { - x87_write_stack(0, s_result, true); - x87_dec_stack(); - x87_write_stack(0, c_result, true); - } - - CYCLES(291); -} - - -/************************************* - * - * Load data - * - *************************************/ - -void i386_device::x87_fld_m32real(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 0); - if (x87_dec_stack()) - { - uint32_t m32real = READ32(ea); - - value = float32_to_floatx80(m32real); - - m_x87_sw &= ~X87_SW_C1; - - if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value)) - { - m_x87_sw |= X87_SW_IE; - value = fx80_inan; - } - } - else - { - value = fx80_inan; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(3); -} - -void i386_device::x87_fld_m64real(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 0); - if (x87_dec_stack()) - { - uint64_t m64real = READ64(ea); - - value = float64_to_floatx80(m64real); - - m_x87_sw &= ~X87_SW_C1; - - if (floatx80_is_signaling_nan(value) || floatx80_is_denormal(value)) - { - m_x87_sw |= X87_SW_IE; - value = fx80_inan; - } - } - else - { - value = fx80_inan; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(3); -} - -void i386_device::x87_fld_m80real(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 0); - if (x87_dec_stack()) - { - m_x87_sw &= ~X87_SW_C1; - value = READ80(ea); - } - else - { - value = fx80_inan; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(6); -} - -void i386_device::x87_fld_sti(uint8_t modrm) -{ - floatx80 value; - - if (x87_dec_stack()) - { - m_x87_sw &= ~X87_SW_C1; - value = ST((modrm + 1) & 7); - } - else - { - value = fx80_inan; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(4); -} - -void i386_device::x87_fild_m16int(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 0); - if (!x87_dec_stack()) - { - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - int16_t m16int = READ16(ea); - value = int32_to_floatx80(m16int); - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(13); -} - -void i386_device::x87_fild_m32int(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 0); - if (!x87_dec_stack()) - { - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - int32_t m32int = READ32(ea); - value = int32_to_floatx80(m32int); - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(9); -} - -void i386_device::x87_fild_m64int(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 0); - if (!x87_dec_stack()) - { - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - int64_t m64int = READ64(ea); - value = int64_to_floatx80(m64int); - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(10); -} - -void i386_device::x87_fbld(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 0); - if (!x87_dec_stack()) - { - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - uint64_t m64val = 0; - uint16_t sign; - - value = READ80(ea); - - sign = value.high & 0x8000; - m64val += ((value.high >> 4) & 0xf) * 10; - m64val += ((value.high >> 0) & 0xf); - - for (int i = 60; i >= 0; i -= 4) - { - m64val *= 10; - m64val += (value.low >> i) & 0xf; - } - - value = int64_to_floatx80(m64val); - value.high |= sign; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(75); -} - - -/************************************* - * - * Store data - * - *************************************/ - -void i386_device::x87_fst_m32real(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 1); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - } - - if (x87_check_exceptions()) - { - uint32_t m32real = floatx80_to_float32(value); - WRITE32(ea, m32real); - } - - CYCLES(7); -} - -void i386_device::x87_fst_m64real(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 1); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - } - - if (x87_check_exceptions()) - { - uint64_t m64real = floatx80_to_float64(value); - WRITE64(ea, m64real); - } - - CYCLES(8); -} - -void i386_device::x87_fst_sti(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 value; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - } - - if (x87_check_exceptions()) - x87_write_stack(i, value, true); - - CYCLES(3); -} - -void i386_device::x87_fstp_m32real(uint8_t modrm) -{ - floatx80 value; - - uint32_t ea = GetEA(modrm, 1); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - } - - if (x87_check_exceptions()) - { - uint32_t m32real = floatx80_to_float32(value); - WRITE32(ea, m32real); - x87_inc_stack(); - } - - CYCLES(7); -} - -void i386_device::x87_fstp_m64real(uint8_t modrm) -{ - floatx80 value; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - } - - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - uint64_t m64real = floatx80_to_float64(value); - WRITE64(ea, m64real); - x87_inc_stack(); - } - - CYCLES(8); -} - -void i386_device::x87_fstp_m80real(uint8_t modrm) -{ - floatx80 value; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - } - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - WRITE80(ea, value); - x87_inc_stack(); - } - - CYCLES(6); -} - -void i386_device::x87_fstp_sti(uint8_t modrm) -{ - int i = modrm & 7; - floatx80 value; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - } - - if (x87_check_exceptions()) - { - x87_write_stack(i, value, true); - x87_inc_stack(); - } - - CYCLES(3); -} - -void i386_device::x87_fist_m16int(uint8_t modrm) -{ - int16_t m16int; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m16int = -32768; - } - else - { - floatx80 fx80 = floatx80_round_to_int(ST(0)); - - floatx80 lowerLim = int32_to_floatx80(-32768); - floatx80 upperLim = int32_to_floatx80(32767); - - m_x87_sw &= ~X87_SW_C1; - - if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim)) - m16int = floatx80_to_int32(fx80); - else - m16int = -32768; - } - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - WRITE16(ea, m16int); - } - - CYCLES(29); -} - -void i386_device::x87_fist_m32int(uint8_t modrm) -{ - int32_t m32int; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m32int = 0x80000000; - } - else - { - floatx80 fx80 = floatx80_round_to_int(ST(0)); - - floatx80 lowerLim = int32_to_floatx80(0x80000000); - floatx80 upperLim = int32_to_floatx80(0x7fffffff); - - m_x87_sw &= ~X87_SW_C1; - - if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim)) - m32int = floatx80_to_int32(fx80); - else - m32int = 0x80000000; - } - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - WRITE32(ea, m32int); - } - - CYCLES(28); -} - -void i386_device::x87_fistp_m16int(uint8_t modrm) -{ - int16_t m16int; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m16int = (uint16_t)0x8000; - } - else - { - floatx80 fx80 = floatx80_round_to_int(ST(0)); - - floatx80 lowerLim = int32_to_floatx80(-32768); - floatx80 upperLim = int32_to_floatx80(32767); - - m_x87_sw &= ~X87_SW_C1; - - if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim)) - m16int = floatx80_to_int32(fx80); - else - m16int = (uint16_t)0x8000; - } - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - WRITE16(ea, m16int); - x87_inc_stack(); - } - - CYCLES(29); -} - -void i386_device::x87_fistp_m32int(uint8_t modrm) -{ - int32_t m32int; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m32int = 0x80000000; - } - else - { - floatx80 fx80 = floatx80_round_to_int(ST(0)); - - floatx80 lowerLim = int32_to_floatx80(0x80000000); - floatx80 upperLim = int32_to_floatx80(0x7fffffff); - - m_x87_sw &= ~X87_SW_C1; - - if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim)) - m32int = floatx80_to_int32(fx80); - else - m32int = 0x80000000; - } - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - WRITE32(ea, m32int); - x87_inc_stack(); - } - - CYCLES(29); -} - -void i386_device::x87_fistp_m64int(uint8_t modrm) -{ - int64_t m64int; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m64int = 0x8000000000000000U; - } - else - { - floatx80 fx80 = floatx80_round_to_int(ST(0)); - - floatx80 lowerLim = int64_to_floatx80(0x8000000000000000U); - floatx80 upperLim = int64_to_floatx80(0x7fffffffffffffffU); - - m_x87_sw &= ~X87_SW_C1; - - if (!floatx80_lt(fx80, lowerLim) && floatx80_le(fx80, upperLim)) - m64int = floatx80_to_int64(fx80); - else - m64int = 0x8000000000000000U; - } - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - WRITE64(ea, m64int); - x87_inc_stack(); - } - - CYCLES(29); -} - -void i386_device::x87_fbstp(uint8_t modrm) -{ - floatx80 result; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - result = fx80_inan; - } - else - { - uint64_t u64 = floatx80_to_int64(floatx80_abs(ST(0))); - result.low = 0; - - for (int i = 0; i < 64; i += 4) - { - result.low += (u64 % 10) << i; - u64 /= 10; - } - - result.high = (u64 % 10); - result.high += ((u64 / 10) % 10) << 4; - result.high |= ST(0).high & 0x8000; - } - - uint32_t ea = GetEA(modrm, 1); - if (x87_check_exceptions()) - { - WRITE80(ea, result); - x87_inc_stack(); - } - - CYCLES(175); -} - - -/************************************* - * - * Constant load - * - *************************************/ - -void i386_device::x87_fld1(uint8_t modrm) -{ - floatx80 value; - int tag; - - if (x87_dec_stack()) - { - m_x87_sw &= ~X87_SW_C1; - value = fx80_one; - tag = X87_TW_VALID; - } - else - { - value = fx80_inan; - tag = X87_TW_SPECIAL; - } - - if (x87_check_exceptions()) - { - x87_set_tag(ST_TO_PHYS(0), tag); - x87_write_stack(0, value, false); - } - - CYCLES(4); -} - -void i386_device::x87_fldl2t(uint8_t modrm) -{ - floatx80 value; - int tag; - - if (x87_dec_stack()) - { - tag = X87_TW_VALID; - value.high = 0x4000; - - if (X87_RC == X87_CW_RC_UP) - value.low = 0xd49a784bcd1b8affU; - else - value.low = 0xd49a784bcd1b8afeU; - - m_x87_sw &= ~X87_SW_C1; - } - else - { - value = fx80_inan; - tag = X87_TW_SPECIAL; - } - - if (x87_check_exceptions()) - { - x87_set_tag(ST_TO_PHYS(0), tag); - x87_write_stack(0, value, false); - } - - CYCLES(8); -} - -void i386_device::x87_fldl2e(uint8_t modrm) -{ - floatx80 value; - int tag; - - if (x87_dec_stack()) - { - int rc = X87_RC; - tag = X87_TW_VALID; - value.high = 0x3fff; - - if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST) - value.low = 0xb8aa3b295c17f0bcU; - else - value.low = 0xb8aa3b295c17f0bbU; - - m_x87_sw &= ~X87_SW_C1; - } - else - { - value = fx80_inan; - tag = X87_TW_SPECIAL; - } - - if (x87_check_exceptions()) - { - x87_set_tag(ST_TO_PHYS(0), tag); - x87_write_stack(0, value, false); - } - - CYCLES(8); -} - -void i386_device::x87_fldpi(uint8_t modrm) -{ - floatx80 value; - int tag; - - if (x87_dec_stack()) - { - int rc = X87_RC; - tag = X87_TW_VALID; - value.high = 0x4000; - - if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST) - value.low = 0xc90fdaa22168c235U; - else - value.low = 0xc90fdaa22168c234U; - - m_x87_sw &= ~X87_SW_C1; - } - else - { - value = fx80_inan; - tag = X87_TW_SPECIAL; - } - - if (x87_check_exceptions()) - { - x87_set_tag(ST_TO_PHYS(0), tag); - x87_write_stack(0, value, false); - } - - CYCLES(8); -} - -void i386_device::x87_fldlg2(uint8_t modrm) -{ - floatx80 value; - int tag; - - if (x87_dec_stack()) - { - int rc = X87_RC; - tag = X87_TW_VALID; - value.high = 0x3ffd; - - if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST) - value.low = 0x9a209a84fbcff799U; - else - value.low = 0x9a209a84fbcff798U; - - m_x87_sw &= ~X87_SW_C1; - } - else - { - value = fx80_inan; - tag = X87_TW_SPECIAL; - } - - if (x87_check_exceptions()) - { - x87_set_tag(ST_TO_PHYS(0), tag); - x87_write_stack(0, value, false); - } - - CYCLES(8); -} - -void i386_device::x87_fldln2(uint8_t modrm) -{ - floatx80 value; - int tag; - - if (x87_dec_stack()) - { - int rc = X87_RC; - tag = X87_TW_VALID; - value.high = 0x3ffe; - - if (rc == X87_CW_RC_UP || rc == X87_CW_RC_NEAREST) - value.low = 0xb17217f7d1cf79acU; - else - value.low = 0xb17217f7d1cf79abU; - - m_x87_sw &= ~X87_SW_C1; - } - else - { - value = fx80_inan; - tag = X87_TW_SPECIAL; - } - - if (x87_check_exceptions()) - { - x87_set_tag(ST_TO_PHYS(0), tag); - x87_write_stack(0, value, false); - } - - CYCLES(8); -} - -void i386_device::x87_fldz(uint8_t modrm) -{ - floatx80 value; - int tag; - - if (x87_dec_stack()) - { - value = fx80_zero; - tag = X87_TW_ZERO; - m_x87_sw &= ~X87_SW_C1; - } - else - { - value = fx80_inan; - tag = X87_TW_SPECIAL; - } - - if (x87_check_exceptions()) - { - x87_set_tag(ST_TO_PHYS(0), tag); - x87_write_stack(0, value, false); - } - - CYCLES(4); -} - - -/************************************* - * - * Miscellaneous - * - *************************************/ - -void i386_device::x87_fnop(uint8_t modrm) -{ - CYCLES(3); -} - -void i386_device::x87_fchs(uint8_t modrm) -{ - floatx80 value; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - value = ST(0); - value.high ^= 0x8000; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, false); - - CYCLES(6); -} - -void i386_device::x87_fabs(uint8_t modrm) -{ - floatx80 value; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - value = ST(0); - value.high &= 0x7fff; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, false); - - CYCLES(6); -} - -void i386_device::x87_fscale(uint8_t modrm) -{ - floatx80 value; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - value = ST(0); - - // Set the rounding mode to truncate - uint16_t old_cw = m_x87_cw; - uint16_t new_cw = (old_cw & ~(X87_CW_RC_MASK << X87_CW_RC_SHIFT)) | (X87_CW_RC_ZERO << X87_CW_RC_SHIFT); - x87_write_cw(new_cw); - - // Interpret ST(1) as an integer - uint32_t st1 = floatx80_to_int32(floatx80_round_to_int(ST(1))); - - // Restore the rounding mode - x87_write_cw(old_cw); - - // Get the unbiased exponent of ST(0) - int16_t exp = (ST(0).high & 0x7fff) - 0x3fff; - - // Calculate the new exponent - exp = (exp + st1 + 0x3fff) & 0x7fff; - - // Write it back - value.high = (value.high & ~0x7fff) + exp; - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, false); - - CYCLES(31); -} - -void i386_device::x87_frndint(uint8_t modrm) -{ - floatx80 value; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - value = fx80_inan; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - value = floatx80_round_to_int(ST(0)); - } - - if (x87_check_exceptions()) - x87_write_stack(0, value, true); - - CYCLES(21); -} - -void i386_device::x87_fxtract(uint8_t modrm) -{ - floatx80 sig80, exp80; - - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - sig80 = exp80 = fx80_inan; - } - else if (!X87_IS_ST_EMPTY(7)) - { - x87_set_stack_overflow(); - sig80 = exp80 = fx80_inan; - } - else - { - floatx80 value = ST(0); - - if (floatx80_eq(value, fx80_zero)) - { - m_x87_sw |= X87_SW_ZE; - - exp80 = fx80_ninf; - sig80 = fx80_zero; - } - else - { - // Extract the unbiased exponent - exp80 = int32_to_floatx80((value.high & 0x7fff) - 0x3fff); - - // For the significand, replicate the original value and set its true exponent to 0. - sig80 = value; - sig80.high &= ~0x7fff; - sig80.high |= 0x3fff; - } - } - - if (x87_check_exceptions()) - { - x87_write_stack(0, exp80, true); - x87_dec_stack(); - x87_write_stack(0, sig80, true); - } - - CYCLES(21); -} - -/************************************* - * - * Comparison - * - *************************************/ - -void i386_device::x87_ftst(uint8_t modrm) -{ - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - if (floatx80_is_nan(ST(0))) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(ST(0), fx80_zero)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(ST(0), fx80_zero)) - m_x87_sw |= X87_SW_C0; - } - } - - x87_check_exceptions(); - - CYCLES(4); -} - -void i386_device::x87_fxam(uint8_t modrm) -{ - floatx80 value = ST(0); - - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - // TODO: Unsupported and denormal values - if (X87_IS_ST_EMPTY(0)) - { - m_x87_sw |= X87_SW_C3 | X87_SW_C0; - } - else if (floatx80_is_zero(value)) - { - m_x87_sw |= X87_SW_C3; - } - else if (floatx80_is_nan(value)) - { - m_x87_sw |= X87_SW_C0; - } - else if (floatx80_is_inf(value)) - { - m_x87_sw |= X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw |= X87_SW_C2; - } - - if (value.high & 0x8000) - m_x87_sw |= X87_SW_C1; - - CYCLES(8); -} - -void i386_device::x87_ficom_m16int(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - int16_t m16int = READ16(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m16int); - - if (floatx80_is_nan(a)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - x87_check_exceptions(); - - CYCLES(16); -} - -void i386_device::x87_ficom_m32int(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - int32_t m32int = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m32int); - - if (floatx80_is_nan(a)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - x87_check_exceptions(); - - CYCLES(15); -} - -void i386_device::x87_ficomp_m16int(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - int16_t m16int = READ16(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m16int); - - if (floatx80_is_nan(a)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(16); -} - -void i386_device::x87_ficomp_m32int(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - int32_t m32int = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = int32_to_floatx80(m32int); - - if (floatx80_is_nan(a)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(15); -} - - -void i386_device::x87_fcom_m32real(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - uint32_t m32real = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = float32_to_floatx80(m32real); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - x87_check_exceptions(); - - CYCLES(4); -} - -void i386_device::x87_fcom_m64real(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - uint64_t m64real = READ64(ea); - - floatx80 a = ST(0); - floatx80 b = float64_to_floatx80(m64real); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - x87_check_exceptions(); - - CYCLES(4); -} - -void i386_device::x87_fcom_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - x87_check_exceptions(); - - CYCLES(4); -} - -void i386_device::x87_fcomp_m32real(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - uint32_t m32real = READ32(ea); - - floatx80 a = ST(0); - floatx80 b = float32_to_floatx80(m32real); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(4); -} - -void i386_device::x87_fcomp_m64real(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - if (X87_IS_ST_EMPTY(0)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - uint64_t m64real = READ64(ea); - - floatx80 a = ST(0); - floatx80 b = float64_to_floatx80(m64real); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(4); -} - -void i386_device::x87_fcomp_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(4); -} - -void i386_device::x87_fcomi_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - m_x87_sw |= X87_SW_IE; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - - if (floatx80_eq(a, b)) - m_ZF = 1; - - if (floatx80_lt(a, b)) - m_CF = 1; - } - } - - x87_check_exceptions(); - - CYCLES(4); // TODO: correct cycle count -} - -void i386_device::x87_fcomip_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - m_x87_sw |= X87_SW_IE; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - - if (floatx80_eq(a, b)) - m_ZF = 1; - - if (floatx80_lt(a, b)) - m_CF = 1; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(4); // TODO: correct cycle count -} - -void i386_device::x87_fucomi_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - m_x87_sw |= X87_SW_IE; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - - if (floatx80_eq(a, b)) - m_ZF = 1; - - if (floatx80_lt(a, b)) - m_CF = 1; - } - } - - x87_check_exceptions(); - - CYCLES(4); // TODO: correct cycle count -} - -void i386_device::x87_fucomip_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else - { - m_x87_sw &= ~X87_SW_C1; - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_quiet_nan(a) || floatx80_is_quiet_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - } - else if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_ZF = 1; - m_PF = 1; - m_CF = 1; - m_x87_sw |= X87_SW_IE; - } - else - { - m_ZF = 0; - m_PF = 0; - m_CF = 0; - - if (floatx80_eq(a, b)) - m_ZF = 1; - - if (floatx80_lt(a, b)) - m_CF = 1; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(4); // TODO: correct cycle count -} - -void i386_device::x87_fcompp(uint8_t modrm) -{ - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - floatx80 a = ST(0); - floatx80 b = ST(1); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - { - x87_inc_stack(); - x87_inc_stack(); - } - - CYCLES(5); -} - - -/************************************* - * - * Unordererd comparison - * - *************************************/ - -void i386_device::x87_fucom_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - x87_check_exceptions(); - - CYCLES(4); -} - -void i386_device::x87_fucomp_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(i)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - floatx80 a = ST(0); - floatx80 b = ST(i); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - x87_inc_stack(); - - CYCLES(4); -} - -void i386_device::x87_fucompp(uint8_t modrm) -{ - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - { - x87_set_stack_underflow(); - m_x87_sw |= X87_SW_C3 | X87_SW_C2 | X87_SW_C0; - } - else - { - m_x87_sw &= ~(X87_SW_C3 | X87_SW_C2 | X87_SW_C1 | X87_SW_C0); - - floatx80 a = ST(0); - floatx80 b = ST(1); - - if (floatx80_is_nan(a) || floatx80_is_nan(b)) - { - m_x87_sw |= X87_SW_C0 | X87_SW_C2 | X87_SW_C3; - - if (floatx80_is_signaling_nan(a) || floatx80_is_signaling_nan(b)) - m_x87_sw |= X87_SW_IE; - } - else - { - if (floatx80_eq(a, b)) - m_x87_sw |= X87_SW_C3; - - if (floatx80_lt(a, b)) - m_x87_sw |= X87_SW_C0; - } - } - - if (x87_check_exceptions()) - { - x87_inc_stack(); - x87_inc_stack(); - } - - CYCLES(4); -} - - -/************************************* - * - * Control - * - *************************************/ - -void i386_device::x87_fdecstp(uint8_t modrm) -{ - m_x87_sw &= ~X87_SW_C1; - - x87_set_stack_top(ST_TO_PHYS(7)); - - CYCLES(3); -} - -void i386_device::x87_fincstp(uint8_t modrm) -{ - m_x87_sw &= ~X87_SW_C1; - - x87_set_stack_top(ST_TO_PHYS(1)); - - CYCLES(3); -} - -void i386_device::x87_fclex(uint8_t modrm) -{ - m_x87_sw &= ~0x80ff; - m_ferr_handler(0); - CYCLES(7); -} - -void i386_device::x87_ffree(uint8_t modrm) -{ - x87_set_tag(ST_TO_PHYS(modrm & 7), X87_TW_EMPTY); - - CYCLES(3); -} - -void i386_device::x87_feni(uint8_t modrm) -{ - m_x87_cw &= ~X87_CW_IEM; - x87_check_exceptions(); - - CYCLES(5); -} - -void i386_device::x87_fdisi(uint8_t modrm) -{ - m_x87_cw |= X87_CW_IEM; - - CYCLES(5); -} - -void i386_device::x87_finit(uint8_t modrm) -{ - x87_reset(); - - CYCLES(17); -} - -void i386_device::x87_fldcw(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - uint16_t cw = READ16(ea); - - x87_write_cw(cw); - - x87_check_exceptions(); - - CYCLES(4); -} - -void i386_device::x87_fstcw(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 1); - WRITE16(ea, m_x87_cw); - - CYCLES(3); -} - -void i386_device::x87_fldenv(uint8_t modrm) -{ - // TODO: Pointers and selectors - uint32_t ea = GetEA(modrm, 0); - - if (m_operand_size) - { - // 32-bit real/protected mode - x87_write_cw(READ16(ea)); - m_x87_sw = READ16(ea + 4); - m_x87_tw = READ16(ea + 8); - } - else - { - // 16-bit real/protected mode - x87_write_cw(READ16(ea)); - m_x87_sw = READ16(ea + 2); - m_x87_tw = READ16(ea + 4); - } - - x87_check_exceptions(); - - CYCLES((m_cr[0] & 1) ? 34 : 44); -} - -void i386_device::x87_fstenv(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 1); - - // TODO: Pointers and selectors - switch((m_cr[0] & 1)|(m_operand_size & 1)<<1) - { - case 0: // 16-bit real mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 2, m_x87_sw); - WRITE16(ea + 4, m_x87_tw); -// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4); - break; - case 1: // 16-bit protected mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 2, m_x87_sw); - WRITE16(ea + 4, m_x87_tw); -// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4); - break; - case 2: // 32-bit real mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 4, m_x87_sw); - WRITE16(ea + 8, m_x87_tw); -// WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 20, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12); - break; - case 3: // 32-bit protected mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 4, m_x87_sw); - WRITE16(ea + 8, m_x87_tw); -// WRITE32(ea + 12, m_fpu_inst_ptr); -// WRITE32(ea + 16, m_fpu_opcode); -// WRITE32(ea + 20, m_fpu_data_ptr); -// WRITE32(ea + 24, m_fpu_inst_ptr); - break; - } - m_x87_cw |= 0x3f; // set all masks - - CYCLES((m_cr[0] & 1) ? 56 : 67); -} - -void i386_device::x87_fsave(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 1); - - // TODO: Pointers and selectors - switch((m_cr[0] & 1)|(m_operand_size & 1)<<1) - { - case 0: // 16-bit real mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 2, m_x87_sw); - WRITE16(ea + 4, m_x87_tw); -// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4); - ea += 14; - break; - case 1: // 16-bit protected mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 2, m_x87_sw); - WRITE16(ea + 4, m_x87_tw); -// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4); - ea += 14; - break; - case 2: // 32-bit real mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 4, m_x87_sw); - WRITE16(ea + 8, m_x87_tw); -// WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 20, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12); - ea += 28; - break; - case 3: // 32-bit protected mode - WRITE16(ea + 0, m_x87_cw); - WRITE16(ea + 4, m_x87_sw); - WRITE16(ea + 8, m_x87_tw); -// WRITE32(ea + 12, m_fpu_inst_ptr); -// WRITE32(ea + 16, m_fpu_opcode); -// WRITE32(ea + 20, m_fpu_data_ptr); -// WRITE32(ea + 24, m_fpu_inst_ptr); - ea += 28; - break; - } - - for (int i = 0; i < 8; ++i) - WRITE80(ea + i*10, ST(i)); - - CYCLES((m_cr[0] & 1) ? 56 : 67); -} - -void i386_device::x87_frstor(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 0); - - // TODO: Pointers and selectors - switch((m_cr[0] & 1)|(m_operand_size & 1)<<1) - { - case 0: // 16-bit real mode - x87_write_cw(READ16(ea)); - m_x87_sw = READ16(ea + 2); - m_x87_tw = READ16(ea + 4); -// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4); - ea += 14; - break; - case 1: // 16-bit protected mode - x87_write_cw(READ16(ea)); - m_x87_sw = READ16(ea + 2); - m_x87_tw = READ16(ea + 4); -// WRITE16(ea + 6, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 10, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, (m_fpu_inst_ptr & 0x0f0000) >> 4); - ea += 14; - break; - case 2: // 32-bit real mode - x87_write_cw(READ16(ea)); - m_x87_sw = READ16(ea + 4); - m_x87_tw = READ16(ea + 8); -// WRITE16(ea + 12, m_fpu_inst_ptr & 0xffff); -// WRITE16(ea + 8, (m_fpu_opcode & 0x07ff) | ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE16(ea + 20, m_fpu_data_ptr & 0xffff); -// WRITE16(ea + 12, ((m_fpu_inst_ptr & 0x0f0000) >> 4)); -// WRITE32(ea + 24, (m_fpu_data_ptr >> 16) << 12); - ea += 28; - break; - case 3: // 32-bit protected mode - x87_write_cw(READ16(ea)); - m_x87_sw = READ16(ea + 4); - m_x87_tw = READ16(ea + 8); -// WRITE32(ea + 12, m_fpu_inst_ptr); -// WRITE32(ea + 16, m_fpu_opcode); -// WRITE32(ea + 20, m_fpu_data_ptr); -// WRITE32(ea + 24, m_fpu_inst_ptr); - ea += 28; - break; - } - - for (int i = 0; i < 8; ++i) - x87_write_stack(i, READ80(ea + i*10), false); - - CYCLES((m_cr[0] & 1) ? 34 : 44); -} - -void i386_device::x87_fxch(uint8_t modrm) -{ - if (X87_IS_ST_EMPTY(0) || X87_IS_ST_EMPTY(1)) - x87_set_stack_underflow(); - - if (x87_check_exceptions()) - { - floatx80 tmp = ST(0); - ST(0) = ST(1); - ST(1) = tmp; - - // Swap the tags - int tag0 = X87_TAG(ST_TO_PHYS(0)); - x87_set_tag(ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(1))); - x87_set_tag(ST_TO_PHYS(1), tag0); - } - - CYCLES(4); -} - -void i386_device::x87_fxch_sti(uint8_t modrm) -{ - int i = modrm & 7; - - if (X87_IS_ST_EMPTY(0)) - { - ST(0) = fx80_inan; - x87_set_tag(ST_TO_PHYS(0), X87_TW_SPECIAL); - x87_set_stack_underflow(); - } - if (X87_IS_ST_EMPTY(i)) - { - ST(i) = fx80_inan; - x87_set_tag(ST_TO_PHYS(i), X87_TW_SPECIAL); - x87_set_stack_underflow(); - } - - if (x87_check_exceptions()) - { - floatx80 tmp = ST(0); - ST(0) = ST(i); - ST(i) = tmp; - - // Swap the tags - int tag0 = X87_TAG(ST_TO_PHYS(0)); - x87_set_tag(ST_TO_PHYS(0), X87_TAG(ST_TO_PHYS(i))); - x87_set_tag(ST_TO_PHYS(i), tag0); - } - - CYCLES(4); -} - -void i386_device::x87_fstsw_ax(uint8_t modrm) -{ - REG16(AX) = m_x87_sw; - - CYCLES(3); -} - -void i386_device::x87_fstsw_m2byte(uint8_t modrm) -{ - uint32_t ea = GetEA(modrm, 1); - - WRITE16(ea, m_x87_sw); - - CYCLES(3); -} - -void i386_device::x87_invalid(uint8_t modrm) -{ - // TODO - report_invalid_opcode(); - i386_trap(6, 0, 0); -} - - - -/************************************* - * - * Instruction dispatch - * - *************************************/ - -void i386_device::i386_x87_group_d8() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_d8[modrm])(modrm); -} - -void i386_device::i386_x87_group_d9() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_d9[modrm])(modrm); -} - -void i386_device::i386_x87_group_da() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_da[modrm])(modrm); -} - -void i386_device::i386_x87_group_db() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_db[modrm])(modrm); -} - -void i386_device::i386_x87_group_dc() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_dc[modrm])(modrm); -} - -void i386_device::i386_x87_group_dd() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_dd[modrm])(modrm); -} - -void i386_device::i386_x87_group_de() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_de[modrm])(modrm); -} - -void i386_device::i386_x87_group_df() -{ - uint8_t modrm = FETCH(); - (this->*m_opcode_table_x87_df[modrm])(modrm); -} - - -/************************************* - * - * Opcode table building - * - *************************************/ - -void i386_device::build_x87_opcode_table_d8() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fadd_m32real; break; - case 0x01: ptr = &i386_device::x87_fmul_m32real; break; - case 0x02: ptr = &i386_device::x87_fcom_m32real; break; - case 0x03: ptr = &i386_device::x87_fcomp_m32real; break; - case 0x04: ptr = &i386_device::x87_fsub_m32real; break; - case 0x05: ptr = &i386_device::x87_fsubr_m32real; break; - case 0x06: ptr = &i386_device::x87_fdiv_m32real; break; - case 0x07: ptr = &i386_device::x87_fdivr_m32real; break; - } - } - else - { - switch (modrm) - { - case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fadd_st_sti; break; - case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmul_st_sti; break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fcom_sti; break; - case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fcomp_sti; break; - case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsub_st_sti; break; - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsubr_st_sti; break; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdiv_st_sti; break; - case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdivr_st_sti; break; - } - } - - m_opcode_table_x87_d8[modrm] = ptr; - } -} - - -void i386_device::build_x87_opcode_table_d9() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fld_m32real; break; - case 0x02: ptr = &i386_device::x87_fst_m32real; break; - case 0x03: ptr = &i386_device::x87_fstp_m32real; break; - case 0x04: ptr = &i386_device::x87_fldenv; break; - case 0x05: ptr = &i386_device::x87_fldcw; break; - case 0x06: ptr = &i386_device::x87_fstenv; break; - case 0x07: ptr = &i386_device::x87_fstcw; break; - } - } - else - { - switch (modrm) - { - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: ptr = &i386_device::x87_fld_sti; break; - - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: ptr = &i386_device::x87_fxch_sti; break; - - case 0xd0: ptr = &i386_device::x87_fnop; break; - case 0xe0: ptr = &i386_device::x87_fchs; break; - case 0xe1: ptr = &i386_device::x87_fabs; break; - case 0xe4: ptr = &i386_device::x87_ftst; break; - case 0xe5: ptr = &i386_device::x87_fxam; break; - case 0xe8: ptr = &i386_device::x87_fld1; break; - case 0xe9: ptr = &i386_device::x87_fldl2t; break; - case 0xea: ptr = &i386_device::x87_fldl2e; break; - case 0xeb: ptr = &i386_device::x87_fldpi; break; - case 0xec: ptr = &i386_device::x87_fldlg2; break; - case 0xed: ptr = &i386_device::x87_fldln2; break; - case 0xee: ptr = &i386_device::x87_fldz; break; - case 0xf0: ptr = &i386_device::x87_f2xm1; break; - case 0xf1: ptr = &i386_device::x87_fyl2x; break; - case 0xf2: ptr = &i386_device::x87_fptan; break; - case 0xf3: ptr = &i386_device::x87_fpatan; break; - case 0xf4: ptr = &i386_device::x87_fxtract; break; - case 0xf5: ptr = &i386_device::x87_fprem1; break; - case 0xf6: ptr = &i386_device::x87_fdecstp; break; - case 0xf7: ptr = &i386_device::x87_fincstp; break; - case 0xf8: ptr = &i386_device::x87_fprem; break; - case 0xf9: ptr = &i386_device::x87_fyl2xp1; break; - case 0xfa: ptr = &i386_device::x87_fsqrt; break; - case 0xfb: ptr = &i386_device::x87_fsincos; break; - case 0xfc: ptr = &i386_device::x87_frndint; break; - case 0xfd: ptr = &i386_device::x87_fscale; break; - case 0xfe: ptr = &i386_device::x87_fsin; break; - case 0xff: ptr = &i386_device::x87_fcos; break; - } - } - - m_opcode_table_x87_d9[modrm] = ptr; - } -} - -void i386_device::build_x87_opcode_table_da() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fiadd_m32int; break; - case 0x01: ptr = &i386_device::x87_fimul_m32int; break; - case 0x02: ptr = &i386_device::x87_ficom_m32int; break; - case 0x03: ptr = &i386_device::x87_ficomp_m32int; break; - case 0x04: ptr = &i386_device::x87_fisub_m32int; break; - case 0x05: ptr = &i386_device::x87_fisubr_m32int; break; - case 0x06: ptr = &i386_device::x87_fidiv_m32int; break; - case 0x07: ptr = &i386_device::x87_fidivr_m32int; break; - } - } - else - { - switch (modrm) - { - case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fcmovb_sti; break; - case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fcmove_sti; break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fcmovbe_sti; break; - case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fcmovu_sti; break; - case 0xe9: ptr = &i386_device::x87_fucompp; break; - } - } - - m_opcode_table_x87_da[modrm] = ptr; - } -} - - -void i386_device::build_x87_opcode_table_db() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fild_m32int; break; - case 0x02: ptr = &i386_device::x87_fist_m32int; break; - case 0x03: ptr = &i386_device::x87_fistp_m32int; break; - case 0x05: ptr = &i386_device::x87_fld_m80real; break; - case 0x07: ptr = &i386_device::x87_fstp_m80real; break; - } - } - else - { - switch (modrm) - { - case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fcmovnb_sti; break; - case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fcmovne_sti; break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fcmovnbe_sti; break; - case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fcmovnu_sti; break; - case 0xe0: ptr = &i386_device::x87_feni; break; /* FENI */ - case 0xe1: ptr = &i386_device::x87_fdisi; break; /* FDISI */ - case 0xe2: ptr = &i386_device::x87_fclex; break; - case 0xe3: ptr = &i386_device::x87_finit; break; - case 0xe4: ptr = &i386_device::x87_fnop; break; /* FSETPM */ - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fucomi_sti; break; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fcomi_sti; break; - } - } - - m_opcode_table_x87_db[modrm] = ptr; - } -} - - -void i386_device::build_x87_opcode_table_dc() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fadd_m64real; break; - case 0x01: ptr = &i386_device::x87_fmul_m64real; break; - case 0x02: ptr = &i386_device::x87_fcom_m64real; break; - case 0x03: ptr = &i386_device::x87_fcomp_m64real; break; - case 0x04: ptr = &i386_device::x87_fsub_m64real; break; - case 0x05: ptr = &i386_device::x87_fsubr_m64real; break; - case 0x06: ptr = &i386_device::x87_fdiv_m64real; break; - case 0x07: ptr = &i386_device::x87_fdivr_m64real; break; - } - } - else - { - switch (modrm) - { - case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_fadd_sti_st; break; - case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmul_sti_st; break; - case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsubr_sti_st; break; - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsub_sti_st; break; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdivr_sti_st; break; - case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdiv_sti_st; break; - } - } - - m_opcode_table_x87_dc[modrm] = ptr; - } -} - - -void i386_device::build_x87_opcode_table_dd() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fld_m64real; break; - case 0x02: ptr = &i386_device::x87_fst_m64real; break; - case 0x03: ptr = &i386_device::x87_fstp_m64real; break; - case 0x04: ptr = &i386_device::x87_frstor; break; - case 0x06: ptr = &i386_device::x87_fsave; break; - case 0x07: ptr = &i386_device::x87_fstsw_m2byte; break; - } - } - else - { - switch (modrm) - { - case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_ffree; break; - case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fxch_sti; break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: ptr = &i386_device::x87_fst_sti; break; - case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: ptr = &i386_device::x87_fstp_sti; break; - case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fucom_sti; break; - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fucomp_sti; break; - } - } - - m_opcode_table_x87_dd[modrm] = ptr; - } -} - - -void i386_device::build_x87_opcode_table_de() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fiadd_m16int; break; - case 0x01: ptr = &i386_device::x87_fimul_m16int; break; - case 0x02: ptr = &i386_device::x87_ficom_m16int; break; - case 0x03: ptr = &i386_device::x87_ficomp_m16int; break; - case 0x04: ptr = &i386_device::x87_fisub_m16int; break; - case 0x05: ptr = &i386_device::x87_fisubr_m16int; break; - case 0x06: ptr = &i386_device::x87_fidiv_m16int; break; - case 0x07: ptr = &i386_device::x87_fidivr_m16int; break; - } - } - else - { - switch (modrm) - { - case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: ptr = &i386_device::x87_faddp; break; - case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: ptr = &i386_device::x87_fmulp; break; - case 0xd9: ptr = &i386_device::x87_fcompp; break; - case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: ptr = &i386_device::x87_fsubrp; break; - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fsubp; break; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fdivrp; break; - case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: ptr = &i386_device::x87_fdivp; break; - } - } - - m_opcode_table_x87_de[modrm] = ptr; - } -} - - -void i386_device::build_x87_opcode_table_df() -{ - int modrm = 0; - - for (modrm = 0; modrm < 0x100; ++modrm) - { - i386_modrm_func ptr = &i386_device::x87_invalid; - - if (modrm < 0xc0) - { - switch ((modrm >> 3) & 0x7) - { - case 0x00: ptr = &i386_device::x87_fild_m16int; break; - case 0x02: ptr = &i386_device::x87_fist_m16int; break; - case 0x03: ptr = &i386_device::x87_fistp_m16int; break; - case 0x04: ptr = &i386_device::x87_fbld; break; - case 0x05: ptr = &i386_device::x87_fild_m64int; break; - case 0x06: ptr = &i386_device::x87_fbstp; break; - case 0x07: ptr = &i386_device::x87_fistp_m64int; break; - } - } - else - { - switch (modrm) - { - case 0xe0: ptr = &i386_device::x87_fstsw_ax; break; - case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: ptr = &i386_device::x87_fucomip_sti; break; - case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: ptr = &i386_device::x87_fcomip_sti; break; - } - } - - m_opcode_table_x87_df[modrm] = ptr; - } -} - -void i386_device::build_x87_opcode_table() -{ - build_x87_opcode_table_d8(); - build_x87_opcode_table_d9(); - build_x87_opcode_table_da(); - build_x87_opcode_table_db(); - build_x87_opcode_table_dc(); - build_x87_opcode_table_dd(); - build_x87_opcode_table_de(); - build_x87_opcode_table_df(); -} - - diff --git a/source/src/vm/libcpu_newdev/i386/x87priv.h b/source/src/vm/libcpu_newdev/i386/x87priv.h deleted file mode 100644 index 67cf067a1..000000000 --- a/source/src/vm/libcpu_newdev/i386/x87priv.h +++ /dev/null @@ -1,169 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Philip Bennett -#pragma once - -#ifndef __X87PRIV_H__ -#define __X87PRIV_H__ - -#include - - -/************************************* - * - * Defines - * - *************************************/ - -#define X87_SW_IE 0x0001 -#define X87_SW_DE 0x0002 -#define X87_SW_ZE 0x0004 -#define X87_SW_OE 0x0008 -#define X87_SW_UE 0x0010 -#define X87_SW_PE 0x0020 -#define X87_SW_SF 0x0040 -#define X87_SW_ES 0x0080 -#define X87_SW_C0 0x0100 -#define X87_SW_C1 0x0200 -#define X87_SW_C2 0x0400 -#define X87_SW_TOP_SHIFT 11 -#define X87_SW_TOP_MASK 7 -#define X87_SW_C3 0x4000 -#define X87_SW_BUSY 0x8000 - -#define X87_CW_IM 0x0001 -#define X87_CW_DM 0x0002 -#define X87_CW_ZM 0x0004 -#define X87_CW_OM 0x0008 -#define X87_CW_UM 0x0010 -#define X87_CW_PM 0x0020 -#define X87_CW_IEM 0x0080 -#define X87_CW_PC_SHIFT 8 -#define X87_CW_PC_MASK 3 -#define X87_CW_PC_SINGLE 0 -#define X87_CW_PC_DOUBLE 2 -#define X87_CW_PC_EXTEND 3 -#define X87_CW_RC_SHIFT 10 -#define X87_CW_RC_MASK 3 -#define X87_CW_RC_NEAREST 0 -#define X87_CW_RC_DOWN 1 -#define X87_CW_RC_UP 2 -#define X87_CW_RC_ZERO 3 - -#define X87_TW_MASK 3 -#define X87_TW_VALID 0 -#define X87_TW_ZERO 1 -#define X87_TW_SPECIAL 2 -#define X87_TW_EMPTY 3 - - - /************************************* - * - * Macros - * - *************************************/ - -#define ST_TO_PHYS(x) (((m_x87_sw >> X87_SW_TOP_SHIFT) + (x)) & X87_SW_TOP_MASK) -#define ST(x) (m_x87_reg[ST_TO_PHYS(x)]) -#define X87_TW_FIELD_SHIFT(x) ((x) << 1) -#define X87_TAG(x) ((m_x87_tw >> X87_TW_FIELD_SHIFT(x)) & X87_TW_MASK) -#define X87_RC ((m_x87_cw >> X87_CW_RC_SHIFT) & X87_CW_RC_MASK) -#define X87_IS_ST_EMPTY(x) (X87_TAG(ST_TO_PHYS(x)) == X87_TW_EMPTY) -#define X87_SW_C3_0 X87_SW_C0 - -#define UNIMPLEMENTED fatalerror("Unimplemented x87 op: %s (PC:%x)\n", __FUNCTION__, m_pc) - - - /************************************* - * - * Constants - * - *************************************/ - -static const floatx80 fx80_zero = { 0x0000, 0x0000000000000000U }; -static const floatx80 fx80_one = { 0x3fff, 0x8000000000000000U }; - -static const floatx80 fx80_ninf = { 0xffff, 0x8000000000000000U }; -static const floatx80 fx80_inan = { 0xffff, 0xc000000000000000U }; - -/* Maps x87 round modes to SoftFloat round modes */ -static const int x87_to_sf_rc[4] = -{ - float_round_nearest_even, - float_round_down, - float_round_up, - float_round_to_zero, -}; - - -/************************************* - * - * SoftFloat helpers - * - *************************************/ - -extern flag floatx80_is_nan(floatx80 a); - -extern flag floatx80_is_signaling_nan(floatx80 a); - -static inline flag floatx80_is_quiet_nan(floatx80 a) -{ - bits64 aLow; - - aLow = a.low & ~LIT64(0x4000000000000000); - return - ((a.high & 0x7FFF) == 0x7FFF) - && (bits64)(aLow << 1) - && (a.low != aLow); -} - -static inline int floatx80_is_zero(floatx80 fx) -{ - return (((fx.high & 0x7fff) == 0) && ((fx.low << 1) == 0)); -} - -static inline int floatx80_is_inf(floatx80 fx) -{ - return (((fx.high & 0x7fff) == 0x7fff) && ((fx.low << 1) == 0)); -} - -static inline int floatx80_is_denormal(floatx80 fx) -{ - return (((fx.high & 0x7fff) == 0) && - ((fx.low & 0x8000000000000000U) == 0) && - ((fx.low << 1) != 0)); -} - -static inline floatx80 floatx80_abs(floatx80 fx) -{ - fx.high &= 0x7fff; - return fx; -} - -static inline double fx80_to_double(floatx80 fx) -{ - uint64_t d = floatx80_to_float64(fx); - return *(double*)&d; -} - -static inline floatx80 double_to_fx80(double in) -{ - return float64_to_floatx80(*(uint64_t*)&in); -} - -floatx80 i386_device::READ80(uint32_t ea) -{ - floatx80 t; - - t.low = READ64(ea); - t.high = READ16(ea + 8); - - return t; -} - -void i386_device::WRITE80(uint32_t ea, floatx80 t) -{ - WRITE64(ea, t.low); - WRITE16(ea + 8, t.high); -} - -#endif /* __X87PRIV_H__ */ diff --git a/source/src/vm/libcpu_newdev/memcache/memcache.cpp b/source/src/vm/libcpu_newdev/memcache/memcache.cpp deleted file mode 100644 index ce51793ca..000000000 --- a/source/src/vm/libcpu_newdev/memcache/memcache.cpp +++ /dev/null @@ -1,337 +0,0 @@ - - -//************************************************************************** -// DEBUGGING -//************************************************************************** - -#define VERBOSE (0) - -#define VPRINTF(x) do { if (VERBOSE) printf x; } while (0) - -#define VALIDATE_REFCOUNTS 1 - -void handler_entry::dump_map(std::vector &map) const -{ - fatalerror("dump_map called on non-dispatching class\n"); -} - -void handler_entry::reflist::add(const handler_entry *entry) -{ - refcounts[entry]++; - if(seen.find(entry) == seen.end()) { - seen.insert(entry); - todo.insert(entry); - } -} - -void handler_entry::reflist::propagate() -{ - while(!todo.empty()) { - const handler_entry *entry = *todo.begin(); - todo.erase(todo.begin()); - entry->enumerate_references(*this); - } -} - -void handler_entry::reflist::check() -{ - bool bad = false; - for(const auto &i : refcounts) { - if(i.first->get_refcount() != i.second) { - fprintf(stderr, "Reference count error on handler \"%s\" stored %u real %u.\n", - i.first->name().c_str(), i.first->get_refcount(), i.second); - bad = true; - } - } - if(bad) - abort(); -} - - -// default handler methods - -void handler_entry::enumerate_references(handler_entry::reflist &refs) const -{ -} - -template void handler_entry_read::populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read *handler) -{ - fatalerror("populate called on non-dispatching class\n"); -} - -template void handler_entry_read::populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read *handler) -{ - fatalerror("populate called on non-dispatching class\n"); -} - -template void handler_entry_read::populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor &descriptor, u8 rkey, std::vector &mappings) -{ - fatalerror("populate_mismatched called on non-dispatching class\n"); -} - -template void handler_entry_read::populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor &descriptor, std::vector &mappings) -{ - fatalerror("populate_mismatched called on non-dispatching class\n"); -} - -template void handler_entry_read::populate_passthrough_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read_passthrough *handler, std::vector &mappings) -{ - fatalerror("populate_passthrough called on non-dispatching class\n"); -} - -template void handler_entry_read::populate_passthrough_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read_passthrough *handler, std::vector &mappings) -{ - fatalerror("populate_passthrough called on non-dispatching class\n"); -} - -template void handler_entry_read::lookup(offs_t address, offs_t &start, offs_t &end, handler_entry_read *&handler) const -{ - fatalerror("lookup called on non-dispatching class\n"); -} - -template void *handler_entry_read::get_ptr(offs_t offset) const -{ - return nullptr; -} - -template void handler_entry_read::detach(const std::unordered_set &handlers) -{ - fatalerror("detach called on non-dispatching class\n"); -} - - -template void handler_entry_write::populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_write *handler) -{ - fatalerror("populate called on non-dispatching class\n"); -} - -template void handler_entry_write::populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_write *handler) -{ - fatalerror("populate called on non-dispatching class\n"); -} - -template void handler_entry_write::populate_mismatched_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, const memory_units_descriptor &descriptor, u8 rkey, std::vector &mappings) -{ - fatalerror("populate_mismatched called on non-dispatching class\n"); -} - -template void handler_entry_write::populate_mismatched_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, const memory_units_descriptor &descriptor, std::vector &mappings) -{ - fatalerror("populate_mismatched called on non-dispatching class\n"); -} - -template void handler_entry_write::populate_passthrough_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_write_passthrough *handler, std::vector &mappings) -{ - fatalerror("populate_passthrough called on non-dispatching class\n"); -} - -template void handler_entry_write::populate_passthrough_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_write_passthrough *handler, std::vector &mappings) -{ - fatalerror("populate_passthrough called on non-dispatching class\n"); -} - -template void handler_entry_write::lookup(offs_t address, offs_t &start, offs_t &end, handler_entry_write *&handler) const -{ - fatalerror("lookup called on non-dispatching class\n"); -} - -template void *handler_entry_write::get_ptr(offs_t offset) const -{ - return nullptr; -} - -template void handler_entry_write::detach(const std::unordered_set &handlers) -{ - fatalerror("detach called on non-dispatching class\n"); -} - - -//************************************************************************** -// CACHE MEMORY RANGES -//************************************************************************** - -//------------------------------------------------- -// memory_access_cache - constructor -//------------------------------------------------- - -template memory_access_cache::memory_access_cache(address_space &space, - handler_entry_read *root_read, - handler_entry_write *root_write) - : m_space(space), - m_addrmask(space.addrmask()), - m_addrstart_r(1), - m_addrend_r(0), - m_addrstart_w(1), - m_addrend_w(0), - m_cache_r(nullptr), - m_cache_w(nullptr), - m_root_read(root_read), - m_root_write(root_write) -{ - -// m_notifier_id = space.add_change_notifier([this](read_or_write mode) { -// if(u32(mode) & u32(read_or_write::READ)) { -// m_addrend_r = 0; -// m_addrstart_r = 1; -// m_cache_r = nullptr; -// } -// if(u32(mode) & u32(read_or_write::WRITE)) { -// m_addrend_w = 0; -// m_addrstart_w = 1; -// m_cache_w = nullptr; -// } -// }); -} - - -//------------------------------------------------- -// ~memory_access_cache - destructor -//------------------------------------------------- - -template memory_access_cache::~memory_access_cache() -{ -// m_space.remove_change_notifier(m_notifier_id); -} - - -template class memory_access_cache<0, 1, ENDIANNESS_LITTLE>; -template class memory_access_cache<0, 1, ENDIANNESS_BIG>; -template class memory_access_cache<0, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<0, 0, ENDIANNESS_BIG>; -template class memory_access_cache<1, 3, ENDIANNESS_LITTLE>; -template class memory_access_cache<1, 3, ENDIANNESS_BIG>; -template class memory_access_cache<1, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<1, 0, ENDIANNESS_BIG>; -template class memory_access_cache<1, -1, ENDIANNESS_LITTLE>; -template class memory_access_cache<1, -1, ENDIANNESS_BIG>; -template class memory_access_cache<2, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<2, 0, ENDIANNESS_BIG>; -template class memory_access_cache<2, -1, ENDIANNESS_LITTLE>; -template class memory_access_cache<2, -1, ENDIANNESS_BIG>; -template class memory_access_cache<2, -2, ENDIANNESS_LITTLE>; -template class memory_access_cache<2, -2, ENDIANNESS_BIG>; -template class memory_access_cache<3, 0, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, 0, ENDIANNESS_BIG>; -template class memory_access_cache<3, -1, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, -1, ENDIANNESS_BIG>; -template class memory_access_cache<3, -2, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, -2, ENDIANNESS_BIG>; -template class memory_access_cache<3, -3, ENDIANNESS_LITTLE>; -template class memory_access_cache<3, -3, ENDIANNESS_BIG>; - -uint8_t read_native(offs_t offset, uint8_t mask) -{ -// g_profiler.start(PROFILER_MEMREAD); - - uint8_t result = m_root_read->read_data8(offset) & mask; - -// g_profiler.stop(); - return result; -} - -uint16_t read_native(offs_t offset, uint16_t mask) -{ -// g_profiler.start(PROFILER_MEMREAD); - - uint16_t result = m_root_read->read_data16(offset) & mask; - -// g_profiler.stop(); - return result; -} - -uint32_t read_native(offs_t offset, uint32_t mask) -{ -// g_profiler.start(PROFILER_MEMREAD); - - uint32_t result = m_root_read->read_data32(offset) & mask; - -// g_profiler.stop(); - return result; -} - -uint64_t read_native(offs_t offset, uint64_t mask) -{ -// g_profiler.start(PROFILER_MEMREAD); - - pair64_t result; - pair64_t pmask; - pmask.q = mask; - result.d.l = m_root_read->read_data32(offset) & pmask.l; - result.d.h = m_root_read->read_data32(offset + 4) & pmask.h; - -// g_profiler.stop(); - return result; -} - -void write_native(offs_t offset, uint8_t data, uint8_t mask) -{ -// g_profiler.start(PROFILER_MEMWRITE); - - if(mask != 0xff) { - uint8_t n = m_root_write->read_data8(offset); - n = n & ~(mask); - n = n | (data & mask); - m_root_write->write_data8(offset, n); - } else { - m_root_write->write_data8(offset, data); - } - -// g_profiler.stop(); -} - -void write_native(offs_t offset, uint16_t data, uint16_t mask) -{ -// g_profiler.start(PROFILER_MEMWRITE); - - if(mask != 0xffff) { - uint16_t n = m_root_write->read_data16(offset); - n = n & ~(mask); - n = n | (data & mask); - m_root_write->write_data16(offset, n); - } else { - m_root_write->write_data16(offset, data); - } - -// g_profiler.stop(); -} - -void write_native(offs_t offset, uint32_t data, uint32_t mask) -{ -// g_profiler.start(PROFILER_MEMWRITE); - - if(mask != 0xffffffff) { - uint32_t n = m_root_write->read_data32(offset); - n = n & ~(mask); - n = n | (data & mask); - m_root_write->write_data32(offset, n); - } else { - m_root_write->write_data32(offset, data); - } - -// g_profiler.stop(); -} - -void write_native(offs_t offset, uint64_t data, uint64_t mask) -{ -// g_profiler.start(PROFILER_MEMWRITE); - - pair64_t d; - d.q = data; - if(mask != ~((uint64_t)0)) { - pair64_t n; - pair64_t m; - m.q = mask; - n.d.l = m_root_write->read_data32(offset); - n.d.h = m_root_write->read_data32(offset + 4); - n.q = n.q & ~(m.q); - d.q = d.q & m.q; - d.q = d.q | n.q; - m_root_write->write_data32(offset, d.d.l); - m_root_write->write_data32(offset + 4, d.d.h); - } else { - m_root_write->write_data32(offset, d.d.l); - m_root_write->write_data32(offset + 4, d.d.h); - } - -// g_profiler.stop(); -} diff --git a/source/src/vm/libcpu_newdev/memcache/memcache.h b/source/src/vm/libcpu_newdev/memcache/memcache.h deleted file mode 100644 index d9f23632d..000000000 --- a/source/src/vm/libcpu_newdev/memcache/memcache.h +++ /dev/null @@ -1,313 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles,Olivier Galibert -/*************************************************************************** - - emumem.h - - Functions which handle device memory accesses. - -***************************************************************************/ - -#pragma once -#include "../../device.h" - -enum { - CACHE_LINE_NOCACHE = 0, - CACHE_LINE_READ = 1, - CACHE_LINE_WRITE = 2, - CACHE_LINE_READ_WRITE =3 -}; - -class DEVICE; -class cache_line -{ -private: - DEVICE *d_device; - bool prefetch_enabled; - int prefetch_block_size; - bool enabled; - uint32_t start_addr; - uint32_t end_addr; - int access_type; - uint8_t *cache_data; - bool *is_exists; - bool is_little_endian; -public: - cache_line(uint32_t start, uint32_t line_size, DEVICE* dev = NULL, int type = CACHE_LINE_READ_WRITE, int prefetch_size = -1) - { - prefetch_enabled = (prefetch_size > 0) ? true : false; - prefetch_block_size = prefetch_size; - enabled = false; - cache_data = nullptr; - is_exists = nullptr; - start_addr = start; - end_addr = start_addr; - access_type = type; - d_device = dev; - if(line_size > 0) { - cache_data = new uint8_t[line_size]; - is_exists = new bool[line_size]; - if((cache_data != nullptr) && (is_exists != nullptr)) { - end_addr = start_addr + line_size - 1; - for(int i = 0; i < line_size; i++) { - cache_data[i] = 0x00; - is_exists[i] = false; - } - enabled = true; - } - } - } - ~cache_line() { - if(is_exists != nullptr) delete [] is_exists; - if(cache_data != nullptr) delete [] cache_data; - } - bool is_enabled() { - return enabled; - } - bool is_cache_enabled(addr) { - return resion_check(addr); - } - uint32_t get_start_address() { - if(enabled) { - return start_addr; - } - return 0; - } - uint32_t get_end_address() { - if(enabled) { - return end_addr; - } - return 0; - } - uint32_t get_line_size() { - if(enabled) { - return end_addr - start_addr + 1; - } - return 0; - } - inline bool region_check(addr) { - if(!(enabled)) return false; - return ((addr >= start_addr) && (addr <= end_addr)) ? true : false; - } - inline bool region_check_range(uint32_t addr, uint32_t range) - { - if(!(enabled)) return false; - if(range == 0) return false; - return ((addr >= start_addr) && ((addr + range - 1) <= end_addr)) ? true : false; - } - inline bool cache_hit(uint32_t addr) { - if(region_check(addr)) { - return is_exists[addr - start_addr]; - } - return false; - } - inline bool cache_hit_range(uint32_t addr, uint32_t range) { - if(region_check_range(addr, range)) { - bool f = true; - uint32_t base = addr - start_addr; - for(uint32_t i = 0; i < range; i++) { - if(!(is_exists[base + i])) { - f = false; - break; - } - } - return f; - } - return false; - } - int set_prefetch_block_size(int bytes) - { - prefetch_block_size = bytes; - } - bool request_prefetch(uint32_t start) - { - if(prefetch_block_size <= 0) return false; - if(region_check(start)) { - for(int i = 0; i < prefetch_block_size; i++) { - if(!(prefetch(start + i))) return false; - } - return true; - } - return false; - } - bool prefetch(uint32_t addr) - { - if(region_check(start)) { - int wait; - cache_data[addr - start_addr] = d_device->read_data8w(addr, &wait); - is_exists[addr - start_addr] = true; - return true; - } - return false; - } - bool discard_memory_resion(uint32_t start, uint32_t end) - { - if(!(enabled)) return false; - if(start > end) { - uint32_t tmp; - tmp = start; - start = end; - end = start; - } - if((start < start_addr) && (end < start_addr)) return false; - if((start > end_addr) && (end > end_addr)) return false; - if(start < start_addr) { - start = start_addr; - } - if(end > end_addr) { - end = end_addr; - } - if(!(resion_check(start)) || !(resion_check(end))) return false; - - uint32_t __begin = start - start_addr; - uint32_t __end = end - start_addr + 1; - for(uint32_t a = __begin; a < __end; a++) { - is_exists[a] = false; - } - return true; - } - bool discard_cache(uint32_t addr) - { - if(resion_check(addr)) { - is_exists[addr - start_addr] = false; - return true; - } - return true; - } - void clear_all() - { - if(end_addr < start_addr) return; - uint32_t _size = end_addr - start_addr + 1; - memset(cache_data, 0x00, _size * sizeof(uint8_t)); - for(uint32\t i = 0; i < _size; i++) { - is_exists[i] = false; - } - } - void change_access_mode(int new_mode) - { - int old_mode = access_type; - if((old_mode & 3) == (new_mode & 3)) return; - if((old_mode & CACHE_LINE_READ) != (new_mode & CACHE_LINE_READ)) { // Discard cache. - clear_all(); - } - access_type = new_mode; - } - inline uint32_t read_data8w(uint32_t addr, int* wait) - { - if((access_type & CACHE_LINE_READ) == 0) { - is_exists[addr - start_addr] = false; - return d_device->read_data8w(addr, wait); - } - if(cache_hit(addr)) { - if(wait != nullptr) *wait = 0; - return (uint32_t)(cache_data[addr - start_addr]); - } - - if(region_check(addr)) { - if(d_device != NULL) { - uint32_t data = d_device->read_data8w(addr, wait); - cache_data[addr - start_addr] = (uint8_t)data; - is_exists[addr - start_addr] = true; - return data; - } else { - cache_data[addr - start_addr] = (uint8_t)0xff; - is_exists[addr - start_addr] = false; - return 0xff; - } - } - return 0xff; - } - // ToDo: endian - uint32_t read_data16w(uint32_t addr, int* wait) - { - pair16_t n; - if((access_type & CACHE_LINE_READ) == 0) { - //is_exists[addr - start_addr] = false; - //is_exists[addr - start_addr + 1] = false; - return d_device->read_data16w(addr, wait); - } - if(cache_hit_range(addr, 2)) { - if(wait != nullptr) *wait = 0; - n.b.l = cache_data[addr - start_addr + 0]; - n.b.h = cache_data[addr - start_addr + 1]; - return (uint32_t)(n.w); - } else { - n.b.l = read_data8w(addr + 0, wait); - n.b.h = read_data8w(addr + 0, wait); - return (uint32_t)(n.w); - } - return 0xffff; - } - uint32_t read_data32w(uint32_t addr, int* wait) - { - pair32_t n; - if((access_type & CACHE_LINE_READ) == 0) { - return d_device->read_data32w(addr, wait); - } - if(cache_hit_range(addr, 4)) { - if(wait != nullptr) *wait = 0; - n.b.l = cache_data[addr - start_addr + 0]; - n.b.h = cache_data[addr - start_addr + 1]; - n.b.h2 = cache_data[addr - start_addr + 2]; - n.b.h3 = cache_data[addr - start_addr + 3]; - return n.d; - } else { - n.b.l = read_data8w(addr + 0, wait); - n.b.h = read_data8w(addr + 1, wait); - n.b.h2 = read_data8w(addr + 2, wait); - n.b.h3 = read_data8w(addr + 3, wait); - return n.d; - } - return 0xffffffff; - } - inline void write_data8w(uint32_t addr, uint32_t data, int* wait) - { - if(region_check(addr)) { - if((access_type & CACHE_TYPE_WRITE) != 0) { - if(d_device != NULL) { - d_device->write_data8w(addr, data, wait); - } else { - if(wait != nullptr) *wait = 0; - data = 0xff; - } - if((access_type & CACHE_LINE_READ) != 0) { - cache_data[addr - start_addr] = (uint8_t)data; - is_exists[addr - start_addr] = true; - } - } else if((access_type & CACHE_TYPE_READ) != 0) { // read Only - if(is_exists[addr - start_addr]) return; - if(d_device != NULL) { - cache_data[addr - start_addr] = d_device->read_data8w(addr, wait); - } else { - if(wait != nullptr) *wait = 0; - cache_data[addr - start_addr] = 0xff; - } - is_exists[addr - start_addr] = true; - } - } - } - void write_data16w(uint32_t addr, uint32_t data, int* wait) - { - pair16_t n; - bool bh, bl; - n.w = data & 0x0000ffff; - if(wait != nullptr) *wait = 0; - write_data8w(addr + 0, (uint32_t)(n.b.l), wait); - write_data8w(addr + 1, (uint32_t)(n.b.h), wait); - } - void write_data32w(uint32_t addr, uint32_t data, int* wait) - { - pair32_t n; - bool bl, bh, bh2, bh3; - n.d = data; - if(wait != nullptr) *wait = 0; - write_data8w(addr + 0, (uint32_t)(n.b.l), wait); - write_data8w(addr + 1, (uint32_t)(n.b.h), wait); - write_data8w(addr + 2, (uint32_t)(n.b.h2), wait); - write_data8w(addr + 3, (uint32_t)(n.b.h3), wait); - } - void set_context_device(DEVIVE* dev) - { - d_device = dev; - } -}; diff --git a/source/src/vm/libcpu_newdev/softfloat/000_artane.txt b/source/src/vm/libcpu_newdev/softfloat/000_artane.txt deleted file mode 100644 index c501f8c5a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/000_artane.txt +++ /dev/null @@ -1 +0,0 @@ -This source code from 3rdparty/softfloat, MAME 0.208. \ No newline at end of file diff --git a/source/src/vm/libcpu_newdev/softfloat/README.txt b/source/src/vm/libcpu_newdev/softfloat/README.txt deleted file mode 100644 index 9500d25e8..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/README.txt +++ /dev/null @@ -1,78 +0,0 @@ -MAME note: this package is derived from the following original SoftFloat -package and has been "re-packaged" to work with MAME's conventions and -build system. The source files come from bits64/ and bits64/templates -in the original distribution as MAME requires a compiler with a 64-bit -integer type. - - -Package Overview for SoftFloat Release 2b - -John R. Hauser -2002 May 27 - - ----------------------------------------------------------------------------- -Overview - -SoftFloat is a software implementation of floating-point that conforms to -the IEC/IEEE Standard for Binary Floating-Point Arithmetic. SoftFloat is -distributed in the form of C source code. Compiling the SoftFloat sources -generates two things: - --- A SoftFloat object file (typically `softfloat.o') containing the complete - set of IEC/IEEE floating-point routines. - --- A `timesoftfloat' program for evaluating the speed of the SoftFloat - routines. (The SoftFloat module is linked into this program.) - -The SoftFloat package is documented in four text files: - - SoftFloat.txt Documentation for using the SoftFloat functions. - SoftFloat-source.txt Documentation for compiling SoftFloat. - SoftFloat-history.txt History of major changes to SoftFloat. - timesoftfloat.txt Documentation for using `timesoftfloat'. - -Other files in the package comprise the source code for SoftFloat. - -Please be aware that some work is involved in porting this software to other -targets. It is not just a matter of getting `make' to complete without -error messages. I would have written the code that way if I could, but -there are fundamental differences between systems that can't be hidden. -You should not attempt to compile SoftFloat without first reading both -`SoftFloat.txt' and `SoftFloat-source.txt'. - - ----------------------------------------------------------------------------- -Legal Notice - -SoftFloat was written by me, John R. Hauser. This work was made possible in -part by the International Computer Science Institute, located at Suite 600, -1947 Center Street, Berkeley, California 94704. Funding was partially -provided by the National Science Foundation under grant MIP-9311980. The -original version of this code was written as part of a project to build -a fixed-point vector processor in collaboration with the University of -California at Berkeley, overseen by Profs. Nelson Morgan and John Wawrzynek. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort -has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT -TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO -PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL -LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO -FURTHERMORE EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER -SCIENCE INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, -COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE -SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, provided -that the minimal documentation requirements stated in the source code are -satisfied. - - ----------------------------------------------------------------------------- -Contact Information - -At the time of this writing, the most up-to-date information about -SoftFloat and the latest release can be found at the Web page `http:// -www.cs.berkeley.edu/~jhauser/arithmetic/SoftFloat.html'. - - diff --git a/source/src/vm/libcpu_newdev/softfloat/fpu_constant.h b/source/src/vm/libcpu_newdev/softfloat/fpu_constant.h deleted file mode 100644 index fdd9719eb..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/fpu_constant.h +++ /dev/null @@ -1,80 +0,0 @@ -/*============================================================================ -This source file is an extension to the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator) -floating point emulation. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -#ifndef _FPU_CONSTANTS_H_ -#define _FPU_CONSTANTS_H_ - -// Pentium CPU uses only 68-bit precision M_PI approximation -#define BETTER_THAN_PENTIUM - -/*============================================================================ - * Written for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -////////////////////////////// -// PI, PI/2, PI/4 constants -////////////////////////////// - -#define FLOATX80_PI_EXP (0x4000) - -// 128-bit PI fraction -#ifdef BETTER_THAN_PENTIUM -#define FLOAT_PI_HI (0xc90fdaa22168c234U) -#define FLOAT_PI_LO (0xc4c6628b80dc1cd1U) -#else -#define FLOAT_PI_HI (0xc90fdaa22168c234U) -#define FLOAT_PI_LO (0xC000000000000000U) -#endif - -#define FLOATX80_PI2_EXP (0x3FFF) -#define FLOATX80_PI4_EXP (0x3FFE) - -////////////////////////////// -// 3PI/4 constant -////////////////////////////// - -#define FLOATX80_3PI4_EXP (0x4000) - -// 128-bit 3PI/4 fraction -#ifdef BETTER_THAN_PENTIUM -#define FLOAT_3PI4_HI (0x96cbe3f9990e91a7U) -#define FLOAT_3PI4_LO (0x9394c9e8a0a5159cU) -#else -#define FLOAT_3PI4_HI (0x96cbe3f9990e91a7U) -#define FLOAT_3PI4_LO (0x9000000000000000U) -#endif - -////////////////////////////// -// 1/LN2 constant -////////////////////////////// - -#define FLOAT_LN2INV_EXP (0x3FFF) - -// 128-bit 1/LN2 fraction -#ifdef BETTER_THAN_PENTIUM -#define FLOAT_LN2INV_HI (0xb8aa3b295c17f0bbU) -#define FLOAT_LN2INV_LO (0xbe87fed0691d3e89U) -#else -#define FLOAT_LN2INV_HI (0xb8aa3b295c17f0bbU) -#define FLOAT_LN2INV_LO (0xC000000000000000U) -#endif - -#endif diff --git a/source/src/vm/libcpu_newdev/softfloat/fsincos.c b/source/src/vm/libcpu_newdev/softfloat/fsincos.c deleted file mode 100644 index a57b9ccbf..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/fsincos.c +++ /dev/null @@ -1,645 +0,0 @@ -/*============================================================================ -This source file is an extension to the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator) -floating point emulation. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Written for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * ==========================================================================*/ - -#define FLOAT128 - -#define USE_estimateDiv128To64 -#include "mamesf.h" -#include "softfloat.h" -//#include "softfloat-specialize" -#include "fpu_constant.h" - -static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, 0x8000000000000000U); -static const floatx80 floatx80_default_nan = packFloatx80(0, 0xffff, 0xffffffffffffffffU); - -#define packFloat2x128m(zHi, zLo) {(zHi), (zLo)} -#define PACK_FLOAT_128(hi,lo) packFloat2x128m(LIT64(hi),LIT64(lo)) - -#define EXP_BIAS 0x3FFF - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -INLINE bits64 extractFloatx80Frac( floatx80 a ) -{ - return a.low; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -INLINE int32 extractFloatx80Exp( floatx80 a ) -{ - return a.high & 0x7FFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the extended double-precision floating-point value -| `a'. -*----------------------------------------------------------------------------*/ - -INLINE flag extractFloatx80Sign( floatx80 a ) -{ - return a.high>>15; - -} - -/*---------------------------------------------------------------------------- -| Takes extended double-precision floating-point NaN `a' and returns the -| appropriate NaN result. If `a' is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ - -INLINE floatx80 propagateFloatx80NaNOneArg(floatx80 a) -{ - if (floatx80_is_signaling_nan(a)) - float_raise(float_flag_invalid); - - a.low |= 0xC000000000000000U; - - return a; -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal extended double-precision floating-point value -| represented by the denormalized significand `aSig'. The normalized exponent -| and significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr) -{ - int shiftCount = countLeadingZeros64(aSig); - *zSigPtr = aSig< 0) { - q = argument_reduction_kernel(aSig0, expDiff, &aSig0, &aSig1); - } - else { - if (FLOAT_PI_HI <= aSig0) { - aSig0 -= FLOAT_PI_HI; - q = 1; - } - } - - shift128Right(FLOAT_PI_HI, FLOAT_PI_LO, 1, &term0, &term1); - if (! lt128(aSig0, aSig1, term0, term1)) - { - int lt = lt128(term0, term1, aSig0, aSig1); - int eq = eq128(aSig0, aSig1, term0, term1); - - if ((eq && (q & 1)) || lt) { - zSign = !zSign; - ++q; - } - if (lt) sub128(FLOAT_PI_HI, FLOAT_PI_LO, aSig0, aSig1, &aSig0, &aSig1); - } - - return (int)(q & 3); -} - -#define SIN_ARR_SIZE 11 -#define COS_ARR_SIZE 11 - -static float128 sin_arr[SIN_ARR_SIZE] = -{ - PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */ - PACK_FLOAT_128(0xbffc555555555555, 0x5555555555555555), /* 3 */ - PACK_FLOAT_128(0x3ff8111111111111, 0x1111111111111111), /* 5 */ - PACK_FLOAT_128(0xbff2a01a01a01a01, 0xa01a01a01a01a01a), /* 7 */ - PACK_FLOAT_128(0x3fec71de3a556c73, 0x38faac1c88e50017), /* 9 */ - PACK_FLOAT_128(0xbfe5ae64567f544e, 0x38fe747e4b837dc7), /* 11 */ - PACK_FLOAT_128(0x3fde6124613a86d0, 0x97ca38331d23af68), /* 13 */ - PACK_FLOAT_128(0xbfd6ae7f3e733b81, 0xf11d8656b0ee8cb0), /* 15 */ - PACK_FLOAT_128(0x3fce952c77030ad4, 0xa6b2605197771b00), /* 17 */ - PACK_FLOAT_128(0xbfc62f49b4681415, 0x724ca1ec3b7b9675), /* 19 */ - PACK_FLOAT_128(0x3fbd71b8ef6dcf57, 0x18bef146fcee6e45) /* 21 */ -}; - -static float128 cos_arr[COS_ARR_SIZE] = -{ - PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 0 */ - PACK_FLOAT_128(0xbffe000000000000, 0x0000000000000000), /* 2 */ - PACK_FLOAT_128(0x3ffa555555555555, 0x5555555555555555), /* 4 */ - PACK_FLOAT_128(0xbff56c16c16c16c1, 0x6c16c16c16c16c17), /* 6 */ - PACK_FLOAT_128(0x3fefa01a01a01a01, 0xa01a01a01a01a01a), /* 8 */ - PACK_FLOAT_128(0xbfe927e4fb7789f5, 0xc72ef016d3ea6679), /* 10 */ - PACK_FLOAT_128(0x3fe21eed8eff8d89, 0x7b544da987acfe85), /* 12 */ - PACK_FLOAT_128(0xbfda93974a8c07c9, 0xd20badf145dfa3e5), /* 14 */ - PACK_FLOAT_128(0x3fd2ae7f3e733b81, 0xf11d8656b0ee8cb0), /* 16 */ - PACK_FLOAT_128(0xbfca6827863b97d9, 0x77bb004886a2c2ab), /* 18 */ - PACK_FLOAT_128(0x3fc1e542ba402022, 0x507a9cad2bf8f0bb) /* 20 */ -}; - -extern float128 OddPoly (float128 x, float128 *arr, unsigned n); - -/* 0 <= x <= pi/4 */ -INLINE float128 poly_sin(float128 x) -{ - // 3 5 7 9 11 13 15 - // x x x x x x x - // sin (x) ~ x - --- + --- - --- + --- - ---- + ---- - ---- = - // 3! 5! 7! 9! 11! 13! 15! - // - // 2 4 6 8 10 12 14 - // x x x x x x x - // = x * [ 1 - --- + --- - --- + --- - ---- + ---- - ---- ] = - // 3! 5! 7! 9! 11! 13! 15! - // - // 3 3 - // -- 4k -- 4k+2 - // p(x) = > C * x > 0 q(x) = > C * x < 0 - // -- 2k -- 2k+1 - // k=0 k=0 - // - // 2 - // sin(x) ~ x * [ p(x) + x * q(x) ] - // - - return OddPoly(x, sin_arr, SIN_ARR_SIZE); -} - -extern float128 EvenPoly(float128 x, float128 *arr, unsigned n); - -/* 0 <= x <= pi/4 */ -INLINE float128 poly_cos(float128 x) -{ - // 2 4 6 8 10 12 14 - // x x x x x x x - // cos (x) ~ 1 - --- + --- - --- + --- - ---- + ---- - ---- - // 2! 4! 6! 8! 10! 12! 14! - // - // 3 3 - // -- 4k -- 4k+2 - // p(x) = > C * x > 0 q(x) = > C * x < 0 - // -- 2k -- 2k+1 - // k=0 k=0 - // - // 2 - // cos(x) ~ [ p(x) + x * q(x) ] - // - - return EvenPoly(x, cos_arr, COS_ARR_SIZE); -} - -INLINE void sincos_invalid(floatx80 *sin_a, floatx80 *cos_a, floatx80 a) -{ - if (sin_a) *sin_a = a; - if (cos_a) *cos_a = a; -} - -INLINE void sincos_tiny_argument(floatx80 *sin_a, floatx80 *cos_a, floatx80 a) -{ - if (sin_a) *sin_a = a; - if (cos_a) *cos_a = floatx80_one; -} - -static floatx80 sincos_approximation(int neg, float128 r, uint64_t quotient) -{ - if (quotient & 0x1) { - r = poly_cos(r); - neg = 0; - } else { - r = poly_sin(r); - } - - floatx80 result = float128_to_floatx80(r); - if (quotient & 0x2) - neg = ! neg; - - if (neg) - result = floatx80_chs(result); - - return result; -} - -// ================================================= -// SFFSINCOS Compute sin(x) and cos(x) -// ================================================= - -// -// Uses the following identities: -// ---------------------------------------------------------- -// -// sin(-x) = -sin(x) -// cos(-x) = cos(x) -// -// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y) -// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y) -// -// sin(x+ pi/2) = cos(x) -// sin(x+ pi) = -sin(x) -// sin(x+3pi/2) = -cos(x) -// sin(x+2pi) = sin(x) -// - -int sf_fsincos(floatx80 a, floatx80 *sin_a, floatx80 *cos_a) -{ - uint64_t aSig0, aSig1 = 0; - int32_t aExp, zExp, expDiff; - int aSign, zSign; - int q = 0; - - aSig0 = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - /* invalid argument */ - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig0<<1)) { - sincos_invalid(sin_a, cos_a, propagateFloatx80NaNOneArg(a)); - return 0; - } - - float_raise(float_flag_invalid); - sincos_invalid(sin_a, cos_a, floatx80_default_nan); - return 0; - } - - if (aExp == 0) { - if (aSig0 == 0) { - sincos_tiny_argument(sin_a, cos_a, a); - return 0; - } - -// float_raise(float_flag_denormal); - - /* handle pseudo denormals */ - if (! (aSig0 & 0x8000000000000000U)) - { - float_raise(float_flag_inexact); - if (sin_a) - float_raise(float_flag_underflow); - sincos_tiny_argument(sin_a, cos_a, a); - return 0; - } - - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); - } - - zSign = aSign; - zExp = EXP_BIAS; - expDiff = aExp - zExp; - - /* argument is out-of-range */ - if (expDiff >= 63) - return -1; - - float_raise(float_flag_inexact); - - if (expDiff < -1) { // doesn't require reduction - if (expDiff <= -68) { - a = packFloatx80(aSign, aExp, aSig0); - sincos_tiny_argument(sin_a, cos_a, a); - return 0; - } - zExp = aExp; - } - else { - q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1); - } - - /* **************************** */ - /* argument reduction completed */ - /* **************************** */ - - /* using float128 for approximation */ - float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1); - - if (aSign) q = -q; - if (sin_a) *sin_a = sincos_approximation(zSign, r, q); - if (cos_a) *cos_a = sincos_approximation(zSign, r, q+1); - - return 0; -} - -int floatx80_fsin(floatx80 &a) -{ - return sf_fsincos(a, &a, 0); -} - -int floatx80_fcos(floatx80 &a) -{ - return sf_fsincos(a, 0, &a); -} - -// ================================================= -// FPTAN Compute tan(x) -// ================================================= - -// -// Uses the following identities: -// -// 1. ---------------------------------------------------------- -// -// sin(-x) = -sin(x) -// cos(-x) = cos(x) -// -// sin(x+y) = sin(x)*cos(y)+cos(x)*sin(y) -// cos(x+y) = sin(x)*sin(y)+cos(x)*cos(y) -// -// sin(x+ pi/2) = cos(x) -// sin(x+ pi) = -sin(x) -// sin(x+3pi/2) = -cos(x) -// sin(x+2pi) = sin(x) -// -// 2. ---------------------------------------------------------- -// -// sin(x) -// tan(x) = ------ -// cos(x) -// - -int floatx80_ftan(floatx80 &a) -{ - uint64_t aSig0, aSig1 = 0; - int32_t aExp, zExp, expDiff; - int aSign, zSign; - int q = 0; - - aSig0 = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - - /* invalid argument */ - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig0<<1)) - { - a = propagateFloatx80NaNOneArg(a); - return 0; - } - - float_raise(float_flag_invalid); - a = floatx80_default_nan; - return 0; - } - - if (aExp == 0) { - if (aSig0 == 0) return 0; -// float_raise(float_flag_denormal); - /* handle pseudo denormals */ - if (! (aSig0 & 0x8000000000000000U)) - { - float_raise(float_flag_inexact | float_flag_underflow); - return 0; - } - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); - } - - zSign = aSign; - zExp = EXP_BIAS; - expDiff = aExp - zExp; - - /* argument is out-of-range */ - if (expDiff >= 63) - return -1; - - float_raise(float_flag_inexact); - - if (expDiff < -1) { // doesn't require reduction - if (expDiff <= -68) { - a = packFloatx80(aSign, aExp, aSig0); - return 0; - } - zExp = aExp; - } - else { - q = reduce_trig_arg(expDiff, zSign, aSig0, aSig1); - } - - /* **************************** */ - /* argument reduction completed */ - /* **************************** */ - - /* using float128 for approximation */ - float128 r = normalizeRoundAndPackFloat128(0, zExp-0x10, aSig0, aSig1); - - float128 sin_r = poly_sin(r); - float128 cos_r = poly_cos(r); - - if (q & 0x1) { - r = float128_div(cos_r, sin_r); - zSign = ! zSign; - } else { - r = float128_div(sin_r, cos_r); - } - - a = float128_to_floatx80(r); - if (zSign) - a = floatx80_chs(a); - - return 0; -} - -// 2 3 4 n -// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x) -// 0 1 2 3 4 n -// -// -- 2k -- 2k+1 -// p(x) = > C * x q(x) = > C * x -// -- 2k -- 2k+1 -// -// f(x) ~ [ p(x) + x * q(x) ] -// - -float128 EvalPoly(float128 x, float128 *arr, unsigned n) -{ - float128 x2 = float128_mul(x, x); - unsigned i; - - assert(n > 1); - - float128 r1 = arr[--n]; - i = n; - while(i >= 2) { - r1 = float128_mul(r1, x2); - i -= 2; - r1 = float128_add(r1, arr[i]); - } - if (i) r1 = float128_mul(r1, x); - - float128 r2 = arr[--n]; - i = n; - while(i >= 2) { - r2 = float128_mul(r2, x2); - i -= 2; - r2 = float128_add(r2, arr[i]); - } - if (i) r2 = float128_mul(r2, x); - - return float128_add(r1, r2); -} - -// 2 4 6 8 2n -// f(x) ~ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x) -// 0 1 2 3 4 n -// -// -- 4k -- 4k+2 -// p(x) = > C * x q(x) = > C * x -// -- 2k -- 2k+1 -// -// 2 -// f(x) ~ [ p(x) + x * q(x) ] -// - -float128 EvenPoly(float128 x, float128 *arr, unsigned n) -{ - return EvalPoly(float128_mul(x, x), arr, n); -} - -// 3 5 7 9 2n+1 -// f(x) ~ (C * x) + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x) -// 0 1 2 3 4 n -// 2 4 6 8 2n -// = x * [ C + (C * x) + (C * x) + (C * x) + (C * x) + ... + (C * x) -// 0 1 2 3 4 n -// -// -- 4k -- 4k+2 -// p(x) = > C * x q(x) = > C * x -// -- 2k -- 2k+1 -// -// 2 -// f(x) ~ x * [ p(x) + x * q(x) ] -// - -float128 OddPoly(float128 x, float128 *arr, unsigned n) -{ - return float128_mul(x, EvenPoly(x, arr, n)); -} - -/*---------------------------------------------------------------------------- -| Scales extended double-precision floating-point value in operand `a' by -| value `b'. The function truncates the value in the second operand 'b' to -| an integral value and adds that value to the exponent of the operand 'a'. -| The operation performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -extern floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ); - -floatx80 floatx80_scale(floatx80 a, floatx80 b) -{ - sbits32 aExp, bExp; - bits64 aSig, bSig; - - // handle unsupported extended double-precision floating encodings -/* if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) - { - float_raise(float_flag_invalid); - return floatx80_default_nan; - }*/ - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - int bSign = extractFloatx80Sign(b); - - if (aExp == 0x7FFF) { - if ((bits64) (aSig<<1) || ((bExp == 0x7FFF) && (bits64) (bSig<<1))) - { - return propagateFloatx80NaN(a, b); - } - if ((bExp == 0x7FFF) && bSign) { - float_raise(float_flag_invalid); - return floatx80_default_nan; - } - if (bSig && (bExp == 0)) float_raise(float_flag_denormal); - return a; - } - if (bExp == 0x7FFF) { - if ((bits64) (bSig<<1)) return propagateFloatx80NaN(a, b); - if ((aExp | aSig) == 0) { - if (! bSign) { - float_raise(float_flag_invalid); - return floatx80_default_nan; - } - return a; - } - if (aSig && (aExp == 0)) float_raise(float_flag_denormal); - if (bSign) return packFloatx80(aSign, 0, 0); - return packFloatx80(aSign, 0x7FFF, 0x8000000000000000U); - } - if (aExp == 0) { - if (aSig == 0) return a; - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) return a; - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - - if (bExp > 0x400E) { - /* generate appropriate overflow/underflow */ - return roundAndPackFloatx80(80, aSign, - bSign ? -0x3FFF : 0x7FFF, aSig, 0); - } - if (bExp < 0x3FFF) return a; - - int shiftCount = 0x403E - bExp; - bSig >>= shiftCount; - sbits32 scale = bSig; - if (bSign) scale = -scale; /* -32768..32767 */ - return - roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0); -} diff --git a/source/src/vm/libcpu_newdev/softfloat/fyl2x.c b/source/src/vm/libcpu_newdev/softfloat/fyl2x.c deleted file mode 100644 index 44c3e7610..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/fyl2x.c +++ /dev/null @@ -1,486 +0,0 @@ -/*============================================================================ -This source file is an extension to the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b, written for Bochs (x86 achitecture simulator) -floating point emulation. -float_raise(float_flag_invalid) -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. -=============================================================================*/ - -/*============================================================================ - * Written for Bochs (x86 achitecture simulator) by - * Stanislav Shwartsman [sshwarts at sourceforge net] - * Adapted for lib/softfloat in MESS by Hans Ostermeyer (03/2012) - * ==========================================================================*/ - -#define FLOAT128 - -#define USE_estimateDiv128To64 -#include "mamesf.h" -#include "softfloat.h" -//#include "softfloat-specialize" -#include "fpu_constant.h" - -static const floatx80 floatx80_log10_2 = packFloatx80(0, 0x3ffd, 0x9a209a84fbcff798U); -static const floatx80 floatx80_ln_2 = packFloatx80(0, 0x3ffe, 0xb17217f7d1cf79acU); -static const floatx80 floatx80_one = packFloatx80(0, 0x3fff, 0x8000000000000000U); -static const floatx80 floatx80_default_nan = packFloatx80(0, 0xffff, 0xffffffffffffffffU); - -#define packFloat_128(zHi, zLo) {(zHi), (zLo)} -#define PACK_FLOAT_128(hi,lo) packFloat_128(LIT64(hi),LIT64(lo)) - -#define EXP_BIAS 0x3FFF - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -INLINE bits64 extractFloatx80Frac( floatx80 a ) -{ - return a.low; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -INLINE int32 extractFloatx80Exp( floatx80 a ) -{ - return a.high & 0x7FFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the extended double-precision floating-point value -| `a'. -*----------------------------------------------------------------------------*/ - -INLINE flag extractFloatx80Sign( floatx80 a ) -{ - return a.high>>15; - -} - -#if 0 -/*---------------------------------------------------------------------------- -| Takes extended double-precision floating-point NaN `a' and returns the -| appropriate NaN result. If `a' is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ - -INLINE floatx80 propagateFloatx80NaNOneArg(floatx80 a) -{ - if (floatx80_is_signaling_nan(a)) - float_raise(float_flag_invalid); - - a.low |= 0xC000000000000000U; - - return a; -} -#endif - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal extended double-precision floating-point value -| represented by the denormalized significand `aSig'. The normalized exponent -| and significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -INLINE void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr, uint64_t *zSigPtr) -{ - int shiftCount = countLeadingZeros64(aSig); - *zSigPtr = aSig< C * u q(u) = > C * u - // -- 2k -- 2k+1 - // k=0 k=0 - // - // 1+u 2 - // 1/2 ln --- ~ u * [ p(u) + u * q(u) ] - // 1-u - // -*/ - return OddPoly(x1, ln_arr, L2_ARR_SIZE); -} - -/* required sqrt(2)/2 < x < sqrt(2) */ -static float128 poly_l2(float128 x) -{ - /* using float128 for approximation */ - float128 x_p1 = float128_add(x, float128_one); - float128 x_m1 = float128_sub(x, float128_one); - x = float128_div(x_m1, x_p1); - x = poly_ln(x); - x = float128_mul(x, float128_ln2inv2); - return x; -} - -static float128 poly_l2p1(float128 x) -{ - /* using float128 for approximation */ - float128 x_p2 = float128_add(x, float128_two); - x = float128_div(x, x_p2); - x = poly_ln(x); - x = float128_mul(x, float128_ln2inv2); - return x; -} - -// ================================================= -// FYL2X Compute y * log (x) -// 2 -// ================================================= - -// -// Uses the following identities: -// -// 1. ---------------------------------------------------------- -// ln(x) -// log (x) = -------, ln (x*y) = ln(x) + ln(y) -// 2 ln(2) -// -// 2. ---------------------------------------------------------- -// 1+u x-1 -// ln (x) = ln -----, when u = ----- -// 1-u x+1 -// -// 3. ---------------------------------------------------------- -// 3 5 7 2n+1 -// 1+u u u u u -// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ] -// 1-u 3 5 7 2n+1 -// - -static floatx80 fyl2x(floatx80 a, floatx80 b) -{ - uint64_t aSig = extractFloatx80Frac(a); - int32_t aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - uint64_t bSig = extractFloatx80Frac(b); - int32_t bExp = extractFloatx80Exp(b); - int bSign = extractFloatx80Sign(b); - - int zSign = bSign ^ 1; - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1) - || ((bExp == 0x7FFF) && (uint64_t) (bSig<<1))) - { - return propagateFloatx80NaN(a, b); - } - if (aSign) - { -invalid: - float_raise(float_flag_invalid); - return floatx80_default_nan; - } - else { - if (bExp == 0) { - if (bSig == 0) goto invalid; - float_raise(float_flag_denormal); - } - return packFloatx80(bSign, 0x7FFF, 0x8000000000000000U); - } - } - if (bExp == 0x7FFF) - { - if ((uint64_t) (bSig<<1)) return propagateFloatx80NaN(a, b); - if (aSign && (uint64_t)(aExp | aSig)) goto invalid; - if (aSig && (aExp == 0)) - float_raise(float_flag_denormal); - if (aExp < 0x3FFF) { - return packFloatx80(zSign, 0x7FFF, 0x8000000000000000U); - } - if (aExp == 0x3FFF && ((uint64_t) (aSig<<1) == 0)) goto invalid; - return packFloatx80(bSign, 0x7FFF, 0x8000000000000000U); - } - if (aExp == 0) { - if (aSig == 0) { - if ((bExp | bSig) == 0) goto invalid; - float_raise(float_flag_divbyzero); - return packFloatx80(zSign, 0x7FFF, 0x8000000000000000U); - } - if (aSign) goto invalid; - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (aSign) goto invalid; - if (bExp == 0) { - if (bSig == 0) { - if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0); - return packFloatx80(bSign, 0, 0); - } - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - if (aExp == 0x3FFF && ((uint64_t) (aSig<<1) == 0)) - return packFloatx80(bSign, 0, 0); - - float_raise(float_flag_inexact); - - int ExpDiff = aExp - 0x3FFF; - aExp = 0; - if (aSig >= SQRT2_HALF_SIG) { - ExpDiff++; - aExp--; - } - - /* ******************************** */ - /* using float128 for approximation */ - /* ******************************** */ - - uint64_t zSig0, zSig1; - shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); - float128 x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1); - x = poly_l2(x); - x = float128_add(x, int64_to_float128((int64_t) ExpDiff)); - return floatx80_mul(b, float128_to_floatx80(x)); -} - -// ================================================= -// FYL2XP1 Compute y * log (x + 1) -// 2 -// ================================================= - -// -// Uses the following identities: -// -// 1. ---------------------------------------------------------- -// ln(x) -// log (x) = ------- -// 2 ln(2) -// -// 2. ---------------------------------------------------------- -// 1+u x -// ln (x+1) = ln -----, when u = ----- -// 1-u x+2 -// -// 3. ---------------------------------------------------------- -// 3 5 7 2n+1 -// 1+u u u u u -// ln ----- = 2 [ u + --- + --- + --- + ... + ------ + ... ] -// 1-u 3 5 7 2n+1 -// - -floatx80 fyl2xp1(floatx80 a, floatx80 b) -{ - int32_t aExp, bExp; - uint64_t aSig, bSig, zSig0, zSig1, zSig2; - int aSign, bSign; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - bSign = extractFloatx80Sign(b); - int zSign = aSign ^ bSign; - - if (aExp == 0x7FFF) { - if ((uint64_t) (aSig<<1) - || ((bExp == 0x7FFF) && (uint64_t) (bSig<<1))) - { - return propagateFloatx80NaN(a, b); - } - if (aSign) - { -invalid: - float_raise(float_flag_invalid); - return floatx80_default_nan; - } - else { - if (bExp == 0) { - if (bSig == 0) goto invalid; - float_raise(float_flag_denormal); - } - return packFloatx80(bSign, 0x7FFF, 0x8000000000000000U); - } - } - if (bExp == 0x7FFF) - { - if ((uint64_t) (bSig<<1)) - return propagateFloatx80NaN(a, b); - - if (aExp == 0) { - if (aSig == 0) goto invalid; - float_raise(float_flag_denormal); - } - - return packFloatx80(zSign, 0x7FFF, 0x8000000000000000U); - } - if (aExp == 0) { - if (aSig == 0) { - if (bSig && (bExp == 0)) float_raise(float_flag_denormal); - return packFloatx80(zSign, 0, 0); - } - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) return packFloatx80(zSign, 0, 0); - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - - float_raise(float_flag_inexact); - - if (aSign && aExp >= 0x3FFF) - return a; - - if (aExp >= 0x3FFC) // big argument - { - return fyl2x(floatx80_add(a, floatx80_one), b); - } - - // handle tiny argument - if (aExp < EXP_BIAS-70) - { - // first order approximation, return (a*b)/ln(2) - int32_t zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE; - - mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2); - if (0 < (int64_t) zSig0) { - shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); - --zExp; - } - - zExp = zExp + bExp - 0x3FFE; - mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2); - if (0 < (int64_t) zSig0) { - shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); - --zExp; - } - - return - roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1); - } - - /* ******************************** */ - /* using float128 for approximation */ - /* ******************************** */ - - shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); - float128 x = packFloat128(aSign, aExp, zSig0, zSig1); - x = poly_l2p1(x); - return floatx80_mul(b, float128_to_floatx80(x)); -} - -floatx80 floatx80_flognp1(floatx80 a) -{ - return fyl2xp1(a, floatx80_ln_2); -} - -floatx80 floatx80_flogn(floatx80 a) -{ - return fyl2x(a, floatx80_ln_2); -} - -floatx80 floatx80_flog2(floatx80 a) -{ - return fyl2x(a, floatx80_one); -} - -floatx80 floatx80_flog10(floatx80 a) -{ - return fyl2x(a, floatx80_log10_2); -} diff --git a/source/src/vm/libcpu_newdev/softfloat/mamesf.h b/source/src/vm/libcpu_newdev/softfloat/mamesf.h deleted file mode 100644 index 437f54834..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/mamesf.h +++ /dev/null @@ -1,67 +0,0 @@ -/*---------------------------------------------------------------------------- -| One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. -*----------------------------------------------------------------------------*/ -#ifdef LSB_FIRST -#define LITTLEENDIAN -#else -#define BIGENDIAN -#endif - -/*---------------------------------------------------------------------------- -| The macro `BITS64' can be defined to indicate that 64-bit integer types are -| supported by the compiler. -*----------------------------------------------------------------------------*/ -#define BITS64 - -/*---------------------------------------------------------------------------- -| Each of the following `typedef's defines the most convenient type that holds -| integers of at least as many bits as specified. For example, `uint8' should -| be the most convenient type that can hold unsigned integers of as many as -| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most -| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed -| to the same as `int'. -*----------------------------------------------------------------------------*/ -#include "assert.h" -#include "osdcomm.h" - -typedef int8_t flag; -typedef uint8_t uint8; -typedef int8_t int8; -typedef uint16_t uint16; -typedef int16_t int16; -typedef uint32_t uint32; -typedef int32_t int32; -typedef uint64_t uint64; -typedef int64_t int64; - -/*---------------------------------------------------------------------------- -| Each of the following `typedef's defines a type that holds integers -| of _exactly_ the number of bits specified. For instance, for most -| implementation of C, `bits16' and `sbits16' should be `typedef'ed to -| `unsigned short int' and `signed short int' (or `short int'), respectively. -*----------------------------------------------------------------------------*/ -typedef uint8_t bits8; -typedef int8_t sbits8; -typedef uint16_t bits16; -typedef int16_t sbits16; -typedef uint32_t bits32; -typedef int32_t sbits32; -typedef uint64_t bits64; -typedef int64_t sbits64; - -/*---------------------------------------------------------------------------- -| The `LIT64' macro takes as its argument a textual integer literal and -| if necessary ``marks'' the literal as having a 64-bit integer type. -| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be -| appended with the letters `LL' standing for `long long', which is `gcc's -| name for the 64-bit integer type. Some compilers may allow `LIT64' to be -| defined as the identity macro: `#define LIT64( a ) a'. -*----------------------------------------------------------------------------*/ -#define LIT64( a ) a##ULL - -/*---------------------------------------------------------------------------- -| The macro `INLINE' can be used before functions that should be inlined. If -| a compiler does not support explicit inlining, this macro should be defined -| to be `static'. -*----------------------------------------------------------------------------*/ -#define INLINE static inline diff --git a/source/src/vm/libcpu_newdev/softfloat/milieu.h b/source/src/vm/libcpu_newdev/softfloat/milieu.h deleted file mode 100644 index 10687b755..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/milieu.h +++ /dev/null @@ -1,42 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| Include common integer types and flags. -*----------------------------------------------------------------------------*/ -#include "mamesf.h" - -/*---------------------------------------------------------------------------- -| Symbolic Boolean literals. -*----------------------------------------------------------------------------*/ -#define FALSE 0 -#define TRUE 1 diff --git a/source/src/vm/libcpu_newdev/softfloat/softfloat-macros b/source/src/vm/libcpu_newdev/softfloat/softfloat-macros deleted file mode 100644 index f58a30472..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/softfloat-macros +++ /dev/null @@ -1,732 +0,0 @@ - -/*============================================================================ - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 32, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -| The result is stored in the location pointed to by `zPtr'. -*----------------------------------------------------------------------------*/ - -INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) -{ - bits32 z; - - if ( count == 0 ) { - z = a; - } - else if ( count < 32 ) { - z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); - } - else { - z = ( a != 0 ); - } - *zPtr = z; - -} - -/*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 64, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -| The result is stored in the location pointed to by `zPtr'. -*----------------------------------------------------------------------------*/ - -INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) -{ - bits64 z; - - if ( count == 0 ) { - z = a; - } - else if ( count < 64 ) { - z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); - } - else { - z = ( a != 0 ); - } - *zPtr = z; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 -| _plus_ the number of bits given in `count'. The shifted result is at most -| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The -| bits shifted off form a second 64-bit result as follows: The _last_ bit -| shifted off is the most-significant bit of the extra result, and the other -| 63 bits of the extra result are all zero if and only if _all_but_the_last_ -| bits shifted off were all zero. This extra result is stored in the location -| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. -| (This routine makes more sense if `a0' and `a1' are considered to form -| a fixed-point value with binary point between `a0' and `a1'. This fixed- -| point value is shifted right by the number of bits given in `count', and -| the integer part of the result is returned at the location pointed to by -| `z0Ptr'. The fractional part of the result may be slightly corrupted as -| described above, and is returned at the location pointed to by `z1Ptr'.) -*----------------------------------------------------------------------------*/ - -INLINE void - shift64ExtraRightJamming( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z0, z1; - int8 negCount = ( - count ) & 63; - - if ( count == 0 ) { - z1 = a1; - z0 = a0; - } - else if ( count < 64 ) { - z1 = ( a0<>count; - } - else { - if ( count == 64 ) { - z1 = a0 | ( a1 != 0 ); - } - else { - z1 = ( ( a0 | a1 ) != 0 ); - } - z0 = 0; - } - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. Any bits shifted off are lost. The value -| of `count' can be arbitrarily large; in particular, if `count' is greater -| than 128, the result will be 0. The result is broken into two 64-bit pieces -| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - shift128Right( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z0, z1; - int8 negCount = ( - count ) & 63; - - if ( count == 0 ) { - z1 = a1; - z0 = a0; - } - else if ( count < 64 ) { - z1 = ( a0<>count ); - z0 = a0>>count; - } - else { - z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0; - z0 = 0; - } - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. If any nonzero bits are shifted off, they -| are ``jammed'' into the least significant bit of the result by setting the -| least significant bit to 1. The value of `count' can be arbitrarily large; -| in particular, if `count' is greater than 128, the result will be either -| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or -| nonzero. The result is broken into two 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - shift128RightJamming( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z0, z1; - int8 negCount = ( - count ) & 63; - - if ( count == 0 ) { - z1 = a1; - z0 = a0; - } - else if ( count < 64 ) { - z1 = ( a0<>count ) | ( ( a1<>count; - } - else { - if ( count == 64 ) { - z1 = a0 | ( a1 != 0 ); - } - else if ( count < 128 ) { - z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<>count ); - z0 = a0>>count; - } - else { - if ( count == 64 ) { - z2 = a1; - z1 = a0; - } - else { - a2 |= a1; - if ( count < 128 ) { - z2 = a0<>( count & 63 ); - } - else { - z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); - z1 = 0; - } - } - z0 = 0; - } - z2 |= ( a2 != 0 ); - } - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the -| number of bits given in `count'. Any bits shifted off are lost. The value -| of `count' must be less than 64. The result is broken into two 64-bit -| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - shortShift128Left( - bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - - *z1Ptr = a1<>( ( - count ) & 63 ) ); - -} - -/*---------------------------------------------------------------------------- -| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left -| by the number of bits given in `count'. Any bits shifted off are lost. -| The value of `count' must be less than 64. The result is broken into three -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', -| `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - shortShift192Left( - bits64 a0, - bits64 a1, - bits64 a2, - int16 count, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2; - int8 negCount; - - z2 = a2<>negCount; - z0 |= a1>>negCount; - } - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit -| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so -| any carry out is lost. The result is broken into two 64-bit pieces which -| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - add128( - bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits64 z1; - - z1 = a1 + b1; - *z1Ptr = z1; - *z0Ptr = a0 + b0 + ( z1 < a1 ); - -} - -/*---------------------------------------------------------------------------- -| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the -| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is -| modulo 2^192, so any carry out is lost. The result is broken into three -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', -| `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - add192( - bits64 a0, - bits64 a1, - bits64 a2, - bits64 b0, - bits64 b1, - bits64 b2, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2; - uint8 carry0, carry1; - - z2 = a2 + b2; - carry1 = ( z2 < a2 ); - z1 = a1 + b1; - carry0 = ( z1 < a1 ); - z0 = a0 + b0; - z1 += carry1; - z0 += ( z1 < carry1 ); - z0 += carry0; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the -| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo -| 2^128, so any borrow out (carry out) is lost. The result is broken into two -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and -| `z1Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - sub128( - bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - - *z1Ptr = a1 - b1; - *z0Ptr = a0 - b0 - ( a1 < b1 ); - -} - -/*---------------------------------------------------------------------------- -| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' -| from the 192-bit value formed by concatenating `a0', `a1', and `a2'. -| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The -| result is broken into three 64-bit pieces which are stored at the locations -| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - sub192( - bits64 a0, - bits64 a1, - bits64 a2, - bits64 b0, - bits64 b1, - bits64 b2, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2; - uint8 borrow0, borrow1; - - z2 = a2 - b2; - borrow1 = ( a2 < b2 ); - z1 = a1 - b1; - borrow0 = ( a1 < b1 ); - z0 = a0 - b0; - z0 -= ( z1 < borrow1 ); - z1 -= borrow1; - z0 -= borrow0; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken -| into two 64-bit pieces which are stored at the locations pointed to by -| `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) -{ - bits32 aHigh, aLow, bHigh, bLow; - bits64 z0, zMiddleA, zMiddleB, z1; - - aLow = a; - aHigh = a>>32; - bLow = b; - bHigh = b>>32; - z1 = ( (bits64) aLow ) * bLow; - zMiddleA = ( (bits64) aLow ) * bHigh; - zMiddleB = ( (bits64) aHigh ) * bLow; - z0 = ( (bits64) aHigh ) * bHigh; - zMiddleA += zMiddleB; - z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); - zMiddleA <<= 32; - z1 += zMiddleA; - z0 += ( z1 < zMiddleA ); - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by -| `b' to obtain a 192-bit product. The product is broken into three 64-bit -| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and -| `z2Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - mul128By64To192( - bits64 a0, - bits64 a1, - bits64 b, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr - ) -{ - bits64 z0, z1, z2, more1; - - mul64To128( a1, b, &z1, &z2 ); - mul64To128( a0, b, &z0, &more1 ); - add128( z0, more1, 0, z1, &z0, &z1 ); - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the -| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit -| product. The product is broken into four 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. -*----------------------------------------------------------------------------*/ - -INLINE void - mul128To256( - bits64 a0, - bits64 a1, - bits64 b0, - bits64 b1, - bits64 *z0Ptr, - bits64 *z1Ptr, - bits64 *z2Ptr, - bits64 *z3Ptr - ) -{ - bits64 z0, z1, z2, z3; - bits64 more1, more2; - - mul64To128( a1, b1, &z2, &z3 ); - mul64To128( a1, b0, &z1, &more2 ); - add128( z1, more2, 0, z2, &z1, &z2 ); - mul64To128( a0, b0, &z0, &more1 ); - add128( z0, more1, 0, z1, &z0, &z1 ); - mul64To128( a0, b1, &more1, &more2 ); - add128( more1, more2, 0, z2, &more1, &z2 ); - add128( z0, z1, 0, more1, &z0, &z1 ); - *z3Ptr = z3; - *z2Ptr = z2; - *z1Ptr = z1; - *z0Ptr = z0; - -} - -/*---------------------------------------------------------------------------- -| Returns an approximation to the 64-bit integer quotient obtained by dividing -| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The -| divisor `b' must be at least 2^63. If q is the exact quotient truncated -| toward zero, the approximation returned lies between q and q + 2 inclusive. -| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit -| unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -INLINE bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) -{ - bits64 b0, b1; - bits64 rem0, rem1, term0, term1; - bits64 z; - - if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); - b0 = b>>32; - z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; - mul64To128( b, z, &term0, &term1 ); - sub128( a0, a1, term0, term1, &rem0, &rem1 ); - while ( ( (sbits64) rem0 ) < 0 ) { - z -= LIT64( 0x100000000 ); - b1 = b<<32; - add128( rem0, rem1, b0, b1, &rem0, &rem1 ); - } - rem0 = ( rem0<<32 ) | ( rem1>>32 ); - z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns an approximation to the square root of the 32-bit significand given -| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of -| `aExp' (the least significant bit) is 1, the integer returned approximates -| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' -| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either -| case, the approximation returned lies strictly within +/-2 of the exact -| value. -*----------------------------------------------------------------------------*/ - -INLINE bits32 estimateSqrt32( int16 aExp, bits32 a ) -{ - static const bits16 sqrtOddAdjustments[] = { - 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, - 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 - }; - static const bits16 sqrtEvenAdjustments[] = { - 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, - 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 - }; - int8 index; - bits32 z; - - index = ( a>>27 ) & 15; - if ( aExp & 1 ) { - z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; - z = ( ( a / z )<<14 ) + ( z<<15 ); - a >>= 1; - } - else { - z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; - z = a / z + z; - z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); - if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); - } - return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 32 is returned. -*----------------------------------------------------------------------------*/ - -static int8 countLeadingZeros32( bits32 a ) -{ - static const int8 countLeadingZerosHigh[] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - int8 shiftCount; - - shiftCount = 0; - if ( a < 0x10000 ) { - shiftCount += 16; - a <<= 16; - } - if ( a < 0x1000000 ) { - shiftCount += 8; - a <<= 8; - } - shiftCount += countLeadingZerosHigh[ a>>24 ]; - return shiftCount; - -} - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 64 is returned. -*----------------------------------------------------------------------------*/ - -static int8 countLeadingZeros64( bits64 a ) -{ - int8 shiftCount; - - shiftCount = 0; - if ( a < ( (bits64) 1 )<<32 ) { - shiftCount += 32; - } - else { - a >>= 32; - } - shiftCount += countLeadingZeros32( a ); - return shiftCount; - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' -| is equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 == b0 ) && ( a1 == b1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less -| than or equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less -| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, -| returns 0. -*----------------------------------------------------------------------------*/ - -INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is -| not equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) -{ - - return ( a0 != b0 ) || ( a1 != b1 ); - -} - -/*----------------------------------------------------------------------------- -| Changes the sign of the extended double-precision floating-point value 'a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -INLINE floatx80 floatx80_chs(floatx80 reg) -{ - reg.high ^= 0x8000; - return reg; -} - diff --git a/source/src/vm/libcpu_newdev/softfloat/softfloat-specialize b/source/src/vm/libcpu_newdev/softfloat/softfloat-specialize deleted file mode 100644 index 9865c9dda..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/softfloat-specialize +++ /dev/null @@ -1,470 +0,0 @@ - -/*============================================================================ - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| Underflow tininess-detection mode, statically initialized to default value. -| (The declaration in `softfloat.h' must match the `int8' type here.) -*----------------------------------------------------------------------------*/ -int8 float_detect_tininess = float_tininess_after_rounding; - -/*---------------------------------------------------------------------------- -| Raises the exceptions specified by `flags'. Floating-point traps can be -| defined here if desired. It is currently not possible for such a trap to -| substitute a result value. If traps are not implemented, this routine -| should be simply `float_exception_flags |= flags;'. -*----------------------------------------------------------------------------*/ - -void float_raise( int8 flags ) -{ - - float_exception_flags |= flags; - -} - -/*---------------------------------------------------------------------------- -| Internal canonical NaN format. -*----------------------------------------------------------------------------*/ -typedef struct { - flag sign; - bits64 high, low; -} commonNaNT; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -#define float32_default_nan 0xFFFFFFFF - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float32_is_nan( float32 a ) -{ - - return ( 0xFF000000 < (bits32) ( a<<1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a signaling -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float32_is_signaling_nan( float32 a ) -{ - - return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float32ToCommonNaN( float32 a ) -{ - commonNaNT z; - - if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a>>31; - z.low = 0; - z.high = ( (bits64) a )<<41; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the single- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float32 commonNaNToFloat32( commonNaNT a ) -{ - - return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); - -} - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float32 propagateFloat32NaN( float32 a, float32 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float32_is_nan( a ); - aIsSignalingNaN = float32_is_signaling_nan( a ); - bIsNaN = float32_is_nan( b ); - bIsSignalingNaN = float32_is_signaling_nan( b ); - a |= 0x00400000; - b |= 0x00400000; - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float64_is_nan( float64 a ) -{ - - return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a signaling -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float64_is_signaling_nan( float64 a ) -{ - - return - ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) - && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float64ToCommonNaN( float64 a ) -{ - commonNaNT z; - - if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a>>63; - z.low = 0; - z.high = a<<12; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the double- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float64 commonNaNToFloat64( commonNaNT a ) -{ - - return - ( ( (bits64) a.sign )<<63 ) - | LIT64( 0x7FF8000000000000 ) - | ( a.high>>12 ); - -} - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float64 propagateFloat64NaN( float64 a, float64 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float64_is_nan( a ); - aIsSignalingNaN = float64_is_signaling_nan( a ); - bIsNaN = float64_is_nan( b ); - bIsSignalingNaN = float64_is_signaling_nan( b ); - a |= LIT64( 0x0008000000000000 ); - b |= LIT64( 0x0008000000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. The -| `high' and `low' values hold the most- and least-significant bits, -| respectively. -*----------------------------------------------------------------------------*/ -#define floatx80_default_nan_high 0xFFFF -#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag floatx80_is_nan( floatx80 a ) -{ - - return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| signaling NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag floatx80_is_signaling_nan( floatx80 a ) -{ - bits64 aLow; - - aLow = a.low & ~ LIT64( 0x4000000000000000 ); - return - ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (bits64) ( aLow<<1 ) - && ( a.low == aLow ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT floatx80ToCommonNaN( floatx80 a ) -{ - commonNaNT z; - - if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a.high>>15; - z.low = 0; - z.high = a.low<<1; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the extended -| double-precision floating-point format. -*----------------------------------------------------------------------------*/ - -static floatx80 commonNaNToFloatx80( commonNaNT a ) -{ - floatx80 z; - - z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); - z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes two extended double-precision floating-point values `a' and `b', one -| of which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = floatx80_is_nan( a ); - aIsSignalingNaN = floatx80_is_signaling_nan( a ); - bIsNaN = floatx80_is_nan( b ); - bIsSignalingNaN = floatx80_is_signaling_nan( b ); - a.low |= LIT64( 0xC000000000000000 ); - b.low |= LIT64( 0xC000000000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -#define EXP_BIAS 0x3FFF - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -INLINE bits64 extractFloatx80Frac( floatx80 a ) -{ - - return a.low; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the extended double-precision floating-point -| value `a'. -*----------------------------------------------------------------------------*/ - -INLINE int32 extractFloatx80Exp( floatx80 a ) -{ - - return a.high & 0x7FFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the extended double-precision floating-point value -| `a'. -*----------------------------------------------------------------------------*/ - -INLINE flag extractFloatx80Sign( floatx80 a ) -{ - - return a.high>>15; - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. The `high' and -| `low' values hold the most- and least-significant bits, respectively. -*----------------------------------------------------------------------------*/ -#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) -#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; -| otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float128_is_nan( float128 a ) -{ - - return - ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) - && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a -| signaling NaN; otherwise returns 0. -*----------------------------------------------------------------------------*/ - -flag float128_is_signaling_nan( float128 a ) -{ - - return - ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) - && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float128ToCommonNaN( float128 a ) -{ - commonNaNT z; - - if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a.high>>63; - shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the quadruple- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float128 commonNaNToFloat128( commonNaNT a ) -{ - float128 z; - - shift128Right( a.high, a.low, 16, &z.high, &z.low ); - z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes two quadruple-precision floating-point values `a' and `b', one of -| which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float128 propagateFloat128NaN( float128 a, float128 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float128_is_nan( a ); - aIsSignalingNaN = float128_is_signaling_nan( a ); - bIsNaN = float128_is_nan( b ); - bIsSignalingNaN = float128_is_signaling_nan( b ); - a.high |= LIT64( 0x0000800000000000 ); - b.high |= LIT64( 0x0000800000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsNaN ) { - return ( aIsSignalingNaN & bIsNaN ) ? b : a; - } - else { - return b; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat/softfloat.c b/source/src/vm/libcpu_newdev/softfloat/softfloat.c deleted file mode 100644 index edd4def33..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/softfloat.c +++ /dev/null @@ -1,4941 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#include "milieu.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Floating-point rounding mode, extended double-precision rounding precision, -| and exception flags. -*----------------------------------------------------------------------------*/ -int8 float_exception_flags = 0; -#ifdef FLOATX80 -int8 floatx80_rounding_precision = 80; -#endif - -int8 float_rounding_mode = float_round_nearest_even; - -/*---------------------------------------------------------------------------- -| Functions and definitions to determine: (1) whether tininess for underflow -| is detected before or after rounding by default, (2) what (if anything) -| happens when exceptions are raised, (3) how signaling NaNs are distinguished -| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs -| are propagated from function inputs to output. These details are target- -| specific. -*----------------------------------------------------------------------------*/ -#include "softfloat-specialize" - -/*---------------------------------------------------------------------------- -| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 -| and 7, and returns the properly rounded 32-bit integer corresponding to the -| input. If `zSign' is 1, the input is negated before being converted to an -| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input -| is simply rounded to an integer, with the inexact exception raised if the -| input cannot be represented exactly as an integer. However, if the fixed- -| point input is too large, the invalid exception is raised and the largest -| positive or negative integer is returned. -*----------------------------------------------------------------------------*/ - -static int32 roundAndPackInt32( flag zSign, bits64 absZ ) -{ - int8 roundingMode; - flag roundNearestEven; - int8 roundIncrement, roundBits; - int32 z; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - roundIncrement = 0x40; - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - roundIncrement = 0; - } - else { - roundIncrement = 0x7F; - if ( zSign ) { - if ( roundingMode == float_round_up ) roundIncrement = 0; - } - else { - if ( roundingMode == float_round_down ) roundIncrement = 0; - } - } - } - roundBits = absZ & 0x7F; - absZ = ( absZ + roundIncrement )>>7; - absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); - z = absZ; - if ( zSign ) z = - z; - if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { - float_raise( float_flag_invalid ); - return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( roundBits ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit integer corresponding to the input. -| If `zSign' is 1, the input is negated before being converted to an integer. -| Ordinarily, the fixed-point input is simply rounded to an integer, with -| the inexact exception raised if the input cannot be represented exactly as -| an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the largest positive or negative integer is -| returned. -*----------------------------------------------------------------------------*/ - -static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) -{ - int8 roundingMode; - flag roundNearestEven, increment; - int64 z; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) absZ1 < 0 ); - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - increment = 0; - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && absZ1; - } - else { - increment = ( roundingMode == float_round_up ) && absZ1; - } - } - } - if ( increment ) { - ++absZ0; - if ( absZ0 == 0 ) goto overflow; - absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); - } - z = absZ0; - if ( zSign ) z = - z; - if ( z && ( ( z < 0 ) ^ zSign ) ) { - overflow: - float_raise( float_flag_invalid ); - return - zSign ? (sbits64) LIT64( 0x8000000000000000 ) - : LIT64( 0x7FFFFFFFFFFFFFFF ); - } - if ( absZ1 ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -INLINE bits32 extractFloat32Frac( float32 a ) -{ - return a & 0x007FFFFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -INLINE int16 extractFloat32Exp( float32 a ) -{ - return ( a>>23 ) & 0xFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -INLINE flag extractFloat32Sign( float32 a ) -{ - return a>>31; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal single-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros32( aSig ) - 8; - *zSigPtr = aSig<>7; - zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); - if ( zSig == 0 ) zExp = 0; - return packFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -static float32 - normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros32( zSig ) - 1; - return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>52 ) & 0x7FF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -INLINE flag extractFloat64Sign( float64 a ) -{ - return a>>63; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal double-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros64( aSig ) - 11; - *zSigPtr = aSig<>10; - zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); - if ( zSig == 0 ) zExp = 0; - return packFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ - -static float64 - normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) -{ - int8 shiftCount; - - shiftCount = countLeadingZeros64( zSig ) - 1; - return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<>48 ) & 0x7FFF; - -} - -/*---------------------------------------------------------------------------- -| Returns the sign bit of the quadruple-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ - -INLINE flag extractFloat128Sign( float128 a ) -{ - return a.high>>63; - -} - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal quadruple-precision floating-point value -| represented by the denormalized significand formed by the concatenation of -| `aSig0' and `aSig1'. The normalized exponent is stored at the location -| pointed to by `zExpPtr'. The most significant 49 bits of the normalized -| significand are stored at the location pointed to by `zSig0Ptr', and the -| least significant 64 bits of the normalized significand are stored at the -| location pointed to by `zSig1Ptr'. -*----------------------------------------------------------------------------*/ - -static void - normalizeFloat128Subnormal( - bits64 aSig0, - bits64 aSig1, - int32 *zExpPtr, - bits64 *zSig0Ptr, - bits64 *zSig1Ptr - ) -{ - int8 shiftCount; - - if ( aSig0 == 0 ) { - shiftCount = countLeadingZeros64( aSig1 ) - 15; - if ( shiftCount < 0 ) { - *zSig0Ptr = aSig1>>( - shiftCount ); - *zSig1Ptr = aSig1<<( shiftCount & 63 ); - } - else { - *zSig0Ptr = aSig1<>( - shiftCount ); - if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int64 float32_to_int64( float32 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64, aSigExtra; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = 0xBE - aExp; - if ( shiftCount < 0 ) { - float_raise( float_flag_invalid ); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - return (sbits64) LIT64( 0x8000000000000000 ); - } - if ( aExp ) aSig |= 0x00800000; - aSig64 = aSig; - aSig64 <<= 40; - shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); - return roundAndPackInt64( aSign, aSig64, aSigExtra ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the 64-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int64 float32_to_int64_round_to_zero( float32 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits32 aSig; - bits64 aSig64; - int64 z; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - shiftCount = aExp - 0xBE; - if ( 0 <= shiftCount ) { - if ( a != 0xDF000000 ) { - float_raise( float_flag_invalid ); - if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { - return LIT64( 0x7FFFFFFFFFFFFFFF ); - } - } - return (sbits64) LIT64( 0x8000000000000000 ); - } - else if ( aExp <= 0x7E ) { - if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig64 = aSig | 0x00800000; - aSig64 <<= 40; - z = aSig64>>( - shiftCount ); - if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the double-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float32_to_float64( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); - return packFloat64( aSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float32_to_floatx80( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - aSig |= 0x00800000; - return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point value -| `a' to the double-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float32_to_float128( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 aSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) ); - return packFloat128( aSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the single-precision floating-point value `a' to an integer, and -| returns the result as a single-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_round_to_int( float32 a ) -{ - flag aSign; - int16 aExp; - bits32 lastBitMask, roundBitsMask; - int8 roundingMode; - float32 z; - - aExp = extractFloat32Exp( a ); - if ( 0x96 <= aExp ) { - if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { - return propagateFloat32NaN( a, a ); - } - return a; - } - if ( aExp <= 0x7E ) { - if ( (bits32) ( a<<1 ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat32Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { - return packFloat32( aSign, 0x7F, 0 ); - } - break; - case float_round_down: - return aSign ? 0xBF800000 : 0; - case float_round_up: - return aSign ? 0x80000000 : 0x3F800000; - } - return packFloat32( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x96 - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z += lastBitMask>>1; - if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z += roundBitsMask; - } - } - z &= ~ roundBitsMask; - if ( z != a ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the single-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 6; - bSig <<= 6; - if ( 0 < expDiff ) { - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x20000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x20000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0xFF ) { - if ( aSig | bSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); - zSig = 0x40000000 + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= 0x20000000; - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (sbits32) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the single- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - expDiff = aExp - bExp; - aSig <<= 7; - bSig <<= 7; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0xFF ) { - if ( aSig | bSig ) return propagateFloat32NaN( a, b ); - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign ^ 1, 0xFF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= 0x40000000; - } - shift32RightJamming( aSig, - expDiff, &aSig ); - bSig |= 0x40000000; - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= 0x40000000; - } - shift32RightJamming( bSig, expDiff, &bSig ); - aSig |= 0x40000000; - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the single-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_add( float32 a, float32 b ) -{ - flag aSign, bSign; - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return addFloat32Sigs( a, b, aSign ); - } - else { - return subFloat32Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sub( float32 a, float32 b ) -{ - flag aSign, bSign; - - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign == bSign ) { - return subFloat32Sigs( a, b, aSign ); - } - else { - return addFloat32Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the single-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_mul( float32 a, float32 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits32 aSig, bSig; - bits64 zSig64; - bits32 zSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x7F; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); - zSig = zSig64; - if ( 0 <= (sbits32) ( zSig<<1 ) ) { - zSig <<= 1; - --zExp; - } - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the single-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_div( float32 a, float32 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits32 aSig, bSig, zSig; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); - bSign = extractFloat32Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, b ); - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - float_raise( float_flag_invalid ); - return float32_default_nan; - } - return packFloat32( zSign, 0xFF, 0 ); - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return packFloat32( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - float_raise( float_flag_divbyzero ); - return packFloat32( zSign, 0xFF, 0 ); - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x7D; - aSig = ( aSig | 0x00800000 )<<7; - bSig = ( bSig | 0x00800000 )<<8; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = ( ( (bits64) aSig )<<32 ) / bSig; - if ( ( zSig & 0x3F ) == 0 ) { - zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); - } - return roundAndPackFloat32( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the single-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_rem( float32 a, float32 b ) -{ - flag aSign, zSign; - int16 aExp, bExp, expDiff; - bits32 aSig, bSig; - bits32 q; - bits64 aSig64, bSig64, q64; - bits32 alternateASig; - sbits32 sigMean; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - bSig = extractFloat32Frac( b ); - bExp = extractFloat32Exp( b ); -// bSign = extractFloat32Sign( b ); - if ( aExp == 0xFF ) { - if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { - return propagateFloat32NaN( a, b ); - } - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( bExp == 0xFF ) { - if ( bSig ) return propagateFloat32NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise( float_flag_invalid ); - return float32_default_nan; - } - normalizeFloat32Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig |= 0x00800000; - bSig |= 0x00800000; - if ( expDiff < 32 ) { - aSig <<= 8; - bSig <<= 8; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - if ( 0 < expDiff ) { - q = ( ( (bits64) aSig )<<32 ) / bSig; - q >>= 32 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - } - else { - if ( bSig <= aSig ) aSig -= bSig; - aSig64 = ( (bits64) aSig )<<40; - bSig64 = ( (bits64) bSig )<<40; - expDiff -= 64; - while ( 0 < expDiff ) { - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - aSig64 = - ( ( bSig * q64 )<<38 ); - expDiff -= 62; - } - expDiff += 64; - q64 = estimateDiv128To64( aSig64, 0, bSig64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - q = q64>>( 64 - expDiff ); - bSig <<= 6; - aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (sbits32) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (sbits32) aSig < 0 ); - if ( zSign ) aSig = - aSig; - return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the single-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float32_sqrt( float32 a ) -{ - flag aSign; - int16 aExp, zExp; - bits32 aSig, zSig; - bits64 rem, term; - - aSig = extractFloat32Frac( a ); - aExp = extractFloat32Exp( a ); - aSign = extractFloat32Sign( a ); - if ( aExp == 0xFF ) { - if ( aSig ) return propagateFloat32NaN( a, 0 ); - if ( ! aSign ) return a; - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise( float_flag_invalid ); - return float32_default_nan; - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return 0; - normalizeFloat32Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; - aSig = ( aSig | 0x00800000 )<<8; - zSig = estimateSqrt32( aExp, aSig ) + 2; - if ( ( zSig & 0x7F ) <= 5 ) { - if ( zSig < 2 ) { - zSig = 0x7FFFFFFF; - goto roundAndPack; - } - aSig >>= aExp & 1; - term = ( (bits64) zSig ) * zSig; - rem = ( ( (bits64) aSig )<<32 ) - term; - while ( (sbits64) rem < 0 ) { - --zSig; - rem += ( ( (bits64) zSig )<<1 ) | 1; - } - zSig |= ( rem != 0 ); - } - shift32RightJamming( zSig, 1, &zSig ); - roundAndPack: - return roundAndPackFloat32( 0, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_eq( float32 a, float32 b ) -{ - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_le( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_lt( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_eq_signaling( float32 a, float32 b ) -{ - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_le_quiet( float32 a, float32 b ) -{ - flag aSign, bSign; -// int16 aExp, bExp; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float32_lt_quiet( float32 a, float32 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) - || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) - ) { - if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat32Sign( a ); - bSign = extractFloat32Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 float64_to_int32( float64 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits64 aSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x42C - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32( aSign, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the 32-bit two's complement integer format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. -| If `a' is a NaN, the largest positive integer is returned. Otherwise, if -| the conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32 float64_to_int32_round_to_zero( float64 a ) -{ - flag aSign; - int16 aExp, shiftCount; - bits64 aSig, savedASig; - int32 z; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( 0x41E < aExp ) { - if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FF ) { - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig |= LIT64( 0x0010000000000000 ); - shiftCount = 0x433 - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the single-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float64_to_float32( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig; - bits32 zSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 22, &aSig ); - zSig = aSig; - if ( aExp || zSig ) { - zSig |= 0x40000000; - aExp -= 0x381; - } - return roundAndPackFloat32( aSign, aExp, zSig ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the extended double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float64_to_floatx80( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - return - packFloatx80( - aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point value -| `a' to the quadruple-precision floating-point format. The conversion is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float64_to_float128( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig, zSig0, zSig1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) ); - return packFloat128( aSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - --aExp; - } - shift128Right( aSig, 0, 4, &zSig0, &zSig1 ); - return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the double-precision floating-point value `a' to an integer, and -| returns the result as a double-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_round_to_int( float64 a ) -{ - flag aSign; - int16 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - float64 z; - - aExp = extractFloat64Exp( a ); - if ( 0x433 <= aExp ) { - if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { - return propagateFloat64NaN( a, a ); - } - return a; - } - if ( aExp < 0x3FF ) { - if ( (bits64) ( a<<1 ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat64Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { - return packFloat64( aSign, 0x3FF, 0 ); - } - break; - case float_round_down: - return aSign ? LIT64( 0xBFF0000000000000 ) : 0; - case float_round_up: - return - aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); - } - return packFloat64( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x433 - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z += lastBitMask>>1; - if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z += roundBitsMask; - } - } - z &= ~ roundBitsMask; - if ( z != a ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 9; - bSig <<= 9; - if ( 0 < expDiff ) { - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x2000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - zExp = bExp; - } - else { - if ( aExp == 0x7FF ) { - if ( aSig | bSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); - zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; - zExp = aExp; - goto roundAndPack; - } - aSig |= LIT64( 0x2000000000000000 ); - zSig = ( aSig + bSig )<<1; - --zExp; - if ( (sbits64) zSig < 0 ) { - zSig = aSig + bSig; - ++zExp; - } - roundAndPack: - return roundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) -{ - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - int16 expDiff; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - expDiff = aExp - bExp; - aSig <<= 10; - bSig <<= 10; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FF ) { - if ( aSig | bSig ) return propagateFloat64NaN( a, b ); - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign ^ 1, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( aSig, - expDiff, &aSig ); - bSig |= LIT64( 0x4000000000000000 ); - bBigger: - zSig = bSig - aSig; - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig |= LIT64( 0x4000000000000000 ); - } - shift64RightJamming( bSig, expDiff, &bSig ); - aSig |= LIT64( 0x4000000000000000 ); - aBigger: - zSig = aSig - bSig; - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the double-precision floating-point values `a' -| and `b'. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_add( float64 a, float64 b ) -{ - flag aSign, bSign; - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return addFloat64Sigs( a, b, aSign ); - } - else { - return subFloat64Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sub( float64 a, float64 b ) -{ - flag aSign, bSign; - - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign == bSign ) { - return subFloat64Sigs( a, b, aSign ); - } - else { - return addFloat64Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the double-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_mul( float64 a, float64 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FF; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - zSig0 |= ( zSig1 != 0 ); - if ( 0 <= (sbits64) ( zSig0<<1 ) ) { - zSig0 <<= 1; - --zExp; - } - return roundAndPackFloat64( zSign, zExp, zSig0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the double-precision floating-point value `a' -| by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_div( float64 a, float64 b ) -{ - flag aSign, bSign, zSign; - int16 aExp, bExp, zExp; - bits64 aSig, bSig, zSig; - bits64 rem0, rem1; - bits64 term0, term1; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); - bSign = extractFloat64Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, b ); - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - float_raise( float_flag_invalid ); - return float64_default_nan; - } - return packFloat64( zSign, 0x7FF, 0 ); - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return packFloat64( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - float_raise( float_flag_divbyzero ); - return packFloat64( zSign, 0x7FF, 0 ); - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FD; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( bSig <= ( aSig + aSig ) ) { - aSig >>= 1; - ++zExp; - } - zSig = estimateDiv128To64( aSig, 0, bSig ); - if ( ( zSig & 0x1FF ) <= 2 ) { - mul64To128( bSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig |= ( rem1 != 0 ); - } - return roundAndPackFloat64( zSign, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the double-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_rem( float64 a, float64 b ) -{ - flag aSign, zSign; - int16 aExp, bExp, expDiff; - bits64 aSig, bSig; - bits64 q, alternateASig; - sbits64 sigMean; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - bSig = extractFloat64Frac( b ); - bExp = extractFloat64Exp( b ); -// bSign = extractFloat64Sign( b ); - if ( aExp == 0x7FF ) { - if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { - return propagateFloat64NaN( a, b ); - } - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( bExp == 0x7FF ) { - if ( bSig ) return propagateFloat64NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - float_raise( float_flag_invalid ); - return float64_default_nan; - } - normalizeFloat64Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return a; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - expDiff = aExp - bExp; - aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; - bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - aSig >>= 1; - } - q = ( bSig <= aSig ); - if ( q ) aSig -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - aSig = - ( ( bSig>>2 ) * q ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig, 0, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - bSig >>= 2; - aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; - } - else { - aSig >>= 2; - bSig >>= 2; - } - do { - alternateASig = aSig; - ++q; - aSig -= bSig; - } while ( 0 <= (sbits64) aSig ); - sigMean = aSig + alternateASig; - if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { - aSig = alternateASig; - } - zSign = ( (sbits64) aSig < 0 ); - if ( zSign ) aSig = - aSig; - return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the double-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float64_sqrt( float64 a ) -{ - flag aSign; - int16 aExp, zExp; - bits64 aSig, zSig, doubleZSig; - bits64 rem0, rem1, term0, term1; -// float64 z; - - aSig = extractFloat64Frac( a ); - aExp = extractFloat64Exp( a ); - aSign = extractFloat64Sign( a ); - if ( aExp == 0x7FF ) { - if ( aSig ) return propagateFloat64NaN( a, a ); - if ( ! aSign ) return a; - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aSign ) { - if ( ( aExp | aSig ) == 0 ) return a; - float_raise( float_flag_invalid ); - return float64_default_nan; - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return 0; - normalizeFloat64Subnormal( aSig, &aExp, &aSig ); - } - zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; - aSig |= LIT64( 0x0010000000000000 ); - zSig = estimateSqrt32( aExp, aSig>>21 ); - aSig <<= 9 - ( aExp & 1 ); - zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); - if ( ( zSig & 0x1FF ) <= 5 ) { - doubleZSig = zSig<<1; - mul64To128( zSig, zSig, &term0, &term1 ); - sub128( aSig, 0, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig; - doubleZSig -= 2; - add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); - } - zSig |= ( ( rem0 | rem1 ) != 0 ); - } - return roundAndPackFloat64( 0, zExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_eq( float64 a, float64 b ) -{ - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_le( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_lt( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is equal to the -| corresponding value `b', and 0 otherwise. The invalid exception is raised -| if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_eq_signaling( float64 a, float64 b ) -{ - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than or -| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_le_quiet( float64 a, float64 b ) -{ - flag aSign, bSign; -// int16 aExp, bExp; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); - return ( a == b ) || ( aSign ^ ( a < b ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float64_lt_quiet( float64 a, float64 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) - || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) - ) { - if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat64Sign( a ); - bSign = extractFloat64Sign( b ); - if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); - return ( a != b ) && ( aSign ^ ( a < b ) ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic---which means in particular that the conversion -| is rounded according to the current rounding mode. If `a' is a NaN, the -| largest positive integer is returned. Otherwise, if the conversion -| overflows, the largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 floatx80_to_int32( floatx80 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; - shiftCount = 0x4037 - aExp; - if ( shiftCount <= 0 ) shiftCount = 1; - shift64RightJamming( aSig, shiftCount, &aSig ); - return roundAndPackInt32( aSign, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the 32-bit two's complement integer format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic, except that the conversion is always rounded -| toward zero. If `a' is a NaN, the largest positive integer is returned. -| Otherwise, if the conversion overflows, the largest integer with the same -| sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 floatx80_to_int32_round_to_zero( floatx80 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig, savedASig; - int32 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; - return 0; - } - shiftCount = 0x403E - aExp; - savedASig = aSig; - aSig >>= shiftCount; - z = aSig; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig<>( - shiftCount ); - if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { - float_exception_flags |= float_flag_inexact; - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the single-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 floatx80_to_float32( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); - } - return packFloat32( aSign, 0xFF, 0 ); - } - shift64RightJamming( aSig, 33, &aSig ); - if ( aExp || aSig ) aExp -= 0x3F81; - return roundAndPackFloat32( aSign, aExp, aSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 floatx80_to_float64( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig, zSig; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shift64RightJamming( aSig, 1, &zSig ); - if ( aExp || aSig ) aExp -= 0x3C01; - return roundAndPackFloat64( aSign, aExp, zSig ); - -} - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point value `a' to the quadruple-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 floatx80_to_float128( floatx80 a ) -{ - flag aSign; - int16 aExp; - bits64 aSig, zSig0, zSig1; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { - return commonNaNToFloat128( floatx80ToCommonNaN( a ) ); - } - shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); - return packFloat128( aSign, aExp, zSig0, zSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the extended double-precision floating-point value `a' to an integer, -| and returns the result as an extended quadruple-precision floating-point -| value. The operation is performed according to the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_round_to_int( floatx80 a ) -{ - flag aSign; - int32 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - floatx80 z; - - aExp = extractFloatx80Exp( a ); - if ( 0x403E <= aExp ) { - if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { - return propagateFloatx80NaN( a, a ); - } - return a; - } - if ( aExp < 0x3FFF ) { - if ( ( aExp == 0 ) - && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { - return a; - } - float_exception_flags |= float_flag_inexact; - aSign = extractFloatx80Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) - ) { - return - packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); - } - break; - case float_round_down: - return - aSign ? - packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) - : packFloatx80( 0, 0, 0 ); - case float_round_up: - return - aSign ? packFloatx80( 1, 0, 0 ) - : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); - } - return packFloatx80( aSign, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x403E - aExp; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z.low += lastBitMask>>1; - if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { - z.low += roundBitsMask; - } - } - z.low &= ~ roundBitsMask; - if ( z.low == 0 ) { - ++z.high; - z.low = LIT64( 0x8000000000000000 ); - } - if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the extended double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is -| negated before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - int32 expDiff; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) --expDiff; - shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) ++expDiff; - shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN( a, b ); - } - return a; - } - zSig1 = 0; - zSig0 = aSig + bSig; - if ( aExp == 0 ) { - normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); - goto roundAndPack; - } - zExp = aExp; - goto shiftRight1; - } - zSig0 = aSig + bSig; - if ( (sbits64) zSig0 < 0 ) goto roundAndPack; - shiftRight1: - shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= LIT64( 0x8000000000000000 ); - ++zExp; - roundAndPack: - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the extended -| double-precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - int32 expDiff; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( ( aSig | bSig )<<1 ) ) { - return propagateFloatx80NaN( a, b ); - } - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - zSig1 = 0; - if ( bSig < aSig ) goto aBigger; - if ( aSig < bSig ) goto bBigger; - return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) ++expDiff; - shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); - bBigger: - sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) --expDiff; - shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); - aBigger: - sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - return - normalizeRoundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the extended double-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_add( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == bSign ) { - return addFloatx80Sigs( a, b, aSign ); - } - else { - return subFloatx80Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sub( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign == bSign ) { - return subFloatx80Sigs( a, b, aSign ); - } - else { - return addFloatx80Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the extended double-precision floating- -| point values `a' and `b'. The operation is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_mul( floatx80 a, floatx80 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN( a, b ); - } - if ( ( bExp | bSig ) == 0 ) goto invalid; - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - if ( ( aExp | aSig ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - zExp = aExp + bExp - 0x3FFE; - mul64To128( aSig, bSig, &zSig0, &zSig1 ); - if ( 0 < (sbits64) zSig0 ) { - shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); - --zExp; - } - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the extended double-precision floating-point -| value `a' by the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_div( floatx80 a, floatx80 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig, bSig, zSig0, zSig1; - bits64 rem0, rem1, rem2, term0, term1, term2; - floatx80 z; - - aSig = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); - bSign = extractFloatx80Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - goto invalid; - } - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return packFloatx80( zSign, 0, 0 ); - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - if ( ( aExp | aSig ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - float_raise( float_flag_divbyzero ); - return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); - normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); - } - zExp = aExp - bExp + 0x3FFE; - rem1 = 0; - if ( bSig <= aSig ) { - shift128Right( aSig, 0, 1, &aSig, &rem1 ); - ++zExp; - } - zSig0 = estimateDiv128To64( aSig, rem1, bSig ); - mul64To128( bSig, zSig0, &term0, &term1 ); - sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, bSig ); - if ( (bits64) ( zSig1<<1 ) <= 8 ) { - mul64To128( bSig, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); - } - zSig1 |= ( ( rem1 | rem2 ) != 0 ); - } - return - roundAndPackFloatx80( - floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the extended double-precision floating-point value -| `a' with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_rem( floatx80 a, floatx80 b ) -{ - flag aSign, zSign; - int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig; - bits64 q, term0, term1, alternateASig0, alternateASig1; - floatx80 z; - - aSig0 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - bSig = extractFloatx80Frac( b ); - bExp = extractFloatx80Exp( b ); -// bSign = extractFloatx80Sign( b ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) - || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { - return propagateFloatx80NaN( a, b ); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( bSig == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); - } - if ( aExp == 0 ) { - if ( (bits64) ( aSig0<<1 ) == 0 ) return a; - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - bSig |= LIT64( 0x8000000000000000 ); - zSign = aSign; - expDiff = aExp - bExp; - aSig1 = 0; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); - expDiff = 0; - } - q = ( bSig <= aSig0 ); - if ( q ) aSig0 -= bSig; - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - mul64To128( bSig, q, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); - while ( le128( term0, term1, aSig0, aSig1 ) ) { - ++q; - sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); - } - } - else { - term1 = 0; - term0 = bSig; - } - sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); - if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) - || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) - && ( q & 1 ) ) - ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - zSign = ! zSign; - } - return - normalizeRoundAndPackFloatx80( - 80, zSign, bExp + expDiff, aSig0, aSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the extended double-precision floating-point -| value `a'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 floatx80_sqrt( floatx80 a ) -{ - flag aSign; - int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - floatx80 z; - - aSig0 = extractFloatx80Frac( a ); - aExp = extractFloatx80Exp( a ); - aSign = extractFloatx80Sign( a ); - if ( aExp == 0x7FFF ) { - if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 ) == 0 ) return a; - invalid: - float_raise( float_flag_invalid ); - z.low = floatx80_default_nan_low; - z.high = floatx80_default_nan_high; - return z; - } - if ( aExp == 0 ) { - if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); - normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; - zSig0 = estimateSqrt32( aExp, aSig0>>32 ); - shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); - zSig0 |= doubleZSig0; - return - roundAndPackFloatx80( - floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| equal to the corresponding value `b', and 0 otherwise. The comparison is -| performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_eq( floatx80 a, floatx80 b ) -{ - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| less than or equal to the corresponding value `b', and 0 otherwise. The -| comparison is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_le( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is -| less than the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_lt( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is equal -| to the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_eq_signaling( floatx80 a, floatx80 b ) -{ - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is less -| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs -| do not cause an exception. Otherwise, the comparison is performed according -| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_le_quiet( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is less -| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause -| an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag floatx80_lt_quiet( floatx80 a, floatx80 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( a )<<1 ) ) - || ( ( extractFloatx80Exp( b ) == 0x7FFF ) - && (bits64) ( extractFloatx80Frac( b )<<1 ) ) - ) { - if ( floatx80_is_signaling_nan( a ) - || floatx80_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloatx80Sign( a ); - bSign = extractFloatx80Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the 32-bit two's complement integer format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic---which means in particular that the conversion is rounded -| according to the current rounding mode. If `a' is a NaN, the largest -| positive integer is returned. Otherwise, if the conversion overflows, the -| largest integer with the same sign as `a' is returned. -*----------------------------------------------------------------------------*/ - -int32 float128_to_int32( float128 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0; - if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); - aSig0 |= ( aSig1 != 0 ); - shiftCount = 0x4028 - aExp; - if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 ); - return roundAndPackInt32( aSign, aSig0 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the 32-bit two's complement integer format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic, except that the conversion is always rounded toward zero. If -| `a' is a NaN, the largest positive integer is returned. Otherwise, if the -| conversion overflows, the largest integer with the same sign as `a' is -| returned. -*----------------------------------------------------------------------------*/ - -int32 float128_to_int32_round_to_zero( float128 a ) -{ - flag aSign; - int32 aExp, shiftCount; - bits64 aSig0, aSig1, savedASig; - int32 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - aSig0 |= ( aSig1 != 0 ); - if ( 0x401E < aExp ) { - if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0; - goto invalid; - } - else if ( aExp < 0x3FFF ) { - if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact; - return 0; - } - aSig0 |= LIT64( 0x0001000000000000 ); - shiftCount = 0x402F - aExp; - savedASig = aSig0; - aSig0 >>= shiftCount; - z = aSig0; - if ( aSign ) z = - z; - if ( ( z < 0 ) ^ aSign ) { - invalid: - float_raise( float_flag_invalid ); - return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; - } - if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); - if ( (bits64) ( aSig1<>( - shiftCount ); - if ( aSig1 - || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { - float_exception_flags |= float_flag_inexact; - } - } - if ( aSign ) z = - z; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the single-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float32 float128_to_float32( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - bits32 zSig; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloat32( float128ToCommonNaN( a ) ); - } - return packFloat32( aSign, 0xFF, 0 ); - } - aSig0 |= ( aSig1 != 0 ); - shift64RightJamming( aSig0, 18, &aSig0 ); - zSig = aSig0; - if ( aExp || zSig ) { - zSig |= 0x40000000; - aExp -= 0x3F81; - } - return roundAndPackFloat32( aSign, aExp, zSig ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the double-precision floating-point format. The conversion -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -float64 float128_to_float64( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloat64( float128ToCommonNaN( a ) ); - } - return packFloat64( aSign, 0x7FF, 0 ); - } - shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); - aSig0 |= ( aSig1 != 0 ); - if ( aExp || aSig0 ) { - aSig0 |= LIT64( 0x4000000000000000 ); - aExp -= 0x3C01; - } - return roundAndPackFloat64( aSign, aExp, aSig0 ); - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point -| value `a' to the extended double-precision floating-point format. The -| conversion is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -floatx80 float128_to_floatx80( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 aSig0, aSig1; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) { - return commonNaNToFloatx80( float128ToCommonNaN( a ) ); - } - return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - else { - aSig0 |= LIT64( 0x0001000000000000 ); - } - shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); - return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 ); - -} - -#endif - -/*---------------------------------------------------------------------------- -| Rounds the quadruple-precision floating-point value `a' to an integer, and -| returns the result as a quadruple-precision floating-point value. The -| operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_round_to_int( float128 a ) -{ - flag aSign; - int32 aExp; - bits64 lastBitMask, roundBitsMask; - int8 roundingMode; - float128 z; - - aExp = extractFloat128Exp( a ); - if ( 0x402F <= aExp ) { - if ( 0x406F <= aExp ) { - if ( ( aExp == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) - ) { - return propagateFloat128NaN( a, a ); - } - return a; - } - lastBitMask = 1; - lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; - roundBitsMask = lastBitMask - 1; - z = a; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - if ( lastBitMask ) { - add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); - if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; - } - else { - if ( (sbits64) z.low < 0 ) { - ++z.high; - if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; - } - } - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat128Sign( z ) - ^ ( roundingMode == float_round_up ) ) { - add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); - } - } - z.low &= ~ roundBitsMask; - } - else { - if ( aExp < 0x3FFF ) { - if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; - float_exception_flags |= float_flag_inexact; - aSign = extractFloat128Sign( a ); - switch ( float_rounding_mode ) { - case float_round_nearest_even: - if ( ( aExp == 0x3FFE ) - && ( extractFloat128Frac0( a ) - | extractFloat128Frac1( a ) ) - ) { - return packFloat128( aSign, 0x3FFF, 0, 0 ); - } - break; - case float_round_down: - return - aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) - : packFloat128( 0, 0, 0, 0 ); - case float_round_up: - return - aSign ? packFloat128( 1, 0, 0, 0 ) - : packFloat128( 0, 0x3FFF, 0, 0 ); - } - return packFloat128( aSign, 0, 0, 0 ); - } - lastBitMask = 1; - lastBitMask <<= 0x402F - aExp; - roundBitsMask = lastBitMask - 1; - z.low = 0; - z.high = a.high; - roundingMode = float_rounding_mode; - if ( roundingMode == float_round_nearest_even ) { - z.high += lastBitMask>>1; - if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { - z.high &= ~ lastBitMask; - } - } - else if ( roundingMode != float_round_to_zero ) { - if ( extractFloat128Sign( z ) - ^ ( roundingMode == float_round_up ) ) { - z.high |= ( a.low != 0 ); - z.high += roundBitsMask; - } - } - z.high &= ~ roundBitsMask; - } - if ( ( z.low != a.low ) || ( z.high != a.high ) ) { - float_exception_flags |= float_flag_inexact; - } - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the quadruple-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 addFloat128Sigs( float128 a, float128 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - int32 expDiff; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - if ( 0 < expDiff ) { - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= LIT64( 0x0001000000000000 ); - } - shift128ExtraRightJamming( - bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); - zExp = aExp; - } - else if ( expDiff < 0 ) { - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= LIT64( 0x0001000000000000 ); - } - shift128ExtraRightJamming( - aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); - zExp = bExp; - } - else { - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN( a, b ); - } - return a; - } - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); - zSig2 = 0; - zSig0 |= LIT64( 0x0002000000000000 ); - zExp = aExp; - goto shiftRight1; - } - aSig0 |= LIT64( 0x0001000000000000 ); - add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - --zExp; - if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack; - ++zExp; - shiftRight1: - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); - roundAndPack: - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the quadruple- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -static float128 subFloat128Sigs( float128 a, float128 b, flag zSign ) -{ - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; - int32 expDiff; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - expDiff = aExp - bExp; - shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); - shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); - if ( 0 < expDiff ) goto aExpBigger; - if ( expDiff < 0 ) goto bExpBigger; - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 | bSig0 | bSig1 ) { - return propagateFloat128NaN( a, b ); - } - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - if ( aExp == 0 ) { - aExp = 1; - bExp = 1; - } - if ( bSig0 < aSig0 ) goto aBigger; - if ( aSig0 < bSig0 ) goto bBigger; - if ( bSig1 < aSig1 ) goto aBigger; - if ( aSig1 < bSig1 ) goto bBigger; - return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 ); - bExpBigger: - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - ++expDiff; - } - else { - aSig0 |= LIT64( 0x4000000000000000 ); - } - shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - bSig0 |= LIT64( 0x4000000000000000 ); - bBigger: - sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); - zExp = bExp; - zSign ^= 1; - goto normalizeRoundAndPack; - aExpBigger: - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - --expDiff; - } - else { - bSig0 |= LIT64( 0x4000000000000000 ); - } - shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); - aSig0 |= LIT64( 0x4000000000000000 ); - aBigger: - sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); - zExp = aExp; - normalizeRoundAndPack: - --zExp; - return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of adding the quadruple-precision floating-point values -| `a' and `b'. The operation is performed according to the IEC/IEEE Standard -| for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_add( float128 a, float128 b ) -{ - flag aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return addFloat128Sigs( a, b, aSign ); - } - else { - return subFloat128Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sub( float128 a, float128 b ) -{ - flag aSign, bSign; - - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign == bSign ) { - return subFloat128Sigs( a, b, aSign ); - } - else { - return addFloat128Sigs( a, b, aSign ); - } - -} - -/*---------------------------------------------------------------------------- -| Returns the result of multiplying the quadruple-precision floating-point -| values `a' and `b'. The operation is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_mul( float128 a, float128 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - bSign = extractFloat128Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN( a, b ); - } - if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - if ( ( aExp | aSig0 | aSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - zExp = aExp + bExp - 0x4000; - aSig0 |= LIT64( 0x0001000000000000 ); - shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 ); - mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); - add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); - zSig2 |= ( zSig3 != 0 ); - if ( LIT64( 0x0002000000000000 ) <= zSig0 ) { - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); - ++zExp; - } - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of dividing the quadruple-precision floating-point value -| `a' by the corresponding value `b'. The operation is performed according to -| the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_div( float128 a, float128 b ) -{ - flag aSign, bSign, zSign; - int32 aExp, bExp, zExp; - bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); - bSign = extractFloat128Sign( b ); - zSign = aSign ^ bSign; - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - goto invalid; - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return packFloat128( zSign, 0, 0, 0 ); - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) { - if ( ( aExp | aSig0 | aSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - float_raise( float_flag_divbyzero ); - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp = aExp - bExp + 0x3FFD; - shortShift128Left( - aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 ); - shortShift128Left( - bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); - if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) { - shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); - ++zExp; - } - zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); - mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); - sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); - } - zSig1 = estimateDiv128To64( rem1, rem2, bSig0 ); - if ( ( zSig1 & 0x3FFF ) <= 4 ) { - mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); - sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 ); - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the remainder of the quadruple-precision floating-point value `a' -| with respect to the corresponding value `b'. The operation is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_rem( float128 a, float128 b ) -{ - flag aSign, zSign; - int32 aExp, bExp, expDiff; - bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; - bits64 allZero, alternateASig0, alternateASig1, sigMean1; - sbits64 sigMean0; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - bSig1 = extractFloat128Frac1( b ); - bSig0 = extractFloat128Frac0( b ); - bExp = extractFloat128Exp( b ); -// bSign = extractFloat128Sign( b ); - if ( aExp == 0x7FFF ) { - if ( ( aSig0 | aSig1 ) - || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { - return propagateFloat128NaN( a, b ); - } - goto invalid; - } - if ( bExp == 0x7FFF ) { - if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); - return a; - } - if ( bExp == 0 ) { - if ( ( bSig0 | bSig1 ) == 0 ) { - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return a; - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - expDiff = aExp - bExp; - if ( expDiff < -1 ) return a; - shortShift128Left( - aSig0 | LIT64( 0x0001000000000000 ), - aSig1, - 15 - ( expDiff < 0 ), - &aSig0, - &aSig1 - ); - shortShift128Left( - bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); - q = le128( bSig0, bSig1, aSig0, aSig1 ); - if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - expDiff -= 64; - while ( 0 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); - shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); - sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); - expDiff -= 61; - } - if ( -64 < expDiff ) { - q = estimateDiv128To64( aSig0, aSig1, bSig0 ); - q = ( 4 < q ) ? q - 4 : 0; - q >>= - expDiff; - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - expDiff += 52; - if ( expDiff < 0 ) { - shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); - } - else { - shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); - } - mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); - sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); - } - else { - shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); - shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); - } - do { - alternateASig0 = aSig0; - alternateASig1 = aSig1; - ++q; - sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); - } while ( 0 <= (sbits64) aSig0 ); - add128( - aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 ); - if ( ( sigMean0 < 0 ) - || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { - aSig0 = alternateASig0; - aSig1 = alternateASig1; - } - zSign = ( (sbits64) aSig0 < 0 ); - if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); - return - normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns the square root of the quadruple-precision floating-point value `a'. -| The operation is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -float128 float128_sqrt( float128 a ) -{ - flag aSign; - int32 aExp, zExp; - bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; - bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; - float128 z; - - aSig1 = extractFloat128Frac1( a ); - aSig0 = extractFloat128Frac0( a ); - aExp = extractFloat128Exp( a ); - aSign = extractFloat128Sign( a ); - if ( aExp == 0x7FFF ) { - if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a ); - if ( ! aSign ) return a; - goto invalid; - } - if ( aSign ) { - if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; - invalid: - float_raise( float_flag_invalid ); - z.low = float128_default_nan_low; - z.high = float128_default_nan_high; - return z; - } - if ( aExp == 0 ) { - if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); - normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); - } - zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; - aSig0 |= LIT64( 0x0001000000000000 ); - zSig0 = estimateSqrt32( aExp, aSig0>>17 ); - shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); - zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); - doubleZSig0 = zSig0<<1; - mul64To128( zSig0, zSig0, &term0, &term1 ); - sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); - while ( (sbits64) rem0 < 0 ) { - --zSig0; - doubleZSig0 -= 2; - add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); - } - zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); - if ( ( zSig1 & 0x1FFF ) <= 5 ) { - if ( zSig1 == 0 ) zSig1 = 1; - mul64To128( doubleZSig0, zSig1, &term1, &term2 ); - sub128( rem1, 0, term1, term2, &rem1, &rem2 ); - mul64To128( zSig1, zSig1, &term2, &term3 ); - sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); - while ( (sbits64) rem1 < 0 ) { - --zSig1; - shortShift128Left( 0, zSig1, 1, &term2, &term3 ); - term3 |= 1; - term2 |= doubleZSig0; - add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); - } - zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); - } - shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 ); - return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_eq( float128 a, float128 b ) -{ - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. The comparison -| is performed according to the IEC/IEEE Standard for Binary Floating-Point -| Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_le( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. The comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_lt( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is equal to -| the corresponding value `b', and 0 otherwise. The invalid exception is -| raised if either operand is a NaN. Otherwise, the comparison is performed -| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_eq_signaling( float128 a, float128 b ) -{ - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - float_raise( float_flag_invalid ); - return 0; - } - return - ( a.low == b.low ) - && ( ( a.high == b.high ) - || ( ( a.low == 0 ) - && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) - ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not -| cause an exception. Otherwise, the comparison is performed according to the -| IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_le_quiet( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - == 0 ); - } - return - aSign ? le128( b.high, b.low, a.high, a.low ) - : le128( a.high, a.low, b.high, b.low ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is less than -| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an -| exception. Otherwise, the comparison is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -flag float128_lt_quiet( float128 a, float128 b ) -{ - flag aSign, bSign; - - if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) - && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) - || ( ( extractFloat128Exp( b ) == 0x7FFF ) - && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) - ) { - if ( float128_is_signaling_nan( a ) - || float128_is_signaling_nan( b ) ) { - float_raise( float_flag_invalid ); - } - return 0; - } - aSign = extractFloat128Sign( a ); - bSign = extractFloat128Sign( b ); - if ( aSign != bSign ) { - return - aSign - && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) - != 0 ); - } - return - aSign ? lt128( b.high, b.low, a.high, a.low ) - : lt128( a.high, a.low, b.high, b.low ); - -} - -#endif diff --git a/source/src/vm/libcpu_newdev/softfloat/softfloat.h b/source/src/vm/libcpu_newdev/softfloat/softfloat.h deleted file mode 100644 index 6f4389b10..000000000 --- a/source/src/vm/libcpu_newdev/softfloat/softfloat.h +++ /dev/null @@ -1,460 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| The macro `FLOATX80' must be defined to enable the extended double-precision -| floating-point format `floatx80'. If this macro is not defined, the -| `floatx80' type will not be defined, and none of the functions that either -| input or output the `floatx80' type will be defined. The same applies to -| the `FLOAT128' macro and the quadruple-precision format `float128'. -*----------------------------------------------------------------------------*/ -#define FLOATX80 -#define FLOAT128 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point types. -*----------------------------------------------------------------------------*/ -typedef bits32 float32; -typedef bits64 float64; -#ifdef FLOATX80 -typedef struct { - bits16 high; - bits64 low; -} floatx80; -#endif -#ifdef FLOAT128 -typedef struct { - bits64 high, low; -} float128; -#endif - -/*---------------------------------------------------------------------------- -| Primitive arithmetic functions, including multi-word arithmetic, and -| division and square root approximations. (Can be specialized to target if -| desired.) -*----------------------------------------------------------------------------*/ -#include "softfloat-macros" - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point underflow tininess-detection mode. -*----------------------------------------------------------------------------*/ -extern int8 float_detect_tininess; -enum { - float_tininess_after_rounding = 0, - float_tininess_before_rounding = 1 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point rounding mode. -*----------------------------------------------------------------------------*/ -extern int8 float_rounding_mode; -enum { - float_round_nearest_even = 0, - float_round_to_zero = 1, - float_round_down = 2, - float_round_up = 3 -}; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE floating-point exception flags. -*----------------------------------------------------------------------------*/ -extern int8 float_exception_flags; -enum { - float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, - float_flag_underflow = 0x10, float_flag_inexact = 0x20 -}; - -/*---------------------------------------------------------------------------- -| Routine to raise any or all of the software IEC/IEEE floating-point -| exception flags. -*----------------------------------------------------------------------------*/ -void float_raise( int8 ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float32 int32_to_float32( int32 ); -float64 int32_to_float64( int32 ); -#ifdef FLOATX80 -floatx80 int32_to_floatx80( int32 ); -#endif -#ifdef FLOAT128 -float128 int32_to_float128( int32 ); -#endif -float32 int64_to_float32( int64 ); -float64 int64_to_float64( int64 ); -#ifdef FLOATX80 -floatx80 int64_to_floatx80( int64 ); -#endif -#ifdef FLOAT128 -float128 int64_to_float128( int64 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 float32_to_int32( float32 ); -int32 float32_to_int32_round_to_zero( float32 ); -int64 float32_to_int64( float32 ); -int64 float32_to_int64_round_to_zero( float32 ); -float64 float32_to_float64( float32 ); -#ifdef FLOATX80 -floatx80 float32_to_floatx80( float32 ); -#endif -#ifdef FLOAT128 -float128 float32_to_float128( float32 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE single-precision operations. -*----------------------------------------------------------------------------*/ -float32 float32_round_to_int( float32 ); -float32 float32_add( float32, float32 ); -float32 float32_sub( float32, float32 ); -float32 float32_mul( float32, float32 ); -float32 float32_div( float32, float32 ); -float32 float32_rem( float32, float32 ); -float32 float32_sqrt( float32 ); -flag float32_eq( float32, float32 ); -flag float32_le( float32, float32 ); -flag float32_lt( float32, float32 ); -flag float32_eq_signaling( float32, float32 ); -flag float32_le_quiet( float32, float32 ); -flag float32_lt_quiet( float32, float32 ); -flag float32_is_signaling_nan( float32 ); - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 float64_to_int32( float64 ); -int32 float64_to_int32_round_to_zero( float64 ); -int64 float64_to_int64( float64 ); -int64 float64_to_int64_round_to_zero( float64 ); -float32 float64_to_float32( float64 ); -#ifdef FLOATX80 -floatx80 float64_to_floatx80( float64 ); -#endif -#ifdef FLOAT128 -float128 float64_to_float128( float64 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE double-precision operations. -*----------------------------------------------------------------------------*/ -float64 float64_round_to_int( float64 ); -float64 float64_add( float64, float64 ); -float64 float64_sub( float64, float64 ); -float64 float64_mul( float64, float64 ); -float64 float64_div( float64, float64 ); -float64 float64_rem( float64, float64 ); -float64 float64_sqrt( float64 ); -flag float64_eq( float64, float64 ); -flag float64_le( float64, float64 ); -flag float64_lt( float64, float64 ); -flag float64_eq_signaling( float64, float64 ); -flag float64_le_quiet( float64, float64 ); -flag float64_lt_quiet( float64, float64 ); -flag float64_is_signaling_nan( float64 ); - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 floatx80_to_int32( floatx80 ); -int32 floatx80_to_int32_round_to_zero( floatx80 ); -int64 floatx80_to_int64( floatx80 ); -int64 floatx80_to_int64_round_to_zero( floatx80 ); -float32 floatx80_to_float32( floatx80 ); -float64 floatx80_to_float64( floatx80 ); -#ifdef FLOAT128 -float128 floatx80_to_float128( floatx80 ); -#endif -floatx80 floatx80_scale(floatx80 a, floatx80 b); - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an -| extended double-precision floating-point value, returning the result. -*----------------------------------------------------------------------------*/ - -INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) -{ - floatx80 z; - - z.low = zSig; - z.high = ( ( (bits16) zSign )<<15 ) + zExp; - return z; - -} - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision rounding precision. Valid -| values are 32, 64, and 80. -*----------------------------------------------------------------------------*/ -extern int8 floatx80_rounding_precision; - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE extended double-precision operations. -*----------------------------------------------------------------------------*/ -floatx80 floatx80_round_to_int( floatx80 ); -floatx80 floatx80_add( floatx80, floatx80 ); -floatx80 floatx80_sub( floatx80, floatx80 ); -floatx80 floatx80_mul( floatx80, floatx80 ); -floatx80 floatx80_div( floatx80, floatx80 ); -floatx80 floatx80_rem( floatx80, floatx80 ); -floatx80 floatx80_sqrt( floatx80 ); -flag floatx80_eq( floatx80, floatx80 ); -flag floatx80_le( floatx80, floatx80 ); -flag floatx80_lt( floatx80, floatx80 ); -flag floatx80_eq_signaling( floatx80, floatx80 ); -flag floatx80_le_quiet( floatx80, floatx80 ); -flag floatx80_lt_quiet( floatx80, floatx80 ); -flag floatx80_is_signaling_nan( floatx80 ); - -int floatx80_fsin(floatx80 &a); -int floatx80_fcos(floatx80 &a); -int floatx80_ftan(floatx80 &a); - -floatx80 floatx80_flognp1(floatx80 a); -floatx80 floatx80_flogn(floatx80 a); -floatx80 floatx80_flog2(floatx80 a); -floatx80 floatx80_flog10(floatx80 a); - -// roundAndPackFloatx80 used to be in softfloat-round-pack, is now in softfloat.c -floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1); - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision conversion routines. -*----------------------------------------------------------------------------*/ -int32 float128_to_int32( float128 ); -int32 float128_to_int32_round_to_zero( float128 ); -int64 float128_to_int64( float128 ); -int64 float128_to_int64_round_to_zero( float128 ); -float32 float128_to_float32( float128 ); -float64 float128_to_float64( float128 ); -#ifdef FLOATX80 -floatx80 float128_to_floatx80( float128 ); -#endif - -/*---------------------------------------------------------------------------- -| Software IEC/IEEE quadruple-precision operations. -*----------------------------------------------------------------------------*/ -float128 float128_round_to_int( float128 ); -float128 float128_add( float128, float128 ); -float128 float128_sub( float128, float128 ); -float128 float128_mul( float128, float128 ); -float128 float128_div( float128, float128 ); -float128 float128_rem( float128, float128 ); -float128 float128_sqrt( float128 ); -flag float128_eq( float128, float128 ); -flag float128_le( float128, float128 ); -flag float128_lt( float128, float128 ); -flag float128_eq_signaling( float128, float128 ); -flag float128_le_quiet( float128, float128 ); -flag float128_lt_quiet( float128, float128 ); -flag float128_is_signaling_nan( float128 ); - -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', the exponent `zExp', and the significand formed -| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision -| floating-point value, returning the result. After being shifted into the -| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply -| added together to form the most significant 32 bits of the result. This -| means that any integer portion of `zSig0' will be added into the exponent. -| Since a properly normalized significand will have an integer portion equal -| to 1, the `zExp' input should be 1 less than the desired result exponent -| whenever `zSig0' and `zSig1' concatenated form a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ - -INLINE float128 - packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) -{ - float128 z; - - z.low = zSig1; - z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and extended significand formed by the concatenation of `zSig0', `zSig1', -| and `zSig2', and returns the proper quadruple-precision floating-point value -| corresponding to the abstract input. Ordinarily, the abstract value is -| simply rounded and packed into the quadruple-precision format, with the -| inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal quadruple- -| precision floating-point number. -| The input significand must be normalized or smaller. If the input -| significand is not normalized, `zExp' must be 0; in that case, the result -| returned is a subnormal number, and it must not require rounding. In the -| usual case that the input significand is normalized, `zExp' must be 1 less -| than the ``true'' floating-point exponent. The handling of underflow and -| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ - -INLINE float128 - roundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 ) -{ - int8 roundingMode; - flag roundNearestEven, increment, isTiny; - - roundingMode = float_rounding_mode; - roundNearestEven = ( roundingMode == float_round_nearest_even ); - increment = ( (sbits64) zSig2 < 0 ); - if ( ! roundNearestEven ) { - if ( roundingMode == float_round_to_zero ) { - increment = 0; - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && zSig2; - } - else { - increment = ( roundingMode == float_round_up ) && zSig2; - } - } - } - if ( 0x7FFD <= (bits32) zExp ) { - if ( ( 0x7FFD < zExp ) - || ( ( zExp == 0x7FFD ) - && eq128( - LIT64( 0x0001FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ), - zSig0, - zSig1 - ) - && increment - ) - ) { - float_raise( float_flag_overflow | float_flag_inexact ); - if ( ( roundingMode == float_round_to_zero ) - || ( zSign && ( roundingMode == float_round_up ) ) - || ( ! zSign && ( roundingMode == float_round_down ) ) - ) { - return - packFloat128( - zSign, - 0x7FFE, - LIT64( 0x0000FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ) - ); - } - return packFloat128( zSign, 0x7FFF, 0, 0 ); - } - if ( zExp < 0 ) { - isTiny = - ( float_detect_tininess == float_tininess_before_rounding ) - || ( zExp < -1 ) - || ! increment - || lt128( - zSig0, - zSig1, - LIT64( 0x0001FFFFFFFFFFFF ), - LIT64( 0xFFFFFFFFFFFFFFFF ) - ); - shift128ExtraRightJamming( - zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 ); - zExp = 0; - if ( isTiny && zSig2 ) float_raise( float_flag_underflow ); - if ( roundNearestEven ) { - increment = ( (sbits64) zSig2 < 0 ); - } - else { - if ( zSign ) { - increment = ( roundingMode == float_round_down ) && zSig2; - } - else { - increment = ( roundingMode == float_round_up ) && zSig2; - } - } - } - } - if ( zSig2 ) float_exception_flags |= float_flag_inexact; - if ( increment ) { - add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 ); - zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven ); - } - else { - if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0; - } - return packFloat128( zSign, zExp, zSig0, zSig1 ); - -} - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand formed by the concatenation of `zSig0' and `zSig1', and -| returns the proper quadruple-precision floating-point value corresponding -| to the abstract input. This routine is just like `roundAndPackFloat128' -| except that the input significand has fewer bits and does not have to be -| normalized. In all cases, `zExp' must be 1 less than the ``true'' floating- -| point exponent. -*----------------------------------------------------------------------------*/ - -INLINE float128 - normalizeRoundAndPackFloat128( - flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 ) -{ - int8 shiftCount; - bits64 zSig2; - - if ( zSig0 == 0 ) { - zSig0 = zSig1; - zSig1 = 0; - zExp -= 64; - } - shiftCount = countLeadingZeros64( zSig0 ) - 15; - if ( 0 <= shiftCount ) { - zSig2 = 0; - shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); - } - else { - shift128ExtraRightJamming( - zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 ); - } - zExp -= shiftCount; - return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); - -} -#endif diff --git a/source/src/vm/libcpu_newdev/softfloat3/000_artane.txt b/source/src/vm/libcpu_newdev/softfloat3/000_artane.txt deleted file mode 100644 index 46e3f43f2..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/000_artane.txt +++ /dev/null @@ -1 +0,0 @@ -This source code from 3rdparty/softfloat3, MAME 0.208. \ No newline at end of file diff --git a/source/src/vm/libcpu_newdev/softfloat3/COPYING.txt b/source/src/vm/libcpu_newdev/softfloat3/COPYING.txt deleted file mode 100644 index b5690face..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/COPYING.txt +++ /dev/null @@ -1,37 +0,0 @@ - -License for Berkeley SoftFloat Release 3e - -John R. Hauser -2018 January 20 - -The following applies to the whole of SoftFloat Release 3e as well as to -each source file individually. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions, and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/source/src/vm/libcpu_newdev/softfloat3/README.html b/source/src/vm/libcpu_newdev/softfloat3/README.html deleted file mode 100644 index e695c2bd8..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/README.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - -Berkeley SoftFloat Package Overview - - - - -

Package Overview for Berkeley SoftFloat Release 3e

- -

-John R. Hauser
-2018 January 20
-

- -

-Berkeley SoftFloat is a software implementation of binary floating-point that -conforms to the IEEE Standard for Floating-Point Arithmetic. -SoftFloat is distributed in the form of C source code. -Building the SoftFloat sources generates a library file (typically -softfloat.a or libsoftfloat.a) containing the -floating-point subroutines. -

- -

-The SoftFloat package is documented in the following files in the -doc subdirectory: -

- - - - - - - - - - - - - -
SoftFloat.htmlDocumentation for using the SoftFloat functions.
SoftFloat-source.htmlDocumentation for building SoftFloat.
SoftFloat-history.html   History of the major changes to SoftFloat.
-
-Other files in the package comprise the source code for SoftFloat. -

- - - diff --git a/source/src/vm/libcpu_newdev/softfloat3/README.txt b/source/src/vm/libcpu_newdev/softfloat3/README.txt deleted file mode 100644 index 1613c7671..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/README.txt +++ /dev/null @@ -1,21 +0,0 @@ - -Package Overview for Berkeley SoftFloat Release 3e - -John R. Hauser -2018 January 20 - -Berkeley SoftFloat is a software implementation of binary floating-point -that conforms to the IEEE Standard for Floating-Point Arithmetic. SoftFloat -is distributed in the form of C source code. Building the SoftFloat sources -generates a library file (typically "softfloat.a" or "libsoftfloat.a") -containing the floating-point subroutines. - -The SoftFloat package is documented in the following files in the "doc" -subdirectory: - - SoftFloat.html Documentation for using the SoftFloat functions. - SoftFloat-source.html Documentation for building SoftFloat. - SoftFloat-history.html History of the major changes to SoftFloat. - -Other files in the package comprise the source code for SoftFloat. - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-GCC/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-GCC/Makefile deleted file mode 100644 index faeb39728..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-GCC/Makefile +++ /dev/null @@ -1,325 +0,0 @@ - -#============================================================================= -# -# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic -# Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -SOURCE_DIR ?= ../../source -SPECIALIZE_TYPE ?= 8086 - -SOFTFLOAT_OPTS ?= \ - -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ - -DSOFTFLOAT_FAST_DIV64TO32 - -DELETE = rm -f -C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -COMPILE_C = \ - gcc -c -Werror-implicit-function-declaration $(SOFTFLOAT_OPTS) \ - $(C_INCLUDES) -O2 -o $@ -MAKELIB = ar crs $@ - -OBJ = .o -LIB = .a - -OTHER_HEADERS = - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_compare96M$(OBJ) \ - s_compare128M$(OBJ) \ - s_shortShiftLeft64To96M$(OBJ) \ - s_shortShiftLeftM$(OBJ) \ - s_shiftLeftM$(OBJ) \ - s_shortShiftRightM$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJamM$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJamM$(OBJ) \ - s_shiftRightM$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_addM$(OBJ) \ - s_addCarryM$(OBJ) \ - s_addComplCarryM$(OBJ) \ - s_negXM$(OBJ) \ - s_sub1XM$(OBJ) \ - s_subM$(OBJ) \ - s_mul64To128M$(OBJ) \ - s_mul128MTo256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - s_remStepMBy32$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80MToCommonNaN$(OBJ) \ - s_commonNaNToExtF80M$(OBJ) \ - s_propagateNaNExtF80M$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128MToCommonNaN$(OBJ) \ - s_commonNaNToF128M$(OBJ) \ - s_propagateNaNF128M$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundMToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundMToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_tryPropagateNaNExtF80M$(OBJ) \ - s_invalidExtF80M$(OBJ) \ - s_normExtF80SigM$(OBJ) \ - s_roundPackMToExtF80M$(OBJ) \ - s_normRoundPackMToExtF80M$(OBJ) \ - s_addExtF80M$(OBJ) \ - s_compareNonnormExtF80M$(OBJ) \ - s_isNaNF128M$(OBJ) \ - s_tryPropagateNaNF128M$(OBJ) \ - s_invalidF128M$(OBJ) \ - s_shiftNormSigF128M$(OBJ) \ - s_roundPackMToF128M$(OBJ) \ - s_normRoundPackMToF128M$(OBJ) \ - s_addF128M$(OBJ) \ - s_mulAddF128M$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-GCC/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-GCC/platform.h deleted file mode 100644 index d514dbc40..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-GCC/platform.h +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define SOFTFLOAT_BUILTIN_CLZ 1 -#include "opts-GCC.h" - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-SSE2-GCC/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-SSE2-GCC/Makefile deleted file mode 100644 index ced977b69..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-SSE2-GCC/Makefile +++ /dev/null @@ -1,325 +0,0 @@ - -#============================================================================= -# -# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic -# Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -SOURCE_DIR ?= ../../source -SPECIALIZE_TYPE ?= 8086-SSE - -SOFTFLOAT_OPTS ?= \ - -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ - -DSOFTFLOAT_FAST_DIV64TO32 - -DELETE = rm -f -C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -COMPILE_C = \ - gcc -c -Werror-implicit-function-declaration $(SOFTFLOAT_OPTS) \ - $(C_INCLUDES) -O2 -o $@ -MAKELIB = ar crs $@ - -OBJ = .o -LIB = .a - -OTHER_HEADERS = - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_compare96M$(OBJ) \ - s_compare128M$(OBJ) \ - s_shortShiftLeft64To96M$(OBJ) \ - s_shortShiftLeftM$(OBJ) \ - s_shiftLeftM$(OBJ) \ - s_shortShiftRightM$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJamM$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJamM$(OBJ) \ - s_shiftRightM$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_addM$(OBJ) \ - s_addCarryM$(OBJ) \ - s_addComplCarryM$(OBJ) \ - s_negXM$(OBJ) \ - s_sub1XM$(OBJ) \ - s_subM$(OBJ) \ - s_mul64To128M$(OBJ) \ - s_mul128MTo256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - s_remStepMBy32$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80MToCommonNaN$(OBJ) \ - s_commonNaNToExtF80M$(OBJ) \ - s_propagateNaNExtF80M$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128MToCommonNaN$(OBJ) \ - s_commonNaNToF128M$(OBJ) \ - s_propagateNaNF128M$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundMToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundMToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_tryPropagateNaNExtF80M$(OBJ) \ - s_invalidExtF80M$(OBJ) \ - s_normExtF80SigM$(OBJ) \ - s_roundPackMToExtF80M$(OBJ) \ - s_normRoundPackMToExtF80M$(OBJ) \ - s_addExtF80M$(OBJ) \ - s_compareNonnormExtF80M$(OBJ) \ - s_isNaNF128M$(OBJ) \ - s_tryPropagateNaNF128M$(OBJ) \ - s_invalidF128M$(OBJ) \ - s_shiftNormSigF128M$(OBJ) \ - s_roundPackMToF128M$(OBJ) \ - s_normRoundPackMToF128M$(OBJ) \ - s_addF128M$(OBJ) \ - s_mulAddF128M$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-SSE2-GCC/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-SSE2-GCC/platform.h deleted file mode 100644 index d514dbc40..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-386-SSE2-GCC/platform.h +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define SOFTFLOAT_BUILTIN_CLZ 1 -#include "opts-GCC.h" - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-ARM-VFPv2-GCC/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-ARM-VFPv2-GCC/Makefile deleted file mode 100644 index a1e7c8303..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-ARM-VFPv2-GCC/Makefile +++ /dev/null @@ -1,323 +0,0 @@ - -#============================================================================= -# -# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic -# Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -SOURCE_DIR ?= ../../source -SPECIALIZE_TYPE ?= ARM-VFPv2 - -SOFTFLOAT_OPTS ?= -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 - -DELETE = rm -f -C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -COMPILE_C = \ - gcc -c -Werror-implicit-function-declaration $(SOFTFLOAT_OPTS) \ - $(C_INCLUDES) -O2 -o $@ -MAKELIB = ar crs $@ - -OBJ = .o -LIB = .a - -OTHER_HEADERS = - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_compare96M$(OBJ) \ - s_compare128M$(OBJ) \ - s_shortShiftLeft64To96M$(OBJ) \ - s_shortShiftLeftM$(OBJ) \ - s_shiftLeftM$(OBJ) \ - s_shortShiftRightM$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJamM$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJamM$(OBJ) \ - s_shiftRightM$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_addM$(OBJ) \ - s_addCarryM$(OBJ) \ - s_addComplCarryM$(OBJ) \ - s_negXM$(OBJ) \ - s_sub1XM$(OBJ) \ - s_subM$(OBJ) \ - s_mul64To128M$(OBJ) \ - s_mul128MTo256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - s_remStepMBy32$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80MToCommonNaN$(OBJ) \ - s_commonNaNToExtF80M$(OBJ) \ - s_propagateNaNExtF80M$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128MToCommonNaN$(OBJ) \ - s_commonNaNToF128M$(OBJ) \ - s_propagateNaNF128M$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundMToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundMToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_tryPropagateNaNExtF80M$(OBJ) \ - s_invalidExtF80M$(OBJ) \ - s_normExtF80SigM$(OBJ) \ - s_roundPackMToExtF80M$(OBJ) \ - s_normRoundPackMToExtF80M$(OBJ) \ - s_addExtF80M$(OBJ) \ - s_compareNonnormExtF80M$(OBJ) \ - s_isNaNF128M$(OBJ) \ - s_tryPropagateNaNF128M$(OBJ) \ - s_invalidF128M$(OBJ) \ - s_shiftNormSigF128M$(OBJ) \ - s_roundPackMToF128M$(OBJ) \ - s_normRoundPackMToF128M$(OBJ) \ - s_addF128M$(OBJ) \ - s_mulAddF128M$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-ARM-VFPv2-GCC/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-ARM-VFPv2-GCC/platform.h deleted file mode 100644 index d514dbc40..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-ARM-VFPv2-GCC/platform.h +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define SOFTFLOAT_BUILTIN_CLZ 1 -#include "opts-GCC.h" - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-x86_64-GCC/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-x86_64-GCC/Makefile deleted file mode 100644 index 2ee5dad84..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-x86_64-GCC/Makefile +++ /dev/null @@ -1,390 +0,0 @@ - -#============================================================================= -# -# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic -# Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -SOURCE_DIR ?= ../../source -SPECIALIZE_TYPE ?= 8086-SSE - -SOFTFLOAT_OPTS ?= \ - -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ - -DSOFTFLOAT_FAST_DIV64TO32 - -DELETE = rm -f -C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -COMPILE_C = \ - gcc -c -Werror-implicit-function-declaration -DSOFTFLOAT_FAST_INT64 \ - $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@ -MAKELIB = ar crs $@ - -OBJ = .o -LIB = .a - -OTHER_HEADERS = $(SOURCE_DIR)/include/opts-GCC.h - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_eq128$(OBJ) \ - s_le128$(OBJ) \ - s_lt128$(OBJ) \ - s_shortShiftLeft128$(OBJ) \ - s_shortShiftRight128$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJam64Extra$(OBJ) \ - s_shortShiftRightJam128$(OBJ) \ - s_shortShiftRightJam128Extra$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJam64Extra$(OBJ) \ - s_shiftRightJam128$(OBJ) \ - s_shiftRightJam128Extra$(OBJ) \ - s_shiftRightJam256M$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_add128$(OBJ) \ - s_add256M$(OBJ) \ - s_sub128$(OBJ) \ - s_sub256M$(OBJ) \ - s_mul64ByShifted32To128$(OBJ) \ - s_mul64To128$(OBJ) \ - s_mul128By32$(OBJ) \ - s_mul128To256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80UIToCommonNaN$(OBJ) \ - s_commonNaNToExtF80UI$(OBJ) \ - s_propagateNaNExtF80UI$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128UIToCommonNaN$(OBJ) \ - s_commonNaNToF128UI$(OBJ) \ - s_propagateNaNF128UI$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_normSubnormalExtF80Sig$(OBJ) \ - s_roundPackToExtF80$(OBJ) \ - s_normRoundPackToExtF80$(OBJ) \ - s_addMagsExtF80$(OBJ) \ - s_subMagsExtF80$(OBJ) \ - s_normSubnormalF128Sig$(OBJ) \ - s_roundPackToF128$(OBJ) \ - s_normRoundPackToF128$(OBJ) \ - s_addMagsF128$(OBJ) \ - s_subMagsF128$(OBJ) \ - s_mulAddF128$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80_to_ui32$(OBJ) \ - extF80_to_ui64$(OBJ) \ - extF80_to_i32$(OBJ) \ - extF80_to_i64$(OBJ) \ - extF80_to_ui32_r_minMag$(OBJ) \ - extF80_to_ui64_r_minMag$(OBJ) \ - extF80_to_i32_r_minMag$(OBJ) \ - extF80_to_i64_r_minMag$(OBJ) \ - extF80_to_f16$(OBJ) \ - extF80_to_f32$(OBJ) \ - extF80_to_f64$(OBJ) \ - extF80_to_f128$(OBJ) \ - extF80_roundToInt$(OBJ) \ - extF80_add$(OBJ) \ - extF80_sub$(OBJ) \ - extF80_mul$(OBJ) \ - extF80_div$(OBJ) \ - extF80_rem$(OBJ) \ - extF80_sqrt$(OBJ) \ - extF80_eq$(OBJ) \ - extF80_le$(OBJ) \ - extF80_lt$(OBJ) \ - extF80_eq_signaling$(OBJ) \ - extF80_le_quiet$(OBJ) \ - extF80_lt_quiet$(OBJ) \ - extF80_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128_to_ui32$(OBJ) \ - f128_to_ui64$(OBJ) \ - f128_to_i32$(OBJ) \ - f128_to_i64$(OBJ) \ - f128_to_ui32_r_minMag$(OBJ) \ - f128_to_ui64_r_minMag$(OBJ) \ - f128_to_i32_r_minMag$(OBJ) \ - f128_to_i64_r_minMag$(OBJ) \ - f128_to_f16$(OBJ) \ - f128_to_f32$(OBJ) \ - f128_to_extF80$(OBJ) \ - f128_to_f64$(OBJ) \ - f128_roundToInt$(OBJ) \ - f128_add$(OBJ) \ - f128_sub$(OBJ) \ - f128_mul$(OBJ) \ - f128_mulAdd$(OBJ) \ - f128_div$(OBJ) \ - f128_rem$(OBJ) \ - f128_sqrt$(OBJ) \ - f128_eq$(OBJ) \ - f128_le$(OBJ) \ - f128_lt$(OBJ) \ - f128_eq_signaling$(OBJ) \ - f128_le_quiet$(OBJ) \ - f128_lt_quiet$(OBJ) \ - f128_isSignalingNaN$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-x86_64-GCC/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/Linux-x86_64-GCC/platform.h deleted file mode 100644 index c5e06f8e9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Linux-x86_64-GCC/platform.h +++ /dev/null @@ -1,54 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define SOFTFLOAT_BUILTIN_CLZ 1 -#define SOFTFLOAT_INTRINSIC_INT128 1 -#include "opts-GCC.h" - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/MAME/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/MAME/platform.h deleted file mode 100644 index 5dfa70495..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/MAME/platform.h +++ /dev/null @@ -1,81 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -Softfloat 3 MAME modifications -*----------------------------------------------------------------------------*/ -#ifdef LSB_FIRST -#define LITTLEENDIAN 1 -#else -#define LITTLEENDIAN 0 -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ - -#if defined(_MSC_VER) && !defined(__clang__) - -#define _INC_MALLOC 0 -#include - -// MSVC has __lzcnt16 as well, but opts-GCC.h expects __lzcnt for uint16_t and uint32_t -#if defined(_M_IX86) || defined(_M_AMD64) -#define __builtin_clz __lzcnt -#endif // defined(_M_IX86) || defined(_M_AMD64) -#if defined(_M_AMD64) -#define SOFTFLOAT_BUILTIN_CLZ 1 -#define __builtin_clzll __lzcnt64 -#endif // defined(_M_AMD64) - -#else // defined(_MSC_VER) - -// true for GCC and Clang on Intel and ARM, and MSVC on Intel. -#define SOFTFLOAT_BUILTIN_CLZ 1 -#if defined(PTR64) -#define SOFTFLOAT_INTRINSIC_INT128 1 -#endif // defined(PTR64) - -#endif // defined(_MSC_VER) - -#include "opts-GCC.h" diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-MinGW/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/Win32-MinGW/Makefile deleted file mode 100644 index faeb39728..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-MinGW/Makefile +++ /dev/null @@ -1,325 +0,0 @@ - -#============================================================================= -# -# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic -# Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -SOURCE_DIR ?= ../../source -SPECIALIZE_TYPE ?= 8086 - -SOFTFLOAT_OPTS ?= \ - -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ - -DSOFTFLOAT_FAST_DIV64TO32 - -DELETE = rm -f -C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -COMPILE_C = \ - gcc -c -Werror-implicit-function-declaration $(SOFTFLOAT_OPTS) \ - $(C_INCLUDES) -O2 -o $@ -MAKELIB = ar crs $@ - -OBJ = .o -LIB = .a - -OTHER_HEADERS = - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_compare96M$(OBJ) \ - s_compare128M$(OBJ) \ - s_shortShiftLeft64To96M$(OBJ) \ - s_shortShiftLeftM$(OBJ) \ - s_shiftLeftM$(OBJ) \ - s_shortShiftRightM$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJamM$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJamM$(OBJ) \ - s_shiftRightM$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_addM$(OBJ) \ - s_addCarryM$(OBJ) \ - s_addComplCarryM$(OBJ) \ - s_negXM$(OBJ) \ - s_sub1XM$(OBJ) \ - s_subM$(OBJ) \ - s_mul64To128M$(OBJ) \ - s_mul128MTo256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - s_remStepMBy32$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80MToCommonNaN$(OBJ) \ - s_commonNaNToExtF80M$(OBJ) \ - s_propagateNaNExtF80M$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128MToCommonNaN$(OBJ) \ - s_commonNaNToF128M$(OBJ) \ - s_propagateNaNF128M$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundMToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundMToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_tryPropagateNaNExtF80M$(OBJ) \ - s_invalidExtF80M$(OBJ) \ - s_normExtF80SigM$(OBJ) \ - s_roundPackMToExtF80M$(OBJ) \ - s_normRoundPackMToExtF80M$(OBJ) \ - s_addExtF80M$(OBJ) \ - s_compareNonnormExtF80M$(OBJ) \ - s_isNaNF128M$(OBJ) \ - s_tryPropagateNaNF128M$(OBJ) \ - s_invalidF128M$(OBJ) \ - s_shiftNormSigF128M$(OBJ) \ - s_roundPackMToF128M$(OBJ) \ - s_normRoundPackMToF128M$(OBJ) \ - s_addF128M$(OBJ) \ - s_mulAddF128M$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-MinGW/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/Win32-MinGW/platform.h deleted file mode 100644 index d514dbc40..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-MinGW/platform.h +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define SOFTFLOAT_BUILTIN_CLZ 1 -#include "opts-GCC.h" - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-SSE2-MinGW/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/Win32-SSE2-MinGW/Makefile deleted file mode 100644 index ced977b69..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-SSE2-MinGW/Makefile +++ /dev/null @@ -1,325 +0,0 @@ - -#============================================================================= -# -# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic -# Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -SOURCE_DIR ?= ../../source -SPECIALIZE_TYPE ?= 8086-SSE - -SOFTFLOAT_OPTS ?= \ - -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ - -DSOFTFLOAT_FAST_DIV64TO32 - -DELETE = rm -f -C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -COMPILE_C = \ - gcc -c -Werror-implicit-function-declaration $(SOFTFLOAT_OPTS) \ - $(C_INCLUDES) -O2 -o $@ -MAKELIB = ar crs $@ - -OBJ = .o -LIB = .a - -OTHER_HEADERS = - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_compare96M$(OBJ) \ - s_compare128M$(OBJ) \ - s_shortShiftLeft64To96M$(OBJ) \ - s_shortShiftLeftM$(OBJ) \ - s_shiftLeftM$(OBJ) \ - s_shortShiftRightM$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJamM$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJamM$(OBJ) \ - s_shiftRightM$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_addM$(OBJ) \ - s_addCarryM$(OBJ) \ - s_addComplCarryM$(OBJ) \ - s_negXM$(OBJ) \ - s_sub1XM$(OBJ) \ - s_subM$(OBJ) \ - s_mul64To128M$(OBJ) \ - s_mul128MTo256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - s_remStepMBy32$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80MToCommonNaN$(OBJ) \ - s_commonNaNToExtF80M$(OBJ) \ - s_propagateNaNExtF80M$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128MToCommonNaN$(OBJ) \ - s_commonNaNToF128M$(OBJ) \ - s_propagateNaNF128M$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundMToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundMToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_tryPropagateNaNExtF80M$(OBJ) \ - s_invalidExtF80M$(OBJ) \ - s_normExtF80SigM$(OBJ) \ - s_roundPackMToExtF80M$(OBJ) \ - s_normRoundPackMToExtF80M$(OBJ) \ - s_addExtF80M$(OBJ) \ - s_compareNonnormExtF80M$(OBJ) \ - s_isNaNF128M$(OBJ) \ - s_tryPropagateNaNF128M$(OBJ) \ - s_invalidF128M$(OBJ) \ - s_shiftNormSigF128M$(OBJ) \ - s_roundPackMToF128M$(OBJ) \ - s_normRoundPackMToF128M$(OBJ) \ - s_addF128M$(OBJ) \ - s_mulAddF128M$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-SSE2-MinGW/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/Win32-SSE2-MinGW/platform.h deleted file mode 100644 index d514dbc40..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Win32-SSE2-MinGW/platform.h +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define SOFTFLOAT_BUILTIN_CLZ 1 -#include "opts-GCC.h" - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Win64-MinGW-w64/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/Win64-MinGW-w64/Makefile deleted file mode 100644 index cc5bc0c5b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Win64-MinGW-w64/Makefile +++ /dev/null @@ -1,390 +0,0 @@ - -#============================================================================= -# -# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic -# Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -SOURCE_DIR ?= ../../source -SPECIALIZE_TYPE ?= 8086-SSE - -SOFTFLOAT_OPTS ?= \ - -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ - -DSOFTFLOAT_FAST_DIV64TO32 - -DELETE = rm -f -C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -COMPILE_C = \ - x86_64-w64-mingw32-gcc -c -Werror-implicit-function-declaration \ - -DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@ -MAKELIB = x86_64-w64-mingw32-ar crs $@ - -OBJ = .o -LIB = .a - -OTHER_HEADERS = $(SOURCE_DIR)/include/opts-GCC.h - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_eq128$(OBJ) \ - s_le128$(OBJ) \ - s_lt128$(OBJ) \ - s_shortShiftLeft128$(OBJ) \ - s_shortShiftRight128$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJam64Extra$(OBJ) \ - s_shortShiftRightJam128$(OBJ) \ - s_shortShiftRightJam128Extra$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJam64Extra$(OBJ) \ - s_shiftRightJam128$(OBJ) \ - s_shiftRightJam128Extra$(OBJ) \ - s_shiftRightJam256M$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_add128$(OBJ) \ - s_add256M$(OBJ) \ - s_sub128$(OBJ) \ - s_sub256M$(OBJ) \ - s_mul64ByShifted32To128$(OBJ) \ - s_mul64To128$(OBJ) \ - s_mul128By32$(OBJ) \ - s_mul128To256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80UIToCommonNaN$(OBJ) \ - s_commonNaNToExtF80UI$(OBJ) \ - s_propagateNaNExtF80UI$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128UIToCommonNaN$(OBJ) \ - s_commonNaNToF128UI$(OBJ) \ - s_propagateNaNF128UI$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_normSubnormalExtF80Sig$(OBJ) \ - s_roundPackToExtF80$(OBJ) \ - s_normRoundPackToExtF80$(OBJ) \ - s_addMagsExtF80$(OBJ) \ - s_subMagsExtF80$(OBJ) \ - s_normSubnormalF128Sig$(OBJ) \ - s_roundPackToF128$(OBJ) \ - s_normRoundPackToF128$(OBJ) \ - s_addMagsF128$(OBJ) \ - s_subMagsF128$(OBJ) \ - s_mulAddF128$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80_to_ui32$(OBJ) \ - extF80_to_ui64$(OBJ) \ - extF80_to_i32$(OBJ) \ - extF80_to_i64$(OBJ) \ - extF80_to_ui32_r_minMag$(OBJ) \ - extF80_to_ui64_r_minMag$(OBJ) \ - extF80_to_i32_r_minMag$(OBJ) \ - extF80_to_i64_r_minMag$(OBJ) \ - extF80_to_f16$(OBJ) \ - extF80_to_f32$(OBJ) \ - extF80_to_f64$(OBJ) \ - extF80_to_f128$(OBJ) \ - extF80_roundToInt$(OBJ) \ - extF80_add$(OBJ) \ - extF80_sub$(OBJ) \ - extF80_mul$(OBJ) \ - extF80_div$(OBJ) \ - extF80_rem$(OBJ) \ - extF80_sqrt$(OBJ) \ - extF80_eq$(OBJ) \ - extF80_le$(OBJ) \ - extF80_lt$(OBJ) \ - extF80_eq_signaling$(OBJ) \ - extF80_le_quiet$(OBJ) \ - extF80_lt_quiet$(OBJ) \ - extF80_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128_to_ui32$(OBJ) \ - f128_to_ui64$(OBJ) \ - f128_to_i32$(OBJ) \ - f128_to_i64$(OBJ) \ - f128_to_ui32_r_minMag$(OBJ) \ - f128_to_ui64_r_minMag$(OBJ) \ - f128_to_i32_r_minMag$(OBJ) \ - f128_to_i64_r_minMag$(OBJ) \ - f128_to_f16$(OBJ) \ - f128_to_f32$(OBJ) \ - f128_to_extF80$(OBJ) \ - f128_to_f64$(OBJ) \ - f128_roundToInt$(OBJ) \ - f128_add$(OBJ) \ - f128_sub$(OBJ) \ - f128_mul$(OBJ) \ - f128_mulAdd$(OBJ) \ - f128_div$(OBJ) \ - f128_rem$(OBJ) \ - f128_sqrt$(OBJ) \ - f128_eq$(OBJ) \ - f128_le$(OBJ) \ - f128_lt$(OBJ) \ - f128_eq_signaling$(OBJ) \ - f128_le_quiet$(OBJ) \ - f128_lt_quiet$(OBJ) \ - f128_isSignalingNaN$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/Win64-MinGW-w64/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/Win64-MinGW-w64/platform.h deleted file mode 100644 index c5e06f8e9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/Win64-MinGW-w64/platform.h +++ /dev/null @@ -1,54 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#ifdef __GNUC_STDC_INLINE__ -#define INLINE inline -#else -#define INLINE extern inline -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define SOFTFLOAT_BUILTIN_CLZ 1 -#define SOFTFLOAT_INTRINSIC_INT128 1 -#include "opts-GCC.h" - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/template-FAST_INT64/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/template-FAST_INT64/Makefile deleted file mode 100644 index 78e7ff5aa..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/template-FAST_INT64/Makefile +++ /dev/null @@ -1,391 +0,0 @@ - -#============================================================================= -# -# This Makefile template is part of the SoftFloat IEEE Floating-Point -# Arithmetic Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -# Edit lines marked with `==>'. See "SoftFloat-source.html". - -==> SOURCE_DIR ?= ../../source -==> SPECIALIZE_TYPE ?= 8086 - -==> SOFTFLOAT_OPTS ?= \ -==> -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ -==> -DSOFTFLOAT_FAST_DIV64TO32 - -==> DELETE = rm -f -==> C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -==> COMPILE_C = \ -==> cc -c -DSOFTFLOAT_FAST_INT64 $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@ -==> MAKELIB = ar crs $@ - -==> OBJ = .o -==> LIB = .a - -==> OTHER_HEADERS = - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_eq128$(OBJ) \ - s_le128$(OBJ) \ - s_lt128$(OBJ) \ - s_shortShiftLeft128$(OBJ) \ - s_shortShiftRight128$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJam64Extra$(OBJ) \ - s_shortShiftRightJam128$(OBJ) \ - s_shortShiftRightJam128Extra$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJam64Extra$(OBJ) \ - s_shiftRightJam128$(OBJ) \ - s_shiftRightJam128Extra$(OBJ) \ - s_shiftRightJam256M$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_add128$(OBJ) \ - s_add256M$(OBJ) \ - s_sub128$(OBJ) \ - s_sub256M$(OBJ) \ - s_mul64ByShifted32To128$(OBJ) \ - s_mul64To128$(OBJ) \ - s_mul128By32$(OBJ) \ - s_mul128To256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80UIToCommonNaN$(OBJ) \ - s_commonNaNToExtF80UI$(OBJ) \ - s_propagateNaNExtF80UI$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128UIToCommonNaN$(OBJ) \ - s_commonNaNToF128UI$(OBJ) \ - s_propagateNaNF128UI$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_normSubnormalExtF80Sig$(OBJ) \ - s_roundPackToExtF80$(OBJ) \ - s_normRoundPackToExtF80$(OBJ) \ - s_addMagsExtF80$(OBJ) \ - s_subMagsExtF80$(OBJ) \ - s_normSubnormalF128Sig$(OBJ) \ - s_roundPackToF128$(OBJ) \ - s_normRoundPackToF128$(OBJ) \ - s_addMagsF128$(OBJ) \ - s_subMagsF128$(OBJ) \ - s_mulAddF128$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80_to_ui32$(OBJ) \ - extF80_to_ui64$(OBJ) \ - extF80_to_i32$(OBJ) \ - extF80_to_i64$(OBJ) \ - extF80_to_ui32_r_minMag$(OBJ) \ - extF80_to_ui64_r_minMag$(OBJ) \ - extF80_to_i32_r_minMag$(OBJ) \ - extF80_to_i64_r_minMag$(OBJ) \ - extF80_to_f16$(OBJ) \ - extF80_to_f32$(OBJ) \ - extF80_to_f64$(OBJ) \ - extF80_to_f128$(OBJ) \ - extF80_roundToInt$(OBJ) \ - extF80_add$(OBJ) \ - extF80_sub$(OBJ) \ - extF80_mul$(OBJ) \ - extF80_div$(OBJ) \ - extF80_rem$(OBJ) \ - extF80_sqrt$(OBJ) \ - extF80_eq$(OBJ) \ - extF80_le$(OBJ) \ - extF80_lt$(OBJ) \ - extF80_eq_signaling$(OBJ) \ - extF80_le_quiet$(OBJ) \ - extF80_lt_quiet$(OBJ) \ - extF80_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128_to_ui32$(OBJ) \ - f128_to_ui64$(OBJ) \ - f128_to_i32$(OBJ) \ - f128_to_i64$(OBJ) \ - f128_to_ui32_r_minMag$(OBJ) \ - f128_to_ui64_r_minMag$(OBJ) \ - f128_to_i32_r_minMag$(OBJ) \ - f128_to_i64_r_minMag$(OBJ) \ - f128_to_f16$(OBJ) \ - f128_to_f32$(OBJ) \ - f128_to_extF80$(OBJ) \ - f128_to_f64$(OBJ) \ - f128_roundToInt$(OBJ) \ - f128_add$(OBJ) \ - f128_sub$(OBJ) \ - f128_mul$(OBJ) \ - f128_mulAdd$(OBJ) \ - f128_div$(OBJ) \ - f128_rem$(OBJ) \ - f128_sqrt$(OBJ) \ - f128_eq$(OBJ) \ - f128_le$(OBJ) \ - f128_lt$(OBJ) \ - f128_eq_signaling$(OBJ) \ - f128_le_quiet$(OBJ) \ - f128_lt_quiet$(OBJ) \ - f128_isSignalingNaN$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/template-FAST_INT64/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/template-FAST_INT64/platform.h deleted file mode 100644 index 20946587b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/template-FAST_INT64/platform.h +++ /dev/null @@ -1,50 +0,0 @@ - -/*============================================================================ - -This C header template is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -// Edit lines marked with `==>'. See "SoftFloat-source.html". - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -==> #define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -==> #define INLINE inline - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -==> #define THREAD_LOCAL _Thread_local - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/template-not-FAST_INT64/Makefile b/source/src/vm/libcpu_newdev/softfloat3/build/template-not-FAST_INT64/Makefile deleted file mode 100644 index 48b2cd6bf..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/template-not-FAST_INT64/Makefile +++ /dev/null @@ -1,325 +0,0 @@ - -#============================================================================= -# -# This Makefile template is part of the SoftFloat IEEE Floating-Point -# Arithmetic Package, Release 3e, by John R. Hauser. -# -# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -# University of California. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions, and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions, and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# 3. Neither the name of the University nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#============================================================================= - -# Edit lines marked with `==>'. See "SoftFloat-source.html". - -==> SOURCE_DIR ?= ../../source -==> SPECIALIZE_TYPE ?= 8086 - -==> SOFTFLOAT_OPTS ?= \ -==> -DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \ -==> -DSOFTFLOAT_FAST_DIV64TO32 - -==> DELETE = rm -f -==> C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include -==> COMPILE_C = cc -c $(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@ -==> MAKELIB = ar crs $@ - -==> OBJ = .o -==> LIB = .a - -==> OTHER_HEADERS = - -.PHONY: all -all: softfloat$(LIB) - -OBJS_PRIMITIVES = \ - s_compare96M$(OBJ) \ - s_compare128M$(OBJ) \ - s_shortShiftLeft64To96M$(OBJ) \ - s_shortShiftLeftM$(OBJ) \ - s_shiftLeftM$(OBJ) \ - s_shortShiftRightM$(OBJ) \ - s_shortShiftRightJam64$(OBJ) \ - s_shortShiftRightJamM$(OBJ) \ - s_shiftRightJam32$(OBJ) \ - s_shiftRightJam64$(OBJ) \ - s_shiftRightJamM$(OBJ) \ - s_shiftRightM$(OBJ) \ - s_countLeadingZeros8$(OBJ) \ - s_countLeadingZeros16$(OBJ) \ - s_countLeadingZeros32$(OBJ) \ - s_countLeadingZeros64$(OBJ) \ - s_addM$(OBJ) \ - s_addCarryM$(OBJ) \ - s_addComplCarryM$(OBJ) \ - s_negXM$(OBJ) \ - s_sub1XM$(OBJ) \ - s_subM$(OBJ) \ - s_mul64To128M$(OBJ) \ - s_mul128MTo256M$(OBJ) \ - s_approxRecip_1Ks$(OBJ) \ - s_approxRecip32_1$(OBJ) \ - s_approxRecipSqrt_1Ks$(OBJ) \ - s_approxRecipSqrt32_1$(OBJ) \ - s_remStepMBy32$(OBJ) \ - -OBJS_SPECIALIZE = \ - softfloat_raiseFlags$(OBJ) \ - s_f16UIToCommonNaN$(OBJ) \ - s_commonNaNToF16UI$(OBJ) \ - s_propagateNaNF16UI$(OBJ) \ - s_f32UIToCommonNaN$(OBJ) \ - s_commonNaNToF32UI$(OBJ) \ - s_propagateNaNF32UI$(OBJ) \ - s_f64UIToCommonNaN$(OBJ) \ - s_commonNaNToF64UI$(OBJ) \ - s_propagateNaNF64UI$(OBJ) \ - extF80M_isSignalingNaN$(OBJ) \ - s_extF80MToCommonNaN$(OBJ) \ - s_commonNaNToExtF80M$(OBJ) \ - s_propagateNaNExtF80M$(OBJ) \ - f128M_isSignalingNaN$(OBJ) \ - s_f128MToCommonNaN$(OBJ) \ - s_commonNaNToF128M$(OBJ) \ - s_propagateNaNF128M$(OBJ) \ - -OBJS_OTHERS = \ - s_roundToUI32$(OBJ) \ - s_roundMToUI64$(OBJ) \ - s_roundToI32$(OBJ) \ - s_roundMToI64$(OBJ) \ - s_normSubnormalF16Sig$(OBJ) \ - s_roundPackToF16$(OBJ) \ - s_normRoundPackToF16$(OBJ) \ - s_addMagsF16$(OBJ) \ - s_subMagsF16$(OBJ) \ - s_mulAddF16$(OBJ) \ - s_normSubnormalF32Sig$(OBJ) \ - s_roundPackToF32$(OBJ) \ - s_normRoundPackToF32$(OBJ) \ - s_addMagsF32$(OBJ) \ - s_subMagsF32$(OBJ) \ - s_mulAddF32$(OBJ) \ - s_normSubnormalF64Sig$(OBJ) \ - s_roundPackToF64$(OBJ) \ - s_normRoundPackToF64$(OBJ) \ - s_addMagsF64$(OBJ) \ - s_subMagsF64$(OBJ) \ - s_mulAddF64$(OBJ) \ - s_tryPropagateNaNExtF80M$(OBJ) \ - s_invalidExtF80M$(OBJ) \ - s_normExtF80SigM$(OBJ) \ - s_roundPackMToExtF80M$(OBJ) \ - s_normRoundPackMToExtF80M$(OBJ) \ - s_addExtF80M$(OBJ) \ - s_compareNonnormExtF80M$(OBJ) \ - s_isNaNF128M$(OBJ) \ - s_tryPropagateNaNF128M$(OBJ) \ - s_invalidF128M$(OBJ) \ - s_shiftNormSigF128M$(OBJ) \ - s_roundPackMToF128M$(OBJ) \ - s_normRoundPackMToF128M$(OBJ) \ - s_addF128M$(OBJ) \ - s_mulAddF128M$(OBJ) \ - softfloat_state$(OBJ) \ - ui32_to_f16$(OBJ) \ - ui32_to_f32$(OBJ) \ - ui32_to_f64$(OBJ) \ - ui32_to_extF80M$(OBJ) \ - ui32_to_f128M$(OBJ) \ - ui64_to_f16$(OBJ) \ - ui64_to_f32$(OBJ) \ - ui64_to_f64$(OBJ) \ - ui64_to_extF80M$(OBJ) \ - ui64_to_f128M$(OBJ) \ - i32_to_f16$(OBJ) \ - i32_to_f32$(OBJ) \ - i32_to_f64$(OBJ) \ - i32_to_extF80M$(OBJ) \ - i32_to_f128M$(OBJ) \ - i64_to_f16$(OBJ) \ - i64_to_f32$(OBJ) \ - i64_to_f64$(OBJ) \ - i64_to_extF80M$(OBJ) \ - i64_to_f128M$(OBJ) \ - f16_to_ui32$(OBJ) \ - f16_to_ui64$(OBJ) \ - f16_to_i32$(OBJ) \ - f16_to_i64$(OBJ) \ - f16_to_ui32_r_minMag$(OBJ) \ - f16_to_ui64_r_minMag$(OBJ) \ - f16_to_i32_r_minMag$(OBJ) \ - f16_to_i64_r_minMag$(OBJ) \ - f16_to_f32$(OBJ) \ - f16_to_f64$(OBJ) \ - f16_to_extF80M$(OBJ) \ - f16_to_f128M$(OBJ) \ - f16_roundToInt$(OBJ) \ - f16_add$(OBJ) \ - f16_sub$(OBJ) \ - f16_mul$(OBJ) \ - f16_mulAdd$(OBJ) \ - f16_div$(OBJ) \ - f16_rem$(OBJ) \ - f16_sqrt$(OBJ) \ - f16_eq$(OBJ) \ - f16_le$(OBJ) \ - f16_lt$(OBJ) \ - f16_eq_signaling$(OBJ) \ - f16_le_quiet$(OBJ) \ - f16_lt_quiet$(OBJ) \ - f16_isSignalingNaN$(OBJ) \ - f32_to_ui32$(OBJ) \ - f32_to_ui64$(OBJ) \ - f32_to_i32$(OBJ) \ - f32_to_i64$(OBJ) \ - f32_to_ui32_r_minMag$(OBJ) \ - f32_to_ui64_r_minMag$(OBJ) \ - f32_to_i32_r_minMag$(OBJ) \ - f32_to_i64_r_minMag$(OBJ) \ - f32_to_f16$(OBJ) \ - f32_to_f64$(OBJ) \ - f32_to_extF80M$(OBJ) \ - f32_to_f128M$(OBJ) \ - f32_roundToInt$(OBJ) \ - f32_add$(OBJ) \ - f32_sub$(OBJ) \ - f32_mul$(OBJ) \ - f32_mulAdd$(OBJ) \ - f32_div$(OBJ) \ - f32_rem$(OBJ) \ - f32_sqrt$(OBJ) \ - f32_eq$(OBJ) \ - f32_le$(OBJ) \ - f32_lt$(OBJ) \ - f32_eq_signaling$(OBJ) \ - f32_le_quiet$(OBJ) \ - f32_lt_quiet$(OBJ) \ - f32_isSignalingNaN$(OBJ) \ - f64_to_ui32$(OBJ) \ - f64_to_ui64$(OBJ) \ - f64_to_i32$(OBJ) \ - f64_to_i64$(OBJ) \ - f64_to_ui32_r_minMag$(OBJ) \ - f64_to_ui64_r_minMag$(OBJ) \ - f64_to_i32_r_minMag$(OBJ) \ - f64_to_i64_r_minMag$(OBJ) \ - f64_to_f16$(OBJ) \ - f64_to_f32$(OBJ) \ - f64_to_extF80M$(OBJ) \ - f64_to_f128M$(OBJ) \ - f64_roundToInt$(OBJ) \ - f64_add$(OBJ) \ - f64_sub$(OBJ) \ - f64_mul$(OBJ) \ - f64_mulAdd$(OBJ) \ - f64_div$(OBJ) \ - f64_rem$(OBJ) \ - f64_sqrt$(OBJ) \ - f64_eq$(OBJ) \ - f64_le$(OBJ) \ - f64_lt$(OBJ) \ - f64_eq_signaling$(OBJ) \ - f64_le_quiet$(OBJ) \ - f64_lt_quiet$(OBJ) \ - f64_isSignalingNaN$(OBJ) \ - extF80M_to_ui32$(OBJ) \ - extF80M_to_ui64$(OBJ) \ - extF80M_to_i32$(OBJ) \ - extF80M_to_i64$(OBJ) \ - extF80M_to_ui32_r_minMag$(OBJ) \ - extF80M_to_ui64_r_minMag$(OBJ) \ - extF80M_to_i32_r_minMag$(OBJ) \ - extF80M_to_i64_r_minMag$(OBJ) \ - extF80M_to_f16$(OBJ) \ - extF80M_to_f32$(OBJ) \ - extF80M_to_f64$(OBJ) \ - extF80M_to_f128M$(OBJ) \ - extF80M_roundToInt$(OBJ) \ - extF80M_add$(OBJ) \ - extF80M_sub$(OBJ) \ - extF80M_mul$(OBJ) \ - extF80M_div$(OBJ) \ - extF80M_rem$(OBJ) \ - extF80M_sqrt$(OBJ) \ - extF80M_eq$(OBJ) \ - extF80M_le$(OBJ) \ - extF80M_lt$(OBJ) \ - extF80M_eq_signaling$(OBJ) \ - extF80M_le_quiet$(OBJ) \ - extF80M_lt_quiet$(OBJ) \ - f128M_to_ui32$(OBJ) \ - f128M_to_ui64$(OBJ) \ - f128M_to_i32$(OBJ) \ - f128M_to_i64$(OBJ) \ - f128M_to_ui32_r_minMag$(OBJ) \ - f128M_to_ui64_r_minMag$(OBJ) \ - f128M_to_i32_r_minMag$(OBJ) \ - f128M_to_i64_r_minMag$(OBJ) \ - f128M_to_f16$(OBJ) \ - f128M_to_f32$(OBJ) \ - f128M_to_f64$(OBJ) \ - f128M_to_extF80M$(OBJ) \ - f128M_roundToInt$(OBJ) \ - f128M_add$(OBJ) \ - f128M_sub$(OBJ) \ - f128M_mul$(OBJ) \ - f128M_mulAdd$(OBJ) \ - f128M_div$(OBJ) \ - f128M_rem$(OBJ) \ - f128M_sqrt$(OBJ) \ - f128M_eq$(OBJ) \ - f128M_le$(OBJ) \ - f128M_lt$(OBJ) \ - f128M_eq_signaling$(OBJ) \ - f128M_le_quiet$(OBJ) \ - f128M_lt_quiet$(OBJ) \ - -OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS) - -$(OBJS_ALL): \ - $(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \ - $(SOURCE_DIR)/include/primitives.h -$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \ - $(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \ - $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \ - $(SOURCE_DIR)/include/softfloat.h - -$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$*.c - -$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c - $(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c - -softfloat$(LIB): $(OBJS_ALL) - $(DELETE) $@ - $(MAKELIB) $^ - -.PHONY: clean -clean: - $(DELETE) $(OBJS_ALL) softfloat$(LIB) - diff --git a/source/src/vm/libcpu_newdev/softfloat3/build/template-not-FAST_INT64/platform.h b/source/src/vm/libcpu_newdev/softfloat3/build/template-not-FAST_INT64/platform.h deleted file mode 100644 index 20946587b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/build/template-not-FAST_INT64/platform.h +++ /dev/null @@ -1,50 +0,0 @@ - -/*============================================================================ - -This C header template is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -// Edit lines marked with `==>'. See "SoftFloat-source.html". - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -==> #define LITTLEENDIAN 1 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -==> #define INLINE inline - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -==> #define THREAD_LOCAL _Thread_local - diff --git a/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat-history.html b/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat-history.html deleted file mode 100644 index d81c6bc5a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat-history.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - -Berkeley SoftFloat History - - - - -

History of Berkeley SoftFloat, to Release 3e

- -

-John R. Hauser
-2018 January 20
-

- - -

Release 3e (2018 January)

- -
    - -
  • -Changed the default numeric code for optional rounding mode odd -(round to odd, also known as jamming) from 5 to 6. - -
  • -Modified the behavior of rounding mode odd when rounding to an -integer value (either conversion to an integer format or a -‘roundToInt’ function). -Previously, for those cases only, rounding mode odd acted the same -as rounding to minimum magnitude. -Now all operations are rounded consistently. - -
  • -Fixed some errors in the specialization code modeling Intel x86 floating-point, -specifically the integers returned on invalid operations and the propagation of -NaN payloads in a few rare cases. - -
  • -Added specialization code modeling ARM floating-point, conforming to VFPv2 or -later. - -
  • -Added an example target for ARM processors. - -
  • -Fixed a minor bug whereby function f16_to_ui64 might return a -different integer than expected in the case that the floating-point operand is -negative. - -
  • -Added example target-specific optimization for GCC, employing GCC instrinsics -and support for 128-bit integer arithmetic. - -
  • -Made other minor improvements. - -
- - -

Release 3d (2017 August)

- -
    - -
  • -Fixed bugs in the square root functions for 64-bit -double-precision, 80-bit double-extended-precision, and -128-bit quadruple-precision. -For 64-bit double-precision (f64_sqrt), the result -could sometimes be off by 1 unit in the last place -(1 ulp) from what it should be. -For the larger formats, the square root could be wrong in a large portion of -the less-significant bits. -(A bug in f128_sqrt was first reported by Alexei Sibidanov.) - -
- - -

Release 3c (2017 February)

- -
    - -
  • -Added optional rounding mode odd (round to odd, also known as -jamming). - -
  • -Corrected the documentation concerning non-canonical representations in -80-bit double-extended-precision. - -
- - -

Release 3b (2016 July)

- -
    - -
  • -Implemented the common 16-bit “half-precision” -floating-point format (float16_t). - -
  • -Made the integer values returned on invalid conversions to integer formats -be determined by the port-specific specialization instead of being the same for -all ports. - -
  • -Added preprocessor macro THREAD_LOCAL to allow the floating-point -state (modes and exception flags) to be made per-thread. - -
  • -Modified the provided Makefiles to allow some options to be overridden from the -make command. - -
  • -Made other minor improvements. - -
- - -

Release 3a (2015 October)

- -
    - -
  • -Replaced the license text supplied by the University of California, Berkeley. - -
- - -

Release 3 (2015 February)

- -
    - -
  • -Complete rewrite, funded by the University of California, Berkeley, and -consequently having a different use license than earlier releases. -Major changes included renaming most types and functions, upgrading some -algorithms, restructuring the source files, and making SoftFloat into a true -library. - -
  • -Added functions to convert between floating-point and unsigned integers, both -32-bit and 64-bit (uint32_t and -uint64_t). - -
  • -Added functions for fused multiply-add, for all supported floating-point -formats except 80-bit double-extended-precision. - -
  • -Added support for a fifth rounding mode, near_maxMag (round to -nearest, with ties to maximum magnitude, away from zero). - -
  • -Dropped the timesoftfloat program (now part of the Berkeley -TestFloat package). - -
- - -

Release 2c (2015 January)

- -
    - -
  • -Fixed mistakes affecting some 64-bit processors. - -
  • -Further improved the documentation and the wording for the legal restrictions -on using SoftFloat releases through 2c (not applicable to -Release 3 or later). - -
- - -

Release 2b (2002 May)

- -
    - -
  • -Made minor updates to the documentation, including improved wording for the -legal restrictions on using SoftFloat. - -
- - -

Release 2a (1998 December)

- -
    - -
  • -Added functions to convert between 64-bit integers -(int64) and all supported floating-point formats. - -
  • -Fixed a bug in all 64-bit-version square root functions except -float32_sqrt that caused the result sometimes to be off by -1 unit in the last place (1 ulp) from what it should -be. -(Bug discovered by Paul Donahue.) - -
  • -Improved the Makefiles. -
- - -

Release 2 (1997 June)

- -
    - -
  • -Created the 64-bit (bits64) version, adding the -floatx80 and float128 formats. - -
  • -Changed the source directory structure, splitting the sources into a -bits32 and a bits64 version. -Renamed environment.h to milieu.h to avoid confusion -with environment variables. - -
  • -Fixed a small error that caused float64_round_to_int often to -round the wrong way in nearest/even mode when the operand was between -220 and 221 and halfway between two integers. - -
- - -

Release 1a (1996 July)

- -
    - -
  • -Corrected a mistake that caused borderline underflow cases not to raise the -underflow flag when they should have. -(Problem reported by Doug Priest.) - -
  • -Added the float_detect_tininess variable to control whether -tininess is detected before or after rounding. - -
- - -

Release 1 (1996 July)

- -
    - -
  • -Original release, based on work done for the International Computer Science -Institute (ICSI) in Berkeley, California. - -
- - - - diff --git a/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat-source.html b/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat-source.html deleted file mode 100644 index 4ff9d4c45..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat-source.html +++ /dev/null @@ -1,686 +0,0 @@ - - - - -Berkeley SoftFloat Source Documentation - - - - -

Berkeley SoftFloat Release 3e: Source Documentation

- -

-John R. Hauser
-2018 January 20
-

- - -

Contents

- -
- --- - - - - - - - - - - - - - - - - - - - -
1. Introduction
2. Limitations
3. Acknowledgments and License
4. SoftFloat Package Directory Structure
5. Issues for Porting SoftFloat to a New Target
5.1. Standard Headers <stdbool.h> and - <stdint.h>
5.2. Specializing Floating-Point Behavior
5.3. Macros for Build Options
5.4. Adapting a Template Target Directory
5.5. Target-Specific Optimization of Primitive Functions
6. Testing SoftFloat
7. Providing SoftFloat as a Common Library for Applications
8. Contact Information
-
- - -

1. Introduction

- -

-This document gives information needed for compiling and/or porting Berkeley -SoftFloat, a library of C functions implementing binary floating-point -conforming to the IEEE Standard for Floating-Point Arithmetic. -For basic documentation about SoftFloat refer to -SoftFloat.html. -

- -

-The source code for SoftFloat is intended to be relatively machine-independent -and should be compilable with any ISO-Standard C compiler that also supports -64-bit integers. -SoftFloat has been successfully compiled with the GNU C Compiler -(gcc) for several platforms. -

- -

-Release 3 of SoftFloat was a complete rewrite relative to -Release 2 or earlier. -Changes to the interface of SoftFloat functions are documented in -SoftFloat.html. -The current version of SoftFloat is Release 3e. -

- - -

2. Limitations

- -

-SoftFloat assumes the computer has an addressable byte size of either 8 or -16 bits. -(Nearly all computers in use today have 8-bit bytes.) -

- -

-SoftFloat is written in C and is designed to work with other C code. -The C compiler used must conform at a minimum to the 1989 ANSI standard for the -C language (same as the 1990 ISO standard) and must in addition support basic -arithmetic on 64-bit integers. -Earlier releases of SoftFloat included implementations of 32-bit -single-precision and 64-bit double-precision floating-point that -did not require 64-bit integers, but this option is not supported -starting with Release 3. -Since 1999, ISO standards for C have mandated compiler support for -64-bit integers. -A compiler conforming to the 1999 C Standard or later is recommended but not -strictly required. -

- -

-C Standard header files <stdbool.h> and -<stdint.h> are required for defining standard Boolean and -integer types. -If these headers are not supplied with the C compiler, minimal substitutes must -be provided. -SoftFloat’s dependence on these headers is detailed later in -section 5.1, Standard Headers <stdbool.h> -and <stdint.h>. -

- - -

3. Acknowledgments and License

- -

-The SoftFloat package was written by me, John R. Hauser. -Release 3 of SoftFloat was a completely new implementation -supplanting earlier releases. -The project to create Release 3 (now through 3e) was -done in the employ of the University of California, Berkeley, within the -Department of Electrical Engineering and Computer Sciences, first for the -Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab. -The work was officially overseen by Prof. Krste Asanovic, with funding provided -by these sources: -

- ---- - - - - - - - - - -
Par Lab: -Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery -(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia, -NVIDIA, Oracle, and Samsung. -
ASPIRE Lab: -DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from -ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA, -Oracle, and Samsung. -
-
-

- -

-The following applies to the whole of SoftFloat Release 3e as well -as to each source file individually. -

- -

-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the -University of California. -All rights reserved. -

- -

-Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -

    - -
  1. -

    -Redistributions of source code must retain the above copyright notice, this -list of conditions, and the following disclaimer. -

    - -
  2. -

    -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions, and the following disclaimer in the documentation and/or -other materials provided with the distribution. -

    - -
  3. -

    -Neither the name of the University nor the names of its contributors may be -used to endorse or promote products derived from this software without specific -prior written permission. -

    - -
-

- -

-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS”, -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. -IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -

- - -

4. SoftFloat Package Directory Structure

- -

-Because SoftFloat is targeted to multiple platforms, its source code is -slightly scattered between target-specific and target-independent directories -and files. -The supplied directory structure is as follows: -

-
-doc
-source
-    include
-    8086
-    8086-SSE
-    ARM-VFPv2
-    ARM-VFPv2-defaultNaN
-build
-    template-FAST_INT64
-    template-not-FAST_INT64
-    Linux-386-GCC
-    Linux-386-SSE2-GCC
-    Linux-x86_64-GCC
-    Linux-ARM-VFPv2-GCC
-    Win32-MinGW
-    Win32-SSE2-MinGW
-    Win64-MinGW-w64
-
-
-The majority of the SoftFloat sources are provided in the source -directory. -The include subdirectory contains several header files -(unsurprisingly), while the other subdirectories of source contain -source files that specialize the floating-point behavior to match particular -processor families: -
-
-
8086
-
-Intel’s older, 8087-derived floating-point, extended to all supported -floating-point types -
-
8086-SSE
-
-Intel’s x86 processors with Streaming SIMD Extensions (SSE) and later -compatible extensions, having 8087 behavior for 80-bit -double-extended-precision (extFloat80_t) and SSE behavior for -other floating-point types -
-
ARM-VFPv2
-
-ARM’s VFPv2 or later floating-point, with NaN payload propagation -
-
ARM-VFPv2-defaultNaN
-
-ARM’s VFPv2 or later floating-point, with the “default NaN” -option -
-
-
-If other specializations are attempted, these would be expected to be other -subdirectories of source alongside the ones listed above. -Specialization is covered later, in section 5.2, Specializing -Floating-Point Behavior. -

- -

-The build directory is intended to contain a subdirectory for each -target platform for which a build of the SoftFloat library may be created. -For each build target, the target’s subdirectory is where all derived -object files and the completed SoftFloat library (typically -softfloat.a or libsoftfloat.a) are created. -The two template subdirectories are not actual build targets but -contain sample files for creating new target directories. -(The meaning of FAST_INT64 will be explained later.) -

- -

-Ignoring the template directories, the supplied target directories -are intended to follow a naming system of -<execution-environment>-<compiler>. -For the example targets, -<execution-environment> is -Linux-386, Linux-386-SSE2, -Linux-x86_64, -Linux-ARM-VFPv2, Win32, -Win32-SSE2, or Win64, and -<compiler> is GCC, -MinGW, or MinGW-w64. -

- -

-All of the supplied target directories are merely examples that may or may not -be correct for compiling on any particular system. -Despite requests, there are currently no plans to include and maintain in the -SoftFloat package the build files needed for a great many users’ -compilation environments, which can span a huge range of operating systems, -compilers, and other tools. -

- -

-As supplied, each target directory contains two files: -

-
-Makefile
-platform.h
-
-
-The provided Makefile is written for GNU make. -A build of SoftFloat for the specific target is begun by executing the -make command with the target directory as the current directory. -A completely different build tool can be used if an appropriate -Makefile equivalent is created. -

- -

-The platform.h header file exists to provide a location for -additional C declarations specific to the build target. -Every C source file of SoftFloat contains a #include for -platform.h. -In many cases, the contents of platform.h can be as simple as one -or two lines of code. -At the other extreme, to get maximal performance from SoftFloat, it may be -desirable to include in header platform.h (directly or via -#include) declarations for numerous target-specific optimizations. -Such possibilities are discussed in the next section, Issues for Porting -SoftFloat to a New Target. -If the target’s compiler or library has bugs or other shortcomings, -workarounds for these issues may also be possible with target-specific -declarations in platform.h, avoiding the need to modify the main -SoftFloat sources. -

- - -

5. Issues for Porting SoftFloat to a New Target

- -

5.1. Standard Headers <stdbool.h> and <stdint.h>

- -

-The SoftFloat sources make use of standard headers -<stdbool.h> and <stdint.h>, which have -been part of the ISO C Standard Library since 1999. -With any recent compiler, these standard headers are likely to be supported, -even if the compiler does not claim complete conformance to the latest ISO C -Standard. -For older or nonstandard compilers, substitutes for -<stdbool.h> and <stdint.h> may need to be -created. -SoftFloat depends on these names from <stdbool.h>: -

-
-bool
-true
-false
-
-
-and on these names from <stdint.h>: -
-
-uint16_t
-uint32_t
-uint64_t
-int32_t
-int64_t
-UINT64_C
-INT64_C
-uint_least8_t
-uint_fast8_t
-uint_fast16_t
-uint_fast32_t
-uint_fast64_t
-int_fast8_t
-int_fast16_t
-int_fast32_t
-int_fast64_t
-
-
-

- - -

5.2. Specializing Floating-Point Behavior

- -

-The IEEE Floating-Point Standard allows for some flexibility in a conforming -implementation, particularly concerning NaNs. -The SoftFloat source directory is supplied with some -specialization subdirectories containing possible definitions for this -implementation-specific behavior. -For example, the 8086 and 8086-SSE -subdirectories have source files that specialize SoftFloat’s behavior to -match that of Intel’s x86 line of processors. -The files in a specialization subdirectory must determine: -

    -
  • -whether tininess for underflow is detected before or after rounding by default; -
  • -how signaling NaNs are distinguished from quiet NaNs; -
  • -what (if anything) special happens when exceptions are raised; -
  • -the default generated quiet NaNs; -
  • -how NaNs are propagated from function inputs to output; and -
  • -the integer results returned when conversions to integer type raise the -invalid exception. -
-

- -

-As provided, the build process for a target expects to involve exactly -one specialization directory that defines all of these -implementation-specific details for the target. -A specialization directory such as 8086 is expected to contain a -header file called specialize.h, together with whatever other -source files are needed to complete the specialization. -

- -

-A new build target may use an existing specialization, such as the ones -provided by the 8086 and 8086-SSE -subdirectories. -If a build target needs a new specialization, different from any existing ones, -it is recommended that a new specialization directory be created for this -purpose. -The specialize.h header file from any of the provided -specialization subdirectories can be used as a model for what definitions are -needed. -

- - -

5.3. Macros for Build Options

- -

-The SoftFloat source files adapt the floating-point implementation according to -several C preprocessor macros: -

-
-
LITTLEENDIAN -
-Must be defined for little-endian machines; must not be defined for big-endian -machines. -
INLINE -
-Specifies the sequence of tokens used to indicate that a C function should be -inlined. -If macro INLINE_LEVEL is defined with a value of 1 or higher, this -macro must be defined; otherwise, this macro is ignored and need not be -defined. -For compilers that conform to the C Standard’s rules for inline -functions, this macro can be defined as the single keyword inline. -For other compilers that follow a convention pre-dating the standardization of -inline, this macro may need to be defined to extern -inline. -
THREAD_LOCAL -
-Can be defined to a sequence of tokens that, when appearing at the start of a -variable declaration, indicates to the C compiler that the variable is -per-thread, meaning that each execution thread gets its own separate -instance of the variable. -This macro is used in header softfloat.h in the declarations of -variables softfloat_roundingMode, -softfloat_detectTininess, extF80_roundingPrecision, -and softfloat_exceptionFlags. -If macro THREAD_LOCAL is left undefined, these variables will -default to being ordinary global variables. -Depending on the compiler, possible valid definitions of this macro include -_Thread_local and __thread. -
-
-
SOFTFLOAT_ROUND_ODD -
-Can be defined to enable support for optional rounding mode -softfloat_round_odd. -
-
-
INLINE_LEVEL -
-Can be defined to an integer to determine the degree of inlining requested of -the compiler. -Larger numbers request that more inlining be done. -If this macro is not defined or is defined to a value less than 1 -(zero or negative), no inlining is requested. -The maximum effective value is no higher than 5. -Defining this macro to a value greater than 5 is the same as defining it -to 5. -
SOFTFLOAT_FAST_INT64 -
-Can be defined to indicate that the build target’s implementation of -64-bit arithmetic is efficient. -For newer 64-bit processors, this macro should usually be defined. -For very small microprocessors whose buses and registers are 8-bit -or 16-bit in size, this macro should usually not be defined. -Whether this macro should be defined for a 32-bit processor may -depend on the target machine and the applications that will use SoftFloat. -
SOFTFLOAT_FAST_DIV32TO16 -
-Can be defined to indicate that the target’s division operator -in C (written as /) is reasonably efficient for -dividing a 32-bit unsigned integer by a 16-bit -unsigned integer. -Setting this macro may affect the performance of function f16_div. -
SOFTFLOAT_FAST_DIV64TO32 -
-Can be defined to indicate that the target’s division operator -in C (written as /) is reasonably efficient for -dividing a 64-bit unsigned integer by a 32-bit -unsigned integer. -Setting this macro may affect the performance of division, remainder, and -square root operations other than f16_div. -
-
-

- -

-Following the usual custom for C, for most of these macros (all -except INLINE, THREAD_LOCAL, and -INLINE_LEVEL), the content of any definition is irrelevant; -what matters is a macro’s effect on #ifdef directives. -

- -

-It is recommended that any definitions of macros LITTLEENDIAN, -INLINE, and THREAD_LOCAL be made in a build -target’s platform.h header file, because these macros are -expected to be determined inflexibly by the target machine and compiler. -The other five macros select options and control optimization, and thus might -be better located in the target’s Makefile (or its equivalent). -

- - -

5.4. Adapting a Template Target Directory

- -

-In the build directory, two template subdirectories -provide models for new target directories. -Two different templates exist because different functions are needed in the -SoftFloat library depending on whether macro SOFTFLOAT_FAST_INT64 -is defined. -If macro SOFTFLOAT_FAST_INT64 will be defined, -template-FAST_INT64 is the template to use; -otherwise, template-not-FAST_INT64 is the appropriate -template. -A new target directory can be created by copying the correct template directory -and editing the files inside. -To avoid confusion, it would be wise to refrain from editing the files within a -template directory directly. -

- - -

5.5. Target-Specific Optimization of Primitive Functions

- -

-Header file primitives.h (in directory -source/include) declares macros and functions for numerous -underlying arithmetic operations upon which many of SoftFloat’s -floating-point functions are ultimately built. -The SoftFloat sources include implementations of all of these functions/macros, -written as standard C code, so a complete and correct SoftFloat library can be -created using only the supplied code for all functions. -However, for many targets, SoftFloat’s performance can be improved by -substituting target-specific implementations of some of the functions/macros -declared in primitives.h. -

- -

-For example, primitives.h declares a function called -softfloat_countLeadingZeros32 that takes an unsigned -32-bit integer as an argument and returns the number of the -integer’s most-significant bits that are zeros. -While the SoftFloat sources include an implementation of this function written -in standard C, many processors can perform this same function -directly in only one or two machine instructions. -An alternative, target-specific implementation that maps to those instructions -is likely to be more efficient than the generic C code from the SoftFloat -package. -

- -

-A build target can replace the supplied version of any function or macro of -primitives.h by defining a macro with the same name in the -target’s platform.h header file. -For this purpose, it may be helpful for platform.h to -#include header file primitiveTypes.h, which defines -types used for arguments and results of functions declared in -primitives.h. -When a desired replacement implementation is a function, not a macro, it is -sufficient for platform.h to include the line -

-
-#define <function-name> <function-name>
-
-
-where <function-name> is the name of the -function. -This technically defines <function-name> -as a macro, but one that resolves to the same name, which may then be a -function. -(A preprocessor that conforms to the C Standard is required to limit recursive -macro expansion from being applied more than once.) -

- -

-The supplied header file opts-GCC.h (in directory -source/include) provides an example of target-specific -optimization for the GCC compiler. -Each GCC target example in the build directory has -

-#include "opts-GCC.h" -
-in its platform.h header file. -Before opts-GCC.h is included, the following macros must be -defined (or not) to control which features are invoked: -
-
-
SOFTFLOAT_BUILTIN_CLZ
-
-If defined, SoftFloat’s internal -‘countLeadingZeros’ functions use intrinsics -__builtin_clz and __builtin_clzll. -
-
SOFTFLOAT_INTRINSIC_INT128
-
-If defined, SoftFloat makes use of GCC’s nonstandard 128-bit -integer type __int128. -
-
-
-On some machines, these improvements are observed to increase the speeds of -f64_mul and f128_mul by around 20 to 25%, although -other functions receive less dramatic boosts, or none at all. -Results can vary greatly across different platforms. -

- - -

6. Testing SoftFloat

- -

-SoftFloat can be tested using the testsoftfloat program by the -same author. -This program is part of the Berkeley TestFloat package available at the Web -page -http://www.jhauser.us/arithmetic/TestFloat.html. -The TestFloat package also has a program called timesoftfloat that -measures the speed of SoftFloat’s floating-point functions. -

- - -

7. Providing SoftFloat as a Common Library for Applications

- -

-Header file softfloat.h defines the SoftFloat interface as seen by -clients. -If the SoftFloat library will be made a common library for programs on a -system, the supplied softfloat.h has a couple of deficiencies for -this purpose: -

    -
  • -As supplied, softfloat.h depends on another header, -softfloat_types.h, that is not intended for public use but which -must also be visible to the programmer’s compiler. -
  • -More troubling, at the time softfloat.h is included in a C source -file, macros SOFTFLOAT_FAST_INT64 and THREAD_LOCAL -must be defined, or not defined, consistent with how these macro were defined -when the SoftFloat library was built. -
-In the situation that new programs may regularly #include header -file softfloat.h, it is recommended that a custom, self-contained -version of this header file be created that eliminates these issues. -

- - -

8. Contact Information

- -

-At the time of this writing, the most up-to-date information about SoftFloat -and the latest release can be found at the Web page -http://www.jhauser.us/arithmetic/SoftFloat.html. -

- - - - diff --git a/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat.html b/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat.html deleted file mode 100644 index b72b407f4..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/doc/SoftFloat.html +++ /dev/null @@ -1,1527 +0,0 @@ - - - - -Berkeley SoftFloat Library Interface - - - - -

Berkeley SoftFloat Release 3e: Library Interface

- -

-John R. Hauser
-2018 January 20
-

- - -

Contents

- -
- --- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1. Introduction
2. Limitations
3. Acknowledgments and License
4. Types and Functions
4.1. Boolean and Integer Types
4.2. Floating-Point Types
4.3. Supported Floating-Point Functions
4.4. Non-canonical Representations in extFloat80_t
4.5. Conventions for Passing Arguments and Results
5. Reserved Names
6. Mode Variables
6.1. Rounding Mode
6.2. Underflow Detection
6.3. Rounding Precision for the 80-Bit Extended Format
7. Exceptions and Exception Flags
8. Function Details
8.1. Conversions from Integer to Floating-Point
8.2. Conversions from Floating-Point to Integer
8.3. Conversions Among Floating-Point Types
8.4. Basic Arithmetic Functions
8.5. Fused Multiply-Add Functions
8.6. Remainder Functions
8.7. Round-to-Integer Functions
8.8. Comparison Functions
8.9. Signaling NaN Test Functions
8.10. Raise-Exception Function
9. Changes from SoftFloat Release 2
9.1. Name Changes
9.2. Changes to Function Arguments
9.3. Added Capabilities
9.4. Better Compatibility with the C Language
9.5. New Organization as a Library
9.6. Optimization Gains (and Losses)
10. Future Directions
11. Contact Information
-
- - -

1. Introduction

- -

-Berkeley SoftFloat is a software implementation of binary floating-point that -conforms to the IEEE Standard for Floating-Point Arithmetic. -The current release supports five binary formats: 16-bit -half-precision, 32-bit single-precision, 64-bit -double-precision, 80-bit double-extended-precision, and -128-bit quadruple-precision. -The following functions are supported for each format: -

    -
  • -addition, subtraction, multiplication, division, and square root; -
  • -fused multiply-add as defined by the IEEE Standard, except for -80-bit double-extended-precision; -
  • -remainder as defined by the IEEE Standard; -
  • -round to integral value; -
  • -comparisons; -
  • -conversions to/from other supported formats; and -
  • -conversions to/from 32-bit and 64-bit integers, -signed and unsigned. -
-All operations required by the original 1985 version of the IEEE Floating-Point -Standard are implemented, except for conversions to and from decimal. -

- -

-This document gives information about the types defined and the routines -implemented by SoftFloat. -It does not attempt to define or explain the IEEE Floating-Point Standard. -Information about the standard is available elsewhere. -

- -

-The current version of SoftFloat is Release 3e. -This release modifies the behavior of the rarely used odd rounding mode -(round to odd, also known as jamming), and also adds some new -specialization and optimization examples for those compiling SoftFloat. -

- -

-The previous Release 3d fixed bugs that were found in the square -root functions for the 64-bit, 80-bit, and -128-bit floating-point formats. -(Thanks to Alexei Sibidanov at the University of Victoria for reporting an -incorrect result.) -The bugs affected all prior Release-3 versions of SoftFloat -through 3c. -The flaw in the 64-bit floating-point square root function was of -very minor impact, causing a 1-ulp error (1 unit in -the last place) a few times out of a billion. -The bugs in the 80-bit and 128-bit square root -functions were more serious. -Although incorrect results again occurred only a few times out of a billion, -when they did occur a large portion of the less-significant bits could be -wrong. -

- -

-Among earlier releases, 3b was notable for adding support for the -16-bit half-precision format. -For more about the evolution of SoftFloat releases, see -SoftFloat-history.html. -

- -

-The functional interface of SoftFloat Release 3 and later differs -in many details from the releases that came before. -For specifics of these differences, see section 9 below, -Changes from SoftFloat Release 2. -

- - -

2. Limitations

- -

-SoftFloat assumes the computer has an addressable byte size of 8 or -16 bits. -(Nearly all computers in use today have 8-bit bytes.) -

- -

-SoftFloat is written in C and is designed to work with other C code. -The C compiler used must conform at a minimum to the 1989 ANSI standard for the -C language (same as the 1990 ISO standard) and must in addition support basic -arithmetic on 64-bit integers. -Earlier releases of SoftFloat included implementations of 32-bit -single-precision and 64-bit double-precision floating-point that -did not require 64-bit integers, but this option is not supported -starting with Release 3. -Since 1999, ISO standards for C have mandated compiler support for -64-bit integers. -A compiler conforming to the 1999 C Standard or later is recommended but not -strictly required. -

- -

-Most operations not required by the original 1985 version of the IEEE -Floating-Point Standard but added in the 2008 version are not yet supported in -SoftFloat Release 3e. -

- - -

3. Acknowledgments and License

- -

-The SoftFloat package was written by me, John R. Hauser. -Release 3 of SoftFloat was a completely new implementation -supplanting earlier releases. -The project to create Release 3 (now through 3e) was -done in the employ of the University of California, Berkeley, within the -Department of Electrical Engineering and Computer Sciences, first for the -Parallel Computing Laboratory (Par Lab) and then for the ASPIRE Lab. -The work was officially overseen by Prof. Krste Asanovic, with funding provided -by these sources: -

- ---- - - - - - - - - - -
Par Lab: -Microsoft (Award #024263), Intel (Award #024894), and U.C. Discovery -(Award #DIG07-10227), with additional support from Par Lab affiliates Nokia, -NVIDIA, Oracle, and Samsung. -
ASPIRE Lab: -DARPA PERFECT program (Award #HR0011-12-2-0016), with additional support from -ASPIRE industrial sponsor Intel and ASPIRE affiliates Google, Nokia, NVIDIA, -Oracle, and Samsung. -
-
-

- -

-The following applies to the whole of SoftFloat Release 3e as well -as to each source file individually. -

- -

-Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the -University of California. -All rights reserved. -

- -

-Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: -

    - -
  1. -

    -Redistributions of source code must retain the above copyright notice, this -list of conditions, and the following disclaimer. -

    - -
  2. -

    -Redistributions in binary form must reproduce the above copyright notice, this -list of conditions, and the following disclaimer in the documentation and/or -other materials provided with the distribution. -

    - -
  3. -

    -Neither the name of the University nor the names of its contributors may be -used to endorse or promote products derived from this software without specific -prior written permission. -

    - -
-

- -

-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS”, -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. -IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -

- - -

4. Types and Functions

- -

-The types and functions of SoftFloat are declared in header file -softfloat.h. -

- -

4.1. Boolean and Integer Types

- -

-Header file softfloat.h depends on standard headers -<stdbool.h> and <stdint.h> to define type -bool and several integer types. -These standard headers have been part of the ISO C Standard Library since 1999. -With any recent compiler, they are likely to be supported, even if the compiler -does not claim complete conformance to the latest ISO C Standard. -For older or nonstandard compilers, a port of SoftFloat may have substitutes -for these headers. -Header softfloat.h depends only on the name bool from -<stdbool.h> and on these type names from -<stdint.h>: -

-
-uint16_t
-uint32_t
-uint64_t
-int32_t
-int64_t
-uint_fast8_t
-uint_fast32_t
-uint_fast64_t
-int_fast32_t
-int_fast64_t
-
-
-

- - -

4.2. Floating-Point Types

- -

-The softfloat.h header defines five floating-point types: -

- - - - - - - - - - - - - - - - - - - - - -
float16_t16-bit half-precision binary format
float32_t32-bit single-precision binary format
float64_t64-bit double-precision binary format
extFloat80_t   80-bit double-extended-precision binary format (old Intel or -Motorola format)
float128_t128-bit quadruple-precision binary format
-
-The non-extended types are each exactly the size specified: -16 bits for float16_t, 32 bits for -float32_t, 64 bits for float64_t, and -128 bits for float128_t. -Aside from these size requirements, the definitions of all these types may -differ for different ports of SoftFloat to specific systems. -A given port of SoftFloat may or may not define some of the floating-point -types as aliases for the C standard types float, -double, and long double. -

- -

-Header file softfloat.h also defines a structure, -struct extFloat80M, for the representation of -80-bit double-extended-precision floating-point values in memory. -This structure is the same size as type extFloat80_t and contains -at least these two fields (not necessarily in this order): -

-
-uint16_t signExp;
-uint64_t signif;
-
-
-Field signExp contains the sign and exponent of the floating-point -value, with the sign in the most significant bit (bit 15) and the -encoded exponent in the other 15 bits. -Field signif is the complete 64-bit significand of -the floating-point value. -(In the usual encoding for 80-bit extended floating-point, the -leading 1 bit of normalized numbers is not implicit but is stored -in the most significant bit of the significand.) -

- -

4.3. Supported Floating-Point Functions

- -

-SoftFloat implements these arithmetic operations for its floating-point types: -

    -
  • -conversions between any two floating-point formats; -
  • -for each floating-point format, conversions to and from signed and unsigned -32-bit and 64-bit integers; -
  • -for each format, the usual addition, subtraction, multiplication, division, and -square root operations; -
  • -for each format except extFloat80_t, the fused multiply-add -operation defined by the IEEE Standard; -
  • -for each format, the floating-point remainder operation defined by the IEEE -Standard; -
  • -for each format, a “round to integer” operation that rounds to the -nearest integer value in the same format; and -
  • -comparisons between two values in the same floating-point format. -
-

- -

-The following operations required by the 2008 IEEE Floating-Point Standard are -not supported in SoftFloat Release 3e: -

    -
  • -nextUp, nextDown, minNum, maxNum, minNumMag, -maxNumMag, scaleB, and logB; -
  • -conversions between floating-point formats and decimal or hexadecimal character -sequences; -
  • -all “quiet-computation” operations (copy, negate, -abs, and copySign, which all involve only simple copying and/or -manipulation of the floating-point sign bit); and -
  • -all “non-computational” operations other than isSignaling -(which is supported). -
-

- -

4.4. Non-canonical Representations in extFloat80_t

- -

-Because the 80-bit double-extended-precision format, -extFloat80_t, stores an explicit leading significand bit, many -finite floating-point numbers are encodable in this type in multiple equivalent -forms. -Of these multiple encodings, there is always a unique one with the least -encoded exponent value, and this encoding is considered the canonical -representation of the floating-point number. -Any other equivalent representations (having a higher encoded exponent value) -are non-canonical. -For a value in the subnormal range (including zero), the canonical -representation always has an encoded exponent of zero and a leading significand -bit of 0. -For finite values outside the subnormal range, the canonical representation -always has an encoded exponent that is nonzero and a leading significand bit -of 1. -

- -

-For an infinity or NaN, the leading significand bit is similarly expected to -be 1. -An infinity or NaN with a leading significand bit of 0 is again -considered non-canonical. -Hence, altogether, to be canonical, a value of type extFloat80_t -must have a leading significand bit of 1, unless the value is -subnormal or zero, in which case the leading significand bit and the encoded -exponent must both be zero. -

- -

-SoftFloat’s functions are not guaranteed to operate as expected when -inputs of type extFloat80_t are non-canonical. -Assuming all of a function’s extFloat80_t inputs (if any) -are canonical, function outputs of type extFloat80_t will always -be canonical. -

- -

4.5. Conventions for Passing Arguments and Results

- -

-Values that are at most 64 bits in size (i.e., not the -80-bit or 128-bit floating-point formats) are in all -cases passed as function arguments by value. -Likewise, when an output of a function is no more than 64 bits, it -is always returned directly as the function result. -Thus, for example, the SoftFloat function for adding two 64-bit -floating-point values has this simple signature: -

-float64_t f64_add( float64_t, float64_t ); -
-

- -

-The story is more complex when function inputs and outputs are -80-bit and 128-bit floating-point. -For these types, SoftFloat always provides a function that passes these larger -values into or out of the function indirectly, via pointers. -For example, for adding two 128-bit floating-point values, -SoftFloat supplies this function: -

-void f128M_add( const float128_t *, const float128_t *, float128_t * ); -
-The first two arguments point to the values to be added, and the last argument -points to the location where the sum will be stored. -The M in the name f128M_add is mnemonic for the fact -that the 128-bit inputs and outputs are “in memory”, -pointed to by pointer arguments. -

- -

-All ports of SoftFloat implement these pass-by-pointer functions for -types extFloat80_t and float128_t. -At the same time, SoftFloat ports may also implement alternate versions of -these same functions that pass extFloat80_t and -float128_t by value, like the smaller formats. -Thus, besides the function with name f128M_add shown above, a -SoftFloat port may also supply an equivalent function with this signature: -

-float128_t f128_add( float128_t, float128_t ); -
-

- -

-As a general rule, on computers where the machine word size is -32 bits or smaller, only the pass-by-pointer versions of functions -(e.g., f128M_add) are provided for types extFloat80_t -and float128_t, because passing such large types directly can have -significant extra cost. -On computers where the word size is 64 bits or larger, both -function versions (f128M_add and f128_add) are -provided, because the cost of passing by value is then more reasonable. -Applications that must be portable accross both classes of computers must use -the pointer-based functions, as these are always implemented. -However, if it is known that SoftFloat includes the by-value functions for all -platforms of interest, programmers can use whichever version they prefer. -

- - -

5. Reserved Names

- -

-In addition to the variables and functions documented here, SoftFloat defines -some symbol names for its own private use. -These private names always begin with the prefix -‘softfloat_’. -When a program includes header softfloat.h or links with the -SoftFloat library, all names with prefix ‘softfloat_’ -are reserved for possible use by SoftFloat. -Applications that use SoftFloat should not define their own names with this -prefix, and should reference only such names as are documented. -

- - -

6. Mode Variables

- -

-The following global variables control rounding mode, underflow detection, and -the 80-bit extended format’s rounding precision: -

-softfloat_roundingMode
-softfloat_detectTininess
-extF80_roundingPrecision -
-These mode variables are covered in the next several subsections. -For some SoftFloat ports, these variables may be per-thread (declared -thread_local), meaning that different execution threads have their -own separate copies of the variables. -

- -

6.1. Rounding Mode

- -

-All five rounding modes defined by the 2008 IEEE Floating-Point Standard are -implemented for all operations that require rounding. -Some ports of SoftFloat may also implement the round-to-odd mode. -

- -

-The rounding mode is selected by the global variable -

-uint_fast8_t softfloat_roundingMode; -
-This variable may be set to one of the values -
- - - - - - - - - - - - - - - - - - - - - - - - - -
softfloat_round_near_evenround to nearest, with ties to even
softfloat_round_near_maxMag  round to nearest, with ties to maximum magnitude (away from zero)
softfloat_round_minMaground to minimum magnitude (toward zero)
softfloat_round_minround to minimum (down)
softfloat_round_maxround to maximum (up)
softfloat_round_oddround to odd (jamming), if supported by the SoftFloat port
-
-Variable softfloat_roundingMode is initialized to -softfloat_round_near_even. -

- -

-When softfloat_round_odd is the rounding mode for a function that -rounds to an integer value (either conversion to an integer format or a -‘roundToInt’ function), if the input is not already an -integer, the rounded result is the closest odd integer. -For other operations, this rounding mode acts as though the floating-point -result is first rounded to minimum magnitude, the same as -softfloat_round_minMag, and then, if the result is inexact, the -least-significant bit of the result is set to 1. -Rounding to odd is also known as jamming. -

- -

6.2. Underflow Detection

- -

-In the terminology of the IEEE Standard, SoftFloat can detect tininess for -underflow either before or after rounding. -The choice is made by the global variable -

-uint_fast8_t softfloat_detectTininess; -
-which can be set to either -
-softfloat_tininess_beforeRounding
-softfloat_tininess_afterRounding -
-Detecting tininess after rounding is usually better because it results in fewer -spurious underflow signals. -The other option is provided for compatibility with some systems. -Like most systems (and as required by the newer 2008 IEEE Standard), SoftFloat -always detects loss of accuracy for underflow as an inexact result. -

- -

6.3. Rounding Precision for the 80-Bit Extended Format

- -

-For extFloat80_t only, the rounding precision of the basic -arithmetic operations is controlled by the global variable -

-uint_fast8_t extF80_roundingPrecision; -
-The operations affected are: -
-extF80_add
-extF80_sub
-extF80_mul
-extF80_div
-extF80_sqrt -
-When extF80_roundingPrecision is set to its default value of 80, -these operations are rounded to the full precision of the 80-bit -double-extended-precision format, like occurs for other formats. -Setting extF80_roundingPrecision to 32 or to 64 causes the -operations listed to be rounded to 32-bit precision (equivalent to -float32_t) or to 64-bit precision (equivalent to -float64_t), respectively. -When rounding to reduced precision, additional bits in the result significand -beyond the rounding point are set to zero. -The consequences of setting extF80_roundingPrecision to a value -other than 32, 64, or 80 is not specified. -Operations other than the ones listed above are not affected by -extF80_roundingPrecision. -

- - -

7. Exceptions and Exception Flags

- -

-All five exception flags required by the IEEE Floating-Point Standard are -implemented. -Each flag is stored as a separate bit in the global variable -

-uint_fast8_t softfloat_exceptionFlags; -
-The positions of the exception flag bits within this variable are determined by -the bit masks -
-softfloat_flag_inexact
-softfloat_flag_underflow
-softfloat_flag_overflow
-softfloat_flag_infinite
-softfloat_flag_invalid -
-Variable softfloat_exceptionFlags is initialized to all zeros, -meaning no exceptions. -

- -

-For some SoftFloat ports, softfloat_exceptionFlags may be -per-thread (declared thread_local), meaning that different -execution threads have their own separate instances of it. -

- -

-An individual exception flag can be cleared with the statement -

-softfloat_exceptionFlags &= ~softfloat_flag_<exception>; -
-where <exception> is the appropriate name. -To raise a floating-point exception, function softfloat_raiseFlags -should normally be used. -

- -

-When SoftFloat detects an exception other than inexact, it calls -softfloat_raiseFlags. -The default version of this function simply raises the corresponding exception -flags. -Particular ports of SoftFloat may support alternate behavior, such as exception -traps, by modifying the default softfloat_raiseFlags. -A program may also supply its own softfloat_raiseFlags function to -override the one from the SoftFloat library. -

- -

-Because inexact results occur frequently under most circumstances (and thus are -hardly exceptional), SoftFloat does not ordinarily call -softfloat_raiseFlags for inexact exceptions. -It does always raise the inexact exception flag as required. -

- - -

8. Function Details

- -

-In this section, <float> appears in function names as -a substitute for one of these abbreviations: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
f16indicates float16_t, passed by value
f32indicates float32_t, passed by value
f64indicates float64_t, passed by value
extF80M   indicates extFloat80_t, passed indirectly via pointers
extF80indicates extFloat80_t, passed by value
f128Mindicates float128_t, passed indirectly via pointers
f128indicates float128_t, passed by value
-
-The circumstances under which values of floating-point types -extFloat80_t and float128_t may be passed either by -value or indirectly via pointers was discussed earlier in -section 4.5, Conventions for Passing Arguments and Results. -

- -

8.1. Conversions from Integer to Floating-Point

- -

-All conversions from a 32-bit or 64-bit integer, -signed or unsigned, to a floating-point format are supported. -Functions performing these conversions have these names: -

-ui32_to_<float>
-ui64_to_<float>
-i32_to_<float>
-i64_to_<float> -
-Conversions from 32-bit integers to 64-bit -double-precision and larger formats are always exact, and likewise conversions -from 64-bit integers to 80-bit -double-extended-precision and 128-bit quadruple-precision are also -always exact. -

- -

-Each conversion function takes one input of the appropriate type and generates -one output. -The following illustrates the signatures of these functions in cases when the -floating-point result is passed either by value or via pointers: -

-
-float64_t i32_to_f64( int32_t a );
-
-
-void i32_to_f128M( int32_t a, float128_t *destPtr );
-
-
-

- -

8.2. Conversions from Floating-Point to Integer

- -

-Conversions from a floating-point format to a 32-bit or -64-bit integer, signed or unsigned, are supported with these -functions: -

-<float>_to_ui32
-<float>_to_ui64
-<float>_to_i32
-<float>_to_i64 -
-The functions have signatures as follows, depending on whether the -floating-point input is passed by value or via pointers: -
-
-int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact );
-
-
-int_fast32_t
- f128M_to_i32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact );
-
-
-

- -

-The roundingMode argument specifies the rounding mode for -the conversion. -The variable that usually indicates rounding mode, -softfloat_roundingMode, is ignored. -Argument exact determines whether the inexact -exception flag is raised if the conversion is not exact. -If exact is true, the inexact flag may -be raised; -otherwise, it will not be, even if the conversion is inexact. -

- -

-A conversion from floating-point to integer format raises the invalid -exception if the source value cannot be rounded to a representable integer of -the desired size (32 or 64 bits). -In such circumstances, the integer result returned is determined by the -particular port of SoftFloat, although typically this value will be either the -maximum or minimum value of the integer format. -The functions that convert to integer types never raise the floating-point -overflow exception. -

- -

-Because languages such as C require that conversions to integers -be rounded toward zero, the following functions are provided for improved speed -and convenience: -

-<float>_to_ui32_r_minMag
-<float>_to_ui64_r_minMag
-<float>_to_i32_r_minMag
-<float>_to_i64_r_minMag -
-These functions round only toward zero (to minimum magnitude). -The signatures for these functions are the same as above without the redundant -roundingMode argument: -
-
-int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact );
-
-
-int_fast32_t f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact );
-
-
-

- -

8.3. Conversions Among Floating-Point Types

- -

-Conversions between floating-point formats are done by functions with these -names: -

-<float>_to_<float> -
-All combinations of source and result type are supported where the source and -result are different formats. -There are four different styles of signature for these functions, depending on -whether the input and the output floating-point values are passed by value or -via pointers: -
-
-float32_t f64_to_f32( float64_t a );
-
-
-float32_t f128M_to_f32( const float128_t *aPtr );
-
-
-void f32_to_f128M( float32_t a, float128_t *destPtr );
-
-
-void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *destPtr );
-
-
-

- -

-Conversions from a smaller to a larger floating-point format are always exact -and so require no rounding. -

- -

8.4. Basic Arithmetic Functions

- -

-The following basic arithmetic functions are provided: -

-<float>_add
-<float>_sub
-<float>_mul
-<float>_div
-<float>_sqrt -
-Each floating-point operation takes two operands, except for sqrt -(square root) which takes only one. -The operands and result are all of the same floating-point format. -Signatures for these functions take the following forms: -
-
-float64_t f64_add( float64_t a, float64_t b );
-
-
-void
- f128M_add(
-     const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
-
-
-float64_t f64_sqrt( float64_t a );
-
-
-void f128M_sqrt( const float128_t *aPtr, float128_t *destPtr );
-
-
-When floating-point values are passed indirectly through pointers, arguments -aPtr and bPtr point to the input -operands, and the last argument, destPtr, points to the -location where the result is stored. -

- -

-Rounding of the 80-bit double-extended-precision -(extFloat80_t) functions is affected by variable -extF80_roundingPrecision, as explained earlier in -section 6.3, -Rounding Precision for the 80-Bit Extended Format. -

- -

8.5. Fused Multiply-Add Functions

- -

-The 2008 version of the IEEE Floating-Point Standard defines a fused -multiply-add operation that does a combined multiplication and addition -with only a single rounding. -SoftFloat implements fused multiply-add with functions -

-<float>_mulAdd -
-Unlike other operations, fused multiple-add is not supported for the -80-bit double-extended-precision format, -extFloat80_t. -

- -

-Depending on whether floating-point values are passed by value or via pointers, -the fused multiply-add functions have signatures of these forms: -

-
-float64_t f64_mulAdd( float64_t a, float64_t b, float64_t c );
-
-
-void
- f128M_mulAdd(
-     const float128_t *aPtr,
-     const float128_t *bPtr,
-     const float128_t *cPtr,
-     float128_t *destPtr
- );
-
-
-The functions compute -(a × b) - + c -with a single rounding. -When floating-point values are passed indirectly through pointers, arguments -aPtr, bPtr, and -cPtr point to operands a, -b, and c respectively, and -destPtr points to the location where the result is stored. -

- -

-If one of the multiplication operands a and -b is infinite and the other is zero, these functions raise -the invalid exception even if operand c is a quiet NaN. -

- -

8.6. Remainder Functions

- -

-For each format, SoftFloat implements the remainder operation defined by the -IEEE Floating-Point Standard. -The remainder functions have names -

-<float>_rem -
-Each remainder operation takes two floating-point operands of the same format -and returns a result in the same format. -Depending on whether floating-point values are passed by value or via pointers, -the remainder functions have signatures of these forms: -
-
-float64_t f64_rem( float64_t a, float64_t b );
-
-
-void
- f128M_rem(
-     const float128_t *aPtr, const float128_t *bPtr, float128_t *destPtr );
-
-
-When floating-point values are passed indirectly through pointers, arguments -aPtr and bPtr point to operands -a and b respectively, and -destPtr points to the location where the result is stored. -

- -

-The IEEE Standard remainder operation computes the value -a - − n × b, -where n is the integer closest to -a ÷ b. -If a ÷ b is exactly -halfway between two integers, n is the even integer closest to -a ÷ b. -The IEEE Standard’s remainder operation is always exact and so requires -no rounding. -

- -

-Depending on the relative magnitudes of the operands, the remainder -functions can take considerably longer to execute than the other SoftFloat -functions. -This is an inherent characteristic of the remainder operation itself and is not -a flaw in the SoftFloat implementation. -

- -

8.7. Round-to-Integer Functions

- -

-For each format, SoftFloat implements the round-to-integer operation specified -by the IEEE Floating-Point Standard. -These functions are named -

-<float>_roundToInt -
-Each round-to-integer operation takes a single floating-point operand. -This operand is rounded to an integer according to a specified rounding mode, -and the resulting integer value is returned in the same floating-point format. -(Note that the result is not an integer type.) -

- -

-The signatures of the round-to-integer functions are similar to those for -conversions to an integer type: -

-
-float64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact );
-
-
-void
- f128M_roundToInt(
-     const float128_t *aPtr,
-     uint_fast8_t roundingMode,
-     bool exact,
-     float128_t *destPtr
- );
-
-
-When floating-point values are passed indirectly through pointers, -aPtr points to the input operand and -destPtr points to the location where the result is stored. -

- -

-The roundingMode argument specifies the rounding mode to -apply. -The variable that usually indicates rounding mode, -softfloat_roundingMode, is ignored. -Argument exact determines whether the inexact -exception flag is raised if the conversion is not exact. -If exact is true, the inexact flag may -be raised; -otherwise, it will not be, even if the conversion is inexact. -

- -

8.8. Comparison Functions

- -

-For each format, the following floating-point comparison functions are -provided: -

-<float>_eq
-<float>_le
-<float>_lt -
-Each comparison takes two operands of the same type and returns a Boolean. -The abbreviation eq stands for “equal” (=); -le stands for “less than or equal” (≤); -and lt stands for “less than” (<). -Depending on whether the floating-point operands are passed by value or via -pointers, the comparison functions have signatures of these forms: -
-
-bool f64_eq( float64_t a, float64_t b );
-
-
-bool f128M_eq( const float128_t *aPtr, const float128_t *bPtr );
-
-
-

- -

-The usual greater-than (>), greater-than-or-equal (≥), and not-equal -(≠) comparisons are easily obtained from the functions provided. -The not-equal function is just the logical complement of the equal function. -The greater-than-or-equal function is identical to the less-than-or-equal -function with the arguments in reverse order, and likewise the greater-than -function is identical to the less-than function with the arguments reversed. -

- -

-The IEEE Floating-Point Standard specifies that the less-than-or-equal and -less-than comparisons by default raise the invalid exception if either -operand is any kind of NaN. -Equality comparisons, on the other hand, are defined by default to raise the -invalid exception only for signaling NaNs, not quiet NaNs. -For completeness, SoftFloat provides these complementary functions: -

-<float>_eq_signaling
-<float>_le_quiet
-<float>_lt_quiet -
-The signaling equality comparisons are identical to the default -equality comparisons except that the invalid exception is raised for any -NaN input, not just for signaling NaNs. -Similarly, the quiet comparison functions are identical to their -default counterparts except that the invalid exception is not raised for -quiet NaNs. -

- -

8.9. Signaling NaN Test Functions

- -

-Functions for testing whether a floating-point value is a signaling NaN are -provided with these names: -

-<float>_isSignalingNaN -
-The functions take one floating-point operand and return a Boolean indicating -whether the operand is a signaling NaN. -Accordingly, the functions have the forms -
-
-bool f64_isSignalingNaN( float64_t a );
-
-
-bool f128M_isSignalingNaN( const float128_t *aPtr );
-
-
-

- -

8.10. Raise-Exception Function

- -

-SoftFloat provides a single function for raising floating-point exceptions: -

-
-void softfloat_raiseFlags( uint_fast8_t exceptions );
-
-
-The exceptions argument is a mask indicating the set of -exceptions to raise. -(See earlier section 7, Exceptions and Exception Flags.) -In addition to setting the specified exception flags in variable -softfloat_exceptionFlags, the softfloat_raiseFlags -function may cause a trap or abort appropriate for the current system. -

- - -

9. Changes from SoftFloat Release 2

- -

-Apart from a change in the legal use license, Release 3 of -SoftFloat introduced numerous technical differences compared to earlier -releases. -

- -

9.1. Name Changes

- -

-The most obvious and pervasive difference compared to Release 2 -is that the names of most functions and variables have changed, even when the -behavior has not. -First, the floating-point types, the mode variables, the exception flags -variable, the function to raise exceptions, and various associated constants -have been renamed as follows: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
old name, Release 2:new name, Release 3:
float32float32_t
float64float64_t
floatx80extFloat80_t
float128float128_t
float_rounding_modesoftfloat_roundingMode
float_round_nearest_evensoftfloat_round_near_even
float_round_to_zerosoftfloat_round_minMag
float_round_downsoftfloat_round_min
float_round_upsoftfloat_round_max
float_detect_tininesssoftfloat_detectTininess
float_tininess_before_rounding    softfloat_tininess_beforeRounding
float_tininess_after_roundingsoftfloat_tininess_afterRounding
floatx80_rounding_precisionextF80_roundingPrecision
float_exception_flagssoftfloat_exceptionFlags
float_flag_inexactsoftfloat_flag_inexact
float_flag_underflowsoftfloat_flag_underflow
float_flag_overflowsoftfloat_flag_overflow
float_flag_divbyzerosoftfloat_flag_infinite
float_flag_invalidsoftfloat_flag_invalid
float_raisesoftfloat_raiseFlags
-
-

- -

-Furthermore, Release 3 adopted the following new abbreviations for -function names: -

- - - - - - - - - - - -
used in names in Release 2:    used in names in Release 3:
int32 i32
int64 i64
float32 f32
float64 f64
floatx80 extF80
float128 f128
-
-Thus, for example, the function to add two 32-bit floating-point -numbers, previously called float32_add in Release 2, -is now f32_add. -Lastly, there have been a few other changes to function names: -
- - - - - - - - - - - - - - - - - - - - - -
used in names in Release 2:   used in names in Release 3:   relevant functions:
_round_to_zero_r_minMagconversions from floating-point to integer (section 8.2)
round_to_introundToIntround-to-integer functions (section 8.7)
is_signaling_nan    isSignalingNaNsignaling NaN test functions (section 8.9)
-
-

- -

9.2. Changes to Function Arguments

- -

-Besides simple name changes, some operations were given a different interface -in Release 3 than they had in Release 2: -

    - -
  • -

    -Since Release 3, integer arguments and results of functions have -standard types from header <stdint.h>, such as -uint32_t, whereas previously their types could be defined -differently for each port of SoftFloat, usually using traditional C types such -as unsigned int. -Likewise, functions in Release 3 and later pass Booleans as -standard type bool from <stdbool.h>, whereas -previously these were again passed as a port-specific type (usually -int). -

    - -
  • -

    -As explained earlier in section 4.5, Conventions for Passing -Arguments and Results, SoftFloat functions in Release 3 and -later may pass 80-bit and 128-bit floating-point -values through pointers, meaning that functions take pointer arguments and then -read or write floating-point values at the locations indicated by the pointers. -In Release 2, floating-point arguments and results were always -passed by value, regardless of their size. -

    - -
  • -

    -Functions that round to an integer have additional -roundingMode and exact arguments that -they did not have in Release 2. -Refer to sections 8.2 and 8.7 for descriptions of these functions -since Release 3. -For Release 2, the rounding mode, when needed, was taken from the -same global variable that affects the basic arithmetic operations (now called -softfloat_roundingMode but previously known as -float_rounding_mode). -Also, for Release 2, if the original floating-point input was not -an exact integer value, and if the invalid exception was not raised by -the function, the inexact exception was always raised. -Release 2 had no option to suppress raising inexact in this -case. -Applications using SoftFloat Release 3 or later can get the same -effect as Release 2 by passing variable -softfloat_roundingMode for argument -roundingMode and true for argument -exact. -

    - -
-

- -

9.3. Added Capabilities

- -

-With Release 3, some new features have been added that were not -present in Release 2: -

    - -
  • -

    -A port of SoftFloat can now define any of the floating-point types -float32_t, float64_t, extFloat80_t, and -float128_t as aliases for C’s standard floating-point types -float, double, and long -double, using either #define or typedef. -This potential convenience was not supported under Release 2. -

    - -

    -(Note, however, that there may be a performance cost to defining -SoftFloat’s floating-point types this way, depending on the platform and -the applications using SoftFloat. -Ports of SoftFloat may choose to forgo the convenience in favor of better -speed.) -

    - -

    -

  • -As of Release 3b, 16-bit half-precision, -float16_t, is supported. -

    - -

    -

  • -Functions have been added for converting between the floating-point types and -unsigned integers. -Release 2 supported only signed integers, not unsigned. -

    - -

    -

  • -Fused multiply-add functions have been added for all floating-point formats -except 80-bit double-extended-precision, -extFloat80_t. -

    - -

    -

  • -New rounding modes are supported: -softfloat_round_near_maxMag (round to nearest, with ties to -maximum magnitude, away from zero), and, as of Release 3c, -optional softfloat_round_odd (round to odd, also known as -jamming). -

    - -
-

- -

9.4. Better Compatibility with the C Language

- -

-Release 3 of SoftFloat was written to conform better to the ISO C -Standard’s rules for portability. -For example, older releases of SoftFloat employed type conversions in ways -that, while commonly practiced, are not fully defined by the C Standard. -Such problematic type conversions have generally been replaced by the use of -unions, the behavior around which is more strictly regulated these days. -

- -

9.5. New Organization as a Library

- -

-Starting with Release 3, SoftFloat now builds as a library. -Previously, SoftFloat compiled into a single, monolithic object file containing -all the SoftFloat functions, with the consequence that a program linking with -SoftFloat would get every SoftFloat function in its binary file even if only a -few functions were actually used. -With SoftFloat in the form of a library, a program that is linked by a standard -linker will include only those functions of SoftFloat that it needs and no -others. -

- -

9.6. Optimization Gains (and Losses)

- -

-Individual SoftFloat functions have been variously improved in -Release 3 compared to earlier releases. -In particular, better, faster algorithms have been deployed for the operations -of division, square root, and remainder. -For functions operating on the larger 80-bit and -128-bit formats, extFloat80_t and -float128_t, code size has also generally been reduced. -

- -

-However, because Release 2 compiled all of SoftFloat together as a -single object file, compilers could make optimizations across function calls -when one SoftFloat function calls another. -Now that the functions of SoftFloat are compiled separately and only afterward -linked together into a program, there is not usually the same opportunity to -optimize across function calls. -Some loss of speed has been observed due to this change. -

- - -

10. Future Directions

- -

-The following improvements are anticipated for future releases of SoftFloat: -

    -
  • -more functions from the 2008 version of the IEEE Floating-Point Standard; -
  • -consistent, defined behavior for non-canonical representations of extended -format extFloat80_t (discussed in section 4.4, -Non-canonical Representations in extFloat80_t). - -
-

- - -

11. Contact Information

- -

-At the time of this writing, the most up-to-date information about SoftFloat -and the latest release can be found at the Web page -http://www.jhauser.us/arithmetic/SoftFloat.html. -

- - - - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/extF80M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/extF80M_isSignalingNaN.c deleted file mode 100644 index c2cca65c9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/extF80M_isSignalingNaN.c +++ /dev/null @@ -1,57 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool extF80M_isSignalingNaN( const extFloat80_t *aPtr ) -{ - const struct extFloat80M *aSPtr; - uint64_t uiA0; - - aSPtr = (const struct extFloat80M *) aPtr; - if ( (aSPtr->signExp & 0x7FFF) != 0x7FFF ) return false; - uiA0 = aSPtr->signif; - return - ! (uiA0 & UINT64_C( 0x4000000000000000 )) - && (uiA0 & UINT64_C( 0x3FFFFFFFFFFFFFFF)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/f128M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/f128M_isSignalingNaN.c deleted file mode 100644 index 9ff83d726..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/f128M_isSignalingNaN.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool f128M_isSignalingNaN( const float128_t *aPtr ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - if ( (uiA96 & 0x7FFF8000) != 0x7FFF0000 ) return false; - return - ((uiA96 & 0x00007FFF) != 0) - || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )]) - != 0); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToExtF80M.c deleted file mode 100644 index 06302aa15..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToExtF80M.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| `zSPtr'. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) -{ - - zSPtr->signExp = packToExtF80UI64( aPtr->sign, 0x7FFF ); - zSPtr->signif = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToExtF80UI.c deleted file mode 100644 index 7325468ff..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToExtF80UI.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ.v64 = (uint_fast16_t) aPtr->sign<<15 | 0x7FFF; - uiZ.v0 = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF128M.c deleted file mode 100644 index e2940bb77..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF128M.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by `zWPtr'. Argument -| `zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) -{ - - softfloat_shortShiftRight128M( (const uint32_t *) &aPtr->v0, 16, zWPtr ); - zWPtr[indexWordHi( 4 )] |= (uint32_t) aPtr->sign<<31 | 0x7FFF8000; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF128UI.c deleted file mode 100644 index ac8ea7b70..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF128UI.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ = softfloat_shortShiftRight128( aPtr->v64, aPtr->v0, 16 ); - uiZ.v64 |= (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FFF800000000000 ); - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF16UI.c deleted file mode 100644 index 07679d717..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF16UI.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 16-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ) -{ - - return (uint_fast16_t) aPtr->sign<<15 | 0x7E00 | aPtr->v64>>54; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF32UI.c deleted file mode 100644 index 982c1edf6..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF32UI.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ) -{ - - return (uint_fast32_t) aPtr->sign<<31 | 0x7FC00000 | aPtr->v64>>41; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF64UI.c deleted file mode 100644 index d88c68ade..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_commonNaNToF64UI.c +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 64-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ) -{ - - return - (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FF8000000000000 ) - | aPtr->v64>>12; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_extF80MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_extF80MToCommonNaN.c deleted file mode 100644 index 6bf45cf86..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_extF80MToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the 80-bit extended floating-point value pointed to by `aSPtr' is -| a NaN, converts this NaN to the common NaN form, and stores the resulting -| common NaN at the location pointed to by `zPtr'. If the NaN is a signaling -| NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80MToCommonNaN( - const struct extFloat80M *aSPtr, struct commonNaN *zPtr ) -{ - - if ( extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = signExtF80UI64( aSPtr->signExp ); - zPtr->v64 = aSPtr->signif<<1; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_extF80UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_extF80UIToCommonNaN.c deleted file mode 100644 index 8b8c92780..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_extF80UIToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' -| has the bit pattern of an 80-bit extended floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80UIToCommonNaN( - uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA64>>15; - zPtr->v64 = uiA0<<1; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f128MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f128MToCommonNaN.c deleted file mode 100644 index 22152145a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f128MToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN, -| converts this NaN to the common NaN form, and stores the resulting common -| NaN at the location pointed to by `zPtr'. If the NaN is a signaling NaN, -| the invalid exception is raised. Argument `aWPtr' points to an array of -| four 32-bit elements that concatenate in the platform's normal endian order -| to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr ) -{ - - if ( f128M_isSignalingNaN( (const float128_t *) aWPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = aWPtr[indexWordHi( 4 )]>>31; - softfloat_shortShiftLeft128M( aWPtr, 16, (uint32_t *) &zPtr->v0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f128UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f128UIToCommonNaN.c deleted file mode 100644 index 2510c0707..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f128UIToCommonNaN.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' -| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to -| the common NaN form, and stores the resulting common NaN at the location -| pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_f128UIToCommonNaN( - uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ) -{ - struct uint128 NaNSig; - - if ( softfloat_isSigNaNF128UI( uiA64, uiA0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - NaNSig = softfloat_shortShiftLeft128( uiA64, uiA0, 16 ); - zPtr->sign = uiA64>>63; - zPtr->v64 = NaNSig.v64; - zPtr->v0 = NaNSig.v0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f16UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f16UIToCommonNaN.c deleted file mode 100644 index 4d5003f6a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f16UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming `uiA' has the bit pattern of a 16-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF16UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>15; - zPtr->v64 = (uint_fast64_t) uiA<<54; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f32UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f32UIToCommonNaN.c deleted file mode 100644 index f4734db7a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f32UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming `uiA' has the bit pattern of a 32-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF32UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>31; - zPtr->v64 = (uint_fast64_t) uiA<<41; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f64UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f64UIToCommonNaN.c deleted file mode 100644 index 9a481a74f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_f64UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming `uiA' has the bit pattern of a 64-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF64UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>63; - zPtr->v64 = uiA<<12; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNExtF80M.c deleted file mode 100644 index f35e06654..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNExtF80M.c +++ /dev/null @@ -1,107 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by `aSPtr' and `bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by `zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ) -{ - bool isSigNaNA; - const struct extFloat80M *sPtr; - bool isSigNaNB; - uint_fast16_t uiB64; - uint64_t uiB0; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiMagA64, uiMagB64; - - isSigNaNA = extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr ); - sPtr = aSPtr; - if ( ! bSPtr ) { - if ( isSigNaNA ) softfloat_raiseFlags( softfloat_flag_invalid ); - goto copy; - } - isSigNaNB = extF80M_isSignalingNaN( (const extFloat80_t *) bSPtr ); - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - uiB64 = bSPtr->signExp; - if ( isSigNaNB ) goto returnLargerUIMag; - uiB0 = bSPtr->signif; - if ( isNaNExtF80UI( uiB64, uiB0 ) ) goto copyB; - goto copy; - } else { - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) ) goto copy; - goto copyB; - } - } - uiB64 = bSPtr->signExp; - returnLargerUIMag: - uiA64 = aSPtr->signExp; - uiMagA64 = uiA64 & 0x7FFF; - uiMagB64 = uiB64 & 0x7FFF; - if ( uiMagA64 < uiMagB64 ) goto copyB; - if ( uiMagB64 < uiMagA64 ) goto copy; - uiA0 = aSPtr->signif; - uiB0 = bSPtr->signif; - if ( uiA0 < uiB0 ) goto copyB; - if ( uiB0 < uiA0 ) goto copy; - if ( uiA64 < uiB64 ) goto copy; - copyB: - sPtr = bSPtr; - copy: - zSPtr->signExp = sPtr->signExp; - zSPtr->signif = sPtr->signif | UINT64_C( 0xC000000000000000 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNExtF80UI.c deleted file mode 100644 index fa2daae2e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNExtF80UI.c +++ /dev/null @@ -1,106 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2018 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ) -{ - bool isSigNaNA, isSigNaNB; - uint_fast64_t uiNonsigA0, uiNonsigB0; - uint_fast16_t uiMagA64, uiMagB64; - struct uint128 uiZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isSigNaNA = softfloat_isSigNaNExtF80UI( uiA64, uiA0 ); - isSigNaNB = softfloat_isSigNaNExtF80UI( uiB64, uiB0 ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiNonsigA0 = uiA0 | UINT64_C( 0xC000000000000000 ); - uiNonsigB0 = uiB0 | UINT64_C( 0xC000000000000000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerMag; - if ( isNaNExtF80UI( uiB64, uiB0 ) ) goto returnB; - goto returnA; - } else { - if ( isNaNExtF80UI( uiA64, uiA0 ) ) goto returnA; - goto returnB; - } - } - returnLargerMag: - uiMagA64 = uiA64 & 0x7FFF; - uiMagB64 = uiB64 & 0x7FFF; - if ( uiMagA64 < uiMagB64 ) goto returnB; - if ( uiMagB64 < uiMagA64 ) goto returnA; - if ( uiA0 < uiB0 ) goto returnB; - if ( uiB0 < uiA0 ) goto returnA; - if ( uiA64 < uiB64 ) goto returnA; - returnB: - uiZ.v64 = uiB64; - uiZ.v0 = uiNonsigB0; - return uiZ; - returnA: - uiZ.v64 = uiA64; - uiZ.v0 = uiNonsigA0; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF128M.c deleted file mode 100644 index e8872742c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF128M.c +++ /dev/null @@ -1,76 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by `zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of `aWPtr', `bWPtr', -| and `zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) -{ - bool isSigNaNA; - const uint32_t *ptr; - - ptr = aWPtr; - isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr ); - if ( - isSigNaNA - || (bWPtr && f128M_isSignalingNaN( (const float128_t *) bWPtr )) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) goto copy; - } - if ( ! softfloat_isNaNF128M( aWPtr ) ) ptr = bWPtr; - copy: - zWPtr[indexWordHi( 4 )] = ptr[indexWordHi( 4 )] | 0x00008000; - zWPtr[indexWord( 4, 2 )] = ptr[indexWord( 4, 2 )]; - zWPtr[indexWord( 4, 1 )] = ptr[indexWord( 4, 1 )]; - zWPtr[indexWord( 4, 0 )] = ptr[indexWord( 4, 0 )]; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF128UI.c deleted file mode 100644 index fb0e862dc..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF128UI.c +++ /dev/null @@ -1,81 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating `uiA64' and -| `uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating `uiB64' and `uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ) -{ - bool isSigNaNA; - struct uint128 uiZ; - - isSigNaNA = softfloat_isSigNaNF128UI( uiA64, uiA0 ); - if ( isSigNaNA || softfloat_isSigNaNF128UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) goto returnNonsigA; - } - if ( isNaNF128UI( uiA64, uiA0 ) ) { - returnNonsigA: - uiZ.v64 = uiA64; - uiZ.v0 = uiA0; - } else { - uiZ.v64 = uiB64; - uiZ.v0 = uiB0; - } - uiZ.v64 |= UINT64_C( 0x0000800000000000 ); - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF16UI.c deleted file mode 100644 index 8e19e4301..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF16UI.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting `uiA' and `uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either `uiA' or `uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) -{ - bool isSigNaNA; - - isSigNaNA = softfloat_isSigNaNF16UI( uiA ); - if ( isSigNaNA || softfloat_isSigNaNF16UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) return uiA | 0x0200; - } - return (isNaNF16UI( uiA ) ? uiA : uiB) | 0x0200; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF32UI.c deleted file mode 100644 index 6e423cac6..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF32UI.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting `uiA' and `uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either `uiA' or `uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - bool isSigNaNA; - - isSigNaNA = softfloat_isSigNaNF32UI( uiA ); - if ( isSigNaNA || softfloat_isSigNaNF32UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) return uiA | 0x00400000; - } - return (isNaNF32UI( uiA ) ? uiA : uiB) | 0x00400000; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF64UI.c deleted file mode 100644 index 474c1967d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/s_propagateNaNF64UI.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either `uiA' or `uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) -{ - bool isSigNaNA; - - isSigNaNA = softfloat_isSigNaNF64UI( uiA ); - if ( isSigNaNA || softfloat_isSigNaNF64UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) return uiA | UINT64_C( 0x0008000000000000 ); - } - return (isNaNF64UI( uiA ) ? uiA : uiB) | UINT64_C( 0x0008000000000000 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/softfloat_raiseFlags.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/softfloat_raiseFlags.c deleted file mode 100644 index 7a1aee930..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/softfloat_raiseFlags.c +++ /dev/null @@ -1,52 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Raises the exceptions specified by `flags'. Floating-point traps can be -| defined here if desired. It is currently not possible for such a trap -| to substitute a result value. If traps are not implemented, this routine -| should be simply `softfloat_exceptionFlags |= flags;'. -*----------------------------------------------------------------------------*/ -void softfloat_raiseFlags( uint_fast8_t flags ) -{ - - softfloat_exceptionFlags |= flags; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/specialize.h b/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/specialize.h deleted file mode 100644 index a9166e170..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086-SSE/specialize.h +++ /dev/null @@ -1,376 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2018 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef specialize_h -#define specialize_h 1 - -#include -#include -#include "primitiveTypes.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Default value for 'softfloat_detectTininess'. -*----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_afterRounding - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 32-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui32_fromPosOverflow 0xFFFFFFFF -#define ui32_fromNegOverflow 0xFFFFFFFF -#define ui32_fromNaN 0xFFFFFFFF -#define i32_fromPosOverflow (-0x7FFFFFFF - 1) -#define i32_fromNegOverflow (-0x7FFFFFFF - 1) -#define i32_fromNaN (-0x7FFFFFFF - 1) - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 64-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define i64_fromPosOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNaN (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) - -/*---------------------------------------------------------------------------- -| "Common NaN" structure, used to transfer NaN representations from one format -| to another. -*----------------------------------------------------------------------------*/ -struct commonNaN { - bool sign; -#ifdef LITTLEENDIAN - uint64_t v0, v64; -#else - uint64_t v64, v0; -#endif -}; - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 16-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF16UI 0xFE00 - -/*---------------------------------------------------------------------------- -| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a -| 16-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 32-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF32UI 0xFFC00000 - -/*---------------------------------------------------------------------------- -| Returns true when 32-bit unsigned integer 'uiA' has the bit pattern of a -| 32-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 64-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF64UI UINT64_C( 0xFFF8000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a -| 64-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 80-bit extended floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNExtF80UI64 0xFFFF -#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 80-bit unsigned integer formed from concatenating -| 16-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of an 80-bit extended -| floating-point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) - -#ifdef SOFTFLOAT_FAST_INT64 - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of an 80-bit extended floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80UIToCommonNaN( - uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 ) -#define defaultNaNF128UI0 UINT64_C( 0 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 128-bit unsigned integer formed from concatenating -| 64-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of a 128-bit floating- -| point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to -| the common NaN form, and stores the resulting common NaN at the location -| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_f128UIToCommonNaN( - uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ); - -#else - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is not -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the 80-bit extended floating-point value pointed to by 'aSPtr' is -| a NaN, converts this NaN to the common NaN form, and stores the resulting -| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling -| NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80MToCommonNaN( - const struct extFloat80M *aSPtr, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| 'zSPtr'. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ); - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by 'aSPtr' and 'bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by 'zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI96 0xFFFF8000 -#define defaultNaNF128UI64 0 -#define defaultNaNF128UI32 0 -#define defaultNaNF128UI0 0 - -/*---------------------------------------------------------------------------- -| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, -| converts this NaN to the common NaN form, and stores the resulting common -| NaN at the location pointed to by 'zPtr'. If the NaN is a signaling NaN, -| the invalid exception is raised. Argument 'aWPtr' points to an array of -| four 32-bit elements that concatenate in the platform's normal endian order -| to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by 'zWPtr'. Argument -| 'zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ); - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| 'aWPtr' and 'bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by 'zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of 'aWPtr', 'bWPtr', -| and 'zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ); - -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/extF80M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/extF80M_isSignalingNaN.c deleted file mode 100644 index c2cca65c9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/extF80M_isSignalingNaN.c +++ /dev/null @@ -1,57 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool extF80M_isSignalingNaN( const extFloat80_t *aPtr ) -{ - const struct extFloat80M *aSPtr; - uint64_t uiA0; - - aSPtr = (const struct extFloat80M *) aPtr; - if ( (aSPtr->signExp & 0x7FFF) != 0x7FFF ) return false; - uiA0 = aSPtr->signif; - return - ! (uiA0 & UINT64_C( 0x4000000000000000 )) - && (uiA0 & UINT64_C( 0x3FFFFFFFFFFFFFFF)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/f128M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/f128M_isSignalingNaN.c deleted file mode 100644 index 9ff83d726..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/f128M_isSignalingNaN.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool f128M_isSignalingNaN( const float128_t *aPtr ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - if ( (uiA96 & 0x7FFF8000) != 0x7FFF0000 ) return false; - return - ((uiA96 & 0x00007FFF) != 0) - || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )]) - != 0); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToExtF80M.c deleted file mode 100644 index 06302aa15..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToExtF80M.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| `zSPtr'. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) -{ - - zSPtr->signExp = packToExtF80UI64( aPtr->sign, 0x7FFF ); - zSPtr->signif = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToExtF80UI.c deleted file mode 100644 index 7325468ff..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToExtF80UI.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ.v64 = (uint_fast16_t) aPtr->sign<<15 | 0x7FFF; - uiZ.v0 = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF128M.c deleted file mode 100644 index e2940bb77..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF128M.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by `zWPtr'. Argument -| `zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) -{ - - softfloat_shortShiftRight128M( (const uint32_t *) &aPtr->v0, 16, zWPtr ); - zWPtr[indexWordHi( 4 )] |= (uint32_t) aPtr->sign<<31 | 0x7FFF8000; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF128UI.c deleted file mode 100644 index ac8ea7b70..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF128UI.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ = softfloat_shortShiftRight128( aPtr->v64, aPtr->v0, 16 ); - uiZ.v64 |= (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FFF800000000000 ); - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF16UI.c deleted file mode 100644 index 07679d717..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF16UI.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 16-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ) -{ - - return (uint_fast16_t) aPtr->sign<<15 | 0x7E00 | aPtr->v64>>54; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF32UI.c deleted file mode 100644 index 982c1edf6..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF32UI.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ) -{ - - return (uint_fast32_t) aPtr->sign<<31 | 0x7FC00000 | aPtr->v64>>41; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF64UI.c deleted file mode 100644 index d88c68ade..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_commonNaNToF64UI.c +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by `aPtr' into a 64-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ) -{ - - return - (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FF8000000000000 ) - | aPtr->v64>>12; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_extF80MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_extF80MToCommonNaN.c deleted file mode 100644 index 6bf45cf86..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_extF80MToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the 80-bit extended floating-point value pointed to by `aSPtr' is -| a NaN, converts this NaN to the common NaN form, and stores the resulting -| common NaN at the location pointed to by `zPtr'. If the NaN is a signaling -| NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80MToCommonNaN( - const struct extFloat80M *aSPtr, struct commonNaN *zPtr ) -{ - - if ( extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = signExtF80UI64( aSPtr->signExp ); - zPtr->v64 = aSPtr->signif<<1; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_extF80UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_extF80UIToCommonNaN.c deleted file mode 100644 index 8b8c92780..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_extF80UIToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' -| has the bit pattern of an 80-bit extended floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80UIToCommonNaN( - uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA64>>15; - zPtr->v64 = uiA0<<1; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f128MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f128MToCommonNaN.c deleted file mode 100644 index 22152145a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f128MToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN, -| converts this NaN to the common NaN form, and stores the resulting common -| NaN at the location pointed to by `zPtr'. If the NaN is a signaling NaN, -| the invalid exception is raised. Argument `aWPtr' points to an array of -| four 32-bit elements that concatenate in the platform's normal endian order -| to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr ) -{ - - if ( f128M_isSignalingNaN( (const float128_t *) aWPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = aWPtr[indexWordHi( 4 )]>>31; - softfloat_shortShiftLeft128M( aWPtr, 16, (uint32_t *) &zPtr->v0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f128UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f128UIToCommonNaN.c deleted file mode 100644 index 2510c0707..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f128UIToCommonNaN.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' -| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to -| the common NaN form, and stores the resulting common NaN at the location -| pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_f128UIToCommonNaN( - uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ) -{ - struct uint128 NaNSig; - - if ( softfloat_isSigNaNF128UI( uiA64, uiA0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - NaNSig = softfloat_shortShiftLeft128( uiA64, uiA0, 16 ); - zPtr->sign = uiA64>>63; - zPtr->v64 = NaNSig.v64; - zPtr->v0 = NaNSig.v0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f16UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f16UIToCommonNaN.c deleted file mode 100644 index 4d5003f6a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f16UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming `uiA' has the bit pattern of a 16-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF16UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>15; - zPtr->v64 = (uint_fast64_t) uiA<<54; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f32UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f32UIToCommonNaN.c deleted file mode 100644 index f4734db7a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f32UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming `uiA' has the bit pattern of a 32-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF32UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>31; - zPtr->v64 = (uint_fast64_t) uiA<<41; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f64UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f64UIToCommonNaN.c deleted file mode 100644 index 9a481a74f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_f64UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming `uiA' has the bit pattern of a 64-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF64UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>63; - zPtr->v64 = uiA<<12; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNExtF80M.c deleted file mode 100644 index f35e06654..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNExtF80M.c +++ /dev/null @@ -1,107 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by `aSPtr' and `bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by `zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ) -{ - bool isSigNaNA; - const struct extFloat80M *sPtr; - bool isSigNaNB; - uint_fast16_t uiB64; - uint64_t uiB0; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiMagA64, uiMagB64; - - isSigNaNA = extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr ); - sPtr = aSPtr; - if ( ! bSPtr ) { - if ( isSigNaNA ) softfloat_raiseFlags( softfloat_flag_invalid ); - goto copy; - } - isSigNaNB = extF80M_isSignalingNaN( (const extFloat80_t *) bSPtr ); - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - uiB64 = bSPtr->signExp; - if ( isSigNaNB ) goto returnLargerUIMag; - uiB0 = bSPtr->signif; - if ( isNaNExtF80UI( uiB64, uiB0 ) ) goto copyB; - goto copy; - } else { - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) ) goto copy; - goto copyB; - } - } - uiB64 = bSPtr->signExp; - returnLargerUIMag: - uiA64 = aSPtr->signExp; - uiMagA64 = uiA64 & 0x7FFF; - uiMagB64 = uiB64 & 0x7FFF; - if ( uiMagA64 < uiMagB64 ) goto copyB; - if ( uiMagB64 < uiMagA64 ) goto copy; - uiA0 = aSPtr->signif; - uiB0 = bSPtr->signif; - if ( uiA0 < uiB0 ) goto copyB; - if ( uiB0 < uiA0 ) goto copy; - if ( uiA64 < uiB64 ) goto copy; - copyB: - sPtr = bSPtr; - copy: - zSPtr->signExp = sPtr->signExp; - zSPtr->signif = sPtr->signif | UINT64_C( 0xC000000000000000 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNExtF80UI.c deleted file mode 100644 index fa2daae2e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNExtF80UI.c +++ /dev/null @@ -1,106 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2018 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ) -{ - bool isSigNaNA, isSigNaNB; - uint_fast64_t uiNonsigA0, uiNonsigB0; - uint_fast16_t uiMagA64, uiMagB64; - struct uint128 uiZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isSigNaNA = softfloat_isSigNaNExtF80UI( uiA64, uiA0 ); - isSigNaNB = softfloat_isSigNaNExtF80UI( uiB64, uiB0 ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiNonsigA0 = uiA0 | UINT64_C( 0xC000000000000000 ); - uiNonsigB0 = uiB0 | UINT64_C( 0xC000000000000000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerMag; - if ( isNaNExtF80UI( uiB64, uiB0 ) ) goto returnB; - goto returnA; - } else { - if ( isNaNExtF80UI( uiA64, uiA0 ) ) goto returnA; - goto returnB; - } - } - returnLargerMag: - uiMagA64 = uiA64 & 0x7FFF; - uiMagB64 = uiB64 & 0x7FFF; - if ( uiMagA64 < uiMagB64 ) goto returnB; - if ( uiMagB64 < uiMagA64 ) goto returnA; - if ( uiA0 < uiB0 ) goto returnB; - if ( uiB0 < uiA0 ) goto returnA; - if ( uiA64 < uiB64 ) goto returnA; - returnB: - uiZ.v64 = uiB64; - uiZ.v0 = uiNonsigB0; - return uiZ; - returnA: - uiZ.v64 = uiA64; - uiZ.v0 = uiNonsigA0; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF128M.c deleted file mode 100644 index 7ac2e5f63..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF128M.c +++ /dev/null @@ -1,108 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by `zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of `aWPtr', `bWPtr', -| and `zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) -{ - bool isSigNaNA; - const uint32_t *ptr; - bool isSigNaNB; - uint32_t uiA96, uiB96, wordMagA, wordMagB; - - isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr ); - ptr = aWPtr; - if ( ! bWPtr ) { - if ( isSigNaNA ) softfloat_raiseFlags( softfloat_flag_invalid ); - goto copy; - } - isSigNaNB = f128M_isSignalingNaN( (const float128_t *) bWPtr ); - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerUIMag; - if ( softfloat_isNaNF128M( bWPtr ) ) goto copyB; - goto copy; - } else { - if ( softfloat_isNaNF128M( aWPtr ) ) goto copy; - goto copyB; - } - } - returnLargerUIMag: - uiA96 = aWPtr[indexWordHi( 4 )]; - uiB96 = bWPtr[indexWordHi( 4 )]; - wordMagA = uiA96 & 0x7FFFFFFF; - wordMagB = uiB96 & 0x7FFFFFFF; - if ( wordMagA < wordMagB ) goto copyB; - if ( wordMagB < wordMagA ) goto copy; - wordMagA = aWPtr[indexWord( 4, 2 )]; - wordMagB = bWPtr[indexWord( 4, 2 )]; - if ( wordMagA < wordMagB ) goto copyB; - if ( wordMagB < wordMagA ) goto copy; - wordMagA = aWPtr[indexWord( 4, 1 )]; - wordMagB = bWPtr[indexWord( 4, 1 )]; - if ( wordMagA < wordMagB ) goto copyB; - if ( wordMagB < wordMagA ) goto copy; - wordMagA = aWPtr[indexWord( 4, 0 )]; - wordMagB = bWPtr[indexWord( 4, 0 )]; - if ( wordMagA < wordMagB ) goto copyB; - if ( wordMagB < wordMagA ) goto copy; - if ( uiA96 < uiB96 ) goto copy; - copyB: - ptr = bWPtr; - copy: - zWPtr[indexWordHi( 4 )] = ptr[indexWordHi( 4 )] | 0x00008000; - zWPtr[indexWord( 4, 2 )] = ptr[indexWord( 4, 2 )]; - zWPtr[indexWord( 4, 1 )] = ptr[indexWord( 4, 1 )]; - zWPtr[indexWord( 4, 0 )] = ptr[indexWord( 4, 0 )]; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF128UI.c deleted file mode 100644 index 6caecd205..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF128UI.c +++ /dev/null @@ -1,105 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2018 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ) -{ - bool isSigNaNA, isSigNaNB; - uint_fast64_t uiNonsigA64, uiNonsigB64, uiMagA64, uiMagB64; - struct uint128 uiZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isSigNaNA = softfloat_isSigNaNF128UI( uiA64, uiA0 ); - isSigNaNB = softfloat_isSigNaNF128UI( uiB64, uiB0 ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiNonsigA64 = uiA64 | UINT64_C( 0x0000800000000000 ); - uiNonsigB64 = uiB64 | UINT64_C( 0x0000800000000000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerMag; - if ( isNaNF128UI( uiB64, uiB0 ) ) goto returnB; - goto returnA; - } else { - if ( isNaNF128UI( uiA64, uiA0 ) ) goto returnA; - goto returnB; - } - } - returnLargerMag: - uiMagA64 = uiA64 & UINT64_C( 0x7FFFFFFFFFFFFFFF ); - uiMagB64 = uiB64 & UINT64_C( 0x7FFFFFFFFFFFFFFF ); - if ( uiMagA64 < uiMagB64 ) goto returnB; - if ( uiMagB64 < uiMagA64 ) goto returnA; - if ( uiA0 < uiB0 ) goto returnB; - if ( uiB0 < uiA0 ) goto returnA; - if ( uiNonsigA64 < uiNonsigB64 ) goto returnA; - returnB: - uiZ.v64 = uiNonsigB64; - uiZ.v0 = uiB0; - return uiZ; - returnA: - uiZ.v64 = uiNonsigA64; - uiZ.v0 = uiA0; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF16UI.c deleted file mode 100644 index f9d80d6ac..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF16UI.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2018 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) -{ - bool isSigNaNA, isSigNaNB; - uint_fast16_t uiNonsigA, uiNonsigB, uiMagA, uiMagB; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isSigNaNA = softfloat_isSigNaNF16UI( uiA ); - isSigNaNB = softfloat_isSigNaNF16UI( uiB ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiNonsigA = uiA | 0x0200; - uiNonsigB = uiB | 0x0200; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerMag; - return isNaNF16UI( uiB ) ? uiNonsigB : uiNonsigA; - } else { - return isNaNF16UI( uiA ) ? uiNonsigA : uiNonsigB; - } - } - returnLargerMag: - uiMagA = uiA & 0x7FFF; - uiMagB = uiB & 0x7FFF; - if ( uiMagA < uiMagB ) return uiNonsigB; - if ( uiMagB < uiMagA ) return uiNonsigA; - return (uiNonsigA < uiNonsigB) ? uiNonsigA : uiNonsigB; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF32UI.c deleted file mode 100644 index 2350ad7c0..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF32UI.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2018 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - bool isSigNaNA, isSigNaNB; - uint_fast32_t uiNonsigA, uiNonsigB, uiMagA, uiMagB; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isSigNaNA = softfloat_isSigNaNF32UI( uiA ); - isSigNaNB = softfloat_isSigNaNF32UI( uiB ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiNonsigA = uiA | 0x00400000; - uiNonsigB = uiB | 0x00400000; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerMag; - return isNaNF32UI( uiB ) ? uiNonsigB : uiNonsigA; - } else { - return isNaNF32UI( uiA ) ? uiNonsigA : uiNonsigB; - } - } - returnLargerMag: - uiMagA = uiA & 0x7FFFFFFF; - uiMagB = uiB & 0x7FFFFFFF; - if ( uiMagA < uiMagB ) return uiNonsigB; - if ( uiMagB < uiMagA ) return uiNonsigA; - return (uiNonsigA < uiNonsigB) ? uiNonsigA : uiNonsigB; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF64UI.c deleted file mode 100644 index a4013d489..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/s_propagateNaNF64UI.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2018 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) -{ - bool isSigNaNA, isSigNaNB; - uint_fast64_t uiNonsigA, uiNonsigB, uiMagA, uiMagB; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isSigNaNA = softfloat_isSigNaNF64UI( uiA ); - isSigNaNB = softfloat_isSigNaNF64UI( uiB ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiNonsigA = uiA | UINT64_C( 0x0008000000000000 ); - uiNonsigB = uiB | UINT64_C( 0x0008000000000000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerMag; - return isNaNF64UI( uiB ) ? uiNonsigB : uiNonsigA; - } else { - return isNaNF64UI( uiA ) ? uiNonsigA : uiNonsigB; - } - } - returnLargerMag: - uiMagA = uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF ); - uiMagB = uiB & UINT64_C( 0x7FFFFFFFFFFFFFFF ); - if ( uiMagA < uiMagB ) return uiNonsigB; - if ( uiMagB < uiMagA ) return uiNonsigA; - return (uiNonsigA < uiNonsigB) ? uiNonsigA : uiNonsigB; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/softfloat_raiseFlags.c b/source/src/vm/libcpu_newdev/softfloat3/source/8086/softfloat_raiseFlags.c deleted file mode 100644 index 7a1aee930..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/softfloat_raiseFlags.c +++ /dev/null @@ -1,52 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Raises the exceptions specified by `flags'. Floating-point traps can be -| defined here if desired. It is currently not possible for such a trap -| to substitute a result value. If traps are not implemented, this routine -| should be simply `softfloat_exceptionFlags |= flags;'. -*----------------------------------------------------------------------------*/ -void softfloat_raiseFlags( uint_fast8_t flags ) -{ - - softfloat_exceptionFlags |= flags; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/8086/specialize.h b/source/src/vm/libcpu_newdev/softfloat3/source/8086/specialize.h deleted file mode 100644 index a9166e170..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/8086/specialize.h +++ /dev/null @@ -1,376 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2018 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef specialize_h -#define specialize_h 1 - -#include -#include -#include "primitiveTypes.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Default value for 'softfloat_detectTininess'. -*----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_afterRounding - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 32-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui32_fromPosOverflow 0xFFFFFFFF -#define ui32_fromNegOverflow 0xFFFFFFFF -#define ui32_fromNaN 0xFFFFFFFF -#define i32_fromPosOverflow (-0x7FFFFFFF - 1) -#define i32_fromNegOverflow (-0x7FFFFFFF - 1) -#define i32_fromNaN (-0x7FFFFFFF - 1) - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 64-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define i64_fromPosOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNaN (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) - -/*---------------------------------------------------------------------------- -| "Common NaN" structure, used to transfer NaN representations from one format -| to another. -*----------------------------------------------------------------------------*/ -struct commonNaN { - bool sign; -#ifdef LITTLEENDIAN - uint64_t v0, v64; -#else - uint64_t v64, v0; -#endif -}; - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 16-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF16UI 0xFE00 - -/*---------------------------------------------------------------------------- -| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a -| 16-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 32-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF32UI 0xFFC00000 - -/*---------------------------------------------------------------------------- -| Returns true when 32-bit unsigned integer 'uiA' has the bit pattern of a -| 32-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 64-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF64UI UINT64_C( 0xFFF8000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a -| 64-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 80-bit extended floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNExtF80UI64 0xFFFF -#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 80-bit unsigned integer formed from concatenating -| 16-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of an 80-bit extended -| floating-point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) - -#ifdef SOFTFLOAT_FAST_INT64 - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of an 80-bit extended floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80UIToCommonNaN( - uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 ) -#define defaultNaNF128UI0 UINT64_C( 0 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 128-bit unsigned integer formed from concatenating -| 64-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of a 128-bit floating- -| point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to -| the common NaN form, and stores the resulting common NaN at the location -| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_f128UIToCommonNaN( - uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ); - -#else - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is not -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the 80-bit extended floating-point value pointed to by 'aSPtr' is -| a NaN, converts this NaN to the common NaN form, and stores the resulting -| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling -| NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80MToCommonNaN( - const struct extFloat80M *aSPtr, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| 'zSPtr'. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ); - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by 'aSPtr' and 'bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by 'zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI96 0xFFFF8000 -#define defaultNaNF128UI64 0 -#define defaultNaNF128UI32 0 -#define defaultNaNF128UI0 0 - -/*---------------------------------------------------------------------------- -| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, -| converts this NaN to the common NaN form, and stores the resulting common -| NaN at the location pointed to by 'zPtr'. If the NaN is a signaling NaN, -| the invalid exception is raised. Argument 'aWPtr' points to an array of -| four 32-bit elements that concatenate in the platform's normal endian order -| to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by 'zWPtr'. Argument -| 'zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ); - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| 'aWPtr' and 'bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by 'zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of 'aWPtr', 'bWPtr', -| and 'zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ); - -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/extF80M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/extF80M_isSignalingNaN.c deleted file mode 100644 index c2cca65c9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/extF80M_isSignalingNaN.c +++ /dev/null @@ -1,57 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool extF80M_isSignalingNaN( const extFloat80_t *aPtr ) -{ - const struct extFloat80M *aSPtr; - uint64_t uiA0; - - aSPtr = (const struct extFloat80M *) aPtr; - if ( (aSPtr->signExp & 0x7FFF) != 0x7FFF ) return false; - uiA0 = aSPtr->signif; - return - ! (uiA0 & UINT64_C( 0x4000000000000000 )) - && (uiA0 & UINT64_C( 0x3FFFFFFFFFFFFFFF)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/f128M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/f128M_isSignalingNaN.c deleted file mode 100644 index 9ff83d726..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/f128M_isSignalingNaN.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool f128M_isSignalingNaN( const float128_t *aPtr ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - if ( (uiA96 & 0x7FFF8000) != 0x7FFF0000 ) return false; - return - ((uiA96 & 0x00007FFF) != 0) - || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )]) - != 0); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToExtF80M.c deleted file mode 100644 index 2e6bf7c75..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToExtF80M.c +++ /dev/null @@ -1,57 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "softfloat_types.h" - -#define softfloat_commonNaNToExtF80M softfloat_commonNaNToExtF80M -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| 'zSPtr'. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) -{ - - zSPtr->signExp = defaultNaNExtF80UI64; - zSPtr->signif = defaultNaNExtF80UI0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToExtF80UI.c deleted file mode 100644 index e37004f7f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToExtF80UI.c +++ /dev/null @@ -1,57 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "primitiveTypes.h" - -#define softfloat_commonNaNToExtF80UI softfloat_commonNaNToExtF80UI -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ.v64 = defaultNaNExtF80UI64; - uiZ.v0 = defaultNaNExtF80UI0; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF128M.c deleted file mode 100644 index 2ff4c1631..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF128M.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#define softfloat_commonNaNToF128M softfloat_commonNaNToF128M -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by 'zWPtr'. Argument -| 'zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) -{ - - zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96; - zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64; - zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32; - zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF128UI.c deleted file mode 100644 index 05dfb5f14..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF128UI.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "primitiveTypes.h" - -#define softfloat_commonNaNToF128UI softfloat_commonNaNToF128UI -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF16UI.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF16UI.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF32UI.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF32UI.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF64UI.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_commonNaNToF64UI.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_extF80MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_extF80MToCommonNaN.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_extF80MToCommonNaN.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_extF80UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_extF80UIToCommonNaN.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_extF80UIToCommonNaN.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f128MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f128MToCommonNaN.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f128MToCommonNaN.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f128UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f128UIToCommonNaN.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f128UIToCommonNaN.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f16UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f16UIToCommonNaN.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f16UIToCommonNaN.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f32UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f32UIToCommonNaN.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f32UIToCommonNaN.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f64UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f64UIToCommonNaN.c deleted file mode 100644 index 861b26965..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_f64UIToCommonNaN.c +++ /dev/null @@ -1,5 +0,0 @@ - -/*---------------------------------------------------------------------------- -| This file intentionally contains no code. -*----------------------------------------------------------------------------*/ - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNExtF80M.c deleted file mode 100644 index 827ed5e3a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNExtF80M.c +++ /dev/null @@ -1,74 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by 'aSPtr' and 'bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by 'zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ) -{ - uint_fast16_t ui64; - uint_fast64_t ui0; - - ui64 = aSPtr->signExp; - ui0 = aSPtr->signif; - if ( - softfloat_isSigNaNExtF80UI( ui64, ui0 ) - || (bSPtr - && (ui64 = bSPtr->signExp, - ui0 = bSPtr->signif, - softfloat_isSigNaNExtF80UI( ui64, ui0 ))) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zSPtr->signExp = defaultNaNExtF80UI64; - zSPtr->signif = defaultNaNExtF80UI0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNExtF80UI.c deleted file mode 100644 index e2ddd937e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNExtF80UI.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ) -{ - struct uint128 uiZ; - - if ( - softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) - || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - uiZ.v64 = defaultNaNExtF80UI64; - uiZ.v0 = defaultNaNExtF80UI0; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF128M.c deleted file mode 100644 index b876ae1f1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF128M.c +++ /dev/null @@ -1,68 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| 'aWPtr' and 'bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by 'zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of 'aWPtr', 'bWPtr', -| and 'zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) -{ - - if ( - f128M_isSignalingNaN( (const float128_t *) aWPtr ); - || (bWPtr && f128M_isSignalingNaN( (const float128_t *) bWPtr )) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96; - zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64; - zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32; - zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF128UI.c deleted file mode 100644 index 31b788e0c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF128UI.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ) -{ - struct uint128 uiZ; - - if ( - softfloat_isSigNaNF128UI( uiA64, uiA0 ) - || softfloat_isSigNaNF128UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF16UI.c deleted file mode 100644 index 17618fc2e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF16UI.c +++ /dev/null @@ -1,58 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) -{ - - if ( softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return defaultNaNF16UI; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF32UI.c deleted file mode 100644 index e4c3fc1a8..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF32UI.c +++ /dev/null @@ -1,58 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - - if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return defaultNaNF32UI; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF64UI.c deleted file mode 100644 index 75361b8e2..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/s_propagateNaNF64UI.c +++ /dev/null @@ -1,58 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) -{ - - if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return defaultNaNF64UI; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/softfloat_raiseFlags.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/softfloat_raiseFlags.c deleted file mode 100644 index f8f106570..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/softfloat_raiseFlags.c +++ /dev/null @@ -1,52 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Raises the exceptions specified by 'flags'. Floating-point traps can be -| defined here if desired. It is currently not possible for such a trap -| to substitute a result value. If traps are not implemented, this routine -| should be simply 'softfloat_exceptionFlags |= flags;'. -*----------------------------------------------------------------------------*/ -void softfloat_raiseFlags( uint_fast8_t flags ) -{ - - softfloat_exceptionFlags |= flags; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/specialize.h b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/specialize.h deleted file mode 100644 index e4ea15d14..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2-defaultNaN/specialize.h +++ /dev/null @@ -1,407 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef specialize_h -#define specialize_h 1 - -#include -#include -#include "primitiveTypes.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Default value for 'softfloat_detectTininess'. -*----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_beforeRounding - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 32-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui32_fromPosOverflow 0xFFFFFFFF -#define ui32_fromNegOverflow 0 -#define ui32_fromNaN 0 -#define i32_fromPosOverflow 0x7FFFFFFF -#define i32_fromNegOverflow (-0x7FFFFFFF - 1) -#define i32_fromNaN 0 - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 64-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNegOverflow 0 -#define ui64_fromNaN 0 -#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF ) -#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNaN 0 - -/*---------------------------------------------------------------------------- -| "Common NaN" structure, used to transfer NaN representations from one format -| to another. -*----------------------------------------------------------------------------*/ -struct commonNaN { char _unused; }; - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 16-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF16UI 0x7E00 - -/*---------------------------------------------------------------------------- -| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a -| 16-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) softfloat_raiseFlags( softfloat_flag_invalid ) - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -#define softfloat_commonNaNToF16UI( aPtr ) ((uint_fast16_t) defaultNaNF16UI) - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 32-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF32UI 0x7FC00000 - -/*---------------------------------------------------------------------------- -| Returns true when 32-bit unsigned integer 'uiA' has the bit pattern of a -| 32-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -#define softfloat_f32UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x00400000) ) softfloat_raiseFlags( softfloat_flag_invalid ) - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -#define softfloat_commonNaNToF32UI( aPtr ) ((uint_fast32_t) defaultNaNF32UI) - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 64-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a -| 64-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -#define softfloat_f64UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & UINT64_C( 0x0008000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -#define softfloat_commonNaNToF64UI( aPtr ) ((uint_fast64_t) defaultNaNF64UI) - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 80-bit extended floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNExtF80UI64 0x7FFF -#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 80-bit unsigned integer formed from concatenating -| 16-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of an 80-bit extended -| floating-point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) - -#ifdef SOFTFLOAT_FAST_INT64 - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of an 80-bit extended floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -#define softfloat_extF80UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA0) & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -#if defined INLINE && ! defined softfloat_commonNaNToExtF80UI -INLINE -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - uiZ.v64 = defaultNaNExtF80UI64; - uiZ.v0 = defaultNaNExtF80UI0; - return uiZ; -} -#else -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); -#endif - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 ) -#define defaultNaNF128UI0 UINT64_C( 0 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 128-bit unsigned integer formed from concatenating -| 64-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of a 128-bit floating- -| point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to -| the common NaN form, and stores the resulting common NaN at the location -| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ -#define softfloat_f128UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA64) & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -#if defined INLINE && ! defined softfloat_commonNaNToF128UI -INLINE -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - return uiZ; -} -#else -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); -#endif - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ); - -#else - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is not -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the 80-bit extended floating-point value pointed to by 'aSPtr' is -| a NaN, converts this NaN to the common NaN form, and stores the resulting -| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling -| NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -#define softfloat_extF80MToCommonNaN( aSPtr, zPtr ) if ( ! ((aSPtr)->signif & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| 'zSPtr'. -*----------------------------------------------------------------------------*/ -#if defined INLINE && ! defined softfloat_commonNaNToExtF80M -INLINE -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) -{ - zSPtr->signExp = defaultNaNExtF80UI64; - zSPtr->signif = defaultNaNExtF80UI0; -} -#else -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ); -#endif - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by 'aSPtr' and 'bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by 'zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI96 0x7FFF8000 -#define defaultNaNF128UI64 0 -#define defaultNaNF128UI32 0 -#define defaultNaNF128UI0 0 - -/*---------------------------------------------------------------------------- -| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, -| converts this NaN to the common NaN form, and stores the resulting common -| NaN at the location pointed to by 'zPtr'. If the NaN is a signaling NaN, -| the invalid exception is raised. Argument 'aWPtr' points to an array of -| four 32-bit elements that concatenate in the platform's normal endian order -| to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -#define softfloat_f128MToCommonNaN( aWPtr, zPtr ) if ( ! ((aWPtr)[indexWordHi( 4 )] & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by 'zWPtr'. Argument -| 'zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -#if defined INLINE && ! defined softfloat_commonNaNToF128M -INLINE -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) -{ - zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96; - zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64; - zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32; - zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0; -} -#else -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ); -#endif - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| 'aWPtr' and 'bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by 'zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of 'aWPtr', 'bWPtr', -| and 'zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ); - -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/extF80M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/extF80M_isSignalingNaN.c deleted file mode 100644 index c2cca65c9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/extF80M_isSignalingNaN.c +++ /dev/null @@ -1,57 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool extF80M_isSignalingNaN( const extFloat80_t *aPtr ) -{ - const struct extFloat80M *aSPtr; - uint64_t uiA0; - - aSPtr = (const struct extFloat80M *) aPtr; - if ( (aSPtr->signExp & 0x7FFF) != 0x7FFF ) return false; - uiA0 = aSPtr->signif; - return - ! (uiA0 & UINT64_C( 0x4000000000000000 )) - && (uiA0 & UINT64_C( 0x3FFFFFFFFFFFFFFF)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/f128M_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/f128M_isSignalingNaN.c deleted file mode 100644 index 9ff83d726..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/f128M_isSignalingNaN.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool f128M_isSignalingNaN( const float128_t *aPtr ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - if ( (uiA96 & 0x7FFF8000) != 0x7FFF0000 ) return false; - return - ((uiA96 & 0x00007FFF) != 0) - || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )]) - != 0); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToExtF80M.c deleted file mode 100644 index 6bb922a1d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToExtF80M.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| 'zSPtr'. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) -{ - - zSPtr->signExp = packToExtF80UI64( aPtr->sign, 0x7FFF ); - zSPtr->signif = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToExtF80UI.c deleted file mode 100644 index 5e841b253..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToExtF80UI.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ.v64 = (uint_fast16_t) aPtr->sign<<15 | 0x7FFF; - uiZ.v0 = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1; - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF128M.c deleted file mode 100644 index 02e234853..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF128M.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by 'zWPtr'. Argument -| 'zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) -{ - - softfloat_shortShiftRight128M( (const uint32_t *) &aPtr->v0, 16, zWPtr ); - zWPtr[indexWordHi( 4 )] |= (uint32_t) aPtr->sign<<31 | 0x7FFF8000; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF128UI.c deleted file mode 100644 index fa87d75fa..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF128UI.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) -{ - struct uint128 uiZ; - - uiZ = softfloat_shortShiftRight128( aPtr->v64, aPtr->v0, 16 ); - uiZ.v64 |= (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FFF800000000000 ); - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF16UI.c deleted file mode 100644 index 6d5bf9ab3..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF16UI.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ) -{ - - return (uint_fast16_t) aPtr->sign<<15 | 0x7E00 | aPtr->v64>>54; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF32UI.c deleted file mode 100644 index e45d63b3b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF32UI.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ) -{ - - return (uint_fast32_t) aPtr->sign<<31 | 0x7FC00000 | aPtr->v64>>41; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF64UI.c deleted file mode 100644 index bfde88bbc..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_commonNaNToF64UI.c +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ) -{ - - return - (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FF8000000000000 ) - | aPtr->v64>>12; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_extF80MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_extF80MToCommonNaN.c deleted file mode 100644 index 5fd54dbbd..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_extF80MToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the 80-bit extended floating-point value pointed to by 'aSPtr' is -| a NaN, converts this NaN to the common NaN form, and stores the resulting -| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling -| NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80MToCommonNaN( - const struct extFloat80M *aSPtr, struct commonNaN *zPtr ) -{ - - if ( extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = signExtF80UI64( aSPtr->signExp ); - zPtr->v64 = aSPtr->signif<<1; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_extF80UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_extF80UIToCommonNaN.c deleted file mode 100644 index 9c0f0ca08..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_extF80UIToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of an 80-bit extended floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80UIToCommonNaN( - uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA64>>15; - zPtr->v64 = uiA0<<1; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f128MToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f128MToCommonNaN.c deleted file mode 100644 index e54756b10..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f128MToCommonNaN.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, -| converts this NaN to the common NaN form, and stores the resulting common -| NaN at the location pointed to by 'zPtr'. If the NaN is a signaling NaN, -| the invalid exception is raised. Argument 'aWPtr' points to an array of -| four 32-bit elements that concatenate in the platform's normal endian order -| to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr ) -{ - - if ( f128M_isSignalingNaN( (const float128_t *) aWPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = aWPtr[indexWordHi( 4 )]>>31; - softfloat_shortShiftLeft128M( aWPtr, 16, (uint32_t *) &zPtr->v0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f128UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f128UIToCommonNaN.c deleted file mode 100644 index 27952a775..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f128UIToCommonNaN.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to -| the common NaN form, and stores the resulting common NaN at the location -| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_f128UIToCommonNaN( - uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ) -{ - struct uint128 NaNSig; - - if ( softfloat_isSigNaNF128UI( uiA64, uiA0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - NaNSig = softfloat_shortShiftLeft128( uiA64, uiA0, 16 ); - zPtr->sign = uiA64>>63; - zPtr->v64 = NaNSig.v64; - zPtr->v0 = NaNSig.v0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f16UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f16UIToCommonNaN.c deleted file mode 100644 index ee1928eb3..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f16UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF16UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>15; - zPtr->v64 = (uint_fast64_t) uiA<<54; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f32UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f32UIToCommonNaN.c deleted file mode 100644 index 249e47825..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f32UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF32UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>31; - zPtr->v64 = (uint_fast64_t) uiA<<41; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f64UIToCommonNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f64UIToCommonNaN.c deleted file mode 100644 index adca2d047..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_f64UIToCommonNaN.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ) -{ - - if ( softfloat_isSigNaNF64UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - zPtr->sign = uiA>>63; - zPtr->v64 = uiA<<12; - zPtr->v0 = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNExtF80M.c deleted file mode 100644 index 1c142562e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNExtF80M.c +++ /dev/null @@ -1,86 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by 'aSPtr' and 'bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by 'zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ) -{ - const struct extFloat80M *sPtr; - bool isSigNaNA; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - - sPtr = aSPtr; - isSigNaNA = extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr ); - if ( - isSigNaNA - || (bSPtr - && extF80M_isSignalingNaN( (const extFloat80_t *) bSPtr )) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) goto copyNonsig; - goto copyNonsigB; - } - uiZ64 = sPtr->signExp; - uiZ0 = sPtr->signif; - if ( isNaNExtF80UI( uiZ64, uiZ0 ) ) goto returnNonsig; - copyNonsigB: - sPtr = bSPtr; - copyNonsig: - uiZ64 = sPtr->signExp; - uiZ0 = sPtr->signif; - returnNonsig: - zSPtr->signExp = uiZ64; - zSPtr->signif = uiZ0 | UINT64_C( 0xC000000000000000 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNExtF80UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNExtF80UI.c deleted file mode 100644 index be95414ac..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNExtF80UI.c +++ /dev/null @@ -1,83 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ) -{ - bool isSigNaNA; - struct uint128 uiZ; - - isSigNaNA = softfloat_isSigNaNExtF80UI( uiA64, uiA0 ); - if ( isSigNaNA || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) goto returnNonsigA; - goto returnNonsigB; - } - if ( isNaNExtF80UI( uiA64, uiA0 ) ) { - returnNonsigA: - uiZ.v64 = uiA64; - uiZ.v0 = uiA0; - } else { - returnNonsigB: - uiZ.v64 = uiB64; - uiZ.v0 = uiB0; - } - uiZ.v0 | UINT64_C( 0xC000000000000000 ); - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF128M.c deleted file mode 100644 index 6a30052cb..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF128M.c +++ /dev/null @@ -1,77 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| 'aWPtr' and 'bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by 'zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of 'aWPtr', 'bWPtr', -| and 'zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) -{ - const uint32_t *ptr; - bool isSigNaNA; - - ptr = aWPtr; - isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr ); - if ( - isSigNaNA - || (bWPtr && f128M_isSignalingNaN( (const float128_t *) bWPtr )) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! isSigNaNA ) ptr = bWPtr; - goto copyNonsig; - } - if ( ! softfloat_isNaNF128M( aWPtr ) ) ptr = bWPtr; - copyNonsig: - zWPtr[indexWordHi( 4 )] = ptr[indexWordHi( 4 )] | 0x00008000; - zWPtr[indexWord( 4, 2 )] = ptr[indexWord( 4, 2 )]; - zWPtr[indexWord( 4, 1 )] = ptr[indexWord( 4, 1 )]; - zWPtr[indexWord( 4, 0 )] = ptr[indexWord( 4, 0 )]; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF128UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF128UI.c deleted file mode 100644 index 5aece622e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF128UI.c +++ /dev/null @@ -1,83 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ) -{ - bool isSigNaNA; - struct uint128 uiZ; - - isSigNaNA = softfloat_isSigNaNF128UI( uiA64, uiA0 ); - if ( isSigNaNA || softfloat_isSigNaNF128UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( isSigNaNA ) goto returnNonsigA; - goto returnNonsigB; - } - if ( isNaNF128UI( uiA64, uiA0 ) ) { - returnNonsigA: - uiZ.v64 = uiA64; - uiZ.v0 = uiA0; - } else { - returnNonsigB: - uiZ.v64 = uiB64; - uiZ.v0 = uiB0; - } - uiZ.v64 |= UINT64_C( 0x0000800000000000 ); - return uiZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF16UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF16UI.c deleted file mode 100644 index 880146033..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF16UI.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ) -{ - bool isSigNaNA; - - isSigNaNA = softfloat_isSigNaNF16UI( uiA ); - if ( isSigNaNA || softfloat_isSigNaNF16UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return (isSigNaNA ? uiA : uiB) | 0x0200; - } - return isNaNF16UI( uiA ) ? uiA : uiB; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF32UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF32UI.c deleted file mode 100644 index 31b289e9d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF32UI.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - bool isSigNaNA; - - isSigNaNA = softfloat_isSigNaNF32UI( uiA ); - if ( isSigNaNA || softfloat_isSigNaNF32UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return (isSigNaNA ? uiA : uiB) | 0x00400000; - } - return isNaNF32UI( uiA ) ? uiA : uiB; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF64UI.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF64UI.c deleted file mode 100644 index 224049ab1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/s_propagateNaNF64UI.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) -{ - bool isSigNaNA; - - isSigNaNA = softfloat_isSigNaNF64UI( uiA ); - if ( isSigNaNA || softfloat_isSigNaNF64UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return (isSigNaNA ? uiA : uiB) | UINT64_C( 0x0008000000000000 ); - } - return isNaNF64UI( uiA ) ? uiA : uiB; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/softfloat_raiseFlags.c b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/softfloat_raiseFlags.c deleted file mode 100644 index f8f106570..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/softfloat_raiseFlags.c +++ /dev/null @@ -1,52 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Raises the exceptions specified by 'flags'. Floating-point traps can be -| defined here if desired. It is currently not possible for such a trap -| to substitute a result value. If traps are not implemented, this routine -| should be simply 'softfloat_exceptionFlags |= flags;'. -*----------------------------------------------------------------------------*/ -void softfloat_raiseFlags( uint_fast8_t flags ) -{ - - softfloat_exceptionFlags |= flags; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/specialize.h b/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/specialize.h deleted file mode 100644 index 10b0b357f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ARM-VFPv2/specialize.h +++ /dev/null @@ -1,376 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef specialize_h -#define specialize_h 1 - -#include -#include -#include "primitiveTypes.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Default value for 'softfloat_detectTininess'. -*----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_beforeRounding - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 32-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui32_fromPosOverflow 0xFFFFFFFF -#define ui32_fromNegOverflow 0 -#define ui32_fromNaN 0 -#define i32_fromPosOverflow 0x7FFFFFFF -#define i32_fromNegOverflow (-0x7FFFFFFF - 1) -#define i32_fromNaN 0 - -/*---------------------------------------------------------------------------- -| The values to return on conversions to 64-bit integer formats that raise an -| invalid exception. -*----------------------------------------------------------------------------*/ -#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) -#define ui64_fromNegOverflow 0 -#define ui64_fromNaN 0 -#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF ) -#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) -#define i64_fromNaN 0 - -/*---------------------------------------------------------------------------- -| "Common NaN" structure, used to transfer NaN representations from one format -| to another. -*----------------------------------------------------------------------------*/ -struct commonNaN { - bool sign; -#ifdef LITTLEENDIAN - uint64_t v0, v64; -#else - uint64_t v64, v0; -#endif -}; - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 16-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF16UI 0x7E00 - -/*---------------------------------------------------------------------------- -| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a -| 16-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF16UI( uiA ) ((((uiA) & 0x7E00) == 0x7C00) && ((uiA) & 0x01FF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast16_t - softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 32-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF32UI 0x7FC00000 - -/*---------------------------------------------------------------------------- -| Returns true when 32-bit unsigned integer 'uiA' has the bit pattern of a -| 32-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 32-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 64-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when 64-bit unsigned integer 'uiA' has the bit pattern of a -| 64-bit floating-point signaling NaN. -| Note: This macro evaluates its argument more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) - -/*---------------------------------------------------------------------------- -| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating- -| point values, at least one of which is a NaN, returns the bit pattern of -| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 80-bit extended floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNExtF80UI64 0x7FFF -#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 80-bit unsigned integer formed from concatenating -| 16-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of an 80-bit extended -| floating-point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) - -#ifdef SOFTFLOAT_FAST_INT64 - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of an 80-bit extended floating-point NaN, converts -| this NaN to the common NaN form, and stores the resulting common NaN at the -| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80UIToCommonNaN( - uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and returns the bit pattern of this value as an unsigned -| integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting -| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 80-bit extended floating-point value, and assuming at least on of these -| floating-point values is a NaN, returns the bit pattern of the combined NaN -| result. If either original floating-point value is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNExtF80UI( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0 - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 ) -#define defaultNaNF128UI0 UINT64_C( 0 ) - -/*---------------------------------------------------------------------------- -| Returns true when the 128-bit unsigned integer formed from concatenating -| 64-bit 'uiA64' and 64-bit 'uiA0' has the bit pattern of a 128-bit floating- -| point signaling NaN. -| Note: This macro evaluates its arguments more than once. -*----------------------------------------------------------------------------*/ -#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) - -/*---------------------------------------------------------------------------- -| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0' -| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to -| the common NaN form, and stores the resulting common NaN at the location -| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception -| is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_f128UIToCommonNaN( - uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and returns the bit pattern of this value as an unsigned integer. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); - -/*---------------------------------------------------------------------------- -| Interpreting the unsigned integer formed from concatenating 'uiA64' and -| 'uiA0' as a 128-bit floating-point value, and likewise interpreting the -| unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another -| 128-bit floating-point value, and assuming at least on of these floating- -| point values is a NaN, returns the bit pattern of the combined NaN result. -| If either original floating-point value is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_propagateNaNF128UI( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0 - ); - -#else - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is not -| defined. -*----------------------------------------------------------------------------*/ - -/*---------------------------------------------------------------------------- -| Assuming the 80-bit extended floating-point value pointed to by 'aSPtr' is -| a NaN, converts this NaN to the common NaN form, and stores the resulting -| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling -| NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_extF80MToCommonNaN( - const struct extFloat80M *aSPtr, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended -| floating-point NaN, and stores this NaN at the location pointed to by -| 'zSPtr'. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToExtF80M( - const struct commonNaN *aPtr, struct extFloat80M *zSPtr ); - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 80-bit extended floating-point values -| pointed to by 'aSPtr' and 'bSPtr' is a NaN, stores the combined NaN result -| at the location pointed to by 'zSPtr'. If either original floating-point -| value is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ); - -/*---------------------------------------------------------------------------- -| The bit pattern for a default generated 128-bit floating-point NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF128UI96 0x7FFF8000 -#define defaultNaNF128UI64 0 -#define defaultNaNF128UI32 0 -#define defaultNaNF128UI0 0 - -/*---------------------------------------------------------------------------- -| Assuming the 128-bit floating-point value pointed to by 'aWPtr' is a NaN, -| converts this NaN to the common NaN form, and stores the resulting common -| NaN at the location pointed to by 'zPtr'. If the NaN is a signaling NaN, -| the invalid exception is raised. Argument 'aWPtr' points to an array of -| four 32-bit elements that concatenate in the platform's normal endian order -| to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr ); - -/*---------------------------------------------------------------------------- -| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point -| NaN, and stores this NaN at the location pointed to by 'zWPtr'. Argument -| 'zWPtr' points to an array of four 32-bit elements that concatenate in the -| platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ); - -/*---------------------------------------------------------------------------- -| Assuming at least one of the two 128-bit floating-point values pointed to by -| 'aWPtr' and 'bWPtr' is a NaN, stores the combined NaN result at the location -| pointed to by 'zWPtr'. If either original floating-point value is a -| signaling NaN, the invalid exception is raised. Each of 'aWPtr', 'bWPtr', -| and 'zWPtr' points to an array of four 32-bit elements that concatenate in -| the platform's normal endian order to form a 128-bit floating-point value. -*----------------------------------------------------------------------------*/ -void - softfloat_propagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ); - -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_add.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_add.c deleted file mode 100644 index 4ba6a311c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_add.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - extF80M_add( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - extFloat80_t - (*magsFuncPtr)( - uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); -#endif - - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - signA = signExtF80UI64( uiA64 ); - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - signB = signExtF80UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - *zPtr = softfloat_addMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - *zPtr = softfloat_subMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_addMagsExtF80 : softfloat_subMagsExtF80; - *zPtr = (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - -#else - -void - extF80M_add( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - - softfloat_addExtF80M( - (const struct extFloat80M *) aPtr, - (const struct extFloat80M *) bPtr, - (struct extFloat80M *) zPtr, - false - ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_div.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_div.c deleted file mode 100644 index 24c069a98..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_div.c +++ /dev/null @@ -1,194 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - extF80M_div( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - - *zPtr = extF80_div( *aPtr, *bPtr ); - -} - -#else - -void - extF80M_div( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - struct extFloat80M *zSPtr; - uint_fast16_t uiA64; - int32_t expA; - uint_fast16_t uiB64; - int32_t expB; - bool signZ; - uint64_t sigA, x64; - int32_t expZ; - int shiftDist; - uint32_t y[3], recip32, sigB[3]; - int ix; - uint32_t q, qs[2]; - uint_fast16_t uiZ64; - uint64_t uiZ0; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - zSPtr = (struct extFloat80M *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - expA = expExtF80UI64( uiA64 ); - uiB64 = bSPtr->signExp; - expB = expExtF80UI64( uiB64 ); - signZ = signExtF80UI64( uiA64 ) ^ signExtF80UI64( uiB64 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNExtF80M( aSPtr, bSPtr, zSPtr ) ) return; - if ( expA == 0x7FFF ) { - if ( expB == 0x7FFF ) goto invalid; - goto infinity; - } - goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sigA = aSPtr->signif; - x64 = bSPtr->signif; - if ( ! expB ) expB = 1; - if ( ! (x64 & UINT64_C( 0x8000000000000000 )) ) { - if ( ! x64 ) { - if ( ! sigA ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinite ); - goto infinity; - } - expB += softfloat_normExtF80SigM( &x64 ); - } - if ( ! expA ) expA = 1; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigA ) goto zero; - expA += softfloat_normExtF80SigM( &sigA ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA - expB + 0x3FFF; - shiftDist = 29; - if ( sigA < x64 ) { - --expZ; - shiftDist = 30; - } - softfloat_shortShiftLeft64To96M( sigA, shiftDist, y ); - recip32 = softfloat_approxRecip32_1( x64>>32 ); - sigB[indexWord( 3, 0 )] = (uint32_t) x64<<30; - x64 >>= 2; - sigB[indexWord( 3, 2 )] = x64>>32; - sigB[indexWord( 3, 1 )] = x64; - ix = 2; - for (;;) { - x64 = (uint64_t) y[indexWordHi( 3 )] * recip32; - q = (x64 + 0x80000000)>>32; - --ix; - if ( ix < 0 ) break; - softfloat_remStep96MBy32( y, 29, sigB, q, y ); - if ( y[indexWordHi( 3 )] & 0x80000000 ) { - --q; - softfloat_add96M( y, sigB, y ); - } - qs[ix] = q; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ((q + 1) & 0x3FFFFF) < 2 ) { - softfloat_remStep96MBy32( y, 29, sigB, q, y ); - if ( y[indexWordHi( 3 )] & 0x80000000 ) { - --q; - softfloat_add96M( y, sigB, y ); - } else if ( softfloat_compare96M( sigB, y ) <= 0 ) { - ++q; - softfloat_sub96M( y, sigB, y ); - } - if ( - y[indexWordLo( 3 )] || y[indexWord( 3, 1 )] || y[indexWord( 3, 2 )] - ) { - q |= 1; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - x64 = (uint64_t) q<<9; - y[indexWord( 3, 0 )] = x64; - x64 = ((uint64_t) qs[0]<<6) + (x64>>32); - y[indexWord( 3, 1 )] = x64; - y[indexWord( 3, 2 )] = (qs[1]<<3) + (x64>>32); - softfloat_roundPackMToExtF80M( - signZ, expZ, y, extF80_roundingPrecision, zSPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_invalidExtF80M( zSPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ64 = packToExtF80UI64( signZ, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64( signZ, 0 ); - uiZ0 = 0; - uiZ: - zSPtr->signExp = uiZ64; - zSPtr->signif = uiZ0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_eq.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_eq.c deleted file mode 100644 index 248003710..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_eq.c +++ /dev/null @@ -1,98 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool extF80M_eq( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - - return extF80_eq( *aPtr, *bPtr ); - -} - -#else - -bool extF80M_eq( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiB64; - uint64_t uiB0; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) - || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( uiA0 == uiB0 ) { - return (uiA64 == uiB64) || ! uiA0; - } else { - if ( ! ((uiA0 & uiB0) & UINT64_C( 0x8000000000000000 )) ) { - return ! softfloat_compareNonnormExtF80M( aSPtr, bSPtr ); - } - return false; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_eq_signaling.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_eq_signaling.c deleted file mode 100644 index 785eba1eb..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_eq_signaling.c +++ /dev/null @@ -1,92 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool extF80M_eq_signaling( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - - return extF80_eq_signaling( *aPtr, *bPtr ); - -} - -#else - -bool extF80M_eq_signaling( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiB64; - uint64_t uiB0; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( uiA0 == uiB0 ) { - return (uiA64 == uiB64) || ! uiA0; - } else { - if ( ! ((uiA0 & uiB0) & UINT64_C( 0x8000000000000000 )) ) { - return ! softfloat_compareNonnormExtF80M( aSPtr, bSPtr ); - } - return false; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_le.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_le.c deleted file mode 100644 index 24edae877..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_le.c +++ /dev/null @@ -1,106 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool extF80M_le( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - - return extF80_le( *aPtr, *bPtr ); - -} - -#else - -bool extF80M_le( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiB64; - uint64_t uiB0; - bool signA, ltMags; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signExtF80UI64( uiA64 ); - if ( (uiA64 ^ uiB64) & 0x8000 ) { - /*-------------------------------------------------------------------- - | Signs are different. - *--------------------------------------------------------------------*/ - return signA || ! (uiA0 | uiB0); - } else { - /*-------------------------------------------------------------------- - | Signs are the same. - *--------------------------------------------------------------------*/ - if ( ! ((uiA0 & uiB0) & UINT64_C( 0x8000000000000000 )) ) { - return (softfloat_compareNonnormExtF80M( aSPtr, bSPtr ) <= 0); - } - if ( uiA64 == uiB64 ) { - if ( uiA0 == uiB0 ) return true; - ltMags = (uiA0 < uiB0); - } else { - ltMags = (uiA64 < uiB64); - } - return signA ^ ltMags; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_le_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_le_quiet.c deleted file mode 100644 index 3880e36d5..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_le_quiet.c +++ /dev/null @@ -1,112 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool extF80M_le_quiet( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - - return extF80_le_quiet( *aPtr, *bPtr ); - -} - -#else - -bool extF80M_le_quiet( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiB64; - uint64_t uiB0; - bool signA, ltMags; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) - || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signExtF80UI64( uiA64 ); - if ( (uiA64 ^ uiB64) & 0x8000 ) { - /*-------------------------------------------------------------------- - | Signs are different. - *--------------------------------------------------------------------*/ - return signA || ! (uiA0 | uiB0); - } else { - /*-------------------------------------------------------------------- - | Signs are the same. - *--------------------------------------------------------------------*/ - if ( ! ((uiA0 & uiB0) & UINT64_C( 0x8000000000000000 )) ) { - return (softfloat_compareNonnormExtF80M( aSPtr, bSPtr ) <= 0); - } - if ( uiA64 == uiB64 ) { - if ( uiA0 == uiB0 ) return true; - ltMags = (uiA0 < uiB0); - } else { - ltMags = (uiA64 < uiB64); - } - return signA ^ ltMags; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_lt.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_lt.c deleted file mode 100644 index 70fa8f05d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_lt.c +++ /dev/null @@ -1,106 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool extF80M_lt( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - - return extF80_lt( *aPtr, *bPtr ); - -} - -#else - -bool extF80M_lt( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiB64; - uint64_t uiB0; - bool signA, ltMags; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signExtF80UI64( uiA64 ); - if ( (uiA64 ^ uiB64) & 0x8000 ) { - /*-------------------------------------------------------------------- - | Signs are different. - *--------------------------------------------------------------------*/ - return signA && ((uiA0 | uiB0) != 0); - } else { - /*-------------------------------------------------------------------- - | Signs are the same. - *--------------------------------------------------------------------*/ - if ( ! ((uiA0 & uiB0) & UINT64_C( 0x8000000000000000 )) ) { - return (softfloat_compareNonnormExtF80M( aSPtr, bSPtr ) < 0); - } - if ( uiA64 == uiB64 ) { - if ( uiA0 == uiB0 ) return false; - ltMags = (uiA0 < uiB0); - } else { - ltMags = (uiA64 < uiB64); - } - return signA ^ ltMags; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_lt_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_lt_quiet.c deleted file mode 100644 index b119af308..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_lt_quiet.c +++ /dev/null @@ -1,112 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool extF80M_lt_quiet( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - - return extF80_lt_quiet( *aPtr, *bPtr ); - -} - -#else - -bool extF80M_lt_quiet( const extFloat80_t *aPtr, const extFloat80_t *bPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint64_t uiA0; - uint_fast16_t uiB64; - uint64_t uiB0; - bool signA, ltMags; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) - || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signExtF80UI64( uiA64 ); - if ( (uiA64 ^ uiB64) & 0x8000 ) { - /*-------------------------------------------------------------------- - | Signs are different. - *--------------------------------------------------------------------*/ - return signA && ((uiA0 | uiB0) != 0); - } else { - /*-------------------------------------------------------------------- - | Signs are the same. - *--------------------------------------------------------------------*/ - if ( ! ((uiA0 & uiB0) & UINT64_C( 0x8000000000000000 )) ) { - return (softfloat_compareNonnormExtF80M( aSPtr, bSPtr ) < 0); - } - if ( uiA64 == uiB64 ) { - if ( uiA0 == uiB0 ) return false; - ltMags = (uiA0 < uiB0); - } else { - ltMags = (uiA64 < uiB64); - } - return signA ^ ltMags; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_mul.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_mul.c deleted file mode 100644 index 273444900..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_mul.c +++ /dev/null @@ -1,139 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - extF80M_mul( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - - *zPtr = extF80_mul( *aPtr, *bPtr ); - -} - -#else - -void - extF80M_mul( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - struct extFloat80M *zSPtr; - uint_fast16_t uiA64; - int32_t expA; - uint_fast16_t uiB64; - int32_t expB; - bool signZ; - uint_fast16_t exp, uiZ64; - uint64_t uiZ0, sigA, sigB; - int32_t expZ; - uint32_t sigProd[4], *extSigZPtr; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - zSPtr = (struct extFloat80M *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - expA = expExtF80UI64( uiA64 ); - uiB64 = bSPtr->signExp; - expB = expExtF80UI64( uiB64 ); - signZ = signExtF80UI64( uiA64 ) ^ signExtF80UI64( uiB64 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNExtF80M( aSPtr, bSPtr, zSPtr ) ) return; - if ( - (! aSPtr->signif && (expA != 0x7FFF)) - || (! bSPtr->signif && (expB != 0x7FFF)) - ) { - softfloat_invalidExtF80M( zSPtr ); - return; - } - uiZ64 = packToExtF80UI64( signZ, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) expA = 1; - sigA = aSPtr->signif; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigA ) goto zero; - expA += softfloat_normExtF80SigM( &sigA ); - } - if ( ! expB ) expB = 1; - sigB = bSPtr->signif; - if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigB ) goto zero; - expB += softfloat_normExtF80SigM( &sigB ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x3FFE; - softfloat_mul64To128M( sigA, sigB, sigProd ); - if ( sigProd[indexWordLo( 4 )] ) sigProd[indexWord( 4, 1 )] |= 1; - extSigZPtr = &sigProd[indexMultiwordHi( 4, 3 )]; - if ( sigProd[indexWordHi( 4 )] < 0x80000000 ) { - --expZ; - softfloat_add96M( extSigZPtr, extSigZPtr, extSigZPtr ); - } - softfloat_roundPackMToExtF80M( - signZ, expZ, extSigZPtr, extF80_roundingPrecision, zSPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64( signZ, 0 ); - uiZ0 = 0; - uiZ: - zSPtr->signExp = uiZ64; - zSPtr->signif = uiZ0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_rem.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_rem.c deleted file mode 100644 index 065e271a7..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_rem.c +++ /dev/null @@ -1,204 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - extF80M_rem( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - - *zPtr = extF80_rem( *aPtr, *bPtr ); - -} - -#else - -void - extF80M_rem( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - struct extFloat80M *zSPtr; - uint_fast16_t uiA64; - int32_t expA, expB; - uint64_t x64; - bool signRem; - uint64_t sigA; - int32_t expDiff; - uint32_t rem[3], x[3], sig32B, q, recip32, rem2[3], *remPtr, *altRemPtr; - uint32_t *newRemPtr, wordMeanRem; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - zSPtr = (struct extFloat80M *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - expA = expExtF80UI64( uiA64 ); - expB = expExtF80UI64( bSPtr->signExp ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNExtF80M( aSPtr, bSPtr, zSPtr ) ) return; - if ( expA == 0x7FFF ) goto invalid; - /*-------------------------------------------------------------------- - | If we get here, then argument b is an infinity and `expB' is 0x7FFF; - | Doubling `expB' is an easy way to ensure that `expDiff' later is - | less than -1, which will result in returning a canonicalized version - | of argument a. - *--------------------------------------------------------------------*/ - expB += expB; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) expB = 1; - x64 = bSPtr->signif; - if ( ! (x64 & UINT64_C( 0x8000000000000000 )) ) { - if ( ! x64 ) goto invalid; - expB += softfloat_normExtF80SigM( &x64 ); - } - signRem = signExtF80UI64( uiA64 ); - if ( ! expA ) expA = 1; - sigA = aSPtr->signif; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigA ) { - expA = 0; - goto copyA; - } - expA += softfloat_normExtF80SigM( &sigA ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( expDiff < -1 ) goto copyA; - rem[indexWord( 3, 2 )] = sigA>>34; - rem[indexWord( 3, 1 )] = sigA>>2; - rem[indexWord( 3, 0 )] = (uint32_t) sigA<<30; - x[indexWord( 3, 0 )] = (uint32_t) x64<<30; - sig32B = x64>>32; - x64 >>= 2; - x[indexWord( 3, 2 )] = x64>>32; - x[indexWord( 3, 1 )] = x64; - if ( expDiff < 1 ) { - if ( expDiff ) { - --expB; - softfloat_add96M( x, x, x ); - q = 0; - } else { - q = (softfloat_compare96M( x, rem ) <= 0); - if ( q ) softfloat_sub96M( rem, x, rem ); - } - } else { - recip32 = softfloat_approxRecip32_1( sig32B ); - expDiff -= 30; - for (;;) { - x64 = (uint64_t) rem[indexWordHi( 3 )] * recip32; - if ( expDiff < 0 ) break; - q = (x64 + 0x80000000)>>32; - softfloat_remStep96MBy32( rem, 29, x, q, rem ); - if ( rem[indexWordHi( 3 )] & 0x80000000 ) { - softfloat_add96M( rem, x, rem ); - } - expDiff -= 29; - } - /*-------------------------------------------------------------------- - | (`expDiff' cannot be less than -29 here.) - *--------------------------------------------------------------------*/ - q = (uint32_t) (x64>>32)>>(~expDiff & 31); - softfloat_remStep96MBy32( rem, expDiff + 30, x, q, rem ); - if ( rem[indexWordHi( 3 )] & 0x80000000 ) { - remPtr = rem; - altRemPtr = rem2; - softfloat_add96M( remPtr, x, altRemPtr ); - goto selectRem; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - remPtr = rem; - altRemPtr = rem2; - do { - ++q; - newRemPtr = altRemPtr; - softfloat_sub96M( remPtr, x, newRemPtr ); - altRemPtr = remPtr; - remPtr = newRemPtr; - } while ( ! (remPtr[indexWordHi( 3 )] & 0x80000000) ); - selectRem: - softfloat_add96M( remPtr, altRemPtr, x ); - wordMeanRem = x[indexWordHi( 3 )]; - if ( - (wordMeanRem & 0x80000000) - || (! wordMeanRem && (q & 1) && ! x[indexWord( 3, 0 )] - && ! x[indexWord( 3, 1 )]) - ) { - remPtr = altRemPtr; - } - if ( remPtr[indexWordHi( 3 )] & 0x80000000 ) { - signRem = ! signRem; - softfloat_negX96M( remPtr ); - } - softfloat_normRoundPackMToExtF80M( signRem, expB + 2, remPtr, 80, zSPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_invalidExtF80M( zSPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - copyA: - if ( expA < 1 ) { - sigA >>= 1 - expA; - expA = 0; - } - zSPtr->signExp = packToExtF80UI64( signRem, expA ); - zSPtr->signif = sigA; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_roundToInt.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_roundToInt.c deleted file mode 100644 index ff4ae876a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_roundToInt.c +++ /dev/null @@ -1,176 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - extF80M_roundToInt( - const extFloat80_t *aPtr, - uint_fast8_t roundingMode, - bool exact, - extFloat80_t *zPtr - ) -{ - - *zPtr = extF80_roundToInt( *aPtr, roundingMode, exact ); - -} - -#else - -void - extF80M_roundToInt( - const extFloat80_t *aPtr, - uint_fast8_t roundingMode, - bool exact, - extFloat80_t *zPtr - ) -{ - const struct extFloat80M *aSPtr; - struct extFloat80M *zSPtr; - uint_fast16_t uiA64, signUI64; - int32_t exp; - uint64_t sigA; - uint_fast16_t uiZ64; - uint64_t sigZ, lastBitMask, roundBitsMask; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - zSPtr = (struct extFloat80M *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - signUI64 = uiA64 & packToExtF80UI64( 1, 0 ); - exp = expExtF80UI64( uiA64 ); - sigA = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( !(sigA & UINT64_C( 0x8000000000000000 )) && (exp != 0x7FFF) ) { - if ( !sigA ) { - uiZ64 = signUI64; - sigZ = 0; - goto uiZ; - } - exp += softfloat_normExtF80SigM( &sigA ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp <= 0x3FFE ) { - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - switch ( roundingMode ) { - case softfloat_round_near_even: - if ( !(sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) break; - case softfloat_round_near_maxMag: - if ( exp == 0x3FFE ) goto mag1; - break; - case softfloat_round_min: - if ( signUI64 ) goto mag1; - break; - case softfloat_round_max: - if ( !signUI64 ) goto mag1; - break; -#ifdef SOFTFLOAT_ROUND_ODD - case softfloat_round_odd: - goto mag1; -#endif - } - uiZ64 = signUI64; - sigZ = 0; - goto uiZ; - mag1: - uiZ64 = signUI64 | 0x3FFF; - sigZ = UINT64_C( 0x8000000000000000 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x403E <= exp ) { - if ( exp == 0x7FFF ) { - if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_propagateNaNExtF80M( aSPtr, 0, zSPtr ); - return; - } - sigZ = UINT64_C( 0x8000000000000000 ); - } else { - sigZ = sigA; - } - uiZ64 = signUI64 | exp; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = signUI64 | exp; - lastBitMask = (uint64_t) 1<<(0x403E - exp); - roundBitsMask = lastBitMask - 1; - sigZ = sigA; - if ( roundingMode == softfloat_round_near_maxMag ) { - sigZ += lastBitMask>>1; - } else if ( roundingMode == softfloat_round_near_even ) { - sigZ += lastBitMask>>1; - if ( !(sigZ & roundBitsMask) ) sigZ &= ~lastBitMask; - } else if ( - roundingMode == (signUI64 ? softfloat_round_min : softfloat_round_max) - ) { - sigZ += roundBitsMask; - } - sigZ &= ~roundBitsMask; - if ( !sigZ ) { - ++uiZ64; - sigZ = UINT64_C( 0x8000000000000000 ); - } - if ( sigZ != sigA ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) sigZ |= lastBitMask; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - uiZ: - zSPtr->signExp = uiZ64; - zSPtr->signif = sigZ; - return; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_sqrt.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_sqrt.c deleted file mode 100644 index 21c15da07..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_sqrt.c +++ /dev/null @@ -1,180 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void extF80M_sqrt( const extFloat80_t *aPtr, extFloat80_t *zPtr ) -{ - - *zPtr = extF80_sqrt( *aPtr ); - -} - -#else - -void extF80M_sqrt( const extFloat80_t *aPtr, extFloat80_t *zPtr ) -{ - const struct extFloat80M *aSPtr; - struct extFloat80M *zSPtr; - uint_fast16_t uiA64, signUI64; - int32_t expA; - uint64_t rem64; - int32_t expZ; - uint32_t rem96[3], sig32A, recipSqrt32, sig32Z, q; - uint64_t sig64Z, x64; - uint32_t rem32, term[4], rem[4], extSigZ[3]; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - zSPtr = (struct extFloat80M *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - signUI64 = uiA64 & packToExtF80UI64( 1, 0 ); - expA = expExtF80UI64( uiA64 ); - rem64 = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( rem64 & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_propagateNaNExtF80M( aSPtr, 0, zSPtr ); - return; - } - if ( signUI64 ) goto invalid; - rem64 = UINT64_C( 0x8000000000000000 ); - goto copyA; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) expA = 1; - if ( ! (rem64 & UINT64_C( 0x8000000000000000 )) ) { - if ( ! rem64 ) { - uiA64 = signUI64; - goto copyA; - } - expA += softfloat_normExtF80SigM( &rem64 ); - } - if ( signUI64 ) goto invalid; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = ((expA - 0x3FFF)>>1) + 0x3FFF; - expA &= 1; - softfloat_shortShiftLeft64To96M( rem64, 30 - expA, rem96 ); - sig32A = rem64>>32; - recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A ); - sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32; - if ( expA ) sig32Z >>= 1; - rem64 = - ((uint64_t) rem96[indexWord( 3, 2 )]<<32 | rem96[indexWord( 3, 1 )]) - - (uint64_t) sig32Z * sig32Z; - rem96[indexWord( 3, 2 )] = rem64>>32; - rem96[indexWord( 3, 1 )] = rem64; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = ((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32; - sig64Z = ((uint64_t) sig32Z<<32) + ((uint64_t) q<<3); - term[indexWord( 3, 2 )] = 0; - /*------------------------------------------------------------------------ - | (Repeating this loop is a rare occurrence.) - *------------------------------------------------------------------------*/ - for (;;) { - x64 = ((uint64_t) sig32Z<<32) + sig64Z; - term[indexWord( 3, 1 )] = x64>>32; - term[indexWord( 3, 0 )] = x64; - softfloat_remStep96MBy32( - rem96, 29, term, q, &rem[indexMultiwordHi( 4, 3 )] ); - rem32 = rem[indexWord( 4, 3 )]; - if ( ! (rem32 & 0x80000000) ) break; - --q; - sig64Z -= 1<<3; - } - rem64 = (uint64_t) rem32<<32 | rem[indexWord( 4, 2 )]; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = (((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32) + 2; - if ( rem64>>34 ) q += recipSqrt32; - x64 = (uint64_t) q<<7; - extSigZ[indexWord( 3, 0 )] = x64; - x64 = (sig64Z<<1) + (x64>>32); - extSigZ[indexWord( 3, 2 )] = x64>>32; - extSigZ[indexWord( 3, 1 )] = x64; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (q & 0xFFFFFF) <= 2 ) { - q &= ~(uint32_t) 0xFFFF; - extSigZ[indexWordLo( 3 )] = q<<7; - x64 = sig64Z + (q>>27); - term[indexWord( 4, 3 )] = 0; - term[indexWord( 4, 2 )] = x64>>32; - term[indexWord( 4, 1 )] = x64; - term[indexWord( 4, 0 )] = q<<5; - rem[indexWord( 4, 0 )] = 0; - softfloat_remStep128MBy32( rem, 28, term, q, rem ); - q = rem[indexWordHi( 4 )]; - if ( q & 0x80000000 ) { - softfloat_sub1X96M( extSigZ ); - } else { - if ( q || rem[indexWord( 4, 1 )] || rem[indexWord( 4, 2 )] ) { - extSigZ[indexWordLo( 3 )] |= 1; - } - } - } - softfloat_roundPackMToExtF80M( - 0, expZ, extSigZ, extF80_roundingPrecision, zSPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_invalidExtF80M( zSPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - copyA: - zSPtr->signExp = uiA64; - zSPtr->signif = rem64; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_sub.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_sub.c deleted file mode 100644 index 4f9f1a623..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_sub.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - extF80M_sub( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - const struct extFloat80M *aSPtr, *bSPtr; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - extFloat80_t - (*magsFuncPtr)( - uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); -#endif - - aSPtr = (const struct extFloat80M *) aPtr; - bSPtr = (const struct extFloat80M *) bPtr; - uiA64 = aSPtr->signExp; - uiA0 = aSPtr->signif; - signA = signExtF80UI64( uiA64 ); - uiB64 = bSPtr->signExp; - uiB0 = bSPtr->signif; - signB = signExtF80UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - *zPtr = softfloat_subMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - *zPtr = softfloat_addMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_subMagsExtF80 : softfloat_addMagsExtF80; - *zPtr = (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - -#else - -void - extF80M_sub( - const extFloat80_t *aPtr, const extFloat80_t *bPtr, extFloat80_t *zPtr ) -{ - - softfloat_addExtF80M( - (const struct extFloat80M *) aPtr, - (const struct extFloat80M *) bPtr, - (struct extFloat80M *) zPtr, - true - ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f128M.c deleted file mode 100644 index c0306af82..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f128M.c +++ /dev/null @@ -1,125 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *zPtr ) -{ - - *zPtr = extF80_to_f128( *aPtr ); - -} - -#else - -void extF80M_to_f128M( const extFloat80_t *aPtr, float128_t *zPtr ) -{ - const struct extFloat80M *aSPtr; - uint32_t *zWPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - struct commonNaN commonNaN; - uint32_t uiZ96; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zWPtr[indexWord( 4, 0 )] = 0; - if ( exp == 0x7FFF ) { - if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); - softfloat_commonNaNToF128M( &commonNaN, zWPtr ); - return; - } - uiZ96 = packToF128UI96( sign, 0x7FFF, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) --exp; - if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sig ) { - uiZ96 = packToF128UI96( sign, 0, 0 ); - goto uiZ; - } - exp += softfloat_normExtF80SigM( &sig ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zWPtr[indexWord( 4, 1 )] = (uint32_t) sig<<17; - sig >>= 15; - zWPtr[indexWord( 4, 2 )] = sig; - if ( exp < 0 ) { - zWPtr[indexWordHi( 4 )] = sig>>32; - softfloat_shiftRight96M( - &zWPtr[indexMultiwordHi( 4, 3 )], - -exp, - &zWPtr[indexMultiwordHi( 4, 3 )] - ); - exp = 0; - sig = (uint64_t) zWPtr[indexWordHi( 4 )]<<32; - } - zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, exp, sig>>32 ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f16.c deleted file mode 100644 index 7ff56de2d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f16.c +++ /dev/null @@ -1,112 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -float16_t extF80M_to_f16( const extFloat80_t *aPtr ) -{ - - return extF80_to_f16( *aPtr ); - -} - -#else - -float16_t extF80M_to_f16( const extFloat80_t *aPtr ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - struct commonNaN commonNaN; - uint16_t uiZ, sig16; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); - uiZ = softfloat_commonNaNToF16UI( &commonNaN ); - } else { - uiZ = packToF16UI( sign, 0x1F, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sig ) { - uiZ = packToF16UI( sign, 0, 0 ); - goto uiZ; - } - exp += softfloat_normExtF80SigM( &sig ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig16 = softfloat_shortShiftRightJam64( sig, 49 ); - exp -= 0x3FF1; - if ( sizeof (int_fast16_t) < sizeof (int32_t) ) { - if ( exp < -0x40 ) exp = -0x40; - } - return softfloat_roundPackToF16( sign, exp, sig16 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f32.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f32.c deleted file mode 100644 index bb1166f97..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f32.c +++ /dev/null @@ -1,112 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -float32_t extF80M_to_f32( const extFloat80_t *aPtr ) -{ - - return extF80_to_f32( *aPtr ); - -} - -#else - -float32_t extF80M_to_f32( const extFloat80_t *aPtr ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - struct commonNaN commonNaN; - uint32_t uiZ, sig32; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); - uiZ = softfloat_commonNaNToF32UI( &commonNaN ); - } else { - uiZ = packToF32UI( sign, 0xFF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sig ) { - uiZ = packToF32UI( sign, 0, 0 ); - goto uiZ; - } - exp += softfloat_normExtF80SigM( &sig ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig32 = softfloat_shortShiftRightJam64( sig, 33 ); - exp -= 0x3F81; - if ( sizeof (int_fast16_t) < sizeof (int32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return softfloat_roundPackToF32( sign, exp, sig32 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f64.c deleted file mode 100644 index 696255f87..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_f64.c +++ /dev/null @@ -1,112 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -float64_t extF80M_to_f64( const extFloat80_t *aPtr ) -{ - - return extF80_to_f64( *aPtr ); - -} - -#else - -float64_t extF80M_to_f64( const extFloat80_t *aPtr ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - struct commonNaN commonNaN; - uint64_t uiZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_extF80MToCommonNaN( aSPtr, &commonNaN ); - uiZ = softfloat_commonNaNToF64UI( &commonNaN ); - } else { - uiZ = packToF64UI( sign, 0x7FF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! (sig & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sig ) { - uiZ = packToF64UI( sign, 0, 0 ); - goto uiZ; - } - exp += softfloat_normExtF80SigM( &sig ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = softfloat_shortShiftRightJam64( sig, 1 ); - exp -= 0x3C01; - if ( sizeof (int_fast16_t) < sizeof (int32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return softfloat_roundPackToF64( sign, exp, sig ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i32.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i32.c deleted file mode 100644 index c0464b138..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i32.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast32_t - extF80M_to_i32( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return extF80_to_i32( *aPtr, roundingMode, exact ); - -} - -#else - -int_fast32_t - extF80M_to_i32( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x4032 - exp; - if ( shiftDist <= 0 ) { - if ( sig>>32 ) goto invalid; - if ( -32 < shiftDist ) { - sig <<= -shiftDist; - } else { - if ( (uint32_t) sig ) goto invalid; - } - } else { - sig = softfloat_shiftRightJam64( sig, shiftDist ); - } - return softfloat_roundToI32( sign, sig, roundingMode, exact ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ? i32_fromNaN - : sign ? i32_fromNegOverflow : i32_fromPosOverflow; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i32_r_minMag.c deleted file mode 100644 index 9a803cc23..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i32_r_minMag.c +++ /dev/null @@ -1,120 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - - return extF80_to_i32_r_minMag( *aPtr, exact ); - -} - -#else - -int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - bool sign, raiseInexact; - int32_t z; - uint64_t shiftedSig; - uint32_t absZ; - union { uint32_t ui; int32_t i; } u; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - raiseInexact = exact; - z = 0; - } else { - sign = signExtF80UI64( uiA64 ); - raiseInexact = false; - if ( shiftDist < 0 ) { - if ( sig>>32 || (shiftDist <= -31) ) goto invalid; - shiftedSig = (uint64_t) (uint32_t) sig<<-shiftDist; - if ( shiftedSig>>32 ) goto invalid; - absZ = shiftedSig; - } else { - shiftedSig = sig; - if ( shiftDist ) shiftedSig >>= shiftDist; - if ( shiftedSig>>32 ) goto invalid; - absZ = shiftedSig; - if ( exact && shiftDist ) { - raiseInexact = ((uint64_t) absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast64_t - extF80M_to_i64( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return extF80_to_i64( *aPtr, roundingMode, exact ); - -} - -#else - -int_fast64_t - extF80M_to_i64( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - uint32_t extSig[3]; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( shiftDist < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - extSig[indexWord( 3, 2 )] = sig>>32; - extSig[indexWord( 3, 1 )] = sig; - extSig[indexWord( 3, 0 )] = 0; - if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - return softfloat_roundMToI64( sign, extSig, roundingMode, exact ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i64_r_minMag.c deleted file mode 100644 index 07282cd42..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_i64_r_minMag.c +++ /dev/null @@ -1,115 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - - return extF80_to_i64_r_minMag( *aPtr, exact ); - -} - -#else - -int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - bool sign, raiseInexact; - int64_t z; - uint64_t absZ; - union { uint64_t ui; int64_t i; } u; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - raiseInexact = exact; - z = 0; - } else { - sign = signExtF80UI64( uiA64 ); - raiseInexact = false; - if ( shiftDist < 0 ) { - if ( shiftDist <= -63 ) goto invalid; - shiftDist = -shiftDist; - absZ = sig<>shiftDist != sig ) goto invalid; - } else { - absZ = sig; - if ( shiftDist ) absZ >>= shiftDist; - if ( exact && shiftDist ) raiseInexact = (absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast32_t - extF80M_to_ui32( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return extF80_to_ui32( *aPtr, roundingMode, exact ); - -} - -#else - -uint_fast32_t - extF80M_to_ui32( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x4032 - exp; - if ( shiftDist <= 0 ) { - if ( sig>>32 ) goto invalid; - if ( -32 < shiftDist ) { - sig <<= -shiftDist; - } else { - if ( (uint32_t) sig ) goto invalid; - } - } else { - sig = softfloat_shiftRightJam64( sig, shiftDist ); - } - return softfloat_roundToUI32( sign, sig, roundingMode, exact ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_ui32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_ui32_r_minMag.c deleted file mode 100644 index c09e48341..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_ui32_r_minMag.c +++ /dev/null @@ -1,111 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - - return extF80_to_ui32_r_minMag( *aPtr, exact ); - -} - -#else - -uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - bool sign; - uint64_t shiftedSig; - uint32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signExtF80UI64( uiA64 ); - if ( shiftDist < 0 ) { - if ( sign || sig>>32 || (shiftDist <= -31) ) goto invalid; - shiftedSig = (uint64_t) (uint32_t) sig<<-shiftDist; - if ( shiftedSig>>32 ) goto invalid; - z = shiftedSig; - } else { - shiftedSig = sig; - if ( shiftDist ) shiftedSig >>= shiftDist; - if ( shiftedSig>>32 ) goto invalid; - z = shiftedSig; - if ( sign && z ) goto invalid; - if ( exact && shiftDist && ((uint64_t) z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast64_t - extF80M_to_ui64( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return extF80_to_ui64( *aPtr, roundingMode, exact ); - -} - -#else - -uint_fast64_t - extF80M_to_ui64( - const extFloat80_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - bool sign; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - uint32_t extSig[3]; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( shiftDist < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - extSig[indexWord( 3, 2 )] = sig>>32; - extSig[indexWord( 3, 1 )] = sig; - extSig[indexWord( 3, 0 )] = 0; - if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_ui64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_ui64_r_minMag.c deleted file mode 100644 index bf4839032..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80M_to_ui64_r_minMag.c +++ /dev/null @@ -1,108 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - - return extF80_to_ui64_r_minMag( *aPtr, exact ); - -} - -#else - -uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *aPtr, bool exact ) -{ - const struct extFloat80M *aSPtr; - uint_fast16_t uiA64; - int32_t exp; - uint64_t sig; - int32_t shiftDist; - bool sign; - uint64_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aSPtr = (const struct extFloat80M *) aPtr; - uiA64 = aSPtr->signExp; - exp = expExtF80UI64( uiA64 ); - sig = aSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! sig && (exp != 0x7FFF) ) return 0; - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signExtF80UI64( uiA64 ); - if ( shiftDist < 0 ) { - if ( sign || (shiftDist <= -63) ) goto invalid; - shiftDist = -shiftDist; - z = sig<>shiftDist != sig ) goto invalid; - } else { - z = sig; - if ( shiftDist ) z >>= shiftDist; - if ( sign && z ) goto invalid; - if ( exact && shiftDist && (z< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -extFloat80_t extF80_add( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - extFloat80_t - (*magsFuncPtr)( - uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); -#endif - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - signA = signExtF80UI64( uiA64 ); - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - signB = signExtF80UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_addMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - return softfloat_subMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_addMagsExtF80 : softfloat_subMagsExtF80; - return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_div.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_div.c deleted file mode 100644 index 7d649c549..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_div.c +++ /dev/null @@ -1,203 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t extF80_div( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - int_fast32_t expA; - uint_fast64_t sigA; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signB; - int_fast32_t expB; - uint_fast64_t sigB; - bool signZ; - struct exp32_sig64 normExpSig; - int_fast32_t expZ; - struct uint128 rem; - uint_fast32_t recip32; - uint_fast64_t sigZ; - int ix; - uint_fast64_t q64; - uint_fast32_t q; - struct uint128 term; - uint_fast64_t sigZExtra; - struct uint128 uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - signA = signExtF80UI64( uiA64 ); - expA = expExtF80UI64( uiA64 ); - sigA = uiA0; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - signB = signExtF80UI64( uiB64 ); - expB = expExtF80UI64( uiB64 ); - sigB = uiB0; - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - if ( expB == 0x7FFF ) { - if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - goto invalid; - } - goto infinity; - } - if ( expB == 0x7FFF ) { - if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) expB = 1; - if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigB ) { - if ( ! sigA ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinite ); - goto infinity; - } - normExpSig = softfloat_normSubnormalExtF80Sig( sigB ); - expB += normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) expA = 1; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalExtF80Sig( sigA ); - expA += normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA - expB + 0x3FFF; - if ( sigA < sigB ) { - --expZ; - rem = softfloat_shortShiftLeft128( 0, sigA, 32 ); - } else { - rem = softfloat_shortShiftLeft128( 0, sigA, 31 ); - } - recip32 = softfloat_approxRecip32_1( sigB>>32 ); - sigZ = 0; - ix = 2; - for (;;) { - q64 = (uint_fast64_t) (uint32_t) (rem.v64>>2) * recip32; - q = (q64 + 0x80000000)>>32; - --ix; - if ( ix < 0 ) break; - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - term = softfloat_mul64ByShifted32To128( sigB, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - --q; - rem = softfloat_add128( rem.v64, rem.v0, sigB>>32, sigB<<32 ); - } - sigZ = (sigZ<<29) + q; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ((q + 1) & 0x3FFFFF) < 2 ) { - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - term = softfloat_mul64ByShifted32To128( sigB, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - term = softfloat_shortShiftLeft128( 0, sigB, 32 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - --q; - rem = softfloat_add128( rem.v64, rem.v0, term.v64, term.v0 ); - } else if ( softfloat_le128( term.v64, term.v0, rem.v64, rem.v0 ) ) { - ++q; - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - } - if ( rem.v64 | rem.v0 ) q |= 1; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sigZ = (sigZ<<6) + (q>>23); - sigZExtra = (uint64_t) ((uint_fast64_t) q<<41); - return - softfloat_roundPackToExtF80( - signZ, expZ, sigZ, sigZExtra, extF80_roundingPrecision ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, uiB64, uiB0 ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ64 = packToExtF80UI64( signZ, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64( signZ, 0 ); - uiZ0 = 0; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_eq.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_eq.c deleted file mode 100644 index 60f29dafa..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_eq.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool extF80_eq( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) - || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - return - (uiA0 == uiB0) - && ((uiA64 == uiB64) || (! uiA0 && ! ((uiA64 | uiB64) & 0x7FFF))); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_eq_signaling.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_eq_signaling.c deleted file mode 100644 index 5a0dfe4aa..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_eq_signaling.c +++ /dev/null @@ -1,67 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool extF80_eq_signaling( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - return - (uiA0 == uiB0) - && ((uiA64 == uiB64) || (! uiA0 && ! ((uiA64 | uiB64) & 0x7FFF))); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_isSignalingNaN.c deleted file mode 100644 index 6086f4b70..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_isSignalingNaN.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool extF80_isSignalingNaN( extFloat80_t a ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - - uA.f = a; - return softfloat_isSigNaNExtF80UI( uA.s.signExp, uA.s.signif ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_le.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_le.c deleted file mode 100644 index 2a1ee60f6..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_le.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool extF80_le( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signExtF80UI64( uiA64 ); - signB = signExtF80UI64( uiB64 ); - return - (signA != signB) - ? signA || ! (((uiA64 | uiB64) & 0x7FFF) | uiA0 | uiB0) - : ((uiA64 == uiB64) && (uiA0 == uiB0)) - || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_le_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_le_quiet.c deleted file mode 100644 index 5d0c3ae73..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_le_quiet.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool extF80_le_quiet( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) - || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signExtF80UI64( uiA64 ); - signB = signExtF80UI64( uiB64 ); - return - (signA != signB) - ? signA || ! (((uiA64 | uiB64) & 0x7FFF) | uiA0 | uiB0) - : ((uiA64 == uiB64) && (uiA0 == uiB0)) - || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_lt.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_lt.c deleted file mode 100644 index 9560d8ecc..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_lt.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool extF80_lt( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signExtF80UI64( uiA64 ); - signB = signExtF80UI64( uiB64 ); - return - (signA != signB) - ? signA && (((uiA64 | uiB64) & 0x7FFF) | uiA0 | uiB0) - : ((uiA64 != uiB64) || (uiA0 != uiB0)) - && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_lt_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_lt_quiet.c deleted file mode 100644 index 711652c7d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_lt_quiet.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool extF80_lt_quiet( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - if ( isNaNExtF80UI( uiA64, uiA0 ) || isNaNExtF80UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) - || softfloat_isSigNaNExtF80UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signExtF80UI64( uiA64 ); - signB = signExtF80UI64( uiB64 ); - return - (signA != signB) - ? signA && (((uiA64 | uiB64) & 0x7FFF) | uiA0 | uiB0) - : ((uiA64 != uiB64) || (uiA0 != uiB0)) - && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_mul.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_mul.c deleted file mode 100644 index c0c50a6ca..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_mul.c +++ /dev/null @@ -1,158 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t extF80_mul( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - int_fast32_t expA; - uint_fast64_t sigA; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signB; - int_fast32_t expB; - uint_fast64_t sigB; - bool signZ; - uint_fast64_t magBits; - struct exp32_sig64 normExpSig; - int_fast32_t expZ; - struct uint128 sig128Z, uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - signA = signExtF80UI64( uiA64 ); - expA = expExtF80UI64( uiA64 ); - sigA = uiA0; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - signB = signExtF80UI64( uiB64 ); - expB = expExtF80UI64( uiB64 ); - sigB = uiB0; - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( - (sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - || ((expB == 0x7FFF) && (sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ) { - goto propagateNaN; - } - magBits = expB | sigB; - goto infArg; - } - if ( expB == 0x7FFF ) { - if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - magBits = expA | sigA; - goto infArg; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) expA = 1; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalExtF80Sig( sigA ); - expA += normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) expB = 1; - if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigB ) goto zero; - normExpSig = softfloat_normSubnormalExtF80Sig( sigB ); - expB += normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x3FFE; - sig128Z = softfloat_mul64To128( sigA, sigB ); - if ( sig128Z.v64 < UINT64_C( 0x8000000000000000 ) ) { - --expZ; - sig128Z = - softfloat_add128( - sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0 ); - } - return - softfloat_roundPackToExtF80( - signZ, expZ, sig128Z.v64, sig128Z.v0, extF80_roundingPrecision ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, uiB64, uiB0 ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infArg: - if ( ! magBits ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - } else { - uiZ64 = packToExtF80UI64( signZ, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - } - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64( signZ, 0 ); - uiZ0 = 0; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_rem.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_rem.c deleted file mode 100644 index a2ebaad81..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_rem.c +++ /dev/null @@ -1,225 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t extF80_rem( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - int_fast32_t expA; - uint_fast64_t sigA; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - int_fast32_t expB; - uint_fast64_t sigB; - struct exp32_sig64 normExpSig; - int_fast32_t expDiff; - struct uint128 rem, shiftedSigB; - uint_fast32_t q, recip32; - uint_fast64_t q64; - struct uint128 term, altRem, meanRem; - bool signRem; - struct uint128 uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - signA = signExtF80UI64( uiA64 ); - expA = expExtF80UI64( uiA64 ); - sigA = uiA0; - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - expB = expExtF80UI64( uiB64 ); - sigB = uiB0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( - (sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - || ((expB == 0x7FFF) && (sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ) { - goto propagateNaN; - } - goto invalid; - } - if ( expB == 0x7FFF ) { - if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - /*-------------------------------------------------------------------- - | Argument b is an infinity. Doubling `expB' is an easy way to ensure - | that `expDiff' later is less than -1, which will result in returning - | a canonicalized version of argument a. - *--------------------------------------------------------------------*/ - expB += expB; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) expB = 1; - if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigB ) goto invalid; - normExpSig = softfloat_normSubnormalExtF80Sig( sigB ); - expB += normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) expA = 1; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigA ) { - expA = 0; - goto copyA; - } - normExpSig = softfloat_normSubnormalExtF80Sig( sigA ); - expA += normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( expDiff < -1 ) goto copyA; - rem = softfloat_shortShiftLeft128( 0, sigA, 32 ); - shiftedSigB = softfloat_shortShiftLeft128( 0, sigB, 32 ); - if ( expDiff < 1 ) { - if ( expDiff ) { - --expB; - shiftedSigB = softfloat_shortShiftLeft128( 0, sigB, 33 ); - q = 0; - } else { - q = (sigB <= sigA); - if ( q ) { - rem = - softfloat_sub128( - rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 ); - } - } - } else { - recip32 = softfloat_approxRecip32_1( sigB>>32 ); - expDiff -= 30; - for (;;) { - q64 = (uint_fast64_t) (uint32_t) (rem.v64>>2) * recip32; - if ( expDiff < 0 ) break; - q = (q64 + 0x80000000)>>32; - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - term = softfloat_mul64ByShifted32To128( sigB, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - rem = - softfloat_add128( - rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 ); - } - expDiff -= 29; - } - /*-------------------------------------------------------------------- - | (`expDiff' cannot be less than -29 here.) - *--------------------------------------------------------------------*/ - q = (uint32_t) (q64>>32)>>(~expDiff & 31); - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, expDiff + 30 ); - term = softfloat_mul64ByShifted32To128( sigB, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - altRem = - softfloat_add128( - rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 ); - goto selectRem; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - do { - altRem = rem; - ++q; - rem = - softfloat_sub128( - rem.v64, rem.v0, shiftedSigB.v64, shiftedSigB.v0 ); - } while ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ); - selectRem: - meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 ); - if ( - (meanRem.v64 & UINT64_C( 0x8000000000000000 )) - || (! (meanRem.v64 | meanRem.v0) && (q & 1)) - ) { - rem = altRem; - } - signRem = signA; - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - signRem = ! signRem; - rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 ); - } - return - softfloat_normRoundPackToExtF80( - signRem, rem.v64 | rem.v0 ? expB + 32 : 0, rem.v64, rem.v0, 80 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, uiB64, uiB0 ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - copyA: - if ( expA < 1 ) { - sigA >>= 1 - expA; - expA = 0; - } - uiZ64 = packToExtF80UI64( signA, expA ); - uiZ0 = sigA; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_roundToInt.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_roundToInt.c deleted file mode 100644 index 8103dae8f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_roundToInt.c +++ /dev/null @@ -1,154 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t - extF80_roundToInt( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64, signUI64; - int_fast32_t exp; - uint_fast64_t sigA; - uint_fast16_t uiZ64; - uint_fast64_t sigZ; - struct exp32_sig64 normExpSig; - struct uint128 uiZ; - uint_fast64_t lastBitMask, roundBitsMask; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - signUI64 = uiA64 & packToExtF80UI64( 1, 0 ); - exp = expExtF80UI64( uiA64 ); - sigA = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( !(sigA & UINT64_C( 0x8000000000000000 )) && (exp != 0x7FFF) ) { - if ( !sigA ) { - uiZ64 = signUI64; - sigZ = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalExtF80Sig( sigA ); - exp += normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x403E <= exp ) { - if ( exp == 0x7FFF ) { - if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - uiZ = softfloat_propagateNaNExtF80UI( uiA64, sigA, 0, 0 ); - uiZ64 = uiZ.v64; - sigZ = uiZ.v0; - goto uiZ; - } - sigZ = UINT64_C( 0x8000000000000000 ); - } else { - sigZ = sigA; - } - uiZ64 = signUI64 | exp; - goto uiZ; - } - if ( exp <= 0x3FFE ) { - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - switch ( roundingMode ) { - case softfloat_round_near_even: - if ( !(sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) break; - case softfloat_round_near_maxMag: - if ( exp == 0x3FFE ) goto mag1; - break; - case softfloat_round_min: - if ( signUI64 ) goto mag1; - break; - case softfloat_round_max: - if ( !signUI64 ) goto mag1; - break; -#ifdef SOFTFLOAT_ROUND_ODD - case softfloat_round_odd: - goto mag1; -#endif - } - uiZ64 = signUI64; - sigZ = 0; - goto uiZ; - mag1: - uiZ64 = signUI64 | 0x3FFF; - sigZ = UINT64_C( 0x8000000000000000 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = signUI64 | exp; - lastBitMask = (uint_fast64_t) 1<<(0x403E - exp); - roundBitsMask = lastBitMask - 1; - sigZ = sigA; - if ( roundingMode == softfloat_round_near_maxMag ) { - sigZ += lastBitMask>>1; - } else if ( roundingMode == softfloat_round_near_even ) { - sigZ += lastBitMask>>1; - if ( !(sigZ & roundBitsMask) ) sigZ &= ~lastBitMask; - } else if ( - roundingMode == (signUI64 ? softfloat_round_min : softfloat_round_max) - ) { - sigZ += roundBitsMask; - } - sigZ &= ~roundBitsMask; - if ( !sigZ ) { - ++uiZ64; - sigZ = UINT64_C( 0x8000000000000000 ); - } - if ( sigZ != sigA ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) sigZ |= lastBitMask; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = sigZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_sqrt.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_sqrt.c deleted file mode 100644 index 5d328a0e4..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_sqrt.c +++ /dev/null @@ -1,176 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t extF80_sqrt( extFloat80_t a ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - int_fast32_t expA; - uint_fast64_t sigA; - struct uint128 uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - struct exp32_sig64 normExpSig; - int_fast32_t expZ; - uint_fast32_t sig32A, recipSqrt32, sig32Z; - struct uint128 rem; - uint_fast64_t q, x64, sigZ; - struct uint128 y, term; - uint_fast64_t sigZExtra; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - signA = signExtF80UI64( uiA64 ); - expA = expExtF80UI64( uiA64 ); - sigA = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, 0, 0 ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - goto uiZ; - } - if ( ! signA ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signA ) { - if ( ! sigA ) goto zero; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) expA = 1; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalExtF80Sig( sigA ); - expA += normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - | (`sig32Z' is guaranteed to be a lower bound on the square root of - | `sig32A', which makes `sig32Z' also a lower bound on the square root of - | `sigA'.) - *------------------------------------------------------------------------*/ - expZ = ((expA - 0x3FFF)>>1) + 0x3FFF; - expA &= 1; - sig32A = sigA>>32; - recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A ); - sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32; - if ( expA ) { - sig32Z >>= 1; - rem = softfloat_shortShiftLeft128( 0, sigA, 61 ); - } else { - rem = softfloat_shortShiftLeft128( 0, sigA, 62 ); - } - rem.v64 -= (uint_fast64_t) sig32Z * sig32Z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = ((uint32_t) (rem.v64>>2) * (uint_fast64_t) recipSqrt32)>>32; - x64 = (uint_fast64_t) sig32Z<<32; - sigZ = x64 + (q<<3); - y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - /*------------------------------------------------------------------------ - | (Repeating this loop is a rare occurrence.) - *------------------------------------------------------------------------*/ - for (;;) { - term = softfloat_mul64ByShifted32To128( x64 + sigZ, q ); - rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 ); - if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break; - --q; - sigZ -= 1<<3; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = (((rem.v64>>2) * recipSqrt32)>>32) + 2; - x64 = sigZ; - sigZ = (sigZ<<1) + (q>>25); - sigZExtra = (uint64_t) (q<<39); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (q & 0xFFFFFF) <= 2 ) { - q &= ~(uint_fast64_t) 0xFFFF; - sigZExtra = (uint64_t) (q<<39); - term = softfloat_mul64ByShifted32To128( x64 + (q>>27), q ); - x64 = (uint32_t) (q<<5) * (uint_fast64_t) (uint32_t) q; - term = softfloat_add128( term.v64, term.v0, 0, x64 ); - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 28 ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - if ( ! sigZExtra ) --sigZ; - --sigZExtra; - } else { - if ( rem.v64 | rem.v0 ) sigZExtra |= 1; - } - } - return - softfloat_roundPackToExtF80( - 0, expZ, sigZ, sigZExtra, extF80_roundingPrecision ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ64 = packToExtF80UI64( signA, 0 ); - uiZ0 = 0; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_sub.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_sub.c deleted file mode 100644 index 494d3162c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_sub.c +++ /dev/null @@ -1,80 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -extFloat80_t extF80_sub( extFloat80_t a, extFloat80_t b ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool signA; - union { struct extFloat80M s; extFloat80_t f; } uB; - uint_fast16_t uiB64; - uint_fast64_t uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - extFloat80_t - (*magsFuncPtr)( - uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); -#endif - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - signA = signExtF80UI64( uiA64 ); - uB.f = b; - uiB64 = uB.s.signExp; - uiB0 = uB.s.signif; - signB = signExtF80UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_subMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - return softfloat_addMagsExtF80( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_subMagsExtF80 : softfloat_addMagsExtF80; - return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f128.c deleted file mode 100644 index 7fbc9cb69..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f128.c +++ /dev/null @@ -1,75 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t extF80_to_f128( extFloat80_t a ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - uint_fast16_t exp; - uint_fast64_t frac; - struct commonNaN commonNaN; - struct uint128 uiZ; - bool sign; - struct uint128 frac128; - union ui128_f128 uZ; - - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - exp = expExtF80UI64( uiA64 ); - frac = uiA0 & UINT64_C( 0x7FFFFFFFFFFFFFFF ); - if ( (exp == 0x7FFF) && frac ) { - softfloat_extF80UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToF128UI( &commonNaN ); - } else { - sign = signExtF80UI64( uiA64 ); - frac128 = softfloat_shortShiftLeft128( 0, frac, 49 ); - uiZ.v64 = packToF128UI64( sign, exp, frac128.v64 ); - uiZ.v0 = frac128.v0; - } - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f16.c deleted file mode 100644 index ca5050f4c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f16.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t extF80_to_f16( extFloat80_t a ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig; - struct commonNaN commonNaN; - uint_fast16_t uiZ, sig16; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_extF80UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToF16UI( &commonNaN ); - } else { - uiZ = packToF16UI( sign, 0x1F, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig16 = softfloat_shortShiftRightJam64( sig, 49 ); - if ( ! (exp | sig16) ) { - uiZ = packToF16UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3FF1; - if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { - if ( exp < -0x40 ) exp = -0x40; - } - return softfloat_roundPackToF16( sign, exp, sig16 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f32.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f32.c deleted file mode 100644 index 357f56e9d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f32.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t extF80_to_f32( extFloat80_t a ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig; - struct commonNaN commonNaN; - uint_fast32_t uiZ, sig32; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_extF80UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToF32UI( &commonNaN ); - } else { - uiZ = packToF32UI( sign, 0xFF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig32 = softfloat_shortShiftRightJam64( sig, 33 ); - if ( ! (exp | sig32) ) { - uiZ = packToF32UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3F81; - if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return softfloat_roundPackToF32( sign, exp, sig32 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f64.c deleted file mode 100644 index c38739925..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_f64.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t extF80_to_f64( extFloat80_t a ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - uint_fast64_t uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig; - struct commonNaN commonNaN; - uint_fast64_t uiZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - uiA0 = uA.s.signif; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! (exp | sig) ) { - uiZ = packToF64UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( sig & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - softfloat_extF80UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToF64UI( &commonNaN ); - } else { - uiZ = packToF64UI( sign, 0x7FF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = softfloat_shortShiftRightJam64( sig, 1 ); - exp -= 0x3C01; - if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return softfloat_roundPackToF64( sign, exp, sig ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i32.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i32.c deleted file mode 100644 index 549ca7659..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i32.c +++ /dev/null @@ -1,83 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t - extF80_to_i32( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - bool sign; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) - if ( (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) { -#if (i32_fromNaN == i32_fromPosOverflow) - sign = 0; -#elif (i32_fromNaN == i32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return i32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x4032 - exp; - if ( shiftDist <= 0 ) shiftDist = 1; - sig = softfloat_shiftRightJam64( sig, shiftDist ); - return softfloat_roundToI32( sign, sig, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i32_r_minMag.c deleted file mode 100644 index 2b7b9e2b2..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i32_r_minMag.c +++ /dev/null @@ -1,97 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t extF80_to_i32_r_minMag( extFloat80_t a, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - bool sign; - int_fast32_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signExtF80UI64( uiA64 ); - if ( shiftDist < 33 ) { - if ( - (uiA64 == packToExtF80UI64( 1, 0x401E )) - && (sig < UINT64_C( 0x8000000100000000 )) - ) { - if ( exact && (sig & UINT64_C( 0x00000000FFFFFFFF )) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return -0x7FFFFFFF - 1; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? i32_fromNaN - : sign ? i32_fromNegOverflow : i32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - absZ = sig>>shiftDist; - if ( exact && ((uint_fast64_t) (uint_fast32_t) absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t - extF80_to_i64( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - bool sign; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - uint_fast64_t sigExtra; - struct uint64_extra sig64Extra; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( shiftDist <= 0 ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( shiftDist ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sigExtra = 0; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); - sig = sig64Extra.v; - sigExtra = sig64Extra.extra; - } - return softfloat_roundToI64( sign, sig, sigExtra, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i64_r_minMag.c deleted file mode 100644 index 215876da7..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_i64_r_minMag.c +++ /dev/null @@ -1,94 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t extF80_to_i64_r_minMag( extFloat80_t a, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - bool sign; - int_fast64_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signExtF80UI64( uiA64 ); - if ( shiftDist <= 0 ) { - if ( - (uiA64 == packToExtF80UI64( 1, 0x403E )) - && (sig == UINT64_C( 0x8000000000000000 )) - ) { - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - absZ = sig>>shiftDist; - if ( exact && (uint64_t) (sig<<(-shiftDist & 63)) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return sign ? -absZ : absZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui32.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui32.c deleted file mode 100644 index d121c4801..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui32.c +++ /dev/null @@ -1,83 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t - extF80_to_ui32( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - bool sign; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) - if ( (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) { -#if (ui32_fromNaN == ui32_fromPosOverflow) - sign = 0; -#elif (ui32_fromNaN == ui32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return ui32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x4032 - exp; - if ( shiftDist <= 0 ) shiftDist = 1; - sig = softfloat_shiftRightJam64( sig, shiftDist ); - return softfloat_roundToUI32( sign, sig, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui32_r_minMag.c deleted file mode 100644 index ad3048340..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui32_r_minMag.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t a, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - bool sign; - uint_fast32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signExtF80UI64( uiA64 ); - if ( sign || (shiftDist < 32) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - z = sig>>shiftDist; - if ( exact && ((uint_fast64_t) z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t - extF80_to_ui64( extFloat80_t a, uint_fast8_t roundingMode, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - bool sign; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - uint_fast64_t sigExtra; - struct uint64_extra sig64Extra; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - sign = signExtF80UI64( uiA64 ); - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( shiftDist < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sigExtra = 0; - if ( shiftDist ) { - sig64Extra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); - sig = sig64Extra.v; - sigExtra = sig64Extra.extra; - } - return softfloat_roundToUI64( sign, sig, sigExtra, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui64_r_minMag.c deleted file mode 100644 index 65adfe7e8..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/extF80_to_ui64_r_minMag.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t a, bool exact ) -{ - union { struct extFloat80M s; extFloat80_t f; } uA; - uint_fast16_t uiA64; - int_fast32_t exp; - uint_fast64_t sig; - int_fast32_t shiftDist; - bool sign; - uint_fast64_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.s.signExp; - exp = expExtF80UI64( uiA64 ); - sig = uA.s.signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( 64 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signExtF80UI64( uiA64 ); - if ( sign || (shiftDist < 0) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - z = sig>>shiftDist; - if ( exact && (z< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - f128M_add( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - const uint64_t *aWPtr, *bWPtr; - uint_fast64_t uiA64, uiA0; - bool signA; - uint_fast64_t uiB64, uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - float128_t - (*magsFuncPtr)( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); -#endif - - aWPtr = (const uint64_t *) aPtr; - bWPtr = (const uint64_t *) bPtr; - uiA64 = aWPtr[indexWord( 2, 1 )]; - uiA0 = aWPtr[indexWord( 2, 0 )]; - signA = signF128UI64( uiA64 ); - uiB64 = bWPtr[indexWord( 2, 1 )]; - uiB0 = bWPtr[indexWord( 2, 0 )]; - signB = signF128UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - *zPtr = softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - *zPtr = softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_addMagsF128 : softfloat_subMagsF128; - *zPtr = (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - -#else - -void - f128M_add( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - - softfloat_addF128M( - (const uint32_t *) aPtr, - (const uint32_t *) bPtr, - (uint32_t *) zPtr, - false - ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_div.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_div.c deleted file mode 100644 index 8355dc20a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_div.c +++ /dev/null @@ -1,187 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - f128M_div( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - - *zPtr = f128_div( *aPtr, *bPtr ); - -} - -#else - -void - f128M_div( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t *zWPtr, uiA96; - bool signA; - int32_t expA; - uint32_t uiB96; - bool signB; - int32_t expB; - bool signZ; - uint32_t y[5], sigB[4]; - int32_t expZ; - uint32_t recip32; - int ix; - uint64_t q64; - uint32_t q, qs[3], uiZ96; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - signA = signF128UI96( uiA96 ); - expA = expF128UI96( uiA96 ); - uiB96 = bWPtr[indexWordHi( 4 )]; - signB = signF128UI96( uiB96 ); - expB = expF128UI96( uiB96 ); - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return; - if ( expA == 0x7FFF ) { - if ( expB == 0x7FFF ) goto invalid; - goto infinity; - } - goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = softfloat_shiftNormSigF128M( aWPtr, 13, y ); - expB = softfloat_shiftNormSigF128M( bWPtr, 13, sigB ); - if ( expA == -128 ) { - if ( expB == -128 ) goto invalid; - goto zero; - } - if ( expB == -128 ) { - softfloat_raiseFlags( softfloat_flag_infinite ); - goto infinity; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA - expB + 0x3FFE; - if ( softfloat_compare128M( y, sigB ) < 0 ) { - --expZ; - softfloat_add128M( y, y, y ); - } - recip32 = - softfloat_approxRecip32_1( - ((uint64_t) sigB[indexWord( 4, 3 )]<<32 | sigB[indexWord( 4, 2 )]) - >>30 - ); - ix = 3; - for (;;) { - q64 = (uint64_t) y[indexWordHi( 4 )] * recip32; - q = (q64 + 0x80000000)>>32; - --ix; - if ( ix < 0 ) break; - softfloat_remStep128MBy32( y, 29, sigB, q, y ); - if ( y[indexWordHi( 4 )] & 0x80000000 ) { - --q; - softfloat_add128M( y, sigB, y ); - } - qs[ix] = q; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ((q + 1) & 7) < 2 ) { - softfloat_remStep128MBy32( y, 29, sigB, q, y ); - if ( y[indexWordHi( 4 )] & 0x80000000 ) { - --q; - softfloat_add128M( y, sigB, y ); - } else if ( softfloat_compare128M( sigB, y ) <= 0 ) { - ++q; - softfloat_sub128M( y, sigB, y ); - } - if ( - y[indexWordLo( 4 )] || y[indexWord( 4, 1 )] - || (y[indexWord( 4, 2 )] | y[indexWord( 4, 3 )]) - ) { - q |= 1; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q64 = (uint64_t) q<<28; - y[indexWord( 5, 0 )] = q64; - q64 = ((uint64_t) qs[0]<<25) + (q64>>32); - y[indexWord( 5, 1 )] = q64; - q64 = ((uint64_t) qs[1]<<22) + (q64>>32); - y[indexWord( 5, 2 )] = q64; - q64 = ((uint64_t) qs[2]<<19) + (q64>>32); - y[indexWord( 5, 3 )] = q64; - y[indexWord( 5, 4 )] = q64>>32; - softfloat_roundPackMToF128M( signZ, expZ, y, zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_invalidF128M( zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ96 = packToF128UI96( signZ, 0x7FFF, 0 ); - goto uiZ96; - zero: - uiZ96 = packToF128UI96( signZ, 0, 0 ); - uiZ96: - zWPtr[indexWordHi( 4 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_eq.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_eq.c deleted file mode 100644 index 4f28f5f31..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_eq.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool f128M_eq( const float128_t *aPtr, const float128_t *bPtr ) -{ - - return f128_eq( *aPtr, *bPtr ); - -} - -#else - -bool f128M_eq( const float128_t *aPtr, const float128_t *bPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t wordA, wordB, uiA96, uiB96; - bool possibleOppositeZeros; - uint32_t mashWord; - - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - wordA = aWPtr[indexWord( 4, 2 )]; - wordB = bWPtr[indexWord( 4, 2 )]; - if ( wordA != wordB ) goto false_checkSigNaNs; - uiA96 = aWPtr[indexWordHi( 4 )]; - uiB96 = bWPtr[indexWordHi( 4 )]; - possibleOppositeZeros = false; - if ( uiA96 != uiB96 ) { - possibleOppositeZeros = (((uiA96 | uiB96) & 0x7FFFFFFF) == 0); - if ( ! possibleOppositeZeros ) goto false_checkSigNaNs; - } - mashWord = wordA | wordB; - wordA = aWPtr[indexWord( 4, 1 )]; - wordB = bWPtr[indexWord( 4, 1 )]; - if ( wordA != wordB ) goto false_checkSigNaNs; - mashWord |= wordA | wordB; - wordA = aWPtr[indexWord( 4, 0 )]; - wordB = bWPtr[indexWord( 4, 0 )]; - if ( wordA != wordB ) goto false_checkSigNaNs; - if ( possibleOppositeZeros && ((mashWord | wordA | wordB) != 0) ) { - goto false_checkSigNaNs; - } - if ( ! softfloat_isNaNF128M( aWPtr ) && ! softfloat_isNaNF128M( bWPtr ) ) { - return true; - } - false_checkSigNaNs: - if ( - f128M_isSignalingNaN( (const float128_t *) aWPtr ) - || f128M_isSignalingNaN( (const float128_t *) bWPtr ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_eq_signaling.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_eq_signaling.c deleted file mode 100644 index d2ea5f434..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_eq_signaling.c +++ /dev/null @@ -1,92 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool f128M_eq_signaling( const float128_t *aPtr, const float128_t *bPtr ) -{ - - return f128_eq_signaling( *aPtr, *bPtr ); - -} - -#else - -bool f128M_eq_signaling( const float128_t *aPtr, const float128_t *bPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t wordA, wordB, uiA96, uiB96; - bool possibleOppositeZeros; - uint32_t mashWord; - - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - wordA = aWPtr[indexWord( 4, 2 )]; - wordB = bWPtr[indexWord( 4, 2 )]; - if ( wordA != wordB ) return false; - uiA96 = aWPtr[indexWordHi( 4 )]; - uiB96 = bWPtr[indexWordHi( 4 )]; - possibleOppositeZeros = false; - if ( uiA96 != uiB96 ) { - possibleOppositeZeros = (((uiA96 | uiB96) & 0x7FFFFFFF) == 0); - if ( ! possibleOppositeZeros ) return false; - } - mashWord = wordA | wordB; - wordA = aWPtr[indexWord( 4, 1 )]; - wordB = bWPtr[indexWord( 4, 1 )]; - if ( wordA != wordB ) return false; - mashWord |= wordA | wordB; - wordA = aWPtr[indexWord( 4, 0 )]; - wordB = bWPtr[indexWord( 4, 0 )]; - return - (wordA == wordB) - && (! possibleOppositeZeros || ((mashWord | wordA | wordB) == 0)); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_le.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_le.c deleted file mode 100644 index af1dcba74..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_le.c +++ /dev/null @@ -1,93 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool f128M_le( const float128_t *aPtr, const float128_t *bPtr ) -{ - - return f128_le( *aPtr, *bPtr ); - -} - -#else - -bool f128M_le( const float128_t *aPtr, const float128_t *bPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t uiA96, uiB96; - bool signA, signB; - uint32_t wordA, wordB; - - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - uiA96 = aWPtr[indexWordHi( 4 )]; - uiB96 = bWPtr[indexWordHi( 4 )]; - signA = signF128UI96( uiA96 ); - signB = signF128UI96( uiB96 ); - if ( signA != signB ) { - if ( signA ) return true; - if ( (uiA96 | uiB96) & 0x7FFFFFFF ) return false; - wordA = aWPtr[indexWord( 4, 2 )]; - wordB = bWPtr[indexWord( 4, 2 )]; - if ( wordA | wordB ) return false; - wordA = aWPtr[indexWord( 4, 1 )]; - wordB = bWPtr[indexWord( 4, 1 )]; - if ( wordA | wordB ) return false; - wordA = aWPtr[indexWord( 4, 0 )]; - wordB = bWPtr[indexWord( 4, 0 )]; - return ((wordA | wordB) == 0); - } - if ( signA ) { - aWPtr = (const uint32_t *) bPtr; - bWPtr = (const uint32_t *) aPtr; - } - return (softfloat_compare128M( aWPtr, bWPtr ) <= 0); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_le_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_le_quiet.c deleted file mode 100644 index 0d051b656..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_le_quiet.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool f128M_le_quiet( const float128_t *aPtr, const float128_t *bPtr ) -{ - - return f128_le_quiet( *aPtr, *bPtr ); - -} - -#else - -bool f128M_le_quiet( const float128_t *aPtr, const float128_t *bPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t uiA96, uiB96; - bool signA, signB; - uint32_t wordA, wordB; - - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { - if ( f128M_isSignalingNaN( aPtr ) || f128M_isSignalingNaN( bPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - uiA96 = aWPtr[indexWordHi( 4 )]; - uiB96 = bWPtr[indexWordHi( 4 )]; - signA = signF128UI96( uiA96 ); - signB = signF128UI96( uiB96 ); - if ( signA != signB ) { - if ( signA ) return true; - if ( (uiA96 | uiB96) & 0x7FFFFFFF ) return false; - wordA = aWPtr[indexWord( 4, 2 )]; - wordB = bWPtr[indexWord( 4, 2 )]; - if ( wordA | wordB ) return false; - wordA = aWPtr[indexWord( 4, 1 )]; - wordB = bWPtr[indexWord( 4, 1 )]; - if ( wordA | wordB ) return false; - wordA = aWPtr[indexWord( 4, 0 )]; - wordB = bWPtr[indexWord( 4, 0 )]; - return ((wordA | wordB) == 0); - } - if ( signA ) { - aWPtr = (const uint32_t *) bPtr; - bWPtr = (const uint32_t *) aPtr; - } - return (softfloat_compare128M( aWPtr, bWPtr ) <= 0); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_lt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_lt.c deleted file mode 100644 index 64ff9b45d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_lt.c +++ /dev/null @@ -1,93 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool f128M_lt( const float128_t *aPtr, const float128_t *bPtr ) -{ - - return f128_lt( *aPtr, *bPtr ); - -} - -#else - -bool f128M_lt( const float128_t *aPtr, const float128_t *bPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t uiA96, uiB96; - bool signA, signB; - uint32_t wordA, wordB; - - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - uiA96 = aWPtr[indexWordHi( 4 )]; - uiB96 = bWPtr[indexWordHi( 4 )]; - signA = signF128UI96( uiA96 ); - signB = signF128UI96( uiB96 ); - if ( signA != signB ) { - if ( signB ) return false; - if ( (uiA96 | uiB96) & 0x7FFFFFFF ) return true; - wordA = aWPtr[indexWord( 4, 2 )]; - wordB = bWPtr[indexWord( 4, 2 )]; - if ( wordA | wordB ) return true; - wordA = aWPtr[indexWord( 4, 1 )]; - wordB = bWPtr[indexWord( 4, 1 )]; - if ( wordA | wordB ) return true; - wordA = aWPtr[indexWord( 4, 0 )]; - wordB = bWPtr[indexWord( 4, 0 )]; - return ((wordA | wordB) != 0); - } - if ( signA ) { - aWPtr = (const uint32_t *) bPtr; - bWPtr = (const uint32_t *) aPtr; - } - return (softfloat_compare128M( aWPtr, bWPtr ) < 0); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_lt_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_lt_quiet.c deleted file mode 100644 index 6ccf3c861..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_lt_quiet.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -bool f128M_lt_quiet( const float128_t *aPtr, const float128_t *bPtr ) -{ - - return f128_lt_quiet( *aPtr, *bPtr ); - -} - -#else - -bool f128M_lt_quiet( const float128_t *aPtr, const float128_t *bPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t uiA96, uiB96; - bool signA, signB; - uint32_t wordA, wordB; - - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { - if ( f128M_isSignalingNaN( aPtr ) || f128M_isSignalingNaN( bPtr ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - uiA96 = aWPtr[indexWordHi( 4 )]; - uiB96 = bWPtr[indexWordHi( 4 )]; - signA = signF128UI96( uiA96 ); - signB = signF128UI96( uiB96 ); - if ( signA != signB ) { - if ( signB ) return false; - if ( (uiA96 | uiB96) & 0x7FFFFFFF ) return true; - wordA = aWPtr[indexWord( 4, 2 )]; - wordB = bWPtr[indexWord( 4, 2 )]; - if ( wordA | wordB ) return true; - wordA = aWPtr[indexWord( 4, 1 )]; - wordB = bWPtr[indexWord( 4, 1 )]; - if ( wordA | wordB ) return true; - wordA = aWPtr[indexWord( 4, 0 )]; - wordB = bWPtr[indexWord( 4, 0 )]; - return ((wordA | wordB) != 0); - } - if ( signA ) { - aWPtr = (const uint32_t *) bPtr; - bWPtr = (const uint32_t *) aPtr; - } - return (softfloat_compare128M( aWPtr, bWPtr ) < 0); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_mul.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_mul.c deleted file mode 100644 index f2d6051e0..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_mul.c +++ /dev/null @@ -1,158 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - f128M_mul( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - - *zPtr = f128_mul( *aPtr, *bPtr ); - -} - -#else - -void - f128M_mul( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t *zWPtr; - uint32_t uiA96; - int32_t expA; - uint32_t uiB96; - int32_t expB; - bool signZ; - const uint32_t *ptr; - uint32_t uiZ96, sigA[4]; - uint_fast8_t shiftDist; - uint32_t sigB[4]; - int32_t expZ; - uint32_t sigProd[8], *extSigZPtr; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - expA = expF128UI96( uiA96 ); - uiB96 = bWPtr[indexWordHi( 4 )]; - expB = expF128UI96( uiB96 ); - signZ = signF128UI96( uiA96 ) ^ signF128UI96( uiB96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return; - ptr = aWPtr; - if ( ! expA ) goto possiblyInvalid; - if ( ! expB ) { - ptr = bWPtr; - possiblyInvalid: - if ( - ! fracF128UI96( ptr[indexWordHi( 4 )] ) - && ! (ptr[indexWord( 4, 2 )] | ptr[indexWord( 4, 1 )] - | ptr[indexWord( 4, 0 )]) - ) { - softfloat_invalidF128M( zWPtr ); - return; - } - } - uiZ96 = packToF128UI96( signZ, 0x7FFF, 0 ); - goto uiZ96; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA ) { - sigA[indexWordHi( 4 )] = fracF128UI96( uiA96 ) | 0x00010000; - sigA[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - sigA[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - sigA[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - } else { - expA = softfloat_shiftNormSigF128M( aWPtr, 0, sigA ); - if ( expA == -128 ) goto zero; - } - if ( expB ) { - sigB[indexWordHi( 4 )] = fracF128UI96( uiB96 ) | 0x00010000; - sigB[indexWord( 4, 2 )] = bWPtr[indexWord( 4, 2 )]; - sigB[indexWord( 4, 1 )] = bWPtr[indexWord( 4, 1 )]; - sigB[indexWord( 4, 0 )] = bWPtr[indexWord( 4, 0 )]; - } else { - expB = softfloat_shiftNormSigF128M( bWPtr, 0, sigB ); - if ( expB == -128 ) goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x4000; - softfloat_mul128MTo256M( sigA, sigB, sigProd ); - if ( - sigProd[indexWord( 8, 2 )] - || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )]) - ) { - sigProd[indexWord( 8, 3 )] |= 1; - } - extSigZPtr = &sigProd[indexMultiwordHi( 8, 5 )]; - shiftDist = 16; - if ( extSigZPtr[indexWordHi( 5 )] & 2 ) { - ++expZ; - shiftDist = 15; - } - softfloat_shortShiftLeft160M( extSigZPtr, shiftDist, extSigZPtr ); - softfloat_roundPackMToF128M( signZ, expZ, extSigZPtr, zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ96 = packToF128UI96( signZ, 0, 0 ); - uiZ96: - zWPtr[indexWordHi( 4 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_mulAdd.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_mulAdd.c deleted file mode 100644 index e2f95df01..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_mulAdd.c +++ /dev/null @@ -1,92 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - f128M_mulAdd( - const float128_t *aPtr, - const float128_t *bPtr, - const float128_t *cPtr, - float128_t *zPtr - ) -{ - const uint64_t *aWPtr, *bWPtr, *cWPtr; - uint_fast64_t uiA64, uiA0; - uint_fast64_t uiB64, uiB0; - uint_fast64_t uiC64, uiC0; - - aWPtr = (const uint64_t *) aPtr; - bWPtr = (const uint64_t *) bPtr; - cWPtr = (const uint64_t *) cPtr; - uiA64 = aWPtr[indexWord( 2, 1 )]; - uiA0 = aWPtr[indexWord( 2, 0 )]; - uiB64 = bWPtr[indexWord( 2, 1 )]; - uiB0 = bWPtr[indexWord( 2, 0 )]; - uiC64 = cWPtr[indexWord( 2, 1 )]; - uiC0 = cWPtr[indexWord( 2, 0 )]; - *zPtr = softfloat_mulAddF128( uiA64, uiA0, uiB64, uiB0, uiC64, uiC0, 0 ); - -} - -#else - -void - f128M_mulAdd( - const float128_t *aPtr, - const float128_t *bPtr, - const float128_t *cPtr, - float128_t *zPtr - ) -{ - - softfloat_mulAddF128M( - (const uint32_t *) aPtr, - (const uint32_t *) bPtr, - (const uint32_t *) cPtr, - (uint32_t *) zPtr, - 0 - ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_rem.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_rem.c deleted file mode 100644 index 645ec9938..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_rem.c +++ /dev/null @@ -1,182 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - f128M_rem( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - - *zPtr = f128_rem( *aPtr, *bPtr ); - -} - -#else - -void - f128M_rem( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - const uint32_t *aWPtr, *bWPtr; - uint32_t *zWPtr, uiA96; - int32_t expA, expB; - uint32_t x[4], rem1[5], *remPtr; - bool signRem; - int32_t expDiff; - uint32_t q, recip32; - uint64_t q64; - uint32_t rem2[5], *altRemPtr, *newRemPtr, wordMeanRem; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - bWPtr = (const uint32_t *) bPtr; - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - expA = expF128UI96( uiA96 ); - expB = expF128UI96( bWPtr[indexWordHi( 4 )] ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return; - if ( expA == 0x7FFF ) goto invalid; - goto copyA; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA < expB - 1 ) goto copyA; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expB = softfloat_shiftNormSigF128M( bWPtr, 13, x ); - if ( expB == -128 ) goto invalid; - remPtr = &rem1[indexMultiwordLo( 5, 4 )]; - expA = softfloat_shiftNormSigF128M( aWPtr, 13, remPtr ); - if ( expA == -128 ) goto copyA; - signRem = signF128UI96( uiA96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( expDiff < 1 ) { - if ( expDiff < -1 ) goto copyA; - if ( expDiff ) { - --expB; - softfloat_add128M( x, x, x ); - q = 0; - } else { - q = (softfloat_compare128M( x, remPtr ) <= 0); - if ( q ) softfloat_sub128M( remPtr, x, remPtr ); - } - } else { - recip32 = - softfloat_approxRecip32_1( - ((uint64_t) x[indexWord( 4, 3 )]<<32 | x[indexWord( 4, 2 )]) - >>30 - ); - expDiff -= 30; - for (;;) { - q64 = (uint64_t) remPtr[indexWordHi( 4 )] * recip32; - if ( expDiff < 0 ) break; - q = (q64 + 0x80000000)>>32; - softfloat_remStep128MBy32( remPtr, 29, x, q, remPtr ); - if ( remPtr[indexWordHi( 4 )] & 0x80000000 ) { - softfloat_add128M( remPtr, x, remPtr ); - } - expDiff -= 29; - } - /*-------------------------------------------------------------------- - | (`expDiff' cannot be less than -29 here.) - *--------------------------------------------------------------------*/ - q = (uint32_t) (q64>>32)>>(~expDiff & 31); - softfloat_remStep128MBy32( remPtr, expDiff + 30, x, q, remPtr ); - if ( remPtr[indexWordHi( 4 )] & 0x80000000 ) { - altRemPtr = &rem2[indexMultiwordLo( 5, 4 )]; - softfloat_add128M( remPtr, x, altRemPtr ); - goto selectRem; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - altRemPtr = &rem2[indexMultiwordLo( 5, 4 )]; - do { - ++q; - newRemPtr = altRemPtr; - softfloat_sub128M( remPtr, x, newRemPtr ); - altRemPtr = remPtr; - remPtr = newRemPtr; - } while ( ! (remPtr[indexWordHi( 4 )] & 0x80000000) ); - selectRem: - softfloat_add128M( remPtr, altRemPtr, x ); - wordMeanRem = x[indexWordHi( 4 )]; - if ( - (wordMeanRem & 0x80000000) - || (! wordMeanRem && (q & 1) && ! x[indexWord( 4, 0 )] - && ! (x[indexWord( 4, 2 )] | x[indexWord( 4, 1 )])) - ) { - remPtr = altRemPtr; - } - if ( remPtr[indexWordHi( 4 )] & 0x80000000 ) { - signRem = ! signRem; - softfloat_negX128M( remPtr ); - } - remPtr -= indexMultiwordLo( 5, 4 ); - remPtr[indexWordHi( 5 )] = 0; - softfloat_normRoundPackMToF128M( signRem, expB + 18, remPtr, zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_invalidF128M( zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - copyA: - zWPtr[indexWordHi( 4 )] = uiA96; - zWPtr[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - zWPtr[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - zWPtr[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_roundToInt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_roundToInt.c deleted file mode 100644 index c46712656..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_roundToInt.c +++ /dev/null @@ -1,223 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - f128M_roundToInt( - const float128_t *aPtr, - uint_fast8_t roundingMode, - bool exact, - float128_t *zPtr - ) -{ - - *zPtr = f128_roundToInt( *aPtr, roundingMode, exact ); - -} - -#else - -void - f128M_roundToInt( - const float128_t *aPtr, - uint_fast8_t roundingMode, - bool exact, - float128_t *zPtr - ) -{ - const uint32_t *aWPtr; - uint32_t *zWPtr; - uint32_t ui96; - int32_t exp; - uint32_t sigExtra; - bool sign; - uint_fast8_t bitPos; - bool roundNear; - unsigned int index, lastIndex; - bool extra; - uint32_t wordA, bit, wordZ; - uint_fast8_t carry; - uint32_t extrasMask; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - ui96 = aWPtr[indexWordHi( 4 )]; - exp = expF128UI96( ui96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp < 0x3FFF ) { - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - sigExtra = aWPtr[indexWord( 4, 2 )]; - if ( !sigExtra ) { - sigExtra = aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )]; - } - if ( !sigExtra && !(ui96 & 0x7FFFFFFF) ) goto ui96; - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - sign = signF128UI96( ui96 ); - switch ( roundingMode ) { - case softfloat_round_near_even: - if ( !fracF128UI96( ui96 ) && !sigExtra ) break; - case softfloat_round_near_maxMag: - if ( exp == 0x3FFE ) goto mag1; - break; - case softfloat_round_min: - if ( sign ) goto mag1; - break; - case softfloat_round_max: - if ( !sign ) goto mag1; - break; -#ifdef SOFTFLOAT_ROUND_ODD - case softfloat_round_odd: - goto mag1; -#endif - } - ui96 = packToF128UI96( sign, 0, 0 ); - goto ui96; - mag1: - ui96 = packToF128UI96( sign, 0x3FFF, 0 ); - goto ui96; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x406F <= exp ) { - if ( - (exp == 0x7FFF) - && (fracF128UI96( ui96 ) - || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )])) - ) { - softfloat_propagateNaNF128M( aWPtr, 0, zWPtr ); - return; - } - zWPtr[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - zWPtr[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - zWPtr[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - goto ui96; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - bitPos = 0x406F - exp; - roundNear = - (roundingMode == softfloat_round_near_maxMag) - || (roundingMode == softfloat_round_near_even); - bitPos -= roundNear; - index = indexWordLo( 4 ); - lastIndex = indexWordHi( 4 ); - extra = 0; - for (;;) { - wordA = aWPtr[index]; - if ( bitPos < 32 ) break; - if ( wordA ) extra = 1; - zWPtr[index] = 0; - index += wordIncr; - bitPos -= 32; - } - bit = (uint32_t) 1< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f128M_sqrt( const float128_t *aPtr, float128_t *zPtr ) -{ - - *zPtr = f128_sqrt( *aPtr ); - -} - -#else - -void f128M_sqrt( const float128_t *aPtr, float128_t *zPtr ) -{ - const uint32_t *aWPtr; - uint32_t *zWPtr; - uint32_t uiA96; - bool signA; - int32_t rawExpA; - uint32_t rem[6]; - int32_t expA, expZ; - uint64_t rem64; - uint32_t sig32A, recipSqrt32, sig32Z, qs[3], q; - uint64_t sig64Z; - uint32_t term[5]; - uint64_t x64; - uint32_t y[5], rem32; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - signA = signF128UI96( uiA96 ); - rawExpA = expF128UI96( uiA96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( rawExpA == 0x7FFF ) { - if ( - fracF128UI96( uiA96 ) - || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )]) - ) { - softfloat_propagateNaNF128M( aWPtr, 0, zWPtr ); - return; - } - if ( ! signA ) goto copyA; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = softfloat_shiftNormSigF128M( aWPtr, 13 - (rawExpA & 1), rem ); - if ( expA == -128 ) goto copyA; - if ( signA ) goto invalid; - /*------------------------------------------------------------------------ - | (`sig32Z' is guaranteed to be a lower bound on the square root of - | `sig32A', which makes `sig32Z' also a lower bound on the square root of - | `sigA'.) - *------------------------------------------------------------------------*/ - expZ = ((expA - 0x3FFF)>>1) + 0x3FFE; - expA &= 1; - rem64 = (uint64_t) rem[indexWord( 4, 3 )]<<32 | rem[indexWord( 4, 2 )]; - if ( expA ) { - if ( ! rawExpA ) { - softfloat_shortShiftRight128M( rem, 1, rem ); - rem64 >>= 1; - } - sig32A = rem64>>29; - } else { - sig32A = rem64>>30; - } - recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A ); - sig32Z = ((uint64_t) sig32A * recipSqrt32)>>32; - if ( expA ) sig32Z >>= 1; - qs[2] = sig32Z; - rem64 -= (uint64_t) sig32Z * sig32Z; - rem[indexWord( 4, 3 )] = rem64>>32; - rem[indexWord( 4, 2 )] = rem64; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = ((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32; - sig64Z = ((uint64_t) sig32Z<<32) + ((uint64_t) q<<3); - term[indexWord( 4, 3 )] = 0; - term[indexWord( 4, 0 )] = 0; - /*------------------------------------------------------------------------ - | (Repeating this loop is a rare occurrence.) - *------------------------------------------------------------------------*/ - for (;;) { - x64 = ((uint64_t) sig32Z<<32) + sig64Z; - term[indexWord( 4, 2 )] = x64>>32; - term[indexWord( 4, 1 )] = x64; - softfloat_remStep128MBy32( rem, 29, term, q, y ); - rem32 = y[indexWord( 4, 3 )]; - if ( ! (rem32 & 0x80000000) ) break; - --q; - sig64Z -= 1<<3; - } - qs[1] = q; - rem64 = (uint64_t) rem32<<32 | y[indexWord( 4, 2 )]; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = ((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32; - if ( rem64>>34 ) q += recipSqrt32; - sig64Z <<= 1; - /*------------------------------------------------------------------------ - | (Repeating this loop is a rare occurrence.) - *------------------------------------------------------------------------*/ - for (;;) { - x64 = sig64Z + (q>>26); - term[indexWord( 4, 2 )] = x64>>32; - term[indexWord( 4, 1 )] = x64; - term[indexWord( 4, 0 )] = q<<6; - softfloat_remStep128MBy32( - y, 29, term, q, &rem[indexMultiwordHi( 6, 4 )] ); - rem32 = rem[indexWordHi( 6 )]; - if ( ! (rem32 & 0x80000000) ) break; - --q; - } - qs[0] = q; - rem64 = (uint64_t) rem32<<32 | rem[indexWord( 6, 4 )]; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = (((uint32_t) (rem64>>2) * (uint64_t) recipSqrt32)>>32) + 2; - if ( rem64>>34 ) q += recipSqrt32; - x64 = (uint64_t) q<<27; - y[indexWord( 5, 0 )] = x64; - x64 = ((uint64_t) qs[0]<<24) + (x64>>32); - y[indexWord( 5, 1 )] = x64; - x64 = ((uint64_t) qs[1]<<21) + (x64>>32); - y[indexWord( 5, 2 )] = x64; - x64 = ((uint64_t) qs[2]<<18) + (x64>>32); - y[indexWord( 5, 3 )] = x64; - y[indexWord( 5, 4 )] = x64>>32; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (q & 0xF) <= 2 ) { - q &= ~3; - y[indexWordLo( 5 )] = q<<27; - term[indexWord( 5, 4 )] = 0; - term[indexWord( 5, 3 )] = 0; - term[indexWord( 5, 2 )] = 0; - term[indexWord( 5, 1 )] = q>>6; - term[indexWord( 5, 0 )] = q<<26; - softfloat_sub160M( y, term, term ); - rem[indexWord( 6, 1 )] = 0; - rem[indexWord( 6, 0 )] = 0; - softfloat_remStep160MBy32( - &rem[indexMultiwordLo( 6, 5 )], - 14, - term, - q, - &rem[indexMultiwordLo( 6, 5 )] - ); - rem32 = rem[indexWord( 6, 4 )]; - if ( rem32 & 0x80000000 ) { - softfloat_sub1X160M( y ); - } else { - if ( - rem32 || rem[indexWord( 6, 0 )] || rem[indexWord( 6, 1 )] - || (rem[indexWord( 6, 3 )] | rem[indexWord( 6, 2 )]) - ) { - y[indexWordLo( 5 )] |= 1; - } - } - } - softfloat_roundPackMToF128M( 0, expZ, y, zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_invalidF128M( zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - copyA: - zWPtr[indexWordHi( 4 )] = uiA96; - zWPtr[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - zWPtr[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - zWPtr[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_sub.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_sub.c deleted file mode 100644 index 1b609fdab..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_sub.c +++ /dev/null @@ -1,97 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void - f128M_sub( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - const uint64_t *aWPtr, *bWPtr; - uint_fast64_t uiA64, uiA0; - bool signA; - uint_fast64_t uiB64, uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - float128_t - (*magsFuncPtr)( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); -#endif - - aWPtr = (const uint64_t *) aPtr; - bWPtr = (const uint64_t *) bPtr; - uiA64 = aWPtr[indexWord( 2, 1 )]; - uiA0 = aWPtr[indexWord( 2, 0 )]; - signA = signF128UI64( uiA64 ); - uiB64 = bWPtr[indexWord( 2, 1 )]; - uiB0 = bWPtr[indexWord( 2, 0 )]; - signB = signF128UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - *zPtr = softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - *zPtr = softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_subMagsF128 : softfloat_addMagsF128; - *zPtr = (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - -#else - -void - f128M_sub( const float128_t *aPtr, const float128_t *bPtr, float128_t *zPtr ) -{ - - softfloat_addF128M( - (const uint32_t *) aPtr, - (const uint32_t *) bPtr, - (uint32_t *) zPtr, - true - ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_extF80M.c deleted file mode 100644 index fe8b0fc81..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_extF80M.c +++ /dev/null @@ -1,101 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f128M_to_extF80M( const float128_t *aPtr, extFloat80_t *zPtr ) -{ - - *zPtr = f128_to_extF80( *aPtr ); - -} - -#else - -void f128M_to_extF80M( const float128_t *aPtr, extFloat80_t *zPtr ) -{ - const uint32_t *aWPtr; - struct extFloat80M *zSPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - struct commonNaN commonNaN; - uint32_t sig[4]; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - zSPtr = (struct extFloat80M *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( softfloat_isNaNF128M( aWPtr ) ) { - softfloat_f128MToCommonNaN( aWPtr, &commonNaN ); - softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); - return; - } - zSPtr->signExp = packToExtF80UI64( sign, 0x7FFF ); - zSPtr->signif = UINT64_C( 0x8000000000000000 ); - return; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp = softfloat_shiftNormSigF128M( aWPtr, 15, sig ); - if ( exp == -128 ) { - zSPtr->signExp = packToExtF80UI64( sign, 0 ); - zSPtr->signif = 0; - return; - } - if ( sig[indexWord( 4, 0 )] ) sig[indexWord( 4, 1 )] |= 1; - softfloat_roundPackMToExtF80M( - sign, exp, &sig[indexMultiwordHi( 4, 3 )], 80, zSPtr ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f16.c deleted file mode 100644 index 4f0c5bb2a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f16.c +++ /dev/null @@ -1,113 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -float16_t f128M_to_f16( const float128_t *aPtr ) -{ - - return f128_to_f16( *aPtr ); - -} - -#else - -float16_t f128M_to_f16( const float128_t *aPtr ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint32_t frac32; - struct commonNaN commonNaN; - uint16_t uiZ, frac16; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - frac32 = - fracF128UI96( uiA96 ) - | ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )]) - != 0); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( frac32 ) { - softfloat_f128MToCommonNaN( aWPtr, &commonNaN ); - uiZ = softfloat_commonNaNToF16UI( &commonNaN ); - } else { - uiZ = packToF16UI( sign, 0x1F, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac16 = frac32>>2 | (frac32 & 3); - if ( ! (exp | frac16) ) { - uiZ = packToF16UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3FF1; - if ( sizeof (int_fast16_t) < sizeof (int32_t) ) { - if ( exp < -0x40 ) exp = -0x40; - } - return softfloat_roundPackToF16( sign, exp, frac16 | 0x4000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f32.c deleted file mode 100644 index 8b73de08e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f32.c +++ /dev/null @@ -1,109 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -float32_t f128M_to_f32( const float128_t *aPtr ) -{ - - return f128_to_f32( *aPtr ); - -} - -#else - -float32_t f128M_to_f32( const float128_t *aPtr ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint64_t frac64; - struct commonNaN commonNaN; - uint32_t uiZ, frac32; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - frac64 = - (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )] - | ((aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )]) != 0); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( frac64 ) { - softfloat_f128MToCommonNaN( aWPtr, &commonNaN ); - uiZ = softfloat_commonNaNToF32UI( &commonNaN ); - } else { - uiZ = packToF32UI( sign, 0xFF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac32 = softfloat_shortShiftRightJam64( frac64, 18 ); - if ( ! (exp | frac32) ) { - uiZ = packToF32UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3F81; - if ( sizeof (int_fast16_t) < sizeof (int32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return softfloat_roundPackToF32( sign, exp, frac32 | 0x40000000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f64.c deleted file mode 100644 index 1cddd347a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_f64.c +++ /dev/null @@ -1,112 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -float64_t f128M_to_f64( const float128_t *aPtr ) -{ - - return f128_to_f64( *aPtr ); - -} - -#else - -float64_t f128M_to_f64( const float128_t *aPtr ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint64_t frac64; - struct commonNaN commonNaN; - uint64_t uiZ; - uint32_t frac32; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - frac64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( frac64 || aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) { - softfloat_f128MToCommonNaN( aWPtr, &commonNaN ); - uiZ = softfloat_commonNaNToF64UI( &commonNaN ); - } else { - uiZ = packToF64UI( sign, 0x7FF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac32 = aWPtr[indexWord( 4, 1 )]; - frac64 = frac64<<14 | frac32>>18; - if ( (frac32 & 0x0003FFFF) || aWPtr[indexWord( 4, 0 )] ) frac64 |= 1; - if ( ! (exp | frac64) ) { - uiZ = packToF64UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3C01; - if ( sizeof (int_fast16_t) < sizeof (int32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return - softfloat_roundPackToF64( - sign, exp, frac64 | UINT64_C( 0x4000000000000000 ) ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i32.c deleted file mode 100644 index 1265c60ad..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i32.c +++ /dev/null @@ -1,98 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast32_t - f128M_to_i32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return f128_to_i32( *aPtr, roundingMode, exact ); - -} - -#else - -int_fast32_t - f128M_to_i32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint64_t sig64; - int32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; - if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) - if ( (exp == 0x7FFF) && sig64 ) { -#if (i32_fromNaN == i32_fromPosOverflow) - sign = 0; -#elif (i32_fromNaN == i32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return i32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - shiftDist = 0x4023 - exp; - if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - return softfloat_roundToI32( sign, sig64, roundingMode, exact ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i32_r_minMag.c deleted file mode 100644 index dde3dea2b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i32_r_minMag.c +++ /dev/null @@ -1,106 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast32_t f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact ) -{ - - return f128_to_i32_r_minMag( *aPtr, exact ); - -} - -#else - -int_fast32_t f128M_to_i32_r_minMag( const float128_t *aPtr, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint64_t sig64; - int32_t shiftDist; - uint32_t absZ, uiZ; - union { uint32_t ui; int32_t i; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; - if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp < 0x3FFF ) { - if ( exact && (exp | sig64) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x401F <= exp ) goto invalid; - shiftDist = 0x402F - exp; - sig64 |= UINT64_C( 0x0001000000000000 ); - absZ = sig64>>shiftDist; - uiZ = sign ? -absZ : absZ; - if ( uiZ>>31 != sign ) goto invalid; - if ( exact && ((uint64_t) absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast64_t - f128M_to_i64( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return f128_to_i64( *aPtr, roundingMode, exact ); - -} - -#else - -int_fast64_t - f128M_to_i64( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint32_t sig96; - int32_t shiftDist; - uint32_t sig[4]; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - sig96 = fracF128UI96( uiA96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x404F - exp; - if ( shiftDist < 17 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) - && (sig96 - || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )])) - ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig96 |= 0x00010000; - sig[indexWord( 4, 3 )] = sig96; - sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftDist, sig ); - return - softfloat_roundMToI64( - sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i64_r_minMag.c deleted file mode 100644 index bcc79502f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_i64_r_minMag.c +++ /dev/null @@ -1,124 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -int_fast64_t f128M_to_i64_r_minMag( const float128_t *aPtr, bool exact ) -{ - - return f128_to_i64_r_minMag( *aPtr, exact ); - -} - -#else - -int_fast64_t f128M_to_i64_r_minMag( const float128_t *aPtr, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint32_t sig96; - int32_t shiftDist; - uint32_t sig[4]; - uint64_t uiZ; - union { uint64_t ui; int64_t i; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - sig96 = fracF128UI96( uiA96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( shiftDist < 0 ) goto invalid; - if ( exact ) { - if ( exp ) sig96 |= 0x00010000; - sig[indexWord( 4, 3 )] = sig96; - sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftDist + 17, sig ); - uiZ = (uint64_t) sig[indexWord( 4, 2 )]<<32 | sig[indexWord( 4, 1 )]; - if ( uiZ>>63 && (! sign || (uiZ != UINT64_C( 0x8000000000000000 ))) ) { - goto invalid; - } - if ( sig[indexWordLo( 4 )] ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - } else { - if ( 64 <= shiftDist ) return 0; - uiZ = - (uint64_t) sig96<<47 - | (uint64_t) aWPtr[indexWord( 4, 2 )]<<15 - | aWPtr[indexWord( 4, 1 )]>>17; - if ( shiftDist ) { - uiZ |= UINT64_C( 0x8000000000000000 ); - uiZ >>= shiftDist; - } else { - if ( uiZ || ! sign ) goto invalid; - uiZ |= UINT64_C( 0x8000000000000000 ); - } - } - if ( sign ) uiZ = -uiZ; - uZ.ui = uiZ; - return uZ.i; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) - && (sig96 - || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )])) - ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui32.c deleted file mode 100644 index 33ed93a3f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui32.c +++ /dev/null @@ -1,98 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast32_t - f128M_to_ui32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return f128_to_ui32( *aPtr, roundingMode, exact ); - -} - -#else - -uint_fast32_t - f128M_to_ui32( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint64_t sig64; - int32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; - if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) - if ( (exp == 0x7FFF) && sig64 ) { -#if (ui32_fromNaN == ui32_fromPosOverflow) - sign = 0; -#elif (ui32_fromNaN == ui32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return ui32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - shiftDist = 0x4023 - exp; - if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - return softfloat_roundToUI32( sign, sig64, roundingMode, exact ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui32_r_minMag.c deleted file mode 100644 index 87813c04a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui32_r_minMag.c +++ /dev/null @@ -1,102 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *aPtr, bool exact ) -{ - - return f128_to_ui32_r_minMag( *aPtr, exact ); - -} - -#else - -uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *aPtr, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - int32_t exp; - uint64_t sig64; - int32_t shiftDist; - bool sign; - uint32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - exp = expF128UI96( uiA96 ); - sig64 = (uint64_t) fracF128UI96( uiA96 )<<32 | aWPtr[indexWord( 4, 2 )]; - if ( aWPtr[indexWord( 4, 1 )] | aWPtr[indexWord( 4, 0 )] ) sig64 |= 1; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x402F - exp; - if ( 49 <= shiftDist ) { - if ( exact && (exp | sig64) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF128UI96( uiA96 ); - if ( sign || (shiftDist < 17) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && sig64 ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig64 |= UINT64_C( 0x0001000000000000 ); - z = sig64>>shiftDist; - if ( exact && ((uint64_t) z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast64_t - f128M_to_ui64( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - - return f128_to_ui64( *aPtr, roundingMode, exact ); - -} - -#else - -uint_fast64_t - f128M_to_ui64( const float128_t *aPtr, uint_fast8_t roundingMode, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint32_t sig96; - int32_t shiftDist; - uint32_t sig[4]; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - sig96 = fracF128UI96( uiA96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x404F - exp; - if ( shiftDist < 17 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) - && (sig96 - || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )])) - ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig96 |= 0x00010000; - sig[indexWord( 4, 3 )] = sig96; - sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftDist, sig ); - return - softfloat_roundMToUI64( - sign, sig + indexMultiwordLo( 4, 3 ), roundingMode, exact ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui64_r_minMag.c deleted file mode 100644 index 503a6058c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128M_to_ui64_r_minMag.c +++ /dev/null @@ -1,114 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *aPtr, bool exact ) -{ - - return f128_to_ui64_r_minMag( *aPtr, exact ); - -} - -#else - -uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *aPtr, bool exact ) -{ - const uint32_t *aWPtr; - uint32_t uiA96; - bool sign; - int32_t exp; - uint32_t sig96; - int32_t shiftDist; - uint32_t sig[4]; - uint64_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - aWPtr = (const uint32_t *) aPtr; - uiA96 = aWPtr[indexWordHi( 4 )]; - sign = signF128UI96( uiA96 ); - exp = expF128UI96( uiA96 ); - sig96 = fracF128UI96( uiA96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x403E - exp; - if ( shiftDist < 0 ) goto invalid; - if ( exact ) { - if ( exp ) sig96 |= 0x00010000; - sig[indexWord( 4, 3 )] = sig96; - sig[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - sig[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - sig[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - softfloat_shiftRightJam128M( sig, shiftDist + 17, sig ); - z = (uint64_t) sig[indexWord( 4, 2 )]<<32 | sig[indexWord( 4, 1 )]; - if ( sign && z ) goto invalid; - if ( sig[indexWordLo( 4 )] ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - } else { - if ( 64 <= shiftDist ) return 0; - if ( sign ) goto invalid; - z = UINT64_C( 0x8000000000000000 ) - | (uint64_t) sig96<<47 - | (uint64_t) aWPtr[indexWord( 4, 2 )]<<15 - | aWPtr[indexWord( 4, 1 )]>>17; - z >>= shiftDist; - } - return z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) - && (sig96 - || (aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )])) - ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_add.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_add.c deleted file mode 100644 index 2f6c6b5ae..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_add.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t f128_add( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool signA; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - float128_t - (*magsFuncPtr)( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); -#endif - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - signA = signF128UI64( uiA64 ); - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - signB = signF128UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - return softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_addMagsF128 : softfloat_subMagsF128; - return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_div.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_div.c deleted file mode 100644 index dcd3ecbde..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_div.c +++ /dev/null @@ -1,199 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t f128_div( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool signA; - int_fast32_t expA; - struct uint128 sigA; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signB; - int_fast32_t expB; - struct uint128 sigB; - bool signZ; - struct exp32_sig128 normExpSig; - int_fast32_t expZ; - struct uint128 rem; - uint_fast32_t recip32; - int ix; - uint_fast64_t q64; - uint_fast32_t q; - struct uint128 term; - uint_fast32_t qs[3]; - uint_fast64_t sigZExtra; - struct uint128 sigZ, uiZ; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - signA = signF128UI64( uiA64 ); - expA = expF128UI64( uiA64 ); - sigA.v64 = fracF128UI64( uiA64 ); - sigA.v0 = uiA0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - signB = signF128UI64( uiB64 ); - expB = expF128UI64( uiB64 ); - sigB.v64 = fracF128UI64( uiB64 ); - sigB.v0 = uiB0; - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( sigA.v64 | sigA.v0 ) goto propagateNaN; - if ( expB == 0x7FFF ) { - if ( sigB.v64 | sigB.v0 ) goto propagateNaN; - goto invalid; - } - goto infinity; - } - if ( expB == 0x7FFF ) { - if ( sigB.v64 | sigB.v0 ) goto propagateNaN; - goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! (sigB.v64 | sigB.v0) ) { - if ( ! (expA | sigA.v64 | sigA.v0) ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinite ); - goto infinity; - } - normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! (sigA.v64 | sigA.v0) ) goto zero; - normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA - expB + 0x3FFE; - sigA.v64 |= UINT64_C( 0x0001000000000000 ); - sigB.v64 |= UINT64_C( 0x0001000000000000 ); - rem = sigA; - if ( softfloat_lt128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ) ) { - --expZ; - rem = softfloat_add128( sigA.v64, sigA.v0, sigA.v64, sigA.v0 ); - } - recip32 = softfloat_approxRecip32_1( sigB.v64>>17 ); - ix = 3; - for (;;) { - q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32; - q = (q64 + 0x80000000)>>32; - --ix; - if ( ix < 0 ) break; - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - --q; - rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); - } - qs[ix] = q; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ((q + 1) & 7) < 2 ) { - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - --q; - rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); - } else if ( softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ) ) { - ++q; - rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); - } - if ( rem.v64 | rem.v0 ) q |= 1; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sigZExtra = (uint64_t) ((uint_fast64_t) q<<60); - term = softfloat_shortShiftLeft128( 0, qs[1], 54 ); - sigZ = - softfloat_add128( - (uint_fast64_t) qs[2]<<19, ((uint_fast64_t) qs[0]<<25) + (q>>4), - term.v64, term.v0 - ); - return - softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); - goto uiZ0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ.v64 = packToF128UI64( signZ, 0, 0 ); - uiZ0: - uiZ.v0 = 0; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_eq.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_eq.c deleted file mode 100644 index 65183daee..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_eq.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f128_eq( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNF128UI( uiA64, uiA0 ) - || softfloat_isSigNaNF128UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - return - (uiA0 == uiB0) - && ( (uiA64 == uiB64) - || (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_eq_signaling.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_eq_signaling.c deleted file mode 100644 index 892b7da1e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_eq_signaling.c +++ /dev/null @@ -1,67 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f128_eq_signaling( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - return - (uiA0 == uiB0) - && ( (uiA64 == uiB64) - || (! uiA0 && ! ((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_isSignalingNaN.c deleted file mode 100644 index f8e5d2368..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_isSignalingNaN.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f128_isSignalingNaN( float128_t a ) -{ - union ui128_f128 uA; - - uA.f = a; - return softfloat_isSigNaNF128UI( uA.ui.v64, uA.ui.v0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_le.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_le.c deleted file mode 100644 index 28d452bd0..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_le.c +++ /dev/null @@ -1,72 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f128_le( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF128UI64( uiA64 ); - signB = signF128UI64( uiB64 ); - return - (signA != signB) - ? signA - || ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - | uiA0 | uiB0) - : ((uiA64 == uiB64) && (uiA0 == uiB0)) - || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_le_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_le_quiet.c deleted file mode 100644 index f3ea5a65d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_le_quiet.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f128_le_quiet( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNF128UI( uiA64, uiA0 ) - || softfloat_isSigNaNF128UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF128UI64( uiA64 ); - signB = signF128UI64( uiB64 ); - return - (signA != signB) - ? signA - || ! (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - | uiA0 | uiB0) - : ((uiA64 == uiB64) && (uiA0 == uiB0)) - || (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_lt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_lt.c deleted file mode 100644 index 97589a47f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_lt.c +++ /dev/null @@ -1,72 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f128_lt( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF128UI64( uiA64 ); - signB = signF128UI64( uiB64 ); - return - (signA != signB) - ? signA - && (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - | uiA0 | uiB0) - : ((uiA64 != uiB64) || (uiA0 != uiB0)) - && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_lt_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_lt_quiet.c deleted file mode 100644 index 0daf32958..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_lt_quiet.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f128_lt_quiet( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signA, signB; - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - if ( isNaNF128UI( uiA64, uiA0 ) || isNaNF128UI( uiB64, uiB0 ) ) { - if ( - softfloat_isSigNaNF128UI( uiA64, uiA0 ) - || softfloat_isSigNaNF128UI( uiB64, uiB0 ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF128UI64( uiA64 ); - signB = signF128UI64( uiB64 ); - return - (signA != signB) - ? signA - && (((uiA64 | uiB64) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - | uiA0 | uiB0) - : ((uiA64 != uiB64) || (uiA0 != uiB0)) - && (signA ^ softfloat_lt128( uiA64, uiA0, uiB64, uiB0 )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_mul.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_mul.c deleted file mode 100644 index 7dff6edfe..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_mul.c +++ /dev/null @@ -1,163 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t f128_mul( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool signA; - int_fast32_t expA; - struct uint128 sigA; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signB; - int_fast32_t expB; - struct uint128 sigB; - bool signZ; - uint_fast64_t magBits; - struct exp32_sig128 normExpSig; - int_fast32_t expZ; - uint64_t sig256Z[4]; - uint_fast64_t sigZExtra; - struct uint128 sigZ; - struct uint128_extra sig128Extra; - struct uint128 uiZ; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - signA = signF128UI64( uiA64 ); - expA = expF128UI64( uiA64 ); - sigA.v64 = fracF128UI64( uiA64 ); - sigA.v0 = uiA0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - signB = signF128UI64( uiB64 ); - expB = expF128UI64( uiB64 ); - sigB.v64 = fracF128UI64( uiB64 ); - sigB.v0 = uiB0; - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( - (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0)) - ) { - goto propagateNaN; - } - magBits = expB | sigB.v64 | sigB.v0; - goto infArg; - } - if ( expB == 0x7FFF ) { - if ( sigB.v64 | sigB.v0 ) goto propagateNaN; - magBits = expA | sigA.v64 | sigA.v0; - goto infArg; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! (sigA.v64 | sigA.v0) ) goto zero; - normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! (sigB.v64 | sigB.v0) ) goto zero; - normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x4000; - sigA.v64 |= UINT64_C( 0x0001000000000000 ); - sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 16 ); - softfloat_mul128To256M( sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z ); - sigZExtra = sig256Z[indexWord( 4, 1 )] | (sig256Z[indexWord( 4, 0 )] != 0); - sigZ = - softfloat_add128( - sig256Z[indexWord( 4, 3 )], sig256Z[indexWord( 4, 2 )], - sigA.v64, sigA.v0 - ); - if ( UINT64_C( 0x0002000000000000 ) <= sigZ.v64 ) { - ++expZ; - sig128Extra = - softfloat_shortShiftRightJam128Extra( - sigZ.v64, sigZ.v0, sigZExtra, 1 ); - sigZ = sig128Extra.v; - sigZExtra = sig128Extra.extra; - } - return - softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infArg: - if ( ! magBits ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - goto uiZ; - } - uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); - goto uiZ0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ.v64 = packToF128UI64( signZ, 0, 0 ); - uiZ0: - uiZ.v0 = 0; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_mulAdd.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_mulAdd.c deleted file mode 100644 index 8d4850e6a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_mulAdd.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t f128_mulAdd( float128_t a, float128_t b, float128_t c ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - union ui128_f128 uC; - uint_fast64_t uiC64, uiC0; - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - uC.f = c; - uiC64 = uC.ui.v64; - uiC0 = uC.ui.v0; - return softfloat_mulAddF128( uiA64, uiA0, uiB64, uiB0, uiC64, uiC0, 0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_rem.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_rem.c deleted file mode 100644 index 28d3df6cb..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_rem.c +++ /dev/null @@ -1,190 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t f128_rem( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool signA; - int_fast32_t expA; - struct uint128 sigA; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - int_fast32_t expB; - struct uint128 sigB; - struct exp32_sig128 normExpSig; - struct uint128 rem; - int_fast32_t expDiff; - uint_fast32_t q, recip32; - uint_fast64_t q64; - struct uint128 term, altRem, meanRem; - bool signRem; - struct uint128 uiZ; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - signA = signF128UI64( uiA64 ); - expA = expF128UI64( uiA64 ); - sigA.v64 = fracF128UI64( uiA64 ); - sigA.v0 = uiA0; - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - expB = expF128UI64( uiB64 ); - sigB.v64 = fracF128UI64( uiB64 ); - sigB.v0 = uiB0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( - (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0)) - ) { - goto propagateNaN; - } - goto invalid; - } - if ( expB == 0x7FFF ) { - if ( sigB.v64 | sigB.v0 ) goto propagateNaN; - return a; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! (sigB.v64 | sigB.v0) ) goto invalid; - normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! (sigA.v64 | sigA.v0) ) return a; - normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sigA.v64 |= UINT64_C( 0x0001000000000000 ); - sigB.v64 |= UINT64_C( 0x0001000000000000 ); - rem = sigA; - expDiff = expA - expB; - if ( expDiff < 1 ) { - if ( expDiff < -1 ) return a; - if ( expDiff ) { - --expB; - sigB = softfloat_add128( sigB.v64, sigB.v0, sigB.v64, sigB.v0 ); - q = 0; - } else { - q = softfloat_le128( sigB.v64, sigB.v0, rem.v64, rem.v0 ); - if ( q ) { - rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); - } - } - } else { - recip32 = softfloat_approxRecip32_1( sigB.v64>>17 ); - expDiff -= 30; - for (;;) { - q64 = (uint_fast64_t) (uint32_t) (rem.v64>>19) * recip32; - if ( expDiff < 0 ) break; - q = (q64 + 0x80000000)>>32; - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - rem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); - } - expDiff -= 29; - } - /*-------------------------------------------------------------------- - | (`expDiff' cannot be less than -29 here.) - *--------------------------------------------------------------------*/ - q = (uint32_t) (q64>>32)>>(~expDiff & 31); - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, expDiff + 30 ); - term = softfloat_mul128By32( sigB.v64, sigB.v0, q ); - rem = softfloat_sub128( rem.v64, rem.v0, term.v64, term.v0 ); - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - altRem = softfloat_add128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); - goto selectRem; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - do { - altRem = rem; - ++q; - rem = softfloat_sub128( rem.v64, rem.v0, sigB.v64, sigB.v0 ); - } while ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ); - selectRem: - meanRem = softfloat_add128( rem.v64, rem.v0, altRem.v64, altRem.v0 ); - if ( - (meanRem.v64 & UINT64_C( 0x8000000000000000 )) - || (! (meanRem.v64 | meanRem.v0) && (q & 1)) - ) { - rem = altRem; - } - signRem = signA; - if ( rem.v64 & UINT64_C( 0x8000000000000000 ) ) { - signRem = ! signRem; - rem = softfloat_sub128( 0, 0, rem.v64, rem.v0 ); - } - return softfloat_normRoundPackToF128( signRem, expB - 1, rem.v64, rem.v0 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_roundToInt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_roundToInt.c deleted file mode 100644 index 96ae30e34..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_roundToInt.c +++ /dev/null @@ -1,172 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t - f128_roundToInt( float128_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - int_fast32_t exp; - struct uint128 uiZ; - uint_fast64_t lastBitMask0, roundBitsMask; - bool roundNearEven; - uint_fast64_t lastBitMask64; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - exp = expF128UI64( uiA64 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x402F <= exp ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( 0x406F <= exp ) { - if ( (exp == 0x7FFF) && (fracF128UI64( uiA64 ) | uiA0) ) { - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, 0, 0 ); - goto uiZ; - } - return a; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - lastBitMask0 = (uint_fast64_t) 2<<(0x406E - exp); - roundBitsMask = lastBitMask0 - 1; - uiZ.v64 = uiA64; - uiZ.v0 = uiA0; - roundNearEven = (roundingMode == softfloat_round_near_even); - if ( roundNearEven || (roundingMode == softfloat_round_near_maxMag) ) { - if ( exp == 0x402F ) { - if ( UINT64_C( 0x8000000000000000 ) <= uiZ.v0 ) { - ++uiZ.v64; - if ( - roundNearEven - && (uiZ.v0 == UINT64_C( 0x8000000000000000 )) - ) { - uiZ.v64 &= ~1; - } - } - } else { - uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, lastBitMask0>>1 ); - if ( roundNearEven && !(uiZ.v0 & roundBitsMask) ) { - uiZ.v0 &= ~lastBitMask0; - } - } - } else if ( - roundingMode - == (signF128UI64( uiZ.v64 ) ? softfloat_round_min - : softfloat_round_max) - ) { - uiZ = softfloat_add128( uiZ.v64, uiZ.v0, 0, roundBitsMask ); - } - uiZ.v0 &= ~roundBitsMask; - lastBitMask64 = !lastBitMask0; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( exp < 0x3FFF ) { - if ( !((uiA64 & UINT64_C( 0x7FFFFFFFFFFFFFFF )) | uiA0) ) return a; - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - uiZ.v64 = uiA64 & packToF128UI64( 1, 0, 0 ); - uiZ.v0 = 0; - switch ( roundingMode ) { - case softfloat_round_near_even: - if ( !(fracF128UI64( uiA64 ) | uiA0) ) break; - case softfloat_round_near_maxMag: - if ( exp == 0x3FFE ) uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 ); - break; - case softfloat_round_min: - if ( uiZ.v64 ) uiZ.v64 = packToF128UI64( 1, 0x3FFF, 0 ); - break; - case softfloat_round_max: - if ( !uiZ.v64 ) uiZ.v64 = packToF128UI64( 0, 0x3FFF, 0 ); - break; -#ifdef SOFTFLOAT_ROUND_ODD - case softfloat_round_odd: - uiZ.v64 |= packToF128UI64( 0, 0x3FFF, 0 ); - break; -#endif - } - goto uiZ; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - uiZ.v64 = uiA64; - uiZ.v0 = 0; - lastBitMask64 = (uint_fast64_t) 1<<(0x402F - exp); - roundBitsMask = lastBitMask64 - 1; - if ( roundingMode == softfloat_round_near_maxMag ) { - uiZ.v64 += lastBitMask64>>1; - } else if ( roundingMode == softfloat_round_near_even ) { - uiZ.v64 += lastBitMask64>>1; - if ( !((uiZ.v64 & roundBitsMask) | uiA0) ) { - uiZ.v64 &= ~lastBitMask64; - } - } else if ( - roundingMode - == (signF128UI64( uiZ.v64 ) ? softfloat_round_min - : softfloat_round_max) - ) { - uiZ.v64 = (uiZ.v64 | (uiA0 != 0)) + roundBitsMask; - } - uiZ.v64 &= ~roundBitsMask; - lastBitMask0 = 0; - } - if ( (uiZ.v64 != uiA64) || (uiZ.v0 != uiA0) ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - uiZ.v64 |= lastBitMask64; - uiZ.v0 |= lastBitMask0; - } -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_sqrt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_sqrt.c deleted file mode 100644 index a32fe33f3..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_sqrt.c +++ /dev/null @@ -1,201 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t f128_sqrt( float128_t a ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool signA; - int_fast32_t expA; - struct uint128 sigA, uiZ; - struct exp32_sig128 normExpSig; - int_fast32_t expZ; - uint_fast32_t sig32A, recipSqrt32, sig32Z; - struct uint128 rem; - uint32_t qs[3]; - uint_fast32_t q; - uint_fast64_t x64, sig64Z; - struct uint128 y, term; - uint_fast64_t sigZExtra; - struct uint128 sigZ; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - signA = signF128UI64( uiA64 ); - expA = expF128UI64( uiA64 ); - sigA.v64 = fracF128UI64( uiA64 ); - sigA.v0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( sigA.v64 | sigA.v0 ) { - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, 0, 0 ); - goto uiZ; - } - if ( ! signA ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signA ) { - if ( ! (expA | sigA.v64 | sigA.v0) ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! (sigA.v64 | sigA.v0) ) return a; - normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - | (`sig32Z' is guaranteed to be a lower bound on the square root of - | `sig32A', which makes `sig32Z' also a lower bound on the square root of - | `sigA'.) - *------------------------------------------------------------------------*/ - expZ = ((expA - 0x3FFF)>>1) + 0x3FFE; - expA &= 1; - sigA.v64 |= UINT64_C( 0x0001000000000000 ); - sig32A = sigA.v64>>17; - recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A ); - sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32; - if ( expA ) { - sig32Z >>= 1; - rem = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 12 ); - } else { - rem = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 13 ); - } - qs[2] = sig32Z; - rem.v64 -= (uint_fast64_t) sig32Z * sig32Z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = ((uint32_t) (rem.v64>>2) * (uint_fast64_t) recipSqrt32)>>32; - x64 = (uint_fast64_t) sig32Z<<32; - sig64Z = x64 + ((uint_fast64_t) q<<3); - y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - /*------------------------------------------------------------------------ - | (Repeating this loop is a rare occurrence.) - *------------------------------------------------------------------------*/ - for (;;) { - term = softfloat_mul64ByShifted32To128( x64 + sig64Z, q ); - rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 ); - if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break; - --q; - sig64Z -= 1<<3; - } - qs[1] = q; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = ((rem.v64>>2) * recipSqrt32)>>32; - y = softfloat_shortShiftLeft128( rem.v64, rem.v0, 29 ); - sig64Z <<= 1; - /*------------------------------------------------------------------------ - | (Repeating this loop is a rare occurrence.) - *------------------------------------------------------------------------*/ - for (;;) { - term = softfloat_shortShiftLeft128( 0, sig64Z, 32 ); - term = softfloat_add128( term.v64, term.v0, 0, (uint_fast64_t) q<<6 ); - term = softfloat_mul128By32( term.v64, term.v0, q ); - rem = softfloat_sub128( y.v64, y.v0, term.v64, term.v0 ); - if ( ! (rem.v64 & UINT64_C( 0x8000000000000000 )) ) break; - --q; - } - qs[0] = q; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - q = (((rem.v64>>2) * recipSqrt32)>>32) + 2; - sigZExtra = (uint64_t) ((uint_fast64_t) q<<59); - term = softfloat_shortShiftLeft128( 0, qs[1], 53 ); - sigZ = - softfloat_add128( - (uint_fast64_t) qs[2]<<18, ((uint_fast64_t) qs[0]<<24) + (q>>5), - term.v64, term.v0 - ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (q & 0xF) <= 2 ) { - q &= ~3; - sigZExtra = (uint64_t) ((uint_fast64_t) q<<59); - y = softfloat_shortShiftLeft128( sigZ.v64, sigZ.v0, 6 ); - y.v0 |= sigZExtra>>58; - term = softfloat_sub128( y.v64, y.v0, 0, q ); - y = softfloat_mul64ByShifted32To128( term.v0, q ); - term = softfloat_mul64ByShifted32To128( term.v64, q ); - term = softfloat_add128( term.v64, term.v0, 0, y.v64 ); - rem = softfloat_shortShiftLeft128( rem.v64, rem.v0, 20 ); - term = softfloat_sub128( term.v64, term.v0, rem.v64, rem.v0 ); - /*-------------------------------------------------------------------- - | The concatenation of `term' and `y.v0' is now the negative remainder - | (3 words altogether). - *--------------------------------------------------------------------*/ - if ( term.v64 & UINT64_C( 0x8000000000000000 ) ) { - sigZExtra |= 1; - } else { - if ( term.v64 | term.v0 | y.v0 ) { - if ( sigZExtra ) { - --sigZExtra; - } else { - sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, 0, 1 ); - sigZExtra = ~0; - } - } - } - } - return softfloat_roundPackToF128( 0, expZ, sigZ.v64, sigZ.v0, sigZExtra ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_sub.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_sub.c deleted file mode 100644 index ef76ac4e7..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_sub.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t f128_sub( float128_t a, float128_t b ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool signA; - union ui128_f128 uB; - uint_fast64_t uiB64, uiB0; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - float128_t - (*magsFuncPtr)( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); -#endif - - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - signA = signF128UI64( uiA64 ); - uB.f = b; - uiB64 = uB.ui.v64; - uiB0 = uB.ui.v0; - signB = signF128UI64( uiB64 ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_subMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } else { - return softfloat_addMagsF128( uiA64, uiA0, uiB64, uiB0, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_subMagsF128 : softfloat_addMagsF128; - return (*magsFuncPtr)( uiA64, uiA0, uiB64, uiB0, signA ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_extF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_extF80.c deleted file mode 100644 index cb0a6ce68..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_extF80.c +++ /dev/null @@ -1,109 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t f128_to_extF80( float128_t a ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t frac64, frac0; - struct commonNaN commonNaN; - struct uint128 uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - struct exp32_sig128 normExpSig; - struct uint128 sig128; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - frac64 = fracF128UI64( uiA64 ); - frac0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( frac64 | frac0 ) { - softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToExtF80UI( &commonNaN ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - } else { - uiZ64 = packToExtF80UI64( sign, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! (frac64 | frac0) ) { - uiZ64 = packToExtF80UI64( sign, 0 ); - uiZ0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF128Sig( frac64, frac0 ); - exp = normExpSig.exp; - frac64 = normExpSig.sig.v64; - frac0 = normExpSig.sig.v0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig128 = - softfloat_shortShiftLeft128( - frac64 | UINT64_C( 0x0001000000000000 ), frac0, 15 ); - return softfloat_roundPackToExtF80( sign, exp, sig128.v64, sig128.v0, 80 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f16.c deleted file mode 100644 index 62ed35b7c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f16.c +++ /dev/null @@ -1,95 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t f128_to_f16( float128_t a ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t frac64; - struct commonNaN commonNaN; - uint_fast16_t uiZ, frac16; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - frac64 = fracF128UI64( uiA64 ) | (uiA0 != 0); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( frac64 ) { - softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToF16UI( &commonNaN ); - } else { - uiZ = packToF16UI( sign, 0x1F, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac16 = softfloat_shortShiftRightJam64( frac64, 34 ); - if ( ! (exp | frac16) ) { - uiZ = packToF16UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3FF1; - if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { - if ( exp < -0x40 ) exp = -0x40; - } - return softfloat_roundPackToF16( sign, exp, frac16 | 0x4000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f32.c deleted file mode 100644 index c10105f78..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f32.c +++ /dev/null @@ -1,95 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f128_to_f32( float128_t a ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t frac64; - struct commonNaN commonNaN; - uint_fast32_t uiZ, frac32; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - frac64 = fracF128UI64( uiA64 ) | (uiA0 != 0); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( frac64 ) { - softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToF32UI( &commonNaN ); - } else { - uiZ = packToF32UI( sign, 0xFF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac32 = softfloat_shortShiftRightJam64( frac64, 18 ); - if ( ! (exp | frac32) ) { - uiZ = packToF32UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3F81; - if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return softfloat_roundPackToF32( sign, exp, frac32 | 0x40000000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f64.c deleted file mode 100644 index 76da76cd7..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_f64.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f128_to_f64( float128_t a ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t frac64, frac0; - struct commonNaN commonNaN; - uint_fast64_t uiZ; - struct uint128 frac128; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - frac64 = fracF128UI64( uiA64 ); - frac0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FFF ) { - if ( frac64 | frac0 ) { - softfloat_f128UIToCommonNaN( uiA64, uiA0, &commonNaN ); - uiZ = softfloat_commonNaNToF64UI( &commonNaN ); - } else { - uiZ = packToF64UI( sign, 0x7FF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac128 = softfloat_shortShiftLeft128( frac64, frac0, 14 ); - frac64 = frac128.v64 | (frac128.v0 != 0); - if ( ! (exp | frac64) ) { - uiZ = packToF64UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - exp -= 0x3C01; - if ( sizeof (int_fast16_t) < sizeof (int_fast32_t) ) { - if ( exp < -0x1000 ) exp = -0x1000; - } - return - softfloat_roundPackToF64( - sign, exp, frac64 | UINT64_C( 0x4000000000000000 ) ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i32.c deleted file mode 100644 index cfff04aeb..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i32.c +++ /dev/null @@ -1,85 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f128_to_i32( float128_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig64, sig0; - int_fast32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ); - sig0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) - if ( (exp == 0x7FFF) && (sig64 | sig0) ) { -#if (i32_fromNaN == i32_fromPosOverflow) - sign = 0; -#elif (i32_fromNaN == i32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return i32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - sig64 |= (sig0 != 0); - shiftDist = 0x4023 - exp; - if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - return softfloat_roundToI32( sign, sig64, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i32_r_minMag.c deleted file mode 100644 index 161b67569..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i32_r_minMag.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f128_to_i32_r_minMag( float128_t a, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - int_fast32_t exp; - uint_fast64_t sig64; - int_fast32_t shiftDist; - bool sign; - int_fast32_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x402F - exp; - if ( 49 <= shiftDist ) { - if ( exact && (exp | sig64) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF128UI64( uiA64 ); - if ( shiftDist < 18 ) { - if ( - sign && (shiftDist == 17) - && (sig64 < UINT64_C( 0x0000000000020000 )) - ) { - if ( exact && sig64 ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return -0x7FFFFFFF - 1; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && sig64 ? i32_fromNaN - : sign ? i32_fromNegOverflow : i32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig64 |= UINT64_C( 0x0001000000000000 ); - absZ = sig64>>shiftDist; - if ( - exact && ((uint_fast64_t) (uint_fast32_t) absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f128_to_i64( float128_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig64, sig0; - int_fast32_t shiftDist; - struct uint128 sig128; - struct uint64_extra sigExtra; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ); - sig0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x402F - exp; - if ( shiftDist <= 0 ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( shiftDist < -15 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig64 |= UINT64_C( 0x0001000000000000 ); - if ( shiftDist ) { - sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist ); - sig64 = sig128.v64; - sig0 = sig128.v0; - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); - sig64 = sigExtra.v; - sig0 = sigExtra.extra; - } - return softfloat_roundToI64( sign, sig64, sig0, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i64_r_minMag.c deleted file mode 100644 index dc44e7ae2..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_i64_r_minMag.c +++ /dev/null @@ -1,113 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f128_to_i64_r_minMag( float128_t a, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig64, sig0; - int_fast32_t shiftDist; - int_fast8_t negShiftDist; - int_fast64_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ); - sig0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x402F - exp; - if ( shiftDist < 0 ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( shiftDist < -14 ) { - if ( - (uiA64 == UINT64_C( 0xC03E000000000000 )) - && (sig0 < UINT64_C( 0x0002000000000000 )) - ) { - if ( exact && sig0 ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig64 | sig0) ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig64 |= UINT64_C( 0x0001000000000000 ); - negShiftDist = -shiftDist; - absZ = sig64<>(shiftDist & 63); - if ( exact && (uint64_t) (sig0<>shiftDist; - if ( exact && (sig0 || (absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t - f128_to_ui32( float128_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig64; - int_fast32_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) - if ( (exp == 0x7FFF) && sig64 ) { -#if (ui32_fromNaN == ui32_fromPosOverflow) - sign = 0; -#elif (ui32_fromNaN == ui32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return ui32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - shiftDist = 0x4023 - exp; - if ( 0 < shiftDist ) { - sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - } - return softfloat_roundToUI32( sign, sig64, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_ui32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_ui32_r_minMag.c deleted file mode 100644 index 650c18fd9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_ui32_r_minMag.c +++ /dev/null @@ -1,89 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t f128_to_ui32_r_minMag( float128_t a, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - int_fast32_t exp; - uint_fast64_t sig64; - int_fast32_t shiftDist; - bool sign; - uint_fast32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ) | (uiA0 != 0); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x402F - exp; - if ( 49 <= shiftDist ) { - if ( exact && (exp | sig64) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF128UI64( uiA64 ); - if ( sign || (shiftDist < 17) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && sig64 ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig64 |= UINT64_C( 0x0001000000000000 ); - z = sig64>>shiftDist; - if ( exact && ((uint_fast64_t) z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t - f128_to_ui64( float128_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig64, sig0; - int_fast32_t shiftDist; - struct uint128 sig128; - struct uint64_extra sigExtra; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ); - sig0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x402F - exp; - if ( shiftDist <= 0 ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( shiftDist < -15 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FFF) && (sig64 | sig0) ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig64 |= UINT64_C( 0x0001000000000000 ); - if ( shiftDist ) { - sig128 = softfloat_shortShiftLeft128( sig64, sig0, -shiftDist ); - sig64 = sig128.v64; - sig0 = sig128.v0; - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( exp ) sig64 |= UINT64_C( 0x0001000000000000 ); - sigExtra = softfloat_shiftRightJam64Extra( sig64, sig0, shiftDist ); - sig64 = sigExtra.v; - sig0 = sigExtra.extra; - } - return softfloat_roundToUI64( sign, sig64, sig0, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_ui64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_ui64_r_minMag.c deleted file mode 100644 index 3f2fb6bce..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f128_to_ui64_r_minMag.c +++ /dev/null @@ -1,105 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t f128_to_ui64_r_minMag( float128_t a, bool exact ) -{ - union ui128_f128 uA; - uint_fast64_t uiA64, uiA0; - bool sign; - int_fast32_t exp; - uint_fast64_t sig64, sig0; - int_fast32_t shiftDist; - int_fast8_t negShiftDist; - uint_fast64_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA64 = uA.ui.v64; - uiA0 = uA.ui.v0; - sign = signF128UI64( uiA64 ); - exp = expF128UI64( uiA64 ); - sig64 = fracF128UI64( uiA64 ); - sig0 = uiA0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x402F - exp; - if ( shiftDist < 0 ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( sign || (shiftDist < -15) ) goto invalid; - sig64 |= UINT64_C( 0x0001000000000000 ); - negShiftDist = -shiftDist; - z = sig64<>(shiftDist & 63); - if ( exact && (uint64_t) (sig0<>shiftDist; - if ( exact && (sig0 || (z< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t f16_add( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) - float16_t (*magsFuncPtr)( uint_fast16_t, uint_fast16_t ); -#endif - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; -#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) - if ( signF16UI( uiA ^ uiB ) ) { - return softfloat_subMagsF16( uiA, uiB ); - } else { - return softfloat_addMagsF16( uiA, uiB ); - } -#else - magsFuncPtr = - signF16UI( uiA ^ uiB ) ? softfloat_subMagsF16 : softfloat_addMagsF16; - return (*magsFuncPtr)( uiA, uiB ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_div.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_div.c deleted file mode 100644 index ad91a9076..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_div.c +++ /dev/null @@ -1,186 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extern const uint16_t softfloat_approxRecip_1k0s[]; -extern const uint16_t softfloat_approxRecip_1k1s[]; - -float16_t f16_div( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool signA; - int_fast8_t expA; - uint_fast16_t sigA; - union ui16_f16 uB; - uint_fast16_t uiB; - bool signB; - int_fast8_t expB; - uint_fast16_t sigB; - bool signZ; - struct exp8_sig16 normExpSig; - int_fast8_t expZ; -#ifdef SOFTFLOAT_FAST_DIV32TO16 - uint_fast32_t sig32A; - uint_fast16_t sigZ; -#else - int index; - uint16_t r0; - uint_fast16_t sigZ, rem; -#endif - uint_fast16_t uiZ; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF16UI( uiA ); - expA = expF16UI( uiA ); - sigA = fracF16UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF16UI( uiB ); - expB = expF16UI( uiB ); - sigB = fracF16UI( uiB ); - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x1F ) { - if ( sigA ) goto propagateNaN; - if ( expB == 0x1F ) { - if ( sigB ) goto propagateNaN; - goto invalid; - } - goto infinity; - } - if ( expB == 0x1F ) { - if ( sigB ) goto propagateNaN; - goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! sigB ) { - if ( ! (expA | sigA) ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinite ); - goto infinity; - } - normExpSig = softfloat_normSubnormalF16Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF16Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA - expB + 0xE; - sigA |= 0x0400; - sigB |= 0x0400; -#ifdef SOFTFLOAT_FAST_DIV32TO16 - if ( sigA < sigB ) { - --expZ; - sig32A = (uint_fast32_t) sigA<<15; - } else { - sig32A = (uint_fast32_t) sigA<<14; - } - sigZ = sig32A / sigB; - if ( ! (sigZ & 7) ) sigZ |= ((uint_fast32_t) sigB * sigZ != sig32A); -#else - if ( sigA < sigB ) { - --expZ; - sigA <<= 5; - } else { - sigA <<= 4; - } - index = sigB>>6 & 0xF; - r0 = softfloat_approxRecip_1k0s[index] - - (((uint_fast32_t) softfloat_approxRecip_1k1s[index] - * (sigB & 0x3F)) - >>10); - sigZ = ((uint_fast32_t) sigA * r0)>>16; - rem = (sigA<<10) - sigZ * sigB; - sigZ += (rem * (uint_fast32_t) r0)>>26; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - ++sigZ; - if ( ! (sigZ & 7) ) { - sigZ &= ~1; - rem = (sigA<<10) - sigZ * sigB; - if ( rem & 0x8000 ) { - sigZ -= 2; - } else { - if ( rem ) sigZ |= 1; - } - } -#endif - return softfloat_roundPackToF16( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF16UI; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ = packToF16UI( signZ, 0x1F, 0 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ = packToF16UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_eq.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_eq.c deleted file mode 100644 index 4079f50f7..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_eq.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f16_eq( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { - if ( - softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - return (uiA == uiB) || ! (uint16_t) ((uiA | uiB)<<1); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_eq_signaling.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_eq_signaling.c deleted file mode 100644 index 117d05d6e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_eq_signaling.c +++ /dev/null @@ -1,61 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f16_eq_signaling( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - return (uiA == uiB) || ! (uint16_t) ((uiA | uiB)<<1); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_isSignalingNaN.c deleted file mode 100644 index c49e0f2e1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_isSignalingNaN.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f16_isSignalingNaN( float16_t a ) -{ - union ui16_f16 uA; - - uA.f = a; - return softfloat_isSigNaNF16UI( uA.ui ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_le.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_le.c deleted file mode 100644 index fa6943225..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_le.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f16_le( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF16UI( uiA ); - signB = signF16UI( uiB ); - return - (signA != signB) ? signA || ! (uint16_t) ((uiA | uiB)<<1) - : (uiA == uiB) || (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_le_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_le_quiet.c deleted file mode 100644 index 769a1dc9e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_le_quiet.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f16_le_quiet( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { - if ( - softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF16UI( uiA ); - signB = signF16UI( uiB ); - return - (signA != signB) ? signA || ! (uint16_t) ((uiA | uiB)<<1) - : (uiA == uiB) || (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_lt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_lt.c deleted file mode 100644 index e796016b6..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_lt.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f16_lt( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF16UI( uiA ); - signB = signF16UI( uiB ); - return - (signA != signB) ? signA && ((uint16_t) ((uiA | uiB)<<1) != 0) - : (uiA != uiB) && (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_lt_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_lt_quiet.c deleted file mode 100644 index c55bade74..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_lt_quiet.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f16_lt_quiet( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF16UI( uiA ) || isNaNF16UI( uiB ) ) { - if ( - softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF16UI( uiA ); - signB = signF16UI( uiB ); - return - (signA != signB) ? signA && ((uint16_t) ((uiA | uiB)<<1) != 0) - : (uiA != uiB) && (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_mul.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_mul.c deleted file mode 100644 index 112111d8d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_mul.c +++ /dev/null @@ -1,140 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t f16_mul( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool signA; - int_fast8_t expA; - uint_fast16_t sigA; - union ui16_f16 uB; - uint_fast16_t uiB; - bool signB; - int_fast8_t expB; - uint_fast16_t sigB; - bool signZ; - uint_fast16_t magBits; - struct exp8_sig16 normExpSig; - int_fast8_t expZ; - uint_fast32_t sig32Z; - uint_fast16_t sigZ, uiZ; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF16UI( uiA ); - expA = expF16UI( uiA ); - sigA = fracF16UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF16UI( uiB ); - expB = expF16UI( uiB ); - sigB = fracF16UI( uiB ); - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x1F ) { - if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN; - magBits = expB | sigB; - goto infArg; - } - if ( expB == 0x1F ) { - if ( sigB ) goto propagateNaN; - magBits = expA | sigA; - goto infArg; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF16Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zero; - normExpSig = softfloat_normSubnormalF16Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0xF; - sigA = (sigA | 0x0400)<<4; - sigB = (sigB | 0x0400)<<5; - sig32Z = (uint_fast32_t) sigA * sigB; - sigZ = sig32Z>>16; - if ( sig32Z & 0xFFFF ) sigZ |= 1; - if ( sigZ < 0x4000 ) { - --expZ; - sigZ <<= 1; - } - return softfloat_roundPackToF16( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infArg: - if ( ! magBits ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF16UI; - } else { - uiZ = packToF16UI( signZ, 0x1F, 0 ); - } - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ = packToF16UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_mulAdd.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_mulAdd.c deleted file mode 100644 index 092937298..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_mulAdd.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t f16_mulAdd( float16_t a, float16_t b, float16_t c ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; - union ui16_f16 uC; - uint_fast16_t uiC; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - uC.f = c; - uiC = uC.ui; - return softfloat_mulAddF16( uiA, uiB, uiC, 0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_rem.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_rem.c deleted file mode 100644 index 76a0de68a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_rem.c +++ /dev/null @@ -1,171 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t f16_rem( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool signA; - int_fast8_t expA; - uint_fast16_t sigA; - union ui16_f16 uB; - uint_fast16_t uiB; - int_fast8_t expB; - uint_fast16_t sigB; - struct exp8_sig16 normExpSig; - uint16_t rem; - int_fast8_t expDiff; - uint_fast16_t q; - uint32_t recip32, q32; - uint16_t altRem, meanRem; - bool signRem; - uint_fast16_t uiZ; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF16UI( uiA ); - expA = expF16UI( uiA ); - sigA = fracF16UI( uiA ); - uB.f = b; - uiB = uB.ui; - expB = expF16UI( uiB ); - sigB = fracF16UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x1F ) { - if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN; - goto invalid; - } - if ( expB == 0x1F ) { - if ( sigB ) goto propagateNaN; - return a; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! sigB ) goto invalid; - normExpSig = softfloat_normSubnormalF16Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF16Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - rem = sigA | 0x0400; - sigB |= 0x0400; - expDiff = expA - expB; - if ( expDiff < 1 ) { - if ( expDiff < -1 ) return a; - sigB <<= 3; - if ( expDiff ) { - rem <<= 2; - q = 0; - } else { - rem <<= 3; - q = (sigB <= rem); - if ( q ) rem -= sigB; - } - } else { - recip32 = softfloat_approxRecip32_1( (uint_fast32_t) sigB<<21 ); - /*-------------------------------------------------------------------- - | Changing the shift of `rem' here requires also changing the initial - | subtraction from `expDiff'. - *--------------------------------------------------------------------*/ - rem <<= 4; - expDiff -= 31; - /*-------------------------------------------------------------------- - | The scale of `sigB' affects how many bits are obtained during each - | cycle of the loop. Currently this is 29 bits per loop iteration, - | which is believed to be the maximum possible. - *--------------------------------------------------------------------*/ - sigB <<= 3; - for (;;) { - q32 = (rem * (uint_fast64_t) recip32)>>16; - if ( expDiff < 0 ) break; - rem = -((uint_fast16_t) q32 * sigB); - expDiff -= 29; - } - /*-------------------------------------------------------------------- - | (`expDiff' cannot be less than -30 here.) - *--------------------------------------------------------------------*/ - q32 >>= ~expDiff & 31; - q = q32; - rem = (rem<<(expDiff + 30)) - q * sigB; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - do { - altRem = rem; - ++q; - rem -= sigB; - } while ( ! (rem & 0x8000) ); - meanRem = rem + altRem; - if ( (meanRem & 0x8000) || (! meanRem && (q & 1)) ) rem = altRem; - signRem = signA; - if ( 0x8000 <= rem ) { - signRem = ! signRem; - rem = -rem; - } - return softfloat_normRoundPackToF16( signRem, expB, rem ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); - goto uiZ; - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF16UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_roundToInt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_roundToInt.c deleted file mode 100644 index d5ed190d5..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_roundToInt.c +++ /dev/null @@ -1,120 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t f16_roundToInt( float16_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - int_fast8_t exp; - uint_fast16_t uiZ, lastBitMask, roundBitsMask; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp <= 0xE ) { - if ( !(uint16_t) (uiA<<1) ) return a; - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - uiZ = uiA & packToF16UI( 1, 0, 0 ); - switch ( roundingMode ) { - case softfloat_round_near_even: - if ( !fracF16UI( uiA ) ) break; - case softfloat_round_near_maxMag: - if ( exp == 0xE ) uiZ |= packToF16UI( 0, 0xF, 0 ); - break; - case softfloat_round_min: - if ( uiZ ) uiZ = packToF16UI( 1, 0xF, 0 ); - break; - case softfloat_round_max: - if ( !uiZ ) uiZ = packToF16UI( 0, 0xF, 0 ); - break; -#ifdef SOFTFLOAT_ROUND_ODD - case softfloat_round_odd: - uiZ |= packToF16UI( 0, 0xF, 0 ); - break; -#endif - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x19 <= exp ) { - if ( (exp == 0x1F) && fracF16UI( uiA ) ) { - uiZ = softfloat_propagateNaNF16UI( uiA, 0 ); - goto uiZ; - } - return a; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ = uiA; - lastBitMask = (uint_fast16_t) 1<<(0x19 - exp); - roundBitsMask = lastBitMask - 1; - if ( roundingMode == softfloat_round_near_maxMag ) { - uiZ += lastBitMask>>1; - } else if ( roundingMode == softfloat_round_near_even ) { - uiZ += lastBitMask>>1; - if ( !(uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; - } else if ( - roundingMode - == (signF16UI( uiZ ) ? softfloat_round_min : softfloat_round_max) - ) { - uiZ += roundBitsMask; - } - uiZ &= ~roundBitsMask; - if ( uiZ != uiA ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) uiZ |= lastBitMask; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_sqrt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_sqrt.c deleted file mode 100644 index 40865fccc..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_sqrt.c +++ /dev/null @@ -1,136 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extern const uint16_t softfloat_approxRecipSqrt_1k0s[]; -extern const uint16_t softfloat_approxRecipSqrt_1k1s[]; - -float16_t f16_sqrt( float16_t a ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool signA; - int_fast8_t expA; - uint_fast16_t sigA, uiZ; - struct exp8_sig16 normExpSig; - int_fast8_t expZ; - int index; - uint_fast16_t r0; - uint_fast32_t ESqrR0; - uint16_t sigma0; - uint_fast16_t recipSqrt16, sigZ, shiftedSigZ; - uint16_t negRem; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF16UI( uiA ); - expA = expF16UI( uiA ); - sigA = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x1F ) { - if ( sigA ) { - uiZ = softfloat_propagateNaNF16UI( uiA, 0 ); - goto uiZ; - } - if ( ! signA ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signA ) { - if ( ! (expA | sigA) ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF16Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = ((expA - 0xF)>>1) + 0xE; - expA &= 1; - sigA |= 0x0400; - index = (sigA>>6 & 0xE) + expA; - r0 = softfloat_approxRecipSqrt_1k0s[index] - - (((uint_fast32_t) softfloat_approxRecipSqrt_1k1s[index] - * (sigA & 0x7F)) - >>11); - ESqrR0 = ((uint_fast32_t) r0 * r0)>>1; - if ( expA ) ESqrR0 >>= 1; - sigma0 = ~(uint_fast16_t) ((ESqrR0 * sigA)>>16); - recipSqrt16 = r0 + (((uint_fast32_t) r0 * sigma0)>>25); - if ( ! (recipSqrt16 & 0x8000) ) recipSqrt16 = 0x8000; - sigZ = ((uint_fast32_t) (sigA<<5) * recipSqrt16)>>16; - if ( expA ) sigZ >>= 1; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - ++sigZ; - if ( ! (sigZ & 7) ) { - shiftedSigZ = sigZ>>1; - negRem = shiftedSigZ * shiftedSigZ; - sigZ &= ~1; - if ( negRem & 0x8000 ) { - sigZ |= 1; - } else { - if ( negRem ) --sigZ; - } - } - return softfloat_roundPackToF16( 0, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF16UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_sub.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_sub.c deleted file mode 100644 index e18f25cf1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_sub.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t f16_sub( float16_t a, float16_t b ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - union ui16_f16 uB; - uint_fast16_t uiB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) - float16_t (*magsFuncPtr)( uint_fast16_t, uint_fast16_t ); -#endif - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; -#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) - if ( signF16UI( uiA ^ uiB ) ) { - return softfloat_addMagsF16( uiA, uiB ); - } else { - return softfloat_subMagsF16( uiA, uiB ); - } -#else - magsFuncPtr = - signF16UI( uiA ^ uiB ) ? softfloat_addMagsF16 : softfloat_subMagsF16; - return (*magsFuncPtr)( uiA, uiB ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_extF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_extF80.c deleted file mode 100644 index aaeed4d0a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_extF80.c +++ /dev/null @@ -1,101 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t f16_to_extF80( float16_t a ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - struct commonNaN commonNaN; - struct uint128 uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - struct exp8_sig16 normExpSig; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - if ( frac ) { - softfloat_f16UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToExtF80UI( &commonNaN ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - } else { - uiZ64 = packToExtF80UI64( sign, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ64 = packToExtF80UI64( sign, 0 ); - uiZ0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF16Sig( frac ); - exp = normExpSig.exp; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = packToExtF80UI64( sign, exp + 0x3FF0 ); - uiZ0 = (uint_fast64_t) (frac | 0x0400)<<53; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_extF80M.c deleted file mode 100644 index 75c5e6041..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_extF80M.c +++ /dev/null @@ -1,111 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f16_to_extF80M( float16_t a, extFloat80_t *zPtr ) -{ - - *zPtr = f16_to_extF80( a ); - -} - -#else - -void f16_to_extF80M( float16_t a, extFloat80_t *zPtr ) -{ - struct extFloat80M *zSPtr; - union ui16_f16 uA; - uint16_t uiA; - bool sign; - int_fast8_t exp; - uint16_t frac; - struct commonNaN commonNaN; - uint_fast16_t uiZ64; - uint32_t uiZ32; - struct exp8_sig16 normExpSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zSPtr = (struct extFloat80M *) zPtr; - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - if ( frac ) { - softfloat_f16UIToCommonNaN( uiA, &commonNaN ); - softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); - return; - } - uiZ64 = packToExtF80UI64( sign, 0x7FFF ); - uiZ32 = 0x80000000; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ64 = packToExtF80UI64( sign, 0 ); - uiZ32 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF16Sig( frac ); - exp = normExpSig.exp; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = packToExtF80UI64( sign, exp + 0x3FF0 ); - uiZ32 = 0x80000000 | (uint32_t) frac<<21; - uiZ: - zSPtr->signExp = uiZ64; - zSPtr->signif = (uint64_t) uiZ32<<32; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f128.c deleted file mode 100644 index 107479af9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f128.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t f16_to_f128( float16_t a ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - struct commonNaN commonNaN; - struct uint128 uiZ; - struct exp8_sig16 normExpSig; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - if ( frac ) { - softfloat_f16UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF128UI( &commonNaN ); - } else { - uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 ); - uiZ.v0 = 0; - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ.v64 = packToF128UI64( sign, 0, 0 ); - uiZ.v0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF16Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ.v64 = packToF128UI64( sign, exp + 0x3FF0, (uint_fast64_t) frac<<38 ); - uiZ.v0 = 0; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f128M.c deleted file mode 100644 index a31dab6ce..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f128M.c +++ /dev/null @@ -1,111 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f16_to_f128M( float16_t a, float128_t *zPtr ) -{ - - *zPtr = f16_to_f128( a ); - -} - -#else - -void f16_to_f128M( float16_t a, float128_t *zPtr ) -{ - uint32_t *zWPtr; - union ui16_f16 uA; - uint16_t uiA; - bool sign; - int_fast8_t exp; - uint16_t frac; - struct commonNaN commonNaN; - uint32_t uiZ96; - struct exp8_sig16 normExpSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - if ( frac ) { - softfloat_f16UIToCommonNaN( uiA, &commonNaN ); - softfloat_commonNaNToF128M( &commonNaN, zWPtr ); - return; - } - uiZ96 = packToF128UI96( sign, 0x7FFF, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ96 = packToF128UI96( sign, 0, 0 ); - goto uiZ; - } - normExpSig = softfloat_normSubnormalF16Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ96 = packToF128UI96( sign, exp + 0x3FF0, (uint32_t) frac<<6 ); - uiZ: - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f32.c deleted file mode 100644 index c58208a86..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f32.c +++ /dev/null @@ -1,93 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f16_to_f32( float16_t a ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - struct commonNaN commonNaN; - uint_fast32_t uiZ; - struct exp8_sig16 normExpSig; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - if ( frac ) { - softfloat_f16UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF32UI( &commonNaN ); - } else { - uiZ = packToF32UI( sign, 0xFF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ = packToF32UI( sign, 0, 0 ); - goto uiZ; - } - normExpSig = softfloat_normSubnormalF16Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ = packToF32UI( sign, exp + 0x70, (uint_fast32_t) frac<<13 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f64.c deleted file mode 100644 index dd85d33fc..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_f64.c +++ /dev/null @@ -1,93 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f16_to_f64( float16_t a ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - struct commonNaN commonNaN; - uint_fast64_t uiZ; - struct exp8_sig16 normExpSig; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - if ( frac ) { - softfloat_f16UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF64UI( &commonNaN ); - } else { - uiZ = packToF64UI( sign, 0x7FF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ = packToF64UI( sign, 0, 0 ); - goto uiZ; - } - normExpSig = softfloat_normSubnormalF16Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ = packToF64UI( sign, exp + 0x3F0, (uint_fast64_t) frac<<42 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i32.c deleted file mode 100644 index aeb2faca4..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i32.c +++ /dev/null @@ -1,87 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f16_to_i32( float16_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - int_fast32_t sig32; - int_fast8_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - frac ? i32_fromNaN - : sign ? i32_fromNegOverflow : i32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig32 = frac; - if ( exp ) { - sig32 |= 0x0400; - shiftDist = exp - 0x19; - if ( 0 <= shiftDist ) { - sig32 <<= shiftDist; - return sign ? -sig32 : sig32; - } - shiftDist = exp - 0x0D; - if ( 0 < shiftDist ) sig32 <<= shiftDist; - } - return - softfloat_roundToI32( - sign, (uint_fast32_t) sig32, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i32_r_minMag.c deleted file mode 100644 index 1aa72f569..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i32_r_minMag.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f16_to_i32_r_minMag( float16_t a, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - int_fast8_t exp; - uint_fast16_t frac; - int_fast8_t shiftDist; - bool sign; - int_fast32_t alignedSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = exp - 0x0F; - if ( shiftDist < 0 ) { - if ( exact && (exp | frac) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF16UI( uiA ); - if ( exp == 0x1F ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x1F) && frac ? i32_fromNaN - : sign ? i32_fromNegOverflow : i32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - alignedSig = (int_fast32_t) (frac | 0x0400)<>= 10; - return sign ? -alignedSig : alignedSig; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i64.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i64.c deleted file mode 100644 index c0487cf31..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i64.c +++ /dev/null @@ -1,87 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f16_to_i64( float16_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - int_fast32_t sig32; - int_fast8_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - frac ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig32 = frac; - if ( exp ) { - sig32 |= 0x0400; - shiftDist = exp - 0x19; - if ( 0 <= shiftDist ) { - sig32 <<= shiftDist; - return sign ? -sig32 : sig32; - } - shiftDist = exp - 0x0D; - if ( 0 < shiftDist ) sig32 <<= shiftDist; - } - return - softfloat_roundToI32( - sign, (uint_fast32_t) sig32, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i64_r_minMag.c deleted file mode 100644 index 25f91e210..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_i64_r_minMag.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f16_to_i64_r_minMag( float16_t a, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - int_fast8_t exp; - uint_fast16_t frac; - int_fast8_t shiftDist; - bool sign; - int_fast32_t alignedSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = exp - 0x0F; - if ( shiftDist < 0 ) { - if ( exact && (exp | frac) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF16UI( uiA ); - if ( exp == 0x1F ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x1F) && frac ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - alignedSig = (int_fast32_t) (frac | 0x0400)<>= 10; - return sign ? -alignedSig : alignedSig; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui32.c deleted file mode 100644 index 19ab66e72..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui32.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t f16_to_ui32( float16_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - uint_fast32_t sig32; - int_fast8_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - frac ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig32 = frac; - if ( exp ) { - sig32 |= 0x0400; - shiftDist = exp - 0x19; - if ( (0 <= shiftDist) && ! sign ) { - return sig32< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t f16_to_ui32_r_minMag( float16_t a, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - int_fast8_t exp; - uint_fast16_t frac; - int_fast8_t shiftDist; - bool sign; - uint_fast32_t alignedSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = exp - 0x0F; - if ( shiftDist < 0 ) { - if ( exact && (exp | frac) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF16UI( uiA ); - if ( sign || (exp == 0x1F) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x1F) && frac ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - alignedSig = (uint_fast32_t) (frac | 0x0400)<>10; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui64.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui64.c deleted file mode 100644 index 4260b7a05..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui64.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t f16_to_ui64( float16_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - bool sign; - int_fast8_t exp; - uint_fast16_t frac; - uint_fast32_t sig32; - int_fast8_t shiftDist; -#ifndef SOFTFLOAT_FAST_INT64 - uint32_t extSig[3]; -#endif - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF16UI( uiA ); - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x1F ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - frac ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig32 = frac; - if ( exp ) { - sig32 |= 0x0400; - shiftDist = exp - 0x19; - if ( (0 <= shiftDist) && ! sign ) { - return sig32<>12, (uint_fast64_t) sig32<<52, roundingMode, exact ); -#else - extSig[indexWord( 3, 2 )] = 0; - extSig[indexWord( 3, 1 )] = sig32>>12; - extSig[indexWord( 3, 0 )] = sig32<<20; - return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui64_r_minMag.c deleted file mode 100644 index 098a59763..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f16_to_ui64_r_minMag.c +++ /dev/null @@ -1,87 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t f16_to_ui64_r_minMag( float16_t a, bool exact ) -{ - union ui16_f16 uA; - uint_fast16_t uiA; - int_fast8_t exp; - uint_fast16_t frac; - int_fast8_t shiftDist; - bool sign; - uint_fast32_t alignedSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF16UI( uiA ); - frac = fracF16UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = exp - 0x0F; - if ( shiftDist < 0 ) { - if ( exact && (exp | frac) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF16UI( uiA ); - if ( sign || (exp == 0x1F) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x1F) && frac ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - alignedSig = (uint_fast32_t) (frac | 0x0400)<>10; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_add.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_add.c deleted file mode 100644 index f59ac0a8a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_add.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t f32_add( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) - float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t ); -#endif - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; -#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) - if ( signF32UI( uiA ^ uiB ) ) { - return softfloat_subMagsF32( uiA, uiB ); - } else { - return softfloat_addMagsF32( uiA, uiB ); - } -#else - magsFuncPtr = - signF32UI( uiA ^ uiB ) ? softfloat_subMagsF32 : softfloat_addMagsF32; - return (*magsFuncPtr)( uiA, uiB ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_div.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_div.c deleted file mode 100644 index 8d4447914..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_div.c +++ /dev/null @@ -1,180 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f32_div( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool signA; - int_fast16_t expA; - uint_fast32_t sigA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signB; - int_fast16_t expB; - uint_fast32_t sigB; - bool signZ; - struct exp16_sig32 normExpSig; - int_fast16_t expZ; -#ifdef SOFTFLOAT_FAST_DIV64TO32 - uint_fast64_t sig64A; - uint_fast32_t sigZ; -#else - uint_fast32_t sigZ; - uint_fast64_t rem; -#endif - uint_fast32_t uiZ; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF32UI( uiB ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0xFF ) { - if ( sigA ) goto propagateNaN; - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN; - goto invalid; - } - goto infinity; - } - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN; - goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! sigB ) { - if ( ! (expA | sigA) ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinite ); - goto infinity; - } - normExpSig = softfloat_normSubnormalF32Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA - expB + 0x7E; - sigA |= 0x00800000; - sigB |= 0x00800000; -#ifdef SOFTFLOAT_FAST_DIV64TO32 - if ( sigA < sigB ) { - --expZ; - sig64A = (uint_fast64_t) sigA<<31; - } else { - sig64A = (uint_fast64_t) sigA<<30; - } - sigZ = sig64A / sigB; - if ( ! (sigZ & 0x3F) ) sigZ |= ((uint_fast64_t) sigB * sigZ != sig64A); -#else - if ( sigA < sigB ) { - --expZ; - sigA <<= 8; - } else { - sigA <<= 7; - } - sigB <<= 8; - sigZ = ((uint_fast64_t) sigA * softfloat_approxRecip32_1( sigB ))>>32; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sigZ += 2; - if ( (sigZ & 0x3F) < 2 ) { - sigZ &= ~3; -#ifdef SOFTFLOAT_FAST_INT64 - rem = ((uint_fast64_t) sigA<<31) - (uint_fast64_t) sigZ * sigB; -#else - rem = ((uint_fast64_t) sigA<<32) - (uint_fast64_t) (sigZ<<1) * sigB; -#endif - if ( rem & UINT64_C( 0x8000000000000000 ) ) { - sigZ -= 4; - } else { - if ( rem ) sigZ |= 1; - } - } -#endif - return softfloat_roundPackToF32( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF32UI; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ = packToF32UI( signZ, 0xFF, 0 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ = packToF32UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_eq.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_eq.c deleted file mode 100644 index 316fe6a4d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_eq.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f32_eq( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { - if ( - softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - return (uiA == uiB) || ! (uint32_t) ((uiA | uiB)<<1); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_eq_signaling.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_eq_signaling.c deleted file mode 100644 index 03395f310..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_eq_signaling.c +++ /dev/null @@ -1,61 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f32_eq_signaling( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - return (uiA == uiB) || ! (uint32_t) ((uiA | uiB)<<1); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_isSignalingNaN.c deleted file mode 100644 index d98cc9b26..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_isSignalingNaN.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f32_isSignalingNaN( float32_t a ) -{ - union ui32_f32 uA; - - uA.f = a; - return softfloat_isSigNaNF32UI( uA.ui ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_le.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_le.c deleted file mode 100644 index 83a30079d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_le.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f32_le( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF32UI( uiA ); - signB = signF32UI( uiB ); - return - (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1) - : (uiA == uiB) || (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_le_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_le_quiet.c deleted file mode 100644 index 329fe3937..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_le_quiet.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f32_le_quiet( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { - if ( - softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF32UI( uiA ); - signB = signF32UI( uiB ); - return - (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1) - : (uiA == uiB) || (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_lt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_lt.c deleted file mode 100644 index ddc180499..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_lt.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f32_lt( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF32UI( uiA ); - signB = signF32UI( uiB ); - return - (signA != signB) ? signA && ((uint32_t) ((uiA | uiB)<<1) != 0) - : (uiA != uiB) && (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_lt_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_lt_quiet.c deleted file mode 100644 index 59c9cf12c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_lt_quiet.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f32_lt_quiet( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { - if ( - softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF32UI( uiA ); - signB = signF32UI( uiB ); - return - (signA != signB) ? signA && ((uint32_t) ((uiA | uiB)<<1) != 0) - : (uiA != uiB) && (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_mul.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_mul.c deleted file mode 100644 index b1f8ec002..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_mul.c +++ /dev/null @@ -1,137 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f32_mul( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool signA; - int_fast16_t expA; - uint_fast32_t sigA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signB; - int_fast16_t expB; - uint_fast32_t sigB; - bool signZ; - uint_fast32_t magBits; - struct exp16_sig32 normExpSig; - int_fast16_t expZ; - uint_fast32_t sigZ, uiZ; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF32UI( uiB ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0xFF ) { - if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN; - magBits = expB | sigB; - goto infArg; - } - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN; - magBits = expA | sigA; - goto infArg; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zero; - normExpSig = softfloat_normSubnormalF32Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x7F; - sigA = (sigA | 0x00800000)<<7; - sigB = (sigB | 0x00800000)<<8; - sigZ = softfloat_shortShiftRightJam64( (uint_fast64_t) sigA * sigB, 32 ); - if ( sigZ < 0x40000000 ) { - --expZ; - sigZ <<= 1; - } - return softfloat_roundPackToF32( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infArg: - if ( ! magBits ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF32UI; - } else { - uiZ = packToF32UI( signZ, 0xFF, 0 ); - } - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ = packToF32UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_mulAdd.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_mulAdd.c deleted file mode 100644 index b77777e4e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_mulAdd.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t f32_mulAdd( float32_t a, float32_t b, float32_t c ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - union ui32_f32 uC; - uint_fast32_t uiC; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - uC.f = c; - uiC = uC.ui; - return softfloat_mulAddF32( uiA, uiB, uiC, 0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_rem.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_rem.c deleted file mode 100644 index 2d74c8cd9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_rem.c +++ /dev/null @@ -1,168 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f32_rem( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool signA; - int_fast16_t expA; - uint_fast32_t sigA; - union ui32_f32 uB; - uint_fast32_t uiB; - int_fast16_t expB; - uint_fast32_t sigB; - struct exp16_sig32 normExpSig; - uint32_t rem; - int_fast16_t expDiff; - uint32_t q, recip32, altRem, meanRem; - bool signRem; - uint_fast32_t uiZ; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - uB.f = b; - uiB = uB.ui; - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0xFF ) { - if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN; - goto invalid; - } - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN; - return a; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! sigB ) goto invalid; - normExpSig = softfloat_normSubnormalF32Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - rem = sigA | 0x00800000; - sigB |= 0x00800000; - expDiff = expA - expB; - if ( expDiff < 1 ) { - if ( expDiff < -1 ) return a; - sigB <<= 6; - if ( expDiff ) { - rem <<= 5; - q = 0; - } else { - rem <<= 6; - q = (sigB <= rem); - if ( q ) rem -= sigB; - } - } else { - recip32 = softfloat_approxRecip32_1( sigB<<8 ); - /*-------------------------------------------------------------------- - | Changing the shift of `rem' here requires also changing the initial - | subtraction from `expDiff'. - *--------------------------------------------------------------------*/ - rem <<= 7; - expDiff -= 31; - /*-------------------------------------------------------------------- - | The scale of `sigB' affects how many bits are obtained during each - | cycle of the loop. Currently this is 29 bits per loop iteration, - | which is believed to be the maximum possible. - *--------------------------------------------------------------------*/ - sigB <<= 6; - for (;;) { - q = (rem * (uint_fast64_t) recip32)>>32; - if ( expDiff < 0 ) break; - rem = -(q * (uint32_t) sigB); - expDiff -= 29; - } - /*-------------------------------------------------------------------- - | (`expDiff' cannot be less than -30 here.) - *--------------------------------------------------------------------*/ - q >>= ~expDiff & 31; - rem = (rem<<(expDiff + 30)) - q * (uint32_t) sigB; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - do { - altRem = rem; - ++q; - rem -= sigB; - } while ( ! (rem & 0x80000000) ); - meanRem = rem + altRem; - if ( (meanRem & 0x80000000) || (! meanRem && (q & 1)) ) rem = altRem; - signRem = signA; - if ( 0x80000000 <= rem ) { - signRem = ! signRem; - rem = -rem; - } - return softfloat_normRoundPackToF32( signRem, expB, rem ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); - goto uiZ; - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF32UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_roundToInt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_roundToInt.c deleted file mode 100644 index 801a76919..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_roundToInt.c +++ /dev/null @@ -1,120 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f32_roundToInt( float32_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t uiZ, lastBitMask, roundBitsMask; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp <= 0x7E ) { - if ( !(uint32_t) (uiA<<1) ) return a; - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - uiZ = uiA & packToF32UI( 1, 0, 0 ); - switch ( roundingMode ) { - case softfloat_round_near_even: - if ( !fracF32UI( uiA ) ) break; - case softfloat_round_near_maxMag: - if ( exp == 0x7E ) uiZ |= packToF32UI( 0, 0x7F, 0 ); - break; - case softfloat_round_min: - if ( uiZ ) uiZ = packToF32UI( 1, 0x7F, 0 ); - break; - case softfloat_round_max: - if ( !uiZ ) uiZ = packToF32UI( 0, 0x7F, 0 ); - break; -#ifdef SOFTFLOAT_ROUND_ODD - case softfloat_round_odd: - uiZ |= packToF32UI( 0, 0x7F, 0 ); - break; -#endif - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x96 <= exp ) { - if ( (exp == 0xFF) && fracF32UI( uiA ) ) { - uiZ = softfloat_propagateNaNF32UI( uiA, 0 ); - goto uiZ; - } - return a; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ = uiA; - lastBitMask = (uint_fast32_t) 1<<(0x96 - exp); - roundBitsMask = lastBitMask - 1; - if ( roundingMode == softfloat_round_near_maxMag ) { - uiZ += lastBitMask>>1; - } else if ( roundingMode == softfloat_round_near_even ) { - uiZ += lastBitMask>>1; - if ( !(uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; - } else if ( - roundingMode - == (signF32UI( uiZ ) ? softfloat_round_min : softfloat_round_max) - ) { - uiZ += roundBitsMask; - } - uiZ &= ~roundBitsMask; - if ( uiZ != uiA ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) uiZ |= lastBitMask; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_sqrt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_sqrt.c deleted file mode 100644 index 9c6a99846..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_sqrt.c +++ /dev/null @@ -1,121 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f32_sqrt( float32_t a ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool signA; - int_fast16_t expA; - uint_fast32_t sigA, uiZ; - struct exp16_sig32 normExpSig; - int_fast16_t expZ; - uint_fast32_t sigZ, shiftedSigZ; - uint32_t negRem; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0xFF ) { - if ( sigA ) { - uiZ = softfloat_propagateNaNF32UI( uiA, 0 ); - goto uiZ; - } - if ( ! signA ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signA ) { - if ( ! (expA | sigA) ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = ((expA - 0x7F)>>1) + 0x7E; - expA &= 1; - sigA = (sigA | 0x00800000)<<8; - sigZ = - ((uint_fast64_t) sigA * softfloat_approxRecipSqrt32_1( expA, sigA )) - >>32; - if ( expA ) sigZ >>= 1; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sigZ += 2; - if ( (sigZ & 0x3F) < 2 ) { - shiftedSigZ = sigZ>>2; - negRem = shiftedSigZ * shiftedSigZ; - sigZ &= ~3; - if ( negRem & 0x80000000 ) { - sigZ |= 1; - } else { - if ( negRem ) --sigZ; - } - } - return softfloat_roundPackToF32( 0, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF32UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_sub.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_sub.c deleted file mode 100644 index edbcd2fb1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_sub.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t f32_sub( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) - float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t ); -#endif - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; -#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) - if ( signF32UI( uiA ^ uiB ) ) { - return softfloat_addMagsF32( uiA, uiB ); - } else { - return softfloat_subMagsF32( uiA, uiB ); - } -#else - magsFuncPtr = - signF32UI( uiA ^ uiB ) ? softfloat_addMagsF32 : softfloat_subMagsF32; - return (*magsFuncPtr)( uiA, uiB ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_extF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_extF80.c deleted file mode 100644 index 8d3545701..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_extF80.c +++ /dev/null @@ -1,101 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t f32_to_extF80( float32_t a ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t frac; - struct commonNaN commonNaN; - struct uint128 uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - struct exp16_sig32 normExpSig; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - frac = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0xFF ) { - if ( frac ) { - softfloat_f32UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToExtF80UI( &commonNaN ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - } else { - uiZ64 = packToExtF80UI64( sign, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ64 = packToExtF80UI64( sign, 0 ); - uiZ0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF32Sig( frac ); - exp = normExpSig.exp; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = packToExtF80UI64( sign, exp + 0x3F80 ); - uiZ0 = (uint_fast64_t) (frac | 0x00800000)<<40; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_extF80M.c deleted file mode 100644 index 03580fd5f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_extF80M.c +++ /dev/null @@ -1,111 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f32_to_extF80M( float32_t a, extFloat80_t *zPtr ) -{ - - *zPtr = f32_to_extF80( a ); - -} - -#else - -void f32_to_extF80M( float32_t a, extFloat80_t *zPtr ) -{ - struct extFloat80M *zSPtr; - union ui32_f32 uA; - uint32_t uiA; - bool sign; - int_fast16_t exp; - uint32_t frac; - struct commonNaN commonNaN; - uint_fast16_t uiZ64; - uint32_t uiZ32; - struct exp16_sig32 normExpSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zSPtr = (struct extFloat80M *) zPtr; - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - frac = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0xFF ) { - if ( frac ) { - softfloat_f32UIToCommonNaN( uiA, &commonNaN ); - softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); - return; - } - uiZ64 = packToExtF80UI64( sign, 0x7FFF ); - uiZ32 = 0x80000000; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ64 = packToExtF80UI64( sign, 0 ); - uiZ32 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF32Sig( frac ); - exp = normExpSig.exp; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = packToExtF80UI64( sign, exp + 0x3F80 ); - uiZ32 = 0x80000000 | (uint32_t) frac<<8; - uiZ: - zSPtr->signExp = uiZ64; - zSPtr->signif = (uint64_t) uiZ32<<32; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f128.c deleted file mode 100644 index ee0b414c1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f128.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t f32_to_f128( float32_t a ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t frac; - struct commonNaN commonNaN; - struct uint128 uiZ; - struct exp16_sig32 normExpSig; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - frac = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0xFF ) { - if ( frac ) { - softfloat_f32UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF128UI( &commonNaN ); - } else { - uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 ); - uiZ.v0 = 0; - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ.v64 = packToF128UI64( sign, 0, 0 ); - uiZ.v0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF32Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ.v64 = packToF128UI64( sign, exp + 0x3F80, (uint_fast64_t) frac<<25 ); - uiZ.v0 = 0; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f128M.c deleted file mode 100644 index cd3ad693f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f128M.c +++ /dev/null @@ -1,115 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f32_to_f128M( float32_t a, float128_t *zPtr ) -{ - - *zPtr = f32_to_f128( a ); - -} - -#else - -void f32_to_f128M( float32_t a, float128_t *zPtr ) -{ - uint32_t *zWPtr; - union ui32_f32 uA; - uint32_t uiA; - bool sign; - int_fast16_t exp; - uint32_t frac, uiZ64; - struct commonNaN commonNaN; - uint32_t uiZ96; - struct exp16_sig32 normExpSig; - uint64_t frac64; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - frac = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = 0; - if ( exp == 0xFF ) { - if ( frac ) { - softfloat_f32UIToCommonNaN( uiA, &commonNaN ); - softfloat_commonNaNToF128M( &commonNaN, zWPtr ); - return; - } - uiZ96 = packToF128UI96( sign, 0x7FFF, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ96 = packToF128UI96( sign, 0, 0 ); - goto uiZ; - } - normExpSig = softfloat_normSubnormalF32Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac64 = (uint64_t) frac<<25; - uiZ96 = packToF128UI96( sign, exp + 0x3F80, frac64>>32 ); - uiZ64 = frac64; - uiZ: - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = uiZ64; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f16.c deleted file mode 100644 index a00b2e8de..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f16.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t f32_to_f16( float32_t a ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t frac; - struct commonNaN commonNaN; - uint_fast16_t uiZ, frac16; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - frac = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0xFF ) { - if ( frac ) { - softfloat_f32UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF16UI( &commonNaN ); - } else { - uiZ = packToF16UI( sign, 0x1F, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac16 = frac>>9 | ((frac & 0x1FF) != 0); - if ( ! (exp | frac16) ) { - uiZ = packToF16UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - return softfloat_roundPackToF16( sign, exp - 0x71, frac16 | 0x4000 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f64.c deleted file mode 100644 index 6cd08eddb..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_f64.c +++ /dev/null @@ -1,93 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f32_to_f64( float32_t a ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t frac; - struct commonNaN commonNaN; - uint_fast64_t uiZ; - struct exp16_sig32 normExpSig; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - frac = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0xFF ) { - if ( frac ) { - softfloat_f32UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF64UI( &commonNaN ); - } else { - uiZ = packToF64UI( sign, 0x7FF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ = packToF64UI( sign, 0, 0 ); - goto uiZ; - } - normExpSig = softfloat_normSubnormalF32Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ = packToF64UI( sign, exp + 0x380, (uint_fast64_t) frac<<29 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i32.c deleted file mode 100644 index 241ab8e8c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i32.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - uint_fast64_t sig64; - int_fast16_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) - if ( (exp == 0xFF) && sig ) { -#if (i32_fromNaN == i32_fromPosOverflow) - sign = 0; -#elif (i32_fromNaN == i32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return i32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<32; - shiftDist = 0xAA - exp; - if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - return softfloat_roundToI32( sign, sig64, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i32_r_minMag.c deleted file mode 100644 index f8134f461..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i32_r_minMag.c +++ /dev/null @@ -1,89 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f32_to_i32_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftDist; - bool sign; - int_fast32_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x9E - exp; - if ( 32 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF32UI( uiA ); - if ( shiftDist <= 0 ) { - if ( uiA == packToF32UI( 1, 0x9E, 0 ) ) return -0x7FFFFFFF - 1; - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0xFF) && sig ? i32_fromNaN - : sign ? i32_fromNegOverflow : i32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = (sig | 0x00800000)<<8; - absZ = sig>>shiftDist; - if ( exact && ((uint_fast32_t) absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftDist; -#ifdef SOFTFLOAT_FAST_INT64 - uint_fast64_t sig64, extra; - struct uint64_extra sig64Extra; -#else - uint32_t extSig[3]; -#endif - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0xBE - exp; - if ( shiftDist < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0xFF) && sig ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= 0x00800000; -#ifdef SOFTFLOAT_FAST_INT64 - sig64 = (uint_fast64_t) sig<<40; - extra = 0; - if ( shiftDist ) { - sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist ); - sig64 = sig64Extra.v; - extra = sig64Extra.extra; - } - return softfloat_roundToI64( sign, sig64, extra, roundingMode, exact ); -#else - extSig[indexWord( 3, 2 )] = sig<<8; - extSig[indexWord( 3, 1 )] = 0; - extSig[indexWord( 3, 0 )] = 0; - if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - return softfloat_roundMToI64( sign, extSig, roundingMode, exact ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i64_r_minMag.c deleted file mode 100644 index 346f6b83d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_i64_r_minMag.c +++ /dev/null @@ -1,94 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f32_to_i64_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftDist; - bool sign; - uint_fast64_t sig64; - int_fast64_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0xBE - exp; - if ( 64 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF32UI( uiA ); - if ( shiftDist <= 0 ) { - if ( uiA == packToF32UI( 1, 0xBE, 0 ) ) { - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0xFF) && sig ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<40; - absZ = sig64>>shiftDist; - shiftDist = 40 - shiftDist; - if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return sign ? -absZ : absZ; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui32.c deleted file mode 100644 index 32d9eaca1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui32.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t f32_to_ui32( float32_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - uint_fast64_t sig64; - int_fast16_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) - if ( (exp == 0xFF) && sig ) { -#if (ui32_fromNaN == ui32_fromPosOverflow) - sign = 0; -#elif (ui32_fromNaN == ui32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return ui32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<32; - shiftDist = 0xAA - exp; - if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); - return softfloat_roundToUI32( sign, sig64, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui32_r_minMag.c deleted file mode 100644 index a90ef926e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui32_r_minMag.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t f32_to_ui32_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftDist; - bool sign; - uint_fast32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x9E - exp; - if ( 32 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF32UI( uiA ); - if ( sign || (shiftDist < 0) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0xFF) && sig ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = (sig | 0x00800000)<<8; - z = sig>>shiftDist; - if ( exact && (z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftDist; -#ifdef SOFTFLOAT_FAST_INT64 - uint_fast64_t sig64, extra; - struct uint64_extra sig64Extra; -#else - uint32_t extSig[3]; -#endif - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0xBE - exp; - if ( shiftDist < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0xFF) && sig ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= 0x00800000; -#ifdef SOFTFLOAT_FAST_INT64 - sig64 = (uint_fast64_t) sig<<40; - extra = 0; - if ( shiftDist ) { - sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist ); - sig64 = sig64Extra.v; - extra = sig64Extra.extra; - } - return softfloat_roundToUI64( sign, sig64, extra, roundingMode, exact ); -#else - extSig[indexWord( 3, 2 )] = sig<<8; - extSig[indexWord( 3, 1 )] = 0; - extSig[indexWord( 3, 0 )] = 0; - if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui64_r_minMag.c deleted file mode 100644 index 69e00648f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f32_to_ui64_r_minMag.c +++ /dev/null @@ -1,90 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t f32_to_ui64_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftDist; - bool sign; - uint_fast64_t sig64, z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0xBE - exp; - if ( 64 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF32UI( uiA ); - if ( sign || (shiftDist < 0) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0xFF) && sig ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<40; - z = sig64>>shiftDist; - shiftDist = 40 - shiftDist; - if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return z; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_add.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_add.c deleted file mode 100644 index 878f6da75..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_add.c +++ /dev/null @@ -1,74 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t f64_add( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - float64_t (*magsFuncPtr)( uint_fast64_t, uint_fast64_t, bool ); -#endif - - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF64UI( uiB ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_addMagsF64( uiA, uiB, signA ); - } else { - return softfloat_subMagsF64( uiA, uiB, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_addMagsF64 : softfloat_subMagsF64; - return (*magsFuncPtr)( uiA, uiB, signA ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_div.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_div.c deleted file mode 100644 index 7f5eddd4a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_div.c +++ /dev/null @@ -1,172 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f64_div( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - int_fast16_t expA; - uint_fast64_t sigA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signB; - int_fast16_t expB; - uint_fast64_t sigB; - bool signZ; - struct exp16_sig64 normExpSig; - int_fast16_t expZ; - uint32_t recip32, sig32Z, doubleTerm; - uint_fast64_t rem; - uint32_t q; - uint_fast64_t sigZ; - uint_fast64_t uiZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF64UI( uiB ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FF ) { - if ( sigA ) goto propagateNaN; - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN; - goto invalid; - } - goto infinity; - } - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN; - goto zero; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! sigB ) { - if ( ! (expA | sigA) ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinite ); - goto infinity; - } - normExpSig = softfloat_normSubnormalF64Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA - expB + 0x3FE; - sigA |= UINT64_C( 0x0010000000000000 ); - sigB |= UINT64_C( 0x0010000000000000 ); - if ( sigA < sigB ) { - --expZ; - sigA <<= 11; - } else { - sigA <<= 10; - } - sigB <<= 11; - recip32 = softfloat_approxRecip32_1( sigB>>32 ) - 2; - sig32Z = ((uint32_t) (sigA>>32) * (uint_fast64_t) recip32)>>32; - doubleTerm = sig32Z<<1; - rem = - ((sigA - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28) - - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4); - q = (((uint32_t) (rem>>32) * (uint_fast64_t) recip32)>>32) + 4; - sigZ = ((uint_fast64_t) sig32Z<<32) + ((uint_fast64_t) q<<4); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (sigZ & 0x1FF) < 4<<4 ) { - q &= ~7; - sigZ &= ~(uint_fast64_t) 0x7F; - doubleTerm = q<<1; - rem = - ((rem - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28) - - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4); - if ( rem & UINT64_C( 0x8000000000000000 ) ) { - sigZ -= 1<<7; - } else { - if ( rem ) sigZ |= 1; - } - } - return softfloat_roundPackToF64( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infinity: - uiZ = packToF64UI( signZ, 0x7FF, 0 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ = packToF64UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_eq.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_eq.c deleted file mode 100644 index e075c02f8..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_eq.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f64_eq( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { - if ( - softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - return (uiA == uiB) || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_eq_signaling.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_eq_signaling.c deleted file mode 100644 index d7e89a2ed..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_eq_signaling.c +++ /dev/null @@ -1,61 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f64_eq_signaling( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - return (uiA == uiB) || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_isSignalingNaN.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_isSignalingNaN.c deleted file mode 100644 index 5e1411fc1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_isSignalingNaN.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f64_isSignalingNaN( float64_t a ) -{ - union ui64_f64 uA; - - uA.f = a; - return softfloat_isSigNaNF64UI( uA.ui ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_le.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_le.c deleted file mode 100644 index a96808f33..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_le.c +++ /dev/null @@ -1,67 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f64_le( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF64UI( uiA ); - signB = signF64UI( uiB ); - return - (signA != signB) - ? signA || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - : (uiA == uiB) || (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_le_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_le_quiet.c deleted file mode 100644 index 942afba75..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_le_quiet.c +++ /dev/null @@ -1,72 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f64_le_quiet( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { - if ( - softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF64UI( uiA ); - signB = signF64UI( uiB ); - return - (signA != signB) - ? signA || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - : (uiA == uiB) || (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_lt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_lt.c deleted file mode 100644 index d9cf5aa7e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_lt.c +++ /dev/null @@ -1,67 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -bool f64_lt( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return false; - } - signA = signF64UI( uiA ); - signB = signF64UI( uiB ); - return - (signA != signB) - ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - : (uiA != uiB) && (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_lt_quiet.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_lt_quiet.c deleted file mode 100644 index 89d30bc00..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_lt_quiet.c +++ /dev/null @@ -1,72 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -bool f64_lt_quiet( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signA, signB; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { - if ( - softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) - ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return false; - } - signA = signF64UI( uiA ); - signB = signF64UI( uiB ); - return - (signA != signB) - ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - : (uiA != uiB) && (signA ^ (uiA < uiB)); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_mul.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_mul.c deleted file mode 100644 index 38bdc852a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_mul.c +++ /dev/null @@ -1,150 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f64_mul( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - int_fast16_t expA; - uint_fast64_t sigA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signB; - int_fast16_t expB; - uint_fast64_t sigB; - bool signZ; - uint_fast64_t magBits; - struct exp16_sig64 normExpSig; - int_fast16_t expZ; -#ifdef SOFTFLOAT_FAST_INT64 - struct uint128 sig128Z; -#else - uint32_t sig128Z[4]; -#endif - uint_fast64_t sigZ, uiZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF64UI( uiB ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - signZ = signA ^ signB; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FF ) { - if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN; - magBits = expB | sigB; - goto infArg; - } - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN; - magBits = expA | sigA; - goto infArg; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zero; - normExpSig = softfloat_normSubnormalF64Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x3FF; - sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10; - sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<11; -#ifdef SOFTFLOAT_FAST_INT64 - sig128Z = softfloat_mul64To128( sigA, sigB ); - sigZ = sig128Z.v64 | (sig128Z.v0 != 0); -#else - softfloat_mul64To128M( sigA, sigB, sig128Z ); - sigZ = - (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )]; - if ( sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] ) sigZ |= 1; -#endif - if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { - --expZ; - sigZ <<= 1; - } - return softfloat_roundPackToF64( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infArg: - if ( ! magBits ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - } else { - uiZ = packToF64UI( signZ, 0x7FF, 0 ); - } - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zero: - uiZ = packToF64UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_mulAdd.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_mulAdd.c deleted file mode 100644 index 13fc38287..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_mulAdd.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t f64_mulAdd( float64_t a, float64_t b, float64_t c ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - union ui64_f64 uC; - uint_fast64_t uiC; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - uC.f = c; - uiC = uC.ui; - return softfloat_mulAddF64( uiA, uiB, uiC, 0 ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_rem.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_rem.c deleted file mode 100644 index ca5350c94..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_rem.c +++ /dev/null @@ -1,189 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f64_rem( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - int_fast16_t expA; - uint_fast64_t sigA; - union ui64_f64 uB; - uint_fast64_t uiB; - int_fast16_t expB; - uint_fast64_t sigB; - struct exp16_sig64 normExpSig; - uint64_t rem; - int_fast16_t expDiff; - uint32_t q, recip32; - uint_fast64_t q64; - uint64_t altRem, meanRem; - bool signRem; - uint_fast64_t uiZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - uB.f = b; - uiB = uB.ui; - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FF ) { - if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN; - goto invalid; - } - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN; - return a; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA < expB - 1 ) return a; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expB ) { - if ( ! sigB ) goto invalid; - normExpSig = softfloat_normSubnormalF64Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - rem = sigA | UINT64_C( 0x0010000000000000 ); - sigB |= UINT64_C( 0x0010000000000000 ); - expDiff = expA - expB; - if ( expDiff < 1 ) { - if ( expDiff < -1 ) return a; - sigB <<= 9; - if ( expDiff ) { - rem <<= 8; - q = 0; - } else { - rem <<= 9; - q = (sigB <= rem); - if ( q ) rem -= sigB; - } - } else { - recip32 = softfloat_approxRecip32_1( sigB>>21 ); - /*-------------------------------------------------------------------- - | Changing the shift of `rem' here requires also changing the initial - | subtraction from `expDiff'. - *--------------------------------------------------------------------*/ - rem <<= 9; - expDiff -= 30; - /*-------------------------------------------------------------------- - | The scale of `sigB' affects how many bits are obtained during each - | cycle of the loop. Currently this is 29 bits per loop iteration, - | the maximum possible. - *--------------------------------------------------------------------*/ - sigB <<= 9; - for (;;) { - q64 = (uint32_t) (rem>>32) * (uint_fast64_t) recip32; - if ( expDiff < 0 ) break; - q = (q64 + 0x80000000)>>32; -#ifdef SOFTFLOAT_FAST_INT64 - rem <<= 29; -#else - rem = (uint_fast64_t) (uint32_t) (rem>>3)<<32; -#endif - rem -= q * (uint64_t) sigB; - if ( rem & UINT64_C( 0x8000000000000000 ) ) rem += sigB; - expDiff -= 29; - } - /*-------------------------------------------------------------------- - | (`expDiff' cannot be less than -29 here.) - *--------------------------------------------------------------------*/ - q = (uint32_t) (q64>>32)>>(~expDiff & 31); - rem = (rem<<(expDiff + 30)) - q * (uint64_t) sigB; - if ( rem & UINT64_C( 0x8000000000000000 ) ) { - altRem = rem + sigB; - goto selectRem; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - do { - altRem = rem; - ++q; - rem -= sigB; - } while ( ! (rem & UINT64_C( 0x8000000000000000 )) ); - selectRem: - meanRem = rem + altRem; - if ( - (meanRem & UINT64_C( 0x8000000000000000 )) || (! meanRem && (q & 1)) - ) { - rem = altRem; - } - signRem = signA; - if ( rem & UINT64_C( 0x8000000000000000 ) ) { - signRem = ! signRem; - rem = -rem; - } - return softfloat_normRoundPackToF64( signRem, expB, rem ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - goto uiZ; - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_roundToInt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_roundToInt.c deleted file mode 100644 index c5f08ae16..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_roundToInt.c +++ /dev/null @@ -1,120 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - int_fast16_t exp; - uint_fast64_t uiZ, lastBitMask, roundBitsMask; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp <= 0x3FE ) { - if ( !(uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) return a; - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - uiZ = uiA & packToF64UI( 1, 0, 0 ); - switch ( roundingMode ) { - case softfloat_round_near_even: - if ( !fracF64UI( uiA ) ) break; - case softfloat_round_near_maxMag: - if ( exp == 0x3FE ) uiZ |= packToF64UI( 0, 0x3FF, 0 ); - break; - case softfloat_round_min: - if ( uiZ ) uiZ = packToF64UI( 1, 0x3FF, 0 ); - break; - case softfloat_round_max: - if ( !uiZ ) uiZ = packToF64UI( 0, 0x3FF, 0 ); - break; -#ifdef SOFTFLOAT_ROUND_ODD - case softfloat_round_odd: - uiZ |= packToF64UI( 0, 0x3FF, 0 ); - break; -#endif - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x433 <= exp ) { - if ( (exp == 0x7FF) && fracF64UI( uiA ) ) { - uiZ = softfloat_propagateNaNF64UI( uiA, 0 ); - goto uiZ; - } - return a; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ = uiA; - lastBitMask = (uint_fast64_t) 1<<(0x433 - exp); - roundBitsMask = lastBitMask - 1; - if ( roundingMode == softfloat_round_near_maxMag ) { - uiZ += lastBitMask>>1; - } else if ( roundingMode == softfloat_round_near_even ) { - uiZ += lastBitMask>>1; - if ( !(uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; - } else if ( - roundingMode - == (signF64UI( uiZ ) ? softfloat_round_min : softfloat_round_max) - ) { - uiZ += roundBitsMask; - } - uiZ &= ~roundBitsMask; - if ( uiZ != uiA ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) uiZ |= lastBitMask; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_sqrt.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_sqrt.c deleted file mode 100644 index f12acdb41..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_sqrt.c +++ /dev/null @@ -1,133 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f64_sqrt( float64_t a ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - int_fast16_t expA; - uint_fast64_t sigA, uiZ; - struct exp16_sig64 normExpSig; - int_fast16_t expZ; - uint32_t sig32A, recipSqrt32, sig32Z; - uint_fast64_t rem; - uint32_t q; - uint_fast64_t sigZ, shiftedSigZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FF ) { - if ( sigA ) { - uiZ = softfloat_propagateNaNF64UI( uiA, 0 ); - goto uiZ; - } - if ( ! signA ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signA ) { - if ( ! (expA | sigA) ) return a; - goto invalid; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - /*------------------------------------------------------------------------ - | (`sig32Z' is guaranteed to be a lower bound on the square root of - | `sig32A', which makes `sig32Z' also a lower bound on the square root of - | `sigA'.) - *------------------------------------------------------------------------*/ - expZ = ((expA - 0x3FF)>>1) + 0x3FE; - expA &= 1; - sigA |= UINT64_C( 0x0010000000000000 ); - sig32A = sigA>>21; - recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A ); - sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32; - if ( expA ) { - sigA <<= 8; - sig32Z >>= 1; - } else { - sigA <<= 9; - } - rem = sigA - (uint_fast64_t) sig32Z * sig32Z; - q = ((uint32_t) (rem>>2) * (uint_fast64_t) recipSqrt32)>>32; - sigZ = ((uint_fast64_t) sig32Z<<32 | 1<<5) + ((uint_fast64_t) q<<3); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (sigZ & 0x1FF) < 0x22 ) { - sigZ &= ~(uint_fast64_t) 0x3F; - shiftedSigZ = sigZ>>6; - rem = (sigA<<52) - shiftedSigZ * shiftedSigZ; - if ( rem & UINT64_C( 0x8000000000000000 ) ) { - --sigZ; - } else { - if ( rem ) sigZ |= 1; - } - } - return softfloat_roundPackToF64( 0, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_sub.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_sub.c deleted file mode 100644 index 74158bec1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_sub.c +++ /dev/null @@ -1,74 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t f64_sub( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signB; -#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) - float64_t (*magsFuncPtr)( uint_fast64_t, uint_fast64_t, bool ); -#endif - - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF64UI( uiB ); -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) - if ( signA == signB ) { - return softfloat_subMagsF64( uiA, uiB, signA ); - } else { - return softfloat_addMagsF64( uiA, uiB, signA ); - } -#else - magsFuncPtr = - (signA == signB) ? softfloat_subMagsF64 : softfloat_addMagsF64; - return (*magsFuncPtr)( uiA, uiB, signA ); -#endif - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_extF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_extF80.c deleted file mode 100644 index 553ebd0c5..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_extF80.c +++ /dev/null @@ -1,101 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t f64_to_extF80( float64_t a ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t frac; - struct commonNaN commonNaN; - struct uint128 uiZ; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - struct exp16_sig64 normExpSig; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - frac = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FF ) { - if ( frac ) { - softfloat_f64UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToExtF80UI( &commonNaN ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - } else { - uiZ64 = packToExtF80UI64( sign, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ64 = packToExtF80UI64( sign, 0 ); - uiZ0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF64Sig( frac ); - exp = normExpSig.exp; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = packToExtF80UI64( sign, exp + 0x3C00 ); - uiZ0 = (frac | UINT64_C( 0x0010000000000000 ))<<11; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_extF80M.c deleted file mode 100644 index d258bdc26..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_extF80M.c +++ /dev/null @@ -1,111 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f64_to_extF80M( float64_t a, extFloat80_t *zPtr ) -{ - - *zPtr = f64_to_extF80( a ); - -} - -#else - -void f64_to_extF80M( float64_t a, extFloat80_t *zPtr ) -{ - struct extFloat80M *zSPtr; - union ui64_f64 uA; - uint64_t uiA; - bool sign; - int_fast16_t exp; - uint64_t frac; - struct commonNaN commonNaN; - uint_fast16_t uiZ64; - uint64_t uiZ0; - struct exp16_sig64 normExpSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zSPtr = (struct extFloat80M *) zPtr; - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - frac = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FF ) { - if ( frac ) { - softfloat_f64UIToCommonNaN( uiA, &commonNaN ); - softfloat_commonNaNToExtF80M( &commonNaN, zSPtr ); - return; - } - uiZ64 = packToExtF80UI64( sign, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ64 = packToExtF80UI64( sign, 0 ); - uiZ0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF64Sig( frac ); - exp = normExpSig.exp; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ64 = packToExtF80UI64( sign, exp + 0x3C00 ); - uiZ0 = UINT64_C( 0x8000000000000000 ) | frac<<11; - uiZ: - zSPtr->signExp = uiZ64; - zSPtr->signif = uiZ0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f128.c deleted file mode 100644 index 8f03f2ff0..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f128.c +++ /dev/null @@ -1,98 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t f64_to_f128( float64_t a ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t frac; - struct commonNaN commonNaN; - struct uint128 uiZ; - struct exp16_sig64 normExpSig; - struct uint128 frac128; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - frac = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FF ) { - if ( frac ) { - softfloat_f64UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF128UI( &commonNaN ); - } else { - uiZ.v64 = packToF128UI64( sign, 0x7FFF, 0 ); - uiZ.v0 = 0; - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ.v64 = packToF128UI64( sign, 0, 0 ); - uiZ.v0 = 0; - goto uiZ; - } - normExpSig = softfloat_normSubnormalF64Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac128 = softfloat_shortShiftLeft128( 0, frac, 60 ); - uiZ.v64 = packToF128UI64( sign, exp + 0x3C00, frac128.v64 ); - uiZ.v0 = frac128.v0; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f128M.c deleted file mode 100644 index e4a862c7f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f128M.c +++ /dev/null @@ -1,117 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void f64_to_f128M( float64_t a, float128_t *zPtr ) -{ - - *zPtr = f64_to_f128( a ); - -} - -#else - -void f64_to_f128M( float64_t a, float128_t *zPtr ) -{ - uint32_t *zWPtr; - union ui64_f64 uA; - uint64_t uiA; - bool sign; - int_fast16_t exp; - uint64_t frac; - struct commonNaN commonNaN; - uint32_t uiZ96; - struct exp16_sig64 normExpSig; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zWPtr = (uint32_t *) zPtr; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - frac = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zWPtr[indexWord( 4, 0 )] = 0; - if ( exp == 0x7FF ) { - if ( frac ) { - softfloat_f64UIToCommonNaN( uiA, &commonNaN ); - softfloat_commonNaNToF128M( &commonNaN, zWPtr ); - return; - } - uiZ96 = packToF128UI96( sign, 0x7FFF, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! exp ) { - if ( ! frac ) { - uiZ96 = packToF128UI96( sign, 0, 0 ); - goto uiZ; - } - normExpSig = softfloat_normSubnormalF64Sig( frac ); - exp = normExpSig.exp - 1; - frac = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zWPtr[indexWord( 4, 1 )] = (uint32_t) frac<<28; - frac >>= 4; - zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, exp + 0x3C00, frac>>32 ); - zWPtr[indexWord( 4, 2 )] = frac; - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiZ: - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f16.c deleted file mode 100644 index 0cc6cc534..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f16.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t f64_to_f16( float64_t a ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t frac; - struct commonNaN commonNaN; - uint_fast16_t uiZ, frac16; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - frac = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FF ) { - if ( frac ) { - softfloat_f64UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF16UI( &commonNaN ); - } else { - uiZ = packToF16UI( sign, 0x1F, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac16 = softfloat_shortShiftRightJam64( frac, 38 ); - if ( ! (exp | frac16) ) { - uiZ = packToF16UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - return softfloat_roundPackToF16( sign, exp - 0x3F1, frac16 | 0x4000 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f32.c deleted file mode 100644 index 6074bb845..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_f32.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f64_to_f32( float64_t a ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t frac; - struct commonNaN commonNaN; - uint_fast32_t uiZ, frac32; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - frac = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp == 0x7FF ) { - if ( frac ) { - softfloat_f64UIToCommonNaN( uiA, &commonNaN ); - uiZ = softfloat_commonNaNToF32UI( &commonNaN ); - } else { - uiZ = packToF32UI( sign, 0xFF, 0 ); - } - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - frac32 = softfloat_shortShiftRightJam64( frac, 22 ); - if ( ! (exp | frac32) ) { - uiZ = packToF32UI( sign, 0, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - return softfloat_roundPackToF32( sign, exp - 0x381, frac32 | 0x40000000 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i32.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i32.c deleted file mode 100644 index 2cf260304..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i32.c +++ /dev/null @@ -1,82 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) - if ( (exp == 0x7FF) && sig ) { -#if (i32_fromNaN == i32_fromPosOverflow) - sign = 0; -#elif (i32_fromNaN == i32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return i32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftDist = 0x427 - exp; - if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); - return softfloat_roundToI32( sign, sig, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i32_r_minMag.c deleted file mode 100644 index 8cccb8efd..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i32_r_minMag.c +++ /dev/null @@ -1,96 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; - bool sign; - int_fast32_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x433 - exp; - if ( 53 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF64UI( uiA ); - if ( shiftDist < 22 ) { - if ( - sign && (exp == 0x41E) && (sig < UINT64_C( 0x0000000000200000 )) - ) { - if ( exact && sig ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return -0x7FFFFFFF - 1; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FF) && sig ? i32_fromNaN - : sign ? i32_fromNegOverflow : i32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig |= UINT64_C( 0x0010000000000000 ); - absZ = sig>>shiftDist; - if ( exact && ((uint_fast64_t) (uint_fast32_t) absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; -#ifdef SOFTFLOAT_FAST_INT64 - struct uint64_extra sigExtra; -#else - uint32_t extSig[3]; -#endif - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftDist = 0x433 - exp; -#ifdef SOFTFLOAT_FAST_INT64 - if ( shiftDist <= 0 ) { - if ( shiftDist < -11 ) goto invalid; - sigExtra.v = sig<<-shiftDist; - sigExtra.extra = 0; - } else { - sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); - } - return - softfloat_roundToI64( - sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); -#else - extSig[indexWord( 3, 0 )] = 0; - if ( shiftDist <= 0 ) { - if ( shiftDist < -11 ) goto invalid; - sig <<= -shiftDist; - extSig[indexWord( 3, 2 )] = sig>>32; - extSig[indexWord( 3, 1 )] = sig; - } else { - extSig[indexWord( 3, 2 )] = sig>>32; - extSig[indexWord( 3, 1 )] = sig; - softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - } - return softfloat_roundMToI64( sign, extSig, roundingMode, exact ); -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FF) && fracF64UI( uiA ) ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i64_r_minMag.c deleted file mode 100644 index 4fcc52c56..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_i64_r_minMag.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t f64_to_i64_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; - int_fast64_t absZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x433 - exp; - if ( shiftDist <= 0 ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( shiftDist < -10 ) { - if ( uiA == packToF64UI( 1, 0x43E, 0 ) ) { - return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FF) && sig ? i64_fromNaN - : sign ? i64_fromNegOverflow : i64_fromPosOverflow; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig |= UINT64_C( 0x0010000000000000 ); - absZ = sig<<-shiftDist; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( 53 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig |= UINT64_C( 0x0010000000000000 ); - absZ = sig>>shiftDist; - if ( exact && (absZ< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t f64_to_ui32( float64_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ -#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) - if ( (exp == 0x7FF) && sig ) { -#if (ui32_fromNaN == ui32_fromPosOverflow) - sign = 0; -#elif (ui32_fromNaN == ui32_fromNegOverflow) - sign = 1; -#else - softfloat_raiseFlags( softfloat_flag_invalid ); - return ui32_fromNaN; -#endif - } -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftDist = 0x427 - exp; - if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); - return softfloat_roundToUI32( sign, sig, roundingMode, exact ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_ui32_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_ui32_r_minMag.c deleted file mode 100644 index 01758dc54..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_ui32_r_minMag.c +++ /dev/null @@ -1,88 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t f64_to_ui32_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; - bool sign; - uint_fast32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x433 - exp; - if ( 53 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF64UI( uiA ); - if ( sign || (shiftDist < 21) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FF) && sig ? ui32_fromNaN - : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig |= UINT64_C( 0x0010000000000000 ); - z = sig>>shiftDist; - if ( exact && ((uint_fast64_t) z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; -#ifdef SOFTFLOAT_FAST_INT64 - struct uint64_extra sigExtra; -#else - uint32_t extSig[3]; -#endif - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftDist = 0x433 - exp; -#ifdef SOFTFLOAT_FAST_INT64 - if ( shiftDist <= 0 ) { - if ( shiftDist < -11 ) goto invalid; - sigExtra.v = sig<<-shiftDist; - sigExtra.extra = 0; - } else { - sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); - } - return - softfloat_roundToUI64( - sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); -#else - extSig[indexWord( 3, 0 )] = 0; - if ( shiftDist <= 0 ) { - if ( shiftDist < -11 ) goto invalid; - sig <<= -shiftDist; - extSig[indexWord( 3, 2 )] = sig>>32; - extSig[indexWord( 3, 1 )] = sig; - } else { - extSig[indexWord( 3, 2 )] = sig>>32; - extSig[indexWord( 3, 1 )] = sig; - softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); - } - return softfloat_roundMToUI64( sign, extSig, roundingMode, exact ); -#endif - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FF) && fracF64UI( uiA ) ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_ui64_r_minMag.c b/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_ui64_r_minMag.c deleted file mode 100644 index e1d81a018..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/f64_to_ui64_r_minMag.c +++ /dev/null @@ -1,93 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t f64_to_ui64_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftDist; - bool sign; - uint_fast64_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uA.f = a; - uiA = uA.ui; - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 0x433 - exp; - if ( 53 <= shiftDist ) { - if ( exact && (exp | sig) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sign = signF64UI( uiA ); - if ( sign ) goto invalid; - if ( shiftDist <= 0 ) { - if ( shiftDist < -11 ) goto invalid; - z = (sig | UINT64_C( 0x0010000000000000 ))<<-shiftDist; - } else { - sig |= UINT64_C( 0x0010000000000000 ); - z = sig>>shiftDist; - if ( exact && (uint64_t) (sig<<(-shiftDist & 63)) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - } - return z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return - (exp == 0x7FF) && sig ? ui64_fromNaN - : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_extF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_extF80.c deleted file mode 100644 index fd91cf059..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_extF80.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -extFloat80_t i32_to_extF80( int32_t a ) -{ - uint_fast16_t uiZ64; - uint_fast32_t absA; - bool sign; - int_fast8_t shiftDist; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - uiZ64 = 0; - absA = 0; - if ( a ) { - sign = (a < 0); - absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; - shiftDist = softfloat_countLeadingZeros32( absA ); - uiZ64 = packToExtF80UI64( sign, 0x401E - shiftDist ); - absA <<= shiftDist; - } - uZ.s.signExp = uiZ64; - uZ.s.signif = (uint_fast64_t) absA<<32; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_extF80M.c deleted file mode 100644 index d12e3a8ef..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_extF80M.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void i32_to_extF80M( int32_t a, extFloat80_t *zPtr ) -{ - - *zPtr = i32_to_extF80( a ); - -} - -#else - -void i32_to_extF80M( int32_t a, extFloat80_t *zPtr ) -{ - struct extFloat80M *zSPtr; - uint_fast16_t uiZ64; - uint64_t sigZ; - bool sign; - uint32_t absA; - int_fast8_t shiftDist; - - zSPtr = (struct extFloat80M *) zPtr; - uiZ64 = 0; - sigZ = 0; - if ( a ) { - sign = (a < 0); - absA = sign ? -(uint32_t) a : (uint32_t) a; - shiftDist = softfloat_countLeadingZeros32( absA ); - uiZ64 = packToExtF80UI64( sign, 0x401E - shiftDist ); - sigZ = (uint64_t) (absA<signExp = uiZ64; - zSPtr->signif = sigZ; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f128.c deleted file mode 100644 index 75575bddc..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f128.c +++ /dev/null @@ -1,64 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t i32_to_f128( int32_t a ) -{ - uint_fast64_t uiZ64; - bool sign; - uint_fast32_t absA; - int_fast8_t shiftDist; - union ui128_f128 uZ; - - uiZ64 = 0; - if ( a ) { - sign = (a < 0); - absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; - shiftDist = softfloat_countLeadingZeros32( absA ) + 17; - uiZ64 = - packToF128UI64( - sign, 0x402E - shiftDist, (uint_fast64_t) absA< -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void i32_to_f128M( int32_t a, float128_t *zPtr ) -{ - - *zPtr = i32_to_f128( a ); - -} - -#else - -void i32_to_f128M( int32_t a, float128_t *zPtr ) -{ - uint32_t *zWPtr; - uint32_t uiZ96, uiZ64; - bool sign; - uint32_t absA; - int_fast8_t shiftDist; - uint64_t normAbsA; - - zWPtr = (uint32_t *) zPtr; - uiZ96 = 0; - uiZ64 = 0; - if ( a ) { - sign = (a < 0); - absA = sign ? -(uint32_t) a : (uint32_t) a; - shiftDist = softfloat_countLeadingZeros32( absA ) + 17; - normAbsA = (uint64_t) absA<>32 ); - uiZ64 = normAbsA; - } - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = uiZ64; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f16.c deleted file mode 100644 index 14ac58860..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f16.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t i32_to_f16( int32_t a ) -{ - bool sign; - uint_fast32_t absA; - int_fast8_t shiftDist; - union ui16_f16 u; - uint_fast16_t sig; - - sign = (a < 0); - absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; - shiftDist = softfloat_countLeadingZeros32( absA ) - 21; - if ( 0 <= shiftDist ) { - u.ui = - a ? packToF16UI( - sign, 0x18 - shiftDist, (uint_fast16_t) absA<>(-shiftDist) - | ((uint32_t) (absA<<(shiftDist & 31)) != 0) - : (uint_fast16_t) absA< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t i32_to_f32( int32_t a ) -{ - bool sign; - union ui32_f32 uZ; - uint_fast32_t absA; - - sign = (a < 0); - if ( ! (a & 0x7FFFFFFF) ) { - uZ.ui = sign ? packToF32UI( 1, 0x9E, 0 ) : 0; - return uZ.f; - } - absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; - return softfloat_normRoundPackToF32( sign, 0x9C, absA ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f64.c deleted file mode 100644 index 64662bb22..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i32_to_f64.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t i32_to_f64( int32_t a ) -{ - uint_fast64_t uiZ; - bool sign; - uint_fast32_t absA; - int_fast8_t shiftDist; - union ui64_f64 uZ; - - if ( ! a ) { - uiZ = 0; - } else { - sign = (a < 0); - absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; - shiftDist = softfloat_countLeadingZeros32( absA ) + 21; - uiZ = - packToF64UI( - sign, 0x432 - shiftDist, (uint_fast64_t) absA< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -extFloat80_t i64_to_extF80( int64_t a ) -{ - uint_fast16_t uiZ64; - uint_fast64_t absA; - bool sign; - int_fast8_t shiftDist; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - uiZ64 = 0; - absA = 0; - if ( a ) { - sign = (a < 0); - absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; - shiftDist = softfloat_countLeadingZeros64( absA ); - uiZ64 = packToExtF80UI64( sign, 0x403E - shiftDist ); - absA <<= shiftDist; - } - uZ.s.signExp = uiZ64; - uZ.s.signif = absA; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_extF80M.c deleted file mode 100644 index 0bf67ff46..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_extF80M.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void i64_to_extF80M( int64_t a, extFloat80_t *zPtr ) -{ - - *zPtr = i64_to_extF80( a ); - -} - -#else - -void i64_to_extF80M( int64_t a, extFloat80_t *zPtr ) -{ - struct extFloat80M *zSPtr; - uint_fast16_t uiZ64; - uint64_t sigZ; - bool sign; - uint64_t absA; - int_fast8_t shiftDist; - - zSPtr = (struct extFloat80M *) zPtr; - uiZ64 = 0; - sigZ = 0; - if ( a ) { - sign = (a < 0); - absA = sign ? -(uint64_t) a : (uint64_t) a; - shiftDist = softfloat_countLeadingZeros64( absA ); - uiZ64 = packToExtF80UI64( sign, 0x403E - shiftDist ); - sigZ = absA<signExp = uiZ64; - zSPtr->signif = sigZ; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f128.c deleted file mode 100644 index a2b6dea88..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f128.c +++ /dev/null @@ -1,72 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t i64_to_f128( int64_t a ) -{ - uint_fast64_t uiZ64, uiZ0; - bool sign; - uint_fast64_t absA; - int_fast8_t shiftDist; - struct uint128 zSig; - union ui128_f128 uZ; - - if ( ! a ) { - uiZ64 = 0; - uiZ0 = 0; - } else { - sign = (a < 0); - absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; - shiftDist = softfloat_countLeadingZeros64( absA ) + 49; - if ( 64 <= shiftDist ) { - zSig.v64 = absA<<(shiftDist - 64); - zSig.v0 = 0; - } else { - zSig = softfloat_shortShiftLeft128( 0, absA, shiftDist ); - } - uiZ64 = packToF128UI64( sign, 0x406E - shiftDist, zSig.v64 ); - uiZ0 = zSig.v0; - } - uZ.ui.v64 = uiZ64; - uZ.ui.v0 = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f128M.c deleted file mode 100644 index 7b44ec7bd..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f128M.c +++ /dev/null @@ -1,92 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void i64_to_f128M( int64_t a, float128_t *zPtr ) -{ - - *zPtr = i64_to_f128( a ); - -} - -#else - -void i64_to_f128M( int64_t a, float128_t *zPtr ) -{ - uint32_t *zWPtr; - uint32_t uiZ96, uiZ64; - bool sign; - uint64_t absA; - uint_fast8_t shiftDist; - uint32_t *ptr; - - zWPtr = (uint32_t *) zPtr; - uiZ96 = 0; - uiZ64 = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - if ( a ) { - sign = (a < 0); - absA = sign ? -(uint64_t) a : (uint64_t) a; - shiftDist = softfloat_countLeadingZeros64( absA ) + 17; - if ( shiftDist < 32 ) { - ptr = zWPtr + indexMultiwordHi( 4, 3 ); - ptr[indexWord( 3, 2 )] = 0; - ptr[indexWord( 3, 1 )] = absA>>32; - ptr[indexWord( 3, 0 )] = absA; - softfloat_shortShiftLeft96M( ptr, shiftDist, ptr ); - ptr[indexWordHi( 3 )] = - packToF128UI96( - sign, 0x404E - shiftDist, ptr[indexWordHi( 3 )] ); - return; - } - absA <<= shiftDist - 32; - uiZ96 = packToF128UI96( sign, 0x404E - shiftDist, absA>>32 ); - uiZ64 = absA; - } - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = uiZ64; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f16.c deleted file mode 100644 index f16eccf04..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/i64_to_f16.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t i64_to_f16( int64_t a ) -{ - bool sign; - uint_fast64_t absA; - int_fast8_t shiftDist; - union ui16_f16 u; - uint_fast16_t sig; - - sign = (a < 0); - absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; - shiftDist = softfloat_countLeadingZeros64( absA ) - 53; - if ( 0 <= shiftDist ) { - u.ui = - a ? packToF16UI( - sign, 0x18 - shiftDist, (uint_fast16_t) absA< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t i64_to_f32( int64_t a ) -{ - bool sign; - uint_fast64_t absA; - int_fast8_t shiftDist; - union ui32_f32 u; - uint_fast32_t sig; - - sign = (a < 0); - absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; - shiftDist = softfloat_countLeadingZeros64( absA ) - 40; - if ( 0 <= shiftDist ) { - u.ui = - a ? packToF32UI( - sign, 0x95 - shiftDist, (uint_fast32_t) absA< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t i64_to_f64( int64_t a ) -{ - bool sign; - union ui64_f64 uZ; - uint_fast64_t absA; - - sign = (a < 0); - if ( ! (a & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) { - uZ.ui = sign ? packToF64UI( 1, 0x43E, 0 ) : 0; - return uZ.f; - } - absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; - return softfloat_normRoundPackToF64( sign, 0x43C, absA ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/include/internals.h b/source/src/vm/libcpu_newdev/softfloat3/source/include/internals.h deleted file mode 100644 index f8eac0530..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/include/internals.h +++ /dev/null @@ -1,278 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef internals_h -#define internals_h 1 - -#include -#include -#include "primitives.h" -#include "softfloat_types.h" - -union ui16_f16 { uint16_t ui; float16_t f; }; -union ui32_f32 { uint32_t ui; float32_t f; }; -union ui64_f64 { uint64_t ui; float64_t f; }; - -#ifdef SOFTFLOAT_FAST_INT64 -union extF80M_extF80 { struct extFloat80M fM; extFloat80_t f; }; -union ui128_f128 { struct uint128 ui; float128_t f; }; -#endif - -enum { - softfloat_mulAdd_subC = 1, - softfloat_mulAdd_subProd = 2 -}; - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_roundToUI32( bool, uint_fast64_t, uint_fast8_t, bool ); - -#ifdef SOFTFLOAT_FAST_INT64 -uint_fast64_t - softfloat_roundToUI64( - bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool ); -#else -uint_fast64_t softfloat_roundMToUI64( bool, uint32_t *, uint_fast8_t, bool ); -#endif - -int_fast32_t softfloat_roundToI32( bool, uint_fast64_t, uint_fast8_t, bool ); - -#ifdef SOFTFLOAT_FAST_INT64 -int_fast64_t - softfloat_roundToI64( - bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool ); -#else -int_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool ); -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define signF16UI( a ) ((bool) ((uint16_t) (a)>>15)) -#define expF16UI( a ) ((int_fast8_t) ((a)>>10) & 0x1F) -#define fracF16UI( a ) ((a) & 0x03FF) -#define packToF16UI( sign, exp, sig ) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig)) - -#define isNaNF16UI( a ) (((~(a) & 0x7C00) == 0) && ((a) & 0x03FF)) - -struct exp8_sig16 { int_fast8_t exp; uint_fast16_t sig; }; -struct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t ); - -float16_t softfloat_roundPackToF16( bool, int_fast16_t, uint_fast16_t ); -float16_t softfloat_normRoundPackToF16( bool, int_fast16_t, uint_fast16_t ); - -float16_t softfloat_addMagsF16( uint_fast16_t, uint_fast16_t ); -float16_t softfloat_subMagsF16( uint_fast16_t, uint_fast16_t ); -float16_t - softfloat_mulAddF16( - uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t ); - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define signF32UI( a ) ((bool) ((uint32_t) (a)>>31)) -#define expF32UI( a ) ((int_fast16_t) ((a)>>23) & 0xFF) -#define fracF32UI( a ) ((a) & 0x007FFFFF) -#define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig)) - -#define isNaNF32UI( a ) (((~(a) & 0x7F800000) == 0) && ((a) & 0x007FFFFF)) - -struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; }; -struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t ); - -float32_t softfloat_roundPackToF32( bool, int_fast16_t, uint_fast32_t ); -float32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t ); - -float32_t softfloat_addMagsF32( uint_fast32_t, uint_fast32_t ); -float32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t ); -float32_t - softfloat_mulAddF32( - uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t ); - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define signF64UI( a ) ((bool) ((uint64_t) (a)>>63)) -#define expF64UI( a ) ((int_fast16_t) ((a)>>52) & 0x7FF) -#define fracF64UI( a ) ((a) & UINT64_C( 0x000FFFFFFFFFFFFF )) -#define packToF64UI( sign, exp, sig ) ((uint64_t) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<52) + (sig))) - -#define isNaNF64UI( a ) (((~(a) & UINT64_C( 0x7FF0000000000000 )) == 0) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))) - -struct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; }; -struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t ); - -float64_t softfloat_roundPackToF64( bool, int_fast16_t, uint_fast64_t ); -float64_t softfloat_normRoundPackToF64( bool, int_fast16_t, uint_fast64_t ); - -float64_t softfloat_addMagsF64( uint_fast64_t, uint_fast64_t, bool ); -float64_t softfloat_subMagsF64( uint_fast64_t, uint_fast64_t, bool ); -float64_t - softfloat_mulAddF64( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define signExtF80UI64( a64 ) ((bool) ((uint16_t) (a64)>>15)) -#define expExtF80UI64( a64 ) ((a64) & 0x7FFF) -#define packToExtF80UI64( sign, exp ) ((uint_fast16_t) (sign)<<15 | (exp)) - -#define isNaNExtF80UI( a64, a0 ) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) - -#ifdef SOFTFLOAT_FAST_INT64 - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ - -struct exp32_sig64 { int_fast32_t exp; uint64_t sig; }; -struct exp32_sig64 softfloat_normSubnormalExtF80Sig( uint_fast64_t ); - -extFloat80_t - softfloat_roundPackToExtF80( - bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); -extFloat80_t - softfloat_normRoundPackToExtF80( - bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); - -extFloat80_t - softfloat_addMagsExtF80( - uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); -extFloat80_t - softfloat_subMagsExtF80( - uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define signF128UI64( a64 ) ((bool) ((uint64_t) (a64)>>63)) -#define expF128UI64( a64 ) ((int_fast32_t) ((a64)>>48) & 0x7FFF) -#define fracF128UI64( a64 ) ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )) -#define packToF128UI64( sign, exp, sig64 ) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<48) + (sig64)) - -#define isNaNF128UI( a64, a0 ) (((~(a64) & UINT64_C( 0x7FFF000000000000 )) == 0) && (a0 || ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )))) - -struct exp32_sig128 { int_fast32_t exp; struct uint128 sig; }; -struct exp32_sig128 - softfloat_normSubnormalF128Sig( uint_fast64_t, uint_fast64_t ); - -float128_t - softfloat_roundPackToF128( - bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast64_t ); -float128_t - softfloat_normRoundPackToF128( - bool, int_fast32_t, uint_fast64_t, uint_fast64_t ); - -float128_t - softfloat_addMagsF128( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); -float128_t - softfloat_subMagsF128( - uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); -float128_t - softfloat_mulAddF128( - uint_fast64_t, - uint_fast64_t, - uint_fast64_t, - uint_fast64_t, - uint_fast64_t, - uint_fast64_t, - uint_fast8_t - ); - -#else - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ - -bool - softfloat_tryPropagateNaNExtF80M( - const struct extFloat80M *, - const struct extFloat80M *, - struct extFloat80M * - ); -void softfloat_invalidExtF80M( struct extFloat80M * ); - -int softfloat_normExtF80SigM( uint64_t * ); - -void - softfloat_roundPackMToExtF80M( - bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * ); -void - softfloat_normRoundPackMToExtF80M( - bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * ); - -void - softfloat_addExtF80M( - const struct extFloat80M *, - const struct extFloat80M *, - struct extFloat80M *, - bool - ); - -int - softfloat_compareNonnormExtF80M( - const struct extFloat80M *, const struct extFloat80M * ); - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define signF128UI96( a96 ) ((bool) ((uint32_t) (a96)>>31)) -#define expF128UI96( a96 ) ((int32_t) ((a96)>>16) & 0x7FFF) -#define fracF128UI96( a96 ) ((a96) & 0x0000FFFF) -#define packToF128UI96( sign, exp, sig96 ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<16) + (sig96)) - -bool softfloat_isNaNF128M( const uint32_t * ); - -bool - softfloat_tryPropagateNaNF128M( - const uint32_t *, const uint32_t *, uint32_t * ); -void softfloat_invalidF128M( uint32_t * ); - -int softfloat_shiftNormSigF128M( const uint32_t *, uint_fast8_t, uint32_t * ); - -void softfloat_roundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * ); -void softfloat_normRoundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * ); - -void - softfloat_addF128M( const uint32_t *, const uint32_t *, uint32_t *, bool ); -void - softfloat_mulAddF128M( - const uint32_t *, - const uint32_t *, - const uint32_t *, - uint32_t *, - uint_fast8_t - ); - -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/include/opts-GCC.h b/source/src/vm/libcpu_newdev/softfloat3/source/include/opts-GCC.h deleted file mode 100644 index 192cb58ca..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/include/opts-GCC.h +++ /dev/null @@ -1,114 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2017 The Regents of the University of California. All rights -reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef opts_GCC_h -#define opts_GCC_h 1 - -#ifdef INLINE - -#include -#include "primitiveTypes.h" - -#ifdef SOFTFLOAT_BUILTIN_CLZ - -INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ) - { return a ? __builtin_clz( a ) - 16 : 16; } -#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16 - -INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) - { return a ? __builtin_clz( a ) : 32; } -#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32 - -INLINE uint_fast8_t softfloat_countLeadingZeros64( uint64_t a ) - { return a ? __builtin_clzll( a ) : 64; } -#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64 - -#endif - -#ifdef SOFTFLOAT_INTRINSIC_INT128 - -INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) -{ - union { unsigned __int128 ui; struct uint128 s; } uZ; - uZ.ui = (unsigned __int128) a * ((uint_fast64_t) b<<32); - return uZ.s; -} -#define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128 - -INLINE struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ) -{ - union { unsigned __int128 ui; struct uint128 s; } uZ; - uZ.ui = (unsigned __int128) a * b; - return uZ.s; -} -#define softfloat_mul64To128 softfloat_mul64To128 - -INLINE -struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) -{ - union { unsigned __int128 ui; struct uint128 s; } uZ; - uZ.ui = ((unsigned __int128) a64<<64 | a0) * b; - return uZ.s; -} -#define softfloat_mul128By32 softfloat_mul128By32 - -INLINE -void - softfloat_mul128To256M( - uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr ) -{ - unsigned __int128 z0, mid1, mid, z128; - z0 = (unsigned __int128) a0 * b0; - mid1 = (unsigned __int128) a64 * b0; - mid = mid1 + (unsigned __int128) a0 * b64; - z128 = (unsigned __int128) a64 * b64; - z128 += (unsigned __int128) (mid < mid1)<<64 | mid>>64; - mid <<= 64; - z0 += mid; - z128 += (z0 < mid); - zPtr[indexWord( 4, 0 )] = z0; - zPtr[indexWord( 4, 1 )] = z0>>64; - zPtr[indexWord( 4, 2 )] = z128; - zPtr[indexWord( 4, 3 )] = z128>>64; -} -#define softfloat_mul128To256M softfloat_mul128To256M - -#endif - -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/include/primitiveTypes.h b/source/src/vm/libcpu_newdev/softfloat3/source/include/primitiveTypes.h deleted file mode 100644 index e30540068..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/include/primitiveTypes.h +++ /dev/null @@ -1,85 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef primitiveTypes_h -#define primitiveTypes_h 1 - -#include - -#ifdef SOFTFLOAT_FAST_INT64 - -#ifdef LITTLEENDIAN -struct uint128 { uint64_t v0, v64; }; -struct uint64_extra { uint64_t extra, v; }; -struct uint128_extra { uint64_t extra; struct uint128 v; }; -#else -struct uint128 { uint64_t v64, v0; }; -struct uint64_extra { uint64_t v, extra; }; -struct uint128_extra { struct uint128 v; uint64_t extra; }; -#endif - -#endif - -/*---------------------------------------------------------------------------- -| These macros are used to isolate the differences in word order between big- -| endian and little-endian platforms. -*----------------------------------------------------------------------------*/ -#ifdef LITTLEENDIAN -#define wordIncr 1 -#define indexWord( total, n ) (n) -#define indexWordHi( total ) ((total) - 1) -#define indexWordLo( total ) 0 -#define indexMultiword( total, m, n ) (n) -#define indexMultiwordHi( total, n ) ((total) - (n)) -#define indexMultiwordLo( total, n ) 0 -#define indexMultiwordHiBut( total, n ) (n) -#define indexMultiwordLoBut( total, n ) 0 -#define INIT_UINTM4( v3, v2, v1, v0 ) { v0, v1, v2, v3 } -#else -#define wordIncr -1 -#define indexWord( total, n ) ((total) - 1 - (n)) -#define indexWordHi( total ) 0 -#define indexWordLo( total ) ((total) - 1) -#define indexMultiword( total, m, n ) ((total) - 1 - (m)) -#define indexMultiwordHi( total, n ) 0 -#define indexMultiwordLo( total, n ) ((total) - (n)) -#define indexMultiwordHiBut( total, n ) 0 -#define indexMultiwordLoBut( total, n ) (n) -#define INIT_UINTM4( v3, v2, v1, v0 ) { v3, v2, v1, v0 } -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/include/primitives.h b/source/src/vm/libcpu_newdev/softfloat3/source/include/primitives.h deleted file mode 100644 index 10847817a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/include/primitives.h +++ /dev/null @@ -1,1160 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef primitives_h -#define primitives_h 1 - -#include -#include -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRightJam64 -/*---------------------------------------------------------------------------- -| Shifts 'a' right by the number of bits given in 'dist', which must be in -| the range 1 to 63. If any nonzero bits are shifted off, they are "jammed" -| into the least-significant bit of the shifted value by setting the least- -| significant bit to 1. This shifted-and-jammed value is returned. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist ) - { return a>>dist | ((a & (((uint_fast64_t) 1<>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0); -} -#else -uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist ); -#endif -#endif - -#ifndef softfloat_shiftRightJam64 -/*---------------------------------------------------------------------------- -| Shifts 'a' right by the number of bits given in 'dist', which must not -| be zero. If any nonzero bits are shifted off, they are "jammed" into the -| least-significant bit of the shifted value by setting the least-significant -| bit to 1. This shifted-and-jammed value is returned. -| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is -| greater than 64, the result will be either 0 or 1, depending on whether 'a' -| is zero or nonzero. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) -INLINE uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ) -{ - return - (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0); -} -#else -uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ); -#endif -#endif - -/*---------------------------------------------------------------------------- -| A constant table that translates an 8-bit unsigned integer (the array index) -| into the number of leading 0 bits before the most-significant 1 of that -| integer. For integer zero (index 0), the corresponding table element is 8. -*----------------------------------------------------------------------------*/ -extern const uint_least8_t softfloat_countLeadingZeros8[256]; - -#ifndef softfloat_countLeadingZeros16 -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| 'a'. If 'a' is zero, 16 is returned. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ) -{ - uint_fast8_t count = 8; - if ( 0x100 <= a ) { - count = 0; - a >>= 8; - } - count += softfloat_countLeadingZeros8[a]; - return count; -} -#else -uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ); -#endif -#endif - -#ifndef softfloat_countLeadingZeros32 -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| 'a'. If 'a' is zero, 32 is returned. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) -INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) -{ - uint_fast8_t count = 0; - if ( a < 0x10000 ) { - count = 16; - a <<= 16; - } - if ( a < 0x1000000 ) { - count += 8; - a <<= 8; - } - count += softfloat_countLeadingZeros8[a>>24]; - return count; -} -#else -uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ); -#endif -#endif - -#ifndef softfloat_countLeadingZeros64 -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| 'a'. If 'a' is zero, 64 is returned. -*----------------------------------------------------------------------------*/ -uint_fast8_t softfloat_countLeadingZeros64( uint64_t a ); -#endif - -extern const uint16_t softfloat_approxRecip_1k0s[16]; -extern const uint16_t softfloat_approxRecip_1k1s[16]; - -#ifndef softfloat_approxRecip32_1 -/*---------------------------------------------------------------------------- -| Returns an approximation to the reciprocal of the number represented by 'a', -| where 'a' is interpreted as an unsigned fixed-point number with one integer -| bit and 31 fraction bits. The 'a' input must be "normalized", meaning that -| its most-significant bit (bit 31) must be 1. Thus, if A is the value of -| the fixed-point interpretation of 'a', then 1 <= A < 2. The returned value -| is interpreted as a pure unsigned fraction, having no integer bits and 32 -| fraction bits. The approximation returned is never greater than the true -| reciprocal 1/A, and it differs from the true reciprocal by at most 2.006 ulp -| (units in the last place). -*----------------------------------------------------------------------------*/ -#ifdef SOFTFLOAT_FAST_DIV64TO32 -#define softfloat_approxRecip32_1( a ) ((uint32_t) (UINT64_C( 0x7FFFFFFFFFFFFFFF ) / (uint32_t) (a))) -#else -uint32_t softfloat_approxRecip32_1( uint32_t a ); -#endif -#endif - -extern const uint16_t softfloat_approxRecipSqrt_1k0s[16]; -extern const uint16_t softfloat_approxRecipSqrt_1k1s[16]; - -#ifndef softfloat_approxRecipSqrt32_1 -/*---------------------------------------------------------------------------- -| Returns an approximation to the reciprocal of the square root of the number -| represented by 'a', where 'a' is interpreted as an unsigned fixed-point -| number either with one integer bit and 31 fraction bits or with two integer -| bits and 30 fraction bits. The format of 'a' is determined by 'oddExpA', -| which must be either 0 or 1. If 'oddExpA' is 1, 'a' is interpreted as -| having one integer bit, and if 'oddExpA' is 0, 'a' is interpreted as having -| two integer bits. The 'a' input must be "normalized", meaning that its -| most-significant bit (bit 31) must be 1. Thus, if A is the value of the -| fixed-point interpretation of 'a', it follows that 1 <= A < 2 when 'oddExpA' -| is 1, and 2 <= A < 4 when 'oddExpA' is 0. -| The returned value is interpreted as a pure unsigned fraction, having -| no integer bits and 32 fraction bits. The approximation returned is never -| greater than the true reciprocal 1/sqrt(A), and it differs from the true -| reciprocal by at most 2.06 ulp (units in the last place). The approximation -| returned is also always within the range 0.5 to 1; thus, the most- -| significant bit of the result is always set. -*----------------------------------------------------------------------------*/ -uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a ); -#endif - -#ifdef SOFTFLOAT_FAST_INT64 - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is -| defined. -*----------------------------------------------------------------------------*/ - -#ifndef softfloat_eq128 -/*---------------------------------------------------------------------------- -| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' -| and 'a0' is equal to the 128-bit unsigned integer formed by concatenating -| 'b64' and 'b0'. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) -INLINE -bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) - { return (a64 == b64) && (a0 == b0); } -#else -bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); -#endif -#endif - -#ifndef softfloat_le128 -/*---------------------------------------------------------------------------- -| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' -| and 'a0' is less than or equal to the 128-bit unsigned integer formed by -| concatenating 'b64' and 'b0'. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) - { return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); } -#else -bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); -#endif -#endif - -#ifndef softfloat_lt128 -/*---------------------------------------------------------------------------- -| Returns true if the 128-bit unsigned integer formed by concatenating 'a64' -| and 'a0' is less than the 128-bit unsigned integer formed by concatenating -| 'b64' and 'b0'. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) - { return (a64 < b64) || ((a64 == b64) && (a0 < b0)); } -#else -bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); -#endif -#endif - -#ifndef softfloat_shortShiftLeft128 -/*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating 'a64' and 'a0' left by the -| number of bits given in 'dist', which must be in the range 1 to 63. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -struct uint128 - softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist ) -{ - struct uint128 z; - z.v64 = a64<>(-dist & 63); - z.v0 = a0<>dist; - z.v0 = a64<<(-dist & 63) | a0>>dist; - return z; -} -#else -struct uint128 - softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist ); -#endif -#endif - -#ifndef softfloat_shortShiftRightJam64Extra -/*---------------------------------------------------------------------------- -| This function is the same as 'softfloat_shiftRightJam64Extra' (below), -| except that 'dist' must be in the range 1 to 63. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -struct uint64_extra - softfloat_shortShiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast8_t dist ) -{ - struct uint64_extra z; - z.v = a>>dist; - z.extra = a<<(-dist & 63) | (extra != 0); - return z; -} -#else -struct uint64_extra - softfloat_shortShiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast8_t dist ); -#endif -#endif - -#ifndef softfloat_shortShiftRightJam128 -/*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the -| number of bits given in 'dist', which must be in the range 1 to 63. If any -| nonzero bits are shifted off, they are "jammed" into the least-significant -| bit of the shifted value by setting the least-significant bit to 1. This -| shifted-and-jammed value is returned. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) -INLINE -struct uint128 - softfloat_shortShiftRightJam128( - uint64_t a64, uint64_t a0, uint_fast8_t dist ) -{ - uint_fast8_t negDist = -dist; - struct uint128 z; - z.v64 = a64>>dist; - z.v0 = - a64<<(negDist & 63) | a0>>dist - | ((uint64_t) (a0<<(negDist & 63)) != 0); - return z; -} -#else -struct uint128 - softfloat_shortShiftRightJam128( - uint64_t a64, uint64_t a0, uint_fast8_t dist ); -#endif -#endif - -#ifndef softfloat_shortShiftRightJam128Extra -/*---------------------------------------------------------------------------- -| This function is the same as 'softfloat_shiftRightJam128Extra' (below), -| except that 'dist' must be in the range 1 to 63. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) -INLINE -struct uint128_extra - softfloat_shortShiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist ) -{ - uint_fast8_t negDist = -dist; - struct uint128_extra z; - z.v.v64 = a64>>dist; - z.v.v0 = a64<<(negDist & 63) | a0>>dist; - z.extra = a0<<(negDist & 63) | (extra != 0); - return z; -} -#else -struct uint128_extra - softfloat_shortShiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist ); -#endif -#endif - -#ifndef softfloat_shiftRightJam64Extra -/*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating 'a' and 'extra' right by 64 -| _plus_ the number of bits given in 'dist', which must not be zero. This -| shifted value is at most 64 nonzero bits and is returned in the 'v' field -| of the 'struct uint64_extra' result. The 64-bit 'extra' field of the result -| contains a value formed as follows from the bits that were shifted off: The -| _last_ bit shifted off is the most-significant bit of the 'extra' field, and -| the other 63 bits of the 'extra' field are all zero if and only if _all_but_ -| _the_last_ bits shifted off were all zero. -| (This function makes more sense if 'a' and 'extra' are considered to form -| an unsigned fixed-point number with binary point between 'a' and 'extra'. -| This fixed-point value is shifted right by the number of bits given in -| 'dist', and the integer part of this shifted value is returned in the 'v' -| field of the result. The fractional part of the shifted value is modified -| as described above and returned in the 'extra' field of the result.) -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) -INLINE -struct uint64_extra - softfloat_shiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast32_t dist ) -{ - struct uint64_extra z; - if ( dist < 64 ) { - z.v = a>>dist; - z.extra = a<<(-dist & 63); - } else { - z.v = 0; - z.extra = (dist == 64) ? a : (a != 0); - } - z.extra |= (extra != 0); - return z; -} -#else -struct uint64_extra - softfloat_shiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast32_t dist ); -#endif -#endif - -#ifndef softfloat_shiftRightJam128 -/*---------------------------------------------------------------------------- -| Shifts the 128 bits formed by concatenating 'a64' and 'a0' right by the -| number of bits given in 'dist', which must not be zero. If any nonzero bits -| are shifted off, they are "jammed" into the least-significant bit of the -| shifted value by setting the least-significant bit to 1. This shifted-and- -| jammed value is returned. -| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is -| greater than 128, the result will be either 0 or 1, depending on whether the -| original 128 bits are all zeros. -*----------------------------------------------------------------------------*/ -struct uint128 - softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist ); -#endif - -#ifndef softfloat_shiftRightJam128Extra -/*---------------------------------------------------------------------------- -| Shifts the 192 bits formed by concatenating 'a64', 'a0', and 'extra' right -| by 64 _plus_ the number of bits given in 'dist', which must not be zero. -| This shifted value is at most 128 nonzero bits and is returned in the 'v' -| field of the 'struct uint128_extra' result. The 64-bit 'extra' field of the -| result contains a value formed as follows from the bits that were shifted -| off: The _last_ bit shifted off is the most-significant bit of the 'extra' -| field, and the other 63 bits of the 'extra' field are all zero if and only -| if _all_but_the_last_ bits shifted off were all zero. -| (This function makes more sense if 'a64', 'a0', and 'extra' are considered -| to form an unsigned fixed-point number with binary point between 'a0' and -| 'extra'. This fixed-point value is shifted right by the number of bits -| given in 'dist', and the integer part of this shifted value is returned -| in the 'v' field of the result. The fractional part of the shifted value -| is modified as described above and returned in the 'extra' field of the -| result.) -*----------------------------------------------------------------------------*/ -struct uint128_extra - softfloat_shiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist ); -#endif - -#ifndef softfloat_shiftRightJam256M -/*---------------------------------------------------------------------------- -| Shifts the 256-bit unsigned integer pointed to by 'aPtr' right by the number -| of bits given in 'dist', which must not be zero. If any nonzero bits are -| shifted off, they are "jammed" into the least-significant bit of the shifted -| value by setting the least-significant bit to 1. This shifted-and-jammed -| value is stored at the location pointed to by 'zPtr'. Each of 'aPtr' and -| 'zPtr' points to an array of four 64-bit elements that concatenate in the -| platform's normal endian order to form a 256-bit integer. -| The value of 'dist' can be arbitrarily large. In particular, if 'dist' -| is greater than 256, the stored result will be either 0 or 1, depending on -| whether the original 256 bits are all zeros. -*----------------------------------------------------------------------------*/ -void - softfloat_shiftRightJam256M( - const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr ); -#endif - -#ifndef softfloat_add128 -/*---------------------------------------------------------------------------- -| Returns the sum of the 128-bit integer formed by concatenating 'a64' and -| 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. The -| addition is modulo 2^128, so any carry out is lost. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -struct uint128 - softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - struct uint128 z; - z.v0 = a0 + b0; - z.v64 = a64 + b64 + (z.v0 < a0); - return z; -} -#else -struct uint128 - softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); -#endif -#endif - -#ifndef softfloat_add256M -/*---------------------------------------------------------------------------- -| Adds the two 256-bit integers pointed to by 'aPtr' and 'bPtr'. The addition -| is modulo 2^256, so any carry out is lost. The sum is stored at the -| location pointed to by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to -| an array of four 64-bit elements that concatenate in the platform's normal -| endian order to form a 256-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_add256M( - const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ); -#endif - -#ifndef softfloat_sub128 -/*---------------------------------------------------------------------------- -| Returns the difference of the 128-bit integer formed by concatenating 'a64' -| and 'a0' and the 128-bit integer formed by concatenating 'b64' and 'b0'. -| The subtraction is modulo 2^128, so any borrow out (carry out) is lost. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -struct uint128 - softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - struct uint128 z; - z.v0 = a0 - b0; - z.v64 = a64 - b64; - z.v64 -= (a0 < b0); - return z; -} -#else -struct uint128 - softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); -#endif -#endif - -#ifndef softfloat_sub256M -/*---------------------------------------------------------------------------- -| Subtracts the 256-bit integer pointed to by 'bPtr' from the 256-bit integer -| pointed to by 'aPtr'. The addition is modulo 2^256, so any borrow out -| (carry out) is lost. The difference is stored at the location pointed to -| by 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to an array of four -| 64-bit elements that concatenate in the platform's normal endian order to -| form a 256-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_sub256M( - const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ); -#endif - -#ifndef softfloat_mul64ByShifted32To128 -/*---------------------------------------------------------------------------- -| Returns the 128-bit product of 'a', 'b', and 2^32. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) -INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) -{ - uint_fast64_t mid; - struct uint128 z; - mid = (uint_fast64_t) (uint32_t) a * b; - z.v0 = mid<<32; - z.v64 = (uint_fast64_t) (uint32_t) (a>>32) * b + (mid>>32); - return z; -} -#else -struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ); -#endif -#endif - -#ifndef softfloat_mul64To128 -/*---------------------------------------------------------------------------- -| Returns the 128-bit product of 'a' and 'b'. -*----------------------------------------------------------------------------*/ -struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ); -#endif - -#ifndef softfloat_mul128By32 -/*---------------------------------------------------------------------------- -| Returns the product of the 128-bit integer formed by concatenating 'a64' and -| 'a0', multiplied by 'b'. The multiplication is modulo 2^128; any overflow -| bits are discarded. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) -INLINE -struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) -{ - struct uint128 z; - uint_fast64_t mid; - uint_fast32_t carry; - z.v0 = a0 * b; - mid = (uint_fast64_t) (uint32_t) (a0>>32) * b; - carry = (uint32_t) ((uint_fast32_t) (z.v0>>32) - (uint_fast32_t) mid); - z.v64 = a64 * b + (uint_fast32_t) ((mid + carry)>>32); - return z; -} -#else -struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ); -#endif -#endif - -#ifndef softfloat_mul128To256M -/*---------------------------------------------------------------------------- -| Multiplies the 128-bit unsigned integer formed by concatenating 'a64' and -| 'a0' by the 128-bit unsigned integer formed by concatenating 'b64' and -| 'b0'. The 256-bit product is stored at the location pointed to by 'zPtr'. -| Argument 'zPtr' points to an array of four 64-bit elements that concatenate -| in the platform's normal endian order to form a 256-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_mul128To256M( - uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr ); -#endif - -#else - -/*---------------------------------------------------------------------------- -| The following functions are needed only when 'SOFTFLOAT_FAST_INT64' is not -| defined. -*----------------------------------------------------------------------------*/ - -#ifndef softfloat_compare96M -/*---------------------------------------------------------------------------- -| Compares the two 96-bit unsigned integers pointed to by 'aPtr' and 'bPtr'. -| Returns -1 if the first integer (A) is less than the second (B); returns 0 -| if the two integers are equal; and returns +1 if the first integer (A) -| is greater than the second (B). (The result is thus the signum of A - B.) -| Each of 'aPtr' and 'bPtr' points to an array of three 32-bit elements that -| concatenate in the platform's normal endian order to form a 96-bit integer. -*----------------------------------------------------------------------------*/ -int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr ); -#endif - -#ifndef softfloat_compare128M -/*---------------------------------------------------------------------------- -| Compares the two 128-bit unsigned integers pointed to by 'aPtr' and 'bPtr'. -| Returns -1 if the first integer (A) is less than the second (B); returns 0 -| if the two integers are equal; and returns +1 if the first integer (A) -| is greater than the second (B). (The result is thus the signum of A - B.) -| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that -| concatenate in the platform's normal endian order to form a 128-bit integer. -*----------------------------------------------------------------------------*/ -int_fast8_t - softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr ); -#endif - -#ifndef softfloat_shortShiftLeft64To96M -/*---------------------------------------------------------------------------- -| Extends 'a' to 96 bits and shifts the value left by the number of bits given -| in 'dist', which must be in the range 1 to 31. The result is stored at the -| location pointed to by 'zPtr'. Argument 'zPtr' points to an array of three -| 32-bit elements that concatenate in the platform's normal endian order to -| form a 96-bit integer. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) -INLINE -void - softfloat_shortShiftLeft64To96M( - uint64_t a, uint_fast8_t dist, uint32_t *zPtr ) -{ - zPtr[indexWord( 3, 0 )] = (uint32_t) a<>= 32 - dist; - zPtr[indexWord( 3, 2 )] = a>>32; - zPtr[indexWord( 3, 1 )] = a; -} -#else -void - softfloat_shortShiftLeft64To96M( - uint64_t a, uint_fast8_t dist, uint32_t *zPtr ); -#endif -#endif - -#ifndef softfloat_shortShiftLeftM -/*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by 'aPtr' left by the number -| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' -| must be in the range 1 to 31. Any nonzero bits shifted off are lost. The -| shifted N-bit result is stored at the location pointed to by 'zPtr'. Each -| of 'aPtr' and 'zPtr' points to a 'size_words'-long array of 32-bit elements -| that concatenate in the platform's normal endian order to form an N-bit -| integer. -*----------------------------------------------------------------------------*/ -void - softfloat_shortShiftLeftM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t dist, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_shortShiftLeft96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shortShiftLeftM' with -| 'size_words' = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_shortShiftLeft96M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 3, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shortShiftLeft128M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shortShiftLeftM' with -| 'size_words' = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_shortShiftLeft128M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 4, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shortShiftLeft160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shortShiftLeftM' with -| 'size_words' = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_shortShiftLeft160M( aPtr, dist, zPtr ) softfloat_shortShiftLeftM( 5, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shiftLeftM -/*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by 'aPtr' left by the number -| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' -| must not be zero. Any nonzero bits shifted off are lost. The shifted -| N-bit result is stored at the location pointed to by 'zPtr'. Each of 'aPtr' -| and 'zPtr' points to a 'size_words'-long array of 32-bit elements that -| concatenate in the platform's normal endian order to form an N-bit integer. -| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is -| greater than N, the stored result will be 0. -*----------------------------------------------------------------------------*/ -void - softfloat_shiftLeftM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint32_t dist, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_shiftLeft96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shiftLeftM' with -| 'size_words' = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_shiftLeft96M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 3, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shiftLeft128M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shiftLeftM' with -| 'size_words' = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_shiftLeft128M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 4, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shiftLeft160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shiftLeftM' with -| 'size_words' = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_shiftLeft160M( aPtr, dist, zPtr ) softfloat_shiftLeftM( 5, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shortShiftRightM -/*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number -| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' -| must be in the range 1 to 31. Any nonzero bits shifted off are lost. The -| shifted N-bit result is stored at the location pointed to by 'zPtr'. Each -| of 'aPtr' and 'zPtr' points to a 'size_words'-long array of 32-bit elements -| that concatenate in the platform's normal endian order to form an N-bit -| integer. -*----------------------------------------------------------------------------*/ -void - softfloat_shortShiftRightM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t dist, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_shortShiftRight128M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shortShiftRightM' with -| 'size_words' = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_shortShiftRight128M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 4, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shortShiftRight160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shortShiftRightM' with -| 'size_words' = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_shortShiftRight160M( aPtr, dist, zPtr ) softfloat_shortShiftRightM( 5, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shortShiftRightJamM -/*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number -| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' -| must be in the range 1 to 31. If any nonzero bits are shifted off, they are -| "jammed" into the least-significant bit of the shifted value by setting the -| least-significant bit to 1. This shifted-and-jammed N-bit result is stored -| at the location pointed to by 'zPtr'. Each of 'aPtr' and 'zPtr' points -| to a 'size_words'-long array of 32-bit elements that concatenate in the -| platform's normal endian order to form an N-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_shortShiftRightJamM( - uint_fast8_t, const uint32_t *, uint_fast8_t, uint32_t * ); -#endif - -#ifndef softfloat_shortShiftRightJam160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shortShiftRightJamM' with -| 'size_words' = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_shortShiftRightJam160M( aPtr, dist, zPtr ) softfloat_shortShiftRightJamM( 5, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shiftRightM -/*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number -| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' -| must not be zero. Any nonzero bits shifted off are lost. The shifted -| N-bit result is stored at the location pointed to by 'zPtr'. Each of 'aPtr' -| and 'zPtr' points to a 'size_words'-long array of 32-bit elements that -| concatenate in the platform's normal endian order to form an N-bit integer. -| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is -| greater than N, the stored result will be 0. -*----------------------------------------------------------------------------*/ -void - softfloat_shiftRightM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint32_t dist, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_shiftRight96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shiftRightM' with -| 'size_words' = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_shiftRight96M( aPtr, dist, zPtr ) softfloat_shiftRightM( 3, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shiftRightJamM -/*---------------------------------------------------------------------------- -| Shifts the N-bit unsigned integer pointed to by 'aPtr' right by the number -| of bits given in 'dist', where N = 'size_words' * 32. The value of 'dist' -| must not be zero. If any nonzero bits are shifted off, they are "jammed" -| into the least-significant bit of the shifted value by setting the least- -| significant bit to 1. This shifted-and-jammed N-bit result is stored -| at the location pointed to by 'zPtr'. Each of 'aPtr' and 'zPtr' points -| to a 'size_words'-long array of 32-bit elements that concatenate in the -| platform's normal endian order to form an N-bit integer. -| The value of 'dist' can be arbitrarily large. In particular, if 'dist' -| is greater than N, the stored result will be either 0 or 1, depending on -| whether the original N bits are all zeros. -*----------------------------------------------------------------------------*/ -void - softfloat_shiftRightJamM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint32_t dist, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_shiftRightJam96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shiftRightJamM' with -| 'size_words' = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_shiftRightJam96M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 3, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shiftRightJam128M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shiftRightJamM' with -| 'size_words' = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_shiftRightJam128M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 4, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_shiftRightJam160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_shiftRightJamM' with -| 'size_words' = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_shiftRightJam160M( aPtr, dist, zPtr ) softfloat_shiftRightJamM( 5, aPtr, dist, zPtr ) -#endif - -#ifndef softfloat_addM -/*---------------------------------------------------------------------------- -| Adds the two N-bit integers pointed to by 'aPtr' and 'bPtr', where N = -| 'size_words' * 32. The addition is modulo 2^N, so any carry out is lost. -| The N-bit sum is stored at the location pointed to by 'zPtr'. Each of -| 'aPtr', 'bPtr', and 'zPtr' points to a 'size_words'-long array of 32-bit -| elements that concatenate in the platform's normal endian order to form an -| N-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_addM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_add96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_addM' with 'size_words' -| = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_add96M( aPtr, bPtr, zPtr ) softfloat_addM( 3, aPtr, bPtr, zPtr ) -#endif - -#ifndef softfloat_add128M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_addM' with 'size_words' -| = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_add128M( aPtr, bPtr, zPtr ) softfloat_addM( 4, aPtr, bPtr, zPtr ) -#endif - -#ifndef softfloat_add160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_addM' with 'size_words' -| = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_add160M( aPtr, bPtr, zPtr ) softfloat_addM( 5, aPtr, bPtr, zPtr ) -#endif - -#ifndef softfloat_addCarryM -/*---------------------------------------------------------------------------- -| Adds the two N-bit unsigned integers pointed to by 'aPtr' and 'bPtr', where -| N = 'size_words' * 32, plus 'carry', which must be either 0 or 1. The N-bit -| sum (modulo 2^N) is stored at the location pointed to by 'zPtr', and any -| carry out is returned as the result. Each of 'aPtr', 'bPtr', and 'zPtr' -| points to a 'size_words'-long array of 32-bit elements that concatenate in -| the platform's normal endian order to form an N-bit integer. -*----------------------------------------------------------------------------*/ -uint_fast8_t - softfloat_addCarryM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint_fast8_t carry, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_addComplCarryM -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_addCarryM', except that -| the value of the unsigned integer pointed to by 'bPtr' is bit-wise completed -| before the addition. -*----------------------------------------------------------------------------*/ -uint_fast8_t - softfloat_addComplCarryM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint_fast8_t carry, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_addComplCarry96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_addComplCarryM' with -| 'size_words' = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_addComplCarry96M( aPtr, bPtr, carry, zPtr ) softfloat_addComplCarryM( 3, aPtr, bPtr, carry, zPtr ) -#endif - -#ifndef softfloat_negXM -/*---------------------------------------------------------------------------- -| Replaces the N-bit unsigned integer pointed to by 'zPtr' by the -| 2s-complement of itself, where N = 'size_words' * 32. Argument 'zPtr' -| points to a 'size_words'-long array of 32-bit elements that concatenate in -| the platform's normal endian order to form an N-bit integer. -*----------------------------------------------------------------------------*/ -void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); -#endif - -#ifndef softfloat_negX96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_negXM' with 'size_words' -| = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_negX96M( zPtr ) softfloat_negXM( 3, zPtr ) -#endif - -#ifndef softfloat_negX128M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_negXM' with 'size_words' -| = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_negX128M( zPtr ) softfloat_negXM( 4, zPtr ) -#endif - -#ifndef softfloat_negX160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_negXM' with 'size_words' -| = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_negX160M( zPtr ) softfloat_negXM( 5, zPtr ) -#endif - -#ifndef softfloat_negX256M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_negXM' with 'size_words' -| = 8 (N = 256). -*----------------------------------------------------------------------------*/ -#define softfloat_negX256M( zPtr ) softfloat_negXM( 8, zPtr ) -#endif - -#ifndef softfloat_sub1XM -/*---------------------------------------------------------------------------- -| Subtracts 1 from the N-bit integer pointed to by 'zPtr', where N = -| 'size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry -| out) is lost. Argument 'zPtr' points to a 'size_words'-long array of 32-bit -| elements that concatenate in the platform's normal endian order to form an -| N-bit integer. -*----------------------------------------------------------------------------*/ -void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ); -#endif - -#ifndef softfloat_sub1X96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_sub1XM' with 'size_words' -| = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_sub1X96M( zPtr ) softfloat_sub1XM( 3, zPtr ) -#endif - -#ifndef softfloat_sub1X160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_sub1XM' with 'size_words' -| = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_sub1X160M( zPtr ) softfloat_sub1XM( 5, zPtr ) -#endif - -#ifndef softfloat_subM -/*---------------------------------------------------------------------------- -| Subtracts the two N-bit integers pointed to by 'aPtr' and 'bPtr', where N = -| 'size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry -| out) is lost. The N-bit difference is stored at the location pointed to by -| 'zPtr'. Each of 'aPtr', 'bPtr', and 'zPtr' points to a 'size_words'-long -| array of 32-bit elements that concatenate in the platform's normal endian -| order to form an N-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_subM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_sub96M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_subM' with 'size_words' -| = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_sub96M( aPtr, bPtr, zPtr ) softfloat_subM( 3, aPtr, bPtr, zPtr ) -#endif - -#ifndef softfloat_sub128M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_subM' with 'size_words' -| = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_sub128M( aPtr, bPtr, zPtr ) softfloat_subM( 4, aPtr, bPtr, zPtr ) -#endif - -#ifndef softfloat_sub160M -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_subM' with 'size_words' -| = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_sub160M( aPtr, bPtr, zPtr ) softfloat_subM( 5, aPtr, bPtr, zPtr ) -#endif - -#ifndef softfloat_mul64To128M -/*---------------------------------------------------------------------------- -| Multiplies 'a' and 'b' and stores the 128-bit product at the location -| pointed to by 'zPtr'. Argument 'zPtr' points to an array of four 32-bit -| elements that concatenate in the platform's normal endian order to form a -| 128-bit integer. -*----------------------------------------------------------------------------*/ -void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr ); -#endif - -#ifndef softfloat_mul128MTo256M -/*---------------------------------------------------------------------------- -| Multiplies the two 128-bit unsigned integers pointed to by 'aPtr' and -| 'bPtr', and stores the 256-bit product at the location pointed to by 'zPtr'. -| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that -| concatenate in the platform's normal endian order to form a 128-bit integer. -| Argument 'zPtr' points to an array of eight 32-bit elements that concatenate -| to form a 256-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_mul128MTo256M( - const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr ); -#endif - -#ifndef softfloat_remStepMBy32 -/*---------------------------------------------------------------------------- -| Performs a "remainder reduction step" as follows: Arguments 'remPtr' and -| 'bPtr' both point to N-bit unsigned integers, where N = 'size_words' * 32. -| Defining R and B as the values of those integers, the expression (R<<'dist') -| - B * q is computed modulo 2^N, and the N-bit result is stored at the -| location pointed to by 'zPtr'. Each of 'remPtr', 'bPtr', and 'zPtr' points -| to a 'size_words'-long array of 32-bit elements that concatenate in the -| platform's normal endian order to form an N-bit integer. -*----------------------------------------------------------------------------*/ -void - softfloat_remStepMBy32( - uint_fast8_t size_words, - const uint32_t *remPtr, - uint_fast8_t dist, - const uint32_t *bPtr, - uint32_t q, - uint32_t *zPtr - ); -#endif - -#ifndef softfloat_remStep96MBy32 -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_remStepMBy32' with -| 'size_words' = 3 (N = 96). -*----------------------------------------------------------------------------*/ -#define softfloat_remStep96MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 3, remPtr, dist, bPtr, q, zPtr ) -#endif - -#ifndef softfloat_remStep128MBy32 -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_remStepMBy32' with -| 'size_words' = 4 (N = 128). -*----------------------------------------------------------------------------*/ -#define softfloat_remStep128MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 4, remPtr, dist, bPtr, q, zPtr ) -#endif - -#ifndef softfloat_remStep160MBy32 -/*---------------------------------------------------------------------------- -| This function or macro is the same as 'softfloat_remStepMBy32' with -| 'size_words' = 5 (N = 160). -*----------------------------------------------------------------------------*/ -#define softfloat_remStep160MBy32( remPtr, dist, bPtr, q, zPtr ) softfloat_remStepMBy32( 5, remPtr, dist, bPtr, q, zPtr ) -#endif - -#endif - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/include/softfloat.h b/source/src/vm/libcpu_newdev/softfloat3/source/include/softfloat.h deleted file mode 100644 index 9ed17c1b9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/include/softfloat.h +++ /dev/null @@ -1,372 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - - -/*============================================================================ -| Note: If SoftFloat is made available as a general library for programs to -| use, it is strongly recommended that a platform-specific version of this -| header, "softfloat.h", be created that folds in "softfloat_types.h" and that -| eliminates all dependencies on compile-time macros. -*============================================================================*/ - - -#ifndef softfloat_h -#define softfloat_h 1 - -#include -#include -#include "softfloat_types.h" - -#ifndef THREAD_LOCAL -#define THREAD_LOCAL -#endif - -/*---------------------------------------------------------------------------- -| Software floating-point underflow tininess-detection mode. -*----------------------------------------------------------------------------*/ -extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess; -enum { - softfloat_tininess_beforeRounding = 0, - softfloat_tininess_afterRounding = 1 -}; - -/*---------------------------------------------------------------------------- -| Software floating-point rounding mode. (Mode "odd" is supported only if -| SoftFloat is compiled with macro 'SOFTFLOAT_ROUND_ODD' defined.) -*----------------------------------------------------------------------------*/ -extern THREAD_LOCAL uint_fast8_t softfloat_roundingMode; -enum { - softfloat_round_near_even = 0, - softfloat_round_minMag = 1, - softfloat_round_min = 2, - softfloat_round_max = 3, - softfloat_round_near_maxMag = 4, - softfloat_round_odd = 6 -}; - -/*---------------------------------------------------------------------------- -| Software floating-point exception flags. -*----------------------------------------------------------------------------*/ -extern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags; -enum { - softfloat_flag_inexact = 1, - softfloat_flag_underflow = 2, - softfloat_flag_overflow = 4, - softfloat_flag_infinite = 8, - softfloat_flag_invalid = 16 -}; - -/*---------------------------------------------------------------------------- -| Routine to raise any or all of the software floating-point exception flags. -*----------------------------------------------------------------------------*/ -void softfloat_raiseFlags( uint_fast8_t ); - -/*---------------------------------------------------------------------------- -| Integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float16_t ui32_to_f16( uint32_t ); -float32_t ui32_to_f32( uint32_t ); -float64_t ui32_to_f64( uint32_t ); -#ifdef SOFTFLOAT_FAST_INT64 -extFloat80_t ui32_to_extF80( uint32_t ); -float128_t ui32_to_f128( uint32_t ); -#endif -void ui32_to_extF80M( uint32_t, extFloat80_t * ); -void ui32_to_f128M( uint32_t, float128_t * ); -float16_t ui64_to_f16( uint64_t ); -float32_t ui64_to_f32( uint64_t ); -float64_t ui64_to_f64( uint64_t ); -#ifdef SOFTFLOAT_FAST_INT64 -extFloat80_t ui64_to_extF80( uint64_t ); -float128_t ui64_to_f128( uint64_t ); -#endif -void ui64_to_extF80M( uint64_t, extFloat80_t * ); -void ui64_to_f128M( uint64_t, float128_t * ); -float16_t i32_to_f16( int32_t ); -float32_t i32_to_f32( int32_t ); -float64_t i32_to_f64( int32_t ); -#ifdef SOFTFLOAT_FAST_INT64 -extFloat80_t i32_to_extF80( int32_t ); -float128_t i32_to_f128( int32_t ); -#endif -void i32_to_extF80M( int32_t, extFloat80_t * ); -void i32_to_f128M( int32_t, float128_t * ); -float16_t i64_to_f16( int64_t ); -float32_t i64_to_f32( int64_t ); -float64_t i64_to_f64( int64_t ); -#ifdef SOFTFLOAT_FAST_INT64 -extFloat80_t i64_to_extF80( int64_t ); -float128_t i64_to_f128( int64_t ); -#endif -void i64_to_extF80M( int64_t, extFloat80_t * ); -void i64_to_f128M( int64_t, float128_t * ); - -/*---------------------------------------------------------------------------- -| 16-bit (half-precision) floating-point operations. -*----------------------------------------------------------------------------*/ -uint_fast32_t f16_to_ui32( float16_t, uint_fast8_t, bool ); -uint_fast64_t f16_to_ui64( float16_t, uint_fast8_t, bool ); -int_fast32_t f16_to_i32( float16_t, uint_fast8_t, bool ); -int_fast64_t f16_to_i64( float16_t, uint_fast8_t, bool ); -uint_fast32_t f16_to_ui32_r_minMag( float16_t, bool ); -uint_fast64_t f16_to_ui64_r_minMag( float16_t, bool ); -int_fast32_t f16_to_i32_r_minMag( float16_t, bool ); -int_fast64_t f16_to_i64_r_minMag( float16_t, bool ); -float32_t f16_to_f32( float16_t ); -float64_t f16_to_f64( float16_t ); -#ifdef SOFTFLOAT_FAST_INT64 -extFloat80_t f16_to_extF80( float16_t ); -float128_t f16_to_f128( float16_t ); -#endif -void f16_to_extF80M( float16_t, extFloat80_t * ); -void f16_to_f128M( float16_t, float128_t * ); -float16_t f16_roundToInt( float16_t, uint_fast8_t, bool ); -float16_t f16_add( float16_t, float16_t ); -float16_t f16_sub( float16_t, float16_t ); -float16_t f16_mul( float16_t, float16_t ); -float16_t f16_mulAdd( float16_t, float16_t, float16_t ); -float16_t f16_div( float16_t, float16_t ); -float16_t f16_rem( float16_t, float16_t ); -float16_t f16_sqrt( float16_t ); -bool f16_eq( float16_t, float16_t ); -bool f16_le( float16_t, float16_t ); -bool f16_lt( float16_t, float16_t ); -bool f16_eq_signaling( float16_t, float16_t ); -bool f16_le_quiet( float16_t, float16_t ); -bool f16_lt_quiet( float16_t, float16_t ); -bool f16_isSignalingNaN( float16_t ); - -/*---------------------------------------------------------------------------- -| 32-bit (single-precision) floating-point operations. -*----------------------------------------------------------------------------*/ -uint_fast32_t f32_to_ui32( float32_t, uint_fast8_t, bool ); -uint_fast64_t f32_to_ui64( float32_t, uint_fast8_t, bool ); -int_fast32_t f32_to_i32( float32_t, uint_fast8_t, bool ); -int_fast64_t f32_to_i64( float32_t, uint_fast8_t, bool ); -uint_fast32_t f32_to_ui32_r_minMag( float32_t, bool ); -uint_fast64_t f32_to_ui64_r_minMag( float32_t, bool ); -int_fast32_t f32_to_i32_r_minMag( float32_t, bool ); -int_fast64_t f32_to_i64_r_minMag( float32_t, bool ); -float16_t f32_to_f16( float32_t ); -float64_t f32_to_f64( float32_t ); -#ifdef SOFTFLOAT_FAST_INT64 -extFloat80_t f32_to_extF80( float32_t ); -float128_t f32_to_f128( float32_t ); -#endif -void f32_to_extF80M( float32_t, extFloat80_t * ); -void f32_to_f128M( float32_t, float128_t * ); -float32_t f32_roundToInt( float32_t, uint_fast8_t, bool ); -float32_t f32_add( float32_t, float32_t ); -float32_t f32_sub( float32_t, float32_t ); -float32_t f32_mul( float32_t, float32_t ); -float32_t f32_mulAdd( float32_t, float32_t, float32_t ); -float32_t f32_div( float32_t, float32_t ); -float32_t f32_rem( float32_t, float32_t ); -float32_t f32_sqrt( float32_t ); -bool f32_eq( float32_t, float32_t ); -bool f32_le( float32_t, float32_t ); -bool f32_lt( float32_t, float32_t ); -bool f32_eq_signaling( float32_t, float32_t ); -bool f32_le_quiet( float32_t, float32_t ); -bool f32_lt_quiet( float32_t, float32_t ); -bool f32_isSignalingNaN( float32_t ); - -/*---------------------------------------------------------------------------- -| 64-bit (double-precision) floating-point operations. -*----------------------------------------------------------------------------*/ -uint_fast32_t f64_to_ui32( float64_t, uint_fast8_t, bool ); -uint_fast64_t f64_to_ui64( float64_t, uint_fast8_t, bool ); -int_fast32_t f64_to_i32( float64_t, uint_fast8_t, bool ); -int_fast64_t f64_to_i64( float64_t, uint_fast8_t, bool ); -uint_fast32_t f64_to_ui32_r_minMag( float64_t, bool ); -uint_fast64_t f64_to_ui64_r_minMag( float64_t, bool ); -int_fast32_t f64_to_i32_r_minMag( float64_t, bool ); -int_fast64_t f64_to_i64_r_minMag( float64_t, bool ); -float16_t f64_to_f16( float64_t ); -float32_t f64_to_f32( float64_t ); -#ifdef SOFTFLOAT_FAST_INT64 -extFloat80_t f64_to_extF80( float64_t ); -float128_t f64_to_f128( float64_t ); -#endif -void f64_to_extF80M( float64_t, extFloat80_t * ); -void f64_to_f128M( float64_t, float128_t * ); -float64_t f64_roundToInt( float64_t, uint_fast8_t, bool ); -float64_t f64_add( float64_t, float64_t ); -float64_t f64_sub( float64_t, float64_t ); -float64_t f64_mul( float64_t, float64_t ); -float64_t f64_mulAdd( float64_t, float64_t, float64_t ); -float64_t f64_div( float64_t, float64_t ); -float64_t f64_rem( float64_t, float64_t ); -float64_t f64_sqrt( float64_t ); -bool f64_eq( float64_t, float64_t ); -bool f64_le( float64_t, float64_t ); -bool f64_lt( float64_t, float64_t ); -bool f64_eq_signaling( float64_t, float64_t ); -bool f64_le_quiet( float64_t, float64_t ); -bool f64_lt_quiet( float64_t, float64_t ); -bool f64_isSignalingNaN( float64_t ); - -/*---------------------------------------------------------------------------- -| Rounding precision for 80-bit extended double-precision floating-point. -| Valid values are 32, 64, and 80. -*----------------------------------------------------------------------------*/ -extern THREAD_LOCAL uint_fast8_t extF80_roundingPrecision; - -/*---------------------------------------------------------------------------- -| 80-bit extended double-precision floating-point operations. -*----------------------------------------------------------------------------*/ -#ifdef SOFTFLOAT_FAST_INT64 -uint_fast32_t extF80_to_ui32( extFloat80_t, uint_fast8_t, bool ); -uint_fast64_t extF80_to_ui64( extFloat80_t, uint_fast8_t, bool ); -int_fast32_t extF80_to_i32( extFloat80_t, uint_fast8_t, bool ); -int_fast64_t extF80_to_i64( extFloat80_t, uint_fast8_t, bool ); -uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t, bool ); -uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t, bool ); -int_fast32_t extF80_to_i32_r_minMag( extFloat80_t, bool ); -int_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bool ); -float16_t extF80_to_f16( extFloat80_t ); -float32_t extF80_to_f32( extFloat80_t ); -float64_t extF80_to_f64( extFloat80_t ); -float128_t extF80_to_f128( extFloat80_t ); -extFloat80_t extF80_roundToInt( extFloat80_t, uint_fast8_t, bool ); -extFloat80_t extF80_add( extFloat80_t, extFloat80_t ); -extFloat80_t extF80_sub( extFloat80_t, extFloat80_t ); -extFloat80_t extF80_mul( extFloat80_t, extFloat80_t ); -extFloat80_t extF80_div( extFloat80_t, extFloat80_t ); -extFloat80_t extF80_rem( extFloat80_t, extFloat80_t ); -extFloat80_t extF80_sqrt( extFloat80_t ); -bool extF80_eq( extFloat80_t, extFloat80_t ); -bool extF80_le( extFloat80_t, extFloat80_t ); -bool extF80_lt( extFloat80_t, extFloat80_t ); -bool extF80_eq_signaling( extFloat80_t, extFloat80_t ); -bool extF80_le_quiet( extFloat80_t, extFloat80_t ); -bool extF80_lt_quiet( extFloat80_t, extFloat80_t ); -bool extF80_isSignalingNaN( extFloat80_t ); -#endif -uint_fast32_t extF80M_to_ui32( const extFloat80_t *, uint_fast8_t, bool ); -uint_fast64_t extF80M_to_ui64( const extFloat80_t *, uint_fast8_t, bool ); -int_fast32_t extF80M_to_i32( const extFloat80_t *, uint_fast8_t, bool ); -int_fast64_t extF80M_to_i64( const extFloat80_t *, uint_fast8_t, bool ); -uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *, bool ); -uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *, bool ); -int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *, bool ); -int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bool ); -float16_t extF80M_to_f16( const extFloat80_t * ); -float32_t extF80M_to_f32( const extFloat80_t * ); -float64_t extF80M_to_f64( const extFloat80_t * ); -void extF80M_to_f128M( const extFloat80_t *, float128_t * ); -void - extF80M_roundToInt( - const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * ); -void extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); -void extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); -void extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); -void extF80M_div( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); -void extF80M_rem( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); -void extF80M_sqrt( const extFloat80_t *, extFloat80_t * ); -bool extF80M_eq( const extFloat80_t *, const extFloat80_t * ); -bool extF80M_le( const extFloat80_t *, const extFloat80_t * ); -bool extF80M_lt( const extFloat80_t *, const extFloat80_t * ); -bool extF80M_eq_signaling( const extFloat80_t *, const extFloat80_t * ); -bool extF80M_le_quiet( const extFloat80_t *, const extFloat80_t * ); -bool extF80M_lt_quiet( const extFloat80_t *, const extFloat80_t * ); -bool extF80M_isSignalingNaN( const extFloat80_t * ); - -/*---------------------------------------------------------------------------- -| 128-bit (quadruple-precision) floating-point operations. -*----------------------------------------------------------------------------*/ -#ifdef SOFTFLOAT_FAST_INT64 -uint_fast32_t f128_to_ui32( float128_t, uint_fast8_t, bool ); -uint_fast64_t f128_to_ui64( float128_t, uint_fast8_t, bool ); -int_fast32_t f128_to_i32( float128_t, uint_fast8_t, bool ); -int_fast64_t f128_to_i64( float128_t, uint_fast8_t, bool ); -uint_fast32_t f128_to_ui32_r_minMag( float128_t, bool ); -uint_fast64_t f128_to_ui64_r_minMag( float128_t, bool ); -int_fast32_t f128_to_i32_r_minMag( float128_t, bool ); -int_fast64_t f128_to_i64_r_minMag( float128_t, bool ); -float16_t f128_to_f16( float128_t ); -float32_t f128_to_f32( float128_t ); -float64_t f128_to_f64( float128_t ); -extFloat80_t f128_to_extF80( float128_t ); -float128_t f128_roundToInt( float128_t, uint_fast8_t, bool ); -float128_t f128_add( float128_t, float128_t ); -float128_t f128_sub( float128_t, float128_t ); -float128_t f128_mul( float128_t, float128_t ); -float128_t f128_mulAdd( float128_t, float128_t, float128_t ); -float128_t f128_div( float128_t, float128_t ); -float128_t f128_rem( float128_t, float128_t ); -float128_t f128_sqrt( float128_t ); -bool f128_eq( float128_t, float128_t ); -bool f128_le( float128_t, float128_t ); -bool f128_lt( float128_t, float128_t ); -bool f128_eq_signaling( float128_t, float128_t ); -bool f128_le_quiet( float128_t, float128_t ); -bool f128_lt_quiet( float128_t, float128_t ); -bool f128_isSignalingNaN( float128_t ); -#endif -uint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bool ); -uint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bool ); -int_fast32_t f128M_to_i32( const float128_t *, uint_fast8_t, bool ); -int_fast64_t f128M_to_i64( const float128_t *, uint_fast8_t, bool ); -uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *, bool ); -uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *, bool ); -int_fast32_t f128M_to_i32_r_minMag( const float128_t *, bool ); -int_fast64_t f128M_to_i64_r_minMag( const float128_t *, bool ); -float16_t f128M_to_f16( const float128_t * ); -float32_t f128M_to_f32( const float128_t * ); -float64_t f128M_to_f64( const float128_t * ); -void f128M_to_extF80M( const float128_t *, extFloat80_t * ); -void f128M_roundToInt( const float128_t *, uint_fast8_t, bool, float128_t * ); -void f128M_add( const float128_t *, const float128_t *, float128_t * ); -void f128M_sub( const float128_t *, const float128_t *, float128_t * ); -void f128M_mul( const float128_t *, const float128_t *, float128_t * ); -void - f128M_mulAdd( - const float128_t *, const float128_t *, const float128_t *, float128_t * - ); -void f128M_div( const float128_t *, const float128_t *, float128_t * ); -void f128M_rem( const float128_t *, const float128_t *, float128_t * ); -void f128M_sqrt( const float128_t *, float128_t * ); -bool f128M_eq( const float128_t *, const float128_t * ); -bool f128M_le( const float128_t *, const float128_t * ); -bool f128M_lt( const float128_t *, const float128_t * ); -bool f128M_eq_signaling( const float128_t *, const float128_t * ); -bool f128M_le_quiet( const float128_t *, const float128_t * ); -bool f128M_lt_quiet( const float128_t *, const float128_t * ); -bool f128M_isSignalingNaN( const float128_t * ); - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/include/softfloat_types.h b/source/src/vm/libcpu_newdev/softfloat3/source/include/softfloat_types.h deleted file mode 100644 index b92d24625..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/include/softfloat_types.h +++ /dev/null @@ -1,81 +0,0 @@ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#ifndef softfloat_types_h -#define softfloat_types_h 1 - -#include - -/*---------------------------------------------------------------------------- -| Types used to pass 16-bit, 32-bit, 64-bit, and 128-bit floating-point -| arguments and results to/from functions. These types must be exactly -| 16 bits, 32 bits, 64 bits, and 128 bits in size, respectively. Where a -| platform has "native" support for IEEE-Standard floating-point formats, -| the types below may, if desired, be defined as aliases for the native types -| (typically 'float' and 'double', and possibly 'long double'). -*----------------------------------------------------------------------------*/ -typedef struct { uint16_t v; } float16_t; -typedef struct { uint32_t v; } float32_t; -typedef struct { uint64_t v; } float64_t; -typedef struct { uint64_t v[2]; } float128_t; - -/*---------------------------------------------------------------------------- -| The format of an 80-bit extended floating-point number in memory. This -| structure must contain a 16-bit field named 'signExp' and a 64-bit field -| named 'signif'. -*----------------------------------------------------------------------------*/ -#ifdef LITTLEENDIAN -struct extFloat80M { uint64_t signif; uint16_t signExp; }; -#else -struct extFloat80M { uint16_t signExp; uint64_t signif; }; -#endif - -/*---------------------------------------------------------------------------- -| The type used to pass 80-bit extended floating-point arguments and -| results to/from functions. This type must have size identical to -| 'struct extFloat80M'. Type 'extFloat80_t' can be defined as an alias for -| 'struct extFloat80M'. Alternatively, if a platform has "native" support -| for IEEE-Standard 80-bit extended floating-point, it may be possible, -| if desired, to define 'extFloat80_t' as an alias for the native type -| (presumably either 'long double' or a nonstandard compiler-intrinsic type). -| In that case, the 'signif' and 'signExp' fields of 'struct extFloat80M' -| must align exactly with the locations in memory of the sign, exponent, and -| significand of the native type. -*----------------------------------------------------------------------------*/ -typedef struct extFloat80M extFloat80_t; - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_add128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_add128.c deleted file mode 100644 index 984664360..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_add128.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_add128 - -struct uint128 - softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - struct uint128 z; - - z.v0 = a0 + b0; - z.v64 = a64 + b64 + (z.v0 < a0); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_add256M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_add256M.c deleted file mode 100644 index bfecf7b2e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_add256M.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_add256M - -void - softfloat_add256M( - const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ) -{ - unsigned int index; - uint_fast8_t carry; - uint64_t wordA, wordZ; - - index = indexWordLo( 4 ); - carry = 0; - for (;;) { - wordA = aPtr[index]; - wordZ = wordA + bPtr[index] + carry; - zPtr[index] = wordZ; - if ( index == indexWordHi( 4 ) ) break; - if ( wordZ != wordA ) carry = (wordZ < wordA); - index += wordIncr; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addCarryM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addCarryM.c deleted file mode 100644 index fb84a383c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addCarryM.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_addCarryM - -uint_fast8_t - softfloat_addCarryM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint_fast8_t carry, - uint32_t *zPtr - ) -{ - unsigned int index, lastIndex; - uint32_t wordA, wordZ; - - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - for (;;) { - wordA = aPtr[index]; - wordZ = wordA + bPtr[index] + carry; - zPtr[index] = wordZ; - if ( wordZ != wordA ) carry = (wordZ < wordA); - if ( index == lastIndex ) break; - index += wordIncr; - } - return carry; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addComplCarryM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addComplCarryM.c deleted file mode 100644 index 1f8d543e2..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addComplCarryM.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_addComplCarryM - -uint_fast8_t - softfloat_addComplCarryM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint_fast8_t carry, - uint32_t *zPtr - ) -{ - unsigned int index, lastIndex; - uint32_t wordA, wordZ; - - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - for (;;) { - wordA = aPtr[index]; - wordZ = wordA + ~bPtr[index] + carry; - zPtr[index] = wordZ; - if ( wordZ != wordA ) carry = (wordZ < wordA); - if ( index == lastIndex ) break; - index += wordIncr; - } - return carry; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addExtF80M.c deleted file mode 100644 index f0142905f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addExtF80M.c +++ /dev/null @@ -1,186 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -void - softfloat_addExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr, - bool negateB - ) -{ - uint32_t uiA64; - int32_t expA; - uint32_t uiB64; - int32_t expB; - uint32_t uiZ64; - bool signZ, signB; - const struct extFloat80M *tempSPtr; - uint64_t sigZ, sigB; - void - (*roundPackRoutinePtr)( - bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * ); - int32_t expDiff; - uint32_t extSigX[3], sigZExtra; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - expA = expExtF80UI64( uiA64 ); - uiB64 = bSPtr->signExp; - expB = expExtF80UI64( uiB64 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNExtF80M( aSPtr, bSPtr, zSPtr ) ) return; - uiZ64 = uiA64; - if ( expB == 0x7FFF ) { - uiZ64 = uiB64 ^ packToExtF80UI64( negateB, 0 ); - if ( (expA == 0x7FFF) && (uiZ64 != uiA64) ) { - softfloat_invalidExtF80M( zSPtr ); - return; - } - } - zSPtr->signExp = uiZ64; - zSPtr->signif = UINT64_C( 0x8000000000000000 ); - return; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signZ = signExtF80UI64( uiA64 ); - signB = signExtF80UI64( uiB64 ) ^ negateB; - negateB = (signZ != signB); - if ( expA < expB ) { - signZ = signB; - expA = expB; - expB = expExtF80UI64( uiA64 ); - tempSPtr = aSPtr; - aSPtr = bSPtr; - bSPtr = tempSPtr; - } - if ( ! expB ) { - expB = 1; - if ( ! expA ) expA = 1; - } - sigZ = aSPtr->signif; - sigB = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundPackRoutinePtr = softfloat_roundPackMToExtF80M; - expDiff = expA - expB; - if ( expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - extSigX[indexWord( 3, 2 )] = sigB>>32; - extSigX[indexWord( 3, 1 )] = sigB; - extSigX[indexWord( 3, 0 )] = 0; - softfloat_shiftRightJam96M( extSigX, expDiff, extSigX ); - sigB = - (uint64_t) extSigX[indexWord( 3, 2 )]<<32 - | extSigX[indexWord( 3, 1 )]; - if ( negateB ) { - sigZ -= sigB; - sigZExtra = extSigX[indexWordLo( 3 )]; - if ( sigZExtra ) { - --sigZ; - sigZExtra = -sigZExtra; - } - if ( ! (sigZ & UINT64_C( 0x8000000000000000 )) ) { - if ( sigZ & UINT64_C( 0x4000000000000000 ) ) { - --expA; - sigZ = sigZ<<1 | sigZExtra>>31; - sigZExtra <<= 1; - } else { - roundPackRoutinePtr = softfloat_normRoundPackMToExtF80M; - } - } - } else { - sigZ += sigB; - if ( sigZ & UINT64_C( 0x8000000000000000 ) ) goto sigZ; - sigZExtra = (uint32_t) sigZ<<31 | (extSigX[indexWordLo( 3 )] != 0); - goto completeNormAfterAdd; - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sigZExtra = 0; - if ( negateB ) { - if ( sigZ < sigB ) { - signZ = ! signZ; - sigZ = sigB - sigZ; - } else { - sigZ -= sigB; - if ( ! sigZ ) { - signZ = (softfloat_roundingMode == softfloat_round_min); - zSPtr->signExp = packToExtF80UI64( signZ, 0 ); - zSPtr->signif = 0; - return; - } - } - roundPackRoutinePtr = softfloat_normRoundPackMToExtF80M; - } else { - sigZ += sigB; - if ( sigZ < sigB ) { - sigZExtra = (uint32_t) sigZ<<31; - completeNormAfterAdd: - ++expA; - sigZ = UINT64_C( 0x8000000000000000 ) | sigZ>>1; - } else { - if ( ! (sigZ & UINT64_C( 0x8000000000000000 )) ) { - roundPackRoutinePtr = softfloat_normRoundPackMToExtF80M; - } - } - } - } - extSigX[indexWord( 3, 0 )] = sigZExtra; - sigZ: - extSigX[indexWord( 3, 2 )] = sigZ>>32; - extSigX[indexWord( 3, 1 )] = sigZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundPack: - (*roundPackRoutinePtr)( - signZ, expA, extSigX, extF80_roundingPrecision, zSPtr ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addF128M.c deleted file mode 100644 index c5fcf7047..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addF128M.c +++ /dev/null @@ -1,211 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -void - softfloat_addF128M( - const uint32_t *aWPtr, - const uint32_t *bWPtr, - uint32_t *zWPtr, - bool negateB - ) -{ - uint32_t uiA96; - int32_t expA; - uint32_t uiB96; - int32_t expB; - uint32_t uiZ96; - bool signZ, signB; - const uint32_t *tempPtr; - uint32_t sig96A, sig96B; - int32_t expDiff; - uint_fast8_t - (*addCarryMRoutinePtr)( - uint_fast8_t, - const uint32_t *, - const uint32_t *, - uint_fast8_t, - uint32_t * - ); - uint32_t extSigZ[5], wordSigZ; - uint_fast8_t carry; - void (*roundPackRoutinePtr)( bool, int32_t, uint32_t *, uint32_t * ); - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - expA = expF128UI96( uiA96 ); - uiB96 = bWPtr[indexWordHi( 4 )]; - expB = expF128UI96( uiB96 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) return; - uiZ96 = uiA96; - if ( expB == 0x7FFF ) { - uiZ96 = uiB96 ^ packToF128UI96( negateB, 0, 0 ); - if ( (expA == 0x7FFF) && (uiZ96 != uiA96) ) { - softfloat_invalidF128M( zWPtr ); - return; - } - } - zWPtr[indexWordHi( 4 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - return; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signZ = signF128UI96( uiA96 ); - signB = signF128UI96( uiB96 ) ^ negateB; - negateB = (signZ != signB); - if ( (uint32_t) (uiA96<<1) < (uint32_t) (uiB96<<1) ) { - signZ = signB; - expA = expB; - expB = expF128UI96( uiA96 ); - tempPtr = aWPtr; - aWPtr = bWPtr; - bWPtr = tempPtr; - uiA96 = uiB96; - uiB96 = bWPtr[indexWordHi( 4 )]; - } - sig96A = fracF128UI96( uiA96 ); - sig96B = fracF128UI96( uiB96 ); - if ( expA ) { - --expA; - sig96A |= 0x00010000; - if ( expB ) { - --expB; - sig96B |= 0x00010000; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - addCarryMRoutinePtr = - negateB ? softfloat_addComplCarryM : softfloat_addCarryM; - expDiff = expA - expB; - if ( expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - extSigZ[indexWordHi( 5 )] = sig96B; - extSigZ[indexWord( 5, 3 )] = bWPtr[indexWord( 4, 2 )]; - extSigZ[indexWord( 5, 2 )] = bWPtr[indexWord( 4, 1 )]; - extSigZ[indexWord( 5, 1 )] = bWPtr[indexWord( 4, 0 )]; - extSigZ[indexWord( 5, 0 )] = 0; - softfloat_shiftRightJam160M( extSigZ, expDiff, extSigZ ); - sig96B = extSigZ[indexWordHi( 5 )]; - carry = 0; - if ( negateB ) { - sig96B = ~sig96B; - wordSigZ = extSigZ[indexWordLo( 5 )]; - extSigZ[indexWordLo( 5 )] = -wordSigZ; - carry = ! wordSigZ; - } - carry = - (*addCarryMRoutinePtr)( - 3, - &aWPtr[indexMultiwordLo( 4, 3 )], - &extSigZ[indexMultiword( 5, 3, 1 )], - carry, - &extSigZ[indexMultiword( 5, 3, 1 )] - ); - wordSigZ = sig96A + sig96B + carry; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - extSigZ[indexWordLo( 5 )] = 0; - carry = - (*addCarryMRoutinePtr)( - 3, - &aWPtr[indexMultiwordLo( 4, 3 )], - &bWPtr[indexMultiwordLo( 4, 3 )], - negateB, - &extSigZ[indexMultiword( 5, 3, 1 )] - ); - if ( negateB ) { - wordSigZ = sig96A + ~sig96B + carry; - if ( wordSigZ & 0x80000000 ) { - signZ = ! signZ; - carry = - softfloat_addComplCarry96M( - &bWPtr[indexMultiwordLo( 4, 3 )], - &aWPtr[indexMultiwordLo( 4, 3 )], - 1, - &extSigZ[indexMultiword( 5, 3, 1 )] - ); - wordSigZ = sig96B + ~sig96A + carry; - } else { - if ( - ! wordSigZ && ! extSigZ[indexWord( 5, 3 )] - && ! ( extSigZ[indexWord( 5, 2 )] - | extSigZ[indexWord( 5, 1 )] - | extSigZ[indexWord( 5, 0 )] - ) - ) { - signZ = (softfloat_roundingMode == softfloat_round_min); - zWPtr[indexWordHi( 4 )] = packToF128UI96( signZ, 0, 0 ); - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - return; - } - } - } else { - wordSigZ = sig96A + sig96B + carry; - } - } - extSigZ[indexWordHi( 5 )] = wordSigZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundPackRoutinePtr = softfloat_normRoundPackMToF128M; - if ( 0x00010000 <= wordSigZ ) { - if ( 0x00020000 <= wordSigZ ) { - ++expA; - softfloat_shortShiftRightJam160M( extSigZ, 1, extSigZ ); - } - roundPackRoutinePtr = softfloat_roundPackMToF128M; - } - (*roundPackRoutinePtr)( signZ, expA, extSigZ, zWPtr ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addM.c deleted file mode 100644 index e1cc66bf0..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addM.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_addM - -void - softfloat_addM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint32_t *zPtr - ) -{ - unsigned int index, lastIndex; - uint_fast8_t carry; - uint32_t wordA, wordZ; - - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - carry = 0; - for (;;) { - wordA = aPtr[index]; - wordZ = wordA + bPtr[index] + carry; - zPtr[index] = wordZ; - if ( index == lastIndex ) break; - if ( wordZ != wordA ) carry = (wordZ < wordA); - index += wordIncr; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsExtF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsExtF80.c deleted file mode 100644 index 6e7d1a6ff..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsExtF80.c +++ /dev/null @@ -1,156 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t - softfloat_addMagsExtF80( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0, - bool signZ - ) -{ - int_fast32_t expA; - uint_fast64_t sigA; - int_fast32_t expB; - uint_fast64_t sigB; - int_fast32_t expDiff; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0, sigZ, sigZExtra; - struct exp32_sig64 normExpSig; - int_fast32_t expZ; - struct uint64_extra sig64Extra; - struct uint128 uiZ; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expExtF80UI64( uiA64 ); - sigA = uiA0; - expB = expExtF80UI64( uiB64 ); - sigB = uiB0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( ! expDiff ) { - if ( expA == 0x7FFF ) { - if ( (sigA | sigB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - goto propagateNaN; - } - uiZ64 = uiA64; - uiZ0 = uiA0; - goto uiZ; - } - sigZ = sigA + sigB; - sigZExtra = 0; - if ( ! expA ) { - normExpSig = softfloat_normSubnormalExtF80Sig( sigZ ); - expZ = normExpSig.exp + 1; - sigZ = normExpSig.sig; - goto roundAndPack; - } - expZ = expA; - goto shiftRight1; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expDiff < 0 ) { - if ( expB == 0x7FFF ) { - if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - uiZ64 = packToExtF80UI64( signZ, 0x7FFF ); - uiZ0 = uiB0; - goto uiZ; - } - expZ = expB; - if ( ! expA ) { - ++expDiff; - sigZExtra = 0; - if ( ! expDiff ) goto newlyAligned; - } - sig64Extra = softfloat_shiftRightJam64Extra( sigA, 0, -expDiff ); - sigA = sig64Extra.v; - sigZExtra = sig64Extra.extra; - } else { - if ( expA == 0x7FFF ) { - if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - uiZ64 = uiA64; - uiZ0 = uiA0; - goto uiZ; - } - expZ = expA; - if ( ! expB ) { - --expDiff; - sigZExtra = 0; - if ( ! expDiff ) goto newlyAligned; - } - sig64Extra = softfloat_shiftRightJam64Extra( sigB, 0, expDiff ); - sigB = sig64Extra.v; - sigZExtra = sig64Extra.extra; - } - newlyAligned: - sigZ = sigA + sigB; - if ( sigZ & UINT64_C( 0x8000000000000000 ) ) goto roundAndPack; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftRight1: - sig64Extra = softfloat_shortShiftRightJam64Extra( sigZ, sigZExtra, 1 ); - sigZ = sig64Extra.v | UINT64_C( 0x8000000000000000 ); - sigZExtra = sig64Extra.extra; - ++expZ; - roundAndPack: - return - softfloat_roundPackToExtF80( - signZ, expZ, sigZ, sigZExtra, extF80_roundingPrecision ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, uiB64, uiB0 ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF128.c deleted file mode 100644 index da8e88824..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF128.c +++ /dev/null @@ -1,154 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -float128_t - softfloat_addMagsF128( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0, - bool signZ - ) -{ - int_fast32_t expA; - struct uint128 sigA; - int_fast32_t expB; - struct uint128 sigB; - int_fast32_t expDiff; - struct uint128 uiZ, sigZ; - int_fast32_t expZ; - uint_fast64_t sigZExtra; - struct uint128_extra sig128Extra; - union ui128_f128 uZ; - - expA = expF128UI64( uiA64 ); - sigA.v64 = fracF128UI64( uiA64 ); - sigA.v0 = uiA0; - expB = expF128UI64( uiB64 ); - sigB.v64 = fracF128UI64( uiB64 ); - sigB.v0 = uiB0; - expDiff = expA - expB; - if ( ! expDiff ) { - if ( expA == 0x7FFF ) { - if ( sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0 ) goto propagateNaN; - uiZ.v64 = uiA64; - uiZ.v0 = uiA0; - goto uiZ; - } - sigZ = softfloat_add128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ); - if ( ! expA ) { - uiZ.v64 = packToF128UI64( signZ, 0, sigZ.v64 ); - uiZ.v0 = sigZ.v0; - goto uiZ; - } - expZ = expA; - sigZ.v64 |= UINT64_C( 0x0002000000000000 ); - sigZExtra = 0; - goto shiftRight1; - } - if ( expDiff < 0 ) { - if ( expB == 0x7FFF ) { - if ( sigB.v64 | sigB.v0 ) goto propagateNaN; - uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); - uiZ.v0 = 0; - goto uiZ; - } - expZ = expB; - if ( expA ) { - sigA.v64 |= UINT64_C( 0x0001000000000000 ); - } else { - ++expDiff; - sigZExtra = 0; - if ( ! expDiff ) goto newlyAligned; - } - sig128Extra = - softfloat_shiftRightJam128Extra( sigA.v64, sigA.v0, 0, -expDiff ); - sigA = sig128Extra.v; - sigZExtra = sig128Extra.extra; - } else { - if ( expA == 0x7FFF ) { - if ( sigA.v64 | sigA.v0 ) goto propagateNaN; - uiZ.v64 = uiA64; - uiZ.v0 = uiA0; - goto uiZ; - } - expZ = expA; - if ( expB ) { - sigB.v64 |= UINT64_C( 0x0001000000000000 ); - } else { - --expDiff; - sigZExtra = 0; - if ( ! expDiff ) goto newlyAligned; - } - sig128Extra = - softfloat_shiftRightJam128Extra( sigB.v64, sigB.v0, 0, expDiff ); - sigB = sig128Extra.v; - sigZExtra = sig128Extra.extra; - } - newlyAligned: - sigZ = - softfloat_add128( - sigA.v64 | UINT64_C( 0x0001000000000000 ), - sigA.v0, - sigB.v64, - sigB.v0 - ); - --expZ; - if ( sigZ.v64 < UINT64_C( 0x0002000000000000 ) ) goto roundAndPack; - ++expZ; - shiftRight1: - sig128Extra = - softfloat_shortShiftRightJam128Extra( - sigZ.v64, sigZ.v0, sigZExtra, 1 ); - sigZ = sig128Extra.v; - sigZExtra = sig128Extra.extra; - roundAndPack: - return - softfloat_roundPackToF128( signZ, expZ, sigZ.v64, sigZ.v0, sigZExtra ); - propagateNaN: - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF16.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF16.c deleted file mode 100644 index abc42b8ae..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF16.c +++ /dev/null @@ -1,183 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t softfloat_addMagsF16( uint_fast16_t uiA, uint_fast16_t uiB ) -{ - int_fast8_t expA; - uint_fast16_t sigA; - int_fast8_t expB; - uint_fast16_t sigB; - int_fast8_t expDiff; - uint_fast16_t uiZ; - bool signZ; - int_fast8_t expZ; - uint_fast16_t sigZ; - uint_fast16_t sigX, sigY; - int_fast8_t shiftDist; - uint_fast32_t sig32Z; - int_fast8_t roundingMode; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expF16UI( uiA ); - sigA = fracF16UI( uiA ); - expB = expF16UI( uiB ); - sigB = fracF16UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( ! expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( ! expA ) { - uiZ = uiA + sigB; - goto uiZ; - } - if ( expA == 0x1F ) { - if ( sigA | sigB ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - signZ = signF16UI( uiA ); - expZ = expA; - sigZ = 0x0800 + sigA + sigB; - if ( ! (sigZ & 1) && (expZ < 0x1E) ) { - sigZ >>= 1; - goto pack; - } - sigZ <<= 3; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - signZ = signF16UI( uiA ); - if ( expDiff < 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - if ( expB == 0x1F ) { - if ( sigB ) goto propagateNaN; - uiZ = packToF16UI( signZ, 0x1F, 0 ); - goto uiZ; - } - if ( expDiff <= -13 ) { - uiZ = packToF16UI( signZ, expB, sigB ); - if ( expA | sigA ) goto addEpsilon; - goto uiZ; - } - expZ = expB; - sigX = sigB | 0x0400; - sigY = sigA + (expA ? 0x0400 : sigA); - shiftDist = 19 + expDiff; - } else { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - uiZ = uiA; - if ( expA == 0x1F ) { - if ( sigA ) goto propagateNaN; - goto uiZ; - } - if ( 13 <= expDiff ) { - if ( expB | sigB ) goto addEpsilon; - goto uiZ; - } - expZ = expA; - sigX = sigA | 0x0400; - sigY = sigB + (expB ? 0x0400 : sigB); - shiftDist = 19 - expDiff; - } - sig32Z = - ((uint_fast32_t) sigX<<19) + ((uint_fast32_t) sigY<>16; - if ( sig32Z & 0xFFFF ) { - sigZ |= 1; - } else { - if ( ! (sigZ & 0xF) && (expZ < 0x1E) ) { - sigZ >>= 4; - goto pack; - } - } - } - return softfloat_roundPackToF16( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - addEpsilon: - roundingMode = softfloat_roundingMode; - if ( roundingMode != softfloat_round_near_even ) { - if ( - roundingMode - == (signF16UI( uiZ ) ? softfloat_round_min - : softfloat_round_max) - ) { - ++uiZ; - if ( (uint16_t) (uiZ<<1) == 0xF800 ) { - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - } - } -#ifdef SOFTFLOAT_ROUND_ODD - else if ( roundingMode == softfloat_round_odd ) { - uiZ |= 1; - } -#endif - } - softfloat_exceptionFlags |= softfloat_flag_inexact; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - pack: - uiZ = packToF16UI( signZ, expZ, sigZ ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF32.c deleted file mode 100644 index ed85bb00b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF32.c +++ /dev/null @@ -1,126 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -float32_t softfloat_addMagsF32( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - int_fast16_t expA; - uint_fast32_t sigA; - int_fast16_t expB; - uint_fast32_t sigB; - int_fast16_t expDiff; - uint_fast32_t uiZ; - bool signZ; - int_fast16_t expZ; - uint_fast32_t sigZ; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( ! expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( ! expA ) { - uiZ = uiA + sigB; - goto uiZ; - } - if ( expA == 0xFF ) { - if ( sigA | sigB ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - signZ = signF32UI( uiA ); - expZ = expA; - sigZ = 0x01000000 + sigA + sigB; - if ( ! (sigZ & 1) && (expZ < 0xFE) ) { - uiZ = packToF32UI( signZ, expZ, sigZ>>1 ); - goto uiZ; - } - sigZ <<= 6; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - signZ = signF32UI( uiA ); - sigA <<= 6; - sigB <<= 6; - if ( expDiff < 0 ) { - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN; - uiZ = packToF32UI( signZ, 0xFF, 0 ); - goto uiZ; - } - expZ = expB; - sigA += expA ? 0x20000000 : sigA; - sigA = softfloat_shiftRightJam32( sigA, -expDiff ); - } else { - if ( expA == 0xFF ) { - if ( sigA ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - expZ = expA; - sigB += expB ? 0x20000000 : sigB; - sigB = softfloat_shiftRightJam32( sigB, expDiff ); - } - sigZ = 0x20000000 + sigA + sigB; - if ( sigZ < 0x40000000 ) { - --expZ; - sigZ <<= 1; - } - } - return softfloat_roundPackToF32( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF64.c deleted file mode 100644 index 25b8f386e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_addMagsF64.c +++ /dev/null @@ -1,128 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -float64_t - softfloat_addMagsF64( uint_fast64_t uiA, uint_fast64_t uiB, bool signZ ) -{ - int_fast16_t expA; - uint_fast64_t sigA; - int_fast16_t expB; - uint_fast64_t sigB; - int_fast16_t expDiff; - uint_fast64_t uiZ; - int_fast16_t expZ; - uint_fast64_t sigZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( ! expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( ! expA ) { - uiZ = uiA + sigB; - goto uiZ; - } - if ( expA == 0x7FF ) { - if ( sigA | sigB ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - expZ = expA; - sigZ = UINT64_C( 0x0020000000000000 ) + sigA + sigB; - sigZ <<= 9; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sigA <<= 9; - sigB <<= 9; - if ( expDiff < 0 ) { - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN; - uiZ = packToF64UI( signZ, 0x7FF, 0 ); - goto uiZ; - } - expZ = expB; - if ( expA ) { - sigA += UINT64_C( 0x2000000000000000 ); - } else { - sigA <<= 1; - } - sigA = softfloat_shiftRightJam64( sigA, -expDiff ); - } else { - if ( expA == 0x7FF ) { - if ( sigA ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - expZ = expA; - if ( expB ) { - sigB += UINT64_C( 0x2000000000000000 ); - } else { - sigB <<= 1; - } - sigB = softfloat_shiftRightJam64( sigB, expDiff ); - } - sigZ = UINT64_C( 0x2000000000000000 ) + sigA + sigB; - if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { - --expZ; - sigZ <<= 1; - } - } - return softfloat_roundPackToF64( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecip32_1.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecip32_1.c deleted file mode 100644 index f4fdbfe5b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecip32_1.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_approxRecip32_1 - -extern const uint16_t softfloat_approxRecip_1k0s[16]; -extern const uint16_t softfloat_approxRecip_1k1s[16]; - -uint32_t softfloat_approxRecip32_1( uint32_t a ) -{ - int index; - uint16_t eps, r0; - uint32_t sigma0; - uint_fast32_t r; - uint32_t sqrSigma0; - - index = a>>27 & 0xF; - eps = (uint16_t) (a>>11); - r0 = softfloat_approxRecip_1k0s[index] - - ((softfloat_approxRecip_1k1s[index] * (uint_fast32_t) eps)>>20); - sigma0 = ~(uint_fast32_t) ((r0 * (uint_fast64_t) a)>>7); - r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) sigma0)>>24); - sqrSigma0 = ((uint_fast64_t) sigma0 * sigma0)>>32; - r += ((uint32_t) r * (uint_fast64_t) sqrSigma0)>>48; - return r; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecipSqrt32_1.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecipSqrt32_1.c deleted file mode 100644 index 28eca6495..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecipSqrt32_1.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_approxRecipSqrt32_1 - -extern const uint16_t softfloat_approxRecipSqrt_1k0s[]; -extern const uint16_t softfloat_approxRecipSqrt_1k1s[]; - -uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a ) -{ - int index; - uint16_t eps, r0; - uint_fast32_t ESqrR0; - uint32_t sigma0; - uint_fast32_t r; - uint32_t sqrSigma0; - - index = (a>>27 & 0xE) + oddExpA; - eps = (uint16_t) (a>>12); - r0 = softfloat_approxRecipSqrt_1k0s[index] - - ((softfloat_approxRecipSqrt_1k1s[index] * (uint_fast32_t) eps) - >>20); - ESqrR0 = (uint_fast32_t) r0 * r0; - if ( ! oddExpA ) ESqrR0 <<= 1; - sigma0 = ~(uint_fast32_t) (((uint32_t) ESqrR0 * (uint_fast64_t) a)>>23); - r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) sigma0)>>25); - sqrSigma0 = ((uint_fast64_t) sigma0 * sigma0)>>32; - r += ((uint32_t) ((r>>1) + (r>>3) - ((uint_fast32_t) r0<<14)) - * (uint_fast64_t) sqrSigma0) - >>48; - if ( ! (r & 0x80000000) ) r = 0x80000000; - return r; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecipSqrt_1Ks.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecipSqrt_1Ks.c deleted file mode 100644 index 7a8663b51..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecipSqrt_1Ks.c +++ /dev/null @@ -1,49 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" - -const uint16_t softfloat_approxRecipSqrt_1k0s[16] = { - 0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29, - 0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1 -}; -const uint16_t softfloat_approxRecipSqrt_1k1s[16] = { - 0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6, - 0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD -}; - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecip_1Ks.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecip_1Ks.c deleted file mode 100644 index 54b1b0fab..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_approxRecip_1Ks.c +++ /dev/null @@ -1,49 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" - -const uint16_t softfloat_approxRecip_1k0s[16] = { - 0xFFC4, 0xF0BE, 0xE363, 0xD76F, 0xCCAD, 0xC2F0, 0xBA16, 0xB201, - 0xAA97, 0xA3C6, 0x9D7A, 0x97A6, 0x923C, 0x8D32, 0x887E, 0x8417 -}; -const uint16_t softfloat_approxRecip_1k1s[16] = { - 0xF0F1, 0xD62C, 0xBFA1, 0xAC77, 0x9C0A, 0x8DDB, 0x8185, 0x76BA, - 0x6D3B, 0x64D4, 0x5D5C, 0x56B1, 0x50B6, 0x4B55, 0x4679, 0x4211 -}; - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_compare128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_compare128M.c deleted file mode 100644 index 8f1218209..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_compare128M.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_compare128M - -int_fast8_t softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr ) -{ - unsigned int index, lastIndex; - uint32_t wordA, wordB; - - index = indexWordHi( 4 ); - lastIndex = indexWordLo( 4 ); - for (;;) { - wordA = aPtr[index]; - wordB = bPtr[index]; - if ( wordA != wordB ) return (wordA < wordB) ? -1 : 1; - if ( index == lastIndex ) break; - index -= wordIncr; - } - return 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_compare96M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_compare96M.c deleted file mode 100644 index 8fdf71861..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_compare96M.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_compare96M - -int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr ) -{ - unsigned int index, lastIndex; - uint32_t wordA, wordB; - - index = indexWordHi( 3 ); - lastIndex = indexWordLo( 3 ); - for (;;) { - wordA = aPtr[index]; - wordB = bPtr[index]; - if ( wordA != wordB ) return (wordA < wordB) ? -1 : 1; - if ( index == lastIndex ) break; - index -= wordIncr; - } - return 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_compareNonnormExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_compareNonnormExtF80M.c deleted file mode 100644 index 6712e5764..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_compareNonnormExtF80M.c +++ /dev/null @@ -1,111 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat_types.h" - -int - softfloat_compareNonnormExtF80M( - const struct extFloat80M *aSPtr, const struct extFloat80M *bSPtr ) -{ - uint_fast16_t uiA64, uiB64; - uint64_t sigA; - bool signB; - uint64_t sigB; - int32_t expA, expB; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA64 = aSPtr->signExp; - uiB64 = bSPtr->signExp; - sigA = aSPtr->signif; - signB = signExtF80UI64( uiB64 ); - sigB = bSPtr->signif; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( (uiA64 ^ uiB64) & 0x8000 ) { - if ( ! (sigA | sigB) ) return 0; - goto resultFromSignB; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expExtF80UI64( uiA64 ); - expB = expExtF80UI64( uiB64 ); - if ( expA == 0x7FFF ) { - if (expB == 0x7FFF) return 0; - signB = ! signB; - goto resultFromSignB; - } - if ( expB == 0x7FFF ) { - goto resultFromSignB; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) expA = 1; - if ( ! (sigA & UINT64_C( 0x8000000000000000 )) ) { - if ( sigA ) { - expA += softfloat_normExtF80SigM( &sigA ); - } else { - expA = -128; - } - } - if ( ! expB ) expB = 1; - if ( ! (sigB & UINT64_C( 0x8000000000000000 )) ) { - if ( sigB ) { - expB += softfloat_normExtF80SigM( &sigB ); - } else { - expB = -128; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signB ) { - if ( expA < expB ) return 1; - if ( (expB < expA) || (sigB < sigA) ) return -1; - } else { - if ( expB < expA ) return 1; - if ( (expA < expB) || (sigA < sigB) ) return -1; - } - return (sigA != sigB); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - resultFromSignB: - return signB ? 1 : -1; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros16.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros16.c deleted file mode 100644 index af2831cc9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros16.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_countLeadingZeros16 - -#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16 -#include "primitives.h" - -uint_fast8_t softfloat_countLeadingZeros16( uint16_t a ) -{ - uint_fast8_t count; - - count = 8; - if ( 0x100 <= a ) { - count = 0; - a >>= 8; - } - count += softfloat_countLeadingZeros8[a]; - return count; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros32.c deleted file mode 100644 index a7c50cd45..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros32.c +++ /dev/null @@ -1,64 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_countLeadingZeros32 - -#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32 -#include "primitives.h" - -uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) -{ - uint_fast8_t count; - - count = 0; - if ( a < 0x10000 ) { - count = 16; - a <<= 16; - } - if ( a < 0x1000000 ) { - count += 8; - a <<= 8; - } - count += softfloat_countLeadingZeros8[a>>24]; - return count; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros64.c deleted file mode 100644 index 34745b12e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros64.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_countLeadingZeros64 - -#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64 -#include "primitives.h" - -uint_fast8_t softfloat_countLeadingZeros64( uint64_t a ) -{ - uint_fast8_t count; - uint32_t a32; - - count = 0; - a32 = a>>32; - if ( ! a32 ) { - count = 32; - a32 = a; - } - /*------------------------------------------------------------------------ - | From here, result is current count + count leading zeros of `a32'. - *------------------------------------------------------------------------*/ - if ( a32 < 0x10000 ) { - count += 16; - a32 <<= 16; - } - if ( a32 < 0x1000000 ) { - count += 8; - a32 <<= 8; - } - count += softfloat_countLeadingZeros8[a32>>24]; - return count; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros8.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros8.c deleted file mode 100644 index 0cc60a110..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_countLeadingZeros8.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" - -const uint_least8_t softfloat_countLeadingZeros8[256] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_eq128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_eq128.c deleted file mode 100644 index 1ccc24354..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_eq128.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" - -#ifndef softfloat_eq128 - -bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - - return (a64 == b64) && (a0 == b0); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_invalidExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_invalidExtF80M.c deleted file mode 100644 index d33047867..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_invalidExtF80M.c +++ /dev/null @@ -1,49 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -void softfloat_invalidExtF80M( struct extFloat80M *zSPtr ) -{ - - softfloat_raiseFlags( softfloat_flag_invalid ); - zSPtr->signExp = defaultNaNExtF80UI64; - zSPtr->signif = defaultNaNExtF80UI0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_invalidF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_invalidF128M.c deleted file mode 100644 index ee63cc3b7..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_invalidF128M.c +++ /dev/null @@ -1,53 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitives.h" -#include "specialize.h" -#include "softfloat.h" - -void softfloat_invalidF128M( uint32_t *zWPtr ) -{ - - softfloat_raiseFlags( softfloat_flag_invalid ); - zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96; - zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64; - zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32; - zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_isNaNF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_isNaNF128M.c deleted file mode 100644 index c73e49b44..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_isNaNF128M.c +++ /dev/null @@ -1,57 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "primitives.h" - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -bool softfloat_isNaNF128M( const uint32_t *aWPtr ) -{ - uint32_t uiA96; - - uiA96 = aWPtr[indexWordHi( 4 )]; - if ( (~uiA96 & 0x7FFF0000) != 0 ) return false; - return - ((uiA96 & 0x0000FFFF) != 0) - || ((aWPtr[indexWord( 4, 2 )] | aWPtr[indexWord( 4, 1 )] - | aWPtr[indexWord( 4, 0 )]) - != 0); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_le128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_le128.c deleted file mode 100644 index da3d62427..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_le128.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" - -#ifndef softfloat_le128 - -bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - - return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_lt128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_lt128.c deleted file mode 100644 index b78199174..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_lt128.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" - -#ifndef softfloat_lt128 - -bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - - return (a64 < b64) || ((a64 == b64) && (a0 < b0)); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128By32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128By32.c deleted file mode 100644 index df32ee730..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128By32.c +++ /dev/null @@ -1,58 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_mul128By32 - -struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) -{ - struct uint128 z; - uint_fast64_t mid; - uint_fast32_t carry; - - z.v0 = a0 * b; - mid = (uint_fast64_t) (uint32_t) (a0>>32) * b; - carry = (uint32_t) ((uint_fast32_t) (z.v0>>32) - (uint_fast32_t) mid); - z.v64 = a64 * b + (uint_fast32_t) ((mid + carry)>>32); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128MTo256M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128MTo256M.c deleted file mode 100644 index 68d272ea1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128MTo256M.c +++ /dev/null @@ -1,100 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_mul128MTo256M - -void - softfloat_mul128MTo256M( - const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr ) -{ - uint32_t *lastZPtr, wordB; - uint64_t dwordProd; - uint32_t wordZ; - uint_fast8_t carry; - - bPtr += indexWordLo( 4 ); - lastZPtr = zPtr + indexMultiwordHi( 8, 5 ); - zPtr += indexMultiwordLo( 8, 5 ); - wordB = *bPtr; - dwordProd = (uint64_t) aPtr[indexWord( 4, 0 )] * wordB; - zPtr[indexWord( 5, 0 )] = dwordProd; - dwordProd = (uint64_t) aPtr[indexWord( 4, 1 )] * wordB + (dwordProd>>32); - zPtr[indexWord( 5, 1 )] = dwordProd; - dwordProd = (uint64_t) aPtr[indexWord( 4, 2 )] * wordB + (dwordProd>>32); - zPtr[indexWord( 5, 2 )] = dwordProd; - dwordProd = (uint64_t) aPtr[indexWord( 4, 3 )] * wordB + (dwordProd>>32); - zPtr[indexWord( 5, 3 )] = dwordProd; - zPtr[indexWord( 5, 4 )] = dwordProd>>32; - do { - bPtr += wordIncr; - zPtr += wordIncr; - wordB = *bPtr; - dwordProd = (uint64_t) aPtr[indexWord( 4, 0 )] * wordB; - wordZ = zPtr[indexWord( 5, 0 )] + (uint32_t) dwordProd; - zPtr[indexWord( 5, 0 )] = wordZ; - carry = (wordZ < (uint32_t) dwordProd); - dwordProd = - (uint64_t) aPtr[indexWord( 4, 1 )] * wordB + (dwordProd>>32); - wordZ = zPtr[indexWord( 5, 1 )] + (uint32_t) dwordProd + carry; - zPtr[indexWord( 5, 1 )] = wordZ; - if ( wordZ != (uint32_t) dwordProd ) { - carry = (wordZ < (uint32_t) dwordProd); - } - dwordProd = - (uint64_t) aPtr[indexWord( 4, 2 )] * wordB + (dwordProd>>32); - wordZ = zPtr[indexWord( 5, 2 )] + (uint32_t) dwordProd + carry; - zPtr[indexWord( 5, 2 )] = wordZ; - if ( wordZ != (uint32_t) dwordProd ) { - carry = (wordZ < (uint32_t) dwordProd); - } - dwordProd = - (uint64_t) aPtr[indexWord( 4, 3 )] * wordB + (dwordProd>>32); - wordZ = zPtr[indexWord( 5, 3 )] + (uint32_t) dwordProd + carry; - zPtr[indexWord( 5, 3 )] = wordZ; - if ( wordZ != (uint32_t) dwordProd ) { - carry = (wordZ < (uint32_t) dwordProd); - } - zPtr[indexWord( 5, 4 )] = (dwordProd>>32) + carry; - } while ( zPtr != lastZPtr ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128To256M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128To256M.c deleted file mode 100644 index 91df8f223..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul128To256M.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_mul128To256M - -#define softfloat_mul128To256M softfloat_mul128To256M -#include "primitives.h" - -void - softfloat_mul128To256M( - uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr ) -{ - struct uint128 p0, p64, p128; - uint_fast64_t z64, z128, z192; - - p0 = softfloat_mul64To128( a0, b0 ); - zPtr[indexWord( 4, 0 )] = p0.v0; - p64 = softfloat_mul64To128( a64, b0 ); - z64 = p64.v0 + p0.v64; - z128 = p64.v64 + (z64 < p64.v0); - p128 = softfloat_mul64To128( a64, b64 ); - z128 += p128.v0; - z192 = p128.v64 + (z128 < p128.v0); - p64 = softfloat_mul64To128( a0, b64 ); - z64 += p64.v0; - zPtr[indexWord( 4, 1 )] = z64; - p64.v64 += (z64 < p64.v0); - z128 += p64.v64; - zPtr[indexWord( 4, 2 )] = z128; - zPtr[indexWord( 4, 3 )] = z192 + (z128 < p64.v64); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64ByShifted32To128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64ByShifted32To128.c deleted file mode 100644 index ea8d486a1..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64ByShifted32To128.c +++ /dev/null @@ -1,56 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_mul64ByShifted32To128 - -struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) -{ - uint_fast64_t mid; - struct uint128 z; - - mid = (uint_fast64_t) (uint32_t) a * b; - z.v0 = mid<<32; - z.v64 = (uint_fast64_t) (uint32_t) (a>>32) * b + (mid>>32); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64To128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64To128.c deleted file mode 100644 index 0a3c2b992..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64To128.c +++ /dev/null @@ -1,66 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_mul64To128 - -struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ) -{ - uint32_t a32, a0, b32, b0; - struct uint128 z; - uint64_t mid1, mid; - - a32 = a>>32; - a0 = a; - b32 = b>>32; - b0 = b; - z.v0 = (uint_fast64_t) a0 * b0; - mid1 = (uint_fast64_t) a32 * b0; - mid = mid1 + (uint_fast64_t) a0 * b32; - z.v64 = (uint_fast64_t) a32 * b32; - z.v64 += (uint_fast64_t) (mid < mid1)<<32 | mid>>32; - mid <<= 32; - z.v0 += mid; - z.v64 += (z.v0 < mid); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64To128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64To128M.c deleted file mode 100644 index cd1528978..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mul64To128M.c +++ /dev/null @@ -1,68 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_mul64To128M - -void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr ) -{ - uint32_t a32, a0, b32, b0; - uint64_t z0, mid1, z64, mid; - - a32 = a>>32; - a0 = a; - b32 = b>>32; - b0 = b; - z0 = (uint64_t) a0 * b0; - mid1 = (uint64_t) a32 * b0; - mid = mid1 + (uint64_t) a0 * b32; - z64 = (uint64_t) a32 * b32; - z64 += (uint64_t) (mid < mid1)<<32 | mid>>32; - mid <<= 32; - z0 += mid; - zPtr[indexWord( 4, 1 )] = z0>>32; - zPtr[indexWord( 4, 0 )] = z0; - z64 += (z0 < mid); - zPtr[indexWord( 4, 3 )] = z64>>32; - zPtr[indexWord( 4, 2 )] = z64; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF128.c deleted file mode 100644 index 9b98b9f64..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF128.c +++ /dev/null @@ -1,350 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t - softfloat_mulAddF128( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0, - uint_fast64_t uiC64, - uint_fast64_t uiC0, - uint_fast8_t op - ) -{ - bool signA; - int_fast32_t expA; - struct uint128 sigA; - bool signB; - int_fast32_t expB; - struct uint128 sigB; - bool signC; - int_fast32_t expC; - struct uint128 sigC; - bool signZ; - uint_fast64_t magBits; - struct uint128 uiZ; - struct exp32_sig128 normExpSig; - int_fast32_t expZ; - uint64_t sig256Z[4]; - struct uint128 sigZ; - int_fast32_t shiftDist, expDiff; - struct uint128 x128; - uint64_t sig256C[4]; - static uint64_t zero256[4] = INIT_UINTM4( 0, 0, 0, 0 ); - uint_fast64_t sigZExtra, sig256Z0; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signF128UI64( uiA64 ); - expA = expF128UI64( uiA64 ); - sigA.v64 = fracF128UI64( uiA64 ); - sigA.v0 = uiA0; - signB = signF128UI64( uiB64 ); - expB = expF128UI64( uiB64 ); - sigB.v64 = fracF128UI64( uiB64 ); - sigB.v0 = uiB0; - signC = signF128UI64( uiC64 ) ^ (op == softfloat_mulAdd_subC); - expC = expF128UI64( uiC64 ); - sigC.v64 = fracF128UI64( uiC64 ); - sigC.v0 = uiC0; - signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FFF ) { - if ( - (sigA.v64 | sigA.v0) || ((expB == 0x7FFF) && (sigB.v64 | sigB.v0)) - ) { - goto propagateNaN_ABC; - } - magBits = expB | sigB.v64 | sigB.v0; - goto infProdArg; - } - if ( expB == 0x7FFF ) { - if ( sigB.v64 | sigB.v0 ) goto propagateNaN_ABC; - magBits = expA | sigA.v64 | sigA.v0; - goto infProdArg; - } - if ( expC == 0x7FFF ) { - if ( sigC.v64 | sigC.v0 ) { - uiZ.v64 = 0; - uiZ.v0 = 0; - goto propagateNaN_ZC; - } - uiZ.v64 = uiC64; - uiZ.v0 = uiC0; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! (sigA.v64 | sigA.v0) ) goto zeroProd; - normExpSig = softfloat_normSubnormalF128Sig( sigA.v64, sigA.v0 ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! (sigB.v64 | sigB.v0) ) goto zeroProd; - normExpSig = softfloat_normSubnormalF128Sig( sigB.v64, sigB.v0 ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x3FFE; - sigA.v64 |= UINT64_C( 0x0001000000000000 ); - sigB.v64 |= UINT64_C( 0x0001000000000000 ); - sigA = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 8 ); - sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 15 ); - softfloat_mul128To256M( sigA.v64, sigA.v0, sigB.v64, sigB.v0, sig256Z ); - sigZ.v64 = sig256Z[indexWord( 4, 3 )]; - sigZ.v0 = sig256Z[indexWord( 4, 2 )]; - shiftDist = 0; - if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) { - --expZ; - shiftDist = -1; - } - if ( ! expC ) { - if ( ! (sigC.v64 | sigC.v0) ) { - shiftDist += 8; - goto sigZ; - } - normExpSig = softfloat_normSubnormalF128Sig( sigC.v64, sigC.v0 ); - expC = normExpSig.exp; - sigC = normExpSig.sig; - } - sigC.v64 |= UINT64_C( 0x0001000000000000 ); - sigC = softfloat_shortShiftLeft128( sigC.v64, sigC.v0, 8 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expZ - expC; - if ( expDiff < 0 ) { - expZ = expC; - if ( (signZ == signC) || (expDiff < -1) ) { - shiftDist -= expDiff; - if ( shiftDist ) { - sigZ = - softfloat_shiftRightJam128( sigZ.v64, sigZ.v0, shiftDist ); - } - } else { - if ( ! shiftDist ) { - x128 = - softfloat_shortShiftRight128( - sig256Z[indexWord( 4, 1 )], sig256Z[indexWord( 4, 0 )], - 1 - ); - sig256Z[indexWord( 4, 1 )] = (sigZ.v0<<63) | x128.v64; - sig256Z[indexWord( 4, 0 )] = x128.v0; - sigZ = softfloat_shortShiftRight128( sigZ.v64, sigZ.v0, 1 ); - sig256Z[indexWord( 4, 3 )] = sigZ.v64; - sig256Z[indexWord( 4, 2 )] = sigZ.v0; - } - } - } else { - if ( shiftDist ) softfloat_add256M( sig256Z, sig256Z, sig256Z ); - if ( ! expDiff ) { - sigZ.v64 = sig256Z[indexWord( 4, 3 )]; - sigZ.v0 = sig256Z[indexWord( 4, 2 )]; - } else { - sig256C[indexWord( 4, 3 )] = sigC.v64; - sig256C[indexWord( 4, 2 )] = sigC.v0; - sig256C[indexWord( 4, 1 )] = 0; - sig256C[indexWord( 4, 0 )] = 0; - softfloat_shiftRightJam256M( sig256C, expDiff, sig256C ); - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - shiftDist = 8; - if ( signZ == signC ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff <= 0 ) { - sigZ = softfloat_add128( sigC.v64, sigC.v0, sigZ.v64, sigZ.v0 ); - } else { - softfloat_add256M( sig256Z, sig256C, sig256Z ); - sigZ.v64 = sig256Z[indexWord( 4, 3 )]; - sigZ.v0 = sig256Z[indexWord( 4, 2 )]; - } - if ( sigZ.v64 & UINT64_C( 0x0200000000000000 ) ) { - ++expZ; - shiftDist = 9; - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff < 0 ) { - signZ = signC; - if ( expDiff < -1 ) { - sigZ = - softfloat_sub128( sigC.v64, sigC.v0, sigZ.v64, sigZ.v0 ); - sigZExtra = - sig256Z[indexWord( 4, 1 )] | sig256Z[indexWord( 4, 0 )]; - if ( sigZExtra ) { - sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, 0, 1 ); - } - if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) { - --expZ; - shiftDist = 7; - } - goto shiftRightRoundPack; - } else { - sig256C[indexWord( 4, 3 )] = sigC.v64; - sig256C[indexWord( 4, 2 )] = sigC.v0; - sig256C[indexWord( 4, 1 )] = 0; - sig256C[indexWord( 4, 0 )] = 0; - softfloat_sub256M( sig256C, sig256Z, sig256Z ); - } - } else if ( ! expDiff ) { - sigZ = softfloat_sub128( sigZ.v64, sigZ.v0, sigC.v64, sigC.v0 ); - if ( - ! (sigZ.v64 | sigZ.v0) && ! sig256Z[indexWord( 4, 1 )] - && ! sig256Z[indexWord( 4, 0 )] - ) { - goto completeCancellation; - } - sig256Z[indexWord( 4, 3 )] = sigZ.v64; - sig256Z[indexWord( 4, 2 )] = sigZ.v0; - if ( sigZ.v64 & UINT64_C( 0x8000000000000000 ) ) { - signZ = ! signZ; - softfloat_sub256M( zero256, sig256Z, sig256Z ); - } - } else { - softfloat_sub256M( sig256Z, sig256C, sig256Z ); - if ( 1 < expDiff ) { - sigZ.v64 = sig256Z[indexWord( 4, 3 )]; - sigZ.v0 = sig256Z[indexWord( 4, 2 )]; - if ( ! (sigZ.v64 & UINT64_C( 0x0100000000000000 )) ) { - --expZ; - shiftDist = 7; - } - goto sigZ; - } - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sigZ.v64 = sig256Z[indexWord( 4, 3 )]; - sigZ.v0 = sig256Z[indexWord( 4, 2 )]; - sigZExtra = sig256Z[indexWord( 4, 1 )]; - sig256Z0 = sig256Z[indexWord( 4, 0 )]; - if ( sigZ.v64 ) { - if ( sig256Z0 ) sigZExtra |= 1; - } else { - expZ -= 64; - sigZ.v64 = sigZ.v0; - sigZ.v0 = sigZExtra; - sigZExtra = sig256Z0; - if ( ! sigZ.v64 ) { - expZ -= 64; - sigZ.v64 = sigZ.v0; - sigZ.v0 = sigZExtra; - sigZExtra = 0; - if ( ! sigZ.v64 ) { - expZ -= 64; - sigZ.v64 = sigZ.v0; - sigZ.v0 = 0; - } - } - } - shiftDist = softfloat_countLeadingZeros64( sigZ.v64 ); - expZ += 7 - shiftDist; - shiftDist = 15 - shiftDist; - if ( 0 < shiftDist ) goto shiftRightRoundPack; - if ( shiftDist ) { - shiftDist = -shiftDist; - sigZ = softfloat_shortShiftLeft128( sigZ.v64, sigZ.v0, shiftDist ); - x128 = softfloat_shortShiftLeft128( 0, sigZExtra, shiftDist ); - sigZ.v0 |= x128.v64; - sigZExtra = x128.v0; - } - goto roundPack; - } - sigZ: - sigZExtra = sig256Z[indexWord( 4, 1 )] | sig256Z[indexWord( 4, 0 )]; - shiftRightRoundPack: - sigZExtra = (uint64_t) (sigZ.v0<<(64 - shiftDist)) | (sigZExtra != 0); - sigZ = softfloat_shortShiftRight128( sigZ.v64, sigZ.v0, shiftDist ); - roundPack: - return - softfloat_roundPackToF128( - signZ, expZ - 1, sigZ.v64, sigZ.v0, sigZExtra ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN_ABC: - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); - goto propagateNaN_ZC; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infProdArg: - if ( magBits ) { - uiZ.v64 = packToF128UI64( signZ, 0x7FFF, 0 ); - uiZ.v0 = 0; - if ( expC != 0x7FFF ) goto uiZ; - if ( sigC.v64 | sigC.v0 ) goto propagateNaN_ZC; - if ( signZ == signC ) goto uiZ; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - propagateNaN_ZC: - uiZ = softfloat_propagateNaNF128UI( uiZ.v64, uiZ.v0, uiC64, uiC0 ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zeroProd: - uiZ.v64 = uiC64; - uiZ.v0 = uiC0; - if ( ! (expC | sigC.v64 | sigC.v0) && (signZ != signC) ) { - completeCancellation: - uiZ.v64 = - packToF128UI64( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - uiZ.v0 = 0; - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF128M.c deleted file mode 100644 index 3ed3bae41..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF128M.c +++ /dev/null @@ -1,382 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -void - softfloat_mulAddF128M( - const uint32_t *aWPtr, - const uint32_t *bWPtr, - const uint32_t *cWPtr, - uint32_t *zWPtr, - uint_fast8_t op - ) -{ - uint32_t uiA96; - int32_t expA; - uint32_t uiB96; - int32_t expB; - uint32_t uiC96; - bool signC; - int32_t expC; - bool signProd, prodIsInfinite; - uint32_t *ptr, uiZ96, sigA[4]; - uint_fast8_t shiftDist; - uint32_t sigX[5]; - int32_t expProd; - uint32_t sigProd[8], wordSig; - bool doSub; - uint_fast8_t - (*addCarryMRoutinePtr)( - uint_fast8_t, - const uint32_t *, - const uint32_t *, - uint_fast8_t, - uint32_t * - ); - int32_t expDiff; - bool signZ; - int32_t expZ; - uint32_t *extSigPtr; - uint_fast8_t carry; - void (*roundPackRoutinePtr)( bool, int32_t, uint32_t *, uint32_t * ); - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uiA96 = aWPtr[indexWordHi( 4 )]; - expA = expF128UI96( uiA96 ); - uiB96 = bWPtr[indexWordHi( 4 )]; - expB = expF128UI96( uiB96 ); - uiC96 = cWPtr[indexWordHi( 4 )]; - signC = signF128UI96( uiC96 ) ^ (op == softfloat_mulAdd_subC); - expC = expF128UI96( uiC96 ); - signProd = - signF128UI96( uiA96 ) ^ signF128UI96( uiB96 ) - ^ (op == softfloat_mulAdd_subProd); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - prodIsInfinite = false; - if ( (expA == 0x7FFF) || (expB == 0x7FFF) ) { - if ( softfloat_tryPropagateNaNF128M( aWPtr, bWPtr, zWPtr ) ) { - goto propagateNaN_ZC; - } - ptr = (uint32_t *) aWPtr; - if ( ! (uint32_t) (uiA96<<1) ) goto possibleInvalidProd; - if ( ! (uint32_t) (uiB96<<1) ) { - ptr = (uint32_t *) bWPtr; - possibleInvalidProd: - if ( - ! (ptr[indexWord( 4, 2 )] | ptr[indexWord( 4, 1 )] - | ptr[indexWord( 4, 0 )]) - ) { - goto invalid; - } - } - prodIsInfinite = true; - } - if ( expC == 0x7FFF ) { - if ( - fracF128UI96( uiC96 ) - || (cWPtr[indexWord( 4, 2 )] | cWPtr[indexWord( 4, 1 )] - | cWPtr[indexWord( 4, 0 )]) - ) { - zWPtr[indexWordHi( 4 )] = 0; - goto propagateNaN_ZC; - } - if ( prodIsInfinite && (signProd != signC) ) goto invalid; - goto copyC; - } - if ( prodIsInfinite ) { - uiZ96 = packToF128UI96( signProd, 0x7FFF, 0 ); - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA ) { - sigA[indexWordHi( 4 )] = fracF128UI96( uiA96 ) | 0x00010000; - sigA[indexWord( 4, 2 )] = aWPtr[indexWord( 4, 2 )]; - sigA[indexWord( 4, 1 )] = aWPtr[indexWord( 4, 1 )]; - sigA[indexWord( 4, 0 )] = aWPtr[indexWord( 4, 0 )]; - } else { - expA = softfloat_shiftNormSigF128M( aWPtr, 0, sigA ); - if ( expA == -128 ) goto zeroProd; - } - if ( expB ) { - sigX[indexWordHi( 4 )] = fracF128UI96( uiB96 ) | 0x00010000; - sigX[indexWord( 4, 2 )] = bWPtr[indexWord( 4, 2 )]; - sigX[indexWord( 4, 1 )] = bWPtr[indexWord( 4, 1 )]; - sigX[indexWord( 4, 0 )] = bWPtr[indexWord( 4, 0 )]; - } else { - expB = softfloat_shiftNormSigF128M( bWPtr, 0, sigX ); - if ( expB == -128 ) goto zeroProd; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expProd = expA + expB - 0x3FF0; - softfloat_mul128MTo256M( sigA, sigX, sigProd ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - wordSig = fracF128UI96( uiC96 ); - if ( expC ) { - --expC; - wordSig |= 0x00010000; - } - sigX[indexWordHi( 5 )] = wordSig; - sigX[indexWord( 5, 3 )] = cWPtr[indexWord( 4, 2 )]; - sigX[indexWord( 5, 2 )] = cWPtr[indexWord( 4, 1 )]; - sigX[indexWord( 5, 1 )] = cWPtr[indexWord( 4, 0 )]; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - doSub = (signProd != signC); - addCarryMRoutinePtr = - doSub ? softfloat_addComplCarryM : softfloat_addCarryM; - expDiff = expProd - expC; - if ( expDiff <= 0 ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - signZ = signC; - expZ = expC; - if ( - sigProd[indexWord( 8, 2 )] - || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )]) - ) { - sigProd[indexWord( 8, 3 )] |= 1; - } - extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )]; - if ( expDiff ) { - softfloat_shiftRightJam160M( extSigPtr, -expDiff, extSigPtr ); - } - carry = 0; - if ( doSub ) { - wordSig = extSigPtr[indexWordLo( 5 )]; - extSigPtr[indexWordLo( 5 )] = -wordSig; - carry = ! wordSig; - } - (*addCarryMRoutinePtr)( - 4, - &sigX[indexMultiwordHi( 5, 4 )], - extSigPtr + indexMultiwordHi( 5, 4 ), - carry, - extSigPtr + indexMultiwordHi( 5, 4 ) - ); - wordSig = extSigPtr[indexWordHi( 5 )]; - if ( ! expZ ) { - if ( wordSig & 0x80000000 ) { - signZ = ! signZ; - softfloat_negX160M( extSigPtr ); - wordSig = extSigPtr[indexWordHi( 5 )]; - } - goto checkCancellation; - } - if ( wordSig < 0x00010000 ) { - --expZ; - softfloat_add160M( extSigPtr, extSigPtr, extSigPtr ); - goto roundPack; - } - goto extSigReady_noCancellation; - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - signZ = signProd; - expZ = expProd; - sigX[indexWordLo( 5 )] = 0; - expDiff -= 128; - if ( 0 <= expDiff ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - if ( expDiff ) softfloat_shiftRightJam160M( sigX, expDiff, sigX ); - wordSig = sigX[indexWordLo( 5 )]; - carry = 0; - if ( doSub ) { - carry = ! wordSig; - wordSig = -wordSig; - } - carry = - (*addCarryMRoutinePtr)( - 4, - &sigProd[indexMultiwordLo( 8, 4 )], - &sigX[indexMultiwordHi( 5, 4 )], - carry, - &sigProd[indexMultiwordLo( 8, 4 )] - ); - sigProd[indexWord( 8, 2 )] |= wordSig; - ptr = &sigProd[indexWord( 8, 4 )]; - } else { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - shiftDist = expDiff & 31; - if ( shiftDist ) { - softfloat_shortShiftRight160M( sigX, shiftDist, sigX ); - } - expDiff >>= 5; - extSigPtr = - &sigProd[indexMultiwordLo( 8, 5 )] - wordIncr - + expDiff * -wordIncr; - carry = - (*addCarryMRoutinePtr)( 5, extSigPtr, sigX, doSub, extSigPtr ); - if ( expDiff == -4 ) { - /*------------------------------------------------------------ - *------------------------------------------------------------*/ - wordSig = sigProd[indexWordHi( 8 )]; - if ( wordSig & 0x80000000 ) { - signZ = ! signZ; - softfloat_negX256M( sigProd ); - wordSig = sigProd[indexWordHi( 8 )]; - } - /*------------------------------------------------------------ - *------------------------------------------------------------*/ - if ( wordSig ) goto expProdBigger_noWordShift; - wordSig = sigProd[indexWord( 8, 6 )]; - if ( 0x00040000 <= wordSig ) goto expProdBigger_noWordShift; - expZ -= 32; - extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )] - wordIncr; - for (;;) { - if ( wordSig ) break; - wordSig = extSigPtr[indexWord( 5, 3 )]; - if ( 0x00040000 <= wordSig ) break; - expZ -= 32; - extSigPtr -= wordIncr; - if ( extSigPtr == &sigProd[indexMultiwordLo( 8, 5 )] ) { - goto checkCancellation; - } - } - /*------------------------------------------------------------ - *------------------------------------------------------------*/ - ptr = extSigPtr + indexWordLo( 5 ); - do { - ptr -= wordIncr; - if ( *ptr ) { - extSigPtr[indexWordLo( 5 )] |= 1; - break; - } - } while ( ptr != &sigProd[indexWordLo( 8 )] ); - wordSig = extSigPtr[indexWordHi( 5 )]; - goto extSigReady; - } - ptr = extSigPtr + indexWordHi( 5 ) + wordIncr; - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( carry != doSub ) { - if ( doSub ) { - do { - wordSig = *ptr; - *ptr = wordSig - 1; - ptr += wordIncr; - } while ( ! wordSig ); - } else { - do { - wordSig = *ptr + 1; - *ptr = wordSig; - ptr += wordIncr; - } while ( ! wordSig ); - } - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - expProdBigger_noWordShift: - if ( - sigProd[indexWord( 8, 2 )] - || (sigProd[indexWord( 8, 1 )] | sigProd[indexWord( 8, 0 )]) - ) { - sigProd[indexWord( 8, 3 )] |= 1; - } - extSigPtr = &sigProd[indexMultiwordHi( 8, 5 )]; - wordSig = extSigPtr[indexWordHi( 5 )]; - } - extSigReady: - roundPackRoutinePtr = softfloat_normRoundPackMToF128M; - if ( wordSig < 0x00010000 ) goto doRoundPack; - extSigReady_noCancellation: - if ( 0x00020000 <= wordSig ) { - ++expZ; - softfloat_shortShiftRightJam160M( extSigPtr, 1, extSigPtr ); - } - roundPack: - roundPackRoutinePtr = softfloat_roundPackMToF128M; - doRoundPack: - (*roundPackRoutinePtr)( signZ, expZ, extSigPtr, zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_invalidF128M( zWPtr ); - propagateNaN_ZC: - softfloat_propagateNaNF128M( zWPtr, cWPtr, zWPtr ); - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zeroProd: - if ( - ! (uint32_t) (uiC96<<1) && (signProd != signC) - && ! cWPtr[indexWord( 4, 2 )] - && ! (cWPtr[indexWord( 4, 1 )] | cWPtr[indexWord( 4, 0 )]) - ) { - goto completeCancellation; - } - copyC: - zWPtr[indexWordHi( 4 )] = uiC96; - zWPtr[indexWord( 4, 2 )] = cWPtr[indexWord( 4, 2 )]; - zWPtr[indexWord( 4, 1 )] = cWPtr[indexWord( 4, 1 )]; - zWPtr[indexWord( 4, 0 )] = cWPtr[indexWord( 4, 0 )]; - return; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - checkCancellation: - if ( - wordSig - || (extSigPtr[indexWord( 5, 3 )] | extSigPtr[indexWord( 5, 2 )]) - || (extSigPtr[indexWord( 5, 1 )] | extSigPtr[indexWord( 5, 0 )]) - ) { - goto extSigReady; - } - completeCancellation: - uiZ96 = - packToF128UI96( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - uiZ: - zWPtr[indexWordHi( 4 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF16.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF16.c deleted file mode 100644 index cca4db42b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_mulAddF16.c +++ /dev/null @@ -1,226 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t - softfloat_mulAddF16( - uint_fast16_t uiA, uint_fast16_t uiB, uint_fast16_t uiC, uint_fast8_t op ) -{ - bool signA; - int_fast8_t expA; - uint_fast16_t sigA; - bool signB; - int_fast8_t expB; - uint_fast16_t sigB; - bool signC; - int_fast8_t expC; - uint_fast16_t sigC; - bool signProd; - uint_fast16_t magBits, uiZ; - struct exp8_sig16 normExpSig; - int_fast8_t expProd; - uint_fast32_t sigProd; - bool signZ; - int_fast8_t expZ; - uint_fast16_t sigZ; - int_fast8_t expDiff; - uint_fast32_t sig32Z, sig32C; - int_fast8_t shiftDist; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signF16UI( uiA ); - expA = expF16UI( uiA ); - sigA = fracF16UI( uiA ); - signB = signF16UI( uiB ); - expB = expF16UI( uiB ); - sigB = fracF16UI( uiB ); - signC = signF16UI( uiC ) ^ (op == softfloat_mulAdd_subC); - expC = expF16UI( uiC ); - sigC = fracF16UI( uiC ); - signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x1F ) { - if ( sigA || ((expB == 0x1F) && sigB) ) goto propagateNaN_ABC; - magBits = expB | sigB; - goto infProdArg; - } - if ( expB == 0x1F ) { - if ( sigB ) goto propagateNaN_ABC; - magBits = expA | sigA; - goto infProdArg; - } - if ( expC == 0x1F ) { - if ( sigC ) { - uiZ = 0; - goto propagateNaN_ZC; - } - uiZ = uiC; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) goto zeroProd; - normExpSig = softfloat_normSubnormalF16Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zeroProd; - normExpSig = softfloat_normSubnormalF16Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expProd = expA + expB - 0xE; - sigA = (sigA | 0x0400)<<4; - sigB = (sigB | 0x0400)<<4; - sigProd = (uint_fast32_t) sigA * sigB; - if ( sigProd < 0x20000000 ) { - --expProd; - sigProd <<= 1; - } - signZ = signProd; - if ( ! expC ) { - if ( ! sigC ) { - expZ = expProd - 1; - sigZ = sigProd>>15 | ((sigProd & 0x7FFF) != 0); - goto roundPack; - } - normExpSig = softfloat_normSubnormalF16Sig( sigC ); - expC = normExpSig.exp; - sigC = normExpSig.sig; - } - sigC = (sigC | 0x0400)<<3; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expProd - expC; - if ( signProd == signC ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff <= 0 ) { - expZ = expC; - sigZ = sigC + softfloat_shiftRightJam32( sigProd, 16 - expDiff ); - } else { - expZ = expProd; - sig32Z = - sigProd - + softfloat_shiftRightJam32( - (uint_fast32_t) sigC<<16, expDiff ); - sigZ = sig32Z>>16 | ((sig32Z & 0xFFFF) != 0 ); - } - if ( sigZ < 0x4000 ) { - --expZ; - sigZ <<= 1; - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig32C = (uint_fast32_t) sigC<<16; - if ( expDiff < 0 ) { - signZ = signC; - expZ = expC; - sig32Z = sig32C - softfloat_shiftRightJam32( sigProd, -expDiff ); - } else if ( ! expDiff ) { - expZ = expProd; - sig32Z = sigProd - sig32C; - if ( ! sig32Z ) goto completeCancellation; - if ( sig32Z & 0x80000000 ) { - signZ = ! signZ; - sig32Z = -sig32Z; - } - } else { - expZ = expProd; - sig32Z = sigProd - softfloat_shiftRightJam32( sig32C, expDiff ); - } - shiftDist = softfloat_countLeadingZeros32( sig32Z ) - 1; - expZ -= shiftDist; - shiftDist -= 16; - if ( shiftDist < 0 ) { - sigZ = - sig32Z>>(-shiftDist) - | ((uint32_t) (sig32Z<<(shiftDist & 31)) != 0); - } else { - sigZ = (uint_fast16_t) sig32Z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t - softfloat_mulAddF32( - uint_fast32_t uiA, uint_fast32_t uiB, uint_fast32_t uiC, uint_fast8_t op ) -{ - bool signA; - int_fast16_t expA; - uint_fast32_t sigA; - bool signB; - int_fast16_t expB; - uint_fast32_t sigB; - bool signC; - int_fast16_t expC; - uint_fast32_t sigC; - bool signProd; - uint_fast32_t magBits, uiZ; - struct exp16_sig32 normExpSig; - int_fast16_t expProd; - uint_fast64_t sigProd; - bool signZ; - int_fast16_t expZ; - uint_fast32_t sigZ; - int_fast16_t expDiff; - uint_fast64_t sig64Z, sig64C; - int_fast8_t shiftDist; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - signB = signF32UI( uiB ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - signC = signF32UI( uiC ) ^ (op == softfloat_mulAdd_subC); - expC = expF32UI( uiC ); - sigC = fracF32UI( uiC ); - signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0xFF ) { - if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN_ABC; - magBits = expB | sigB; - goto infProdArg; - } - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN_ABC; - magBits = expA | sigA; - goto infProdArg; - } - if ( expC == 0xFF ) { - if ( sigC ) { - uiZ = 0; - goto propagateNaN_ZC; - } - uiZ = uiC; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) goto zeroProd; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zeroProd; - normExpSig = softfloat_normSubnormalF32Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expProd = expA + expB - 0x7E; - sigA = (sigA | 0x00800000)<<7; - sigB = (sigB | 0x00800000)<<7; - sigProd = (uint_fast64_t) sigA * sigB; - if ( sigProd < UINT64_C( 0x2000000000000000 ) ) { - --expProd; - sigProd <<= 1; - } - signZ = signProd; - if ( ! expC ) { - if ( ! sigC ) { - expZ = expProd - 1; - sigZ = softfloat_shortShiftRightJam64( sigProd, 31 ); - goto roundPack; - } - normExpSig = softfloat_normSubnormalF32Sig( sigC ); - expC = normExpSig.exp; - sigC = normExpSig.sig; - } - sigC = (sigC | 0x00800000)<<6; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expProd - expC; - if ( signProd == signC ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff <= 0 ) { - expZ = expC; - sigZ = sigC + softfloat_shiftRightJam64( sigProd, 32 - expDiff ); - } else { - expZ = expProd; - sig64Z = - sigProd - + softfloat_shiftRightJam64( - (uint_fast64_t) sigC<<32, expDiff ); - sigZ = softfloat_shortShiftRightJam64( sig64Z, 32 ); - } - if ( sigZ < 0x40000000 ) { - --expZ; - sigZ <<= 1; - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - sig64C = (uint_fast64_t) sigC<<32; - if ( expDiff < 0 ) { - signZ = signC; - expZ = expC; - sig64Z = sig64C - softfloat_shiftRightJam64( sigProd, -expDiff ); - } else if ( ! expDiff ) { - expZ = expProd; - sig64Z = sigProd - sig64C; - if ( ! sig64Z ) goto completeCancellation; - if ( sig64Z & UINT64_C( 0x8000000000000000 ) ) { - signZ = ! signZ; - sig64Z = -sig64Z; - } - } else { - expZ = expProd; - sig64Z = sigProd - softfloat_shiftRightJam64( sig64C, expDiff ); - } - shiftDist = softfloat_countLeadingZeros64( sig64Z ) - 1; - expZ -= shiftDist; - shiftDist -= 32; - if ( shiftDist < 0 ) { - sigZ = softfloat_shortShiftRightJam64( sig64Z, -shiftDist ); - } else { - sigZ = (uint_fast32_t) sig64Z< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -float64_t - softfloat_mulAddF64( - uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC, uint_fast8_t op ) -{ - bool signA; - int_fast16_t expA; - uint_fast64_t sigA; - bool signB; - int_fast16_t expB; - uint_fast64_t sigB; - bool signC; - int_fast16_t expC; - uint_fast64_t sigC; - bool signZ; - uint_fast64_t magBits, uiZ; - struct exp16_sig64 normExpSig; - int_fast16_t expZ; - struct uint128 sig128Z; - uint_fast64_t sigZ; - int_fast16_t expDiff; - struct uint128 sig128C; - int_fast8_t shiftDist; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - signB = signF64UI( uiB ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC); - expC = expF64UI( uiC ); - sigC = fracF64UI( uiC ); - signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FF ) { - if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN_ABC; - magBits = expB | sigB; - goto infProdArg; - } - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN_ABC; - magBits = expA | sigA; - goto infProdArg; - } - if ( expC == 0x7FF ) { - if ( sigC ) { - uiZ = 0; - goto propagateNaN_ZC; - } - uiZ = uiC; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) goto zeroProd; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zeroProd; - normExpSig = softfloat_normSubnormalF64Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x3FE; - sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10; - sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<10; - sig128Z = softfloat_mul64To128( sigA, sigB ); - if ( sig128Z.v64 < UINT64_C( 0x2000000000000000 ) ) { - --expZ; - sig128Z = - softfloat_add128( - sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0 ); - } - if ( ! expC ) { - if ( ! sigC ) { - --expZ; - sigZ = sig128Z.v64<<1 | (sig128Z.v0 != 0); - goto roundPack; - } - normExpSig = softfloat_normSubnormalF64Sig( sigC ); - expC = normExpSig.exp; - sigC = normExpSig.sig; - } - sigC = (sigC | UINT64_C( 0x0010000000000000 ))<<9; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expZ - expC; - if ( expDiff < 0 ) { - expZ = expC; - if ( (signZ == signC) || (expDiff < -1) ) { - sig128Z.v64 = softfloat_shiftRightJam64( sig128Z.v64, -expDiff ); - } else { - sig128Z = - softfloat_shortShiftRightJam128( sig128Z.v64, sig128Z.v0, 1 ); - } - } else if ( expDiff ) { - sig128C = softfloat_shiftRightJam128( sigC, 0, expDiff ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signZ == signC ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff <= 0 ) { - sigZ = (sigC + sig128Z.v64) | (sig128Z.v0 != 0); - } else { - sig128Z = - softfloat_add128( - sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0 ); - sigZ = sig128Z.v64 | (sig128Z.v0 != 0); - } - if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { - --expZ; - sigZ <<= 1; - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff < 0 ) { - signZ = signC; - sig128Z = softfloat_sub128( sigC, 0, sig128Z.v64, sig128Z.v0 ); - } else if ( ! expDiff ) { - sig128Z.v64 = sig128Z.v64 - sigC; - if ( ! (sig128Z.v64 | sig128Z.v0) ) goto completeCancellation; - if ( sig128Z.v64 & UINT64_C( 0x8000000000000000 ) ) { - signZ = ! signZ; - sig128Z = softfloat_sub128( 0, 0, sig128Z.v64, sig128Z.v0 ); - } - } else { - sig128Z = - softfloat_sub128( - sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0 ); - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( ! sig128Z.v64 ) { - expZ -= 64; - sig128Z.v64 = sig128Z.v0; - sig128Z.v0 = 0; - } - shiftDist = softfloat_countLeadingZeros64( sig128Z.v64 ) - 1; - expZ -= shiftDist; - if ( shiftDist < 0 ) { - sigZ = softfloat_shortShiftRightJam64( sig128Z.v64, -shiftDist ); - } else { - sig128Z = - softfloat_shortShiftLeft128( - sig128Z.v64, sig128Z.v0, shiftDist ); - sigZ = sig128Z.v64; - } - sigZ |= (sig128Z.v0 != 0); - } - roundPack: - return softfloat_roundPackToF64( signZ, expZ, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN_ABC: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - goto propagateNaN_ZC; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infProdArg: - if ( magBits ) { - uiZ = packToF64UI( signZ, 0x7FF, 0 ); - if ( expC != 0x7FF ) goto uiZ; - if ( sigC ) goto propagateNaN_ZC; - if ( signZ == signC ) goto uiZ; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - propagateNaN_ZC: - uiZ = softfloat_propagateNaNF64UI( uiZ, uiC ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zeroProd: - uiZ = uiC; - if ( ! (expC | sigC) && (signZ != signC) ) { - completeCancellation: - uiZ = - packToF64UI( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#else - -float64_t - softfloat_mulAddF64( - uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC, uint_fast8_t op ) -{ - bool signA; - int_fast16_t expA; - uint64_t sigA; - bool signB; - int_fast16_t expB; - uint64_t sigB; - bool signC; - int_fast16_t expC; - uint64_t sigC; - bool signZ; - uint64_t magBits, uiZ; - struct exp16_sig64 normExpSig; - int_fast16_t expZ; - uint32_t sig128Z[4]; - uint64_t sigZ; - int_fast16_t shiftDist, expDiff; - uint32_t sig128C[4]; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - signB = signF64UI( uiB ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC); - expC = expF64UI( uiC ); - sigC = fracF64UI( uiC ); - signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( expA == 0x7FF ) { - if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN_ABC; - magBits = expB | sigB; - goto infProdArg; - } - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN_ABC; - magBits = expA | sigA; - goto infProdArg; - } - if ( expC == 0x7FF ) { - if ( sigC ) { - uiZ = 0; - goto propagateNaN_ZC; - } - uiZ = uiC; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( ! expA ) { - if ( ! sigA ) goto zeroProd; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zeroProd; - normExpSig = softfloat_normSubnormalF64Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA + expB - 0x3FE; - sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10; - sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<11; - softfloat_mul64To128M( sigA, sigB, sig128Z ); - sigZ = - (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )]; - shiftDist = 0; - if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) { - --expZ; - shiftDist = -1; - } - if ( ! expC ) { - if ( ! sigC ) { - if ( shiftDist ) sigZ <<= 1; - goto sigZ; - } - normExpSig = softfloat_normSubnormalF64Sig( sigC ); - expC = normExpSig.exp; - sigC = normExpSig.sig; - } - sigC = (sigC | UINT64_C( 0x0010000000000000 ))<<10; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expZ - expC; - if ( expDiff < 0 ) { - expZ = expC; - if ( (signZ == signC) || (expDiff < -1) ) { - shiftDist -= expDiff; - if ( shiftDist) { - sigZ = softfloat_shiftRightJam64( sigZ, shiftDist ); - } - } else { - if ( ! shiftDist ) { - softfloat_shortShiftRight128M( sig128Z, 1, sig128Z ); - } - } - } else { - if ( shiftDist ) softfloat_add128M( sig128Z, sig128Z, sig128Z ); - if ( ! expDiff ) { - sigZ = - (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 - | sig128Z[indexWord( 4, 2 )]; - } else { - sig128C[indexWord( 4, 3 )] = sigC>>32; - sig128C[indexWord( 4, 2 )] = sigC; - sig128C[indexWord( 4, 1 )] = 0; - sig128C[indexWord( 4, 0 )] = 0; - softfloat_shiftRightJam128M( sig128C, expDiff, sig128C ); - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( signZ == signC ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff <= 0 ) { - sigZ += sigC; - } else { - softfloat_add128M( sig128Z, sig128C, sig128Z ); - sigZ = - (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 - | sig128Z[indexWord( 4, 2 )]; - } - if ( sigZ & UINT64_C( 0x8000000000000000 ) ) { - ++expZ; - sigZ = softfloat_shortShiftRightJam64( sigZ, 1 ); - } - } else { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expDiff < 0 ) { - signZ = signC; - if ( expDiff < -1 ) { - sigZ = sigC - sigZ; - if ( - sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] - ) { - sigZ = (sigZ - 1) | 1; - } - if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) { - --expZ; - sigZ <<= 1; - } - goto roundPack; - } else { - sig128C[indexWord( 4, 3 )] = sigC>>32; - sig128C[indexWord( 4, 2 )] = sigC; - sig128C[indexWord( 4, 1 )] = 0; - sig128C[indexWord( 4, 0 )] = 0; - softfloat_sub128M( sig128C, sig128Z, sig128Z ); - } - } else if ( ! expDiff ) { - sigZ -= sigC; - if ( - ! sigZ && ! sig128Z[indexWord( 4, 1 )] - && ! sig128Z[indexWord( 4, 0 )] - ) { - goto completeCancellation; - } - sig128Z[indexWord( 4, 3 )] = sigZ>>32; - sig128Z[indexWord( 4, 2 )] = sigZ; - if ( sigZ & UINT64_C( 0x8000000000000000 ) ) { - signZ = ! signZ; - softfloat_negX128M( sig128Z ); - } - } else { - softfloat_sub128M( sig128Z, sig128C, sig128Z ); - if ( 1 < expDiff ) { - sigZ = - (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 - | sig128Z[indexWord( 4, 2 )]; - if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) { - --expZ; - sigZ <<= 1; - } - goto sigZ; - } - } - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - shiftDist = 0; - sigZ = - (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 - | sig128Z[indexWord( 4, 2 )]; - if ( ! sigZ ) { - shiftDist = 64; - sigZ = - (uint64_t) sig128Z[indexWord( 4, 1 )]<<32 - | sig128Z[indexWord( 4, 0 )]; - } - shiftDist += softfloat_countLeadingZeros64( sigZ ) - 1; - if ( shiftDist ) { - expZ -= shiftDist; - softfloat_shiftLeft128M( sig128Z, shiftDist, sig128Z ); - sigZ = - (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 - | sig128Z[indexWord( 4, 2 )]; - } - } - sigZ: - if ( sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] ) sigZ |= 1; - roundPack: - return softfloat_roundPackToF64( signZ, expZ - 1, sigZ ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN_ABC: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - goto propagateNaN_ZC; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - infProdArg: - if ( magBits ) { - uiZ = packToF64UI( signZ, 0x7FF, 0 ); - if ( expC != 0x7FF ) goto uiZ; - if ( sigC ) goto propagateNaN_ZC; - if ( signZ == signC ) goto uiZ; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - propagateNaN_ZC: - uiZ = softfloat_propagateNaNF64UI( uiZ, uiC ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - zeroProd: - uiZ = uiC; - if ( ! (expC | sigC) && (signZ != signC) ) { - completeCancellation: - uiZ = - packToF64UI( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_negXM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_negXM.c deleted file mode 100644 index bb1c5a1f4..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_negXM.c +++ /dev/null @@ -1,63 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_negXM - -void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ) -{ - unsigned int index, lastIndex; - uint_fast8_t carry; - uint32_t word; - - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - carry = 1; - for (;;) { - word = ~zPtr[index] + carry; - zPtr[index] = word; - if ( index == lastIndex ) break; - index += wordIncr; - if ( word ) carry = 0; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_normExtF80SigM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_normExtF80SigM.c deleted file mode 100644 index fabe91ca3..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_normExtF80SigM.c +++ /dev/null @@ -1,52 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" - -int softfloat_normExtF80SigM( uint64_t *sigPtr ) -{ - uint64_t sig; - int_fast8_t shiftDist; - - sig = *sigPtr; - shiftDist = softfloat_countLeadingZeros64( sig ); - *sigPtr = sig< -#include -#include "platform.h" -#include "internals.h" - -void - softfloat_normRoundPackMToExtF80M( - bool sign, - int32_t exp, - uint32_t *extSigPtr, - uint_fast8_t roundingPrecision, - struct extFloat80M *zSPtr - ) -{ - int_fast16_t shiftDist; - uint32_t wordSig; - - shiftDist = 0; - wordSig = extSigPtr[indexWord( 3, 2 )]; - if ( ! wordSig ) { - shiftDist = 32; - wordSig = extSigPtr[indexWord( 3, 1 )]; - if ( ! wordSig ) { - shiftDist = 64; - wordSig = extSigPtr[indexWord( 3, 0 )]; - if ( ! wordSig ) { - zSPtr->signExp = packToExtF80UI64( sign, 0 ); - zSPtr->signif = 0; - return; - } - } - } - shiftDist += softfloat_countLeadingZeros32( wordSig ); - if ( shiftDist ) { - exp -= shiftDist; - softfloat_shiftLeft96M( extSigPtr, shiftDist, extSigPtr ); - } - softfloat_roundPackMToExtF80M( - sign, exp, extSigPtr, roundingPrecision, zSPtr ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackMToF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackMToF128M.c deleted file mode 100644 index b15d160e9..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackMToF128M.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" - -void - softfloat_normRoundPackMToF128M( - bool sign, int32_t exp, uint32_t *extSigPtr, uint32_t *zWPtr ) -{ - const uint32_t *ptr; - int_fast16_t shiftDist; - uint32_t wordSig; - - ptr = extSigPtr + indexWordHi( 5 ); - shiftDist = 0; - for (;;) { - wordSig = *ptr; - if ( wordSig ) break; - shiftDist += 32; - if ( 160 <= shiftDist ) { - zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, 0, 0 ); - zWPtr[indexWord( 4, 2 )] = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - return; - } - ptr -= wordIncr; - } - shiftDist += softfloat_countLeadingZeros32( wordSig ) - 15; - if ( shiftDist ) { - exp -= shiftDist; - softfloat_shiftLeft160M( extSigPtr, shiftDist, extSigPtr ); - } - softfloat_roundPackMToF128M( sign, exp, extSigPtr, zWPtr ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToExtF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToExtF80.c deleted file mode 100644 index 2518bf44a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToExtF80.c +++ /dev/null @@ -1,71 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" - -extFloat80_t - softfloat_normRoundPackToExtF80( - bool sign, - int_fast32_t exp, - uint_fast64_t sig, - uint_fast64_t sigExtra, - uint_fast8_t roundingPrecision - ) -{ - int_fast8_t shiftDist; - struct uint128 sig128; - - if ( ! sig ) { - exp -= 64; - sig = sigExtra; - sigExtra = 0; - } - shiftDist = softfloat_countLeadingZeros64( sig ); - exp -= shiftDist; - if ( shiftDist ) { - sig128 = softfloat_shortShiftLeft128( sig, sigExtra, shiftDist ); - sig = sig128.v64; - sigExtra = sig128.v0; - } - return - softfloat_roundPackToExtF80( - sign, exp, sig, sigExtra, roundingPrecision ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToF128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToF128.c deleted file mode 100644 index 14cf28ead..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToF128.c +++ /dev/null @@ -1,81 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" - -float128_t - softfloat_normRoundPackToF128( - bool sign, int_fast32_t exp, uint_fast64_t sig64, uint_fast64_t sig0 ) -{ - int_fast8_t shiftDist; - struct uint128 sig128; - union ui128_f128 uZ; - uint_fast64_t sigExtra; - struct uint128_extra sig128Extra; - - if ( ! sig64 ) { - exp -= 64; - sig64 = sig0; - sig0 = 0; - } - shiftDist = softfloat_countLeadingZeros64( sig64 ) - 15; - exp -= shiftDist; - if ( 0 <= shiftDist ) { - if ( shiftDist ) { - sig128 = softfloat_shortShiftLeft128( sig64, sig0, shiftDist ); - sig64 = sig128.v64; - sig0 = sig128.v0; - } - if ( (uint32_t) exp < 0x7FFD ) { - uZ.ui.v64 = packToF128UI64( sign, sig64 | sig0 ? exp : 0, sig64 ); - uZ.ui.v0 = sig0; - return uZ.f; - } - sigExtra = 0; - } else { - sig128Extra = - softfloat_shortShiftRightJam128Extra( sig64, sig0, 0, -shiftDist ); - sig64 = sig128Extra.v.v64; - sig0 = sig128Extra.v.v0; - sigExtra = sig128Extra.extra; - } - return softfloat_roundPackToF128( sign, exp, sig64, sig0, sigExtra ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToF16.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToF16.c deleted file mode 100644 index 008c5f124..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_normRoundPackToF16.c +++ /dev/null @@ -1,58 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" - -float16_t - softfloat_normRoundPackToF16( bool sign, int_fast16_t exp, uint_fast16_t sig ) -{ - int_fast8_t shiftDist; - union ui16_f16 uZ; - - shiftDist = softfloat_countLeadingZeros16( sig ) - 1; - exp -= shiftDist; - if ( (4 <= shiftDist) && ((unsigned int) exp < 0x1D) ) { - uZ.ui = packToF16UI( sign, sig ? exp : 0, sig<<(shiftDist - 4) ); - return uZ.f; - } else { - return softfloat_roundPackToF16( sign, exp, sig< -#include -#include "platform.h" -#include "internals.h" - -float32_t - softfloat_normRoundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig ) -{ - int_fast8_t shiftDist; - union ui32_f32 uZ; - - shiftDist = softfloat_countLeadingZeros32( sig ) - 1; - exp -= shiftDist; - if ( (7 <= shiftDist) && ((unsigned int) exp < 0xFD) ) { - uZ.ui = packToF32UI( sign, sig ? exp : 0, sig<<(shiftDist - 7) ); - return uZ.f; - } else { - return softfloat_roundPackToF32( sign, exp, sig< -#include -#include "platform.h" -#include "internals.h" - -float64_t - softfloat_normRoundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig ) -{ - int_fast8_t shiftDist; - union ui64_f64 uZ; - - shiftDist = softfloat_countLeadingZeros64( sig ) - 1; - exp -= shiftDist; - if ( (10 <= shiftDist) && ((unsigned int) exp < 0x7FD) ) { - uZ.ui = packToF64UI( sign, sig ? exp : 0, sig<<(shiftDist - 10) ); - return uZ.f; - } else { - return softfloat_roundPackToF64( sign, exp, sig< -#include "platform.h" -#include "internals.h" - -struct exp32_sig64 softfloat_normSubnormalExtF80Sig( uint_fast64_t sig ) -{ - int_fast8_t shiftDist; - struct exp32_sig64 z; - - shiftDist = softfloat_countLeadingZeros64( sig ); - z.exp = -shiftDist; - z.sig = sig< -#include "platform.h" -#include "internals.h" - -struct exp32_sig128 - softfloat_normSubnormalF128Sig( uint_fast64_t sig64, uint_fast64_t sig0 ) -{ - int_fast8_t shiftDist; - struct exp32_sig128 z; - - if ( ! sig64 ) { - shiftDist = softfloat_countLeadingZeros64( sig0 ) - 15; - z.exp = -63 - shiftDist; - if ( shiftDist < 0 ) { - z.sig.v64 = sig0>>-shiftDist; - z.sig.v0 = sig0<<(shiftDist & 63); - } else { - z.sig.v64 = sig0< -#include "platform.h" -#include "internals.h" - -int softfloat_normSubnormalF128SigM( uint32_t *sigPtr ) -{ - const uint32_t *ptr; - int_fast16_t shiftDist; - uint32_t wordSig; - - ptr = sigPtr + indexWordHi( 4 ); - shiftDist = 0; - for (;;) { - wordSig = *ptr; - if ( wordSig ) break; - shiftDist += 32; - if ( 128 <= shiftDist ) return 1; - ptr -= wordIncr; - } - shiftDist += softfloat_countLeadingZeros32( wordSig ) - 15; - if ( shiftDist ) softfloat_shiftLeft128M( sigPtr, shiftDist, sigPtr ); - return 1 - shiftDist; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_normSubnormalF16Sig.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_normSubnormalF16Sig.c deleted file mode 100644 index 94541c914..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_normSubnormalF16Sig.c +++ /dev/null @@ -1,52 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" - -struct exp8_sig16 softfloat_normSubnormalF16Sig( uint_fast16_t sig ) -{ - int_fast8_t shiftDist; - struct exp8_sig16 z; - - shiftDist = softfloat_countLeadingZeros16( sig ) - 5; - z.exp = 1 - shiftDist; - z.sig = sig< -#include "platform.h" -#include "internals.h" - -struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t sig ) -{ - int_fast8_t shiftDist; - struct exp16_sig32 z; - - shiftDist = softfloat_countLeadingZeros32( sig ) - 8; - z.exp = 1 - shiftDist; - z.sig = sig< -#include "platform.h" -#include "internals.h" - -struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t sig ) -{ - int_fast8_t shiftDist; - struct exp16_sig64 z; - - shiftDist = softfloat_countLeadingZeros64( sig ) - 11; - z.exp = 1 - shiftDist; - z.sig = sig< -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_remStepMBy32 - -void - softfloat_remStepMBy32( - uint_fast8_t size_words, - const uint32_t *remPtr, - uint_fast8_t dist, - const uint32_t *bPtr, - uint32_t q, - uint32_t *zPtr - ) -{ - unsigned int index, lastIndex; - uint64_t dwordProd; - uint32_t wordRem, wordShiftedRem, wordProd; - uint_fast8_t uNegDist, borrow; - - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - dwordProd = (uint64_t) bPtr[index] * q; - wordRem = remPtr[index]; - wordShiftedRem = wordRem<>(uNegDist & 31); - index += wordIncr; - dwordProd = (uint64_t) bPtr[index] * q + (dwordProd>>32); - wordRem = remPtr[index]; - wordShiftedRem |= wordRem< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t - softfloat_roundMToI64( - bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact ) -{ - uint64_t sig; - uint32_t sigExtra; - union { uint64_t ui; int64_t i; } uZ; - int64_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = - (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 - | extSigPtr[indexWord( 3, 1 )]; - sigExtra = extSigPtr[indexWordLo( 3 )]; - if ( - (roundingMode == softfloat_round_near_maxMag) - || (roundingMode == softfloat_round_near_even) - ) { - if ( 0x80000000 <= sigExtra ) goto increment; - } else { - if ( - sigExtra - && (sign - ? (roundingMode == softfloat_round_min) -#ifdef SOFTFLOAT_ROUND_ODD - || (roundingMode == softfloat_round_odd) -#endif - : (roundingMode == softfloat_round_max)) - ) { - increment: - ++sig; - if ( !sig ) goto invalid; - if ( - (sigExtra == 0x80000000) - && (roundingMode == softfloat_round_near_even) - ) { - sig &= ~(uint_fast64_t) 1; - } - } - } - uZ.ui = sign ? -sig : sig; - z = uZ.i; - if ( z && ((z < 0) ^ sign) ) goto invalid; - if ( sigExtra ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) z |= 1; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? i64_fromNegOverflow : i64_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundMToUI64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundMToUI64.c deleted file mode 100644 index c91147453..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundMToUI64.c +++ /dev/null @@ -1,98 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t - softfloat_roundMToUI64( - bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact ) -{ - uint64_t sig; - uint32_t sigExtra; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = - (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 - | extSigPtr[indexWord( 3, 1 )]; - sigExtra = extSigPtr[indexWordLo( 3 )]; - if ( - (roundingMode == softfloat_round_near_maxMag) - || (roundingMode == softfloat_round_near_even) - ) { - if ( 0x80000000 <= sigExtra ) goto increment; - } else { - if ( sign ) { - if ( !(sig | sigExtra) ) return 0; - if ( roundingMode == softfloat_round_min ) goto invalid; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) goto invalid; -#endif - } else { - if ( (roundingMode == softfloat_round_max) && sigExtra ) { - increment: - ++sig; - if ( !sig ) goto invalid; - if ( - (sigExtra == 0x80000000) - && (roundingMode == softfloat_round_near_even) - ) { - sig &= ~(uint_fast64_t) 1; - } - } - } - } - if ( sign && sig ) goto invalid; - if ( sigExtra ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) sig |= 1; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return sig; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackMToExtF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackMToExtF80M.c deleted file mode 100644 index e9d3c3b10..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackMToExtF80M.c +++ /dev/null @@ -1,256 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -void - softfloat_roundPackMToExtF80M( - bool sign, - int32_t exp, - uint32_t *extSigPtr, - uint_fast8_t roundingPrecision, - struct extFloat80M *zSPtr - ) -{ - uint_fast8_t roundingMode; - bool roundNearEven; - uint64_t sig, roundIncrement, roundMask, roundBits; - bool isTiny; - uint32_t sigExtra; - bool doIncrement; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundingMode = softfloat_roundingMode; - roundNearEven = (roundingMode == softfloat_round_near_even); - sig = - (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 - | extSigPtr[indexWord( 3, 1 )]; - if ( roundingPrecision == 80 ) goto precision80; - if ( roundingPrecision == 64 ) { - roundIncrement = UINT64_C( 0x0000000000000400 ); - roundMask = UINT64_C( 0x00000000000007FF ); - } else if ( roundingPrecision == 32 ) { - roundIncrement = UINT64_C( 0x0000008000000000 ); - roundMask = UINT64_C( 0x000000FFFFFFFFFF ); - } else { - goto precision80; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( extSigPtr[indexWordLo( 3 )] ) sig |= 1; - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - roundIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ? roundMask - : 0; - } - roundBits = sig & roundMask; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x7FFD <= (uint32_t) (exp - 1) ) { - if ( exp <= 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < 0) - || (sig <= (uint64_t) (sig + roundIncrement)); - sig = softfloat_shiftRightJam64( sig, 1 - exp ); - roundBits = sig & roundMask; - if ( roundBits ) { - if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= roundMask + 1; - } -#endif - } - sig += roundIncrement; - exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); - roundIncrement = roundMask + 1; - if ( roundNearEven && (roundBits<<1 == roundIncrement) ) { - roundMask |= roundIncrement; - } - sig &= ~roundMask; - goto packReturn; - } - if ( - (0x7FFE < exp) - || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig)) - ) { - goto overflow; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( roundBits ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig = (sig & ~roundMask) | (roundMask + 1); - goto packReturn; - } -#endif - } - sig += roundIncrement; - if ( sig < roundIncrement ) { - ++exp; - sig = UINT64_C( 0x8000000000000000 ); - } - roundIncrement = roundMask + 1; - if ( roundNearEven && (roundBits<<1 == roundIncrement) ) { - roundMask |= roundIncrement; - } - sig &= ~roundMask; - goto packReturn; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - precision80: - sigExtra = extSigPtr[indexWordLo( 3 )]; - doIncrement = (0x80000000 <= sigExtra); - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x7FFD <= (uint32_t) (exp - 1) ) { - if ( exp <= 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < 0) - || ! doIncrement - || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF )); - softfloat_shiftRightJam96M( extSigPtr, 1 - exp, extSigPtr ); - exp = 0; - sig = - (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 - | extSigPtr[indexWord( 3, 1 )]; - sigExtra = extSigPtr[indexWordLo( 3 )]; - if ( sigExtra ) { - if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= 1; - goto packReturn; - } -#endif - } - doIncrement = (0x80000000 <= sigExtra); - if ( - ! roundNearEven - && (roundingMode != softfloat_round_near_maxMag) - ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - if ( doIncrement ) { - ++sig; - sig &= ~(uint64_t) (! (sigExtra & 0x7FFFFFFF) & roundNearEven); - exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); - } - goto packReturn; - } - if ( - (0x7FFE < exp) - || ((exp == 0x7FFE) && (sig == UINT64_C( 0xFFFFFFFFFFFFFFFF )) - && doIncrement) - ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - roundMask = 0; - overflow: - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - if ( - roundNearEven - || (roundingMode == softfloat_round_near_maxMag) - || (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ) { - exp = 0x7FFF; - sig = UINT64_C( 0x8000000000000000 ); - } else { - exp = 0x7FFE; - sig = ~roundMask; - } - goto packReturn; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( sigExtra ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= 1; - goto packReturn; - } -#endif - } - if ( doIncrement ) { - ++sig; - if ( ! sig ) { - ++exp; - sig = UINT64_C( 0x8000000000000000 ); - } else { - sig &= ~(uint64_t) (! (sigExtra & 0x7FFFFFFF) & roundNearEven); - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - packReturn: - zSPtr->signExp = packToExtF80UI64( sign, exp ); - zSPtr->signif = sig; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackMToF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackMToF128M.c deleted file mode 100644 index fad5d08df..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackMToF128M.c +++ /dev/null @@ -1,178 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -void - softfloat_roundPackMToF128M( - bool sign, int32_t exp, uint32_t *extSigPtr, uint32_t *zWPtr ) -{ - uint_fast8_t roundingMode; - bool roundNearEven; - uint32_t sigExtra; - bool doIncrement, isTiny; - static const uint32_t maxSig[4] = - INIT_UINTM4( 0x0001FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF ); - uint32_t ui, uj; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundingMode = softfloat_roundingMode; - roundNearEven = (roundingMode == softfloat_round_near_even); - sigExtra = extSigPtr[indexWordLo( 5 )]; - doIncrement = (0x80000000 <= sigExtra); - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x7FFD <= (uint32_t) exp ) { - if ( exp < 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < -1) - || ! doIncrement - || (softfloat_compare128M( - extSigPtr + indexMultiwordHi( 5, 4 ), maxSig ) - < 0); - softfloat_shiftRightJam160M( extSigPtr, -exp, extSigPtr ); - exp = 0; - sigExtra = extSigPtr[indexWordLo( 5 )]; - if ( isTiny && sigExtra ) { - softfloat_raiseFlags( softfloat_flag_underflow ); - } - doIncrement = (0x80000000 <= sigExtra); - if ( - ! roundNearEven - && (roundingMode != softfloat_round_near_maxMag) - ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - } else if ( - (0x7FFD < exp) - || ((exp == 0x7FFD) && doIncrement - && (softfloat_compare128M( - extSigPtr + indexMultiwordHi( 5, 4 ), maxSig ) - == 0)) - ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - if ( - roundNearEven - || (roundingMode == softfloat_round_near_maxMag) - || (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ) { - ui = packToF128UI96( sign, 0x7FFF, 0 ); - uj = 0; - } else { - ui = packToF128UI96( sign, 0x7FFE, 0x0000FFFF ); - uj = 0xFFFFFFFF; - } - zWPtr[indexWordHi( 4 )] = ui; - zWPtr[indexWord( 4, 2 )] = uj; - zWPtr[indexWord( 4, 1 )] = uj; - zWPtr[indexWord( 4, 0 )] = uj; - return; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - uj = extSigPtr[indexWord( 5, 1 )]; - if ( sigExtra ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - uj |= 1; - goto noIncrementPackReturn; - } -#endif - } - if ( doIncrement ) { - ++uj; - if ( uj ) { - if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) uj &= ~1; - zWPtr[indexWord( 4, 2 )] = extSigPtr[indexWord( 5, 3 )]; - zWPtr[indexWord( 4, 1 )] = extSigPtr[indexWord( 5, 2 )]; - zWPtr[indexWord( 4, 0 )] = uj; - ui = extSigPtr[indexWordHi( 5 )]; - } else { - zWPtr[indexWord( 4, 0 )] = uj; - ui = extSigPtr[indexWord( 5, 2 )] + 1; - zWPtr[indexWord( 4, 1 )] = ui; - uj = extSigPtr[indexWord( 5, 3 )]; - if ( ui ) { - zWPtr[indexWord( 4, 2 )] = uj; - ui = extSigPtr[indexWordHi( 5 )]; - } else { - ++uj; - zWPtr[indexWord( 4, 2 )] = uj; - ui = extSigPtr[indexWordHi( 5 )]; - if ( ! uj ) ++ui; - } - } - } else { - noIncrementPackReturn: - zWPtr[indexWord( 4, 0 )] = uj; - ui = extSigPtr[indexWord( 5, 2 )]; - zWPtr[indexWord( 4, 1 )] = ui; - uj |= ui; - ui = extSigPtr[indexWord( 5, 3 )]; - zWPtr[indexWord( 4, 2 )] = ui; - uj |= ui; - ui = extSigPtr[indexWordHi( 5 )]; - uj |= ui; - if ( ! uj ) exp = 0; - } - zWPtr[indexWordHi( 4 )] = packToF128UI96( sign, exp, ui ); - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToExtF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToExtF80.c deleted file mode 100644 index a5ea38c60..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToExtF80.c +++ /dev/null @@ -1,256 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -extFloat80_t - softfloat_roundPackToExtF80( - bool sign, - int_fast32_t exp, - uint_fast64_t sig, - uint_fast64_t sigExtra, - uint_fast8_t roundingPrecision - ) -{ - uint_fast8_t roundingMode; - bool roundNearEven; - uint_fast64_t roundIncrement, roundMask, roundBits; - bool isTiny, doIncrement; - struct uint64_extra sig64Extra; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundingMode = softfloat_roundingMode; - roundNearEven = (roundingMode == softfloat_round_near_even); - if ( roundingPrecision == 80 ) goto precision80; - if ( roundingPrecision == 64 ) { - roundIncrement = UINT64_C( 0x0000000000000400 ); - roundMask = UINT64_C( 0x00000000000007FF ); - } else if ( roundingPrecision == 32 ) { - roundIncrement = UINT64_C( 0x0000008000000000 ); - roundMask = UINT64_C( 0x000000FFFFFFFFFF ); - } else { - goto precision80; - } - sig |= (sigExtra != 0); - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - roundIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ? roundMask - : 0; - } - roundBits = sig & roundMask; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x7FFD <= (uint32_t) (exp - 1) ) { - if ( exp <= 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < 0) - || (sig <= (uint64_t) (sig + roundIncrement)); - sig = softfloat_shiftRightJam64( sig, 1 - exp ); - roundBits = sig & roundMask; - if ( roundBits ) { - if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= roundMask + 1; - } -#endif - } - sig += roundIncrement; - exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); - roundIncrement = roundMask + 1; - if ( roundNearEven && (roundBits<<1 == roundIncrement) ) { - roundMask |= roundIncrement; - } - sig &= ~roundMask; - goto packReturn; - } - if ( - (0x7FFE < exp) - || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig)) - ) { - goto overflow; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( roundBits ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig = (sig & ~roundMask) | (roundMask + 1); - goto packReturn; - } -#endif - } - sig = (uint64_t) (sig + roundIncrement); - if ( sig < roundIncrement ) { - ++exp; - sig = UINT64_C( 0x8000000000000000 ); - } - roundIncrement = roundMask + 1; - if ( roundNearEven && (roundBits<<1 == roundIncrement) ) { - roundMask |= roundIncrement; - } - sig &= ~roundMask; - goto packReturn; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - precision80: - doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x7FFD <= (uint32_t) (exp - 1) ) { - if ( exp <= 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < 0) - || ! doIncrement - || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF )); - sig64Extra = - softfloat_shiftRightJam64Extra( sig, sigExtra, 1 - exp ); - exp = 0; - sig = sig64Extra.v; - sigExtra = sig64Extra.extra; - if ( sigExtra ) { - if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow ); - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= 1; - goto packReturn; - } -#endif - } - doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); - if ( - ! roundNearEven - && (roundingMode != softfloat_round_near_maxMag) - ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - if ( doIncrement ) { - ++sig; - sig &= - ~(uint_fast64_t) - (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - & roundNearEven); - exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0); - } - goto packReturn; - } - if ( - (0x7FFE < exp) - || ((exp == 0x7FFE) && (sig == UINT64_C( 0xFFFFFFFFFFFFFFFF )) - && doIncrement) - ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - roundMask = 0; - overflow: - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - if ( - roundNearEven - || (roundingMode == softfloat_round_near_maxMag) - || (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ) { - exp = 0x7FFF; - sig = UINT64_C( 0x8000000000000000 ); - } else { - exp = 0x7FFE; - sig = ~roundMask; - } - goto packReturn; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( sigExtra ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= 1; - goto packReturn; - } -#endif - } - if ( doIncrement ) { - ++sig; - if ( ! sig ) { - ++exp; - sig = UINT64_C( 0x8000000000000000 ); - } else { - sig &= - ~(uint_fast64_t) - (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - & roundNearEven); - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - packReturn: - uZ.s.signExp = packToExtF80UI64( sign, exp ); - uZ.s.signif = sig; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF128.c deleted file mode 100644 index 6688c524b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF128.c +++ /dev/null @@ -1,171 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t - softfloat_roundPackToF128( - bool sign, - int_fast32_t exp, - uint_fast64_t sig64, - uint_fast64_t sig0, - uint_fast64_t sigExtra - ) -{ - uint_fast8_t roundingMode; - bool roundNearEven, doIncrement, isTiny; - struct uint128_extra sig128Extra; - uint_fast64_t uiZ64, uiZ0; - struct uint128 sig128; - union ui128_f128 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundingMode = softfloat_roundingMode; - roundNearEven = (roundingMode == softfloat_round_near_even); - doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x7FFD <= (uint32_t) exp ) { - if ( exp < 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess - == softfloat_tininess_beforeRounding) - || (exp < -1) - || ! doIncrement - || softfloat_lt128( - sig64, - sig0, - UINT64_C( 0x0001FFFFFFFFFFFF ), - UINT64_C( 0xFFFFFFFFFFFFFFFF ) - ); - sig128Extra = - softfloat_shiftRightJam128Extra( sig64, sig0, sigExtra, -exp ); - sig64 = sig128Extra.v.v64; - sig0 = sig128Extra.v.v0; - sigExtra = sig128Extra.extra; - exp = 0; - if ( isTiny && sigExtra ) { - softfloat_raiseFlags( softfloat_flag_underflow ); - } - doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); - if ( - ! roundNearEven - && (roundingMode != softfloat_round_near_maxMag) - ) { - doIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - && sigExtra; - } - } else if ( - (0x7FFD < exp) - || ((exp == 0x7FFD) - && softfloat_eq128( - sig64, - sig0, - UINT64_C( 0x0001FFFFFFFFFFFF ), - UINT64_C( 0xFFFFFFFFFFFFFFFF ) - ) - && doIncrement) - ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - if ( - roundNearEven - || (roundingMode == softfloat_round_near_maxMag) - || (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ) { - uiZ64 = packToF128UI64( sign, 0x7FFF, 0 ); - uiZ0 = 0; - } else { - uiZ64 = - packToF128UI64( - sign, 0x7FFE, UINT64_C( 0x0000FFFFFFFFFFFF ) ); - uiZ0 = UINT64_C( 0xFFFFFFFFFFFFFFFF ); - } - goto uiZ; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( sigExtra ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig0 |= 1; - goto packReturn; - } -#endif - } - if ( doIncrement ) { - sig128 = softfloat_add128( sig64, sig0, 0, 1 ); - sig64 = sig128.v64; - sig0 = - sig128.v0 - & ~(uint64_t) - (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) - & roundNearEven); - } else { - if ( ! (sig64 | sig0) ) exp = 0; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - packReturn: - uiZ64 = packToF128UI64( sign, exp, sig64 ); - uiZ0 = sig0; - uiZ: - uZ.ui.v64 = uiZ64; - uZ.ui.v0 = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF16.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF16.c deleted file mode 100644 index 8d03d3b2c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF16.c +++ /dev/null @@ -1,113 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t - softfloat_roundPackToF16( bool sign, int_fast16_t exp, uint_fast16_t sig ) -{ - uint_fast8_t roundingMode; - bool roundNearEven; - uint_fast8_t roundIncrement, roundBits; - bool isTiny; - uint_fast16_t uiZ; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundingMode = softfloat_roundingMode; - roundNearEven = (roundingMode == softfloat_round_near_even); - roundIncrement = 0x8; - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - roundIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ? 0xF - : 0; - } - roundBits = sig & 0xF; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x1D <= (unsigned int) exp ) { - if ( exp < 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess == softfloat_tininess_beforeRounding) - || (exp < -1) || (sig + roundIncrement < 0x8000); - sig = softfloat_shiftRightJam32( sig, -exp ); - exp = 0; - roundBits = sig & 0xF; - if ( isTiny && roundBits ) { - softfloat_raiseFlags( softfloat_flag_underflow ); - } - } else if ( (0x1D < exp) || (0x8000 <= sig + roundIncrement) ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - uiZ = packToF16UI( sign, 0x1F, 0 ) - ! roundIncrement; - goto uiZ; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = (sig + roundIncrement)>>4; - if ( roundBits ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= 1; - goto packReturn; - } -#endif - } - sig &= ~(uint_fast16_t) (! (roundBits ^ 8) & roundNearEven); - if ( ! sig ) exp = 0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - packReturn: - uiZ = packToF16UI( sign, exp, sig ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF32.c deleted file mode 100644 index f1eb0c2ab..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF32.c +++ /dev/null @@ -1,113 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t - softfloat_roundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig ) -{ - uint_fast8_t roundingMode; - bool roundNearEven; - uint_fast8_t roundIncrement, roundBits; - bool isTiny; - uint_fast32_t uiZ; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundingMode = softfloat_roundingMode; - roundNearEven = (roundingMode == softfloat_round_near_even); - roundIncrement = 0x40; - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - roundIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ? 0x7F - : 0; - } - roundBits = sig & 0x7F; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0xFD <= (unsigned int) exp ) { - if ( exp < 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess == softfloat_tininess_beforeRounding) - || (exp < -1) || (sig + roundIncrement < 0x80000000); - sig = softfloat_shiftRightJam32( sig, -exp ); - exp = 0; - roundBits = sig & 0x7F; - if ( isTiny && roundBits ) { - softfloat_raiseFlags( softfloat_flag_underflow ); - } - } else if ( (0xFD < exp) || (0x80000000 <= sig + roundIncrement) ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - uiZ = packToF32UI( sign, 0xFF, 0 ) - ! roundIncrement; - goto uiZ; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = (sig + roundIncrement)>>7; - if ( roundBits ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= 1; - goto packReturn; - } -#endif - } - sig &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven); - if ( ! sig ) exp = 0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - packReturn: - uiZ = packToF32UI( sign, exp, sig ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF64.c deleted file mode 100644 index 98c1639a4..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundPackToF64.c +++ /dev/null @@ -1,117 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t - softfloat_roundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig ) -{ - uint_fast8_t roundingMode; - bool roundNearEven; - uint_fast16_t roundIncrement, roundBits; - bool isTiny; - uint_fast64_t uiZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundingMode = softfloat_roundingMode; - roundNearEven = (roundingMode == softfloat_round_near_even); - roundIncrement = 0x200; - if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { - roundIncrement = - (roundingMode - == (sign ? softfloat_round_min : softfloat_round_max)) - ? 0x3FF - : 0; - } - roundBits = sig & 0x3FF; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( 0x7FD <= (uint16_t) exp ) { - if ( exp < 0 ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - isTiny = - (softfloat_detectTininess == softfloat_tininess_beforeRounding) - || (exp < -1) - || (sig + roundIncrement < UINT64_C( 0x8000000000000000 )); - sig = softfloat_shiftRightJam64( sig, -exp ); - exp = 0; - roundBits = sig & 0x3FF; - if ( isTiny && roundBits ) { - softfloat_raiseFlags( softfloat_flag_underflow ); - } - } else if ( - (0x7FD < exp) - || (UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement) - ) { - /*---------------------------------------------------------------- - *----------------------------------------------------------------*/ - softfloat_raiseFlags( - softfloat_flag_overflow | softfloat_flag_inexact ); - uiZ = packToF64UI( sign, 0x7FF, 0 ) - ! roundIncrement; - goto uiZ; - } - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - sig = (sig + roundIncrement)>>10; - if ( roundBits ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) { - sig |= 1; - goto packReturn; - } -#endif - } - sig &= ~(uint_fast64_t) (! (roundBits ^ 0x200) & roundNearEven); - if ( ! sig ) exp = 0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - packReturn: - uiZ = packToF64UI( sign, exp, sig ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToI32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToI32.c deleted file mode 100644 index 1999dcf56..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToI32.c +++ /dev/null @@ -1,98 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast32_t - softfloat_roundToI32( - bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact ) -{ - uint_fast16_t roundIncrement, roundBits; - uint_fast32_t sig32; - union { uint32_t ui; int32_t i; } uZ; - int_fast32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundIncrement = 0x800; - if ( - (roundingMode != softfloat_round_near_maxMag) - && (roundingMode != softfloat_round_near_even) - ) { - roundIncrement = 0; - if ( - sign - ? (roundingMode == softfloat_round_min) -#ifdef SOFTFLOAT_ROUND_ODD - || (roundingMode == softfloat_round_odd) -#endif - : (roundingMode == softfloat_round_max) - ) { - roundIncrement = 0xFFF; - } - } - roundBits = sig & 0xFFF; - sig += roundIncrement; - if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid; - sig32 = sig>>12; - if ( - (roundBits == 0x800) && (roundingMode == softfloat_round_near_even) - ) { - sig32 &= ~(uint_fast32_t) 1; - } - uZ.ui = sign ? -sig32 : sig32; - z = uZ.i; - if ( z && ((z < 0) ^ sign) ) goto invalid; - if ( roundBits ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) z |= 1; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? i32_fromNegOverflow : i32_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToI64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToI64.c deleted file mode 100644 index d1e9d2799..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToI64.c +++ /dev/null @@ -1,101 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -int_fast64_t - softfloat_roundToI64( - bool sign, - uint_fast64_t sig, - uint_fast64_t sigExtra, - uint_fast8_t roundingMode, - bool exact - ) -{ - union { uint64_t ui; int64_t i; } uZ; - int_fast64_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( - (roundingMode == softfloat_round_near_maxMag) - || (roundingMode == softfloat_round_near_even) - ) { - if ( UINT64_C( 0x8000000000000000 ) <= sigExtra ) goto increment; - } else { - if ( - sigExtra - && (sign - ? (roundingMode == softfloat_round_min) -#ifdef SOFTFLOAT_ROUND_ODD - || (roundingMode == softfloat_round_odd) -#endif - : (roundingMode == softfloat_round_max)) - ) { - increment: - ++sig; - if ( !sig ) goto invalid; - if ( - (sigExtra == UINT64_C( 0x8000000000000000 )) - && (roundingMode == softfloat_round_near_even) - ) { - sig &= ~(uint_fast64_t) 1; - } - } - } - uZ.ui = sign ? -sig : sig; - z = uZ.i; - if ( z && ((z < 0) ^ sign) ) goto invalid; - if ( sigExtra ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) z |= 1; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? i64_fromNegOverflow : i64_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToUI32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToUI32.c deleted file mode 100644 index eaad69e70..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToUI32.c +++ /dev/null @@ -1,93 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast32_t - softfloat_roundToUI32( - bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact ) -{ - uint_fast16_t roundIncrement, roundBits; - uint_fast32_t z; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - roundIncrement = 0x800; - if ( - (roundingMode != softfloat_round_near_maxMag) - && (roundingMode != softfloat_round_near_even) - ) { - roundIncrement = 0; - if ( sign ) { - if ( !sig ) return 0; - if ( roundingMode == softfloat_round_min ) goto invalid; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) goto invalid; -#endif - } else { - if ( roundingMode == softfloat_round_max ) roundIncrement = 0xFFF; - } - } - roundBits = sig & 0xFFF; - sig += roundIncrement; - if ( sig & UINT64_C( 0xFFFFF00000000000 ) ) goto invalid; - z = sig>>12; - if ( - (roundBits == 0x800) && (roundingMode == softfloat_round_near_even) - ) { - z &= ~(uint_fast32_t) 1; - } - if ( sign && z ) goto invalid; - if ( roundBits ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) z |= 1; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return z; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToUI64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToUI64.c deleted file mode 100644 index 0ba78a640..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_roundToUI64.c +++ /dev/null @@ -1,97 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -uint_fast64_t - softfloat_roundToUI64( - bool sign, - uint_fast64_t sig, - uint_fast64_t sigExtra, - uint_fast8_t roundingMode, - bool exact - ) -{ - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( - (roundingMode == softfloat_round_near_maxMag) - || (roundingMode == softfloat_round_near_even) - ) { - if ( UINT64_C( 0x8000000000000000 ) <= sigExtra ) goto increment; - } else { - if ( sign ) { - if ( !(sig | sigExtra) ) return 0; - if ( roundingMode == softfloat_round_min ) goto invalid; -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) goto invalid; -#endif - } else { - if ( (roundingMode == softfloat_round_max) && sigExtra ) { - increment: - ++sig; - if ( !sig ) goto invalid; - if ( - (sigExtra == UINT64_C( 0x8000000000000000 )) - && (roundingMode == softfloat_round_near_even) - ) { - sig &= ~(uint_fast64_t) 1; - } - } - } - } - if ( sign && sig ) goto invalid; - if ( sigExtra ) { -#ifdef SOFTFLOAT_ROUND_ODD - if ( roundingMode == softfloat_round_odd ) sig |= 1; -#endif - if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return sig; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftLeftM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftLeftM.c deleted file mode 100644 index feafc67bf..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftLeftM.c +++ /dev/null @@ -1,91 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_shiftLeftM - -#define softfloat_shiftLeftM softfloat_shiftLeftM -#include "primitives.h" - -void - softfloat_shiftLeftM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint32_t dist, - uint32_t *zPtr - ) -{ - uint32_t wordDist; - uint_fast8_t innerDist; - uint32_t *destPtr; - uint_fast8_t i; - - wordDist = dist>>5; - if ( wordDist < size_words ) { - aPtr += indexMultiwordLoBut( size_words, wordDist ); - innerDist = dist & 31; - if ( innerDist ) { - softfloat_shortShiftLeftM( - size_words - wordDist, - aPtr, - innerDist, - zPtr + indexMultiwordHiBut( size_words, wordDist ) - ); - if ( ! wordDist ) return; - } else { - aPtr += indexWordHi( size_words - wordDist ); - destPtr = zPtr + indexWordHi( size_words ); - for ( i = size_words - wordDist; i; --i ) { - *destPtr = *aPtr; - aPtr -= wordIncr; - destPtr -= wordIncr; - } - } - zPtr += indexMultiwordLo( size_words, wordDist ); - } else { - wordDist = size_words; - } - do { - *zPtr++ = 0; - --wordDist; - } while ( wordDist ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftNormSigF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftNormSigF128M.c deleted file mode 100644 index 4820f3908..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftNormSigF128M.c +++ /dev/null @@ -1,78 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" - -int - softfloat_shiftNormSigF128M( - const uint32_t *wPtr, uint_fast8_t shiftDist, uint32_t *sigPtr ) -{ - uint32_t wordSig; - int32_t exp; - uint32_t leadingBit; - - wordSig = wPtr[indexWordHi( 4 )]; - exp = expF128UI96( wordSig ); - if ( exp ) { - softfloat_shortShiftLeft128M( wPtr, shiftDist, sigPtr ); - leadingBit = 0x00010000< -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shiftRightJam128 - -struct uint128 - softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist ) -{ - uint_fast8_t u8NegDist; - struct uint128 z; - - if ( dist < 64 ) { - u8NegDist = -dist; - z.v64 = a64>>dist; - z.v0 = - a64<<(u8NegDist & 63) | a0>>dist - | ((uint64_t) (a0<<(u8NegDist & 63)) != 0); - } else { - z.v64 = 0; - z.v0 = - (dist < 127) - ? a64>>(dist & 63) - | (((a64 & (((uint_fast64_t) 1<<(dist & 63)) - 1)) | a0) - != 0) - : ((a64 | a0) != 0); - } - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam128Extra.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam128Extra.c deleted file mode 100644 index efdfc5432..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam128Extra.c +++ /dev/null @@ -1,77 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shiftRightJam128Extra - -struct uint128_extra - softfloat_shiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist ) -{ - uint_fast8_t u8NegDist; - struct uint128_extra z; - - u8NegDist = -dist; - if ( dist < 64 ) { - z.v.v64 = a64>>dist; - z.v.v0 = a64<<(u8NegDist & 63) | a0>>dist; - z.extra = a0<<(u8NegDist & 63); - } else { - z.v.v64 = 0; - if ( dist == 64 ) { - z.v.v0 = a64; - z.extra = a0; - } else { - extra |= a0; - if ( dist < 128 ) { - z.v.v0 = a64>>(dist & 63); - z.extra = a64<<(u8NegDist & 63); - } else { - z.v.v0 = 0; - z.extra = (dist == 128) ? a64 : (a64 != 0); - } - } - } - z.extra |= (extra != 0); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam256M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam256M.c deleted file mode 100644 index 36601f87b..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam256M.c +++ /dev/null @@ -1,126 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shiftRightJam256M - -static - void - softfloat_shortShiftRightJamM( - uint_fast8_t size_words, - const uint64_t *aPtr, - uint_fast8_t dist, - uint64_t *zPtr - ) -{ - uint_fast8_t uNegDist; - unsigned int index, lastIndex; - uint64_t partWordZ, wordA; - - uNegDist = -dist; - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - wordA = aPtr[index]; - partWordZ = wordA>>dist; - if ( partWordZ<>dist; - } - zPtr[index] = partWordZ; - -} - -void - softfloat_shiftRightJam256M( - const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr ) -{ - uint64_t wordJam; - uint_fast32_t wordDist; - uint64_t *ptr; - uint_fast8_t i, innerDist; - - wordJam = 0; - wordDist = dist>>6; - if ( wordDist ) { - if ( 4 < wordDist ) wordDist = 4; - ptr = (uint64_t *) (aPtr + indexMultiwordLo( 4, wordDist )); - i = wordDist; - do { - wordJam = *ptr++; - if ( wordJam ) break; - --i; - } while ( i ); - ptr = zPtr; - } - if ( wordDist < 4 ) { - aPtr += indexMultiwordHiBut( 4, wordDist ); - innerDist = dist & 63; - if ( innerDist ) { - softfloat_shortShiftRightJamM( - 4 - wordDist, - aPtr, - innerDist, - zPtr + indexMultiwordLoBut( 4, wordDist ) - ); - if ( ! wordDist ) goto wordJam; - } else { - aPtr += indexWordLo( 4 - wordDist ); - ptr = zPtr + indexWordLo( 4 ); - for ( i = 4 - wordDist; i; --i ) { - *ptr = *aPtr; - aPtr += wordIncr; - ptr += wordIncr; - } - } - ptr = zPtr + indexMultiwordHi( 4, wordDist ); - } - do { - *ptr++ = 0; - --wordDist; - } while ( wordDist ); - wordJam: - if ( wordJam ) zPtr[indexWordLo( 4 )] |= 1; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam32.c deleted file mode 100644 index be4622abe..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam32.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_shiftRightJam32 - -uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist ) -{ - - return - (dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam64.c deleted file mode 100644 index 733c1736c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam64.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_shiftRightJam64 - -uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist ) -{ - - return - (dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam64Extra.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam64Extra.c deleted file mode 100644 index 2c5609b1c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJam64Extra.c +++ /dev/null @@ -1,62 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shiftRightJam64Extra - -struct uint64_extra - softfloat_shiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast32_t dist ) -{ - struct uint64_extra z; - - if ( dist < 64 ) { - z.v = a>>dist; - z.extra = a<<(-dist & 63); - } else { - z.v = 0; - z.extra = (dist == 64) ? a : (a != 0); - } - z.extra |= (extra != 0); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJamM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJamM.c deleted file mode 100644 index 0a0dd7d75..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightJamM.c +++ /dev/null @@ -1,101 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_shiftRightJamM - -#define softfloat_shiftRightJamM softfloat_shiftRightJamM -#include "primitives.h" - -void - softfloat_shiftRightJamM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint32_t dist, - uint32_t *zPtr - ) -{ - uint32_t wordJam, wordDist, *ptr; - uint_fast8_t i, innerDist; - - wordJam = 0; - wordDist = dist>>5; - if ( wordDist ) { - if ( size_words < wordDist ) wordDist = size_words; - ptr = (uint32_t *) (aPtr + indexMultiwordLo( size_words, wordDist )); - i = wordDist; - do { - wordJam = *ptr++; - if ( wordJam ) break; - --i; - } while ( i ); - ptr = zPtr; - } - if ( wordDist < size_words ) { - aPtr += indexMultiwordHiBut( size_words, wordDist ); - innerDist = dist & 31; - if ( innerDist ) { - softfloat_shortShiftRightJamM( - size_words - wordDist, - aPtr, - innerDist, - zPtr + indexMultiwordLoBut( size_words, wordDist ) - ); - if ( ! wordDist ) goto wordJam; - } else { - aPtr += indexWordLo( size_words - wordDist ); - ptr = zPtr + indexWordLo( size_words ); - for ( i = size_words - wordDist; i; --i ) { - *ptr = *aPtr; - aPtr += wordIncr; - ptr += wordIncr; - } - } - ptr = zPtr + indexMultiwordHi( size_words, wordDist ); - } - do { - *ptr++ = 0; - --wordDist; - } while ( wordDist ); - wordJam: - if ( wordJam ) zPtr[indexWordLo( size_words )] |= 1; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightM.c deleted file mode 100644 index 6ac383f0f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shiftRightM.c +++ /dev/null @@ -1,91 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_shiftRightM - -#define softfloat_shiftRightM softfloat_shiftRightM -#include "primitives.h" - -void - softfloat_shiftRightM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint32_t dist, - uint32_t *zPtr - ) -{ - uint32_t wordDist; - uint_fast8_t innerDist; - uint32_t *destPtr; - uint_fast8_t i; - - wordDist = dist>>5; - if ( wordDist < size_words ) { - aPtr += indexMultiwordHiBut( size_words, wordDist ); - innerDist = dist & 31; - if ( innerDist ) { - softfloat_shortShiftRightM( - size_words - wordDist, - aPtr, - innerDist, - zPtr + indexMultiwordLoBut( size_words, wordDist ) - ); - if ( ! wordDist ) return; - } else { - aPtr += indexWordLo( size_words - wordDist ); - destPtr = zPtr + indexWordLo( size_words ); - for ( i = size_words - wordDist; i; --i ) { - *destPtr = *aPtr; - aPtr += wordIncr; - destPtr += wordIncr; - } - } - zPtr += indexMultiwordHi( size_words, wordDist ); - } else { - wordDist = size_words; - } - do { - *zPtr++ = 0; - --wordDist; - } while ( wordDist ); - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftLeft128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftLeft128.c deleted file mode 100644 index 9e0b8beee..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftLeft128.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftLeft128 - -struct uint128 - softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist ) -{ - struct uint128 z; - - z.v64 = a64<>(-dist & 63); - z.v0 = a0< -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftLeft64To96M - -void - softfloat_shortShiftLeft64To96M( - uint64_t a, uint_fast8_t dist, uint32_t *zPtr ) -{ - - zPtr[indexWord( 3, 0 )] = (uint32_t) a<>= 32 - dist; - zPtr[indexWord( 3, 2 )] = a>>32; - zPtr[indexWord( 3, 1 )] = a; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftLeftM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftLeftM.c deleted file mode 100644 index b947c63ce..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftLeftM.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftLeftM - -void - softfloat_shortShiftLeftM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t dist, - uint32_t *zPtr - ) -{ - uint_fast8_t uNegDist; - unsigned int index, lastIndex; - uint32_t partWordZ, wordA; - - uNegDist = -dist; - index = indexWordHi( size_words ); - lastIndex = indexWordLo( size_words ); - partWordZ = aPtr[index]<>(uNegDist & 31); - index -= wordIncr; - partWordZ = wordA< -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRight128 - -struct uint128 - softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist ) -{ - struct uint128 z; - - z.v64 = a64>>dist; - z.v0 = a64<<(-dist & 63) | a0>>dist; - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightExtendM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightExtendM.c deleted file mode 100644 index 92c786af8..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightExtendM.c +++ /dev/null @@ -1,73 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRightExtendM - -void - softfloat_shortShiftRightExtendM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t dist, - uint32_t *zPtr - ) -{ - uint_fast8_t uNegDist; - unsigned int indexA, lastIndexA; - uint32_t partWordZ, wordA; - - uNegDist = -dist; - indexA = indexWordLo( size_words ); - lastIndexA = indexWordHi( size_words ); - zPtr += indexWordLo( size_words + 1 ); - partWordZ = 0; - for (;;) { - wordA = aPtr[indexA]; - *zPtr = wordA<<(uNegDist & 31) | partWordZ; - zPtr += wordIncr; - partWordZ = wordA>>dist; - if ( indexA == lastIndexA ) break; - indexA += wordIncr; - } - *zPtr = partWordZ; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam128.c deleted file mode 100644 index 8a75a71ac..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam128.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRightJam128 - -struct uint128 - softfloat_shortShiftRightJam128( - uint64_t a64, uint64_t a0, uint_fast8_t dist ) -{ - uint_fast8_t uNegDist; - struct uint128 z; - - uNegDist = -dist; - z.v64 = a64>>dist; - z.v0 = - a64<<(uNegDist & 63) | a0>>dist - | ((uint64_t) (a0<<(uNegDist & 63)) != 0); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam128Extra.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam128Extra.c deleted file mode 100644 index b5d4e1c31..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam128Extra.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRightJam128Extra - -struct uint128_extra - softfloat_shortShiftRightJam128Extra( - uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist ) -{ - uint_fast8_t uNegDist; - struct uint128_extra z; - - uNegDist = -dist; - z.v.v64 = a64>>dist; - z.v.v0 = a64<<(uNegDist & 63) | a0>>dist; - z.extra = a0<<(uNegDist & 63) | (extra != 0); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam64.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam64.c deleted file mode 100644 index 1a7724f98..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJam64.c +++ /dev/null @@ -1,50 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" - -#ifndef softfloat_shortShiftRightJam64 - -uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist ) -{ - - return a>>dist | ((a & (((uint_fast64_t) 1< -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRightJam64Extra - -struct uint64_extra - softfloat_shortShiftRightJam64Extra( - uint64_t a, uint64_t extra, uint_fast8_t dist ) -{ - struct uint64_extra z; - - z.v = a>>dist; - z.extra = a<<(-dist & 63) | (extra != 0); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJamM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJamM.c deleted file mode 100644 index 60f698b9f..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightJamM.c +++ /dev/null @@ -1,72 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRightJamM - -void - softfloat_shortShiftRightJamM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t dist, - uint32_t *zPtr - ) -{ - uint_fast8_t uNegDist; - unsigned int index, lastIndex; - uint32_t partWordZ, wordA; - - uNegDist = -dist; - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - wordA = aPtr[index]; - partWordZ = wordA>>dist; - if ( partWordZ<>dist; - } - zPtr[index] = partWordZ; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightM.c deleted file mode 100644 index 8a165fe45..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_shortShiftRightM.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_shortShiftRightM - -void - softfloat_shortShiftRightM( - uint_fast8_t size_words, - const uint32_t *aPtr, - uint_fast8_t dist, - uint32_t *zPtr - ) -{ - uint_fast8_t uNegDist; - unsigned int index, lastIndex; - uint32_t partWordZ, wordA; - - uNegDist = -dist; - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - partWordZ = aPtr[index]>>dist; - while ( index != lastIndex ) { - wordA = aPtr[index + wordIncr]; - zPtr[index] = wordA<<(uNegDist & 31) | partWordZ; - index += wordIncr; - partWordZ = wordA>>dist; - } - zPtr[index] = partWordZ; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_sub128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_sub128.c deleted file mode 100644 index 4691aec19..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_sub128.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_sub128 - -struct uint128 - softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - struct uint128 z; - - z.v0 = a0 - b0; - z.v64 = a64 - b64 - (a0 < b0); - return z; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_sub1XM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_sub1XM.c deleted file mode 100644 index 6c79a8b2e..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_sub1XM.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_sub1XM - -void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ) -{ - unsigned int index, lastIndex; - uint32_t wordA; - - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - for (;;) { - wordA = zPtr[index]; - zPtr[index] = wordA - 1; - if ( wordA || (index == lastIndex) ) break; - index += wordIncr; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_sub256M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_sub256M.c deleted file mode 100644 index a1f9f899c..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_sub256M.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_sub256M - -void - softfloat_sub256M( - const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ) -{ - unsigned int index; - uint_fast8_t borrow; - uint64_t wordA, wordB; - - index = indexWordLo( 4 ); - borrow = 0; - for (;;) { - wordA = aPtr[index]; - wordB = bPtr[index]; - zPtr[index] = wordA - wordB - borrow; - if ( index == indexWordHi( 4 ) ) break; - borrow = borrow ? (wordA <= wordB) : (wordA < wordB); - index += wordIncr; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_subM.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_subM.c deleted file mode 100644 index 213b0bf6d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_subM.c +++ /dev/null @@ -1,70 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "primitiveTypes.h" - -#ifndef softfloat_subM - -void - softfloat_subM( - uint_fast8_t size_words, - const uint32_t *aPtr, - const uint32_t *bPtr, - uint32_t *zPtr - ) -{ - unsigned int index, lastIndex; - uint_fast8_t borrow; - uint32_t wordA, wordB; - - index = indexWordLo( size_words ); - lastIndex = indexWordHi( size_words ); - borrow = 0; - for (;;) { - wordA = aPtr[index]; - wordB = bPtr[index]; - zPtr[index] = wordA - wordB - borrow; - if ( index == lastIndex ) break; - borrow = borrow ? (wordA <= wordB) : (wordA < wordB); - index += wordIncr; - } - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsExtF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsExtF80.c deleted file mode 100644 index 86ffd9b89..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsExtF80.c +++ /dev/null @@ -1,158 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -extFloat80_t - softfloat_subMagsExtF80( - uint_fast16_t uiA64, - uint_fast64_t uiA0, - uint_fast16_t uiB64, - uint_fast64_t uiB0, - bool signZ - ) -{ - int_fast32_t expA; - uint_fast64_t sigA; - int_fast32_t expB; - uint_fast64_t sigB; - int_fast32_t expDiff; - uint_fast16_t uiZ64; - uint_fast64_t uiZ0; - int_fast32_t expZ; - uint_fast64_t sigExtra; - struct uint128 sig128, uiZ; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expExtF80UI64( uiA64 ); - sigA = uiA0; - expB = expExtF80UI64( uiB64 ); - sigB = uiB0; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( 0 < expDiff ) goto expABigger; - if ( expDiff < 0 ) goto expBBigger; - if ( expA == 0x7FFF ) { - if ( (sigA | sigB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) { - goto propagateNaN; - } - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ64 = defaultNaNExtF80UI64; - uiZ0 = defaultNaNExtF80UI0; - goto uiZ; - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expZ = expA; - if ( ! expZ ) expZ = 1; - sigExtra = 0; - if ( sigB < sigA ) goto aBigger; - if ( sigA < sigB ) goto bBigger; - uiZ64 = - packToExtF80UI64( (softfloat_roundingMode == softfloat_round_min), 0 ); - uiZ0 = 0; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expBBigger: - if ( expB == 0x7FFF ) { - if ( sigB & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - uiZ64 = packToExtF80UI64( signZ ^ 1, 0x7FFF ); - uiZ0 = UINT64_C( 0x8000000000000000 ); - goto uiZ; - } - if ( ! expA ) { - ++expDiff; - sigExtra = 0; - if ( ! expDiff ) goto newlyAlignedBBigger; - } - sig128 = softfloat_shiftRightJam128( sigA, 0, -expDiff ); - sigA = sig128.v64; - sigExtra = sig128.v0; - newlyAlignedBBigger: - expZ = expB; - bBigger: - signZ = ! signZ; - sig128 = softfloat_sub128( sigB, 0, sigA, sigExtra ); - goto normRoundPack; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expABigger: - if ( expA == 0x7FFF ) { - if ( sigA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) goto propagateNaN; - uiZ64 = uiA64; - uiZ0 = uiA0; - goto uiZ; - } - if ( ! expB ) { - --expDiff; - sigExtra = 0; - if ( ! expDiff ) goto newlyAlignedABigger; - } - sig128 = softfloat_shiftRightJam128( sigB, 0, expDiff ); - sigB = sig128.v64; - sigExtra = sig128.v0; - newlyAlignedABigger: - expZ = expA; - aBigger: - sig128 = softfloat_sub128( sigA, 0, sigB, sigExtra ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - normRoundPack: - return - softfloat_normRoundPackToExtF80( - signZ, expZ, sig128.v64, sig128.v0, extF80_roundingPrecision ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNExtF80UI( uiA64, uiA0, uiB64, uiB0 ); - uiZ64 = uiZ.v64; - uiZ0 = uiZ.v0; - uiZ: - uZ.s.signExp = uiZ64; - uZ.s.signif = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF128.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF128.c deleted file mode 100644 index 595ed7e89..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF128.c +++ /dev/null @@ -1,139 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float128_t - softfloat_subMagsF128( - uint_fast64_t uiA64, - uint_fast64_t uiA0, - uint_fast64_t uiB64, - uint_fast64_t uiB0, - bool signZ - ) -{ - int_fast32_t expA; - struct uint128 sigA; - int_fast32_t expB; - struct uint128 sigB, sigZ; - int_fast32_t expDiff, expZ; - struct uint128 uiZ; - union ui128_f128 uZ; - - expA = expF128UI64( uiA64 ); - sigA.v64 = fracF128UI64( uiA64 ); - sigA.v0 = uiA0; - expB = expF128UI64( uiB64 ); - sigB.v64 = fracF128UI64( uiB64 ); - sigB.v0 = uiB0; - sigA = softfloat_shortShiftLeft128( sigA.v64, sigA.v0, 4 ); - sigB = softfloat_shortShiftLeft128( sigB.v64, sigB.v0, 4 ); - expDiff = expA - expB; - if ( 0 < expDiff ) goto expABigger; - if ( expDiff < 0 ) goto expBBigger; - if ( expA == 0x7FFF ) { - if ( sigA.v64 | sigA.v0 | sigB.v64 | sigB.v0 ) goto propagateNaN; - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ.v64 = defaultNaNF128UI64; - uiZ.v0 = defaultNaNF128UI0; - goto uiZ; - } - expZ = expA; - if ( ! expZ ) expZ = 1; - if ( sigB.v64 < sigA.v64 ) goto aBigger; - if ( sigA.v64 < sigB.v64 ) goto bBigger; - if ( sigB.v0 < sigA.v0 ) goto aBigger; - if ( sigA.v0 < sigB.v0 ) goto bBigger; - uiZ.v64 = - packToF128UI64( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - uiZ.v0 = 0; - goto uiZ; - expBBigger: - if ( expB == 0x7FFF ) { - if ( sigB.v64 | sigB.v0 ) goto propagateNaN; - uiZ.v64 = packToF128UI64( signZ ^ 1, 0x7FFF, 0 ); - uiZ.v0 = 0; - goto uiZ; - } - if ( expA ) { - sigA.v64 |= UINT64_C( 0x0010000000000000 ); - } else { - ++expDiff; - if ( ! expDiff ) goto newlyAlignedBBigger; - } - sigA = softfloat_shiftRightJam128( sigA.v64, sigA.v0, -expDiff ); - newlyAlignedBBigger: - expZ = expB; - sigB.v64 |= UINT64_C( 0x0010000000000000 ); - bBigger: - signZ = ! signZ; - sigZ = softfloat_sub128( sigB.v64, sigB.v0, sigA.v64, sigA.v0 ); - goto normRoundPack; - expABigger: - if ( expA == 0x7FFF ) { - if ( sigA.v64 | sigA.v0 ) goto propagateNaN; - uiZ.v64 = uiA64; - uiZ.v0 = uiA0; - goto uiZ; - } - if ( expB ) { - sigB.v64 |= UINT64_C( 0x0010000000000000 ); - } else { - --expDiff; - if ( ! expDiff ) goto newlyAlignedABigger; - } - sigB = softfloat_shiftRightJam128( sigB.v64, sigB.v0, expDiff ); - newlyAlignedABigger: - expZ = expA; - sigA.v64 |= UINT64_C( 0x0010000000000000 ); - aBigger: - sigZ = softfloat_sub128( sigA.v64, sigA.v0, sigB.v64, sigB.v0 ); - normRoundPack: - return softfloat_normRoundPackToF128( signZ, expZ - 5, sigZ.v64, sigZ.v0 ); - propagateNaN: - uiZ = softfloat_propagateNaNF128UI( uiA64, uiA0, uiB64, uiB0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF16.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF16.c deleted file mode 100644 index 6bbcb5c88..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF16.c +++ /dev/null @@ -1,187 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the -University of California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float16_t softfloat_subMagsF16( uint_fast16_t uiA, uint_fast16_t uiB ) -{ - int_fast8_t expA; - uint_fast16_t sigA; - int_fast8_t expB; - uint_fast16_t sigB; - int_fast8_t expDiff; - uint_fast16_t uiZ; - int_fast16_t sigDiff; - bool signZ; - int_fast8_t shiftDist, expZ; - uint_fast16_t sigZ, sigX, sigY; - uint_fast32_t sig32Z; - int_fast8_t roundingMode; - union ui16_f16 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expF16UI( uiA ); - sigA = fracF16UI( uiA ); - expB = expF16UI( uiB ); - sigB = fracF16UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( ! expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expA == 0x1F ) { - if ( sigA | sigB ) goto propagateNaN; - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF16UI; - goto uiZ; - } - sigDiff = sigA - sigB; - if ( ! sigDiff ) { - uiZ = - packToF16UI( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - goto uiZ; - } - if ( expA ) --expA; - signZ = signF16UI( uiA ); - if ( sigDiff < 0 ) { - signZ = ! signZ; - sigDiff = -sigDiff; - } - shiftDist = softfloat_countLeadingZeros16( sigDiff ) - 5; - expZ = expA - shiftDist; - if ( expZ < 0 ) { - shiftDist = expA; - expZ = 0; - } - sigZ = sigDiff<>16; - if ( sig32Z & 0xFFFF ) { - sigZ |= 1; - } else { - if ( ! (sigZ & 0xF) && ((unsigned int) expZ < 0x1E) ) { - sigZ >>= 4; - goto pack; - } - } - return softfloat_roundPackToF16( signZ, expZ, sigZ ); - } - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - propagateNaN: - uiZ = softfloat_propagateNaNF16UI( uiA, uiB ); - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - subEpsilon: - roundingMode = softfloat_roundingMode; - if ( roundingMode != softfloat_round_near_even ) { - if ( - (roundingMode == softfloat_round_minMag) - || (roundingMode - == (signF16UI( uiZ ) ? softfloat_round_max - : softfloat_round_min)) - ) { - --uiZ; - } -#ifdef SOFTFLOAT_ROUND_ODD - else if ( roundingMode == softfloat_round_odd ) { - uiZ = (uiZ - 1) | 1; - } -#endif - } - softfloat_exceptionFlags |= softfloat_flag_inexact; - goto uiZ; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - pack: - uiZ = packToF16UI( signZ, expZ, sigZ ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF32.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF32.c deleted file mode 100644 index 8b3aee0d6..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_subMagsF32.c +++ /dev/null @@ -1,143 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t softfloat_subMagsF32( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - int_fast16_t expA; - uint_fast32_t sigA; - int_fast16_t expB; - uint_fast32_t sigB; - int_fast16_t expDiff; - uint_fast32_t uiZ; - int_fast32_t sigDiff; - bool signZ; - int_fast8_t shiftDist; - int_fast16_t expZ; - uint_fast32_t sigX, sigY; - union ui32_f32 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( ! expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expA == 0xFF ) { - if ( sigA | sigB ) goto propagateNaN; - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF32UI; - goto uiZ; - } - sigDiff = sigA - sigB; - if ( ! sigDiff ) { - uiZ = - packToF32UI( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - goto uiZ; - } - if ( expA ) --expA; - signZ = signF32UI( uiA ); - if ( sigDiff < 0 ) { - signZ = ! signZ; - sigDiff = -sigDiff; - } - shiftDist = softfloat_countLeadingZeros32( sigDiff ) - 8; - expZ = expA - shiftDist; - if ( expZ < 0 ) { - shiftDist = expA; - expZ = 0; - } - uiZ = packToF32UI( signZ, expZ, sigDiff< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t - softfloat_subMagsF64( uint_fast64_t uiA, uint_fast64_t uiB, bool signZ ) -{ - int_fast16_t expA; - uint_fast64_t sigA; - int_fast16_t expB; - uint_fast64_t sigB; - int_fast16_t expDiff; - uint_fast64_t uiZ; - int_fast64_t sigDiff; - int_fast8_t shiftDist; - int_fast16_t expZ; - uint_fast64_t sigZ; - union ui64_f64 uZ; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - expDiff = expA - expB; - if ( ! expDiff ) { - /*-------------------------------------------------------------------- - *--------------------------------------------------------------------*/ - if ( expA == 0x7FF ) { - if ( sigA | sigB ) goto propagateNaN; - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - goto uiZ; - } - sigDiff = sigA - sigB; - if ( ! sigDiff ) { - uiZ = - packToF64UI( - (softfloat_roundingMode == softfloat_round_min), 0, 0 ); - goto uiZ; - } - if ( expA ) --expA; - if ( sigDiff < 0 ) { - signZ = ! signZ; - sigDiff = -sigDiff; - } - shiftDist = softfloat_countLeadingZeros64( sigDiff ) - 11; - expZ = expA - shiftDist; - if ( expZ < 0 ) { - shiftDist = expA; - expZ = 0; - } - uiZ = packToF64UI( signZ, expZ, sigDiff< -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -bool - softfloat_tryPropagateNaNExtF80M( - const struct extFloat80M *aSPtr, - const struct extFloat80M *bSPtr, - struct extFloat80M *zSPtr - ) -{ - uint_fast16_t ui64; - uint64_t ui0; - - ui64 = aSPtr->signExp; - ui0 = aSPtr->signif; - if ( isNaNExtF80UI( ui64, ui0 ) ) goto propagateNaN; - ui64 = bSPtr->signExp; - ui0 = bSPtr->signif; - if ( isNaNExtF80UI( ui64, ui0 ) ) goto propagateNaN; - return false; - propagateNaN: - softfloat_propagateNaNExtF80M( aSPtr, bSPtr, zSPtr ); - return true; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/s_tryPropagateNaNF128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/s_tryPropagateNaNF128M.c deleted file mode 100644 index 57199d963..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/s_tryPropagateNaNF128M.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" - -bool - softfloat_tryPropagateNaNF128M( - const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ) -{ - - if ( softfloat_isNaNF128M( aWPtr ) || softfloat_isNaNF128M( bWPtr ) ) { - softfloat_propagateNaNF128M( aWPtr, bWPtr, zWPtr ); - return true; - } - return false; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/softfloat_state.c b/source/src/vm/libcpu_newdev/softfloat3/source/softfloat_state.c deleted file mode 100644 index 277d76f95..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/softfloat_state.c +++ /dev/null @@ -1,52 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -#ifndef THREAD_LOCAL -#define THREAD_LOCAL -#endif - -THREAD_LOCAL uint_fast8_t softfloat_roundingMode = softfloat_round_near_even; -THREAD_LOCAL uint_fast8_t softfloat_detectTininess = init_detectTininess; -THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags = 0; - -THREAD_LOCAL uint_fast8_t extF80_roundingPrecision = 80; - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_extF80.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_extF80.c deleted file mode 100644 index dbb35c747..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_extF80.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -extFloat80_t ui32_to_extF80( uint32_t a ) -{ - uint_fast16_t uiZ64; - int_fast8_t shiftDist; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - uiZ64 = 0; - if ( a ) { - shiftDist = softfloat_countLeadingZeros32( a ); - uiZ64 = 0x401E - shiftDist; - a <<= shiftDist; - } - uZ.s.signExp = uiZ64; - uZ.s.signif = (uint_fast64_t) a<<32; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_extF80M.c deleted file mode 100644 index ec2396e61..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_extF80M.c +++ /dev/null @@ -1,74 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void ui32_to_extF80M( uint32_t a, extFloat80_t *zPtr ) -{ - - *zPtr = ui32_to_extF80( a ); - -} - -#else - -void ui32_to_extF80M( uint32_t a, extFloat80_t *zPtr ) -{ - struct extFloat80M *zSPtr; - uint_fast16_t uiZ64; - uint64_t sigZ; - int_fast8_t shiftDist; - - zSPtr = (struct extFloat80M *) zPtr; - uiZ64 = 0; - sigZ = 0; - if ( a ) { - shiftDist = softfloat_countLeadingZeros32( a ); - uiZ64 = packToExtF80UI64( 0, 0x401E - shiftDist ); - sigZ = (uint64_t) (a<signExp = uiZ64; - zSPtr->signif = sigZ; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f128.c deleted file mode 100644 index 8dcf2eb4d..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f128.c +++ /dev/null @@ -1,60 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t ui32_to_f128( uint32_t a ) -{ - uint_fast64_t uiZ64; - int_fast8_t shiftDist; - union ui128_f128 uZ; - - uiZ64 = 0; - if ( a ) { - shiftDist = softfloat_countLeadingZeros32( a ) + 17; - uiZ64 = - packToF128UI64( - 0, 0x402E - shiftDist, (uint_fast64_t) a< -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void ui32_to_f128M( uint32_t a, float128_t *zPtr ) -{ - - *zPtr = ui32_to_f128( a ); - -} - -#else - -void ui32_to_f128M( uint32_t a, float128_t *zPtr ) -{ - uint32_t *zWPtr, uiZ96, uiZ64; - int_fast8_t shiftDist; - uint64_t normA; - - zWPtr = (uint32_t *) zPtr; - uiZ96 = 0; - uiZ64 = 0; - if ( a ) { - shiftDist = softfloat_countLeadingZeros32( a ) + 17; - normA = (uint64_t) a<>32 ); - uiZ64 = normA; - } - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = uiZ64; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f16.c deleted file mode 100644 index a923f2234..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f16.c +++ /dev/null @@ -1,65 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t ui32_to_f16( uint32_t a ) -{ - int_fast8_t shiftDist; - union ui16_f16 u; - uint_fast16_t sig; - - shiftDist = softfloat_countLeadingZeros32( a ) - 21; - if ( 0 <= shiftDist ) { - u.ui = - a ? packToF16UI( - 0, 0x18 - shiftDist, (uint_fast16_t) a<>(-shiftDist) | ((uint32_t) (a<<(shiftDist & 31)) != 0) - : (uint_fast16_t) a< -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t ui32_to_f32( uint32_t a ) -{ - union ui32_f32 uZ; - - if ( ! a ) { - uZ.ui = 0; - return uZ.f; - } - if ( a & 0x80000000 ) { - return softfloat_roundPackToF32( 0, 0x9D, a>>1 | (a & 1) ); - } else { - return softfloat_normRoundPackToF32( 0, 0x9C, a ); - } - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f64.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f64.c deleted file mode 100644 index 11050c100..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui32_to_f64.c +++ /dev/null @@ -1,59 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t ui32_to_f64( uint32_t a ) -{ - uint_fast64_t uiZ; - int_fast8_t shiftDist; - union ui64_f64 uZ; - - if ( ! a ) { - uiZ = 0; - } else { - shiftDist = softfloat_countLeadingZeros32( a ) + 21; - uiZ = - packToF64UI( 0, 0x432 - shiftDist, (uint_fast64_t) a< -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -extFloat80_t ui64_to_extF80( uint64_t a ) -{ - uint_fast16_t uiZ64; - int_fast8_t shiftDist; - union { struct extFloat80M s; extFloat80_t f; } uZ; - - uiZ64 = 0; - if ( a ) { - shiftDist = softfloat_countLeadingZeros64( a ); - uiZ64 = 0x403E - shiftDist; - a <<= shiftDist; - } - uZ.s.signExp = uiZ64; - uZ.s.signif = a; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_extF80M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_extF80M.c deleted file mode 100644 index 96628843a..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_extF80M.c +++ /dev/null @@ -1,74 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void ui64_to_extF80M( uint64_t a, extFloat80_t *zPtr ) -{ - - *zPtr = ui64_to_extF80( a ); - -} - -#else - -void ui64_to_extF80M( uint64_t a, extFloat80_t *zPtr ) -{ - struct extFloat80M *zSPtr; - uint_fast16_t uiZ64; - uint64_t sigZ; - int_fast8_t shiftDist; - - zSPtr = (struct extFloat80M *) zPtr; - uiZ64 = 0; - sigZ = 0; - if ( a ) { - shiftDist = softfloat_countLeadingZeros64( a ); - uiZ64 = packToExtF80UI64( 0, 0x403E - shiftDist ); - sigZ = a<signExp = uiZ64; - zSPtr->signif = sigZ; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f128.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f128.c deleted file mode 100644 index c2c1ce3ec..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f128.c +++ /dev/null @@ -1,68 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float128_t ui64_to_f128( uint64_t a ) -{ - uint_fast64_t uiZ64, uiZ0; - int_fast8_t shiftDist; - struct uint128 zSig; - union ui128_f128 uZ; - - if ( ! a ) { - uiZ64 = 0; - uiZ0 = 0; - } else { - shiftDist = softfloat_countLeadingZeros64( a ) + 49; - if ( 64 <= shiftDist ) { - zSig.v64 = a<<(shiftDist - 64); - zSig.v0 = 0; - } else { - zSig = softfloat_shortShiftLeft128( 0, a, shiftDist ); - } - uiZ64 = packToF128UI64( 0, 0x406E - shiftDist, zSig.v64 ); - uiZ0 = zSig.v0; - } - uZ.ui.v64 = uiZ64; - uZ.ui.v0 = uiZ0; - return uZ.f; - -} - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f128M.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f128M.c deleted file mode 100644 index 2475304ba..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f128M.c +++ /dev/null @@ -1,86 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -#ifdef SOFTFLOAT_FAST_INT64 - -void ui64_to_f128M( uint64_t a, float128_t *zPtr ) -{ - - *zPtr = ui64_to_f128( a ); - -} - -#else - -void ui64_to_f128M( uint64_t a, float128_t *zPtr ) -{ - uint32_t *zWPtr, uiZ96, uiZ64; - uint_fast8_t shiftDist; - uint32_t *ptr; - - zWPtr = (uint32_t *) zPtr; - uiZ96 = 0; - uiZ64 = 0; - zWPtr[indexWord( 4, 1 )] = 0; - zWPtr[indexWord( 4, 0 )] = 0; - if ( a ) { - shiftDist = softfloat_countLeadingZeros64( a ) + 17; - if ( shiftDist < 32 ) { - ptr = zWPtr + indexMultiwordHi( 4, 3 ); - ptr[indexWord( 3, 2 )] = 0; - ptr[indexWord( 3, 1 )] = a>>32; - ptr[indexWord( 3, 0 )] = a; - softfloat_shortShiftLeft96M( ptr, shiftDist, ptr ); - ptr[indexWordHi( 3 )] = - packToF128UI96( 0, 0x404E - shiftDist, ptr[indexWordHi( 3 )] ); - return; - } - a <<= shiftDist - 32; - uiZ96 = packToF128UI96( 0, 0x404E - shiftDist, a>>32 ); - uiZ64 = a; - } - zWPtr[indexWord( 4, 3 )] = uiZ96; - zWPtr[indexWord( 4, 2 )] = uiZ64; - -} - -#endif - diff --git a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f16.c b/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f16.c deleted file mode 100644 index 9ff6e1739..000000000 --- a/source/src/vm/libcpu_newdev/softfloat3/source/ui64_to_f16.c +++ /dev/null @@ -1,64 +0,0 @@ - -/*============================================================================ - -This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic -Package, Release 3e, by John R. Hauser. - -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of -California. All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions, and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions, and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. Neither the name of the University nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -=============================================================================*/ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float16_t ui64_to_f16( uint64_t a ) -{ - int_fast8_t shiftDist; - union ui16_f16 u; - uint_fast16_t sig; - - shiftDist = softfloat_countLeadingZeros64( a ) - 53; - if ( 0 <= shiftDist ) { - u.ui = - a ? packToF16UI( - 0, 0x18 - shiftDist, (uint_fast16_t) a< -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t ui64_to_f32( uint64_t a ) -{ - int_fast8_t shiftDist; - union ui32_f32 u; - uint_fast32_t sig; - - shiftDist = softfloat_countLeadingZeros64( a ) - 40; - if ( 0 <= shiftDist ) { - u.ui = - a ? packToF32UI( - 0, 0x95 - shiftDist, (uint_fast32_t) a< -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t ui64_to_f64( uint64_t a ) -{ - union ui64_f64 uZ; - - if ( ! a ) { - uZ.ui = 0; - return uZ.f; - } - if ( a & UINT64_C( 0x8000000000000000 ) ) { - return - softfloat_roundPackToF64( - 0, 0x43D, softfloat_shortShiftRightJam64( a, 1 ) ); - } else { - return softfloat_normRoundPackToF64( 0, 0x43C, a ); - } - -} - diff --git a/source/src/vm/libcpu_newdev/vtlb/000_artane.txt b/source/src/vm/libcpu_newdev/vtlb/000_artane.txt deleted file mode 100644 index c36927343..000000000 --- a/source/src/vm/libcpu_newdev/vtlb/000_artane.txt +++ /dev/null @@ -1 +0,0 @@ -This source code from src/emu/, MAME 0.208. \ No newline at end of file diff --git a/source/src/vm/libcpu_newdev/vtlb/divtlb.cpp b/source/src/vm/libcpu_newdev/vtlb/divtlb.cpp deleted file mode 100644 index 1539c455c..000000000 --- a/source/src/vm/libcpu_newdev/vtlb/divtlb.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/* - Virtual TLB interfaces(universal) - - Origin : MAME 0.208 - Author : Kyuma.Ohta - Date : 2019.04.23- - -*/ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - divtlb.c - - Device generic virtual TLB interface. - -***************************************************************************/ - -#include "../../vm_template.h" -#include "../../../emu.h" -#include "./divtlb.h" - - -//************************************************************************** -// DEBUGGING -//************************************************************************** - -#define PRINTF_TLB (0) - - - -//************************************************************************** -// DEVICE VTLB INTERFACE -//************************************************************************** - -//------------------------------------------------- -// device_vtlb_interface - constructor -//------------------------------------------------- - -device_vtlb_interface::device_vtlb_interface(VM_TEMPLATE* parent_vm, EMU* parent_emu, DEVICE* parent_device, int space, int fixed_entries, int dynamic_entries) - : DEVICE(parent_vm, parent_emu), - m_space(space), - m_dynamic(dynamic_entries), - m_fixed(fixed_entries), - m_dynindex(0), - m_pageshift(12), - m_addrwidth(32), - m_table_base(nullptr) -{ - m_device = parent_device; - set_device_name(_T("VTLB DEVICE")); -} - - -//------------------------------------------------- -// device_vtlb_interface - destructor -//------------------------------------------------- - -device_vtlb_interface::~device_vtlb_interface() -{ -} - - -//------------------------------------------------- -// interface_validity_check - validation for a -// device after the configuration has been -// constructed -//------------------------------------------------- - -// -// 2019-04-23 K.O: Temporally disable interface_varidity_check(). -// -/* -void device_vtlb_interface::interface_validity_check(validity_checker &valid) const -{ - const device_memory_interface *intf; - if (!device().interface(intf)) - osd_printf_error("Device does not have memory interface\n"); - else - { - // validate CPU information - const address_space_config *spaceconfig = intf->space_config(m_space); - if (spaceconfig == nullptr) - osd_printf_error("No memory address space configuration found for space %d\n", m_space); - else if ((1 << spaceconfig->page_shift()) <= VTLB_FLAGS_MASK || spaceconfig->logaddr_width() <= spaceconfig->page_shift()) - osd_printf_error("Invalid page shift %d for VTLB\n", spaceconfig->page_shift()); - } -} -*/ - - -//------------------------------------------------- -// interface_pre_start - work to be done prior to -// actually starting a device -//------------------------------------------------- - -void device_vtlb_interface::initialize() -{ - // fill in CPU information - //const address_space_config *spaceconfig = device().memory().space_config(m_space); - //m_pageshift = spaceconfig->page_shift(); - //m_addrwidth = spaceconfig->logaddr_width(); - // -> You must call set_page_shift() and set_addr_width() before initialize. - // allocate the entry array - m_live.resize(m_fixed + m_dynamic); - memset(&m_live[0], 0, m_live.size()*sizeof(m_live[0])); - - // allocate the lookup table - m_table.resize((size_t)1 << (m_addrwidth - m_pageshift)); - memset(&m_table[0], 0, m_table.size() * sizeof(m_table[0])); - m_refcnt.resize((size_t)1 << (m_addrwidth - m_pageshift)); - memset(&m_refcnt[0], 0, m_refcnt.size() * sizeof(m_refcnt[0])); - // pointer to first element for quick access - m_table_base = &m_table[0]; - - // allocate the fixed page count array - if (m_fixed > 0) - { - m_fixedpages.resize(m_fixed); - memset(&m_fixedpages[0], 0, m_fixed*sizeof(m_fixedpages[0])); - } -} - -void device_vtlb_interface::release() -{ -} - -void device_vtlb_interface::reset() -{ - vtlb_flush_dynamic(); -} - - -//************************************************************************** -// FILLING -//************************************************************************** - -//------------------------------------------------- -// vtlb_fill - called by the CPU core in -// response to an unmapped access -//------------------------------------------------- - -bool device_vtlb_interface::vtlb_fill(offs_t address, int intention) -{ - offs_t tableindex = address >> m_pageshift; - vtlb_entry entry = m_table[tableindex]; - uint64_t taddress; - -#if PRINTF_TLB - out_debug_log("vtlb_fill: %08X(%X) ... ", address, intention); -#endif - - // should not be called here if the entry is in the table already -// assert((entry & (1 << intention)) == 0); - - // if we have no dynamic entries, we always fail - if (m_dynamic == 0) - { -#if PRINTF_TLB - out_debug_log("failed: no dynamic entries\n"); -#endif - return false; - } - - // ask the CPU core to translate for us - taddress = address; - if (!m_device->address_translate(m_space, intention, taddress)) - { -#if PRINTF_TLB - out_debug_log("failed: no translation\n"); -#endif - return false; - } - - // if this is the first successful translation for this address, allocate a new entry - if ((entry & VTLB_FLAGS_MASK) == 0) - { - int liveindex = m_dynindex++ % m_dynamic; - - - // if an entry already exists at this index, free it - if (m_live[liveindex] != 0) - { - if (m_refcnt[m_live[liveindex] - 1] <= 1) - m_table[m_live[liveindex] - 1] = 0; - else - m_refcnt[m_live[liveindex] - 1]--; - } - - - // claim this new entry - m_live[liveindex] = tableindex + 1; - - // form a new blank entry - entry = (taddress >> m_pageshift) << m_pageshift; - entry |= VTLB_FLAG_VALID; - -#if PRINTF_TLB - out_debug_log("success (%08X), new entry\n", taddress); -#endif - } - - // otherwise, ensure that different intentions do not produce different addresses - else - { - assert((entry >> m_pageshift) == (taddress >> m_pageshift)); - assert(entry & VTLB_FLAG_VALID); - -#if PRINTF_TLB - out_debug_log("success (%08X), existing entry\n", taddress); -#endif - } - - // add the intention to the list of valid intentions and store - entry |= 1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK)); - m_table[tableindex] = entry; - return true; -} - - -//------------------------------------------------- -// vtlb_load - load a fixed VTLB entry -//------------------------------------------------- - -void device_vtlb_interface::vtlb_load(int entrynum, int numpages, offs_t address, vtlb_entry value) -{ - offs_t tableindex = address >> m_pageshift; - int liveindex = m_dynamic + entrynum; - int pagenum; - - // must be in range - assert(entrynum >= 0 && entrynum < m_fixed); - -#if PRINTF_TLB - out_debug_log("vtlb_load %d for %d pages at %08X == %08X\n", entrynum, numpages, address, value); -#endif - - // if an entry already exists at this index, free it - if (m_live[liveindex] != 0) - { - int oldtableindex = m_live[liveindex] - 1; - m_refcnt[oldtableindex]--; - if (m_refcnt[oldtableindex] == 0) { - int pagecount = m_fixedpages[entrynum]; - for (pagenum = 0; pagenum < pagecount; pagenum++) { - m_table[oldtableindex + pagenum] = 0; - } - } - } - - // claim this new entry - m_live[liveindex] = tableindex + 1; - m_refcnt[tableindex]++; - - // store the raw value, making sure the "fixed" flag is set - value |= VTLB_FLAG_FIXED; - m_fixedpages[entrynum] = numpages; - for (pagenum = 0; pagenum < numpages; pagenum++) - m_table[tableindex + pagenum] = value + (pagenum << m_pageshift); -} - -//------------------------------------------------- -// vtlb_dynload - load a dynamic VTLB entry -//------------------------------------------------- - -void device_vtlb_interface::vtlb_dynload(u32 index, offs_t address, vtlb_entry value) -{ - vtlb_entry entry = m_table[index]; - - if (m_dynamic == 0) - { -#if PRINTF_TLB - out_debug_log("failed: no dynamic entries\n"); -#endif - return; - } - - int liveindex = m_dynindex++ % m_dynamic; - // is entry already live? - if (!(entry & VTLB_FLAG_VALID)) - { - // if an entry already exists at this index, free it - if (m_live[liveindex] != 0) - m_table[m_live[liveindex] - 1] = 0; - - // claim this new entry - m_live[liveindex] = index + 1; - } - // form a new blank entry - entry = (address >> m_pageshift) << m_pageshift; - entry |= VTLB_FLAG_VALID | value; - -#if PRINTF_TLB - out_debug_log("success (%08X), new entry\n", address); -#endif - m_table[index] = entry; -} - -//************************************************************************** -// FLUSHING -//************************************************************************** - -//------------------------------------------------- -// vtlb_flush_dynamic - flush all knowledge -// from the dynamic part of the VTLB -//------------------------------------------------- - -void device_vtlb_interface::vtlb_flush_dynamic() -{ -#if PRINTF_TLB - out_debug_log("vtlb_flush_dynamic\n"); -#endif - - // loop over live entries and release them from the table - for (int liveindex = 0; liveindex < m_dynamic; liveindex++) - if (m_live[liveindex] != 0) - { - offs_t tableindex = m_live[liveindex] - 1; - m_table[tableindex] = 0; - m_live[liveindex] = 0; - } -} - - -//------------------------------------------------- -// vtlb_flush_address - flush knowledge of a -// particular address from the VTLB -//------------------------------------------------- - -void device_vtlb_interface::vtlb_flush_address(offs_t address) -{ - offs_t tableindex = address >> m_pageshift; - -#if PRINTF_TLB - out_debug_log("vtlb_flush_address %08X\n", address); -#endif - - // free the entry in the table; for speed, we leave the entry in the live array - m_table[tableindex] = 0; -} - - - -//************************************************************************** -// ACCESSORS -//************************************************************************** - -//------------------------------------------------- -// vtlb_table - return a pointer to the base of -// the linear VTLB lookup table -//------------------------------------------------- - -const vtlb_entry *device_vtlb_interface::vtlb_table() const -{ - return m_table_base; -} - -#define STATE_VERSION 1 - -bool device_vtlb_device::process_state(FILEIO* fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - state_fio->StateValue(m_space); - state_fio->StateValue(m_dynamic); - state_fio->StateValue(m_fixed); - state_fio->StateValue(m_dynindex); - state_fio->StateValue(m_pageshift); - state_fio->StateValue(m_addrwidth); - - state_fio->StateVector(m_live); - state_fio->StateVector(m_table); - state_fio->StateVector(m_refpages); - if(m_fixed > 0) { - state_fio->StateVector(m_fixedpages); - } - return true; -} diff --git a/source/src/vm/libcpu_newdev/vtlb/divtlb.h b/source/src/vm/libcpu_newdev/vtlb/divtlb.h deleted file mode 100644 index 0a2acee90..000000000 --- a/source/src/vm/libcpu_newdev/vtlb/divtlb.h +++ /dev/null @@ -1,96 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -/*************************************************************************** - - divtlb.h - - Generic virtual TLB implementation. - -***************************************************************************/ - -#ifndef MAME_EMU_DIVTLB_H -#define MAME_EMU_DIVTLB_H - -#pragma once - -#include "device.h" - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -constexpr uint32_t VTLB_FLAGS_MASK = 0xff; - -constexpr uint32_t VTLB_READ_ALLOWED = 0x01; /* (1 << TRANSLATE_READ) */ -constexpr uint32_t VTLB_WRITE_ALLOWED = 0x02; /* (1 << TRANSLATE_WRITE) */ -constexpr uint32_t VTLB_FETCH_ALLOWED = 0x04; /* (1 << TRANSLATE_FETCH) */ -constexpr uint32_t VTLB_FLAG_VALID = 0x08; -constexpr uint32_t VTLB_USER_READ_ALLOWED = 0x10; /* (1 << TRANSLATE_READ_USER) */ -constexpr uint32_t VTLB_USER_WRITE_ALLOWED = 0x20; /* (1 << TRANSLATE_WRITE_USER) */ -constexpr uint32_t VTLB_USER_FETCH_ALLOWED = 0x40; /* (1 << TRANSLATE_FETCH_USER) */ -constexpr uint32_t VTLB_FLAG_FIXED = 0x80; - - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* represents an entry in the VTLB */ -typedef uint32_t vtlb_entry; -typedef uint32_t offs_t; - -// ======================> device_vtlb_interface -#include "../address_spacename.h" - -class VM_TEMPLATE; -class EMU; -class device_vtlb_interface : public DEVICE -{ -protected: - DEVICE* m_device; - // private state - int m_space; // address space - int m_dynamic; // number of dynamic entries - int m_fixed; // number of fixed entries - int m_dynindex; // index of next dynamic entry - int m_pageshift; // bits to shift to get page index - int m_addrwidth; // logical address bus width - std::vector m_live; // array of live entries by table index - std::vector m_fixedpages; // number of pages each fixed entry covers - std::vector m_table; // table of entries by address - std::vector m_refcnt; // table of entry reference counts by address - vtlb_entry *m_table_base; // pointer to m_table[0] -public: - // construction/destruction - device_vtlb_interface(VM_TEMPLATE* parent_vm, EMU* parent_emu, DEVICE* parent_device, int space, int fixed_entries = 0, int dynamic_entries = 0); - virtual ~device_vtlb_interface(); - - void initialize(); - void release(); - void reset(); - bool process_state(FILEIO* fio, bool loading); - - // configuration helpers - void set_vtlb_dynamic_entries(int entries) { m_dynamic = entries; } - void set_vtlb_fixed_entries(int entries) { m_fixed = entries; } - - // filling - bool vtlb_fill(offs_t address, int intention); - void vtlb_load(int entrynum, int numpages, offs_t address, vtlb_entry value); - void vtlb_dynload(uint32_t index, offs_t address, vtlb_entry value); - - // flushing - void vtlb_flush_dynamic(); - void vtlb_flush_address(offs_t address); - - // accessors - const vtlb_entry *vtlb_table() const; - // Original APIs, must call before initialize(). - void set_vtlb_page_shift(int m) { m_pageshift = m; } - void set_vtlb_addr_width(int m) { m_addrwidth = m; } - void set_parent_device(DEVICE* dev) { m_device = dev; } -}; - - -#endif /* MAME_EMU_DIVTLB_H */ diff --git a/source/src/vm/ls244.h b/source/src/vm/ls244.h index 17d02c40e..20c215bea 100644 --- a/source/src/vm/ls244.h +++ b/source/src/vm/ls244.h @@ -10,15 +10,11 @@ #ifndef _LS244_H_ #define _LS244_H_ -//#include "vm.h" -//#include "../emu.h" #include "device.h" #define SIG_LS244_INPUT 0 -class VM; -class EMU; -class LS244 : public DEVICE +class DLL_PREFIX LS244 : public DEVICE { private: // output signals @@ -27,7 +23,7 @@ class LS244 : public DEVICE uint8_t din; public: - LS244(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + LS244(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs); set_device_name(_T("74LS244 Octal 3-State Buffer")); diff --git a/source/src/vm/ls393.h b/source/src/vm/ls393.h index b3aab0861..369c59288 100644 --- a/source/src/vm/ls393.h +++ b/source/src/vm/ls393.h @@ -10,15 +10,11 @@ #ifndef _LS393_H_ #define _LS393_H_ -//#include "vm.h" -//#include "../emu.h" #include "device.h" #define SIG_LS393_CLK 0 -class VM; -class EMU; -class LS393 : public DEVICE +class DLL_PREFIX LS393 : public DEVICE { private: // output signals @@ -28,7 +24,7 @@ class LS393 : public DEVICE bool prev_in; public: - LS393(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + LS393(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 8; i++) { initialize_output_signals(&outputs[i]); diff --git a/source/src/vm/m5/CMakeLists.txt b/source/src/vm/m5/CMakeLists.txt index e4b360b52..58073561c 100644 --- a/source/src/vm/m5/CMakeLists.txt +++ b/source/src/vm/m5/CMakeLists.txt @@ -1,9 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/m5") +message("* vm/emum5") + +add_library(vm_emum5 -add_library(vm_m5 - m5.cpp cmt.cpp keyboard.cpp -) \ No newline at end of file + m5.cpp +) diff --git a/source/src/vm/m5/cmt.h b/source/src/vm/m5/cmt.h index baaa6170c..cb6d43064 100644 --- a/source/src/vm/m5/cmt.h +++ b/source/src/vm/m5/cmt.h @@ -36,7 +36,7 @@ class CMT : public DEVICE const uint8_t* key_stat; public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } diff --git a/source/src/vm/m5/keyboard.cpp b/source/src/vm/m5/keyboard.cpp index 1c1d46aed..dbf65f42f 100644 --- a/source/src/vm/m5/keyboard.cpp +++ b/source/src/vm/m5/keyboard.cpp @@ -13,7 +13,9 @@ namespace M5 { static const int key_map[7][8] = { // back-space (0x08): reset/halt key - {0x11, 0x09, 0x10, 0x10, 0x00, 0x00, 0x20, 0x0d}, + // Column0 From MAME 0.208: src/mame/drivers/m5.cpp 20191105 K.O. + // Column0 : Ctrl(LCONTROL), TAB, LSHIFT, RSHIFT, UNUSED, UNUSED, SPACE, ENTER + {VK_CONTROL, 0x09, VK_LSHIFT, VK_RSHIFT, 0x00, 0x00, 0x20, 0x0d}, {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, {0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49}, {0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b}, @@ -39,11 +41,18 @@ uint32_t KEYBOARD::read_io8(uint32_t addr) case 0x34: case 0x35: case 0x36: +/* case 0x38: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e:*/ for(int i = 0; i < 8; i++) { - val |= key_stat[key_map[addr & 0xf][i]] ? (1 << i) : 0; + val |= key_stat[key_map[addr & 0x7][i]] ? (1 << i) : 0; } return val; case 0x31: +// case 0x39: for(int i = 0; i < 8; i++) { val |= key_stat[key_map[1][i]] ? (1 << i) : 0; } @@ -53,6 +62,7 @@ uint32_t KEYBOARD::read_io8(uint32_t addr) val |= (joy_stat[1] & 0x20) ? 0x20 : 0; return val; case 0x37: +// case 0x3f: val |= (joy_stat[0] & 0x08) ? 0x01 : 0; val |= (joy_stat[0] & 0x01) ? 0x02 : 0; val |= (joy_stat[0] & 0x04) ? 0x04 : 0; diff --git a/source/src/vm/m5/keyboard.h b/source/src/vm/m5/keyboard.h index 4c3f1b872..57294488e 100644 --- a/source/src/vm/m5/keyboard.h +++ b/source/src/vm/m5/keyboard.h @@ -22,7 +22,7 @@ class KEYBOARD : public DEVICE const uint8_t* key_stat; const uint32_t* joy_stat; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/m5/m5.cpp b/source/src/vm/m5/m5.cpp index 42c92c79b..a7fc66797 100644 --- a/source/src/vm/m5/m5.cpp +++ b/source/src/vm/m5/m5.cpp @@ -35,7 +35,7 @@ using M5::KEYBOARD; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -49,6 +49,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) drec->set_context_noise_fast(new NOISE(this, emu)); io = new IO(this, emu); memory = new MEMORY(this, emu); + psg = new SN76489AN(this, emu); vdp = new TMS9918A(this, emu); #ifdef USE_DEBUGGER @@ -102,6 +103,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io->set_iomap_range_rw(0x10, 0x11, vdp); io->set_iomap_single_w(0x20, psg); io->set_iomap_range_r(0x30, 0x37, key); +// io->set_iomap_range_r(0x38, 0x3f, key); io->set_iomap_single_w(0x40, cmt); io->set_iomap_single_rw(0x50, cmt); @@ -344,6 +346,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -356,7 +370,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/m5/m5.h b/source/src/vm/m5/m5.h index f839af881..733f35e44 100644 --- a/source/src/vm/m5/m5.h +++ b/source/src/vm/m5/m5.h @@ -97,7 +97,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -148,6 +148,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/m6502.cpp b/source/src/vm/m6502.cpp index f9c8ae411..add87d73a 100644 --- a/source/src/vm/m6502.cpp +++ b/source/src/vm/m6502.cpp @@ -1030,10 +1030,10 @@ int M6502::run(int clock) #define offs_t UINT16 #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) +#define CPU_DISASSEMBLE(name) int DLL_PREFIX CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, oprom, d_debugger->first_symbol) const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length -extern CPU_DISASSEMBLE(m6502); +extern DLL_PREFIX_I CPU_DISASSEMBLE(m6502); int M6502::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) { diff --git a/source/src/vm/m6502.h b/source/src/vm/m6502.h index b1d8db12d..088578528 100644 --- a/source/src/vm/m6502.h +++ b/source/src/vm/m6502.h @@ -11,8 +11,6 @@ #ifndef _M6502_H_ #define _M6502_H_ -//#include "vm.h" -//#include "../emu.h" #include "device.h" #define SIG_M6502_OVERFLOW 0 @@ -21,7 +19,7 @@ class DEBUGGER; //#endif -class M6502_BASE : public DEVICE +class DLL_PREFIX M6502_BASE : public DEVICE { protected: DEVICE *d_mem, *d_pic; @@ -47,7 +45,7 @@ class M6502_BASE : public DEVICE void __FASTCALL update_irq(); public: - M6502_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + M6502_BASE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { total_icount = prev_total_icount = 0; busreq = false; @@ -65,7 +63,7 @@ class M6502_BASE : public DEVICE virtual int __FASTCALL run(int clock); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void set_intr_line(bool line, bool pending, uint32_t bit) + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit) { write_signal(SIG_CPU_IRQ, line ? 1 : 0, 1); } @@ -102,7 +100,7 @@ class M6502_BASE : public DEVICE { d_mem = device; } - void set_context_intr(DEVICE* device) + void set_context_intr(DEVICE* device, uint32_t bit = 0xfffffffff) { d_pic = device; } @@ -119,7 +117,7 @@ class M6502 : public M6502_BASE protected: void __FASTCALL OP(uint8_t code); public: - M6502(VM_TEMPLATE* parent_vm, EMU* parent_emu) : M6502_BASE(parent_vm, parent_emu) + M6502(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : M6502_BASE(parent_vm, parent_emu) { } ~M6502() {} @@ -135,7 +133,7 @@ class N2A03 : public M6502_BASE protected: void __FASTCALL OP(uint8_t code); public: - N2A03(VM_TEMPLATE* parent_vm, EMU* parent_emu) : M6502_BASE(parent_vm, parent_emu) + N2A03(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : M6502_BASE(parent_vm, parent_emu) { } ~N2A03() {} diff --git a/source/src/vm/m6502_base.cpp b/source/src/vm/m6502_base.cpp index 27e3dce6a..02f609539 100644 --- a/source/src/vm/m6502_base.cpp +++ b/source/src/vm/m6502_base.cpp @@ -246,7 +246,7 @@ bool M6502_BASE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) // CPU interface functions #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) +#define CPU_DISASSEMBLE(name) int DLL_PREFIX CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, oprom, d_debugger->first_symbol) /*****************************************************************************/ diff --git a/source/src/vm/mame/emu/cpu/h6280/h6280.h b/source/src/vm/mame/emu/cpu/h6280/h6280.h index d9ea42fce..94398abdb 100644 --- a/source/src/vm/mame/emu/cpu/h6280/h6280.h +++ b/source/src/vm/mame/emu/cpu/h6280/h6280.h @@ -54,7 +54,7 @@ struct h6280_Regs DEVICE *program; DEVICE *io; //#ifdef USE_DEBUGGER - EMU *emu; + EMU_TEMPLATE *emu; DEBUGGER *debugger; DEVICE *program_stored; DEVICE *io_stored; diff --git a/source/src/vm/mame/emu/cpu/i386/i386.c b/source/src/vm/mame/emu/cpu/i386/i386.c index e4fb610aa..367bb0ee8 100644 --- a/source/src/vm/mame/emu/cpu/i386/i386.c +++ b/source/src/vm/mame/emu/cpu/i386/i386.c @@ -54,7 +54,7 @@ static void pentium_smi(i386_state* cpustate); #define FAULT(fault,error) {\ /*logerror("FAULT(%s , %s) PC=%08x V8086=%s PROTECTED=%s SP=%08X:%08X\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO", (PROTECTED_MODE) ? cpustate->sreg[SS].base : (cpustate->sreg[SS].selector << 4), REG32(ESP)); */ \ if(cpustate->is_report_exception) { \ - cpustate->exception_code = ((UINT64)error << 32) | (UINT64)fault; \ + cpustate->exception_code = (((UINT64)error) << 32) | (UINT64)fault; \ cpustate->exception_pc = cpustate->prev_pc; \ cpustate->exception_caused = 1; \ cpustate->ext = 1; \ @@ -66,7 +66,7 @@ static void pentium_smi(i386_state* cpustate); #define FAULT_EXP(fault,error) { \ /*logerror("FAULT_EXP(%s , %s) PC=%08x V8086=%s PROTECTED=%s\n", #fault, #error, cpustate->pc, (cpustate->VM) ? "YES" : "NO", (PROTECTED_MODE) ? "YES" : "NO"); */ \ if(cpustate->is_report_exception) { \ - cpustate->exception_code = ((UINT64)error << 32) | (UINT64)fault; \ + cpustate->exception_code = (((UINT64)error) << 32) | (UINT64)fault; \ cpustate->exception_pc = cpustate->prev_pc; \ cpustate->exception_caused = 1; \ cpustate->ext = 1; \ @@ -78,6 +78,8 @@ static void pentium_smi(i386_state* cpustate); static void cpu_reset_generic(i386_state* cpustate) { + int busreq = cpustate->busreq; + int haltreq = cpustate->haltreq; switch(cpustate->cpu_type) { case N_CPU_TYPE_I386: CPU_RESET_CALL( i386 ); @@ -110,6 +112,8 @@ static void cpu_reset_generic(i386_state* cpustate) CPU_RESET_CALL( i386 ); break; } + cpustate->busreq = busreq; + cpustate->haltreq = haltreq; } @@ -119,7 +123,7 @@ static void cpu_reset_generic(i386_state* cpustate) { UINT32 v1,v2; UINT32 base, limit; - int entry; + UINT32 entry; if(!seg->selector) { @@ -164,7 +168,7 @@ static void cpu_reset_generic(i386_state* cpustate) { UINT32 v1,v2; UINT32 base,limit; - int entry; + UINT32 entry; if ( gate->segment & 0x4 ) { @@ -534,32 +538,7 @@ static UINT32 i386_get_stack_ptr(i386_state* cpustate, UINT8 privilege) i386_load_segment_descriptor(cpustate,reg); } } -#if 0 -static int i386_limit_check(i386_state *cpustate, int seg, UINT32 offset, UINT32 size) -{ - if(PROTECTED_MODE && !V8086_MODE) - { - if((cpustate->sreg[seg].flags & 0x0018) == 0x0010 && cpustate->sreg[seg].flags & 0x0004) // if expand-down data segment - { - // compare if greater then 0xffffffff when we're passed the access size - if(((offset + size - 1) <= cpustate->sreg[seg].limit) || ((cpustate->sreg[seg].d)?0:((offset + size - 1) > 0xffff))) - { - logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x (expand-down)\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset); - return 1; - } - } - else - { - if((offset + size - 1) > cpustate->sreg[seg].limit) - { - logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x\n",cpustate->pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset); - return 1; - } - } - } - return 0; -} -#endif + static void __FASTCALL i386_sreg_load(i386_state *cpustate, UINT16 selector, UINT8 reg, bool *fault) { // Checks done when MOV changes a segment register in protected mode @@ -958,7 +937,7 @@ static void __FASTCALL i386_trap(i386_state *cpustate,int irq, int irq_gate, int if((stack.flags & 0x0080) == 0) { logerror("IRQ: New stack segment is not present.\n"); - FAULT_EXP(FAULT_SS,(stack.selector & ~0x03)+cpustate->ext) // #TS(stack selector + EXT) + FAULT_EXP(FAULT_SS,((stack.selector & ~0x03) + cpustate->ext)) // #TS(stack selector + EXT) } newESP = i386_get_stack_ptr(cpustate,DPL); if(type & 0x08) // 32-bit gate @@ -1039,7 +1018,7 @@ static void __FASTCALL i386_trap(i386_state *cpustate,int irq, int irq_gate, int } else { - int stack_limit; + uint32_t stack_limit; if((desc.flags & 0x0004) || (DPL == CPL)) { /* IRQ to same privilege */ @@ -1528,7 +1507,6 @@ static void __FASTCALL i386_protected_mode_jump(i386_state *cpustate, UINT16 seg DPL = (desc.flags >> 5) & 0x03; // descriptor privilege level RPL = segment & 0x03; // requested privilege level - //logerror("JMP: protected mode PC=%08X SEG=%04x OFFSET=%08x VALID=%s BASE=%08x LIMIT=%08x FLAGS=%08x INDIRECT=%s OP32=%s V8086=%s CPL=%d DPL=%d RPL=%d\n", cpustate->prev_pc, seg, off, (desc.valid) ? "YES" : "NO", desc.base, desc.limit, desc.flags, (indirect != 0) ? "YES" : "NO", (operand32 != 0) ? "YES" : "NO" ,(V8086_MODE) ? "YES" : "NO", CPL, DPL, RPL); if((desc.flags & 0x0018) == 0x0018) { @@ -1536,7 +1514,7 @@ static void __FASTCALL i386_protected_mode_jump(i386_state *cpustate, UINT16 seg if((desc.flags & 0x0004) == 0) { /* non-conforming */ - if(RPL < CPL) + if(RPL > CPL) { logerror("JMP: RPL %i is less than CPL %i\n",RPL,CPL); FAULT(FAULT_GP,segment & 0xfffc) @@ -1550,7 +1528,7 @@ static void __FASTCALL i386_protected_mode_jump(i386_state *cpustate, UINT16 seg else { /* conforming */ - if(DPL < CPL) + if(DPL > CPL) { logerror("JMP: DPL %i is less than CPL %i\n",DPL,CPL); FAULT(FAULT_GP,segment & 0xfffc) @@ -1562,8 +1540,10 @@ static void __FASTCALL i386_protected_mode_jump(i386_state *cpustate, UINT16 seg logerror("JMP: Segment is not present\n"); FAULT(FAULT_NP,segment & 0xfffc) } - if(offset > desc.limit) + if((offset /*& cpustate->a20_mask*/) > desc.limit) { + logerror("JMP: SELECTOR=%04X BASE=%08X LIMIT=%08X FLAGS=%04X D=%d\n", + desc.selector, desc.base, desc.limit, desc.flags, desc.d); logerror("JMP: Offset is past segment limit\n"); FAULT(FAULT_GP,0) } @@ -1752,9 +1732,9 @@ static void __FASTCALL i386_protected_mode_jump(i386_state *cpustate, UINT16 seg if(SetRPL != 0) segment = (segment & ~0x03) | cpustate->CPL; if(operand32 == 0) - cpustate->eip = offset & 0x0000ffff; + cpustate->eip = (offset & 0x0000ffff) /*& cpustate->a20_mask*/; else - cpustate->eip = offset; + cpustate->eip = offset /*& cpustate->a20_mask*/; cpustate->sreg[CS].selector = segment; cpustate->performed_intersegment_jump = 1; i386_load_segment_descriptor(cpustate,CS); @@ -3021,7 +3001,8 @@ INLINE void __FASTCALL CYCLES_RM(i386_state *cpustate,int modrm, int r, int m) static void build_cycle_table() { - int i, j; + long unsigned int i; + int j; for (j=0; j < X86_NUM_CPUS; j++) { // cycle_table_rm[j] = (UINT8 *)malloc(CYCLES_NUM_OPCODES); @@ -3279,6 +3260,8 @@ CPU_INIT( i386 ) { i386_state *cpustate = i386_common_init(32); build_opcode_table(cpustate, OP_I386); +// build_opcode_table(cpustate, OP_I386 | OP_FPU); +// build_x87_opcode_table(cpustate); cpustate->cycle_table_rm = cycle_table_rm[CPU_CYCLES_I386]; cpustate->cycle_table_pm = cycle_table_pm[CPU_CYCLES_I386]; return cpustate; @@ -3286,7 +3269,7 @@ CPU_INIT( i386 ) static void build_opcode_table(i386_state *cpustate, UINT32 features) { - int i; + long unsigned int i; for (i=0; i < 256; i++) { cpustate->opcode_table1_16[i] = I386OP(invalid); @@ -3438,7 +3421,7 @@ static void zero_state(i386_state *cpustate) cpustate->dr[6] = 0xffff1ff0; cpustate->ext = 0; -// cpustate->halted = 0; + cpustate->halted = 0; // cpustate->busreq = 0; cpustate->shutdown = 0; cpustate->operand_size = 0; @@ -3508,6 +3491,8 @@ static CPU_RESET( i386 ) cpustate->nmi_masked = false; cpustate->nmi_latched = false; +// x87_reset(cpustate); + cpustate->a20_mask = ~0; // Move to zero_state(). cpustate->cr[0] = 0x7fffffe0; // reserved bits set to 1 @@ -3621,8 +3606,8 @@ static void i386_set_irq_line(i386_state *cpustate,int irqline, int state) { int first_cycles = cpustate->cycles; if (cpustate->haltreq != 0) { - cpustate->extra_cycles += first_cycles - cpustate->cycles; - cpustate->cycles = first_cycles; +// cpustate->extra_cycles += first_cycles - cpustate->cycles; +// cpustate->cycles = first_cycles; return; } if (state != CLEAR_LINE && cpustate->halted) @@ -3741,9 +3726,18 @@ static CPU_EXECUTE( i386 ) } } if (cycles == -1) { - int passed_cycles = max(1, cpustate->extra_cycles); + int passed_cycles = max(5, cpustate->extra_cycles); // 80386 CPI: 4.9 // this is main cpu, cpustate->cycles is not used - /*cpustate->cycles = */cpustate->extra_cycles = 0; + cpustate->cycles -= passed_cycles; + /* if busreq is raised, spin cpu while remained clock */ + if (cpustate->cycles > 0) { + cpustate->cycles = 0; + } +// cpustate->cycles = 0; + cpustate->base_cycles = cpustate->cycles; + + /* adjust for any interrupts that came in */ + cpustate->extra_cycles = 0; // cpu_wait_i386(cpustate, 1); cpustate->tsc += passed_cycles; //#ifdef USE_DEBUGGER @@ -3773,13 +3767,10 @@ static CPU_EXECUTE( i386 ) return passed_cycles; } } - int ncycles; if (cycles == -1) { cpustate->cycles = 1; - ncycles = 1; } else { cpustate->cycles += cycles; - ncycles = cycles; } cpustate->base_cycles = cpustate->cycles; @@ -3808,7 +3799,7 @@ static CPU_EXECUTE( i386 ) cpustate->debugger->exception_happened = true; exception_caused = false; exception_code = 0; - printf("EXCEPTION HIT PC=%08X CODE=%X\n", exception_pc, exception_code); + //printf("EXCEPTION HIT PC=%08X CODE=%X\n", exception_pc, exception_code); } cpustate->debugger->check_break_points(cpustate->pc); if(cpustate->debugger->now_suspended) { diff --git a/source/src/vm/mame/emu/cpu/i386/i386dasm.c b/source/src/vm/mame/emu/cpu/i386/i386dasm.c index 060e4c9a9..36f789d74 100644 --- a/source/src/vm/mame/emu/cpu/i386/i386dasm.c +++ b/source/src/vm/mame/emu/cpu/i386/i386dasm.c @@ -694,7 +694,7 @@ static const I386_OPCODE i386_opcode_table2[256] = {_T("bt"), MODRM, PARAM_RM, PARAM_REG, 0 }, {_T("shld"), MODRM, PARAM_RM, PARAM_REG, PARAM_UI8 }, {_T("shld"), MODRM, PARAM_RM, PARAM_REG, PARAM_CL }, - {_T("???"), 0, 0, 0, 0 }, + {_T("int 6"), 0, 0, 0, 0 }, {_T("???"), 0, 0, 0, 0 }, {_T("push gs"), 0, 0, 0, 0 }, {_T("pop gs"), 0, 0, 0, 0 }, @@ -2090,7 +2090,7 @@ static _TCHAR *hexstringpc(UINT64 pc) static _TCHAR *shexstring(UINT32 value, int digits, int always) { - static _TCHAR buffer[20]; + static _TCHAR buffer[32]; if (value >= 0x80000000) _stprintf(buffer, _T("-%s"), hexstring(-value, digits)); else if (always) diff --git a/source/src/vm/mame/emu/cpu/i386/i386op16.c b/source/src/vm/mame/emu/cpu/i386/i386op16.c index ab8f78628..a1503f2b8 100644 --- a/source/src/vm/mame/emu/cpu/i386/i386op16.c +++ b/source/src/vm/mame/emu/cpu/i386/i386op16.c @@ -494,7 +494,7 @@ static void __FASTCALL I386OP(call_abs16)(i386_state *cpustate) // Opcode CYCLES(cpustate,CYCLES_CALL_INTERSEG); /* TODO: Timing = 17 + m */ -//#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1); // ToDo: PROTECTED MODE CALL and PSEUDO-BIOS. // Q: In V8086_MODE, is enabled call far (foo)? @@ -3097,7 +3097,7 @@ static void __FASTCALL I386OP(groupFF_16)(i386_state *cpustate) // Opcode address = READ16(cpustate,ea + 0); selector = READ16(cpustate,ea + 2); CYCLES(cpustate,CYCLES_CALL_MEM_INTERSEG); /* TODO: Timing = 10 + m */ -//#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS UINT8 IOPL = cpustate->IOP1 | (cpustate->IOP2 << 1); // ToDo: PROTECTED MODE CALL and PSEUDO-BIOS. // Q: In V8086_MODE, is enabled call far (foo)? diff --git a/source/src/vm/mame/emu/cpu/i386/i386ops.h b/source/src/vm/mame/emu/cpu/i386/i386ops.h index c27be95f1..04113d1e5 100644 --- a/source/src/vm/mame/emu/cpu/i386/i386ops.h +++ b/source/src/vm/mame/emu/cpu/i386/i386ops.h @@ -33,853 +33,853 @@ struct X86_OPCODE { static const X86_OPCODE x86_opcode_table[] = { // Opcode Flags 16-bit handler 32-bit handler - { 0x00, OP_I386, I386OP(add_rm8_r8), I386OP(add_rm8_r8), true }, - { 0x01, OP_I386, I386OP(add_rm16_r16), I386OP(add_rm32_r32), true }, - { 0x02, OP_I386, I386OP(add_r8_rm8), I386OP(add_r8_rm8), false}, - { 0x03, OP_I386, I386OP(add_r16_rm16), I386OP(add_r32_rm32), false}, - { 0x04, OP_I386, I386OP(add_al_i8), I386OP(add_al_i8), false}, - { 0x05, OP_I386, I386OP(add_ax_i16), I386OP(add_eax_i32), false}, - { 0x06, OP_I386, I386OP(push_es16), I386OP(push_es32), false}, - { 0x07, OP_I386, I386OP(pop_es16), I386OP(pop_es32), false}, - { 0x08, OP_I386, I386OP(or_rm8_r8), I386OP(or_rm8_r8), true }, - { 0x09, OP_I386, I386OP(or_rm16_r16), I386OP(or_rm32_r32), true }, - { 0x0A, OP_I386, I386OP(or_r8_rm8), I386OP(or_r8_rm8), false}, - { 0x0B, OP_I386, I386OP(or_r16_rm16), I386OP(or_r32_rm32), false}, - { 0x0C, OP_I386, I386OP(or_al_i8), I386OP(or_al_i8), false}, - { 0x0D, OP_I386, I386OP(or_ax_i16), I386OP(or_eax_i32), false}, - { 0x0E, OP_I386, I386OP(push_cs16), I386OP(push_cs32), false}, - { 0x0F, OP_I386, I386OP(decode_two_byte), I386OP(decode_two_byte), true }, - { 0x10, OP_I386, I386OP(adc_rm8_r8), I386OP(adc_rm8_r8), true }, - { 0x11, OP_I386, I386OP(adc_rm16_r16), I386OP(adc_rm32_r32), true }, - { 0x12, OP_I386, I386OP(adc_r8_rm8), I386OP(adc_r8_rm8), false}, - { 0x13, OP_I386, I386OP(adc_r16_rm16), I386OP(adc_r32_rm32), false}, - { 0x14, OP_I386, I386OP(adc_al_i8), I386OP(adc_al_i8), false}, - { 0x15, OP_I386, I386OP(adc_ax_i16), I386OP(adc_eax_i32), false}, - { 0x16, OP_I386, I386OP(push_ss16), I386OP(push_ss32), false}, - { 0x17, OP_I386, I386OP(pop_ss16), I386OP(pop_ss32), false}, - { 0x18, OP_I386, I386OP(sbb_rm8_r8), I386OP(sbb_rm8_r8), true }, - { 0x19, OP_I386, I386OP(sbb_rm16_r16), I386OP(sbb_rm32_r32), true }, - { 0x1A, OP_I386, I386OP(sbb_r8_rm8), I386OP(sbb_r8_rm8), false}, - { 0x1B, OP_I386, I386OP(sbb_r16_rm16), I386OP(sbb_r32_rm32), false}, - { 0x1C, OP_I386, I386OP(sbb_al_i8), I386OP(sbb_al_i8), false}, - { 0x1D, OP_I386, I386OP(sbb_ax_i16), I386OP(sbb_eax_i32), false}, - { 0x1E, OP_I386, I386OP(push_ds16), I386OP(push_ds32), false}, - { 0x1F, OP_I386, I386OP(pop_ds16), I386OP(pop_ds32), false}, - { 0x20, OP_I386, I386OP(and_rm8_r8), I386OP(and_rm8_r8), true }, - { 0x21, OP_I386, I386OP(and_rm16_r16), I386OP(and_rm32_r32), true }, - { 0x22, OP_I386, I386OP(and_r8_rm8), I386OP(and_r8_rm8), false}, - { 0x23, OP_I386, I386OP(and_r16_rm16), I386OP(and_r32_rm32), false}, - { 0x24, OP_I386, I386OP(and_al_i8), I386OP(and_al_i8), false}, - { 0x25, OP_I386, I386OP(and_ax_i16), I386OP(and_eax_i32), false}, - { 0x26, OP_I386, I386OP(segment_ES), I386OP(segment_ES), true }, - { 0x27, OP_I386, I386OP(daa), I386OP(daa), false}, - { 0x28, OP_I386, I386OP(sub_rm8_r8), I386OP(sub_rm8_r8), true }, - { 0x29, OP_I386, I386OP(sub_rm16_r16), I386OP(sub_rm32_r32), true }, - { 0x2A, OP_I386, I386OP(sub_r8_rm8), I386OP(sub_r8_rm8), false}, - { 0x2B, OP_I386, I386OP(sub_r16_rm16), I386OP(sub_r32_rm32), false}, - { 0x2C, OP_I386, I386OP(sub_al_i8), I386OP(sub_al_i8), false}, - { 0x2D, OP_I386, I386OP(sub_ax_i16), I386OP(sub_eax_i32), false}, - { 0x2E, OP_I386, I386OP(segment_CS), I386OP(segment_CS), true }, - { 0x2F, OP_I386, I386OP(das), I386OP(das), false}, - { 0x30, OP_I386, I386OP(xor_rm8_r8), I386OP(xor_rm8_r8), true }, - { 0x31, OP_I386, I386OP(xor_rm16_r16), I386OP(xor_rm32_r32), true }, - { 0x32, OP_I386, I386OP(xor_r8_rm8), I386OP(xor_r8_rm8), false}, - { 0x33, OP_I386, I386OP(xor_r16_rm16), I386OP(xor_r32_rm32), false}, - { 0x34, OP_I386, I386OP(xor_al_i8), I386OP(xor_al_i8), false}, - { 0x35, OP_I386, I386OP(xor_ax_i16), I386OP(xor_eax_i32), false}, - { 0x36, OP_I386, I386OP(segment_SS), I386OP(segment_SS), true }, - { 0x37, OP_I386, I386OP(aaa), I386OP(aaa), false}, - { 0x38, OP_I386, I386OP(cmp_rm8_r8), I386OP(cmp_rm8_r8), false}, - { 0x39, OP_I386, I386OP(cmp_rm16_r16), I386OP(cmp_rm32_r32), false}, - { 0x3A, OP_I386, I386OP(cmp_r8_rm8), I386OP(cmp_r8_rm8), false}, - { 0x3B, OP_I386, I386OP(cmp_r16_rm16), I386OP(cmp_r32_rm32), false}, - { 0x3C, OP_I386, I386OP(cmp_al_i8), I386OP(cmp_al_i8), false}, - { 0x3D, OP_I386, I386OP(cmp_ax_i16), I386OP(cmp_eax_i32), false}, - { 0x3E, OP_I386, I386OP(segment_DS), I386OP(segment_DS), true }, - { 0x3F, OP_I386, I386OP(aas), I386OP(aas), false}, - { 0x40, OP_I386, I386OP(inc_ax), I386OP(inc_eax), false}, - { 0x41, OP_I386, I386OP(inc_cx), I386OP(inc_ecx), false}, - { 0x42, OP_I386, I386OP(inc_dx), I386OP(inc_edx), false}, - { 0x43, OP_I386, I386OP(inc_bx), I386OP(inc_ebx), false}, - { 0x44, OP_I386, I386OP(inc_sp), I386OP(inc_esp), false}, - { 0x45, OP_I386, I386OP(inc_bp), I386OP(inc_ebp), false}, - { 0x46, OP_I386, I386OP(inc_si), I386OP(inc_esi), false}, - { 0x47, OP_I386, I386OP(inc_di), I386OP(inc_edi), false}, - { 0x48, OP_I386, I386OP(dec_ax), I386OP(dec_eax), false}, - { 0x49, OP_I386, I386OP(dec_cx), I386OP(dec_ecx), false}, - { 0x4A, OP_I386, I386OP(dec_dx), I386OP(dec_edx), false}, - { 0x4B, OP_I386, I386OP(dec_bx), I386OP(dec_ebx), false}, - { 0x4C, OP_I386, I386OP(dec_sp), I386OP(dec_esp), false}, - { 0x4D, OP_I386, I386OP(dec_bp), I386OP(dec_ebp), false}, - { 0x4E, OP_I386, I386OP(dec_si), I386OP(dec_esi), false}, - { 0x4F, OP_I386, I386OP(dec_di), I386OP(dec_edi), false}, - { 0x50, OP_I386, I386OP(push_ax), I386OP(push_eax), false}, - { 0x51, OP_I386, I386OP(push_cx), I386OP(push_ecx), false}, - { 0x52, OP_I386, I386OP(push_dx), I386OP(push_edx), false}, - { 0x53, OP_I386, I386OP(push_bx), I386OP(push_ebx), false}, - { 0x54, OP_I386, I386OP(push_sp), I386OP(push_esp), false}, - { 0x55, OP_I386, I386OP(push_bp), I386OP(push_ebp), false}, - { 0x56, OP_I386, I386OP(push_si), I386OP(push_esi), false}, - { 0x57, OP_I386, I386OP(push_di), I386OP(push_edi), false}, - { 0x58, OP_I386, I386OP(pop_ax), I386OP(pop_eax), false}, - { 0x59, OP_I386, I386OP(pop_cx), I386OP(pop_ecx), false}, - { 0x5A, OP_I386, I386OP(pop_dx), I386OP(pop_edx), false}, - { 0x5B, OP_I386, I386OP(pop_bx), I386OP(pop_ebx), false}, - { 0x5C, OP_I386, I386OP(pop_sp), I386OP(pop_esp), false}, - { 0x5D, OP_I386, I386OP(pop_bp), I386OP(pop_ebp), false}, - { 0x5E, OP_I386, I386OP(pop_si), I386OP(pop_esi), false}, - { 0x5F, OP_I386, I386OP(pop_di), I386OP(pop_edi), false}, - { 0x60, OP_I386, I386OP(pusha), I386OP(pushad), false}, - { 0x61, OP_I386, I386OP(popa), I386OP(popad), false}, - { 0x62, OP_I386, I386OP(bound_r16_m16_m16), I386OP(bound_r32_m32_m32), false}, - { 0x63, OP_I386, I386OP(arpl), I386OP(arpl), false}, - { 0x64, OP_I386, I386OP(segment_FS), I386OP(segment_FS), true }, - { 0x65, OP_I386, I386OP(segment_GS), I386OP(segment_GS), true }, - { 0x66, OP_I386, I386OP(operand_size), I386OP(operand_size), true }, - { 0x67, OP_I386, I386OP(address_size), I386OP(address_size), true }, - { 0x68, OP_I386, I386OP(push_i16), I386OP(push_i32), false}, - { 0x69, OP_I386, I386OP(imul_r16_rm16_i16), I386OP(imul_r32_rm32_i32), false}, - { 0x6A, OP_I386, I386OP(push_i8), I386OP(push_i8), false}, - { 0x6B, OP_I386, I386OP(imul_r16_rm16_i8), I386OP(imul_r32_rm32_i8), false}, - { 0x6C, OP_I386, I386OP(insb), I386OP(insb), false}, - { 0x6D, OP_I386, I386OP(insw), I386OP(insd), false}, - { 0x6E, OP_I386, I386OP(outsb), I386OP(outsb), false}, - { 0x6F, OP_I386, I386OP(outsw), I386OP(outsd), false}, - { 0x70, OP_I386, I386OP(jo_rel8), I386OP(jo_rel8), false}, - { 0x71, OP_I386, I386OP(jno_rel8), I386OP(jno_rel8), false}, - { 0x72, OP_I386, I386OP(jc_rel8), I386OP(jc_rel8), false}, - { 0x73, OP_I386, I386OP(jnc_rel8), I386OP(jnc_rel8), false}, - { 0x74, OP_I386, I386OP(jz_rel8), I386OP(jz_rel8), false}, - { 0x75, OP_I386, I386OP(jnz_rel8), I386OP(jnz_rel8), false}, - { 0x76, OP_I386, I386OP(jbe_rel8), I386OP(jbe_rel8), false}, - { 0x77, OP_I386, I386OP(ja_rel8), I386OP(ja_rel8), false}, - { 0x78, OP_I386, I386OP(js_rel8), I386OP(js_rel8), false}, - { 0x79, OP_I386, I386OP(jns_rel8), I386OP(jns_rel8), false}, - { 0x7A, OP_I386, I386OP(jp_rel8), I386OP(jp_rel8), false}, - { 0x7B, OP_I386, I386OP(jnp_rel8), I386OP(jnp_rel8), false}, - { 0x7C, OP_I386, I386OP(jl_rel8), I386OP(jl_rel8), false}, - { 0x7D, OP_I386, I386OP(jge_rel8), I386OP(jge_rel8), false}, - { 0x7E, OP_I386, I386OP(jle_rel8), I386OP(jle_rel8), false}, - { 0x7F, OP_I386, I386OP(jg_rel8), I386OP(jg_rel8), false}, - { 0x80, OP_I386, I386OP(group80_8), I386OP(group80_8), true }, - { 0x81, OP_I386, I386OP(group81_16), I386OP(group81_32), true }, - { 0x82, OP_I386, I386OP(group80_8), I386OP(group80_8), true }, - { 0x83, OP_I386, I386OP(group83_16), I386OP(group83_32), true }, - { 0x84, OP_I386, I386OP(test_rm8_r8), I386OP(test_rm8_r8), false}, - { 0x85, OP_I386, I386OP(test_rm16_r16), I386OP(test_rm32_r32), false}, - { 0x86, OP_I386, I386OP(xchg_r8_rm8), I386OP(xchg_r8_rm8), true }, - { 0x87, OP_I386, I386OP(xchg_r16_rm16), I386OP(xchg_r32_rm32), true }, - { 0x88, OP_I386, I386OP(mov_rm8_r8), I386OP(mov_rm8_r8), false}, - { 0x89, OP_I386, I386OP(mov_rm16_r16), I386OP(mov_rm32_r32), false}, - { 0x8A, OP_I386, I386OP(mov_r8_rm8), I386OP(mov_r8_rm8), false}, - { 0x8B, OP_I386, I386OP(mov_r16_rm16), I386OP(mov_r32_rm32), false}, - { 0x8C, OP_I386, I386OP(mov_rm16_sreg), I386OP(mov_rm16_sreg), false}, - { 0x8D, OP_I386, I386OP(lea16), I386OP(lea32), false}, - { 0x8E, OP_I386, I386OP(mov_sreg_rm16), I386OP(mov_sreg_rm16), false}, - { 0x8F, OP_I386, I386OP(pop_rm16), I386OP(pop_rm32), false}, - { 0x90, OP_I386, I386OP(nop), I386OP(nop), false}, - { 0x91, OP_I386, I386OP(xchg_ax_cx), I386OP(xchg_eax_ecx), false}, - { 0x92, OP_I386, I386OP(xchg_ax_dx), I386OP(xchg_eax_edx), false}, - { 0x93, OP_I386, I386OP(xchg_ax_bx), I386OP(xchg_eax_ebx), false}, - { 0x94, OP_I386, I386OP(xchg_ax_sp), I386OP(xchg_eax_esp), false}, - { 0x95, OP_I386, I386OP(xchg_ax_bp), I386OP(xchg_eax_ebp), false}, - { 0x96, OP_I386, I386OP(xchg_ax_si), I386OP(xchg_eax_esi), false}, - { 0x97, OP_I386, I386OP(xchg_ax_di), I386OP(xchg_eax_edi), false}, - { 0x98, OP_I386, I386OP(cbw), I386OP(cwde), false}, - { 0x99, OP_I386, I386OP(cwd), I386OP(cdq), false}, - { 0x9A, OP_I386, I386OP(call_abs16), I386OP(call_abs32), false}, - { 0x9B, OP_I386, I386OP(wait), I386OP(wait), false}, - { 0x9C, OP_I386, I386OP(pushf), I386OP(pushfd), false}, - { 0x9D, OP_I386, I386OP(popf), I386OP(popfd), false}, - { 0x9E, OP_I386, I386OP(sahf), I386OP(sahf), false}, - { 0x9F, OP_I386, I386OP(lahf), I386OP(lahf), false}, - { 0xA0, OP_I386, I386OP(mov_al_m8), I386OP(mov_al_m8), false}, - { 0xA1, OP_I386, I386OP(mov_ax_m16), I386OP(mov_eax_m32), false}, - { 0xA2, OP_I386, I386OP(mov_m8_al), I386OP(mov_m8_al), false}, - { 0xA3, OP_I386, I386OP(mov_m16_ax), I386OP(mov_m32_eax), false}, - { 0xA4, OP_I386, I386OP(movsb), I386OP(movsb), false}, - { 0xA5, OP_I386, I386OP(movsw), I386OP(movsd), false}, - { 0xA6, OP_I386, I386OP(cmpsb), I386OP(cmpsb), false}, - { 0xA7, OP_I386, I386OP(cmpsw), I386OP(cmpsd), false}, - { 0xA8, OP_I386, I386OP(test_al_i8), I386OP(test_al_i8), false}, - { 0xA9, OP_I386, I386OP(test_ax_i16), I386OP(test_eax_i32), false}, - { 0xAA, OP_I386, I386OP(stosb), I386OP(stosb), false}, - { 0xAB, OP_I386, I386OP(stosw), I386OP(stosd), false}, - { 0xAC, OP_I386, I386OP(lodsb), I386OP(lodsb), false}, - { 0xAD, OP_I386, I386OP(lodsw), I386OP(lodsd), false}, - { 0xAE, OP_I386, I386OP(scasb), I386OP(scasb), false}, - { 0xAF, OP_I386, I386OP(scasw), I386OP(scasd), false}, - { 0xB0, OP_I386, I386OP(mov_al_i8), I386OP(mov_al_i8), false}, - { 0xB1, OP_I386, I386OP(mov_cl_i8), I386OP(mov_cl_i8), false}, - { 0xB2, OP_I386, I386OP(mov_dl_i8), I386OP(mov_dl_i8), false}, - { 0xB3, OP_I386, I386OP(mov_bl_i8), I386OP(mov_bl_i8), false}, - { 0xB4, OP_I386, I386OP(mov_ah_i8), I386OP(mov_ah_i8), false}, - { 0xB5, OP_I386, I386OP(mov_ch_i8), I386OP(mov_ch_i8), false}, - { 0xB6, OP_I386, I386OP(mov_dh_i8), I386OP(mov_dh_i8), false}, - { 0xB7, OP_I386, I386OP(mov_bh_i8), I386OP(mov_bh_i8), false}, - { 0xB8, OP_I386, I386OP(mov_ax_i16), I386OP(mov_eax_i32), false}, - { 0xB9, OP_I386, I386OP(mov_cx_i16), I386OP(mov_ecx_i32), false}, - { 0xBA, OP_I386, I386OP(mov_dx_i16), I386OP(mov_edx_i32), false}, - { 0xBB, OP_I386, I386OP(mov_bx_i16), I386OP(mov_ebx_i32), false}, - { 0xBC, OP_I386, I386OP(mov_sp_i16), I386OP(mov_esp_i32), false}, - { 0xBD, OP_I386, I386OP(mov_bp_i16), I386OP(mov_ebp_i32), false}, - { 0xBE, OP_I386, I386OP(mov_si_i16), I386OP(mov_esi_i32), false}, - { 0xBF, OP_I386, I386OP(mov_di_i16), I386OP(mov_edi_i32), false}, - { 0xC0, OP_I386, I386OP(groupC0_8), I386OP(groupC0_8), false}, - { 0xC1, OP_I386, I386OP(groupC1_16), I386OP(groupC1_32), false}, - { 0xC2, OP_I386, I386OP(ret_near16_i16), I386OP(ret_near32_i16), false}, - { 0xC3, OP_I386, I386OP(ret_near16), I386OP(ret_near32), false}, - { 0xC4, OP_I386, I386OP(les16), I386OP(les32), false}, - { 0xC5, OP_I386, I386OP(lds16), I386OP(lds32), false}, - { 0xC6, OP_I386, I386OP(mov_rm8_i8), I386OP(mov_rm8_i8), false}, - { 0xC7, OP_I386, I386OP(mov_rm16_i16), I386OP(mov_rm32_i32), false}, - { 0xC8, OP_I386, I386OP(enter16), I386OP(enter32), false}, - { 0xC9, OP_I386, I386OP(leave16), I386OP(leave32), false}, - { 0xCA, OP_I386, I386OP(retf_i16), I386OP(retf_i32), false}, - { 0xCB, OP_I386, I386OP(retf16), I386OP(retf32), false}, - { 0xCC, OP_I386, I386OP(int3), I386OP(int3), false}, - { 0xCD, OP_I386, I386OP(int_16), I386OP(int_32), false}, - { 0xCE, OP_I386, I386OP(into), I386OP(into), false}, - { 0xCF, OP_I386, I386OP(iret16), I386OP(iret32), false}, - { 0xD0, OP_I386, I386OP(groupD0_8), I386OP(groupD0_8), false}, - { 0xD1, OP_I386, I386OP(groupD1_16), I386OP(groupD1_32), false}, - { 0xD2, OP_I386, I386OP(groupD2_8), I386OP(groupD2_8), false}, - { 0xD3, OP_I386, I386OP(groupD3_16), I386OP(groupD3_32), false}, - { 0xD4, OP_I386, I386OP(aam), I386OP(aam), false}, - { 0xD5, OP_I386, I386OP(aad), I386OP(aad), false}, - { 0xD6, OP_I386, I386OP(setalc), I386OP(setalc), false}, - { 0xD7, OP_I386, I386OP(xlat), I386OP(xlat), false}, - { 0xD8, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xD9, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xDA, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xDB, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xDC, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xDD, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xDE, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xDF, OP_I386, I386OP(escape), I386OP(escape), false}, - { 0xD8, OP_FPU, I386OP(x87_group_d8), I386OP(x87_group_d8), false}, - { 0xD9, OP_FPU, I386OP(x87_group_d9), I386OP(x87_group_d9), false}, - { 0xDA, OP_FPU, I386OP(x87_group_da), I386OP(x87_group_da), false}, - { 0xDB, OP_FPU, I386OP(x87_group_db), I386OP(x87_group_db), false}, - { 0xDC, OP_FPU, I386OP(x87_group_dc), I386OP(x87_group_dc), false}, - { 0xDD, OP_FPU, I386OP(x87_group_dd), I386OP(x87_group_dd), false}, - { 0xDE, OP_FPU, I386OP(x87_group_de), I386OP(x87_group_de), false}, - { 0xDF, OP_FPU, I386OP(x87_group_df), I386OP(x87_group_df), false}, - { 0xE0, OP_I386, I386OP(loopne16), I386OP(loopne32), false}, - { 0xE1, OP_I386, I386OP(loopz16), I386OP(loopz32), false}, - { 0xE2, OP_I386, I386OP(loop16), I386OP(loop32), false}, - { 0xE3, OP_I386, I386OP(jcxz16), I386OP(jcxz32), false}, - { 0xE4, OP_I386, I386OP(in_al_i8), I386OP(in_al_i8), false}, - { 0xE5, OP_I386, I386OP(in_ax_i8), I386OP(in_eax_i8), false}, - { 0xE6, OP_I386, I386OP(out_al_i8), I386OP(out_al_i8), false}, - { 0xE7, OP_I386, I386OP(out_ax_i8), I386OP(out_eax_i8), false}, - { 0xE8, OP_I386, I386OP(call_rel16), I386OP(call_rel32), false}, - { 0xE9, OP_I386, I386OP(jmp_rel16), I386OP(jmp_rel32), false}, - { 0xEA, OP_I386, I386OP(jmp_abs16), I386OP(jmp_abs32), false}, - { 0xEB, OP_I386, I386OP(jmp_rel8), I386OP(jmp_rel8), false}, - { 0xEC, OP_I386, I386OP(in_al_dx), I386OP(in_al_dx), false}, - { 0xED, OP_I386, I386OP(in_ax_dx), I386OP(in_eax_dx), false}, - { 0xEE, OP_I386, I386OP(out_al_dx), I386OP(out_al_dx), false}, - { 0xEF, OP_I386, I386OP(out_ax_dx), I386OP(out_eax_dx), false}, - { 0xF0, OP_I386, I386OP(lock), I386OP(lock), false}, - { 0xF1, OP_I386, I386OP(invalid), I386OP(invalid), false}, - { 0xF2, OP_I386, I386OP(repne), I386OP(repne), false}, - { 0xF3, OP_I386, I386OP(rep), I386OP(rep), false}, - { 0xF4, OP_I386, I386OP(hlt), I386OP(hlt), false}, - { 0xF5, OP_I386, I386OP(cmc), I386OP(cmc), false}, - { 0xF6, OP_I386, I386OP(groupF6_8), I386OP(groupF6_8), true }, - { 0xF7, OP_I386, I386OP(groupF7_16), I386OP(groupF7_32), true }, - { 0xF8, OP_I386, I386OP(clc), I386OP(clc), false}, - { 0xF9, OP_I386, I386OP(stc), I386OP(stc), false}, - { 0xFA, OP_I386, I386OP(cli), I386OP(cli), false}, - { 0xFB, OP_I386, I386OP(sti), I386OP(sti), false}, - { 0xFC, OP_I386, I386OP(cld), I386OP(cld), false}, - { 0xFD, OP_I386, I386OP(std), I386OP(std), false}, - { 0xFE, OP_I386, I386OP(groupFE_8), I386OP(groupFE_8), true }, - { 0xFF, OP_I386, I386OP(groupFF_16), I386OP(groupFF_32), true }, + { 0x00, OP_I386, I386OP_D(add_rm8_r8), I386OP_D(add_rm8_r8), true }, + { 0x01, OP_I386, I386OP_D(add_rm16_r16), I386OP_D(add_rm32_r32), true }, + { 0x02, OP_I386, I386OP_D(add_r8_rm8), I386OP_D(add_r8_rm8), false}, + { 0x03, OP_I386, I386OP_D(add_r16_rm16), I386OP_D(add_r32_rm32), false}, + { 0x04, OP_I386, I386OP_D(add_al_i8), I386OP_D(add_al_i8), false}, + { 0x05, OP_I386, I386OP_D(add_ax_i16), I386OP_D(add_eax_i32), false}, + { 0x06, OP_I386, I386OP_D(push_es16), I386OP_D(push_es32), false}, + { 0x07, OP_I386, I386OP_D(pop_es16), I386OP_D(pop_es32), false}, + { 0x08, OP_I386, I386OP_D(or_rm8_r8), I386OP_D(or_rm8_r8), true }, + { 0x09, OP_I386, I386OP_D(or_rm16_r16), I386OP_D(or_rm32_r32), true }, + { 0x0A, OP_I386, I386OP_D(or_r8_rm8), I386OP_D(or_r8_rm8), false}, + { 0x0B, OP_I386, I386OP_D(or_r16_rm16), I386OP_D(or_r32_rm32), false}, + { 0x0C, OP_I386, I386OP_D(or_al_i8), I386OP_D(or_al_i8), false}, + { 0x0D, OP_I386, I386OP_D(or_ax_i16), I386OP_D(or_eax_i32), false}, + { 0x0E, OP_I386, I386OP_D(push_cs16), I386OP_D(push_cs32), false}, + { 0x0F, OP_I386, I386OP_D(decode_two_byte), I386OP_D(decode_two_byte), true }, + { 0x10, OP_I386, I386OP_D(adc_rm8_r8), I386OP_D(adc_rm8_r8), true }, + { 0x11, OP_I386, I386OP_D(adc_rm16_r16), I386OP_D(adc_rm32_r32), true }, + { 0x12, OP_I386, I386OP_D(adc_r8_rm8), I386OP_D(adc_r8_rm8), false}, + { 0x13, OP_I386, I386OP_D(adc_r16_rm16), I386OP_D(adc_r32_rm32), false}, + { 0x14, OP_I386, I386OP_D(adc_al_i8), I386OP_D(adc_al_i8), false}, + { 0x15, OP_I386, I386OP_D(adc_ax_i16), I386OP_D(adc_eax_i32), false}, + { 0x16, OP_I386, I386OP_D(push_ss16), I386OP_D(push_ss32), false}, + { 0x17, OP_I386, I386OP_D(pop_ss16), I386OP_D(pop_ss32), false}, + { 0x18, OP_I386, I386OP_D(sbb_rm8_r8), I386OP_D(sbb_rm8_r8), true }, + { 0x19, OP_I386, I386OP_D(sbb_rm16_r16), I386OP_D(sbb_rm32_r32), true }, + { 0x1A, OP_I386, I386OP_D(sbb_r8_rm8), I386OP_D(sbb_r8_rm8), false}, + { 0x1B, OP_I386, I386OP_D(sbb_r16_rm16), I386OP_D(sbb_r32_rm32), false}, + { 0x1C, OP_I386, I386OP_D(sbb_al_i8), I386OP_D(sbb_al_i8), false}, + { 0x1D, OP_I386, I386OP_D(sbb_ax_i16), I386OP_D(sbb_eax_i32), false}, + { 0x1E, OP_I386, I386OP_D(push_ds16), I386OP_D(push_ds32), false}, + { 0x1F, OP_I386, I386OP_D(pop_ds16), I386OP_D(pop_ds32), false}, + { 0x20, OP_I386, I386OP_D(and_rm8_r8), I386OP_D(and_rm8_r8), true }, + { 0x21, OP_I386, I386OP_D(and_rm16_r16), I386OP_D(and_rm32_r32), true }, + { 0x22, OP_I386, I386OP_D(and_r8_rm8), I386OP_D(and_r8_rm8), false}, + { 0x23, OP_I386, I386OP_D(and_r16_rm16), I386OP_D(and_r32_rm32), false}, + { 0x24, OP_I386, I386OP_D(and_al_i8), I386OP_D(and_al_i8), false}, + { 0x25, OP_I386, I386OP_D(and_ax_i16), I386OP_D(and_eax_i32), false}, + { 0x26, OP_I386, I386OP_D(segment_ES), I386OP_D(segment_ES), true }, + { 0x27, OP_I386, I386OP_D(daa), I386OP_D(daa), false}, + { 0x28, OP_I386, I386OP_D(sub_rm8_r8), I386OP_D(sub_rm8_r8), true }, + { 0x29, OP_I386, I386OP_D(sub_rm16_r16), I386OP_D(sub_rm32_r32), true }, + { 0x2A, OP_I386, I386OP_D(sub_r8_rm8), I386OP_D(sub_r8_rm8), false}, + { 0x2B, OP_I386, I386OP_D(sub_r16_rm16), I386OP_D(sub_r32_rm32), false}, + { 0x2C, OP_I386, I386OP_D(sub_al_i8), I386OP_D(sub_al_i8), false}, + { 0x2D, OP_I386, I386OP_D(sub_ax_i16), I386OP_D(sub_eax_i32), false}, + { 0x2E, OP_I386, I386OP_D(segment_CS), I386OP_D(segment_CS), true }, + { 0x2F, OP_I386, I386OP_D(das), I386OP_D(das), false}, + { 0x30, OP_I386, I386OP_D(xor_rm8_r8), I386OP_D(xor_rm8_r8), true }, + { 0x31, OP_I386, I386OP_D(xor_rm16_r16), I386OP_D(xor_rm32_r32), true }, + { 0x32, OP_I386, I386OP_D(xor_r8_rm8), I386OP_D(xor_r8_rm8), false}, + { 0x33, OP_I386, I386OP_D(xor_r16_rm16), I386OP_D(xor_r32_rm32), false}, + { 0x34, OP_I386, I386OP_D(xor_al_i8), I386OP_D(xor_al_i8), false}, + { 0x35, OP_I386, I386OP_D(xor_ax_i16), I386OP_D(xor_eax_i32), false}, + { 0x36, OP_I386, I386OP_D(segment_SS), I386OP_D(segment_SS), true }, + { 0x37, OP_I386, I386OP_D(aaa), I386OP_D(aaa), false}, + { 0x38, OP_I386, I386OP_D(cmp_rm8_r8), I386OP_D(cmp_rm8_r8), false}, + { 0x39, OP_I386, I386OP_D(cmp_rm16_r16), I386OP_D(cmp_rm32_r32), false}, + { 0x3A, OP_I386, I386OP_D(cmp_r8_rm8), I386OP_D(cmp_r8_rm8), false}, + { 0x3B, OP_I386, I386OP_D(cmp_r16_rm16), I386OP_D(cmp_r32_rm32), false}, + { 0x3C, OP_I386, I386OP_D(cmp_al_i8), I386OP_D(cmp_al_i8), false}, + { 0x3D, OP_I386, I386OP_D(cmp_ax_i16), I386OP_D(cmp_eax_i32), false}, + { 0x3E, OP_I386, I386OP_D(segment_DS), I386OP_D(segment_DS), true }, + { 0x3F, OP_I386, I386OP_D(aas), I386OP_D(aas), false}, + { 0x40, OP_I386, I386OP_D(inc_ax), I386OP_D(inc_eax), false}, + { 0x41, OP_I386, I386OP_D(inc_cx), I386OP_D(inc_ecx), false}, + { 0x42, OP_I386, I386OP_D(inc_dx), I386OP_D(inc_edx), false}, + { 0x43, OP_I386, I386OP_D(inc_bx), I386OP_D(inc_ebx), false}, + { 0x44, OP_I386, I386OP_D(inc_sp), I386OP_D(inc_esp), false}, + { 0x45, OP_I386, I386OP_D(inc_bp), I386OP_D(inc_ebp), false}, + { 0x46, OP_I386, I386OP_D(inc_si), I386OP_D(inc_esi), false}, + { 0x47, OP_I386, I386OP_D(inc_di), I386OP_D(inc_edi), false}, + { 0x48, OP_I386, I386OP_D(dec_ax), I386OP_D(dec_eax), false}, + { 0x49, OP_I386, I386OP_D(dec_cx), I386OP_D(dec_ecx), false}, + { 0x4A, OP_I386, I386OP_D(dec_dx), I386OP_D(dec_edx), false}, + { 0x4B, OP_I386, I386OP_D(dec_bx), I386OP_D(dec_ebx), false}, + { 0x4C, OP_I386, I386OP_D(dec_sp), I386OP_D(dec_esp), false}, + { 0x4D, OP_I386, I386OP_D(dec_bp), I386OP_D(dec_ebp), false}, + { 0x4E, OP_I386, I386OP_D(dec_si), I386OP_D(dec_esi), false}, + { 0x4F, OP_I386, I386OP_D(dec_di), I386OP_D(dec_edi), false}, + { 0x50, OP_I386, I386OP_D(push_ax), I386OP_D(push_eax), false}, + { 0x51, OP_I386, I386OP_D(push_cx), I386OP_D(push_ecx), false}, + { 0x52, OP_I386, I386OP_D(push_dx), I386OP_D(push_edx), false}, + { 0x53, OP_I386, I386OP_D(push_bx), I386OP_D(push_ebx), false}, + { 0x54, OP_I386, I386OP_D(push_sp), I386OP_D(push_esp), false}, + { 0x55, OP_I386, I386OP_D(push_bp), I386OP_D(push_ebp), false}, + { 0x56, OP_I386, I386OP_D(push_si), I386OP_D(push_esi), false}, + { 0x57, OP_I386, I386OP_D(push_di), I386OP_D(push_edi), false}, + { 0x58, OP_I386, I386OP_D(pop_ax), I386OP_D(pop_eax), false}, + { 0x59, OP_I386, I386OP_D(pop_cx), I386OP_D(pop_ecx), false}, + { 0x5A, OP_I386, I386OP_D(pop_dx), I386OP_D(pop_edx), false}, + { 0x5B, OP_I386, I386OP_D(pop_bx), I386OP_D(pop_ebx), false}, + { 0x5C, OP_I386, I386OP_D(pop_sp), I386OP_D(pop_esp), false}, + { 0x5D, OP_I386, I386OP_D(pop_bp), I386OP_D(pop_ebp), false}, + { 0x5E, OP_I386, I386OP_D(pop_si), I386OP_D(pop_esi), false}, + { 0x5F, OP_I386, I386OP_D(pop_di), I386OP_D(pop_edi), false}, + { 0x60, OP_I386, I386OP_D(pusha), I386OP_D(pushad), false}, + { 0x61, OP_I386, I386OP_D(popa), I386OP_D(popad), false}, + { 0x62, OP_I386, I386OP_D(bound_r16_m16_m16), I386OP_D(bound_r32_m32_m32), false}, + { 0x63, OP_I386, I386OP_D(arpl), I386OP_D(arpl), false}, + { 0x64, OP_I386, I386OP_D(segment_FS), I386OP_D(segment_FS), true }, + { 0x65, OP_I386, I386OP_D(segment_GS), I386OP_D(segment_GS), true }, + { 0x66, OP_I386, I386OP_D(operand_size), I386OP_D(operand_size), true }, + { 0x67, OP_I386, I386OP_D(address_size), I386OP_D(address_size), true }, + { 0x68, OP_I386, I386OP_D(push_i16), I386OP_D(push_i32), false}, + { 0x69, OP_I386, I386OP_D(imul_r16_rm16_i16), I386OP_D(imul_r32_rm32_i32), false}, + { 0x6A, OP_I386, I386OP_D(push_i8), I386OP_D(push_i8), false}, + { 0x6B, OP_I386, I386OP_D(imul_r16_rm16_i8), I386OP_D(imul_r32_rm32_i8), false}, + { 0x6C, OP_I386, I386OP_D(insb), I386OP_D(insb), false}, + { 0x6D, OP_I386, I386OP_D(insw), I386OP_D(insd), false}, + { 0x6E, OP_I386, I386OP_D(outsb), I386OP_D(outsb), false}, + { 0x6F, OP_I386, I386OP_D(outsw), I386OP_D(outsd), false}, + { 0x70, OP_I386, I386OP_D(jo_rel8), I386OP_D(jo_rel8), false}, + { 0x71, OP_I386, I386OP_D(jno_rel8), I386OP_D(jno_rel8), false}, + { 0x72, OP_I386, I386OP_D(jc_rel8), I386OP_D(jc_rel8), false}, + { 0x73, OP_I386, I386OP_D(jnc_rel8), I386OP_D(jnc_rel8), false}, + { 0x74, OP_I386, I386OP_D(jz_rel8), I386OP_D(jz_rel8), false}, + { 0x75, OP_I386, I386OP_D(jnz_rel8), I386OP_D(jnz_rel8), false}, + { 0x76, OP_I386, I386OP_D(jbe_rel8), I386OP_D(jbe_rel8), false}, + { 0x77, OP_I386, I386OP_D(ja_rel8), I386OP_D(ja_rel8), false}, + { 0x78, OP_I386, I386OP_D(js_rel8), I386OP_D(js_rel8), false}, + { 0x79, OP_I386, I386OP_D(jns_rel8), I386OP_D(jns_rel8), false}, + { 0x7A, OP_I386, I386OP_D(jp_rel8), I386OP_D(jp_rel8), false}, + { 0x7B, OP_I386, I386OP_D(jnp_rel8), I386OP_D(jnp_rel8), false}, + { 0x7C, OP_I386, I386OP_D(jl_rel8), I386OP_D(jl_rel8), false}, + { 0x7D, OP_I386, I386OP_D(jge_rel8), I386OP_D(jge_rel8), false}, + { 0x7E, OP_I386, I386OP_D(jle_rel8), I386OP_D(jle_rel8), false}, + { 0x7F, OP_I386, I386OP_D(jg_rel8), I386OP_D(jg_rel8), false}, + { 0x80, OP_I386, I386OP_D(group80_8), I386OP_D(group80_8), true }, + { 0x81, OP_I386, I386OP_D(group81_16), I386OP_D(group81_32), true }, + { 0x82, OP_I386, I386OP_D(group80_8), I386OP_D(group80_8), true }, + { 0x83, OP_I386, I386OP_D(group83_16), I386OP_D(group83_32), true }, + { 0x84, OP_I386, I386OP_D(test_rm8_r8), I386OP_D(test_rm8_r8), false}, + { 0x85, OP_I386, I386OP_D(test_rm16_r16), I386OP_D(test_rm32_r32), false}, + { 0x86, OP_I386, I386OP_D(xchg_r8_rm8), I386OP_D(xchg_r8_rm8), true }, + { 0x87, OP_I386, I386OP_D(xchg_r16_rm16), I386OP_D(xchg_r32_rm32), true }, + { 0x88, OP_I386, I386OP_D(mov_rm8_r8), I386OP_D(mov_rm8_r8), false}, + { 0x89, OP_I386, I386OP_D(mov_rm16_r16), I386OP_D(mov_rm32_r32), false}, + { 0x8A, OP_I386, I386OP_D(mov_r8_rm8), I386OP_D(mov_r8_rm8), false}, + { 0x8B, OP_I386, I386OP_D(mov_r16_rm16), I386OP_D(mov_r32_rm32), false}, + { 0x8C, OP_I386, I386OP_D(mov_rm16_sreg), I386OP_D(mov_rm16_sreg), false}, + { 0x8D, OP_I386, I386OP_D(lea16), I386OP_D(lea32), false}, + { 0x8E, OP_I386, I386OP_D(mov_sreg_rm16), I386OP_D(mov_sreg_rm16), false}, + { 0x8F, OP_I386, I386OP_D(pop_rm16), I386OP_D(pop_rm32), false}, + { 0x90, OP_I386, I386OP_D(nop), I386OP_D(nop), false}, + { 0x91, OP_I386, I386OP_D(xchg_ax_cx), I386OP_D(xchg_eax_ecx), false}, + { 0x92, OP_I386, I386OP_D(xchg_ax_dx), I386OP_D(xchg_eax_edx), false}, + { 0x93, OP_I386, I386OP_D(xchg_ax_bx), I386OP_D(xchg_eax_ebx), false}, + { 0x94, OP_I386, I386OP_D(xchg_ax_sp), I386OP_D(xchg_eax_esp), false}, + { 0x95, OP_I386, I386OP_D(xchg_ax_bp), I386OP_D(xchg_eax_ebp), false}, + { 0x96, OP_I386, I386OP_D(xchg_ax_si), I386OP_D(xchg_eax_esi), false}, + { 0x97, OP_I386, I386OP_D(xchg_ax_di), I386OP_D(xchg_eax_edi), false}, + { 0x98, OP_I386, I386OP_D(cbw), I386OP_D(cwde), false}, + { 0x99, OP_I386, I386OP_D(cwd), I386OP_D(cdq), false}, + { 0x9A, OP_I386, I386OP_D(call_abs16), I386OP_D(call_abs32), false}, + { 0x9B, OP_I386, I386OP_D(wait), I386OP_D(wait), false}, + { 0x9C, OP_I386, I386OP_D(pushf), I386OP_D(pushfd), false}, + { 0x9D, OP_I386, I386OP_D(popf), I386OP_D(popfd), false}, + { 0x9E, OP_I386, I386OP_D(sahf), I386OP_D(sahf), false}, + { 0x9F, OP_I386, I386OP_D(lahf), I386OP_D(lahf), false}, + { 0xA0, OP_I386, I386OP_D(mov_al_m8), I386OP_D(mov_al_m8), false}, + { 0xA1, OP_I386, I386OP_D(mov_ax_m16), I386OP_D(mov_eax_m32), false}, + { 0xA2, OP_I386, I386OP_D(mov_m8_al), I386OP_D(mov_m8_al), false}, + { 0xA3, OP_I386, I386OP_D(mov_m16_ax), I386OP_D(mov_m32_eax), false}, + { 0xA4, OP_I386, I386OP_D(movsb), I386OP_D(movsb), false}, + { 0xA5, OP_I386, I386OP_D(movsw), I386OP_D(movsd), false}, + { 0xA6, OP_I386, I386OP_D(cmpsb), I386OP_D(cmpsb), false}, + { 0xA7, OP_I386, I386OP_D(cmpsw), I386OP_D(cmpsd), false}, + { 0xA8, OP_I386, I386OP_D(test_al_i8), I386OP_D(test_al_i8), false}, + { 0xA9, OP_I386, I386OP_D(test_ax_i16), I386OP_D(test_eax_i32), false}, + { 0xAA, OP_I386, I386OP_D(stosb), I386OP_D(stosb), false}, + { 0xAB, OP_I386, I386OP_D(stosw), I386OP_D(stosd), false}, + { 0xAC, OP_I386, I386OP_D(lodsb), I386OP_D(lodsb), false}, + { 0xAD, OP_I386, I386OP_D(lodsw), I386OP_D(lodsd), false}, + { 0xAE, OP_I386, I386OP_D(scasb), I386OP_D(scasb), false}, + { 0xAF, OP_I386, I386OP_D(scasw), I386OP_D(scasd), false}, + { 0xB0, OP_I386, I386OP_D(mov_al_i8), I386OP_D(mov_al_i8), false}, + { 0xB1, OP_I386, I386OP_D(mov_cl_i8), I386OP_D(mov_cl_i8), false}, + { 0xB2, OP_I386, I386OP_D(mov_dl_i8), I386OP_D(mov_dl_i8), false}, + { 0xB3, OP_I386, I386OP_D(mov_bl_i8), I386OP_D(mov_bl_i8), false}, + { 0xB4, OP_I386, I386OP_D(mov_ah_i8), I386OP_D(mov_ah_i8), false}, + { 0xB5, OP_I386, I386OP_D(mov_ch_i8), I386OP_D(mov_ch_i8), false}, + { 0xB6, OP_I386, I386OP_D(mov_dh_i8), I386OP_D(mov_dh_i8), false}, + { 0xB7, OP_I386, I386OP_D(mov_bh_i8), I386OP_D(mov_bh_i8), false}, + { 0xB8, OP_I386, I386OP_D(mov_ax_i16), I386OP_D(mov_eax_i32), false}, + { 0xB9, OP_I386, I386OP_D(mov_cx_i16), I386OP_D(mov_ecx_i32), false}, + { 0xBA, OP_I386, I386OP_D(mov_dx_i16), I386OP_D(mov_edx_i32), false}, + { 0xBB, OP_I386, I386OP_D(mov_bx_i16), I386OP_D(mov_ebx_i32), false}, + { 0xBC, OP_I386, I386OP_D(mov_sp_i16), I386OP_D(mov_esp_i32), false}, + { 0xBD, OP_I386, I386OP_D(mov_bp_i16), I386OP_D(mov_ebp_i32), false}, + { 0xBE, OP_I386, I386OP_D(mov_si_i16), I386OP_D(mov_esi_i32), false}, + { 0xBF, OP_I386, I386OP_D(mov_di_i16), I386OP_D(mov_edi_i32), false}, + { 0xC0, OP_I386, I386OP_D(groupC0_8), I386OP_D(groupC0_8), false}, + { 0xC1, OP_I386, I386OP_D(groupC1_16), I386OP_D(groupC1_32), false}, + { 0xC2, OP_I386, I386OP_D(ret_near16_i16), I386OP_D(ret_near32_i16), false}, + { 0xC3, OP_I386, I386OP_D(ret_near16), I386OP_D(ret_near32), false}, + { 0xC4, OP_I386, I386OP_D(les16), I386OP_D(les32), false}, + { 0xC5, OP_I386, I386OP_D(lds16), I386OP_D(lds32), false}, + { 0xC6, OP_I386, I386OP_D(mov_rm8_i8), I386OP_D(mov_rm8_i8), false}, + { 0xC7, OP_I386, I386OP_D(mov_rm16_i16), I386OP_D(mov_rm32_i32), false}, + { 0xC8, OP_I386, I386OP_D(enter16), I386OP_D(enter32), false}, + { 0xC9, OP_I386, I386OP_D(leave16), I386OP_D(leave32), false}, + { 0xCA, OP_I386, I386OP_D(retf_i16), I386OP_D(retf_i32), false}, + { 0xCB, OP_I386, I386OP_D(retf16), I386OP_D(retf32), false}, + { 0xCC, OP_I386, I386OP_D(int3), I386OP_D(int3), false}, + { 0xCD, OP_I386, I386OP_D(int_16), I386OP_D(int_32), false}, + { 0xCE, OP_I386, I386OP_D(into), I386OP_D(into), false}, + { 0xCF, OP_I386, I386OP_D(iret16), I386OP_D(iret32), false}, + { 0xD0, OP_I386, I386OP_D(groupD0_8), I386OP_D(groupD0_8), false}, + { 0xD1, OP_I386, I386OP_D(groupD1_16), I386OP_D(groupD1_32), false}, + { 0xD2, OP_I386, I386OP_D(groupD2_8), I386OP_D(groupD2_8), false}, + { 0xD3, OP_I386, I386OP_D(groupD3_16), I386OP_D(groupD3_32), false}, + { 0xD4, OP_I386, I386OP_D(aam), I386OP_D(aam), false}, + { 0xD5, OP_I386, I386OP_D(aad), I386OP_D(aad), false}, + { 0xD6, OP_I386, I386OP_D(setalc), I386OP_D(setalc), false}, + { 0xD7, OP_I386, I386OP_D(xlat), I386OP_D(xlat), false}, + { 0xD8, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xD9, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xDA, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xDB, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xDC, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xDD, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xDE, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xDF, OP_I386, I386OP_D(escape), I386OP_D(escape), false}, + { 0xD8, OP_FPU, I386OP_D(x87_group_d8), I386OP_D(x87_group_d8), false}, + { 0xD9, OP_FPU, I386OP_D(x87_group_d9), I386OP_D(x87_group_d9), false}, + { 0xDA, OP_FPU, I386OP_D(x87_group_da), I386OP_D(x87_group_da), false}, + { 0xDB, OP_FPU, I386OP_D(x87_group_db), I386OP_D(x87_group_db), false}, + { 0xDC, OP_FPU, I386OP_D(x87_group_dc), I386OP_D(x87_group_dc), false}, + { 0xDD, OP_FPU, I386OP_D(x87_group_dd), I386OP_D(x87_group_dd), false}, + { 0xDE, OP_FPU, I386OP_D(x87_group_de), I386OP_D(x87_group_de), false}, + { 0xDF, OP_FPU, I386OP_D(x87_group_df), I386OP_D(x87_group_df), false}, + { 0xE0, OP_I386, I386OP_D(loopne16), I386OP_D(loopne32), false}, + { 0xE1, OP_I386, I386OP_D(loopz16), I386OP_D(loopz32), false}, + { 0xE2, OP_I386, I386OP_D(loop16), I386OP_D(loop32), false}, + { 0xE3, OP_I386, I386OP_D(jcxz16), I386OP_D(jcxz32), false}, + { 0xE4, OP_I386, I386OP_D(in_al_i8), I386OP_D(in_al_i8), false}, + { 0xE5, OP_I386, I386OP_D(in_ax_i8), I386OP_D(in_eax_i8), false}, + { 0xE6, OP_I386, I386OP_D(out_al_i8), I386OP_D(out_al_i8), false}, + { 0xE7, OP_I386, I386OP_D(out_ax_i8), I386OP_D(out_eax_i8), false}, + { 0xE8, OP_I386, I386OP_D(call_rel16), I386OP_D(call_rel32), false}, + { 0xE9, OP_I386, I386OP_D(jmp_rel16), I386OP_D(jmp_rel32), false}, + { 0xEA, OP_I386, I386OP_D(jmp_abs16), I386OP_D(jmp_abs32), false}, + { 0xEB, OP_I386, I386OP_D(jmp_rel8), I386OP_D(jmp_rel8), false}, + { 0xEC, OP_I386, I386OP_D(in_al_dx), I386OP_D(in_al_dx), false}, + { 0xED, OP_I386, I386OP_D(in_ax_dx), I386OP_D(in_eax_dx), false}, + { 0xEE, OP_I386, I386OP_D(out_al_dx), I386OP_D(out_al_dx), false}, + { 0xEF, OP_I386, I386OP_D(out_ax_dx), I386OP_D(out_eax_dx), false}, + { 0xF0, OP_I386, I386OP_D(lock), I386OP_D(lock), false}, + { 0xF1, OP_I386, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF2, OP_I386, I386OP_D(repne), I386OP_D(repne), false}, + { 0xF3, OP_I386, I386OP_D(rep), I386OP_D(rep), false}, + { 0xF4, OP_I386, I386OP_D(hlt), I386OP_D(hlt), false}, + { 0xF5, OP_I386, I386OP_D(cmc), I386OP_D(cmc), false}, + { 0xF6, OP_I386, I386OP_D(groupF6_8), I386OP_D(groupF6_8), true }, + { 0xF7, OP_I386, I386OP_D(groupF7_16), I386OP_D(groupF7_32), true }, + { 0xF8, OP_I386, I386OP_D(clc), I386OP_D(clc), false}, + { 0xF9, OP_I386, I386OP_D(stc), I386OP_D(stc), false}, + { 0xFA, OP_I386, I386OP_D(cli), I386OP_D(cli), false}, + { 0xFB, OP_I386, I386OP_D(sti), I386OP_D(sti), false}, + { 0xFC, OP_I386, I386OP_D(cld), I386OP_D(cld), false}, + { 0xFD, OP_I386, I386OP_D(std), I386OP_D(std), false}, + { 0xFE, OP_I386, I386OP_D(groupFE_8), I386OP_D(groupFE_8), true }, + { 0xFF, OP_I386, I386OP_D(groupFF_16), I386OP_D(groupFF_32), true }, /* 0F ?? */ - { 0x00, OP_2BYTE|OP_I386, I386OP(group0F00_16), I386OP(group0F00_32), false}, - { 0x01, OP_2BYTE|OP_I386, I386OP(group0F01_16), I386OP(group0F01_32), false}, - { 0x01, OP_2BYTE|OP_I486, I486OP(group0F01_16), I486OP(group0F01_32), false}, - { 0x02, OP_2BYTE|OP_I386, I386OP(lar_r16_rm16), I386OP(lar_r32_rm32), false}, - { 0x03, OP_2BYTE|OP_I386, I386OP(lsl_r16_rm16), I386OP(lsl_r32_rm32), false}, - { 0x06, OP_2BYTE|OP_I386, I386OP(clts), I386OP(clts), false}, - { 0x07, OP_2BYTE|OP_I386, I386OP(loadall), I386OP(loadall), false}, - { 0x07, OP_2BYTE|OP_I486, I386OP(invalid), I386OP(invalid), false}, - { 0x08, OP_2BYTE|OP_I486, I486OP(invd), I486OP(invd), false}, - { 0x09, OP_2BYTE|OP_I486, I486OP(wbinvd), I486OP(wbinvd), false}, - { 0x0B, OP_2BYTE|OP_PENTIUM, PENTIUMOP(ud2), PENTIUMOP(ud2), false}, - { 0x10, OP_2BYTE|OP_SSE, SSEOP(movups_r128_rm128), SSEOP(movups_r128_rm128), false}, - { 0x11, OP_2BYTE|OP_SSE, SSEOP(movups_rm128_r128), SSEOP(movups_rm128_r128), false}, - { 0x12, OP_2BYTE|OP_SSE, SSEOP(movlps_r128_m64), SSEOP(movlps_r128_m64), false}, - { 0x13, OP_2BYTE|OP_SSE, SSEOP(movlps_m64_r128), SSEOP(movlps_m64_r128), false}, - { 0x14, OP_2BYTE|OP_SSE, SSEOP(unpcklps_r128_rm128), SSEOP(unpcklps_r128_rm128), false}, - { 0x15, OP_2BYTE|OP_SSE, SSEOP(unpckhps_r128_rm128), SSEOP(unpckhps_r128_rm128), false}, - { 0x16, OP_2BYTE|OP_SSE, SSEOP(movhps_r128_m64), SSEOP(movhps_r128_m64), false}, - { 0x17, OP_2BYTE|OP_SSE, SSEOP(movhps_m64_r128), SSEOP(movhps_m64_r128), false}, - { 0x18, OP_2BYTE|OP_PENTIUM, PENTIUMOP(prefetch_m8), PENTIUMOP(prefetch_m8), false}, - { 0x20, OP_2BYTE|OP_I386, I386OP(mov_r32_cr), I386OP(mov_r32_cr), false}, - { 0x21, OP_2BYTE|OP_I386, I386OP(mov_r32_dr), I386OP(mov_r32_dr), false}, - { 0x22, OP_2BYTE|OP_I386, I386OP(mov_cr_r32), I386OP(mov_cr_r32), false}, - { 0x22, OP_2BYTE|OP_I486, I486OP(mov_cr_r32), I486OP(mov_cr_r32), false}, - { 0x23, OP_2BYTE|OP_I386, I386OP(mov_dr_r32), I386OP(mov_dr_r32), false}, - { 0x24, OP_2BYTE|OP_I386, I386OP(mov_r32_tr), I386OP(mov_r32_tr), false}, - { 0x26, OP_2BYTE|OP_I386, I386OP(mov_tr_r32), I386OP(mov_tr_r32), false}, - { 0x28, OP_2BYTE|OP_SSE, SSEOP(movaps_r128_rm128), SSEOP(movaps_r128_rm128), false}, - { 0x29, OP_2BYTE|OP_SSE, SSEOP(movaps_rm128_r128), SSEOP(movaps_rm128_r128), false}, - { 0x2a, OP_2BYTE|OP_SSE, SSEOP(cvtpi2ps_r128_rm64), SSEOP(cvtpi2ps_r128_rm64), false}, - { 0x2b, OP_2BYTE|OP_SSE, SSEOP(movntps_m128_r128), SSEOP(movntps_m128_r128), false}, - { 0x2c, OP_2BYTE|OP_SSE, SSEOP(cvttps2pi_r64_r128m64), SSEOP(cvttps2pi_r64_r128m64),false}, - { 0x2d, OP_2BYTE|OP_SSE, SSEOP(cvtps2pi_r64_r128m64), SSEOP(cvtps2pi_r64_r128m64),false}, - { 0x2e, OP_2BYTE|OP_SSE, SSEOP(ucomiss_r128_r128m32), SSEOP(ucomiss_r128_r128m32),false}, - { 0x2f, OP_2BYTE|OP_SSE, SSEOP(comiss_r128_r128m32), SSEOP(comiss_r128_r128m32), false}, - { 0x30, OP_2BYTE|OP_PENTIUM, PENTIUMOP(wrmsr), PENTIUMOP(wrmsr), false}, - { 0x31, OP_2BYTE|OP_PENTIUM, PENTIUMOP(rdtsc), PENTIUMOP(rdtsc), false}, - { 0x32, OP_2BYTE|OP_PENTIUM, PENTIUMOP(rdmsr), PENTIUMOP(rdmsr), false}, - { 0x38, OP_2BYTE|OP_PENTIUM, I386OP(decode_three_byte38), I386OP(decode_three_byte38),false}, - { 0x3A, OP_2BYTE|OP_PENTIUM, I386OP(decode_three_byte3a), I386OP(decode_three_byte3a),false}, - { 0x3A, OP_2BYTE|OP_CYRIX, I386OP(cyrix_special), I386OP(cyrix_special), false}, - { 0x3B, OP_2BYTE|OP_CYRIX, I386OP(cyrix_special), I386OP(cyrix_special), false}, - { 0x3C, OP_2BYTE|OP_CYRIX, I386OP(cyrix_special), I386OP(cyrix_special), false}, - { 0x3D, OP_2BYTE|OP_CYRIX, I386OP(cyrix_special), I386OP(cyrix_special), false}, - { 0x40, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovo_r16_rm16), PENTIUMOP(cmovo_r32_rm32), false}, - { 0x41, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovno_r16_rm16), PENTIUMOP(cmovno_r32_rm32), false}, - { 0x42, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovb_r16_rm16), PENTIUMOP(cmovb_r32_rm32), false}, - { 0x43, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovae_r16_rm16), PENTIUMOP(cmovae_r32_rm32), false}, - { 0x44, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmove_r16_rm16), PENTIUMOP(cmove_r32_rm32), false}, - { 0x45, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovne_r16_rm16), PENTIUMOP(cmovne_r32_rm32), false}, - { 0x46, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovbe_r16_rm16), PENTIUMOP(cmovbe_r32_rm32), false}, - { 0x47, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmova_r16_rm16), PENTIUMOP(cmova_r32_rm32), false}, - { 0x48, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovs_r16_rm16), PENTIUMOP(cmovs_r32_rm32), false}, - { 0x49, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovns_r16_rm16), PENTIUMOP(cmovns_r32_rm32), false}, - { 0x4a, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovp_r16_rm16), PENTIUMOP(cmovp_r32_rm32), false}, - { 0x4b, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovnp_r16_rm16), PENTIUMOP(cmovnp_r32_rm32), false}, - { 0x4c, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovl_r16_rm16), PENTIUMOP(cmovl_r32_rm32), false}, - { 0x4d, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovge_r16_rm16), PENTIUMOP(cmovge_r32_rm32), false}, - { 0x4e, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovle_r16_rm16), PENTIUMOP(cmovle_r32_rm32), false}, - { 0x4f, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmovg_r16_rm16), PENTIUMOP(cmovg_r32_rm32), false}, - { 0x50, OP_2BYTE|OP_SSE, SSEOP(movmskps_r16_r128), SSEOP(movmskps_r32_r128), false}, - { 0x51, OP_2BYTE|OP_SSE, SSEOP(sqrtps_r128_rm128), SSEOP(sqrtps_r128_rm128), false}, - { 0x52, OP_2BYTE|OP_SSE, SSEOP(rsqrtps_r128_rm128), SSEOP(rsqrtps_r128_rm128), false}, - { 0x53, OP_2BYTE|OP_SSE, SSEOP(rcpps_r128_rm128), SSEOP(rcpps_r128_rm128), false}, - { 0x54, OP_2BYTE|OP_SSE, SSEOP(andps_r128_rm128), SSEOP(andps_r128_rm128), false}, - { 0x55, OP_2BYTE|OP_SSE, SSEOP(andnps_r128_rm128), SSEOP(andnps_r128_rm128), false}, - { 0x56, OP_2BYTE|OP_SSE, SSEOP(orps_r128_rm128), SSEOP(orps_r128_rm128), false}, - { 0x57, OP_2BYTE|OP_SSE, SSEOP(xorps), SSEOP(xorps), false}, - { 0x58, OP_2BYTE|OP_SSE, SSEOP(addps), SSEOP(addps), false}, - { 0x59, OP_2BYTE|OP_SSE, SSEOP(mulps), SSEOP(mulps), false}, - { 0x5a, OP_2BYTE|OP_SSE, SSEOP(cvtps2pd_r128_r128m64), SSEOP(cvtps2pd_r128_r128m64),false}, - { 0x5b, OP_2BYTE|OP_SSE, SSEOP(cvtdq2ps_r128_rm128), SSEOP(cvtdq2ps_r128_rm128), false}, - { 0x5c, OP_2BYTE|OP_SSE, SSEOP(subps), SSEOP(subps), false}, - { 0x5d, OP_2BYTE|OP_SSE, SSEOP(minps), SSEOP(minps), false}, - { 0x5e, OP_2BYTE|OP_SSE, SSEOP(divps), SSEOP(divps), false}, - { 0x5f, OP_2BYTE|OP_SSE, SSEOP(maxps), SSEOP(maxps), false}, - { 0x60, OP_2BYTE|OP_MMX, MMXOP(punpcklbw_r64_r64m32), MMXOP(punpcklbw_r64_r64m32),false}, - { 0x61, OP_2BYTE|OP_MMX, MMXOP(punpcklwd_r64_r64m32), MMXOP(punpcklwd_r64_r64m32),false}, - { 0x62, OP_2BYTE|OP_MMX, MMXOP(punpckldq_r64_r64m32), MMXOP(punpckldq_r64_r64m32),false}, - { 0x63, OP_2BYTE|OP_MMX, MMXOP(packsswb_r64_rm64), MMXOP(packsswb_r64_rm64), false}, - { 0x64, OP_2BYTE|OP_MMX, MMXOP(pcmpgtb_r64_rm64), MMXOP(pcmpgtb_r64_rm64), false}, - { 0x65, OP_2BYTE|OP_MMX, MMXOP(pcmpgtw_r64_rm64), MMXOP(pcmpgtw_r64_rm64), false}, - { 0x66, OP_2BYTE|OP_MMX, MMXOP(pcmpgtd_r64_rm64), MMXOP(pcmpgtd_r64_rm64), false}, - { 0x67, OP_2BYTE|OP_MMX, MMXOP(packuswb_r64_rm64), MMXOP(packuswb_r64_rm64), false}, - { 0x68, OP_2BYTE|OP_MMX, MMXOP(punpckhbw_r64_rm64), MMXOP(punpckhbw_r64_rm64), false}, - { 0x69, OP_2BYTE|OP_MMX, MMXOP(punpckhwd_r64_rm64), MMXOP(punpckhwd_r64_rm64), false}, - { 0x6a, OP_2BYTE|OP_MMX, MMXOP(punpckhdq_r64_rm64), MMXOP(punpckhdq_r64_rm64), false}, - { 0x6b, OP_2BYTE|OP_MMX, MMXOP(packssdw_r64_rm64), MMXOP(packssdw_r64_rm64), false}, - { 0x6e, OP_2BYTE|OP_MMX, MMXOP(movd_r64_rm32), MMXOP(movd_r64_rm32), false}, - { 0x6f, OP_2BYTE|OP_MMX, MMXOP(movq_r64_rm64), MMXOP(movq_r64_rm64), false}, - { 0x70, OP_2BYTE|OP_MMX, MMXOP(pshufw_r64_rm64_i8), MMXOP(pshufw_r64_rm64_i8), false}, - { 0x71, OP_2BYTE|OP_MMX, MMXOP(group_0f71), MMXOP(group_0f71), false}, - { 0x72, OP_2BYTE|OP_MMX, MMXOP(group_0f72), MMXOP(group_0f72), false}, - { 0x73, OP_2BYTE|OP_MMX, MMXOP(group_0f73), MMXOP(group_0f73), false}, - { 0x74, OP_2BYTE|OP_CYRIX, I386OP(cyrix_unknown), I386OP(cyrix_unknown), false}, - { 0x74, OP_2BYTE|OP_MMX, MMXOP(pcmpeqb_r64_rm64), MMXOP(pcmpeqb_r64_rm64), false}, - { 0x75, OP_2BYTE|OP_MMX, MMXOP(pcmpeqw_r64_rm64), MMXOP(pcmpeqw_r64_rm64), false}, - { 0x76, OP_2BYTE|OP_MMX, MMXOP(pcmpeqd_r64_rm64), MMXOP(pcmpeqd_r64_rm64), false}, - { 0x77, OP_2BYTE|OP_MMX, MMXOP(emms), MMXOP(emms), false}, - { 0x78, OP_2BYTE|OP_CYRIX, I386OP(cyrix_svdc), I386OP(cyrix_svdc), false}, - { 0x79, OP_2BYTE|OP_CYRIX, I386OP(cyrix_rsdc), I386OP(cyrix_rsdc), false}, - { 0x7a, OP_2BYTE|OP_CYRIX, I386OP(cyrix_svldt), I386OP(cyrix_svldt), false}, - { 0x7b, OP_2BYTE|OP_CYRIX, I386OP(cyrix_rsldt), I386OP(cyrix_rsldt), false}, - { 0x7c, OP_2BYTE|OP_CYRIX, I386OP(cyrix_svts), I386OP(cyrix_svts), false}, - { 0x7d, OP_2BYTE|OP_CYRIX, I386OP(cyrix_rsts), I386OP(cyrix_rsts), false}, - { 0x7e, OP_2BYTE|OP_MMX, MMXOP(movd_rm32_r64), MMXOP(movd_rm32_r64), false}, - { 0x7f, OP_2BYTE|OP_MMX, MMXOP(movq_rm64_r64), MMXOP(movq_rm64_r64), false}, - { 0x80, OP_2BYTE|OP_I386, I386OP(jo_rel16), I386OP(jo_rel32), false}, - { 0x81, OP_2BYTE|OP_I386, I386OP(jno_rel16), I386OP(jno_rel32), false}, - { 0x82, OP_2BYTE|OP_I386, I386OP(jc_rel16), I386OP(jc_rel32), false}, - { 0x83, OP_2BYTE|OP_I386, I386OP(jnc_rel16), I386OP(jnc_rel32), false}, - { 0x84, OP_2BYTE|OP_I386, I386OP(jz_rel16), I386OP(jz_rel32), false}, - { 0x85, OP_2BYTE|OP_I386, I386OP(jnz_rel16), I386OP(jnz_rel32), false}, - { 0x86, OP_2BYTE|OP_I386, I386OP(jbe_rel16), I386OP(jbe_rel32), false}, - { 0x87, OP_2BYTE|OP_I386, I386OP(ja_rel16), I386OP(ja_rel32), false}, - { 0x88, OP_2BYTE|OP_I386, I386OP(js_rel16), I386OP(js_rel32), false}, - { 0x89, OP_2BYTE|OP_I386, I386OP(jns_rel16), I386OP(jns_rel32), false}, - { 0x8A, OP_2BYTE|OP_I386, I386OP(jp_rel16), I386OP(jp_rel32), false}, - { 0x8B, OP_2BYTE|OP_I386, I386OP(jnp_rel16), I386OP(jnp_rel32), false}, - { 0x8C, OP_2BYTE|OP_I386, I386OP(jl_rel16), I386OP(jl_rel32), false}, - { 0x8D, OP_2BYTE|OP_I386, I386OP(jge_rel16), I386OP(jge_rel32), false}, - { 0x8E, OP_2BYTE|OP_I386, I386OP(jle_rel16), I386OP(jle_rel32), false}, - { 0x8F, OP_2BYTE|OP_I386, I386OP(jg_rel16), I386OP(jg_rel32), false}, - { 0x90, OP_2BYTE|OP_I386, I386OP(seto_rm8), I386OP(seto_rm8), false}, - { 0x91, OP_2BYTE|OP_I386, I386OP(setno_rm8), I386OP(setno_rm8), false}, - { 0x92, OP_2BYTE|OP_I386, I386OP(setc_rm8), I386OP(setc_rm8), false}, - { 0x93, OP_2BYTE|OP_I386, I386OP(setnc_rm8), I386OP(setnc_rm8), false}, - { 0x94, OP_2BYTE|OP_I386, I386OP(setz_rm8), I386OP(setz_rm8), false}, - { 0x95, OP_2BYTE|OP_I386, I386OP(setnz_rm8), I386OP(setnz_rm8), false}, - { 0x96, OP_2BYTE|OP_I386, I386OP(setbe_rm8), I386OP(setbe_rm8), false}, - { 0x97, OP_2BYTE|OP_I386, I386OP(seta_rm8), I386OP(seta_rm8), false}, - { 0x98, OP_2BYTE|OP_I386, I386OP(sets_rm8), I386OP(sets_rm8), false}, - { 0x99, OP_2BYTE|OP_I386, I386OP(setns_rm8), I386OP(setns_rm8), false}, - { 0x9A, OP_2BYTE|OP_I386, I386OP(setp_rm8), I386OP(setp_rm8), false}, - { 0x9B, OP_2BYTE|OP_I386, I386OP(setnp_rm8), I386OP(setnp_rm8), false}, - { 0x9C, OP_2BYTE|OP_I386, I386OP(setl_rm8), I386OP(setl_rm8), false}, - { 0x9D, OP_2BYTE|OP_I386, I386OP(setge_rm8), I386OP(setge_rm8), false}, - { 0x9E, OP_2BYTE|OP_I386, I386OP(setle_rm8), I386OP(setle_rm8), false}, - { 0x9F, OP_2BYTE|OP_I386, I386OP(setg_rm8), I386OP(setg_rm8), false}, - { 0xA0, OP_2BYTE|OP_I386, I386OP(push_fs16), I386OP(push_fs32), false}, - { 0xA1, OP_2BYTE|OP_I386, I386OP(pop_fs16), I386OP(pop_fs32), false}, - { 0xA2, OP_2BYTE|OP_I486, I486OP(cpuid), I486OP(cpuid), false}, - { 0xA3, OP_2BYTE|OP_I386, I386OP(bt_rm16_r16), I386OP(bt_rm32_r32), false}, - { 0xA4, OP_2BYTE|OP_I386, I386OP(shld16_i8), I386OP(shld32_i8), false}, - { 0xA5, OP_2BYTE|OP_I386, I386OP(shld16_cl), I386OP(shld32_cl), false}, - { 0xA8, OP_2BYTE|OP_I386, I386OP(push_gs16), I386OP(push_gs32), false}, - { 0xA9, OP_2BYTE|OP_I386, I386OP(pop_gs16), I386OP(pop_gs32), false}, - { 0xAA, OP_2BYTE|OP_PENTIUM, PENTIUMOP(rsm), PENTIUMOP(rsm), false}, - { 0xAB, OP_2BYTE|OP_I386, I386OP(bts_rm16_r16), I386OP(bts_rm32_r32), true }, - { 0xAC, OP_2BYTE|OP_I386, I386OP(shrd16_i8), I386OP(shrd32_i8), false}, - { 0xAD, OP_2BYTE|OP_I386, I386OP(shrd16_cl), I386OP(shrd32_cl), false}, - { 0xAE, OP_2BYTE|OP_SSE, SSEOP(group_0fae), SSEOP(group_0fae), false}, - { 0xAF, OP_2BYTE|OP_I386, I386OP(imul_r16_rm16), I386OP(imul_r32_rm32), false}, - { 0xB0, OP_2BYTE|OP_I486, I486OP(cmpxchg_rm8_r8), I486OP(cmpxchg_rm8_r8), true }, - { 0xB1, OP_2BYTE|OP_I486, I486OP(cmpxchg_rm16_r16), I486OP(cmpxchg_rm32_r32), true }, - { 0xB2, OP_2BYTE|OP_I386, I386OP(lss16), I386OP(lss32), false}, - { 0xB3, OP_2BYTE|OP_I386, I386OP(btr_rm16_r16), I386OP(btr_rm32_r32), true }, - { 0xB4, OP_2BYTE|OP_I386, I386OP(lfs16), I386OP(lfs32), false}, - { 0xB5, OP_2BYTE|OP_I386, I386OP(lgs16), I386OP(lgs32), false}, - { 0xB6, OP_2BYTE|OP_I386, I386OP(movzx_r16_rm8), I386OP(movzx_r32_rm8), false}, - { 0xB7, OP_2BYTE|OP_I386, I386OP(invalid), I386OP(movzx_r32_rm16), false}, - { 0xBA, OP_2BYTE|OP_I386, I386OP(group0FBA_16), I386OP(group0FBA_32), true }, - { 0xBB, OP_2BYTE|OP_I386, I386OP(btc_rm16_r16), I386OP(btc_rm32_r32), true }, - { 0xBC, OP_2BYTE|OP_I386, I386OP(bsf_r16_rm16), I386OP(bsf_r32_rm32), false}, - { 0xBD, OP_2BYTE|OP_I386, I386OP(bsr_r16_rm16), I386OP(bsr_r32_rm32), false}, - { 0xBE, OP_2BYTE|OP_I386, I386OP(movsx_r16_rm8), I386OP(movsx_r32_rm8), false}, - { 0xBF, OP_2BYTE|OP_I386, I386OP(invalid), I386OP(movsx_r32_rm16), false}, - { 0xC0, OP_2BYTE|OP_I486, I486OP(xadd_rm8_r8), I486OP(xadd_rm8_r8), true }, - { 0xC1, OP_2BYTE|OP_I486, I486OP(xadd_rm16_r16), I486OP(xadd_rm32_r32), true }, - { 0xC2, OP_2BYTE|OP_SSE, SSEOP(cmpps_r128_rm128_i8), SSEOP(cmpps_r128_rm128_i8), false}, - { 0xC3, OP_2BYTE|OP_PENTIUM, PENTIUMOP(movnti_m16_r16), PENTIUMOP(movnti_m32_r32), false}, - { 0xC4, OP_2BYTE|OP_SSE, SSEOP(pinsrw_r64_r16m16_i8), SSEOP(pinsrw_r64_r32m16_i8),false}, - { 0xC5, OP_2BYTE|OP_SSE, SSEOP(pextrw_r16_r64_i8), SSEOP(pextrw_r32_r64_i8), false}, - { 0xC6, OP_2BYTE|OP_SSE, SSEOP(shufps), SSEOP(shufps), false}, - { 0xC7, OP_2BYTE|OP_PENTIUM, PENTIUMOP(cmpxchg8b_m64), PENTIUMOP(cmpxchg8b_m64), true }, - { 0xC8, OP_2BYTE|OP_I486, I486OP(bswap_eax), I486OP(bswap_eax), false}, - { 0xC9, OP_2BYTE|OP_I486, I486OP(bswap_ecx), I486OP(bswap_ecx), false}, - { 0xCA, OP_2BYTE|OP_I486, I486OP(bswap_edx), I486OP(bswap_edx), false}, - { 0xCB, OP_2BYTE|OP_I486, I486OP(bswap_ebx), I486OP(bswap_ebx), false}, - { 0xCC, OP_2BYTE|OP_I486, I486OP(bswap_esp), I486OP(bswap_esp), false}, - { 0xCD, OP_2BYTE|OP_I486, I486OP(bswap_ebp), I486OP(bswap_ebp), false}, - { 0xCE, OP_2BYTE|OP_I486, I486OP(bswap_esi), I486OP(bswap_esi), false}, - { 0xCF, OP_2BYTE|OP_I486, I486OP(bswap_edi), I486OP(bswap_edi), false}, - { 0xD1, OP_2BYTE|OP_MMX, MMXOP(psrlw_r64_rm64), MMXOP(psrlw_r64_rm64), false}, - { 0xD2, OP_2BYTE|OP_MMX, MMXOP(psrld_r64_rm64), MMXOP(psrld_r64_rm64), false}, - { 0xD3, OP_2BYTE|OP_MMX, MMXOP(psrlq_r64_rm64), MMXOP(psrlq_r64_rm64), false}, - { 0xD4, OP_2BYTE|OP_MMX, MMXOP(paddq_r64_rm64), MMXOP(paddq_r64_rm64), false}, - { 0xD5, OP_2BYTE|OP_MMX, MMXOP(pmullw_r64_rm64), MMXOP(pmullw_r64_rm64), false}, - { 0xD7, OP_2BYTE|OP_SSE, SSEOP(pmovmskb_r16_r64), SSEOP(pmovmskb_r32_r64), false}, - { 0xD8, OP_2BYTE|OP_MMX, MMXOP(psubusb_r64_rm64), MMXOP(psubusb_r64_rm64), false}, - { 0xD9, OP_2BYTE|OP_MMX, MMXOP(psubusw_r64_rm64), MMXOP(psubusw_r64_rm64), false}, - { 0xDA, OP_2BYTE|OP_SSE, SSEOP(pminub_r64_rm64), SSEOP(pminub_r64_rm64), false}, - { 0xDB, OP_2BYTE|OP_MMX, MMXOP(pand_r64_rm64), MMXOP(pand_r64_rm64), false}, - { 0xDC, OP_2BYTE|OP_MMX, MMXOP(paddusb_r64_rm64), MMXOP(paddusb_r64_rm64), false}, - { 0xDD, OP_2BYTE|OP_MMX, MMXOP(paddusw_r64_rm64), MMXOP(paddusw_r64_rm64), false}, - { 0xDE, OP_2BYTE|OP_SSE, SSEOP(pmaxub_r64_rm64), SSEOP(pmaxub_r64_rm64), false}, - { 0xDF, OP_2BYTE|OP_MMX, MMXOP(pandn_r64_rm64), MMXOP(pandn_r64_rm64), false}, - { 0xE0, OP_2BYTE|OP_SSE, SSEOP(pavgb_r64_rm64), SSEOP(pavgb_r64_rm64), false}, - { 0xE1, OP_2BYTE|OP_MMX, MMXOP(psraw_r64_rm64), MMXOP(psraw_r64_rm64), false}, - { 0xE2, OP_2BYTE|OP_MMX, MMXOP(psrad_r64_rm64), MMXOP(psrad_r64_rm64), false}, - { 0xE3, OP_2BYTE|OP_SSE, SSEOP(pavgw_r64_rm64), SSEOP(pavgw_r64_rm64), false}, - { 0xE4, OP_2BYTE|OP_SSE, SSEOP(pmulhuw_r64_rm64), SSEOP(pmulhuw_r64_rm64), false}, - { 0xE5, OP_2BYTE|OP_MMX, MMXOP(pmulhw_r64_rm64), MMXOP(pmulhw_r64_rm64), false}, - { 0xE7, OP_2BYTE|OP_PENTIUM, PENTIUMOP(movntq_m64_r64), PENTIUMOP(movntq_m64_r64), false}, - { 0xE8, OP_2BYTE|OP_MMX, MMXOP(psubsb_r64_rm64), MMXOP(psubsb_r64_rm64), false}, - { 0xE9, OP_2BYTE|OP_MMX, MMXOP(psubsw_r64_rm64), MMXOP(psubsw_r64_rm64), false}, - { 0xEA, OP_2BYTE|OP_SSE, SSEOP(pminsw_r64_rm64), SSEOP(pminsw_r64_rm64), false}, - { 0xEB, OP_2BYTE|OP_MMX, MMXOP(por_r64_rm64), MMXOP(por_r64_rm64), false}, - { 0xEC, OP_2BYTE|OP_MMX, MMXOP(paddsb_r64_rm64), MMXOP(paddsb_r64_rm64), false}, - { 0xED, OP_2BYTE|OP_MMX, MMXOP(paddsw_r64_rm64), MMXOP(paddsw_r64_rm64), false}, - { 0xEE, OP_2BYTE|OP_SSE, SSEOP(pmaxsw_r64_rm64), SSEOP(pmaxsw_r64_rm64), false}, - { 0xEF, OP_2BYTE|OP_MMX, MMXOP(pxor_r64_rm64), MMXOP(pxor_r64_rm64), false}, - { 0xF1, OP_2BYTE|OP_MMX, MMXOP(psllw_r64_rm64), MMXOP(psllw_r64_rm64), false}, - { 0xF2, OP_2BYTE|OP_MMX, MMXOP(pslld_r64_rm64), MMXOP(pslld_r64_rm64), false}, - { 0xF3, OP_2BYTE|OP_MMX, MMXOP(psllq_r64_rm64), MMXOP(psllq_r64_rm64), false}, - { 0xF4, OP_2BYTE|OP_SSE, SSEOP(pmuludq_r64_rm64), SSEOP(pmuludq_r64_rm64), false}, - { 0xF5, OP_2BYTE|OP_MMX, MMXOP(pmaddwd_r64_rm64), MMXOP(pmaddwd_r64_rm64), false}, - { 0xF6, OP_2BYTE|OP_SSE, SSEOP(psadbw_r64_rm64), SSEOP(psadbw_r64_rm64), false}, - { 0xf7, OP_2BYTE|OP_PENTIUM, PENTIUMOP(maskmovq_r64_r64), PENTIUMOP(maskmovq_r64_r64),false}, - { 0xF8, OP_2BYTE|OP_MMX, MMXOP(psubb_r64_rm64), MMXOP(psubb_r64_rm64), false}, - { 0xF9, OP_2BYTE|OP_MMX, MMXOP(psubw_r64_rm64), MMXOP(psubw_r64_rm64), false}, - { 0xFA, OP_2BYTE|OP_MMX, MMXOP(psubd_r64_rm64), MMXOP(psubd_r64_rm64), false}, - { 0xFB, OP_2BYTE|OP_SSE, SSEOP(psubq_r64_rm64), SSEOP(psubq_r64_rm64), false}, - { 0xFC, OP_2BYTE|OP_MMX, MMXOP(paddb_r64_rm64), MMXOP(paddb_r64_rm64), false}, - { 0xFD, OP_2BYTE|OP_MMX, MMXOP(paddw_r64_rm64), MMXOP(paddw_r64_rm64), false}, - { 0xFE, OP_2BYTE|OP_MMX, MMXOP(paddd_r64_rm64), MMXOP(paddd_r64_rm64), false}, + { 0x00, OP_2BYTE|OP_I386, I386OP_D(group0F00_16), I386OP_D(group0F00_32), false}, + { 0x01, OP_2BYTE|OP_I386, I386OP_D(group0F01_16), I386OP_D(group0F01_32), false}, + { 0x01, OP_2BYTE|OP_I486, I486OP_D(group0F01_16), I486OP_D(group0F01_32), false}, + { 0x02, OP_2BYTE|OP_I386, I386OP_D(lar_r16_rm16), I386OP_D(lar_r32_rm32), false}, + { 0x03, OP_2BYTE|OP_I386, I386OP_D(lsl_r16_rm16), I386OP_D(lsl_r32_rm32), false}, + { 0x06, OP_2BYTE|OP_I386, I386OP_D(clts), I386OP_D(clts), false}, + { 0x07, OP_2BYTE|OP_I386, I386OP_D(loadall), I386OP_D(loadall), false}, + { 0x07, OP_2BYTE|OP_I486, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x08, OP_2BYTE|OP_I486, I486OP_D(invd), I486OP_D(invd), false}, + { 0x09, OP_2BYTE|OP_I486, I486OP_D(wbinvd), I486OP_D(wbinvd), false}, + { 0x0B, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(ud2), PENTIUMOP_D(ud2), false}, + { 0x10, OP_2BYTE|OP_SSE, SSEOP_D(movups_r128_rm128), SSEOP_D(movups_r128_rm128), false}, + { 0x11, OP_2BYTE|OP_SSE, SSEOP_D(movups_rm128_r128), SSEOP_D(movups_rm128_r128), false}, + { 0x12, OP_2BYTE|OP_SSE, SSEOP_D(movlps_r128_m64), SSEOP_D(movlps_r128_m64), false}, + { 0x13, OP_2BYTE|OP_SSE, SSEOP_D(movlps_m64_r128), SSEOP_D(movlps_m64_r128), false}, + { 0x14, OP_2BYTE|OP_SSE, SSEOP_D(unpcklps_r128_rm128), SSEOP_D(unpcklps_r128_rm128), false}, + { 0x15, OP_2BYTE|OP_SSE, SSEOP_D(unpckhps_r128_rm128), SSEOP_D(unpckhps_r128_rm128), false}, + { 0x16, OP_2BYTE|OP_SSE, SSEOP_D(movhps_r128_m64), SSEOP_D(movhps_r128_m64), false}, + { 0x17, OP_2BYTE|OP_SSE, SSEOP_D(movhps_m64_r128), SSEOP_D(movhps_m64_r128), false}, + { 0x18, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(prefetch_m8), PENTIUMOP_D(prefetch_m8), false}, + { 0x20, OP_2BYTE|OP_I386, I386OP_D(mov_r32_cr), I386OP_D(mov_r32_cr), false}, + { 0x21, OP_2BYTE|OP_I386, I386OP_D(mov_r32_dr), I386OP_D(mov_r32_dr), false}, + { 0x22, OP_2BYTE|OP_I386, I386OP_D(mov_cr_r32), I386OP_D(mov_cr_r32), false}, + { 0x22, OP_2BYTE|OP_I486, I486OP_D(mov_cr_r32), I486OP_D(mov_cr_r32), false}, + { 0x23, OP_2BYTE|OP_I386, I386OP_D(mov_dr_r32), I386OP_D(mov_dr_r32), false}, + { 0x24, OP_2BYTE|OP_I386, I386OP_D(mov_r32_tr), I386OP_D(mov_r32_tr), false}, + { 0x26, OP_2BYTE|OP_I386, I386OP_D(mov_tr_r32), I386OP_D(mov_tr_r32), false}, + { 0x28, OP_2BYTE|OP_SSE, SSEOP_D(movaps_r128_rm128), SSEOP_D(movaps_r128_rm128), false}, + { 0x29, OP_2BYTE|OP_SSE, SSEOP_D(movaps_rm128_r128), SSEOP_D(movaps_rm128_r128), false}, + { 0x2a, OP_2BYTE|OP_SSE, SSEOP_D(cvtpi2ps_r128_rm64), SSEOP_D(cvtpi2ps_r128_rm64), false}, + { 0x2b, OP_2BYTE|OP_SSE, SSEOP_D(movntps_m128_r128), SSEOP_D(movntps_m128_r128), false}, + { 0x2c, OP_2BYTE|OP_SSE, SSEOP_D(cvttps2pi_r64_r128m64), SSEOP_D(cvttps2pi_r64_r128m64),false}, + { 0x2d, OP_2BYTE|OP_SSE, SSEOP_D(cvtps2pi_r64_r128m64), SSEOP_D(cvtps2pi_r64_r128m64),false}, + { 0x2e, OP_2BYTE|OP_SSE, SSEOP_D(ucomiss_r128_r128m32), SSEOP_D(ucomiss_r128_r128m32),false}, + { 0x2f, OP_2BYTE|OP_SSE, SSEOP_D(comiss_r128_r128m32), SSEOP_D(comiss_r128_r128m32), false}, + { 0x30, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(wrmsr), PENTIUMOP_D(wrmsr), false}, + { 0x31, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(rdtsc), PENTIUMOP_D(rdtsc), false}, + { 0x32, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(rdmsr), PENTIUMOP_D(rdmsr), false}, + { 0x38, OP_2BYTE|OP_PENTIUM, I386OP_D(decode_three_byte38), I386OP_D(decode_three_byte38),false}, + { 0x3A, OP_2BYTE|OP_PENTIUM, I386OP_D(decode_three_byte3a), I386OP_D(decode_three_byte3a),false}, + { 0x3A, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_special), I386OP_D(cyrix_special), false}, + { 0x3B, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_special), I386OP_D(cyrix_special), false}, + { 0x3C, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_special), I386OP_D(cyrix_special), false}, + { 0x3D, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_special), I386OP_D(cyrix_special), false}, + { 0x40, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovo_r16_rm16), PENTIUMOP_D(cmovo_r32_rm32), false}, + { 0x41, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovno_r16_rm16), PENTIUMOP_D(cmovno_r32_rm32), false}, + { 0x42, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovb_r16_rm16), PENTIUMOP_D(cmovb_r32_rm32), false}, + { 0x43, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovae_r16_rm16), PENTIUMOP_D(cmovae_r32_rm32), false}, + { 0x44, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmove_r16_rm16), PENTIUMOP_D(cmove_r32_rm32), false}, + { 0x45, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovne_r16_rm16), PENTIUMOP_D(cmovne_r32_rm32), false}, + { 0x46, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovbe_r16_rm16), PENTIUMOP_D(cmovbe_r32_rm32), false}, + { 0x47, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmova_r16_rm16), PENTIUMOP_D(cmova_r32_rm32), false}, + { 0x48, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovs_r16_rm16), PENTIUMOP_D(cmovs_r32_rm32), false}, + { 0x49, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovns_r16_rm16), PENTIUMOP_D(cmovns_r32_rm32), false}, + { 0x4a, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovp_r16_rm16), PENTIUMOP_D(cmovp_r32_rm32), false}, + { 0x4b, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovnp_r16_rm16), PENTIUMOP_D(cmovnp_r32_rm32), false}, + { 0x4c, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovl_r16_rm16), PENTIUMOP_D(cmovl_r32_rm32), false}, + { 0x4d, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovge_r16_rm16), PENTIUMOP_D(cmovge_r32_rm32), false}, + { 0x4e, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovle_r16_rm16), PENTIUMOP_D(cmovle_r32_rm32), false}, + { 0x4f, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmovg_r16_rm16), PENTIUMOP_D(cmovg_r32_rm32), false}, + { 0x50, OP_2BYTE|OP_SSE, SSEOP_D(movmskps_r16_r128), SSEOP_D(movmskps_r32_r128), false}, + { 0x51, OP_2BYTE|OP_SSE, SSEOP_D(sqrtps_r128_rm128), SSEOP_D(sqrtps_r128_rm128), false}, + { 0x52, OP_2BYTE|OP_SSE, SSEOP_D(rsqrtps_r128_rm128), SSEOP_D(rsqrtps_r128_rm128), false}, + { 0x53, OP_2BYTE|OP_SSE, SSEOP_D(rcpps_r128_rm128), SSEOP_D(rcpps_r128_rm128), false}, + { 0x54, OP_2BYTE|OP_SSE, SSEOP_D(andps_r128_rm128), SSEOP_D(andps_r128_rm128), false}, + { 0x55, OP_2BYTE|OP_SSE, SSEOP_D(andnps_r128_rm128), SSEOP_D(andnps_r128_rm128), false}, + { 0x56, OP_2BYTE|OP_SSE, SSEOP_D(orps_r128_rm128), SSEOP_D(orps_r128_rm128), false}, + { 0x57, OP_2BYTE|OP_SSE, SSEOP_D(xorps), SSEOP_D(xorps), false}, + { 0x58, OP_2BYTE|OP_SSE, SSEOP_D(addps), SSEOP_D(addps), false}, + { 0x59, OP_2BYTE|OP_SSE, SSEOP_D(mulps), SSEOP_D(mulps), false}, + { 0x5a, OP_2BYTE|OP_SSE, SSEOP_D(cvtps2pd_r128_r128m64), SSEOP_D(cvtps2pd_r128_r128m64),false}, + { 0x5b, OP_2BYTE|OP_SSE, SSEOP_D(cvtdq2ps_r128_rm128), SSEOP_D(cvtdq2ps_r128_rm128), false}, + { 0x5c, OP_2BYTE|OP_SSE, SSEOP_D(subps), SSEOP_D(subps), false}, + { 0x5d, OP_2BYTE|OP_SSE, SSEOP_D(minps), SSEOP_D(minps), false}, + { 0x5e, OP_2BYTE|OP_SSE, SSEOP_D(divps), SSEOP_D(divps), false}, + { 0x5f, OP_2BYTE|OP_SSE, SSEOP_D(maxps), SSEOP_D(maxps), false}, + { 0x60, OP_2BYTE|OP_MMX, MMXOP_D(punpcklbw_r64_r64m32), MMXOP_D(punpcklbw_r64_r64m32),false}, + { 0x61, OP_2BYTE|OP_MMX, MMXOP_D(punpcklwd_r64_r64m32), MMXOP_D(punpcklwd_r64_r64m32),false}, + { 0x62, OP_2BYTE|OP_MMX, MMXOP_D(punpckldq_r64_r64m32), MMXOP_D(punpckldq_r64_r64m32),false}, + { 0x63, OP_2BYTE|OP_MMX, MMXOP_D(packsswb_r64_rm64), MMXOP_D(packsswb_r64_rm64), false}, + { 0x64, OP_2BYTE|OP_MMX, MMXOP_D(pcmpgtb_r64_rm64), MMXOP_D(pcmpgtb_r64_rm64), false}, + { 0x65, OP_2BYTE|OP_MMX, MMXOP_D(pcmpgtw_r64_rm64), MMXOP_D(pcmpgtw_r64_rm64), false}, + { 0x66, OP_2BYTE|OP_MMX, MMXOP_D(pcmpgtd_r64_rm64), MMXOP_D(pcmpgtd_r64_rm64), false}, + { 0x67, OP_2BYTE|OP_MMX, MMXOP_D(packuswb_r64_rm64), MMXOP_D(packuswb_r64_rm64), false}, + { 0x68, OP_2BYTE|OP_MMX, MMXOP_D(punpckhbw_r64_rm64), MMXOP_D(punpckhbw_r64_rm64), false}, + { 0x69, OP_2BYTE|OP_MMX, MMXOP_D(punpckhwd_r64_rm64), MMXOP_D(punpckhwd_r64_rm64), false}, + { 0x6a, OP_2BYTE|OP_MMX, MMXOP_D(punpckhdq_r64_rm64), MMXOP_D(punpckhdq_r64_rm64), false}, + { 0x6b, OP_2BYTE|OP_MMX, MMXOP_D(packssdw_r64_rm64), MMXOP_D(packssdw_r64_rm64), false}, + { 0x6e, OP_2BYTE|OP_MMX, MMXOP_D(movd_r64_rm32), MMXOP_D(movd_r64_rm32), false}, + { 0x6f, OP_2BYTE|OP_MMX, MMXOP_D(movq_r64_rm64), MMXOP_D(movq_r64_rm64), false}, + { 0x70, OP_2BYTE|OP_MMX, MMXOP_D(pshufw_r64_rm64_i8), MMXOP_D(pshufw_r64_rm64_i8), false}, + { 0x71, OP_2BYTE|OP_MMX, MMXOP_D(group_0f71), MMXOP_D(group_0f71), false}, + { 0x72, OP_2BYTE|OP_MMX, MMXOP_D(group_0f72), MMXOP_D(group_0f72), false}, + { 0x73, OP_2BYTE|OP_MMX, MMXOP_D(group_0f73), MMXOP_D(group_0f73), false}, + { 0x74, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_unknown), I386OP_D(cyrix_unknown), false}, + { 0x74, OP_2BYTE|OP_MMX, MMXOP_D(pcmpeqb_r64_rm64), MMXOP_D(pcmpeqb_r64_rm64), false}, + { 0x75, OP_2BYTE|OP_MMX, MMXOP_D(pcmpeqw_r64_rm64), MMXOP_D(pcmpeqw_r64_rm64), false}, + { 0x76, OP_2BYTE|OP_MMX, MMXOP_D(pcmpeqd_r64_rm64), MMXOP_D(pcmpeqd_r64_rm64), false}, + { 0x77, OP_2BYTE|OP_MMX, MMXOP_D(emms), MMXOP_D(emms), false}, + { 0x78, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_svdc), I386OP_D(cyrix_svdc), false}, + { 0x79, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_rsdc), I386OP_D(cyrix_rsdc), false}, + { 0x7a, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_svldt), I386OP_D(cyrix_svldt), false}, + { 0x7b, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_rsldt), I386OP_D(cyrix_rsldt), false}, + { 0x7c, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_svts), I386OP_D(cyrix_svts), false}, + { 0x7d, OP_2BYTE|OP_CYRIX, I386OP_D(cyrix_rsts), I386OP_D(cyrix_rsts), false}, + { 0x7e, OP_2BYTE|OP_MMX, MMXOP_D(movd_rm32_r64), MMXOP_D(movd_rm32_r64), false}, + { 0x7f, OP_2BYTE|OP_MMX, MMXOP_D(movq_rm64_r64), MMXOP_D(movq_rm64_r64), false}, + { 0x80, OP_2BYTE|OP_I386, I386OP_D(jo_rel16), I386OP_D(jo_rel32), false}, + { 0x81, OP_2BYTE|OP_I386, I386OP_D(jno_rel16), I386OP_D(jno_rel32), false}, + { 0x82, OP_2BYTE|OP_I386, I386OP_D(jc_rel16), I386OP_D(jc_rel32), false}, + { 0x83, OP_2BYTE|OP_I386, I386OP_D(jnc_rel16), I386OP_D(jnc_rel32), false}, + { 0x84, OP_2BYTE|OP_I386, I386OP_D(jz_rel16), I386OP_D(jz_rel32), false}, + { 0x85, OP_2BYTE|OP_I386, I386OP_D(jnz_rel16), I386OP_D(jnz_rel32), false}, + { 0x86, OP_2BYTE|OP_I386, I386OP_D(jbe_rel16), I386OP_D(jbe_rel32), false}, + { 0x87, OP_2BYTE|OP_I386, I386OP_D(ja_rel16), I386OP_D(ja_rel32), false}, + { 0x88, OP_2BYTE|OP_I386, I386OP_D(js_rel16), I386OP_D(js_rel32), false}, + { 0x89, OP_2BYTE|OP_I386, I386OP_D(jns_rel16), I386OP_D(jns_rel32), false}, + { 0x8A, OP_2BYTE|OP_I386, I386OP_D(jp_rel16), I386OP_D(jp_rel32), false}, + { 0x8B, OP_2BYTE|OP_I386, I386OP_D(jnp_rel16), I386OP_D(jnp_rel32), false}, + { 0x8C, OP_2BYTE|OP_I386, I386OP_D(jl_rel16), I386OP_D(jl_rel32), false}, + { 0x8D, OP_2BYTE|OP_I386, I386OP_D(jge_rel16), I386OP_D(jge_rel32), false}, + { 0x8E, OP_2BYTE|OP_I386, I386OP_D(jle_rel16), I386OP_D(jle_rel32), false}, + { 0x8F, OP_2BYTE|OP_I386, I386OP_D(jg_rel16), I386OP_D(jg_rel32), false}, + { 0x90, OP_2BYTE|OP_I386, I386OP_D(seto_rm8), I386OP_D(seto_rm8), false}, + { 0x91, OP_2BYTE|OP_I386, I386OP_D(setno_rm8), I386OP_D(setno_rm8), false}, + { 0x92, OP_2BYTE|OP_I386, I386OP_D(setc_rm8), I386OP_D(setc_rm8), false}, + { 0x93, OP_2BYTE|OP_I386, I386OP_D(setnc_rm8), I386OP_D(setnc_rm8), false}, + { 0x94, OP_2BYTE|OP_I386, I386OP_D(setz_rm8), I386OP_D(setz_rm8), false}, + { 0x95, OP_2BYTE|OP_I386, I386OP_D(setnz_rm8), I386OP_D(setnz_rm8), false}, + { 0x96, OP_2BYTE|OP_I386, I386OP_D(setbe_rm8), I386OP_D(setbe_rm8), false}, + { 0x97, OP_2BYTE|OP_I386, I386OP_D(seta_rm8), I386OP_D(seta_rm8), false}, + { 0x98, OP_2BYTE|OP_I386, I386OP_D(sets_rm8), I386OP_D(sets_rm8), false}, + { 0x99, OP_2BYTE|OP_I386, I386OP_D(setns_rm8), I386OP_D(setns_rm8), false}, + { 0x9A, OP_2BYTE|OP_I386, I386OP_D(setp_rm8), I386OP_D(setp_rm8), false}, + { 0x9B, OP_2BYTE|OP_I386, I386OP_D(setnp_rm8), I386OP_D(setnp_rm8), false}, + { 0x9C, OP_2BYTE|OP_I386, I386OP_D(setl_rm8), I386OP_D(setl_rm8), false}, + { 0x9D, OP_2BYTE|OP_I386, I386OP_D(setge_rm8), I386OP_D(setge_rm8), false}, + { 0x9E, OP_2BYTE|OP_I386, I386OP_D(setle_rm8), I386OP_D(setle_rm8), false}, + { 0x9F, OP_2BYTE|OP_I386, I386OP_D(setg_rm8), I386OP_D(setg_rm8), false}, + { 0xA0, OP_2BYTE|OP_I386, I386OP_D(push_fs16), I386OP_D(push_fs32), false}, + { 0xA1, OP_2BYTE|OP_I386, I386OP_D(pop_fs16), I386OP_D(pop_fs32), false}, + { 0xA2, OP_2BYTE|OP_I486, I486OP_D(cpuid), I486OP_D(cpuid), false}, + { 0xA3, OP_2BYTE|OP_I386, I386OP_D(bt_rm16_r16), I386OP_D(bt_rm32_r32), false}, + { 0xA4, OP_2BYTE|OP_I386, I386OP_D(shld16_i8), I386OP_D(shld32_i8), false}, + { 0xA5, OP_2BYTE|OP_I386, I386OP_D(shld16_cl), I386OP_D(shld32_cl), false}, + { 0xA8, OP_2BYTE|OP_I386, I386OP_D(push_gs16), I386OP_D(push_gs32), false}, + { 0xA9, OP_2BYTE|OP_I386, I386OP_D(pop_gs16), I386OP_D(pop_gs32), false}, + { 0xAA, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(rsm), PENTIUMOP_D(rsm), false}, + { 0xAB, OP_2BYTE|OP_I386, I386OP_D(bts_rm16_r16), I386OP_D(bts_rm32_r32), true }, + { 0xAC, OP_2BYTE|OP_I386, I386OP_D(shrd16_i8), I386OP_D(shrd32_i8), false}, + { 0xAD, OP_2BYTE|OP_I386, I386OP_D(shrd16_cl), I386OP_D(shrd32_cl), false}, + { 0xAE, OP_2BYTE|OP_SSE, SSEOP_D(group_0fae), SSEOP_D(group_0fae), false}, + { 0xAF, OP_2BYTE|OP_I386, I386OP_D(imul_r16_rm16), I386OP_D(imul_r32_rm32), false}, + { 0xB0, OP_2BYTE|OP_I486, I486OP_D(cmpxchg_rm8_r8), I486OP_D(cmpxchg_rm8_r8), true }, + { 0xB1, OP_2BYTE|OP_I486, I486OP_D(cmpxchg_rm16_r16), I486OP_D(cmpxchg_rm32_r32), true }, + { 0xB2, OP_2BYTE|OP_I386, I386OP_D(lss16), I386OP_D(lss32), false}, + { 0xB3, OP_2BYTE|OP_I386, I386OP_D(btr_rm16_r16), I386OP_D(btr_rm32_r32), true }, + { 0xB4, OP_2BYTE|OP_I386, I386OP_D(lfs16), I386OP_D(lfs32), false}, + { 0xB5, OP_2BYTE|OP_I386, I386OP_D(lgs16), I386OP_D(lgs32), false}, + { 0xB6, OP_2BYTE|OP_I386, I386OP_D(movzx_r16_rm8), I386OP_D(movzx_r32_rm8), false}, + { 0xB7, OP_2BYTE|OP_I386, I386OP_D(invalid), I386OP_D(movzx_r32_rm16), false}, + { 0xBA, OP_2BYTE|OP_I386, I386OP_D(group0FBA_16), I386OP_D(group0FBA_32), true }, + { 0xBB, OP_2BYTE|OP_I386, I386OP_D(btc_rm16_r16), I386OP_D(btc_rm32_r32), true }, + { 0xBC, OP_2BYTE|OP_I386, I386OP_D(bsf_r16_rm16), I386OP_D(bsf_r32_rm32), false}, + { 0xBD, OP_2BYTE|OP_I386, I386OP_D(bsr_r16_rm16), I386OP_D(bsr_r32_rm32), false}, + { 0xBE, OP_2BYTE|OP_I386, I386OP_D(movsx_r16_rm8), I386OP_D(movsx_r32_rm8), false}, + { 0xBF, OP_2BYTE|OP_I386, I386OP_D(invalid), I386OP_D(movsx_r32_rm16), false}, + { 0xC0, OP_2BYTE|OP_I486, I486OP_D(xadd_rm8_r8), I486OP_D(xadd_rm8_r8), true }, + { 0xC1, OP_2BYTE|OP_I486, I486OP_D(xadd_rm16_r16), I486OP_D(xadd_rm32_r32), true }, + { 0xC2, OP_2BYTE|OP_SSE, SSEOP_D(cmpps_r128_rm128_i8), SSEOP_D(cmpps_r128_rm128_i8), false}, + { 0xC3, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(movnti_m16_r16), PENTIUMOP_D(movnti_m32_r32), false}, + { 0xC4, OP_2BYTE|OP_SSE, SSEOP_D(pinsrw_r64_r16m16_i8), SSEOP_D(pinsrw_r64_r32m16_i8),false}, + { 0xC5, OP_2BYTE|OP_SSE, SSEOP_D(pextrw_r16_r64_i8), SSEOP_D(pextrw_r32_r64_i8), false}, + { 0xC6, OP_2BYTE|OP_SSE, SSEOP_D(shufps), SSEOP_D(shufps), false}, + { 0xC7, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(cmpxchg8b_m64), PENTIUMOP_D(cmpxchg8b_m64), true }, + { 0xC8, OP_2BYTE|OP_I486, I486OP_D(bswap_eax), I486OP_D(bswap_eax), false}, + { 0xC9, OP_2BYTE|OP_I486, I486OP_D(bswap_ecx), I486OP_D(bswap_ecx), false}, + { 0xCA, OP_2BYTE|OP_I486, I486OP_D(bswap_edx), I486OP_D(bswap_edx), false}, + { 0xCB, OP_2BYTE|OP_I486, I486OP_D(bswap_ebx), I486OP_D(bswap_ebx), false}, + { 0xCC, OP_2BYTE|OP_I486, I486OP_D(bswap_esp), I486OP_D(bswap_esp), false}, + { 0xCD, OP_2BYTE|OP_I486, I486OP_D(bswap_ebp), I486OP_D(bswap_ebp), false}, + { 0xCE, OP_2BYTE|OP_I486, I486OP_D(bswap_esi), I486OP_D(bswap_esi), false}, + { 0xCF, OP_2BYTE|OP_I486, I486OP_D(bswap_edi), I486OP_D(bswap_edi), false}, + { 0xD1, OP_2BYTE|OP_MMX, MMXOP_D(psrlw_r64_rm64), MMXOP_D(psrlw_r64_rm64), false}, + { 0xD2, OP_2BYTE|OP_MMX, MMXOP_D(psrld_r64_rm64), MMXOP_D(psrld_r64_rm64), false}, + { 0xD3, OP_2BYTE|OP_MMX, MMXOP_D(psrlq_r64_rm64), MMXOP_D(psrlq_r64_rm64), false}, + { 0xD4, OP_2BYTE|OP_MMX, MMXOP_D(paddq_r64_rm64), MMXOP_D(paddq_r64_rm64), false}, + { 0xD5, OP_2BYTE|OP_MMX, MMXOP_D(pmullw_r64_rm64), MMXOP_D(pmullw_r64_rm64), false}, + { 0xD7, OP_2BYTE|OP_SSE, SSEOP_D(pmovmskb_r16_r64), SSEOP_D(pmovmskb_r32_r64), false}, + { 0xD8, OP_2BYTE|OP_MMX, MMXOP_D(psubusb_r64_rm64), MMXOP_D(psubusb_r64_rm64), false}, + { 0xD9, OP_2BYTE|OP_MMX, MMXOP_D(psubusw_r64_rm64), MMXOP_D(psubusw_r64_rm64), false}, + { 0xDA, OP_2BYTE|OP_SSE, SSEOP_D(pminub_r64_rm64), SSEOP_D(pminub_r64_rm64), false}, + { 0xDB, OP_2BYTE|OP_MMX, MMXOP_D(pand_r64_rm64), MMXOP_D(pand_r64_rm64), false}, + { 0xDC, OP_2BYTE|OP_MMX, MMXOP_D(paddusb_r64_rm64), MMXOP_D(paddusb_r64_rm64), false}, + { 0xDD, OP_2BYTE|OP_MMX, MMXOP_D(paddusw_r64_rm64), MMXOP_D(paddusw_r64_rm64), false}, + { 0xDE, OP_2BYTE|OP_SSE, SSEOP_D(pmaxub_r64_rm64), SSEOP_D(pmaxub_r64_rm64), false}, + { 0xDF, OP_2BYTE|OP_MMX, MMXOP_D(pandn_r64_rm64), MMXOP_D(pandn_r64_rm64), false}, + { 0xE0, OP_2BYTE|OP_SSE, SSEOP_D(pavgb_r64_rm64), SSEOP_D(pavgb_r64_rm64), false}, + { 0xE1, OP_2BYTE|OP_MMX, MMXOP_D(psraw_r64_rm64), MMXOP_D(psraw_r64_rm64), false}, + { 0xE2, OP_2BYTE|OP_MMX, MMXOP_D(psrad_r64_rm64), MMXOP_D(psrad_r64_rm64), false}, + { 0xE3, OP_2BYTE|OP_SSE, SSEOP_D(pavgw_r64_rm64), SSEOP_D(pavgw_r64_rm64), false}, + { 0xE4, OP_2BYTE|OP_SSE, SSEOP_D(pmulhuw_r64_rm64), SSEOP_D(pmulhuw_r64_rm64), false}, + { 0xE5, OP_2BYTE|OP_MMX, MMXOP_D(pmulhw_r64_rm64), MMXOP_D(pmulhw_r64_rm64), false}, + { 0xE7, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(movntq_m64_r64), PENTIUMOP_D(movntq_m64_r64), false}, + { 0xE8, OP_2BYTE|OP_MMX, MMXOP_D(psubsb_r64_rm64), MMXOP_D(psubsb_r64_rm64), false}, + { 0xE9, OP_2BYTE|OP_MMX, MMXOP_D(psubsw_r64_rm64), MMXOP_D(psubsw_r64_rm64), false}, + { 0xEA, OP_2BYTE|OP_SSE, SSEOP_D(pminsw_r64_rm64), SSEOP_D(pminsw_r64_rm64), false}, + { 0xEB, OP_2BYTE|OP_MMX, MMXOP_D(por_r64_rm64), MMXOP_D(por_r64_rm64), false}, + { 0xEC, OP_2BYTE|OP_MMX, MMXOP_D(paddsb_r64_rm64), MMXOP_D(paddsb_r64_rm64), false}, + { 0xED, OP_2BYTE|OP_MMX, MMXOP_D(paddsw_r64_rm64), MMXOP_D(paddsw_r64_rm64), false}, + { 0xEE, OP_2BYTE|OP_SSE, SSEOP_D(pmaxsw_r64_rm64), SSEOP_D(pmaxsw_r64_rm64), false}, + { 0xEF, OP_2BYTE|OP_MMX, MMXOP_D(pxor_r64_rm64), MMXOP_D(pxor_r64_rm64), false}, + { 0xF1, OP_2BYTE|OP_MMX, MMXOP_D(psllw_r64_rm64), MMXOP_D(psllw_r64_rm64), false}, + { 0xF2, OP_2BYTE|OP_MMX, MMXOP_D(pslld_r64_rm64), MMXOP_D(pslld_r64_rm64), false}, + { 0xF3, OP_2BYTE|OP_MMX, MMXOP_D(psllq_r64_rm64), MMXOP_D(psllq_r64_rm64), false}, + { 0xF4, OP_2BYTE|OP_SSE, SSEOP_D(pmuludq_r64_rm64), SSEOP_D(pmuludq_r64_rm64), false}, + { 0xF5, OP_2BYTE|OP_MMX, MMXOP_D(pmaddwd_r64_rm64), MMXOP_D(pmaddwd_r64_rm64), false}, + { 0xF6, OP_2BYTE|OP_SSE, SSEOP_D(psadbw_r64_rm64), SSEOP_D(psadbw_r64_rm64), false}, + { 0xf7, OP_2BYTE|OP_PENTIUM, PENTIUMOP_D(maskmovq_r64_r64), PENTIUMOP_D(maskmovq_r64_r64),false}, + { 0xF8, OP_2BYTE|OP_MMX, MMXOP_D(psubb_r64_rm64), MMXOP_D(psubb_r64_rm64), false}, + { 0xF9, OP_2BYTE|OP_MMX, MMXOP_D(psubw_r64_rm64), MMXOP_D(psubw_r64_rm64), false}, + { 0xFA, OP_2BYTE|OP_MMX, MMXOP_D(psubd_r64_rm64), MMXOP_D(psubd_r64_rm64), false}, + { 0xFB, OP_2BYTE|OP_SSE, SSEOP_D(psubq_r64_rm64), SSEOP_D(psubq_r64_rm64), false}, + { 0xFC, OP_2BYTE|OP_MMX, MMXOP_D(paddb_r64_rm64), MMXOP_D(paddb_r64_rm64), false}, + { 0xFD, OP_2BYTE|OP_MMX, MMXOP_D(paddw_r64_rm64), MMXOP_D(paddw_r64_rm64), false}, + { 0xFE, OP_2BYTE|OP_MMX, MMXOP_D(paddd_r64_rm64), MMXOP_D(paddd_r64_rm64), false}, /* F3 0F ?? */ - { 0x10, OP_3BYTEF3|OP_SSE, SSEOP(movss_r128_rm128), SSEOP(movss_r128_rm128), false}, - { 0x11, OP_3BYTEF3|OP_SSE, SSEOP(movss_rm128_r128), SSEOP(movss_rm128_r128), false}, - { 0x12, OP_3BYTEF3|OP_SSE, SSEOP(movsldup_r128_rm128), SSEOP(movsldup_r128_rm128), false}, - { 0x16, OP_3BYTEF3|OP_SSE, SSEOP(movshdup_r128_rm128), SSEOP(movshdup_r128_rm128), false}, - { 0x2A, OP_3BYTEF3|OP_SSE, SSEOP(cvtsi2ss_r128_rm32), SSEOP(cvtsi2ss_r128_rm32), false}, - { 0x2C, OP_3BYTEF3|OP_SSE, SSEOP(cvttss2si_r32_r128m32), SSEOP(cvttss2si_r32_r128m32),false}, - { 0x2D, OP_3BYTEF3|OP_SSE, SSEOP(cvtss2si_r32_r128m32), SSEOP(cvtss2si_r32_r128m32),false}, - { 0x51, OP_3BYTEF3|OP_SSE, SSEOP(sqrtss_r128_r128m32), SSEOP(sqrtss_r128_r128m32), false}, - { 0x52, OP_3BYTEF3|OP_SSE, SSEOP(rsqrtss_r128_r128m32), SSEOP(rsqrtss_r128_r128m32),false}, - { 0x53, OP_3BYTEF3|OP_SSE, SSEOP(rcpss_r128_r128m32), SSEOP(rcpss_r128_r128m32), false}, - { 0x58, OP_3BYTEF3|OP_SSE, SSEOP(addss), SSEOP(addss), false}, - { 0x59, OP_3BYTEF3|OP_SSE, SSEOP(mulss), SSEOP(mulss), false}, - { 0x5A, OP_3BYTEF3|OP_SSE, SSEOP(cvtss2sd_r128_r128m32), SSEOP(cvtss2sd_r128_r128m32),false}, - { 0x5B, OP_3BYTEF3|OP_SSE, SSEOP(cvttps2dq_r128_rm128), SSEOP(cvttps2dq_r128_rm128),false}, - { 0x5C, OP_3BYTEF3|OP_SSE, SSEOP(subss), SSEOP(subss), false}, - { 0x5D, OP_3BYTEF3|OP_SSE, SSEOP(minss_r128_r128m32), SSEOP(minss_r128_r128m32), false}, - { 0x5E, OP_3BYTEF3|OP_SSE, SSEOP(divss), SSEOP(divss), false}, - { 0x5F, OP_3BYTEF3|OP_SSE, SSEOP(maxss_r128_r128m32), SSEOP(maxss_r128_r128m32), false}, - { 0x6F, OP_3BYTEF3|OP_SSE, SSEOP(movdqu_r128_rm128), SSEOP(movdqu_r128_rm128), false}, - { 0x70, OP_3BYTEF3|OP_SSE, SSEOP(pshufhw_r128_rm128_i8), SSEOP(pshufhw_r128_rm128_i8),false}, - { 0x7E, OP_3BYTEF3|OP_SSE, SSEOP(movq_r128_r128m64), SSEOP(movq_r128_r128m64), false}, - { 0x7F, OP_3BYTEF3|OP_SSE, SSEOP(movdqu_rm128_r128), SSEOP(movdqu_rm128_r128), false}, - { 0xAE, OP_3BYTE66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xB8, OP_3BYTEF3|OP_PENTIUM, PENTIUMOP(popcnt_r16_rm16), PENTIUMOP(popcnt_r32_rm32), false}, - { 0xBC, OP_3BYTEF3|OP_PENTIUM, PENTIUMOP(tzcnt_r16_rm16), PENTIUMOP(tzcnt_r32_rm32), false}, - { 0xC2, OP_3BYTEF3|OP_SSE, SSEOP(cmpss_r128_r128m32_i8), SSEOP(cmpss_r128_r128m32_i8),false}, - { 0xC7, OP_3BYTEF2|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xD6, OP_3BYTEF3|OP_SSE, SSEOP(movq2dq_r128_r64), SSEOP(movq2dq_r128_r64), false}, - { 0xE6, OP_3BYTEF3|OP_SSE, SSEOP(cvtdq2pd_r128_r128m64), SSEOP(cvtdq2pd_r128_r128m64),false}, + { 0x10, OP_3BYTEF3|OP_SSE, SSEOP_D(movss_r128_rm128), SSEOP_D(movss_r128_rm128), false}, + { 0x11, OP_3BYTEF3|OP_SSE, SSEOP_D(movss_rm128_r128), SSEOP_D(movss_rm128_r128), false}, + { 0x12, OP_3BYTEF3|OP_SSE, SSEOP_D(movsldup_r128_rm128), SSEOP_D(movsldup_r128_rm128), false}, + { 0x16, OP_3BYTEF3|OP_SSE, SSEOP_D(movshdup_r128_rm128), SSEOP_D(movshdup_r128_rm128), false}, + { 0x2A, OP_3BYTEF3|OP_SSE, SSEOP_D(cvtsi2ss_r128_rm32), SSEOP_D(cvtsi2ss_r128_rm32), false}, + { 0x2C, OP_3BYTEF3|OP_SSE, SSEOP_D(cvttss2si_r32_r128m32), SSEOP_D(cvttss2si_r32_r128m32),false}, + { 0x2D, OP_3BYTEF3|OP_SSE, SSEOP_D(cvtss2si_r32_r128m32), SSEOP_D(cvtss2si_r32_r128m32),false}, + { 0x51, OP_3BYTEF3|OP_SSE, SSEOP_D(sqrtss_r128_r128m32), SSEOP_D(sqrtss_r128_r128m32), false}, + { 0x52, OP_3BYTEF3|OP_SSE, SSEOP_D(rsqrtss_r128_r128m32), SSEOP_D(rsqrtss_r128_r128m32),false}, + { 0x53, OP_3BYTEF3|OP_SSE, SSEOP_D(rcpss_r128_r128m32), SSEOP_D(rcpss_r128_r128m32), false}, + { 0x58, OP_3BYTEF3|OP_SSE, SSEOP_D(addss), SSEOP_D(addss), false}, + { 0x59, OP_3BYTEF3|OP_SSE, SSEOP_D(mulss), SSEOP_D(mulss), false}, + { 0x5A, OP_3BYTEF3|OP_SSE, SSEOP_D(cvtss2sd_r128_r128m32), SSEOP_D(cvtss2sd_r128_r128m32),false}, + { 0x5B, OP_3BYTEF3|OP_SSE, SSEOP_D(cvttps2dq_r128_rm128), SSEOP_D(cvttps2dq_r128_rm128),false}, + { 0x5C, OP_3BYTEF3|OP_SSE, SSEOP_D(subss), SSEOP_D(subss), false}, + { 0x5D, OP_3BYTEF3|OP_SSE, SSEOP_D(minss_r128_r128m32), SSEOP_D(minss_r128_r128m32), false}, + { 0x5E, OP_3BYTEF3|OP_SSE, SSEOP_D(divss), SSEOP_D(divss), false}, + { 0x5F, OP_3BYTEF3|OP_SSE, SSEOP_D(maxss_r128_r128m32), SSEOP_D(maxss_r128_r128m32), false}, + { 0x6F, OP_3BYTEF3|OP_SSE, SSEOP_D(movdqu_r128_rm128), SSEOP_D(movdqu_r128_rm128), false}, + { 0x70, OP_3BYTEF3|OP_SSE, SSEOP_D(pshufhw_r128_rm128_i8), SSEOP_D(pshufhw_r128_rm128_i8),false}, + { 0x7E, OP_3BYTEF3|OP_SSE, SSEOP_D(movq_r128_r128m64), SSEOP_D(movq_r128_r128m64), false}, + { 0x7F, OP_3BYTEF3|OP_SSE, SSEOP_D(movdqu_rm128_r128), SSEOP_D(movdqu_rm128_r128), false}, + { 0xAE, OP_3BYTE66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xB8, OP_3BYTEF3|OP_PENTIUM, PENTIUMOP_D(popcnt_r16_rm16), PENTIUMOP_D(popcnt_r32_rm32), false}, + { 0xBC, OP_3BYTEF3|OP_PENTIUM, PENTIUMOP_D(tzcnt_r16_rm16), PENTIUMOP_D(tzcnt_r32_rm32), false}, + { 0xC2, OP_3BYTEF3|OP_SSE, SSEOP_D(cmpss_r128_r128m32_i8), SSEOP_D(cmpss_r128_r128m32_i8),false}, + { 0xC7, OP_3BYTEF2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xD6, OP_3BYTEF3|OP_SSE, SSEOP_D(movq2dq_r128_r64), SSEOP_D(movq2dq_r128_r64), false}, + { 0xE6, OP_3BYTEF3|OP_SSE, SSEOP_D(cvtdq2pd_r128_r128m64), SSEOP_D(cvtdq2pd_r128_r128m64),false}, /* F2 0F ?? */ - { 0x10, OP_3BYTEF2|OP_SSE, SSEOP(movsd_r128_r128m64), SSEOP(movsd_r128_r128m64), false}, - { 0x11, OP_3BYTEF2|OP_SSE, SSEOP(movsd_r128m64_r128), SSEOP(movsd_r128m64_r128), false}, - { 0x12, OP_3BYTEF2|OP_SSE, SSEOP(movddup_r128_r128m64), SSEOP(movddup_r128_r128m64),false}, - { 0x2A, OP_3BYTEF2|OP_SSE, SSEOP(cvtsi2sd_r128_rm32), SSEOP(cvtsi2sd_r128_rm32), false}, - { 0x2C, OP_3BYTEF2|OP_SSE, SSEOP(cvttsd2si_r32_r128m64), SSEOP(cvttsd2si_r32_r128m64),false}, - { 0x2D, OP_3BYTEF2|OP_SSE, SSEOP(cvtsd2si_r32_r128m64), SSEOP(cvtsd2si_r32_r128m64),false}, - { 0x51, OP_3BYTEF2|OP_SSE, SSEOP(sqrtsd_r128_r128m64), SSEOP(sqrtsd_r128_r128m64), false}, - { 0x58, OP_3BYTEF2|OP_SSE, SSEOP(addsd_r128_r128m64), SSEOP(addsd_r128_r128m64), false}, - { 0x59, OP_3BYTEF2|OP_SSE, SSEOP(mulsd_r128_r128m64), SSEOP(mulsd_r128_r128m64), false}, - { 0x5A, OP_3BYTEF2|OP_SSE, SSEOP(cvtsd2ss_r128_r128m64), SSEOP(cvtsd2ss_r128_r128m64),false}, - { 0x5C, OP_3BYTEF2|OP_SSE, SSEOP(subsd_r128_r128m64), SSEOP(subsd_r128_r128m64), false}, - { 0x5D, OP_3BYTEF2|OP_SSE, SSEOP(minsd_r128_r128m64), SSEOP(minsd_r128_r128m64), false}, - { 0x5E, OP_3BYTEF2|OP_SSE, SSEOP(divsd_r128_r128m64), SSEOP(divsd_r128_r128m64), false}, - { 0x5F, OP_3BYTEF2|OP_SSE, SSEOP(maxsd_r128_r128m64), SSEOP(maxsd_r128_r128m64), false}, - { 0x70, OP_3BYTEF2|OP_SSE, SSEOP(pshuflw_r128_rm128_i8), SSEOP(pshuflw_r128_rm128_i8),false}, - { 0x7C, OP_3BYTEF2|OP_SSE, SSEOP(haddps_r128_rm128), SSEOP(haddps_r128_rm128), false}, - { 0x7D, OP_3BYTEF2|OP_SSE, SSEOP(hsubps_r128_rm128), SSEOP(hsubps_r128_rm128), false}, - { 0xC2, OP_3BYTEF2|OP_SSE, SSEOP(cmpsd_r128_r128m64_i8), SSEOP(cmpsd_r128_r128m64_i8),false}, - { 0xD0, OP_3BYTEF2|OP_SSE, SSEOP(addsubps_r128_rm128), SSEOP(addsubps_r128_rm128), false}, - { 0xD6, OP_3BYTEF2|OP_SSE, SSEOP(movdq2q_r64_r128), SSEOP(movdq2q_r64_r128), false}, - { 0xE6, OP_3BYTEF2|OP_SSE, SSEOP(cvtpd2dq_r128_rm128), SSEOP(cvtpd2dq_r128_rm128), false}, - { 0xF0, OP_3BYTEF2|OP_SSE, SSEOP(lddqu_r128_m128), SSEOP(lddqu_r128_m128), false}, + { 0x10, OP_3BYTEF2|OP_SSE, SSEOP_D(movsd_r128_r128m64), SSEOP_D(movsd_r128_r128m64), false}, + { 0x11, OP_3BYTEF2|OP_SSE, SSEOP_D(movsd_r128m64_r128), SSEOP_D(movsd_r128m64_r128), false}, + { 0x12, OP_3BYTEF2|OP_SSE, SSEOP_D(movddup_r128_r128m64), SSEOP_D(movddup_r128_r128m64),false}, + { 0x2A, OP_3BYTEF2|OP_SSE, SSEOP_D(cvtsi2sd_r128_rm32), SSEOP_D(cvtsi2sd_r128_rm32), false}, + { 0x2C, OP_3BYTEF2|OP_SSE, SSEOP_D(cvttsd2si_r32_r128m64), SSEOP_D(cvttsd2si_r32_r128m64),false}, + { 0x2D, OP_3BYTEF2|OP_SSE, SSEOP_D(cvtsd2si_r32_r128m64), SSEOP_D(cvtsd2si_r32_r128m64),false}, + { 0x51, OP_3BYTEF2|OP_SSE, SSEOP_D(sqrtsd_r128_r128m64), SSEOP_D(sqrtsd_r128_r128m64), false}, + { 0x58, OP_3BYTEF2|OP_SSE, SSEOP_D(addsd_r128_r128m64), SSEOP_D(addsd_r128_r128m64), false}, + { 0x59, OP_3BYTEF2|OP_SSE, SSEOP_D(mulsd_r128_r128m64), SSEOP_D(mulsd_r128_r128m64), false}, + { 0x5A, OP_3BYTEF2|OP_SSE, SSEOP_D(cvtsd2ss_r128_r128m64), SSEOP_D(cvtsd2ss_r128_r128m64),false}, + { 0x5C, OP_3BYTEF2|OP_SSE, SSEOP_D(subsd_r128_r128m64), SSEOP_D(subsd_r128_r128m64), false}, + { 0x5D, OP_3BYTEF2|OP_SSE, SSEOP_D(minsd_r128_r128m64), SSEOP_D(minsd_r128_r128m64), false}, + { 0x5E, OP_3BYTEF2|OP_SSE, SSEOP_D(divsd_r128_r128m64), SSEOP_D(divsd_r128_r128m64), false}, + { 0x5F, OP_3BYTEF2|OP_SSE, SSEOP_D(maxsd_r128_r128m64), SSEOP_D(maxsd_r128_r128m64), false}, + { 0x70, OP_3BYTEF2|OP_SSE, SSEOP_D(pshuflw_r128_rm128_i8), SSEOP_D(pshuflw_r128_rm128_i8),false}, + { 0x7C, OP_3BYTEF2|OP_SSE, SSEOP_D(haddps_r128_rm128), SSEOP_D(haddps_r128_rm128), false}, + { 0x7D, OP_3BYTEF2|OP_SSE, SSEOP_D(hsubps_r128_rm128), SSEOP_D(hsubps_r128_rm128), false}, + { 0xC2, OP_3BYTEF2|OP_SSE, SSEOP_D(cmpsd_r128_r128m64_i8), SSEOP_D(cmpsd_r128_r128m64_i8),false}, + { 0xD0, OP_3BYTEF2|OP_SSE, SSEOP_D(addsubps_r128_rm128), SSEOP_D(addsubps_r128_rm128), false}, + { 0xD6, OP_3BYTEF2|OP_SSE, SSEOP_D(movdq2q_r64_r128), SSEOP_D(movdq2q_r64_r128), false}, + { 0xE6, OP_3BYTEF2|OP_SSE, SSEOP_D(cvtpd2dq_r128_rm128), SSEOP_D(cvtpd2dq_r128_rm128), false}, + { 0xF0, OP_3BYTEF2|OP_SSE, SSEOP_D(lddqu_r128_m128), SSEOP_D(lddqu_r128_m128), false}, /* 66 0F ?? */ - { 0x10, OP_3BYTE66|OP_SSE2, SSEOP(movupd_r128_rm128), SSEOP(movupd_r128_rm128), false}, - { 0x11, OP_3BYTE66|OP_SSE2, SSEOP(movupd_rm128_r128), SSEOP(movupd_rm128_r128), false}, - { 0x12, OP_3BYTE66|OP_SSE2, SSEOP(movlpd_r128_m64), SSEOP(movlpd_r128_m64), false}, - { 0x13, OP_3BYTE66|OP_SSE2, SSEOP(movlpd_m64_r128), SSEOP(movlpd_m64_r128), false}, - { 0x14, OP_3BYTE66|OP_SSE2, SSEOP(unpcklpd_r128_rm128), SSEOP(unpcklpd_r128_rm128), false}, - { 0x15, OP_3BYTE66|OP_SSE2, SSEOP(unpckhpd_r128_rm128), SSEOP(unpckhpd_r128_rm128), false}, - { 0x16, OP_3BYTE66|OP_SSE2, SSEOP(movhpd_r128_m64), SSEOP(movhpd_r128_m64), false}, - { 0x17, OP_3BYTE66|OP_SSE2, SSEOP(movhpd_m64_r128), SSEOP(movhpd_m64_r128), false}, - { 0x28, OP_3BYTE66|OP_SSE2, SSEOP(movapd_r128_rm128), SSEOP(movapd_r128_rm128), false}, - { 0x29, OP_3BYTE66|OP_SSE2, SSEOP(movapd_rm128_r128), SSEOP(movapd_rm128_r128), false}, - { 0x2A, OP_3BYTE66|OP_SSE2, SSEOP(cvtpi2pd_r128_rm64), SSEOP(cvtpi2pd_r128_rm64), false}, - { 0x2B, OP_3BYTE66|OP_SSE2, SSEOP(movntpd_m128_r128), SSEOP(movntpd_m128_r128), false}, - { 0x2C, OP_3BYTE66|OP_SSE2, SSEOP(cvttpd2pi_r64_rm128), SSEOP(cvttpd2pi_r64_rm128), false}, - { 0x2D, OP_3BYTE66|OP_SSE2, SSEOP(cvtpd2pi_r64_rm128), SSEOP(cvtpd2pi_r64_rm128), false}, - { 0x2E, OP_3BYTE66|OP_SSE2, SSEOP(ucomisd_r128_r128m64), SSEOP(ucomisd_r128_r128m64),false}, - { 0x2F, OP_3BYTE66|OP_SSE2, SSEOP(comisd_r128_r128m64), SSEOP(comisd_r128_r128m64), false}, - { 0x50, OP_3BYTE66|OP_SSE2, SSEOP(movmskpd_r32_r128), SSEOP(movmskpd_r32_r128), false}, - { 0x51, OP_3BYTE66|OP_SSE2, SSEOP(sqrtpd_r128_rm128), SSEOP(sqrtpd_r128_rm128), false}, - { 0x54, OP_3BYTE66|OP_SSE2, SSEOP(andpd_r128_rm128), SSEOP(andpd_r128_rm128), false}, - { 0x55, OP_3BYTE66|OP_SSE2, SSEOP(andnpd_r128_rm128), SSEOP(andnpd_r128_rm128), false}, - { 0x56, OP_3BYTE66|OP_SSE2, SSEOP(orpd_r128_rm128), SSEOP(orpd_r128_rm128), false}, - { 0x57, OP_3BYTE66|OP_SSE2, SSEOP(xorpd_r128_rm128), SSEOP(xorpd_r128_rm128), false}, - { 0x58, OP_3BYTE66|OP_SSE2, SSEOP(addpd_r128_rm128), SSEOP(addpd_r128_rm128), false}, - { 0x59, OP_3BYTE66|OP_SSE2, SSEOP(mulpd_r128_rm128), SSEOP(mulpd_r128_rm128), false}, - { 0x5A, OP_3BYTE66|OP_SSE2, SSEOP(cvtpd2ps_r128_rm128), SSEOP(cvtpd2ps_r128_rm128), false}, - { 0x5B, OP_3BYTE66|OP_SSE2, SSEOP(cvtps2dq_r128_rm128), SSEOP(cvtps2dq_r128_rm128), false}, - { 0x5C, OP_3BYTE66|OP_SSE2, SSEOP(subpd_r128_rm128), SSEOP(subpd_r128_rm128), false}, - { 0x5D, OP_3BYTE66|OP_SSE2, SSEOP(minpd_r128_rm128), SSEOP(minpd_r128_rm128), false}, - { 0x5E, OP_3BYTE66|OP_SSE2, SSEOP(divpd_r128_rm128), SSEOP(divpd_r128_rm128), false}, - { 0x5F, OP_3BYTE66|OP_SSE2, SSEOP(maxpd_r128_rm128), SSEOP(maxpd_r128_rm128), false}, - { 0x60, OP_3BYTE66|OP_SSE2, SSEOP(punpcklbw_r128_rm128), SSEOP(punpcklbw_r128_rm128),false}, - { 0x61, OP_3BYTE66|OP_SSE2, SSEOP(punpcklwd_r128_rm128), SSEOP(punpcklwd_r128_rm128),false}, - { 0x62, OP_3BYTE66|OP_SSE2, SSEOP(punpckldq_r128_rm128), SSEOP(punpckldq_r128_rm128),false}, - { 0x63, OP_3BYTE66|OP_SSE2, SSEOP(packsswb_r128_rm128), SSEOP(packsswb_r128_rm128), false}, - { 0x64, OP_3BYTE66|OP_SSE2, SSEOP(pcmpgtb_r128_rm128), SSEOP(pcmpgtb_r128_rm128), false}, - { 0x65, OP_3BYTE66|OP_SSE2, SSEOP(pcmpgtw_r128_rm128), SSEOP(pcmpgtw_r128_rm128), false}, - { 0x66, OP_3BYTE66|OP_SSE2, SSEOP(pcmpgtd_r128_rm128), SSEOP(pcmpgtd_r128_rm128), false}, - { 0x67, OP_3BYTE66|OP_SSE2, SSEOP(packuswb_r128_rm128), SSEOP(packuswb_r128_rm128), false}, - { 0x68, OP_3BYTE66|OP_SSE2, SSEOP(punpckhbw_r128_rm128), SSEOP(punpckhbw_r128_rm128),false}, - { 0x69, OP_3BYTE66|OP_SSE2, SSEOP(punpckhwd_r128_rm128), SSEOP(punpckhwd_r128_rm128),false}, - { 0x6A, OP_3BYTE66|OP_SSE2, SSEOP(unpckhdq_r128_rm128), SSEOP(unpckhdq_r128_rm128), false}, - { 0x6B, OP_3BYTE66|OP_SSE2, SSEOP(packssdw_r128_rm128), SSEOP(packssdw_r128_rm128), false}, - { 0x6C, OP_3BYTE66|OP_SSE2, SSEOP(punpcklqdq_r128_rm128), SSEOP(punpcklqdq_r128_rm128),false}, - { 0x6D, OP_3BYTE66|OP_SSE2, SSEOP(punpckhqdq_r128_rm128), SSEOP(punpckhqdq_r128_rm128),false}, - { 0x6E, OP_3BYTE66|OP_SSE2, SSEOP(movd_m128_rm32), SSEOP(movd_m128_rm32), false}, - { 0x6F, OP_3BYTE66|OP_SSE2, SSEOP(movdqa_m128_rm128), SSEOP(movdqa_m128_rm128), false}, - { 0x70, OP_3BYTE66|OP_SSE2, SSEOP(pshufd_r128_rm128_i8), SSEOP(pshufd_r128_rm128_i8),false}, - { 0x71, OP_3BYTE66|OP_SSE2, SSEOP(group_660f71), SSEOP(group_660f71), false}, - { 0x72, OP_3BYTE66|OP_SSE2, SSEOP(group_660f72), SSEOP(group_660f72), false}, - { 0x73, OP_3BYTE66|OP_SSE2, SSEOP(group_660f73), SSEOP(group_660f73), false}, - { 0x74, OP_3BYTE66|OP_SSE2, SSEOP(pcmpeqb_r128_rm128), SSEOP(pcmpeqb_r128_rm128), false}, - { 0x75, OP_3BYTE66|OP_SSE2, SSEOP(pcmpeqw_r128_rm128), SSEOP(pcmpeqw_r128_rm128), false}, - { 0x76, OP_3BYTE66|OP_SSE2, SSEOP(pcmpeqd_r128_rm128), SSEOP(pcmpeqd_r128_rm128), false}, - { 0x7C, OP_3BYTE66|OP_SSE2, SSEOP(haddpd_r128_rm128), SSEOP(haddpd_r128_rm128), false}, - { 0x7D, OP_3BYTE66|OP_SSE2, SSEOP(hsubpd_r128_rm128), SSEOP(hsubpd_r128_rm128), false}, - { 0x7E, OP_3BYTE66|OP_SSE2, SSEOP(movd_rm32_r128), SSEOP(movd_rm32_r128), false}, - { 0x7F, OP_3BYTE66|OP_SSE2, SSEOP(movdqa_rm128_r128), SSEOP(movdqa_rm128_r128), false}, - { 0xC2, OP_3BYTE66|OP_SSE2, SSEOP(cmppd_r128_rm128_i8), SSEOP(cmppd_r128_rm128_i8), false}, - { 0xC4, OP_3BYTE66|OP_SSE, SSEOP(pinsrw_r128_r32m16_i8), SSEOP(pinsrw_r128_r32m16_i8),false}, - { 0xC5, OP_3BYTE66|OP_SSE, SSEOP(pextrw_reg_r128_i8), SSEOP(pextrw_reg_r128_i8), false}, - { 0xC6, OP_3BYTE66|OP_SSE2, SSEOP(shufpd_r128_rm128_i8), SSEOP(shufpd_r128_rm128_i8),false}, - { 0xC7, OP_3BYTE66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xD0, OP_3BYTE66|OP_SSE2, SSEOP(addsubpd_r128_rm128), SSEOP(addsubpd_r128_rm128), false}, - { 0xD1, OP_3BYTE66|OP_SSE2, SSEOP(psrlw_r128_rm128), SSEOP(psrlw_r128_rm128), false}, - { 0xD2, OP_3BYTE66|OP_SSE2, SSEOP(psrld_r128_rm128), SSEOP(psrld_r128_rm128), false}, - { 0xD3, OP_3BYTE66|OP_SSE2, SSEOP(psrlq_r128_rm128), SSEOP(psrlq_r128_rm128), false}, - { 0xD4, OP_3BYTE66|OP_SSE2, SSEOP(paddq_r128_rm128), SSEOP(paddq_r128_rm128), false}, - { 0xD5, OP_3BYTE66|OP_SSE2, SSEOP(pmullw_r128_rm128), SSEOP(pmullw_r128_rm128), false}, - { 0xD6, OP_3BYTE66|OP_SSE2, SSEOP(movq_r128m64_r128), SSEOP(movq_r128m64_r128), false}, - { 0xD7, OP_3BYTE66|OP_SSE, SSEOP(pmovmskb_r32_r128), SSEOP(pmovmskb_r32_r128), false}, - { 0xD8, OP_3BYTE66|OP_SSE2, SSEOP(psubusb_r128_rm128), SSEOP(psubusb_r128_rm128), false}, - { 0xD9, OP_3BYTE66|OP_SSE2, SSEOP(psubusw_r128_rm128), SSEOP(psubusw_r128_rm128), false}, - { 0xDA, OP_3BYTE66|OP_SSE2, SSEOP(pminub_r128_rm128), SSEOP(pminub_r128_rm128), false}, - { 0xDB, OP_3BYTE66|OP_SSE2, SSEOP(pand_r128_rm128), SSEOP(pand_r128_rm128), false}, - { 0xDC, OP_3BYTE66|OP_SSE2, SSEOP(paddusb_r128_rm128), SSEOP(paddusb_r128_rm128), false}, - { 0xDD, OP_3BYTE66|OP_SSE2, SSEOP(paddusw_r128_rm128), SSEOP(paddusw_r128_rm128), false}, - { 0xDE, OP_3BYTE66|OP_SSE, SSEOP(pmaxub_r128_rm128), SSEOP(pmaxub_r128_rm128), false}, - { 0xDF, OP_3BYTE66|OP_SSE2, SSEOP(pandn_r128_rm128), SSEOP(pandn_r128_rm128), false}, - { 0xE0, OP_3BYTE66|OP_SSE, SSEOP(pavgb_r128_rm128), SSEOP(pavgb_r128_rm128), false}, - { 0xE1, OP_3BYTE66|OP_SSE2, SSEOP(psraw_r128_rm128), SSEOP(psraw_r128_rm128), false}, - { 0xE2, OP_3BYTE66|OP_SSE2, SSEOP(psrad_r128_rm128), SSEOP(psrad_r128_rm128), false}, - { 0xE3, OP_3BYTE66|OP_SSE, SSEOP(pavgw_r128_rm128), SSEOP(pavgw_r128_rm128), false}, - { 0xE4, OP_3BYTE66|OP_SSE, SSEOP(pmulhuw_r128_rm128), SSEOP(pmulhuw_r128_rm128), false}, - { 0xE5, OP_3BYTE66|OP_SSE2, SSEOP(pmulhw_r128_rm128), SSEOP(pmulhw_r128_rm128), false}, - { 0xE6, OP_3BYTE66|OP_SSE2, SSEOP(cvttpd2dq_r128_rm128), SSEOP(cvttpd2dq_r128_rm128),false}, - { 0xE7, OP_3BYTE66|OP_SSE2, SSEOP(movntdq_m128_r128), SSEOP(movntdq_m128_r128), false}, - { 0xE8, OP_3BYTE66|OP_SSE2, SSEOP(psubsb_r128_rm128), SSEOP(psubsb_r128_rm128), false}, - { 0xE9, OP_3BYTE66|OP_SSE2, SSEOP(psubsw_r128_rm128), SSEOP(psubsw_r128_rm128), false}, - { 0xEA, OP_3BYTE66|OP_SSE, SSEOP(pminsw_r128_rm128), SSEOP(pminsw_r128_rm128), false}, - { 0xEB, OP_3BYTE66|OP_SSE2, SSEOP(por_r128_rm128), SSEOP(por_r128_rm128), false}, - { 0xEC, OP_3BYTE66|OP_SSE2, SSEOP(paddsb_r128_rm128), SSEOP(paddsb_r128_rm128), false}, - { 0xED, OP_3BYTE66|OP_SSE2, SSEOP(paddsw_r128_rm128), SSEOP(paddsw_r128_rm128), false}, - { 0xEE, OP_3BYTE66|OP_SSE, SSEOP(pmaxsw_r128_rm128), SSEOP(pmaxsw_r128_rm128), false}, - { 0xEF, OP_3BYTE66|OP_SSE2, SSEOP(pxor_r128_rm128), SSEOP(pxor_r128_rm128), false}, - { 0xF1, OP_3BYTE66|OP_SSE2, SSEOP(psllw_r128_rm128), SSEOP(psllw_r128_rm128), false}, - { 0xF2, OP_3BYTE66|OP_SSE2, SSEOP(pslld_r128_rm128), SSEOP(pslld_r128_rm128), false}, - { 0xF3, OP_3BYTE66|OP_SSE2, SSEOP(psllq_r128_rm128), SSEOP(psllq_r128_rm128), false}, - { 0xF4, OP_3BYTE66|OP_SSE2, SSEOP(pmuludq_r128_rm128), SSEOP(pmuludq_r128_rm128), false}, - { 0xF5, OP_3BYTE66|OP_SSE2, SSEOP(pmaddwd_r128_rm128), SSEOP(pmaddwd_r128_rm128), false}, - { 0xF6, OP_3BYTE66|OP_SSE, SSEOP(psadbw_r128_rm128), SSEOP(psadbw_r128_rm128), false}, - { 0xF7, OP_3BYTE66|OP_SSE2, SSEOP(maskmovdqu_r128_r128), SSEOP(maskmovdqu_r128_r128),false}, - { 0xF8, OP_3BYTE66|OP_SSE2, SSEOP(psubb_r128_rm128), SSEOP(psubb_r128_rm128), false}, - { 0xF9, OP_3BYTE66|OP_SSE2, SSEOP(psubw_r128_rm128), SSEOP(psubw_r128_rm128), false}, - { 0xFA, OP_3BYTE66|OP_SSE2, SSEOP(psubd_r128_rm128), SSEOP(psubd_r128_rm128), false}, - { 0xFB, OP_3BYTE66|OP_SSE2, SSEOP(psubq_r128_rm128), SSEOP(psubq_r128_rm128), false}, - { 0xFC, OP_3BYTE66|OP_SSE2, SSEOP(paddb_r128_rm128), SSEOP(paddb_r128_rm128), false}, - { 0xFD, OP_3BYTE66|OP_SSE2, SSEOP(paddw_r128_rm128), SSEOP(paddw_r128_rm128), false}, - { 0xFE, OP_3BYTE66|OP_SSE2, SSEOP(paddd_r128_rm128), SSEOP(paddd_r128_rm128), false}, + { 0x10, OP_3BYTE66|OP_SSE2, SSEOP_D(movupd_r128_rm128), SSEOP_D(movupd_r128_rm128), false}, + { 0x11, OP_3BYTE66|OP_SSE2, SSEOP_D(movupd_rm128_r128), SSEOP_D(movupd_rm128_r128), false}, + { 0x12, OP_3BYTE66|OP_SSE2, SSEOP_D(movlpd_r128_m64), SSEOP_D(movlpd_r128_m64), false}, + { 0x13, OP_3BYTE66|OP_SSE2, SSEOP_D(movlpd_m64_r128), SSEOP_D(movlpd_m64_r128), false}, + { 0x14, OP_3BYTE66|OP_SSE2, SSEOP_D(unpcklpd_r128_rm128), SSEOP_D(unpcklpd_r128_rm128), false}, + { 0x15, OP_3BYTE66|OP_SSE2, SSEOP_D(unpckhpd_r128_rm128), SSEOP_D(unpckhpd_r128_rm128), false}, + { 0x16, OP_3BYTE66|OP_SSE2, SSEOP_D(movhpd_r128_m64), SSEOP_D(movhpd_r128_m64), false}, + { 0x17, OP_3BYTE66|OP_SSE2, SSEOP_D(movhpd_m64_r128), SSEOP_D(movhpd_m64_r128), false}, + { 0x28, OP_3BYTE66|OP_SSE2, SSEOP_D(movapd_r128_rm128), SSEOP_D(movapd_r128_rm128), false}, + { 0x29, OP_3BYTE66|OP_SSE2, SSEOP_D(movapd_rm128_r128), SSEOP_D(movapd_rm128_r128), false}, + { 0x2A, OP_3BYTE66|OP_SSE2, SSEOP_D(cvtpi2pd_r128_rm64), SSEOP_D(cvtpi2pd_r128_rm64), false}, + { 0x2B, OP_3BYTE66|OP_SSE2, SSEOP_D(movntpd_m128_r128), SSEOP_D(movntpd_m128_r128), false}, + { 0x2C, OP_3BYTE66|OP_SSE2, SSEOP_D(cvttpd2pi_r64_rm128), SSEOP_D(cvttpd2pi_r64_rm128), false}, + { 0x2D, OP_3BYTE66|OP_SSE2, SSEOP_D(cvtpd2pi_r64_rm128), SSEOP_D(cvtpd2pi_r64_rm128), false}, + { 0x2E, OP_3BYTE66|OP_SSE2, SSEOP_D(ucomisd_r128_r128m64), SSEOP_D(ucomisd_r128_r128m64),false}, + { 0x2F, OP_3BYTE66|OP_SSE2, SSEOP_D(comisd_r128_r128m64), SSEOP_D(comisd_r128_r128m64), false}, + { 0x50, OP_3BYTE66|OP_SSE2, SSEOP_D(movmskpd_r32_r128), SSEOP_D(movmskpd_r32_r128), false}, + { 0x51, OP_3BYTE66|OP_SSE2, SSEOP_D(sqrtpd_r128_rm128), SSEOP_D(sqrtpd_r128_rm128), false}, + { 0x54, OP_3BYTE66|OP_SSE2, SSEOP_D(andpd_r128_rm128), SSEOP_D(andpd_r128_rm128), false}, + { 0x55, OP_3BYTE66|OP_SSE2, SSEOP_D(andnpd_r128_rm128), SSEOP_D(andnpd_r128_rm128), false}, + { 0x56, OP_3BYTE66|OP_SSE2, SSEOP_D(orpd_r128_rm128), SSEOP_D(orpd_r128_rm128), false}, + { 0x57, OP_3BYTE66|OP_SSE2, SSEOP_D(xorpd_r128_rm128), SSEOP_D(xorpd_r128_rm128), false}, + { 0x58, OP_3BYTE66|OP_SSE2, SSEOP_D(addpd_r128_rm128), SSEOP_D(addpd_r128_rm128), false}, + { 0x59, OP_3BYTE66|OP_SSE2, SSEOP_D(mulpd_r128_rm128), SSEOP_D(mulpd_r128_rm128), false}, + { 0x5A, OP_3BYTE66|OP_SSE2, SSEOP_D(cvtpd2ps_r128_rm128), SSEOP_D(cvtpd2ps_r128_rm128), false}, + { 0x5B, OP_3BYTE66|OP_SSE2, SSEOP_D(cvtps2dq_r128_rm128), SSEOP_D(cvtps2dq_r128_rm128), false}, + { 0x5C, OP_3BYTE66|OP_SSE2, SSEOP_D(subpd_r128_rm128), SSEOP_D(subpd_r128_rm128), false}, + { 0x5D, OP_3BYTE66|OP_SSE2, SSEOP_D(minpd_r128_rm128), SSEOP_D(minpd_r128_rm128), false}, + { 0x5E, OP_3BYTE66|OP_SSE2, SSEOP_D(divpd_r128_rm128), SSEOP_D(divpd_r128_rm128), false}, + { 0x5F, OP_3BYTE66|OP_SSE2, SSEOP_D(maxpd_r128_rm128), SSEOP_D(maxpd_r128_rm128), false}, + { 0x60, OP_3BYTE66|OP_SSE2, SSEOP_D(punpcklbw_r128_rm128), SSEOP_D(punpcklbw_r128_rm128),false}, + { 0x61, OP_3BYTE66|OP_SSE2, SSEOP_D(punpcklwd_r128_rm128), SSEOP_D(punpcklwd_r128_rm128),false}, + { 0x62, OP_3BYTE66|OP_SSE2, SSEOP_D(punpckldq_r128_rm128), SSEOP_D(punpckldq_r128_rm128),false}, + { 0x63, OP_3BYTE66|OP_SSE2, SSEOP_D(packsswb_r128_rm128), SSEOP_D(packsswb_r128_rm128), false}, + { 0x64, OP_3BYTE66|OP_SSE2, SSEOP_D(pcmpgtb_r128_rm128), SSEOP_D(pcmpgtb_r128_rm128), false}, + { 0x65, OP_3BYTE66|OP_SSE2, SSEOP_D(pcmpgtw_r128_rm128), SSEOP_D(pcmpgtw_r128_rm128), false}, + { 0x66, OP_3BYTE66|OP_SSE2, SSEOP_D(pcmpgtd_r128_rm128), SSEOP_D(pcmpgtd_r128_rm128), false}, + { 0x67, OP_3BYTE66|OP_SSE2, SSEOP_D(packuswb_r128_rm128), SSEOP_D(packuswb_r128_rm128), false}, + { 0x68, OP_3BYTE66|OP_SSE2, SSEOP_D(punpckhbw_r128_rm128), SSEOP_D(punpckhbw_r128_rm128),false}, + { 0x69, OP_3BYTE66|OP_SSE2, SSEOP_D(punpckhwd_r128_rm128), SSEOP_D(punpckhwd_r128_rm128),false}, + { 0x6A, OP_3BYTE66|OP_SSE2, SSEOP_D(unpckhdq_r128_rm128), SSEOP_D(unpckhdq_r128_rm128), false}, + { 0x6B, OP_3BYTE66|OP_SSE2, SSEOP_D(packssdw_r128_rm128), SSEOP_D(packssdw_r128_rm128), false}, + { 0x6C, OP_3BYTE66|OP_SSE2, SSEOP_D(punpcklqdq_r128_rm128), SSEOP_D(punpcklqdq_r128_rm128),false}, + { 0x6D, OP_3BYTE66|OP_SSE2, SSEOP_D(punpckhqdq_r128_rm128), SSEOP_D(punpckhqdq_r128_rm128),false}, + { 0x6E, OP_3BYTE66|OP_SSE2, SSEOP_D(movd_m128_rm32), SSEOP_D(movd_m128_rm32), false}, + { 0x6F, OP_3BYTE66|OP_SSE2, SSEOP_D(movdqa_m128_rm128), SSEOP_D(movdqa_m128_rm128), false}, + { 0x70, OP_3BYTE66|OP_SSE2, SSEOP_D(pshufd_r128_rm128_i8), SSEOP_D(pshufd_r128_rm128_i8),false}, + { 0x71, OP_3BYTE66|OP_SSE2, SSEOP_D(group_660f71), SSEOP_D(group_660f71), false}, + { 0x72, OP_3BYTE66|OP_SSE2, SSEOP_D(group_660f72), SSEOP_D(group_660f72), false}, + { 0x73, OP_3BYTE66|OP_SSE2, SSEOP_D(group_660f73), SSEOP_D(group_660f73), false}, + { 0x74, OP_3BYTE66|OP_SSE2, SSEOP_D(pcmpeqb_r128_rm128), SSEOP_D(pcmpeqb_r128_rm128), false}, + { 0x75, OP_3BYTE66|OP_SSE2, SSEOP_D(pcmpeqw_r128_rm128), SSEOP_D(pcmpeqw_r128_rm128), false}, + { 0x76, OP_3BYTE66|OP_SSE2, SSEOP_D(pcmpeqd_r128_rm128), SSEOP_D(pcmpeqd_r128_rm128), false}, + { 0x7C, OP_3BYTE66|OP_SSE2, SSEOP_D(haddpd_r128_rm128), SSEOP_D(haddpd_r128_rm128), false}, + { 0x7D, OP_3BYTE66|OP_SSE2, SSEOP_D(hsubpd_r128_rm128), SSEOP_D(hsubpd_r128_rm128), false}, + { 0x7E, OP_3BYTE66|OP_SSE2, SSEOP_D(movd_rm32_r128), SSEOP_D(movd_rm32_r128), false}, + { 0x7F, OP_3BYTE66|OP_SSE2, SSEOP_D(movdqa_rm128_r128), SSEOP_D(movdqa_rm128_r128), false}, + { 0xC2, OP_3BYTE66|OP_SSE2, SSEOP_D(cmppd_r128_rm128_i8), SSEOP_D(cmppd_r128_rm128_i8), false}, + { 0xC4, OP_3BYTE66|OP_SSE, SSEOP_D(pinsrw_r128_r32m16_i8), SSEOP_D(pinsrw_r128_r32m16_i8),false}, + { 0xC5, OP_3BYTE66|OP_SSE, SSEOP_D(pextrw_reg_r128_i8), SSEOP_D(pextrw_reg_r128_i8), false}, + { 0xC6, OP_3BYTE66|OP_SSE2, SSEOP_D(shufpd_r128_rm128_i8), SSEOP_D(shufpd_r128_rm128_i8),false}, + { 0xC7, OP_3BYTE66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xD0, OP_3BYTE66|OP_SSE2, SSEOP_D(addsubpd_r128_rm128), SSEOP_D(addsubpd_r128_rm128), false}, + { 0xD1, OP_3BYTE66|OP_SSE2, SSEOP_D(psrlw_r128_rm128), SSEOP_D(psrlw_r128_rm128), false}, + { 0xD2, OP_3BYTE66|OP_SSE2, SSEOP_D(psrld_r128_rm128), SSEOP_D(psrld_r128_rm128), false}, + { 0xD3, OP_3BYTE66|OP_SSE2, SSEOP_D(psrlq_r128_rm128), SSEOP_D(psrlq_r128_rm128), false}, + { 0xD4, OP_3BYTE66|OP_SSE2, SSEOP_D(paddq_r128_rm128), SSEOP_D(paddq_r128_rm128), false}, + { 0xD5, OP_3BYTE66|OP_SSE2, SSEOP_D(pmullw_r128_rm128), SSEOP_D(pmullw_r128_rm128), false}, + { 0xD6, OP_3BYTE66|OP_SSE2, SSEOP_D(movq_r128m64_r128), SSEOP_D(movq_r128m64_r128), false}, + { 0xD7, OP_3BYTE66|OP_SSE, SSEOP_D(pmovmskb_r32_r128), SSEOP_D(pmovmskb_r32_r128), false}, + { 0xD8, OP_3BYTE66|OP_SSE2, SSEOP_D(psubusb_r128_rm128), SSEOP_D(psubusb_r128_rm128), false}, + { 0xD9, OP_3BYTE66|OP_SSE2, SSEOP_D(psubusw_r128_rm128), SSEOP_D(psubusw_r128_rm128), false}, + { 0xDA, OP_3BYTE66|OP_SSE2, SSEOP_D(pminub_r128_rm128), SSEOP_D(pminub_r128_rm128), false}, + { 0xDB, OP_3BYTE66|OP_SSE2, SSEOP_D(pand_r128_rm128), SSEOP_D(pand_r128_rm128), false}, + { 0xDC, OP_3BYTE66|OP_SSE2, SSEOP_D(paddusb_r128_rm128), SSEOP_D(paddusb_r128_rm128), false}, + { 0xDD, OP_3BYTE66|OP_SSE2, SSEOP_D(paddusw_r128_rm128), SSEOP_D(paddusw_r128_rm128), false}, + { 0xDE, OP_3BYTE66|OP_SSE, SSEOP_D(pmaxub_r128_rm128), SSEOP_D(pmaxub_r128_rm128), false}, + { 0xDF, OP_3BYTE66|OP_SSE2, SSEOP_D(pandn_r128_rm128), SSEOP_D(pandn_r128_rm128), false}, + { 0xE0, OP_3BYTE66|OP_SSE, SSEOP_D(pavgb_r128_rm128), SSEOP_D(pavgb_r128_rm128), false}, + { 0xE1, OP_3BYTE66|OP_SSE2, SSEOP_D(psraw_r128_rm128), SSEOP_D(psraw_r128_rm128), false}, + { 0xE2, OP_3BYTE66|OP_SSE2, SSEOP_D(psrad_r128_rm128), SSEOP_D(psrad_r128_rm128), false}, + { 0xE3, OP_3BYTE66|OP_SSE, SSEOP_D(pavgw_r128_rm128), SSEOP_D(pavgw_r128_rm128), false}, + { 0xE4, OP_3BYTE66|OP_SSE, SSEOP_D(pmulhuw_r128_rm128), SSEOP_D(pmulhuw_r128_rm128), false}, + { 0xE5, OP_3BYTE66|OP_SSE2, SSEOP_D(pmulhw_r128_rm128), SSEOP_D(pmulhw_r128_rm128), false}, + { 0xE6, OP_3BYTE66|OP_SSE2, SSEOP_D(cvttpd2dq_r128_rm128), SSEOP_D(cvttpd2dq_r128_rm128),false}, + { 0xE7, OP_3BYTE66|OP_SSE2, SSEOP_D(movntdq_m128_r128), SSEOP_D(movntdq_m128_r128), false}, + { 0xE8, OP_3BYTE66|OP_SSE2, SSEOP_D(psubsb_r128_rm128), SSEOP_D(psubsb_r128_rm128), false}, + { 0xE9, OP_3BYTE66|OP_SSE2, SSEOP_D(psubsw_r128_rm128), SSEOP_D(psubsw_r128_rm128), false}, + { 0xEA, OP_3BYTE66|OP_SSE, SSEOP_D(pminsw_r128_rm128), SSEOP_D(pminsw_r128_rm128), false}, + { 0xEB, OP_3BYTE66|OP_SSE2, SSEOP_D(por_r128_rm128), SSEOP_D(por_r128_rm128), false}, + { 0xEC, OP_3BYTE66|OP_SSE2, SSEOP_D(paddsb_r128_rm128), SSEOP_D(paddsb_r128_rm128), false}, + { 0xED, OP_3BYTE66|OP_SSE2, SSEOP_D(paddsw_r128_rm128), SSEOP_D(paddsw_r128_rm128), false}, + { 0xEE, OP_3BYTE66|OP_SSE, SSEOP_D(pmaxsw_r128_rm128), SSEOP_D(pmaxsw_r128_rm128), false}, + { 0xEF, OP_3BYTE66|OP_SSE2, SSEOP_D(pxor_r128_rm128), SSEOP_D(pxor_r128_rm128), false}, + { 0xF1, OP_3BYTE66|OP_SSE2, SSEOP_D(psllw_r128_rm128), SSEOP_D(psllw_r128_rm128), false}, + { 0xF2, OP_3BYTE66|OP_SSE2, SSEOP_D(pslld_r128_rm128), SSEOP_D(pslld_r128_rm128), false}, + { 0xF3, OP_3BYTE66|OP_SSE2, SSEOP_D(psllq_r128_rm128), SSEOP_D(psllq_r128_rm128), false}, + { 0xF4, OP_3BYTE66|OP_SSE2, SSEOP_D(pmuludq_r128_rm128), SSEOP_D(pmuludq_r128_rm128), false}, + { 0xF5, OP_3BYTE66|OP_SSE2, SSEOP_D(pmaddwd_r128_rm128), SSEOP_D(pmaddwd_r128_rm128), false}, + { 0xF6, OP_3BYTE66|OP_SSE, SSEOP_D(psadbw_r128_rm128), SSEOP_D(psadbw_r128_rm128), false}, + { 0xF7, OP_3BYTE66|OP_SSE2, SSEOP_D(maskmovdqu_r128_r128), SSEOP_D(maskmovdqu_r128_r128),false}, + { 0xF8, OP_3BYTE66|OP_SSE2, SSEOP_D(psubb_r128_rm128), SSEOP_D(psubb_r128_rm128), false}, + { 0xF9, OP_3BYTE66|OP_SSE2, SSEOP_D(psubw_r128_rm128), SSEOP_D(psubw_r128_rm128), false}, + { 0xFA, OP_3BYTE66|OP_SSE2, SSEOP_D(psubd_r128_rm128), SSEOP_D(psubd_r128_rm128), false}, + { 0xFB, OP_3BYTE66|OP_SSE2, SSEOP_D(psubq_r128_rm128), SSEOP_D(psubq_r128_rm128), false}, + { 0xFC, OP_3BYTE66|OP_SSE2, SSEOP_D(paddb_r128_rm128), SSEOP_D(paddb_r128_rm128), false}, + { 0xFD, OP_3BYTE66|OP_SSE2, SSEOP_D(paddw_r128_rm128), SSEOP_D(paddw_r128_rm128), false}, + { 0xFE, OP_3BYTE66|OP_SSE2, SSEOP_D(paddd_r128_rm128), SSEOP_D(paddd_r128_rm128), false}, /* 0F 38 ?? */ - { 0x00, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x01, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x02, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x03, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x04, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x05, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x06, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x07, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x08, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x09, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0A, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0B, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1C, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1D, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1E, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF0, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF1, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF2, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF3, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF5, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF7, OP_3BYTE38|OP_SSE, I386OP(invalid), I386OP(invalid), false}, + { 0x00, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x01, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x02, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x03, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x04, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x05, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x06, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x07, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x08, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x09, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0A, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0B, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1C, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1D, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1E, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF0, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF1, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF2, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF3, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF5, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF7, OP_3BYTE38|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, /* 0F 3A ?? */ - { 0x0F, OP_3BYTE3A|OP_SSE, I386OP(invalid), I386OP(invalid), false}, + { 0x0F, OP_3BYTE3A|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, /* 66 0F 38 ?? */ - { 0x00, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x01, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x02, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x03, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x04, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x05, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x06, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x07, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x08, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x09, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0A, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0B, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0C, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0D, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0E, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0F, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x10, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x13, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x14, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x15, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x16, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x17, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x18, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x19, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1A, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1C, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1D, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1E, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x20, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x21, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x22, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x23, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x24, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x25, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x28, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x29, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x2A, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x2B, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x2C, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x2D, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x2E, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x2F, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x30, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x31, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x32, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x33, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x34, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x35, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x36, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x37, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x38, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x39, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x3A, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x3B, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x3C, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x3D, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x3E, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x3F, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x40, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x41, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x45, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x46, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x47, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x58, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x59, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x5A, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x78, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x79, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x80, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x81, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x82, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x8C, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x8E, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x90, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x91, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x92, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x93, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x96, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x97, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x98, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x99, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x9A, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x9B, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x9C, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x9D, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x9E, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x9F, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xA6, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xA7, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xA8, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xA9, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xAA, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xAB, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xAC, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xAD, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xAE, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xAF, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xB6, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xB7, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xB8, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xB9, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xBA, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xBB, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xBC, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xBD, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xBE, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xBF, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xDB, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xDC, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xDD, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xDE, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xDF, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF0, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF1, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF3, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF6, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF7, OP_4BYTE3866|OP_SSE, I386OP(invalid), I386OP(invalid), false}, + { 0x00, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x01, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x02, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x03, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x04, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x05, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x06, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x07, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x08, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x09, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0A, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0B, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0C, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0D, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0E, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0F, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x10, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x13, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x14, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x15, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x16, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x17, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x18, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x19, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1A, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1C, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1D, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1E, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x20, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x21, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x22, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x23, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x24, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x25, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x28, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x29, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x2A, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x2B, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x2C, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x2D, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x2E, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x2F, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x30, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x31, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x32, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x33, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x34, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x35, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x36, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x37, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x38, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x39, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x3A, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x3B, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x3C, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x3D, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x3E, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x3F, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x40, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x41, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x45, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x46, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x47, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x58, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x59, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x5A, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x78, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x79, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x80, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x81, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x82, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x8C, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x8E, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x90, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x91, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x92, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x93, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x96, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x97, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x98, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x99, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x9A, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x9B, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x9C, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x9D, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x9E, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x9F, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xA6, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xA7, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xA8, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xA9, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xAA, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xAB, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xAC, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xAD, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xAE, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xAF, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xB6, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xB7, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xB8, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xB9, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xBA, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xBB, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xBC, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xBD, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xBE, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xBF, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xDB, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xDC, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xDD, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xDE, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xDF, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF0, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF1, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF3, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF6, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF7, OP_4BYTE3866|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, /* F2 0F 38 ?? */ - { 0xF0, OP_4BYTE38F2|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF1, OP_4BYTE38F2|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF3, OP_4BYTE38F2|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF5, OP_4BYTE38F2|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF6, OP_4BYTE38F2|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF7, OP_4BYTE38F2|OP_SSE, I386OP(invalid), I386OP(invalid), false}, + { 0xF0, OP_4BYTE38F2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF1, OP_4BYTE38F2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF3, OP_4BYTE38F2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF5, OP_4BYTE38F2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF6, OP_4BYTE38F2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF7, OP_4BYTE38F2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, /* F3 0F 38 ?? */ - { 0xF3, OP_4BYTE38F3|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF5, OP_4BYTE38F3|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF6, OP_4BYTE38F3|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xF7, OP_4BYTE38F3|OP_SSE, I386OP(invalid), I386OP(invalid), false}, + { 0xF3, OP_4BYTE38F3|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF5, OP_4BYTE38F3|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF6, OP_4BYTE38F3|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xF7, OP_4BYTE38F3|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, /* 66 0F 3A ?? */ - { 0x00, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x01, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x02, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x04, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x05, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x06, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x08, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x09, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0A, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0B, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0C, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0D, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0E, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x0F, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x14, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x15, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x16, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x17, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x18, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x19, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x1D, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x20, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x21, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x22, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x38, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x39, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x40, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x41, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x42, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x44, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x46, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x4A, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x4B, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x4C, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x60, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x61, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x62, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0x63, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, - { 0xDF, OP_4BYTE3A66|OP_SSE, I386OP(invalid), I386OP(invalid), false}, + { 0x00, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x01, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x02, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x04, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x05, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x06, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x08, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x09, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0A, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0B, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0C, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0D, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0E, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x0F, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x14, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x15, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x16, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x17, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x18, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x19, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x1D, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x20, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x21, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x22, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x38, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x39, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x40, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x41, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x42, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x44, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x46, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x4A, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x4B, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x4C, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x60, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x61, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x62, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0x63, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, + { 0xDF, OP_4BYTE3A66|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false}, /* F2 0F 3A ?? */ - { 0xF0, OP_4BYTE3AF2|OP_SSE, I386OP(invalid), I386OP(invalid), false} + { 0xF0, OP_4BYTE3AF2|OP_SSE, I386OP_D(invalid), I386OP_D(invalid), false} }; diff --git a/source/src/vm/mame/emu/cpu/i386/i386priv.h b/source/src/vm/mame/emu/cpu/i386/i386priv.h index d5fbc09c7..15bbe2389 100644 --- a/source/src/vm/mame/emu/cpu/i386/i386priv.h +++ b/source/src/vm/mame/emu/cpu/i386/i386priv.h @@ -19,6 +19,11 @@ #define PENTIUMOP(XX) pentium_##XX #define MMXOP(XX) mmx_##XX #define SSEOP(XX) sse_##XX +#define I386OP_D(XX) (void __FASTCALL (*)(i386_state *))(&i386_##XX) +#define I486OP_D(XX) (void __FASTCALL (*)(i386_state *))(&i486_##XX) +#define PENTIUMOP_D(XX) (void __FASTCALL (*)(i386_state *))(&pentium_##XX) +#define MMXOP_D(XX) (void __FASTCALL (*)(i386_state *))(&mmx_##XX) +#define SSEOP_D(XX) (void __FASTCALL (*)(i386_state *))(&sse_##XX) static int i386_dasm_one(_TCHAR *buffer, UINT32 pc, const UINT8 *oprom, int mode); @@ -588,14 +593,14 @@ struct i386_state DEVICE *pic; DEVICE *program; DEVICE *io; -//#ifdef I386_PSEUDO_BIOS +//#ifdef I86_PSEUDO_BIOS DEVICE *bios; //#endif //#ifdef SINGLE_MODE_DMA DEVICE *dma; //#endif //#ifdef USE_DEBUGGER - EMU *emu; + EMU_TEMPLATE *emu; DEBUGGER *debugger; DEVICE *program_stored; DEVICE *io_stored; @@ -868,6 +873,7 @@ INLINE int __FASTCALL i386_limit_check(i386_state *cpustate, int seg, UINT32 off } else { +// offset &= cpustate->a20_mask; if(((offset + size - 1) > cpustate->sreg[seg].limit) /*&& (cpustate->sreg[seg].limit != 0)*/) { logerror("Limit check at 0x%08x failed. Segment %04x, limit %08x, offset %08x\n",cpustate->prev_pc,cpustate->sreg[seg].selector,cpustate->sreg[seg].limit,offset); @@ -1432,7 +1438,6 @@ INLINE UINT32 __FASTCALL READ32PL0(i386_state *cpustate,UINT32 ea) { UINT32 value; UINT32 address = ea, error; - if( !DWORD_ALIGNED(ea) ) { /* Unaligned read */ UINT32 mask = cpustate->a20_mask; if(!translate_address_with_width(cpustate,0,TRANSLATE_READ,4,&address,&error)) { diff --git a/source/src/vm/mame/emu/cpu/i386/x87ops.c b/source/src/vm/mame/emu/cpu/i386/x87ops.c index 62342608e..8ea590798 100644 --- a/source/src/vm/mame/emu/cpu/i386/x87ops.c +++ b/source/src/vm/mame/emu/cpu/i386/x87ops.c @@ -165,7 +165,7 @@ INLINE double fx80_to_double(floatx80 fx) INLINE floatx80 double_to_fx80(double in) { - return float64_to_floatx80(*(UINT64*)&in); + return float64_to_floatx80(*((UINT64*)(&in))); } INLINE floatx80 READ80(i386_state *cpustate, UINT32 ea) diff --git a/source/src/vm/mame/emu/cpu/i86/i286.c b/source/src/vm/mame/emu/cpu/i86/i286.c index 9f484b979..b0e33e972 100644 --- a/source/src/vm/mame/emu/cpu/i86/i286.c +++ b/source/src/vm/mame/emu/cpu/i86/i286.c @@ -71,7 +71,7 @@ struct i80286_state DEVICE *dma; //#endif //#ifdef USE_DEBUGGER - EMU *emu; + EMU_TEMPLATE *emu; DEBUGGER *debugger; DEVICE *program_stored; DEVICE *io_stored; @@ -336,7 +336,7 @@ static CPU_EXECUTE( i80286 ) } } if (icount == -1) { - int passed_icount = max(1, cpustate->extra_cycles); + int passed_icount = max(5, cpustate->extra_cycles); // 80286 CPI: 4.8 // this is main cpu, cpustate->icount is not used /*cpustate->icount = */cpustate->extra_cycles = 0; //#ifdef USE_DEBUGGER diff --git a/source/src/vm/mame/emu/cpu/i86/i86.c b/source/src/vm/mame/emu/cpu/i86/i86.c index cdeb3ea4c..aa93aee1c 100644 --- a/source/src/vm/mame/emu/cpu/i86/i86.c +++ b/source/src/vm/mame/emu/cpu/i86/i86.c @@ -38,7 +38,8 @@ struct i8086_state INT32 AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */ UINT8 ParityVal; UINT8 TF, IF; /* 0 or 1 valued flags */ - UINT8 MF; /* V30 mode flag */ + UINT8 MF, MF_WriteDisabled; /* V30 mode flag */ + UINT8 NF; /* 8080 N flag */ UINT8 int_vector; INT8 nmi_state; @@ -64,7 +65,7 @@ struct i8086_state DEVICE *dma; //#endif //#ifdef USE_DEBUGGER - EMU *emu; + EMU_TEMPLATE *emu; DEBUGGER *debugger; DEVICE *program_stored; DEVICE *io_stored; @@ -169,6 +170,12 @@ static CPU_INIT( i80186 ) return ret; } +static CPU_INIT( v30 ) +{ + void *ret = CPU_INIT_CALL(i8086); + return ret; +} + static CPU_RESET( i8086 ) { //#ifdef USE_DEBUGGER @@ -211,6 +218,12 @@ static CPU_RESET( i80186 ) CPU_RESET_CALL(i8086); } +static CPU_RESET( v30 ) +{ + CPU_RESET_CALL(i8086); + cpustate->MF = cpustate->MF_WriteDisabled = 1; + cpustate->NF = 0; /* is this correct ? */ +} /* ASG 971222 -- added these interface functions */ @@ -238,6 +251,7 @@ static void set_irq_line(i8086_state *cpustate, int irqline, int state) if (state != CLEAR_LINE) { PREFIX(_interrupt)(cpustate, I8086_NMI_INT_VECTOR); + cpustate->MF = 1; /* enter native mode */ cpustate->nmi_state = CLEAR_LINE; } } @@ -248,6 +262,7 @@ static void set_irq_line(i8086_state *cpustate, int irqline, int state) /* if the IF is set, signal an interrupt */ if (state != CLEAR_LINE && cpustate->IF) { PREFIX(_interrupt)(cpustate, (UINT32)-1); + cpustate->MF = 1; /* enter native mode */ cpustate->irq_state = CLEAR_LINE; } } @@ -409,6 +424,184 @@ CPU_EXECUTE( i8086 ) int first_icount = cpustate->icount; cpustate->seg_prefix = FALSE; cpustate->prevpc = cpustate->pc; + cpustate->MF = 1; /* bit15 in flags is always 1 */ + TABLE86; + cpustate->total_icount += first_icount - cpustate->icount; +//#ifdef SINGLE_MODE_DMA + if(!cpustate->haltreq) { + if(cpustate->dma != NULL) { + cpustate->dma->do_dma(); + } + } +//#endif + if(now_debugging) { + if(!cpustate->debugger->now_going) { + cpustate->debugger->now_suspended = true; + } + cpustate->program = cpustate->program_stored; + cpustate->io = cpustate->io_stored; + } + } else { + if(cpustate->debugger != NULL) { + cpustate->debugger->add_cpu_trace(cpustate->pc); + } + int first_icount = cpustate->icount; +//#endif + cpustate->seg_prefix = FALSE; + cpustate->prevpc = cpustate->pc; + cpustate->MF = 1; /* bit15 in flags is always 1 */ + TABLE86; +//#ifdef USE_DEBUGGER + cpustate->total_icount += first_icount - cpustate->icount; +//#endif +//#ifdef SINGLE_MODE_DMA + if(!cpustate->haltreq) { + if(cpustate->dma != NULL) { + cpustate->dma->do_dma(); + } + } +//#endif +//#ifdef USE_DEBUGGER + } +//#endif + /* adjust for any interrupts that came in */ +//#ifdef USE_DEBUGGER + cpustate->total_icount += cpustate->extra_cycles; +//#endif + cpustate->icount -= cpustate->extra_cycles; + cpustate->extra_cycles = 0; + } + + /* if busreq is raised, spin cpu while remained clock */ + if (cpustate->icount > 0 && (cpustate->busreq || cpustate->haltreq)) { +//#ifdef USE_DEBUGGER + cpustate->total_icount += cpustate->icount; +//#endif + cpustate->icount = 0; + } + cpu_wait_i86(cpustate, base_icount - cpustate->icount); + int passed_icount = base_icount - cpustate->icount; + cpustate->icount = 0; + return passed_icount; +} + +CPU_EXECUTE( i8088 ) +{ + if (cpustate->halted || cpustate->busreq || cpustate->haltreq) + { +//#ifdef SINGLE_MODE_DMA + if(!cpustate->haltreq) { + if(cpustate->dma != NULL) { + cpustate->dma->do_dma(); + } + } +//#endif + bool now_debugging = false; + if(cpustate->debugger != NULL) { + now_debugging = cpustate->debugger->now_debugging; + } + if(now_debugging) { + cpustate->debugger->check_break_points(cpustate->pc); + if(cpustate->debugger->now_suspended) { + cpustate->debugger->now_waiting = true; + cpustate->emu->start_waiting_in_debugger(); + while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) { + cpustate->emu->process_waiting_in_debugger(); + } + cpustate->emu->finish_waiting_in_debugger(); + cpustate->debugger->now_waiting = false; + } + if(cpustate->debugger->now_debugging) { + cpustate->program = cpustate->io = cpustate->debugger; + } else { + now_debugging = false; + } + if(now_debugging) { + if(!cpustate->debugger->now_going) { + cpustate->debugger->now_suspended = true; + } + cpustate->program = cpustate->program_stored; + cpustate->io = cpustate->io_stored; + } + } + if (icount == -1) { + int passed_icount = max(1, cpustate->extra_cycles); + // this is main cpu, cpustate->icount is not used + /*cpustate->icount = */cpustate->extra_cycles = 0; +//#ifdef USE_DEBUGGER + cpustate->total_icount += passed_icount; +//#endif + cpu_wait_i86(cpustate, passed_icount); + return passed_icount; + } else { + cpustate->icount += icount; + int base_icount = cpustate->icount; + + /* adjust for any interrupts that came in */ + cpustate->icount -= cpustate->extra_cycles; + cpustate->extra_cycles = 0; + + /* if busreq is raised, spin cpu while remained clock */ + if (cpustate->icount > 0) { + cpustate->icount = 0; + } +//#ifdef USE_DEBUGGER + cpustate->total_icount += base_icount - cpustate->icount; +//#endif + cpu_wait_i86(cpustate, base_icount - cpustate->icount); + int passed_icount = base_icount - cpustate->icount; + cpustate->icount = 0; + return passed_icount; + } + } + + if (icount == -1) { + cpustate->icount = 1; + } else { + cpustate->icount += icount; + } + int base_icount = cpustate->icount; + + /* copy over the cycle counts if they're not correct */ + if (timing.id != 8086) + timing = i8086_cycles; + + /* adjust for any interrupts that came in */ +//#ifdef USE_DEBUGGER + cpustate->total_icount += cpustate->extra_cycles; +//#endif + cpustate->icount -= cpustate->extra_cycles; + cpustate->extra_cycles = 0; + + /* run until we're out */ + while (cpustate->icount > 0 && !cpustate->busreq && !cpustate->haltreq) + { +//#ifdef USE_DEBUGGER + bool now_debugging = false; + if(cpustate->debugger != NULL) { + now_debugging = cpustate->debugger->now_debugging; + } + if(now_debugging) { + cpustate->debugger->check_break_points(cpustate->pc); + if(cpustate->debugger->now_suspended) { + cpustate->debugger->now_waiting = true; + cpustate->emu->start_waiting_in_debugger(); + while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) { + cpustate->emu->process_waiting_in_debugger(); + } + cpustate->emu->finish_waiting_in_debugger(); + cpustate->debugger->now_waiting = false; + } + if(cpustate->debugger->now_debugging) { + cpustate->program = cpustate->io = cpustate->debugger; + } else { + now_debugging = false; + } + cpustate->debugger->add_cpu_trace(cpustate->pc); + int first_icount = cpustate->icount; + cpustate->seg_prefix = FALSE; + cpustate->prevpc = cpustate->pc; + cpustate->MF = 1; /* bit15 in flags is always 1 */ TABLE86; cpustate->total_icount += first_icount - cpustate->icount; //#ifdef SINGLE_MODE_DMA @@ -433,6 +626,7 @@ CPU_EXECUTE( i8086 ) //#endif cpustate->seg_prefix = FALSE; cpustate->prevpc = cpustate->pc; + cpustate->MF = 1; /* bit15 in flags is always 1 */ TABLE86; //#ifdef USE_DEBUGGER cpustate->total_icount += first_icount - cpustate->icount; @@ -620,6 +814,7 @@ CPU_EXECUTE( i80186 ) int first_icount = cpustate->icount; cpustate->seg_prefix = FALSE; cpustate->prevpc = cpustate->pc; + cpustate->MF = 1; /* bit15 in flags is always 1 */ TABLE186; cpustate->total_icount += first_icount - cpustate->icount; //#ifdef SINGLE_MODE_DMA @@ -644,6 +839,7 @@ CPU_EXECUTE( i80186 ) //#endif cpustate->seg_prefix = FALSE; cpustate->prevpc = cpustate->pc; + cpustate->MF = 1; /* bit15 in flags is always 1 */ TABLE186; //#ifdef USE_DEBUGGER cpustate->total_icount += first_icount - cpustate->icount; @@ -679,3 +875,256 @@ CPU_EXECUTE( i80186 ) return passed_icount; } +#undef I80186 + +#undef PREFIX +#define PREFIX(name) v30##name +#define PREFIXV30(name) v30##name +#define PREFIX80(name) i8080##name + +#define I80186 +#include "instrv30.h" +#include "tablev30.h" + +#include "instr86.c" +#include "instrv30.c" +#undef I80186 + +static void PREFIX(_interrupt)(i8086_state *cpustate, unsigned int_num) +{ + PREFIX86(_interrupt)(cpustate, int_num); +} + +static void __FASTCALL cpu_wait_v30(cpu_state *cpustate,int clocks) +{ + if(clocks <= 0) clocks = 1; + int64_t wfactor = cpustate->waitfactor; + int64_t wcount = cpustate->waitcount; + int64_t mwait = cpustate->memory_wait; + int64_t ncount; + if(cpustate->waitfactor >= 65536) { + wcount += ((wfactor - 65536) * clocks); // Append wait due to be slower clock. + } + wcount += (wfactor * mwait); // memory wait + if(wcount >= 65536) { + ncount = wcount >> 16; + wcount = wcount - (ncount << 16); + cpustate->extra_cycles += (int)ncount; + } else if(wcount < 0) { + wcount = 0; + } + cpustate->waitcount = wcount; + cpustate->memory_wait = 0; +} + +CPU_EXECUTE( v30 ) +{ + if (cpustate->halted || cpustate->busreq || cpustate->haltreq) + { +//#ifdef SINGLE_MODE_DMA + if(!cpustate->haltreq) { + if (cpustate->dma != NULL){ + cpustate->dma->do_dma(); + } + } +//#endif + bool now_debugging = false; + if(cpustate->debugger != NULL) { + now_debugging = cpustate->debugger->now_debugging; + } + if(now_debugging) { + cpustate->debugger->check_break_points(cpustate->pc); + if(cpustate->debugger->now_suspended) { + cpustate->debugger->now_waiting = true; + cpustate->emu->start_waiting_in_debugger(); + while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) { + cpustate->emu->process_waiting_in_debugger(); + } + cpustate->emu->finish_waiting_in_debugger(); + cpustate->debugger->now_waiting = false; + } + if(cpustate->debugger->now_debugging) { + cpustate->program = cpustate->io = cpustate->debugger; + } else { + now_debugging = false; + } + if(now_debugging) { + if(!cpustate->debugger->now_going) { + cpustate->debugger->now_suspended = true; + } + cpustate->program = cpustate->program_stored; + cpustate->io = cpustate->io_stored; + } + } + int passed_icount; + if (icount == -1) { + passed_icount = max(1, cpustate->extra_cycles); + // this is main cpu, cpustate->icount is not used + cpustate->icount += passed_icount; + cpustate->extra_cycles = 0; + cpustate->total_icount += passed_icount; +// cpu_wait_v30(cpustate, passed_icount); + } else { +#if 0 + cpustate->icount += icount; + int base_icount = cpustate->icount; + /* adjust for any interrupts that came in */ + cpustate->icount -= cpustate->extra_cycles; + cpustate->extra_cycles = 0; + /* if busreq is raised, spin cpu while remained clock */ + if (cpustate->icount > 0) { + cpustate->icount = 0; + } +//#ifdef USE_DEBUGGER + cpustate->total_icount += base_icount - cpustate->icount; +//#endif + cpu_wait_v30(cpustate, base_icount - cpustate->icount); + return base_icount - cpustate->icount; +#else + int passed_icount = 0; + if(icount > 0) { + passed_icount = icount; + } + if(cpustate->extra_cycles > 0) { + passed_icount += cpustate->extra_cycles; + } + cpustate->icount = 0; + cpustate->extra_cycles = 0; + cpustate->total_icount += passed_icount; +//#endif +// cpu_wait_v30(cpustate, passed_icount); +#endif + } + return passed_icount; + } + // Not HALTED + if (icount == -1) { + cpustate->icount = 1; + } else { + cpustate->icount += icount; + } + int base_icount = cpustate->icount; + + /* copy over the cycle counts if they're not correct */ + if (timing.id != 80186) + timing = i80186_cycles; + + /* adjust for any interrupts that came in */ +//#ifdef USE_DEBUGGER + cpustate->total_icount += cpustate->extra_cycles; +//#endif + cpustate->icount -= cpustate->extra_cycles; + cpustate->extra_cycles = 0; + + /* run until we're out */ + while (cpustate->icount > 0 && !cpustate->busreq && !cpustate->haltreq) + { +//#ifdef USE_DEBUGGER + bool now_debugging = false; + if(cpustate->debugger != NULL) { + now_debugging = cpustate->debugger->now_debugging; + } + if(now_debugging) { + cpustate->debugger->check_break_points(cpustate->pc); + if(cpustate->debugger->now_suspended) { + cpustate->debugger->now_waiting = true; + cpustate->emu->start_waiting_in_debugger(); + while(cpustate->debugger->now_debugging && cpustate->debugger->now_suspended) { + cpustate->emu->process_waiting_in_debugger(); + } + cpustate->emu->finish_waiting_in_debugger(); + cpustate->debugger->now_waiting = false; + } + if(cpustate->debugger->now_debugging) { + cpustate->program = cpustate->io = cpustate->debugger; + } else { + now_debugging = false; + } + cpustate->debugger->add_cpu_trace(cpustate->pc); + int first_icount = cpustate->icount; + cpustate->seg_prefix = FALSE; + cpustate->prevpc = cpustate->pc; + if(cpustate->MF) { + TABLEV30; + if(cpustate->MF_WriteDisabled) cpustate->MF = 1; + } else { + UINT16 flags = (CompressFlags() & ~2) | (cpustate->NF << 1); + UINT8 ah = cpustate->regs.b[AH]; + cpustate->regs.b[AH] = (UINT8)(flags & 0xff); + TABLE80; + flags = (cpustate->MF ? 0x8000 : 0) | (flags & 0x7f00) | cpustate->regs.b[AH]; + ExpandFlags(flags); + cpustate->NF = (flags & 2) >> 1; + cpustate->regs.b[AH] = ah; + } + cpustate->total_icount += first_icount - cpustate->icount; +//#ifdef SINGLE_MODE_DMA + if(!cpustate->haltreq) { + if (cpustate->dma != NULL) { + cpustate->dma->do_dma(); + } + } +//#endif + if(now_debugging) { + if(!cpustate->debugger->now_going) { + cpustate->debugger->now_suspended = true; + } + cpustate->program = cpustate->program_stored; + cpustate->io = cpustate->io_stored; + } + } else { + if(cpustate->debugger != NULL) { + cpustate->debugger->add_cpu_trace(cpustate->pc); + } + int first_icount = cpustate->icount; +//#endif + cpustate->seg_prefix = FALSE; + cpustate->prevpc = cpustate->pc; + if(cpustate->MF) { + TABLEV30; + if(cpustate->MF_WriteDisabled) cpustate->MF = 1; + } else { + UINT16 flags = (CompressFlags() & ~2) | (cpustate->NF << 1); + UINT8 ah = cpustate->regs.b[AH]; + cpustate->regs.b[AH] = (UINT8)(flags & 0xff); + TABLE80; + flags = (cpustate->MF ? 0x8000 : 0) | (flags & 0x7f00) | cpustate->regs.b[AH]; + ExpandFlags(flags); + cpustate->NF = (flags & 2) >> 1; + cpustate->regs.b[AH] = ah; + } +//#ifdef USE_DEBUGGER + cpustate->total_icount += first_icount - cpustate->icount; +//#endif +//#ifdef SINGLE_MODE_DMA + if(!cpustate->haltreq) { + if (cpustate->dma != NULL) { + cpustate->dma->do_dma(); + } + } +//#endif +//#ifdef USE_DEBUGGER + } +//#endif + /* adjust for any interrupts that came in */ +//#ifdef USE_DEBUGGER + cpustate->total_icount += cpustate->extra_cycles; +//#endif + cpustate->icount -= cpustate->extra_cycles; + cpustate->extra_cycles = 0; + } + + /* if busreq is raised, spin cpu while remained clock */ + if (cpustate->icount > 0 && (cpustate->busreq || cpustate->haltreq)) { +//#ifdef USE_DEBUGGER + cpustate->total_icount += cpustate->icount; +//#endif + cpustate->icount = 0; + return base_icount; + } + int passed_icount = base_icount - cpustate->icount; + cpu_wait_v30(cpustate, passed_icount); + cpustate->icount = 0; + return passed_icount; +} + diff --git a/source/src/vm/mame/emu/cpu/i86/i86priv.h b/source/src/vm/mame/emu/cpu/i86/i86priv.h index f03bdf35f..14f130458 100644 --- a/source/src/vm/mame/emu/cpu/i86/i86priv.h +++ b/source/src/vm/mame/emu/cpu/i86/i86priv.h @@ -42,7 +42,6 @@ enum BREGS { #define SetTF(x) (cpustate->TF = (x)) #define SetIF(x) (cpustate->IF = (x)) -#define SetMD(x) (cpustate->MF = (x)) #define SetDF(x) (cpustate->DirVal = (x) ? -1 : 1) #define SetOFW_Add(x,y,z) (cpustate->OverVal = ((x) ^ (y)) & ((x) ^ (z)) & 0x8000) @@ -230,11 +229,11 @@ inline __FASTCALL void write_port_word(i8086_state *cpustate, uint32_t a, uint32 #else #define IOPL (3) #define NT (1) -#define xF (1) +#define xF (cpustate->MF) #endif #define CompressFlags() (WORD)(CF | 2 |(PF << 2) | (AF << 4) | (ZF << 6) \ - | (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) | (cpustate->MF << 15) \ + | (SF << 7) | (cpustate->TF << 8) | (cpustate->IF << 9) \ | (DF << 10) | (OF << 11) | (IOPL << 12) | (NT << 14) | (xF << 15)) #define ExpandFlags(f) \ @@ -246,8 +245,8 @@ inline __FASTCALL void write_port_word(i8086_state *cpustate, uint32_t a, uint32 cpustate->SignVal = ((f) & 128) ? -1 : 0; \ cpustate->TF = ((f) & 256) >> 8; \ cpustate->IF = ((f) & 512) >> 9; \ - cpustate->MF = ((f) & 32768) >> 15; \ cpustate->DirVal = ((f) & 1024) ? -1 : 1; \ cpustate->OverVal = (f) & 2048; \ + cpustate->MF = ((f) & 32768) >> 15; \ } #endif /* __I86_H__ */ diff --git a/source/src/vm/mame/emu/cpu/i86/instr286.c b/source/src/vm/mame/emu/cpu/i86/instr286.c index 7e1925cc7..4ef2c9663 100644 --- a/source/src/vm/mame/emu/cpu/i86/instr286.c +++ b/source/src/vm/mame/emu/cpu/i86/instr286.c @@ -78,7 +78,7 @@ #define JMP 1 #define CALL 2 -static CPU_RESET( CPU_MODEL ); +static CPU_RESET( i80286 ); // when a cpu reset happens on a AT the bios checks for 9 in byte 0xf // of the nvram. if yes, after init, it sets the stack pointer to the value in 0040:0067 @@ -113,7 +113,7 @@ static void i80286_trap2(i80286_state *cpustate,UINT32 error) // this is supposed to triggered by support hardware // create a shutdown output line that causes a reset // NMI can wake processor without reset - CPU_RESET_CALL(CPU_MODEL); + CPU_RESET_CALL(i80286); cpustate->shutdown = 1; } cpustate->trap_level = 0; diff --git a/source/src/vm/mame/emu/cpu/i86/instrv30.c b/source/src/vm/mame/emu/cpu/i86/instrv30.c index 7729feed9..6b76548e2 100644 --- a/source/src/vm/mame/emu/cpu/i86/instrv30.c +++ b/source/src/vm/mame/emu/cpu/i86/instrv30.c @@ -1064,6 +1064,8 @@ static void PREFIXV30(_0fpre)(i8086_state *cpustate) /* Opcode 0x0f */ ICOUNT -= 38; logerror("PC=%06x : BRKEM %02x\n", activecpu_get_pc() - 3, ModRM); PREFIX86(_interrupt)(cpustate, ModRM); + cpustate->MF = 0; + cpustate->MF_WriteDisabled = 0; break; } } @@ -1240,6 +1242,18 @@ static void PREFIXV30(_repc)(i8086_state *cpustate) /* Opcode 0x65 */ PREFIXV30(repc)(cpustate, 1); } +static void PREFIXV30(_aam)(i8086_state *cpustate) /* Opcode 0xd4 */ +{ + unsigned mult = FETCH; + + ICOUNT -= timing.aam; + + cpustate->regs.b[AH] = cpustate->regs.b[AL] / 10; + cpustate->regs.b[AL] %= 10; + + SetSZPF_Word(cpustate->regs.w[AX]); +} + static void PREFIXV30(_aad)(i8086_state *cpustate) /* Opcode 0xd5 */ { unsigned mult = FETCH; @@ -1328,3 +1342,2197 @@ static void PREFIXV30(_brks)(i8086_state *cpustate) /* Opcode 0xf1 - Break to S logerror("PC=%06x : BRKS %02x\n", activecpu_get_pc() - 2, int_vector); } #endif + +/* i8080 instructions */ + +/* +DS1 ES +PS CS +SS SS +DS0 DS +*/ +#define I8080_AF cpustate->regs.w[AX] +#define I8080_HL cpustate->regs.w[BX] +#define I8080_BC cpustate->regs.w[CX] +#define I8080_DE cpustate->regs.w[DX] + +#define I8080_F cpustate->regs.b[AH] +#define I8080_A cpustate->regs.b[AL] + +#define I8080_H cpustate->regs.b[BH] +#define I8080_L cpustate->regs.b[BL] +#define I8080_B cpustate->regs.b[CH] +#define I8080_C cpustate->regs.b[CL] +#define I8080_D cpustate->regs.b[DH] +#define I8080_E cpustate->regs.b[DL] + +#define I8080_SP cpustate->regs.w[BP] + +#define I8080_CF 0x01 +#define I8080_NF 0x02 +#define I8080_VF 0x04 +#define I8080_XF 0x08 +#define I8080_HF 0x10 +#define I8080_YF 0x20 +#define I8080_ZF 0x40 +#define I8080_SF 0x80 + +static const int I8080_CLK[0x100] = { + 4,10, 7, 5, 5, 5, 7, 4, 4,10, 7, 5, 5, 5, 7, 4, 4,10, 7, 5, 5, 5, 7, 4, 4,10, 7, 5, 5, 5, 7, 4, + 4,10,16, 5, 5, 5, 7, 4, 4,10,16, 5, 5, 5, 7, 4, 4,10,13, 5,10,10,10, 4, 4,10,13, 5, 5, 5, 7, 4, + 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, + 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 7, 5, + 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, + 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, + 5,10,10,10,11,11, 7,11, 5,10,10,10,11,17, 7,11, 5,10,10,10,11,11, 7,11, 5,10,10,10,11,17, 7,11, + 5,10,10,18,11,11, 7,11, 5, 5,10, 5,11,17, 7,11, 5,10,10, 4,11,11, 7,11, 5, 5,10, 4,11,17, 7,11 +}; + +static const UINT8 I8080_ZS[256] = { + 0x40,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,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,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,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, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80 +}; + +static const UINT8 I8080_ZSP[256] = { + 0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04, + 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00, + 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00, + 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04, + 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00, + 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04, + 0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04, + 0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00, + 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80, + 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84, + 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84, + 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80, + 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84, + 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80, + 0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80, + 0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84 +}; + +static const UINT16 I8080_DAA[2048] = { + 0x0044,0x0100,0x0200,0x0304,0x0400,0x0504,0x0604,0x0700,0x0808,0x090c,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510, + 0x1000,0x1104,0x1204,0x1300,0x1404,0x1500,0x1600,0x1704,0x180c,0x1908,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530, + 0x2020,0x2124,0x2224,0x2320,0x2424,0x2520,0x2620,0x2724,0x282c,0x2928,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534, + 0x3024,0x3120,0x3220,0x3324,0x3420,0x3524,0x3624,0x3720,0x3828,0x392c,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510, + 0x4000,0x4104,0x4204,0x4300,0x4404,0x4500,0x4600,0x4704,0x480c,0x4908,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514, + 0x5004,0x5100,0x5200,0x5304,0x5400,0x5504,0x5604,0x5700,0x5808,0x590c,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534, + 0x6024,0x6120,0x6220,0x6324,0x6420,0x6524,0x6624,0x6720,0x6828,0x692c,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530, + 0x7020,0x7124,0x7224,0x7320,0x7424,0x7520,0x7620,0x7724,0x782c,0x7928,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590, + 0x8080,0x8184,0x8284,0x8380,0x8484,0x8580,0x8680,0x8784,0x888c,0x8988,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594, + 0x9084,0x9180,0x9280,0x9384,0x9480,0x9584,0x9684,0x9780,0x9888,0x998c,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515, + 0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,0x0809,0x090d,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511, + 0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,0x180d,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531, + 0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,0x282d,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535, + 0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,0x3829,0x392d,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511, + 0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,0x480d,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515, + 0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,0x5809,0x590d,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535, + 0x6025,0x6121,0x6221,0x6325,0x6421,0x6525,0x6625,0x6721,0x6829,0x692d,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531, + 0x7021,0x7125,0x7225,0x7321,0x7425,0x7521,0x7621,0x7725,0x782d,0x7929,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591, + 0x8081,0x8185,0x8285,0x8381,0x8485,0x8581,0x8681,0x8785,0x888d,0x8989,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595, + 0x9085,0x9181,0x9281,0x9385,0x9481,0x9585,0x9685,0x9781,0x9889,0x998d,0xa0b5,0xa1b1,0xa2b1,0xa3b5,0xa4b1,0xa5b5, + 0xa0a5,0xa1a1,0xa2a1,0xa3a5,0xa4a1,0xa5a5,0xa6a5,0xa7a1,0xa8a9,0xa9ad,0xb0b1,0xb1b5,0xb2b5,0xb3b1,0xb4b5,0xb5b1, + 0xb0a1,0xb1a5,0xb2a5,0xb3a1,0xb4a5,0xb5a1,0xb6a1,0xb7a5,0xb8ad,0xb9a9,0xc095,0xc191,0xc291,0xc395,0xc491,0xc595, + 0xc085,0xc181,0xc281,0xc385,0xc481,0xc585,0xc685,0xc781,0xc889,0xc98d,0xd091,0xd195,0xd295,0xd391,0xd495,0xd591, + 0xd081,0xd185,0xd285,0xd381,0xd485,0xd581,0xd681,0xd785,0xd88d,0xd989,0xe0b1,0xe1b5,0xe2b5,0xe3b1,0xe4b5,0xe5b1, + 0xe0a1,0xe1a5,0xe2a5,0xe3a1,0xe4a5,0xe5a1,0xe6a1,0xe7a5,0xe8ad,0xe9a9,0xf0b5,0xf1b1,0xf2b1,0xf3b5,0xf4b1,0xf5b5, + 0xf0a5,0xf1a1,0xf2a1,0xf3a5,0xf4a1,0xf5a5,0xf6a5,0xf7a1,0xf8a9,0xf9ad,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515, + 0x0045,0x0101,0x0201,0x0305,0x0401,0x0505,0x0605,0x0701,0x0809,0x090d,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511, + 0x1001,0x1105,0x1205,0x1301,0x1405,0x1501,0x1601,0x1705,0x180d,0x1909,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531, + 0x2021,0x2125,0x2225,0x2321,0x2425,0x2521,0x2621,0x2725,0x282d,0x2929,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535, + 0x3025,0x3121,0x3221,0x3325,0x3421,0x3525,0x3625,0x3721,0x3829,0x392d,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511, + 0x4001,0x4105,0x4205,0x4301,0x4405,0x4501,0x4601,0x4705,0x480d,0x4909,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515, + 0x5005,0x5101,0x5201,0x5305,0x5401,0x5505,0x5605,0x5701,0x5809,0x590d,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535, + 0x0604,0x0700,0x0808,0x090c,0x0a0c,0x0b08,0x0c0c,0x0d08,0x0e08,0x0f0c,0x1010,0x1114,0x1214,0x1310,0x1414,0x1510, + 0x1600,0x1704,0x180c,0x1908,0x1a08,0x1b0c,0x1c08,0x1d0c,0x1e0c,0x1f08,0x2030,0x2134,0x2234,0x2330,0x2434,0x2530, + 0x2620,0x2724,0x282c,0x2928,0x2a28,0x2b2c,0x2c28,0x2d2c,0x2e2c,0x2f28,0x3034,0x3130,0x3230,0x3334,0x3430,0x3534, + 0x3624,0x3720,0x3828,0x392c,0x3a2c,0x3b28,0x3c2c,0x3d28,0x3e28,0x3f2c,0x4010,0x4114,0x4214,0x4310,0x4414,0x4510, + 0x4600,0x4704,0x480c,0x4908,0x4a08,0x4b0c,0x4c08,0x4d0c,0x4e0c,0x4f08,0x5014,0x5110,0x5210,0x5314,0x5410,0x5514, + 0x5604,0x5700,0x5808,0x590c,0x5a0c,0x5b08,0x5c0c,0x5d08,0x5e08,0x5f0c,0x6034,0x6130,0x6230,0x6334,0x6430,0x6534, + 0x6624,0x6720,0x6828,0x692c,0x6a2c,0x6b28,0x6c2c,0x6d28,0x6e28,0x6f2c,0x7030,0x7134,0x7234,0x7330,0x7434,0x7530, + 0x7620,0x7724,0x782c,0x7928,0x7a28,0x7b2c,0x7c28,0x7d2c,0x7e2c,0x7f28,0x8090,0x8194,0x8294,0x8390,0x8494,0x8590, + 0x8680,0x8784,0x888c,0x8988,0x8a88,0x8b8c,0x8c88,0x8d8c,0x8e8c,0x8f88,0x9094,0x9190,0x9290,0x9394,0x9490,0x9594, + 0x9684,0x9780,0x9888,0x998c,0x9a8c,0x9b88,0x9c8c,0x9d88,0x9e88,0x9f8c,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515, + 0x0605,0x0701,0x0809,0x090d,0x0a0d,0x0b09,0x0c0d,0x0d09,0x0e09,0x0f0d,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511, + 0x1601,0x1705,0x180d,0x1909,0x1a09,0x1b0d,0x1c09,0x1d0d,0x1e0d,0x1f09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531, + 0x2621,0x2725,0x282d,0x2929,0x2a29,0x2b2d,0x2c29,0x2d2d,0x2e2d,0x2f29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535, + 0x3625,0x3721,0x3829,0x392d,0x3a2d,0x3b29,0x3c2d,0x3d29,0x3e29,0x3f2d,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511, + 0x4601,0x4705,0x480d,0x4909,0x4a09,0x4b0d,0x4c09,0x4d0d,0x4e0d,0x4f09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515, + 0x5605,0x5701,0x5809,0x590d,0x5a0d,0x5b09,0x5c0d,0x5d09,0x5e09,0x5f0d,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535, + 0x6625,0x6721,0x6829,0x692d,0x6a2d,0x6b29,0x6c2d,0x6d29,0x6e29,0x6f2d,0x7031,0x7135,0x7235,0x7331,0x7435,0x7531, + 0x7621,0x7725,0x782d,0x7929,0x7a29,0x7b2d,0x7c29,0x7d2d,0x7e2d,0x7f29,0x8091,0x8195,0x8295,0x8391,0x8495,0x8591, + 0x8681,0x8785,0x888d,0x8989,0x8a89,0x8b8d,0x8c89,0x8d8d,0x8e8d,0x8f89,0x9095,0x9191,0x9291,0x9395,0x9491,0x9595, + 0x9685,0x9781,0x9889,0x998d,0x9a8d,0x9b89,0x9c8d,0x9d89,0x9e89,0x9f8d,0xa0b5,0xa1b1,0xa2b1,0xa3b5,0xa4b1,0xa5b5, + 0xa6a5,0xa7a1,0xa8a9,0xa9ad,0xaaad,0xaba9,0xacad,0xada9,0xaea9,0xafad,0xb0b1,0xb1b5,0xb2b5,0xb3b1,0xb4b5,0xb5b1, + 0xb6a1,0xb7a5,0xb8ad,0xb9a9,0xbaa9,0xbbad,0xbca9,0xbdad,0xbead,0xbfa9,0xc095,0xc191,0xc291,0xc395,0xc491,0xc595, + 0xc685,0xc781,0xc889,0xc98d,0xca8d,0xcb89,0xcc8d,0xcd89,0xce89,0xcf8d,0xd091,0xd195,0xd295,0xd391,0xd495,0xd591, + 0xd681,0xd785,0xd88d,0xd989,0xda89,0xdb8d,0xdc89,0xdd8d,0xde8d,0xdf89,0xe0b1,0xe1b5,0xe2b5,0xe3b1,0xe4b5,0xe5b1, + 0xe6a1,0xe7a5,0xe8ad,0xe9a9,0xeaa9,0xebad,0xeca9,0xedad,0xeead,0xefa9,0xf0b5,0xf1b1,0xf2b1,0xf3b5,0xf4b1,0xf5b5, + 0xf6a5,0xf7a1,0xf8a9,0xf9ad,0xfaad,0xfba9,0xfcad,0xfda9,0xfea9,0xffad,0x0055,0x0111,0x0211,0x0315,0x0411,0x0515, + 0x0605,0x0701,0x0809,0x090d,0x0a0d,0x0b09,0x0c0d,0x0d09,0x0e09,0x0f0d,0x1011,0x1115,0x1215,0x1311,0x1415,0x1511, + 0x1601,0x1705,0x180d,0x1909,0x1a09,0x1b0d,0x1c09,0x1d0d,0x1e0d,0x1f09,0x2031,0x2135,0x2235,0x2331,0x2435,0x2531, + 0x2621,0x2725,0x282d,0x2929,0x2a29,0x2b2d,0x2c29,0x2d2d,0x2e2d,0x2f29,0x3035,0x3131,0x3231,0x3335,0x3431,0x3535, + 0x3625,0x3721,0x3829,0x392d,0x3a2d,0x3b29,0x3c2d,0x3d29,0x3e29,0x3f2d,0x4011,0x4115,0x4215,0x4311,0x4415,0x4511, + 0x4601,0x4705,0x480d,0x4909,0x4a09,0x4b0d,0x4c09,0x4d0d,0x4e0d,0x4f09,0x5015,0x5111,0x5211,0x5315,0x5411,0x5515, + 0x5605,0x5701,0x5809,0x590d,0x5a0d,0x5b09,0x5c0d,0x5d09,0x5e09,0x5f0d,0x6035,0x6131,0x6231,0x6335,0x6431,0x6535, + 0x0046,0x0102,0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,0x080a,0x090e,0x0402,0x0506,0x0606,0x0702,0x080a,0x090e, + 0x1002,0x1106,0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,0x180e,0x190a,0x1406,0x1502,0x1602,0x1706,0x180e,0x190a, + 0x2022,0x2126,0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,0x282e,0x292a,0x2426,0x2522,0x2622,0x2726,0x282e,0x292a, + 0x3026,0x3122,0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,0x382a,0x392e,0x3422,0x3526,0x3626,0x3722,0x382a,0x392e, + 0x4002,0x4106,0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,0x480e,0x490a,0x4406,0x4502,0x4602,0x4706,0x480e,0x490a, + 0x5006,0x5102,0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,0x580a,0x590e,0x5402,0x5506,0x5606,0x5702,0x580a,0x590e, + 0x6026,0x6122,0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,0x682a,0x692e,0x6422,0x6526,0x6626,0x6722,0x682a,0x692e, + 0x7022,0x7126,0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,0x782e,0x792a,0x7426,0x7522,0x7622,0x7726,0x782e,0x792a, + 0x8082,0x8186,0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,0x888e,0x898a,0x8486,0x8582,0x8682,0x8786,0x888e,0x898a, + 0x9086,0x9182,0x9282,0x9386,0x9482,0x9586,0x9686,0x9782,0x988a,0x998e,0x3423,0x3527,0x3627,0x3723,0x382b,0x392f, + 0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480f,0x490b,0x4407,0x4503,0x4603,0x4707,0x480f,0x490b, + 0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580b,0x590f,0x5403,0x5507,0x5607,0x5703,0x580b,0x590f, + 0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682b,0x692f,0x6423,0x6527,0x6627,0x6723,0x682b,0x692f, + 0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782f,0x792b,0x7427,0x7523,0x7623,0x7727,0x782f,0x792b, + 0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888f,0x898b,0x8487,0x8583,0x8683,0x8787,0x888f,0x898b, + 0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988b,0x998f,0x9483,0x9587,0x9687,0x9783,0x988b,0x998f, + 0xa0a7,0xa1a3,0xa2a3,0xa3a7,0xa4a3,0xa5a7,0xa6a7,0xa7a3,0xa8ab,0xa9af,0xa4a3,0xa5a7,0xa6a7,0xa7a3,0xa8ab,0xa9af, + 0xb0a3,0xb1a7,0xb2a7,0xb3a3,0xb4a7,0xb5a3,0xb6a3,0xb7a7,0xb8af,0xb9ab,0xb4a7,0xb5a3,0xb6a3,0xb7a7,0xb8af,0xb9ab, + 0xc087,0xc183,0xc283,0xc387,0xc483,0xc587,0xc687,0xc783,0xc88b,0xc98f,0xc483,0xc587,0xc687,0xc783,0xc88b,0xc98f, + 0xd083,0xd187,0xd287,0xd383,0xd487,0xd583,0xd683,0xd787,0xd88f,0xd98b,0xd487,0xd583,0xd683,0xd787,0xd88f,0xd98b, + 0xe0a3,0xe1a7,0xe2a7,0xe3a3,0xe4a7,0xe5a3,0xe6a3,0xe7a7,0xe8af,0xe9ab,0xe4a7,0xe5a3,0xe6a3,0xe7a7,0xe8af,0xe9ab, + 0xf0a7,0xf1a3,0xf2a3,0xf3a7,0xf4a3,0xf5a7,0xf6a7,0xf7a3,0xf8ab,0xf9af,0xf4a3,0xf5a7,0xf6a7,0xf7a3,0xf8ab,0xf9af, + 0x0047,0x0103,0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,0x080b,0x090f,0x0403,0x0507,0x0607,0x0703,0x080b,0x090f, + 0x1003,0x1107,0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,0x180f,0x190b,0x1407,0x1503,0x1603,0x1707,0x180f,0x190b, + 0x2023,0x2127,0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,0x282f,0x292b,0x2427,0x2523,0x2623,0x2727,0x282f,0x292b, + 0x3027,0x3123,0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,0x382b,0x392f,0x3423,0x3527,0x3627,0x3723,0x382b,0x392f, + 0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480f,0x490b,0x4407,0x4503,0x4603,0x4707,0x480f,0x490b, + 0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580b,0x590f,0x5403,0x5507,0x5607,0x5703,0x580b,0x590f, + 0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682b,0x692f,0x6423,0x6527,0x6627,0x6723,0x682b,0x692f, + 0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782f,0x792b,0x7427,0x7523,0x7623,0x7727,0x782f,0x792b, + 0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888f,0x898b,0x8487,0x8583,0x8683,0x8787,0x888f,0x898b, + 0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988b,0x998f,0x9483,0x9587,0x9687,0x9783,0x988b,0x998f, + 0xfabe,0xfbba,0xfcbe,0xfdba,0xfeba,0xffbe,0x0046,0x0102,0x0202,0x0306,0x0402,0x0506,0x0606,0x0702,0x080a,0x090e, + 0x0a1e,0x0b1a,0x0c1e,0x0d1a,0x0e1a,0x0f1e,0x1002,0x1106,0x1206,0x1302,0x1406,0x1502,0x1602,0x1706,0x180e,0x190a, + 0x1a1a,0x1b1e,0x1c1a,0x1d1e,0x1e1e,0x1f1a,0x2022,0x2126,0x2226,0x2322,0x2426,0x2522,0x2622,0x2726,0x282e,0x292a, + 0x2a3a,0x2b3e,0x2c3a,0x2d3e,0x2e3e,0x2f3a,0x3026,0x3122,0x3222,0x3326,0x3422,0x3526,0x3626,0x3722,0x382a,0x392e, + 0x3a3e,0x3b3a,0x3c3e,0x3d3a,0x3e3a,0x3f3e,0x4002,0x4106,0x4206,0x4302,0x4406,0x4502,0x4602,0x4706,0x480e,0x490a, + 0x4a1a,0x4b1e,0x4c1a,0x4d1e,0x4e1e,0x4f1a,0x5006,0x5102,0x5202,0x5306,0x5402,0x5506,0x5606,0x5702,0x580a,0x590e, + 0x5a1e,0x5b1a,0x5c1e,0x5d1a,0x5e1a,0x5f1e,0x6026,0x6122,0x6222,0x6326,0x6422,0x6526,0x6626,0x6722,0x682a,0x692e, + 0x6a3e,0x6b3a,0x6c3e,0x6d3a,0x6e3a,0x6f3e,0x7022,0x7126,0x7226,0x7322,0x7426,0x7522,0x7622,0x7726,0x782e,0x792a, + 0x7a3a,0x7b3e,0x7c3a,0x7d3e,0x7e3e,0x7f3a,0x8082,0x8186,0x8286,0x8382,0x8486,0x8582,0x8682,0x8786,0x888e,0x898a, + 0x8a9a,0x8b9e,0x8c9a,0x8d9e,0x8e9e,0x8f9a,0x9086,0x9182,0x9282,0x9386,0x3423,0x3527,0x3627,0x3723,0x382b,0x392f, + 0x3a3f,0x3b3b,0x3c3f,0x3d3b,0x3e3b,0x3f3f,0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480f,0x490b, + 0x4a1b,0x4b1f,0x4c1b,0x4d1f,0x4e1f,0x4f1b,0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580b,0x590f, + 0x5a1f,0x5b1b,0x5c1f,0x5d1b,0x5e1b,0x5f1f,0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682b,0x692f, + 0x6a3f,0x6b3b,0x6c3f,0x6d3b,0x6e3b,0x6f3f,0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782f,0x792b, + 0x7a3b,0x7b3f,0x7c3b,0x7d3f,0x7e3f,0x7f3b,0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888f,0x898b, + 0x8a9b,0x8b9f,0x8c9b,0x8d9f,0x8e9f,0x8f9b,0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988b,0x998f, + 0x9a9f,0x9b9b,0x9c9f,0x9d9b,0x9e9b,0x9f9f,0xa0a7,0xa1a3,0xa2a3,0xa3a7,0xa4a3,0xa5a7,0xa6a7,0xa7a3,0xa8ab,0xa9af, + 0xaabf,0xabbb,0xacbf,0xadbb,0xaebb,0xafbf,0xb0a3,0xb1a7,0xb2a7,0xb3a3,0xb4a7,0xb5a3,0xb6a3,0xb7a7,0xb8af,0xb9ab, + 0xbabb,0xbbbf,0xbcbb,0xbdbf,0xbebf,0xbfbb,0xc087,0xc183,0xc283,0xc387,0xc483,0xc587,0xc687,0xc783,0xc88b,0xc98f, + 0xca9f,0xcb9b,0xcc9f,0xcd9b,0xce9b,0xcf9f,0xd083,0xd187,0xd287,0xd383,0xd487,0xd583,0xd683,0xd787,0xd88f,0xd98b, + 0xda9b,0xdb9f,0xdc9b,0xdd9f,0xde9f,0xdf9b,0xe0a3,0xe1a7,0xe2a7,0xe3a3,0xe4a7,0xe5a3,0xe6a3,0xe7a7,0xe8af,0xe9ab, + 0xeabb,0xebbf,0xecbb,0xedbf,0xeebf,0xefbb,0xf0a7,0xf1a3,0xf2a3,0xf3a7,0xf4a3,0xf5a7,0xf6a7,0xf7a3,0xf8ab,0xf9af, + 0xfabf,0xfbbb,0xfcbf,0xfdbb,0xfebb,0xffbf,0x0047,0x0103,0x0203,0x0307,0x0403,0x0507,0x0607,0x0703,0x080b,0x090f, + 0x0a1f,0x0b1b,0x0c1f,0x0d1b,0x0e1b,0x0f1f,0x1003,0x1107,0x1207,0x1303,0x1407,0x1503,0x1603,0x1707,0x180f,0x190b, + 0x1a1b,0x1b1f,0x1c1b,0x1d1f,0x1e1f,0x1f1b,0x2023,0x2127,0x2227,0x2323,0x2427,0x2523,0x2623,0x2727,0x282f,0x292b, + 0x2a3b,0x2b3f,0x2c3b,0x2d3f,0x2e3f,0x2f3b,0x3027,0x3123,0x3223,0x3327,0x3423,0x3527,0x3627,0x3723,0x382b,0x392f, + 0x3a3f,0x3b3b,0x3c3f,0x3d3b,0x3e3b,0x3f3f,0x4003,0x4107,0x4207,0x4303,0x4407,0x4503,0x4603,0x4707,0x480f,0x490b, + 0x4a1b,0x4b1f,0x4c1b,0x4d1f,0x4e1f,0x4f1b,0x5007,0x5103,0x5203,0x5307,0x5403,0x5507,0x5607,0x5703,0x580b,0x590f, + 0x5a1f,0x5b1b,0x5c1f,0x5d1b,0x5e1b,0x5f1f,0x6027,0x6123,0x6223,0x6327,0x6423,0x6527,0x6627,0x6723,0x682b,0x692f, + 0x6a3f,0x6b3b,0x6c3f,0x6d3b,0x6e3b,0x6f3f,0x7023,0x7127,0x7227,0x7323,0x7427,0x7523,0x7623,0x7727,0x782f,0x792b, + 0x7a3b,0x7b3f,0x7c3b,0x7d3f,0x7e3f,0x7f3b,0x8083,0x8187,0x8287,0x8383,0x8487,0x8583,0x8683,0x8787,0x888f,0x898b, + 0x8a9b,0x8b9f,0x8c9b,0x8d9f,0x8e9f,0x8f9b,0x9087,0x9183,0x9283,0x9387,0x9483,0x9587,0x9687,0x9783,0x988b,0x998f +}; + +inline UINT8 I8080_RM8(i8086_state *cpustate, UINT16 a) +{ + return read_mem_byte(cpustate, (cpustate->base[DS] + a) & AMASK); +} + +inline void I8080_WM8(i8086_state *cpustate, UINT16 a, UINT8 v) +{ + write_mem_byte(cpustate, (cpustate->base[DS] + a) & AMASK, v); +} + +inline UINT16 I8080_RM16(i8086_state *cpustate, UINT16 a) +{ + return read_mem_word(cpustate, (cpustate->base[DS] + a) & AMASK); +} + +inline void I8080_WM16(i8086_state *cpustate, UINT16 a, UINT16 v) +{ + write_mem_word(cpustate, (cpustate->base[DS] + a) & AMASK, v); +} + +inline void I8080_PUSH(i8086_state *cpustate, UINT16 v) +{ + cpustate->regs.w[BP] -= 2; + write_mem_word(cpustate, (cpustate->base[DS] + cpustate->regs.w[BP]) & AMASK, v); +} + +inline UINT16 I8080_POP(i8086_state *cpustate) +{ + UINT16 bp = cpustate->regs.w[BP]; + cpustate->regs.w[BP] += 2; + return read_mem_word(cpustate, (cpustate->base[DS] + bp) & AMASK); +} + +inline UINT8 I8080_FETCH8(i8086_state *cpustate) +{ + UINT8 var = read_mem_byte(cpustate, cpustate->pc & AMASK); + UINT16 ip = cpustate->pc - cpustate->base[CS]; + ip += 1; + cpustate->pc = cpustate->base[CS] + ip; + return var; +} + +inline UINT16 I8080_FETCH16(i8086_state *cpustate) +{ + UINT16 var = read_mem_word(cpustate, cpustate->pc & AMASK); + UINT16 ip = cpustate->pc - cpustate->base[CS]; + ip += 2; + cpustate->pc = cpustate->base[CS] + ip; + return var; +} + +inline UINT8 I8080_IN8(i8086_state *cpustate, UINT16 a) +{ + return cpustate->io->read_io8(a); +} + +inline void I8080_OUT8(i8086_state *cpustate, UINT16 a, UINT8 v) +{ + cpustate->io->write_io8(a, v); +} + +#define I8080_INR(v) { \ + UINT8 hc = ((v & 0x0f) == 0x0f) ? I8080_HF : 0; \ + ++v; \ + I8080_F = (I8080_F & I8080_CF) | I8080_ZSP[v] | hc; \ +} +#define I8080_DCR(v) { \ + UINT8 hc = ((v & 0x0f) == 0x00) ? I8080_HF : 0; \ + --v; \ + I8080_F = (I8080_F & I8080_CF) | I8080_ZSP[v] | hc | I8080_NF; \ +} +#define I8080_MVI(v) { \ + v = I8080_FETCH8(cpustate); \ +} +#define I8080_ANA(v) { \ + int i = (((I8080_A | v) >> 3) & 1) * I8080_HF; \ + I8080_A &= v; \ + I8080_F = I8080_ZSP[I8080_A]; \ + I8080_F |= i; \ +} +#define I8080_ORA(v) { \ + I8080_A |= v; \ + I8080_F = I8080_ZSP[I8080_A]; \ +} +#define I8080_XRA(v) { \ + I8080_A ^= v; \ + I8080_F = I8080_ZSP[I8080_A]; \ +} +#define I8080_RLC() { \ + I8080_A = (I8080_A << 1) | (I8080_A >> 7); \ + I8080_F = (I8080_F & 0xfe) | (I8080_A & I8080_CF); \ +} +#define I8080_RRC() { \ + I8080_F = (I8080_F & 0xfe) | (I8080_A & I8080_CF); \ + I8080_A = (I8080_A >> 1) | (I8080_A << 7); \ +} +#define I8080_RAL() { \ + int c = I8080_F & I8080_CF; \ + I8080_F = (I8080_F & 0xfe) | (I8080_A >> 7); \ + I8080_A = (I8080_A << 1) | c; \ +} +#define i8080_RAR() { \ + int c = (I8080_F & I8080_CF) << 7; \ + I8080_F = (I8080_F & 0xfe) | (I8080_A & I8080_CF); \ + I8080_A = (I8080_A >> 1) | c; \ +} +#define i8080_ADD(v) { \ + int q = I8080_A + v; \ + I8080_F = I8080_ZSP[q & 255] | ((q >> 8) & I8080_CF) | ((I8080_A ^ q ^ v) & I8080_HF) | (((v ^ I8080_A ^ I8080_SF) & (v ^ q) & I8080_SF) >> 5); \ + I8080_A = q; \ +} +#define I8080_ADC(v) {\ + int q = I8080_A + v + (I8080_F & I8080_CF); \ + I8080_F = I8080_ZSP[q & 255] | ((q >> 8) & I8080_CF) | ((I8080_A ^ q ^ v) & I8080_HF) | (((v ^ I8080_A ^ I8080_SF) & (v ^ q) & I8080_SF) >> 5); \ + I8080_A = q; \ +} +#define I8080_SUB(v) { \ + int q = I8080_A - v; \ + I8080_F = I8080_ZSP[q & 255] | ((q >> 8) & I8080_CF) | I8080_NF | ((I8080_A ^ q ^ v) & I8080_HF) | (((v ^ I8080_A) & (I8080_A ^ q) & I8080_SF) >> 5); \ + I8080_A = q; \ +} +#define I8080_SBB(v) { \ + int q = I8080_A - v - (I8080_F & I8080_CF); \ + I8080_F = I8080_ZSP[q & 255] | ((q >> 8) & I8080_CF) | I8080_NF | ((I8080_A ^ q ^ v) & I8080_HF) | (((v ^ I8080_A) & (I8080_A ^ q) & I8080_SF) >> 5); \ + I8080_A = q; \ +} +#define I8080_CMP(v) { \ + int q = I8080_A - v; \ + I8080_F = I8080_ZSP[q & 255] | ((q >> 8) & I8080_CF) | I8080_NF | ((I8080_A ^ q ^ v) & I8080_HF) | (((v ^ I8080_A) & (I8080_A ^ q) & I8080_SF) >> 5); \ +} +#define I8080_DAD(v) { \ + int q = I8080_HL + v; \ + I8080_F = (I8080_F & ~(I8080_HF + I8080_CF)) | (((I8080_HL ^ q ^ v) >> 8) & I8080_HF) | ((q >> 16) & I8080_CF); \ + I8080_HL = q; \ +} +#define I8080_RET(c) { \ + if(c) { \ + ICOUNT -= 6; \ + cpustate->pc = cpustate->base[CS] + I8080_POP(cpustate); \ + } \ +} +#define I8080_JMP(c) { \ + UINT16 a = I8080_FETCH16(cpustate); \ + if(c) { \ + cpustate->pc = cpustate->base[CS] + a; \ + } \ +} +#define I8080_CALL(c) { \ + UINT16 a = I8080_FETCH16(cpustate); \ + if(c) { \ + UINT16 ip = cpustate->pc - cpustate->base[CS]; \ + ICOUNT -= 6; \ + I8080_PUSH(cpustate, ip); \ + cpustate->pc = cpustate->base[CS] + a; \ + } \ +} +#define RST(n) { \ + UINT16 ip = cpustate->pc - cpustate->base[CS]; \ + I8080_PUSH(cpustate, ip); \ + cpustate->pc = cpustate->base[CS] + 8 * n; \ +} + +static void PREFIX80(_00h)(i8086_state *cpustate) +{ + // NOP + ICOUNT -= I8080_CLK[0x00]; +} + +static void PREFIX80(_01h)(i8086_state *cpustate) +{ + // LXI B,nnnn + I8080_BC = I8080_FETCH16(cpustate); + ICOUNT -= I8080_CLK[0x01]; +} + +static void PREFIX80(_02h)(i8086_state *cpustate) +{ + // STAX B + I8080_WM8(cpustate, I8080_BC, I8080_A); + ICOUNT -= I8080_CLK[0x02]; +} + +static void PREFIX80(_03h)(i8086_state *cpustate) +{ + // INX B + I8080_BC++; + ICOUNT -= I8080_CLK[0x03]; +} + +static void PREFIX80(_04h)(i8086_state *cpustate) +{ + // INR B + I8080_INR(I8080_B); + ICOUNT -= I8080_CLK[0x04]; +} + +static void PREFIX80(_05h)(i8086_state *cpustate) +{ + // DCR B + I8080_DCR(I8080_B); + ICOUNT -= I8080_CLK[0x05]; +} + +static void PREFIX80(_06h)(i8086_state *cpustate) +{ + // MVI B,nn + I8080_MVI(I8080_B); + ICOUNT -= I8080_CLK[0x06]; +} + +static void PREFIX80(_07h)(i8086_state *cpustate) +{ + // RLC + I8080_RLC(); + ICOUNT -= I8080_CLK[0x07]; +} + +static void PREFIX80(_08h)(i8086_state *cpustate) +{ + // NOP + ICOUNT -= I8080_CLK[0x08]; +} + +static void PREFIX80(_09h)(i8086_state *cpustate) +{ + // DAD B + I8080_DAD(I8080_BC); + ICOUNT -= I8080_CLK[0x09]; +} + +static void PREFIX80(_0ah)(i8086_state *cpustate) +{ + // LDAX B + I8080_A = I8080_RM8(cpustate, I8080_BC); + ICOUNT -= I8080_CLK[0x0a]; +} + +static void PREFIX80(_0bh)(i8086_state *cpustate) +{ + // DCX B + I8080_BC--; + ICOUNT -= I8080_CLK[0x0b]; +} + +static void PREFIX80(_0ch)(i8086_state *cpustate) +{ + // INR C + I8080_INR(I8080_C); + ICOUNT -= I8080_CLK[0x0c]; +} + +static void PREFIX80(_0dh)(i8086_state *cpustate) +{ + // DCR C + I8080_DCR(I8080_C); + ICOUNT -= I8080_CLK[0x0d]; +} + +static void PREFIX80(_0eh)(i8086_state *cpustate) +{ + // MVI C,nn + I8080_MVI(I8080_C); + ICOUNT -= I8080_CLK[0x0e]; +} + +static void PREFIX80(_0fh)(i8086_state *cpustate) +{ + // RRC + I8080_RRC(); + ICOUNT -= I8080_CLK[0x0f]; +} + +static void PREFIX80(_10h)(i8086_state *cpustate) +{ + // NOP + ICOUNT -= I8080_CLK[0x10]; +} + +static void PREFIX80(_11h)(i8086_state *cpustate) +{ + // LXI D,nnnn + I8080_DE = I8080_FETCH16(cpustate); + ICOUNT -= I8080_CLK[0x11]; +} + +static void PREFIX80(_12h)(i8086_state *cpustate) +{ + // STAX D + I8080_WM8(cpustate, I8080_DE, I8080_A); + ICOUNT -= I8080_CLK[0x12]; +} + +static void PREFIX80(_13h)(i8086_state *cpustate) +{ + // INX D + I8080_DE++; + ICOUNT -= I8080_CLK[0x13]; +} + +static void PREFIX80(_14h)(i8086_state *cpustate) +{ + // INR D + I8080_INR(I8080_D); + ICOUNT -= I8080_CLK[0x14]; +} + +static void PREFIX80(_15h)(i8086_state *cpustate) +{ + // DCR D + I8080_DCR(I8080_D); + ICOUNT -= I8080_CLK[0x15]; +} + +static void PREFIX80(_16h)(i8086_state *cpustate) +{ + // MVI D,nn + I8080_MVI(I8080_D); + ICOUNT -= I8080_CLK[0x16]; +} + +static void PREFIX80(_17h)(i8086_state *cpustate) +{ + // RAL + I8080_RAL(); + ICOUNT -= I8080_CLK[0x17]; +} + +static void PREFIX80(_18h)(i8086_state *cpustate) +{ + // NOP + ICOUNT -= I8080_CLK[0x18]; +} + +static void PREFIX80(_19h)(i8086_state *cpustate) +{ + // DAD D + I8080_DAD(I8080_DE); + ICOUNT -= I8080_CLK[0x19]; +} + +static void PREFIX80(_1ah)(i8086_state *cpustate) +{ + // LDAX D + I8080_A = I8080_RM8(cpustate, I8080_DE); + ICOUNT -= I8080_CLK[0x1a]; +} + +static void PREFIX80(_1bh)(i8086_state *cpustate) +{ + // DCX D + I8080_DE--; + ICOUNT -= I8080_CLK[0x1b]; +} + +static void PREFIX80(_1ch)(i8086_state *cpustate) +{ + // INR E + I8080_INR(I8080_E); + ICOUNT -= I8080_CLK[0x1c]; +} + +static void PREFIX80(_1dh)(i8086_state *cpustate) +{ + // DCR E + I8080_DCR(I8080_E); + ICOUNT -= I8080_CLK[0x1d]; +} + +static void PREFIX80(_1eh)(i8086_state *cpustate) +{ + // MVI E,nn + I8080_MVI(I8080_E); + ICOUNT -= I8080_CLK[0x1e]; +} + +static void PREFIX80(_1fh)(i8086_state *cpustate) +{ + // RAR + i8080_RAR(); + ICOUNT -= I8080_CLK[0x1f]; +} + +static void PREFIX80(_20h)(i8086_state *cpustate) +{ + // NOP + ICOUNT -= I8080_CLK[0x20]; +} + +static void PREFIX80(_21h)(i8086_state *cpustate) +{ + // LXI H,nnnn + I8080_HL = I8080_FETCH16(cpustate); + ICOUNT -= I8080_CLK[0x21]; +} + +static void PREFIX80(_22h)(i8086_state *cpustate) +{ + // SHLD nnnn + I8080_WM16(cpustate, I8080_FETCH16(cpustate), I8080_HL); + ICOUNT -= I8080_CLK[0x22]; +} + +static void PREFIX80(_23h)(i8086_state *cpustate) +{ + // INX H + I8080_HL++; + ICOUNT -= I8080_CLK[0x23]; +} + +static void PREFIX80(_24h)(i8086_state *cpustate) +{ + // INR H + I8080_INR(I8080_H); + ICOUNT -= I8080_CLK[0x24]; +} + +static void PREFIX80(_25h)(i8086_state *cpustate) +{ + // DCR H + I8080_DCR(I8080_H); + ICOUNT -= I8080_CLK[0x25]; +} + +static void PREFIX80(_26h)(i8086_state *cpustate) +{ + // MVI H,nn + I8080_MVI(I8080_H); + ICOUNT -= I8080_CLK[0x26]; +} + +static void PREFIX80(_27h)(i8086_state *cpustate) +{ + // DAA + UINT16 tmp16 = I8080_A; + if(I8080_F & I8080_CF) tmp16 |= 0x100; + if(I8080_F & I8080_HF) tmp16 |= 0x200; + if(I8080_F & I8080_NF) tmp16 |= 0x400; + I8080_AF = I8080_DAA[tmp16]; + I8080_F &= 0xd5; + ICOUNT -= I8080_CLK[0x27]; +} + +static void PREFIX80(_28h)(i8086_state *cpustate) +{ + // NOP + ICOUNT -= I8080_CLK[0x28]; +} + +static void PREFIX80(_29h)(i8086_state *cpustate) +{ + // DAD H + I8080_DAD(I8080_HL); + ICOUNT -= I8080_CLK[0x29]; +} + +static void PREFIX80(_2ah)(i8086_state *cpustate) +{ + // LHLD nnnn + I8080_HL = I8080_RM16(cpustate, I8080_FETCH16(cpustate)); + ICOUNT -= I8080_CLK[0x2a]; +} + +static void PREFIX80(_2bh)(i8086_state *cpustate) +{ + // DCX H + I8080_HL--; + ICOUNT -= I8080_CLK[0x2b]; +} + +static void PREFIX80(_2ch)(i8086_state *cpustate) +{ + // INR L + I8080_INR(I8080_L); + ICOUNT -= I8080_CLK[0x2c]; +} + +static void PREFIX80(_2dh)(i8086_state *cpustate) +{ + // DCR L + I8080_DCR(I8080_L); + ICOUNT -= I8080_CLK[0x2d]; +} + +static void PREFIX80(_2eh)(i8086_state *cpustate) +{ + // MVI L,nn + I8080_MVI(I8080_L); + ICOUNT -= I8080_CLK[0x2e]; +} + +static void PREFIX80(_2fh)(i8086_state *cpustate) +{ + // CMA + I8080_A ^= 0xff; + ICOUNT -= I8080_CLK[0x2f]; +} + +static void PREFIX80(_30h)(i8086_state *cpustate) +{ + // NOP + ICOUNT -= I8080_CLK[0x30]; +} + +static void PREFIX80(_31h)(i8086_state *cpustate) +{ + // LXI SP,nnnn + I8080_SP = I8080_FETCH16(cpustate); + ICOUNT -= I8080_CLK[0x31]; +} + +static void PREFIX80(_32h)(i8086_state *cpustate) +{ + // STA nnnn + I8080_WM8(cpustate, I8080_FETCH16(cpustate), I8080_A); + ICOUNT -= I8080_CLK[0x32]; +} + +static void PREFIX80(_33h)(i8086_state *cpustate) +{ + // INX SP + I8080_SP++; + ICOUNT -= I8080_CLK[0x33]; +} + +static void PREFIX80(_34h)(i8086_state *cpustate) +{ + // INR M + UINT8 tmp8 = I8080_RM8(cpustate, I8080_HL); + I8080_INR(tmp8); + I8080_WM8(cpustate, I8080_HL, tmp8); + ICOUNT -= I8080_CLK[0x34]; +} + +static void PREFIX80(_35h)(i8086_state *cpustate) +{ + // DCR M + UINT8 tmp8 = I8080_RM8(cpustate, I8080_HL); + I8080_DCR(tmp8); + I8080_WM8(cpustate, I8080_HL, tmp8); + ICOUNT -= I8080_CLK[0x35]; +} + +static void PREFIX80(_36h)(i8086_state *cpustate) +{ + // MVI M,nn + I8080_WM8(cpustate, I8080_HL, I8080_FETCH8(cpustate)); + ICOUNT -= I8080_CLK[0x36]; +} + +static void PREFIX80(_37h)(i8086_state *cpustate) +{ + // STC + I8080_F = (I8080_F & 0xfe) | I8080_CF; + ICOUNT -= I8080_CLK[0x37]; +} + +static void PREFIX80(_38h)(i8086_state *cpustate) +{ + // LDES nn (NOP) + ICOUNT -= I8080_CLK[0x38]; +} + +static void PREFIX80(_39h)(i8086_state *cpustate) +{ + // DAD SP + I8080_DAD(I8080_SP); + ICOUNT -= I8080_CLK[0x39]; +} + +static void PREFIX80(_3ah)(i8086_state *cpustate) +{ + // LDA nnnn + I8080_A = I8080_RM8(cpustate, I8080_FETCH16(cpustate)); + ICOUNT -= I8080_CLK[0x3a]; +} + +static void PREFIX80(_3bh)(i8086_state *cpustate) +{ + // DCX SP + I8080_SP--; + ICOUNT -= I8080_CLK[0x3b]; +} + +static void PREFIX80(_3ch)(i8086_state *cpustate) +{ + // INR A + I8080_INR(I8080_A); + ICOUNT -= I8080_CLK[0x3c]; +} + +static void PREFIX80(_3dh)(i8086_state *cpustate) +{ + // DCR A + I8080_DCR(I8080_A); + ICOUNT -= I8080_CLK[0x3d]; +} + +static void PREFIX80(_3eh)(i8086_state *cpustate) +{ + // MVI A,nn + I8080_MVI(I8080_A); + ICOUNT -= I8080_CLK[0x3e]; +} + +static void PREFIX80(_3fh)(i8086_state *cpustate) +{ + // CMC + I8080_F ^= I8080_CF; + ICOUNT -= I8080_CLK[0x3f]; +} + +static void PREFIX80(_40h)(i8086_state *cpustate) +{ + // MOV B,B + ICOUNT -= I8080_CLK[0x40]; +} + +static void PREFIX80(_41h)(i8086_state *cpustate) +{ + // MOV B,C + I8080_B = I8080_C; + ICOUNT -= I8080_CLK[0x41]; +} + +static void PREFIX80(_42h)(i8086_state *cpustate) +{ + // MOV B,D + I8080_B = I8080_D; + ICOUNT -= I8080_CLK[0x42]; +} + +static void PREFIX80(_43h)(i8086_state *cpustate) +{ + // MOV B,E + I8080_B = I8080_E; + ICOUNT -= I8080_CLK[0x43]; +} + +static void PREFIX80(_44h)(i8086_state *cpustate) +{ + // MOV B,H + I8080_B = I8080_H; + ICOUNT -= I8080_CLK[0x44]; +} + +static void PREFIX80(_45h)(i8086_state *cpustate) +{ + // MOV B,L + I8080_B = I8080_L; + ICOUNT -= I8080_CLK[0x45]; +} + +static void PREFIX80(_46h)(i8086_state *cpustate) +{ + // MOV B,M + I8080_B = I8080_RM8(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0x46]; +} + +static void PREFIX80(_47h)(i8086_state *cpustate) +{ + // MOV B,A + I8080_B = I8080_A; + ICOUNT -= I8080_CLK[0x47]; +} + +static void PREFIX80(_48h)(i8086_state *cpustate) +{ + // MOV C,B + I8080_C = I8080_B; + ICOUNT -= I8080_CLK[0x48]; +} + +static void PREFIX80(_49h)(i8086_state *cpustate) +{ + // MOV C,C + ICOUNT -= I8080_CLK[0x49]; +} + +static void PREFIX80(_4ah)(i8086_state *cpustate) +{ + // MOV C,D + I8080_C = I8080_D; + ICOUNT -= I8080_CLK[0x4a]; +} + +static void PREFIX80(_4bh)(i8086_state *cpustate) +{ + // MOV C,E + I8080_C = I8080_E; + ICOUNT -= I8080_CLK[0x4b]; +} + +static void PREFIX80(_4ch)(i8086_state *cpustate) +{ + // MOV C,H + I8080_C = I8080_H; + ICOUNT -= I8080_CLK[0x4c]; +} + +static void PREFIX80(_4dh)(i8086_state *cpustate) +{ + // MOV C,L + I8080_C = I8080_L; + ICOUNT -= I8080_CLK[0x4d]; +} + +static void PREFIX80(_4eh)(i8086_state *cpustate) +{ + // MOV C,M + I8080_C = I8080_RM8(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0x4e]; +} + +static void PREFIX80(_4fh)(i8086_state *cpustate) +{ + // MOV C,A + I8080_C = I8080_A; + ICOUNT -= I8080_CLK[0x4f]; +} + +static void PREFIX80(_50h)(i8086_state *cpustate) +{ + // MOV D,B + I8080_D = I8080_B; + ICOUNT -= I8080_CLK[0x50]; +} + +static void PREFIX80(_51h)(i8086_state *cpustate) +{ + // MOV D,C + I8080_D = I8080_C; + ICOUNT -= I8080_CLK[0x51]; +} + +static void PREFIX80(_52h)(i8086_state *cpustate) +{ + // MOV D,D + ICOUNT -= I8080_CLK[0x52]; +} + +static void PREFIX80(_53h)(i8086_state *cpustate) +{ + // MOV D,E + I8080_D = I8080_E; + ICOUNT -= I8080_CLK[0x53]; +} + +static void PREFIX80(_54h)(i8086_state *cpustate) +{ + // MOV D,H + I8080_D = I8080_H; + ICOUNT -= I8080_CLK[0x54]; +} + +static void PREFIX80(_55h)(i8086_state *cpustate) +{ + // MOV D,L + I8080_D = I8080_L; + ICOUNT -= I8080_CLK[0x55]; +} + +static void PREFIX80(_56h)(i8086_state *cpustate) +{ + // MOV D,M + I8080_D = I8080_RM8(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0x56]; +} + +static void PREFIX80(_57h)(i8086_state *cpustate) +{ + // MOV D,A + I8080_D = I8080_A; + ICOUNT -= I8080_CLK[0x57]; +} + +static void PREFIX80(_58h)(i8086_state *cpustate) +{ + // MOV E,B + I8080_E = I8080_B; + ICOUNT -= I8080_CLK[0x58]; +} + +static void PREFIX80(_59h)(i8086_state *cpustate) +{ + // MOV E,C + I8080_E = I8080_C; + ICOUNT -= I8080_CLK[0x59]; +} + +static void PREFIX80(_5ah)(i8086_state *cpustate) +{ + // MOV E,D + I8080_E = I8080_D; + ICOUNT -= I8080_CLK[0x5a]; +} + +static void PREFIX80(_5bh)(i8086_state *cpustate) +{ + // MOV E,E + ICOUNT -= I8080_CLK[0x5b]; +} + +static void PREFIX80(_5ch)(i8086_state *cpustate) +{ + // MOV E,H + I8080_E = I8080_H; + ICOUNT -= I8080_CLK[0x5c]; +} + +static void PREFIX80(_5dh)(i8086_state *cpustate) +{ + // MOV E,L + I8080_E = I8080_L; + ICOUNT -= I8080_CLK[0x5d]; +} + +static void PREFIX80(_5eh)(i8086_state *cpustate) +{ + // MOV E,M + I8080_E = I8080_RM8(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0x5e]; +} + +static void PREFIX80(_5fh)(i8086_state *cpustate) +{ + // MOV E,A + I8080_E = I8080_A; + ICOUNT -= I8080_CLK[0x5f]; +} + +static void PREFIX80(_60h)(i8086_state *cpustate) +{ + // MOV H,B + I8080_H = I8080_B; + ICOUNT -= I8080_CLK[0x60]; +} + +static void PREFIX80(_61h)(i8086_state *cpustate) +{ + // MOV H,C + I8080_H = I8080_C; + ICOUNT -= I8080_CLK[0x61]; +} + +static void PREFIX80(_62h)(i8086_state *cpustate) +{ + // MOV H,D + I8080_H = I8080_D; + ICOUNT -= I8080_CLK[0x62]; +} + +static void PREFIX80(_63h)(i8086_state *cpustate) +{ + // MOV H,E + I8080_H = I8080_E; + ICOUNT -= I8080_CLK[0x63]; +} + +static void PREFIX80(_64h)(i8086_state *cpustate) +{ + // MOV H,H + ICOUNT -= I8080_CLK[0x64]; +} + +static void PREFIX80(_65h)(i8086_state *cpustate) +{ + // MOV H,L + I8080_H = I8080_L; + ICOUNT -= I8080_CLK[0x65]; +} + +static void PREFIX80(_66h)(i8086_state *cpustate) +{ + // MOV H,M + I8080_H = I8080_RM8(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0x66]; +} + +static void PREFIX80(_67h)(i8086_state *cpustate) +{ + // MOV H,A + I8080_H = I8080_A; + ICOUNT -= I8080_CLK[0x67]; +} + +static void PREFIX80(_68h)(i8086_state *cpustate) +{ + // MOV L,B + I8080_L = I8080_B; + ICOUNT -= I8080_CLK[0x68]; +} + +static void PREFIX80(_69h)(i8086_state *cpustate) +{ + // MOV L,C + I8080_L = I8080_C; + ICOUNT -= I8080_CLK[0x69]; +} + +static void PREFIX80(_6ah)(i8086_state *cpustate) +{ + // MOV L,D + I8080_L = I8080_D; + ICOUNT -= I8080_CLK[0x6a]; +} + +static void PREFIX80(_6bh)(i8086_state *cpustate) +{ + // MOV L,E + I8080_L = I8080_E; + ICOUNT -= I8080_CLK[0x6b]; +} + +static void PREFIX80(_6ch)(i8086_state *cpustate) +{ + // MOV L,H + I8080_L = I8080_H; + ICOUNT -= I8080_CLK[0x6c]; +} + +static void PREFIX80(_6dh)(i8086_state *cpustate) +{ + // MOV L,L + ICOUNT -= I8080_CLK[0x6d]; +} + +static void PREFIX80(_6eh)(i8086_state *cpustate) +{ + // MOV L,M + I8080_L = I8080_RM8(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0x6e]; +} + +static void PREFIX80(_6fh)(i8086_state *cpustate) +{ + // MOV L,A + I8080_L = I8080_A; + ICOUNT -= I8080_CLK[0x6f]; +} + +static void PREFIX80(_70h)(i8086_state *cpustate) +{ + // MOV M,B + I8080_WM8(cpustate, I8080_HL, I8080_B); + ICOUNT -= I8080_CLK[0x70]; +} + +static void PREFIX80(_71h)(i8086_state *cpustate) +{ + // MOV M,C + I8080_WM8(cpustate, I8080_HL, I8080_C); + ICOUNT -= I8080_CLK[0x71]; +} + +static void PREFIX80(_72h)(i8086_state *cpustate) +{ + // MOV M,D + I8080_WM8(cpustate, I8080_HL, I8080_D); + ICOUNT -= I8080_CLK[0x72]; +} + +static void PREFIX80(_73h)(i8086_state *cpustate) +{ + // MOV M,E + I8080_WM8(cpustate, I8080_HL, I8080_E); + ICOUNT -= I8080_CLK[0x73]; +} + +static void PREFIX80(_74h)(i8086_state *cpustate) +{ + // MOV M,H + I8080_WM8(cpustate, I8080_HL, I8080_H); + ICOUNT -= I8080_CLK[0x74]; +} + +static void PREFIX80(_75h)(i8086_state *cpustate) +{ + // MOV M,L + I8080_WM8(cpustate, I8080_HL, I8080_L); + ICOUNT -= I8080_CLK[0x75]; +} + +static void PREFIX80(_76h)(i8086_state *cpustate) +{ + // HLT +// PREFIX86(_hlt)(cpustate); + ICOUNT -= I8080_CLK[0x76]; +} + +static void PREFIX80(_77h)(i8086_state *cpustate) +{ + // MOV M,A + I8080_WM8(cpustate, I8080_HL, I8080_A); + ICOUNT -= I8080_CLK[0x77]; +} + +static void PREFIX80(_78h)(i8086_state *cpustate) +{ + // MOV A,B + I8080_A = I8080_B; + ICOUNT -= I8080_CLK[0x78]; +} + +static void PREFIX80(_79h)(i8086_state *cpustate) +{ + // MOV A,C + I8080_A = I8080_C; + ICOUNT -= I8080_CLK[0x79]; +} + +static void PREFIX80(_7ah)(i8086_state *cpustate) +{ + // MOV A,D + I8080_A = I8080_D; + ICOUNT -= I8080_CLK[0x7a]; +} + +static void PREFIX80(_7bh)(i8086_state *cpustate) +{ + // MOV A,E + I8080_A = I8080_E; + ICOUNT -= I8080_CLK[0x7b]; +} + +static void PREFIX80(_7ch)(i8086_state *cpustate) +{ + // MOV A,H + I8080_A = I8080_H; + ICOUNT -= I8080_CLK[0x7c]; +} + +static void PREFIX80(_7dh)(i8086_state *cpustate) +{ + // MOV A,L + I8080_A = I8080_L; + ICOUNT -= I8080_CLK[0x7d]; +} + +static void PREFIX80(_7eh)(i8086_state *cpustate) +{ + // MOV A,M + I8080_A = I8080_RM8(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0x7e]; +} + +static void PREFIX80(_7fh)(i8086_state *cpustate) +{ + // MOV A,A + ICOUNT -= I8080_CLK[0x7f]; +} + +static void PREFIX80(_80h)(i8086_state *cpustate) +{ + // ADD B + i8080_ADD(I8080_B); + ICOUNT -= I8080_CLK[0x80]; +} + +static void PREFIX80(_81h)(i8086_state *cpustate) +{ + // ADD C + i8080_ADD(I8080_C); + ICOUNT -= I8080_CLK[0x81]; +} + +static void PREFIX80(_82h)(i8086_state *cpustate) +{ + // ADD D + i8080_ADD(I8080_D); + ICOUNT -= I8080_CLK[0x82]; +} + +static void PREFIX80(_83h)(i8086_state *cpustate) +{ + // ADD E + i8080_ADD(I8080_E); + ICOUNT -= I8080_CLK[0x83]; +} + +static void PREFIX80(_84h)(i8086_state *cpustate) +{ + // ADD H + i8080_ADD(I8080_H); + ICOUNT -= I8080_CLK[0x84]; +} + +static void PREFIX80(_85h)(i8086_state *cpustate) +{ + // ADD L + i8080_ADD(I8080_L); + ICOUNT -= I8080_CLK[0x85]; +} + +static void PREFIX80(_86h)(i8086_state *cpustate) +{ + // ADD M + i8080_ADD(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0x86]; +} + +static void PREFIX80(_87h)(i8086_state *cpustate) +{ + // ADD A + i8080_ADD(I8080_A); + ICOUNT -= I8080_CLK[0x87]; +} + +static void PREFIX80(_88h)(i8086_state *cpustate) +{ + // ADC B + I8080_ADC(I8080_B); + ICOUNT -= I8080_CLK[0x88]; +} + +static void PREFIX80(_89h)(i8086_state *cpustate) +{ + // ADC C + I8080_ADC(I8080_C); + ICOUNT -= I8080_CLK[0x89]; +} + +static void PREFIX80(_8ah)(i8086_state *cpustate) +{ + // ADC D + I8080_ADC(I8080_D); + ICOUNT -= I8080_CLK[0x8a]; +} + +static void PREFIX80(_8bh)(i8086_state *cpustate) +{ + // ADC E + I8080_ADC(I8080_E); + ICOUNT -= I8080_CLK[0x8b]; +} + +static void PREFIX80(_8ch)(i8086_state *cpustate) +{ + // ADC H + I8080_ADC(I8080_H); + ICOUNT -= I8080_CLK[0x8c]; +} + +static void PREFIX80(_8dh)(i8086_state *cpustate) +{ + // ADC L + I8080_ADC(I8080_L); + ICOUNT -= I8080_CLK[0x8d]; +} + +static void PREFIX80(_8eh)(i8086_state *cpustate) +{ + // ADC M + I8080_ADC(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0x8e]; +} + +static void PREFIX80(_8fh)(i8086_state *cpustate) +{ + // ADC A + I8080_ADC(I8080_A); + ICOUNT -= I8080_CLK[0x8f]; +} + +static void PREFIX80(_90h)(i8086_state *cpustate) +{ + // SUB B + I8080_SUB(I8080_B); + ICOUNT -= I8080_CLK[0x90]; +} + +static void PREFIX80(_91h)(i8086_state *cpustate) +{ + // SUB C + I8080_SUB(I8080_C); + ICOUNT -= I8080_CLK[0x91]; +} + +static void PREFIX80(_92h)(i8086_state *cpustate) +{ + // SUB D + I8080_SUB(I8080_D); + ICOUNT -= I8080_CLK[0x92]; +} + +static void PREFIX80(_93h)(i8086_state *cpustate) +{ + // SUB E + I8080_SUB(I8080_E); + ICOUNT -= I8080_CLK[0x93]; +} + +static void PREFIX80(_94h)(i8086_state *cpustate) +{ + // SUB H + I8080_SUB(I8080_H); + ICOUNT -= I8080_CLK[0x94]; +} + +static void PREFIX80(_95h)(i8086_state *cpustate) +{ + // SUB L + I8080_SUB(I8080_L); + ICOUNT -= I8080_CLK[0x95]; +} + +static void PREFIX80(_96h)(i8086_state *cpustate) +{ + // SUB M + I8080_SUB(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0x96]; +} + +static void PREFIX80(_97h)(i8086_state *cpustate) +{ + // SUB A + I8080_SUB(I8080_A); + ICOUNT -= I8080_CLK[0x97]; +} + +static void PREFIX80(_98h)(i8086_state *cpustate) +{ + // SBB B + I8080_SBB(I8080_B); + ICOUNT -= I8080_CLK[0x98]; +} + +static void PREFIX80(_99h)(i8086_state *cpustate) +{ + // SBB C + I8080_SBB(I8080_C); + ICOUNT -= I8080_CLK[0x99]; +} + +static void PREFIX80(_9ah)(i8086_state *cpustate) +{ + // SBB D + I8080_SBB(I8080_D); + ICOUNT -= I8080_CLK[0x9a]; +} + +static void PREFIX80(_9bh)(i8086_state *cpustate) +{ + // SBB E + I8080_SBB(I8080_E); + ICOUNT -= I8080_CLK[0x9b]; +} + +static void PREFIX80(_9ch)(i8086_state *cpustate) +{ + // SBB H + I8080_SBB(I8080_H); + ICOUNT -= I8080_CLK[0x9c]; +} + +static void PREFIX80(_9dh)(i8086_state *cpustate) +{ + // SBB L + I8080_SBB(I8080_L); + ICOUNT -= I8080_CLK[0x9d]; +} + +static void PREFIX80(_9eh)(i8086_state *cpustate) +{ + // SBB M + I8080_SBB(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0x9e]; +} + +static void PREFIX80(_9fh)(i8086_state *cpustate) +{ + // SBB A + I8080_SBB(I8080_A); + ICOUNT -= I8080_CLK[0x9f]; +} + +static void PREFIX80(_a0h)(i8086_state *cpustate) +{ + // ANA B + I8080_ANA(I8080_B); + ICOUNT -= I8080_CLK[0xa0]; +} + +static void PREFIX80(_a1h)(i8086_state *cpustate) +{ + // ANA C + I8080_ANA(I8080_C); + ICOUNT -= I8080_CLK[0xa1]; +} + +static void PREFIX80(_a2h)(i8086_state *cpustate) +{ + // ANA D + I8080_ANA(I8080_D); + ICOUNT -= I8080_CLK[0xa2]; +} + +static void PREFIX80(_a3h)(i8086_state *cpustate) +{ + // ANA E + I8080_ANA(I8080_E); + ICOUNT -= I8080_CLK[0xa3]; +} + +static void PREFIX80(_a4h)(i8086_state *cpustate) +{ + // ANA H + I8080_ANA(I8080_H); + ICOUNT -= I8080_CLK[0xa4]; +} + +static void PREFIX80(_a5h)(i8086_state *cpustate) +{ + // ANA L + I8080_ANA(I8080_L); + ICOUNT -= I8080_CLK[0xa5]; +} + +static void PREFIX80(_a6h)(i8086_state *cpustate) +{ + // ANA M + I8080_ANA(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0xa6]; +} + +static void PREFIX80(_a7h)(i8086_state *cpustate) +{ + // ANA A + I8080_ANA(I8080_A); + ICOUNT -= I8080_CLK[0xa7]; +} + +static void PREFIX80(_a8h)(i8086_state *cpustate) +{ + // XRA B + I8080_XRA(I8080_B); + ICOUNT -= I8080_CLK[0xa8]; +} + +static void PREFIX80(_a9h)(i8086_state *cpustate) +{ + // XRA C + I8080_XRA(I8080_C); + ICOUNT -= I8080_CLK[0xa9]; +} + +static void PREFIX80(_aah)(i8086_state *cpustate) +{ + // XRA D + I8080_XRA(I8080_D); + ICOUNT -= I8080_CLK[0xaa]; +} + +static void PREFIX80(_abh)(i8086_state *cpustate) +{ + // XRA E + I8080_XRA(I8080_E); + ICOUNT -= I8080_CLK[0xab]; +} + +static void PREFIX80(_ach)(i8086_state *cpustate) +{ + // XRA H + I8080_XRA(I8080_H); + ICOUNT -= I8080_CLK[0xac]; +} + +static void PREFIX80(_adh)(i8086_state *cpustate) +{ + // XRA L + I8080_XRA(I8080_L); + ICOUNT -= I8080_CLK[0xad]; +} + +static void PREFIX80(_aeh)(i8086_state *cpustate) +{ + // XRA M + I8080_XRA(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0xae]; +} + +static void PREFIX80(_afh)(i8086_state *cpustate) +{ + // XRA A + I8080_XRA(I8080_A); + ICOUNT -= I8080_CLK[0xaf]; +} + +static void PREFIX80(_b0h)(i8086_state *cpustate) +{ + // ORA B + I8080_ORA(I8080_B); + ICOUNT -= I8080_CLK[0xb0]; +} + +static void PREFIX80(_b1h)(i8086_state *cpustate) +{ + // ORA C + I8080_ORA(I8080_C); + ICOUNT -= I8080_CLK[0xb1]; +} + +static void PREFIX80(_b2h)(i8086_state *cpustate) +{ + // ORA D + I8080_ORA(I8080_D); + ICOUNT -= I8080_CLK[0xb2]; +} + +static void PREFIX80(_b3h)(i8086_state *cpustate) +{ + // ORA E + I8080_ORA(I8080_E); + ICOUNT -= I8080_CLK[0xb3]; +} + +static void PREFIX80(_b4h)(i8086_state *cpustate) +{ + // ORA H + I8080_ORA(I8080_H); + ICOUNT -= I8080_CLK[0xb4]; +} + +static void PREFIX80(_b5h)(i8086_state *cpustate) +{ + // ORA L + I8080_ORA(I8080_L); + ICOUNT -= I8080_CLK[0xb5]; +} + +static void PREFIX80(_b6h)(i8086_state *cpustate) +{ + // ORA M + I8080_ORA(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0xb6]; +} + +static void PREFIX80(_b7h)(i8086_state *cpustate) +{ + // ORA A + I8080_ORA(I8080_A); + ICOUNT -= I8080_CLK[0xb7]; +} + +static void PREFIX80(_b8h)(i8086_state *cpustate) +{ + // CMP B + I8080_CMP(I8080_B); + ICOUNT -= I8080_CLK[0xb8]; +} + +static void PREFIX80(_b9h)(i8086_state *cpustate) +{ + // CMP C + I8080_CMP(I8080_C); + ICOUNT -= I8080_CLK[0xb9]; +} + +static void PREFIX80(_bah)(i8086_state *cpustate) +{ + // CMP D + I8080_CMP(I8080_D); + ICOUNT -= I8080_CLK[0xba]; +} + +static void PREFIX80(_bbh)(i8086_state *cpustate) +{ + // CMP E + I8080_CMP(I8080_E); + ICOUNT -= I8080_CLK[0xbb]; +} + +static void PREFIX80(_bch)(i8086_state *cpustate) +{ + // CMP H + I8080_CMP(I8080_H); + ICOUNT -= I8080_CLK[0xbc]; +} + +static void PREFIX80(_bdh)(i8086_state *cpustate) +{ + // CMP L + I8080_CMP(I8080_L); + ICOUNT -= I8080_CLK[0xbd]; +} + +static void PREFIX80(_beh)(i8086_state *cpustate) +{ + // CMP M + I8080_CMP(I8080_RM8(cpustate, I8080_HL)); + ICOUNT -= I8080_CLK[0xbe]; +} + +static void PREFIX80(_bfh)(i8086_state *cpustate) +{ + // CMP A + I8080_CMP(I8080_A); + ICOUNT -= I8080_CLK[0xbf]; +} + +static void PREFIX80(_c0h)(i8086_state *cpustate) +{ + // RNZ + I8080_RET(!(I8080_F & I8080_ZF)); + ICOUNT -= I8080_CLK[0xc0]; +} + +static void PREFIX80(_c1h)(i8086_state *cpustate) +{ + // POP B + I8080_BC = I8080_POP(cpustate); + ICOUNT -= I8080_CLK[0xc1]; +} + +static void PREFIX80(_c2h)(i8086_state *cpustate) +{ + // JNZ nnnn + I8080_JMP(!(I8080_F & I8080_ZF)); + ICOUNT -= I8080_CLK[0xc2]; +} + +static void PREFIX80(_c3h)(i8086_state *cpustate) +{ + // JMP nnnn + I8080_JMP(1); + ICOUNT -= I8080_CLK[0xc3]; +} + +static void PREFIX80(_c4h)(i8086_state *cpustate) +{ + // CNZ nnnn + I8080_CALL(!(I8080_F & I8080_ZF)); + ICOUNT -= I8080_CLK[0xc4]; +} + +static void PREFIX80(_c5h)(i8086_state *cpustate) +{ + // PUSH B + I8080_PUSH(cpustate, I8080_BC); + ICOUNT -= I8080_CLK[0xc5]; +} + +static void PREFIX80(_c6h)(i8086_state *cpustate) +{ + // ADI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + i8080_ADD(tmp8); + ICOUNT -= I8080_CLK[0xc6]; +} + +static void PREFIX80(_c7h)(i8086_state *cpustate) +{ + // RST 0 + RST(0); + ICOUNT -= I8080_CLK[0xc7]; +} + +static void PREFIX80(_c8h)(i8086_state *cpustate) +{ + // RZ + I8080_RET(I8080_F & I8080_ZF); + ICOUNT -= I8080_CLK[0xc8]; +} + +static void PREFIX80(_c9h)(i8086_state *cpustate) +{ + // RET + I8080_RET(1); + ICOUNT -= I8080_CLK[0xc9]; +} + +static void PREFIX80(_cah)(i8086_state *cpustate) +{ + // JZ nnnn + I8080_JMP(I8080_F & I8080_ZF); + ICOUNT -= I8080_CLK[0xca]; +} + +static void PREFIX80(_cbh)(i8086_state *cpustate) +{ + // JMP nnnn + I8080_JMP(1); + ICOUNT -= I8080_CLK[0xcb]; +} + +static void PREFIX80(_cch)(i8086_state *cpustate) +{ + // CZ nnnn + I8080_CALL(I8080_F & I8080_ZF); + ICOUNT -= I8080_CLK[0xcc]; +} + +static void PREFIX80(_cdh)(i8086_state *cpustate) +{ + // CALL nnnn + I8080_CALL(1); + ICOUNT -= I8080_CLK[0xcd]; +} + +static void PREFIX80(_ceh)(i8086_state *cpustate) +{ + // ACI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + I8080_ADC(tmp8); + ICOUNT -= I8080_CLK[0xce]; +} + +static void PREFIX80(_cfh)(i8086_state *cpustate) +{ + // RST 1 + RST(1); + ICOUNT -= I8080_CLK[0xcf]; +} + +static void PREFIX80(_d0h)(i8086_state *cpustate) +{ + // RNC + I8080_RET(!(I8080_F & I8080_CF)); + ICOUNT -= I8080_CLK[0xd0]; +} + +static void PREFIX80(_d1h)(i8086_state *cpustate) +{ + // POP D + I8080_DE = I8080_POP(cpustate); + ICOUNT -= I8080_CLK[0xd1]; +} + +static void PREFIX80(_d2h)(i8086_state *cpustate) +{ + // JNC nnnn + I8080_JMP(!(I8080_F & I8080_CF)); + ICOUNT -= I8080_CLK[0xd2]; +} + +static void PREFIX80(_d3h)(i8086_state *cpustate) +{ + // OUT nn + I8080_OUT8(cpustate, I8080_FETCH8(cpustate), I8080_A); + ICOUNT -= I8080_CLK[0xd3]; +} + +static void PREFIX80(_d4h)(i8086_state *cpustate) +{ + // CNC nnnn + I8080_CALL(!(I8080_F & I8080_CF)); + ICOUNT -= I8080_CLK[0xd4]; +} + +static void PREFIX80(_d5h)(i8086_state *cpustate) +{ + // PUSH D + I8080_PUSH(cpustate, I8080_DE); + ICOUNT -= I8080_CLK[0xd5]; +} + +static void PREFIX80(_d6h)(i8086_state *cpustate) +{ + // SUI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + I8080_SUB(tmp8); + ICOUNT -= I8080_CLK[0xd6]; +} + +static void PREFIX80(_d7h)(i8086_state *cpustate) +{ + // RST 2 + RST(2); + ICOUNT -= I8080_CLK[0xd7]; +} + +static void PREFIX80(_d8h)(i8086_state *cpustate) +{ + // RC + I8080_RET(I8080_F & I8080_CF); + ICOUNT -= I8080_CLK[0xd8]; +} + +static void PREFIX80(_d9h)(i8086_state *cpustate) +{ + // RET + I8080_RET(1); + ICOUNT -= I8080_CLK[0xd9]; +} + +static void PREFIX80(_dah)(i8086_state *cpustate) +{ + // JC nnnn + I8080_JMP(I8080_F & I8080_CF); + ICOUNT -= I8080_CLK[0xda]; +} + +static void PREFIX80(_dbh)(i8086_state *cpustate) +{ + // IN nn + I8080_A = I8080_IN8(cpustate, I8080_FETCH8(cpustate)); + ICOUNT -= I8080_CLK[0xdb]; +} + +static void PREFIX80(_dch)(i8086_state *cpustate) +{ + // CC nnnn + I8080_CALL(I8080_F & I8080_CF); + ICOUNT -= I8080_CLK[0xdc]; +} + +static void PREFIX80(_ddh)(i8086_state *cpustate) +{ + // CALL nnnn + I8080_CALL(1); + ICOUNT -= I8080_CLK[0xdd]; +} + +static void PREFIX80(_deh)(i8086_state *cpustate) +{ + // SBI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + I8080_SBB(tmp8); + ICOUNT -= I8080_CLK[0xde]; +} + +static void PREFIX80(_dfh)(i8086_state *cpustate) +{ + // RST 3 + RST(3); + ICOUNT -= I8080_CLK[0xdf]; +} + +static void PREFIX80(_e0h)(i8086_state *cpustate) +{ + // RPO + I8080_RET(!(I8080_F & I8080_VF)); + ICOUNT -= I8080_CLK[0xe0]; +} + +static void PREFIX80(_e1h)(i8086_state *cpustate) +{ + // POP H + I8080_HL = I8080_POP(cpustate); + ICOUNT -= I8080_CLK[0xe1]; +} + +static void PREFIX80(_e2h)(i8086_state *cpustate) +{ + // JPO nnnn + I8080_JMP(!(I8080_F & I8080_VF)); + ICOUNT -= I8080_CLK[0xe2]; +} + +static void PREFIX80(_e3h)(i8086_state *cpustate) +{ + // XTHL + UINT16 tmp16 = I8080_POP(cpustate); + I8080_PUSH(cpustate, I8080_HL); + I8080_HL = tmp16; + ICOUNT -= I8080_CLK[0xe3]; +} + +static void PREFIX80(_e4h)(i8086_state *cpustate) +{ + // CPO nnnn + I8080_CALL(!(I8080_F & I8080_VF)); + ICOUNT -= I8080_CLK[0xe4]; +} + +static void PREFIX80(_e5h)(i8086_state *cpustate) +{ + // PUSH H + I8080_PUSH(cpustate, I8080_HL); + ICOUNT -= I8080_CLK[0xe5]; +} + +static void PREFIX80(_e6h)(i8086_state *cpustate) +{ + // ANI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + I8080_ANA(tmp8); + ICOUNT -= I8080_CLK[0xe6]; +} + +static void PREFIX80(_e7h)(i8086_state *cpustate) +{ + // RST 4 + RST(4); + ICOUNT -= I8080_CLK[0xe7]; +} + +static void PREFIX80(_e8h)(i8086_state *cpustate) +{ + // RPE + I8080_RET(I8080_F & I8080_VF); + ICOUNT -= I8080_CLK[0xe8]; +} + +static void PREFIX80(_e9h)(i8086_state *cpustate) +{ + // PCHL + cpustate->pc = cpustate->base[CS] + I8080_HL; + ICOUNT -= I8080_CLK[0xe9]; +} + +static void PREFIX80(_eah)(i8086_state *cpustate) +{ + // JPE nnnn + I8080_JMP(I8080_F & I8080_VF); + ICOUNT -= I8080_CLK[0xea]; +} + +static void PREFIX80(_ebh)(i8086_state *cpustate) +{ + // XCHG + UINT16 tmp16 = I8080_DE; + I8080_DE = I8080_HL; + I8080_HL = tmp16; + ICOUNT -= I8080_CLK[0xeb]; +} + +static void PREFIX80(_ech)(i8086_state *cpustate) +{ + // CPE nnnn + I8080_CALL(I8080_F & I8080_VF); + ICOUNT -= I8080_CLK[0xec]; +} + +static void PREFIX80(_edh)(i8086_state *cpustate) +{ + UINT8 lo = I8080_FETCH8(cpustate); + UINT8 hi = I8080_FETCH8(cpustate); + UINT16 a = lo | (hi << 8); + + if(lo == 0xed) { + // CALLN + ICOUNT -= 38; + PREFIX86(_interrupt)(cpustate, hi); + /* keep MF write-enabled, so MF will be 0 and re-enter emulation mode when iret is done in native code */ + cpustate->MF = 1; + } else if(lo == 0xfd) { + // RETEM + int icount = ICOUNT - 27; + PREFIX86(_iret)(cpustate); + cpustate->MF = 1; + cpustate->MF_WriteDisabled = 1; + ICOUNT = icount; + } else { + // CALL nnnn + UINT16 ip = cpustate->pc - cpustate->base[CS]; + ICOUNT -= 6; + I8080_PUSH(cpustate, ip); + cpustate->pc = cpustate->base[CS] + a; + ICOUNT -= I8080_CLK[0xed]; + } +} + +static void PREFIX80(_eeh)(i8086_state *cpustate) +{ + // XRI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + I8080_XRA(tmp8); + ICOUNT -= I8080_CLK[0xee]; +} + +static void PREFIX80(_efh)(i8086_state *cpustate) +{ + // RST 5 + RST(5); + ICOUNT -= I8080_CLK[0xef]; +} + +static void PREFIX80(_f0h)(i8086_state *cpustate) +{ + // RP + I8080_RET(!(I8080_F & I8080_SF)); + ICOUNT -= I8080_CLK[0xf0]; +} + +static void PREFIX80(_f1h)(i8086_state *cpustate) +{ + // POP A + I8080_AF = I8080_POP(cpustate); + ICOUNT -= I8080_CLK[0xf1]; +} + +static void PREFIX80(_f2h)(i8086_state *cpustate) +{ + // JP nnnn + I8080_JMP(!(I8080_F & I8080_SF)); + ICOUNT -= I8080_CLK[0xf2]; +} + +static void PREFIX80(_f3h)(i8086_state *cpustate) +{ + // DI + ICOUNT -= I8080_CLK[0xf3]; +} + +static void PREFIX80(_f4h)(i8086_state *cpustate) +{ + // CP nnnn + I8080_CALL(!(I8080_F & I8080_SF)); + ICOUNT -= I8080_CLK[0xf4]; +} + +static void PREFIX80(_f5h)(i8086_state *cpustate) +{ + // PUSH A + I8080_PUSH(cpustate, I8080_AF); + ICOUNT -= I8080_CLK[0xf5]; +} + +static void PREFIX80(_f6h)(i8086_state *cpustate) +{ + // ORI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + I8080_ORA(tmp8); + ICOUNT -= I8080_CLK[0xf6]; +} + +static void PREFIX80(_f7h)(i8086_state *cpustate) +{ + // RST 6 + RST(6); + ICOUNT -= I8080_CLK[0xf7]; +} + +static void PREFIX80(_f8h)(i8086_state *cpustate) +{ + // RM + I8080_RET(I8080_F & I8080_SF); + ICOUNT -= I8080_CLK[0xf8]; +} + +static void PREFIX80(_f9h)(i8086_state *cpustate) +{ + // SPHL + I8080_SP = I8080_HL; + ICOUNT -= I8080_CLK[0xf9]; +} + +static void PREFIX80(_fah)(i8086_state *cpustate) +{ + // JM nnnn + I8080_JMP(I8080_F & I8080_SF); + ICOUNT -= I8080_CLK[0xfa]; +} + +static void PREFIX80(_fbh)(i8086_state *cpustate) +{ + // EI + ICOUNT -= I8080_CLK[0xfb]; +} + +static void PREFIX80(_fch)(i8086_state *cpustate) +{ + // CM nnnn + I8080_CALL(I8080_F & I8080_SF); + ICOUNT -= I8080_CLK[0xfc]; +} + +static void PREFIX80(_fdh)(i8086_state *cpustate) +{ + // CALL nnnn + I8080_CALL(1); + ICOUNT -= I8080_CLK[0xfd]; +} + +static void PREFIX80(_feh)(i8086_state *cpustate) +{ + // CPI nn + UINT8 tmp8 = I8080_FETCH8(cpustate); + I8080_CMP(tmp8); + ICOUNT -= I8080_CLK[0xfe]; +} + +static void PREFIX80(_ffh)(i8086_state *cpustate) +{ + // RST 7 + RST(7); + ICOUNT -= I8080_CLK[0xff]; +} diff --git a/source/src/vm/mame/emu/cpu/i86/instrv30.h b/source/src/vm/mame/emu/cpu/i86/instrv30.h index 1a63415a8..97327a7c6 100644 --- a/source/src/vm/mame/emu/cpu/i86/instrv30.h +++ b/source/src/vm/mame/emu/cpu/i86/instrv30.h @@ -1,6 +1,7 @@ static void PREFIXV30(_0fpre)(i8086_state *cpustate); static void PREFIXV30(_repnc)(i8086_state *cpustate); static void PREFIXV30(_repc)(i8086_state *cpustate); +static void PREFIXV30(_aam)(i8086_state *cpustate); static void PREFIXV30(_aad)(i8086_state *cpustate); static void PREFIXV30(_setalc)(i8086_state *cpustate); #if 0 @@ -17,3 +18,261 @@ static void PREFIX(_mov_sregw)(i8086_state *cpustate); static void PREFIXV30(_repne)(i8086_state *cpustate); static void PREFIXV30(_repe)(i8086_state *cpustate); static void PREFIXV30(_sti)(i8086_state *cpustate); + +/* i8080 instructions */ +static void PREFIX80(_00h)(i8086_state *cpustate); +static void PREFIX80(_01h)(i8086_state *cpustate); +static void PREFIX80(_02h)(i8086_state *cpustate); +static void PREFIX80(_03h)(i8086_state *cpustate); +static void PREFIX80(_04h)(i8086_state *cpustate); +static void PREFIX80(_05h)(i8086_state *cpustate); +static void PREFIX80(_06h)(i8086_state *cpustate); +static void PREFIX80(_07h)(i8086_state *cpustate); +static void PREFIX80(_08h)(i8086_state *cpustate); +static void PREFIX80(_09h)(i8086_state *cpustate); +static void PREFIX80(_0ah)(i8086_state *cpustate); +static void PREFIX80(_0bh)(i8086_state *cpustate); +static void PREFIX80(_0ch)(i8086_state *cpustate); +static void PREFIX80(_0dh)(i8086_state *cpustate); +static void PREFIX80(_0eh)(i8086_state *cpustate); +static void PREFIX80(_0fh)(i8086_state *cpustate); +static void PREFIX80(_10h)(i8086_state *cpustate); +static void PREFIX80(_11h)(i8086_state *cpustate); +static void PREFIX80(_12h)(i8086_state *cpustate); +static void PREFIX80(_13h)(i8086_state *cpustate); +static void PREFIX80(_14h)(i8086_state *cpustate); +static void PREFIX80(_15h)(i8086_state *cpustate); +static void PREFIX80(_16h)(i8086_state *cpustate); +static void PREFIX80(_17h)(i8086_state *cpustate); +static void PREFIX80(_18h)(i8086_state *cpustate); +static void PREFIX80(_19h)(i8086_state *cpustate); +static void PREFIX80(_1ah)(i8086_state *cpustate); +static void PREFIX80(_1bh)(i8086_state *cpustate); +static void PREFIX80(_1ch)(i8086_state *cpustate); +static void PREFIX80(_1dh)(i8086_state *cpustate); +static void PREFIX80(_1eh)(i8086_state *cpustate); +static void PREFIX80(_1fh)(i8086_state *cpustate); +static void PREFIX80(_20h)(i8086_state *cpustate); +static void PREFIX80(_21h)(i8086_state *cpustate); +static void PREFIX80(_22h)(i8086_state *cpustate); +static void PREFIX80(_23h)(i8086_state *cpustate); +static void PREFIX80(_24h)(i8086_state *cpustate); +static void PREFIX80(_25h)(i8086_state *cpustate); +static void PREFIX80(_26h)(i8086_state *cpustate); +static void PREFIX80(_27h)(i8086_state *cpustate); +static void PREFIX80(_28h)(i8086_state *cpustate); +static void PREFIX80(_29h)(i8086_state *cpustate); +static void PREFIX80(_2ah)(i8086_state *cpustate); +static void PREFIX80(_2bh)(i8086_state *cpustate); +static void PREFIX80(_2ch)(i8086_state *cpustate); +static void PREFIX80(_2dh)(i8086_state *cpustate); +static void PREFIX80(_2eh)(i8086_state *cpustate); +static void PREFIX80(_2fh)(i8086_state *cpustate); +static void PREFIX80(_30h)(i8086_state *cpustate); +static void PREFIX80(_31h)(i8086_state *cpustate); +static void PREFIX80(_32h)(i8086_state *cpustate); +static void PREFIX80(_33h)(i8086_state *cpustate); +static void PREFIX80(_34h)(i8086_state *cpustate); +static void PREFIX80(_35h)(i8086_state *cpustate); +static void PREFIX80(_36h)(i8086_state *cpustate); +static void PREFIX80(_37h)(i8086_state *cpustate); +static void PREFIX80(_38h)(i8086_state *cpustate); +static void PREFIX80(_39h)(i8086_state *cpustate); +static void PREFIX80(_3ah)(i8086_state *cpustate); +static void PREFIX80(_3bh)(i8086_state *cpustate); +static void PREFIX80(_3ch)(i8086_state *cpustate); +static void PREFIX80(_3dh)(i8086_state *cpustate); +static void PREFIX80(_3eh)(i8086_state *cpustate); +static void PREFIX80(_3fh)(i8086_state *cpustate); +static void PREFIX80(_40h)(i8086_state *cpustate); +static void PREFIX80(_41h)(i8086_state *cpustate); +static void PREFIX80(_42h)(i8086_state *cpustate); +static void PREFIX80(_43h)(i8086_state *cpustate); +static void PREFIX80(_44h)(i8086_state *cpustate); +static void PREFIX80(_45h)(i8086_state *cpustate); +static void PREFIX80(_46h)(i8086_state *cpustate); +static void PREFIX80(_47h)(i8086_state *cpustate); +static void PREFIX80(_48h)(i8086_state *cpustate); +static void PREFIX80(_49h)(i8086_state *cpustate); +static void PREFIX80(_4ah)(i8086_state *cpustate); +static void PREFIX80(_4bh)(i8086_state *cpustate); +static void PREFIX80(_4ch)(i8086_state *cpustate); +static void PREFIX80(_4dh)(i8086_state *cpustate); +static void PREFIX80(_4eh)(i8086_state *cpustate); +static void PREFIX80(_4fh)(i8086_state *cpustate); +static void PREFIX80(_50h)(i8086_state *cpustate); +static void PREFIX80(_51h)(i8086_state *cpustate); +static void PREFIX80(_52h)(i8086_state *cpustate); +static void PREFIX80(_53h)(i8086_state *cpustate); +static void PREFIX80(_54h)(i8086_state *cpustate); +static void PREFIX80(_55h)(i8086_state *cpustate); +static void PREFIX80(_56h)(i8086_state *cpustate); +static void PREFIX80(_57h)(i8086_state *cpustate); +static void PREFIX80(_58h)(i8086_state *cpustate); +static void PREFIX80(_59h)(i8086_state *cpustate); +static void PREFIX80(_5ah)(i8086_state *cpustate); +static void PREFIX80(_5bh)(i8086_state *cpustate); +static void PREFIX80(_5ch)(i8086_state *cpustate); +static void PREFIX80(_5dh)(i8086_state *cpustate); +static void PREFIX80(_5eh)(i8086_state *cpustate); +static void PREFIX80(_5fh)(i8086_state *cpustate); +static void PREFIX80(_60h)(i8086_state *cpustate); +static void PREFIX80(_61h)(i8086_state *cpustate); +static void PREFIX80(_62h)(i8086_state *cpustate); +static void PREFIX80(_63h)(i8086_state *cpustate); +static void PREFIX80(_64h)(i8086_state *cpustate); +static void PREFIX80(_65h)(i8086_state *cpustate); +static void PREFIX80(_66h)(i8086_state *cpustate); +static void PREFIX80(_67h)(i8086_state *cpustate); +static void PREFIX80(_68h)(i8086_state *cpustate); +static void PREFIX80(_69h)(i8086_state *cpustate); +static void PREFIX80(_6ah)(i8086_state *cpustate); +static void PREFIX80(_6bh)(i8086_state *cpustate); +static void PREFIX80(_6ch)(i8086_state *cpustate); +static void PREFIX80(_6dh)(i8086_state *cpustate); +static void PREFIX80(_6eh)(i8086_state *cpustate); +static void PREFIX80(_6fh)(i8086_state *cpustate); +static void PREFIX80(_70h)(i8086_state *cpustate); +static void PREFIX80(_71h)(i8086_state *cpustate); +static void PREFIX80(_72h)(i8086_state *cpustate); +static void PREFIX80(_73h)(i8086_state *cpustate); +static void PREFIX80(_74h)(i8086_state *cpustate); +static void PREFIX80(_75h)(i8086_state *cpustate); +static void PREFIX80(_76h)(i8086_state *cpustate); +static void PREFIX80(_77h)(i8086_state *cpustate); +static void PREFIX80(_78h)(i8086_state *cpustate); +static void PREFIX80(_79h)(i8086_state *cpustate); +static void PREFIX80(_7ah)(i8086_state *cpustate); +static void PREFIX80(_7bh)(i8086_state *cpustate); +static void PREFIX80(_7ch)(i8086_state *cpustate); +static void PREFIX80(_7dh)(i8086_state *cpustate); +static void PREFIX80(_7eh)(i8086_state *cpustate); +static void PREFIX80(_7fh)(i8086_state *cpustate); +static void PREFIX80(_80h)(i8086_state *cpustate); +static void PREFIX80(_81h)(i8086_state *cpustate); +static void PREFIX80(_82h)(i8086_state *cpustate); +static void PREFIX80(_83h)(i8086_state *cpustate); +static void PREFIX80(_84h)(i8086_state *cpustate); +static void PREFIX80(_85h)(i8086_state *cpustate); +static void PREFIX80(_86h)(i8086_state *cpustate); +static void PREFIX80(_87h)(i8086_state *cpustate); +static void PREFIX80(_88h)(i8086_state *cpustate); +static void PREFIX80(_89h)(i8086_state *cpustate); +static void PREFIX80(_8ah)(i8086_state *cpustate); +static void PREFIX80(_8bh)(i8086_state *cpustate); +static void PREFIX80(_8ch)(i8086_state *cpustate); +static void PREFIX80(_8dh)(i8086_state *cpustate); +static void PREFIX80(_8eh)(i8086_state *cpustate); +static void PREFIX80(_8fh)(i8086_state *cpustate); +static void PREFIX80(_90h)(i8086_state *cpustate); +static void PREFIX80(_91h)(i8086_state *cpustate); +static void PREFIX80(_92h)(i8086_state *cpustate); +static void PREFIX80(_93h)(i8086_state *cpustate); +static void PREFIX80(_94h)(i8086_state *cpustate); +static void PREFIX80(_95h)(i8086_state *cpustate); +static void PREFIX80(_96h)(i8086_state *cpustate); +static void PREFIX80(_97h)(i8086_state *cpustate); +static void PREFIX80(_98h)(i8086_state *cpustate); +static void PREFIX80(_99h)(i8086_state *cpustate); +static void PREFIX80(_9ah)(i8086_state *cpustate); +static void PREFIX80(_9bh)(i8086_state *cpustate); +static void PREFIX80(_9ch)(i8086_state *cpustate); +static void PREFIX80(_9dh)(i8086_state *cpustate); +static void PREFIX80(_9eh)(i8086_state *cpustate); +static void PREFIX80(_9fh)(i8086_state *cpustate); +static void PREFIX80(_a0h)(i8086_state *cpustate); +static void PREFIX80(_a1h)(i8086_state *cpustate); +static void PREFIX80(_a2h)(i8086_state *cpustate); +static void PREFIX80(_a3h)(i8086_state *cpustate); +static void PREFIX80(_a4h)(i8086_state *cpustate); +static void PREFIX80(_a5h)(i8086_state *cpustate); +static void PREFIX80(_a6h)(i8086_state *cpustate); +static void PREFIX80(_a7h)(i8086_state *cpustate); +static void PREFIX80(_a8h)(i8086_state *cpustate); +static void PREFIX80(_a9h)(i8086_state *cpustate); +static void PREFIX80(_aah)(i8086_state *cpustate); +static void PREFIX80(_abh)(i8086_state *cpustate); +static void PREFIX80(_ach)(i8086_state *cpustate); +static void PREFIX80(_adh)(i8086_state *cpustate); +static void PREFIX80(_aeh)(i8086_state *cpustate); +static void PREFIX80(_afh)(i8086_state *cpustate); +static void PREFIX80(_b0h)(i8086_state *cpustate); +static void PREFIX80(_b1h)(i8086_state *cpustate); +static void PREFIX80(_b2h)(i8086_state *cpustate); +static void PREFIX80(_b3h)(i8086_state *cpustate); +static void PREFIX80(_b4h)(i8086_state *cpustate); +static void PREFIX80(_b5h)(i8086_state *cpustate); +static void PREFIX80(_b6h)(i8086_state *cpustate); +static void PREFIX80(_b7h)(i8086_state *cpustate); +static void PREFIX80(_b8h)(i8086_state *cpustate); +static void PREFIX80(_b9h)(i8086_state *cpustate); +static void PREFIX80(_bah)(i8086_state *cpustate); +static void PREFIX80(_bbh)(i8086_state *cpustate); +static void PREFIX80(_bch)(i8086_state *cpustate); +static void PREFIX80(_bdh)(i8086_state *cpustate); +static void PREFIX80(_beh)(i8086_state *cpustate); +static void PREFIX80(_bfh)(i8086_state *cpustate); +static void PREFIX80(_c0h)(i8086_state *cpustate); +static void PREFIX80(_c1h)(i8086_state *cpustate); +static void PREFIX80(_c2h)(i8086_state *cpustate); +static void PREFIX80(_c3h)(i8086_state *cpustate); +static void PREFIX80(_c4h)(i8086_state *cpustate); +static void PREFIX80(_c5h)(i8086_state *cpustate); +static void PREFIX80(_c6h)(i8086_state *cpustate); +static void PREFIX80(_c7h)(i8086_state *cpustate); +static void PREFIX80(_c8h)(i8086_state *cpustate); +static void PREFIX80(_c9h)(i8086_state *cpustate); +static void PREFIX80(_cah)(i8086_state *cpustate); +static void PREFIX80(_cbh)(i8086_state *cpustate); +static void PREFIX80(_cch)(i8086_state *cpustate); +static void PREFIX80(_cdh)(i8086_state *cpustate); +static void PREFIX80(_ceh)(i8086_state *cpustate); +static void PREFIX80(_cfh)(i8086_state *cpustate); +static void PREFIX80(_d0h)(i8086_state *cpustate); +static void PREFIX80(_d1h)(i8086_state *cpustate); +static void PREFIX80(_d2h)(i8086_state *cpustate); +static void PREFIX80(_d3h)(i8086_state *cpustate); +static void PREFIX80(_d4h)(i8086_state *cpustate); +static void PREFIX80(_d5h)(i8086_state *cpustate); +static void PREFIX80(_d6h)(i8086_state *cpustate); +static void PREFIX80(_d7h)(i8086_state *cpustate); +static void PREFIX80(_d8h)(i8086_state *cpustate); +static void PREFIX80(_d9h)(i8086_state *cpustate); +static void PREFIX80(_dah)(i8086_state *cpustate); +static void PREFIX80(_dbh)(i8086_state *cpustate); +static void PREFIX80(_dch)(i8086_state *cpustate); +static void PREFIX80(_ddh)(i8086_state *cpustate); +static void PREFIX80(_deh)(i8086_state *cpustate); +static void PREFIX80(_dfh)(i8086_state *cpustate); +static void PREFIX80(_e0h)(i8086_state *cpustate); +static void PREFIX80(_e1h)(i8086_state *cpustate); +static void PREFIX80(_e2h)(i8086_state *cpustate); +static void PREFIX80(_e3h)(i8086_state *cpustate); +static void PREFIX80(_e4h)(i8086_state *cpustate); +static void PREFIX80(_e5h)(i8086_state *cpustate); +static void PREFIX80(_e6h)(i8086_state *cpustate); +static void PREFIX80(_e7h)(i8086_state *cpustate); +static void PREFIX80(_e8h)(i8086_state *cpustate); +static void PREFIX80(_e9h)(i8086_state *cpustate); +static void PREFIX80(_eah)(i8086_state *cpustate); +static void PREFIX80(_ebh)(i8086_state *cpustate); +static void PREFIX80(_ech)(i8086_state *cpustate); +static void PREFIX80(_edh)(i8086_state *cpustate); +static void PREFIX80(_eeh)(i8086_state *cpustate); +static void PREFIX80(_efh)(i8086_state *cpustate); +static void PREFIX80(_f0h)(i8086_state *cpustate); +static void PREFIX80(_f1h)(i8086_state *cpustate); +static void PREFIX80(_f2h)(i8086_state *cpustate); +static void PREFIX80(_f3h)(i8086_state *cpustate); +static void PREFIX80(_f4h)(i8086_state *cpustate); +static void PREFIX80(_f5h)(i8086_state *cpustate); +static void PREFIX80(_f6h)(i8086_state *cpustate); +static void PREFIX80(_f7h)(i8086_state *cpustate); +static void PREFIX80(_f8h)(i8086_state *cpustate); +static void PREFIX80(_f9h)(i8086_state *cpustate); +static void PREFIX80(_fah)(i8086_state *cpustate); +static void PREFIX80(_fbh)(i8086_state *cpustate); +static void PREFIX80(_fch)(i8086_state *cpustate); +static void PREFIX80(_fdh)(i8086_state *cpustate); +static void PREFIX80(_feh)(i8086_state *cpustate); +static void PREFIX80(_ffh)(i8086_state *cpustate); diff --git a/source/src/vm/mame/emu/cpu/i86/tablev30.h b/source/src/vm/mame/emu/cpu/i86/tablev30.h index 1ef4a51fc..e1aa206b0 100644 --- a/source/src/vm/mame/emu/cpu/i86/tablev30.h +++ b/source/src/vm/mame/emu/cpu/i86/tablev30.h @@ -215,7 +215,7 @@ void (*const PREFIXV30(_instruction)[256])(i8086_state *cpustate) = PREFIX86(_rotshft_w), /* 0xd1 */ PREFIX86(_rotshft_bcl), /* 0xd2 */ PREFIX86(_rotshft_wcl), /* 0xd3 */ - PREFIX86(_aam), /* 0xd4 */ + PREFIXV30(_aam), /* 0xd4 */ PREFIXV30(_aad), /* 0xd5 */ PREFIXV30(_setalc), /* 0xd6 */ PREFIX86(_xlat), /* 0xd7 */ @@ -479,7 +479,7 @@ void (*const PREFIXV30(_instruction)[256])(i8086_state *cpustate) = case 0xd1: PREFIX86(_rotshft_w)(cpustate); break;\ case 0xd2: PREFIX86(_rotshft_bcl)(cpustate); break;\ case 0xd3: PREFIX86(_rotshft_wcl)(cpustate); break;\ - case 0xd4: PREFIX86(_aam)(cpustate); break;\ + case 0xd4: PREFIXV30(_aam)(cpustate); break;\ case 0xd5: PREFIXV30(_aad)(cpustate); break;\ case 0xd6: PREFIXV30(_setalc)(cpustate); break;\ case 0xd7: PREFIX86(_xlat)(cpustate); break;\ @@ -527,3 +527,531 @@ void (*const PREFIXV30(_instruction)[256])(i8086_state *cpustate) = #else #define TABLEV30 PREFIXV30(_instruction)[FETCHOP](cpustate); #endif + +/* i8080 instructions */ + +static void (*const PREFIX80(_instruction)[256])(i8086_state *cpustate) = +{ + PREFIX80(_00h), + PREFIX80(_01h), + PREFIX80(_02h), + PREFIX80(_03h), + PREFIX80(_04h), + PREFIX80(_05h), + PREFIX80(_06h), + PREFIX80(_07h), + PREFIX80(_08h), + PREFIX80(_09h), + PREFIX80(_0ah), + PREFIX80(_0bh), + PREFIX80(_0ch), + PREFIX80(_0dh), + PREFIX80(_0eh), + PREFIX80(_0fh), + PREFIX80(_10h), + PREFIX80(_11h), + PREFIX80(_12h), + PREFIX80(_13h), + PREFIX80(_14h), + PREFIX80(_15h), + PREFIX80(_16h), + PREFIX80(_17h), + PREFIX80(_18h), + PREFIX80(_19h), + PREFIX80(_1ah), + PREFIX80(_1bh), + PREFIX80(_1ch), + PREFIX80(_1dh), + PREFIX80(_1eh), + PREFIX80(_1fh), + PREFIX80(_20h), + PREFIX80(_21h), + PREFIX80(_22h), + PREFIX80(_23h), + PREFIX80(_24h), + PREFIX80(_25h), + PREFIX80(_26h), + PREFIX80(_27h), + PREFIX80(_28h), + PREFIX80(_29h), + PREFIX80(_2ah), + PREFIX80(_2bh), + PREFIX80(_2ch), + PREFIX80(_2dh), + PREFIX80(_2eh), + PREFIX80(_2fh), + PREFIX80(_30h), + PREFIX80(_31h), + PREFIX80(_32h), + PREFIX80(_33h), + PREFIX80(_34h), + PREFIX80(_35h), + PREFIX80(_36h), + PREFIX80(_37h), + PREFIX80(_38h), + PREFIX80(_39h), + PREFIX80(_3ah), + PREFIX80(_3bh), + PREFIX80(_3ch), + PREFIX80(_3dh), + PREFIX80(_3eh), + PREFIX80(_3fh), + PREFIX80(_40h), + PREFIX80(_41h), + PREFIX80(_42h), + PREFIX80(_43h), + PREFIX80(_44h), + PREFIX80(_45h), + PREFIX80(_46h), + PREFIX80(_47h), + PREFIX80(_48h), + PREFIX80(_49h), + PREFIX80(_4ah), + PREFIX80(_4bh), + PREFIX80(_4ch), + PREFIX80(_4dh), + PREFIX80(_4eh), + PREFIX80(_4fh), + PREFIX80(_50h), + PREFIX80(_51h), + PREFIX80(_52h), + PREFIX80(_53h), + PREFIX80(_54h), + PREFIX80(_55h), + PREFIX80(_56h), + PREFIX80(_57h), + PREFIX80(_58h), + PREFIX80(_59h), + PREFIX80(_5ah), + PREFIX80(_5bh), + PREFIX80(_5ch), + PREFIX80(_5dh), + PREFIX80(_5eh), + PREFIX80(_5fh), + PREFIX80(_60h), + PREFIX80(_61h), + PREFIX80(_62h), + PREFIX80(_63h), + PREFIX80(_64h), + PREFIX80(_65h), + PREFIX80(_66h), + PREFIX80(_67h), + PREFIX80(_68h), + PREFIX80(_69h), + PREFIX80(_6ah), + PREFIX80(_6bh), + PREFIX80(_6ch), + PREFIX80(_6dh), + PREFIX80(_6eh), + PREFIX80(_6fh), + PREFIX80(_70h), + PREFIX80(_71h), + PREFIX80(_72h), + PREFIX80(_73h), + PREFIX80(_74h), + PREFIX80(_75h), + PREFIX80(_76h), + PREFIX80(_77h), + PREFIX80(_78h), + PREFIX80(_79h), + PREFIX80(_7ah), + PREFIX80(_7bh), + PREFIX80(_7ch), + PREFIX80(_7dh), + PREFIX80(_7eh), + PREFIX80(_7fh), + PREFIX80(_80h), + PREFIX80(_81h), + PREFIX80(_82h), + PREFIX80(_83h), + PREFIX80(_84h), + PREFIX80(_85h), + PREFIX80(_86h), + PREFIX80(_87h), + PREFIX80(_88h), + PREFIX80(_89h), + PREFIX80(_8ah), + PREFIX80(_8bh), + PREFIX80(_8ch), + PREFIX80(_8dh), + PREFIX80(_8eh), + PREFIX80(_8fh), + PREFIX80(_90h), + PREFIX80(_91h), + PREFIX80(_92h), + PREFIX80(_93h), + PREFIX80(_94h), + PREFIX80(_95h), + PREFIX80(_96h), + PREFIX80(_97h), + PREFIX80(_98h), + PREFIX80(_99h), + PREFIX80(_9ah), + PREFIX80(_9bh), + PREFIX80(_9ch), + PREFIX80(_9dh), + PREFIX80(_9eh), + PREFIX80(_9fh), + PREFIX80(_a0h), + PREFIX80(_a1h), + PREFIX80(_a2h), + PREFIX80(_a3h), + PREFIX80(_a4h), + PREFIX80(_a5h), + PREFIX80(_a6h), + PREFIX80(_a7h), + PREFIX80(_a8h), + PREFIX80(_a9h), + PREFIX80(_aah), + PREFIX80(_abh), + PREFIX80(_ach), + PREFIX80(_adh), + PREFIX80(_aeh), + PREFIX80(_afh), + PREFIX80(_b0h), + PREFIX80(_b1h), + PREFIX80(_b2h), + PREFIX80(_b3h), + PREFIX80(_b4h), + PREFIX80(_b5h), + PREFIX80(_b6h), + PREFIX80(_b7h), + PREFIX80(_b8h), + PREFIX80(_b9h), + PREFIX80(_bah), + PREFIX80(_bbh), + PREFIX80(_bch), + PREFIX80(_bdh), + PREFIX80(_beh), + PREFIX80(_bfh), + PREFIX80(_c0h), + PREFIX80(_c1h), + PREFIX80(_c2h), + PREFIX80(_c3h), + PREFIX80(_c4h), + PREFIX80(_c5h), + PREFIX80(_c6h), + PREFIX80(_c7h), + PREFIX80(_c8h), + PREFIX80(_c9h), + PREFIX80(_cah), + PREFIX80(_cbh), + PREFIX80(_cch), + PREFIX80(_cdh), + PREFIX80(_ceh), + PREFIX80(_cfh), + PREFIX80(_d0h), + PREFIX80(_d1h), + PREFIX80(_d2h), + PREFIX80(_d3h), + PREFIX80(_d4h), + PREFIX80(_d5h), + PREFIX80(_d6h), + PREFIX80(_d7h), + PREFIX80(_d8h), + PREFIX80(_d9h), + PREFIX80(_dah), + PREFIX80(_dbh), + PREFIX80(_dch), + PREFIX80(_ddh), + PREFIX80(_deh), + PREFIX80(_dfh), + PREFIX80(_e0h), + PREFIX80(_e1h), + PREFIX80(_e2h), + PREFIX80(_e3h), + PREFIX80(_e4h), + PREFIX80(_e5h), + PREFIX80(_e6h), + PREFIX80(_e7h), + PREFIX80(_e8h), + PREFIX80(_e9h), + PREFIX80(_eah), + PREFIX80(_ebh), + PREFIX80(_ech), + PREFIX80(_edh), + PREFIX80(_eeh), + PREFIX80(_efh), + PREFIX80(_f0h), + PREFIX80(_f1h), + PREFIX80(_f2h), + PREFIX80(_f3h), + PREFIX80(_f4h), + PREFIX80(_f5h), + PREFIX80(_f6h), + PREFIX80(_f7h), + PREFIX80(_f8h), + PREFIX80(_f9h), + PREFIX80(_fah), + PREFIX80(_fbh), + PREFIX80(_fch), + PREFIX80(_fdh), + PREFIX80(_feh), + PREFIX80(_ffh), +}; + +#if defined(BIGCASE) && !defined(RS6000) + /* Some compilers cannot handle large case statements */ +#define TABLE80 \ + switch(I8080_FETCH8(cpustate))\ + {\ + case 0x00: PREFIX80(_00h); break; \ + case 0x01: PREFIX80(_01h); break; \ + case 0x02: PREFIX80(_02h); break; \ + case 0x03: PREFIX80(_03h); break; \ + case 0x04: PREFIX80(_04h); break; \ + case 0x05: PREFIX80(_05h); break; \ + case 0x06: PREFIX80(_06h); break; \ + case 0x07: PREFIX80(_07h); break; \ + case 0x08: PREFIX80(_08h); break; \ + case 0x09: PREFIX80(_09h); break; \ + case 0x0a: PREFIX80(_0ah); break; \ + case 0x0b: PREFIX80(_0bh); break; \ + case 0x0c: PREFIX80(_0ch); break; \ + case 0x0d: PREFIX80(_0dh); break; \ + case 0x0e: PREFIX80(_0eh); break; \ + case 0x0f: PREFIX80(_0fh); break; \ + case 0x10: PREFIX80(_10h); break; \ + case 0x11: PREFIX80(_11h); break; \ + case 0x12: PREFIX80(_12h); break; \ + case 0x13: PREFIX80(_13h); break; \ + case 0x14: PREFIX80(_14h); break; \ + case 0x15: PREFIX80(_15h); break; \ + case 0x16: PREFIX80(_16h); break; \ + case 0x17: PREFIX80(_17h); break; \ + case 0x18: PREFIX80(_18h); break; \ + case 0x19: PREFIX80(_19h); break; \ + case 0x1a: PREFIX80(_1ah); break; \ + case 0x1b: PREFIX80(_1bh); break; \ + case 0x1c: PREFIX80(_1ch); break; \ + case 0x1d: PREFIX80(_1dh); break; \ + case 0x1e: PREFIX80(_1eh); break; \ + case 0x1f: PREFIX80(_1fh); break; \ + case 0x20: PREFIX80(_20h); break; \ + case 0x21: PREFIX80(_21h); break; \ + case 0x22: PREFIX80(_22h); break; \ + case 0x23: PREFIX80(_23h); break; \ + case 0x24: PREFIX80(_24h); break; \ + case 0x25: PREFIX80(_25h); break; \ + case 0x26: PREFIX80(_26h); break; \ + case 0x27: PREFIX80(_27h); break; \ + case 0x28: PREFIX80(_28h); break; \ + case 0x29: PREFIX80(_29h); break; \ + case 0x2a: PREFIX80(_2ah); break; \ + case 0x2b: PREFIX80(_2bh); break; \ + case 0x2c: PREFIX80(_2ch); break; \ + case 0x2d: PREFIX80(_2dh); break; \ + case 0x2e: PREFIX80(_2eh); break; \ + case 0x2f: PREFIX80(_2fh); break; \ + case 0x30: PREFIX80(_30h); break; \ + case 0x31: PREFIX80(_31h); break; \ + case 0x32: PREFIX80(_32h); break; \ + case 0x33: PREFIX80(_33h); break; \ + case 0x34: PREFIX80(_34h); break; \ + case 0x35: PREFIX80(_35h); break; \ + case 0x36: PREFIX80(_36h); break; \ + case 0x37: PREFIX80(_37h); break; \ + case 0x38: PREFIX80(_38h); break; \ + case 0x39: PREFIX80(_39h); break; \ + case 0x3a: PREFIX80(_3ah); break; \ + case 0x3b: PREFIX80(_3bh); break; \ + case 0x3c: PREFIX80(_3ch); break; \ + case 0x3d: PREFIX80(_3dh); break; \ + case 0x3e: PREFIX80(_3eh); break; \ + case 0x3f: PREFIX80(_3fh); break; \ + case 0x40: PREFIX80(_40h); break; \ + case 0x41: PREFIX80(_41h); break; \ + case 0x42: PREFIX80(_42h); break; \ + case 0x43: PREFIX80(_43h); break; \ + case 0x44: PREFIX80(_44h); break; \ + case 0x45: PREFIX80(_45h); break; \ + case 0x46: PREFIX80(_46h); break; \ + case 0x47: PREFIX80(_47h); break; \ + case 0x48: PREFIX80(_48h); break; \ + case 0x49: PREFIX80(_49h); break; \ + case 0x4a: PREFIX80(_4ah); break; \ + case 0x4b: PREFIX80(_4bh); break; \ + case 0x4c: PREFIX80(_4ch); break; \ + case 0x4d: PREFIX80(_4dh); break; \ + case 0x4e: PREFIX80(_4eh); break; \ + case 0x4f: PREFIX80(_4fh); break; \ + case 0x50: PREFIX80(_50h); break; \ + case 0x51: PREFIX80(_51h); break; \ + case 0x52: PREFIX80(_52h); break; \ + case 0x53: PREFIX80(_53h); break; \ + case 0x54: PREFIX80(_54h); break; \ + case 0x55: PREFIX80(_55h); break; \ + case 0x56: PREFIX80(_56h); break; \ + case 0x57: PREFIX80(_57h); break; \ + case 0x58: PREFIX80(_58h); break; \ + case 0x59: PREFIX80(_59h); break; \ + case 0x5a: PREFIX80(_5ah); break; \ + case 0x5b: PREFIX80(_5bh); break; \ + case 0x5c: PREFIX80(_5ch); break; \ + case 0x5d: PREFIX80(_5dh); break; \ + case 0x5e: PREFIX80(_5eh); break; \ + case 0x5f: PREFIX80(_5fh); break; \ + case 0x60: PREFIX80(_60h); break; \ + case 0x61: PREFIX80(_61h); break; \ + case 0x62: PREFIX80(_62h); break; \ + case 0x63: PREFIX80(_63h); break; \ + case 0x64: PREFIX80(_64h); break; \ + case 0x65: PREFIX80(_65h); break; \ + case 0x66: PREFIX80(_66h); break; \ + case 0x67: PREFIX80(_67h); break; \ + case 0x68: PREFIX80(_68h); break; \ + case 0x69: PREFIX80(_69h); break; \ + case 0x6a: PREFIX80(_6ah); break; \ + case 0x6b: PREFIX80(_6bh); break; \ + case 0x6c: PREFIX80(_6ch); break; \ + case 0x6d: PREFIX80(_6dh); break; \ + case 0x6e: PREFIX80(_6eh); break; \ + case 0x6f: PREFIX80(_6fh); break; \ + case 0x70: PREFIX80(_70h); break; \ + case 0x71: PREFIX80(_71h); break; \ + case 0x72: PREFIX80(_72h); break; \ + case 0x73: PREFIX80(_73h); break; \ + case 0x74: PREFIX80(_74h); break; \ + case 0x75: PREFIX80(_75h); break; \ + case 0x76: PREFIX80(_76h); break; \ + case 0x77: PREFIX80(_77h); break; \ + case 0x78: PREFIX80(_78h); break; \ + case 0x79: PREFIX80(_79h); break; \ + case 0x7a: PREFIX80(_7ah); break; \ + case 0x7b: PREFIX80(_7bh); break; \ + case 0x7c: PREFIX80(_7ch); break; \ + case 0x7d: PREFIX80(_7dh); break; \ + case 0x7e: PREFIX80(_7eh); break; \ + case 0x7f: PREFIX80(_7fh); break; \ + case 0x80: PREFIX80(_80h); break; \ + case 0x81: PREFIX80(_81h); break; \ + case 0x82: PREFIX80(_82h); break; \ + case 0x83: PREFIX80(_83h); break; \ + case 0x84: PREFIX80(_84h); break; \ + case 0x85: PREFIX80(_85h); break; \ + case 0x86: PREFIX80(_86h); break; \ + case 0x87: PREFIX80(_87h); break; \ + case 0x88: PREFIX80(_88h); break; \ + case 0x89: PREFIX80(_89h); break; \ + case 0x8a: PREFIX80(_8ah); break; \ + case 0x8b: PREFIX80(_8bh); break; \ + case 0x8c: PREFIX80(_8ch); break; \ + case 0x8d: PREFIX80(_8dh); break; \ + case 0x8e: PREFIX80(_8eh); break; \ + case 0x8f: PREFIX80(_8fh); break; \ + case 0x90: PREFIX80(_90h); break; \ + case 0x91: PREFIX80(_91h); break; \ + case 0x92: PREFIX80(_92h); break; \ + case 0x93: PREFIX80(_93h); break; \ + case 0x94: PREFIX80(_94h); break; \ + case 0x95: PREFIX80(_95h); break; \ + case 0x96: PREFIX80(_96h); break; \ + case 0x97: PREFIX80(_97h); break; \ + case 0x98: PREFIX80(_98h); break; \ + case 0x99: PREFIX80(_99h); break; \ + case 0x9a: PREFIX80(_9ah); break; \ + case 0x9b: PREFIX80(_9bh); break; \ + case 0x9c: PREFIX80(_9ch); break; \ + case 0x9d: PREFIX80(_9dh); break; \ + case 0x9e: PREFIX80(_9eh); break; \ + case 0x9f: PREFIX80(_9fh); break; \ + case 0xa0: PREFIX80(_a0h); break; \ + case 0xa1: PREFIX80(_a1h); break; \ + case 0xa2: PREFIX80(_a2h); break; \ + case 0xa3: PREFIX80(_a3h); break; \ + case 0xa4: PREFIX80(_a4h); break; \ + case 0xa5: PREFIX80(_a5h); break; \ + case 0xa6: PREFIX80(_a6h); break; \ + case 0xa7: PREFIX80(_a7h); break; \ + case 0xa8: PREFIX80(_a8h); break; \ + case 0xa9: PREFIX80(_a9h); break; \ + case 0xaa: PREFIX80(_aah); break; \ + case 0xab: PREFIX80(_abh); break; \ + case 0xac: PREFIX80(_ach); break; \ + case 0xad: PREFIX80(_adh); break; \ + case 0xae: PREFIX80(_aeh); break; \ + case 0xaf: PREFIX80(_afh); break; \ + case 0xb0: PREFIX80(_b0h); break; \ + case 0xb1: PREFIX80(_b1h); break; \ + case 0xb2: PREFIX80(_b2h); break; \ + case 0xb3: PREFIX80(_b3h); break; \ + case 0xb4: PREFIX80(_b4h); break; \ + case 0xb5: PREFIX80(_b5h); break; \ + case 0xb6: PREFIX80(_b6h); break; \ + case 0xb7: PREFIX80(_b7h); break; \ + case 0xb8: PREFIX80(_b8h); break; \ + case 0xb9: PREFIX80(_b9h); break; \ + case 0xba: PREFIX80(_bah); break; \ + case 0xbb: PREFIX80(_bbh); break; \ + case 0xbc: PREFIX80(_bch); break; \ + case 0xbd: PREFIX80(_bdh); break; \ + case 0xbe: PREFIX80(_beh); break; \ + case 0xbf: PREFIX80(_bfh); break; \ + case 0xc0: PREFIX80(_c0h); break; \ + case 0xc1: PREFIX80(_c1h); break; \ + case 0xc2: PREFIX80(_c2h); break; \ + case 0xc3: PREFIX80(_c3h); break; \ + case 0xc4: PREFIX80(_c4h); break; \ + case 0xc5: PREFIX80(_c5h); break; \ + case 0xc6: PREFIX80(_c6h); break; \ + case 0xc7: PREFIX80(_c7h); break; \ + case 0xc8: PREFIX80(_c8h); break; \ + case 0xc9: PREFIX80(_c9h); break; \ + case 0xca: PREFIX80(_cah); break; \ + case 0xcb: PREFIX80(_cbh); break; \ + case 0xcc: PREFIX80(_cch); break; \ + case 0xcd: PREFIX80(_cdh); break; \ + case 0xce: PREFIX80(_ceh); break; \ + case 0xcf: PREFIX80(_cfh); break; \ + case 0xd0: PREFIX80(_d0h); break; \ + case 0xd1: PREFIX80(_d1h); break; \ + case 0xd2: PREFIX80(_d2h); break; \ + case 0xd3: PREFIX80(_d3h); break; \ + case 0xd4: PREFIX80(_d4h); break; \ + case 0xd5: PREFIX80(_d5h); break; \ + case 0xd6: PREFIX80(_d6h); break; \ + case 0xd7: PREFIX80(_d7h); break; \ + case 0xd8: PREFIX80(_d8h); break; \ + case 0xd9: PREFIX80(_d9h); break; \ + case 0xda: PREFIX80(_dah); break; \ + case 0xdb: PREFIX80(_dbh); break; \ + case 0xdc: PREFIX80(_dch); break; \ + case 0xdd: PREFIX80(_ddh); break; \ + case 0xde: PREFIX80(_deh); break; \ + case 0xdf: PREFIX80(_dfh); break; \ + case 0xe0: PREFIX80(_e0h); break; \ + case 0xe1: PREFIX80(_e1h); break; \ + case 0xe2: PREFIX80(_e2h); break; \ + case 0xe3: PREFIX80(_e3h); break; \ + case 0xe4: PREFIX80(_e4h); break; \ + case 0xe5: PREFIX80(_e5h); break; \ + case 0xe6: PREFIX80(_e6h); break; \ + case 0xe7: PREFIX80(_e7h); break; \ + case 0xe8: PREFIX80(_e8h); break; \ + case 0xe9: PREFIX80(_e9h); break; \ + case 0xea: PREFIX80(_eah); break; \ + case 0xeb: PREFIX80(_ebh); break; \ + case 0xec: PREFIX80(_ech); break; \ + case 0xed: PREFIX80(_edh); break; \ + case 0xee: PREFIX80(_eeh); break; \ + case 0xef: PREFIX80(_efh); break; \ + case 0xf0: PREFIX80(_f0h); break; \ + case 0xf1: PREFIX80(_f1h); break; \ + case 0xf2: PREFIX80(_f2h); break; \ + case 0xf3: PREFIX80(_f3h); break; \ + case 0xf4: PREFIX80(_f4h); break; \ + case 0xf5: PREFIX80(_f5h); break; \ + case 0xf6: PREFIX80(_f6h); break; \ + case 0xf7: PREFIX80(_f7h); break; \ + case 0xf8: PREFIX80(_f8h); break; \ + case 0xf9: PREFIX80(_f9h); break; \ + case 0xfa: PREFIX80(_fah); break; \ + case 0xfb: PREFIX80(_fbh); break; \ + case 0xfc: PREFIX80(_fch); break; \ + case 0xfd: PREFIX80(_fdh); break; \ + case 0xfe: PREFIX80(_feh); break; \ + case 0xff: PREFIX80(_ffh); break; \ + }; +#else +#define TABLE80 PREFIX80(_instruction)[I8080_FETCH8(cpustate)](cpustate); +#endif diff --git a/source/src/vm/mame/emu/cpu/i86/v30.c b/source/src/vm/mame/emu/cpu/i86/v30.c index 151fa544b..ef5d3c4e6 100644 --- a/source/src/vm/mame/emu/cpu/i86/v30.c +++ b/source/src/vm/mame/emu/cpu/i86/v30.c @@ -39,7 +39,8 @@ struct i8086_state INT32 AuxVal, OverVal, SignVal, ZeroVal, CarryVal, DirVal; /* 0 or non-0 valued flags */ UINT8 ParityVal; UINT8 TF, IF; /* 0 or 1 valued flags */ - UINT8 MF; /* V30 mode flag */ + UINT8 MF, MF_WriteDisabled; /* V30 mode flag */ + UINT8 NF; /* 8080 N flag */ UINT8 int_vector; INT8 nmi_state; @@ -65,7 +66,7 @@ struct i8086_state DEVICE *dma; //#endif //#ifdef USE_DEBUGGER - EMU *emu; + EMU_TEMPLATE *emu; DEBUGGER *debugger; DEVICE *program_stored; DEVICE *io_stored; @@ -233,6 +234,8 @@ static CPU_RESET( v30 ) { CPU_RESET_CALL(i8086); SetMD(1); + cpustate->MF = cpustate->MF_WriteDisabled = 1; + cpustate->NF = 0; /* is this correct ? */ } /* ASG 971222 -- added these interface functions */ @@ -355,23 +358,21 @@ CPU_EXECUTE( v30 ) cpustate->io = cpustate->io_stored; } } + int passed_icount; if (icount == -1) { - int passed_icount = max(1, cpustate->extra_cycles); + passed_icount = max(1, cpustate->extra_cycles); // this is main cpu, cpustate->icount is not used - /*cpustate->icount = */cpustate->extra_cycles = 0; -//#ifdef USE_DEBUGGER + cpustate->icount += passed_icount; + cpustate->extra_cycles = 0; cpustate->total_icount += passed_icount; -//#endif - cpu_wait_v30(cpustate, passed_icount); - return passed_icount; +// cpu_wait_v30(cpustate, passed_icount); } else { +#if 0 cpustate->icount += icount; int base_icount = cpustate->icount; - /* adjust for any interrupts that came in */ cpustate->icount -= cpustate->extra_cycles; cpustate->extra_cycles = 0; - /* if busreq is raised, spin cpu while remained clock */ if (cpustate->icount > 0) { cpustate->icount = 0; @@ -381,8 +382,24 @@ CPU_EXECUTE( v30 ) //#endif cpu_wait_v30(cpustate, base_icount - cpustate->icount); return base_icount - cpustate->icount; +#else + int passed_icount = 0; + if(icount > 0) { + passed_icount = icount; + } + if(cpustate->extra_cycles > 0) { + passed_icount += cpustate->extra_cycles; + } + cpustate->icount = 0; + cpustate->extra_cycles = 0; + cpustate->total_icount += passed_icount; +//#endif +// cpu_wait_v30(cpustate, passed_icount); +#endif } + return passed_icount; } + // Not HALTED if (icount == -1) { cpustate->icount = 1; } else { @@ -481,9 +498,11 @@ CPU_EXECUTE( v30 ) cpustate->total_icount += cpustate->icount; //#endif cpustate->icount = 0; + return base_icount; } - cpu_wait_v30(cpustate, base_icount - cpustate->icount); int passed_icount = base_icount - cpustate->icount; + cpu_wait_v30(cpustate, passed_icount); cpustate->icount = 0; return passed_icount; } + diff --git a/source/src/vm/mame/emu/cpu/upd7810/upd7810_common.c b/source/src/vm/mame/emu/cpu/upd7810/upd7810_common.c index 42518f48f..a97b9b135 100644 --- a/source/src/vm/mame/emu/cpu/upd7810/upd7810_common.c +++ b/source/src/vm/mame/emu/cpu/upd7810/upd7810_common.c @@ -497,7 +497,7 @@ struct upd7810_state const struct opcode_s *op64; const struct opcode_s *op70; const struct opcode_s *op74; - void (*handle_timers)(upd7810_state *cpustate, int cycles); + void (__FASTCALL *handle_timers)(upd7810_state *cpustate, int cycles); UPD7810_CONFIG config; // device_irq_acknowledge_callback irq_callback; // legacy_cpu_device *device; @@ -506,7 +506,7 @@ struct upd7810_state void *outputs_to; void *outputs_txd; - EMU *emu; + EMU_TEMPLATE *emu; DEBUGGER *debugger; DEVICE *program_stored; DEVICE *io_stored; diff --git a/source/src/vm/mb8861.h b/source/src/vm/mb8861.h index 96a9c1ed3..b908ec055 100644 --- a/source/src/vm/mb8861.h +++ b/source/src/vm/mb8861.h @@ -7,7 +7,7 @@ class DEBUGGER; class FIFO; //#endif -class MB8861 : public MC6800 +class DLL_PREFIX MB8861 : public MC6800 { private: #define XX 5 // invalid opcode unknown cc @@ -41,7 +41,7 @@ class MB8861 : public MC6800 void __FASTCALL adx_ex(); public: - MB8861(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MC6800(parent_vm, parent_emu) + MB8861(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MC6800(parent_vm, parent_emu) { set_device_name(_T("MB8861 MPU")); } diff --git a/source/src/vm/mb8877.cpp b/source/src/vm/mb8877.cpp index 58b73fe61..baca4acc5 100644 --- a/source/src/vm/mb8877.cpp +++ b/source/src/vm/mb8877.cpp @@ -787,6 +787,7 @@ uint32_t MB8877::read_dma_io8(uint32_t addr) return read_io8(3); } + void MB8877::write_signal(int id, uint32_t data, uint32_t mask) { if(id == SIG_MB8877_DRIVEREG) { diff --git a/source/src/vm/mb8877.h b/source/src/vm/mb8877.h index 6c55661ff..d6f305295 100644 --- a/source/src/vm/mb8877.h +++ b/source/src/vm/mb8877.h @@ -23,7 +23,7 @@ class DISK; class NOISE; -class MB8877 : public DEVICE +class DLL_PREFIX MB8877 : public DEVICE { private: // output signals @@ -148,7 +148,7 @@ class MB8877 : public DEVICE void __FASTCALL set_drq(bool val); public: - MB8877(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MB8877(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_irq); initialize_output_signals(&outputs_drq); @@ -166,6 +166,9 @@ class MB8877 : public DEVICE mb8877_no_busy_after_seek = false; _max_drive = 4; _drive_mask = _max_drive - 1; + for(int i = 0; i < 16; i++) { + disk[i] = NULL; + } //#if defined(HAS_MB89311) // set_device_name(_T("MB89311 FDC")); //#elif defined(HAS_MB8866) @@ -188,7 +191,7 @@ class MB8877 : public DEVICE uint32_t __FASTCALL read_dma_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_config(); bool is_debugger_available() { diff --git a/source/src/vm/mc6800.cpp b/source/src/vm/mc6800.cpp index 18d66a504..a2a16893d 100644 --- a/source/src/vm/mc6800.cpp +++ b/source/src/vm/mc6800.cpp @@ -3,7 +3,7 @@ Origin : MAME 0.142 Author : Takeda.Toshiya - Date : 2011.04.23- + Date : 2011.04.23- [ MC6800 ] */ diff --git a/source/src/vm/mc6800.h b/source/src/vm/mc6800.h index 6778df6f3..5ddfa0ffb 100644 --- a/source/src/vm/mc6800.h +++ b/source/src/vm/mc6800.h @@ -3,7 +3,7 @@ Origin : MAME 0.142 Author : Takeda.Toshiya - Date : 2011.04.23- + Date : 2011.04.23- [ MC6800 ] */ @@ -31,7 +31,7 @@ class DEBUGGER; //#endif -class MC6800 : public DEVICE +class DLL_PREFIX MC6800 : public DEVICE { private: @@ -307,19 +307,22 @@ class MC6800 : public DEVICE bool __USE_DEBUGGER; public: - MC6800(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MC6800(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_mem = NULL; d_debugger = NULL; d_mem_stored = NULL; __USE_DEBUGGER = false; -//#if defined(HAS_MC6801) || defined(HAS_HD6301) -// for(int i = 0; i < 4; i++) { -// initialize_output_signals(&port[i].outputs); -// port[i].wreg = port[i].rreg = 0;//0xff; -// } + for(int i = 0; i < 4; i++) { + initialize_output_signals(&port[i].outputs); + port[i].ddr = 0; + port[i].latched_data = 0; + port[i].latched = false; + port[i].first_write = false; + port[i].wreg = port[i].rreg = 0;//0xff; + } + memset(ram, 0x00, sizeof(ram)); // initialize_output_signals(&outputs_sio); -//#endif //#if defined(HAS_MC6801) // set_device_name(_T("MC6801 MPU")); //#elif defined(HAS_HD6301) @@ -331,6 +334,17 @@ class MC6800 : public DEVICE ~MC6800() {} // common functions + struct { + uint8_t wreg; + uint8_t rreg; + uint8_t ddr; + uint8_t latched_data; + bool latched; + outputs_t outputs; + bool first_write; + } port[4]; + uint8_t ram[128]; + virtual void initialize(); virtual void reset(); virtual int __FASTCALL run(int clock); diff --git a/source/src/vm/mc6801.h b/source/src/vm/mc6801.h index 36e0382c2..a9473375b 100644 --- a/source/src/vm/mc6801.h +++ b/source/src/vm/mc6801.h @@ -28,7 +28,7 @@ class DEBUGGER; class FIFO; //#endif -class MC6801 : public MC6800 +class DLL_PREFIX MC6801 : public MC6800 { private: protected: @@ -56,17 +56,7 @@ class MC6801 : public MC6800 #undef XX //#if defined(HAS_MC6801) || defined(HAS_HD6301) // data - struct { - uint8_t wreg; - uint8_t rreg; - uint8_t ddr; - uint8_t latched_data; - bool latched; - // output signals - outputs_t outputs; - bool first_write; - } port[4]; - + uint8_t p3csr; bool p3csr_is3_flag_read; bool sc1_state; @@ -94,9 +84,7 @@ class MC6801 : public MC6800 // memory controller uint8_t ram_ctrl; - uint8_t ram[128]; - uint32_t __FASTCALL mc6801_io_r(uint32_t offset); virtual void __FASTCALL mc6801_io_w(uint32_t offset, uint32_t data); void __FASTCALL increment_counter(int amount); @@ -136,7 +124,7 @@ class MC6801 : public MC6800 //#endif public: - MC6801(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MC6800(parent_vm, parent_emu) + MC6801(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MC6800(parent_vm, parent_emu) { for(int i = 0; i < 4; i++) { initialize_output_signals(&port[i].outputs); diff --git a/source/src/vm/mc6809.cpp b/source/src/vm/mc6809.cpp index 16b03ff8f..cefd47a81 100644 --- a/source/src/vm/mc6809.cpp +++ b/source/src/vm/mc6809.cpp @@ -16,126 +16,3949 @@ // Fixed IRQ/FIRQ by Mr.Sasaji at 2011.06.17 -#include "vm.h" -#include "../emu.h" -#include "mc6809.h" -#include "mc6809_consts.h" +//#include "vm.h" +//#include "../emu.h" +#include "./mc6809.h" +#include "./mc6809_consts.h" +#include "common.h" #include "debugger.h" #include "config.h" +#define OP_HANDLER(_name) void MC6809::_name (void) + +void (__FASTCALL MC6809::*MC6809::m6809_optable[0x100]) (void) = +{ +/* 0xX0, 0xX1, 0xX2, 0xX3, 0xX4, 0xX5, 0xX6, 0xX7, + 0xX8, 0xX9, 0xXA, 0xXB, 0xXC, 0xXD, 0xXE, 0xXF */ + +/* 0x0X */ + &MC6809::neg_di, &MC6809::neg_di, &MC6809::ngc_di, &MC6809::com_di, + &MC6809::lsr_di, &MC6809::lsr_di, &MC6809::ror_di, &MC6809::asr_di, + &MC6809::asl_di, &MC6809::rol_di, &MC6809::dec_di, &MC6809::dcc_di, + &MC6809::inc_di, &MC6809::tst_di, &MC6809::jmp_di, &MC6809::clr_di, +/* 0x1X */ + &MC6809::pref10, &MC6809::pref11, &MC6809::nop, &MC6809::sync_09, + &MC6809::trap, &MC6809::trap, &MC6809::lbra, &MC6809::lbsr, + &MC6809::aslcc_in, &MC6809::daa, &MC6809::orcc, &MC6809::nop, + &MC6809::andcc, &MC6809::sex, &MC6809::exg, &MC6809::tfr, +/* 0x2X */ + &MC6809::bra, &MC6809::brn, &MC6809::bhi, &MC6809::bls, + &MC6809::bcc, &MC6809::bcs, &MC6809::bne, &MC6809::beq, + &MC6809::bvc, &MC6809::bvs, &MC6809::bpl, &MC6809::bmi, + &MC6809::bge, &MC6809::blt, &MC6809::bgt, &MC6809::ble, +/* 0x3X */ + &MC6809::leax, &MC6809::leay, &MC6809::leas, &MC6809::leau, + &MC6809::pshs, &MC6809::puls, &MC6809::pshu, &MC6809::pulu, + &MC6809::andcc, &MC6809::rts, &MC6809::abx, &MC6809::rti, + &MC6809::cwai, &MC6809::mul, &MC6809::rst, &MC6809::swi, +/* 0x4X */ + &MC6809::nega, &MC6809::nega, &MC6809::ngca, &MC6809::coma, + &MC6809::lsra, &MC6809::lsra, &MC6809::rora, &MC6809::asra, + &MC6809::asla, &MC6809::rola, &MC6809::deca, &MC6809::dcca, + &MC6809::inca, &MC6809::tsta, &MC6809::clca, &MC6809::clra, +/* 0x5X */ + &MC6809::negb, &MC6809::negb, &MC6809::ngcb, &MC6809::comb, + &MC6809::lsrb, &MC6809::lsrb, &MC6809::rorb, &MC6809::asrb, + &MC6809::aslb, &MC6809::rolb, &MC6809::decb, &MC6809::dccb, + &MC6809::incb, &MC6809::tstb, &MC6809::clcb, &MC6809::clrb, +/* 0x6X */ + &MC6809::neg_ix, &MC6809::neg_ix, &MC6809::ngc_ix, &MC6809::com_ix, + &MC6809::lsr_ix, &MC6809::lsr_ix, &MC6809::ror_ix, &MC6809::asr_ix, + &MC6809::asl_ix, &MC6809::rol_ix, &MC6809::dec_ix, &MC6809::dcc_ix, + &MC6809::inc_ix, &MC6809::tst_ix, &MC6809::jmp_ix, &MC6809::clr_ix, +/* 0x7X */ + &MC6809::neg_ex, &MC6809::neg_ex, &MC6809::ngc_ex, &MC6809::com_ex, + &MC6809::lsr_ex, &MC6809::lsr_ex, &MC6809::ror_ex, &MC6809::asr_ex, + &MC6809::asl_ex, &MC6809::rol_ex, &MC6809::dec_ex, &MC6809::dcc_ex, + &MC6809::inc_ex, &MC6809::tst_ex, &MC6809::jmp_ex, &MC6809::clr_ex, +/* 0x8X */ + &MC6809::suba_im, &MC6809::cmpa_im, &MC6809::sbca_im, &MC6809::subd_im, + &MC6809::anda_im, &MC6809::bita_im, &MC6809::lda_im, &MC6809::flag8_im, + &MC6809::eora_im, &MC6809::adca_im, &MC6809::ora_im, &MC6809::adda_im, + &MC6809::cmpx_im, &MC6809::bsr, &MC6809::ldx_im, &MC6809::flag16_im, +/* 0x9X */ + &MC6809::suba_di, &MC6809::cmpa_di, &MC6809::sbca_di, &MC6809::subd_di, + &MC6809::anda_di, &MC6809::bita_di, &MC6809::lda_di, &MC6809::sta_di, + &MC6809::eora_di, &MC6809::adca_di, &MC6809::ora_di, &MC6809::adda_di, + &MC6809::cmpx_di, &MC6809::jsr_di, &MC6809::ldx_di, &MC6809::stx_di, +/* 0xAX */ + &MC6809::suba_ix, &MC6809::cmpa_ix, &MC6809::sbca_ix, &MC6809::subd_ix, + &MC6809::anda_ix, &MC6809::bita_ix, &MC6809::lda_ix, &MC6809::sta_ix, + &MC6809::eora_ix, &MC6809::adca_ix, &MC6809::ora_ix, &MC6809::adda_ix, + &MC6809::cmpx_ix, &MC6809::jsr_ix, &MC6809::ldx_ix, &MC6809::stx_ix, +/* 0xBX */ + &MC6809::suba_ex, &MC6809::cmpa_ex, &MC6809::sbca_ex, &MC6809::subd_ex, + &MC6809::anda_ex, &MC6809::bita_ex, &MC6809::lda_ex, &MC6809::sta_ex, + &MC6809::eora_ex, &MC6809::adca_ex, &MC6809::ora_ex, &MC6809::adda_ex, + &MC6809::cmpx_ex, &MC6809::jsr_ex, &MC6809::ldx_ex, &MC6809::stx_ex, +/* 0xCX */ + &MC6809::subb_im, &MC6809::cmpb_im, &MC6809::sbcb_im, &MC6809::addd_im, + &MC6809::andb_im, &MC6809::bitb_im, &MC6809::ldb_im, &MC6809::flag8_im, + &MC6809::eorb_im, &MC6809::adcb_im, &MC6809::orb_im, &MC6809::addb_im, + &MC6809::ldd_im, &MC6809::trap, &MC6809::ldu_im, &MC6809::flag16_im, +/* 0xDX */ + &MC6809::subb_di, &MC6809::cmpb_di, &MC6809::sbcb_di, &MC6809::addd_di, + &MC6809::andb_di, &MC6809::bitb_di, &MC6809::ldb_di, &MC6809::stb_di, + &MC6809::eorb_di, &MC6809::adcb_di, &MC6809::orb_di, &MC6809::addb_di, + &MC6809::ldd_di, &MC6809::std_di, &MC6809::ldu_di, &MC6809::stu_di, +/* 0xEX */ + &MC6809::subb_ix, &MC6809::cmpb_ix, &MC6809::sbcb_ix, &MC6809::addd_ix, + &MC6809::andb_ix, &MC6809::bitb_ix, &MC6809::ldb_ix, &MC6809::stb_ix, + &MC6809::eorb_ix, &MC6809::adcb_ix, &MC6809::orb_ix, &MC6809::addb_ix, + &MC6809::ldd_ix, &MC6809::std_ix, &MC6809::ldu_ix, &MC6809::stu_ix, +/* 0xFX */ + &MC6809::subb_ex, &MC6809::cmpb_ex, &MC6809::sbcb_ex, &MC6809::addd_ex, + &MC6809::andb_ex, &MC6809::bitb_ex, &MC6809::ldb_ex, &MC6809::stb_ex, + &MC6809::eorb_ex, &MC6809::adcb_ex, &MC6809::orb_ex, &MC6809::addb_ex, + &MC6809::ldd_ex, &MC6809::std_ex, &MC6809::ldu_ex, &MC6809::stu_ex +}; + +/* macros for branch instructions */ +inline void MC6809::BRANCH(bool cond) +{ + uint8_t t; + IMMBYTE(t); + if(!cond) return; + PC = PC + SIGNED(t); + PC = PC & 0xffff; +} + +inline void MC6809::LBRANCH(bool cond) +{ + pair32_t t; + IMMWORD(t); + if(!cond) return; + icount -= 1; + PC += t.w.l; + PC = PC & 0xffff; +} + +/* macros for setting/getting registers in TFR/EXG instructions */ + +inline pair32_t MC6809::RM16_PAIR(uint32_t addr) +{ + pair32_t b; + b.d = 0; + b.b.h = RM(addr); + b.b.l = RM((addr + 1)); + return b; +} + +inline void MC6809::WM16(uint32_t Addr, pair32_t *p) +{ + WM(Addr , p->b.h); + WM((Addr + 1), p->b.l); +} + +void MC6809::reset() +{ + //extar_tmp_count += extra_icount; + + icount = 0; + waitcount = 0; + int_state &= MC6809_HALT_BIT; + extra_icount = 0; + //busreq = false; + + DPD = 0; /* Reset direct page register */ + CC = 0; + D = 0; + X = 0; + Y = 0; + U = 0; + S = 0; + EA = 0; +//#if defined(_FM7) || defined(_FM8) || defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS) + + if((req_halt_on) && !(req_halt_off)) { + int_state |= MC6809_HALT_BIT; + } else { + req_halt_on = req_halt_off = false; + } + if((int_state & MC6809_HALT_BIT) != 0) { + write_signals(&outputs_bus_ba, 0xffffffff); + write_signals(&outputs_bus_bs, 0xffffffff); + } else { + write_signals(&outputs_bus_ba, 0x00000000); + write_signals(&outputs_bus_bs, 0x00000000); + } + +//#endif + CC |= CC_II; /* IRQ disabled */ + CC |= CC_IF; /* FIRQ disabled */ + + pPC = RM16_PAIR(0xfffe); +} + + + void MC6809::initialize() { - MC6809_BASE::initialize(); + DEVICE::initialize(); int_state = 0; busreq = false; + icount = 0; + extra_icount = 0; + req_halt_on = req_halt_off = false; + cycles_tmp_count = 0; + insns_count = 0; + + __USE_DEBUGGER = osd->check_feature(_T("USE_DEBUGGER")); + insns_count = 0; + frames_count = 0; + cycles_tmp_count = 0; + nmi_count = 0; + firq_count = 0; + irq_count = 0; +// if(config.print_statistics) { + register_frame_event(this); +// } + waitfactor = 0; + waitcount = 0; + // Updata insn table + void (__FASTCALL MC6809::*_op)(void); + for(int i = 0; i < 0x100; i++) { + _op = (void (__FASTCALL MC6809::*)(void))m6809_optable[i]; + m6809_main[i] = _op; + } + if(__USE_DEBUGGER) { + d_mem_stored = d_mem; + d_debugger->set_context_mem(d_mem); + } + +} + +void MC6809::event_frame() +{ + if(frames_count < 0) { + cycles_tmp_count = total_icount; + extra_tmp_count = 0; + insns_count = 0; + frames_count = 0; + nmi_count = 0; + firq_count = 0; + irq_count = 0; + } else if(frames_count >= 16) { + uint64_t _icount = total_icount - cycles_tmp_count; + if(config.print_statistics) { + out_debug_log(_T("INFO: 16 frames done.\nINFO: CLOCKS = %ld INSNS = %d EXTRA_ICOUNT = %d \nINFO: NMI# = %d FIRQ# = %d IRQ# = %d"), _icount, insns_count, extra_tmp_count, nmi_count, firq_count, irq_count); + } + cycles_tmp_count = total_icount; + insns_count = 0; + extra_tmp_count = 0; + frames_count = 0; + nmi_count = 0; + firq_count = 0; + irq_count = 0; + } else { + frames_count++; + } +} + +void MC6809::write_signal(int id, uint32_t data, uint32_t mask) +{ + if(id == SIG_CPU_IRQ) { + if(data & mask) { + int_state |= MC6809_IRQ_BIT; + irq_count++; + } else { + int_state &= ~MC6809_IRQ_BIT; + } + } else if(id == SIG_CPU_FIRQ) { + if(data & mask) { + int_state |= MC6809_FIRQ_BIT; + firq_count++; + } else { + int_state &= ~MC6809_FIRQ_BIT; + } + } else if(id == SIG_CPU_NMI) { + if(data & mask) { + int_state |= MC6809_NMI_BIT; + nmi_count++; + } else { + int_state &= ~MC6809_NMI_BIT; + } + } else if(id == SIG_CPU_BUSREQ) { + if(data & mask) { + req_halt_on = false; + req_halt_off = false; + int_state |= MC6809_HALT_BIT; + busreq = false; + } else { + req_halt_on = false; + req_halt_off = false; + int_state &= ~MC6809_HALT_BIT; + } + } else if(id == SIG_CPU_HALTREQ) { + if(data & mask) { + req_halt_on = true; + //int_state |= MC6809_HALT_BIT; + } else { + if(req_halt_on) { + req_halt_off = true; + } + //int_state &= ~MC6809_HALT_BIT; + } + } else if(id == SIG_CPU_WAIT_FACTOR) { + waitfactor = data; // 65536. + } +} + +void MC6809::cpu_nmi_push(void) +{ + if ((int_state & MC6809_CWAI_IN) == 0) { + CC |= CC_E; + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + } + return; +} + +void MC6809::cpu_nmi_fetch_vector_address(void) +{ + pPC = RM16_PAIR(0xfffc); +// printf("NMI occured PC=0x%04x VECTOR=%04x SP=%04x \n",rpc.w.l,pPC.w.l,S); + int_state |= MC6809_CWAI_OUT; + //int_state &= ~(MC6809_NMI_BIT | MC6809_SYNC_IN | MC6809_SYNC_OUT | MC6809_CWAI_IN); // $FF1E + return; +} + + + +void MC6809::cpu_firq_fetch_vector_address(void) +{ + pPC = RM16_PAIR(0xfff6); + int_state |= MC6809_CWAI_OUT; + int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT ); + return; +} + +void MC6809::cpu_firq_push(void) +{ + //pair32_t rpc = pPC; + if ((int_state & MC6809_CWAI_IN) == 0) { + /* NORMAL */ + CC &= ~CC_E; + PUSHWORD(pPC); + PUSHBYTE(CC); + } +// printf("Firq occured PC=0x%04x VECTOR=%04x SP=%04x \n",rpc.w.l,pPC.w.l,S); +} +void MC6809::cpu_irq_push(void) +{ + if ((int_state & MC6809_CWAI_IN) == 0) { + CC |= CC_E; + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + } +} +void MC6809::cpu_irq_fetch_vector_address(void) +{ + //pair32_t rpc = pPC; + pPC = RM16_PAIR(0xfff8); + int_state |= MC6809_CWAI_OUT; + int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT); +} + +void MC6809::cpu_wait(int clocks) +{ + uint32_t ncount = 0; + if(clocks < 0) return; + if(waitfactor == 0) return; + waitcount += (waitfactor * (uint32_t)clocks); + if(waitcount >= 65536) { + ncount = waitcount >> 16; + waitcount = waitcount - (ncount << 16); + } + if(ncount > 0) extra_icount += ncount; +} + +int MC6809::run(int clock) +{ + int cycle = 0; + int first_icount = 0; + int passed_icount = 0; + first_icount = icount; + if(extra_icount > 0) { + extra_tmp_count += extra_icount; + } + + if((req_halt_on) && !(req_halt_off)) { + int_state |= MC6809_HALT_BIT; + } else if(req_halt_on && req_halt_off) { // HALT OFF + int_state &= ~MC6809_HALT_BIT; + req_halt_on = req_halt_off = false; + } + + if ((int_state & MC6809_HALT_BIT) != 0) { // 0x80 + if(clock <= 0) { + clock = 1; + } else { + icount += clock; + } + first_icount = icount; + if(!busreq) { + write_signals(&outputs_bus_ba, 0); + write_signals(&outputs_bus_bs, 0); + busreq = true; + icount -= clock; + icount -= extra_icount; + extra_icount = 0; + passed_icount = first_icount - icount; + total_icount += passed_icount; + + write_signals(&outputs_bus_ba, 0xffffffff); + write_signals(&outputs_bus_bs, 0xffffffff); + debugger_hook(); + cpu_wait(passed_icount); + return passed_icount; + } else { + icount -= clock; + icount -= extra_icount; + extra_icount = 0; + passed_icount = first_icount - icount; + total_icount += passed_icount; + debugger_hook(); + cpu_wait(passed_icount); + return passed_icount; + } + } + if(busreq) { // Exit from BUSREQ state. + if((int_state & MC6809_SYNC_IN) != 0) { + write_signals(&outputs_bus_ba, 0xffffffff); + } else { + write_signals(&outputs_bus_ba, 0x00000000); + } + write_signals(&outputs_bus_bs, 0x00000000); + busreq = false; + } + if((int_state & MC6809_INSN_HALT) != 0) { // 0x80 + if(clock <= 1) clock = 1; + icount += clock; + first_icount = icount; + while(icount > 0) { + RM(PCD); //Will save.Need to keep. + icount -= 1; + } + icount -= extra_icount; + passed_icount = first_icount - icount; + extra_icount = 0; + PC++; + debugger_hook(); + total_icount += passed_icount; + cpu_wait(passed_icount); + return passed_icount; + } + /* + * Check Interrupt + */ +check_nmi: + if ((int_state & (MC6809_NMI_BIT | MC6809_FIRQ_BIT | MC6809_IRQ_BIT)) != 0) { // 0x0007 + if ((int_state & MC6809_NMI_BIT) == 0) + goto check_firq; + int_state &= ~MC6809_SYNC_IN; // Thanks to Ryu Takegami. + write_signals(&outputs_bus_ba, 0x00000000); + write_signals(&outputs_bus_bs, 0x00000000); + if((int_state & MC6809_CWAI_IN) == 0) { + CC = CC | CC_E; + cycle += 14; + cpu_nmi_push(); + } + write_signals(&outputs_bus_bs, 0xffffffff); + CC = CC | CC_II | CC_IF; // 0x50 + cycle += 2; + cpu_nmi_fetch_vector_address(); + cycle += 3; + write_signals(&outputs_bus_bs, 0x00000000); + int_state &= ~(MC6809_NMI_BIT | MC6809_SYNC_IN | MC6809_SYNC_OUT); // $FF1E + goto int_cycle; + } else { + // OK, none interrupts. + goto check_ok; + } +check_firq: + if ((int_state & MC6809_FIRQ_BIT) != 0) { + int_state &= ~MC6809_SYNC_IN; // Moved to before checking MASK.Thanks to Ryu Takegami. + if ((CC & CC_IF) != 0) + goto check_irq; + write_signals(&outputs_bus_bs, 0x00000000); + write_signals(&outputs_bus_ba, 0x00000000); + if((int_state & MC6809_CWAI_IN) == 0) { + CC = CC & (uint8_t)(~CC_E); + cycle += 5; + cpu_firq_push(); + } + write_signals(&outputs_bus_bs, 0xffffffff); + CC = CC | CC_II | CC_IF; // 0x50 + cycle += 2; + cpu_firq_fetch_vector_address(); + cycle += 3; + write_signals(&outputs_bus_bs, 0x00000000); + int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT); // $FF1E + goto int_cycle; + + } +check_irq: + if ((int_state & MC6809_IRQ_BIT) != 0) { + int_state &= ~MC6809_SYNC_IN; // Moved to before checking MASK.Thanks to Ryu Takegami. + if ((CC & CC_II) != 0) + goto check_ok; + write_signals(&outputs_bus_bs, 0x00000000); + write_signals(&outputs_bus_ba, 0x00000000); + if((int_state & MC6809_CWAI_IN) == 0) { + CC = CC | CC_E; + cycle += 14; + cpu_irq_push(); + } + write_signals(&outputs_bus_bs, 0xffffffff); + cycle += 2; + CC = CC | CC_II; // 0x50 + cpu_irq_fetch_vector_address(); + cycle += 3; + write_signals(&outputs_bus_bs, 0x00000000); + int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT); // $FF1E + goto int_cycle; + } + /* + * NO INTERRUPT + */ + goto check_ok; + /* + * INTERRUPT + */ +int_cycle: + if((int_state & MC6809_CWAI_IN) != 0) { + int_state &= ~MC6809_CWAI_IN; + } + if(clock >= 0) icount += clock; + first_icount = icount; + icount -= cycle; + debugger_hook(); + icount -= extra_icount; + passed_icount = first_icount - icount; + extra_icount = 0; + total_icount += (uint64_t)passed_icount; + cpu_wait(passed_icount); +#if 1 + if((icount <= 0) || (clock <= passed_icount)) return passed_icount; + clock -= passed_icount; +#else + return passed_icount; +#endif + // goto check_ok; + // run cpu +check_ok: + if((int_state & MC6809_SYNC_IN) != 0) { + int tmp_passed_icount = 0; + first_icount = icount; + if(clock < 1) clock = 1; + icount -= extra_icount; + icount -= clock; + extra_icount = 0; + debugger_hook(); + tmp_passed_icount = first_icount - icount; + total_icount += (uint64_t)passed_icount; + cpu_wait(tmp_passed_icount); + return passed_icount + tmp_passed_icount; + } + if((int_state & MC6809_CWAI_IN) == 0) { + if(clock <= -1) { + // run only one opcode + int tmp_passed_icount = 0; + first_icount = icount; + insns_count++; + run_one_opecode(); + tmp_passed_icount = first_icount - icount; + cpu_wait(tmp_passed_icount); + return passed_icount + tmp_passed_icount;; + } else { + // run cpu while given clocks + int tmp_passed_icount = 0; + icount += clock; + first_icount = icount; + while((icount > 0) && (!(req_halt_on) && !(req_halt_off)) && (!busreq)) { + insns_count++; + run_one_opecode(); + } + tmp_passed_icount = first_icount - icount; + cpu_wait(tmp_passed_icount); + return tmp_passed_icount + passed_icount; + } + } else { // CWAI_IN + int tmp_passed_icount = 0; + first_icount = icount; + if(clock < 1) clock = 1; + icount -= extra_icount; + icount -= clock; + extra_icount = 0; + debugger_hook(); + tmp_passed_icount = first_icount - icount; + total_icount += tmp_passed_icount; + cpu_wait(tmp_passed_icount); + return passed_icount + tmp_passed_icount; + } + +} + +void MC6809::run_one_opecode() +{ + if(__USE_DEBUGGER) { + bool now_debugging = d_debugger->now_debugging; + if(now_debugging) { + d_debugger->check_break_points(PC); + if(d_debugger->now_suspended) { + d_debugger->now_waiting = true; + emu->start_waiting_in_debugger(); + while(d_debugger->now_debugging && d_debugger->now_suspended) { + emu->process_waiting_in_debugger(); + } + emu->finish_waiting_in_debugger(); + d_debugger->now_waiting = false; + } + if(d_debugger->now_debugging) { + d_mem = d_debugger; + } else { + now_debugging = false; + } + + d_debugger->add_cpu_trace(PC & 0xffff); + int first_icount = icount; + pPPC = pPC; + uint8_t ireg = ROP(PCD); + PC++; + icount -= cycles1[ireg]; + icount -= extra_icount; + extra_icount = 0; + op(ireg); + total_icount += first_icount - icount; + + if(now_debugging) { + if(!d_debugger->now_going) { + d_debugger->now_suspended = true; + } + d_mem = d_mem_stored; + } + } else { + d_debugger->add_cpu_trace(PC & 0xffff); + int first_icount = icount; + pPPC = pPC; + uint8_t ireg = ROP(PCD); + PC++; + icount -= cycles1[ireg]; + icount -= extra_icount; + extra_icount = 0; + op(ireg); + total_icount += first_icount - icount; + } + } else { + pPPC = pPC; + d_debugger->add_cpu_trace(PC & 0xffff); + uint8_t ireg = ROP(PCD); + PC++; + icount -= cycles1[ireg]; + icount -= extra_icount; + extra_icount = 0; + op(ireg); + } +} + +void MC6809::debugger_hook() +{ + if(__USE_DEBUGGER) { + bool now_debugging = d_debugger->now_debugging; + if(now_debugging) { + d_debugger->check_break_points(PC); + if(d_debugger->now_suspended) { + d_debugger->now_waiting = true; + emu->start_waiting_in_debugger(); + while(d_debugger->now_debugging && d_debugger->now_suspended) { + emu->process_waiting_in_debugger(); + } + emu->finish_waiting_in_debugger(); + d_debugger->now_waiting = false; + } + if(d_debugger->now_debugging) { + d_mem = d_debugger; + } else { + now_debugging = false; + } + + //d_debugger->add_cpu_trace(PC); + int first_icount = icount; + //pPPC = pPC; + if(now_debugging) { + if(!d_debugger->now_going) { + d_debugger->now_suspended = true; + } + d_mem = d_mem_stored; + } + } + } +} + +void MC6809::op(uint8_t ireg) +{ + //printf("CPU(%08x) PC=%04x OP=%02x %02x %02x %02x %02x\n", (void *)this, PC, ireg, RM(PC), RM(PC + 1), RM(PC + 2), RM(PC + 3)); + + (this->*m6809_main[ireg])(); +} + + +void MC6809::write_debug_data8(uint32_t addr, uint32_t data) +{ + if(__USE_DEBUGGER) d_mem_stored->write_data8(addr, data); +} + +uint32_t MC6809::read_debug_data8(uint32_t addr) +{ + if(__USE_DEBUGGER) { + return d_mem_stored->read_data8(addr); + } + return 0xff; +} + +void MC6809::write_debug_io8(uint32_t addr, uint32_t data) +{ + if(__USE_DEBUGGER) d_mem_stored->write_io8(addr, data); +} + +uint32_t MC6809::read_debug_io8(uint32_t addr) +{ + if(__USE_DEBUGGER) { + uint8_t val = d_mem_stored->read_io8(addr); + return val; + } + return 0xff; +} + +inline void MC6809::fetch_effective_address() +{ + uint8_t postbyte; + uint8_t upper, lower; + + IMMBYTE(postbyte); + + upper = (postbyte >> 4) & 0x0f; + lower = postbyte & 0x0f; + switch (upper) { + case 0x00: + EA = X + lower; + break; + case 0x01: + EA = X - 16 + lower; + break; + case 0x02: + EA = Y + lower; + break; + case 0x03: + EA = Y - 16 + lower; + break; + case 0x04: + EA = U + lower; + break; + case 0x05: + EA = U - 16 + lower; + break; + case 0x06: + EA = S + lower; + break; + case 0x07: + EA = S - 16 + lower; + break; + default: + fetch_effective_address_IDX(upper, lower); + break; + } + EAD &= 0xffff; + icount -= index_cycle_em[postbyte]; +} + +inline void MC6809::fetch_effective_address_IDX(uint8_t upper, uint8_t lower) +{ + bool indirect = false; + uint16_t *reg; + uint8_t bx_p; + pair32_t pp; + + indirect = ((upper & 0x01) != 0) ? true : false; + + switch ((upper >> 1) & 0x03) { // $8-$f >> 1 = $4 - $7 : delete bit2 + case 0: // $8x,$9x + reg = &X; + break; + case 1: // $ax,$bx + reg = &Y; + break; + case 2: // $cx,$dx + reg = &U; + break; + case 3: // $ex,$fx + reg = &S; + break; + } + + switch (lower) { + case 0: // ,r+ + EA = *reg; + *reg = *reg + 1; + *reg = *reg & 0xffff; + break; + case 1: // ,r++ + EA = *reg; + *reg = *reg + 2; + *reg = *reg & 0xffff; + break; + case 2: // ,-r + *reg = *reg - 1; + *reg = *reg & 0xffff; + EA = *reg; + break; + case 3: // ,--r + *reg = *reg - 2; + *reg = *reg & 0xffff; + EA = *reg; + break; + case 4: // ,r + EA = *reg; + break; + case 5: // b,r + EA = *reg + SIGNED(B); + break; + case 6: // a,r + case 7: + EA = *reg + SIGNED(A); + break; + case 8: // $xx,r + IMMBYTE(bx_p); + EA = *reg + SIGNED(bx_p); + break; + case 9: // $xxxx, r + IMMWORD(EAP); + EA = EA + *reg; + break; + case 0x0a: // Undocumented + EA = PC; + EA++; + EAP.w.l |= 0x00ff; + break; + case 0x0b: // D,r + EA = *reg + D; + break; + case 0x0c: // xx,pc + IMMBYTE(bx_p); + EA = PC + SIGNED(bx_p); + break; + case 0x0d: // xxxx,pc + IMMWORD(EAP); + EA = EA + PC; + break; + case 0x0e: // Undocumented + EA = 0xffff; + break; + case 0x0f: + IMMWORD(EAP); + break; + } + EAP.w.h = 0x0000; + // $9x,$bx,$dx,$fx = INDIRECT + if (indirect) { + pp = EAP; + EAP = RM16_PAIR(pp.d); + } +} + +#define IIError() illegal() + +OP_HANDLER(illegal) +{ + //logerror("M6809: illegal opcode at %04x\n",PC); + //printf("M6809: illegal opcode at %04x %02x %02x %02x %02x %02x \n", + // PC - 2, RM(PC - 2), RM(PC - 1), RM(PC), RM(PC + 1), RM(PC + 2)); +// PC-=1; +} + +inline uint8_t MC6809::GET_INDEXED_DATA(void) +{ + uint8_t t; + fetch_effective_address(); + t = RM(EAD); + return t; +} + +inline pair32_t MC6809::GET_INDEXED_DATA16(void) +{ + pair32_t t; + fetch_effective_address(); + t = RM16_PAIR(EAD); + return t; +} + +// $x0, $x1 +inline void MC6809::NEG_MEM(uint8_t a_neg) +{ + uint16_t r_neg; + r_neg = 0 - (uint16_t)a_neg; + CLR_NZVC; + SET_FLAGS8(0, a_neg, r_neg); + WM(EAD, r_neg); +} + +inline uint8_t MC6809::NEG_REG(uint8_t a_neg) +{ + uint16_t r_neg; + r_neg = 0 - (uint16_t)a_neg; + CLR_NZVC; + SET_FLAGS8(0, a_neg, r_neg); + return (uint8_t)r_neg; +} + + +// $x2 +inline void MC6809::COM_MEM(uint8_t a_com) +{ + uint8_t t_com; + t_com = ~a_com; + CLR_NZVC; + SET_NZ8(t_com); + SEC; + WM(EAD, t_com); +} + +inline uint8_t MC6809::COM_REG(uint8_t r_com) +{ + r_com = ~r_com; + CLR_NZVC; + SET_NZ8(r_com); + SEC; + return r_com; +} + +inline void MC6809::LSR_MEM(uint8_t t) +{ + CLR_NZC; + CC = CC | (t & CC_C); + t >>= 1; + SET_NZ8(t); + WM(EAD, t); +} + +inline uint8_t MC6809::LSR_REG(uint8_t r) +{ + CLR_NZC; + CC |= (r & CC_C); + r >>= 1; + SET_NZ8(r); + return r; +} + +inline void MC6809::ROR_MEM(uint8_t t) +{ + uint8_t r; + r = (CC & CC_C) << 7; + CLR_NZC; + CC |= (t & CC_C); + t >>= 1; + r |= t; + SET_NZ8(r); //NZ8? + WM(EAD, r); +} + +inline uint8_t MC6809::ROR_REG(uint8_t t) +{ + uint8_t r; + r = (CC & CC_C) << 7; + CLR_NZC; + CC |= (t & CC_C); + t >>= 1; + r |= t; + SET_NZ8(r); //NZ8? + return r; +} + + +inline void MC6809::ASR_MEM(uint8_t t) +{ + uint8_t r; + CLR_NZC; + CC = CC | (t & CC_C); + r = (t & 0x80) | (t >> 1); + // H is undefined + SET_NZ8(r); + //SET_H(t, t, r); + WM(EAD, r); +} + +inline uint8_t MC6809::ASR_REG(uint8_t t) +{ + uint8_t r; + CLR_NZC; + CC = CC | (t & CC_C); + r = (t & 0x80) | (t >> 1); + // H is undefined + SET_NZ8(r); + //SET_H(t, t, r); + return r; +} + +inline void MC6809::ASL_MEM(uint8_t t) +{ + uint16_t r, tt; + tt = (uint16_t)t & 0x00ff; + r = tt << 1; + CLR_NZVC; + SET_FLAGS8(tt, tt, r); + //SET_H(tt, tt, r); + WM(EAD, (uint8_t)r); +} + +inline uint8_t MC6809::ASL_REG(uint8_t t) +{ + uint16_t r, tt; + tt = (uint16_t)t & 0x00ff; + r = tt << 1; + CLR_NZVC; + SET_FLAGS8(tt, tt, r); + //SET_H(tt, tt, r); + return (uint8_t)r; +} + +inline void MC6809::ROL_MEM(uint8_t t) +{ + uint16_t r, tt; + tt = (uint16_t)t & 0x00ff; + r = (CC & CC_C) | (tt << 1); + CLR_NZVC; + //SET_NZ8(r); + //if(t & 0x80) { + // SEC; + // if((r & 0x80) == 0)SEV; + //} else { + // if((r & 0x80) != 0) SEV; + //} + SET_FLAGS8(tt, tt, r); + WM(EAD, (uint8_t)r); +} + +inline uint8_t MC6809::ROL_REG(uint8_t t) +{ + uint16_t r, tt; + tt = (uint16_t)t & 0x00ff; + r = (CC & CC_C) | (tt << 1); + CLR_NZVC; + //SET_NZ8(r); + //if(t & 0x80) { + // SEC; + // if((r & 0x80) == 0) SEV; + //} else { + // if((r & 0x80) != 0) SEV; + //} + SET_FLAGS8(tt, tt, r); + return (uint8_t)r; +} + +inline void MC6809::DEC_MEM(uint8_t t) +{ + uint16_t tt; + tt = t - 1; + CLR_NZV; + SET_FLAGS8D(tt); + WM(EAD, tt); +} + +inline uint8_t MC6809::DEC_REG(uint8_t t) +{ + uint8_t tt; + tt = t - 1; + CLR_NZV; + SET_FLAGS8D(tt); + return tt; +} + +inline void MC6809::DCC_MEM(uint8_t t) +{ + uint16_t tt, ss; + tt = t - 1; + CLR_NZVC; + SET_FLAGS8D(tt); + ss = CC; + ss >>= 2; + ss = ~ss; + ss = ss & CC_C; + CC = ss | CC; + WM(EAD, tt); +} + +inline uint8_t MC6809::DCC_REG(uint8_t t) +{ + uint16_t tt, ss; + tt = t - 1; + CLR_NZVC; + SET_FLAGS8D(tt); + ss = CC; + ss >>= 2; + ss = ~ss; + ss = ss & CC_C; + CC = ss | CC; + return (uint8_t)tt; +} + +inline void MC6809::INC_MEM(uint8_t t) +{ + uint16_t tt = t + 1; + CLR_NZV; + SET_FLAGS8I(tt); + WM(EAD, tt); +} + +inline uint8_t MC6809::INC_REG(uint8_t t) +{ + uint16_t tt = t + 1; + CLR_NZV; + SET_FLAGS8I(tt); + return (uint8_t)tt; +} + +inline void MC6809::TST_MEM(uint8_t t) +{ + CLR_NZV; + SET_NZ8(t); +} + +inline uint8_t MC6809::TST_REG(uint8_t t) +{ + CLR_NZV; + SET_NZ8(t); + return t; +} + +inline uint8_t MC6809::CLC_REG(uint8_t t) +{ + uint8_t r; + r = 0; + CLR_NZV; + SEZ; + return r; +} + + +inline void MC6809::CLR_MEM(uint8_t t) +{ + WM(EAD, 0); + CLR_NZVC; + SEZ; +} + +inline uint8_t MC6809::CLR_REG(uint8_t t) +{ + CLR_NZVC; + SEZ; + return 0; +} + +inline uint8_t MC6809::SUB8_REG(uint8_t reg, uint8_t data) +{ + uint16_t r; + r = (uint16_t)reg - (uint16_t)data; + CLR_HNZVC; + // H is undefined + SET_FLAGS8(reg, data, r); + return (uint8_t)r; +} + +inline uint8_t MC6809::CMP8_REG(uint8_t reg, uint8_t data) +{ + uint16_t r; + r = (uint16_t)reg - (uint16_t)data; + CLR_NZVC; + // H is undefined + SET_FLAGS8(reg, data, r); + return reg; +} + +inline uint8_t MC6809::SBC8_REG(uint8_t reg, uint8_t data) +{ + uint16_t r; + uint8_t cc_c = CC & CC_C; + r = (uint16_t)reg - (uint16_t)data - (uint16_t)cc_c; + CLR_HNZVC; + SET_FLAGS8(reg, (data + cc_c) , r); + return (uint8_t)r; +} + +inline uint8_t MC6809::AND8_REG(uint8_t reg, uint8_t data) +{ + uint8_t r = reg; + r &= data; + CLR_NZV; + SET_NZ8(r); + return r; +} + +inline uint8_t MC6809::BIT8_REG(uint8_t reg, uint8_t data) +{ + uint16_t r; + r = reg & data; + CLR_NZV; + SET_NZ8(r); + SET_V8(reg, data, r); + return reg; +} + +inline uint8_t MC6809::EOR8_REG(uint8_t reg, uint8_t data) +{ + uint8_t r = reg; + r ^= data; + CLR_NZV; + SET_NZ8(r); + return r; +} + +inline uint8_t MC6809::OR8_REG(uint8_t reg, uint8_t data) +{ + uint8_t r = reg; + r |= data; + CLR_NZV; + SET_NZ8(r); + return r; +} + +inline uint8_t MC6809::ADD8_REG(uint8_t reg, uint8_t data) +{ + uint16_t t, r; + t = (uint16_t) data; + t &= 0x00ff; + r = reg + t; + CLR_HNZVC; + SET_HNZVC8(reg, t, r); + return (uint8_t)r; +} + +inline uint8_t MC6809::ADC8_REG(uint8_t reg, uint8_t data) +{ + uint16_t t, r; + uint8_t c_cc = CC & CC_C; + t = (uint16_t) data; + t &= 0x00ff; + r = reg + t + c_cc; + CLR_HNZVC; + SET_HNZVC8(reg, (t + c_cc), r); + return (uint8_t)r; +} + +inline uint8_t MC6809::LOAD8_REG(uint8_t reg) +{ + CLR_NZV; + SET_NZ8(reg); + return reg; +} + +inline void MC6809::STORE8_REG(uint8_t reg) +{ + CLR_NZV; + SET_NZ8(reg); + WM(EAD, reg); +} + +inline uint16_t MC6809::LOAD16_REG(uint16_t reg) +{ + CLR_NZV; + SET_NZ16(reg); + return reg; +} + + +inline uint16_t MC6809::SUB16_REG(uint16_t reg, uint16_t data) +{ + uint32_t r, d; + d = reg; + r = d - data; + CLR_NZVC; + SET_FLAGS16(d, data, r); + return (uint16_t)r; +} + +inline uint16_t MC6809::ADD16_REG(uint16_t reg, uint16_t data) +{ + uint32_t r, d; + d = reg; + r = d + (uint32_t)data; + CLR_HNZVC; + SET_HNZVC16(d, data, r); + return (uint16_t)r; +} + +inline uint16_t MC6809::CMP16_REG(uint16_t reg, uint16_t data) +{ + uint32_t r, d; + d = reg; + r = d - data; + CLR_NZVC; + SET_FLAGS16(d, data, r); + return reg; +} + +inline void MC6809::STORE16_REG(pair32_t *p) +{ + CLR_NZV; + SET_NZ16(p->w.l); + WM16(EAD, p); +} + + +/* $00 NEG direct ?**** */ +OP_HANDLER(neg_di) { + uint8_t t; + DIRBYTE(t); + NEG_MEM(t); +} + +/* $01 Undefined Neg */ +/* $03 COM direct -**01 */ +OP_HANDLER(com_di) { + uint8_t t; + DIRBYTE(t); + COM_MEM(t); +} + +/* $02 NGC Direct (Undefined) */ +OP_HANDLER(ngc_di) { + if ((CC & CC_C) == 0) { + neg_di(); + } + else { + com_di(); + } +} + + +/* $04 LSR direct -0*-* */ +OP_HANDLER(lsr_di) { + uint8_t t; + DIRBYTE(t); + LSR_MEM(t); +} + +/* $05 ILLEGAL */ + +/* $06 ROR direct -**-* */ +OP_HANDLER(ror_di) { + uint8_t t; + DIRBYTE(t); + ROR_MEM(t); +} + +/* $07 ASR direct ?**-* */ +OP_HANDLER(asr_di) { + uint8_t t; + DIRBYTE(t); + ASR_MEM(t); +} + +/* $08 ASL direct ?**** */ +OP_HANDLER(asl_di) { + uint8_t t; + DIRBYTE(t); + ASL_MEM(t); +} + +/* $09 ROL direct -**** */ +OP_HANDLER(rol_di) { + uint8_t t; + DIRBYTE(t); + ROL_MEM(t); +} + +/* $0A DEC direct -***- */ +OP_HANDLER(dec_di) { + uint8_t t; + DIRBYTE(t); + DEC_MEM(t); +} + +/* $0B DCC direct */ +OP_HANDLER(dcc_di) { + uint8_t t; + DIRBYTE(t); + DCC_MEM(t); +} + + +/* $OC INC direct -***- */ +OP_HANDLER(inc_di) { + uint8_t t; + DIRBYTE(t); + INC_MEM(t); +} + +/* $OD TST direct -**0- */ +OP_HANDLER(tst_di) { + uint8_t t; + DIRBYTE(t); + t = RM(EAD); + TST_MEM(t); +} + +/* $0E JMP direct ----- */ +OP_HANDLER(jmp_di) { + DIRECT; + PC = EA; +} + +/* $0F CLR direct -0100 */ +OP_HANDLER(clr_di) { + uint8_t dummy; + DIRECT; + dummy = RM(EAD); // Dummy Read(Alpha etc...) + CLR_MEM(dummy); +} + +/* $10 FLAG */ + +/* $11 FLAG */ + +/* $12 NOP inherent ----- */ +OP_HANDLER(nop) { + ; +} + +/* $13 SYNC inherent ----- */ +OP_HANDLER(sync_09) // Rename 20101110 +{ + int_state |= MC6809_SYNC_IN; + write_signals(&outputs_bus_ba, 0xffffffff); + write_signals(&outputs_bus_bs, 0x00000000); +} + + + +/* $14 trap(HALT) */ +OP_HANDLER(trap) { + int_state |= MC6809_INSN_HALT; // HALT繝輔Λ繧ー + // Debug: 繝医Λ繝・・隕∝屏 + this->out_debug_log(_T("TRAP(HALT) @%04x %02x %02x\n"), PC - 1, RM((PC - 1)), RM(PC)); +} + +/* $15 trap */ + +/* $16 LBRA relative ----- */ +OP_HANDLER(lbra) { + LBRANCH(true); +} + +/* $17 LBSR relative ----- */ +OP_HANDLER(lbsr) { + IMMWORD(EAP); + PUSHWORD(pPC); + PC += EAD; +} + +/* $18 ASLCC */ + +OP_HANDLER(aslcc_in) { + uint8_t cc_r = CC; + if ((cc_r & CC_Z) != 0x00) { //20100824 Fix + cc_r |= CC_C; + } + cc_r <<= 1; + cc_r &= 0x3e; + CC = cc_r; +} + +/* $19 DAA inherent (A) -**0* */ +OP_HANDLER(daa) { + uint8_t msn, lsn; + uint16_t t, cf = 0; + msn = A & 0xf0; + lsn = A & 0x0f; + if (lsn > 0x09 || CC & CC_H) + cf |= 0x06; + if (msn > 0x80 && lsn > 0x09) + cf |= 0x60; + if (msn > 0x90 || CC & CC_C) + cf |= 0x60; + t = cf + A; + CLR_NZV; /* keep carry from previous operation */ + SET_NZ8((uint8_t) t); + SET_C8(t); + A = (uint8_t)t; +} + + +/* $1A ORCC immediate ##### */ +OP_HANDLER(orcc) { + uint8_t t; + IMMBYTE(t); + CC |= t; +} + +/* $1B ILLEGAL */ + + +/* $1C ANDCC immediate ##### */ +OP_HANDLER(andcc) { + uint8_t t; + IMMBYTE(t); + CC &= t; +// check_irq_lines(); /* HJB 990116 */ +} + +/* $1D SEX inherent -**-- */ +OP_HANDLER(sex) { + uint16_t t; + t = SIGNED(B); + D = t; // Endian OK? + // CLR_NZV; Tim Lindner 20020905: verified that V flag is not affected + CLR_NZ; + SET_NZ16(t); +} + + /* $1E EXG inherent ----- */// 20100825 +OP_HANDLER(exg) { + pair32_t t1, t2; + uint8_t tb; + IMMBYTE(tb); + t1.d = 0; + t2.d = 0; + /* + * 20111011: 16bit vs 16Bit縺ョ貍皮ョ励↓縺吶k(XM7/ cpu_x86.asm繧医j + */ + { + switch ((tb >> 4) & 15) { + case 0: + t1.w.l = D; + break; + case 1: + t1.w.l = X; + break; + case 2: + t1.w.l = Y; + break; + case 3: + t1.w.l = U; + break; + case 4: + t1.w.l = S; + break; + case 5: + t1.w.l = PC; + break; + case 8: + t1.b.l = A; + t1.b.h = 0xff; + break; + case 9: + t1.b.l = B; + t1.b.h = 0xff; + break; + case 10: + t1.b.l = CC; + t1.b.h = 0xff; + break; + case 11: + t1.b.l = DP; + t1.b.h = 0xff; + break; + default: + t1.w.l = 0xffff; + break; + } + switch (tb & 15) { + case 0: + t2.w.l = D; + break; + case 1: + t2.w.l = X; + break; + case 2: + t2.w.l = Y; + break; + case 3: + t2.w.l = U; + break; + case 4: + t2.w.l = S; + break; + case 5: + t2.w.l = PC; + break; + case 8: + t2.b.l = A; + t2.b.h = 0xff; + break; + case 9: + t2.b.l = B; + t2.b.h = 0xff; + break; + case 10: + t2.b.l = CC; + t2.b.h = 0xff; + break; + case 11: + t2.b.l = DP; + t2.b.h = 0xff; + break; + default: + t2.w.l = 0xffff; + break; + } + } + switch ((tb >> 4) & 15) { + case 0: + D = t2.w.l; + break; + case 1: + X = t2.w.l; + break; + case 2: + Y = t2.w.l; + break; + case 3: + U = t2.w.l; + break; + case 4: + S = t2.w.l; + int_state |= MC6809_LDS; + break; + case 5: + PC = t2.w.l; + break; + case 8: + A = t2.b.l; + break; + case 9: + B = t2.b.l; + break; + case 10: + CC = t2.b.l; + break; + case 11: + DP = t2.b.l; + break; + } + switch (tb & 15) { + case 0: + D = t1.w.l; + break; + case 1: + X = t1.w.l; + break; + case 2: + Y = t1.w.l; + break; + case 3: + U = t1.w.l; + break; + case 4: + S = t1.w.l; + int_state |= MC6809_LDS; + break; + case 5: + PC = t1.w.l; + break; + case 8: + A = t1.b.l; + break; + case 9: + B = t1.b.l; + break; + case 10: + CC = t1.b.l; + break; + case 11: + DP = t1.b.l; + break; + } +} + +/* $1F TFR inherent ----- */ +OP_HANDLER(tfr) { + uint8_t tb; + pair32_t t; + IMMBYTE(tb); + t.d = 0; + /* + * 20111011: 16bit vs 16Bit縺ョ貍皮ョ励↓縺吶k(XM7/ cpu_x86.asm繧医j) + */ + { + switch ((tb >> 4) & 15) { + case 0: + t.w.l = D; + break; + case 1: + t.w.l = X; + break; + case 2: + t.w.l = Y; + break; + case 3: + t.w.l = U; + break; + case 4: + t.w.l = S; + break; + case 5: + t.w.l = PC; + break; + case 8: + t.b.l = A; + t.b.h = 0xff; + break; + case 9: + t.b.l = B; + t.b.h = 0xff; + break; + case 10: + t.b.l = CC; + t.b.h = 0xff; + break; + case 11: + t.b.l = DP; + t.b.h = 0xff; + break; + default: + t.w.l = 0xffff; + break; + } + } + switch (tb & 15) { + case 0: + D = t.w.l; + break; + case 1: + X = t.w.l; + break; + case 2: + Y = t.w.l; + break; + case 3: + U = t.w.l; + break; + case 4: + S = t.w.l; + int_state |= MC6809_LDS; + break; + case 5: + PC = t.w.l; + break; + case 8: + A = t.b.l; + break; + case 9: + B = t.b.l; + break; + case 10: + CC = t.b.l; + break; + case 11: + DP = t.b.l; + break; + } +} + +/* $20 BRA relative ----- */ +OP_HANDLER(bra) { + BRANCH(true); +} + +/* $21 BRN relative ----- */ +OP_HANDLER(brn) { + BRANCH(false); +} + +/* $1021 LBRN relative ----- */ +OP_HANDLER(lbrn) { + LBRANCH(false); +} + +/* $22 BHI relative ----- */ +OP_HANDLER(bhi) { + BRANCH(((CC & (CC_Z | CC_C)) == 0)); +} + +/* $1022 LBHI relative ----- */ +OP_HANDLER(lbhi) { + LBRANCH(((CC & (CC_Z | CC_C)) == 0)); +} + +/* $23 BLS relative ----- */ +OP_HANDLER(bls) { + BRANCH(((CC & (CC_Z | CC_C)) != 0)); +} + +/* $1023 LBLS relative ----- */ +OP_HANDLER(lbls) { + LBRANCH(((CC & (CC_Z | CC_C)) != 0)); + //LBRANCH((CC & (CC_Z | CC_C))); +} + +/* $24 BCC relative ----- */ +OP_HANDLER(bcc) { + BRANCH((CC & CC_C) == 0); +} + +/* $1024 LBCC relative ----- */ +OP_HANDLER(lbcc) { + LBRANCH((CC & CC_C) == 0); +} + +/* $25 BCS relative ----- */ +OP_HANDLER(bcs) { + BRANCH((CC & CC_C) != 0); +} + +/* $1025 LBCS relative ----- */ +OP_HANDLER(lbcs) { + LBRANCH((CC & CC_C) != 0); +} + +/* $26 BNE relative ----- */ +OP_HANDLER(bne) { + BRANCH((CC & CC_Z) == 0); +} + +/* $1026 LBNE relative ----- */ +OP_HANDLER(lbne) { + LBRANCH((CC & CC_Z) == 0); +} + +/* $27 BEQ relative ----- */ +OP_HANDLER(beq) { + BRANCH((CC & CC_Z) != 0); +} + +/* $1027 LBEQ relative ----- */ +OP_HANDLER(lbeq) { + LBRANCH((CC & CC_Z) != 0); +} + +/* $28 BVC relative ----- */ +OP_HANDLER(bvc) { + BRANCH((CC & CC_V) == 0); +} + +/* $1028 LBVC relative ----- */ +OP_HANDLER(lbvc) { + LBRANCH((CC & CC_V) == 0); +} + +/* $29 BVS relative ----- */ +OP_HANDLER(bvs) { + BRANCH((CC & CC_V) != 0); +} + +/* $1029 LBVS relative ----- */ +OP_HANDLER(lbvs) { + LBRANCH((CC & CC_V) != 0); +} + +/* $2A BPL relative ----- */ +OP_HANDLER(bpl) { + BRANCH((CC & CC_N) == 0); +} + +/* $102A LBPL relative ----- */ +OP_HANDLER(lbpl) { + LBRANCH((CC & CC_N) == 0); +} + +/* $2B BMI relative ----- */ +OP_HANDLER(bmi) { + BRANCH((CC & CC_N) != 0); +} + +/* $102B LBMI relative ----- */ +OP_HANDLER(lbmi) { + LBRANCH((CC & CC_N) != 0); +} + +/* $2C BGE relative ----- */ +OP_HANDLER(bge) { + BRANCH(!NXORV); +} + +/* $102C LBGE relative ----- */ +OP_HANDLER(lbge) { + LBRANCH(!NXORV); +} + +/* $2D BLT relative ----- */ +OP_HANDLER(blt) { + BRANCH(NXORV); +} + +/* $102D LBLT relative ----- */ +OP_HANDLER(lblt) { + LBRANCH(NXORV); +} + +/* $2E BGT relative ----- */ +OP_HANDLER(bgt) { + BRANCH(!(NXORV || (CC & CC_Z))); +} + +/* $102E LBGT relative ----- */ +OP_HANDLER(lbgt) { + LBRANCH(!(NXORV || (CC & CC_Z))); +} + +/* $2F BLE relative ----- */ +OP_HANDLER(ble) { + BRANCH((NXORV || (CC & CC_Z))); +} + +/* $102F LBLE relative ----- */ +OP_HANDLER(lble) { + LBRANCH((NXORV || (CC & CC_Z))); +} + +/* $30 LEAX indexed --*-- */ +OP_HANDLER(leax) { + fetch_effective_address(); + X = EA; + CLR_Z; + SET_Z16(X); +} + +/* $31 LEAY indexed --*-- */ +OP_HANDLER(leay) { + fetch_effective_address(); + Y = EA; + CLR_Z; + SET_Z16(Y); +} + +/* $32 LEAS indexed ----- */ +OP_HANDLER(leas) { + fetch_effective_address(); + S = EA; + int_state |= MC6809_LDS; +} + +/* $33 LEAU indexed ----- */ +OP_HANDLER(leau) { + fetch_effective_address(); + U = EA; +} + +/* $34 PSHS inherent ----- */ +OP_HANDLER(pshs) { + uint8_t t; + IMMBYTE(t); + //dmy = RM(S); // Add 20100825 + RM(S); // Add 20100825 + if (t & 0x80) { + PUSHWORD(pPC); + icount -= 2; + } + if (t & 0x40) { + PUSHWORD(pU); + icount -= 2; + } + if (t & 0x20) { + PUSHWORD(pY); + icount -= 2; + } + if (t & 0x10) { + PUSHWORD(pX); + icount -= 2; + } + if (t & 0x08) { + PUSHBYTE(DP); + icount -= 1; + } + if (t & 0x04) { + PUSHBYTE(B); + icount -= 1; + } + if (t & 0x02) { + PUSHBYTE(A); + icount -= 1; + } + if (t & 0x01) { + PUSHBYTE(CC); + icount -= 1; + } + } + +/* 35 PULS inherent ----- */ +OP_HANDLER(puls) { + uint8_t t; + IMMBYTE(t); + if (t & 0x01) { + PULLBYTE(CC); + icount -= 1; + } + if (t & 0x02) { + PULLBYTE(A); + icount -= 1; + } + if (t & 0x04) { + PULLBYTE(B); + icount -= 1; + } + if (t & 0x08) { + PULLBYTE(DP); + icount -= 1; + } + if (t & 0x10) { + PULLWORD(pX); + icount -= 2; + } + if (t & 0x20) { + PULLWORD(pY); + icount -= 2; + } + if (t & 0x40) { + PULLWORD(pU); + icount -= 2; + } + if (t & 0x80) { + PULLWORD(pPC); + icount -= 2; + } + //dmy = RM(S); // Add 20100825 + RM(S); // Add 20100825 + /* HJB 990225: moved check after all PULLs */ +// if( t&0x01 ) { check_irq_lines(); } + } + +/* $36 PSHU inherent ----- */ +OP_HANDLER(pshu) { + uint8_t t; + IMMBYTE(t); + //dmy = RM(U); // Add 20100825 + RM(U); // Add 20100825 + if (t & 0x80) { + PSHUWORD(pPC); + icount -= 2; + } + if (t & 0x40) { + PSHUWORD(pS); + icount -= 2; + } + if (t & 0x20) { + PSHUWORD(pY); + icount -= 2; + } + if (t & 0x10) { + PSHUWORD(pX); + icount -= 2; + } + if (t & 0x08) { + PSHUBYTE(DP); + icount -= 1; + } + if (t & 0x04) { + PSHUBYTE(B); + icount -= 1; + } + if (t & 0x02) { + PSHUBYTE(A); + icount -= 1; + } + if (t & 0x01) { + PSHUBYTE(CC); + icount -= 1; + } + } + +/* 37 PULU inherent ----- */ +OP_HANDLER(pulu) { + uint8_t t; + IMMBYTE(t); + if (t & 0x01) { + PULUBYTE(CC); + icount -= 1; + } + if (t & 0x02) { + PULUBYTE(A); + icount -= 1; + } + if (t & 0x04) { + PULUBYTE(B); + icount -= 1; + } + if (t & 0x08) { + PULUBYTE(DP); + icount -= 1; + } + if (t & 0x10) { + PULUWORD(pX); + icount -= 2; + } + if (t & 0x20) { + PULUWORD(pY); + icount -= 2; + } + if (t & 0x40) { + PULUWORD(pS); + icount -= 2; + } + if (t & 0x80) { + PULUWORD(pPC); + icount -= 2; + } + //dmy = RM(U); // Add 20100825 + RM(U); // Add 20100825 + /* HJB 990225: moved check after all PULLs */ + //if( t&0x01 ) { check_irq_lines(); } +} + +/* $38 ILLEGAL */ + +/* $39 RTS inherent ----- */ +OP_HANDLER(rts) { + //printf("RTS: Before PC=%04x", pPC.w.l); + PULLWORD(pPC); + //printf(" After PC=%04x\n", pPC.w.l); +} + +/* $3A ABX inherent ----- */ +OP_HANDLER(abx) { + pair32_t bt; + bt.d = 0; + bt.b.l = B; + X = X + bt.w.l; +} + +/* $3B RTI inherent ##### */ +OP_HANDLER(rti) { + PULLBYTE(CC); +// t = CC & CC_E; /* HJB 990225: entire state saved? */ + if ((CC & CC_E) != 0) { // NMIIRQ + icount -= 9; + PULLBYTE(A); + PULLBYTE(B); + PULLBYTE(DP); + PULLWORD(pX); + PULLWORD(pY); + PULLWORD(pU); + } + PULLWORD(pPC); +// check_irq_lines(); /* HJB 990116 */ +} + +/* $3C CWAI inherent ----1 */ +OP_HANDLER(cwai) { + uint8_t t; + IMMBYTE(t); + CC = CC & t; + CC |= CC_E; /* HJB 990225: save entire state */ + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + + int_state = int_state | MC6809_CWAI_IN; + int_state &= ~MC6809_CWAI_OUT; // 0xfeff + return; +} + +/* $3D MUL inherent --*-@ */ +OP_HANDLER(mul) { + pair32_t t, r; + t.d = 0; + r.d = 0; + t.b.l = A; + r.b.l = B; + t.d = t.d * r.d; + CLR_ZC; + SET_Z16(t.w.l); + if (t.b.l & 0x80) SEC; + A = t.b.h; + B = t.b.l; +} + +/* $3E RST */ +OP_HANDLER(rst) { + this->reset(); +} + + +/* $3F SWI (SWI2 SWI3) absolute indirect ----- */ +OP_HANDLER(swi) { + CC |= CC_E; /* HJB 980225: save entire state */ + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + CC |= CC_IF | CC_II; /* inhibit FIRQ and IRQ */ + pPC = RM16_PAIR(0xfffa); +} + +/* $103F SWI2 absolute indirect ----- */ +OP_HANDLER(swi2) { + CC |= CC_E; /* HJB 980225: save entire state */ + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + pPC = RM16_PAIR(0xfff4); +} + +/* $113F SWI3 absolute indirect ----- */ +OP_HANDLER(swi3) { + CC |= CC_E; /* HJB 980225: save entire state */ + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + pPC = RM16_PAIR(0xfff2); +} + +/* $40 NEGA inherent ?**** */ +OP_HANDLER(nega) { + A = NEG_REG(A); +} + +/* $41 NEGA */ + + +/* $43 COMA inherent -**01 */ +OP_HANDLER(coma) { + A = COM_REG(A); +} + +/* $42 NGCA */ +OP_HANDLER(ngca) { + if ((CC & CC_C) == 0) { + nega(); + } else { + coma(); + } +} + +/* $44 LSRA inherent -0*-* */ +OP_HANDLER(lsra) { + A = LSR_REG(A); +} + +/* $45 LSRA */ + +/* $46 RORA inherent -**-* */ +OP_HANDLER(rora) { + A = ROR_REG(A); +} + +/* $47 ASRA inherent ?**-* */ +OP_HANDLER(asra) { + A = ASR_REG(A); +} + +/* $48 ASLA inherent ?**** */ +OP_HANDLER(asla) { + A = ASL_REG(A); +} + +/* $49 ROLA inherent -**** */ +OP_HANDLER(rola) { + A = ROL_REG(A); +} + +/* $4A DECA inherent -***- */ +OP_HANDLER(deca) { + A = DEC_REG(A); +} + + +/* $4B DCCA */ +OP_HANDLER(dcca) { + A = DCC_REG(A); +} + +/* $4C INCA inherent -***- */ +OP_HANDLER(inca) { + A = INC_REG(A); +} + +/* $4D TSTA inherent -**0- */ +OP_HANDLER(tsta) { + A = TST_REG(A); +} + +/* $4E ILLEGAL */ +OP_HANDLER(clca) { + A = CLC_REG(A); +} + +/* $4F CLRA inherent -0100 */ +OP_HANDLER(clra) { + A = CLR_REG(A); +} + +/* $50 NEGB inherent ?**** */ +OP_HANDLER(negb) { + B = NEG_REG(B); +} + +/* $51 NEGB */ + +/* $52 NGCB */ + +/* $53 COMB inherent -**01 */ +OP_HANDLER(comb) { + B = COM_REG(B); +} + +/* $52 NGCB */ +OP_HANDLER(ngcb) { + if ((CC & CC_C) == 0) { + negb(); + } else { + comb(); + } +} + +/* $54 LSRB inherent -0*-* */ +OP_HANDLER(lsrb) { + B = LSR_REG(B); +} + +/* $55 LSRB */ + +/* $56 RORB inherent -**-* */ +OP_HANDLER(rorb) { + B = ROR_REG(B); +} + +/* $57 ASRB inherent ?**-* */ +OP_HANDLER(asrb) { + B = ASR_REG(B); +} + +/* $58 ASLB inherent ?**** */ +OP_HANDLER(aslb) { + B = ASL_REG(B); +} + +/* $59 ROLB inherent -**** */ +OP_HANDLER(rolb) { + B = ROL_REG(B); +} + +/* $5A DECB inherent -***- */ +OP_HANDLER(decb) { + B = DEC_REG(B); +} + +/* $5B DCCB */ +OP_HANDLER(dccb) { + B = DCC_REG(B); +} + +/* $5C INCB inherent -***- */ +OP_HANDLER(incb) { + B = INC_REG(B); +} + +/* $5D TSTB inherent -**0- */ +OP_HANDLER(tstb) { + B = TST_REG(B); +} + +/* $5E ILLEGAL */ +OP_HANDLER(clcb) { + B = CLC_REG(B); +} + +/* $5F CLRB inherent -0100 */ +OP_HANDLER(clrb) { + B = CLR_REG(B); +} + +/* $60 NEG indexed ?**** */ +OP_HANDLER(neg_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + NEG_MEM(t); +} + +/* $61 ILLEGAL */ + + +/* $63 COM indexed -**01 */ +OP_HANDLER(com_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + COM_MEM(t); +} + +/* $62 ILLEGAL */ +OP_HANDLER(ngc_ix) { + if ((CC & CC_C) == 0) { + neg_ix(); + } else { + com_ix(); + } +} + +/* $64 LSR indexed -0*-* */ +OP_HANDLER(lsr_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + LSR_MEM(t); +} + +/* $65 ILLEGAL */ + +/* $66 ROR indexed -**-* */ +OP_HANDLER(ror_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + ROR_MEM(t); +} + +/* $67 ASR indexed ?**-* */ +OP_HANDLER(asr_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + ASR_MEM(t); +} + +/* $68 ASL indexed ?**** */ +OP_HANDLER(asl_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + ASL_MEM(t); +} + +/* $69 ROL indexed -**** */ +OP_HANDLER(rol_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + ROL_MEM(t); +} + +/* $6A DEC indexed -***- */ +OP_HANDLER(dec_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + DEC_MEM(t); +} + +/* $6B DCC index */ +OP_HANDLER(dcc_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + DCC_MEM(t); +} + +/* $6C INC indexed -***- */ +OP_HANDLER(inc_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + INC_MEM(t); +} + +/* $6D TST indexed -**0- */ +OP_HANDLER(tst_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + TST_MEM(t); +} + +/* $6E JMP indexed ----- */ +OP_HANDLER(jmp_ix) { + fetch_effective_address(); + PCD = EAD; +} + +/* $6F CLR indexed -0100 */ +OP_HANDLER(clr_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + //dummy = RM(EAD); // Dummy Read(Alpha etc...) + RM(EAD); // Dummy Read(Alpha etc...) + CLR_MEM(t); +} + +/* $70 NEG extended ?**** */ +OP_HANDLER(neg_ex) { + uint8_t t; + EXTBYTE(t); + NEG_MEM(t); +} + + +/* $73 COM extended -**01 */ +OP_HANDLER(com_ex) { + uint8_t t; + EXTBYTE(t); + COM_MEM(t); +} + +/* $72 NGC extended */ +OP_HANDLER(ngc_ex) { + if ((CC & CC_C) == 0) { + neg_ex(); + } else { + com_ex(); + } +} + +/* $74 LSR extended -0*-* */ +OP_HANDLER(lsr_ex) { + uint8_t t; + EXTBYTE(t); + LSR_MEM(t); +} + +/* $75 ILLEGAL */ + +/* $76 ROR extended -**-* */ +OP_HANDLER(ror_ex) { + uint8_t t; + EXTBYTE(t); + ROR_MEM(t); +} + +/* $77 ASR extended ?**-* */ +OP_HANDLER(asr_ex) { + uint8_t t; + EXTBYTE(t); + ASR_MEM(t); +} + +/* $78 ASL extended ?**** */ +OP_HANDLER(asl_ex) { + uint8_t t; + EXTBYTE(t); + ASL_MEM(t); +} + +/* $79 ROL extended -**** */ +OP_HANDLER(rol_ex) { + uint8_t t; + EXTBYTE(t); + ROL_MEM(t); +} + +/* $7A DEC extended -***- */ +OP_HANDLER(dec_ex) { + uint8_t t; + EXTBYTE(t); + DEC_MEM(t); +} + +/* $7B ILLEGAL */ +/* $6B DCC index */ +OP_HANDLER(dcc_ex) { + uint8_t t; + EXTBYTE(t); + DCC_MEM(t); +} + +/* $7C INC extended -***- */ +OP_HANDLER(inc_ex) { + uint8_t t; + EXTBYTE(t); + INC_MEM(t); +} + +/* $7D TST extended -**0- */ +OP_HANDLER(tst_ex) { + uint8_t t; + EXTBYTE(t); + TST_MEM(t); +} + +/* $7E JMP extended ----- */ +OP_HANDLER(jmp_ex) { + EXTENDED; + PCD = EAD; +} + +/* $7F CLR extended -0100 */ +OP_HANDLER(clr_ex) { + uint8_t dummy; + EXTENDED; + dummy = RM(EAD); + CLR_MEM(dummy); +} + +/* $80 SUBA immediate ?**** */ +OP_HANDLER(suba_im) { + uint8_t t; + IMMBYTE(t); + A = SUB8_REG(A, t); +} + +/* $81 CMPA immediate ?**** */ +OP_HANDLER(cmpa_im) { + uint8_t t; + IMMBYTE(t); + A = CMP8_REG(A, t); +} + +/* $82 SBCA immediate ?**** */ +OP_HANDLER(sbca_im) { + uint8_t t; + IMMBYTE(t); + A = SBC8_REG(A, t); +} + +/* $83 SUBD (CMPD CMPU) immediate -**** */ +OP_HANDLER(subd_im) { + pair32_t b; + IMMWORD(b); + D = SUB16_REG(D, b.w.l); +} + +/* $1083 CMPD immediate -**** */ +OP_HANDLER(cmpd_im) { + pair32_t b; + IMMWORD(b); + D = CMP16_REG(D, b.w.l); +} + +/* $1183 CMPU immediate -**** */ +OP_HANDLER(cmpu_im) { + pair32_t b; + IMMWORD(b); + U = CMP16_REG(U, b.w.l); +} + +/* $84 ANDA immediate -**0- */ +OP_HANDLER(anda_im) { + uint8_t t; + IMMBYTE(t); + A = AND8_REG(A, t); +} + +/* $85 BITA immediate -**0- */ +OP_HANDLER(bita_im) { + uint8_t t; + IMMBYTE(t); + A = BIT8_REG(A, t); +} + +/* $86 LDA immediate -**0- */ +OP_HANDLER(lda_im) { + IMMBYTE(A); + A = LOAD8_REG(A); +} + +/* is this a legal instruction? */ +/* $87 STA immediate -**0- */ +OP_HANDLER(sta_im) { + CLR_NZV; + SET_NZ8(A); + IMM8; + WM(EAD, A); + } + +/* + * $87 , $C7: FLAG8 + */ +OP_HANDLER(flag8_im) { + // 20111117 + //uint8_t t; + // IMMBYTE(t); + ROP_ARG(PCD); + PC++; + CLR_NZV; + CC |= CC_N; + } + + +/* $88 EORA immediate -**0- */ +OP_HANDLER(eora_im) { + uint8_t t; + IMMBYTE(t); + A = EOR8_REG(A, t); +} + +/* $89 ADCA immediate ***** */ +OP_HANDLER(adca_im) { + uint8_t t; + IMMBYTE(t); + A = ADC8_REG(A, t); +} + +/* $8A ORA immediate -**0- */ +OP_HANDLER(ora_im) { + uint8_t t; + IMMBYTE(t); + A = OR8_REG(A, t); +} + +/* $8B ADDA immediate ***** */ +OP_HANDLER(adda_im) { + uint8_t t; + IMMBYTE(t); + A = ADD8_REG(A, t); +} + +/* $8C CMPX (CMPY CMPS) immediate -**** */ +OP_HANDLER(cmpx_im) { + pair32_t b; + IMMWORD(b); + X = CMP16_REG(X, b.w.l); +} + +/* $108C CMPY immediate -**** */ +OP_HANDLER(cmpy_im) { + pair32_t b; + IMMWORD(b); + Y = CMP16_REG(Y, b.w.l); +} + +/* $118C CMPS immediate -**** */ +OP_HANDLER(cmps_im) { + pair32_t b; + IMMWORD(b); + S = CMP16_REG(S, b.w.l); +} + +/* $8D BSR ----- */ +OP_HANDLER(bsr) { + uint8_t t; + IMMBYTE(t); + PUSHWORD(pPC); + PC += SIGNED(t); + } + +/* $8E LDX (LDY) immediate -**0- */ +OP_HANDLER(ldx_im) { + IMMWORD(pX); + X = LOAD16_REG(X); +} + +/* $108E LDY immediate -**0- */ +OP_HANDLER(ldy_im) { + IMMWORD(pY); + Y = LOAD16_REG(Y); +} + +/* is this a legal instruction? */ +/* $8F STX (STY) immediate -**0- */ +OP_HANDLER(stx_im) { + CLR_NZV; + SET_NZ16(X); + IMM16; + WM16(EAD, &pX); + } + +/* + * $8F , $CF: FLAG16 + */ +OP_HANDLER(flag16_im) { + pair32_t t; + IMMWORD(t); + CLR_NZV; + CC |= CC_N; +} + + +/* is this a legal instruction? */ +/* $108F STY immediate -**0- */ +OP_HANDLER(sty_im) { + CLR_NZV; + SET_NZ16(Y); + IMM16; + WM16(EAD, &pY); + } + +/* $90 SUBA direct ?**** */ +OP_HANDLER(suba_di) { + uint8_t t; + DIRBYTE(t); + A = SUB8_REG(A, t); +} + +/* $91 CMPA direct ?**** */ +OP_HANDLER(cmpa_di) { + uint8_t t; + DIRBYTE(t); + A = CMP8_REG(A, t); +} + +/* $92 SBCA direct ?**** */ +OP_HANDLER(sbca_di) { + uint8_t t; + DIRBYTE(t); + A = SBC8_REG(A, t); +} + +/* $93 SUBD (CMPD CMPU) direct -**** */ +OP_HANDLER(subd_di) { + pair32_t b; + DIRWORD(b); + D = SUB16_REG(D, b.w.l); +} + +/* $1093 CMPD direct -**** */ +OP_HANDLER(cmpd_di) { + pair32_t b; + DIRWORD(b); + D = CMP16_REG(D, b.w.l); +} + +/* $1193 CMPU direct -**** */ +OP_HANDLER(cmpu_di) { + pair32_t b; + DIRWORD(b); + U = CMP16_REG(U, b.w.l); +} + +/* $94 ANDA direct -**0- */ +OP_HANDLER(anda_di) { + uint8_t t; + DIRBYTE(t); + A = AND8_REG(A, t); +} + +/* $95 BITA direct -**0- */ +OP_HANDLER(bita_di) { + uint8_t t; + DIRBYTE(t); + A = BIT8_REG(A, t); +} + +/* $96 LDA direct -**0- */ +OP_HANDLER(lda_di) { + DIRBYTE(A); + A = LOAD8_REG(A); +} + +/* $97 STA direct -**0- */ +OP_HANDLER(sta_di) { + DIRECT; + STORE8_REG(A); +} + +/* $98 EORA direct -**0- */ +OP_HANDLER(eora_di) { + uint8_t t; + DIRBYTE(t); + A = EOR8_REG(A, t); +} + +/* $99 ADCA direct ***** */ +OP_HANDLER(adca_di) { + uint8_t t; + DIRBYTE(t); + A = ADC8_REG(A, t); +} + +/* $9A ORA direct -**0- */ +OP_HANDLER(ora_di) { + uint8_t t; + DIRBYTE(t); + A = OR8_REG(A, t); +} + +/* $9B ADDA direct ***** */ +OP_HANDLER(adda_di) { + uint8_t t; + DIRBYTE(t); + A = ADD8_REG(A, t); +} + +/* $9C CMPX (CMPY CMPS) direct -**** */ +OP_HANDLER(cmpx_di) { + pair32_t b; + DIRWORD(b); + X = CMP16_REG(X, b.w.l); +} + +/* $109C CMPY direct -**** */ +OP_HANDLER(cmpy_di) { + pair32_t b; + DIRWORD(b); + Y = CMP16_REG(Y, b.w.l); +} + +/* $119C CMPS direct -**** */ +OP_HANDLER(cmps_di) { + pair32_t b; + DIRWORD(b); + S = CMP16_REG(S, b.w.l); +} + +/* $9D JSR direct ----- */ +OP_HANDLER(jsr_di) { + DIRECT; + PUSHWORD(pPC); + PCD = EAD; + } + +/* $9E LDX (LDY) direct -**0- */ +OP_HANDLER(ldx_di) { + DIRWORD(pX); + X = LOAD16_REG(X); +} + +/* $109E LDY direct -**0- */ +OP_HANDLER(ldy_di) { + DIRWORD(pY); + Y = LOAD16_REG(Y); +} + +/* $9F STX (STY) direct -**0- */ +OP_HANDLER(stx_di) { + DIRECT; + STORE16_REG(&pX); +} + +/* $109F STY direct -**0- */ +OP_HANDLER(sty_di) { + DIRECT; + STORE16_REG(&pY); +} + +/* $a0 SUBA indexed ?**** */ +OP_HANDLER(suba_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = SUB8_REG(A, t); +} + +/* $a1 CMPA indexed ?**** */ +OP_HANDLER(cmpa_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = CMP8_REG(A, t); +} + +/* $a2 SBCA indexed ?**** */ +OP_HANDLER(sbca_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = SBC8_REG(A, t); +} + +/* $a3 SUBD (CMPD CMPU) indexed -**** */ +OP_HANDLER(subd_ix) { + pair32_t b; + b = GET_INDEXED_DATA16(); + D = SUB16_REG(D, b.w.l); +} + +/* $10a3 CMPD indexed -**** */ +OP_HANDLER(cmpd_ix) { + pair32_t b; + b = GET_INDEXED_DATA16(); + D = CMP16_REG(D, b.w.l); +} + +/* $11a3 CMPU indexed -**** */ +OP_HANDLER(cmpu_ix) { + pair32_t b; + b = GET_INDEXED_DATA16(); + U = CMP16_REG(U, b.w.l); +} + +/* $a4 ANDA indexed -**0- */ +OP_HANDLER(anda_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = AND8_REG(A, t); +} + +/* $a5 BITA indexed -**0- */ +OP_HANDLER(bita_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = BIT8_REG(A, t); +} + +/* $a6 LDA indexed -**0- */ +OP_HANDLER(lda_ix) { + A = GET_INDEXED_DATA(); + A = LOAD8_REG(A); +} + +/* $a7 STA indexed -**0- */ +OP_HANDLER(sta_ix) { + fetch_effective_address(); + STORE8_REG(A); +} + +/* $a8 EORA indexed -**0- */ +OP_HANDLER(eora_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = EOR8_REG(A, t); +} + +/* $a9 ADCA indexed ***** */ +OP_HANDLER(adca_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = ADC8_REG(A, t); +} + +/* $aA ORA indexed -**0- */ +OP_HANDLER(ora_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = OR8_REG(A, t); +} + +/* $aB ADDA indexed ***** */ +OP_HANDLER(adda_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + A = ADD8_REG(A, t); +} + +/* $aC CMPX (CMPY CMPS) indexed -**** */ +OP_HANDLER(cmpx_ix) { + pair32_t b; + b = GET_INDEXED_DATA16(); + X = CMP16_REG(X, b.w.l); +} + +/* $10aC CMPY indexed -**** */ +OP_HANDLER(cmpy_ix) { + pair32_t b; + b = GET_INDEXED_DATA16(); + Y = CMP16_REG(Y, b.w.l); +} + +/* $11aC CMPS indexed -**** */ +OP_HANDLER(cmps_ix) { + pair32_t b; + b = GET_INDEXED_DATA16(); + S = CMP16_REG(S, b.w.l); +} + +/* $aD JSR indexed ----- */ +OP_HANDLER(jsr_ix) { + fetch_effective_address(); + PUSHWORD(pPC); + PCD = EAD; +} + +/* $aE LDX (LDY) indexed -**0- */ +OP_HANDLER(ldx_ix) { + pair32_t t; + t = GET_INDEXED_DATA16(); + X = t.w.l; + X = LOAD16_REG(X); +} + +/* $10aE LDY indexed -**0- */ +OP_HANDLER(ldy_ix) { + pair32_t t; + t = GET_INDEXED_DATA16(); + Y = t.w.l; + Y = LOAD16_REG(Y); +} + +/* $aF STX (STY) indexed -**0- */ +OP_HANDLER(stx_ix) { + fetch_effective_address(); + STORE16_REG(&pX); +} + +/* $10aF STY indexed -**0- */ +OP_HANDLER(sty_ix) { + fetch_effective_address(); + STORE16_REG(&pY); +} + +/* $b0 SUBA extended ?**** */ +OP_HANDLER(suba_ex) { + uint8_t t; + EXTBYTE(t); + A = SUB8_REG(A, t); +} + +/* $b1 CMPA extended ?**** */ +OP_HANDLER(cmpa_ex) { + uint8_t t; + EXTBYTE(t); + A = CMP8_REG(A, t); +} + +/* $b2 SBCA extended ?**** */ +OP_HANDLER(sbca_ex) { + uint8_t t; + EXTBYTE(t); + A = SBC8_REG(A, t); +} + +/* $b3 SUBD (CMPD CMPU) extended -**** */ +OP_HANDLER(subd_ex) { + pair32_t b; + EXTWORD(b); + D = SUB16_REG(D, b.w.l); +} + +/* $10b3 CMPD extended -**** */ +OP_HANDLER(cmpd_ex) { + pair32_t b; + EXTWORD(b); + D = CMP16_REG(D, b.w.l); +} + +/* $11b3 CMPU extended -**** */ +OP_HANDLER(cmpu_ex) { + pair32_t b; + EXTWORD(b); + U = CMP16_REG(U, b.w.l); +} + +/* $b4 ANDA extended -**0- */ +OP_HANDLER(anda_ex) { + uint8_t t; + EXTBYTE(t); + A = AND8_REG(A, t); +} + +/* $b5 BITA extended -**0- */ +OP_HANDLER(bita_ex) { + uint8_t t; + EXTBYTE(t); + A = BIT8_REG(A, t); +} + +/* $b6 LDA extended -**0- */ +OP_HANDLER(lda_ex) { + EXTBYTE(A); + A = LOAD8_REG(A); +} + +/* $b7 STA extended -**0- */ +OP_HANDLER(sta_ex) { + EXTENDED; + STORE8_REG(A); +} + +/* $b8 EORA extended -**0- */ +OP_HANDLER(eora_ex) { + uint8_t t; + EXTBYTE(t); + A = EOR8_REG(A, t); +} + +/* $b9 ADCA extended ***** */ +OP_HANDLER(adca_ex) { + uint8_t t; + EXTBYTE(t); + A = ADC8_REG(A, t); +} + +/* $bA ORA extended -**0- */ +OP_HANDLER(ora_ex) { + uint8_t t; + EXTBYTE(t); + A = OR8_REG(A, t); +} + +/* $bB ADDA extended ***** */ +OP_HANDLER(adda_ex) { + uint8_t t; + EXTBYTE(t); + A = ADD8_REG(A, t); +} + +/* $bC CMPX (CMPY CMPS) extended -**** */ +OP_HANDLER(cmpx_ex) { + pair32_t b; + EXTWORD(b); + X = CMP16_REG(X, b.w.l); +} + +/* $10bC CMPY extended -**** */ +OP_HANDLER(cmpy_ex) { + pair32_t b; + EXTWORD(b); + Y = CMP16_REG(Y, b.w.l); +} + +/* $11bC CMPS extended -**** */ +OP_HANDLER(cmps_ex) { + pair32_t b; + EXTWORD(b); + S = CMP16_REG(S, b.w.l); +} + +/* $bD JSR extended ----- */ +OP_HANDLER(jsr_ex) { + EXTENDED; + PUSHWORD(pPC); + PCD = EAD; +} + +/* $bE LDX (LDY) extended -**0- */ +OP_HANDLER(ldx_ex) { + EXTWORD(pX); + X = LOAD16_REG(X); +} + +/* $10bE LDY extended -**0- */ +OP_HANDLER(ldy_ex) { + EXTWORD(pY); + Y = LOAD16_REG(Y); +} + +/* $bF STX (STY) extended -**0- */ +OP_HANDLER(stx_ex) { + EXTENDED; + STORE16_REG(&pX); +} + +/* $10bF STY extended -**0- */ +OP_HANDLER(sty_ex) { + EXTENDED; + STORE16_REG(&pY); +} + +/* $c0 SUBB immediate ?**** */ +OP_HANDLER(subb_im) { + uint8_t t; + IMMBYTE(t); + B = SUB8_REG(B, t); +} + +/* $c1 CMPB immediate ?**** */ +OP_HANDLER(cmpb_im) { + uint8_t t; + IMMBYTE(t); + B = CMP8_REG(B, t); +} + +/* $c2 SBCB immediate ?**** */ +OP_HANDLER(sbcb_im) { + uint8_t t; + IMMBYTE(t); + B = SBC8_REG(B, t); +} + +/* $c3 ADDD immediate -**** */ +OP_HANDLER(addd_im) { + pair32_t b; + IMMWORD(b); + D = ADD16_REG(D, b.w.l); +} + +/* $c4 ANDB immediate -**0- */ +OP_HANDLER(andb_im) { + uint8_t t; + IMMBYTE(t); + B = AND8_REG(B, t); +} + +/* $c5 BITB immediate -**0- */ +OP_HANDLER(bitb_im) { + uint8_t t; + IMMBYTE(t); + B = BIT8_REG(B, t); +} + +/* $c6 LDB immediate -**0- */ +OP_HANDLER(ldb_im) { + IMMBYTE(B); + B = LOAD8_REG(B); +} + +/* is this a legal instruction? */ +/* $c7 STB immediate -**0- */ +OP_HANDLER(stb_im) { + CLR_NZV; + SET_NZ8(B); + IMM8; + WM(EAD, B); +} + +/* $c8 EORB immediate -**0- */ +OP_HANDLER(eorb_im) { + uint8_t t; + IMMBYTE(t); + B = EOR8_REG(B, t); +} + +/* $c9 ADCB immediate ***** */ +OP_HANDLER(adcb_im) { + uint8_t t; + IMMBYTE(t); + B = ADC8_REG(B, t); +} + +/* $cA ORB immediate -**0- */ +OP_HANDLER(orb_im) { + uint8_t t; + IMMBYTE(t); + B = OR8_REG(B, t); +} + +/* $cB ADDB immediate ***** */ +OP_HANDLER(addb_im) { + uint8_t t; + IMMBYTE(t); + B = ADD8_REG(B, t); +} + +/* $cC LDD immediate -**0- */ +OP_HANDLER(ldd_im) { + IMMWORD(pD); + D = LOAD16_REG(D); +} + +/* is this a legal instruction? */ +/* $cD STD immediate -**0- */ +OP_HANDLER(std_im) { + CLR_NZV; + SET_NZ16(D); + IMM16; + WM(EAD, D); +} + +/* $cE LDU (LDS) immediate -**0- */ +OP_HANDLER(ldu_im) { + IMMWORD(pU); + U = LOAD16_REG(U); +} + +/* $10cE LDS immediate -**0- */ +OP_HANDLER(lds_im) { + IMMWORD(pS); + S = LOAD16_REG(S); + int_state |= MC6809_LDS; +} + +/* is this a legal instruction? */ +/* $cF STU (STS) immediate -**0- */ +OP_HANDLER(stu_im) { + CLR_NZV; + SET_NZ16(U); + IMM16; + WM16(EAD, &pU); + } + +/* is this a legal instruction? */ +/* $10cF STS immediate -**0- */ +OP_HANDLER(sts_im) { + CLR_NZV; + SET_NZ16(S); + IMM16; + WM16(EAD, &pS); + } + +/* $d0 SUBB direct ?**** */ +OP_HANDLER(subb_di) { + uint8_t t; + DIRBYTE(t); + B = SUB8_REG(B, t); +} +/* $d1 CMPB direct ?**** */ +OP_HANDLER(cmpb_di) { + uint8_t t; + DIRBYTE(t); + B = CMP8_REG(B, t); +} + +/* $d2 SBCB direct ?**** */ +OP_HANDLER(sbcb_di) { + uint8_t t; + DIRBYTE(t); + B = SBC8_REG(B, t); +} + +/* $d3 ADDD direct -**** */ +OP_HANDLER(addd_di) { + pair32_t b; + DIRWORD(b); + D = ADD16_REG(D, b.w.l); +} + +/* $d4 ANDB direct -**0- */ +OP_HANDLER(andb_di) { + uint8_t t; + DIRBYTE(t); + B = AND8_REG(B, t); +} + +/* $d5 BITB direct -**0- */ +OP_HANDLER(bitb_di) { + uint8_t t; + DIRBYTE(t); + B = BIT8_REG(B, t); +} + +/* $d6 LDB direct -**0- */ +OP_HANDLER(ldb_di) { + DIRBYTE(B); + B = LOAD8_REG(B); +} + +/* $d7 STB direct -**0- */ +OP_HANDLER(stb_di) { + DIRECT; + STORE8_REG(B); +} + +/* $d8 EORB direct -**0- */ +OP_HANDLER(eorb_di) { + uint8_t t; + DIRBYTE(t); + B = EOR8_REG(B, t); +} + +/* $d9 ADCB direct ***** */ +OP_HANDLER(adcb_di) { + uint8_t t; + DIRBYTE(t); + B = ADC8_REG(B, t); +} + +/* $dA ORB direct -**0- */ +OP_HANDLER(orb_di) { + uint8_t t; + DIRBYTE(t); + B = OR8_REG(B, t); +} + +/* $dB ADDB direct ***** */ +OP_HANDLER(addb_di) { + uint8_t t; + DIRBYTE(t); + B = ADD8_REG(B, t); +} - if(__USE_DEBUGGER) { - d_mem_stored = d_mem; - d_debugger->set_context_mem(d_mem); - } +/* $dC LDD direct -**0- */ +OP_HANDLER(ldd_di) { + DIRWORD(pD); + D = LOAD16_REG(D); } -void MC6809::run_one_opecode() -{ - if(__USE_DEBUGGER) { - bool now_debugging = d_debugger->now_debugging; - if(now_debugging) { - d_debugger->check_break_points(PC); - if(d_debugger->now_suspended) { - d_debugger->now_waiting = true; - emu->start_waiting_in_debugger(); - while(d_debugger->now_debugging && d_debugger->now_suspended) { - emu->process_waiting_in_debugger(); - } - emu->finish_waiting_in_debugger(); - d_debugger->now_waiting = false; - } - if(d_debugger->now_debugging) { - d_mem = d_debugger; - } else { - now_debugging = false; - } - - d_debugger->add_cpu_trace(PC & 0xffff); - int first_icount = icount; - pPPC = pPC; - uint8_t ireg = ROP(PCD); - PC++; - icount -= cycles1[ireg]; - icount -= extra_icount; - extra_icount = 0; - op(ireg); - total_icount += first_icount - icount; - - if(now_debugging) { - if(!d_debugger->now_going) { - d_debugger->now_suspended = true; - } - d_mem = d_mem_stored; - } - } else { - d_debugger->add_cpu_trace(PC & 0xffff); - int first_icount = icount; - pPPC = pPC; - uint8_t ireg = ROP(PCD); - PC++; - icount -= cycles1[ireg]; - icount -= extra_icount; - extra_icount = 0; - op(ireg); - total_icount += first_icount - icount; - } - } else { - pPPC = pPC; - d_debugger->add_cpu_trace(PC & 0xffff); - uint8_t ireg = ROP(PCD); - PC++; - icount -= cycles1[ireg]; - icount -= extra_icount; - extra_icount = 0; - op(ireg); - } +/* $dD STD direct -**0- */ +OP_HANDLER(std_di) { + DIRECT; + STORE16_REG(&pD); } -void MC6809::debugger_hook() -{ - if(__USE_DEBUGGER) { - bool now_debugging = d_debugger->now_debugging; - if(now_debugging) { - d_debugger->check_break_points(PC); - if(d_debugger->now_suspended) { - d_debugger->now_waiting = true; - emu->start_waiting_in_debugger(); - while(d_debugger->now_debugging && d_debugger->now_suspended) { - emu->process_waiting_in_debugger(); - } - emu->finish_waiting_in_debugger(); - d_debugger->now_waiting = false; - } - if(d_debugger->now_debugging) { - d_mem = d_debugger; - } else { - now_debugging = false; - } - - //d_debugger->add_cpu_trace(PC); - int first_icount = icount; - //pPPC = pPC; - if(now_debugging) { - if(!d_debugger->now_going) { - d_debugger->now_suspended = true; - } - d_mem = d_mem_stored; - } - } +/* $dE LDU (LDS) direct -**0- */ +OP_HANDLER(ldu_di) { + DIRWORD(pU); + U = LOAD16_REG(U); +} + +/* $10dE LDS direct -**0- */ +OP_HANDLER(lds_di) { + DIRWORD(pS); + S = LOAD16_REG(S); + int_state |= MC6809_LDS; +} + +/* $dF STU (STS) direct -**0- */ +OP_HANDLER(stu_di) { + DIRECT; + STORE16_REG(&pU); +} + +/* $10dF STS direct -**0- */ +OP_HANDLER(sts_di) { + DIRECT; + STORE16_REG(&pS); +} + +/* $e0 SUBB indexed ?**** */ +OP_HANDLER(subb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = SUB8_REG(B, t); +} + +/* $e1 CMPB indexed ?**** */ +OP_HANDLER(cmpb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = CMP8_REG(B, t); +} + +/* $e2 SBCB indexed ?**** */ +OP_HANDLER(sbcb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = SBC8_REG(B, t); +} + +/* $e3 ADDD indexed -**** */ +OP_HANDLER(addd_ix) { + pair32_t b; + b = GET_INDEXED_DATA16(); + D = ADD16_REG(D, b.w.l); +} + +/* $e4 ANDB indexed -**0- */ +OP_HANDLER(andb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = AND8_REG(B, t); +} + +/* $e5 BITB indexed -**0- */ +OP_HANDLER(bitb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = BIT8_REG(B, t); +} + +/* $e6 LDB indexed -**0- */ +OP_HANDLER(ldb_ix) { + B = GET_INDEXED_DATA(); + B = LOAD8_REG(B); +} + +/* $e7 STB indexed -**0- */ +OP_HANDLER(stb_ix) { + fetch_effective_address(); + STORE8_REG(B); +} + +/* $e8 EORB indexed -**0- */ +OP_HANDLER(eorb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = EOR8_REG(B, t); +} + +/* $e9 ADCB indexed ***** */ +OP_HANDLER(adcb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = ADC8_REG(B, t); +} + +/* $eA ORB indexed -**0- */ +OP_HANDLER(orb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = OR8_REG(B, t); +} + +/* $eB ADDB indexed ***** */ +OP_HANDLER(addb_ix) { + uint8_t t; + t = GET_INDEXED_DATA(); + B = ADD8_REG(B, t); +} + +/* $eC LDD indexed -**0- */ +OP_HANDLER(ldd_ix) { + pair32_t t; + t = GET_INDEXED_DATA16(); + D = t.w.l; + D = LOAD16_REG(D); +} + +/* $eD STD indexed -**0- */ +OP_HANDLER(std_ix) { + fetch_effective_address(); + STORE16_REG(&pD); +} + +/* $eE LDU (LDS) indexed -**0- */ +OP_HANDLER(ldu_ix) { + pair32_t t; + t = GET_INDEXED_DATA16(); + U = t.w.l; + U = LOAD16_REG(U); +} + +/* $10eE LDS indexed -**0- */ +OP_HANDLER(lds_ix) { + pair32_t t; + t = GET_INDEXED_DATA16(); + S = t.w.l; + S = LOAD16_REG(S); + int_state |= MC6809_LDS; +} + +/* $eF STU (STS) indexed -**0- */ +OP_HANDLER(stu_ix) { + fetch_effective_address(); + STORE16_REG(&pU); +} + +/* $10eF STS indexed -**0- */ +OP_HANDLER(sts_ix) { + fetch_effective_address(); + STORE16_REG(&pS); +} + +/* $f0 SUBB extended ?**** */ +OP_HANDLER(subb_ex) { + uint8_t t; + EXTBYTE(t); + B = SUB8_REG(B, t); +} + +/* $f1 CMPB extended ?**** */ +OP_HANDLER(cmpb_ex) { + uint8_t t; + EXTBYTE(t); + B = CMP8_REG(B, t); +} + +/* $f2 SBCB extended ?**** */ +OP_HANDLER(sbcb_ex) { + uint8_t t; + EXTBYTE(t); + B = SBC8_REG(B, t); +} + +/* $f3 ADDD extended -**** */ +OP_HANDLER(addd_ex) { + pair32_t b; + EXTWORD(b); + D = ADD16_REG(D, b.w.l); +} + +/* $f4 ANDB extended -**0- */ +OP_HANDLER(andb_ex) { + uint8_t t; + EXTBYTE(t); + B = AND8_REG(B, t); +} + +/* $f5 BITB extended -**0- */ +OP_HANDLER(bitb_ex) { + uint8_t t; + EXTBYTE(t); + B = BIT8_REG(B, t); +} + +/* $f6 LDB extended -**0- */ +OP_HANDLER(ldb_ex) { + EXTBYTE(B); + B = LOAD8_REG(B); +} + +/* $f7 STB extended -**0- */ +OP_HANDLER(stb_ex) { + EXTENDED; + STORE8_REG(B); +} + +/* $f8 EORB extended -**0- */ +OP_HANDLER(eorb_ex) { + uint8_t t; + EXTBYTE(t); + B = EOR8_REG(B, t); +} + +/* $f9 ADCB extended ***** */ +OP_HANDLER(adcb_ex) { + uint8_t t; + EXTBYTE(t); + B = ADC8_REG(B, t); +} + +/* $fA ORB extended -**0- */ +OP_HANDLER(orb_ex) { + uint8_t t; + EXTBYTE(t); + B = OR8_REG(B, t); +} + +/* $fB ADDB extended ***** */ +OP_HANDLER(addb_ex) { + uint8_t t; + EXTBYTE(t); + B = ADD8_REG(B, t); +} + +/* $fC LDD extended -**0- */ +OP_HANDLER(ldd_ex) { + EXTWORD(pD); + D = LOAD16_REG(D); +} + +/* $fD STD extended -**0- */ +OP_HANDLER(std_ex) { + EXTENDED; + STORE16_REG(&pD); +} + +/* $fE LDU (LDS) extended -**0- */ +OP_HANDLER(ldu_ex) { + EXTWORD(pU); + U = LOAD16_REG(U); +} + +/* $10fE LDS extended -**0- */ +OP_HANDLER(lds_ex) { + EXTWORD(pS); + S = LOAD16_REG(S); + int_state |= MC6809_LDS; +} + +/* $fF STU (STS) extended -**0- */ +OP_HANDLER(stu_ex) { + EXTENDED; + STORE16_REG(&pU); +} + +/* $10fF STS extended -**0- */ +OP_HANDLER(sts_ex) { + EXTENDED; + STORE16_REG(&pS); +} + + +/* $10xx opcodes */ +OP_HANDLER(pref10) { + uint8_t ireg2 = ROP_ARG(PCD); + PC++; + switch (ireg2) { + case 0x20: + lbra(); + icount -= 5; + break; // 20111217 + case 0x21: + lbrn(); + icount -= 5; + break; + case 0x22: + lbhi(); + icount -= 5; + break; + case 0x23: + lbls(); + icount -= 5; + break; + case 0x24: + lbcc(); + icount -= 5; + break; + case 0x25: + lbcs(); + icount -= 5; + break; + case 0x26: + lbne(); + icount -= 5; + break; + case 0x27: + lbeq(); + icount -= 5; + break; + case 0x28: + lbvc(); + icount -= 5; + break; + case 0x29: + lbvs(); + icount -= 5; + break; + case 0x2a: + lbpl(); + icount -= 5; + break; + case 0x2b: + lbmi(); + icount -= 5; + break; + case 0x2c: + lbge(); + icount -= 5; + break; + case 0x2d: + lblt(); + icount -= 5; + break; + case 0x2e: + lbgt(); + icount -= 5; + break; + case 0x2f: + lble(); + icount -= 5; + break; + case 0x3f: + swi2(); + icount -= 20; + break; + case 0x83: + cmpd_im(); + icount -= 5; + break; + case 0x8c: + cmpy_im(); + icount -= 5; + break; + case 0x8d: + lbsr(); + icount -= 9; + break; + case 0x8e: + ldy_im(); + icount -= 4; + break; +// case 0x8f: flag16_im();->cycle=4; break; // 20130417 + case 0x93: + cmpd_di(); + icount -= 7; + break; + case 0x9c: + cmpy_di(); + icount -= 7; + break; + case 0x9e: + ldy_di(); + icount -= 6; + break; + case 0x9f: + sty_di(); + icount -= 6; + break; + case 0xa3: + cmpd_ix(); + icount -= 7; + break; + case 0xac: + cmpy_ix(); + icount -= 7; + break; + case 0xae: + ldy_ix(); + icount -= 6; + break; + case 0xaf: + sty_ix(); + icount -= 6; + break; + case 0xb3: + cmpd_ex(); + icount -= 8; + break; + case 0xbc: + cmpy_ex(); + icount -= 8; + break; + case 0xbe: + ldy_ex(); + icount -= 7; + break; + case 0xbf: + sty_ex(); + icount -= 7; + break; + case 0xce: + lds_im(); + icount -= 4; + break; +// case 0xcf: flag16_im();->cycle=4; break; + case 0xde: + lds_di(); + icount -= 6; + break; + case 0xdf: + sts_di(); + icount -= 6; + break; + case 0xee: + lds_ix(); + icount -= 6; + break; + case 0xef: + sts_ix(); + icount -= 6; + break; + case 0xfe: + lds_ex(); + icount -= 7; + break; + case 0xff: + sts_ex(); + icount -= 7; + break; + default: + PC--; + IIError(); + break; } } +/* $11xx opcodes */ +OP_HANDLER(pref11) { + uint8_t ireg2 = ROP_ARG(PCD); + PC++; + switch (ireg2) { + case 0x3f: + swi3(); + icount -= 20; + break; -// from MAME 0.160 + case 0x83: + cmpu_im(); + icount -= 5; + break; + case 0x8c: + cmps_im(); + icount -= 5; + break; + + case 0x93: + cmpu_di(); + icount -= 7; + break; + case 0x9c: + cmps_di(); + icount -= 7; + break; + + case 0xa3: + cmpu_ix(); + icount -= 7; + break; + case 0xac: + cmps_ix(); + icount -= 7; + break; + + case 0xb3: + cmpu_ex(); + icount -= 8; + break; + case 0xbc: + cmps_ex(); + icount -= 8; + break; + + default: + PC--; + IIError(); + break; + } + } +// from MAME 0.160 //#ifdef USE_DEBUGGER /***************************************************************************** @@ -827,3 +4650,153 @@ int MC6809::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_ } + +bool MC6809::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ +//#ifdef USE_DEBUGGER + if(_tcsicmp(reg, _T("PC")) == 0) { + PC = data; + } else if(_tcsicmp(reg, _T("DP")) == 0) { + DP = data; + } else if(_tcsicmp(reg, _T("A")) == 0) { + A = data; + } else if(_tcsicmp(reg, _T("B")) == 0) { + B = data; + } else if(_tcsicmp(reg, _T("D")) == 0) { + D = data; + } else if(_tcsicmp(reg, _T("U")) == 0) { + U = data; + } else if(_tcsicmp(reg, _T("X")) == 0) { + X = data; + } else if(_tcsicmp(reg, _T("Y")) == 0) { + Y = data; + } else if(_tcsicmp(reg, _T("S")) == 0) { + S = data; + } else if(_tcsicmp(reg, _T("CC")) == 0) { + CC = data; + } else { + return false; + } +//#endif + return true; +} + +bool MC6809::get_debug_regs_description(_TCHAR *buffer, size_t buffer_len) +{ + my_stprintf_s(buffer, buffer_len, + _T("PC : PROGRAM COUNTER (16bit)\n") + _T("CC : CONDITION FLAGS (16bit)\n") + _T("DP : DIRECT POINTER (8bit)\n") + _T("S : SYSTEM STACK POINTER (16bit)\n") + _T("U : USER STACK POINTER (16bit)\n") + _T("X : INDEX REGISTER (16bit)\n") + _T("Y : INDEX REGISTER (16bit)\n") + _T("A : ACCUMLATOR (8bit)\n") + _T("B : ACCUMLATOR (8bit)\n") + _T("D : ACCUMLATOR (16bit)\n") + _T("NOTE: D is chain of A and B.D = (A << 8) | B.\n") + _T("NOTE: ENDIANNESS is BIG.\n") + _T("ADDRESSING:\n") + _T("foo #bar (16/8bit) : immediate value of bar\n") + _T("foo StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(icount); + state_fio->StateValue(extra_icount); + state_fio->StateValue(int_state); + + state_fio->StateValue(pc.d); + state_fio->StateValue(ppc.d); + state_fio->StateValue(acc.d); + state_fio->StateValue(dp.d); + state_fio->StateValue(u.d); + state_fio->StateValue(s.d); + state_fio->StateValue(x.d); + state_fio->StateValue(y.d); + state_fio->StateValue(cc); + state_fio->StateValue(ea.d); + + // V2 + state_fio->StateValue(req_halt_on); + state_fio->StateValue(req_halt_off); + state_fio->StateValue(busreq); + + state_fio->StateValue(total_icount); + state_fio->StateValue(waitfactor); + state_fio->StateValue(waitcount); + + // post process + if(loading) { + prev_total_icount = total_icount; + // Post process for collecting statistics. + cycles_tmp_count = total_icount; + extra_tmp_count = 0; + insns_count = 0; + frames_count = 0; + nmi_count = 0; + firq_count = 0; + irq_count = 0; + } + return true; +} diff --git a/source/src/vm/mc6809.h b/source/src/vm/mc6809.h index 8c7f6eb7b..2d0cb9a55 100644 --- a/source/src/vm/mc6809.h +++ b/source/src/vm/mc6809.h @@ -32,10 +32,9 @@ enum { // Note: Below is ugly hack cause of CPU#0 cannot modify clock. -class VM; -class EMU; class DEBUGGER; -class MC6809_BASE : public DEVICE + +class DLL_PREFIX MC6809 : public DEVICE { protected: // context @@ -72,14 +71,19 @@ class MC6809_BASE : public DEVICE int icount; int extra_icount; - void __FASTCALL WM16(uint32_t Addr, pair32_t *p); - void __FASTCALL cpu_irq_push(void); - void __FASTCALL cpu_firq_push(void); - void __FASTCALL cpu_nmi_push(void); - void __FASTCALL cpu_irq_fetch_vector_address(void); - void __FASTCALL cpu_firq_fetch_vector_address(void); - void __FASTCALL cpu_nmi_fetch_vector_address(void); - void __FASTCALL cpu_wait(int clocks = 1); + bool __USE_DEBUGGER; + + uint64_t cycles_tmp_count; + uint32_t insns_count; + uint32_t extra_tmp_count; + uint32_t nmi_count; + uint32_t firq_count; + uint32_t irq_count; + int frames_count; + + // Op table + void (__FASTCALL MC6809::*m6809_main[0x100]) (void); + static void (__FASTCALL MC6809::*m6809_optable[0x100]) (void); // Tables /* increment */ const uint8_t flags8i[256] = { @@ -164,11 +168,17 @@ class MC6809_BASE : public DEVICE /*E*/ 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, /*F*/ 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 }; - // opcodes - virtual void __FASTCALL run_one_opecode(); - void __FASTCALL op(uint8_t ireg); - void __FASTCALL fetch_effective_address(); - void __FASTCALL fetch_effective_address_IDX(uint8_t upper, uint8_t lower); + + // Primitives + void __FASTCALL WM16(uint32_t Addr, pair32_t *p); + void __FASTCALL cpu_irq_push(void); + void __FASTCALL cpu_firq_push(void); + void __FASTCALL cpu_nmi_push(void); + void __FASTCALL cpu_irq_fetch_vector_address(void); + void __FASTCALL cpu_firq_fetch_vector_address(void); + void __FASTCALL cpu_nmi_fetch_vector_address(void); + void __FASTCALL cpu_wait(int clocks = 1); + // Useful routines. inline void __FASTCALL BRANCH(bool cond); inline void __FASTCALL LBRANCH(bool cond); @@ -220,7 +230,8 @@ class MC6809_BASE : public DEVICE inline uint16_t CMP16_REG(uint16_t reg, uint16_t data); inline uint16_t LOAD16_REG(uint16_t reg); inline void __FASTCALL STORE16_REG(pair32_t *p); - public: + + // Instructions. void __FASTCALL abx(); void __FASTCALL adca_di(); void __FASTCALL adca_ex(); @@ -517,17 +528,17 @@ class MC6809_BASE : public DEVICE void __FASTCALL tst_ex(); void __FASTCALL tst_ix(); - bool __USE_DEBUGGER; - uint64_t cycles_tmp_count; - uint32_t insns_count; - uint32_t extra_tmp_count; - uint32_t nmi_count; - uint32_t firq_count; - uint32_t irq_count; - int frames_count; + // opcodes + virtual void __FASTCALL run_one_opecode(); + void __FASTCALL op(uint8_t ireg); + void __FASTCALL fetch_effective_address(); + void __FASTCALL fetch_effective_address_IDX(uint8_t upper, uint8_t lower); + virtual uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram); + virtual void __FASTCALL debugger_hook(void); + public: - MC6809_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MC6809(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { total_icount = prev_total_icount = 0; @@ -535,11 +546,35 @@ class MC6809_BASE : public DEVICE insns_count = 0; __USE_DEBUGGER = false; d_debugger = NULL; + for(int i = 0; i < 0x100; i++) { + m6809_main[i] = &MC6809::nop; + } + initialize_output_signals(&outputs_bus_ba); initialize_output_signals(&outputs_bus_bs); set_device_name(_T("MC6809 MPU")); } - ~MC6809_BASE() {} + ~MC6809() {} + + // common functions + virtual void initialize(); + virtual void reset(); + void event_frame(); + + int __FASTCALL run(int clock); + + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + virtual bool process_state(FILEIO* state_fio, bool loading); + + void __FASTCALL set_extra_clock(int clock) + { + extra_icount += clock; + } + int get_extra_clock() + { + return extra_icount; + } + bool is_cpu() { @@ -563,17 +598,20 @@ class MC6809_BASE : public DEVICE } void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_data16(uint32_t addr, uint32_t data) { write_debug_data8(addr, (data >> 8) & 0xff); write_debug_data8(addr + 1, data & 0xff); } + uint32_t __FASTCALL read_debug_data16(uint32_t addr) { uint32_t val = read_debug_data8(addr) << 8; val |= read_debug_data8(addr + 1); return val; } + void __FASTCALL write_debug_data32(uint32_t addr, uint32_t data) { write_debug_data16(addr, (data >> 16) & 0xffff); @@ -585,50 +623,40 @@ class MC6809_BASE : public DEVICE val |= read_debug_data16(addr + 2); return val; } + void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_debug_io8(uint32_t addr); + void __FASTCALL write_debug_io16(uint32_t addr, uint32_t data) { write_debug_io8(addr, (data >> 8) & 0xff); write_debug_io8(addr + 1, data & 0xff); } + uint32_t __FASTCALL read_debug_io16(uint32_t addr) { uint32_t val = read_debug_io8(addr) << 8; val |= read_debug_io8(addr + 1); return val; } + void __FASTCALL write_debug_io32(uint32_t addr, uint32_t data) { write_debug_io16(addr, (data >> 16) & 0xffff); write_debug_io16(addr + 2, data & 0xffff); } + uint32_t __FASTCALL read_debug_io32(uint32_t addr) { uint32_t val = read_debug_io16(addr) << 16; val |= read_debug_io16(addr + 2); return val; } - bool write_debug_reg(const _TCHAR *reg, uint32_t data); - bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data); + virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + virtual bool get_debug_regs_description(_TCHAR *buffer, size_t buffer_len); virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); - virtual uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram); - virtual void __FASTCALL debugger_hook(void); - // common functions - void reset(); - virtual void initialize(); - int __FASTCALL run(int clock); - void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - bool process_state(FILEIO* state_fio, bool loading); - - void set_extra_clock(int clock) - { - extra_icount += clock; - } - int get_extra_clock() - { - return extra_icount; - } + uint32_t get_pc() { return ppc.w.l; @@ -689,22 +717,7 @@ class MC6809_BASE : public DEVICE { d_debugger = device; } - void event_frame(); -}; -class MC6809 : public MC6809_BASE -{ - - public: - MC6809(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MC6809_BASE(parent_vm, parent_emu) - { - } - ~MC6809() {} - void initialize(); - void __FASTCALL run_one_opecode(); - uint32_t cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram); - virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); - void __FASTCALL debugger_hook(void); }; #endif diff --git a/source/src/vm/mc6809_base.cpp b/source/src/vm/mc6809_base.cpp deleted file mode 100644 index 3c3552f72..000000000 --- a/source/src/vm/mc6809_base.cpp +++ /dev/null @@ -1,3998 +0,0 @@ -/* - Skelton for retropc emulator - - Origin : MAME 0.142 - Author : Takeda.Toshiya - Date : 2011.05.06- - - [ MC6809 ] - Notes from K.Ohta at Jan 16, 2015: - All of undocumented instructions (i.e. ngc, flag16) of MC6809(not HD6309) are written by me. - These behaviors of undocumented insns are refered from "vm/cpu_x86.asm" (ia32 assembly codefor nasm) within XM7 - written by Ryu Takegami , and older article wrote in magazine, "I/O" at 1985. - But, these C implements are written from scratch by me , and I tested many years at XM7/SDL. - Perhaps, these insns. are not implement MAME/MESS yet. -*/ - -// Fixed IRQ/FIRQ by Mr.Sasaji at 2011.06.17 -#include "./mc6809.h" -#include "./mc6809_consts.h" -#include "common.h" -#include "../config.h" - -#define OP_HANDLER(_name) void MC6809_BASE::_name (void) - -static void (__FASTCALL MC6809_BASE::*m6809_main[0x100]) (void) = { -/* 0xX0, 0xX1, 0xX2, 0xX3, 0xX4, 0xX5, 0xX6, 0xX7, - 0xX8, 0xX9, 0xXA, 0xXB, 0xXC, 0xXD, 0xXE, 0xXF */ - -/* 0x0X */ - &MC6809_BASE::neg_di, &MC6809_BASE::neg_di, &MC6809_BASE::ngc_di, &MC6809_BASE::com_di, - &MC6809_BASE::lsr_di, &MC6809_BASE::lsr_di, &MC6809_BASE::ror_di, &MC6809_BASE::asr_di, - &MC6809_BASE::asl_di, &MC6809_BASE::rol_di, &MC6809_BASE::dec_di, &MC6809_BASE::dcc_di, - &MC6809_BASE::inc_di, &MC6809_BASE::tst_di, &MC6809_BASE::jmp_di, &MC6809_BASE::clr_di, -/* 0x1X */ - &MC6809_BASE::pref10, &MC6809_BASE::pref11, &MC6809_BASE::nop, &MC6809_BASE::sync_09, - &MC6809_BASE::trap, &MC6809_BASE::trap, &MC6809_BASE::lbra, &MC6809_BASE::lbsr, - &MC6809_BASE::aslcc_in, &MC6809_BASE::daa, &MC6809_BASE::orcc, &MC6809_BASE::nop, - &MC6809_BASE::andcc, &MC6809_BASE::sex, &MC6809_BASE::exg, &MC6809_BASE::tfr, -/* 0x2X */ - &MC6809_BASE::bra, &MC6809_BASE::brn, &MC6809_BASE::bhi, &MC6809_BASE::bls, - &MC6809_BASE::bcc, &MC6809_BASE::bcs, &MC6809_BASE::bne, &MC6809_BASE::beq, - &MC6809_BASE::bvc, &MC6809_BASE::bvs, &MC6809_BASE::bpl, &MC6809_BASE::bmi, - &MC6809_BASE::bge, &MC6809_BASE::blt, &MC6809_BASE::bgt, &MC6809_BASE::ble, -/* 0x3X */ - &MC6809_BASE::leax, &MC6809_BASE::leay, &MC6809_BASE::leas, &MC6809_BASE::leau, - &MC6809_BASE::pshs, &MC6809_BASE::puls, &MC6809_BASE::pshu, &MC6809_BASE::pulu, - &MC6809_BASE::andcc, &MC6809_BASE::rts, &MC6809_BASE::abx, &MC6809_BASE::rti, - &MC6809_BASE::cwai, &MC6809_BASE::mul, &MC6809_BASE::rst, &MC6809_BASE::swi, -/* 0x4X */ - &MC6809_BASE::nega, &MC6809_BASE::nega, &MC6809_BASE::ngca, &MC6809_BASE::coma, - &MC6809_BASE::lsra, &MC6809_BASE::lsra, &MC6809_BASE::rora, &MC6809_BASE::asra, - &MC6809_BASE::asla, &MC6809_BASE::rola, &MC6809_BASE::deca, &MC6809_BASE::dcca, - &MC6809_BASE::inca, &MC6809_BASE::tsta, &MC6809_BASE::clca, &MC6809_BASE::clra, -/* 0x5X */ - &MC6809_BASE::negb, &MC6809_BASE::negb, &MC6809_BASE::ngcb, &MC6809_BASE::comb, - &MC6809_BASE::lsrb, &MC6809_BASE::lsrb, &MC6809_BASE::rorb, &MC6809_BASE::asrb, - &MC6809_BASE::aslb, &MC6809_BASE::rolb, &MC6809_BASE::decb, &MC6809_BASE::dccb, - &MC6809_BASE::incb, &MC6809_BASE::tstb, &MC6809_BASE::clcb, &MC6809_BASE::clrb, -/* 0x6X */ - &MC6809_BASE::neg_ix, &MC6809_BASE::neg_ix, &MC6809_BASE::ngc_ix, &MC6809_BASE::com_ix, - &MC6809_BASE::lsr_ix, &MC6809_BASE::lsr_ix, &MC6809_BASE::ror_ix, &MC6809_BASE::asr_ix, - &MC6809_BASE::asl_ix, &MC6809_BASE::rol_ix, &MC6809_BASE::dec_ix, &MC6809_BASE::dcc_ix, - &MC6809_BASE::inc_ix, &MC6809_BASE::tst_ix, &MC6809_BASE::jmp_ix, &MC6809_BASE::clr_ix, -/* 0x7X */ - &MC6809_BASE::neg_ex, &MC6809_BASE::neg_ex, &MC6809_BASE::ngc_ex, &MC6809_BASE::com_ex, - &MC6809_BASE::lsr_ex, &MC6809_BASE::lsr_ex, &MC6809_BASE::ror_ex, &MC6809_BASE::asr_ex, - &MC6809_BASE::asl_ex, &MC6809_BASE::rol_ex, &MC6809_BASE::dec_ex, &MC6809_BASE::dcc_ex, - &MC6809_BASE::inc_ex, &MC6809_BASE::tst_ex, &MC6809_BASE::jmp_ex, &MC6809_BASE::clr_ex, -/* 0x8X */ - &MC6809_BASE::suba_im, &MC6809_BASE::cmpa_im, &MC6809_BASE::sbca_im, &MC6809_BASE::subd_im, - &MC6809_BASE::anda_im, &MC6809_BASE::bita_im, &MC6809_BASE::lda_im, &MC6809_BASE::flag8_im, - &MC6809_BASE::eora_im, &MC6809_BASE::adca_im, &MC6809_BASE::ora_im, &MC6809_BASE::adda_im, - &MC6809_BASE::cmpx_im, &MC6809_BASE::bsr, &MC6809_BASE::ldx_im, &MC6809_BASE::flag16_im, -/* 0x9X */ - &MC6809_BASE::suba_di, &MC6809_BASE::cmpa_di, &MC6809_BASE::sbca_di, &MC6809_BASE::subd_di, - &MC6809_BASE::anda_di, &MC6809_BASE::bita_di, &MC6809_BASE::lda_di, &MC6809_BASE::sta_di, - &MC6809_BASE::eora_di, &MC6809_BASE::adca_di, &MC6809_BASE::ora_di, &MC6809_BASE::adda_di, - &MC6809_BASE::cmpx_di, &MC6809_BASE::jsr_di, &MC6809_BASE::ldx_di, &MC6809_BASE::stx_di, -/* 0xAX */ - &MC6809_BASE::suba_ix, &MC6809_BASE::cmpa_ix, &MC6809_BASE::sbca_ix, &MC6809_BASE::subd_ix, - &MC6809_BASE::anda_ix, &MC6809_BASE::bita_ix, &MC6809_BASE::lda_ix, &MC6809_BASE::sta_ix, - &MC6809_BASE::eora_ix, &MC6809_BASE::adca_ix, &MC6809_BASE::ora_ix, &MC6809_BASE::adda_ix, - &MC6809_BASE::cmpx_ix, &MC6809_BASE::jsr_ix, &MC6809_BASE::ldx_ix, &MC6809_BASE::stx_ix, -/* 0xBX */ - &MC6809_BASE::suba_ex, &MC6809_BASE::cmpa_ex, &MC6809_BASE::sbca_ex, &MC6809_BASE::subd_ex, - &MC6809_BASE::anda_ex, &MC6809_BASE::bita_ex, &MC6809_BASE::lda_ex, &MC6809_BASE::sta_ex, - &MC6809_BASE::eora_ex, &MC6809_BASE::adca_ex, &MC6809_BASE::ora_ex, &MC6809_BASE::adda_ex, - &MC6809_BASE::cmpx_ex, &MC6809_BASE::jsr_ex, &MC6809_BASE::ldx_ex, &MC6809_BASE::stx_ex, -/* 0xCX */ - &MC6809_BASE::subb_im, &MC6809_BASE::cmpb_im, &MC6809_BASE::sbcb_im, &MC6809_BASE::addd_im, - &MC6809_BASE::andb_im, &MC6809_BASE::bitb_im, &MC6809_BASE::ldb_im, &MC6809_BASE::flag8_im, - &MC6809_BASE::eorb_im, &MC6809_BASE::adcb_im, &MC6809_BASE::orb_im, &MC6809_BASE::addb_im, - &MC6809_BASE::ldd_im, &MC6809_BASE::trap, &MC6809_BASE::ldu_im, &MC6809_BASE::flag16_im, -/* 0xDX */ - &MC6809_BASE::subb_di, &MC6809_BASE::cmpb_di, &MC6809_BASE::sbcb_di, &MC6809_BASE::addd_di, - &MC6809_BASE::andb_di, &MC6809_BASE::bitb_di, &MC6809_BASE::ldb_di, &MC6809_BASE::stb_di, - &MC6809_BASE::eorb_di, &MC6809_BASE::adcb_di, &MC6809_BASE::orb_di, &MC6809_BASE::addb_di, - &MC6809_BASE::ldd_di, &MC6809_BASE::std_di, &MC6809_BASE::ldu_di, &MC6809_BASE::stu_di, -/* 0xEX */ - &MC6809_BASE::subb_ix, &MC6809_BASE::cmpb_ix, &MC6809_BASE::sbcb_ix, &MC6809_BASE::addd_ix, - &MC6809_BASE::andb_ix, &MC6809_BASE::bitb_ix, &MC6809_BASE::ldb_ix, &MC6809_BASE::stb_ix, - &MC6809_BASE::eorb_ix, &MC6809_BASE::adcb_ix, &MC6809_BASE::orb_ix, &MC6809_BASE::addb_ix, - &MC6809_BASE::ldd_ix, &MC6809_BASE::std_ix, &MC6809_BASE::ldu_ix, &MC6809_BASE::stu_ix, -/* 0xFX */ - &MC6809_BASE::subb_ex, &MC6809_BASE::cmpb_ex, &MC6809_BASE::sbcb_ex, &MC6809_BASE::addd_ex, - &MC6809_BASE::andb_ex, &MC6809_BASE::bitb_ex, &MC6809_BASE::ldb_ex, &MC6809_BASE::stb_ex, - &MC6809_BASE::eorb_ex, &MC6809_BASE::adcb_ex, &MC6809_BASE::orb_ex, &MC6809_BASE::addb_ex, - &MC6809_BASE::ldd_ex, &MC6809_BASE::std_ex, &MC6809_BASE::ldu_ex, &MC6809_BASE::stu_ex - }; -/* macros for branch instructions */ -inline void MC6809_BASE::BRANCH(bool cond) -{ - uint8_t t; - IMMBYTE(t); - if(!cond) return; - PC = PC + SIGNED(t); - PC = PC & 0xffff; -} - -inline void MC6809_BASE::LBRANCH(bool cond) -{ - pair32_t t; - IMMWORD(t); - if(!cond) return; - icount -= 1; - PC += t.w.l; - PC = PC & 0xffff; -} - -/* macros for setting/getting registers in TFR/EXG instructions */ - -inline pair32_t MC6809_BASE::RM16_PAIR(uint32_t addr) -{ - pair32_t b; - b.d = 0; - b.b.h = RM(addr); - b.b.l = RM((addr + 1)); - return b; -} - -inline void MC6809_BASE::WM16(uint32_t Addr, pair32_t *p) -{ - WM(Addr , p->b.h); - WM((Addr + 1), p->b.l); -} - -void MC6809_BASE::reset() -{ - //extar_tmp_count += extra_icount; - - icount = 0; - waitcount = 0; - int_state &= MC6809_HALT_BIT; - extra_icount = 0; - //busreq = false; - - DPD = 0; /* Reset direct page register */ - CC = 0; - D = 0; - X = 0; - Y = 0; - U = 0; - S = 0; - EA = 0; -//#if defined(_FM7) || defined(_FM8) || defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS) - - if((req_halt_on) && !(req_halt_off)) { - int_state |= MC6809_HALT_BIT; - } else { - req_halt_on = req_halt_off = false; - } - if((int_state & MC6809_HALT_BIT) != 0) { - write_signals(&outputs_bus_ba, 0xffffffff); - write_signals(&outputs_bus_bs, 0xffffffff); - } else { - write_signals(&outputs_bus_ba, 0x00000000); - write_signals(&outputs_bus_bs, 0x00000000); - } - -//#endif - CC |= CC_II; /* IRQ disabled */ - CC |= CC_IF; /* FIRQ disabled */ - - pPC = RM16_PAIR(0xfffe); -} - - -void MC6809_BASE::initialize() -{ - DEVICE::initialize(); - int_state = 0; - busreq = false; - icount = 0; - extra_icount = 0; - req_halt_on = req_halt_off = false; - cycles_tmp_count = 0; - insns_count = 0; - - __USE_DEBUGGER = osd->check_feature(_T("USE_DEBUGGER")); - insns_count = 0; - frames_count = 0; - cycles_tmp_count = 0; - nmi_count = 0; - firq_count = 0; - irq_count = 0; -// if(config.print_statistics) { - register_frame_event(this); -// } - waitfactor = 0; - waitcount = 0; -} - -void MC6809_BASE::event_frame() -{ - if(frames_count < 0) { - cycles_tmp_count = total_icount; - extra_tmp_count = 0; - insns_count = 0; - frames_count = 0; - nmi_count = 0; - firq_count = 0; - irq_count = 0; - } else if(frames_count >= 16) { - uint64_t _icount = total_icount - cycles_tmp_count; - if(config.print_statistics) { - out_debug_log(_T("INFO: 16 frames done.\nINFO: CLOCKS = %ld INSNS = %d EXTRA_ICOUNT = %d \nINFO: NMI# = %d FIRQ# = %d IRQ# = %d"), _icount, insns_count, extra_tmp_count, nmi_count, firq_count, irq_count); - } - cycles_tmp_count = total_icount; - insns_count = 0; - extra_tmp_count = 0; - frames_count = 0; - nmi_count = 0; - firq_count = 0; - irq_count = 0; - } else { - frames_count++; - } -} - -void MC6809_BASE::write_signal(int id, uint32_t data, uint32_t mask) -{ - if(id == SIG_CPU_IRQ) { - if(data & mask) { - int_state |= MC6809_IRQ_BIT; - irq_count++; - } else { - int_state &= ~MC6809_IRQ_BIT; - } - } else if(id == SIG_CPU_FIRQ) { - if(data & mask) { - int_state |= MC6809_FIRQ_BIT; - firq_count++; - } else { - int_state &= ~MC6809_FIRQ_BIT; - } - } else if(id == SIG_CPU_NMI) { - if(data & mask) { - int_state |= MC6809_NMI_BIT; - nmi_count++; - } else { - int_state &= ~MC6809_NMI_BIT; - } - } else if(id == SIG_CPU_BUSREQ) { - if(data & mask) { - req_halt_on = false; - req_halt_off = false; - int_state |= MC6809_HALT_BIT; - busreq = false; - } else { - req_halt_on = false; - req_halt_off = false; - int_state &= ~MC6809_HALT_BIT; - } - } else if(id == SIG_CPU_HALTREQ) { - if(data & mask) { - req_halt_on = true; - //int_state |= MC6809_HALT_BIT; - } else { - if(req_halt_on) { - req_halt_off = true; - } - //int_state &= ~MC6809_HALT_BIT; - } - } else if(id == SIG_CPU_WAIT_FACTOR) { - waitfactor = data; // 65536. - } -} - -void MC6809_BASE::cpu_nmi_push(void) -{ - if ((int_state & MC6809_CWAI_IN) == 0) { - CC |= CC_E; - PUSHWORD(pPC); - PUSHWORD(pU); - PUSHWORD(pY); - PUSHWORD(pX); - PUSHBYTE(DP); - PUSHBYTE(B); - PUSHBYTE(A); - PUSHBYTE(CC); - } - return; -} - -void MC6809_BASE::cpu_nmi_fetch_vector_address(void) -{ - pPC = RM16_PAIR(0xfffc); -// printf("NMI occured PC=0x%04x VECTOR=%04x SP=%04x \n",rpc.w.l,pPC.w.l,S); - int_state |= MC6809_CWAI_OUT; - //int_state &= ~(MC6809_NMI_BIT | MC6809_SYNC_IN | MC6809_SYNC_OUT | MC6809_CWAI_IN); // $FF1E - return; -} - - - -void MC6809_BASE::cpu_firq_fetch_vector_address(void) -{ - pPC = RM16_PAIR(0xfff6); - int_state |= MC6809_CWAI_OUT; - int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT ); - return; -} - -void MC6809_BASE::cpu_firq_push(void) -{ - //pair32_t rpc = pPC; - if ((int_state & MC6809_CWAI_IN) == 0) { - /* NORMAL */ - CC &= ~CC_E; - PUSHWORD(pPC); - PUSHBYTE(CC); - } -// printf("Firq occured PC=0x%04x VECTOR=%04x SP=%04x \n",rpc.w.l,pPC.w.l,S); -} -void MC6809_BASE::cpu_irq_push(void) -{ - if ((int_state & MC6809_CWAI_IN) == 0) { - CC |= CC_E; - PUSHWORD(pPC); - PUSHWORD(pU); - PUSHWORD(pY); - PUSHWORD(pX); - PUSHBYTE(DP); - PUSHBYTE(B); - PUSHBYTE(A); - PUSHBYTE(CC); - } -} -void MC6809_BASE::cpu_irq_fetch_vector_address(void) -{ - //pair32_t rpc = pPC; - pPC = RM16_PAIR(0xfff8); - int_state |= MC6809_CWAI_OUT; - int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT); -} - -void MC6809_BASE::cpu_wait(int clocks) -{ - uint32_t ncount = 0; - if(clocks < 0) return; - if(waitfactor == 0) return; - waitcount += (waitfactor * (uint32_t)clocks); - if(waitcount >= 65536) { - ncount = waitcount >> 16; - waitcount = waitcount - (ncount << 16); - } - if(ncount > 0) extra_icount += ncount; -} - - -int MC6809_BASE::run(int clock) -{ - int cycle = 0; - int first_icount = 0; - int passed_icount = 0; - first_icount = icount; - if(extra_icount > 0) { - extra_tmp_count += extra_icount; - } - - if((req_halt_on) && !(req_halt_off)) { - int_state |= MC6809_HALT_BIT; - } else if(req_halt_on && req_halt_off) { // HALT OFF - int_state &= ~MC6809_HALT_BIT; - req_halt_on = req_halt_off = false; - } - - if ((int_state & MC6809_HALT_BIT) != 0) { // 0x80 - if(clock <= 0) { - clock = 1; - } else { - icount += clock; - } - first_icount = icount; - if(!busreq) { - write_signals(&outputs_bus_ba, 0); - write_signals(&outputs_bus_bs, 0); - busreq = true; - icount -= clock; - icount -= extra_icount; - extra_icount = 0; - passed_icount = first_icount - icount; - total_icount += passed_icount; - - write_signals(&outputs_bus_ba, 0xffffffff); - write_signals(&outputs_bus_bs, 0xffffffff); - debugger_hook(); - cpu_wait(passed_icount); - return passed_icount; - } else { - icount -= clock; - icount -= extra_icount; - extra_icount = 0; - passed_icount = first_icount - icount; - total_icount += passed_icount; - debugger_hook(); - cpu_wait(passed_icount); - return passed_icount; - } - } - if(busreq) { // Exit from BUSREQ state. - if((int_state & MC6809_SYNC_IN) != 0) { - write_signals(&outputs_bus_ba, 0xffffffff); - } else { - write_signals(&outputs_bus_ba, 0x00000000); - } - write_signals(&outputs_bus_bs, 0x00000000); - busreq = false; - } - if((int_state & MC6809_INSN_HALT) != 0) { // 0x80 - if(clock <= 1) clock = 1; - icount += clock; - first_icount = icount; - while(icount > 0) { - RM(PCD); //Will save.Need to keep. - icount -= 1; - } - icount -= extra_icount; - passed_icount = first_icount - icount; - extra_icount = 0; - PC++; - debugger_hook(); - total_icount += passed_icount; - cpu_wait(passed_icount); - return passed_icount; - } - /* - * Check Interrupt - */ -check_nmi: - if ((int_state & (MC6809_NMI_BIT | MC6809_FIRQ_BIT | MC6809_IRQ_BIT)) != 0) { // 0x0007 - if ((int_state & MC6809_NMI_BIT) == 0) - goto check_firq; - int_state &= ~MC6809_SYNC_IN; // Thanks to Ryu Takegami. - write_signals(&outputs_bus_ba, 0x00000000); - write_signals(&outputs_bus_bs, 0x00000000); - if((int_state & MC6809_CWAI_IN) == 0) { - CC = CC | CC_E; - cycle += 14; - cpu_nmi_push(); - } - write_signals(&outputs_bus_bs, 0xffffffff); - CC = CC | CC_II | CC_IF; // 0x50 - cycle += 2; - cpu_nmi_fetch_vector_address(); - cycle += 3; - write_signals(&outputs_bus_bs, 0x00000000); - int_state &= ~(MC6809_NMI_BIT | MC6809_SYNC_IN | MC6809_SYNC_OUT); // $FF1E - goto int_cycle; - } else { - // OK, none interrupts. - goto check_ok; - } -check_firq: - if ((int_state & MC6809_FIRQ_BIT) != 0) { - int_state &= ~MC6809_SYNC_IN; // Moved to before checking MASK.Thanks to Ryu Takegami. - if ((CC & CC_IF) != 0) - goto check_irq; - write_signals(&outputs_bus_bs, 0x00000000); - write_signals(&outputs_bus_ba, 0x00000000); - if((int_state & MC6809_CWAI_IN) == 0) { - CC = CC & (uint8_t)(~CC_E); - cycle += 5; - cpu_firq_push(); - } - write_signals(&outputs_bus_bs, 0xffffffff); - CC = CC | CC_II | CC_IF; // 0x50 - cycle += 2; - cpu_firq_fetch_vector_address(); - cycle += 3; - write_signals(&outputs_bus_bs, 0x00000000); - int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT); // $FF1E - goto int_cycle; - - } -check_irq: - if ((int_state & MC6809_IRQ_BIT) != 0) { - int_state &= ~MC6809_SYNC_IN; // Moved to before checking MASK.Thanks to Ryu Takegami. - if ((CC & CC_II) != 0) - goto check_ok; - write_signals(&outputs_bus_bs, 0x00000000); - write_signals(&outputs_bus_ba, 0x00000000); - if((int_state & MC6809_CWAI_IN) == 0) { - CC = CC | CC_E; - cycle += 14; - cpu_irq_push(); - } - write_signals(&outputs_bus_bs, 0xffffffff); - cycle += 2; - CC = CC | CC_II; // 0x50 - cpu_irq_fetch_vector_address(); - cycle += 3; - write_signals(&outputs_bus_bs, 0x00000000); - int_state &= ~(MC6809_SYNC_IN | MC6809_SYNC_OUT); // $FF1E - goto int_cycle; - } - /* - * NO INTERRUPT - */ - goto check_ok; - /* - * INTERRUPT - */ -int_cycle: - if((int_state & MC6809_CWAI_IN) != 0) { - int_state &= ~MC6809_CWAI_IN; - } - if(clock >= 0) icount += clock; - first_icount = icount; - icount -= cycle; - debugger_hook(); - icount -= extra_icount; - passed_icount = first_icount - icount; - extra_icount = 0; - total_icount += (uint64_t)passed_icount; - cpu_wait(passed_icount); -#if 1 - if((icount <= 0) || (clock <= passed_icount)) return passed_icount; - clock -= passed_icount; -#else - return passed_icount; -#endif - // goto check_ok; - // run cpu -check_ok: - if((int_state & MC6809_SYNC_IN) != 0) { - int tmp_passed_icount = 0; - first_icount = icount; - if(clock < 1) clock = 1; - icount -= extra_icount; - icount -= clock; - extra_icount = 0; - debugger_hook(); - tmp_passed_icount = first_icount - icount; - total_icount += (uint64_t)passed_icount; - cpu_wait(tmp_passed_icount); - return passed_icount + tmp_passed_icount; - } - if((int_state & MC6809_CWAI_IN) == 0) { - if(clock <= -1) { - // run only one opcode - int tmp_passed_icount = 0; - first_icount = icount; - insns_count++; - run_one_opecode(); - tmp_passed_icount = first_icount - icount; - cpu_wait(tmp_passed_icount); - return passed_icount + tmp_passed_icount;; - } else { - // run cpu while given clocks - int tmp_passed_icount = 0; - icount += clock; - first_icount = icount; - while((icount > 0) && (!(req_halt_on) && !(req_halt_off)) && (!busreq)) { - insns_count++; - run_one_opecode(); - } - tmp_passed_icount = first_icount - icount; - cpu_wait(tmp_passed_icount); - return tmp_passed_icount + passed_icount; - } - } else { // CWAI_IN - int tmp_passed_icount = 0; - first_icount = icount; - if(clock < 1) clock = 1; - icount -= extra_icount; - icount -= clock; - extra_icount = 0; - debugger_hook(); - tmp_passed_icount = first_icount - icount; - total_icount += tmp_passed_icount; - cpu_wait(tmp_passed_icount); - return passed_icount + tmp_passed_icount; - } - -} - -void MC6809_BASE::debugger_hook() -{ - -} - -void MC6809_BASE::run_one_opecode() -{ - pPPC = pPC; - uint8_t ireg = ROP(PCD); - PC++; - icount -= cycles1[ireg]; - icount -= extra_icount; - extra_icount = 0; - op(ireg); -} - -void MC6809_BASE::op(uint8_t ireg) -{ - //printf("CPU(%08x) PC=%04x OP=%02x %02x %02x %02x %02x\n", (void *)this, PC, ireg, RM(PC), RM(PC + 1), RM(PC + 2), RM(PC + 3)); - - (this->*m6809_main[ireg])(); -} - - -void MC6809_BASE::write_debug_data8(uint32_t addr, uint32_t data) -{ - if(__USE_DEBUGGER) d_mem_stored->write_data8(addr, data); -} - -uint32_t MC6809_BASE::read_debug_data8(uint32_t addr) -{ - if(__USE_DEBUGGER) { - return d_mem_stored->read_data8(addr); - } - return 0xff; -} - -void MC6809_BASE::write_debug_io8(uint32_t addr, uint32_t data) -{ - if(__USE_DEBUGGER) d_mem_stored->write_io8(addr, data); -} - -uint32_t MC6809_BASE::read_debug_io8(uint32_t addr) -{ - if(__USE_DEBUGGER) { - uint8_t val = d_mem_stored->read_io8(addr); - return val; - } - return 0xff; -} - - -bool MC6809_BASE::write_debug_reg(const _TCHAR *reg, uint32_t data) -{ -//#ifdef USE_DEBUGGER - if(_tcsicmp(reg, _T("PC")) == 0) { - PC = data; - } else if(_tcsicmp(reg, _T("DP")) == 0) { - DP = data; - } else if(_tcsicmp(reg, _T("A")) == 0) { - A = data; - } else if(_tcsicmp(reg, _T("B")) == 0) { - B = data; - } else if(_tcsicmp(reg, _T("D")) == 0) { - D = data; - } else if(_tcsicmp(reg, _T("U")) == 0) { - U = data; - } else if(_tcsicmp(reg, _T("X")) == 0) { - X = data; - } else if(_tcsicmp(reg, _T("Y")) == 0) { - Y = data; - } else if(_tcsicmp(reg, _T("S")) == 0) { - S = data; - } else if(_tcsicmp(reg, _T("CC")) == 0) { - CC = data; - } else { - return false; - } -//#endif - return true; -} - -/* -PC = 0000 PPC = 0000 -INTR=[ IRQ FIRQ NMI HALT][CI CO SI SO TRAP] CC =[EFHINZVC] -A = 00 B = 00 DP = 00 X = 0000 Y = 0000 U = 0000 S = 0000 EA = 0000 -Clocks = 0 (0) Since Scanline = 0/0 (0/0) -*/ -bool MC6809_BASE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) -{ -//#ifdef USE_DEBUGGER - my_stprintf_s(buffer, buffer_len, - _T("PC = %04x PPC = %04x\n") - _T("INTR = [%s %s %s %s][%s %s %s %s %s] CC = [%c%c%c%c%c%c%c%c]\n") - _T("A = %02x B = %02x DP = %02x X = %04x Y = %04x U = %04x S = %04x EA = %04x\n") - _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), - PC, - PPC, - ((int_state & MC6809_IRQ_BIT) == 0) ? _T("----") : _T(" IRQ"), - ((int_state & MC6809_FIRQ_BIT) == 0) ? _T("----") : _T("FIRQ"), - ((int_state & MC6809_NMI_BIT) == 0) ? _T("----") : _T(" NMI"), - ((int_state & MC6809_HALT_BIT) == 0) ? _T("----") : _T("HALT"), - ((int_state & MC6809_CWAI_IN) == 0) ? _T("--") : _T("CI"), - ((int_state & MC6809_CWAI_OUT) == 0) ? _T("--") : _T("CO"), - ((int_state & MC6809_SYNC_IN) == 0) ? _T("--") : _T("SI"), - ((int_state & MC6809_SYNC_OUT) == 0) ? _T("--") : _T("SO"), - ((int_state & MC6809_INSN_HALT) == 0) ? _T("----") : _T("TRAP"), - ((CC & CC_E) == 0) ? _T('-') : _T('E'), - ((CC & CC_IF) == 0) ? _T('-') : _T('F'), - ((CC & CC_H) == 0) ? _T('-') : _T('H'), - ((CC & CC_II) == 0) ? _T('-') : _T('I'), - ((CC & CC_N) == 0) ? _T('-') : _T('N'), - ((CC & CC_Z) == 0) ? _T('-') : _T('Z'), - ((CC & CC_V) == 0) ? _T('-') : _T('V'), - ((CC & CC_C) == 0) ? _T('-') : _T('C'), - A, B, DP, - X, Y, U, S, - EAD, - total_icount, total_icount - prev_total_icount, - get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame() - ); - prev_total_icount = total_icount; -//#endif - return true; -} - -uint32_t MC6809_BASE::cpu_disassemble_m6809(_TCHAR *buffer, uint32_t pc, const uint8_t *oprom, const uint8_t *opram) -{ - return 0; -} - -int MC6809_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata) -{ - return 0; -} - - - -inline void MC6809_BASE::fetch_effective_address() -{ - uint8_t postbyte; - uint8_t upper, lower; - - IMMBYTE(postbyte); - - upper = (postbyte >> 4) & 0x0f; - lower = postbyte & 0x0f; - switch (upper) { - case 0x00: - EA = X + lower; - break; - case 0x01: - EA = X - 16 + lower; - break; - case 0x02: - EA = Y + lower; - break; - case 0x03: - EA = Y - 16 + lower; - break; - case 0x04: - EA = U + lower; - break; - case 0x05: - EA = U - 16 + lower; - break; - case 0x06: - EA = S + lower; - break; - case 0x07: - EA = S - 16 + lower; - break; - default: - fetch_effective_address_IDX(upper, lower); - break; - } - EAD &= 0xffff; - icount -= index_cycle_em[postbyte]; -} - -inline void MC6809_BASE::fetch_effective_address_IDX(uint8_t upper, uint8_t lower) -{ - bool indirect = false; - uint16_t *reg; - uint8_t bx_p; - pair32_t pp; - - indirect = ((upper & 0x01) != 0) ? true : false; - - switch ((upper >> 1) & 0x03) { // $8-$f >> 1 = $4 - $7 : delete bit2 - case 0: // $8x,$9x - reg = &X; - break; - case 1: // $ax,$bx - reg = &Y; - break; - case 2: // $cx,$dx - reg = &U; - break; - case 3: // $ex,$fx - reg = &S; - break; - } - - switch (lower) { - case 0: // ,r+ - EA = *reg; - *reg = *reg + 1; - *reg = *reg & 0xffff; - break; - case 1: // ,r++ - EA = *reg; - *reg = *reg + 2; - *reg = *reg & 0xffff; - break; - case 2: // ,-r - *reg = *reg - 1; - *reg = *reg & 0xffff; - EA = *reg; - break; - case 3: // ,--r - *reg = *reg - 2; - *reg = *reg & 0xffff; - EA = *reg; - break; - case 4: // ,r - EA = *reg; - break; - case 5: // b,r - EA = *reg + SIGNED(B); - break; - case 6: // a,r - case 7: - EA = *reg + SIGNED(A); - break; - case 8: // $xx,r - IMMBYTE(bx_p); - EA = *reg + SIGNED(bx_p); - break; - case 9: // $xxxx, r - IMMWORD(EAP); - EA = EA + *reg; - break; - case 0x0a: // Undocumented - EA = PC; - EA++; - EAP.w.l |= 0x00ff; - break; - case 0x0b: // D,r - EA = *reg + D; - break; - case 0x0c: // xx,pc - IMMBYTE(bx_p); - EA = PC + SIGNED(bx_p); - break; - case 0x0d: // xxxx,pc - IMMWORD(EAP); - EA = EA + PC; - break; - case 0x0e: // Undocumented - EA = 0xffff; - break; - case 0x0f: - IMMWORD(EAP); - break; - } - EAP.w.h = 0x0000; - // $9x,$bx,$dx,$fx = INDIRECT - if (indirect) { - pp = EAP; - EAP = RM16_PAIR(pp.d); - } -} - -#define IIError() illegal() - -OP_HANDLER(illegal) -{ - //logerror("M6809: illegal opcode at %04x\n",PC); - //printf("M6809: illegal opcode at %04x %02x %02x %02x %02x %02x \n", - // PC - 2, RM(PC - 2), RM(PC - 1), RM(PC), RM(PC + 1), RM(PC + 2)); -// PC-=1; -} - -inline uint8_t MC6809_BASE::GET_INDEXED_DATA(void) -{ - uint8_t t; - fetch_effective_address(); - t = RM(EAD); - return t; -} - -inline pair32_t MC6809_BASE::GET_INDEXED_DATA16(void) -{ - pair32_t t; - fetch_effective_address(); - t = RM16_PAIR(EAD); - return t; -} - -// $x0, $x1 -inline void MC6809_BASE::NEG_MEM(uint8_t a_neg) -{ - uint16_t r_neg; - r_neg = 0 - (uint16_t)a_neg; - CLR_NZVC; - SET_FLAGS8(0, a_neg, r_neg); - WM(EAD, r_neg); -} - -inline uint8_t MC6809_BASE::NEG_REG(uint8_t a_neg) -{ - uint16_t r_neg; - r_neg = 0 - (uint16_t)a_neg; - CLR_NZVC; - SET_FLAGS8(0, a_neg, r_neg); - return (uint8_t)r_neg; -} - - -// $x2 -inline void MC6809_BASE::COM_MEM(uint8_t a_com) -{ - uint8_t t_com; - t_com = ~a_com; - CLR_NZVC; - SET_NZ8(t_com); - SEC; - WM(EAD, t_com); -} - -inline uint8_t MC6809_BASE::COM_REG(uint8_t r_com) -{ - r_com = ~r_com; - CLR_NZVC; - SET_NZ8(r_com); - SEC; - return r_com; -} - -inline void MC6809_BASE::LSR_MEM(uint8_t t) -{ - CLR_NZC; - CC = CC | (t & CC_C); - t >>= 1; - SET_NZ8(t); - WM(EAD, t); -} - -inline uint8_t MC6809_BASE::LSR_REG(uint8_t r) -{ - CLR_NZC; - CC |= (r & CC_C); - r >>= 1; - SET_NZ8(r); - return r; -} - -inline void MC6809_BASE::ROR_MEM(uint8_t t) -{ - uint8_t r; - r = (CC & CC_C) << 7; - CLR_NZC; - CC |= (t & CC_C); - t >>= 1; - r |= t; - SET_NZ8(r); //NZ8? - WM(EAD, r); -} - -inline uint8_t MC6809_BASE::ROR_REG(uint8_t t) -{ - uint8_t r; - r = (CC & CC_C) << 7; - CLR_NZC; - CC |= (t & CC_C); - t >>= 1; - r |= t; - SET_NZ8(r); //NZ8? - return r; -} - - -inline void MC6809_BASE::ASR_MEM(uint8_t t) -{ - uint8_t r; - CLR_NZC; - CC = CC | (t & CC_C); - r = (t & 0x80) | (t >> 1); - // H is undefined - SET_NZ8(r); - //SET_H(t, t, r); - WM(EAD, r); -} - -inline uint8_t MC6809_BASE::ASR_REG(uint8_t t) -{ - uint8_t r; - CLR_NZC; - CC = CC | (t & CC_C); - r = (t & 0x80) | (t >> 1); - // H is undefined - SET_NZ8(r); - //SET_H(t, t, r); - return r; -} - -inline void MC6809_BASE::ASL_MEM(uint8_t t) -{ - uint16_t r, tt; - tt = (uint16_t)t & 0x00ff; - r = tt << 1; - CLR_NZVC; - SET_FLAGS8(tt, tt, r); - //SET_H(tt, tt, r); - WM(EAD, (uint8_t)r); -} - -inline uint8_t MC6809_BASE::ASL_REG(uint8_t t) -{ - uint16_t r, tt; - tt = (uint16_t)t & 0x00ff; - r = tt << 1; - CLR_NZVC; - SET_FLAGS8(tt, tt, r); - //SET_H(tt, tt, r); - return (uint8_t)r; -} - -inline void MC6809_BASE::ROL_MEM(uint8_t t) -{ - uint16_t r, tt; - tt = (uint16_t)t & 0x00ff; - r = (CC & CC_C) | (tt << 1); - CLR_NZVC; - //SET_NZ8(r); - //if(t & 0x80) { - // SEC; - // if((r & 0x80) == 0)SEV; - //} else { - // if((r & 0x80) != 0) SEV; - //} - SET_FLAGS8(tt, tt, r); - WM(EAD, (uint8_t)r); -} - -inline uint8_t MC6809_BASE::ROL_REG(uint8_t t) -{ - uint16_t r, tt; - tt = (uint16_t)t & 0x00ff; - r = (CC & CC_C) | (tt << 1); - CLR_NZVC; - //SET_NZ8(r); - //if(t & 0x80) { - // SEC; - // if((r & 0x80) == 0) SEV; - //} else { - // if((r & 0x80) != 0) SEV; - //} - SET_FLAGS8(tt, tt, r); - return (uint8_t)r; -} - -inline void MC6809_BASE::DEC_MEM(uint8_t t) -{ - uint16_t tt; - tt = t - 1; - CLR_NZV; - SET_FLAGS8D(tt); - WM(EAD, tt); -} - -inline uint8_t MC6809_BASE::DEC_REG(uint8_t t) -{ - uint8_t tt; - tt = t - 1; - CLR_NZV; - SET_FLAGS8D(tt); - return tt; -} - -inline void MC6809_BASE::DCC_MEM(uint8_t t) -{ - uint16_t tt, ss; - tt = t - 1; - CLR_NZVC; - SET_FLAGS8D(tt); - ss = CC; - ss >>= 2; - ss = ~ss; - ss = ss & CC_C; - CC = ss | CC; - WM(EAD, tt); -} - -inline uint8_t MC6809_BASE::DCC_REG(uint8_t t) -{ - uint16_t tt, ss; - tt = t - 1; - CLR_NZVC; - SET_FLAGS8D(tt); - ss = CC; - ss >>= 2; - ss = ~ss; - ss = ss & CC_C; - CC = ss | CC; - return (uint8_t)tt; -} - -inline void MC6809_BASE::INC_MEM(uint8_t t) -{ - uint16_t tt = t + 1; - CLR_NZV; - SET_FLAGS8I(tt); - WM(EAD, tt); -} - -inline uint8_t MC6809_BASE::INC_REG(uint8_t t) -{ - uint16_t tt = t + 1; - CLR_NZV; - SET_FLAGS8I(tt); - return (uint8_t)tt; -} - -inline void MC6809_BASE::TST_MEM(uint8_t t) -{ - CLR_NZV; - SET_NZ8(t); -} - -inline uint8_t MC6809_BASE::TST_REG(uint8_t t) -{ - CLR_NZV; - SET_NZ8(t); - return t; -} - -inline uint8_t MC6809_BASE::CLC_REG(uint8_t t) -{ - uint8_t r; - r = 0; - CLR_NZV; - SEZ; - return r; -} - - -inline void MC6809_BASE::CLR_MEM(uint8_t t) -{ - WM(EAD, 0); - CLR_NZVC; - SEZ; -} - -inline uint8_t MC6809_BASE::CLR_REG(uint8_t t) -{ - CLR_NZVC; - SEZ; - return 0; -} - -inline uint8_t MC6809_BASE::SUB8_REG(uint8_t reg, uint8_t data) -{ - uint16_t r; - r = (uint16_t)reg - (uint16_t)data; - CLR_HNZVC; - // H is undefined - SET_FLAGS8(reg, data, r); - return (uint8_t)r; -} - -inline uint8_t MC6809_BASE::CMP8_REG(uint8_t reg, uint8_t data) -{ - uint16_t r; - r = (uint16_t)reg - (uint16_t)data; - CLR_NZVC; - // H is undefined - SET_FLAGS8(reg, data, r); - return reg; -} - -inline uint8_t MC6809_BASE::SBC8_REG(uint8_t reg, uint8_t data) -{ - uint16_t r; - uint8_t cc_c = CC & CC_C; - r = (uint16_t)reg - (uint16_t)data - (uint16_t)cc_c; - CLR_HNZVC; - SET_FLAGS8(reg, (data + cc_c) , r); - return (uint8_t)r; -} - -inline uint8_t MC6809_BASE::AND8_REG(uint8_t reg, uint8_t data) -{ - uint8_t r = reg; - r &= data; - CLR_NZV; - SET_NZ8(r); - return r; -} - -inline uint8_t MC6809_BASE::BIT8_REG(uint8_t reg, uint8_t data) -{ - uint16_t r; - r = reg & data; - CLR_NZV; - SET_NZ8(r); - SET_V8(reg, data, r); - return reg; -} - -inline uint8_t MC6809_BASE::EOR8_REG(uint8_t reg, uint8_t data) -{ - uint8_t r = reg; - r ^= data; - CLR_NZV; - SET_NZ8(r); - return r; -} - -inline uint8_t MC6809_BASE::OR8_REG(uint8_t reg, uint8_t data) -{ - uint8_t r = reg; - r |= data; - CLR_NZV; - SET_NZ8(r); - return r; -} - -inline uint8_t MC6809_BASE::ADD8_REG(uint8_t reg, uint8_t data) -{ - uint16_t t, r; - t = (uint16_t) data; - t &= 0x00ff; - r = reg + t; - CLR_HNZVC; - SET_HNZVC8(reg, t, r); - return (uint8_t)r; -} - -inline uint8_t MC6809_BASE::ADC8_REG(uint8_t reg, uint8_t data) -{ - uint16_t t, r; - uint8_t c_cc = CC & CC_C; - t = (uint16_t) data; - t &= 0x00ff; - r = reg + t + c_cc; - CLR_HNZVC; - SET_HNZVC8(reg, (t + c_cc), r); - return (uint8_t)r; -} - -inline uint8_t MC6809_BASE::LOAD8_REG(uint8_t reg) -{ - CLR_NZV; - SET_NZ8(reg); - return reg; -} - -inline void MC6809_BASE::STORE8_REG(uint8_t reg) -{ - CLR_NZV; - SET_NZ8(reg); - WM(EAD, reg); -} - -inline uint16_t MC6809_BASE::LOAD16_REG(uint16_t reg) -{ - CLR_NZV; - SET_NZ16(reg); - return reg; -} - - -inline uint16_t MC6809_BASE::SUB16_REG(uint16_t reg, uint16_t data) -{ - uint32_t r, d; - d = reg; - r = d - data; - CLR_NZVC; - SET_FLAGS16(d, data, r); - return (uint16_t)r; -} - -inline uint16_t MC6809_BASE::ADD16_REG(uint16_t reg, uint16_t data) -{ - uint32_t r, d; - d = reg; - r = d + (uint32_t)data; - CLR_HNZVC; - SET_HNZVC16(d, data, r); - return (uint16_t)r; -} - -inline uint16_t MC6809_BASE::CMP16_REG(uint16_t reg, uint16_t data) -{ - uint32_t r, d; - d = reg; - r = d - data; - CLR_NZVC; - SET_FLAGS16(d, data, r); - return reg; -} - -inline void MC6809_BASE::STORE16_REG(pair32_t *p) -{ - CLR_NZV; - SET_NZ16(p->w.l); - WM16(EAD, p); -} - - -/* $00 NEG direct ?**** */ -OP_HANDLER(neg_di) { - uint8_t t; - DIRBYTE(t); - NEG_MEM(t); -} - -/* $01 Undefined Neg */ -/* $03 COM direct -**01 */ -OP_HANDLER(com_di) { - uint8_t t; - DIRBYTE(t); - COM_MEM(t); -} - -/* $02 NGC Direct (Undefined) */ -OP_HANDLER(ngc_di) { - if ((CC & CC_C) == 0) { - neg_di(); - } - else { - com_di(); - } -} - - -/* $04 LSR direct -0*-* */ -OP_HANDLER(lsr_di) { - uint8_t t; - DIRBYTE(t); - LSR_MEM(t); -} - -/* $05 ILLEGAL */ - -/* $06 ROR direct -**-* */ -OP_HANDLER(ror_di) { - uint8_t t; - DIRBYTE(t); - ROR_MEM(t); -} - -/* $07 ASR direct ?**-* */ -OP_HANDLER(asr_di) { - uint8_t t; - DIRBYTE(t); - ASR_MEM(t); -} - -/* $08 ASL direct ?**** */ -OP_HANDLER(asl_di) { - uint8_t t; - DIRBYTE(t); - ASL_MEM(t); -} - -/* $09 ROL direct -**** */ -OP_HANDLER(rol_di) { - uint8_t t; - DIRBYTE(t); - ROL_MEM(t); -} - -/* $0A DEC direct -***- */ -OP_HANDLER(dec_di) { - uint8_t t; - DIRBYTE(t); - DEC_MEM(t); -} - -/* $0B DCC direct */ -OP_HANDLER(dcc_di) { - uint8_t t; - DIRBYTE(t); - DCC_MEM(t); -} - - -/* $OC INC direct -***- */ -OP_HANDLER(inc_di) { - uint8_t t; - DIRBYTE(t); - INC_MEM(t); -} - -/* $OD TST direct -**0- */ -OP_HANDLER(tst_di) { - uint8_t t; - DIRBYTE(t); - t = RM(EAD); - TST_MEM(t); -} - -/* $0E JMP direct ----- */ -OP_HANDLER(jmp_di) { - DIRECT; - PC = EA; -} - -/* $0F CLR direct -0100 */ -OP_HANDLER(clr_di) { - uint8_t dummy; - DIRECT; - dummy = RM(EAD); // Dummy Read(Alpha etc...) - CLR_MEM(dummy); -} - -/* $10 FLAG */ - -/* $11 FLAG */ - -/* $12 NOP inherent ----- */ -OP_HANDLER(nop) { - ; -} - -/* $13 SYNC inherent ----- */ -OP_HANDLER(sync_09) // Rename 20101110 -{ - int_state |= MC6809_SYNC_IN; - write_signals(&outputs_bus_ba, 0xffffffff); - write_signals(&outputs_bus_bs, 0x00000000); -} - - - -/* $14 trap(HALT) */ -OP_HANDLER(trap) { - int_state |= MC6809_INSN_HALT; // HALTフラグ - // Debug: トラチEE要因 - this->out_debug_log(_T("TRAP(HALT) @%04x %02x %02x\n"), PC - 1, RM((PC - 1)), RM(PC)); -} - -/* $15 trap */ - -/* $16 LBRA relative ----- */ -OP_HANDLER(lbra) { - LBRANCH(true); -} - -/* $17 LBSR relative ----- */ -OP_HANDLER(lbsr) { - IMMWORD(EAP); - PUSHWORD(pPC); - PC += EAD; -} - -/* $18 ASLCC */ - -OP_HANDLER(aslcc_in) { - uint8_t cc_r = CC; - if ((cc_r & CC_Z) != 0x00) { //20100824 Fix - cc_r |= CC_C; - } - cc_r <<= 1; - cc_r &= 0x3e; - CC = cc_r; -} - -/* $19 DAA inherent (A) -**0* */ -OP_HANDLER(daa) { - uint8_t msn, lsn; - uint16_t t, cf = 0; - msn = A & 0xf0; - lsn = A & 0x0f; - if (lsn > 0x09 || CC & CC_H) - cf |= 0x06; - if (msn > 0x80 && lsn > 0x09) - cf |= 0x60; - if (msn > 0x90 || CC & CC_C) - cf |= 0x60; - t = cf + A; - CLR_NZV; /* keep carry from previous operation */ - SET_NZ8((uint8_t) t); - SET_C8(t); - A = (uint8_t)t; -} - - -/* $1A ORCC immediate ##### */ -OP_HANDLER(orcc) { - uint8_t t; - IMMBYTE(t); - CC |= t; -} - -/* $1B ILLEGAL */ - - -/* $1C ANDCC immediate ##### */ -OP_HANDLER(andcc) { - uint8_t t; - IMMBYTE(t); - CC &= t; -// check_irq_lines(); /* HJB 990116 */ -} - -/* $1D SEX inherent -**-- */ -OP_HANDLER(sex) { - uint16_t t; - t = SIGNED(B); - D = t; // Endian OK? - // CLR_NZV; Tim Lindner 20020905: verified that V flag is not affected - CLR_NZ; - SET_NZ16(t); -} - - /* $1E EXG inherent ----- */// 20100825 -OP_HANDLER(exg) { - pair32_t t1, t2; - uint8_t tb; - IMMBYTE(tb); - t1.d = 0; - t2.d = 0; - /* - * 20111011: 16bit vs 16Bitの演算にする(XM7/ cpu_x86.asmより - */ - { - switch ((tb >> 4) & 15) { - case 0: - t1.w.l = D; - break; - case 1: - t1.w.l = X; - break; - case 2: - t1.w.l = Y; - break; - case 3: - t1.w.l = U; - break; - case 4: - t1.w.l = S; - break; - case 5: - t1.w.l = PC; - break; - case 8: - t1.b.l = A; - t1.b.h = 0xff; - break; - case 9: - t1.b.l = B; - t1.b.h = 0xff; - break; - case 10: - t1.b.l = CC; - t1.b.h = 0xff; - break; - case 11: - t1.b.l = DP; - t1.b.h = 0xff; - break; - default: - t1.w.l = 0xffff; - break; - } - switch (tb & 15) { - case 0: - t2.w.l = D; - break; - case 1: - t2.w.l = X; - break; - case 2: - t2.w.l = Y; - break; - case 3: - t2.w.l = U; - break; - case 4: - t2.w.l = S; - break; - case 5: - t2.w.l = PC; - break; - case 8: - t2.b.l = A; - t2.b.h = 0xff; - break; - case 9: - t2.b.l = B; - t2.b.h = 0xff; - break; - case 10: - t2.b.l = CC; - t2.b.h = 0xff; - break; - case 11: - t2.b.l = DP; - t2.b.h = 0xff; - break; - default: - t2.w.l = 0xffff; - break; - } - } - switch ((tb >> 4) & 15) { - case 0: - D = t2.w.l; - break; - case 1: - X = t2.w.l; - break; - case 2: - Y = t2.w.l; - break; - case 3: - U = t2.w.l; - break; - case 4: - S = t2.w.l; - int_state |= MC6809_LDS; - break; - case 5: - PC = t2.w.l; - break; - case 8: - A = t2.b.l; - break; - case 9: - B = t2.b.l; - break; - case 10: - CC = t2.b.l; - break; - case 11: - DP = t2.b.l; - break; - } - switch (tb & 15) { - case 0: - D = t1.w.l; - break; - case 1: - X = t1.w.l; - break; - case 2: - Y = t1.w.l; - break; - case 3: - U = t1.w.l; - break; - case 4: - S = t1.w.l; - int_state |= MC6809_LDS; - break; - case 5: - PC = t1.w.l; - break; - case 8: - A = t1.b.l; - break; - case 9: - B = t1.b.l; - break; - case 10: - CC = t1.b.l; - break; - case 11: - DP = t1.b.l; - break; - } -} - -/* $1F TFR inherent ----- */ -OP_HANDLER(tfr) { - uint8_t tb; - pair32_t t; - IMMBYTE(tb); - t.d = 0; - /* - * 20111011: 16bit vs 16Bitの演算にする(XM7/ cpu_x86.asmより) - */ - { - switch ((tb >> 4) & 15) { - case 0: - t.w.l = D; - break; - case 1: - t.w.l = X; - break; - case 2: - t.w.l = Y; - break; - case 3: - t.w.l = U; - break; - case 4: - t.w.l = S; - break; - case 5: - t.w.l = PC; - break; - case 8: - t.b.l = A; - t.b.h = 0xff; - break; - case 9: - t.b.l = B; - t.b.h = 0xff; - break; - case 10: - t.b.l = CC; - t.b.h = 0xff; - break; - case 11: - t.b.l = DP; - t.b.h = 0xff; - break; - default: - t.w.l = 0xffff; - break; - } - } - switch (tb & 15) { - case 0: - D = t.w.l; - break; - case 1: - X = t.w.l; - break; - case 2: - Y = t.w.l; - break; - case 3: - U = t.w.l; - break; - case 4: - S = t.w.l; - int_state |= MC6809_LDS; - break; - case 5: - PC = t.w.l; - break; - case 8: - A = t.b.l; - break; - case 9: - B = t.b.l; - break; - case 10: - CC = t.b.l; - break; - case 11: - DP = t.b.l; - break; - } -} - -/* $20 BRA relative ----- */ -OP_HANDLER(bra) { - BRANCH(true); -} - -/* $21 BRN relative ----- */ -OP_HANDLER(brn) { - BRANCH(false); -} - -/* $1021 LBRN relative ----- */ -OP_HANDLER(lbrn) { - LBRANCH(false); -} - -/* $22 BHI relative ----- */ -OP_HANDLER(bhi) { - BRANCH(((CC & (CC_Z | CC_C)) == 0)); -} - -/* $1022 LBHI relative ----- */ -OP_HANDLER(lbhi) { - LBRANCH(((CC & (CC_Z | CC_C)) == 0)); -} - -/* $23 BLS relative ----- */ -OP_HANDLER(bls) { - BRANCH(((CC & (CC_Z | CC_C)) != 0)); -} - -/* $1023 LBLS relative ----- */ -OP_HANDLER(lbls) { - LBRANCH(((CC & (CC_Z | CC_C)) != 0)); - //LBRANCH((CC & (CC_Z | CC_C))); -} - -/* $24 BCC relative ----- */ -OP_HANDLER(bcc) { - BRANCH((CC & CC_C) == 0); -} - -/* $1024 LBCC relative ----- */ -OP_HANDLER(lbcc) { - LBRANCH((CC & CC_C) == 0); -} - -/* $25 BCS relative ----- */ -OP_HANDLER(bcs) { - BRANCH((CC & CC_C) != 0); -} - -/* $1025 LBCS relative ----- */ -OP_HANDLER(lbcs) { - LBRANCH((CC & CC_C) != 0); -} - -/* $26 BNE relative ----- */ -OP_HANDLER(bne) { - BRANCH((CC & CC_Z) == 0); -} - -/* $1026 LBNE relative ----- */ -OP_HANDLER(lbne) { - LBRANCH((CC & CC_Z) == 0); -} - -/* $27 BEQ relative ----- */ -OP_HANDLER(beq) { - BRANCH((CC & CC_Z) != 0); -} - -/* $1027 LBEQ relative ----- */ -OP_HANDLER(lbeq) { - LBRANCH((CC & CC_Z) != 0); -} - -/* $28 BVC relative ----- */ -OP_HANDLER(bvc) { - BRANCH((CC & CC_V) == 0); -} - -/* $1028 LBVC relative ----- */ -OP_HANDLER(lbvc) { - LBRANCH((CC & CC_V) == 0); -} - -/* $29 BVS relative ----- */ -OP_HANDLER(bvs) { - BRANCH((CC & CC_V) != 0); -} - -/* $1029 LBVS relative ----- */ -OP_HANDLER(lbvs) { - LBRANCH((CC & CC_V) != 0); -} - -/* $2A BPL relative ----- */ -OP_HANDLER(bpl) { - BRANCH((CC & CC_N) == 0); -} - -/* $102A LBPL relative ----- */ -OP_HANDLER(lbpl) { - LBRANCH((CC & CC_N) == 0); -} - -/* $2B BMI relative ----- */ -OP_HANDLER(bmi) { - BRANCH((CC & CC_N) != 0); -} - -/* $102B LBMI relative ----- */ -OP_HANDLER(lbmi) { - LBRANCH((CC & CC_N) != 0); -} - -/* $2C BGE relative ----- */ -OP_HANDLER(bge) { - BRANCH(!NXORV); -} - -/* $102C LBGE relative ----- */ -OP_HANDLER(lbge) { - LBRANCH(!NXORV); -} - -/* $2D BLT relative ----- */ -OP_HANDLER(blt) { - BRANCH(NXORV); -} - -/* $102D LBLT relative ----- */ -OP_HANDLER(lblt) { - LBRANCH(NXORV); -} - -/* $2E BGT relative ----- */ -OP_HANDLER(bgt) { - BRANCH(!(NXORV || (CC & CC_Z))); -} - -/* $102E LBGT relative ----- */ -OP_HANDLER(lbgt) { - LBRANCH(!(NXORV || (CC & CC_Z))); -} - -/* $2F BLE relative ----- */ -OP_HANDLER(ble) { - BRANCH((NXORV || (CC & CC_Z))); -} - -/* $102F LBLE relative ----- */ -OP_HANDLER(lble) { - LBRANCH((NXORV || (CC & CC_Z))); -} - -/* $30 LEAX indexed --*-- */ -OP_HANDLER(leax) { - fetch_effective_address(); - X = EA; - CLR_Z; - SET_Z16(X); -} - -/* $31 LEAY indexed --*-- */ -OP_HANDLER(leay) { - fetch_effective_address(); - Y = EA; - CLR_Z; - SET_Z16(Y); -} - -/* $32 LEAS indexed ----- */ -OP_HANDLER(leas) { - fetch_effective_address(); - S = EA; - int_state |= MC6809_LDS; -} - -/* $33 LEAU indexed ----- */ -OP_HANDLER(leau) { - fetch_effective_address(); - U = EA; -} - -/* $34 PSHS inherent ----- */ -OP_HANDLER(pshs) { - uint8_t t; - IMMBYTE(t); - //dmy = RM(S); // Add 20100825 - RM(S); // Add 20100825 - if (t & 0x80) { - PUSHWORD(pPC); - icount -= 2; - } - if (t & 0x40) { - PUSHWORD(pU); - icount -= 2; - } - if (t & 0x20) { - PUSHWORD(pY); - icount -= 2; - } - if (t & 0x10) { - PUSHWORD(pX); - icount -= 2; - } - if (t & 0x08) { - PUSHBYTE(DP); - icount -= 1; - } - if (t & 0x04) { - PUSHBYTE(B); - icount -= 1; - } - if (t & 0x02) { - PUSHBYTE(A); - icount -= 1; - } - if (t & 0x01) { - PUSHBYTE(CC); - icount -= 1; - } - } - -/* 35 PULS inherent ----- */ -OP_HANDLER(puls) { - uint8_t t; - IMMBYTE(t); - if (t & 0x01) { - PULLBYTE(CC); - icount -= 1; - } - if (t & 0x02) { - PULLBYTE(A); - icount -= 1; - } - if (t & 0x04) { - PULLBYTE(B); - icount -= 1; - } - if (t & 0x08) { - PULLBYTE(DP); - icount -= 1; - } - if (t & 0x10) { - PULLWORD(pX); - icount -= 2; - } - if (t & 0x20) { - PULLWORD(pY); - icount -= 2; - } - if (t & 0x40) { - PULLWORD(pU); - icount -= 2; - } - if (t & 0x80) { - PULLWORD(pPC); - icount -= 2; - } - //dmy = RM(S); // Add 20100825 - RM(S); // Add 20100825 - /* HJB 990225: moved check after all PULLs */ -// if( t&0x01 ) { check_irq_lines(); } - } - -/* $36 PSHU inherent ----- */ -OP_HANDLER(pshu) { - uint8_t t; - IMMBYTE(t); - //dmy = RM(U); // Add 20100825 - RM(U); // Add 20100825 - if (t & 0x80) { - PSHUWORD(pPC); - icount -= 2; - } - if (t & 0x40) { - PSHUWORD(pS); - icount -= 2; - } - if (t & 0x20) { - PSHUWORD(pY); - icount -= 2; - } - if (t & 0x10) { - PSHUWORD(pX); - icount -= 2; - } - if (t & 0x08) { - PSHUBYTE(DP); - icount -= 1; - } - if (t & 0x04) { - PSHUBYTE(B); - icount -= 1; - } - if (t & 0x02) { - PSHUBYTE(A); - icount -= 1; - } - if (t & 0x01) { - PSHUBYTE(CC); - icount -= 1; - } - } - -/* 37 PULU inherent ----- */ -OP_HANDLER(pulu) { - uint8_t t; - IMMBYTE(t); - if (t & 0x01) { - PULUBYTE(CC); - icount -= 1; - } - if (t & 0x02) { - PULUBYTE(A); - icount -= 1; - } - if (t & 0x04) { - PULUBYTE(B); - icount -= 1; - } - if (t & 0x08) { - PULUBYTE(DP); - icount -= 1; - } - if (t & 0x10) { - PULUWORD(pX); - icount -= 2; - } - if (t & 0x20) { - PULUWORD(pY); - icount -= 2; - } - if (t & 0x40) { - PULUWORD(pS); - icount -= 2; - } - if (t & 0x80) { - PULUWORD(pPC); - icount -= 2; - } - //dmy = RM(U); // Add 20100825 - RM(U); // Add 20100825 - /* HJB 990225: moved check after all PULLs */ - //if( t&0x01 ) { check_irq_lines(); } -} - -/* $38 ILLEGAL */ - -/* $39 RTS inherent ----- */ -OP_HANDLER(rts) { - //printf("RTS: Before PC=%04x", pPC.w.l); - PULLWORD(pPC); - //printf(" After PC=%04x\n", pPC.w.l); -} - -/* $3A ABX inherent ----- */ -OP_HANDLER(abx) { - pair32_t bt; - bt.d = 0; - bt.b.l = B; - X = X + bt.w.l; -} - -/* $3B RTI inherent ##### */ -OP_HANDLER(rti) { - PULLBYTE(CC); -// t = CC & CC_E; /* HJB 990225: entire state saved? */ - if ((CC & CC_E) != 0) { // NMIIRQ - icount -= 9; - PULLBYTE(A); - PULLBYTE(B); - PULLBYTE(DP); - PULLWORD(pX); - PULLWORD(pY); - PULLWORD(pU); - } - PULLWORD(pPC); -// check_irq_lines(); /* HJB 990116 */ -} - -/* $3C CWAI inherent ----1 */ -OP_HANDLER(cwai) { - uint8_t t; - IMMBYTE(t); - CC = CC & t; - CC |= CC_E; /* HJB 990225: save entire state */ - PUSHWORD(pPC); - PUSHWORD(pU); - PUSHWORD(pY); - PUSHWORD(pX); - PUSHBYTE(DP); - PUSHBYTE(B); - PUSHBYTE(A); - PUSHBYTE(CC); - - int_state = int_state | MC6809_CWAI_IN; - int_state &= ~MC6809_CWAI_OUT; // 0xfeff - return; -} - -/* $3D MUL inherent --*-@ */ -OP_HANDLER(mul) { - pair32_t t, r; - t.d = 0; - r.d = 0; - t.b.l = A; - r.b.l = B; - t.d = t.d * r.d; - CLR_ZC; - SET_Z16(t.w.l); - if (t.b.l & 0x80) SEC; - A = t.b.h; - B = t.b.l; -} - -/* $3E RST */ -OP_HANDLER(rst) { - this->reset(); -} - - -/* $3F SWI (SWI2 SWI3) absolute indirect ----- */ -OP_HANDLER(swi) { - CC |= CC_E; /* HJB 980225: save entire state */ - PUSHWORD(pPC); - PUSHWORD(pU); - PUSHWORD(pY); - PUSHWORD(pX); - PUSHBYTE(DP); - PUSHBYTE(B); - PUSHBYTE(A); - PUSHBYTE(CC); - CC |= CC_IF | CC_II; /* inhibit FIRQ and IRQ */ - pPC = RM16_PAIR(0xfffa); -} - -/* $103F SWI2 absolute indirect ----- */ -OP_HANDLER(swi2) { - CC |= CC_E; /* HJB 980225: save entire state */ - PUSHWORD(pPC); - PUSHWORD(pU); - PUSHWORD(pY); - PUSHWORD(pX); - PUSHBYTE(DP); - PUSHBYTE(B); - PUSHBYTE(A); - PUSHBYTE(CC); - pPC = RM16_PAIR(0xfff4); -} - -/* $113F SWI3 absolute indirect ----- */ -OP_HANDLER(swi3) { - CC |= CC_E; /* HJB 980225: save entire state */ - PUSHWORD(pPC); - PUSHWORD(pU); - PUSHWORD(pY); - PUSHWORD(pX); - PUSHBYTE(DP); - PUSHBYTE(B); - PUSHBYTE(A); - PUSHBYTE(CC); - pPC = RM16_PAIR(0xfff2); -} - -/* $40 NEGA inherent ?**** */ -OP_HANDLER(nega) { - A = NEG_REG(A); -} - -/* $41 NEGA */ - - -/* $43 COMA inherent -**01 */ -OP_HANDLER(coma) { - A = COM_REG(A); -} - -/* $42 NGCA */ -OP_HANDLER(ngca) { - if ((CC & CC_C) == 0) { - nega(); - } else { - coma(); - } -} - -/* $44 LSRA inherent -0*-* */ -OP_HANDLER(lsra) { - A = LSR_REG(A); -} - -/* $45 LSRA */ - -/* $46 RORA inherent -**-* */ -OP_HANDLER(rora) { - A = ROR_REG(A); -} - -/* $47 ASRA inherent ?**-* */ -OP_HANDLER(asra) { - A = ASR_REG(A); -} - -/* $48 ASLA inherent ?**** */ -OP_HANDLER(asla) { - A = ASL_REG(A); -} - -/* $49 ROLA inherent -**** */ -OP_HANDLER(rola) { - A = ROL_REG(A); -} - -/* $4A DECA inherent -***- */ -OP_HANDLER(deca) { - A = DEC_REG(A); -} - - -/* $4B DCCA */ -OP_HANDLER(dcca) { - A = DCC_REG(A); -} - -/* $4C INCA inherent -***- */ -OP_HANDLER(inca) { - A = INC_REG(A); -} - -/* $4D TSTA inherent -**0- */ -OP_HANDLER(tsta) { - A = TST_REG(A); -} - -/* $4E ILLEGAL */ -OP_HANDLER(clca) { - A = CLC_REG(A); -} - -/* $4F CLRA inherent -0100 */ -OP_HANDLER(clra) { - A = CLR_REG(A); -} - -/* $50 NEGB inherent ?**** */ -OP_HANDLER(negb) { - B = NEG_REG(B); -} - -/* $51 NEGB */ - -/* $52 NGCB */ - -/* $53 COMB inherent -**01 */ -OP_HANDLER(comb) { - B = COM_REG(B); -} - -/* $52 NGCB */ -OP_HANDLER(ngcb) { - if ((CC & CC_C) == 0) { - negb(); - } else { - comb(); - } -} - -/* $54 LSRB inherent -0*-* */ -OP_HANDLER(lsrb) { - B = LSR_REG(B); -} - -/* $55 LSRB */ - -/* $56 RORB inherent -**-* */ -OP_HANDLER(rorb) { - B = ROR_REG(B); -} - -/* $57 ASRB inherent ?**-* */ -OP_HANDLER(asrb) { - B = ASR_REG(B); -} - -/* $58 ASLB inherent ?**** */ -OP_HANDLER(aslb) { - B = ASL_REG(B); -} - -/* $59 ROLB inherent -**** */ -OP_HANDLER(rolb) { - B = ROL_REG(B); -} - -/* $5A DECB inherent -***- */ -OP_HANDLER(decb) { - B = DEC_REG(B); -} - -/* $5B DCCB */ -OP_HANDLER(dccb) { - B = DCC_REG(B); -} - -/* $5C INCB inherent -***- */ -OP_HANDLER(incb) { - B = INC_REG(B); -} - -/* $5D TSTB inherent -**0- */ -OP_HANDLER(tstb) { - B = TST_REG(B); -} - -/* $5E ILLEGAL */ -OP_HANDLER(clcb) { - B = CLC_REG(B); -} - -/* $5F CLRB inherent -0100 */ -OP_HANDLER(clrb) { - B = CLR_REG(B); -} - -/* $60 NEG indexed ?**** */ -OP_HANDLER(neg_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - NEG_MEM(t); -} - -/* $61 ILLEGAL */ - - -/* $63 COM indexed -**01 */ -OP_HANDLER(com_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - COM_MEM(t); -} - -/* $62 ILLEGAL */ -OP_HANDLER(ngc_ix) { - if ((CC & CC_C) == 0) { - neg_ix(); - } else { - com_ix(); - } -} - -/* $64 LSR indexed -0*-* */ -OP_HANDLER(lsr_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - LSR_MEM(t); -} - -/* $65 ILLEGAL */ - -/* $66 ROR indexed -**-* */ -OP_HANDLER(ror_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - ROR_MEM(t); -} - -/* $67 ASR indexed ?**-* */ -OP_HANDLER(asr_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - ASR_MEM(t); -} - -/* $68 ASL indexed ?**** */ -OP_HANDLER(asl_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - ASL_MEM(t); -} - -/* $69 ROL indexed -**** */ -OP_HANDLER(rol_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - ROL_MEM(t); -} - -/* $6A DEC indexed -***- */ -OP_HANDLER(dec_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - DEC_MEM(t); -} - -/* $6B DCC index */ -OP_HANDLER(dcc_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - DCC_MEM(t); -} - -/* $6C INC indexed -***- */ -OP_HANDLER(inc_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - INC_MEM(t); -} - -/* $6D TST indexed -**0- */ -OP_HANDLER(tst_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - TST_MEM(t); -} - -/* $6E JMP indexed ----- */ -OP_HANDLER(jmp_ix) { - fetch_effective_address(); - PCD = EAD; -} - -/* $6F CLR indexed -0100 */ -OP_HANDLER(clr_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - //dummy = RM(EAD); // Dummy Read(Alpha etc...) - RM(EAD); // Dummy Read(Alpha etc...) - CLR_MEM(t); -} - -/* $70 NEG extended ?**** */ -OP_HANDLER(neg_ex) { - uint8_t t; - EXTBYTE(t); - NEG_MEM(t); -} - - -/* $73 COM extended -**01 */ -OP_HANDLER(com_ex) { - uint8_t t; - EXTBYTE(t); - COM_MEM(t); -} - -/* $72 NGC extended */ -OP_HANDLER(ngc_ex) { - if ((CC & CC_C) == 0) { - neg_ex(); - } else { - com_ex(); - } -} - -/* $74 LSR extended -0*-* */ -OP_HANDLER(lsr_ex) { - uint8_t t; - EXTBYTE(t); - LSR_MEM(t); -} - -/* $75 ILLEGAL */ - -/* $76 ROR extended -**-* */ -OP_HANDLER(ror_ex) { - uint8_t t; - EXTBYTE(t); - ROR_MEM(t); -} - -/* $77 ASR extended ?**-* */ -OP_HANDLER(asr_ex) { - uint8_t t; - EXTBYTE(t); - ASR_MEM(t); -} - -/* $78 ASL extended ?**** */ -OP_HANDLER(asl_ex) { - uint8_t t; - EXTBYTE(t); - ASL_MEM(t); -} - -/* $79 ROL extended -**** */ -OP_HANDLER(rol_ex) { - uint8_t t; - EXTBYTE(t); - ROL_MEM(t); -} - -/* $7A DEC extended -***- */ -OP_HANDLER(dec_ex) { - uint8_t t; - EXTBYTE(t); - DEC_MEM(t); -} - -/* $7B ILLEGAL */ -/* $6B DCC index */ -OP_HANDLER(dcc_ex) { - uint8_t t; - EXTBYTE(t); - DCC_MEM(t); -} - -/* $7C INC extended -***- */ -OP_HANDLER(inc_ex) { - uint8_t t; - EXTBYTE(t); - INC_MEM(t); -} - -/* $7D TST extended -**0- */ -OP_HANDLER(tst_ex) { - uint8_t t; - EXTBYTE(t); - TST_MEM(t); -} - -/* $7E JMP extended ----- */ -OP_HANDLER(jmp_ex) { - EXTENDED; - PCD = EAD; -} - -/* $7F CLR extended -0100 */ -OP_HANDLER(clr_ex) { - uint8_t dummy; - EXTENDED; - dummy = RM(EAD); - CLR_MEM(dummy); -} - -/* $80 SUBA immediate ?**** */ -OP_HANDLER(suba_im) { - uint8_t t; - IMMBYTE(t); - A = SUB8_REG(A, t); -} - -/* $81 CMPA immediate ?**** */ -OP_HANDLER(cmpa_im) { - uint8_t t; - IMMBYTE(t); - A = CMP8_REG(A, t); -} - -/* $82 SBCA immediate ?**** */ -OP_HANDLER(sbca_im) { - uint8_t t; - IMMBYTE(t); - A = SBC8_REG(A, t); -} - -/* $83 SUBD (CMPD CMPU) immediate -**** */ -OP_HANDLER(subd_im) { - pair32_t b; - IMMWORD(b); - D = SUB16_REG(D, b.w.l); -} - -/* $1083 CMPD immediate -**** */ -OP_HANDLER(cmpd_im) { - pair32_t b; - IMMWORD(b); - D = CMP16_REG(D, b.w.l); -} - -/* $1183 CMPU immediate -**** */ -OP_HANDLER(cmpu_im) { - pair32_t b; - IMMWORD(b); - U = CMP16_REG(U, b.w.l); -} - -/* $84 ANDA immediate -**0- */ -OP_HANDLER(anda_im) { - uint8_t t; - IMMBYTE(t); - A = AND8_REG(A, t); -} - -/* $85 BITA immediate -**0- */ -OP_HANDLER(bita_im) { - uint8_t t; - IMMBYTE(t); - A = BIT8_REG(A, t); -} - -/* $86 LDA immediate -**0- */ -OP_HANDLER(lda_im) { - IMMBYTE(A); - A = LOAD8_REG(A); -} - -/* is this a legal instruction? */ -/* $87 STA immediate -**0- */ -OP_HANDLER(sta_im) { - CLR_NZV; - SET_NZ8(A); - IMM8; - WM(EAD, A); - } - -/* - * $87 , $C7: FLAG8 - */ -OP_HANDLER(flag8_im) { - // 20111117 - //uint8_t t; - // IMMBYTE(t); - ROP_ARG(PCD); - PC++; - CLR_NZV; - CC |= CC_N; - } - - -/* $88 EORA immediate -**0- */ -OP_HANDLER(eora_im) { - uint8_t t; - IMMBYTE(t); - A = EOR8_REG(A, t); -} - -/* $89 ADCA immediate ***** */ -OP_HANDLER(adca_im) { - uint8_t t; - IMMBYTE(t); - A = ADC8_REG(A, t); -} - -/* $8A ORA immediate -**0- */ -OP_HANDLER(ora_im) { - uint8_t t; - IMMBYTE(t); - A = OR8_REG(A, t); -} - -/* $8B ADDA immediate ***** */ -OP_HANDLER(adda_im) { - uint8_t t; - IMMBYTE(t); - A = ADD8_REG(A, t); -} - -/* $8C CMPX (CMPY CMPS) immediate -**** */ -OP_HANDLER(cmpx_im) { - pair32_t b; - IMMWORD(b); - X = CMP16_REG(X, b.w.l); -} - -/* $108C CMPY immediate -**** */ -OP_HANDLER(cmpy_im) { - pair32_t b; - IMMWORD(b); - Y = CMP16_REG(Y, b.w.l); -} - -/* $118C CMPS immediate -**** */ -OP_HANDLER(cmps_im) { - pair32_t b; - IMMWORD(b); - S = CMP16_REG(S, b.w.l); -} - -/* $8D BSR ----- */ -OP_HANDLER(bsr) { - uint8_t t; - IMMBYTE(t); - PUSHWORD(pPC); - PC += SIGNED(t); - } - -/* $8E LDX (LDY) immediate -**0- */ -OP_HANDLER(ldx_im) { - IMMWORD(pX); - X = LOAD16_REG(X); -} - -/* $108E LDY immediate -**0- */ -OP_HANDLER(ldy_im) { - IMMWORD(pY); - Y = LOAD16_REG(Y); -} - -/* is this a legal instruction? */ -/* $8F STX (STY) immediate -**0- */ -OP_HANDLER(stx_im) { - CLR_NZV; - SET_NZ16(X); - IMM16; - WM16(EAD, &pX); - } - -/* - * $8F , $CF: FLAG16 - */ -OP_HANDLER(flag16_im) { - pair32_t t; - IMMWORD(t); - CLR_NZV; - CC |= CC_N; -} - - -/* is this a legal instruction? */ -/* $108F STY immediate -**0- */ -OP_HANDLER(sty_im) { - CLR_NZV; - SET_NZ16(Y); - IMM16; - WM16(EAD, &pY); - } - -/* $90 SUBA direct ?**** */ -OP_HANDLER(suba_di) { - uint8_t t; - DIRBYTE(t); - A = SUB8_REG(A, t); -} - -/* $91 CMPA direct ?**** */ -OP_HANDLER(cmpa_di) { - uint8_t t; - DIRBYTE(t); - A = CMP8_REG(A, t); -} - -/* $92 SBCA direct ?**** */ -OP_HANDLER(sbca_di) { - uint8_t t; - DIRBYTE(t); - A = SBC8_REG(A, t); -} - -/* $93 SUBD (CMPD CMPU) direct -**** */ -OP_HANDLER(subd_di) { - pair32_t b; - DIRWORD(b); - D = SUB16_REG(D, b.w.l); -} - -/* $1093 CMPD direct -**** */ -OP_HANDLER(cmpd_di) { - pair32_t b; - DIRWORD(b); - D = CMP16_REG(D, b.w.l); -} - -/* $1193 CMPU direct -**** */ -OP_HANDLER(cmpu_di) { - pair32_t b; - DIRWORD(b); - U = CMP16_REG(U, b.w.l); -} - -/* $94 ANDA direct -**0- */ -OP_HANDLER(anda_di) { - uint8_t t; - DIRBYTE(t); - A = AND8_REG(A, t); -} - -/* $95 BITA direct -**0- */ -OP_HANDLER(bita_di) { - uint8_t t; - DIRBYTE(t); - A = BIT8_REG(A, t); -} - -/* $96 LDA direct -**0- */ -OP_HANDLER(lda_di) { - DIRBYTE(A); - A = LOAD8_REG(A); -} - -/* $97 STA direct -**0- */ -OP_HANDLER(sta_di) { - DIRECT; - STORE8_REG(A); -} - -/* $98 EORA direct -**0- */ -OP_HANDLER(eora_di) { - uint8_t t; - DIRBYTE(t); - A = EOR8_REG(A, t); -} - -/* $99 ADCA direct ***** */ -OP_HANDLER(adca_di) { - uint8_t t; - DIRBYTE(t); - A = ADC8_REG(A, t); -} - -/* $9A ORA direct -**0- */ -OP_HANDLER(ora_di) { - uint8_t t; - DIRBYTE(t); - A = OR8_REG(A, t); -} - -/* $9B ADDA direct ***** */ -OP_HANDLER(adda_di) { - uint8_t t; - DIRBYTE(t); - A = ADD8_REG(A, t); -} - -/* $9C CMPX (CMPY CMPS) direct -**** */ -OP_HANDLER(cmpx_di) { - pair32_t b; - DIRWORD(b); - X = CMP16_REG(X, b.w.l); -} - -/* $109C CMPY direct -**** */ -OP_HANDLER(cmpy_di) { - pair32_t b; - DIRWORD(b); - Y = CMP16_REG(Y, b.w.l); -} - -/* $119C CMPS direct -**** */ -OP_HANDLER(cmps_di) { - pair32_t b; - DIRWORD(b); - S = CMP16_REG(S, b.w.l); -} - -/* $9D JSR direct ----- */ -OP_HANDLER(jsr_di) { - DIRECT; - PUSHWORD(pPC); - PCD = EAD; - } - -/* $9E LDX (LDY) direct -**0- */ -OP_HANDLER(ldx_di) { - DIRWORD(pX); - X = LOAD16_REG(X); -} - -/* $109E LDY direct -**0- */ -OP_HANDLER(ldy_di) { - DIRWORD(pY); - Y = LOAD16_REG(Y); -} - -/* $9F STX (STY) direct -**0- */ -OP_HANDLER(stx_di) { - DIRECT; - STORE16_REG(&pX); -} - -/* $109F STY direct -**0- */ -OP_HANDLER(sty_di) { - DIRECT; - STORE16_REG(&pY); -} - -/* $a0 SUBA indexed ?**** */ -OP_HANDLER(suba_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = SUB8_REG(A, t); -} - -/* $a1 CMPA indexed ?**** */ -OP_HANDLER(cmpa_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = CMP8_REG(A, t); -} - -/* $a2 SBCA indexed ?**** */ -OP_HANDLER(sbca_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = SBC8_REG(A, t); -} - -/* $a3 SUBD (CMPD CMPU) indexed -**** */ -OP_HANDLER(subd_ix) { - pair32_t b; - b = GET_INDEXED_DATA16(); - D = SUB16_REG(D, b.w.l); -} - -/* $10a3 CMPD indexed -**** */ -OP_HANDLER(cmpd_ix) { - pair32_t b; - b = GET_INDEXED_DATA16(); - D = CMP16_REG(D, b.w.l); -} - -/* $11a3 CMPU indexed -**** */ -OP_HANDLER(cmpu_ix) { - pair32_t b; - b = GET_INDEXED_DATA16(); - U = CMP16_REG(U, b.w.l); -} - -/* $a4 ANDA indexed -**0- */ -OP_HANDLER(anda_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = AND8_REG(A, t); -} - -/* $a5 BITA indexed -**0- */ -OP_HANDLER(bita_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = BIT8_REG(A, t); -} - -/* $a6 LDA indexed -**0- */ -OP_HANDLER(lda_ix) { - A = GET_INDEXED_DATA(); - A = LOAD8_REG(A); -} - -/* $a7 STA indexed -**0- */ -OP_HANDLER(sta_ix) { - fetch_effective_address(); - STORE8_REG(A); -} - -/* $a8 EORA indexed -**0- */ -OP_HANDLER(eora_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = EOR8_REG(A, t); -} - -/* $a9 ADCA indexed ***** */ -OP_HANDLER(adca_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = ADC8_REG(A, t); -} - -/* $aA ORA indexed -**0- */ -OP_HANDLER(ora_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = OR8_REG(A, t); -} - -/* $aB ADDA indexed ***** */ -OP_HANDLER(adda_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - A = ADD8_REG(A, t); -} - -/* $aC CMPX (CMPY CMPS) indexed -**** */ -OP_HANDLER(cmpx_ix) { - pair32_t b; - b = GET_INDEXED_DATA16(); - X = CMP16_REG(X, b.w.l); -} - -/* $10aC CMPY indexed -**** */ -OP_HANDLER(cmpy_ix) { - pair32_t b; - b = GET_INDEXED_DATA16(); - Y = CMP16_REG(Y, b.w.l); -} - -/* $11aC CMPS indexed -**** */ -OP_HANDLER(cmps_ix) { - pair32_t b; - b = GET_INDEXED_DATA16(); - S = CMP16_REG(S, b.w.l); -} - -/* $aD JSR indexed ----- */ -OP_HANDLER(jsr_ix) { - fetch_effective_address(); - PUSHWORD(pPC); - PCD = EAD; -} - -/* $aE LDX (LDY) indexed -**0- */ -OP_HANDLER(ldx_ix) { - pair32_t t; - t = GET_INDEXED_DATA16(); - X = t.w.l; - X = LOAD16_REG(X); -} - -/* $10aE LDY indexed -**0- */ -OP_HANDLER(ldy_ix) { - pair32_t t; - t = GET_INDEXED_DATA16(); - Y = t.w.l; - Y = LOAD16_REG(Y); -} - -/* $aF STX (STY) indexed -**0- */ -OP_HANDLER(stx_ix) { - fetch_effective_address(); - STORE16_REG(&pX); -} - -/* $10aF STY indexed -**0- */ -OP_HANDLER(sty_ix) { - fetch_effective_address(); - STORE16_REG(&pY); -} - -/* $b0 SUBA extended ?**** */ -OP_HANDLER(suba_ex) { - uint8_t t; - EXTBYTE(t); - A = SUB8_REG(A, t); -} - -/* $b1 CMPA extended ?**** */ -OP_HANDLER(cmpa_ex) { - uint8_t t; - EXTBYTE(t); - A = CMP8_REG(A, t); -} - -/* $b2 SBCA extended ?**** */ -OP_HANDLER(sbca_ex) { - uint8_t t; - EXTBYTE(t); - A = SBC8_REG(A, t); -} - -/* $b3 SUBD (CMPD CMPU) extended -**** */ -OP_HANDLER(subd_ex) { - pair32_t b; - EXTWORD(b); - D = SUB16_REG(D, b.w.l); -} - -/* $10b3 CMPD extended -**** */ -OP_HANDLER(cmpd_ex) { - pair32_t b; - EXTWORD(b); - D = CMP16_REG(D, b.w.l); -} - -/* $11b3 CMPU extended -**** */ -OP_HANDLER(cmpu_ex) { - pair32_t b; - EXTWORD(b); - U = CMP16_REG(U, b.w.l); -} - -/* $b4 ANDA extended -**0- */ -OP_HANDLER(anda_ex) { - uint8_t t; - EXTBYTE(t); - A = AND8_REG(A, t); -} - -/* $b5 BITA extended -**0- */ -OP_HANDLER(bita_ex) { - uint8_t t; - EXTBYTE(t); - A = BIT8_REG(A, t); -} - -/* $b6 LDA extended -**0- */ -OP_HANDLER(lda_ex) { - EXTBYTE(A); - A = LOAD8_REG(A); -} - -/* $b7 STA extended -**0- */ -OP_HANDLER(sta_ex) { - EXTENDED; - STORE8_REG(A); -} - -/* $b8 EORA extended -**0- */ -OP_HANDLER(eora_ex) { - uint8_t t; - EXTBYTE(t); - A = EOR8_REG(A, t); -} - -/* $b9 ADCA extended ***** */ -OP_HANDLER(adca_ex) { - uint8_t t; - EXTBYTE(t); - A = ADC8_REG(A, t); -} - -/* $bA ORA extended -**0- */ -OP_HANDLER(ora_ex) { - uint8_t t; - EXTBYTE(t); - A = OR8_REG(A, t); -} - -/* $bB ADDA extended ***** */ -OP_HANDLER(adda_ex) { - uint8_t t; - EXTBYTE(t); - A = ADD8_REG(A, t); -} - -/* $bC CMPX (CMPY CMPS) extended -**** */ -OP_HANDLER(cmpx_ex) { - pair32_t b; - EXTWORD(b); - X = CMP16_REG(X, b.w.l); -} - -/* $10bC CMPY extended -**** */ -OP_HANDLER(cmpy_ex) { - pair32_t b; - EXTWORD(b); - Y = CMP16_REG(Y, b.w.l); -} - -/* $11bC CMPS extended -**** */ -OP_HANDLER(cmps_ex) { - pair32_t b; - EXTWORD(b); - S = CMP16_REG(S, b.w.l); -} - -/* $bD JSR extended ----- */ -OP_HANDLER(jsr_ex) { - EXTENDED; - PUSHWORD(pPC); - PCD = EAD; -} - -/* $bE LDX (LDY) extended -**0- */ -OP_HANDLER(ldx_ex) { - EXTWORD(pX); - X = LOAD16_REG(X); -} - -/* $10bE LDY extended -**0- */ -OP_HANDLER(ldy_ex) { - EXTWORD(pY); - Y = LOAD16_REG(Y); -} - -/* $bF STX (STY) extended -**0- */ -OP_HANDLER(stx_ex) { - EXTENDED; - STORE16_REG(&pX); -} - -/* $10bF STY extended -**0- */ -OP_HANDLER(sty_ex) { - EXTENDED; - STORE16_REG(&pY); -} - -/* $c0 SUBB immediate ?**** */ -OP_HANDLER(subb_im) { - uint8_t t; - IMMBYTE(t); - B = SUB8_REG(B, t); -} - -/* $c1 CMPB immediate ?**** */ -OP_HANDLER(cmpb_im) { - uint8_t t; - IMMBYTE(t); - B = CMP8_REG(B, t); -} - -/* $c2 SBCB immediate ?**** */ -OP_HANDLER(sbcb_im) { - uint8_t t; - IMMBYTE(t); - B = SBC8_REG(B, t); -} - -/* $c3 ADDD immediate -**** */ -OP_HANDLER(addd_im) { - pair32_t b; - IMMWORD(b); - D = ADD16_REG(D, b.w.l); -} - -/* $c4 ANDB immediate -**0- */ -OP_HANDLER(andb_im) { - uint8_t t; - IMMBYTE(t); - B = AND8_REG(B, t); -} - -/* $c5 BITB immediate -**0- */ -OP_HANDLER(bitb_im) { - uint8_t t; - IMMBYTE(t); - B = BIT8_REG(B, t); -} - -/* $c6 LDB immediate -**0- */ -OP_HANDLER(ldb_im) { - IMMBYTE(B); - B = LOAD8_REG(B); -} - -/* is this a legal instruction? */ -/* $c7 STB immediate -**0- */ -OP_HANDLER(stb_im) { - CLR_NZV; - SET_NZ8(B); - IMM8; - WM(EAD, B); -} - -/* $c8 EORB immediate -**0- */ -OP_HANDLER(eorb_im) { - uint8_t t; - IMMBYTE(t); - B = EOR8_REG(B, t); -} - -/* $c9 ADCB immediate ***** */ -OP_HANDLER(adcb_im) { - uint8_t t; - IMMBYTE(t); - B = ADC8_REG(B, t); -} - -/* $cA ORB immediate -**0- */ -OP_HANDLER(orb_im) { - uint8_t t; - IMMBYTE(t); - B = OR8_REG(B, t); -} - -/* $cB ADDB immediate ***** */ -OP_HANDLER(addb_im) { - uint8_t t; - IMMBYTE(t); - B = ADD8_REG(B, t); -} - -/* $cC LDD immediate -**0- */ -OP_HANDLER(ldd_im) { - IMMWORD(pD); - D = LOAD16_REG(D); -} - -/* is this a legal instruction? */ -/* $cD STD immediate -**0- */ -OP_HANDLER(std_im) { - CLR_NZV; - SET_NZ16(D); - IMM16; - WM(EAD, D); -} - -/* $cE LDU (LDS) immediate -**0- */ -OP_HANDLER(ldu_im) { - IMMWORD(pU); - U = LOAD16_REG(U); -} - -/* $10cE LDS immediate -**0- */ -OP_HANDLER(lds_im) { - IMMWORD(pS); - S = LOAD16_REG(S); - int_state |= MC6809_LDS; -} - -/* is this a legal instruction? */ -/* $cF STU (STS) immediate -**0- */ -OP_HANDLER(stu_im) { - CLR_NZV; - SET_NZ16(U); - IMM16; - WM16(EAD, &pU); - } - -/* is this a legal instruction? */ -/* $10cF STS immediate -**0- */ -OP_HANDLER(sts_im) { - CLR_NZV; - SET_NZ16(S); - IMM16; - WM16(EAD, &pS); - } - -/* $d0 SUBB direct ?**** */ -OP_HANDLER(subb_di) { - uint8_t t; - DIRBYTE(t); - B = SUB8_REG(B, t); -} -/* $d1 CMPB direct ?**** */ -OP_HANDLER(cmpb_di) { - uint8_t t; - DIRBYTE(t); - B = CMP8_REG(B, t); -} - -/* $d2 SBCB direct ?**** */ -OP_HANDLER(sbcb_di) { - uint8_t t; - DIRBYTE(t); - B = SBC8_REG(B, t); -} - -/* $d3 ADDD direct -**** */ -OP_HANDLER(addd_di) { - pair32_t b; - DIRWORD(b); - D = ADD16_REG(D, b.w.l); -} - -/* $d4 ANDB direct -**0- */ -OP_HANDLER(andb_di) { - uint8_t t; - DIRBYTE(t); - B = AND8_REG(B, t); -} - -/* $d5 BITB direct -**0- */ -OP_HANDLER(bitb_di) { - uint8_t t; - DIRBYTE(t); - B = BIT8_REG(B, t); -} - -/* $d6 LDB direct -**0- */ -OP_HANDLER(ldb_di) { - DIRBYTE(B); - B = LOAD8_REG(B); -} - -/* $d7 STB direct -**0- */ -OP_HANDLER(stb_di) { - DIRECT; - STORE8_REG(B); -} - -/* $d8 EORB direct -**0- */ -OP_HANDLER(eorb_di) { - uint8_t t; - DIRBYTE(t); - B = EOR8_REG(B, t); -} - -/* $d9 ADCB direct ***** */ -OP_HANDLER(adcb_di) { - uint8_t t; - DIRBYTE(t); - B = ADC8_REG(B, t); -} - -/* $dA ORB direct -**0- */ -OP_HANDLER(orb_di) { - uint8_t t; - DIRBYTE(t); - B = OR8_REG(B, t); -} - -/* $dB ADDB direct ***** */ -OP_HANDLER(addb_di) { - uint8_t t; - DIRBYTE(t); - B = ADD8_REG(B, t); -} - -/* $dC LDD direct -**0- */ -OP_HANDLER(ldd_di) { - DIRWORD(pD); - D = LOAD16_REG(D); -} - -/* $dD STD direct -**0- */ -OP_HANDLER(std_di) { - DIRECT; - STORE16_REG(&pD); -} - -/* $dE LDU (LDS) direct -**0- */ -OP_HANDLER(ldu_di) { - DIRWORD(pU); - U = LOAD16_REG(U); -} - -/* $10dE LDS direct -**0- */ -OP_HANDLER(lds_di) { - DIRWORD(pS); - S = LOAD16_REG(S); - int_state |= MC6809_LDS; -} - -/* $dF STU (STS) direct -**0- */ -OP_HANDLER(stu_di) { - DIRECT; - STORE16_REG(&pU); -} - -/* $10dF STS direct -**0- */ -OP_HANDLER(sts_di) { - DIRECT; - STORE16_REG(&pS); -} - -/* $e0 SUBB indexed ?**** */ -OP_HANDLER(subb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = SUB8_REG(B, t); -} - -/* $e1 CMPB indexed ?**** */ -OP_HANDLER(cmpb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = CMP8_REG(B, t); -} - -/* $e2 SBCB indexed ?**** */ -OP_HANDLER(sbcb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = SBC8_REG(B, t); -} - -/* $e3 ADDD indexed -**** */ -OP_HANDLER(addd_ix) { - pair32_t b; - b = GET_INDEXED_DATA16(); - D = ADD16_REG(D, b.w.l); -} - -/* $e4 ANDB indexed -**0- */ -OP_HANDLER(andb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = AND8_REG(B, t); -} - -/* $e5 BITB indexed -**0- */ -OP_HANDLER(bitb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = BIT8_REG(B, t); -} - -/* $e6 LDB indexed -**0- */ -OP_HANDLER(ldb_ix) { - B = GET_INDEXED_DATA(); - B = LOAD8_REG(B); -} - -/* $e7 STB indexed -**0- */ -OP_HANDLER(stb_ix) { - fetch_effective_address(); - STORE8_REG(B); -} - -/* $e8 EORB indexed -**0- */ -OP_HANDLER(eorb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = EOR8_REG(B, t); -} - -/* $e9 ADCB indexed ***** */ -OP_HANDLER(adcb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = ADC8_REG(B, t); -} - -/* $eA ORB indexed -**0- */ -OP_HANDLER(orb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = OR8_REG(B, t); -} - -/* $eB ADDB indexed ***** */ -OP_HANDLER(addb_ix) { - uint8_t t; - t = GET_INDEXED_DATA(); - B = ADD8_REG(B, t); -} - -/* $eC LDD indexed -**0- */ -OP_HANDLER(ldd_ix) { - pair32_t t; - t = GET_INDEXED_DATA16(); - D = t.w.l; - D = LOAD16_REG(D); -} - -/* $eD STD indexed -**0- */ -OP_HANDLER(std_ix) { - fetch_effective_address(); - STORE16_REG(&pD); -} - -/* $eE LDU (LDS) indexed -**0- */ -OP_HANDLER(ldu_ix) { - pair32_t t; - t = GET_INDEXED_DATA16(); - U = t.w.l; - U = LOAD16_REG(U); -} - -/* $10eE LDS indexed -**0- */ -OP_HANDLER(lds_ix) { - pair32_t t; - t = GET_INDEXED_DATA16(); - S = t.w.l; - S = LOAD16_REG(S); - int_state |= MC6809_LDS; -} - -/* $eF STU (STS) indexed -**0- */ -OP_HANDLER(stu_ix) { - fetch_effective_address(); - STORE16_REG(&pU); -} - -/* $10eF STS indexed -**0- */ -OP_HANDLER(sts_ix) { - fetch_effective_address(); - STORE16_REG(&pS); -} - -/* $f0 SUBB extended ?**** */ -OP_HANDLER(subb_ex) { - uint8_t t; - EXTBYTE(t); - B = SUB8_REG(B, t); -} - -/* $f1 CMPB extended ?**** */ -OP_HANDLER(cmpb_ex) { - uint8_t t; - EXTBYTE(t); - B = CMP8_REG(B, t); -} - -/* $f2 SBCB extended ?**** */ -OP_HANDLER(sbcb_ex) { - uint8_t t; - EXTBYTE(t); - B = SBC8_REG(B, t); -} - -/* $f3 ADDD extended -**** */ -OP_HANDLER(addd_ex) { - pair32_t b; - EXTWORD(b); - D = ADD16_REG(D, b.w.l); -} - -/* $f4 ANDB extended -**0- */ -OP_HANDLER(andb_ex) { - uint8_t t; - EXTBYTE(t); - B = AND8_REG(B, t); -} - -/* $f5 BITB extended -**0- */ -OP_HANDLER(bitb_ex) { - uint8_t t; - EXTBYTE(t); - B = BIT8_REG(B, t); -} - -/* $f6 LDB extended -**0- */ -OP_HANDLER(ldb_ex) { - EXTBYTE(B); - B = LOAD8_REG(B); -} - -/* $f7 STB extended -**0- */ -OP_HANDLER(stb_ex) { - EXTENDED; - STORE8_REG(B); -} - -/* $f8 EORB extended -**0- */ -OP_HANDLER(eorb_ex) { - uint8_t t; - EXTBYTE(t); - B = EOR8_REG(B, t); -} - -/* $f9 ADCB extended ***** */ -OP_HANDLER(adcb_ex) { - uint8_t t; - EXTBYTE(t); - B = ADC8_REG(B, t); -} - -/* $fA ORB extended -**0- */ -OP_HANDLER(orb_ex) { - uint8_t t; - EXTBYTE(t); - B = OR8_REG(B, t); -} - -/* $fB ADDB extended ***** */ -OP_HANDLER(addb_ex) { - uint8_t t; - EXTBYTE(t); - B = ADD8_REG(B, t); -} - -/* $fC LDD extended -**0- */ -OP_HANDLER(ldd_ex) { - EXTWORD(pD); - D = LOAD16_REG(D); -} - -/* $fD STD extended -**0- */ -OP_HANDLER(std_ex) { - EXTENDED; - STORE16_REG(&pD); -} - -/* $fE LDU (LDS) extended -**0- */ -OP_HANDLER(ldu_ex) { - EXTWORD(pU); - U = LOAD16_REG(U); -} - -/* $10fE LDS extended -**0- */ -OP_HANDLER(lds_ex) { - EXTWORD(pS); - S = LOAD16_REG(S); - int_state |= MC6809_LDS; -} - -/* $fF STU (STS) extended -**0- */ -OP_HANDLER(stu_ex) { - EXTENDED; - STORE16_REG(&pU); -} - -/* $10fF STS extended -**0- */ -OP_HANDLER(sts_ex) { - EXTENDED; - STORE16_REG(&pS); -} - - -/* $10xx opcodes */ -OP_HANDLER(pref10) { - uint8_t ireg2 = ROP_ARG(PCD); - PC++; - switch (ireg2) { - case 0x20: - lbra(); - icount -= 5; - break; // 20111217 - case 0x21: - lbrn(); - icount -= 5; - break; - case 0x22: - lbhi(); - icount -= 5; - break; - case 0x23: - lbls(); - icount -= 5; - break; - case 0x24: - lbcc(); - icount -= 5; - break; - case 0x25: - lbcs(); - icount -= 5; - break; - case 0x26: - lbne(); - icount -= 5; - break; - case 0x27: - lbeq(); - icount -= 5; - break; - case 0x28: - lbvc(); - icount -= 5; - break; - case 0x29: - lbvs(); - icount -= 5; - break; - case 0x2a: - lbpl(); - icount -= 5; - break; - case 0x2b: - lbmi(); - icount -= 5; - break; - case 0x2c: - lbge(); - icount -= 5; - break; - case 0x2d: - lblt(); - icount -= 5; - break; - case 0x2e: - lbgt(); - icount -= 5; - break; - case 0x2f: - lble(); - icount -= 5; - break; - case 0x3f: - swi2(); - icount -= 20; - break; - case 0x83: - cmpd_im(); - icount -= 5; - break; - case 0x8c: - cmpy_im(); - icount -= 5; - break; - case 0x8d: - lbsr(); - icount -= 9; - break; - case 0x8e: - ldy_im(); - icount -= 4; - break; -// case 0x8f: flag16_im();->cycle=4; break; // 20130417 - case 0x93: - cmpd_di(); - icount -= 7; - break; - case 0x9c: - cmpy_di(); - icount -= 7; - break; - case 0x9e: - ldy_di(); - icount -= 6; - break; - case 0x9f: - sty_di(); - icount -= 6; - break; - case 0xa3: - cmpd_ix(); - icount -= 7; - break; - case 0xac: - cmpy_ix(); - icount -= 7; - break; - case 0xae: - ldy_ix(); - icount -= 6; - break; - case 0xaf: - sty_ix(); - icount -= 6; - break; - case 0xb3: - cmpd_ex(); - icount -= 8; - break; - case 0xbc: - cmpy_ex(); - icount -= 8; - break; - case 0xbe: - ldy_ex(); - icount -= 7; - break; - case 0xbf: - sty_ex(); - icount -= 7; - break; - case 0xce: - lds_im(); - icount -= 4; - break; -// case 0xcf: flag16_im();->cycle=4; break; - case 0xde: - lds_di(); - icount -= 6; - break; - case 0xdf: - sts_di(); - icount -= 6; - break; - case 0xee: - lds_ix(); - icount -= 6; - break; - case 0xef: - sts_ix(); - icount -= 6; - break; - case 0xfe: - lds_ex(); - icount -= 7; - break; - case 0xff: - sts_ex(); - icount -= 7; - break; - default: - PC--; - IIError(); - break; - } -} - -/* $11xx opcodes */ -OP_HANDLER(pref11) { - uint8_t ireg2 = ROP_ARG(PCD); - PC++; - switch (ireg2) { - case 0x3f: - swi3(); - icount -= 20; - break; - - case 0x83: - cmpu_im(); - icount -= 5; - break; - case 0x8c: - cmps_im(); - icount -= 5; - break; - - case 0x93: - cmpu_di(); - icount -= 7; - break; - case 0x9c: - cmps_di(); - icount -= 7; - break; - - case 0xa3: - cmpu_ix(); - icount -= 7; - break; - case 0xac: - cmps_ix(); - icount -= 7; - break; - - case 0xb3: - cmpu_ex(); - icount -= 8; - break; - case 0xbc: - cmps_ex(); - icount -= 8; - break; - - default: - PC--; - IIError(); - break; - } - } - -#define STATE_VERSION 5 - -bool MC6809_BASE::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - state_fio->StateValue(icount); - state_fio->StateValue(extra_icount); - state_fio->StateValue(int_state); - - state_fio->StateValue(pc.d); - state_fio->StateValue(ppc.d); - state_fio->StateValue(acc.d); - state_fio->StateValue(dp.d); - state_fio->StateValue(u.d); - state_fio->StateValue(s.d); - state_fio->StateValue(x.d); - state_fio->StateValue(y.d); - state_fio->StateValue(cc); - state_fio->StateValue(ea.d); - - // V2 - state_fio->StateValue(req_halt_on); - state_fio->StateValue(req_halt_off); - state_fio->StateValue(busreq); - - state_fio->StateValue(total_icount); - state_fio->StateValue(waitfactor); - state_fio->StateValue(waitcount); - - // post process - if(loading) { - prev_total_icount = total_icount; - // Post process for collecting statistics. - cycles_tmp_count = total_icount; - extra_tmp_count = 0; - insns_count = 0; - frames_count = 0; - nmi_count = 0; - firq_count = 0; - irq_count = 0; - } - return true; -} - - diff --git a/source/src/vm/mc6820.h b/source/src/vm/mc6820.h index e6550c48b..d66b1793b 100644 --- a/source/src/vm/mc6820.h +++ b/source/src/vm/mc6820.h @@ -21,9 +21,7 @@ #define SIG_MC6820_C2_A 4 #define SIG_MC6820_C2_B 5 -class VM; -class EMU; -class MC6820 : public DEVICE +class DLL_PREFIX MC6820 : public DEVICE { private: struct { @@ -39,7 +37,7 @@ class MC6820 : public DEVICE } port[2]; public: - MC6820(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MC6820(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 2; i++) { initialize_output_signals(&port[i].outputs); diff --git a/source/src/vm/mc6840.h b/source/src/vm/mc6840.h index 9ed8042cf..a8d306174 100644 --- a/source/src/vm/mc6840.h +++ b/source/src/vm/mc6840.h @@ -22,9 +22,7 @@ #define SIG_MC6840_GATE_1 4 #define SIG_MC6840_GATE_2 5 -class VM; -class EMU; -class MC6840 : public DEVICE +class DLL_PREFIX MC6840 : public DEVICE { private: enum @@ -79,7 +77,7 @@ class MC6840 : public DEVICE void __FASTCALL set_clock(int idx, int state); public: - MC6840(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MC6840(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_ch0); initialize_output_signals(&outputs_ch1); @@ -96,7 +94,7 @@ class MC6840 : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t offset, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t offset); - void event_callback(int id, int err); + void __FASTCALL event_callback(int id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mc6844.h b/source/src/vm/mc6844.h index 5cbca05ab..d36d93c09 100644 --- a/source/src/vm/mc6844.h +++ b/source/src/vm/mc6844.h @@ -21,7 +21,7 @@ class DEBUGGER; -class MC6844 : public DEVICE +class DLL_PREFIX MC6844 : public DEVICE { private: DEVICE* d_memory; @@ -44,7 +44,7 @@ class MC6844 : public DEVICE void __FASTCALL update_irq(); public: - MC6844(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MC6844(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { // TIP: if((DEVICE::prev_device == NULL) || (DEVICE::this_device_id == 0)) DEVICE must be DUMMY. // And, at this device, should not be FIRST DEVICE. 20170613 Ohta. diff --git a/source/src/vm/mc6847.cpp b/source/src/vm/mc6847.cpp index 5715cd6d0..962c7e2ec 100644 --- a/source/src/vm/mc6847.cpp +++ b/source/src/vm/mc6847.cpp @@ -8,7 +8,7 @@ */ #include "vm.h" -#include "emu.h" +//#include "emu.h" #include "mc6847.h" #ifndef MC6847_VRAM_OFS diff --git a/source/src/vm/mc6847.h b/source/src/vm/mc6847.h index 68e75c3d4..e8502302c 100644 --- a/source/src/vm/mc6847.h +++ b/source/src/vm/mc6847.h @@ -23,7 +23,7 @@ #define SIG_MC6847_ENABLE 6 #define SIG_MC6847_DISABLE 7 -class MC6847_BASE : public DEVICE +class DLL_PREFIX MC6847_BASE : public DEVICE { protected: DEVICE *d_cpu; @@ -57,7 +57,7 @@ class MC6847_BASE : public DEVICE virtual void __FASTCALL draw_alpha(); public: - MC6847_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MC6847_BASE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_cpu = NULL; ag = as = intext = css = inv = false; @@ -73,7 +73,7 @@ class MC6847_BASE : public DEVICE void reset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); bool process_state(FILEIO* state_fio, bool loading); @@ -103,7 +103,7 @@ class MC6847 : public MC6847_BASE protected: void __FASTCALL draw_alpha(); public: - MC6847(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MC6847_BASE(parent_vm, parent_emu) + MC6847(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MC6847_BASE(parent_vm, parent_emu) { } ~MC6847() {}; diff --git a/source/src/vm/mc6850.h b/source/src/vm/mc6850.h index a2c3c3864..244e780d9 100644 --- a/source/src/vm/mc6850.h +++ b/source/src/vm/mc6850.h @@ -21,7 +21,7 @@ class FIFO; -class MC6850 : public DEVICE +class DLL_PREFIX MC6850 : public DEVICE { private: uint8_t recv, status, ctrl; @@ -37,7 +37,7 @@ class MC6850 : public DEVICE void __FASTCALL update_irq(); public: - MC6850(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MC6850(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_out); initialize_output_signals(&outputs_rts); @@ -53,7 +53,7 @@ class MC6850 : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/mcs48.cpp b/source/src/vm/mcs48.cpp index 3d81bedd8..8d4b10193 100644 --- a/source/src/vm/mcs48.cpp +++ b/source/src/vm/mcs48.cpp @@ -8,7 +8,7 @@ [ MCS48 ] */ #include "vm.h" -#include "../emu.h" +//#include "../emu.h" #include "mcs48_flags.h" #include "mcs48.h" diff --git a/source/src/vm/mcs48.h b/source/src/vm/mcs48.h index 8c307c7e9..51ba48f29 100644 --- a/source/src/vm/mcs48.h +++ b/source/src/vm/mcs48.h @@ -107,12 +107,12 @@ struct mcs48_state #define __MCS48_OPHANDLER(_name) int MCS48_BASE::_name(mcs48_state *cpustate) #define __MCS48_OPHANDLER_D(_name) int __FASTCALL _name(mcs48_state *cpustate) -class MCS48MEM : public DEVICE +class DLL_PREFIX MCS48MEM : public DEVICE { private: uint8_t ram[0x100]; public: - MCS48MEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MCS48MEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { memset(ram, 0, sizeof(ram)); set_device_name(_T("MCS48 MEMORY BUS")); @@ -130,7 +130,7 @@ class MCS48MEM : public DEVICE bool process_state(FILEIO* state_fio, bool loading); }; -class MCS48_BASE : public DEVICE +class DLL_PREFIX MCS48_BASE : public DEVICE { protected: inline UINT8 __FASTCALL argument_fetch(mcs48_state *cpustate); @@ -470,7 +470,7 @@ class MCS48_BASE : public DEVICE inline UINT8 __FASTCALL opcode_fetch(mcs48_state *cpustate); int __FASTCALL op_call(mcs48_state *); public: - MCS48_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MCS48_BASE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_mem = d_io = d_intr = NULL; d_debugger = NULL; @@ -507,7 +507,7 @@ class MCS48_BASE : public DEVICE { d_io = device; } - void set_context_intr(DEVICE* device) + void set_context_intr(DEVICE* device, uint32_t bit = 0xfffffffff) { d_intr = device; } @@ -734,7 +734,7 @@ class MCS48 : public MCS48_BASE public: - MCS48(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MCS48_BASE(parent_vm, parent_emu) + MCS48(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MCS48_BASE(parent_vm, parent_emu) { } ~MCS48() {} diff --git a/source/src/vm/memory.cpp b/source/src/vm/memory.cpp index 2c5b3bee7..670f24524 100644 --- a/source/src/vm/memory.cpp +++ b/source/src/vm/memory.cpp @@ -7,6 +7,9 @@ [ memory ] */ +// NOTE: this memory bus class invites the cpu is little endian. +// if the cpu is big endian, you need to use the memory bus class for big endian (not implemented yet). + #include "memory.h" #define ADDR_MASK (addr_max - 1) @@ -14,9 +17,19 @@ void MEMORY::initialize() { + DEVICE::initialize(); + _MEMORY_DISABLE_DMA_MMIO = osd->check_feature(_T("MEMORY_DISABLE_DMA_MMIO")); + if(!(addr_max_was_set) && osd->check_feature(_T("MEMORY_ADDR_MAX"))) { + addr_max = osd->get_feature_uint64_value(_T("MEMORY_ADDR_MAX")); + } + if(!(bank_size_was_set) && osd->check_feature(_T("MEMORY_BANK_SIZE"))) { + bank_size = osd->get_feature_uint64_value(_T("MEMORY_BANK_SIZE")); + } // allocate tables here to support multiple instances with different address range if(rd_table == NULL) { int64_t bank_num = addr_max / bank_size; + bank_mask = BANK_MASK; + addr_mask = ADDR_MASK; rd_dummy = (uint8_t *)malloc(bank_size); wr_dummy = (uint8_t *)malloc(bank_size); @@ -25,16 +38,16 @@ void MEMORY::initialize() wr_table = (bank_t *)calloc(bank_num, sizeof(bank_t)); for(int i = 0; i < bank_num; i++) { - rd_table[i].dev = NULL; + rd_table[i].device = NULL; rd_table[i].memory = rd_dummy; - rd_table[i].wait = 0; + rd_table[i].wait = 0; - wr_table[i].dev = NULL; + wr_table[i].device = NULL; wr_table[i].memory = wr_dummy; - rd_table[i].wait = 0; + wr_table[i].wait = 0; } for(int i = 0;; i++) { - if(bank_size == (int64_t)(1 << i)) { + if(bank_size == (uint64_t)(1 << i)) { addr_shift = i; break; } @@ -55,10 +68,10 @@ uint32_t MEMORY::read_data8(uint32_t addr) { int bank = (addr & ADDR_MASK) >> addr_shift; - if(rd_table[bank].dev != NULL) { - return rd_table[bank].dev->read_memory_mapped_io8(addr); + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io8(addr); } else { - return rd_table[bank].memory[addr & BANK_MASK]; + return rd_table[bank].memory[addr & bank_mask]; } } @@ -66,114 +79,125 @@ void MEMORY::write_data8(uint32_t addr, uint32_t data) { int bank = (addr & ADDR_MASK) >> addr_shift; - if(wr_table[bank].dev != NULL) { - wr_table[bank].dev->write_memory_mapped_io8(addr, data); + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io8(addr, data); } else { - wr_table[bank].memory[addr & BANK_MASK] = data; + wr_table[bank].memory[addr & bank_mask] = data; } } uint32_t MEMORY::read_data16(uint32_t addr) { - int bank = (addr & ADDR_MASK) >> addr_shift; + uint32_t addr2 = addr & BANK_MASK; - if(rd_table[bank].dev != NULL) { - return rd_table[bank].dev->read_memory_mapped_io16(addr); - } else { - int bank1 = ((addr + 1) & ADDR_MASK) >> addr_shift; - if(bank != bank1) { - uint32_t val = read_data8(addr); - val |= read_data8(addr + 1) << 8; - return val; + if(addr2 + 1 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io16(addr); } else { - uint8_t* p = (uint8_t*)(&(rd_table[bank].memory[addr & BANK_MASK])); - uint32_t val; -#if defined(__LITTLE_ENDIAN__) - uint16_t* pp = (uint16_t*)p; - val = (uint32_t)(*pp); -#else - val = p[0]; - val = (val << 8) | ((uint32_t)(p[1])); -#endif - return val; + #ifdef __BIG_ENDIAN__ + uint32_t val; + val = rd_table[bank].memory[addr2 ]; + val |= rd_table[bank].memory[addr2 + 1] << 8; + return val; + #else + return *(uint16_t *)(rd_table[bank].memory + addr2); + #endif } - } + } else { + uint32_t val; + val = read_data8(addr ); + val |= read_data8(addr + 1) << 8; + return val; + } } void MEMORY::write_data16(uint32_t addr, uint32_t data) { - int bank = (addr & ADDR_MASK) >> addr_shift; - - if(wr_table[bank].dev != NULL) { - wr_table[bank].dev->write_memory_mapped_io16(addr, data); - } else { - int bank1 = ((addr + 1) & ADDR_MASK) >> addr_shift; - if(bank != bank1) { - write_data8(addr, data & 0xff); - write_data8(addr + 1, (data >> 8) & 0xff); + uint32_t addr2 = addr & BANK_MASK; + if(addr2 + 1 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io16(addr, data); } else { - uint8_t* p = (uint8_t*)(&(wr_table[bank].memory[addr & BANK_MASK])); -#if defined(__LITTLE_ENDIAN__) - uint16_t* pp = (uint16_t*)p; - *pp = (uint16_t)data; -#else - p[0] = data & 0xff; - p[1] = (data >> 8) & 0xff; -#endif - } - } + #ifdef __BIG_ENDIAN__ + wr_table[bank].memory[addr2 ] = (data ) & 0xff + wr_table[bank].memory[addr2 + 1] = (data >> 8) & 0xff + #else + *(uint16_t *)(wr_table[bank].memory + addr2) = data; + #endif + } + } else { + write_data8(addr , (data ) & 0xff); + write_data8(addr + 1, (data >> 8) & 0xff); + } + } uint32_t MEMORY::read_data32(uint32_t addr) { - int bank = (addr & ADDR_MASK) >> addr_shift; + uint32_t addr2 = addr & BANK_MASK; - if(rd_table[bank].dev != NULL) { - return rd_table[bank].dev->read_memory_mapped_io32(addr); - } else { - int bank1 = ((addr + 3) & ADDR_MASK) >> addr_shift; - if(bank != bank1) { - uint32_t val = read_data16(addr); - val |= read_data16(addr + 2) << 16; - return val; + if(addr2 + 3 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io32(addr); } else { - uint8_t* p = (uint8_t*)(&(rd_table[bank].memory[addr & BANK_MASK])); - uint32_t val; -#if defined(__LITTLE_ENDIAN__) - uint32_t* pp = (uint32_t*)p; - val = *pp; -#else - val = ((uint32_t)p[0]) | (((uint32_t)p[1]) << 8) | (((uint32_t)p[2]) << 16) |(((uint32_t)p[3]) << 24); -#endif - return val; + #ifdef __BIG_ENDIAN__ + uint32_t val; + val = rd_table[bank].memory[addr2 ]; + val |= rd_table[bank].memory[addr2 + 1] << 8; + val |= rd_table[bank].memory[addr2 + 2] << 16; + val |= rd_table[bank].memory[addr2 + 3] << 24; + return val; + #else + return *(uint32_t *)(rd_table[bank].memory + addr2); + #endif } - } + } else if(!(addr & 1)) { + uint32_t val; + val = read_data16(addr ); + val |= read_data16(addr + 2) << 16; + return val; + } else { + uint32_t val; + val = read_data8 (addr ); + val |= read_data16(addr + 1) << 8; + val |= read_data8 (addr + 3) << 24; + return val; + } } void MEMORY::write_data32(uint32_t addr, uint32_t data) { - int bank = (addr & ADDR_MASK) >> addr_shift; + uint32_t addr2 = addr & BANK_MASK; - if(wr_table[bank].dev != NULL) { - wr_table[bank].dev->write_memory_mapped_io32(addr, data); - } else { - int bank1 = ((addr + 3) & ADDR_MASK) >> addr_shift; - if(bank != bank1) { - write_data16(addr, data & 0xffff); - write_data16(addr + 2, (data >> 16) & 0xffff); + if(addr2 + 3 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io32(addr, data); } else { - uint8_t* p = (uint8_t*)(&(wr_table[bank].memory[addr & BANK_MASK])); -#if defined(__LITTLE_ENDIAN__) - uint32_t* pp = (uint32_t*)p; - *pp = data; -#else - p[0] = data & 0xff; - p[1] = (data >> 8) & 0xff; - p[2] = (data >> 16) & 0xff; - p[3] = (data >> 24) & 0xff; -#endif + #ifdef __BIG_ENDIAN__ + wr_table[bank].memory[addr2 ] = (data ) & 0xff + wr_table[bank].memory[addr2 + 1] = (data >> 8) & 0xff + wr_table[bank].memory[addr2 + 2] = (data >> 16) & 0xff + wr_table[bank].memory[addr2 + 3] = (data >> 24) & 0xff + #else + *(uint32_t *)(wr_table[bank].memory + addr2) = data; + #endif } - } + } else if(!(addr & 1)) { + write_data16(addr , (data ) & 0xffff); + write_data16(addr + 2, (data >> 16) & 0xffff); + } else { + write_data8 (addr , (data ) & 0x00ff); + write_data16(addr + 1, (data >> 8) & 0xffff); + write_data8 (addr + 3, (data >> 24) & 0x00ff); + } } uint32_t MEMORY::read_data8w(uint32_t addr, int* wait) @@ -181,10 +205,10 @@ uint32_t MEMORY::read_data8w(uint32_t addr, int* wait) int bank = (addr & ADDR_MASK) >> addr_shift; *wait = rd_table[bank].wait; - if(rd_table[bank].dev != NULL) { - return rd_table[bank].dev->read_memory_mapped_io8(addr); + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io8(addr); } else { - return rd_table[bank].memory[addr & BANK_MASK]; + return rd_table[bank].memory[addr & bank_mask]; } } @@ -193,78 +217,186 @@ void MEMORY::write_data8w(uint32_t addr, uint32_t data, int* wait) int bank = (addr & ADDR_MASK) >> addr_shift; *wait = wr_table[bank].wait; - if(wr_table[bank].dev != NULL) { - wr_table[bank].dev->write_memory_mapped_io8(addr, data); + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io8(addr, data); } else { - wr_table[bank].memory[addr & BANK_MASK] = data; + wr_table[bank].memory[addr & bank_mask] = data; } } uint32_t MEMORY::read_data16w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_data8w(addr, &wait_l); - val |= read_data8w(addr + 1, &wait_h) << 8; - *wait = wait_l + wait_h; - return val; + uint32_t addr2 = addr & BANK_MASK; + + if(addr2 + 1 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + *wait = rd_table[bank].wait * 2; // 8bit bus ??? + + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io16(addr); + } else { + #ifdef __BIG_ENDIAN__ + uint32_t val; + val = rd_table[bank].memory[addr2 ]; + val |= rd_table[bank].memory[addr2 + 1] << 8; + return val; + #else + return *(uint16_t *)(rd_table[bank].memory + addr2); + #endif + } + } else { + int wait_0, wait_1; + uint32_t val; + val = read_data8w(addr , &wait_0); + val |= read_data8w(addr + 1, &wait_1) << 8; + *wait = wait_0 + wait_1; + return val; + } } void MEMORY::write_data16w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_data8w(addr, data & 0xff, &wait_l); - write_data8w(addr + 1, (data >> 8) & 0xff, &wait_h); - *wait = wait_l + wait_h; + uint32_t addr2 = addr & BANK_MASK; + + if(addr2 + 1 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + *wait = wr_table[bank].wait * 2; // 8bit bus ??? + + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io16(addr, data); + } else { + #ifdef __BIG_ENDIAN__ + wr_table[bank].memory[addr2 ] = (data ) & 0xff + wr_table[bank].memory[addr2 + 1] = (data >> 8) & 0xff + #else + *(uint16_t *)(wr_table[bank].memory + addr2) = data; + #endif + } + } else { + int wait_0, wait_1; + write_data8w(addr , (data ) & 0xff, &wait_0); + write_data8w(addr + 1, (data >> 8) & 0xff, &wait_1); + *wait = wait_0 + wait_1; + } } uint32_t MEMORY::read_data32w(uint32_t addr, int* wait) { - int wait_l, wait_h; - uint32_t val = read_data16w(addr, &wait_l); - val |= read_data16w(addr + 2, &wait_h) << 16; - *wait = wait_l + wait_h; - return val; + uint32_t addr2 = addr & BANK_MASK; + + if(addr2 + 3 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + *wait = rd_table[bank].wait * 4; // 8bit bus ??? + + if(rd_table[bank].device != NULL) { + return rd_table[bank].device->read_memory_mapped_io32(addr); + } else { + #ifdef __BIG_ENDIAN__ + uint32_t val; + val = rd_table[bank].memory[addr2 ]; + val |= rd_table[bank].memory[addr2 + 1] << 8; + val |= rd_table[bank].memory[addr2 + 2] << 16; + val |= rd_table[bank].memory[addr2 + 3] << 24; + return val; + #else + return *(uint32_t *)(rd_table[bank].memory + addr2); + #endif + } + } else if(!(addr & 1)) { + int wait_0, wait_1; + uint32_t val; + val = read_data16w(addr , &wait_0); + val |= read_data16w(addr + 2, &wait_1) << 16; + *wait = wait_0 + wait_1; + return val; + } else { + int wait_0, wait_1, wait_2; + uint32_t val; + val = read_data8w (addr , &wait_0); + val |= read_data16w(addr + 1, &wait_1) << 8; + val |= read_data8w (addr + 3, &wait_2) << 24; + *wait = wait_0 + wait_1 + wait_2; + return val; + } } void MEMORY::write_data32w(uint32_t addr, uint32_t data, int* wait) { - int wait_l, wait_h; - write_data16w(addr, data & 0xffff, &wait_l); - write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_h); - *wait = wait_l + wait_h; + uint32_t addr2 = addr & BANK_MASK; + + if(addr2 + 3 < bank_size) { + int bank = (addr & ADDR_MASK) >> addr_shift; + + *wait = wr_table[bank].wait * 4; // 8bit bus ??? + + if(wr_table[bank].device != NULL) { + wr_table[bank].device->write_memory_mapped_io32(addr, data); + } else { + #ifdef __BIG_ENDIAN__ + wr_table[bank].memory[addr2 ] = (data ) & 0xff + wr_table[bank].memory[addr2 + 1] = (data >> 8) & 0xff + wr_table[bank].memory[addr2 + 2] = (data >> 16) & 0xff + wr_table[bank].memory[addr2 + 3] = (data >> 24) & 0xff + #else + *(uint32_t *)(wr_table[bank].memory + addr2) = data; + #endif + } + } else if(!(addr & 1)) { + int wait_0, wait_1; + write_data16w(addr , (data ) & 0xffff, &wait_0); + write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_1); + *wait = wait_0 + wait_1; + } else { + int wait_0, wait_1, wait_2; + write_data8w (addr , (data ) & 0x00ff, &wait_0); + write_data16w(addr + 1, (data >> 8) & 0xffff, &wait_1); + write_data8w (addr + 3, (data >> 24) & 0x00ff, &wait_2); + *wait = wait_0 + wait_1 + wait_2; + } } -#ifdef MEMORY_DISABLE_DMA_MMIO - uint32_t MEMORY::read_dma_data8(uint32_t addr) { + if(!(_MEMORY_DISABLE_DMA_MMIO)) { + return read_data8(addr); + } int bank = (addr & ADDR_MASK) >> addr_shift; - if(rd_table[bank].dev != NULL) { -// return rd_table[bank].dev->read_memory_mapped_io8(addr); + if(rd_table[bank].device != NULL) { +// return rd_table[bank].device->read_memory_mapped_io8(addr); return 0xff; } else { - return rd_table[bank].memory[addr & BANK_MASK]; + return rd_table[bank].memory[addr & bank_mask]; } } void MEMORY::write_dma_data8(uint32_t addr, uint32_t data) { + if(!(_MEMORY_DISABLE_DMA_MMIO)) { + write_data8(addr, data); + return; + } int bank = (addr & ADDR_MASK) >> addr_shift; - if(wr_table[bank].dev != NULL) { -// wr_table[bank].dev->write_memory_mapped_io8(addr, data); + if(wr_table[bank].device != NULL) { +// wr_table[bank].device->write_memory_mapped_io8(addr, data); } else { - wr_table[bank].memory[addr & BANK_MASK] = data; + wr_table[bank].memory[addr & bank_mask] = data; } } uint32_t MEMORY::read_dma_data16(uint32_t addr) { + if(!(_MEMORY_DISABLE_DMA_MMIO)) { + return read_data16(addr); + } int bank = (addr & ADDR_MASK) >> addr_shift; - if(rd_table[bank].dev != NULL) { -// return rd_table[bank].dev->read_memory_mapped_io16(addr); + if(rd_table[bank].device != NULL) { +// return rd_table[bank].device->read_memory_mapped_io16(addr); return 0xffff; } else { uint32_t val = read_dma_data8(addr); @@ -275,10 +407,14 @@ uint32_t MEMORY::read_dma_data16(uint32_t addr) void MEMORY::write_dma_data16(uint32_t addr, uint32_t data) { + if(!(_MEMORY_DISABLE_DMA_MMIO)) { + write_data16(addr, data); + return; + } int bank = (addr & ADDR_MASK) >> addr_shift; - if(wr_table[bank].dev != NULL) { -// wr_table[bank].dev->write_memory_mapped_io16(addr, data); + if(wr_table[bank].device != NULL) { +// wr_table[bank].device->write_memory_mapped_io16(addr, data); } else { write_dma_data8(addr, data & 0xff); write_dma_data8(addr + 1, (data >> 8) & 0xff); @@ -289,8 +425,8 @@ uint32_t MEMORY::read_dma_data32(uint32_t addr) { int bank = (addr & ADDR_MASK) >> addr_shift; - if(rd_table[bank].dev != NULL) { -// return rd_table[bank].dev->read_memory_mapped_io32(addr); + if(rd_table[bank].device != NULL) { +// return rd_table[bank].device->read_memory_mapped_io32(addr); return 0xffffffff; } else { uint32_t val = read_dma_data16(addr); @@ -303,14 +439,13 @@ void MEMORY::write_dma_data32(uint32_t addr, uint32_t data) { int bank = (addr & ADDR_MASK) >> addr_shift; - if(wr_table[bank].dev != NULL) { -// wr_table[bank].dev->write_memory_mapped_io32(addr, data); + if(wr_table[bank].device != NULL) { +// wr_table[bank].device->write_memory_mapped_io32(addr, data); } else { write_dma_data16(addr, data & 0xffff); write_dma_data16(addr + 2, (data >> 16) & 0xffff); } } -#endif // register @@ -322,7 +457,7 @@ void MEMORY::set_memory_r(uint32_t start, uint32_t end, uint8_t *memory) uint32_t end_bank = end >> addr_shift; for(uint32_t i = start_bank; i <= end_bank; i++) { - rd_table[i].dev = NULL; + rd_table[i].device = NULL; rd_table[i].memory = memory + bank_size * (i - start_bank); } } @@ -335,7 +470,7 @@ void MEMORY::set_memory_w(uint32_t start, uint32_t end, uint8_t *memory) uint32_t end_bank = end >> addr_shift; for(uint32_t i = start_bank; i <= end_bank; i++) { - wr_table[i].dev = NULL; + wr_table[i].device = NULL; wr_table[i].memory = memory + bank_size * (i - start_bank); } } @@ -348,7 +483,7 @@ void MEMORY::set_memory_mapped_io_r(uint32_t start, uint32_t end, DEVICE *device uint32_t end_bank = end >> addr_shift; for(uint32_t i = start_bank; i <= end_bank; i++) { - rd_table[i].dev = device; + rd_table[i].device = device; } } @@ -360,7 +495,7 @@ void MEMORY::set_memory_mapped_io_w(uint32_t start, uint32_t end, DEVICE *device uint32_t end_bank = end >> addr_shift; for(uint32_t i = start_bank; i <= end_bank; i++) { - wr_table[i].dev = device; + wr_table[i].device = device; } } @@ -396,7 +531,7 @@ void MEMORY::unset_memory_r(uint32_t start, uint32_t end) uint32_t end_bank = end >> addr_shift; for(uint32_t i = start_bank; i <= end_bank; i++) { - rd_table[i].dev = NULL; + rd_table[i].device = NULL; rd_table[i].memory = rd_dummy; } } @@ -409,7 +544,7 @@ void MEMORY::unset_memory_w(uint32_t start, uint32_t end) uint32_t end_bank = end >> addr_shift; for(uint32_t i = start_bank; i <= end_bank; i++) { - wr_table[i].dev = NULL; + wr_table[i].device = NULL; wr_table[i].memory = wr_dummy; } } @@ -421,11 +556,11 @@ void MEMORY::copy_table_w(uint32_t to, uint32_t start, uint32_t end) uint32_t start_bank = start >> addr_shift; uint32_t end_bank = end >> addr_shift; uint32_t to_bank = to >> addr_shift; - int blocks = (int)(addr_max / bank_size); + uint64_t blocks = addr_max / bank_size; - for(uint32_t i = start_bank; i <= end_bank; i++) { + for(uint64_t i = start_bank; i <= end_bank; i++) { if(to_bank >= blocks) break; - wr_table[to_bank].dev = wr_table[i].dev; + wr_table[to_bank].device = wr_table[i].device; wr_table[to_bank].memory = wr_table[i].memory; wr_table[to_bank].wait = wr_table[i].wait; to_bank++; @@ -439,11 +574,11 @@ void MEMORY::copy_table_r(uint32_t to, uint32_t start, uint32_t end) uint32_t start_bank = start >> addr_shift; uint32_t end_bank = end >> addr_shift; uint32_t to_bank = to >> addr_shift; - int blocks = (int)(addr_max / bank_size); + uint64_t blocks = addr_max / bank_size; - for(uint32_t i = start_bank; i <= end_bank; i++) { + for(uint64_t i = start_bank; i <= end_bank; i++) { if(to_bank >= blocks) break; - rd_table[to_bank].dev = rd_table[i].dev; + rd_table[to_bank].device = rd_table[i].device; rd_table[to_bank].memory = rd_table[i].memory; rd_table[to_bank].wait = rd_table[i].wait; to_bank++; diff --git a/source/src/vm/memory.h b/source/src/vm/memory.h index da9acc460..252ac189b 100644 --- a/source/src/vm/memory.h +++ b/source/src/vm/memory.h @@ -10,104 +10,104 @@ #ifndef _MEMORY_H_ #define _MEMORY_H_ -#include "vm.h" -#include "../emu.h" +#include "vm_template.h" +#include "../emu_template.h" #include "device.h" -#ifndef MEMORY_ADDR_MAX -#define MEMORY_ADDR_MAX 0x10000 -#endif -#ifndef MEMORY_BANK_SIZE -#define MEMORY_BANK_SIZE 0x1000 -#endif +//#ifndef MEMORY_ADDR_MAX +//#define MEMORY_ADDR_MAX 0x10000 +//#endif +//#ifndef MEMORY_BANK_SIZE +//#define MEMORY_BANK_SIZE 0x1000 +//#endif -class VM; -class EMU; -class MEMORY : public DEVICE +class DLL_PREFIX MEMORY : public DEVICE { -private: +protected: typedef struct { - DEVICE* dev; - uint8_t* memory; + DEVICE *device; + uint8_t *memory; int wait; } bank_t; - bank_t *rd_table; - bank_t *wr_table; - - int addr_shift; - uint8_t *rd_dummy; uint8_t *wr_dummy; + bool _MEMORY_DISABLE_DMA_MMIO; + bool bank_size_was_set; + bool addr_max_was_set; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { - addr_max = MEMORY_ADDR_MAX; - bank_size = MEMORY_BANK_SIZE; + // Set temporally values. + addr_max = 0x10000; + bank_size = 0x1000; + bank_size_was_set = false; + addr_max_was_set = false; rd_table = wr_table = NULL; rd_dummy = wr_dummy = NULL; - + + _MEMORY_DISABLE_DMA_MMIO = false; + set_device_name(_T("Generic Memory Bus")); } ~MEMORY() {} // common functions - void initialize(); - void release(); - uint32_t __FASTCALL read_data8(uint32_t addr); - void __FASTCALL write_data8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_data16(uint32_t addr); - void __FASTCALL write_data16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_data32(uint32_t addr); - void __FASTCALL write_data32(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_data8w(uint32_t addr, int* wait); - void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait); - uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait); - void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait); - uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait); - void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait); -#ifdef MEMORY_DISABLE_DMA_MMIO - uint32_t __FASTCALL read_dma_data8(uint32_t addr); - void __FASTCALL write_dma_data8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_dma_data16(uint32_t addr); - void __FASTCALL write_dma_data16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_dma_data32(uint32_t addr); - void __FASTCALL write_dma_data32(uint32_t addr, uint32_t data); -#endif + virtual void initialize(); + virtual void release(); + virtual uint32_t __FASTCALL read_data8(uint32_t addr); + virtual void __FASTCALL write_data8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_data16(uint32_t addr); + virtual void __FASTCALL write_data16(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_data32(uint32_t addr); + virtual void __FASTCALL write_data32(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_data8w(uint32_t addr, int* wait); + virtual void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait); + virtual uint32_t __FASTCALL read_data16w(uint32_t addr, int* wait); + virtual void __FASTCALL write_data16w(uint32_t addr, uint32_t data, int* wait); + virtual uint32_t __FASTCALL read_data32w(uint32_t addr, int* wait); + virtual void __FASTCALL write_data32w(uint32_t addr, uint32_t data, int* wait); + + virtual uint32_t __FASTCALL read_dma_data8(uint32_t addr); + virtual void __FASTCALL write_dma_data8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_data16(uint32_t addr); + virtual void __FASTCALL write_dma_data16(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_data32(uint32_t addr); + virtual void __FASTCALL write_dma_data32(uint32_t addr, uint32_t data); // unique functions - void set_memory_r(uint32_t start, uint32_t end, uint8_t *memory); - void set_memory_w(uint32_t start, uint32_t end, uint8_t *memory); + virtual void set_memory_r(uint32_t start, uint32_t end, uint8_t *memory); + virtual void set_memory_w(uint32_t start, uint32_t end, uint8_t *memory); void set_memory_rw(uint32_t start, uint32_t end, uint8_t *memory) { set_memory_r(start, end, memory); set_memory_w(start, end, memory); } - void set_memory_mapped_io_r(uint32_t start, uint32_t end, DEVICE *device); - void set_memory_mapped_io_w(uint32_t start, uint32_t end, DEVICE *device); + virtual void set_memory_mapped_io_r(uint32_t start, uint32_t end, DEVICE *device); + virtual void set_memory_mapped_io_w(uint32_t start, uint32_t end, DEVICE *device); void set_memory_mapped_io_rw(uint32_t start, uint32_t end, DEVICE *device) { set_memory_mapped_io_r(start, end, device); set_memory_mapped_io_w(start, end, device); } - void set_wait_r(uint32_t start, uint32_t end, int wait); - void set_wait_w(uint32_t start, uint32_t end, int wait); + virtual void set_wait_r(uint32_t start, uint32_t end, int wait); + virtual void set_wait_w(uint32_t start, uint32_t end, int wait); void set_wait_rw(uint32_t start, uint32_t end, int wait) { set_wait_r(start, end, wait); set_wait_w(start, end, wait); } - void unset_memory_r(uint32_t start, uint32_t end); - void unset_memory_w(uint32_t start, uint32_t end); + virtual void unset_memory_r(uint32_t start, uint32_t end); + virtual void unset_memory_w(uint32_t start, uint32_t end); void unset_memory_rw(uint32_t start, uint32_t end) { unset_memory_r(start, end); unset_memory_w(start, end); } - void copy_table_r(uint32_t to, uint32_t start, uint32_t end); - void copy_table_w(uint32_t to, uint32_t start, uint32_t end); + virtual void copy_table_r(uint32_t to, uint32_t start, uint32_t end); + virtual void copy_table_w(uint32_t to, uint32_t start, uint32_t end); void copy_table_rw(uint32_t to, uint32_t start, uint32_t end) { copy_table_r(to, start, end); copy_table_w(to, start, end); @@ -116,9 +116,42 @@ class MEMORY : public DEVICE bool write_bios(const _TCHAR *file_name, uint8_t *buffer, int size); bool read_image(const _TCHAR *file_path, uint8_t *buffer, int size); bool write_image(const _TCHAR *file_path, uint8_t *buffer, int size); + + // Unique functions. + void set_addr_max(int64_t size) + { + // Allow to modify before initialize() or set_foo_r|w|rw().. + if(rd_table == NULL) { + addr_max_was_set = true; + addr_max = size; + } + } + void set_bank_size(int64_t size) + { + if(rd_table == NULL) { + bank_size_was_set = true; + bank_size = size; + } + } + uint64_t get_addr_max() + { + return addr_max; + } + uint64_t get_bank_size() + { + return bank_size; + } - int64_t addr_max; - int64_t bank_size; + uint64_t addr_max; + uint64_t bank_size; + + uint64_t addr_mask; + uint64_t bank_mask; + + bank_t *rd_table; + bank_t *wr_table; + + int addr_shift; }; #endif diff --git a/source/src/vm/micom_mahjong/CMakeLists.txt b/source/src/vm/micom_mahjong/CMakeLists.txt new file mode 100644 index 000000000..29e84890d --- /dev/null +++ b/source/src/vm/micom_mahjong/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required (VERSION 2.6) + +message("* vm/${EXE_NAME}") + +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +add_library(vm_${EXE_NAME} + ./memory.cpp + ./keyboard.cpp + + ./micom_mahjong.cpp + ) diff --git a/source/src/vm/micom_mahjong/dis.bat b/source/src/vm/micom_mahjong/dis.bat new file mode 100644 index 000000000..905a80e08 --- /dev/null +++ b/source/src/vm/micom_mahjong/dis.bat @@ -0,0 +1,2 @@ +yazd MICOM_MAHJONG.ROM MICOM_MAHJONG.DIS --list --entry:0 --entry:0x0125 --entry:0x0145 --entry:0x0165 --entry:0x0750 --entry:0x3000 --entry:0x3002 --entry:0x3004 --entry:0x3006 --entry:0x3009 --entry:0x300c --entry:0x300f --entry:0x3012 --entry:0x3015 --entry:0x3018 --entry:0x301b --entry:0x301e --entry:0x3021 --entry:0x3024 --entry:0x3027 --entry:0x302a --entry:0x302d --entry:0x3030 --entry:0x3033 --entry:0x3036 --entry:0x3039 --entry:0x303c --entry:0x303f --entry:0x3042 --entry:0x3fca --entry:0x3fdf + diff --git a/source/src/vm/micom_mahjong/keyboard.cpp b/source/src/vm/micom_mahjong/keyboard.cpp new file mode 100644 index 000000000..3106dc5f3 --- /dev/null +++ b/source/src/vm/micom_mahjong/keyboard.cpp @@ -0,0 +1,109 @@ +/* + MICOM MAHJONG Emulator 'eMuCom Mahjong' + + Author : Hiroaki GOTO as GORRY + Date : 2020.07.20 - + + [ keyboard ] +*/ + +#include "keyboard.h" +#include "memory.h" + +namespace MICOM_MAHJONG { +static const int key_map[][3] = { + { 0x31, 2, 0}, // KEY 1 = 1[FULL] + { 0x32, 2, 1}, // KEY 2 = 2[FULL] + { 0x33, 2, 2}, // KEY 3 = 3[FULL] + { 0x34, 2, 3}, // KEY 4 = 4[FULL] + { 0x35, 2, 4}, // KEY 5 = 5[FULL] + { 0x36, 2, 5}, // KEY 6 = 6[FULL] + { 0x37, 2, 6}, // KEY 7 = 7[FULL] + { 0x38, 2, 7}, // KEY 8 = 8[FULL] + { 0x39, 1, 2}, // KEY 9 = 9[FULL] + { 0x30, 1, 3}, // KEY 10 = 0[FULL] + { 0xbd, 1, 4}, // KEY 11 = -=[JP][US] + { 0x61, 1, 4}, // KEY 11 = 1[10KEY] + { 0xde, 1, 5}, // KEY 12 = ^~[JP] + { 0xbb, 1, 5}, // KEY 12 = =+[US] + { 0x62, 1, 5}, // KEY 12 = 2[10KEY] + { 0xdc, 1, 6}, // KEY 13 = \|[JP] + { 0x08, 1, 6}, // KEY 13 = Backspace + { 0x63, 1, 6}, // KEY 13 = 3[10KEY] + { 0x0d, 1, 7}, // KEY ツモ = Enter + { 0x20, 1, 7}, // KEY ツモ = Space + { 0x5a, 0, 2}, // KEY ポン = Z + { 0x58, 0, 3}, // KEY チー = X + { 0x43, 0, 4}, // KEY カン = C + { 0x56, 0, 5}, // KEY リーチ = V + { 0x41, 0, 6}, // KEY ロン = A + { 0x70, 0, 2}, // KEY ポン = [F1] + { 0x71, 0, 3}, // KEY チー = [F2] + { 0x72, 0, 4}, // KEY カン = [F3] + { 0x73, 0, 5}, // KEY リーチ = [F4] + { 0x74, 0, 6}, // KEY ロン = [F5] + { 0x00, 0, 0} +}; + +void KEYBOARD::initialize() +{ + key_stat = emu->get_key_buffer(); + column = 0; + + // register event + register_frame_event(this); +} + +void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask) +{ + switch (data) { + default: + break; + case 0xfe: + column = 2; + break; + case 0xfd: + column = 1; + break; + case 0xfb: + column = 0; + break; + } + update_key(); +} + +void KEYBOARD::event_frame() +{ + update_key(); +} + +void KEYBOARD::update_key() +{ + uint8_t stat = 0xff; + int i = 0; + while (!0) { + if (key_map[i][0] == 0) break; + if (key_map[i][1] == column) { + if (key_stat[key_map[i][0]]) { + stat &= ~(1 << key_map[i][2]); + } + } + i++; + } + d_memory->write_signal(SIG_MEMORY_KEYDATA, stat, 0xff); +} + +#define STATE_VERSION 1 + +bool KEYBOARD::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(column); + return true; +} +} diff --git a/source/src/vm/micom_mahjong/keyboard.h b/source/src/vm/micom_mahjong/keyboard.h new file mode 100644 index 000000000..40aacd6ac --- /dev/null +++ b/source/src/vm/micom_mahjong/keyboard.h @@ -0,0 +1,49 @@ +/* + MICOM MAHJONG Emulator 'eMuCom Mahjong' + + Author : Hiroaki GOTO as GORRY + Date : 2020.07.20 - + + [ keyboard ] +*/ + +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ + +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" + +#define SIG_KEYBOARD_STROBE 0 + +namespace MICOM_MAHJONG { +class KEYBOARD : public DEVICE +{ +private: + DEVICE *d_memory; + + const uint8_t* key_stat; + uint8_t column; + void update_key(); + +public: + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + set_device_name(_T("Keyboard")); + } + ~KEYBOARD() {} + + // common functions + void initialize(); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void event_frame(); + bool process_state(FILEIO* state_fio, bool loading); + + // unique function + void set_context_memory(DEVICE* device) + { + d_memory = device; + } +}; +} +#endif diff --git a/source/src/vm/micom_mahjong/memory.cpp b/source/src/vm/micom_mahjong/memory.cpp new file mode 100644 index 000000000..c49e7e547 --- /dev/null +++ b/source/src/vm/micom_mahjong/memory.cpp @@ -0,0 +1,167 @@ +/* + MICOM MAHJONG Emulator 'eMuCom Mahjong' + + Author : Hiroaki GOTO as GORRY + Date : 2020.07.20 - + + [ memory ] +*/ + + +#include "./memory.h" + +#define PRG_FILE_NAME "PRG.ROM" +#define CG_FILE_NAME "CG.ROM" + +namespace MICOM_MAHJONG { +void MEMORY::initialize() +{ + memset(prg, 0xff, sizeof(prg)); + memset(ram, 0x00, sizeof(ram)); + memset(vram, 0x00, sizeof(vram)); + memset(cg, 0x00, sizeof(vram)); + + // load rom images + FILEIO* fio = new FILEIO(); + if(fio->Fopen(create_local_path(_T(PRG_FILE_NAME)), FILEIO_READ_BINARY)) { + fio->Fread(prg, sizeof(prg), 1); + fio->Fclose(); + } + if(fio->Fopen(create_local_path(_T(CG_FILE_NAME)), FILEIO_READ_BINARY)) { + fio->Fread(cg, sizeof(cg), 1); + fio->Fclose(); + } + delete fio; + + register_vline_event(this); +} + +void MEMORY::write_signal(int id, uint32_t data, uint32_t mask) +{ + if(id == SIG_MEMORY_KEYDATA) { + key_data = data; + } +} + +void MEMORY::reset() +{ +} + +void MEMORY::event_vline(int v, int clock) +{ + // draw one line + if(v < 200) { + draw_line(v); + } +} + +void MEMORY::event_callback(int event_id, int err) +{ +} + +void MEMORY::write_data8(uint32_t addr, uint32_t data) +{ + addr &= 0xffff; + if(addr < 0x5000) { + } else if(addr < 0x5400) { + ram[addr-0x5000] = data; + } else if(addr < 0x6000) { + } else if(addr < 0x6400) { + vram[addr-0x6000] = data; + } else if(addr == 0x7002) { + d_keyboard->write_signal(SIG_KEYBOARD_STROBE, data, 0xff); + } else if(addr == 0x7004) { + speaker = data & 1; + d_pcm->write_signal(SIG_KEYBOARD_STROBE, speaker, 0x01); + } +} + +uint32_t MEMORY::read_data8(uint32_t addr) +{ + uint32_t val = 0; + + addr &= 0xffff; + if(addr < 0x4000) { + return prg[addr]; + } else if(addr < 0x5000) { + return 0xff; // pull up ? + } else if(addr < 0x5400) { + return ram[addr-0x5000]; + } else if(addr < 0x6000) { + return 0xff; // pull up ? + } else if(addr < 0x6400) { + return ram[addr-0x6000]; + } else if(addr == 0x7001) { + return key_data; + } + return 0xff; // pull up ? +} + +void MEMORY::draw_line(int v) +{ + int ptr = 32 * (v >> 3); + + for(int x = 0; x < 256; x += 8) { + uint16_t code = vram[ptr] << 3; + uint8_t pat_t = cg[code | (v & 7)]; + uint8_t* dest = &screen[v][x]; + + dest[0] = (pat_t & 0x80) ? 1 : 0; + dest[1] = (pat_t & 0x40) ? 1 : 0; + dest[2] = (pat_t & 0x20) ? 1 : 0; + dest[3] = (pat_t & 0x10) ? 1 : 0; + dest[4] = (pat_t & 0x08) ? 1 : 0; + dest[5] = (pat_t & 0x04) ? 1 : 0; + dest[6] = (pat_t & 0x02) ? 1 : 0; + dest[7] = (pat_t & 0x01) ? 1 : 0; + ptr++; + } +} + +void MEMORY::draw_screen() +{ + if(emu->now_waiting_in_debugger) { + // draw lines + for(int v = 0; v < 200; v++) { + draw_line(v); + } + } + + // copy to real screen + emu->set_vm_screen_lines(200); + for(int y = 0; y < 200; y++) { + scrntype_t* dest0 = emu->get_screen_buffer(2 * y); + scrntype_t* dest1 = emu->get_screen_buffer(2 * y + 1); + uint8_t* src = screen[y]; + + for(int x = 0, x2 = 0; x < 256; x++, x2 += 2) { + const scrntype_t col[2] = {0, RGB_COLOR(255,255,255)}; + dest0[x2] = dest0[x2 + 1] = col[src[x]]; + } + if(!config.scan_line) { + my_memcpy(dest1, dest0, 512 * sizeof(scrntype_t)); + } else { + memset(dest1, 0, 512 * sizeof(scrntype_t)); + } + } + emu->screen_skip_line(true); +} + +#define STATE_VERSION 1 + +bool MEMORY::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateArray(ram, sizeof(ram), 1); + state_fio->StateArray(vram, sizeof(vram), 1); + state_fio->StateValue(key_strobe); + state_fio->StateValue(key_data); + state_fio->StateValue(speaker); + return true; +} +} diff --git a/source/src/vm/micom_mahjong/memory.h b/source/src/vm/micom_mahjong/memory.h new file mode 100644 index 000000000..3dde96670 --- /dev/null +++ b/source/src/vm/micom_mahjong/memory.h @@ -0,0 +1,74 @@ +/* + MICOM MAHJONG Emulator 'eMuCom Mahjong' + + Author : Hiroaki GOTO as GORRY + Date : 2020.07.20 - + + [ memory ] +*/ + +#ifndef _MICOM_MAHJONG_MEMORY_H_ +#define _MICOM_MAHJONG_MEMORY_H_ + +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" + +#include "./keyboard.h" + +#define SIG_MEMORY_KEYDATA 0 + +namespace MICOM_MAHJONG { +class MEMORY : public DEVICE +{ +private: + DEVICE *d_keyboard; + DEVICE *d_pcm; + + uint8_t prg[0x8000]; // prg rom (16k) + uint8_t ram[0x0400]; // ram(1k) + uint8_t vram[0x400]; // vram(1k) + uint8_t cg[0x800]; // cg(2k) + + uint8_t key_strobe; + uint8_t key_data; + uint8_t speaker; + + // renderer + uint8_t screen[200][320]; + +public: + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + set_device_name(_T("Memory Bus")); + } + ~MEMORY() {} + + // common functions + void initialize(); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void reset(); + void event_vline(int v, int clock); + void __FASTCALL event_callback(int event_id, int err); + void __FASTCALL write_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_data8(uint32_t addr); + bool process_state(FILEIO* state_fio, bool loading); + + // unique functions + void set_context_keyboard(DEVICE* device) + { + d_keyboard = device; + } + + void set_context_pcm(DEVICE* device) + { + d_pcm = device; + } + + void draw_line(int v); + void draw_screen(); + +}; +} +#endif + diff --git a/source/src/vm/micom_mahjong/micom_mahjong.cpp b/source/src/vm/micom_mahjong/micom_mahjong.cpp new file mode 100644 index 000000000..57f538c48 --- /dev/null +++ b/source/src/vm/micom_mahjong/micom_mahjong.cpp @@ -0,0 +1,210 @@ +/* + MICOM MAHJONG Emulator 'eMuCom Mahjong' + + Author : Hiroaki GOTO as GORRY + Date : 2020.07.20 - + + [ virtual machine ] +*/ + +#include "micom_mahjong.h" +#include "../../emu.h" +#include "../device.h" +#include "../event.h" + +#include "../pcm1bit.h" +#include "../z80.h" + +#ifdef USE_DEBUGGER +#include "../debugger.h" +#endif + +#include "./keyboard.h" +#include "./memory.h" + +// ---------------------------------------------------------------------------- +// initialize +// ---------------------------------------------------------------------------- +using MICOM_MAHJONG::KEYBOARD; +using MICOM_MAHJONG::MEMORY; + +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) +{ + // create devices + first_device = last_device = NULL; + dummy = new DEVICE(this, emu); // must be 1st device + event = new EVENT(this, emu); // must be 2nd device + + dummy->set_device_name(_T("1st Dummy")); + + cpu = new Z80(this, emu); + + memory = new MEMORY(this, emu); + keyboard = new KEYBOARD(this, emu); + pcm = new PCM1BIT(this, emu); + + // set contexts + event->set_context_cpu(cpu); + event->set_context_sound(pcm); + + memory->set_context_keyboard(keyboard); + memory->set_context_pcm(pcm); + + keyboard->set_context_memory(memory); + + // cpu bus + cpu->set_context_mem(memory); +#ifdef USE_DEBUGGER + cpu->set_context_debugger(new DEBUGGER(this, emu)); +#endif + + // initialize all devices +#if defined(__GIT_REPO_VERSION) + strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1); +#endif + for(DEVICE* device = first_device; device; device = device->next_device) { + device->initialize(); + } +} + +VM::~VM() +{ + // delete all devices + for(DEVICE* device = first_device; device;) { + DEVICE *next_device = device->next_device; + device->release(); + delete device; + device = next_device; + } +} + +DEVICE* VM::get_device(int id) +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + if(device->this_device_id == id) { + return device; + } + } + return NULL; +} + +// ---------------------------------------------------------------------------- +// drive virtual machine +// ---------------------------------------------------------------------------- + +void VM::reset() +{ + // reset all devices + for(DEVICE* device = first_device; device; device = device->next_device) { + device->reset(); + } +} + +void VM::run() +{ + event->drive(); +} + +// ---------------------------------------------------------------------------- +// debugger +// ---------------------------------------------------------------------------- + +#ifdef USE_DEBUGGER +DEVICE *VM::get_cpu(int index) +{ + if(index == 0) { + return cpu; + } + return NULL; +} +#endif + +// ---------------------------------------------------------------------------- +// draw screen +// ---------------------------------------------------------------------------- + +void VM::draw_screen() +{ + memory->draw_screen(); +} + +// ---------------------------------------------------------------------------- +// soud manager +// ---------------------------------------------------------------------------- + +void VM::initialize_sound(int rate, int samples) +{ + // init sound manager + event->initialize_sound(rate, samples); + + // init sound gen + pcm->initialize_sound(rate, 8000); +} + +uint16_t* VM::create_sound(int* extra_frames) +{ + return event->create_sound(extra_frames); +} + +int VM::get_sound_buffer_ptr() +{ + return event->get_sound_buffer_ptr(); +} + +#ifdef USE_SOUND_VOLUME +void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r) +{ + if(ch == 0) { + pcm->set_volume(0, decibel_l, decibel_r); + } +} +#endif + +bool VM::is_frame_skippable() +{ + return event->is_frame_skippable(); +} + +void VM::update_config() +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + device->update_config(); + } +} + +#define STATE_VERSION 1 + +bool VM::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + for(DEVICE* device = first_device; device; device = device->next_device) { + // Note: typeid(foo).name is fixed by recent ABI.Not dec 6. + // const char *name = typeid(*device).name(); + // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O + const char *name = device->get_device_name(); + int len = (int)strlen(name); + + if(!state_fio->StateCheckInt32(len)) { + if(loading) { + printf("Class name len Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name); + } + return false; + } + if(!state_fio->StateCheckBuffer(name, len, 1)) { + if(loading) { + printf("Class name Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name); + } + return false; + } + if(!device->process_state(state_fio, loading)) { + if(loading) { + printf("Data loading Error: DEVID=%d\n", device->this_device_id); + } + return false; + } + } + // Machine specified. + return true; +} diff --git a/source/src/vm/micom_mahjong/micom_mahjong.h b/source/src/vm/micom_mahjong/micom_mahjong.h new file mode 100644 index 000000000..547554c88 --- /dev/null +++ b/source/src/vm/micom_mahjong/micom_mahjong.h @@ -0,0 +1,125 @@ +/* + MICOM MAHJONG Emulator 'eMuCom Mahjong' + + Author : Hiroaki GOTO as GORRY + Date : 2020.07.20 - + + [ virtual machine ] +*/ + +#ifndef _MICOM_MAHJONG_H_ +#define _MICOM_MAHJONG_H_ + +#define DEVICE_NAME "MICOM MAHJONG" +#define CONFIG_NAME "micom_mahjong" + +// device informations for virtual machine +#define FRAMES_PER_SEC 60 +#define LINES_PER_FRAME 262 +#define CPU_CLOCKS (11059200/4) +#define SCREEN_WIDTH 512 +#define SCREEN_HEIGHT 400 + +// device informations for win32 +#define USE_AUTO_KEY 5 +#define USE_AUTO_KEY_RELEASE 6 +#define USE_SOUND_VOLUME 1 +#define USE_DEBUGGER +#define USE_STATE +#define USE_CPU_Z80 +#define USE_SCREEN_FILTER +#define USE_SCANLINE + +#include "../../common.h" +#include "../../fileio.h" +#include "../vm_template.h" + +#ifdef USE_SOUND_VOLUME +static const _TCHAR *sound_device_caption[] = { + _T("BEEP"), +}; +#endif + + +class EMU; +class DEVICE; +class EVENT; + +class AND; +class PCM1BIT; +class Z80; + +namespace MICOM_MAHJONG { + class KEYBOARD; + class MEMORY; +} + +class VM : public VM_TEMPLATE +{ +protected: +// EMU* emu; + + // devices + EVENT* event; + + PCM1BIT* pcm; + Z80* cpu; + + MICOM_MAHJONG::MEMORY* memory; + MICOM_MAHJONG::KEYBOARD* keyboard; + +public: + // ---------------------------------------- + // initialize + // ---------------------------------------- + + VM(EMU_TEMPLATE* parent_emu); + ~VM(); + + // ---------------------------------------- + // for emulation class + // ---------------------------------------- + + // drive virtual machine + void reset(); + void run(); + double get_frame_rate() + { + return FRAMES_PER_SEC; + } + +#ifdef USE_DEBUGGER + // debugger + DEVICE *get_cpu(int index); +#endif + + // draw screen + void draw_screen(); + + // sound generation + void initialize_sound(int rate, int samples); + uint16_t* create_sound(int* extra_frames); + int get_sound_buffer_ptr(); +#ifdef USE_SOUND_VOLUME + void set_sound_device_volume(int ch, int decibel_l, int decibel_r); +#endif + + // user interface + + bool is_frame_skippable(); + + void update_config(); + bool process_state(FILEIO* state_fio, bool loading); + + // ---------------------------------------- + // for each device + // ---------------------------------------- + + // devices + DEVICE* get_device(int id); + //DEVICE* dummy; + //DEVICE* first_device; + //DEVICE* last_device; +}; + +#endif diff --git a/source/src/vm/midi_redirector.h b/source/src/vm/midi_redirector.h index 15e938b1a..aac5c72ce 100644 --- a/source/src/vm/midi_redirector.h +++ b/source/src/vm/midi_redirector.h @@ -49,9 +49,9 @@ Unset receiver (within some DEVICEs) port.This DON'T allow multiple device. */ class VM_TEMPLATE; -class EMU; +class EMU_TEMPLATE; class FIFO; -class MIDI_REDIRECTOR : public DEVICE { +class DLL_PREFIX MIDI_REDIRECTOR : public DEVICE { protected: FIFO* send_queue; FIFO* recv_queue; @@ -72,7 +72,7 @@ class MIDI_REDIRECTOR : public DEVICE { outputs_t outputs_receive_event; public: - MIDI_REDIRECTOR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MIDI_REDIRECTOR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_receiver = NULL; send_queue = NULL; diff --git a/source/src/vm/msm5205.h b/source/src/vm/msm5205.h index f46df8c78..18331b910 100644 --- a/source/src/vm/msm5205.h +++ b/source/src/vm/msm5205.h @@ -37,9 +37,7 @@ #define MSM6585_S80 (6+8) /* prescaler 1/80 (8KHz), data 4bit */ #define MSM6585_S20 (7+8) /* prescaler 1/20(32KHz), data 4bit */ -class VM; -class EMU; -class MSM5205 : public DEVICE +class DLL_PREFIX MSM5205 : public DEVICE { private: int32_t m_mod_clock; /* clock rate */ @@ -62,7 +60,7 @@ class MSM5205 : public DEVICE int volume_l, volume_r; public: - MSM5205(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MSM5205(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&m_vclk_cb); volume_m = 1024; @@ -74,8 +72,8 @@ class MSM5205 : public DEVICE // common functions void initialize(); void reset(); - void event_callback(int event_id, int err); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int event_id, int err); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/msm5832.cpp b/source/src/vm/msm5832.cpp index 7a5a8f84a..8d1776bf8 100644 --- a/source/src/vm/msm5832.cpp +++ b/source/src/vm/msm5832.cpp @@ -8,7 +8,7 @@ */ #include "vm.h" -#include "../emu.h" +//#include "../emu.h" #include "msm58321.h" #define EVENT_BUSY 0 @@ -19,7 +19,7 @@ DLL_PREFIX_I struct cur_time_s cur_time; #endif -MSM5832::MSM5832(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MSM58321_BASE(parent_vm, parent_emu) +MSM5832::MSM5832(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MSM58321_BASE(parent_vm, parent_emu) { set_device_name(_T("MSM5832 RTC")); } diff --git a/source/src/vm/msm58321.cpp b/source/src/vm/msm58321.cpp index 679a3dab9..39461eb54 100644 --- a/source/src/vm/msm58321.cpp +++ b/source/src/vm/msm58321.cpp @@ -8,7 +8,7 @@ */ #include "vm.h" -#include "../emu.h" +//#include "../emu.h" #include "msm58321.h" #define EVENT_BUSY 0 @@ -19,7 +19,7 @@ DLL_PREFIX_I struct cur_time_s cur_time; #endif -MSM58321::MSM58321(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MSM58321_BASE(parent_vm, parent_emu) +MSM58321::MSM58321(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MSM58321_BASE(parent_vm, parent_emu) { initialize_output_signals(&outputs_busy); set_device_name(_T("MSM58321 RTC")); diff --git a/source/src/vm/msm58321.h b/source/src/vm/msm58321.h index f4c048e11..1af297b89 100644 --- a/source/src/vm/msm58321.h +++ b/source/src/vm/msm58321.h @@ -24,9 +24,7 @@ #define SIG_MSM5832_ADDR 5 #define SIG_MSM5832_HOLD 6 -class VM; -class EMU; -class MSM58321_BASE : public DEVICE +class DLL_PREFIX MSM58321_BASE : public DEVICE { protected: // output signals @@ -47,7 +45,7 @@ class MSM58321_BASE : public DEVICE int start_day; int start_year; public: - MSM58321_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MSM58321_BASE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_data); set_device_name(_T("MSM5832 RTC")); @@ -58,7 +56,7 @@ class MSM58321_BASE : public DEVICE // common functions virtual void initialize(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); bool process_state(FILEIO* state_fio, bool loading); @@ -78,7 +76,7 @@ class MSM58321: public MSM58321_BASE void __FASTCALL write_to_cur_time(); void __FASTCALL set_busy(bool val); public: - MSM58321(VM_TEMPLATE* parent_vm, EMU* parent_emu); + MSM58321(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~MSM58321() {} void initialize(); @@ -96,7 +94,7 @@ class MSM5832: public MSM58321_BASE void __FASTCALL set_busy(bool val); public: - MSM5832(VM_TEMPLATE* parent_vm, EMU* parent_emu); + MSM5832(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~MSM5832() {} void initialize(); diff --git a/source/src/vm/msx/CMakeLists.txt b/source/src/vm/msx/CMakeLists.txt index d94fb6034..fa605da3d 100644 --- a/source/src/vm/msx/CMakeLists.txt +++ b/source/src/vm/msx/CMakeLists.txt @@ -1,9 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/msx1") +message("* vm/${EXE_NAME}") -if(BUILD_PX7) - add_library(vm_msx +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +set(MSX_BASE_SRCS joystick.cpp kanjirom.cpp keyboard.cpp @@ -13,65 +14,52 @@ if(BUILD_PX7) sound_cart.cpp msx_ex.cpp ) -elseif(BUILD_MSX2) - add_library(vm_msx - joystick.cpp - kanjirom.cpp - keyboard.cpp - memory_ex.cpp - rtcif.cpp - printer.cpp - scc.cpp - sound_cart.cpp - msx_ex.cpp + +if("${U_EXE_NAME}" STREQUAL "EMUHBF1XDJ") + add_library(vm_${EXE_NAME} + rtcif.cpp + ${MSX_BASE_SRCS} ) -elseif(BUILD_MSX2PLUS) - add_library(vm_msx - joystick.cpp - kanjirom.cpp - keyboard.cpp - memory_ex.cpp - rtcif.cpp - printer.cpp - scc.cpp - sound_cart.cpp - msx_ex.cpp + target_compile_definitions(vm_${EXE_NAME} PRIVATE -D_MSX_VDP_MESS) +elseif("${U_EXE_NAME}" STREQUAL "EMUPX7") + add_library(vm_${EXE_NAME} + ../ld700.cpp + ${MSX_BASE_SRCS} ) -elseif(BUILD_FSA1) - add_library(vm_msx - joystick.cpp - keyboard.cpp - kanjirom.cpp - memory_ex.cpp - rtcif.cpp - printer.cpp - scc.cpp - sound_cart.cpp - msx_ex.cpp +elseif("${U_EXE_NAME}" STREQUAL "EMUMSX2PLUS") + add_library(vm_${EXE_NAME} + rtcif.cpp + ${MSX_BASE_SRCS} ) -elseif(BUILD_HX20) - add_library(vm_msx - joystick.cpp - keyboard.cpp - kanjirom.cpp - memory_ex.cpp - rtcif.cpp - printer.cpp - scc.cpp - sound_cart.cpp - psg_stereo.cpp - msx_ex.cpp + target_compile_definitions(vm_${EXE_NAME} PRIVATE -D_MSX_VDP_MESS) +elseif("${U_EXE_NAME}" STREQUAL "EMUMSX2P") + add_library(vm_${EXE_NAME} + rtcif.cpp + ${MSX_BASE_SRCS} + ) + target_compile_definitions(vm_${EXE_NAME} PRIVATE -D_MSX_VDP_MESS) +elseif("${U_EXE_NAME}" STREQUAL "EMUMSX2") + add_library(vm_${EXE_NAME} + rtcif.cpp + ${MSX_BASE_SRCS} + ) + target_compile_definitions(vm_${EXE_NAME} PRIVATE -D_MSX_VDP_MESS) +elseif("${U_EXE_NAME}" STREQUAL "EMUFSA1") + add_library(vm_${EXE_NAME} + rtcif.cpp + ${MSX_BASE_SRCS} ) + target_compile_definitions(vm_${EXE_NAME} PRIVATE -D_MSX_VDP_MESS) +elseif("${U_EXE_NAME}" STREQUAL "EMUHX20") + add_library(vm_${EXE_NAME} + psg_stereo.cpp + rtcif.cpp + ${MSX_BASE_SRCS} + ) + target_compile_definitions(vm_${EXE_NAME} PRIVATE -D_MSX_VDP_MESS) else() - add_library(vm_msx - joystick.cpp - kanjirom.cpp - keyboard.cpp - memory_ex.cpp - printer.cpp - scc.cpp - sound_cart.cpp - msx_ex.cpp - ) + # standard MSX1 + add_library(vm_${EXE_NAME} + ${MSX_BASE_SRCS} + ) endif() - diff --git a/source/src/vm/msx/joystick.h b/source/src/vm/msx/joystick.h index 878cf6d39..dc85189e5 100644 --- a/source/src/vm/msx/joystick.h +++ b/source/src/vm/msx/joystick.h @@ -30,7 +30,7 @@ class JOYSTICK : public DEVICE int select; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/msx/kanjirom.cpp b/source/src/vm/msx/kanjirom.cpp index 9c7ed7fb8..b5614c784 100644 --- a/source/src/vm/msx/kanjirom.cpp +++ b/source/src/vm/msx/kanjirom.cpp @@ -14,7 +14,7 @@ namespace MSX { -KANJIROM::KANJIROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) +KANJIROM::KANJIROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { index = 0; memset(rom, 0xff, sizeof(rom)); diff --git a/source/src/vm/msx/kanjirom.h b/source/src/vm/msx/kanjirom.h index a6af7dbfc..e469a5adc 100644 --- a/source/src/vm/msx/kanjirom.h +++ b/source/src/vm/msx/kanjirom.h @@ -25,7 +25,7 @@ class KANJIROM : public DEVICE int index; public: - KANJIROM(VM_TEMPLATE* parent_vm, EMU* parent_emu); + KANJIROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~KANJIROM() {} // common functions diff --git a/source/src/vm/msx/keyboard.h b/source/src/vm/msx/keyboard.h index 0f1fe5566..482227001 100644 --- a/source/src/vm/msx/keyboard.h +++ b/source/src/vm/msx/keyboard.h @@ -35,7 +35,7 @@ class KEYBOARD : public DEVICE void update_keyboard(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/msx/memory.h b/source/src/vm/msx/memory.h index b68ab1450..7b3b7beca 100644 --- a/source/src/vm/msx/memory.h +++ b/source/src/vm/msx/memory.h @@ -45,7 +45,7 @@ class SLOT0 : public DEVICE uint8_t ram[0x8000]; #endif public: - SLOT0(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT0(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Slot #0")); } @@ -74,7 +74,7 @@ class SLOT1 : public DEVICE #endif public: - SLOT1(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT1(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Slot #1")); } @@ -116,7 +116,7 @@ class SLOT2 : public DEVICE bool pc4, mute_l, mute_r; public: - SLOT2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Slot #2")); } @@ -128,7 +128,7 @@ class SLOT2 : public DEVICE void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions @@ -156,7 +156,7 @@ class SLOT2 : public DEVICE uint8_t rom[0x8000]; public: - SLOT2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Slot #2")); } @@ -184,7 +184,7 @@ class SLOT3 : public DEVICE uint8_t mapper[4]; public: - SLOT3(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT3(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Slot #3")); } @@ -221,7 +221,7 @@ class MSX_MEMORY : public DEVICE void update_map(uint32_t val); public: - MSX_MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MSX_MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/msx/memory_ex.cpp b/source/src/vm/msx/memory_ex.cpp index f88427ad5..4f95cb765 100644 --- a/source/src/vm/msx/memory_ex.cpp +++ b/source/src/vm/msx/memory_ex.cpp @@ -456,14 +456,14 @@ bool SLOT_CART::process_state(FILEIO* state_fio, bool loading) } } else { if(inserted) { - state_fio->FputInt32_LE(rbank[0]==rdmy ? (-1) : rbank[0] - rom); - state_fio->FputInt32_LE(rbank[1]==rdmy ? (-1) : rbank[1] - rom); - state_fio->FputInt32_LE(rbank[2]==rdmy ? (-1) : rbank[2] - rom); - state_fio->FputInt32_LE(rbank[3]==rdmy ? (-1) : rbank[3] - rom); - state_fio->FputInt32_LE(rbank[4]==rdmy ? (-1) : rbank[4] - rom); - state_fio->FputInt32_LE(rbank[5]==rdmy ? (-1) : rbank[5] - rom); - state_fio->FputInt32_LE(rbank[6]==rdmy ? (-1) : rbank[6] - rom); - state_fio->FputInt32_LE(rbank[7]==rdmy ? (-1) : rbank[7] - rom); + state_fio->FputInt32_LE(rbank[0]==rdmy ? (-1) : (int)(rbank[0] - rom)); + state_fio->FputInt32_LE(rbank[1]==rdmy ? (-1) : (int)(rbank[1] - rom)); + state_fio->FputInt32_LE(rbank[2]==rdmy ? (-1) : (int)(rbank[2] - rom)); + state_fio->FputInt32_LE(rbank[3]==rdmy ? (-1) : (int)(rbank[3] - rom)); + state_fio->FputInt32_LE(rbank[4]==rdmy ? (-1) : (int)(rbank[4] - rom)); + state_fio->FputInt32_LE(rbank[5]==rdmy ? (-1) : (int)(rbank[5] - rom)); + state_fio->FputInt32_LE(rbank[6]==rdmy ? (-1) : (int)(rbank[6] - rom)); + state_fio->FputInt32_LE(rbank[7]==rdmy ? (-1) : (int)(rbank[7] - rom)); } } #else diff --git a/source/src/vm/msx/memory_ex.h b/source/src/vm/msx/memory_ex.h index 2109de38a..01e7f39e0 100644 --- a/source/src/vm/msx/memory_ex.h +++ b/source/src/vm/msx/memory_ex.h @@ -50,7 +50,7 @@ class SLOT_MAINROM : public DEVICE uint8_t ram[0x8000]; #endif public: - SLOT_MAINROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_MAINROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Main ROM")); } @@ -85,7 +85,7 @@ class SLOT_CART : public DEVICE bool inserted; public: - SLOT_CART(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_CART(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { #ifdef USE_MEGAROM event_register_id = -1; @@ -100,7 +100,7 @@ class SLOT_CART : public DEVICE uint32_t __FASTCALL read_data8(uint32_t addr); bool process_state(FILEIO* state_fio, bool loading); #ifdef USE_MEGAROM - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); int event_register_id; #endif @@ -134,7 +134,7 @@ class SLOT_MSXDOS2 : public DEVICE uint8_t mapper[2]; public: - SLOT_MSXDOS2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_MSXDOS2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MSX-DOS2")); } @@ -169,7 +169,7 @@ class SLOT_LDC : public DEVICE bool pc4, mute_l, mute_r; public: - SLOT_LDC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_LDC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("LDC Control")); } @@ -181,7 +181,7 @@ class SLOT_LDC : public DEVICE void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions @@ -217,7 +217,7 @@ class SLOT_SUBROM : public DEVICE #endif public: - SLOT_SUBROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_SUBROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Sub ROM")); } @@ -243,7 +243,7 @@ class SLOT_FDD_PATCH : public DEVICE uint8_t rom[0x4000]; public: - SLOT_FDD_PATCH(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_FDD_PATCH(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("FDD I/F")); } @@ -270,7 +270,7 @@ class SLOT_MAPPERRAM : public DEVICE uint8_t mapper[4]; public: - SLOT_MAPPERRAM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_MAPPERRAM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Mapper RAM")); } @@ -294,7 +294,7 @@ class SLOT_RAM64K : public DEVICE uint8_t ram[0x10000]; public: - SLOT_RAM64K(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_RAM64K(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RAM 64KB")); } @@ -322,7 +322,7 @@ class SLOT_FIRMWARE32K : public DEVICE const _TCHAR* m_filename; public: - SLOT_FIRMWARE32K(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_FIRMWARE32K(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Firmware 32KB")); } @@ -354,7 +354,7 @@ class SLOT_MSXMUSIC : public DEVICE uint8_t rom[0x4000]; public: - SLOT_MSXMUSIC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SLOT_MSXMUSIC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MSX-MUSIC")); } @@ -392,7 +392,7 @@ class MEMORY_EX : public DEVICE void update_map(uint32_t val); public: - MEMORY_EX(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY_EX(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { ssl[0] = ssl[1] = ssl[2] = ssl[3] = 0; expanded[0] = expanded[1] = expanded[2] = expanded[3] = false; diff --git a/source/src/vm/msx/msx.cpp b/source/src/vm/msx/msx.cpp index 47d34a92b..761332553 100644 --- a/source/src/vm/msx/msx.cpp +++ b/source/src/vm/msx/msx.cpp @@ -62,7 +62,7 @@ using MSX::SLOT3; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -487,6 +487,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 5 void VM::save_state(FILEIO* state_fio) @@ -521,7 +533,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/msx/msx.h b/source/src/vm/msx/msx.h index caa1c3023..51b5d8bb5 100644 --- a/source/src/vm/msx/msx.h +++ b/source/src/vm/msx/msx.h @@ -163,7 +163,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -230,6 +230,9 @@ class VM : public VM_TEMPLATE #endif bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/msx/msx_ex.cpp b/source/src/vm/msx/msx_ex.cpp index a032dee8c..5dc1824d4 100644 --- a/source/src/vm/msx/msx_ex.cpp +++ b/source/src/vm/msx/msx_ex.cpp @@ -119,7 +119,7 @@ class PORT_F4 : public DEVICE uint8_t port; public: - PORT_F4(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + PORT_F4(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { port = 0; } ~PORT_F4() {} @@ -141,7 +141,7 @@ class PORT_F4 : public DEVICE // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -705,6 +705,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 6 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -717,7 +729,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/msx/msx_ex.h b/source/src/vm/msx/msx_ex.h index 85032bef4..57140dd27 100644 --- a/source/src/vm/msx/msx_ex.h +++ b/source/src/vm/msx/msx_ex.h @@ -359,7 +359,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -427,6 +427,9 @@ class VM : public VM_TEMPLATE #endif bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/msx/printer.h b/source/src/vm/msx/printer.h index 7d4588d6b..164846ffc 100644 --- a/source/src/vm/msx/printer.h +++ b/source/src/vm/msx/printer.h @@ -22,7 +22,7 @@ class PRINTER : public DEVICE DEVICE* d_prn; public: - PRINTER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PRINTER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Printer I/F")); } diff --git a/source/src/vm/msx/psg_stereo.cpp b/source/src/vm/msx/psg_stereo.cpp index 6fe825861..64eef4248 100644 --- a/source/src/vm/msx/psg_stereo.cpp +++ b/source/src/vm/msx/psg_stereo.cpp @@ -18,7 +18,7 @@ namespace MSX { -PSG_STEREO::PSG_STEREO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) +PSG_STEREO::PSG_STEREO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { #if defined(USE_PSG_STEREO_REALLY) // d_psg[1] = new YM2203(parent_vm, parent_emu); diff --git a/source/src/vm/msx/psg_stereo.h b/source/src/vm/msx/psg_stereo.h index 047a65619..37f106ca0 100644 --- a/source/src/vm/msx/psg_stereo.h +++ b/source/src/vm/msx/psg_stereo.h @@ -33,7 +33,7 @@ class PSG_STEREO : public DEVICE int m_decibel_r; public: - PSG_STEREO(VM_TEMPLATE* parent_vm, EMU* parent_emu); + PSG_STEREO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~PSG_STEREO() {} // common functions @@ -42,7 +42,7 @@ class PSG_STEREO : public DEVICE void initialize(); void release(); void reset(); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); void update_config(); diff --git a/source/src/vm/msx/rtcif.h b/source/src/vm/msx/rtcif.h index 7defc95b5..917820b4c 100644 --- a/source/src/vm/msx/rtcif.h +++ b/source/src/vm/msx/rtcif.h @@ -25,7 +25,7 @@ class RTCIF : public DEVICE uint8_t adrs; public: - RTCIF(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RTCIF(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RTC I/F")); } diff --git a/source/src/vm/msx/scc.cpp b/source/src/vm/msx/scc.cpp index 90eff778b..91e51ecb1 100644 --- a/source/src/vm/msx/scc.cpp +++ b/source/src/vm/msx/scc.cpp @@ -503,7 +503,7 @@ SCC_set_type (SCC * scc, uint32_t type) */ -SCC::SCC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) +SCC::SCC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { emu2212 = SCC_new(3579545, 48000); volume_l = volume_r = 1024; diff --git a/source/src/vm/msx/scc.h b/source/src/vm/msx/scc.h index 047975a1f..f282af029 100644 --- a/source/src/vm/msx/scc.h +++ b/source/src/vm/msx/scc.h @@ -85,7 +85,7 @@ class SCC : public DEVICE void save_load_state(FILEIO* state_fio, bool is_save); public: - SCC(VM_TEMPLATE* parent_vm, EMU* parent_emu); + SCC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~SCC() {} // common functions @@ -94,7 +94,7 @@ class SCC : public DEVICE void initialize(); void release(); void reset(); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/msx/sound_cart.cpp b/source/src/vm/msx/sound_cart.cpp index c6de080a5..8e2fb16db 100644 --- a/source/src/vm/msx/sound_cart.cpp +++ b/source/src/vm/msx/sound_cart.cpp @@ -12,7 +12,7 @@ namespace MSX { -SOUND_CART::SOUND_CART(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) +SOUND_CART::SOUND_CART(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_chip[SOUND_CHIP_SCC] = new SCC(parent_vm, parent_emu); enable_chip[SOUND_CHIP_SCC] = false; diff --git a/source/src/vm/msx/sound_cart.h b/source/src/vm/msx/sound_cart.h index cb9074a9d..3fa3a52b4 100644 --- a/source/src/vm/msx/sound_cart.h +++ b/source/src/vm/msx/sound_cart.h @@ -29,14 +29,14 @@ class SOUND_CART : public DEVICE bool enable_chip[SOUND_CHIP_MAX+1]; public: - SOUND_CART(VM_TEMPLATE* parent_vm, EMU* parent_emu); + SOUND_CART(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); ~SOUND_CART() {} // common functions void initialize(); void release(); void reset(); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); // unique functions diff --git a/source/src/vm/multi8/CMakeLists.txt b/source/src/vm/multi8/CMakeLists.txt index eb7a1d9d9..690cc2c18 100644 --- a/source/src/vm/multi8/CMakeLists.txt +++ b/source/src/vm/multi8/CMakeLists.txt @@ -1,13 +1,15 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/multi8") +message("* vm/emumulti8") + +add_library(vm_emumulti8 -add_library(vm_multi8 - multi8.cpp cmt.cpp display.cpp floppy.cpp kanji.cpp keyboard.cpp - memory.cpp - ) \ No newline at end of file + ./memory.cpp + + multi8.cpp +) diff --git a/source/src/vm/multi8/cmt.h b/source/src/vm/multi8/cmt.h index 9b6b7ae57..79c32debf 100644 --- a/source/src/vm/multi8/cmt.h +++ b/source/src/vm/multi8/cmt.h @@ -36,7 +36,7 @@ class CMT : public DEVICE void release_tape(); public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } diff --git a/source/src/vm/multi8/display.h b/source/src/vm/multi8/display.h index 66e29207f..b04c0ba1d 100644 --- a/source/src/vm/multi8/display.h +++ b/source/src/vm/multi8/display.h @@ -43,7 +43,7 @@ class DISPLAY : public DEVICE void draw_text_normal(); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/multi8/floppy.h b/source/src/vm/multi8/floppy.h index 1883c8bfc..1b29b48dd 100644 --- a/source/src/vm/multi8/floppy.h +++ b/source/src/vm/multi8/floppy.h @@ -25,7 +25,7 @@ class FLOPPY : public DEVICE bool drq; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/multi8/kanji.h b/source/src/vm/multi8/kanji.h index 8cd7dbd7b..75f8fdf18 100644 --- a/source/src/vm/multi8/kanji.h +++ b/source/src/vm/multi8/kanji.h @@ -25,7 +25,7 @@ class KANJI : public DEVICE uint32_t ptr; public: - KANJI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KANJI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Kanji ROM")); } diff --git a/source/src/vm/multi8/keyboard.h b/source/src/vm/multi8/keyboard.h index ea9d98f16..e8e04348a 100644 --- a/source/src/vm/multi8/keyboard.h +++ b/source/src/vm/multi8/keyboard.h @@ -27,7 +27,7 @@ class KEYBOARD : public DEVICE const uint8_t* key_stat; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/multi8/memory.h b/source/src/vm/multi8/memory.h index 411ea2474..3a6c2e725 100644 --- a/source/src/vm/multi8/memory.h +++ b/source/src/vm/multi8/memory.h @@ -38,7 +38,7 @@ class MEMORY : public DEVICE uint8_t map1, map2; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/multi8/multi8.cpp b/source/src/vm/multi8/multi8.cpp index e1cf1c1f3..97497073b 100644 --- a/source/src/vm/multi8/multi8.cpp +++ b/source/src/vm/multi8/multi8.cpp @@ -48,7 +48,7 @@ using MULTI8::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -334,6 +334,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 5 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -346,7 +358,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/multi8/multi8.h b/source/src/vm/multi8/multi8.h index f6c7b1620..7692e78e2 100644 --- a/source/src/vm/multi8/multi8.h +++ b/source/src/vm/multi8/multi8.h @@ -33,7 +33,6 @@ #define TAPE_BINARY_ONLY #define USE_FLOPPY_DISK 2 #define USE_KEY_LOCKED -#define USE_SHIFT_NUMPAD_KEY #define USE_ALT_F10_KEY #define USE_AUTO_KEY 5 #define USE_AUTO_KEY_RELEASE 6 @@ -114,7 +113,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -159,6 +158,9 @@ class VM : public VM_TEMPLATE bool is_tape_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mycomz80a/CMakeLists.txt b/source/src/vm/mycomz80a/CMakeLists.txt index 314ad924a..dbaa85ba6 100644 --- a/source/src/vm/mycomz80a/CMakeLists.txt +++ b/source/src/vm/mycomz80a/CMakeLists.txt @@ -1,16 +1,18 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/mycomz80a") +message("* vm/emumycomz80a") set(VM_MYCOMZ80A_LIB_SRCS + ../msm5832.cpp + display.cpp keyboard.cpp - memory.cpp + ./memory.cpp mycomz80a.cpp ) -add_library(vm_mycomz80a +add_library(vm_emumycomz80a ${VM_MYCOMZ80A_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/mycomz80a/display.h b/source/src/vm/mycomz80a/display.h index b89c50d6f..67365d608 100644 --- a/source/src/vm/mycomz80a/display.h +++ b/source/src/vm/mycomz80a/display.h @@ -39,7 +39,7 @@ class DISPLAY : public DEVICE void draw_80column(); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/mycomz80a/keyboard.h b/source/src/vm/mycomz80a/keyboard.h index ed41dee92..751b2e994 100644 --- a/source/src/vm/mycomz80a/keyboard.h +++ b/source/src/vm/mycomz80a/keyboard.h @@ -30,7 +30,7 @@ class KEYBOARD : public DEVICE int event_cnt; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/mycomz80a/memory.h b/source/src/vm/mycomz80a/memory.h index d4f361178..8c247ed74 100644 --- a/source/src/vm/mycomz80a/memory.h +++ b/source/src/vm/mycomz80a/memory.h @@ -33,7 +33,7 @@ class MEMORY : public DEVICE void update_memory_map(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/mycomz80a/mycomz80a.cpp b/source/src/vm/mycomz80a/mycomz80a.cpp index 973cdc71d..c0217e8cd 100644 --- a/source/src/vm/mycomz80a/mycomz80a.cpp +++ b/source/src/vm/mycomz80a/mycomz80a.cpp @@ -37,7 +37,7 @@ using MYCOMZ80A::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -382,6 +382,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -394,7 +406,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mycomz80a/mycomz80a.h b/source/src/vm/mycomz80a/mycomz80a.h index 6dfdd3e3b..b53bf93a6 100644 --- a/source/src/vm/mycomz80a/mycomz80a.h +++ b/source/src/vm/mycomz80a/mycomz80a.h @@ -95,7 +95,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -146,6 +146,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz1p17.h b/source/src/vm/mz1p17.h index 6a0c59c8f..58c9d847e 100644 --- a/source/src/vm/mz1p17.h +++ b/source/src/vm/mz1p17.h @@ -16,7 +16,7 @@ #define _MZ1P17_H_ #include "vm.h" -#include "../emu.h" +//#include "../emu.h" #include "device.h" #define MZ1P17_MODE_MZ1 0 @@ -94,7 +94,7 @@ class MZ1P17 : public DEVICE void finish_paper(); public: - MZ1P17(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ1P17(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_busy); initialize_output_signals(&outputs_ack); @@ -109,7 +109,7 @@ class MZ1P17 : public DEVICE void event_frame(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/mz2500/CMakeLists.txt b/source/src/vm/mz2500/CMakeLists.txt index abd0853b7..22df9e0d8 100644 --- a/source/src/vm/mz2500/CMakeLists.txt +++ b/source/src/vm/mz2500/CMakeLists.txt @@ -1,8 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/mz2500") +message("* vm/${EXE_NAME}") set(MZ2500_SRCS + ../mz1p17.cpp + calendar.cpp cmt.cpp floppy.cpp @@ -23,6 +25,8 @@ set(MZ2500_SRCS ) set(MZ80B_SRCS + ../mz1p17.cpp + cmt.cpp floppy.cpp keyboard.cpp @@ -35,19 +39,28 @@ set(MZ80B_SRCS serial.cpp timer.cpp ) +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) -if(BUILD_MZ2500) - -add_library(vm_mz2500 ${MZ2500_SRCS}) - -elseif(BUILD_MZ80B) - -add_library(vm_mz2500 ${MZ80B_SRCS}) - -elseif(BUILD_MZ2000) -add_library(vm_mz2500 ${MZ80B_SRCS} mz1m01.cpp) - -elseif(BUILD_MZ2200) -add_library(vm_mz2500 ${MZ80B_SRCS} mz1m01.cpp) - +if("${U_EXE_NAME}" STREQUAL "EMUMZ2500") + add_library(vm_${EXE_NAME} + ../scsi_host.cpp + ../w3100a.cpp + ${MZ2500_SRCS} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUMZ80B") + add_library(vm_${EXE_NAME} + ${MZ80B_SRCS} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUMZ2000") + add_library(vm_${EXE_NAME} + ../mz700/quickdisk.cpp + mz1m01.cpp + ${MZ80B_SRCS} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUMZ2200") + add_library(vm_${EXE_NAME} + ../mz700/quickdisk.cpp + mz1m01.cpp + ${MZ80B_SRCS} + ) endif() diff --git a/source/src/vm/mz2500/calendar.h b/source/src/vm/mz2500/calendar.h index b952fff96..aff9e7dab 100644 --- a/source/src/vm/mz2500/calendar.h +++ b/source/src/vm/mz2500/calendar.h @@ -22,7 +22,7 @@ class CALENDAR : public DEVICE DEVICE* d_rtc; public: - CALENDAR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CALENDAR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RTC I/F")); } diff --git a/source/src/vm/mz2500/cmt.cpp b/source/src/vm/mz2500/cmt.cpp index e95602f85..29d769531 100644 --- a/source/src/vm/mz2500/cmt.cpp +++ b/source/src/vm/mz2500/cmt.cpp @@ -182,7 +182,7 @@ void CMT::write_signal(int id, uint32_t data, uint32_t mask) pa = data; } else if(id == SIG_CMT_PIO_PC) { if(!(pc & 2) && (data & 2)) { - vm->special_reset(); + vm->special_reset(0); } #ifdef _MZ2500 if(!(pc & 8) && (data & 8)) { diff --git a/source/src/vm/mz2500/cmt.h b/source/src/vm/mz2500/cmt.h index d0351766b..cef773c11 100644 --- a/source/src/vm/mz2500/cmt.h +++ b/source/src/vm/mz2500/cmt.h @@ -54,7 +54,7 @@ class CMT : public DEVICE void stop(); public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } @@ -64,7 +64,7 @@ class CMT : public DEVICE void initialize(); void reset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique function diff --git a/source/src/vm/mz2500/crtc.cpp b/source/src/vm/mz2500/crtc.cpp index 6047ed381..a6252e60e 100644 --- a/source/src/vm/mz2500/crtc.cpp +++ b/source/src/vm/mz2500/crtc.cpp @@ -966,10 +966,10 @@ void CRTC::draw_40column_screen() uint32_t dest = 640 * y; uint8_t col; for(int x = 0; x < 640; x++) { - if((text[src1] & 8) && (text[src2] & 8)) { + // thanks Mr.Koucha-Youkan + col = (((text[src1] & 7) << 3) | (text[src2] & 7)) + 16; + if(col == 16 && ((text[src1] & 8) && (text[src2] & 8))) { col = 8; // non transparent black - } else { - col = (((text[src1] & 7) << 3) | (text[src2] & 7)) + 16; } text[dest++] = col; src1++; @@ -1626,7 +1626,7 @@ void CRTC::draw_640x200x16screen(uint8_t pl) create_addr_map(80, 200); } ex = (cgreg[0x0e] & 0x80) << 7; - subplane = (pl & 1) ? 0x2000 : 0x0000; + subplane = (pl & 1) ? 0x4000 : 0x0000; // thanks Mr.856 for(int y = 0; y < 200; y++) { for(int x = 0; x < 80; x++) { uint16_t src = (map_addr[y][x] ^ subplane) | ex; diff --git a/source/src/vm/mz2500/crtc.h b/source/src/vm/mz2500/crtc.h index dde940c4e..410a39d2c 100644 --- a/source/src/vm/mz2500/crtc.h +++ b/source/src/vm/mz2500/crtc.h @@ -41,7 +41,7 @@ class CRTC : public DEVICE uint8_t *pcg0, *pcg1, *pcg2, *pcg3; // crtc - void set_hsync(int h); + void __FASTCALL set_hsync(int h); uint8_t textreg_num, textreg[16]; uint8_t cgreg_num, cgreg[32]; uint8_t scrn_size, cg_mask, cg_mask256; @@ -77,18 +77,18 @@ class CRTC : public DEVICE void draw_text(); void draw_80column_screen(); void draw_40column_screen(); - void draw_80column_font(uint16_t src, int dest, int y); - void draw_40column_font(uint16_t src, int dest, int y); + void __FASTCALL draw_80column_font(uint16_t src, int dest, int y); + void __FASTCALL draw_40column_font(uint16_t src, int dest, int y); uint8_t text[640*480*2]; // draw cg void draw_cg(); - void draw_320x200x16screen(uint8_t pl); - void draw_320x200x256screen(int ymax); - void draw_640x200x16screen(uint8_t pl); + void __FASTCALL draw_320x200x16screen(uint8_t pl); + void __FASTCALL draw_320x200x256screen(int ymax); + void __FASTCALL draw_640x200x16screen(uint8_t pl); void draw_640x400x4screen(); void draw_640x400x16screen(); - void create_addr_map(int xmax, int ymax); + void __FASTCALL create_addr_map(int xmax, int ymax); uint8_t cg[640*400*2]; uint16_t map_addr[400][80]; uint8_t map_hdsc[400][80]; @@ -105,7 +105,7 @@ class CRTC : public DEVICE bool map_init, trans_init; public: - CRTC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CRTC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CRTC")); } @@ -118,7 +118,7 @@ class CRTC : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_vline(int v, int clock); void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz2500/floppy.h b/source/src/vm/mz2500/floppy.h index 75e7bdea6..939b7b573 100644 --- a/source/src/vm/mz2500/floppy.h +++ b/source/src/vm/mz2500/floppy.h @@ -29,7 +29,7 @@ class FLOPPY : public DEVICE #endif public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/mz2500/interrupt.h b/source/src/vm/mz2500/interrupt.h index 15e9a8a8d..f4e7caf01 100644 --- a/source/src/vm/mz2500/interrupt.h +++ b/source/src/vm/mz2500/interrupt.h @@ -42,7 +42,7 @@ class INTERRUPT : public DEVICE void update_intr(); public: - INTERRUPT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + INTERRUPT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_cpu = d_child = NULL; set_device_name(_T("Interrupt")); @@ -65,7 +65,7 @@ class INTERRUPT : public DEVICE { d_child = device; } - void set_intr_iei(bool val); + void __FASTCALL set_intr_iei(bool val); uint32_t get_intr_ack(); void notify_intr_reti(); }; diff --git a/source/src/vm/mz2500/joystick.h b/source/src/vm/mz2500/joystick.h index 7ff62ed4a..6d0733321 100644 --- a/source/src/vm/mz2500/joystick.h +++ b/source/src/vm/mz2500/joystick.h @@ -22,7 +22,7 @@ class JOYSTICK : public DEVICE uint32_t mode; const uint32_t* joy_stat; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/mz2500/keyboard.h b/source/src/vm/mz2500/keyboard.h index c8229fc97..92b06e237 100644 --- a/source/src/vm/mz2500/keyboard.h +++ b/source/src/vm/mz2500/keyboard.h @@ -32,7 +32,7 @@ class KEYBOARD : public DEVICE void create_keystat(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/mz2500/memory.cpp b/source/src/vm/mz2500/memory.cpp index b172ba7c0..10fae5a2f 100644 --- a/source/src/vm/mz2500/memory.cpp +++ b/source/src/vm/mz2500/memory.cpp @@ -87,7 +87,7 @@ void MEMORY::reset() extra_wait = 0; } -void MEMORY::special_reset() +void MEMORY::special_reset(int num) { // reset bank = 0; diff --git a/source/src/vm/mz2500/memory.h b/source/src/vm/mz2500/memory.h index 95b8c8112..771f8d704 100644 --- a/source/src/vm/mz2500/memory.h +++ b/source/src/vm/mz2500/memory.h @@ -52,7 +52,7 @@ class MEMORY : public DEVICE void __FASTCALL set_map(uint8_t data); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus(MZ2500)")); } @@ -61,7 +61,7 @@ class MEMORY : public DEVICE // common functions void initialize(); void reset(); - void special_reset(); + void special_reset(int num); void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait); diff --git a/source/src/vm/mz2500/memory80b.cpp b/source/src/vm/mz2500/memory80b.cpp index a1645addc..4b53395fe 100644 --- a/source/src/vm/mz2500/memory80b.cpp +++ b/source/src/vm/mz2500/memory80b.cpp @@ -107,7 +107,7 @@ void MEMORY::reset() update_vram_map(); } -void MEMORY::special_reset() +void MEMORY::special_reset(int num) { // reset SET_BANK(0x0000, 0xffff, ram, ram, false); @@ -294,7 +294,7 @@ void MEMORY::load_dat_image(const _TCHAR* file_path) fio->Fread(ram, sizeof(ram), 1); fio->Fclose(); - vm->special_reset(); + vm->special_reset(0); } delete fio; } @@ -319,7 +319,7 @@ bool MEMORY::load_mzt_image(const _TCHAR* file_path) memset(tvram, 0, sizeof(tvram)); fio->Fread(ram, size, 1); - vm->special_reset(); + vm->special_reset(0); result = true; } fio->Fclose(); diff --git a/source/src/vm/mz2500/memory80b.h b/source/src/vm/mz2500/memory80b.h index f2f6422f5..098f6091a 100644 --- a/source/src/vm/mz2500/memory80b.h +++ b/source/src/vm/mz2500/memory80b.h @@ -83,7 +83,7 @@ class MEMORY : public DEVICE #endif public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus(MZ80B/2000/2200)")); } @@ -92,14 +92,14 @@ class MEMORY : public DEVICE // common functions void initialize(); void reset(); - void special_reset(); + void special_reset(int num); void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); uint32_t __FASTCALL fetch_op(uint32_t addr, int *wait); void __FASTCALL write_io8(uint32_t addr, uint32_t data); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique function diff --git a/source/src/vm/mz2500/mouse.h b/source/src/vm/mz2500/mouse.h index 443ab56f2..010b4bfa2 100644 --- a/source/src/vm/mz2500/mouse.h +++ b/source/src/vm/mz2500/mouse.h @@ -29,7 +29,7 @@ class MOUSE : public DEVICE bool select; public: - MOUSE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MOUSE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Mouse I/F")); } diff --git a/source/src/vm/mz2500/mz1e26.h b/source/src/vm/mz2500/mz1e26.h index 2618f8872..a28666421 100644 --- a/source/src/vm/mz2500/mz1e26.h +++ b/source/src/vm/mz2500/mz1e26.h @@ -22,7 +22,7 @@ class MZ1E26 : public DEVICE // uint8_t prev_data; public: - MZ1E26(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ1E26(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-1E26 (Voice Communication I/F)")); } diff --git a/source/src/vm/mz2500/mz1e30.h b/source/src/vm/mz2500/mz1e30.h index df76eb02b..6bc8b7f55 100644 --- a/source/src/vm/mz2500/mz1e30.h +++ b/source/src/vm/mz2500/mz1e30.h @@ -33,7 +33,7 @@ class MZ1E30 : public DEVICE bool drq_status; public: - MZ1E30(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ1E30(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-1E30 (SASI I/F)")); } diff --git a/source/src/vm/mz2500/mz1m01.h b/source/src/vm/mz2500/mz1m01.h index 0b72be75d..4bdd7f24c 100644 --- a/source/src/vm/mz2500/mz1m01.h +++ b/source/src/vm/mz2500/mz1m01.h @@ -35,7 +35,7 @@ class MZ1M01 : public DEVICE uint8_t port[2]; public: - MZ1M01(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ1M01(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-1M01 (16bit CPU Board)")); } diff --git a/source/src/vm/mz2500/mz1r12.h b/source/src/vm/mz2500/mz1r12.h index 88a395489..786f4ae79 100644 --- a/source/src/vm/mz2500/mz1r12.h +++ b/source/src/vm/mz2500/mz1r12.h @@ -26,7 +26,7 @@ class MZ1R12 : public DEVICE uint32_t crc32; public: - MZ1R12(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ1R12(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-1R12 (32KB SRAM)")); } diff --git a/source/src/vm/mz2500/mz1r13.h b/source/src/vm/mz2500/mz1r13.h index af1378326..01e33c651 100644 --- a/source/src/vm/mz2500/mz1r13.h +++ b/source/src/vm/mz2500/mz1r13.h @@ -28,7 +28,7 @@ class MZ1R13 : public DEVICE bool select_kanji; public: - MZ1R13(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ1R13(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-1R13 (KANJI ROM)")); } diff --git a/source/src/vm/mz2500/mz1r37.h b/source/src/vm/mz2500/mz1r37.h index 1c4ae6d29..d6eb16d4d 100644 --- a/source/src/vm/mz2500/mz1r37.h +++ b/source/src/vm/mz2500/mz1r37.h @@ -23,7 +23,7 @@ class MZ1R37 : public DEVICE uint32_t address; int tmp_buffer_size; public: - MZ1R37(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ1R37(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-1R37 (640KB EMM)")); } diff --git a/source/src/vm/mz2500/mz2500.cpp b/source/src/vm/mz2500/mz2500.cpp index 5a4e85219..c9d9de137 100644 --- a/source/src/vm/mz2500/mz2500.cpp +++ b/source/src/vm/mz2500/mz2500.cpp @@ -75,7 +75,7 @@ using MZ2500::TIMER; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -106,7 +106,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) sasi_hdd = new SASI_HDD(this, emu); sasi_hdd->set_device_name(_T("SASI Hard Disk Drive")); sasi_hdd->scsi_id = 0; - sasi_hdd->bytes_per_sec = 32 * 1024; // 32KB/s +// sasi_hdd->bytes_per_sec = 32 * 1024; // 32KB/s + sasi_hdd->bytes_per_sec = 3600 / 60 * 256 * 33; // 3600rpm, 256bytes x 33sectors in track (thanks Mr.Sato) for(int i = 0; i < USE_HARD_DISK; i++) { sasi_hdd->set_disk_handler(i, new HARDDISK(emu)); } @@ -319,13 +320,13 @@ void VM::reset() opn->write_signal(SIG_YM2203_PORT_B, (monitor_type & 2) ? 0x77 : 0x37, 0xff); } -void VM::special_reset() +void VM::special_reset(int num) { // reset all devices // for(DEVICE* device = first_device; device; device = device->next_device) { // device->special_reset(); // } - memory->special_reset(); + memory->special_reset(num); cpu->reset(); } @@ -626,6 +627,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 8 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -638,7 +651,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mz2500/mz2500.h b/source/src/vm/mz2500/mz2500.h index cc2c07223..5eec48347 100644 --- a/source/src/vm/mz2500/mz2500.h +++ b/source/src/vm/mz2500/mz2500.h @@ -36,7 +36,7 @@ #define Z80_IO_WAIT // device informations for win32 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_FLOPPY_DISK 4 #define USE_TAPE 1 #define USE_HARD_DISK 2 @@ -153,7 +153,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -162,7 +162,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -218,6 +218,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz2500/mz80b.cpp b/source/src/vm/mz2500/mz80b.cpp index b36fe791e..6cfb5bf39 100644 --- a/source/src/vm/mz2500/mz80b.cpp +++ b/source/src/vm/mz2500/mz80b.cpp @@ -69,7 +69,7 @@ using MZ80B::MZ1M01; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -117,7 +117,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #ifdef SUPPORT_16BIT_BOARD pio_to16 = new Z80PIO(this, emu); - cpu_16 = new I8086(this, emu); // 8088 + cpu_16 = new I86(this, emu); // 8088 + cpu_16->device_model = INTEL_8088; pic_16 = new I8259(this, emu); mz1m01 = new MZ1M01(this, emu); pio_to16->set_device_name(_T("Z80 PIO(16BIT BOARD)")); @@ -321,13 +322,13 @@ void VM::reset() } } -void VM::special_reset() +void VM::special_reset(int num) { // reset all devices // for(DEVICE* device = first_device; device; device = device->next_device) { -// device->special_reset(); +// device->special_reset(num); // } - memory->special_reset(); + memory->special_reset(num); cpu->reset(); #ifdef SUPPORT_16BIT_BOARD pio_to16->reset(); @@ -593,7 +594,19 @@ void VM::update_config() } } -#define STATE_VERSION 4 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 5 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -605,7 +618,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mz2500/mz80b.h b/source/src/vm/mz2500/mz80b.h index bbb8cb977..90583450a 100644 --- a/source/src/vm/mz2500/mz80b.h +++ b/source/src/vm/mz2500/mz80b.h @@ -40,7 +40,6 @@ #ifdef SUPPORT_QUICK_DISK #endif #ifdef SUPPORT_16BIT_BOARD -#define HAS_I88 #define I8259_MAX_CHIPS 1 #endif #define PRINTER_STROBE_RISING_EDGE @@ -50,7 +49,7 @@ #define Z80_IO_WAIT // device informations for win32 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_CPU_TYPE 2 #define USE_FLOPPY_DISK 4 #ifdef SUPPORT_QUICK_DISK @@ -104,7 +103,7 @@ namespace MZ700 { } #endif #ifdef SUPPORT_16BIT_BOARD - class I8086; + class I86; class I8259; #endif namespace MZ2500 { @@ -157,7 +156,7 @@ class VM : public VM_TEMPLATE #ifdef SUPPORT_16BIT_BOARD Z80PIO* pio_to16; - I8086* cpu_16; + I86* cpu_16; I8259* pic_16; MZ80B::MZ1M01* mz1m01; #endif @@ -167,7 +166,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -176,7 +175,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate() { @@ -228,6 +227,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz2500/printer.h b/source/src/vm/mz2500/printer.h index 7b205072f..d31ba8bd9 100644 --- a/source/src/vm/mz2500/printer.h +++ b/source/src/vm/mz2500/printer.h @@ -24,7 +24,7 @@ class PRINTER : public DEVICE DEVICE* d_prn; public: - PRINTER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PRINTER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Printer I/F")); } diff --git a/source/src/vm/mz2500/serial.h b/source/src/vm/mz2500/serial.h index a73a4878b..9668b3c8d 100644 --- a/source/src/vm/mz2500/serial.h +++ b/source/src/vm/mz2500/serial.h @@ -25,7 +25,7 @@ class SERIAL : public DEVICE bool addr_a0; public: - SERIAL(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SERIAL(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Serial I/F")); } diff --git a/source/src/vm/mz2500/timer.h b/source/src/vm/mz2500/timer.h index 940281f33..2288a1da5 100644 --- a/source/src/vm/mz2500/timer.h +++ b/source/src/vm/mz2500/timer.h @@ -23,7 +23,7 @@ class TIMER : public DEVICE DEVICE* d_pit; public: - TIMER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TIMER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Timer I/F")); } diff --git a/source/src/vm/mz2800/CMakeLists.txt b/source/src/vm/mz2800/CMakeLists.txt index b02225824..81fe6a53a 100644 --- a/source/src/vm/mz2800/CMakeLists.txt +++ b/source/src/vm/mz2800/CMakeLists.txt @@ -1,21 +1,26 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/mz2800") +message("* vm/${EXE_NAME}") set(BASIC_VM_FILES - mz2800.cpp - crtc.cpp - floppy.cpp - joystick.cpp - keyboard.cpp - memory.cpp - mouse.cpp - reset.cpp - sasi.cpp - serial.cpp - sysport.cpp - printer.cpp - ) + + ../mz1p17.cpp + ../scsi_host.cpp + + crtc.cpp + floppy.cpp + joystick.cpp + keyboard.cpp + ./memory.cpp + mouse.cpp + reset.cpp + sasi.cpp + serial.cpp + sysport.cpp + printer.cpp + + mz2800.cpp +) -add_library(vm_mz2800 ${BASIC_VM_FILES}) +add_library(vm_emumz2800 ${BASIC_VM_FILES}) diff --git a/source/src/vm/mz2800/crtc.h b/source/src/vm/mz2800/crtc.h index 27342dad9..8336b07e7 100644 --- a/source/src/vm/mz2800/crtc.h +++ b/source/src/vm/mz2800/crtc.h @@ -84,7 +84,7 @@ class CRTC : public DEVICE bool map_init, trans_init; public: - CRTC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CRTC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CRTC")); } @@ -96,7 +96,7 @@ class CRTC : public DEVICE uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_io8(uint32_t addr, uint32_t data); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_vline(int v, int clock); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz2800/floppy.h b/source/src/vm/mz2800/floppy.h index 28ef90eb5..367c206b5 100644 --- a/source/src/vm/mz2800/floppy.h +++ b/source/src/vm/mz2800/floppy.h @@ -24,7 +24,7 @@ class FLOPPY : public DEVICE MB8877* d_fdc; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/mz2800/joystick.h b/source/src/vm/mz2800/joystick.h index 797cb4851..1f3476801 100644 --- a/source/src/vm/mz2800/joystick.h +++ b/source/src/vm/mz2800/joystick.h @@ -22,7 +22,7 @@ class JOYSTICK : public DEVICE uint32_t mode; const uint32_t* joy_stat; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/mz2800/keyboard.h b/source/src/vm/mz2800/keyboard.h index 34fb065a9..b158e3fd4 100644 --- a/source/src/vm/mz2800/keyboard.h +++ b/source/src/vm/mz2800/keyboard.h @@ -31,7 +31,7 @@ class KEYBOARD : public DEVICE void create_keystat(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/mz2800/memory.h b/source/src/vm/mz2800/memory.h index bb7ae6ef6..4427e3e54 100644 --- a/source/src/vm/mz2800/memory.h +++ b/source/src/vm/mz2800/memory.h @@ -38,7 +38,7 @@ class MEMORY : public DEVICE uint8_t vram_bank, dic_bank, kanji_bank; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/mz2800/mouse.h b/source/src/vm/mz2800/mouse.h index cf4d75d49..e48ce348a 100644 --- a/source/src/vm/mz2800/mouse.h +++ b/source/src/vm/mz2800/mouse.h @@ -29,7 +29,7 @@ class MOUSE : public DEVICE bool select; public: - MOUSE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MOUSE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Mouse I/F")); } diff --git a/source/src/vm/mz2800/mz2800.cpp b/source/src/vm/mz2800/mz2800.cpp index 4ea63b45f..279913904 100644 --- a/source/src/vm/mz2800/mz2800.cpp +++ b/source/src/vm/mz2800/mz2800.cpp @@ -66,7 +66,7 @@ using MZ2800::SYSPORT; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -74,7 +74,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) event = new EVENT(this, emu); // must be 2nd device dummy->set_device_name(_T("1st Dummy")); - cpu = new I80286(this, emu); + cpu = new I286(this, emu); pit = new I8253(this, emu); pio0 = new I8255(this, emu); pic = new I8259(this, emu); @@ -99,7 +99,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) sasi_hdd[i] = new SASI_HDD(this, emu); sasi_hdd[i]->set_device_name(_T("SASI Hard Disk Drive #%d"), i + 1); sasi_hdd[i]->scsi_id = i; - sasi_hdd[i]->bytes_per_sec = 32 * 1024; // 32KB/s +// sasi_hdd[i]->bytes_per_sec = 32 * 1024; // 32KB/s + sasi_hdd[i]->bytes_per_sec = 3600 / 60 * 1024 * 8; // 3600rpm, 1024bytes x 8sectors in track (thanks Mr.Sato) sasi_hdd[i]->set_context_interface(sasi_host); sasi_host->set_context_target(sasi_hdd[i]); } @@ -165,8 +166,9 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) dma->set_context_memory(memory); dma->set_context_ch0(sasi); dma->set_context_ch1(fdc); - dma->set_context_tc(pic, SIG_I8259_CHIP0 | SIG_I8259_IR3, 1); - dma->set_context_tc(sasi, SIG_SASI_TC, 1); + dma->set_context_tc0(pic, SIG_I8259_CHIP0 | SIG_I8259_IR3, 3); // OK? + dma->set_context_tc1(pic, SIG_I8259_CHIP0 | SIG_I8259_IR3, 3); // OK? + dma->set_context_tc0(sasi, SIG_SASI_TC, 1); opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR7, 1); opn->set_context_port_a(crtc, SIG_CRTC_PALLETE, 0x04, 0); opn->set_context_port_a(mouse, SIG_MOUSE_SEL, 0x08, 0); @@ -479,6 +481,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 8 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -491,7 +505,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mz2800/mz2800.h b/source/src/vm/mz2800/mz2800.h index 5ea352ecf..67ca33303 100644 --- a/source/src/vm/mz2800/mz2800.h +++ b/source/src/vm/mz2800/mz2800.h @@ -22,7 +22,6 @@ #define SCREEN_HEIGHT 400 #define WINDOW_HEIGHT_ASPECT 480 #define MAX_DRIVE 4 -#define HAS_I286 #define I8259_MAX_CHIPS 2 #define SINGLE_MODE_DMA #define HAS_RP5C15 @@ -62,7 +61,7 @@ class EVENT; class I8253; class I8255; class I8259; -class I80286; +class I286; class IO; class MB8877; class NOT; @@ -101,7 +100,7 @@ class VM : public VM_TEMPLATE I8253* pit; I8255* pio0; I8259* pic; - I80286* cpu; + I286* cpu; IO* io; MB8877* fdc; NOT* not_busy; @@ -131,7 +130,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -176,6 +175,9 @@ class VM : public VM_TEMPLATE uint32_t is_hard_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz2800/printer.h b/source/src/vm/mz2800/printer.h index 24a96f1e1..027afb772 100644 --- a/source/src/vm/mz2800/printer.h +++ b/source/src/vm/mz2800/printer.h @@ -22,7 +22,7 @@ class PRINTER : public DEVICE DEVICE* d_prn; public: - PRINTER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PRINTER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Printer I/F")); } diff --git a/source/src/vm/mz2800/reset.h b/source/src/vm/mz2800/reset.h index 366fbf797..f1b0bc653 100644 --- a/source/src/vm/mz2800/reset.h +++ b/source/src/vm/mz2800/reset.h @@ -24,7 +24,7 @@ class RESET : public DEVICE uint8_t prev; public: - RESET(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RESET(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Reset I/O")); } diff --git a/source/src/vm/mz2800/sasi.cpp b/source/src/vm/mz2800/sasi.cpp index 4160b4da0..0b6ac2537 100644 --- a/source/src/vm/mz2800/sasi.cpp +++ b/source/src/vm/mz2800/sasi.cpp @@ -12,6 +12,11 @@ #include "../upd71071.h" #include "../scsi_host.h" +#define CONTROL_SEL 0x20 +#define CONTROL_RST 0x08 +#define CONTROL_DMAE 0x02 +#define CONTROL_INTE 0x01 + #define STATUS_INT 0x01 #define STATUS_IXO 0x04 #define STATUS_CXD 0x08 @@ -48,13 +53,13 @@ void SASI::write_io8(uint32_t addr, uint32_t data) this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data); #endif control = data; - if((prev_control & 0x20) != (control & 0x20)) { - d_host->write_signal(SIG_SCSI_SEL, data, 0x20); + if((prev_control & CONTROL_SEL) != (control & CONTROL_SEL)) { + d_host->write_signal(SIG_SCSI_SEL, data, CONTROL_SEL); } - if((prev_control & 0x08) != (control & 0x08)) { - d_host->write_signal(SIG_SCSI_RST, data, 0x08); + if((prev_control & CONTROL_RST) != (control & CONTROL_RST)) { + d_host->write_signal(SIG_SCSI_RST, data, CONTROL_RST); } - if((prev_control & 0x03) != (control & 0x03)) { + if((prev_control & (CONTROL_DMAE | CONTROL_INTE)) != (control & (CONTROL_DMAE | CONTROL_INTE))) { update_signal(); } prev_control = control; @@ -147,7 +152,7 @@ void SASI::write_signal(int id, uint32_t data, uint32_t mask) break; case SIG_SASI_TC: if(data & mask) { - control &= ~0x02; + control &= ~CONTROL_DMAE; update_signal(); prev_control = control; } @@ -160,27 +165,27 @@ void SASI::update_signal() // http://retropc.net/ohishi/museum/mz1e30.htm bool prev_ic20_o11 = (!prev_req_status) && prev_cxd_status; bool prev_ic10_o8 = !(!prev_req_status && !prev_ixo_status && prev_msg_status && !prev_cxd_status); - bool prev_ic18_o11 = !(!(prev_control & 0x02) && prev_ic20_o11); + bool prev_ic18_o11 = !(!(prev_control & CONTROL_DMAE) && prev_ic20_o11); bool prev_ic18_o8 = !(prev_ic10_o8 && prev_ic18_o11); bool ic20_o11 = (!req_status) && cxd_status; bool ic10_o8 = !(!req_status && !ixo_status && msg_status && !cxd_status); - bool ic18_o11 = !(!(control & 0x02) && ic20_o11); + bool ic18_o11 = !(!(control & CONTROL_DMAE) && ic20_o11); bool ic18_o8 = !(ic10_o8 && ic18_o11); bool prev_irq_status = irq_status; bool prev_drq_status = drq_status; if(!prev_ic18_o8 && ic18_o8) { - irq_status = ((control & 0x01) != 0); + irq_status = ((control & CONTROL_INTE) != 0); } if(!prev_ic20_o11 && ic20_o11) { - drq_status = ((control & 0x02) != 0); + drq_status = ((control & CONTROL_DMAE) != 0); } - if((prev_control & 0x01) && !(control & 0x01)) { + if((prev_control & CONTROL_INTE) && !(control & CONTROL_INTE)) { irq_status = false; } - if((prev_control & 0x02) && !(control & 0x02)) { + if((prev_control & CONTROL_DMAE) && !(control & CONTROL_DMAE)) { drq_status = false; } if(prev_ack_status && !ack_status) { diff --git a/source/src/vm/mz2800/sasi.h b/source/src/vm/mz2800/sasi.h index 386cb13f0..356fed74b 100644 --- a/source/src/vm/mz2800/sasi.h +++ b/source/src/vm/mz2800/sasi.h @@ -43,7 +43,7 @@ class SASI : public DEVICE void __FASTCALL update_signal(); public: - SASI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SASI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { control = 0x00; bsy_status = prev_bsy_status = false; diff --git a/source/src/vm/mz2800/serial.h b/source/src/vm/mz2800/serial.h index a0ab6fe9f..10690410b 100644 --- a/source/src/vm/mz2800/serial.h +++ b/source/src/vm/mz2800/serial.h @@ -25,7 +25,7 @@ class SERIAL : public DEVICE bool addr_a0; public: - SERIAL(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SERIAL(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Serial I/F")); } diff --git a/source/src/vm/mz2800/sysport.h b/source/src/vm/mz2800/sysport.h index fd2daa9db..26487764f 100644 --- a/source/src/vm/mz2800/sysport.h +++ b/source/src/vm/mz2800/sysport.h @@ -22,7 +22,7 @@ class SYSPORT : public DEVICE DEVICE *d_pit, *d_sio; public: - SYSPORT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSPORT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/mz3500/CMakeLists.txt b/source/src/vm/mz3500/CMakeLists.txt index 4ee337001..100456cd0 100644 --- a/source/src/vm/mz3500/CMakeLists.txt +++ b/source/src/vm/mz3500/CMakeLists.txt @@ -1,14 +1,15 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/mz3500") - -set(BASIC_VM_FILES - mz3500.cpp - - keyboard.cpp - main.cpp - sub.cpp - ) +message("* vm/${EXE_NAME}") + +set(BASIC_VM_FILES + ../mz1p17.cpp + + keyboard.cpp + main.cpp + sub.cpp + + mz3500.cpp +) - -add_library(vm_mz3500 ${BASIC_VM_FILES}) +add_library(vm_${EXE_NAME} ${BASIC_VM_FILES}) diff --git a/source/src/vm/mz3500/keyboard.h b/source/src/vm/mz3500/keyboard.h index 01fb26eea..261325597 100644 --- a/source/src/vm/mz3500/keyboard.h +++ b/source/src/vm/mz3500/keyboard.h @@ -43,7 +43,7 @@ class KEYBOARD : public DEVICE void set_dk(bool value); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } @@ -54,7 +54,7 @@ class KEYBOARD : public DEVICE void release(); void reset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_frame(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz3500/main.h b/source/src/vm/mz3500/main.h index 0ea7de455..fb33c79a0 100644 --- a/source/src/vm/mz3500/main.h +++ b/source/src/vm/mz3500/main.h @@ -58,7 +58,7 @@ class MAIN : public DEVICE void update_bank(); public: - MAIN(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MAIN(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { intfd = int0 = int1 = int2 = int3 = int4 = false; me = e1 = false; diff --git a/source/src/vm/mz3500/mz3500.cpp b/source/src/vm/mz3500/mz3500.cpp index 989b656e6..fc451fabd 100644 --- a/source/src/vm/mz3500/mz3500.cpp +++ b/source/src/vm/mz3500/mz3500.cpp @@ -44,7 +44,7 @@ using MZ3500::KEYBOARD; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -317,7 +317,7 @@ void VM::reset() pio->write_signal(SIG_I8255_PORT_C, 0x40, 0x40); // ack = high } -void VM::special_reset() +void VM::special_reset(int num) { // halt key is pressed (mz3500sm p.80) halt = 8; @@ -469,6 +469,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 5 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -481,7 +493,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mz3500/mz3500.h b/source/src/vm/mz3500/mz3500.h index 86cdd9a16..f49c88f2d 100644 --- a/source/src/vm/mz3500/mz3500.h +++ b/source/src/vm/mz3500/mz3500.h @@ -28,7 +28,7 @@ #define PRINTER_STROBE_RISING_EDGE // device informations for win32 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_DIPSWITCH #define DIPSWITCH_DEFAULT 0x1fd #define USE_FLOPPY_DISK 4 @@ -124,7 +124,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -133,7 +133,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -168,6 +168,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz3500/sub.h b/source/src/vm/mz3500/sub.h index 8c3ff6736..d7058a339 100644 --- a/source/src/vm/mz3500/sub.h +++ b/source/src/vm/mz3500/sub.h @@ -53,7 +53,7 @@ class SUB : public DEVICE void draw_gfx_200line_8bit(); public: - SUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus (Sub)")); } diff --git a/source/src/vm/mz5500/CMakeLists.txt b/source/src/vm/mz5500/CMakeLists.txt index 1db268fbf..2ea3a687e 100644 --- a/source/src/vm/mz5500/CMakeLists.txt +++ b/source/src/vm/mz5500/CMakeLists.txt @@ -1,16 +1,19 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/mz5500") +message("* vm/${EXE_NAME}") set(VM_MZ5500_LIB_SRCS - mz5500.cpp + ../i8237.cpp + ../mz1p17.cpp display.cpp keyboard.cpp memory.cpp sysport.cpp + + mz5500.cpp ) -add_library(vm_mz5500 +add_library(vm_${EXE_NAME} ${VM_MZ5500_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/mz5500/display.h b/source/src/vm/mz5500/display.h index 8873f3fce..25d13d40c 100644 --- a/source/src/vm/mz5500/display.h +++ b/source/src/vm/mz5500/display.h @@ -45,7 +45,7 @@ class DISPLAY : public DEVICE void update_palette(); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/mz5500/keyboard.h b/source/src/vm/mz5500/keyboard.h index fa0e8388d..faf1519d5 100644 --- a/source/src/vm/mz5500/keyboard.h +++ b/source/src/vm/mz5500/keyboard.h @@ -38,7 +38,7 @@ class KEYBOARD : public DEVICE int phase, timeout; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/mz5500/memory.h b/source/src/vm/mz5500/memory.h index 7d3158bb2..1e2edc684 100644 --- a/source/src/vm/mz5500/memory.h +++ b/source/src/vm/mz5500/memory.h @@ -52,7 +52,7 @@ class MEMORY : public DEVICE void update_bank(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/mz5500/mz5500.cpp b/source/src/vm/mz5500/mz5500.cpp index 85f4b5d07..28dfec650 100644 --- a/source/src/vm/mz5500/mz5500.cpp +++ b/source/src/vm/mz5500/mz5500.cpp @@ -16,7 +16,7 @@ #include "../i8237.h" #include "../i8255.h" #include "../i8259.h" -#if defined(HAS_I286) +#if defined(_MZ6550) #include "../i286.h" #else #include "../i86.h" @@ -53,7 +53,7 @@ using MZ5500::SYSPORT; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -74,10 +74,11 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #endif pio = new I8255(this, emu); pic = new I8259(this, emu); -#if defined(HAS_I286) - cpu = new I80286(this, emu); +#if defined(_MZ6550) + cpu = new I286(this, emu); #else - cpu = new I8086(this, emu); + cpu = new I86(this, emu); + cpu->device_model = INTEL_8086; #endif io = new IO(this, emu); div = new LS393(this, emu); @@ -295,7 +296,7 @@ void VM::reset() pio->write_signal(SIG_I8255_PORT_C, 0x40, 0x40); // ack = high } -void VM::special_reset() +void VM::special_reset(int num) { // nmi cpu->write_signal(SIG_CPU_NMI, 1, 1); @@ -441,7 +442,19 @@ void VM::update_config() } } -#define STATE_VERSION 7 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 8 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -453,7 +466,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mz5500/mz5500.h b/source/src/vm/mz5500/mz5500.h index 00b3ec753..c583d4fc2 100644 --- a/source/src/vm/mz5500/mz5500.h +++ b/source/src/vm/mz5500/mz5500.h @@ -33,11 +33,6 @@ #define SCREEN_HEIGHT 400 #define WINDOW_HEIGHT_ASPECT 480 #define MAX_DRIVE 4 -#ifdef _MZ6550 -#define HAS_I286 -#else -#define HAS_I86 -#endif #define I8259_MAX_CHIPS 2 #define UPD7220_HORIZ_FREQ 24860 #define Z80CTC_CLOCKS 2457600 @@ -47,7 +42,7 @@ #define PRINTER_STROBE_RISING_EDGE // device informations for win32 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_FLOPPY_DISK 4 #define USE_KEY_LOCKED #define USE_AUTO_KEY 5 @@ -61,7 +56,7 @@ #define USE_PRINTER_TYPE 4 #define USE_DEBUGGER #define USE_STATE -#ifdef HAS_I286 +#if defined(_MZ6550) #define USE_CPU_I286 #else #define USE_CPU_I86 @@ -84,10 +79,10 @@ class EVENT; class I8237; class I8255; class I8259; -#if defined(HAS_I286) -class I80286; +#if defined(_MZ6550) +class I286; #else -class I8086; +class I86; #endif class IO; class LS393; @@ -120,10 +115,10 @@ class VM : public VM_TEMPLATE I8237* dma; I8255* pio; I8259* pic; // includes 2chips -#if defined(HAS_I286) - I80286* cpu; +#if defined(_MZ6550) + I286* cpu; #else - I8086* cpu; + I86* cpu; #endif IO* io; LS393* div; @@ -157,7 +152,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -166,7 +161,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -201,6 +196,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz5500/sysport.h b/source/src/vm/mz5500/sysport.h index b7064fa6f..a1d4ea574 100644 --- a/source/src/vm/mz5500/sysport.h +++ b/source/src/vm/mz5500/sysport.h @@ -23,7 +23,7 @@ class SYSPORT : public DEVICE int rst, highden; public: - SYSPORT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSPORT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/mz700/CMakeLists.txt b/source/src/vm/mz700/CMakeLists.txt index c7128e5fd..1afb63a4d 100644 --- a/source/src/vm/mz700/CMakeLists.txt +++ b/source/src/vm/mz700/CMakeLists.txt @@ -1,47 +1,50 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/mz700") - -if(BUILD_MZ800) - -add_library(vm_mz700 - cmos.cpp - emm.cpp - kanji.cpp - keyboard.cpp - memory.cpp - mz700.cpp - ramfile.cpp - floppy.cpp - quickdisk.cpp +message("* vm/${EXE_NAME}") + +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +if("${U_EXE_NAME}" STREQUAL "EMUMZ800") +add_library(vm_${EXE_NAME} + ./cmos.cpp + ./emm.cpp + ./kanji.cpp + ./keyboard.cpp + ./memory.cpp + ./ramfile.cpp + ./floppy.cpp + ./quickdisk.cpp + + ./mz700.cpp ) - -elseif(BUILD_MZ1500) - -add_library(vm_mz700 - cmos.cpp - emm.cpp - kanji.cpp - keyboard.cpp - memory.cpp - mz700.cpp - ramfile.cpp - floppy.cpp - quickdisk.cpp - ramfile.cpp - psg.cpp +elseif("${U_EXE_NAME}" STREQUAL "EMUMZ1500") +add_library(vm_${EXE_NAME} + ../mz1p17.cpp + + ./cmos.cpp + ./emm.cpp + ./kanji.cpp + ./keyboard.cpp + ./memory.cpp + ./ramfile.cpp + ./floppy.cpp + ./quickdisk.cpp + ./ramfile.cpp + ./psg.cpp + + ./mz700.cpp ) - else() - -add_library(vm_mz700 - cmos.cpp - emm.cpp - kanji.cpp - keyboard.cpp - memory.cpp - mz700.cpp - ramfile.cpp +# MZ700 +add_library(vm_${EXE_NAME} + ./cmos.cpp + ./emm.cpp + ./kanji.cpp + ./keyboard.cpp + ./memory.cpp + ./ramfile.cpp + + ./mz700.cpp ) diff --git a/source/src/vm/mz700/cmos.h b/source/src/vm/mz700/cmos.h index b6830c2d0..d42792c8c 100644 --- a/source/src/vm/mz700/cmos.h +++ b/source/src/vm/mz700/cmos.h @@ -26,7 +26,7 @@ class CMOS : public DEVICE bool modified; public: - CMOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMOS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMOS RAM")); } diff --git a/source/src/vm/mz700/emm.h b/source/src/vm/mz700/emm.h index 8756ee749..42271eeb0 100644 --- a/source/src/vm/mz700/emm.h +++ b/source/src/vm/mz700/emm.h @@ -25,7 +25,7 @@ class EMM : public DEVICE uint32_t data_addr; public: - EMM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + EMM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("EMM")); } diff --git a/source/src/vm/mz700/floppy.h b/source/src/vm/mz700/floppy.h index 004381453..15f3390f5 100644 --- a/source/src/vm/mz700/floppy.h +++ b/source/src/vm/mz700/floppy.h @@ -31,7 +31,7 @@ class FLOPPY : public DEVICE bool irq_enabled; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } @@ -41,7 +41,7 @@ class FLOPPY : public DEVICE void initialize(); void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz700/kanji.h b/source/src/vm/mz700/kanji.h index cf168f31b..130c79645 100644 --- a/source/src/vm/mz700/kanji.h +++ b/source/src/vm/mz700/kanji.h @@ -27,7 +27,7 @@ class KANJI : public DEVICE uint32_t kanji_addr, dic_addr; public: - KANJI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KANJI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Kanji ROM")); } diff --git a/source/src/vm/mz700/keyboard.h b/source/src/vm/mz700/keyboard.h index 5f0890def..9bf8ee7cc 100644 --- a/source/src/vm/mz700/keyboard.h +++ b/source/src/vm/mz700/keyboard.h @@ -30,7 +30,7 @@ class KEYBOARD : public DEVICE void update_key(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/mz700/memory.h b/source/src/vm/mz700/memory.h index e5dd7d92c..aaa6d8077 100644 --- a/source/src/vm/mz700/memory.h +++ b/source/src/vm/mz700/memory.h @@ -72,8 +72,8 @@ class MEMORY : public DEVICE void update_map_middle(); void update_map_high(); #if defined(_MZ800) - int vram_page_mask(uint8_t f); - int vram_addr(int addr); + int __FASTCALL vram_page_mask(uint8_t f); + int __FASTCALL vram_addr(int addr); #endif // crtc @@ -93,8 +93,8 @@ class MEMORY : public DEVICE #if defined(_MZ1500) bool hblank_pcg; #endif - void set_vblank(bool val); - void set_hblank(bool val); + void __FASTCALL set_vblank(bool val); + void __FASTCALL set_hblank(bool val); // renderer #if defined(_MZ800) @@ -106,16 +106,16 @@ class MEMORY : public DEVICE scrntype_t palette_pc[8]; #if defined(_MZ800) - void draw_line_320x200_2bpp(int v); - void draw_line_320x200_4bpp(int v); - void draw_line_640x200_1bpp(int v); - void draw_line_640x200_2bpp(int v); - void draw_line_mz700(int v); + void __FASTCALL draw_line_320x200_2bpp(int v); + void __FASTCALL draw_line_320x200_4bpp(int v); + void __FASTCALL draw_line_640x200_1bpp(int v); + void __FASTCALL draw_line_640x200_2bpp(int v); + void __FASTCALL draw_line_mz700(int v); #endif - void draw_line(int v); + void __FASTCALL draw_line(int v); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } @@ -128,7 +128,7 @@ class MEMORY : public DEVICE void update_config(); #endif void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_data8w(uint32_t addr, uint32_t data, int* wait); diff --git a/source/src/vm/mz700/mz700.cpp b/source/src/vm/mz700/mz700.cpp index ae19424c5..96292c8f0 100644 --- a/source/src/vm/mz700/mz700.cpp +++ b/source/src/vm/mz700/mz700.cpp @@ -67,7 +67,7 @@ using MZ700::QUICKDISK; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { #if defined(_MZ800) boot_mode = config.boot_mode; @@ -726,6 +726,18 @@ void VM::update_config() #endif } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 @@ -739,7 +751,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mz700/mz700.h b/source/src/vm/mz700/mz700.h index 35d03cca0..14a9d5808 100644 --- a/source/src/vm/mz700/mz700.h +++ b/source/src/vm/mz700/mz700.h @@ -268,7 +268,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -328,6 +328,9 @@ class VM : public VM_TEMPLATE #endif bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz700/psg.h b/source/src/vm/mz700/psg.h index ecd195061..93b39c42a 100644 --- a/source/src/vm/mz700/psg.h +++ b/source/src/vm/mz700/psg.h @@ -23,7 +23,7 @@ class PSG : public DEVICE DEVICE *d_psg_l, *d_psg_r; public: - PSG(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PSG(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("PSG")); } diff --git a/source/src/vm/mz700/quickdisk.h b/source/src/vm/mz700/quickdisk.h index e71938fbe..16b997f46 100644 --- a/source/src/vm/mz700/quickdisk.h +++ b/source/src/vm/mz700/quickdisk.h @@ -56,7 +56,7 @@ class QUICKDISK : public DEVICE void release_disk(); public: - QUICKDISK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + QUICKDISK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Quick Disk")); } @@ -68,7 +68,7 @@ class QUICKDISK : public DEVICE void reset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/mz700/ramfile.h b/source/src/vm/mz700/ramfile.h index 4127a14c3..6a5d35469 100644 --- a/source/src/vm/mz700/ramfile.h +++ b/source/src/vm/mz700/ramfile.h @@ -25,7 +25,7 @@ class RAMFILE : public DEVICE uint32_t data_addr; public: - RAMFILE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RAMFILE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RAM File")); } diff --git a/source/src/vm/mz80k/CMakeLists.txt b/source/src/vm/mz80k/CMakeLists.txt index 3207b84c7..271fccfb9 100644 --- a/source/src/vm/mz80k/CMakeLists.txt +++ b/source/src/vm/mz80k/CMakeLists.txt @@ -1,32 +1,47 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/mz80K") +message("* vm/${EXE_NAME}") -if(BUILD_MZ80AIF) +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) -add_library(vm_mz80k - memory.cpp - keyboard.cpp - mz80aif.cpp - mz80k.cpp - printer.cpp -) +if("${U_EXE_NAME}" STREQUAL "EMUMZ80A") +add_library(vm_${EXE_NAME} + ../mz1p17.cpp -elseif(BUILD_MZ80FIO) -add_library(vm_mz80k - memory.cpp - keyboard.cpp - mz80fio.cpp - mz80k.cpp - printer.cpp + ./memory.cpp + ./keyboard.cpp + ./mz80aif.cpp + ./printer.cpp + ./mz80k.cpp ) -else() +elseif("${U_EXE_NAME}" STREQUAL "EMUMZ80K") +add_library(vm_${EXE_NAME} + ../mz1p17.cpp -add_library(vm_mz80k - memory.cpp - keyboard.cpp - mz80k.cpp - printer.cpp + ./memory.cpp + ./keyboard.cpp + ./mz80fio.cpp + ./printer.cpp + ./mz80k.cpp +) +elseif("${U_EXE_NAME}" STREQUAL "EMUMZ1200") +add_library(vm_${EXE_NAME} + ../mz1p17.cpp + ./memory.cpp + ./keyboard.cpp + ./mz80fio.cpp + ./printer.cpp + ./mz80k.cpp +) +else() +## IS Exists? +add_library(vm_${EXE_NAME} + ../mz1p17.cpp + + ./memory.cpp + ./keyboard.cpp + ./printer.cpp + ./mz80k.cpp ) endif() diff --git a/source/src/vm/mz80k/keyboard.h b/source/src/vm/mz80k/keyboard.h index 3be878bf6..7f885fbc8 100644 --- a/source/src/vm/mz80k/keyboard.h +++ b/source/src/vm/mz80k/keyboard.h @@ -33,7 +33,7 @@ class KEYBOARD : public DEVICE void update_key(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/mz80k/memory.h b/source/src/vm/mz80k/memory.h index 09647061c..139afcf2c 100644 --- a/source/src/vm/mz80k/memory.h +++ b/source/src/vm/mz80k/memory.h @@ -91,10 +91,10 @@ class MEMORY : public DEVICE uint8_t pcg_addr; uint8_t pcg_ctrl; - void draw_line(int v); + void __FASTCALL draw_line(int v); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } @@ -104,7 +104,7 @@ class MEMORY : public DEVICE void initialize(); void reset(); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_data8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_data8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); diff --git a/source/src/vm/mz80k/mz80aif.h b/source/src/vm/mz80k/mz80aif.h index 838115093..a5acc63fd 100644 --- a/source/src/vm/mz80k/mz80aif.h +++ b/source/src/vm/mz80k/mz80aif.h @@ -25,7 +25,7 @@ class MZ80AIF : public DEVICE DEVICE* d_fdc; public: - MZ80AIF(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ80AIF(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-80AIF (FDC I/F)")); } diff --git a/source/src/vm/mz80k/mz80fio.h b/source/src/vm/mz80k/mz80fio.h index 3dfd10672..6c912ac22 100644 --- a/source/src/vm/mz80k/mz80fio.h +++ b/source/src/vm/mz80k/mz80fio.h @@ -23,7 +23,7 @@ class MZ80FIO : public DEVICE DEVICE* d_fdc; public: - MZ80FIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MZ80FIO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("MZ-80FIO (FDC I/F)")); } diff --git a/source/src/vm/mz80k/mz80k.cpp b/source/src/vm/mz80k/mz80k.cpp index 736a4fb21..fd45f217a 100644 --- a/source/src/vm/mz80k/mz80k.cpp +++ b/source/src/vm/mz80k/mz80k.cpp @@ -63,7 +63,7 @@ using MZ80::MZ80FIO; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -485,6 +485,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 7 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -497,7 +509,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/mz80k/mz80k.h b/source/src/vm/mz80k/mz80k.h index d0ea8c508..211f8d3a0 100644 --- a/source/src/vm/mz80k/mz80k.h +++ b/source/src/vm/mz80k/mz80k.h @@ -164,7 +164,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -226,6 +226,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/mz80k/printer.h b/source/src/vm/mz80k/printer.h index bc11a7bea..fdb4f686b 100644 --- a/source/src/vm/mz80k/printer.h +++ b/source/src/vm/mz80k/printer.h @@ -27,7 +27,7 @@ class PRINTER : public DEVICE #endif public: - PRINTER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PRINTER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Printer I/F")); } diff --git a/source/src/vm/n5200/CMakeLists.txt b/source/src/vm/n5200/CMakeLists.txt index b3f76bb29..3adae4c19 100644 --- a/source/src/vm/n5200/CMakeLists.txt +++ b/source/src/vm/n5200/CMakeLists.txt @@ -1,17 +1,19 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/n5200") +message("* vm/emun5200") set(VM_N5200_LIB_SRCS - n5200.cpp + ../i8237.cpp display.cpp floppy.cpp keyboard.cpp memory.cpp system.cpp + + n5200.cpp ) -add_library(vm_n5200 +add_library(vm_emun5200 ${VM_N5200_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/n5200/display.h b/source/src/vm/n5200/display.h index ce8cde75a..297cd73c0 100644 --- a/source/src/vm/n5200/display.h +++ b/source/src/vm/n5200/display.h @@ -25,7 +25,7 @@ class DISPLAY : public DEVICE bool vsync_enb; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/n5200/floppy.h b/source/src/vm/n5200/floppy.h index 8ba01eec3..44935fbef 100644 --- a/source/src/vm/n5200/floppy.h +++ b/source/src/vm/n5200/floppy.h @@ -26,7 +26,7 @@ class FLOPPY : public DEVICE uint8_t chgreg, ctrlreg; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/n5200/keyboard.h b/source/src/vm/n5200/keyboard.h index 3541110cd..20ec0fef0 100644 --- a/source/src/vm/n5200/keyboard.h +++ b/source/src/vm/n5200/keyboard.h @@ -28,7 +28,7 @@ class KEYBOARD : public DEVICE uint8_t flag[256]; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/n5200/memory.h b/source/src/vm/n5200/memory.h index 5ba1c1e20..50a145e84 100644 --- a/source/src/vm/n5200/memory.h +++ b/source/src/vm/n5200/memory.h @@ -34,7 +34,7 @@ class MEMORY : public DEVICE bool protect; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/n5200/n5200.cpp b/source/src/vm/n5200/n5200.cpp index b49e75982..0de0955fc 100644 --- a/source/src/vm/n5200/n5200.cpp +++ b/source/src/vm/n5200/n5200.cpp @@ -13,7 +13,8 @@ #include "../event.h" #include "../beep.h" -#include "../i386.h" +#include "../i386_np21.h" +//#include "../i386.h" #include "../i8237.h" #include "../i8251.h" #include "../i8253.h" @@ -45,7 +46,7 @@ using N5200::SYSTEM; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -58,6 +59,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // beep->set_context_debugger(new DEBUGGER(this, emu)); #endif cpu = new I386(this, emu); + cpu->device_model = INTEL_80386; dma = new I8237(this, emu); #ifdef USE_DEBUGGER dma->set_context_debugger(new DEBUGGER(this, emu)); @@ -439,7 +441,19 @@ void VM::update_config() } } -#define STATE_VERSION 2 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -451,7 +465,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/n5200/n5200.h b/source/src/vm/n5200/n5200.h index 9e2d61b5d..37af6bffa 100644 --- a/source/src/vm/n5200/n5200.h +++ b/source/src/vm/n5200/n5200.h @@ -21,7 +21,6 @@ #define SCREEN_HEIGHT 400 #define WINDOW_HEIGHT_ASPECT 480 #define MAX_DRIVE 4 -#define HAS_I386 #define I8259_MAX_CHIPS 2 #define IO_ADDR_MAX 0x10000 @@ -104,7 +103,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -150,6 +149,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/n5200/system.h b/source/src/vm/n5200/system.h index 4a54949af..fb76c244b 100644 --- a/source/src/vm/n5200/system.h +++ b/source/src/vm/n5200/system.h @@ -25,7 +25,7 @@ class SYSTEM : public DEVICE bool nmi_enb; public: - SYSTEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSTEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/nand.h b/source/src/vm/nand.h index 69a7da7b1..08e8849e8 100644 --- a/source/src/vm/nand.h +++ b/source/src/vm/nand.h @@ -23,9 +23,7 @@ #define SIG_NAND_BIT_6 0x40 #define SIG_NAND_BIT_7 0x80 -class VM; -class EMU; -class NAND : public DEVICE +class DLL_PREFIX NAND : public DEVICE { private: outputs_t outputs; @@ -33,7 +31,7 @@ class NAND : public DEVICE bool prev, first; public: - NAND(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + NAND(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs); bits_mask = bits_in = 0; diff --git a/source/src/vm/noise.h b/source/src/vm/noise.h index be275ed7e..fc2ab5b42 100644 --- a/source/src/vm/noise.h +++ b/source/src/vm/noise.h @@ -14,7 +14,7 @@ //#include "../emu.h" #include "device.h" -class NOISE : public DEVICE +class DLL_PREFIX NOISE : public DEVICE { private: int16_t *buffer_l; @@ -31,7 +31,7 @@ class NOISE : public DEVICE void __FASTCALL get_sample(); public: - NOISE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + NOISE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { buffer_l = buffer_r = NULL; samples = 0; @@ -46,8 +46,8 @@ class NOISE : public DEVICE void initialize(); void release(); void reset(); - void event_callback(int event_id, int err); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int event_id, int err); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/nor.h b/source/src/vm/nor.h index 5151d4741..5b0422c7e 100644 --- a/source/src/vm/nor.h +++ b/source/src/vm/nor.h @@ -23,9 +23,7 @@ #define SIG_NOR_BIT_6 0x40 #define SIG_NOR_BIT_7 0x80 -class VM; -class EMU; -class NOR : public DEVICE +class DLL_PREFIX NOR : public DEVICE { private: outputs_t outputs; @@ -33,7 +31,7 @@ class NOR : public DEVICE bool prev, first; public: - NOR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + NOR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs); bits_in = 0; diff --git a/source/src/vm/not.h b/source/src/vm/not.h index febdf6a58..aa0c59a48 100644 --- a/source/src/vm/not.h +++ b/source/src/vm/not.h @@ -16,16 +16,14 @@ #define SIG_NOT_INPUT 0 -class VM; -class EMU; -class NOT : public DEVICE +class DLL_PREFIX NOT : public DEVICE { private: outputs_t outputs; bool prev, first; public: - NOT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + NOT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs); prev = first = true; diff --git a/source/src/vm/np21/i286c/cpucore.h b/source/src/vm/np21/i286c/cpucore.h new file mode 100644 index 000000000..2d3b01d08 --- /dev/null +++ b/source/src/vm/np21/i286c/cpucore.h @@ -0,0 +1,402 @@ +//---------------------------------------------------------------------------- +// +// i286c : 80286 Engine for Pentium ver0.05 +// +// Copyright by Yui/Studio Milmake 1999-2003 +// +//---------------------------------------------------------------------------- + +#ifndef NP2_I286C_CPUCORE_H__ +#define NP2_I286C_CPUCORE_H__ + +#include "../../vm_template.h" +//#include "../../../emu.h" +#include "../../device.h" +//#ifdef USE_DEBUGGER +#include "../../debugger.h" +//#endif + +namespace I286_NP21 { +extern DEVICE *device_cpu; +extern DEVICE *device_mem; +extern DEVICE *device_io; +//#ifdef I86_PSEUDO_BIOS +extern DEVICE *device_bios; +//#endif +//#ifdef SINGLE_MODE_DMA +extern DEVICE *device_dma; +//#endif +//#ifdef USE_DEBUGGER +extern DEBUGGER *device_debugger; +//#endif +extern SINT64 i286_memory_wait; +extern bool _SINGLE_MODE_DMA; +} +#ifdef __BIG_ENDIAN__ + #define BYTESEX_BIG +#else + #define BYTESEX_LITTLE +#endif + +#ifndef SINT8 + typedef signed __int8 SINT8; +#endif +#ifndef SINT16 + typedef signed __int16 SINT16; +#endif +#ifndef SINT32 + typedef signed __int32 SINT32; +#endif +#ifndef SINT64 + typedef signed __int64 SINT64; +#endif +#ifndef REG8 + #define REG8 UINT8 +#endif +#ifndef REG16 + #define REG16 UINT16 +#endif + +#ifndef LOADINTELDWORD +#define LOADINTELDWORD(a) (((UINT32)(((UINT8*)(a))[0]) ) | \ + ((UINT32)(((UINT8*)(a))[1]) << 8) | \ + ((UINT32)(((UINT8*)(a))[2]) << 16) | \ + ((UINT32)(((UINT8*)(a))[3]) << 24)) +#endif + +#ifndef LOADINTELWORD +#define LOADINTELWORD(a) (((UINT16)((UINT8*)(a))[0]) | ((UINT16)(((UINT8*)(a))[1]) << 8)) +#endif + +#ifndef STOREINTELDWORD +#define STOREINTELDWORD(a, b) *(((UINT8*)(a))+0) = (UINT8)((b) ); \ + *(((UINT8*)(a))+1) = (UINT8)((b)>> 8); \ + *(((UINT8*)(a))+2) = (UINT8)((b)>>16); \ + *(((UINT8*)(a))+3) = (UINT8)((b)>>24) +#endif + +#ifndef STOREINTELWORD +#define STOREINTELWORD(a, b) *(((UINT8*)(a))+0) = (UINT8)((b) ); \ + *(((UINT8*)(a))+1) = (UINT8)((b)>>8) +#endif + +#ifndef LOW16 +#define LOW16(a) ((UINT16)(a)) +#endif + +#define _MALLOC(a, b) malloc(a) +#define _MFREE(a) free(a) + +#ifndef TRACEOUT + #define TRACEOUT(a) +#endif + +#define PARTSCALL __fastcall +#define CPUCALL __fastcall +#define MEMCALL __fastcall +#define DMACCALL __fastcall +#define IOOUTCALL __fastcall +#define IOINPCALL __fastcall + +#include "cpumem.h" + +#if defined(CPUCORE_IA32) +#error : not support CPUCORE_IA32 +#endif + +enum { + C_FLAG = 0x0001, + P_FLAG = 0x0004, + A_FLAG = 0x0010, + Z_FLAG = 0x0040, + S_FLAG = 0x0080, + T_FLAG = 0x0100, + I_FLAG = 0x0200, + D_FLAG = 0x0400, + O_FLAG = 0x0800 +}; + +enum { + MSW_PE = 0x0001, + MSW_MP = 0x0002, + MSW_EM = 0x0004, + MSW_TS = 0x0008 +}; + +enum { + CPUTYPE_V30 = 0x01, + CPUTYPE_I8086, + CPUTYPE_I80186, +}; + +#ifndef CPUCALL +#define CPUCALL __FASTCALL +#endif + +#if defined(BYTESEX_LITTLE) + +typedef struct { + UINT8 al; + UINT8 ah; + UINT8 cl; + UINT8 ch; + UINT8 dl; + UINT8 dh; + UINT8 bl; + UINT8 bh; + UINT8 sp_l; + UINT8 sp_h; + UINT8 bp_l; + UINT8 bp_h; + UINT8 si_l; + UINT8 si_h; + UINT8 di_l; + UINT8 di_h; + UINT8 es_l; + UINT8 es_h; + UINT8 cs_l; + UINT8 cs_h; + UINT8 ss_l; + UINT8 ss_h; + UINT8 ds_l; + UINT8 ds_h; + UINT8 flag_l; + UINT8 flag_h; + UINT8 ip_l; + UINT8 ip_h; +} I286REG8; + +#else + +typedef struct { + UINT8 ah; + UINT8 al; + UINT8 ch; + UINT8 cl; + UINT8 dh; + UINT8 dl; + UINT8 bh; + UINT8 bl; + UINT8 sp_h; + UINT8 sp_l; + UINT8 bp_h; + UINT8 bp_l; + UINT8 si_h; + UINT8 si_l; + UINT8 di_h; + UINT8 di_l; + UINT8 es_h; + UINT8 es_l; + UINT8 cs_h; + UINT8 cs_l; + UINT8 ss_h; + UINT8 ss_l; + UINT8 ds_h; + UINT8 ds_l; + UINT8 flag_h; + UINT8 flag_l; + UINT8 ip_h; + UINT8 ip_l; +} I286REG8; + +#endif + +typedef struct { + UINT16 ax; + UINT16 cx; + UINT16 dx; + UINT16 bx; + UINT16 sp; + UINT16 bp; + UINT16 si; + UINT16 di; + UINT16 es; + UINT16 cs; + UINT16 ss; + UINT16 ds; + UINT16 flag; + UINT16 ip; +} I286REG16; + +typedef struct { + UINT16 limit; + UINT16 base; + UINT8 base24; + UINT8 reserved; +} I286DTR; + +typedef struct { + union { + I286REG8 b; + I286REG16 w; + } r; + UINT32 es_base; + UINT32 cs_base; + UINT32 ss_base; + UINT32 ds_base; + UINT32 ss_fix; + UINT32 ds_fix; + UINT32 adrsmask; // ver0.72 + UINT16 prefix; + UINT8 trap; + UINT8 resetreq; // ver0.72 + UINT32 ovflag; + I286DTR GDTR; + UINT16 MSW; + I286DTR IDTR; + UINT16 LDTR; // ver0.73 + I286DTR LDTRC; + UINT16 TR; + I286DTR TRC; + UINT8 padding[2]; + + UINT8 cpu_type; +// UINT8 itfbank; // ver0.72 +// UINT16 ram_d0; + SINT32 remainclock; + SINT32 baseclock; +// UINT32 clock; +} I286STAT; + +typedef struct { // for ver0.73 + UINT8 *ext; + UINT32 extsize; + UINT8 *extbase; // ext - 0x100000 + UINT32 extlimit16mb; // extsize + 0x100000 + UINT8 *ems[4]; + UINT32 inport; +#if defined(CPUSTRUC_MEMWAIT) + UINT8 tramwait; + UINT8 vramwait; + UINT8 grcgwait; + UINT8 padding; +#endif +} I286EXT; + +typedef struct { + I286STAT s; // STATsaveされる奴 + I286EXT e; +} I286CORE; + + +//#ifdef __cplusplus +//extern "C" { +//#endif + +namespace I286_NP21 { +extern I286CORE i286core; +extern const UINT8 iflags[]; + +void i286c_initialize(void); +void i286c_deinitialize(void); +void i286c_reset(void); +void i286c_shut(void); +//void i286c_setextsize(UINT32 size); +//void i286c_setemm(UINT frame, UINT32 addr); + +void CPUCALL i286c_interrupt(REG8 vect); + +void i286c(void); +void i286c_step(void); + +void v30c(void); +void v30c_step(void); +} +//#ifdef __cplusplus +//} +//#endif + + +// ---- macros + +namespace I286_NP21 { +#define CPU_STATSAVE i286core.s + +#define CPU_AX i286core.s.r.w.ax +#define CPU_BX i286core.s.r.w.bx +#define CPU_CX i286core.s.r.w.cx +#define CPU_DX i286core.s.r.w.dx +#define CPU_SI i286core.s.r.w.si +#define CPU_DI i286core.s.r.w.di +#define CPU_BP i286core.s.r.w.bp +#define CPU_SP i286core.s.r.w.sp +#define CPU_CS i286core.s.r.w.cs +#define CPU_DS i286core.s.r.w.ds +#define CPU_ES i286core.s.r.w.es +#define CPU_SS i286core.s.r.w.ss +#define CPU_IP i286core.s.r.w.ip + +#define CPU_EAX i286core.s.r.w.ax +#define CPU_EBX i286core.s.r.w.bx +#define CPU_ECX i286core.s.r.w.cx +#define CPU_EDX i286core.s.r.w.dx +#define CPU_ESI i286core.s.r.w.si +#define CPU_EDI i286core.s.r.w.di +#define CPU_EBP i286core.s.r.w.bp +#define CPU_ESP i286core.s.r.w.sp +#define CPU_EIP i286core.s.r.w.ip + +#define ES_BASE i286core.s.es_base +#define CS_BASE i286core.s.cs_base +#define SS_BASE i286core.s.ss_base +#define DS_BASE i286core.s.ds_base + +#define CPU_AL i286core.s.r.b.al +#define CPU_BL i286core.s.r.b.bl +#define CPU_CL i286core.s.r.b.cl +#define CPU_DL i286core.s.r.b.dl +#define CPU_AH i286core.s.r.b.ah +#define CPU_BH i286core.s.r.b.bh +#define CPU_CH i286core.s.r.b.ch +#define CPU_DH i286core.s.r.b.dh + +#define CPU_FLAG i286core.s.r.w.flag +#define CPU_FLAGL i286core.s.r.b.flag_l + +#define CPU_REMCLOCK i286core.s.remainclock +#define CPU_BASECLOCK i286core.s.baseclock +#define CPU_CLOCK i286core.s.clock +#define CPU_ADRSMASK i286core.s.adrsmask +#define CPU_MSW i286core.s.MSW +#define CPU_RESETREQ i286core.s.resetreq +//#define CPU_ITFBANK i286core.s.itfbank +//#define CPU_RAM_D000 i286core.s.ram_d0 + +#define CPU_EXTMEM i286core.e.ext +#define CPU_EXTMEMSIZE i286core.e.extsize +#define CPU_EXTMEMBASE i286core.e.extbase +#define CPU_EXTLIMIT16 i286core.e.extlimit16mb +#define CPU_INPADRS i286core.e.inport +#define CPU_EMSPTR i286core.e.ems + +#define CPU_TYPE i286core.s.cpu_type + +#if defined(CPUSTRUC_MEMWAIT) +#define MEMWAIT_TRAM i286core.e.tramwait +#define MEMWAIT_VRAM i286core.e.vramwait +#define MEMWAIT_GRCG i286core.e.grcgwait +#endif + + +#define CPU_isDI (!(i286core.s.r.w.flag & I_FLAG)) +#define CPU_isEI (i286core.s.r.w.flag & I_FLAG) +#define CPU_CLI i286core.s.r.w.flag &= ~I_FLAG; \ + i286core.s.trap = 0; +#define CPU_STI i286core.s.r.w.flag |= I_FLAG; \ + i286core.s.trap = (i286core.s.r.w.flag >> 8) & 1; +#define CPU_A20EN(en) CPU_ADRSMASK = (en)?0x00ffffff:0x000fffff; + +#define CPU_INITIALIZE i286c_initialize +#define CPU_DEINITIALIZE i286c_deinitialize +#define CPU_RESET i286c_reset +#define CPU_CLEARPREFETCH() +#define CPU_INTERRUPT(vect, soft) i286c_interrupt(vect) +#define CPU_EXEC i286c +#define CPU_EXECV30 v30c +#define CPU_SHUT i286c_shut +#define CPU_SETEXTSIZE(size) i286c_setextsize((UINT32)(size) << 20) +#define CPU_SETEMM(frame, addr) i286c_setemm(frame, addr) + +#define CPU_STEPEXEC i286c_step +} +#endif /* !NP2_I286C_CPUCORE_H__ */ diff --git a/source/src/vm/np21/i286c/cpumem.cpp b/source/src/vm/np21/i286c/cpumem.cpp new file mode 100644 index 000000000..1ae8683f0 --- /dev/null +++ b/source/src/vm/np21/i286c/cpumem.cpp @@ -0,0 +1,231 @@ +//#include "compiler.h" + +#ifndef NP2_MEMORY_ASM + +#include "cpucore.h" + +namespace I286_NP21 { + DEVICE *device_cpu; + DEVICE *device_mem; + DEVICE *device_io; +//#ifdef I86_PSEUDO_BIOS + DEVICE *device_bios = NULL; +//#endif +//#ifdef SINGLE_MODE_DMA + DEVICE *device_dma = NULL; +//#endif +//#ifdef USE_DEBUGGER + DEBUGGER *device_debugger = NULL; +//#endif + SINT64 i286_memory_wait; + bool _SINGLE_MODE_DMA = false; +} +namespace I286_NP21 { +// ---- + +REG8 MEMCALL memp_read8(UINT32 address) { + + address = address & CPU_ADRSMASK; + int wait = 0; + REG8 val; + val = device_mem->read_data8w(address, &wait); + i286_memory_wait += wait; + return val; + +} + +REG16 MEMCALL memp_read16(UINT32 address) +{ + address = address & CPU_ADRSMASK; + int wait = 0; + REG16 val; + val = device_mem->read_data16w(address, &wait); + i286_memory_wait += wait; + return val; +} + +UINT32 MEMCALL memp_read32(UINT32 address) +{ + address = address & CPU_ADRSMASK; + int wait = 0; + REG32 val; + val = device_mem->read_data32w(address, &wait); + i286_memory_wait += wait; + return val; +} + +void MEMCALL memp_write8(UINT32 address, REG8 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data8w(address, value, &wait); + i286_memory_wait += wait; +} + +void MEMCALL memp_write16(UINT32 address, REG16 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data16w(address, value, &wait); + i286_memory_wait += wait; +} + +void MEMCALL memp_write32(UINT32 address, UINT32 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data32w(address, value, &wait); + i286_memory_wait += wait; +} + + +void MEMCALL memp_reads(UINT32 address, void *dat, UINT leng) { + + UINT8 *out = (UINT8 *)dat; + + while(leng--) { + *out++ = memp_read8(address++); + } +} + +void MEMCALL memp_writes(UINT32 address, const void *dat, UINT leng) { + + const UINT8 *out = (UINT8 *)dat; + + while(leng--) { + memp_write8(address++, *out++); + } +} + + +// ---- Logical Space (BIOS) + +REG8 MEMCALL memr_read8(UINT seg, UINT off) { + + UINT32 address; + + address = (seg << 4) + LOW16(off); + return(memp_read8(address)); + +} + +REG16 MEMCALL memr_read16(UINT seg, UINT off) { + + UINT32 address; + + address = (seg << 4) + LOW16(off); + return(memp_read16(address)); + +} + +void MEMCALL memr_write8(UINT seg, UINT off, REG8 value) { + + UINT32 address; + + address = (seg << 4) + LOW16(off); + memp_write8(address, value); +} + +void MEMCALL memr_write16(UINT seg, UINT off, REG16 value) { + + UINT32 address; + + address = (seg << 4) + LOW16(off); + memp_write16(address, value); +} + +void MEMCALL memr_reads(UINT seg, UINT off, void *dat, UINT leng) { + + UINT8 *out; + UINT32 adrs; + + out = (UINT8 *)dat; + adrs = seg << 4; + off = LOW16(off); + + while(leng--) { + *out++ = memp_read8(adrs + off); + off = LOW16(off + 1); + } +} + +void MEMCALL memr_writes(UINT seg, UINT off, const void *dat, UINT leng) { + + UINT8 *out; + UINT32 adrs; + + out = (UINT8 *)dat; + adrs = seg << 4; + off = LOW16(off); + + while(leng--) { + memp_write8(adrs + off, *out++); + off = LOW16(off + 1); + } +} + +void IOOUTCALL iocore_out8(UINT port, REG8 dat) +{ + int wait = 0; + device_io->write_io8w(port, dat, &wait); + i286_memory_wait += wait; +} + +REG8 IOINPCALL iocore_inp8(UINT port) +{ + int wait = 0; + UINT8 val = device_io->read_io8w(port, &wait); + i286_memory_wait += wait; + return val; +} + +void IOOUTCALL iocore_out16(UINT port, REG16 dat) +{ + int wait = 0; + device_io->write_io16w(port, dat, &wait); + i286_memory_wait += wait; +} + +REG16 IOINPCALL iocore_inp16(UINT port) +{ + int wait = 0; + UINT16 val = device_io->read_io16w(port, &wait); + i286_memory_wait += wait; + return val; +} + +void IOOUTCALL iocore_out32(UINT port, UINT32 dat) +{ + int wait = 0; + device_io->write_io32w(port, dat, &wait); + i286_memory_wait += wait; +} + +UINT32 IOINPCALL iocore_inp32(UINT port) +{ + int wait = 0; + UINT32 val = device_io->read_io32w(port, &wait); + i286_memory_wait += wait; + return val; +} + +void dmax86(void) +{ +//#ifdef SINGLE_MODE_DMA + if(_SINGLE_MODE_DMA) { + if(device_dma != NULL) device_dma->do_dma(); + } +//#endif +} + +void dmav30(void) +{ +//#ifdef SINGLE_MODE_DMA + if(_SINGLE_MODE_DMA) { + if(device_dma != NULL) device_dma->do_dma(); + } +//#endif +} +} +#endif + diff --git a/source/src/vm/np21/i286c/cpumem.h b/source/src/vm/np21/i286c/cpumem.h new file mode 100644 index 000000000..9bfbe7b03 --- /dev/null +++ b/source/src/vm/np21/i286c/cpumem.h @@ -0,0 +1,82 @@ + +#pragma once + +#ifndef MEMCALL +#define MEMCALL +#endif + +//#ifdef __cplusplus +//extern "C" { +//#endif + +namespace I286_NP21 { +REG8 MEMCALL memp_read8(UINT32 address); +REG16 MEMCALL memp_read16(UINT32 address); +UINT32 MEMCALL memp_read32(UINT32 address); +void MEMCALL memp_write8(UINT32 address, REG8 value); +void MEMCALL memp_write16(UINT32 address, REG16 value); +void MEMCALL memp_write32(UINT32 address, UINT32 value); + +void MEMCALL memp_reads(UINT32 address, void *dat, UINT leng); +void MEMCALL memp_writes(UINT32 address, const void *dat, UINT leng); + +REG8 MEMCALL memr_read8(UINT seg, UINT off); +REG16 MEMCALL memr_read16(UINT seg, UINT off); +void MEMCALL memr_write8(UINT seg, UINT off, REG8 value); +void MEMCALL memr_write16(UINT seg, UINT off, REG16 value); +void MEMCALL memr_reads(UINT seg, UINT off, void *dat, UINT leng); +void MEMCALL memr_writes(UINT seg, UINT off, const void *dat, UINT leng); + +void IOOUTCALL iocore_out8(UINT port, REG8 dat); +REG8 IOINPCALL iocore_inp8(UINT port); + +void IOOUTCALL iocore_out16(UINT port, REG16 dat); +REG16 IOINPCALL iocore_inp16(UINT port); + +void IOOUTCALL iocore_out32(UINT port, UINT32 dat); +UINT32 IOINPCALL iocore_inp32(UINT port); + +void dmax86(void); +void dmav30(void); + +//#ifdef __cplusplus +//} +//#endif + + +// ---- Physical Space (DMA) + +#define MEMP_READ8(addr) \ + memp_read8((addr)) +#define MEMP_WRITE8(addr, dat) \ + memp_write8((addr), (dat)) + + +// ---- Logical Space (BIOS) + +#define MEML_READ8(addr) \ + memp_read8((addr)) +#define MEML_READ16(addr) \ + memp_read16((addr)) +#define MEML_WRITE8(addr, dat) \ + memp_write8((addr), (dat)) +#define MEML_WRITE16(addr, dat) \ + memp_write16((addr), (dat)) +#define MEML_READS(addr, dat, leng) \ + memp_reads((addr), (dat), (leng)) +#define MEML_WRITES(addr, dat, leng) \ + memp_writes((addr), (dat), (leng)) + +#define MEMR_READ8(seg, off) \ + memr_read8((seg), (off)) +#define MEMR_READ16(seg, off) \ + memr_read16((seg), (off)) +#define MEMR_WRITE8(seg, off, dat) \ + memr_write8((seg), (off), (dat)) +#define MEMR_WRITE16(seg, off, dat) \ + memr_write16((seg), (off), (dat)) +#define MEMR_READS(seg, off, dat, leng) \ + memr_reads((seg), (off), (dat), (leng)) +#define MEMR_WRITES(seg, off, dat, leng) \ + memr_writes((seg), (off), (dat), (leng)) +} diff --git a/source/src/vm/np21/i286c/i286c.cpp b/source/src/vm/np21/i286c/i286c.cpp new file mode 100644 index 000000000..44ebb3985 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c.cpp @@ -0,0 +1,641 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include "v30patch.h" +//#include "pccore.h" +//#include "iocore.h" +//#include "dmax86.h" +#include "i286c.mcr" +#if defined(ENABLE_TRAP) +#include "trap/steptrap.h" +#endif +#if defined(SUPPORT_ASYNC_CPU) +#include "timing.h" +#include "nevent.h" +//#include "sound/sound.h" +//#include "sound/beep.h" +//#include "sound/fmboard.h" +//#include "sound/soundrom.h" +//#include "cbus/mpu98ii.h" +#endif + + +namespace I286_NP21 { + I286CORE i286core; + +const UINT8 iflags[512] = { // Z_FLAG, S_FLAG, P_FLAG + 0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x45, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85}; + + +// ---- + +#if !defined(MEMOPTIMIZE) + UINT8 _szpflag16[0x10000]; +#endif + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) + UINT8 *_reg8_b53[256]; + UINT8 *_reg8_b20[256]; +#endif +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) + UINT16 *_reg16_b53[256]; + UINT16 *_reg16_b20[256]; +#endif + +void i286c_initialize(void) { + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) + UINT i; +#endif + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) + for (i=0; i<0x100; i++) { + int pos; +#if defined(BYTESEX_LITTLE) + pos = ((i & 0x20)?1:0); +#else + pos = ((i & 0x20)?0:1); +#endif + pos += ((i >> 3) & 3) * 2; + _reg8_b53[i] = ((UINT8 *)&I286_REG) + pos; +#if defined(BYTESEX_LITTLE) + pos = ((i & 0x4)?1:0); +#else + pos = ((i & 0x4)?0:1); +#endif + pos += (i & 3) * 2; + _reg8_b20[i] = ((UINT8 *)&I286_REG) + pos; +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) + _reg16_b53[i] = ((UINT16 *)&I286_REG) + ((i >> 3) & 7); + _reg16_b20[i] = ((UINT16 *)&I286_REG) + (i & 7); +#endif + } +#endif + +#if !defined(MEMOPTIMIZE) + for (i=0; i<0x10000; i++) { + REG8 f; + UINT bit; + f = P_FLAG; + for (bit=0x80; bit; bit>>=1) { + if (i & bit) { + f ^= P_FLAG; + } + } + if (!i) { + f |= Z_FLAG; + } + if (i & 0x8000) { + f |= S_FLAG; + } + _szpflag16[i] = f; + } +#endif +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) + i286cea_initialize(); +#endif + v30cinit(); + ZeroMemory(&i286core, sizeof(i286core)); +} + +void i286c_deinitialize(void) { + + if (CPU_EXTMEM) { + _MFREE(CPU_EXTMEM); + CPU_EXTMEM = NULL; + CPU_EXTMEMSIZE = 0; + } +} + +static void i286c_initreg(void) { + + I286_CS = 0xf000; + CS_BASE = 0xf0000; + I286_IP = 0xfff0; + I286_ADRSMASK = 0xfffff; +} + +void i286c_reset(void) { + + ZeroMemory(&i286core.s, sizeof(i286core.s)); + i286c_initreg(); +} + +void i286c_shut(void) { + + ZeroMemory(&i286core.s, offsetof(I286STAT, cpu_type)); + i286c_initreg(); +} + +/* +void i286c_setextsize(UINT32 size) { + + if (CPU_EXTMEMSIZE != size) { + UINT8 *extmem; + extmem = CPU_EXTMEM; + if (extmem != NULL) { + _MFREE(extmem); + extmem = NULL; + } + if (size != 0) { + extmem = (UINT8 *)_MALLOC(size + 16, "EXTMEM"); + } + if (extmem != NULL) { + CPU_EXTMEM = extmem; + CPU_EXTMEMSIZE = size; + CPU_EXTMEMBASE = CPU_EXTMEM - 0x100000; + CPU_EXTLIMIT16 = min(size + 0x100000, 0xf00000); +#if defined(CPU_EXTLIMIT) + CPU_EXTLIMIT = size + 0x100000; +#endif + } + else { + CPU_EXTMEM = NULL; + CPU_EXTMEMSIZE = 0; + CPU_EXTMEMBASE = NULL; + CPU_EXTLIMIT16 = 0; +#if defined(CPU_EXTLIMIT) + CPU_EXTLIMIT = 0; +#endif + } + } + i286core.e.ems[0] = mem + 0xc0000; + i286core.e.ems[1] = mem + 0xc4000; + i286core.e.ems[2] = mem + 0xc8000; + i286core.e.ems[3] = mem + 0xcc000; +} + +void i286c_setemm(UINT frame, UINT32 addr) { + + UINT8 *ptr; + + frame &= 3; + if (addr < USE_HIMEM) { + ptr = mem + addr; + } + else if ((addr - 0x100000 + 0x4000) <= CPU_EXTMEMSIZE) { + ptr = CPU_EXTMEM + (addr - 0x100000); + } + else { + ptr = mem + 0xc0000 + (frame << 14); + } + i286core.e.ems[frame] = ptr; +} +*/ + +void CPUCALL i286c_interrupt_descriptor(UINT vect) { + + #define RIGHTS(desc) ((desc[2] >> 8) & 0xff) + #define GATE(r) (r & 31) + #define GATESEL(desc) (desc[1]) + #define TASKGATE 5 + #define INTGATE 6 + #define TRAPGATE 7 + + I286DTR *idtr = &I286_IDTR; + UINT32 addr = (idtr->base24 << 16) + idtr->base + vect * 8; + UINT16 desc[3], gatedesc[3]; + + desc[0] = i286_memoryread_w(addr + 0); + desc[1] = i286_memoryread_w(addr + 2); + desc[2] = i286_memoryread_w(addr + 4); + + UINT16 rights = RIGHTS(desc); + UINT16 gatesel = GATESEL(desc); + I286DTR *dtr = (gatesel & 4) ? &I286_LDTRC : &I286_GDTR; + + switch(GATE(rights)) { + case TASKGATE: + // not implemented :-( + break; + case INTGATE: + case TRAPGATE: + addr = (dtr->base24 << 16) + dtr->base + (gatesel & (~7)); + gatedesc[0] = i286_memoryread_w(addr + 0); + gatedesc[1] = i286_memoryread_w(addr + 2); + gatedesc[2] = i286_memoryread_w(addr + 4); + rights = RIGHTS(gatedesc); + gatedesc[2] |= 0x100; + i286_memorywrite_w(addr + 4, gatedesc[2]); + I286_IP = desc[0]; + I286_CS = (gatesel & (~3)) | ((rights >> 5) & 3); + CS_BASE = (gatedesc[1] | (gatedesc[2] << 16)) & 0xffffff; + I286_FLAG &= ~T_FLAG; + if (GATE(RIGHTS(desc)) == INTGATE) I286_FLAG &= ~I_FLAG; + break; + default: + break; + } +} + +void CPUCALL i286c_intnum(UINT vect, REG16 IP) { + +//const UINT8 *ptr; + +//#ifdef I86_PSEUDO_BIOS + if (device_bios != NULL) { + uint16_t regs[8] = {CPU_AX, CPU_CX, CPU_DX, CPU_BX, CPU_SP, CPU_BP, CPU_SI, CPU_DI}; + uint16_t sregs[4] = {CPU_ES, CPU_CS, CPU_SS, CPU_DS}; + int32_t ZeroFlag = ((CPU_FLAG & Z_FLAG) ? 1 : 0); + int32_t CarryFlag = ((CPU_FLAG & C_FLAG) ? 1 : 0); + + if (device_bios->bios_int_i86(vect, regs, sregs, &ZeroFlag, &CarryFlag)) { + CPU_AX = regs[0]; + CPU_CX = regs[1]; + CPU_DX = regs[2]; + CPU_BX = regs[3]; + CPU_SP = regs[4]; + CPU_BP = regs[5]; + CPU_SI = regs[6]; + CPU_DI = regs[7]; + if (ZeroFlag) { + CPU_FLAG |= Z_FLAG; + } else { + CPU_FLAG &= ~Z_FLAG; + } + if (CarryFlag) { + CPU_FLAG |= C_FLAG; + } else { + CPU_FLAG &= ~C_FLAG; + } + I286_WORKCLOCK(1000); // temporary + return; + } + } +//#endif + +// if (vect < 0x10) TRACEOUT(("i286c_intnum - %.2x", vect)); + REGPUSH0(REAL_FLAGREG) + REGPUSH0(I286_CS) + REGPUSH0(IP) + + I286_FLAG &= ~(T_FLAG | I_FLAG); + I286_TRAP = 0; + + if(I286_MSW & MSW_PE) { + i286c_interrupt_descriptor(vect); + } else { +// ptr = mem + (vect * 4); + I286_IP = i286_memoryread_w(vect * 4 + 0);//LOADINTELWORD(ptr+0); // real mode! + I286_CS = i286_memoryread_w(vect * 4 + 2);//LOADINTELWORD(ptr+2); // real mode! + CS_BASE = I286_CS << 4; + } + I286_WORKCLOCK(20); +} + +void CPUCALL i286c_interrupt(REG8 vect) { + + UINT op; +//const UINT8 *ptr; + + op = i286_memoryread(I286_IP + CS_BASE); + if (op == 0xf4) { // hlt + I286_IP++; + } + +//#ifdef I86_PSEUDO_BIOS + if (device_bios != NULL) { + uint16_t regs[8] = {CPU_AX, CPU_CX, CPU_DX, CPU_BX, CPU_SP, CPU_BP, CPU_SI, CPU_DI}; + uint16_t sregs[4] = {CPU_ES, CPU_CS, CPU_SS, CPU_DS}; + int32_t ZeroFlag = ((CPU_FLAG & Z_FLAG) ? 1 : 0); + int32_t CarryFlag = ((CPU_FLAG & C_FLAG) ? 1 : 0); + + if (device_bios->bios_int_i86(vect, regs, sregs, &ZeroFlag, &CarryFlag)) { + CPU_AX = regs[0]; + CPU_CX = regs[1]; + CPU_DX = regs[2]; + CPU_BX = regs[3]; + CPU_SP = regs[4]; + CPU_BP = regs[5]; + CPU_SI = regs[6]; + CPU_DI = regs[7]; + if (ZeroFlag) { + CPU_FLAG |= Z_FLAG; + } else { + CPU_FLAG &= ~Z_FLAG; + } + if (CarryFlag) { + CPU_FLAG |= C_FLAG; + } else { + CPU_FLAG &= ~C_FLAG; + } + I286_WORKCLOCK(1000); // temporary + return; + } + } +//#endif + + REGPUSH0(REAL_FLAGREG) // ここV30で辻褄が合わない + REGPUSH0(I286_CS) + REGPUSH0(I286_IP) + + I286_FLAG &= ~(T_FLAG | I_FLAG); + I286_TRAP = 0; + + if(I286_MSW & MSW_PE) { + i286c_interrupt_descriptor(vect); + } else { +// ptr = mem + (vect * 4); + I286_IP = i286_memoryread_w(vect * 4 + 0);//LOADINTELWORD(ptr+0); // real mode! + I286_CS = i286_memoryread_w(vect * 4 + 2);//LOADINTELWORD(ptr+2); // real mode! + CS_BASE = I286_CS << 4; + } + I286_WORKCLOCK(20); +} + +void i286c(void) { + + UINT opcode; + + if (I286_TRAP) { + do { +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_IP); +#endif +//#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +//#endif + GET_PCBYTE(opcode); + i286op[opcode](); + if (I286_TRAP) { + i286c_interrupt(1); + } + dmax86(); + } while(I286_REMCLOCK > 0); + } + else /*if (dmac.working)*/ { + do { +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_IP); +#endif +//#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +//#endif + GET_PCBYTE(opcode); + i286op[opcode](); + dmax86(); + } while(I286_REMCLOCK > 0); + } +/* +#if defined(SUPPORT_ASYNC_CPU) + else if(np2cfg.asynccpu){ + int firstflag = 1; + UINT timing; + UINT lcflag = 0; + SINT32 oldremclock = CPU_REMCLOCK; + static int remclock_mul = 1000; + int remclockb = 0; + int remclkcnt = 0x100; + int repflag = 0; + static int latecount = 0; + static int latecount2 = 0; + static int hltflag = 0; +#define LATECOUNTER_THRESHOLD 6 +#define LATECOUNTER_THRESHOLDM 6 + int realclock = 0; + + if(latecount2==0){ + if(latecount > 0){ + //latecount--; + }else if (latecount < 0){ + latecount++; + } + } + latecount2 = (latecount2+1) & 0x1fff; + + do { +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_IP); +#endif +#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +#endif + GET_PCBYTE(opcode); + i286op[opcode](); + + // 非同期CPU処理 + realclock = 0; + if(CPU_REMCLOCK >= 0 && !realclock && (remclkcnt > 0x7)){ + remclkcnt = 0; + firstflag = 0; + timing = timing_getcount_baseclock(); + if(timing!=0){ + if(!asynccpu_fastflag && !asynccpu_lateflag){ + if(remclock_mul < 100000) { + latecount++; + if(latecount > +LATECOUNTER_THRESHOLD){ + if(pccore.multiple > 2){ + if(pccore.multiple > 40){ + pccore.multiple-=3; + }else if(pccore.multiple > 20){ + pccore.multiple-=2; + }else{ + pccore.multiple-=1; + } + pccore.realclock = pccore.baseclock * pccore.multiple; + + sound_changeclock(); + beep_changeclock(); + mpu98ii_changeclock(); + keyboard_changeclock(); + mouseif_changeclock(); + gdc_updateclock(); + } + + latecount = 0; + } + } + asynccpu_lateflag = 1; + } + CPU_REMCLOCK = 0; + break; + }else{ + if(!hltflag && !asynccpu_lateflag && g_nevent.item[NEVENT_FLAMES].proc==screendisp && g_nevent.item[NEVENT_FLAMES].clock <= CPU_BASECLOCK){ + //CPU_REMCLOCK = 10000; + //oldremclock = CPU_REMCLOCK; + if(!asynccpu_fastflag){ + latecount--; + if(latecount < -LATECOUNTER_THRESHOLDM){ + if(pccore.multiple < np2cfg.multiple){ + pccore.multiple+=1; + pccore.realclock = pccore.baseclock * pccore.multiple; + + sound_changeclock(); + beep_changeclock(); + mpu98ii_changeclock(); + keyboard_changeclock(); + mouseif_changeclock(); + gdc_updateclock(); + + latecount = 0; + } + } + asynccpu_fastflag = 1; + } + } + firstflag = 1; + } + } + remclkcnt++; + } while(I286_REMCLOCK > 0); + } +#endif + else { + do { +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_IP); +#endif +#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +#endif + GET_PCBYTE(opcode); + i286op[opcode](); + } while(I286_REMCLOCK > 0); + } +*/ +} + +void i286c_step(void) { + + UINT opcode; + + I286_OV = I286_FLAG & O_FLAG; + I286_FLAG &= ~(O_FLAG); + +//#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +//#endif + GET_PCBYTE(opcode); + i286op[opcode](); + + I286_FLAG &= ~(O_FLAG); + if (I286_OV) { + I286_FLAG |= (O_FLAG); + } + dmax86(); +} + + +// ---- test + +#if defined(I286C_TEST) +UINT8 BYTESZPF(UINT r) { + + if (r & (~0xff)) { + TRACEOUT(("BYTESZPF bound error: %x", r)); + } + return(iflags[r & 0xff]); +} + +UINT8 BYTESZPCF(UINT r) { + + if (r & (~0x1ff)) { + TRACEOUT(("BYTESZPCF bound error: %x", r)); + } + return(iflags[r & 0x1ff]); +} + +UINT8 WORDSZPF(UINT32 r) { + + UINT8 f1; + UINT8 f2; + + if (r & (~0xffff)) { + TRACEOUT(("WORDSZPF bound error: %x", r)); + } + f1 = _szpflag16[r & 0xffff]; + f2 = iflags[r & 0xff] & P_FLAG; + f2 += (r)?0:Z_FLAG; + f2 += (r >> 8) & S_FLAG; + if (f1 != f2) { + TRACEOUT(("word flag error: %.2x %.2x", f1, f2)); + } + return(f1); +} + +UINT8 WORDSZPCF(UINT32 r) { + + UINT8 f1; + UINT8 f2; + + if ((r & 0xffff0000) && (!(r & 0x00010000))) { + TRACEOUT(("WORDSZPCF bound error: %x", r)); + } + f1 = (r >> 16) & 1; + f1 += _szpflag16[LOW16(r)]; + + f2 = iflags[r & 0xff] & P_FLAG; + f2 += (LOW16(r))?0:Z_FLAG; + f2 += (r >> 8) & S_FLAG; + f2 += (r >> 16) & 1; + + if (f1 != f2) { + TRACEOUT(("word flag error: %.2x %.2x", f1, f2)); + } + return(f1); +} +#endif +} diff --git a/source/src/vm/np21/i286c/i286c.h b/source/src/vm/np21/i286c/i286c.h new file mode 100644 index 000000000..216b5c7cb --- /dev/null +++ b/source/src/vm/np21/i286c/i286c.h @@ -0,0 +1,182 @@ + +//#define INTR_FAST + +// #define I286C_TEST +#if defined(I286C_TEST) +#undef MEMOPTIMIZE +#endif + +namespace I286_NP21 { +#define I286_STAT i286core.s.r + +#define I286_REG i286core.s.r +#define I286_SEGREG i286core.s.r.w.es + +#define I286_AX i286core.s.r.w.ax +#define I286_BX i286core.s.r.w.bx +#define I286_CX i286core.s.r.w.cx +#define I286_DX i286core.s.r.w.dx +#define I286_SI i286core.s.r.w.si +#define I286_DI i286core.s.r.w.di +#define I286_BP i286core.s.r.w.bp +#define I286_SP i286core.s.r.w.sp +#define I286_CS i286core.s.r.w.cs +#define I286_DS i286core.s.r.w.ds +#define I286_ES i286core.s.r.w.es +#define I286_SS i286core.s.r.w.ss +#define I286_IP i286core.s.r.w.ip + +#define SEG_BASE i286core.s.es_base +#define ES_BASE i286core.s.es_base +#define CS_BASE i286core.s.cs_base +#define SS_BASE i286core.s.ss_base +#define DS_BASE i286core.s.ds_base +#define SS_FIX i286core.s.ss_fix +#define DS_FIX i286core.s.ds_fix + +#define I286_AL i286core.s.r.b.al +#define I286_BL i286core.s.r.b.bl +#define I286_CL i286core.s.r.b.cl +#define I286_DL i286core.s.r.b.dl +#define I286_AH i286core.s.r.b.ah +#define I286_BH i286core.s.r.b.bh +#define I286_CH i286core.s.r.b.ch +#define I286_DH i286core.s.r.b.dh + +#define I286_FLAG i286core.s.r.w.flag +#define I286_FLAGL i286core.s.r.b.flag_l +#define I286_FLAGH i286core.s.r.b.flag_h +#define I286_TRAP i286core.s.trap +#define I286_OV i286core.s.ovflag + +#define I286_GDTR i286core.s.GDTR +#define I286_IDTR i286core.s.IDTR +#define I286_LDTR i286core.s.LDTR +#define I286_LDTRC i286core.s.LDTRC +#define I286_TR i286core.s.TR +#define I286_TRC i286core.s.TRC +#define I286_MSW i286core.s.MSW + +#define I286_REMCLOCK i286core.s.remainclock +#define I286_BASECLOCK i286core.s.baseclock +#define I286_CLOCK i286core.s.clock +#define I286_ADRSMASK i286core.s.adrsmask + +#define I286_PREFIX i286core.s.prefix + +#define I286_INPADRS i286core.e.inport + + +#define I286FN static void +#define I286EXT void + +typedef void (*I286OP)(void); + +extern void CPUCALL i286c_intnum(UINT vect, REG16 IP); +extern UINT32 i286c_selector(UINT sel); + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) +extern void i286cea_initialize(void); +#endif + +extern const I286OP i286op[]; +extern const I286OP i286op_repe[]; +extern const I286OP i286op_repne[]; + +#define I286_0F static void CPUCALL +typedef void (CPUCALL * I286OP_0F)(UINT op); + +I286EXT i286c_cts(void); + + +#define I286_8X static void CPUCALL +typedef void (CPUCALL * I286OP8XREG8)(UINT8 *p); +typedef void (CPUCALL * I286OP8XEXT8)(UINT32 madr); +typedef void (CPUCALL * I286OP8XREG16)(UINT16 *p, UINT32 src); +typedef void (CPUCALL * I286OP8XEXT16)(UINT32 madr, UINT32 src); + +extern const I286OP8XREG8 c_op8xreg8_table[]; +extern const I286OP8XEXT8 c_op8xext8_table[]; +extern const I286OP8XREG16 c_op8xreg16_table[]; +extern const I286OP8XEXT16 c_op8xext16_table[]; + + +#define I286_SFT static void CPUCALL +typedef void (CPUCALL * I286OPSFTR8)(UINT8 *p); +typedef void (CPUCALL * I286OPSFTE8)(UINT32 madr); +typedef void (CPUCALL * I286OPSFTR16)(UINT16 *p); +typedef void (CPUCALL * I286OPSFTE16)(UINT32 madr); +typedef void (CPUCALL * I286OPSFTR8CL)(UINT8 *p, REG8 cl); +typedef void (CPUCALL * I286OPSFTE8CL)(UINT32 madr, REG8 cl); +typedef void (CPUCALL * I286OPSFTR16CL)(UINT16 *p, REG8 cl); +typedef void (CPUCALL * I286OPSFTE16CL)(UINT32 madr, REG8 cl); + +extern const I286OPSFTR8 sft_r8_table[]; +extern const I286OPSFTE8 sft_e8_table[]; +extern const I286OPSFTR16 sft_r16_table[]; +extern const I286OPSFTE16 sft_e16_table[]; +extern const I286OPSFTR8CL sft_r8cl_table[]; +extern const I286OPSFTE8CL sft_e8cl_table[]; +extern const I286OPSFTR16CL sft_r16cl_table[]; +extern const I286OPSFTE16CL sft_e16cl_table[]; + + +#define I286_F6 static void CPUCALL +typedef void (CPUCALL * I286OPF6)(UINT op); + +extern const I286OPF6 c_ope0xf6_table[]; +extern const I286OPF6 c_ope0xf7_table[]; + + +extern const I286OPF6 c_ope0xfe_table[]; +extern const I286OPF6 c_ope0xff_table[]; + + +extern I286EXT i286c_rep_insb(void); +extern I286EXT i286c_rep_insw(void); +extern I286EXT i286c_rep_outsb(void); +extern I286EXT i286c_rep_outsw(void); +extern I286EXT i286c_rep_movsb(void); +extern I286EXT i286c_rep_movsw(void); +extern I286EXT i286c_rep_lodsb(void); +extern I286EXT i286c_rep_lodsw(void); +extern I286EXT i286c_rep_stosb(void); +extern I286EXT i286c_rep_stosw(void); +extern I286EXT i286c_repe_cmpsb(void); +extern I286EXT i286c_repne_cmpsb(void); +extern I286EXT i286c_repe_cmpsw(void); +extern I286EXT i286c_repne_cmpsw(void); +extern I286EXT i286c_repe_scasb(void); +extern I286EXT i286c_repne_scasb(void); +extern I286EXT i286c_repe_scasw(void); +extern I286EXT i286c_repne_scasw(void); + +extern I286EXT _jo_short(void); +extern I286EXT _jno_short(void); +extern I286EXT _jc_short(void); +extern I286EXT _jnc_short(void); +extern I286EXT _jz_short(void); +extern I286EXT _jnz_short(void); +extern I286EXT _jna_short(void); +extern I286EXT _ja_short(void); +extern I286EXT _js_short(void); +extern I286EXT _jns_short(void); +extern I286EXT _jp_short(void); +extern I286EXT _jnp_short(void); +extern I286EXT _jl_short(void); +extern I286EXT _jnl_short(void); +extern I286EXT _jle_short(void); +extern I286EXT _jnle_short(void); +extern I286EXT _ret_near_data16(void); +extern I286EXT _ret_near(void); +extern I286EXT _ret_far_data16(void); +extern I286EXT _ret_far(void); + + +#define i286_memoryread(a) memp_read8(a) +#define i286_memoryread_w(a) memp_read16(a) +#define i286_memoryread_d(a) memp_read32(a) +#define i286_memorywrite(a, v) memp_write8(a, v) +#define i286_memorywrite_w(a, v) memp_write16(a, v) +#define i286_memorywrite_d(a, v) memp_write32(a, v) +} diff --git a/source/src/vm/np21/i286c/i286c.mcr b/source/src/vm/np21/i286c/i286c.mcr new file mode 100644 index 000000000..e52fa260b --- /dev/null +++ b/source/src/vm/np21/i286c/i286c.mcr @@ -0,0 +1,498 @@ +/* +#if defined(X11) && (defined(i386) || defined(__i386__)) +#define INHIBIT_WORDP(m) ((m) >= (I286_MEMWRITEMAX - 1)) +#elif (defined(ARM) || defined(X11)) && defined(BYTESEX_LITTLE) +#define INHIBIT_WORDP(m) (((m) & 1) || ((m) >= I286_MEMWRITEMAX)) +#else +#define INHIBIT_WORDP(m) (1) +#endif +*/ + +namespace I286_NP21 { +#define __CBW(src) (UINT16)((SINT8)(src)) +#define __CBD(src) ((SINT8)(src)) +#define WORD2LONG(src) ((SINT16)(src)) + + +#define SEGMENTPTR(s) (((UINT16 *)&I286_SEGREG) + (s)) + +#define REAL_FLAGREG (UINT16)((I286_FLAG & 0x7ff) | (I286_OV?O_FLAG:0) | 2) + +#define STRING_DIR ((I286_FLAG & D_FLAG)?-1:1) +#define STRING_DIRx2 ((I286_FLAG & D_FLAG)?-2:2) + + +// ---- flags + +#if defined(I286C_TEST) + +extern UINT8 BYTESZPF(UINT r); +extern UINT8 BYTESZPCF(UINT r); +#define BYTESZPCF2(a) BYTESZPCF((a) & 0x1ff) +extern UINT8 WORDSZPF(UINT32 r); +extern UINT8 WORDSZPCF(UINT32 r); + +#elif !defined(MEMOPTIMIZE) + +extern UINT8 _szpflag16[0x10000]; +#define BYTESZPF(a) (iflags[(a)]) +#define BYTESZPCF(a) (iflags[(a)]) +#define BYTESZPCF2(a) (iflags[(a) & 0x1ff]) +#define WORDSZPF(a) (_szpflag16[(a)]) +#define WORDSZPCF(a) (_szpflag16[LOW16(a)] + (((a) >> 16) & 1)) + +#else + +#define BYTESZPF(a) (iflags[(a)]) +#define BYTESZPCF(a) (iflags[(a)]) +#define BYTESZPCF2(a) (iflags[(a) & 0x1ff]) +#define WORDSZPF(a) ((iflags[(a) & 0xff] & P_FLAG) + \ + (((a))?0:Z_FLAG) + (((a) >> 8) & S_FLAG)) +#define WORDSZPCF(a) ((iflags[(a) & 0xff] & P_FLAG) + \ + ((LOW16(a))?0:Z_FLAG) + (((a) >> 8) & S_FLAG) + \ + (((a) >> 16) & 1)) + +#endif + + +// ---- reg position + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) +extern UINT8 *_reg8_b53[256]; +extern UINT8 *_reg8_b20[256]; +#define REG8_B53(op) _reg8_b53[(op)] +#define REG8_B20(op) _reg8_b20[(op)] +#else +#if defined(BYTESEX_LITTLE) +#define REG8_B53(op) \ + (((UINT8 *)&I286_REG) + (((op) >> 2) & 6) + (((op) >> 5) & 1)) +#define REG8_B20(op) \ + (((UINT8 *)&I286_REG) + (((op) & 3) * 2) + (((op) >> 2) & 1)) +#else +#define REG8_B53(op) (((UINT8 *)&I286_REG) + (((op) >> 2) & 6) + \ + ((((op) >> 5) & 1) ^ 1)) +#define REG8_B20(op) (((UINT8 *)&I286_REG) + (((op) & 3) * 2) + \ + ((((op) >> 2) & 1) ^ 1)) +#endif +#endif + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) +extern UINT16 *_reg16_b53[256]; +extern UINT16 *_reg16_b20[256]; +#define REG16_B53(op) _reg16_b53[(op)] +#define REG16_B20(op) _reg16_b20[(op)] +#else +#define REG16_B53(op) (((UINT16 *)&I286_REG) + (((op) >> 3) & 7)) +#define REG16_B20(op) (((UINT16 *)&I286_REG) + ((op) & 7)) +#endif + + +// ---- ea + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) +typedef UINT32 (*CALCEA)(void); +typedef UINT16 (*CALCLEA)(void); +typedef UINT (*GETLEA)(UINT32 *seg); +extern CALCEA _calc_ea_dst[]; +extern CALCLEA _calc_lea[]; +extern GETLEA _get_ea[]; +#define CALC_EA(o) (_calc_ea_dst[(o)]()) +#define CALC_LEA(o) (_calc_lea[(o)]()) +#define GET_EA(o, s) (_get_ea[(o)](s)) +#else +extern UINT32 calc_ea_dst(UINT op); +extern UINT16 calc_lea(UINT op); +extern UINT calc_a(UINT op, UINT32 *seg); +#define CALC_EA(o) (calc_ea_dst(o)) +#define CALC_LEA(o) (calc_lea(o)) +#define GET_EA(o, s) (calc_a(o, s)) +#endif + + +#define SWAPBYTE(p, q) { \ + REG8 tmp; \ + tmp = (p); \ + (p) = (q); \ + (q) = tmp; \ + } + +#define SWAPWORD(p, q) { \ + REG16 tmp; \ + tmp = (p); \ + (p) = (q); \ + (q) = tmp; \ + } + + +#define I286IRQCHECKTERM \ + if (I286_REMCLOCK > 0) { \ + I286_BASECLOCK -= I286_REMCLOCK; \ + I286_REMCLOCK = 0; \ + } + + +#define REMOVE_PREFIX \ + SS_FIX = SS_BASE; \ + DS_FIX = DS_BASE; + + +#define I286_WORKCLOCK(c) I286_REMCLOCK -= (c) + + +#define GET_PCBYTE(b) \ + (b) = i286_memoryread(CS_BASE + I286_IP); \ + I286_IP++; + + +#define GET_PCBYTES(b) \ + (b) = __CBW(i286_memoryread(CS_BASE + I286_IP)); \ + I286_IP++; + + +#define GET_PCBYTESD(b) \ + (b) = __CBD(i286_memoryread(CS_BASE + I286_IP)); \ + I286_IP++; + + +#define GET_PCWORD(b) \ + (b) = i286_memoryread_w(CS_BASE + I286_IP); \ + I286_IP += 2; + + +#define PREPART_EA_REG8(b, d_s) \ + GET_PCBYTE((b)) \ + (d_s) = *(REG8_B53(b)); + + +#define PREPART_EA_REG8P(b, d_s) \ + GET_PCBYTE((b)) \ + (d_s) = REG8_B53(b); + + +#define PREPART_EA_REG16(b, d_s) \ + GET_PCBYTE((b)) \ + (d_s) = *(REG16_B53(b)); + + +#define PREPART_EA_REG16P(b, d_s) \ + GET_PCBYTE((b)) \ + (d_s) = REG16_B53(b); + + +#define PREPART_REG8_EA(b, s, d, regclk, memclk) \ + GET_PCBYTE((b)) \ + if ((b) >= 0xc0) { \ + I286_WORKCLOCK(regclk); \ + (s) = *(REG8_B20(b)); \ + } \ + else { \ + I286_WORKCLOCK(memclk); \ + (s) = i286_memoryread(CALC_EA(b)); \ + } \ + (d) = REG8_B53(b); + + +#define PREPART_REG16_EA(b, s, d, regclk, memclk) \ + GET_PCBYTE(b) \ + if (b >= 0xc0) { \ + I286_WORKCLOCK(regclk); \ + s = *(REG16_B20(b)); \ + } \ + else { \ + I286_WORKCLOCK(memclk); \ + s = i286_memoryread_w(CALC_EA(b)); \ + } \ + d = REG16_B53(b); + + +#define ADDBYTE(r, d, s) \ + (r) = (s) + (d); \ + I286_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80; \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPCF(r); + +#define ADDWORD(r, d, s) \ + (r) = (s) + (d); \ + I286_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= WORDSZPCF(r); + + +// flag no check +#define ORBYTE(d, s) \ + (d) |= (s); \ + I286_OV = 0; \ + I286_FLAGL = BYTESZPF(d); + +#define ORWORD(d, s) \ + (d) |= (s); \ + I286_OV = 0; \ + I286_FLAGL = WORDSZPF(d); + + +#define ADCBYTE(r, d, s) \ + (r) = (I286_FLAGL & 1) + (s) + (d); \ + I286_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80; \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPCF(r); + +#define ADCWORD(r, d, s) \ + (r) = (I286_FLAGL & 1) + (s) + (d); \ + I286_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= WORDSZPCF(r); + + +// flag no check +#define SBBBYTE(r, d, s) \ + (r) = (d) - (s) - (I286_FLAGL & 1); \ + I286_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPCF2(r); + +#define SBBWORD(r, d, s) \ + (r) = (d) - (s) - (I286_FLAGL & 1); \ + I286_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x8000; \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= WORDSZPCF(r); + + +// flag no check +#define ANDBYTE(d, s) \ + (d) &= (s); \ + I286_OV = 0; \ + I286_FLAGL = BYTESZPF(d); + +#define ANDWORD(d, s) \ + (d) &= (s); \ + I286_OV = 0; \ + I286_FLAGL = WORDSZPF(d); + + +// flag no check +#define SUBBYTE(r, d, s) \ + (r) = (d) - (s); \ + I286_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ + I286_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPCF2(r); + +#define SUBWORD(r, d, s) \ + (r) = (d) - (s); \ + I286_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x8000; \ + I286_FLAGL = ((r) ^ (d) ^ (s)) & A_FLAG; \ + I286_FLAGL |= WORDSZPCF(r); + + +// flag no check +#define XORBYTE(d, s) \ + (d) ^= s; \ + I286_OV = 0; \ + I286_FLAGL = BYTESZPF(d); + +#define XORWORD(d, s) \ + (d) ^= (s); \ + I286_OV = 0; \ + I286_FLAGL = WORDSZPF(d); + + +#define NEGBYTE(d, s) \ + (d) = 0 - (s); \ + I286_OV = ((d) & (s)) & 0x80; \ + I286_FLAGL = (UINT8)(((d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPCF2(d); + +#define NEGWORD(d, s) \ + (d) = 0 - (s); \ + I286_OV = ((d) & (s)) & 0x8000; \ + I286_FLAGL = (UINT8)(((d) ^ (s)) & A_FLAG); \ + I286_FLAGL |= WORDSZPCF(d); + + +#define BYTE_MUL(r, d, s) \ + I286_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (UINT8)(d) * (UINT8)(s); \ + I286_OV = (r) >> 8; \ + if (I286_OV) { \ + I286_FLAGL |= C_FLAG; \ + } + +#define WORD_MUL(r, d, s) \ + I286_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (UINT16)(d) * (UINT16)(s); \ + I286_OV = (r) >> 16; \ + if (I286_OV) { \ + I286_FLAGL |= C_FLAG; \ + } + + +#define BYTE_IMUL(r, d, s) \ + I286_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SINT8)(d) * (SINT8)(s); \ + I286_OV = ((r) + 0x80) & 0xffffff00; \ + if (I286_OV) { \ + I286_FLAGL |= C_FLAG; \ + } + +#define WORD_IMUL(r, d, s) \ + I286_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SINT16)(d) * (SINT16)(s); \ + I286_OV = ((r) + 0x8000) & 0xffff0000; \ + if (I286_OV) { \ + I286_FLAGL |= C_FLAG; \ + } + + +// flag no check +#define INCBYTE(s) { \ + UINT b = (s); \ + (s)++; \ + I286_OV = (s) & (b ^ (s)) & 0x80; \ + I286_FLAGL &= C_FLAG; \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPF((UINT8)(s)); \ + } + +#define INCWORD(s) { \ + UINT32 b = (s); \ + (s)++; \ + I286_OV = (s) & (b ^ (s)) & 0x8000; \ + I286_FLAGL &= C_FLAG; \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= WORDSZPF((UINT16)(s)); \ + } + + +// flag no check +#define DECBYTE(s) { \ + UINT b = (s); \ + b--; \ + I286_OV = (s) & (b ^ (s)) & 0x80; \ + I286_FLAGL &= C_FLAG; \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= BYTESZPF((UINT8)b); \ + (s) = b; \ + } + +#define DECWORD(s) { \ + UINT32 b = (s); \ + b--; \ + I286_OV = (s) & (b ^ (s)) & 0x8000; \ + I286_FLAGL &= C_FLAG; \ + I286_FLAGL |= (UINT8)((b ^ (s)) & A_FLAG); \ + I286_FLAGL |= WORDSZPF((UINT16)b); \ + (s) = b; \ + } + + +// flag no check +#define INCWORD2(r, clock) { \ + REG16 s = (r); \ + REG16 d = (r); \ + d++; \ + (r) = (UINT16)d; \ + I286_OV = d & (d ^ s) & 0x8000; \ + I286_FLAGL &= C_FLAG; \ + I286_FLAGL |= (UINT8)((d ^ s) & A_FLAG); \ + I286_FLAGL |= WORDSZPF((UINT16)d); \ + I286_WORKCLOCK(clock); \ + } + +#define DECWORD2(r, clock) { \ + REG16 s = (r); \ + REG16 d = (r); \ + d--; \ + (r) = (UINT16)d; \ + I286_OV = s & (d ^ s) & 0x8000; \ + I286_FLAGL &= C_FLAG; \ + I286_FLAGL |= (UINT8)((d ^ s) & A_FLAG); \ + I286_FLAGL |= WORDSZPF((UINT16)d); \ + I286_WORKCLOCK(clock); \ + } + + +// ---- stack + +#define REGPUSH0(reg) \ + I286_SP -= 2; \ + i286_memorywrite_w(I286_SP + SS_BASE, reg); + +#define REGPOP0(reg) \ + reg = i286_memoryread_w(I286_SP + SS_BASE); \ + I286_SP += 2; + +#if (defined(ARM) || defined(X11)) && defined(BYTESEX_LITTLE) + +#define REGPUSH(reg, clock) { \ + UINT32 addr; \ + I286_WORKCLOCK(clock); \ + I286_SP -= 2; \ + addr = I286_SP + SS_BASE; \ + i286_memorywrite_w(addr, reg); \ + } + +#define REGPOP(reg, clock) { \ + UINT32 addr; \ + I286_WORKCLOCK(clock); \ + addr = I286_SP + SS_BASE; \ + (reg) = i286_memoryread_w(addr); \ + I286_SP += 2; \ + } + +#else + +#define REGPUSH(reg, clock) { \ + I286_WORKCLOCK(clock); \ + I286_SP -= 2; \ + i286_memorywrite_w(I286_SP + SS_BASE, reg); \ + } + +#define REGPOP(reg, clock) { \ + I286_WORKCLOCK(clock); \ + reg = i286_memoryread_w(I286_SP + SS_BASE); \ + I286_SP += 2; \ + } + +#endif + +#define SP_PUSH(reg, clock) { \ + REG16 sp = (reg); \ + I286_SP -= 2; \ + i286_memorywrite_w(I286_SP + SS_BASE, sp); \ + I286_WORKCLOCK(clock); \ + } + +#define SP_POP(reg, clock) { \ + I286_WORKCLOCK(clock); \ + reg = i286_memoryread_w(I286_SP + SS_BASE); \ + } + + +#define JMPSHORT(clock) { \ + I286_WORKCLOCK(clock); \ + I286_IP += __CBW(i286_memoryread(CS_BASE + I286_IP)); \ + I286_IP++; \ + } + + +#define JMPNOP(clock) { \ + I286_WORKCLOCK(clock); \ + I286_IP++; \ + } + + +#define MOVIMM8(reg) { \ + I286_WORKCLOCK(2); \ + GET_PCBYTE(reg) \ + } + + +#define MOVIMM16(reg) { \ + I286_WORKCLOCK(2); \ + GET_PCWORD(reg) \ + } + + +#define SEGSELECT(c) ((I286_MSW & MSW_PE)?i286c_selector(c):((c) << 4)) + +#define INT_NUM(a, b) i286c_intnum((a), (REG16)(b)) +} diff --git a/source/src/vm/np21/i286c/i286c_0f.cpp b/source/src/vm/np21/i286c/i286c_0f.cpp new file mode 100644 index 000000000..b93de6149 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_0f.cpp @@ -0,0 +1,290 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include "i286c.mcr" + +namespace I286_NP21 { + +I286_0F _sldt(UINT op) { + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG16_B20(op)) = I286_LDTR; + } + else { + I286_WORKCLOCK(3); + i286_memorywrite_w(CALC_EA(op), I286_LDTR); + } +} + +I286_0F _str(UINT op) { + + if (op >= 0xc0) { + I286_WORKCLOCK(3); + *(REG16_B20(op)) = I286_TR; + } + else { + I286_WORKCLOCK(6); + i286_memorywrite_w(CALC_EA(op), I286_TR); + } +} + +I286_0F _lldt(UINT op) { + + REG16 r; + UINT32 addr; + + if (op >= 0xc0) { + I286_WORKCLOCK(17); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(19); + r = i286_memoryread_w(CALC_EA(op)); + } + addr = i286c_selector(r); + I286_LDTR = r; + I286_LDTRC.limit = i286_memoryread_w(addr); + I286_LDTRC.base = i286_memoryread_w(addr + 2); + I286_LDTRC.base24 = i286_memoryread(addr + 4); +} + +I286_0F _ltr(UINT op) { + + REG16 r; + UINT32 addr; + + if (op >= 0xc0) { + I286_WORKCLOCK(17); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(19); + r = i286_memoryread_w(CALC_EA(op)); + } + addr = i286c_selector(r); + I286_TR = r; + I286_TRC.limit = i286_memoryread_w(addr); + I286_TRC.base = i286_memoryread_w(addr + 2); + I286_TRC.base24 = i286_memoryread(addr + 4); +} + +I286_0F _verr(UINT op) { + + REG16 r; + + if (op >= 0xc0) { + I286_WORKCLOCK(14); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(16); + r = i286_memoryread_w(CALC_EA(op)); + } +} + +I286_0F _verw(UINT op) { + + REG16 r; + + if (op >= 0xc0) { + I286_WORKCLOCK(14); + r = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(16); + r = i286_memoryread_w(CALC_EA(op)); + } +} + +I286_0F __sgdt(UINT op) { + + UINT32 addr; + + I286_WORKCLOCK(11); + if (op < 0xc0) { + addr = CALC_EA(op); + i286_memorywrite_w(addr, I286_GDTR.limit); + i286_memorywrite_w(addr + 2, I286_GDTR.base); + i286_memorywrite_w(addr + 4, (REG16)(0xff00 + I286_GDTR.base24)); + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286_0F _sidt(UINT op) { + + UINT32 addr; + + I286_WORKCLOCK(12); + if (op < 0xc0) { + addr = CALC_EA(op); + i286_memorywrite_w(addr, I286_IDTR.limit); + i286_memorywrite_w(addr + 2, I286_IDTR.base); + i286_memorywrite_w(addr + 4, (REG16)(0xff00 + I286_IDTR.base24)); + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286_0F __lgdt(UINT op) { + + UINT32 addr; + + I286_WORKCLOCK(11); + if (op < 0xc0) { + addr = CALC_EA(op); + I286_GDTR.limit = i286_memoryread_w(addr); + I286_GDTR.base = i286_memoryread_w(addr + 2); + I286_GDTR.base24 = i286_memoryread(addr + 4); + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286_0F _lidt(UINT op) { + + UINT32 addr; + + I286_WORKCLOCK(12); + if (op < 0xc0) { + addr = CALC_EA(op); + I286_IDTR.limit = i286_memoryread_w(addr); + I286_IDTR.base = i286_memoryread_w(addr + 2); + I286_IDTR.base24 = i286_memoryread(addr + 4); + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286_0F _smsw(UINT op) { + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG16_B20(op)) = I286_MSW; + } + else { + I286_WORKCLOCK(3); + i286_memorywrite_w(CALC_EA(op), I286_MSW); + } +} + +I286_0F _lmsw(UINT op) { + + REG16 msw; + + if (op >= 0xc0) { + I286_WORKCLOCK(3); + msw = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(6); + msw = i286_memoryread_w(CALC_EA(op)); + } + I286_MSW = msw | (I286_MSW & MSW_PE); + if (msw & MSW_PE) { + TRACEOUT(("80286 ProtectMode Enable... / MSW=%.4x [%.4x:%.4x]", + I286_MSW, I286_CS, I286_IP)); + } +} + +static const I286OP_0F cts0_table[] = { + _sldt, _str, _lldt, _ltr, + _verr, _verw, _verr, _verw}; + +static const I286OP_0F cts1_table[] = { + __sgdt, _sidt, __lgdt, _lidt, + _smsw, _smsw, _lmsw, _lmsw}; + + +I286_0F _loadall286(void) { + + UINT16 tmp; + UINT32 base; + + I286_WORKCLOCK(195); + I286_MSW = i286_memoryread_w(0x804);//LOADINTELWORD(mem + 0x804); + I286_TR = i286_memoryread_w(0x816);//LOADINTELWORD(mem + 0x816); // ver0.73 + tmp = i286_memoryread_w(0x818);//LOADINTELWORD(mem + 0x818); + I286_OV = tmp & O_FLAG; + I286_FLAG = tmp & (0xfff ^ O_FLAG); + I286_TRAP = ((tmp & 0x300) == 0x300); + I286_IP = i286_memoryread_w(0x81a);//LOADINTELWORD(mem + 0x81a); + I286_LDTR = i286_memoryread_w(0x81c);//LOADINTELWORD(mem + 0x81c); // ver0.73 + I286_DS = i286_memoryread_w(0x81e);//LOADINTELWORD(mem + 0x81e); + I286_SS = i286_memoryread_w(0x820);//LOADINTELWORD(mem + 0x820); + I286_CS = i286_memoryread_w(0x822);//LOADINTELWORD(mem + 0x822); + I286_ES = i286_memoryread_w(0x824);//LOADINTELWORD(mem + 0x824); + I286_DI = i286_memoryread_w(0x826);//LOADINTELWORD(mem + 0x826); + I286_SI = i286_memoryread_w(0x828);//LOADINTELWORD(mem + 0x828); + I286_BP = i286_memoryread_w(0x82a);//LOADINTELWORD(mem + 0x82a); + I286_SP = i286_memoryread_w(0x82c);//LOADINTELWORD(mem + 0x82c); + I286_BX = i286_memoryread_w(0x82e);//LOADINTELWORD(mem + 0x82e); + I286_DX = i286_memoryread_w(0x830);//LOADINTELWORD(mem + 0x830); + I286_CX = i286_memoryread_w(0x832);//LOADINTELWORD(mem + 0x832); + I286_AX = i286_memoryread_w(0x834);//LOADINTELWORD(mem + 0x834); + base = i286_memoryread_d(0x836) & 0x00ffffff;//LOADINTELDWORD(mem + 0x836) & 0x00ffffff; + ES_BASE = base; + base = i286_memoryread_d(0x83c) & 0x00ffffff;//LOADINTELDWORD(mem + 0x83c) & 0x00ffffff; + CS_BASE = base; + base = i286_memoryread_d(0x842) & 0x00ffffff;//LOADINTELDWORD(mem + 0x842) & 0x00ffffff; + SS_BASE = base; + SS_FIX = base; + base = i286_memoryread_d(0x848) & 0x00ffffff;//LOADINTELDWORD(mem + 0x848) & 0x00ffffff; + DS_BASE = base; + DS_FIX = base; + + I286_GDTR.base = i286_memoryread_w(0x84e);//LOADINTELWORD(mem + 0x84e); + *(UINT16 *)(&I286_GDTR.base24) = i286_memoryread_w(0x850);//LOADINTELWORD(mem + 0x850); + I286_GDTR.limit = i286_memoryread_w(0x852);//LOADINTELWORD(mem + 0x852); + + I286_LDTRC.base = i286_memoryread_w(0x854);//LOADINTELWORD(mem + 0x854); + *(UINT16 *)(&I286_LDTRC.base24) = i286_memoryread_w(0x856);//LOADINTELWORD(mem + 0x856); + I286_LDTRC.limit = i286_memoryread_w(0x858);//LOADINTELWORD(mem + 0x858); + + I286_IDTR.base = i286_memoryread_w(0x85a);//LOADINTELWORD(mem + 0x85a); + *(UINT16 *)(&I286_IDTR.base24) = i286_memoryread_w(0x85c);//LOADINTELWORD(mem + 0x85c); + I286_IDTR.limit = i286_memoryread_w(0x85e);//LOADINTELWORD(mem + 0x85e); + + I286_TRC.base = i286_memoryread_w(0x860);//LOADINTELWORD(mem + 0x860); + *(UINT16 *)(&I286_TRC.base24) = i286_memoryread_w(0x8620);//LOADINTELWORD(mem + 0x8620); + I286_TRC.limit = i286_memoryread_w(0x864);//LOADINTELWORD(mem + 0x864); + + I286IRQCHECKTERM +} + +I286EXT i286c_cts(void) { + + UINT16 ip; + UINT op; + UINT op2; + + ip = I286_IP; + GET_PCBYTE(op); + + if (op == 0) { + if (!(I286_MSW & MSW_PE)) { + INT_NUM(6, ip - 1); + } + else { + GET_PCBYTE(op2); + cts0_table[(op2 >> 3) & 7](op2); + } + } + else if (op == 1) { + GET_PCBYTE(op2); + cts1_table[(op2 >> 3) & 7](op2); + } + else if (op == 5) { + _loadall286(); + } + else { + INT_NUM(6, ip - 1); + } +} + +} diff --git a/source/src/vm/np21/i286c/i286c_8x.cpp b/source/src/vm/np21/i286c/i286c_8x.cpp new file mode 100644 index 000000000..fb366ac58 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_8x.cpp @@ -0,0 +1,376 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include "i286c.mcr" + +namespace I286_NP21 { + +// -------------------------------------------------------- opecode 0x80,1,2,3 + +// ----- reg8 + +I286_8X _add_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = *p; + ADDBYTE(res, dst, src); + *p = (UINT8)res; +} + +I286_8X _or_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + + GET_PCBYTE(src) + dst = *p; + ORBYTE(dst, src); + *p = (UINT8)dst; +} + +I286_8X _adc_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = *p; + ADCBYTE(res, dst, src); + *p = (UINT8)res; +} + +I286_8X _sbb_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = *p; + SBBBYTE(res, dst, src); + *p = (UINT8)res; +} + +I286_8X _and_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + + GET_PCBYTE(src) + dst = *p; + ANDBYTE(dst, src); + *p = (UINT8)dst; +} + +I286_8X _sub_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = *p; + SUBBYTE(res, dst, src); + *p = (UINT8)res; +} + +I286_8X _xor_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + + GET_PCBYTE(src) + dst = *p; + XORBYTE(dst, src); + *p = (UINT8)dst; +} + +I286_8X _cmp_r8_i(UINT8 *p) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = *p; + SUBBYTE(res, dst, src); +} + + +// ----- ext8 + +I286_8X _add_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + ADDBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); +} + +I286_8X _or_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + ORBYTE(dst, src); + i286_memorywrite(madr, (REG8)dst); +} + +I286_8X _adc_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + ADCBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); +} + +I286_8X _sbb_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + SBBBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); +} + +I286_8X _and_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + ANDBYTE(dst, src); + i286_memorywrite(madr, (REG8)dst); +} + +I286_8X _sub_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + SUBBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); +} + +I286_8X _xor_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + XORBYTE(dst, src); + i286_memorywrite(madr, (REG8)dst); +} + +I286_8X _cmp_ext8_i(UINT32 madr) { + + UINT src; + UINT dst; + UINT res; + + GET_PCBYTE(src) + dst = i286_memoryread(madr); + SUBBYTE(res, dst, src); +} + + +const I286OP8XREG8 c_op8xreg8_table[] = { + _add_r8_i, _or_r8_i, _adc_r8_i, _sbb_r8_i, + _and_r8_i, _sub_r8_i, _xor_r8_i, _cmp_r8_i}; + +const I286OP8XEXT8 c_op8xext8_table[] = { + _add_ext8_i, _or_ext8_i, _adc_ext8_i, _sbb_ext8_i, + _and_ext8_i, _sub_ext8_i, _xor_ext8_i, _cmp_ext8_i}; + +// ------------------------------------------------------------------------- + +// ----- reg16 + +I286_8X _add_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = *p; + ADDWORD(res, dst, src); + *p = (UINT16)res; +} + +I286_8X _or_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + + dst = *p; + ORWORD(dst, src); + *p = (UINT16)dst; +} + +I286_8X _adc_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = *p; + ADCWORD(res, dst, src); + *p = (UINT16)res; +} + +I286_8X _sbb_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = *p; + SBBWORD(res, dst, src); + *p = (UINT16)res; +} + +I286_8X _and_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + + dst = *p; + ANDWORD(dst, src); + *p = (UINT16)dst; +} + +I286_8X _sub_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = *p; + SUBWORD(res, dst, src); + *p = (UINT16)res; +} + +I286_8X _xor_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + + dst = *p; + XORWORD(dst, src); + *p = (UINT16)dst; +} + +I286_8X _cmp_r16_i(UINT16 *p, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = *p; + SUBWORD(res, dst, src); +} + + +// ----- ext16 + +I286_8X _add_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = i286_memoryread_w(madr); + ADDWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); +} + +I286_8X _or_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + + dst = i286_memoryread_w(madr); + ORWORD(dst, src); + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_8X _adc_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = i286_memoryread_w(madr); + ADCWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); +} + +I286_8X _sbb_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = i286_memoryread_w(madr); + SBBWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); +} + +I286_8X _and_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + + dst = i286_memoryread_w(madr); + ANDWORD(dst, src); + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_8X _sub_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = i286_memoryread_w(madr); + SUBWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); +} + +I286_8X _xor_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + + dst = i286_memoryread_w(madr); + XORWORD(dst, src); + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_8X _cmp_ext16_i(UINT32 madr, UINT32 src) { + + UINT32 dst; + UINT32 res; + + dst = i286_memoryread_w(madr); + SUBWORD(res, dst, src); +} + + +const I286OP8XREG16 c_op8xreg16_table[] = { + _add_r16_i, _or_r16_i, _adc_r16_i, _sbb_r16_i, + _and_r16_i, _sub_r16_i, _xor_r16_i, _cmp_r16_i}; + +const I286OP8XEXT16 c_op8xext16_table[] = { + _add_ext16_i, _or_ext16_i, _adc_ext16_i, _sbb_ext16_i, + _and_ext16_i, _sub_ext16_i, _xor_ext16_i, _cmp_ext16_i}; + +} diff --git a/source/src/vm/np21/i286c/i286c_ea.cpp b/source/src/vm/np21/i286c/i286c_ea.cpp new file mode 100644 index 000000000..825a1ad28 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_ea.cpp @@ -0,0 +1,993 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include "i286c.mcr" + +namespace I286_NP21 { + +enum { + EA_BX_SI = 0, + EA_BX_DI, + EA_BP_SI, + EA_BP_DI, + EA_SI, + EA_DI, + EA_DISP16, + EA_BX, + EA_BX_SI_DISP8, + EA_BX_DI_DISP8, + EA_BP_SI_DISP8, + EA_BP_DI_DISP8, + EA_SI_DISP8, + EA_DI_DISP8, + EA_BP_DISP8, + EA_BX_DISP8, + EA_BX_SI_DISP16, + EA_BX_DI_DISP16, + EA_BP_SI_DISP16, + EA_BP_DI_DISP16, + EA_SI_DISP16, + EA_DI_DISP16, + EA_BP_DISP16, + EA_BX_DISP16 +}; + + +#if !defined(MEMOPTIMIZE) || (MEMOPTIMIZE < 2) + +static UINT32 ea_bx_si(void) { + + return(LOW16(I286_BX + I286_SI) + DS_FIX); +} + +static UINT32 ea_bx_si_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX + I286_SI) + DS_FIX); +} + +static UINT32 ea_bx_si_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_SI) + DS_FIX); +} + +static UINT32 ea_bx_di(void) { + + return(LOW16(I286_BX + I286_DI) + DS_FIX); +} + +static UINT32 ea_bx_di_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX + I286_DI) + DS_FIX); +} + +static UINT32 ea_bx_di_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_DI) + DS_FIX); +} + +static UINT32 ea_bp_si(void) { + + return(LOW16(I286_BP + I286_SI) + SS_FIX); +} + +static UINT32 ea_bp_si_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP + I286_SI) + SS_FIX); +} + +static UINT32 ea_bp_si_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_SI) + SS_FIX); +} + +static UINT32 ea_bp_di(void) { + + return(LOW16(I286_BP + I286_DI) + SS_FIX); +} + +static UINT32 ea_bp_di_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP + I286_DI) + SS_FIX); +} + +static UINT32 ea_bp_di_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_DI) + SS_FIX); +} + +static UINT32 ea_si(void) { + + return(I286_SI + DS_FIX); +} + +static UINT32 ea_si_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_SI) + DS_FIX); +} + +static UINT32 ea_si_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_SI) + DS_FIX); +} + +static UINT32 ea_di(void) { + + return(I286_DI + DS_FIX); +} + +static UINT32 ea_di_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_DI) + DS_FIX); +} + +static UINT32 ea_di_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_DI) + DS_FIX); +} + +static UINT32 ea_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(adrs + DS_FIX); +} + +static UINT32 ea_bp_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP) + SS_FIX); +} + +static UINT32 ea_bp_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP) + SS_FIX); +} + +static UINT32 ea_bx(void) { + + return(I286_BX + DS_FIX); +} + +static UINT32 ea_bx_disp8(void) { + + SINT32 adrs; + + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX) + DS_FIX); +} + +static UINT32 ea_bx_disp16(void) { + + UINT32 adrs; + + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX) + DS_FIX); +} + +static const CALCEA i286c_ea_dst_tbl[] = { + ea_bx_si, ea_bx_di, + ea_bp_si, ea_bp_di, + ea_si, ea_di, + ea_disp16, ea_bx, + ea_bx_si_disp8, ea_bx_di_disp8, + ea_bp_si_disp8, ea_bp_di_disp8, + ea_si_disp8, ea_di_disp8, + ea_bp_disp8, ea_bx_disp8, + ea_bx_si_disp16, ea_bx_di_disp16, + ea_bp_si_disp16, ea_bp_di_disp16, + ea_si_disp16, ea_di_disp16, + ea_bp_disp16, ea_bx_disp16}; + + +// ---- + +static UINT16 lea_bx_si(void) { + + return(I286_BX + I286_SI); +} + +static UINT16 lea_bx_si_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_BX + I286_SI); +} + +static UINT16 lea_bx_si_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_BX + I286_SI); +} + +static UINT16 lea_bx_di(void) { + + return(I286_BX + I286_DI); +} + +static UINT16 lea_bx_di_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_BX + I286_DI); +} + +static UINT16 lea_bx_di_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_BX + I286_DI); +} + +static UINT16 lea_bp_si(void) { + + return(I286_BP + I286_SI); +} + +static UINT16 lea_bp_si_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_BP + I286_SI); +} + +static UINT16 lea_bp_si_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_BP + I286_SI); +} + +static UINT16 lea_bp_di(void) { + + return(I286_BP + I286_DI); +} + +static UINT16 lea_bp_di_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_BP + I286_DI); +} + +static UINT16 lea_bp_di_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_BP + I286_DI); +} + +static UINT16 lea_si(void) { + + return(I286_SI); +} + +static UINT16 lea_si_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_SI); +} + +static UINT16 lea_si_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_SI); +} + +static UINT16 lea_di(void) { + + return(I286_DI); +} + +static UINT16 lea_di_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_DI); +} + +static UINT16 lea_di_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_DI); +} + +static UINT16 lea_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs); +} + +static UINT16 lea_bp_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_BP); +} + +static UINT16 lea_bp_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_BP); +} + +static UINT16 lea_bx(void) { + + return(I286_BX); +} + +static UINT16 lea_bx_disp8(void) { + + UINT16 adrs; + + GET_PCBYTES(adrs); + return(adrs + I286_BX); +} + +static UINT16 lea_bx_disp16(void) { + + UINT16 adrs; + + GET_PCWORD(adrs); + return(adrs + I286_BX); +} + +static const CALCLEA i286c_lea_tbl[] = { + lea_bx_si, lea_bx_di, + lea_bp_si, lea_bp_di, + lea_si, lea_di, + lea_disp16, lea_bx, + lea_bx_si_disp8, lea_bx_di_disp8, + lea_bp_si_disp8, lea_bp_di_disp8, + lea_si_disp8, lea_di_disp8, + lea_bp_disp8, lea_bx_disp8, + lea_bx_si_disp16, lea_bx_di_disp16, + lea_bp_si_disp16, lea_bp_di_disp16, + lea_si_disp16, lea_di_disp16, + lea_bp_disp16, lea_bx_disp16}; + + +// ---- + +static UINT a_bx_si(UINT32 *seg) { + + *seg = DS_FIX; + return(LOW16(I286_BX + I286_SI)); +} + +static UINT a_bx_si_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_BX + I286_SI)); +} + +static UINT a_bx_si_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_SI)); +} + +static UINT a_bx_di(UINT32 *seg) { + + *seg = DS_FIX; + return(LOW16(I286_BX + I286_DI)); +} + +static UINT a_bx_di_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_BX + I286_DI)); +} + +static UINT a_bx_di_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_DI)); +} + +static UINT a_bp_si(UINT32 *seg) { + + *seg = SS_FIX; + return(LOW16(I286_BP + I286_SI)); +} + +static UINT a_bp_si_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = SS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_BP + I286_SI)); +} + +static UINT a_bp_si_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = SS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_SI)); +} + +static UINT a_bp_di(UINT32 *seg) { + + *seg = SS_FIX; + return(LOW16(I286_BP + I286_DI)); +} + +static UINT a_bp_di_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = SS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_BP + I286_DI)); +} + +static UINT a_bp_di_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = SS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_DI)); +} + +static UINT a_si(UINT32 *seg) { + + *seg = DS_FIX; + return(I286_SI); +} + +static UINT a_si_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_SI)); +} + +static UINT a_si_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_SI)); +} + +static UINT a_di(UINT32 *seg) { + + *seg = DS_FIX; + return(I286_DI); +} + +static UINT a_di_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_DI)); +} + +static UINT a_di_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_DI)); +} + +static UINT a_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCWORD(adrs); + return(adrs); +} + +static UINT a_bp_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = SS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_BP)); +} + +static UINT a_bp_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = SS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP)); +} + +static UINT a_bx(UINT32 *seg) { + + *seg = DS_FIX; + return(I286_BX); +} + +static UINT a_bx_disp8(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCBYTES(adrs); + return(LOW16(adrs + I286_BX)); +} + +static UINT a_bx_disp16(UINT32 *seg) { + + UINT adrs; + + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX)); +} + +static const GETLEA i286c_ea_tbl[] = { + a_bx_si, a_bx_di, + a_bp_si, a_bp_di, + a_si, a_di, + a_disp16, a_bx, + a_bx_si_disp8, a_bx_di_disp8, + a_bp_si_disp8, a_bp_di_disp8, + a_si_disp8, a_di_disp8, + a_bp_disp8, a_bx_disp8, + a_bx_si_disp16, a_bx_di_disp16, + a_bp_si_disp16, a_bp_di_disp16, + a_si_disp16, a_di_disp16, + a_bp_disp16, a_bx_disp16}; + + +// ---- + + CALCEA _calc_ea_dst[256]; + CALCLEA _calc_lea[192]; + GETLEA _get_ea[192]; + +static UINT32 ea_nop(void) { + + return(0); +} + +void i286cea_initialize(void) { + + UINT i; + UINT pos; + + for (i=0; i<0xc0; i++) { + pos = ((i >> 3) & 0x18) + (i & 0x07); + _calc_ea_dst[i] = i286c_ea_dst_tbl[pos]; + _calc_lea[i] = i286c_lea_tbl[pos]; + _get_ea[i] = i286c_ea_tbl[pos]; + } + for (; i<0x100; i++) { + _calc_ea_dst[i] = ea_nop; + } +} + +#else // ARMだとswitchにしたほーが早いはず… + +UINT32 calc_ea_dst(UINT op) { + + UINT32 adrs; + + switch(((op >> 3) & 0x18) + (op & 0x07)) { + case EA_BX_SI: + return(LOW16(I286_BX + I286_SI) + DS_FIX); + + case EA_BX_SI_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX + I286_SI) + DS_FIX); + + case EA_BX_SI_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_SI) + DS_FIX); + + case EA_BX_DI: + return(LOW16(I286_BX + I286_DI) + DS_FIX); + + case EA_BX_DI_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX + I286_DI) + DS_FIX); + + case EA_BX_DI_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_DI) + DS_FIX); + + case EA_BP_SI: + return(LOW16(I286_BP + I286_SI) + SS_FIX); + + case EA_BP_SI_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP + I286_SI) + SS_FIX); + + case EA_BP_SI_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_SI) + SS_FIX); + + case EA_BP_DI: + return(LOW16(I286_BP + I286_DI) + SS_FIX); + + case EA_BP_DI_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP + I286_DI) + SS_FIX); + + case EA_BP_DI_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_DI) + SS_FIX); + + case EA_SI: + return(I286_SI + DS_FIX); + + case EA_SI_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_SI) + DS_FIX); + + case EA_SI_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_SI) + DS_FIX); + + case EA_DI: + return(I286_DI + DS_FIX); + + case EA_DI_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_DI) + DS_FIX); + + case EA_DI_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_DI) + DS_FIX); + + case EA_BX: + return(I286_BX + DS_FIX); + + case EA_BX_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX) + DS_FIX); + + case EA_BX_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX) + DS_FIX); + + case EA_BP_DISP8: + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP) + SS_FIX); + + case EA_BP_DISP16: + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP) + SS_FIX); + + case EA_DISP16: + GET_PCWORD(adrs); + return(adrs + DS_FIX); + + default: + return(0); + } +} + +UINT16 calc_lea(UINT op) { + + UINT16 adrs; + + switch(((op >> 3) & 0x18) + (op & 0x07)) { + case EA_BX_SI: + return(I286_BX + I286_SI); + + case EA_BX_SI_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_BX + I286_SI); + + case EA_BX_SI_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_BX + I286_SI); + + case EA_BX_DI: + return(I286_BX + I286_DI); + + case EA_BX_DI_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_BX + I286_DI); + + case EA_BX_DI_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_BX + I286_DI); + + case EA_BP_SI: + return(I286_BP + I286_SI); + + case EA_BP_SI_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_BP + I286_SI); + + case EA_BP_SI_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_BP + I286_SI); + + case EA_BP_DI: + return(I286_BP + I286_DI); + + case EA_BP_DI_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_BP + I286_DI); + + case EA_BP_DI_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_BP + I286_DI); + + case EA_SI: + return(I286_SI); + + case EA_SI_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_SI); + + case EA_SI_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_SI); + + case EA_DI: + return(I286_DI); + + case EA_DI_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_DI); + + case EA_DI_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_DI); + + case EA_BX: + return(I286_BX); + + case EA_BX_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_BX); + + case EA_BX_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_BX); + + case EA_BP_DISP8: + GET_PCBYTESD(adrs); + return(adrs + I286_BP); + + case EA_BP_DISP16: + GET_PCWORD(adrs); + return(adrs + I286_BP); + + case EA_DISP16: + GET_PCWORD(adrs); + return(adrs); + + default: + return(0); + } +} + +UINT calc_a(UINT op, UINT32 *seg) { + + UINT adrs; + + switch(((op >> 3) & 0x18) + (op & 0x07)) { + case EA_BX_SI: + *seg = DS_FIX; + return(LOW16(I286_BX + I286_SI)); + + case EA_BX_SI_DISP8: + *seg = DS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX + I286_SI)); + + case EA_BX_SI_DISP16: + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_SI)); + + case EA_BX_DI: + *seg = DS_FIX; + return(LOW16(I286_BX + I286_DI)); + + case EA_BX_DI_DISP8: + *seg = DS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX + I286_DI)); + + case EA_BX_DI_DISP16: + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX + I286_DI)); + + case EA_BP_SI: + *seg = SS_FIX; + return(LOW16(I286_BP + I286_SI)); + + case EA_BP_SI_DISP8: + *seg = SS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP + I286_SI)); + + case EA_BP_SI_DISP16: + *seg = SS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_SI)); + + case EA_BP_DI: + *seg = SS_FIX; + return(LOW16(I286_BP + I286_DI)); + + case EA_BP_DI_DISP8: + *seg = SS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP + I286_DI)); + + case EA_BP_DI_DISP16: + *seg = SS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP + I286_DI)); + + case EA_SI: + *seg = DS_FIX; + return(I286_SI); + + case EA_SI_DISP8: + *seg = DS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_SI)); + + case EA_SI_DISP16: + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_SI)); + + case EA_DI: + *seg = DS_FIX; + return(I286_DI); + + case EA_DI_DISP8: + *seg = DS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_DI)); + + case EA_DI_DISP16: + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_DI)); + + case EA_BX: + *seg = DS_FIX; + return(I286_BX); + + case EA_BX_DISP8: + *seg = DS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BX)); + + case EA_BX_DISP16: + *seg = DS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BX)); + + case EA_BP_DISP8: + *seg = SS_FIX; + GET_PCBYTESD(adrs); + return(LOW16(adrs + I286_BP)); + + case EA_BP_DISP16: + *seg = SS_FIX; + GET_PCWORD(adrs); + return(LOW16(adrs + I286_BP)); + + case EA_DISP16: + *seg = DS_FIX; + GET_PCWORD(adrs); + return(adrs); + + default: + *seg = 0; + return(0); + } +} + +#endif + + +UINT32 i286c_selector(UINT sel) { + + I286DTR *dtr; + UINT32 addr; + UINT32 ret; + + dtr = (sel & 4)?&I286_LDTRC:&I286_GDTR; + addr = (dtr->base24 << 16) + dtr->base + (sel & (~7)); + ret = i286_memoryread_w(addr+2); + ret += i286_memoryread(addr+4) << 16; + TRACEOUT(("ProtectMode: selector idx=%x %s rpl=%d - real addr = %.6x", + (sel >> 3), (sel & 4)?"LDT":"GDT", sel & 3, ret)); + return(ret); +} +} + diff --git a/source/src/vm/np21/i286c/i286c_f6.cpp b/source/src/vm/np21/i286c/i286c_f6.cpp new file mode 100644 index 000000000..6d58cd88f --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_f6.cpp @@ -0,0 +1,330 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include +#include "i286c.mcr" + +namespace I286_NP21 { +// ------------------------------------------------------------ opecode 0xf6,7 + +I286_F6 _test_ea8_data8(UINT op) { + + UINT src; + UINT dst; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + dst = *(REG8_B20(op)); + } + else { + I286_WORKCLOCK(6); + dst = i286_memoryread(CALC_EA(op)); + } + GET_PCBYTE(src) + ANDBYTE(dst, src) +} + +I286_F6 _not_ea8(UINT op) { + + UINT32 madr; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG8_B20(op)) ^= 0xff; + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + REG8 value = i286_memoryread(madr); + value ^= 0xff; + i286_memorywrite(madr, value); + return; +// } +// *(mem + madr) ^= 0xff; + } +} + +I286_F6 _neg_ea8(UINT op) { + + UINT8 *out; + UINT src; + UINT dst; + UINT32 madr; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + src = i286_memoryread(madr); + NEGBYTE(dst, src) + i286_memorywrite(madr, (REG8)dst); + return; +// } +// out = mem + madr; + } + src = *out; + NEGBYTE(dst, src) + *out = (UINT8)dst; +} + +I286_F6 _mul_ea8(UINT op) { + + UINT8 src; + UINT res; + + if (op >= 0xc0) { + I286_WORKCLOCK(13); + src = *(REG8_B20(op)); + } + else { + I286_WORKCLOCK(16); + src = i286_memoryread(CALC_EA(op)); + } + BYTE_MUL(res, I286_AL, src) + I286_AX = (UINT16)res; +} + +I286_F6 _imul_ea8(UINT op) { + + UINT8 src; + SINT32 res; + + if (op >= 0xc0) { + I286_WORKCLOCK(13); + src = *(REG8_B20(op)); + } + else { + I286_WORKCLOCK(16); + src = i286_memoryread(CALC_EA(op)); + } + BYTE_IMUL(res, I286_AL, src) + I286_AX = (UINT16)res; +} + +I286_F6 _div_ea8(UINT op) { + + UINT16 tmp; + UINT8 src; + UINT16 ip; + + ip = I286_IP; + if (op >= 0xc0) { + I286_WORKCLOCK(14); + src = *(REG8_B20(op)); + } + else { + I286_WORKCLOCK(17); + src = i286_memoryread(CALC_EA(op)); + } + tmp = I286_AX; + if ((src) && (tmp < ((UINT16)src << 8))) { + I286_AL = tmp / src; + I286_AH = tmp % src; + } + else { + INT_NUM(0, ip - 2); // 80x86 + } +} + +I286_F6 _idiv_ea8(UINT op) { + + SINT16 tmp, r; + SINT8 src; + UINT16 ip; + + ip = I286_IP; + if (op >= 0xc0) { + I286_WORKCLOCK(17); + src = *(REG8_B20(op)); + } + else { + I286_WORKCLOCK(20); + src = i286_memoryread(CALC_EA(op)); + } + tmp = (SINT16)I286_AX; + if (src) { + r = tmp / src; + if (!((r + 0x80) & 0xff00)) { + I286_AL = (UINT8)r; + I286_AH = tmp % src; + return; + } + } + INT_NUM(0, ip - 2); // 80x86 +} + + +I286_F6 _test_ea16_data16(UINT op) { + + UINT32 src; + UINT32 dst; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + dst = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(6); + dst = i286_memoryread_w(CALC_EA(op)); + } + GET_PCWORD(src) + ANDWORD(dst, src) +} + +I286_F6 _not_ea16(UINT op) { + + UINT32 madr; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG16_B20(op)) ^= 0xffff; + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (!(INHIBIT_WORDP(madr))) { +// *(mem + madr) ^= 0xffff; +// } +// else { + REG16 value = i286_memoryread_w(madr); + value = ~value; + i286_memorywrite_w(madr, value); +// } + } +} + +I286_F6 _neg_ea16(UINT op) { + + UINT16 *out; + UINT32 src; + UINT32 dst; + UINT32 madr; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + src = i286_memoryread_w(madr); + NEGWORD(dst, src) + i286_memorywrite_w(madr, (REG16)dst); + return; +// } +// out = (UINT16 *)(mem + madr); + } + src = *out; + NEGWORD(dst, src) + *out = (UINT16)dst; +} + +I286_F6 _mul_ea16(UINT op) { + + UINT16 src; + UINT32 res; + + if (op >= 0xc0) { + I286_WORKCLOCK(21); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(24); + src = i286_memoryread_w(CALC_EA(op)); + } + WORD_MUL(res, I286_AX, src) + I286_AX = (UINT16)res; + I286_DX = (UINT16)(res >> 16); +} + +I286_F6 _imul_ea16(UINT op) { + + SINT16 src; + SINT32 res; + + if (op >= 0xc0) { + I286_WORKCLOCK(21); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(24); + src = i286_memoryread_w(CALC_EA(op)); + } + WORD_IMUL(res, I286_AX, src) + I286_AX = (UINT16)res; + I286_DX = (UINT16)(res >> 16); +} + +I286_F6 _div_ea16(UINT op) { + + UINT32 tmp; + UINT32 src; + UINT16 ip; + + ip = I286_IP; + if (op >= 0xc0) { + I286_WORKCLOCK(22); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(25); + src = i286_memoryread_w(CALC_EA(op)); + } + tmp = (I286_DX << 16) + I286_AX; + if ((src) && (tmp < (src << 16))) { + I286_AX = tmp / src; + I286_DX = tmp % src; + } + else { + INT_NUM(0, ip - 2); // 80x86 + } +} + +I286_F6 _idiv_ea16(UINT op) { + + SINT32 tmp; + SINT32 r; + SINT16 src; + UINT16 ip; + + ip = I286_IP; + if (op >= 0xc0) { + I286_WORKCLOCK(25); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(28); + src = i286_memoryread_w(CALC_EA(op)); + } + tmp = (SINT32)((I286_DX << 16) + I286_AX); + if ((src) && (tmp != INT_MIN)) { + r = tmp / src; + if (!((r + 0x8000) & 0xffff0000)) { + I286_AX = (SINT16)r; + I286_DX = tmp % src; + return; + } + } + INT_NUM(0, ip - 2); // 80x86 +} + + +const I286OPF6 c_ope0xf6_table[] = { + _test_ea8_data8, _test_ea8_data8, + _not_ea8, _neg_ea8, + _mul_ea8, _imul_ea8, + _div_ea8, _idiv_ea8}; + +const I286OPF6 c_ope0xf7_table[] = { + _test_ea16_data16, _test_ea16_data16, + _not_ea16, _neg_ea16, + _mul_ea16, _imul_ea16, + _div_ea16, _idiv_ea16}; + +} diff --git a/source/src/vm/np21/i286c/i286c_fe.cpp b/source/src/vm/np21/i286c/i286c_fe.cpp new file mode 100644 index 000000000..20455d5f2 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_fe.cpp @@ -0,0 +1,259 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include "i286c.mcr" + +namespace I286_NP21 { +// ------------------------------------------------------------ opecode 0xfe,f + +#if 0 +I286_F6 _nop_int(UINT op) { + + INT_NUM(6, I286_IP - 2); +} +#endif + +I286_F6 _inc_ea8(UINT op) { + + UINT32 madr; + UINT8 *out; + REG8 res; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + res = i286_memoryread(madr); + INCBYTE(res) + i286_memorywrite(madr, res); + return; +// } +// out = mem + madr; + } + res = *out; + INCBYTE(res) + *out = (UINT8)res; +} + +I286_F6 _dec_ea8(UINT op) { + + UINT32 madr; + UINT8 *out; + REG8 res; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + res = i286_memoryread(madr); + DECBYTE(res) + i286_memorywrite(madr, res); + return; +// } +// out = mem + madr; + } + res = *out; + DECBYTE(res) + *out = (UINT8)res; +} + +I286_F6 _inc_ea16(UINT op) { + + UINT32 madr; + UINT16 *out; + REG16 res; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + res = i286_memoryread_w(madr); + INCWORD(res) + i286_memorywrite_w(madr, res); + return; +// } +// out = (UINT16 *)(mem + madr); + } + res = *out; + INCWORD(res) + *out = (UINT16)res; +} + +I286_F6 _dec_ea16(UINT op) { + + UINT32 madr; + UINT16 *out; + REG16 res; + + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + res = i286_memoryread_w(madr); + DECWORD(res) + i286_memorywrite_w(madr, res); + return; +// } +// out = (UINT16 *)(mem + madr); + } + res = *out; + DECWORD(res) + *out = (UINT16)res; +} + +I286_F6 _call_ea16(UINT op) { + + UINT16 src; + + if (op >= 0xc0) { + I286_WORKCLOCK(7); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(11); + src = i286_memoryread_w(CALC_EA(op)); + } + REGPUSH0(I286_IP); + I286_IP = src; +} + +I286_F6 _call_far_ea16(UINT op) { + + UINT32 seg; + UINT ad; + + I286_WORKCLOCK(16); + if (op < 0xc0) { + ad = GET_EA(op, &seg); + UINT16 newip = i286_memoryread_w(seg + ad); + UINT16 newcs = i286_memoryread_w(seg + LOW16(ad + 2)); + +#ifdef I86_PSEUDO_BIOS + if (device_bios != NULL) { + uint16_t regs[8] = {CPU_AX, CPU_CX, CPU_DX, CPU_BX, CPU_SP, CPU_BP, CPU_SI, CPU_DI}; + uint16_t sregs[4] = {CPU_ES, CPU_CS, CPU_SS, CPU_DS}; + int32_t ZeroFlag = ((CPU_FLAG & Z_FLAG) ? 1 : 0); + int32_t CarryFlag = ((CPU_FLAG & C_FLAG) ? 1 : 0); + + if (device_bios->bios_call_far_i86((newcs << 4) + newip, regs, sregs, &ZeroFlag, &CarryFlag)) { + CPU_AX = regs[0]; + CPU_CX = regs[1]; + CPU_DX = regs[2]; + CPU_BX = regs[3]; + CPU_SP = regs[4]; + CPU_BP = regs[5]; + CPU_SI = regs[6]; + CPU_DI = regs[7]; + if (ZeroFlag) { + CPU_FLAG |= Z_FLAG; + } else { + CPU_FLAG &= ~Z_FLAG; + } + if (CarryFlag) { + CPU_FLAG |= C_FLAG; + } else { + CPU_FLAG &= ~C_FLAG; + } + I286_WORKCLOCK(1000); // temporary + return; + } + } +#endif + + REGPUSH0(I286_CS) // ToDo + REGPUSH0(I286_IP) +// I286_IP = i286_memoryread_w(seg + ad); +// I286_CS = i286_memoryread_w(seg + LOW16(ad + 2)); + I286_IP = newip; + I286_CS = newcs; + CS_BASE = SEGSELECT(I286_CS); + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286_F6 _jmp_ea16(UINT op) { + + if (op >= 0xc0) { + I286_WORKCLOCK(7); + I286_IP = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(11); + I286_IP = i286_memoryread_w(CALC_EA(op)); + } +} + +I286_F6 _jmp_far_ea16(UINT op) { + + UINT32 seg; + UINT ad; + + I286_WORKCLOCK(11); + if (op < 0xc0) { + ad = GET_EA(op, &seg); + I286_IP = i286_memoryread_w(seg + ad); + I286_CS = i286_memoryread_w(seg + LOW16(ad + 2)); + CS_BASE = SEGSELECT(I286_CS); + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286_F6 _push_ea16(UINT op) { + + UINT16 src; + + if (op >= 0xc0) { + I286_WORKCLOCK(3); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(5); + src = i286_memoryread_w(CALC_EA(op)); + } + REGPUSH0(src); +} + +I286_F6 _pop_ea16(UINT op) { + + UINT16 src; + + REGPOP0(src); + I286_WORKCLOCK(5); + if (op >= 0xc0) { + *(REG16_B20(op)) = src; + } + else { + i286_memorywrite_w(CALC_EA(op), src); + } +} + + +const I286OPF6 c_ope0xfe_table[] = { + _inc_ea8, _dec_ea8}; + +const I286OPF6 c_ope0xff_table[] = { + _inc_ea16, _dec_ea16, + _call_ea16, _call_far_ea16, + _jmp_ea16, _jmp_far_ea16, + _push_ea16, _pop_ea16}; +} diff --git a/source/src/vm/np21/i286c/i286c_mn.cpp b/source/src/vm/np21/i286c/i286c_mn.cpp new file mode 100644 index 000000000..4a623ec75 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_mn.cpp @@ -0,0 +1,3722 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +//#include "pccore.h" +//#include "iocore.h" +//#include "bios/bios.h" +#include "i286c.mcr" +//#if defined(ENABLE_TRAP) +//#include "trap/inttrap.h" +//#endif + + +#define MAX_PREFIX 8 + +namespace I286_NP21 { + +#define NEXT_OPCODE \ + if (I286_REMCLOCK < 1) { \ + I286_BASECLOCK += (1 - I286_REMCLOCK); \ + I286_REMCLOCK = 1; \ + } + +#define REMAIN_ADJUST(c) \ + if (I286_REMCLOCK != (c)) { \ + I286_BASECLOCK += ((c) - I286_REMCLOCK); \ + I286_REMCLOCK = (c); \ + } + + +// ---- + +I286FN _reserved(void) { + + INT_NUM(6, I286_IP - 1); +} + +I286FN _add_ea_r8(void) { // 00: add EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + dst = i286_memoryread(madr); + ADDBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); + return; +// } +// out = mem + madr; + } + dst = *out; + ADDBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _add_ea_r16(void) { // 01: add EA, REG16 + + UINT16 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + dst = i286_memoryread_w(madr); + ADDWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); + return; +// } +// out = (UINT16 *)(mem + madr); + } + dst = *out; + ADDWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _add_r8_ea(void) { // 02: add REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ADDBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _add_r16_ea(void) { // 03: add REG16, EA + + UINT16 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ADDWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _add_al_data8(void) { // 04: add al, DATA8 + + UINT src; + UINT res; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + ADDBYTE(res, I286_AL, src); + I286_AL = (UINT8)res; +} + +I286FN _add_ax_data16(void) { // 05: add ax, DATA16 + + UINT src; + UINT res; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + ADDWORD(res, I286_AX, src); + I286_AX = (UINT16)res; +} + +I286FN _push_es(void) { // 06: push es + + REGPUSH(I286_ES, 3); +} + +I286FN _pop_es(void) { // 07: pop es + + UINT tmp; + + REGPOP(tmp, 5) + I286_ES = tmp; + ES_BASE = SEGSELECT(tmp); +} + +I286FN _or_ea_r8(void) { // 08: or EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + dst = i286_memoryread(madr); + ORBYTE(dst, src); + i286_memorywrite(madr, (REG8)dst); + return; +// } +// out = mem + madr; + } + dst = *out; + ORBYTE(dst, src); + *out = (UINT8)dst; +} + +I286FN _or_ea_r16(void) { // 09: or EA, REG16 + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + dst = i286_memoryread_w(madr); + ORWORD(dst, src); + i286_memorywrite_w(madr, (REG16)dst); + return; +// } +// out = (UINT16 *)(mem + madr); + } + dst = *out; + ORWORD(dst, src); + *out = (UINT16)dst; +} + +I286FN _or_r8_ea(void) { // 0a: or REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ORBYTE(dst, src); + *out = (UINT8)dst; +} + +I286FN _or_r16_ea(void) { // 0b: or REG16, EA + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ORWORD(dst, src); + *out = (UINT16)dst; +} + +I286FN _or_al_data8(void) { // 0c: or al, DATA8 + + UINT src; + UINT dst; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + dst = I286_AL; + ORBYTE(dst, src); + I286_AL = (UINT8)dst; +} + +I286FN _or_ax_data16(void) { // 0d: or ax, DATA16 + + UINT32 src; + UINT32 dst; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + dst = I286_AX; + ORWORD(dst, src); + I286_AX = (UINT16)dst; +} + +I286FN _push_cs(void) { // 0e: push cs + + REGPUSH(I286_CS, 3); +} + +I286FN _adc_ea_r8(void) { // 10: adc EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + dst = i286_memoryread(madr); + ADCBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); + return; +// } +// out = mem + madr; + } + dst = *out; + ADCBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _adc_ea_r16(void) { // 11: adc EA, REG16 + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + dst = i286_memoryread_w(madr); + ADCWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); + return; +// } +// out = (UINT16 *)(mem + madr); + } + dst = *out; + ADCWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _adc_r8_ea(void) { // 12: adc REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ADCBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _adc_r16_ea(void) { // 13: adc REG16, EA + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ADCWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _adc_al_data8(void) { // 14: adc al, DATA8 + + UINT src; + UINT res; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + ADCBYTE(res, I286_AL, src); + I286_AL = (UINT8)res; +} + +I286FN _adc_ax_data16(void) { // 15: adc ax, DATA16 + + UINT32 src; + UINT32 res; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + ADCWORD(res, I286_AX, src); + I286_AX = (UINT16)res; +} + +I286FN _push_ss(void) { // 16: push ss + + REGPUSH(I286_SS, 3); +} + +I286FN _pop_ss(void) { // 17: pop ss + + UINT tmp; + + REGPOP(tmp, 5) + I286_SS = tmp; + SS_BASE = SEGSELECT(tmp); + SS_FIX = SS_BASE; + NEXT_OPCODE +} + +I286FN _sbb_ea_r8(void) { // 18: sbb EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + dst = i286_memoryread(madr); + SBBBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); + return; +// } +// out = mem + madr; + } + dst = *out; + SBBBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _sbb_ea_r16(void) { // 19: sbb EA, REG16 + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + dst = i286_memoryread_w(madr); + SBBWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); + return; +// } +// out = (UINT16 *)(mem + madr); + } + dst = *out; + SBBWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _sbb_r8_ea(void) { // 1a: sbb REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT32 res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + SBBBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _sbb_r16_ea(void) { // 1b: sbb REG16, EA + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + SBBWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _sbb_al_data8(void) { // 1c: adc al, DATA8 + + UINT src; + UINT res; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + SBBBYTE(res, I286_AL, src); + I286_AL = (UINT8)res; +} + +I286FN _sbb_ax_data16(void) { // 1d: adc ax, DATA16 + + UINT32 src; + UINT32 res; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + SBBWORD(res, I286_AX, src); + I286_AX = (UINT16)res; +} + +I286FN _push_ds(void) { // 1e: push ds + + REGPUSH(I286_DS, 3); +} + +I286FN _pop_ds(void) { // 1f: pop ds + + UINT tmp; + + REGPOP(tmp, 5) + I286_DS = tmp; + DS_BASE = SEGSELECT(tmp); + DS_FIX = DS_BASE; +} + +I286FN _and_ea_r8(void) { // 20: and EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + dst = i286_memoryread(madr); + ANDBYTE(dst, src); + i286_memorywrite(madr, (REG8)dst); + return; +// } +// out = mem + madr; + } + dst = *out; + ANDBYTE(dst, src); + *out = (UINT8)dst; +} + +I286FN _and_ea_r16(void) { // 21: and EA, REG16 + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + dst = i286_memoryread_w(madr); + ANDWORD(dst, src); + i286_memorywrite_w(madr, (REG16)dst); + return; +// } +// out = (UINT16 *)(mem + madr); + } + dst = *out; + ANDWORD(dst, src); + *out = (UINT16)dst; +} + +I286FN _and_r8_ea(void) { // 22: and REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + ANDBYTE(dst, src); + *out = (UINT8)dst; +} + +I286FN _and_r16_ea(void) { // 23: and REG16, EA + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + ANDWORD(dst, src); + *out = (UINT16)dst; +} + +I286FN _and_al_data8(void) { // 24: and al, DATA8 + + UINT src; + UINT dst; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + dst = I286_AL; + ANDBYTE(dst, src); + I286_AL = (UINT8)dst; +} + +I286FN _and_ax_data16(void) { // 25: and ax, DATA16 + + UINT32 src; + UINT32 dst; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + dst = I286_AX; + ANDWORD(dst, src); + I286_AX = (UINT16)dst; +} + +I286FN _segprefix_es(void) { // 26: es: + + SS_FIX = ES_BASE; + DS_FIX = ES_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _daa(void) { // 27: daa + + I286_WORKCLOCK(3); + I286_OV = ((I286_AL < 0x80) && + ((I286_AL >= 0x7a) || + ((I286_AL >= 0x1a) && (I286_FLAGL & C_FLAG)))); + if ((I286_FLAGL & A_FLAG) || ((I286_AL & 0x0f) > 9)) { + I286_FLAGL |= A_FLAG; + I286_FLAGL |= (UINT8)((I286_AL + 6) >> 8); + I286_AL += 6; + } + if ((I286_FLAGL & C_FLAG) || (I286_AL > 0x9f)) { + I286_FLAGL |= C_FLAG; + I286_AL += 0x60; + } + I286_FLAGL &= A_FLAG | C_FLAG; + I286_FLAGL |= BYTESZPF(I286_AL); +} + +I286FN _sub_ea_r8(void) { // 28: sub EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + dst = i286_memoryread(madr); + SUBBYTE(res, dst, src); + i286_memorywrite(madr, (REG8)res); + return; +// } +// out = mem + madr; + } + dst = *out; + SUBBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _sub_ea_r16(void) { // 29: sub EA, REG16 + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + dst = i286_memoryread_w(madr); + SUBWORD(res, dst, src); + i286_memorywrite_w(madr, (REG16)res); + return; +// } +// out = (UINT16 *)(mem + madr); + } + dst = *out; + SUBWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _sub_r8_ea(void) { // 2a: sub REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + SUBBYTE(res, dst, src); + *out = (UINT8)res; +} + +I286FN _sub_r16_ea(void) { // 2b: sub REG16, EA + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + SUBWORD(res, dst, src); + *out = (UINT16)res; +} + +I286FN _sub_al_data8(void) { // 2c: sub al, DATA8 + + UINT src; + UINT res; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + SUBBYTE(res, I286_AL, src); + I286_AL = (UINT8)res; +} + +I286FN _sub_ax_data16(void) { // 2d: sub ax, DATA16 + + UINT32 src; + UINT32 res; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + SUBWORD(res, I286_AX, src); + I286_AX = (UINT16)res; +} + +I286FN _segprefix_cs(void) { // 2e: cs: + + SS_FIX = CS_BASE; + DS_FIX = CS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _das(void) { // 2f: das + + I286_WORKCLOCK(3); + if ((I286_FLAGL & C_FLAG) || (I286_AL > 0x99)) { + I286_FLAGL |= C_FLAG; + I286_AL -= 0x60; + } + if ((I286_FLAGL & A_FLAG) || ((I286_AL & 0x0f) > 9)) { + I286_FLAGL |= A_FLAG; + I286_FLAGL |= ((I286_AL - 6) >> 8) & 1; + I286_AL -= 6; + } + I286_FLAGL &= A_FLAG | C_FLAG; + I286_FLAGL |= BYTESZPF(I286_AL); +} + +I286FN _xor_ea_r8(void) { // 30: xor EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + dst = i286_memoryread(madr); + XORBYTE(dst, src); + i286_memorywrite(madr, (REG8)dst); + return; +// } +// out = mem + madr; + } + dst = *out; + XORBYTE(dst, src); + *out = (UINT8)dst; +} + +I286FN _xor_ea_r16(void) { // 31: xor EA, REG16 + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + dst = i286_memoryread_w(madr); + XORWORD(dst, src); + i286_memorywrite_w(madr, (REG16)dst); + return; +// } +// out = (UINT16 *)(mem + madr); + } + dst = *out; + XORWORD(dst, src); + *out = (UINT16)dst; +} + +I286FN _xor_r8_ea(void) { // 32: xor REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + + PREPART_REG8_EA(op, src, out, 2, 7); + dst = *out; + XORBYTE(dst, src); + *out = (UINT8)dst; +} + +I286FN _xor_r16_ea(void) { // 33: or REG16, EA + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + + PREPART_REG16_EA(op, src, out, 2, 7); + dst = *out; + XORWORD(dst, src); + *out = (UINT16)dst; +} + +I286FN _xor_al_data8(void) { // 34: or al, DATA8 + + UINT src; + UINT dst; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + dst = I286_AL; + XORBYTE(dst, src); + I286_AL = (UINT8)dst; +} + +I286FN _xor_ax_data16(void) { // 35: or ax, DATA16 + + UINT32 src; + UINT32 dst; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + dst = I286_AX; + XORWORD(dst, src); + I286_AX = (UINT16)dst; +} + +I286FN _segprefix_ss(void) { // 36: ss: + + SS_FIX = SS_BASE; + DS_FIX = SS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _aaa(void) { // 37: aaa + + I286_WORKCLOCK(3); + if ((I286_FLAGL & A_FLAG) || ((I286_AL & 0xf) > 9)) { + I286_FLAGL |= A_FLAG | C_FLAG; + I286_AX += 6; + I286_AH++; + } + else { + I286_FLAGL &= ~(A_FLAG | C_FLAG); + } + I286_AL &= 0x0f; +} + +I286FN _cmp_ea_r8(void) { // 38: cmp EA, REG8 + + UINT op; + UINT src; + UINT dst; + UINT res; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + dst = *(REG8_B20(op)); + SUBBYTE(res, dst, src); + } + else { + I286_WORKCLOCK(6); + dst = i286_memoryread(CALC_EA(op)); + SUBBYTE(res, dst, src); + } +} + +I286FN _cmp_ea_r16(void) { // 39: cmp EA, REG16 + + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + dst = *(REG16_B20(op)); + SUBWORD(res, dst, src); + } + else { + I286_WORKCLOCK(6); + dst = i286_memoryread_w(CALC_EA(op)); + SUBWORD(res, dst, src); + } +} + +I286FN _cmp_r8_ea(void) { // 3a: cmp REG8, EA + + UINT8 *out; + UINT op; + UINT src; + UINT dst; + UINT res; + + PREPART_REG8_EA(op, src, out, 2, 6); + dst = *out; + SUBBYTE(res, dst, src); +} + +I286FN _cmp_r16_ea(void) { // 3b: cmp REG16, EA + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 dst; + UINT32 res; + + PREPART_REG16_EA(op, src, out, 2, 6); + dst = *out; + SUBWORD(res, dst, src); +} + +I286FN _cmp_al_data8(void) { // 3c: cmp al, DATA8 + + UINT src; + UINT res; + + I286_WORKCLOCK(3); + GET_PCBYTE(src); + SUBBYTE(res, I286_AL, src); +} + +I286FN _cmp_ax_data16(void) { // 3d: cmp ax, DATA16 + + UINT32 src; + UINT32 res; + + I286_WORKCLOCK(3); + GET_PCWORD(src); + SUBWORD(res, I286_AX, src); +} + +I286FN _segprefix_ds(void) { // 3e: ds: + + SS_FIX = DS_BASE; + DS_FIX = DS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _aas(void) { // 3f: aas + + I286_WORKCLOCK(3); + if ((I286_FLAGL & A_FLAG) || ((I286_AL & 0xf) > 9)) { + I286_FLAGL |= A_FLAG | C_FLAG; + I286_AX -= 6; + I286_AH--; + } + else { + I286_FLAGL &= ~(A_FLAG | C_FLAG); + } +} + +I286FN _inc_ax(void) INCWORD2(I286_AX, 2) // 40: inc ax +I286FN _inc_cx(void) INCWORD2(I286_CX, 2) // 41: inc cx +I286FN _inc_dx(void) INCWORD2(I286_DX, 2) // 42: inc dx +I286FN _inc_bx(void) INCWORD2(I286_BX, 2) // 43: inc bx +I286FN _inc_sp(void) INCWORD2(I286_SP, 2) // 44: inc sp +I286FN _inc_bp(void) INCWORD2(I286_BP, 2) // 45: inc bp +I286FN _inc_si(void) INCWORD2(I286_SI, 2) // 46: inc si +I286FN _inc_di(void) INCWORD2(I286_DI, 2) // 47: inc di +I286FN _dec_ax(void) DECWORD2(I286_AX, 2) // 48: dec ax +I286FN _dec_cx(void) DECWORD2(I286_CX, 2) // 49: dec cx +I286FN _dec_dx(void) DECWORD2(I286_DX, 2) // 4a: dec dx +I286FN _dec_bx(void) DECWORD2(I286_BX, 2) // 4b: dec bx +I286FN _dec_sp(void) DECWORD2(I286_SP, 2) // 4c: dec sp +I286FN _dec_bp(void) DECWORD2(I286_BP, 2) // 4d: dec bp +I286FN _dec_si(void) DECWORD2(I286_SI, 2) // 4e: dec si +I286FN _dec_di(void) DECWORD2(I286_DI, 2) // 4f: dec di + +I286FN _push_ax(void) REGPUSH(I286_AX, 3) // 50: push ax +I286FN _push_cx(void) REGPUSH(I286_CX, 3) // 51: push cx +I286FN _push_dx(void) REGPUSH(I286_DX, 3) // 52: push dx +I286FN _push_bx(void) REGPUSH(I286_BX, 3) // 53: push bx +I286FN _push_sp(void) SP_PUSH(I286_SP, 3) // 54: push sp +I286FN _push_bp(void) REGPUSH(I286_BP, 3) // 55: push bp +I286FN _push_si(void) REGPUSH(I286_SI, 3) // 56: push si +I286FN _push_di(void) REGPUSH(I286_DI, 3) // 57: push di +I286FN _pop_ax(void) REGPOP(I286_AX, 5) // 58: pop ax +I286FN _pop_cx(void) REGPOP(I286_CX, 5) // 59: pop cx +I286FN _pop_dx(void) REGPOP(I286_DX, 5) // 5A: pop dx +I286FN _pop_bx(void) REGPOP(I286_BX, 5) // 5B: pop bx +I286FN _pop_sp(void) SP_POP(I286_SP, 5) // 5C: pop sp +I286FN _pop_bp(void) REGPOP(I286_BP, 5) // 5D: pop bp +I286FN _pop_si(void) REGPOP(I286_SI, 5) // 5E: pop si +I286FN _pop_di(void) REGPOP(I286_DI, 5) // 5F: pop di + +#if (defined(ARM) || defined(X11)) && defined(BYTESEX_LITTLE) + +I286FN _pusha(void) { // 60: pusha + +// REG16 tmp; +// UINT32 addr; + + I286_WORKCLOCK(17); +// tmp = I286_SP; +// addr = tmp + SS_BASE; +// if ((tmp < 16) || (INHIBIT_WORDP(addr))) { + REGPUSH0(I286_AX) + REGPUSH0(I286_CX) + REGPUSH0(I286_DX) + REGPUSH0(I286_BX) + REGPUSH0(tmp) + REGPUSH0(I286_BP) + REGPUSH0(I286_SI) + REGPUSH0(I286_DI) +// } +// else { +// *(UINT16 *)(mem + addr - 2) = I286_AX; +// *(UINT16 *)(mem + addr - 4) = I286_CX; +// *(UINT16 *)(mem + addr - 6) = I286_DX; +// *(UINT16 *)(mem + addr - 8) = I286_BX; +// *(UINT16 *)(mem + addr - 10) = tmp; +// *(UINT16 *)(mem + addr - 12) = I286_BP; +// *(UINT16 *)(mem + addr - 14) = I286_SI; +// *(UINT16 *)(mem + addr - 16) = I286_DI; +// I286_SP -= 16; +// } +} + +I286FN _popa(void) { // 61: popa + +// UINT tmp; +// UINT32 addr; + + I286_WORKCLOCK(19); +// tmp = I286_SP + 16; +// addr = tmp + SS_BASE; +// if ((tmp >= 0x10000) || (INHIBIT_WORDP(addr))) { + REGPOP0(I286_DI); + REGPOP0(I286_SI); + REGPOP0(I286_BP); + I286_SP += 2; + REGPOP0(I286_BX); + REGPOP0(I286_DX); + REGPOP0(I286_CX); + REGPOP0(I286_AX); +// } +// else { +// I286_DI = *(UINT16 *)(mem + addr - 16); +// I286_SI = *(UINT16 *)(mem + addr - 14); +// I286_BP = *(UINT16 *)(mem + addr - 12); +// I286_BX = *(UINT16 *)(mem + addr - 8); +// I286_DX = *(UINT16 *)(mem + addr - 6); +// I286_CX = *(UINT16 *)(mem + addr - 4); +// I286_AX = *(UINT16 *)(mem + addr - 2); +// I286_SP = tmp; +// } +} + +#else + +I286FN _pusha(void) { // 60: pusha + + REG16 tmp; + + tmp = I286_SP; + REGPUSH0(I286_AX) + REGPUSH0(I286_CX) + REGPUSH0(I286_DX) + REGPUSH0(I286_BX) + REGPUSH0(tmp) + REGPUSH0(I286_BP) + REGPUSH0(I286_SI) + REGPUSH0(I286_DI) + I286_WORKCLOCK(17); +} + +I286FN _popa(void) { // 61: popa + + REGPOP0(I286_DI); + REGPOP0(I286_SI); + REGPOP0(I286_BP); + I286_SP += 2; + REGPOP0(I286_BX); + REGPOP0(I286_DX); + REGPOP0(I286_CX); + REGPOP0(I286_AX); + I286_WORKCLOCK(19); +} + +#endif + +I286FN _bound(void) { // 62: bound + + UINT vect = 0; + UINT op; + UINT32 madr; + REG16 reg; + + I286_WORKCLOCK(13); // ToDo + GET_PCBYTE(op); + if (op < 0xc0) { + reg = *(REG16_B53(op)); + madr = CALC_EA(op); + if (reg >= i286_memoryread_w(madr)) { + madr += 2; // ToDo + if (reg <= i286_memoryread_w(madr)) { + return; + } + } + vect = 5; + } + else { + vect = 6; + } + INT_NUM(vect, I286_IP); +} + +I286FN _arpl(void) { // 63: arpl + + UINT op; + UINT tmp; + + GET_PCBYTE(op) + tmp = ((op < 0xc0)?1:0); + I286_IP += (UINT8)tmp; + I286_WORKCLOCK(tmp + 10); + INT_NUM(6, I286_IP); +} + +I286FN _push_data16(void) { // 68: push DATA16 + + UINT16 tmp; + + GET_PCWORD(tmp) + REGPUSH(tmp, 3) +} + +I286FN _imul_reg_ea_data16(void) { // 69: imul REG, EA, DATA16 + + UINT16 *out; + UINT op; + SINT16 src; + SINT16 dst; + SINT32 res; + + PREPART_REG16_EA(op, src, out, 21, 24) + GET_PCWORD(dst) + WORD_IMUL(res, dst, src) + *out = (UINT16)res; +} + +I286FN _push_data8(void) { // 6A: push DATA8 + + UINT16 tmp; + + GET_PCBYTES(tmp) + REGPUSH(tmp, 3) +} + +I286FN _imul_reg_ea_data8(void) { // 6B: imul REG, EA, DATA8 + + UINT16 *out; + UINT op; + SINT16 src; + SINT16 dst; + SINT32 res; + + PREPART_REG16_EA(op, src, out, 21, 24) + GET_PCBYTES(dst) + WORD_IMUL(res, dst, src) + *out = (UINT16)res; +} + +I286FN _insb(void) { // 6C: insb + + REG8 dat; + + I286_WORKCLOCK(5); + dat = iocore_inp8(I286_DX); + i286_memorywrite(I286_DI + ES_BASE, dat); + I286_DI += STRING_DIR; +} + +I286FN _insw(void) { // 6D: insw + + REG16 dat; + + I286_WORKCLOCK(5); + dat = iocore_inp16(I286_DX); + i286_memorywrite_w(I286_DI + ES_BASE, dat); + I286_DI += STRING_DIRx2; +} + +I286FN _outsb(void) { // 6E: outsb + + REG8 dat; + + I286_WORKCLOCK(3); + dat = i286_memoryread(I286_SI + DS_FIX); + I286_SI += STRING_DIR; + iocore_out8(I286_DX, (UINT8)dat); +} + +I286FN _outsw(void) { // 6F: outsw + + REG16 dat; + + I286_WORKCLOCK(3); + dat = i286_memoryread_w(I286_SI + DS_FIX); + I286_SI += STRING_DIRx2; + iocore_out16(I286_DX, (UINT16)dat); +} + +I286EXT _jo_short(void) { // 70: jo short + + if (!I286_OV) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jno_short(void) { // 71: jno short + + if (I286_OV) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jc_short(void) { // 72: jnae/jb/jc short + + if (!(I286_FLAGL & C_FLAG)) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jnc_short(void) { // 73: jae/jnb/jnc short + + if (I286_FLAGL & C_FLAG) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jz_short(void) { // 74: je/jz short + + if (!(I286_FLAGL & Z_FLAG)) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jnz_short(void) { // 75: jne/jnz short + + if (I286_FLAGL & Z_FLAG) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jna_short(void) { // 76: jna/jbe short + + if (!(I286_FLAGL & (Z_FLAG | C_FLAG))) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _ja_short(void) { // 77: ja/jnbe short + if (I286_FLAGL & (Z_FLAG | C_FLAG)) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _js_short(void) { // 78: js short + + if (!(I286_FLAGL & S_FLAG)) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jns_short(void) { // 79: jns short + + if (I286_FLAGL & S_FLAG) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jp_short(void) { // 7A: jp/jpe short + + if (!(I286_FLAGL & P_FLAG)) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jnp_short(void) { // 7B: jnp/jpo short + + if (I286_FLAGL & P_FLAG) JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jl_short(void) { // 7C: jl/jnge short + + if (((I286_FLAGL & S_FLAG) == 0) == (I286_OV == 0)) + JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jnl_short(void) { // 7D: jnl/jge short + + if (((I286_FLAGL & S_FLAG) == 0) != (I286_OV == 0)) + JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jle_short(void) { // 7E: jle/jng short + + if ((!(I286_FLAGL & Z_FLAG)) && + (((I286_FLAGL & S_FLAG) == 0) == (I286_OV == 0))) + JMPNOP(3) else JMPSHORT(7) +} + +I286EXT _jnle_short(void) { // 7F: jg/jnle short + + if ((I286_FLAGL & Z_FLAG) || + (((I286_FLAGL & S_FLAG) == 0) != (I286_OV == 0))) + JMPNOP(3) else JMPSHORT(7) +} + +I286FN _calc_ea8_i8(void) { // 80: op EA8, DATA8 + // 82: op EA8, DATA8 + UINT8 *out; + UINT op; + UINT32 madr; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(3); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + c_op8xext8_table[(op >> 3) & 7](madr); + return; +// } +// out = mem + madr; + } + c_op8xreg8_table[(op >> 3) & 7](out); +} + +I286FN _calc_ea16_i16(void) { // 81: op EA16, DATA16 + + UINT16 *out; + UINT op; + UINT32 madr; + UINT32 src; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(3); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + GET_PCWORD(src); + c_op8xext16_table[(op >> 3) & 7](madr, src); + return; +// } +// out = (UINT16 *)(mem + madr); + } + GET_PCWORD(src); + c_op8xreg16_table[(op >> 3) & 7](out, src); +} + +I286FN _calc_ea16_i8(void) { // 83: op EA16, DATA8 + + UINT16 *out; + UINT op; + UINT32 madr; + UINT32 src; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(3); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + GET_PCBYTES(src); + c_op8xext16_table[(op >> 3) & 7](madr, src); + return; +// } +// out = (UINT16 *)(mem + madr); + } + GET_PCBYTES(src); + c_op8xreg16_table[(op >> 3) & 7](out, src); +} + +I286FN _test_ea_r8(void) { // 84: test EA, REG8 + + UINT8 *out; + UINT op; + UINT src; + UINT tmp; + UINT32 madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(6); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + tmp = i286_memoryread(madr); + ANDBYTE(tmp, src); + return; +// } +// out = mem + madr; + } + tmp = *out; + ANDBYTE(tmp, src); +} + +I286FN _test_ea_r16(void) { // 85: test EA, REG16 + + UINT16 *out; + UINT op; + UINT32 src; + UINT32 tmp; + UINT32 madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(6); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + tmp = i286_memoryread_w(madr); + ANDWORD(tmp, src); + return; +// } +// out = (UINT16 *)(mem + madr); + } + tmp = *out; + ANDWORD(tmp, src); +} + +I286FN _xchg_ea_r8(void) { // 86: xchg EA, REG8 + + UINT8 *out; + UINT8 *src; + UINT op; + UINT32 madr; + + PREPART_EA_REG8P(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(3); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(5); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + UINT8 tmp = i286_memoryread(madr); + i286_memorywrite(madr, *src); + *src = tmp; + return; +// } +// out = mem + madr; + } + SWAPBYTE(*out, *src); +} + +I286FN _xchg_ea_r16(void) { // 87: xchg EA, REG16 + + UINT16 *out; + UINT16 *src; + UINT op; + UINT32 madr; + + PREPART_EA_REG16P(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(3); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(5); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + UINT16 tmp = i286_memoryread_w(madr); + i286_memorywrite_w(madr, *src); + *src = tmp; + return; +// } +// out = (UINT16 *)(mem + madr); + } + SWAPWORD(*out, *src); +} + +I286FN _mov_ea_r8(void) { // 88: mov EA, REG8 + + UINT8 src; + UINT op; + UINT32 madr; + + PREPART_EA_REG8(op, src) + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG8_B20(op)) = src; + } + else { + I286_WORKCLOCK(3); + madr = CALC_EA(op); + i286_memorywrite(madr, src); + } +} + +I286FN _mov_ea_r16(void) { // 89: mov EA, REG16 + + UINT16 src; + UINT op; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG16_B20(op)) = src; + } + else { + I286_WORKCLOCK(3); + i286_memorywrite_w(CALC_EA(op), src); + } +} + +I286FN _mov_r8_ea(void) { // 8A: mov REG8, EA + + UINT8 *out; + UINT8 src; + UINT op; + + PREPART_REG8_EA(op, src, out, 2, 5); + *out = src; +} + +I286FN _mov_r16_ea(void) { // 8B: mov REG16, EA + + UINT16 *out; + UINT16 src; + UINT op; + + PREPART_REG16_EA(op, src, out, 2, 5); + *out = src; +} + +I286FN _mov_ea_seg(void) { // 8C: mov EA, segreg + + UINT op; + UINT16 tmp; + + GET_PCBYTE(op); + tmp = *SEGMENTPTR((op >> 3) & 3); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + *(REG16_B20(op)) = tmp; + } + else { + I286_WORKCLOCK(3); + i286_memorywrite_w(CALC_EA(op), tmp); + } +} + +I286FN _lea_r16_ea(void) { // 8D: lea REG16, EA + + UINT op; + + I286_WORKCLOCK(3); + GET_PCBYTE(op) + if (op < 0xc0) { + *(REG16_B53(op)) = CALC_LEA(op); + } + else { + INT_NUM(6, I286_SP - 2); + } +} + +I286FN _mov_seg_ea(void) { // 8E: mov segrem, EA + + UINT op; + UINT tmp; + UINT32 base; + UINT16 ipbak; + + ipbak = I286_IP; + GET_PCBYTE(op); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + tmp = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(5); + tmp = i286_memoryread_w(CALC_EA(op)); + } + base = SEGSELECT(tmp); + switch(op & 0x18) { + case 0x00: // es + I286_ES = (UINT16)tmp; + ES_BASE = base; + break; + + case 0x10: // ss + I286_SS = (UINT16)tmp; + SS_BASE = base; + SS_FIX = base; + NEXT_OPCODE + break; + + case 0x18: // ds + I286_DS = (UINT16)tmp; + DS_BASE = base; + DS_FIX = base; + break; + + default: // cs + INT_NUM(6, ipbak - 1); + break; + } +} + +I286FN _pop_ea(void) { // 8F: pop EA + + UINT op; + UINT16 tmp; + + I286_WORKCLOCK(5); + REGPOP0(tmp) + + GET_PCBYTE(op) + if (op < 0xc0) { + i286_memorywrite_w(CALC_EA(op), tmp); + } + else { + *(REG16_B20(op)) = tmp; + } +} + +I286FN _nop(void) { // 90: nop / bios func + +#if 0 // call BIOS + UINT32 adrs; + + adrs = LOW16(I286_IP - 1) + CS_BASE; + if ((adrs >= 0xf8000) && (adrs < 0x100000)) { + biosfunc(adrs); + ES_BASE = I286_ES << 4; + CS_BASE = I286_CS << 4; + SS_BASE = I286_SS << 4; + SS_FIX = SS_BASE; + DS_BASE = I286_DS << 4; + DS_FIX = DS_BASE; + } +#endif + I286_WORKCLOCK(3); +} + +I286FN _xchg_ax_cx(void) { // 91: xchg ax, cx + + I286_WORKCLOCK(3); + SWAPWORD(I286_AX, I286_CX); +} + +I286FN _xchg_ax_dx(void) { // 92: xchg ax, dx + + I286_WORKCLOCK(3); + SWAPWORD(I286_AX, I286_DX); +} + +I286FN _xchg_ax_bx(void) { // 93: xchg ax, bx + + I286_WORKCLOCK(3); + SWAPWORD(I286_AX, I286_BX); +} + +I286FN _xchg_ax_sp(void) { // 94: xchg ax, sp + + I286_WORKCLOCK(3); + SWAPWORD(I286_AX, I286_SP); +} + +I286FN _xchg_ax_bp(void) { // 95: xchg ax, bp + + I286_WORKCLOCK(3); + SWAPWORD(I286_AX, I286_BP); +} + +I286FN _xchg_ax_si(void) { // 96: xchg ax, si + + I286_WORKCLOCK(3); + SWAPWORD(I286_AX, I286_SI); +} + +I286FN _xchg_ax_di(void) { // 97: xchg ax, di + + I286_WORKCLOCK(3); + SWAPWORD(I286_AX, I286_DI); +} + +I286FN _cbw(void) { // 98: cbw + + I286_WORKCLOCK(2); + I286_AX = __CBW(I286_AL); +} + +I286FN _cwd(void) { // 99: cwd + + I286_WORKCLOCK(2); + I286_DX = ((I286_AH & 0x80)?0xffff:0x0000); +} + +I286FN _call_far(void) { // 9A: call far + + UINT16 newip, newcs; + + I286_WORKCLOCK(13); +// REGPUSH0(I286_CS) + GET_PCWORD(newip) +// GET_PCWORD(I286_CS) + GET_PCWORD(newcs) + +#ifdef I86_PSEUDO_BIOS + if (device_bios != NULL) { + uint16_t regs[8] = {CPU_AX, CPU_CX, CPU_DX, CPU_BX, CPU_SP, CPU_BP, CPU_SI, CPU_DI}; + uint16_t sregs[4] = {CPU_ES, CPU_CS, CPU_SS, CPU_DS}; + int32_t ZeroFlag = ((CPU_FLAG & Z_FLAG) ? 1 : 0); + int32_t CarryFlag = ((CPU_FLAG & C_FLAG) ? 1 : 0); + + if (device_bios->bios_call_far_i86((newcs << 4) + newip, regs, sregs, &ZeroFlag, &CarryFlag)) { + CPU_AX = regs[0]; + CPU_CX = regs[1]; + CPU_DX = regs[2]; + CPU_BX = regs[3]; + CPU_SP = regs[4]; + CPU_BP = regs[5]; + CPU_SI = regs[6]; + CPU_DI = regs[7]; + if (ZeroFlag) { + CPU_FLAG |= Z_FLAG; + } else { + CPU_FLAG &= ~Z_FLAG; + } + if (CarryFlag) { + CPU_FLAG |= C_FLAG; + } else { + CPU_FLAG &= ~C_FLAG; + } + I286_WORKCLOCK(1000); // temporary + return; + } + } +#endif + + REGPUSH0(I286_CS) + I286_CS = newcs; + CS_BASE = SEGSELECT(I286_CS); + REGPUSH0(I286_IP) + I286_IP = newip; +} + +I286FN _wait(void) { // 9B: wait + + I286_WORKCLOCK(2); +} + +I286FN _pushf(void) { // 9C: pushf + + REGPUSH(REAL_FLAGREG, 3) +} + +I286FN _popf(void) { // 9D: popf + + UINT flag; + + REGPOP0(flag) + I286_OV = flag & O_FLAG; + I286_FLAG = flag & (0xfff ^ O_FLAG); + I286_TRAP = ((flag & 0x300) == 0x300); + I286_WORKCLOCK(5); +#if defined(INTR_FAST) + if ((I286_TRAP) || ((flag & I_FLAG) && (PICEXISTINTR))) { + I286IRQCHECKTERM + } +#else + I286IRQCHECKTERM +#endif +} + +I286FN _sahf(void) { // 9E: sahf + + I286_WORKCLOCK(2); + I286_FLAGL = I286_AH | 2; +} + +I286FN _lahf(void) { // 9F: lahf + + I286_WORKCLOCK(2); + I286_AH = I286_FLAGL | 2; +} + +I286FN _mov_al_m8(void) { // A0: mov al, m8 + + UINT op; + + I286_WORKCLOCK(5); + GET_PCWORD(op) + I286_AL = i286_memoryread(DS_FIX + op); +} + +I286FN _mov_ax_m16(void) { // A1: mov ax, m16 + + UINT op; + + I286_WORKCLOCK(5); + GET_PCWORD(op) + I286_AX = i286_memoryread_w(DS_FIX + op); +} + +I286FN _mov_m8_al(void) { // A2: mov m8, al + + UINT op; + + I286_WORKCLOCK(3); + GET_PCWORD(op) + i286_memorywrite(DS_FIX + op, I286_AL); +} + +I286FN _mov_m16_ax(void) { // A3: mov m16, ax + + UINT op; + + I286_WORKCLOCK(3); + GET_PCWORD(op); + i286_memorywrite_w(DS_FIX + op, I286_AX); +} + +I286FN _movsb(void) { // A4: movsb + + UINT8 tmp; + + I286_WORKCLOCK(5); + tmp = i286_memoryread(I286_SI + DS_FIX); + i286_memorywrite(I286_DI + ES_BASE, tmp); + I286_SI += STRING_DIR; + I286_DI += STRING_DIR; +} + +I286FN _movsw(void) { // A5: movsw + + UINT16 tmp; + + I286_WORKCLOCK(5); + tmp = i286_memoryread_w(I286_SI + DS_FIX); + i286_memorywrite_w(I286_DI + ES_BASE, tmp); + I286_SI += STRING_DIRx2; + I286_DI += STRING_DIRx2; +} + +I286FN _cmpsb(void) { // A6: cmpsb + + UINT src; + UINT dst; + UINT res; + + I286_WORKCLOCK(8); + dst = i286_memoryread(I286_SI + DS_FIX); + src = i286_memoryread(I286_DI + ES_BASE); + SUBBYTE(res, dst, src) + I286_SI += STRING_DIR; + I286_DI += STRING_DIR; +} + +I286FN _cmpsw(void) { // A7: cmpsw + + UINT32 src; + UINT32 dst; + UINT32 res; + + I286_WORKCLOCK(8); + dst = i286_memoryread_w(I286_SI + DS_FIX); + src = i286_memoryread_w(I286_DI + ES_BASE); + SUBWORD(res, dst, src) + I286_SI += STRING_DIRx2; + I286_DI += STRING_DIRx2; +} + +I286FN _test_al_data8(void) { // A8: test al, DATA8 + + UINT src; + UINT dst; + + I286_WORKCLOCK(3); + GET_PCBYTE(src) + dst = I286_AL; + ANDBYTE(dst, src) +} + +I286FN _test_ax_data16(void) { // A9: test ax, DATA16 + + UINT32 src; + UINT32 dst; + + I286_WORKCLOCK(3); + GET_PCWORD(src) + dst = I286_AX; + ANDWORD(dst, src) +} + +I286FN _stosb(void) { // AA: stosw + + I286_WORKCLOCK(3); + i286_memorywrite(I286_DI + ES_BASE, I286_AL); + I286_DI += STRING_DIR; +} + +I286FN _stosw(void) { // AB: stosw + + I286_WORKCLOCK(3); + i286_memorywrite_w(I286_DI + ES_BASE, I286_AX); + I286_DI += STRING_DIRx2; +} + +I286FN _lodsb(void) { // AC: lodsb + + I286_WORKCLOCK(5); + I286_AL = i286_memoryread(I286_SI + DS_FIX); + I286_SI += STRING_DIR; +} + +I286FN _lodsw(void) { // AD: lodsw + + I286_WORKCLOCK(5); + I286_AX = i286_memoryread_w(I286_SI + DS_FIX); + I286_SI += STRING_DIRx2; +} + +I286FN _scasb(void) { // AE: scasb + + UINT src; + UINT dst; + UINT res; + + I286_WORKCLOCK(7); + src = i286_memoryread(I286_DI + ES_BASE); + dst = I286_AL; + SUBBYTE(res, dst, src) + I286_DI += STRING_DIR; +} + +I286FN _scasw(void) { // AF: scasw + + UINT32 src; + UINT32 dst; + UINT32 res; + + I286_WORKCLOCK(7); + src = i286_memoryread_w(I286_DI + ES_BASE); + dst = I286_AX; + SUBWORD(res, dst, src) + I286_DI += STRING_DIRx2; +} + +I286FN _mov_al_imm(void) MOVIMM8(I286_AL) // B0: mov al, imm8 +I286FN _mov_cl_imm(void) MOVIMM8(I286_CL) // B1: mov cl, imm8 +I286FN _mov_dl_imm(void) MOVIMM8(I286_DL) // B2: mov dl, imm8 +I286FN _mov_bl_imm(void) MOVIMM8(I286_BL) // B3: mov bl, imm8 +I286FN _mov_ah_imm(void) MOVIMM8(I286_AH) // B4: mov ah, imm8 +I286FN _mov_ch_imm(void) MOVIMM8(I286_CH) // B5: mov ch, imm8 +I286FN _mov_dh_imm(void) MOVIMM8(I286_DH) // B6: mov dh, imm8 +I286FN _mov_bh_imm(void) MOVIMM8(I286_BH) // B7: mov bh, imm8 +I286FN _mov_ax_imm(void) MOVIMM16(I286_AX) // B8: mov ax, imm16 +I286FN _mov_cx_imm(void) MOVIMM16(I286_CX) // B9: mov cx, imm16 +I286FN _mov_dx_imm(void) MOVIMM16(I286_DX) // BA: mov dx, imm16 +I286FN _mov_bx_imm(void) MOVIMM16(I286_BX) // BB: mov bx, imm16 +I286FN _mov_sp_imm(void) MOVIMM16(I286_SP) // BC: mov sp, imm16 +I286FN _mov_bp_imm(void) MOVIMM16(I286_BP) // BD: mov bp, imm16 +I286FN _mov_si_imm(void) MOVIMM16(I286_SI) // BE: mov si, imm16 +I286FN _mov_di_imm(void) MOVIMM16(I286_DI) // BF: mov di, imm16 + +I286FN _shift_ea8_data8(void) { // C0: shift EA8, DATA8 + + UINT8 *out; + UINT op; + UINT32 madr; + UINT8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + GET_PCBYTE(cl) + I286_WORKCLOCK(cl); + sft_e8cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = mem + madr; + } + GET_PCBYTE(cl) + I286_WORKCLOCK(cl); + sft_r8cl_table[(op >> 3) & 7](out, cl); +} + +I286FN _shift_ea16_data8(void) { // C1: shift EA16, DATA8 + + UINT16 *out; + UINT op; + UINT32 madr; + UINT8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + GET_PCBYTE(cl); + I286_WORKCLOCK(cl); + sft_e16cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = (UINT16 *)(mem + madr); + } + GET_PCBYTE(cl); + I286_WORKCLOCK(cl); + sft_r16cl_table[(op >> 3) & 7](out, cl); +} + +I286EXT _ret_near_data16(void) { // C2: ret near DATA16 + + UINT16 ad; + + I286_WORKCLOCK(11); + GET_PCWORD(ad) + REGPOP0(I286_IP) + I286_SP += ad; +} + +I286EXT _ret_near(void) { // C3: ret near + + I286_WORKCLOCK(11); + REGPOP0(I286_IP) +} + +I286FN _les_r16_ea(void) { // C4: les REG16, EA + + UINT op; + UINT32 seg; + UINT ad; + + I286_WORKCLOCK(3); + GET_PCBYTE(op) + if (op < 0xc0) { + ad = GET_EA(op, &seg); + *(REG16_B53(op)) = i286_memoryread_w(seg + ad); + I286_ES = i286_memoryread_w(seg + LOW16(ad + 2)); + ES_BASE = SEGSELECT(I286_ES); + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286FN _lds_r16_ea(void) { // C5: lds REG16, EA + + UINT op; + UINT32 seg; + UINT ad; + + I286_WORKCLOCK(3); + GET_PCBYTE(op) + if (op < 0xc0) { + ad = GET_EA(op, &seg); + *(REG16_B53(op)) = i286_memoryread_w(seg + ad); + I286_DS = i286_memoryread_w(seg + LOW16(ad + 2)); + DS_BASE = SEGSELECT(I286_DS); + DS_FIX = DS_BASE; + } + else { + INT_NUM(6, I286_IP - 2); + } +} + +I286FN _mov_ea8_data8(void) { // C6: mov EA8, DATA8 + + UINT op; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(2); + GET_PCBYTE(*(REG8_B53(op))) + } + else { // 03/11/23 + UINT32 ad; + UINT8 val; + I286_WORKCLOCK(3); + ad = CALC_EA(op); + GET_PCBYTE(val) + i286_memorywrite(ad, val); + } +} + +I286FN _mov_ea16_data16(void) { // C7: mov EA16, DATA16 + + UINT op; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(2); + GET_PCWORD(*(REG16_B53(op))) + } + else { // 03/11/23 + UINT32 ad; + UINT16 val; + I286_WORKCLOCK(3); + ad = CALC_EA(op); + GET_PCWORD(val) + i286_memorywrite_w(ad, val); + } +} + +I286FN _enter(void) { // C8: enter DATA16, DATA8 + + UINT16 dimsize; + UINT8 level; + + GET_PCWORD(dimsize) + GET_PCBYTE(level) + REGPUSH0(I286_BP) + level &= 0x1f; + if (!level) { // enter level=0 + I286_WORKCLOCK(11); + I286_BP = I286_SP; + I286_SP -= dimsize; + } + else { + level--; + if (!level) { // enter level=1 + UINT16 tmp; + I286_WORKCLOCK(15); + tmp = I286_SP; + REGPUSH0(tmp) + I286_BP = tmp; + I286_SP -= dimsize; + } + else { // enter level=2-31 + UINT16 bp; + I286_WORKCLOCK(12 + 4 + level*4); + bp = I286_BP; + I286_BP = I286_SP; + while(level--) { +#if 1 // なにやってんだヲレ + REG16 val; + bp -= 2; + I286_SP -= 2; + val = i286_memoryread_w(bp + SS_BASE); + i286_memorywrite_w(I286_SP + SS_BASE, val); +#else + UINT16 val = i286_memoryread_w(bp + SS_BASE); + i286_memorywrite_w(I286_SP + SS_BASE, val); + bp -= 2; + I286_SP -= 2; +#endif + } + REGPUSH0(I286_BP) + I286_SP -= dimsize; + } + } +} + +I286FN fleave(void) { // C9: leave + + I286_WORKCLOCK(5); + I286_SP = I286_BP; + REGPOP0(I286_BP) +} + +I286EXT _ret_far_data16(void) { // CA: ret far DATA16 + + UINT16 ad; + + I286_WORKCLOCK(15); + GET_PCWORD(ad) + REGPOP0(I286_IP) + REGPOP0(I286_CS) + I286_SP += ad; + CS_BASE = SEGSELECT(I286_CS); +} + +I286EXT _ret_far(void) { // CB: ret far + + I286_WORKCLOCK(15); + REGPOP0(I286_IP) + REGPOP0(I286_CS) + CS_BASE = SEGSELECT(I286_CS); +} + +I286FN _int_03(void) { // CC: int 3 + + I286_WORKCLOCK(3); + INT_NUM(3, I286_IP); +} + +I286FN _int_data8(void) { // CD: int DATA8 + + UINT vect; + + I286_WORKCLOCK(3); + GET_PCBYTE(vect) +#if defined(ENABLE_TRAP) + softinttrap(CPU_CS, CPU_IP - 2, vect); +#endif + INT_NUM(vect, I286_IP); +} + +I286FN _into(void) { // CE: into + + I286_WORKCLOCK(4); + if (I286_OV) { + INT_NUM(4, I286_IP); + } +} + +I286FN _iret(void) { // CF: iret + + UINT flag; + + REGPOP0(I286_IP) + REGPOP0(I286_CS) + REGPOP0(flag) + I286_OV = flag & O_FLAG; + I286_FLAG = flag & (0xfff ^ O_FLAG); + I286_TRAP = ((flag & 0x300) == 0x300); +// CS_BASE = I286_CS << 4; + CS_BASE = SEGSELECT(I286_CS); + I286_WORKCLOCK(31); +#if defined(INTR_FAST) + if ((I286_TRAP) || ((flag & I_FLAG) && (PICEXISTINTR))) { + I286IRQCHECKTERM + } +#else + I286IRQCHECKTERM +#endif +} + +I286FN _shift_ea8_1(void) { // D0: shift EA8, 1 + + UINT8 *out; + UINT op; + UINT32 madr; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + sft_e8_table[(op >> 3) & 7](madr); + return; +// } +// out = mem + madr; + } + sft_r8_table[(op >> 3) & 7](out); +} + +I286FN _shift_ea16_1(void) { // D1: shift EA16, 1 + + UINT16 *out; + UINT op; + UINT32 madr; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(2); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(7); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + sft_e16_table[(op >> 3) & 7](madr); + return; +// } +// out = (UINT16 *)(mem + madr); + } + sft_r16_table[(op >> 3) & 7](out); +} + +I286FN _shift_ea8_cl(void) { // D2: shift EA8, cl + + UINT8 *out; + UINT op; + UINT32 madr; + REG8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + cl = I286_CL; + I286_WORKCLOCK(cl); + sft_e8cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = mem + madr; + } + cl = I286_CL; + I286_WORKCLOCK(cl); + sft_r8cl_table[(op >> 3) & 7](out, cl); +} + +I286FN _shift_ea16_cl(void) { // D3: shift EA16, cl + + UINT16 *out; + UINT op; + UINT32 madr; + REG8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + cl = I286_CL; + I286_WORKCLOCK(cl); + sft_e16cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = (UINT16 *)(mem + madr); + } + cl = I286_CL; + I286_WORKCLOCK(cl); + sft_r16cl_table[(op >> 3) & 7](out, cl); +} + +I286FN _aam(void) { // D4: AAM + + UINT8 al; + UINT8 div; + + I286_WORKCLOCK(16); + GET_PCBYTE(div); + if (div) { + al = I286_AL; + I286_AH = al / div; + I286_AL = al % div; + I286_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); + I286_FLAGL |= WORDSZPF(I286_AX); + } + else { + INT_NUM(0, I286_IP - 2); // 80286 +// INT_NUM(0, I286_IP); // V30 + } +} + +I286FN _aad(void) { // D5: AAD + + UINT8 mul; + + I286_WORKCLOCK(14); + GET_PCBYTE(mul); + I286_AL += (UINT8)(I286_AH * mul); + I286_AH = 0; + I286_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); + I286_FLAGL |= BYTESZPF(I286_AL); +} + +I286FN _setalc(void) { // D6: setalc (80286) + + I286_AL = ((I286_FLAGL & C_FLAG)?0xff:0); +} + +I286FN _xlat(void) { // D7: xlat + + I286_WORKCLOCK(5); + I286_AL = i286_memoryread(LOW16(I286_AL + I286_BX) + DS_FIX); +} + +I286FN _esc(void) { // D8: esc + + UINT op; + + I286_WORKCLOCK(2); + GET_PCBYTE(op) + if (op < 0xc0) { + CALC_LEA(op); + } +} + +I286FN _loopnz(void) { // E0: loopnz + + I286_CX--; + if ((!I286_CX) || (I286_FLAGL & Z_FLAG)) JMPNOP(4) else JMPSHORT(8) +} + +I286FN _loopz(void) { // E1: loopz + + I286_CX--; + if ((!I286_CX) || (!(I286_FLAGL & Z_FLAG))) JMPNOP(4) else JMPSHORT(8) +} + +I286FN _loop(void) { // E2: loop + + I286_CX--; + if (!I286_CX) JMPNOP(4) else JMPSHORT(8) +} + +I286FN _jcxz(void) { // E3: jcxz + + if (I286_CX) JMPNOP(4) else JMPSHORT(8) +} + +I286FN _in_al_data8(void) { // E4: in al, DATA8 + + UINT port; + + I286_WORKCLOCK(5); + GET_PCBYTE(port) + I286_INPADRS = CS_BASE + I286_IP; + I286_AL = iocore_inp8(port); + I286_INPADRS = 0; +} + +I286FN _in_ax_data8(void) { // E5: in ax, DATA8 + + UINT port; + + I286_WORKCLOCK(5); + GET_PCBYTE(port) + I286_AX = iocore_inp16(port); +} + +I286FN _out_data8_al(void) { // E6: out DATA8, al + + UINT port; + + I286_WORKCLOCK(3); + GET_PCBYTE(port); + iocore_out8(port, I286_AL); +} + +I286FN _out_data8_ax(void) { // E7: out DATA8, ax + + UINT port; + + I286_WORKCLOCK(3); + GET_PCBYTE(port); + iocore_out16(port, I286_AX); +} + +I286FN _call_near(void) { // E8: call near + + UINT16 ad; + + I286_WORKCLOCK(7); + GET_PCWORD(ad) + REGPUSH0(I286_IP) + I286_IP += ad; +} + +I286FN _jmp_near(void) { // E9: jmp near + + UINT16 ad; + + I286_WORKCLOCK(7); + GET_PCWORD(ad) + I286_IP += ad; +} + +I286FN _jmp_far(void) { // EA: jmp far + + UINT16 ad; + + I286_WORKCLOCK(11); + GET_PCWORD(ad); + GET_PCWORD(I286_CS); + I286_IP = ad; + CS_BASE = SEGSELECT(I286_CS); +} + +I286FN _jmp_short(void) { // EB: jmp short + + UINT16 ad; + + I286_WORKCLOCK(7); + GET_PCBYTES(ad) + I286_IP += ad; +} + +I286FN _in_al_dx(void) { // EC: in al, dx + + I286_WORKCLOCK(5); + I286_AL = iocore_inp8(I286_DX); +} + +I286FN _in_ax_dx(void) { // ED: in ax, dx + + I286_WORKCLOCK(5); + I286_AX = iocore_inp16(I286_DX); +} + +I286FN _out_dx_al(void) { // EE: out dx, al + + I286_WORKCLOCK(3); + iocore_out8(I286_DX, I286_AL); +} + +I286FN _out_dx_ax(void) { // EF: out dx, ax + + I286_WORKCLOCK(3); + iocore_out16(I286_DX, I286_AX); +} + +I286FN _lock(void) { // F0: lock + // F1: lock + I286_WORKCLOCK(2); +} + +I286FN _repne(void) { // F2: repne + + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repne[op](); + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _repe(void) { // F3: repe + + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repe[op](); + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _hlt(void) { // F4: hlt + + I286_REMCLOCK = -1; + I286_IP--; +} + +I286FN _cmc(void) { // F5: cmc + + I286_WORKCLOCK(2); + I286_FLAGL ^= C_FLAG; +} + +I286FN _ope0xf6(void) { // F6: + + UINT op; + + GET_PCBYTE(op); + c_ope0xf6_table[(op >> 3) & 7](op); +} + +I286FN _ope0xf7(void) { // F7: + + UINT op; + + GET_PCBYTE(op); + c_ope0xf7_table[(op >> 3) & 7](op); +} + +I286FN _clc(void) { // F8: clc + + I286_WORKCLOCK(2); + I286_FLAGL &= ~C_FLAG; +} + +I286FN _stc(void) { // F9: stc + + I286_WORKCLOCK(2); + I286_FLAGL |= C_FLAG; +} + +I286FN _cli(void) { // FA: cli + + I286_WORKCLOCK(2); + I286_FLAG &= ~I_FLAG; + I286_TRAP = 0; +} + +I286FN _sti(void) { // FB: sti + + I286_WORKCLOCK(2); +#if defined(INTR_FAST) + if (I286_FLAG & I_FLAG) { + NEXT_OPCODE; + return; // 更新の意味なし + } +#endif + I286_FLAG |= I_FLAG; + I286_TRAP = (I286_FLAG & T_FLAG) >> 8; +#if defined(INTR_FAST) + if ((I286_TRAP) || (PICEXISTINTR)) { + REMAIN_ADJUST(1) + } + else { + NEXT_OPCODE; + } +#else + REMAIN_ADJUST(1) +#endif +} + +I286FN _cld(void) { // FC: cld + + I286_WORKCLOCK(2); + I286_FLAG &= ~D_FLAG; +} + +I286FN _std(void) { // FD: std + + I286_WORKCLOCK(2); + I286_FLAG |= D_FLAG; +} + +I286FN _ope0xfe(void) { // FE: + + UINT op; + + GET_PCBYTE(op); + c_ope0xfe_table[(op >> 3) & 1](op); +} + +I286FN _ope0xff(void) { // FF: + + UINT op; + + GET_PCBYTE(op); + c_ope0xff_table[(op >> 3) & 7](op); +} + +// ------------------------------------------------------------------------- + +const I286OP i286op[] = { + _add_ea_r8, // 00: add EA, REG8 + _add_ea_r16, // 01: add EA, REG16 + _add_r8_ea, // 02: add REG8, EA + _add_r16_ea, // 03: add REG16, EA + _add_al_data8, // 04: add al, DATA8 + _add_ax_data16, // 05: add ax, DATA16 + _push_es, // 06: push es + _pop_es, // 07: pop es + _or_ea_r8, // 08: or EA, REGF8 + _or_ea_r16, // 09: or EA, REG16 + _or_r8_ea, // 0A: or REG8, EA + _or_r16_ea, // 0B: or REG16, EA + _or_al_data8, // 0C: or al, DATA8 + _or_ax_data16, // 0D: or ax, DATA16 + _push_cs, // 0E: push cs + i286c_cts, // 0F: i286 upper opcode + + _adc_ea_r8, // 10: adc EA, REG8 + _adc_ea_r16, // 11: adc EA, REG16 + _adc_r8_ea, // 12: adc REG8, EA + _adc_r16_ea, // 13: adc REG16, EA + _adc_al_data8, // 14: adc al, DATA8 + _adc_ax_data16, // 15: adc ax, DATA16 + _push_ss, // 16: push ss + _pop_ss, // 17: pop ss + _sbb_ea_r8, // 18: sbb EA, REG8 + _sbb_ea_r16, // 19: sbb EA, REG16 + _sbb_r8_ea, // 1A: sbb REG8, EA + _sbb_r16_ea, // 1B: sbb REG16, EA + _sbb_al_data8, // 1C: sbb al, DATA8 + _sbb_ax_data16, // 1D: sbb ax, DATA16 + _push_ds, // 1E: push ds + _pop_ds, // 1F: pop ds + + _and_ea_r8, // 20: and EA, REG8 + _and_ea_r16, // 21: and EA, REG16 + _and_r8_ea, // 22: and REG8, EA + _and_r16_ea, // 23: and REG16, EA + _and_al_data8, // 24: and al, DATA8 + _and_ax_data16, // 25: and ax, DATA16 + _segprefix_es, // 26: es: + _daa, // 27: daa + _sub_ea_r8, // 28: sub EA, REG8 + _sub_ea_r16, // 29: sub EA, REG16 + _sub_r8_ea, // 2A: sub REG8, EA + _sub_r16_ea, // 2B: sub REG16, EA + _sub_al_data8, // 2C: sub al, DATA8 + _sub_ax_data16, // 2D: sub ax, DATA16 + _segprefix_cs, // 2E: cs: + _das, // 2F: das + + _xor_ea_r8, // 30: xor EA, REG8 + _xor_ea_r16, // 31: xor EA, REG16 + _xor_r8_ea, // 32: xor REG8, EA + _xor_r16_ea, // 33: xor REG16, EA + _xor_al_data8, // 34: xor al, DATA8 + _xor_ax_data16, // 35: xor ax, DATA16 + _segprefix_ss, // 36: ss: + _aaa, // 37: aaa + _cmp_ea_r8, // 38: cmp EA, REG8 + _cmp_ea_r16, // 39: cmp EA, REG16 + _cmp_r8_ea, // 3A: cmp REG8, EA + _cmp_r16_ea, // 3B: cmp REG16, EA + _cmp_al_data8, // 3C: cmp al, DATA8 + _cmp_ax_data16, // 3D: cmp ax, DATA16 + _segprefix_ds, // 3E: ds: + _aas, // 3F: aas + + _inc_ax, // 40: inc ax + _inc_cx, // 41: inc cx + _inc_dx, // 42: inc dx + _inc_bx, // 43: inc bx + _inc_sp, // 44: inc sp + _inc_bp, // 45: inc bp + _inc_si, // 46: inc si + _inc_di, // 47: inc di + _dec_ax, // 48: dec ax + _dec_cx, // 49: dec cx + _dec_dx, // 4A: dec dx + _dec_bx, // 4B: dec bx + _dec_sp, // 4C: dec sp + _dec_bp, // 4D: dec bp + _dec_si, // 4E: dec si + _dec_di, // 4F: dec di + + _push_ax, // 50: push ax + _push_cx, // 51: push cx + _push_dx, // 52: push dx + _push_bx, // 53: push bx + _push_sp, // 54: push sp + _push_bp, // 55: push bp + _push_si, // 56: push si + _push_di, // 57: push di + _pop_ax, // 58: pop ax + _pop_cx, // 59: pop cx + _pop_dx, // 5A: pop dx + _pop_bx, // 5B: pop bx + _pop_sp, // 5C: pop sp + _pop_bp, // 5D: pop bp + _pop_si, // 5E: pop si + _pop_di, // 5F: pop di + + _pusha, // 60: pusha + _popa, // 61: popa + _bound, // 62: bound + _arpl, // 63: arpl + _reserved, // 64: reserved + _reserved, // 65: reserved + _reserved, // 66: reserved + _reserved, // 67: reserved + _push_data16, // 68: push DATA16 + _imul_reg_ea_data16, // 69: imul REG, EA, DATA16 + _push_data8, // 6A: push DATA8 + _imul_reg_ea_data8, // 6B: imul REG, EA, DATA8 + _insb, // 6C: insb + _insw, // 6D: insw + _outsb, // 6E: outsb + _outsw, // 6F: outsw + + _jo_short, // 70: jo short + _jno_short, // 71: jno short + _jc_short, // 72: jnae/jb/jc short + _jnc_short, // 73: jae/jnb/jnc short + _jz_short, // 74: je/jz short + _jnz_short, // 75: jne/jnz short + _jna_short, // 76: jna/jbe short + _ja_short, // 77: ja/jnbe short + _js_short, // 78: js short + _jns_short, // 79: jns short + _jp_short, // 7A: jp/jpe short + _jnp_short, // 7B: jnp/jpo short + _jl_short, // 7C: jl/jnge short + _jnl_short, // 7D: jnl/jge short + _jle_short, // 7E: jle/jng short + _jnle_short, // 7F: jg/jnle short + + _calc_ea8_i8, // 80: op EA8, DATA8 + _calc_ea16_i16, // 81: op EA16, DATA16 + _calc_ea8_i8, // 82: op EA8, DATA8 + _calc_ea16_i8, // 83: op EA16, DATA8 + _test_ea_r8, // 84: test EA, REG8 + _test_ea_r16, // 85: test EA, REG16 + _xchg_ea_r8, // 86: xchg EA, REG8 + _xchg_ea_r16, // 87: xchg EA, REG16 + _mov_ea_r8, // 88: mov EA, REG8 + _mov_ea_r16, // 89: mov EA, REG16 + _mov_r8_ea, // 8A: mov REG8, EA + _mov_r16_ea, // 8B: mov REG16, EA + _mov_ea_seg, // 8C: mov EA, segreg + _lea_r16_ea, // 8D: lea REG16, EA + _mov_seg_ea, // 8E: mov segrem, EA + _pop_ea, // 8F: pop EA + + _nop, // 90: xchg ax, ax + _xchg_ax_cx, // 91: xchg ax, cx + _xchg_ax_dx, // 92: xchg ax, dx + _xchg_ax_bx, // 93: xchg ax, bx + _xchg_ax_sp, // 94: xchg ax, sp + _xchg_ax_bp, // 95: xchg ax, bp + _xchg_ax_si, // 96: xchg ax, si + _xchg_ax_di, // 97: xchg ax, di + _cbw, // 98: cbw + _cwd, // 99: cwd + _call_far, // 9A: call far + _wait, // 9B: wait + _pushf, // 9C: pushf + _popf, // 9D: popf + _sahf, // 9E: sahf + _lahf, // 9F: lahf + + _mov_al_m8, // A0: mov al, m8 + _mov_ax_m16, // A1: mov ax, m16 + _mov_m8_al, // A2: mov m8, al + _mov_m16_ax, // A3: mov m16, ax + _movsb, // A4: movsb + _movsw, // A5: movsw + _cmpsb, // A6: cmpsb + _cmpsw, // A7: cmpsw + _test_al_data8, // A8: test al, DATA8 + _test_ax_data16, // A9: test ax, DATA16 + _stosb, // AA: stosw + _stosw, // AB: stosw + _lodsb, // AC: lodsb + _lodsw, // AD: lodsw + _scasb, // AE: scasb + _scasw, // AF: scasw + + _mov_al_imm, // B0: mov al, imm8 + _mov_cl_imm, // B1: mov cl, imm8 + _mov_dl_imm, // B2: mov dl, imm8 + _mov_bl_imm, // B3: mov bl, imm8 + _mov_ah_imm, // B4: mov ah, imm8 + _mov_ch_imm, // B5: mov ch, imm8 + _mov_dh_imm, // B6: mov dh, imm8 + _mov_bh_imm, // B7: mov bh, imm8 + _mov_ax_imm, // B8: mov ax, imm16 + _mov_cx_imm, // B9: mov cx, imm16 + _mov_dx_imm, // BA: mov dx, imm16 + _mov_bx_imm, // BB: mov bx, imm16 + _mov_sp_imm, // BC: mov sp, imm16 + _mov_bp_imm, // BD: mov bp, imm16 + _mov_si_imm, // BE: mov si, imm16 + _mov_di_imm, // BF: mov di, imm16 + + _shift_ea8_data8, // C0: shift EA8, DATA8 + _shift_ea16_data8, // C1: shift EA16, DATA8 + _ret_near_data16, // C2: ret near DATA16 + _ret_near, // C3: ret near + _les_r16_ea, // C4: les REG16, EA + _lds_r16_ea, // C5: lds REG16, EA + _mov_ea8_data8, // C6: mov EA8, DATA8 + _mov_ea16_data16, // C7: mov EA16, DATA16 + _enter, // C8: enter DATA16, DATA8 + fleave, // C9: leave + _ret_far_data16, // CA: ret far DATA16 + _ret_far, // CB: ret far + _int_03, // CC: int 3 + _int_data8, // CD: int DATA8 + _into, // CE: into + _iret, // CF: iret + + _shift_ea8_1, // D0: shift EA8, 1 + _shift_ea16_1, // D1: shift EA16, 1 + _shift_ea8_cl, // D2: shift EA8, cl + _shift_ea16_cl, // D3: shift EA16, cl + _aam, // D4: AAM + _aad, // D5: AAD + _setalc, // D6: setalc (80286) + _xlat, // D7: xlat + _esc, // D8: esc + _esc, // D9: esc + _esc, // DA: esc + _esc, // DB: esc + _esc, // DC: esc + _esc, // DD: esc + _esc, // DE: esc + _esc, // DF: esc + + _loopnz, // E0: loopnz + _loopz, // E1: loopz + _loop, // E2: loop + _jcxz, // E3: jcxz + _in_al_data8, // E4: in al, DATA8 + _in_ax_data8, // E5: in ax, DATA8 + _out_data8_al, // E6: out DATA8, al + _out_data8_ax, // E7: out DATA8, ax + _call_near, // E8: call near + _jmp_near, // E9: jmp near + _jmp_far, // EA: jmp far + _jmp_short, // EB: jmp short + _in_al_dx, // EC: in al, dx + _in_ax_dx, // ED: in ax, dx + _out_dx_al, // EE: out dx, al + _out_dx_ax, // EF: out dx, ax + + _lock, // F0: lock + _lock, // F1: lock + _repne, // F2: repne + _repe, // F3: repe + _hlt, // F4: hlt + _cmc, // F5: cmc + _ope0xf6, // F6: + _ope0xf7, // F7: + _clc, // F8: clc + _stc, // F9: stc + _cli, // FA: cli + _sti, // FB: sti + _cld, // FC: cld + _std, // FD: std + _ope0xfe, // FE: + _ope0xff, // FF: +}; + + + +// ----------------------------------------------------------------- repe + +I286FN _repe_segprefix_es(void) { + + DS_FIX = ES_BASE; + SS_FIX = ES_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _repe_segprefix_cs(void) { + + DS_FIX = CS_BASE; + SS_FIX = CS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _repe_segprefix_ss(void) { + + DS_FIX = SS_BASE; + SS_FIX = SS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _repe_segprefix_ds(void) { + + DS_FIX = DS_BASE; + SS_FIX = DS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +const I286OP i286op_repe[] = { + _add_ea_r8, // 00: add EA, REG8 + _add_ea_r16, // 01: add EA, REG16 + _add_r8_ea, // 02: add REG8, EA + _add_r16_ea, // 03: add REG16, EA + _add_al_data8, // 04: add al, DATA8 + _add_ax_data16, // 05: add ax, DATA16 + _push_es, // 06: push es + _pop_es, // 07: pop es + _or_ea_r8, // 08: or EA, REGF8 + _or_ea_r16, // 09: or EA, REG16 + _or_r8_ea, // 0A: or REG8, EA + _or_r16_ea, // 0B: or REG16, EA + _or_al_data8, // 0C: or al, DATA8 + _or_ax_data16, // 0D: or ax, DATA16 + _push_cs, // 0E: push cs + i286c_cts, // 0F: i286 upper opcode + + _adc_ea_r8, // 10: adc EA, REG8 + _adc_ea_r16, // 11: adc EA, REG16 + _adc_r8_ea, // 12: adc REG8, EA + _adc_r16_ea, // 13: adc REG16, EA + _adc_al_data8, // 14: adc al, DATA8 + _adc_ax_data16, // 15: adc ax, DATA16 + _push_ss, // 16: push ss + _pop_ss, // 17: pop ss + _sbb_ea_r8, // 18: sbb EA, REG8 + _sbb_ea_r16, // 19: sbb EA, REG16 + _sbb_r8_ea, // 1A: sbb REG8, EA + _sbb_r16_ea, // 1B: sbb REG16, EA + _sbb_al_data8, // 1C: sbb al, DATA8 + _sbb_ax_data16, // 1D: sbb ax, DATA16 + _push_ds, // 1E: push ds + _pop_ds, // 1F: pop ds + + _and_ea_r8, // 20: and EA, REG8 + _and_ea_r16, // 21: and EA, REG16 + _and_r8_ea, // 22: and REG8, EA + _and_r16_ea, // 23: and REG16, EA + _and_al_data8, // 24: and al, DATA8 + _and_ax_data16, // 25: and ax, DATA16 + _repe_segprefix_es, // 26: repe es: + _daa, // 27: daa + _sub_ea_r8, // 28: sub EA, REG8 + _sub_ea_r16, // 29: sub EA, REG16 + _sub_r8_ea, // 2A: sub REG8, EA + _sub_r16_ea, // 2B: sub REG16, EA + _sub_al_data8, // 2C: sub al, DATA8 + _sub_ax_data16, // 2D: sub ax, DATA16 + _repe_segprefix_cs, // 2E: repe cs: + _das, // 2F: das + + _xor_ea_r8, // 30: xor EA, REG8 + _xor_ea_r16, // 31: xor EA, REG16 + _xor_r8_ea, // 32: xor REG8, EA + _xor_r16_ea, // 33: xor REG16, EA + _xor_al_data8, // 34: xor al, DATA8 + _xor_ax_data16, // 35: xor ax, DATA16 + _repe_segprefix_ss, // 36: repe ss: + _aaa, // 37: aaa + _cmp_ea_r8, // 38: cmp EA, REG8 + _cmp_ea_r16, // 39: cmp EA, REG16 + _cmp_r8_ea, // 3A: cmp REG8, EA + _cmp_r16_ea, // 3B: cmp REG16, EA + _cmp_al_data8, // 3C: cmp al, DATA8 + _cmp_ax_data16, // 3D: cmp ax, DATA16 + _repe_segprefix_ds, // 3E: repe ds: + _aas, // 3F: aas + + _inc_ax, // 40: inc ax + _inc_cx, // 41: inc cx + _inc_dx, // 42: inc dx + _inc_bx, // 43: inc bx + _inc_sp, // 44: inc sp + _inc_bp, // 45: inc bp + _inc_si, // 46: inc si + _inc_di, // 47: inc di + _dec_ax, // 48: dec ax + _dec_cx, // 49: dec cx + _dec_dx, // 4A: dec dx + _dec_bx, // 4B: dec bx + _dec_sp, // 4C: dec sp + _dec_bp, // 4D: dec bp + _dec_si, // 4E: dec si + _dec_di, // 4F: dec di + + _push_ax, // 50: push ax + _push_cx, // 51: push cx + _push_dx, // 52: push dx + _push_bx, // 53: push bx + _push_sp, // 54: push sp + _push_bp, // 55: push bp + _push_si, // 56: push si + _push_di, // 57: push di + _pop_ax, // 58: pop ax + _pop_cx, // 59: pop cx + _pop_dx, // 5A: pop dx + _pop_bx, // 5B: pop bx + _pop_sp, // 5C: pop sp + _pop_bp, // 5D: pop bp + _pop_si, // 5E: pop si + _pop_di, // 5F: pop di + + _pusha, // 60: pusha + _popa, // 61: popa + _bound, // 62: bound + _arpl, // 63: arpl + _reserved, // 64: reserved + _reserved, // 65: reserved + _reserved, // 66: reserved + _reserved, // 67: reserved + _push_data16, // 68: push DATA16 + _imul_reg_ea_data16, // 69: imul REG, EA, DATA16 + _push_data8, // 6A: push DATA8 + _imul_reg_ea_data8, // 6B: imul REG, EA, DATA8 + i286c_rep_insb, // 6C: rep insb + i286c_rep_insw, // 6D: rep insw + i286c_rep_outsb, // 6E: rep outsb + i286c_rep_outsw, // 6F: rep outsw + + _jo_short, // 70: jo short + _jno_short, // 71: jno short + _jc_short, // 72: jnae/jb/jc short + _jnc_short, // 73: jae/jnb/jnc short + _jz_short, // 74: je/jz short + _jnz_short, // 75: jne/jnz short + _jna_short, // 76: jna/jbe short + _ja_short, // 77: ja/jnbe short + _js_short, // 78: js short + _jns_short, // 79: jns short + _jp_short, // 7A: jp/jpe short + _jnp_short, // 7B: jnp/jpo short + _jl_short, // 7C: jl/jnge short + _jnl_short, // 7D: jnl/jge short + _jle_short, // 7E: jle/jng short + _jnle_short, // 7F: jg/jnle short + + _calc_ea8_i8, // 80: op EA8, DATA8 + _calc_ea16_i16, // 81: op EA16, DATA16 + _calc_ea8_i8, // 82: op EA8, DATA8 + _calc_ea16_i8, // 83: op EA16, DATA8 + _test_ea_r8, // 84: test EA, REG8 + _test_ea_r16, // 85: test EA, REG16 + _xchg_ea_r8, // 86: xchg EA, REG8 + _xchg_ea_r16, // 87: xchg EA, REG16 + _mov_ea_r8, // 88: mov EA, REG8 + _mov_ea_r16, // 89: mov EA, REG16 + _mov_r8_ea, // 8A: mov REG8, EA + _mov_r16_ea, // 8B: add REG16, EA + _mov_ea_seg, // 8C: mov EA, segreg + _lea_r16_ea, // 8D: lea REG16, EA + _mov_seg_ea, // 8E: mov segrem, EA + _pop_ea, // 8F: pop EA + + _nop, // 90: xchg ax, ax + _xchg_ax_cx, // 91: xchg ax, cx + _xchg_ax_dx, // 92: xchg ax, dx + _xchg_ax_bx, // 93: xchg ax, bx + _xchg_ax_sp, // 94: xchg ax, sp + _xchg_ax_bp, // 95: xchg ax, bp + _xchg_ax_si, // 96: xchg ax, si + _xchg_ax_di, // 97: xchg ax, di + _cbw, // 98: cbw + _cwd, // 99: cwd + _call_far, // 9A: call far + _wait, // 9B: wait + _pushf, // 9C: pushf + _popf, // 9D: popf + _sahf, // 9E: sahf + _lahf, // 9F: lahf + + _mov_al_m8, // A0: mov al, m8 + _mov_ax_m16, // A1: mov ax, m16 + _mov_m8_al, // A2: mov m8, al + _mov_m16_ax, // A3: mov m16, ax + i286c_rep_movsb, // A4: rep movsb + i286c_rep_movsw, // A5: rep movsw + i286c_repe_cmpsb, // A6: repe cmpsb + i286c_repe_cmpsw, // A7: repe cmpsw + _test_al_data8, // A8: test al, DATA8 + _test_ax_data16, // A9: test ax, DATA16 + i286c_rep_stosb, // AA: rep stosb + i286c_rep_stosw, // AB: rep stosw + i286c_rep_lodsb, // AC: rep lodsb + i286c_rep_lodsw, // AD: rep lodsw + i286c_repe_scasb, // AE: repe scasb + i286c_repe_scasw, // AF: repe scasw + + _mov_al_imm, // B0: mov al, imm8 + _mov_cl_imm, // B1: mov cl, imm8 + _mov_dl_imm, // B2: mov dl, imm8 + _mov_bl_imm, // B3: mov bl, imm8 + _mov_ah_imm, // B4: mov ah, imm8 + _mov_ch_imm, // B5: mov ch, imm8 + _mov_dh_imm, // B6: mov dh, imm8 + _mov_bh_imm, // B7: mov bh, imm8 + _mov_ax_imm, // B8: mov ax, imm16 + _mov_cx_imm, // B9: mov cx, imm16 + _mov_dx_imm, // BA: mov dx, imm16 + _mov_bx_imm, // BB: mov bx, imm16 + _mov_sp_imm, // BC: mov sp, imm16 + _mov_bp_imm, // BD: mov bp, imm16 + _mov_si_imm, // BE: mov si, imm16 + _mov_di_imm, // BF: mov di, imm16 + + _shift_ea8_data8, // C0: shift EA8, DATA8 + _shift_ea16_data8, // C1: shift EA16, DATA8 + _ret_near_data16, // C2: ret near DATA16 + _ret_near, // C3: ret near + _les_r16_ea, // C4: les REG16, EA + _lds_r16_ea, // C5: lds REG16, EA + _mov_ea8_data8, // C6: mov EA8, DATA8 + _mov_ea16_data16, // C7: mov EA16, DATA16 + _enter, // C8: enter DATA16, DATA8 + fleave, // C9: leave + _ret_far_data16, // CA: ret far DATA16 + _ret_far, // CB: ret far + _int_03, // CC: int 3 + _int_data8, // CD: int DATA8 + _into, // CE: into + _iret, // CF: iret + + _shift_ea8_1, // D0: shift EA8, 1 + _shift_ea16_1, // D1: shift EA16, 1 + _shift_ea8_cl, // D2: shift EA8, cl + _shift_ea16_cl, // D3: shift EA16, cl + _aam, // D4: AAM + _aad, // D5: AAD + _setalc, // D6: setalc (80286) + _xlat, // D7: xlat + _esc, // D8: esc + _esc, // D9: esc + _esc, // DA: esc + _esc, // DB: esc + _esc, // DC: esc + _esc, // DD: esc + _esc, // DE: esc + _esc, // DF: esc + + _loopnz, // E0: loopnz + _loopz, // E1: loopz + _loop, // E2: loop + _jcxz, // E3: jcxz + _in_al_data8, // E4: in al, DATA8 + _in_ax_data8, // E5: in ax, DATA8 + _out_data8_al, // E6: out DATA8, al + _out_data8_ax, // E7: out DATA8, ax + _call_near, // E8: call near + _jmp_near, // E9: jmp near + _jmp_far, // EA: jmp far + _jmp_short, // EB: jmp short + _in_al_dx, // EC: in al, dx + _in_ax_dx, // ED: in ax, dx + _out_dx_al, // EE: out dx, al + _out_dx_ax, // EF: out dx, ax + + _lock, // F0: lock + _lock, // F1: lock + _repne, // F2: repne + _repe, // F3: repe + _hlt, // F4: hlt + _cmc, // F5: cmc + _ope0xf6, // F6: + _ope0xf7, // F7: + _clc, // F8: clc + _stc, // F9: stc + _cli, // FA: cli + _sti, // FB: sti + _cld, // FC: cld + _std, // FD: std + _ope0xfe, // FE: + _ope0xff, // FF: +}; + + +// ----------------------------------------------------------------- repne + +I286FN _repne_segprefix_es(void) { + + DS_FIX = ES_BASE; + SS_FIX = ES_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _repne_segprefix_cs(void) { + + DS_FIX = CS_BASE; + SS_FIX = CS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _repne_segprefix_ss(void) { + + DS_FIX = SS_BASE; + SS_FIX = SS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN _repne_segprefix_ds(void) { + + DS_FIX = DS_BASE; + SS_FIX = DS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + i286op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +const I286OP i286op_repne[] = { + _add_ea_r8, // 00: add EA, REG8 + _add_ea_r16, // 01: add EA, REG16 + _add_r8_ea, // 02: add REG8, EA + _add_r16_ea, // 03: add REG16, EA + _add_al_data8, // 04: add al, DATA8 + _add_ax_data16, // 05: add ax, DATA16 + _push_es, // 06: push es + _pop_es, // 07: pop es + _or_ea_r8, // 08: or EA, REGF8 + _or_ea_r16, // 09: or EA, REG16 + _or_r8_ea, // 0A: or REG8, EA + _or_r16_ea, // 0B: or REG16, EA + _or_al_data8, // 0C: or al, DATA8 + _or_ax_data16, // 0D: or ax, DATA16 + _push_cs, // 0E: push cs + i286c_cts, // 0F: i286 upper opcode + + _adc_ea_r8, // 10: adc EA, REG8 + _adc_ea_r16, // 11: adc EA, REG16 + _adc_r8_ea, // 12: adc REG8, EA + _adc_r16_ea, // 13: adc REG16, EA + _adc_al_data8, // 14: adc al, DATA8 + _adc_ax_data16, // 15: adc ax, DATA16 + _push_ss, // 16: push ss + _pop_ss, // 17: pop ss + _sbb_ea_r8, // 18: sbb EA, REG8 + _sbb_ea_r16, // 19: sbb EA, REG16 + _sbb_r8_ea, // 1A: sbb REG8, EA + _sbb_r16_ea, // 1B: sbb REG16, EA + _sbb_al_data8, // 1C: sbb al, DATA8 + _sbb_ax_data16, // 1D: sbb ax, DATA16 + _push_ds, // 1E: push ds + _pop_ds, // 1F: pop ds + + _and_ea_r8, // 20: and EA, REG8 + _and_ea_r16, // 21: and EA, REG16 + _and_r8_ea, // 22: and REG8, EA + _and_r16_ea, // 23: and REG16, EA + _and_al_data8, // 24: and al, DATA8 + _and_ax_data16, // 25: and ax, DATA16 + _repne_segprefix_es, // 26: repne es: + _daa, // 27: daa + _sub_ea_r8, // 28: sub EA, REG8 + _sub_ea_r16, // 29: sub EA, REG16 + _sub_r8_ea, // 2A: sub REG8, EA + _sub_r16_ea, // 2B: sub REG16, EA + _sub_al_data8, // 2C: sub al, DATA8 + _sub_ax_data16, // 2D: sub ax, DATA16 + _repne_segprefix_cs, // 2E: repne cs: + _das, // 2F: das + + _xor_ea_r8, // 30: xor EA, REG8 + _xor_ea_r16, // 31: xor EA, REG16 + _xor_r8_ea, // 32: xor REG8, EA + _xor_r16_ea, // 33: xor REG16, EA + _xor_al_data8, // 34: xor al, DATA8 + _xor_ax_data16, // 35: xor ax, DATA16 + _repne_segprefix_ss, // 36: repne ss: + _aaa, // 37: aaa + _cmp_ea_r8, // 38: cmp EA, REG8 + _cmp_ea_r16, // 39: cmp EA, REG16 + _cmp_r8_ea, // 3A: cmp REG8, EA + _cmp_r16_ea, // 3B: cmp REG16, EA + _cmp_al_data8, // 3C: cmp al, DATA8 + _cmp_ax_data16, // 3D: cmp ax, DATA16 + _repne_segprefix_ds, // 3E: repne ds: + _aas, // 3F: aas + + _inc_ax, // 40: inc ax + _inc_cx, // 41: inc cx + _inc_dx, // 42: inc dx + _inc_bx, // 43: inc bx + _inc_sp, // 44: inc sp + _inc_bp, // 45: inc bp + _inc_si, // 46: inc si + _inc_di, // 47: inc di + _dec_ax, // 48: dec ax + _dec_cx, // 49: dec cx + _dec_dx, // 4A: dec dx + _dec_bx, // 4B: dec bx + _dec_sp, // 4C: dec sp + _dec_bp, // 4D: dec bp + _dec_si, // 4E: dec si + _dec_di, // 4F: dec di + + _push_ax, // 50: push ax + _push_cx, // 51: push cx + _push_dx, // 52: push dx + _push_bx, // 53: push bx + _push_sp, // 54: push sp + _push_bp, // 55: push bp + _push_si, // 56: push si + _push_di, // 57: push di + _pop_ax, // 58: pop ax + _pop_cx, // 59: pop cx + _pop_dx, // 5A: pop dx + _pop_bx, // 5B: pop bx + _pop_sp, // 5C: pop sp + _pop_bp, // 5D: pop bp + _pop_si, // 5E: pop si + _pop_di, // 5F: pop di + + _pusha, // 60: pusha + _popa, // 61: popa + _bound, // 62: bound + _arpl, // 63: arpl + _reserved, // 64: reserved + _reserved, // 65: reserved + _reserved, // 66: reserved + _reserved, // 67: reserved + _push_data16, // 68: push DATA16 + _imul_reg_ea_data16, // 69: imul REG, EA, DATA16 + _push_data8, // 6A: push DATA8 + _imul_reg_ea_data8, // 6B: imul REG, EA, DATA8 + i286c_rep_insb, // 6C: rep insb + i286c_rep_insw, // 6D: rep insw + i286c_rep_outsb, // 6E: rep outsb + i286c_rep_outsw, // 6F: rep outsw + + _jo_short, // 70: jo short + _jno_short, // 71: jno short + _jc_short, // 72: jnae/jb/jc short + _jnc_short, // 73: jae/jnb/jnc short + _jz_short, // 74: je/jz short + _jnz_short, // 75: jne/jnz short + _jna_short, // 76: jna/jbe short + _ja_short, // 77: ja/jnbe short + _js_short, // 78: js short + _jns_short, // 79: jns short + _jp_short, // 7A: jp/jpe short + _jnp_short, // 7B: jnp/jpo short + _jl_short, // 7C: jl/jnge short + _jnl_short, // 7D: jnl/jge short + _jle_short, // 7E: jle/jng short + _jnle_short, // 7F: jg/jnle short + + _calc_ea8_i8, // 80: op EA8, DATA8 + _calc_ea16_i16, // 81: op EA16, DATA16 + _calc_ea8_i8, // 82: op EA8, DATA8 + _calc_ea16_i8, // 83: op EA16, DATA8 + _test_ea_r8, // 84: test EA, REG8 + _test_ea_r16, // 85: test EA, REG16 + _xchg_ea_r8, // 86: xchg EA, REG8 + _xchg_ea_r16, // 87: xchg EA, REG16 + _mov_ea_r8, // 88: mov EA, REG8 + _mov_ea_r16, // 89: mov EA, REG16 + _mov_r8_ea, // 8A: mov REG8, EA + _mov_r16_ea, // 8B: add REG16, EA + _mov_ea_seg, // 8C: mov EA, segreg + _lea_r16_ea, // 8D: lea REG16, EA + _mov_seg_ea, // 8E: mov segrem, EA + _pop_ea, // 8F: pop EA + + _nop, // 90: xchg ax, ax + _xchg_ax_cx, // 91: xchg ax, cx + _xchg_ax_dx, // 92: xchg ax, dx + _xchg_ax_bx, // 93: xchg ax, bx + _xchg_ax_sp, // 94: xchg ax, sp + _xchg_ax_bp, // 95: xchg ax, bp + _xchg_ax_si, // 96: xchg ax, si + _xchg_ax_di, // 97: xchg ax, di + _cbw, // 98: cbw + _cwd, // 99: cwd + _call_far, // 9A: call far + _wait, // 9B: wait + _pushf, // 9C: pushf + _popf, // 9D: popf + _sahf, // 9E: sahf + _lahf, // 9F: lahf + + _mov_al_m8, // A0: mov al, m8 + _mov_ax_m16, // A1: mov ax, m16 + _mov_m8_al, // A2: mov m8, al + _mov_m16_ax, // A3: mov m16, ax + i286c_rep_movsb, // A4: rep movsb + i286c_rep_movsw, // A5: rep movsw + i286c_repne_cmpsb, // A6: repne cmpsb + i286c_repne_cmpsw, // A7: repne cmpsw + _test_al_data8, // A8: test al, DATA8 + _test_ax_data16, // A9: test ax, DATA16 + i286c_rep_stosb, // AA: rep stosb + i286c_rep_stosw, // AB: rep stosw + i286c_rep_lodsb, // AC: rep lodsb + i286c_rep_lodsw, // AD: rep lodsw + i286c_repne_scasb, // AE: repne scasb + i286c_repne_scasw, // AF: repne scasw + + _mov_al_imm, // B0: mov al, imm8 + _mov_cl_imm, // B1: mov cl, imm8 + _mov_dl_imm, // B2: mov dl, imm8 + _mov_bl_imm, // B3: mov bl, imm8 + _mov_ah_imm, // B4: mov ah, imm8 + _mov_ch_imm, // B5: mov ch, imm8 + _mov_dh_imm, // B6: mov dh, imm8 + _mov_bh_imm, // B7: mov bh, imm8 + _mov_ax_imm, // B8: mov ax, imm16 + _mov_cx_imm, // B9: mov cx, imm16 + _mov_dx_imm, // BA: mov dx, imm16 + _mov_bx_imm, // BB: mov bx, imm16 + _mov_sp_imm, // BC: mov sp, imm16 + _mov_bp_imm, // BD: mov bp, imm16 + _mov_si_imm, // BE: mov si, imm16 + _mov_di_imm, // BF: mov di, imm16 + + _shift_ea8_data8, // C0: shift EA8, DATA8 + _shift_ea16_data8, // C1: shift EA16, DATA8 + _ret_near_data16, // C2: ret near DATA16 + _ret_near, // C3: ret near + _les_r16_ea, // C4: les REG16, EA + _lds_r16_ea, // C5: lds REG16, EA + _mov_ea8_data8, // C6: mov EA8, DATA8 + _mov_ea16_data16, // C7: mov EA16, DATA16 + _enter, // C8: enter DATA16, DATA8 + fleave, // C9: leave + _ret_far_data16, // CA: ret far DATA16 + _ret_far, // CB: ret far + _int_03, // CC: int 3 + _int_data8, // CD: int DATA8 + _into, // CE: into + _iret, // CF: iret + + _shift_ea8_1, // D0: shift EA8, 1 + _shift_ea16_1, // D1: shift EA16, 1 + _shift_ea8_cl, // D2: shift EA8, cl + _shift_ea16_cl, // D3: shift EA16, cl + _aam, // D4: AAM + _aad, // D5: AAD + _setalc, // D6: setalc (80286) + _xlat, // D7: xlat + _esc, // D8: esc + _esc, // D9: esc + _esc, // DA: esc + _esc, // DB: esc + _esc, // DC: esc + _esc, // DD: esc + _esc, // DE: esc + _esc, // DF: esc + + _loopnz, // E0: loopnz + _loopz, // E1: loopz + _loop, // E2: loop + _jcxz, // E3: jcxz + _in_al_data8, // E4: in al, DATA8 + _in_ax_data8, // E5: in ax, DATA8 + _out_data8_al, // E6: out DATA8, al + _out_data8_ax, // E7: out DATA8, ax + _call_near, // E8: call near + _jmp_near, // E9: jmp near + _jmp_far, // EA: jmp far + _jmp_short, // EB: jmp short + _in_al_dx, // EC: in al, dx + _in_ax_dx, // ED: in ax, dx + _out_dx_al, // EE: out dx, al + _out_dx_ax, // EF: out dx, ax + + _lock, // F0: lock + _lock, // F1: lock + _repne, // F2: repne + _repe, // F3: repe + _hlt, // F4: hlt + _cmc, // F5: cmc + _ope0xf6, // F6: + _ope0xf7, // F7: + _clc, // F8: clc + _stc, // F9: stc + _cli, // FA: cli + _sti, // FB: sti + _cld, // FC: cld + _std, // FD: std + _ope0xfe, // FE: + _ope0xff, // FF: +}; + +} diff --git a/source/src/vm/np21/i286c/i286c_rp.cpp b/source/src/vm/np21/i286c/i286c_rp.cpp new file mode 100644 index 000000000..9898736e2 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_rp.cpp @@ -0,0 +1,425 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +//#include "pccore.h" +//#include "iocore.h" +#include "i286c.mcr" + +namespace I286_NP21 { + +// ---------------------------------------------------------------------- ins + +I286EXT i286c_rep_insb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + do { + REG8 dat = iocore_inp8(I286_DX); + i286_memorywrite(I286_DI + ES_BASE, dat); + I286_DI += stp; + I286_WORKCLOCK(4); + } while (--I286_CX); + } +} + +I286EXT i286c_rep_insw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + do { + REG16 dat = iocore_inp16(I286_DX); + i286_memorywrite_w(I286_DI + ES_BASE, dat); + I286_DI += stp; + I286_WORKCLOCK(4); + } while(--I286_CX); + } +} + +// ---------------------------------------------------------------------- outs + +I286EXT i286c_rep_outsb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + do { + REG8 dat = i286_memoryread(I286_SI + DS_FIX); + I286_SI += stp; + iocore_out8(I286_DX, (UINT8)dat); + I286_WORKCLOCK(4); + } while(--I286_CX); + } +} + +I286EXT i286c_rep_outsw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + do { + REG16 dat = i286_memoryread_w(I286_SI + DS_FIX); + I286_SI += stp; + iocore_out16(I286_DX, (UINT16)dat); + I286_WORKCLOCK(4); + } while(--I286_CX); + } +} + + +// ---------------------------------------------------------------------- movs + +#if 1 +I286EXT i286c_rep_movsb(void) { + + UINT16 r_cx; + int stp; + UINT16 r_si; + UINT16 r_di; + + I286_WORKCLOCK(5); + r_cx = I286_CX; + if (r_cx) { + stp = STRING_DIR; + r_si = I286_SI; + r_di = I286_DI; + while(1) { + REG8 dat = i286_memoryread(DS_FIX + r_si); + i286_memorywrite(ES_BASE + r_di, dat); + r_si += stp; + r_di += stp; + I286_WORKCLOCK(4); + r_cx--; + if (!r_cx) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + I286_CX = r_cx; + I286_SI = r_si; + I286_DI = r_di; + } +} + +I286EXT i286c_rep_movsw(void) { + + UINT16 r_cx; + int stp; + UINT16 r_si; + UINT16 r_di; + + I286_WORKCLOCK(5); + r_cx = I286_CX; + if (r_cx) { + stp = STRING_DIRx2; + r_si = I286_SI; + r_di = I286_DI; + while(1) { + REG16 dat = i286_memoryread_w(DS_FIX + r_si); + i286_memorywrite_w(ES_BASE + r_di, dat); + r_si += stp; + r_di += stp; + I286_WORKCLOCK(4); + r_cx--; + if (!r_cx) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + I286_CX = r_cx; + I286_SI = r_si; + I286_DI = r_di; + } +} +#else +I286EXT i286c_rep_movsb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + while(1) { + REG8 dat = i286_memoryread(I286_SI + DS_FIX); + i286_memorywrite(I286_DI + ES_BASE, dat); + I286_SI += stp; + I286_DI += stp; + I286_WORKCLOCK(4); + I286_CX--; + if (!I286_CX) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + } +} + +I286EXT i286c_rep_movsw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + while(1) { + REG16 dat = i286_memoryread_w(I286_SI + DS_FIX); + i286_memorywrite_w(I286_DI + ES_BASE, dat); + I286_SI += stp; + I286_DI += stp; + I286_WORKCLOCK(4); + I286_CX--; + if (!I286_CX) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + } +} +#endif + + +// ---------------------------------------------------------------------- lods + +I286EXT i286c_rep_lodsb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + while(1) { + I286_AL = i286_memoryread(I286_SI + DS_FIX); + I286_SI += stp; + I286_WORKCLOCK(4); + I286_CX--; + if (!I286_CX) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + } +} + +I286EXT i286c_rep_lodsw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + while(1) { + I286_AX = i286_memoryread_w(I286_SI + DS_FIX); + I286_SI += stp; + I286_WORKCLOCK(4); + I286_CX--; + if (!I286_CX) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + } +} + + +// ---------------------------------------------------------------------- stos + +I286EXT i286c_rep_stosb(void) { + + I286_WORKCLOCK(4); + if (I286_CX) { + int stp = STRING_DIR; + while(1) { + i286_memorywrite(I286_DI + ES_BASE, I286_AL); + I286_DI += stp; + I286_WORKCLOCK(3); + I286_CX--; + if (!I286_CX) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + } +} + +I286EXT i286c_rep_stosw(void) { + + I286_WORKCLOCK(4); + if (I286_CX) { + int stp = STRING_DIRx2; + while(1) { + i286_memorywrite_w(I286_DI + ES_BASE, I286_AX); + I286_DI += stp; + I286_WORKCLOCK(3); + I286_CX--; + if (!I286_CX) { + break; + } + if (I286_REMCLOCK <= 0) { + I286_IP -= I286_PREFIX + 1; + break; + } + } + } +} + + +// ---------------------------------------------------------------------- cmps + +I286EXT i286c_repe_cmpsb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + do { + UINT res; + UINT dst = i286_memoryread(I286_SI + DS_FIX); + UINT src = i286_memoryread(I286_DI + ES_BASE); + I286_SI += stp; + I286_DI += stp; + I286_WORKCLOCK(9); + SUBBYTE(res, dst, src) + I286_CX--; + } while((I286_CX) && (I286_FLAGL & Z_FLAG)); + } +} + +I286EXT i286c_repne_cmpsb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + do { + UINT res; + UINT dst = i286_memoryread(I286_SI + DS_FIX); + UINT src = i286_memoryread(I286_DI + ES_BASE); + I286_SI += stp; + I286_DI += stp; + I286_WORKCLOCK(9); + SUBBYTE(res, dst, src) + I286_CX--; + } while((I286_CX) && (!(I286_FLAGL & Z_FLAG))); + } +} + +I286EXT i286c_repe_cmpsw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + do { + UINT32 res; + UINT32 dst = i286_memoryread_w(I286_SI + DS_FIX); + UINT32 src = i286_memoryread_w(I286_DI + ES_BASE); + I286_SI += stp; + I286_DI += stp; + I286_WORKCLOCK(9); + SUBWORD(res, dst, src) + I286_CX--; + } while((I286_CX) && (I286_FLAGL & Z_FLAG)); + } +} + +I286EXT i286c_repne_cmpsw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + do { + UINT32 res; + UINT32 dst = i286_memoryread_w(I286_SI + DS_FIX); + UINT32 src = i286_memoryread_w(I286_DI + ES_BASE); + I286_SI += stp; + I286_DI += stp; + I286_WORKCLOCK(9); + SUBWORD(res, dst, src) + I286_CX--; + } while((I286_CX) && (!(I286_FLAGL & Z_FLAG))); + } +} + + +// ---------------------------------------------------------------------- scas + +I286EXT i286c_repe_scasb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + UINT dst = I286_AL; + do { + UINT res; + UINT src = i286_memoryread(I286_DI + ES_BASE); + I286_DI += stp; + I286_WORKCLOCK(8); + SUBBYTE(res, dst, src) + I286_CX--; + } while((I286_CX) && (I286_FLAGL & Z_FLAG)); + } +} + +I286EXT i286c_repne_scasb(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIR; + UINT dst = I286_AL; + do { + UINT res; + UINT src = i286_memoryread(I286_DI + ES_BASE); + I286_DI += stp; + I286_WORKCLOCK(8); + SUBBYTE(res, dst, src) + I286_CX--; + } while((I286_CX) && (!(I286_FLAGL & Z_FLAG))); + } +} + +I286EXT i286c_repe_scasw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + UINT32 dst = I286_AX; + do { + UINT32 res; + UINT32 src = i286_memoryread_w(I286_DI + ES_BASE); + I286_DI += stp; + I286_WORKCLOCK(8); + SUBWORD(res, dst, src) + I286_CX--; + } while((I286_CX) && (I286_FLAGL & Z_FLAG)); + } +} + +I286EXT i286c_repne_scasw(void) { + + I286_WORKCLOCK(5); + if (I286_CX) { + int stp = STRING_DIRx2; + UINT32 dst = I286_AX; + do { + UINT32 res; + UINT32 src = i286_memoryread_w(I286_DI + ES_BASE); + I286_DI += stp; + I286_WORKCLOCK(8); + SUBWORD(res, dst, src) + I286_CX--; + } while((I286_CX) && (!(I286_FLAGL & Z_FLAG))); + } +} + +} diff --git a/source/src/vm/np21/i286c/i286c_sf.cpp b/source/src/vm/np21/i286c/i286c_sf.cpp new file mode 100644 index 000000000..50851d964 --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_sf.cpp @@ -0,0 +1,618 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include "i286c.mcr" +#include "i286c_sf.mcr" + +namespace I286_NP21 { +// ------------------------------------------------------------------------ + +I286_SFT _rol_r8_1(UINT8 *p) { + + UINT src; + UINT dst; + + src = *p; + BYTE_ROL1(dst, src) + *p = (UINT8)dst; +} + +I286_SFT _ror_r8_1(UINT8 *p) { + + UINT src; + UINT dst; + + src = *p; + BYTE_ROR1(dst, src) + *p = (UINT8)dst; +} + +I286_SFT _rcl_r8_1(UINT8 *p) { + + UINT src; + UINT dst; + + src = *p; + BYTE_RCL1(dst, src) + *p = (UINT8)dst; +} + +I286_SFT _rcr_r8_1(UINT8 *p) { + + UINT src; + UINT dst; + + src = *p; + BYTE_RCR1(dst, src) + *p = (UINT8)dst; +} + +I286_SFT _shl_r8_1(UINT8 *p) { + + UINT src; + UINT dst; + + src = *p; + BYTE_SHL1(dst, src) + *p = (UINT8)dst; +} + +I286_SFT _shr_r8_1(UINT8 *p) { + + UINT src; + UINT dst; + + src = *p; + BYTE_SHR1(dst, src) + *p = (UINT8)dst; +} + +I286_SFT _sar_r8_1(UINT8 *p) { + + UINT src; + UINT dst; + + src = *p; + BYTE_SAR1(dst, src) + *p = (UINT8)dst; +} + + +I286_SFT _rol_e8_1(UINT32 madr) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_ROL1(dst, src) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _ror_e8_1(UINT32 madr) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_ROR1(dst, src) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _rcl_e8_1(UINT32 madr) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_RCL1(dst, src) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _rcr_e8_1(UINT32 madr) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_RCR1(dst, src) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _shl_e8_1(UINT32 madr) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_SHL1(dst, src) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _shr_e8_1(UINT32 madr) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_SHR1(dst, src) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _sar_e8_1(UINT32 madr) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_SAR1(dst, src) + i286_memorywrite(madr, (REG8)dst); +} + + +const I286OPSFTR8 sft_r8_table[] = { + _rol_r8_1, _ror_r8_1, _rcl_r8_1, _rcr_r8_1, + _shl_r8_1, _shr_r8_1, _shl_r8_1, _sar_r8_1}; + +const I286OPSFTE8 sft_e8_table[] = { + _rol_e8_1, _ror_e8_1, _rcl_e8_1, _rcr_e8_1, + _shl_e8_1, _shr_e8_1, _shl_e8_1, _sar_e8_1}; + + +// ------------------------------------------------------------------------ + +I286_SFT _rol_r16_1(UINT16 *p) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_ROL1(dst, src) + *p = (UINT16)dst; +} + +I286_SFT _ror_r16_1(UINT16 *p) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_ROR1(dst, src) + *p = (UINT16)dst; +} + +I286_SFT _rcl_r16_1(UINT16 *p) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_RCL1(dst, src) + *p = (UINT16)dst; +} + +I286_SFT _rcr_r16_1(UINT16 *p) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_RCR1(dst, src) + *p = (UINT16)dst; +} + +I286_SFT _shl_r16_1(UINT16 *p) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_SHL1(dst, src) + *p = (UINT16)dst; +} + +I286_SFT _shr_r16_1(UINT16 *p) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_SHR1(dst, src) + *p = (UINT16)dst; +} + +I286_SFT _sar_r16_1(UINT16 *p) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_SAR1(dst, src) + *p = (UINT16)dst; +} + + +I286_SFT _rol_e16_1(UINT32 madr) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_ROL1(dst, src) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _ror_e16_1(UINT32 madr) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_ROR1(dst, src) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _rcl_e16_1(UINT32 madr) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_RCL1(dst, src) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _rcr_e16_1(UINT32 madr) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_RCR1(dst, src) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _shl_e16_1(UINT32 madr) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_SHL1(dst, src) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _shr_e16_1(UINT32 madr) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_SHR1(dst, src) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _sar_e16_1(UINT32 madr) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_SAR1(dst, src) + i286_memorywrite_w(madr, (REG16)dst); +} + + +const I286OPSFTR16 sft_r16_table[] = { + _rol_r16_1, _ror_r16_1, _rcl_r16_1, _rcr_r16_1, + _shl_r16_1, _shr_r16_1, _shl_r16_1, _sar_r16_1}; + +const I286OPSFTE16 sft_e16_table[] = { + _rol_e16_1, _ror_e16_1, _rcl_e16_1, _rcr_e16_1, + _shl_e16_1, _shr_e16_1, _shl_e16_1, _sar_e16_1}; + +// ------------------------------------------------------------------------ + +I286_SFT _rol_r8_cl(UINT8 *p, REG8 cl) { + + UINT src; + UINT dst; + + src = *p; + BYTE_ROLCL(dst, src, cl) + *p = (UINT8)dst; +} + +I286_SFT _ror_r8_cl(UINT8 *p, REG8 cl) { + + UINT src; + UINT dst; + + src = *p; + BYTE_RORCL(dst, src, cl) + *p = (UINT8)dst; +} + +I286_SFT _rcl_r8_cl(UINT8 *p, REG8 cl) { + + UINT src; + UINT dst; + + src = *p; + BYTE_RCLCL(dst, src, cl) + *p = (UINT8)dst; +} + +I286_SFT _rcr_r8_cl(UINT8 *p, REG8 cl) { + + UINT src; + UINT dst; + + src = *p; + BYTE_RCRCL(dst, src, cl) + *p = (UINT8)dst; +} + +I286_SFT _shl_r8_cl(UINT8 *p, REG8 cl) { + + UINT src; + UINT dst; + + src = *p; + BYTE_SHLCL(dst, src, cl) + *p = (UINT8)dst; +} + +I286_SFT _shr_r8_cl(UINT8 *p, REG8 cl) { + + UINT src; + UINT dst; + + src = *p; + BYTE_SHRCL(dst, src, cl) + *p = (UINT8)dst; +} + +I286_SFT _sar_r8_cl(UINT8 *p, REG8 cl) { + + UINT src; + UINT dst; + + src = *p; + BYTE_SARCL(dst, src, cl) + *p = (UINT8)dst; +} + + +I286_SFT _rol_e8_cl(UINT32 madr, REG8 cl) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_ROLCL(dst, src, cl) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _ror_e8_cl(UINT32 madr, REG8 cl) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_RORCL(dst, src, cl) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _rcl_e8_cl(UINT32 madr, REG8 cl) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_RCLCL(dst, src, cl) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _rcr_e8_cl(UINT32 madr, REG8 cl) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_RCRCL(dst, src, cl) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _shl_e8_cl(UINT32 madr, REG8 cl) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_SHLCL(dst, src, cl) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _shr_e8_cl(UINT32 madr, REG8 cl) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_SHRCL(dst, src, cl) + i286_memorywrite(madr, (REG8)dst); +} + +I286_SFT _sar_e8_cl(UINT32 madr, REG8 cl) { + + UINT src; + UINT dst; + + src = i286_memoryread(madr); + BYTE_SARCL(dst, src, cl) + i286_memorywrite(madr, (REG8)dst); +} + + +const I286OPSFTR8CL sft_r8cl_table[] = { + _rol_r8_cl, _ror_r8_cl, _rcl_r8_cl, _rcr_r8_cl, + _shl_r8_cl, _shr_r8_cl, _shl_r8_cl, _sar_r8_cl}; + +const I286OPSFTE8CL sft_e8cl_table[] = { + _rol_e8_cl, _ror_e8_cl, _rcl_e8_cl, _rcr_e8_cl, + _shl_e8_cl, _shr_e8_cl, _shl_e8_cl, _sar_e8_cl}; + + +// ------------------------------------------------------------------------ + +I286_SFT _rol_r16_cl(UINT16 *p, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_ROLCL(dst, src, cl) + *p = (UINT16)dst; +} + +I286_SFT _ror_r16_cl(UINT16 *p, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_RORCL(dst, src, cl) + *p = (UINT16)dst; +} + +I286_SFT _rcl_r16_cl(UINT16 *p, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_RCLCL(dst, src, cl) + *p = (UINT16)dst; +} + +I286_SFT _rcr_r16_cl(UINT16 *p, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_RCRCL(dst, src, cl) + *p = (UINT16)dst; +} + +I286_SFT _shl_r16_cl(UINT16 *p, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_SHLCL(dst, src, cl) + *p = (UINT16)dst; +} + +I286_SFT _shr_r16_cl(UINT16 *p, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_SHRCL(dst, src, cl) + *p = (UINT16)dst; +} + +I286_SFT _sar_r16_cl(UINT16 *p, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = *p; + WORD_SARCL(dst, src, cl) + *p = (UINT16)dst; +} + + +I286_SFT _rol_e16_cl(UINT32 madr, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_ROLCL(dst, src, cl) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _ror_e16_cl(UINT32 madr, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_RORCL(dst, src, cl) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _rcl_e16_cl(UINT32 madr, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_RCLCL(dst, src, cl) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _rcr_e16_cl(UINT32 madr, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_RCRCL(dst, src, cl) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _shl_e16_cl(UINT32 madr, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_SHLCL(dst, src, cl) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _shr_e16_cl(UINT32 madr, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_SHRCL(dst, src, cl) + i286_memorywrite_w(madr, (REG16)dst); +} + +I286_SFT _sar_e16_cl(UINT32 madr, REG8 cl) { + + UINT32 src; + UINT32 dst; + + src = i286_memoryread_w(madr); + WORD_SARCL(dst, src, cl) + i286_memorywrite_w(madr, (REG16)dst); +} + + +const I286OPSFTR16CL sft_r16cl_table[] = { + _rol_r16_cl, _ror_r16_cl, _rcl_r16_cl, _rcr_r16_cl, + _shl_r16_cl, _shr_r16_cl, _shl_r16_cl, _sar_r16_cl}; + +const I286OPSFTE16CL sft_e16cl_table[] = { + _rol_e16_cl, _ror_e16_cl, _rcl_e16_cl, _rcr_e16_cl, + _shl_e16_cl, _shr_e16_cl, _shl_e16_cl, _sar_e16_cl}; + +} diff --git a/source/src/vm/np21/i286c/i286c_sf.mcr b/source/src/vm/np21/i286c/i286c_sf.mcr new file mode 100644 index 000000000..a4793d2cc --- /dev/null +++ b/source/src/vm/np21/i286c/i286c_sf.mcr @@ -0,0 +1,351 @@ +// wordはかなりノーチェック + +namespace I286_NP21 { + +#define BYTE_ROL1(d, s) { \ + UINT tmp = ((s) >> 7); \ + (d) = ((s) << 1) + tmp; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= tmp; \ + I286_OV = ((s) ^ (d)) & 0x80; \ + } + +#define BYTE_ROR1(d, s) { \ + UINT tmp = ((s) & 1); \ + (d) = ((tmp << 8) + (s)) >> 1; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= tmp; \ + I286_OV = ((s) ^ (d)) & 0x80; \ + } + +#define BYTE_RCL1(d, s) \ + (d) = ((s) << 1) | (I286_FLAGL & C_FLAG); \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= ((s) >> 7); \ + I286_OV = ((s) ^ (d)) & 0x80; + +#define BYTE_RCR1(d, s) \ + (d) = (((I286_FLAGL & C_FLAG) << 8) | (s)) >> 1; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= ((s) & 1); \ + I286_OV = ((s) ^ (d)) & 0x80; + +#define BYTE_SHL1(d, s) \ + (d) = (s) << 1; \ + I286_OV = ((s) ^ (d)) & 0x80; \ + I286_FLAGL = BYTESZPCF(d) | A_FLAG; + +#define BYTE_SHR1(d, s) \ + (d) = (s) >> 1; \ + I286_OV = (s) & 0x80; \ + I286_FLAGL = (UINT8)(BYTESZPF(d) | A_FLAG | ((s) & 1)); + +#if 1 +#define BYTE_SAR1(d, s) \ + (d) = ((s) & 0x80) + ((s) >> 1); \ + I286_OV = 0; \ + I286_FLAGL = (UINT8)(BYTESZPF(d) | A_FLAG | ((s) & 1)); +#else // eVC3/4 compiler bug +#define BYTE_SAR1(d, s) \ + (d) = (UINT8)(((SINT8)(s)) >> 1); \ + I286_OV = 0; \ + I286_FLAGL = (UINT8)(BYTESZPF(d) | A_FLAG | ((s) & 1)); +#endif + + +#define WORD_ROL1(d, s) { \ + UINT32 tmp = ((s) >> 15); \ + (d) = ((s) << 1) + tmp; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= tmp; \ + I286_OV = ((s) ^ (d)) & 0x8000; \ + } + +#define WORD_ROR1(d, s) { \ + UINT32 tmp = ((s) & 1); \ + (d) = ((tmp << 16) + (s)) >> 1; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= tmp; \ + I286_OV = ((s) ^ (d)) & 0x8000; \ + } + +#define WORD_RCL1(d, s) \ + (d) = ((s) << 1) | (I286_FLAGL & 1); \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= ((s) >> 15); \ + I286_OV = ((s) ^ (d)) & 0x8000; + +#define WORD_RCR1(d, s) \ + (d) = (((I286_FLAGL & 1) << 16) + (s)) >> 1; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= ((s) & 1); \ + I286_OV = ((s) ^ (d)) & 0x8000; + +#define WORD_SHL1(d, s) \ + (d) = (s) << 1; \ + I286_OV = ((s) ^ (d)) & 0x8000; \ + I286_FLAGL = WORDSZPCF(d) + A_FLAG; + +#define WORD_SHR1(d, s) \ + (d) = (s) >> 1; \ + I286_OV = (s) & 0x8000; \ + I286_FLAGL = (UINT8)(WORDSZPF(d) | A_FLAG | ((s) & 1)); + +#if 1 +#define WORD_SAR1(d, s) \ + (d) = ((s) & 0x8000) + ((s) >> 1); \ + I286_OV = 0; \ + I286_FLAGL = (UINT8)(WORDSZPF(d) | A_FLAG | ((s) & 1)); +#else // eVC3/4 compiler bug +#define WORD_SAR1(d, s) \ + (d) = (UINT16)(((SINT16)(s)) >> 1); \ + I286_OV = 0; \ + I286_FLAGL = (UINT8)(WORDSZPF(d) | A_FLAG | ((s) & 1)); +#endif + + + +#define BYTE_ROLCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + (c) = ((c) - 1) & 7; \ + if (c) { \ + (s) = ((s) << (c)) | ((s) >> (8 - (c))); \ + (s) &= 0xff; \ + } \ + BYTE_ROL1(d, s) \ + } \ + else { \ + (d) = (s); \ + } + +#define BYTE_RORCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + (c) = ((c) - 1) & 7; \ + if (c) { \ + (s) = ((s) >> (c)) | ((s) << (8 - (c))); \ + (s) &= 0xff; \ + } \ + BYTE_ROR1(d, s) \ + } \ + else { \ + (d) = (s); \ + } + +#define BYTE_RCLCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + UINT tmp; \ + tmp = I286_FLAGL & C_FLAG; \ + I286_FLAGL &= ~C_FLAG; \ + while((c)--) { \ + (s) = (((s) << 1) | tmp) & 0x1ff; \ + tmp = (s) >> 8; \ + } \ + I286_OV = ((s) ^ (s >> 1)) & 0x80; \ + I286_FLAGL |= tmp; \ + } \ + (d) = (s); + +#define BYTE_RCRCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + UINT tmp; \ + tmp = I286_FLAGL & C_FLAG; \ + I286_FLAGL &= ~C_FLAG; \ + while((c)--) { \ + (s) |= tmp << 8; \ + tmp = (s) & 1; \ + (s) >>= 1; \ + } \ + I286_OV = ((s) ^ (s >> 1)) & 0x40; \ + I286_FLAGL |= tmp; \ + } \ + (d) = (s); + +#define BYTE_SHLCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + if ((c) > 10) { \ + (c) = 10; \ + } \ + (s) <<= (c); \ + (s) &= 0x1ff; \ + I286_FLAGL = BYTESZPCF(s) + A_FLAG; \ + I286_OV = ((s) ^ ((s) >> 1)) & 0x80; \ + } \ + (d) = (s); + +#define BYTE_SHRCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + if ((c) >= 10) { \ + (c) = 10; \ + } \ + (s) >>= ((c) - 1); \ + I286_FLAGL = (UINT8)((s) & 1); \ + (s) >>= 1; \ + I286_OV = ((s) ^ ((s) >> 1)) & 0x40; \ + I286_FLAGL |= BYTESZPF(s) + A_FLAG; \ + } \ + (d) = (s); + +#if !defined(_WIN32_WCE) || (_WIN32_WCE < 300) +#define BYTE_SARCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + (s) = ((SINT8)(s)) >> ((c) - 1); \ + I286_FLAGL = (UINT8)((s) & 1); \ + (s) = (UINT8)(((SINT8)s) >> 1); \ + I286_OV = 0; \ + I286_FLAGL |= BYTESZPF(s) | A_FLAG; \ + } \ + (d) = (s); +#else +#define BYTE_SARCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + SINT32 t; \ + t = (s) << 24; \ + t = t >> ((c) - 1); \ + I286_FLAGL = (UINT8)((t >> 24) & 1); \ + (s) = (t >> 25) & 0xff; \ + I286_OV = 0; \ + I286_FLAGL |= BYTESZPF(s) | A_FLAG; \ + } \ + (d) = (s); +#endif + +#define WORD_ROLCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + UINT tmp; \ + (c)--; \ + if (c) { \ + (c) &= 0x0f; \ + (s) = ((s) << (c)) | ((s) >> (16 - (c))); \ + (s) &= 0xffff; \ + } \ + else { \ + I286_OV = ((s) + 0x4000) & 0x8000; \ + } \ + tmp = ((s) >> 15); \ + (s) = ((s) << 1) + tmp; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= tmp; \ + } \ + (d) = (s); + +#define WORD_RORCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + UINT32 tmp; \ + (c)--; \ + if (c) { \ + (c) &= 0x0f; \ + (s) = ((s) >> (c)) | ((s) << (16 - (c))); \ + (s) &= 0xffff; \ + } \ + else { \ + I286_OV = ((s) >> 15) ^ ((s) & 1); \ + } \ + tmp = (s) & 1; \ + (s) = ((tmp << 16) + (s)) >> 1; \ + I286_FLAGL &= ~C_FLAG; \ + I286_FLAGL |= tmp; \ + } \ + (d) = (s); + +#define WORD_RCLCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + UINT tmp; \ + tmp = I286_FLAGL & C_FLAG; \ + I286_FLAGL &= ~C_FLAG; \ + if ((c) == 1) { \ + I286_OV = ((s) + 0x4000) & 0x8000; \ + } \ + while((c)--) { \ + (s) = (((s) << 1) + tmp) & 0x1ffff; \ + tmp = (s) >> 16; \ + } \ + I286_FLAGL |= tmp; \ + } \ + (d) = (s); + +#define WORD_RCRCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + UINT32 tmp; \ + tmp = I286_FLAGL & C_FLAG; \ + I286_FLAGL &= ~C_FLAG; \ + if ((c) == 1) { \ + I286_OV = ((s) >> 15) ^ tmp; \ + } \ + while((c)--) { \ + (s) |= tmp << 16; \ + tmp = (s) & 1; \ + (s) >>= 1; \ + } \ + I286_FLAGL |= tmp; \ + } \ + (d) = (s); + +#define WORD_SHLCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + I286_OV = 0; \ + if ((c) == 1) { \ + I286_OV = ((s) + 0x4000) & 0x8000; \ + } \ + (s) <<= (c); \ + (s) &= 0x1ffff; \ + I286_FLAGL = WORDSZPCF(s); \ + } \ + (d) = (s); + +#define WORD_SHRCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + (c)--; \ + if (c) { \ + (s) >>= (c); \ + I286_OV = 0; \ + } \ + else { \ + I286_OV = (s) & 0x8000; \ + } \ + I286_FLAGL = (UINT8)((s) & 1); \ + (s) >>= 1; \ + I286_FLAGL |= WORDSZPF(s); \ + } \ + (d) = (s); + +#if !defined(_WIN32_WCE) || (_WIN32_WCE < 300) +#define WORD_SARCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + (s) = ((SINT16)(s)) >> ((c) - 1); \ + I286_FLAGL = (UINT8)((s) & 1); \ + (s) = (UINT16)(((SINT16)s) >> 1); \ + I286_OV = 0; \ + I286_FLAGL |= WORDSZPF(s); \ + } \ + (d) = (s); +#else // eVC〜 +#define WORD_SARCL(d, s, c) \ + (c) &= 0x1f; \ + if (c) { \ + SINT32 tmp; \ + tmp = (s) << 16; \ + tmp = tmp >> (16 + (c) - 1); \ + I286_FLAGL = (UINT8)(tmp & 1); \ + (s) = (UINT16)(tmp >> 1); \ + I286_OV = 0; \ + I286_FLAGL |= WORDSZPF(s); \ + } \ + (d) = (s); +#endif + +} \ No newline at end of file diff --git a/source/src/vm/np21/i286c/readme_takeda.txt b/source/src/vm/np21/i286c/readme_takeda.txt new file mode 100644 index 000000000..24e615a19 --- /dev/null +++ b/source/src/vm/np21/i286c/readme_takeda.txt @@ -0,0 +1,4 @@ +Based on Neko Project 21/W 0.86 rev70beta1 +Supported Intel 8086 and 80186 +Fixed that undefined bit1 of flags is always 1 +Fixed int/iret for protected mode (partial) diff --git a/source/src/vm/np21/i286c/v30patch.cpp b/source/src/vm/np21/i286c/v30patch.cpp new file mode 100644 index 000000000..c05595017 --- /dev/null +++ b/source/src/vm/np21/i286c/v30patch.cpp @@ -0,0 +1,1019 @@ +//#include "compiler.h" +#include "cpucore.h" +#include "i286c.h" +#include "v30patch.h" +//#include "pccore.h" +//#include "iocore.h" +//#include "bios/bios.h" +//#include "dmav30.h" +#include "i286c.mcr" +#if defined(ENABLE_TRAP) +#include "trap/steptrap.h" +#endif + + +// victory30 patch +namespace I286_NP21 { + +#define MAX_PREFIX 8 + +#define NEXT_OPCODE \ + if (I286_REMCLOCK < 1) { \ + I286_BASECLOCK += (1 - I286_REMCLOCK); \ + I286_REMCLOCK = 1; \ + } + +#define REAL_V30FLAG (UINT16)((I286_FLAG & 0x7ff) | \ + (I286_OV?O_FLAG:0) | 0xf002) + +typedef struct { + UINT opnum; + I286OP v30opcode; +} V30PATCH; + +static I286OP v30op[256]; +static I286OP v30op_repne[256]; +static I286OP v30op_repe[256]; +static I286OPF6 v30ope0xf6_table[8]; +static I286OPF6 v30ope0xf7_table[8]; + + +static const UINT8 rotatebase16[256] = + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}; + +static const UINT8 rotatebase09[256] = + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3}; + +static const UINT8 rotatebase17[256] = + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, + 15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, + 14,15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, + 13,14,15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, + 12,13,14,15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, + 11,12,13,14,15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10,11,12,13,14,15,16,17, 1, 2, 3, 4, 5, 6, 7, 8, + 9,10,11,12,13,14,15,16,17, 1, 2, 3, 4, 5, 6, 7, + 8, 9,10,11,12,13,14,15,16,17, 1, 2, 3, 4, 5, 6, + 7, 8, 9,10,11,12,13,14,15,16,17, 1, 2, 3, 4, 5, + 6, 7, 8, 9,10,11,12,13,14,15,16,17, 1, 2, 3, 4, + 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 1, 2, 3, + 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 1, 2, + 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 1, + 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17}; + + +I286FN v30_reserved(void) { + + I286_WORKCLOCK(2); +} + +I286FN v30segprefix_es(void) { // 26: es: + + SS_FIX = ES_BASE; + DS_FIX = ES_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30segprefix_cs(void) { // 2e: cs: + + SS_FIX = CS_BASE; + DS_FIX = CS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30segprefix_ss(void) { // 36: ss: + + SS_FIX = SS_BASE; + DS_FIX = SS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30segprefix_ds(void) { // 3e: ds: + + SS_FIX = DS_BASE; + DS_FIX = DS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30push_sp(void) REGPUSH(I286_SP, 3) // 54: push sp +I286FN v30pop_sp(void) REGPOP(I286_SP, 5) // 5C: pop sp + +I286FN v30mov_seg_ea(void) { // 8E: mov segrem, EA + + UINT op; + UINT tmp; + UINT16 ipbak; + + ipbak = I286_IP; + GET_PCBYTE(op); + if (op >= 0xc0) { + I286_WORKCLOCK(2); + tmp = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(5); + tmp = i286_memoryread_w(CALC_EA(op)); + } + switch(op & 0x18) { + case 0x00: // es + I286_ES = (UINT16)tmp; + ES_BASE = tmp << 4; + break; + + case 0x08: // cs + I286_CS = (UINT16)tmp; + CS_BASE = tmp << 4; + break; + + case 0x10: // ss + I286_SS = (UINT16)tmp; + SS_BASE = tmp << 4; + SS_FIX = SS_BASE; + NEXT_OPCODE + break; + + case 0x18: // ds + I286_DS = (UINT16)tmp; + DS_BASE = tmp << 4; + DS_FIX = DS_BASE; + break; + } +} + +I286FN v30_pushf(void) { // 9C: pushf + + REGPUSH(REAL_V30FLAG, 3) +} + +I286FN v30_popf(void) { // 9D: popf + + I286_WORKCLOCK(5); + REGPOP0(I286_FLAG) + I286_FLAG |= 0xf000; + I286_OV = I286_FLAG & O_FLAG; + I286_FLAG &= (0xfff ^ O_FLAG); + I286_TRAP = ((I286_FLAG & 0x300) == 0x300); + I286IRQCHECKTERM +} + +I286FN v30shift_ea8_data8(void) { // C0: shift EA8, DATA8 + + UINT8 *out; + UINT op; + UINT32 madr; + REG8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + GET_PCBYTE(cl) + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // rotate with carry + cl = rotatebase09[cl]; + } + } + else { + cl = max(cl, 9); + } + sft_e8cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = mem + madr; + } + GET_PCBYTE(cl) + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // rotate with carry + cl = rotatebase09[cl]; + } + } + else { + cl = max(cl, 9); + } + sft_r8cl_table[(op >> 3) & 7](out, cl); +} + +I286FN v30shift_ea16_data8(void) { // C1: shift EA16, DATA8 + + UINT16 *out; + UINT op; + UINT32 madr; + REG8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + GET_PCBYTE(cl); + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // with carry + cl = rotatebase17[cl]; + } + } + else { // shift + cl = max(cl, 17); + } + sft_e16cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = (UINT16 *)(mem + madr); + } + GET_PCBYTE(cl); + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // with carry + cl = rotatebase17[cl]; + } + } + else { // shift + cl = max(cl, 17); + } + sft_r16cl_table[(op >> 3) & 7](out, cl); +} + +I286FN v30shift_ea8_cl(void) { // D2: shift EA8, cl + + UINT8 *out; + UINT op; + UINT32 madr; + REG8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG8_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (madr >= I286_MEMWRITEMAX) { + cl = I286_CL; + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // rotate with carry + cl = rotatebase09[cl]; + } + } + else { + cl = max(cl, 9); + } + sft_e8cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = mem + madr; + } + cl = I286_CL; + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // rotate with carry + cl = rotatebase09[cl]; + } + } + else { + cl = max(cl, 9); + } + sft_r8cl_table[(op >> 3) & 7](out, cl); +} + +I286FN v30shift_ea16_cl(void) { // D3: shift EA16, cl + + UINT16 *out; + UINT op; + UINT32 madr; + REG8 cl; + + GET_PCBYTE(op) + if (op >= 0xc0) { + I286_WORKCLOCK(5); + out = REG16_B20(op); + } + else { + I286_WORKCLOCK(8); + madr = CALC_EA(op); +// if (INHIBIT_WORDP(madr)) { + cl = I286_CL; + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // with carry + cl = rotatebase17[cl]; + } + } + else { // shift + cl = max(cl, 17); + } + sft_e16cl_table[(op >> 3) & 7](madr, cl); + return; +// } +// out = (UINT16 *)(mem + madr); + } + cl = I286_CL; + I286_WORKCLOCK(cl); + if (!(op & 0x20)) { // rotate + if (!(op & 0x10)) { + cl = rotatebase16[cl]; + } + else { // with carry + cl = rotatebase17[cl]; + } + } + else { // shift + cl = max(cl, 17); + } + sft_r16cl_table[(op >> 3) & 7](out, cl); +} + +I286FN v30_aam(void) { // D4: AAM + + UINT8 al; + + I286_WORKCLOCK(16); + I286_IP++; // is 10 + al = I286_AL; + I286_AH = al / 10; + I286_AL = al % 10; + I286_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); + I286_FLAGL |= WORDSZPF(I286_AX); +} + +I286FN v30_aad(void) { // D5: AAD + + I286_WORKCLOCK(14); + I286_IP++; // is 10 + I286_AL += (UINT8)(I286_AH * 10); + I286_AH = 0; + I286_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); + I286_FLAGL |= BYTESZPF(I286_AL); +} + +I286FN v30_xlat(void) { // D6: xlat + + I286_WORKCLOCK(5); + I286_AL = i286_memoryread(LOW16(I286_AL + I286_BX) + DS_FIX); +} + +I286FN v30_repne(void) { // F2: repne + + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repne[op](); + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30_repe(void) { // F3: repe + + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repe[op](); + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286_F6 v30_div_ea8(UINT op) { + + UINT16 tmp; + UINT8 src; + + if (op >= 0xc0) { + I286_WORKCLOCK(14); + src = *(REG8_B20(op)); + } + else { + I286_WORKCLOCK(17); + src = i286_memoryread(CALC_EA(op)); + } + tmp = I286_AX; + if ((src) && (tmp < ((UINT16)src << 8))) { + I286_AL = tmp / src; + I286_AH = tmp % src; + } + else { + INT_NUM(0, I286_IP); // V30 + } +} + +I286_F6 v30_idiv_ea8(UINT op) { + + SINT16 tmp; + SINT16 r; + SINT8 src; + + if (op >= 0xc0) { + I286_WORKCLOCK(17); + src = *(REG8_B20(op)); + } + else { + I286_WORKCLOCK(20); + src = i286_memoryread(CALC_EA(op)); + } + tmp = (SINT16)I286_AX; + if (src) { + r = tmp / src; + if (!((r + 0x80) & 0xff00)) { + I286_AL = (UINT8)r; + I286_AH = tmp % src; + return; + } + } + INT_NUM(0, I286_IP); // V30 +} + +I286FN v30_ope0xf6(void) { // F6: + + UINT op; + + GET_PCBYTE(op); + v30ope0xf6_table[(op >> 3) & 7](op); +} + +I286_F6 v30_div_ea16(UINT op) { + + UINT32 tmp; + UINT32 src; + + if (op >= 0xc0) { + I286_WORKCLOCK(22); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(25); + src = i286_memoryread_w(CALC_EA(op)); + } + tmp = (I286_DX << 16) + I286_AX; + if ((src) && (tmp < (src << 16))) { + I286_AX = tmp / src; + I286_DX = tmp % src; + } + else { + INT_NUM(0, I286_IP); // V30 + } +} + +I286_F6 v30_idiv_ea16(UINT op) { + + SINT32 tmp; + SINT32 r; + SINT16 src; + + if (op >= 0xc0) { + I286_WORKCLOCK(25); + src = *(REG16_B20(op)); + } + else { + I286_WORKCLOCK(28); + src = i286_memoryread_w(CALC_EA(op)); + } + tmp = (SINT32)((I286_DX << 16) + I286_AX); + if (src) { + r = tmp / src; + if (!((r + 0x8000) & 0xffff0000)) { + I286_AX = (SINT16)r; + I286_DX = tmp % src; + return; + } + } + INT_NUM(0, I286_IP); // V30 +} + +I286FN v30_ope0xf7(void) { // F7: + + UINT op; + + GET_PCBYTE(op); + v30ope0xf7_table[(op >> 3) & 7](op); +} + +static const V30PATCH v30patch_op[] = { + {0x26, v30segprefix_es}, // 26: es: + {0x2e, v30segprefix_cs}, // 2E: cs: + {0x36, v30segprefix_ss}, // 36: ss: + {0x3e, v30segprefix_ds}, // 3E: ds: + {0x54, v30push_sp}, // 54: push sp + {0x5c, v30pop_sp}, // 5C: pop sp + {0x63, v30_reserved}, // 63: reserved + {0x64, v30_reserved}, // 64: reserved + {0x65, v30_reserved}, // 65: reserved + {0x66, v30_reserved}, // 66: reserved + {0x67, v30_reserved}, // 67: reserved + {0x8e, v30mov_seg_ea}, // 8E: mov segrem, EA + {0x9c, v30_pushf}, // 9C: pushf + {0x9d, v30_popf}, // 9D: popf + {0xc0, v30shift_ea8_data8}, // C0: shift EA8, DATA8 + {0xc1, v30shift_ea16_data8}, // C1: shift EA16, DATA8 + {0xd2, v30shift_ea8_cl}, // D2: shift EA8, cl + {0xd3, v30shift_ea16_cl}, // D3: shift EA16, cl + {0xd4, v30_aam}, // D4: AAM + {0xd5, v30_aad}, // D5: AAD + {0xd6, v30_xlat}, // D6: xlat (8086/V30) + {0xf2, v30_repne}, // F2: repne + {0xf3, v30_repe}, // F3: repe + {0xf6, v30_ope0xf6}, // F6: + {0xf7, v30_ope0xf7}}; // F7: + + +// ----------------------------------------------------------------- repe + +I286FN v30repe_segprefix_es(void) { + + DS_FIX = ES_BASE; + SS_FIX = ES_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30repe_segprefix_cs(void) { + + DS_FIX = CS_BASE; + SS_FIX = CS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30repe_segprefix_ss(void) { + + DS_FIX = SS_BASE; + SS_FIX = SS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30repe_segprefix_ds(void) { + + DS_FIX = DS_BASE; + SS_FIX = DS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repe[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +static const V30PATCH v30patch_repe[] = { + {0x26, v30repe_segprefix_es}, // 26: repe es: + {0x2e, v30repe_segprefix_cs}, // 2E: repe cs: + {0x36, v30repe_segprefix_ss}, // 36: repe ss: + {0x3e, v30repe_segprefix_ds}, // 3E: repe ds: + {0x54, v30push_sp}, // 54: push sp + {0x5c, v30pop_sp}, // 5C: pop sp + {0x63, v30_reserved}, // 63: reserved + {0x64, v30_reserved}, // 64: reserved + {0x65, v30_reserved}, // 65: reserved + {0x66, v30_reserved}, // 66: reserved + {0x67, v30_reserved}, // 67: reserved + {0x8e, v30mov_seg_ea}, // 8E: mov segrem, EA + {0x9c, v30_pushf}, // 9C: pushf + {0x9d, v30_popf}, // 9D: popf + {0xc0, v30shift_ea8_data8}, // C0: shift EA8, DATA8 + {0xc1, v30shift_ea16_data8}, // C1: shift EA16, DATA8 + {0xd2, v30shift_ea8_cl}, // D2: shift EA8, cl + {0xd3, v30shift_ea16_cl}, // D3: shift EA16, cl + {0xd4, v30_aam}, // D4: AAM + {0xd5, v30_aad}, // D5: AAD + {0xd6, v30_xlat}, // D6: xlat (8086/V30) + {0xf2, v30_repne}, // F2: repne + {0xf3, v30_repe}, // F3: repe + {0xf6, v30_ope0xf6}, // F6: + {0xf7, v30_ope0xf7}}; // F7: + + +// ----------------------------------------------------------------- repne + +I286FN v30repne_segprefix_es(void) { + + DS_FIX = ES_BASE; + SS_FIX = ES_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30repne_segprefix_cs(void) { + + DS_FIX = CS_BASE; + SS_FIX = CS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30repne_segprefix_ss(void) { + + DS_FIX = SS_BASE; + SS_FIX = SS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +I286FN v30repne_segprefix_ds(void) { + + DS_FIX = DS_BASE; + SS_FIX = DS_BASE; + I286_PREFIX++; + if (I286_PREFIX < MAX_PREFIX) { + UINT op; + GET_PCBYTE(op); + v30op_repne[op](); + REMOVE_PREFIX + I286_PREFIX = 0; + } + else { + INT_NUM(6, I286_IP); + } +} + +static const V30PATCH v30patch_repne[] = { + {0x26, v30repne_segprefix_es}, // 26: repne es: + {0x2e, v30repne_segprefix_cs}, // 2E: repne cs: + {0x36, v30repne_segprefix_ss}, // 36: repne ss: + {0x3e, v30repne_segprefix_ds}, // 3E: repne ds: + {0x54, v30push_sp}, // 54: push sp + {0x5c, v30pop_sp}, // 5C: pop sp + {0x63, v30_reserved}, // 63: reserved + {0x64, v30_reserved}, // 64: reserved + {0x65, v30_reserved}, // 65: reserved + {0x66, v30_reserved}, // 66: reserved + {0x67, v30_reserved}, // 67: reserved + {0x8e, v30mov_seg_ea}, // 8E: mov segrem, EA + {0x9c, v30_pushf}, // 9C: pushf + {0x9d, v30_popf}, // 9D: popf + {0xc0, v30shift_ea8_data8}, // C0: shift EA8, DATA8 + {0xc1, v30shift_ea16_data8}, // C1: shift EA16, DATA8 + {0xd2, v30shift_ea8_cl}, // D2: shift EA8, cl + {0xd3, v30shift_ea16_cl}, // D3: shift EA16, cl + {0xd4, v30_aam}, // D4: AAM + {0xd5, v30_aad}, // D5: AAD + {0xd6, v30_xlat}, // D6: xlat (8086/V30) + {0xf2, v30_repne}, // F2: repne + {0xf3, v30_repe}, // F3: repe + {0xf6, v30_ope0xf6}, // F6: + {0xf7, v30_ope0xf7}}; // F7: + + +// --------------------------------------------------------------------------- + +static void v30patching(I286OP *op, const V30PATCH *patch, int cnt) { + + do { + op[patch->opnum] = patch->v30opcode; + patch++; + } while(--cnt); +} + +#define V30PATCHING(a, b) v30patching(a, b, sizeof(b)/sizeof(V30PATCH)) + +void v30cinit(void) { + + CopyMemory(v30op, i286op, sizeof(v30op)); + V30PATCHING(v30op, v30patch_op); + CopyMemory(v30op_repne, i286op_repne, sizeof(v30op_repne)); + V30PATCHING(v30op_repne, v30patch_repne); + CopyMemory(v30op_repe, i286op_repe, sizeof(v30op_repe)); + V30PATCHING(v30op_repe, v30patch_repe); + CopyMemory(v30ope0xf6_table, c_ope0xf6_table, sizeof(v30ope0xf6_table)); + v30ope0xf6_table[6] = v30_div_ea8; + v30ope0xf6_table[7] = v30_idiv_ea8; + CopyMemory(v30ope0xf7_table, c_ope0xf7_table, sizeof(v30ope0xf7_table)); + v30ope0xf7_table[6] = v30_div_ea16; + v30ope0xf7_table[7] = v30_idiv_ea16; +} + +void v30c(void) { + + UINT opcode; + + if (I286_TRAP) { + do { +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_IP); +#endif +#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +#endif + GET_PCBYTE(opcode); + v30op[opcode](); + if (I286_TRAP) { + i286c_interrupt(1); + } + dmav30(); + } while(I286_REMCLOCK > 0); + } + else /*if (dmac.working)*/ { + do { +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_IP); +#endif +#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +#endif + GET_PCBYTE(opcode); + v30op[opcode](); + dmav30(); + } while(I286_REMCLOCK > 0); + } +/* + else { + do { +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_IP); +#endif +#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +#endif + GET_PCBYTE(opcode); + v30op[opcode](); + } while(I286_REMCLOCK > 0); + } +*/ +} + +void v30c_step(void) { + + UINT opcode; + + I286_OV = I286_FLAG & O_FLAG; + I286_FLAG &= ~(O_FLAG); + +#ifdef USE_DEBUGGER + device_debugger->add_cpu_trace(CS_BASE + I286_IP); +#endif + GET_PCBYTE(opcode); + v30op[opcode](); + + I286_FLAG &= ~(O_FLAG); + if (I286_OV) { + I286_FLAG |= (O_FLAG); + } + dmav30(); +} + +I286FN _pop_cs(void) { + + UINT tmp; + + REGPOP(tmp, 5) + I286_CS = tmp; + CS_BASE = SEGSELECT(tmp); +} + +// 8086 'invalid opcodes', as documented at http://www.os2museum.com/wp/?p=2147 and tested on real hardware +// - 0x60 - 0x6f are aliases to 0x70 - 0x7f. +// - 0xc0, 0xc1, 0xc8, 0xc9 are also aliases where the CPU ignores BIT 1 (*). +// - 0xf1 is an alias to 0xf0. +// +// Instructions are used in the boot sector for some versions of +// MS-DOS (e.g. the DEC Rainbow-100 version of DOS 2.x) + +static const V30PATCH i86patch_op[] = { + {0x0f, _pop_cs}, // 0F: pop cs + {0x26, v30segprefix_es}, // 26: es: + {0x2e, v30segprefix_cs}, // 2E: cs: + {0x36, v30segprefix_ss}, // 36: ss: + {0x3e, v30segprefix_ds}, // 3E: ds: + {0x54, v30push_sp}, // 54: push sp + {0x5c, v30pop_sp}, // 5C: pop sp + {0x60, _jo_short}, // 60: jo short + {0x61, _jno_short}, // 61: jno short + {0x62, _jc_short}, // 62: jnae/jb/jc short + {0x63, _jnc_short}, // 63: jae/jnb/jnc short + {0x64, _jz_short}, // 64: je/jz short + {0x65, _jnz_short}, // 65: jne/jnz short + {0x66, _jna_short}, // 66: jna/jbe short + {0x67, _ja_short}, // 67: ja/jnbe short + {0x68, _js_short}, // 68: js short + {0x69, _jns_short}, // 69: jns short + {0x6a, _jp_short}, // 6A: jp/jpe short + {0x6b, _jnp_short}, // 6B: jnp/jpo short + {0x6c, _jl_short}, // 6C: jl/jnge short + {0x6d, _jnl_short}, // 6D: jnl/jge short + {0x6e, _jle_short}, // 6E: jle/jng short + {0x6f, _jnle_short}, // 6F: jg/jnle short + {0x8e, v30mov_seg_ea}, // 8E: mov segrem, EA + {0x9c, v30_pushf}, // 9C: pushf + {0x9d, v30_popf}, // 9D: popf + {0xc0, _ret_near_data16}, // C0: ret near DATA16 + {0xc1, _ret_near}, // C1: ret near + {0xc8, _ret_far_data16}, // C8: ret far DATA16 + {0xc9, _ret_far}, // C9: ret far + {0xd2, v30shift_ea8_cl}, // D2: shift EA8, cl + {0xd3, v30shift_ea16_cl}, // D3: shift EA16, cl + {0xd6, v30_reserved}, // D6: reserved + {0xf2, v30_repne}, // F2: repne + {0xf3, v30_repe}, // F3: repe +}; + +void i86cinit(void) { + + CopyMemory(v30op, i286op, sizeof(v30op)); + V30PATCHING(v30op, i86patch_op); + CopyMemory(v30op_repne, i286op_repne, sizeof(v30op_repne)); + V30PATCHING(v30op_repne, i86patch_op); + CopyMemory(v30op_repe, i286op_repe, sizeof(v30op_repe)); + V30PATCHING(v30op_repe, i86patch_op); +} + +static const V30PATCH i186patch_op[] = { + {0x0f, v30_reserved}, // 0F: reserved +// PREFIX186(_pop_ss), /* 0x17 */ + {0x26, v30segprefix_es}, // 26: es: + {0x2e, v30segprefix_cs}, // 2E: cs: + {0x36, v30segprefix_ss}, // 36: ss: + {0x3e, v30segprefix_ds}, // 3E: ds: + {0x54, v30push_sp}, // 54: push sp + {0x5c, v30pop_sp}, // 5C: pop sp + {0x63, v30_reserved}, // 63: reserved + {0x64, v30_reserved}, // 64: reserved + {0x65, v30_reserved}, // 65: reserved + {0x66, v30_reserved}, // 66: reserved + {0x67, v30_reserved}, // 67: reserved +// {0x8e, v30mov_seg_ea}, // 8E: mov segrem, EA + {0x9c, v30_pushf}, // 9C: pushf + {0x9d, v30_popf}, // 9D: popf + {0xd6, v30_reserved}, // D6: reserved + {0xf1, v30_reserved}, // D6: reserved + {0xf2, v30_repne}, // F2: repne + {0xf3, v30_repe}, // F3: repe +}; + +void i186cinit(void) { + + CopyMemory(v30op, i286op, sizeof(v30op)); + V30PATCHING(v30op, i186patch_op); + CopyMemory(v30op_repne, i286op_repne, sizeof(v30op_repne)); + V30PATCHING(v30op_repne, i186patch_op); + CopyMemory(v30op_repe, i286op_repe, sizeof(v30op_repe)); + V30PATCHING(v30op_repe, i186patch_op); +} +} diff --git a/source/src/vm/np21/i286c/v30patch.h b/source/src/vm/np21/i286c/v30patch.h new file mode 100644 index 000000000..6c7d3e7ca --- /dev/null +++ b/source/src/vm/np21/i286c/v30patch.h @@ -0,0 +1,6 @@ + +namespace I286_NP21 { +void v30cinit(void); +void i86cinit(void); +void i186cinit(void); +} diff --git a/source/src/vm/np21/i386c/cpucore.cpp b/source/src/vm/np21/i386c/cpucore.cpp new file mode 100644 index 000000000..77595fe38 --- /dev/null +++ b/source/src/vm/np21/i386c/cpucore.cpp @@ -0,0 +1,98 @@ +//#include "compiler.h" +#include "cpucore.h" + +/* Z_FLAG, S_FLAG, P_FLAG, C_FLAG */ +const UINT8 iflags[512] = { + 0x44, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, + 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x00, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x84, 0x80, 0x80, 0x84, 0x80, 0x84, 0x84, 0x80, + 0x80, 0x84, 0x84, 0x80, 0x84, 0x80, 0x80, 0x84, + 0x45, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x01, 0x05, 0x05, 0x01, 0x05, 0x01, 0x01, 0x05, + 0x05, 0x01, 0x01, 0x05, 0x01, 0x05, 0x05, 0x01, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x85, 0x81, 0x81, 0x85, 0x81, 0x85, 0x85, 0x81, + 0x81, 0x85, 0x85, 0x81, 0x85, 0x81, 0x81, 0x85 +}; + +UINT8 szpflag_w[0x10000]; + + +void i386c_initialize(void) { + + UINT32 bit; + UINT i; + UINT8 f; + + for (i=0; i<0x10000; i++) { + f = P_FLAG; + for (bit=0x80; bit; bit>>=1) { + if (i & bit) { + f ^= P_FLAG; + } + } + if (!i) { + f |= Z_FLAG; + } + if (i & 0x8000) { + f |= S_FLAG; + } + szpflag_w[i] = f; + } + + ia32_init(); +} diff --git a/source/src/vm/np21/i386c/cpucore.h b/source/src/vm/np21/i386c/cpucore.h new file mode 100644 index 000000000..2e8368293 --- /dev/null +++ b/source/src/vm/np21/i386c/cpucore.h @@ -0,0 +1,9 @@ +#ifndef NP2_I386C_CPUCORE_H__ +#define NP2_I386C_CPUCORE_H__ + +#include "ia32/cpu.h" + +#define I286_MEMREADMAX CPU_MEMREADMAX +#define I286_MEMWRITEMAX CPU_MEMWRITEMAX + +#endif /* !NP2_I386C_CPUCORE_H__ */ diff --git a/source/src/vm/np21/i386c/cpumem.cpp b/source/src/vm/np21/i386c/cpumem.cpp new file mode 100644 index 000000000..db20120b1 --- /dev/null +++ b/source/src/vm/np21/i386c/cpumem.cpp @@ -0,0 +1,233 @@ +//#include "compiler.h" + +#if 1 +#undef TRACEOUT +#define USE_TRACEOUT_VS +//#define MEM_BDA_TRACEOUT +//#define MEM_D8_TRACEOUT +#ifdef USE_TRACEOUT_VS +#include "../../common.h" +#include "../device.h" +#include "../i386_np21.h" + +extern I386 *device_cpu; +static void __FASTCALL trace_fmt_ex(const char *fmt, ...) +{ + if(device_cpu != NULL) { + char stmp[2048]; + va_list ap; + va_start(ap, fmt); + vsprintf(stmp, fmt, ap); + strcat(stmp, "\n"); + va_end(ap); +// OutputDebugStringA(stmp); + device_cpu->out_debug_log(stmp); + } +} +#define TRACEOUT(s) trace_fmt_ex s +#else +#define TRACEOUT(s) (void)(s) +#endif +#endif /* 1 */ + +#ifndef NP2_MEMORY_ASM + +#include "cpucore.h" +#if defined(SUPPORT_IA32_HAXM) +#include "i386hax/haxfunc.h" +#include "i386hax/haxcore.h" +#endif +#include "./cpumem.h" + +I386 *device_cpu = NULL; +DEVICE *device_mem = NULL; +DEVICE *device_io = NULL; +//#ifdef I386_PSEUDO_BIOS +DEVICE *device_bios = NULL; +//#endif +//#ifdef SINGLE_MODE_DMA +DEVICE *device_dma = NULL; +//#endif +SINT64 i386_memory_wait; +DEBUGGER *device_debugger = NULL; +UINT32 codefetch_address; +SINT32 __exception_set; +UINT32 __exception_pc; +UINT64 __exception_code; +// ---- + +// ---- Logical Space (BIOS) +#if 1 +static inline UINT32 MEMCALL physicaladdr(UINT32 addr, BOOL wr) { + + UINT32 a; + UINT32 pde; + UINT32 pte; + + a = CPU_STAT_PDE_BASE + ((addr >> 20) & 0xffc); + pde = memp_read32(a); + if (!(pde & CPU_PDE_PRESENT)) { + goto retdummy; + } + if (!(pde & CPU_PDE_ACCESS)) { + memp_write8(a, (UINT8)(pde | CPU_PDE_ACCESS)); + } + a = (pde & CPU_PDE_BASEADDR_MASK) + ((addr >> 10) & 0xffc); + pte = cpu_memoryread_d(a); + if (!(pte & CPU_PTE_PRESENT)) { + goto retdummy; + } + if (!(pte & CPU_PTE_ACCESS)) { + memp_write8(a, (UINT8)(pte | CPU_PTE_ACCESS)); + } + if ((wr) && (!(pte & CPU_PTE_DIRTY))) { + memp_write8(a, (UINT8)(pte | CPU_PTE_DIRTY)); + } + addr = (pte & CPU_PTE_BASEADDR_MASK) + (addr & 0x00000fff); + return(addr); + + retdummy: + return(0x01000000); /* XXX */ +} + + +void MEMCALL meml_reads(UINT32 address, void *dat, UINT leng) { + + UINT size; + + if (!CPU_STAT_PAGING) { + memp_reads(address, dat, leng); + } + else { + while(leng) { + size = 0x1000 - (address & 0xfff); + size = min(size, leng); + memp_reads(physicaladdr(address, FALSE), dat, size); + address += size; + dat = ((UINT8 *)dat) + size; + leng -= size; + } + } +} + +void MEMCALL meml_writes(UINT32 address, const void *dat, UINT leng) { + + UINT size; + + if (!CPU_STAT_PAGING) { + memp_writes(address, dat, leng); + } + else { + while(leng) { + size = 0x1000 - (address & 0xfff); + size = min(size, leng); + memp_writes(physicaladdr(address, TRUE), dat, size); + address += size; + dat = ((UINT8 *)dat) + size; + leng -= size; + } + } +} + + +REG8 MEMCALL memr_read8(UINT seg, UINT off) { + + UINT32 addr; + + addr = (seg << 4) + LOW16(off); + if (CPU_STAT_PAGING) { + addr = physicaladdr(addr, FALSE); + } + return(memp_read8(addr)); +} + +REG16 MEMCALL memr_read16(UINT seg, UINT off) { + + UINT32 addr; + + addr = (seg << 4) + LOW16(off); + if (!CPU_STAT_PAGING) { + return(memp_read16(addr)); + } + else if ((addr + 1) & 0xfff) { + return(memp_read16(physicaladdr(addr, FALSE))); + } + return(memr_read8(seg, off) + (memr_read8(seg, off + 1) << 8)); +} + +void MEMCALL memr_write8(UINT seg, UINT off, REG8 dat) { + + UINT32 addr; + + addr = (seg << 4) + LOW16(off); + if (CPU_STAT_PAGING) { + addr = physicaladdr(addr, TRUE); + } + memp_write8(addr, dat); +} + +void MEMCALL memr_write16(UINT seg, UINT off, REG16 dat) { + + UINT32 addr; + + addr = (seg << 4) + LOW16(off); + if (!CPU_STAT_PAGING) { + memp_write16(addr, dat); + } + else if ((addr + 1) & 0xfff) { + memp_write16(physicaladdr(addr, TRUE), dat); + } + else { + memr_write8(seg, off, (REG8)dat); + memr_write8(seg, off + 1, (REG8)(dat >> 8)); + } +} + +void MEMCALL memr_reads(UINT seg, UINT off, void *dat, UINT leng) { + + UINT32 addr; + UINT rem; + UINT size; + + while(leng) { + off = LOW16(off); + addr = (seg << 4) + off; + rem = 0x10000 - off; + size = min(leng, rem); + if (CPU_STAT_PAGING) { + rem = 0x1000 - (addr & 0xfff); + size = min(size, rem); + addr = physicaladdr(addr, FALSE); + } + memp_reads(addr, dat, size); + off += size; + dat = ((UINT8 *)dat) + size; + leng -= size; + } +} + +void MEMCALL memr_writes(UINT seg, UINT off, const void *dat, UINT leng) { + + UINT32 addr; + UINT rem; + UINT size; + + while(leng) { + off = LOW16(off); + addr = (seg << 4) + off; + rem = 0x10000 - off; + size = min(leng, rem); + if (CPU_STAT_PAGING) { + rem = 0x1000 - (addr & 0xfff); + size = min(size, rem); + addr = physicaladdr(addr, TRUE); + } + memp_writes(addr, dat, size); + off += size; + dat = ((UINT8 *)dat) + size; + leng -= size; + } +} + +#endif +#endif diff --git a/source/src/vm/np21/i386c/cpumem.h b/source/src/vm/np21/i386c/cpumem.h new file mode 100644 index 000000000..f03092d08 --- /dev/null +++ b/source/src/vm/np21/i386c/cpumem.h @@ -0,0 +1,362 @@ +#ifndef NP2_I386C_CPUMEM_H__ +#define NP2_I386C_CPUMEM_H__ +#include "cpucore.h" +#if defined(SUPPORT_IA32_HAXM) +#include "i386hax/haxfunc.h" +#include "i386hax/haxcore.h" +#endif + +#ifdef NP2_MEMORY_ASM // アセンブラ版は 必ずfastcallで +#undef MEMCALL +#define MEMCALL FASTCALL +#endif + +#if !defined(MEMCALL) +#define MEMCALL +#endif + +//#ifdef __cplusplus +//extern "C" { +//#endif +#include "../../common.h" +#include "../device.h" +class I386; + +extern I386 *device_cpu; +extern DEVICE *device_mem; +extern DEVICE *device_io; +//#ifdef I386_PSEUDO_BIOS +extern DEVICE *device_bios; +//#endif +//#ifdef SINGLE_MODE_DMA +extern DEVICE *device_dma; +//#endif +extern SINT64 i386_memory_wait; +extern DEBUGGER *device_debugger; +extern UINT32 codefetch_address; +extern SINT32 __exception_set; +extern UINT32 __exception_pc; +extern UINT64 __exception_code; + +inline REG8 MEMCALL memp_read8(UINT32 address); +inline REG16 MEMCALL memp_read16(UINT32 address); +inline UINT32 MEMCALL memp_read32(UINT32 address); +inline void MEMCALL memp_write8(UINT32 address, REG8 value); +inline void MEMCALL memp_write16(UINT32 address, REG16 value); +inline void MEMCALL memp_write32(UINT32 address, UINT32 value); +inline void MEMCALL memp_reads(UINT32 address, void *dat, UINT leng); +inline void MEMCALL memp_writes(UINT32 address, const void *dat, UINT leng); +inline REG8 MEMCALL memp_read8_codefetch(UINT32 address); +inline REG16 MEMCALL memp_read16_codefetch(UINT32 address); +inline UINT32 MEMCALL memp_read32_codefetch(UINT32 address); +inline REG8 MEMCALL memp_read8_paging(UINT32 address); +inline REG16 MEMCALL memp_read16_paging(UINT32 address); +inline UINT32 MEMCALL memp_read32_paging(UINT32 address); +inline void MEMCALL memp_write8_paging(UINT32 address, REG8 value); +inline void MEMCALL memp_write16_paging(UINT32 address, REG16 value); +inline void MEMCALL memp_write32_paging(UINT32 address, UINT32 value); + +REG8 MEMCALL meml_read8(UINT32 address); +REG16 MEMCALL meml_read16(UINT32 address); +UINT32 MEMCALL meml_read32(UINT32 address); +void MEMCALL meml_write8(UINT32 address, REG8 dat); +void MEMCALL meml_write16(UINT32 address, REG16 dat); +void MEMCALL meml_write32(UINT32 address, UINT32 dat); +void MEMCALL meml_reads(UINT32 address, void *dat, UINT leng); +void MEMCALL meml_writes(UINT32 address, const void *dat, UINT leng); + +REG8 MEMCALL memr_read8(UINT seg, UINT off); +REG16 MEMCALL memr_read16(UINT seg, UINT off); +UINT32 MEMCALL memr_read32(UINT seg, UINT off); +void MEMCALL memr_write8(UINT seg, UINT off, REG8 dat); +void MEMCALL memr_write16(UINT seg, UINT off, REG16 dat); +void MEMCALL memr_write32(UINT seg, UINT off, UINT32 dat); +void MEMCALL memr_reads(UINT seg, UINT off, void *dat, UINT leng); +void MEMCALL memr_writes(UINT seg, UINT off, const void *dat, UINT leng); + +inline void IOOUTCALL iocore_out8(UINT port, REG8 dat); +inline REG8 IOINPCALL iocore_inp8(UINT port); + +inline void IOOUTCALL iocore_out16(UINT port, REG16 dat); +inline REG16 IOINPCALL iocore_inp16(UINT port); + +inline void IOOUTCALL iocore_out32(UINT port, UINT32 dat); +inline UINT32 IOINPCALL iocore_inp32(UINT port); + +inline void dmax86(void); + +//#ifdef __cplusplus +//} +//#endif + + +// ---- Physical Space (DMA) + +#define MEMP_READ8(addr) \ + memp_read8((addr)) +#define MEMP_READ16(addr) \ + memp_read16((addr)) +#define MEMP_READ32(addr) \ + memp_read32((addr)) +#define MEMP_WRITE8(addr, dat) \ + memp_write8((addr), (dat)) +#define MEMP_WRITE16(addr, dat) \ + memp_write16((addr), (dat)) +#define MEMP_WRITE32(addr, dat) \ + memp_write32((addr), (dat)) +#define MEMP_READS(addr, dat, leng) \ + memp_reads((addr), (dat), (leng)) +#define MEMP_WRITES(addr, dat, leng) \ + memp_writes((addr), (dat), (leng)) + + +// ---- Logical Space (BIOS) + +#define MEML_READ8(addr) \ + meml_read8((addr)) +#define MEML_READ16(addr) \ + meml_read16((addr)) +#define MEML_READ32(addr) \ + meml_read32((addr)) +#define MEML_WRITE8(addr, dat) \ + meml_write8((addr), (dat)) +#define MEML_WRITE16(addr, dat) \ + meml_write16((addr), (dat)) +#define MEML_WRITE32(addr, dat) \ + meml_write32((addr), (dat)) +#define MEML_READS(addr, dat, leng) \ + meml_reads((addr), (dat), (leng)) +#define MEML_WRITES(addr, dat, leng) \ + meml_writes((addr), (dat), (leng)) + +#define MEMR_READ8(seg, off) \ + memr_read8((seg), (off)) +#define MEMR_READ16(seg, off) \ + memr_read16((seg), (off)) +#define MEMR_WRITE8(seg, off, dat) \ + memr_write8((seg), (off), (dat)) +#define MEMR_WRITE16(seg, off, dat) \ + memr_write16((seg), (off), (dat)) +#define MEMR_READS(seg, off, dat, leng) \ + memr_reads((seg), (off), (dat), (leng)) +#define MEMR_WRITES(seg, off, dat, leng) \ + memr_writes((seg), (off), (dat), (leng)) + +inline REG8 MEMCALL memp_read8(UINT32 address) { + + address = address & CPU_ADRSMASK; + int wait = 0; + REG8 val; + val = device_mem->read_data8w(address, &wait); + i386_memory_wait += wait; + return val; +} + +inline REG16 MEMCALL memp_read16(UINT32 address) { + + address = address & CPU_ADRSMASK; + int wait = 0; + REG16 val; + val = device_mem->read_data16w(address, &wait); + i386_memory_wait += wait; + return val; +// return device_mem->read_data16(address); +} + +inline UINT32 MEMCALL memp_read32(UINT32 address) { + address = address & CPU_ADRSMASK; + int wait = 0; + UINT32 val; + val = device_mem->read_data32w(address, &wait); + i386_memory_wait += wait; + return val; +// return device_mem->read_data32(address); +} + +// ---- +inline REG8 MEMCALL memp_read8_codefetch(UINT32 address) { + + address = address & CPU_ADRSMASK; + int wait = 0; + REG8 val; + codefetch_address = address; + val = device_mem->read_data8w(codefetch_address, &wait); + i386_memory_wait += wait; + return val; +// return device_mem->read_data8(address); +} + +inline REG16 MEMCALL memp_read16_codefetch(UINT32 address) { + + address = address & CPU_ADRSMASK; + int wait = 0; + REG16 val; + codefetch_address = address; + val = device_mem->read_data16w(codefetch_address, &wait); + i386_memory_wait += wait; + return val; +// return device_mem->read_data16(address); +} + +inline UINT32 MEMCALL memp_read32_codefetch(UINT32 address) { + + address = address & CPU_ADRSMASK; + int wait = 0; + UINT32 val; + codefetch_address = address; + val = device_mem->read_data32w(codefetch_address, &wait); + i386_memory_wait += wait; + return val; +// return device_mem->read_data32(address); +} + +// ---- +inline REG8 MEMCALL memp_read8_paging(UINT32 address) { + + return memp_read8_codefetch(address); +} +inline REG16 MEMCALL memp_read16_paging(UINT32 address) { + + return memp_read16_codefetch(address); +} + +inline UINT32 MEMCALL memp_read32_paging(UINT32 address) { + + return memp_read32_codefetch(address); +} + +inline void MEMCALL memp_write8(UINT32 address, REG8 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data8w(address, value, &wait); + i386_memory_wait += wait; +} + +inline void MEMCALL memp_write16(UINT32 address, REG16 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data16w(address, value, &wait); + i386_memory_wait += wait; +// device_mem->write_data16(address, value); +} + +inline void MEMCALL memp_write32(UINT32 address, UINT32 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data32w(address, value, &wait); + i386_memory_wait += wait; +// device_mem->write_data32(address, value); +} + +inline void MEMCALL memp_write8_paging(UINT32 address, REG8 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data8w(address, value, &wait); + i386_memory_wait += wait; +// device_mem->write_data8(address, value); +} + +inline void MEMCALL memp_write16_paging(UINT32 address, REG16 value) { + + address = address & CPU_ADRSMASK; + int wait = 0; + device_mem->write_data16w(address, value, &wait); + i386_memory_wait += wait; +// device_mem->write_data16(address, value); +} + +inline void MEMCALL memp_write32_paging(UINT32 address, UINT32 value) { + + address = address & CPU_ADRSMASK; +// device_mem->write_data32(address, value); + int wait = 0; + device_mem->write_data32w(address, value, &wait); + i386_memory_wait += wait; +} + + +inline void MEMCALL memp_reads(UINT32 address, void *dat, UINT leng) { + + UINT8 *out = (UINT8 *)dat; + + //address = address & CPU_ADRSMASK; + + /* slow memory access */ + while (leng-- > 0) { + address = address & CPU_ADRSMASK; + *out++ = memp_read8(address++); + } +} + +inline void MEMCALL memp_writes(UINT32 address, const void *dat, UINT leng) { + + const UINT8 *out = (UINT8 *)dat; + + /* slow memory access */ + while (leng-- > 0) { + address = address & CPU_ADRSMASK; + memp_write8(address++, *out++); + } +} + +inline void dmax86(void) +{ +//#ifdef SINGLE_MODE_DMA + if(device_dma != NULL) device_dma->do_dma(); +//#endif +} + +inline void IOOUTCALL iocore_out8(UINT port, REG8 dat) +{ + int wait = 0; + device_io->write_io8w(port, dat, &wait); + i386_memory_wait += wait; +} + +inline REG8 IOINPCALL iocore_inp8(UINT port) +{ + int wait = 0; + REG8 val = device_io->read_io8w(port, &wait); + i386_memory_wait += wait; + return val; +} + +inline void IOOUTCALL iocore_out16(UINT port, REG16 dat) +{ + int wait = 0; + device_io->write_io16w(port, dat, &wait); + i386_memory_wait += wait; +// device_io->write_io16(port, dat); +} + +inline REG16 IOINPCALL iocore_inp16(UINT port) +{ + int wait = 0; + REG16 val = device_io->read_io16w(port, &wait); + i386_memory_wait += wait; + return val; +// return device_io->read_io16(port); +} + +inline void IOOUTCALL iocore_out32(UINT port, UINT32 dat) +{ + int wait = 0; + device_io->write_io32w(port, dat, &wait); + i386_memory_wait += wait; +// device_io->write_io32(port, dat); +} + +inline UINT32 IOINPCALL iocore_inp32(UINT port) +{ + int wait = 0; + UINT32 val = device_io->read_io32w(port, &wait); + i386_memory_wait += wait; + return val; +// return device_io->read_io32(port); +} + +#endif /* !NP2_I386C_CPUMEM_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/cpu.cpp b/source/src/vm/np21/i386c/ia32/cpu.cpp new file mode 100644 index 000000000..5c7dd9d56 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpu.cpp @@ -0,0 +1,908 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +//#include "dosio.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "inst_table.h" + +#if defined(ENABLE_TRAP) +#include "trap/steptrap.h" +#endif + +#if defined(SUPPORT_ASYNC_CPU) +#include "timing.h" +#include "nevent.h" +#include "pccore.h" +#include "iocore.h" +#include "sound/sound.h" +#include "sound/beep.h" +#include "sound/fmboard.h" +#include "sound/soundrom.h" +#include "cbus/mpu98ii.h" +#if defined(SUPPORT_SMPU98) +#include "cbus/smpu98.h" +#endif +#endif +#include "../i386_np21.h" + +#ifndef __cplusplus +sigjmp_buf exec_1step_jmpbuf; +#endif +UINT32 realclock; + +#if defined(IA32_INSTRUCTION_TRACE) +typedef struct { + CPU_REGS regs; + disasm_context_t disasm; + + BYTE op[MAX_PREFIX + 2]; + int opbytes; +} ia32_context_t; + +#define NCTX 1024 + +ia32_context_t ctx[NCTX]; +int ctx_index = 0; + +int cpu_inst_trace = 0; +#endif + +#if defined(DEBUG) +int cpu_debug_rep_cont = 0; +CPU_REGS cpu_debug_rep_regs; +#endif + +extern SINT32 __exception_set; +extern UINT32 __exception_pc; +extern UINT64 __exception_code; + +#define I386_TRACE_DATA_BIT_USERDATA_SET 0x80000000 +#define I386_TRACE_DATA_BIT_OP32 0x00000001 +#define I386_TRACE_DATA_BIT_RET 0x00000040 +#define I386_TRACE_DATA_BIT_RETF 0x00000050 +#define I386_TRACE_DATA_BIT_IRET 0x00000060 +#define I386_TRACE_DATA_BIT_JMP 0x00000080 +#define I386_TRACE_DATA_BIT_JMP_COND 0x00000090 +#define I386_TRACE_DATA_BIT_CALL 0x00000100 +#define I386_TRACE_DATA_BIT_INT 0x10000000 +#define I386_TRACE_DATA_BIT_IRQ 0x20000000 +#define I386_TRACE_DATA_BIT_EXCEPTION 0x40000000 + +static __inline__ void __FASTCALL check_exception(bool is_debugging) +{ +// if(!(is_debugging)) return; + if(__exception_set != 0) { + device_debugger->exception_code = __exception_code; + device_debugger->exception_pc = __exception_pc; + device_debugger->exception_happened = true; + device_debugger->add_cpu_trace_exception(__exception_code); + __exception_set = 0; + } + //device_cpu->check_interrupts(); +} + +void +exec_1step(void) +{ + int prefix; + UINT32 op; + bool is_debugging = ((device_debugger != NULL) && (device_debugger->now_debugging)) ? true : false; + CPU_PREV_EIP = CPU_EIP; + CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; + __exception_set = 0; +#if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_EIP); +#endif + +#if defined(IA32_INSTRUCTION_TRACE) + ctx[ctx_index].regs = CPU_STATSAVE.cpu_regs; + if (cpu_inst_trace) { + disasm_context_t *d = &ctx[ctx_index].disasm; + UINT32 eip = CPU_EIP; + int rv; + + rv = disasm(&eip, d); + if (rv == 0) { + char buf[256]; + char tmp[32]; + int len = d->nopbytes > 8 ? 8 : d->nopbytes; + int i; + + buf[0] = '\0'; + for (i = 0; i < len; i++) { + snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); + milstr_ncat(buf, tmp, sizeof(buf)); + } + for (; i < 8; i++) { + milstr_ncat(buf, " ", sizeof(buf)); + } + VERBOSE(("%04x:%08x: %s%s", CPU_CS, CPU_EIP, buf, d->str)); + + buf[0] = '\0'; + for (; i < d->nopbytes; i++) { + snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); + milstr_ncat(buf, tmp, sizeof(buf)); + if ((i % 8) == 7) { + VERBOSE((" : %s", buf)); + buf[0] = '\0'; + } + } + if ((i % 8) != 0) { + VERBOSE((" : %s", buf)); + } + } + } + ctx[ctx_index].opbytes = 0; +#endif + UINT32 old_eip = CPU_PREV_EIP; + UINT32 old_addr = 0; + + for (prefix = 0; prefix < MAX_PREFIX; prefix++) { + GET_PCBYTE(op); +//#ifdef USE_DEBUGGER + UINT32 op_size = I386_TRACE_DATA_BIT_USERDATA_SET; + if (prefix == 0) { + if(device_debugger != NULL) { + device_debugger->add_cpu_trace(codefetch_address); + op_size |= ((CPU_INST_AS32) ? I386_TRACE_DATA_BIT_OP32 : 0); +// device_debugger->add_cpu_trace_userdata(op_size, (I386_TRACE_DATA_BIT_USERDATA_SET | I386_TRACE_DATA_BIT_OP32)); + } + } +//#endif +#if defined(IA32_INSTRUCTION_TRACE) + ctx[ctx_index].op[prefix] = op; + ctx[ctx_index].opbytes++; +#endif + // ToDo: more accurate call trace. + if((op >= 0x70) && (op <= 0x7f)) { + op_size |= I386_TRACE_DATA_BIT_JMP_COND; + } else { + switch(op) { + case 0x9a: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + old_eip; + } + op_size |= I386_TRACE_DATA_BIT_CALL; + break; + case 0xc2: // RET far + case 0xc3: + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + old_eip; + } + op_size |= I386_TRACE_DATA_BIT_RET; + break; + case 0xca: // RET far + case 0xcb: + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + old_eip; + } + op_size |= I386_TRACE_DATA_BIT_RET; + break; + case 0xcf: + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + old_eip; + } + op_size |= I386_TRACE_DATA_BIT_IRET; + break; + case 0xe8: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + old_eip; + } + op_size |= I386_TRACE_DATA_BIT_CALL; + break; + case 0xe9: //JMP + case 0xea: //JMP16 + case 0xeb: //JMP + op_size |= I386_TRACE_DATA_BIT_JMP; + break; + case 0xe3: + op_size |= I386_TRACE_DATA_BIT_JMP_COND; + break; + case 0xf1: + op_size |= I386_TRACE_DATA_BIT_INT; + break; + } + } + device_debugger->add_cpu_trace_userdata(op_size, 0xf000ffff); + + /* prefix */ + if (insttable_info[op] & INST_PREFIX) { + (*insttable_1byte[0][op])(); + switch(op) { + case 0x9a: //CAll + case 0xe8: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; + device_debugger->add_cpu_trace_call(old_addr, new_addr); + } + break; + case 0xc2: // RET far + case 0xc3: + case 0xca: // RET far + case 0xcb: + case 0xcf: // iRET + { + // ToDo: Collect intr num. + device_debugger->add_cpu_trace_return(old_addr); + } + break; + } + continue; + } + break; + } + if (prefix == MAX_PREFIX) { + EXCEPTION(UD_EXCEPTION, 0); + } + +#if defined(IA32_INSTRUCTION_TRACE) + if (op == 0x0f) { + BYTE op2; + op2 = cpu_codefetch(CPU_EIP); + ctx[ctx_index].op[prefix + 1] = op2; + ctx[ctx_index].opbytes++; + } + ctx_index = (ctx_index + 1) % NELEMENTS(ctx); +#endif + + /* normal / rep, but not use */ + if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + switch(op) { + case 0x9a: //CAll + case 0xe8: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; + device_debugger->add_cpu_trace_call(old_addr, new_addr); + } + break; + case 0xc2: // RET far + case 0xc3: + case 0xca: // RET far + case 0xcb: + case 0xcf: // iRET + { + // ToDo: Collect intr num. + device_debugger->add_cpu_trace_return(old_addr); + } + break; + } + return; + } + + /* rep */ + CPU_WORKCLOCK(5); +#if defined(DEBUG) + if (!cpu_debug_rep_cont) { + cpu_debug_rep_cont = 1; + cpu_debug_rep_regs = CPU_STATSAVE.cpu_regs; + } +#endif + if (!CPU_INST_AS32) { + if (CPU_CX != 0) { + if (!(insttable_info[op] & REP_CHECKZF)) { + /* rep */ + for (;;) { + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + if (--CPU_CX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } else if (CPU_INST_REPUSE != 0xf2) { + /* repe */ + for (;;) { + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + if (--CPU_CX == 0 || CC_NZ) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } else { + /* repne */ + for (;;) { + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + if (--CPU_CX == 0 || CC_Z) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } + } else { + if (CPU_ECX != 0) { + if (!(insttable_info[op] & REP_CHECKZF)) { + /* rep */ + for (;;) { + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + if (--CPU_ECX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } else if (CPU_INST_REPUSE != 0xf2) { + /* repe */ + for (;;) { + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + if (--CPU_ECX == 0 || CC_NZ) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } else { + /* repne */ + for (;;) { + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + if (--CPU_ECX == 0 || CC_Z) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } + } +} + +#if 0 +void +exec_allstep(void) +{ + int prefix; + UINT32 op; + void (*func)(void); +#if defined(SUPPORT_ASYNC_CPU) + int firstflag = 1; + UINT timing; + UINT lcflag = 0; + SINT32 oldremclock = CPU_REMCLOCK; + static int remclock_mul = 1000; + int remclockb = 0; + int remclkcnt = 0x100; + int repflag = 0; + static int latecount = 0; + static int latecount2 = 0; + static int hltflag = 0; + bool is_debugging = ((device_debugger != NULL) && (device_debugger->now_debugging)) ? true : false; + __exception_set = 0; + + if(latecount2==0){ + if(latecount > 0){ + //latecount--; + }else if (latecount < 0){ + latecount++; + } + } + latecount2 = (latecount2+1) & 0x1fff; +#endif + + do { + + CPU_PREV_EIP = CPU_EIP; + CPU_STATSAVE.cpu_inst = CPU_STATSAVE.cpu_inst_default; + + #if defined(ENABLE_TRAP) + steptrap(CPU_CS, CPU_EIP); + #endif + + #if defined(IA32_INSTRUCTION_TRACE) + ctx[ctx_index].regs = CPU_STATSAVE.cpu_regs; + if (cpu_inst_trace) { + disasm_context_t *d = &ctx[ctx_index].disasm; + UINT32 eip = CPU_EIP; + int rv; + + rv = disasm(&eip, d); + if (rv == 0) { + char buf[256]; + char tmp[32]; + int len = d->nopbytes > 8 ? 8 : d->nopbytes; + int i; + + buf[0] = '\0'; + for (i = 0; i < len; i++) { + snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); + milstr_ncat(buf, tmp, sizeof(buf)); + } + for (; i < 8; i++) { + milstr_ncat(buf, " ", sizeof(buf)); + } + VERBOSE(("%04x:%08x: %s%s", CPU_CS, CPU_EIP, buf, d->str)); + + buf[0] = '\0'; + for (; i < d->nopbytes; i++) { + snprintf(tmp, sizeof(tmp), "%02x ", d->opbyte[i]); + milstr_ncat(buf, tmp, sizeof(buf)); + if ((i % 8) == 7) { + VERBOSE((" : %s", buf)); + buf[0] = '\0'; + } + } + if ((i % 8) != 0) { + VERBOSE((" : %s", buf)); + } + } + } + ctx[ctx_index].opbytes = 0; + #endif + + for (prefix = 0; prefix < MAX_PREFIX; prefix++) { + GET_PCBYTE(op); + #if defined(IA32_INSTRUCTION_TRACE) + ctx[ctx_index].op[prefix] = op; + ctx[ctx_index].opbytes++; + #endif + + /* prefix */ + if (insttable_info[op] & INST_PREFIX) { + (*insttable_1byte[0][op])(); + check_exception(is_debugging); + switch(op) { + case 0x9a: //CAll + case 0xe8: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; + device_debugger->add_cpu_trace_call(old_addr, new_addr); + } + break; + case 0xcc: // INTr + case 0xcd: + case 0xce: + case 0xf1: + { + // ToDo: Collect intr num. + descriptor_t *sdp = &CPU_CS_DESC; + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; + device_debugger->add_cpu_trace_call(old_addr, new_addr); + } + break; + case 0xc2: // RET far + case 0xc3: + case 0xca: // RET far + case 0xcb: + case 0xcf: // iRET + { + // ToDo: Collect intr num. + device_debugger->add_cpu_trace_return(old_addr); + } + break; + } + continue; + } + break; + } + if (prefix == MAX_PREFIX) { + EXCEPTION(UD_EXCEPTION, 0); + } + check_exception(is_debugging); + + #if defined(IA32_INSTRUCTION_TRACE) + if (op == 0x0f) { + BYTE op2; + op2 = cpu_codefetch(CPU_EIP); + ctx[ctx_index].op[prefix + 1] = op2; + ctx[ctx_index].opbytes++; + } + ctx_index = (ctx_index + 1) % NELEMENTS(ctx); + #endif + + /* normal / rep, but not use */ + if (!(insttable_info[op] & INST_STRING) || !CPU_INST_REPUSE) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + (*insttable_1byte[CPU_INST_OP32][op])(); + check_exception(is_debugging); + switch(op) { + case 0x9a: //CAll + case 0xe8: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; + device_debugger->add_cpu_trace_call(old_addr, new_addr); + } + break; + case 0xcc: // INTr + case 0xcd: + case 0xce: + case 0xf1: + { + // ToDo: Collect intr num. + descriptor_t *sdp = &CPU_CS_DESC; + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; + device_debugger->add_cpu_trace_call(old_addr, new_addr); + } + break; + case 0xc2: // RET far + case 0xc3: + case 0xca: // RET far + case 0xcb: + case 0xcf: // iRET + { + // ToDo: Collect intr num. + device_debugger->add_cpu_trace_return(old_addr); + } + break; + } + goto cpucontinue; //continue; + } + + /* rep */ +#if defined(SUPPORT_ASYNC_CPU) + repflag = CPU_ECX; +#endif + CPU_WORKCLOCK(5); + #if defined(DEBUG) + if (!cpu_debug_rep_cont) { + cpu_debug_rep_cont = 1; + cpu_debug_rep_regs = CPU_STATSAVE.cpu_regs; + } + #endif + func = insttable_1byte[CPU_INST_OP32][op]; + if (!CPU_INST_AS32) { + if (CPU_CX != 0) { + if(CPU_CX==1){ + (*func)(); + check_exception(is_debugging); + --CPU_CX; + }else{ + if (!(insttable_info[op] & REP_CHECKZF)) { + if(insttable_1byte_repfunc[CPU_INST_OP32][op]){ + (*insttable_1byte_repfunc[CPU_INST_OP32][op])(0); + check_exception(is_debugging); + }else{ + /* rep */ + for (;;) { + (*func)(); + check_exception(is_debugging); + if (--CPU_CX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } else if (CPU_INST_REPUSE != 0xf2) { + if(insttable_1byte_repfunc[CPU_INST_OP32][op]){ + (*insttable_1byte_repfunc[CPU_INST_OP32][op])(1); + check_exception(is_debugging); + }else{ + /* repe */ + for (;;) { + (*func)(); + check_exception(is_debugging); + if (--CPU_CX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } else { + if(insttable_1byte_repfunc[CPU_INST_OP32][op]){ + (*insttable_1byte_repfunc[CPU_INST_OP32][op])(2); + check_exception(is_debugging); + }else{ + /* repne */ + for (;;) { + (*func)(); + check_exception(is_debugging); + if (--CPU_CX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } + } + } + } else { + if (CPU_ECX != 0) { + if(CPU_ECX==1){ + (*func)(); + check_exception(is_debugging); + --CPU_ECX; + }else{ + if (!(insttable_info[op] & REP_CHECKZF)) { + if(insttable_1byte_repfunc[CPU_INST_OP32][op]){ + (*insttable_1byte_repfunc[CPU_INST_OP32][op])(0); + check_exception(is_debugging); + }else{ + /* rep */ + for (;;) { + (*func)(); + check_exception(is_debugging); + if (--CPU_ECX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } else if (CPU_INST_REPUSE != 0xf2) { + if(insttable_1byte_repfunc[CPU_INST_OP32][op]){ + (*insttable_1byte_repfunc[CPU_INST_OP32][op])(1); + check_exception(is_debugging); + }else{ + /* repe */ + for (;;) { + (*func)(); + check_exception(is_debugging); + if (--CPU_ECX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } else { + if(insttable_1byte_repfunc[CPU_INST_OP32][op]){ + (*insttable_1byte_repfunc[CPU_INST_OP32][op])(2); + check_exception(is_debugging); + }else{ + /* repne */ + for (;;) { + (*func)(); + check_exception(is_debugging); + if (--CPU_ECX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + if(device_cpu->check_interrupts()) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } + } + } + } + } +cpucontinue: +#if defined(SUPPORT_ASYNC_CPU) + // 非同期CPU処理 + if(np2cfg.asynccpu){ +#define LATECOUNTER_THRESHOLD 6 +#define LATECOUNTER_THRESHOLDM 6 + int realclock = 0; + if(CPU_STAT_HLT){ + hltflag = pccore.multiple; + } + if(CPU_REMCLOCK >= 0 && !realclock && (remclkcnt > 0x7)){ + remclkcnt = 0; + firstflag = 0; + timing = timing_getcount_baseclock(); + if(timing!=0){ + if(!asynccpu_fastflag && !asynccpu_lateflag){ + if(remclock_mul < 100000) { + latecount++; + if(latecount > +LATECOUNTER_THRESHOLD){ + if(pccore.multiple > 4){ + UINT32 oldmultiple = pccore.multiple; + if(pccore.multiple > 40){ + pccore.multiple-=3; + }else if(pccore.multiple > 20){ + pccore.multiple-=2; + }else{ + pccore.multiple-=1; + } + pccore.realclock = pccore.baseclock * pccore.multiple; + nevent_changeclock(oldmultiple, pccore.multiple); + + sound_changeclock(); + beep_changeclock(); + mpu98ii_changeclock(); +#if defined(SUPPORT_SMPU98) + smpu98_changeclock(); +#endif + keyboard_changeclock(); + mouseif_changeclock(); + gdc_updateclock(); + } + + latecount = 0; + } + } + asynccpu_lateflag = 1; + + CPU_REMCLOCK = 0; + break; + } + }else{ + if(!hltflag && !asynccpu_lateflag && g_nevent.item[NEVENT_FLAMES].proc==screendisp && g_nevent.item[NEVENT_FLAMES].clock <= CPU_BASECLOCK){ + //CPU_REMCLOCK = 10000; + //oldremclock = CPU_REMCLOCK; + if(!asynccpu_fastflag){ + latecount--; + if(latecount < -LATECOUNTER_THRESHOLDM){ + if(pccore.multiple < pccore.maxmultiple){ + UINT32 oldmultiple = pccore.multiple; + pccore.multiple+=1; + pccore.realclock = pccore.baseclock * pccore.multiple; + nevent_changeclock(oldmultiple, pccore.multiple); + + sound_changeclock(); + beep_changeclock(); + mpu98ii_changeclock(); +#if defined(SUPPORT_SMPU98) + smpu98_changeclock(); +#endif + keyboard_changeclock(); + mouseif_changeclock(); + gdc_updateclock(); + } + latecount = 0; + } + asynccpu_fastflag = 1; + } + } + firstflag = 1; + } + } + remclkcnt++; + } +#else + ; +#endif + + } while (CPU_REMCLOCK > 0); +#if defined(SUPPORT_ASYNC_CPU) + if(hltflag > 0) hltflag--; +#endif +} +#endif + diff --git a/source/src/vm/np21/i386c/ia32/cpu.h b/source/src/vm/np21/i386c/ia32/cpu.h new file mode 100644 index 000000000..3c615ef5e --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpu.h @@ -0,0 +1,1488 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Intel Architecture 32-bit Processor Interpreter Engine for Pentium + + Copyright by Yui/Studio Milmake 1999-2000 + Copyright by Norio HATTORI 2000,2001 + Copyright by NONAKA Kimihiro 2002-2004 +*/ + +#ifndef IA32_CPU_CPU_H__ +#define IA32_CPU_CPU_H__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning( disable : 4065 ) +#pragma warning( disable : 4996 ) +#endif + +#include "../../../vm_template.h" +#include "../../../../emu.h" +#include "../../../device.h" +//#ifdef USE_DEBUGGER +#include "../../../debugger.h" +//#endif +class I386; + +#ifdef __BIG_ENDIAN__ + #define BYTESEX_BIG +#else + #define BYTESEX_LITTLE +#endif + +#if defined(_MSC_VER) && defined(_WIN32) +#ifndef SINT8 + typedef signed __int8 SINT8; +#endif +#ifndef SINT16 + typedef signed __int16 SINT16; +#endif +#ifndef SINT32 + typedef signed __int32 SINT32; +#endif +#ifndef SINT64 + typedef signed __int64 SINT64; +#endif +#else +#ifndef SINT8 + typedef int8_t SINT8; +#endif +#ifndef SINT16 + typedef int16_t SINT16; +#endif +#ifndef SINT32 + typedef int32_t SINT32; +#endif +#ifndef SINT64 + typedef int64_t SINT64; +#endif +#ifndef UINT8 + typedef uint8_t UINT8; +#endif +#ifndef UINT16 + typedef uint16_t UINT16; +#endif +#ifndef UINT32 + typedef uint32_t UINT32; +#endif +#ifndef UINT64 + typedef uint64_t UINT64; +#endif +#endif + +#ifndef REG8 + #define REG8 UINT8 +#endif +#ifndef REG16 + #define REG16 UINT16 +#endif + +#ifndef LOADINTELDWORD +#define LOADINTELDWORD(a) (((UINT32)(((UINT8*)(a))[0]) ) | \ + ((UINT32)(((UINT8*)(a))[1]) << 8) | \ + ((UINT32)(((UINT8*)(a))[2]) << 16) | \ + ((UINT32)(((UINT8*)(a))[3]) << 24)) +#endif + +#ifndef LOADINTELWORD +#define LOADINTELWORD(a) (((UINT16)((UINT8*)(a))[0]) | ((UINT16)(((UINT8*)(a))[1]) << 8)) +#endif + +#ifndef STOREINTELDWORD +#define STOREINTELDWORD(a, b) *(((UINT8*)(a))+0) = (UINT8)((b) ); \ + *(((UINT8*)(a))+1) = (UINT8)((b)>> 8); \ + *(((UINT8*)(a))+2) = (UINT8)((b)>>16); \ + *(((UINT8*)(a))+3) = (UINT8)((b)>>24) +#endif + +#ifndef STOREINTELWORD +#define STOREINTELWORD(a, b) *(((UINT8*)(a))+0) = (UINT8)((b) ); \ + *(((UINT8*)(a))+1) = (UINT8)((b)>>8) +#endif + +#ifndef LOW16 +#define LOW16(a) ((UINT16)(a)) +#endif + +#ifndef INLINE + #ifdef __cplusplus + #define INLINE inline + #else + #define INLINE __inline + #endif +#endif + +#ifndef __ASSERT + #define __ASSERT assert +#endif + +#define _MALLOC(a, b) malloc(a) +#define _MFREE(a) free(a) + +#define msgbox(a, b) +#ifndef TRACEOUT + #define TRACEOUT(a) +#endif +#define VERBOSE(a) + +#include "./cpucall_types.h" + +#define SUPPORT_FPU_DOSBOX +#define SUPPORT_FPU_DOSBOX2 +#define SUPPORT_FPU_SOFTFLOAT +#define USE_FPU +#define USE_MMX +#define USE_3DNOW +#define USE_SSE +#define USE_SSE2 +#define USE_SSE3 +#define USE_TSC +#define USE_FASTPAGING +#define USE_VME +#define IA32_REBOOT_ON_PANIC + +enum { + FPU_TYPE_SOFTFLOAT = 0, /* Berkeley SoftFloat */ + FPU_TYPE_DOSBOX = 1, /* DOSBox FPU */ + FPU_TYPE_DOSBOX2 = 2 /* DOSBox FPU+INT64 */ +}; + +#include "interface.h" +#if defined(SUPPORT_FPU_SOFTFLOAT) +#include "instructions/fpu/softfloat/softfloat.h" +#endif + +//#ifdef __cplusplus +//extern "C" { +//#endif + +typedef union { +#if defined(BYTESEX_LITTLE) + struct { + UINT8 l; + UINT8 h; + UINT8 _hl; + UINT8 _hh; + } b; + struct { + UINT16 w; + UINT16 _hw; + } w; +#elif defined(BYTESEX_BIG) + struct { + UINT8 _hh; + UINT8 _hl; + UINT8 h; + UINT8 l; + } b; + struct { + UINT16 _hw; + UINT16 w; + } w; +#endif + UINT32 d; +} REG32; + +typedef struct { + UINT8 b[10]; +} REG80; + +//#ifdef __cplusplus +//} +//#endif + +#include "segments.h" + +//#ifdef __cplusplus +//extern "C" { +//#endif + +enum { + CPU_EAX_INDEX = 0, + CPU_ECX_INDEX = 1, + CPU_EDX_INDEX = 2, + CPU_EBX_INDEX = 3, + CPU_ESP_INDEX = 4, + CPU_EBP_INDEX = 5, + CPU_ESI_INDEX = 6, + CPU_EDI_INDEX = 7, + CPU_REG_NUM +}; + +enum { + CPU_ES_INDEX = 0, + CPU_CS_INDEX = 1, + CPU_SS_INDEX = 2, + CPU_DS_INDEX = 3, + CPU_SEGREG286_NUM = 4, + CPU_FS_INDEX = 4, + CPU_GS_INDEX = 5, + CPU_SEGREG_NUM +}; + +enum { + CPU_TEST_REG_NUM = 8 +}; + +enum { + CPU_DEBUG_REG_NUM = 8, + CPU_DEBUG_REG_INDEX_NUM = 4 +}; + +enum { + MAX_PREFIX = 8 +}; + +typedef struct { + REG32 reg[CPU_REG_NUM]; + UINT16 sreg[CPU_SEGREG_NUM]; + + REG32 eflags; + REG32 eip; + + REG32 prev_eip; + REG32 prev_esp; + + UINT32 tr[CPU_TEST_REG_NUM]; + UINT32 dr[CPU_DEBUG_REG_NUM]; +} CPU_REGS; + +typedef struct { + UINT16 gdtr_limit; + UINT16 pad0; + UINT32 gdtr_base; + UINT16 idtr_limit; + UINT16 pad1; + UINT32 idtr_base; + + UINT16 ldtr; + UINT16 tr; + + UINT32 cr0; + UINT32 cr1; + UINT32 cr2; + UINT32 cr3; + UINT32 cr4; + UINT32 mxcsr; +} CPU_SYSREGS; + +typedef struct { + descriptor_t sreg[CPU_SEGREG_NUM]; + descriptor_t ldtr; + descriptor_t tr; + + UINT32 adrsmask; + UINT32 ovflag; + + UINT8 ss_32; + UINT8 resetreq; + UINT8 trap; + + UINT8 page_wp; + + UINT8 protected_mode; + UINT8 paging; + UINT8 vm86; + UINT8 user_mode; + + UINT8 hlt; + UINT8 bp; /* break point bitmap */ + UINT8 bp_ev; /* break point event */ + + UINT8 backout_sp; /* backout ESP, when exception */ + + UINT32 pde_base; + + UINT32 ioaddr; /* I/O bitmap linear address */ + UINT16 iolimit; /* I/O bitmap count */ + + UINT8 nerror; /* double fault/ triple fault */ + UINT8 prev_exception; +} CPU_STAT; + +typedef struct { + UINT8 op_32; + UINT8 as_32; + UINT8 rep_used; + UINT8 seg_used; + UINT32 seg_base; +} CPU_INST; + +/* FPU */ +enum { + FPU_REG_NUM = 8, + XMM_REG_NUM = 8 +}; + +typedef struct { + UINT16 seg; + UINT16 pad; + UINT32 offset; +} FPU_PTR; + +typedef struct { + UINT16 control; // 制御レジスター +#ifdef USE_FPU_ASM + UINT16 cw_mask_all; // 制御レジスターmask +#endif + UINT16 status; // ステータスレジスター + UINT16 op; // オペコードレジスター + UINT16 tag; // タグワードレジスター + + FPU_PTR inst; // ラスト命令ポインタレジスター + FPU_PTR data; // ラストデータポインタレジスター +} FPU_REGS; + +#if 0 + +typedef struct { + UINT8 valid; + UINT8 sign; + UINT8 zero; + UINT8 inf; + UINT8 nan; + UINT8 denorm; + SINT16 exp; + UINT64 num; +} FP_REG; + +typedef struct { + UINT8 top; + UINT8 pc; + UINT8 rc; + UINT8 dmy[1]; + + FP_REG reg[FPU_REG_NUM]; // R0 to R7 +} FPU_STAT; + +#else + +typedef enum { + TAG_Valid = 0, + TAG_Zero = 1, + TAG_Weird = 2, + TAG_Empty = 3 +} FP_TAG; + +typedef enum { + ROUND_Nearest = 0, + ROUND_Down = 1, + ROUND_Up = 2, + ROUND_Chop = 3 +} FP_RND; + +typedef union { + floatx80 d; + double d64; + struct { + UINT32 lower; + SINT32 upper; + SINT16 ext; + } l; + struct { + UINT32 lower; + UINT32 upper; + SINT16 ext; + } ul; + SINT64 ll; +} FP_REG; + +typedef struct { + UINT32 m1; + UINT32 m2; + UINT16 m3; + + UINT16 d1; + UINT32 d2; +} FP_P_REG; + +typedef union { + struct { + UINT32 m1; + UINT32 m2; + UINT16 m3; + } ul32; + struct { + UINT32 m1; + UINT32 m2; + SINT16 m3; + } l32; + struct { + UINT64 m12; + UINT16 m3; + } ul64; + struct { + UINT64 m12; + SINT16 m3; + } l64; +} FP_INT_REG; + +typedef union { + float f[4]; + double d[2]; + UINT8 ul8[16]; + UINT16 ul16[8]; + UINT32 ul32[4]; + UINT64 ul64[2]; +} XMM_REG; + +typedef struct { +#ifdef USE_FPU_ASM + unsigned int top; +#else + UINT8 top; +#endif + UINT8 pc; + UINT8 rc; + UINT8 dmy[1]; +// +//#if defined(USE_FPU_ASM) +// FP_P_REG p_reg[FPU_REG_NUM+1]; // R0 to R7 +//#else + FP_REG reg[FPU_REG_NUM+1]; // R0 to R7 +//#endif + FP_TAG tag[FPU_REG_NUM+1]; // R0 to R7 + FP_RND round; +#ifdef SUPPORT_FPU_DOSBOX2 // XXX: 整数間だけ正確にするため用 + FP_INT_REG int_reg[FPU_REG_NUM+1]; + UINT8 int_regvalid[FPU_REG_NUM+1]; +#endif +#ifdef USE_SSE + XMM_REG xmm_reg[XMM_REG_NUM+1]; // xmm0 to xmm7 +#endif +#ifdef USE_MMX + UINT8 mmxenable; +#endif +} FPU_STAT; + +#endif + +typedef struct { + CPU_REGS cpu_regs; + CPU_SYSREGS cpu_sysregs; + CPU_STAT cpu_stat; + CPU_INST cpu_inst; + CPU_INST cpu_inst_default; + +#if defined(USE_FPU) + FPU_REGS fpu_regs; + FPU_STAT fpu_stat; +#endif + + /* protected by cpu shut */ + UINT8 cpu_type; + UINT8 itfbank; + UINT16 ram_d0; + SINT32 remainclock; + SINT32 baseclock; + UINT32 clock; + +#if defined(USE_TSC) + UINT64 cpu_tsc; +#endif +} I386STAT; + +typedef struct { + UINT8 *ext; + UINT32 extsize; + UINT8 *extbase; /* = ext - 0x100000 */ + UINT32 extlimit16mb; /* = extsize + 0x100000 (MAX:16MB) */ + UINT32 extlimit4gb; /* = extsize + 0x100000 */ + UINT32 inport; + UINT8 *ems[4]; +} I386EXT; + +typedef struct { + I386STAT s; /* STATsave'ed */ + I386EXT e; +} I386CORE; + +#define I386CPUID_VERSION 1 +typedef struct { + UINT32 version; // CPUIDバージョン(ステートセーブ互換性を維持するため用)I386CPUID_VERSIONが最新 + char cpu_vendor[16]; // ベンダー(12byte) + UINT32 cpu_family; // ファミリ + UINT32 cpu_model; // モデル + UINT32 cpu_stepping; // ステッピング + UINT32 cpu_feature; // 機能フラグ + UINT32 cpu_feature_ex; // 拡張機能フラグ + char cpu_brandstring[64]; // ブランド名(48byte) + UINT32 cpu_brandid; // ブランドID + UINT32 cpu_feature_ecx; // ECX機能フラグ + UINT32 cpu_eflags_mask; // EFLAGSマスク(1のところがマスク状態) + UINT32 reserved[31]; // 将来の拡張のためにとりあえず32bit*31個用意しておく + + UINT8 fpu_type; // FPU種類 +} I386CPUID; + +#define I386MSR_VERSION 1 +typedef struct { + UINT64 ia32_sysenter_cs; // SYSENTER CSレジスタ + UINT64 ia32_sysenter_esp; // SYSENTER ESPレジスタ + UINT64 ia32_sysenter_eip; // SYSENTER EIPレジスタ +} I386MSR_REG; +typedef struct { + UINT32 version; // MSRバージョン(ステートセーブ互換性を維持するため用)I386MSR_VERSIONが最新 + union{ + UINT64 regs[32]; // 将来の拡張のためにとりあえず64bit*32個用意しておく + I386MSR_REG reg; + }; +} I386MSR; + +extern I386CORE i386core; +extern I386CPUID i386cpuid; +extern I386MSR i386msr; + +#define CPU_STATSAVE i386core.s + +#define CPU_ADRSMASK i386core.s.cpu_stat.adrsmask +#define CPU_RESETREQ i386core.s.cpu_stat.resetreq + +#define CPU_REMCLOCK i386core.s.remainclock +#define CPU_BASECLOCK i386core.s.baseclock +#define CPU_CLOCK i386core.s.clock +#define CPU_ITFBANK i386core.s.itfbank +#define CPU_RAM_D000 i386core.s.ram_d0 + +#define CPU_TYPE i386core.s.cpu_type +#define CPUTYPE_V30 0x01 + +#define CPU_EXTMEM i386core.e.ext +#define CPU_EXTMEMSIZE i386core.e.extsize +#define CPU_EXTMEMBASE i386core.e.extbase +#define CPU_EXTLIMIT16 i386core.e.extlimit16mb +#define CPU_EXTLIMIT i386core.e.extlimit4gb +#define CPU_INPADRS i386core.e.inport +#define CPU_EMSPTR i386core.e.ems + +#ifndef __cplusplus +extern sigjmp_buf exec_1step_jmpbuf; +#endif +extern UINT32 realclock; +extern I386 *device_cpu; +extern DEVICE *device_mem; +extern DEVICE *device_io; +//#ifdef I386_PSEUDO_BIOS +extern DEVICE *device_bios; +//#endif +//#ifdef SINGLE_MODE_DMA +extern DEVICE *device_dma; +extern DEBUGGER *device_debugger; +//#endif +extern int64_t i386_memory_wait; +extern UINT32 codefetch_address; + +/* + * CPUID + */ +/*** vendor ***/ +#define CPU_VENDOR_INTEL "GenuineIntel" +#define CPU_VENDOR_AMD "AuthenticAMD" +#define CPU_VENDOR_AMD2 "AMDisbetter!" +#define CPU_VENDOR_CYRIX "CyrixInstead" +#define CPU_VENDOR_NEXGEN "NexGenDriven" +#define CPU_VENDOR_CENTAUR "CentaurHauls" +#define CPU_VENDOR_TRANSMETA "GenuineTMx86" +#define CPU_VENDOR_TRANSMETA2 "TransmetaCPU" +#define CPU_VENDOR_NSC "Geode by NSC" +#define CPU_VENDOR_RISE "RiseRiseRise" +#define CPU_VENDOR_UMC "UMC UMC UMC " +#define CPU_VENDOR_SIS "SiS SiS SiS " +#define CPU_VENDOR_VIA "VIA VIA VIA " +#define CPU_VENDOR_NEKOPRO "Neko Project" + +// デフォルト設定 +#define CPU_VENDOR CPU_VENDOR_INTEL + +/*** version ***/ +#define CPU_PENTIUM_4_FAMILY 15 +#define CPU_PENTIUM_4_MODEL 2 /* Pentium 4 */ +#define CPU_PENTIUM_4_STEPPING 4 + +#define CPU_PENTIUM_M_FAMILY 6 +#define CPU_PENTIUM_M_MODEL 9 /* Pentium M */ +#define CPU_PENTIUM_M_STEPPING 5 + +#define CPU_PENTIUM_III_FAMILY 6 +#define CPU_PENTIUM_III_MODEL 7 /* Pentium III */ +#define CPU_PENTIUM_III_STEPPING 2 + +#define CPU_PENTIUM_II_FAMILY 6 +#define CPU_PENTIUM_II_MODEL 3 /* Pentium II */ +#define CPU_PENTIUM_II_STEPPING 3 + +#define CPU_PENTIUM_PRO_FAMILY 6 +#define CPU_PENTIUM_PRO_MODEL 1 /* Pentium Pro */ +#define CPU_PENTIUM_PRO_STEPPING 1 + +#define CPU_MMX_PENTIUM_FAMILY 5 +#define CPU_MMX_PENTIUM_MODEL 4 /* MMX Pentium */ +#define CPU_MMX_PENTIUM_STEPPING 4 + +#define CPU_PENTIUM_FAMILY 5 +#define CPU_PENTIUM_MODEL 2 /* Pentium */ +#define CPU_PENTIUM_STEPPING 5 + +#define CPU_I486DX_FAMILY 4 +#define CPU_I486DX_MODEL 1 /* 486DX */ +#define CPU_I486DX_STEPPING 3 + +#define CPU_I486SX_FAMILY 4 +#define CPU_I486SX_MODEL 2 /* 486SX */ +#define CPU_I486SX_STEPPING 3 + +#define CPU_80386_FAMILY 3 +#define CPU_80386_MODEL 0 /* 80386 */ +#define CPU_80386_STEPPING 8 + +#define CPU_80286_FAMILY 2 +#define CPU_80286_MODEL 1 /* 80286 */ +#define CPU_80286_STEPPING 1 + + +#define CPU_AMD_K7_ATHLON_XP_FAMILY 6 +#define CPU_AMD_K7_ATHLON_XP_MODEL 6 /* AMD K7 Athlon XP */ +#define CPU_AMD_K7_ATHLON_XP_STEPPING 2 + +#define CPU_AMD_K7_ATHLON_FAMILY 6 +#define CPU_AMD_K7_ATHLON_MODEL 1 /* AMD K7 Athlon */ +#define CPU_AMD_K7_ATHLON_STEPPING 2 + +#define CPU_AMD_K6_III_FAMILY 5 +#define CPU_AMD_K6_III_MODEL 9 /* AMD K6-III */ +#define CPU_AMD_K6_III_STEPPING 1 + +#define CPU_AMD_K6_2_FAMILY 5 +#define CPU_AMD_K6_2_MODEL 8 /* AMD K6-2 */ +#define CPU_AMD_K6_2_STEPPING 12 + + +/*** feature ***/ +#define CPU_FEATURE_FPU (1 << 0) +#define CPU_FEATURE_VME (1 << 1) +#define CPU_FEATURE_DE (1 << 2) +#define CPU_FEATURE_PSE (1 << 3) +#define CPU_FEATURE_TSC (1 << 4) +#define CPU_FEATURE_MSR (1 << 5) +#define CPU_FEATURE_PAE (1 << 6) +#define CPU_FEATURE_MCE (1 << 7) +#define CPU_FEATURE_CX8 (1 << 8) +#define CPU_FEATURE_APIC (1 << 9) +/* (1 << 10) */ +#define CPU_FEATURE_SEP (1 << 11) +#define CPU_FEATURE_MTRR (1 << 12) +#define CPU_FEATURE_PGE (1 << 13) +#define CPU_FEATURE_MCA (1 << 14) +#define CPU_FEATURE_CMOV (1 << 15) +#define CPU_FEATURE_FGPAT (1 << 16) +#define CPU_FEATURE_PSE36 (1 << 17) +#define CPU_FEATURE_PN (1 << 18) +#define CPU_FEATURE_CLFSH (1 << 19) +/* (1 << 20) */ +#define CPU_FEATURE_DS (1 << 21) +#define CPU_FEATURE_ACPI (1 << 22) +#define CPU_FEATURE_MMX (1 << 23) +#define CPU_FEATURE_FXSR (1 << 24) +#define CPU_FEATURE_SSE (1 << 25) +#define CPU_FEATURE_SSE2 (1 << 26) +#define CPU_FEATURE_SS (1 << 27) +#define CPU_FEATURE_HTT (1 << 28) +#define CPU_FEATURE_TM (1 << 29) +/* (1 << 30) */ +#define CPU_FEATURE_PBE (1 << 31) + +//#define CPU_FEATURE_XMM CPU_FEATURE_SSE + +#if defined(USE_FPU) +#define CPU_FEATURE_FPU_FLAG CPU_FEATURE_FPU +#else +#define CPU_FEATURE_FPU_FLAG 0 +#endif + +#if defined(USE_TSC) +#define CPU_FEATURE_TSC_FLAG CPU_FEATURE_TSC +#else +#define CPU_FEATURE_TSC_FLAG 0 +#endif + +#if defined(USE_VME) +#define CPU_FEATURE_VME_FLAG CPU_FEATURE_VME +#else +#define CPU_FEATURE_VME_FLAG 0 +#endif + +#if defined(USE_MMX)&&defined(USE_FPU) +#define CPU_FEATURE_MMX_FLAG CPU_FEATURE_MMX|CPU_FEATURE_FXSR +#else +#define CPU_FEATURE_MMX_FLAG 0 +#endif + +#if defined(USE_MMX)&&defined(USE_FPU)&&defined(USE_SSE) +#define CPU_FEATURE_SSE_FLAG CPU_FEATURE_SSE|CPU_FEATURE_CLFSH +#else +#define CPU_FEATURE_SSE_FLAG 0 +#endif + +#if defined(USE_MMX)&&defined(USE_FPU)&&defined(USE_SSE)&&defined(USE_SSE2) +#define CPU_FEATURE_SSE2_FLAG CPU_FEATURE_SSE2 +#else +#define CPU_FEATURE_SSE2_FLAG 0 +#endif + +/* 使用できる機能全部 */ +#define CPU_FEATURES_ALL (CPU_FEATURE_FPU_FLAG|CPU_FEATURE_CX8|CPU_FEATURE_TSC_FLAG|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_MMX_FLAG|CPU_FEATURE_SSE_FLAG|CPU_FEATURE_SSE2_FLAG|CPU_FEATURE_SEP) + +#define CPU_FEATURES_PENTIUM_4 (CPU_FEATURE_FPU|CPU_FEATURE_CX8|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_FXSR|CPU_FEATURE_MMX|CPU_FEATURE_CLFSH|CPU_FEATURE_SSE|CPU_FEATURE_SSE2) +#define CPU_FEATURES_PENTIUM_M (CPU_FEATURE_FPU|CPU_FEATURE_CX8|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_FXSR|CPU_FEATURE_MMX|CPU_FEATURE_CLFSH|CPU_FEATURE_SSE|CPU_FEATURE_SSE2) +#define CPU_FEATURES_PENTIUM_III (CPU_FEATURE_FPU|CPU_FEATURE_CX8|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_FXSR|CPU_FEATURE_MMX|CPU_FEATURE_CLFSH|CPU_FEATURE_SSE) +#define CPU_FEATURES_PENTIUM_II (CPU_FEATURE_FPU|CPU_FEATURE_CX8|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_FXSR|CPU_FEATURE_MMX) +#define CPU_FEATURES_PENTIUM_PRO (CPU_FEATURE_FPU|CPU_FEATURE_CX8|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_FXSR) +#define CPU_FEATURES_MMX_PENTIUM (CPU_FEATURE_FPU|CPU_FEATURE_CX8|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_MMX) +#define CPU_FEATURES_PENTIUM (CPU_FEATURE_FPU|CPU_FEATURE_CX8|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG) +#define CPU_FEATURES_I486DX (CPU_FEATURE_FPU) +#define CPU_FEATURES_I486SX (0) +#define CPU_FEATURES_80386 (0) +#define CPU_FEATURES_80286 (0) + +#define CPU_FEATURES_AMD_K7_ATHLON_XP (CPU_FEATURE_FPU|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_FXSR|CPU_FEATURE_MMX|CPU_FEATURE_CLFSH|CPU_FEATURE_SSE) +#define CPU_FEATURES_AMD_K7_ATHLON (CPU_FEATURE_FPU|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_CMOV|CPU_FEATURE_MMX) +#define CPU_FEATURES_AMD_K6_III (CPU_FEATURE_FPU|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_MMX) +#define CPU_FEATURES_AMD_K6_2 (CPU_FEATURE_FPU|CPU_FEATURE_TSC|CPU_FEATURE_VME_FLAG|CPU_FEATURE_MMX) + +/*** extended feature ***/ +#define CPU_FEATURE_EX_SYSCALL (1 << 11) +#define CPU_FEATURE_EX_XDBIT (1 << 20) +#define CPU_FEATURE_EX_EM64T (1 << 29) +#define CPU_FEATURE_EX_E3DNOW (1 << 30) +#define CPU_FEATURE_EX_3DNOW (1 << 31) + +#if defined(USE_MMX)&&defined(USE_FPU)&&defined(USE_3DNOW) +#define CPU_FEATURE_EX_3DNOW_FLAG CPU_FEATURE_EX_3DNOW +#else +#define CPU_FEATURE_EX_3DNOW_FLAG 0 +#endif + +#if defined(USE_MMX)&&defined(USE_FPU)&&defined(USE_3DNOW)&&defined(USE_SSE) +#define CPU_FEATURE_EX_E3DNOW_FLAG CPU_FEATURE_EX_E3DNOW +#else +#define CPU_FEATURE_EX_E3DNOW_FLAG 0 +#endif + +/* 使用できる機能全部 */ +#define CPU_FEATURES_EX_ALL (CPU_FEATURE_EX_3DNOW_FLAG|CPU_FEATURE_EX_E3DNOW_FLAG) + +#define CPU_FEATURES_EX_PENTIUM_4 (0) +#define CPU_FEATURES_EX_PENTIUM_M (0) +#define CPU_FEATURES_EX_PENTIUM_III (0) +#define CPU_FEATURES_EX_PENTIUM_II (0) +#define CPU_FEATURES_EX_PENTIUM_PRO (0) +#define CPU_FEATURES_EX_MMX_PENTIUM (0) +#define CPU_FEATURES_EX_PENTIUM (0) +#define CPU_FEATURES_EX_I486DX (0) +#define CPU_FEATURES_EX_I486SX (0) +#define CPU_FEATURES_EX_80386 (0) +#define CPU_FEATURES_EX_80286 (0) + +#define CPU_FEATURES_EX_AMD_K6_2 (CPU_FEATURE_EX_3DNOW) +#define CPU_FEATURES_EX_AMD_K6_III (CPU_FEATURE_EX_3DNOW) +#define CPU_FEATURES_EX_AMD_K7_ATHLON (CPU_FEATURE_EX_3DNOW|CPU_FEATURE_EX_E3DNOW) +#define CPU_FEATURES_EX_AMD_K7_ATHLON_XP (CPU_FEATURE_EX_3DNOW|CPU_FEATURE_EX_E3DNOW) + +/*** ECX feature ***/ +#define CPU_FEATURE_ECX_SSE3 (1 << 0) +#define CPU_FEATURE_ECX_PCLMULDQ (1 << 1) +#define CPU_FEATURE_ECX_DTES64 (1 << 2) +#define CPU_FEATURE_ECX_MONITOR (1 << 3) +#define CPU_FEATURE_ECX_DSCPL (1 << 4) +#define CPU_FEATURE_ECX_VMX (1 << 5) +#define CPU_FEATURE_ECX_SMX (1 << 6) +#define CPU_FEATURE_ECX_EST (1 << 7) +#define CPU_FEATURE_ECX_TM2 (1 << 8) +#define CPU_FEATURE_ECX_SSSE3 (1 << 9) +#define CPU_FEATURE_ECX_CNXT1D (1 << 10) +/* (1 << 11) */ +/* (1 << 12) */ +#define CPU_FEATURE_ECX_CX16 (1 << 13) +#define CPU_FEATURE_ECX_xTPR (1 << 14) +#define CPU_FEATURE_ECX_PDCM (1 << 15) +/* (1 << 16) */ +/* (1 << 17) */ +#define CPU_FEATURE_ECX_DCA (1 << 18) +#define CPU_FEATURE_ECX_SSE4_1 (1 << 19) +#define CPU_FEATURE_ECX_SSE4_2 (1 << 20) +#define CPU_FEATURE_ECX_x2APIC (1 << 21) +#define CPU_FEATURE_ECX_MOVBE (1 << 22) +#define CPU_FEATURE_ECX_POPCNT (1 << 23) +/* (1 << 24) */ +#define CPU_FEATURE_ECX_AES (1 << 25) +#define CPU_FEATURE_ECX_XSAVE (1 << 26) +#define CPU_FEATURE_ECX_OSXSAVE (1 << 27) +/* (1 << 28) */ +/* (1 << 29) */ +/* (1 << 30) */ +/* (1 << 31) */ + +#if defined(USE_MMX)&&defined(USE_FPU)&&defined(USE_SSE)&&defined(USE_SSE2)&&defined(USE_SSE3) +#define CPU_FEATURE_ECX_SSE3_FLAG CPU_FEATURE_ECX_SSE3 +#else +#define CPU_FEATURE_ECX_SSE3_FLAG 0 +#endif + +/* 使用できる機能全部 */ +#define CPU_FEATURES_ECX_ALL (CPU_FEATURE_ECX_SSE3_FLAG) + +#define CPU_FEATURES_ECX_PENTIUM_4 (CPU_FEATURE_ECX_SSE3) +#define CPU_FEATURES_ECX_PENTIUM_M (0) +#define CPU_FEATURES_ECX_PENTIUM_III (0) +#define CPU_FEATURES_ECX_PENTIUM_II (0) +#define CPU_FEATURES_ECX_PENTIUM_PRO (0) +#define CPU_FEATURES_ECX_MMX_PENTIUM (0) +#define CPU_FEATURES_ECX_PENTIUM (0) +#define CPU_FEATURES_ECX_I486DX (0) +#define CPU_FEATURES_ECX_I486SX (0) +#define CPU_FEATURES_ECX_80386 (0) +#define CPU_FEATURES_ECX_80286 (0) + +#define CPU_FEATURES_ECX_AMD_K6_2 (0) +#define CPU_FEATURES_ECX_AMD_K6_III (0) +#define CPU_FEATURES_ECX_AMD_K7_ATHLON (0) +#define CPU_FEATURES_ECX_AMD_K7_ATHLON_XP (0) + + +/* EFLAGS MASK */ +#define CPU_EFLAGS_MASK_PENTIUM_4 (0) +#define CPU_EFLAGS_MASK_PENTIUM_M (0) +#define CPU_EFLAGS_MASK_PENTIUM_III (0) +#define CPU_EFLAGS_MASK_PENTIUM_II (0) +#define CPU_EFLAGS_MASK_PENTIUM_PRO (0) +#define CPU_EFLAGS_MASK_MMX_PENTIUM (0) +#define CPU_EFLAGS_MASK_PENTIUM (0) +#define CPU_EFLAGS_MASK_I486DX (0) +#define CPU_EFLAGS_MASK_I486SX (0) +#define CPU_EFLAGS_MASK_80386 ((1 << 18)) +#define CPU_EFLAGS_MASK_80286 ((1 << 18)) + +#define CPU_EFLAGS_MASK_AMD_K6_2 (0) +#define CPU_EFLAGS_MASK_AMD_K6_III (0) +#define CPU_EFLAGS_MASK_AMD_K7_ATHLON (0) +#define CPU_EFLAGS_MASK_AMD_K7_ATHLON_XP (0) + + +/* brand string */ +#define CPU_BRAND_STRING_PENTIUM_4 "Intel(R) Pentium(R) 4 CPU " +#define CPU_BRAND_STRING_PENTIUM_M "Intel(R) Pentium(R) M processor " +#define CPU_BRAND_STRING_PENTIUM_III "Intel(R) Pentium(R) III CPU " +#define CPU_BRAND_STRING_PENTIUM_II "Intel(R) Pentium(R) II CPU " +#define CPU_BRAND_STRING_PENTIUM_PRO "Intel(R) Pentium(R) Pro CPU " +#define CPU_BRAND_STRING_MMX_PENTIUM "Intel(R) Pentium(R) with MMX " +#define CPU_BRAND_STRING_PENTIUM "Intel(R) Pentium(R) Processor " +#define CPU_BRAND_STRING_I486DX "Intel(R) i486DX Processor " +#define CPU_BRAND_STRING_I486SX "Intel(R) i486SX Processor " +#define CPU_BRAND_STRING_80386 "Intel(R) 80386 Processor " +#define CPU_BRAND_STRING_80286 "Intel(R) 80286 Processor " +#define CPU_BRAND_STRING_AMD_K6_2 "AMD-K6(tm) 3D processor " +#define CPU_BRAND_STRING_AMD_K6_III "AMD-K6(tm) 3D+ Processor " +#define CPU_BRAND_STRING_AMD_K7_ATHLON "AMD-K7(tm) Processor " +#define CPU_BRAND_STRING_AMD_K7_ATHLON_XP "AMD Athlon(tm) XP " +#define CPU_BRAND_STRING_NEKOPRO "Neko Processor " // カスタム設定 +#define CPU_BRAND_STRING_NEKOPRO2 "Neko Processor II " // 全機能使用可能 + + +/* brand id */ +#define CPU_BRAND_ID_PENTIUM_4 0x9 +#define CPU_BRAND_ID_PENTIUM_M 0x16 +#define CPU_BRAND_ID_PENTIUM_III 0x2 +#define CPU_BRAND_ID_PENTIUM_II 0 +#define CPU_BRAND_ID_PENTIUM_PRO 0 +#define CPU_BRAND_ID_MMX_PENTIUM 0 +#define CPU_BRAND_ID_PENTIUM 0 +#define CPU_BRAND_ID_I486DX 0 +#define CPU_BRAND_ID_I486SX 0 +#define CPU_BRAND_ID_80386 0 +#define CPU_BRAND_ID_80286 0 +#define CPU_BRAND_ID_AMD_K6_2 0 +#define CPU_BRAND_ID_AMD_K6_III 0 +#define CPU_BRAND_ID_AMD_K7_ATHLON 0 +#define CPU_BRAND_ID_AMD_K7_ATHLON_XP 0 +#define CPU_BRAND_ID_NEKOPRO 0 // カスタム設定 +#define CPU_BRAND_ID_NEKOPRO2 0 // 全機能使用可能 + +#define CPU_BRAND_ID_AUTO 0xffffffff // BrandID自動設定(過去バージョンとの互換維持用) + +// CPUID デフォルト設定 +#if defined(USE_FPU) +#if defined(USE_SSE3) +#define CPU_FAMILY CPU_PENTIUM_III_FAMILY +#define CPU_MODEL CPU_PENTIUM_III_MODEL /* Pentium III */ +#define CPU_STEPPING CPU_PENTIUM_III_STEPPING +#define CPU_FEATURES CPU_FEATURES_PENTIUM_III +#define CPU_FEATURES_EX CPU_FEATURES_EX_PENTIUM_III +#define CPU_FEATURES_ECX CPU_FEATURES_ECX_PENTIUM_III +#define CPU_BRAND_STRING CPU_BRAND_STRING_PENTIUM_III +#define CPU_BRAND_ID CPU_BRAND_ID_PENTIUM_III +#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_PENTIUM_III +//#define CPU_FAMILY CPU_PENTIUM_4_FAMILY +//#define CPU_MODEL CPU_PENTIUM_4_MODEL /* Pentium 4 */ +//#define CPU_STEPPING CPU_PENTIUM_4_STEPPING +//#define CPU_FEATURES CPU_FEATURES_PENTIUM_4 +//#define CPU_FEATURES_EX CPU_FEATURES_EX_PENTIUM_4 +//#define CPU_FEATURES_ECX CPU_FEATURES_ECX_PENTIUM_4 +//#define CPU_BRAND_STRING CPU_BRAND_STRING_PENTIUM_4 +//#define CPU_BRAND_ID CPU_BRAND_ID_PENTIUM_4 +//#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_PENTIUM_4 +#elif defined(USE_SSE2) +#define CPU_FAMILY CPU_PENTIUM_III_FAMILY +#define CPU_MODEL CPU_PENTIUM_III_MODEL /* Pentium III */ +#define CPU_STEPPING CPU_PENTIUM_III_STEPPING +#define CPU_FEATURES CPU_FEATURES_PENTIUM_III +#define CPU_FEATURES_EX CPU_FEATURES_EX_PENTIUM_III +#define CPU_FEATURES_ECX CPU_FEATURES_ECX_PENTIUM_III +#define CPU_BRAND_STRING CPU_BRAND_STRING_PENTIUM_III +#define CPU_BRAND_ID CPU_BRAND_ID_PENTIUM_III +#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_PENTIUM_III +//#define CPU_FAMILY CPU_PENTIUM_M_FAMILY +//#define CPU_MODEL CPU_PENTIUM_M_MODEL /* Pentium M */ +//#define CPU_STEPPING CPU_PENTIUM_M_STEPPING +//#define CPU_FEATURES CPU_FEATURES_PENTIUM_M +//#define CPU_FEATURES_EX CPU_FEATURES_EX_PENTIUM_M +//#define CPU_FEATURES_ECX CPU_FEATURES_ECX_PENTIUM_M +//#define CPU_BRAND_STRING CPU_BRAND_STRING_PENTIUM_M +//#define CPU_BRAND_ID CPU_BRAND_ID_PENTIUM_M +//#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_PENTIUM_M +#elif defined(USE_SSE) +#define CPU_FAMILY CPU_PENTIUM_III_FAMILY +#define CPU_MODEL CPU_PENTIUM_III_MODEL /* Pentium III */ +#define CPU_STEPPING CPU_PENTIUM_III_STEPPING +#define CPU_FEATURES CPU_FEATURES_PENTIUM_III +#define CPU_FEATURES_EX CPU_FEATURES_EX_PENTIUM_III +#define CPU_FEATURES_ECX CPU_FEATURES_ECX_PENTIUM_III +#define CPU_BRAND_STRING CPU_BRAND_STRING_PENTIUM_III +#define CPU_BRAND_ID CPU_BRAND_ID_PENTIUM_III +#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_PENTIUM_III +#elif defined(USE_MMX) +#define CPU_FAMILY CPU_PENTIUM_II_FAMILY +#define CPU_MODEL CPU_PENTIUM_II_MODEL /* Pentium II */ +#define CPU_STEPPING CPU_PENTIUM_II_STEPPING +#define CPU_FEATURES CPU_FEATURES_PENTIUM_II +#define CPU_FEATURES_EX CPU_FEATURES_EX_PENTIUM_II +#define CPU_FEATURES_ECX CPU_FEATURES_ECX_PENTIUM_II +#define CPU_BRAND_STRING CPU_BRAND_STRING_PENTIUM_II +#define CPU_BRAND_ID CPU_BRAND_ID_PENTIUM_II +#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_PENTIUM_II +#else +#define CPU_FAMILY CPU_PENTIUM_FAMILY +#define CPU_MODEL CPU_PENTIUM_MODEL /* Pentium */ +#define CPU_STEPPING CPU_PENTIUM_STEPPING +#define CPU_FEATURES CPU_FEATURES_PENTIUM +#define CPU_FEATURES_EX CPU_FEATURES_EX_PENTIUM +#define CPU_FEATURES_ECX CPU_FEATURES_ECX_PENTIUM +#define CPU_BRAND_STRING CPU_BRAND_STRING_PENTIUM +#define CPU_BRAND_ID CPU_BRAND_ID_PENTIUM +#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_PENTIUM +#endif +#else +#define CPU_FAMILY CPU_I486SX_FAMILY +#define CPU_MODEL CPU_I486SX_MODEL /* 486SX */ +#define CPU_STEPPING CPU_I486SX_STEPPING +#define CPU_FEATURES CPU_FEATURES_I486SX +#define CPU_FEATURES_EX CPU_FEATURES_EX_I486SX +#define CPU_FEATURES_ECX CPU_FEATURES_ECX_I486SX +#define CPU_BRAND_STRING CPU_BRAND_STRING_I486SX +#define CPU_BRAND_ID CPU_BRAND_ID_I486SX +#define CPU_EFLAGS_MASK CPU_EFLAGS_MASK_I486SX +#endif + + + +#define CPU_REGS_BYTEL(n) CPU_STATSAVE.cpu_regs.reg[(n)].b.l +#define CPU_REGS_BYTEH(n) CPU_STATSAVE.cpu_regs.reg[(n)].b.h +#define CPU_REGS_WORD(n) CPU_STATSAVE.cpu_regs.reg[(n)].w.w +#define CPU_REGS_DWORD(n) CPU_STATSAVE.cpu_regs.reg[(n)].d +#define CPU_REGS_SREG(n) CPU_STATSAVE.cpu_regs.sreg[(n)] + +#define CPU_STAT_SREG(n) CPU_STATSAVE.cpu_stat.sreg[(n)] +#define CPU_STAT_SREGBASE(n) CPU_STAT_SREG((n)).u.seg.segbase +#define CPU_STAT_SREGLIMIT(n) CPU_STAT_SREG((n)).u.seg.limit + + +#define CPU_AL CPU_REGS_BYTEL(CPU_EAX_INDEX) +#define CPU_CL CPU_REGS_BYTEL(CPU_ECX_INDEX) +#define CPU_DL CPU_REGS_BYTEL(CPU_EDX_INDEX) +#define CPU_BL CPU_REGS_BYTEL(CPU_EBX_INDEX) +#define CPU_AH CPU_REGS_BYTEH(CPU_EAX_INDEX) +#define CPU_CH CPU_REGS_BYTEH(CPU_ECX_INDEX) +#define CPU_DH CPU_REGS_BYTEH(CPU_EDX_INDEX) +#define CPU_BH CPU_REGS_BYTEH(CPU_EBX_INDEX) + +#define CPU_AX CPU_REGS_WORD(CPU_EAX_INDEX) +#define CPU_CX CPU_REGS_WORD(CPU_ECX_INDEX) +#define CPU_DX CPU_REGS_WORD(CPU_EDX_INDEX) +#define CPU_BX CPU_REGS_WORD(CPU_EBX_INDEX) +#define CPU_SP CPU_REGS_WORD(CPU_ESP_INDEX) +#define CPU_BP CPU_REGS_WORD(CPU_EBP_INDEX) +#define CPU_SI CPU_REGS_WORD(CPU_ESI_INDEX) +#define CPU_DI CPU_REGS_WORD(CPU_EDI_INDEX) +#define CPU_IP CPU_STATSAVE.cpu_regs.eip.w.w + +#define CPU_EAX CPU_REGS_DWORD(CPU_EAX_INDEX) +#define CPU_ECX CPU_REGS_DWORD(CPU_ECX_INDEX) +#define CPU_EDX CPU_REGS_DWORD(CPU_EDX_INDEX) +#define CPU_EBX CPU_REGS_DWORD(CPU_EBX_INDEX) +#define CPU_ESP CPU_REGS_DWORD(CPU_ESP_INDEX) +#define CPU_EBP CPU_REGS_DWORD(CPU_EBP_INDEX) +#define CPU_ESI CPU_REGS_DWORD(CPU_ESI_INDEX) +#define CPU_EDI CPU_REGS_DWORD(CPU_EDI_INDEX) +#define CPU_EIP CPU_STATSAVE.cpu_regs.eip.d +#define CPU_PREV_EIP CPU_STATSAVE.cpu_regs.prev_eip.d +#define CPU_PREV_ESP CPU_STATSAVE.cpu_regs.prev_esp.d + +#define CPU_ES CPU_REGS_SREG(CPU_ES_INDEX) +#define CPU_CS CPU_REGS_SREG(CPU_CS_INDEX) +#define CPU_SS CPU_REGS_SREG(CPU_SS_INDEX) +#define CPU_DS CPU_REGS_SREG(CPU_DS_INDEX) +#define CPU_FS CPU_REGS_SREG(CPU_FS_INDEX) +#define CPU_GS CPU_REGS_SREG(CPU_GS_INDEX) + +#define CPU_ES_DESC CPU_STAT_SREG(CPU_ES_INDEX) +#define CPU_CS_DESC CPU_STAT_SREG(CPU_CS_INDEX) +#define CPU_SS_DESC CPU_STAT_SREG(CPU_SS_INDEX) +#define CPU_DS_DESC CPU_STAT_SREG(CPU_DS_INDEX) +#define CPU_FS_DESC CPU_STAT_SREG(CPU_FS_INDEX) +#define CPU_GS_DESC CPU_STAT_SREG(CPU_GS_INDEX) + +#define ES_BASE CPU_STAT_SREGBASE(CPU_ES_INDEX) +#define CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) +#define SS_BASE CPU_STAT_SREGBASE(CPU_SS_INDEX) +#define DS_BASE CPU_STAT_SREGBASE(CPU_DS_INDEX) +#define FS_BASE CPU_STAT_SREGBASE(CPU_FS_INDEX) +#define GS_BASE CPU_STAT_SREGBASE(CPU_GS_INDEX) + +#define CPU_EFLAG CPU_STATSAVE.cpu_regs.eflags.d +#define CPU_FLAG CPU_STATSAVE.cpu_regs.eflags.w.w +#define CPU_FLAGL CPU_STATSAVE.cpu_regs.eflags.b.l +#define CPU_FLAGH CPU_STATSAVE.cpu_regs.eflags.b.h +#define CPU_TRAP CPU_STATSAVE.cpu_stat.trap +#define CPU_INPORT CPU_STATSAVE.cpu_stat.inport +#define CPU_OV CPU_STATSAVE.cpu_stat.ovflag + +#define C_FLAG (1 << 0) +#define P_FLAG (1 << 2) +#define A_FLAG (1 << 4) +#define Z_FLAG (1 << 6) +#define S_FLAG (1 << 7) +#define T_FLAG (1 << 8) +#define I_FLAG (1 << 9) +#define D_FLAG (1 << 10) +#define O_FLAG (1 << 11) +#define IOPL_FLAG (3 << 12) +#define NT_FLAG (1 << 14) +#define RF_FLAG (1 << 16) +#define VM_FLAG (1 << 17) +#define AC_FLAG (1 << 18) +#define VIF_FLAG (1 << 19) +#define VIP_FLAG (1 << 20) +#define ID_FLAG (1 << 21) +#define SZP_FLAG (P_FLAG|Z_FLAG|S_FLAG) +#define SZAP_FLAG (P_FLAG|A_FLAG|Z_FLAG|S_FLAG) +#define SZPC_FLAG (C_FLAG|P_FLAG|Z_FLAG|S_FLAG) +#define SZAPC_FLAG (C_FLAG|P_FLAG|A_FLAG|Z_FLAG|S_FLAG) +#define ALL_FLAG (SZAPC_FLAG|T_FLAG|I_FLAG|D_FLAG|O_FLAG|IOPL_FLAG|NT_FLAG) +#define ALL_EFLAG (ALL_FLAG|RF_FLAG|VM_FLAG|AC_FLAG|VIF_FLAG|VIP_FLAG|ID_FLAG) + +#define REAL_FLAGREG ((CPU_FLAG & 0xf7ff) | (CPU_OV ? O_FLAG : 0) | 2) +#define REAL_EFLAGREG ((CPU_EFLAG & 0xfffff7ff) | (CPU_OV ? O_FLAG : 0) | 2) + +void CPUCALL set_flags(UINT16 new_flags, UINT16 mask); +void CPUCALL set_eflags(UINT32 new_flags, UINT32 mask); + +#define CPU_INST_OP32 CPU_STATSAVE.cpu_inst.op_32 +#define CPU_INST_AS32 CPU_STATSAVE.cpu_inst.as_32 +#define CPU_INST_REPUSE CPU_STATSAVE.cpu_inst.rep_used +#define CPU_INST_SEGUSE CPU_STATSAVE.cpu_inst.seg_used +#define CPU_INST_SEGREG_INDEX CPU_STATSAVE.cpu_inst.seg_base +#define DS_FIX (!CPU_INST_SEGUSE ? CPU_DS_INDEX : CPU_INST_SEGREG_INDEX) +#define SS_FIX (!CPU_INST_SEGUSE ? CPU_SS_INDEX : CPU_INST_SEGREG_INDEX) + +#define CPU_STAT_CS_BASE CPU_STAT_SREGBASE(CPU_CS_INDEX) +#define CPU_STAT_CS_LIMIT CPU_STAT_SREGLIMIT(CPU_CS_INDEX) + +#define CPU_STAT_ADRSMASK CPU_STATSAVE.cpu_stat.adrsmask +#define CPU_STAT_SS32 CPU_STATSAVE.cpu_stat.ss_32 +#define CPU_STAT_RESETREQ CPU_STATSAVE.cpu_stat.resetreq +#define CPU_STAT_PM CPU_STATSAVE.cpu_stat.protected_mode +#define CPU_STAT_PAGING CPU_STATSAVE.cpu_stat.paging +#define CPU_STAT_VM86 CPU_STATSAVE.cpu_stat.vm86 +#define CPU_STAT_WP CPU_STATSAVE.cpu_stat.page_wp +#define CPU_STAT_CPL CPU_CS_DESC.rpl +#define CPU_STAT_USER_MODE CPU_STATSAVE.cpu_stat.user_mode +#define CPU_STAT_PDE_BASE CPU_STATSAVE.cpu_stat.pde_base +#define CPU_SET_PREV_ESP1(esp) \ +do { \ + CPU_STATSAVE.cpu_stat.backout_sp = 1; \ + CPU_PREV_ESP = (esp); \ +} while (/*CONSTCOND*/0) +#define CPU_SET_PREV_ESP() CPU_SET_PREV_ESP1(CPU_ESP) +#define CPU_CLEAR_PREV_ESP() \ +do { \ + CPU_STATSAVE.cpu_stat.backout_sp = 0; \ +} while (/*CONSTCOND*/0) + +#define CPU_STAT_HLT CPU_STATSAVE.cpu_stat.hlt + +#define CPU_STAT_IOPL ((CPU_EFLAG & IOPL_FLAG) >> 12) +#define CPU_IOPL0 0 +#define CPU_IOPL1 1 +#define CPU_IOPL2 2 +#define CPU_IOPL3 3 + +#define CPU_STAT_IOADDR CPU_STATSAVE.cpu_stat.ioaddr +#define CPU_STAT_IOLIMIT CPU_STATSAVE.cpu_stat.iolimit + +#define CPU_STAT_PREV_EXCEPTION CPU_STATSAVE.cpu_stat.prev_exception +#define CPU_STAT_EXCEPTION_COUNTER CPU_STATSAVE.cpu_stat.nerror +#define CPU_STAT_EXCEPTION_COUNTER_INC() CPU_STATSAVE.cpu_stat.nerror++ +#define CPU_STAT_EXCEPTION_COUNTER_CLEAR() CPU_STATSAVE.cpu_stat.nerror = 0 + +#define CPU_MODE_SUPERVISER 0 +#define CPU_MODE_USER (1 << 3) + +#if defined(SUPPORT_IA32_HAXM) +#define CPU_CLI \ +do { \ + CPU_FLAG &= ~I_FLAG; \ + CPU_TRAP = 0; \ + np2haxstat.update_regs = 1; \ +} while (/*CONSTCOND*/0) + +#define CPU_STI \ +do { \ + CPU_FLAG |= I_FLAG; \ + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG) ; \ + np2haxstat.update_regs = 1; \ +} while (/*CONSTCOND*/0) + +#else +#define CPU_CLI \ +do { \ + CPU_FLAG &= ~I_FLAG; \ + CPU_TRAP = 0; \ +} while (/*CONSTCOND*/0) + +#define CPU_STI \ +do { \ + CPU_FLAG |= I_FLAG; \ + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG) ; \ +} while (/*CONSTCOND*/0) +#endif + +#define CPU_GDTR_LIMIT CPU_STATSAVE.cpu_sysregs.gdtr_limit +#define CPU_GDTR_BASE CPU_STATSAVE.cpu_sysregs.gdtr_base +#define CPU_IDTR_LIMIT CPU_STATSAVE.cpu_sysregs.idtr_limit +#define CPU_IDTR_BASE CPU_STATSAVE.cpu_sysregs.idtr_base +#define CPU_LDTR CPU_STATSAVE.cpu_sysregs.ldtr +#define CPU_LDTR_DESC CPU_STATSAVE.cpu_stat.ldtr +#define CPU_LDTR_BASE CPU_LDTR_DESC.u.seg.segbase +#define CPU_LDTR_LIMIT CPU_LDTR_DESC.u.seg.limit +#define CPU_TR CPU_STATSAVE.cpu_sysregs.tr +#define CPU_TR_DESC CPU_STATSAVE.cpu_stat.tr +#define CPU_TR_BASE CPU_TR_DESC.u.seg.segbase +#define CPU_TR_LIMIT CPU_TR_DESC.u.seg.limit + +/* + * control register + */ +#define CPU_MSW CPU_STATSAVE.cpu_sysregs.cr0 + +#define CPU_CR0 CPU_STATSAVE.cpu_sysregs.cr0 +#define CPU_CR1 CPU_STATSAVE.cpu_sysregs.cr1 +#define CPU_CR2 CPU_STATSAVE.cpu_sysregs.cr2 +#define CPU_CR3 CPU_STATSAVE.cpu_sysregs.cr3 +#define CPU_CR4 CPU_STATSAVE.cpu_sysregs.cr4 +#define CPU_MXCSR CPU_STATSAVE.cpu_sysregs.mxcsr + +#define CPU_MSR_TSC CPU_STATSAVE.cpu_tsc + +#define CPU_CR0_PE (1 << 0) +#define CPU_CR0_MP (1 << 1) +#define CPU_CR0_EM (1 << 2) +#define CPU_CR0_TS (1 << 3) +#define CPU_CR0_ET (1 << 4) +#define CPU_CR0_NE (1 << 5) +#define CPU_CR0_WP (1 << 16) +#define CPU_CR0_AM (1 << 18) +#define CPU_CR0_NW (1 << 29) +#define CPU_CR0_CD (1 << 30) +#define CPU_CR0_PG (1 << 31) +#define CPU_CR0_ALL (CPU_CR0_PE|CPU_CR0_MP|CPU_CR0_EM|CPU_CR0_TS|CPU_CR0_ET|CPU_CR0_NE|CPU_CR0_WP|CPU_CR0_AM|CPU_CR0_NW|CPU_CR0_CD|CPU_CR0_PG) + +#define CPU_CR3_PD_MASK 0xfffff000 +#define CPU_CR3_PWT (1 << 3) +#define CPU_CR3_PCD (1 << 4) +#define CPU_CR3_MASK (CPU_CR3_PD_MASK|CPU_CR3_PWT|CPU_CR3_PCD) + +#define CPU_CR4_VME (1 << 0) +#define CPU_CR4_PVI (1 << 1) +#define CPU_CR4_TSD (1 << 2) +#define CPU_CR4_DE (1 << 3) +#define CPU_CR4_PSE (1 << 4) +#define CPU_CR4_PAE (1 << 5) +#define CPU_CR4_MCE (1 << 6) +#define CPU_CR4_PGE (1 << 7) +#define CPU_CR4_PCE (1 << 8) +#define CPU_CR4_OSFXSR (1 << 9) +#define CPU_CR4_OSXMMEXCPT (1 << 10) + +/* + * debug register + */ +#define CPU_DR(r) CPU_STATSAVE.cpu_regs.dr[(r)] +#define CPU_DR6 CPU_DR(6) +#define CPU_DR7 CPU_DR(7) + +#define CPU_STAT_BP CPU_STATSAVE.cpu_stat.bp +#define CPU_STAT_BP_EVENT CPU_STATSAVE.cpu_stat.bp_ev +#define CPU_STAT_BP_EVENT_B(r) (1 << (r)) +#define CPU_STAT_BP_EVENT_DR (1 << 4) /* fault */ +#define CPU_STAT_BP_EVENT_STEP (1 << 5) /* as CPU_TRAP */ +#define CPU_STAT_BP_EVENT_TASK (1 << 6) +#define CPU_STAT_BP_EVENT_RF (1 << 7) /* RF_FLAG */ + +#define CPU_DR6_B(r) (1 << (r)) +#define CPU_DR6_BD (1 << 13) +#define CPU_DR6_BS (1 << 14) +#define CPU_DR6_BT (1 << 15) + +#define CPU_DR7_L(r) (1 << ((r) * 2)) +#define CPU_DR7_G(r) (1 << ((r) * 2 + 1)) +#define CPU_DR7_LE (1 << 8) +#define CPU_DR7_GE (1 << 9) +#define CPU_DR7_GD (1 << 13) +#define CPU_DR7_RW(r) (3 << ((r) * 4 + 16)) +#define CPU_DR7_LEN(r) (3 << ((r) * 4 + 16 + 2)) + +#define CPU_DR7_GET_RW(r) ((CPU_DR7) >> (16 + (r) * 4)) +#define CPU_DR7_RW_CODE 0 +#define CPU_DR7_RW_RO 1 +#define CPU_DR7_RW_IO 2 +#define CPU_DR7_RW_RW 3 + +#define CPU_DR7_GET_LEN(r) ((CPU_DR7) >> (16 + 2 + (r) * 4)) + +void ia32_init(void); +void ia32_initreg(void); +//void ia32_setextsize(UINT32 size); +//void ia32_setemm(UINT frame, UINT32 addr); + +void ia32reset(void); +void ia32shut(void); +void ia32a20enable(BOOL enable); +void ia32(void); +void ia32_step(void); +void CPUCALL ia32_interrupt(int vect, int soft); + +void exec_1step(void); +//void exec_allstep(void); +#define INST_PREFIX (1 << 0) +#define INST_STRING (1 << 1) +#define REP_CHECKZF (1 << 7) + +void ia32_printf(const char *buf, ...); +void ia32_warning(const char *buf, ...); +void ia32_panic(const char *buf, ...); + +//void ia32_bioscall(void); + +void CPUCALL change_pm(BOOL onoff); +void CPUCALL change_vm(BOOL onoff); +void CPUCALL change_pg(BOOL onoff); + +void CPUCALL set_cr3(UINT32 new_cr3); +void CPUCALL set_cpl(int new_cpl); + +extern const UINT8 iflags[]; +#define szpcflag iflags +extern UINT8 szpflag_w[0x10000]; + +extern UINT8 *reg8_b20[0x100]; +extern UINT8 *reg8_b53[0x100]; +extern UINT16 *reg16_b20[0x100]; +extern UINT16 *reg16_b53[0x100]; +extern UINT32 *reg32_b20[0x100]; +extern UINT32 *reg32_b53[0x100]; + +extern const char *reg8_str[CPU_REG_NUM]; +extern const char *reg16_str[CPU_REG_NUM]; +extern const char *reg32_str[CPU_REG_NUM]; +extern const char *sreg_str[CPU_SEGREG_NUM]; + +char *cpu_reg2str(void); +#if defined(USE_FPU) +char *fpu_reg2str(void); +#endif +void put_cpuinfo(void); +void dbg_printf(const char *str, ...); + + +/* + * FPU + */ +#define FPU_REGS CPU_STATSAVE.fpu_regs +#define FPU_CTRLWORD FPU_REGS.control +#define FPU_CTRLWORDMASK FPU_REGS.cw_mask_all +#define FPU_STATUSWORD FPU_REGS.status +#define FPU_INSTPTR FPU_REGS.inst +#define FPU_DATAPTR FPU_REGS.data +#define FPU_LASTINSTOP FPU_REGS.op +#define FPU_INSTPTR_OFFSET FPU_REGS.inst.offset +#define FPU_INSTPTR_SEG FPU_REGS.inst.seg +#define FPU_DATAPTR_OFFSET FPU_REGS.data.offset +#define FPU_DATAPTR_SEG FPU_REGS.data.seg + +#define FPU_STAT CPU_STATSAVE.fpu_stat +#define FPU_STAT_TOP FPU_STAT.top +#define FPU_STAT_PC FPU_STAT.pc +#define FPU_STAT_RC FPU_STAT.rc + +/* + * SSE + */ +#ifdef USE_SSE +#define SSE_MXCSR CPU_MXCSR +#define SSE_XMMREG(i) FPU_STAT.xmm_reg[i] +#endif + +#if 0 +#define FPU_ST(i) FPU_STAT.reg[((i) + FPU_STAT_TOP) & 7] +#else +#define FPU_ST(i) ((FPU_STAT_TOP+ (i) ) & 7) +#endif +#define FPU_REG(i) FPU_STAT.reg[i] + +/* FPU status register */ +#define FP_IE_FLAG (1 << 0) /* 無効な動作 */ +#define FP_DE_FLAG (1 << 1) /* デノーマライズド・オペランド */ +#define FP_ZE_FLAG (1 << 2) /* ゼロによる除算 */ +#define FP_OE_FLAG (1 << 3) /* オーバーフロー */ +#define FP_UE_FLAG (1 << 4) /* アンダーフロー */ +#define FP_PE_FLAG (1 << 5) /* 精度 */ +#define FP_SF_FLAG (1 << 6) /* スタックフォルト */ +#define FP_ES_FLAG (1 << 7) /* エラーサマリステータス */ +#define FP_C0_FLAG (1 << 8) /* 条件コード */ +#define FP_C1_FLAG (1 << 9) /* 条件コード */ +#define FP_C2_FLAG (1 << 10) /* 条件コード */ +#define FP_TOP_FLAG (7 << 11) /* スタックポイントのトップ */ +#define FP_C3_FLAG (1 << 14) /* 条件コード */ +#define FP_B_FLAG (1 << 15) /* FPU ビジー */ + +#define FP_TOP_SHIFT 11 +#define FP_TOP_GET() ((FPU_STATUSWORD & FP_TOP_FLAG) >> FP_TOP_SHIFT) +#define FP_TOP_SET(v) ((FPU_STATUSWORD & ~FP_TOP_FLAG) | ((v) << FP_TOP_SHIFT)) + +#define FPU_STAT_TOP_INC() \ +do { \ + FPU_STAT.top = (FPU_STAT.top + 1) & 7; \ +} while (/*CONSTCOND*/0) +#define FPU_STAT_TOP_DEC() \ +do { \ + FPU_STAT.top = (FPU_STAT.top - 1) & 7; \ +} while (/*CONSTCOND*/0) + +/* FPU control register */ +#define FP_CTRL_PC_SHIFT 8 /* 精度制御 */ +#define FP_CTRL_RC_SHIFT 10 /* 丸め制御 */ + +#define FP_CTRL_PC_24 0 /* 単精度 */ +#define FP_CTRL_PC_53 1 /* 倍精度 */ +#define FP_CTRL_PC_64 3 /* 拡張精度 */ + +#define FP_CTRL_RC_NEAREST_EVEN 0 +#define FP_CTRL_RC_DOWN 1 +#define FP_CTRL_RC_UP 2 +#define FP_CTRL_RC_TO_ZERO 3 + + +/* + * Misc. + */ +void memory_dump(int idx, UINT32 madr); +void gdtr_dump(UINT32 base, UINT limit); +void idtr_dump(UINT32 base, UINT limit); +void ldtr_dump(UINT32 base, UINT limit); +void tr_dump(UINT16 selector, UINT32 base, UINT limit); +UINT32 pde_dump(UINT32 base, int idx); +void segdesc_dump(descriptor_t *sdp); +UINT32 convert_laddr_to_paddr(UINT32 laddr); +UINT32 convert_vaddr_to_paddr(unsigned int idx, UINT32 offset); + +/* + * disasm + */ +/* context */ +typedef struct { + UINT32 val; + + UINT32 eip; + BOOL op32; + BOOL as32; + + UINT32 baseaddr; + UINT8 opcode[3]; + UINT8 modrm; + UINT8 sib; + + BOOL useseg; + int seg; + + UINT8 opbyte[32]; + int nopbytes; + + char str[256]; + size_t remain; + + char *next; + char *prefix; + char *op; + char *arg[3]; + int narg; + + char pad; +} disasm_context_t; + +int disasm(UINT32 *eip, disasm_context_t *ctx); +char *cpu_disasm2str(UINT32 eip); + +//#ifdef __cplusplus +//} +//#endif + +#include "cpu_io.h" +#include "cpu_mem.h" +#include "exception.h" +#include "paging.h" +#include "resolve.h" +#include "task.h" + +#endif /* !IA32_CPU_CPU_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/cpu_io.cpp b/source/src/vm/np21/i386c/ia32/cpu_io.cpp new file mode 100644 index 000000000..397657ff6 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpu_io.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" + +#include "cpu.h" +//#include "pccore.h" +//#include "iocore.h" +#include "../cpumem.h" + + +static __inline__ void CPUCALL check_io(UINT port, UINT len); + +static __inline__ void CPUCALL +check_io(UINT port, UINT len) +{ + UINT off; + UINT16 map; + UINT16 mask; + + if (CPU_STAT_IOLIMIT == 0) { + VERBOSE(("check_io: CPU_STAT_IOLIMIT == 0 (port = %04x, len = %d)", port, len)); + EXCEPTION(GP_EXCEPTION, 0); + } + + if ((port + len) / 8 >= CPU_STAT_IOLIMIT) { + VERBOSE(("check_io: out of range: CPU_STAT_IOLIMIT(%08x) (port = %04x, len = %d)", CPU_STAT_IOLIMIT, port, len)); + EXCEPTION(GP_EXCEPTION, 0); + } + + off = port / 8; + mask = ((1 << len) - 1) << (port % 8); + map = cpu_kmemoryread_w(CPU_STAT_IOADDR + off); + if (map & mask) { + VERBOSE(("check_io: (bitmap(0x%04x) & bit(0x%04x)) != 0 (CPU_STAT_IOADDR=0x%08x, offset=0x%04x, port = 0x%04x, len = %d)", map, mask, CPU_STAT_IOADDR, off, port, len)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + +UINT8 IOINPCALL +cpu_in(UINT port) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 1); + } + return iocore_inp8(port); +} + +UINT16 IOINPCALL +cpu_in_w(UINT port) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 2); + } + return iocore_inp16(port); +} + +UINT32 IOINPCALL +cpu_in_d(UINT port) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 4); + } + return iocore_inp32(port); +} + +void IOOUTCALL +cpu_out(UINT port, UINT8 data) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 1); + } + iocore_out8(port, data); +} + +void IOOUTCALL +cpu_out_w(UINT port, UINT16 data) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 2); + } + iocore_out16(port, data); +} + +void IOOUTCALL +cpu_out_d(UINT port, UINT32 data) +{ + + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL > CPU_STAT_IOPL))) { + check_io(port, 4); + } + iocore_out32(port, data); +} + diff --git a/source/src/vm/np21/i386c/ia32/cpu_io.h b/source/src/vm/np21/i386c/ia32/cpu_io.h new file mode 100644 index 000000000..a2e49aaa2 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpu_io.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_CPU_IO_H__ +#define IA32_CPU_CPU_IO_H__ + +#include "interface.h" + +//#ifdef __cplusplus +//extern "C" { +//#endif + +UINT8 IOINPCALL cpu_in(UINT port); +UINT16 IOINPCALL cpu_in_w(UINT port); +UINT32 IOINPCALL cpu_in_d(UINT port); +void IOOUTCALL cpu_out(UINT port, UINT8 val); +void IOOUTCALL cpu_out_w(UINT port, UINT16 val); +void IOOUTCALL cpu_out_d(UINT port, UINT32 val); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* !IA32_CPU_CPU_IO_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/cpu_mem.cpp b/source/src/vm/np21/i386c/ia32/cpu_mem.cpp new file mode 100644 index 000000000..64d0d7697 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpu_mem.cpp @@ -0,0 +1,569 @@ +/* + * Copyright (c) 2002-2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cpu.h" +#include "../cpumem.h" +#if 0 +/* + * memory access check + */ +static __inline__ int MEMCALL check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len, BOOL is32bit); +static __inline__ void MEMCALL cpu_memoryread_check(descriptor_t *sdp, UINT32 offset, UINT len, int e); +static __inline__ void MEMCALL cpu_memorywrite_check(descriptor_t *sdp, UINT32 offset, UINT len, int e); + +static __inline__ int MEMCALL +check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len, BOOL is32bit) +{ + UINT32 limit; + UINT32 end; + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + len--; + end = offset + len; + + if (SEG_IS_DATA(sdp) && SEG_IS_EXPANDDOWN_DATA(sdp)) { + /* expand-down data segment */ + limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; + if (sdp->u.seg.limit == 0) { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | | + * | | + [1] + 0000FFFFh + * | valid | | | + * | | +-------+ 0000FFFFh - len -1 + * | | | valid | + * +-------+ +-------+ 00000000h + */ + if (!SEG_IS_32BIT(sdp)) { + if ((len > limit) /* len check */ + || (end > limit)) { /* [1] */ + goto exc; + } + } else { + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } + } else { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | [2] | | | + * +-------+ +.......+ FFFFFFFFh - len - 1 + * | | | [2] | + * | | +.......+ 0000FFFFh + * | valid | | | + * | | +-------+ 0000FFFFh - len - 1 + * | | | valid | + * +-------+ +-------+ seg.limit + * | [1] | | [1] | + * +-------+ +-------+ 00000000h + */ + if ((len > limit - sdp->u.seg.limit) /* len check */ + || (end < offset) /* wrap check */ + || (offset < sdp->u.seg.limit) /* [1] */ + || (end > limit)) { /* [2] */ + goto exc; + } + } + } else { + /* expand-up data or code segment */ + if (sdp->u.seg.limit == 0xffffffff) { + /* + * 16/32bit + * +-------+ FFFFFFFFh + * | | + * | | + * | valid | + * | | + * | | + * +-------+ 00000000h + */ + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } else { + /* + * 16/32bit + * +-------+ FFFFFFFFh + * | | + * | | + * | [1] | + * +.......+ seg.limit + * | | + * +-------+ seg.limit - len - 1 + * | valid | + * +-------+ 00000000h + */ + if ((len > sdp->u.seg.limit) /* len check */ + || (end < offset) /* wrap check */ + || (end > sdp->u.seg.limit + 1)) { /* [1] */ + goto exc; + } + } + } + return 1; /* Ok! */ + +exc: + VERBOSE(("check_limit_upstairs: check failure: offset = 0x%08x, len = %d", offset, len + 1)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + return 0; +} + +static __inline__ void MEMCALL +cpu_memoryread_check(descriptor_t *sdp, UINT32 offset, UINT len, int e) +{ + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + if (!SEG_IS_VALID(sdp)) { + e = GP_EXCEPTION; + goto exc; + } + if (!SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || (SEG_IS_CODE(sdp) && !SEG_IS_READABLE_CODE(sdp))) { + goto exc; + } + + switch (sdp->type) { + case 0: case 1: /* ro */ + case 2: case 3: /* rw */ + case 4: case 5: /* ro (expand down) */ + case 6: case 7: /* rw (expand down) */ + case 10: case 11: /* rx */ + case 14: case 15: /* rxc */ + if (!check_limit_upstairs(sdp, offset, len, SEG_IS_32BIT(sdp))) + goto exc; + break; + + default: + goto exc; + } + sdp->flag |= CPU_DESC_FLAG_READABLE; + return; + +exc: + VERBOSE(("cpu_memoryread_check: check failure: offset = 0x%08x, len = %d", offset, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(e, 0); +} + +static __inline__ void MEMCALL +cpu_memorywrite_check(descriptor_t *sdp, UINT32 offset, UINT len, int e) +{ + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + if (!SEG_IS_VALID(sdp)) { + e = GP_EXCEPTION; + goto exc; + } + if (!SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || SEG_IS_CODE(sdp) + || (SEG_IS_DATA(sdp) && !SEG_IS_WRITABLE_DATA(sdp))) { + goto exc; + } + + switch (sdp->type) { + case 2: case 3: /* rw */ + case 6: case 7: /* rw (expand down) */ + if (!check_limit_upstairs(sdp, offset, len, SEG_IS_32BIT(sdp))) + goto exc; + break; + + default: + goto exc; + } + sdp->flag |= CPU_DESC_FLAG_WRITABLE | CPU_DESC_FLAG_READABLE; + return; + +exc: + VERBOSE(("cpu_memorywrite_check: check failure: offset = 0x%08x, len = %d", offset, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(e, 0); +} +#endif +#if 0 +void MEMCALL +cpu_stack_push_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, + BOOL is32bit) +{ + UINT32 limit; + UINT32 start; + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + len--; + + if (!SEG_IS_VALID(sdp) + || !SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || SEG_IS_CODE(sdp) + || !SEG_IS_WRITABLE_DATA(sdp)) { + goto exc; + } + + //start = sp - len; + //limit = is32bit ? 0xffffffff : 0x0000ffff; + limit = is32bit ? 0xffffffff : 0x0000ffff; + sp = (sp - 1) & limit; + start = (sp - len) & limit; + + + if (SEG_IS_EXPANDDOWN_DATA(sdp)) { + /* expand-down stack */ + if (!SEG_IS_32BIT(sdp)) { + if (sp > limit) { /* [*] */ + goto exc; + } + } + if (sdp->u.seg.limit == 0) { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | [*] | + * | | +-------+ 0000FFFFh + * | valid | | | + * | | | valid | + * | | | | + * +-------+ +-------+ 00000000h + */ + if (!SEG_IS_32BIT(sdp)) { + if (sp > limit) { /* [1] */ + goto exc; + } + } else { + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } + } else { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | [*] | + * | valid | +-------+ 0000FFFFh + * | | | valid | + * +-------+ +-------+ seg.limit + len - 1 + * | | | | + * +..[1]..+ +..[1]..+ seg.limit + * | | | | + * +-------+ +-------+ 00000000h + */ + if ((len > limit - sdp->u.seg.limit) /* len check */ + || (start > sp) /* wrap check */ + || (start < sdp->u.seg.limit)) { /* [1] */ + goto exc; + } + } + } else { + /* expand-up stack */ + if (sdp->u.seg.limit == limit) { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | [1] | + * | | +-------+ 0000FFFFh + * | valid | | | + * | | | valid | + * | | | | + * +-------+ +-------+ 00000000h + */ + if (!SEG_IS_32BIT(sdp)) { + if (sp > limit) { /* [1] */ + goto exc; + } + } else { + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } + } else { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | | + * | [1] | + [1] + 0000FFFFh + * | | | | + * +-------+ +-------+ seg.limit + * | valid | | valid | + * +.......+ +.......+ len - 1 + * | [+] | | [+] | + * +-------+ +-------+ 00000000h + * + * [+]: wrap check + */ + if ((len > sdp->u.seg.limit) /* len check */ + || (start > sp) /* wrap check */ + || (sp > sdp->u.seg.limit + 1)) { /* [1] */ + goto exc; + } + } + } + return; + +exc: + VERBOSE(("cpu_stack_push_check: check failure: selector = 0x%04x, sp = 0x%08x, len = %d", s, sp, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(SS_EXCEPTION, s & 0xfffc); +} + +void MEMCALL +cpu_stack_pop_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, + BOOL is32bit) +{ + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + if (!SEG_IS_VALID(sdp) + || !SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || SEG_IS_CODE(sdp) + || !SEG_IS_WRITABLE_DATA(sdp)) { + goto exc; + } + + if (!check_limit_upstairs(sdp, sp, len, is32bit)) + goto exc; + return; + +exc: + VERBOSE(("cpu_stack_pop_check: check failure: selector = 0x%04x, sp = 0x%08x, len = %d", s, sp, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(SS_EXCEPTION, s & 0xfffc); +} +#endif + + +/* + * additional physical address memory access functions + */ +UINT64 MEMCALL +cpu_memoryread_q(UINT32 paddr) +{ + UINT64 value; + + value = cpu_memoryread_d(paddr); + value += (UINT64)cpu_memoryread_d(paddr + 4) << 32; + + return value; +} + +void MEMCALL +cpu_memorywrite_q(UINT32 paddr, UINT64 value) +{ + + cpu_memorywrite_d(paddr, (UINT32)value); + cpu_memorywrite_d(paddr + 4, (UINT32)(value >> 32)); +} + +REG80 MEMCALL +cpu_memoryread_f(UINT32 paddr) +{ + REG80 value; + int i; + + for (i = 0; i < (int)sizeof(REG80); ++i) { + value.b[i] = cpu_memoryread(paddr + i); + } + return value; +} + +void MEMCALL +cpu_memorywrite_f(UINT32 paddr, const REG80 *value) +{ + int i; + + for (i = 0; i < (int)sizeof(REG80); ++i) { + cpu_memorywrite(paddr + i, value->b[i]); + } +} + +/* + * virtual address memory access functions + */ +#if 0 +#define CHOOSE_EXCEPTION(sreg) \ + (((sreg) == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION) + +#include "cpu_mem.mcr" + +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(b, UINT8, 1) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(b, UINT8, 1) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(w, UINT16, 2) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(w, UINT16, 2) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(d, UINT32, 4) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(d, UINT32, 4) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(q, UINT64, 8) +#endif +#if 0 +REG80 MEMCALL +cpu_vmemoryread_f(int idx, UINT32 offset) +{ + descriptor_t *sdp; + UINT32 addr; + int exc; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sdp = &CPU_STAT_SREG(idx); + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_f(addr); + + if (!SEG_IS_VALID(sdp)) { + exc = GP_EXCEPTION; + goto err; + } + if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { + cpu_memoryread_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); + } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { + if (!check_limit_upstairs(sdp, offset, 10, SEG_IS_32BIT(sdp))) + goto range_failure; + } + return cpu_lmemoryread_f(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); + +range_failure: + VERBOSE(("cpu_vmemoryread_f: type = %d, offset = %08x, limit = %08x", sdp->type, offset, sdp->u.seg.limit)); + exc = CHOOSE_EXCEPTION(idx); +err: + EXCEPTION(exc, 0); + { + REG80 dummy; + memset(&dummy, 0, sizeof(dummy)); + return dummy; /* compiler happy */ + } +} + +void MEMCALL +cpu_vmemorywrite_f(int idx, UINT32 offset, const REG80 *value) +{ + descriptor_t *sdp; + UINT32 addr; + int exc; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sdp = &CPU_STAT_SREG(idx); + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) { + cpu_memorywrite_f(addr, value); + return; + } + + if (!SEG_IS_VALID(sdp)) { + exc = GP_EXCEPTION; + goto err; + } + if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { + cpu_memorywrite_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); + } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { + if (!check_limit_upstairs(sdp, offset, 10, SEG_IS_32BIT(sdp))) + goto range_failure; + } + cpu_lmemorywrite_f(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); + return; + +range_failure: + VERBOSE(("cpu_vmemorywrite_f: type = %d, offset = %08x, limit = %08x", sdp->type, offset, sdp->u.seg.limit)); + exc = CHOOSE_EXCEPTION(idx); +err: + EXCEPTION(exc, 0); +} + +/* + * code fetch + */ +UINT8 MEMCALL +cpu_codefetch(UINT32 offset) +{ + const int ucrw = CPU_PAGE_READ_CODE | CPU_STAT_USER_MODE; + descriptor_t *sdp; + UINT32 addr; + + sdp = &CPU_CS_DESC; + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_codefetch(addr); + if (offset <= sdp->u.seg.limit) + return cpu_lmemoryread_codefetch(addr, ucrw); + + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} + +UINT16 MEMCALL +cpu_codefetch_w(UINT32 offset) +{ + const int ucrw = CPU_PAGE_READ_CODE | CPU_STAT_USER_MODE; + descriptor_t *sdp; + UINT32 addr; + + sdp = &CPU_CS_DESC; + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_w_codefetch(addr); + if (offset <= sdp->u.seg.limit - 1) + return cpu_lmemoryread_w_codefetch(addr, ucrw); + + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} + +UINT32 MEMCALL +cpu_codefetch_d(UINT32 offset) +{ + const int ucrw = CPU_PAGE_READ_CODE | CPU_STAT_USER_MODE; + descriptor_t *sdp; + UINT32 addr; + + sdp = &CPU_CS_DESC; + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_d_codefetch(addr); + + if (offset <= sdp->u.seg.limit - 3) + return cpu_lmemoryread_d_codefetch(addr, ucrw); + + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} +#endif diff --git a/source/src/vm/np21/i386c/ia32/cpu_mem.h b/source/src/vm/np21/i386c/ia32/cpu_mem.h new file mode 100644 index 000000000..150097eb1 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpu_mem.h @@ -0,0 +1,602 @@ +/* + * Copyright (c) 2002-2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_CPU_MEM_H__ +#define IA32_CPU_CPU_MEM_H__ + +#include "../cpumem.h" +#include "segments.h" + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * memory access check + */ +#if 0 +void MEMCALL cpu_stack_push_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, BOOL is32bit); +void MEMCALL cpu_stack_pop_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, BOOL is32bit); +#define SS_PUSH_CHECK1(sp, len, is32bit) \ + cpu_stack_push_check(CPU_SS_INDEX, &CPU_SS_DESC, (sp), (len), (is32bit)) +#define SS_POP_CHECK1(sp, len, is32bit) \ + cpu_stack_pop_check(CPU_SS_INDEX, &CPU_SS_DESC, (sp), (len), (is32bit)) +#define SS_PUSH_CHECK(sp, len) \ + SS_PUSH_CHECK1((sp), (len), CPU_SS_DESC.d) +#define SS_POP_CHECK(sp, len) \ + SS_POP_CHECK1((sp), (len), CPU_SS_DESC.d) +#endif +/* + * virtual address function + */ +#if 0 +void MEMCALL cpu_vmemorywrite_b(int idx, UINT32 offset, UINT8 value); +#define cpu_vmemorywrite(i,o,v) cpu_vmemorywrite_b(i,o,v) +void MEMCALL cpu_vmemorywrite_w(int idx, UINT32 offset, UINT16 value); +void MEMCALL cpu_vmemorywrite_d(int idx, UINT32 offset, UINT32 value); +void MEMCALL cpu_vmemorywrite_q(int idx, UINT32 offset, UINT64 value); +void MEMCALL cpu_vmemorywrite_f(int idx, UINT32 offset, const REG80 *value); +UINT8 MEMCALL cpu_vmemoryread_b(int idx, UINT32 offset); +#define cpu_vmemoryread(i,o) cpu_vmemoryread_b(i,o) +UINT16 MEMCALL cpu_vmemoryread_w(int idx, UINT32 offset); +UINT32 MEMCALL cpu_vmemoryread_d(int idx, UINT32 offset); +UINT64 MEMCALL cpu_vmemoryread_q(int idx, UINT32 offset); +REG80 MEMCALL cpu_vmemoryread_f(int idx, UINT32 offset); +UINT32 MEMCALL cpu_vmemory_RMW_b(int idx, UINT32 offset, UINT32 (CPUCALL *func)(UINT32, void *), void *arg); +UINT32 MEMCALL cpu_vmemory_RMW_w(int idx, UINT32 offset, UINT32 (CPUCALL *func)(UINT32, void *), void *arg); +UINT32 MEMCALL cpu_vmemory_RMW_d(int idx, UINT32 offset, UINT32 (CPUCALL *func)(UINT32, void *), void *arg); +#else +//void MEMCALL cpu_vmemorywrite_f(int idx, UINT32 offset, const REG80 *value); +//REG80 MEMCALL cpu_vmemoryread_f(int idx, UINT32 offset); + +#endif +#if 0 +/* + * code fetch + */ +UINT8 MEMCALL cpu_codefetch(UINT32 offset); +UINT16 MEMCALL cpu_codefetch_w(UINT32 offset); +UINT32 MEMCALL cpu_codefetch_d(UINT32 offset); + +/* + * additional physical address function + */ +#endif +UINT64 MEMCALL cpu_memoryread_q(UINT32 paddr); +REG80 MEMCALL cpu_memoryread_f(UINT32 paddr); +void MEMCALL cpu_memorywrite_q(UINT32 paddr, UINT64 value); +void MEMCALL cpu_memorywrite_f(UINT32 paddr, const REG80 *value); + + +#if 1 +#define CHOOSE_EXCEPTION(sreg) \ + (((sreg) == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION) + +#include "exception.h" +#include "paging.h" + +static __inline__ int MEMCALL check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len, BOOL is32bit); +static __inline__ void MEMCALL cpu_memoryread_check(descriptor_t *sdp, UINT32 offset, UINT len, int e); +static __inline__ void MEMCALL cpu_memorywrite_check(descriptor_t *sdp, UINT32 offset, UINT len, int e); + +__inline__ void MEMCALL +cpu_stack_push_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, + BOOL is32bit) +{ + UINT32 limit; + UINT32 start; + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + len--; + + if (!SEG_IS_VALID(sdp) + || !SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || SEG_IS_CODE(sdp) + || !SEG_IS_WRITABLE_DATA(sdp)) { + goto exc; + } + + //start = sp - len; + //limit = is32bit ? 0xffffffff : 0x0000ffff; + limit = is32bit ? 0xffffffff : 0x0000ffff; + sp = (sp - 1) & limit; + start = (sp - len) & limit; + + + if (SEG_IS_EXPANDDOWN_DATA(sdp)) { + /* expand-down stack */ + if (!SEG_IS_32BIT(sdp)) { + if (sp > limit) { /* [*] */ + goto exc; + } + } + if (sdp->u.seg.limit == 0) { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | [*] | + * | | +-------+ 0000FFFFh + * | valid | | | + * | | | valid | + * | | | | + * +-------+ +-------+ 00000000h + */ + if (!SEG_IS_32BIT(sdp)) { + if (sp > limit) { /* [1] */ + goto exc; + } + } else { + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } + } else { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | [*] | + * | valid | +-------+ 0000FFFFh + * | | | valid | + * +-------+ +-------+ seg.limit + len - 1 + * | | | | + * +..[1]..+ +..[1]..+ seg.limit + * | | | | + * +-------+ +-------+ 00000000h + */ + if ((len > limit - sdp->u.seg.limit) /* len check */ + || (start > sp) /* wrap check */ + || (start < sdp->u.seg.limit)) { /* [1] */ + goto exc; + } + } + } else { + /* expand-up stack */ + if (sdp->u.seg.limit == limit) { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | [1] | + * | | +-------+ 0000FFFFh + * | valid | | | + * | | | valid | + * | | | | + * +-------+ +-------+ 00000000h + */ + if (!SEG_IS_32BIT(sdp)) { + if (sp > limit) { /* [1] */ + goto exc; + } + } else { + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } + } else { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | | + * | [1] | + [1] + 0000FFFFh + * | | | | + * +-------+ +-------+ seg.limit + * | valid | | valid | + * +.......+ +.......+ len - 1 + * | [+] | | [+] | + * +-------+ +-------+ 00000000h + * + * [+]: wrap check + */ + if ((len > sdp->u.seg.limit) /* len check */ + || (start > sp) /* wrap check */ + || (sp > sdp->u.seg.limit + 1)) { /* [1] */ + goto exc; + } + } + } + return; + +exc: + VERBOSE(("cpu_stack_push_check: check failure: selector = 0x%04x, sp = 0x%08x, len = %d", s, sp, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(SS_EXCEPTION, s & 0xfffc); +} + +__inline__ void MEMCALL +cpu_stack_pop_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, + BOOL is32bit) +{ + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + if (!SEG_IS_VALID(sdp) + || !SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || SEG_IS_CODE(sdp) + || !SEG_IS_WRITABLE_DATA(sdp)) { + goto exc; + } + + if (!check_limit_upstairs(sdp, sp, len, is32bit)) + goto exc; + return; + +exc: + VERBOSE(("cpu_stack_pop_check: check failure: selector = 0x%04x, sp = 0x%08x, len = %d", s, sp, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(SS_EXCEPTION, s & 0xfffc); +} +#define SS_PUSH_CHECK1(sp, len, is32bit) \ + cpu_stack_push_check(CPU_SS_INDEX, &CPU_SS_DESC, (sp), (len), (is32bit)) +#define SS_POP_CHECK1(sp, len, is32bit) \ + cpu_stack_pop_check(CPU_SS_INDEX, &CPU_SS_DESC, (sp), (len), (is32bit)) +#define SS_PUSH_CHECK(sp, len) \ + SS_PUSH_CHECK1((sp), (len), CPU_SS_DESC.d) +#define SS_POP_CHECK(sp, len) \ + SS_POP_CHECK1((sp), (len), CPU_SS_DESC.d) + +#include "cpu_mem.mcr" + +/* + * memory access check + */ +static __inline__ int MEMCALL +check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len, BOOL is32bit) +{ + UINT32 limit; + UINT32 end; + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + len--; + end = offset + len; + + if (SEG_IS_DATA(sdp) && SEG_IS_EXPANDDOWN_DATA(sdp)) { + /* expand-down data segment */ + limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; + if (sdp->u.seg.limit == 0) { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | | | | + * | | + [1] + 0000FFFFh + * | valid | | | + * | | +-------+ 0000FFFFh - len -1 + * | | | valid | + * +-------+ +-------+ 00000000h + */ + if (!SEG_IS_32BIT(sdp)) { + if ((len > limit) /* len check */ + || (end > limit)) { /* [1] */ + goto exc; + } + } else { + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } + } else { + /* + * 32bit 16bit + * +-------+ +-------+ FFFFFFFFh + * | [2] | | | + * +-------+ +.......+ FFFFFFFFh - len - 1 + * | | | [2] | + * | | +.......+ 0000FFFFh + * | valid | | | + * | | +-------+ 0000FFFFh - len - 1 + * | | | valid | + * +-------+ +-------+ seg.limit + * | [1] | | [1] | + * +-------+ +-------+ 00000000h + */ + if ((len > limit - sdp->u.seg.limit) /* len check */ + || (end < offset) /* wrap check */ + || (offset < sdp->u.seg.limit) /* [1] */ + || (end > limit)) { /* [2] */ + goto exc; + } + } + } else { + /* expand-up data or code segment */ + if (sdp->u.seg.limit == 0xffffffff) { + /* + * 16/32bit + * +-------+ FFFFFFFFh + * | | + * | | + * | valid | + * | | + * | | + * +-------+ 00000000h + */ + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; + } else { + /* + * 16/32bit + * +-------+ FFFFFFFFh + * | | + * | | + * | [1] | + * +.......+ seg.limit + * | | + * +-------+ seg.limit - len - 1 + * | valid | + * +-------+ 00000000h + */ + if ((len > sdp->u.seg.limit) /* len check */ + || (end < offset) /* wrap check */ + || (end > sdp->u.seg.limit + 1)) { /* [1] */ + goto exc; + } + } + } + return 1; /* Ok! */ + +exc: + VERBOSE(("check_limit_upstairs: check failure: offset = 0x%08x, len = %d", offset, len + 1)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + return 0; +} + +static __inline__ void MEMCALL +cpu_memoryread_check(descriptor_t *sdp, UINT32 offset, UINT len, int e) +{ + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + if (!SEG_IS_VALID(sdp)) { + e = GP_EXCEPTION; + goto exc; + } + if (!SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || (SEG_IS_CODE(sdp) && !SEG_IS_READABLE_CODE(sdp))) { + goto exc; + } + + switch (sdp->type) { + case 0: case 1: /* ro */ + case 2: case 3: /* rw */ + case 4: case 5: /* ro (expand down) */ + case 6: case 7: /* rw (expand down) */ + case 10: case 11: /* rx */ + case 14: case 15: /* rxc */ + if (!check_limit_upstairs(sdp, offset, len, SEG_IS_32BIT(sdp))) + goto exc; + break; + + default: + goto exc; + } + sdp->flag |= CPU_DESC_FLAG_READABLE; + return; + +exc: + VERBOSE(("cpu_memoryread_check: check failure: offset = 0x%08x, len = %d", offset, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(e, 0); +} + +static __inline__ void MEMCALL +cpu_memorywrite_check(descriptor_t *sdp, UINT32 offset, UINT len, int e) +{ + + __ASSERT(sdp != NULL); + __ASSERT(len > 0); + + if (!SEG_IS_VALID(sdp)) { + e = GP_EXCEPTION; + goto exc; + } + if (!SEG_IS_PRESENT(sdp) + || SEG_IS_SYSTEM(sdp) + || SEG_IS_CODE(sdp) + || (SEG_IS_DATA(sdp) && !SEG_IS_WRITABLE_DATA(sdp))) { + goto exc; + } + + switch (sdp->type) { + case 2: case 3: /* rw */ + case 6: case 7: /* rw (expand down) */ + if (!check_limit_upstairs(sdp, offset, len, SEG_IS_32BIT(sdp))) + goto exc; + break; + + default: + goto exc; + } + sdp->flag |= CPU_DESC_FLAG_WRITABLE | CPU_DESC_FLAG_READABLE; + return; + +exc: + VERBOSE(("cpu_memorywrite_check: check failure: offset = 0x%08x, len = %d", offset, len)); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif + EXCEPTION(e, 0); +} + +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(b, UINT8, 1) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(b, UINT8, 1) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(w, UINT16, 2) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(w, UINT16, 2) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(d, UINT32, 4) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(d, UINT32, 4) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(q, UINT64, 8) + +#define cpu_vmemorywrite(i,o,v) cpu_vmemorywrite_b(i,o,v) +#define cpu_vmemoryread(i,o) cpu_vmemoryread_b(i,o) + +__inline__ REG80 MEMCALL +cpu_vmemoryread_f(int idx, UINT32 offset) +{ + descriptor_t *sdp; + UINT32 addr; + int exc; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sdp = &CPU_STAT_SREG(idx); + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_f(addr); + + if (!SEG_IS_VALID(sdp)) { + exc = GP_EXCEPTION; + goto err; + } + if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { + cpu_memoryread_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); + } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { + if (!check_limit_upstairs(sdp, offset, 10, SEG_IS_32BIT(sdp))) + goto range_failure; + } + return cpu_lmemoryread_f(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); + +range_failure: + VERBOSE(("cpu_vmemoryread_f: type = %d, offset = %08x, limit = %08x", sdp->type, offset, sdp->u.seg.limit)); + exc = CHOOSE_EXCEPTION(idx); +err: + EXCEPTION(exc, 0); + { + REG80 dummy; + memset(&dummy, 0, sizeof(dummy)); + return dummy; /* compiler happy */ + } +} + +__inline__ void MEMCALL +cpu_vmemorywrite_f(int idx, UINT32 offset, const REG80 *value) +{ + descriptor_t *sdp; + UINT32 addr; + int exc; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + + sdp = &CPU_STAT_SREG(idx); + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) { + cpu_memorywrite_f(addr, value); + return; + } + + if (!SEG_IS_VALID(sdp)) { + exc = GP_EXCEPTION; + goto err; + } + if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { + cpu_memorywrite_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); + } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { + if (!check_limit_upstairs(sdp, offset, 10, SEG_IS_32BIT(sdp))) + goto range_failure; + } + cpu_lmemorywrite_f(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); + return; + +range_failure: + VERBOSE(("cpu_vmemorywrite_f: type = %d, offset = %08x, limit = %08x", sdp->type, offset, sdp->u.seg.limit)); + exc = CHOOSE_EXCEPTION(idx); +err: + EXCEPTION(exc, 0); +} + +/* + * code fetch + */ +__inline__ UINT8 MEMCALL +cpu_codefetch(UINT32 offset) +{ + const int ucrw = CPU_PAGE_READ_CODE | CPU_STAT_USER_MODE; + descriptor_t *sdp; + UINT32 addr; + + sdp = &CPU_CS_DESC; + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_codefetch(addr); + if (offset <= sdp->u.seg.limit) + return cpu_lmemoryread_codefetch(addr, ucrw); + + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} + +__inline__ UINT16 MEMCALL +cpu_codefetch_w(UINT32 offset) +{ + const int ucrw = CPU_PAGE_READ_CODE | CPU_STAT_USER_MODE; + descriptor_t *sdp; + UINT32 addr; + + sdp = &CPU_CS_DESC; + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_w_codefetch(addr); + if (offset <= sdp->u.seg.limit - 1) + return cpu_lmemoryread_w_codefetch(addr, ucrw); + + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} + +__inline__ UINT32 MEMCALL +cpu_codefetch_d(UINT32 offset) +{ + const int ucrw = CPU_PAGE_READ_CODE | CPU_STAT_USER_MODE; + descriptor_t *sdp; + UINT32 addr; + + sdp = &CPU_CS_DESC; + addr = sdp->u.seg.segbase + offset; + + if (!CPU_STAT_PM) + return cpu_memoryread_d_codefetch(addr); + + if (offset <= sdp->u.seg.limit - 3) + return cpu_lmemoryread_d_codefetch(addr, ucrw); + + EXCEPTION(GP_EXCEPTION, 0); + return 0; /* compiler happy */ +} +#endif +//#ifdef __cplusplus +//} +//#endif + + +#endif /* !IA32_CPU_CPU_MEM_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/cpu_mem.mcr b/source/src/vm/np21/i386c/ia32/cpu_mem.mcr new file mode 100644 index 000000000..30864f76b --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpu_mem.mcr @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(width, valtype, length) \ +__inline__ valtype MEMCALL \ +cpu_vmemoryread_##width(int idx, UINT32 offset) \ +{ \ + descriptor_t *sdp; \ + UINT32 addr; \ + int exc; \ +\ + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ +\ + sdp = &CPU_STAT_SREG(idx); \ + addr = sdp->u.seg.segbase + offset; \ +\ + if (!CPU_STAT_PM) \ + return cpu_memoryread_##width(addr); \ +\ + if (!SEG_IS_VALID(sdp)) { \ + exc = GP_EXCEPTION; \ + goto err; \ + } \ + if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { \ + cpu_memoryread_check(sdp, offset, (length), \ + CHOOSE_EXCEPTION(idx)); \ + } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \ + if (!check_limit_upstairs(sdp, offset, (length), SEG_IS_32BIT(sdp))) \ + goto range_failure; \ + } \ + return cpu_lmemoryread_##width(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); \ +\ +range_failure: \ + VERBOSE(("cpu_vmemoryread_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \ + exc = CHOOSE_EXCEPTION(idx); \ +err: \ + EXCEPTION(exc, 0); \ + return 0; /* compiler happy */ \ +} \ +\ +__inline__ void MEMCALL \ +cpu_vmemorywrite_##width(int idx, UINT32 offset, valtype value) \ +{ \ + descriptor_t *sdp; \ + UINT32 addr; \ + int exc; \ +\ + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ +\ + sdp = &CPU_STAT_SREG(idx); \ + addr = sdp->u.seg.segbase + offset; \ +\ + if (!CPU_STAT_PM) { \ + cpu_memorywrite_##width(addr, value); \ + return; \ + } \ +\ + if (!SEG_IS_VALID(sdp)) { \ + exc = GP_EXCEPTION; \ + goto err; \ + } \ + if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { \ + cpu_memorywrite_check(sdp, offset, (length), \ + CHOOSE_EXCEPTION(idx)); \ + } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \ + if (!check_limit_upstairs(sdp, offset, (length), SEG_IS_32BIT(sdp))) \ + goto range_failure; \ + } \ + cpu_lmemorywrite_##width(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); \ + return; \ +\ +range_failure: \ + VERBOSE(("cpu_vmemorywrite_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \ + exc = CHOOSE_EXCEPTION(idx); \ +err: \ + EXCEPTION(exc, 0); \ +} + +#define DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(width, valtype, length) \ +__inline__ UINT32 MEMCALL \ +cpu_vmemory_RMW_##width(int idx, UINT32 offset, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) \ +{ \ + descriptor_t *sdp; \ + UINT32 addr; \ + UINT32 result; \ + valtype value; \ + int exc; \ +\ + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ +\ + sdp = &CPU_STAT_SREG(idx); \ + addr = sdp->u.seg.segbase + offset; \ +\ + if (!CPU_STAT_PM) { \ + value = cpu_memoryread_##width(addr); \ + result = (*func)(value, arg); \ + cpu_memorywrite_##width(addr, (valtype)result); \ + return value; \ + } \ +\ + if (!SEG_IS_VALID(sdp)) { \ + exc = GP_EXCEPTION; \ + goto err; \ + } \ + if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { \ + cpu_memorywrite_check(sdp, offset, (length), \ + CHOOSE_EXCEPTION(idx)); \ + } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \ + if (!check_limit_upstairs(sdp, offset, (length), SEG_IS_32BIT(sdp))) \ + goto range_failure; \ + } \ + return cpu_lmemory_RMW_##width(addr, func, arg); \ +\ +range_failure: \ + VERBOSE(("cpu_vmemory_RMW_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \ + exc = CHOOSE_EXCEPTION(idx); \ +err: \ + EXCEPTION(exc, 0); \ + return 0; /* compiler happy */ \ +} diff --git a/source/src/vm/np21/i386c/ia32/cpucall_types.h b/source/src/vm/np21/i386c/ia32/cpucall_types.h new file mode 100644 index 000000000..59e2bf521 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/cpucall_types.h @@ -0,0 +1,9 @@ + +#pragma once +#include "../../common.h" +#define PARTSCALL __FASTCALL +#define CPUCALL __FASTCALL +#define MEMCALL __FASTCALL +#define DMACCALL __FASTCALL +#define IOOUTCALL __FASTCALL +#define IOINPCALL __FASTCALL diff --git a/source/src/vm/np21/i386c/ia32/ctrlxfer.cpp b/source/src/vm/np21/i386c/ia32/ctrlxfer.cpp new file mode 100644 index 000000000..a72df675e --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/ctrlxfer.cpp @@ -0,0 +1,1437 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#include "ctrlxfer.h" + + +/*------------------------------------------------------------------------------ + * JMPfar_pm + */ +static void CPUCALL JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); +static void CPUCALL JMPfar_pm_call_gate(const selector_t *callgate_sel); +static void CPUCALL JMPfar_pm_task_gate(selector_t *taskgate_sel); +static void CPUCALL JMPfar_pm_tss(selector_t *tss_sel); + + +void CPUCALL +JMPfar_pm(UINT16 selector, UINT32 new_ip) +{ + selector_t jmp_sel; + int rv; + + VERBOSE(("JMPfar_pm: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP)); + VERBOSE(("JMPfar_pm: selector = 0x%04x, new_ip = 0x%08x", selector, new_ip)); + + rv = parse_selector(&jmp_sel, selector); + if (rv < 0) { + VERBOSE(("JMPfar_pm: parse_selector (selector = %04x, rv = %d)", selector, rv)); + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + + if (!SEG_IS_SYSTEM(&jmp_sel.desc)) { + VERBOSE(("JMPfar_pm: code or data segment descriptor")); + + /* check segment type */ + if (SEG_IS_DATA(&jmp_sel.desc)) { + /* data segment */ + VERBOSE(("JMPfar_pm: data segment")); + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + } + + /* code segment descriptor */ + JMPfar_pm_code_segment(&jmp_sel, new_ip); + } else { + /* system descriptor */ + VERBOSE(("JMPfar_pm: system descriptor")); + + switch (jmp_sel.desc.type) { + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_CALL_32: + JMPfar_pm_call_gate(&jmp_sel); + break; + + case CPU_SYSDESC_TYPE_TASK: + JMPfar_pm_task_gate(&jmp_sel); + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + JMPfar_pm_tss(&jmp_sel); + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("JMPfar_pm: task is busy")); + /*FALLTHROUGH*/ + default: + VERBOSE(("JMPfar_pm: invalid descriptor type (type = %d)", jmp_sel.desc.type)); + EXCEPTION(GP_EXCEPTION, jmp_sel.idx); + break; + } + } + + VERBOSE(("JMPfar_pm: new EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP)); +} + +/*--- + * JMPfar: code segment + */ +static void CPUCALL +JMPfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) +{ + + VERBOSE(("JMPfar_pm: CODE-SEGMENT")); + + /* check privilege level */ + if (!SEG_IS_CONFORMING_CODE(&cs_sel->desc)) { + VERBOSE(("JMPfar_pm: NON-CONFORMING-CODE-SEGMENT")); + /* 下巻 p.119 4.8.1.1. */ + if (cs_sel->rpl > CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d)", cs_sel->rpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel->idx); + } + if (cs_sel->desc.dpl != CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: DPL(%d) != CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel->idx); + } + } else { + VERBOSE(("JMPfar_pm: CONFORMING-CODE-SEGMENT")); + /* 下巻 p.120 4.8.1.2. */ + if (cs_sel->desc.dpl > CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel->idx); + } + } + + /* not present */ + if (selector_is_not_present(cs_sel)) { + VERBOSE(("JMPfar_pm: code selector is not present")); + EXCEPTION(NP_EXCEPTION, cs_sel->idx); + } + + /* out of range */ + if (new_ip > cs_sel->desc.u.seg.limit) { + VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel->desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); + CPU_EIP = new_ip; +} + +/*--- + * JMPfar: call gate + */ +static void CPUCALL +JMPfar_pm_call_gate(const selector_t *callgate_sel) +{ + selector_t cs_sel; + int rv; + + VERBOSE(("JMPfar_pm: CALL-GATE")); + + /* check privilege level */ + if (callgate_sel->desc.dpl < CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: DPL(%d) < CPL(%d)", callgate_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, callgate_sel->idx); + } + if (callgate_sel->desc.dpl < callgate_sel->rpl) { + VERBOSE(("JMPfar_pm: DPL(%d) < RPL(%d)", callgate_sel->desc.dpl, callgate_sel->rpl)); + EXCEPTION(GP_EXCEPTION, callgate_sel->idx); + } + + /* not present */ + if (selector_is_not_present(callgate_sel)) { + VERBOSE(("JMPfar_pm: call gate selector is not present")); + EXCEPTION(NP_EXCEPTION, callgate_sel->idx); + } + + /* parse code segment selector */ + rv = parse_selector(&cs_sel, callgate_sel->desc.u.gate.selector); + if (rv < 0) { + VERBOSE(("JMPfar_pm: parse_selector (selector = %04x, rv = %d)", callgate_sel->desc.u.gate.selector, rv)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check segment type */ + if (SEG_IS_SYSTEM(&cs_sel.desc)) { + VERBOSE(("JMPfar_pm: code segment is system segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (SEG_IS_DATA(&cs_sel.desc)) { + VERBOSE(("JMPfar_pm: code segment is data segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check privilege level */ + if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc)) { + /* 下巻 p.119 4.8.1.1. */ + if (cs_sel.rpl > CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: RPL(%d) > CPL(%d)", cs_sel.rpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (cs_sel.desc.dpl != CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: DPL(%d) != CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + } else { + /* 下巻 p.120 4.8.1.2. */ + if (cs_sel.desc.dpl > CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: DPL(%d) > CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + } + + /* not present */ + if (selector_is_not_present(&cs_sel)) { + VERBOSE(("JMPfar_pm: code selector is not present")); + EXCEPTION(NP_EXCEPTION, cs_sel.idx); + } + + /* out of range */ + if (callgate_sel->desc.u.gate.offset > cs_sel.desc.u.seg.limit) { + VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", callgate_sel->desc.u.gate.offset, cs_sel.desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL); + CPU_EIP = callgate_sel->desc.u.gate.offset; +} + +/*--- + * JMPfar: task gate + */ +static void CPUCALL +JMPfar_pm_task_gate(selector_t *taskgate_sel) +{ + selector_t tss_sel; + int rv; + + VERBOSE(("JMPfar_pm: TASK-GATE")); + + /* check privilege level */ + if (taskgate_sel->desc.dpl < CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: DPL(%d) < CPL(%d)", taskgate_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, taskgate_sel->idx); + } + if (taskgate_sel->desc.dpl < taskgate_sel->rpl) { + VERBOSE(("JMPfar_pm: DPL(%d) < RPL(%d)", taskgate_sel->desc.dpl, taskgate_sel->rpl)); + EXCEPTION(GP_EXCEPTION, taskgate_sel->idx); + } + + /* not present */ + if (selector_is_not_present(taskgate_sel)) { + VERBOSE(("JMPfar_pm: selector is not present")); + EXCEPTION(NP_EXCEPTION, taskgate_sel->idx); + } + + /* parse tss selector */ + rv = parse_selector(&tss_sel, taskgate_sel->desc.u.gate.selector); + if (rv < 0 || tss_sel.ldt) { + VERBOSE(("JMPfar_pm: parse_selector (selector = %04x, rv = %d, %cDT)", taskgate_sel->desc.u.gate.selector, rv, tss_sel.ldt ? 'L' : 'G')); + EXCEPTION(GP_EXCEPTION, tss_sel.idx); + } + + /* check descriptor type */ + switch (tss_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("JMPfar_pm: task is busy")); + /*FALLTHROUGH*/ + default: + VERBOSE(("JMPfar_pm: invalid descriptor type (type = %d)", tss_sel.desc.type)); + EXCEPTION(GP_EXCEPTION, tss_sel.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&tss_sel)) { + VERBOSE(("JMPfar_pm: selector is not present")); + EXCEPTION(NP_EXCEPTION, tss_sel.idx); + } + + task_switch(&tss_sel, TASK_SWITCH_JMP); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + +/*--- + * JMPfar: TSS + */ +static void CPUCALL +JMPfar_pm_tss(selector_t *tss_sel) +{ + + VERBOSE(("JMPfar_pm: TASK-STATE-SEGMENT")); + + /* check privilege level */ + if (tss_sel->desc.dpl < CPU_STAT_CPL) { + VERBOSE(("JMPfar_pm: DPL(%d) < CPL(%d)", tss_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, tss_sel->idx); + } + if (tss_sel->desc.dpl < tss_sel->rpl) { + VERBOSE(("JMPfar_pm: DPL(%d) < RPL(%d)", tss_sel->desc.dpl, tss_sel->rpl)); + EXCEPTION(GP_EXCEPTION, tss_sel->idx); + } + + /* not present */ + if (selector_is_not_present(tss_sel)) { + VERBOSE(("JMPfar_pm: selector is not present")); + EXCEPTION(NP_EXCEPTION, tss_sel->idx); + } + + task_switch(tss_sel, TASK_SWITCH_JMP); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + + +/*------------------------------------------------------------------------------ + * CALLfar_pm + */ +static void CPUCALL CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip); +static void CPUCALL CALLfar_pm_call_gate(const selector_t *callgate_sel); +static void CPUCALL CALLfar_pm_task_gate(selector_t *taskgate_sel); +static void CPUCALL CALLfar_pm_tss(selector_t *tss_sel); + +void CPUCALL +CALLfar_pm(UINT16 selector, UINT32 new_ip) +{ + selector_t call_sel; + int rv; + + VERBOSE(("CALLfar_pm: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP)); + VERBOSE(("CALLfar_pm: selector = 0x%04x, new_ip = 0x%08x", selector, new_ip)); + + rv = parse_selector(&call_sel, selector); + if (rv < 0) { + VERBOSE(("CALLfar_pm: parse_selector (selector = %04x, rv = %d)", selector, rv)); + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + + if (!SEG_IS_SYSTEM(&call_sel.desc)) { + /* code or data segment descriptor */ + VERBOSE(("CALLfar_pm: code or data segment descriptor")); + + if (SEG_IS_DATA(&call_sel.desc)) { + /* data segment */ + VERBOSE(("CALLfar_pm: data segment")); + EXCEPTION(GP_EXCEPTION, call_sel.idx); + } + + /* code segment descriptor */ + CALLfar_pm_code_segment(&call_sel, new_ip); + } else { + /* system descriptor */ + VERBOSE(("CALLfar_pm: system descriptor")); + + switch (call_sel.desc.type) { + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_CALL_32: + CALLfar_pm_call_gate(&call_sel); + break; + + case CPU_SYSDESC_TYPE_TASK: + CALLfar_pm_task_gate(&call_sel); + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + CALLfar_pm_tss(&call_sel); + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("CALLfar_pm: task is busy")); + /*FALLTHROUGH*/ + default: + VERBOSE(("CALLfar_pm: invalid descriptor type (type = %d)", call_sel.desc.type)); + EXCEPTION(GP_EXCEPTION, call_sel.idx); + break; + } + } + + VERBOSE(("CALLfar_pm: new EIP = %04x:%08x, new ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP)); +} + +/*--- + * CALLfar_pm: code segment + */ +static void CPUCALL +CALLfar_pm_code_segment(const selector_t *cs_sel, UINT32 new_ip) +{ + UINT32 sp; + + VERBOSE(("CALLfar_pm: CODE-SEGMENT")); + + /* check privilege level */ + if (!SEG_IS_CONFORMING_CODE(&cs_sel->desc)) { + VERBOSE(("CALLfar_pm: NON-CONFORMING-CODE-SEGMENT")); + /* 下巻 p.119 4.8.1.1. */ + if (cs_sel->rpl > CPU_STAT_CPL) { + VERBOSE(("CALLfar_pm: RPL(%d) > CPL(%d)", cs_sel->rpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel->idx); + } + if (cs_sel->desc.dpl != CPU_STAT_CPL) { + VERBOSE(("CALLfar_pm: DPL(%d) != CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel->idx); + } + } else { + VERBOSE(("CALLfar_pm: CONFORMING-CODE-SEGMENT")); + /* 下巻 p.120 4.8.1.2. */ + if (cs_sel->desc.dpl > CPU_STAT_CPL) { + VERBOSE(("CALLfar_pm: DPL(%d) > CPL(%d)", cs_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel->idx); + } + } + + /* not present */ + if (selector_is_not_present(cs_sel)) { + VERBOSE(("CALLfar_pm: selector is not present")); + EXCEPTION(NP_EXCEPTION, cs_sel->idx); + } + + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + if (CPU_INST_OP32) { + SS_PUSH_CHECK(sp, 8); + + /* out of range */ + if (new_ip > cs_sel->desc.u.seg.limit) { + VERBOSE(("CALLfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel->desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + } else { + SS_PUSH_CHECK(sp, 4); + + /* out of range */ + if (new_ip > cs_sel->desc.u.seg.limit) { + VERBOSE(("CALLfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel->desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + } + + load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); + CPU_EIP = new_ip; +} + +/*--- + * CALLfar_pm: call gate + */ +static void CPUCALL CALLfar_pm_call_gate_same_privilege(const selector_t *call_sel, selector_t *cs_sel); +static void CPUCALL CALLfar_pm_call_gate_more_privilege(const selector_t *call_sel, selector_t *cs_sel); + +static void CPUCALL +CALLfar_pm_call_gate(const selector_t *callgate_sel) +{ + selector_t cs_sel; + int rv; + + VERBOSE(("CALLfar_pm: CALL-GATE")); + + /* check privilege level */ + if (callgate_sel->desc.dpl < CPU_STAT_CPL) { + VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", callgate_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, callgate_sel->idx); + } + if (callgate_sel->desc.dpl < callgate_sel->rpl) { + VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", callgate_sel->desc.dpl, callgate_sel->rpl)); + EXCEPTION(GP_EXCEPTION, callgate_sel->idx); + } + + /* not present */ + if (selector_is_not_present(callgate_sel)) { + VERBOSE(("CALLfar_pm: selector is not present")); + EXCEPTION(NP_EXCEPTION, callgate_sel->idx); + } + + /* parse code segment descriptor */ + rv = parse_selector(&cs_sel, callgate_sel->desc.u.gate.selector); + if (rv < 0) { + VERBOSE(("CALLfar_pm: parse_selector (selector = %04x, rv = %d)", callgate_sel->desc.u.gate.selector, rv)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check segment type */ + if (SEG_IS_SYSTEM(&cs_sel.desc)) { + VERBOSE(("CALLfar_pm: code segment is system segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (SEG_IS_DATA(&cs_sel.desc)) { + VERBOSE(("CALLfar_pm: code segment is data segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check privilege level */ + if (cs_sel.desc.dpl > CPU_STAT_CPL) { + VERBOSE(("CALLfar_pm: DPL(%d) > CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&cs_sel)) { + VERBOSE(("CALLfar_pm: selector is not present")); + EXCEPTION(NP_EXCEPTION, cs_sel.idx); + } + + /* out of range */ + if (callgate_sel->desc.u.gate.offset > cs_sel.desc.u.seg.limit) { + VERBOSE(("CALLfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", callgate_sel->desc.u.gate.offset, cs_sel.desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc) && (cs_sel.desc.dpl < CPU_STAT_CPL)) { + CALLfar_pm_call_gate_more_privilege(callgate_sel, &cs_sel); + } else { + CALLfar_pm_call_gate_same_privilege(callgate_sel, &cs_sel); + } +} + +/*--- + * CALLfar_pm: call gate (SAME-PRIVILEGE) + */ +static void CPUCALL +CALLfar_pm_call_gate_same_privilege(const selector_t *callgate_sel, selector_t *cs_sel) +{ + UINT32 sp; + + VERBOSE(("CALLfar_pm: SAME-PRIVILEGE")); + + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { + SS_PUSH_CHECK(sp, 8); + + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + } else { + SS_PUSH_CHECK(sp, 4); + + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + } + + load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); + CPU_EIP = callgate_sel->desc.u.gate.offset; +} + +/*--- + * CALLfar_pm: call gate (MORE-PRIVILEGE) + */ +static void CPUCALL +CALLfar_pm_call_gate_more_privilege(const selector_t *callgate_sel, selector_t *cs_sel) +{ + UINT32 param[32]; /* copy param */ + selector_t ss_sel; + UINT stacksize; + UINT32 old_eip, old_esp; + UINT32 new_esp; + UINT16 old_cs, old_ss; + UINT16 new_ss; + int param_count; + int i; + int rv; + + VERBOSE(("CALLfar_pm: MORE-PRIVILEGE")); + + /* save register */ + old_cs = CPU_CS; + old_ss = CPU_SS; + old_eip = CPU_EIP; + old_esp = CPU_ESP; + if (!CPU_STAT_SS32) { + old_esp &= 0xffff; + } + + /* get stack pointer from TSS */ + get_stack_pointer_from_tss(cs_sel->desc.dpl, &new_ss, &new_esp); + + /* parse stack segment descriptor */ + rv = parse_selector(&ss_sel, new_ss); + if (rv < 0) { + VERBOSE(("CALLfar_pm: parse_selector (selector = %04x, rv = %d)", new_ss, rv)); + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* check privilege level */ + if (ss_sel.rpl != cs_sel->desc.dpl) { + VERBOSE(("CALLfar_pm: selector RPL[SS](%d) != DPL[CS](%d)", ss_sel.rpl, cs_sel->desc.dpl)); + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + if (ss_sel.desc.dpl != cs_sel->desc.dpl) { + VERBOSE(("CALLfar_pm: descriptor DPL[SS](%d) != DPL[CS](%d)", ss_sel.desc.dpl, cs_sel->desc.dpl)); + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* stack segment must be writable data segment. */ + if (SEG_IS_SYSTEM(&ss_sel.desc)) { + VERBOSE(("CALLfar_pm: stack segment is system segment")); + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + if (SEG_IS_CODE(&ss_sel.desc)) { + VERBOSE(("CALLfar_pm: stack segment is code segment")); + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + if (!SEG_IS_WRITABLE_DATA(&ss_sel.desc)) { + VERBOSE(("CALLfar_pm: stack segment is read-only data segment")); + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + VERBOSE(("CALLfar_pm: stack segment selector is not present")); + EXCEPTION(SS_EXCEPTION, ss_sel.idx); + } + + param_count = callgate_sel->desc.u.gate.count; + VERBOSE(("CALLfar_pm: param_count = %d", param_count)); + + /* check stack size */ + if (cs_sel->desc.d) { + stacksize = 16; + } else { + stacksize = 8; + } + if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { + stacksize += param_count * 4; + } else { + stacksize += param_count * 2; + } + cpu_stack_push_check(ss_sel.idx, &ss_sel.desc, new_esp, stacksize, ss_sel.desc.d); + + if (callgate_sel->desc.type == CPU_SYSDESC_TYPE_CALL_32) { + /* dump param */ + for (i = 0; i < param_count; i++) { + param[i] = cpu_vmemoryread_d(CPU_SS_INDEX, old_esp + i * 4); + VERBOSE(("CALLfar_pm: get param[%d] = %08x", i, param[i])); + } + + load_ss(ss_sel.selector, &ss_sel.desc, ss_sel.desc.dpl); + if (CPU_STAT_SS32) { + CPU_ESP = new_esp; + } else { + CPU_SP = (UINT16)new_esp; + } + + load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl); + CPU_EIP = callgate_sel->desc.u.gate.offset; + + PUSH0_32(old_ss); + PUSH0_32(old_esp); + + /* restore param */ + for (i = param_count; i > 0; i--) { + PUSH0_32(param[i - 1]); + VERBOSE(("CALLfar_pm: set param[%d] = %08x", i - 1, param[i - 1])); + } + + PUSH0_32(old_cs); + PUSH0_32(old_eip); + } else { + /* dump param */ + for (i = 0; i < param_count; i++) { + param[i] = cpu_vmemoryread_w(CPU_SS_INDEX, old_esp + i * 2); + VERBOSE(("CALLfar_pm: get param[%d] = %04x", i, param[i])); + } + + load_ss(ss_sel.selector, &ss_sel.desc, ss_sel.desc.dpl); + if (CPU_STAT_SS32) { + CPU_ESP = new_esp; + } else { + CPU_SP = (UINT16)new_esp; + } + + load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->desc.dpl); + CPU_EIP = callgate_sel->desc.u.gate.offset; + + PUSH0_16(old_ss); + PUSH0_16(old_esp); + + /* restore param */ + for (i = param_count; i > 0; i--) { + PUSH0_16(param[i - 1]); + VERBOSE(("CALLfar_pm: set param[%d] = %04x", i - 1, param[i - 1])); + } + + PUSH0_16(old_cs); + PUSH0_16(old_eip); + } +} + +/*--- + * CALLfar_pm: task gate + */ +static void CPUCALL +CALLfar_pm_task_gate(selector_t *taskgate_sel) +{ + selector_t tss_sel; + int rv; + + VERBOSE(("CALLfar_pm: TASK-GATE")); + + /* check privilege level */ + if (taskgate_sel->desc.dpl < CPU_STAT_CPL) { + VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", taskgate_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, taskgate_sel->idx); + } + if (taskgate_sel->desc.dpl < taskgate_sel->rpl) { + VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", taskgate_sel->desc.dpl, taskgate_sel->rpl)); + EXCEPTION(GP_EXCEPTION, taskgate_sel->idx); + } + + /* not present */ + if (selector_is_not_present(taskgate_sel)) { + VERBOSE(("CALLfar_pm: selector is not present")); + EXCEPTION(NP_EXCEPTION, taskgate_sel->idx); + } + + /* tss descriptor */ + rv = parse_selector(&tss_sel, taskgate_sel->desc.u.gate.selector); + if (rv < 0 || tss_sel.ldt) { + VERBOSE(("CALLfar_pm: parse_selector (selector = %04x, rv = %d, %cDT)", tss_sel.selector, rv, tss_sel.ldt ? 'L' : 'G')); + EXCEPTION(GP_EXCEPTION, tss_sel.idx); + } + + /* check descriptor type */ + switch (tss_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("CALLfar_pm: task is busy")); + /*FALLTHROUGH*/ + default: + VERBOSE(("CALLfar_pm: invalid descriptor type (type = %d)", tss_sel.desc.type)); + EXCEPTION(GP_EXCEPTION, tss_sel.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&tss_sel)) { + VERBOSE(("CALLfar_pm: TSS selector is not present")); + EXCEPTION(NP_EXCEPTION, tss_sel.idx); + } + + task_switch(&tss_sel, TASK_SWITCH_CALL); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + +/*--- + * CALLfar_pm: TSS + */ +static void CPUCALL +CALLfar_pm_tss(selector_t *tss_sel) +{ + + VERBOSE(("TASK-STATE-SEGMENT")); + + /* check privilege level */ + if (tss_sel->desc.dpl < CPU_STAT_CPL) { + VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", tss_sel->desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, tss_sel->idx); + } + if (tss_sel->desc.dpl < tss_sel->rpl) { + VERBOSE(("CALLfar_pm: DPL(%d) < CPL(%d)", tss_sel->desc.dpl, tss_sel->rpl)); + EXCEPTION(GP_EXCEPTION, tss_sel->idx); + } + + /* not present */ + if (selector_is_not_present(tss_sel)) { + VERBOSE(("CALLfar_pm: TSS selector is not present")); + EXCEPTION(NP_EXCEPTION, tss_sel->idx); + } + + task_switch(tss_sel, TASK_SWITCH_CALL); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + + +/*------------------------------------------------------------------------------ + * RETfar_pm + */ + +void CPUCALL +RETfar_pm(UINT nbytes) +{ + selector_t cs_sel, ss_sel, temp_sel; + descriptor_t *sdp; + UINT32 sp; + UINT32 new_ip, new_sp; + UINT16 new_cs, new_ss; + int rv; + int i; + + VERBOSE(("RETfar_pm: old EIP = %04x:%08x, ESP = %04x:%08x, nbytes = %d", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP, nbytes)); + + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + if (CPU_INST_OP32) { + SS_POP_CHECK(sp, nbytes + 8); + new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp); + new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); + } else { + SS_POP_CHECK(sp, nbytes + 4); + new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp); + new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2); + } + + rv = parse_selector(&cs_sel, new_cs); + if (rv < 0) { + VERBOSE(("RETfar_pm: parse_selector (selector = %04x, rv = %d)", cs_sel.selector, rv)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check segment type */ + if (SEG_IS_SYSTEM(&cs_sel.desc)) { + VERBOSE(("RETfar_pm: return to system segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (SEG_IS_DATA(&cs_sel.desc)) { + VERBOSE(("RETfar_pm: return to data segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check privilege level */ + if (cs_sel.rpl < CPU_STAT_CPL) { + VERBOSE(("RETfar_pm: RPL(%d) < CPL(%d)", cs_sel.rpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc) && (cs_sel.desc.dpl > cs_sel.rpl)) { + VERBOSE(("RETfar_pm: NON-COMFORMING-CODE-SEGMENT and DPL(%d) > RPL(%d)", cs_sel.desc.dpl, cs_sel.rpl)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&cs_sel)) { + VERBOSE(("RETfar_pm: returned code segment is not present")); + EXCEPTION(NP_EXCEPTION, cs_sel.idx); + } + + if (cs_sel.rpl == CPU_STAT_CPL) { + VERBOSE(("RETfar_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL")); + + /* check code segment limit */ + if (new_ip > cs_sel.desc.u.seg.limit) { + VERBOSE(("RETfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel.desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + VERBOSE(("RETfar_pm: new_ip = %08x, new_cs = %04x", new_ip, cs_sel.selector)); + + if (CPU_INST_OP32) { + nbytes += 8; + } else { + nbytes += 4; + } + if (CPU_STAT_SS32) { + CPU_ESP += nbytes; + } else { + CPU_SP += (UINT16)nbytes; + } + + load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL); + CPU_EIP = new_ip; + } else { + VERBOSE(("RETfar_pm: RETURN-OUTER-PRIVILEGE-LEVEL")); + + if (CPU_INST_OP32) { + SS_POP_CHECK(sp, 8 + 8 + nbytes); + new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8 + nbytes); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8 + nbytes + 4); + } else { + SS_POP_CHECK(sp, 4 + 4 + nbytes); + new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4 + nbytes + 2); + } + + rv = parse_selector(&ss_sel, new_ss); + if (rv < 0) { + VERBOSE(("RETfar_pm: parse_selector (selector = %04x, rv = %d)", ss_sel.selector, rv)); + EXCEPTION(GP_EXCEPTION, (rv == -2) ? 0 : ss_sel.idx); + } + + /* stack segment must be writable data segment. */ + if (SEG_IS_SYSTEM(&ss_sel.desc)) { + VERBOSE(("RETfar_pm: stack segment is system segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (SEG_IS_CODE(&ss_sel.desc)) { + VERBOSE(("RETfar_pm: stack segment is code segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (!SEG_IS_WRITABLE_DATA(&ss_sel.desc)) { + VERBOSE(("RETfar_pm: stack segment is read-only data segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check privilege level */ + if (ss_sel.rpl != cs_sel.rpl) { + VERBOSE(("RETfar_pm: selector RPL[SS](%d) != RPL[CS](%d)", ss_sel.rpl, cs_sel.rpl)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (ss_sel.desc.dpl != cs_sel.rpl) { + VERBOSE(("RETfar_pm: descriptor DPL[SS](%d) != RPL[CS](%d)", ss_sel.desc.dpl, cs_sel.rpl)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + VERBOSE(("RETfar_pm: stack segment is not present")); + EXCEPTION(SS_EXCEPTION, ss_sel.idx); + } + + /* check code segment limit */ + if (new_ip > cs_sel.desc.u.seg.limit) { + VERBOSE(("RETfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel.desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + VERBOSE(("RETfar_pm: new_ip = %08x, new_cs = %04x", new_ip, cs_sel.selector)); + VERBOSE(("RETfar_pm: new_sp = %08x, new_ss = %04x", new_sp, ss_sel.selector)); + + load_ss(ss_sel.selector, &ss_sel.desc, cs_sel.rpl); + if (CPU_STAT_SS32) { + CPU_ESP = new_sp + nbytes; + } else { + CPU_SP = (UINT16)(new_sp + nbytes); + } + + load_cs(cs_sel.selector, &cs_sel.desc, cs_sel.rpl); + CPU_EIP = new_ip; + + /* check segment register */ + for (i = 0; i < CPU_SEGREG_NUM; i++) { + if (i == CPU_SS_INDEX || i == CPU_CS_INDEX) + continue; + + sdp = &CPU_STAT_SREG(i); + if ((SEG_IS_DATA(sdp) || !SEG_IS_CONFORMING_CODE(sdp)) + && (CPU_STAT_CPL > sdp->dpl)) { + /* current segment descriptor is invalid */ + CPU_REGS_SREG(i) = 0; + memset(sdp, 0, sizeof(*sdp)); + continue; + } + + /* Reload segment descriptor */ + rv = parse_selector(&temp_sel, CPU_REGS_SREG(i)); + if (rv < 0) { + /* segment register is invalid */ + CPU_REGS_SREG(i) = 0; + memset(sdp, 0, sizeof(*sdp)); + continue; + } + + /* + * - system segment + * - execute-only code segment + * - data or conforming code segment && CPL > DPL + */ + if (SEG_IS_SYSTEM(&temp_sel.desc) + || (SEG_IS_CODE(&temp_sel.desc) + && !SEG_IS_READABLE_CODE(&temp_sel.desc)) + || ((SEG_IS_DATA(&temp_sel.desc) + || !SEG_IS_CONFORMING_CODE(&temp_sel.desc)) + && (CPU_STAT_CPL > temp_sel.desc.dpl))) { + /* segment descriptor is invalid */ + CPU_REGS_SREG(i) = 0; + memset(sdp, 0, sizeof(*sdp)); + } + } + } + + VERBOSE(("RETfar_pm: new EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP)); +} + + +/*------------------------------------------------------------------------------ + * IRET_pm + */ +static void IRET_pm_nested_task(void); +static void CPUCALL IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); +static void CPUCALL IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags); +static void CPUCALL IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags); +static void CPUCALL IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); +static void CPUCALL IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags); + +void +IRET_pm(void) +{ + UINT32 sp; + UINT32 new_ip, new_flags; + UINT16 new_cs; + + VERBOSE(("IRET_pm: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_PREV_EIP, CPU_SS, CPU_ESP)); + + if (!(CPU_EFLAG & VM_FLAG) && (CPU_EFLAG & NT_FLAG)) { + /* TASK-RETURN: PE=1, VM=0, NT=1 */ + IRET_pm_nested_task(); + } else { + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + if (CPU_INST_OP32) { + SS_POP_CHECK(sp, 12); + new_ip = cpu_vmemoryread_d(CPU_SS_INDEX, sp); + new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); + new_flags = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 8); + } else { + SS_POP_CHECK(sp, 6); + new_ip = cpu_vmemoryread_w(CPU_SS_INDEX, sp); + new_cs = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 2); + new_flags = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 4); + } + + VERBOSE(("IRET_pm: new_ip = %08x, new_cs = %04x, new_eflags = %08x", new_ip, new_cs, new_flags)); + + if (CPU_EFLAG & VM_FLAG) { + /* RETURN-FROM-VIRTUAL-8086-MODE */ + IRET_pm_return_from_vm86(new_cs, new_ip, new_flags); + } else if ((new_flags & VM_FLAG) && CPU_STAT_CPL == 0) { + /* RETURN-TO-VIRTUAL-8086-MODE */ + IRET_pm_return_to_vm86(new_cs, new_ip, new_flags); + } else { + /* PROTECTED-MODE-RETURN */ + IRET_pm_protected_mode_return(new_cs, new_ip, new_flags); + } + } + + VERBOSE(("IRET_pm: new EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP)); +} + +/*--- + * IRET_pm: NT_FLAG + */ +static void +IRET_pm_nested_task(void) +{ + selector_t tss_sel; + UINT16 new_tss; + int rv; + + VERBOSE(("IRET_pm: TASK-RETURN: PE=1, VM=0, NT=1")); + + new_tss = get_backlink_selector_from_tss(); + + rv = parse_selector(&tss_sel, new_tss); + if (rv < 0 || tss_sel.ldt) { + VERBOSE(("IRET_pm: parse_selector (selector = %04x, rv = %d, %cDT)", tss_sel.selector, rv, tss_sel.ldt ? 'L' : 'G')); + EXCEPTION(GP_EXCEPTION, tss_sel.idx); + } + + /* check system segment */ + if (!SEG_IS_SYSTEM(&tss_sel.desc)) { + VERBOSE(("IRET_pm: task segment is %s segment", tss_sel.desc.u.seg.c ? "code" : "data")); + EXCEPTION(GP_EXCEPTION, tss_sel.idx); + } + + switch (tss_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + VERBOSE(("IRET_pm: task is not busy")); + /*FALLTHROUGH*/ + default: + VERBOSE(("IRET_pm: invalid descriptor type (type = %d)", tss_sel.desc.type)); + EXCEPTION(GP_EXCEPTION, tss_sel.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&tss_sel)) { + VERBOSE(("IRET_pm: tss segment is not present")); + EXCEPTION(NP_EXCEPTION, tss_sel.idx); + } + + task_switch(&tss_sel, TASK_SWITCH_IRET); + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + VERBOSE(("JMPfar_pm: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + +/*--- + * IRET_pm: PROTECTED-MODE-RETURN + */ +static void CPUCALL +IRET_pm_protected_mode_return(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) +{ + selector_t cs_sel; + int rv; + + /* PROTECTED-MODE-RETURN */ + VERBOSE(("IRET_pm: PE=1, VM=0 in flags image")); + + rv = parse_selector(&cs_sel, new_cs); + if (rv < 0) { + VERBOSE(("IRET_pm: parse_selector (selector = %04x, rv = %d)", cs_sel.selector, rv)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check code segment descriptor */ + if (SEG_IS_SYSTEM(&cs_sel.desc)) { + VERBOSE(("IRET_pm: return code segment is system segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (SEG_IS_DATA(&cs_sel.desc)) { + VERBOSE(("IRET_pm: return code segment is data segment")); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* check privilege level */ + if (cs_sel.rpl < CPU_STAT_CPL) { + VERBOSE(("IRET_pm: RPL(%d) < CPL(%d)", cs_sel.rpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + if (SEG_IS_CONFORMING_CODE(&cs_sel.desc) && (cs_sel.desc.dpl > cs_sel.rpl)) { + VERBOSE(("IRET_pm: CONFORMING-CODE-SEGMENT and DPL(%d) > RPL(%d)", cs_sel.desc.dpl, cs_sel.rpl)); + EXCEPTION(GP_EXCEPTION, cs_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&cs_sel)) { + VERBOSE(("IRET_pm: code segment is not present")); + EXCEPTION(NP_EXCEPTION, cs_sel.idx); + } + + if (cs_sel.rpl > CPU_STAT_CPL) { + IRET_pm_protected_mode_return_outer_privilege(&cs_sel, new_ip, new_flags); + } else { + IRET_pm_protected_mode_return_same_privilege(&cs_sel, new_ip, new_flags); + } +} + +/*--- + * IRET_pm: SAME-PRIVILEGE + */ +static void CPUCALL +IRET_pm_protected_mode_return_same_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) +{ + UINT32 mask; + UINT stacksize; + + VERBOSE(("IRET_pm: RETURN-TO-SAME-PRIVILEGE-LEVEL")); + + /* check code segment limit */ + if (new_ip > cs_sel->desc.u.seg.limit) { + VERBOSE(("IRET_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel->desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + mask = 0; + if (CPU_INST_OP32) + mask |= RF_FLAG; + if (CPU_STAT_CPL <= CPU_STAT_IOPL) + mask |= I_FLAG; + if (CPU_STAT_CPL == 0) { + mask |= IOPL_FLAG; + if (CPU_INST_OP32) { + mask |= VM_FLAG|VIF_FLAG|VIP_FLAG; + } + } + + if (CPU_INST_OP32) { + stacksize = 12; + } else { + stacksize = 6; + } + + /* set new register */ + load_cs(cs_sel->selector, &cs_sel->desc, CPU_STAT_CPL); + CPU_EIP = new_ip; + + if (CPU_STAT_SS32) { + CPU_ESP += stacksize; + } else { + CPU_SP += (UINT16)stacksize; + } + + set_eflags(new_flags, mask); +} + +/*--- + * IRET_pm: OUTER-PRIVILEGE + */ +static void CPUCALL +IRET_pm_protected_mode_return_outer_privilege(const selector_t *cs_sel, UINT32 new_ip, UINT32 new_flags) +{ + descriptor_t *sdp; + selector_t ss_sel; + UINT32 mask; + UINT32 sp; + UINT32 new_sp; + UINT16 new_ss; + int rv; + int i; + + VERBOSE(("IRET_pm: RETURN-OUTER-PRIVILEGE-LEVEL")); + + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + if (CPU_INST_OP32) { + SS_POP_CHECK(sp, 20); + new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16); + } else { + SS_POP_CHECK(sp, 10); + new_sp = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 6); + new_ss = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 8); + } + VERBOSE(("IRET_pm: new_sp = 0x%08x, new_ss = 0x%04x", new_sp, new_ss)); + + rv = parse_selector(&ss_sel, new_ss); + if (rv < 0) { + VERBOSE(("IRET_pm: parse_selector (selector = %04x, rv = %d)", ss_sel.selector, rv)); + EXCEPTION(GP_EXCEPTION, (rv == -2) ? 0 : ss_sel.idx); + } + + /* check privilege level */ + if (ss_sel.rpl != cs_sel->rpl) { + VERBOSE(("IRET_pm: selector RPL[SS](%d) != RPL[CS](%d)", ss_sel.rpl, cs_sel->rpl)); + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } +#if 0 + if (ss_sel.desc.dpl != cs_sel->rpl) { + VERBOSE(("IRET_pm: segment DPL[SS](%d) != RPL[CS](%d)", ss_sel.desc.dpl, cs_sel->rpl)); + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + if (ss_sel.desc.rpl != cs_sel->rpl) { + VERBOSE(("IRET_pm: segment RPL[SS](%d) != RPL[CS](%d)", ss_sel.desc.rpl, cs_sel->rpl)); + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } +#endif + + /* stack segment must be writable data segment. */ + if (SEG_IS_SYSTEM(&ss_sel.desc)) { + VERBOSE(("IRET_pm: stack segment is system segment")); + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + if (SEG_IS_CODE(&ss_sel.desc)) { + VERBOSE(("IRET_pm: stack segment is code segment")); + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + if (!SEG_IS_WRITABLE_DATA(&ss_sel.desc)) { + VERBOSE(("IRET_pm: stack segment is read-only data segment")); + EXCEPTION(GP_EXCEPTION, ss_sel.idx); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + VERBOSE(("IRET_pm: stack segment is not present")); + EXCEPTION(SS_EXCEPTION, ss_sel.idx); + } + + /* check code segment limit */ + if (new_ip > cs_sel->desc.u.seg.limit) { + VERBOSE(("IRET_pm: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel->desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + mask = 0; + if (CPU_INST_OP32) + mask |= RF_FLAG; + if (CPU_STAT_CPL <= CPU_STAT_IOPL) + mask |= I_FLAG; + if (CPU_STAT_CPL == 0) { + mask |= IOPL_FLAG; + if (CPU_INST_OP32) { + mask |= VM_FLAG|VIF_FLAG|VIP_FLAG; + } + } + + /* set new register */ + load_cs(cs_sel->selector, &cs_sel->desc, cs_sel->rpl); + CPU_EIP = new_ip; + + load_ss(ss_sel.selector, &ss_sel.desc, cs_sel->rpl); + if (CPU_STAT_SS32) { + CPU_ESP = new_sp; + } else { + CPU_SP = (UINT16)new_sp; + } + + set_eflags(new_flags, mask); + + /* check segment register */ + for (i = 0; i < CPU_SEGREG_NUM; i++) { + if ((i != CPU_CS_INDEX) && (i != CPU_SS_INDEX)) { + sdp = &CPU_STAT_SREG(i); + if ((SEG_IS_DATA(sdp) || !SEG_IS_CONFORMING_CODE(sdp)) + && (sdp->dpl < CPU_STAT_CPL)) { + /* segment register is invalid */ + CPU_REGS_SREG(i) = 0; + memset(sdp, 0, sizeof(*sdp)); + } + } + } +} + +/*--- + * IRET_pm: new_flags & VM_FLAG + */ +static void CPUCALL +IRET_pm_return_to_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) +{ + UINT16 segsel[CPU_SEGREG_NUM]; + UINT32 sp; + UINT32 new_sp; + int i; + + VERBOSE(("IRET_pm: Interrupt procedure was in virtual-8086 mode: PE=1, VM=1 in flags image")); + + if (!CPU_INST_OP32) { + ia32_panic("IRET_pm: 16bit mode"); + } + + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + SS_POP_CHECK(sp, 36); + + new_sp = cpu_vmemoryread_d(CPU_SS_INDEX, sp + 12); + segsel[CPU_SS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 16); + segsel[CPU_ES_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 20); + segsel[CPU_DS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 24); + segsel[CPU_FS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 28); + segsel[CPU_GS_INDEX] = cpu_vmemoryread_w(CPU_SS_INDEX, sp + 32); + segsel[CPU_CS_INDEX] = new_cs; + + for (i = 0; i < CPU_SEGREG_NUM; i++) { + segdesc_init(i, segsel[i], &CPU_STAT_SREG(i)); + } + + CPU_ESP = new_sp; + CPU_EIP = new_ip & 0xffff; + + /* to VM86 mode */ + set_eflags(new_flags, IOPL_FLAG|I_FLAG|VM_FLAG|RF_FLAG); +} + +/*--- + * IRET_pm: VM_FLAG + */ +static void CPUCALL +IRET_pm_return_from_vm86(UINT16 new_cs, UINT32 new_ip, UINT32 new_flags) +{ + UINT stacksize; + + VERBOSE(("IRET_pm: virtual-8086 mode: VM=1")); + + if (CPU_STAT_IOPL == CPU_IOPL3) { + VERBOSE(("IRET_pm: virtual-8086 mode: IOPL=3")); +//vme_emulate: + if (CPU_INST_OP32) { + stacksize = 12; + } else { + stacksize = 6; + } + if (CPU_STAT_SS32) { + CPU_ESP += stacksize; + } else { + CPU_SP += stacksize; + } + + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_EIP = new_ip; + + set_eflags(new_flags, I_FLAG|RF_FLAG); + return; + } + VERBOSE(("IRET_pm: trap to virtual-8086 monitor: VM=1, IOPL<3")); +#if defined(USE_VME) + //if(CPU_CR4 & CPU_CR4_VME){ + // if((CPU_EFLAG & VIP_FLAG) || (CPU_EFLAG & T_FLAG)){ + // EXCEPTION(GP_EXCEPTION, 0); + // }else{ + // new_flags = (new_flags & ~VIF_FLAG) | ((new_flags & I_FLAG) << 10); // IF → VIFにコピー + // new_flags = (new_flags & ~(IOPL_FLAG|I_FLAG)) | (CPU_EFLAG & (IOPL_FLAG|I_FLAG)); // IF, IOPLは変更させない + // goto vme_emulate; + // } + //}else{ + // EXCEPTION(GP_EXCEPTION, 0); + //} + EXCEPTION(GP_EXCEPTION, 0); // XXX: 一応動いてるけど実装しないとまずい・・・? +#else + EXCEPTION(GP_EXCEPTION, 0); +#endif +} diff --git a/source/src/vm/np21/i386c/ia32/ctrlxfer.h b/source/src/vm/np21/i386c/ia32/ctrlxfer.h new file mode 100644 index 000000000..af896a5da --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/ctrlxfer.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_CTRLXFER_H__ +#define IA32_CPU_CTRLXFER_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void CPUCALL JMPfar_pm(UINT16 selector, UINT32 new_ip); +void CPUCALL CALLfar_pm(UINT16 selector, UINT32 new_ip); +void CPUCALL RETfar_pm(UINT nbytes); +void IRET_pm(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_CTRLXFER_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/debug.cpp b/source/src/vm/np21/i386c/ia32/debug.cpp new file mode 100644 index 000000000..bb4d7a99c --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/debug.cpp @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" + +#include "cpu.h" +#if defined(USE_FPU) +#include "instructions/fpu/fp.h" +#endif + + +/* + * register strings + */ +const char *reg8_str[CPU_REG_NUM] = { + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" +}; + +const char *reg16_str[CPU_REG_NUM] = { + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" +}; + +const char *reg32_str[CPU_REG_NUM] = { + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" +}; + +const char *sreg_str[CPU_SEGREG_NUM] = { + "es", "cs", "ss", "ds", "fs", "gs" +}; + +#include "../../common.h" + +char * +cpu_reg2str(void) +{ + static char buf[512]; + + my_sprintf_s (buf, sizeof(buf), + "At pc=%08x\n" + "eax=%08x ecx=%08x edx=%08x ebx=%08x\n" + "esp=%08x ebp=%08x esi=%08x edi=%08x\n" + "eip=%08x prev_eip=%08x\n" + "cs=%04x (%08x:%08x) ss=%04x (%08x:%08x) \n" + "ds=%04x (%08x:%08x) es=%04x (%08x:%08x) \n" + "fs=%04x (%08x:%08x) gs=%04x (%08x:%08x) \n" + "eflag=%08x " + /* ID VIP VIF AC VM RF NT IOPL OF DF IF TF SF ZF AF PF CF */ + "[ ID=%d VIP=%d VIF=%d AC=%d VM=%d RF=%d NT=%d IOPL=%d %s %s %s TF=%d %s %s %s %s %s ]\n" + "gdtr=%08x:%04x idtr=%08x:%04x\n" + "ldtr=%04x(%08x:%04x) tr=%04x(%08x:%04x)\n" + "cr0=%08x cr1=%08x cr2=%08x cr3=%08x cr4=%08x mxcsr=%08x", + (CPU_STAT_PM) ? ((CPU_STAT_SREGBASE(CPU_CS_INDEX) + CPU_PREV_EIP) & 0xffffffff) : (((CPU_STAT_SREGBASE(CPU_CS_INDEX) & 0xfffff) + (CPU_PREV_EIP & 0xffff)) & 0x000fffff), + CPU_EAX, CPU_ECX, CPU_EDX, CPU_EBX, + CPU_ESP, CPU_EBP,CPU_ESI, CPU_EDI, + CPU_EIP, CPU_PREV_EIP, + CPU_CS, CPU_STAT_SREGBASE(CPU_CS_INDEX), CPU_STAT_SREGLIMIT(CPU_CS_INDEX), + CPU_SS, CPU_STAT_SREGBASE(CPU_SS_INDEX), CPU_STAT_SREGLIMIT(CPU_SS_INDEX), + CPU_DS, CPU_STAT_SREGBASE(CPU_DS_INDEX), CPU_STAT_SREGLIMIT(CPU_DS_INDEX), + CPU_ES, CPU_STAT_SREGBASE(CPU_ES_INDEX), CPU_STAT_SREGLIMIT(CPU_ES_INDEX), + CPU_FS, CPU_STAT_SREGBASE(CPU_FS_INDEX), CPU_STAT_SREGLIMIT(CPU_FS_INDEX), + CPU_GS, CPU_STAT_SREGBASE(CPU_GS_INDEX), CPU_STAT_SREGLIMIT(CPU_GS_INDEX), + CPU_EFLAG, + (CPU_EFLAG & ID_FLAG) != 0, + (CPU_EFLAG & VIP_FLAG) != 0, + (CPU_EFLAG & VIF_FLAG) != 0, + (CPU_EFLAG & AC_FLAG) != 0, + (CPU_EFLAG & VM_FLAG) != 0, + (CPU_EFLAG & RF_FLAG) != 0, + (CPU_EFLAG & NT_FLAG) != 0, + (int)((CPU_EFLAG >> 12) & 3), + CPU_OV ? "OV" : "NV", + CPU_EFLAG & D_FLAG ? "UP" : "DN", + CPU_EFLAG & I_FLAG ? "DI" : "EI", + (CPU_EFLAG & T_FLAG) != 0, + CPU_EFLAG & S_FLAG ? "NG" : "PL", + CPU_EFLAG & Z_FLAG ? "ZR" : "NZ", + CPU_EFLAG & A_FLAG ? "AC" : "NA", + CPU_EFLAG & P_FLAG ? "PE" : "PO", + CPU_EFLAG & C_FLAG ? "CY" : "NC", + CPU_GDTR_BASE, CPU_GDTR_LIMIT, CPU_IDTR_BASE, CPU_IDTR_LIMIT, + CPU_LDTR, CPU_LDTR_BASE, CPU_LDTR_LIMIT, + CPU_TR, CPU_TR_BASE, CPU_TR_LIMIT, + CPU_CR0, CPU_CR1, CPU_CR2, CPU_CR3, CPU_CR4, CPU_MXCSR); + + return buf; +} + +static char * +a20str(void) +{ + static char buf[32]; + + my_sprintf_s(buf, sizeof(buf), "a20line=%s\n", + (CPU_STAT_ADRSMASK == 0xffffffff) ? "enable" : "disable"); + return buf; +} + +void +put_cpuinfo(void) +{ + char buf[2048]; + + strcpy(buf, cpu_reg2str()); + strcat(buf, "\n"); +#if defined(USE_FPU) + strcat(buf, fpu_reg2str()); + strcat(buf, "\n"); +#endif + strcat(buf, a20str()); + + printf("%s", buf); +} + +void +dbg_printf(const char *str, ...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + strcat(buf, "\n"); + + printf("%s", buf); +} + +void +memory_dump(int idx, UINT32 madr) +{ + UINT32 addr; + UINT32 size; + UINT32 s, i; + UINT8 buf[16]; + UINT8 c; + + if (madr < 0x80) { + size = madr + 0x80; + addr = 0; + } else { + size = 0x100; + addr = madr - 0x80; + } + VERBOSE(("memory dump\n--")); + for (s = 0; s < size; s++) { + if ((s % 16) == 0) { + VERBOSE(("%08x: ", addr + s)); + memset(buf, '.', sizeof(buf)); + } + + c = cpu_vmemoryread(idx, addr + s); + VERBOSE(("%02x ", c)); + if (c >= 0x20 && c <= 0x7e) + buf[s % 16] = c; + + if ((s % 16) == 15) { + VERBOSE(("| ")); + for (i = 0; i < sizeof(buf); i++) + VERBOSE(("%c", buf[i])); + VERBOSE(("\n")); + } + } +} + +void +gdtr_dump(UINT32 base, UINT limit) +{ + UINT32 v[2]; + UINT i; + + VERBOSE(("GDTR_DUMP: GDTR_BASE = 0x%08x, GDTR_LIMIT = 0x%04x", base, limit)); + + for (i = 0; i < limit; i += 8) { + v[0] = cpu_kmemoryread_d(base + i); + v[1] = cpu_kmemoryread_d(base + i + 4); + VERBOSE(("GDTR_DUMP: %08x: %08x%08x", base + i, v[0], v[1])); + } +} + +void +ldtr_dump(UINT32 base, UINT limit) +{ + UINT32 v[2]; + UINT i; + + VERBOSE(("LDTR_DUMP: LDTR_BASE = 0x%08x, LDTR_LIMIT = 0x%04x", base, limit)); + + for (i = 0; i < limit; i += 8) { + v[0] = cpu_kmemoryread_d(base + i); + v[1] = cpu_kmemoryread_d(base + i + 4); + VERBOSE(("LDTR_DUMP: %08x: %08x%08x", base + i, v[0], v[1])); + } +} + +void +idtr_dump(UINT32 base, UINT limit) +{ + UINT32 v[2]; + UINT i; + + VERBOSE(("IDTR_DUMP: IDTR_BASE = 0x%08x, IDTR_LIMIT = 0x%04x", base, limit)); + + for (i = 0; i < limit; i += 8) { + v[0] = cpu_kmemoryread_d(base + i); + v[1] = cpu_kmemoryread_d(base + i + 4); + VERBOSE(("IDTR_DUMP: %08x: %08x%08x", base + i, v[0], v[1])); + } +} + +void +tr_dump(UINT16 selector, UINT32 base, UINT limit) +{ + UINT32 v; + UINT i; + + VERBOSE(("TR_DUMP: selector = %04x", selector)); + + for (i = 0; i < limit; i += 4) { + v = cpu_kmemoryread_d(base + i); + VERBOSE(("TR_DUMP: %08x: %08x", base + i, v)); + } +} + +UINT32 +pde_dump(UINT32 base, int idx) +{ + UINT32 paddr; + UINT32 v; + int i; + + if (idx < 0 && idx > -8192) { + idx = -idx; + VERBOSE(("PDE_DUMP: address = 0x%08x, num = %d", base, idx)); + for (i = 0; i < idx; i++) { + paddr = (base & CPU_CR3_PD_MASK) | (idx << 2); + v = cpu_memoryread_d(paddr); + VERBOSE(("PDE_DUMP: 0x%08x: %08x", paddr, v)); + } + paddr = 0; + } else if (idx < 8192) { + VERBOSE(("PDE_DUMP: address = 0x%08x", base)); + paddr = (base & CPU_CR3_PD_MASK) | (idx << 2); + v = cpu_memoryread_d(paddr); + VERBOSE(("PDE_DUMP: 0x%08x: %08x", paddr, v)); + } else { + VERBOSE(("PDE_DUMP: invalid idx (%d)", idx)); + paddr = 0; + } + + return paddr; +} + +void +segdesc_dump(descriptor_t *sdp) +{ +#if defined(DEBUG) + const char *s; + + __ASSERT(sdp != NULL); + + VERBOSE(("dump descriptor: %p", sdp)); + + VERBOSE(("valid : %s", SEG_IS_VALID(sdp) ? "true" : "false")); + VERBOSE(("present : %s", SEG_IS_PRESENT(sdp) ? "true" : "false")); + VERBOSE(("DPL : %d", sdp->dpl)); + VERBOSE(("type : %d", sdp->type)); + VERBOSE(("kind : %s", SEG_IS_SYSTEM(sdp) ? "system" : "code/data")); + if (!SEG_IS_SYSTEM(sdp)) { + if (SEG_IS_CODE(sdp)) { + VERBOSE(("type : %dbit %sconforming code", + SEG_IS_32BIT(sdp) ? 32 : 16, + SEG_IS_CONFORMING_CODE(sdp) ? "" : "non-")); + VERBOSE(("access : execute%s", + SEG_IS_READABLE_CODE(sdp) ? "/read" : "")); + } else { + VERBOSE(("type : %dbit expand-%s data", + SEG_IS_32BIT(sdp) ? 32 : 16, + SEG_IS_EXPANDDOWN_DATA(sdp) ? "down" : "up")); + VERBOSE(("access : read%s", + SEG_IS_WRITABLE_DATA(sdp) ? "/write" : "")); + } + VERBOSE(("4k scale : %s", sdp->u.seg.g ? "true" : "false")); + VERBOSE(("baseadr : 0x%08x", sdp->u.seg.segbase)); + VERBOSE(("limit : 0x%08x", sdp->u.seg.limit)); + } else { + switch (sdp->type) { + case CPU_SYSDESC_TYPE_LDT: /* LDT */ + VERBOSE(("type : LDT")); + VERBOSE(("4k scale : %s", sdp->u.seg.g ? "true" : "false")); + VERBOSE(("baseadr : 0x%08x", sdp->u.seg.segbase)); + VERBOSE(("limit : 0x%08x", sdp->u.seg.limit)); + break; + + case CPU_SYSDESC_TYPE_TASK: /* task gate */ + VERBOSE(("type : task gate")); + VERBOSE(("selector : 0x%04x", sdp->u.gate.selector)); + break; + + case CPU_SYSDESC_TYPE_TSS_16: /* 286 TSS */ + case CPU_SYSDESC_TYPE_TSS_BUSY_16: /* 286 Busy TSS */ + case CPU_SYSDESC_TYPE_TSS_32: /* 386 TSS */ + case CPU_SYSDESC_TYPE_TSS_BUSY_32: /* 386 Busy TSS */ + VERBOSE(("type : %dbit %sTSS", + (sdp->type & CPU_SYSDESC_TYPE_32BIT) ? 32 : 16, + (sdp->type & CPU_SYSDESC_TYPE_TSS_BUSY_IND) ? + "Busy " : "")); + VERBOSE(("4k scale : %s", sdp->u.seg.g ? "true" : "false")); + VERBOSE(("baseadr : 0x%08x", sdp->u.seg.segbase)); + VERBOSE(("limit : 0x%08x", sdp->u.seg.limit)); + break; + + case CPU_SYSDESC_TYPE_CALL_16: /* 286 call gate */ + case CPU_SYSDESC_TYPE_INTR_16: /* 286 interrupt gate */ + case CPU_SYSDESC_TYPE_TRAP_16: /* 286 trap gate */ + case CPU_SYSDESC_TYPE_CALL_32: /* 386 call gate */ + case CPU_SYSDESC_TYPE_INTR_32: /* 386 interrupt gate */ + case CPU_SYSDESC_TYPE_TRAP_32: /* 386 trap gate */ + switch (sdp->type & CPU_SYSDESC_TYPE_MASKBIT) { + case CPU_SYSDESC_TYPE_CALL: + s = "call"; + break; + + case CPU_SYSDESC_TYPE_INTR: + s = "interrupt"; + break; + + case CPU_SYSDESC_TYPE_TRAP: + s = "trap"; + break; + + default: + s = "unknown"; + break; + } + VERBOSE(("type : %c86 %s gate", + (sdp->type & CPU_SYSDESC_TYPE_32BIT) ? '3':'2', s)); + VERBOSE(("selector : 0x%04x", sdp->u.gate.selector)); + VERBOSE(("offset : 0x%08x", sdp->u.gate.offset)); + VERBOSE(("count : %d", sdp->u.gate.count)); + break; + + case 0: case 8: case 10: case 13: /* reserved */ + default: + VERBOSE(("type : unknown descriptor")); + break; + } + } +#endif +} + +UINT32 +convert_laddr_to_paddr(UINT32 laddr) +{ + UINT32 paddr; /* physical address */ + UINT32 pde_addr; /* page directory entry address */ + UINT32 pde; /* page directory entry */ + UINT32 pte_addr; /* page table entry address */ + UINT32 pte; /* page table entry */ + + pde_addr = (CPU_CR3 & CPU_CR3_PD_MASK) | ((laddr >> 20) & 0xffc); + pde = cpu_memoryread_d(pde_addr); + + if ((CPU_CR4 & CPU_CR4_PSE) && (pde & CPU_PDE_PAGE_SIZE)) { + /* 4MB page size */ + paddr = (pde & CPU_PDE_4M_BASEADDR_MASK) | (laddr & 0x003fffff); + } else { + /* 4KB page size */ + pte_addr = (pde & CPU_PDE_BASEADDR_MASK) | ((laddr >> 10) & 0xffc); + pte = cpu_memoryread_d(pte_addr); + paddr = (pte & CPU_PTE_BASEADDR_MASK) | (laddr & 0x00000fff); + } + return paddr; +} + +UINT32 +convert_vaddr_to_paddr(unsigned int idx, UINT32 offset) +{ + descriptor_t *sdp; + UINT32 laddr; + + if (idx < CPU_SEGREG_NUM) { + sdp = &CPU_STAT_SREG(idx); + if (SEG_IS_VALID(sdp)) { + laddr = CPU_STAT_SREGBASE(idx) + offset; + return convert_laddr_to_paddr(laddr); + } + } + return 0; +} diff --git a/source/src/vm/np21/i386c/ia32/disasm.cpp b/source/src/vm/np21/i386c/ia32/disasm.cpp new file mode 100644 index 000000000..c8a483a93 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/disasm.cpp @@ -0,0 +1,863 @@ +/* + * Copyright (c) 2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "inst_table.h" + + +/* + * opcode strings + */ +static const char *opcode_1byte[2][256] = { +/* 16bit */ +{ +/*00*/ "addb", "addw", "addb", "addw", "addb", "addw", "push", "pop", + "orb", "orw", "orb", "orw", "orb", "orw", "push", NULL, +/*10*/ "adcb", "adcw", "adcb", "adcw", "adcb", "adcw", "push", "pop", + "sbbb", "sbbw", "sbbb", "sbbw", "sbbb", "sbbw", "push", "pop", +/*20*/ "andb", "andw", "andb", "andw", "andb", "andw", NULL, "daa", + "subb", "subw", "subb", "subw", "subb", "subw", NULL, "das", +/*30*/ "xorb", "xorw", "xorb", "xorw", "xorb", "xorw", NULL, "aaa", + "cmpb", "cmpw", "cmpb", "cmpw", "cmpb", "cmpw", NULL, "aas", +/*40*/ "incw", "incw", "incw", "incw", "incw", "incw", "incw", "incw", + "decw", "decw", "decw", "decw", "decw", "decw", "decw", "decw", +/*50*/ "push", "push", "push", "push", "push", "push", "push", "push", + "pop", "pop", "pop", "pop", "pop", "pop", "pop", "pop", +/*60*/ "pusha", "popa", "bound", "arpl", NULL, NULL, NULL, NULL, + "push", "imul", "push", "imul", "insb", "insw", "outsb", "outsw", +/*70*/ "jo", "jno", "jc", "jnc", "jz", "jnz", "jna", "ja", + "js", "jns", "jp", "jnp", "jl", "jnl", "jle", "jnle", +/*80*/ NULL, NULL, NULL, NULL, "testb", "testw", "xchgb", "xchgw", + "movb", "movw", "movb", "movw", "movw", "lea", "movw", "pop", +/*90*/ "nop", "xchgw", "xchgw", "xchgw", "xchgw", "xchgw", "xchgw", "xchgw", + "cbw", "cwd", "callf", "fwait", "pushf", "popf", "sahf", "lahf", +/*a0*/ "movb", "movw", "movb", "movw", "movsb", "movsw", "cmpsb", "cmpsw", + "testb", "testw", "stosb", "stosw", "lodsb", "lodsw", "scasb", "scasw", +/*b0*/ "movb", "movb", "movb", "movb", "movb", "movb", "movb", "movb", + "movw", "movw", "movw", "movw", "movw", "movw", "movw", "movw", +/*c0*/ NULL, NULL, "ret", "ret", "les", "lds", "movb", "movw", + "enter", "leave", "retf", "retf", "int3", "int", "into", "iret", +/*d0*/ NULL, NULL, NULL, NULL, "aam", "aad", "salc", "xlat", + "esc0", "esc1", "esc2", "esc3", "esc4", "esc5", "esc6", "esc7", +/*e0*/ "loopne","loope", "loop", "jcxz", "inb", "inw", "outb", "outw", + "call", "jmp", "jmpf", "jmp", "inb", "inw", "outb", "outw", +/*f0*/ "lock:", "int1", "repne", "repe", "hlt", "cmc", NULL, NULL, + "clc", "stc", "cli", "sti", "cld", "std", NULL, NULL, +}, +/* 32bit */ +{ +/*00*/ "addb", "addl", "addb", "addl", "addb", "addl", "pushl", "popl", + "orb", "orl", "orb", "orl", "orb", "orl", "pushl", NULL, +/*10*/ "adcb", "adcl", "adcb", "adcl", "adcb", "adcl", "pushl", "popl", + "sbbb", "sbbl", "sbbb", "sbbl", "sbbb", "sbbl", "pushl", "popl", +/*20*/ "andb", "andl", "andb", "andl", "andb", "andl", NULL, "daa", + "subb", "subl", "subb", "subl", "subb", "subl", NULL, "das", +/*30*/ "xorb", "xorl", "xorb", "xorl", "xorb", "xorl", NULL, "aaa", + "cmpb", "cmpl", "cmpb", "cmpl", "cmpb", "cmpl", NULL, "aas", +/*40*/ "incl", "incl", "incl", "incl", "incl", "incl", "incl", "incl", + "decl", "decl", "decl", "decl", "decl", "decl", "decl", "decl", +/*50*/ "pushl", "pushl", "pushl", "pushl", "pushl", "pushl", "pushl", "pushl", + "popl", "popl", "popl", "popl", "popl", "popl", "popl", "pop", +/*60*/ "pushad","popad", "bound", "arpl", NULL, NULL, NULL, NULL, + "pushl", "imul", "pushl", "imul", "insb", "insl", "outsb", "outsl", +/*70*/ "jo", "jno", "jc", "jnc", "jz", "jnz", "jna", "ja", + "js", "jns", "jp", "jnp", "jl", "jnl", "jle", "jnle", +/*80*/ NULL, NULL, NULL, NULL, "testb", "testl", "xchgb", "xchgl", + "movb", "movl", "movb", "movl", "movl", "lea", "movl", "popl", +/*90*/ "nop", "xchgl", "xchgl", "xchgl", "xchgl", "xchgl", "xchgl", "xchgl", + "cwde", "cdq", "callfl","fwait", "pushfd","popfd", "sahf", "lahf", +/*a0*/ "movb", "movl", "movb", "movl", "movsb", "movsd", "cmpsb", "cmpsd", + "testb", "testl", "stosb", "stosd", "lodsb", "lodsd", "scasb", "scasd", +/*b0*/ "movb", "movb", "movb", "movb", "movb", "movb", "movb", "movb", + "movl", "movl", "movl", "movl", "movl", "movl", "movl", "movl", +/*c0*/ NULL, NULL, "ret", "ret", "les", "lds", "movb", "movl", + "enter", "leave", "retf", "retf", "int3", "int", "into", "iretd", +/*d0*/ NULL, NULL, NULL, NULL, "aam", "aad", "salc", "xlat", + "esc0", "esc1", "esc2", "esc3", "esc4", "esc5", "esc6", "esc7", +/*e0*/ "loopne","loope", "loop", "jecxz", "inb", "inl", "outb", "outl", + "call", "jmp", "jmpf", "jmp", "inb", "inl", "outb", "outl", +/*f0*/ "lock:", "int1", "repne", "repe", "hlt", "cmc", NULL, NULL, + "clc", "stc", "cli", "sti", "cld", "std", NULL, NULL, +} +}; + +static const char *opcode_2byte[2][256] = { +/* 16bit */ +{ +/*00*/ NULL, NULL, "lar", "lsl", + NULL, "loadall", "clts", NULL, + "invd", "wbinvd", NULL, "UD2", + NULL, "prefetch", "femms", NULL, +/*10*/ NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*20*/ "movl", "movl", "movl", "movl", + "movl", NULL, "movl", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*30*/ "wrmsr", "rdtsc", "rdmsr", "rdpmc", + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*40*/ "cmovo", "cmovno", "cmovc", "cmovnc", + "cmovz", "cmovnz", "cmovna", "cmova", + "cmovs", "cmovns", "cmovp", "cmovnp", + "cmovl", "cmovnl", "cmovle", "cmovnle", +/*50*/ NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*60*/ "PUNPCKLBW", "PUNPCKLWD", "PUNPCKLDQ", "PACKSSWB", + "PCMPGTB", "PCMPGTW", "PCMPGTD", "PACKUSWB", + "PUNPCKHBW", "PUNPCKHWD", "PUNPCKHDQ", "PACKSSDW", + NULL, NULL, "MOVD", "MOVQ", +/*70*/ NULL, "PSxxW", "PSxxD", "PSxxQ", + "PCMPEQB", "PCMPEQW", "PCMPEQD", "EMMS", + NULL, NULL, NULL, NULL, + NULL, NULL, "MOVD", "MOVQ", +/*80*/ "jo", "jno", "jc", "jnc", + "jz", "jnz", "jna", "ja", + "js", "jns", "jp", "jnp", + "jl", "jnl", "jle", "jnle", +/*90*/ "seto", "setno", "setc", "setnc", + "setz", "setnz", "setna", "seta", + "sets", "setns", "setp", "setnp", + "setl", "setnl", "setle", "setnle", +/*a0*/ "push", "pop", "cpuid", "bt", + "shldb", "shldw", /*"cmpxchgb"*/ "int6","cmpxchgw", + "push", "pop", "rsm", "bts", + "shrdb", "shrdw", NULL, "imul", +/*b0*/ "cmpxchgb","cmpxchgw","lss", "btr", + "lfs", "lgs", "movzb", "movzw", + NULL, "UD2", NULL, "btc", + "bsf", "bsr", "movsb", "movsw", +/*c0*/ "xaddb", "xaddw", NULL, NULL, + NULL, NULL, NULL, NULL, + "bswap", "bswap", "bswap", "bswap", + "bswap", "bswap", "bswap", "bswap", +/*d0*/ NULL, "PSRLW", "PSRLD", "PSRLQ", + NULL, "PMULLW", NULL, NULL, + "PSUBUSB", "PSUBUSW", NULL, "PAND", + "PADDUSB", "PADDUSW", NULL, "PANDN", +/*e0*/ NULL, "PSRAW", "PSRAD", NULL, + "PMULHUW", "PMULHW", NULL, NULL, + "PSUBSB", "PSUBSW", NULL, "POR", + "PADDSB", "PADDSW", NULL, "PXOR", +/*f0*/ NULL, "PSLLW", "PSLLD", "PSLLQ", + NULL, "PMADDWD", NULL, NULL, + "PSUBB", "PSUBW", "PSUBD", NULL, + "PADDB", "PADDW", "PADDD", NULL, +}, +/* 32bit */ +{ +/*00*/ NULL, NULL, "lar", "lsl", + NULL, "loadall", "clts", NULL, + "invd", "wbinvd", NULL, "UD2", + NULL, "prefetch", "femms", NULL, +/*10*/ NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*20*/ "movl", "movl", "movl", "movl", + "movl", NULL, "movl", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*30*/ "wrmsr", "rdtsc", "rdmsr", NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*40*/ "cmovo", "cmovno", "cmovc", "cmovnc", + "cmovz", "cmovnz", "cmovna", "cmova", + "cmovs", "cmovns", "cmovp", "cmovnp", + "cmovl", "cmovnl", "cmovle", "cmovnle", +/*50*/ NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +/*60*/ "PUNPCKLBW", "PUNPCKLWD", "PUNPCKLDQ", "PACKSSWB", + "PCMPGTB", "PCMPGTW", "PCMPGTD", "PACKUSWB", + "PUNPCKHBW", "PUNPCKHWD", "PUNPCKHDQ", "PACKSSDW", + NULL, NULL, "MOVD", "MOVQ", +/*70*/ NULL, "PSxxW", "PSxxD", "PSxxQ", + "PCMPEQB", "PCMPEQW", "PCMPEQD", "EMMS", + NULL, NULL, NULL, NULL, + NULL, NULL, "MOVD", "MOVQ", +/*80*/ "jo", "jno", "jc", "jnc", + "jz", "jnz", "jna", "ja", + "js", "jns", "jp", "jnp", + "jl", "jnl", "jle", "jnle", +/*90*/ "seto", "setno", "setc", "setnc", + "setz", "setnz", "setna", "seta", + "sets", "setns", "setp", "setnp", + "setl", "setnl", "setle", "setnle", +/*a0*/ "push", "pop", "cpuid", "bt", + "shldb", "shldl", /*"cmpxchgb"*/"int6","cmpxchgl", + "push", "pop", "rsm", "bts", + "shrdb", "shrdl", NULL, "imul", +/*b0*/ "cmpxchgb","cmpxchgd","lss", "btr", + "lfs", "lgs", "movzbl", "movzwl", + NULL, "UD2", NULL, "btc", + "bsf", "bsr", "movsbl", "movswl", +/*c0*/ "xaddb", "xaddl", NULL, NULL, + NULL, NULL, NULL, NULL, + "bswapl", "bswapl", "bswapl", "bswapl", + "bswapl", "bswapl", "bswapl", "bswapl", +/*d0*/ NULL, "PSRLW", "PSRLD", "PSRLQ", + NULL, "PMULLW", NULL, NULL, + "PSUBUSB", "PSUBUSW", NULL, "PAND", + "PADDUSB", "PADDUSW", NULL, "PANDN", +/*e0*/ NULL, "PSRAW", "PSRAD", NULL, + "PMULHUW", "PMULHW", NULL, NULL, + "PSUBSB", "PSUBSW", NULL, "POR", + "PADDSB", "PADDSW", NULL, "PXOR", +/*f0*/ NULL, "PSLLW", "PSLLD", "PSLLQ", + NULL, "PMADDWD", NULL, NULL, + "PSUBB", "PSUBW", "PSUBD", NULL, + "PADDB", "PADDW", "PADDD", NULL, +} +}; + +static const char *opcode_0x8x[2][2][8] = { +/* 16bit */ +{ + { "addb", "orb", "adcb", "sbbb", "andb", "subb", "xorb", "cmpb" }, + { "addw", "orw", "adcw", "sbbw", "andw", "subw", "xorw", "cmpw" } +}, +/* 32bit */ +{ + { "addb", "orb", "adcb", "sbbb", "andb", "subb", "xorb", "cmpb" }, + { "addl", "orl", "adcl", "sbbl", "andl", "subl", "xorl", "cmpl" } +} +}; + +static const char *opcode_shift[2][2][8] = { +/* 16bit */ +{ + { "rolb", "rorb", "rclb", "rcrb", "shlb", "shrb", "shlb", "sarb" }, + { "rolw", "rorw", "rclw", "rcrw", "shlw", "shrw", "shlw", "sarw" } +}, +/* 32bit */ +{ + { "rolb", "rorb", "rclb", "rcrb", "shlb", "shrb", "shlb", "sarb" }, + { "roll", "rorl", "rcll", "rcrl", "shll", "shrl", "shll", "sarl" } +}, +}; + +static const char *opcode_0xf6[2][2][8] = { +/* 16bit */ +{ + { "testb", "testb", "notb", "negb", "mul", "imul", "div", "idiv" }, + { "testw", "testw", "notw", "negw", "mulw", "imulw", "divw", "idivw" } +}, +/* 32bit */ +{ + { "testb", "testb", "notb", "negb", "mul", "imul", "div", "idiv" }, + { "testl", "testl", "notl", "negl", "mull", "imull", "divl", "idivl" } +}, +}; + +static const char *opcode_0xfe[2][2][8] = { +/* 16bit */ +{ + { "incb", "decb", NULL, NULL, NULL, NULL, NULL, NULL }, + { "incw", "decw", "call", "callf", "jmp", "jmpf", "push", NULL } +}, +/* 32bit */ +{ + { "incb", "decb", NULL, NULL, NULL, NULL, NULL, NULL }, + { "incl", "decl", "call", "callf", "jmp", "jmpf", "pushl", NULL } +} +}; + +static const char *opcode2_g6[8] = { + "sldt", "str", "lldt", "ltr", "verr", "verw", NULL, NULL +}; + +static const char *opcode2_g7[8] = { + "sgdt", "sidt", "lgdt", "lidt", "smsw", NULL, "lmsw", "invlpg" +}; + +static const char *opcode2_g8[8] = { + NULL, NULL, NULL, NULL, "bt", "bts", "btr", "btc" +}; + +static const char *opcode2_g9[8] = { + NULL, "cmpxchg8b", NULL, NULL, NULL, NULL, NULL, NULL +}; + +#if 0 +static const char *sep[2] = { " ", ", " }; +#endif + +/** + * string copy + */ +static char * +ncpy(char *dest, const char *src, size_t n) +{ + strncpy(dest, src, n); + dest[n - 1] = '\0'; + return dest; +} + +/** + * string copy at + */ +static char * +ncat(char *dest, const char *src, size_t n) +{ + const size_t offset = strlen(dest); + ncpy(dest + offset, src, n - offset); + return dest; +} + +/* + * fetch memory + */ +static int +convert_address(disasm_context_t *ctx) +{ + UINT32 pde_addr; /* page directory entry address */ + UINT32 pde; /* page directory entry */ + UINT32 pte_addr; /* page table entry address */ + UINT32 pte; /* page table entry */ + UINT32 addr; + + if (CPU_STAT_SREG(CPU_CS_INDEX).valid) { + addr = CPU_STAT_SREGBASE(CPU_CS_INDEX) + ctx->eip; + if (CPU_STAT_PAGING) { + pde_addr = CPU_STAT_PDE_BASE + ((addr >> 20) & 0xffc); + pde = cpu_memoryread_d(pde_addr); + /* XXX: check */ + pte_addr = (pde & CPU_PDE_BASEADDR_MASK) + ((addr >> 10) & 0xffc); + pte = cpu_memoryread_d(pte_addr); + /* XXX: check */ + addr = (pte & CPU_PTE_BASEADDR_MASK) + (addr & 0x00000fff); + } + ctx->val = addr; + return 0; + } + return 1; +} + +static int +disasm_codefetch_1(disasm_context_t *ctx) +{ + UINT8 val; + int rv; + + rv = convert_address(ctx); + if (rv) + return rv; + + val = cpu_memoryread(ctx->val); + ctx->val = val; + + ctx->opbyte[ctx->nopbytes++] = (UINT8)ctx->val; + ctx->eip++; + + return 0; +} + +#if 0 +static int +disasm_codefetch_2(disasm_context_t *ctx) +{ + UINT16 val; + int rv; + + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + val = (UINT16)(ctx->val & 0xff); + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + val |= (UINT16)(ctx->val & 0xff) << 8; + + ctx->val = val; + return 0; +} + +static int +disasm_codefetch_4(disasm_context_t *ctx) +{ + UINT32 val; + int rv; + + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + val = ctx->val & 0xff; + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + val |= (UINT32)(ctx->val & 0xff) << 8; + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + val |= (UINT32)(ctx->val & 0xff) << 16; + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + val |= (UINT32)(ctx->val & 0xff) << 24; + + ctx->val = val; + return 0; +} + +/* + * get effective address. + */ + +static int +ea16(disasm_context_t *ctx, char *buf, size_t size) +{ + static const char *ea16_str[8] = { + "bx + si", "bx + di", "bp + si", "bp + di", + "si", "di", "bp", "bx" + }; + UINT32 val; + UINT mod, rm; + int rv; + + mod = (ctx->modrm >> 6) & 3; + rm = ctx->modrm & 7; + + if (mod == 0) { + if (rm == 6) { + /* disp16 */ + rv = disasm_codefetch_2(ctx); + if (rv) + return rv; + + _snprintf(buf, size, "[0x%04x]", ctx->val); + } else { + _snprintf(buf, size, "[%s]", ea16_str[rm]); + } + } else { + if (mod == 1) { + /* disp8 */ + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + + val = ctx->val; + if (val & 0x80) { + val |= 0xff00; + } + } else { + /* disp16 */ + rv = disasm_codefetch_2(ctx); + if (rv) + return rv; + + val = ctx->val; + } + _snprintf(buf, size, "[%s + 0x%04x]", ea16_str[rm], val); + } + + return 0; +} + +static int +ea32(disasm_context_t *ctx, char *buf, size_t size) +{ + char tmp[32]; + UINT count[9]; + UINT32 val; + UINT mod, rm; + UINT sib; + UINT scale; + UINT idx; + UINT base; + int rv; + int i, n; + + memset(count, 0, sizeof(count)); + + mod = (ctx->modrm >> 6) & 3; + rm = ctx->modrm & 7; + + /* SIB */ + if (rm == 4) { + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + + sib = ctx->val; + scale = (sib >> 6) & 3; + idx = (sib >> 3) & 7; + base = sib & 7; + + /* base */ + if (mod == 0 && base == 5) { + /* disp32 */ + rv = disasm_codefetch_4(ctx); + if (rv) + return rv; + count[8] += ctx->val; + } else { + count[base]++; + } + + /* index & scale */ + if (idx != 4) { + count[idx] += 1 << scale; + } + } + + /* MOD/RM */ + if (mod == 0 && rm == 5) { + /* disp32 */ + rv = disasm_codefetch_4(ctx); + if (rv) + return rv; + count[8] += ctx->val; + } else { + /* mod */ + if (mod == 1) { + /* disp8 */ + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + + val = ctx->val; + if (val & 0x80) { + val |= 0xffffff00; + } + count[8] += val; + } else if (mod == 2) { + /* disp32 */ + rv = disasm_codefetch_4(ctx); + if (rv) + return rv; + count[8] += ctx->val; + } + + /* rm */ + if (rm != 4) { + count[rm]++; + } + } + + ncpy(buf, "[", size); + for (n = 0, i = 0; i < 8; i++) { + if (count[i] != 0) { + if (n > 0) { + ncat(buf, " + ", size); + } + if (count[i] > 1) { + _snprintf(tmp, size, "%s * %d", + reg32_str[i], count[i]); + } else { + ncpy(tmp, reg32_str[i], sizeof(tmp)); + } + ncat(buf, tmp, size); + n++; + } + } + if (count[8] != 0) { + if (n > 0) { + ncat(buf, " + ", size); + } + _snprintf(tmp, sizeof(tmp), "0x%08x", count[8]); + ncat(buf, tmp, size); + } + ncat(buf, "]", size); + + return 0; +} + +static int +ea(disasm_context_t *ctx) +{ + char buf[256]; + char tmp[8]; + size_t len; + int rv; + + memset(buf, 0, sizeof(buf)); + + if (!ctx->as32) + rv = ea16(ctx, buf, sizeof(buf)); + else + rv = ea32(ctx, buf, sizeof(buf)); + if (rv) + return rv; + + if (ctx->narg == 0) { + ncat(ctx->next, sep[0], ctx->remain); + } else { + ncat(ctx->next, sep[1], ctx->remain); + } + len = strlen(ctx->next); + len = (len < ctx->remain) ? len : ctx->remain; + ctx->next += len; + ctx->remain -= len; + + ctx->arg[ctx->narg++] = ctx->next; + if (ctx->useseg) { + _snprintf(tmp, sizeof(tmp), "%s:", sreg_str[ctx->seg]); + ncat(ctx->next, tmp, ctx->remain); + } + ncat(ctx->next, buf, ctx->remain); + len = strlen(ctx->next); + len = (len < ctx->remain) ? len : ctx->remain; + ctx->next += len; + ctx->remain -= len; + + return 0; +} +#endif + +/* + * get opcode + */ +static int +get_opcode(disasm_context_t *ctx) +{ + const char *opcode; + UINT8 op[3]; + int prefix; + size_t len; + int rv; + int i; + + for (prefix = 0; prefix < MAX_PREFIX; prefix++) { + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + + op[0] = (UINT8)(ctx->val & 0xff); + if (!(insttable_info[op[0]] & INST_PREFIX)) + break; + + if (ctx->prefix == 0) + ctx->prefix = ctx->next; + + switch (op[0]) { + case 0x26: /* ES: */ + case 0x2e: /* CS: */ + case 0x36: /* SS: */ + case 0x3e: /* DS: */ + ctx->useseg = TRUE; + ctx->seg = (op[0] >> 3) & 3; + break; + + case 0x64: /* FS: */ + case 0x65: /* GS: */ + ctx->useseg = TRUE; + ctx->seg = (op[0] - 0x64) + 4; + break; + + case 0x66: /* OPSize: */ + ctx->op32 = !CPU_STATSAVE.cpu_inst_default.op_32; + break; + + case 0x67: /* AddrSize: */ + ctx->as32 = !CPU_STATSAVE.cpu_inst_default.as_32; + break; + } + } + if (prefix == MAX_PREFIX) + return 1; + + if (ctx->prefix) { + for (i = 0; i < prefix - 1; i++) { + opcode = opcode_1byte[ctx->op32][ctx->opbyte[i]]; + if (opcode) { + ncat(ctx->next, opcode, ctx->remain); + ncat(ctx->next, " ", ctx->remain); + } + } + len = strlen(ctx->next); + len = (len < ctx->remain) ? len : ctx->remain; + ctx->next += len; + ctx->remain -= len; + } + + ctx->opcode[0] = op[0]; + opcode = opcode_1byte[ctx->op32][op[0]]; + if (opcode == NULL) { + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + + op[1] = (UINT8)(ctx->val & 0xff); + ctx->opcode[1] = op[1]; + + switch (op[0]) { + case 0x0f: + opcode = opcode_2byte[ctx->op32][op[1]]; + if (opcode == NULL) { + rv = disasm_codefetch_1(ctx); + if (rv) + return rv; + + op[2] = (UINT8)(ctx->val & 0xff); + ctx->opcode[2] = op[2]; + + switch (op[1]) { + case 0x00: + opcode = opcode2_g6[(op[2]>>3)&7]; + ctx->modrm = op[2]; + break; + + case 0x01: + opcode = opcode2_g7[(op[2]>>3)&7]; + ctx->modrm = op[2]; + break; + + case 0xba: + opcode = opcode2_g8[(op[2]>>3)&7]; + ctx->modrm = op[2]; + break; + + case 0xc7: + opcode = opcode2_g9[(op[2]>>3)&7]; + ctx->modrm = op[2]; + break; + } + } + break; + + case 0x80: case 0x81: case 0x82: case 0x83: + opcode = opcode_0x8x[ctx->op32][op[0]&1][(op[1]>>3)&7]; + ctx->modrm = op[1]; + break; + + case 0xc0: case 0xc1: + case 0xd0: case 0xd1: case 0xd2: case 0xd3: + opcode = opcode_shift[ctx->op32][op[0]&1][(op[1]>>3)&7]; + ctx->modrm = op[1]; + break; + + case 0xf6: case 0xf7: + opcode = opcode_0xf6[ctx->op32][op[0]&1][(op[1]>>3)&7]; + ctx->modrm = op[1]; + break; + + case 0xfe: case 0xff: + opcode = opcode_0xfe[ctx->op32][op[0]&1][(op[1]>>3)&7]; + ctx->modrm = op[1]; + break; + } + } + if (opcode == NULL) + return 1; + + ncat(ctx->next, opcode, ctx->remain); + + return 0; +} + +/* + * interface + */ +int +disasm(UINT32 *eip, disasm_context_t *ctx) +{ + int rv; + + memset(ctx, 0, sizeof(disasm_context_t)); + ctx->remain = sizeof(ctx->str) - 1; + ctx->next = ctx->str; + ctx->prefix = 0; + ctx->op = 0; + ctx->arg[0] = 0; + ctx->arg[1] = 0; + ctx->arg[2] = 0; + + ctx->eip = *eip; + ctx->op32 = CPU_STATSAVE.cpu_inst_default.op_32; + ctx->as32 = CPU_STATSAVE.cpu_inst_default.as_32; + ctx->seg = -1; + + ctx->baseaddr = ctx->eip; + ctx->pad = ' '; + + rv = get_opcode(ctx); + if (rv) { + memset(ctx, 0, sizeof(disasm_context_t)); + return rv; + } + *eip = ctx->eip; + + return 0; +} + +char * +cpu_disasm2str(UINT32 eip) +{ + static char output[2048]; + disasm_context_t d; + UINT32 eip2 = eip; + int rv; + + output[0] = '\0'; + rv = disasm(&eip2, &d); + if (rv == 0) { + char buf[256]; + char tmp[32]; + int len = d.nopbytes > 8 ? 8 : d.nopbytes; + int i; + + buf[0] = '\0'; + for (i = 0; i < len; i++) { + _snprintf(tmp, sizeof(tmp), "%02x ", d.opbyte[i]); + ncat(buf, tmp, sizeof(buf)); + } + for (; i < 8; i++) { + ncat(buf, " ", sizeof(buf)); + } + _snprintf(output, sizeof(output), "%04x:%08x: %s%s", + CPU_CS, eip, buf, d.str); + + if (i < d.nopbytes) { + char t[256]; + buf[0] = '\0'; + for (; i < d.nopbytes; i++) { + _snprintf(tmp, sizeof(tmp), "%02x ", + d.opbyte[i]); + ncat(buf, tmp, sizeof(buf)); + if ((i % 8) == 7) { + _snprintf(t, sizeof(t), + "\n : %s", buf); + ncat(output, t, sizeof(output)); + buf[0] = '\0'; + } + } + if ((i % 8) != 0) { + _snprintf(t, sizeof(t), + "\n : %s", buf); + ncat(output, t, sizeof(output)); + } + } + } + return output; +} diff --git a/source/src/vm/np21/i386c/ia32/exception.cpp b/source/src/vm/np21/i386c/ia32/exception.cpp new file mode 100644 index 000000000..12bec4c38 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/exception.cpp @@ -0,0 +1,711 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" +#include "../../../i386_np21.h" +const char *exception_str[EXCEPTION_NUM] = { + "DE_EXCEPTION", + "DB_EXCEPTION", + "NMI_EXCEPTION", + "BP_EXCEPTION", + "OF_EXCEPTION", + "BR_EXCEPTION", + "UD_EXCEPTION", + "NM_EXCEPTION", + "DF_EXCEPTION", + "CoProcesser Segment Overrun", + "TS_EXCEPTION", + "NP_EXCEPTION", + "SS_EXCEPTION", + "GP_EXCEPTION", + "PF_EXCEPTION", + "Reserved", + "MF_EXCEPTION", + "AC_EXCEPTION", + "MC_EXCEPTION", + "XF_EXCEPTION", +}; + +static const int exctype[EXCEPTION_NUM] = { + 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, +}; + +static const int dftable[4][4] = { + { 0, 0, 0, 1, }, + { 0, 1, 0, 1, }, + { 0, 1, 1, 1, }, + { 1, 1, 1, 1, }, +}; + +extern SINT32 __exception_set; +extern UINT32 __exception_pc; +extern UINT64 __exception_code; + +void CPUCALL +exception(int num, int error_code) +{ +#if defined(DEBUG) + extern int cpu_debug_rep_cont; + extern CPU_REGS cpu_debug_rep_regs; +#endif + int errorp = 0; + + __ASSERT((unsigned int)num < EXCEPTION_NUM); + +#if 0 + iptrace_out(); + debugwriteseg("execption.bin", &CPU_CS_DESC, CPU_PREV_EIP & 0xffff0000, 0x10000); +#endif + + VERBOSE(("exception: -------------------------------------------------------------- start")); + VERBOSE(("exception: %s, error_code = %x at %04x:%08x", exception_str[num], error_code, CPU_CS, CPU_PREV_EIP)); + VERBOSE(("%s", cpu_reg2str())); + VERBOSE(("code: %dbit(%dbit), address: %dbit(%dbit)", CPU_INST_OP32 ? 32 : 16, CPU_STATSAVE.cpu_inst_default.op_32 ? 32 : 16, CPU_INST_AS32 ? 32 : 16, CPU_STATSAVE.cpu_inst_default.as_32 ? 32 : 16)); +#if defined(DEBUG) + if (cpu_debug_rep_cont) { + VERBOSE(("rep: original regs: ecx=%08x, esi=%08x, edi=%08x", cpu_debug_rep_regs.reg[CPU_ECX_INDEX].d, cpu_debug_rep_regs.reg[CPU_ESI_INDEX].d, cpu_debug_rep_regs.reg[CPU_EDI_INDEX].d)); + } + VERBOSE(("%s", cpu_disasm2str(CPU_PREV_EIP))); +#endif + __exception_set = 1; + __exception_pc = device_cpu->get_pc(); + __exception_code = num; + + CPU_STAT_EXCEPTION_COUNTER_INC(); + if ((CPU_STAT_EXCEPTION_COUNTER >= 3) + || (CPU_STAT_EXCEPTION_COUNTER == 2 && CPU_STAT_PREV_EXCEPTION == DF_EXCEPTION)) { + /* Triple fault */ + ia32_panic("exception: catch triple fault!"); + } + + switch (num) { + case UD_EXCEPTION: /* (F) 無効オペコード */ + //ia32_warning("warning: undefined op!"); + //{ // TEST!! + // UINT32 op[5]; + // CPU_EIP = CPU_PREV_EIP; + // GET_PCBYTE(op[0]); + // GET_PCBYTE(op[1]); + // GET_PCBYTE(op[2]); + // GET_PCBYTE(op[3]); + // GET_PCBYTE(op[4]); + //} + case DE_EXCEPTION: /* (F) 除算エラー */ + case DB_EXCEPTION: /* (F/T) デバッグ */ + case BR_EXCEPTION: /* (F) BOUND の範囲外 */ + case NM_EXCEPTION: /* (F) デバイス使用不可 (FPU が無い) */ + case MF_EXCEPTION: /* (F) 浮動小数点エラー */ + CPU_EIP = CPU_PREV_EIP; + if (CPU_STATSAVE.cpu_stat.backout_sp) + CPU_ESP = CPU_PREV_ESP; + /*FALLTHROUGH*/ + case NMI_EXCEPTION: /* (I) NMI 割り込み */ + case BP_EXCEPTION: /* (T) ブレークポイント */ + case OF_EXCEPTION: /* (T) オーバーフロー */ + errorp = 0; + break; + + case DF_EXCEPTION: /* (A) ダブルフォルト (errcode: 0) */ + errorp = 1; + error_code = 0; + break; + + case AC_EXCEPTION: /* (F) アラインメントチェック (errcode: 0) */ + error_code = 0; + /*FALLTHROUGH*/ + case TS_EXCEPTION: /* (F) 無効 TSS (errcode) */ + case NP_EXCEPTION: /* (F) セグメント不在 (errcode) */ + case SS_EXCEPTION: /* (F) スタックセグメントフォルト (errcode) */ + case GP_EXCEPTION: /* (F) 一般保護例外 (errcode) */ + case PF_EXCEPTION: /* (F) ページフォルト (errcode) */ + CPU_EIP = CPU_PREV_EIP; + if (CPU_STATSAVE.cpu_stat.backout_sp) + CPU_ESP = CPU_PREV_ESP; + errorp = 1; + break; + + default: + ia32_panic("exception: unknown exception (%d)", num); + break; + } +// device_cpu->out_debug_log("EXCEPTION: %s PC=%08X", exception_str[num], device_cpu->get_pc()); + + if (CPU_STAT_EXCEPTION_COUNTER >= 2) { + if (dftable[exctype[CPU_STAT_PREV_EXCEPTION]][exctype[num]]) { + num = DF_EXCEPTION; + errorp = 1; + error_code = 0; + } + } + CPU_STAT_PREV_EXCEPTION = num; + + VERBOSE(("exception: ---------------------------------------------------------------- end")); + + interrupt(num, INTR_TYPE_EXCEPTION, errorp, error_code); + CPU_STAT_EXCEPTION_COUNTER_CLEAR(); +#ifdef __cplusplus + throw(1); +#else + siglongjmp(exec_1step_jmpbuf, 1); +#endif +} + +/* + * コール・ゲート・ディスクリプタ + * + * 31 16 15 14 13 12 8 7 5 4 0 + * +------------------------------------+--+-----+----------+-----+---------+ + * | オフセット 31..16 | P| DPL | 0 D 1 0 0|0 0 0|カウント | 4 + * +------------------------------------+--+-----+----------+-----+---------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | セグメント・セレクタ | オフセット 15..0 | 0 + * +------------------------------------+-----------------------------------+ + */ + +/* + * 割り込みディスクリプタ + *-- + * タスク・ゲート + * + * 31 16 15 14 13 12 8 7 0 + * +------------------------------------+--+-----+----------+---------------+ + * | Reserved | P| DPL | 0 0 1 0 1| Reserved | 4 + * +------------------------------------+--+-----+----------+---------------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | TSS セグメント・セレクタ | Reserved | 0 + * +------------------------------------+-----------------------------------+ + *-- + * 割り込み・ゲート + * + * 31 16 15 14 13 12 8 7 5 4 0 + * +------------------------------------+--+-----+----------+-----+---------+ + * | オフセット 31..16 | P| DPL | 0 D 1 1 0|0 0 0|Reserved | 4 + * +------------------------------------+--+-----+----------+-----+---------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | セグメント・セレクタ | オフセット 15..0 | 0 + * +------------------------------------+-----------------------------------+ + *-- + * トラップ・ゲート + * + * 31 16 15 14 13 12 8 7 5 4 0 + * +------------------------------------+--+-----+----------+-----+---------+ + * | オフセット 31..16 | P| DPL | 0 D 1 1 1|0 0 0|Reserved | 4 + * +------------------------------------+--+-----+----------+-----+---------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | セグメント・セレクタ | オフセット 15..0 | 0 + * +------------------------------------+-----------------------------------+ + *-- + * DPL : ディスクリプタ特権レベル + * オフセット : プロシージャ・エントリ・ポイントまでのオフセット + * P : セグメント存在フラグ + * セレクタ : ディスティネーション・コード・セグメントのセグメント・セレクタ + * D : ゲートのサイズ.0 = 16 bit, 1 = 32 bit + */ + +static void CPUCALL interrupt_task_gate(const descriptor_t *gsdp, int intrtype, int errorp, int error_code); +static void CPUCALL interrupt_intr_or_trap(const descriptor_t *gsdp, int intrtype, int errorp, int error_code); + +void CPUCALL +interrupt(int num, int intrtype, int errorp, int error_code) +{ + descriptor_t gsd; + UINT idt_idx; + UINT32 new_ip; + UINT16 new_cs; + int exc_errcode; + + VERBOSE(("interrupt: num = 0x%02x, intrtype = %s, errorp = %s, error_code = %08x", num, (intrtype == INTR_TYPE_EXTINTR) ? "external" : (intrtype == INTR_TYPE_EXCEPTION ? "exception" : "softint"), errorp ? "on" : "off", error_code)); + +//#ifdef I86_PSEUDO_BIOS + if ((!CPU_STAT_PM || CPU_STAT_VM86) && intrtype == INTR_TYPE_SOFTINTR && device_bios != NULL) { +// uint16_t regs[8] = {CPU_AX, CPU_CX, CPU_DX, CPU_BX, CPU_SP, CPU_BP, CPU_SI, CPU_DI}; + uint32_t regs[8] = {CPU_EAX, CPU_ECX, CPU_EDX, CPU_EBX, CPU_ESP, CPU_EBP, CPU_ESI, CPU_EDI}; + uint16_t sregs[4] = {CPU_ES, CPU_CS, CPU_SS, CPU_DS}; + int32_t ZeroFlag = ((CPU_FLAG & Z_FLAG) ? 1 : 0); + int32_t CarryFlag = ((CPU_FLAG & C_FLAG) ? 1 : 0); + int cycles = 0; + uint64_t total_cycles = 0; +// if (device_bios->bios_int_i86(num, regs, sregs, &ZeroFlag, &CarryFlag)) { + if (device_bios->bios_int_ia32(num, regs, sregs, &ZeroFlag, &CarryFlag, &cycles, &total_cycles)) { + CPU_EAX = regs[0]; + CPU_ECX = regs[1]; + CPU_EDX = regs[2]; + CPU_EBX = regs[3]; + CPU_ESP = regs[4]; + CPU_EBP = regs[5]; + CPU_ESI = regs[6]; + CPU_EDI = regs[7]; + if (ZeroFlag) { + CPU_FLAG |= Z_FLAG; + } else { + CPU_FLAG &= ~Z_FLAG; + } + if (CarryFlag) { + CPU_FLAG |= C_FLAG; + } else { + CPU_FLAG &= ~C_FLAG; + } + CPU_WORKCLOCK(1000); // temporary + CPU_REMCLOCK -= cycles; + return; + } + } +//#endif + + CPU_SET_PREV_ESP(); + + if (!CPU_STAT_PM) { + /* real mode */ + CPU_WORKCLOCK(20); + + idt_idx = num * 4; + if (idt_idx + 3 > CPU_IDTR_LIMIT) { + VERBOSE(("interrupt: real-mode IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT)); + EXCEPTION(GP_EXCEPTION, idt_idx + 2); + } + + if ((intrtype == INTR_TYPE_EXTINTR) && CPU_STAT_HLT) { + VERBOSE(("interrupt: reset HTL in real mode")); + CPU_EIP++; + CPU_STAT_HLT = 0; + } + + REGPUSH0(REAL_FLAGREG); + REGPUSH0(CPU_CS); + REGPUSH0(CPU_IP); + + CPU_EFLAG &= ~(T_FLAG | I_FLAG | AC_FLAG | RF_FLAG); + CPU_TRAP = 0; + + new_ip = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx); + new_cs = cpu_memoryread_w(CPU_IDTR_BASE + idt_idx + 2); + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + } else { + /* protected mode */ + CPU_WORKCLOCK(200); + + VERBOSE(("interrupt: -------------------------------------------------------------- start")); + VERBOSE(("interrupt: old EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP)); + +#if defined(DEBUG) + if (num == 0x80) { + /* Linux, FreeBSD, NetBSD, OpenBSD system call */ + VERBOSE(("interrupt: syscall# = %d\n%s", CPU_EAX, cpu_reg2str())); + } +#endif + + idt_idx = num * 8; + exc_errcode = idt_idx + 2; + if (intrtype == INTR_TYPE_EXTINTR) + exc_errcode++; + + if (idt_idx + 7 > CPU_IDTR_LIMIT) { + VERBOSE(("interrupt: IDTR limit check failure (idx = 0x%04x, limit = 0x%08x", idt_idx, CPU_IDTR_LIMIT)); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + + /* load a gate descriptor from interrupt descriptor table */ + memset(&gsd, 0, sizeof(gsd)); + load_descriptor(&gsd, CPU_IDTR_BASE + idt_idx); + if (!SEG_IS_VALID(&gsd)) { + VERBOSE(("interrupt: gate descripter is invalid.")); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + if (!SEG_IS_SYSTEM(&gsd)) { + VERBOSE(("interrupt: gate descriptor is not system segment.")); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + + switch (gsd.type) { + case CPU_SYSDESC_TYPE_TASK: + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_16: + case CPU_SYSDESC_TYPE_TRAP_32: + break; + + default: + VERBOSE(("interrupt: invalid gate type (%d)", gsd.type)); + EXCEPTION(GP_EXCEPTION, exc_errcode); + break; + } + + /* 5.10.1.1. 例外/割り込みハンドラ・プロシージャの保護 */ + if ((intrtype == INTR_TYPE_SOFTINTR) && (gsd.dpl < CPU_STAT_CPL)) { + VERBOSE(("interrupt: intrtype(softint) && DPL(%d) < CPL(%d)", gsd.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + + if (!SEG_IS_PRESENT(&gsd)) { + VERBOSE(("interrupt: gate descriptor is not present.")); + EXCEPTION(NP_EXCEPTION, exc_errcode); + } + + if ((intrtype == INTR_TYPE_EXTINTR) && CPU_STAT_HLT) { + VERBOSE(("interrupt: reset HTL in protected mode")); + CPU_EIP++; + CPU_STAT_HLT = 0; + } + + switch (gsd.type) { + case CPU_SYSDESC_TYPE_TASK: + interrupt_task_gate(&gsd, intrtype, errorp, error_code); + break; + + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_INTR_32: + case CPU_SYSDESC_TYPE_TRAP_16: + case CPU_SYSDESC_TYPE_TRAP_32: + interrupt_intr_or_trap(&gsd, intrtype, errorp, error_code); + break; + + default: + EXCEPTION(GP_EXCEPTION, exc_errcode); + break; + } + + VERBOSE(("interrupt: ---------------------------------------------------------------- end")); + } + + CPU_CLEAR_PREV_ESP(); +} + +static void CPUCALL +interrupt_task_gate(const descriptor_t *gsdp, int intrtype, int errorp, int error_code) +{ + selector_t task_sel; + int rv; + + VERBOSE(("interrupt: TASK-GATE")); + + rv = parse_selector(&task_sel, gsdp->u.gate.selector); + if (rv < 0 || task_sel.ldt || !SEG_IS_SYSTEM(&task_sel.desc)) { + VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d, %cDT, type = %s)", gsdp->u.gate.selector, rv, task_sel.ldt ? 'L' : 'G', task_sel.desc.s ? "code/data" : "system")); + EXCEPTION(TS_EXCEPTION, task_sel.idx); + } + + /* check gate type */ + switch (task_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_32: + break; + + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + VERBOSE(("interrupt: task is busy.")); + /*FALLTHROUGH*/ + default: + VERBOSE(("interrupt: invalid gate type (%d)", task_sel.desc.type)); + EXCEPTION(TS_EXCEPTION, task_sel.idx); + break; + } + + /* not present */ + if (selector_is_not_present(&task_sel)) { + VERBOSE(("interrupt: selector is not present")); + EXCEPTION(NP_EXCEPTION, task_sel.idx); + } + + task_switch(&task_sel, TASK_SWITCH_INTR); + + CPU_SET_PREV_ESP(); + + if (errorp) { + VERBOSE(("interrupt: push error code (%08x)", error_code)); + if (task_sel.desc.type == CPU_SYSDESC_TYPE_TSS_32) { + PUSH0_32(error_code); + } else { + PUSH0_16(error_code); + } + } + + /* out of range */ + if (CPU_EIP > CPU_STAT_CS_LIMIT) { + VERBOSE(("interrupt: new_ip is out of range. new_ip = %08x, limit = %08x", CPU_EIP, CPU_STAT_CS_LIMIT)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + +static void CPUCALL +interrupt_intr_or_trap(const descriptor_t *gsdp, int intrtype, int errorp, int error_code) +{ + selector_t cs_sel, ss_sel; + UINT stacksize; + UINT32 old_flags; + UINT32 new_flags; + UINT32 mask; + UINT32 sp; + UINT32 new_ip, new_sp; + UINT32 old_ip, old_sp; + UINT16 old_cs, old_ss, new_ss; + BOOL is32bit; + int exc_errcode; + int rv; + + new_ip = gsdp->u.gate.offset; + old_ss = CPU_SS; + old_cs = CPU_CS; + old_ip = CPU_EIP; + old_sp = CPU_ESP; + old_flags = REAL_EFLAGREG; + new_flags = REAL_EFLAGREG & ~(T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG); + mask = T_FLAG|RF_FLAG|NT_FLAG|VM_FLAG; + + switch (gsdp->type) { + case CPU_SYSDESC_TYPE_INTR_16: + case CPU_SYSDESC_TYPE_INTR_32: + VERBOSE(("interrupt: INTERRUPT-GATE")); + new_flags &= ~I_FLAG; + mask |= I_FLAG; + break; + + case CPU_SYSDESC_TYPE_TRAP_16: + case CPU_SYSDESC_TYPE_TRAP_32: + VERBOSE(("interrupt: TRAP-GATE")); + break; + + default: + ia32_panic("interrupt: gate descriptor type is invalid (type = %d)", gsdp->type); + break; + } + + exc_errcode = gsdp->u.gate.selector & ~3; + if (intrtype == INTR_TYPE_EXTINTR) + exc_errcode++; + + rv = parse_selector(&cs_sel, gsdp->u.gate.selector); + if (rv < 0) { + VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", gsdp->u.gate.selector, rv)); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + + /* check segment type */ + if (SEG_IS_SYSTEM(&cs_sel.desc)) { + VERBOSE(("interrupt: code segment is system segment")); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + if (SEG_IS_DATA(&cs_sel.desc)) { + VERBOSE(("interrupt: code segment is data segment")); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + + /* check privilege level */ + if (cs_sel.desc.dpl > CPU_STAT_CPL) { + VERBOSE(("interrupt: DPL(%d) > CPL(%d)", cs_sel.desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + + /* not present */ + if (selector_is_not_present(&cs_sel)) { + VERBOSE(("interrupt: selector is not present")); + EXCEPTION(NP_EXCEPTION, exc_errcode); + } + + is32bit = gsdp->type & CPU_SYSDESC_TYPE_32BIT; + if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc) && (cs_sel.desc.dpl < CPU_STAT_CPL)) { + stacksize = errorp ? 12 : 10; + if (!CPU_STAT_VM86) { + VERBOSE(("interrupt: INTER-PRIVILEGE-LEVEL-INTERRUPT")); + } else { + /* VM86 */ + VERBOSE(("interrupt: INTERRUPT-FROM-VIRTUAL-8086-MODE")); + if (cs_sel.desc.dpl != 0) { + /* 16.3.1.1 */ + VERBOSE(("interrupt: DPL[CS](%d) != 0", cs_sel.desc.dpl)); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + stacksize += 8; + } + if (is32bit) { + stacksize *= 2; + } + + /* get stack pointer from TSS */ + get_stack_pointer_from_tss(cs_sel.desc.dpl, &new_ss, &new_sp); + + /* parse stack segment descriptor */ + rv = parse_selector(&ss_sel, new_ss); + + /* update exception error code */ + exc_errcode = ss_sel.idx; + if (intrtype == INTR_TYPE_EXTINTR) + exc_errcode++; + + if (rv < 0) { + VERBOSE(("interrupt: parse_selector (selector = %04x, rv = %d)", new_ss, rv)); + EXCEPTION(TS_EXCEPTION, exc_errcode); + } + + /* check privilege level */ + if (ss_sel.rpl != cs_sel.desc.dpl) { + VERBOSE(("interrupt: selector RPL[SS](%d) != DPL[CS](%d)", ss_sel.rpl, cs_sel.desc.dpl)); + EXCEPTION(TS_EXCEPTION, exc_errcode); + } + if (ss_sel.desc.dpl != cs_sel.desc.dpl) { + VERBOSE(("interrupt: descriptor DPL[SS](%d) != DPL[CS](%d)", ss_sel.desc.dpl, cs_sel.desc.dpl)); + EXCEPTION(TS_EXCEPTION, exc_errcode); + } + + /* stack segment must be writable data segment. */ + if (SEG_IS_SYSTEM(&ss_sel.desc)) { + VERBOSE(("interrupt: stack segment is system segment")); + EXCEPTION(TS_EXCEPTION, exc_errcode); + } + if (SEG_IS_CODE(&ss_sel.desc)) { + VERBOSE(("interrupt: stack segment is code segment")); + EXCEPTION(TS_EXCEPTION, exc_errcode); + } + if (!SEG_IS_WRITABLE_DATA(&ss_sel.desc)) { + VERBOSE(("interrupt: stack segment is read-only data segment")); + EXCEPTION(TS_EXCEPTION, exc_errcode); + } + + /* not present */ + if (selector_is_not_present(&ss_sel)) { + VERBOSE(("interrupt: selector is not present")); + EXCEPTION(SS_EXCEPTION, exc_errcode); + } + + /* check stack room size */ + cpu_stack_push_check(ss_sel.idx, &ss_sel.desc, new_sp, stacksize, ss_sel.desc.d); + + /* out of range */ + if (new_ip > cs_sel.desc.u.seg.limit) { + VERBOSE(("interrupt: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel.desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + load_ss(ss_sel.selector, &ss_sel.desc, cs_sel.desc.dpl); + CPU_ESP = new_sp; + + load_cs(cs_sel.selector, &cs_sel.desc, cs_sel.desc.dpl); + CPU_EIP = new_ip; + + if (is32bit) { + if (CPU_STAT_VM86) { + PUSH0_32(CPU_GS); + PUSH0_32(CPU_FS); + PUSH0_32(CPU_DS); + PUSH0_32(CPU_ES); + + LOAD_SEGREG(CPU_GS_INDEX, 0); + CPU_STAT_SREG(CPU_GS_INDEX).valid = 0; + LOAD_SEGREG(CPU_FS_INDEX, 0); + CPU_STAT_SREG(CPU_FS_INDEX).valid = 0; + LOAD_SEGREG(CPU_DS_INDEX, 0); + CPU_STAT_SREG(CPU_DS_INDEX).valid = 0; + LOAD_SEGREG(CPU_ES_INDEX, 0); + CPU_STAT_SREG(CPU_ES_INDEX).valid = 0; + } + PUSH0_32(old_ss); + PUSH0_32(old_sp); + PUSH0_32(old_flags); + PUSH0_32(old_cs); + PUSH0_32(old_ip); + if (errorp) { + PUSH0_32(error_code); + } + } else { + if (CPU_STAT_VM86) { + ia32_panic("interrupt: 16bit gate && VM86"); + } + PUSH0_16(old_ss); + PUSH0_16(old_sp); + PUSH0_16(old_flags); + PUSH0_16(old_cs); + PUSH0_16(old_ip); + if (errorp) { + PUSH0_16(error_code); + } + } + } else { + if (CPU_STAT_VM86) { + VERBOSE(("interrupt: VM86")); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc) && (cs_sel.desc.dpl != CPU_STAT_CPL)) { + VERBOSE(("interrupt: %sCONFORMING-CODE-SEGMENT(%d) && DPL[CS](%d) != CPL", SEG_IS_CONFORMING_CODE(&cs_sel.desc) ? "" : "NON-", cs_sel.desc.dpl, CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, exc_errcode); + } + + VERBOSE(("interrupt: INTRA-PRIVILEGE-LEVEL-INTERRUPT")); + + stacksize = errorp ? 8 : 6; + if (is32bit) { + stacksize *= 2; + } + + /* check stack room size */ + if (CPU_STAT_SS32) { + sp = CPU_ESP; + } else { + sp = CPU_SP; + } + /* + * 17.1 + * コールゲート、割り込みゲート、またはトラップゲートを通じて + * プログラムの制御を他のコード・セグメントに移行するときは、 + * 移行中に使用されるオペランド・サイズは使用されるゲートの + * タイプ(16 ビットまたは32 ビット)によって決まる(移行命 + * 令のD フラグ、プリフィックスのいずれにもよらない)。 + */ + SS_PUSH_CHECK1(sp, stacksize, is32bit); + + /* out of range */ + if (new_ip > cs_sel.desc.u.seg.limit) { + VERBOSE(("interrupt: new_ip is out of range. new_ip = %08x, limit = %08x", new_ip, cs_sel.desc.u.seg.limit)); + EXCEPTION(GP_EXCEPTION, 0); + } + + load_cs(cs_sel.selector, &cs_sel.desc, CPU_STAT_CPL); + CPU_EIP = new_ip; + + if (is32bit) { + PUSH0_32(old_flags); + PUSH0_32(old_cs); + PUSH0_32(old_ip); + if (errorp) { + PUSH0_32(error_code); + } + } else { + PUSH0_16(old_flags); + PUSH0_16(old_cs); + PUSH0_16(old_ip); + if (errorp) { + PUSH0_16(error_code); + } + } + } + set_eflags(new_flags, mask); + + VERBOSE(("interrupt: new EIP = %04x:%08x, ESP = %04x:%08x", CPU_CS, CPU_EIP, CPU_SS, CPU_ESP)); +} diff --git a/source/src/vm/np21/i386c/ia32/exception.h b/source/src/vm/np21/i386c/ia32/exception.h new file mode 100644 index 000000000..bebe69b67 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/exception.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_EXCEPTION_H__ +#define IA32_CPU_EXCEPTION_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +enum { + DE_EXCEPTION = 0, /* F */ + DB_EXCEPTION = 1, /* F/T */ + NMI_EXCEPTION = 2, /* I */ + BP_EXCEPTION = 3, /* T */ + OF_EXCEPTION = 4, /* T */ + BR_EXCEPTION = 5, /* F */ + UD_EXCEPTION = 6, /* F */ + NM_EXCEPTION = 7, /* F */ + DF_EXCEPTION = 8, /* A, Err(0) */ + /* CoProcesser Segment Overrun = 9 */ + TS_EXCEPTION = 10, /* F */ + NP_EXCEPTION = 11, /* F, Err */ + SS_EXCEPTION = 12, /* F, Err */ + GP_EXCEPTION = 13, /* F, Err */ + PF_EXCEPTION = 14, /* F, Err */ + /* Reserved = 15 */ + MF_EXCEPTION = 16, /* F */ + AC_EXCEPTION = 17, /* F, Err(0) */ + MC_EXCEPTION = 18, /* A, Err(?) */ + XF_EXCEPTION = 19, /* F */ + EXCEPTION_NUM +}; + +enum { + INTR_TYPE_SOFTINTR = -1, /* software interrupt (INTn) */ + INTR_TYPE_EXTINTR = 0, /* external interrupt */ + INTR_TYPE_EXCEPTION = 1, /* exception */ +}; + +#define EXCEPTION(num, vec) \ + exception(num, vec); +#define INTERRUPT(num, softintp) \ + interrupt(num, softintp, 0, 0) + +void CPUCALL exception(int num, int vec); +void CPUCALL interrupt(int num, int intrtype, int errorp, int error_code); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* !IA32_CPU_EXCEPTION_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/groups.cpp b/source/src/vm/np21/i386c/ia32/groups.cpp new file mode 100644 index 000000000..c23f8ecb1 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/groups.cpp @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" +#include "groups.h" +#include "inst_table.h" + +#if defined(USE_SSE3) +#include "instructions/sse3/sse3.h" +#endif + +/* group 1 */ +void +Grp1_EbIb(void) +{ + UINT8 *out; + UINT32 madr; + UINT32 op, src; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + GET_PCBYTE(src); + (*insttable_G1EbIb[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + (*insttable_G1EbIb_ext[idx])(madr, src); + } +} + +void +Grp1_EwIb(void) +{ + UINT16 *out; + UINT32 madr, src; + UINT32 op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + GET_PCBYTES(src); + (*insttable_G1EwIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCBYTES(src); + (*insttable_G1EwIx_ext[idx])(madr, src); + } +} + +void +Grp1_EdIb(void) +{ + UINT32 *out; + UINT32 madr, src; + UINT32 op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + GET_PCBYTESD(src); + (*insttable_G1EdIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCBYTESD(src); + (*insttable_G1EdIx_ext[idx])(madr, src); + } +} + +void +Grp1_EwIw(void) +{ + UINT16 *out; + UINT32 madr, src; + UINT32 op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + GET_PCWORD(src); + (*insttable_G1EwIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCWORD(src); + (*insttable_G1EwIx_ext[idx])(madr, src); + } +} + +void +Grp1_EdId(void) +{ + UINT32 *out; + UINT32 madr, src; + UINT32 op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + GET_PCDWORD(src); + (*insttable_G1EdIx[idx])(out, src); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCDWORD(src); + (*insttable_G1EdIx_ext[idx])(madr, src); + } +} + + +/* group 2 */ +void +Grp2_EbIb(void) +{ + UINT8 *out; + UINT32 madr; + UINT32 op; + UINT32 cl; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg8_b20[op]; + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EbCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EbCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EwIb(void) +{ + UINT16 *out; + UINT32 madr; + UINT32 op; + UINT32 cl; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg16_b20[op]; + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EwCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EwCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EdIb(void) +{ + UINT32 *out; + UINT32 madr; + UINT32 op; + UINT32 cl; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg32_b20[op]; + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EdCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + GET_PCBYTE(cl); + CPU_WORKCLOCK(cl & 0x1f); + (*insttable_G2EdCL_ext[idx])(madr, cl); + } +} + +void +Grp2_Eb(void) +{ + UINT32 op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + (*insttable_G2Eb[idx])(reg8_b20[op]); + } else { + CPU_WORKCLOCK(7); + (*insttable_G2Eb_ext[idx])(calc_ea_dst(op)); + } +} + +void +Grp2_Ew(void) +{ + UINT32 op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + (*insttable_G2Ew[idx])(reg16_b20[op]); + } else { + CPU_WORKCLOCK(7); + (*insttable_G2Ew_ext[idx])(calc_ea_dst(op)); + } +} + +void +Grp2_Ed(void) +{ + UINT32 op; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + (*insttable_G2Ed[idx])(reg32_b20[op]); + } else { + CPU_WORKCLOCK(7); + (*insttable_G2Ed_ext[idx])(calc_ea_dst(op)); + } +} + +void +Grp2_EbCL(void) +{ + UINT8 *out; + UINT32 madr; + UINT32 op; + UINT32 cl; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg8_b20[op]; + cl = CPU_CL; + cl &= 0x1f; + CPU_WORKCLOCK(cl); + (*insttable_G2EbCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + cl = CPU_CL; + cl &= 0x1f; + CPU_WORKCLOCK(cl); + (*insttable_G2EbCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EwCL(void) +{ + UINT16 *out; + UINT32 madr; + UINT32 op; + UINT32 cl; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg16_b20[op]; + cl = CPU_CL; + cl &= 0x1f; + CPU_WORKCLOCK(cl); + (*insttable_G2EwCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + cl = CPU_CL; + cl &= 0x1f; + CPU_WORKCLOCK(cl); + (*insttable_G2EwCL_ext[idx])(madr, cl); + } +} + +void +Grp2_EdCL(void) +{ + UINT32 *out; + UINT32 madr; + UINT32 op; + UINT32 cl; + int idx; + + GET_PCBYTE(op); + idx = (op >> 3) & 7; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + out = reg32_b20[op]; + cl = CPU_CL; + cl &= 0x1f; + CPU_WORKCLOCK(cl); + (*insttable_G2EdCL[idx])(out, cl); + } else { + CPU_WORKCLOCK(8); + madr = calc_ea_dst(op); + cl = CPU_CL; + cl &= 0x1f; + CPU_WORKCLOCK(cl); + (*insttable_G2EdCL_ext[idx])(madr, cl); + } +} + + +/* group 3 */ +void +Grp3_Eb(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G3Eb[(op >> 3) & 7])(op); +} + +void +Grp3_Ew(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G3Ew[(op >> 3) & 7])(op); +} + +void +Grp3_Ed(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G3Ed[(op >> 3) & 7])(op); +} + + +/* group 4 */ +void +Grp4(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G4[(op >> 3) & 7])(op); +} + + +/* group 5 */ +void +Grp5_Ew(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G5Ew[(op >> 3) & 7])(op); +} + +void +Grp5_Ed(void) +{ + UINT32 op; + + UINT32 old_eip = CPU_PREV_EIP; + UINT32 old_addr = 0; + GET_PCBYTE(op); + UINT32 op_old = op; + switch((op >> 3) & 7) { + case 2: //CAll + case 3: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + old_eip; + } + break; + } + (*insttable_G5Ed[(op >> 3) & 7])(op); + switch((op >> 3) & 7) { + case 2: //CAll + case 3: //CAll + { + descriptor_t *sdp = &CPU_CS_DESC; + uint32_t new_addr = sdp->u.seg.segbase + CPU_EIP; + device_debugger->add_cpu_trace_call(old_addr, new_addr); + } + break; + } +} + + +/* group 6 */ +void +Grp6(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G6[(op >> 3) & 7])(op); +} + + +/* group 7 */ +void +Grp7(void) +{ + UINT32 op; + + GET_PCBYTE(op); +#if defined(USE_SSE3) + if(op==0xC8){ + SSE3_MONITOR(); + return; + } + if(op==0xC9){ + SSE3_MWAIT(); + return; + } +#endif + (*insttable_G7[(op >> 3) & 7])(op); +} + + +/* group 8 */ +void +Grp8_EwIb(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G8EwIb[(op >> 3) & 7])(op); +} + +void +Grp8_EdIb(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G8EdIb[(op >> 3) & 7])(op); +} + + +/* group 9 */ +void +Grp9(void) +{ + UINT32 op; + + GET_PCBYTE(op); + (*insttable_G9[(op >> 3) & 7])(op); +} diff --git a/source/src/vm/np21/i386c/ia32/groups.h b/source/src/vm/np21/i386c/ia32/groups.h new file mode 100644 index 000000000..b560acb31 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/groups.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_GROUPS_H__ +#define IA32_CPU_GROUPS_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* group 1 */ +void Grp1_EbIb(void); +void Grp1_EwIb(void); +void Grp1_EdIb(void); +void Grp1_EwIw(void); +void Grp1_EdId(void); + +/* group 2 */ +void Grp2_Eb(void); +void Grp2_Ew(void); +void Grp2_Ed(void); +void Grp2_EbCL(void); +void Grp2_EwCL(void); +void Grp2_EdCL(void); +void Grp2_EbIb(void); +void Grp2_EwIb(void); +void Grp2_EdIb(void); + +/* group 3 */ +void Grp3_Eb(void); +void Grp3_Ew(void); +void Grp3_Ed(void); + +/* group 4 */ +void Grp4(void); + +/* group 5 */ +void Grp5_Ew(void); +void Grp5_Ed(void); + +/* group 6 */ +void Grp6(void); + +/* group 7 */ +void Grp7(void); + +/* group 8 */ +void Grp8_EwIb(void); +void Grp8_EdIb(void); + +/* group 9 */ +void Grp9(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_GROUPS_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/ia32.cpp b/source/src/vm/np21/i386c/ia32/ia32.cpp new file mode 100644 index 000000000..3983dc422 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/ia32.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#if defined(SUPPORT_IA32_HAXM) +#include "i386hax/haxfunc.h" +#include "i386hax/haxcore.h" +#endif + +I386CORE i386core; +I386CPUID i386cpuid = {I386CPUID_VERSION, CPU_VENDOR, CPU_FAMILY, CPU_MODEL, CPU_STEPPING, CPU_FEATURES, CPU_FEATURES_EX, CPU_BRAND_STRING, CPU_BRAND_ID, CPU_FEATURES_ECX, CPU_EFLAGS_MASK}; +I386MSR i386msr = {0}; + +UINT8 *reg8_b20[0x100]; +UINT8 *reg8_b53[0x100]; +UINT16 *reg16_b20[0x100]; +UINT16 *reg16_b53[0x100]; +UINT32 *reg32_b20[0x100]; +UINT32 *reg32_b53[0x100]; + +void +ia32_init(void) +{ + int i; + + i386msr.version = I386MSR_VERSION; + i386cpuid.version = I386CPUID_VERSION; + + memset(&i386core.s, 0, sizeof(i386core.s)); + ia32_initreg(); + memset(&i386msr.regs, 0, sizeof(i386msr.regs)); + + for (i = 0; i < 0x100; ++i) { + /* 8bit */ + if (i & 0x20) { + /* h */ + reg8_b53[i] = &CPU_REGS_BYTEH((i >> 3) & 3); + } else { + /* l */ + reg8_b53[i] = &CPU_REGS_BYTEL((i >> 3) & 3); + } + + if (i & 0x04) { + /* h */ + reg8_b20[i] = &CPU_REGS_BYTEH(i & 3); + } else { + /* l */ + reg8_b20[i] = &CPU_REGS_BYTEL(i & 3); + } + + /* 16bit */ + reg16_b53[i] = &CPU_REGS_WORD((i >> 3) & 7); + reg16_b20[i] = &CPU_REGS_WORD(i & 7); + + /* 32bit */ + reg32_b53[i] = &CPU_REGS_DWORD((i >> 3) & 7); + reg32_b20[i] = &CPU_REGS_DWORD(i & 7); + } + + resolve_init(); +} + +#if 0 +void +ia32_setextsize(UINT32 size) +{ +//#if defined(SUPPORT_LARGE_MEMORY)&&defined(_WIN32) && !defined(MEMTRACE) && !defined(MEMCHECK) +// static int vallocflag = 0; +// static int vallocsize = 0; +// static LPVOID memblock = NULL; +//#endif + + if (CPU_EXTMEMSIZE != size) { + UINT8 *extmem; + extmem = CPU_EXTMEM; + if (extmem != NULL) { +//#if defined(SUPPORT_LARGE_MEMORY) && defined(_WIN32) && !defined(MEMTRACE) && !defined(MEMCHECK) +// if(vallocflag){ +// VirtualFree((LPVOID)extmem, vallocsize, MEM_DECOMMIT); +// VirtualFree(memblock, 0, MEM_RELEASE); +// vallocflag = 0; +// }else +//#endif + { +#if defined(SUPPORT_IA32_HAXM) + _aligned_free(extmem); +#else + _MFREE(extmem); +#endif + } + extmem = NULL; + } + if (size != 0) { +//#if defined(SUPPORT_LARGE_MEMORY) && defined(_WIN32) && !defined(MEMTRACE) && !defined(MEMCHECK) +// if(size > (255 << 20)){ +// HANDLE hp = OpenProcess(PROCESS_ALL_ACCESS, TRUE, GetCurrentProcessId()); +// vallocsize = size + 16; +// SetProcessWorkingSetSize(hp, vallocsize + 50*1024*1024, vallocsize + 50*1024*1024); +// CloseHandle(hp); +// memblock = VirtualAlloc(NULL, vallocsize, MEM_RESERVE, PAGE_READWRITE); +// extmem = (UINT8 *)VirtualAlloc(memblock, vallocsize, MEM_COMMIT, PAGE_READWRITE); +// if(!extmem){ +// extmem = (UINT8 *)_MALLOC(size + 16, "EXTMEM"); +// }else{ +// vallocflag = 1; +// } +// }else +//#endif + { +#if defined(SUPPORT_IA32_HAXM) + extmem = (UINT8*)_aligned_malloc(size + 4096, 4096); +#else + extmem = (UINT8 *)_MALLOC(size + 16, "EXTMEM"); +#endif + } + } + if (extmem != NULL) { + ZeroMemory(extmem, size + 16); + CPU_EXTMEM = extmem; + CPU_EXTMEMSIZE = size; + CPU_EXTMEMBASE = CPU_EXTMEM - 0x100000; + CPU_EXTLIMIT16 = min(size + 0x100000, 0xf00000); + CPU_EXTLIMIT = size + 0x100000; + } + else { +#if defined(SUPPORT_LARGE_MEMORY) + if(size != 0){ + msgbox("Error", "Cannot allocate extended memory."); + } +#endif + CPU_EXTMEM = NULL; + CPU_EXTMEMSIZE = 0; + CPU_EXTMEMBASE = NULL; + CPU_EXTLIMIT16 = 0; + CPU_EXTLIMIT = 0; + } + } + CPU_EMSPTR[0] = mem + 0xc0000; + CPU_EMSPTR[1] = mem + 0xc4000; + CPU_EMSPTR[2] = mem + 0xc8000; + CPU_EMSPTR[3] = mem + 0xcc000; +} + +void +ia32_setemm(UINT frame, UINT32 addr) { + + UINT8 *ptr; + + frame &= 3; + if (addr < USE_HIMEM) { + ptr = mem + addr; + } + else if ((addr - 0x100000 + 0x4000) <= CPU_EXTMEMSIZE) { + ptr = CPU_EXTMEM + (addr - 0x100000); + } + else { + ptr = mem + 0xc0000 + (frame << 14); + } + CPU_EMSPTR[frame] = ptr; +} +#endif + +/* + * モード遷移 + */ +void CPUCALL +change_pm(BOOL onoff) +{ + + if (onoff) { + VERBOSE(("change_pm: Entering to Protected-Mode...")); + } else { + VERBOSE(("change_pm: Leaveing from Protected-Mode...")); + } + + CPU_INST_OP32 = CPU_INST_AS32 = + CPU_STATSAVE.cpu_inst_default.op_32 = + CPU_STATSAVE.cpu_inst_default.as_32 = 0; + CPU_STAT_SS32 = 0; + set_cpl(0); + CPU_STAT_PM = onoff; +} + +void CPUCALL +change_pg(BOOL onoff) +{ + + if (onoff) { + VERBOSE(("change_pg: Entering to Paging-Mode...")); + } else { + VERBOSE(("change_pg: Leaveing from Paging-Mode...")); + } + + CPU_STAT_PAGING = onoff; +} + +void CPUCALL +change_vm(BOOL onoff) +{ + int i; + + CPU_STAT_VM86 = onoff; + if (onoff) { + VERBOSE(("change_vm: Entering to Virtual-8086-Mode...")); + for (i = 0; i < CPU_SEGREG_NUM; i++) { + LOAD_SEGREG(i, CPU_REGS_SREG(i)); + } + CPU_INST_OP32 = CPU_INST_AS32 = + CPU_STATSAVE.cpu_inst_default.op_32 = + CPU_STATSAVE.cpu_inst_default.as_32 = 0; + CPU_STAT_SS32 = 0; + set_cpl(3); + } else { + VERBOSE(("change_vm: Leaveing from Virtual-8086-Mode...")); + } +} + +/* + * flags + */ +static __inline__ void CPUCALL +modify_eflags(UINT32 new_flags, UINT32 mask) +{ + UINT32 orig = CPU_EFLAG; + + new_flags &= ALL_EFLAG; + mask &= ALL_EFLAG; + CPU_EFLAG = (REAL_EFLAGREG & ~mask) | (new_flags & mask); + + CPU_OV = CPU_FLAG & O_FLAG; + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); + if (CPU_STAT_PM) { + if ((orig ^ CPU_EFLAG) & VM_FLAG) { + if (CPU_EFLAG & VM_FLAG) { + change_vm(1); + } else { + change_vm(0); + } + } + } +} + +void CPUCALL set_flags(UINT16 new_flags, UINT16 mask) +{ + + mask &= I_FLAG|IOPL_FLAG; + mask |= SZAPC_FLAG|T_FLAG|D_FLAG|O_FLAG|NT_FLAG; + modify_eflags(new_flags, mask); +} + +void CPUCALL set_eflags(UINT32 new_flags, UINT32 mask) +{ + + mask &= I_FLAG|IOPL_FLAG|RF_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG; + mask |= SZAPC_FLAG|T_FLAG|D_FLAG|O_FLAG|NT_FLAG; + mask |= AC_FLAG|ID_FLAG; + mask &= ~i386cpuid.cpu_eflags_mask; + modify_eflags(new_flags, mask); +} + +/* + * CR3 (Page Directory Entry base physical address) + */ +void CPUCALL +set_cr3(UINT32 new_cr3) +{ + + VERBOSE(("set_CR3: old = %08x, new = 0x%08x", CPU_CR3, new_cr3)); + + CPU_CR3 = new_cr3 & CPU_CR3_MASK; + CPU_STAT_PDE_BASE = CPU_CR3 & CPU_CR3_PD_MASK; + tlb_flush(); +} + +/* + * CPL (Current Privilege Level) + */ +void CPUCALL +set_cpl(int new_cpl) +{ + int cpl = new_cpl & 3; + + CPU_STAT_CPL = (UINT8)cpl; + CPU_STAT_USER_MODE = (cpl == 3) ? CPU_MODE_USER : CPU_MODE_SUPERVISER; +} diff --git a/source/src/vm/np21/i386c/ia32/ia32.mcr b/source/src/vm/np21/i386c/ia32/ia32.mcr new file mode 100644 index 000000000..f98154f1e --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/ia32.mcr @@ -0,0 +1,951 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_IA32_MCR__ +#define IA32_CPU_IA32_MCR__ + +/* + * misc + */ +#define __CBW(src) ((UINT16)((SINT8)(src))) +#define __CBD(src) ((UINT32)((SINT8)(src))) +#define __CWDE(src) ((SINT16)(src)) + +#ifndef PTR_TO_UINT32 +#define PTR_TO_UINT32(p) ((UINT32)((unsigned long)(p))) +#endif +#ifndef UINT32_TO_PTR +#define UINT32_TO_PTR(v) ((void *)((unsigned long)(UINT32)(v))) +#endif + +#define SWAP_BYTE(p, q) \ +do { \ + UINT8 __tmp = (p); \ + (p) = (q); \ + (q) = __tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SWAP_WORD(p, q) \ +do { \ + UINT16 __tmp = (p); \ + (p) = (q); \ + (q) = __tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SWAP_DWORD(p, q) \ +do { \ + UINT32 __tmp = (p); \ + (p) = (q); \ + (q) = __tmp; \ +} while (/*CONSTCOND*/ 0) + + +/* + * clock + */ +#define CPU_WORKCLOCK(clock) \ +do { \ + CPU_REMCLOCK -= (clock); \ +} while (/*CONSTCOND*/ 0) + +#define CPU_HALT() \ +do { \ + CPU_REMCLOCK = -1; \ +} while (/*CONSTCOND*/ 0) + +#define IRQCHECKTERM() \ +do { \ + if (CPU_REMCLOCK > 0) { \ + CPU_BASECLOCK -= CPU_REMCLOCK; \ + CPU_REMCLOCK = 0; \ + } \ +} while (/*CONSTCOND*/ 0) + + +/* + * instruction pointer + */ +/* コードフェッチに使用するので、OpSize の影響を受けてはいけない */ +#define _ADD_EIP(v) \ +do { \ + UINT32 __tmp_ip = CPU_EIP + (v); \ + if (!CPU_STATSAVE.cpu_inst_default.op_32) { \ + __tmp_ip &= 0xffff; \ + } \ + CPU_EIP = __tmp_ip; \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCBYTE(v) \ +do { \ + (v) = cpu_codefetch(CPU_EIP); \ + _ADD_EIP(1); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCBYTES(v) \ +do { \ + (v) = __CBW(cpu_codefetch(CPU_EIP)); \ + _ADD_EIP(1); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCBYTESD(v) \ +do { \ + (v) = __CBD(cpu_codefetch(CPU_EIP)); \ + _ADD_EIP(1); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCWORD(v) \ +do { \ + (v) = cpu_codefetch_w(CPU_EIP); \ + _ADD_EIP(2); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCWORDS(v) \ +do { \ + (v) = __CWDE(cpu_codefetch_w(CPU_EIP)); \ + _ADD_EIP(2); \ +} while (/*CONSTCOND*/ 0) + +#define GET_PCDWORD(v) \ +do { \ + (v) = cpu_codefetch_d(CPU_EIP); \ + _ADD_EIP(4); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG8(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = *(reg8_b53[(b)]); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG8P(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = reg8_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG16(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = *(reg16_b53[(b)]); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG16P(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = reg16_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG32(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = *(reg32_b53[(b)]); \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_EA_REG32P(b, d_s) \ +do { \ + GET_PCBYTE((b)); \ + (d_s) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG8_EA(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg8_b20[(b)]); \ + } else { \ + UINT32 __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg8_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG16_EA(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg16_b20[(b)]); \ + } else { \ + UINT32 __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg16_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG16_EA8(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg8_b20[(b)]); \ + } else { \ + UINT32 __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg16_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG32_EA(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg32_b20[(b)]); \ + } else { \ + UINT32 __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG32_EA8(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg8_b20[(b)]); \ + } else { \ + UINT32 __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + +#define PREPART_REG32_EA16(b, s, d, regclk, memclk) \ +do { \ + GET_PCBYTE((b)); \ + if ((b) >= 0xc0) { \ + CPU_WORKCLOCK(regclk); \ + (s) = *(reg16_b20[(b)]); \ + } else { \ + UINT32 __t; \ + CPU_WORKCLOCK(memclk); \ + __t = calc_ea_dst((b)); \ + (s) = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, __t); \ + } \ + (d) = reg32_b53[(b)]; \ +} while (/*CONSTCOND*/ 0) + + +/* + * arith + */ +#define _ADD_BYTE(r, d, s) \ +do { \ + (r) = (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADD_WORD(r, d, s) \ +do { \ + (r) = (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(UINT16)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADD_DWORD(r, d, s) \ +do { \ + (r) = (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80000000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) < (s)) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(UINT8)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _OR_BYTE(d, s) \ +do { \ + (d) |= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(UINT8)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _OR_WORD(d, s) \ +do { \ + (d) |= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpflag_w[(UINT16)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _OR_DWORD(d, s) \ +do { \ + (d) |= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = (UINT8)(szpcflag[(UINT8)(d)] & P_FLAG); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _ADC_BYTE(r, d, s) \ +do { \ + (r) = (CPU_FLAGL & C_FLAG) + (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADC_WORD(r, d, s) \ +do { \ + (r) = (CPU_FLAGL & C_FLAG) + (s) + (d); \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x8000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(UINT16)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _ADC_DWORD(r, d, s) \ +do { \ + UINT32 __c = (CPU_FLAGL & C_FLAG); \ + (r) = (s) + (d) + __c; \ + CPU_OV = ((r) ^ (s)) & ((r) ^ (d)) & 0x80000000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((!__c && (r) < (s)) || (__c && (r) <= (s))) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(UINT8)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _BYTE_SBB(r, d, s) \ +do { \ + (r) = (d) - (s) - (CPU_FLAGL & C_FLAG); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SBB(r, d, s) \ +do { \ + (r) = (d) - (s) - (CPU_FLAGL & C_FLAG); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x8000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(UINT16)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SBB(r, d, s) \ +do { \ + UINT32 __c = (CPU_FLAGL & C_FLAG); \ + (r) = (d) - (s) - __c; \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80000000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((!__c && (d) < (s)) || (__c && (d) <= (s))) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(UINT8)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _AND_BYTE(d, s) \ +do { \ + (d) &= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(UINT8)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _AND_WORD(d, s) \ +do { \ + (d) &= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpflag_w[(UINT16)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _AND_DWORD(d, s) \ +do { \ + (d) &= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = (UINT8)(szpcflag[(UINT8)(d)] & P_FLAG); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SUB(r, d, s) \ +do { \ + (r) = (d) - (s); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(r) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SUB(r, d, s) \ +do { \ + (r) = (d) - (s); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x8000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((r) & 0xffff0000) { \ + (r) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(UINT16)(r)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SUB(r, d, s) \ +do { \ + (r) = (d) - (s); \ + CPU_OV = ((d) ^ (r)) & ((d) ^ (s)) & 0x80000000; \ + CPU_FLAGL = (UINT8)(((r) ^ (d) ^ (s)) & A_FLAG); \ + if ((d) < (s)) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((r) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((r) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(UINT8)(r)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_XOR(d, s) \ +do { \ + (d) ^= s; \ + CPU_OV = 0; \ + CPU_FLAGL = szpcflag[(UINT8)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_XOR(d, s) \ +do { \ + (d) ^= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = szpflag_w[(UINT16)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_XOR(d, s) \ +do { \ + (d) ^= (s); \ + CPU_OV = 0; \ + CPU_FLAGL = (UINT8)(szpcflag[(UINT8)(d)] & P_FLAG); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_NEG(d, s) \ +do { \ + (d) = 0 - (s); \ + CPU_OV = ((d) & (s)) & 0x80; \ + CPU_FLAGL = (UINT8)(((d) ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[(d) & 0x1ff]; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_NEG(d, s) \ +do { \ + (d) = 0 - (s); \ + CPU_OV = ((d) & (s)) & 0x8000; \ + CPU_FLAGL = (UINT8)(((d) ^ (s)) & A_FLAG); \ + if ((d) & 0xffff0000) { \ + (d) &= 0x0000ffff; \ + CPU_FLAGL |= C_FLAG; \ + } \ + CPU_FLAGL |= szpflag_w[(UINT16)(d)]; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_NEG(d, s) \ +do { \ + (d) = 0 - (s); \ + CPU_OV = ((d) & (s)) & 0x80000000; \ + CPU_FLAGL = (UINT8)(((d) ^ (s)) & A_FLAG); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(UINT8)(d)] & P_FLAG; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_MUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (UINT8)(d) * (UINT8)(s); \ + CPU_OV = (r) >> 8; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_MUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (UINT16)(d) * (UINT16)(s); \ + CPU_OV = (r) >> 16; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_MUL(r, d, s) \ +do { \ + UINT64 __v; \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + __v = (UINT64)(d) * (UINT64)(s); \ + (r) = (UINT32)__v; \ + CPU_OV = (UINT32)(__v >> 32); \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_IMUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SINT8)(d) * (SINT8)(s); \ + CPU_OV = ((r) + 0x80) & 0xffffff00; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_IMUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SINT16)(d) * (SINT16)(s); \ + CPU_OV = ((r) + 0x8000) & 0xffff0000; \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_IMUL(r, d, s) \ +do { \ + CPU_FLAGL &= (Z_FLAG | S_FLAG | A_FLAG | P_FLAG); \ + (r) = (SINT64)(d) * (SINT64)(s); \ + CPU_OV = (UINT32)(((r) + QWORD_CONST(0x80000000)) >> 32); \ + if (CPU_OV) { \ + CPU_FLAGL |= C_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _BYTE_INC(s) \ +do { \ + UINT8 __b = (s); \ + __b++; \ + CPU_OV = __b & (__b ^ (s)) & 0x80; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (UINT8)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_INC(s) \ +do { \ + UINT16 __b = (s); \ + __b++; \ + CPU_OV = __b & (__b ^ (s)) & 0x8000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (UINT8)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpflag_w[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_INC(s) \ +do { \ + UINT32 __b = (s); \ + __b++; \ + CPU_OV = __b & (__b ^ (s)) & 0x80000000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (UINT8)((__b ^ (s)) & A_FLAG); \ + if (__b == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if (__b & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(UINT8)(__b)] & P_FLAG; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define _BYTE_DEC(s) \ +do { \ + UINT8 __b = (s); \ + __b--; \ + CPU_OV = (s) & (__b ^ (s)) & 0x80; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (UINT8)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpcflag[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_DEC(s) \ +do { \ + UINT16 __b = (s); \ + __b--; \ + CPU_OV = (s) & (__b ^ (s)) & 0x8000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (UINT8)((__b ^ (s)) & A_FLAG); \ + CPU_FLAGL |= szpflag_w[__b]; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_DEC(s) \ +do { \ + UINT32 __b = (s); \ + __b--; \ + CPU_OV = (s) & (__b ^ (s)) & 0x80000000; \ + CPU_FLAGL &= C_FLAG; \ + CPU_FLAGL |= (UINT8)((__b ^ (s)) & A_FLAG); \ + if ((__b) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + if ((__b) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= szpcflag[(UINT8)(__b)] & P_FLAG; \ + (s) = __b; \ +} while (/*CONSTCOND*/ 0) + +#define BYTE_NOT(s) \ +do { \ + (s) ^= 0xff; \ +} while (/*CONSTCOND*/ 0) + +#define WORD_NOT(s) \ +do { \ + (s) ^= 0xffff; \ +} while (/*CONSTCOND*/ 0) + +#define DWORD_NOT(s) \ +do { \ + (s) ^= 0xffffffff; \ +} while (/*CONSTCOND*/ 0) + + +/* + * stack + */ +#define REGPUSH(reg, clock) \ +do { \ + UINT16 __new_sp = CPU_SP - 2; \ + CPU_WORKCLOCK(clock); \ + cpu_vmemorywrite_w(CPU_SS_INDEX, __new_sp, reg); \ + CPU_SP = __new_sp; \ +} while (/*CONSTCOND*/ 0) + +#define REGPUSH_32(reg, clock) \ +do { \ + UINT32 __new_esp = CPU_ESP - 4; \ + CPU_WORKCLOCK(clock); \ + cpu_vmemorywrite_d(CPU_SS_INDEX, __new_esp, reg); \ + CPU_ESP = __new_esp; \ +} while (/*CONSTCOND*/ 0) + +#define REGPUSH0(reg) \ +do { \ + UINT16 __new_sp = CPU_SP - 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, __new_sp, (UINT16)reg); \ + CPU_SP = __new_sp; \ +} while (/*CONSTCOND*/ 0) + +/* Operand Size == 16 && Stack Size == 32 */ +#define REGPUSH0_16_32(reg) \ +do { \ + UINT32 __new_esp = CPU_ESP - 2; \ + cpu_vmemorywrite_w(CPU_SS_INDEX, __new_esp, (UINT16)reg); \ + CPU_ESP = __new_esp; \ +} while (/*CONSTCOND*/ 0) + +/* Operand Size == 32 && Stack Size == 16 */ +#define REGPUSH0_32_16(reg) \ +do { \ + UINT16 __new_sp = CPU_SP - 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, __new_sp, reg); \ + CPU_SP = __new_sp; \ +} while (/*CONSTCOND*/ 0) + +#define REGPUSH0_32(reg) \ +do { \ + UINT32 __new_esp = CPU_ESP - 4; \ + cpu_vmemorywrite_d(CPU_SS_INDEX, __new_esp, reg); \ + CPU_ESP = __new_esp; \ +} while (/*CONSTCOND*/ 0) + +#define PUSH0_16(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + REGPUSH0(reg); \ + } else { \ + REGPUSH0_16_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define PUSH0_32(reg) \ +do { \ + if (CPU_STAT_SS32) { \ + REGPUSH0_32(reg); \ + } else { \ + REGPUSH0_32_16(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XPUSH0(reg) \ +do { \ + if (!CPU_INST_OP32) { \ + PUSH0_16(reg); \ + } else { \ + PUSH0_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP(reg, clock) \ +do { \ + CPU_WORKCLOCK(clock); \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP); \ + CPU_SP += 2; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP_32(reg, clock) \ +do { \ + CPU_WORKCLOCK(clock); \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP); \ + CPU_ESP += 4; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0(reg) \ +do { \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_SP); \ + CPU_SP += 2; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0_16_32(reg) \ +do { \ + (reg) = cpu_vmemoryread_w(CPU_SS_INDEX, CPU_ESP); \ + CPU_ESP += 2; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0_32_16(reg) \ +do { \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_SP); \ + CPU_SP += 4; \ +} while (/*CONSTCOND*/ 0) + +#define REGPOP0_32(reg) \ +do { \ + (reg) = cpu_vmemoryread_d(CPU_SS_INDEX, CPU_ESP); \ + CPU_ESP += 4; \ +} while (/*CONSTCOND*/ 0) + +#define POP0_16(reg) \ +do { \ + if (!CPU_STAT_SS32) { \ + REGPOP0(reg); \ + } else { \ + REGPOP0_16_32(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define POP0_32(reg) \ +do { \ + if (CPU_STAT_SS32) { \ + REGPOP0_32(reg); \ + } else { \ + REGPOP0_32_16(reg); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* + * stack pointer + */ +#define SP_PUSH_16(reg) \ +do { \ + UINT16 __sp = CPU_SP; \ + if (!CPU_STAT_SS32) { \ + REGPUSH0(__sp); \ + } else { \ + REGPUSH0_16_32(__sp); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define ESP_PUSH_32(reg) \ +do { \ + UINT32 __esp = CPU_ESP; \ + if (!CPU_STAT_SS32) { \ + REGPUSH0_32_16(__esp); \ + } else { \ + REGPUSH0_32(__esp); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define SP_POP_16(reg) \ +do { \ + UINT32 __sp; \ + if (!CPU_STAT_SS32) { \ + __sp = CPU_SP; \ + } else { \ + __sp = CPU_ESP; \ + } \ + CPU_SP = cpu_vmemoryread_w(CPU_SS_INDEX, __sp); \ +} while (/*CONSTCOND*/ 0) + +#define ESP_POP_32(reg) \ +do { \ + UINT32 __esp; \ + if (!CPU_STAT_SS32) { \ + __esp = CPU_SP; \ + } else { \ + __esp = CPU_ESP; \ + } \ + CPU_ESP = cpu_vmemoryread_d(CPU_SS_INDEX, __esp); \ +} while (/*CONSTCOND*/ 0) + + +/* + * jump + */ +#define JMPSHORT(clock) \ +do { \ + UINT32 __new_ip; \ + UINT32 __dest; \ + CPU_WORKCLOCK(clock); \ + GET_PCBYTESD(__dest); \ + __new_ip = CPU_EIP + __dest; \ + if (!CPU_INST_OP32) { \ + __new_ip &= 0xffff; \ + } \ + if (__new_ip > CPU_STAT_CS_LIMIT) { \ + EXCEPTION(GP_EXCEPTION, 0); \ + } \ + CPU_EIP = __new_ip; \ +} while (/*CONSTCOND*/ 0) + +#define JMPNEAR(clock) \ +do { \ + UINT16 __new_ip; \ + SINT16 __dest; \ + CPU_WORKCLOCK(clock); \ + GET_PCWORDS(__dest); \ + __new_ip = CPU_IP + __dest; \ + if (__new_ip > CPU_STAT_CS_LIMIT) { \ + EXCEPTION(GP_EXCEPTION, 0); \ + } \ + CPU_EIP = __new_ip; \ +} while (/*CONSTCOND*/ 0) + +#define JMPNEAR32(clock) \ +do { \ + UINT32 __new_ip; \ + UINT32 __dest; \ + CPU_WORKCLOCK(clock); \ + GET_PCDWORD(__dest); \ + __new_ip = CPU_EIP + __dest; \ + if (__new_ip > CPU_STAT_CS_LIMIT) { \ + EXCEPTION(GP_EXCEPTION, 0); \ + } \ + CPU_EIP = __new_ip; \ +} while (/*CONSTCOND*/ 0) + +#define JMPNOP(clock, d) \ +do { \ + CPU_WORKCLOCK(clock); \ + _ADD_EIP((d)); \ +} while (/*CONSTCOND*/ 0) + + +/* + * conditions + */ +#define CC_O (CPU_OV) +#define CC_NO (!CPU_OV) +#define CC_C (CPU_FLAGL & C_FLAG) +#define CC_NC (!(CPU_FLAGL & C_FLAG)) +#define CC_Z (CPU_FLAGL & Z_FLAG) +#define CC_NZ (!(CPU_FLAGL & Z_FLAG)) +#define CC_NA (CPU_FLAGL & (Z_FLAG | C_FLAG)) +#define CC_A (!(CPU_FLAGL & (Z_FLAG | C_FLAG))) +#define CC_S (CPU_FLAGL & S_FLAG) +#define CC_NS (!(CPU_FLAGL & S_FLAG)) +#define CC_P (CPU_FLAGL & P_FLAG) +#define CC_NP (!(CPU_FLAGL & P_FLAG)) +#define CC_L (((CPU_FLAGL & S_FLAG) == 0) != (CPU_OV == 0)) +#define CC_NL (((CPU_FLAGL & S_FLAG) == 0) == (CPU_OV == 0)) +#define CC_LE ((CPU_FLAGL & Z_FLAG) || \ + (((CPU_FLAGL & S_FLAG) == 0) != (CPU_OV == 0))) +#define CC_NLE ((!(CPU_FLAGL & Z_FLAG)) && \ + (((CPU_FLAGL & S_FLAG) == 0) == (CPU_OV == 0))) + + +/* + * instruction check + */ +#include "ia32xc.mcr" + +#endif /* IA32_CPU_IA32_MCR__ */ diff --git a/source/src/vm/np21/i386c/ia32/ia32weak.txt b/source/src/vm/np21/i386c/ia32/ia32weak.txt new file mode 100644 index 000000000..28e16354e --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/ia32weak.txt @@ -0,0 +1,77 @@ + + + 現状では問題になっていないが、将来問題になる点。 + + + +・結局のところ… +  メモリが一番スピードに関る、命令フェッチで毎回読む訳だし。 + +  ・引き数 int crw と int user_modeをどうにか一本に出来ないか? +    crw + (user_mode << 3) の形で持つ? + + →やってみました。どんなもんでしょ。 + + +・複雑なスタック処理の問題 +  pushaの esp==7,9,11,13,15の GPF(やる気しない + + + +・repe/ne string命令 +  現状、string命令中に外部割り込みを受け付けない。 +  ドラッケンみたいな repのカウンタ数が長く、かつ 特定タイミングで割り込みを +  必要とするソフトで不都合が生じる。 + + + +・デバグレジスタのブレーク +  現在はDRのブレークを使用するアプリは存在しないようだ。 +  もし対応するのであれば 現在の形ではなく exec_1step()を二重化し、 +  シングルステップ割り込みのように ia32()で振り分け処理を行なうとよい。 + + + +・シフトマクロ + if ((s) == 0) CPU_FLAGL |= Z_FLAG; + if ((s) & (1 << (SIZE - 1))) CPU_FLAGL |= S_FLAG; + + if ((s) == 0) CPU_FLAGL |= Z_FLAG; + else if ((s) & (1 << (SIZE - 1))) CPU_FLAGL |= S_FLAG; + +  どっちが高速?(elseでジャンプが生まれる…) + +  (所詮CPUによって変わるが) むしろ… + + if ((s) == 0) CPU_FLAGL |= Z_FLAG; + CPU_FLAGL |= ((s) >> (SIZE - 8)) & S_FLAG; + +  の方が面白い? + + + x86 ARM + cmp (s), 0 cmp (s), #0 + jne short @f orreq CPU_FLAGL, CPU_FLAGL, #Z_FLAG + or CPU_FLAGL, Z_FLAG +@@: test (s), 1 << (SIZE - 1) tst (s), #(1 << (SIZE - 1)) + je short @f orrne CPU_FLAGL, CPU_FLAGL, #S_FLAG + or CPU_FLAGL, S_FLAG +@@: + + cmp (s), 0 cmp (s), #0 + jne short @1 orreq CPU_FLAGL, CPU_FLAGL, #Z_FLAG + or CPU_FLAGL, Z_FLAG beq @2 + jmp short @2 +@1: test (s), 1 << (SIZE - 1) tst (s), #(1 << (SIZE - 1)) + je short @2 orrne CPU_FLAGL, CPU_FLAGL, #S_FLAG + or CPU_FLAGL, S_FLAG +@2: + + mov reg, (s) movs reg, (s) + cmp reg, 0 + jne short @f + or CPU_FLAGL, Z_FLAG orreq CPU_FLAGL, CPU_FLAGL, Z_FLAG +@@: shr reg, SIZE - 8 mov reg, reg lsr #(SIZE - 8) + and reg, S_FLAG and reg, reg, #S_FLAG + or CPU_FLAGL, reg orr CPU_FLAGL, reg, CPU_FLAGL + diff --git a/source/src/vm/np21/i386c/ia32/ia32xc.mcr b/source/src/vm/np21/i386c/ia32/ia32xc.mcr new file mode 100644 index 000000000..1836ba686 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/ia32xc.mcr @@ -0,0 +1,1710 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_IA32XC_MCR__ +#define IA32_CPU_IA32XC_MCR__ + +#if defined(IA32_CROSS_CHECK) && defined(GCC_CPU_ARCH_IA32) + +#define IA32_CPU_ENABLE_XC + +/* + * arith + */ +#define XC_ADD_BYTE(r, d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT8 __r = __d; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _ADD_BYTE((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "addb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADD_BYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_ADD_BYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_ADD_BYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADD_BYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADD_WORD(r, d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _ADD_WORD((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "addw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax", "ecx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADD_WORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_ADD_WORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_ADD_WORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADD_WORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADD_DWORD(r, d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _ADD_DWORD((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "addl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax", "ecx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADD_DWORD: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_ADD_DWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_ADD_DWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADD_DWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_OR_BYTE(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT8 __r = __d; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _OR_BYTE((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "orb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_OR_BYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_OR_BYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_OR_BYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_OR_BYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_OR_WORD(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _OR_WORD((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "orw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_OR_WORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_OR_WORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_OR_WORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_OR_WORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_OR_DWORD(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _OR_DWORD((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushl %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "orl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_OR_DWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_OR_DWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_OR_DWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_OR_DWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_ADC_BYTE(r, d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT8 __r = __d; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _ADC_BYTE((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "adcb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADC_BYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_ADC_BYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_ADC_BYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADC_BYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADC_WORD(r, d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _ADC_WORD((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "adcw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADC_WORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_ADC_WORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_ADC_WORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADC_WORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_ADC_DWORD(r, d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _ADC_DWORD((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "adcl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ADC_DWORD: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_ADC_DWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_ADC_DWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_ADC_DWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_BYTE_SBB(r, d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT8 __r = __d; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_SBB((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "sbbb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SBB: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_BYTE_SBB: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SBB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_BYTE_SBB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SBB(r, d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _WORD_SBB((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "sbbw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SBB: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_WORD_SBB: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SBB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_WORD_SBB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SBB(r, d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_SBB((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "sbbl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SBB: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_DWORD_SBB: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SBB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_DWORD_SBB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_AND_BYTE(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT8 __r = __d; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _AND_BYTE((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "andb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ANDBYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_ANDBYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_ANDBYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ANDBYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_AND_WORD(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _AND_WORD((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "andw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ANDWORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_ANDWORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_ANDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ANDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_AND_DWORD(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _AND_DWORD((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "andl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_ANDDWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_ANDDWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_ANDDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_ANDDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SUB(r, d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT8 __r = __d; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_SUB((r), (d), (s)); \ + __R = (r) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "subb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SUB: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_BYTE_SUB: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SUB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_BYTE_SUB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SUB(r, d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SUB((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "subw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SUB: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_WORD_SUB: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SUB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_WORD_SUB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SUB(r, d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SUB((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "subl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SUB: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_DWORD_SUB: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SUB: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_DWORD_SUB: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_XOR(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT8 __r = __d; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_XOR((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "xorb %4, %%al\n\t" \ + "movb %%al, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_XORBYTE: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_XORBYTE: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_XORBYTE: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_XORBYTE: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_XOR(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_XOR((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movw %3, %%ax\n\t" \ + "xorw %4, %%ax\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_XORWORD: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_XORWORD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_XORWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_XORWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_XOR(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_XOR((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movl %3, %%eax\n\t" \ + "xorl %4, %%eax\n\t" \ + "movl %%eax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_XORDWORD: __s = %08x, __d = %08x", __s, __d); \ + ia32_warning("XC_XORDWORD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_XORDWORD: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZP_FLAG); \ + ia32_warning("XC_XORDWORD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_NEG(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_NEG((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "negb %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_NEG: __s = %02x", __s); \ + ia32_warning("XC_BYTE_NEG: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_NEG: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_BYTE_NEG: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_NEG(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_NEG((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "negw %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_NEG: __s = %04x", __s); \ + ia32_warning("XC_WORD_NEG: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_NEG: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_WORD_NEG: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_NEG(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_NEG((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "negl %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_NEG: __s = %08x", __s);\ + ia32_warning("XC_DWORD_NEG: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_NEG: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); \ + ia32_warning("XC_DWORD_NEG: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_MUL(r, d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __d = (d) & 0xff; \ + UINT16 __r; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_MUL((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "movb %4, %%ah\n\t" \ + "mulb %%ah\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_MUL: __s = %02x, __d = %02x", __s, __d); \ + ia32_warning("XC_BYTE_MUL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_MUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_MUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_MUL(r, d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT32 __r; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_MUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movw %3, %%ax\n\t" \ + "movw %4, %%dx\n\t" \ + "mulw %%dx\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "andl $0x0000ffff, %0\n\t" \ + "shll $16, %%edx\n\t" \ + "orl %%edx, %0\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_MUL: __s = %04x, __d = %04x", __s, __d); \ + ia32_warning("XC_WORD_MUL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_WORD_MUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_MUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_MUL(r, d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r; \ + UINT32 __h; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_MUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movl %4, %%eax\n\t" \ + "movl %5, %%edx\n\t" \ + "mull %%edx\n\t" \ + "movl %%eax, %0\n\t" \ + "movl %%edx, %1\n\t" \ + "lahf\n\t" \ + "movb %%ah, %2\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %3\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__h), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if ((__R != __r) || \ + (CPU_OV != __h) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_MUL: __s = %08x, __d = %08x", __s, __d);\ + ia32_warning("XC_DWORD_MUL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_MUL: CPU_OV == %08x, __h == %08x", \ + CPU_OV, __h); \ + ia32_warning("XC_DWORD_MUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_MUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_IMUL(r, d, s) \ +do { \ + SINT8 __s = (s) & 0xff; \ + SINT8 __d = (d) & 0xff; \ + SINT16 __R; \ + SINT16 __r; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_IMUL((r), (d), (s)); \ + __R = (r) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "movb %3, %%al\n\t" \ + "movb %4, %%ah\n\t" \ + "imulb %%ah\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_IMUL: __s = %02x, __d = %02x", __s, __d);\ + ia32_warning("XC_BYTE_IMUL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_BYTE_IMUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_IMUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_IMUL(r, d, s) \ +do { \ + SINT16 __s = (s) & 0xffff; \ + SINT16 __d = (d) & 0xffff; \ + SINT32 __r; \ + SINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_IMUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movw %3, %%ax\n\t" \ + "movw %4, %%dx\n\t" \ + "imulw %%dx\n\t" \ + "movw %%ax, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "andl $0x0000ffff, %0\n\t" \ + "shll $16, %%edx\n\t" \ + "orl %%edx, %0\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_IMUL: __s = %04x, __d = %04x", __s, __d);\ + ia32_warning("XC_WORD_IMUL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_WORD_IMUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_IMUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_IMUL(r, d, s) \ +do { \ + SINT64 __R; \ + SINT32 __s = (s); \ + SINT32 __d = (d); \ + UINT32 __r; \ + UINT32 __h; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_IMUL((r), (d), (s)); \ + __R = (r); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "push %%edx\n\t" \ + "movl %4, %%eax\n\t" \ + "movl %5, %%edx\n\t" \ + "imull %%edx\n\t" \ + "movl %%eax, %0\n\t" \ + "movl %%edx, %1\n\t" \ + "lahf\n\t" \ + "movb %%ah, %2\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %3\n\t" \ + "popl %%edx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__h), "=m" (__f), "=m" (__o) \ + : "m" (__d), "m" (__s) \ + : "eax", "edx"); \ + if (((UINT32)__R != __r) || \ + ((UINT32)(__R >> 32) != __h) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_IMUL: __s = %08x, __d = %08x",__s, __d);\ + ia32_warning("XC_DWORD_IMUL: __Rl = %08x, __r = %08x", \ + (UINT32)__R, __r); \ + ia32_warning("XC_DWORD_IMUL: __Rh == %08x, __h == %08x", \ + (UINT32)(__R >> 32), __h); \ + ia32_warning("XC_DWORD_IMUL: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_IMUL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert((UINT32)__R == __r); \ + assert((UINT32)(__R >> 32) == __h); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_BYTE_INC(s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_INC((s)); \ + __R = (s) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "incb %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_INC: __s = %02x", __s); \ + ia32_warning("XC_BYTE_INC: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_INC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_BYTE_INC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_INC(s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_INC((s)); \ + __R = (s) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "incw %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_INC: __s = %04x", __s); \ + ia32_warning("XC_WORD_INC: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_INC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_WORD_INC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_INC(s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_INC((s)); \ + __R = (s); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "incl %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_INC: __s = %08x", __s); \ + ia32_warning("XC_DWORD_INC: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_INC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_DWORD_INC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* flag no check */ +#define XC_BYTE_DEC(s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_DEC((s)); \ + __R = (s) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "decb %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_DEC: __s = %02x", __s); \ + ia32_warning("XC_BYTE_DEC: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_DEC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_BYTE_DEC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_DEC(s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_DEC((s)); \ + __R = (s) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "decw %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_DEC: __s = %04x", __s); \ + ia32_warning("XC_WORD_DEC: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_DEC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_WORD_DEC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_DEC(s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_DEC((s)); \ + __R = (s); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "push %%eax\n\t" \ + "decl %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZAP_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_DEC: __s = %08x", __s); \ + ia32_warning("XC_DWORD_DEC: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_DEC: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZAP_FLAG); \ + ia32_warning("XC_DWORD_DEC: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZAP_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define BYTE_ADD(r, d, s) XC_ADD_BYTE(r, d, s) +#define WORD_ADD(r, d, s) XC_ADD_WORD(r, d, s) +#define DWORD_ADD(r, d, s) XC_ADD_DWORD(r, d, s) +#define BYTE_OR(d, s) XC_OR_BYTE(d, s) +#define WORD_OR(d, s) XC_OR_WORD(d, s) +#define DWORD_OR(d, s) XC_OR_DWORD(d, s) +#define BYTE_ADC(r, d, s) XC_ADC_BYTE(r, d, s) +#define WORD_ADC(r, d, s) XC_ADC_WORD(r, d, s) +#define DWORD_ADC(r, d, s) XC_ADC_DWORD(r, d, s) +#define BYTE_SBB(r, d, s) XC_BYTE_SBB(r, d, s) +#define WORD_SBB(r, d, s) XC_WORD_SBB(r, d, s) +#define DWORD_SBB(r, d, s) XC_DWORD_SBB(r, d, s) +#define BYTE_AND(d, s) XC_AND_BYTE(d, s) +#define WORD_AND(d, s) XC_AND_WORD(d, s) +#define DWORD_AND(d, s) XC_AND_DWORD(d, s) +#define BYTE_SUB(r, d, s) XC_BYTE_SUB(r, d, s) +#define WORD_SUB(r, d, s) XC_WORD_SUB(r, d, s) +#define DWORD_SUB(r, d, s) XC_DWORD_SUB(r, d, s) +#define BYTE_XOR(d, s) XC_BYTE_XOR(d, s) +#define WORD_XOR(d, s) XC_WORD_XOR(d, s) +#define DWORD_XOR(d, s) XC_DWORD_XOR(d, s) +#define BYTE_NEG(d, s) XC_BYTE_NEG(d, s) +#define WORD_NEG(d, s) XC_WORD_NEG(d, s) +#define DWORD_NEG(d, s) XC_DWORD_NEG(d, s) +#define BYTE_MUL(r, d, s) XC_BYTE_MUL(r, d, s) +#define WORD_MUL(r, d, s) XC_WORD_MUL(r, d, s) +#define DWORD_MUL(r, d, s) XC_DWORD_MUL(r, d, s) +#define BYTE_IMUL(r, d, s) XC_BYTE_IMUL(r, d, s) +#define WORD_IMUL(r, d, s) XC_WORD_IMUL(r, d, s) +#define DWORD_IMUL(r, d, s) XC_DWORD_IMUL(r, d, s) +#define BYTE_INC(s) XC_BYTE_INC(s) +#define WORD_INC(s) XC_WORD_INC(s) +#define DWORD_INC(s) XC_DWORD_INC(s) +#define BYTE_DEC(s) XC_BYTE_DEC(s) +#define WORD_DEC(s) XC_WORD_DEC(s) +#define DWORD_DEC(s) XC_DWORD_DEC(s) + +#define ADD_BYTE(r, d, s) XC_ADD_BYTE(r, d, s) +#define ADD_WORD(r, d, s) XC_ADD_WORD(r, d, s) +#define ADD_DWORD(r, d, s) XC_ADD_DWORD(r, d, s) +#define OR_BYTE(d, s) XC_OR_BYTE(d, s) +#define OR_WORD(d, s) XC_OR_WORD(d, s) +#define OR_DWORD(d, s) XC_OR_DWORD(d, s) +#define ADC_BYTE(r, d, s) XC_ADC_BYTE(r, d, s) +#define ADC_WORD(r, d, s) XC_ADC_WORD(r, d, s) +#define ADC_DWORD(r, d, s) XC_ADC_DWORD(r, d, s) +#define AND_BYTE(d, s) XC_AND_BYTE(d, s) +#define AND_WORD(d, s) XC_AND_WORD(d, s) +#define AND_DWORD(d, s) XC_AND_DWORD(d, s) + +#define XC_STORE_FLAGL() UINT8 __xc_flagl = CPU_FLAGL + +#elif defined(IA32_CROSS_CHECK) && defined(_MSC_VER) + +#include "ia32xc_msc.mcr" + +#else /* !(IA32_CROSS_CHECK && __GNUC__ && (i386) || __i386__)) */ + +#define BYTE_ADD(r, d, s) _ADD_BYTE(r, d, s) +#define WORD_ADD(r, d, s) _ADD_WORD(r, d, s) +#define DWORD_ADD(r, d, s) _ADD_DWORD(r, d, s) +#define BYTE_OR(d, s) _OR_BYTE(d, s) +#define WORD_OR(d, s) _OR_WORD(d, s) +#define DWORD_OR(d, s) _OR_DWORD(d, s) +#define BYTE_ADC(r, d, s) _ADC_BYTE(r, d, s) +#define WORD_ADC(r, d, s) _ADC_WORD(r, d, s) +#define DWORD_ADC(r, d, s) _ADC_DWORD(r, d, s) +#define BYTE_SBB(r, d, s) _BYTE_SBB(r, d, s) +#define WORD_SBB(r, d, s) _WORD_SBB(r, d, s) +#define DWORD_SBB(r, d, s) _DWORD_SBB(r, d, s) +#define BYTE_AND(d, s) _AND_BYTE(d, s) +#define WORD_AND(d, s) _AND_WORD(d, s) +#define DWORD_AND(d, s) _AND_DWORD(d, s) +#define BYTE_SUB(r, d, s) _BYTE_SUB(r, d, s) +#define WORD_SUB(r, d, s) _WORD_SUB(r, d, s) +#define DWORD_SUB(r, d, s) _DWORD_SUB(r, d, s) +#define BYTE_XOR(d, s) _BYTE_XOR(d, s) +#define WORD_XOR(d, s) _WORD_XOR(d, s) +#define DWORD_XOR(d, s) _DWORD_XOR(d, s) +#define BYTE_NEG(d, s) _BYTE_NEG(d, s) +#define WORD_NEG(d, s) _WORD_NEG(d, s) +#define DWORD_NEG(d, s) _DWORD_NEG(d, s) +#define BYTE_MUL(r, d, s) _BYTE_MUL(r, d, s) +#define WORD_MUL(r, d, s) _WORD_MUL(r, d, s) +#define DWORD_MUL(r, d, s) _DWORD_MUL(r, d, s) +#define BYTE_IMUL(r, d, s) _BYTE_IMUL(r, d, s) +#define WORD_IMUL(r, d, s) _WORD_IMUL(r, d, s) +#define DWORD_IMUL(r, d, s) _DWORD_IMUL(r, d, s) +#define BYTE_INC(s) _BYTE_INC(s) +#define WORD_INC(s) _WORD_INC(s) +#define DWORD_INC(s) _DWORD_INC(s) +#define BYTE_DEC(s) _BYTE_DEC(s) +#define WORD_DEC(s) _WORD_DEC(s) +#define DWORD_DEC(s) _DWORD_DEC(s) + +#define ADD_BYTE(r, d, s) _ADD_BYTE(r, d, s) +#define ADD_WORD(r, d, s) _ADD_WORD(r, d, s) +#define ADD_DWORD(r, d, s) _ADD_DWORD(r, d, s) +#define OR_BYTE(d, s) _OR_BYTE(d, s) +#define OR_WORD(d, s) _OR_WORD(d, s) +#define OR_DWORD(d, s) _OR_DWORD(d, s) +#define ADC_BYTE(r, d, s) _ADC_BYTE(r, d, s) +#define ADC_WORD(r, d, s) _ADC_WORD(r, d, s) +#define ADC_DWORD(r, d, s) _ADC_DWORD(r, d, s) +#define AND_BYTE(d, s) _AND_BYTE(d, s) +#define AND_WORD(d, s) _AND_WORD(d, s) +#define AND_DWORD(d, s) _AND_DWORD(d, s) + +#define XC_STORE_FLAGL() + +#endif /* IA32_CROSS_CHECK && GCC_CPU_ARCH_IA32 */ + +#endif /* IA32_CPU_IA32_MCR__ */ diff --git a/source/src/vm/np21/i386c/ia32/ia32xc_msc.mcr b/source/src/vm/np21/i386c/ia32/ia32xc_msc.mcr new file mode 100644 index 000000000..287a6a283 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/ia32xc_msc.mcr @@ -0,0 +1,547 @@ + +// Crosscheck for VC++ + +#define BYTE_ADC(r, d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT8 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov al, _d } \ + __asm { adc al, _s } \ + __asm { mov _r, al } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _ADC_BYTE((r), (d), (s)); \ + if ((_r != (UINT8)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("adcb r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_ADC(r, d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT16 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov ax, _d } \ + __asm { adc ax, _s } \ + __asm { mov _r, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _ADC_WORD((r), (d), (s)); \ + if ((_r != (UINT16)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("adcw r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_ADC(r, d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT32 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov eax, _d } \ + __asm { adc eax, _s } \ + __asm { mov _r, eax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _ADC_DWORD((r), (d), (s)); \ + if ((_r != (UINT32)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("adcd r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_ADD(r, d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT8 _r; \ + UINT8 _f, _ov; \ + __asm { mov al, _d } \ + __asm { add al, _s } \ + __asm { mov _r, al } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _ADD_BYTE((r), (d), (s)); \ + if ((_r != (UINT8)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("addb r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_ADD(r, d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT16 _r; \ + UINT8 _f, _ov; \ + __asm { mov ax, _d } \ + __asm { add ax, _s } \ + __asm { mov _r, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _ADD_WORD((r), (d), (s)); \ + if ((_r != (UINT16)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("addw r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_ADD(r, d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT32 _r; \ + UINT8 _f, _ov; \ + __asm { mov eax, _d } \ + __asm { add eax, _s } \ + __asm { mov _r, eax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _ADD_DWORD((r), (d), (s)); \ + if ((_r != (UINT32)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("addd r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_AND(d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov al, _s } \ + __asm { and _d, al } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _AND_BYTE((d), (s)); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("andb r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_AND(d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov ax, _s } \ + __asm { and _d, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _AND_WORD((d), (s)); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("andw r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_AND(d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov eax, _s } \ + __asm { and _d, eax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _AND_DWORD((d), (s)); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("andd r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_DEC(s) { \ + UINT8 _s = (s); \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { dec _s } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_DEC((s)); \ + if ((_s != (UINT8)(s)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("decb r=%x:%x f=%x:%x o=%d %d", _s, s, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_DEC(s) { \ + UINT16 _s = (s); \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { dec _s } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_DEC((s)); \ + if ((_s != (UINT16)(s)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("decd r=%x:%x f=%x:%x o=%d %d", _s, s, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_DEC(s) { \ + UINT32 _s = (s); \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { dec _s } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_DEC((s)); \ + if ((_s != (UINT32)(s)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("decd r=%x:%x f=%x:%x o=%d %d", _s, s, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_INC(s) { \ + UINT8 _s = (s); \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { inc _s } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_INC((s)); \ + if ((_s != (UINT8)(s)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("incb r=%x:%x f=%x:%x o=%d %d", _s, s, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_INC(s) { \ + UINT16 _s = (s); \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { inc _s } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_INC((s)); \ + if ((_s != (UINT16)(s)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("incd r=%x:%x f=%x:%x o=%d %d", _s, s, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_INC(s) { \ + UINT32 _s = (s); \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { inc _s } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_INC((s)); \ + if ((_s != (UINT32)(s)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("incd r=%x:%x f=%x:%x o=%d %d", _s, s, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_NEG(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + __asm { neg _d } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_NEG((d), (s)); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("negb r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_NEG(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + __asm { neg _d } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_NEG((d), (s)); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("negw r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_NEG(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + __asm { neg _d } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_NEG((d), (s)); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("negd r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_OR(d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov al, _s } \ + __asm { or _d, al } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _OR_BYTE((d), (s)); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("orb r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_OR(d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov ax, _s } \ + __asm { or _d, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _OR_WORD((d), (s)); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("orw r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_OR(d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov eax, _s } \ + __asm { or _d, eax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _OR_DWORD((d), (s)); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("ord r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_SBB(r, d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT8 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov al, _d } \ + __asm { sbb al, _s } \ + __asm { mov _r, al } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SBB((r), (d), (s)); \ + if ((_r != (UINT8)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sbbb r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SBB(r, d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT16 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov ax, _d } \ + __asm { sbb ax, _s } \ + __asm { mov _r, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SBB((r), (d), (s)); \ + if ((_r != (UINT16)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sbbw r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SBB(r, d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT32 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov eax, _d } \ + __asm { sbb eax, _s } \ + __asm { mov _r, eax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SBB((r), (d), (s)); \ + if ((_r != (UINT32)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sbbd r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_SUB(r, d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT8 _r; \ + UINT8 _f, _ov; \ + __asm { mov al, _d } \ + __asm { sub al, _s } \ + __asm { mov _r, al } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SUB((r), (d), (s)); \ + if ((_r != (UINT8)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("subb r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SUB(r, d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT16 _r; \ + UINT8 _f, _ov; \ + __asm { mov ax, _d } \ + __asm { sub ax, _s } \ + __asm { mov _r, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SUB((r), (d), (s)); \ + if ((_r != (UINT16)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("subw r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SUB(r, d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT32 _r; \ + UINT8 _f, _ov; \ + __asm { mov eax, _d } \ + __asm { sub eax, _s } \ + __asm { mov _r, eax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SUB((r), (d), (s)); \ + if ((_r != (UINT32)(r)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("subd r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_XOR(d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov al, _s } \ + __asm { xor _d, al } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_XOR((d), (s)); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("xorb r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_XOR(d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov ax, _s } \ + __asm { xor _d, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_XOR((d), (s)); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("xorw r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_XOR(d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT8 _f, _ov; \ + __asm { mov eax, _s } \ + __asm { xor _d, eax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_XOR((d), (s)); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZAPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("xord r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + +// ---- + +#define BYTE_IMUL(r, d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT16 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov al, _d } \ + __asm { imul _s } \ + __asm { mov _r, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_IMUL((r), (d), (s)); \ + if ((_r != (UINT16)(r)) || ((_f ^ CPU_FLAGL) & C_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("imulb r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_IMUL(r, d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT16 _rl, _rh; \ + UINT32 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov ax, _d } \ + __asm { imul _s } \ + __asm { mov _rl, ax } \ + __asm { mov _rh, dx } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _r = _rl + (_rh << 16); \ + _WORD_IMUL((r), (d), (s)); \ + if ((_r != (UINT32)(r)) || ((_f ^ CPU_FLAGL) & C_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("imulw r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_IMUL(r, d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT32 _rl, _rh; \ + UINT64 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov eax, _d } \ + __asm { imul _s } \ + __asm { mov _rl, eax } \ + __asm { mov _rh, edx } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _r = (UINT64)_rl + ((UINT64)_rh << 32); \ + _DWORD_IMUL((r), (d), (s)); \ + if ((_r != (UINT64)(r)) || ((_f ^ CPU_FLAGL) & C_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("imuld r=%x%x:%x%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_MUL(r, d, s) { \ + UINT8 _d = (d); \ + UINT8 _s = (s); \ + UINT16 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov al, _d } \ + __asm { mul _s } \ + __asm { mov _r, ax } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_MUL((r), (d), (s)); \ + if ((_r != (UINT16)(r)) || ((_f ^ CPU_FLAGL) & C_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("mulb r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_MUL(r, d, s) { \ + UINT16 _d = (d); \ + UINT16 _s = (s); \ + UINT16 _rl, _rh; \ + UINT32 _r; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov ax, _d } \ + __asm { mul _s } \ + __asm { mov _rl, ax } \ + __asm { mov _rh, dx } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _r = _rl + (_rh << 16); \ + _WORD_MUL((r), (d), (s)); \ + if ((_r != (UINT32)(r)) || ((_f ^ CPU_FLAGL) & C_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("mulw r=%x:%x f=%x:%x o=%d %d", _r, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_MUL(r, d, s) { \ + UINT32 _d = (d); \ + UINT32 _s = (s); \ + UINT32 _r, _o; \ + UINT8 _f, _ov; \ + __asm { bt CPU_FLAG, 0 } \ + __asm { mov eax, _d } \ + __asm { mul _s } \ + __asm { mov _r, eax } \ + __asm { mov _o, edx } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_MUL((r), (d), (s)); \ + if ((_r != (UINT32)(r)) || (_o != CPU_OV) || ((_f ^ CPU_FLAGL) & C_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("muld r=%x%x:%x%x f=%x:%x o=%d %d", _o, _r, CPU_OV, r, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + +// ---- + +#define AND_BYTE(d, s) BYTE_AND(d, s) +#define AND_WORD(d, s) WORD_AND(d, s) +#define AND_DWORD(d, s) DWORD_AND(d, s) + +#define XC_STORE_FLAGL() + diff --git a/source/src/vm/np21/i386c/ia32/inst_table.cpp b/source/src/vm/np21/i386c/ia32/inst_table.cpp new file mode 100644 index 000000000..c6e87fa4c --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/inst_table.cpp @@ -0,0 +1,3149 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" + +#include "inst_table.h" +#include "groups.h" + +#include "instructions/bin_arith.h" +#include "instructions/bit_byte.h" +#include "instructions/ctrl_trans.h" +#include "instructions/data_trans.h" +#include "instructions/dec_arith.h" +#include "instructions/flag_ctrl.h" +#include "instructions/logic_arith.h" +#include "instructions/misc_inst.h" +#include "instructions/seg_reg.h" +#include "instructions/shift_rotate.h" +#include "instructions/string_inst.h" +#include "instructions/system_inst.h" + +#include "instructions/fpu/fp.h" +#include "instructions/mmx/mmx.h" +#include "instructions/mmx/3dnow.h" +#include "instructions/sse/sse.h" +#include "instructions/sse2/sse2.h" +#include "instructions/sse3/sse3.h" + +/* + * UNDEF OP + */ +static void +undef_op(void) +{ + + EXCEPTION(UD_EXCEPTION, 0); +} + +static void CPUCALL +undef_op2(UINT32 v) +{ + + EXCEPTION(UD_EXCEPTION, 0); +} + + +UINT8 insttable_info[256] = { + 0, /* 00 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 08 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 10 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 18 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 20 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* ES: */ + 0, + 0, /* 28 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* CS: */ + 0, + + 0, /* 30 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* SS: */ + 0, + 0, /* 38 */ + 0, + 0, + 0, + 0, + 0, + INST_PREFIX, /* DS: */ + 0, + + 0, /* 40 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 48 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 50 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 58 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 60 */ + 0, + 0, + 0, + INST_PREFIX, /* FS: */ + INST_PREFIX, /* GS: */ + INST_PREFIX, /* OpSize: */ + INST_PREFIX, /* AddrSize: */ + 0, /* 68 */ + 0, + 0, + 0, + INST_STRING, /* INSB_YbDX */ + INST_STRING, /* INSW_YvDX */ + INST_STRING, /* OUTSB_DXXb */ + INST_STRING, /* OUTSW_DXXv */ + + 0, /* 70 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 78 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 80 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 88 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* 90 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 98 */ + 0, + 0, + INST_PREFIX, /* FWAIT */ + 0, + 0, + 0, + 0, + + 0, /* A0 */ + 0, + 0, + 0, + INST_STRING, /* MOVSB_XbYb */ + INST_STRING, /* MOVSW_XvYv */ + INST_STRING | REP_CHECKZF, /* CMPSB_XbYb */ + INST_STRING | REP_CHECKZF, /* CMPSW_XvYv */ + 0, /* A8 */ + 0, + INST_STRING, /* STOSB_YbAL */ + INST_STRING, /* STOSW_YveAX */ + INST_STRING, /* LODSB_ALXb */ + INST_STRING, /* LODSW_eAXXv */ + INST_STRING | REP_CHECKZF, /* SCASB_ALXb */ + INST_STRING | REP_CHECKZF, /* SCASW_eAXXv */ + + 0, /* B0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* B8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* C0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* C8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* D0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* D8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + 0, /* E0 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* E8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + + INST_PREFIX, /* F0 *//* LOCK */ + 0, + INST_PREFIX, /* REPNE */ + INST_PREFIX, /* REPE */ + 0, + 0, + 0, + 0, + 0, /* F8 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; + +void (*insttable_1byte[2][256])(void) = { + /* 16bit */ + { + ADD_EbGb, /* 00 */ + ADD_EwGw, + ADD_GbEb, + ADD_GwEw, + ADD_ALIb, + ADD_AXIw, + PUSH16_ES, + POP16_ES, + OR_EbGb, /* 08 */ + OR_EwGw, + OR_GbEb, + OR_GwEw, + OR_ALIb, + OR_AXIw, + PUSH16_CS, + _2byte_ESC16, + + ADC_EbGb, /* 10 */ + ADC_EwGw, + ADC_GbEb, + ADC_GwEw, + ADC_ALIb, + ADC_AXIw, + PUSH16_SS, + POP16_SS, + SBB_EbGb, /* 18 */ + SBB_EwGw, + SBB_GbEb, + SBB_GwEw, + SBB_ALIb, + SBB_AXIw, + PUSH16_DS, + POP16_DS, + + AND_EbGb, /* 20 */ + AND_EwGw, + AND_GbEb, + AND_GwEw, + AND_ALIb, + AND_AXIw, + Prefix_ES, + DAA, + SUB_EbGb, /* 28 */ + SUB_EwGw, + SUB_GbEb, + SUB_GwEw, + SUB_ALIb, + SUB_AXIw, + Prefix_CS, + DAS, + + XOR_EbGb, /* 30 */ + XOR_EwGw, + XOR_GbEb, + XOR_GwEw, + XOR_ALIb, + XOR_AXIw, + Prefix_SS, + AAA, + CMP_EbGb, /* 38 */ + CMP_EwGw, + CMP_GbEb, + CMP_GwEw, + CMP_ALIb, + CMP_AXIw, + Prefix_DS, + AAS, + + INC_AX, /* 40 */ + INC_CX, + INC_DX, + INC_BX, + INC_SP, + INC_BP, + INC_SI, + INC_DI, + DEC_AX, /* 48 */ + DEC_CX, + DEC_DX, + DEC_BX, + DEC_SP, + DEC_BP, + DEC_SI, + DEC_DI, + + PUSH_AX, /* 50 */ + PUSH_CX, + PUSH_DX, + PUSH_BX, + PUSH_SP, + PUSH_BP, + PUSH_SI, + PUSH_DI, + POP_AX, /* 58 */ + POP_CX, + POP_DX, + POP_BX, + POP_SP, + POP_BP, + POP_SI, + POP_DI, + + PUSHA, /* 60 */ + POPA, + BOUND_GwMa, + ARPL_EwGw, + Prefix_FS, + Prefix_GS, + OpSize, + AddrSize, + PUSH_Iw, /* 68 */ + IMUL_GwEwIw, + PUSH_Ib, + IMUL_GwEwIb, + INSB_YbDX, + INSW_YwDX, + OUTSB_DXXb, + OUTSW_DXXw, + + JO_Jb, /* 70 */ + JNO_Jb, + JC_Jb, + JNC_Jb, + JZ_Jb, + JNZ_Jb, + JNA_Jb, + JA_Jb, + JS_Jb, /* 78 */ + JNS_Jb, + JP_Jb, + JNP_Jb, + JL_Jb, + JNL_Jb, + JLE_Jb, + JNLE_Jb, + + Grp1_EbIb, /* 80 */ + Grp1_EwIw, + Grp1_EbIb, + Grp1_EwIb, + TEST_EbGb, + TEST_EwGw, + XCHG_EbGb, + XCHG_EwGw, + MOV_EbGb, /* 88 */ + MOV_EwGw, + MOV_GbEb, + MOV_GwEw, + MOV_EwSw, + LEA_GwM, + MOV_SwEw, + POP_Ew, + + _NOP, /* 90 */ + XCHG_CXAX, + XCHG_DXAX, + XCHG_BXAX, + XCHG_SPAX, + XCHG_BPAX, + XCHG_SIAX, + XCHG_DIAX, + CBW, /* 98 */ + CWD, + CALL16_Ap, + FPU_FWAIT, + PUSHF_Fw, + POPF_Fw, + SAHF, + LAHF, + + MOV_ALOb, /* A0 */ + MOV_AXOw, + MOV_ObAL, + MOV_OwAX, + MOVSB_XbYb, + MOVSW_XwYw, + CMPSB_XbYb, + CMPSW_XwYw, + TEST_ALIb, /* A8 */ + TEST_AXIw, + STOSB_YbAL, + STOSW_YwAX, + LODSB_ALXb, + LODSW_AXXw, + SCASB_ALXb, + SCASW_AXXw, + + MOV_ALIb, /* B0 */ + MOV_CLIb, + MOV_DLIb, + MOV_BLIb, + MOV_AHIb, + MOV_CHIb, + MOV_DHIb, + MOV_BHIb, + MOV_AXIw, /* B8 */ + MOV_CXIw, + MOV_DXIw, + MOV_BXIw, + MOV_SPIw, + MOV_BPIw, + MOV_SIIw, + MOV_DIIw, + + Grp2_EbIb, /* C0 */ + Grp2_EwIb, + RETnear16_Iw, + RETnear16, + LES_GwMp, + LDS_GwMp, + MOV_EbIb, + MOV_EwIw, + ENTER16_IwIb, /* C8 */ + LEAVE, + RETfar16_Iw, + RETfar16, + INT3, + INT_Ib, + INTO, + IRET, + + Grp2_Eb, /* D0 */ + Grp2_Ew, + Grp2_EbCL, + Grp2_EwCL, + AAM, + AAD, + SALC, /* undoc(8086) */ + XLAT, + NOFPU_ESC0, /* D8 */ + NOFPU_ESC1, + NOFPU_ESC2, + NOFPU_ESC3, + NOFPU_ESC4, + NOFPU_ESC5, + NOFPU_ESC6, + NOFPU_ESC7, + + LOOPNE_Jb, /* E0 */ + LOOPE_Jb, + LOOP_Jb, + JeCXZ_Jb, + IN_ALIb, + IN_AXIb, + OUT_IbAL, + OUT_IbAX, + CALL_Aw, /* E8 */ + JMP_Jw, + JMP16_Ap, + JMP_Jb, + IN_ALDX, + IN_AXDX, + OUT_DXAL, + OUT_DXAX, + + _LOCK, /* F0 */ + INT1, + _REPNE, + _REPE, + HLT, + CMC, + Grp3_Eb, + Grp3_Ew, + CLC, /* F8 */ + STC, + CLI, + STI, + CLD, + STD, + Grp4, + Grp5_Ew, + }, + + /* 32bit */ + { + ADD_EbGb, /* 00 */ + ADD_EdGd, + ADD_GbEb, + ADD_GdEd, + ADD_ALIb, + ADD_EAXId, + PUSH32_ES, + POP32_ES, + OR_EbGb, /* 08 */ + OR_EdGd, + OR_GbEb, + OR_GdEd, + OR_ALIb, + OR_EAXId, + PUSH32_CS, + _2byte_ESC32, + + ADC_EbGb, /* 10 */ + ADC_EdGd, + ADC_GbEb, + ADC_GdEd, + ADC_ALIb, + ADC_EAXId, + PUSH32_SS, + POP32_SS, + SBB_EbGb, /* 18 */ + SBB_EdGd, + SBB_GbEb, + SBB_GdEd, + SBB_ALIb, + SBB_EAXId, + PUSH32_DS, + POP32_DS, + + AND_EbGb, /* 20 */ + AND_EdGd, + AND_GbEb, + AND_GdEd, + AND_ALIb, + AND_EAXId, + undef_op, /* Prefix_ES */ + DAA, + SUB_EbGb, /* 28 */ + SUB_EdGd, + SUB_GbEb, + SUB_GdEd, + SUB_ALIb, + SUB_EAXId, + undef_op, /* Prefix_CS */ + DAS, + + XOR_EbGb, /* 30 */ + XOR_EdGd, + XOR_GbEb, + XOR_GdEd, + XOR_ALIb, + XOR_EAXId, + undef_op, /* Prefix_SS */ + AAA, + CMP_EbGb, /* 38 */ + CMP_EdGd, + CMP_GbEb, + CMP_GdEd, + CMP_ALIb, + CMP_EAXId, + undef_op, /* Prefix_DS */ + AAS, + + INC_EAX, /* 40 */ + INC_ECX, + INC_EDX, + INC_EBX, + INC_ESP, + INC_EBP, + INC_ESI, + INC_EDI, + DEC_EAX, /* 48 */ + DEC_ECX, + DEC_EDX, + DEC_EBX, + DEC_ESP, + DEC_EBP, + DEC_ESI, + DEC_EDI, + + PUSH_EAX, /* 50 */ + PUSH_ECX, + PUSH_EDX, + PUSH_EBX, + PUSH_ESP, + PUSH_EBP, + PUSH_ESI, + PUSH_EDI, + POP_EAX, /* 58 */ + POP_ECX, + POP_EDX, + POP_EBX, + POP_ESP, + POP_EBP, + POP_ESI, + POP_EDI, + + PUSHAD, /* 60 */ + POPAD, + BOUND_GdMa, + ARPL_EwGw, + undef_op, /* Prefix_FS */ + undef_op, /* Prefix_GS */ + undef_op, /* OpSize */ + undef_op, /* AddrSize */ + PUSH_Id, /* 68 */ + IMUL_GdEdId, + PUSH_Ib, + IMUL_GdEdIb, + INSB_YbDX, + INSD_YdDX, + OUTSB_DXXb, + OUTSD_DXXd, + + JO_Jb, /* 70 */ + JNO_Jb, + JC_Jb, + JNC_Jb, + JZ_Jb, + JNZ_Jb, + JNA_Jb, + JA_Jb, + JS_Jb, /* 78 */ + JNS_Jb, + JP_Jb, + JNP_Jb, + JL_Jb, + JNL_Jb, + JLE_Jb, + JNLE_Jb, + + Grp1_EbIb, /* 80 */ + Grp1_EdId, + Grp1_EbIb, + Grp1_EdIb, + TEST_EbGb, + TEST_EdGd, + XCHG_EbGb, + XCHG_EdGd, + MOV_EbGb, /* 88 */ + MOV_EdGd, + MOV_GbEb, + MOV_GdEd, + MOV_EdSw, + LEA_GdM, + MOV_SwEw, + POP_Ed, + + _NOP, /* 90 */ + XCHG_ECXEAX, + XCHG_EDXEAX, + XCHG_EBXEAX, + XCHG_ESPEAX, + XCHG_EBPEAX, + XCHG_ESIEAX, + XCHG_EDIEAX, + CWDE, /* 98 */ + CDQ, + CALL32_Ap, + undef_op, /* FWAIT */ + PUSHFD_Fd, + POPFD_Fd, + SAHF, + LAHF, + + MOV_ALOb, /* A0 */ + MOV_EAXOd, + MOV_ObAL, + MOV_OdEAX, + MOVSB_XbYb, + MOVSD_XdYd, + CMPSB_XbYb, + CMPSD_XdYd, + TEST_ALIb, /* A8 */ + TEST_EAXId, + STOSB_YbAL, + STOSD_YdEAX, + LODSB_ALXb, + LODSD_EAXXd, + SCASB_ALXb, + SCASD_EAXXd, + + MOV_ALIb, /* B0 */ + MOV_CLIb, + MOV_DLIb, + MOV_BLIb, + MOV_AHIb, + MOV_CHIb, + MOV_DHIb, + MOV_BHIb, + MOV_EAXId, /* B8 */ + MOV_ECXId, + MOV_EDXId, + MOV_EBXId, + MOV_ESPId, + MOV_EBPId, + MOV_ESIId, + MOV_EDIId, + + Grp2_EbIb, /* C0 */ + Grp2_EdIb, + RETnear32_Iw, + RETnear32, + LES_GdMp, + LDS_GdMp, + MOV_EbIb, + MOV_EdId, + ENTER32_IwIb, /* C8 */ + LEAVE, + RETfar32_Iw, + RETfar32, + INT3, + INT_Ib, + INTO, + IRET, + + Grp2_Eb, /* D0 */ + Grp2_Ed, + Grp2_EbCL, + Grp2_EdCL, + AAM, + AAD, + SALC, /* undoc(8086) */ + XLAT, + NOFPU_ESC0, /* D8 */ + NOFPU_ESC1, + NOFPU_ESC2, + NOFPU_ESC3, + NOFPU_ESC4, + NOFPU_ESC5, + NOFPU_ESC6, + NOFPU_ESC7, + + LOOPNE_Jb, /* E0 */ + LOOPE_Jb, + LOOP_Jb, + JeCXZ_Jb, + IN_ALIb, + IN_EAXIb, + OUT_IbAL, + OUT_IbEAX, + CALL_Ad, /* E8 */ + JMP_Jd, + JMP32_Ap, + JMP_Jb, + IN_ALDX, + IN_EAXDX, + OUT_DXAL, + OUT_DXEAX, + + _LOCK, /* F0 */ + INT1, + undef_op, /* repne */ + undef_op, /* repe */ + HLT, + CMC, + Grp3_Eb, + Grp3_Ed, + CLC, /* F8 */ + STC, + CLI, + STI, + CLD, + STD, + Grp4, + Grp5_Ed, + }, +}; + + +void (*insttable_1byte_repfunc[2][256])(int reptype) = { + /* 16bit */ + { + NULL, /* 00 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 08 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 10 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 18 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 20 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 28 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 30 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 38 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 40 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 48 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 50 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 58 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 60 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 68 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 70 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 78 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 80 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 88 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 90 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 98 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* A0 */ + NULL, + NULL, + NULL, + MOVSB_XbYb_rep, + MOVSW_XwYw_rep, + CMPSB_XbYb_rep, + CMPSW_XwYw_rep, + NULL, /* A8 */ + NULL, + STOSB_YbAL_rep, + STOSW_YwAX_rep, + NULL, + NULL, + NULL, + NULL, + + NULL, /* B0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* B8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* C0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* C8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* D0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* undoc(8086) */ + NULL, + NULL, /* D8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* E0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* E8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* F0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* F8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }, + + /* 32bit */ + { + NULL, /* 00 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 08 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 10 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 18 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 20 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 28 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 30 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 38 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 40 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 48 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 50 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 58 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 60 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 68 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 70 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 78 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 80 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 88 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 90 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 98 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* A0 */ + NULL, + NULL, + NULL, + MOVSB_XbYb_rep, + MOVSD_XdYd_rep, + CMPSB_XbYb_rep, + CMPSD_XdYd_rep, + NULL, /* A8 */ + NULL, + STOSB_YbAL_rep, + STOSD_YdEAX_rep, + NULL, + NULL, + NULL, + NULL, + + NULL, /* B0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* B8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* C0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* C8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* D0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* undoc(8086) */ + NULL, + NULL, /* D8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* E0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* E8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* F0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* F8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + }, +}; + +void (*insttable_2byte[2][256])(void) = { + /* 16bit */ + { + Grp6, /* 00 */ + Grp7, + LAR_GwEw, + LSL_GwEw, + undef_op, + LOADALL286, /* undoc(286) */ + CLTS, + LOADALL, + INVD, /* 08 */ + WBINVD, + undef_op, + UD2, + undef_op, + AMD3DNOW_PREFETCH, + AMD3DNOW_FEMMS, + undef_op, + + SSE_MOVUPSmem2xmm, /* 10 */ + SSE_MOVUPSxmm2mem, + SSE_MOVLPSmem2xmm, // + MOVHLPS + SSE_MOVLPSxmm2mem, + SSE_UNPCKLPS, + SSE_UNPCKHPS, + SSE_MOVHPSmem2xmm, // + MOVLHPS + SSE_MOVHPSxmm2mem, + SSE_PREFETCHTx, /* 18 */ + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + + MOV_RdCd, /* 20 */ + MOV_RdDd, + MOV_CdRd, + MOV_DdRd, + MOV_RdTd, + undef_op, + MOV_TdRd, + undef_op, + SSE_MOVAPSmem2xmm, /* 28 */ + SSE_MOVAPSxmm2mem, + SSE_CVTPI2PS, + SSE_MOVNTPS, + SSE_CVTTPS2PI, + SSE_CVTPS2PI, + SSE_UCOMISS, + SSE_COMISS, + + WRMSR, /* 30 */ + RDTSC, + RDMSR, + RDPMC, + SYSENTER, + SYSEXIT, + undef_op, + undef_op, + undef_op, /* 38 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + CMOVO_GwEw, /* 40 */ + CMOVNO_GwEw, + CMOVC_GwEw, + CMOVNC_GwEw, + CMOVZ_GwEw, + CMOVNZ_GwEw, + CMOVNA_GwEw, + CMOVA_GwEw, + CMOVS_GwEw, /* 48 */ + CMOVNS_GwEw, + CMOVP_GwEw, + CMOVNP_GwEw, + CMOVL_GwEw, + CMOVNL_GwEw, + CMOVLE_GwEw, + CMOVNLE_GwEw, + + SSE_MOVMSKPS, /* 50 */ + SSE_SQRTPS, + SSE_RSQRTPS, + SSE_RCPPS, + SSE_ANDPS, + SSE_ANDNPS, + SSE_ORPS, + SSE_XORPS, + SSE_ADDPS, /* 58 */ + SSE_MULPS, + SSE2_CVTPS2PD, + SSE2_CVTDQ2PS, + SSE_SUBPS, + SSE_MINPS, + SSE_DIVPS, + SSE_MAXPS, + + MMX_PUNPCKLBW, /* 60 */ + MMX_PUNPCKLWD, + MMX_PUNPCKLDQ, + MMX_PACKSSWB, + MMX_PCMPGTB, + MMX_PCMPGTW, + MMX_PCMPGTD, + MMX_PACKUSWB, + MMX_PUNPCKHBW, /* 68 */ + MMX_PUNPCKHWD, + MMX_PUNPCKHDQ, + MMX_PACKSSDW, + undef_op, + undef_op, + MMX_MOVD_mm_rm32, + MMX_MOVQ_mm_mmm64, + + SSE_PSHUFW, /* 70 */ + MMX_PSxxW_imm8, + MMX_PSxxD_imm8, + MMX_PSxxQ_imm8, + MMX_PCMPEQB, + MMX_PCMPEQW, + MMX_PCMPEQD, + MMX_EMMS, + undef_op, /* 78 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + MMX_MOVD_rm32_mm, + MMX_MOVQ_mmm64_mm, + + JO_Jw, /* 80 */ + JNO_Jw, + JC_Jw, + JNC_Jw, + JZ_Jw, + JNZ_Jw, + JNA_Jw, + JA_Jw, + JS_Jw, /* 88 */ + JNS_Jw, + JP_Jw, + JNP_Jw, + JL_Jw, + JNL_Jw, + JLE_Jw, + JNLE_Jw, + + SETO_Eb, /* 90 */ + SETNO_Eb, + SETC_Eb, + SETNC_Eb, + SETZ_Eb, + SETNZ_Eb, + SETNA_Eb, + SETA_Eb, + SETS_Eb, /* 98 */ + SETNS_Eb, + SETP_Eb, + SETNP_Eb, + SETL_Eb, + SETNL_Eb, + SETLE_Eb, + SETNLE_Eb, + + PUSH16_FS, /* A0 */ + POP16_FS, + _CPUID, + BT_EwGw, + SHLD_EwGwIb, + SHLD_EwGwCL, +// CMPXCHG_EbGb, /* undoc(486) */ + INT6, /* undoc(486) */ + CMPXCHG_EwGw, /* undoc(486) */ + PUSH16_GS, /* A8 */ + POP16_GS, + RSM, + BTS_EwGw, + SHRD_EwGwIb, + SHRD_EwGwCL, + NOFPU_FPU_FXSAVERSTOR, // + LDMXCSR + STMXCSR + SFENCE + LFENCE + CLFLUSH + IMUL_GwEw, + + CMPXCHG_EbGb, /* B0 */ + CMPXCHG_EwGw, + LSS_GwMp, + BTR_EwGw, + LFS_GwMp, + LGS_GwMp, + MOVZX_GwEb, + MOVZX_GwEw, + undef_op, /* B8 */ + UD2, + Grp8_EwIb, + BTC_EwGw, + BSF_GwEw, + BSR_GwEw, + MOVSX_GwEb, + MOVSX_GwEw, + + XADD_EbGb, /* C0 */ + XADD_EwGw, + SSE_CMPPS, + undef_op, + SSE_PINSRW, + SSE_PEXTRW, + SSE_SHUFPS, + Grp9, + BSWAP_EAX, /* C8 */ + BSWAP_ECX, + BSWAP_EDX, + BSWAP_EBX, + BSWAP_ESP, + BSWAP_EBP, + BSWAP_ESI, + BSWAP_EDI, + + undef_op, /* D0 */ + MMX_PSRLW, + MMX_PSRLD, + MMX_PSRLQ, + SSE2_PADDQmm, + MMX_PMULLW, + undef_op, + SSE_PMOVMSKB, + MMX_PSUBUSB, /* D8 */ + MMX_PSUBUSW, + SSE_PMINUB, + MMX_PAND, + MMX_PADDUSB, + MMX_PADDUSW, + SSE_PMAXUB, + MMX_PANDN, + + SSE_PAVGB, /* E0 */ + MMX_PSRAW, + MMX_PSRAD, + SSE_PAVGW, + SSE_PMULHUW, + MMX_PMULHW, + undef_op, + SSE_MOVNTQ, + MMX_PSUBSB, /* E8 */ + MMX_PSUBSW, + SSE_PMINSW, + MMX_POR, + MMX_PADDSB, + MMX_PADDSW, + SSE_PMAXSW, + MMX_PXOR, + + AMD3DNOW_F0, /* F0 */ + MMX_PSLLW, + MMX_PSLLD, + MMX_PSLLQ, + SSE2_PMULUDQmm, + MMX_PMADDWD, + SSE_PSADBW, + SSE_MASKMOVQ, + MMX_PSUBB, /* F8 */ + MMX_PSUBW, + MMX_PSUBD, + SSE2_PSUBQmm, + MMX_PADDB, + MMX_PADDW, + MMX_PADDD, + undef_op, + }, + + /* 32bit */ + { + Grp6, /* 00 */ + Grp7, + LAR_GdEw, + LSL_GdEw, + undef_op, + LOADALL286, /* undoc(286) */ + CLTS, + LOADALL, + INVD, /* 08 */ + WBINVD, + undef_op, + UD2, + undef_op, + AMD3DNOW_PREFETCH, + AMD3DNOW_FEMMS, + undef_op, + + SSE_MOVUPSmem2xmm, /* 10 */ + SSE_MOVUPSxmm2mem, + SSE_MOVLPSmem2xmm, // + MOVHLPS + SSE_MOVLPSxmm2mem, + SSE_UNPCKLPS, + SSE_UNPCKHPS, + SSE_MOVHPSmem2xmm, // + MOVLHPS + SSE_MOVHPSxmm2mem, + SSE_PREFETCHTx, /* 18 */ + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + SSE_NOPPREFETCH, + + MOV_RdCd, /* 20 */ + MOV_RdDd, + MOV_CdRd, + MOV_DdRd, + MOV_RdTd, + undef_op, + MOV_TdRd, + undef_op, + SSE_MOVAPSmem2xmm, /* 28 */ + SSE_MOVAPSxmm2mem, + SSE_CVTPI2PS, + SSE_MOVNTPS, + SSE_CVTTPS2PI, + SSE_CVTPS2PI, + SSE_UCOMISS, + SSE_COMISS, + + WRMSR, /* 30 */ + RDTSC, + RDMSR, + RDPMC, + SYSENTER, + SYSEXIT, + undef_op, + undef_op, + undef_op, /* 38 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + + CMOVO_GdEd, /* 40 */ + CMOVNO_GdEd, + CMOVC_GdEd, + CMOVNC_GdEd, + CMOVZ_GdEd, + CMOVNZ_GdEd, + CMOVNA_GdEd, + CMOVA_GdEd, + CMOVS_GdEd, /* 48 */ + CMOVNS_GdEd, + CMOVP_GdEd, + CMOVNP_GdEd, + CMOVL_GdEd, + CMOVNL_GdEd, + CMOVLE_GdEd, + CMOVNLE_GdEd, + + SSE_MOVMSKPS, /* 50 */ + SSE_SQRTPS, + SSE_RSQRTPS, + SSE_RCPPS, + SSE_ANDPS, + SSE_ANDNPS, + SSE_ORPS, + SSE_XORPS, + SSE_ADDPS, /* 58 */ + SSE_MULPS, + SSE2_CVTPS2PD, + SSE2_CVTDQ2PS, + SSE_SUBPS, + SSE_MINPS, + SSE_DIVPS, + SSE_MAXPS, + + MMX_PUNPCKLBW, /* 60 */ + MMX_PUNPCKLWD, + MMX_PUNPCKLDQ, + MMX_PACKSSWB, + MMX_PCMPGTB, + MMX_PCMPGTW, + MMX_PCMPGTD, + MMX_PACKUSWB, + MMX_PUNPCKHBW, /* 68 */ + MMX_PUNPCKHWD, + MMX_PUNPCKHDQ, + MMX_PACKSSDW, + undef_op, + undef_op, + MMX_MOVD_mm_rm32, + MMX_MOVQ_mm_mmm64, + + SSE_PSHUFW, /* 70 */ + MMX_PSxxW_imm8, + MMX_PSxxD_imm8, + MMX_PSxxQ_imm8, + MMX_PCMPEQB, + MMX_PCMPEQW, + MMX_PCMPEQD, + MMX_EMMS, + undef_op, /* 78 */ + undef_op, + undef_op, + undef_op, + undef_op, + undef_op, + MMX_MOVD_rm32_mm, + MMX_MOVQ_mmm64_mm, + + JO_Jd, /* 80 */ + JNO_Jd, + JC_Jd, + JNC_Jd, + JZ_Jd, + JNZ_Jd, + JNA_Jd, + JA_Jd, + JS_Jd, /* 88 */ + JNS_Jd, + JP_Jd, + JNP_Jd, + JL_Jd, + JNL_Jd, + JLE_Jd, + JNLE_Jd, + + SETO_Eb, /* 90 */ + SETNO_Eb, + SETC_Eb, + SETNC_Eb, + SETZ_Eb, + SETNZ_Eb, + SETNA_Eb, + SETA_Eb, + SETS_Eb, /* 98 */ + SETNS_Eb, + SETP_Eb, + SETNP_Eb, + SETL_Eb, + SETNL_Eb, + SETLE_Eb, + SETNLE_Eb, + + PUSH32_FS, /* A0 */ + POP32_FS, + _CPUID, + BT_EdGd, + SHLD_EdGdIb, + SHLD_EdGdCL, +// CMPXCHG_EbGb, /* undoc(486) */ + INT6, /* undoc(486) */ + CMPXCHG_EdGd, /* undoc(486) */ + PUSH32_GS, /* A8 */ + POP32_GS, + RSM, + BTS_EdGd, + SHRD_EdGdIb, + SHRD_EdGdCL, + NOFPU_FPU_FXSAVERSTOR, // + LDMXCSR + STMXCSR + SFENCE + LFENCE + CLFLUSH + IMUL_GdEd, + + CMPXCHG_EbGb, /* B0 */ + CMPXCHG_EdGd, + LSS_GdMp, + BTR_EdGd, + LFS_GdMp, + LGS_GdMp, + MOVZX_GdEb, + MOVZX_GdEw, + undef_op, /* B8 */ + UD2, + Grp8_EdIb, + BTC_EdGd, + BSF_GdEd, + BSR_GdEd, + MOVSX_GdEb, + MOVSX_GdEw, + + XADD_EbGb, /* C0 */ + XADD_EdGd, + SSE_CMPPS, + undef_op, + SSE_PINSRW, + SSE_PEXTRW, + SSE_SHUFPS, + Grp9, + BSWAP_EAX, /* C8 */ + BSWAP_ECX, + BSWAP_EDX, + BSWAP_EBX, + BSWAP_ESP, + BSWAP_EBP, + BSWAP_ESI, + BSWAP_EDI, + + undef_op, /* D0 */ + MMX_PSRLW, + MMX_PSRLD, + MMX_PSRLQ, + SSE2_PADDQmm, + MMX_PMULLW, + undef_op, + SSE_PMOVMSKB, + MMX_PSUBUSB, /* D8 */ + MMX_PSUBUSW, + SSE_PMINUB, + MMX_PAND, + MMX_PADDUSB, + MMX_PADDUSW, + SSE_PMAXUB, + MMX_PANDN, + + SSE_PAVGB, /* E0 */ + MMX_PSRAW, + MMX_PSRAD, + SSE_PAVGW, + SSE_PMULHUW, + MMX_PMULHW, + undef_op, + SSE_MOVNTQ, + MMX_PSUBSB, /* E8 */ + MMX_PSUBSW, + SSE_PMINSW, + MMX_POR, + MMX_PADDSB, + MMX_PADDSW, + SSE_PMAXSW, + MMX_PXOR, + + AMD3DNOW_F0, /* F0 */ + MMX_PSLLW, + MMX_PSLLD, + MMX_PSLLQ, + SSE2_PMULUDQmm, + MMX_PMADDWD, + SSE_PSADBW, + SSE_MASKMOVQ, + MMX_PSUBB, /* F8 */ + MMX_PSUBW, + MMX_PSUBD, + SSE2_PSUBQmm, + MMX_PADDB, + MMX_PADDW, + MMX_PADDD, + undef_op, + }, +}; + +void (*insttable_2byte660F_32[256])(void) = { + NULL, /* 00 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 08 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE2_MOVUPDmem2xmm, /* 10 */ + SSE2_MOVUPDxmm2mem, + SSE2_MOVLPDmem2xmm, + SSE2_MOVLPDxmm2mem, + SSE2_UNPCKLPD, + SSE2_UNPCKHPD, + SSE2_MOVHPDmem2xmm, + SSE2_MOVHPDxmm2mem, + NULL, /* 18 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 20 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_MOVAPDmem2xmm, /* 28 */ + SSE2_MOVAPDxmm2mem, + SSE2_CVTPI2PD, + SSE2_MOVNTPD, + SSE2_CVTTPD2PI, + SSE2_CVTPD2PI, + SSE2_UCOMISD, + SSE2_COMISD, + + NULL, /* 30 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 38 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 40 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 48 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE2_MOVMSKPD, /* 50 */ + SSE2_SQRTPD, + NULL, + NULL, + SSE2_ANDPD, + SSE2_ANDNPD, + SSE2_ORPD, + SSE2_XORPD, + SSE2_ADDPD, /* 58 */ + SSE2_MULPD, + SSE2_CVTPD2PS, + SSE2_CVTPS2DQ, + SSE2_SUBPD, + SSE2_MINPD, + SSE2_DIVPD, + SSE2_MAXPD, + + SSE2_PUNPCKLBW, /* 60 */ + SSE2_PUNPCKLWD, + SSE2_PUNPCKLDQ, + SSE2_PACKSSWB, + SSE2_PCMPGTB, + SSE2_PCMPGTW, + SSE2_PCMPGTD, + SSE2_PACKUSWB, + SSE2_PUNPCKHBW, /* 68 */ + SSE2_PUNPCKHWD, + SSE2_PUNPCKHDQ, + SSE2_PACKSSDW, + SSE2_PUNPCKLQDQ, + SSE2_PUNPCKHQDQ, + SSE2_MOVDrm2xmm, + SSE2_MOVDQAmem2xmm, + + SSE2_PSHUFD, /* 70 */ + SSE2_PSxxWimm, // PSLLWimm + PSRAWimm + PSRLWimm + SSE2_PSxxDimm, // PSLLDimm + PSRADimm + PSRLDimm + SSE2_PSxxQimm, // PSLLQimm + PSRAQimm + PSRLQimm + PSLLDQ + PSRLDQ + SSE2_PCMPEQB, + SSE2_PCMPEQW, + SSE2_PCMPEQD, + NULL, + NULL, /* 78 */ + NULL, + NULL, + NULL, + SSE3_HADDPD, + SSE3_HSUBPD, + SSE2_MOVDxmm2rm, + SSE2_MOVDQAxmm2mem, + + NULL, /* 80 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 88 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 90 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 98 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* A0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* A8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* B0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* B8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* C0 */ + NULL, + SSE2_CMPPD, + SSE2_MOVNTI, + SSE2_PINSRW, + SSE2_PEXTRW, + SSE2_SHUFPD, + NULL, + NULL, /* C8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE3_ADDSUBPD, /* D0 */ + SSE2_PSRLW, + SSE2_PSRLD, + SSE2_PSRLQ, + SSE2_PADDQxmm, + SSE2_PMULLW, + SSE2_MOVQxmm2mem, + SSE2_PMOVMSKB, + SSE2_PSUBUSB, /* D8 */ + SSE2_PSUBUSW, + SSE2_PMINUB, + SSE2_PAND, + SSE2_PADDUSB, + SSE2_PADDUSW, + SSE2_PMAXUB, + SSE2_PANDN, + + SSE2_PAVGB, /* E0 */ + SSE2_PSRAW, + SSE2_PSRAD, + SSE2_PAVGW, + SSE2_PMULHUW, + SSE2_PMULHW, + SSE2_CVTTPD2DQ, + SSE2_MOVNTDQ, + SSE2_PSUBSB, /* E8 */ + SSE2_PSUBSW, + SSE2_PMINSW, + SSE2_POR, + SSE2_PADDSB, + SSE2_PADDSW, + SSE2_PMAXSW, + SSE2_PXOR, + + NULL, /* F0 */ + SSE2_PSLLW, + SSE2_PSLLD, + SSE2_PSLLQ, + SSE2_PMULUDQxmm, + SSE2_PMADD, + SSE2_PSADBW, + SSE2_MASKMOVDQU, + SSE2_PSUBB, /* F8 */ + SSE2_PSUBW, + SSE2_PSUBD, + SSE2_PSUBQxmm, + SSE2_PADDB, + SSE2_PADDW, + SSE2_PADDD, + NULL, +}; + +void (*insttable_2byteF20F_32[256])(void) = { + NULL, /* 00 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 08 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE2_MOVSDmem2xmm, /* 10 */ + SSE2_MOVSDxmm2mem, + SSE3_MOVDDUP, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 18 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 20 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 28 */ + NULL, + SSE2_CVTSI2SD, + NULL, + SSE2_CVTTSD2SI, + SSE2_CVTSD2SI, + NULL, + NULL, + + NULL, /* 30 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 38 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 40 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 48 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 50 */ + SSE2_SQRTSD, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_ADDSD, /* 58 */ + SSE2_MULSD, + SSE2_CVTSD2SS, + NULL, + SSE2_SUBSD, + SSE2_MINSD, + SSE2_DIVSD, + SSE2_MAXSD, + + NULL, /* 60 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 68 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE2_PSHUFLW, /* 70 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 78 */ + NULL, + NULL, + NULL, + SSE3_HADDPS, + SSE3_HSUBPS, + NULL, + NULL, + + NULL, /* 80 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 88 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 90 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 98 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* A0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* A8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* B0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* B8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* C0 */ + NULL, + SSE2_CMPSD, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* C8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE3_ADDSUBPS, /* D0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_MOVDQ2Q, + NULL, + NULL, /* D8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* E0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_CVTPD2DQ, + NULL, + NULL, /* E8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE3_LDDQU, /* F0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* F8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +void (*insttable_2byteF30F_32[256])(void) = { + NULL, /* 00 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 08 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + SSE_MOVSSmem2xmm, /* 10 */ + SSE_MOVSSxmm2mem, + SSE3_MOVSLDUP, + NULL, + NULL, + NULL, + SSE3_MOVSHDUP, + NULL, + NULL, /* 18 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 20 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 28 */ + NULL, + SSE_CVTSI2SS, + NULL, + SSE_CVTTSS2SI, + SSE_CVTSS2SI, + NULL, + NULL, + + NULL, /* 30 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 38 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 40 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 48 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 50 */ + SSE_SQRTSS, + SSE_RSQRTSS, + SSE_RCPSS, + NULL, + NULL, + NULL, + NULL, + SSE_ADDSS, /* 58 */ + SSE_MULSS, + SSE2_CVTSS2SD, + SSE2_CVTTPS2DQ, + SSE_SUBSS, + SSE_MINSS, + SSE_DIVSS, + SSE_MAXSS, + + NULL, /* 60 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 68 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_MOVDQUmem2xmm, + + SSE2_PSHUFHW, /* 70 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 78 */ + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_MOVQmem2xmm, + SSE2_MOVDQUxmm2mem, + + NULL, /* 80 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 88 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* 90 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* 98 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* A0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* A8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* B0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* B8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* C0 */ + NULL, + SSE_CMPSS, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* C8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* D0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_MOVQ2DQ, + NULL, + NULL, /* D8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* E0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + SSE2_CVTDQ2PD, + NULL, + NULL, /* E8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + + NULL, /* F0 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, /* F8 */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + + + +/* + * for group + */ + +/* group 1 */ +void (CPUCALL *insttable_G1EbIb[])(UINT8 *, UINT32) = { + ADD_EbIb, + OR_EbIb, + ADC_EbIb, + SBB_EbIb, + AND_EbIb, + SUB_EbIb, + XOR_EbIb, + CMP_EbIb, +}; +void (CPUCALL *insttable_G1EbIb_ext[])(UINT32, UINT32) = { + ADD_EbIb_ext, + OR_EbIb_ext, + ADC_EbIb_ext, + SBB_EbIb_ext, + AND_EbIb_ext, + SUB_EbIb_ext, + XOR_EbIb_ext, + CMP_EbIb_ext, +}; + +void (CPUCALL *insttable_G1EwIx[])(UINT16 *, UINT32) = { + ADD_EwIx, + OR_EwIx, + ADC_EwIx, + SBB_EwIx, + AND_EwIx, + SUB_EwIx, + XOR_EwIx, + CMP_EwIx, +}; +void (CPUCALL *insttable_G1EwIx_ext[])(UINT32, UINT32) = { + ADD_EwIx_ext, + OR_EwIx_ext, + ADC_EwIx_ext, + SBB_EwIx_ext, + AND_EwIx_ext, + SUB_EwIx_ext, + XOR_EwIx_ext, + CMP_EwIx_ext, +}; + +void (CPUCALL *insttable_G1EdIx[])(UINT32 *, UINT32) = { + ADD_EdIx, + OR_EdIx, + ADC_EdIx, + SBB_EdIx, + AND_EdIx, + SUB_EdIx, + XOR_EdIx, + CMP_EdIx, +}; +void (CPUCALL *insttable_G1EdIx_ext[])(UINT32, UINT32) = { + ADD_EdIx_ext, + OR_EdIx_ext, + ADC_EdIx_ext, + SBB_EdIx_ext, + AND_EdIx_ext, + SUB_EdIx_ext, + XOR_EdIx_ext, + CMP_EdIx_ext, +}; + + +/* group 2 */ +void (CPUCALL *insttable_G2Eb[])(UINT8 *) = { + ROL_Eb, + ROR_Eb, + RCL_Eb, + RCR_Eb, + SHL_Eb, + SHR_Eb, + SHL_Eb, + SAR_Eb, +}; +void (CPUCALL *insttable_G2Eb_ext[])(UINT32) = { + ROL_Eb_ext, + ROR_Eb_ext, + RCL_Eb_ext, + RCR_Eb_ext, + SHL_Eb_ext, + SHR_Eb_ext, + SHL_Eb_ext, + SAR_Eb_ext, +}; + +void (CPUCALL *insttable_G2Ew[])(UINT16 *) = { + ROL_Ew, + ROR_Ew, + RCL_Ew, + RCR_Ew, + SHL_Ew, + SHR_Ew, + SHL_Ew, + SAR_Ew, +}; +void (CPUCALL *insttable_G2Ew_ext[])(UINT32) = { + ROL_Ew_ext, + ROR_Ew_ext, + RCL_Ew_ext, + RCR_Ew_ext, + SHL_Ew_ext, + SHR_Ew_ext, + SHL_Ew_ext, + SAR_Ew_ext, +}; + +void (CPUCALL *insttable_G2Ed[])(UINT32 *) = { + ROL_Ed, + ROR_Ed, + RCL_Ed, + RCR_Ed, + SHL_Ed, + SHR_Ed, + SHL_Ed, + SAR_Ed, +}; +void (CPUCALL *insttable_G2Ed_ext[])(UINT32) = { + ROL_Ed_ext, + ROR_Ed_ext, + RCL_Ed_ext, + RCR_Ed_ext, + SHL_Ed_ext, + SHR_Ed_ext, + SHL_Ed_ext, + SAR_Ed_ext, +}; + +void (CPUCALL *insttable_G2EbCL[])(UINT8 *, UINT) = { + ROL_EbCL, + ROR_EbCL, + RCL_EbCL, + RCR_EbCL, + SHL_EbCL, + SHR_EbCL, + SHL_EbCL, + SAR_EbCL, +}; +void (CPUCALL *insttable_G2EbCL_ext[])(UINT32, UINT) = { + ROL_EbCL_ext, + ROR_EbCL_ext, + RCL_EbCL_ext, + RCR_EbCL_ext, + SHL_EbCL_ext, + SHR_EbCL_ext, + SHL_EbCL_ext, + SAR_EbCL_ext, +}; + +void (CPUCALL *insttable_G2EwCL[])(UINT16 *, UINT) = { + ROL_EwCL, + ROR_EwCL, + RCL_EwCL, + RCR_EwCL, + SHL_EwCL, + SHR_EwCL, + SHL_EwCL, + SAR_EwCL, +}; +void (CPUCALL *insttable_G2EwCL_ext[])(UINT32, UINT) = { + ROL_EwCL_ext, + ROR_EwCL_ext, + RCL_EwCL_ext, + RCR_EwCL_ext, + SHL_EwCL_ext, + SHR_EwCL_ext, + SHL_EwCL_ext, + SAR_EwCL_ext, +}; + +void (CPUCALL *insttable_G2EdCL[])(UINT32 *, UINT) = { + ROL_EdCL, + ROR_EdCL, + RCL_EdCL, + RCR_EdCL, + SHL_EdCL, + SHR_EdCL, + SHL_EdCL, + SAR_EdCL, +}; +void (CPUCALL *insttable_G2EdCL_ext[])(UINT32, UINT) = { + ROL_EdCL_ext, + ROR_EdCL_ext, + RCL_EdCL_ext, + RCR_EdCL_ext, + SHL_EdCL_ext, + SHR_EdCL_ext, + SHL_EdCL_ext, + SAR_EdCL_ext, +}; + +/* group 3 */ +void (CPUCALL *insttable_G3Eb[])(UINT32) = { + TEST_EbIb, + TEST_EbIb, + NOT_Eb, + NEG_Eb, + MUL_ALEb, + IMUL_ALEb, + DIV_ALEb, + IDIV_ALEb, +}; + +void (CPUCALL *insttable_G3Ew[])(UINT32) = { + TEST_EwIw, + TEST_EwIw, + NOT_Ew, + NEG_Ew, + MUL_AXEw, + IMUL_AXEw, + DIV_AXEw, + IDIV_AXEw, +}; + +void (CPUCALL *insttable_G3Ed[])(UINT32) = { + TEST_EdId, + TEST_EdId, + NOT_Ed, + NEG_Ed, + MUL_EAXEd, + IMUL_EAXEd, + DIV_EAXEd, + IDIV_EAXEd, +}; + +/* group 4 */ +void (CPUCALL *insttable_G4[])(UINT32) = { + INC_Eb, + DEC_Eb, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, +}; + +/* group 5 */ +void (CPUCALL *insttable_G5Ew[])(UINT32) = { + INC_Ew, + DEC_Ew, + CALL_Ew, + CALL16_Ep, + JMP_Ew, + JMP16_Ep, + PUSH_Ew, + undef_op2, /* POP_Ew_G5 */ +}; + +void (CPUCALL *insttable_G5Ed[])(UINT32) = { + INC_Ed, + DEC_Ed, + CALL_Ed, + CALL32_Ep, + JMP_Ed, + JMP32_Ep, + PUSH_Ed, + undef_op2, /* POP_Ed_G5 */ +}; + +/* group 6 */ +void (CPUCALL *insttable_G6[])(UINT32) = { + SLDT_Ew, + STR_Ew, + LLDT_Ew, + LTR_Ew, + VERR_Ew, + VERW_Ew, + undef_op2, + undef_op2, +}; + +/* group 7 */ +void (CPUCALL *insttable_G7[])(UINT32) = { + SGDT_Ms, + SIDT_Ms, + LGDT_Ms, + LIDT_Ms, + SMSW_Ew, + undef_op2, + LMSW_Ew, + INVLPG, +}; + +/* group 8 */ +void (CPUCALL *insttable_G8EwIb[])(UINT32) = { + undef_op2, + undef_op2, + undef_op2, + undef_op2, + BT_EwIb, + BTS_EwIb, + BTR_EwIb, + BTC_EwIb, +}; + +void (CPUCALL *insttable_G8EdIb[])(UINT32) = { + undef_op2, + undef_op2, + undef_op2, + undef_op2, + BT_EdIb, + BTS_EdIb, + BTR_EdIb, + BTC_EdIb, +}; + +/* group 9 */ +void (CPUCALL *insttable_G9[])(UINT32) = { + undef_op2, + CMPXCHG8B, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, + undef_op2, +}; diff --git a/source/src/vm/np21/i386c/ia32/inst_table.h b/source/src/vm/np21/i386c/ia32/inst_table.h new file mode 100644 index 000000000..4517128a0 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/inst_table.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INST_TABLE_H__ +#define IA32_CPU_INST_TABLE_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* info of instruction */ +extern UINT8 insttable_info[256]; + +/* table of instruction */ +extern void (*insttable_1byte[2][256])(void); +extern void (*insttable_1byte_repfunc[2][256])(int reptype); +extern void (*insttable_2byte[2][256])(void); + +extern void (*insttable_2byte660F_32[256])(void); +extern void (*insttable_2byteF20F_32[256])(void); +extern void (*insttable_2byteF30F_32[256])(void); + +/* + * for group + */ + +/* group 1 */ +extern void (CPUCALL *insttable_G1EbIb[])(UINT8 *, UINT32); +extern void (CPUCALL *insttable_G1EwIx[])(UINT16 *, UINT32); +extern void (CPUCALL *insttable_G1EdIx[])(UINT32 *, UINT32); +extern void (CPUCALL *insttable_G1EbIb_ext[])(UINT32, UINT32); +extern void (CPUCALL *insttable_G1EwIx_ext[])(UINT32, UINT32); +extern void (CPUCALL *insttable_G1EdIx_ext[])(UINT32, UINT32); + +/* group 2 */ +extern void (CPUCALL *insttable_G2Eb[])(UINT8 *); +extern void (CPUCALL *insttable_G2Ew[])(UINT16 *); +extern void (CPUCALL *insttable_G2Ed[])(UINT32 *); +extern void (CPUCALL *insttable_G2EbCL[])(UINT8 *, UINT); +extern void (CPUCALL *insttable_G2EwCL[])(UINT16 *, UINT); +extern void (CPUCALL *insttable_G2EdCL[])(UINT32 *, UINT); +extern void (CPUCALL *insttable_G2Eb_ext[])(UINT32); +extern void (CPUCALL *insttable_G2Ew_ext[])(UINT32); +extern void (CPUCALL *insttable_G2Ed_ext[])(UINT32); +extern void (CPUCALL *insttable_G2EbCL_ext[])(UINT32, UINT); +extern void (CPUCALL *insttable_G2EwCL_ext[])(UINT32, UINT); +extern void (CPUCALL *insttable_G2EdCL_ext[])(UINT32, UINT); + +/* group 3 */ +extern void (CPUCALL *insttable_G3Eb[])(UINT32); +extern void (CPUCALL *insttable_G3Ew[])(UINT32); +extern void (CPUCALL *insttable_G3Ed[])(UINT32); + +/* group 4 */ +extern void (CPUCALL *insttable_G4[])(UINT32); + +/* group 5 */ +extern void (CPUCALL *insttable_G5Ew[])(UINT32); +extern void (CPUCALL *insttable_G5Ed[])(UINT32); + +/* group 6 */ +extern void (CPUCALL *insttable_G6[])(UINT32); + +/* group 7 */ +extern void (CPUCALL *insttable_G7[])(UINT32); + +/* group 8 */ +extern void (CPUCALL *insttable_G8EwIb[])(UINT32); +extern void (CPUCALL *insttable_G8EdIb[])(UINT32); + +/* group 9 */ +extern void (CPUCALL *insttable_G9[])(UINT32); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INST_TABLE_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/arith.mcr b/source/src/vm/np21/i386c/ia32/instructions/arith.mcr new file mode 100644 index 000000000..0ddc4fc43 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/arith.mcr @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_ARITH_MCR__ +#define IA32_CPU_ARITH_MCR__ + +/* args == 1 */ +#define ARITH_INSTRUCTION_1(inst) \ +static UINT32 CPUCALL \ +inst##1(UINT32 dst, void *arg) \ +{ \ + BYTE_##inst(dst); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##2(UINT32 dst, void *arg) \ +{ \ + WORD_##inst(dst); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##4(UINT32 dst, void *arg) \ +{ \ + DWORD_##inst(dst); \ + return dst; \ +} \ +\ +void CPUCALL \ +inst##_Eb(UINT32 op) \ +{ \ + UINT8 *out; \ + UINT32 dst, madr; \ +\ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg8_b20[op]; \ + dst = *out; \ + BYTE_##inst(dst); \ + *out = (UINT8)dst; \ + } else { \ + CPU_WORKCLOCK(5); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##1, 0); \ + } \ +} \ +\ +void CPUCALL \ +inst##_Ew(UINT32 op) \ +{ \ + UINT16 *out; \ + UINT32 dst, madr; \ +\ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg16_b20[op]; \ + dst = *out; \ + WORD_##inst(dst); \ + *out = (UINT16)dst; \ + } else { \ + CPU_WORKCLOCK(5); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, 0); \ + } \ +} \ +\ +void CPUCALL \ +inst##_Ed(UINT32 op) \ +{ \ + UINT32 *out; \ + UINT32 dst, madr; \ +\ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg32_b20[op]; \ + dst = *out; \ + DWORD_##inst(dst); \ + *out = dst; \ + } else { \ + CPU_WORKCLOCK(5); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, 0); \ + } \ +} + +/* args == 2 */ +#define ARITH_INSTRUCTION_2(inst) \ +static UINT32 CPUCALL \ +inst##1(UINT32 dst, void *arg) \ +{ \ + UINT32 src = PTR_TO_UINT32(arg); \ + BYTE_##inst(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##2(UINT32 dst, void *arg) \ +{ \ + UINT32 src = PTR_TO_UINT32(arg); \ + WORD_##inst(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##4(UINT32 dst, void *arg) \ +{ \ + UINT32 src = PTR_TO_UINT32(arg); \ + DWORD_##inst(dst, src); \ + return dst; \ +} \ +\ +void \ +inst##_EbGb(void) \ +{ \ + UINT8 *out; \ + UINT32 op, src, dst, madr; \ +\ + PREPART_EA_REG8(op, src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg8_b20[op]; \ + dst = *out; \ + BYTE_##inst(dst, src); \ + *out = (UINT8)dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##1, UINT32_TO_PTR(src)); \ + } \ +} \ +\ +void \ +inst##_EwGw(void) \ +{ \ + UINT16 *out; \ + UINT32 op, src, dst, madr; \ +\ + PREPART_EA_REG16(op, src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg16_b20[op]; \ + dst = *out; \ + WORD_##inst(dst, src); \ + *out = (UINT16)dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, UINT32_TO_PTR(src)); \ + } \ +} \ +\ +void \ +inst##_EdGd(void) \ +{ \ + UINT32 *out; \ + UINT32 op, src, dst, madr; \ +\ + PREPART_EA_REG32(op, src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg32_b20[op]; \ + dst = *out; \ + DWORD_##inst(dst, src); \ + *out = dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, UINT32_TO_PTR(src)); \ + } \ +} \ +\ +void \ +inst##_GbEb(void) \ +{ \ + UINT8 *out; \ + UINT32 op, src, dst; \ +\ + PREPART_REG8_EA(op, src, out, 2, 7); \ + dst = *out; \ + BYTE_##inst(dst, src); \ + *out = (UINT8)dst; \ +} \ +\ +void \ +inst##_GwEw(void) \ +{ \ + UINT16 *out; \ + UINT32 op, src, dst; \ +\ + PREPART_REG16_EA(op, src, out, 2, 7); \ + dst = *out; \ + WORD_##inst(dst, src); \ + *out = (UINT16)dst; \ +} \ +\ +void \ +inst##_GdEd(void) \ +{ \ + UINT32 *out; \ + UINT32 op, src, dst; \ +\ + PREPART_REG32_EA(op, src, out, 2, 7); \ + dst = *out; \ + DWORD_##inst(dst, src); \ + *out = dst; \ +} \ +\ +void \ +inst##_ALIb(void) \ +{ \ + UINT32 src, dst; \ +\ + CPU_WORKCLOCK(3); \ + GET_PCBYTE(src); \ + dst = CPU_AL; \ + BYTE_##inst(dst, src); \ + CPU_AL = (UINT8)dst; \ +} \ +\ +void \ +inst##_AXIw(void) \ +{ \ + UINT32 src, dst; \ +\ + CPU_WORKCLOCK(3); \ + GET_PCWORD(src); \ + dst = CPU_AX; \ + WORD_##inst(dst, src); \ + CPU_AX = (UINT16)dst; \ +} \ +\ +void \ +inst##_EAXId(void) \ +{ \ + UINT32 src, dst; \ +\ + CPU_WORKCLOCK(3); \ + GET_PCDWORD(src); \ + dst = CPU_EAX; \ + DWORD_##inst(dst, src); \ + CPU_EAX = dst; \ +} \ +\ +void CPUCALL \ +inst##_EbIb(UINT8 *regp, UINT32 src) \ +{ \ + UINT32 dst; \ +\ + dst = *regp; \ + BYTE_##inst(dst, src); \ + *regp = (UINT8)dst; \ +} \ +\ +void CPUCALL \ +inst##_EbIb_ext(UINT32 madr, UINT32 src) \ +{ \ +\ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##1, UINT32_TO_PTR(src)); \ +} \ +\ +void CPUCALL \ +inst##_EwIx(UINT16 *regp, UINT32 src) \ +{ \ + UINT32 dst; \ +\ + dst = *regp; \ + WORD_##inst(dst, src); \ + *regp = (UINT16)dst; \ +} \ +\ +void CPUCALL \ +inst##_EwIx_ext(UINT32 madr, UINT32 src) \ +{ \ +\ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, UINT32_TO_PTR(src)); \ +} \ +\ +void CPUCALL \ +inst##_EdIx(UINT32 *regp, UINT32 src) \ +{ \ + UINT32 dst; \ +\ + dst = *regp; \ + DWORD_##inst(dst, src); \ + *regp = dst; \ +} \ +\ +void CPUCALL \ +inst##_EdIx_ext(UINT32 madr, UINT32 src) \ +{ \ +\ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, UINT32_TO_PTR(src)); \ +} + +/* args == 3 */ +#define ARITH_INSTRUCTION_3(inst) \ +static UINT32 CPUCALL \ +inst##1(UINT32 dst, void *arg) \ +{ \ + UINT32 src = PTR_TO_UINT32(arg); \ + UINT32 res; \ + BYTE_##inst(res, dst, src); \ + return res; \ +} \ +static UINT32 CPUCALL \ +inst##2(UINT32 dst, void *arg) \ +{ \ + UINT32 src = PTR_TO_UINT32(arg); \ + UINT32 res; \ + WORD_##inst(res, dst, src); \ + return res; \ +} \ +static UINT32 CPUCALL \ +inst##4(UINT32 dst, void *arg) \ +{ \ + UINT32 src = PTR_TO_UINT32(arg); \ + UINT32 res; \ + DWORD_##inst(res, dst, src); \ + return res; \ +} \ +\ +void \ +inst##_EbGb(void) \ +{ \ + UINT8 *out; \ + UINT32 op, src, dst, res, madr; \ +\ + PREPART_EA_REG8(op, src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg8_b20[op]; \ + dst = *out; \ + BYTE_##inst(res, dst, src); \ + *out = (UINT8)res; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##1, UINT32_TO_PTR(src)); \ + } \ +} \ +\ +void \ +inst##_EwGw(void) \ +{ \ + UINT16 *out; \ + UINT32 op, src, dst, res, madr; \ +\ + PREPART_EA_REG16(op, src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg16_b20[op]; \ + dst = *out; \ + WORD_##inst(res, dst, src); \ + *out = (UINT16)res; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, UINT32_TO_PTR(src)); \ + } \ +} \ +\ +void \ +inst##_EdGd(void) \ +{ \ + UINT32 *out; \ + UINT32 op, src, dst, res, madr; \ +\ + PREPART_EA_REG32(op, src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(2); \ + out = reg32_b20[op]; \ + dst = *out; \ + DWORD_##inst(res, dst, src); \ + *out = res; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, UINT32_TO_PTR(src)); \ + } \ +} \ +\ +void \ +inst##_GbEb(void) \ +{ \ + UINT8 *out; \ + UINT32 op, src, dst, res; \ +\ + PREPART_REG8_EA(op, src, out, 2, 7); \ + dst = *out; \ + BYTE_##inst(res, dst, src); \ + *out = (UINT8)res; \ +} \ +\ +void \ +inst##_GwEw(void) \ +{ \ + UINT16 *out; \ + UINT32 op, src, dst, res; \ +\ + PREPART_REG16_EA(op, src, out, 2, 7); \ + dst = *out; \ + WORD_##inst(res, dst, src); \ + *out = (UINT16)res; \ +} \ +\ +void \ +inst##_GdEd(void) \ +{ \ + UINT32 *out; \ + UINT32 op, src, dst, res; \ +\ + PREPART_REG32_EA(op, src, out, 2, 7); \ + dst = *out; \ + DWORD_##inst(res, dst, src); \ + *out = res; \ +} \ +\ +void \ +inst##_ALIb(void) \ +{ \ + UINT32 src, dst, res; \ +\ + CPU_WORKCLOCK(2); \ + GET_PCBYTE(src); \ + dst = CPU_AL; \ + BYTE_##inst(res, dst, src); \ + CPU_AL = (UINT8)res; \ +} \ +\ +void \ +inst##_AXIw(void) \ +{ \ + UINT32 src, dst, res; \ +\ + CPU_WORKCLOCK(2); \ + GET_PCWORD(src); \ + dst = CPU_AX; \ + WORD_##inst(res, dst, src); \ + CPU_AX = (UINT16)res; \ +} \ +\ +void \ +inst##_EAXId(void) \ +{ \ + UINT32 src, dst, res; \ +\ + CPU_WORKCLOCK(2); \ + GET_PCDWORD(src); \ + dst = CPU_EAX; \ + DWORD_##inst(res, dst, src); \ + CPU_EAX = res; \ +} \ +\ +void CPUCALL \ +inst##_EbIb(UINT8 *regp, UINT32 src) \ +{ \ + UINT32 dst, res; \ +\ + dst = *regp; \ + BYTE_##inst(res, dst, src); \ + *regp = (UINT8)res; \ +} \ +\ +void CPUCALL \ +inst##_EbIb_ext(UINT32 madr, UINT32 src) \ +{ \ +\ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##1, UINT32_TO_PTR(src)); \ +} \ +\ +void CPUCALL \ +inst##_EwIx(UINT16 *regp, UINT32 src) \ +{ \ + UINT32 dst, res; \ +\ + dst = *regp; \ + WORD_##inst(res, dst, src); \ + *regp = (UINT16)res; \ +} \ +\ +void CPUCALL \ +inst##_EwIx_ext(UINT32 madr, UINT32 src) \ +{ \ +\ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, UINT32_TO_PTR(src)); \ +} \ +\ +void CPUCALL \ +inst##_EdIx(UINT32 *regp, UINT32 src) \ +{ \ + UINT32 dst, res; \ +\ + dst = *regp; \ + DWORD_##inst(res, dst, src); \ + *regp = res; \ +} \ +\ +void CPUCALL \ +inst##_EdIx_ext(UINT32 madr, UINT32 src) \ +{ \ +\ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, UINT32_TO_PTR(src)); \ +} + +#endif /* IA32_CPU_ARITH_MCR__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/bin_arith.cpp b/source/src/vm/np21/i386c/ia32/instructions/bin_arith.cpp new file mode 100644 index 000000000..10af380e7 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/bin_arith.cpp @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2002-2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" +#include "arith.mcr" + +#include "bin_arith.h" +#include + + +/* + * arith + */ +ARITH_INSTRUCTION_3(ADD) +ARITH_INSTRUCTION_3(ADC) +ARITH_INSTRUCTION_3(SUB) +ARITH_INSTRUCTION_3(SBB) + + +/* + * IMUL + */ +void CPUCALL +IMUL_ALEb(UINT32 op) +{ + UINT32 madr; + SINT32 res; + SINT8 src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(13); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(16); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AL; + BYTE_IMUL(res, dst, src); + CPU_AX = (UINT16)res; +} + +void CPUCALL +IMUL_AXEw(UINT32 op) +{ + UINT32 madr; + SINT32 res; + SINT16 src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AX; + WORD_IMUL(res, dst, src); + CPU_AX = (UINT16)(res & 0xffff); + CPU_DX = (UINT16)(res >> 16); +} + +void CPUCALL +IMUL_EAXEd(UINT32 op) +{ + UINT32 madr; + SINT64 res; + SINT32 src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_EAX; + DWORD_IMUL(res, dst, src); + CPU_EAX = (UINT32)res; + CPU_EDX = (UINT32)(res >> 32); +} + +void +IMUL_GwEw(void) +{ + UINT16 *out; + UINT32 op; + SINT32 res; + SINT16 src, dst; + + PREPART_REG16_EA(op, src, out, 21, 27); + dst = *out; + WORD_IMUL(res, dst, src); + *out = (UINT16)res; +} + +void +IMUL_GdEd(void) +{ + UINT32 *out; + UINT32 op; + SINT64 res; + SINT32 src, dst; + + PREPART_REG32_EA(op, src, out, 21, 27); + dst = *out; + DWORD_IMUL(res, dst, src); + *out = (UINT32)res; +} + +void +IMUL_GwEwIb(void) +{ + UINT16 *out; + UINT32 op; + SINT32 res; + SINT16 src, dst; + + PREPART_REG16_EA(op, src, out, 21, 24); + GET_PCBYTES(dst); + WORD_IMUL(res, dst, src); + *out = (UINT16)res; +} + +void +IMUL_GdEdIb(void) +{ + UINT32 *out; + UINT32 op; + SINT64 res; + SINT32 src, dst; + + PREPART_REG32_EA(op, src, out, 21, 24); + GET_PCBYTESD(dst); + DWORD_IMUL(res, dst, src); + *out = (UINT32)res; +} + +void +IMUL_GwEwIw(void) +{ + UINT16 *out; + UINT32 op; + SINT32 res; + SINT16 src, dst; + + PREPART_REG16_EA(op, src, out, 21, 24); + GET_PCWORD(dst); + WORD_IMUL(res, dst, src); + *out = (UINT16)res; +} + +void +IMUL_GdEdId(void) +{ + UINT32 *out; + UINT32 op; + SINT64 res; + SINT32 src, dst; + + PREPART_REG32_EA(op, src, out, 21, 24); + GET_PCDWORD(dst); + DWORD_IMUL(res, dst, src); + *out = (UINT32)res; +} + + +/* + * MUL + */ +void CPUCALL +MUL_ALEb(UINT32 op) +{ + UINT32 res, madr; + UINT8 src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(13); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(16); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AL; + BYTE_MUL(res, dst, src); + CPU_AX = (UINT16)res; +} + +void CPUCALL +MUL_AXEw(UINT32 op) +{ + UINT32 res, madr; + UINT16 src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_AX; + WORD_MUL(res, dst, src); + CPU_AX = (UINT16)res; + CPU_DX = (UINT16)(res >> 16); +} + +void CPUCALL +MUL_EAXEd(UINT32 op) +{ + UINT32 res, madr; + UINT32 src, dst; + + if (op >= 0xc0) { + CPU_WORKCLOCK(21); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(24); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + dst = CPU_EAX; + DWORD_MUL(res, dst, src); + CPU_EAX = res; + CPU_EDX = CPU_OV; +} + + +/* + * IDIV + */ +void CPUCALL +IDIV_ALEb(UINT32 op) +{ + UINT32 madr; + SINT16 tmp, r; + SINT8 src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + tmp = (SINT16)CPU_AX; + if (src != 0) { + r = tmp / src; + if (((r + 0x80) & 0xff00) == 0) { + CPU_AL = (SINT8)r; + CPU_AH = tmp % src; + if(i386cpuid.cpu_family == 4){ + CPU_FLAGL ^= A_FLAG; + } + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void CPUCALL +IDIV_AXEw(UINT32 op) +{ + SINT32 tmp, r; + UINT32 madr; + SINT16 src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + tmp = (SINT32)(((UINT32)CPU_DX << 16) + (UINT32)CPU_AX); + if ((src != 0) && (tmp != INT_MIN)) { + r = tmp / src; + if (((r + 0x8000) & 0xffff0000) == 0) { + CPU_AX = (SINT16)r; + CPU_DX = tmp % src; + if(i386cpuid.cpu_family == 4){ + CPU_FLAGL ^= A_FLAG; + } + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void CPUCALL +IDIV_EAXEd(UINT32 op) +{ + SINT64 tmp, r; + SINT32 src; + UINT32 madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + tmp = (SINT64)(((UINT64)CPU_EDX << 32) + (SINT64)CPU_EAX); + if ((src != 0) && (tmp != QWORD_CONST(0x8000000000000000))) { + r = tmp / src; + if (((r + SQWORD_CONST(0x80000000)) & QWORD_CONST(0xffffffff00000000)) == 0) { + CPU_EAX = (SINT32)r; + CPU_EDX = (SINT32)(tmp % src); + if(i386cpuid.cpu_family == 4){ + CPU_FLAGL ^= A_FLAG; + } + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + + +/* + * DIV + */ +void CPUCALL +DIV_ALEb(UINT32 op) +{ + UINT32 madr; + UINT16 tmp; + UINT8 src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + tmp = CPU_AX; + if (src != 0) { + if (tmp < ((UINT16)src << 8)) { + CPU_AL = tmp / src; + CPU_AH = tmp % src; + if(i386cpuid.cpu_family == 4){ + CPU_FLAGL ^= A_FLAG; + } + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void CPUCALL +DIV_AXEw(UINT32 op) +{ + UINT32 madr; + UINT32 tmp; + UINT16 src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + tmp = ((UINT32)CPU_DX << 16) + CPU_AX; + if (src != 0) { + if (tmp < ((UINT32)src << 16)) { + CPU_AX = (UINT16)(tmp / src); + CPU_DX = (UINT16)(tmp % src); + if(i386cpuid.cpu_family == 4){ + CPU_FLAGL ^= A_FLAG; + } + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void CPUCALL +DIV_EAXEd(UINT32 op) +{ + UINT32 madr; + UINT64 tmp; + UINT32 src; + + if (op >= 0xc0) { + CPU_WORKCLOCK(17); + src = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(25); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + tmp = ((UINT64)CPU_EDX << 32) + CPU_EAX; + if (src != 0) { + if (tmp < ((UINT64)src << 32)) { + CPU_EAX = (UINT32)(tmp / src); + CPU_EDX = (UINT32)(tmp % src); + if(i386cpuid.cpu_family == 4){ + CPU_FLAGL ^= A_FLAG; + } + return; + } + } + EXCEPTION(DE_EXCEPTION, 0); +} + + +/* + * INC + */ +ARITH_INSTRUCTION_1(INC) + +void INC_AX(void) { WORD_INC(CPU_AX); CPU_WORKCLOCK(2); } +void INC_CX(void) { WORD_INC(CPU_CX); CPU_WORKCLOCK(2); } +void INC_DX(void) { WORD_INC(CPU_DX); CPU_WORKCLOCK(2); } +void INC_BX(void) { WORD_INC(CPU_BX); CPU_WORKCLOCK(2); } +void INC_SP(void) { WORD_INC(CPU_SP); CPU_WORKCLOCK(2); } +void INC_BP(void) { WORD_INC(CPU_BP); CPU_WORKCLOCK(2); } +void INC_SI(void) { WORD_INC(CPU_SI); CPU_WORKCLOCK(2); } +void INC_DI(void) { WORD_INC(CPU_DI); CPU_WORKCLOCK(2); } + +void INC_EAX(void) { DWORD_INC(CPU_EAX); CPU_WORKCLOCK(2); } +void INC_ECX(void) { DWORD_INC(CPU_ECX); CPU_WORKCLOCK(2); } +void INC_EDX(void) { DWORD_INC(CPU_EDX); CPU_WORKCLOCK(2); } +void INC_EBX(void) { DWORD_INC(CPU_EBX); CPU_WORKCLOCK(2); } +void INC_ESP(void) { DWORD_INC(CPU_ESP); CPU_WORKCLOCK(2); } +void INC_EBP(void) { DWORD_INC(CPU_EBP); CPU_WORKCLOCK(2); } +void INC_ESI(void) { DWORD_INC(CPU_ESI); CPU_WORKCLOCK(2); } +void INC_EDI(void) { DWORD_INC(CPU_EDI); CPU_WORKCLOCK(2); } + + + +/* + * DEC + */ +ARITH_INSTRUCTION_1(DEC) + +void DEC_AX(void) { WORD_DEC(CPU_AX); CPU_WORKCLOCK(2); } +void DEC_CX(void) { WORD_DEC(CPU_CX); CPU_WORKCLOCK(2); } +void DEC_DX(void) { WORD_DEC(CPU_DX); CPU_WORKCLOCK(2); } +void DEC_BX(void) { WORD_DEC(CPU_BX); CPU_WORKCLOCK(2); } +void DEC_SP(void) { WORD_DEC(CPU_SP); CPU_WORKCLOCK(2); } +void DEC_BP(void) { WORD_DEC(CPU_BP); CPU_WORKCLOCK(2); } +void DEC_SI(void) { WORD_DEC(CPU_SI); CPU_WORKCLOCK(2); } +void DEC_DI(void) { WORD_DEC(CPU_DI); CPU_WORKCLOCK(2); } + +void DEC_EAX(void) { DWORD_DEC(CPU_EAX); CPU_WORKCLOCK(2); } +void DEC_ECX(void) { DWORD_DEC(CPU_ECX); CPU_WORKCLOCK(2); } +void DEC_EDX(void) { DWORD_DEC(CPU_EDX); CPU_WORKCLOCK(2); } +void DEC_EBX(void) { DWORD_DEC(CPU_EBX); CPU_WORKCLOCK(2); } +void DEC_ESP(void) { DWORD_DEC(CPU_ESP); CPU_WORKCLOCK(2); } +void DEC_EBP(void) { DWORD_DEC(CPU_EBP); CPU_WORKCLOCK(2); } +void DEC_ESI(void) { DWORD_DEC(CPU_ESI); CPU_WORKCLOCK(2); } +void DEC_EDI(void) { DWORD_DEC(CPU_EDI); CPU_WORKCLOCK(2); } + + +/* + * NEG + */ +static UINT32 CPUCALL +NEG1(UINT32 src, void *arg) +{ + UINT32 dst; + BYTE_NEG(dst, src); + return dst; +} + +static UINT32 CPUCALL +NEG2(UINT32 src, void *arg) +{ + UINT32 dst; + WORD_NEG(dst, src); + return dst; +} + +static UINT32 CPUCALL +NEG4(UINT32 src, void *arg) +{ + UINT32 dst; + DWORD_NEG(dst, src); + return dst; +} + +void CPUCALL +NEG_Eb(UINT32 op) +{ + UINT8 *out; + UINT32 src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + src = *out; + BYTE_NEG(dst, src); + *out = (UINT8)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, NEG1, 0); + } +} + +void CPUCALL +NEG_Ew(UINT32 op) +{ + UINT16 *out; + UINT32 src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + src = *out; + WORD_NEG(dst, src); + *out = (UINT16)dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, NEG2, 0); + } +} + +void CPUCALL +NEG_Ed(UINT32 op) +{ + UINT32 *out; + UINT32 src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + src = *out; + DWORD_NEG(dst, src); + *out = dst; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, NEG4, 0); + } +} + + +/* + * CMP + */ +void +CMP_EbGb(void) +{ + UINT8 *out; + UINT32 op, src, dst, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + BYTE_SUB(res, dst, src); +} + +void +CMP_EwGw(void) +{ + UINT16 *out; + UINT32 op, src, dst, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + WORD_SUB(res, dst, src); +} + +void +CMP_EdGd(void) +{ + UINT32 *out; + UINT32 op, src, dst, res, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + DWORD_SUB(res, dst, src); +} + +void +CMP_GbEb(void) +{ + UINT8 *out; + UINT32 op, src, dst, res; + + PREPART_REG8_EA(op, src, out, 2, 5); + dst = *out; + BYTE_SUB(res, dst, src); +} + +void +CMP_GwEw(void) +{ + UINT16 *out; + UINT32 op, src, dst, res; + + PREPART_REG16_EA(op, src, out, 2, 5); + dst = *out; + WORD_SUB(res, dst, src); +} + +void +CMP_GdEd(void) +{ + UINT32 *out; + UINT32 op, src, dst, res; + + PREPART_REG32_EA(op, src, out, 2, 5); + dst = *out; + DWORD_SUB(res, dst, src); +} + +void +CMP_ALIb(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + dst = CPU_AL; + BYTE_SUB(res, dst, src); +} + +void +CMP_AXIw(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(2); + GET_PCWORD(src); + dst = CPU_AX; + WORD_SUB(res, dst, src); +} + +void +CMP_EAXId(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(2); + GET_PCDWORD(src); + dst = CPU_EAX; + DWORD_SUB(res, dst, src); +} + +void CPUCALL +CMP_EbIb(UINT8 *regp, UINT32 src) +{ + UINT32 dst, res; + + dst = *regp; + BYTE_SUB(res, dst, src); +} + +void CPUCALL +CMP_EbIb_ext(UINT32 madr, UINT32 src) +{ + UINT32 dst, res; + + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + BYTE_SUB(res, dst, src); +} + +void CPUCALL +CMP_EwIx(UINT16 *regp, UINT32 src) +{ + UINT32 dst, res; + + dst = *regp; + WORD_SUB(res, dst, src); +} + +void CPUCALL +CMP_EwIx_ext(UINT32 madr, UINT32 src) +{ + UINT32 dst, res; + + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + WORD_SUB(res, dst, src); +} + +void CPUCALL +CMP_EdIx(UINT32 *regp, UINT32 src) +{ + UINT32 dst, res; + + dst = *regp; + DWORD_SUB(res, dst, src); +} + +void CPUCALL +CMP_EdIx_ext(UINT32 madr, UINT32 src) +{ + UINT32 dst, res; + + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + DWORD_SUB(res, dst, src); +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/bin_arith.h b/source/src/vm/np21/i386c/ia32/instructions/bin_arith.h new file mode 100644 index 000000000..aa593a553 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/bin_arith.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_BIN_ARITH_H__ +#define IA32_CPU_INSTRUCTION_BIN_ARITH_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* ADD */ +void ADD_EbGb(void); +void ADD_EwGw(void); +void ADD_EdGd(void); +void ADD_GbEb(void); +void ADD_GwEw(void); +void ADD_GdEd(void); +void ADD_ALIb(void); +void ADD_AXIw(void); +void ADD_EAXId(void); +void CPUCALL ADD_EbIb(UINT8 *, UINT32); +void CPUCALL ADD_EwIx(UINT16 *, UINT32); +void CPUCALL ADD_EdIx(UINT32 *, UINT32); +void CPUCALL ADD_EbIb_ext(UINT32, UINT32); +void CPUCALL ADD_EwIx_ext(UINT32, UINT32); +void CPUCALL ADD_EdIx_ext(UINT32, UINT32); + +/* ADC */ +void ADC_EbGb(void); +void ADC_EwGw(void); +void ADC_EdGd(void); +void ADC_GbEb(void); +void ADC_GwEw(void); +void ADC_GdEd(void); +void ADC_ALIb(void); +void ADC_AXIw(void); +void ADC_EAXId(void); +void CPUCALL ADC_EbIb(UINT8 *, UINT32); +void CPUCALL ADC_EwIx(UINT16 *, UINT32); +void CPUCALL ADC_EdIx(UINT32 *, UINT32); +void CPUCALL ADC_EbIb_ext(UINT32, UINT32); +void CPUCALL ADC_EwIx_ext(UINT32, UINT32); +void CPUCALL ADC_EdIx_ext(UINT32, UINT32); + +/* SUB */ +void SUB_EbGb(void); +void SUB_EwGw(void); +void SUB_EdGd(void); +void SUB_GbEb(void); +void SUB_GwEw(void); +void SUB_GdEd(void); +void SUB_ALIb(void); +void SUB_AXIw(void); +void SUB_EAXId(void); +void CPUCALL SUB_EbIb(UINT8 *, UINT32); +void CPUCALL SUB_EwIx(UINT16 *, UINT32); +void CPUCALL SUB_EdIx(UINT32 *, UINT32); +void CPUCALL SUB_EbIb_ext(UINT32, UINT32); +void CPUCALL SUB_EwIx_ext(UINT32, UINT32); +void CPUCALL SUB_EdIx_ext(UINT32, UINT32); + +/* SBB */ +void SBB_EbGb(void); +void SBB_EwGw(void); +void SBB_EdGd(void); +void SBB_GbEb(void); +void SBB_GwEw(void); +void SBB_GdEd(void); +void SBB_ALIb(void); +void SBB_AXIw(void); +void SBB_EAXId(void); +void CPUCALL SBB_EbIb(UINT8 *, UINT32); +void CPUCALL SBB_EwIx(UINT16 *, UINT32); +void CPUCALL SBB_EdIx(UINT32 *, UINT32); +void CPUCALL SBB_EbIb_ext(UINT32, UINT32); +void CPUCALL SBB_EwIx_ext(UINT32, UINT32); +void CPUCALL SBB_EdIx_ext(UINT32, UINT32); + +/* IMUL */ +void CPUCALL IMUL_ALEb(UINT32 op); +void CPUCALL IMUL_AXEw(UINT32 op); +void CPUCALL IMUL_EAXEd(UINT32 op); +void IMUL_GwEw(void); +void IMUL_GdEd(void); +void IMUL_GwEwIb(void); +void IMUL_GdEdIb(void); +void IMUL_GwEwIw(void); +void IMUL_GdEdId(void); + +/* MUL */ +void CPUCALL MUL_ALEb(UINT32 op); +void CPUCALL MUL_AXEw(UINT32 op); +void CPUCALL MUL_EAXEd(UINT32 op); + +/* IDIV */ +void CPUCALL IDIV_ALEb(UINT32 op); +void CPUCALL IDIV_AXEw(UINT32 op); +void CPUCALL IDIV_EAXEd(UINT32 op); + +/* DIV */ +void CPUCALL DIV_ALEb(UINT32 op); +void CPUCALL DIV_AXEw(UINT32 op); +void CPUCALL DIV_EAXEd(UINT32 op); + +/* INC */ +void CPUCALL INC_Eb(UINT32 op); +void CPUCALL INC_Ew(UINT32 op); +void CPUCALL INC_Ed(UINT32 op); +void INC_AX(void); +void INC_CX(void); +void INC_DX(void); +void INC_BX(void); +void INC_SP(void); +void INC_BP(void); +void INC_SI(void); +void INC_DI(void); +void INC_EAX(void); +void INC_ECX(void); +void INC_EDX(void); +void INC_EBX(void); +void INC_ESP(void); +void INC_EBP(void); +void INC_ESI(void); +void INC_EDI(void); + +/* DEC */ +void CPUCALL DEC_Eb(UINT32 op); +void CPUCALL DEC_Ew(UINT32 op); +void CPUCALL DEC_Ed(UINT32 op); +void DEC_AX(void); +void DEC_CX(void); +void DEC_DX(void); +void DEC_BX(void); +void DEC_SP(void); +void DEC_BP(void); +void DEC_SI(void); +void DEC_DI(void); +void DEC_EAX(void); +void DEC_ECX(void); +void DEC_EDX(void); +void DEC_EBX(void); +void DEC_ESP(void); +void DEC_EBP(void); +void DEC_ESI(void); +void DEC_EDI(void); + +/* NEG */ +void CPUCALL NEG_Eb(UINT32 op); +void CPUCALL NEG_Ew(UINT32 op); +void CPUCALL NEG_Ed(UINT32 op); + +/* CMP */ +void CMP_EbGb(void); +void CMP_EwGw(void); +void CMP_EdGd(void); +void CMP_GbEb(void); +void CMP_GwEw(void); +void CMP_GdEd(void); +void CMP_ALIb(void); +void CMP_AXIw(void); +void CMP_EAXId(void); +void CPUCALL CMP_EbIb(UINT8 *, UINT32); +void CPUCALL CMP_EwIx(UINT16 *, UINT32); +void CPUCALL CMP_EdIx(UINT32 *, UINT32); +void CPUCALL CMP_EbIb_ext(UINT32, UINT32); +void CPUCALL CMP_EwIx_ext(UINT32, UINT32); +void CPUCALL CMP_EdIx_ext(UINT32, UINT32); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_BIN_ARITH_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/bit_byte.cpp b/source/src/vm/np21/i386c/ia32/instructions/bit_byte.cpp new file mode 100644 index 000000000..91b5aa301 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/bit_byte.cpp @@ -0,0 +1,1056 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "bit_byte.h" + +#define BIT_OFFSET16(v) (2 * (((SINT16)(v)) >> 4)) +#define BIT_INDEX16(v) ((v) & 0xf) +#define BIT_MAKEBIT16(v) (1 << BIT_INDEX16(v)) + +#define BIT_OFFSET32(v) (4 * (((SINT32)(v)) >> 5)) +#define BIT_INDEX32(v) ((v) & 0x1f) +#define BIT_MAKEBIT32(v) (1 << BIT_INDEX32(v)) + + +/* + * BT + */ +void +BT_EwGw(void) +{ + UINT32 op, src, dst, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET16(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + CPU_FLAGL &= ~C_FLAG; + CPU_FLAGL |= (dst >> BIT_INDEX16(src)) & 1; +} + +void +BT_EdGd(void) +{ + UINT32 op, src, dst, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET32(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + CPU_FLAGL &= ~C_FLAG; + CPU_FLAGL |= (dst >> BIT_INDEX32(src)) & 1; +} + +void CPUCALL +BT_EwIb(UINT32 op) +{ + UINT32 src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + dst = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + CPU_FLAGL &= ~C_FLAG; + CPU_FLAGL |= (dst >> BIT_INDEX16(src)) & 1; +} + +void CPUCALL +BT_EdIb(UINT32 op) +{ + UINT32 src, dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + dst = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + CPU_FLAGL &= ~C_FLAG; + CPU_FLAGL |= (dst >> BIT_INDEX32(src)) & 1; +} + +/* + * BTS + */ +void +BTS_EwGw(void) +{ + UINT16 *out; + UINT32 op, src, dst, res, madr; + UINT16 bit; + + PREPART_EA_REG16(op, src); + bit = BIT_MAKEBIT16(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + res = dst | bit; + *out = (UINT16)res; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET16(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst | bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + } +} + +void +BTS_EdGd(void) +{ + UINT32 *out; + UINT32 op, src, dst, res, madr; + UINT32 bit; + + PREPART_EA_REG32(op, src); + bit = BIT_MAKEBIT32(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + res = dst | bit; + *out = res; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET32(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst | bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void CPUCALL +BTS_EwIb(UINT32 op) +{ + UINT16 *out; + UINT32 src, dst, res, madr; + UINT16 bit; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + out = reg16_b20[op]; + dst = *out; + bit = BIT_MAKEBIT16(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + res = dst | bit; + *out = (UINT16)res; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + bit = BIT_MAKEBIT16(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst | bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + } +} + +void CPUCALL +BTS_EdIb(UINT32 op) +{ + UINT32 *out; + UINT32 src, dst, res, madr; + UINT32 bit; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + out = reg32_b20[op]; + dst = *out; + bit = BIT_MAKEBIT32(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + res = dst | bit; + *out = res; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + bit = BIT_MAKEBIT32(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst | bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +/* + * BTR + */ +void +BTR_EwGw(void) +{ + UINT16 *out; + UINT32 op, src, dst, res, madr; + UINT16 bit; + + PREPART_EA_REG16(op, src); + bit = BIT_MAKEBIT16(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + res = dst & ~bit; + *out = (UINT16)res; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET16(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst & ~bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + } +} + +void +BTR_EdGd(void) +{ + UINT32 *out; + UINT32 op, src, dst, res, madr; + UINT32 bit; + + PREPART_EA_REG32(op, src); + bit = BIT_MAKEBIT32(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + res = dst & ~bit; + *out = res; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET32(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst & ~bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void CPUCALL +BTR_EwIb(UINT32 op) +{ + UINT16 *out; + UINT32 src, dst, res, madr; + UINT16 bit; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + out = reg16_b20[op]; + dst = *out; + bit = BIT_MAKEBIT16(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + res = dst & ~bit; + *out = (UINT16)res; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + bit = BIT_MAKEBIT16(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst & ~bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + } +} + +void CPUCALL +BTR_EdIb(UINT32 op) +{ + UINT32 *out; + UINT32 src, dst, res, madr; + UINT32 bit; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + out = reg32_b20[op]; + dst = *out; + bit = BIT_MAKEBIT32(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + res = dst & ~bit; + *out = res; + } else { + CPU_FLAGL &= ~C_FLAG; + } + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + bit = BIT_MAKEBIT32(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst & ~bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +/* + * BTC + */ +void +BTC_EwGw(void) +{ + UINT16 *out; + UINT32 op, src, dst, res, madr; + UINT16 bit; + + PREPART_EA_REG16(op, src); + bit = BIT_MAKEBIT16(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + *out = (UINT16)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET16(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + } +} + +void +BTC_EdGd(void) +{ + UINT32 *out; + UINT32 op, src, dst, res, madr; + UINT32 bit; + + PREPART_EA_REG32(op, src); + bit = BIT_MAKEBIT32(src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + *out = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + madr += BIT_OFFSET32(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void CPUCALL +BTC_EwIb(UINT32 op) +{ + UINT16 *out; + UINT32 src, dst, res, madr; + UINT16 bit; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + out = reg16_b20[op]; + dst = *out; + bit = BIT_MAKEBIT16(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + *out = (UINT16)res; + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + bit = BIT_MAKEBIT16(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + } +} + +void CPUCALL +BTC_EdIb(UINT32 op) +{ + UINT32 *out; + UINT32 src, dst, res, madr; + UINT32 bit; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(src); + out = reg32_b20[op]; + dst = *out; + bit = BIT_MAKEBIT32(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + *out = res; + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + GET_PCBYTE(src); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + bit = BIT_MAKEBIT32(src); + if (dst & bit) { + CPU_FLAGL |= C_FLAG; + } else { + CPU_FLAGL &= ~C_FLAG; + } + res = dst ^ bit; + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +/* + * BSF + */ +void +BSF_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + int bit; + + PREPART_REG16_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + CPU_FLAGL &= ~Z_FLAG; + for (bit = 0; bit < 15; bit++) { + if (src & (1 << bit)) + break; + } + *out = (UINT16)bit; + } +} + +void +BSF_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + int bit; + + PREPART_REG32_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + CPU_FLAGL &= ~Z_FLAG; + for (bit = 0; bit < 31; bit++) { + if (src & (1 << bit)) + break; + } + *out = (UINT32)bit; + } +} + +/* + * BSR + */ +void +BSR_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + int bit; + + PREPART_REG16_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + CPU_FLAGL &= ~Z_FLAG; + for (bit = 15; bit > 0; bit--) { + if (src & (1 << bit)) + break; + } + *out = (UINT16)bit; + } +} + +void +BSR_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + int bit; + + PREPART_REG32_EA(op, src, out, 2, 7); + if (src == 0) { + CPU_FLAGL |= Z_FLAG; + /* dest reg is undefined */ + } else { + CPU_FLAGL &= ~Z_FLAG; + for (bit = 31; bit > 0; bit--) { + if (src & (1 << bit)) + break; + } + *out = (UINT32)bit; + } +} + +/* + * SETcc + */ +void +SETO_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_O?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNO_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NO?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETC_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_C?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNC_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NC?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETZ_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_Z?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNZ_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NZ?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETA_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_A?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNA_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NA?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETS_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_S?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNS_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NS?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETP_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_P?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNP_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NP?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETL_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_L?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNL_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NL?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETLE_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_LE?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +void +SETNLE_Eb(void) +{ + UINT32 op, madr; + UINT8 v = CC_NLE?1:0; + + GET_PCBYTE(op); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = v; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, v); + } +} + +/* + * TEST + */ +void +TEST_EbGb(void) +{ + UINT32 op, src, tmp, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + BYTE_AND(tmp, src); +} + +void +TEST_EwGw(void) +{ + UINT32 op, src, tmp, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + WORD_AND(tmp, src); +} + +void +TEST_EdGd(void) +{ + UINT32 op, src, tmp, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + DWORD_AND(tmp, src); +} + +void +TEST_ALIb(void) +{ + UINT32 src, tmp; + + CPU_WORKCLOCK(3); + tmp = CPU_AL; + GET_PCBYTE(src); + BYTE_AND(tmp, src); +} + +void +TEST_AXIw(void) +{ + UINT32 src, tmp; + + CPU_WORKCLOCK(3); + tmp = CPU_AX; + GET_PCWORD(src); + WORD_AND(tmp, src); +} + +void +TEST_EAXId(void) +{ + UINT32 src, tmp; + + CPU_WORKCLOCK(3); + tmp = CPU_EAX; + GET_PCDWORD(src); + DWORD_AND(tmp, src); +} + +void CPUCALL +TEST_EbIb(UINT32 op) +{ + UINT32 src, tmp, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg8_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + } + GET_PCBYTE(src); + BYTE_AND(tmp, src); +} + +void CPUCALL +TEST_EwIw(UINT32 op) +{ + UINT32 src, tmp, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + GET_PCWORD(src); + WORD_AND(tmp, src); +} + +void CPUCALL +TEST_EdId(UINT32 op) +{ + UINT32 src, tmp, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + tmp = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(6); + madr = calc_ea_dst(op); + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + GET_PCDWORD(src); + DWORD_AND(tmp, src); +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/bit_byte.h b/source/src/vm/np21/i386c/ia32/instructions/bit_byte.h new file mode 100644 index 000000000..a33461fba --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/bit_byte.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_BIT_BYTE_H__ +#define IA32_CPU_INSTRUCTION_BIT_BYTE_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * BTx + */ +void BT_EwGw(void); +void BT_EdGd(void); +void CPUCALL BT_EwIb(UINT32); +void CPUCALL BT_EdIb(UINT32); +void BTS_EwGw(void); +void BTS_EdGd(void); +void CPUCALL BTS_EwIb(UINT32); +void CPUCALL BTS_EdIb(UINT32); +void BTR_EwGw(void); +void BTR_EdGd(void); +void CPUCALL BTR_EwIb(UINT32); +void CPUCALL BTR_EdIb(UINT32); +void BTC_EwGw(void); +void BTC_EdGd(void); +void CPUCALL BTC_EwIb(UINT32); +void CPUCALL BTC_EdIb(UINT32); + +/* + * BSx + */ +void BSF_GwEw(void); +void BSF_GdEd(void); +void BSR_GwEw(void); +void BSR_GdEd(void); + +/* + * SETcc + */ +void SETO_Eb(void); +void SETNO_Eb(void); +void SETC_Eb(void); +void SETNC_Eb(void); +void SETZ_Eb(void); +void SETNZ_Eb(void); +void SETA_Eb(void); +void SETNA_Eb(void); +void SETS_Eb(void); +void SETNS_Eb(void); +void SETP_Eb(void); +void SETNP_Eb(void); +void SETL_Eb(void); +void SETNL_Eb(void); +void SETLE_Eb(void); +void SETNLE_Eb(void); + +/* + * TEST + */ +void TEST_EbGb(void); +void TEST_EwGw(void); +void TEST_EdGd(void); +void TEST_ALIb(void); +void TEST_AXIw(void); +void TEST_EAXId(void); + +void CPUCALL TEST_EbIb(UINT32); +void CPUCALL TEST_EwIw(UINT32); +void CPUCALL TEST_EdId(UINT32); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_BIT_BYTE_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/ctrl_trans.cpp b/source/src/vm/np21/i386c/ia32/instructions/ctrl_trans.cpp new file mode 100644 index 000000000..02ddb33be --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/ctrl_trans.cpp @@ -0,0 +1,1712 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" +#include "../ctrlxfer.h" + +#include "ctrl_trans.h" + +#if defined(ENABLE_TRAP) +#include "trap/inttrap.h" +#endif + +#ifdef SUPPORT_IA32_HAXM +#include "bios/bios.h" +#endif + + +/* + * JMP + */ +void +JMP_Jb(void) +{ + + JMPSHORT(7); +} + +void +JMP_Jw(void) +{ + + JMPNEAR(7); +} + +void +JMP_Jd(void) +{ + + JMPNEAR32(7); +} + +void CPUCALL +JMP_Ew(UINT32 op) +{ + UINT32 madr; + UINT16 new_ip; + + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_EIP = new_ip; +} + +void CPUCALL +JMP_Ed(UINT32 op) +{ + UINT32 madr; + UINT32 new_ip; + + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_EIP = new_ip; +} + +void +JMP16_Ap(void) +{ + descriptor_t sd; + UINT16 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(11); + GET_PCWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } +} + +void +JMP32_Ap(void) +{ + descriptor_t sd; + UINT32 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(11); + GET_PCDWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } +} + +void CPUCALL +JMP16_Ep(UINT32 op) +{ + descriptor_t sd; + UINT32 madr; + UINT16 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(11); + if (op < 0xc0) { + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +JMP32_Ep(UINT32 op) +{ + descriptor_t sd; + UINT32 madr; + UINT32 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(11); + if (op < 0xc0) { + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + } else { + /* Protected mode */ + JMPfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* jo */ +void +JO_Jb(void) +{ + + if (CC_NO) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JO_Jw(void) +{ + + if (CC_NO) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JO_Jd(void) +{ + + if (CC_NO) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jno */ +void +JNO_Jb(void) +{ + + if (CC_O) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNO_Jw(void) +{ + + if (CC_O) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNO_Jd(void) +{ + + if (CC_O) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jc */ +void +JC_Jb(void) +{ + + if (CC_NC) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JC_Jw(void) +{ + + if (CC_NC) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JC_Jd(void) +{ + + if (CC_NC) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jnc */ +void +JNC_Jb(void) +{ + + if (CC_C) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} +void +JNC_Jw(void) +{ + + if (CC_C) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} +void +JNC_Jd(void) +{ + + if (CC_C) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jz */ +void +JZ_Jb(void) +{ + + if (CC_NZ) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JZ_Jw(void) +{ + + if (CC_NZ) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JZ_Jd(void) +{ + + if (CC_NZ) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jnz */ +void +JNZ_Jb(void) +{ + + if (CC_Z) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNZ_Jw(void) +{ + + if (CC_Z) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNZ_Jd(void) +{ + + if (CC_Z) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jna */ +void +JNA_Jb(void) +{ + + if (CC_A) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNA_Jw(void) +{ + + if (CC_A) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNA_Jd(void) +{ + + if (CC_A) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* ja */ +void +JA_Jb(void) +{ + + if (CC_NA) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JA_Jw(void) +{ + + if (CC_NA) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JA_Jd(void) +{ + + if (CC_NA) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* js */ +void +JS_Jb(void) +{ + + if (CC_NS) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JS_Jw(void) +{ + + if (CC_NS) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JS_Jd(void) +{ + + if (CC_NS) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jns */ +void +JNS_Jb(void) +{ + + if (CC_S) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNS_Jw(void) +{ + + if (CC_S) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNS_Jd(void) +{ + + if (CC_S) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jp */ +void +JP_Jb(void) +{ + + if (CC_NP) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JP_Jw(void) +{ + + if (CC_NP) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JP_Jd(void) +{ + + if (CC_NP) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jnp */ +void +JNP_Jb(void) +{ + + if (CC_P) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNP_Jw(void) +{ + + if (CC_P) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNP_Jd(void) +{ + + if (CC_P) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jl */ +void +JL_Jb(void) +{ + + if (CC_NL) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JL_Jw(void) +{ + + if (CC_NL) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JL_Jd(void) +{ + + if (CC_NL) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jnl */ +void +JNL_Jb(void) +{ + + if (CC_L) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNL_Jw(void) +{ + + if (CC_L) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNL_Jd(void) +{ + + if (CC_L) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jle */ +void +JLE_Jb(void) +{ + + if (CC_NLE) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JLE_Jw(void) +{ + + if (CC_NLE) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JLE_Jd(void) +{ + + if (CC_NLE) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jnle */ +void +JNLE_Jb(void) +{ + + if (CC_LE) { + JMPNOP(2, 1); + } else { + JMPSHORT(7); + } +} + +void +JNLE_Jw(void) +{ + + if (CC_LE) { + JMPNOP(2, 2); + } else { + JMPNEAR(7); + } +} + +void +JNLE_Jd(void) +{ + + if (CC_LE) { + JMPNOP(2, 4); + } else { + JMPNEAR32(7); + } +} + +/* jcxz */ +void +JeCXZ_Jb(void) +{ + + if (!CPU_INST_AS32) { + if (CPU_CX == 0) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + } else { + if (CPU_ECX == 0) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + } +} + +/* + * LOOPcc + */ +/* loopne */ +void +LOOPNE_Jb(void) +{ + UINT32 cx; + + if (!CPU_INST_AS32) { + cx = CPU_CX; + if (--cx != 0 && CC_NZ) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + CPU_CX--; + } else { + cx = CPU_ECX; + if (--cx != 0 && CC_NZ) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + CPU_ECX--; + } +} + +/* loope */ +void +LOOPE_Jb(void) +{ + UINT32 cx; + + if (!CPU_INST_AS32) { + cx = CPU_CX; + if (--cx != 0 && CC_Z) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + CPU_CX--; + } else { + cx = CPU_ECX; + if (--cx != 0 && CC_Z) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + CPU_ECX--; + } +} + +/* loop */ +void +LOOP_Jb(void) +{ + UINT32 cx; + + if (!CPU_INST_AS32) { + cx = CPU_CX; + if (--cx != 0) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + CPU_CX--; + } else { + cx = CPU_ECX; + if (--cx != 0) { + JMPSHORT(8); + } else { + JMPNOP(4, 1); + } + CPU_ECX--; + } +} + +/* + * CALL + */ +void +CALL_Aw(void) +{ + UINT16 new_ip; + SINT16 dest; + + CPU_WORKCLOCK(7); + CPU_SET_PREV_ESP(); + GET_PCWORDS(dest); + new_ip = CPU_EIP + dest; + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + PUSH0_16(CPU_IP); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); +} + +void +CALL_Ad(void) +{ + UINT32 new_ip; + UINT32 dest; + + CPU_WORKCLOCK(7); + CPU_SET_PREV_ESP(); + GET_PCDWORD(dest); + new_ip = CPU_EIP + dest; + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + PUSH0_32(CPU_EIP); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); +} + +void CPUCALL +CALL_Ew(UINT32 op) +{ + UINT32 madr; + UINT16 new_ip; + + CPU_SET_PREV_ESP(); + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + PUSH0_16(CPU_IP); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); +} + +void CPUCALL +CALL_Ed(UINT32 op) +{ + UINT32 madr; + UINT32 new_ip; + + CPU_SET_PREV_ESP(); + if (op >= 0xc0) { + CPU_WORKCLOCK(7); + new_ip = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + PUSH0_32(CPU_EIP); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); +} + +//#ifdef I86_PSEUDO_BIOS +int +CALL_PSEUDO_BIOS(UINT16 new_ip, UINT16 new_cs) +{ + if (device_bios != NULL) { +// uint16_t regs[8] = {CPU_AX, CPU_CX, CPU_DX, CPU_BX, CPU_SP, CPU_BP, CPU_SI, CPU_DI}; + uint32_t regs[8] = {CPU_EAX, CPU_ECX, CPU_EDX, CPU_EBX, CPU_ESP, CPU_EBP, CPU_ESI, CPU_EDI}; + uint16_t sregs[4] = {CPU_ES, CPU_CS, CPU_SS, CPU_DS}; + int32_t ZeroFlag = ((CPU_FLAG & Z_FLAG) ? 1 : 0); + int32_t CarryFlag = ((CPU_FLAG & C_FLAG) ? 1 : 0); + + int cycles = 0; + uint64_t total_cycles = 0; +// if (device_bios->bios_call_far_i86((new_cs << 4) + new_ip, regs, sregs, &ZeroFlag, &CarryFlag)) { + if (device_bios->bios_call_far_ia32((new_cs << 4) + new_ip, regs, sregs, &ZeroFlag, &CarryFlag, &cycles, &total_cycles)) { + CPU_EAX = regs[0]; + CPU_ECX = regs[1]; + CPU_EDX = regs[2]; + CPU_EBX = regs[3]; + CPU_ESP = regs[4]; + CPU_EBP = regs[5]; + CPU_ESI = regs[6]; + CPU_EDI = regs[7]; + if (ZeroFlag) { + CPU_FLAG |= Z_FLAG; + } else { + CPU_FLAG &= ~Z_FLAG; + } + if (CarryFlag) { + CPU_FLAG |= C_FLAG; + } else { + CPU_FLAG &= ~C_FLAG; + } + CPU_WORKCLOCK(1000); // temporary + return 1; + } + } + return 0; +} +//#endif + +void +CALL16_Ap(void) +{ + descriptor_t sd; + UINT16 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(13); + GET_PCWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { +//#ifdef I86_PSEUDO_BIOS + if (CALL_PSEUDO_BIOS(new_ip, new_cs)) { + return; + } +//#endif + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } +} + +void +CALL32_Ap(void) +{ + descriptor_t sd; + UINT32 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(13); + GET_PCDWORD(new_ip); + GET_PCWORD(new_cs); + if (!CPU_STAT_PM || CPU_STAT_VM86) { +//#ifdef I86_PSEUDO_BIOS + if (CALL_PSEUDO_BIOS(new_ip, new_cs)) { + return; + } +//#endif + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } +} + +void CPUCALL +CALL16_Ep(UINT32 op) +{ + descriptor_t sd; + UINT32 madr; + UINT16 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(16); + if (op < 0xc0) { + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + if (!CPU_STAT_PM || CPU_STAT_VM86) { +//#ifdef I86_PSEUDO_BIOS + if (CALL_PSEUDO_BIOS(new_ip, new_cs)) { + return; + } +//#endif + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_16(CPU_CS); + PUSH0_16(CPU_IP); + + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +CALL32_Ep(UINT32 op) +{ + descriptor_t sd; + UINT32 madr; + UINT32 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(16); + if (op < 0xc0) { + madr = calc_ea_dst(op); + new_ip = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + new_cs = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + if (!CPU_STAT_PM || CPU_STAT_VM86) { +//#ifdef I86_PSEUDO_BIOS + if (CALL_PSEUDO_BIOS(new_ip, new_cs)) { + return; + } +//#endif + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + PUSH0_32(CPU_CS); + PUSH0_32(CPU_EIP); + + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + CALLfar_pm(new_cs, new_ip); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* + * RET + */ +void +RETnear16(void) +{ + UINT16 new_ip; + + CPU_WORKCLOCK(11); + CPU_SET_PREV_ESP(); + POP0_16(new_ip); + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); +} + +void +RETnear32(void) +{ + UINT32 new_ip; + + CPU_WORKCLOCK(11); + CPU_SET_PREV_ESP(); + POP0_32(new_ip); + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); +} + +void +RETnear16_Iw(void) +{ + UINT16 new_ip; + UINT16 size; + + CPU_WORKCLOCK(11); + CPU_SET_PREV_ESP(); + GET_PCWORD(size); + POP0_16(new_ip); + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_EIP = new_ip; + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } + CPU_CLEAR_PREV_ESP(); +} + +void +RETnear32_Iw(void) +{ + UINT32 new_ip; + UINT16 size; + + CPU_WORKCLOCK(11); + CPU_SET_PREV_ESP(); + GET_PCWORD(size); + POP0_32(new_ip); + if (new_ip > CPU_STAT_CS_LIMIT) { + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_EIP = new_ip; + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } + CPU_CLEAR_PREV_ESP(); +} + +void +RETfar16(void) +{ + descriptor_t sd; + UINT16 new_ip; + UINT16 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(15); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + POP0_16(new_ip); + POP0_16(new_cs); + + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + RETfar_pm(0); + } +} + +void +RETfar32(void) +{ + descriptor_t sd; + UINT32 new_ip; + UINT32 new_cs; + UINT16 sreg; + + CPU_WORKCLOCK(15); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + POP0_32(new_ip); + POP0_32(new_cs); + + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, (UINT16)new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + LOAD_SEGREG(CPU_CS_INDEX, (UINT16)new_cs); + CPU_EIP = new_ip; + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + RETfar_pm(0); + } +} + +void +RETfar16_Iw(void) +{ + descriptor_t sd; + UINT16 new_ip; + UINT16 new_cs; + UINT16 sreg; + UINT16 size; + + CPU_WORKCLOCK(15); + GET_PCWORD(size); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + POP0_16(new_ip); + POP0_16(new_cs); + + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + LOAD_SEGREG(CPU_CS_INDEX, new_cs); + CPU_EIP = new_ip; + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + RETfar_pm(size); + } +} + +void +RETfar32_Iw(void) +{ + descriptor_t sd; + UINT32 new_ip; + UINT32 new_cs; + UINT16 sreg; + UINT16 size; + + CPU_WORKCLOCK(15); + GET_PCWORD(size); + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* Real mode or VM86 mode */ + CPU_SET_PREV_ESP(); + POP0_32(new_ip); + POP0_32(new_cs); + + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, (UINT16)new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + LOAD_SEGREG(CPU_CS_INDEX, (UINT16)new_cs); + CPU_EIP = new_ip; + if (!CPU_STAT_SS32) { + CPU_SP += size; + } else { + CPU_ESP += size; + } + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + RETfar_pm(size); + } +} + +void +IRET(void) +{ + descriptor_t sd; + UINT32 new_ip; + UINT32 new_flags; + UINT32 new_cs; + UINT32 mask; + UINT16 sreg; + + CPU_WORKCLOCK(22); + if (!CPU_STAT_PM) { + /* Real mode */ + CPU_SET_PREV_ESP(); + mask = I_FLAG|IOPL_FLAG; + if (!CPU_INST_OP32) { + POP0_16(new_ip); + POP0_16(new_cs); + POP0_16(new_flags); + } else { + POP0_32(new_ip); + POP0_32(new_cs); + POP0_32(new_flags); + mask |= RF_FLAG; + } + + /* check new instrunction pointer with new code segment */ + load_segreg(CPU_CS_INDEX, (UINT16)new_cs, &sreg, &sd, GP_EXCEPTION); + if (new_ip > sd.u.seg.limit) { + EXCEPTION(GP_EXCEPTION, 0); + } + + LOAD_SEGREG(CPU_CS_INDEX, (UINT16)new_cs); + CPU_EIP = new_ip; + + set_eflags(new_flags, mask); + CPU_CLEAR_PREV_ESP(); + } else { + /* Protected mode */ + IRET_pm(); + } + IRQCHECKTERM(); +} + +/* + * INT + */ +void +INT1(void) +{ + + uint32_t old_addr; + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; + } + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(old_addr, 1); + } + CPU_WORKCLOCK(33); + INTERRUPT(1, INTR_TYPE_SOFTINTR); +} + +/* This is undefined instruction; 0FA6 */ +void +INT6(void) +{ + uint32_t old_addr; + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; + } + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(old_addr, 6); + } + CPU_WORKCLOCK(33); + INTERRUPT(6, INTR_TYPE_SOFTINTR); +} + +void +INT3(void) +{ +/* +#if defined(SUPPORT_IA32_HAXM) +#if defined(USE_CUSTOM_HOOKINST) + if(bioshookinfo.hookinst == 0xCC){ + if (!CPU_STAT_PM || CPU_STAT_VM86) { + UINT32 adrs; + adrs = CPU_PREV_EIP + (CPU_CS << 4); + if ((adrs >= 0xf8000) && (adrs < 0x100000)) { + ia32_bioscall(); + return; + } + } + } +#endif +#endif +*/ + CPU_WORKCLOCK(33); + uint32_t old_addr; + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; + } + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(old_addr, 3); + } + INTERRUPT(3, INTR_TYPE_SOFTINTR); +} + +void +INTO(void) +{ + + if (!CPU_OV) { + CPU_WORKCLOCK(3); + return; + } + CPU_WORKCLOCK(35); + uint32_t old_addr; + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; + } + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(old_addr, 4); + } + INTERRUPT(4, INTR_TYPE_SOFTINTR); +} + +void +INT_Ib(void) +{ + UINT8 vect; + + CPU_WORKCLOCK(37); + if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { + uint32_t old_addr; + { + descriptor_t *sdp = &CPU_CS_DESC; + old_addr = sdp->u.seg.segbase + CPU_PREV_EIP; + } + GET_PCBYTE(vect); + if(device_debugger != NULL) { + device_debugger->add_cpu_trace_irq(old_addr, vect); + } +#if defined(ENABLE_TRAP) + softinttrap(CPU_CS, CPU_EIP - 2, vect); +#endif + INTERRUPT(vect, INTR_TYPE_SOFTINTR); + return; + } + VERBOSE(("INT_Ib: VM86 && IOPL < 3 && INTn")); +#if defined(USE_VME) + EXCEPTION(GP_EXCEPTION, 0); // XXX: 一応動いてるけど実装しないとまずい・・・? +#else + EXCEPTION(GP_EXCEPTION, 0); +#endif +} + +void +BOUND_GwMa(void) +{ + UINT32 op, madr; + UINT16 reg; + + CPU_WORKCLOCK(13); + GET_PCBYTE(op); + if (op < 0xc0) { + reg = *(reg16_b53[op]); + madr = calc_ea_dst(op); + if (reg >= cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr) && + reg <= cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2)) { + return; + } + EXCEPTION(BR_EXCEPTION, 0); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +BOUND_GdMa(void) +{ + UINT32 op, madr; + UINT32 reg; + + CPU_WORKCLOCK(13); + GET_PCBYTE(op); + if (op < 0xc0) { + reg = *(reg32_b53[op]); + madr = calc_ea_dst(op); + if (reg >= cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr) && + reg <= cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 4)) { + return; + } + EXCEPTION(BR_EXCEPTION, 0); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* + * STACK + */ +void +ENTER16_IwIb(void) +{ + UINT32 sp, bp; + UINT32 val; + UINT16 dimsize; + UINT16 new_bp; + UINT8 level; + + GET_PCWORD(dimsize); + GET_PCBYTE(level); + level &= 0x1f; + + CPU_SET_PREV_ESP(); + PUSH0_16(CPU_BP); + if (level == 0) { /* enter level=0 */ + CPU_WORKCLOCK(11); + CPU_BP = CPU_SP; + if (!CPU_STAT_SS32) { + CPU_SP -= dimsize; + } else { + CPU_ESP -= dimsize; + } + } else { + --level; + if (level == 0) { /* enter level=1 */ + CPU_WORKCLOCK(15); + sp = CPU_SP; + PUSH0_16(sp); + CPU_BP = (UINT16)sp; + if (!CPU_STAT_SS32) { + CPU_SP -= dimsize; + } else { + CPU_ESP -= dimsize; + } + } else { /* enter level=2-31 */ + CPU_WORKCLOCK(12 + level * 4); + if (!CPU_STAT_SS32) { + bp = CPU_BP; + new_bp = CPU_SP; + while (level--) { + bp -= 2; + CPU_SP -= 2; + val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_SP, (UINT16)val); + } + REGPUSH0(new_bp); + CPU_BP = new_bp; + CPU_SP -= dimsize; + } else { + bp = CPU_EBP; + new_bp = CPU_SP; + while (level--) { + bp -= 2; + CPU_ESP -= 2; + val = cpu_vmemoryread_w(CPU_SS_INDEX, bp); + cpu_vmemorywrite_w(CPU_SS_INDEX, CPU_ESP, (UINT16)val); + } + REGPUSH0_16_32(new_bp); + CPU_BP = new_bp; + CPU_ESP -= dimsize; + } + } + } + CPU_CLEAR_PREV_ESP(); +} + +void +ENTER32_IwIb(void) +{ + UINT32 sp, bp; + UINT32 new_bp; + UINT32 val; + UINT16 dimsize; + UINT8 level; + + GET_PCWORD(dimsize); + GET_PCBYTE(level); + level &= 0x1f; + + CPU_SET_PREV_ESP(); + PUSH0_32(CPU_EBP); + if (level == 0) { /* enter level=0 */ + CPU_WORKCLOCK(11); + CPU_EBP = CPU_ESP; + if (!CPU_STAT_SS32) { + CPU_SP -= dimsize; + } else { + CPU_ESP -= dimsize; + } + } else { + --level; + if (level == 0) { /* enter level=1 */ + CPU_WORKCLOCK(15); + sp = CPU_ESP; + PUSH0_32(sp); + CPU_EBP = sp; + if (CPU_STAT_SS32) { + CPU_ESP -= dimsize; + } else { + CPU_SP -= dimsize; + } + } else { /* enter level=2-31 */ + CPU_WORKCLOCK(12 + level * 4); + if (CPU_STAT_SS32) { + bp = CPU_EBP; + new_bp = CPU_ESP; + while (level--) { + bp -= 4; + CPU_ESP -= 4; + val = cpu_vmemoryread_d(CPU_SS_INDEX, bp); + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_ESP, val); + } + REGPUSH0_32(new_bp); + CPU_EBP = new_bp; + CPU_ESP -= dimsize; + } else { + bp = CPU_BP; + new_bp = CPU_ESP; + while (level--) { + bp -= 4; + CPU_SP -= 4; + val = cpu_vmemoryread_d(CPU_SS_INDEX, bp); + cpu_vmemorywrite_d(CPU_SS_INDEX, CPU_SP, val); + } + REGPUSH0_32_16(new_bp); + CPU_EBP = new_bp; + CPU_SP -= dimsize; + } + } + } + CPU_CLEAR_PREV_ESP(); +} + +void +LEAVE(void) +{ + + CPU_WORKCLOCK(4); + + CPU_SET_PREV_ESP(); + if (!CPU_STAT_SS32) { + CPU_SP = CPU_BP; + } else { + CPU_ESP = CPU_EBP; + } + if (!CPU_INST_OP32) { + POP0_16(CPU_BP); + } else { + POP0_32(CPU_EBP); + } + CPU_CLEAR_PREV_ESP(); +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/ctrl_trans.h b/source/src/vm/np21/i386c/ia32/instructions/ctrl_trans.h new file mode 100644 index 000000000..b8f715b3f --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/ctrl_trans.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_CTRL_TRANS_H__ +#define IA32_CPU_INSTRUCTION_CTRL_TRANS_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * JMP + */ +void JMP_Jb(void); +void JMP_Jw(void); +void JMP_Jd(void); +void CPUCALL JMP_Ew(UINT32); +void CPUCALL JMP_Ed(UINT32); +void JMP16_Ap(void); +void JMP32_Ap(void); +void CPUCALL JMP16_Ep(UINT32); +void CPUCALL JMP32_Ep(UINT32); + +/* + * Jcc + */ +void JO_Jb(void); +void JO_Jw(void); +void JO_Jd(void); +void JNO_Jb(void); +void JNO_Jw(void); +void JNO_Jd(void); +void JC_Jb(void); +void JC_Jw(void); +void JC_Jd(void); +void JNC_Jb(void); +void JNC_Jw(void); +void JNC_Jd(void); +void JZ_Jb(void); +void JZ_Jw(void); +void JZ_Jd(void); +void JNZ_Jb(void); +void JNZ_Jw(void); +void JNZ_Jd(void); +void JA_Jb(void); +void JA_Jw(void); +void JA_Jd(void); +void JNA_Jb(void); +void JNA_Jw(void); +void JNA_Jd(void); +void JS_Jb(void); +void JS_Jw(void); +void JS_Jd(void); +void JNS_Jb(void); +void JNS_Jw(void); +void JNS_Jd(void); +void JP_Jb(void); +void JP_Jw(void); +void JP_Jd(void); +void JNP_Jb(void); +void JNP_Jw(void); +void JNP_Jd(void); +void JL_Jb(void); +void JL_Jw(void); +void JL_Jd(void); +void JNL_Jb(void); +void JNL_Jw(void); +void JNL_Jd(void); +void JLE_Jb(void); +void JLE_Jw(void); +void JLE_Jd(void); +void JNLE_Jb(void); +void JNLE_Jw(void); +void JNLE_Jd(void); +void JeCXZ_Jb(void); + +/* + * LOOPcc + */ +void LOOPNE_Jb(void); +void LOOPE_Jb(void); +void LOOP_Jb(void); + +/* + * CALL + */ +void CALL_Aw(void); +void CALL_Ad(void); +void CPUCALL CALL_Ew(UINT32); +void CPUCALL CALL_Ed(UINT32); +void CALL16_Ap(void); +void CALL32_Ap(void); +void CPUCALL CALL16_Ep(UINT32); +void CPUCALL CALL32_Ep(UINT32); + +/* + * RET + */ +void RETnear16(void); +void RETnear32(void); +void RETnear16_Iw(void); +void RETnear32_Iw(void); +void RETfar16(void); +void RETfar32(void); +void RETfar16_Iw(void); +void RETfar32_Iw(void); +void IRET(void); + +/* + * INT + */ +void INT6(void); +void INT1(void); +void INT3(void); +void INTO(void); +void INT_Ib(void); + +void BOUND_GwMa(void); +void BOUND_GdMa(void); + +/* + * STACK + */ +void ENTER16_IwIb(void); +void ENTER32_IwIb(void); +void LEAVE(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_CTRL_TRANS_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/data_trans.cpp b/source/src/vm/np21/i386c/ia32/instructions/data_trans.cpp new file mode 100644 index 000000000..9b5d24753 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/data_trans.cpp @@ -0,0 +1,1763 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "data_trans.h" + +/* + * MOV + */ +void +MOV_EbGb(void) +{ + UINT32 op, src, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg8_b20[op]) = (UINT8)src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)src); + } +} + +void +MOV_EwGw(void) +{ + UINT32 op, src, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg16_b20[op]) = (UINT16)src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)src); + } +} + +void +MOV_EdGd(void) +{ + UINT32 op, src, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg32_b20[op]) = src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void +MOV_GbEb(void) +{ + UINT8 *out; + UINT32 op, src; + + PREPART_REG8_EA(op, src, out, 2, 5); + *out = (UINT8)src; +} + +void +MOV_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + *out = (UINT16)src; +} + +void +MOV_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + *out = src; +} + +void +MOV_EwSw(void) +{ + UINT32 op, src, madr; + UINT8 idx; + + GET_PCBYTE(op); + idx = (UINT8)((op >> 3) & 7); + if (idx < CPU_SEGREG_NUM) { + src = CPU_REGS_SREG(idx); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg16_b20[op]) = (UINT16)src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)src); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_EdSw(void) +{ + UINT32 op, src, madr; + UINT8 idx; + + GET_PCBYTE(op); + idx = (UINT8)((op >> 3) & 7); + if (idx < CPU_SEGREG_NUM) { + src = CPU_REGS_SREG(idx); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + *(reg32_b20[op]) = src; + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)src); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_SwEw(void) +{ + UINT32 op, src, madr; + UINT8 idx; + + GET_PCBYTE(op); + idx = ((UINT8)(op >> 3) & 7); + if (idx != CPU_CS_INDEX && idx < CPU_SEGREG_NUM) { + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + LOAD_SEGREG(idx, (UINT16)src); + if (idx == CPU_SS_INDEX) { + exec_1step(); + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_ALOb(void) +{ + UINT32 madr; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + } else { + GET_PCDWORD(madr); + } + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); +} + +void +MOV_AXOw(void) +{ + UINT32 madr; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + } else { + GET_PCDWORD(madr); + } + CPU_AX = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); +} + +void +MOV_EAXOd(void) +{ + UINT32 madr; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + } else { + GET_PCDWORD(madr); + } + CPU_EAX = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); +} + +void +MOV_ObAL(void) +{ + UINT32 madr; + + CPU_WORKCLOCK(3); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + } else { + GET_PCDWORD(madr); + } + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, CPU_AL); +} + +void +MOV_OwAX(void) +{ + UINT32 madr; + + CPU_WORKCLOCK(3); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + } else { + GET_PCDWORD(madr); + } + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, CPU_AX); +} + +void +MOV_OdEAX(void) +{ + UINT32 madr; + + CPU_WORKCLOCK(3); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + GET_PCWORD(madr); + } else { + GET_PCDWORD(madr); + } + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_EAX); +} + +void +MOV_EbIb(void) +{ + UINT32 op, src, res, madr; + + PREPART_EA_REG8(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCBYTE(res); + *(reg8_b20[op]) = (UINT8)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCBYTE(res); + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)res); + } +} + +void +MOV_EwIw(void) +{ + UINT32 op, src, res, madr; + + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCWORD(res); + *(reg16_b20[op]) = (UINT16)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCWORD(res); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)res); + } +} + +void +MOV_EdId(void) +{ + UINT32 op, src, res, madr; + + PREPART_EA_REG32(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + GET_PCDWORD(res); + *(reg32_b20[op]) = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + GET_PCDWORD(res); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, res); + } +} + +void MOV_ALIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_AL); } +void MOV_CLIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_CL); } +void MOV_DLIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_DL); } +void MOV_BLIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_BL); } +void MOV_AHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_AH); } +void MOV_CHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_CH); } +void MOV_DHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_DH); } +void MOV_BHIb(void) { CPU_WORKCLOCK(2); GET_PCBYTE(CPU_BH); } + +void MOV_AXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_AX); } +void MOV_CXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_CX); } +void MOV_DXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_DX); } +void MOV_BXIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_BX); } +void MOV_SPIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_SP); } +void MOV_BPIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_BP); } +void MOV_SIIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_SI); } +void MOV_DIIw(void) { CPU_WORKCLOCK(2); GET_PCWORD(CPU_DI); } + +void MOV_EAXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EAX); } +void MOV_ECXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_ECX); } +void MOV_EDXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EDX); } +void MOV_EBXId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EBX); } +void MOV_ESPId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_ESP); } +void MOV_EBPId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EBP); } +void MOV_ESIId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_ESI); } +void MOV_EDIId(void) { CPU_WORKCLOCK(2); GET_PCDWORD(CPU_EDI); } + +/* + * CMOVcc + */ +void +CMOVO_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_O) { + *out = (UINT16)src; + } +} + +void +CMOVO_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_O) { + *out = src; + } +} + +void +CMOVNO_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NO) { + *out = (UINT16)src; + } +} + +void +CMOVNO_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NO) { + *out = src; + } +} + +void +CMOVC_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_C) { + *out = (UINT16)src; + } +} + +void +CMOVC_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_C) { + *out = src; + } +} + +void +CMOVNC_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NC) { + *out = (UINT16)src; + } +} + +void +CMOVNC_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NC) { + *out = src; + } +} + +void +CMOVZ_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_Z) { + *out = (UINT16)src; + } +} + +void +CMOVZ_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_Z) { + *out = src; + } +} + +void +CMOVNZ_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NZ) { + *out = (UINT16)src; + } +} + +void +CMOVNZ_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NZ) { + *out = src; + } +} + +void +CMOVA_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_A) { + *out = (UINT16)src; + } +} + +void +CMOVA_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_A) { + *out = src; + } +} + +void +CMOVNA_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NA) { + *out = (UINT16)src; + } +} + +void +CMOVNA_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NA) { + *out = src; + } +} + +void +CMOVS_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_S) { + *out = (UINT16)src; + } +} + +void +CMOVS_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_S) { + *out = src; + } +} + +void +CMOVNS_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NS) { + *out = (UINT16)src; + } +} + +void +CMOVNS_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NS) { + *out = src; + } +} + +void +CMOVP_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_P) { + *out = (UINT16)src; + } +} + +void +CMOVP_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_P) { + *out = src; + } +} + +void +CMOVNP_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NP) { + *out = (UINT16)src; + } +} + +void +CMOVNP_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NP) { + *out = src; + } +} + +void +CMOVL_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_L) { + *out = (UINT16)src; + } +} + +void +CMOVL_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_L) { + *out = src; + } +} + +void +CMOVNL_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NL) { + *out = (UINT16)src; + } +} + +void +CMOVNL_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NL) { + *out = src; + } +} + +void +CMOVLE_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_LE) { + *out = (UINT16)src; + } +} + +void +CMOVLE_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_LE) { + *out = src; + } +} + +void +CMOVNLE_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + if (CC_NLE) { + *out = (UINT16)src; + } +} + +void +CMOVNLE_GdEd(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA(op, src, out, 2, 5); + if (CC_NLE) { + *out = src; + } +} + +/* + * XCHG + */ +static UINT32 CPUCALL +XCHG(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + (void)dst; + return src; +} + +void +XCHG_EbGb(void) +{ + UINT8 *out, *src; + UINT32 op, madr; + + PREPART_EA_REG8P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg8_b20[op]; + SWAP_BYTE(*out, *src); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + *src = (UINT8)cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, XCHG, UINT32_TO_PTR(*src)); + } +} + +void +XCHG_EwGw(void) +{ + UINT16 *out, *src; + UINT32 op, madr; + + PREPART_EA_REG16P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg16_b20[op]; + SWAP_WORD(*out, *src); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + *src = (UINT16)cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, XCHG, UINT32_TO_PTR(*src)); + } +} + +void +XCHG_EdGd(void) +{ + UINT32 *out, *src; + UINT32 op, madr; + + PREPART_EA_REG32P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(3); + out = reg32_b20[op]; + SWAP_DWORD(*out, *src); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + *src = cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, XCHG, UINT32_TO_PTR(*src)); + } +} + +/* void XCHG_AXAX(void) { } */ +void XCHG_CXAX(void) { CPU_WORKCLOCK(3); SWAP_WORD(CPU_CX, CPU_AX); } +void XCHG_DXAX(void) { CPU_WORKCLOCK(3); SWAP_WORD(CPU_DX, CPU_AX); } +void XCHG_BXAX(void) { CPU_WORKCLOCK(3); SWAP_WORD(CPU_BX, CPU_AX); } +void XCHG_SPAX(void) { CPU_WORKCLOCK(3); SWAP_WORD(CPU_SP, CPU_AX); } +void XCHG_BPAX(void) { CPU_WORKCLOCK(3); SWAP_WORD(CPU_BP, CPU_AX); } +void XCHG_SIAX(void) { CPU_WORKCLOCK(3); SWAP_WORD(CPU_SI, CPU_AX); } +void XCHG_DIAX(void) { CPU_WORKCLOCK(3); SWAP_WORD(CPU_DI, CPU_AX); } + +/* void XCHG_EAXEAX(void) { } */ +void XCHG_ECXEAX(void) { CPU_WORKCLOCK(3); SWAP_DWORD(CPU_ECX, CPU_EAX); } +void XCHG_EDXEAX(void) { CPU_WORKCLOCK(3); SWAP_DWORD(CPU_EDX, CPU_EAX); } +void XCHG_EBXEAX(void) { CPU_WORKCLOCK(3); SWAP_DWORD(CPU_EBX, CPU_EAX); } +void XCHG_ESPEAX(void) { CPU_WORKCLOCK(3); SWAP_DWORD(CPU_ESP, CPU_EAX); } +void XCHG_EBPEAX(void) { CPU_WORKCLOCK(3); SWAP_DWORD(CPU_EBP, CPU_EAX); } +void XCHG_ESIEAX(void) { CPU_WORKCLOCK(3); SWAP_DWORD(CPU_ESI, CPU_EAX); } +void XCHG_EDIEAX(void) { CPU_WORKCLOCK(3); SWAP_DWORD(CPU_EDI, CPU_EAX); } + +/* + * BSWAP + */ +static INLINE UINT32 CPUCALL +BSWAP_DWORD(UINT32 val) +{ + UINT32 v; + v = (val & 0x000000ff) << 24; + v |= (val & 0x0000ff00) << 8; + v |= (val & 0x00ff0000) >> 8; + v |= (val & 0xff000000) >> 24; + return v; +} + +void BSWAP_EAX(void) { CPU_WORKCLOCK(2); CPU_EAX = BSWAP_DWORD(CPU_EAX); } +void BSWAP_ECX(void) { CPU_WORKCLOCK(2); CPU_ECX = BSWAP_DWORD(CPU_ECX); } +void BSWAP_EDX(void) { CPU_WORKCLOCK(2); CPU_EDX = BSWAP_DWORD(CPU_EDX); } +void BSWAP_EBX(void) { CPU_WORKCLOCK(2); CPU_EBX = BSWAP_DWORD(CPU_EBX); } +void BSWAP_ESP(void) { CPU_WORKCLOCK(2); CPU_ESP = BSWAP_DWORD(CPU_ESP); } +void BSWAP_EBP(void) { CPU_WORKCLOCK(2); CPU_EBP = BSWAP_DWORD(CPU_EBP); } +void BSWAP_ESI(void) { CPU_WORKCLOCK(2); CPU_ESI = BSWAP_DWORD(CPU_ESI); } +void BSWAP_EDI(void) { CPU_WORKCLOCK(2); CPU_EDI = BSWAP_DWORD(CPU_EDI); } + +/* + * XADD + */ +static UINT32 CPUCALL +XADD1(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + UINT32 res; + BYTE_ADD(res, dst, src); + return res; +} + +static UINT32 CPUCALL +XADD2(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + UINT32 res; + WORD_ADD(res, dst, src); + return res; +} + +static UINT32 CPUCALL +XADD4(UINT32 dst, void *arg) +{ + UINT32 src = PTR_TO_UINT32(arg); + UINT32 res; + DWORD_ADD(res, dst, src); + return res; +} + +void +XADD_EbGb(void) +{ + UINT8 *out, *src; + UINT32 op, dst, res, madr; + + PREPART_EA_REG8P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg8_b20[op]; + dst = *out; + BYTE_ADD(res, dst, *src); + *src = (UINT8)dst; + *out = (UINT8)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + *src = (UINT8)cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, XADD1, UINT32_TO_PTR(*src)); + } +} + +void +XADD_EwGw(void) +{ + UINT16 *out, *src; + UINT32 op, dst, res, madr; + + PREPART_EA_REG16P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b20[op]; + dst = *out; + WORD_ADD(res, dst, *src); + *src = (UINT16)dst; + *out = (UINT16)res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + *src = (UINT16)cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, XADD2, UINT32_TO_PTR(*src)); + } +} + +void +XADD_EdGd(void) +{ + UINT32 *out, *src; + UINT32 op, dst, res, madr; + + PREPART_EA_REG32P(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b20[op]; + dst = *out; + DWORD_ADD(res, dst, *src); + *src = dst; + *out = res; + } else { + CPU_WORKCLOCK(7); + madr = calc_ea_dst(op); + *src = cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, XADD4, UINT32_TO_PTR(*src)); + } +} + +/* + * CMPXCHG + */ +void +CMPXCHG_EbGb(void) +{ + UINT8 *out; + UINT32 op, src, dst, madr, tmp; + UINT8 al; + + PREPART_EA_REG8(op, src); + al = CPU_AL; + if (op >= 0xc0) { + out = reg8_b20[op]; + dst = *out; + if (al == dst) { + *out = (UINT8)src; + } else { + CPU_AL = (UINT8)dst; + } + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, madr); + if (al == dst) { + cpu_vmemorywrite(CPU_INST_SEGREG_INDEX, madr, (UINT8)src); + } else { + CPU_AL = (UINT8)dst; + } + } + BYTE_SUB(tmp, al, dst); +} + +void +CMPXCHG_EwGw(void) +{ + UINT16 *out; + UINT32 op, src, dst, madr, tmp; + UINT16 ax; + + PREPART_EA_REG16(op, src); + ax = CPU_AX; + if (op >= 0xc0) { + out = reg16_b20[op]; + dst = *out; + if (ax == dst) { + *out = (UINT16)src; + } else { + CPU_AX = (UINT16)dst; + } + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + if (ax == dst) { + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)src); + } else { + CPU_AX = (UINT16)dst; + } + } + WORD_SUB(tmp, ax, dst); +} + +void +CMPXCHG_EdGd(void) +{ + UINT32 *out; + UINT32 op, src, dst, madr, tmp; + UINT32 eax; + + PREPART_EA_REG32(op, src); + eax = CPU_EAX; + if (op >= 0xc0) { + out = reg32_b20[op]; + dst = *out; + if (eax == dst) { + *out = src; + } else { + CPU_EAX = dst; + } + } else { + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + if (eax == dst) { + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } else { + CPU_EAX = dst; + } + } + DWORD_SUB(tmp, eax, dst); +} + +void CPUCALL +CMPXCHG8B(UINT32 op) +{ + UINT32 madr, dst_l, dst_h; + + if (op < 0xc0) { + CPU_WORKCLOCK(2); + madr = calc_ea_dst(op); + dst_l = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + dst_h = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 4); + if ((CPU_EDX == dst_h) && (CPU_EAX == dst_l)) { + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, CPU_EBX); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 4, CPU_ECX); + CPU_FLAGL |= Z_FLAG; + } else { + CPU_EDX = dst_h; + CPU_EAX = dst_l; + CPU_FLAGL &= ~Z_FLAG; + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +/* + * PUSH + */ +void PUSH_AX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_AX); } +void PUSH_CX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_CX); } +void PUSH_DX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_DX); } +void PUSH_BX(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_BX); } +void PUSH_SP(void) { CPU_WORKCLOCK(3); SP_PUSH_16(CPU_SP); } +void PUSH_BP(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_BP); } +void PUSH_SI(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_SI); } +void PUSH_DI(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_DI); } + +void PUSH_EAX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EAX); } +void PUSH_ECX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_ECX); } +void PUSH_EDX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EDX); } +void PUSH_EBX(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EBX); } +void PUSH_ESP(void) { CPU_WORKCLOCK(3); ESP_PUSH_32(CPU_ESP); } +void PUSH_EBP(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EBP); } +void PUSH_ESI(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_ESI); } +void PUSH_EDI(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_EDI); } + +void CPUCALL +PUSH_Ew(UINT32 op) +{ + UINT32 dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + PUSH0_16(dst); +} + +void CPUCALL +PUSH_Ed(UINT32 op) +{ + UINT32 dst, madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg32_b20[op]); + } else { + CPU_WORKCLOCK(5); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + } + PUSH0_32(dst); +} + +void +PUSH_Ib(void) +{ + SINT32 val; + + CPU_WORKCLOCK(3); + GET_PCBYTESD(val); + XPUSH0(val); +} + +void +PUSH_Iw(void) +{ + UINT16 val; + + CPU_WORKCLOCK(3); + GET_PCWORD(val); + PUSH0_16(val); +} + +void +PUSH_Id(void) +{ + UINT32 val; + + CPU_WORKCLOCK(3); + GET_PCDWORD(val); + PUSH0_32(val); +} + +void PUSH16_ES(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_ES); } +void PUSH16_CS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_CS); } +void PUSH16_SS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_SS); } +void PUSH16_DS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_DS); } +void PUSH16_FS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_FS); } +void PUSH16_GS(void) { CPU_WORKCLOCK(3); PUSH0_16(CPU_GS); } + +void PUSH32_ES(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_ES); } +void PUSH32_CS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_CS); } +void PUSH32_SS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_SS); } +void PUSH32_DS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_DS); } +void PUSH32_FS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_FS); } +void PUSH32_GS(void) { CPU_WORKCLOCK(3); PUSH0_32(CPU_GS); } + +/* + * POP + */ +void POP_AX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_AX); } +void POP_CX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_CX); } +void POP_DX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_DX); } +void POP_BX(void) { CPU_WORKCLOCK(5); POP0_16(CPU_BX); } +void POP_SP(void) { CPU_WORKCLOCK(5); SP_POP_16(CPU_SP); } +void POP_BP(void) { CPU_WORKCLOCK(5); POP0_16(CPU_BP); } +void POP_SI(void) { CPU_WORKCLOCK(5); POP0_16(CPU_SI); } +void POP_DI(void) { CPU_WORKCLOCK(5); POP0_16(CPU_DI); } + +void POP_EAX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EAX); } +void POP_ECX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_ECX); } +void POP_EDX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EDX); } +void POP_EBX(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EBX); } +void POP_ESP(void) { CPU_WORKCLOCK(5); ESP_POP_32(CPU_ESP); } +void POP_EBP(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EBP); } +void POP_ESI(void) { CPU_WORKCLOCK(5); POP0_32(CPU_ESI); } +void POP_EDI(void) { CPU_WORKCLOCK(5); POP0_32(CPU_EDI); } + +void +POP_Ew(void) +{ + UINT32 op, madr; + UINT16 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_16(src); + GET_PCBYTE(op); + if (op >= 0xc0) { + *(reg16_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, src); + } + CPU_CLEAR_PREV_ESP(); +} + +void CPUCALL +POP_Ew_G5(UINT32 op) +{ + UINT32 madr; + UINT16 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_16(src); + if (op >= 0xc0) { + *(reg16_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, src); + } + CPU_CLEAR_PREV_ESP(); +} + +void +POP_Ed(void) +{ + UINT32 op, madr; + UINT32 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_32(src); + GET_PCBYTE(op); + if (op >= 0xc0) { + *(reg32_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } + CPU_CLEAR_PREV_ESP(); +} + +void CPUCALL +POP_Ed_G5(UINT32 op) +{ + UINT32 src, madr; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_32(src); + if (op >= 0xc0) { + *(reg32_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } + CPU_CLEAR_PREV_ESP(); +} + +void +POP16_ES(void) +{ + UINT16 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_16(src); + LOAD_SEGREG(CPU_ES_INDEX, src); + CPU_CLEAR_PREV_ESP(); +} + +void +POP32_ES(void) +{ + UINT32 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_32(src); + LOAD_SEGREG(CPU_ES_INDEX, (UINT16)src); + CPU_CLEAR_PREV_ESP(); +} + +void +POP16_SS(void) +{ + UINT16 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_16(src); + LOAD_SEGREG(CPU_SS_INDEX, src); + CPU_CLEAR_PREV_ESP(); + exec_1step(); +} + +void +POP32_SS(void) +{ + UINT32 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_32(src); + LOAD_SEGREG(CPU_SS_INDEX, (UINT16)src); + CPU_CLEAR_PREV_ESP(); + exec_1step(); +} + +void +POP16_DS(void) +{ + UINT16 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_16(src); + LOAD_SEGREG(CPU_DS_INDEX, src); + CPU_CLEAR_PREV_ESP(); +} + +void +POP32_DS(void) +{ + UINT32 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_32(src); + LOAD_SEGREG(CPU_DS_INDEX, (UINT16)src); + CPU_CLEAR_PREV_ESP(); +} + +void +POP16_FS(void) +{ + UINT16 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_16(src); + LOAD_SEGREG(CPU_FS_INDEX, src); + CPU_CLEAR_PREV_ESP(); +} + +void +POP32_FS(void) +{ + UINT32 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_32(src); + LOAD_SEGREG(CPU_FS_INDEX, (UINT16)src); + CPU_CLEAR_PREV_ESP(); +} + +void +POP16_GS(void) +{ + UINT16 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_16(src); + LOAD_SEGREG(CPU_GS_INDEX, src); + CPU_CLEAR_PREV_ESP(); +} + +void +POP32_GS(void) +{ + UINT32 src; + + CPU_WORKCLOCK(5); + + CPU_SET_PREV_ESP(); + POP0_32(src); + LOAD_SEGREG(CPU_GS_INDEX, (UINT16)src); + CPU_CLEAR_PREV_ESP(); +} + +/* + * PUSHA/POPA + */ +void +PUSHA(void) +{ + UINT16 sp = CPU_SP; + + CPU_WORKCLOCK(17); + CPU_SET_PREV_ESP(); + if (!CPU_STAT_SS32) { + REGPUSH0(CPU_AX); + REGPUSH0(CPU_CX); + REGPUSH0(CPU_DX); + REGPUSH0(CPU_BX); + REGPUSH0(sp); + REGPUSH0(CPU_BP); + REGPUSH0(CPU_SI); + REGPUSH0(CPU_DI); + } else { + REGPUSH0_16_32(CPU_AX); + REGPUSH0_16_32(CPU_CX); + REGPUSH0_16_32(CPU_DX); + REGPUSH0_16_32(CPU_BX); + REGPUSH0_16_32(sp); + REGPUSH0_16_32(CPU_BP); + REGPUSH0_16_32(CPU_SI); + REGPUSH0_16_32(CPU_DI); + } + CPU_CLEAR_PREV_ESP(); +} + +void +PUSHAD(void) +{ + UINT32 esp = CPU_ESP; + + CPU_WORKCLOCK(17); + CPU_SET_PREV_ESP(); + if (!CPU_STAT_SS32) { + REGPUSH0_32_16(CPU_EAX); + REGPUSH0_32_16(CPU_ECX); + REGPUSH0_32_16(CPU_EDX); + REGPUSH0_32_16(CPU_EBX); + REGPUSH0_32_16(esp); + REGPUSH0_32_16(CPU_EBP); + REGPUSH0_32_16(CPU_ESI); + REGPUSH0_32_16(CPU_EDI); + } else { + REGPUSH0_32(CPU_EAX); + REGPUSH0_32(CPU_ECX); + REGPUSH0_32(CPU_EDX); + REGPUSH0_32(CPU_EBX); + REGPUSH0_32(esp); + REGPUSH0_32(CPU_EBP); + REGPUSH0_32(CPU_ESI); + REGPUSH0_32(CPU_EDI); + } + CPU_CLEAR_PREV_ESP(); +} + +void +POPA(void) +{ + UINT16 ax, cx, dx, bx, bp, si, di; + + CPU_WORKCLOCK(19); + CPU_SET_PREV_ESP(); + if (!CPU_STAT_SS32) { + REGPOP0(di); + REGPOP0(si); + REGPOP0(bp); + CPU_SP += 2; + REGPOP0(bx); + REGPOP0(dx); + REGPOP0(cx); + REGPOP0(ax); + } else { + REGPOP0_16_32(di); + REGPOP0_16_32(si); + REGPOP0_16_32(bp); + CPU_ESP += 2; + REGPOP0_16_32(bx); + REGPOP0_16_32(dx); + REGPOP0_16_32(cx); + REGPOP0_16_32(ax); + } + CPU_CLEAR_PREV_ESP(); + + CPU_AX = ax; + CPU_CX = cx; + CPU_DX = dx; + CPU_BX = bx; + CPU_BP = bp; + CPU_SI = si; + CPU_DI = di; +} + +void +POPAD(void) +{ + UINT32 eax, ecx, edx, ebx, ebp, esi, edi; + + CPU_WORKCLOCK(19); + CPU_SET_PREV_ESP(); + if (!CPU_STAT_SS32) { + REGPOP0_32_16(edi); + REGPOP0_32_16(esi); + REGPOP0_32_16(ebp); + CPU_SP += 4; + REGPOP0_32_16(ebx); + REGPOP0_32_16(edx); + REGPOP0_32_16(ecx); + REGPOP0_32_16(eax); + } else { + REGPOP0_32(edi); + REGPOP0_32(esi); + REGPOP0_32(ebp); + CPU_ESP += 4; + REGPOP0_32(ebx); + REGPOP0_32(edx); + REGPOP0_32(ecx); + REGPOP0_32(eax); + } + CPU_CLEAR_PREV_ESP(); + + CPU_EAX = eax; + CPU_ECX = ecx; + CPU_EDX = edx; + CPU_EBX = ebx; + CPU_EBP = ebp; + CPU_ESI = esi; + CPU_EDI = edi; +} + +/* + * in port + */ +void +IN_ALDX(void) +{ + + CPU_WORKCLOCK(12); + CPU_AL = cpu_in(CPU_DX); +} + +void +IN_AXDX(void) +{ + + CPU_WORKCLOCK(12); + CPU_AX = cpu_in_w(CPU_DX); +} + +void +IN_EAXDX(void) +{ + + CPU_WORKCLOCK(12); + CPU_EAX = cpu_in_d(CPU_DX); +} + +void +IN_ALIb(void) +{ + UINT port; + + CPU_WORKCLOCK(12); + GET_PCBYTE(port); + CPU_AL = cpu_in(port); +} + +void +IN_AXIb(void) +{ + UINT port; + + CPU_WORKCLOCK(12); + GET_PCBYTE(port); + CPU_AX = cpu_in_w(port); +} + +void +IN_EAXIb(void) +{ + UINT port; + + CPU_WORKCLOCK(12); + GET_PCBYTE(port); + CPU_EAX = cpu_in_d(port); +} + +/* + * out port + */ +void +OUT_DXAL(void) +{ + + CPU_WORKCLOCK(10); + cpu_out(CPU_DX, CPU_AL); +} + +void +OUT_DXAX(void) +{ + + CPU_WORKCLOCK(10); + cpu_out_w(CPU_DX, CPU_AX); +} + +void +OUT_DXEAX(void) +{ + + CPU_WORKCLOCK(10); + cpu_out_d(CPU_DX, CPU_EAX); +} + +void +OUT_IbAL(void) +{ + UINT port; + + CPU_WORKCLOCK(10); + GET_PCBYTE(port); + cpu_out(port, CPU_AL); +} + +void +OUT_IbAX(void) +{ + UINT port; + + CPU_WORKCLOCK(10); + GET_PCBYTE(port); + cpu_out_w(port, CPU_AX); +} + +void +OUT_IbEAX(void) +{ + UINT port; + + CPU_WORKCLOCK(10); + GET_PCBYTE(port); + cpu_out_d(port, CPU_EAX); +} + +/* + * convert + */ +void +CWD(void) +{ + + CPU_WORKCLOCK(2); + if (CPU_AX & 0x8000) { + CPU_DX = 0xffff; + } else { + CPU_DX = 0; + } +} + +void +CDQ(void) +{ + + CPU_WORKCLOCK(2); + if (CPU_EAX & 0x80000000) { + CPU_EDX = 0xffffffff; + } else { + CPU_EDX = 0; + } +} + +void +CBW(void) +{ + UINT16 tmp; + + CPU_WORKCLOCK(2); + tmp = __CBW(CPU_AL); + CPU_AX = tmp; +} + +void +CWDE(void) +{ + UINT32 tmp; + + CPU_WORKCLOCK(2); + tmp = __CWDE(CPU_AX); + CPU_EAX = tmp; +} + +/* + * MOVSx + */ +void +MOVSX_GwEb(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA8(op, src, out, 2, 5); + *out = __CBW(src); +} + +void +MOVSX_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + *out = (UINT16)src; +} + +void +MOVSX_GdEb(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA8(op, src, out, 2, 5); + *out = __CBD(src); +} + +void +MOVSX_GdEw(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA16(op, src, out, 2, 5); + *out = __CWDE(src); +} + +/* + * MOVZx + */ +void +MOVZX_GwEb(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA8(op, src, out, 2, 5); + *out = (UINT8)src; +} + +void +MOVZX_GwEw(void) +{ + UINT16 *out; + UINT32 op, src; + + PREPART_REG16_EA(op, src, out, 2, 5); + *out = (UINT16)src; +} + +void +MOVZX_GdEb(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA8(op, src, out, 2, 5); + *out = (UINT8)src; +} + +void +MOVZX_GdEw(void) +{ + UINT32 *out; + UINT32 op, src; + + PREPART_REG32_EA16(op, src, out, 2, 5); + *out = (UINT16)src; +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/data_trans.h b/source/src/vm/np21/i386c/ia32/instructions/data_trans.h new file mode 100644 index 000000000..009d3b0bf --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/data_trans.h @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_DATA_TRANS_H__ +#define IA32_CPU_INSTRUCTION_DATA_TRANS_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * MOV + */ +void MOV_EbGb(void); +void MOV_EwGw(void); +void MOV_EdGd(void); +void MOV_GbEb(void); +void MOV_GwEw(void); +void MOV_GdEd(void); +void MOV_EwSw(void); +void MOV_EdSw(void); +void MOV_SwEw(void); +void MOV_ALOb(void); +void MOV_AXOw(void); +void MOV_EAXOd(void); +void MOV_ObAL(void); +void MOV_OwAX(void); +void MOV_OdEAX(void); +void MOV_EbIb(void); +void MOV_EwIw(void); +void MOV_EdId(void); +void MOV_ALIb(void); +void MOV_CLIb(void); +void MOV_DLIb(void); +void MOV_BLIb(void); +void MOV_AHIb(void); +void MOV_CHIb(void); +void MOV_DHIb(void); +void MOV_BHIb(void); +void MOV_AXIw(void); +void MOV_CXIw(void); +void MOV_DXIw(void); +void MOV_BXIw(void); +void MOV_SPIw(void); +void MOV_BPIw(void); +void MOV_SIIw(void); +void MOV_DIIw(void); +void MOV_EAXId(void); +void MOV_ECXId(void); +void MOV_EDXId(void); +void MOV_EBXId(void); +void MOV_ESPId(void); +void MOV_EBPId(void); +void MOV_ESIId(void); +void MOV_EDIId(void); + +/* + * CMOVcc + */ +void CMOVO_GwEw(void); +void CMOVO_GdEd(void); +void CMOVNO_GwEw(void); +void CMOVNO_GdEd(void); +void CMOVC_GwEw(void); +void CMOVC_GdEd(void); +void CMOVNC_GwEw(void); +void CMOVNC_GdEd(void); +void CMOVZ_GwEw(void); +void CMOVZ_GdEd(void); +void CMOVNZ_GwEw(void); +void CMOVNZ_GdEd(void); +void CMOVA_GwEw(void); +void CMOVA_GdEd(void); +void CMOVNA_GwEw(void); +void CMOVNA_GdEd(void); +void CMOVS_GwEw(void); +void CMOVS_GdEd(void); +void CMOVNS_GwEw(void); +void CMOVNS_GdEd(void); +void CMOVP_GwEw(void); +void CMOVP_GdEd(void); +void CMOVNP_GwEw(void); +void CMOVNP_GdEd(void); +void CMOVL_GwEw(void); +void CMOVL_GdEd(void); +void CMOVNL_GwEw(void); +void CMOVNL_GdEd(void); +void CMOVLE_GwEw(void); +void CMOVLE_GdEd(void); +void CMOVNLE_GwEw(void); +void CMOVNLE_GdEd(void); + +/* + * XCHG + */ +void XCHG_EbGb(void); +void XCHG_EwGw(void); +void XCHG_EdGd(void); +void XCHG_CXAX(void); +void XCHG_DXAX(void); +void XCHG_BXAX(void); +void XCHG_SPAX(void); +void XCHG_BPAX(void); +void XCHG_SIAX(void); +void XCHG_DIAX(void); +void XCHG_ECXEAX(void); +void XCHG_EDXEAX(void); +void XCHG_EBXEAX(void); +void XCHG_ESPEAX(void); +void XCHG_EBPEAX(void); +void XCHG_ESIEAX(void); +void XCHG_EDIEAX(void); + +/* + * BSWAP + */ +void BSWAP_EAX(void); +void BSWAP_ECX(void); +void BSWAP_EDX(void); +void BSWAP_EBX(void); +void BSWAP_ESP(void); +void BSWAP_EBP(void); +void BSWAP_ESI(void); +void BSWAP_EDI(void); + +/* + * XADD + */ +void XADD_EbGb(void); +void XADD_EwGw(void); +void XADD_EdGd(void); + +/* + * CMPXCHG + */ +void CMPXCHG_EbGb(void); +void CMPXCHG_EwGw(void); +void CMPXCHG_EdGd(void); +void CPUCALL CMPXCHG8B(UINT32); + +/* + * PUSH + */ +void PUSH_AX(void); +void PUSH_CX(void); +void PUSH_DX(void); +void PUSH_BX(void); +void PUSH_SP(void); +void PUSH_BP(void); +void PUSH_SI(void); +void PUSH_DI(void); +void PUSH_EAX(void); +void PUSH_ECX(void); +void PUSH_EDX(void); +void PUSH_EBX(void); +void PUSH_ESP(void); +void PUSH_EBP(void); +void PUSH_ESI(void); +void PUSH_EDI(void); +void PUSH_Ib(void); +void PUSH_Iw(void); +void PUSH_Id(void); +void PUSH16_ES(void); +void PUSH16_CS(void); +void PUSH16_SS(void); +void PUSH16_DS(void); +void PUSH16_FS(void); +void PUSH16_GS(void); +void PUSH32_ES(void); +void PUSH32_CS(void); +void PUSH32_SS(void); +void PUSH32_DS(void); +void PUSH32_FS(void); +void PUSH32_GS(void); + +void CPUCALL PUSH_Ew(UINT32); +void CPUCALL PUSH_Ed(UINT32); + +/* + * POP + */ +void POP_AX(void); +void POP_CX(void); +void POP_DX(void); +void POP_BX(void); +void POP_SP(void); +void POP_BP(void); +void POP_SI(void); +void POP_DI(void); +void POP_EAX(void); +void POP_ECX(void); +void POP_EDX(void); +void POP_EBX(void); +void POP_ESP(void); +void POP_EBP(void); +void POP_ESI(void); +void POP_EDI(void); +void POP_Ew(void); +void POP_Ed(void); +void POP16_ES(void); +void POP32_ES(void); +void POP16_SS(void); +void POP32_SS(void); +void POP16_DS(void); +void POP32_DS(void); +void POP16_FS(void); +void POP32_FS(void); +void POP16_GS(void); +void POP32_GS(void); + +void CPUCALL POP_Ew_G5(UINT32); +void CPUCALL POP_Ed_G5(UINT32); + +/* + * PUSHA/POPA + */ +void PUSHA(void); +void PUSHAD(void); +void POPA(void); +void POPAD(void); + +/* + * in/out + */ +void IN_ALDX(void); +void IN_AXDX(void); +void IN_EAXDX(void); +void IN_ALIb(void); +void IN_AXIb(void); +void IN_EAXIb(void); +void OUT_DXAL(void); +void OUT_DXAX(void); +void OUT_DXEAX(void); +void OUT_IbAL(void); +void OUT_IbAX(void); +void OUT_IbEAX(void); + +/* + * convert + */ +void CWD(void); +void CDQ(void); +void CBW(void); +void CWDE(void); + +/* + * MOVSx/MOVZx + */ +void MOVSX_GwEb(void); +void MOVSX_GwEw(void); +void MOVSX_GdEb(void); +void MOVSX_GdEw(void); +void MOVZX_GwEb(void); +void MOVZX_GwEw(void); +void MOVZX_GdEb(void); +void MOVZX_GdEw(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_DATA_TRANS_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/dec_arith.cpp b/source/src/vm/np21/i386c/ia32/instructions/dec_arith.cpp new file mode 100644 index 000000000..e5102ea69 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/dec_arith.cpp @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "dec_arith.h" + + +/* + * decimal arithmetic + */ +void +DAA(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + UINT8 __s = CPU_AL; + UINT8 __r = __s; + UINT8 __R; + UINT8 __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_FLAGL |= A_FLAG; + CPU_FLAGL |= (((UINT16)CPU_AL + 6) >> 8) & 1; /* C_FLAG */ + CPU_AL += 6; + } + if ((CPU_FLAGL & C_FLAG) || (CPU_AL & 0xf0) > 0x90) { + CPU_FLAGL |= C_FLAG; + CPU_AL += 0x60; + } + CPU_FLAGL &= A_FLAG | C_FLAG; + CPU_FLAGL |= szpcflag[CPU_AL] & (S_FLAG | Z_FLAG | P_FLAG); + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %3, %%ah\n\t" + "sahf\n\t" + "movb %2, %%al\n\t" + "daa\n\t" + "movb %%al, %0\n\t" + "lahf\n\t" + "movb %%ah, %1\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0)) { + ia32_warning("XC_DAA: __s = %02x", __s); + ia32_warning("XC_DAA: __R = %02x, __r = %02x", __R, __r); + ia32_warning("XC_DAA: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); + ia32_warning("XC_DAA: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); + } +#endif +} + +void +DAS(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + UINT8 __s = CPU_AL; + UINT8 __r = __s; + UINT8 __R; + UINT8 __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_FLAGL |= A_FLAG; + CPU_FLAGL |= (((UINT16)CPU_AL - 6) >> 8) & 1; /* C_FLAG */ + CPU_AL -= 6; + } + if ((CPU_FLAGL & C_FLAG) || CPU_AL > 0x9f) { + CPU_FLAGL |= C_FLAG; + CPU_AL -= 0x60; + } + CPU_FLAGL &= A_FLAG | C_FLAG; + CPU_FLAGL |= szpcflag[CPU_AL] & (S_FLAG | Z_FLAG | P_FLAG); + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %3, %%ah\n\t" + "sahf\n\t" + "movb %2, %%al\n\t" + "das\n\t" + "movb %%al, %0\n\t" + "lahf\n\t" + "movb %%ah, %1\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (((__f ^ CPU_FLAGL) & SZAPC_FLAG) != 0)) { + ia32_warning("XC_DAS: __s = %02x", __s); + ia32_warning("XC_DAS: __R = %02x, __r = %02x", __R, __r); + ia32_warning("XC_DAS: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, SZAPC_FLAG); + ia32_warning("XC_DAS: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(((__f ^ CPU_FLAGL) & SZAPC_FLAG) == 0); + } +#endif +} + +void +AAA(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + UINT8 __s = CPU_AL; + UINT8 __s1 = CPU_AH; + UINT8 __r = __s; + UINT8 __r1; + UINT8 __R; + UINT8 __R1; + UINT8 __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_AL += 6; + CPU_AH++; + CPU_FLAGL |= (A_FLAG | C_FLAG); + } else { + CPU_FLAGL &= ~(A_FLAG | C_FLAG); + } + CPU_AL &= 0x0f; + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + __R1 = CPU_AH; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %4, %%ah\n\t" + "sahf\n\t" + "movb %3, %%al\n\t" + "aaa\n\t" + "movb %%al, %0\n\t" + "movb %%ah, %1\n\t" + "lahf\n\t" + "movb %%ah, %2\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__r1), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (__R1 != __r1) || + (((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) != 0)) { + ia32_warning("XC_AAA: __s = %02x, __s1 = %02x", __s, __s1); + ia32_warning("XC_AAA: __R = %02x, __R1 = %02x", __R, __R1); + ia32_warning("XC_AAA: __r = %02x, __r1 = %02x", __r, __r1); + ia32_warning("XC_AAA: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, (A_FLAG|C_FLAG)); + ia32_warning("XC_AAA: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(__R1 == __r1); + __ASSERT(((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) == 0); + } +#endif +} + +void +AAS(void) +{ +#if defined(IA32_CPU_ENABLE_XC) + UINT8 __s = CPU_AL; + UINT8 __s1 = CPU_AH; + UINT8 __r = __s; + UINT8 __r1; + UINT8 __R; + UINT8 __R1; + UINT8 __f; + XC_STORE_FLAGL(); +#endif + + CPU_WORKCLOCK(3); + if ((CPU_FLAGL & A_FLAG) || (CPU_AL & 0x0f) > 9) { + CPU_AL -= 6; + CPU_AH--; + CPU_FLAGL |= (A_FLAG | C_FLAG); + } else { + CPU_FLAGL &= ~(A_FLAG | C_FLAG); + } + CPU_AL &= 0x0f; + +#if defined(IA32_CPU_ENABLE_XC) + __R = CPU_AL; + __R1 = CPU_AH; + + __asm__ __volatile__( + "pushf\n\t" + "pushl %%eax\n\t" + "movb %4, %%ah\n\t" + "sahf\n\t" + "movb %3, %%al\n\t" + "aas\n\t" + "movb %%al, %0\n\t" + "movb %%ah, %1\n\t" + "lahf\n\t" + "movb %%ah, %2\n\t" + "popl %%eax\n\t" + "popf\n\t" + : "=m" (__r), "=m" (__r1), "=m" (__f) + : "0" (__r), "m" (__xc_flagl) + : "eax"); + if ((__R != __r) || + (__R1 != __r1) || + (((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) != 0)) { + ia32_warning("XC_AAS: __s = %02x, __s1 = %02x", __s, __s1); + ia32_warning("XC_AAS: __R = %02x, __R1 = %02x", __R, __R1); + ia32_warning("XC_AAS: __r = %02x, __r1 = %02x", __r, __r1); + ia32_warning("XC_AAS: CPU_FLAGL = %02x, __f = %02x, " + "mask = %02x", CPU_FLAGL, __f, (A_FLAG|C_FLAG)); + ia32_warning("XC_AAS: __xc_flagl = %02x", __xc_flagl); + __ASSERT(__R == __r); + __ASSERT(__R1 == __r1); + __ASSERT(((__f ^ CPU_FLAGL) & (A_FLAG|C_FLAG)) == 0); + } +#endif +} + +void +AAM(void) +{ + UINT8 base; + UINT8 al; + + CPU_WORKCLOCK(16); + GET_PCBYTE(base); + if (base != 0) { + al = CPU_AL; + CPU_AH = al / base; + CPU_AL = al % base; + CPU_FLAGL = szpcflag[CPU_AL]; + return; + } + EXCEPTION(DE_EXCEPTION, 0); +} + +void +AAD(void) +{ + UINT32 base; + + CPU_WORKCLOCK(14); + GET_PCBYTE(base); + CPU_AL += (UINT8)(CPU_AH * base); + CPU_AH = 0; + CPU_FLAGL &= ~(S_FLAG | Z_FLAG | P_FLAG); + CPU_FLAGL |= szpcflag[CPU_AL]; +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/dec_arith.h b/source/src/vm/np21/i386c/ia32/instructions/dec_arith.h new file mode 100644 index 000000000..c1aa26668 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/dec_arith.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_DEC_ARITH_H__ +#define IA32_CPU_INSTRUCTION_DEC_ARITH_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * decimal arithmetic + */ +void DAA(void); +void DAS(void); +void AAA(void); +void AAS(void); +void AAM(void); +void AAD(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_DEC_ARITH_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/flag_ctrl.cpp b/source/src/vm/np21/i386c/ia32/instructions/flag_ctrl.cpp new file mode 100644 index 000000000..e7d3f476a --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/flag_ctrl.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "flag_ctrl.h" + + +/* + * flag contol instructions + */ +void +STC(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL |= C_FLAG; +} + +void +CLC(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL &= ~C_FLAG; +} + +void +CMC(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL ^= C_FLAG; +} + +void +CLD(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAG &= ~D_FLAG; +} + +void +STD(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAG |= D_FLAG; +} + +void +LAHF(void) +{ + + CPU_WORKCLOCK(2); + CPU_AH = (CPU_FLAGL & SZAPC_FLAG) | 0x2; /* SZ0A0P1C */ +} + +void +SAHF(void) +{ + + CPU_WORKCLOCK(2); + CPU_FLAGL = (CPU_AH & SZAPC_FLAG) | 0x2; /* SZ0A0P1C */ +} + +/* + * PUSHF/POPF + */ +void +PUSHF_Fw(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { + UINT16 flags = REAL_FLAGREG; + flags = (flags & ALL_FLAG) | 2; + PUSH0_16(flags); + return; + } + /* VM86 && IOPL != 3 */ + EXCEPTION(GP_EXCEPTION, 0); +} + +void +PUSHFD_Fd(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_STAT_PM || !CPU_STAT_VM86 || (CPU_STAT_IOPL == CPU_IOPL3)) { + UINT32 flags = REAL_EFLAGREG & ~(RF_FLAG|VM_FLAG); + flags = (flags & ALL_EFLAG) | 2; + PUSH0_32(flags); + return; + } + /* VM86 && IOPL != 3 */ +#if defined(USE_VME) + if(CPU_CR4 & CPU_CR4_VME){ + if(CPU_EFLAG & VIP_FLAG){ + EXCEPTION(GP_EXCEPTION, 0); + }else{ + UINT32 flags = REAL_EFLAGREG & ~(RF_FLAG|VM_FLAG); + flags = (flags & ALL_EFLAG) | 2; + flags = (flags & ~I_FLAG) | ((flags & VIF_FLAG) >> 10); // VIF → IFにコピー + flags |= IOPL_FLAG; // IOPL == 3 の振りをする + PUSH0_32(flags); + return; + } + }else{ + EXCEPTION(GP_EXCEPTION, 0); + } +#else + EXCEPTION(GP_EXCEPTION, 0); +#endif +} + +void +POPF_Fw(void) +{ + UINT16 flags, mask; + + CPU_WORKCLOCK(3); + CPU_SET_PREV_ESP(); + if (!CPU_STAT_PM) { + /* Real Mode */ + POP0_16(flags); + mask = I_FLAG|IOPL_FLAG; + } else if (!CPU_STAT_VM86) { + /* Protected Mode */ + POP0_16(flags); + if (CPU_STAT_CPL == 0) { + mask = I_FLAG|IOPL_FLAG; + } else if (CPU_STAT_CPL <= CPU_STAT_IOPL) { + mask = I_FLAG; + } else { + mask = 0; + } + } else if (CPU_STAT_IOPL == CPU_IOPL3) { + /* Virtual-8086 Mode, IOPL == 3 */ + POP0_16(flags); + mask = I_FLAG; + } else { + EXCEPTION(GP_EXCEPTION, 0); + flags = 0; + mask = 0; + /* compiler happy */ + } + set_eflags(flags, mask); + CPU_CLEAR_PREV_ESP(); + IRQCHECKTERM(); +} + +void +POPFD_Fd(void) +{ + UINT32 flags, mask; + + CPU_WORKCLOCK(3); + CPU_SET_PREV_ESP(); + if (!CPU_STAT_PM) { + /* Real Mode */ + POP0_32(flags); + flags &= ~(RF_FLAG|VIF_FLAG|VIP_FLAG); + mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; + } else if (!CPU_STAT_VM86) { + /* Protected Mode */ + POP0_32(flags); + flags &= ~RF_FLAG; + if (CPU_STAT_CPL == 0) { + flags &= ~(VIP_FLAG|VIF_FLAG); + mask = I_FLAG|IOPL_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; + } else if (CPU_STAT_CPL <= CPU_STAT_IOPL) { + flags &= ~(VIP_FLAG|VIF_FLAG); + mask = I_FLAG|RF_FLAG|VIF_FLAG|VIP_FLAG; + } else { + mask = RF_FLAG; + } + } else if (CPU_STAT_IOPL == CPU_IOPL3) { + /* Virtual-8086 Mode, IOPL == 3 */ + POP0_32(flags); + mask = I_FLAG; + } else { + /* Virtual-8086 Mode, IOPL != 3 */ +#if defined(USE_VME) + if(CPU_CR4 & CPU_CR4_VME){ + if((CPU_EFLAG & VIP_FLAG) || (CPU_EFLAG & T_FLAG)){ + EXCEPTION(GP_EXCEPTION, 0); + flags = 0; + mask = 0; + }else{ + POP0_32(flags); + flags = (flags & ~VIF_FLAG) | ((flags & I_FLAG) << 10); // IF → VIFにコピー + mask = I_FLAG | IOPL_FLAG; // IF, IOPLは変更させない + } + }else{ + EXCEPTION(GP_EXCEPTION, 0); + flags = 0; + mask = 0; + } +#else + EXCEPTION(GP_EXCEPTION, 0); + flags = 0; + mask = 0; + /* compiler happy */ +#endif + } + set_eflags(flags, mask); + CPU_CLEAR_PREV_ESP(); + IRQCHECKTERM(); +} + +void +STI(void) +{ + + CPU_WORKCLOCK(2); + if (CPU_STAT_PM) { + if (!CPU_STAT_VM86) { + if (CPU_STAT_CPL > CPU_STAT_IOPL) { +#if defined(USE_VME) + if((CPU_CR4 & CPU_CR4_PVI) && CPU_STAT_CPL==3){ + if(CPU_EFLAG & VIP_FLAG){ + EXCEPTION(GP_EXCEPTION, 0); + }else{ + CPU_EFLAG |= VIF_FLAG; + return; + } + }else{ + EXCEPTION(GP_EXCEPTION, 0); + } +#else + EXCEPTION(GP_EXCEPTION, 0); +#endif + } + } else { + if (CPU_STAT_IOPL < 3) { +#if defined(USE_VME) + if(CPU_CR4 & CPU_CR4_VME){ + if(CPU_EFLAG & VIP_FLAG){ + EXCEPTION(GP_EXCEPTION, 0); + }else{ + CPU_EFLAG |= VIF_FLAG; + return; + } + }else{ + EXCEPTION(GP_EXCEPTION, 0); + } +#else + EXCEPTION(GP_EXCEPTION, 0); +#endif + } + } + } + CPU_FLAG |= I_FLAG; + CPU_TRAP = (CPU_FLAG & (I_FLAG|T_FLAG)) == (I_FLAG|T_FLAG); + exec_1step(); + IRQCHECKTERM(); +} + +void +CLI(void) +{ + + CPU_WORKCLOCK(2); + if (CPU_STAT_PM) { + if (!CPU_STAT_VM86) { + if (CPU_STAT_CPL > CPU_STAT_IOPL) { +#if defined(USE_VME) + if((CPU_CR4 & CPU_CR4_PVI) && CPU_STAT_CPL==3){ + CPU_EFLAG &= ~VIF_FLAG; + return; + }else{ + EXCEPTION(GP_EXCEPTION, 0); + } +#else + EXCEPTION(GP_EXCEPTION, 0); +#endif + } + } else { + if (CPU_STAT_IOPL < 3) { +#if defined(USE_VME) + if(CPU_CR4 & CPU_CR4_VME){ + CPU_EFLAG &= ~VIF_FLAG; + return; + }else{ + EXCEPTION(GP_EXCEPTION, 0); + } +#else + EXCEPTION(GP_EXCEPTION, 0); +#endif + } + } + } + CPU_FLAG &= ~I_FLAG; + CPU_TRAP = 0; +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/flag_ctrl.h b/source/src/vm/np21/i386c/ia32/instructions/flag_ctrl.h new file mode 100644 index 000000000..2b769f11d --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/flag_ctrl.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_FLAG_CTRL_H__ +#define IA32_CPU_INSTRUCTION_FLAG_CTRL_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void STC(void); +void CLC(void); +void CMC(void); +void CLD(void); +void STD(void); +void LAHF(void); +void SAHF(void); +void PUSHF_Fw(void); +void PUSHFD_Fd(void); +void POPF_Fw(void); +void POPFD_Fd(void); +void STI(void); +void CLI(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_FLAG_CTRL_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu.cpp b/source/src/vm/np21/i386c/ia32/instructions/fpu.cpp new file mode 100644 index 000000000..9c2a32161 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2012 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//include "compiler.h" +//#include "pccore.h" +#include "../cpu.h" +#include "../ia32.mcr" +#include "../inst_table.h" + +#include "fpu/fp.h" +#include "fpu/fpumem.h" + +#if defined(USE_FPU) && !defined(SUPPORT_FPU_DOSBOX) && !defined(SUPPORT_FPU_DOSBOX2) && !defined(SUPPORT_FPU_SOFTFLOAT) +#error No FPU detected. Please define SUPPORT_FPU_DOSBOX, SUPPORT_FPU_DOSBOX2 or SUPPORT_FPU_SOFTFLOAT. +#endif + +void +fpu_initialize(void) +{ +#if defined(USE_FPU) + if(i386cpuid.cpu_feature & CPU_FEATURE_FPU){ + switch(i386cpuid.fpu_type){ +#if defined(SUPPORT_FPU_DOSBOX) + case FPU_TYPE_DOSBOX: + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = DB_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = DB_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = DB_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = DB_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = DB_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = DB_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = DB_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = DB_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = DB_ESC7; + DB_FPU_FINIT(); + break; +#endif +#if defined(SUPPORT_FPU_DOSBOX2) + case FPU_TYPE_DOSBOX2: + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = DB2_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = DB2_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = DB2_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = DB2_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = DB2_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = DB2_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = DB2_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = DB2_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = DB2_ESC7; + DB2_FPU_FINIT(); + break; +#endif +#if defined(SUPPORT_FPU_SOFTFLOAT) + case FPU_TYPE_SOFTFLOAT: + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = SF_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = SF_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = SF_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = SF_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = SF_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = SF_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = SF_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = SF_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = SF_ESC7; + SF_FPU_FINIT(); + break; +#endif + default: +#if defined(SUPPORT_FPU_SOFTFLOAT) + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = SF_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = SF_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = SF_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = SF_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = SF_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = SF_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = SF_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = SF_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = SF_ESC7; + SF_FPU_FINIT(); +#elif defined(SUPPORT_FPU_DOSBOX) + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = DB_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = DB_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = DB_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = DB_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = DB_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = DB_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = DB_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = DB_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = DB_ESC7; + DB_FPU_FINIT(); +#elif defined(SUPPORT_FPU_DOSBOX2) + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = DB2_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = DB2_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = DB2_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = DB2_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = DB2_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = DB2_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = DB2_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = DB2_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = DB2_ESC7; + DB2_FPU_FINIT(); +#else + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = NOFPU_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = NOFPU_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = NOFPU_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = NOFPU_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = NOFPU_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = NOFPU_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = NOFPU_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = NOFPU_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = NOFPU_ESC7; + NOFPU_FPU_FINIT(); +#endif + break; + } + }else{ +#endif + insttable_2byte[0][0xae] = insttable_2byte[1][0xae] = NOFPU_FPU_FXSAVERSTOR; + insttable_1byte[0][0xd8] = insttable_1byte[1][0xd8] = NOFPU_ESC0; + insttable_1byte[0][0xd9] = insttable_1byte[1][0xd9] = NOFPU_ESC1; + insttable_1byte[0][0xda] = insttable_1byte[1][0xda] = NOFPU_ESC2; + insttable_1byte[0][0xdb] = insttable_1byte[1][0xdb] = NOFPU_ESC3; + insttable_1byte[0][0xdc] = insttable_1byte[1][0xdc] = NOFPU_ESC4; + insttable_1byte[0][0xdd] = insttable_1byte[1][0xdd] = NOFPU_ESC5; + insttable_1byte[0][0xde] = insttable_1byte[1][0xde] = NOFPU_ESC6; + insttable_1byte[0][0xdf] = insttable_1byte[1][0xdf] = NOFPU_ESC7; + NOFPU_FPU_FINIT(); +#if defined(USE_FPU) + } +#endif +} + +char * +fpu_reg2str(void) +{ + return NULL; +} + +/* + * FPU memory access function + */ +#if defined(USE_FPU) +UINT8 MEMCALL +fpu_memoryread_b(UINT32 address) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + return cpu_vmemoryread_b(seg, address); +} + +UINT16 MEMCALL +fpu_memoryread_w(UINT32 address) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + return cpu_vmemoryread_w(seg, address); +} + +UINT32 MEMCALL +fpu_memoryread_d(UINT32 address) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + return cpu_vmemoryread_d(seg, address); +} + +UINT64 MEMCALL +fpu_memoryread_q(UINT32 address) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + return cpu_vmemoryread_q(seg, address); +} + +REG80 MEMCALL +fpu_memoryread_f(UINT32 address) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + return cpu_vmemoryread_f(seg, address); +} + +void MEMCALL +fpu_memorywrite_b(UINT32 address, UINT8 value) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + cpu_vmemorywrite_b(seg, address, value); +} + +void MEMCALL +fpu_memorywrite_w(UINT32 address, UINT16 value) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + cpu_vmemorywrite_w(seg, address, value); +} + +void MEMCALL +fpu_memorywrite_d(UINT32 address, UINT32 value) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + cpu_vmemorywrite_d(seg, address, value); +} + +void MEMCALL +fpu_memorywrite_q(UINT32 address, UINT64 value) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + cpu_vmemorywrite_q(seg, address, value); +} + +void MEMCALL +fpu_memorywrite_f(UINT32 address, REG80 *value) +{ + UINT16 seg; + + FPU_DATAPTR_SEG = seg = CPU_INST_SEGREG_INDEX; + FPU_DATAPTR_OFFSET = address; + cpu_vmemorywrite_f(seg, address, value); +} +#endif + +void +FPU_FWAIT(void) +{ +#if defined(USE_FPU) + // FPUなしなら何もしない + if(!(i386cpuid.cpu_feature & CPU_FEATURE_FPU)){ + return; + } + // タスクスイッチまたはMPでNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_MP|CPU_CR0_TS))==(CPU_CR0_MP|CPU_CR0_TS)) { + EXCEPTION(NM_EXCEPTION, 0); + } + + // Check exception + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & 0x3F){ + EXCEPTION(MF_EXCEPTION, 0); + } +#endif +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/fp.h b/source/src/vm/np21/i386c/ia32/instructions/fpu/fp.h new file mode 100644 index 000000000..4d1f69652 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/fp.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_FPU_FP_H__ +#define IA32_CPU_INSTRUCTION_FPU_FP_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void fpu_initialize(void); + +void FPU_FWAIT(void); + +#if defined(USE_FPU) +#if defined(SUPPORT_FPU_DOSBOX) +void DB_FPU_FINIT(void); +void DB_FPU_FXSAVERSTOR(void); +void DB_ESC0(void); +void DB_ESC1(void); +void DB_ESC2(void); +void DB_ESC3(void); +void DB_ESC4(void); +void DB_ESC5(void); +void DB_ESC6(void); +void DB_ESC7(void); +#endif +#if defined(SUPPORT_FPU_DOSBOX2) +void DB2_FPU_FINIT(void); +void DB2_FPU_FXSAVERSTOR(void); +void DB2_ESC0(void); +void DB2_ESC1(void); +void DB2_ESC2(void); +void DB2_ESC3(void); +void DB2_ESC4(void); +void DB2_ESC5(void); +void DB2_ESC6(void); +void DB2_ESC7(void); +#endif +#if defined(SUPPORT_FPU_SOFTFLOAT) +void SF_FPU_FINIT(void); +void SF_FPU_FXSAVERSTOR(void); +void SF_ESC0(void); +void SF_ESC1(void); +void SF_ESC2(void); +void SF_ESC3(void); +void SF_ESC4(void); +void SF_ESC5(void); +void SF_ESC6(void); +void SF_ESC7(void); +#endif +#endif + +// for i486SX +void NOFPU_FPU_FINIT(void); +void NOFPU_FPU_FXSAVERSTOR(void); +void NOFPU_ESC0(void); +void NOFPU_ESC1(void); +void NOFPU_ESC2(void); +void NOFPU_ESC3(void); +void NOFPU_ESC4(void); +void NOFPU_ESC5(void); +void NOFPU_ESC6(void); +void NOFPU_ESC7(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_FPU_FP_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/fpdummy.cpp b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpdummy.cpp new file mode 100644 index 000000000..a28f19ca1 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpdummy.cpp @@ -0,0 +1,161 @@ +//#include "compiler.h" + +#include "../../cpu.h" +#include "../../ia32.mcr" +#include "fp.h" + +void NOFPU_FPU_FINIT(void){ + // Nothing to do +} + +void NOFPU_FPU_FXSAVERSTOR(void){ + EXCEPTION(UD_EXCEPTION, 0); +} + +void +NOFPU_ESC0(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU d8 %.2x", op)); + if (op >= 0xc0) { + EXCEPTION(NM_EXCEPTION, 0); + } else { + madr = calc_ea_dst(op); + EXCEPTION(NM_EXCEPTION, 0); + } +} + +void +NOFPU_ESC1(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU d9 %.2x", op)); + if (op >= 0xc0) { + EXCEPTION(NM_EXCEPTION, 0); + } else { + madr = calc_ea_dst(op); + switch (op & 0x38) { + case 0x28: + TRACEOUT(("FLDCW")); + (void) cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + break; + + case 0x38: + TRACEOUT(("FSTCW")); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, 0xffff); + break; + + default: + EXCEPTION(NM_EXCEPTION, 0); + break; + } + } +} + +void +NOFPU_ESC2(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU da %.2x", op)); + if (op >= 0xc0) { + EXCEPTION(NM_EXCEPTION, 0); + } else { + madr = calc_ea_dst(op); + EXCEPTION(NM_EXCEPTION, 0); + } +} + +void +NOFPU_ESC3(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU db %.2x", op)); + if (op >= 0xc0) { + if (op != 0xe3) { + EXCEPTION(NM_EXCEPTION, 0); + } + /* FNINIT */ + (void)madr; + } else { + madr = calc_ea_dst(op); + EXCEPTION(NM_EXCEPTION, 0); + } +} + +void +NOFPU_ESC4(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU dc %.2x", op)); + if (op >= 0xc0) { + EXCEPTION(NM_EXCEPTION, 0); + } else { + madr = calc_ea_dst(op); + EXCEPTION(NM_EXCEPTION, 0); + } +} + +void +NOFPU_ESC5(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU dd %.2x", op)); + if (op >= 0xc0) { + EXCEPTION(NM_EXCEPTION, 0); + } else { + madr = calc_ea_dst(op); + if (((op >> 3) & 7) != 7) { + EXCEPTION(NM_EXCEPTION, 0); + } + /* FSTSW */ + TRACEOUT(("FSTSW")); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, 0xffff); + } +} + +void +NOFPU_ESC6(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU de %.2x", op)); + if (op >= 0xc0) { + EXCEPTION(NM_EXCEPTION, 0); + } else { + madr = calc_ea_dst(op); + EXCEPTION(NM_EXCEPTION, 0); + } +} + +void +NOFPU_ESC7(void) +{ + UINT32 op, madr; + + GET_PCBYTE(op); + TRACEOUT(("use FPU df %.2x", op)); + if (op >= 0xc0) { + if (op != 0xe0) { + EXCEPTION(NM_EXCEPTION, 0); + } + /* FSTSW AX */ + TRACEOUT(("FSTSW AX")); + CPU_AX = 0xffff; + } else { + madr = calc_ea_dst(op); + EXCEPTION(NM_EXCEPTION, 0); + } +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_dosbox.cpp b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_dosbox.cpp new file mode 100644 index 000000000..675356630 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_dosbox.cpp @@ -0,0 +1,2010 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Copyright (c) 2012 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * modified by SimK + * 拡張倍精度浮動小数点ではなく倍精度浮動小数点で計算されるので実際のx87 FPUより精度が劣ります + */ + +//#include "compiler.h" +#include "../../cpu.h" + +#if defined(USE_FPU) && defined(SUPPORT_FPU_DOSBOX) + +#include +#include +#include "../../ia32.mcr" + +#include "fp.h" +#include "fpumem.h" +#ifdef USE_SSE +#include "../sse/sse.h" +#endif + +#if 1 +#undef TRACEOUT +#define TRACEOUT(s) (void)(s) +#endif /* 0 */ + +#define FPU_WORKCLOCK 6 + +#define PI 3.14159265358979323846 +#define L2E 1.4426950408889634 +#define L2T 3.3219280948873623 +#define LN2 0.69314718055994531 +#define LG2 0.3010299956639812 + +static void FPU_FINIT(void); + +static void +fpu_check_NM_EXCEPTION(){ + // タスクスイッチまたはエミュレーション時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } +} +static void +fpu_check_NM_EXCEPTION2(){ + // タスクスイッチまたはエミュレーション時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static const FPU_PTR zero_ptr = { 0, 0, 0 }; + +/* + * FPU interface + */ + +static INLINE UINT FPU_GET_TOP(void) { + return (FPU_STATUSWORD & 0x3800)>>11; +} + +static INLINE void FPU_SET_TOP(UINT val){ + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (val&7)<<11; +} + + +static INLINE void FPU_SET_C0(UINT C){ + FPU_STATUSWORD &= ~0x0100; + if(C) FPU_STATUSWORD |= 0x0100; +} + +static INLINE void FPU_SET_C1(UINT C){ + FPU_STATUSWORD &= ~0x0200; + if(C) FPU_STATUSWORD |= 0x0200; +} + +static INLINE void FPU_SET_C2(UINT C){ + FPU_STATUSWORD &= ~0x0400; + if(C) FPU_STATUSWORD |= 0x0400; +} + +static INLINE void FPU_SET_C3(UINT C){ + FPU_STATUSWORD &= ~0x4000; + if(C) FPU_STATUSWORD |= 0x4000; +} + +static INLINE void FPU_SET_D(UINT C){ + FPU_STATUSWORD &= ~0x0002; + if(C) FPU_STATUSWORD |= 0x0002; +} + +static INLINE void FPU_SetCW(UINT16 cword) +{ + // HACK: Bits 13-15 are not defined. Apparently, one program likes to test for + // Cyrix EMC87 by trying to set bit 15. We want the test program to see + // us as an Intel 287 when cputype == 286. + cword &= 0x7FFF; + FPU_CTRLWORD = cword; + FPU_STAT.round = (FP_RND)((cword >> 10) & 3); +} + +static void FPU_FLDCW(UINT32 addr) +{ + UINT16 temp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, addr); + FPU_SetCW(temp); +} + +static UINT16 FPU_GetTag(void) +{ + UINT i; + + UINT16 tag=0; + for(i=0;i<8;i++) + tag |= ( (FPU_STAT.tag[i]&3) <<(2*i)); + return tag; +} +static UINT8 FPU_GetTag8(void) +{ + UINT i; + + UINT8 tag=0; + for(i=0;i<8;i++) + tag |= ( (FPU_STAT.tag[i]==TAG_Empty ? 0 : 1) <<(i)); + return tag; +} + +static INLINE void FPU_SetTag(UINT16 tag) +{ + UINT i; + + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = (FP_TAG)((tag >>(2*i))&3); + + } +} +static INLINE void FPU_SetTag8(UINT8 tag) +{ + UINT i; + + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = (((tag>>i)&1) == 0 ? TAG_Empty : TAG_Valid); + } +} + +static void FPU_FCLEX(void){ + //FPU_STATUSWORD &= 0xff00; //should clear exceptions + FPU_STATUSWORD &= 0x7f00; //should clear exceptions? +} + +static void FPU_FNOP(void){ + return; +} + +static void FPU_PUSH(double in){ + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + //actually check if empty + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Valid; + FPU_STAT.reg[FPU_STAT_TOP].d64 = in; +// LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); + return; +} + +static void FPU_PREP_PUSH(void){ + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Valid; +} + +static void FPU_FPOP(void){ + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Empty; + //maybe set zero in it as well + FPU_STAT_TOP = ((FPU_STAT_TOP+1)&7); +// LOG(LOG_FPU,LOG_ERROR)("popped from %d %g off the stack",top,fpu.regs[top].d64); + return; +} + +static double FROUND(double in){ + switch(FPU_STAT.round){ + case ROUND_Nearest: + if (in-floor(in)>0.5) return (floor(in)+1); + else if (in-floor(in)<0.5) return (floor(in)); + else return ((((SINT64)(floor(in)))&1)!=0)?(floor(in)+1):(floor(in)); + break; + case ROUND_Down: + return (floor(in)); + break; + case ROUND_Up: + return (ceil(in)); + break; + case ROUND_Chop: + return in; //the cast afterwards will do it right maybe cast here + break; + default: + return in; + break; + } +} + +#define BIAS80 16383 +#define BIAS64 1023 + +static void FPU_FLD80(UINT32 addr, UINT reg) +{ + FP_REG result; + SINT64 exp64, exp64final; + SINT64 blah; + SINT64 mant64; + SINT64 sign; + + struct { + SINT16 begin; + FP_REG eind; + } test; + + test.eind.l.lower = fpu_memoryread_d(addr); + test.eind.l.upper = fpu_memoryread_d(addr+4); + test.begin = fpu_memoryread_w(addr+8); + + exp64 = (((test.begin&0x7fff) - BIAS80)); + blah = ((exp64 >0)?exp64:-exp64)&0x3ff; + exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + + mant64 = (test.eind.ll >> 11) & QWORD_CONST(0xfffffffffffff); + sign = (test.begin&0x8000)?1:0; + result.ll = (sign <<63)|(exp64final << 52)| mant64; + + if(test.eind.l.lower == 0 && (UINT32)test.eind.l.upper == (UINT32)0x80000000UL && (test.begin&0x7fff) == 0x7fff) { + //Detect INF and -INF (score 3.11 when drawing a slur.) + result.d64 = sign?-HUGE_VAL:HUGE_VAL; + } + FPU_STAT.reg[reg].d64 = result.d64; + //return result.d64; + + //mant64= test.mant80/2***64 * 2 **53 +} + +static void FPU_ST80(UINT32 addr,UINT reg) +{ + SINT64 sign80; + SINT64 exp80, exp80final; + SINT64 mant80, mant80final; + + struct { + SINT16 begin; + FP_REG eind; + } test; + + sign80 = (FPU_STAT.reg[reg].ll&QWORD_CONST(0x8000000000000000))?1:0; + exp80 = FPU_STAT.reg[reg].ll&QWORD_CONST(0x7ff0000000000000); + exp80final = (exp80>>52); + mant80 = FPU_STAT.reg[reg].ll&QWORD_CONST(0x000fffffffffffff); + mant80final = (mant80 << 11); + if(FPU_STAT.reg[reg].d64 != 0){ //Zero is a special case + // Elvira wants the 8 and tcalc doesn't + mant80final |= QWORD_CONST(0x8000000000000000); + //Ca-cyber doesn't like this when result is zero. + exp80final += (BIAS80 - BIAS64); + } + test.begin = ((SINT16)(sign80)<<15)| (SINT16)(exp80final); + test.eind.ll = mant80final; + fpu_memorywrite_d(addr,test.eind.l.lower); + fpu_memorywrite_d(addr+4,test.eind.l.upper); + fpu_memorywrite_w(addr+8,test.begin); +} + + +static void FPU_FLD_F32(UINT32 addr,UINT store_to) { + union { + float f; + UINT32 l; + } blah; + + blah.l = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].d64 = (double)(blah.f); +} + +static void FPU_FLD_F64(UINT32 addr,UINT store_to) { + FPU_STAT.reg[store_to].l.lower = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].l.upper = fpu_memoryread_d(addr+4); +} + +static void FPU_FLD_F80(UINT32 addr) { + FPU_FLD80(addr, FPU_STAT_TOP); +} + +static void FPU_FLD_I16(UINT32 addr,UINT store_to) { + SINT16 blah; + + blah = fpu_memoryread_w(addr); + FPU_STAT.reg[store_to].d64 = (double)(blah); +} + +static void FPU_FLD_I32(UINT32 addr,UINT store_to) { + SINT32 blah; + + blah = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].d64 = (double)(blah); +} + +static void FPU_FLD_I64(UINT32 addr,UINT store_to) { + FP_REG blah; + + blah.l.lower = fpu_memoryread_d(addr); + blah.l.upper = fpu_memoryread_d(addr+4); + FPU_STAT.reg[store_to].d64 = (double)(blah.ll); +} + +static void FPU_FBLD(UINT32 addr,UINT store_to) +{ + UINT i; + double temp; + + UINT64 val = 0; + UINT in = 0; + UINT64 base = 1; + for(i = 0;i < 9;i++){ + in = fpu_memoryread_b(addr + i); + val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 + base *= 10; + val += ((( in>>4)&0xf) * base); + base *= 10; + } + + //last number, only now convert to float in order to get + //the best signification + temp = (double)(val); + in = fpu_memoryread_b(addr + 9); + temp += ( (in&0xf) * base ); + if(in&0x80) temp *= -1.0; + FPU_STAT.reg[store_to].d64 = temp; +} + + +static INLINE void FPU_FLD_F32_EA(UINT32 addr) { + FPU_FLD_F32(addr,8); +} +static INLINE void FPU_FLD_F64_EA(UINT32 addr) { + FPU_FLD_F64(addr,8); +} +static INLINE void FPU_FLD_I32_EA(UINT32 addr) { + FPU_FLD_I32(addr,8); +} +static INLINE void FPU_FLD_I16_EA(UINT32 addr) { + FPU_FLD_I16(addr,8); +} + +static void FPU_FST_F32(UINT32 addr) { + union { + float f; + UINT32 l; + } blah; + + //should depend on rounding method + blah.f = (float)(FPU_STAT.reg[FPU_STAT_TOP].d64); + fpu_memorywrite_d(addr,blah.l); +} + +static void FPU_FST_F64(UINT32 addr) { + fpu_memorywrite_d(addr,FPU_STAT.reg[FPU_STAT_TOP].l.lower); + fpu_memorywrite_d(addr+4,FPU_STAT.reg[FPU_STAT_TOP].l.upper); +} + +static void FPU_FST_F80(UINT32 addr) { + FPU_ST80(addr,FPU_STAT_TOP); +} + +static void FPU_FST_I16(UINT32 addr) { + fpu_memorywrite_w(addr,(SINT16)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64))); +} + +static void FPU_FST_I32(UINT32 addr) { + fpu_memorywrite_d(addr,(SINT32)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64))); +} + +static void FPU_FST_I64(UINT32 addr) { + FP_REG blah; + + blah.ll = (SINT64)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64)); + fpu_memorywrite_d(addr,blah.l.lower); + fpu_memorywrite_d(addr+4,blah.l.upper); +} + +static void FPU_FBST(UINT32 addr) +{ + FP_REG val; + UINT p; + UINT i; + BOOL sign; + double temp; + + val = FPU_STAT.reg[FPU_STAT_TOP]; + sign = FALSE; + if(FPU_STAT.reg[FPU_STAT_TOP].ll & QWORD_CONST(0x8000000000000000)) { //sign + sign=TRUE; + val.d64=-val.d64; + } + //numbers from back to front + temp=val.d64; + for(i=0;i<9;i++){ + val.d64=temp; + temp = (double)((SINT64)(floor(val.d64/10.0))); + p = (UINT)(val.d64 - 10.0*temp); + val.d64=temp; + temp = (double)((SINT64)(floor(val.d64/10.0))); + p |= ((UINT)(val.d64 - 10.0*temp)<<4); + + fpu_memorywrite_b(addr+i,p); + } + val.d64=temp; + temp = (double)((SINT64)(floor(val.d64/10.0))); + p = (UINT)(val.d64 - 10.0*temp); + if(sign) + p|=0x80; + fpu_memorywrite_b(addr+9,p); +} + +#define isinf(x) (!(_finite(x) || _isnan(x))) +#define isdenormal(x) (_fpclass(x) == _FPCLASS_ND || _fpclass(x) == _FPCLASS_PD) + +static void FPU_FADD(UINT op1, UINT op2){ + //// HACK: Set the denormal flag according to whether the source or final result is a denormalized number. + //// This is vital if we don't want certain DOS programs to mis-detect our FPU emulation as an IIT clone chip when cputype == 286 + //BOOL was_not_normal; + + //was_not_normal = isdenormal(FPU_STAT.reg[op1].d64); + //FPU_STAT.reg[op1].d64 += FPU_STAT.reg[op2].d64; + //FPU_SET_D(was_not_normal || isdenormal(FPU_STAT.reg[op1].d64) || isdenormal(FPU_STAT.reg[op2].d64)); + FPU_STAT.reg[op1].d64 += FPU_STAT.reg[op2].d64; + //flags and such :) + return; +} + +static void FPU_FSIN(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = sin(FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_SET_C2(0); + //flags and such :) + return; +} + +static void FPU_FSINCOS(void){ + double temp; + + temp = FPU_STAT.reg[FPU_STAT_TOP].d64; + FPU_STAT.reg[FPU_STAT_TOP].d64 = sin(temp); + FPU_PUSH(cos(temp)); + FPU_SET_C2(0); + //flags and such :) + return; +} + +static void FPU_FCOS(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = cos(FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_SET_C2(0); + //flags and such :) + return; +} + +static void FPU_FSQRT(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = sqrt(FPU_STAT.reg[FPU_STAT_TOP].d64); + //flags and such :) + return; +} +static void FPU_FPATAN(void){ + FPU_STAT.reg[FPU_ST(1)].d64 = atan2(FPU_STAT.reg[FPU_ST(1)].d64,FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_FPOP(); + //flags and such :) + return; +} +static void FPU_FPTAN(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = tan(FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_PUSH(1.0); + FPU_SET_C2(0); + //flags and such :) + return; +} +static void FPU_FDIV(UINT st, UINT other){ + if(FPU_STAT.reg[other].d64==0){ + FPU_STATUSWORD |= FP_ZE_FLAG; + if(!(FPU_CTRLWORD & FP_ZE_FLAG)) + return; + } + FPU_STAT.reg[st].d64= FPU_STAT.reg[st].d64/FPU_STAT.reg[other].d64; + //flags and such :) + return; +} + +static void FPU_FDIVR(UINT st, UINT other){ + if(FPU_STAT.reg[st].d64==0){ + FPU_STATUSWORD |= FP_ZE_FLAG; + if(!(FPU_CTRLWORD & FP_ZE_FLAG)) + return; + } + FPU_STAT.reg[st].d64= FPU_STAT.reg[other].d64/FPU_STAT.reg[st].d64; + // flags and such :) + return; +} + +static void FPU_FMUL(UINT st, UINT other){ + FPU_STAT.reg[st].d64*=FPU_STAT.reg[other].d64; + //flags and such :) + return; +} + +static void FPU_FSUB(UINT st, UINT other){ + FPU_STAT.reg[st].d64 = FPU_STAT.reg[st].d64 - FPU_STAT.reg[other].d64; + //flags and such :) + return; +} + +static void FPU_FSUBR(UINT st, UINT other){ + FPU_STAT.reg[st].d64 = FPU_STAT.reg[other].d64 - FPU_STAT.reg[st].d64; + //flags and such :) + return; +} + +static void FPU_FXCH(UINT st, UINT other){ + FP_TAG tag; + FP_REG reg; + + tag = FPU_STAT.tag[other]; + reg = FPU_STAT.reg[other]; + FPU_STAT.tag[other] = FPU_STAT.tag[st]; + FPU_STAT.reg[other] = FPU_STAT.reg[st]; + FPU_STAT.tag[st] = tag; + FPU_STAT.reg[st] = reg; +} + +static void FPU_FST(UINT st, UINT other){ + FPU_STAT.tag[other] = FPU_STAT.tag[st]; + FPU_STAT.reg[other] = FPU_STAT.reg[st]; +} + +static void FPU_FCOM(UINT st, UINT other){ + if(((FPU_STAT.tag[st] != TAG_Valid) && (FPU_STAT.tag[st] != TAG_Zero)) || + ((FPU_STAT.tag[other] != TAG_Valid) && (FPU_STAT.tag[other] != TAG_Zero))){ + FPU_SET_C3(1); + FPU_SET_C2(1); + FPU_SET_C0(1); + return; + } + + if(FPU_STAT.reg[st].d64 == FPU_STAT.reg[other].d64){ + FPU_SET_C3(1); + FPU_SET_C2(0); + FPU_SET_C0(0); + return; + } + if(FPU_STAT.reg[st].d64 < FPU_STAT.reg[other].d64){ + FPU_SET_C3(0); + FPU_SET_C2(0); + FPU_SET_C0(1); + return; + } + // st > other + FPU_SET_C3(0); + FPU_SET_C2(0); + FPU_SET_C0(0); + return; +} +static void FPU_FCOMI(UINT st, UINT other){ + if(((FPU_STAT.tag[st] != TAG_Valid) && (FPU_STAT.tag[st] != TAG_Zero)) || + ((FPU_STAT.tag[other] != TAG_Valid) && (FPU_STAT.tag[other] != TAG_Zero))){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | P_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + return; + } + + if(FPU_STAT.reg[st].d64 == FPU_STAT.reg[other].d64){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + return; + } + if(FPU_STAT.reg[st].d64 < FPU_STAT.reg[other].d64){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + return; + } + // st > other + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + return; +} + +static void FPU_FUCOM(UINT st, UINT other){ + //does atm the same as fcom + FPU_FCOM(st,other); +} +static void FPU_FUCOMI(UINT st, UINT other){ + //does atm the same as fcomi + FPU_FCOMI(st,other); +} + +static void FPU_FCMOVB(UINT st, UINT other){ + if(CPU_FLAGL & C_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVE(UINT st, UINT other){ + if(CPU_FLAGL & Z_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVBE(UINT st, UINT other){ + if(CPU_FLAGL & (C_FLAG|Z_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVU(UINT st, UINT other){ + if(CPU_FLAGL & P_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} + +static void FPU_FCMOVNB(UINT st, UINT other){ + if(!(CPU_FLAGL & C_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVNE(UINT st, UINT other){ + if(!(CPU_FLAGL & Z_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVNBE(UINT st, UINT other){ + if(!(CPU_FLAGL & (C_FLAG|Z_FLAG))){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVNU(UINT st, UINT other){ + if(!(CPU_FLAGL & P_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} + +static void FPU_FRNDINT(void){ + SINT64 temp; + + temp = (SINT64)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64)); + FPU_STAT.reg[FPU_STAT_TOP].d64=(double)(temp); +} + +static void FPU_FPREM(void){ + double valtop; + double valdiv; + SINT64 ressaved; + + valtop = FPU_STAT.reg[FPU_STAT_TOP].d64; + valdiv = FPU_STAT.reg[FPU_ST(1)].d64; + ressaved = (SINT64)( (valtop/valdiv) ); +// Some backups +// Real64 res=valtop - ressaved*valdiv; +// res= fmod(valtop,valdiv); + FPU_STAT.reg[FPU_STAT_TOP].d64 = valtop - ressaved*valdiv; + FPU_SET_C0((UINT)(ressaved&4)); + FPU_SET_C3((UINT)(ressaved&2)); + FPU_SET_C1((UINT)(ressaved&1)); + FPU_SET_C2(0); +} + +static void FPU_FPREM1(void){ + double valtop; + double valdiv, quot, quotf; + SINT64 ressaved; + + valtop = FPU_STAT.reg[FPU_STAT_TOP].d64; + valdiv = FPU_STAT.reg[FPU_ST(1)].d64; + quot = valtop/valdiv; + quotf = floor(quot); + + if (quot-quotf>0.5) ressaved = (SINT64)(quotf+1); + else if (quot-quotf<0.5) ressaved = (SINT64)(quotf); + else ressaved = (SINT64)(((((SINT64)(quotf))&1)!=0)?(quotf+1):(quotf)); + + FPU_STAT.reg[FPU_STAT_TOP].d64 = valtop - ressaved*valdiv; + FPU_SET_C0((UINT)(ressaved&4)); + FPU_SET_C3((UINT)(ressaved&2)); + FPU_SET_C1((UINT)(ressaved&1)); + FPU_SET_C2(0); +} + +static void FPU_FXAM(void){ + if(FPU_STAT.reg[FPU_STAT_TOP].ll & QWORD_CONST(0x8000000000000000)) //sign + { + FPU_SET_C1(1); + } + else + { + FPU_SET_C1(0); + } + if(FPU_STAT.tag[FPU_STAT_TOP] == TAG_Empty) + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); + return; + } + if(FPU_STAT.reg[FPU_STAT_TOP].d64 == 0.0) //zero or normalized number. + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0); + } + else + { + FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0); + } +} + +static void FPU_F2XM1(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = pow(2.0,FPU_STAT.reg[FPU_STAT_TOP].d64) - 1; + return; +} + +static void FPU_FYL2X(void){ + FPU_STAT.reg[FPU_ST(1)].d64*=log(FPU_STAT.reg[FPU_STAT_TOP].d64)/log((double)(2.0)); + FPU_FPOP(); + return; +} + +static void FPU_FYL2XP1(void){ + FPU_STAT.reg[FPU_ST(1)].d64*=log(FPU_STAT.reg[FPU_STAT_TOP].d64+1.0)/log((double)(2.0)); + FPU_FPOP(); + return; +} + +static void FPU_FSCALE(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 *= pow(2.0,(double)((SINT64)(FPU_STAT.reg[FPU_ST(1)].d64))); + return; //2^x where x is chopped. +} + +static void FPU_FSTENV(UINT32 addr) +{ + descriptor_t *sdp = &CPU_CS_DESC; + FPU_SET_TOP(FPU_STAT_TOP); + + switch ((CPU_CR0 & 1) | (SEG_IS_32BIT(sdp) ? 0x100 : 0x000)) + { + case 0x000: case 0x001: + fpu_memorywrite_w(addr+0,FPU_CTRLWORD); + fpu_memorywrite_w(addr+2,FPU_STATUSWORD); + fpu_memorywrite_w(addr+4,FPU_GetTag()); + fpu_memorywrite_w(addr+10,FPU_LASTINSTOP); + break; + + case 0x100: case 0x101: + fpu_memorywrite_d(addr+0,(UINT32)(FPU_CTRLWORD)); + fpu_memorywrite_d(addr+4,(UINT32)(FPU_STATUSWORD)); + fpu_memorywrite_d(addr+8,(UINT32)(FPU_GetTag())); + fpu_memorywrite_d(addr+20,FPU_LASTINSTOP); + break; + } +} + +static void FPU_FLDENV(UINT32 addr) +{ + descriptor_t *sdp = &CPU_CS_DESC; + + switch ((CPU_CR0 & 1) | (SEG_IS_32BIT(sdp) ? 0x100 : 0x000)) { + case 0x000: case 0x001: + FPU_SetCW(fpu_memoryread_w(addr+0)); + FPU_STATUSWORD = fpu_memoryread_w(addr+2); + FPU_SetTag(fpu_memoryread_w(addr+4)); + FPU_LASTINSTOP = fpu_memoryread_w(addr+10); + break; + + case 0x100: case 0x101: + FPU_SetCW((UINT16)fpu_memoryread_d(addr+0)); + FPU_STATUSWORD = (UINT16)fpu_memoryread_d(addr+4); + FPU_SetTag((UINT16)fpu_memoryread_d(addr+8)); + FPU_LASTINSTOP = (UINT16)fpu_memoryread_d(addr+20); + break; + } + FPU_STAT_TOP = FPU_GET_TOP(); +} + +static void FPU_FSAVE(UINT32 addr) +{ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + FPU_FSTENV(addr); + start = ((SEG_IS_32BIT(sdp))?28:14); + for(i = 0;i < 8;i++){ + FPU_ST80(addr+start,FPU_ST(i)); + start += 10; + } + FPU_FINIT(); +} + +static void FPU_FRSTOR(UINT32 addr) +{ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + FPU_FLDENV(addr); + start = ((SEG_IS_32BIT(sdp))?28:14); + for(i = 0;i < 8;i++){ + FPU_FLD80(addr+start, FPU_ST(i)); + start += 10; + } +} + +static void FPU_FXSAVE(UINT32 addr){ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + //FPU_FSTENV(addr); + FPU_SET_TOP(FPU_STAT_TOP); + fpu_memorywrite_w(addr+0,FPU_CTRLWORD); + fpu_memorywrite_w(addr+2,FPU_STATUSWORD); + fpu_memorywrite_b(addr+4,FPU_GetTag8()); +#ifdef USE_SSE + fpu_memorywrite_d(addr+24,SSE_MXCSR); +#endif + start = 32; + for(i = 0;i < 8;i++){ + //FPU_ST80(addr+start,FPU_ST(i)); + fpu_memorywrite_d(addr+start+0,FPU_STAT.reg[FPU_ST(i)].l.lower); + fpu_memorywrite_d(addr+start+4,FPU_STAT.reg[FPU_ST(i)].l.upper); + fpu_memorywrite_d(addr+start+8,0x0000ffff); + fpu_memorywrite_d(addr+start+12,0x00000000); + start += 16; + } +#ifdef USE_SSE + start = 160; + for(i = 0;i < 8;i++){ + fpu_memorywrite_q(addr+start+0,SSE_XMMREG(i).ul64[0]); + fpu_memorywrite_q(addr+start+8,SSE_XMMREG(i).ul64[1]); + start += 16; + } +#endif +} +static void FPU_FXRSTOR(UINT32 addr){ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + //FPU_FLDENV(addr); + FPU_SetCW(fpu_memoryread_w(addr+0)); + FPU_STATUSWORD = fpu_memoryread_w(addr+2); + FPU_SetTag8(fpu_memoryread_b(addr+4)); + FPU_STAT_TOP = FPU_GET_TOP(); +#ifdef USE_SSE + SSE_MXCSR = fpu_memoryread_d(addr+24); +#endif + start = 32; + for(i = 0;i < 8;i++){ + //FPU_STAT.reg[FPU_ST(i)].d64 = FPU_FLD80(addr+start); + FPU_STAT.reg[FPU_ST(i)].l.lower = fpu_memoryread_d(addr+start+0); + FPU_STAT.reg[FPU_ST(i)].l.upper = fpu_memoryread_d(addr+start+4); + start += 16; + } +#ifdef USE_SSE + start = 160; + for(i = 0;i < 8;i++){ + SSE_XMMREG(i).ul64[0] = fpu_memoryread_q(addr+start+0); + SSE_XMMREG(i).ul64[1] = fpu_memoryread_q(addr+start+8); + start += 16; + } +#endif +} + +void DB_FPU_FXSAVERSTOR(void){ + UINT32 op; + UINT idx, sub; + UINT32 maddr; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION2(); // XXX: 根拠無し + switch(idx){ + case 0: // FXSAVE + maddr = calc_ea_dst(op); + FPU_FXSAVE(maddr); + break; + case 1: // FXRSTOR + maddr = calc_ea_dst(op); + FPU_FXRSTOR(maddr); + break; +#ifdef USE_SSE + case 2: // LDMXCSR + maddr = calc_ea_dst(op); + SSE_LDMXCSR(maddr); + break; + case 3: // STMXCSR + maddr = calc_ea_dst(op); + SSE_STMXCSR(maddr); + break; + case 4: // SFENCE + SSE_SFENCE(); + break; + case 5: // LFENCE + SSE_LFENCE(); + break; + case 6: // MFENCE + SSE_MFENCE(); + break; + case 7: // CLFLUSH; + SSE_CLFLUSH(op); + break; +#endif + default: + ia32_panic("invalid opcode = %02x\n", op); + break; + } +} + +static void FPU_FXTRACT(void) { + // function stores real bias in st and + // pushes the significant number onto the stack + // if double ever uses a different base please correct this function + FP_REG test; + SINT64 exp80, exp80final; + double mant; + + test = FPU_STAT.reg[FPU_STAT_TOP]; + exp80 = test.ll&QWORD_CONST(0x7ff0000000000000); + exp80final = (exp80>>52) - BIAS64; + mant = test.d64 / (pow(2.0,(double)(exp80final))); + FPU_STAT.reg[FPU_STAT_TOP].d64 = (double)(exp80final); + FPU_PUSH(mant); +} + +static void FPU_FCHS(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = -1.0*(FPU_STAT.reg[FPU_STAT_TOP].d64); +} + +static void FPU_FABS(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = fabs(FPU_STAT.reg[FPU_STAT_TOP].d64); +} + +static void FPU_FTST(void){ + FPU_STAT.reg[8].d64 = 0.0; + FPU_FCOM(FPU_STAT_TOP,8); +} + +static void FPU_FLD1(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = 1.0; +} + +static void FPU_FLDL2T(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = L2T; +} + +static void FPU_FLDL2E(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = L2E; +} + +static void FPU_FLDPI(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = PI; +} + +static void FPU_FLDLG2(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = LG2; +} + +static void FPU_FLDLN2(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = LN2; +} + +static void FPU_FLDZ(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = 0.0; + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Zero; +} + + +static INLINE void FPU_FADD_EA(UINT op1){ + FPU_FADD(op1,8); +} +static INLINE void FPU_FMUL_EA(UINT op1){ + FPU_FMUL(op1,8); +} +static INLINE void FPU_FSUB_EA(UINT op1){ + FPU_FSUB(op1,8); +} +static INLINE void FPU_FSUBR_EA(UINT op1){ + FPU_FSUBR(op1,8); +} +static INLINE void FPU_FDIV_EA(UINT op1){ + FPU_FDIV(op1,8); +} +static INLINE void FPU_FDIVR_EA(UINT op1){ + FPU_FDIVR(op1,8); +} +static INLINE void FPU_FCOM_EA(UINT op1){ + FPU_FCOM(op1,8); +} + +/* + * FPU interface + */ +//int fpu_updateEmuEnv(void); +static void +FPU_FINIT(void) +{ + int i; + FPU_SetCW(0x37F); + FPU_STATUSWORD = 0; + FPU_STAT_TOP=FPU_GET_TOP(); + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = TAG_Empty; + // レジスタの内容は消してはいけない ver0.86 rev40 + //FPU_STAT.reg[i].d64 = 0; + //FPU_STAT.reg[i].l.lower = 0; + //FPU_STAT.reg[i].l.upper = 0; + //FPU_STAT.reg[i].ll = 0; + } + FPU_STAT.tag[8] = TAG_Valid; // is only used by us +} +void DB_FPU_FINIT(void){ + int i; + FPU_FINIT(); + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = TAG_Empty; + FPU_STAT.reg[i].l.ext = 0; + FPU_STAT.reg[i].l.lower = 0; + FPU_STAT.reg[i].l.upper = 0; + } +} + +/* + * FPU instruction + */ + +static void fpu_checkexception(){ + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & 0x3F){ + EXCEPTION(MF_EXCEPTION, 0); + } +} + +static void EA_TREE(UINT op) +{ + UINT idx; + + idx = (op >> 3) & 7; + + switch (idx) { + case 0: /* FADD (単精度実数) */ + TRACEOUT(("FADD EA")); + FPU_FADD_EA(FPU_STAT_TOP); + break; + case 1: /* FMUL (単精度実数) */ + TRACEOUT(("FMUL EA")); + FPU_FMUL_EA(FPU_STAT_TOP); + break; + case 2: /* FCOM (単精度実数) */ + TRACEOUT(("FCOM EA")); + FPU_FCOM_EA(FPU_STAT_TOP); + break; + case 3: /* FCOMP (単精度実数) */ + TRACEOUT(("FCOMP EA")); + FPU_FCOM_EA(FPU_STAT_TOP); + FPU_FPOP(); + break; + case 4: /* FSUB (単精度実数) */ + TRACEOUT(("FSUB EA")); + FPU_FSUB_EA(FPU_STAT_TOP); + break; + case 5: /* FSUBR (単精度実数) */ + TRACEOUT(("FSUBR EA")); + FPU_FSUBR_EA(FPU_STAT_TOP); + break; + case 6: /* FDIV (単精度実数) */ + TRACEOUT(("FDIV EA")); + FPU_FDIV_EA(FPU_STAT_TOP); + break; + case 7: /* FDIVR (単精度実数) */ + TRACEOUT(("FDIVR EA")); + FPU_FDIVR_EA(FPU_STAT_TOP); + break; + default: + break; + } +} + +// d8 +void +DB_ESC0(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU d8 %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FADD */ + TRACEOUT(("FADD")); + FPU_FADD(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FMUL */ + TRACEOUT(("FMUL")); + FPU_FMUL(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCOM */ + TRACEOUT(("FCOM")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMP */ + TRACEOUT(("FCOMP")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FSUB */ + TRACEOUT(("FSUB")); + FPU_FSUB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: /* FSUBR */ + TRACEOUT(("FSUBR")); + FPU_FSUBR(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 6: /* FDIV */ + TRACEOUT(("FDIV")); + FPU_FDIV(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 7: /* FDIVR */ + TRACEOUT(("FDIVR")); + FPU_FDIVR(FPU_STAT_TOP,FPU_ST(sub)); + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_F32_EA(madr); + EA_TREE(op); + } +} + +// d9 +void +DB_ESC1(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU d9 %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op < 0xc0 && idx>=4)){ + fpu_checkexception(); + } + if (op >= 0xc0) + { + switch (idx) { + case 0: /* FLD ST(0), ST(i) */ + { + UINT reg_from; + + TRACEOUT(("FLD STi")); + reg_from = FPU_ST(sub); + FPU_PREP_PUSH(); + FPU_FST(reg_from, FPU_STAT_TOP); + } + break; + + case 1: /* FXCH ST(0), ST(i) */ + TRACEOUT(("FXCH STi")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + + case 2: /* FNOP */ + TRACEOUT(("FNOP")); + FPU_FNOP(); + break; + + case 3: /* FSTP STi */ + TRACEOUT(("FSTP STi")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + case 4: + switch (sub) { + case 0x0: /* FCHS */ + TRACEOUT(("FCHS")); + FPU_FCHS(); + break; + + case 0x1: /* FABS */ + TRACEOUT(("FABS")); + FPU_FABS(); + break; + + case 0x2: /* UNKNOWN */ + case 0x3: /* ILLEGAL */ + break; + + case 0x4: /* FTST */ + TRACEOUT(("FTST")); + FPU_FTST(); + break; + + case 0x5: /* FXAM */ + TRACEOUT(("FXAM")); + FPU_FXAM(); + break; + + case 0x06: /* FTSTP (cyrix)*/ + case 0x07: /* UNKNOWN */ + break; + } + break; + + case 5: + switch (sub) { + case 0x0: /* FLD1 */ + TRACEOUT(("FLD1")); + FPU_FLD1(); + break; + + case 0x1: /* FLDL2T */ + TRACEOUT(("FLDL2T")); + FPU_FLDL2T(); + break; + + case 0x2: /* FLDL2E */ + TRACEOUT(("FLDL2E")); + FPU_FLDL2E(); + break; + + case 0x3: /* FLDPI */ + TRACEOUT(("FLDPI")); + FPU_FLDPI(); + break; + + case 0x4: /* FLDLG2 */ + TRACEOUT(("FLDLG2")); + FPU_FLDLG2(); + break; + + case 0x5: /* FLDLN2 */ + TRACEOUT(("FLDLN2")); + FPU_FLDLN2(); + break; + + case 0x6: /* FLDZ */ + TRACEOUT(("FLDZ")); + FPU_FLDZ(); + break; + + case 0x07: /* ILLEGAL */ + break; + } + break; + + case 6: + switch (sub) { + case 0x0: /* F2XM1 */ + TRACEOUT(("F2XM1")); + FPU_F2XM1(); + break; + + case 0x1: /* FYL2X */ + TRACEOUT(("FYL2X")); + FPU_FYL2X(); + break; + + case 0x2: /* FPTAN */ + TRACEOUT(("FPTAN")); + FPU_FPTAN(); + break; + + case 0x3: /* FPATAN */ + TRACEOUT(("FPATAN")); + FPU_FPATAN(); + break; + + case 0x4: /* FXTRACT */ + TRACEOUT(("FXTRACT")); + FPU_FXTRACT(); + break; + + case 0x5: /* FPREM1 */ + TRACEOUT(("FPREM1")); + FPU_FPREM1(); + break; + + case 0x6: /* FDECSTP */ + TRACEOUT(("FDECSTP")); + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + break; + + case 0x7: /* FINCSTP */ + TRACEOUT(("FINCSTP")); + FPU_STAT_TOP = (FPU_STAT_TOP + 1) & 7; + break; + } + break; + + case 7: + switch (sub) { + case 0x0: /* FPREM */ + TRACEOUT(("FPREM")); + FPU_FPREM(); + break; + + case 0x1: /* FYL2XP1 */ + TRACEOUT(("FYL2XP1")); + FPU_FYL2XP1(); + break; + + case 0x2: /* FSQRT */ + TRACEOUT(("FSQRT")); + FPU_FSQRT(); + break; + + case 0x3: /* FSINCOS */ + TRACEOUT(("FSINCOS")); + FPU_FSINCOS(); + break; + + case 0x4: /* FRNDINT */ + TRACEOUT(("FRNDINT")); + FPU_FRNDINT(); + break; + + case 0x5: /* FSCALE */ + TRACEOUT(("FSCALE")); + FPU_FSCALE(); + break; + + case 0x6: /* FSIN */ + TRACEOUT(("FSIN")); + FPU_FSIN(); + break; + + case 0x7: /* FCOS */ + TRACEOUT(("FCOS")); + FPU_FCOS(); + break; + } + break; + + default: + ia32_panic("ESC1: invalid opcode = %02x\n", op); + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FLD (単精度実数) */ + TRACEOUT(("FLD float")); + FPU_PREP_PUSH(); + FPU_FLD_F32(madr,FPU_STAT_TOP); + break; + + case 1: /* UNKNOWN */ + break; + + case 2: /* FST (単精度実数) */ + TRACEOUT(("FST float")); + FPU_FST_F32(madr); + break; + + case 3: /* FSTP (単精度実数) */ + TRACEOUT(("FSTP float")); + FPU_FST_F32(madr); + FPU_FPOP(); + break; + + case 4: /* FLDENV */ + TRACEOUT(("FLDENV")); + FPU_FLDENV(madr); + break; + + case 5: /* FLDCW */ + TRACEOUT(("FLDCW")); + FPU_FLDCW(madr); + break; + + case 6: /* FSTENV */ + TRACEOUT(("FSTENV")); + FPU_FSTENV(madr); + break; + + case 7: /* FSTCW */ + TRACEOUT(("FSTCW/FNSTCW")); + fpu_memorywrite_w(madr,FPU_CTRLWORD); + break; + + default: + break; + } + } +} + +// da +void +DB_ESC2(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU da %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FCMOVB */ + TRACEOUT(("ESC2: FCMOVB")); + FPU_FCMOVB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FCMOVE */ + TRACEOUT(("ESC2: FCMOVE")); + FPU_FCMOVE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCMOVBE */ + TRACEOUT(("ESC2: FCMOVBE")); + FPU_FCMOVBE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCMOVU */ + TRACEOUT(("ESC2: FCMOVU")); + FPU_FCMOVU(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: + switch (sub) { + case 1: /* FUCOMPP */ + TRACEOUT(("FUCOMPP")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(1)); + FPU_FPOP(); + FPU_FPOP(); + break; + + default: + break; + } + break; + + default: + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_I32_EA(madr); + EA_TREE(op); + } +} + +// db +void +DB_ESC3(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU db %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op >= 0xc0 && idx==4)){ + fpu_checkexception(); + } + if (op >= 0xc0) + { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FCMOVNB */ + TRACEOUT(("ESC3: FCMOVNB")); + FPU_FCMOVNB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FCMOVNE */ + TRACEOUT(("ESC3: FCMOVNE")); + FPU_FCMOVNE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCMOVNBE */ + TRACEOUT(("ESC3: FCMOVNBE")); + FPU_FCMOVNBE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCMOVNU */ + TRACEOUT(("ESC3: FCMOVNU")); + FPU_FCMOVNU(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 4: + switch (sub) { + case 0: /* FNENI */ + case 1: /* FNDIS */ + break; + + case 2: /* FCLEX */ + TRACEOUT(("FCLEX")); + FPU_FCLEX(); + break; + + case 3: /* FNINIT/FINIT */ + TRACEOUT(("FNINIT/FINIT")); + FPU_FINIT(); + break; + + case 4: /* FNSETPM */ + case 5: /* FRSTPM */ + FPU_FNOP(); + break; + + default: + break; + } + break; + case 5: /* FUCOMI */ + TRACEOUT(("ESC3: FUCOMI")); + FPU_FUCOMI(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 6: /* FCOMI */ + TRACEOUT(("ESC3: FCOMI")); + FPU_FCOMI(FPU_STAT_TOP,FPU_ST(sub)); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FILD (DWORD) */ + TRACEOUT(("FILD")); + FPU_PREP_PUSH(); + FPU_FLD_I32(madr,FPU_STAT_TOP); + break; + + case 1: /* FISTTP (DWORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + FP_RND oldrnd = FPU_STAT.round; + FPU_STAT.round = ROUND_Down; + FPU_FST_I32(madr); + FPU_STAT.round = oldrnd; + } + FPU_FPOP(); + } + break; + + case 2: /* FIST (DWORD) */ + TRACEOUT(("FIST")); + FPU_FST_I32(madr); + break; + + case 3: /* FISTP (DWORD) */ + TRACEOUT(("FISTP")); + FPU_FST_I32(madr); + FPU_FPOP(); + break; + + case 5: /* FLD (拡張実数) */ + TRACEOUT(("FLD 80 Bits Real")); + FPU_PREP_PUSH(); + FPU_FLD_F80(madr); + break; + + case 7: /* FSTP (拡張実数) */ + TRACEOUT(("FSTP 80 Bits Real")); + FPU_FST_F80(madr); + FPU_FPOP(); + break; + + default: + break; + } + } +} + +// dc +void +DB_ESC4(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU dc %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(i), ST(0) */ + switch (idx) { + case 0: /* FADD */ + TRACEOUT(("ESC4: FADD")); + FPU_FADD(FPU_ST(sub),FPU_STAT_TOP); + break; + case 1: /* FMUL */ + TRACEOUT(("ESC4: FMUL")); + FPU_FMUL(FPU_ST(sub),FPU_STAT_TOP); + break; + case 2: /* FCOM */ + TRACEOUT(("ESC4: FCOM")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMP */ + TRACEOUT(("ESC4: FCOMP")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FSUBR */ + TRACEOUT(("ESC4: FSUBR")); + FPU_FSUBR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 5: /* FSUB */ + TRACEOUT(("ESC4: FSUB")); + FPU_FSUB(FPU_ST(sub),FPU_STAT_TOP); + break; + case 6: /* FDIVR */ + TRACEOUT(("ESC4: FDIVR")); + FPU_FDIVR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 7: /* FDIV */ + TRACEOUT(("ESC4: FDIV")); + FPU_FDIV(FPU_ST(sub),FPU_STAT_TOP); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_F64_EA(madr); + EA_TREE(op); + } +} + +// dd +void +DB_ESC5(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU dd %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + fpu_check_NM_EXCEPTION(); + //if(op < 0xc0 && (idx==6 || idx==4)){ + // _ADD_EIP(-1); // XXX: 無理やり戻す + // fpu_check_NM_EXCEPTION2(); + // _ADD_EIP(1); + //}else{ + // _ADD_EIP(-1); // XXX: 無理やり戻す + // fpu_check_NM_EXCEPTION(); + // _ADD_EIP(1); + //} + if(op >= 0xc0 || (idx!=4 && idx!=6 && idx!=7)){ + fpu_checkexception(); + } + if (op >= 0xc0) { + /* FUCOM ST(i), ST(0) */ + /* Fxxx ST(i) */ + switch (idx) { + case 0: /* FFREE */ + TRACEOUT(("FFREE")); + FPU_STAT.tag[FPU_ST(sub)]=TAG_Empty; + break; + case 1: /* FXCH */ + TRACEOUT(("FXCH")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FST */ + TRACEOUT(("FST")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FSTP */ + TRACEOUT(("FSTP")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FUCOM */ + TRACEOUT(("FUCOM")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: /* FUCOMP */ + TRACEOUT(("FUCOMP")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FLD (倍精度実数) */ + TRACEOUT(("FLD double real")); + FPU_PREP_PUSH(); + FPU_FLD_F64(madr,FPU_STAT_TOP); + break; + case 1: /* FISTTP (QWORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + FP_RND oldrnd = FPU_STAT.round; + FPU_STAT.round = ROUND_Down; + FPU_FST_I64(madr); + FPU_STAT.round = oldrnd; + } + FPU_FPOP(); + } + break; + case 2: /* FST (倍精度実数) */ + TRACEOUT(("FST double real")); + FPU_FST_F64(madr); + break; + case 3: /* FSTP (倍精度実数) */ + TRACEOUT(("FSTP double real")); + FPU_FST_F64(madr); + FPU_FPOP(); + break; + case 4: /* FRSTOR */ + TRACEOUT(("FRSTOR")); + FPU_FRSTOR(madr); + break; + case 6: /* FSAVE */ + TRACEOUT(("FSAVE")); + FPU_FSAVE(madr); + break; + + case 7: /* FSTSW */ + FPU_SET_TOP(FPU_STAT_TOP); + //cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, FPU_CTRLWORD); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, FPU_STATUSWORD); + break; + + default: + break; + } + } +} + +// de +void +DB_ESC6(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU de %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(i), ST(0) */ + switch (idx) { + case 0: /* FADDP */ + TRACEOUT(("FADDP")); + FPU_FADD(FPU_ST(sub),FPU_STAT_TOP); + break; + case 1: /* FMULP */ + TRACEOUT(("FMULP")); + FPU_FMUL(FPU_ST(sub),FPU_STAT_TOP); + break; + case 2: /* FCOMP5 */ + TRACEOUT(("FCOMP5")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMPP */ + TRACEOUT(("FCOMPP")); + if(sub != 1) { + return; + } + FPU_FCOM(FPU_STAT_TOP,FPU_ST(1)); + FPU_FPOP(); /* extra pop at the bottom*/ + break; + case 4: /* FSUBRP */ + TRACEOUT(("FSUBRP")); + FPU_FSUBR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 5: /* FSUBP */ + TRACEOUT(("FSUBP")); + FPU_FSUB(FPU_ST(sub),FPU_STAT_TOP); + break; + case 6: /* FDIVRP */ + TRACEOUT(("FDIVRP")); + FPU_FDIVR(FPU_ST(sub),FPU_STAT_TOP); + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & FP_ZE_FLAG){ + return; // POPしないようにする + } + break; + case 7: /* FDIVP */ + TRACEOUT(("FDIVP")); + FPU_FDIV(FPU_ST(sub),FPU_STAT_TOP); + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & FP_ZE_FLAG){ + return; // POPしないようにする + } + break; + /*FALLTHROUGH*/ + default: + break; + } + FPU_FPOP(); + } else { + madr = calc_ea_dst(op); + FPU_FLD_I16_EA(madr); + EA_TREE(op); + } +} + +// df +void +DB_ESC7(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU df %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op >= 0xc0 && idx==4 && sub==0)){ + fpu_checkexception(); + } + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FFREEP */ + TRACEOUT(("FFREEP")); + FPU_STAT.tag[FPU_ST(sub)]=TAG_Empty; + FPU_FPOP(); + break; + case 1: /* FXCH */ + TRACEOUT(("FXCH")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + + case 2: + case 3: /* FSTP */ + TRACEOUT(("FSTP")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + case 4: + switch (sub) + { + case 0: /* FSTSW AX */ + TRACEOUT(("FSTSW AX")); + FPU_SET_TOP(FPU_STAT_TOP); + CPU_AX = FPU_STATUSWORD; + break; + + default: + break; + } + break; + case 5: /* FUCOMIP */ + TRACEOUT(("ESC7: FUCOMIP")); + FPU_FUCOMI(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 6: /* FCOMIP */ + TRACEOUT(("ESC7: FCOMIP")); + FPU_FCOMI(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FILD (WORD) */ + TRACEOUT(("FILD SINT16")); + FPU_PREP_PUSH(); + FPU_FLD_I16(madr,FPU_STAT_TOP); + break; + case 1: /* FISTTP (WORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + FP_RND oldrnd = FPU_STAT.round; + FPU_STAT.round = ROUND_Down; + FPU_FST_I16(madr); + FPU_STAT.round = oldrnd; + } + FPU_FPOP(); + } + break; + case 2: /* FIST (WORD) */ + TRACEOUT(("FIST SINT16")); + FPU_FST_I16(madr); + break; + case 3: /* FISTP (WORD) */ + TRACEOUT(("FISTP SINT16")); + FPU_FST_I16(madr); + FPU_FPOP(); + break; + + case 4: /* FBLD (BCD) */ + TRACEOUT(("FBLD packed BCD")); + FPU_PREP_PUSH(); + FPU_FBLD(madr,FPU_STAT_TOP); + break; + + case 5: /* FILD (QWORD) */ + TRACEOUT(("FILD SINT64")); + FPU_PREP_PUSH(); + FPU_FLD_I64(madr,FPU_STAT_TOP); + break; + + case 6: /* FBSTP (BCD) */ + TRACEOUT(("FBSTP packed BCD")); + FPU_FBST(madr); + FPU_FPOP(); + break; + + case 7: /* FISTP (QWORD) */ + TRACEOUT(("FISTP SINT64")); + FPU_FST_I64(madr); + FPU_FPOP(); + break; + + default: + break; + } + } +} +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_dosbox2.cpp b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_dosbox2.cpp new file mode 100644 index 000000000..53d190b8d --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_dosbox2.cpp @@ -0,0 +1,2217 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Copyright (c) 2012 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * modified by SimK + * 整数値のロード・ストア限定で拡張倍精度浮動小数点相当の精度があります + */ + +//#include "compiler.h" +#include "../../cpu.h" + +#if defined(USE_FPU) && defined(SUPPORT_FPU_DOSBOX2) + +#include +#include +#include "../../ia32.mcr" + +#include "fp.h" +#include "fpumem.h" +#ifdef USE_SSE +#include "../sse/sse.h" +#endif + +#if 1 +#undef TRACEOUT +#define TRACEOUT(s) (void)(s) +#endif /* 0 */ + +#define FPU_WORKCLOCK 6 + +#define PI 3.14159265358979323846 +#define L2E 1.4426950408889634 +#define L2T 3.3219280948873623 +#define LN2 0.69314718055994531 +#define LG2 0.3010299956639812 + +static void FPU_FINIT(void); + +static void +fpu_check_NM_EXCEPTION(){ + // タスクスイッチまたはエミュレーション時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } +} +static void +fpu_check_NM_EXCEPTION2(){ + // タスクスイッチまたはエミュレーション時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static const FPU_PTR zero_ptr = { 0, 0, 0 }; + +/* + * FPU interface + */ + +static INLINE UINT FPU_GET_TOP(void) { + return (FPU_STATUSWORD & 0x3800)>>11; +} + +static INLINE void FPU_SET_TOP(UINT val){ + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (val&7)<<11; +} + + +static INLINE void FPU_SET_C0(UINT C){ + FPU_STATUSWORD &= ~0x0100; + if(C) FPU_STATUSWORD |= 0x0100; +} + +static INLINE void FPU_SET_C1(UINT C){ + FPU_STATUSWORD &= ~0x0200; + if(C) FPU_STATUSWORD |= 0x0200; +} + +static INLINE void FPU_SET_C2(UINT C){ + FPU_STATUSWORD &= ~0x0400; + if(C) FPU_STATUSWORD |= 0x0400; +} + +static INLINE void FPU_SET_C3(UINT C){ + FPU_STATUSWORD &= ~0x4000; + if(C) FPU_STATUSWORD |= 0x4000; +} + +static INLINE void FPU_SET_D(UINT C){ + FPU_STATUSWORD &= ~0x0002; + if(C) FPU_STATUSWORD |= 0x0002; +} + +static INLINE void FPU_SetCW(UINT16 cword) +{ + // HACK: Bits 13-15 are not defined. Apparently, one program likes to test for + // Cyrix EMC87 by trying to set bit 15. We want the test program to see + // us as an Intel 287 when cputype == 286. + cword &= 0x7FFF; + FPU_CTRLWORD = cword; + FPU_STAT.round = (FP_RND)((cword >> 10) & 3); +} + +static void FPU_FLDCW(UINT32 addr) +{ + UINT16 temp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, addr); + FPU_SetCW(temp); +} + +static UINT16 FPU_GetTag(void) +{ + UINT i; + + UINT16 tag=0; + for(i=0;i<8;i++) + tag |= ( (FPU_STAT.tag[i]&3) <<(2*i)); + return tag; +} +static UINT8 FPU_GetTag8(void) +{ + UINT i; + + UINT8 tag=0; + for(i=0;i<8;i++) + tag |= ( (FPU_STAT.tag[i]==TAG_Empty ? 0 : 1) <<(i)); + return tag; +} + +static INLINE void FPU_SetTag(UINT16 tag) +{ + UINT i; + + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = (FP_TAG)((tag >>(2*i))&3); + + } +} +static INLINE void FPU_SetTag8(UINT8 tag) +{ + UINT i; + + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = (((tag>>i)&1) == 0 ? TAG_Empty : TAG_Valid); + } +} + +static void FPU_FCLEX(void){ + //FPU_STATUSWORD &= 0xff00; //should clear exceptions + FPU_STATUSWORD &= 0x7f00; //should clear exceptions? +} + +static void FPU_FNOP(void){ + return; +} + +static void FPU_PUSH(double in){ + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + //actually check if empty + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Valid; + FPU_STAT.reg[FPU_STAT_TOP].d64 = in; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; +// LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); + return; +} + +static void FPU_PREP_PUSH(void){ + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Valid; +} + +static void FPU_FPOP(void){ + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Empty; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + //maybe set zero in it as well + FPU_STAT_TOP = ((FPU_STAT_TOP+1)&7); +// LOG(LOG_FPU,LOG_ERROR)("popped from %d %g off the stack",top,fpu.regs[top].d64); + return; +} + +static double FROUND(double in){ + switch(FPU_STAT.round){ + case ROUND_Nearest: + if (in-floor(in)>0.5) return (floor(in)+1); + else if (in-floor(in)<0.5) return (floor(in)); + else return ((((SINT64)(floor(in)))&1)!=0)?(floor(in)+1):(floor(in)); + break; + case ROUND_Down: + return (floor(in)); + break; + case ROUND_Up: + return (ceil(in)); + break; + case ROUND_Chop: + return in; //the cast afterwards will do it right maybe cast here + break; + default: + return in; + break; + } +} + +#define BIAS80 16383 +#define BIAS64 1023 + +static void FPU_FLD80(UINT32 addr, UINT reg) +{ + FP_REG result; + SINT64 exp64, exp64final; + SINT64 blah; + SINT64 mant64; + SINT64 sign; + + struct { + SINT16 begin; + FP_REG eind; + } test; + + test.eind.l.lower = fpu_memoryread_d(addr); + test.eind.l.upper = fpu_memoryread_d(addr+4); + test.begin = fpu_memoryread_w(addr+8); + + exp64 = (((test.begin&0x7fff) - BIAS80)); + blah = ((exp64 >0)?exp64:-exp64)&0x3ff; + exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + + mant64 = (test.eind.ll >> 11) & QWORD_CONST(0xfffffffffffff); + sign = (test.begin&0x8000)?1:0; + result.ll = (sign <<63)|(exp64final << 52)| mant64; + + { + UINT64 tmp; + unsigned int shift; + shift = (unsigned int)(63-exp64); + // 1.xxxを64bit整数表現できるかチェック + if(exp64 >= 0 && // 1未満なったらアウト + exp64 <= 63 && // 値が64bit整数で表現できない場合もアウト(とりあえず符号無しで判定) + ((test.eind.ll >> shift) << shift)==test.eind.ll){ // 小数点以下の数がある場合もアウト + //tmp = ((((UINT64)test.eind.ll) >> 1) | QWORD_CONST(0x8000000000000000)) >> shift; + tmp = ((UINT64)test.eind.ll) >> shift; + if(sign==0 && tmp < QWORD_CONST(0x8000000000000000)){ // 符号付き(正)で表現できるか + FPU_STAT.int_reg[reg].ul64.m12 = tmp; + FPU_STAT.int_regvalid[reg] = 1; + }else if(sign==1 && tmp <= QWORD_CONST(0x8000000000000000)){ // 符号付き(負)で表現できるか + FPU_STAT.int_reg[reg].ul64.m12 = ((~tmp) + 1); + FPU_STAT.int_regvalid[reg] = 1; + }else{ + FPU_STAT.int_regvalid[reg] = 0; + } + }else if((test.begin&0x7fff) == 0 && test.eind.ll == 0){ // 0の場合 + FPU_STAT.int_reg[reg].ul64.m12 = 0; + FPU_STAT.int_regvalid[reg] = 1; + }else{ + FPU_STAT.int_regvalid[reg] = 0; + } + } + + if(test.eind.l.lower == 0 && (UINT32)test.eind.l.upper == (UINT32)0x80000000UL && (test.begin&0x7fff) == 0x7fff) { + //Detect INF and -INF (score 3.11 when drawing a slur.) + result.d64 = sign?-HUGE_VAL:HUGE_VAL; + } + FPU_STAT.reg[reg].d64 = result.d64; + //return result.d64; + + //mant64= test.mant80/2***64 * 2 **53 +} + +static void FPU_ST80(UINT32 addr,UINT reg) +{ + SINT64 sign80; + SINT64 exp80, exp80final; + SINT64 mant80, mant80final; + + struct { + SINT16 begin; + FP_REG eind; + } test; + + sign80 = (FPU_STAT.reg[reg].ll&QWORD_CONST(0x8000000000000000))?1:0; + exp80 = FPU_STAT.reg[reg].ll&QWORD_CONST(0x7ff0000000000000); + exp80final = (exp80>>52); + mant80 = FPU_STAT.reg[reg].ll&QWORD_CONST(0x000fffffffffffff); + mant80final = (mant80 << 11); + if(FPU_STAT.reg[reg].d64 != 0){ //Zero is a special case + // Elvira wants the 8 and tcalc doesn't + mant80final |= QWORD_CONST(0x8000000000000000); + //Ca-cyber doesn't like this when result is zero. + exp80final += (BIAS80 - BIAS64); + } + test.begin = ((SINT16)(sign80)<<15)| (SINT16)(exp80final); + test.eind.ll = mant80final; + if(FPU_STAT.int_regvalid[reg] && FPU_STAT.int_reg[reg].ul64.m12!=0){ + UINT64 tmp; + if((SINT64)FPU_STAT.int_reg[reg].ul64.m12 < 0){ + sign80 = 1; + tmp = (~(FPU_STAT.int_reg[reg].ul64.m12)) + 1; + }else{ + sign80 = 0; + tmp = FPU_STAT.int_reg[reg].ul64.m12; + } + exp80final = BIAS80 + 63; + while(!(tmp & QWORD_CONST(0x8000000000000000))){ + tmp = tmp << 1; + exp80final--; + } + test.begin = ((SINT16)(sign80)<<15)| (SINT16)(exp80final); + test.eind.ll = tmp; + } + fpu_memorywrite_d(addr,test.eind.l.lower); + fpu_memorywrite_d(addr+4,test.eind.l.upper); + fpu_memorywrite_w(addr+8,test.begin); +} + + +static void FPU_FLD_F32(UINT32 addr,UINT store_to) { + union { + float f; + UINT32 l; + } blah; + + blah.l = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].d64 = (double)(blah.f); + FPU_STAT.int_regvalid[store_to] = 0; +} + +static void FPU_FLD_F64(UINT32 addr,UINT store_to) { + FPU_STAT.reg[store_to].l.lower = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].l.upper = fpu_memoryread_d(addr+4); + FPU_STAT.int_regvalid[store_to] = 0; +} + +static void FPU_FLD_F80(UINT32 addr) { + FPU_FLD80(addr, FPU_STAT_TOP); +} + +static void FPU_FLD_I16(UINT32 addr,UINT store_to) { + SINT16 blah; + + blah = fpu_memoryread_w(addr); + FPU_STAT.reg[store_to].d64 = (double)(blah); + FPU_STAT.int_reg[store_to].ul64.m12 = (UINT64)((SINT64)blah); + FPU_STAT.int_regvalid[store_to] = 1; +} + +static void FPU_FLD_I32(UINT32 addr,UINT store_to) { + SINT32 blah; + + blah = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].d64 = (double)(blah); + FPU_STAT.int_reg[store_to].ul64.m12 = (UINT64)((SINT64)blah); + FPU_STAT.int_regvalid[store_to] = 1; +} + +static void FPU_FLD_I64(UINT32 addr,UINT store_to) { + FP_REG blah; + + blah.l.lower = fpu_memoryread_d(addr); + blah.l.upper = fpu_memoryread_d(addr+4); + FPU_STAT.reg[store_to].d64 = (double)(blah.ll); + FPU_STAT.int_reg[store_to].ul64.m12 = (UINT64)(blah.ll); + FPU_STAT.int_regvalid[store_to] = 1; +} + +static void FPU_FBLD(UINT32 addr,UINT store_to) +{ + UINT i; + double temp; + + UINT64 val = 0; + UINT in = 0; + UINT64 base = 1; + for(i = 0;i < 9;i++){ + in = fpu_memoryread_b(addr + i); + val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 + base *= 10; + val += ((( in>>4)&0xf) * base); + base *= 10; + } + + //last number, only now convert to float in order to get + //the best signification + temp = (double)(val); + in = fpu_memoryread_b(addr + 9); + temp += ( (in&0xf) * base ); + if(in&0x80) temp *= -1.0; + FPU_STAT.reg[store_to].d64 = temp; +} + + +static INLINE void FPU_FLD_F32_EA(UINT32 addr) { + FPU_FLD_F32(addr,8); +} +static INLINE void FPU_FLD_F64_EA(UINT32 addr) { + FPU_FLD_F64(addr,8); +} +static INLINE void FPU_FLD_I32_EA(UINT32 addr) { + FPU_FLD_I32(addr,8); +} +static INLINE void FPU_FLD_I16_EA(UINT32 addr) { + FPU_FLD_I16(addr,8); +} + +static void FPU_FST_F32(UINT32 addr) { + union { + float f; + UINT32 l; + } blah; + + //should depend on rounding method + blah.f = (float)(FPU_STAT.reg[FPU_STAT_TOP].d64); + fpu_memorywrite_d(addr,blah.l); +} + +static void FPU_FST_F64(UINT32 addr) { + fpu_memorywrite_d(addr,FPU_STAT.reg[FPU_STAT_TOP].l.lower); + fpu_memorywrite_d(addr+4,FPU_STAT.reg[FPU_STAT_TOP].l.upper); +} + +static void FPU_FST_F80(UINT32 addr) { + FPU_ST80(addr,FPU_STAT_TOP); +} + +static void FPU_FST_I16(UINT32 addr) { + if(FPU_STAT.int_regvalid[FPU_STAT_TOP]){ + fpu_memorywrite_w(addr,(SINT16)((SINT64)(FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12))); + }else{ + fpu_memorywrite_w(addr,(SINT16)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64))); + } +} + +static void FPU_FST_I32(UINT32 addr) { + if(FPU_STAT.int_regvalid[FPU_STAT_TOP]){ + fpu_memorywrite_d(addr,(SINT32)((SINT64)(FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12))); + }else{ + fpu_memorywrite_d(addr,(SINT32)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64))); + } +} + +static void FPU_FST_I64(UINT32 addr) { + FP_REG blah; + + if(FPU_STAT.int_regvalid[FPU_STAT_TOP]){ + blah.ll = (SINT64)FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12; + fpu_memorywrite_d(addr,blah.l.lower); + fpu_memorywrite_d(addr+4,blah.l.upper); + }else{ + blah.ll = (SINT64)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64)); + fpu_memorywrite_d(addr,blah.l.lower); + fpu_memorywrite_d(addr+4,blah.l.upper); + } +} + +static void FPU_FBST(UINT32 addr) +{ + FP_REG val; + UINT p; + UINT i; + BOOL sign; + double temp; + + val = FPU_STAT.reg[FPU_STAT_TOP]; + sign = FALSE; + if(FPU_STAT.reg[FPU_STAT_TOP].ll & QWORD_CONST(0x8000000000000000)) { //sign + sign=TRUE; + val.d64=-val.d64; + } + //numbers from back to front + temp=val.d64; + for(i=0;i<9;i++){ + val.d64=temp; + temp = (double)((SINT64)(floor(val.d64/10.0))); + p = (UINT)(val.d64 - 10.0*temp); + val.d64=temp; + temp = (double)((SINT64)(floor(val.d64/10.0))); + p |= ((UINT)(val.d64 - 10.0*temp)<<4); + + fpu_memorywrite_b(addr+i,p); + } + val.d64=temp; + temp = (double)((SINT64)(floor(val.d64/10.0))); + p = (UINT)(val.d64 - 10.0*temp); + if(sign) + p|=0x80; + fpu_memorywrite_b(addr+9,p); +} + +#define isinf(x) (!(_finite(x) || _isnan(x))) +#define isdenormal(x) (_fpclass(x) == _FPCLASS_ND || _fpclass(x) == _FPCLASS_PD) + +static void FPU_FADD(UINT op1, UINT op2){ + //// HACK: Set the denormal flag according to whether the source or final result is a denormalized number. + //// This is vital if we don't want certain DOS programs to mis-detect our FPU emulation as an IIT clone chip when cputype == 286 + //BOOL was_not_normal; + + //was_not_normal = isdenormal(FPU_STAT.reg[op1].d64); + //FPU_STAT.reg[op1].d64 += FPU_STAT.reg[op2].d64; + //FPU_SET_D(was_not_normal || isdenormal(FPU_STAT.reg[op1].d64) || isdenormal(FPU_STAT.reg[op2].d64)); + FPU_STAT.reg[op1].d64 += FPU_STAT.reg[op2].d64; + //flags and such :) + //if(FPU_STAT.int_regvalid[op1] && FPU_STAT.int_regvalid[op2]){ + // SINT64 v1 = (SINT64)FPU_STAT.int_reg[op1].ul64.m12; + // SINT64 v2 = (SINT64)FPU_STAT.int_reg[op2].ul64.m12; + // SINT64 v12 = v1+v2; + // if((v1>=0 && v2<=0) || (v1<=0 && v2>=0)){ // 符号が異なればオーバーフローしない + // FPU_STAT.int_reg[op1].ul64.m12 = (UINT64)v12; + // }else if((v1>0 && v2>0) && v12 > 0){ // XXX: 正+正→正 多分処理系依存 + // FPU_STAT.int_reg[op1].ul64.m12 = (UINT64)v12; + // }else if((v1<0 && v2<0) && v12 < 0){ // XXX: 負+負→負 多分処理系依存 + // FPU_STAT.int_reg[op1].ul64.m12 = (UINT64)v12; + // }else{ + // FPU_STAT.int_regvalid[op1] = 0; + // } + //}else{ + FPU_STAT.int_regvalid[op1] = 0; + //} + return; +} + +static void FPU_FSIN(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = sin(FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + FPU_SET_C2(0); + //flags and such :) + return; +} + +static void FPU_FSINCOS(void){ + double temp; + + temp = FPU_STAT.reg[FPU_STAT_TOP].d64; + FPU_STAT.reg[FPU_STAT_TOP].d64 = sin(temp); + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + FPU_PUSH(cos(temp)); + FPU_SET_C2(0); + //flags and such :) + return; +} + +static void FPU_FCOS(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = cos(FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + FPU_SET_C2(0); + //flags and such :) + return; +} + +static void FPU_FSQRT(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = sqrt(FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + //flags and such :) + return; +} +static void FPU_FPATAN(void){ + FPU_STAT.reg[FPU_ST(1)].d64 = atan2(FPU_STAT.reg[FPU_ST(1)].d64,FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_STAT.int_regvalid[FPU_ST(1)] = 0; + FPU_FPOP(); + //flags and such :) + return; +} +static void FPU_FPTAN(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = tan(FPU_STAT.reg[FPU_STAT_TOP].d64); + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + FPU_PUSH(1.0); + FPU_SET_C2(0); + //flags and such :) + return; +} +static void FPU_FDIV(UINT st, UINT other){ + if(FPU_STAT.reg[other].d64==0){ + FPU_STATUSWORD |= FP_ZE_FLAG; + if(!(FPU_CTRLWORD & FP_ZE_FLAG)) + return; + } + FPU_STAT.reg[st].d64= FPU_STAT.reg[st].d64/FPU_STAT.reg[other].d64; + FPU_STAT.int_regvalid[st] = 0; + //flags and such :) + return; +} + +static void FPU_FDIVR(UINT st, UINT other){ + if(FPU_STAT.reg[st].d64==0){ + FPU_STATUSWORD |= FP_ZE_FLAG; + if(!(FPU_CTRLWORD & FP_ZE_FLAG)) + return; + } + FPU_STAT.reg[st].d64= FPU_STAT.reg[other].d64/FPU_STAT.reg[st].d64; + FPU_STAT.int_regvalid[st] = 0; + // flags and such :) + return; +} + +static void FPU_FMUL(UINT st, UINT other){ + FPU_STAT.reg[st].d64*=FPU_STAT.reg[other].d64; + FPU_STAT.int_regvalid[st] = 0; + //flags and such :) + return; +} + +static void FPU_FSUB(UINT st, UINT other){ + FPU_STAT.reg[st].d64 = FPU_STAT.reg[st].d64 - FPU_STAT.reg[other].d64; + //if(FPU_STAT.int_regvalid[st] && FPU_STAT.int_regvalid[other]){ + // SINT64 v1 = (SINT64)FPU_STAT.int_reg[st].ul64.m12; + // SINT64 v2 = (SINT64)FPU_STAT.int_reg[other].ul64.m12; + // SINT64 v12 = v1-v2; + // if((v1>=0 && v2>=0) || (v1<=0 && v2<=0)){ // 符号が異なればオーバーフローしない + // FPU_STAT.int_reg[st].ul64.m12 = (UINT64)v12; + // }else if((v1>0 && v2<0) && v12 > 0){ // XXX: 正+正→正 多分処理系依存 + // FPU_STAT.int_reg[st].ul64.m12 = (UINT64)v12; + // }else if((v1<0 && v2>0) && v12 < 0){ // XXX: 負+負→負 多分処理系依存 + // FPU_STAT.int_reg[st].ul64.m12 = (UINT64)v12; + // }else{ + // FPU_STAT.int_regvalid[st] = 0; + // } + //}else{ + FPU_STAT.int_regvalid[st] = 0; + //} + //flags and such :) + return; +} + +static void FPU_FSUBR(UINT st, UINT other){ + FPU_STAT.reg[st].d64 = FPU_STAT.reg[other].d64 - FPU_STAT.reg[st].d64; + //if(FPU_STAT.int_regvalid[st] && FPU_STAT.int_regvalid[other]){ + // SINT64 v1 = (SINT64)FPU_STAT.int_reg[other].ul64.m12; + // SINT64 v2 = (SINT64)FPU_STAT.int_reg[st].ul64.m12; + // SINT64 v12 = v1-v2; + // if((v1>=0 && v2>=0) || (v1<=0 && v2<=0)){ // 符号が異なればオーバーフローしない + // FPU_STAT.int_reg[st].ul64.m12 = (UINT64)v12; + // }else if((v1>0 && v2<0) && v12 > 0){ // 正+正→正 多分処理系依存 + // FPU_STAT.int_reg[st].ul64.m12 = (UINT64)v12; + // }else if((v1<0 && v2>0) && v12 < 0){ // 負+負→負 多分処理系依存 + // FPU_STAT.int_reg[st].ul64.m12 = (UINT64)v12; + // }else{ + // FPU_STAT.int_regvalid[st] = 0; + // } + //}else{ + FPU_STAT.int_regvalid[st] = 0; + //} + //flags and such :) + return; +} + +static void FPU_FXCH(UINT st, UINT other){ + FP_TAG tag; + FP_REG reg; + UINT8 regvalid; + FP_INT_REG intreg; + + tag = FPU_STAT.tag[other]; + reg = FPU_STAT.reg[other]; + FPU_STAT.tag[other] = FPU_STAT.tag[st]; + FPU_STAT.reg[other] = FPU_STAT.reg[st]; + FPU_STAT.tag[st] = tag; + FPU_STAT.reg[st] = reg; + regvalid = FPU_STAT.int_regvalid[other]; + intreg = FPU_STAT.int_reg[other]; + FPU_STAT.int_regvalid[other] = FPU_STAT.int_regvalid[st]; + FPU_STAT.int_reg[other] = FPU_STAT.int_reg[st]; + FPU_STAT.int_regvalid[st] = regvalid; + FPU_STAT.int_reg[st] = intreg; +} + +static void FPU_FST(UINT st, UINT other){ + FPU_STAT.tag[other] = FPU_STAT.tag[st]; + FPU_STAT.reg[other] = FPU_STAT.reg[st]; + FPU_STAT.int_regvalid[other] = FPU_STAT.int_regvalid[st]; + FPU_STAT.int_reg[other] = FPU_STAT.int_reg[st]; +} + +static void FPU_FCOM(UINT st, UINT other){ + if(((FPU_STAT.tag[st] != TAG_Valid) && (FPU_STAT.tag[st] != TAG_Zero)) || + ((FPU_STAT.tag[other] != TAG_Valid) && (FPU_STAT.tag[other] != TAG_Zero))){ + FPU_SET_C3(1); + FPU_SET_C2(1); + FPU_SET_C0(1); + return; + } + + if(FPU_STAT.reg[st].d64 == FPU_STAT.reg[other].d64){ + FPU_SET_C3(1); + FPU_SET_C2(0); + FPU_SET_C0(0); + return; + } + if(FPU_STAT.reg[st].d64 < FPU_STAT.reg[other].d64){ + FPU_SET_C3(0); + FPU_SET_C2(0); + FPU_SET_C0(1); + return; + } + // st > other + FPU_SET_C3(0); + FPU_SET_C2(0); + FPU_SET_C0(0); + return; +} +static void FPU_FCOMI(UINT st, UINT other){ + if(((FPU_STAT.tag[st] != TAG_Valid) && (FPU_STAT.tag[st] != TAG_Zero)) || + ((FPU_STAT.tag[other] != TAG_Valid) && (FPU_STAT.tag[other] != TAG_Zero))){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | P_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + return; + } + + if(FPU_STAT.reg[st].d64 == FPU_STAT.reg[other].d64){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + return; + } + if(FPU_STAT.reg[st].d64 < FPU_STAT.reg[other].d64){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + return; + } + // st > other + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + return; +} + +static void FPU_FUCOM(UINT st, UINT other){ + //does atm the same as fcom + FPU_FCOM(st,other); +} +static void FPU_FUCOMI(UINT st, UINT other){ + //does atm the same as fcomi + FPU_FCOMI(st,other); +} + +static void FPU_FCMOVB(UINT st, UINT other){ + if(CPU_FLAGL & C_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} +static void FPU_FCMOVE(UINT st, UINT other){ + if(CPU_FLAGL & Z_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} +static void FPU_FCMOVBE(UINT st, UINT other){ + if(CPU_FLAGL & (C_FLAG|Z_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} +static void FPU_FCMOVU(UINT st, UINT other){ + if(CPU_FLAGL & P_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} + +static void FPU_FCMOVNB(UINT st, UINT other){ + if(!(CPU_FLAGL & C_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} +static void FPU_FCMOVNE(UINT st, UINT other){ + if(!(CPU_FLAGL & Z_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} +static void FPU_FCMOVNBE(UINT st, UINT other){ + if(!(CPU_FLAGL & (C_FLAG|Z_FLAG))){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} +static void FPU_FCMOVNU(UINT st, UINT other){ + if(!(CPU_FLAGL & P_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + FPU_STAT.int_regvalid[st] = FPU_STAT.int_regvalid[other]; + FPU_STAT.int_reg[st] = FPU_STAT.int_reg[other]; + } +} + +static void FPU_FRNDINT(void){ + SINT64 temp; + + temp = (SINT64)(FROUND(FPU_STAT.reg[FPU_STAT_TOP].d64)); + FPU_STAT.reg[FPU_STAT_TOP].d64=(double)(temp); + if(!FPU_STAT.int_regvalid[FPU_STAT_TOP]){ + FPU_STAT.int_reg[FPU_STAT_TOP].l64.m12 = temp; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 1; + }else{ + // 既に整数 + } +} + +static void FPU_FPREM(void){ + double valtop; + double valdiv; + SINT64 ressaved; + + valtop = FPU_STAT.reg[FPU_STAT_TOP].d64; + valdiv = FPU_STAT.reg[FPU_ST(1)].d64; + ressaved = (SINT64)( (valtop/valdiv) ); +// Some backups +// Real64 res=valtop - ressaved*valdiv; +// res= fmod(valtop,valdiv); + FPU_STAT.reg[FPU_STAT_TOP].d64 = valtop - ressaved*valdiv; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + FPU_SET_C0((UINT)(ressaved&4)); + FPU_SET_C3((UINT)(ressaved&2)); + FPU_SET_C1((UINT)(ressaved&1)); + FPU_SET_C2(0); +} + +static void FPU_FPREM1(void){ + double valtop; + double valdiv, quot, quotf; + SINT64 ressaved; + + valtop = FPU_STAT.reg[FPU_STAT_TOP].d64; + valdiv = FPU_STAT.reg[FPU_ST(1)].d64; + quot = valtop/valdiv; + quotf = floor(quot); + + if (quot-quotf>0.5) ressaved = (SINT64)(quotf+1); + else if (quot-quotf<0.5) ressaved = (SINT64)(quotf); + else ressaved = (SINT64)(((((SINT64)(quotf))&1)!=0)?(quotf+1):(quotf)); + + FPU_STAT.reg[FPU_STAT_TOP].d64 = valtop - ressaved*valdiv; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + FPU_SET_C0((UINT)(ressaved&4)); + FPU_SET_C3((UINT)(ressaved&2)); + FPU_SET_C1((UINT)(ressaved&1)); + FPU_SET_C2(0); +} + +static void FPU_FXAM(void){ + if(FPU_STAT.reg[FPU_STAT_TOP].ll & QWORD_CONST(0x8000000000000000)) //sign + { + FPU_SET_C1(1); + } + else + { + FPU_SET_C1(0); + } + if(FPU_STAT.tag[FPU_STAT_TOP] == TAG_Empty) + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); + return; + } + if(FPU_STAT.reg[FPU_STAT_TOP].d64 == 0.0) //zero or normalized number. + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0); + } + else + { + FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0); + } +} + +static void FPU_F2XM1(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = pow(2.0,FPU_STAT.reg[FPU_STAT_TOP].d64) - 1; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + return; +} + +static void FPU_FYL2X(void){ + FPU_STAT.reg[FPU_ST(1)].d64*=log(FPU_STAT.reg[FPU_STAT_TOP].d64)/log((double)(2.0)); + FPU_STAT.int_regvalid[FPU_ST(1)] = 0; + FPU_FPOP(); + return; +} + +static void FPU_FYL2XP1(void){ + FPU_STAT.reg[FPU_ST(1)].d64*=log(FPU_STAT.reg[FPU_STAT_TOP].d64+1.0)/log((double)(2.0)); + FPU_STAT.int_regvalid[FPU_ST(1)] = 0; + FPU_FPOP(); + return; +} + +static void FPU_FSCALE(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 *= pow(2.0,(double)((SINT64)(FPU_STAT.reg[FPU_ST(1)].d64))); + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + return; //2^x where x is chopped. +} + +static void FPU_FSTENV(UINT32 addr) +{ + descriptor_t *sdp = &CPU_CS_DESC; + FPU_SET_TOP(FPU_STAT_TOP); + + switch ((CPU_CR0 & 1) | (SEG_IS_32BIT(sdp) ? 0x100 : 0x000)) + { + case 0x000: case 0x001: + fpu_memorywrite_w(addr+0,FPU_CTRLWORD); + fpu_memorywrite_w(addr+2,FPU_STATUSWORD); + fpu_memorywrite_w(addr+4,FPU_GetTag()); + fpu_memorywrite_w(addr+10,FPU_LASTINSTOP); + break; + + case 0x100: case 0x101: + fpu_memorywrite_d(addr+0,(UINT32)(FPU_CTRLWORD)); + fpu_memorywrite_d(addr+4,(UINT32)(FPU_STATUSWORD)); + fpu_memorywrite_d(addr+8,(UINT32)(FPU_GetTag())); + fpu_memorywrite_d(addr+20,FPU_LASTINSTOP); + break; + } +} + +static void FPU_FLDENV(UINT32 addr) +{ + descriptor_t *sdp = &CPU_CS_DESC; + + switch ((CPU_CR0 & 1) | (SEG_IS_32BIT(sdp) ? 0x100 : 0x000)) { + case 0x000: case 0x001: + FPU_SetCW(fpu_memoryread_w(addr+0)); + FPU_STATUSWORD = fpu_memoryread_w(addr+2); + FPU_SetTag(fpu_memoryread_w(addr+4)); + FPU_LASTINSTOP = fpu_memoryread_w(addr+10); + break; + + case 0x100: case 0x101: + FPU_SetCW((UINT16)fpu_memoryread_d(addr+0)); + FPU_STATUSWORD = (UINT16)fpu_memoryread_d(addr+4); + FPU_SetTag((UINT16)fpu_memoryread_d(addr+8)); + FPU_LASTINSTOP = (UINT16)fpu_memoryread_d(addr+20); + break; + } + FPU_STAT_TOP = FPU_GET_TOP(); +} + +static void FPU_FSAVE(UINT32 addr) +{ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + FPU_FSTENV(addr); + start = ((SEG_IS_32BIT(sdp))?28:14); + for(i = 0;i < 8;i++){ + FPU_ST80(addr+start,FPU_ST(i)); + start += 10; + } + FPU_FINIT(); +} + +static void FPU_FRSTOR(UINT32 addr) +{ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + FPU_FLDENV(addr); + start = ((SEG_IS_32BIT(sdp))?28:14); + for(i = 0;i < 8;i++){ + FPU_FLD80(addr+start, FPU_ST(i)); + start += 10; + } +} + +static void FPU_FXSAVE(UINT32 addr){ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + //FPU_FSTENV(addr); + FPU_SET_TOP(FPU_STAT_TOP); + fpu_memorywrite_w(addr+0,FPU_CTRLWORD); + fpu_memorywrite_w(addr+2,FPU_STATUSWORD); + fpu_memorywrite_b(addr+4,FPU_GetTag8()); +#ifdef USE_SSE + fpu_memorywrite_d(addr+24,SSE_MXCSR); +#endif + start = 32; + for(i = 0;i < 8;i++){ + //FPU_ST80(addr+start,FPU_ST(i)); + fpu_memorywrite_d(addr+start+0,FPU_STAT.reg[FPU_ST(i)].l.lower); + fpu_memorywrite_d(addr+start+4,FPU_STAT.reg[FPU_ST(i)].l.upper); + if(FPU_STAT.int_regvalid[FPU_ST(i)]){ + fpu_memorywrite_d(addr+start+8,FPU_STAT.int_reg[FPU_ST(i)].ul32.m1); + fpu_memorywrite_d(addr+start+12,FPU_STAT.int_reg[FPU_ST(i)].ul32.m2); + }else{ + fpu_memorywrite_d(addr+start+8,0x00000000); + fpu_memorywrite_d(addr+start+12,0x00000000); + } + start += 16; + } +#ifdef USE_SSE + start = 160; + for(i = 0;i < 8;i++){ + fpu_memorywrite_q(addr+start+0,SSE_XMMREG(i).ul64[0]); + fpu_memorywrite_q(addr+start+8,SSE_XMMREG(i).ul64[1]); + start += 16; + } +#endif +} +static void FPU_FXRSTOR(UINT32 addr){ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + //FPU_FLDENV(addr); + FPU_SetCW(fpu_memoryread_w(addr+0)); + FPU_STATUSWORD = fpu_memoryread_w(addr+2); + FPU_SetTag8(fpu_memoryread_b(addr+4)); + FPU_STAT_TOP = FPU_GET_TOP(); +#ifdef USE_SSE + SSE_MXCSR = fpu_memoryread_d(addr+24); +#endif + start = 32; + for(i = 0;i < 8;i++){ + //FPU_STAT.reg[FPU_ST(i)].d64 = FPU_FLD80(addr+start); + FPU_STAT.reg[FPU_ST(i)].l.lower = fpu_memoryread_d(addr+start+0); + FPU_STAT.reg[FPU_ST(i)].l.upper = fpu_memoryread_d(addr+start+4); + FPU_STAT.int_reg[FPU_ST(i)].ul32.m1 = fpu_memoryread_d(addr+start+8); + FPU_STAT.int_reg[FPU_ST(i)].ul32.m2 = fpu_memoryread_d(addr+start+12); + if(FPU_STAT.int_reg[FPU_ST(i)].ul64.m12){ + FPU_STAT.int_regvalid[FPU_ST(i)] = 1; + }else{ + FPU_STAT.int_regvalid[FPU_ST(i)] = 0; + } + start += 16; + } +#ifdef USE_SSE + start = 160; + for(i = 0;i < 8;i++){ + SSE_XMMREG(i).ul64[0] = fpu_memoryread_q(addr+start+0); + SSE_XMMREG(i).ul64[1] = fpu_memoryread_q(addr+start+8); + start += 16; + } +#endif +} + +void DB2_FPU_FXSAVERSTOR(void){ + UINT32 op; + UINT idx, sub; + UINT32 maddr; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION2(); // XXX: 根拠無し + switch(idx){ + case 0: // FXSAVE + maddr = calc_ea_dst(op); + FPU_FXSAVE(maddr); + break; + case 1: // FXRSTOR + maddr = calc_ea_dst(op); + FPU_FXRSTOR(maddr); + break; +#ifdef USE_SSE + case 2: // LDMXCSR + maddr = calc_ea_dst(op); + SSE_LDMXCSR(maddr); + break; + case 3: // STMXCSR + maddr = calc_ea_dst(op); + SSE_STMXCSR(maddr); + break; + case 4: // SFENCE + SSE_SFENCE(); + break; + case 5: // LFENCE + SSE_LFENCE(); + break; + case 6: // MFENCE + SSE_MFENCE(); + break; + case 7: // CLFLUSH; + SSE_CLFLUSH(op); + break; +#endif + default: + ia32_panic("invalid opcode = %02x\n", op); + break; + } +} + +static void FPU_FXTRACT(void) { + // function stores real bias in st and + // pushes the significant number onto the stack + // if double ever uses a different base please correct this function + FP_REG test; + SINT64 exp80, exp80final; + double mant; + + test = FPU_STAT.reg[FPU_STAT_TOP]; + exp80 = test.ll&QWORD_CONST(0x7ff0000000000000); + exp80final = (exp80>>52) - BIAS64; + mant = test.d64 / (pow(2.0,(double)(exp80final))); + FPU_STAT.reg[FPU_STAT_TOP].d64 = (double)(exp80final); + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + FPU_PUSH(mant); +} + +static void FPU_FCHS(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = -1.0*(FPU_STAT.reg[FPU_STAT_TOP].d64); + if(FPU_STAT.int_regvalid[FPU_STAT_TOP]){ + if(FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12 != QWORD_CONST(0x8000000000000000)){ + FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12 = (~FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12) + 1; // 符号反転 + }else{ + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + } + } +} + +static void FPU_FABS(void){ + FPU_STAT.reg[FPU_STAT_TOP].d64 = fabs(FPU_STAT.reg[FPU_STAT_TOP].d64); + if(FPU_STAT.int_regvalid[FPU_STAT_TOP]){ + if((QWORD_CONST(0x8000000000000000) & FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12)!=0 && + (FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12 != QWORD_CONST(0x8000000000000000))){ + FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12 = (~FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12) + 1; // 符号反転 + }else{ + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; + } + } +} + +static void FPU_FTST(void){ + FPU_STAT.reg[8].d64 = 0.0; + FPU_FCOM(FPU_STAT_TOP,8); +} + +static void FPU_FLD1(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = 1.0; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; +} + +static void FPU_FLDL2T(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = L2T; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; +} + +static void FPU_FLDL2E(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = L2E; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; +} + +static void FPU_FLDPI(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = PI; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; +} + +static void FPU_FLDLG2(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = LG2; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; +} + +static void FPU_FLDLN2(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = LN2; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 0; +} + +static void FPU_FLDZ(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d64 = 0.0; + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Zero; + FPU_STAT.int_reg[FPU_STAT_TOP].ul64.m12 = 0; + FPU_STAT.int_regvalid[FPU_STAT_TOP] = 1; +} + + +static INLINE void FPU_FADD_EA(UINT op1){ + FPU_FADD(op1,8); +} +static INLINE void FPU_FMUL_EA(UINT op1){ + FPU_FMUL(op1,8); +} +static INLINE void FPU_FSUB_EA(UINT op1){ + FPU_FSUB(op1,8); +} +static INLINE void FPU_FSUBR_EA(UINT op1){ + FPU_FSUBR(op1,8); +} +static INLINE void FPU_FDIV_EA(UINT op1){ + FPU_FDIV(op1,8); +} +static INLINE void FPU_FDIVR_EA(UINT op1){ + FPU_FDIVR(op1,8); +} +static INLINE void FPU_FCOM_EA(UINT op1){ + FPU_FCOM(op1,8); +} + +/* + * FPU interface + */ +//int fpu_updateEmuEnv(void); +static void +FPU_FINIT(void) +{ + int i; + FPU_SetCW(0x37F); + FPU_STATUSWORD = 0; + FPU_STAT_TOP=FPU_GET_TOP(); + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = TAG_Empty; + FPU_STAT.int_regvalid[i] = 0; + // レジスタの内容は消してはいけない ver0.86 rev40 + //FPU_STAT.reg[i].d64 = 0; + //FPU_STAT.reg[i].l.lower = 0; + //FPU_STAT.reg[i].l.upper = 0; + //FPU_STAT.reg[i].ll = 0; + } + FPU_STAT.tag[8] = TAG_Valid; // is only used by us +} +void DB2_FPU_FINIT(void){ + int i; + FPU_FINIT(); + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = TAG_Empty; + FPU_STAT.reg[i].l.ext = 0; + FPU_STAT.reg[i].l.lower = 0; + FPU_STAT.reg[i].l.upper = 0; + } +} + +//char * +//fpu_reg2str(void) +//{ +// return NULL; +//} + + +/* + * FPU instruction + */ + +static void fpu_checkexception(){ + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & 0x3F){ + EXCEPTION(MF_EXCEPTION, 0); + } +} + +static void EA_TREE(UINT op) +{ + UINT idx; + + idx = (op >> 3) & 7; + + switch (idx) { + case 0: /* FADD (単精度実数) */ + TRACEOUT(("FADD EA")); + FPU_FADD_EA(FPU_STAT_TOP); + break; + case 1: /* FMUL (単精度実数) */ + TRACEOUT(("FMUL EA")); + FPU_FMUL_EA(FPU_STAT_TOP); + break; + case 2: /* FCOM (単精度実数) */ + TRACEOUT(("FCOM EA")); + FPU_FCOM_EA(FPU_STAT_TOP); + break; + case 3: /* FCOMP (単精度実数) */ + TRACEOUT(("FCOMP EA")); + FPU_FCOM_EA(FPU_STAT_TOP); + FPU_FPOP(); + break; + case 4: /* FSUB (単精度実数) */ + TRACEOUT(("FSUB EA")); + FPU_FSUB_EA(FPU_STAT_TOP); + break; + case 5: /* FSUBR (単精度実数) */ + TRACEOUT(("FSUBR EA")); + FPU_FSUBR_EA(FPU_STAT_TOP); + break; + case 6: /* FDIV (単精度実数) */ + TRACEOUT(("FDIV EA")); + FPU_FDIV_EA(FPU_STAT_TOP); + break; + case 7: /* FDIVR (単精度実数) */ + TRACEOUT(("FDIVR EA")); + FPU_FDIVR_EA(FPU_STAT_TOP); + break; + default: + break; + } +} + +// d8 +void +DB2_ESC0(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU d8 %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FADD */ + TRACEOUT(("FADD")); + FPU_FADD(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FMUL */ + TRACEOUT(("FMUL")); + FPU_FMUL(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCOM */ + TRACEOUT(("FCOM")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMP */ + TRACEOUT(("FCOMP")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FSUB */ + TRACEOUT(("FSUB")); + FPU_FSUB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: /* FSUBR */ + TRACEOUT(("FSUBR")); + FPU_FSUBR(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 6: /* FDIV */ + TRACEOUT(("FDIV")); + FPU_FDIV(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 7: /* FDIVR */ + TRACEOUT(("FDIVR")); + FPU_FDIVR(FPU_STAT_TOP,FPU_ST(sub)); + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_F32_EA(madr); + EA_TREE(op); + } +} + +// d9 +void +DB2_ESC1(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU d9 %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op < 0xc0 && idx>=4)){ + fpu_checkexception(); + } + if (op >= 0xc0) + { + switch (idx) { + case 0: /* FLD ST(0), ST(i) */ + { + UINT reg_from; + + TRACEOUT(("FLD STi")); + reg_from = FPU_ST(sub); + FPU_PREP_PUSH(); + FPU_FST(reg_from, FPU_STAT_TOP); + } + break; + + case 1: /* FXCH ST(0), ST(i) */ + TRACEOUT(("FXCH STi")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + + case 2: /* FNOP */ + TRACEOUT(("FNOP")); + FPU_FNOP(); + break; + + case 3: /* FSTP STi */ + TRACEOUT(("FSTP STi")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + case 4: + switch (sub) { + case 0x0: /* FCHS */ + TRACEOUT(("FCHS")); + FPU_FCHS(); + break; + + case 0x1: /* FABS */ + TRACEOUT(("FABS")); + FPU_FABS(); + break; + + case 0x2: /* UNKNOWN */ + case 0x3: /* ILLEGAL */ + break; + + case 0x4: /* FTST */ + TRACEOUT(("FTST")); + FPU_FTST(); + break; + + case 0x5: /* FXAM */ + TRACEOUT(("FXAM")); + FPU_FXAM(); + break; + + case 0x06: /* FTSTP (cyrix)*/ + case 0x07: /* UNKNOWN */ + break; + } + break; + + case 5: + switch (sub) { + case 0x0: /* FLD1 */ + TRACEOUT(("FLD1")); + FPU_FLD1(); + break; + + case 0x1: /* FLDL2T */ + TRACEOUT(("FLDL2T")); + FPU_FLDL2T(); + break; + + case 0x2: /* FLDL2E */ + TRACEOUT(("FLDL2E")); + FPU_FLDL2E(); + break; + + case 0x3: /* FLDPI */ + TRACEOUT(("FLDPI")); + FPU_FLDPI(); + break; + + case 0x4: /* FLDLG2 */ + TRACEOUT(("FLDLG2")); + FPU_FLDLG2(); + break; + + case 0x5: /* FLDLN2 */ + TRACEOUT(("FLDLN2")); + FPU_FLDLN2(); + break; + + case 0x6: /* FLDZ */ + TRACEOUT(("FLDZ")); + FPU_FLDZ(); + break; + + case 0x07: /* ILLEGAL */ + break; + } + break; + + case 6: + switch (sub) { + case 0x0: /* F2XM1 */ + TRACEOUT(("F2XM1")); + FPU_F2XM1(); + break; + + case 0x1: /* FYL2X */ + TRACEOUT(("FYL2X")); + FPU_FYL2X(); + break; + + case 0x2: /* FPTAN */ + TRACEOUT(("FPTAN")); + FPU_FPTAN(); + break; + + case 0x3: /* FPATAN */ + TRACEOUT(("FPATAN")); + FPU_FPATAN(); + break; + + case 0x4: /* FXTRACT */ + TRACEOUT(("FXTRACT")); + FPU_FXTRACT(); + break; + + case 0x5: /* FPREM1 */ + TRACEOUT(("FPREM1")); + FPU_FPREM1(); + break; + + case 0x6: /* FDECSTP */ + TRACEOUT(("FDECSTP")); + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + break; + + case 0x7: /* FINCSTP */ + TRACEOUT(("FINCSTP")); + FPU_STAT_TOP = (FPU_STAT_TOP + 1) & 7; + break; + } + break; + + case 7: + switch (sub) { + case 0x0: /* FPREM */ + TRACEOUT(("FPREM")); + FPU_FPREM(); + break; + + case 0x1: /* FYL2XP1 */ + TRACEOUT(("FYL2XP1")); + FPU_FYL2XP1(); + break; + + case 0x2: /* FSQRT */ + TRACEOUT(("FSQRT")); + FPU_FSQRT(); + break; + + case 0x3: /* FSINCOS */ + TRACEOUT(("FSINCOS")); + FPU_FSINCOS(); + break; + + case 0x4: /* FRNDINT */ + TRACEOUT(("FRNDINT")); + FPU_FRNDINT(); + break; + + case 0x5: /* FSCALE */ + TRACEOUT(("FSCALE")); + FPU_FSCALE(); + break; + + case 0x6: /* FSIN */ + TRACEOUT(("FSIN")); + FPU_FSIN(); + break; + + case 0x7: /* FCOS */ + TRACEOUT(("FCOS")); + FPU_FCOS(); + break; + } + break; + + default: + ia32_panic("ESC1: invalid opcode = %02x\n", op); + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FLD (単精度実数) */ + TRACEOUT(("FLD float")); + FPU_PREP_PUSH(); + FPU_FLD_F32(madr,FPU_STAT_TOP); + break; + + case 1: /* UNKNOWN */ + break; + + case 2: /* FST (単精度実数) */ + TRACEOUT(("FST float")); + FPU_FST_F32(madr); + break; + + case 3: /* FSTP (単精度実数) */ + TRACEOUT(("FSTP float")); + FPU_FST_F32(madr); + FPU_FPOP(); + break; + + case 4: /* FLDENV */ + TRACEOUT(("FLDENV")); + FPU_FLDENV(madr); + break; + + case 5: /* FLDCW */ + TRACEOUT(("FLDCW")); + FPU_FLDCW(madr); + break; + + case 6: /* FSTENV */ + TRACEOUT(("FSTENV")); + FPU_FSTENV(madr); + break; + + case 7: /* FSTCW */ + TRACEOUT(("FSTCW/FNSTCW")); + fpu_memorywrite_w(madr,FPU_CTRLWORD); + break; + + default: + break; + } + } +} + +// da +void +DB2_ESC2(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU da %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FCMOVB */ + TRACEOUT(("ESC2: FCMOVB")); + FPU_FCMOVB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FCMOVE */ + TRACEOUT(("ESC2: FCMOVE")); + FPU_FCMOVE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCMOVBE */ + TRACEOUT(("ESC2: FCMOVBE")); + FPU_FCMOVBE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCMOVU */ + TRACEOUT(("ESC2: FCMOVU")); + FPU_FCMOVU(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: + switch (sub) { + case 1: /* FUCOMPP */ + TRACEOUT(("FUCOMPP")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(1)); + FPU_FPOP(); + FPU_FPOP(); + break; + + default: + break; + } + break; + + default: + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_I32_EA(madr); + EA_TREE(op); + } +} + +// db +void +DB2_ESC3(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU db %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op >= 0xc0 && idx==4)){ + fpu_checkexception(); + } + if (op >= 0xc0) + { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FCMOVNB */ + TRACEOUT(("ESC3: FCMOVNB")); + FPU_FCMOVNB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FCMOVNE */ + TRACEOUT(("ESC3: FCMOVNE")); + FPU_FCMOVNE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCMOVNBE */ + TRACEOUT(("ESC3: FCMOVNBE")); + FPU_FCMOVNBE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCMOVNU */ + TRACEOUT(("ESC3: FCMOVNU")); + FPU_FCMOVNU(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 4: + switch (sub) { + case 0: /* FNENI */ + case 1: /* FNDIS */ + break; + + case 2: /* FCLEX */ + TRACEOUT(("FCLEX")); + FPU_FCLEX(); + break; + + case 3: /* FNINIT/FINIT */ + TRACEOUT(("FNINIT/FINIT")); + FPU_FINIT(); + break; + + case 4: /* FNSETPM */ + case 5: /* FRSTPM */ + FPU_FNOP(); + break; + + default: + break; + } + break; + case 5: /* FUCOMI */ + TRACEOUT(("ESC3: FUCOMI")); + FPU_FUCOMI(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 6: /* FCOMI */ + TRACEOUT(("ESC3: FCOMI")); + FPU_FCOMI(FPU_STAT_TOP,FPU_ST(sub)); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FILD (DWORD) */ + TRACEOUT(("FILD")); + FPU_PREP_PUSH(); + FPU_FLD_I32(madr,FPU_STAT_TOP); + break; + + case 1: /* FISTTP (DWORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + FP_RND oldrnd = FPU_STAT.round; + FPU_STAT.round = ROUND_Down; + FPU_FST_I32(madr); + FPU_STAT.round = oldrnd; + } + FPU_FPOP(); + } + break; + + case 2: /* FIST (DWORD) */ + TRACEOUT(("FIST")); + FPU_FST_I32(madr); + break; + + case 3: /* FISTP (DWORD) */ + TRACEOUT(("FISTP")); + FPU_FST_I32(madr); + FPU_FPOP(); + break; + + case 5: /* FLD (拡張実数) */ + TRACEOUT(("FLD 80 Bits Real")); + FPU_PREP_PUSH(); + FPU_FLD_F80(madr); + break; + + case 7: /* FSTP (拡張実数) */ + TRACEOUT(("FSTP 80 Bits Real")); + FPU_FST_F80(madr); + FPU_FPOP(); + break; + + default: + break; + } + } +} + +// dc +void +DB2_ESC4(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU dc %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(i), ST(0) */ + switch (idx) { + case 0: /* FADD */ + TRACEOUT(("ESC4: FADD")); + FPU_FADD(FPU_ST(sub),FPU_STAT_TOP); + break; + case 1: /* FMUL */ + TRACEOUT(("ESC4: FMUL")); + FPU_FMUL(FPU_ST(sub),FPU_STAT_TOP); + break; + case 2: /* FCOM */ + TRACEOUT(("ESC4: FCOM")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMP */ + TRACEOUT(("ESC4: FCOMP")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FSUBR */ + TRACEOUT(("ESC4: FSUBR")); + FPU_FSUBR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 5: /* FSUB */ + TRACEOUT(("ESC4: FSUB")); + FPU_FSUB(FPU_ST(sub),FPU_STAT_TOP); + break; + case 6: /* FDIVR */ + TRACEOUT(("ESC4: FDIVR")); + FPU_FDIVR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 7: /* FDIV */ + TRACEOUT(("ESC4: FDIV")); + FPU_FDIV(FPU_ST(sub),FPU_STAT_TOP); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_F64_EA(madr); + EA_TREE(op); + } +} + +// dd +void +DB2_ESC5(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU dd %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + fpu_check_NM_EXCEPTION(); + //if(op < 0xc0 && (idx==6 || idx==4)){ + // _ADD_EIP(-1); // XXX: 無理やり戻す + // fpu_check_NM_EXCEPTION2(); + // _ADD_EIP(1); + //}else{ + // _ADD_EIP(-1); // XXX: 無理やり戻す + // fpu_check_NM_EXCEPTION(); + // _ADD_EIP(1); + //} + if(op >= 0xc0 || (idx!=4 && idx!=6 && idx!=7)){ + fpu_checkexception(); + } + if (op >= 0xc0) { + /* FUCOM ST(i), ST(0) */ + /* Fxxx ST(i) */ + switch (idx) { + case 0: /* FFREE */ + TRACEOUT(("FFREE")); + FPU_STAT.tag[FPU_ST(sub)]=TAG_Empty; + break; + case 1: /* FXCH */ + TRACEOUT(("FXCH")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FST */ + TRACEOUT(("FST")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FSTP */ + TRACEOUT(("FSTP")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FUCOM */ + TRACEOUT(("FUCOM")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: /* FUCOMP */ + TRACEOUT(("FUCOMP")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FLD (倍精度実数) */ + TRACEOUT(("FLD double real")); + FPU_PREP_PUSH(); + FPU_FLD_F64(madr,FPU_STAT_TOP); + break; + case 1: /* FISTTP (QWORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + FP_RND oldrnd = FPU_STAT.round; + FPU_STAT.round = ROUND_Down; + FPU_FST_I64(madr); + FPU_STAT.round = oldrnd; + } + FPU_FPOP(); + } + break; + case 2: /* FST (倍精度実数) */ + TRACEOUT(("FST double real")); + FPU_FST_F64(madr); + break; + case 3: /* FSTP (倍精度実数) */ + TRACEOUT(("FSTP double real")); + FPU_FST_F64(madr); + FPU_FPOP(); + break; + case 4: /* FRSTOR */ + TRACEOUT(("FRSTOR")); + FPU_FRSTOR(madr); + break; + case 6: /* FSAVE */ + TRACEOUT(("FSAVE")); + FPU_FSAVE(madr); + break; + + case 7: /* FSTSW */ + FPU_SET_TOP(FPU_STAT_TOP); + //cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, FPU_CTRLWORD); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, FPU_STATUSWORD); + break; + + default: + break; + } + } +} + +// de +void +DB2_ESC6(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU de %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(i), ST(0) */ + switch (idx) { + case 0: /* FADDP */ + TRACEOUT(("FADDP")); + FPU_FADD(FPU_ST(sub),FPU_STAT_TOP); + break; + case 1: /* FMULP */ + TRACEOUT(("FMULP")); + FPU_FMUL(FPU_ST(sub),FPU_STAT_TOP); + break; + case 2: /* FCOMP5 */ + TRACEOUT(("FCOMP5")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMPP */ + TRACEOUT(("FCOMPP")); + if(sub != 1) { + return; + } + FPU_FCOM(FPU_STAT_TOP,FPU_ST(1)); + FPU_FPOP(); /* extra pop at the bottom*/ + break; + case 4: /* FSUBRP */ + TRACEOUT(("FSUBRP")); + FPU_FSUBR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 5: /* FSUBP */ + TRACEOUT(("FSUBP")); + FPU_FSUB(FPU_ST(sub),FPU_STAT_TOP); + break; + case 6: /* FDIVRP */ + TRACEOUT(("FDIVRP")); + FPU_FDIVR(FPU_ST(sub),FPU_STAT_TOP); + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & FP_ZE_FLAG){ + return; // POPしないようにする + } + break; + case 7: /* FDIVP */ + TRACEOUT(("FDIVP")); + FPU_FDIV(FPU_ST(sub),FPU_STAT_TOP); + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & FP_ZE_FLAG){ + return; // POPしないようにする + } + break; + /*FALLTHROUGH*/ + default: + break; + } + FPU_FPOP(); + } else { + madr = calc_ea_dst(op); + FPU_FLD_I16_EA(madr); + EA_TREE(op); + } +} + +// df +void +DB2_ESC7(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU df %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op >= 0xc0 && idx==4 && sub==0)){ + fpu_checkexception(); + } + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FFREEP */ + TRACEOUT(("FFREEP")); + FPU_STAT.tag[FPU_ST(sub)]=TAG_Empty; + FPU_FPOP(); + break; + case 1: /* FXCH */ + TRACEOUT(("FXCH")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + + case 2: + case 3: /* FSTP */ + TRACEOUT(("FSTP")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + case 4: + switch (sub) + { + case 0: /* FSTSW AX */ + TRACEOUT(("FSTSW AX")); + FPU_SET_TOP(FPU_STAT_TOP); + CPU_AX = FPU_STATUSWORD; + break; + + default: + break; + } + break; + case 5: /* FUCOMIP */ + TRACEOUT(("ESC7: FUCOMIP")); + FPU_FUCOMI(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 6: /* FCOMIP */ + TRACEOUT(("ESC7: FCOMIP")); + FPU_FCOMI(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FILD (WORD) */ + TRACEOUT(("FILD SINT16")); + FPU_PREP_PUSH(); + FPU_FLD_I16(madr,FPU_STAT_TOP); + break; + case 1: /* FISTTP (WORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + FP_RND oldrnd = FPU_STAT.round; + FPU_STAT.round = ROUND_Down; + FPU_FST_I16(madr); + FPU_STAT.round = oldrnd; + } + FPU_FPOP(); + } + break; + case 2: /* FIST (WORD) */ + TRACEOUT(("FIST SINT16")); + FPU_FST_I16(madr); + break; + case 3: /* FISTP (WORD) */ + TRACEOUT(("FISTP SINT16")); + FPU_FST_I16(madr); + FPU_FPOP(); + break; + + case 4: /* FBLD (BCD) */ + TRACEOUT(("FBLD packed BCD")); + FPU_PREP_PUSH(); + FPU_FBLD(madr,FPU_STAT_TOP); + break; + + case 5: /* FILD (QWORD) */ + TRACEOUT(("FILD SINT64")); + FPU_PREP_PUSH(); + FPU_FLD_I64(madr,FPU_STAT_TOP); + break; + + case 6: /* FBSTP (BCD) */ + TRACEOUT(("FBSTP packed BCD")); + FPU_FBST(madr); + FPU_FPOP(); + break; + + case 7: /* FISTP (QWORD) */ + TRACEOUT(("FISTP SINT64")); + FPU_FST_I64(madr); + FPU_FPOP(); + break; + + default: + break; + } + } +} +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_softfloat.cpp b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_softfloat.cpp new file mode 100644 index 000000000..db9a3407b --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpemul_softfloat.cpp @@ -0,0 +1,2018 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Copyright (c) 2012 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * modified by SimK + */ + +//#include "compiler.h" +#include "../../cpu.h" + +#if defined(USE_FPU) && defined(SUPPORT_FPU_SOFTFLOAT) + +#include +#include +#include "../../ia32.mcr" + +#include "fp.h" +#include "fpumem.h" +#ifdef USE_SSE +#include "../sse/sse.h" +#endif + +#if 1 +#undef TRACEOUT +#define TRACEOUT(s) (void)(s) +#endif /* 0 */ + +#define FPU_WORKCLOCK 6 + +#define PI 3.14159265358979323846 +#define L2E 1.4426950408889634 +#define L2T 3.3219280948873623 +#define LN2 0.69314718055994531 +#define LG2 0.3010299956639812 + +static void FPU_FINIT(void); + +static void +fpu_check_NM_EXCEPTION(){ + // タスクスイッチまたはエミュレーション時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } +} +static void +fpu_check_NM_EXCEPTION2(){ + // タスクスイッチまたはエミュレーション時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static const FPU_PTR zero_ptr = { 0, 0, 0 }; + +/* + * FPU interface + */ + +static INLINE UINT FPU_GET_TOP(void) { + return (FPU_STATUSWORD & 0x3800)>>11; +} + +static INLINE void FPU_SET_TOP(UINT val){ + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (val&7)<<11; +} + + +static INLINE void FPU_SET_C0(UINT C){ + FPU_STATUSWORD &= ~0x0100; + if(C) FPU_STATUSWORD |= 0x0100; +} + +static INLINE void FPU_SET_C1(UINT C){ + FPU_STATUSWORD &= ~0x0200; + if(C) FPU_STATUSWORD |= 0x0200; +} + +static INLINE void FPU_SET_C2(UINT C){ + FPU_STATUSWORD &= ~0x0400; + if(C) FPU_STATUSWORD |= 0x0400; +} + +static INLINE void FPU_SET_C3(UINT C){ + FPU_STATUSWORD &= ~0x4000; + if(C) FPU_STATUSWORD |= 0x4000; +} + +static INLINE void FPU_SET_D(UINT C){ + FPU_STATUSWORD &= ~0x0002; + if(C) FPU_STATUSWORD |= 0x0002; +} + +static INLINE void FPU_SetCW(UINT16 cword) +{ + // HACK: Bits 13-15 are not defined. Apparently, one program likes to test for + // Cyrix EMC87 by trying to set bit 15. We want the test program to see + // us as an Intel 287 when cputype == 286. + cword &= 0x7FFF; + FPU_CTRLWORD = cword; + FPU_STAT.round = (FP_RND)((cword >> 10) & 3); + switch(FPU_STAT.round){ + case ROUND_Nearest: + float_rounding_mode = float_round_nearest_even; + break; + case ROUND_Down: + float_rounding_mode = float_round_down; + break; + case ROUND_Up: + float_rounding_mode = float_round_up; + break; + case ROUND_Chop: + float_rounding_mode = float_round_to_zero; + break; + default: + break; + } +} + +static void FPU_FLDCW(UINT32 addr) +{ + UINT16 temp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, addr); + FPU_SetCW(temp); +} + +static UINT16 FPU_GetTag(void) +{ + UINT i; + + UINT16 tag=0; + for(i=0;i<8;i++) + tag |= ( (FPU_STAT.tag[i]&3) <<(2*i)); + return tag; +} +static UINT8 FPU_GetTag8(void) +{ + UINT i; + + UINT8 tag=0; + for(i=0;i<8;i++) + tag |= ( (FPU_STAT.tag[i]==TAG_Empty ? 0 : 1) <<(i)); + return tag; +} + +static INLINE void FPU_SetTag(UINT16 tag) +{ + UINT i; + + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = (FP_TAG)((tag >>(2*i))&3); + + } +} +static INLINE void FPU_SetTag8(UINT8 tag) +{ + UINT i; + + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = (((tag>>i)&1) == 0 ? TAG_Empty : TAG_Valid); + } +} + +static void FPU_FCLEX(void){ + //FPU_STATUSWORD &= 0xff00; //should clear exceptions + FPU_STATUSWORD &= 0x7f00; //should clear exceptions? +} + +static void FPU_FNOP(void){ + return; +} + +static void FPU_PUSH(floatx80 in){ + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + //actually check if empty + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Valid; + FPU_STAT.reg[FPU_STAT_TOP].d = in; +// LOG(LOG_FPU,LOG_ERROR)("Pushed at %d %g to the stack",newtop,in); + return; +} + +static void FPU_PREP_PUSH(void){ + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Valid; +} + +static void FPU_FPOP(void){ + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Empty; + FPU_STAT.mmxenable = 0; + //maybe set zero in it as well + FPU_STAT_TOP = ((FPU_STAT_TOP+1)&7); +// LOG(LOG_FPU,LOG_ERROR)("popped from %d %g off the stack",top,fpu.regs[top].d); + return; +} + +static floatx80 FROUND(floatx80 in){ + return floatx80_round_to_int(in); +} + +#define BIAS80 16383 +#define BIAS64 1023 + +static void FPU_FLD80(UINT32 addr, UINT reg) +{ + FPU_STAT.reg[reg].ul.lower = fpu_memoryread_d(addr); + FPU_STAT.reg[reg].ul.upper = fpu_memoryread_d(addr+4); + FPU_STAT.reg[reg].ul.ext = fpu_memoryread_w(addr+8); +} + +static void FPU_ST80(UINT32 addr,UINT reg) +{ + fpu_memorywrite_d(addr,FPU_STAT.reg[reg].ul.lower); + fpu_memorywrite_d(addr+4,FPU_STAT.reg[reg].ul.upper); + fpu_memorywrite_w(addr+8,FPU_STAT.reg[reg].ul.ext); +} + + +static void FPU_FLD_F32(UINT32 addr,UINT store_to) { + union { + float f; + UINT32 l; + } blah; + + blah.l = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].d = c_float_to_floatx80(blah.f); +} + +static void FPU_FLD_F64(UINT32 addr,UINT store_to) { + union { + double d; + UINT64 l; + } blah; + blah.l = fpu_memoryread_q(addr); + FPU_STAT.reg[store_to].d = c_double_to_floatx80(blah.d); +} + +static void FPU_FLD_F80(UINT32 addr) { + FPU_FLD80(addr, FPU_STAT_TOP); +} + +static void FPU_FLD_I16(UINT32 addr,UINT store_to) { + SINT16 blah; + + blah = fpu_memoryread_w(addr); + FPU_STAT.reg[store_to].d = int32_to_floatx80((SINT32)blah); +} + +static void FPU_FLD_I32(UINT32 addr,UINT store_to) { + SINT32 blah; + + blah = fpu_memoryread_d(addr); + FPU_STAT.reg[store_to].d = int32_to_floatx80(blah); +} + +static void FPU_FLD_I64(UINT32 addr,UINT store_to) { + SINT64 blah; + + blah = fpu_memoryread_q(addr); + FPU_STAT.reg[store_to].d = int64_to_floatx80(blah); +} + +static void FPU_FBLD(UINT32 addr,UINT store_to) +{ + UINT i; + floatx80 temp; + + UINT64 val = 0; + UINT in = 0; + UINT64 base = 1; + for(i = 0;i < 9;i++){ + in = fpu_memoryread_b(addr + i); + val += ( (in&0xf) * base); //in&0xf shouldn't be higher then 9 + base *= 10; + val += ((( in>>4)&0xf) * base); + base *= 10; + } + + //last number, only now convert to float in order to get + //the best signification + temp = int64_to_floatx80(val); + in = fpu_memoryread_b(addr + 9); + temp = floatx80_add(temp, int64_to_floatx80((in&0xf) * base)); + if(in&0x80) temp = floatx80_mul(temp, int32_to_floatx80(-1)); + FPU_STAT.reg[store_to].d = temp; +} + + +static INLINE void FPU_FLD_F32_EA(UINT32 addr) { + FPU_FLD_F32(addr,8); +} +static INLINE void FPU_FLD_F64_EA(UINT32 addr) { + FPU_FLD_F64(addr,8); +} +static INLINE void FPU_FLD_I32_EA(UINT32 addr) { + FPU_FLD_I32(addr,8); +} +static INLINE void FPU_FLD_I16_EA(UINT32 addr) { + FPU_FLD_I16(addr,8); +} + +static void FPU_FST_F32(UINT32 addr) { + union { + float f; + UINT32 l; + } blah; + + blah.f = floatx80_to_c_float(FPU_STAT.reg[FPU_STAT_TOP].d); + fpu_memorywrite_d(addr,blah.l); +} + +static void FPU_FST_F64(UINT32 addr) { + union { + double d; + UINT64 l; + } blah; + + blah.d = floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d); + fpu_memorywrite_q(addr,blah.l); +} + +static void FPU_FST_F80(UINT32 addr) { + FPU_ST80(addr,FPU_STAT_TOP); +} + +static void FPU_FST_I16(UINT32 addr) { + INT16 blah; + + float_exception_flags = (FPU_STATUSWORD & 0x3f); + blah = (SINT16)floatx80_to_int32(FPU_STAT.reg[FPU_STAT_TOP].d); + fpu_memorywrite_w(addr,(UINT16)blah); + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FST_I32(UINT32 addr) { + INT32 blah; + + float_exception_flags = (FPU_STATUSWORD & 0x3f); + blah = floatx80_to_int32(FPU_STAT.reg[FPU_STAT_TOP].d); + fpu_memorywrite_d(addr,blah); + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FST_I64(UINT32 addr) { + INT64 blah; + + float_exception_flags = (FPU_STATUSWORD & 0x3f); + blah = floatx80_to_int64(FPU_STAT.reg[FPU_STAT_TOP].d); + fpu_memorywrite_q(addr,blah); + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FBST(UINT32 addr) +{ + FP_REG val; + UINT32 p; + UINT i; + BOOL sign; + floatx80 temp; + floatx80 m1 = int32_to_floatx80(-1); + floatx80 p10 = int32_to_floatx80(10); + signed char oldrnd = float_rounding_mode; + float_rounding_mode = float_round_down; + + val = FPU_STAT.reg[FPU_STAT_TOP]; + sign = FALSE; + if(FPU_STAT.reg[FPU_STAT_TOP].l.ext & 0x8000) { //sign + sign=TRUE; + val.d = floatx80_mul(val.d, m1); + } + //numbers from back to front + temp = val.d; + for(i=0;i<9;i++){ + val.d = temp; + temp = floatx80_round_to_int(floatx80_div(val.d, p10)); + p = floatx80_to_int32_round_to_zero(floatx80_sub(val.d, floatx80_mul(temp, p10))); + val.d = temp; + temp = floatx80_round_to_int(floatx80_div(val.d, p10)); + p |= (floatx80_to_int32_round_to_zero(floatx80_sub(val.d, floatx80_mul(temp, p10))) << 4); + + fpu_memorywrite_b(addr+i,(UINT8)p); + } + val.d = temp; + temp = floatx80_round_to_int(floatx80_div(val.d, p10)); + p = floatx80_to_int32_round_to_zero(floatx80_sub(val.d, floatx80_mul(temp, p10))); + if(sign) + p |= 0x80; + fpu_memorywrite_b(addr+9,(UINT8)p); + + float_rounding_mode = oldrnd; + FPU_STATUSWORD |= float_exception_flags; +} + +#define isinf(x) (!(_finite(x) || _isnan(x))) +#define isdenormal(x) (_fpclass(x) == _FPCLASS_ND || _fpclass(x) == _FPCLASS_PD) + +static void FPU_FADD(UINT op1, UINT op2){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[op1].d = floatx80_add(FPU_STAT.reg[op1].d, FPU_STAT.reg[op2].d); + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FSIN(void){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(sin(floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d))); + FPU_SET_C2(0); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FSINCOS(void){ + double temp; + + float_exception_flags = (FPU_STATUSWORD & 0x3f); + temp = floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(sin(temp)); + FPU_PUSH(c_double_to_floatx80(cos(temp))); + FPU_SET_C2(0); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FCOS(void){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(cos(floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d))); + FPU_SET_C2(0); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FSQRT(void){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[FPU_STAT_TOP].d = floatx80_sqrt(FPU_STAT.reg[FPU_STAT_TOP].d); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} +static void FPU_FPATAN(void){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[FPU_ST(1)].d = c_double_to_floatx80(atan2(floatx80_to_c_double(FPU_STAT.reg[FPU_ST(1)].d),floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d))); + FPU_FPOP(); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} +static void FPU_FPTAN(void){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(tan(floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d))); + FPU_PUSH(c_double_to_floatx80(1.0)); + FPU_SET_C2(0); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} +static void FPU_FDIV(UINT st, UINT other){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + //if(floatx80_eq(FPU_STAT.reg[other].d, c_double_to_floatx80(0.0))){ + // FPU_STATUSWORD |= FP_ZE_FLAG; + // if(!(FPU_CTRLWORD & FP_ZE_FLAG)) + // return; + //} + FPU_STAT.reg[st].d = floatx80_div(FPU_STAT.reg[st].d, FPU_STAT.reg[other].d); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FDIVR(UINT st, UINT other){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + //if(floatx80_eq(FPU_STAT.reg[st].d, c_double_to_floatx80(0.0))){ + // FPU_STATUSWORD |= FP_ZE_FLAG; + // if(!(FPU_CTRLWORD & FP_ZE_FLAG)) + // return; + //} + FPU_STAT.reg[st].d = floatx80_div(FPU_STAT.reg[other].d, FPU_STAT.reg[st].d); + // flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FMUL(UINT st, UINT other){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[st].d = floatx80_mul(FPU_STAT.reg[st].d, FPU_STAT.reg[other].d); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FSUB(UINT st, UINT other){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[st].d = floatx80_sub(FPU_STAT.reg[st].d, FPU_STAT.reg[other].d); + //flags and such :) + return; +} + +static void FPU_FSUBR(UINT st, UINT other){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[st].d = floatx80_sub(FPU_STAT.reg[other].d, FPU_STAT.reg[st].d); + //flags and such :) + FPU_STATUSWORD |= float_exception_flags; + return; +} + +static void FPU_FXCH(UINT st, UINT other){ + FP_TAG tag; + FP_REG reg; + + tag = FPU_STAT.tag[other]; + reg = FPU_STAT.reg[other]; + FPU_STAT.tag[other] = FPU_STAT.tag[st]; + FPU_STAT.reg[other] = FPU_STAT.reg[st]; + FPU_STAT.tag[st] = tag; + FPU_STAT.reg[st] = reg; +} + +static void FPU_FST(UINT st, UINT other){ + FPU_STAT.tag[other] = FPU_STAT.tag[st]; + FPU_STAT.reg[other] = FPU_STAT.reg[st]; +} + +static void FPU_FCOM(UINT st, UINT other){ + if(((FPU_STAT.tag[st] != TAG_Valid) && (FPU_STAT.tag[st] != TAG_Zero)) || + ((FPU_STAT.tag[other] != TAG_Valid) && (FPU_STAT.tag[other] != TAG_Zero))){ + FPU_SET_C3(1); + FPU_SET_C2(1); + FPU_SET_C0(1); + return; + } + + if(floatx80_eq(FPU_STAT.reg[st].d, FPU_STAT.reg[other].d)){ + FPU_SET_C3(1); + FPU_SET_C2(0); + FPU_SET_C0(0); + return; + } + if(floatx80_lt(FPU_STAT.reg[st].d, FPU_STAT.reg[other].d)){ + FPU_SET_C3(0); + FPU_SET_C2(0); + FPU_SET_C0(1); + return; + } + // st > other + FPU_SET_C3(0); + FPU_SET_C2(0); + FPU_SET_C0(0); + return; +} +static void FPU_FCOMI(UINT st, UINT other){ + if(((FPU_STAT.tag[st] != TAG_Valid) && (FPU_STAT.tag[st] != TAG_Zero)) || + ((FPU_STAT.tag[other] != TAG_Valid) && (FPU_STAT.tag[other] != TAG_Zero))){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | P_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + return; + } + + if(floatx80_eq(FPU_STAT.reg[st].d, FPU_STAT.reg[other].d)){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + return; + } + if(floatx80_lt(FPU_STAT.reg[st].d, FPU_STAT.reg[other].d)){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + return; + } + // st > other + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + return; +} + +static void FPU_FUCOM(UINT st, UINT other){ + //does atm the same as fcom + FPU_FCOM(st,other); +} +static void FPU_FUCOMI(UINT st, UINT other){ + //does atm the same as fcomi + FPU_FCOMI(st,other); +} + +static void FPU_FCMOVB(UINT st, UINT other){ + if(CPU_FLAGL & C_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVE(UINT st, UINT other){ + if(CPU_FLAGL & Z_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVBE(UINT st, UINT other){ + if(CPU_FLAGL & (C_FLAG|Z_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVU(UINT st, UINT other){ + if(CPU_FLAGL & P_FLAG){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} + +static void FPU_FCMOVNB(UINT st, UINT other){ + if(!(CPU_FLAGL & C_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVNE(UINT st, UINT other){ + if(!(CPU_FLAGL & Z_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVNBE(UINT st, UINT other){ + if(!(CPU_FLAGL & (C_FLAG|Z_FLAG))){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} +static void FPU_FCMOVNU(UINT st, UINT other){ + if(!(CPU_FLAGL & P_FLAG)){ + FPU_STAT.tag[st] = FPU_STAT.tag[other]; + FPU_STAT.reg[st] = FPU_STAT.reg[other]; + } +} + +static void FPU_FRNDINT(void){ + + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[FPU_STAT_TOP].d = floatx80_round_to_int(FPU_STAT.reg[FPU_STAT_TOP].d); + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FPREM(void){ + floatx80 valtop; + floatx80 valdiv; + SINT64 ressaved; + + float_exception_flags = (FPU_STATUSWORD & 0x3f); + valtop = FPU_STAT.reg[FPU_STAT_TOP].d; + valdiv = FPU_STAT.reg[FPU_ST(1)].d; + ressaved = floatx80_to_int64_round_to_zero(floatx80_div(valtop, valdiv)); +// Some backups +// Real64 res=valtop - ressaved*valdiv; +// res= fmod(valtop,valdiv); + FPU_STAT.reg[FPU_STAT_TOP].d = floatx80_sub(valtop, floatx80_mul(int64_to_floatx80(ressaved), valdiv)); + FPU_SET_C0((UINT)(ressaved&4)); + FPU_SET_C3((UINT)(ressaved&2)); + FPU_SET_C1((UINT)(ressaved&1)); + FPU_SET_C2(0); + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FPREM1(void){ + floatx80 valtop; + floatx80 valdiv, quot, quotf, quot_sub_quotf; + SINT64 ressaved; + floatx80 v05 = c_double_to_floatx80(0.5); + signed char oldrnd = float_rounding_mode; + + float_exception_flags = (FPU_STATUSWORD & 0x3f); + valtop = FPU_STAT.reg[FPU_STAT_TOP].d; + valdiv = FPU_STAT.reg[FPU_ST(1)].d; + quot = floatx80_div(valtop, valdiv); + float_rounding_mode = float_round_down; + quotf = floatx80_round_to_int(quot); + + quot_sub_quotf = floatx80_sub(quot, quotf); + if (floatx80_lt(v05, quot_sub_quotf)) ressaved = floatx80_to_int64_round_to_zero(quotf)+1; + else if (floatx80_lt(quot_sub_quotf, v05)) ressaved = floatx80_to_int64_round_to_zero(quotf); + else ressaved = ((((floatx80_to_int64_round_to_zero(quotf))&1)!=0) ? floatx80_to_int64_round_to_zero(quotf)+1 : floatx80_to_int64_round_to_zero(quotf)); + + FPU_STAT.reg[FPU_STAT_TOP].d = floatx80_sub(valtop, floatx80_mul(int64_to_floatx80(ressaved), valdiv)); + FPU_SET_C0((UINT)(ressaved&4)); + FPU_SET_C3((UINT)(ressaved&2)); + FPU_SET_C1((UINT)(ressaved&1)); + FPU_SET_C2(0); + + float_rounding_mode = oldrnd; + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FXAM(void){ + if(FPU_STAT.reg[FPU_STAT_TOP].d.high & 0x8000) //sign + { + FPU_SET_C1(1); + } + else + { + FPU_SET_C1(0); + } + if(FPU_STAT.tag[FPU_STAT_TOP] == TAG_Empty) + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(1); + return; + } + if(floatx80_eq(FPU_STAT.reg[FPU_STAT_TOP].d, c_double_to_floatx80(0.0))) //zero or normalized number. + { + FPU_SET_C3(1);FPU_SET_C2(0);FPU_SET_C0(0); + } + else + { + FPU_SET_C3(0);FPU_SET_C2(1);FPU_SET_C0(0); + } +} + +static void FPU_F2XM1(void){ + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(pow(2.0, floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d)) - 1); + return; +} + +static void FPU_FYL2X(void){ + FPU_STAT.reg[FPU_ST(1)].d = floatx80_mul(FPU_STAT.reg[FPU_ST(1)].d, c_double_to_floatx80(log(floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d))/log((double)(2.0)))); + FPU_FPOP(); + return; +} + +static void FPU_FYL2XP1(void){ + FPU_STAT.reg[FPU_ST(1)].d = floatx80_mul(FPU_STAT.reg[FPU_ST(1)].d, c_double_to_floatx80(log(floatx80_to_c_double(FPU_STAT.reg[FPU_STAT_TOP].d)+1.0)/log((double)(2.0)))); + FPU_FPOP(); + return; +} + +static void FPU_FSCALE(void){ + FPU_STAT.reg[FPU_STAT_TOP].d = floatx80_mul(FPU_STAT.reg[FPU_STAT_TOP].d, c_double_to_floatx80(pow(2.0, floatx80_to_c_double(FPU_STAT.reg[FPU_ST(1)].d)))); + return; //2^x where x is chopped. +} + +static void FPU_FSTENV(UINT32 addr) +{ + descriptor_t *sdp = &CPU_CS_DESC; + FPU_SET_TOP(FPU_STAT_TOP); + + switch ((CPU_CR0 & 1) | (SEG_IS_32BIT(sdp) ? 0x100 : 0x000)) + { + case 0x000: case 0x001: + fpu_memorywrite_w(addr+0,FPU_CTRLWORD); + fpu_memorywrite_w(addr+2,FPU_STATUSWORD); + fpu_memorywrite_w(addr+4,FPU_GetTag()); + fpu_memorywrite_w(addr+10,FPU_LASTINSTOP); + break; + + case 0x100: case 0x101: + fpu_memorywrite_d(addr+0,(UINT32)(FPU_CTRLWORD)); + fpu_memorywrite_d(addr+4,(UINT32)(FPU_STATUSWORD)); + fpu_memorywrite_d(addr+8,(UINT32)(FPU_GetTag())); + fpu_memorywrite_d(addr+20,FPU_LASTINSTOP); + break; + } +} + +static void FPU_FLDENV(UINT32 addr) +{ + descriptor_t *sdp = &CPU_CS_DESC; + + switch ((CPU_CR0 & 1) | (SEG_IS_32BIT(sdp) ? 0x100 : 0x000)) { + case 0x000: case 0x001: + FPU_SetCW(fpu_memoryread_w(addr+0)); + FPU_STATUSWORD = fpu_memoryread_w(addr+2); + FPU_SetTag(fpu_memoryread_w(addr+4)); + FPU_LASTINSTOP = fpu_memoryread_w(addr+10); + break; + + case 0x100: case 0x101: + FPU_SetCW((UINT16)fpu_memoryread_d(addr+0)); + FPU_STATUSWORD = (UINT16)fpu_memoryread_d(addr+4); + FPU_SetTag((UINT16)fpu_memoryread_d(addr+8)); + FPU_LASTINSTOP = (UINT16)fpu_memoryread_d(addr+20); + break; + } + FPU_STAT_TOP = FPU_GET_TOP(); +} + +static void FPU_FSAVE(UINT32 addr) +{ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + FPU_FSTENV(addr); + start = ((SEG_IS_32BIT(sdp))?28:14); + for(i = 0;i < 8;i++){ + FPU_ST80(addr+start,FPU_ST(i)); + start += 10; + } + FPU_FINIT(); +} + +static void FPU_FRSTOR(UINT32 addr) +{ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + FPU_FLDENV(addr); + start = ((SEG_IS_32BIT(sdp))?28:14); + for(i = 0;i < 8;i++){ + FPU_FLD80(addr+start, FPU_ST(i)); + start += 10; + } +} + +static void FPU_FXSAVE(UINT32 addr){ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + //FPU_FSTENV(addr); + FPU_SET_TOP(FPU_STAT_TOP); + fpu_memorywrite_w(addr+0,FPU_CTRLWORD); + fpu_memorywrite_w(addr+2,FPU_STATUSWORD); + fpu_memorywrite_b(addr+4,FPU_GetTag8()); +#ifdef USE_SSE + fpu_memorywrite_d(addr+24,SSE_MXCSR); +#endif + start = 32; + for(i = 0;i < 8;i++){ + FPU_ST80(addr+start, FPU_ST(i)); + start += 16; + } +#ifdef USE_SSE + start = 160; + for(i = 0;i < 8;i++){ + fpu_memorywrite_q(addr+start+0,SSE_XMMREG(i).ul64[0]); + fpu_memorywrite_q(addr+start+8,SSE_XMMREG(i).ul64[1]); + start += 16; + } +#endif +} +static void FPU_FXRSTOR(UINT32 addr){ + UINT start; + UINT i; + + descriptor_t *sdp = &CPU_CS_DESC; + + //FPU_FLDENV(addr); + FPU_SetCW(fpu_memoryread_w(addr+0)); + FPU_STATUSWORD = fpu_memoryread_w(addr+2); + FPU_SetTag8(fpu_memoryread_b(addr+4)); + FPU_STAT_TOP = FPU_GET_TOP(); +#ifdef USE_SSE + SSE_MXCSR = fpu_memoryread_d(addr+24); +#endif + start = 32; + for(i = 0;i < 8;i++){ + FPU_FLD80(addr+start, FPU_ST(i)); + start += 16; + } +#ifdef USE_SSE + start = 160; + for(i = 0;i < 8;i++){ + SSE_XMMREG(i).ul64[0] = fpu_memoryread_q(addr+start+0); + SSE_XMMREG(i).ul64[1] = fpu_memoryread_q(addr+start+8); + start += 16; + } +#endif +} + +void SF_FPU_FXSAVERSTOR(void){ + UINT32 op; + UINT idx, sub; + UINT32 maddr; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION2(); // XXX: 根拠無し + switch(idx){ + case 0: // FXSAVE + maddr = calc_ea_dst(op); + FPU_FXSAVE(maddr); + break; + case 1: // FXRSTOR + maddr = calc_ea_dst(op); + FPU_FXRSTOR(maddr); + break; +#ifdef USE_SSE + case 2: // LDMXCSR + maddr = calc_ea_dst(op); + SSE_LDMXCSR(maddr); + break; + case 3: // STMXCSR + maddr = calc_ea_dst(op); + SSE_STMXCSR(maddr); + break; + case 4: // SFENCE + SSE_SFENCE(); + break; + case 5: // LFENCE + SSE_LFENCE(); + break; + case 6: // MFENCE + SSE_MFENCE(); + break; + case 7: // CLFLUSH; + SSE_CLFLUSH(op); + break; +#endif + default: + ia32_panic("invalid opcode = %02x\n", op); + break; + } +} + +static void FPU_FXTRACT(void) { + // function stores real bias in st and + // pushes the significant number onto the stack + // if double ever uses a different base please correct this function + FP_REG test; + SINT64 exp80, exp80final; + floatx80 mant; + + test = FPU_STAT.reg[FPU_STAT_TOP]; + exp80 = test.ll&QWORD_CONST(0x7ff0000000000000); + exp80final = (exp80>>52) - BIAS64; + mant = floatx80_div(test.d, c_double_to_floatx80(pow(2.0,(double)(exp80final)))); + FPU_STAT.reg[FPU_STAT_TOP].d = int64_to_floatx80(exp80final); + FPU_PUSH(mant); +} + +static void FPU_FCHS(void){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + FPU_STAT.reg[FPU_STAT_TOP].d = floatx80_mul(c_double_to_floatx80(-1.0), FPU_STAT.reg[FPU_STAT_TOP].d); + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FABS(void){ + float_exception_flags = (FPU_STATUSWORD & 0x3f); + if(floatx80_le(FPU_STAT.reg[FPU_STAT_TOP].d, c_double_to_floatx80(0.0))){ + FPU_STAT.reg[FPU_STAT_TOP].d = floatx80_mul(c_double_to_floatx80(-1.0), FPU_STAT.reg[FPU_STAT_TOP].d); + } + FPU_STATUSWORD |= float_exception_flags; +} + +static void FPU_FTST(void){ + FPU_STAT.reg[8].d = c_double_to_floatx80(0.0); + FPU_FCOM(FPU_STAT_TOP,8); +} + +static void FPU_FLD1(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(1.0); +} + +static void FPU_FLDL2T(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(L2T); +} + +static void FPU_FLDL2E(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(L2E); +} + +static void FPU_FLDPI(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(PI); +} + +static void FPU_FLDLG2(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(LG2); +} + +static void FPU_FLDLN2(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(LN2); +} + +static void FPU_FLDZ(void){ + FPU_PREP_PUSH(); + FPU_STAT.reg[FPU_STAT_TOP].d = c_double_to_floatx80(0.0); + FPU_STAT.tag[FPU_STAT_TOP] = TAG_Zero; + FPU_STAT.mmxenable = 0; +} + + +static INLINE void FPU_FADD_EA(UINT op1){ + FPU_FADD(op1,8); +} +static INLINE void FPU_FMUL_EA(UINT op1){ + FPU_FMUL(op1,8); +} +static INLINE void FPU_FSUB_EA(UINT op1){ + FPU_FSUB(op1,8); +} +static INLINE void FPU_FSUBR_EA(UINT op1){ + FPU_FSUBR(op1,8); +} +static INLINE void FPU_FDIV_EA(UINT op1){ + FPU_FDIV(op1,8); +} +static INLINE void FPU_FDIVR_EA(UINT op1){ + FPU_FDIVR(op1,8); +} +static INLINE void FPU_FCOM_EA(UINT op1){ + FPU_FCOM(op1,8); +} + +/* + * FPU interface + */ +//int fpu_updateEmuEnv(void); +static void +FPU_FINIT(void) +{ + int i; + FPU_SetCW(0x37F); + FPU_STATUSWORD = 0; + FPU_STAT_TOP=FPU_GET_TOP(); + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = TAG_Empty; + // レジスタの内容は消してはいけない ver0.86 rev40 + //FPU_STAT.reg[i].d = 0; + //FPU_STAT.reg[i].l.lower = 0; + //FPU_STAT.reg[i].l.upper = 0; + //FPU_STAT.reg[i].ll = 0; + } + FPU_STAT.tag[8] = TAG_Valid; // is only used by us + FPU_STAT.mmxenable = 0; +} +void SF_FPU_FINIT(void){ + int i; + FPU_FINIT(); + for(i=0;i<8;i++){ + FPU_STAT.tag[i] = TAG_Empty; + FPU_STAT.reg[i].l.ext = 0; + FPU_STAT.reg[i].l.lower = 0; + FPU_STAT.reg[i].l.upper = 0; + } +} + +//char * +//fpu_reg2str(void) +//{ +// return NULL; +//} + +/* + * FPU instruction + */ + +static void fpu_checkexception(){ + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & 0x3F){ + EXCEPTION(MF_EXCEPTION, 0); + } +} + +static void EA_TREE(UINT op) +{ + UINT idx; + + idx = (op >> 3) & 7; + + switch (idx) { + case 0: /* FADD (単精度実数) */ + TRACEOUT(("FADD EA")); + FPU_FADD_EA(FPU_STAT_TOP); + break; + case 1: /* FMUL (単精度実数) */ + TRACEOUT(("FMUL EA")); + FPU_FMUL_EA(FPU_STAT_TOP); + break; + case 2: /* FCOM (単精度実数) */ + TRACEOUT(("FCOM EA")); + FPU_FCOM_EA(FPU_STAT_TOP); + break; + case 3: /* FCOMP (単精度実数) */ + TRACEOUT(("FCOMP EA")); + FPU_FCOM_EA(FPU_STAT_TOP); + FPU_FPOP(); + break; + case 4: /* FSUB (単精度実数) */ + TRACEOUT(("FSUB EA")); + FPU_FSUB_EA(FPU_STAT_TOP); + break; + case 5: /* FSUBR (単精度実数) */ + TRACEOUT(("FSUBR EA")); + FPU_FSUBR_EA(FPU_STAT_TOP); + break; + case 6: /* FDIV (単精度実数) */ + TRACEOUT(("FDIV EA")); + FPU_FDIV_EA(FPU_STAT_TOP); + break; + case 7: /* FDIVR (単精度実数) */ + TRACEOUT(("FDIVR EA")); + FPU_FDIVR_EA(FPU_STAT_TOP); + break; + default: + break; + } +} + +// d8 +void +SF_ESC0(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU d8 %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FADD */ + TRACEOUT(("FADD")); + FPU_FADD(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FMUL */ + TRACEOUT(("FMUL")); + FPU_FMUL(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCOM */ + TRACEOUT(("FCOM")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMP */ + TRACEOUT(("FCOMP")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FSUB */ + TRACEOUT(("FSUB")); + FPU_FSUB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: /* FSUBR */ + TRACEOUT(("FSUBR")); + FPU_FSUBR(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 6: /* FDIV */ + TRACEOUT(("FDIV")); + FPU_FDIV(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 7: /* FDIVR */ + TRACEOUT(("FDIVR")); + FPU_FDIVR(FPU_STAT_TOP,FPU_ST(sub)); + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_F32_EA(madr); + EA_TREE(op); + } +} + +// d9 +void +SF_ESC1(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU d9 %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op < 0xc0 && idx>=4)){ + fpu_checkexception(); + } + if (op >= 0xc0) + { + switch (idx) { + case 0: /* FLD ST(0), ST(i) */ + { + UINT reg_from; + + TRACEOUT(("FLD STi")); + reg_from = FPU_ST(sub); + FPU_PREP_PUSH(); + FPU_FST(reg_from, FPU_STAT_TOP); + } + break; + + case 1: /* FXCH ST(0), ST(i) */ + TRACEOUT(("FXCH STi")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + + case 2: /* FNOP */ + TRACEOUT(("FNOP")); + FPU_FNOP(); + break; + + case 3: /* FSTP STi */ + TRACEOUT(("FSTP STi")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + case 4: + switch (sub) { + case 0x0: /* FCHS */ + TRACEOUT(("FCHS")); + FPU_FCHS(); + break; + + case 0x1: /* FABS */ + TRACEOUT(("FABS")); + FPU_FABS(); + break; + + case 0x2: /* UNKNOWN */ + case 0x3: /* ILLEGAL */ + break; + + case 0x4: /* FTST */ + TRACEOUT(("FTST")); + FPU_FTST(); + break; + + case 0x5: /* FXAM */ + TRACEOUT(("FXAM")); + FPU_FXAM(); + break; + + case 0x06: /* FTSTP (cyrix)*/ + case 0x07: /* UNKNOWN */ + break; + } + break; + + case 5: + switch (sub) { + case 0x0: /* FLD1 */ + TRACEOUT(("FLD1")); + FPU_FLD1(); + break; + + case 0x1: /* FLDL2T */ + TRACEOUT(("FLDL2T")); + FPU_FLDL2T(); + break; + + case 0x2: /* FLDL2E */ + TRACEOUT(("FLDL2E")); + FPU_FLDL2E(); + break; + + case 0x3: /* FLDPI */ + TRACEOUT(("FLDPI")); + FPU_FLDPI(); + break; + + case 0x4: /* FLDLG2 */ + TRACEOUT(("FLDLG2")); + FPU_FLDLG2(); + break; + + case 0x5: /* FLDLN2 */ + TRACEOUT(("FLDLN2")); + FPU_FLDLN2(); + break; + + case 0x6: /* FLDZ */ + TRACEOUT(("FLDZ")); + FPU_FLDZ(); + break; + + case 0x07: /* ILLEGAL */ + break; + } + break; + + case 6: + switch (sub) { + case 0x0: /* F2XM1 */ + TRACEOUT(("F2XM1")); + FPU_F2XM1(); + break; + + case 0x1: /* FYL2X */ + TRACEOUT(("FYL2X")); + FPU_FYL2X(); + break; + + case 0x2: /* FPTAN */ + TRACEOUT(("FPTAN")); + FPU_FPTAN(); + break; + + case 0x3: /* FPATAN */ + TRACEOUT(("FPATAN")); + FPU_FPATAN(); + break; + + case 0x4: /* FXTRACT */ + TRACEOUT(("FXTRACT")); + FPU_FXTRACT(); + break; + + case 0x5: /* FPREM1 */ + TRACEOUT(("FPREM1")); + FPU_FPREM1(); + break; + + case 0x6: /* FDECSTP */ + TRACEOUT(("FDECSTP")); + FPU_STAT_TOP = (FPU_STAT_TOP - 1) & 7; + break; + + case 0x7: /* FINCSTP */ + TRACEOUT(("FINCSTP")); + FPU_STAT_TOP = (FPU_STAT_TOP + 1) & 7; + break; + } + break; + + case 7: + switch (sub) { + case 0x0: /* FPREM */ + TRACEOUT(("FPREM")); + FPU_FPREM(); + break; + + case 0x1: /* FYL2XP1 */ + TRACEOUT(("FYL2XP1")); + FPU_FYL2XP1(); + break; + + case 0x2: /* FSQRT */ + TRACEOUT(("FSQRT")); + FPU_FSQRT(); + break; + + case 0x3: /* FSINCOS */ + TRACEOUT(("FSINCOS")); + FPU_FSINCOS(); + break; + + case 0x4: /* FRNDINT */ + TRACEOUT(("FRNDINT")); + FPU_FRNDINT(); + break; + + case 0x5: /* FSCALE */ + TRACEOUT(("FSCALE")); + FPU_FSCALE(); + break; + + case 0x6: /* FSIN */ + TRACEOUT(("FSIN")); + FPU_FSIN(); + break; + + case 0x7: /* FCOS */ + TRACEOUT(("FCOS")); + FPU_FCOS(); + break; + } + break; + + default: + ia32_panic("ESC1: invalid opcode = %02x\n", op); + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FLD (単精度実数) */ + TRACEOUT(("FLD float")); + FPU_PREP_PUSH(); + FPU_FLD_F32(madr,FPU_STAT_TOP); + break; + + case 1: /* UNKNOWN */ + break; + + case 2: /* FST (単精度実数) */ + TRACEOUT(("FST float")); + FPU_FST_F32(madr); + break; + + case 3: /* FSTP (単精度実数) */ + TRACEOUT(("FSTP float")); + FPU_FST_F32(madr); + FPU_FPOP(); + break; + + case 4: /* FLDENV */ + TRACEOUT(("FLDENV")); + FPU_FLDENV(madr); + break; + + case 5: /* FLDCW */ + TRACEOUT(("FLDCW")); + FPU_FLDCW(madr); + break; + + case 6: /* FSTENV */ + TRACEOUT(("FSTENV")); + FPU_FSTENV(madr); + break; + + case 7: /* FSTCW */ + TRACEOUT(("FSTCW/FNSTCW")); + fpu_memorywrite_w(madr,FPU_CTRLWORD); + break; + + default: + break; + } + } +} + +// da +void +SF_ESC2(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU da %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FCMOVB */ + TRACEOUT(("ESC2: FCMOVB")); + FPU_FCMOVB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FCMOVE */ + TRACEOUT(("ESC2: FCMOVE")); + FPU_FCMOVE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCMOVBE */ + TRACEOUT(("ESC2: FCMOVBE")); + FPU_FCMOVBE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCMOVU */ + TRACEOUT(("ESC2: FCMOVU")); + FPU_FCMOVU(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: + switch (sub) { + case 1: /* FUCOMPP */ + TRACEOUT(("FUCOMPP")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(1)); + FPU_FPOP(); + FPU_FPOP(); + break; + + default: + break; + } + break; + + default: + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_I32_EA(madr); + EA_TREE(op); + } +} + +// db +void +SF_ESC3(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU db %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op >= 0xc0 && idx==4)){ + fpu_checkexception(); + } + if (op >= 0xc0) + { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FCMOVNB */ + TRACEOUT(("ESC3: FCMOVNB")); + FPU_FCMOVNB(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 1: /* FCMOVNE */ + TRACEOUT(("ESC3: FCMOVNE")); + FPU_FCMOVNE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FCMOVNBE */ + TRACEOUT(("ESC3: FCMOVNBE")); + FPU_FCMOVNBE(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCMOVNU */ + TRACEOUT(("ESC3: FCMOVNU")); + FPU_FCMOVNU(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 4: + switch (sub) { + case 0: /* FNENI */ + case 1: /* FNDIS */ + break; + + case 2: /* FCLEX */ + TRACEOUT(("FCLEX")); + FPU_FCLEX(); + break; + + case 3: /* FNINIT/FINIT */ + TRACEOUT(("FNINIT/FINIT")); + FPU_FINIT(); + break; + + case 4: /* FNSETPM */ + case 5: /* FRSTPM */ + FPU_FNOP(); + break; + + default: + break; + } + break; + case 5: /* FUCOMI */ + TRACEOUT(("ESC3: FUCOMI")); + FPU_FUCOMI(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 6: /* FCOMI */ + TRACEOUT(("ESC3: FCOMI")); + FPU_FCOMI(FPU_STAT_TOP,FPU_ST(sub)); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FILD (DWORD) */ + TRACEOUT(("FILD")); + FPU_PREP_PUSH(); + FPU_FLD_I32(madr,FPU_STAT_TOP); + break; + + case 1: /* FISTTP (DWORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + signed char oldrnd = float_rounding_mode; + float_rounding_mode = float_round_down; + FPU_FST_I32(madr); + float_rounding_mode = oldrnd; + } + FPU_FPOP(); + } + break; + + case 2: /* FIST (DWORD) */ + TRACEOUT(("FIST")); + FPU_FST_I32(madr); + break; + + case 3: /* FISTP (DWORD) */ + TRACEOUT(("FISTP")); + FPU_FST_I32(madr); + FPU_FPOP(); + break; + + case 5: /* FLD (拡張実数) */ + TRACEOUT(("FLD 80 Bits Real")); + FPU_PREP_PUSH(); + FPU_FLD_F80(madr); + break; + + case 7: /* FSTP (拡張実数) */ + TRACEOUT(("FSTP 80 Bits Real")); + FPU_FST_F80(madr); + FPU_FPOP(); + break; + + default: + break; + } + } +} + +// dc +void +SF_ESC4(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU dc %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(i), ST(0) */ + switch (idx) { + case 0: /* FADD */ + TRACEOUT(("ESC4: FADD")); + FPU_FADD(FPU_ST(sub),FPU_STAT_TOP); + break; + case 1: /* FMUL */ + TRACEOUT(("ESC4: FMUL")); + FPU_FMUL(FPU_ST(sub),FPU_STAT_TOP); + break; + case 2: /* FCOM */ + TRACEOUT(("ESC4: FCOM")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMP */ + TRACEOUT(("ESC4: FCOMP")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FSUBR */ + TRACEOUT(("ESC4: FSUBR")); + FPU_FSUBR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 5: /* FSUB */ + TRACEOUT(("ESC4: FSUB")); + FPU_FSUB(FPU_ST(sub),FPU_STAT_TOP); + break; + case 6: /* FDIVR */ + TRACEOUT(("ESC4: FDIVR")); + FPU_FDIVR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 7: /* FDIV */ + TRACEOUT(("ESC4: FDIV")); + FPU_FDIV(FPU_ST(sub),FPU_STAT_TOP); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + FPU_FLD_F64_EA(madr); + EA_TREE(op); + } +} + +// dd +void +SF_ESC5(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU dd %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + fpu_check_NM_EXCEPTION(); + //if(op < 0xc0 && (idx==6 || idx==4)){ + // _ADD_EIP(-1); // XXX: 無理やり戻す + // fpu_check_NM_EXCEPTION2(); + // _ADD_EIP(1); + //}else{ + // _ADD_EIP(-1); // XXX: 無理やり戻す + // fpu_check_NM_EXCEPTION(); + // _ADD_EIP(1); + //} + if(op >= 0xc0 || (idx!=4 && idx!=6 && idx!=7)){ + fpu_checkexception(); + } + if (op >= 0xc0) { + /* FUCOM ST(i), ST(0) */ + /* Fxxx ST(i) */ + switch (idx) { + case 0: /* FFREE */ + TRACEOUT(("FFREE")); + FPU_STAT.tag[FPU_ST(sub)]=TAG_Empty; + FPU_STAT.mmxenable = 0; + break; + case 1: /* FXCH */ + TRACEOUT(("FXCH")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 2: /* FST */ + TRACEOUT(("FST")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FSTP */ + TRACEOUT(("FSTP")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 4: /* FUCOM */ + TRACEOUT(("FUCOM")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 5: /* FUCOMP */ + TRACEOUT(("FUCOMP")); + FPU_FUCOM(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FLD (倍精度実数) */ + TRACEOUT(("FLD double real")); + FPU_PREP_PUSH(); + FPU_FLD_F64(madr,FPU_STAT_TOP); + break; + case 1: /* FISTTP (QWORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + signed char oldrnd = float_rounding_mode; + float_rounding_mode = float_round_down; + FPU_FST_I64(madr); + float_rounding_mode = oldrnd; + } + FPU_FPOP(); + } + break; + case 2: /* FST (倍精度実数) */ + TRACEOUT(("FST double real")); + FPU_FST_F64(madr); + break; + case 3: /* FSTP (倍精度実数) */ + TRACEOUT(("FSTP double real")); + FPU_FST_F64(madr); + FPU_FPOP(); + break; + case 4: /* FRSTOR */ + TRACEOUT(("FRSTOR")); + FPU_FRSTOR(madr); + break; + case 6: /* FSAVE */ + TRACEOUT(("FSAVE")); + FPU_FSAVE(madr); + break; + + case 7: /* FSTSW */ + FPU_SET_TOP(FPU_STAT_TOP); + //cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, FPU_CTRLWORD); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, FPU_STATUSWORD); + break; + + default: + break; + } + } +} + +// de +void +SF_ESC6(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU de %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + fpu_checkexception(); + if (op >= 0xc0) { + /* Fxxx ST(i), ST(0) */ + switch (idx) { + case 0: /* FADDP */ + TRACEOUT(("FADDP")); + FPU_FADD(FPU_ST(sub),FPU_STAT_TOP); + break; + case 1: /* FMULP */ + TRACEOUT(("FMULP")); + FPU_FMUL(FPU_ST(sub),FPU_STAT_TOP); + break; + case 2: /* FCOMP5 */ + TRACEOUT(("FCOMP5")); + FPU_FCOM(FPU_STAT_TOP,FPU_ST(sub)); + break; + case 3: /* FCOMPP */ + TRACEOUT(("FCOMPP")); + if(sub != 1) { + return; + } + FPU_FCOM(FPU_STAT_TOP,FPU_ST(1)); + FPU_FPOP(); /* extra pop at the bottom*/ + break; + case 4: /* FSUBRP */ + TRACEOUT(("FSUBRP")); + FPU_FSUBR(FPU_ST(sub),FPU_STAT_TOP); + break; + case 5: /* FSUBP */ + TRACEOUT(("FSUBP")); + FPU_FSUB(FPU_ST(sub),FPU_STAT_TOP); + break; + case 6: /* FDIVRP */ + TRACEOUT(("FDIVRP")); + FPU_FDIVR(FPU_ST(sub),FPU_STAT_TOP); + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & FP_ZE_FLAG){ + return; // POPしないようにする + } + break; + case 7: /* FDIVP */ + TRACEOUT(("FDIVP")); + FPU_FDIV(FPU_ST(sub),FPU_STAT_TOP); + if((FPU_STATUSWORD & ~FPU_CTRLWORD) & FP_ZE_FLAG){ + return; // POPしないようにする + } + break; + /*FALLTHROUGH*/ + default: + break; + } + FPU_FPOP(); + } else { + madr = calc_ea_dst(op); + FPU_FLD_I16_EA(madr); + EA_TREE(op); + } +} + +// df +void +SF_ESC7(void) +{ + UINT32 op, madr; + UINT idx, sub; + + CPU_WORKCLOCK(FPU_WORKCLOCK); + GET_PCBYTE(op); + TRACEOUT(("use FPU df %.2x", op)); + idx = (op >> 3) & 7; + sub = (op & 7); + + fpu_check_NM_EXCEPTION(); + if(!(op >= 0xc0 && idx==4 && sub==0)){ + fpu_checkexception(); + } + if (op >= 0xc0) { + /* Fxxx ST(0), ST(i) */ + switch (idx) { + case 0: /* FFREEP */ + TRACEOUT(("FFREEP")); + FPU_STAT.tag[FPU_ST(sub)]=TAG_Empty; + FPU_STAT.mmxenable = 0; + FPU_FPOP(); + break; + case 1: /* FXCH */ + TRACEOUT(("FXCH")); + FPU_FXCH(FPU_STAT_TOP,FPU_ST(sub)); + break; + + case 2: + case 3: /* FSTP */ + TRACEOUT(("FSTP")); + FPU_FST(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + + case 4: + switch (sub) + { + case 0: /* FSTSW AX */ + TRACEOUT(("FSTSW AX")); + FPU_SET_TOP(FPU_STAT_TOP); + CPU_AX = FPU_STATUSWORD; + break; + + default: + break; + } + break; + case 5: /* FUCOMIP */ + TRACEOUT(("ESC7: FUCOMIP")); + FPU_FUCOMI(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + case 6: /* FCOMIP */ + TRACEOUT(("ESC7: FCOMIP")); + FPU_FCOMI(FPU_STAT_TOP,FPU_ST(sub)); + FPU_FPOP(); + break; + default: + break; + } + } else { + madr = calc_ea_dst(op); + switch (idx) { + case 0: /* FILD (WORD) */ + TRACEOUT(("FILD SINT16")); + FPU_PREP_PUSH(); + FPU_FLD_I16(madr,FPU_STAT_TOP); + break; + case 1: /* FISTTP (WORD) */ + if(i386cpuid.cpu_family >= CPU_PENTIUM_4_FAMILY) + { + { + signed char oldrnd = float_rounding_mode; + float_rounding_mode = float_round_down; + FPU_FST_I16(madr); + float_rounding_mode = oldrnd; + } + FPU_FPOP(); + } + break; + case 2: /* FIST (WORD) */ + TRACEOUT(("FIST SINT16")); + FPU_FST_I16(madr); + break; + case 3: /* FISTP (WORD) */ + TRACEOUT(("FISTP SINT16")); + FPU_FST_I16(madr); + FPU_FPOP(); + break; + + case 4: /* FBLD (BCD) */ + TRACEOUT(("FBLD packed BCD")); + FPU_PREP_PUSH(); + FPU_FBLD(madr,FPU_STAT_TOP); + break; + + case 5: /* FILD (QWORD) */ + TRACEOUT(("FILD SINT64")); + FPU_PREP_PUSH(); + FPU_FLD_I64(madr,FPU_STAT_TOP); + break; + + case 6: /* FBSTP (BCD) */ + TRACEOUT(("FBSTP packed BCD")); + FPU_FBST(madr); + FPU_FPOP(); + break; + + case 7: /* FISTP (QWORD) */ + TRACEOUT(("FISTP SINT64")); + FPU_FST_I64(madr); + FPU_FPOP(); + break; + + default: + break; + } + } +} +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/fpumem.h b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpumem.h new file mode 100644 index 000000000..281ca9a67 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/fpumem.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_FPU_FPUMEM_H__ +#define IA32_CPU_INSTRUCTION_FPU_FPUMEM_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * FPU memory access function + */ +UINT8 MEMCALL +fpu_memoryread_b(UINT32 address); + +UINT16 MEMCALL +fpu_memoryread_w(UINT32 address); + +UINT32 MEMCALL +fpu_memoryread_d(UINT32 address); + +UINT64 MEMCALL +fpu_memoryread_q(UINT32 address); + +REG80 MEMCALL +fpu_memoryread_f(UINT32 address); + +void MEMCALL +fpu_memorywrite_b(UINT32 address, UINT8 value); + +void MEMCALL +fpu_memorywrite_w(UINT32 address, UINT16 value); + +void MEMCALL +fpu_memorywrite_d(UINT32 address, UINT32 value); + +void MEMCALL +fpu_memorywrite_q(UINT32 address, UINT64 value); + +void MEMCALL +fpu_memorywrite_f(UINT32 address, REG80 *value); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_FPU_FP_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/README.txt b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/README.txt new file mode 100644 index 000000000..1d7c4908f --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/README.txt @@ -0,0 +1,83 @@ + +Package Overview for Berkeley SoftFloat Release 2c + +John R. Hauser +2015 January 30 + + +---------------------------------------------------------------------------- +Overview + +Berkeley SoftFloat is a software implementation of binary floating-point +that conforms to the IEEE Standard for Floating-Point Arithmetic. +Release 2c updates an older version of SoftFloat that has for most purposes +been supplanted by Release 3 or later. For the latest version of SoftFloat, +see Web page `http://www.jhauser.us/arithmetic/SoftFloat.html'. + +SoftFloat is distributed in the form of C source code. For Release 2c, +compiling the SoftFloat sources generates two things: + +-- A SoftFloat object file (typically `softfloat.o') containing the complete + set of IEC/IEEE floating-point routines. + +-- A `timesoftfloat' program for evaluating the speed of the SoftFloat + routines. (The SoftFloat module is linked into this program.) + +This version of the SoftFloat package is documented in four text files: + + SoftFloat.txt Documentation for using the SoftFloat functions. + SoftFloat-source.txt Documentation for compiling SoftFloat. + SoftFloat-history.txt History of major changes to SoftFloat. + timesoftfloat.txt Documentation for using `timesoftfloat'. + +Other files in the package comprise the source code for SoftFloat. + +Please be aware that some work is involved in porting this software to other +targets. It is not just a matter of getting `make' to complete without +error messages. You should not attempt to compile this release of SoftFloat +without first reading both `SoftFloat.txt' and `SoftFloat-source.txt'. +Depending on your needs, you may find that newer versions of SoftFloat are +less work to port. + + +---------------------------------------------------------------------------- +Legal Notice + +SoftFloat was written by John R. Hauser. Release 2c of SoftFloat was made +possible in part by the International Computer Science Institute, located +at Suite 600, 1947 Center Street, Berkeley, California 94704. Funding +was partially provided by the National Science Foundation under grant +MIP-9311980. The original version of this code was written as part of a +project to build a fixed-point vector processor in collaboration with the +University of California at Berkeley, overseen by Profs. Nelson Morgan and +John Wawrzynek. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR +OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN +HAUSER OR THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, +OR INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF +THE SOFTWARE. + +The following are expressly permitted, even for commercial purposes: +(1) distribution of SoftFloat in whole or in part, as long as this and +other legal notices remain and are prominent, and provided also that, for a +partial distribution, prominent notice is given that it is a subset of the +original; and +(2) inclusion or use of SoftFloat in whole or in part in a derivative +work, provided that the use restrictions above are met and the minimal +documentation requirements stated in the source code are satisfied. + + +---------------------------------------------------------------------------- +Contact Information + +At the time of this writing, the most up-to-date information about SoftFloat +and the latest release can be found at the Web page `http://www.jhauser.us/ +arithmetic/SoftFloat.html'. + diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat-history.txt b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat-history.txt new file mode 100644 index 000000000..daabf0e61 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat-history.txt @@ -0,0 +1,65 @@ + +History of Major Changes to Berkeley SoftFloat, up to Release 2c + +John R. Hauser +2015 January 31 + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 2c (2015 January) + +-- Fixed mistakes affecting some 64-bit processors. + +-- Further improved the documentation and the wording for the legal + restrictions on using SoftFloat. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 2b (2002 May) + +-- Made minor updates to the documentation, including improved wording for + the legal restrictions on using SoftFloat. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 2a (1998 December) + +-- Added functions to convert between 64-bit integers (int64) and all + supported floating-point formats. + +-- Fixed a bug in all 64-bit-version square root functions except + `float32_sqrt' that caused the result sometimes to be off by 1 unit in + the last place (1 ulp) from what it should be. (Bug discovered by Paul + Donahue.) + +-- Improved the Makefiles. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 2 (1997 June) + +-- Created the 64-bit (bits64) version, adding the floatx80 and float128 + formats. + +-- Changed the source directory structure, splitting the sources into a + `bits32' and a `bits64' version. Renamed `environment.h' to `milieu.h' + to avoid confusion with environment variables. + +-- Fixed a small error that caused `float64_round_to_int' often to round the + wrong way in nearest/even mode when the operand was between 2^20 and 2^21 + and halfway between two integers. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 1a (1996 July) + +-- Corrected a mistake that caused borderline underflow cases not to raise + the underflow flag when they should have. (Problem reported by Doug + Priest.) + +-- Added the `float_detect_tininess' variable to control whether tininess is + detected before or after rounding. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Release 1 (1996 July) + +-- Original release. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat-source.txt b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat-source.txt new file mode 100644 index 000000000..ed14355a7 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat-source.txt @@ -0,0 +1,400 @@ + +Berkeley SoftFloat Release 2c Source Documentation + +John R. Hauser +2015 January 30 + + +---------------------------------------------------------------------------- +Introduction + +Berkeley SoftFloat is a software implementation of binary floating-point +that conforms to the IEEE Standard for Floating-Point Arithmetic. +Release 2c of SoftFloat can support four floating-point formats: 32-bit +single-precision, 64-bit double-precision, 80-bit double-extended-precision, +and 128-bit quadruple-precision. All operations required by the older 1985 +version of the IEEE Standard are implemented, except for conversions to and +from decimal. SoftFloat is distributed in the form of C source code, so a +C compiler is needed to compile the code. Support for the 80-bit double- +extended-precision and 128-bit quadruple-precision formats is dependent on +the C compiler implementing a 64-bit integer type. + +This document gives information needed for compiling and/or porting this +SoftFloat release. + +The source code for SoftFloat is intended to be relatively machine- +independent and should be compilable using most any ISO/ANSI C compiler. At +the time of this writing, SoftFloat has been successfully compiled with the +GNU C Compiler (`gcc') for several platforms. + + +---------------------------------------------------------------------------- +Limitations + +As supplied, SoftFloat requires an ISO/ANSI-style C compiler. No attempt +has been made to accomodate compilers that are not ISO-conformant. Older +"K&R-style" compilers are not adequate for compiling SoftFloat. All testing +I have done so far has been with the GNU C Compiler. Compilation with other +compilers should be possible but has not been tested by me. + +The SoftFloat sources assume that source code file names can be longer than +8 characters. In order to compile under an MS-DOS-type system, many of the +source files will need to be renamed, and the source and Makefiles edited +appropriately. Once compiled, the SoftFloat binary does not depend on the +existence of long file names. + +The underlying machine is assumed to be binary with a word size that is a +power of 2. Bytes are 8 bits. Arithmetic on signed integers must modularly +wrap around on overflows (as is already required for unsigned integers +in C). + +Support for the 80-bit double-extended-precision and 128-bit quadruple- +precision formats depends on the C compiler implementing a 64-bit integer +type. If the largest integer type supported by the C compiler is 32 bits, +SoftFloat is limited to the 32-bit single-precision and 64-bit double- +precision formats. + + +---------------------------------------------------------------------------- +Contents + + Introduction + Limitations + Contents + Legal Notice + SoftFloat Source Directory Structure + SoftFloat Source Files + processors/*.h + softfloat/bits*/*/softfloat.h + softfloat/bits*/*/milieu.h + softfloat/bits*/*/softfloat-specialize + softfloat/bits*/softfloat-macros + softfloat/bits*/softfloat.c + Steps to Creating a `softfloat.o' + Making `softfloat.o' a Library + Testing SoftFloat + Timing SoftFloat + Compiler Options and Efficiency + Processor-Specific Optimization of `softfloat.c' Using `softfloat-macros' + Contact Information + + + +---------------------------------------------------------------------------- +Legal Notice + +SoftFloat was written by John R. Hauser. Release 2c of SoftFloat was made +possible in part by the International Computer Science Institute, located +at Suite 600, 1947 Center Street, Berkeley, California 94704. Funding +was partially provided by the National Science Foundation under grant +MIP-9311980. The original version of this code was written as part of a +project to build a fixed-point vector processor in collaboration with the +University of California at Berkeley, overseen by Profs. Nelson Morgan and +John Wawrzynek. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR +OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN +HAUSER OR THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, +OR INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF +THE SOFTWARE. + +The following are expressly permitted, even for commercial purposes: +(1) distribution of SoftFloat in whole or in part, as long as this and +other legal notices remain and are prominent, and provided also that, for a +partial distribution, prominent notice is given that it is a subset of the +original; and +(2) inclusion or use of SoftFloat in whole or in part in a derivative +work, provided that the use restrictions above are met and the minimal +documentation requirements stated in the source code are satisfied. + + +---------------------------------------------------------------------------- +SoftFloat Source Directory Structure + +Because SoftFloat is targeted to multiple platforms, its source code +is slightly scattered between target-specific and target-independent +directories and files. The directory structure is as follows: + + processors + softfloat + bits64 + templates + 386-Win32-GCC + SPARC-Solaris-GCC + bits32 + templates + 386-Win32-GCC + SPARC-Solaris-GCC + +The two topmost directories and their contents are: + + softfloat - Most of the source code needed for SoftFloat. + processors - Target-specific header files that are not specific to + SoftFloat. + +The `softfloat' directory is further split into two parts: + + bits64 - SoftFloat implementation using 64-bit integers. + bits32 - SoftFloat implementation using only 32-bit integers. + +Within these directories are subdirectories for each of the targeted +platforms. The SoftFloat source code is distributed with targets +`386-Win32-GCC' and `SPARC-Solaris-GCC' (and perhaps others) already +prepared for both the 32-bit and 64-bit implementations. Source files +that are not within these target-specific subdirectories are intended to be +target-independent. + +The naming convention used for the target-specific directories is +`--'. The names of the supplied +target directories should be interpreted as follows: + + : + 386 - Intel 386-compatible processor. + SPARC - SPARC processor (as used by Sun computers). + : + Win32 - Microsoft Win32 executable. + Solaris - Sun Solaris executable. + : + GCC - GNU C Compiler. + +You do not need to maintain this convention if you do not want to. + +Alongside the supplied target-specific directories is a `templates' +directory containing a set of "generic" target-specific source files. A +new target directory can be created by copying the `templates' directory and +editing the files inside. (Complete instructions for porting SoftFloat to +a new target are in the section _Steps to Creating a `softfloat.o'_.) Note +that the `templates' directory will not work as a target directory without +some editing. To avoid confusion, it would be wise to refrain from editing +the files inside `templates' directly. + + +---------------------------------------------------------------------------- +SoftFloat Source Files + +The purpose of each source file is described below. In the following, +the `*' symbol is used in place of the name of a specific target, such as +`386-Win32-GCC' or `SPARC-Solaris-GCC', or in place of some other text, as +in `bits*' for either `bits32' or `bits64'. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +processors/*.h + +The target-specific `processors' header file defines integer types +of various sizes, and also defines certain C preprocessor macros that +characterize the target. The two examples supplied are `386-GCC.h' and +`SPARC-GCC.h'. The naming convention used for processor header files is +`-.h'. + +If 64-bit integers are supported by the compiler, the macro name `BITS64' +should be defined here along with the corresponding 64-bit integer +types. In addition, the function-like macro `LIT64' must be defined for +constructing 64-bit integer literals (constants). The `LIT64' macro is used +consistently in the SoftFloat code to annotate 64-bit literals. + +If `BITS64' is not defined, only the 32-bit version of SoftFloat can be +compiled. If `BITS64' _is_ defined, either can be compiled. + +If an inlining attribute (such as an `inline' keyword) is provided by the +compiler, the macro `INLINE' should be defined to the appropriate keyword. +If not, `INLINE' can be set to the keyword `static'. The `INLINE' macro +appears in the SoftFloat source code before every function that should +be inlined by the compiler. SoftFloat depends on inlining to obtain +good speed. Even if inlining cannot be forced with a language keyword, +the compiler may still be able to perform inlining on its own as an +optimization. If a command-line option is needed to convince the compiler +to perform this optimization, this should be assured in the Makefile. (See +the section _Compiler Options and Efficiency_ below.) + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/*/softfloat.h + +The target-specific `softfloat.h' header file defines the SoftFloat +interface as seen by clients. + +Unlike the actual function definitions in `softfloat.c', the declarations +in `softfloat.h' do not use any of the types defined by the `processors' +header file. This is done so that clients will not have to include the +`processors' header file in order to use SoftFloat. Nevertheless, the +target-specific declarations in `softfloat.h' must match what `softfloat.c' +expects. For example, if `int32' is defined as `int' in the `processors' +header file, then in `softfloat.h' the output of `float32_to_int32' should +be stated as `int', although in `softfloat.c' it is given in target- +independent form as `int32'. + +For the `bits64' implementation of SoftFloat, the macro names `FLOATX80' +and `FLOAT128' must be defined in order for the 80-bit double-extended- +precision and 128-bit quadruple-precision formats to be enabled in the +code. Conversely, either or both of these larger formats can be disabled by +simply removing the `#define' of the respective macro. When a format is not +enabled, none of the functions that either input or output the format are +defined, and no space is taken up in `softfloat.o' by such functions. There +is no provision for disabling the usual 32-bit single-precision and 64-bit +double-precision formats. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/*/milieu.h + +The target-specific `milieu.h' header file provides declarations that are +needed to compile SoftFloat. In addition, deviations from ISO/ANSI C by +the compiler (such as names not properly declared in system header files) +are corrected in this header if possible. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/*/softfloat-specialize + +This target-specific C source fragment defines: + +-- whether tininess for underflow is detected before or after rounding by + default; +-- what (if anything) special happens when exceptions are raised; +-- how signaling NaNs are distinguished from quiet NaNs; +-- the default generated quiet NaNs; and +-- how NaNs are propagated from function inputs to output. + +These details are not decided by the IEEE Standard. This fragment is +included verbatim within `softfloat.c' when SoftFloat is compiled. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/softfloat-macros + +This target-independent C source fragment defines a number of arithmetic +functions used as primitives within the `softfloat.c' source. Most of +the functions defined here are intended to be inlined for efficiency. +This fragment is included verbatim within `softfloat.c' when SoftFloat is +compiled. + +Target-specific variations on this file are possible. See the section +_Processor-Specific Optimization of `softfloat.c' Using `softfloat-macros'_ +below. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +softfloat/bits*/softfloat.c + +The target-independent `softfloat.c' source file contains the body of the +SoftFloat implementation. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +The inclusion of the files above within each other (using `#include') can be +shown graphically as follows: + + softfloat/bits*/softfloat.c + softfloat/bits*/*/milieu.h + processors/*.h + softfloat/bits*/*/softfloat.h + softfloat/bits*/*/softfloat-specialize + softfloat/bits*/softfloat-macros + +Note in particular that `softfloat.c' does not include the `processors' +header file directly. Rather, `softfloat.c' includes the target-specific +`milieu.h' header file, which in turn includes the appropriate processor +header file. + + +---------------------------------------------------------------------------- +Steps to Creating a `softfloat.o' + +Porting and/or compiling SoftFloat involves the following steps: + +1. If one does not already exist, create an appropriate `.h' file in the + `processors' directory. + +2. If `BITS64' is defined in the `processors' header file, choose whether + to compile the 32-bit or 64-bit implementation of SoftFloat. If + `BITS64' is not defined, your only choice is the 32-bit implementation. + The remaining steps occur within either the `bits32' or `bits64' + subdirectories. + +3. If one does not already exist, create an appropriate target-specific + subdirectory by copying the given `templates' directory. + +4. In the target-specific subdirectory, edit the files `softfloat-specialize' + and `softfloat.h' to define the desired exception handling functions + and mode control values. In the `softfloat.h' header file, ensure also + that all declarations give the proper target-specific type (such as + `int' or `long') corresponding to the target-independent type used in + `softfloat.c' (such as `int32'). None of the type names declared in the + `processors' header file should appear in `softfloat.h'. + +5. In the target-specific subdirectory, edit the files `milieu.h' and + `Makefile' to reflect the current environment. + +6. In the target-specific subdirectory, execute `make'. + +For the targets that are supplied, if the expected compiler is available +(usually `gcc'), it should only be necessary to execute `make' in the +target-specific subdirectory. + + +---------------------------------------------------------------------------- +Making `softfloat.o' a Library + +SoftFloat is not made into a software library by the supplied Makefile. +If desired, `softfloat.o' can easily be put into its own library (typically +`softfloat.a' or `libsoftfloat.a') using the usual system tool (in UNIX, +`ar'). + + +---------------------------------------------------------------------------- +Testing SoftFloat + +SoftFloat can be tested using the `testsoftfloat' program by the same +author. The `testsoftfloat' program is part of the TestFloat package +available at the Web page `http://www.jhauser.us/arithmetic/TestFloat.html'. + + +---------------------------------------------------------------------------- +Timing SoftFloat + +A program called `timesoftfloat' for timing the SoftFloat functions is +included with the SoftFloat source code. Compiling `timesoftfloat' should +pose no difficulties once `softfloat.o' exists. The supplied Makefile +will create a `timesoftfloat' executable by default after generating +`softfloat.o'. See `timesoftfloat.txt' for documentation about using +`timesoftfloat'. + + +---------------------------------------------------------------------------- +Compiler Options and Efficiency + +In order to get good speed with SoftFloat, it is important that the compiler +inline the routines that have been marked `INLINE' in the code. Even if +inlining cannot be forced by an appropriate definition of the `INLINE' +macro, the compiler may still be able to perform inlining on its own as +an optimization. In that case, the Makefile should be edited to give the +compiler whatever option is required to cause it to inline small functions. + + +---------------------------------------------------------------------------- +Processor-Specific Optimization of `softfloat.c' Using `softfloat-macros' + +The `softfloat-macros' source fragment defines arithmetic functions used +as primitives by `softfloat.c'. This file has been written in a target- +independent form. For a given target, it may be possible to improve on +these functions using target-specific and/or non-ISO-C features (such +as `asm' statements). For example, one of the "macro" functions takes +two word-size integers and returns their full product in two words. +This operation can be done directly in hardware on many processors; but +because it is not available through standard C, the function defined in +`softfloat-macros' uses four multiplications to achieve the same result. + +To address these shortcomings, a customized version of `softfloat-macros' +can be created in any of the target-specific subdirectories. A simple +modification to the target's Makefile should be sufficient to ensure that +the custom version is used instead of the generic one. + + +---------------------------------------------------------------------------- +Contact Information + +At the time of this writing, the most up-to-date information about SoftFloat +and the latest release can be found at the Web page `http://www.jhauser.us/ +arithmetic/SoftFloat.html'. + diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat.txt b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat.txt new file mode 100644 index 000000000..079233174 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/SoftFloat.txt @@ -0,0 +1,389 @@ + +Berkeley SoftFloat Release 2c General Documentation + +John R. Hauser +2015 January 30 + + +---------------------------------------------------------------------------- +Introduction + +Berkeley SoftFloat is a software implementation of binary floating-point +that conforms to the IEEE Standard for Floating-Point Arithmetic. For +Release 2c of SoftFloat, as many as four formats are supported: 32-bit +single-precision, 64-bit double-precision, 80-bit double-extended-precision, +and 128-bit quadruple-precision. All operations required by the older 1985 +version of the IEEE Standard are implemented, except for conversions to and +from decimal. + +This document gives information about the types defined and the routines +implemented by this release of SoftFloat. It does not attempt to define or +explain the IEEE Floating-Point Standard. Details about the standard are +available elsewhere. + + +---------------------------------------------------------------------------- +Limitations + +SoftFloat is written in C and is designed to work with other C code. The +SoftFloat header files assume an ISO/ANSI-style C compiler. No attempt +has been made to accomodate compilers that are not ISO-conformant. In +particular, the distributed header files will not be acceptable to any +compiler that does not recognize function prototypes. + +Support for the 80-bit double-extended-precision and 128-bit quadruple- +precision formats depends on a C compiler that implements 64-bit integer +arithmetic. If the largest integer format supported by the C compiler is +32 bits, SoftFloat is limited to only 32-bit single-precision and 64-bit +double-precision. When that is the case, all references in this document +to 80-bit double-extended-precision, 128-bit quadruple-precision, and 64-bit +integers should be ignored. + + +---------------------------------------------------------------------------- +Contents + + Introduction + Limitations + Contents + Legal Notice + Types and Functions + Rounding Modes + Double-Extended-Precision Rounding Precision + Exceptions and Exception Flags + Function Details + Conversion Functions + Basic Arithmetic Functions + Remainder Functions + Round-to-Integer Functions + Comparison Functions + Signaling NaN Test Functions + Raise-Exception Function + Contact Information + + + +---------------------------------------------------------------------------- +Legal Notice + +SoftFloat was written by John R. Hauser. Release 2c of SoftFloat was made +possible in part by the International Computer Science Institute, located +at Suite 600, 1947 Center Street, Berkeley, California 94704. Funding +was partially provided by the National Science Foundation under grant +MIP-9311980. The original version of this code was written as part of a +project to build a fixed-point vector processor in collaboration with the +University of California at Berkeley, overseen by Profs. Nelson Morgan and +John Wawrzynek. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR +OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN +HAUSER OR THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE +EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE +INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR +OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, +OR INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF +THE SOFTWARE. + +The following are expressly permitted, even for commercial purposes: +(1) distribution of SoftFloat in whole or in part, as long as this and +other legal notices remain and are prominent, and provided also that, for a +partial distribution, prominent notice is given that it is a subset of the +original; and +(2) inclusion or use of SoftFloat in whole or in part in a derivative +work, provided that the use restrictions above are met and the minimal +documentation requirements stated in the source code are satisfied. + + +---------------------------------------------------------------------------- +Types and Functions + +When 64-bit integers are supported by the compiler, the `softfloat.h' header +file defines four types: `float32' (32-bit single-precision), `float64' +(64-bit double-precision), `floatx80' (80-bit double-extended-precision), +and `float128' (128-bit quadruple-precision). The `float32' and `float64' +types are defined in terms of 32-bit and 64-bit integer types, respectively, +while the `float128' type is defined as a structure of two 64-bit integers, +taking into account the byte order of the particular machine being used. +The `floatx80' type is defined as a structure containing one 16-bit and one +64-bit integer, with the machine's byte order again determining the order +within the structure. + +When 64-bit integers are _not_ supported by the compiler, the `softfloat.h' +header file defines only two types: `float32' and `float64'. Because +the ISO/ANSI C Standard guarantees at least one built-in integer type of +32 bits, the `float32' type is identified with an appropriate integer type. +The `float64' type is defined as a structure of two 32-bit integers, with +the machine's byte order determining the order of the fields. + +In either case, the types in `softfloat.h' are defined such that if a system +implements the usual C `float' and `double' types according to the IEEE +Standard, then the `float32' and `float64' types should be indistinguishable +in memory from the native `float' and `double' types. (On the other hand, +when `float32' or `float64' values are placed in processor registers by +the compiler, the type of registers used may differ from those used for the +native `float' and `double' types.) + +SoftFloat implements the following arithmetic operations: + +-- Conversions among all the floating-point formats, and also between + integers (32-bit and 64-bit) and any of the floating-point formats. + +-- The usual add, subtract, multiply, divide, and square root operations for + all floating-point formats. + +-- For each format, the floating-point remainder operation defined by the + IEEE Standard. + +-- For each floating-point format, a "round to integer" operation that + rounds to the nearest integer value in the same format. (The floating- + point formats can hold integer values, of course.) + +-- Comparisons between two values in the same floating-point format. + +The only functions required by the 1985 IEEE Standard that are not provided +are conversions to and from decimal. + + +---------------------------------------------------------------------------- +Rounding Modes + +All four rounding modes prescribed by the 1985 IEEE Standard are implemented +for all operations that require rounding. The rounding mode is selected +by the global variable `float_rounding_mode'. This variable may be set +to one of the values `float_round_nearest_even', `float_round_to_zero', +`float_round_down', or `float_round_up'. The rounding mode is initialized +to nearest/even. + + +---------------------------------------------------------------------------- +Double-Extended-Precision Rounding Precision + +For 80-bit double-extended-precision (`floatx80') only, the rounding +precision of the basic arithmetic operations is controlled by the global +variable `floatx80_rounding_precision'. The operations affected are: + + floatx80_add floatx80_sub floatx80_mul floatx80_div floatx80_sqrt + +When `floatx80_rounding_precision' is set to its default value of 80, +these operations are rounded (as usual) to the full precision of the 80-bit +double-extended-precision format. Setting `floatx80_rounding_precision' to +32 or to 64 causes the operations listed to be rounded to reduced precision +equivalent to 32-bit single-precision (`float32') or to 64-bit double- +precision (`float64'), respectively. When rounding to reduced precision, +additional bits in the result significand beyond the rounding point are set +to zero. The consequences of setting `floatx80_rounding_precision' to a +value other than 32, 64, or 80 is not specified. Operations other than the +ones listed above are not affected by `floatx80_rounding_precision'. + + +---------------------------------------------------------------------------- +Exceptions and Exception Flags + +All five exception flags required by the IEEE Standard are implemented. +Each flag is stored as a separate bit in the global variable +`float_exception_flags'. The positions of the exception flag bits within +this variable are determined by the bit masks `float_flag_inexact', +`float_flag_underflow', `float_flag_overflow', `float_flag_divbyzero', and +`float_flag_invalid'. The exception flags variable is initialized to all 0, +meaning no exceptions. + +An individual exception flag can be cleared with the statement + + float_exception_flags &= ~ float_flag_; + +where `' is the appropriate name. To raise a floating-point +exception, the SoftFloat function `float_raise' should be used (see below). + +In the terminology of the IEEE Standard, SoftFloat can detect tininess +for underflow either before or after rounding. The choice is made by +the global variable `float_detect_tininess', which can be set to either +`float_tininess_before_rounding' or `float_tininess_after_rounding'. +Detecting tininess after rounding is better because it results in fewer +spurious underflow signals. The other option is provided for compatibility +with some systems. Like most systems, SoftFloat always detects loss of +accuracy for underflow as an inexact result. + + +---------------------------------------------------------------------------- +Function Details + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Conversion Functions + +All conversions among the floating-point formats are supported, as are all +conversions between a floating-point format and 32-bit and 64-bit signed +integers. The complete set of conversion functions is: + + int32_to_float32 int64_to_float32 + int32_to_float64 int64_to_float64 + int32_to_floatx80 int64_to_floatx80 + int32_to_float128 int64_to_float128 + + float32_to_int32 float32_to_int64 + float64_to_int32 float64_to_int64 + floatx80_to_int32 floatx80_to_int64 + float128_to_int32 float128_to_int64 + + float32_to_float64 float32_to_floatx80 float32_to_float128 + float64_to_float32 float64_to_floatx80 float64_to_float128 + floatx80_to_float32 floatx80_to_float64 floatx80_to_float128 + float128_to_float32 float128_to_float64 float128_to_floatx80 + +Each conversion function takes one operand of the appropriate type and +returns one result. Conversions from a smaller to a larger floating-point +format are always exact and so require no rounding. Conversions from 32-bit +integers to 64-bit double-precision and larger formats are also exact, and +likewise for conversions from 64-bit integers to 80-bit double-extended- +precision and 128-bit quadruple-precision. + +Conversions from floating-point to integer raise the invalid exception if +the source value cannot be rounded to a representable integer of the desired +size (32 or 64 bits). If the floating-point operand is a NaN, the largest +positive integer is returned. Otherwise, if the conversion overflows, the +largest integer with the same sign as the operand is returned. + +On conversions to integer, if the floating-point operand is not already +an integer value, the operand is rounded according to the current rounding +mode as specified by `float_rounding_mode'. Because C (and perhaps other +languages) require that conversions to integers be rounded toward zero, the +following functions are provided for improved speed and convenience: + + float32_to_int32_round_to_zero float32_to_int64_round_to_zero + float64_to_int32_round_to_zero float64_to_int64_round_to_zero + floatx80_to_int32_round_to_zero floatx80_to_int64_round_to_zero + float128_to_int32_round_to_zero float128_to_int64_round_to_zero + +These variant functions ignore `float_rounding_mode' and always round toward +zero. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Basic Arithmetic Functions + +The following basic arithmetic functions are provided: + + float32_add float32_sub float32_mul float32_div float32_sqrt + float64_add float64_sub float64_mul float64_div float64_sqrt + floatx80_add floatx80_sub floatx80_mul floatx80_div floatx80_sqrt + float128_add float128_sub float128_mul float128_div float128_sqrt + +Each function takes two operands, except for `sqrt' which takes only one. +The operands and result are all of the same type. + +Rounding of the 80-bit double-extended-precision (`floatx80') functions is +affected by the `floatx80_rounding_precision' variable, as explained above +in the section _Double-Extended-Precision Rounding Precision_. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Remainder Functions + +For each format, SoftFloat implements the remainder function according to +the IEEE Standard. The remainder functions are: + + float32_rem + float64_rem + floatx80_rem + float128_rem + +Each remainder function takes two operands. The operands and result are all +of the same type. Given operands x and y, the remainder functions return +the value x - n*y, where n is the integer closest to x/y. If x/y is exactly +halfway between two integers, n is the even integer closest to x/y. The +remainder functions are always exact and so require no rounding. + +Depending on the relative magnitudes of the operands, the remainder +functions can take considerably longer to execute than the other SoftFloat +functions. This is inherent in the remainder operation itself and is not a +flaw in the SoftFloat implementation. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Round-to-Integer Functions + +For each format, SoftFloat implements the round-to-integer function +specified by the IEEE Standard. The functions are: + + float32_round_to_int + float64_round_to_int + floatx80_round_to_int + float128_round_to_int + +Each function takes a single floating-point operand and returns a result of +the same type. (Note that the result is not an integer type.) The operand +is rounded to an exact integer according to the current rounding mode, and +the resulting integer value is returned in the same floating-point format. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Comparison Functions + +The following floating-point comparison functions are provided: + + float32_eq float32_le float32_lt + float64_eq float64_le float64_lt + floatx80_eq floatx80_le floatx80_lt + float128_eq float128_le float128_lt + +Each function takes two operands of the same type and returns a 1 or 0 +representing either _true_ or _false_. The abbreviation `eq' stands for +"equal" (=); `le' stands for "less than or equal" (<=); and `lt' stands for +"less than" (<). + +The usual greater-than (>), greater-than-or-equal (>=), and not-equal (!=) +functions are easily obtained using the functions provided. The not-equal +function is just the logical complement of the equal function. The greater- +than-or-equal function is identical to the less-than-or-equal function with +the operands reversed, and the greater-than function is identical to the +less-than function with the operands reversed. + +The IEEE Standard specifies that the less-than-or-equal and less-than +functions raise the invalid exception if either input is any kind of NaN. +The equal functions, on the other hand, are defined not to raise the invalid +exception on quiet NaNs. For completeness, SoftFloat provides the following +additional functions: + + float32_eq_signaling float32_le_quiet float32_lt_quiet + float64_eq_signaling float64_le_quiet float64_lt_quiet + floatx80_eq_signaling floatx80_le_quiet floatx80_lt_quiet + float128_eq_signaling float128_le_quiet float128_lt_quiet + +The `signaling' equal functions are identical to the standard functions +except that the invalid exception is raised for any NaN input. Likewise, +the `quiet' comparison functions are identical to their counterparts except +that the invalid exception is not raised for quiet NaNs. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Signaling NaN Test Functions + +The following functions test whether a floating-point value is a signaling +NaN: + + float32_is_signaling_nan + float64_is_signaling_nan + floatx80_is_signaling_nan + float128_is_signaling_nan + +The functions take one operand and return 1 if the operand is a signaling +NaN and 0 otherwise. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Raise-Exception Function + +SoftFloat provides a function for raising floating-point exceptions: + + float_raise + +The function takes a mask indicating the set of exceptions to raise. No +result is returned. In addition to setting the specified exception flags, +this function may cause a trap or abort appropriate for the current system. + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +---------------------------------------------------------------------------- +Contact Information + +At the time of this writing, the most up-to-date information about SoftFloat +and the latest release can be found at the Web page `http://www.jhauser.us/ +arithmetic/SoftFloat.html'. + diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat-macros.h b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat-macros.h new file mode 100644 index 000000000..dc52a240c --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat-macros.h @@ -0,0 +1,713 @@ + +/*============================================================================ + +This C source fragment is part of the Berkeley SoftFloat IEEE Floating-Point +Arithmetic Package, Release 2c, by John R. Hauser. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER +PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR +THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY +INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE +(possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER +PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR +INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE +SOFTWARE. + +Derivative works require also that (1) the source code for the derivative work +includes prominent notice that the work is derivative, and (2) the source code +includes prominent notice of these three paragraphs for those parts of this +code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Shifts `a' right by the number of bits given in `count'. If any nonzero +| bits are shifted off, they are "jammed" into the least significant bit of +| the result by setting the least significant bit to 1. The value of `count' +| can be arbitrarily large; in particular, if `count' is greater than 32, the +| result will be either 0 or 1, depending on whether `a' is zero or nonzero. +| The result is stored in the location pointed to by `zPtr'. +*----------------------------------------------------------------------------*/ + +INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr ) +{ + bits32 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 32 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; + +} + +/*---------------------------------------------------------------------------- +| Shifts `a' right by the number of bits given in `count'. If any nonzero +| bits are shifted off, they are "jammed" into the least significant bit of +| the result by setting the least significant bit to 1. The value of `count' +| can be arbitrarily large; in particular, if `count' is greater than 64, the +| result will be either 0 or 1, depending on whether `a' is zero or nonzero. +| The result is stored in the location pointed to by `zPtr'. +*----------------------------------------------------------------------------*/ + +INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr ) +{ + bits64 z; + + if ( count == 0 ) { + z = a; + } + else if ( count < 64 ) { + z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); + } + else { + z = ( a != 0 ); + } + *zPtr = z; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 +| _plus_ the number of bits given in `count'. The shifted result is at most +| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The +| bits shifted off form a second 64-bit result as follows: The _last_ bit +| shifted off is the most-significant bit of the extra result, and the other +| 63 bits of the extra result are all zero if and only if _all_but_the_last_ +| bits shifted off were all zero. This extra result is stored in the location +| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. +| (This routine makes more sense if `a0' and `a1' are considered to form +| a fixed-point value with binary point between `a0' and `a1'. This fixed- +| point value is shifted right by the number of bits given in `count', and +| the integer part of the result is returned at the location pointed to by +| `z0Ptr'. The fractional part of the result may be slightly corrupted as +| described above, and is returned at the location pointed to by `z1Ptr'.) +*----------------------------------------------------------------------------*/ + +INLINE void + shift64ExtraRightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else { + z1 = ( ( a0 | a1 ) != 0 ); + } + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +| number of bits given in `count'. Any bits shifted off are lost. The value +| of `count' can be arbitrarily large; in particular, if `count' is greater +| than 128, the result will be 0. The result is broken into two 64-bit pieces +| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + shift128Right( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count ); + z0 = a0>>count; + } + else { + z1 = ( count < 128 ) ? ( a0>>( count & 63 ) ) : 0; + z0 = 0; + } + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the +| number of bits given in `count'. If any nonzero bits are shifted off, they +| are "jammed" into the least significant bit of the result by setting the +| least significant bit to 1. The value of `count' can be arbitrarily large; +| in particular, if `count' is greater than 128, the result will be either +| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or +| nonzero. The result is broken into two 64-bit pieces which are stored at +| the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + shift128RightJamming( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z0, z1; + int8 negCount = ( - count ) & 63; + + if ( count == 0 ) { + z1 = a1; + z0 = a0; + } + else if ( count < 64 ) { + z1 = ( a0<>count ) | ( ( a1<>count; + } + else { + if ( count == 64 ) { + z1 = a0 | ( a1 != 0 ); + } + else if ( count < 128 ) { + z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<>count ); + z0 = a0>>count; + } + else { + if ( count == 64 ) { + z2 = a1; + z1 = a0; + } + else { + a2 |= a1; + if ( count < 128 ) { + z2 = a0<>( count & 63 ); + } + else { + z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); + z1 = 0; + } + } + z0 = 0; + } + z2 |= ( a2 != 0 ); + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the +| number of bits given in `count'. Any bits shifted off are lost. The value +| of `count' must be less than 64. The result is broken into two 64-bit +| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + shortShift128Left( + bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1<>( ( - count ) & 63 ) ); + +} + +/*---------------------------------------------------------------------------- +| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left +| by the number of bits given in `count'. Any bits shifted off are lost. +| The value of `count' must be less than 64. The result is broken into three +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', +| `z1Ptr', and `z2Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + shortShift192Left( + bits64 a0, + bits64 a1, + bits64 a2, + int16 count, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 negCount; + + z2 = a2<>negCount; + z0 |= a1>>negCount; + } + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit +| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so +| any carry out is lost. The result is broken into two 64-bit pieces which +| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + add128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits64 z1; + + z1 = a1 + b1; + *z1Ptr = z1; + *z0Ptr = a0 + b0 + ( z1 < a1 ); + +} + +/*---------------------------------------------------------------------------- +| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the +| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is +| modulo 2^192, so any carry out is lost. The result is broken into three +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', +| `z1Ptr', and `z2Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + add192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 carry0, carry1; + + z2 = a2 + b2; + carry1 = ( z2 < a2 ); + z1 = a1 + b1; + carry0 = ( z1 < a1 ); + z0 = a0 + b0; + z1 += carry1; + z0 += ( z1 < carry1 ); + z0 += carry0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the +| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo +| 2^128, so any borrow out (carry out) is lost. The result is broken into two +| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and +| `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + sub128( + bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + + *z1Ptr = a1 - b1; + *z0Ptr = a0 - b0 - ( a1 < b1 ); + +} + +/*---------------------------------------------------------------------------- +| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' +| from the 192-bit value formed by concatenating `a0', `a1', and `a2'. +| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The +| result is broken into three 64-bit pieces which are stored at the locations +| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + sub192( + bits64 a0, + bits64 a1, + bits64 a2, + bits64 b0, + bits64 b1, + bits64 b2, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2; + int8 borrow0, borrow1; + + z2 = a2 - b2; + borrow1 = ( a2 < b2 ); + z1 = a1 - b1; + borrow0 = ( a1 < b1 ); + z0 = a0 - b0; + z0 -= ( z1 < borrow1 ); + z1 -= borrow1; + z0 -= borrow0; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken +| into two 64-bit pieces which are stored at the locations pointed to by +| `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr ) +{ + bits32 aHigh, aLow, bHigh, bLow; + bits64 z0, zMiddleA, zMiddleB, z1; + + aLow = a; + aHigh = a>>32; + bLow = b; + bHigh = b>>32; + z1 = ( (bits64) aLow ) * bLow; + zMiddleA = ( (bits64) aLow ) * bHigh; + zMiddleB = ( (bits64) aHigh ) * bLow; + z0 = ( (bits64) aHigh ) * bHigh; + zMiddleA += zMiddleB; + z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); + zMiddleA <<= 32; + z1 += zMiddleA; + z0 += ( z1 < zMiddleA ); + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by +| `b' to obtain a 192-bit product. The product is broken into three 64-bit +| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and +| `z2Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + mul128By64To192( + bits64 a0, + bits64 a1, + bits64 b, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr + ) +{ + bits64 z0, z1, z2, more1; + + mul64To128( a1, b, &z1, &z2 ); + mul64To128( a0, b, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the +| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit +| product. The product is broken into four 64-bit pieces which are stored at +| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. +*----------------------------------------------------------------------------*/ + +INLINE void + mul128To256( + bits64 a0, + bits64 a1, + bits64 b0, + bits64 b1, + bits64 *z0Ptr, + bits64 *z1Ptr, + bits64 *z2Ptr, + bits64 *z3Ptr + ) +{ + bits64 z0, z1, z2, z3; + bits64 more1, more2; + + mul64To128( a1, b1, &z2, &z3 ); + mul64To128( a1, b0, &z1, &more2 ); + add128( z1, more2, 0, z2, &z1, &z2 ); + mul64To128( a0, b0, &z0, &more1 ); + add128( z0, more1, 0, z1, &z0, &z1 ); + mul64To128( a0, b1, &more1, &more2 ); + add128( more1, more2, 0, z2, &more1, &z2 ); + add128( z0, z1, 0, more1, &z0, &z1 ); + *z3Ptr = z3; + *z2Ptr = z2; + *z1Ptr = z1; + *z0Ptr = z0; + +} + +/*---------------------------------------------------------------------------- +| Returns an approximation to the 64-bit integer quotient obtained by dividing +| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The +| divisor `b' must be at least 2^63. If q is the exact quotient truncated +| toward zero, the approximation returned lies between q and q + 2 inclusive. +| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +| unsigned integer is returned. +*----------------------------------------------------------------------------*/ + +static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b ) +{ + bits64 b0, b1; + bits64 rem0, rem1, term0, term1; + bits64 z; + + if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); + b0 = b>>32; + z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; + mul64To128( b, z, &term0, &term1 ); + sub128( a0, a1, term0, term1, &rem0, &rem1 ); + while ( ( (sbits64) rem0 ) < 0 ) { + z -= LIT64( 0x100000000 ); + b1 = b<<32; + add128( rem0, rem1, b0, b1, &rem0, &rem1 ); + } + rem0 = ( rem0<<32 ) | ( rem1>>32 ); + z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns an approximation to the square root of the 32-bit significand given +| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of +| `aExp' (the least significant bit) is 1, the integer returned approximates +| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' +| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either +| case, the approximation returned lies strictly within +/-2 of the exact +| value. +*----------------------------------------------------------------------------*/ + +static bits32 estimateSqrt32( int16 aExp, bits32 a ) +{ + static const bits16 sqrtOddAdjustments[] = { + 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, + 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 + }; + static const bits16 sqrtEvenAdjustments[] = { + 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, + 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 + }; + int8 index; + bits32 z; + + index = ( a>>27 ) & 15; + if ( aExp & 1 ) { + z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; + z = ( ( a / z )<<14 ) + ( z<<15 ); + a >>= 1; + } + else { + z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; + z = a / z + z; + z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); + if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 ); + } + return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 32 is returned. +*----------------------------------------------------------------------------*/ + +static int8 countLeadingZeros32( bits32 a ) +{ + static const int8 countLeadingZerosHigh[] = { + 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + int8 shiftCount; + + shiftCount = 0; + if ( a < 0x10000 ) { + shiftCount += 16; + a <<= 16; + } + if ( a < 0x1000000 ) { + shiftCount += 8; + a <<= 8; + } + shiftCount += countLeadingZerosHigh[ a>>24 ]; + return shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 64 is returned. +*----------------------------------------------------------------------------*/ + +static int8 countLeadingZeros64( bits64 a ) +{ + int8 shiftCount; + + shiftCount = 0; + if ( a < ( (bits64) 1 )<<32 ) { + shiftCount += 32; + } + else { + a >>= 32; + } + shiftCount += countLeadingZeros32( a ); + return shiftCount; + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' +| is equal to the 128-bit value formed by concatenating `b0' and `b1'. +| Otherwise, returns 0. +*----------------------------------------------------------------------------*/ + +INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 == b0 ) && ( a1 == b1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +| than or equal to the 128-bit value formed by concatenating `b0' and `b1'. +| Otherwise, returns 0. +*----------------------------------------------------------------------------*/ + +INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less +| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, +| returns 0. +*----------------------------------------------------------------------------*/ + +INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is +| not equal to the 128-bit value formed by concatenating `b0' and `b1'. +| Otherwise, returns 0. +*----------------------------------------------------------------------------*/ + +INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 ) +{ + + return ( a0 != b0 ) || ( a1 != b1 ); + +} + diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat-specialize.h b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat-specialize.h new file mode 100644 index 000000000..e87d175b7 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat-specialize.h @@ -0,0 +1,457 @@ + +/*============================================================================ + +This C source fragment is part of the Berkeley SoftFloat IEEE Floating-Point +Arithmetic Package, Release 2c, by John R. Hauser. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER +PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR +THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY +INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE +(possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER +PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR +INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE +SOFTWARE. + +Derivative works require also that (1) the source code for the derivative work +includes prominent notice that the work is derivative, and (2) the source code +includes prominent notice of these three paragraphs for those parts of this +code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| Underflow tininess-detection mode, statically initialized to default value. +| (The declaration in `softfloat.h' must match the `int8' type here.) +*----------------------------------------------------------------------------*/ +int8 float_detect_tininess = float_tininess_after_rounding; + +/*---------------------------------------------------------------------------- +| Raises the exceptions specified by `flags'. Floating-point traps can be +| defined here if desired. It is currently not possible for such a trap +| to substitute a result value. If traps are not implemented, this routine +| should be simply `float_exception_flags |= flags;'. +*----------------------------------------------------------------------------*/ + +void float_raise( int8 flags ) +{ + + float_exception_flags |= flags; + +} + +/*---------------------------------------------------------------------------- +| Internal canonical NaN format. +*----------------------------------------------------------------------------*/ +typedef struct { + flag sign; + bits64 high, low; +} commonNaNT; + +/*---------------------------------------------------------------------------- +| The pattern for a default generated single-precision NaN. +*----------------------------------------------------------------------------*/ +#define float32_default_nan 0xFFC00000 + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float32_is_nan( float32 a ) +{ + + return ( 0xFF000000 < (bits32) ( a<<1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float32_is_signaling_nan( float32 a ) +{ + + return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point NaN +| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT float32ToCommonNaN( float32 a ) +{ + commonNaNT z; + + if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>31; + z.low = 0; + z.high = ( (bits64) a )<<41; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the single- +| precision floating-point format. +*----------------------------------------------------------------------------*/ + +static float32 commonNaNToFloat32( commonNaNT a ) +{ + + return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); + +} + +/*---------------------------------------------------------------------------- +| Takes two single-precision floating-point values `a' and `b', one of which +| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float32 propagateFloat32NaN( float32 a, float32 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float32_is_nan( a ); + aIsSignalingNaN = float32_is_signaling_nan( a ); + bIsNaN = float32_is_nan( b ); + bIsSignalingNaN = float32_is_signaling_nan( b ); + a |= 0x00400000; + b |= 0x00400000; + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsSignalingNaN ) { + if ( bIsSignalingNaN ) goto returnLargerSignificand; + return bIsNaN ? b : a; + } + else if ( aIsNaN ) { + if ( bIsSignalingNaN | ! bIsNaN ) return a; + returnLargerSignificand: + if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b; + if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a; + return ( a < b ) ? a : b; + } + else { + return b; + } + +} + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-precision NaN. +*----------------------------------------------------------------------------*/ +#define float64_default_nan LIT64( 0xFFF8000000000000 ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float64_is_nan( float64 a ) +{ + + return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is a signaling +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float64_is_signaling_nan( float64 a ) +{ + + return + ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) + && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point NaN +| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT float64ToCommonNaN( float64 a ) +{ + commonNaNT z; + + if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a>>63; + z.low = 0; + z.high = a<<12; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the double- +| precision floating-point format. +*----------------------------------------------------------------------------*/ + +static float64 commonNaNToFloat64( commonNaNT a ) +{ + + return + ( ( (bits64) a.sign )<<63 ) + | LIT64( 0x7FF8000000000000 ) + | ( a.high>>12 ); + +} + +/*---------------------------------------------------------------------------- +| Takes two double-precision floating-point values `a' and `b', one of which +| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float64 propagateFloat64NaN( float64 a, float64 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float64_is_nan( a ); + aIsSignalingNaN = float64_is_signaling_nan( a ); + bIsNaN = float64_is_nan( b ); + bIsSignalingNaN = float64_is_signaling_nan( b ); + a |= LIT64( 0x0008000000000000 ); + b |= LIT64( 0x0008000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsSignalingNaN ) { + if ( bIsSignalingNaN ) goto returnLargerSignificand; + return bIsNaN ? b : a; + } + else if ( aIsNaN ) { + if ( bIsSignalingNaN | ! bIsNaN ) return a; + returnLargerSignificand: + if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b; + if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a; + return ( a < b ) ? a : b; + } + else { + return b; + } + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| The pattern for a default generated double-extended-precision NaN. +| The `high' and `low' values hold the most- and least-significant bits, +| respectively. +*----------------------------------------------------------------------------*/ +#define floatx80_default_nan_high 0xFFFF +#define floatx80_default_nan_low LIT64( 0xC000000000000000 ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is a +| NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag floatx80_is_nan( floatx80 a ) +{ + + return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is a +| signaling NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag floatx80_is_signaling_nan( floatx80 a ) +{ + bits64 aLow; + + aLow = a.low & ~ LIT64( 0x4000000000000000 ); + return + ( ( a.high & 0x7FFF ) == 0x7FFF ) + && (bits64) ( aLow<<1 ) + && ( a.low == aLow ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-extended-precision floating- +| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the +| invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT floatx80ToCommonNaN( floatx80 a ) +{ + commonNaNT z; + + if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>15; + z.low = 0; + z.high = a.low<<1; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the double- +| extended-precision floating-point format. +*----------------------------------------------------------------------------*/ + +static floatx80 commonNaNToFloatx80( commonNaNT a ) +{ + floatx80 z; + + z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); + z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes two double-extended-precision floating-point values `a' and `b', one +| of which is a NaN, and returns the appropriate NaN result. If either `a' or +| `b' is a signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = floatx80_is_nan( a ); + aIsSignalingNaN = floatx80_is_signaling_nan( a ); + bIsNaN = floatx80_is_nan( b ); + bIsSignalingNaN = floatx80_is_signaling_nan( b ); + a.low |= LIT64( 0xC000000000000000 ); + b.low |= LIT64( 0xC000000000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsSignalingNaN ) { + if ( bIsSignalingNaN ) goto returnLargerSignificand; + return bIsNaN ? b : a; + } + else if ( aIsNaN ) { + if ( bIsSignalingNaN | ! bIsNaN ) return a; + returnLargerSignificand: + if ( a.low < b.low ) return b; + if ( b.low < a.low ) return a; + return ( a.high < b.high ) ? a : b; + } + else { + return b; + } + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| The pattern for a default generated quadruple-precision NaN. The `high' and +| `low' values hold the most- and least-significant bits, respectively. +*----------------------------------------------------------------------------*/ +#define float128_default_nan_high LIT64( 0xFFFF800000000000 ) +#define float128_default_nan_low LIT64( 0x0000000000000000 ) + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; +| otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float128_is_nan( float128 a ) +{ + + return + ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) + && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is a +| signaling NaN; otherwise returns 0. +*----------------------------------------------------------------------------*/ + +flag float128_is_signaling_nan( float128 a ) +{ + + return + ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) + && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point NaN +| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ + +static commonNaNT float128ToCommonNaN( float128 a ) +{ + commonNaNT z; + + if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); + z.sign = a.high>>63; + shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the canonical NaN `a' to the quadruple- +| precision floating-point format. +*----------------------------------------------------------------------------*/ + +static float128 commonNaNToFloat128( commonNaNT a ) +{ + float128 z; + + shift128Right( a.high, a.low, 16, &z.high, &z.low ); + z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes two quadruple-precision floating-point values `a' and `b', one of +| which is a NaN, and returns the appropriate NaN result. If either `a' or +| `b' is a signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ + +static float128 propagateFloat128NaN( float128 a, float128 b ) +{ + flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; + + aIsNaN = float128_is_nan( a ); + aIsSignalingNaN = float128_is_signaling_nan( a ); + bIsNaN = float128_is_nan( b ); + bIsSignalingNaN = float128_is_signaling_nan( b ); + a.high |= LIT64( 0x0000800000000000 ); + b.high |= LIT64( 0x0000800000000000 ); + if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); + if ( aIsSignalingNaN ) { + if ( bIsSignalingNaN ) goto returnLargerSignificand; + return bIsNaN ? b : a; + } + else if ( aIsNaN ) { + if ( bIsSignalingNaN | ! bIsNaN ) return a; + returnLargerSignificand: + if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b; + if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a; + return ( a.high < b.high ) ? a : b; + } + else { + return b; + } + +} + +#endif + diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat.cpp b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat.cpp new file mode 100644 index 000000000..4b99845c6 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat.cpp @@ -0,0 +1,5207 @@ + +/*============================================================================ + +This C source file is part of the Berkeley SoftFloat IEEE Floating-Point +Arithmetic Package, Release 2c, by John R. Hauser. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER +PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR +THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY +INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE +(possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER +PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR +INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE +SOFTWARE. + +Derivative works require also that (1) the source code for the derivative work +includes prominent notice that the work is derivative, and (2) the source code +includes prominent notice of these three paragraphs for those parts of this +code that are retained. + +=============================================================================*/ + +//#include "compiler.h" + +//#ifdef SUPPORT_FPU_SOFTFLOAT + +#ifndef INLINE + #ifdef __cplusplus + #define INLINE inline + #else + #define INLINE __inline + #endif +#endif + +#include "softfloatdef.h" +//#include "milieu.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Floating-point rounding mode, double-extended-precision rounding precision, +| and exception flags. +*----------------------------------------------------------------------------*/ +int8 float_rounding_mode = float_round_nearest_even; +int8 float_exception_flags = 0; +#ifdef FLOATX80 +int8 floatx80_rounding_precision = 80; +#endif + +/*---------------------------------------------------------------------------- +| Primitive arithmetic functions, including multi-word arithmetic, and +| division and square root approximations. (Can be specialized to target if +| desired.) +*----------------------------------------------------------------------------*/ +#include "softfloat-macros.h" // rename softfloat-macros -> softfloat-macros.h + +/*---------------------------------------------------------------------------- +| Functions and definitions to determine: (1) whether tininess for underflow +| is detected before or after rounding by default, (2) what (if anything) +| happens when exceptions are raised, (3) how signaling NaNs are distinguished +| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs +| are propagated from function inputs to output. These details are target- +| specific. +*----------------------------------------------------------------------------*/ +#include "softfloat-specialize.h" // rename softfloat-specialize -> softfloat-specialize.h + +/*---------------------------------------------------------------------------- +| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 +| and 7, and returns the properly rounded 32-bit integer corresponding to the +| input. If `zSign' is 1, the input is negated before being converted to an +| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input +| is simply rounded to an integer, with the inexact exception raised if the +| input cannot be represented exactly as an integer. However, if the fixed- +| point input is too large, the invalid exception is raised and the largest +| positive or negative integer is returned. +*----------------------------------------------------------------------------*/ + +static int32 roundAndPackInt32( flag zSign, bits64 absZ ) +{ + int8 roundingMode; + flag roundNearestEven; + int8 roundIncrement, roundBits; + int32 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + roundIncrement = 0x40; + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + roundIncrement = 0; + } + else { + roundIncrement = 0x7F; + if ( zSign ) { + if ( roundingMode == float_round_up ) roundIncrement = 0; + } + else { + if ( roundingMode == float_round_down ) roundIncrement = 0; + } + } + } + roundBits = absZ & 0x7F; + absZ = ( absZ + roundIncrement )>>7; + absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + z = absZ; + if ( zSign ) z = - z; + z = (sbits32) z; + if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) { + float_raise( float_flag_invalid ); + return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( roundBits ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and +| `absZ1', with binary point between bits 63 and 64 (between the input words), +| and returns the properly rounded 64-bit integer corresponding to the input. +| If `zSign' is 1, the input is negated before being converted to an integer. +| Ordinarily, the fixed-point input is simply rounded to an integer, with +| the inexact exception raised if the input cannot be represented exactly as +| an integer. However, if the fixed-point input is too large, the invalid +| exception is raised and the largest positive or negative integer is +| returned. +*----------------------------------------------------------------------------*/ + +static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 ) +{ + int8 roundingMode; + flag roundNearestEven, increment; + int64 z; + + roundingMode = float_rounding_mode; + roundNearestEven = ( roundingMode == float_round_nearest_even ); + increment = ( (sbits64) absZ1 < 0 ); + if ( ! roundNearestEven ) { + if ( roundingMode == float_round_to_zero ) { + increment = 0; + } + else { + if ( zSign ) { + increment = ( roundingMode == float_round_down ) && absZ1; + } + else { + increment = ( roundingMode == float_round_up ) && absZ1; + } + } + } + if ( increment ) { + ++absZ0; + if ( absZ0 == 0 ) goto overflow; + absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven ); + } + z = absZ0; + if ( zSign ) z = - z; + z = (sbits64) z; + if ( z && ( ( z < 0 ) ^ zSign ) ) { + overflow: + float_raise( float_flag_invalid ); + return + zSign ? (sbits64) LIT64( 0x8000000000000000 ) + : LIT64( 0x7FFFFFFFFFFFFFFF ); + } + if ( absZ1 ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the fraction bits of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE bits32 extractFloat32Frac( float32 a ) +{ + + return a & 0x007FFFFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the exponent bits of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE int16 extractFloat32Exp( float32 a ) +{ + + return ( a>>23 ) & 0xFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the single-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE flag extractFloat32Sign( float32 a ) +{ + + return a>>31; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal single-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( aSig ) - 8; + *zSigPtr = aSig<>7; + zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper single-precision floating- +| point value corresponding to the abstract input. This routine is just like +| `roundAndPackFloat32' except that `zSig' does not have to be normalized. +| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the "true" +| floating-point exponent. +*----------------------------------------------------------------------------*/ + +static float32 + normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros32( zSig ) - 1; + return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<>52 ) & 0x7FF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the double-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE flag extractFloat64Sign( float64 a ) +{ + + return a>>63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal double-precision floating-point value represented +| by the denormalized significand `aSig'. The normalized exponent and +| significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ) - 11; + *zSigPtr = aSig<>10; + zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven ); + if ( zSig == 0 ) zExp = 0; + return packFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Takes an abstract floating-point value having sign `zSign', exponent `zExp', +| and significand `zSig', and returns the proper double-precision floating- +| point value corresponding to the abstract input. This routine is just like +| `roundAndPackFloat64' except that `zSig' does not have to be normalized. +| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the "true" +| floating-point exponent. +*----------------------------------------------------------------------------*/ + +static float64 + normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( zSig ) - 1; + return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<>15; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal double-extended-precision floating-point value +| represented by the denormalized significand `aSig'. The normalized exponent +| and significand are stored at the locations pointed to by `zExpPtr' and +| `zSigPtr', respectively. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr ) +{ + int8 shiftCount; + + shiftCount = countLeadingZeros64( aSig ); + *zSigPtr = aSig<>48 ) & 0x7FFF; + +} + +/*---------------------------------------------------------------------------- +| Returns the sign bit of the quadruple-precision floating-point value `a'. +*----------------------------------------------------------------------------*/ + +INLINE flag extractFloat128Sign( float128 a ) +{ + + return a.high>>63; + +} + +/*---------------------------------------------------------------------------- +| Normalizes the subnormal quadruple-precision floating-point value +| represented by the denormalized significand formed by the concatenation of +| `aSig0' and `aSig1'. The normalized exponent is stored at the location +| pointed to by `zExpPtr'. The most significant 49 bits of the normalized +| significand are stored at the location pointed to by `zSig0Ptr', and the +| least significant 64 bits of the normalized significand are stored at the +| location pointed to by `zSig1Ptr'. +*----------------------------------------------------------------------------*/ + +static void + normalizeFloat128Subnormal( + bits64 aSig0, + bits64 aSig1, + int32 *zExpPtr, + bits64 *zSig0Ptr, + bits64 *zSig1Ptr + ) +{ + int8 shiftCount; + + if ( aSig0 == 0 ) { + shiftCount = countLeadingZeros64( aSig1 ) - 15; + if ( shiftCount < 0 ) { + *zSig0Ptr = aSig1>>( - shiftCount ); + *zSig1Ptr = aSig1<<( shiftCount & 63 ); + } + else { + *zSig0Ptr = aSig1<>( - shiftCount ); + if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit two's complement integer format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic--- +| which means in particular that the conversion is rounded according to the +| current rounding mode. If `a' is a NaN, the largest positive integer is +| returned. Otherwise, if the conversion overflows, the largest integer with +| the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int64 float32_to_int64( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64, aSigExtra; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = 0xBE - aExp; + if ( shiftCount < 0 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + if ( aExp ) aSig |= 0x00800000; + aSig64 = aSig; + aSig64 <<= 40; + shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra ); + return roundAndPackInt64( aSign, aSig64, aSigExtra ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit two's complement integer format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic, +| except that the conversion is always rounded toward zero. If `a' is a NaN, +| the largest positive integer is returned. Otherwise, if the conversion +| overflows, the largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int64 float32_to_int64_round_to_zero( float32 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits32 aSig; + bits64 aSig64; + int64 z; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + shiftCount = aExp - 0xBE; + if ( 0 <= shiftCount ) { + if ( a != 0xDF000000 ) { + float_raise( float_flag_invalid ); + if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { + return LIT64( 0x7FFFFFFFFFFFFFFF ); + } + } + return (sbits64) LIT64( 0x8000000000000000 ); + } + else if ( aExp <= 0x7E ) { + if ( aExp | aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig64 = aSig | 0x00800000; + aSig64 <<= 40; + z = aSig64>>( - shiftCount ); + if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the double-precision floating-point format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float32_to_float64( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) ); + return packFloat64( aSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the double-extended-precision floating-point format. The conversion +| is performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float32_to_floatx80( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + aSig |= 0x00800000; + return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value +| `a' to the double-precision floating-point format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float32_to_float128( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 aSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the single-precision floating-point value `a' to an integer, +| and returns the result as a single-precision floating-point value. The +| operation is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_round_to_int( float32 a ) +{ + flag aSign; + int16 aExp; + bits32 lastBitMask, roundBitsMask; + int8 roundingMode; + float32 z; + + aExp = extractFloat32Exp( a ); + if ( 0x96 <= aExp ) { + if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { + return propagateFloat32NaN( a, a ); + } + return a; + } + if ( aExp <= 0x7E ) { + if ( (bits32) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat32Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) { + return packFloat32( aSign, 0x7F, 0 ); + } + break; + case float_round_down: + return aSign ? 0xBF800000 : 0; + case float_round_up: + return aSign ? 0x80000000 : 0x3F800000; + } + return packFloat32( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x96 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the single-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. The +| addition is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +static float32 addFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 6; + bSig <<= 6; + if ( 0 < expDiff ) { + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x20000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x20000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 ); + zSig = 0x40000000 + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= 0x20000000; + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits32) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the single- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float32 subFloat32Sigs( float32 a, float32 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + expDiff = aExp - bExp; + aSig <<= 7; + bSig <<= 7; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0xFF ) { + if ( aSig | bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign ^ 1, 0xFF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= 0x40000000; + } + shift32RightJamming( aSig, - expDiff, &aSig ); + bSig |= 0x40000000; + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= 0x40000000; + } + shift32RightJamming( bSig, expDiff, &bSig ); + aSig |= 0x40000000; + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the single-precision floating-point values +| `a' and `b'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_add( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return addFloat32Sigs( a, b, aSign ); + } + else { + return subFloat32Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the single-precision floating-point values +| `a' and `b'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_sub( float32 a, float32 b ) +{ + flag aSign, bSign; + + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign == bSign ) { + return subFloat32Sigs( a, b, aSign ); + } + else { + return addFloat32Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the single-precision floating-point values +| `a' and `b'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_mul( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig; + bits64 zSig64; + bits32 zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x7F; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 ); + zSig = zSig64; + if ( 0 <= (sbits32) ( zSig<<1 ) ) { + zSig <<= 1; + --zExp; + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the single-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to the +| IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_div( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits32 aSig, bSig, zSig; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, b ); + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + float_raise( float_flag_invalid ); + return float32_default_nan; + } + return packFloat32( zSign, 0xFF, 0 ); + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return packFloat32( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat32( zSign, 0xFF, 0 ); + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat32( zSign, 0, 0 ); + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x7D; + aSig = ( aSig | 0x00800000 )<<7; + bSig = ( bSig | 0x00800000 )<<8; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = ( ( (bits64) aSig )<<32 ) / bSig; + if ( ( zSig & 0x3F ) == 0 ) { + zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 ); + } + return roundAndPackFloat32( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the single-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_rem( float32 a, float32 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits32 aSig, bSig; + bits32 q; + bits64 aSig64, bSig64, q64; + bits32 alternateASig; + sbits32 sigMean; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + bSig = extractFloat32Frac( b ); + bExp = extractFloat32Exp( b ); + bSign = extractFloat32Sign( b ); + if ( aExp == 0xFF ) { + if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) { + return propagateFloat32NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( bExp == 0xFF ) { + if ( bSig ) return propagateFloat32NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float32_default_nan; + } + normalizeFloat32Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig |= 0x00800000; + bSig |= 0x00800000; + if ( expDiff < 32 ) { + aSig <<= 8; + bSig <<= 8; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + if ( 0 < expDiff ) { + q = ( ( (bits64) aSig )<<32 ) / bSig; + q >>= 32 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + } + else { + if ( bSig <= aSig ) aSig -= bSig; + aSig64 = ( (bits64) aSig )<<40; + bSig64 = ( (bits64) bSig )<<40; + expDiff -= 64; + while ( 0 < expDiff ) { + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + aSig64 = - ( ( bSig * q64 )<<38 ); + expDiff -= 62; + } + expDiff += 64; + q64 = estimateDiv128To64( aSig64, 0, bSig64 ); + q64 = ( 2 < q64 ) ? q64 - 2 : 0; + q = q64>>( 64 - expDiff ); + bSig <<= 6; + aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits32) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits32) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the single-precision floating-point value `a'. +| The operation is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float32_sqrt( float32 a ) +{ + flag aSign; + int16 aExp, zExp; + bits32 aSig, zSig; + bits64 rem, term; + + aSig = extractFloat32Frac( a ); + aExp = extractFloat32Exp( a ); + aSign = extractFloat32Sign( a ); + if ( aExp == 0xFF ) { + if ( aSig ) return propagateFloat32NaN( a, 0 ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float32_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat32Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E; + aSig = ( aSig | 0x00800000 )<<8; + zSig = estimateSqrt32( aExp, aSig ) + 2; + if ( ( zSig & 0x7F ) <= 5 ) { + if ( zSig < 2 ) { + zSig = 0x7FFFFFFF; + goto roundAndPack; + } + aSig >>= aExp & 1; + term = ( (bits64) zSig ) * zSig; + rem = ( ( (bits64) aSig )<<32 ) - term; + while ( (sbits64) rem < 0 ) { + --zSig; + rem += ( ( (bits64) zSig )<<1 ) | 1; + } + zSig |= ( rem != 0 ); + } + shift32RightJamming( zSig, 1, &zSig ); + roundAndPack: + return roundAndPackFloat32( 0, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_eq( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. The comparison +| is performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_le( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_lt( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_eq_signaling( float32 a, float32 b ) +{ + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_le_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; +// int16 aExp, bExp; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the single-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float32_lt_quiet( float32 a, float32 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) + || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) + ) { + if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat32Sign( a ); + bSign = extractFloat32Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the 32-bit two's complement integer format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic--- +| which means in particular that the conversion is rounded according to the +| current rounding mode. If `a' is a NaN, the largest positive integer is +| returned. Otherwise, if the conversion overflows, the largest integer with +| the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float64_to_int32( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + if ( aExp ) aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x42C - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the 32-bit two's complement integer format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic, +| except that the conversion is always rounded toward zero. If `a' is a NaN, +| the largest positive integer is returned. Otherwise, if the conversion +| overflows, the largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float64_to_int32_round_to_zero( float64 a ) +{ + flag aSign; + int16 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( 0x41E < aExp ) { + if ( ( aExp == 0x7FF ) && aSig ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig |= LIT64( 0x0010000000000000 ); + shiftCount = 0x433 - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + z = (sbits32) z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the single-precision floating-point format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float64_to_float32( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + bits32 zSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) ); + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 22, &aSig ); + zSig = aSig; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x381; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the double-extended-precision floating-point format. The conversion +| is performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float64_to_floatx80( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) ); + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + return + packFloatx80( + aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-precision floating-point value +| `a' to the quadruple-precision floating-point format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float64_to_float128( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) ); + return packFloat128( aSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + --aExp; + } + shift128Right( aSig, 0, 4, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the double-precision floating-point value `a' to an integer, +| and returns the result as a double-precision floating-point value. The +| operation is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_round_to_int( float64 a ) +{ + flag aSign; + int16 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float64 z; + + aExp = extractFloat64Exp( a ); + if ( 0x433 <= aExp ) { + if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) { + return propagateFloat64NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FF ) { + if ( (bits64) ( a<<1 ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat64Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) { + return packFloat64( aSign, 0x3FF, 0 ); + } + break; + case float_round_down: + return aSign ? LIT64( 0xBFF0000000000000 ) : 0; + case float_round_up: + return + aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ); + } + return packFloat64( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x433 - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z += lastBitMask>>1; + if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z += roundBitsMask; + } + } + z &= ~ roundBitsMask; + if ( z != a ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the double-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. The +| addition is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 addFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 9; + bSig <<= 9; + if ( 0 < expDiff ) { + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x2000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + zExp = bExp; + } + else { + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 ); + zSig = LIT64( 0x4000000000000000 ) + aSig + bSig; + zExp = aExp; + goto roundAndPack; + } + aSig |= LIT64( 0x2000000000000000 ); + zSig = ( aSig + bSig )<<1; + --zExp; + if ( (sbits64) zSig < 0 ) { + zSig = aSig + bSig; + ++zExp; + } + roundAndPack: + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the double- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float64 subFloat64Sigs( float64 a, float64 b, flag zSign ) +{ + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + int16 expDiff; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + expDiff = aExp - bExp; + aSig <<= 10; + bSig <<= 10; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FF ) { + if ( aSig | bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign ^ 1, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( aSig, - expDiff, &aSig ); + bSig |= LIT64( 0x4000000000000000 ); + bBigger: + zSig = bSig - aSig; + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig |= LIT64( 0x4000000000000000 ); + } + shift64RightJamming( bSig, expDiff, &bSig ); + aSig |= LIT64( 0x4000000000000000 ); + aBigger: + zSig = aSig - bSig; + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the double-precision floating-point values +| `a' and `b'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_add( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return addFloat64Sigs( a, b, aSign ); + } + else { + return subFloat64Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the double-precision floating-point values +| `a' and `b'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_sub( float64 a, float64 b ) +{ + flag aSign, bSign; + + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign == bSign ) { + return subFloat64Sigs( a, b, aSign ); + } + else { + return addFloat64Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the double-precision floating-point values +| `a' and `b'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_mul( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FF; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + zSig0 |= ( zSig1 != 0 ); + if ( 0 <= (sbits64) ( zSig0<<1 ) ) { + zSig0 <<= 1; + --zExp; + } + return roundAndPackFloat64( zSign, zExp, zSig0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the double-precision floating-point value `a' +| by the corresponding value `b'. The operation is performed according to the +| IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_div( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, zExp; + bits64 aSig, bSig, zSig; + bits64 rem0, rem1; + bits64 term0, term1; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, b ); + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + float_raise( float_flag_invalid ); + return float64_default_nan; + } + return packFloat64( zSign, 0x7FF, 0 ); + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return packFloat64( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + float_raise( float_flag_divbyzero ); + return packFloat64( zSign, 0x7FF, 0 ); + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloat64( zSign, 0, 0 ); + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FD; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( bSig <= ( aSig + aSig ) ) { + aSig >>= 1; + ++zExp; + } + zSig = estimateDiv128To64( aSig, 0, bSig ); + if ( ( zSig & 0x1FF ) <= 2 ) { + mul64To128( bSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig |= ( rem1 != 0 ); + } + return roundAndPackFloat64( zSign, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the double-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_rem( float64 a, float64 b ) +{ + flag aSign, bSign, zSign; + int16 aExp, bExp, expDiff; + bits64 aSig, bSig; + bits64 q, alternateASig; + sbits64 sigMean; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + bSig = extractFloat64Frac( b ); + bExp = extractFloat64Exp( b ); + bSign = extractFloat64Sign( b ); + if ( aExp == 0x7FF ) { + if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) { + return propagateFloat64NaN( a, b ); + } + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( bExp == 0x7FF ) { + if ( bSig ) return propagateFloat64NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + float_raise( float_flag_invalid ); + return float64_default_nan; + } + normalizeFloat64Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return a; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + expDiff = aExp - bExp; + aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11; + bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + aSig >>= 1; + } + q = ( bSig <= aSig ); + if ( q ) aSig -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + aSig = - ( ( bSig>>2 ) * q ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig, 0, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + bSig >>= 2; + aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q; + } + else { + aSig >>= 2; + bSig >>= 2; + } + do { + alternateASig = aSig; + ++q; + aSig -= bSig; + } while ( 0 <= (sbits64) aSig ); + sigMean = aSig + alternateASig; + if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) { + aSig = alternateASig; + } + zSign = ( (sbits64) aSig < 0 ); + if ( zSign ) aSig = - aSig; + return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the double-precision floating-point value `a'. +| The operation is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float64_sqrt( float64 a ) +{ + flag aSign; + int16 aExp, zExp; + bits64 aSig, zSig, doubleZSig; + bits64 rem0, rem1, term0, term1; +// float64 z; + + aSig = extractFloat64Frac( a ); + aExp = extractFloat64Exp( a ); + aSign = extractFloat64Sign( a ); + if ( aExp == 0x7FF ) { + if ( aSig ) return propagateFloat64NaN( a, a ); + if ( ! aSign ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aSign ) { + if ( ( aExp | aSig ) == 0 ) return a; + float_raise( float_flag_invalid ); + return float64_default_nan; + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return 0; + normalizeFloat64Subnormal( aSig, &aExp, &aSig ); + } + zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE; + aSig |= LIT64( 0x0010000000000000 ); + zSig = estimateSqrt32( aExp, aSig>>21 ); + aSig <<= 9 - ( aExp & 1 ); + zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 ); + if ( ( zSig & 0x1FF ) <= 5 ) { + doubleZSig = zSig<<1; + mul64To128( zSig, zSig, &term0, &term1 ); + sub128( aSig, 0, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig; + doubleZSig -= 2; + add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 ); + } + zSig |= ( ( rem0 | rem1 ) != 0 ); + } + return roundAndPackFloat64( 0, zExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is equal to the +| corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_eq( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_le( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_lt( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_eq_signaling( float64 a, float64 b ) +{ + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than or +| equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_le_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; +// int16 aExp, bExp; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 ); + return ( a == b ) || ( aSign ^ ( a < b ) ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float64_lt_quiet( float64 a, float64 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) + || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) + ) { + if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat64Sign( a ); + bSign = extractFloat64Sign( b ); + if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 ); + return ( a != b ) && ( aSign ^ ( a < b ) ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-extended-precision floating- +| point value `a' to the 32-bit two's complement integer format. The +| conversion is performed according to the IEEE Standard for Floating-Point +| Arithmetic---which means in particular that the conversion is rounded +| according to the current rounding mode. If `a' is a NaN, the largest +| positive integer is returned. Otherwise, if the conversion overflows, the +| largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 floatx80_to_int32( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + shiftCount = 0x4037 - aExp; + if ( shiftCount <= 0 ) shiftCount = 1; + shift64RightJamming( aSig, shiftCount, &aSig ); + return roundAndPackInt32( aSign, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-extended-precision floating- +| point value `a' to the 32-bit two's complement integer format. The +| conversion is performed according to the IEEE Standard for Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. +| If `a' is a NaN, the largest positive integer is returned. Otherwise, if +| the conversion overflows, the largest integer with the same sign as `a' is +| returned. +*----------------------------------------------------------------------------*/ + +int32 floatx80_to_int32_round_to_zero( floatx80 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig, savedASig; + int32 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig ) float_exception_flags |= float_flag_inexact; + return 0; + } + shiftCount = 0x403E - aExp; + savedASig = aSig; + aSig >>= shiftCount; + z = aSig; + if ( aSign ) z = - z; + z = (sbits32) z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig<>( - shiftCount ); + if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { + float_exception_flags |= float_flag_inexact; + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-extended-precision floating- +| point value `a' to the single-precision floating-point format. The +| conversion is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 floatx80_to_float32( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat32( floatx80ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + shift64RightJamming( aSig, 33, &aSig ); + if ( aExp || aSig ) aExp -= 0x3F81; + return roundAndPackFloat32( aSign, aExp, aSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-extended-precision floating- +| point value `a' to the double-precision floating-point format. The +| conversion is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 floatx80_to_float64( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig, zSig; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat64( floatx80ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shift64RightJamming( aSig, 1, &zSig ); + if ( aExp || aSig ) aExp -= 0x3C01; + return roundAndPackFloat64( aSign, aExp, zSig ); + +} + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the double-extended-precision floating- +| point value `a' to the quadruple-precision floating-point format. The +| conversion is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 floatx80_to_float128( floatx80 a ) +{ + flag aSign; + int16 aExp; + bits64 aSig, zSig0, zSig1; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) { + return commonNaNToFloat128( floatx80ToCommonNaN( a ) ); + } + shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 ); + return packFloat128( aSign, aExp, zSig0, zSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the double-extended-precision floating-point value `a' to an integer, +| and returns the result as an double-extended-precision floating-point value. +| The operation is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_round_to_int( floatx80 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + floatx80 z; + + aExp = extractFloatx80Exp( a ); + if ( 0x403E <= aExp ) { + if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { + return propagateFloatx80NaN( a, a ); + } + return a; + } + if ( aExp < 0x3FFF ) { + if ( ( aExp == 0 ) + && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) { + return a; + } + float_exception_flags |= float_flag_inexact; + aSign = extractFloatx80Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 ) + ) { + return + packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + break; + case float_round_down: + return + aSign ? + packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) ) + : packFloatx80( 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloatx80( 1, 0, 0 ) + : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) ); + } + return packFloatx80( aSign, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x403E - aExp; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.low += lastBitMask>>1; + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) { + z.low += roundBitsMask; + } + } + z.low &= ~ roundBitsMask; + if ( z.low == 0 ) { + ++z.high; + z.low = LIT64( 0x8000000000000000 ); + } + if ( z.low != a.low ) float_exception_flags |= float_flag_inexact; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the double-extended- +| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is +| negated before being returned. `zSign' is ignored if the result is a NaN. +| The addition is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + return a; + } + zSig1 = 0; + zSig0 = aSig + bSig; + if ( aExp == 0 ) { + normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 ); + goto roundAndPack; + } + zExp = aExp; + goto shiftRight1; + } + zSig0 = aSig + bSig; + if ( (sbits64) zSig0 < 0 ) goto roundAndPack; + shiftRight1: + shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= LIT64( 0x8000000000000000 ); + ++zExp; + roundAndPack: + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the double- +| extended-precision floating-point values `a' and `b'. If `zSign' is 1, +| the difference is negated before being returned. `zSign' is ignored if +| the result is a NaN. The subtraction is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + int32 expDiff; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( ( aSig | bSig )<<1 ) ) { + return propagateFloatx80NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + zSig1 = 0; + if ( bSig < aSig ) goto aBigger; + if ( aSig < bSig ) goto bBigger; + return packFloatx80( float_rounding_mode == float_round_down, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) ++expDiff; + shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 ); + bBigger: + sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) --expDiff; + shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 ); + aBigger: + sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + return + normalizeRoundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the double-extended-precision floating-point +| values `a' and `b'. The operation is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_add( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return addFloatx80Sigs( a, b, aSign ); + } + else { + return subFloatx80Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the double-extended-precision floating- +| point values `a' and `b'. The operation is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_sub( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign == bSign ) { + return subFloatx80Sigs( a, b, aSign ); + } + else { + return addFloatx80Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the double-extended-precision floating- +| point values `a' and `b'. The operation is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_mul( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + if ( ( bExp | bSig ) == 0 ) goto invalid; + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + zExp = aExp + bExp - 0x3FFE; + mul64To128( aSig, bSig, &zSig0, &zSig1 ); + if ( 0 < (sbits64) zSig0 ) { + shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 ); + --zExp; + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the double-extended-precision floating-point +| value `a' by the corresponding value `b'. The operation is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_div( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig, bSig, zSig0, zSig1; + bits64 rem0, rem1, rem2, term0, term1, term2; + floatx80 z; + + aSig = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + goto invalid; + } + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return packFloatx80( zSign, 0, 0 ); + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + if ( ( aExp | aSig ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 ); + normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); + } + zExp = aExp - bExp + 0x3FFE; + rem1 = 0; + if ( bSig <= aSig ) { + shift128Right( aSig, 0, 1, &aSig, &rem1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig, rem1, bSig ); + mul64To128( bSig, zSig0, &term0, &term1 ); + sub128( aSig, rem1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add128( rem0, rem1, 0, bSig, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, bSig ); + if ( (bits64) ( zSig1<<1 ) <= 8 ) { + mul64To128( bSig, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add128( rem1, rem2, 0, bSig, &rem1, &rem2 ); + } + zSig1 |= ( ( rem1 | rem2 ) != 0 ); + } + return + roundAndPackFloatx80( + floatx80_rounding_precision, zSign, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the double-extended-precision floating-point value +| `a' with respect to the corresponding value `b'. The operation is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_rem( floatx80 a, floatx80 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig; + bits64 q, term0, term1, alternateASig0, alternateASig1; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + bSig = extractFloatx80Frac( b ); + bExp = extractFloatx80Exp( b ); + bSign = extractFloatx80Sign( b ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) + || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) { + return propagateFloatx80NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( bSig == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); + } + if ( aExp == 0 ) { + if ( (bits64) ( aSig0<<1 ) == 0 ) return a; + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + bSig |= LIT64( 0x8000000000000000 ); + zSign = aSign; + expDiff = aExp - bExp; + aSig1 = 0; + if ( expDiff < 0 ) { + if ( expDiff < -1 ) return a; + shift128Right( aSig0, 0, 1, &aSig0, &aSig1 ); + expDiff = 0; + } + q = ( bSig <= aSig0 ); + if ( q ) aSig0 -= bSig; + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + mul64To128( bSig, q, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 ); + expDiff -= 62; + } + expDiff += 64; + if ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig ); + q = ( 2 < q ) ? q - 2 : 0; + q >>= 64 - expDiff; + mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 ); + while ( le128( term0, term1, aSig0, aSig1 ) ) { + ++q; + sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 ); + } + } + else { + term1 = 0; + term0 = bSig; + } + sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 ); + if ( lt128( alternateASig0, alternateASig1, aSig0, aSig1 ) + || ( eq128( alternateASig0, alternateASig1, aSig0, aSig1 ) + && ( q & 1 ) ) + ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + zSign = ! zSign; + } + return + normalizeRoundAndPackFloatx80( + 80, zSign, bExp + expDiff, aSig0, aSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the double-extended-precision floating-point +| value `a'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 floatx80_sqrt( floatx80 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + floatx80 z; + + aSig0 = extractFloatx80Frac( a ); + aExp = extractFloatx80Exp( a ); + aSign = extractFloatx80Sign( a ); + if ( aExp == 0x7FFF ) { + if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = floatx80_default_nan_low; + z.high = floatx80_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 ); + normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF; + zSig0 = estimateSqrt32( aExp, aSig0>>32 ); + shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 ); + zSig0 |= doubleZSig0; + return + roundAndPackFloatx80( + floatx80_rounding_precision, 0, zExp, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is +| equal to the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_eq( floatx80 a, floatx80 b ) +{ + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is +| less than or equal to the corresponding value `b', and 0 otherwise. The +| comparison is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_le( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is +| less than the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_lt( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is equal +| to the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_eq_signaling( floatx80 a, floatx80 b ) +{ + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is less +| than or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs +| do not cause an exception. Otherwise, the comparison is performed according +| to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_le_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the double-extended-precision floating-point value `a' is less +| than the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause +| an exception. Otherwise, the comparison is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag floatx80_lt_quiet( floatx80 a, floatx80 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( a )<<1 ) ) + || ( ( extractFloatx80Exp( b ) == 0x7FFF ) + && (bits64) ( extractFloatx80Frac( b )<<1 ) ) + ) { + if ( floatx80_is_signaling_nan( a ) + || floatx80_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloatx80Sign( a ); + bSign = extractFloatx80Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the 32-bit two's complement integer format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic--- +| which means in particular that the conversion is rounded according to the +| current rounding mode. If `a' is a NaN, the largest positive integer is +| returned. Otherwise, if the conversion overflows, the largest integer with +| the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float128_to_int32( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0; + if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 ); + aSig0 |= ( aSig1 != 0 ); + shiftCount = 0x4028 - aExp; + if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 ); + return roundAndPackInt32( aSign, aSig0 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the 32-bit two's complement integer format. The conversion +| is performed according to the IEEE Standard for Floating-Point Arithmetic, +| except that the conversion is always rounded toward zero. If `a' is a NaN, +| the largest positive integer is returned. Otherwise, if the conversion +| overflows, the largest integer with the same sign as `a' is returned. +*----------------------------------------------------------------------------*/ + +int32 float128_to_int32_round_to_zero( float128 a ) +{ + flag aSign; + int32 aExp, shiftCount; + bits64 aSig0, aSig1, savedASig; + int32 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + aSig0 |= ( aSig1 != 0 ); + if ( 0x401E < aExp ) { + if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0; + goto invalid; + } + else if ( aExp < 0x3FFF ) { + if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact; + return 0; + } + aSig0 |= LIT64( 0x0001000000000000 ); + shiftCount = 0x402F - aExp; + savedASig = aSig0; + aSig0 >>= shiftCount; + z = aSig0; + if ( aSign ) z = - z; + z = (sbits32) z; + if ( ( z < 0 ) ^ aSign ) { + invalid: + float_raise( float_flag_invalid ); + return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; + } + if ( ( aSig0<>( ( - shiftCount ) & 63 ) ); + if ( (bits64) ( aSig1<>( - shiftCount ); + if ( aSig1 + || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { + float_exception_flags |= float_flag_inexact; + } + } + if ( aSign ) z = - z; + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the single-precision floating-point format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float32 float128_to_float32( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + bits32 zSig; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat32( float128ToCommonNaN( a ) ); + } + return packFloat32( aSign, 0xFF, 0 ); + } + aSig0 |= ( aSig1 != 0 ); + shift64RightJamming( aSig0, 18, &aSig0 ); + zSig = aSig0; + if ( aExp || zSig ) { + zSig |= 0x40000000; + aExp -= 0x3F81; + } + return roundAndPackFloat32( aSign, aExp, zSig ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the double-precision floating-point format. The conversion is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float64 float128_to_float64( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloat64( float128ToCommonNaN( a ) ); + } + return packFloat64( aSign, 0x7FF, 0 ); + } + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + aSig0 |= ( aSig1 != 0 ); + if ( aExp || aSig0 ) { + aSig0 |= LIT64( 0x4000000000000000 ); + aExp -= 0x3C01; + } + return roundAndPackFloat64( aSign, aExp, aSig0 ); + +} + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Returns the result of converting the quadruple-precision floating-point +| value `a' to the double-extended-precision floating-point format. The +| conversion is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +floatx80 float128_to_floatx80( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 aSig0, aSig1; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) { + return commonNaNToFloatx80( float128ToCommonNaN( a ) ); + } + return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 ); + return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 ); + +} + +#endif + +/*---------------------------------------------------------------------------- +| Rounds the quadruple-precision floating-point value `a' to an integer, +| and returns the result as a quadruple-precision floating-point value. The +| operation is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_round_to_int( float128 a ) +{ + flag aSign; + int32 aExp; + bits64 lastBitMask, roundBitsMask; + int8 roundingMode; + float128 z; + + aExp = extractFloat128Exp( a ); + if ( 0x402F <= aExp ) { + if ( 0x406F <= aExp ) { + if ( ( aExp == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) + ) { + return propagateFloat128NaN( a, a ); + } + return a; + } + lastBitMask = 1; + lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; + roundBitsMask = lastBitMask - 1; + z = a; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + if ( lastBitMask ) { + add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low ); + if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask; + } + else { + if ( (sbits64) z.low < 0 ) { + ++z.high; + if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1; + } + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low ); + } + } + z.low &= ~ roundBitsMask; + } + else { + if ( aExp < 0x3FFF ) { + if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a; + float_exception_flags |= float_flag_inexact; + aSign = extractFloat128Sign( a ); + switch ( float_rounding_mode ) { + case float_round_nearest_even: + if ( ( aExp == 0x3FFE ) + && ( extractFloat128Frac0( a ) + | extractFloat128Frac1( a ) ) + ) { + return packFloat128( aSign, 0x3FFF, 0, 0 ); + } + break; + case float_round_down: + return + aSign ? packFloat128( 1, 0x3FFF, 0, 0 ) + : packFloat128( 0, 0, 0, 0 ); + case float_round_up: + return + aSign ? packFloat128( 1, 0, 0, 0 ) + : packFloat128( 0, 0x3FFF, 0, 0 ); + } + return packFloat128( aSign, 0, 0, 0 ); + } + lastBitMask = 1; + lastBitMask <<= 0x402F - aExp; + roundBitsMask = lastBitMask - 1; + z.low = 0; + z.high = a.high; + roundingMode = float_rounding_mode; + if ( roundingMode == float_round_nearest_even ) { + z.high += lastBitMask>>1; + if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) { + z.high &= ~ lastBitMask; + } + } + else if ( roundingMode != float_round_to_zero ) { + if ( extractFloat128Sign( z ) + ^ ( roundingMode == float_round_up ) ) { + z.high |= ( a.low != 0 ); + z.high += roundBitsMask; + } + } + z.high &= ~ roundBitsMask; + } + if ( ( z.low != a.low ) || ( z.high != a.high ) ) { + float_exception_flags |= float_flag_inexact; + } + return z; + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the absolute values of the quadruple-precision +| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated +| before being returned. `zSign' is ignored if the result is a NaN. The +| addition is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +static float128 addFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + int32 expDiff; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + if ( 0 < expDiff ) { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 ); + zExp = aExp; + } + else if ( expDiff < 0 ) { + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x0001000000000000 ); + } + shift128ExtraRightJamming( + aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 ); + zExp = bExp; + } + else { + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + return a; + } + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 ); + zSig2 = 0; + zSig0 |= LIT64( 0x0002000000000000 ); + zExp = aExp; + goto shiftRight1; + } + aSig0 |= LIT64( 0x0001000000000000 ); + add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + --zExp; + if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack; + ++zExp; + shiftRight1: + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + roundAndPack: + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the absolute values of the quadruple- +| precision floating-point values `a' and `b'. If `zSign' is 1, the +| difference is negated before being returned. `zSign' is ignored if the +| result is a NaN. The subtraction is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +static float128 subFloat128Sigs( float128 a, float128 b, flag zSign ) +{ + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1; + int32 expDiff; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + expDiff = aExp - bExp; + shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 ); + shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 ); + if ( 0 < expDiff ) goto aExpBigger; + if ( expDiff < 0 ) goto bExpBigger; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 | bSig0 | bSig1 ) { + return propagateFloat128NaN( a, b ); + } + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + aExp = 1; + bExp = 1; + } + if ( bSig0 < aSig0 ) goto aBigger; + if ( aSig0 < bSig0 ) goto bBigger; + if ( bSig1 < aSig1 ) goto aBigger; + if ( aSig1 < bSig1 ) goto bBigger; + return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 ); + bExpBigger: + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + ++expDiff; + } + else { + aSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + bSig0 |= LIT64( 0x4000000000000000 ); + bBigger: + sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zExp = bExp; + zSign ^= 1; + goto normalizeRoundAndPack; + aExpBigger: + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + --expDiff; + } + else { + bSig0 |= LIT64( 0x4000000000000000 ); + } + shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 ); + aSig0 |= LIT64( 0x4000000000000000 ); + aBigger: + sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 ); + zExp = aExp; + normalizeRoundAndPack: + --zExp; + return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of adding the quadruple-precision floating-point values +| `a' and `b'. The operation is performed according to the IEEE Standard for +| Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_add( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return addFloat128Sigs( a, b, aSign ); + } + else { + return subFloat128Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of subtracting the quadruple-precision floating-point +| values `a' and `b'. The operation is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_sub( float128 a, float128 b ) +{ + flag aSign, bSign; + + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign == bSign ) { + return subFloat128Sigs( a, b, aSign ); + } + else { + return addFloat128Sigs( a, b, aSign ); + } + +} + +/*---------------------------------------------------------------------------- +| Returns the result of multiplying the quadruple-precision floating-point +| values `a' and `b'. The operation is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_mul( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + zExp = aExp + bExp - 0x4000; + aSig0 |= LIT64( 0x0001000000000000 ); + shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 ); + mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 ); + add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 ); + zSig2 |= ( zSig3 != 0 ); + if ( LIT64( 0x0002000000000000 ) <= zSig0 ) { + shift128ExtraRightJamming( + zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 ); + ++zExp; + } + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the result of dividing the quadruple-precision floating-point value +| `a' by the corresponding value `b'. The operation is performed according to +| the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_div( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, zExp; + bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + zSign = aSign ^ bSign; + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b ); + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + goto invalid; + } + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return packFloat128( zSign, 0, 0, 0 ); + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + float_raise( float_flag_divbyzero ); + return packFloat128( zSign, 0x7FFF, 0, 0 ); + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = aExp - bExp + 0x3FFD; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) { + shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 ); + ++zExp; + } + zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 ); + mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 ); + sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 ); + } + zSig1 = estimateDiv128To64( rem1, rem2, bSig0 ); + if ( ( zSig1 & 0x3FFF ) <= 4 ) { + mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 ); + sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the remainder of the quadruple-precision floating-point value `a' +| with respect to the corresponding value `b'. The operation is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_rem( float128 a, float128 b ) +{ + flag aSign, bSign, zSign; + int32 aExp, bExp, expDiff; + bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2; + bits64 allZero, alternateASig0, alternateASig1, sigMean1; + sbits64 sigMean0; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + bSig1 = extractFloat128Frac1( b ); + bSig0 = extractFloat128Frac0( b ); + bExp = extractFloat128Exp( b ); + bSign = extractFloat128Sign( b ); + if ( aExp == 0x7FFF ) { + if ( ( aSig0 | aSig1 ) + || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) { + return propagateFloat128NaN( a, b ); + } + goto invalid; + } + if ( bExp == 0x7FFF ) { + if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b ); + return a; + } + if ( bExp == 0 ) { + if ( ( bSig0 | bSig1 ) == 0 ) { + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 ); + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return a; + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + expDiff = aExp - bExp; + if ( expDiff < -1 ) return a; + shortShift128Left( + aSig0 | LIT64( 0x0001000000000000 ), + aSig1, + 15 - ( expDiff < 0 ), + &aSig0, + &aSig1 + ); + shortShift128Left( + bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 ); + q = le128( bSig0, bSig1, aSig0, aSig1 ); + if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + expDiff -= 64; + while ( 0 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero ); + shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero ); + sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 ); + expDiff -= 61; + } + if ( -64 < expDiff ) { + q = estimateDiv128To64( aSig0, aSig1, bSig0 ); + q = ( 4 < q ) ? q - 4 : 0; + q >>= - expDiff; + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + expDiff += 52; + if ( expDiff < 0 ) { + shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 ); + } + else { + shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 ); + } + mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 ); + sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 ); + } + else { + shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 ); + shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 ); + } + do { + alternateASig0 = aSig0; + alternateASig1 = aSig1; + ++q; + sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 ); + } while ( 0 <= (sbits64) aSig0 ); + add128( + aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 ); + if ( ( sigMean0 < 0 ) + || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) { + aSig0 = alternateASig0; + aSig1 = alternateASig1; + } + zSign = ( (sbits64) aSig0 < 0 ); + if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 ); + return + normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 ); + +} + +/*---------------------------------------------------------------------------- +| Returns the square root of the quadruple-precision floating-point value `a'. +| The operation is performed according to the IEEE Standard for Floating-Point +| Arithmetic. +*----------------------------------------------------------------------------*/ + +float128 float128_sqrt( float128 a ) +{ + flag aSign; + int32 aExp, zExp; + bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0; + bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3; + float128 z; + + aSig1 = extractFloat128Frac1( a ); + aSig0 = extractFloat128Frac0( a ); + aExp = extractFloat128Exp( a ); + aSign = extractFloat128Sign( a ); + if ( aExp == 0x7FFF ) { + if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a ); + if ( ! aSign ) return a; + goto invalid; + } + if ( aSign ) { + if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; + invalid: + float_raise( float_flag_invalid ); + z.low = float128_default_nan_low; + z.high = float128_default_nan_high; + return z; + } + if ( aExp == 0 ) { + if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 ); + normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 ); + } + zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE; + aSig0 |= LIT64( 0x0001000000000000 ); + zSig0 = estimateSqrt32( aExp, aSig0>>17 ); + shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 ); + zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 ); + doubleZSig0 = zSig0<<1; + mul64To128( zSig0, zSig0, &term0, &term1 ); + sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 ); + while ( (sbits64) rem0 < 0 ) { + --zSig0; + doubleZSig0 -= 2; + add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 ); + } + zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 ); + if ( ( zSig1 & 0x1FFF ) <= 5 ) { + if ( zSig1 == 0 ) zSig1 = 1; + mul64To128( doubleZSig0, zSig1, &term1, &term2 ); + sub128( rem1, 0, term1, term2, &rem1, &rem2 ); + mul64To128( zSig1, zSig1, &term2, &term3 ); + sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 ); + while ( (sbits64) rem1 < 0 ) { + --zSig1; + shortShift128Left( 0, zSig1, 1, &term2, &term3 ); + term3 |= 1; + term2 |= doubleZSig0; + add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 ); + } + zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 ); + } + shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 ); + return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_eq( float128 a, float128 b ) +{ + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. The comparison is +| performed according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_le( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. The comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_lt( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is equal to +| the corresponding value `b', and 0 otherwise. The invalid exception is +| raised if either operand is a NaN. Otherwise, the comparison is performed +| according to the IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_eq_signaling( float128 a, float128 b ) +{ + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + float_raise( float_flag_invalid ); + return 0; + } + return + ( a.low == b.low ) + && ( ( a.high == b.high ) + || ( ( a.low == 0 ) + && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) ) + ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| or equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not +| cause an exception. Otherwise, the comparison is performed according to the +| IEEE Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_le_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + || ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + == 0 ); + } + return + aSign ? le128( b.high, b.low, a.high, a.low ) + : le128( a.high, a.low, b.high, b.low ); + +} + +/*---------------------------------------------------------------------------- +| Returns 1 if the quadruple-precision floating-point value `a' is less than +| the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an +| exception. Otherwise, the comparison is performed according to the IEEE +| Standard for Floating-Point Arithmetic. +*----------------------------------------------------------------------------*/ + +flag float128_lt_quiet( float128 a, float128 b ) +{ + flag aSign, bSign; + + if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) + && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) + || ( ( extractFloat128Exp( b ) == 0x7FFF ) + && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) + ) { + if ( float128_is_signaling_nan( a ) + || float128_is_signaling_nan( b ) ) { + float_raise( float_flag_invalid ); + } + return 0; + } + aSign = extractFloat128Sign( a ); + bSign = extractFloat128Sign( b ); + if ( aSign != bSign ) { + return + aSign + && ( ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low ) + != 0 ); + } + return + aSign ? lt128( b.high, b.low, a.high, a.low ) + : lt128( a.high, a.low, b.high, b.low ); + +} + +#endif + +float float32_to_c_float(float32 a){ + return *((float*)(&a)); +} +double float64_to_c_double(float64 a){ + return *((double*)(&a)); +} +float32 c_float_to_float32(float a){ + return *((float32*)(&a)); +} +float64 c_double_to_float64(double a){ + return *((float64*)(&a)); +} + +#ifdef FLOATX80 +float floatx80_to_c_float(floatx80 a){ + return float32_to_c_float(floatx80_to_float32(a)); +} +double floatx80_to_c_double(floatx80 a){ + return float64_to_c_double(floatx80_to_float64(a)); +} +floatx80 c_float_to_floatx80(float a){ + return float32_to_floatx80(c_float_to_float32(a)); +} +floatx80 c_double_to_floatx80(double a){ + return float64_to_floatx80(c_double_to_float64(a)); +} +#endif + +//#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat.h b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat.h new file mode 100644 index 000000000..2d1c8c8be --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloat.h @@ -0,0 +1,263 @@ + +/*============================================================================ + +This C header file is part of the Berkeley SoftFloat IEEE Floating-Point +Arithmetic Package, Release 2c, by John R. Hauser. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has +been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES +RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS +AND ORGANIZATIONS WHO CAN AND WILL TOLERATE ALL LOSSES, COSTS, OR OTHER +PROBLEMS THEY INCUR DUE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR +THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE EFFECTIVELY +INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE INSTITUTE +(possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR OTHER +PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE, OR +INCURRED BY ANYONE DUE TO A DERIVATIVE WORK THEY CREATE USING ANY PART OF THE +SOFTWARE. + +Derivative works require also that (1) the source code for the derivative work +includes prominent notice that the work is derivative, and (2) the source code +includes prominent notice of these three paragraphs for those parts of this +code that are retained. + +=============================================================================*/ + +/*---------------------------------------------------------------------------- +| The macro `FLOATX80' must be defined to enable the double-extended-precision +| floating-point format `floatx80'. If this macro is not defined, the +| `floatx80' type will not be defined, and none of the functions that either +| input or output the `floatx80' type will be defined. The same applies to +| the `FLOAT128' macro and the quadruple-precision format `float128'. +*----------------------------------------------------------------------------*/ +#define FLOATX80 +//#define FLOAT128 + +/*---------------------------------------------------------------------------- +| Software IEEE floating-point types. +*----------------------------------------------------------------------------*/ +typedef unsigned int float32; +typedef unsigned long long float64; +#ifdef FLOATX80 +typedef struct { + unsigned long long low; + unsigned short high; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + unsigned long long low, high; +} float128; +#endif + +/*---------------------------------------------------------------------------- +| Software IEEE floating-point underflow tininess-detection mode. +*----------------------------------------------------------------------------*/ +extern signed char float_detect_tininess; +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/*---------------------------------------------------------------------------- +| Software IEEE floating-point rounding mode. +*----------------------------------------------------------------------------*/ +extern signed char float_rounding_mode; +enum { + float_round_nearest_even = 0, + float_round_down = 1, + float_round_up = 2, + float_round_to_zero = 3 +}; + +/*---------------------------------------------------------------------------- +| Software IEEE floating-point exception flags. +*----------------------------------------------------------------------------*/ +extern signed char float_exception_flags; +enum { + float_flag_invalid = 1, + float_flag_divbyzero = 4, + float_flag_overflow = 8, + float_flag_underflow = 16, + float_flag_inexact = 32 +}; + +/*---------------------------------------------------------------------------- +| Routine to raise any or all of the software IEEE floating-point exception +| flags. +*----------------------------------------------------------------------------*/ +void float_raise( signed char ); + +/*---------------------------------------------------------------------------- +| Software IEEE integer-to-floating-point conversion routines. +*----------------------------------------------------------------------------*/ +float32 int32_to_float32( int ); +float64 int32_to_float64( int ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( int ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( int ); +#endif +float32 int64_to_float32( long long ); +float64 int64_to_float64( long long ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( long long ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( long long ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEEE single-precision conversion routines. +*----------------------------------------------------------------------------*/ +int float32_to_int32( float32 ); +int float32_to_int32_round_to_zero( float32 ); +long long float32_to_int64( float32 ); +long long float32_to_int64_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEEE single-precision operations. +*----------------------------------------------------------------------------*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +char float32_eq( float32, float32 ); +char float32_le( float32, float32 ); +char float32_lt( float32, float32 ); +char float32_eq_signaling( float32, float32 ); +char float32_le_quiet( float32, float32 ); +char float32_lt_quiet( float32, float32 ); +char float32_is_signaling_nan( float32 ); + +/*---------------------------------------------------------------------------- +| Software IEEE double-precision conversion routines. +*----------------------------------------------------------------------------*/ +int float64_to_int32( float64 ); +int float64_to_int32_round_to_zero( float64 ); +long long float64_to_int64( float64 ); +long long float64_to_int64_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEEE double-precision operations. +*----------------------------------------------------------------------------*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +char float64_eq( float64, float64 ); +char float64_le( float64, float64 ); +char float64_lt( float64, float64 ); +char float64_eq_signaling( float64, float64 ); +char float64_le_quiet( float64, float64 ); +char float64_lt_quiet( float64, float64 ); +char float64_is_signaling_nan( float64 ); + +#ifdef FLOATX80 + +/*---------------------------------------------------------------------------- +| Software IEEE double-extended-precision conversion routines. +*----------------------------------------------------------------------------*/ +int floatx80_to_int32( floatx80 ); +int floatx80_to_int32_round_to_zero( floatx80 ); +long long floatx80_to_int64( floatx80 ); +long long floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEEE double-extended-precision rounding precision. Valid values +| are 32, 64, and 80. +*----------------------------------------------------------------------------*/ +extern signed char floatx80_rounding_precision; + +/*---------------------------------------------------------------------------- +| Software IEEE double-extended-precision operations. +*----------------------------------------------------------------------------*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +char floatx80_eq( floatx80, floatx80 ); +char floatx80_le( floatx80, floatx80 ); +char floatx80_lt( floatx80, floatx80 ); +char floatx80_eq_signaling( floatx80, floatx80 ); +char floatx80_le_quiet( floatx80, floatx80 ); +char floatx80_lt_quiet( floatx80, floatx80 ); +char floatx80_is_signaling_nan( floatx80 ); + +#endif + +#ifdef FLOAT128 + +/*---------------------------------------------------------------------------- +| Software IEEE quadruple-precision conversion routines. +*----------------------------------------------------------------------------*/ +int float128_to_int32( float128 ); +int float128_to_int32_round_to_zero( float128 ); +long long float128_to_int64( float128 ); +long long float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/*---------------------------------------------------------------------------- +| Software IEEE quadruple-precision operations. +*----------------------------------------------------------------------------*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +char float128_eq( float128, float128 ); +char float128_le( float128, float128 ); +char float128_lt( float128, float128 ); +char float128_eq_signaling( float128, float128 ); +char float128_le_quiet( float128, float128 ); +char float128_lt_quiet( float128, float128 ); +char float128_is_signaling_nan( float128 ); + +#endif + +float float32_to_c_float(float32 a); +double float64_to_c_double(float64 a); +float32 c_float_to_float32(float a); +float64 c_double_to_float64(double a); + +#ifdef FLOATX80 +float floatx80_to_c_float(floatx80 a); +double floatx80_to_c_double(floatx80 a); +floatx80 c_float_to_floatx80(float a); +floatx80 c_double_to_floatx80(double a); +#endif \ No newline at end of file diff --git a/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloatdef.h b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloatdef.h new file mode 100644 index 000000000..5bc07c79e --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/fpu/softfloat/softfloatdef.h @@ -0,0 +1,22 @@ +#pragma once + +typedef char flag; +typedef unsigned char uint8; +typedef signed char int8; +typedef unsigned short int uint16; +typedef signed short int int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned long long int uint64; +typedef signed long long int int64; + +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +typedef unsigned long long int bits64; +typedef signed long long int sbits64; + +#define LIT64(a) (a) diff --git a/source/src/vm/np21/i386c/ia32/instructions/logic_arith.cpp b/source/src/vm/np21/i386c/ia32/instructions/logic_arith.cpp new file mode 100644 index 000000000..b40048c14 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/logic_arith.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" +#include "arith.mcr" + +#include "logic_arith.h" + + +/* + * AND + */ +ARITH_INSTRUCTION_2(AND) + +/* + * OR + */ +ARITH_INSTRUCTION_2(OR) + +/* + * XOR + */ +ARITH_INSTRUCTION_2(XOR) + +/* + * NOT + */ +ARITH_INSTRUCTION_1(NOT) diff --git a/source/src/vm/np21/i386c/ia32/instructions/logic_arith.h b/source/src/vm/np21/i386c/ia32/instructions/logic_arith.h new file mode 100644 index 000000000..898aeef09 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/logic_arith.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_LOGIC_ARITH_H__ +#define IA32_CPU_INSTRUCTION_LOGIC_ARITH_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * AND + */ +void AND_EbGb(void); +void AND_EwGw(void); +void AND_EdGd(void); +void AND_GbEb(void); +void AND_GwEw(void); +void AND_GdEd(void); +void AND_ALIb(void); +void AND_AXIw(void); +void AND_EAXId(void); +void CPUCALL AND_EbIb(UINT8 *, UINT32); +void CPUCALL AND_EwIx(UINT16 *, UINT32); +void CPUCALL AND_EdIx(UINT32 *, UINT32); +void CPUCALL AND_EbIb_ext(UINT32, UINT32); +void CPUCALL AND_EwIx_ext(UINT32, UINT32); +void CPUCALL AND_EdIx_ext(UINT32, UINT32); + +/* + * OR + */ +void OR_EbGb(void); +void OR_EwGw(void); +void OR_EdGd(void); +void OR_GbEb(void); +void OR_GwEw(void); +void OR_GdEd(void); +void OR_ALIb(void); +void OR_AXIw(void); +void OR_EAXId(void); +void CPUCALL OR_EbIb(UINT8 *, UINT32); +void CPUCALL OR_EwIx(UINT16 *, UINT32); +void CPUCALL OR_EdIx(UINT32 *, UINT32); +void CPUCALL OR_EbIb_ext(UINT32, UINT32); +void CPUCALL OR_EwIx_ext(UINT32, UINT32); +void CPUCALL OR_EdIx_ext(UINT32, UINT32); + +/* + * XOR + */ +void XOR_EbGb(void); +void XOR_EwGw(void); +void XOR_EdGd(void); +void XOR_GbEb(void); +void XOR_GwEw(void); +void XOR_GdEd(void); +void XOR_ALIb(void); +void XOR_AXIw(void); +void XOR_EAXId(void); +void CPUCALL XOR_EbIb(UINT8 *, UINT32); +void CPUCALL XOR_EwIx(UINT16 *, UINT32); +void CPUCALL XOR_EdIx(UINT32 *, UINT32); +void CPUCALL XOR_EbIb_ext(UINT32, UINT32); +void CPUCALL XOR_EwIx_ext(UINT32, UINT32); +void CPUCALL XOR_EdIx_ext(UINT32, UINT32); + +/* + * NOT + */ +void CPUCALL NOT_Eb(UINT32); +void CPUCALL NOT_Ew(UINT32); +void CPUCALL NOT_Ed(UINT32); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_LOGIC_ARITH_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/misc_inst.cpp b/source/src/vm/np21/i386c/ia32/instructions/misc_inst.cpp new file mode 100644 index 000000000..f6e08942b --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/misc_inst.cpp @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "misc_inst.h" +#include "../inst_table.h" + +//#include "pccore.h" + +#ifdef USE_SSE2 +#include "sse2/sse2.h" +#endif + +#ifdef SUPPORT_IA32_HAXM +#include "bios/bios.h" +#endif +void +LEA_GwM(void) +{ + UINT16 *out; + UINT32 op, dst; + + GET_PCBYTE(op); + if (op < 0xc0) { + CPU_WORKCLOCK(2); + out = reg16_b53[op]; + dst = calc_ea_dst(op); + *out = (UINT16)dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LEA_GdM(void) +{ + UINT32 *out; + UINT32 op, dst; + + GET_PCBYTE(op); + if (op < 0xc0) { + CPU_WORKCLOCK(2); + out = reg32_b53[op]; + dst = calc_ea_dst(op); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +_NOP(void) +{ +#if defined(SUPPORT_IA32_HAXM) && defined(USE_CUSTOM_HOOKINST) + if(bioshookinfo.hookinst == 0x90) +#endif + //ia32_bioscall(); +} + +void +UD2(void) +{ + + EXCEPTION(UD_EXCEPTION, 0); +} + +void +XLAT(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_BX + CPU_AL); + } else { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_EBX + CPU_AL); + } +} + +void +_CPUID(void) +{ + switch (CPU_EAX) { + case 0: + CPU_EAX = 1; + CPU_EBX = LOADINTELDWORD(((UINT8*)(i386cpuid.cpu_vendor+0))); + CPU_EDX = LOADINTELDWORD(((UINT8*)(i386cpuid.cpu_vendor+4))); + CPU_ECX = LOADINTELDWORD(((UINT8*)(i386cpuid.cpu_vendor+8))); + break; + + case 1: + CPU_EAX = (((i386cpuid.cpu_family >> 4) & 0xff) << 20) | (((i386cpuid.cpu_model >> 4) & 0xf) << 16) | + ((i386cpuid.cpu_family & 0xf) << 8) | ((i386cpuid.cpu_model & 0xf) << 4) | (i386cpuid.cpu_stepping & 0xf); + CPU_EBX = i386cpuid.cpu_brandid; + CPU_ECX = i386cpuid.cpu_feature_ecx & CPU_FEATURES_ECX_ALL; + CPU_EDX = i386cpuid.cpu_feature & CPU_FEATURES_ALL; + break; + + case 2: + if(i386cpuid.cpu_family >= 6){ + CPU_EAX = 0x1; + CPU_EBX = 0; + CPU_ECX = 0; + CPU_EDX = 0x43; // 512KB L2 Cache ̂ӂ + }else{ + CPU_EAX = 0; + CPU_EBX = 0; + CPU_ECX = 0; + CPU_EDX = 0; + } + break; + + case 0x80000000: + CPU_EAX = 0x80000004; + if(strncmp(i386cpuid.cpu_vendor, CPU_VENDOR_AMD, 12)==0){ // AMD判定 + CPU_EBX = LOADINTELDWORD(((UINT8*)(i386cpuid.cpu_vendor+0))); + CPU_EDX = LOADINTELDWORD(((UINT8*)(i386cpuid.cpu_vendor+4))); + CPU_ECX = LOADINTELDWORD(((UINT8*)(i386cpuid.cpu_vendor+8))); + }else{ + CPU_EBX = 0; + CPU_ECX = 0; + CPU_EDX = 0; + } + break; + + case 0x80000001: + if(strncmp(i386cpuid.cpu_vendor, CPU_VENDOR_AMD, 12)==0){ // AMD判定 + if(i386cpuid.cpu_family >= 6 || (i386cpuid.cpu_family==5 && i386cpuid.cpu_model >= 6)){ + CPU_EAX = ((i386cpuid.cpu_family+1) << 8) | (i386cpuid.cpu_model << 4) | i386cpuid.cpu_stepping; + }else{ + CPU_EAX = (i386cpuid.cpu_family << 8) | (i386cpuid.cpu_model << 4) | i386cpuid.cpu_stepping; + } + }else{ + CPU_EAX = 0; + } + CPU_EBX = 0; + CPU_ECX = 0; + CPU_EDX = i386cpuid.cpu_feature_ex & CPU_FEATURES_EX_ALL; + break; + + case 0x80000002: + case 0x80000003: + case 0x80000004: + { + UINT32 clkMHz; + char cpu_brandstringbuf[64] = {0}; + int stroffset = (CPU_EAX - 0x80000002) * 16; + clkMHz = /*pccore.*/realclock/1000/1000; + sprintf(cpu_brandstringbuf, "%s%d MHz", i386cpuid.cpu_brandstring, clkMHz); + CPU_EAX = LOADINTELDWORD(((UINT8*)(cpu_brandstringbuf + stroffset + 0))); + CPU_EBX = LOADINTELDWORD(((UINT8*)(cpu_brandstringbuf + stroffset + 4))); + CPU_ECX = LOADINTELDWORD(((UINT8*)(cpu_brandstringbuf + stroffset + 8))); + CPU_EDX = LOADINTELDWORD(((UINT8*)(cpu_brandstringbuf + stroffset + 12))); + } + + break; + } +} + +/* undoc 8086 */ +void +SALC(void) +{ + + CPU_WORKCLOCK(2); + CPU_AL = (CPU_FLAGL & C_FLAG) ? 0xff : 0; +} + +/* undoc 286 */ +void +LOADALL286(void) +{ + + ia32_panic("LOADALL286: not implemented yet."); +} + +/* undoc 386 */ +void +LOADALL(void) +{ + + ia32_panic("LOADALL: not implemented yet."); +} + +void +OpSize(void) +{ + + CPU_INST_OP32 = !CPU_STATSAVE.cpu_inst_default.op_32; +} + +void +AddrSize(void) +{ + + CPU_INST_AS32 = !CPU_STATSAVE.cpu_inst_default.as_32; +} + +void +_2byte_ESC16(void) +{ + UINT32 op; + + GET_PCBYTE(op); +#ifdef USE_SSE + if(insttable_2byte660F_32[op] && CPU_INST_OP32 == !CPU_STATSAVE.cpu_inst_default.op_32){ + (*insttable_2byte660F_32[op])(); + return; + }else if(insttable_2byteF20F_32[op] && CPU_INST_REPUSE == 0xf2){ + (*insttable_2byteF20F_32[op])(); + return; + }else if(insttable_2byteF30F_32[op] && CPU_INST_REPUSE == 0xf3){ + (*insttable_2byteF30F_32[op])(); + return; + } +#endif + (*insttable_2byte[0][op])(); +} + +void +_2byte_ESC32(void) +{ + UINT32 op; + + GET_PCBYTE(op); +#ifdef USE_SSE + if(insttable_2byte660F_32[op] && CPU_INST_OP32 == !CPU_STATSAVE.cpu_inst_default.op_32){ + (*insttable_2byte660F_32[op])(); + return; + }else if(insttable_2byteF20F_32[op] && CPU_INST_REPUSE == 0xf2){ + (*insttable_2byteF20F_32[op])(); + return; + }else if(insttable_2byteF30F_32[op] && CPU_INST_REPUSE == 0xf3){ + (*insttable_2byteF30F_32[op])(); + return; + } +#endif + (*insttable_2byte[1][op])(); +} + +void +Prefix_ES(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_ES_INDEX; +} + +void +Prefix_CS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_CS_INDEX; +} + +void +Prefix_SS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_SS_INDEX; +} + +void +Prefix_DS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_DS_INDEX; +} + +void +Prefix_FS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_FS_INDEX; +} + +void +Prefix_GS(void) +{ + + CPU_INST_SEGUSE = 1; + CPU_INST_SEGREG_INDEX = CPU_GS_INDEX; +} +// +//void +//_2byte_Prefix660F_32(void) +//{ +//#ifdef USE_SSE2 +// UINT32 op; +// +// GET_PCBYTE(op); +// if(op==0x0f){ +// GET_PCBYTE(op); +// (*insttable_2byte660F_32[op])(); +// }else{ +// EXCEPTION(UD_EXCEPTION, 0); +// } +//#else +// EXCEPTION(UD_EXCEPTION, 0); +//#endif +//} +//void +//_2byte_PrefixF20F_32(void) +//{ +//#ifdef USE_SSE2 +// UINT32 op; +// +// GET_PCBYTE(op); +// if(op==0x0f){ +// GET_PCBYTE(op); +// (*insttable_2byteF20F_32[op])(); +// }else{ +// EXCEPTION(UD_EXCEPTION, 0); +// } +//#else +// EXCEPTION(UD_EXCEPTION, 0); +//#endif +//} +//void +//_2byte_PrefixF30F_32(void) +//{ +//#ifdef USE_SSE +// UINT32 op; +// +// GET_PCBYTE(op); +// if(op==0x0f){ +// GET_PCBYTE(op); +// (*insttable_2byteF30F_32[op])(); +//#ifdef USE_SSE2 +// }else if(op==0x90){ +// SSE2_PAUSE(); +//#endif +// }else{ +// EXCEPTION(UD_EXCEPTION, 0); +// } +//#else +// EXCEPTION(UD_EXCEPTION, 0); +//#endif +//} diff --git a/source/src/vm/np21/i386c/ia32/instructions/misc_inst.h b/source/src/vm/np21/i386c/ia32/instructions/misc_inst.h new file mode 100644 index 000000000..ab5d18800 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/misc_inst.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_MISC_H__ +#define IA32_CPU_INSTRUCTION_MISC_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void LEA_GwM(void); +void LEA_GdM(void); +void _NOP(void); +void UD2(void); +void XLAT(void); +void _CPUID(void); + +void SALC(void); /* undoc 8086 */ +void LOADALL286(void); /* undoc 286 */ +void LOADALL(void); /* undoc 386 */ + +void OpSize(void); +void AddrSize(void); +void _2byte_ESC16(void); +void _2byte_ESC32(void); +void Prefix_ES(void); +void Prefix_CS(void); +void Prefix_SS(void); +void Prefix_DS(void); +void Prefix_FS(void); +void Prefix_GS(void); + +//void _2byte_Prefix660F_32(void); +//void _2byte_PrefixF20F_32(void); +//void _2byte_PrefixF30F_32(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_MISC_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/mmx/3dnow.cpp b/source/src/vm/np21/i386c/ia32/instructions/mmx/3dnow.cpp new file mode 100644 index 000000000..d9768b069 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/mmx/3dnow.cpp @@ -0,0 +1,864 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" + +#include + +#include "../../cpu.h" +#include "../../ia32.mcr" + +#include "3dnow.h" + +#if defined(USE_3DNOW) && defined(USE_MMX) && defined(USE_FPU) + +#define CPU_MMXWORKCLOCK(a) CPU_WORKCLOCK(8) + +// 3DNow! +void AMD3DNOW_PAVGUSB_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PAVGUSB_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PF2ID_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PF2ID_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFACC_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFACC_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFADD_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFADD_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFCMPEQ_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFCMPEQ_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFCMPGE_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFCMPGE_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFCMPGT_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFCMPGT_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFMAX_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFMAX_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFMIN_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFMIN_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFMUL_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFMUL_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFRCP_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFRCP_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFRCPIT1_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFRCPIT1_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFRCPIT2_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFRCPIT2_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFRSQIT1_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFRSQIT1_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFRSQRT_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFRSQRT_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFSUB_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFSUB_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFSUBR_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFSUBR_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PI2FD_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PI2FD_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PMULHRW_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PMULHRW_MEM(UINT8 reg1, UINT32 memaddr); + +// Enhanced 3DNow! +void AMD3DNOW_PF2IW_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PF2IW_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PI2FW_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PI2FW_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFNACC_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFNACC_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PFPNACC_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PFPNACC_MEM(UINT8 reg1, UINT32 memaddr); + +void AMD3DNOW_PSWAPD_REG(UINT8 reg1, UINT8 reg2); +void AMD3DNOW_PSWAPD_MEM(UINT8 reg1, UINT32 memaddr); + + +static INLINE void +AMD3DNOW_check_NM_EXCEPTION(){ + // 3DNow!なしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_MMX) || !(i386cpuid.cpu_feature_ex & CPU_FEATURE_EX_3DNOW)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if (CPU_CR0 & CPU_CR0_TS) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static INLINE void +AMD3DNOW_setTag(void) +{ + int i; + + if(!FPU_STAT.mmxenable){ + FPU_STAT.mmxenable = 1; + //FPU_CTRLWORD = 0x27F; + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Valid; +#ifdef SUPPORT_FPU_DOSBOX2 + FPU_STAT.int_regvalid[i] = 0; +#endif + FPU_STAT.reg[i].ul.ext = 0xffff; + } + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; +} + +/* + * 3DNow! interface + */ +void +AMD3DNOW_FEMMS(void) +{ + int i; + + // MMXなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_MMX)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } + + CPU_WORKCLOCK(2); + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Empty; + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; + FPU_STAT.mmxenable = 0; +} + +void +AMD3DNOW_PREFETCH(void) +{ + UINT32 op; + UINT idx, sub; + + AMD3DNOW_check_NM_EXCEPTION(); + AMD3DNOW_setTag(); + CPU_MMXWORKCLOCK(a); + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + // Invalid Opcode + EXCEPTION(UD_EXCEPTION, 0); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + switch(idx){ + case 1: + // PREFETCHW + break; + case 0: + // PREFETCH + default: + // Reserved(=PREFETCH) + break; + } + // XXX: 何もしない + } +} + +void +AMD3DNOW_F0(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 suffix; + UINT8 reg1; + + AMD3DNOW_check_NM_EXCEPTION(); + AMD3DNOW_setTag(); + CPU_MMXWORKCLOCK(a); + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + // mmreg1, mmreg2 + UINT8 reg2; + reg1 = idx; + reg2 = sub; + GET_PCBYTE((suffix)); + switch(suffix){ + case AMD3DNOW_SUFFIX_PAVGUSB: + AMD3DNOW_PAVGUSB_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFADD: + AMD3DNOW_PFADD_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFSUB: + AMD3DNOW_PFSUB_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFSUBR: + AMD3DNOW_PFSUBR_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFACC: + AMD3DNOW_PFACC_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFCMPGE: + AMD3DNOW_PFCMPGE_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFCMPGT: + AMD3DNOW_PFCMPGT_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFCMPEQ: + AMD3DNOW_PFCMPEQ_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFMIN: + AMD3DNOW_PFMIN_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFMAX: + AMD3DNOW_PFMAX_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PI2FD: + AMD3DNOW_PI2FD_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PF2ID: + AMD3DNOW_PI2FD_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFRCP: + AMD3DNOW_PFRCP_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFRSQRT: + AMD3DNOW_PFRSQRT_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFMUL: + AMD3DNOW_PFMUL_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFRCPIT1: + AMD3DNOW_PFRCPIT1_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFRSQIT1: + AMD3DNOW_PFRSQIT1_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFRCPIT2: + AMD3DNOW_PFRCPIT2_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PMULHRW: + AMD3DNOW_PMULHRW_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PF2IW: + AMD3DNOW_PF2IW_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PI2FW: + AMD3DNOW_PI2FW_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFNACC: + AMD3DNOW_PFNACC_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PFPNACC: + AMD3DNOW_PFPNACC_REG(reg1, reg2); + break; + case AMD3DNOW_SUFFIX_PSWAPD: + AMD3DNOW_PSWAPD_REG(reg1, reg2); + break; + default: + EXCEPTION(UD_EXCEPTION, 0); + break; + } + } else { + // mmreg1, mem + UINT32 memaddr; + reg1 = idx; + memaddr = calc_ea_dst(op); + GET_PCBYTE((suffix)); + switch(suffix){ + case AMD3DNOW_SUFFIX_PAVGUSB: + AMD3DNOW_PAVGUSB_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFADD: + AMD3DNOW_PFADD_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFSUB: + AMD3DNOW_PFSUB_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFSUBR: + AMD3DNOW_PFSUBR_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFACC: + AMD3DNOW_PFACC_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFCMPGE: + AMD3DNOW_PFCMPGE_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFCMPGT: + AMD3DNOW_PFCMPGT_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFCMPEQ: + AMD3DNOW_PFCMPEQ_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFMIN: + AMD3DNOW_PFMIN_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFMAX: + AMD3DNOW_PFMAX_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PI2FD: + AMD3DNOW_PI2FD_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PF2ID: + AMD3DNOW_PI2FD_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFRCP: + AMD3DNOW_PFRCP_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFRSQRT: + AMD3DNOW_PFRSQRT_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFMUL: + AMD3DNOW_PFMUL_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFRCPIT1: + AMD3DNOW_PFRCPIT1_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFRSQIT1: + AMD3DNOW_PFRSQIT1_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFRCPIT2: + AMD3DNOW_PFRCPIT2_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PMULHRW: + AMD3DNOW_PMULHRW_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PF2IW: + AMD3DNOW_PF2IW_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PI2FW: + AMD3DNOW_PI2FW_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFNACC: + AMD3DNOW_PFNACC_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PFPNACC: + AMD3DNOW_PFPNACC_MEM(reg1, memaddr); + break; + case AMD3DNOW_SUFFIX_PSWAPD: + AMD3DNOW_PSWAPD_MEM(reg1, memaddr); + break; + default: + EXCEPTION(UD_EXCEPTION, 0); + break; + } + } +} + +// PAVGUSB +void AMD3DNOW_PAVGUSB(UINT8 *data1, UINT8 *data2){ + int i; + for(i=0;i<8;i++){ + data1[i] = (UINT8)(((UINT16)(data1[i]) + (UINT16)(data2[i]) + 1) / 2); + } +} +void AMD3DNOW_PAVGUSB_REG(UINT8 reg1, UINT8 reg2){ + UINT8 *data1 = (UINT8*)(&(FPU_STAT.reg[reg1])); + UINT8 *data2 = (UINT8*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PAVGUSB(data1, data2); +} +void AMD3DNOW_PAVGUSB_MEM(UINT8 reg1, UINT32 memaddr){ + UINT8 *data1 = (UINT8*)(&(FPU_STAT.reg[reg1])); + UINT8 data2[8]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PAVGUSB(data1, data2); +} + +// PF2ID +void AMD3DNOW_PF2ID(SINT32 *data1, float *data2){ + int i; + for(i=0;i<2;i++){ + if (data2[i] >= (float)((SINT32)0x7fffffff)){ + data1[i] = (SINT32)0x7fffffff; + }else if(data2[i] <= (float)((SINT32)0x80000000)){ + data1[i] = (SINT32)0x80000000; + }else{ + data1[i] = (SINT32)data2[i]; + } + } +} +void AMD3DNOW_PF2ID_REG(UINT8 reg1, UINT8 reg2){ + SINT32 *data1 = (SINT32*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PF2ID(data1, data2); +} +void AMD3DNOW_PF2ID_MEM(UINT8 reg1, UINT32 memaddr){ + SINT32 *data1 = (SINT32*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PF2ID(data1, data2); +} + +// PFACC +void AMD3DNOW_PFACC(float *data1, float *data2){ + float temp[2]; + temp[0] = data2[0]; + temp[1] = data2[1]; + data1[0] = data1[0] + data1[1]; + data1[1] = temp[0] + temp[1]; +} +void AMD3DNOW_PFACC_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFACC(data1, data2); +} +void AMD3DNOW_PFACC_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFACC(data1, data2); +} + +// PFADD +void AMD3DNOW_PFADD(float *data1, float *data2){ + data1[0] = data1[0] + data2[0]; + data1[1] = data1[1] + data2[1]; +} +void AMD3DNOW_PFADD_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFADD(data1, data2); +} +void AMD3DNOW_PFADD_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFADD(data1, data2); +} + +// PFCMPEQ +void AMD3DNOW_PFCMPEQ(float *data1, float *data2){ + *((UINT32*)(data1+0)) = (data1[0] == data2[0] ? 0xffffffff : 0x00000000); + *((UINT32*)(data1+1)) = (data1[1] == data2[1] ? 0xffffffff : 0x00000000); +} +void AMD3DNOW_PFCMPEQ_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFCMPEQ(data1, data2); +} +void AMD3DNOW_PFCMPEQ_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFCMPEQ(data1, data2); +} + +// PFCMPGE +void AMD3DNOW_PFCMPGE(float *data1, float *data2){ + *((UINT32*)(data1+0)) = (data1[0] >= data2[0] ? 0xffffffff : 0x00000000); + *((UINT32*)(data1+1)) = (data1[1] >= data2[1] ? 0xffffffff : 0x00000000); +} +void AMD3DNOW_PFCMPGE_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFCMPGE(data1, data2); +} +void AMD3DNOW_PFCMPGE_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFCMPGE(data1, data2); +} + +// PFCMPGT +void AMD3DNOW_PFCMPGT(float *data1, float *data2){ + *((UINT32*)(data1+0)) = (data1[0] > data2[0] ? 0xffffffff : 0x00000000); + *((UINT32*)(data1+1)) = (data1[1] > data2[1] ? 0xffffffff : 0x00000000); +} +void AMD3DNOW_PFCMPGT_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFCMPGT(data1, data2); +} +void AMD3DNOW_PFCMPGT_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFCMPGT(data1, data2); +} + +// PFMAX +void AMD3DNOW_PFMAX(float *data1, float *data2){ + data1[0] = (data1[0] > data2[0] ? data1[0] : data2[0]); + data1[1] = (data1[1] > data2[1] ? data1[1] : data2[1]); +} +void AMD3DNOW_PFMAX_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFMAX(data1, data2); +} +void AMD3DNOW_PFMAX_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFMAX(data1, data2); +} + +// PFMIN +void AMD3DNOW_PFMIN(float *data1, float *data2){ + data1[0] = (data1[0] < data2[0] ? data1[0] : data2[0]); + data1[1] = (data1[1] < data2[1] ? data1[1] : data2[1]); +} +void AMD3DNOW_PFMIN_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFMIN(data1, data2); +} +void AMD3DNOW_PFMIN_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFMIN(data1, data2); +} + +// PFMUL +void AMD3DNOW_PFMUL(float *data1, float *data2){ + data1[0] = data1[0] * data2[0]; + data1[1] = data1[1] * data2[1]; +} +void AMD3DNOW_PFMUL_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFMUL(data1, data2); +} +void AMD3DNOW_PFMUL_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFMUL(data1, data2); +} + +// PFRCP +void AMD3DNOW_PFRCP(float *data1, float *data2){ + // XXX: ただのコピー + data1[0] = 1.0f / data2[0]; + data1[1] = 1.0f / data2[1]; +} +void AMD3DNOW_PFRCP_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFRCP(data1, data2); +} +void AMD3DNOW_PFRCP_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFRCP(data1, data2); +} + +// PFRCPIT1 +void AMD3DNOW_PFRCPIT1(float *data1, float *data2){ + // XXX: ただのコピーで代替 + data1[0] = data2[0]; + data1[1] = data2[1]; +} +void AMD3DNOW_PFRCPIT1_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFRCPIT1(data1, data2); +} +void AMD3DNOW_PFRCPIT1_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFRCPIT1(data1, data2); +} + +// PFRCPIT2 +void AMD3DNOW_PFRCPIT2(float *data1, float *data2){ + // XXX: ただのコピーで代替 + data1[0] = data2[0]; + data1[1] = data2[1]; +} +void AMD3DNOW_PFRCPIT2_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFRCPIT2(data1, data2); +} +void AMD3DNOW_PFRCPIT2_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFRCPIT2(data1, data2); +} + +// PFRSQIT1 +void AMD3DNOW_PFRSQIT1(float *data1, float *data2){ + // XXX: ただのコピーで代替 + data1[0] = data2[0]; + data1[1] = data2[1]; +} +void AMD3DNOW_PFRSQIT1_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFRSQIT1(data1, data2); +} +void AMD3DNOW_PFRSQIT1_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFRSQIT1(data1, data2); +} + +// PFRSQRT +void AMD3DNOW_PFRSQRT(float *data1, float *data2){ + data1[0] = (float)(1.0f / sqrt(data2[0])); + data1[1] = (float)(1.0f / sqrt(data2[1])); +} +void AMD3DNOW_PFRSQRT_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFRSQRT(data1, data2); +} +void AMD3DNOW_PFRSQRT_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFRSQRT(data1, data2); +} + +// PFSUB +void AMD3DNOW_PFSUB(float *data1, float *data2){ + data1[0] = data1[0] - data2[0]; + data1[1] = data1[1] - data2[1]; +} +void AMD3DNOW_PFSUB_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFSUB(data1, data2); +} +void AMD3DNOW_PFSUB_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFSUB(data1, data2); +} + +// PFSUBR +void AMD3DNOW_PFSUBR(float *data1, float *data2){ + data1[0] = data2[0] - data1[0]; + data1[1] = data2[1] - data1[1]; +} +void AMD3DNOW_PFSUBR_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFSUBR(data1, data2); +} +void AMD3DNOW_PFSUBR_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFSUBR(data1, data2); +} + +// PI2FD +void AMD3DNOW_PI2FD(float *data1, SINT32 *data2){ + data1[0] = (float)(data2[0]); + data1[1] = (float)(data2[1]); +} +void AMD3DNOW_PI2FD_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + SINT32 *data2 = (SINT32*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PI2FD(data1, data2); +} +void AMD3DNOW_PI2FD_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + SINT32 data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PI2FD(data1, data2); +} + +// PMULHRW +void AMD3DNOW_PMULHRW(SINT16 *data1, SINT16 *data2){ + int i; + for(i=0;i<4;i++){ + data1[i] = (UINT16)((((UINT32)data1[i] * (UINT32)data2[i] + 0x8000) >> 16) & 0xffff); + } +} +void AMD3DNOW_PMULHRW_REG(UINT8 reg1, UINT8 reg2){ + SINT16 *data1 = (SINT16*)(&(FPU_STAT.reg[reg1])); + SINT16 *data2 = (SINT16*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PMULHRW(data1, data2); +} +void AMD3DNOW_PMULHRW_MEM(UINT8 reg1, UINT32 memaddr){ + SINT16 *data1 = (SINT16*)(&(FPU_STAT.reg[reg1])); + SINT16 data2[4]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PMULHRW(data1, data2); +} + +/* + * Enhanced 3DNow! interface + */ +// PF2IW +void AMD3DNOW_PF2IW(SINT32 *data1, float *data2){ + int i; + for(i=0;i<2;i++){ + if (data2[i] >= (float)((SINT16)0x7fff)){ + data1[i] = (SINT16)0x7fff; + }else if(data2[i] <= (float)((SINT16)0x8000)){ + data1[i] = (SINT16)0x8000; + }else{ + data1[i] = (SINT16)data2[i]; + } + } +} +void AMD3DNOW_PF2IW_REG(UINT8 reg1, UINT8 reg2){ + SINT32 *data1 = (SINT32*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PF2IW(data1, data2); +} +void AMD3DNOW_PF2IW_MEM(UINT8 reg1, UINT32 memaddr){ + SINT32 *data1 = (SINT32*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PF2IW(data1, data2); +} + +// PI2FW +void AMD3DNOW_PI2FW(float *data1, SINT16 *data2){ + data1[0] = (float)(data2[0]); + data1[1] = (float)(data2[2]); +} +void AMD3DNOW_PI2FW_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + SINT16 *data2 = (SINT16*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PI2FW(data1, data2); +} +void AMD3DNOW_PI2FW_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + SINT16 data2[4]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PI2FW(data1, data2); +} + +// PFNACC +void AMD3DNOW_PFNACC(float *data1, float *data2){ + float temp[2]; + temp[0] = data2[0]; + temp[1] = data2[1]; + data1[0] = data1[0] - data1[1]; + data1[1] = temp[0] - temp[1]; +} +void AMD3DNOW_PFNACC_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFNACC(data1, data2); +} +void AMD3DNOW_PFNACC_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFNACC(data1, data2); +} + +// PFPNACC +void AMD3DNOW_PFPNACC(float *data1, float *data2){ + float temp[2]; + temp[0] = data2[0]; + temp[1] = data2[1]; + data1[0] = data1[0] - data1[1]; + data1[1] = temp[0] + temp[1]; +} +void AMD3DNOW_PFPNACC_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PFPNACC(data1, data2); +} +void AMD3DNOW_PFPNACC_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PFPNACC(data1, data2); +} + +// PSWAPD +void AMD3DNOW_PSWAPD(float *data1, float *data2){ + float temp[2]; + temp[0] = data2[0]; + temp[1] = data2[1]; + data1[0] = temp[1]; + data1[1] = temp[0]; +} +void AMD3DNOW_PSWAPD_REG(UINT8 reg1, UINT8 reg2){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float *data2 = (float*)(&(FPU_STAT.reg[reg2])); + AMD3DNOW_PSWAPD(data1, data2); +} +void AMD3DNOW_PSWAPD_MEM(UINT8 reg1, UINT32 memaddr){ + float *data1 = (float*)(&(FPU_STAT.reg[reg1])); + float data2[2]; + *((UINT64*)data2) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, memaddr); + AMD3DNOW_PSWAPD(data1, data2); +} + +#else + +/* + * 3DNow! interface + */ +void AMD3DNOW_F0(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void AMD3DNOW_FEMMS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void AMD3DNOW_PREFETCH(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/mmx/3dnow.h b/source/src/vm/np21/i386c/ia32/instructions/mmx/3dnow.h new file mode 100644 index 000000000..150b272f5 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/mmx/3dnow.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_MMX_AMD3DNOW_H__ +#define IA32_CPU_INSTRUCTION_MMX_AMD3DNOW_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +enum{ + AMD3DNOW_SUFFIX_PAVGUSB = 0xBF, + AMD3DNOW_SUFFIX_PFADD = 0x9E, + AMD3DNOW_SUFFIX_PFSUB = 0x9A, + AMD3DNOW_SUFFIX_PFSUBR = 0xAA, + AMD3DNOW_SUFFIX_PFACC = 0xAE, + AMD3DNOW_SUFFIX_PFCMPGE = 0x90, + AMD3DNOW_SUFFIX_PFCMPGT = 0xA0, + AMD3DNOW_SUFFIX_PFCMPEQ = 0xB0, + AMD3DNOW_SUFFIX_PFMIN = 0x94, + AMD3DNOW_SUFFIX_PFMAX = 0xA4, + AMD3DNOW_SUFFIX_PI2FD = 0x0D, + AMD3DNOW_SUFFIX_PF2ID = 0x1D, + AMD3DNOW_SUFFIX_PFRCP = 0x96, + AMD3DNOW_SUFFIX_PFRSQRT = 0x97, + AMD3DNOW_SUFFIX_PFMUL = 0xB4, + AMD3DNOW_SUFFIX_PFRCPIT1 = 0xA6, + AMD3DNOW_SUFFIX_PFRSQIT1 = 0xA7, + AMD3DNOW_SUFFIX_PFRCPIT2 = 0xB6, + AMD3DNOW_SUFFIX_PMULHRW = 0xB7, + AMD3DNOW_SUFFIX_PF2IW = 0x1C, + AMD3DNOW_SUFFIX_PI2FW = 0x0C, + AMD3DNOW_SUFFIX_PFNACC = 0x8A, + AMD3DNOW_SUFFIX_PFPNACC = 0x8E, + AMD3DNOW_SUFFIX_PSWAPD = 0xBB, +}; + +void AMD3DNOW_F0(void); + +void AMD3DNOW_FEMMS(void); + +void AMD3DNOW_PREFETCH(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_MMX_AMD3DNOW_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx.cpp b/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx.cpp new file mode 100644 index 000000000..48f7d99ab --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx.cpp @@ -0,0 +1,2090 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" + +#include "../../cpu.h" +#include "../../ia32.mcr" + +#include "mmx.h" + +#if defined(USE_MMX) && defined(USE_FPU) + +#define CPU_MMXWORKCLOCK CPU_WORKCLOCK(6) + +static INLINE void +MMX_check_NM_EXCEPTION(){ + // MMXなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_MMX)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if (CPU_CR0 & CPU_CR0_TS) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static INLINE void +MMX_setTag(void) +{ + int i; + + if(!FPU_STAT.mmxenable){ + FPU_STAT.mmxenable = 1; + //FPU_CTRLWORD = 0x27F; + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Valid; +#ifdef SUPPORT_FPU_DOSBOX2 + FPU_STAT.int_regvalid[i] = 0; +#endif + FPU_STAT.reg[i].ul.ext = 0xffff; + } + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; +} + +/* + * MMX interface + */ +void +MMX_EMMS(void) +{ + int i; + + // MMXなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_MMX)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } + + CPU_WORKCLOCK(2); + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Empty; + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; + FPU_STAT.mmxenable = 0; +} + +// *********** MOV + +void MMX_MOVD_mm_rm32(void) +{ + UINT32 op, src; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + (src) = *(reg32_b20[(op)]); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + (src) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + } + FPU_STAT.reg[idx].ul.lower = src; + FPU_STAT.reg[idx].ul.upper = 0; +} +void MMX_MOVD_rm32_mm(void) +{ + UINT32 op, src, madr; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + src = FPU_STAT.reg[idx].ul.lower; + if (op >= 0xc0) { + *(reg32_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void MMX_MOVQ_mm_mmm64(void) +{ + UINT32 op; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[idx].ll = FPU_STAT.reg[sub].ll; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + FPU_STAT.reg[idx].ll = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, madr); + //FPU_STAT.reg[idx].ul.lower = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + //FPU_STAT.reg[idx].ul.upper = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr+4); + } +} +void MMX_MOVQ_mmm64_mm(void) +{ + UINT32 op; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[sub].ll = FPU_STAT.reg[idx].ll; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_q(CPU_INST_SEGREG_INDEX, madr, FPU_STAT.reg[idx].ll); + //cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, FPU_STAT.reg[idx].ul.lower); + //cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+4, FPU_STAT.reg[idx].ul.upper); + } +} + + +// *********** PACK + +void MMX_PACKSSWB(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcreg2buf[4]; + INT16 *srcreg1; + INT16 *srcreg2; + INT8 *dstreg; + INT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&(FPU_STAT.reg[sub])); + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&srcreg2buf); + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + } + for(i=0;i<4;i++){ + if(srcreg1[i] > 127){ + dstregbuf[i] = 127; + }else if(srcreg1[i] < -128){ + dstregbuf[i] = -128; + }else{ + dstregbuf[i] = (INT8)(srcreg1[i]); + } + } + for(i=0;i<4;i++){ + if(srcreg2[i] > 127){ + dstregbuf[i+4] = 127; + }else if(srcreg2[i] < -128){ + dstregbuf[i+4] = -128; + }else{ + dstregbuf[i+4] = (INT8)(srcreg2[i]); + } + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PACKSSDW(void) +{ + UINT32 op; + UINT idx, sub; + INT32 srcreg2buf[2]; + INT32 *srcreg1; + INT32 *srcreg2; + INT16 *dstreg; + INT16 dstregbuf[4]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT32*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT32*)(&(FPU_STAT.reg[sub])); + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT32*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT32*)(&srcreg2buf); + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + } + for(i=0;i<2;i++){ + if(srcreg1[i] > 32767){ + dstregbuf[i] = 32767; + }else if(srcreg1[i] < -32768){ + dstregbuf[i] = -32768; + }else{ + dstregbuf[i] = (INT16)(srcreg1[i]); + } + } + for(i=0;i<2;i++){ + if(srcreg2[i] > 32767){ + dstregbuf[i+2] = 32767; + }else if(srcreg2[i] < -32768){ + dstregbuf[i+2] = -32768; + }else{ + dstregbuf[i+2] = (INT16)(srcreg2[i]); + } + } + for(i=0;i<4;i++){ + dstreg[i] = dstregbuf[i]; + } +} + +void MMX_PACKUSWB(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcreg2buf[4]; + INT16 *srcreg1; + INT16 *srcreg2; + UINT8 *dstreg; + UINT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&(FPU_STAT.reg[sub])); + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&srcreg2buf); + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + } + for(i=0;i<4;i++){ + if(srcreg1[i] > 255){ + dstregbuf[i] = 255; + }else if(srcreg1[i] < 0){ + dstregbuf[i] = 0; + }else{ + dstregbuf[i] = (UINT8)(srcreg1[i]); + } + } + for(i=0;i<4;i++){ + if(srcreg2[i] > 255){ + dstregbuf[i+4] = 255; + }else if(srcreg2[i] < 0){ + dstregbuf[i+4] = 0; + }else{ + dstregbuf[i+4] = (UINT8)(srcreg2[i]); + } + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} + +// *********** PADD + +void MMX_PADDB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + dstreg[i] += srcreg[i]; + } +} +void MMX_PADDW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] += srcreg[i]; + } +} +void MMX_PADDD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstreg[i] += srcreg[i]; + } +} + +void MMX_PADDSB(void) +{ + UINT32 op; + UINT idx, sub; + INT8 srcregbuf[8]; + INT8 *srcreg; + INT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT8*)(srcregbuf); + } + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + INT16 cbuf = (INT16)dstreg[i] + (INT16)srcreg[i]; + if(cbuf > 127){ + dstreg[i] = 127; + }else if(cbuf < -128){ + dstreg[i] = -128; + }else{ + dstreg[i] = (INT8)cbuf; + } + } +} +void MMX_PADDSW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + INT32 cbuf = (INT32)dstreg[i] + (INT32)srcreg[i]; + if(cbuf > 32767){ + dstreg[i] = 32767; + }else if(cbuf < -32768){ + dstreg[i] = -32768; + }else{ + dstreg[i] = (INT16)cbuf; + } + } +} + +void MMX_PADDUSB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + UINT16 cbuf = (UINT16)dstreg[i] + (UINT16)srcreg[i]; + if(cbuf > 255){ + dstreg[i] = 255; + }else{ + dstreg[i] = (UINT8)cbuf; + } + } +} +void MMX_PADDUSW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + UINT32 cbuf = (UINT32)dstreg[i] + (UINT32)srcreg[i]; + if(cbuf > 65535){ + dstreg[i] = 65535; + }else{ + dstreg[i] = (UINT16)cbuf; + } + } +} + +// *********** PAND/ANDN,OR,XOR + +void MMX_PAND(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstreg[0] = dstreg[0] & srcreg[0]; + dstreg[1] = dstreg[1] & srcreg[1]; +} +void MMX_PANDN(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + //dstreg[0] = ~(dstreg[0] & srcreg[0]); + //dstreg[1] = ~(dstreg[1] & srcreg[1]); + dstreg[0] = (~dstreg[0]) & srcreg[0]; + dstreg[1] = (~dstreg[1]) & srcreg[1]; +} +void MMX_POR(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstreg[0] = dstreg[0] | srcreg[0]; + dstreg[1] = dstreg[1] | srcreg[1]; +} +void MMX_PXOR(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstreg[0] = dstreg[0] ^ srcreg[0]; + dstreg[1] = dstreg[1] ^ srcreg[1]; +} + +// *********** PCMPEQ + +void MMX_PCMPEQB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + if(dstreg[i] == srcreg[i]){ + dstreg[i] = 0xff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPEQW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + if(dstreg[i] == srcreg[i]){ + dstreg[i] = 0xffff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPEQD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + if(dstreg[i] == srcreg[i]){ + dstreg[i] = 0xffffffff; + }else{ + dstreg[i] = 0; + } + } +} + +// *********** PCMPGT + +void MMX_PCMPGTB(void) +{ + UINT32 op; + UINT idx, sub; + INT8 srcregbuf[8]; + INT8 *srcreg; + INT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT8*)(srcregbuf); + } + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + if(dstreg[i] > srcreg[i]){ + dstreg[i] = 0xff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPGTW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + if(dstreg[i] > srcreg[i]){ + dstreg[i] = 0xffff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPGTD(void) +{ + UINT32 op; + UINT idx, sub; + INT32 srcregbuf[2]; + INT32 *srcreg; + INT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT32*)(srcregbuf); + } + dstreg = (INT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + if(dstreg[i] > srcreg[i]){ + dstreg[i] = 0xffffffff; + }else{ + dstreg[i] = 0; + } + } +} + +// *********** PMADDWD +void MMX_PMADDWD(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + INT32 *dstreg32; + INT32 dstregbuf[2]; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + dstreg32 = (INT32*)(&(FPU_STAT.reg[idx])); + + dstregbuf[0] = (INT32)srcreg[0] * (INT32)dstreg[0] + (INT32)srcreg[1] * (INT32)dstreg[1]; + dstregbuf[1] = (INT32)srcreg[2] * (INT32)dstreg[2] + (INT32)srcreg[3] * (INT32)dstreg[3]; + dstreg32[0] = dstregbuf[0]; + dstreg32[1] = dstregbuf[1]; +} + +// *********** PMUL +void MMX_PMULHW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] = (INT16)((((INT32)srcreg[i] * (INT32)dstreg[i]) >> 16) & 0xffff); + } +} +void MMX_PMULLW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] = (INT16)((((INT32)srcreg[i] * (INT32)dstreg[i])) & 0xffff); + } +} + +// *********** PSLL +void MMX_PSLLW(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + //dstreg[i] = (dstreg[i] << shift); + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] << (UINT16)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSLLD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + //dstreg[i] = (dstreg[i] << shift); + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] << (UINT32)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSLLQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT64 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT64*)(&(FPU_STAT.reg[idx])); + + //dstreg[0] = (dstreg[0] << shift); + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] << (UINT64)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) +} + +// *********** PSRA + +void MMX_PSRAW(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + UINT16 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + // 無理やり算術シフト(怪しい) + if(16 <= shift){ + signval = 0xffff; + }else{ + UINT32 rshift = 16 - shift; + signval = (0xffff >> rshift) << rshift; + } + for(i=0;i<4;i++){ + if(((INT16*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } +} +void MMX_PSRAD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + UINT32 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + // 無理やり算術シフト(怪しい) + if(32 <= shift){ + signval = 0xffffffff; + }else{ + UINT32 rshift = 32 - shift; + signval = (0xffffffff >> rshift) << rshift; + } + for(i=0;i<2;i++){ + if(((INT32*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } +} + +// *********** PSRL +void MMX_PSRLW(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + //dstreg[i] = (dstreg[i] >> shift); + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSRLD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + //dstreg[i] = (dstreg[i] >> shift); + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSRLQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT64 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: シフトしすぎ + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: シフトしすぎ + } + dstreg = (UINT64*)(&(FPU_STAT.reg[idx])); + + //dstreg[0] = (dstreg[0] >> shift); + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] >> (UINT64)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) +} + +// *********** PSLL(imm8),PSRL(imm8),PSRA(imm8) +void MMX_PSxxW_imm8(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + UINT16 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT16*)(&(FPU_STAT.reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLW(imm8) + for(i=0;i<4;i++){ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + break; + case 4: // PSRAW(imm8) + // 無理やり算術シフト(怪しい) + if(16 <= shift){ + signval = 0xffff; + }else{ + UINT32 rshift = 16 - shift; + signval = (0xffff >> rshift) << rshift; + } + for(i=0;i<4;i++){ + if(((INT16*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + break; + case 6: // PSLLW(imm8) + for(i=0;i<4;i++){ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] << (UINT16)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + break; + default: + break; + } +} +void MMX_PSxxD_imm8(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + UINT32 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT32*)(&(FPU_STAT.reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLD(imm8) + for(i=0;i<2;i++){ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + break; + case 4: // PSRAD(imm8) + // 無理やり算術シフト(怪しい) + if(32 <= shift){ + signval = 0xffffffff; + }else{ + UINT32 rshift = 32 - shift; + signval = (0xffffffff >> rshift) << rshift; + } + for(i=0;i<2;i++){ + if(((INT32*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + break; + case 6: // PSLLD(imm8) + for(i=0;i<2;i++){ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] << (UINT32)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + break; + default: + break; + } +} +void MMX_PSxxQ_imm8(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT64 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT64*)(&(FPU_STAT.reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLQ(imm8) + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] >> (UINT64)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + break; + case 4: // PSRAQ(imm8) + EXCEPTION(UD_EXCEPTION, 0); + break; + case 6: // PSLLQ(imm8) + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] << (UINT64)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + break; + default: + break; + } +} + +// *********** PSUB + +void MMX_PSUBB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + dstreg[i] -= srcreg[i]; + } +} +void MMX_PSUBW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] -= srcreg[i]; + } +} +void MMX_PSUBD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstreg[i] -= srcreg[i]; + } +} + +void MMX_PSUBSB(void) +{ + UINT32 op; + UINT idx, sub; + INT8 srcregbuf[8]; + INT8 *srcreg; + INT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT8*)(srcregbuf); + } + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + INT16 cbuf = (INT16)dstreg[i] - (INT16)srcreg[i]; + if(cbuf > 127){ + dstreg[i] = 127; + }else if(cbuf < -128){ + dstreg[i] = -128; + }else{ + dstreg[i] = (INT8)cbuf; + } + } +} +void MMX_PSUBSW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + INT32 cbuf = (INT32)dstreg[i] - (INT32)srcreg[i]; + if(cbuf > 32767){ + dstreg[i] = 32767; + }else if(cbuf < -32768){ + dstreg[i] = -32768; + }else{ + dstreg[i] = (INT16)cbuf; + } + } +} + +void MMX_PSUBUSB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + INT16 cbuf = (INT16)dstreg[i] - (INT16)srcreg[i]; + if(cbuf > 255){ + dstreg[i] = 255; + }else if(cbuf < 0){ + dstreg[i] = 0; + }else{ + dstreg[i] = (UINT8)cbuf; + } + } +} +void MMX_PSUBUSW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + INT32 cbuf = (INT32)dstreg[i] - (INT32)srcreg[i]; + if(cbuf > 65535){ + dstreg[i] = 65535; + }else if(cbuf < 0){ + dstreg[i] = 0; + }else{ + dstreg[i] = (UINT16)cbuf; + } + } +} + +// *********** PUNPCK + +void MMX_PUNPCKHBW(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + UINT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstregbuf[i*2] = dstreg[i+4]; + dstregbuf[i*2 + 1] = srcreg[i+4]; + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKHWD(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + UINT16 dstregbuf[4]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstregbuf[i*2] = dstreg[i+2]; + dstregbuf[i*2 + 1] = srcreg[i+2]; + } + for(i=0;i<4;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKHDQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + UINT32 dstregbuf[2]; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstregbuf[0] = dstreg[1]; + dstregbuf[1] = srcreg[1]; + dstreg[0] = dstregbuf[0]; + dstreg[1] = dstregbuf[1]; +} +void MMX_PUNPCKLBW(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + UINT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstregbuf[i*2] = dstreg[i]; + dstregbuf[i*2 + 1] = srcreg[i]; + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKLWD(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + UINT16 dstregbuf[4]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstregbuf[i*2] = dstreg[i]; + dstregbuf[i*2 + 1] = srcreg[i]; + } + for(i=0;i<4;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKLDQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + UINT32 dstregbuf[2]; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstregbuf[0] = dstreg[0]; + dstregbuf[1] = srcreg[0]; + dstreg[0] = dstregbuf[0]; + dstreg[1] = dstregbuf[1]; +} + +#else + +/* + * MMX interface + */ +void +MMX_EMMS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_MOVD_mm_rm32(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_MOVD_rm32_mm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_MOVQ_mm_mmm64(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_MOVQ_mmm64_mm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PACKSSWB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PACKSSDW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PACKUSWB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PADDB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PADDSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PADDUSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDUSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PAND(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PANDN(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_POR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PXOR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PCMPEQB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPEQW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPEQD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PCMPGTB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPGTW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPGTD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PMADDWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PMULHW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PMULLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSLLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSLLD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSLLQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSRAW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSRAD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSRLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSRLD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSRLQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSxxW_imm8(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSxxD_imm8(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSxxQ_imm8(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSUBB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSUBSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSUBUSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBUSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PUNPCKHBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKHWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKHDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKLBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKLWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKLDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx.h b/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx.h new file mode 100644 index 000000000..b41873c94 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_MMX_MMX_H__ +#define IA32_CPU_INSTRUCTION_MMX_MMX_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void MMX_EMMS(void); + +void MMX_MOVD_mm_rm32(void); +void MMX_MOVD_rm32_mm(void); + +void MMX_MOVQ_mm_mmm64(void); +void MMX_MOVQ_mmm64_mm(void); + +void MMX_PACKSSWB(void); +void MMX_PACKSSDW(void); + +void MMX_PACKUSWB(void); + +void MMX_PADDB(void); +void MMX_PADDW(void); +void MMX_PADDD(void); + +void MMX_PADDSB(void); +void MMX_PADDSW(void); + +void MMX_PADDUSB(void); +void MMX_PADDUSW(void); + +void MMX_PAND(void); +void MMX_PANDN(void); +void MMX_POR(void); +void MMX_PXOR(void); + +void MMX_PCMPEQB(void); +void MMX_PCMPEQW(void); +void MMX_PCMPEQD(void); + +void MMX_PCMPGTB(void); +void MMX_PCMPGTW(void); +void MMX_PCMPGTD(void); + +void MMX_PMADDWD(void); + +void MMX_PMULHW(void); +void MMX_PMULLW(void); + +void MMX_PSLLW(void); +void MMX_PSLLD(void); +void MMX_PSLLQ(void); + +void MMX_PSRAW(void); +void MMX_PSRAD(void); + +void MMX_PSRLW(void); +void MMX_PSRLD(void); +void MMX_PSRLQ(void); + +void MMX_PSxxW_imm8(void); +void MMX_PSxxD_imm8(void); +void MMX_PSxxQ_imm8(void); + +void MMX_PSUBB(void); +void MMX_PSUBW(void); +void MMX_PSUBD(void); + +void MMX_PSUBSB(void); +void MMX_PSUBSW(void); + +void MMX_PSUBUSB(void); +void MMX_PSUBUSW(void); + +void MMX_PUNPCKHBW(void); +void MMX_PUNPCKHWD(void); +void MMX_PUNPCKHDQ(void); +void MMX_PUNPCKLBW(void); +void MMX_PUNPCKLWD(void); +void MMX_PUNPCKLDQ(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_MMX_MMX_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx2.txt b/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx2.txt new file mode 100644 index 000000000..6d362cb41 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/mmx/mmx2.txt @@ -0,0 +1,2091 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "compiler.h" + +#include "ia32/cpu.h" +#include "ia32/ia32.mcr" + +#include "ia32/instructions/mmx/mmx.h" + +#if defined(USE_MMX) && defined(USE_FPU) + +#define CPU_MMXWORKCLOCK CPU_WORKCLOCK(6) + +static INLINE void +MMX_check_NM_EXCEPTION(){ + // MMXなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_MMX)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if (CPU_CR0 & CPU_CR0_TS) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static INLINE void +MMX_setTag(void) +{ + int i; + + if(!FPU_STAT.mmxenable){ + FPU_STAT.mmxenable = 1; + //FPU_CTRLWORD = 0x27F; + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Valid; +#ifdef SUPPORT_FPU_DOSBOX2 + FPU_STAT.int_regvalid[i] = 0; +#endif + FPU_STAT.reg[i].ul.ext = 0xffff; + } + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; +} + +/* + * MMX interface + */ +void +MMX_EMMS(void) +{ + int i; + + // MMXなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_MMX)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if ((CPU_CR0 & (CPU_CR0_TS)) || (CPU_CR0 & CPU_CR0_EM)) { + EXCEPTION(NM_EXCEPTION, 0); + } + + CPU_WORKCLOCK(2); + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Empty; + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; + FPU_STAT.mmxenable = 0; +} + +// *********** MOV + +void MMX_MOVD_mm_rm32(void) +{ + UINT32 op, src; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + (src) = *(reg32_b20[(op)]); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + (src) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + } + FPU_STAT.reg[idx].ul.lower = src; + FPU_STAT.reg[idx].ul.upper = 0; +} +void MMX_MOVD_rm32_mm(void) +{ + UINT32 op, src, madr; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + src = FPU_STAT.reg[idx].ul.lower; + if (op >= 0xc0) { + *(reg32_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } +} + +void MMX_MOVQ_mm_mmm64(void) +{ + UINT32 op; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[idx].ll = FPU_STAT.reg[sub].ll; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + FPU_STAT.reg[idx].ll = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, madr); + //FPU_STAT.reg[idx].ul.lower = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + //FPU_STAT.reg[idx].ul.upper = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr+4); + } +} +void MMX_MOVQ_mmm64_mm(void) +{ + UINT32 op; + UINT idx, sub; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[sub].ll = FPU_STAT.reg[idx].ll; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_q(CPU_INST_SEGREG_INDEX, madr, FPU_STAT.reg[idx].ll); + //cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, FPU_STAT.reg[idx].ul.lower); + //cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+4, FPU_STAT.reg[idx].ul.upper); + } +} + + +// *********** PACK + +void MMX_PACKSSWB(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcreg2buf[4]; + INT16 *srcreg1; + INT16 *srcreg2; + INT8 *dstreg; + INT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&(FPU_STAT.reg[sub])); + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&srcreg2buf); + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + } + for(i=0;i<4;i++){ + if(srcreg1[i] > 127){ + dstregbuf[i] = 127; + }else if(srcreg1[i] < -128){ + dstregbuf[i] = -128; + }else{ + dstregbuf[i] = (INT8)(srcreg1[i]); + } + } + for(i=0;i<4;i++){ + if(srcreg2[i] > 127){ + dstregbuf[i+4] = 127; + }else if(srcreg2[i] < -128){ + dstregbuf[i+4] = -128; + }else{ + dstregbuf[i+4] = (INT8)(srcreg2[i]); + } + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PACKSSDW(void) +{ + UINT32 op; + UINT idx, sub; + INT32 srcreg2buf[2]; + INT32 *srcreg1; + INT32 *srcreg2; + INT16 *dstreg; + INT16 dstregbuf[4]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT32*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT32*)(&(FPU_STAT.reg[sub])); + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT32*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT32*)(&srcreg2buf); + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + } + for(i=0;i<2;i++){ + if(srcreg1[i] > 32767){ + dstregbuf[i] = 32767; + }else if(srcreg1[i] < -32768){ + dstregbuf[i] = -32768; + }else{ + dstregbuf[i] = (INT16)(srcreg1[i]); + } + } + for(i=0;i<2;i++){ + if(srcreg2[i] > 32767){ + dstregbuf[i+2] = 32767; + }else if(srcreg2[i] < -32768){ + dstregbuf[i+2] = -32768; + }else{ + dstregbuf[i+2] = (INT16)(srcreg2[i]); + } + } + for(i=0;i<4;i++){ + dstreg[i] = dstregbuf[i]; + } +} + +void MMX_PACKUSWB(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcreg2buf[4]; + INT16 *srcreg1; + INT16 *srcreg2; + UINT8 *dstreg; + UINT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&(FPU_STAT.reg[sub])); + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT16*)(&(FPU_STAT.reg[idx])); + srcreg2 = (INT16*)(&srcreg2buf); + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + } + for(i=0;i<4;i++){ + if(srcreg1[i] > 255){ + dstregbuf[i] = 255; + }else if(srcreg1[i] < 0){ + dstregbuf[i] = 0; + }else{ + dstregbuf[i] = (UINT8)(srcreg1[i]); + } + } + for(i=0;i<4;i++){ + if(srcreg2[i] > 255){ + dstregbuf[i+4] = 255; + }else if(srcreg2[i] < 0){ + dstregbuf[i+4] = 0; + }else{ + dstregbuf[i+4] = (UINT8)(srcreg2[i]); + } + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} + +// *********** PADD + +void MMX_PADDB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + dstreg[i] += srcreg[i]; + } +} +void MMX_PADDW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] += srcreg[i]; + } +} +void MMX_PADDD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstreg[i] += srcreg[i]; + } +} + +void MMX_PADDSB(void) +{ + UINT32 op; + UINT idx, sub; + INT8 srcregbuf[8]; + INT8 *srcreg; + INT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT8*)(srcregbuf); + } + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + INT16 cbuf = (INT16)dstreg[i] + (INT16)srcreg[i]; + if(cbuf > 127){ + dstreg[i] = 127; + }else if(cbuf < -128){ + dstreg[i] = -128; + }else{ + dstreg[i] = (INT8)cbuf; + } + } +} +void MMX_PADDSW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + INT32 cbuf = (INT32)dstreg[i] + (INT32)srcreg[i]; + if(cbuf > 32767){ + dstreg[i] = 32767; + }else if(cbuf < -32768){ + dstreg[i] = -32768; + }else{ + dstreg[i] = (INT16)cbuf; + } + } +} + +void MMX_PADDUSB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + UINT16 cbuf = (UINT16)dstreg[i] + (UINT16)srcreg[i]; + if(cbuf > 255){ + dstreg[i] = 255; + }else{ + dstreg[i] = (UINT8)cbuf; + } + } +} +void MMX_PADDUSW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + UINT32 cbuf = (UINT32)dstreg[i] + (UINT32)srcreg[i]; + if(cbuf > 65535){ + dstreg[i] = 65535; + }else{ + dstreg[i] = (UINT16)cbuf; + } + } +} + +// *********** PAND/ANDN,OR,XOR + +void MMX_PAND(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstreg[0] = dstreg[0] & srcreg[0]; + dstreg[1] = dstreg[1] & srcreg[1]; +} +void MMX_PANDN(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + //dstreg[0] = ~(dstreg[0] & srcreg[0]); + //dstreg[1] = ~(dstreg[1] & srcreg[1]); + dstreg[0] = (~dstreg[0]) & srcreg[0]; + dstreg[1] = (~dstreg[1]) & srcreg[1]; +} +void MMX_POR(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstreg[0] = dstreg[0] | srcreg[0]; + dstreg[1] = dstreg[1] | srcreg[1]; +} +void MMX_PXOR(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstreg[0] = dstreg[0] ^ srcreg[0]; + dstreg[1] = dstreg[1] ^ srcreg[1]; +} + +// *********** PCMPEQ + +void MMX_PCMPEQB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + if(dstreg[i] == srcreg[i]){ + dstreg[i] = 0xff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPEQW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + if(dstreg[i] == srcreg[i]){ + dstreg[i] = 0xffff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPEQD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + if(dstreg[i] == srcreg[i]){ + dstreg[i] = 0xffffffff; + }else{ + dstreg[i] = 0; + } + } +} + +// *********** PCMPGT + +void MMX_PCMPGTB(void) +{ + UINT32 op; + UINT idx, sub; + INT8 srcregbuf[8]; + INT8 *srcreg; + INT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT8*)(srcregbuf); + } + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + if(dstreg[i] > srcreg[i]){ + dstreg[i] = 0xff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPGTW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + if(dstreg[i] > srcreg[i]){ + dstreg[i] = 0xffff; + }else{ + dstreg[i] = 0; + } + } +} +void MMX_PCMPGTD(void) +{ + UINT32 op; + UINT idx, sub; + INT32 srcregbuf[2]; + INT32 *srcreg; + INT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT32*)(srcregbuf); + } + dstreg = (INT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + if(dstreg[i] > srcreg[i]){ + dstreg[i] = 0xffffffff; + }else{ + dstreg[i] = 0; + } + } +} + +// *********** PMADDWD +void MMX_PMADDWD(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + INT32 *dstreg32; + INT32 dstregbuf[2]; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + dstreg32 = (INT32*)(&(FPU_STAT.reg[idx])); + + dstregbuf[0] = (INT32)srcreg[0] * (INT32)dstreg[0] + (INT32)srcreg[1] * (INT32)dstreg[1]; + dstregbuf[1] = (INT32)srcreg[2] * (INT32)dstreg[2] + (INT32)srcreg[3] * (INT32)dstreg[3]; + dstreg32[0] = dstregbuf[0]; + dstreg32[1] = dstregbuf[1]; +} + +// *********** PMUL +void MMX_PMULHW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] = (INT16)((((INT32)srcreg[i] * (INT32)dstreg[i]) >> 16) & 0xffff); + } +} +void MMX_PMULLW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] = (INT16)((((INT32)srcreg[i] * (INT32)dstreg[i])) & 0xffff); + } +} + +// *********** PSLL +void MMX_PSLLW(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + //dstreg[i] = (dstreg[i] << shift); + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] << (UINT16)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSLLD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + //dstreg[i] = (dstreg[i] << shift); + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] << (UINT32)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSLLQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT64 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT64*)(&(FPU_STAT.reg[idx])); + + //dstreg[0] = (dstreg[0] << shift); + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] << (UINT64)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) +} + +// *********** PSRA + +void MMX_PSRAW(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + UINT16 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + // 無理やり算術シフト(怪しい) + if(16 <= shift){ + signval = 0xffff; + }else{ + UINT32 rshift = 16 - shift; + signval = (0xffff >> rshift) << rshift; + } + for(i=0;i<4;i++){ + if(((INT16*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } +} +void MMX_PSRAD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + UINT32 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + // 無理やり算術シフト(怪しい) + if(32 <= shift){ + signval = 0xffffffff; + }else{ + UINT32 rshift = 32 - shift; + signval = (0xffffffff >> rshift) << rshift; + } + for(i=0;i<2;i++){ + if(((INT32*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } +} + +// *********** PSRL +void MMX_PSRLW(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + //dstreg[i] = (dstreg[i] >> shift); + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSRLD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + //dstreg[i] = (dstreg[i] >> shift); + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } +} +void MMX_PSRLQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT64 *dstreg; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + shift = FPU_STAT.reg[sub].ul.lower; + if(FPU_STAT.reg[sub].ul.upper) shift = 0xffffffff; // XXX: シフトしすぎ + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + shift = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + if(cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4)) shift = 0xffffffff; // XXX: シフトしすぎ + } + dstreg = (UINT64*)(&(FPU_STAT.reg[idx])); + + //dstreg[0] = (dstreg[0] >> shift); + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] >> (UINT64)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) +} + +// *********** PSLL(imm8),PSRL(imm8),PSRA(imm8) +void MMX_PSxxW_imm8(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + UINT16 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT16*)(&(FPU_STAT.reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLW(imm8) + for(i=0;i<4;i++){ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[0] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + break; + case 4: // PSRAW(imm8) + // 無理やり算術シフト(怪しい) + if(16 <= shift){ + signval = 0xffff; + }else{ + UINT32 rshift = 16 - shift; + signval = (0xffff >> rshift) << rshift; + } + for(i=0;i<4;i++){ + if(((INT16*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[0] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + break; + case 6: // PSLLW(imm8) + for(i=0;i<4;i++){ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[0] << (UINT16)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + break; + default: + break; + } +} +void MMX_PSxxD_imm8(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + UINT32 signval; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT32*)(&(FPU_STAT.reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLD(imm8) + for(i=0;i<2;i++){ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[0] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + break; + case 4: // PSRAD(imm8) + // 無理やり算術シフト(怪しい) + if(32 <= shift){ + signval = 0xffffffff; + }else{ + UINT32 rshift = 32 - shift; + signval = (0xffffffff >> rshift) << rshift; + } + for(i=0;i<2;i++){ + if(((INT32*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[0] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + break; + case 6: // PSLLD(imm8) + for(i=0;i<2;i++){ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[0] << (UINT32)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + break; + default: + break; + } +} +void MMX_PSxxQ_imm8(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT64 *dstreg; + UINT32 signval; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT64*)(&(FPU_STAT.reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLQ(imm8) + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] >> (UINT64)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + break; + case 4: // PSRAQ(imm8) + EXCEPTION(UD_EXCEPTION, 0); + break; + case 6: // PSLLQ(imm8) + dstreg[0] = (shift >= 64 ? 0 : (dstreg[0] << (UINT64)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + break; + default: + break; + } +} + +// *********** PSUB + +void MMX_PSUBB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + dstreg[i] -= srcreg[i]; + } +} +void MMX_PSUBW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstreg[i] -= srcreg[i]; + } +} +void MMX_PSUBD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstreg[i] -= srcreg[i]; + } +} + +void MMX_PSUBSB(void) +{ + UINT32 op; + UINT idx, sub; + INT8 srcregbuf[8]; + INT8 *srcreg; + INT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT8*)(srcregbuf); + } + dstreg = (INT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + INT16 cbuf = (INT16)dstreg[i] - (INT16)srcreg[i]; + if(cbuf > 127){ + dstreg[i] = 127; + }else if(cbuf < -128){ + dstreg[i] = -128; + }else{ + dstreg[i] = (INT8)cbuf; + } + } +} +void MMX_PSUBSW(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcregbuf[4]; + INT16 *srcreg; + INT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (INT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (INT16*)(srcregbuf); + } + dstreg = (INT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + INT32 cbuf = (INT32)dstreg[i] - (INT32)srcreg[i]; + if(cbuf > 32767){ + dstreg[i] = 32767; + }else if(cbuf < -32768){ + dstreg[i] = -32768; + }else{ + dstreg[i] = (INT16)cbuf; + } + } +} + +void MMX_PSUBUSB(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<8;i++){ + INT16 cbuf = (INT16)dstreg[i] - (INT16)srcreg[i]; + if(cbuf > 255){ + dstreg[i] = 255; + }else if(cbuf < 0){ + dstreg[i] = 0; + }else{ + dstreg[i] = (UINT8)cbuf; + } + } +} +void MMX_PSUBUSW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + INT32 cbuf = (INT32)dstreg[i] - (INT32)srcreg[i]; + if(cbuf > 65535){ + dstreg[i] = 65535; + }else if(cbuf < 0){ + dstreg[i] = 0; + }else{ + dstreg[i] = (UINT16)cbuf; + } + } +} + +// *********** PUNPCK + +void MMX_PUNPCKHBW(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + UINT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstregbuf[i*2] = dstreg[i+4]; + dstregbuf[i*2 + 1] = srcreg[i+4]; + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKHWD(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + UINT16 dstregbuf[4]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstregbuf[i*2] = dstreg[i+2]; + dstregbuf[i*2 + 1] = srcreg[i+2]; + } + for(i=0;i<4;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKHDQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + UINT32 dstregbuf[2]; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstregbuf[0] = dstreg[1]; + dstregbuf[1] = srcreg[1]; + dstreg[0] = dstregbuf[0]; + dstreg[1] = dstregbuf[1]; +} +void MMX_PUNPCKLBW(void) +{ + UINT32 op; + UINT idx, sub; + UINT8 srcregbuf[8]; + UINT8 *srcreg; + UINT8 *dstreg; + UINT8 dstregbuf[8]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT8*)(srcregbuf); + } + dstreg = (UINT8*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<4;i++){ + dstregbuf[i*2] = dstreg[i]; + dstregbuf[i*2 + 1] = srcreg[i]; + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKLWD(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 srcregbuf[4]; + UINT16 *srcreg; + UINT16 *dstreg; + UINT16 dstregbuf[4]; + int i; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT16*)(srcregbuf); + } + dstreg = (UINT16*)(&(FPU_STAT.reg[idx])); + + for(i=0;i<2;i++){ + dstregbuf[i*2] = dstreg[i]; + dstregbuf[i*2 + 1] = srcreg[i]; + } + for(i=0;i<4;i++){ + dstreg[i] = dstregbuf[i]; + } +} +void MMX_PUNPCKLDQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 srcregbuf[2]; + UINT32 *srcreg; + UINT32 *dstreg; + UINT32 dstregbuf[2]; + + MMX_check_NM_EXCEPTION(); + MMX_setTag(); + CPU_MMXWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg = (UINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcregbuf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcregbuf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg = (UINT32*)(srcregbuf); + } + dstreg = (UINT32*)(&(FPU_STAT.reg[idx])); + + dstregbuf[0] = dstreg[0]; + dstregbuf[1] = srcreg[0]; + dstreg[0] = dstregbuf[0]; + dstreg[1] = dstregbuf[1]; +} + +#else + +/* + * MMX interface + */ +void +MMX_EMMS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_MOVD_mm_rm32(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_MOVD_rm32_mm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_MOVQ_mm_mmm64(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_MOVQ_mmm64_mm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PACKSSWB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PACKSSDW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PACKUSWB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PADDB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PADDSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PADDUSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PADDUSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PAND(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PANDN(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_POR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PXOR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PCMPEQB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPEQW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPEQD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PCMPGTB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPGTW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PCMPGTD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PMADDWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PMULHW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PMULLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSLLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSLLD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSLLQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSRAW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSRAD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSRLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSRLD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSRLQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSxxW_imm8(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSxxD_imm8(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSxxQ_imm8(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSUBB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSUBSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PSUBUSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PSUBUSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void MMX_PUNPCKHBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKHWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKHDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKLBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKLWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void MMX_PUNPCKLDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/seg_reg.cpp b/source/src/vm/np21/i386c/ia32/instructions/seg_reg.cpp new file mode 100644 index 000000000..8450c1c5c --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/seg_reg.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "seg_reg.h" + + +void +LES_GwMp(void) +{ + UINT16 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + LOAD_SEGREG(CPU_ES_INDEX, sreg); + *out = (UINT16)dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LES_GdMp(void) +{ + UINT32 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + LOAD_SEGREG(CPU_ES_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSS_GwMp(void) +{ + UINT16 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + LOAD_SEGREG(CPU_SS_INDEX, sreg); + *out = (UINT16)dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSS_GdMp(void) +{ + UINT32 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + LOAD_SEGREG(CPU_SS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LDS_GwMp(void) +{ + UINT16 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + LOAD_SEGREG(CPU_DS_INDEX, sreg); + *out = (UINT16)dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LDS_GdMp(void) +{ + UINT32 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + LOAD_SEGREG(CPU_DS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LFS_GwMp(void) +{ + UINT16 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + LOAD_SEGREG(CPU_FS_INDEX, sreg); + *out = (UINT16)dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LFS_GdMp(void) +{ + UINT32 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + LOAD_SEGREG(CPU_FS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LGS_GwMp(void) +{ + UINT16 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg16_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 2); + LOAD_SEGREG(CPU_GS_INDEX, sreg); + *out = (UINT16)dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LGS_GdMp(void) +{ + UINT32 *out; + UINT32 op, dst, madr; + UINT16 sreg; + + GET_PCBYTE(op); + if (op < 0xc0) { + out = reg32_b53[op]; + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr); + sreg = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr + 4); + LOAD_SEGREG(CPU_GS_INDEX, sreg); + *out = dst; + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/seg_reg.h b/source/src/vm/np21/i386c/ia32/instructions/seg_reg.h new file mode 100644 index 000000000..d7e6add0c --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/seg_reg.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SEG_REG_H__ +#define IA32_CPU_INSTRUCTION_SEG_REG_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void LES_GwMp(void); +void LES_GdMp(void); +void LSS_GwMp(void); +void LSS_GdMp(void); +void LDS_GwMp(void); +void LDS_GdMp(void); +void LFS_GwMp(void); +void LFS_GdMp(void); +void LGS_GwMp(void); +void LGS_GdMp(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_SEG_REG_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.cpp b/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.cpp new file mode 100644 index 000000000..8d9e65c36 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "shift_rotate.h" +#include "shift_rotate.mcr" + + +/* + * shift + */ +SHIFT_ROTATE_INSTRUCTION(SAR) +SHIFT_ROTATE_INSTRUCTION(SHR) +SHIFT_ROTATE_INSTRUCTION(SHL) +SHxD_INSTRUCTION(SHRD) +SHxD_INSTRUCTION(SHLD) + + +/* + * rotate + */ +SHIFT_ROTATE_INSTRUCTION(ROR) +SHIFT_ROTATE_INSTRUCTION(ROL) +SHIFT_ROTATE_INSTRUCTION(RCR) +SHIFT_ROTATE_INSTRUCTION(RCL) diff --git a/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.h b/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.h new file mode 100644 index 000000000..84534c39a --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SHIFT_ROTATE_H__ +#define IA32_CPU_INSTRUCTION_SHIFT_ROTATE_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * SAR + */ +void CPUCALL SAR_Eb(UINT8 *); +void CPUCALL SAR_Ew(UINT16 *); +void CPUCALL SAR_Ed(UINT32 *); +void CPUCALL SAR_Eb_ext(UINT32); +void CPUCALL SAR_Ew_ext(UINT32); +void CPUCALL SAR_Ed_ext(UINT32); +void CPUCALL SAR_EbCL(UINT8 *, UINT32); +void CPUCALL SAR_EbCL_ext(UINT32, UINT32); +void CPUCALL SAR_EwCL(UINT16 *, UINT32); +void CPUCALL SAR_EwCL_ext(UINT32, UINT32); +void CPUCALL SAR_EdCL(UINT32 *, UINT32); +void CPUCALL SAR_EdCL_ext(UINT32, UINT32); + +/* + * SHR + */ +void CPUCALL SHR_Eb(UINT8 *); +void CPUCALL SHR_Ew(UINT16 *); +void CPUCALL SHR_Ed(UINT32 *); +void CPUCALL SHR_Eb_ext(UINT32); +void CPUCALL SHR_Ew_ext(UINT32); +void CPUCALL SHR_Ed_ext(UINT32); +void CPUCALL SHR_EbCL(UINT8 *, UINT32); +void CPUCALL SHR_EbCL_ext(UINT32, UINT32); +void CPUCALL SHR_EwCL(UINT16 *, UINT32); +void CPUCALL SHR_EwCL_ext(UINT32, UINT32); +void CPUCALL SHR_EdCL(UINT32 *, UINT32); +void CPUCALL SHR_EdCL_ext(UINT32, UINT32); + +/* + * SHL + */ +void CPUCALL SHL_Eb(UINT8 *); +void CPUCALL SHL_Ew(UINT16 *); +void CPUCALL SHL_Ed(UINT32 *); +void CPUCALL SHL_Eb_ext(UINT32); +void CPUCALL SHL_Ew_ext(UINT32); +void CPUCALL SHL_Ed_ext(UINT32); +void CPUCALL SHL_EbCL(UINT8 *, UINT32); +void CPUCALL SHL_EbCL_ext(UINT32, UINT32); +void CPUCALL SHL_EwCL(UINT16 *, UINT32); +void CPUCALL SHL_EwCL_ext(UINT32, UINT32); +void CPUCALL SHL_EdCL(UINT32 *, UINT32); +void CPUCALL SHL_EdCL_ext(UINT32, UINT32); + +/* + * SHRD + */ +void SHRD_EwGwIb(void); +void SHRD_EdGdIb(void); +void SHRD_EwGwCL(void); +void SHRD_EdGdCL(void); + +/* + * SHLD + */ +void SHLD_EwGwIb(void); +void SHLD_EdGdIb(void); +void SHLD_EwGwCL(void); +void SHLD_EdGdCL(void); + +/* + * ROR + */ +void CPUCALL ROR_Eb(UINT8 *); +void CPUCALL ROR_Ew(UINT16 *); +void CPUCALL ROR_Ed(UINT32 *); +void CPUCALL ROR_Eb_ext(UINT32); +void CPUCALL ROR_Ew_ext(UINT32); +void CPUCALL ROR_Ed_ext(UINT32); +void CPUCALL ROR_EbCL(UINT8 *, UINT32); +void CPUCALL ROR_EbCL_ext(UINT32, UINT32); +void CPUCALL ROR_EwCL(UINT16 *, UINT32); +void CPUCALL ROR_EwCL_ext(UINT32, UINT32); +void CPUCALL ROR_EdCL(UINT32 *, UINT32); +void CPUCALL ROR_EdCL_ext(UINT32, UINT32); + +/* + * ROL + */ +void CPUCALL ROL_Eb(UINT8 *); +void CPUCALL ROL_Ew(UINT16 *); +void CPUCALL ROL_Ed(UINT32 *); +void CPUCALL ROL_Eb_ext(UINT32); +void CPUCALL ROL_Ew_ext(UINT32); +void CPUCALL ROL_Ed_ext(UINT32); +void CPUCALL ROL_EbCL(UINT8 *, UINT32); +void CPUCALL ROL_EbCL_ext(UINT32, UINT32); +void CPUCALL ROL_EwCL(UINT16 *, UINT32); +void CPUCALL ROL_EwCL_ext(UINT32, UINT32); +void CPUCALL ROL_EdCL(UINT32 *, UINT32); +void CPUCALL ROL_EdCL_ext(UINT32, UINT32); + +/* + * RCR + */ +void CPUCALL RCR_Eb(UINT8 *); +void CPUCALL RCR_Ew(UINT16 *); +void CPUCALL RCR_Ed(UINT32 *); +void CPUCALL RCR_Eb_ext(UINT32); +void CPUCALL RCR_Ew_ext(UINT32); +void CPUCALL RCR_Ed_ext(UINT32); +void CPUCALL RCR_EbCL(UINT8 *, UINT32); +void CPUCALL RCR_EbCL_ext(UINT32, UINT32); +void CPUCALL RCR_EwCL(UINT16 *, UINT32); +void CPUCALL RCR_EwCL_ext(UINT32, UINT32); +void CPUCALL RCR_EdCL(UINT32 *, UINT32); +void CPUCALL RCR_EdCL_ext(UINT32, UINT32); + +/* + * RCL + */ +void CPUCALL RCL_Eb(UINT8 *); +void CPUCALL RCL_Ew(UINT16 *); +void CPUCALL RCL_Ed(UINT32 *); +void CPUCALL RCL_Eb_ext(UINT32); +void CPUCALL RCL_Ew_ext(UINT32); +void CPUCALL RCL_Ed_ext(UINT32); +void CPUCALL RCL_EbCL(UINT8 *, UINT32); +void CPUCALL RCL_EbCL_ext(UINT32, UINT32); +void CPUCALL RCL_EwCL(UINT16 *, UINT32); +void CPUCALL RCL_EwCL_ext(UINT32, UINT32); +void CPUCALL RCL_EdCL(UINT32 *, UINT32); +void CPUCALL RCL_EdCL_ext(UINT32, UINT32); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_SHIFT_ROTATE_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.mcr b/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.mcr new file mode 100644 index 000000000..25b82b314 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/shift_rotate.mcr @@ -0,0 +1,1081 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_SHIFT_ROTATE_MCR__ +#define IA32_CPU_SHIFT_ROTATE_MCR__ + +/* + * shift/rorate instruction macro + */ +#define SHIFT_ROTATE_INSTRUCTION(inst) \ +static UINT32 CPUCALL \ +inst##1(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + BYTE_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##2(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + WORD_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##4(UINT32 src, void *arg) \ +{ \ + UINT32 dst; \ + DWORD_##inst##1(dst, src); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##CL1(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + BYTE_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##CL2(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + WORD_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##CL4(UINT32 src, void *arg) \ +{ \ + UINT32 cl = PTR_TO_UINT32(arg); \ + UINT32 dst; \ + DWORD_##inst##CL(dst, src, cl); \ + return dst; \ +} \ +\ +void CPUCALL \ +inst##_Eb(UINT8 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + BYTE_##inst##1(dst, src); \ + *out = (UINT8)dst; \ +} \ +\ +void CPUCALL \ +inst##_Eb_ext(UINT32 madr) \ +{ \ +\ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##1, 0); \ +} \ +\ +void CPUCALL \ +inst##_Ew(UINT16 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + WORD_##inst##1(dst, src); \ + *out = (UINT16)dst; \ +} \ +\ +void CPUCALL \ +inst##_Ew_ext(UINT32 madr) \ +{ \ +\ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, 0); \ +} \ +\ +void CPUCALL \ +inst##_Ed(UINT32 *out) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + DWORD_##inst##1(dst, src); \ + *out = dst; \ +} \ +\ +void CPUCALL \ +inst##_Ed_ext(UINT32 madr) \ +{ \ +\ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, 0); \ +} \ +\ +/* ExCL, ExIb */ \ +void CPUCALL \ +inst##_EbCL(UINT8 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + BYTE_##inst##CL(dst, src, cl); \ + *out = (UINT8)dst; \ +} \ +\ +void CPUCALL \ +inst##_EbCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_vmemory_RMW_b(CPU_INST_SEGREG_INDEX, madr, inst##CL1, UINT32_TO_PTR(cl)); \ +} \ +\ +void CPUCALL \ +inst##_EwCL(UINT16 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + WORD_##inst##CL(dst, src, cl); \ + *out = (UINT16)dst; \ +} \ +\ +void CPUCALL \ +inst##_EwCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##CL2, UINT32_TO_PTR(cl)); \ +} \ +\ +void CPUCALL \ +inst##_EdCL(UINT32 *out, UINT32 cl) \ +{ \ + UINT32 src, dst; \ +\ + src = *out; \ + DWORD_##inst##CL(dst, src, cl); \ + *out = dst; \ +} \ +\ +void CPUCALL \ +inst##_EdCL_ext(UINT32 madr, UINT32 cl) \ +{ \ +\ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##CL4, UINT32_TO_PTR(cl)); \ +} + +/* + * shift double-words instructions + */ +struct SHxD_arg { + UINT32 src; + UINT32 cl; +}; + +#define SHxD_INSTRUCTION(inst) \ +static UINT32 CPUCALL \ +inst##2(UINT32 dst, void *arg) \ +{ \ + struct SHxD_arg *p = (struct SHxD_arg *)arg; \ + UINT32 src = p->src; \ + UINT32 cl = p->cl; \ + WORD_##inst(dst, src, cl); \ + return dst; \ +} \ +static UINT32 CPUCALL \ +inst##4(UINT32 dst, void *arg) \ +{ \ + struct SHxD_arg *p = (struct SHxD_arg *)arg; \ + UINT32 src = p->src; \ + UINT32 cl = p->cl; \ + DWORD_##inst(dst, src, cl); \ + return dst; \ +} \ +\ +void \ +inst##_EwGwIb(void) \ +{ \ + struct SHxD_arg arg; \ + UINT16 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG16(op, arg.src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + GET_PCBYTE(arg.cl); \ + out = reg16_b20[op]; \ + dst = *out; \ + WORD_##inst(dst, arg.src, arg.cl); \ + *out = (UINT16)dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + GET_PCBYTE(arg.cl); \ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, &arg); \ + } \ +} \ +\ +void \ +inst##_EdGdIb(void) \ +{ \ + struct SHxD_arg arg; \ + UINT32 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG32(op, arg.src); \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + GET_PCBYTE(arg.cl); \ + out = reg32_b20[op]; \ + dst = *out; \ + DWORD_##inst(dst, arg.src, arg.cl); \ + *out = dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + GET_PCBYTE(arg.cl); \ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, &arg); \ + } \ +} \ +\ +void \ +inst##_EwGwCL(void) \ +{ \ + struct SHxD_arg arg; \ + UINT16 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG16(op, arg.src); \ + arg.cl = CPU_CL; \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + out = reg16_b20[op]; \ + dst = *out; \ + WORD_##inst(dst, arg.src, arg.cl); \ + *out = (UINT16)dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_w(CPU_INST_SEGREG_INDEX, madr, inst##2, (void *)&arg); \ + } \ +} \ +\ +void \ +inst##_EdGdCL(void) \ +{ \ + struct SHxD_arg arg; \ + UINT32 *out; \ + UINT32 op, dst, madr; \ +\ + PREPART_EA_REG32(op, arg.src); \ + arg.cl = CPU_CL; \ + if (op >= 0xc0) { \ + CPU_WORKCLOCK(3); \ + out = reg32_b20[op]; \ + dst = *out; \ + DWORD_##inst(dst, arg.src, arg.cl); \ + *out = dst; \ + } else { \ + CPU_WORKCLOCK(7); \ + madr = calc_ea_dst(op); \ + cpu_vmemory_RMW_d(CPU_INST_SEGREG_INDEX, madr, inst##4, (void *)&arg); \ + } \ +} + + +/* Pentium!!! - シフトカウント != 1の場合はOVは不変らすい */ + +/* + * SAR + */ +#define _BYTE_SAR1(d, s) \ +do { \ + (d) = (UINT8)(((SINT8)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL = (UINT8)(szpcflag[(UINT8)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SAR1(d, s) \ +do { \ + (d) = (UINT16)(((SINT16)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL = (UINT8)(szpflag_w[(UINT16)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SAR1(d, s) \ +do { \ + (d) = (UINT32)(((SINT32)(s)) >> 1); \ + CPU_OV = 0; \ + CPU_FLAGL = (UINT8)(A_FLAG | ((s) & 1)); /* C_FLAG */ \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(UINT8)(d)] & P_FLAG); \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SARCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) = ((SINT8)(s)) >> (c); \ + } else { \ + CPU_OV = 0; \ + } \ + CPU_FLAGL = (UINT8)((s) & 1); /* C_FLAG */ \ + (s) = (UINT8)(((SINT8)(s)) >> 1); \ + CPU_FLAGL |= (szpcflag[(UINT8)(s)] | A_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SARCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) = ((SINT16)(s)) >> (c); \ + } else { \ + CPU_OV = 0; \ + } \ + CPU_FLAGL = (UINT8)((s) & 1); /* C_FLAG */ \ + (s) = (UINT16)(((SINT16)(s)) >> 1); \ + CPU_FLAGL |= szpflag_w[(UINT16)(s)]; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SARCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) = ((SINT32)(s)) >> (c); \ + } else { \ + CPU_OV = 0; \ + } \ + CPU_FLAGL = (UINT8)((s) & 1); /* C_FLAG */ \ + (s) = (UINT32)(((SINT32)(s)) >> 1); \ + if ((s) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else if ((s) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(UINT8)(s)] & P_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * SHR + */ +#define _BYTE_SHR1(d, s) \ +do { \ + (d) = (s) >> 1; \ + CPU_OV = (s) & 0x80; \ + CPU_FLAGL = (UINT8)(szpcflag[(UINT8)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHR1(d, s) \ +do { \ + (d) = (s) >> 1; \ + CPU_OV = (s) & 0x8000; \ + CPU_FLAGL = (UINT8)(szpflag_w[(UINT16)(d)] | A_FLAG | ((s) & 1)); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHR1(d, s) \ +do { \ + (d) = (s) >> 1; \ + CPU_OV = (s) & 0x80000000; \ + CPU_FLAGL = (UINT8)(A_FLAG | ((s) & 1)); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(UINT8)(d)] & P_FLAG); \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SHRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) >>= (c); \ + } else { \ + CPU_OV = (s) & 0x80; \ + } \ + CPU_FLAGL = (UINT8)((s) & 1); \ + (s) >>= 1; \ + CPU_FLAGL |= (szpcflag[(UINT8)(s)] | A_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) >>= (c); \ + } else { \ + CPU_OV = (s) & 0x8000; \ + } \ + CPU_FLAGL = (UINT8)((s) & 1); \ + (s) >>= 1; \ + CPU_FLAGL |= szpflag_w[(UINT16)(s)]; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) >>= (c); \ + } else { \ + CPU_OV = (s) & 0x80000000; \ + } \ + CPU_FLAGL = (UINT8)((s) & 1); \ + (s) >>= 1; \ + if ((s) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(UINT8)(s)] & P_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * SHL + */ +#define _BYTE_SHL1(d, s) \ +do { \ + (d) = (s) << 1; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ + CPU_FLAGL = (UINT8)(szpcflag[(d) & 0x1ff] | A_FLAG); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHL1(d, s) \ +do { \ + (d) = (s) << 1; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ + CPU_FLAGL = (UINT8)(szpflag_w[(UINT16)(d)] | A_FLAG | ((d) >> 16)); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHL1(d, s) \ +do { \ + (d) = (s) << 1; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ + CPU_FLAGL = (UINT8)(A_FLAG | (szpcflag[(UINT8)(d)] & P_FLAG)); \ + if ((s) & 0x80000000) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_SHLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x40) & 0x80; \ + } \ + (s) <<= (c); \ + (s) &= 0x1ff; \ + CPU_FLAGL = (UINT8)(szpcflag[(s) & 0x1ff] | A_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_SHLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x4000) & 0x8000; \ + } \ + (s) <<= (c); \ + (s) &= 0x1ffff; \ + CPU_FLAGL = (UINT8)(szpflag_w[(UINT16)(s)] | A_FLAG); \ + CPU_FLAGL |= (UINT8)((s) >> 16); /* C_FLAG */ \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c)--; \ + if ((c)) { \ + (s) <<= (c); \ + } else { \ + CPU_OV = ((s) + 0x40000000) & 0x80000000; \ + } \ + CPU_FLAGL = A_FLAG; \ + if ((s) & 0x80000000) { \ + CPU_FLAGL |= C_FLAG; \ + } \ + (s) <<= 1; \ + if ((s) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else if ((s) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(UINT8)(s)] & P_FLAG); \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * SHRD + */ +#define _WORD_SHRD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (((c)) && ((c) < 16)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = (((d) >> 15) ^ (s)) & 1; \ + } \ + CPU_FLAGL = (UINT8)(((d) >> ((c) - 1)) & 1); /*C_FLAG*/ \ + (d) |= (s) << 16; \ + (d) >>= (c); \ + (d) &= 0xffff; \ + CPU_FLAGL |= szpflag_w[(UINT16)(d)] | A_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHRD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = (((d) >> 31) ^ (s)) & 1; \ + } \ + CPU_FLAGL = (UINT8)(((d) >> ((c) - 1)) & 1); /* C_FLAG */ \ + (d) >>= (c); \ + (d) |= (s) << (32 - (c)); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(UINT8)(d)] & P_FLAG); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* + * SHLD + */ +#define _WORD_SHLD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if (((c)) && ((c) < 16)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((d) ^ ((d) << 1)) & 0x8000; \ + } \ + CPU_FLAGL = (UINT8)(((d) >> (16 - (c))) & 1); /*C_FLAG*/\ + (d) = ((d) << 16) | (s); \ + (d) <<= (c); \ + (d) >>= 16; \ + CPU_FLAGL |= szpflag_w[(d)] | A_FLAG; \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_SHLD(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((d) ^ ((d) << 1)) & 0x80000000; \ + } \ + CPU_FLAGL = (UINT8)(((d) >> (32 - (c))) & 1); /* C_FLAG */ \ + (d) <<= (c); \ + (d) |= ((s) >> (32 - (c))); \ + if ((d) == 0) { \ + CPU_FLAGL |= Z_FLAG; \ + } else if ((d) & 0x80000000) { \ + CPU_FLAGL |= S_FLAG; \ + } \ + CPU_FLAGL |= (szpcflag[(UINT8)(d)] & P_FLAG); \ + } \ +} while (/*CONSTCOND*/ 0) + +/* + * ROR + */ +#define _BYTE_ROR1(d, s) \ +do { \ + UINT32 tmp = (s) & 1; \ + (d) = (tmp << 7) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_ROR1(d, s) \ +do { \ + UINT32 tmp = (s) & 1; \ + (d) = (tmp << 15) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_ROR1(d, s) \ +do { \ + UINT32 tmp = (s) & 1; \ + (d) = (tmp << 31) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_RORCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c) = ((c) - 1) & 7; \ + if ((c)) { \ + (s) = ((s) >> (c)) | ((s) << (8 - (c))); \ + (s) &= 0xff; \ + } \ + _BYTE_ROR1(d, s); \ + } else { \ + (d) = (s); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RORCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp; \ + (c)--; \ + if ((c)) { \ + (c) &= 0x0f; \ + (s) = ((s) >> (c)) | ((s) << (16 - (c))); \ + (s) &= 0xffff; \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) >> 15) ^ ((s) & 1); \ + } \ + tmp = (s) & 1; \ + (s) = (tmp << 15) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RORCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp; \ + (c)--; \ + if ((c)) { \ + (s) = ((s) >> (c)) | ((s) << (32 - (c))); \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) >> 31) ^ ((s) & 1); \ + } \ + tmp = (s) & 1; \ + (s) = (tmp << 31) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * ROL + */ +#define _BYTE_ROL1(d, s) \ +do { \ + UINT32 tmp = (s) >> 7; /* C_FLAG */ \ + (d) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_ROL1(d, s) \ +do { \ + UINT32 tmp = (s) >> 15; /* C_FLAG */ \ + (d) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_ROL1(d, s) \ +do { \ + UINT32 tmp = (s) >> 31; /* C_FLAG */ \ + (d) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_ROLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + (c) = ((c) - 1) & 7; \ + if ((c)) { \ + (s) = ((s) << (c)) | ((s) >> (8 - (c))); \ + (s) &= 0xff; \ + } \ + _BYTE_ROL1(d, s); \ + } else { \ + (d) = (s); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_ROLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp; \ + (c)--; \ + if ((c)) { \ + (c) &= 0x0f; \ + (s) = ((s) << (c)) | ((s) >> (16 - (c))); \ + (s) &= 0xffff; \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) + 0x4000) & 0x8000; \ + } \ + tmp = (s) >> 15; \ + (s) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_ROLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp; \ + (c)--; \ + if ((c)) { \ + (s) = ((s) << (c)) | ((s) >> (32 - (c))); \ + CPU_OV = 0; \ + } else { \ + CPU_OV = ((s) + 0x40000000) & 0x80000000; \ + } \ + tmp = (s) >> 31; \ + (s) = ((s) << 1) + tmp; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * RCR + */ +#define _BYTE_RCR1(d, s) \ +do { \ + (d) = ((CPU_FLAGL & C_FLAG) << 7) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) & 1; \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCR1(d, s) \ +do { \ + (d) = ((CPU_FLAGL & C_FLAG) << 15) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) & 1; \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCR1(d, s) \ +do { \ + (d) = ((CPU_FLAGL & C_FLAG) << 31) + ((s) >> 1); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) & 1; \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_RCRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + while ((c)--) { \ + (s) |= (tmp << 8); \ + tmp = (s) & 1; \ + (s) >>= 1; \ + } \ + CPU_OV = ((s) ^ ((s) >> 1)) & 0x40; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) >> 15) ^ tmp; \ + } \ + while ((c)--) { \ + (s) |= (tmp << 16); \ + tmp = (s) & 1; \ + (s) >>= 1; \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCRCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) >> 31) ^ tmp; \ + } \ + while ((c)--) { \ + UINT32 tmp2 = (s) & 1; \ + (s) = (tmp << 31) | ((s) >> 1); \ + tmp = tmp2; \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +/* + * RCL + */ +#define _BYTE_RCL1(d, s) \ +do { \ + (d) = ((s) << 1) | (CPU_FLAGL & C_FLAG); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) >> 7; /* C_FLAG */ \ + CPU_OV = ((s) ^ (d)) & 0x80; \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCL1(d, s) \ +do { \ + (d) = ((s) << 1) | (CPU_FLAGL & C_FLAG); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) >> 15; /* C_FLAG */ \ + CPU_OV = ((s) ^ (d)) & 0x8000; \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCL1(d, s) \ +do { \ + (d) = ((s) << 1) | (CPU_FLAGL & C_FLAG); \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_FLAGL |= (s) >> 31; /* C_FLAG */ \ + CPU_OV = ((s) ^ (d)) & 0x80000000; \ +} while (/*CONSTCOND*/ 0) + +#define _BYTE_RCLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + while ((c)--) { \ + (s) = (((s) << 1) | tmp) & 0x1ff; \ + tmp = (s) >> 8; \ + } \ + CPU_OV = ((s) ^ ((s) >> 1)) & 0x80; \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _WORD_RCLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x4000) & 0x8000; \ + } \ + while ((c)--) { \ + (s) = (((s) << 1) | tmp) & 0x1ffff; \ + tmp = (s) >> 16; \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#define _DWORD_RCLCL(d, s, c) \ +do { \ + (c) &= 0x1f; \ + if ((c)) { \ + UINT32 tmp = CPU_FLAGL & C_FLAG; \ + CPU_FLAGL &= ~C_FLAG; \ + CPU_OV = 0; \ + if ((c) == 1) { \ + CPU_OV = ((s) + 0x40000000) & 0x80000000; \ + } \ + while ((c)--) { \ + UINT32 tmp2 = (s) & 0x80000000; \ + (s) = ((s) << 1) | (tmp & 1); \ + tmp = tmp2 >> 31; \ + } \ + CPU_FLAGL |= tmp; \ + } \ + (d) = (s); \ +} while (/*CONSTCOND*/ 0) + +#if defined(IA32_CROSS_CHECK) && defined(GCC_CPU_ARCH_IA32) + +#include "shift_rotatexc.mcr" + +#define BYTE_SAR1(d, s) XC_BYTE_SAR1(d, s) +#define WORD_SAR1(d, s) XC_WORD_SAR1(d, s) +#define DWORD_SAR1(d, s) XC_DWORD_SAR1(d, s) +#define BYTE_SARCL(d, s, c) XC_BYTE_SARCL(d, s, c) +#define WORD_SARCL(d, s, c) XC_WORD_SARCL(d, s, c) +#define DWORD_SARCL(d, s, c) XC_DWORD_SARCL(d, s, c) +#define BYTE_SHR1(d, s) XC_BYTE_SHR1(d, s) +#define WORD_SHR1(d, s) XC_WORD_SHR1(d, s) +#define DWORD_SHR1(d, s) XC_DWORD_SHR1(d, s) +#define BYTE_SHRCL(d, s, c) XC_BYTE_SHRCL(d, s, c) +#define WORD_SHRCL(d, s, c) XC_WORD_SHRCL(d, s, c) +#define DWORD_SHRCL(d, s, c) XC_DWORD_SHRCL(d, s, c) +#define BYTE_SHL1(d, s) XC_BYTE_SHL1(d, s) +#define WORD_SHL1(d, s) XC_WORD_SHL1(d, s) +#define DWORD_SHL1(d, s) XC_DWORD_SHL1(d, s) +#define BYTE_SHLCL(d, s, c) XC_BYTE_SHLCL(d, s, c) +#define WORD_SHLCL(d, s, c) XC_WORD_SHLCL(d, s, c) +#define DWORD_SHLCL(d, s, c) XC_DWORD_SHLCL(d, s, c) +#define WORD_SHRD(d, s, c) XC_WORD_SHRD(d, s, c) +#define DWORD_SHRD(d, s, c) XC_DWORD_SHRD(d, s, c) +#define WORD_SHLD(d, s, c) XC_WORD_SHLD(d, s, c) +#define DWORD_SHLD(d, s, c) XC_DWORD_SHLD(d, s, c) +#define BYTE_ROR1(d, s) XC_BYTE_ROR1(d, s) +#define WORD_ROR1(d, s) XC_WORD_ROR1(d, s) +#define DWORD_ROR1(d, s) XC_DWORD_ROR1(d, s) +#define BYTE_RORCL(d, s, c) XC_BYTE_RORCL(d, s, c) +#define WORD_RORCL(d, s, c) XC_WORD_RORCL(d, s, c) +#define DWORD_RORCL(d, s, c) XC_DWORD_RORCL(d, s, c) +#define BYTE_ROL1(d, s) XC_BYTE_ROL1(d, s) +#define WORD_ROL1(d, s) XC_WORD_ROL1(d, s) +#define DWORD_ROL1(d, s) XC_DWORD_ROL1(d, s) +#define BYTE_ROLCL(d, s, c) XC_BYTE_ROLCL(d, s, c) +#define WORD_ROLCL(d, s, c) XC_WORD_ROLCL(d, s, c) +#define DWORD_ROLCL(d, s, c) XC_DWORD_ROLCL(d, s, c) +#define BYTE_RCR1(d, s) XC_BYTE_RCR1(d, s) +#define WORD_RCR1(d, s) XC_WORD_RCR1(d, s) +#define DWORD_RCR1(d, s) XC_DWORD_RCR1(d, s) +#define BYTE_RCRCL(d, s, c) XC_BYTE_RCRCL(d, s, c) +#define WORD_RCRCL(d, s, c) XC_WORD_RCRCL(d, s, c) +#define DWORD_RCRCL(d, s, c) XC_DWORD_RCRCL(d, s, c) +#define BYTE_RCL1(d, s) XC_BYTE_RCL1(d, s) +#define WORD_RCL1(d, s) XC_WORD_RCL1(d, s) +#define DWORD_RCL1(d, s) XC_DWORD_RCL1(d, s) +#define BYTE_RCLCL(d, s, c) XC_BYTE_RCLCL(d, s, c) +#define WORD_RCLCL(d, s, c) XC_WORD_RCLCL(d, s, c) +#define DWORD_RCLCL(d, s, c) XC_DWORD_RCLCL(d, s, c) + +#elif defined(IA32_CROSS_CHECK) && defined(_MSC_VER) + +#include "shift_rotatexc_msc.mcr" + +#else /* !(IA32_CROSS_CHECK && GCC_CPU_ARCH_IA32 */ + +#define BYTE_SAR1(d, s) _BYTE_SAR1(d, s) +#define WORD_SAR1(d, s) _WORD_SAR1(d, s) +#define DWORD_SAR1(d, s) _DWORD_SAR1(d, s) +#define BYTE_SARCL(d, s, c) _BYTE_SARCL(d, s, c) +#define WORD_SARCL(d, s, c) _WORD_SARCL(d, s, c) +#define DWORD_SARCL(d, s, c) _DWORD_SARCL(d, s, c) +#define BYTE_SHR1(d, s) _BYTE_SHR1(d, s) +#define WORD_SHR1(d, s) _WORD_SHR1(d, s) +#define DWORD_SHR1(d, s) _DWORD_SHR1(d, s) +#define BYTE_SHRCL(d, s, c) _BYTE_SHRCL(d, s, c) +#define WORD_SHRCL(d, s, c) _WORD_SHRCL(d, s, c) +#define DWORD_SHRCL(d, s, c) _DWORD_SHRCL(d, s, c) +#define BYTE_SHL1(d, s) _BYTE_SHL1(d, s) +#define WORD_SHL1(d, s) _WORD_SHL1(d, s) +#define DWORD_SHL1(d, s) _DWORD_SHL1(d, s) +#define BYTE_SHLCL(d, s, c) _BYTE_SHLCL(d, s, c) +#define WORD_SHLCL(d, s, c) _WORD_SHLCL(d, s, c) +#define DWORD_SHLCL(d, s, c) _DWORD_SHLCL(d, s, c) +#define WORD_SHRD(d, s, c) _WORD_SHRD(d, s, c) +#define DWORD_SHRD(d, s, c) _DWORD_SHRD(d, s, c) +#define WORD_SHLD(d, s, c) _WORD_SHLD(d, s, c) +#define DWORD_SHLD(d, s, c) _DWORD_SHLD(d, s, c) +#define BYTE_ROR1(d, s) _BYTE_ROR1(d, s) +#define WORD_ROR1(d, s) _WORD_ROR1(d, s) +#define DWORD_ROR1(d, s) _DWORD_ROR1(d, s) +#define BYTE_RORCL(d, s, c) _BYTE_RORCL(d, s, c) +#define WORD_RORCL(d, s, c) _WORD_RORCL(d, s, c) +#define DWORD_RORCL(d, s, c) _DWORD_RORCL(d, s, c) +#define BYTE_ROL1(d, s) _BYTE_ROL1(d, s) +#define WORD_ROL1(d, s) _WORD_ROL1(d, s) +#define DWORD_ROL1(d, s) _DWORD_ROL1(d, s) +#define BYTE_ROLCL(d, s, c) _BYTE_ROLCL(d, s, c) +#define WORD_ROLCL(d, s, c) _WORD_ROLCL(d, s, c) +#define DWORD_ROLCL(d, s, c) _DWORD_ROLCL(d, s, c) +#define BYTE_RCR1(d, s) _BYTE_RCR1(d, s) +#define WORD_RCR1(d, s) _WORD_RCR1(d, s) +#define DWORD_RCR1(d, s) _DWORD_RCR1(d, s) +#define BYTE_RCRCL(d, s, c) _BYTE_RCRCL(d, s, c) +#define WORD_RCRCL(d, s, c) _WORD_RCRCL(d, s, c) +#define DWORD_RCRCL(d, s, c) _DWORD_RCRCL(d, s, c) +#define BYTE_RCL1(d, s) _BYTE_RCL1(d, s) +#define WORD_RCL1(d, s) _WORD_RCL1(d, s) +#define DWORD_RCL1(d, s) _DWORD_RCL1(d, s) +#define BYTE_RCLCL(d, s, c) _BYTE_RCLCL(d, s, c) +#define WORD_RCLCL(d, s, c) _WORD_RCLCL(d, s, c) +#define DWORD_RCLCL(d, s, c) _DWORD_RCLCL(d, s, c) + +#endif /* IA32_CROSS_CHECK && GCC_CPU_ARCH_IA32 */ + +#endif /* IA32_CPU_SHIFT_ROTATE_MCR__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/shift_rotatexc.mcr b/source/src/vm/np21/i386c/ia32/instructions/shift_rotatexc.mcr new file mode 100644 index 000000000..70a2ff814 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/shift_rotatexc.mcr @@ -0,0 +1,2143 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SHIFT_ROTATEXC_H__ +#define IA32_CPU_INSTRUCTION_SHIFT_ROTATEXC_H__ + +#define XC_BYTE_SAR1(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_SAR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "sarb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SAR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SAR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SAR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SAR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SAR1(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SAR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "sarw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SAR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_SAR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SAR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SAR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SAR1(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SAR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "sarl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SAR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SAR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SAR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SAR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SARCL(d, s, c) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_SARCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "sarb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_SARCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SARCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_SARCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SARCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SARCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SARCL(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SARCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "sarw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SARCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_SARCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_SARCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SARCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SARCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SARCL(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SARCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "sarl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SARCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SARCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SARCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SARCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SARCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHR1(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_SHR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shrb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SHR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHR1(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SHR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shrw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SHR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHR1(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SHR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shrl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SHR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHRCL(d, s, c) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_SHRCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shrb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_SHRCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHRCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_SHRCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHRCL(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SHRCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shrw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHRCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHRCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHRCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHRCL(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SHRCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shrl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHRCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHRCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHRCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHL1(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_SHL1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shlb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_SHL1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHL1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/0) + +#define XC_WORD_SHL1(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SHL1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shlw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_SHL1: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHL1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHL1(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SHL1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "shll $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_SHL1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHL1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_SHL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_SHLCL(d, s, c) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_SHLCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shlb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_SHLCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_SHLCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_SHLCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_SHLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_BYTE_SHLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHLCL(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SHLCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shlw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHLCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_SHLCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHLCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHLCL(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SHLCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "shll %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHLCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_SHLCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHLCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHRD(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SHRD((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movw %4, %%dx\n\t" \ + "shrdw %%cl, %%dx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHRD: __s = %04x, __d = %04x", \ + __s, __d); \ + ia32_warning("XC_WORD_SHRD: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHRD: __R = %04x, __r = %04x",\ + __R, __r); \ + ia32_warning("XC_WORD_SHRD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHRD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHRD(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SHRD((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movl %4, %%edx\n\t" \ + "shrdl %%cl, %%edx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHRD: __s = %08x, __d = %08x", \ + __s, __d); \ + ia32_warning("XC_DWORD_SHRD: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHRD: __R = %08x, __r = %08x",\ + __R, __r); \ + ia32_warning("XC_DWORD_SHRD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHRD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_SHLD(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __d = (d) & 0xffff; \ + UINT16 __r = __d; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_SHLD((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movw %4, %%dx\n\t" \ + "shldw %%cl, %%dx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_SHLD: __s = %04x, __d = %04x", \ + __s, __d); \ + ia32_warning("XC_WORD_SHLD: __c = %02x", __c); \ + ia32_warning("XC_WORD_SHLD: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_SHLD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_WORD_SHLD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_SHLD(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __d = (d); \ + UINT32 __r = __d; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_SHLD((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "pushl %%edx\n\t" \ + "movb %5, %%cl\n\t" \ + "movl %4, %%edx\n\t" \ + "shldl %%cl, %%edx, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%edx\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__s), "m" (__c) \ + : "eax", "ecx", "edx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & SZPC_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_SHLD: __s = %08x, __d = %08x", \ + __s, __d); \ + ia32_warning("XC_DWORD_SHLD: __c = %02x", __c); \ + ia32_warning("XC_DWORD_SHLD: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_SHLD: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, SZPC_FLAG); \ + ia32_warning("XC_DWORD_SHLD: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & SZPC_FLAG) == 0); \ + assert((__c != 1) || (!CPU_OV == !__o)); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_ROR1(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_ROR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rorb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_ROR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_ROR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_ROR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_ROR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_ROR1(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_ROR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rorw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_ROR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_ROR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_ROR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_ROR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_ROR1(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_ROR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rorl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_ROR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_ROR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_ROR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_ROR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RORCL(d, s, c) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_RORCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rorb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_RORCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RORCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_RORCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RORCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RORCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RORCL(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_RORCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rorw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_RORCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_RORCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_RORCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RORCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RORCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RORCL(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_RORCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rorl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_RORCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RORCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_RORCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RORCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RORCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_ROL1(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_ROL1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rolb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_ROL1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_ROL1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_ROL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_ROL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_ROL1(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_ROL1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "rolw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_ROL1: __s = %04x", __s); \ + ia32_warning("XC_WORD_ROL1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_ROL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_ROL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_ROL1(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_ROL1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "roll $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_ROL1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_ROL1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_ROL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_ROL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_ROLCL(d, s, c) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _BYTE_ROLCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rolb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_ROLCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_ROLCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_ROLCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_ROLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_ROLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_ROLCL(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _WORD_ROLCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "rolw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_ROLCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_ROLCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_ROLCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_ROLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_ROLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_ROLCL(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + \ + _DWORD_ROLCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "roll %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_ROLCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_ROLCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_ROLCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_ROLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_ROLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCR1(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCR1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_RCR1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCR1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCR1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_BYTE_RCR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCR1(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCR1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_RCR1: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCR1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCR1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_WORD_RCR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCR1(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCR1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrl $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_RCR1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCR1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCR1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_DWORD_RCR1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCR1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCRCL(d, s, c) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCRCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_RCRCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCRCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_RCRCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCRCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_BYTE_RCRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCRCL(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCRCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_RCRCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCRCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_RCRCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCRCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_WORD_RCRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCRCL(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCRCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcrl %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_RCRCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCRCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_RCRCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCRCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_DWORD_RCRCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCRCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCL1(d, s) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCL1((d), (s)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclb $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_BYTE_RCL1: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCL1: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCL1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_BYTE_RCL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCL1(d, s) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCL1((d), (s)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclw $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_WORD_RCL1: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCL1: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCL1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_WORD_RCL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCL1(d, s) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCL1((d), (s)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "movzbl %4, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcll $1, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__xc_flagl) \ + : "eax"); \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + (!CPU_OV != !__o)) { \ + ia32_warning("XC_DWORD_RCL1: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCL1: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCL1: __xc_flagl = %02x", __xc_flagl); \ + ia32_warning("XC_DWORD_RCL1: CPU_FLAGL = %02x, __f = %02x, " \ + "mask = %02x", CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCL1: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_BYTE_RCLCL(d, s, c) \ +do { \ + UINT8 __s = (s) & 0xff; \ + UINT8 __r = __s; \ + UINT8 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _BYTE_RCLCL((d), (s), (c)); \ + __R = (d) & 0xff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclb %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_BYTE_RCLCL: __s = %02x", __s); \ + ia32_warning("XC_BYTE_RCLCL: __c = %02x", __c); \ + ia32_warning("XC_BYTE_RCLCL: __R = %02x, __r = %02x", \ + __R, __r); \ + ia32_warning("XC_BYTE_RCLCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_BYTE_RCLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_BYTE_RCLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_WORD_RCLCL(d, s, c) \ +do { \ + UINT16 __s = (s) & 0xffff; \ + UINT16 __r = __s; \ + UINT16 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _WORD_RCLCL((d), (s), (c)); \ + __R = (d) & 0xffff; \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rclw %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_WORD_RCLCL: __s = %04x", __s); \ + ia32_warning("XC_WORD_RCLCL: __c = %02x", __c); \ + ia32_warning("XC_WORD_RCLCL: __R = %04x, __r = %04x", \ + __R, __r); \ + ia32_warning("XC_WORD_RCLCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_WORD_RCLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_WORD_RCLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#define XC_DWORD_RCLCL(d, s, c) \ +do { \ + UINT32 __s = (s); \ + UINT32 __r = __s; \ + UINT32 __R; \ + UINT8 __c = (c) & 0xff; \ + UINT8 __f; \ + UINT8 __o; \ + UINT8 __xc_flagl = CPU_FLAGL; \ + \ + _DWORD_RCLCL((d), (s), (c)); \ + __R = (d); \ + \ + __asm__ __volatile__ ( \ + "pushf\n\t" \ + "pushl %%eax\n\t" \ + "pushl %%ecx\n\t" \ + "movb %4, %%cl\n\t" \ + "movzbl %5, %%eax\n\t" \ + "bt $0, %%eax\n\t" \ + "rcll %%cl, %0\n\t" \ + "lahf\n\t" \ + "movb %%ah, %1\n\t" \ + "seto %%ah\n\t" \ + "movb %%ah, %2\n\t" \ + "popl %%ecx\n\t" \ + "popl %%eax\n\t" \ + "popf\n\t" \ + : "=m" (__r), "=m" (__f), "=m" (__o) \ + : "0" (__r), "m" (__c), "m" (__xc_flagl) \ + : "eax", "ecx"); \ + if (__c != 0) { \ + if ((__R != __r) || \ + (((__f ^ CPU_FLAGL) & C_FLAG) != 0) || \ + ((__c == 1) && (!CPU_OV != !__o))) { \ + ia32_warning("XC_DWORD_RCLCL: __s = %08x", __s); \ + ia32_warning("XC_DWORD_RCLCL: __c = %02x", __c); \ + ia32_warning("XC_DWORD_RCLCL: __R = %08x, __r = %08x", \ + __R, __r); \ + ia32_warning("XC_DWORD_RCLCL: __xc_flagl = %02x", \ + __xc_flagl); \ + ia32_warning("XC_DWORD_RCLCL: CPU_FLAGL = %02x, " \ + "__f = %02x, mask = %02x", \ + CPU_FLAGL, __f, C_FLAG); \ + ia32_warning("XC_DWORD_RCLCL: CPU_OV = %s, __o = %s", \ + CPU_OV ? "OV" : "NV", __o ? "OV" : "NV"); \ + assert(__R == __r); \ + assert(((__f ^ CPU_FLAGL) & C_FLAG) == 0); \ + assert(!CPU_OV == !__o); \ + } \ + } \ +} while (/*CONSTCOND*/ 0) + +#endif /* IA32_CPU_INSTRUCTION_SHIFT_ROTATEXC_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/shift_rotatexc_msc.mcr b/source/src/vm/np21/i386c/ia32/instructions/shift_rotatexc_msc.mcr new file mode 100644 index 000000000..82b8bdb9e --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/shift_rotatexc_msc.mcr @@ -0,0 +1,638 @@ + +// Crosscheck for VC++ + +#define SETFLAGS \ + __asm { cmp CPU_OV, 0 } \ + __asm { setne al } \ + __asm { add al, 7fh } \ + __asm { mov ah, CPU_FLAGL } \ + __asm { sahf } + + + +#define BYTE_SAR1(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { sar _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SAR1(d, s); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sarb1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SAR1(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { sar _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SAR1(d, s); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sarw1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SAR1(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { sar _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SAR1(d, s); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sard1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_SARCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { sar _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SARCL(d, s, c); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sarb(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SARCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { sar _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SARCL(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sarw(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SARCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { sar _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SARCL(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("sard(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_SHL1(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { shl _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SHL1(d, s); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shlb1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SHL1(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { shl _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SHL1(d, s); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shlw1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SHL1(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { shl _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SHL1(d, s); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shld1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_SHLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { shl _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SHLCL(d, s, c); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shlb(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SHLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { shl _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SHLCL(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shlw(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SHLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { shl _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SHLCL(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shld(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_SHR1(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { shr _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SHR1(d, s); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrb1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SHR1(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { shr _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SHR1(d, s); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrw1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SHR1(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { shr _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SHR1(d, s); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrd1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_SHRCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { shr _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_SHRCL(d, s, c); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrb(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_SHRCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { shr _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SHRCL(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrw(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SHRCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { shr _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SHRCL(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrd(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define WORD_SHLD(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _s = (s); \ + UINT16 _d = (d); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { mov ax, _s } \ + __asm { shld _d, ax, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SHLD(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shldw r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SHLD(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _s = (s); \ + UINT32 _d = (d); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { mov eax, _s } \ + __asm { shld _d, eax, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SHLD(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shldd r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define WORD_SHRD(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _s = (s); \ + UINT16 _d = (d); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { mov ax, _s } \ + __asm { shrd _d, ax, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_SHRD(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrdw r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_SHRD(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _s = (s); \ + UINT32 _d = (d); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { mov eax, _s } \ + __asm { shrd _d, eax, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_SHRD(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("shrdd r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_RCL1(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rcl _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_RCL1(d, s); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rclb1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_RCL1(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rcl _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_RCL1(d, s); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rclw1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_RCL1(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rcl _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_RCL1(d, s); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcld1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_RCLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rcl _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_RCLCL(d, s, c); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rclb(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_RCLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rcl _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_RCLCL(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rclw(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_RCLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rcl _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_RCLCL(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcld(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_RCR1(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rcr _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_RCR1(d, s); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcrb1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_RCR1(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rcr _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_RCR1(d, s); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcrw1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_RCR1(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rcr _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_RCR1(d, s); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcrd1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_RCRCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rcr _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_RCRCL(d, s, c); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcrb(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_RCRCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rcr _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_RCRCL(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcrw(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_RCRCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rcr _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_RCRCL(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rcrd(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_ROL1(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rol _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_ROL1(d, s); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rolb1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_ROL1(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rol _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_ROL1(d, s); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rolw1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_ROL1(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { rol _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_ROL1(d, s); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rold1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_ROLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rol _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_ROLCL(d, s, c); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rolb(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_ROLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rol _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_ROLCL(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rolw(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_ROLCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { rol _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_ROLCL(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rold(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + + + +#define BYTE_ROR1(d, s) { \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { ror _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_ROR1(d, s); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rorb1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_ROR1(d, s) { \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { ror _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_ROR1(d, s); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rorw1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_ROR1(d, s) { \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { ror _d, 1 } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_ROR1(d, s); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rord1 r=%x:%x f=%x:%x o=%d %d", _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define BYTE_RORCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT8 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { ror _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _BYTE_RORCL(d, s, c); \ + if ((_d != (UINT8)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rorb(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define WORD_RORCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT16 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { ror _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _WORD_RORCL(d, s, c); \ + if ((_d != (UINT16)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rorw(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + +#define DWORD_RORCL(d, s, c) { \ + UINT8 _c = (c); \ + UINT32 _d = (s); \ + UINT8 _f, _ov; \ + SETFLAGS \ + __asm { mov cl, _c } \ + __asm { ror _d, cl } \ + __asm { seto _ov } \ + __asm { lahf } \ + __asm { mov _f, ah } \ + _DWORD_RORCL(d, s, c); \ + if ((_d != (UINT32)(d)) || ((_f ^ CPU_FLAGL) & SZPC_FLAG) || ((!_ov) != (!CPU_OV))) TRACEOUT(("rord(%x) r=%x:%x f=%x:%x o=%d %d", _c, _d, d, _f, CPU_FLAGL, _ov, CPU_OV)); \ +} + diff --git a/source/src/vm/np21/i386c/ia32/instructions/sse/sse.cpp b/source/src/vm/np21/i386c/ia32/instructions/sse/sse.cpp new file mode 100644 index 000000000..868e63c80 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/sse/sse.cpp @@ -0,0 +1,1775 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" + +#include +#include +#include + +#if !defined(isnan) +#if defined(_MSC_VER) +#define isnan(x) (_isnan(x)) +#else +#define isnan(x) (__isnan(x)) +#endif +#endif + +#include "../../cpu.h" +#include "../../ia32.mcr" + +#include "sse.h" + +#if defined(USE_SSE) && defined(USE_FPU) + +#define CPU_SSEWORKCLOCK CPU_WORKCLOCK(8) + +static INLINE void +SSE_check_NM_EXCEPTION(){ + // SSEなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_SSE) && !(i386cpuid.cpu_feature_ex & CPU_FEATURE_EX_E3DNOW)){ // XXX: SSE命令にEnhanced 3DNow!命令が一部あるので例外的に認める + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if (CPU_CR0 & CPU_CR0_TS) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static INLINE void +SSE_setTag(void) +{ +// int i; +// +// if(!FPU_STAT.mmxenable){ +// FPU_STAT.mmxenable = 1; +// //FPU_CTRLWORD = 0x27F; +// for (i = 0; i < FPU_REG_NUM; i++) { +// FPU_STAT.tag[i] = TAG_Valid; +//#ifdef SUPPORT_FPU_DOSBOX2 +// FPU_STAT.int_regvalid[i] = 0; +//#endif +// FPU_STAT.reg[i].ul.ext = 0xffff; +// } +// } +// FPU_STAT_TOP = 0; +// FPU_STATUSWORD &= ~0x3800; +// FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; +} + +// mmx.cのものと同じ +static INLINE void +MMX_setTag(void) +{ + int i; + + if(!FPU_STAT.mmxenable){ + FPU_STAT.mmxenable = 1; + //FPU_CTRLWORD = 0x27F; + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Valid; +#ifdef SUPPORT_FPU_DOSBOX2 + FPU_STAT.int_regvalid[i] = 0; +#endif + FPU_STAT.reg[i].ul.ext = 0xffff; + } + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; +} + +float SSE_ROUND(float val){ + float floorval; + int rndbit = (SSE_MXCSR >> 13) & 0x3; + switch(rndbit){ + case 0: + floorval = (float)floor(val); + if (val - floorval > 0.5){ + return (floorval + 1); // 切り上げ + }else if (val - floorval < 0.5){ + return (floorval); // 切り捨て + }else{ + if(floor(floorval / 2) == floorval/2){ + return (floorval); // 偶数 + }else{ + return (floorval+1); // 奇数 + } + } + break; + case 1: + return (float)floor(val); + case 2: + return (float)ceil(val); + case 3: + if(val < 0){ + return (float)ceil(val); // ゼロ方向への切り捨て + }else{ + return (float)floor(val); // ゼロ方向への切り捨て + } + break; + default: + return val; + } +} + +/* + * SSE interface + */ + +// コードが長くなるのでやや強引に共通化 +// xmm/m128 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_P(float **data1, float **data2, float *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + *((UINT32*)(data2buf+ 2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 8); + *((UINT32*)(data2buf+ 3)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+12); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_P_UINT32(UINT32 **data1, UINT32 **data2, UINT32 *data2buf){ + SSE_PART_GETDATA1DATA2_P((float**)data1, (float**)data2, (float*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_S(float **data1, float **data2, float *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_S_UINT32(UINT32 **data1, UINT32 **data2, UINT32 *data2buf){ + SSE_PART_GETDATA1DATA2_S((float**)data1, (float**)data2, (float*)data2buf); +} + +// mm/m64 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_P_MMX2XMM(float **data1, SINT32 **data2, SINT32 *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + MMX_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (SINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_S_MMX2XMM(float **data1, SINT32 **data2, SINT32 *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + MMX_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (SINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} +// xmm/m64 -> mm +static INLINE void SSE_PART_GETDATA1DATA2_P_XMM2MMX(SINT32 **data1, float **data2, float *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + MMX_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (SINT32*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + *data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_S_XMM2MMX(SINT32 **data1, float **data2, float *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + MMX_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (SINT32*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + *data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} + +// reg/m32 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_S_REG2XMM(float **data1, SINT32 **data2, SINT32 *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (SINT32*)reg32_b20[(op)]; + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_S_XMM2REG(SINT32 **data1, float **data2, float *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (SINT32*)reg32_b53[(op)]; + if ((op) >= 0xc0) { + *data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} + +// mm/m64 -> mm +static INLINE void SSE_PART_GETDATA1DATA2_P_MMX2MMX_SB(SINT8 **data1, SINT8 **data2, SINT8 *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + MMX_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (SINT8*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + *data2 = (SINT8*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_P_MMX2MMX_UB(UINT8 **data1, UINT8 **data2, UINT8 *data2buf){ + SSE_PART_GETDATA1DATA2_P_MMX2MMX_SB((SINT8**)data1, (SINT8**)data2, (SINT8*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_P_MMX2MMX_SW(SINT16 **data1, SINT16 **data2, SINT16 *data2buf){ + SSE_PART_GETDATA1DATA2_P_MMX2MMX_SB((SINT8**)data1, (SINT8**)data2, (SINT8*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_P_MMX2MMX_UW(UINT16 **data1, UINT16 **data2, UINT16 *data2buf){ + SSE_PART_GETDATA1DATA2_P_MMX2MMX_SB((SINT8**)data1, (SINT8**)data2, (SINT8*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_P_MMX2MMX_SD(SINT32 **data1, SINT32 **data2, SINT32 *data2buf){ + SSE_PART_GETDATA1DATA2_P_MMX2MMX_SB((SINT8**)data1, (SINT8**)data2, (SINT8*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_P_MMX2MMX_UD(UINT32 **data1, UINT32 **data2, UINT32 *data2buf){ + SSE_PART_GETDATA1DATA2_P_MMX2MMX_SB((SINT8**)data1, (SINT8**)data2, (SINT8*)data2buf); +} + + +// 実際の命令群 + +void SSE_ADDPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = data1[i] + data2[i]; + } +} +void SSE_ADDSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + data1[0] = data1[0] + data2[0]; +} +void SSE_ANDNPS(void) +{ + UINT32 data2buf[4]; + UINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_UINT32(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = ((~(data1[i])) & (data2[i])); + } +} +void SSE_ANDPS(void) +{ + UINT32 data2buf[4]; + UINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_UINT32(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = ((data1[i]) & (data2[i])); + } +} +void SSE_CMPPS(void) +{ + UINT32 idx; + float data2buf[4]; + float *data1, *data2; + UINT32 *data1ui32; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + + data1ui32 = (UINT32*)data1; + + GET_PCBYTE((idx)); + switch(idx){ + case 0: // CMPEQPS + for(i=0;i<4;i++){ + data1ui32[i] = (data1[i] == data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 1: // CMPLTPS + for(i=0;i<4;i++){ + data1ui32[i] = (data1[i] < data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 2: // CMPLEPS + for(i=0;i<4;i++){ + data1ui32[i] = (data1[i] <= data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 3: // CMPUNORDPS + for(i=0;i<4;i++){ + data1ui32[i] = (isnan(data1[i]) || isnan(data2[i]) ? 0xffffffff : 0x00000000); + } + break; + case 4: // CMPNEQPS + for(i=0;i<4;i++){ + data1ui32[i] = (data1[i] != data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 5: // CMPNLTPS + for(i=0;i<4;i++){ + data1ui32[i] = (data1[i] >= data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 6: // CMPNLEPS + for(i=0;i<4;i++){ + data1ui32[i] = (data1[i] > data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 7: // CMPORDPS + for(i=0;i<4;i++){ + data1ui32[i] = (!isnan(data1[i]) && !isnan(data2[i]) ? 0xffffffff : 0x00000000); + } + break; + } +} +void SSE_CMPSS(void) +{ + UINT32 idx; + float data2buf[4]; + float *data1, *data2; + UINT32 *data1ui32; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + + data1ui32 = (UINT32*)data1; + + GET_PCBYTE((idx)); + switch(idx){ + case 0: // CMPEQSS + data1ui32[0] = (data1[0] == data2[0] ? 0xffffffff : 0x00000000); + break; + case 1: // CMPLTSS + data1ui32[0] = (data1[0] < data2[0] ? 0xffffffff : 0x00000000); + break; + case 2: // CMPLESS + data1ui32[0] = (data1[0] <= data2[0] ? 0xffffffff : 0x00000000); + break; + case 3: // CMPUNORDSS + data1ui32[0] = (isnan(data1[0]) || isnan(data2[0]) ? 0xffffffff : 0x00000000); + break; + case 4: // CMPNEQSS + data1ui32[0] = (data1[0] != data2[0] ? 0xffffffff : 0x00000000); + break; + case 5: // CMPNLTSS + data1ui32[0] = (data1[0] >= data2[0] ? 0xffffffff : 0x00000000); + break; + case 6: // CMPNLESS + data1ui32[0] = (data1[0] > data2[0] ? 0xffffffff : 0x00000000); + break; + case 7: // CMPORDSS + data1ui32[0] = (!isnan(data1[0]) && !isnan(data2[0]) ? 0xffffffff : 0x00000000); + break; + } +} +void SSE_COMISS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + + if(isnan(data1[0]) || isnan(data2[0])){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | P_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + }else if(data1[0] > data2[0]){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + }else if(data1[0] < data2[0]){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + }else{ // equal + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + } +} +void SSE_CVTPI2PS(void) +{ + SINT32 data2buf[2]; + float *data1; + SINT32 *data2; + + SSE_PART_GETDATA1DATA2_P_MMX2XMM(&data1, &data2, data2buf); + + data1[0] = (float)data2[0]; + data1[1] = (float)data2[1]; +} +void SSE_CVTPS2PI(void) +{ + float data2buf[2]; + SINT32 *data1; + float *data2; + + SSE_PART_GETDATA1DATA2_P_XMM2MMX(&data1, &data2, data2buf); + + data1[0] = (SINT32)SSE_ROUND(data2[0]); + data1[1] = (SINT32)SSE_ROUND(data2[1]); +} +void SSE_CVTSI2SS(void) +{ + SINT32 data2buf[2]; + float *data1; + SINT32 *data2; + + SSE_PART_GETDATA1DATA2_S_REG2XMM(&data1, &data2, data2buf); + + data1[0] = (float)data2[0]; +} +void SSE_CVTSS2SI(void) +{ + float data2buf[2]; + SINT32 *data1; + float *data2; + + SSE_PART_GETDATA1DATA2_S_XMM2REG(&data1, &data2, data2buf); + + data1[0] = (SINT32)SSE_ROUND(data2[0]); +} +void SSE_CVTTPS2PI(void) +{ + float data2buf[2]; + SINT32 *data1; + float *data2; + + SSE_PART_GETDATA1DATA2_P_XMM2MMX(&data1, &data2, data2buf); + + data1[0] = (SINT32)(data2[0]); + data1[1] = (SINT32)(data2[1]); +} +void SSE_CVTTSS2SI(void) +{ + float data2buf[2]; + SINT32 *data1; + float *data2; + + SSE_PART_GETDATA1DATA2_S_XMM2REG(&data1, &data2, data2buf); + + data1[0] = (SINT32)(data2[0]); +} +void SSE_DIVPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = data1[i] / data2[i]; + } +} +void SSE_DIVSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + data1[0] = data1[0] / data2[0]; +} +void SSE_LDMXCSR(UINT32 maddr) +{ + SSE_MXCSR = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); +} +void SSE_MAXPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + if(isnan(data1[i]) || isnan(data2[i])){ + data1[i] = data2[i]; + }else{ + data1[i] = (data1[i] > data2[i] ? data1[i] : data2[i]); + } + } +} +void SSE_MAXSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + if(isnan(data1[0]) || isnan(data2[0])){ + data1[0] = data2[0]; + }else{ + data1[0] = (data1[0] > data2[0] ? data1[0] : data2[0]); + } +} +void SSE_MINPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + if(isnan(data1[i]) || isnan(data2[i])){ + data1[i] = data2[i]; + }else{ + data1[i] = (data1[i] < data2[i] ? data1[i] : data2[i]); + } + } +} +void SSE_MINSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + if(isnan(data1[0]) || isnan(data2[0])){ + data1[0] = data2[0]; + }else{ + data1[0] = (data1[0] < data2[0] ? data1[0] : data2[0]); + } +} +void SSE_MOVAPSmem2xmm(void) +{ + UINT32 op; + UINT idx, sub; + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + *((UINT32*)(data2buf+ 2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 8); + *((UINT32*)(data2buf+ 3)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+12); + data2 = data2buf; + } + for(i=0;i<4;i++){ + data1[i] = data2[i]; + } +} +void SSE_MOVAPSxmm2mem(void) +{ + UINT32 op; + UINT idx, sub; + float *data1, *data2; + int i; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + for(i=0;i<4;i++){ + data2[i] = data1[i]; + } + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 0, *((UINT32*)(data1+ 0))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 4, *((UINT32*)(data1+ 1))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 8, *((UINT32*)(data1+ 2))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+12, *((UINT32*)(data1+ 3))); + } +} +void SSE_MOVHLPS(float *data1, float *data2) +{ + data1[0] = data2[2]; + data1[1] = data2[3]; +} +void SSE_MOVHPSmem2xmm(void) +{ + UINT32 op; + UINT idx, sub; + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + SSE_MOVLHPS(data1, data2); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 3)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + data2 = data2buf; + for(i=2;i<4;i++){ + data1[i] = data2[i]; + } + } +} +void SSE_MOVHPSxmm2mem(void) +{ + UINT32 op; + UINT idx, sub; + float *data1; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + EXCEPTION(UD_EXCEPTION, 0); + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 0, *((UINT32*)(data1+ 2))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 4, *((UINT32*)(data1+ 3))); + } +} +void SSE_MOVLHPS(float *data1, float *data2) +{ + data1[2] = data2[0]; + data1[3] = data2[1]; +} +void SSE_MOVLPSmem2xmm(void) +{ + UINT32 op; + UINT idx, sub; + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + SSE_MOVHLPS(data1, data2); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + data2 = data2buf; + for(i=0;i<2;i++){ + data1[i] = data2[i]; + } + } +} +void SSE_MOVLPSxmm2mem(void) +{ + UINT32 op; + UINT idx, sub; + float *data1; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + EXCEPTION(UD_EXCEPTION, 0); + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 0, *((UINT32*)(data1+ 0))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 4, *((UINT32*)(data1+ 1))); + } +} +void SSE_MOVMSKPS(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 *data1; + UINT32 *data2; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = reg32_b53[(op)]; + if ((op) >= 0xc0) { + data2 = (UINT32*)(&(FPU_STAT.xmm_reg[sub])); + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + *data1 = ((data2[0] >> 31) & 0x1)| + ((data2[1] >> 30) & 0x2)| + ((data2[2] >> 29) & 0x4)| + ((data2[3] >> 28) & 0x8); +} +void SSE_MOVSSmem2xmm(void) +{ + UINT32 op; + UINT idx, sub; + float data2buf[4]; + float *data1, *data2; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + data2 = data2buf; + } + data1[0] = data2[0]; + *(UINT32*)(data1+1) = *(UINT32*)(data1+2) = *(UINT32*)(data1+3) = 0; +} +void SSE_MOVSSxmm2mem(void) +{ + UINT32 op; + UINT idx, sub; + float *data1, *data2; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + data2[0] = data1[0]; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 0, *((UINT32*)(data1+ 0))); + } +} +void SSE_MOVUPSmem2xmm(void) +{ + SSE_MOVAPSmem2xmm(); // エミュレーションではアライメント制限がないのでMOVAPSと同じ +} +void SSE_MOVUPSxmm2mem(void) +{ + SSE_MOVAPSxmm2mem(); // エミュレーションではアライメント制限がないのでMOVAPSと同じ +} +void SSE_MULPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = data1[i] * data2[i]; + } +} +void SSE_MULSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + data1[0] = data1[0] * data2[0]; +} +void SSE_ORPS(void) +{ + UINT32 data2buf[4]; + UINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_UINT32(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = ((data1[i]) | (data2[i])); + } +} +void SSE_RCPPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = 1.0f / data2[i]; + } +} +void SSE_RCPSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + data1[0] = 1.0f / data2[0]; +} +void SSE_RSQRTPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = (float)(1.0f / sqrt(data2[i])); + } +} +void SSE_RSQRTSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + data1[0] = (float)(1.0f / sqrt(data2[0])); +} +void SSE_SHUFPS(void) +{ + UINT32 imm8; + float data2buf[4]; + float data1buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + + GET_PCBYTE((imm8)); + + for(i=0;i<2;i++){ + data1buf[i] = data1[imm8 & 0x3]; + imm8 = (imm8 >> 2); + } + for(i=2;i<4;i++){ + data1buf[i] = data2[imm8 & 0x3]; + imm8 = (imm8 >> 2); + } + for(i=0;i<4;i++){ + data1[i] = data1buf[i]; + } +} +void SSE_SQRTPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = (float)sqrt(data2[i]); + } +} +void SSE_SQRTSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + data1[0] = (float)sqrt(data2[0]); +} +void SSE_STMXCSR(UINT32 maddr) +{ + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, maddr, SSE_MXCSR); +} +void SSE_SUBPS(void) +{ + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = data1[i] - data2[i]; + } +} +void SSE_SUBSS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_S(&data1, &data2, data2buf); + data1[0] = data1[0] - data2[0]; +} +void SSE_UCOMISS(void) +{ + SSE_COMISS(); // XXX: とりあえず例外は考えないのでCOMISSと同じ +} +void SSE_UNPCKHPS(void) +{ + float data1buf[4]; + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1buf[i] = data1[i]; + } + data1[0] = data1buf[2]; + data1[1] = data2[2]; + data1[2] = data1buf[3]; + data1[3] = data2[3]; +} +void SSE_UNPCKLPS(void) +{ + float data1buf[4]; + float data2buf[4]; + float *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1buf[i] = data1[i]; + } + data1[0] = data1buf[0]; + data1[1] = data2[0]; + data1[2] = data1buf[1]; + data1[3] = data2[1]; +} +void SSE_XORPS(void) +{ + UINT32 data2buf[4]; + UINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_UINT32(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = ((data1[i]) ^ (data2[i])); + } +} + +void SSE_PAVGB(void) +{ + UINT8 data2buf[8]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_UB(&data1, &data2, data2buf); + for(i=0;i<8;i++){ + data1[i] = (UINT8)(((UINT16)data1[i] + (UINT16)data2[i] + 1) / 2); + } +} +void SSE_PAVGW(void) +{ + UINT16 data2buf[4]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_UW(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = (UINT16)(((UINT32)data1[i] + (UINT32)data2[i] + 1) / 2); + } +} +void SSE_PEXTRW(void) +{ + UINT32 imm8; + UINT32 op; + UINT idx, sub; + UINT32 *data1; + UINT16 *data2; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT32*)reg32_b53[(op)]; + if ((op) >= 0xc0) { + data2 = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + GET_PCBYTE((imm8)); + *data1 = (UINT32)data2[imm8 & 0x3]; +} +void SSE_PINSRW(void) +{ + UINT32 imm8; + UINT32 op; + UINT idx, sub; + UINT16 *data1; + UINT16 data2; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT16*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + data2 = (UINT16)((*reg32_b20[(op)]) & 0xffff); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + data2 = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, maddr+ 0); + } + GET_PCBYTE((imm8)); + data1[imm8 & 0x3] = data2; +} +void SSE_PMAXSW(void) +{ + SINT16 data2buf[4]; + SINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_SW(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = (data1[i] > data2[i] ? data1[i] : data2[i]); + } +} +void SSE_PMAXUB(void) +{ + UINT8 data2buf[8]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_UB(&data1, &data2, data2buf); + for(i=0;i<8;i++){ + data1[i] = (data1[i] > data2[i] ? data1[i] : data2[i]); + } +} +void SSE_PMINSW(void) +{ + SINT16 data2buf[4]; + SINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_SW(&data1, &data2, data2buf); + for(i=0;i<4;i++){ + data1[i] = (data1[i] < data2[i] ? data1[i] : data2[i]); + } +} +void SSE_PMINUB(void) +{ + UINT8 data2buf[8]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_UB(&data1, &data2, data2buf); + for(i=0;i<8;i++){ + data1[i] = (data1[i] < data2[i] ? data1[i] : data2[i]); + } +} +void SSE_PMOVMSKB(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 *data1; + UINT8 *data2; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT32*)reg32_b53[(op)]; + if ((op) >= 0xc0) { + data2 = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + *data1 = ((data2[0] >> 7) & 0x1 )| + ((data2[1] >> 6) & 0x2 )| + ((data2[2] >> 5) & 0x4 )| + ((data2[3] >> 4) & 0x8 )| + ((data2[4] >> 3) & 0x10)| + ((data2[5] >> 2) & 0x20)| + ((data2[6] >> 1) & 0x40)| + ((data2[7] >> 0) & 0x80); +} +void SSE_PMULHUW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 data2buf[4]; + UINT16 *data1, *data2; + int i; + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT16*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + data2 = (UINT16*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(data2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + data2 = data2buf; + } + for(i=0;i<4;i++){ + data1[i] = (UINT16)((((UINT32)data2[i] * (UINT32)data1[i]) >> 16) & 0xffff); + } +} +void SSE_PSADBW(void) +{ + SINT16 temp1; + UINT16 temp; + UINT8 data2buf[8]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_UB(&data1, &data2, data2buf); + temp = 0; + for(i=0;i<8;i++){ + temp1 = (SINT16)data2[i] - (SINT16)data1[i]; + temp += (UINT16)(temp1 < 0 ? -temp1 : temp1); + } + *((UINT16*)data2 + 0) = temp; + *((UINT16*)data2 + 1) = 0; + *((UINT16*)data2 + 2) = 0; + *((UINT16*)data2 + 3) = 0; +} +void SSE_PSHUFW(void) +{ + UINT32 imm8; + UINT16 data2buf[4]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_UW(&data1, &data2, data2buf); + GET_PCBYTE((imm8)); + for(i=0;i<4;i++){ + data1[i] = data2[imm8 & 0x3]; + imm8 = imm8 >> 2; + } +} + +void SSE_MASKMOVQ(void) +{ + UINT8 data2buf[8]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_P_MMX2MMX_UB(&data1, &data2, data2buf); + for(i=0;i<8;i++){ + if (!CPU_INST_AS32) { + if(data2[i] & 0x80){ + cpu_vmemorywrite(CPU_DS_INDEX, CPU_DI, data1[i]); + } + CPU_DI += 1; + } else { + if(data2[i] & 0x80){ + cpu_vmemorywrite(CPU_DS_INDEX, CPU_EDI, data1[i]); + } + CPU_EDI += 1; + } + } + // 戻す + if (!CPU_INST_AS32) { + CPU_DI -= 8; + } else { + CPU_EDI -= 8; + } +} +void SSE_MOVNTPS(void) +{ + UINT32 op; + UINT idx, sub; + float *data1; + + // 00001111:00101011 mod xmmreg r/m + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (float*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + // XXX: ここはどう扱う? + EXCEPTION(UD_EXCEPTION, 0); + //data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + //for(i=0;i<4;i++){ + // data2[i] = data1[i]; + //} + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 0, *((UINT32*)(data1+ 0))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 4, *((UINT32*)(data1+ 1))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 8, *((UINT32*)(data1+ 2))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+12, *((UINT32*)(data1+ 3))); + } +} +void SSE_MOVNTQ(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 *data1; + + // 00001111:00101011 mod xmmreg r/m + + SSE_check_NM_EXCEPTION(); + SSE_setTag(); + MMX_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT32*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + // XXX: ここはどう扱う? + EXCEPTION(UD_EXCEPTION, 0); + //data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + //for(i=0;i<4;i++){ + // data2[i] = data1[i]; + //} + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 0, *((UINT32*)(data1+ 0))); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr+ 4, *((UINT32*)(data1+ 1))); + } +} +void SSE_PREFETCHTx(void) +{ + UINT32 op; + UINT idx, sub; + + //SSE_check_NM_EXCEPTION(); + //SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + // XXX: ここはどう扱う? + //EXCEPTION(UD_EXCEPTION, 0); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + switch(idx){ + case 3: + // PREFETCH2 + break; + case 2: + // PREFETCH1 + break; + case 1: + // PREFETCH0 + break; + case 0: + // PREFETCHNTA + break; + default: + //EXCEPTION(UD_EXCEPTION, 0); + break; + } + // XXX: 何もしない + } +} +void SSE_NOPPREFETCH(void) +{ + UINT32 op; + UINT idx, sub; + + //SSE_check_NM_EXCEPTION(); + //SSE_setTag(); + CPU_SSEWORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + // XXX: ここはどう扱う? + //EXCEPTION(UD_EXCEPTION, 0); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + // XXX: 何もしない + } +} +void SSE_SFENCE(void) +{ + // Nothing to do +} +void SSE_LFENCE(void) +{ + // Nothing to do +} +void SSE_MFENCE(void) +{ + // Nothing to do +} +void SSE_CLFLUSH(UINT32 op) +{ + UINT idx, sub; + + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + // XXX: ここはどう扱う? + //EXCEPTION(UD_EXCEPTION, 0); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + // XXX: 何もしない + } +} + + +#else + +/* + * SSE interface + */ + +void SSE_ADDPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_ADDSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_ANDNPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_ANDPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CMPPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CMPSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_COMISS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CVTPI2PS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CVTPS2PI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CVTSI2SS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CVTSS2SI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CVTTPS2PI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CVTTSS2SI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_DIVPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_DIVSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_LDMXCSR(UINT32 maddr) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MAXPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MAXSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MINPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MINSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVAPSmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVAPSxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVHLPS(float *data1, float *data2) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVHPSmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVHPSxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVLHPS(float *data1, float *data2) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVLPSmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVLPSxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVMSKPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVSSmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVSSxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVUPSmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVUPSxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MULPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MULSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_ORPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_RCPPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_RCPSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_RSQRTPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_RSQRTSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_SHUFPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_SQRTPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_SQRTSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_STMXCSR(UINT32 maddr) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_SUBPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_SUBSS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_UCOMISS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_UNPCKHPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_UNPCKLPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_XORPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void SSE_PAVGB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PAVGW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PEXTRW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PINSRW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PMAXSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PMAXUB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PMINSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PMINUB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PMOVMSKB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PMULHUW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PSADBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PSHUFW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void SSE_MASKMOVQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVNTPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MOVNTQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_PREFETCHTx(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_NOPPREFETCH(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_SFENCE(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_LFENCE(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_MFENCE(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE_CLFLUSH(UINT32 op) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + + +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/sse/sse.h b/source/src/vm/np21/i386c/ia32/instructions/sse/sse.h new file mode 100644 index 000000000..a30bf5ada --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/sse/sse.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SSE_SSE_H__ +#define IA32_CPU_INSTRUCTION_SSE_SSE_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +float SSE_ROUND(float val); + +void SSE_ADDPS(void); +void SSE_ADDSS(void); +void SSE_ANDNPS(void); +void SSE_ANDPS(void); +void SSE_CMPPS(void); +void SSE_CMPSS(void); +void SSE_COMISS(void); +void SSE_CVTPI2PS(void); +void SSE_CVTPS2PI(void); +void SSE_CVTSI2SS(void); +void SSE_CVTSS2SI(void); +void SSE_CVTTPS2PI(void); +void SSE_CVTTSS2SI(void); +void SSE_DIVPS(void); +void SSE_DIVSS(void); +void SSE_LDMXCSR(UINT32 maddr); +void SSE_MAXPS(void); +void SSE_MAXSS(void); +void SSE_MINPS(void); +void SSE_MINSS(void); +void SSE_MOVAPSmem2xmm(void); +void SSE_MOVAPSxmm2mem(void); +void SSE_MOVHLPS(float *data1, float *data2); +void SSE_MOVHPSmem2xmm(void); +void SSE_MOVHPSxmm2mem(void); +void SSE_MOVLHPS(float *data1, float *data2); +void SSE_MOVLPSmem2xmm(void); +void SSE_MOVLPSxmm2mem(void); +void SSE_MOVMSKPS(void); +void SSE_MOVSSmem2xmm(void); +void SSE_MOVSSxmm2mem(void); +void SSE_MOVUPSmem2xmm(void); +void SSE_MOVUPSxmm2mem(void); +void SSE_MULPS(void); +void SSE_MULSS(void); +void SSE_ORPS(void); +void SSE_RCPPS(void); +void SSE_RCPSS(void); +void SSE_RSQRTPS(void); +void SSE_RSQRTSS(void); +void SSE_SHUFPS(void); +void SSE_SQRTPS(void); +void SSE_SQRTSS(void); +void SSE_STMXCSR(UINT32 maddr); +void SSE_SUBPS(void); +void SSE_SUBSS(void); +void SSE_UCOMISS(void); +void SSE_UNPCKHPS(void); +void SSE_UNPCKLPS(void); +void SSE_XORPS(void); + +void SSE_PAVGB(void); +void SSE_PAVGW(void); +void SSE_PEXTRW(void); +void SSE_PINSRW(void); +void SSE_PMAXSW(void); +void SSE_PMAXUB(void); +void SSE_PMINSW(void); +void SSE_PMINUB(void); +void SSE_PMOVMSKB(void); +void SSE_PMULHUW(void); +void SSE_PSADBW(void); +void SSE_PSHUFW(void); + +void SSE_MASKMOVQ(void); +void SSE_MOVNTPS(void); +void SSE_MOVNTQ(void); +void SSE_PREFETCHTx(void); +void SSE_NOPPREFETCH(void); +//void SSE_PREFETCHNTA(void); // -> SSE_PREFETCHTx +void SSE_SFENCE(void); +void SSE_LFENCE(void); +void SSE_MFENCE(void); +void SSE_CLFLUSH(UINT32 op); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_SSE_SSE_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/sse2/sse2.cpp b/source/src/vm/np21/i386c/ia32/instructions/sse2/sse2.cpp new file mode 100644 index 000000000..100b21137 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/sse2/sse2.cpp @@ -0,0 +1,3489 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" + +#if 0 +#undef TRACEOUT +#define USE_TRACEOUT_VS +//#define MEM_BDA_TRACEOUT +//#define MEM_D8_TRACEOUT +#ifdef USE_TRACEOUT_VS +static void trace_fmt_ex(const char *fmt, ...) +{ + char stmp[2048]; + va_list ap; + va_start(ap, fmt); + vsprintf(stmp, fmt, ap); + strcat(stmp, "\n"); + va_end(ap); + OutputDebugStringA(stmp); +} +#define TRACEOUT(s) trace_fmt_ex s +#else +#define TRACEOUT(s) (void)(s) +#endif +#endif /* 1 */ + +#include +#include +#include + +#undef isnan +#if defined(_MSC_VER) +#define isnan(x) (_isnan(x)) +#else +#define isnan(x) (__isnan(x)) +#endif + +#include "../../cpu.h" +#include "../../ia32.mcr" + +#include "../sse/sse.h" +#include "sse2.h" + +#if defined(USE_SSE2) && defined(USE_SSE) && defined(USE_FPU) + +#define CPU_SSE2WORKCLOCK CPU_WORKCLOCK(8) + +static INLINE void +SSE2_check_NM_EXCEPTION(){ + // SSE2なしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_SSE2)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if (CPU_CR0 & CPU_CR0_TS) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static INLINE void +SSE2_setTag(void) +{ +} + +// mmx.cのものと同じ +static INLINE void +MMX_setTag(void) +{ + int i; + + if(!FPU_STAT.mmxenable){ + FPU_STAT.mmxenable = 1; + //FPU_CTRLWORD = 0x27F; + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Valid; +#ifdef SUPPORT_FPU_DOSBOX2 + FPU_STAT.int_regvalid[i] = 0; +#endif + FPU_STAT.reg[i].ul.ext = 0xffff; + } + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; +} + +float SSE2_ROUND_FLOAT(float val){ + return SSE_ROUND(val); +} +double SSE2_ROUND_DOUBLE(double val){ + double floorval; + int rndbit = (SSE_MXCSR >> 13) & 0x3; + switch(rndbit){ + case 0: + floorval = floor(val); + if (val - floorval > 0.5){ + return (floorval + 1); // 切り上げ + }else if (val - floorval < 0.5){ + return (floorval); // 切り捨て + }else{ + if(floor(floorval / 2) == floorval/2){ + return (floorval); // 偶数 + }else{ + return (floorval+1); // 奇数 + } + } + break; + case 1: + return floor(val); + case 2: + return ceil(val); + case 3: + if(val < 0){ + return ceil(val); // ゼロ方向への切り捨て + }else{ + return floor(val); // ゼロ方向への切り捨て + } + break; + default: + return val; + } +} + +/* + * SSE2 interface + */ + +// コードが長くなるのでやや強引に共通化 +// xmm/m128 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_PD(double **data1, double **data2, double *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT64*)(data2buf+ 0)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT64*)(data2buf+ 1)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 8); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_P_UINT32(UINT32 **data1, UINT32 **data2, UINT32 *data2buf){ + SSE_PART_GETDATA1DATA2_PD((double**)data1, (double**)data2, (double*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_PD_UINT64(UINT64 **data1, UINT64 **data2, UINT64 *data2buf){ + SSE_PART_GETDATA1DATA2_PD((double**)data1, (double**)data2, (double*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_SD(double **data1, double **data2, double *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT64*)(data2buf+ 0)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_S_UINT32(UINT32 **data1, UINT32 **data2, UINT32 *data2buf){ + SSE_PART_GETDATA1DATA2_SD((double**)data1, (double**)data2, (double*)data2buf); +} +static INLINE void SSE_PART_GETDATA1DATA2_SD_UINT64(UINT64 **data1, UINT64 **data2, UINT64 *data2buf){ + SSE_PART_GETDATA1DATA2_SD((double**)data1, (double**)data2, (double*)data2buf); +} +// xmm/m64 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_PDm64(double **data1, float **data2, float *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_SDm64(double **data1, float **data2, float *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (float*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} + +// mm/m128 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_PD_MMX2XMM(double **data1, SINT32 **data2, SINT32 *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (SINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT32*)(data2buf+ 1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 4); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_SD_MMX2XMM(double **data1, SINT32 **data2, SINT32 *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (SINT32*)(&(FPU_STAT.reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} +// xmm/m128 -> mm +static INLINE void SSE_PART_GETDATA1DATA2_PD_XMM2MMX(SINT32 **data1, double **data2, double *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (SINT32*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + *data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT64*)(data2buf+ 0)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT64*)(data2buf+ 1)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 8); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_SD_XMM2MMX(SINT32 **data1, double **data2, double *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (SINT32*)(&(FPU_STAT.reg[idx])); + if ((op) >= 0xc0) { + *data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT64*)(data2buf+ 0)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} + +// reg/m32 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_SD_REG2XMM(double **data1, SINT32 **data2, SINT32 *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (SINT32*)reg32_b20[(op)]; + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+ 0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} +static INLINE void SSE_PART_GETDATA1DATA2_SD_XMM2REG(SINT32 **data1, double **data2, double *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (SINT32*)reg32_b53[(op)]; + if ((op) >= 0xc0) { + *data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT64*)(data2buf+ 0)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 0); + *data2 = data2buf; + } +} + +void SSE2_ADDPD(void) +{ + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = data1[i] + data2[i]; + } + TRACEOUT(("SSE2_ADDPD")); +} +void SSE2_ADDSD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + data1[0] = data1[0] + data2[0]; + TRACEOUT(("SSE2_ADDSD")); +} +void SSE2_ANDNPD(void) +{ + SSE_ANDNPS(); + TRACEOUT(("SSE2_ANDNPD")); +} +void SSE2_ANDPD(void) +{ + SSE_ANDPS(); + TRACEOUT(("SSE2_ANDPD")); +} +void SSE2_CMPPD(void) +{ + UINT32 idx; + double data2buf[2]; + double *data1, *data2; + UINT32 *data1ui32; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + + data1ui32 = (UINT32*)data1; + + GET_PCBYTE((idx)); + switch(idx){ + case 0: // CMPEQPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (data1[i] == data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 1: // CMPLTPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (data1[i] < data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 2: // CMPLEPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (data1[i] <= data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 3: // CMPUNORDPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (isnan(data1[i]) || isnan(data2[i]) ? 0xffffffff : 0x00000000); + } + break; + case 4: // CMPNEQPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (data1[i] != data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 5: // CMPNLTPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (data1[i] >= data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 6: // CMPNLEPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (data1[i] > data2[i] ? 0xffffffff : 0x00000000); + } + break; + case 7: // CMPORDPS + for(i=0;i<2;i++){ + data1ui32[i*2+0] = data1ui32[i*2+1] = (!isnan(data1[i]) && !isnan(data2[i]) ? 0xffffffff : 0x00000000); + } + break; + } + TRACEOUT(("SSE2_CMPPD")); +} +void SSE2_CMPSD(void) +{ + UINT32 idx; + double data2buf[2]; + double *data1, *data2; + UINT32 *data1ui32; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + + data1ui32 = (UINT32*)data1; + + GET_PCBYTE((idx)); + switch(idx){ + case 0: // CMPEQSS + data1ui32[0] = data1ui32[1] = (data1[0] == data2[0] ? 0xffffffff : 0x00000000); + break; + case 1: // CMPLTSS + data1ui32[0] = data1ui32[1] = (data1[0] < data2[0] ? 0xffffffff : 0x00000000); + break; + case 2: // CMPLESS + data1ui32[0] = data1ui32[1] = (data1[0] <= data2[0] ? 0xffffffff : 0x00000000); + break; + case 3: // CMPUNORDSS + data1ui32[0] = data1ui32[1] = (isnan(data1[0]) || isnan(data2[0]) ? 0xffffffff : 0x00000000); + break; + case 4: // CMPNEQSS + data1ui32[0] = data1ui32[1] = (data1[0] != data2[0] ? 0xffffffff : 0x00000000); + break; + case 5: // CMPNLTSS + data1ui32[0] = data1ui32[1] = (data1[0] >= data2[0] ? 0xffffffff : 0x00000000); + break; + case 6: // CMPNLESS + data1ui32[0] = data1ui32[1] = (data1[0] > data2[0] ? 0xffffffff : 0x00000000); + break; + case 7: // CMPORDSS + data1ui32[0] = data1ui32[1] = (!isnan(data1[0]) && !isnan(data2[0]) ? 0xffffffff : 0x00000000); + break; + } + TRACEOUT(("SSE2_CMPSD")); +} +void SSE2_COMISD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + + if(isnan(data1[0]) || isnan(data2[0])){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | P_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + }else if(data1[0] > data2[0]){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + }else if(data1[0] < data2[0]){ + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | C_FLAG; + }else{ // equal + CPU_FLAGL = (CPU_FLAGL & ~Z_FLAG) | Z_FLAG; + CPU_FLAGL = (CPU_FLAGL & ~P_FLAG) | 0; + CPU_FLAGL = (CPU_FLAGL & ~C_FLAG) | 0; + } + TRACEOUT(("SSE2_COMISD")); +} +void SSE2_CVTPI2PD(void) +{ + SINT32 data2buf[2]; + double *data1; + SINT32 *data2; + + SSE_PART_GETDATA1DATA2_PD_MMX2XMM(&data1, &data2, data2buf); + + data1[0] = (double)data2[0]; + data1[1] = (double)data2[1]; + TRACEOUT(("SSE2_CVTPI2PD")); +} +void SSE2_CVTPD2PI(void) +{ + double data2buf[2]; + SINT32 *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_PD_XMM2MMX(&data1, &data2, data2buf); + + data1[0] = (SINT32)SSE2_ROUND_DOUBLE(data2[0]); + data1[1] = (SINT32)SSE2_ROUND_DOUBLE(data2[1]); + TRACEOUT(("SSE2_CVTPD2PI")); +} +void SSE2_CVTSI2SD(void) +{ + SINT32 data2buf[2]; + double *data1; + SINT32 *data2; + + SSE_PART_GETDATA1DATA2_SD_REG2XMM(&data1, &data2, data2buf); + + data1[0] = (double)data2[0]; + TRACEOUT(("SSE2_CVTSI2SD")); +} +void SSE2_CVTSD2SI(void) +{ + double data2buf[2]; + SINT32 *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_SD_XMM2REG(&data1, &data2, data2buf); + + data1[0] = (SINT32)SSE2_ROUND_DOUBLE(data2[0]); + TRACEOUT(("SSE2_CVTSD2SI")); +} +void SSE2_CVTTPD2PI(void) +{ + double data2buf[2]; + SINT32 *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_PD_XMM2MMX(&data1, &data2, data2buf); + + data1[0] = (SINT32)(data2[0]); + data1[1] = (SINT32)(data2[1]); + TRACEOUT(("SSE2_CVTTPD2PI")); +} +void SSE2_CVTTSD2SI(void) +{ + double data2buf[2]; + SINT32 *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_SD_XMM2REG(&data1, &data2, data2buf); + + data1[0] = (SINT32)(data2[0]); + TRACEOUT(("SSE2_CVTTSD2SI")); +} +void SSE2_CVTPD2PS(void) +{ + double data2buf[2]; + float *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), &data2, data2buf); + + data1[0] = (float)(data2[0]); + data1[1] = (float)(data2[1]); + data1[2] = data1[3] = 0; + TRACEOUT(("SSE2_CVTPD2PS")); +} +void SSE2_CVTPS2PD(void) +{ + float data2buf[2]; + double *data1; + float *data2; + + SSE_PART_GETDATA1DATA2_PDm64(&data1, &data2, data2buf); + + data1[0] = (double)(data2[0]); + data1[1] = (double)(data2[1]); + TRACEOUT(("SSE2_CVTPS2PD")); +} +void SSE2_CVTSD2SS(void) +{ + double data2buf[2]; + float *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_SD((double**)(&data1), &data2, data2buf); + + data1[0] = (float)(data2[0]); + TRACEOUT(("SSE2_CVTSD2SS")); +} +void SSE2_CVTSS2SD(void) +{ + float data2buf[2]; + double *data1; + float *data2; + + SSE_PART_GETDATA1DATA2_SDm64(&data1, &data2, data2buf); + + data1[0] = (double)(data2[0]); + TRACEOUT(("SSE2_CVTSS2SD")); +} +void SSE2_CVTPD2DQ(void) +{ + double data2buf[2]; + SINT32 *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), &data2, data2buf); + + data1[0] = (SINT32)SSE2_ROUND_DOUBLE(data2[0]); + data1[1] = (SINT32)SSE2_ROUND_DOUBLE(data2[1]); + data1[2] = data1[3] = 0; + TRACEOUT(("SSE2_CVTPD2DQ")); +} +void SSE2_CVTTPD2DQ(void) +{ + double data2buf[2]; + SINT32 *data1; + double *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), &data2, data2buf); + + data1[0] = (SINT32)(data2[0]); + data1[1] = (SINT32)(data2[1]); + data1[2] = data1[3] = 0; + TRACEOUT(("SSE2_CVTTPD2DQ")); +} +void SSE2_CVTDQ2PD(void) +{ + SINT32 data2buf[2]; + double *data1; + SINT32 *data2; + + SSE_PART_GETDATA1DATA2_PDm64(&data1, (float**)(&data2), (float*)data2buf); + + data1[0] = (double)(data2[0]); + data1[1] = (double)(data2[1]); + TRACEOUT(("SSE2_CVTDQ2PD")); +} +void SSE2_CVTPS2DQ(void) +{ + float data2buf[4]; + SINT32 *data1; + float *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + + for(i=0;i<4;i++){ + data1[i] = (SINT32)SSE2_ROUND_FLOAT(data2[i]); + } + TRACEOUT(("SSE2_CVTPS2DQ")); +} +void SSE2_CVTTPS2DQ(void) +{ + float data2buf[4]; + SINT32 *data1; + float *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + + for(i=0;i<4;i++){ + data1[i] = (SINT32)(data2[i]); + } + TRACEOUT(("SSE2_CVTTPS2DQ")); +} +void SSE2_CVTDQ2PS(void) +{ + SINT32 data2buf[4]; + float *data1; + SINT32 *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + + for(i=0;i<4;i++){ + data1[i] = (float)(data2[i]); + } + TRACEOUT(("SSE2_CVTDQ2PS")); +} +void SSE2_DIVPD(void) +{ + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = data1[i] / data2[i]; + } + TRACEOUT(("SSE2_DIVPD")); +} +void SSE2_DIVSD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + data1[0] = data1[0] / data2[0]; + TRACEOUT(("SSE2_DIVSD")); +} +void SSE2_MAXPD(void) +{ + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + if(isnan(data1[i]) || isnan(data2[i])){ + data1[i] = data2[i]; + }else{ + data1[i] = (data1[i] > data2[i] ? data1[i] : data2[i]); + } + } + TRACEOUT(("SSE2_MAXPD")); +} +void SSE2_MAXSD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + if(isnan(data1[0]) || isnan(data2[0])){ + data1[0] = data2[0]; + }else{ + data1[0] = (data1[0] > data2[0] ? data1[0] : data2[0]); + } + TRACEOUT(("SSE2_MAXSD")); +} +void SSE2_MINPD(void) +{ + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + if(isnan(data1[i]) || isnan(data2[i])){ + data1[i] = data2[i]; + }else{ + data1[i] = (data1[i] < data2[i] ? data1[i] : data2[i]); + } + } + TRACEOUT(("SSE2_MINPD")); +} +void SSE2_MINSD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + if(isnan(data1[0]) || isnan(data2[0])){ + data1[0] = data2[0]; + }else{ + data1[0] = (data1[0] < data2[0] ? data1[0] : data2[0]); + } + TRACEOUT(("SSE2_MINSD")); +} +void SSE2_MOVAPDmem2xmm(void) +{ + SSE_MOVAPSmem2xmm(); + TRACEOUT(("SSE2_MOVAPDmem2xmm")); +} +void SSE2_MOVAPDxmm2mem(void) +{ + SSE_MOVAPSxmm2mem(); + TRACEOUT(("SSE2_MOVAPDxmm2mem")); +} +void SSE2_MOVHPDmem2xmm(void) +{ + SSE_MOVHPSmem2xmm(); + TRACEOUT(("SSE2_MOVHPDmem2xmm")); +} +void SSE2_MOVHPDxmm2mem(void) +{ + SSE_MOVHPSxmm2mem(); + TRACEOUT(("SSE2_MOVHPDxmm2mem")); +} +void SSE2_MOVLPDmem2xmm(void) +{ + SSE_MOVLPSmem2xmm(); + TRACEOUT(("SSE2_MOVLPDmem2xmm")); +} +void SSE2_MOVLPDxmm2mem(void) +{ + SSE_MOVLPSxmm2mem(); + TRACEOUT(("SSE2_MOVLPDxmm2mem")); +} +void SSE2_MOVMSKPD(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 *data1; + UINT32 *data2; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = reg32_b53[(op)]; + if ((op) >= 0xc0) { + data2 = (UINT32*)(&(FPU_STAT.xmm_reg[sub])); + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + *data1 = ((data2[1] >> 31) & 0x1)| + ((data2[3] >> 30) & 0x2); + TRACEOUT(("SSE2_MOVMSKPD")); +} +void SSE2_MOVSDmem2xmm(void) +{ + UINT32 op; + UINT idx, sub; + double data2buf[2]; + double *data1, *data2; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT64*)(data2buf+ 0)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 0); + data2 = data2buf; + *(UINT64*)(data1+1) = 0; + } + data1[0] = data2[0]; + TRACEOUT(("SSE2_MOVSDmem2xmm")); +} +void SSE2_MOVSDxmm2mem(void) +{ + UINT32 op; + UINT idx, sub; + double *data1, *data2; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + data2[0] = data1[0]; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_q(CPU_INST_SEGREG_INDEX, madr+ 0, *((UINT64*)(data1+ 0))); + } + TRACEOUT(("SSE2_MOVSDxmm2mem")); +} +void SSE2_MOVUPDmem2xmm(void) +{ + SSE2_MOVAPDmem2xmm(); // エミュレーションではアライメント制限がないのでMOVAPDと同じ + TRACEOUT(("SSE2_MOVUPDmem2xmm")); +} +void SSE2_MOVUPDxmm2mem(void) +{ + SSE2_MOVAPDxmm2mem(); // エミュレーションではアライメント制限がないのでMOVAPDと同じ + TRACEOUT(("SSE2_MOVUPDxmm2mem")); +} +void SSE2_MULPD(void) +{ + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = data1[i] * data2[i]; + } + TRACEOUT(("SSE2_MULPD")); +} +void SSE2_MULSD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + data1[0] = data1[0] * data2[0]; + TRACEOUT(("SSE2_MULSD")); +} +void SSE2_ORPD(void) +{ + SSE_ORPS(); + TRACEOUT(("SSE2_ORPD")); +} +void SSE2_SHUFPD(void) +{ + UINT32 imm8; + double data2buf[2]; + double data1buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + + GET_PCBYTE((imm8)); + + for(i=0;i<2;i++){ + data1buf[i] = data1[i]; + } + data1[0] = data1buf[imm8 & 0x1]; + imm8 = (imm8 >> 1); + data1[1] = data2[imm8 & 0x1]; + TRACEOUT(("SSE2_SHUFPD")); +} +void SSE2_SQRTPD(void) +{ + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = sqrt(data2[i]); + } + TRACEOUT(("SSE2_SQRTPD")); +} +void SSE2_SQRTSD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + data1[0] = sqrt(data2[0]); + TRACEOUT(("SSE2_SQRTSD")); +} +//void SSE2_STMXCSR(UINT32 maddr) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_SUBPD(void) +{ + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = data1[i] - data2[i]; + } + TRACEOUT(("SSE2_SUBPD")); +} +void SSE2_SUBSD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_SD(&data1, &data2, data2buf); + data1[0] = data1[0] - data2[0]; + TRACEOUT(("SSE2_SUBSD")); +} +void SSE2_UCOMISD(void) +{ + SSE_COMISS(); // XXX: とりあえず例外は考えないのでCOMISSと同じ + TRACEOUT(("SSE2_UCOMISD")); +} +void SSE2_UNPCKHPD(void) +{ + double data1buf[2]; + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1buf[i] = data1[i]; + } + data1[0] = data1buf[1]; + data1[1] = data2[1]; + TRACEOUT(("SSE2_UNPCKHPD")); +} +void SSE2_UNPCKLPD(void) +{ + double data1buf[2]; + double data2buf[2]; + double *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1buf[i] = data1[i]; + } + data1[0] = data1buf[0]; + data1[1] = data2[0]; + TRACEOUT(("SSE2_UNPCKLPD")); +} +void SSE2_XORPD(void) +{ + SSE_XORPS(); + TRACEOUT(("SSE2_XORPD")); +} + +void SSE2_MOVDrm2xmm(void) +{ + UINT32 op, src; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + (src) = *(reg32_b20[(op)]); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + (src) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + } + FPU_STAT.xmm_reg[idx].ul32[0] = src; + FPU_STAT.xmm_reg[idx].ul32[1] = FPU_STAT.xmm_reg[idx].ul32[2] = FPU_STAT.xmm_reg[idx].ul32[3] = 0; + TRACEOUT(("SSE2_MOVDrm2xmm")); +} +void SSE2_MOVDxmm2rm(void) +{ + UINT32 op, src, madr; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + src = FPU_STAT.xmm_reg[idx].ul32[0]; + if (op >= 0xc0) { + *(reg32_b20[op]) = src; + } else { + madr = calc_ea_dst(op); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr, src); + } + TRACEOUT(("SSE2_MOVDxmm2rm")); +} +void SSE2_MOVDQAmem2xmm(void) +{ + SSE_MOVAPSmem2xmm(); + TRACEOUT(("SSE2_MOVDQAmem2xmm")); +} +void SSE2_MOVDQAxmm2mem(void) +{ + SSE_MOVAPSxmm2mem(); + TRACEOUT(("SSE2_MOVDQAxmm2mem")); +} +void SSE2_MOVDQUmem2xmm(void) +{ + SSE2_MOVDQAmem2xmm(); // エミュレーションではアライメント制限がないのでMOVDQAと同じ + TRACEOUT(("SSE2_MOVDQUmem2xmm")); +} +void SSE2_MOVDQUxmm2mem(void) +{ + SSE2_MOVDQAxmm2mem(); // エミュレーションではアライメント制限がないのでMOVDQAと同じ + TRACEOUT(("SSE2_MOVDQUxmm2mem")); +} +void SSE2_MOVQ2DQ(void) +{ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.xmm_reg[idx].ul64[0] = FPU_STAT.reg[sub].ll; // idxとsubが逆かも。要検証 + FPU_STAT.xmm_reg[idx].ul64[1] = 0; + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + TRACEOUT(("SSE2_MOVQ2DQ")); +} +void SSE2_MOVDQ2Q(void) +{ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[idx].ll = FPU_STAT.xmm_reg[sub].ul64[0]; // idxとsubが逆かも。要検証 + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + TRACEOUT(("SSE2_MOVDQ2Q")); +} +void SSE2_MOVQmem2xmm(void) +{ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.xmm_reg[idx].ul64[0] = FPU_STAT.xmm_reg[sub].ul64[0]; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + FPU_STAT.xmm_reg[idx].ul64[0] = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, madr); + FPU_STAT.xmm_reg[idx].ul64[1] = 0; + } + TRACEOUT(("SSE2_MOVQmem2xmm")); +} +void SSE2_MOVQxmm2mem(void) +{ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.xmm_reg[sub].ul64[0] = FPU_STAT.xmm_reg[idx].ul64[0]; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + cpu_vmemorywrite_q(CPU_INST_SEGREG_INDEX, madr, FPU_STAT.xmm_reg[idx].ul64[0]); + } + TRACEOUT(("SSE2_MOVQxmm2mem")); +} +void SSE2_PACKSSDW(void) +{ + UINT32 op; + UINT idx, sub; + INT32 srcreg2buf[4]; + INT32 *srcreg1; + INT32 *srcreg2; + INT16 *dstreg; + INT16 dstregbuf[8]; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT32*)(&(FPU_STAT.xmm_reg[idx])); + srcreg2 = (INT32*)(&(FPU_STAT.xmm_reg[sub])); + dstreg = (INT16*)(&(FPU_STAT.xmm_reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+1)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT32*)(&(FPU_STAT.xmm_reg[idx])); + srcreg2 = (INT32*)(&srcreg2buf); + dstreg = (INT16*)(&(FPU_STAT.xmm_reg[idx])); + } + for(i=0;i<4;i++){ + if(srcreg1[i] > 32767){ + dstregbuf[i] = 32767; + }else if(srcreg1[i] < -32768){ + dstregbuf[i] = -32768; + }else{ + dstregbuf[i] = (INT16)(srcreg1[i]); + } + } + for(i=0;i<4;i++){ + if(srcreg2[i] > 32767){ + dstregbuf[i+4] = 32767; + }else if(srcreg2[i] < -32768){ + dstregbuf[i+4] = -32768; + }else{ + dstregbuf[i+4] = (INT16)(srcreg2[i]); + } + } + for(i=0;i<8;i++){ + dstreg[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PACKSSDW")); +} +void SSE2_PACKSSWB(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcreg2buf[8]; + INT16 *srcreg1; + INT16 *srcreg2; + INT8 *dstreg; + INT8 dstregbuf[16]; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT16*)(&(FPU_STAT.xmm_reg[idx])); + srcreg2 = (INT16*)(&(FPU_STAT.xmm_reg[sub])); + dstreg = (INT8*)(&(FPU_STAT.xmm_reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT16*)(&(FPU_STAT.xmm_reg[idx])); + srcreg2 = (INT16*)(&srcreg2buf); + dstreg = (INT8*)(&(FPU_STAT.xmm_reg[idx])); + } + for(i=0;i<8;i++){ + if(srcreg1[i] > 127){ + dstregbuf[i] = 127; + }else if(srcreg1[i] < -128){ + dstregbuf[i] = -128; + }else{ + dstregbuf[i] = (INT8)(srcreg1[i]); + } + } + for(i=0;i<8;i++){ + if(srcreg2[i] > 127){ + dstregbuf[i+8] = 127; + }else if(srcreg2[i] < -128){ + dstregbuf[i+8] = -128; + }else{ + dstregbuf[i+8] = (INT8)(srcreg2[i]); + } + } + for(i=0;i<16;i++){ + dstreg[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PACKSSWB")); +} +void SSE2_PACKUSWB(void) +{ + UINT32 op; + UINT idx, sub; + INT16 srcreg2buf[8]; + INT16 *srcreg1; + INT16 *srcreg2; + UINT8 *dstreg; + UINT8 dstregbuf[16]; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + srcreg1 = (INT16*)(&(FPU_STAT.xmm_reg[idx])); + srcreg2 = (INT16*)(&(FPU_STAT.xmm_reg[sub])); + dstreg = (UINT8*)(&(FPU_STAT.xmm_reg[idx])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(srcreg2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(srcreg2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + srcreg1 = (INT16*)(&(FPU_STAT.xmm_reg[idx])); + srcreg2 = (INT16*)(&srcreg2buf); + dstreg = (UINT8*)(&(FPU_STAT.xmm_reg[idx])); + } + for(i=0;i<8;i++){ + if(srcreg1[i] > 255){ + dstregbuf[i] = 255; + }else if(srcreg1[i] < 0){ + dstregbuf[i] = 0; + }else{ + dstregbuf[i] = (UINT8)(srcreg1[i]); + } + } + for(i=0;i<8;i++){ + if(srcreg2[i] > 255){ + dstregbuf[i+8] = 255; + }else if(srcreg2[i] < 0){ + dstregbuf[i+8] = 0; + }else{ + dstregbuf[i+8] = (UINT8)(srcreg2[i]); + } + } + for(i=0;i<16;i++){ + dstreg[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PACKUSWB")); +} +void SSE2_PADDQmm(void) +{ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[idx].ll += FPU_STAT.reg[sub].ll; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + FPU_STAT.reg[idx].ll += (SINT64)cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, madr); + } + TRACEOUT(("SSE2_PADDQmm")); +} +void SSE2_PADDQxmm(void) +{ + UINT64 data2buf[2]; + UINT64 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = data1[i] + data2[i]; + } + TRACEOUT(("SSE2_PADDQxmm")); +} +void SSE2_PADDB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + data1[i] = data1[i] + data2[i]; + } + TRACEOUT(("SSE2_PADDB")); +} +void SSE2_PADDW(void) +{ + UINT16 data2buf[8]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + data1[i] = data1[i] + data2[i]; + } + TRACEOUT(("SSE2_PADDW")); +} +void SSE2_PADDD(void) +{ + UINT32 data2buf[4]; + UINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<4;i++){ + data1[i] = data1[i] + data2[i]; + } + TRACEOUT(("SSE2_PADDD")); +} +//void SSE2_PADDQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PADDSB(void) +{ + SINT8 data2buf[16]; + SINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + SINT16 cbuf = (SINT16)data1[i] + (SINT16)data2[i]; + if(cbuf > 127){ + data1[i] = 127; + }else if(cbuf < -128){ + data1[i] = -128; + }else{ + data1[i] = (SINT8)cbuf; + } + } + TRACEOUT(("SSE2_PADDSB")); +} +void SSE2_PADDSW(void) +{ + SINT16 data2buf[8]; + SINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + SINT32 cbuf = (SINT32)data1[i] + (SINT32)data2[i]; + if(cbuf > 32767){ + data1[i] = 32767; + }else if(cbuf < -32768){ + data1[i] = -32768; + }else{ + data1[i] = (SINT16)cbuf; + } + } + TRACEOUT(("SSE2_PADDSW")); +} +//void SSE2_PADDSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PADDSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PADDUSB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + UINT16 cbuf = (UINT16)data1[i] + (UINT16)data2[i]; + if(cbuf > 255){ + data1[i] = 255; + }else{ + data1[i] = (UINT8)cbuf; + } + } + TRACEOUT(("SSE2_PADDUSB")); +} +void SSE2_PADDUSW(void) +{ + UINT16 data2buf[8]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + UINT32 cbuf = (UINT32)data1[i] + (UINT32)data2[i]; + if(cbuf > 65535){ + data1[i] = 65535; + }else{ + data1[i] = (UINT16)cbuf; + } + } + TRACEOUT(("SSE2_PADDUSW")); +} +//void SSE2_PADDUSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PADDUSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PAND(void) +{ + SSE_ANDPS(); + TRACEOUT(("SSE2_PAND")); +} +void SSE2_PANDN(void) +{ + SSE_ANDNPS(); + TRACEOUT(("SSE2_PANDN")); +} +void SSE2_PAVGB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + data1[i] = (UINT8)(((UINT16)data1[i] + (UINT16)data2[i] + 1) / 2); + } + TRACEOUT(("SSE2_PAVGB")); +} +void SSE2_PAVGW(void) +{ + UINT16 data2buf[8]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + data1[i] = (UINT16)(((UINT32)data1[i] + (UINT32)data2[i] + 1) / 2); + } + TRACEOUT(("SSE2_PAVGW")); +} +void SSE2_PCMPEQB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + data1[i] = (data1[i] == data2[i] ? 0xff : 0x00); + } + TRACEOUT(("SSE2_PCMPEQB")); +} +void SSE2_PCMPEQW(void) +{ + UINT16 data2buf[8]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + data1[i] = (data1[i] == data2[i] ? 0xffff : 0x00); + } + TRACEOUT(("SSE2_PCMPEQW")); +} +void SSE2_PCMPEQD(void) +{ + UINT32 data2buf[4]; + UINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<4;i++){ + data1[i] = (data1[i] == data2[i] ? 0xffffffff : 0x00); + } + TRACEOUT(("SSE2_PCMPEQD")); +} +//void SSE2_PCMPEQQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PCMPGTB(void) +{ + SINT8 data2buf[16]; + SINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + data1[i] = (data1[i] > data2[i] ? 0xff : 0x00); + } + TRACEOUT(("SSE2_PCMPGTB")); +} +void SSE2_PCMPGTW(void) +{ + SINT16 data2buf[8]; + SINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + data1[i] = (data1[i] > data2[i] ? 0xffff : 0x00); + } + TRACEOUT(("SSE2_PCMPGTW")); +} +void SSE2_PCMPGTD(void) +{ + SINT32 data2buf[4]; + SINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<4;i++){ + data1[i] = (data1[i] > data2[i] ? 0xffffffff : 0x00); + } + TRACEOUT(("SSE2_PCMPGTD")); +} +//void SSE2_PCMPGTQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PEXTRW(void) +{ + UINT32 imm8; + UINT32 op; + UINT idx, sub; + UINT32 *data1; + UINT16 *data2; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT32*)reg32_b53[(op)]; + if ((op) >= 0xc0) { + data2 = (UINT16*)(&(FPU_STAT.xmm_reg[sub])); + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + GET_PCBYTE((imm8)); + *data1 = (UINT32)data2[imm8 & 0x7]; + TRACEOUT(("SSE2_PEXTRW")); +} +void SSE2_PINSRW(void) +{ + UINT32 imm8; + UINT32 op; + UINT idx, sub; + UINT16 *data1; + UINT16 data2; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT16*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (UINT16)((*reg32_b20[(op)]) & 0xffff); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + data2 = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, maddr+ 0); + } + GET_PCBYTE((imm8)); + data1[imm8 & 0x7] = data2; + TRACEOUT(("SSE2_PINSRW")); +} +void SSE2_PMADD(void) +{ + SINT16 data2buf[8]; + SINT16 *data1, *data2; + SINT32 data1dbuf[4]; + SINT32 *data1d; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + data1d = (SINT32*)data1; + + data1dbuf[0] = (INT32)data2[0] * (INT32)data1[0] + (INT32)data2[1] * (INT32)data1[1]; + data1dbuf[1] = (INT32)data2[2] * (INT32)data1[2] + (INT32)data2[3] * (INT32)data1[3]; + data1dbuf[2] = (INT32)data2[4] * (INT32)data1[4] + (INT32)data2[5] * (INT32)data1[5]; + data1dbuf[3] = (INT32)data2[6] * (INT32)data1[6] + (INT32)data2[7] * (INT32)data1[7]; + data1d[0] = data1dbuf[0]; + data1d[1] = data1dbuf[1]; + data1d[2] = data1dbuf[2]; + data1d[3] = data1dbuf[3]; + TRACEOUT(("SSE2_PMADD")); +} +void SSE2_PMAXSW(void) +{ + SINT16 data2buf[8]; + SINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + data1[i] = (data1[i] > data2[i] ? data1[i] : data2[i]); + } + TRACEOUT(("SSE2_PMAXSW")); +} +void SSE2_PMAXUB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + data1[i] = (data1[i] > data2[i] ? data1[i] : data2[i]); + } + TRACEOUT(("SSE2_PMAXUB")); +} +void SSE2_PMINSW(void) +{ + SINT16 data2buf[8]; + SINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + data1[i] = (data1[i] < data2[i] ? data1[i] : data2[i]); + } + TRACEOUT(("SSE2_PMINSW")); +} +void SSE2_PMINUB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + data1[i] = (data1[i] < data2[i] ? data1[i] : data2[i]); + } + TRACEOUT(("SSE2_PMINUB")); +} +void SSE2_PMOVMSKB(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 *data1; + UINT8 *data2; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT32*)reg32_b53[(op)]; + if ((op) >= 0xc0) { + data2 = (UINT8*)(&(FPU_STAT.reg[sub])); + } else { + EXCEPTION(UD_EXCEPTION, 0); + } + *data1 = ((UINT32)(data2[0] >> 7) & 0x1 )| + ((UINT32)(data2[1] >> 6) & 0x2 )| + ((UINT32)(data2[2] >> 5) & 0x4 )| + ((UINT32)(data2[3] >> 4) & 0x8 )| + ((UINT32)(data2[4] >> 3) & 0x10)| + ((UINT32)(data2[5] >> 2) & 0x20)| + ((UINT32)(data2[6] >> 1) & 0x40)| + ((UINT32)(data2[7] >> 0) & 0x80)| + (((UINT32)(data2[8] >> 7) & 0x1 ) << 8)| + (((UINT32)(data2[9] >> 6) & 0x2 ) << 8)| + (((UINT32)(data2[10]>> 5) & 0x4 ) << 8)| + (((UINT32)(data2[11]>> 4) & 0x8 ) << 8)| + (((UINT32)(data2[12]>> 3) & 0x10) << 8)| + (((UINT32)(data2[13]>> 2) & 0x20) << 8)| + (((UINT32)(data2[14]>> 1) & 0x40) << 8)| + (((UINT32)(data2[15]>> 0) & 0x80) << 8); + TRACEOUT(("SSE2_PMOVMSKB")); +} +void SSE2_PMULHUW(void) +{ + UINT32 op; + UINT idx, sub; + UINT16 data2buf[8]; + UINT16 *data1, *data2; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (UINT16*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (UINT16*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(data2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + *((UINT32*)(data2buf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+8); + *((UINT32*)(data2buf+6)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+12); + data2 = data2buf; + } + for(i=0;i<8;i++){ + data1[i] = (UINT16)((((UINT32)data2[i] * (UINT32)data1[i]) >> 16) & 0xffff); + } + TRACEOUT(("SSE2_PMULHUW")); +} +void SSE2_PMULHW(void) +{ + UINT32 op; + UINT idx, sub; + SINT16 data2buf[8]; + SINT16 *data1, *data2; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (SINT16*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (SINT16*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(data2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + *((UINT32*)(data2buf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+8); + *((UINT32*)(data2buf+6)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+12); + data2 = data2buf; + } + for(i=0;i<8;i++){ + data1[i] = (SINT16)((((SINT32)data2[i] * (SINT32)data1[i]) >> 16) & 0xffff); + } + TRACEOUT(("SSE2_PMULHW")); +} +void SSE2_PMULLW(void) +{ + UINT32 op; + UINT idx, sub; + SINT16 data2buf[8]; + SINT16 *data1, *data2; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = (SINT16*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + data2 = (SINT16*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT32*)(data2buf+0)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr); + *((UINT32*)(data2buf+2)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+4); + *((UINT32*)(data2buf+4)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+8); + *((UINT32*)(data2buf+6)) = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, maddr+12); + data2 = data2buf; + } + for(i=0;i<8;i++){ + data1[i] = (SINT16)((((SINT32)data2[i] * (SINT32)data1[i])) & 0xffff); + } + TRACEOUT(("SSE2_PMULLW")); +} +void SSE2_PMULUDQmm(void) +{ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[idx].ll = ((UINT64)FPU_STAT.reg[idx].l.lower * (UINT64)FPU_STAT.reg[sub].l.lower); + } else { + UINT32 madr; + madr = calc_ea_dst(op); + FPU_STAT.reg[idx].ll = ((UINT64)FPU_STAT.reg[idx].l.lower * (cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, madr) & 0xffffffff)); + } + TRACEOUT(("SSE2_PMULUDQmm")); +} +void SSE2_PMULUDQxmm(void) +{ + UINT64 data2buf[2]; + UINT64 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = (data1[i] & 0xffffffff) * (data2[i] & 0xffffffff); + } + TRACEOUT(("SSE2_PMULUDQxmm")); +} +void SSE2_POR(void) +{ + SSE_ORPS(); + TRACEOUT(("SSE2_POR")); +} +void SSE2_PSADBW(void) +{ + SINT16 temp1; + UINT16 temp; + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + temp = 0; + for(i=0;i<8;i++){ + temp1 = (SINT16)data2[i] - (SINT16)data1[i]; + temp += (UINT16)(temp1 < 0 ? -temp1 : temp1); + } + *((UINT16*)data2 + 0) = temp; + *((UINT16*)data2 + 1) = 0; + *((UINT16*)data2 + 2) = 0; + *((UINT16*)data2 + 3) = 0; + + temp = 0; + for(i=8;i<16;i++){ + temp1 = (SINT16)data2[i] - (SINT16)data1[i]; + temp += (UINT16)(temp1 < 0 ? -temp1 : temp1); + } + *((UINT16*)data2 + 4) = temp; + *((UINT16*)data2 + 5) = 0; + *((UINT16*)data2 + 6) = 0; + *((UINT16*)data2 + 7) = 0; + TRACEOUT(("SSE2_PSADBW")); +} +void SSE2_PSHUFLW(void) +{ + UINT32 imm8; + UINT16 data2buf[8]; + UINT16 *data1, *data2; + UINT16 dstbuf[8]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + GET_PCBYTE((imm8)); + for(i=0;i<4;i++){ + dstbuf[i] = data2[imm8 & 0x3]; + imm8 = imm8 >> 2; + } + for(i=0;i<4;i++){ + data1[i] = dstbuf[i]; + } + for(i=4;i<8;i++){ + data1[i] = data2[i]; + } + TRACEOUT(("SSE2_PSHUFLW")); +} +void SSE2_PSHUFHW(void) +{ + UINT32 imm8; + UINT16 data2buf[8]; + UINT16 *data1, *data2; + UINT16 dstbuf[8]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + GET_PCBYTE((imm8)); + for(i=0;i<4;i++){ + data1[i] = data2[i]; + } + for(i=4;i<8;i++){ + dstbuf[i] = data2[4 + (imm8 & 0x3)]; + imm8 = imm8 >> 2; + } + for(i=4;i<8;i++){ + data1[i] = dstbuf[i]; + } + TRACEOUT(("SSE2_PSHUFHW")); +} +void SSE2_PSHUFD(void) +{ + UINT32 imm8; + UINT32 data2buf[4]; + UINT32 *data1, *data2; + UINT32 dstbuf[4]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + GET_PCBYTE((imm8)); + for(i=0;i<4;i++){ + dstbuf[i] = data2[imm8 & 0x3]; + imm8 = imm8 >> 2; + } + for(i=0;i<4;i++){ + data1[i] = dstbuf[i]; + } + TRACEOUT(("SSE2_PSHUFD")); +} +//void SSE2_PSLLDQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSLLB(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSLLW(void) +{ + UINT32 data2buf[4]; + UINT16 *data1; + UINT32 *data2; + UINT32 shift; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + for(i=0;i<8;i++){ + data1[i] = (shift >= 16 ? 0 : (data1[i] << (UINT16)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + TRACEOUT(("SSE2_PSLLW")); +} +void SSE2_PSLLD(void) +{ + UINT32 data2buf[4]; + UINT32 *data1; + UINT32 *data2; + UINT32 shift; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + for(i=0;i<4;i++){ + data1[i] = (shift >= 32 ? 0 : (data1[i] << (UINT32)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + TRACEOUT(("SSE2_PSLLD")); +} +void SSE2_PSLLQ(void) +{ + UINT32 data2buf[4]; + UINT64 *data1; + UINT32 *data2; + UINT32 shift; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + for(i=0;i<2;i++){ + data1[i] = (shift >= 64 ? 0 : (data1[i] << (UINT64)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + TRACEOUT(("SSE2_PSLLQ")); +} +//void SSE2_PSLLBimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSLLWimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSLLDimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSLLQimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRAB(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSRAW(void) +{ + UINT32 data2buf[4]; + UINT16 *data1; + UINT32 *data2; + UINT32 shift; + UINT16 signval; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + // 無理やり算術シフト(怪しい) + if(16 <= shift){ + signval = 0xffff; + }else{ + UINT32 rshift = 16 - shift; + signval = (0xffff >> rshift) << rshift; + } + for(i=0;i<8;i++){ + if(((INT16*)data1)[i] < 0){ + data1[i] = (data1[i] >> shift) | signval; + }else{ + data1[i] = (shift >= 16 ? 0 : (data1[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + TRACEOUT(("SSE2_PSRAW")); +} +void SSE2_PSRAD(void) +{ + UINT32 data2buf[4]; + UINT32 *data1; + UINT32 *data2; + UINT32 shift; + UINT32 signval; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + // 無理やり算術シフト(怪しい) + if(32 <= shift){ + signval = 0xffffffff; + }else{ + UINT32 rshift = 32 - shift; + signval = (0xffffffff >> rshift) << rshift; + } + for(i=0;i<2;i++){ + if(((INT32*)data1)[i] < 0){ + data1[i] = (data1[i] >> shift) | signval; + }else{ + data1[i] = (shift >= 32 ? 0 : (data1[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + TRACEOUT(("SSE2_PSRAD")); +} +//void SSE2_PSRAQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRABimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRAWimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRADimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRAQimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRLDQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRLB(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSRLW(void) +{ + UINT32 data2buf[4]; + UINT16 *data1; + UINT32 *data2; + UINT32 shift; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + for(i=0;i<8;i++){ + data1[i] = (shift >= 16 ? 0 : (data1[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + TRACEOUT(("SSE2_PSRLW")); +} +void SSE2_PSRLD(void) +{ + UINT32 data2buf[4]; + UINT32 *data1; + UINT32 *data2; + UINT32 shift; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + for(i=0;i<4;i++){ + data1[i] = (shift >= 32 ? 0 : (data1[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + TRACEOUT(("SSE2_PSRLD")); +} +void SSE2_PSRLQ(void) +{ + UINT32 data2buf[4]; + UINT64 *data1; + UINT32 *data2; + UINT32 shift; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + shift = data2[0]; + if(data2[1] || data2[2] || data2[3]) shift = 0xffffffff; // XXX: とりあえずレジスタ内容が消えるくらい大きなシフト量にしておく + + for(i=0;i<2;i++){ + data1[i] = (shift >= 64 ? 0 : (data1[i] >> (UINT64)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + TRACEOUT(("SSE2_PSRLQ")); +} +//void SSE2_PSRLBimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRLWimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRLDimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSRLQimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSxxWimm(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT16 *dstreg; + UINT16 signval; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT16*)(&(FPU_STAT.xmm_reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLW(imm8) + for(i=0;i<8;i++){ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + break; + case 4: // PSRAW(imm8) + // 無理やり算術シフト(怪しい) + if(16 <= shift){ + signval = 0xffff; + }else{ + UINT32 rshift = 16 - shift; + signval = (0xffff >> rshift) << rshift; + } + for(i=0;i<8;i++){ + if(((INT16*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + break; + case 6: // PSLLW(imm8) + for(i=0;i<8;i++){ + dstreg[i] = (shift >= 16 ? 0 : (dstreg[i] << (UINT16)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + break; + default: + break; + } + TRACEOUT(("SSE2_PSxxWimm")); +} +void SSE2_PSxxDimm(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT32 *dstreg; + UINT32 signval; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT32*)(&(FPU_STAT.xmm_reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLD(imm8) + for(i=0;i<4;i++){ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT32)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + break; + case 4: // PSRAD(imm8) + // 無理やり算術シフト(怪しい) + if(32 <= shift){ + signval = 0xffffffff; + }else{ + UINT32 rshift = 32 - shift; + signval = (0xffffffff >> rshift) << rshift; + } + for(i=0;i<4;i++){ + if(((INT32*)dstreg)[i] < 0){ + dstreg[i] = (dstreg[i] >> shift) | signval; + }else{ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] >> (UINT16)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + } + break; + case 6: // PSLLD(imm8) + for(i=0;i<4;i++){ + dstreg[i] = (shift >= 32 ? 0 : (dstreg[i] << (UINT32)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + break; + default: + break; + } + TRACEOUT(("SSE2_PSxxDimm")); +} +void SSE2_PSxxQimm(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 shift; + UINT64 *dstreg; + int i; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + dstreg = (UINT64*)(&(FPU_STAT.xmm_reg[sub])); + GET_PCBYTE((shift)); + + switch(idx){ + case 2: // PSRLQ(imm8) + for(i=0;i<2;i++){ + dstreg[i] = (shift >= 64 ? 0 : (dstreg[i] >> (UINT64)shift)); // XXX: LSBが取り残されるのでごまかし(環境依存?) + } + break; + case 3: // PSRLDQ + // 無理やり128bit右シフト 怪しいので要検証 + shift *= 8; // シフト量はバイト数で指定 + if(shift == 0){ + // シフト無しなら何もしない + }else if(shift >= 128){ + // シフトが128以上の時 + dstreg[0] = dstreg[1] = 0; + }else if(shift >= 64){ + // シフトが64以上の時 + dstreg[0] = dstreg[1] >> (shift - 64); + dstreg[1] = 0; + }else{ + // シフトが64より小さい時 + dstreg[0] = (dstreg[0] >> shift) | (dstreg[1] << (64-shift)); // 下位QWORD右シフト&上から降りてきたビットをOR + dstreg[1] = (dstreg[1] >> shift); + } + break; + case 4: // PSRAQ(imm8) + EXCEPTION(UD_EXCEPTION, 0); + break; + case 6: // PSLLQ(imm8) + for(i=0;i<2;i++){ + dstreg[i] = (shift >= 64 ? 0 : (dstreg[i] << (UINT64)shift)); // XXX: MSBが取り残されるのでごまかし(環境依存?) + } + break; + case 7: // PSLLDQ + // 無理やり128bit左シフト 怪しいので要検証 + shift *= 8; // シフト量はバイト数で指定 + if(shift == 0){ + // シフト無しなら何もしない + }else if(shift >= 128){ + // シフトが128以上の時 + dstreg[0] = dstreg[1] = 0; + }else if(shift >= 64){ + // シフトが64以上の時 + dstreg[1] = dstreg[0] << (shift - 64); + dstreg[0] = 0; + }else{ + // シフトが64より小さい時 + dstreg[1] = (dstreg[1] << shift) | (dstreg[0] >> (64-shift)); // 上位QWORD左シフト&下から上がってきたビットをOR + dstreg[0] = (dstreg[0] << shift); + } + break; + default: + break; + } + TRACEOUT(("SSE2_PSxxQimm")); +} +void SSE2_PSUBQmm(void) +{ + UINT32 op; + UINT idx, sub; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + MMX_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.reg[idx].ll -= FPU_STAT.reg[sub].ll; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + FPU_STAT.reg[idx].ll -= (SINT64)cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, madr); + } + TRACEOUT(("SSE2_PSUBQmm")); +} +void SSE2_PSUBQxmm(void) +{ + UINT64 data2buf[2]; + UINT64 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64(&data1, &data2, data2buf); + for(i=0;i<2;i++){ + data1[i] = data1[i] - data2[i]; + } + TRACEOUT(("SSE2_PSUBQxmm")); +} +void SSE2_PSUBB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + data1[i] = data1[i] - data2[i]; + } + TRACEOUT(("SSE2_PSUBB")); +} +void SSE2_PSUBW(void) +{ + UINT16 data2buf[8]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + data1[i] = data1[i] - data2[i]; + } + TRACEOUT(("SSE2_PSUBW")); +} +void SSE2_PSUBD(void) +{ + UINT32 data2buf[4]; + UINT32 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<4;i++){ + data1[i] = data1[i] - data2[i]; + } + TRACEOUT(("SSE2_PSUBD")); +} +//void SSE2_PSUBQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSUBSB(void) +{ + SINT8 data2buf[16]; + SINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + SINT16 cbuf = (SINT16)data1[i] - (SINT16)data2[i]; + if(cbuf > 127){ + data1[i] = 127; + }else if(cbuf < -128){ + data1[i] = -128; + }else{ + data1[i] = (SINT8)cbuf; + } + } + TRACEOUT(("SSE2_PSUBSB")); +} +void SSE2_PSUBSW(void) +{ + SINT16 data2buf[8]; + SINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + SINT32 cbuf = (SINT32)data1[i] - (SINT32)data2[i]; + if(cbuf > 32767){ + data1[i] = 32767; + }else if(cbuf < -32768){ + data1[i] = -32768; + }else{ + data1[i] = (SINT16)cbuf; + } + } + TRACEOUT(("SSE2_PSUBSW")); +} +//void SSE2_PSUBSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSUBSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSUBUSB(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + SINT16 cbuf = (SINT16)data1[i] - (SINT16)data2[i]; + if(cbuf > 255){ + data1[i] = 255; + }else if(cbuf < 0){ + data1[i] = 0; + }else{ + data1[i] = (UINT8)cbuf; + } + } + TRACEOUT(("SSE2_PSUBUSB")); +} +void SSE2_PSUBUSW(void) +{ + UINT16 data2buf[8]; + UINT16 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<8;i++){ + SINT32 cbuf = (SINT32)data1[i] - (SINT32)data2[i]; + if(cbuf > 65535){ + data1[i] = 65535; + }else if(cbuf < 0){ + data1[i] = 0; + }else{ + data1[i] = (UINT16)cbuf; + } + } + TRACEOUT(("SSE2_PSUBUSW")); +} +//void SSE2_PSUBUSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSUBUSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PUNPCKHBW(void) +{ + UINT8 data2buf[16]; + UINT8 *data1; + UINT8 *data2; + UINT8 dstregbuf[16]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + for(i=0;i<8;i++){ + dstregbuf[i*2] = data1[i+8]; + dstregbuf[i*2 + 1] = data2[i+8]; + } + for(i=0;i<16;i++){ + data1[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PUNPCKHBW")); +} +void SSE2_PUNPCKHWD(void) +{ + UINT16 data2buf[8]; + UINT16 *data1; + UINT16 *data2; + UINT16 dstregbuf[8]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + for(i=0;i<4;i++){ + dstregbuf[i*2] = data1[i+4]; + dstregbuf[i*2 + 1] = data2[i+4]; + } + for(i=0;i<8;i++){ + data1[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PUNPCKHWD")); +} +void SSE2_PUNPCKHDQ(void) +{ + UINT32 data2buf[4]; + UINT32 *data1; + UINT32 *data2; + UINT32 dstregbuf[4]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + for(i=0;i<2;i++){ + dstregbuf[i*2] = data1[i+2]; + dstregbuf[i*2 + 1] = data2[i+2]; + } + for(i=0;i<4;i++){ + data1[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PUNPCKHDQ")); +} +void SSE2_PUNPCKHQDQ(void) +{ + UINT64 data2buf[2]; + UINT64 *data1; + UINT64 *data2; + UINT64 dstregbuf[2]; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + dstregbuf[0] = data1[1]; + dstregbuf[1] = data2[1]; + data1[0] = dstregbuf[0]; + data1[1] = dstregbuf[1]; + TRACEOUT(("SSE2_PUNPCKHQDQ")); +} +void SSE2_PUNPCKLBW(void) +{ + UINT8 data2buf[16]; + UINT8 *data1; + UINT8 *data2; + UINT8 dstregbuf[16]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + for(i=0;i<8;i++){ + dstregbuf[i*2] = data1[i]; + dstregbuf[i*2 + 1] = data2[i]; + } + for(i=0;i<16;i++){ + data1[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PUNPCKLBW")); +} +void SSE2_PUNPCKLWD(void) +{ + UINT16 data2buf[8]; + UINT16 *data1; + UINT16 *data2; + UINT16 dstregbuf[8]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + for(i=0;i<4;i++){ + dstregbuf[i*2] = data1[i]; + dstregbuf[i*2 + 1] = data2[i]; + } + for(i=0;i<8;i++){ + data1[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PUNPCKLWD")); +} +void SSE2_PUNPCKLDQ(void) +{ + UINT32 data2buf[4]; + UINT32 *data1; + UINT32 *data2; + UINT32 dstregbuf[4]; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + for(i=0;i<2;i++){ + dstregbuf[i*2] = data1[i]; + dstregbuf[i*2 + 1] = data2[i]; + } + for(i=0;i<4;i++){ + data1[i] = dstregbuf[i]; + } + TRACEOUT(("SSE2_PUNPCKLDQ")); +} +void SSE2_PUNPCKLQDQ(void) +{ + UINT64 data2buf[2]; + UINT64 *data1; + UINT64 *data2; + UINT64 dstregbuf[2]; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + + dstregbuf[0] = data1[0]; + dstregbuf[1] = data2[0]; + data1[0] = dstregbuf[0]; + data1[1] = dstregbuf[1]; + TRACEOUT(("SSE2_PUNPCKLQDQ")); +} +void SSE2_PXOR(void) +{ + SSE_XORPS(); + TRACEOUT(("SSE2_PXOR")); +} + +void SSE2_MASKMOVDQU(void) +{ + UINT8 data2buf[16]; + UINT8 *data1, *data2; + int i; + + SSE_PART_GETDATA1DATA2_PD_UINT64((UINT64**)(&data1), (UINT64**)(&data2), (UINT64*)data2buf); + for(i=0;i<16;i++){ + if (!CPU_INST_AS32) { + if(data2[i] & 0x80){ + cpu_vmemorywrite(CPU_DS_INDEX, CPU_DI, data1[i]); + } + CPU_DI += 1; + } else { + if(data2[i] & 0x80){ + cpu_vmemorywrite(CPU_DS_INDEX, CPU_EDI, data1[i]); + } + CPU_EDI += 1; + } + } + // 戻す + if (!CPU_INST_AS32) { + CPU_DI -= 16; + } else { + CPU_EDI -= 16; + } + TRACEOUT(("SSE2_MASKMOVDQU")); +} +//void SSE2_CLFLUSH(UINT32 op) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_MOVNTPD(void) +{ + SSE_MOVNTPS(); + TRACEOUT(("SSE2_MOVNTPD")); +} +void SSE2_MOVNTDQ(void) +{ + SSE_MOVNTPS(); + TRACEOUT(("SSE2_MOVNTDQ")); +} +void SSE2_MOVNTI(void) +{ + UINT32 op; + UINT idx, sub; + UINT32 *data1; + + SSE2_check_NM_EXCEPTION(); + SSE2_setTag(); + CPU_SSE2WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + data1 = reg32_b53[(op)]; // これ合ってる? + if ((op) >= 0xc0) { + EXCEPTION(UD_EXCEPTION, 0); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, maddr, *data1); + } + TRACEOUT(("SSE2_MOVNTI")); +} +void SSE2_PAUSE(void) +{ + // Nothing to do + TRACEOUT(("SSE2_PAUSE")); +} +//void SSE2_LFENCE(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_MFENCE(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} + +#else + +/* + * SSE2 interface + */ + +void SSE2_ADDPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_ADDSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_ANDNPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_ANDPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CMPPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CMPSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_COMISD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTPI2PD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTPD2PI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTSI2SD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTSD2SI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTTPD2PI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTTSD2SI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTPD2PS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTPS2PD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTSD2SS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTSS2SD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTPD2DQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTTPD2DQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTDQ2PD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTPS2DQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTTPS2DQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_CVTDQ2PS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_DIVPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_DIVSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MAXPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MAXSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MINPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MINSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVAPDmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVAPDxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVHPDmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVHPDxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVLPDmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVLPDxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVMSKPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVSDmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVSDxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVUPDmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVUPDxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MULPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MULSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_ORPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_SHUFPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_SQRTPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_SQRTSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_STMXCSR(UINT32 maddr) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_SUBPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_SUBSD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_UCOMISD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_UNPCKHPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_UNPCKLPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_XORPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void SSE2_MOVDrm2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVDxmm2rm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVDQAmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVDQAxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVDQUmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVDQUxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVQ2DQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVDQ2Q(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVQmem2xmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVQxmm2mem(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PACKSSDW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PACKSSWB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PACKUSWB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PADDQmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PADDQxmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PADDB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PADDW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PADDD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PADDQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PADDSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PADDSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PADDSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PADDSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PADDUSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PADDUSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PADDUSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PADDUSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PAND(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PANDN(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PAVGB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PAVGW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PCMPEQB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PCMPEQW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PCMPEQD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PCMPEQQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PCMPGTB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PCMPGTW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PCMPGTD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PCMPGTQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PEXTRW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PINSRW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMADD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMAXSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMAXUB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMINSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMINUB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMOVMSKB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMULHUW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMULHW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMULLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMULUDQmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PMULUDQxmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_POR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSADBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSHUFLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSHUFHW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSHUFD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSLLDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSLLB(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSLLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSLLD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSLLQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSLLBimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSLLWimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSLLDimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSLLQimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSRAB(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSRAW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRAD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRAQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSRABimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSRAWimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRADimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRAQimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRLDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSRLB(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSRLW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRLD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRLQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSRLBimm(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSRLWimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRLDimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSRLQimm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSUBQmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSUBQxmm(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSUBB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSUBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSUBD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSUBQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSUBSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSUBSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSUBSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSUBSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PSUBUSB(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PSUBUSW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_PSUBUSD(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_PSUBUSQ(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_PUNPCKHBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PUNPCKHWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PUNPCKHDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PUNPCKHQDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PUNPCKLBW(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PUNPCKLWD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PUNPCKLDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PUNPCKLQDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PXOR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void SSE2_MASKMOVDQU(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_CLFLUSH(UINT32 op) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE2_MOVNTPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVNTDQ(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_MOVNTI(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE2_PAUSE(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +//void SSE2_LFENCE(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +//void SSE2_MFENCE(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} + + +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/sse2/sse2.h b/source/src/vm/np21/i386c/ia32/instructions/sse2/sse2.h new file mode 100644 index 000000000..de9e827e8 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/sse2/sse2.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SSE2_SSE2_H__ +#define IA32_CPU_INSTRUCTION_SSE2_SSE2_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +float SSE2_ROUND_FLOAT(float val); +double SSE2_ROUND_DOUBLE(double val); + +void SSE2_ADDPD(void); +void SSE2_ADDSD(void); +void SSE2_ANDNPD(void); +void SSE2_ANDPD(void); +void SSE2_CMPPD(void); +void SSE2_CMPSD(void); +void SSE2_COMISD(void); +void SSE2_CVTPI2PD(void); +void SSE2_CVTPD2PI(void); +void SSE2_CVTSI2SD(void); +void SSE2_CVTSD2SI(void); +void SSE2_CVTTPD2PI(void); +void SSE2_CVTTSD2SI(void); +void SSE2_CVTPD2PS(void); +void SSE2_CVTPS2PD(void); +void SSE2_CVTSD2SS(void); +void SSE2_CVTSS2SD(void); +void SSE2_CVTPD2DQ(void); +void SSE2_CVTTPD2DQ(void); +void SSE2_CVTDQ2PD(void); +void SSE2_CVTPS2DQ(void); +void SSE2_CVTTPS2DQ(void); +void SSE2_CVTDQ2PS(void); +void SSE2_DIVPD(void); +void SSE2_DIVSD(void); +void SSE2_MAXPD(void); +void SSE2_MAXSD(void); +void SSE2_MINPD(void); +void SSE2_MINSD(void); +void SSE2_MOVAPDmem2xmm(void); +void SSE2_MOVAPDxmm2mem(void); +void SSE2_MOVHPDmem2xmm(void); +void SSE2_MOVHPDxmm2mem(void); +void SSE2_MOVLPDmem2xmm(void); +void SSE2_MOVLPDxmm2mem(void); +void SSE2_MOVMSKPD(void); +void SSE2_MOVSDmem2xmm(void); +void SSE2_MOVSDxmm2mem(void); +void SSE2_MOVUPDmem2xmm(void); +void SSE2_MOVUPDxmm2mem(void); +void SSE2_MULPD(void); +void SSE2_MULSD(void); +void SSE2_ORPD(void); +void SSE2_SHUFPD(void); +void SSE2_SQRTPD(void); +void SSE2_SQRTSD(void); +//void SSE2_STMXCSR(UINT32 maddr); // -> SSE_STMXCSRと同じ +void SSE2_SUBPD(void); +void SSE2_SUBSD(void); +void SSE2_UCOMISD(void); +void SSE2_UNPCKHPD(void); +void SSE2_UNPCKLPD(void); +void SSE2_XORPD(void); + +void SSE2_MOVDrm2xmm(void); +void SSE2_MOVDxmm2rm(void); +void SSE2_MOVDQAmem2xmm(void); +void SSE2_MOVDQAxmm2mem(void); +void SSE2_MOVDQUmem2xmm(void); +void SSE2_MOVDQUxmm2mem(void); +void SSE2_MOVQ2DQ(void); +void SSE2_MOVDQ2Q(void); +void SSE2_MOVQmem2xmm(void); +void SSE2_MOVQxmm2mem(void); +void SSE2_PACKSSDW(void); +void SSE2_PACKSSWB(void); +void SSE2_PACKUSWB(void); +void SSE2_PADDQmm(void); +void SSE2_PADDQxmm(void); +void SSE2_PADDB(void); +void SSE2_PADDW(void); +void SSE2_PADDD(void); +//void SSE2_PADDQ(void); +void SSE2_PADDSB(void); +void SSE2_PADDSW(void); +//void SSE2_PADDSD(void); +//void SSE2_PADDSQ(void); +void SSE2_PADDUSB(void); +void SSE2_PADDUSW(void); +//void SSE2_PADDUSD(void); +//void SSE2_PADDUSQ(void); +void SSE2_PAND(void); +void SSE2_PANDN(void); +void SSE2_PAVGB(void); +void SSE2_PAVGW(void); +void SSE2_PCMPEQB(void); +void SSE2_PCMPEQW(void); +void SSE2_PCMPEQD(void); +//void SSE2_PCMPEQQ(void); +void SSE2_PCMPGTB(void); +void SSE2_PCMPGTW(void); +void SSE2_PCMPGTD(void); +//void SSE2_PCMPGTQ(void); +void SSE2_PEXTRW(void); +void SSE2_PINSRW(void); +void SSE2_PMADD(void); +void SSE2_PMAXSW(void); +void SSE2_PMAXUB(void); +void SSE2_PMINSW(void); +void SSE2_PMINUB(void); +void SSE2_PMOVMSKB(void); +void SSE2_PMULHUW(void); +void SSE2_PMULHW(void); +void SSE2_PMULLW(void); +void SSE2_PMULUDQmm(void); +void SSE2_PMULUDQxmm(void); +void SSE2_POR(void); +void SSE2_PSADBW(void); +void SSE2_PSHUFLW(void); +void SSE2_PSHUFHW(void); +void SSE2_PSHUFD(void); +//void SSE2_PSLLDQ(void); +//void SSE2_PSLLB(void); +void SSE2_PSLLW(void); +void SSE2_PSLLD(void); +void SSE2_PSLLQ(void); +//void SSE2_PSLLBimm(void); +//void SSE2_PSLLWimm(void); +//void SSE2_PSLLDimm(void); +//void SSE2_PSLLQimm(void); +//void SSE2_PSRAB(void); +void SSE2_PSRAW(void); +void SSE2_PSRAD(void); +//void SSE2_PSRAQ(void); +//void SSE2_PSRABimm(void); +//void SSE2_PSRAWimm(void); +//void SSE2_PSRADimm(void); +//void SSE2_PSRAQimm(void); +//void SSE2_PSRLDQ(void); +//void SSE2_PSRLB(void); +void SSE2_PSRLW(void); +void SSE2_PSRLD(void); +void SSE2_PSRLQ(void); +//void SSE2_PSRLBimm(void); +//void SSE2_PSRLWimm(void); +//void SSE2_PSRLDimm(void); +//void SSE2_PSRLQimm(void); +void SSE2_PSxxWimm(void); +void SSE2_PSxxDimm(void); +void SSE2_PSxxQimm(void); +void SSE2_PSUBQmm(void); +void SSE2_PSUBQxmm(void); +void SSE2_PSUBB(void); +void SSE2_PSUBW(void); +void SSE2_PSUBD(void); +//void SSE2_PSUBQ(void); +void SSE2_PSUBSB(void); +void SSE2_PSUBSW(void); +//void SSE2_PSUBSD(void); +//void SSE2_PSUBSQ(void); +void SSE2_PSUBUSB(void); +void SSE2_PSUBUSW(void); +//void SSE2_PSUBUSD(void); +//void SSE2_PSUBUSQ(void); +void SSE2_PUNPCKHBW(void); +void SSE2_PUNPCKHWD(void); +void SSE2_PUNPCKHDQ(void); +void SSE2_PUNPCKHQDQ(void); +void SSE2_PUNPCKLBW(void); +void SSE2_PUNPCKLWD(void); +void SSE2_PUNPCKLDQ(void); +void SSE2_PUNPCKLQDQ(void); +void SSE2_PXOR(void); + +void SSE2_MASKMOVDQU(void); +//void SSE2_CLFLUSH(UINT32 op); // --> SSE_CLFLUSH(UINT32 op)へ +void SSE2_MOVNTPD(void); +void SSE2_MOVNTDQ(void); +void SSE2_MOVNTI(void); +void SSE2_PAUSE(void); +//void SSE2_LFENCE(void); // --> SSE_LFENCE(void)へ +//void SSE2_MFENCE(void); // --> SSE_MFENCE(void)へ + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_SSE2_SSE2_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/sse3/sse3.cpp b/source/src/vm/np21/i386c/ia32/instructions/sse3/sse3.cpp new file mode 100644 index 000000000..c6b923acc --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/sse3/sse3.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" + +#include +#include +#include + +#define isnan(x) (_isnan(x)) + +#include "../../cpu.h" +#include "../../ia32.mcr" + +#include "../sse/sse.h" +#include "../sse2/sse2.h" +#include "sse3.h" + +#if defined(USE_SSE3) && defined(USE_SSE2) && defined(USE_SSE) && defined(USE_FPU) + +#define CPU_SSE3WORKCLOCK CPU_WORKCLOCK(8) + +static INLINE void +SSE3_check_NM_EXCEPTION(){ + // SSE3なしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature_ecx & CPU_FEATURE_ECX_SSE3)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // エミュレーションならUD(無効オペコード例外)を発生させる + if(CPU_CR0 & CPU_CR0_EM){ + EXCEPTION(UD_EXCEPTION, 0); + } + // タスクスイッチ時にNM(デバイス使用不可例外)を発生させる + if (CPU_CR0 & CPU_CR0_TS) { + EXCEPTION(NM_EXCEPTION, 0); + } +} + +static INLINE void +SSE3_setTag(void) +{ +} + +// mmx.cのものと同じ +static INLINE void +MMX_setTag(void) +{ + int i; + + if(!FPU_STAT.mmxenable){ + FPU_STAT.mmxenable = 1; + //FPU_CTRLWORD = 0x27F; + for (i = 0; i < FPU_REG_NUM; i++) { + FPU_STAT.tag[i] = TAG_Valid; +#ifdef SUPPORT_FPU_DOSBOX2 + FPU_STAT.int_regvalid[i] = 0; +#endif + FPU_STAT.reg[i].ul.ext = 0xffff; + } + } + FPU_STAT_TOP = 0; + FPU_STATUSWORD &= ~0x3800; + FPU_STATUSWORD |= (FPU_STAT_TOP&7)<<11; +} + +/* + * SSE3 interface + */ + +// コードが長くなるのでやや強引に共通化 +// xmm/m128 -> xmm +static INLINE void SSE_PART_GETDATA1DATA2_PD(double **data1, double **data2, double *data2buf){ + UINT32 op; + UINT idx, sub; + + SSE3_check_NM_EXCEPTION(); + SSE3_setTag(); + CPU_SSE3WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + *data1 = (double*)(&(FPU_STAT.xmm_reg[idx])); + if ((op) >= 0xc0) { + *data2 = (double*)(&(FPU_STAT.xmm_reg[sub])); + } else { + UINT32 maddr; + maddr = calc_ea_dst((op)); + *((UINT64*)(data2buf+ 0)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 0); + *((UINT64*)(data2buf+ 1)) = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, maddr+ 8); + *data2 = data2buf; + } +} + +void SSE3_ADDSUBPD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + data1[0] = data1[0] - data2[0]; + data1[1] = data1[1] + data2[1]; +} +void SSE3_ADDSUBPS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + data1[0] = data1[0] - data2[0]; + data1[1] = data1[1] + data2[1]; + data1[2] = data1[2] - data2[2]; + data1[3] = data1[3] + data2[3]; +} +void SSE3_HADDPD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + data1[0] = data1[0] + data1[1]; + data1[1] = data2[0] + data2[1]; +} +void SSE3_HADDPS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + data1[0] = data1[0] + data1[1]; + data1[1] = data1[2] + data1[3]; + data1[2] = data2[0] + data2[1]; + data1[3] = data2[2] + data2[3]; +} +void SSE3_HSUBPD(void) +{ + double data2buf[2]; + double *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD(&data1, &data2, data2buf); + data1[0] = data1[0] - data1[1]; + data1[1] = data2[0] - data2[1]; +} +void SSE3_HSUBPS(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + data1[0] = data1[0] - data1[1]; + data1[1] = data1[2] - data1[3]; + data1[2] = data2[0] - data2[1]; + data1[3] = data2[2] - data2[3]; +} + +void SSE3_MONITOR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); // 未実装 +} +void SSE3_MWAIT(void) +{ + EXCEPTION(UD_EXCEPTION, 0); // 未実装 +} + +//void SSE3_FISTTP(void) +//{ +// EXCEPTION(UD_EXCEPTION, 0); +//} +void SSE3_LDDQU(void) +{ + SSE2_MOVDQAmem2xmm(); // 微妙に違うけどいいかな・・・ +} +void SSE3_MOVDDUP(void) +{ + UINT32 op; + UINT idx, sub; + + SSE3_check_NM_EXCEPTION(); + SSE3_setTag(); + CPU_SSE3WORKCLOCK; + GET_PCBYTE((op)); + idx = (op >> 3) & 7; + sub = (op & 7); + if ((op) >= 0xc0) { + FPU_STAT.xmm_reg[idx].ul64[0] = FPU_STAT.xmm_reg[sub].ul64[0]; + } else { + UINT32 madr; + madr = calc_ea_dst(op); + FPU_STAT.xmm_reg[idx].ul64[0] = cpu_vmemoryread_q(CPU_INST_SEGREG_INDEX, madr); + } + FPU_STAT.xmm_reg[idx].ul64[1] = FPU_STAT.xmm_reg[idx].ul64[0]; +} +void SSE3_MOVSHDUP(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + data1[0] = data2[1]; + data1[1] = data2[1]; + data1[2] = data2[3]; + data1[3] = data2[3]; +} +void SSE3_MOVSLDUP(void) +{ + float data2buf[4]; + float *data1, *data2; + + SSE_PART_GETDATA1DATA2_PD((double**)(&data1), (double**)(&data2), (double*)data2buf); + data1[0] = data2[0]; + data1[1] = data2[0]; + data1[2] = data2[2]; + data1[3] = data2[2]; +} + +#else + +/* + * SSE3 interface + */ + +void SSE3_ADDSUBPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_ADDSUBPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_HADDPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_HADDPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_HSUBPD(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_HSUBPS(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void SSE3_MONITOR(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_MWAIT(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +void SSE3_FISTTP(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_LDDQU(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_MOVDDUP(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_MOVSHDUP(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} +void SSE3_MOVSLDUP(void) +{ + EXCEPTION(UD_EXCEPTION, 0); +} + +#endif diff --git a/source/src/vm/np21/i386c/ia32/instructions/sse3/sse3.h b/source/src/vm/np21/i386c/ia32/instructions/sse3/sse3.h new file mode 100644 index 000000000..770225e88 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/sse3/sse3.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2018 SimK + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SSE3_SSE3_H__ +#define IA32_CPU_INSTRUCTION_SSE3_SSE3_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void SSE3_ADDSUBPD(void); +void SSE3_ADDSUBPS(void); +void SSE3_HADDPD(void); +void SSE3_HADDPS(void); +void SSE3_HSUBPD(void); +void SSE3_HSUBPS(void); + +void SSE3_MONITOR(void); +void SSE3_MWAIT(void); + +//void SSE3_FISTTP(void); // -> FPU ESC7 +void SSE3_LDDQU(void); +void SSE3_MOVDDUP(void); +void SSE3_MOVSHDUP(void); +void SSE3_MOVSLDUP(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_SSE3_SSE3_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/string_inst.cpp b/source/src/vm/np21/i386c/ia32/instructions/string_inst.cpp new file mode 100644 index 000000000..4a92b4afd --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/string_inst.cpp @@ -0,0 +1,1291 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" + +#include "string_inst.h" + +#ifdef USE_SSE +#include "misc_inst.h" +#endif + + +/* movs */ +void +MOVSB_XbYb(void) +{ + UINT8 tmp; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, tmp); + CPU_SI += STRING_DIR; + CPU_DI += STRING_DIR; + } else { + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, tmp); + CPU_ESI += STRING_DIR; + CPU_EDI += STRING_DIR; + } +} + +void +MOVSW_XwYw(void) +{ + UINT16 tmp; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, tmp); + CPU_SI += STRING_DIRx2; + CPU_DI += STRING_DIRx2; + } else { + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, tmp); + CPU_ESI += STRING_DIRx2; + CPU_EDI += STRING_DIRx2; + } +} + +void +MOVSD_XdYd(void) +{ + UINT32 tmp; + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, tmp); + CPU_SI += STRING_DIRx4; + CPU_DI += STRING_DIRx4; + } else { + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, tmp); + CPU_ESI += STRING_DIRx4; + CPU_EDI += STRING_DIRx4; + } +} + +#define MOVSB_XbYb_rep16_part \ + do { \ + CPU_WORKCLOCK(5);\ + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); \ + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, tmp); \ + CPU_SI += STRING_DIR; \ + CPU_DI += STRING_DIR; \ + } while (0) + +#define MOVSW_XwYw_rep16_part \ + do { \ + CPU_WORKCLOCK(5);\ + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); \ + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, tmp); \ + CPU_SI += STRING_DIRx2; \ + CPU_DI += STRING_DIRx2; \ + } while (0) + +#define MOVSD_XdYd_rep16_part \ + do { \ + CPU_WORKCLOCK(5);\ + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); \ + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, tmp); \ + CPU_SI += STRING_DIRx4; \ + CPU_DI += STRING_DIRx4; \ + } while (0) + +#define MOVSB_XbYb_rep32_part \ + do { \ + CPU_WORKCLOCK(5);\ + tmp = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); \ + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, tmp); \ + CPU_ESI += STRING_DIR; \ + CPU_EDI += STRING_DIR; \ + } while (0) + +#define MOVSW_XwYw_rep32_part \ + do { \ + CPU_WORKCLOCK(5);\ + tmp = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); \ + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, tmp); \ + CPU_ESI += STRING_DIRx2; \ + CPU_EDI += STRING_DIRx2; \ + } while (0) + +#define MOVSD_XdYd_rep32_part \ + do { \ + CPU_WORKCLOCK(5);\ + tmp = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); \ + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, tmp); \ + CPU_ESI += STRING_DIRx4; \ + CPU_EDI += STRING_DIRx4; \ + } while (0) + +void +MOVSB_XbYb_rep(int reptype) +{ + UINT8 tmp; + /* rep */ + CPU_INST_SEGREG_INDEX = DS_FIX; + if(!CPU_INST_AS32){ + switch(reptype){ + case 0: /* rep */ + for (;;) { + MOVSB_XbYb_rep16_part; + if (--CPU_CX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + MOVSB_XbYb_rep16_part; + if (--CPU_CX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + MOVSB_XbYb_rep16_part; + if (--CPU_CX == 0 /*|| CC_Z*/) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + }else{ + switch(reptype){ + case 0: /* rep */ + for (;;) { + MOVSB_XbYb_rep32_part; + if (--CPU_ECX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + MOVSB_XbYb_rep32_part; + if (--CPU_ECX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + MOVSB_XbYb_rep32_part; + if (--CPU_ECX == 0 /*|| CC_Z*/) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + } +} + +void +MOVSW_XwYw_rep(int reptype) +{ + UINT16 tmp; + /* rep */ + CPU_INST_SEGREG_INDEX = DS_FIX; + if(!CPU_INST_AS32){ + switch(reptype){ + case 0: /* rep */ + for (;;) { + MOVSW_XwYw_rep16_part; + if (--CPU_CX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + MOVSW_XwYw_rep16_part; + if (--CPU_CX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + MOVSW_XwYw_rep16_part; + if (--CPU_CX == 0 /*|| CC_Z*/) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + }else{ + switch(reptype){ + case 0: /* rep */ + for (;;) { + MOVSW_XwYw_rep32_part; + if (--CPU_ECX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + MOVSW_XwYw_rep32_part; + if (--CPU_ECX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + MOVSW_XwYw_rep32_part; + if (--CPU_ECX == 0 /*|| CC_Z*/) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + } +} + +void +MOVSD_XdYd_rep(int reptype) +{ + UINT32 tmp; + /* rep */ + CPU_INST_SEGREG_INDEX = DS_FIX; + if(!CPU_INST_AS32){ + switch(reptype){ + case 0: /* rep */ + for (;;) { + MOVSD_XdYd_rep16_part; + if (--CPU_CX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + MOVSD_XdYd_rep16_part; + if (--CPU_CX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + MOVSD_XdYd_rep16_part; + if (--CPU_CX == 0 /*|| CC_Z*/) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + }else{ + switch(reptype){ + case 0: /* rep */ + for (;;) { + MOVSD_XdYd_rep32_part; + if (--CPU_ECX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + MOVSD_XdYd_rep32_part; + if (--CPU_ECX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + MOVSD_XdYd_rep32_part; + if (--CPU_ECX == 0 /*|| CC_Z*/) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + } +} + + +/* cmps */ +void +CMPSB_XbYb(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(8); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_DI); + BYTE_SUB(res, dst, src); + CPU_SI += STRING_DIR; + CPU_DI += STRING_DIR; + } else { + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_EDI); + BYTE_SUB(res, dst, src); + CPU_ESI += STRING_DIR; + CPU_EDI += STRING_DIR; + } +} + +void +CMPSW_XwYw(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(8); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_DI); + WORD_SUB(res, dst, src); + CPU_SI += STRING_DIRx2; + CPU_DI += STRING_DIRx2; + } else { + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_EDI); + WORD_SUB(res, dst, src); + CPU_ESI += STRING_DIRx2; + CPU_EDI += STRING_DIRx2; + } +} + +void +CMPSD_XdYd(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(8); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_DI); + DWORD_SUB(res, dst, src); + CPU_SI += STRING_DIRx4; + CPU_DI += STRING_DIRx4; + } else { + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_EDI); + DWORD_SUB(res, dst, src); + CPU_ESI += STRING_DIRx4; + CPU_EDI += STRING_DIRx4; + } +} + +#define CMPSB_XbYb_rep16_part \ + do { \ + CPU_WORKCLOCK(8);\ + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI);\ + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_DI);\ + BYTE_SUB(res, dst, src);\ + CPU_SI += STRING_DIR;\ + CPU_DI += STRING_DIR;\ + } while (0) + +#define CMPSW_XwYw_rep16_part \ + do { \ + CPU_WORKCLOCK(8);\ + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI);\ + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_DI);\ + WORD_SUB(res, dst, src);\ + CPU_SI += STRING_DIRx2;\ + CPU_DI += STRING_DIRx2;\ + } while (0) + +#define CMPSD_XdYd_rep16_part \ + do { \ + CPU_WORKCLOCK(8);\ + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI);\ + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_DI);\ + DWORD_SUB(res, dst, src);\ + CPU_SI += STRING_DIRx4;\ + CPU_DI += STRING_DIRx4;\ + } while (0) + +#define CMPSB_XbYb_rep32_part \ + do { \ + CPU_WORKCLOCK(8);\ + dst = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI);\ + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_EDI);\ + BYTE_SUB(res, dst, src);\ + CPU_ESI += STRING_DIR;\ + CPU_EDI += STRING_DIR;\ + } while (0) + +#define CMPSW_XwYw_rep32_part \ + do { \ + CPU_WORKCLOCK(8);\ + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI);\ + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_EDI);\ + WORD_SUB(res, dst, src);\ + CPU_ESI += STRING_DIRx2;\ + CPU_EDI += STRING_DIRx2;\ + } while (0) + +#define CMPSD_XdYd_rep32_part \ + do { \ + CPU_WORKCLOCK(8);\ + dst = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI);\ + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_EDI);\ + DWORD_SUB(res, dst, src);\ + CPU_ESI += STRING_DIRx4;\ + CPU_EDI += STRING_DIRx4;\ + } while (0) +void +CMPSB_XbYb_rep(int reptype) +{ + UINT32 src, dst, res; + + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + switch(reptype){ + case 0: /* rep */ + for (;;) { + CMPSB_XbYb_rep16_part; + if (--CPU_CX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + CMPSB_XbYb_rep16_part; + if (--CPU_CX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + CMPSB_XbYb_rep16_part; + if (--CPU_CX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + }else{ + switch(reptype){ + case 0: /* rep */ + for (;;) { + CMPSB_XbYb_rep32_part; + if (--CPU_ECX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + CMPSB_XbYb_rep32_part; + if (--CPU_ECX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + CMPSB_XbYb_rep32_part; + if (--CPU_ECX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + } +} + +void +CMPSW_XwYw_rep(int reptype) +{ + UINT32 src, dst, res; + + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + switch(reptype){ + case 0: /* rep */ + for (;;) { + CMPSW_XwYw_rep16_part; + if (--CPU_CX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + CMPSW_XwYw_rep16_part; + if (--CPU_CX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + CMPSW_XwYw_rep16_part; + if (--CPU_CX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + }else{ + switch(reptype){ + case 0: /* rep */ + for (;;) { + CMPSW_XwYw_rep32_part; + if (--CPU_ECX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + CMPSW_XwYw_rep32_part; + if (--CPU_ECX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + CMPSW_XwYw_rep32_part; + if (--CPU_ECX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + } +} + +void +CMPSD_XdYd_rep(int reptype) +{ + UINT32 src, dst, res; + + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + switch(reptype){ + case 0: /* rep */ + for (;;) { + CMPSD_XdYd_rep16_part; + if (--CPU_CX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + CMPSD_XdYd_rep16_part; + if (--CPU_CX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + CMPSD_XdYd_rep16_part; + if (--CPU_CX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + }else{ + switch(reptype){ + case 0: /* rep */ + for (;;) { + CMPSD_XdYd_rep32_part; + if (--CPU_ECX == 0) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 1: /* repe */ + for (;;) { + CMPSD_XdYd_rep32_part; + if (--CPU_ECX == 0 || CC_NZ) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + case 2: /* repne */ + for (;;) { + CMPSD_XdYd_rep32_part; + if (--CPU_ECX == 0 || CC_Z) { + #if defined(DEBUG) + cpu_debug_rep_cont = 0; + #endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + break; + } + } +} + + +/* scas */ +void +SCASB_ALXb(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(7); + dst = CPU_AL; + if (!CPU_INST_AS32) { + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_DI); + BYTE_SUB(res, dst, src); + CPU_DI += STRING_DIR; + } else { + src = cpu_vmemoryread(CPU_ES_INDEX, CPU_EDI); + BYTE_SUB(res, dst, src); + CPU_EDI += STRING_DIR; + } +} + +void +SCASW_AXXw(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(7); + dst = CPU_AX; + if (!CPU_INST_AS32) { + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_DI); + WORD_SUB(res, dst, src); + CPU_DI += STRING_DIRx2; + } else { + src = cpu_vmemoryread_w(CPU_ES_INDEX, CPU_EDI); + WORD_SUB(res, dst, src); + CPU_EDI += STRING_DIRx2; + } +} + +void +SCASD_EAXXd(void) +{ + UINT32 src, dst, res; + + CPU_WORKCLOCK(7); + dst = CPU_EAX; + if (!CPU_INST_AS32) { + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_DI); + DWORD_SUB(res, dst, src); + CPU_DI += STRING_DIRx4; + } else { + src = cpu_vmemoryread_d(CPU_ES_INDEX, CPU_EDI); + DWORD_SUB(res, dst, src); + CPU_EDI += STRING_DIRx4; + } +} + + +/* lods */ +void +LODSB_ALXb(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + CPU_SI += STRING_DIR; + } else { + CPU_AL = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + CPU_ESI += STRING_DIR; + } +} + +void +LODSW_AXXw(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_AX = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + CPU_SI += STRING_DIRx2; + } else { + CPU_AX = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + CPU_ESI += STRING_DIRx2; + } +} + +void +LODSD_EAXXd(void) +{ + + CPU_WORKCLOCK(5); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + CPU_EAX = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + CPU_SI += STRING_DIRx4; + } else { + CPU_EAX = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + CPU_ESI += STRING_DIRx4; + } +} + + +/* stos */ +void +STOSB_YbAL(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_INST_AS32) { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, CPU_AL); + CPU_DI += STRING_DIR; + } else { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, CPU_AL); + CPU_EDI += STRING_DIR; + } +} + +void +STOSW_YwAX(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, CPU_AX); + CPU_DI += STRING_DIRx2; + } else { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, CPU_AX); + CPU_EDI += STRING_DIRx2; + } +} + +void +STOSD_YdEAX(void) +{ + + CPU_WORKCLOCK(3); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, CPU_EAX); + CPU_DI += STRING_DIRx4; + } else { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, CPU_EAX); + CPU_EDI += STRING_DIRx4; + } +} + +// repのみ +void +STOSB_YbAL_rep(int reptype) +{ + if (!CPU_INST_AS32) { + for (;;) { + CPU_WORKCLOCK(3); + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, CPU_AL); + CPU_DI += STRING_DIR; + if (--CPU_CX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } else { + for (;;) { + CPU_WORKCLOCK(3); + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, CPU_AL); + CPU_EDI += STRING_DIR; + if (--CPU_ECX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } +} + +void +STOSW_YwAX_rep(int reptype) +{ + + if (!CPU_INST_AS32) { + for (;;) { + CPU_WORKCLOCK(3); + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, CPU_AX); + CPU_DI += STRING_DIRx2; + if (--CPU_CX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } else { + for (;;) { + CPU_WORKCLOCK(3); + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, CPU_AX); + CPU_EDI += STRING_DIRx2; + if (--CPU_ECX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } +} + +void +STOSD_YdEAX_rep(int reptype) +{ + + if (!CPU_INST_AS32) { + for (;;) { + CPU_WORKCLOCK(3); + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, CPU_EAX); + CPU_DI += STRING_DIRx4; + if (--CPU_CX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } else { + for (;;) { + CPU_WORKCLOCK(3); + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, CPU_EAX); + CPU_EDI += STRING_DIRx4; + if (--CPU_ECX == 0) { +#if defined(DEBUG) + cpu_debug_rep_cont = 0; +#endif + break; + } + if (CPU_REMCLOCK <= 0) { + CPU_EIP = CPU_PREV_EIP; + break; + } + } + } +} + + +/* repeat */ +void +_REPNE(void) +{ + CPU_INST_REPUSE = 0xf2; +} + +void +_REPE(void) +{ + CPU_INST_REPUSE = 0xf3; +} + + +/* ins */ +void +INSB_YbDX(void) +{ + UINT8 data; + + CPU_WORKCLOCK(12); + data = cpu_in(CPU_DX); + if (!CPU_INST_AS32) { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_DI, data); + CPU_DI += STRING_DIR; + } else { + cpu_vmemorywrite(CPU_ES_INDEX, CPU_EDI, data); + CPU_EDI += STRING_DIR; + } +} + +void +INSW_YwDX(void) +{ + UINT16 data; + + CPU_WORKCLOCK(12); + data = cpu_in_w(CPU_DX); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_DI, data); + CPU_DI += STRING_DIRx2; + } else { + cpu_vmemorywrite_w(CPU_ES_INDEX, CPU_EDI, data); + CPU_EDI += STRING_DIRx2; + } +} + +void +INSD_YdDX(void) +{ + UINT32 data; + + CPU_WORKCLOCK(12); + data = cpu_in_d(CPU_DX); + if (!CPU_INST_AS32) { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_DI, data); + CPU_DI += STRING_DIRx4; + } else { + cpu_vmemorywrite_d(CPU_ES_INDEX, CPU_EDI, data); + CPU_EDI += STRING_DIRx4; + } +} + + +/* outs */ +void +OUTSB_DXXb(void) +{ + UINT8 data; + + CPU_WORKCLOCK(14); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + data = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_out(CPU_DX, data); + CPU_SI += STRING_DIR; + } else { + data = cpu_vmemoryread(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_out(CPU_DX, data); + CPU_ESI += STRING_DIR; + } +} + +void +OUTSW_DXXw(void) +{ + UINT16 data; + + CPU_WORKCLOCK(14); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + data = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_out_w(CPU_DX, data); + CPU_SI += STRING_DIRx2; + } else { + data = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_out_w(CPU_DX, data); + CPU_ESI += STRING_DIRx2; + } +} + +void +OUTSD_DXXd(void) +{ + UINT32 data; + + CPU_WORKCLOCK(14); + CPU_INST_SEGREG_INDEX = DS_FIX; + if (!CPU_INST_AS32) { + data = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_SI); + cpu_out_d(CPU_DX, data); + CPU_SI += STRING_DIRx4; + } else { + data = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, CPU_ESI); + cpu_out_d(CPU_DX, data); + CPU_ESI += STRING_DIRx4; + } +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/string_inst.h b/source/src/vm/np21/i386c/ia32/instructions/string_inst.h new file mode 100644 index 000000000..9db046a8a --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/string_inst.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_STRING_H__ +#define IA32_CPU_INSTRUCTION_STRING_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +#define STRING_DIR ((CPU_FLAG & D_FLAG) ? -1 : 1) +#define STRING_DIRx2 ((CPU_FLAG & D_FLAG) ? -2 : 2) +#define STRING_DIRx4 ((CPU_FLAG & D_FLAG) ? -4 : 4) + +/* movs */ +void MOVSB_XbYb(void); +void MOVSW_XwYw(void); +void MOVSD_XdYd(void); +void MOVSB_XbYb_rep(int reptype); +void MOVSW_XwYw_rep(int reptype); +void MOVSD_XdYd_rep(int reptype); + +/* cmps */ +void CMPSB_XbYb(void); +void CMPSW_XwYw(void); +void CMPSD_XdYd(void); +void CMPSB_XbYb_rep(int reptype); +void CMPSW_XwYw_rep(int reptype); +void CMPSD_XdYd_rep(int reptype); + +/* scas */ +void SCASB_ALXb(void); +void SCASW_AXXw(void); +void SCASD_EAXXd(void); + +/* lods */ +void LODSB_ALXb(void); +void LODSW_AXXw(void); +void LODSD_EAXXd(void); + +/* stos */ +void STOSB_YbAL(void); +void STOSW_YwAX(void); +void STOSD_YdEAX(void); +void STOSB_YbAL_rep(int reptype); +void STOSW_YwAX_rep(int reptype); +void STOSD_YdEAX_rep(int reptype); + +/* repeat */ +void _REPNE(void); +void _REPE(void); + +/* ins */ +void INSB_YbDX(void); +void INSW_YwDX(void); +void INSD_YdDX(void); + +/* outs */ +void OUTSB_DXXb(void); +void OUTSW_DXXw(void); +void OUTSD_DXXd(void); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_STRING_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/instructions/system_inst.cpp b/source/src/vm/np21/i386c/ia32/instructions/system_inst.cpp new file mode 100644 index 000000000..4c56f902a --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/system_inst.cpp @@ -0,0 +1,1258 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "../cpu.h" +#include "../ia32.mcr" +//#include "pccore.h" + +#include "system_inst.h" + + +void CPUCALL +LGDT_Ms(UINT32 op) +{ + UINT32 madr; + UINT32 base; + UINT16 limit; + + if (op < 0xc0) { + if (!CPU_STAT_PM || (CPU_STAT_CPL == 0 && !CPU_STAT_VM86)) { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } + +#if defined(MORE_DEBUG) + gdtr_dump(base, limit); +#endif + + CPU_GDTR_BASE = base; + CPU_GDTR_LIMIT = limit; + return; + } + VERBOSE(("LGDT: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +SGDT_Ms(UINT32 op) +{ + UINT32 madr; + UINT32 base; + UINT16 limit; + + if (op < 0xc0) { + CPU_WORKCLOCK(11); + limit = CPU_GDTR_LIMIT; + base = CPU_GDTR_BASE; + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +LLDT_Ew(UINT32 op) +{ + UINT32 madr; + UINT16 src; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (CPU_STAT_CPL == 0) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + load_ldtr(src, GP_EXCEPTION); + return; + } + VERBOSE(("LLDT: CPL(%d) != 0", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + VERBOSE(("LLDT: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +SLDT_Ew(UINT32 op) +{ + UINT32 madr; + UINT16 ldtr; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + ldtr = CPU_LDTR; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + if (CPU_INST_OP32) { + *(reg32_b20[op]) = ldtr; + } else { + *(reg16_b20[op]) = ldtr; + } + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, ldtr); + } + return; + } + VERBOSE(("SLDT: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +LTR_Ew(UINT32 op) +{ + UINT32 madr; + UINT16 src; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (CPU_STAT_CPL == 0) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + load_tr(src); + return; + } + VERBOSE(("LTR: CPL(%d) != 0", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + VERBOSE(("LTR: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +STR_Ew(UINT32 op) +{ + UINT32 madr; + UINT16 tr; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + tr = CPU_TR; + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + if (CPU_INST_OP32) { + *(reg32_b20[op]) = tr; + } else { + *(reg16_b20[op]) = tr; + } + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, tr); + } + return; + } + VERBOSE(("STR: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +LIDT_Ms(UINT32 op) +{ + UINT32 madr; + UINT32 base; + UINT16 limit; + + if (op < 0xc0) { + if (!CPU_STAT_PM || (CPU_STAT_CPL == 0 && !CPU_STAT_VM86)) { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + limit = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + base = cpu_vmemoryread_d(CPU_INST_SEGREG_INDEX, madr + 2); + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } + +#if defined(MORE_DEBUG) + idtr_dump(base, limit); +#endif + + CPU_IDTR_BASE = base; + CPU_IDTR_LIMIT = limit; + return; + } + VERBOSE(("LIDT: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +SIDT_Ms(UINT32 op) +{ + UINT32 madr; + UINT32 base; + UINT16 limit; + + if (op < 0xc0) { + CPU_WORKCLOCK(11); + limit = CPU_IDTR_LIMIT; + base = CPU_IDTR_BASE; + if (!CPU_INST_OP32) { + base &= 0x00ffffff; + } + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, limit); + cpu_vmemorywrite_d(CPU_INST_SEGREG_INDEX, madr + 2, base); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_CdRd(void) +{ + UINT32 op, src; + UINT32 reg; + int idx; + + CPU_WORKCLOCK(11); + GET_PCBYTE(op); + if (op >= 0xc0) { + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("MOV_CdRd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + src = *(reg32_b20[op]); + idx = (op >> 3) & 7; + + switch (idx) { + case 0: /* CR0 */ + /* + * 0 = PE (protect enable) + * 1 = MP (monitor coprocesser) + * 2 = EM (emulation) + * 3 = TS (task switch) + * 4 = ET (extend type, FPU present = 1) + * 5 = NE (numeric error) + * 16 = WP (write protect) + * 18 = AM (alignment mask) + * 29 = NW (not write-through) + * 30 = CD (cache diable) + * 31 = PG (pageing) + */ + + /* 下巻 p.182 割り込み 13 - 一般保護例外 */ + if ((src & (CPU_CR0_PE|CPU_CR0_PG)) == (UINT32)CPU_CR0_PG) { + EXCEPTION(GP_EXCEPTION, 0); + } + if ((src & (CPU_CR0_NW|CPU_CR0_CD)) == CPU_CR0_NW) { + EXCEPTION(GP_EXCEPTION, 0); + } + + reg = CPU_CR0; + src &= CPU_CR0_ALL; +#if defined(USE_FPU) + if(i386cpuid.cpu_feature & CPU_FEATURE_FPU){ + src |= CPU_CR0_ET; /* FPU present */ + //src &= ~CPU_CR0_EM; + }else{ + src |= CPU_CR0_EM | CPU_CR0_NE; + src &= ~(CPU_CR0_MP | CPU_CR0_ET); + } +#else + src |= CPU_CR0_EM | CPU_CR0_NE; + src &= ~(CPU_CR0_MP | CPU_CR0_ET); +#endif + CPU_CR0 = src; + VERBOSE(("MOV_CdRd: %04x:%08x: cr0: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR0, reg32_str[op & 7])); + + if ((reg ^ CPU_CR0) & (CPU_CR0_PE|CPU_CR0_PG)) { + tlb_flush_all(); + } + if ((reg ^ CPU_CR0) & CPU_CR0_PE) { + if (CPU_CR0 & CPU_CR0_PE) { + change_pm(1); + } + } + if ((reg ^ CPU_CR0) & CPU_CR0_PG) { + if (CPU_CR0 & CPU_CR0_PG) { + change_pg(1); + } else { + change_pg(0); + } + } + if ((reg ^ CPU_CR0) & CPU_CR0_PE) { + if (!(CPU_CR0 & CPU_CR0_PE)) { + change_pm(0); + } + } + + CPU_STAT_WP = (CPU_CR0 & CPU_CR0_WP) ? 0x10 : 0; + break; + + case 2: /* CR2 */ + reg = CPU_CR2; + CPU_CR2 = src; /* page fault linear address */ + VERBOSE(("MOV_CdRd: %04x:%08x: cr2: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR2, reg32_str[op & 7])); + break; + + case 3: /* CR3 */ + /* + * 31-12 = page directory base + * 4 = PCD (page level cache diable) + * 3 = PWT (page level write throgh) + */ + reg = CPU_CR3; + set_cr3(src); + VERBOSE(("MOV_CdRd: %04x:%08x: cr3: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR3, reg32_str[op & 7])); + break; + + case 4: /* CR4 */ + /* + * 10 = OSXMMEXCPT (support non masking exception by OS) + * 9 = OSFXSR (support FXSAVE, FXRSTOR by OS) + * 8 = PCE (performance monitoring counter enable) + * 7 = PGE (page global enable) + * 6 = MCE (machine check enable) + * 5 = PAE (physical address extention) + * 4 = PSE (page size extention) + * 3 = DE (debug extention) + * 2 = TSD (time stamp diable) + * 1 = PVI (protected mode virtual interrupt) + * 0 = VME (VM8086 mode extention) + */ + reg = 0 /* allow bit */ +#if (CPU_FEATURES & CPU_FEATURE_PGE) == CPU_FEATURE_PGE + | CPU_CR4_PGE +#endif +#if (CPU_FEATURES & CPU_FEATURE_VME) == CPU_FEATURE_VME + | CPU_CR4_PVI | CPU_CR4_VME +#endif +#if (CPU_FEATURES & CPU_FEATURE_FXSR) == CPU_FEATURE_FXSR + | CPU_CR4_OSFXSR +#endif +#if (CPU_FEATURES & CPU_FEATURE_SSE) == CPU_FEATURE_SSE + | CPU_CR4_OSXMMEXCPT +#endif + | CPU_CR4_PCE + ; + if (src & ~reg) { + //if (src & 0xfffffc00) { + if (src & 0xfffff800) { + EXCEPTION(GP_EXCEPTION, 0); + } + ia32_warning("MOV_CdRd: CR4 <- 0x%08x", src); + } + + reg = CPU_CR4; + CPU_CR4 = src; + VERBOSE(("MOV_CdRd: %04x:%08x: cr4: 0x%08x <- 0x%08x(%s)", CPU_CS, CPU_PREV_EIP, reg, CPU_CR4, reg32_str[op & 7])); + + if ((reg ^ CPU_CR4) & (CPU_CR4_PSE|CPU_CR4_PGE|CPU_CR4_PAE|CPU_CR4_PVI|CPU_CR4_VME|CPU_CR4_OSFXSR|CPU_CR4_OSXMMEXCPT)) { + tlb_flush_all(); + } + break; + + default: + ia32_panic("MOV_CdRd: CR reg index (%d)", idx); + /*NOTREACHED*/ + break; + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_RdCd(void) +{ + UINT32 *out; + UINT32 op; + int idx; + + CPU_WORKCLOCK(11); + GET_PCBYTE(op); + if (op >= 0xc0) { + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("MOV_RdCd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + out = reg32_b20[op]; + idx = (op >> 3) & 7; + + switch (idx) { + case 0: + *out = CPU_CR0; + break; + + case 2: + *out = CPU_CR2; + break; + + case 3: + *out = CPU_CR3; + break; + + case 4: + *out = CPU_CR4; + break; + + default: + ia32_panic("MOV_RdCd: CR reg index (%d)", idx); + /*NOTREACHED*/ + break; + } + VERBOSE(("MOV_RdCd: %04x:%08x: cr%d: 0x%08x -> %s", CPU_CS, CPU_PREV_EIP, idx, *out, reg32_str[op & 7])); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +LMSW_Ew(UINT32 op) +{ + UINT32 src, madr; + UINT32 cr0; + + if (!CPU_STAT_PM || CPU_STAT_CPL == 0) { + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + src = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + src = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + + cr0 = CPU_CR0; + CPU_CR0 &= ~0xe; /* can't switch back from protected mode */ + CPU_CR0 |= (src & 0xf); /* TS, EM, MP, PE */ + if (!(cr0 & CPU_CR0_PE) && (src & CPU_CR0_PE)) { + change_pm(1); /* switch to protected mode */ + } + return; + } + VERBOSE(("LMSW: CPL(%d) != 0", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); +} + +void CPUCALL +SMSW_Ew(UINT32 op) +{ + UINT32 madr; + + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + if (CPU_INST_OP32) { + *(reg32_b20[op]) = (UINT16)CPU_CR0; + } else { + *(reg16_b20[op]) = (UINT16)CPU_CR0; + } + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)CPU_CR0); + } +} + +void +CLTS(void) +{ + + CPU_WORKCLOCK(5); + if (CPU_STAT_PM && (CPU_STAT_VM86 || (CPU_STAT_CPL != 0))) { + VERBOSE(("CLTS: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + CPU_CR0 &= ~CPU_CR0_TS; +} + +void +ARPL_EwGw(void) +{ + UINT32 op, madr; + UINT src, dst; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_EA_REG16(op, src); + if (op >= 0xc0) { + CPU_WORKCLOCK(2); + dst = *(reg16_b20[op]); + if ((dst & 3) < (src & 3)) { + CPU_FLAGL |= Z_FLAG; + dst &= ~3; + dst |= (src & 3); + *(reg16_b20[op]) = (UINT16)dst; + } else { + CPU_FLAGL &= ~Z_FLAG; + } + } else { + CPU_WORKCLOCK(3); + madr = calc_ea_dst(op); + dst = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + if ((dst & 3) < (src & 3)) { + CPU_FLAGL |= Z_FLAG; + dst &= ~3; + dst |= (src & 3); + cpu_vmemorywrite_w(CPU_INST_SEGREG_INDEX, madr, (UINT16)dst); + } else { + CPU_FLAGL &= ~Z_FLAG; + } + } + return; + } + VERBOSE(("ARPL: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +/* + * DPL + */ +void +LAR_GwEw(void) +{ + selector_t sel; + UINT16 *out; + UINT32 op; + UINT32 h; + int rv; + UINT16 selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG16_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (!SEG_IS_SYSTEM(&sel.desc)) { + /* code or data segment */ + if ((SEG_IS_DATA(&sel.desc) + || !SEG_IS_CONFORMING_CODE(&sel.desc))) { + /* data or non-conforming code segment */ + if ((sel.desc.dpl < CPU_STAT_CPL) + || (sel.desc.dpl < sel.rpl)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + } else { + /* system segment */ + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_TASK: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + case CPU_SYSDESC_TYPE_CALL_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + h = cpu_kmemoryread_d(sel.addr + 4); + *out = (UINT16)(h & 0xff00); + CPU_FLAGL |= Z_FLAG; + return; + } + VERBOSE(("LAR: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LAR_GdEw(void) +{ + selector_t sel; + UINT32 *out; + UINT32 op; + UINT32 h; + int rv; + UINT32 selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG32_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, (UINT16)selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (!SEG_IS_SYSTEM(&sel.desc)) { + /* code or data segment */ + if ((SEG_IS_DATA(&sel.desc) + || !SEG_IS_CONFORMING_CODE(&sel.desc))) { + /* data or non-conforming code segment */ + if ((sel.desc.dpl < CPU_STAT_CPL) + || (sel.desc.dpl < sel.rpl)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + } else { + /* system segment */ + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_CALL_16: + case CPU_SYSDESC_TYPE_TASK: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + case CPU_SYSDESC_TYPE_CALL_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + h = cpu_kmemoryread_d(sel.addr + 4); + *out = h & 0x00ffff00; /* 0x00fxff00, x? */ + CPU_FLAGL |= Z_FLAG; + return; + } + VERBOSE(("LAR: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSL_GwEw(void) +{ + selector_t sel; + UINT16 *out; + UINT32 op; + int rv; + UINT16 selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG16_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (!SEG_IS_SYSTEM(&sel.desc)) { + /* code or data segment */ + if ((SEG_IS_DATA(&sel.desc) + || !SEG_IS_CONFORMING_CODE(&sel.desc))) { + /* data or non-conforming code segment */ + if ((sel.desc.dpl < CPU_STAT_CPL) + || (sel.desc.dpl < sel.rpl)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + } else { + /* system segment */ + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + *out = (UINT16)sel.desc.u.seg.limit; + CPU_FLAGL |= Z_FLAG; + return; + } + VERBOSE(("LSL: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void +LSL_GdEw(void) +{ + selector_t sel; + UINT32 *out; + UINT32 op; + int rv; + UINT32 selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + PREPART_REG32_EA(op, selector, out, 5, 11); + + rv = parse_selector(&sel, (UINT16)selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + if (!SEG_IS_SYSTEM(&sel.desc)) { + /* code or data segment */ + if ((SEG_IS_DATA(&sel.desc) + || !SEG_IS_CONFORMING_CODE(&sel.desc))) { + /* data or non-conforming code segment */ + if ((sel.desc.dpl < CPU_STAT_CPL) + || (sel.desc.dpl < sel.rpl)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + } else { + /* system segment */ + switch (sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_LDT: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + break; + + default: + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + + *out = sel.desc.u.seg.limit; + CPU_FLAGL |= Z_FLAG; + return; + } + VERBOSE(("LSL: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +VERR_Ew(UINT32 op) +{ + selector_t sel; + UINT32 madr; + int rv; + UINT16 selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + selector = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + selector = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + /* system segment */ + if (SEG_IS_SYSTEM(&sel.desc)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + /* data or non-conforming code segment */ + if ((SEG_IS_DATA(&sel.desc) + || !SEG_IS_CONFORMING_CODE(&sel.desc))) { + if ((sel.desc.dpl < CPU_STAT_CPL) + || (sel.desc.dpl < sel.rpl)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + } + /* code segment is not readable */ + if (SEG_IS_CODE(&sel.desc) + && !SEG_IS_READABLE_CODE(&sel.desc)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + CPU_FLAGL |= Z_FLAG; + return; + } + VERBOSE(("VERR: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void CPUCALL +VERW_Ew(UINT32 op) +{ + selector_t sel; + UINT32 madr; + int rv; + UINT16 selector; + + if (CPU_STAT_PM && !CPU_STAT_VM86) { + if (op >= 0xc0) { + CPU_WORKCLOCK(5); + selector = *(reg16_b20[op]); + } else { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + selector = cpu_vmemoryread_w(CPU_INST_SEGREG_INDEX, madr); + } + + rv = parse_selector(&sel, selector); + if (rv < 0) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + /* system segment || code segment */ + if (SEG_IS_SYSTEM(&sel.desc) || SEG_IS_CODE(&sel.desc)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + /* data segment is not writable */ + if (!SEG_IS_WRITABLE_DATA(&sel.desc)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + /* privilege level */ + if ((CPU_STAT_CPL > sel.desc.dpl) || (sel.rpl > sel.desc.dpl)) { + CPU_FLAGL &= ~Z_FLAG; + return; + } + + CPU_FLAGL |= Z_FLAG; + return; + } + VERBOSE(("VERW: real-mode or VM86")); + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_DdRd(void) +{ + UINT32 src; + UINT op; + int idx; + + CPU_WORKCLOCK(11); + GET_PCBYTE(op); + if (op >= 0xc0) { + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("MOV_DdRd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + if (CPU_DR7 & CPU_DR7_GD) { + CPU_DR6 |= CPU_DR6_BD; + CPU_DR7 &= ~CPU_DR7_GD; + EXCEPTION(DB_EXCEPTION, 0); + } + + src = *(reg32_b20[op]); + idx = (op >> 3) & 7; + + CPU_DR(idx) = src; + switch (idx) { + case 0: + case 1: + case 2: + case 3: + CPU_DR(idx) = src; + break; + + case 6: + CPU_DR6 = src; + break; + + case 7: + CPU_DR7 = src; + CPU_STAT_BP = 0; + break; + + default: + ia32_panic("MOV_DdRd: DR reg index (%d)", idx); + /*NOTREACHED*/ + break; + } + + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +MOV_RdDd(void) +{ + UINT32 *out; + UINT op; + int idx; + + CPU_WORKCLOCK(11); + GET_PCBYTE(op); + if (op >= 0xc0) { + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("MOV_RdDd: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + if (CPU_DR7 & CPU_DR7_GD) { + CPU_DR6 |= CPU_DR6_BD; + CPU_DR7 &= ~CPU_DR7_GD; + EXCEPTION(DB_EXCEPTION, 0); + } + + out = reg32_b20[op]; + idx = (op >> 3) & 7; + + switch (idx) { + case 0: + case 1: + case 2: + case 3: + *out = CPU_DR(idx); + break; + + case 4: + case 6: + *out = (CPU_DR6 & 0x0000f00f) | 0xffff0ff0; + break; + + case 7: + *out = CPU_DR7; + break; + + default: + ia32_panic("MOV_RdDd: DR reg index (%d)", idx); + /*NOTREACHED*/ + break; + } + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +INVD(void) +{ + + CPU_WORKCLOCK(11); + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("INVD: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + +void +WBINVD(void) +{ + + CPU_WORKCLOCK(11); + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("WBINVD: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } +} + +void CPUCALL +INVLPG(UINT32 op) +{ + descriptor_t *sdp; + UINT32 madr; + int idx; + + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("INVLPG: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + if (op < 0xc0) { + CPU_WORKCLOCK(11); + madr = calc_ea_dst(op); + + idx = CPU_INST_SEGREG_INDEX; + sdp = &CPU_STAT_SREG(idx); + if (!SEG_IS_VALID(sdp)) { + EXCEPTION(GP_EXCEPTION, 0); + } + switch (sdp->type) { + case 4: case 5: case 6: case 7: + if (madr <= sdp->u.seg.limit) { + EXCEPTION((idx == CPU_SS_INDEX) ? + SS_EXCEPTION: GP_EXCEPTION, 0); + } + break; + + default: + if (madr > sdp->u.seg.limit) { + EXCEPTION((idx == CPU_SS_INDEX) ? + SS_EXCEPTION: GP_EXCEPTION, 0); + } + break; + } + tlb_flush_page(sdp->u.seg.segbase + madr); + return; + } + EXCEPTION(UD_EXCEPTION, 0); +} + +void +_LOCK(void) +{ + + /* Nothing to do */ +} + +void +HLT(void) +{ + + if (CPU_STAT_PM && CPU_STAT_CPL != 0) { + VERBOSE(("HLT: CPL(%d) != 0", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + VERBOSE(("HLT: do HLT.")); + CPU_HALT(); + CPU_EIP = CPU_PREV_EIP; + CPU_STAT_HLT = 1; +} + +void +RSM(void) +{ + + ia32_panic("RSM: not implemented yet!"); +} + +void +RDMSR(void) +{ + int idx; + + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("RDMSR: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + idx = CPU_ECX; + switch (idx) { + case 0x174: + CPU_EDX = (UINT32)((i386msr.reg.ia32_sysenter_cs >> 32) & 0xffffffff); + CPU_EAX = (UINT32)((i386msr.reg.ia32_sysenter_cs ) & 0xffffffff); + break; + case 0x175: + CPU_EDX = (UINT32)((i386msr.reg.ia32_sysenter_esp >> 32) & 0xffffffff); + CPU_EAX = (UINT32)((i386msr.reg.ia32_sysenter_esp ) & 0xffffffff); + break; + case 0x176: + CPU_EDX = (UINT32)((i386msr.reg.ia32_sysenter_eip >> 32) & 0xffffffff); + CPU_EAX = (UINT32)((i386msr.reg.ia32_sysenter_eip ) & 0xffffffff); + break; + case 0x10: + RDTSC(); + break; + case 0x2c: + CPU_EDX = 0x00000000; + CPU_EAX = 0xfee00800; + break; + //case 0x1b: + // CPU_EDX = 0x00000000; + // CPU_EAX = 0x00000010; + // break; + default: + CPU_EDX = CPU_EAX = 0; + //EXCEPTION(GP_EXCEPTION, 0); // XXX: とりあえず通す + break; + } +} + +void +WRMSR(void) +{ + int idx; + + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("WRMSR: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + idx = CPU_ECX; + switch (idx) { + case 0x174: + i386msr.reg.ia32_sysenter_cs = ((UINT64)CPU_EDX << 32) | ((UINT64)CPU_EAX); + break; + case 0x175: + i386msr.reg.ia32_sysenter_esp = ((UINT64)CPU_EDX << 32) | ((UINT64)CPU_EAX); + break; + case 0x176: + i386msr.reg.ia32_sysenter_eip = ((UINT64)CPU_EDX << 32) | ((UINT64)CPU_EAX); + break; + /* MTRR への書き込み時 tlb_flush_all(); */ + default: + //EXCEPTION(GP_EXCEPTION, 0); // XXX: とりあえず通す + break; + } +} + +void +RDTSC(void) +{ +#ifdef _WIN32 + LARGE_INTEGER li = {0}; + LARGE_INTEGER qpf; + QueryPerformanceCounter(&li); + if (QueryPerformanceFrequency(&qpf)) { + li.QuadPart = li.QuadPart * /*pccore.*/realclock / qpf.QuadPart; + } + CPU_EDX = li.HighPart; + CPU_EAX = li.LowPart; +#else + UINT64 tsc_tmp; + if(CPU_REMCLOCK != -1){ + tsc_tmp = CPU_MSR_TSC - CPU_REMCLOCK; + }else{ + tsc_tmp = CPU_MSR_TSC; + } + //tsc_tmp /= 1000; + tsc_tmp = (tsc_tmp >> 8); // XXX: ???? + CPU_EDX = ((tsc_tmp >> 32) & 0xffffffff); + CPU_EAX = (tsc_tmp & 0xffffffff); +#endif +// ia32_panic("RDTSC: not implemented yet!"); +} + +void +RDPMC(void) +{ + int idx; + + if(!(CPU_CR4 & CPU_CR4_PCE)){ + if (CPU_STAT_PM && (CPU_STAT_VM86 || CPU_STAT_CPL != 0)) { + VERBOSE(("RDPMC: VM86(%s) or CPL(%d) != 0", CPU_STAT_VM86 ? "true" : "false", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + } + + idx = CPU_ECX; + switch (idx) { + default: + CPU_EDX = CPU_EAX = 0; + } +} + +void +MOV_TdRd(void) +{ + UINT32 op, src; +// PREPART_EA_REG32(op, src); + ia32_panic("MOV_TdRd: not implemented yet!"); +} + +void +MOV_RdTd(void) +{ + UINT32 op, src; +// PREPART_EA_REG32(op, src); + + ia32_panic("MOV_RdTd: not implemented yet!"); +} + +// 中途半端&ノーチェック注意 +void +SYSENTER(void) +{ + // SEPなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_SEP)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // プロテクトモードチェック + if (!CPU_STAT_PM) { + EXCEPTION(GP_EXCEPTION, 0); + } + // MSRレジスタチェック + if (i386msr.reg.ia32_sysenter_cs == 0) { + EXCEPTION(GP_EXCEPTION, 0); + } + + CPU_EFLAG = CPU_EFLAG & ~(VM_FLAG|I_FLAG|RF_FLAG); + CPU_CS = (UINT32)i386msr.reg.ia32_sysenter_cs; + + CPU_SS = CPU_CS + 8; + + CPU_ESP = (UINT32)i386msr.reg.ia32_sysenter_esp; + CPU_EIP = (UINT32)i386msr.reg.ia32_sysenter_eip; + + CPU_STAT_CPL = 0; + CPU_STAT_USER_MODE = (CPU_STAT_CPL == 3) ? CPU_MODE_USER : CPU_MODE_SUPERVISER; +} + +// 中途半端&ノーチェック注意 +void +SYSEXIT(void) +{ + // SEPなしならUD(無効オペコード例外)を発生させる + if(!(i386cpuid.cpu_feature & CPU_FEATURE_SEP)){ + EXCEPTION(UD_EXCEPTION, 0); + } + // プロテクトモードチェック + if (!CPU_STAT_PM) { + EXCEPTION(GP_EXCEPTION, 0); + } + // MSRレジスタチェック + if (i386msr.reg.ia32_sysenter_cs == 0) { + EXCEPTION(GP_EXCEPTION, 0); + } + // 特権レベルチェック + if (CPU_STAT_CPL != 0) { + VERBOSE(("SYSENTER: CPL(%d) != 0", CPU_STAT_CPL)); + EXCEPTION(GP_EXCEPTION, 0); + } + + CPU_CS = (UINT32)i386msr.reg.ia32_sysenter_cs + 16; + + CPU_SS = (UINT32)i386msr.reg.ia32_sysenter_cs + 24; + + CPU_ESP = CPU_ECX; + CPU_EIP = CPU_EDX; + + CPU_STAT_CPL = 3; + CPU_STAT_USER_MODE = (CPU_STAT_CPL == 3) ? CPU_MODE_USER : CPU_MODE_SUPERVISER; +} diff --git a/source/src/vm/np21/i386c/ia32/instructions/system_inst.h b/source/src/vm/np21/i386c/ia32/instructions/system_inst.h new file mode 100644 index 000000000..7addb22c3 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/instructions/system_inst.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INSTRUCTION_SYSTEM_H__ +#define IA32_CPU_INSTRUCTION_SYSTEM_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* Load/Store system register */ +void CPUCALL LGDT_Ms(UINT32); +void CPUCALL SGDT_Ms(UINT32); +void CPUCALL LLDT_Ew(UINT32); +void CPUCALL SLDT_Ew(UINT32); +void CPUCALL LTR_Ew(UINT32); +void CPUCALL STR_Ew(UINT32); +void CPUCALL LIDT_Ms(UINT32); +void CPUCALL SIDT_Ms(UINT32); + +/* ctrl reg */ +void MOV_CdRd(void); +void MOV_RdCd(void); + +/* msw */ +void CPUCALL LMSW_Ew(UINT32); +void CPUCALL SMSW_Ew(UINT32); + +/* */ +void CLTS(void); +void ARPL_EwGw(void); + +/* dpl */ +void LAR_GwEw(void); +void LAR_GdEw(void); +void LSL_GwEw(void); +void LSL_GdEw(void); + +/* */ +void CPUCALL VERR_Ew(UINT32); +void CPUCALL VERW_Ew(UINT32); + +/* dbg reg */ +void MOV_DdRd(void); +void MOV_RdDd(void); + +/* cache */ +void INVD(void); +void WBINVD(void); + +/* */ +void CPUCALL INVLPG(UINT32); + +/* */ +void _LOCK(void); +void HLT(void); + +/* ctrl reg */ +void RSM(void); + +/* msr */ +void RDMSR(void); +void WRMSR(void); + +/* ctrl reg */ +void RDTSC(void); + +void RDPMC(void); + +/* test reg */ +void MOV_TdRd(void); +void MOV_RdTd(void); + +/* fast system call */ +void SYSENTER(void); +void SYSEXIT(void); + + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_INSTRUCTION_SYSTEM_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/interface.cpp b/source/src/vm/np21/i386c/ia32/interface.cpp new file mode 100644 index 000000000..c12468141 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/interface.cpp @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +//#include "pccore.h" +//#include "iocore.h" +//#include "dmax86.h" +//#include "bios/bios.h" + +#include "instructions/fpu/fp.h" + +#if defined(SUPPORT_IA32_HAXM) +#include "i386hax/haxfunc.h" +#include "i386hax/haxcore.h" +#endif +#include "../../../i386_np21.h" + +void +ia32_initreg(void) +{ + int i; + + CPU_STATSAVE.cpu_inst_default.seg_base = (UINT32)-1; + +// CPU_EDX = (CPU_FAMILY << 8) | (CPU_MODEL << 4) | CPU_STEPPING; + CPU_EDX = (i386cpuid.cpu_family << 8) | (i386cpuid.cpu_model << 4) | i386cpuid.cpu_stepping; + CPU_EFLAG = 2; + if(i386cpuid.cpu_family == CPU_80386_FAMILY) { + CPU_CR0 = 0; + } else { + CPU_CR0 = CPU_CR0_CD | CPU_CR0_NW; + } +#if defined(USE_FPU) + if(i386cpuid.cpu_feature & CPU_FEATURE_FPU){ + CPU_CR0 |= CPU_CR0_ET; /* FPU present */ + CPU_CR0 &= ~CPU_CR0_EM; + }else{ + CPU_CR0 |= (CPU_CR0_EM | CPU_CR0_NE); + CPU_CR0 &= ~(CPU_CR0_MP | CPU_CR0_ET); + } +#else + CPU_CR0 |= CPU_CR0_EM | CPU_CR0_NE; + CPU_CR0 &= ~(CPU_CR0_MP | CPU_CR0_ET); +#endif + CPU_MXCSR = 0x1f80; + +#if defined(USE_TSC) + CPU_MSR_TSC = 0; +#endif + + CPU_GDTR_BASE = 0x0; + CPU_GDTR_LIMIT = 0xffff; + CPU_IDTR_BASE = 0x0; + CPU_IDTR_LIMIT = 0xffff; + CPU_LDTR_BASE = 0x0; + CPU_LDTR_LIMIT = 0xffff; + CPU_TR_BASE = 0x0; + CPU_TR_LIMIT = 0xffff; + + CPU_STATSAVE.cpu_regs.dr[6] = 0xffff1ff0; + + for (i = 0; i < CPU_SEGREG_NUM; ++i) { + segdesc_init(i, 0, &CPU_STAT_SREG(i)); + } + LOAD_SEGREG(CPU_CS_INDEX, 0xf000); + CPU_STAT_CS_BASE = 0xffff0000; +// CPU_STAT_CS_LIMIT = 0xffff; +// CPU_STAT_SREG(CPU_CS_INDEX).flag = 0x93; + CPU_EIP = 0xfff0; +// CPU_ADRSMASK = 0x000fffff; + CPU_ADRSMASK = 0xffffffff; + + tlb_init(); + fpu_initialize(); +} + +void +ia32reset(void) +{ + + memset(&i386core.s, 0, sizeof(i386core.s)); + ia32_initreg(); +} + +void +ia32shut(void) +{ + + memset(&i386core.s, 0, offsetof(I386STAT, cpu_type)); + ia32_initreg(); +} + +void +ia32a20enable(BOOL enable) +{ + CPU_ADRSMASK = (enable) ? ~0 : ~(1 << 20); +} + +//#pragma optimize("", off) + +void +ia32(void) +{ +#ifdef __cplusplus + try { +#else + switch (sigsetjmp(exec_1step_jmpbuf, 1)) { + case 0: + break; + + case 1: + VERBOSE(("ia32: return from exception")); + break; + + case 2: + VERBOSE(("ia32: return from panic")); + return; + + default: + VERBOSE(("ia32: return from unknown cause")); + break; + } +#endif +/* + if (!CPU_TRAP && !dmac.working) { + exec_allstep(); + }else +*/ + if (!CPU_TRAP) { + do { + exec_1step(); + dmax86(); + } while (CPU_REMCLOCK > 0); + }else{ + do { + exec_1step(); + if (CPU_TRAP) { + CPU_DR6 |= CPU_DR6_BS; + INTERRUPT(1, INTR_TYPE_EXCEPTION); + } + dmax86(); + } while (CPU_REMCLOCK > 0); + } +#ifdef __cplusplus + } catch (int e) { + switch (e) { + case 0: + break; + + case 1: + VERBOSE(("ia32: return from exception")); + break; + + case 2: + VERBOSE(("ia32: return from panic")); + return; + + default: + VERBOSE(("ia32: return from unknown cause")); + break; + } + } +#endif +} + +void +ia32_step(void) +{ +#ifdef __cplusplus + try { +#else + switch (sigsetjmp(exec_1step_jmpbuf, 1)) { + case 0: + break; + + case 1: + VERBOSE(("ia32: return from exception")); + break; + + case 2: + VERBOSE(("ia32: return from panic")); + return; + + default: + VERBOSE(("ia32: return from unknown cause")); + break; + } +#endif + do { + exec_1step(); + if (CPU_TRAP) { + CPU_DR6 |= CPU_DR6_BS; + INTERRUPT(1, INTR_TYPE_EXCEPTION); + } + //if (dmac.working) { + dmax86(); + //} + } while (CPU_REMCLOCK > 0); +#ifdef __cplusplus + } catch (int e) { + switch (e) { + case 0: + break; + + case 1: + VERBOSE(("ia32: return from exception")); + break; + + case 2: + VERBOSE(("ia32: return from panic")); + return; + + default: + VERBOSE(("ia32: return from unknown cause")); + break; + } + } +#endif +} +//#pragma optimize("", on) + +void CPUCALL +ia32_interrupt(int vect, int soft) +{ + +// TRACEOUT(("int (%x, %x) PE=%d VM=%d", vect, soft, CPU_STAT_PM, CPU_STAT_VM86)); +#if defined(SUPPORT_IA32_HAXM) + if(np2hax.enable && !np2hax.emumode && np2hax.hVCPUDevice){ + np2haxcore.hltflag = 0; + if(!soft){ + HAX_TUNNEL *tunnel; + tunnel = (HAX_TUNNEL*)np2hax.tunnel.va; + if(np2haxstat.irq_reqidx_end - np2haxstat.irq_reqidx_cur < 250){ + np2haxstat.irq_req[np2haxstat.irq_reqidx_end] = vect; + np2haxstat.irq_reqidx_end++; + } + //i386haxfunc_vcpu_interrupt(vect); + } + }else +#endif + { + if (!soft) { + INTERRUPT(vect, INTR_TYPE_EXTINTR); + } else { + if (CPU_STAT_PM && CPU_STAT_VM86 && CPU_STAT_IOPL < CPU_IOPL3) { + VERBOSE(("ia32_interrupt: VM86 && IOPL < 3 && INTn")); + EXCEPTION(GP_EXCEPTION, 0); + } + INTERRUPT(vect, INTR_TYPE_SOFTINTR); + } + } +} + + +/* + * error function + */ +void +ia32_panic(const char *str, ...) +{ + extern char *cpu_reg2str(void); + char buf[2048]; + va_list ap; + + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + strcat(buf, "\n"); + strcat(buf, cpu_reg2str()); + VERBOSE(("%s", buf)); + device_cpu->out_debug_log("PANIC: %s", buf); + msgbox("ia32_panic", buf); + +#if defined(IA32_REBOOT_ON_PANIC) + VERBOSE(("ia32_panic: reboot")); + //pccore_reset(); + //pcstat.screendispflag = 0; + device_cpu->reset(); +#ifdef __cplusplus + throw(2); +#else + siglongjmp(exec_1step_jmpbuf, 2); +#endif +#else + __ASSERT(0); + exit(1); +#endif +} + +void +ia32_warning(const char *str, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + strcat(buf, "\n"); + + msgbox("ia32_warning", buf); +} + +void +ia32_printf(const char *str, ...) +{ + char buf[1024]; + va_list ap; + va_start(ap, str); + vsnprintf(buf, sizeof(buf), str, ap); + va_end(ap); + strcat(buf, "\n"); + + msgbox("ia32_printf", buf); +} + + +/* + * bios call interface + */ +#if 0 +void +ia32_bioscall(void) +{ + UINT32 adrs; + + if (!CPU_STAT_PM || CPU_STAT_VM86) { +#if 1 + adrs = CPU_PREV_EIP + (CPU_CS << 4); +#else + adrs = CPU_PREV_EIP + CPU_STAT_CS_BASE; +#endif + if ((adrs >= 0xf8000) && (adrs < 0x100000)) { + if (biosfunc(adrs)) { + /* Nothing to do */ + } + LOAD_SEGREG(CPU_ES_INDEX, CPU_ES); + LOAD_SEGREG(CPU_CS_INDEX, CPU_CS); + LOAD_SEGREG(CPU_SS_INDEX, CPU_SS); + LOAD_SEGREG(CPU_DS_INDEX, CPU_DS); + } + }else{ +#ifdef SUPPORT_PCI + adrs = CPU_EIP; + if (bios32func(adrs)) { + /* Nothing to do */ + } +#endif + } +} +#endif diff --git a/source/src/vm/np21/i386c/ia32/interface.h b/source/src/vm/np21/i386c/ia32/interface.h new file mode 100644 index 000000000..30706aa78 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/interface.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_INTERFACE_H__ +#define IA32_CPU_INTERFACE_H__ + +#ifndef CPUCALL +#define CPUCALL +#endif + +#ifndef STATIC_INLINE +#if defined(__GNUC__) +#define STATIC_INLINE static INLINE __attribute__((unused)) +#else +#define STATIC_INLINE static INLINE +#endif +#endif + +#if !defined(QWORD_CONST) +#define QWORD_CONST(v) v ## ULL +#define SQWORD_CONST(v) v ## LL +#endif + +#define CPU_isEI (CPU_FLAG & I_FLAG) +#define CPU_isDI (!CPU_isEI) +#define CPU_A20EN(en) CPU_ADRSMASK = (en)?0xffffffff:0x000fffff; + +#define CPU_INITIALIZE() i386c_initialize() +#define CPU_DEINITIALIZE() +#define CPU_RESET() ia32reset() +#define CPU_CLEARPREFETCH() +#define CPU_INTERRUPT(vect, soft) ia32_interrupt(vect, soft) +#define CPU_EXEC() ia32() +#define CPU_EXECV30() ia32() +#define CPU_SHUT() ia32shut() +//#define CPU_SETEXTSIZE(size) ia32_setextsize((UINT32)(size) << 20) +//#define CPU_SETEMM(frame, addr) ia32_setemm(frame, addr) + +#define cpu_memorywrite(a,v) memp_write8(a,v) +#define cpu_memorywrite_b(a,v) memp_write8(a,v) +#define cpu_memorywrite_w(a,v) memp_write16(a,v) +#define cpu_memorywrite_d(a,v) memp_write32(a,v) +#define cpu_memoryread(a) memp_read8(a) +#define cpu_memoryread_b(a) memp_read8(a) +#define cpu_memoryread_w(a) memp_read16(a) +#define cpu_memoryread_d(a) memp_read32(a) +#define cpu_memoryread_codefetch(a) memp_read8_codefetch(a) +#define cpu_memoryread_b_codefetch(a) memp_read8_codefetch(a) +#define cpu_memoryread_w_codefetch(a) memp_read16_codefetch(a) +#define cpu_memoryread_d_codefetch(a) memp_read32_codefetch(a) +#ifdef USE_FASTPAGING +#define cpu_memoryread_paging(a) memp_read8_paging(a) +#define cpu_memoryread_b_paging(a) memp_read8_paging(a) +#define cpu_memoryread_w_paging(a) memp_read16_paging(a) +#define cpu_memoryread_d_paging(a) memp_read32_paging(a) +#define cpu_memorywrite_paging(a,v) memp_write8_paging(a,v) +#define cpu_memorywrite_b_paging(a,v) memp_write8_paging(a,v) +#define cpu_memorywrite_w_paging(a,v) memp_write16_paging(a,v) +#define cpu_memorywrite_d_paging(a,v) memp_write32_paging(a,v) +#else +#define cpu_memoryread_paging(a) memp_read8_codefetch(a) +#define cpu_memoryread_b_paging(a) memp_read8_codefetch(a) +#define cpu_memoryread_w_paging(a) memp_read16_codefetch(a) +#define cpu_memoryread_d_paging(a) memp_read32_codefetch(a) +#define cpu_memorywrite_paging(a,v) memp_write8(a,v) +#define cpu_memorywrite_b_paging(a,v) memp_write8(a,v) +#define cpu_memorywrite_w_paging(a,v) memp_write16(a,v) +#define cpu_memorywrite_d_paging(a,v) memp_write32(a,v) +#endif + +#define cpu_memoryread_region(a,p,l) memp_reads(a,p,l) +#define cpu_memorywrite_region(a,p,l) memp_writes(a,p,l) + +void i386c_initialize(void); + +#endif /* IA32_CPU_INTERFACE_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/paging.cpp b/source/src/vm/np21/i386c/ia32/paging.cpp new file mode 100644 index 000000000..b06198877 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/paging.cpp @@ -0,0 +1,919 @@ +/* + * Copyright (c) 2003-2004 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +/* + * ページフォルト例外 + * + * 4-31: 予約済み + * 3: RSVD: 0 = フォルトの原因は予約ビット違反ではなかった. + * 1 = ページ・フォルトの原因は,違反とマークされた PTE または + * PDE の予約ビット位置のうち一つで,1 が検出されたことである. + * 2: U/S: 0 = フォルトの原因となったアクセスはプロセッサがスーパバイザ・ + * モードで実行中に行われた. + * 1 = フォルトの原因となったアクセスはプロセッサがユーザ・モードで + * 実行中に行われた. + * 1: W/R: 0 = フォルトの原因となったアクセスが読み取りであった. + * 1 = フォルトの原因となったアクセスが書き込みであった. + * 0: P: 0 = フォルトの原因が不在ページであった. + * 1 = フォルトの原因がページ・レベル保護違反であった. + */ + +/* + * 下巻 4.12. ページ保護とセグメント保護の組み合わせ + * 「表 4-2. ページ・ディレクトリとページ・テーブルの保護の組み合わせ」 + * + * +------------+------------+------------+ + * | PDE | PTE | merge | + * +-----+------+-----+------+-----+------+ + * | pri | type | pri | type | pri | type | + * +-----+------+-----+------+-----+------+ + * | u | ro | u | ro | u | ro | + * | u | ro | u | rw | u | ro | + * | u | rw | u | ro | u | ro | + * | u | rw | u | rw | u | rw | + * | u | ro | s | ro | s | rw/p | + * | u | ro | s | rw | s | rw/p | + * | u | rw | s | ro | s | rw/p | + * | u | rw | s | rw | s | rw | + * | s | ro | u | ro | s | rw/p | + * | s | ro | u | rw | s | rw/p | + * | s | rw | u | ro | s | rw/p | + * | s | rw | u | rw | s | rw | + * | s | ro | s | ro | s | rw/p | + * | s | ro | s | rw | s | rw/p | + * | s | rw | s | ro | s | rw/p | + * | s | rw | s | rw | s | rw | + * +-----+------+-----+------+-----+------+ + * + * ※ rw/p : CR0 の WP ビットが ON の場合には ro + */ + +/* + * メモリアクセス/PxE(上記参照)/CPL/CR0 とページアクセス権の関係 + * + * +-----+-----+-----+-----+-----+---+ + * | CR0 | CPL | PxE | PxE | ope | | + * | W/P | u/s | u/s | r/w | r/w | | + * +-----+-----+-----+-----+-----+---+ + * | n/a | s | s | n/a | r | o | + * | n/a | s | u | n/a | r | o | + * | n/a | u | s | n/a | r | x | + * | n/a | u | u | n/a | r | o | + * +-----+-----+-----+-----+-----+---+ + * | n | s | s | r | w | o | + * | n | s | u | r | w | o | + * | n | u | s | r | w | x | + * | n | u | u | r | w | x | + * +-----+-----+-----+-----+-----+---+ + * | p | s | s | r | w | x | + * | p | s | u | r | w | x | + * | p | u | s | r | w | x | + * | p | u | u | r | w | x | + * +-----+-----+-----+-----+-----+---+ + * | n | s | s | w | w | o | + * | n | s | u | w | w | o | + * | n | u | s | w | w | x | + * | n | u | u | w | w | o | + * +-----+-----+-----+-----+-----+---+ + * | p | s | s | w | w | o | + * | p | s | u | w | w | x | + * | p | u | s | w | w | x | + * | p | u | u | w | w | o | + * +-----+-----------+-----+-----+---+ + */ +#if !defined(USE_PAGE_ACCESS_TABLE) +#define page_access 0xd0ddd0ff +#else /* USE_PAGE_ACCESS_TABLE */ +static const UINT8 page_access_bit[32] = { + 1, /* CR0: n, CPL: s, PTE: s, PTE: r, ope: r */ + 1, /* CR0: n, CPL: s, PTE: s, PTE: r, ope: w */ + 1, /* CR0: n, CPL: s, PTE: s, PTE: w, ope: r */ + 1, /* CR0: n, CPL: s, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: n, CPL: s, PTE: u, PTE: r, ope: r */ + 1, /* CR0: n, CPL: s, PTE: u, PTE: r, ope: w */ + 1, /* CR0: n, CPL: s, PTE: u, PTE: w, ope: r */ + 1, /* CR0: n, CPL: s, PTE: u, PTE: w, ope: w */ + + 0, /* CR0: n, CPL: u, PTE: s, PTE: r, ope: r */ + 0, /* CR0: n, CPL: u, PTE: s, PTE: r, ope: w */ + 0, /* CR0: n, CPL: u, PTE: s, PTE: w, ope: r */ + 0, /* CR0: n, CPL: u, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: n, CPL: u, PTE: u, PTE: r, ope: r */ + 0, /* CR0: n, CPL: u, PTE: u, PTE: r, ope: w */ + 1, /* CR0: n, CPL: u, PTE: u, PTE: w, ope: r */ + 1, /* CR0: n, CPL: u, PTE: u, PTE: w, ope: w */ + + 1, /* CR0: p, CPL: s, PTE: s, PTE: r, ope: r */ + 0, /* CR0: p, CPL: s, PTE: s, PTE: r, ope: w */ + 1, /* CR0: p, CPL: s, PTE: s, PTE: w, ope: r */ + 1, /* CR0: p, CPL: s, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: p, CPL: s, PTE: u, PTE: r, ope: r */ + 0, /* CR0: p, CPL: s, PTE: u, PTE: r, ope: w */ + 1, /* CR0: p, CPL: s, PTE: u, PTE: w, ope: r */ + 1, /* CR0: p, CPL: s, PTE: u, PTE: w, ope: w */ + + 0, /* CR0: p, CPL: u, PTE: s, PTE: r, ope: r */ + 0, /* CR0: p, CPL: u, PTE: s, PTE: r, ope: w */ + 0, /* CR0: p, CPL: u, PTE: s, PTE: w, ope: r */ + 0, /* CR0: p, CPL: u, PTE: s, PTE: w, ope: w */ + + 1, /* CR0: p, CPL: u, PTE: u, PTE: r, ope: r */ + 0, /* CR0: p, CPL: u, PTE: u, PTE: r, ope: w */ + 1, /* CR0: p, CPL: u, PTE: u, PTE: w, ope: r */ + 1, /* CR0: p, CPL: u, PTE: u, PTE: w, ope: w */ +}; +#endif /* !USE_PAGE_ACCESS_TABLE */ + +/* + *-- + * 32bit 物理アドレス 4k ページ + * + * リニア・アドレス + * 31 22 21 12 11 0 + * +------------------------+----------------------+--------------------------+ + * | ページ・ディレクトリ | ページ・テーブル | オフセット | + * +------------------------+----------------------+--------------------------+ + * | | | + * +-----------+ +-----------+ +----------+ + * | | | + * | ページ・ディレクトリ | ページ・テーブル ページ | + * | +--------------------+ | +-------------------+ +------------------+ | + * | | | | | | | | | + * | | | | +-------------------+ | | | + * | | | +>| page table entry |-+ | | | + * | +--------------------+ +-------------------+ | | | | + * +>|page directory entry|-+ | | | +------------------+ | + * +--------------------+ | | | | | physical address |<+ + * | | | | | | +------------------+ + * | | | | | | | | + * +>+--------------------+ +>+-------------------+ +>+------------------+ + * | + * +- CR3(物理アドレス) + */ +/* TLB */ +struct tlb_entry { + UINT32 tag; /* linear address */ +#define TLB_ENTRY_TAG_VALID (1 << 0) +/* pde & pte & CPU_PTE_WRITABLE (1 << 1) */ +/* pde & pte & CPU_PTE_USER_MODE (1 << 2) */ +#define TLB_ENTRY_TAG_DIRTY CPU_PTE_DIRTY /* (1 << 6) */ +#define TLB_ENTRY_TAG_GLOBAL CPU_PTE_GLOBAL_PAGE /* (1 << 8) */ +#define TLB_ENTRY_TAG_MAX_SHIFT 12 + UINT32 paddr; /* physical address */ +}; +static __inline__ void MEMCALL tlb_update(UINT32 laddr, UINT entry, int ucrw); + +/* paging */ +static __inline__ UINT32 MEMCALL paging(UINT32 laddr, int ucrw); + +/* + * linear memory access + */ +/* RMW */ +UINT8 MEMCALL +cpu_memory_access_la_RMW_b(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) +{ + const int ucrw = CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE; + UINT32 paddr; + UINT32 result; + UINT8 value; + + paddr = paging(laddr, ucrw); + value = cpu_memoryread(paddr); + result = (*func)(value, arg); + cpu_memorywrite(paddr, (UINT8)result); + return value; +} + +UINT16 MEMCALL +cpu_memory_access_la_RMW_w(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) +{ + const int ucrw = CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE; + UINT32 paddr[2]; + UINT32 result; + UINT16 value; + + paddr[0] = paging(laddr, ucrw); + if ((laddr + 1) & CPU_PAGE_MASK) { + value = cpu_memoryread_w(paddr[0]); + result = (*func)(value, arg); + cpu_memorywrite_w(paddr[0], (UINT16)result); + return value; + } + + paddr[1] = paging(laddr + 1, ucrw); + value = cpu_memoryread_b(paddr[0]); + value += (UINT16)cpu_memoryread_b(paddr[1]) << 8; + result = (*func)(value, arg); + cpu_memorywrite(paddr[0], (UINT8)result); + cpu_memorywrite(paddr[1], (UINT8)(result >> 8)); + return value; +} + +UINT32 MEMCALL +cpu_memory_access_la_RMW_d(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) +{ + const int ucrw = CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE; + UINT32 paddr[2]; + UINT32 result; + UINT32 value; + int remain; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= 4) { + value = cpu_memoryread_d(paddr[0]); + result = (*func)(value, arg); + cpu_memorywrite_d(paddr[0], result); + return value; + } + + paddr[1] = paging(laddr + remain, ucrw); + switch (remain) { + case 3: + value = cpu_memoryread(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[0] + 1) << 8; + value += (UINT32)cpu_memoryread(paddr[1]) << 24; + result = (*func)(value, arg); + cpu_memorywrite(paddr[0], (UINT8)result); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(result >> 8)); + cpu_memorywrite(paddr[1], (UINT8)(result >> 24)); + break; + + case 2: + value = cpu_memoryread_w(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[1]) << 16; + result = (*func)(value, arg); + cpu_memorywrite_w(paddr[0], (UINT16)result); + cpu_memorywrite_w(paddr[1], (UINT16)(result >> 16)); + break; + + case 1: + value = cpu_memoryread(paddr[0]); + value += (UINT32)cpu_memoryread_w(paddr[1]) << 8; + value += (UINT32)cpu_memoryread(paddr[1] + 2) << 24; + result = (*func)(value, arg); + cpu_memorywrite(paddr[0], (UINT8)result); + cpu_memorywrite_w(paddr[1], (UINT16)(result >> 8)); + cpu_memorywrite(paddr[1] + 2, (UINT8)(result >> 24)); + break; + + default: + ia32_panic("cpu_memory_access_la_RMW_d: out of range (remain=%d)\n", remain); + value = 0; /* XXX compiler happy */ + break; + } + return value; +} + +/* read */ +UINT8 MEMCALL +cpu_linear_memory_read_b(UINT32 laddr, int ucrw) +{ + return cpu_memoryread(paging(laddr, ucrw)); +} +UINT8 MEMCALL +cpu_linear_memory_read_b_codefetch(UINT32 laddr, int ucrw) +{ + return cpu_memoryread_codefetch(paging(laddr, ucrw)); +} + +UINT16 MEMCALL +cpu_linear_memory_read_w(UINT32 laddr, int ucrw) +{ + UINT32 paddr[2]; + UINT16 value; + + paddr[0] = paging(laddr, ucrw); + if ((laddr + 1) & CPU_PAGE_MASK) + return cpu_memoryread_w(paddr[0]); + + paddr[1] = paging(laddr + 1, ucrw); + value = cpu_memoryread_b(paddr[0]); + value |= (UINT16)cpu_memoryread_b(paddr[1]) << 8; + return value; +} +UINT16 MEMCALL +cpu_linear_memory_read_w_codefetch(UINT32 laddr, int ucrw) +{ + UINT32 paddr[2]; + UINT16 value; + + paddr[0] = paging(laddr, ucrw); + if ((laddr + 1) & CPU_PAGE_MASK) + return cpu_memoryread_w_codefetch(paddr[0]); + + paddr[1] = paging(laddr + 1, ucrw); + value = cpu_memoryread_b_codefetch(paddr[0]); + value |= (UINT16)cpu_memoryread_b_codefetch(paddr[1]) << 8; + return value; +} + + +UINT32 MEMCALL +cpu_linear_memory_read_d(UINT32 laddr, int ucrw) +{ + UINT32 paddr[2]; + UINT32 value; + UINT remain; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) + return cpu_memoryread_d(paddr[0]); + + paddr[1] = paging(laddr + remain, ucrw); + switch (remain) { + case 3: + value = cpu_memoryread(paddr[0]); + value |= (UINT32)cpu_memoryread_w(paddr[0] + 1) << 8; + value |= (UINT32)cpu_memoryread(paddr[1]) << 24; + break; + + case 2: + value = cpu_memoryread_w(paddr[0]); + value |= (UINT32)cpu_memoryread_w(paddr[1]) << 16; + break; + + case 1: + value = cpu_memoryread(paddr[0]); + value |= (UINT32)cpu_memoryread_w(paddr[1]) << 8; + value |= (UINT32)cpu_memoryread(paddr[1] + 2) << 24; + break; + + default: + ia32_panic("cpu_linear_memory_read_d: out of range (remain=%d)\n", remain); + value = 0; /* XXX compiler happy */ + break; + } + return value; +} +UINT32 MEMCALL +cpu_linear_memory_read_d_codefetch(UINT32 laddr, int ucrw) +{ + UINT32 paddr[2]; + UINT32 value; + UINT remain; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) + return cpu_memoryread_d_codefetch(paddr[0]); + + paddr[1] = paging(laddr + remain, ucrw); + switch (remain) { + case 3: + value = cpu_memoryread_codefetch(paddr[0]); + value |= (UINT32)cpu_memoryread_w_codefetch(paddr[0] + 1) << 8; + value |= (UINT32)cpu_memoryread_codefetch(paddr[1]) << 24; + break; + + case 2: + value = cpu_memoryread_w_codefetch(paddr[0]); + value |= (UINT32)cpu_memoryread_w_codefetch(paddr[1]) << 16; + break; + + case 1: + value = cpu_memoryread_codefetch(paddr[0]); + value |= (UINT32)cpu_memoryread_w_codefetch(paddr[1]) << 8; + value |= (UINT32)cpu_memoryread_codefetch(paddr[1] + 2) << 24; + break; + + default: + ia32_panic("cpu_linear_memory_read_d: out of range (remain=%d)\n", remain); + value = 0; /* XXX compiler happy */ + break; + } + return value; +} + +UINT64 MEMCALL +cpu_linear_memory_read_q(UINT32 laddr, int ucrw) +{ + UINT32 paddr[2]; + UINT64 value; + UINT remain; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) + return cpu_memoryread_q(paddr[0]); + + paddr[1] = paging(laddr + remain, ucrw); + switch (remain) { + case 7: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_w(paddr[0] + 1) << 8; + value += (UINT64)cpu_memoryread_d(paddr[0] + 3) << 24; + value += (UINT64)cpu_memoryread(paddr[1]) << 56; + break; + + case 6: + value = cpu_memoryread_w(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[0] + 2) << 16; + value += (UINT64)cpu_memoryread_w(paddr[1]) << 48; + break; + + case 5: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[0] + 1) << 8; + value += (UINT64)cpu_memoryread_w(paddr[1]) << 40; + value += (UINT64)cpu_memoryread(paddr[1] + 2) << 56; + break; + + case 4: + value = cpu_memoryread_d(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[1]) << 32; + break; + + case 3: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_w(paddr[0] + 1) << 8; + value += (UINT64)cpu_memoryread_d(paddr[1]) << 24; + value += (UINT64)cpu_memoryread(paddr[1] + 4) << 56; + break; + + case 2: + value = cpu_memoryread_w(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[1]) << 16; + value += (UINT64)cpu_memoryread_w(paddr[1] + 4) << 48; + break; + + case 1: + value = cpu_memoryread(paddr[0]); + value += (UINT64)cpu_memoryread_d(paddr[1]) << 8; + value += (UINT64)cpu_memoryread_w(paddr[1] + 4) << 40; + value += (UINT64)cpu_memoryread(paddr[1] + 6) << 56; + break; + + default: + ia32_panic("cpu_linear_memory_read_q: out of range (remain=%d)\n", remain); + value = 0; /* XXX compiler happy */ + break; + } + return value; +} + +REG80 MEMCALL +cpu_linear_memory_read_f(UINT32 laddr, int ucrw) +{ + UINT32 paddr[2]; + REG80 value; + UINT remain; + UINT i, j; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) + return cpu_memoryread_f(paddr[0]); + + paddr[1] = paging(laddr + remain, ucrw); + for (i = 0; i < remain; ++i) { + value.b[i] = cpu_memoryread(paddr[0] + i); + } + for (j = 0; i < 10; ++i, ++j) { + value.b[i] = cpu_memoryread(paddr[1] + j); + } + return value; +} + +/* write */ +void MEMCALL +cpu_linear_memory_write_b(UINT32 laddr, UINT8 value, int ucrw) +{ + + cpu_memorywrite(paging(laddr, ucrw), value); +} + +void MEMCALL +cpu_linear_memory_write_w(UINT32 laddr, UINT16 value, int ucrw) +{ + UINT32 paddr[2]; + + paddr[0] = paging(laddr, ucrw); + if ((laddr + 1) & CPU_PAGE_MASK) { + cpu_memorywrite_w(paddr[0], value); + return; + } + + paddr[1] = paging(laddr + 1, ucrw); + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite(paddr[1], (UINT8)(value >> 8)); +} + +void MEMCALL +cpu_linear_memory_write_d(UINT32 laddr, UINT32 value, int ucrw) +{ + UINT32 paddr[2]; + UINT remain; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_d(paddr[0], value); + return; + } + + paddr[1] = paging(laddr + remain, ucrw); + switch (remain) { + case 3: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); + cpu_memorywrite(paddr[1], (UINT8)(value >> 24)); + break; + + case 2: + cpu_memorywrite_w(paddr[0], (UINT16)value); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 16)); + break; + + case 1: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 8)); + cpu_memorywrite(paddr[1] + 2, (UINT8)(value >> 24)); + break; + + default: + ia32_panic("cpu_linear_memory_write_d: out of range (remain=%d)\n", remain); + break; + } +} + +void MEMCALL +cpu_linear_memory_write_q(UINT32 laddr, UINT64 value, int ucrw) +{ + UINT32 paddr[2]; + UINT remain; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_q(paddr[0], value); + return; + } + + paddr[1] = paging(laddr + remain, ucrw); + switch (remain) { + case 7: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); + cpu_memorywrite_d(paddr[0] + 3, (UINT32)(value >> 24)); + cpu_memorywrite(paddr[1], (UINT8)(value >> 56)); + break; + + case 6: + cpu_memorywrite_w(paddr[0], (UINT16)value); + cpu_memorywrite_d(paddr[0] + 2, (UINT32)(value >> 16)); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 48)); + break; + + case 5: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_d(paddr[0] + 1, (UINT32)(value >> 8)); + cpu_memorywrite_w(paddr[1], (UINT16)(value >> 40)); + cpu_memorywrite(paddr[1] + 2, (UINT8)(value >> 56)); + break; + + case 4: + cpu_memorywrite_d(paddr[0], (UINT32)value); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 32)); + break; + + case 3: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_w(paddr[0] + 1, (UINT16)(value >> 8)); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 24)); + cpu_memorywrite(paddr[1] + 4, (UINT8)(value >> 56)); + break; + + case 2: + cpu_memorywrite_w(paddr[0], (UINT16)value); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 16)); + cpu_memorywrite_w(paddr[1] + 4, (UINT16)(value >> 48)); + break; + + case 1: + cpu_memorywrite(paddr[0], (UINT8)value); + cpu_memorywrite_d(paddr[1], (UINT32)(value >> 8)); + cpu_memorywrite_w(paddr[1] + 4, (UINT16)(value >> 40)); + cpu_memorywrite(paddr[1] + 6, (UINT8)(value >> 56)); + break; + + default: + ia32_panic("cpu_linear_memory_write_q: out of range (remain=%d)\n", remain); + break; + } +} + +void MEMCALL +cpu_linear_memory_write_f(UINT32 laddr, const REG80 *value, int ucrw) +{ + UINT32 paddr[2]; + UINT remain; + UINT i, j; + + paddr[0] = paging(laddr, ucrw); + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (remain >= sizeof(value)) { + cpu_memorywrite_f(paddr[0], value); + return; + } + + paddr[1] = paging(laddr + remain, ucrw); + for (i = 0; i < remain; ++i) { + cpu_memorywrite(paddr[0] + i, value->b[i]); + } + for (j = 0; i < 10; ++i, ++j) { + cpu_memorywrite(paddr[1] + j, value->b[i]); + } +} + +/* + * linear address memory access function + */ +void MEMCALL +cpu_memory_access_la_region(UINT32 laddr, UINT length, int ucrw, UINT8 *data) +{ + UINT32 paddr; + UINT remain; /* page remain */ + UINT r; + + while (length > 0) { + remain = CPU_PAGE_SIZE - (laddr & CPU_PAGE_MASK); + if (!CPU_STAT_PAGING) { + paddr = laddr; + } else { + paddr = paging(laddr, ucrw); + } + + r = (remain > length) ? length : remain; + if (!(ucrw & CPU_PAGE_WRITE)) { + cpu_memoryread_region(paddr, data, r); + } else { + cpu_memorywrite_region(paddr, data, r); + } + + laddr += r; + data += r; + length -= r; + } +} + +UINT32 MEMCALL +laddr2paddr(UINT32 laddr, int ucrw) +{ + + return paging(laddr, ucrw); +} + +/* + * paging + */ +static __inline__ UINT32 MEMCALL +paging(UINT32 laddr, int ucrw) +{ + struct tlb_entry *ep; + UINT32 paddr; /* physical address */ + UINT32 pde_addr; /* page directory entry address */ + UINT32 pde; /* page directory entry */ + UINT32 pte_addr; /* page table entry address */ + UINT32 pte; /* page table entry */ + UINT bit; + UINT err; + + ep = tlb_lookup(laddr, ucrw); + if (ep != NULL) + return ep->paddr + (laddr & CPU_PAGE_MASK); + + pde_addr = CPU_STAT_PDE_BASE + ((laddr >> 20) & 0xffc); + pde = cpu_memoryread_d_paging(pde_addr); + if (!(pde & CPU_PDE_PRESENT)) { + VERBOSE(("paging: PTE page is not present")); + VERBOSE(("paging: CPU_CR3 = 0x%08x", CPU_CR3)); + VERBOSE(("paging: laddr = 0x%08x, pde_addr = 0x%08x, pde = 0x%08x", laddr, pde_addr, pde)); + err = 0; + goto pf_exception; + } + if (!(pde & CPU_PDE_ACCESS)) { + pde |= CPU_PDE_ACCESS; + cpu_memorywrite_d_paging(pde_addr, pde); + } + + pte_addr = (pde & CPU_PDE_BASEADDR_MASK) + ((laddr >> 10) & 0xffc); + pte = cpu_memoryread_d_paging(pte_addr); + if (!(pte & CPU_PTE_PRESENT)) { + VERBOSE(("paging: page is not present")); + VERBOSE(("paging: laddr = 0x%08x, pde_addr = 0x%08x, pde = 0x%08x", laddr, pde_addr, pde)); + VERBOSE(("paging: pte_addr = 0x%08x, pte = 0x%08x", pte_addr, pte)); + err = 0; + goto pf_exception; + } + if (!(pte & CPU_PTE_ACCESS)) { + pte |= CPU_PTE_ACCESS; + cpu_memorywrite_d_paging(pte_addr, pte); + } + + /* make physical address */ + paddr = (pte & CPU_PTE_BASEADDR_MASK) + (laddr & CPU_PAGE_MASK); + + bit = ucrw & (CPU_PAGE_WRITE|CPU_PAGE_USER_MODE); + bit |= (pde & pte & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)); + bit |= CPU_STAT_WP; + +#if !defined(USE_PAGE_ACCESS_TABLE) + if (!(page_access & (1 << bit))) +#else + if (!(page_access_bit[bit])) +#endif + { + VERBOSE(("paging: page access violation.")); + VERBOSE(("paging: laddr = 0x%08x, pde_addr = 0x%08x, pde = 0x%08x", laddr, pde_addr, pde)); + VERBOSE(("paging: pte_addr = 0x%08x, pte = 0x%08x", pte_addr, pte)); + VERBOSE(("paging: paddr = 0x%08x, bit = 0x%08x", paddr, bit)); + err = 1; + goto pf_exception; + } + + if ((ucrw & CPU_PAGE_WRITE) && !(pte & CPU_PTE_DIRTY)) { + pte |= CPU_PTE_DIRTY; + cpu_memorywrite_d_paging(pte_addr, pte); + } + + tlb_update(laddr, pte, (bit & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE)) + ((ucrw & CPU_PAGE_CODE) ? 1 : 0)); + + return paddr; + +pf_exception: + CPU_CR2 = laddr; + err |= (ucrw & CPU_PAGE_WRITE) << 1; + err |= (ucrw & CPU_PAGE_USER_MODE) >> 1; + EXCEPTION(PF_EXCEPTION, err); + return 0; /* compiler happy */ +} + +/* + * TLB + */ +#define TLB_TAG_SHIFT TLB_ENTRY_TAG_MAX_SHIFT +#define TLB_TAG_MASK (~((1 << TLB_TAG_SHIFT) - 1)) +#define TLB_GET_TAG_ADDR(ep) ((ep)->tag & TLB_TAG_MASK) +#define TLB_SET_TAG_ADDR(ep, addr) \ +do { \ + (ep)->tag &= ~TLB_TAG_MASK; \ + (ep)->tag |= (addr) & TLB_TAG_MASK; \ +} while (/*CONSTCOND(*/ 0) + +#define TLB_IS_VALID(ep) ((ep)->tag & TLB_ENTRY_TAG_VALID) +#define TLB_SET_VALID(ep) ((ep)->tag = TLB_ENTRY_TAG_VALID) +#define TLB_SET_INVALID(ep) ((ep)->tag = 0) + +#define TLB_IS_WRITABLE(ep) ((ep)->tag & CPU_PTE_WRITABLE) +#define TLB_IS_USERMODE(ep) ((ep)->tag & CPU_PTE_USER_MODE) +#define TLB_IS_DIRTY(ep) ((ep)->tag & TLB_ENTRY_TAG_DIRTY) +#if (CPU_FEATURES & CPU_FEATURE_PGE) == CPU_FEATURE_PGE +#define TLB_IS_GLOBAL(ep) ((ep)->tag & TLB_ENTRY_TAG_GLOBAL) +#else +#define TLB_IS_GLOBAL(ep) 0 +#endif + +#define TLB_SET_TAG_FLAGS(ep, entry, bit) \ +do { \ + (ep)->tag |= (entry) & (CPU_PTE_GLOBAL_PAGE|CPU_PTE_DIRTY); \ + (ep)->tag |= (bit) & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE); \ +} while (/*CONSTCOND*/ 0) + +#define NTLB 2 /* 0: DTLB, 1: ITLB */ +#define NENTRY (1 << 8) +#define TLB_ENTRY_SHIFT 12 +#define TLB_ENTRY_MASK (NENTRY - 1) + +typedef struct { + struct tlb_entry entry[NENTRY]; +} tlb_t; +static tlb_t tlb[NTLB]; + +void +tlb_init(void) +{ + memset(tlb, 0, sizeof(tlb)); +} + +void MEMCALL +tlb_flush() +{ + struct tlb_entry *ep; + int i; + int n; + + for (n = 0; n < NTLB; n++) { + for (i = 0; i < NENTRY ; i++) { + ep = &tlb[n].entry[i]; + if (TLB_IS_VALID(ep) && !TLB_IS_GLOBAL(ep)) { + TLB_SET_INVALID(ep); + } + } + } +} + +void MEMCALL +tlb_flush_all() +{ + tlb_init(); +} + +void MEMCALL +tlb_flush_page(UINT32 laddr) +{ + struct tlb_entry *ep; + int idx; + int n; + + idx = (laddr >> TLB_ENTRY_SHIFT) & TLB_ENTRY_MASK; + + for (n = 0; n < NTLB; n++) { + ep = &tlb[n].entry[idx]; + if (TLB_IS_VALID(ep)) { + if ((laddr & TLB_TAG_MASK) == TLB_GET_TAG_ADDR(ep)) { + TLB_SET_INVALID(ep); + } + } + } +} + +struct tlb_entry * MEMCALL +tlb_lookup(UINT32 laddr, int ucrw) +{ + struct tlb_entry *ep; + UINT bit; + int idx; + int n; + + n = (ucrw & CPU_PAGE_CODE) ? 1 : 0; + idx = (laddr >> TLB_ENTRY_SHIFT) & TLB_ENTRY_MASK; + ep = &tlb[n].entry[idx]; + + if (TLB_IS_VALID(ep)) { + if ((laddr & TLB_TAG_MASK) == TLB_GET_TAG_ADDR(ep)) { + bit = ucrw & (CPU_PAGE_WRITE|CPU_PAGE_USER_MODE); + bit |= ep->tag & (CPU_PTE_WRITABLE|CPU_PTE_USER_MODE); + bit |= CPU_STAT_WP; +#if !defined(USE_PAGE_ACCESS_TABLE) + if ((page_access & (1 << bit))) +#else + if (page_access_bit[bit]) +#endif + { + if (!(ucrw & CPU_PAGE_WRITE) || TLB_IS_DIRTY(ep)) { + return ep; + } + } + } + } + return NULL; +} + +static __inline__ void MEMCALL +tlb_update(UINT32 laddr, UINT entry, int bit) +{ + struct tlb_entry *ep; + int idx; + int n; + + n = bit & 1; + idx = (laddr >> TLB_ENTRY_SHIFT) & TLB_ENTRY_MASK; + ep = &tlb[n].entry[idx]; + + TLB_SET_VALID(ep); + TLB_SET_TAG_ADDR(ep, laddr); + TLB_SET_TAG_FLAGS(ep, entry, bit); + ep->paddr = entry & CPU_PTE_BASEADDR_MASK; +} diff --git a/source/src/vm/np21/i386c/ia32/paging.h b/source/src/vm/np21/i386c/ia32/paging.h new file mode 100644 index 000000000..99f9e09f1 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/paging.h @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_PAGING_H__ +#define IA32_CPU_PAGING_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * ページ・ディレクトリ・エントリ (4K バイトページ使用時) + * + * 31 12 11 9 8 7 6 5 4 3 2 1 0 + * +----------------------------------------+------+-+--+-+-+---+---+---+---+-+ + * | ページ・テーブルのベース・アドレス |使用可|G|PS|-|A|PCD|PWT|U/S|R/W|P| + * +----------------------------------------+------+-+--+-+-+---+---+---+---+-+ + * | | | | | | | | | | + * 9-11: システム・プログラマが使用可能 --------+ | | | | | | | | | + * 8: グローバル・ページ(無視される) ------------+ | | | | | | | | + * 7: ページ・サイズ (0 = 4k バイトページ) ---------+ | | | | | | | + * 6: 予約 (-) ---------------------------------------+ | | | | | | + * 5: アクセス -----------------------------------------+ | | | | | + * 4: キャッシュ無効 --------------------------------------+ | | | | + * 3: ライトスルー --------------------------------------------+ | | | + * 2: ユーザ/スーパバイザ (0 = スーパバイザ) ---------------------+ | | + * 1: 読み取り/書き込み (0 = 読み取りのみ) ---------------------------+ | + * 0: ページ存在 ---------------------------------------------------------+ + */ +#define CPU_PDE_BASEADDR_MASK 0xfffff000 +#define CPU_PDE_GLOBAL_PAGE (1 << 8) +#define CPU_PDE_PAGE_SIZE (1 << 7) +#define CPU_PDE_DIRTY (1 << 6) +#define CPU_PDE_ACCESS (1 << 5) +#define CPU_PDE_CACHE_DISABLE (1 << 4) +#define CPU_PDE_WRITE_THROUGH (1 << 3) +#define CPU_PDE_USER_MODE (1 << 2) +#define CPU_PDE_WRITABLE (1 << 1) +#define CPU_PDE_PRESENT (1 << 0) + +/* + * ページ・ディレクトリ・エントリ (4M バイトページ使用時) + * + * 31 22 21 12 11 9 8 7 6 5 4 3 2 1 0 + * +----------------------------+-----------+------+-+--+-+-+---+---+---+---+-+ + * |ページテーブルの物理アドレス| 予約済み |使用可|G|PS|D|A|PCD|PWT|U/S|R/W|P| + * +----------------------------+-----------+------+-+--+-+-+---+---+---+---+-+ + * | | | | | | | | | | + * 9-11: システム・プログラマが使用可能 --------+ | | | | | | | | | + * 8: グローバル・ページ ------------------------+ | | | | | | | | + * 7: ページ・サイズ (1 = 4M バイトページ) ---------+ | | | | | | | + * 6: ダーティ ---------------------------------------+ | | | | | | + * 5: アクセス -----------------------------------------+ | | | | | + * 4: キャッシュ無効 --------------------------------------+ | | | | + * 3: ライトスルー --------------------------------------------+ | | | + * 2: ユーザ/スーパバイザ (0 = スーパバイザ) ---------------------+ | | + * 1: 読み取り/書き込み (0 = 読み取りのみ) ---------------------------+ | + * 0: ページ存在 ---------------------------------------------------------+ + */ +#define CPU_PDE_4M_BASEADDR_MASK 0xffc00000 +#define CPU_PDE_4M_GLOBAL_PAGE (1 << 8) +#define CPU_PDE_4M_PAGE_SIZE (1 << 7) +#define CPU_PDE_4M_DIRTY (1 << 6) +#define CPU_PDE_4M_ACCESS (1 << 5) +#define CPU_PDE_4M_CACHE_DISABLE (1 << 4) +#define CPU_PDE_4M_WRITE_THROUGH (1 << 3) +#define CPU_PDE_4M_USER_MODE (1 << 2) +#define CPU_PDE_4M_WRITABLE (1 << 1) +#define CPU_PDE_4M_PRESENT (1 << 0) + +/* + * ページ・テーブル・エントリ (4k バイト・ページ) + * + * 31 12 11 9 8 7 6 5 4 3 2 1 0 + * +----------------------------------------+------+-+-+-+-+---+---+---+---+-+ + * | ページのベース・アドレス |使用可|G|-|D|A|PCD|PWT|U/S|R/W|P| + * +----------------------------------------+------+-+-+-+-+---+---+---+---+-+ + * | | | | | | | | | | + * 9-11: システム・プログラマが使用可能 -------+ | | | | | | | | | + * 8: グローバル・ページ -----------------------+ | | | | | | | | + * 7: 予約 (-) -----------------------------------+ | | | | | | | + * 6: ダーティ -------------------------------------+ | | | | | | + * 5: アクセス ---------------------------------------+ | | | | | + * 4: キャッシュ無効 ------------------------------------+ | | | | + * 3: ライトスルー ------------------------------------------+ | | | + * 2: ユーザ/スーパバイザ (0 = スーパバイザ) -------------------+ | | + * 1: 読み取り/書き込み (0 = 読み取りのみ) -------------------------+ | + * 0: ページ存在 -------------------------------------------------------+ + */ +#define CPU_PTE_BASEADDR_MASK 0xfffff000 +#define CPU_PTE_GLOBAL_PAGE (1 << 8) +#define CPU_PTE_PAGE_SIZE (1 << 7) +#define CPU_PTE_DIRTY (1 << 6) +#define CPU_PTE_ACCESS (1 << 5) +#define CPU_PTE_CACHE_DISABLE (1 << 4) +#define CPU_PTE_WRITE_THROUGH (1 << 3) +#define CPU_PTE_USER_MODE (1 << 2) +#define CPU_PTE_WRITABLE (1 << 1) +#define CPU_PTE_PRESENT (1 << 0) + +#define CPU_PAGE_SIZE 0x1000 +#define CPU_PAGE_MASK (CPU_PAGE_SIZE - 1) + +/* ucrw */ +#define CPU_PAGE_WRITE (1 << 0) +#define CPU_PAGE_CODE (1 << 1) +#define CPU_PAGE_DATA (1 << 2) +#define CPU_PAGE_USER_MODE (1 << 3) /* == CPU_MODE_USER */ +#define CPU_PAGE_READ_CODE (CPU_PAGE_CODE) +#define CPU_PAGE_READ_DATA (CPU_PAGE_DATA) +#define CPU_PAGE_WRITE_DATA (CPU_PAGE_WRITE|CPU_PAGE_DATA) + +UINT8 MEMCALL cpu_memory_access_la_RMW_b(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg); +UINT16 MEMCALL cpu_memory_access_la_RMW_w(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg); +UINT32 MEMCALL cpu_memory_access_la_RMW_d(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg); +UINT8 MEMCALL cpu_linear_memory_read_b(UINT32 laddr, int ucrw); +UINT16 MEMCALL cpu_linear_memory_read_w(UINT32 laddr, int ucrw); +UINT32 MEMCALL cpu_linear_memory_read_d(UINT32 laddr, int ucrw); +UINT64 MEMCALL cpu_linear_memory_read_q(UINT32 laddr, int ucrw); +UINT8 MEMCALL cpu_linear_memory_read_b_codefetch(UINT32 laddr, int ucrw); +UINT16 MEMCALL cpu_linear_memory_read_w_codefetch(UINT32 laddr, int ucrw); +UINT32 MEMCALL cpu_linear_memory_read_d_codefetch(UINT32 laddr, int ucrw); +REG80 MEMCALL cpu_linear_memory_read_f(UINT32 laddr, int ucrw); +void MEMCALL cpu_linear_memory_write_b(UINT32 laddr, UINT8 value, int ucrw); +void MEMCALL cpu_linear_memory_write_w(UINT32 laddr, UINT16 value, int ucrw); +void MEMCALL cpu_linear_memory_write_d(UINT32 laddr, UINT32 value, int ucrw); +void MEMCALL cpu_linear_memory_write_q(UINT32 laddr, UINT64 value, int ucrw); +void MEMCALL cpu_linear_memory_write_f(UINT32 laddr, const REG80 *value, int ucrw); + +/* + * linear address memory access function with TLB + */ +/* RMW */ +STATIC_INLINE UINT8 MEMCALL +cpu_lmemory_RMW_b(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) +{ + UINT32 result; + UINT8 value; + + if (!CPU_STAT_PAGING) { + value = cpu_memoryread_b(laddr); + result = (*func)(value, arg); + cpu_memorywrite_b(laddr, (UINT8)result); + return value; + } + return cpu_memory_access_la_RMW_b(laddr, func, arg); +} + +STATIC_INLINE UINT16 MEMCALL +cpu_lmemory_RMW_w(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) +{ + UINT32 result; + UINT16 value; + + if (!CPU_STAT_PAGING) { + value = cpu_memoryread_w(laddr); + result = (*func)(value, arg); + cpu_memorywrite_w(laddr, (UINT16)result); + return value; + } + return cpu_memory_access_la_RMW_w(laddr, func, arg); +} + +STATIC_INLINE UINT32 MEMCALL +cpu_lmemory_RMW_d(UINT32 laddr, UINT32 (CPUCALL *func)(UINT32, void *), void *arg) +{ + UINT32 result; + UINT32 value; + + if (!CPU_STAT_PAGING) { + value = cpu_memoryread_d(laddr); + result = (*func)(value, arg); + cpu_memorywrite_d(laddr, result); + return value; + } + return cpu_memory_access_la_RMW_d(laddr, func, arg); +} + +/* read */ +STATIC_INLINE UINT8 MEMCALL +cpu_lmemoryread_b(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_b(laddr); + return cpu_linear_memory_read_b(laddr, ucrw); +} +STATIC_INLINE UINT8 MEMCALL +cpu_lmemoryread_b_codefetch(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_b_codefetch(laddr); + return cpu_linear_memory_read_b_codefetch(laddr, ucrw); +} +#define cpu_lmemoryread(a,ucrw) cpu_lmemoryread_b((a),(ucrw)) +#define cpu_lmemoryread_codefetch(a,ucrw) cpu_lmemoryread_b_codefetch((a),(ucrw)) + +STATIC_INLINE UINT16 MEMCALL +cpu_lmemoryread_w(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_w(laddr); + return cpu_linear_memory_read_w(laddr, ucrw); +} +STATIC_INLINE UINT16 MEMCALL +cpu_lmemoryread_w_codefetch(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_w_codefetch(laddr); + return cpu_linear_memory_read_w_codefetch(laddr, ucrw); +} + + +STATIC_INLINE UINT32 MEMCALL +cpu_lmemoryread_d(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_d(laddr); + return cpu_linear_memory_read_d(laddr, ucrw); +} +STATIC_INLINE UINT32 MEMCALL +cpu_lmemoryread_d_codefetch(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_d_codefetch(laddr); + return cpu_linear_memory_read_d_codefetch(laddr, ucrw); +} + +STATIC_INLINE UINT64 +cpu_lmemoryread_q(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_q(laddr); + return cpu_linear_memory_read_q(laddr, ucrw); +} + +STATIC_INLINE REG80 +cpu_lmemoryread_f(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return cpu_memoryread_f(laddr); + return cpu_linear_memory_read_f(laddr, ucrw); +} + +/* write */ +STATIC_INLINE void MEMCALL +cpu_lmemorywrite_b(UINT32 laddr, UINT8 value, int ucrw) +{ + + if (!CPU_STAT_PAGING) { + cpu_memorywrite_b(laddr, value); + return; + } + cpu_linear_memory_write_b(laddr, value, ucrw); +} +#define cpu_lmemorywrite(a,v,ucrw) cpu_lmemorywrite_b((a),(v),(ucrw)) + +STATIC_INLINE void MEMCALL +cpu_lmemorywrite_w(UINT32 laddr, UINT16 value, int ucrw) +{ + + if (!CPU_STAT_PAGING) { + cpu_memorywrite_w(laddr, value); + return; + } + cpu_linear_memory_write_w(laddr, value, ucrw); +} + +STATIC_INLINE void MEMCALL +cpu_lmemorywrite_d(UINT32 laddr, UINT32 value, int ucrw) +{ + + if (!CPU_STAT_PAGING) { + cpu_memorywrite_d(laddr, value); + return; + } + cpu_linear_memory_write_d(laddr, value, ucrw); +} + +STATIC_INLINE void MEMCALL +cpu_lmemorywrite_q(UINT32 laddr, UINT64 value, int ucrw) +{ + + if (!CPU_STAT_PAGING) { + cpu_memorywrite_q(laddr, value); + return; + } + cpu_linear_memory_write_q(laddr, value, ucrw); +} + +STATIC_INLINE void MEMCALL +cpu_lmemorywrite_f(UINT32 laddr, const REG80 *value, int ucrw) +{ + + if (!CPU_STAT_PAGING) { + cpu_memorywrite_f(laddr, value); + return; + } + cpu_linear_memory_write_f(laddr, value, ucrw); +} + + +/* + * linear address memory access with superviser mode + */ +#define cpu_kmemoryread(a) \ + cpu_lmemoryread((a),CPU_PAGE_READ_DATA|CPU_MODE_SUPERVISER) +#define cpu_kmemoryread_w(a) \ + cpu_lmemoryread_w((a),CPU_PAGE_READ_DATA|CPU_MODE_SUPERVISER) +#define cpu_kmemoryread_d(a) \ + cpu_lmemoryread_d((a),CPU_PAGE_READ_DATA|CPU_MODE_SUPERVISER) +#define cpu_kmemorywrite(a,v) \ + cpu_lmemorywrite((a),(v),CPU_PAGE_WRITE_DATA|CPU_MODE_SUPERVISER) +#define cpu_kmemorywrite_w(a,v) \ + cpu_lmemorywrite_w((a),(v),CPU_PAGE_WRITE_DATA|CPU_MODE_SUPERVISER) +#define cpu_kmemorywrite_d(a,v) \ + cpu_lmemorywrite_d((a),(v),CPU_PAGE_WRITE_DATA|CPU_MODE_SUPERVISER) + +/* + * linear address memory access function + */ +void MEMCALL cpu_memory_access_la_region(UINT32 address, UINT length, int ucrw, UINT8 *data); +UINT32 MEMCALL laddr2paddr(UINT32 laddr, int ucrw); + +STATIC_INLINE UINT32 MEMCALL +laddr_to_paddr(UINT32 laddr, int ucrw) +{ + + if (!CPU_STAT_PAGING) + return laddr; + return laddr2paddr(laddr, ucrw); +} + +/* + * TLB function + */ +struct tlb_entry; +void tlb_init(void); +void MEMCALL tlb_flush(); +void MEMCALL tlb_flush_all(); +void MEMCALL tlb_flush_page(UINT32 laddr); +struct tlb_entry *MEMCALL tlb_lookup(UINT32 laddr, int ucrw); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* !IA32_CPU_PAGING_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/resolve.cpp b/source/src/vm/np21/i386c/ia32/resolve.cpp new file mode 100644 index 000000000..1342ac2cd --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/resolve.cpp @@ -0,0 +1,627 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + + +UINT32 (*calc_ea_dst_tbl[0x100])(void); +UINT32 (*calc_ea32_dst_tbl[0x100])(void); + + +/* + * common + */ +static UINT32 +ea_nop(void) +{ + + ia32_panic("ea_nop"); + return 0; +} + + +/* + * 16bit + */ + +/* + * ea_dest + */ +static UINT32 +ea_bx_si(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return (CPU_BX + CPU_SI); +} + +static UINT32 +ea_bx_si_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_SI); +} + +static UINT32 +ea_bx_si_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_SI); +} + +static UINT32 +ea_bx_di(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return (CPU_BX + CPU_DI); +} + +static UINT32 +ea_bx_di_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_DI); +} + +static UINT32 +ea_bx_di_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX + CPU_DI); +} + +static UINT32 +ea_bp_si(void) +{ + + CPU_INST_SEGREG_INDEX = SS_FIX; + return (CPU_BP + CPU_SI); +} + +static UINT32 +ea_bp_si_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_SI); +} + +static UINT32 +ea_bp_si_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_SI); +} + +static UINT32 +ea_bp_di(void) +{ + + CPU_INST_SEGREG_INDEX = SS_FIX; + return (CPU_BP + CPU_DI); +} + +static UINT32 +ea_bp_di_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_DI); +} + +static UINT32 +ea_bp_di_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP + CPU_DI); +} + +static UINT32 +ea_si(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_SI; +} + +static UINT32 +ea_si_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_SI); +} + +static UINT32 +ea_si_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_SI); +} + +static UINT32 +ea_di(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_DI; +} + +static UINT32 +ea_di_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_DI); +} + +static UINT32 +ea_di_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_DI); +} + +static UINT32 +ea_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs; +} + +static UINT32 +ea_bp_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP); +} + +static UINT32 +ea_bp_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return (adrs + CPU_BP); +} + +static UINT32 +ea_bx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_BX; +} + +static UINT32 +ea_bx_disp8(void) +{ + UINT32 adrs; + + GET_PCBYTES(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX); +} + +static UINT32 +ea_bx_disp16(void) +{ + UINT32 adrs; + + GET_PCWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return (adrs + CPU_BX); +} + +static UINT32 (*c_ea_dst_tbl[])(void) = { + ea_bx_si, ea_bx_di, + ea_bp_si, ea_bp_di, + ea_si, ea_di, + ea_disp16, ea_bx, + ea_bx_si_disp8, ea_bx_di_disp8, + ea_bp_si_disp8, ea_bp_di_disp8, + ea_si_disp8, ea_di_disp8, + ea_bp_disp8, ea_bx_disp8, + ea_bx_si_disp16, ea_bx_di_disp16, + ea_bp_si_disp16, ea_bp_di_disp16, + ea_si_disp16, ea_di_disp16, + ea_bp_disp16, ea_bx_disp16, +}; + + +/* + * 32bit + */ +/* + * ea_dest 32 + */ +static UINT32 +ea32_eax(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EAX; +} + +static UINT32 +ea32_ecx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_ECX; +} + +static UINT32 +ea32_edx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EDX; +} + +static UINT32 +ea32_ebx(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EBX; +} + +static UINT32 +ea32_sib(void) +{ + UINT32 dst; + UINT32 op; + UINT32 base, idx, scale; + + GET_PCBYTE(op); + base = op & 7; + idx = (op >> 3) & 7; + scale = (op >> 6) & 3; + + switch (base) { + case 0: case 1: case 2: case 3: case 6: case 7: + CPU_INST_SEGREG_INDEX = DS_FIX; + dst = CPU_REGS_DWORD(base); + break; + + case 4: + CPU_INST_SEGREG_INDEX = SS_FIX; + dst = CPU_ESP; + break; + + case 5: + CPU_INST_SEGREG_INDEX = DS_FIX; + GET_PCDWORD(dst); + break; + + default: + dst = 0; /* compiler happy */ + ia32_panic("ea32_sib: invalid base = %d", base); + break; + } + if (idx != 4) + dst += CPU_REGS_DWORD(idx) << scale; + return dst; +} + +static UINT32 +ea32_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs; +} + +static UINT32 +ea32_esi(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_ESI; +} + +static UINT32 +ea32_edi(void) +{ + + CPU_INST_SEGREG_INDEX = DS_FIX; + return CPU_EDI; +} + +static UINT32 +ea32_eax_disp8(void) +{ + SINT32 adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EAX; +} + +static UINT32 +ea32_ecx_disp8(void) +{ + SINT32 adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ECX; +} + +static UINT32 +ea32_edx_disp8(void) +{ + SINT32 adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDX; +} + +static UINT32 +ea32_ebx_disp8(void) +{ + SINT32 adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EBX; +} + +static UINT32 +ea32_sib_disp8(void) +{ + SINT32 adrs; + UINT32 op; + UINT32 base, idx, scale; + + GET_PCBYTE(op); + base = op & 7; + idx = (op >> 3) & 7; + scale = (op >> 6) & 3; + + GET_PCBYTESD(adrs); + + switch (base) { + case 0: case 1: case 2: case 3: case 6: case 7: + CPU_INST_SEGREG_INDEX = DS_FIX; + break; + + case 4: case 5: + CPU_INST_SEGREG_INDEX = SS_FIX; + break; + } + if (idx != 4) + adrs += CPU_REGS_DWORD(idx) << scale; + return CPU_REGS_DWORD(base) + adrs; +} + +static UINT32 +ea32_ebp_disp8(void) +{ + SINT32 adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return adrs + CPU_EBP; +} + +static UINT32 +ea32_esi_disp8(void) +{ + SINT32 adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ESI; +} + +static UINT32 +ea32_edi_disp8(void) +{ + SINT32 adrs; + + GET_PCBYTESD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDI; +} + +static UINT32 +ea32_eax_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EAX; +} + +static UINT32 +ea32_ecx_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ECX; +} + +static UINT32 +ea32_edx_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDX; +} + +static UINT32 +ea32_ebx_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EBX; +} + +static UINT32 +ea32_sib_disp32(void) +{ + UINT32 adrs; + UINT32 op; + UINT32 base, idx, scale; + + GET_PCBYTE(op); + base = op & 7; + idx = (op >> 3) & 7; + scale = (op >> 6) & 3; + + GET_PCDWORD(adrs); + + switch (base) { + case 0: case 1: case 2: case 3: case 6: case 7: + CPU_INST_SEGREG_INDEX = DS_FIX; + break; + + case 4: case 5: + CPU_INST_SEGREG_INDEX = SS_FIX; + break; + } + if (idx != 4) + adrs += CPU_REGS_DWORD(idx) << scale; + return CPU_REGS_DWORD(base) + adrs; +} + +static UINT32 +ea32_ebp_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = SS_FIX; + return adrs + CPU_EBP; +} + +static UINT32 +ea32_esi_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_ESI; +} + +static UINT32 +ea32_edi_disp32(void) +{ + UINT32 adrs; + + GET_PCDWORD(adrs); + CPU_INST_SEGREG_INDEX = DS_FIX; + return adrs + CPU_EDI; +} + +static UINT32 (*c_ea32_dst_tbl[])(void) = { + ea32_eax, ea32_ecx, + ea32_edx, ea32_ebx, + ea32_sib, ea32_disp32, + ea32_esi, ea32_edi, + ea32_eax_disp8, ea32_ecx_disp8, + ea32_edx_disp8, ea32_ebx_disp8, + ea32_sib_disp8, ea32_ebp_disp8, + ea32_esi_disp8, ea32_edi_disp8, + ea32_eax_disp32, ea32_ecx_disp32, + ea32_edx_disp32, ea32_ebx_disp32, + ea32_sib_disp32, ea32_ebp_disp32, + ea32_esi_disp32, ea32_edi_disp32, +}; + + +/* + * init table + */ +void +resolve_init(void) +{ + int i, pos; + + for (i = 0; i < 0xc0; ++i) { + pos = ((i >> 3) & 0x18) + (i & 0x07); + calc_ea_dst_tbl[i] = c_ea_dst_tbl[pos]; + calc_ea32_dst_tbl[i] = c_ea32_dst_tbl[pos]; + } + for (; i < 0x100; ++i) { + calc_ea_dst_tbl[i] = ea_nop; + calc_ea32_dst_tbl[i] = ea_nop; + } +} diff --git a/source/src/vm/np21/i386c/ia32/resolve.h b/source/src/vm/np21/i386c/ia32/resolve.h new file mode 100644 index 000000000..6d464508c --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/resolve.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2002-2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_RESOLVE_H__ +#define IA32_CPU_RESOLVE_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void resolve_init(void); + +STATIC_INLINE UINT32 CPUCALL +calc_ea_dst(UINT32 op) +{ + extern UINT32 (*calc_ea_dst_tbl[0x100])(void); + extern UINT32 (*calc_ea32_dst_tbl[0x100])(void); + + __ASSERT(op < 0x100); + + if (!CPU_INST_AS32) + return ((*calc_ea_dst_tbl[op])() & 0xffff); + return (*calc_ea32_dst_tbl[op])(); +} + +//#ifdef __cplusplus +//} +//#endif + +#endif /* IA32_CPU_RESOLVE_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/segments.cpp b/source/src/vm/np21/i386c/ia32/segments.cpp new file mode 100644 index 000000000..28cdf9107 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/segments.cpp @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +static __inline__ void CPUCALL segdesc_set_default(int, UINT16, descriptor_t *); + +void CPUCALL +load_segreg(int idx, UINT16 selector, UINT16 *sregp, descriptor_t *sdp, int exc) +{ + selector_t sel; + int rv; + + __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); + __ASSERT((sregp != NULL)); + __ASSERT((sdp != NULL)); + + if (!CPU_STAT_PM || CPU_STAT_VM86) { + /* real-mode or vm86 mode */ + *sregp = selector; + segdesc_set_default(idx, selector, &sel.desc); + *sdp = sel.desc; + return; + } + + VERBOSE(("load_segreg: EIP = %04x:%08x, idx = %d, selector = %04x, sregp = %p, dp = %p, exc = %d", CPU_CS, CPU_PREV_EIP, idx, selector, sregp, sdp, exc)); + + /* + * protected mode + */ + if (idx == CPU_CS_INDEX) { + ia32_panic("load_segreg: CS"); + } + + rv = parse_selector(&sel, selector); + if (rv < 0) { + if ((rv != -2) || (idx == CPU_SS_INDEX)) { + EXCEPTION(exc, sel.idx); + } + /* null selector */ + *sregp = sel.selector; + memset(sdp, 0, sizeof(*sdp)); + return; + } + + switch (idx) { + case CPU_SS_INDEX: + if ((CPU_STAT_CPL != sel.rpl) + || (CPU_STAT_CPL != sel.desc.dpl) + || SEG_IS_SYSTEM(&sel.desc) + || SEG_IS_CODE(&sel.desc) + || !SEG_IS_WRITABLE_DATA(&sel.desc)) { + EXCEPTION(exc, sel.idx); + } + + /* not present */ + rv = selector_is_not_present(&sel); + if (rv < 0) { + EXCEPTION(SS_EXCEPTION, sel.idx); + } + + load_ss(sel.selector, &sel.desc, CPU_STAT_CPL); + break; + + case CPU_ES_INDEX: + case CPU_DS_INDEX: + case CPU_FS_INDEX: + case CPU_GS_INDEX: + if (SEG_IS_SYSTEM(&sel.desc) + || (SEG_IS_CODE(&sel.desc) && !SEG_IS_READABLE_CODE(&sel.desc))) { + EXCEPTION(exc, sel.idx); + } + if (SEG_IS_DATA(&sel.desc) + || !SEG_IS_CONFORMING_CODE(&sel.desc)) { + /* check privilege level */ + if ((sel.rpl > sel.desc.dpl) + || (CPU_STAT_CPL > sel.desc.dpl)) { + EXCEPTION(exc, sel.idx); + } + } + + /* not present */ + rv = selector_is_not_present(&sel); + if (rv < 0) { + EXCEPTION(NP_EXCEPTION, sel.idx); + } + + *sregp = sel.selector; + *sdp = sel.desc; + break; + + default: + ia32_panic("load_segreg(): segment register index is invalid"); + break; + } +} + +/* + * load SS register + */ +void CPUCALL +load_ss(UINT16 selector, const descriptor_t *sdp, int cpl) +{ + + CPU_STAT_SS32 = sdp->d; + CPU_SS = (UINT16)((selector & ~3) | (cpl & 3)); + CPU_SS_DESC = *sdp; +} + +/* + * load CS register + */ +void CPUCALL +load_cs(UINT16 selector, const descriptor_t *sdp, int new_cpl) +{ + int cpl = new_cpl & 3; + + CPU_INST_OP32 = CPU_INST_AS32 = + CPU_STATSAVE.cpu_inst_default.op_32 = + CPU_STATSAVE.cpu_inst_default.as_32 = sdp->d; + CPU_CS = (UINT16)((selector & ~3) | cpl); + CPU_CS_DESC = *sdp; + set_cpl(cpl); +} + +/* + * load LDT register + */ +void CPUCALL +load_ldtr(UINT16 selector, int exc) +{ + selector_t sel; + int rv; + + memset(&sel, 0, sizeof(sel)); + + rv = parse_selector(&sel, selector); + if (rv < 0 || sel.ldt) { + if (rv == -2) { + /* null segment */ + VERBOSE(("load_ldtr: null segment")); + CPU_LDTR = 0; + memset(&CPU_LDTR_DESC, 0, sizeof(CPU_LDTR_DESC)); + return; + } + EXCEPTION(exc, sel.selector); + } + + /* check descriptor type */ + if (!SEG_IS_SYSTEM(&sel.desc) + || (sel.desc.type != CPU_SYSDESC_TYPE_LDT)) { + EXCEPTION(exc, sel.selector); + } + + /* not present */ + rv = selector_is_not_present(&sel); + if (rv < 0) { + EXCEPTION((exc == TS_EXCEPTION) ? TS_EXCEPTION : NP_EXCEPTION, sel.selector); + } + +#if defined(MORE_DEBUG) + ldtr_dump(sel.desc.u.seg.segbase, sel.desc.u.seg.limit); +#endif + + CPU_LDTR = sel.selector; + CPU_LDTR_DESC = sel.desc; +} + +#include "../../../i386_np21.h" // ToDo: Remove after debug 20201129 K.O + +void CPUCALL +load_descriptor(descriptor_t *sdp, UINT32 addr) +{ + UINT32 l, h; + + __ASSERT(sdp != NULL); + + VERBOSE(("load_descriptor: address = 0x%08x", addr)); + + l = cpu_kmemoryread_d(addr); + h = cpu_kmemoryread_d(addr + 4); + VERBOSE(("descriptor value = 0x%08x%08x", h, l)); + + memset(sdp, 0, sizeof(*sdp)); + sdp->flag = 0; + + sdp->p = (h & CPU_DESC_H_P) ? 1 : 0; + sdp->type = (UINT8)((h & CPU_DESC_H_TYPE) >> CPU_DESC_H_TYPE_SHIFT); + sdp->dpl = (UINT8)((h & CPU_DESC_H_DPL) >> CPU_DESC_H_DPL_SHIFT); + sdp->s = (h & CPU_DESC_H_S) ? 1 : 0; + if (!SEG_IS_SYSTEM(sdp)) { + /* code/data */ + sdp->valid = 1; + sdp->d = (h & CPU_SEGDESC_H_D) ? 1 : 0; + + sdp->u.seg.c = (h & CPU_SEGDESC_H_D_C) ? 1 : 0; + sdp->u.seg.g = (h & CPU_SEGDESC_H_G) ? 1 : 0; + sdp->u.seg.wr = (sdp->type & CPU_SEGDESC_TYPE_WR) ? 1 : 0; + sdp->u.seg.ec = (sdp->type & CPU_SEGDESC_TYPE_EC) ? 1 : 0; + + sdp->u.seg.segbase = (l >> 16) & 0xffff; + sdp->u.seg.segbase |= (h & 0xff) << 16; + sdp->u.seg.segbase |= h & 0xff000000; + sdp->u.seg.limit = (h & 0xf0000) | (l & 0xffff); + if (sdp->u.seg.g) { + sdp->u.seg.limit <<= 12; + if (SEG_IS_CODE(sdp) || !SEG_IS_EXPANDDOWN_DATA(sdp)) { + /* expand-up segment */ + sdp->u.seg.limit |= 0xfff; + } + } + } else { + /* system */ + switch (sdp->type) { + case CPU_SYSDESC_TYPE_LDT: /* LDT */ + sdp->valid = 1; + sdp->u.seg.g = (h & CPU_SEGDESC_H_G) ? 1 : 0; + + sdp->u.seg.segbase = h & 0xff000000; + sdp->u.seg.segbase |= (h & 0xff) << 16; + sdp->u.seg.segbase |= l >> 16; + sdp->u.seg.limit = h & 0xf0000; + sdp->u.seg.limit |= l & 0xffff; + if (sdp->u.seg.g) { + sdp->u.seg.limit <<= 12; + sdp->u.seg.limit |= 0xfff; + } + break; + + case CPU_SYSDESC_TYPE_TASK: /* task gate */ + sdp->valid = 1; + sdp->u.gate.selector = (UINT16)(l >> 16); + break; + + case CPU_SYSDESC_TYPE_TSS_16: /* 286 TSS */ + case CPU_SYSDESC_TYPE_TSS_BUSY_16: /* 286 TSS Busy */ + case CPU_SYSDESC_TYPE_TSS_32: /* 386 TSS */ + case CPU_SYSDESC_TYPE_TSS_BUSY_32: /* 386 TSS Busy */ + sdp->valid = 1; + sdp->d = (h & CPU_GATEDESC_H_D) ? 1 : 0; + sdp->u.seg.g = (h & CPU_SEGDESC_H_G) ? 1 : 0; + + sdp->u.seg.segbase = h & 0xff000000; + sdp->u.seg.segbase |= (h & 0xff) << 16; + sdp->u.seg.segbase |= l >> 16; + sdp->u.seg.limit = h & 0xf0000; + sdp->u.seg.limit |= l & 0xffff; + if (sdp->u.seg.g) { + sdp->u.seg.limit <<= 12; + sdp->u.seg.limit |= 0xfff; + } + break; + + case CPU_SYSDESC_TYPE_CALL_16: /* 286 call gate */ + case CPU_SYSDESC_TYPE_INTR_16: /* 286 interrupt gate */ + case CPU_SYSDESC_TYPE_TRAP_16: /* 286 trap gate */ + case CPU_SYSDESC_TYPE_CALL_32: /* 386 call gate */ + case CPU_SYSDESC_TYPE_INTR_32: /* 386 interrupt gate */ + case CPU_SYSDESC_TYPE_TRAP_32: /* 386 trap gate */ + if ((h & 0x0000000e0) == 0) { + sdp->valid = 1; + sdp->d = (h & CPU_GATEDESC_H_D) ? 1 : 0; + sdp->u.gate.selector = (UINT16)(l >> 16); + sdp->u.gate.offset = h & 0xffff0000; + sdp->u.gate.offset |= l & 0xffff; + sdp->u.gate.count = (UINT8)(h & 0x1f); + } else { + sdp->valid = 0; + VERBOSE(("load_descriptor: gate is invalid")); + } + break; + + case 0: case 8: case 10: case 13: /* reserved */ + default: + sdp->valid = 0; + break; + } + } +// device_cpu->out_debug_log("LOAD SEGMENT FROM %08X BASE:LIMIT=%08X:%08X\n", +// addr, sdp->u.seg.segbase, sdp->u.seg.limit); +#if defined(DEBUG) + segdesc_dump(sdp); +#endif +} + +int CPUCALL +parse_selector(selector_t *ssp, UINT16 selector) +{ + UINT32 base; + UINT limit; + UINT idx; + + ssp->selector = selector; + ssp->idx = selector & ~3; + ssp->rpl = selector & 3; + ssp->ldt = (UINT8)(selector & CPU_SEGMENT_TABLE_IND); + + VERBOSE(("parse_selector: selector = %04x, index = %d, RPL = %d, %cDT", ssp->selector, ssp->idx >> 3, ssp->rpl, ssp->ldt ? 'L' : 'G')); + + /* descriptor table */ + idx = selector & CPU_SEGMENT_SELECTOR_INDEX_MASK; + if (ssp->ldt) { + /* LDT */ + if (!SEG_IS_VALID(&CPU_LDTR_DESC)) { + VERBOSE(("parse_selector: LDT is invalid")); + return -1; + } + base = CPU_LDTR_BASE; + limit = CPU_LDTR_LIMIT; + } else { + /* check null segment */ + if (idx == 0) { + VERBOSE(("parse_selector: null segment")); + return -2; + } + base = CPU_GDTR_BASE; + limit = CPU_GDTR_LIMIT; + } + if (idx + 7 > limit) { + VERBOSE(("parse_selector: segment limit check failed: 0x%08x > 0x%08x", idx + 7, limit)); + return -3; + } + + /* load descriptor */ + ssp->addr = base + idx; + load_descriptor(&ssp->desc, ssp->addr); + if (!SEG_IS_VALID(&ssp->desc)) { + VERBOSE(("parse_selector: segment descriptor is invalid")); + return -4; + } + + return 0; +} + +int CPUCALL +selector_is_not_present(const selector_t *ssp) +{ + UINT32 h; + + /* not present */ + if (!SEG_IS_PRESENT(&ssp->desc)) { + VERBOSE(("selector_is_not_present: not present")); + return -1; + } + + /* set access bit if code/data segment descriptor */ + if (!SEG_IS_SYSTEM(&ssp->desc)) { + h = cpu_kmemoryread_d(ssp->addr + 4); + if (!(h & CPU_SEGDESC_H_A)) { + h |= CPU_SEGDESC_H_A; + cpu_kmemorywrite_d(ssp->addr + 4, h); + } + } + + return 0; +} + +void CPUCALL +segdesc_init(int idx, UINT16 sreg, descriptor_t *sdp) +{ + + __ASSERT(((unsigned int)idx < CPU_SEGREG_NUM)); + __ASSERT((sdp != NULL)); + + CPU_REGS_SREG(idx) = sreg; + segdesc_set_default(idx, sreg, sdp); +} + +static __inline__ void CPUCALL +segdesc_set_default(int idx, UINT16 selector, descriptor_t *sdp) +{ + + __ASSERT(((unsigned int)idx < CPU_SEGREG_NUM)); + __ASSERT((sdp != NULL)); + + sdp->u.seg.segbase = (UINT32)selector << 4; + sdp->u.seg.limit = 0xffff; + sdp->u.seg.c = (idx == CPU_CS_INDEX) ? 1 : 0; /* code or data */ + sdp->u.seg.g = 0; /* non 4k factor scale */ + sdp->u.seg.wr = 1; /* execute/read(CS) or read/write(others) */ + sdp->u.seg.ec = 0; /* nonconforming(CS) or expand-up(others) */ + sdp->valid = 1; /* valid */ + sdp->p = 1; /* present */ + sdp->type = (CPU_SEGDESC_TYPE_WR << CPU_DESC_H_TYPE_SHIFT) + | ((idx == CPU_CS_INDEX) ? CPU_SEGDESC_H_D_C : 0); + /* readable code/writable data segment */ + sdp->dpl = CPU_STAT_VM86 ? 3 : 0; /* descriptor privilege level */ + sdp->rpl = CPU_STAT_VM86 ? 3 : 0; /* request privilege level */ + sdp->s = 1; /* code/data */ + sdp->d = 0; /* 16bit */ + sdp->flag = CPU_DESC_FLAG_READABLE|CPU_DESC_FLAG_WRITABLE; +} diff --git a/source/src/vm/np21/i386c/ia32/segments.h b/source/src/vm/np21/i386c/ia32/segments.h new file mode 100644 index 000000000..73e32782b --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/segments.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_SEGMENTS_H__ +#define IA32_CPU_SEGMENTS_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +/* + * segment descriptor + */ +typedef struct { + union { + struct { + UINT32 segbase; + UINT32 d_pad; + UINT32 limit; + + UINT8 c; /* 0 = data, 1 = code */ + UINT8 g; /* 4k base */ + UINT8 wr; /* readable/writable */ + UINT8 ec; /* expand down/conforming */ + } seg; + + struct { + UINT16 selector; + UINT16 w_pad; + UINT32 offset; + + UINT8 count; /* parameter count:call gate */ + + UINT8 b_pad[7]; + } gate; + } u; + + UINT8 valid; /* descriptor valid flag */ + UINT8 p; /* avail flag */ + + UINT8 type; /* descriptor type */ + UINT8 dpl; /* DPL */ + UINT8 rpl; /* RPL */ + UINT8 s; /* 0 = system, 1 = code/data */ + UINT8 d; /* 0 = 16bit, 1 = 32bit */ + + UINT8 flag; +#define CPU_DESC_FLAG_READABLE (1 << 0) +#define CPU_DESC_FLAG_WRITABLE (1 << 1) +#define CPU_DESC_FLAG_WHOLEADR (1 << 2) +} descriptor_t; + +#define SEG_IS_VALID(sdp) ((sdp)->valid) +#define SEG_IS_PRESENT(sdp) ((sdp)->p) +#define SEG_IS_32BIT(sdp) ((sdp)->d) +#define SEG_IS_SYSTEM(sdp) (!(sdp)->s) +#define SEG_IS_CODE(sdp) ((sdp)->s && (sdp)->u.seg.c) +#define SEG_IS_DATA(sdp) ((sdp)->s && !(sdp)->u.seg.c) +#define SEG_IS_READABLE_CODE(sdp) ((sdp)->u.seg.wr) +#define SEG_IS_WRITABLE_DATA(sdp) ((sdp)->u.seg.wr) +#define SEG_IS_CONFORMING_CODE(sdp) ((sdp)->u.seg.ec) +#define SEG_IS_EXPANDDOWN_DATA(sdp) ((sdp)->u.seg.ec) + +/* + * segment descriptor + * + * 31 24 23 22 21 20 19 16 15 14 13 12 11 8 7 0 + * +----------------+--+--+--+--+-------+--+-----+--+-------+---------------+ + * | Base 31..16 | G|DB| 0| A|limit_h| P| DPL | S| type | Base 23:16 | 4 + * +----------------+--+--+--+--+-------+--+-----+--+-------+---------------+ + * 31 16 15 0 + * +------------------------------------+-----------------------------------+ + * | Base 15..00 | limit 15..0 | 0 + * +------------------------------------+-----------------------------------+ + */ + +/* descriptor common */ +#define CPU_DESC_H_TYPE_SHIFT 8 +#define CPU_DESC_H_TYPE (0xf << CPU_DESC_H_TYPE_SHIFT) +#define CPU_DESC_H_S ( 1 << 12) /* 0 = system, 1 = code/data */ +#define CPU_DESC_H_DPL_SHIFT 13 +#define CPU_DESC_H_DPL ( 3 << CPU_DESC_H_DPL_SHIFT) +#define CPU_DESC_H_P ( 1 << 15) /* exist */ + +/* for segment descriptor */ +#define CPU_SEGDESC_H_A ( 1 << 8) +#define CPU_SEGDESC_H_D_C ( 1 << 11) /* 0 = data, 1 = code */ +#define CPU_SEGDESC_H_D ( 1 << 22) +#define CPU_SEGDESC_H_G ( 1 << 23) + +/* for gate descriptor */ +#define CPU_GATEDESC_H_D ( 1 << 11) + +/* for tss descriptor */ +#define CPU_TSS_H_BUSY ( 1 << 9) + +/* + * descriptor type + */ +#define CPU_SEGDESC_TYPE_A 0x01 +#define CPU_SEGDESC_TYPE_WR 0x02 +#define CPU_SEGDESC_TYPE_EC 0x04 + +#define CPU_SYSDESC_TYPE_TSS_16 0x01 +#define CPU_SYSDESC_TYPE_LDT 0x02 +#define CPU_SYSDESC_TYPE_TSS_BUSY_16 0x03 +#define CPU_SYSDESC_TYPE_CALL_16 0x04 /* call gate */ +#define CPU_SYSDESC_TYPE_TASK 0x05 /* task gate */ +#define CPU_SYSDESC_TYPE_INTR_16 0x06 /* hardware interrupt */ +#define CPU_SYSDESC_TYPE_TRAP_16 0x07 /* software interrupt */ +#define CPU_SYSDESC_TYPE_TSS_32 0x09 +#define CPU_SYSDESC_TYPE_TSS_BUSY_32 0x0b +#define CPU_SYSDESC_TYPE_CALL_32 0x0c /* call gate */ +#define CPU_SYSDESC_TYPE_INTR_32 0x0e /* hardware interrupt */ +#define CPU_SYSDESC_TYPE_TRAP_32 0x0f /* software interrupt */ + +#define CPU_SYSDESC_TYPE_TSS 0x01 +/* CPU_SYSDESC_TYPE_LDT 0x02 */ +#define CPU_SYSDESC_TYPE_TSS_BUSY 0x03 +#define CPU_SYSDESC_TYPE_CALL 0x04 +/* CPU_SYSDESC_TYPE_TASK 0x05 */ +#define CPU_SYSDESC_TYPE_INTR 0x06 +#define CPU_SYSDESC_TYPE_TRAP 0x07 +#define CPU_SYSDESC_TYPE_MASKBIT 0x07 +#define CPU_SYSDESC_TYPE_32BIT 0x08 + +#define CPU_SYSDESC_TYPE_TSS_BUSY_IND 0x02 + + +void CPUCALL segdesc_init(int idx, UINT16 sreg, descriptor_t *sdp); +void CPUCALL load_descriptor(descriptor_t *sdp, UINT32 addr); + +void CPUCALL load_segreg(int idx, UINT16 selector, UINT16 *sregp, descriptor_t *sdp, int exc); +#define LOAD_SEGREG1(idx, selector, e) \ + load_segreg(idx, selector, &CPU_REGS_SREG(idx), &CPU_STAT_SREG(idx), e) +#define LOAD_SEGREG(idx, selector) \ + LOAD_SEGREG1((idx), (selector), GP_EXCEPTION) +void CPUCALL load_ss(UINT16 selector, const descriptor_t *sdp, int cpl); +void CPUCALL load_cs(UINT16 selector, const descriptor_t *sdp, int cpl); +void CPUCALL load_ldtr(UINT16 selector, int exc); + + +/* + * segment selector + */ +#define CPU_SEGMENT_SELECTOR_INDEX_MASK (~7) +#define CPU_SEGMENT_SELECTOR_RPL_MASK (3) +#define CPU_SEGMENT_TABLE_IND (1 << 2) /* 0 = GDT, 1 = LDT */ + +typedef struct { + UINT16 selector; + UINT16 idx; + UINT16 rpl; + UINT8 ldt; + UINT8 pad; + + UINT32 addr; /* descriptor linear address */ + + descriptor_t desc; +} selector_t; + +int CPUCALL parse_selector(selector_t *ssp, UINT16 selector); +int CPUCALL selector_is_not_present(const selector_t *ssp); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* !IA32_CPU_SEGMENTS_H__ */ diff --git a/source/src/vm/np21/i386c/ia32/task.cpp b/source/src/vm/np21/i386c/ia32/task.cpp new file mode 100644 index 000000000..ffa08a7fd --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/task.cpp @@ -0,0 +1,546 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#include "compiler.h" +#include "cpu.h" +#include "ia32.mcr" + +#define TSS_16_SIZE 44 +#define TSS_16_LIMIT (TSS_16_SIZE - 1) +#define TSS_32_SIZE 104 +#define TSS_32_LIMIT (TSS_32_SIZE - 1) + +static void CPUCALL +set_task_busy(UINT16 selector) +{ + UINT32 addr; + UINT32 h; + + addr = CPU_GDTR_BASE + (selector & CPU_SEGMENT_SELECTOR_INDEX_MASK); + h = cpu_kmemoryread_d(addr + 4); + if (!(h & CPU_TSS_H_BUSY)) { + h |= CPU_TSS_H_BUSY; + cpu_kmemorywrite_d(addr + 4, h); + } else { + ia32_panic("set_task_busy: already busy(%04x:%08x)", + selector, h); + } +} + +static void CPUCALL +set_task_free(UINT16 selector) +{ + UINT32 addr; + UINT32 h; + + addr = CPU_GDTR_BASE + (selector & CPU_SEGMENT_SELECTOR_INDEX_MASK); + h = cpu_kmemoryread_d(addr + 4); + if (h & CPU_TSS_H_BUSY) { + h &= ~CPU_TSS_H_BUSY; + cpu_kmemorywrite_d(addr + 4, h); + } else { + ia32_panic("set_task_free: already free(%04x:%08x)", + selector, h); + } +} + +void CPUCALL +load_tr(UINT16 selector) +{ + selector_t task_sel; + int rv; + UINT16 iobase; + + rv = parse_selector(&task_sel, selector); + if (rv < 0 || task_sel.ldt || !SEG_IS_SYSTEM(&task_sel.desc)) { + EXCEPTION(GP_EXCEPTION, task_sel.idx); + } + + /* check descriptor type & stack room size */ + switch (task_sel.desc.type) { + case CPU_SYSDESC_TYPE_TSS_16: + if (task_sel.desc.u.seg.limit < TSS_16_LIMIT) { + EXCEPTION(TS_EXCEPTION, task_sel.idx); + } + iobase = 0; + break; + + case CPU_SYSDESC_TYPE_TSS_32: + if (task_sel.desc.u.seg.limit < TSS_32_LIMIT) { + EXCEPTION(TS_EXCEPTION, task_sel.idx); + } + iobase = cpu_kmemoryread_w(task_sel.desc.u.seg.segbase + 102); + break; + + default: + EXCEPTION(GP_EXCEPTION, task_sel.idx); + return; + } + + /* not present */ + rv = selector_is_not_present(&task_sel); + if (rv < 0) { + EXCEPTION(NP_EXCEPTION, task_sel.idx); + } + +#if defined(MORE_DEBUG) + tr_dump(task_sel.selector, task_sel.desc.u.seg.segbase, task_sel.desc.u.seg.limit); +#endif + + set_task_busy(task_sel.selector); + CPU_TR = task_sel.selector; + CPU_TR_DESC = task_sel.desc; + CPU_TR_DESC.type |= CPU_SYSDESC_TYPE_TSS_BUSY_IND; + + /* I/O deny bitmap */ + CPU_STAT_IOLIMIT = 0; + if (CPU_TR_DESC.type == CPU_SYSDESC_TYPE_TSS_BUSY_32) { + if (iobase < CPU_TR_LIMIT) { + CPU_STAT_IOLIMIT = (UINT16)(CPU_TR_LIMIT - iobase); + CPU_STAT_IOADDR = CPU_TR_BASE + iobase; + VERBOSE(("load_tr: enable ioport control: iobase=0x%04x, base=0x%08x, limit=0x%08x", iobase, CPU_STAT_IOADDR, CPU_STAT_IOLIMIT)); + } + } + if (CPU_STAT_IOLIMIT == 0) { + VERBOSE(("load_tr: disable ioport control.")); + } +} + +void CPUCALL +get_stack_pointer_from_tss(UINT pl, UINT16 *new_ss, UINT32 *new_esp) +{ + UINT32 tss_stack_addr; + + VERBOSE(("get_stack_pointer_from_tss: pl = %d", pl)); + VERBOSE(("get_stack_pointer_from_tss: CPU_TR type = %d, base = 0x%08x, limit = 0x%08x", CPU_TR_DESC.type, CPU_TR_BASE, CPU_TR_LIMIT)); + + __ASSERT(pl < 3); + + if (CPU_TR_DESC.type == CPU_SYSDESC_TYPE_TSS_BUSY_32) { + tss_stack_addr = pl * 8 + 4; + if (tss_stack_addr + 7 > CPU_TR_LIMIT) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + tss_stack_addr += CPU_TR_BASE; + *new_esp = cpu_kmemoryread_d(tss_stack_addr); + *new_ss = cpu_kmemoryread_w(tss_stack_addr + 4); + } else if (CPU_TR_DESC.type == CPU_SYSDESC_TYPE_TSS_BUSY_16) { + tss_stack_addr = pl * 4 + 2; + if (tss_stack_addr + 3 > CPU_TR_LIMIT) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + tss_stack_addr += CPU_TR_BASE; + *new_esp = cpu_kmemoryread_w(tss_stack_addr); + *new_ss = cpu_kmemoryread_w(tss_stack_addr + 2); + } else { + ia32_panic("get_stack_pointer_from_tss: task register is invalid (%d)\n", CPU_TR_DESC.type); + } + VERBOSE(("get_stack_pointer_from_tss: new stack pointer = %04x:%08x", + *new_ss, *new_esp)); +} + +UINT16 +get_backlink_selector_from_tss(void) +{ + UINT16 backlink; + + if (CPU_TR_DESC.type == CPU_SYSDESC_TYPE_TSS_BUSY_32) { + if (4 > CPU_TR_LIMIT) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + } else if (CPU_TR_DESC.type == CPU_SYSDESC_TYPE_TSS_BUSY_16) { + if (2 > CPU_TR_LIMIT) { + EXCEPTION(TS_EXCEPTION, CPU_TR & ~3); + } + } else { + ia32_panic("get_backlink_selector_from_tss: task register has invalid type (%d)\n", CPU_TR_DESC.type); + } + + backlink = cpu_kmemoryread_w(CPU_TR_BASE); + VERBOSE(("get_backlink_selector_from_tss: backlink selector = 0x%04x", + backlink)); + return backlink; +} + +void CPUCALL +task_switch(selector_t *task_sel, task_switch_type_t type) +{ + UINT32 regs[CPU_REG_NUM]; + UINT32 eip; + UINT32 new_flags; + UINT32 cr3 = 0; + UINT16 sreg[CPU_SEGREG_NUM]; + UINT16 ldtr; + UINT16 iobase; + UINT16 t; + + selector_t cs_sel, ss_sel; + int rv; + + UINT32 cur_base, cur_paddr; /* current task state */ + UINT32 task_base, task_paddr; /* new task state */ + UINT32 old_flags = REAL_EFLAGREG; + BOOL task16; + UINT i; + + VERBOSE(("task_switch: start")); + + switch (task_sel->desc.type) { + case CPU_SYSDESC_TYPE_TSS_32: + case CPU_SYSDESC_TYPE_TSS_BUSY_32: + if (task_sel->desc.u.seg.limit < TSS_32_LIMIT) { + EXCEPTION(TS_EXCEPTION, task_sel->idx); + } + task16 = 0; + break; + + case CPU_SYSDESC_TYPE_TSS_16: + case CPU_SYSDESC_TYPE_TSS_BUSY_16: + if (task_sel->desc.u.seg.limit < TSS_16_LIMIT) { + EXCEPTION(TS_EXCEPTION, task_sel->idx); + } + task16 = 1; + break; + + default: + ia32_panic("task_switch: descriptor type is invalid."); + task16 = 0; /* compiler happy */ + break; + } + + cur_base = CPU_TR_BASE; + cur_paddr = laddr_to_paddr(cur_base, CPU_PAGE_WRITE_DATA|CPU_MODE_SUPERVISER); + task_base = task_sel->desc.u.seg.segbase; + task_paddr = laddr_to_paddr(task_base, CPU_PAGE_WRITE_DATA|CPU_MODE_SUPERVISER); + VERBOSE(("task_switch: current task (%04x) = 0x%08x:%08x (p0x%08x)", + CPU_TR, cur_base, CPU_TR_LIMIT, cur_paddr)); + VERBOSE(("task_switch: new task (%04x) = 0x%08x:%08x (p0x%08x)", + task_sel->selector, task_base, task_sel->desc.u.seg.limit, + task_paddr)); + VERBOSE(("task_switch: %dbit task switch", task16 ? 16 : 32)); + +#if defined(MORE_DEBUG) + VERBOSE(("task_switch: new task")); + for (i = 0; i < task_sel->desc.u.seg.limit; i += 4) { + VERBOSE(("task_switch: 0x%08x: %08x", task_base + i, + cpu_memoryread_d(task_paddr + i))); + } +#endif + + /* load task state */ + if (!task16) { + if (CPU_STAT_PAGING) { + cr3 = cpu_memoryread_d(task_paddr + 28); + } + eip = cpu_memoryread_d(task_paddr + 32); + new_flags = cpu_memoryread_d(task_paddr + 36); + for (i = 0; i < CPU_REG_NUM; i++) { + regs[i] = cpu_memoryread_d(task_paddr + 40 + i * 4); + } + for (i = 0; i < CPU_SEGREG_NUM; i++) { + sreg[i] = cpu_memoryread_w(task_paddr + 72 + i * 4); + } + ldtr = cpu_memoryread_w(task_paddr + 96); + t = cpu_memoryread_w(task_paddr + 100); + if (t & 1) { + CPU_STAT_BP_EVENT |= CPU_STAT_BP_EVENT_TASK; + } + iobase = cpu_memoryread_w(task_paddr + 102); + } else { + eip = cpu_memoryread_w(task_paddr + 14); + new_flags = cpu_memoryread_w(task_paddr + 16); + for (i = 0; i < CPU_REG_NUM; i++) { + regs[i] = cpu_memoryread_w(task_paddr + 18 + i * 2); + } + for (i = 0; i < CPU_SEGREG286_NUM; i++) { + sreg[i] = cpu_memoryread_w(task_paddr + 34 + i * 2); + } + for (; i < CPU_SEGREG_NUM; i++) { + sreg[i] = 0; + } + ldtr = cpu_memoryread_w(task_paddr + 42); + iobase = 0; + t = 0; + } + +#if defined(DEBUG) + VERBOSE(("task_switch: current task")); + if (!task16) { + VERBOSE(("task_switch: CR3 = 0x%08x", CPU_CR3)); + } + VERBOSE(("task_switch: eip = 0x%08x", CPU_EIP)); + VERBOSE(("task_switch: eflags = 0x%08x", old_flags)); + for (i = 0; i < CPU_REG_NUM; i++) { + VERBOSE(("task_switch: %s = 0x%08x", reg32_str[i], + CPU_REGS_DWORD(i))); + } + for (i = 0; i < CPU_SEGREG_NUM; i++) { + VERBOSE(("task_switch: %s = 0x%04x", sreg_str[i], + CPU_REGS_SREG(i))); + } + VERBOSE(("task_switch: ldtr = 0x%04x", CPU_LDTR)); + + VERBOSE(("task_switch: new task")); + if (!task16) { + VERBOSE(("task_switch: CR3 = 0x%08x", cr3)); + } + VERBOSE(("task_switch: eip = 0x%08x", eip)); + VERBOSE(("task_switch: eflags = 0x%08x", new_flags)); + for (i = 0; i < CPU_REG_NUM; i++) { + VERBOSE(("task_switch: %s = 0x%08x", reg32_str[i], regs[i])); + } + for (i = 0; i < CPU_SEGREG_NUM; i++) { + VERBOSE(("task_switch: %s = 0x%04x", sreg_str[i], sreg[i])); + } + VERBOSE(("task_switch: ldtr = 0x%04x", ldtr)); + if (!task16) { + VERBOSE(("task_switch: t = 0x%04x", t)); + VERBOSE(("task_switch: iobase = 0x%04x", iobase)); + } +#endif + + /* if IRET or JMP, clear busy flag in this task: need */ + /* if IRET, clear NT_FLAG in current EFLAG: need */ + switch (type) { + case TASK_SWITCH_IRET: + /* clear NT_FLAG */ + old_flags &= ~NT_FLAG; + /*FALLTHROUGH*/ + case TASK_SWITCH_JMP: + /* clear busy flags in current task */ + set_task_free(CPU_TR); + break; + + case TASK_SWITCH_CALL: + case TASK_SWITCH_INTR: + /* Nothing to do */ + break; + + default: + ia32_panic("task_switch: task switch type is invalid"); + break; + } + + /* store current task state in current TSS */ + if (!task16) { + cpu_memorywrite_d(cur_paddr + 32, CPU_EIP); + cpu_memorywrite_d(cur_paddr + 36, old_flags); + for (i = 0; i < CPU_REG_NUM; i++) { + cpu_memorywrite_d(cur_paddr + 40 + i * 4, + CPU_REGS_DWORD(i)); + } + for (i = 0; i < CPU_SEGREG_NUM; i++) { + cpu_memorywrite_w(cur_paddr + 72 + i * 4, + CPU_REGS_SREG(i)); + } + } else { + cpu_memorywrite_w(cur_paddr + 14, CPU_IP); + cpu_memorywrite_w(cur_paddr + 16, (UINT16)old_flags); + for (i = 0; i < CPU_REG_NUM; i++) { + cpu_memorywrite_w(cur_paddr + 18 + i * 2, + CPU_REGS_WORD(i)); + } + for (i = 0; i < CPU_SEGREG286_NUM; i++) { + cpu_memorywrite_w(cur_paddr + 34 + i * 2, + CPU_REGS_SREG(i)); + } + } + + /* set back link selector */ + switch (type) { + case TASK_SWITCH_CALL: + case TASK_SWITCH_INTR: + /* set back link selector */ + cpu_memorywrite_w(task_paddr, CPU_TR); + break; + + case TASK_SWITCH_IRET: + case TASK_SWITCH_JMP: + /* Nothing to do */ + break; + + default: + ia32_panic("task_switch: task switch type is invalid"); + break; + } + +#if defined(MORE_DEBUG) + VERBOSE(("task_switch: current task")); + for (i = 0; i < CPU_TR_LIMIT; i += 4) { + VERBOSE(("task_switch: 0x%08x: %08x", cur_base + i, + cpu_memoryread_d(cur_paddr + i))); + } +#endif + + /* Now task switching! */ + + /* if CALL, INTR, set EFLAGS image NT_FLAG */ + /* if CALL, INTR, JMP set busy flag */ + switch (type) { + case TASK_SWITCH_CALL: + case TASK_SWITCH_INTR: + /* set back link selector */ + new_flags |= NT_FLAG; + /*FALLTHROUGH*/ + case TASK_SWITCH_JMP: + set_task_busy(task_sel->selector); + break; + + case TASK_SWITCH_IRET: + /* check busy flag is active */ + if (SEG_IS_VALID(&task_sel->desc)) { + UINT32 h; + h = cpu_kmemoryread_d(task_sel->addr + 4); + if ((h & CPU_TSS_H_BUSY) == 0) { + ia32_panic("task_switch: new task is not busy"); + } + } + break; + + default: + ia32_panic("task_switch: task switch type is invalid"); + break; + } + + /* load task selector to CPU_TR */ + CPU_TR = task_sel->selector; + CPU_TR_DESC = task_sel->desc; + CPU_TR_DESC.type |= CPU_SYSDESC_TYPE_TSS_BUSY_IND; + + /* set CR0 image CPU_CR0_TS */ + CPU_CR0 |= CPU_CR0_TS; + + /* + * load task state (CR3, EIP, GPR, segregs, LDTR, EFLAGS) + */ + + /* set new CR3 */ + if (!task16 && CPU_STAT_PAGING) { + set_cr3(cr3); + } + + /* set new EIP, GPR, segregs */ + CPU_EIP = eip; + for (i = 0; i < CPU_REG_NUM; i++) { + CPU_REGS_DWORD(i) = regs[i]; + } + for (i = 0; i < CPU_SEGREG_NUM; i++) { + segdesc_init(i, sreg[i], &CPU_STAT_SREG(i)); + /* invalidate segreg descriptor */ + CPU_STAT_SREG(i).valid = 0; + } + + CPU_CLEAR_PREV_ESP(); + + /* load new LDTR */ + CPU_LDTR_DESC.valid = 0; + load_ldtr(ldtr, TS_EXCEPTION); + + /* I/O deny bitmap */ + CPU_STAT_IOLIMIT = 0; + if (!task16 && iobase != 0 && iobase < CPU_TR_DESC.u.seg.limit) { + CPU_STAT_IOLIMIT = (UINT16)(CPU_TR_DESC.u.seg.limit - iobase); + CPU_STAT_IOADDR = task_base + iobase; + } + VERBOSE(("task_switch: ioaddr = %08x, limit = %08x", CPU_STAT_IOADDR, + CPU_STAT_IOLIMIT)); + + /* set new EFLAGS */ + set_eflags(new_flags, I_FLAG|IOPL_FLAG|RF_FLAG|VM_FLAG|VIF_FLAG|VIP_FLAG); + + /* set new segment register */ + if (!CPU_STAT_VM86) { + /* load CS */ + rv = parse_selector(&cs_sel, sreg[CPU_CS_INDEX]); + if (rv < 0) { + VERBOSE(("task_switch: load CS failure (sel = 0x%04x, rv = %d)", sreg[CPU_CS_INDEX], rv)); + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + + /* CS must be code segment */ + if (SEG_IS_SYSTEM(&cs_sel.desc) || SEG_IS_DATA(&cs_sel.desc)) { + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + + /* check privilege level */ + if (!SEG_IS_CONFORMING_CODE(&cs_sel.desc)) { + /* non-confirming code segment */ + if (cs_sel.desc.dpl != cs_sel.rpl) { + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + } else { + /* conforming code segment */ + if (cs_sel.desc.dpl > cs_sel.rpl) { + EXCEPTION(TS_EXCEPTION, cs_sel.idx); + } + } + + /* code segment is not present */ + rv = selector_is_not_present(&cs_sel); + if (rv < 0) { + EXCEPTION(NP_EXCEPTION, cs_sel.idx); + } + + /* load SS */ + rv = parse_selector(&ss_sel, sreg[CPU_SS_INDEX]); + if (rv < 0) { + VERBOSE(("task_switch: load SS failure (sel = 0x%04x, rv = %d)", sreg[CPU_SS_INDEX], rv)); + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* SS must be writable data segment */ + if (SEG_IS_SYSTEM(&ss_sel.desc) + || SEG_IS_CODE(&ss_sel.desc) + || !SEG_IS_WRITABLE_DATA(&ss_sel.desc)) { + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* check privilege level */ + if ((ss_sel.desc.dpl != cs_sel.rpl) + || (ss_sel.desc.dpl != ss_sel.rpl)) { + EXCEPTION(TS_EXCEPTION, ss_sel.idx); + } + + /* stack segment is not present */ + rv = selector_is_not_present(&ss_sel); + if (rv < 0) { + EXCEPTION(SS_EXCEPTION, ss_sel.idx); + } + + /* Now loading SS register */ + load_ss(ss_sel.selector, &ss_sel.desc, cs_sel.rpl); + + /* load ES, DS, FS, GS segment register */ + LOAD_SEGREG1(CPU_ES_INDEX, sreg[CPU_ES_INDEX], TS_EXCEPTION); + LOAD_SEGREG1(CPU_DS_INDEX, sreg[CPU_DS_INDEX], TS_EXCEPTION); + LOAD_SEGREG1(CPU_FS_INDEX, sreg[CPU_FS_INDEX], TS_EXCEPTION); + LOAD_SEGREG1(CPU_GS_INDEX, sreg[CPU_GS_INDEX], TS_EXCEPTION); + + /* Now loading CS register */ + load_cs(cs_sel.selector, &cs_sel.desc, cs_sel.rpl); + } + + VERBOSE(("task_switch: done.")); +} diff --git a/source/src/vm/np21/i386c/ia32/task.h b/source/src/vm/np21/i386c/ia32/task.h new file mode 100644 index 000000000..684de4a35 --- /dev/null +++ b/source/src/vm/np21/i386c/ia32/task.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2003 NONAKA Kimihiro + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IA32_CPU_TASK_H__ +#define IA32_CPU_TASK_H__ + +//#ifdef __cplusplus +//extern "C" { +//#endif + +void CPUCALL load_tr(UINT16 selector); +void CPUCALL get_stack_pointer_from_tss(UINT pl, UINT16 *new_ss, UINT32 *new_esp); +UINT16 get_backlink_selector_from_tss(void); + +/* task_switch type */ +typedef enum { + TASK_SWITCH_JMP, + TASK_SWITCH_CALL, + TASK_SWITCH_IRET, + TASK_SWITCH_INTR +} task_switch_type_t; + +void CPUCALL task_switch(selector_t *selector, task_switch_type_t type); + +//#ifdef __cplusplus +//} +//#endif + +#endif /* !IA32_CPU_TASK_H__ */ diff --git a/source/src/vm/np21/i386c/readme_takeda.txt b/source/src/vm/np21/i386c/readme_takeda.txt new file mode 100644 index 000000000..81c2d2ea8 --- /dev/null +++ b/source/src/vm/np21/i386c/readme_takeda.txt @@ -0,0 +1 @@ +Based on Neko Project 21/W 0.86 rev70beta1 diff --git a/source/src/vm/or.h b/source/src/vm/or.h index c9efac764..3fa9942a2 100644 --- a/source/src/vm/or.h +++ b/source/src/vm/or.h @@ -23,9 +23,7 @@ #define SIG_OR_BIT_6 0x40 #define SIG_OR_BIT_7 0x80 -class VM; -class EMU; -class OR : public DEVICE +class DLL_PREFIX OR : public DEVICE { private: outputs_t outputs; @@ -33,7 +31,7 @@ class OR : public DEVICE bool prev, first; public: - OR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + OR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs); bits_in = 0; diff --git a/source/src/vm/pasopia/CMakeLists.txt b/source/src/vm/pasopia/CMakeLists.txt index 2f0fca1a2..d2e41da37 100644 --- a/source/src/vm/pasopia/CMakeLists.txt +++ b/source/src/vm/pasopia/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pasopia") +message("* vm/${EXE_NAME}") set(VM_PASOPIA_LIB_SRCS pasopia.cpp @@ -15,6 +15,6 @@ set(VM_PASOPIA_LIB_SRCS rampac2.cpp ) -add_library(vm_pasopia +add_library(vm_${EXE_NAME} ${VM_PASOPIA_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/pasopia/display.h b/source/src/vm/pasopia/display.h index 9a3df2d06..ea4a35b39 100644 --- a/source/src/vm/pasopia/display.h +++ b/source/src/vm/pasopia/display.h @@ -43,7 +43,7 @@ class DISPLAY : public DEVICE void draw_screen15_wide(uint16_t src); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/pasopia/floppy.h b/source/src/vm/pasopia/floppy.h index d0fc0550d..09355f3e7 100644 --- a/source/src/vm/pasopia/floppy.h +++ b/source/src/vm/pasopia/floppy.h @@ -25,7 +25,7 @@ class FLOPPY : public DEVICE bool intr; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/pasopia/joypac2.h b/source/src/vm/pasopia/joypac2.h index 16e4ba0ed..608cdb11f 100644 --- a/source/src/vm/pasopia/joypac2.h +++ b/source/src/vm/pasopia/joypac2.h @@ -22,7 +22,7 @@ class JOYPAC2 : public PAC2DEV private: const uint32_t* joy; public: - JOYPAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : PAC2DEV(parent_vm, parent_emu) + JOYPAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : PAC2DEV(parent_vm, parent_emu) { set_device_name(_T("Joystick PAC2")); } diff --git a/source/src/vm/pasopia/kanjipac2.h b/source/src/vm/pasopia/kanjipac2.h index 0ea2b6fcc..0a46826db 100644 --- a/source/src/vm/pasopia/kanjipac2.h +++ b/source/src/vm/pasopia/kanjipac2.h @@ -23,7 +23,7 @@ class KANJIPAC2 : public PAC2DEV uint8_t rom[0x20000]; uint32_t ptr; public: - KANJIPAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : PAC2DEV(parent_vm, parent_emu) + KANJIPAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : PAC2DEV(parent_vm, parent_emu) { set_device_name(_T("Kanji ROM PAC2")); } diff --git a/source/src/vm/pasopia/keyboard.h b/source/src/vm/pasopia/keyboard.h index c48258366..b2f016801 100644 --- a/source/src/vm/pasopia/keyboard.h +++ b/source/src/vm/pasopia/keyboard.h @@ -28,7 +28,7 @@ class KEYBOARD : public DEVICE uint8_t sel; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/pasopia/memory.h b/source/src/vm/pasopia/memory.h index 573182ea0..b29b4a927 100644 --- a/source/src/vm/pasopia/memory.h +++ b/source/src/vm/pasopia/memory.h @@ -37,7 +37,7 @@ class MEMORY : public DEVICE uint8_t vram_data, mem_map; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/pasopia/pac2.h b/source/src/vm/pasopia/pac2.h index 29a210e93..73ad048cc 100644 --- a/source/src/vm/pasopia/pac2.h +++ b/source/src/vm/pasopia/pac2.h @@ -36,7 +36,7 @@ class PAC2 : public DEVICE PASOPIA::PAC2DEV* get_device(); public: - PAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("PAC2 Slot")); } diff --git a/source/src/vm/pasopia/pac2dev.h b/source/src/vm/pasopia/pac2dev.h index 5e3246a08..ec8263fb9 100644 --- a/source/src/vm/pasopia/pac2dev.h +++ b/source/src/vm/pasopia/pac2dev.h @@ -12,7 +12,7 @@ #define _PAC2DEV_H_ #include "../vm_template.h" -#include "../../emu.h" +#include "../../emu_template.h" namespace PASOPIA { @@ -20,10 +20,10 @@ class PAC2DEV { protected: VM* vm; - EMU* emu; + EMU_TEMPLATE* emu; public: - PAC2DEV(VM_TEMPLATE* parent_vm, EMU* parent_emu) : vm((VM *)parent_vm), emu(parent_emu) + PAC2DEV(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : vm((VM *)parent_vm), emu(parent_emu) { set_device_name(_T("PAC2 Base Device")); } diff --git a/source/src/vm/pasopia/pasopia.cpp b/source/src/vm/pasopia/pasopia.cpp index 99baacc33..2254bf1d6 100644 --- a/source/src/vm/pasopia/pasopia.cpp +++ b/source/src/vm/pasopia/pasopia.cpp @@ -47,7 +47,7 @@ using PASOPIA::PAC2; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { boot_mode = config.boot_mode; @@ -464,6 +464,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -476,7 +488,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pasopia/pasopia.h b/source/src/vm/pasopia/pasopia.h index 95dce9967..bdde1931b 100644 --- a/source/src/vm/pasopia/pasopia.h +++ b/source/src/vm/pasopia/pasopia.h @@ -110,7 +110,7 @@ class VM : public VM_TEMPLATE //csp_state_utils *state_entry; // devices - EVENT* event; +// EVENT* event; DATAREC* drec; HD46505* crtc; @@ -139,7 +139,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -192,6 +192,9 @@ class VM : public VM_TEMPLATE void save_binary(int drv, const _TCHAR* file_path) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pasopia/rampac2.h b/source/src/vm/pasopia/rampac2.h index 5efbf2746..a7e958249 100644 --- a/source/src/vm/pasopia/rampac2.h +++ b/source/src/vm/pasopia/rampac2.h @@ -26,7 +26,7 @@ class RAMPAC2 : public PAC2DEV bool opened, modified; public: - RAMPAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : PAC2DEV(parent_vm, parent_emu) + RAMPAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : PAC2DEV(parent_vm, parent_emu) { set_device_name(_T("RAM PAC2")); } diff --git a/source/src/vm/pasopia7/CMakeLists.txt b/source/src/vm/pasopia7/CMakeLists.txt index 16b6b57ff..9f4803456 100644 --- a/source/src/vm/pasopia7/CMakeLists.txt +++ b/source/src/vm/pasopia7/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pasopia7") +message("* vm/${EXE_NAME}") set(VM_PASOPIA7_LIB_SRCS pasopia7.cpp @@ -17,6 +17,6 @@ set(VM_PASOPIA7_LIB_SRCS rampac2.cpp ) -add_library(vm_pasopia7 +add_library(vm_${EXE_NAME} ${VM_PASOPIA7_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/pasopia7/display.h b/source/src/vm/pasopia7/display.h index 904b8c874..a208b68df 100644 --- a/source/src/vm/pasopia7/display.h +++ b/source/src/vm/pasopia7/display.h @@ -45,7 +45,7 @@ class DISPLAY : public DEVICE void draw_fine_lcd(uint16_t src); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/pasopia7/floppy.h b/source/src/vm/pasopia7/floppy.h index d7ff6d3bd..7e8d430af 100644 --- a/source/src/vm/pasopia7/floppy.h +++ b/source/src/vm/pasopia7/floppy.h @@ -25,7 +25,7 @@ class FLOPPY : public DEVICE bool intr; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/pasopia7/iobus.h b/source/src/vm/pasopia7/iobus.h index caab16e0e..c60541246 100644 --- a/source/src/vm/pasopia7/iobus.h +++ b/source/src/vm/pasopia7/iobus.h @@ -26,7 +26,7 @@ class IOBUS : public DEVICE bool mio; public: - IOBUS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IOBUS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } diff --git a/source/src/vm/pasopia7/iotrap.h b/source/src/vm/pasopia7/iotrap.h index 944c3333f..0ca479eaf 100644 --- a/source/src/vm/pasopia7/iotrap.h +++ b/source/src/vm/pasopia7/iotrap.h @@ -26,7 +26,7 @@ class IOTRAP : public DEVICE bool nmi_mask, pasopia; public: - IOTRAP(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IOTRAP(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Trap")); } diff --git a/source/src/vm/pasopia7/joypac2.h b/source/src/vm/pasopia7/joypac2.h index 1d2f7b5ec..ffb5e52ee 100644 --- a/source/src/vm/pasopia7/joypac2.h +++ b/source/src/vm/pasopia7/joypac2.h @@ -22,7 +22,7 @@ class JOYPAC2 : public PAC2DEV private: const uint32_t* joy; public: - JOYPAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : PAC2DEV(parent_vm, parent_emu) + JOYPAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : PAC2DEV(parent_vm, parent_emu) { set_device_name(_T("Joystick PAC2")); } diff --git a/source/src/vm/pasopia7/kanjipac2.h b/source/src/vm/pasopia7/kanjipac2.h index a7b6bbbe9..b3309f22d 100644 --- a/source/src/vm/pasopia7/kanjipac2.h +++ b/source/src/vm/pasopia7/kanjipac2.h @@ -23,7 +23,7 @@ class KANJIPAC2 : public PAC2DEV uint8_t rom[0x20000]; uint32_t ptr; public: - KANJIPAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : PAC2DEV(parent_vm, parent_emu) + KANJIPAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : PAC2DEV(parent_vm, parent_emu) { set_device_name(_T("Kanji ROM PAC2")); } diff --git a/source/src/vm/pasopia7/keyboard.h b/source/src/vm/pasopia7/keyboard.h index a5360011c..f551a1cff 100644 --- a/source/src/vm/pasopia7/keyboard.h +++ b/source/src/vm/pasopia7/keyboard.h @@ -28,7 +28,7 @@ class KEYBOARD : public DEVICE uint8_t sel; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/pasopia7/memory.h b/source/src/vm/pasopia7/memory.h index f91e55208..141872938 100644 --- a/source/src/vm/pasopia7/memory.h +++ b/source/src/vm/pasopia7/memory.h @@ -41,7 +41,7 @@ class MEMORY : public DEVICE void update_memory_map(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/pasopia7/pac2.h b/source/src/vm/pasopia7/pac2.h index 7c12cffe4..20b93ac0b 100644 --- a/source/src/vm/pasopia7/pac2.h +++ b/source/src/vm/pasopia7/pac2.h @@ -35,7 +35,7 @@ class PAC2 : public DEVICE PASOPIA7::PAC2DEV* dummy; public: - PAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("PAC2 Slot")); } diff --git a/source/src/vm/pasopia7/pac2dev.h b/source/src/vm/pasopia7/pac2dev.h index fef06899c..b5154d666 100644 --- a/source/src/vm/pasopia7/pac2dev.h +++ b/source/src/vm/pasopia7/pac2dev.h @@ -12,7 +12,7 @@ #define _PAC2DEV_H_ #include "../vm.h" -#include "../../emu.h" +#include "../../emu_template.h" namespace PASOPIA7 { @@ -20,9 +20,9 @@ class PAC2DEV { protected: VM_TEMPLATE* vm; - EMU* emu; + EMU_TEMPLATE* emu; public: - PAC2DEV(VM_TEMPLATE* parent_vm, EMU* parent_emu) : vm(parent_vm), emu(parent_emu) + PAC2DEV(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : vm(parent_vm), emu(parent_emu) { set_device_name(_T("PAC2 Base Device")); } diff --git a/source/src/vm/pasopia7/pasopia7.cpp b/source/src/vm/pasopia7/pasopia7.cpp index 2ea425cb8..8ec0242d8 100644 --- a/source/src/vm/pasopia7/pasopia7.cpp +++ b/source/src/vm/pasopia7/pasopia7.cpp @@ -51,7 +51,7 @@ using PASOPIA7::PAC2; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -458,6 +458,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -470,7 +482,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pasopia7/pasopia7.h b/source/src/vm/pasopia7/pasopia7.h index a346d9fa8..03603923a 100644 --- a/source/src/vm/pasopia7/pasopia7.h +++ b/source/src/vm/pasopia7/pasopia7.h @@ -132,7 +132,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -185,6 +185,9 @@ class VM : public VM_TEMPLATE void save_binary(int drv, const _TCHAR* file_path) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pasopia7/rampac2.h b/source/src/vm/pasopia7/rampac2.h index 0d5af7f1e..d6615a227 100644 --- a/source/src/vm/pasopia7/rampac2.h +++ b/source/src/vm/pasopia7/rampac2.h @@ -26,7 +26,7 @@ class RAMPAC2 : public PAC2DEV bool opened, modified; int this_device_id; public: - RAMPAC2(VM_TEMPLATE* parent_vm, EMU* parent_emu) : PAC2DEV(parent_vm, parent_emu) + RAMPAC2(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : PAC2DEV(parent_vm, parent_emu) { static int num = 1; this_device_id = num++; diff --git a/source/src/vm/pc100/CMakeLists.txt b/source/src/vm/pc100/CMakeLists.txt index eb42b679e..0165b46f7 100644 --- a/source/src/vm/pc100/CMakeLists.txt +++ b/source/src/vm/pc100/CMakeLists.txt @@ -1,15 +1,17 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pc100") +message("* vm/emupc100") -set(VM_pc100_LIB_SRCS - pc100.cpp +set(VM_emupc100_LIB_SRCS + ../msm58321.cpp crtc.cpp ioctrl.cpp kanji.cpp + + pc100.cpp ) -add_library(vm_pc100 - ${VM_pc100_LIB_SRCS} -) \ No newline at end of file +add_library(vm_emupc100 + ${VM_emupc100_LIB_SRCS} +) diff --git a/source/src/vm/pc100/crtc.h b/source/src/vm/pc100/crtc.h index b998844f0..6ceb5b4ae 100644 --- a/source/src/vm/pc100/crtc.h +++ b/source/src/vm/pc100/crtc.h @@ -37,7 +37,7 @@ class CRTC : public DEVICE void update_palette(int num); public: - CRTC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CRTC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CRTC")); } diff --git a/source/src/vm/pc100/ioctrl.h b/source/src/vm/pc100/ioctrl.h index 761404eac..2750c6456 100644 --- a/source/src/vm/pc100/ioctrl.h +++ b/source/src/vm/pc100/ioctrl.h @@ -38,7 +38,7 @@ class IOCTRL : public DEVICE void update_key(); public: - IOCTRL(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IOCTRL(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Controller")); } @@ -50,7 +50,7 @@ class IOCTRL : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc100/kanji.h b/source/src/vm/pc100/kanji.h index 022d56044..ef7e675a5 100644 --- a/source/src/vm/pc100/kanji.h +++ b/source/src/vm/pc100/kanji.h @@ -24,7 +24,7 @@ class KANJI : public DEVICE bool strobe; public: - KANJI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KANJI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Kanji ROM")); } diff --git a/source/src/vm/pc100/pc100.cpp b/source/src/vm/pc100/pc100.cpp index bd069d961..f9eb47450 100644 --- a/source/src/vm/pc100/pc100.cpp +++ b/source/src/vm/pc100/pc100.cpp @@ -18,7 +18,7 @@ #include "../i8251.h" #include "../i8255.h" #include "../i8259.h" -#include "../i286.h" +#include "../i86.h" #include "../io.h" #include "../memory.h" #include "../msm58321.h" @@ -42,7 +42,7 @@ using PC100::KANJI; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -60,9 +60,12 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pio1 = new I8255(this, emu); pio1->set_device_name(_T("8255 PIO (CRTC)")); pic = new I8259(this, emu); - cpu = new I80286(this, emu); + cpu = new I86(this, emu); + cpu->device_model = INTEL_8086; + io = new IO(this, emu); memory = new MEMORY(this, emu); + rtc = new MSM58321(this, emu); pcm = new PCM1BIT(this, emu); fdc = new UPD765A(this, emu); @@ -353,7 +356,19 @@ void VM::update_config() } } -#define STATE_VERSION 3 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -365,7 +380,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pc100/pc100.h b/source/src/vm/pc100/pc100.h index ee4744909..60b7ea331 100644 --- a/source/src/vm/pc100/pc100.h +++ b/source/src/vm/pc100/pc100.h @@ -22,7 +22,6 @@ #define WINDOW_HEIGHT_ASPECT 540 //720 #define MAX_DRIVE 4 -#define HAS_I86 #define I8259_MAX_CHIPS 1 #define MSM58321_START_DAY -9 #define MSM58321_START_YEAR 1980 @@ -65,7 +64,7 @@ class BEEP; class I8251; class I8255; class I8259; -class I80286; +class I86; class IO; class MEMORY; class MSM58321; @@ -93,7 +92,7 @@ class VM : public VM_TEMPLATE I8255* pio0; I8255* pio1; I8259* pic; // includes 2chips - I80286* cpu; + I86* cpu; IO* io; MEMORY* memory; MSM58321* rtc; @@ -113,7 +112,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -159,6 +158,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc2001/CMakeLists.txt b/source/src/vm/pc2001/CMakeLists.txt index fe229aa44..352d68e11 100644 --- a/source/src/vm/pc2001/CMakeLists.txt +++ b/source/src/vm/pc2001/CMakeLists.txt @@ -1,6 +1,10 @@ +message("* vm/${EXE_NAME}") + cmake_minimum_required (VERSION 2.6) -add_library(vm_pc2001 - io.cpp +add_library(vm_emupc2001 + ../upd7907.cpp + + ./io.cpp pc2001.cpp ) diff --git a/source/src/vm/pc2001/io.h b/source/src/vm/pc2001/io.h index 1566f8376..2bfb0d94a 100644 --- a/source/src/vm/pc2001/io.h +++ b/source/src/vm/pc2001/io.h @@ -37,10 +37,10 @@ class IO : public DEVICE uint16_t key_strobe; uint8_t get_key(); - bool key_hit(int code); + bool __FASTCALL key_hit(int code); public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } @@ -53,7 +53,7 @@ class IO : public DEVICE uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_io16(uint32_t addr, uint32_t data); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/pc2001/pc2001.cpp b/source/src/vm/pc2001/pc2001.cpp index 46269080c..99aeb67ee 100644 --- a/source/src/vm/pc2001/pc2001.cpp +++ b/source/src/vm/pc2001/pc2001.cpp @@ -33,7 +33,7 @@ using PC2001::IO; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -45,6 +45,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) drec->set_context_noise_stop(new NOISE(this, emu)); drec->set_context_noise_fast(new NOISE(this, emu)); memory = new MEMORY(this, emu); + pcm = new PCM1BIT(this, emu); #ifdef USE_DEBUGGER // pcm->set_context_debugger(new DEBUGGER(this, emu)); @@ -307,6 +308,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -316,7 +329,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) } for(DEVICE* device = first_device; device; device = device->next_device) { const char *name = typeid(*device).name() + 6; // skip "class " - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { return false; diff --git a/source/src/vm/pc2001/pc2001.h b/source/src/vm/pc2001/pc2001.h index 81dab6dc3..628c97bd2 100644 --- a/source/src/vm/pc2001/pc2001.h +++ b/source/src/vm/pc2001/pc2001.h @@ -89,7 +89,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -137,6 +137,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc6001/CMakeLists.txt b/source/src/vm/pc6001/CMakeLists.txt index c0c4c5bdd..6177628ac 100644 --- a/source/src/vm/pc6001/CMakeLists.txt +++ b/source/src/vm/pc6001/CMakeLists.txt @@ -2,38 +2,37 @@ cmake_minimum_required (VERSION 2.6) message("* vm/pc6001") -set(BASIC_VM_FILES -# display.cpp - - joystick.cpp - memory.cpp -# memory_draw.cpp - pc6001.cpp - psub.cpp - sub.cpp - timer.cpp +set(BASIC_VM_FILES_PC6001 + ../mcs48.cpp + joystick.cpp + memory.cpp + psub.cpp + sub.cpp + timer.cpp + pc6001.cpp ) - -if(BUILD_PC6601) -add_library(vm_pc6001 - ${BASIC_VM_FILES} - memory_draw.cpp - floppy.cpp - ) -elseif(BUILD_PC6601SR) -add_library(vm_pc6001 - ${BASIC_VM_FILES} - memory_draw.cpp - floppy.cpp - ) -elseif(BUILD_PC6001) -add_library(vm_pc6001 - ${BASIC_VM_FILES} - display.cpp - ) +if(${EXE_NAME} STREQUAL emupc6001) + add_library(vm_${EXE_NAME} + ../mc6847.cpp + display.cpp + ${BASIC_VM_FILES_PC6001} + ) +elseif(${EXE_NAME} STREQUAL emupc6601) + add_library(vm_${EXE_NAME} + floppy.cpp + memory_draw.cpp + ${BASIC_VM_FILES_PC6001} + ) +elseif(${EXE_NAME} STREQUAL emupc6601sr) + add_library(vm_${EXE_NAME} + floppy.cpp + memory_draw.cpp + ${BASIC_VM_FILES_PC6001} + ) else() -add_library(vm_pc6001 - ${BASIC_VM_FILES} - memory_draw.cpp - ) -endif() \ No newline at end of file + add_library(vm_${EXE_NAME} + memory_draw.cpp + ${BASIC_VM_FILES_PC6001} + ) +endif() + diff --git a/source/src/vm/pc6001/display.h b/source/src/vm/pc6001/display.h index 29e2a883a..a53ce62a4 100644 --- a/source/src/vm/pc6001/display.h +++ b/source/src/vm/pc6001/display.h @@ -32,7 +32,7 @@ class DISPLAY : public DEVICE int tmp_vram_size; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/pc6001/floppy.h b/source/src/vm/pc6001/floppy.h index d779c43fe..5deb4d2c7 100644 --- a/source/src/vm/pc6001/floppy.h +++ b/source/src/vm/pc6001/floppy.h @@ -103,7 +103,7 @@ class FLOPPY : public DEVICE unsigned char InDDH_66(); public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_noise_seek = NULL; // d_noise_head_down = NULL; diff --git a/source/src/vm/pc6001/joystick.h b/source/src/vm/pc6001/joystick.h index d7704d4b9..fc7de0177 100644 --- a/source/src/vm/pc6001/joystick.h +++ b/source/src/vm/pc6001/joystick.h @@ -27,7 +27,7 @@ class JOYSTICK : public DEVICE const uint32_t *joy_stat; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/pc6001/memory.h b/source/src/vm/pc6001/memory.h index d14e2f044..8696b86fe 100644 --- a/source/src/vm/pc6001/memory.h +++ b/source/src/vm/pc6001/memory.h @@ -145,11 +145,11 @@ class MEMORY : public DEVICE void RefreshScr61(); void RefreshScr62(); void RefreshScr63(); - void do_palet(int dest,int src); + void __FASTCALL do_palet(int dest,int src); void make_semigraph(void); - int chk_gvram(uint32_t A,int flag); - uint8_t gvram_read(uint32_t A); - void gvram_write(uint32_t A, uint32_t V); + int __FASTCALL chk_gvram(uint32_t A,int flag); + uint8_t __FASTCALL gvram_read(uint32_t A); + void __FASTCALL gvram_write(uint32_t A, uint32_t V); #endif #endif @@ -169,7 +169,7 @@ class MEMORY : public DEVICE #endif public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { inserted = false; set_device_name(_T("Memory Bus")); @@ -191,7 +191,7 @@ class MEMORY : public DEVICE void __FASTCALL write_io8w(uint32_t addr, uint32_t data, int* wait); uint32_t __FASTCALL read_io8w(uint32_t addr, int* wait); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc6001/pc6001.cpp b/source/src/vm/pc6001/pc6001.cpp index b6d4ff982..2a7ec01f1 100644 --- a/source/src/vm/pc6001/pc6001.cpp +++ b/source/src/vm/pc6001/pc6001.cpp @@ -70,7 +70,7 @@ using PC6001::TIMER; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { support_pc80s31k = FILEIO::IsFileExisting(create_local_path(_T("DISK.ROM"))); #ifdef _PC6601SR @@ -731,6 +731,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 7 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -743,7 +755,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pc6001/pc6001.h b/source/src/vm/pc6001/pc6001.h index e0235ef34..ec1b1811b 100644 --- a/source/src/vm/pc6001/pc6001.h +++ b/source/src/vm/pc6001/pc6001.h @@ -225,7 +225,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -286,6 +286,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc6001/psub.h b/source/src/vm/pc6001/psub.h index 1b6afbf96..287de38f0 100644 --- a/source/src/vm/pc6001/psub.h +++ b/source/src/vm/pc6001/psub.h @@ -54,7 +54,7 @@ class PSUB : public DEVICE void update_keyboard(int code); public: - PSUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PSUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Pseudo Sub System")); } @@ -67,7 +67,7 @@ class PSUB : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void event_frame(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); uint32_t get_intr_ack(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc6001/sub.h b/source/src/vm/pc6001/sub.h index 0bb0aa1a2..a391d8d2c 100644 --- a/source/src/vm/pc6001/sub.h +++ b/source/src/vm/pc6001/sub.h @@ -42,7 +42,7 @@ class SUB : public DEVICE uint8_t buffer[0x10000]; public: - SUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Sub System")); } @@ -56,7 +56,7 @@ class SUB : public DEVICE uint32_t __FASTCALL read_io8(uint32_t addr); uint32_t get_intr_ack(); void event_frame(); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc6001/timer.h b/source/src/vm/pc6001/timer.h index d3fdba406..855991f03 100644 --- a/source/src/vm/pc6001/timer.h +++ b/source/src/vm/pc6001/timer.h @@ -60,7 +60,7 @@ class TIMER : public DEVICE void update_intr(); public: - TIMER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) {} + TIMER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) {} ~TIMER() {} // common functions @@ -70,7 +70,7 @@ class TIMER : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); #endif - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t get_intr_ack(); void notify_intr_reti(); diff --git a/source/src/vm/pc6031.h b/source/src/vm/pc6031.h index b444b270c..89b9013d3 100644 --- a/source/src/vm/pc6031.h +++ b/source/src/vm/pc6031.h @@ -25,7 +25,7 @@ class DISK; class NOISE; -class PC6031 : public DEVICE +class DLL_PREFIX PC6031 : public DEVICE { private: DISK* disk[2]; @@ -78,7 +78,7 @@ class PC6031 : public DEVICE unsigned char InD3H_60(); public: - PC6031(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PC6031(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { d_noise_seek = NULL; // d_noise_head_down = NULL; diff --git a/source/src/vm/pc80s31k.h b/source/src/vm/pc80s31k.h index 010b4606f..af44c87e8 100644 --- a/source/src/vm/pc80s31k.h +++ b/source/src/vm/pc80s31k.h @@ -16,7 +16,7 @@ class UPD765A; -class PC80S31K : public DEVICE +class DLL_PREFIX PC80S31K : public DEVICE { private: UPD765A *d_fdc; @@ -33,7 +33,7 @@ class PC80S31K : public DEVICE bool _debug_pc80s31k; bool pc80s31k_no_wait; public: - PC80S31K(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PC80S31K(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("PC-80S31K FDD")); diff --git a/source/src/vm/pc8201/CMakeLists.txt b/source/src/vm/pc8201/CMakeLists.txt index 4c5f4efa5..bdcd6b638 100644 --- a/source/src/vm/pc8201/CMakeLists.txt +++ b/source/src/vm/pc8201/CMakeLists.txt @@ -1,11 +1,13 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pc8201") +message("* vm/${EXE_NAME}") -add_library(vm_pc8201 - pc8201.cpp - cmt.cpp - keyboard.cpp - lcd.cpp - memory.cpp +add_library(vm_${EXE_NAME} + ../i8080.cpp + + cmt.cpp + keyboard.cpp + lcd.cpp + ./memory.cpp + pc8201.cpp ) diff --git a/source/src/vm/pc8201/cmt.h b/source/src/vm/pc8201/cmt.h index 124e51c53..f95b7e55e 100644 --- a/source/src/vm/pc8201/cmt.h +++ b/source/src/vm/pc8201/cmt.h @@ -37,7 +37,7 @@ class CMT : public DEVICE void put_signal(); public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } diff --git a/source/src/vm/pc8201/keyboard.h b/source/src/vm/pc8201/keyboard.h index 61630253c..556a88d6f 100644 --- a/source/src/vm/pc8201/keyboard.h +++ b/source/src/vm/pc8201/keyboard.h @@ -27,7 +27,7 @@ class KEYBOARD : public DEVICE bool caps, kana; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/pc8201/lcd.h b/source/src/vm/pc8201/lcd.h index 42536bede..a3b19d112 100644 --- a/source/src/vm/pc8201/lcd.h +++ b/source/src/vm/pc8201/lcd.h @@ -31,7 +31,7 @@ class LCD : public DEVICE uint8_t screen[64][250]; public: - LCD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + LCD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("LCD")); } diff --git a/source/src/vm/pc8201/memory.h b/source/src/vm/pc8201/memory.h index bef0ddc22..a6951782f 100644 --- a/source/src/vm/pc8201/memory.h +++ b/source/src/vm/pc8201/memory.h @@ -33,7 +33,7 @@ class MEMORY : public DEVICE void update_bank(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/pc8201/pc8201.cpp b/source/src/vm/pc8201/pc8201.cpp index e98b9de29..4c71593f5 100644 --- a/source/src/vm/pc8201/pc8201.cpp +++ b/source/src/vm/pc8201/pc8201.cpp @@ -38,7 +38,7 @@ using PC8201::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -362,6 +362,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -374,7 +386,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pc8201/pc8201.h b/source/src/vm/pc8201/pc8201.h index 8a2be0f4c..bc362e826 100644 --- a/source/src/vm/pc8201/pc8201.h +++ b/source/src/vm/pc8201/pc8201.h @@ -91,7 +91,7 @@ class VM :public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -145,6 +145,9 @@ class VM :public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc8801/CMakeLists.txt b/source/src/vm/pc8801/CMakeLists.txt index baef23ebf..943da3a73 100644 --- a/source/src/vm/pc8801/CMakeLists.txt +++ b/source/src/vm/pc8801/CMakeLists.txt @@ -1,15 +1,19 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pc8801") - -if(BUILD_PC98DO) -add_library(vm_pc8801 - pc88.cpp -# pc8801.cpp -) -else() -add_library(vm_pc8801 - pc88.cpp - pc8801.cpp -) -endif() \ No newline at end of file +message("* vm/${EXE_NAME}") + +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +if("${U_EXE_NAME}" STREQUAL "EMUPC8801MA") + add_library(vm_emupc8801ma + ../scsi_host.cpp + pc88.cpp + pc8801.cpp + ) +else() + add_library(vm_${EXE_NAME} + pc88.cpp + pc8801.cpp + ) +endif() + diff --git a/source/src/vm/pc8801/pc88.cpp b/source/src/vm/pc8801/pc88.cpp index 6797e4cc4..32a9b1ada 100644 --- a/source/src/vm/pc8801/pc88.cpp +++ b/source/src/vm/pc8801/pc88.cpp @@ -2808,7 +2808,7 @@ void PC88::draw_text() uint8_t buffer[120 * 200]; memset(buffer, 0, sizeof(buffer)); - for(int i = 0; i < dmac.ch[3].count.sd + 1; i++) { + for(int i = 0; i < dmac.ch[3].count.sd + 1 && i < 120 * 200; i++) { buffer[i] = this->read_dma_data8(dmac.ch[3].addr.w.l + i); } diff --git a/source/src/vm/pc8801/pc88.h b/source/src/vm/pc8801/pc88.h index ed3f3c9a1..c77ec4687 100644 --- a/source/src/vm/pc8801/pc88.h +++ b/source/src/vm/pc8801/pc88.h @@ -112,9 +112,9 @@ typedef struct { void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void start(int c); + void __FASTCALL start(int c); void __FASTCALL run(int c, int nbytes); - void finish(int c); + void __FASTCALL finish(int c); } pc88_dmac_t; class PC88 : public DEVICE @@ -305,7 +305,7 @@ class PC88 : public DEVICE bool intr_req_opn2; #endif uint8_t intr_mask1, intr_mask2; - void request_intr(int level, bool status); + void __FASTCALL request_intr(int level, bool status); void update_intr(); // data recorder @@ -340,7 +340,7 @@ class PC88 : public DEVICE bool nippy_patch; #endif public: - PC88(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PC88(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { #ifdef SUPPORT_PC88_OPN1 d_opn1 = NULL; @@ -391,7 +391,7 @@ class PC88 : public DEVICE void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_frame(); void event_vline(int v, int clock); uint32_t get_intr_ack(); diff --git a/source/src/vm/pc8801/pc8801.cpp b/source/src/vm/pc8801/pc8801.cpp index e446eef8f..f02cb535b 100644 --- a/source/src/vm/pc8801/pc8801.cpp +++ b/source/src/vm/pc8801/pc8801.cpp @@ -62,7 +62,7 @@ using PC88DEV::PC88; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // check configs #if defined(PC8001_VARIANT) @@ -89,27 +89,15 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) dummy = new DEVICE(this, emu); // must be 1st device pc88event = new EVENT(this, emu); -// pc88event->set_device_name(_T("Event Manager (PC-8801)")); -// pc88event->set_frames_per_sec(60); -// pc88event->set_lines_per_frame(260); pc88 = new PC88(this, emu); -// pc88->set_context_event_manager(pc88event); pc88sio = new I8251(this, emu); -// pc88sio->set_device_name(_T("8251 SIO (PC-8801)")); -// pc88sio->set_context_event_manager(pc88event); pc88pio = new I8255(this, emu); -// pc88pio->set_device_name(_T("8255 PIO (PC-8801)")); -// pc88pio->set_context_event_manager(pc88event); pc88pcm = new PCM1BIT(this, emu); #ifdef USE_DEBUGGER // pc88pcm->set_context_debugger(new DEBUGGER(this, emu)); #endif -// pc88pcm->set_device_name(_T("1-Bit PCM Sound (PC-8801)")); -// pc88pcm->set_context_event_manager(pc88event); pc88rtc = new UPD1990A(this, emu); -// pc88rtc->set_device_name(_T("uPD1990A RTC (PC-8801)")); -// pc88rtc->set_context_event_manager(pc88event); #if defined(_PC8801MA) // config.sound_type // 0: 44h:OPNA A4h:None PC-8801FH/MH or later @@ -119,10 +107,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // 4: 44h:OPNA A4h:OPNA PC-8801FH/MH or later + PC-8801-24 // 5: 44h:OPNA A4h:OPN PC-8801FH/MH or later + PC-8801-11 pc88opn1 = new YM2203(this, emu); -#ifdef USE_DEBUGGER - pc88opn1->set_context_debugger(new DEBUGGER(this, emu)); -#endif -// pc88opn1->set_context_event_manager(pc88event); if(config.sound_type == 0 || config.sound_type == 4 || config.sound_type == 5) { pc88opn1->is_ym2608 = true; pc88opn1->set_device_name(_T("YM2608 OPNA #1")); @@ -132,10 +116,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) } if(config.sound_type >= 2) { pc88opn2 = new YM2203(this, emu); -// pc88opn2->set_context_event_manager(pc88event); - #ifdef USE_DEBUGGER - pc88opn2->set_context_debugger(new DEBUGGER(this, emu)); - #endif if(config.sound_type == 2 || config.sound_type == 4) { pc88opn2->is_ym2608 = true; pc88opn2->set_device_name(_T("YM2608 OPNA #2")); @@ -151,20 +131,13 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // 0: 44h:OPN A4h:None PC-8001mkIISR // 1: 44h:OPN A4h:OPN PC-8001mkIISR + PC-8801-11 pc88opn1 = new YM2203(this, emu); -// pc88opn1->set_context_event_manager(pc88event); pc88opn1->is_ym2608 = false; pc88opn1->set_device_name(_T("YM2203 OPN #1")); -#ifdef USE_DEBUGGER - pc88opn1->set_context_debugger(new DEBUGGER(this, emu)); -#endif if(config.sound_type == 1) { pc88opn2 = new YM2203(this, emu); // pc88opn2->set_context_event_manager(pc88event); pc88opn2->is_ym2608 = false; pc88opn2->set_device_name(_T("YM2203 OPN #2")); - #ifdef USE_DEBUGGER - pc88opn2->set_context_debugger(new DEBUGGER(this, emu)); - #endif } else { pc88opn2 = NULL; } @@ -173,19 +146,14 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // 1: 44h:None A4h:OPN PC-8001mkII + PC-8801-11 if(config.sound_type == 1) { pc88opn2 = new YM2203(this, emu); -// pc88opn2->set_context_event_manager(pc88event); pc88opn2->is_ym2608 = false; pc88opn2->set_device_name(_T("YM2203 OPN #2")); - #ifdef USE_DEBUGGER - pc88opn2->set_context_debugger(new DEBUGGER(this, emu)); - #endif } else { pc88opn2 = NULL; } #else #if defined(SUPPORT_PC88_OPN1) pc88opn1 = new YM2203(this, emu); -// pc88opn1->set_context_event_manager(pc88event); #if defined(SUPPORT_PC88_OPNA) pc88opn1->is_ym2608 = true; pc88opn1->set_device_name(_T("YM2608 OPNA #1")); @@ -193,13 +161,9 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pc88opn1->is_ym2608 = false; pc88opn1->set_device_name(_T("YM2203 OPN #1")); #endif - #ifdef USE_DEBUGGER - pc88opn1->set_context_debugger(new DEBUGGER(this, emu)); - #endif #endif #if defined(SUPPORT_PC88_OPN2) pc88opn2 = new YM2203(this, emu); -// pc88opn2->set_context_event_manager(pc88event); #if defined(SUPPORT_PC88_OPNA) pc88opn2->is_ym2608 = true; pc88opn2->set_device_name(_T("YM2608 OPNA #2")); @@ -207,9 +171,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pc88opn2->is_ym2608 = false; pc88opn2->set_device_name(_T("YM2203 OPN #2")); #endif - #ifdef USE_DEBUGGER - pc88opn2->set_context_debugger(new DEBUGGER(this, emu)); - #endif #endif #endif #ifdef USE_DEBUGGER @@ -226,43 +187,30 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #endif if(config.printer_type == 0) { pc88prn = new PRNFILE(this, emu); -// pc88prn->set_context_event_manager(pc88event); // } else if(config.printer_type == 1) { // pc88prn = new PCPR201(this, emu); -// pc88prn->set_context_event_manager(pc88event); } else { pc88prn = dummy; } pc88cpu = new Z80(this, emu); -// pc88cpu->set_context_event_manager(pc88event); pc88sub = new PC80S31K(this, emu); pc88sub->set_device_name(_T("PC-80S31K (Sub)")); -// pc88sub->set_context_event_manager(pc88event); pc88pio_sub = new I8255(this, emu); pc88pio_sub->set_device_name(_T("8255 PIO (Sub)")); -// pc88pio_sub->set_context_event_manager(pc88event); pc88fdc_sub = new UPD765A(this, emu); pc88fdc_sub->set_device_name(_T("uPD765A FDC (Sub)")); #ifdef USE_DEBUGGER // pc88fdc_sub->set_context_debugger(new DEBUGGER(this, emu)); #endif -// pc88fdc_sub->set_context_event_manager(pc88event); pc88noise_seek = new NOISE(this, emu); -// pc88noise_seek->set_context_event_manager(pc88event); pc88noise_head_down = new NOISE(this, emu); -// pc88noise_head_down->set_context_event_manager(pc88event); pc88noise_head_up = new NOISE(this, emu); -// pc88noise_head_up->set_context_event_manager(pc88event); pc88cpu_sub = new Z80(this, emu); pc88cpu_sub->set_device_name(_T("Z80 CPU (Sub)")); -// pc88cpu_sub->set_context_event_manager(pc88event); - #ifdef SUPPORT_PC88_CDROM pc88scsi_host = new SCSI_HOST(this, emu); -// pc88scsi_host->set_context_event_manager(pc88event); pc88scsi_cdrom = new SCSI_CDROM(this, emu); -// pc88scsi_cdrom->set_context_event_manager(pc88event); #endif #ifdef SUPPORT_PC88_HMB20 @@ -272,7 +220,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pc88opm->set_context_debugger(new DEBUGGER(this, emu)); #endif pc88opm->set_device_name(_T("YM2151 OPM (HMB-20)")); -// pc88opm->set_context_event_manager(pc88event); } else { pc88opm = NULL; } @@ -285,16 +232,12 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // pc88gsx_pit->set_context_event_manager(pc88event); pc88gsx_psg1 = new AY_3_891X(this, emu); pc88gsx_psg1->set_device_name(_T("AY-3-8910 PSG #1 (GSX-8800)")); -// pc88gsx_psg1->set_context_event_manager(pc88event); pc88gsx_psg2 = new AY_3_891X(this, emu); pc88gsx_psg2->set_device_name(_T("AY-3-8910 PSG #2 (GSX-8800)")); -// pc88gsx_psg2->set_context_event_manager(pc88event); pc88gsx_psg3 = new AY_3_891X(this, emu); pc88gsx_psg3->set_device_name(_T("AY-3-8910 PSG #3 (GSX-8800)")); -// pc88gsx_psg3->set_context_event_manager(pc88event); pc88gsx_psg4 = new AY_3_891X(this, emu); pc88gsx_psg4->set_device_name(_T("AY-3-8910 PSG #4 (GSX-8800)")); -// pc88gsx_psg4->set_context_event_manager(pc88event); #ifdef USE_DEBUGGER pc88gsx_psg1->set_context_debugger(new DEBUGGER(this, emu)); pc88gsx_psg2->set_context_debugger(new DEBUGGER(this, emu)); @@ -311,16 +254,12 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) if(config.dipswitch & DIPSWITCH_PCG8100) { pc88pcg_pit = new I8253(this, emu); pc88pcg_pit->set_device_name(_T("8253 PIT (PCG-8100)")); -// pc88pcg_pit->set_context_event_manager(pc88event); pc88pcg_pcm1 = new PCM1BIT(this, emu); pc88pcg_pcm1->set_device_name(_T("1-Bit PCM Sound (PCG-8100 #1)")); -// pc88pcg_pcm1->set_context_event_manager(pc88event); pc88pcg_pcm2 = new PCM1BIT(this, emu); pc88pcg_pcm2->set_device_name(_T("1-Bit PCM Sound (PCG-8100 #2)")); -// pc88pcg_pcm2->set_context_event_manager(pc88event); pc88pcg_pcm3 = new PCM1BIT(this, emu); pc88pcg_pcm3->set_device_name(_T("1-Bit PCM Sound (PCG-8100 #3)")); -// pc88pcg_pcm3->set_context_event_manager(pc88event); } else { pc88pcg_pit = NULL; pc88pcg_pcm1 = pc88pcg_pcm2 = pc88pcg_pcm3 = NULL; @@ -483,6 +422,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // initialize all devices for(DEVICE* device = first_device; device; device = device->next_device) { +// printf("DEV NAME=%s ID=%d\n", device->this_device_name, device->this_device_id); device->initialize(); } } @@ -863,6 +803,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(pc88event == NULL) return 0.0; + return pc88event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(pc88event == NULL) return (uint64_t)0; + return pc88event->get_current_clock_uint64(); +} + #define STATE_VERSION 11 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -875,7 +827,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { return false; } diff --git a/source/src/vm/pc8801/pc8801.h b/source/src/vm/pc8801/pc8801.h index 35c203dac..e4120cfbd 100644 --- a/source/src/vm/pc8801/pc8801.h +++ b/source/src/vm/pc8801/pc8801.h @@ -360,7 +360,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -413,6 +413,9 @@ class VM : public VM_TEMPLATE #endif bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc9801/CMakeLists.txt b/source/src/vm/pc9801/CMakeLists.txt index e542f16e6..cccb6f224 100644 --- a/source/src/vm/pc9801/CMakeLists.txt +++ b/source/src/vm/pc9801/CMakeLists.txt @@ -1,43 +1,110 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pc9801") +message("* vm/${EXE_NAME}") -set(BASIC_VM_FILES - pc9801.cpp - dipsw.cpp - display.cpp - floppy.cpp - fmsound.cpp - joystick.cpp - mouse.cpp - keyboard.cpp - dmareg.cpp - membus.cpp - ) - -if(BUILD_PC9801) - add_library(vm_pc9801 ${BASIC_VM_FILES} cmt.cpp ) -elseif(BUILD_PC9801E) - add_library(vm_pc9801 ${BASIC_VM_FILES} cmt.cpp ) -elseif(BUILD_PC9801U) - add_library(vm_pc9801 ${BASIC_VM_FILES} cmt.cpp ) -elseif(BUILD_PC9801VF) - add_library(vm_pc9801 ${BASIC_VM_FILES} ) -elseif(BUILD_PC9801VM) - add_library(vm_pc9801 ${BASIC_VM_FILES} ) -# add_library(vm_pc9801 ${BASIC_VM_FILES}) -elseif(BUILD_PC98DO) - add_library(vm_pc9801 ${BASIC_VM_FILES}) -elseif(BUILD_PC9801VX) - add_library(vm_pc9801 ${BASIC_VM_FILES} cpureg.cpp sasi.cpp sasi_bios.cpp egc.cpp) -elseif(BUILD_PC98XL) - add_library(vm_pc9801 ${BASIC_VM_FILES} cpureg.cpp sasi.cpp sasi_bios.cpp egc.cpp) -elseif(BUILD_PC9801RA) - add_library(vm_pc9801 ${BASIC_VM_FILES} cpureg.cpp sasi.cpp sasi_bios.cpp egc.cpp) -elseif(BUILD_PC98RL) - add_library(vm_pc9801 ${BASIC_VM_FILES} cpureg.cpp sasi.cpp sasi_bios.cpp egc.cpp) -elseif(BUILD_PC98XA) - add_library(vm_pc9801 ${BASIC_VM_FILES} cpureg.cpp sasi.cpp sasi_bios.cpp) -elseif(BUILD_PC98DOP) - add_library(vm_pc9801 ${BASIC_VM_FILES} sasi.cpp sasi_bios.cpp egc.cpp) +set(BASIC_VM_FILES + ../i8237.cpp + + dipsw.cpp + display.cpp + floppy.cpp + fmsound.cpp + joystick.cpp + mouse.cpp + keyboard.cpp + dmareg.cpp + membus.cpp + + pc9801.cpp +) + +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +if("${U_EXE_NAME}" STREQUAL "EMUPC9801") + add_library(vm_${EXE_NAME} + ${BASIC_VM_FILES} + cmt.cpp + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC9801E") + add_library(vm_${EXE_NAME} + ${BASIC_VM_FILES} + cmt.cpp + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC9801U") + add_library(vm_${EXE_NAME} + ${BASIC_VM_FILES} + cmt.cpp + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC9801VF") + add_library(vm_${EXE_NAME} + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC9801VM") + add_library(vm_${EXE_NAME} + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC98DO") + add_library(vm_${EXE_NAME} + ../pc8801/pc88.cpp + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC9801VX") + add_library(vm_${EXE_NAME} + ../scsi_host.cpp + + cpureg.cpp + sasi.cpp + sasi_bios.cpp + egc.cpp + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC98XL") + add_library(vm_${EXE_NAME} + ../scsi_host.cpp + + cpureg.cpp + sasi.cpp + sasi_bios.cpp + egc.cpp + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC9801RA") + add_library(vm_${EXE_NAME} + ../scsi_host.cpp + + cpureg.cpp + sasi.cpp + sasi_bios.cpp + egc.cpp + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC98RL") + add_library(vm_${EXE_NAME} + ../scsi_host.cpp + + cpureg.cpp + sasi.cpp + sasi_bios.cpp + egc.cpp + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC98XA") + add_library(vm_${EXE_NAME} + ../scsi_host.cpp + + cpureg.cpp + sasi.cpp + sasi_bios.cpp + ${BASIC_VM_FILES} + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUPC98DOPLUS") + add_library(vm_${EXE_NAME} + ../scsi_host.cpp + + ../pc8801/pc88.cpp + cpureg.cpp + sasi.cpp + sasi_bios.cpp + ${BASIC_VM_FILES} + ) endif() diff --git a/source/src/vm/pc9801/cmt.h b/source/src/vm/pc9801/cmt.h index 636367578..dc9fb3723 100644 --- a/source/src/vm/pc9801/cmt.h +++ b/source/src/vm/pc9801/cmt.h @@ -38,7 +38,7 @@ class CMT : public DEVICE void release_tape(); public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } diff --git a/source/src/vm/pc9801/cpureg.cpp b/source/src/vm/pc9801/cpureg.cpp index 49e70c270..3739aa747 100644 --- a/source/src/vm/pc9801/cpureg.cpp +++ b/source/src/vm/pc9801/cpureg.cpp @@ -14,122 +14,49 @@ #include "cpureg.h" #include "membus.h" #include "../i8255.h" - +#if defined(SUPPORT_32BIT_ADDRESS) || defined(UPPER_I386) +#include "../i386_np21.h" +//#include "../i386.h" +#else +//#include "../i286_np21.h" +#include "../i286.h" +#endif +#if !defined(SUPPORT_HIRESO) +#include "../i86.h" +#include "../i8255.h" +#endif #define EVENT_WAIT 1 namespace PC9801 { -#if defined(HAS_V30_SUB_CPU) void CPUREG::initialize() { - use_v30 = false; - if((config.dipswitch & (1 << DIPSWITCH_POSITION_CPU_MODE)) != 0) { - enable_v30 = true; - } else { - enable_v30 = false; - } -} - -void CPUREG::halt_by_use_v30() -{ - if((use_v30)) { - d_cpu->write_signal(SIG_CPU_HALTREQ, 1, 1); - d_v30cpu->write_signal(SIG_CPU_HALTREQ, 0, 1); - d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); - d_v30cpu->write_signal(SIG_CPU_BUSREQ, 0, 1); - } else { - d_cpu->write_signal(SIG_CPU_HALTREQ, 0, 1); - d_v30cpu->write_signal(SIG_CPU_HALTREQ, 1, 1); - d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1); - d_v30cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); - } -} + reg_0f0 = 0x00; + event_wait = -1; +#if !defined(SUPPORT_HIRESO) + reg_0f0 = reg_0f0 | ((cpu_mode) ? 1 : 0); #endif - -void CPUREG::halt_by_value(bool val) -{ - bool haltvalue = (val) ? 0xffffffff : 0x0000000; -#if defined(HAS_V30_SUB_CPU) - if((use_v30)) { - d_cpu->write_signal(SIG_CPU_HALTREQ, 0xffffffff, 0xffffffff); - d_cpu->write_signal(SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff); - d_v30cpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff); - d_v30cpu->write_signal(SIG_CPU_BUSREQ, haltvalue, 0xffffffff); - } else { - d_cpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff); - d_cpu->write_signal(SIG_CPU_BUSREQ, haltvalue, 0xffffffff); - d_v30cpu->write_signal(SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff); - d_v30cpu->write_signal(SIG_CPU_HALTREQ, 0xffffffff, 0xffffffff); - } -#else - d_cpu->write_signal(SIG_CPU_BUSREQ, haltvalue, 0xffffffff); -#endif } void CPUREG::reset() { d_cpu->set_address_mask(0x000fffff); - init_clock = get_current_clock_uint64() & 0x000000ffffffffff; nmi_enabled = false; - stat_wait = false; - stat_exthalt = false; - reg_0f0 = 0; - if(event_wait >= 0) { - cancel_event(this, event_wait); - event_wait = -1; - } - -#if defined(HAS_V30_SUB_CPU) -// use_v30 = ((config.cpu_type & 0x02) != 0) ? true : false; - use_v30 = false; - halt_by_use_v30(); - write_signals(&outputs_cputype, 0x00); -#else - d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1); -#endif -} - -void CPUREG::set_intr_line(bool line, bool pending, uint32_t bit) -{ -#if defined(HAS_V30_SUB_CPU) - if((use_v30) && (enable_v30) && (d_v30cpu != NULL)) { - d_v30cpu->set_intr_line(line, pending, bit); - return; + init_clock = get_current_clock_uint64() & 0x000000ffffffffff; +#if !defined(SUPPORT_HIRESO) + reg_0f0 = reg_0f0 & 0xfe; + reg_0f0 = reg_0f0 | ((cpu_mode) ? 1 : 0); + d_pio->write_signal(SIG_I8255_PORT_B, ((reg_0f0 & 1) != 0) ? 2 : 0, 2); + if(d_v30 != NULL) { + d_v30->write_signal(SIG_CPU_BUSREQ, ~reg_0f0, 1); } + d_cpu->write_signal(SIG_CPU_BUSREQ, reg_0f0, 1); #endif - d_cpu->set_intr_line(line, pending, bit); } -void CPUREG::write_signal(int ch, uint32_t data, uint32_t mask) -{ - if(ch == SIG_CPU_NMI) { - out_debug_log("NMI\n"); - //if(nmi_enabled) { - write_signals(&outputs_nmi, data); - //} - } else if(ch == SIG_CPUREG_RESET) { - out_debug_log("RESET FROM CPU!!!\n"); - d_cpu->set_address_mask(0x000fffff); -#if defined(HAS_V30_SUB_CPU) - halt_by_use_v30(); - write_signals(&outputs_cputype, (use_v30) ? 0xffffffff : 0x00000000); -#endif - } else if(ch == SIG_CPUREG_HALT) { - stat_exthalt = ((data & mask) != 0); - halt_by_value(stat_exthalt); - } else if(ch == SIG_CPUREG_USE_V30) { -#if defined(HAS_V30_SUB_CPU) - use_v30 = ((data & mask) != 0); - //halt_by_use_v30(); - out_debug_log(_T("SIG_CPUREG_USE_V30: V30=%s\n"), (use_v30) ? _T("YES") : _T("NO")); -#endif - } -} - void CPUREG::write_io8(uint32_t addr, uint32_t data) { - //out_debug_log(_T("I/O WRITE: %04x %04x\n"), addr, data); switch(addr) { case 0x0050: nmi_enabled = false; @@ -140,10 +67,11 @@ void CPUREG::write_io8(uint32_t addr, uint32_t data) case 0x005f: // ToDo: Both Pseudo BIOS. d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); -#if defined(HAS_V30_SUB_CPU) - d_v30cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); +#if !defined(SUPPORT_HIRESO) + if(d_v30 != NULL) { + d_v30->write_signal(SIG_CPU_BUSREQ, 1, 1); + } #endif - stat_wait = true; if(event_wait >= 0) { cancel_event(this, event_wait); event_wait = -1; @@ -151,18 +79,20 @@ void CPUREG::write_io8(uint32_t addr, uint32_t data) register_event(this, EVENT_WAIT, 0.6, false, &event_wait); break; case 0x00f0: - { - // ToDo: Reflesh - reg_0f0 = data; - d_cpu->set_address_mask(0x000fffff); -#if defined(HAS_V30_SUB_CPU) -// use_v30 = ((config.cpu_type & 0x02) != 0) ? true : false; - use_v30 = (((data & 1) != 0) || ((data & 2) != 0) || ((data & 4) != 0)); - d_v30cpu->reset(); -#endif - d_cpu->reset(); - out_debug_log(_T("WRITE I/O 00F0h: VAL=%02X\n"), data); + out_debug_log(_T("00F0h=%02X"), data); + reg_0f0 = data; + d_cpu->write_signal(SIG_CPU_BUSREQ, reg_0f0, 1); +#if !defined(SUPPORT_HIRESO) + if(d_v30 != NULL) { + d_v30->reset(); + d_v30->write_signal(SIG_CPU_BUSREQ, ~reg_0f0, 1); } + d_pio->write_signal(SIG_I8255_PORT_B, ((reg_0f0 & 1) != 0) ? 2 : 0, 2); +// d_pio->write_signal(SIG_I8255_PORT_B, reg_0f0, 2); +#endif + write_signals(&outputs_cputype, ((reg_0f0 & 1) != 0) ? 0xffffffff : 0x00000000); + d_cpu->reset(); + d_cpu->set_address_mask(0x000fffff); break; case 0x00f2: #if defined(SUPPORT_32BIT_ADDRESS) @@ -171,23 +101,15 @@ void CPUREG::write_io8(uint32_t addr, uint32_t data) d_cpu->set_address_mask(0x00ffffff); #endif break; -#if defined(UPPER_I386) +#if defined(SUPPORT_32BIT_ADDRESS) case 0x00f6: switch(data) { case 0x02: -#if defined(SUPPORT_32BIT_ADDRESS) - d_cpu->set_address_mask(0xffffffff); -#else d_cpu->set_address_mask(0x00ffffff); -#endif break; case 0x03: d_cpu->set_address_mask(0x000fffff); break; - // ToDo: Software DIPSWITCH. - case 0xa0: - case 0xe0: - break; } break; #endif @@ -197,7 +119,6 @@ void CPUREG::write_io8(uint32_t addr, uint32_t data) uint32_t CPUREG::read_io8(uint32_t addr) { uint32_t value; - //out_debug_log(_T("I/O READ: %04x \n"), addr); switch(addr) { case 0x005c: @@ -240,22 +161,19 @@ uint32_t CPUREG::read_io8(uint32_t addr) break; case 0x00f0: value = 0x00; -#if defined(_PC9821_VARIANTS) || defined(_PC9801NA) +//#if defined(_PC9821_VARIANTS) || defined(_PC9801NA) // value |= 0x80; // 1 = PC-9801NA, 0 = PC-9801NA/C // value |= 0x80; // 1 = PC-9821modelS1, 0 = PC-9821modelS2 // value |= 0x80; // 1 = PC-9821CemodelS1, 0 = PC-9821CemodelS2 // value |= 0x80; // 1 = PC-9821Xt, 0 = PC-9821Xa // value |= 0x80; // CPU MODE, 1 = High/Low, 0 = Middle (PC-9821Ap/As/Ae/Af) // value |= 0x40; // ODP, 1 = Existing (PC-9821Ts) -#else - value |= 0x80; +//#else +#if defined(SUPPORT_SCSI_IF) +// value |= 0x40; // Internal 55-type SCSI-HDD, 0 = Existing #endif -#if defined(_PC9801RA) || defined(_PC9801RS) || defined(_PC9821_VARIANTS) - #if !defined(SUPPORT_SCSI_IF) - value |= 0x40; // Internal 55-type SCSI-HDD, 0 = Existing - #endif -#else - value |= 0x40; +#if defined(SUPPORT_SASI_IF) +// value |= 0x20; // Internal 27-type SASI-HDD, 0 = Existing #endif #if defined(_PC9801RA) || defined(_PC9801RS) || defined(_PC9821_VARIANTS) || \ defined(_PC98NOTE_VARIANTS) || defined(_PC98DOPLUS) @@ -264,15 +182,18 @@ uint32_t CPUREG::read_io8(uint32_t addr) #endif #else value |= 0x20; -#endif +#endif // ToDo: AMD98 - value |= 0x10; // Unknown - value |= 0x08; -// value |= ((d_mem->read_signal(SIG_LAST_ACCESS_INTERAM) != 0) ? 0x00: 0x08); // RAM access, 1 = Internal-standard/External-enhanced RAM, 0 = Internal-enhanced RAM - value |= 0x04; // Refresh mode, 1 = Standard, 0 = High speed -#if defined(HAS_V30_SUB_CPU) - // ToDo: Older VMs. - value |= (((reg_0f0 & 0x01) == 0) ? 0x00 : 0x02); // CPU mode, 1 = V30, 0 = 80286/80386 +// value |= 0x10; // Unknown + value |= 0x08; // RAM access, 1 = Internal-standard/External-enhanced RAM, 0 = Internal-enhanced RAM +// value |= 0x04; // Refresh mode, 1 = Standard, 0 = High speed +#if defined(HAS_I86) || defined(HAS_V30) + value |= 0x02; // CPU mode, 1 = V30, 0 = 80286/80386 +#endif +#if !defined(SUPPORT_HIRESO) + if(cpu_mode) { + value |= 0x02; // CPU mode, 1 = V30, 0 = 80286/80386 + } #endif value |= 0x01; // RAM access, 1 = Internal RAM, 0 = External-enhanced RAM return value; @@ -282,60 +203,90 @@ uint32_t CPUREG::read_io8(uint32_t addr) case 0x00f4: // ToDo: DMA SPEED (after 9801DA) return 0xff; break; -#if defined(UPPER_I386) +#if defined(SUPPORT_32BIT_ADDRESS) case 0x00f6: - value = ((d_cpu->get_address_mask() & (1 << 20)) != 0) ? 0x00 : 0x01; + value = 0x00; #if defined(SUPPORT_HIRESO) && !defined(_PC98RL) value |= 0x10; // SASI-HDD, 1 = DMA ch0, 0 = DMA ch1 #endif - value |= 0xec; if(nmi_enabled) { value |= 0x02; // NMI, 1 = Enabled } - return value; + return ((d_cpu->get_address_mask() & (1 << 20)) ? 0x00 : 0x01) | value; #endif } return 0xff; } - void CPUREG::event_callback(int id, int err) { if(id == EVENT_WAIT) { +#if !defined(SUPPORT_HIRESO) // ToDo: Both Pseudo BIOS. - if(!(stat_exthalt)) { - -#if defined(HAS_V30_SUB_CPU) - halt_by_use_v30(); -#else - d_cpu->write_signal(SIG_CPU_BUSREQ, 0, 1); -#endif + uint32_t haltvalue = 0; + uint32_t haltvalue_v30 = 1; + if(cpu_mode) { + haltvalue = 1; + haltvalue_v30 = 0; + } + if(d_v30 != NULL) { + d_v30->write_signal(SIG_CPU_BUSREQ, haltvalue_v30, 1); } - stat_wait = false; + d_cpu->write_signal(SIG_CPU_BUSREQ, haltvalue, 1); event_wait = -1; +#endif + } +} + +#if !defined(SUPPORT_HIRESO) +void CPUREG::set_intr_line(bool line, bool pending, uint32_t bit) +{ + if(d_v30 != NULL) { + if(((reg_0f0 & 1) != 0)){ + d_v30->set_intr_line(line, pending, bit); + } else { + d_cpu->set_intr_line(line, pending, bit); + } + } else { +// if(cpu_mode == 0) { + d_cpu->set_intr_line(line, pending, bit); +// } } } - + +void CPUREG::write_signal(int ch, uint32_t data, uint32_t mask) +{ + if(ch == SIG_CPU_NMI) { + out_debug_log("NMI\n"); + //if(nmi_enabled) { + write_signals(&outputs_nmi, data); + //} + } else if(ch == SIG_CPUREG_RESET) { + // This don't need at PC9801? +// out_debug_log("RESET FROM CPU!!!\n"); + } +} + +#endif + #define STATE_VERSION 3 bool CPUREG::process_state(FILEIO* state_fio, bool loading) { if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } + return false; + } if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } + return false; + } + state_fio->StateValue(reg_0f0); +#if !defined(SUPPORT_HIRESO) + state_fio->StateValue(cpu_mode); +#endif state_fio->StateValue(nmi_enabled); state_fio->StateValue(init_clock); - state_fio->StateValue(stat_wait); - state_fio->StateValue(stat_exthalt); - state_fio->StateValue(reg_0f0); state_fio->StateValue(event_wait); -#if defined(HAS_V30_SUB_CPU) - state_fio->StateValue(use_v30); -#endif - return true; + return true; } } diff --git a/source/src/vm/pc9801/cpureg.h b/source/src/vm/pc9801/cpureg.h index 8f771a07d..ff45fadd3 100644 --- a/source/src/vm/pc9801/cpureg.h +++ b/source/src/vm/pc9801/cpureg.h @@ -20,20 +20,14 @@ #define SIG_CPUREG_RESET 1 #define SIG_CPUREG_HALT 2 -#define SIG_CPUREG_USE_V30 3 - -#if defined(UPPER_I386) -#include "../i386.h" -#elif defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) -#include "../i86.h" -#elif defined(HAS_V30) -#include "../v30.h" +#if defined(SUPPORT_32BIT_ADDRESS) +class I386; #else -#include "../i286.h" +class I286; #endif -#if defined(HAS_V30_SUB_CPU) -#include "../v30.h" +#if !defined(SUPPORT_HIRESO) +class I86; #endif namespace PC9801 { @@ -41,40 +35,25 @@ namespace PC9801 { class CPUREG : public DEVICE { private: -#if defined(UPPER_I386) + outputs_t outputs_nmi; + outputs_t outputs_cputype; + uint8_t reg_0f0; + +#if defined(SUPPORT_32BIT_ADDRESS) || defined(UPPER_I386) I386 *d_cpu; -#elif defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) - I8086 *d_cpu; -#elif defined(HAS_V30) - V30 *d_cpu; #else - I80286 *d_cpu; + I286 *d_cpu; #endif -#if defined(HAS_V30_SUB_CPU) - V30 *d_v30cpu; +#if !defined(SUPPORT_HIRESO) + I86 *d_v30; + DEVICE *d_pio; #endif - DEVICE* d_mem; - DEVICE* d_pio; - uint8_t reg_0f0; bool nmi_enabled; - int event_wait; - bool stat_wait; - bool stat_exthalt; uint64_t init_clock; - - outputs_t outputs_nmi; // NMI must route via CPUREG:: - outputs_t outputs_cputype; // CPU Type 0 = Normal/ 1 = V30(SUB) -#if defined(HAS_V30_SUB_CPU) - bool use_v30; - bool enable_v30; - void halt_by_use_v30(); -#endif - void halt_by_value(bool val); - + int event_wait; public: - CPUREG(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CPUREG(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { - event_wait = -1; initialize_output_signals(&outputs_nmi); initialize_output_signals(&outputs_cputype); set_device_name(_T("CPU I/O")); @@ -82,52 +61,37 @@ class CPUREG : public DEVICE ~CPUREG() {} // common functions -#if defined(HAS_V30_SUB_CPU) + void reset(); void initialize(); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_io8(uint32_t addr); +#if !defined(SUPPORT_HIRESO) + void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit); #endif - void reset(); - void __FASTCALL write_io8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_io8(uint32_t addr); - // NOTE: NMI must route CPUREG::, should not connect directly.20190502 K.O - void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); - void event_callback(int id, int err); + void __FASTCALL event_callback(int id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique function - void set_intr_line(bool line, bool pending, uint32_t bit); -#if defined(UPPER_I386) +#if defined(SUPPORT_32BIT_ADDRESS) || defined(UPPER_I386) void set_context_cpu(I386* device) -#elif defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) - void set_context_cpu(I8086* device) -#elif defined(HAS_V30) - void set_context_cpu(V30* device) #else - void set_context_cpu(I80286* device) + void set_context_cpu(I286* device) #endif { d_cpu = device; - register_output_signal(&outputs_nmi, device, SIG_CPU_NMI, 0xffffffff, 0); - } - // This will be feature developing, still not implement V30 feature.20190502 K.O -#if defined(HAS_V30_SUB_CPU) - void set_context_v30(V30* device) - { - d_v30cpu = device; - register_output_signal(&outputs_nmi, device, SIG_CPU_NMI, 0xffffffff, 0); } -#endif - void set_context_membus(DEVICE* device) +#if !defined(SUPPORT_HIRESO) + void set_context_v30(I86* device) { - d_mem = device; + d_v30 = device; } - void set_context_piosys(DEVICE* device) + void set_context_pio(DEVICE* device) { d_pio = device; } - void set_context_cputype(DEVICE* device, int id, uint32_t mask, int shift) - { - register_output_signal(&outputs_cputype, device, id, mask, shift); - } + bool cpu_mode; +#endif }; diff --git a/source/src/vm/pc9801/dipsw.cpp b/source/src/vm/pc9801/dipsw.cpp index c802fa536..841dad5d5 100644 --- a/source/src/vm/pc9801/dipsw.cpp +++ b/source/src/vm/pc9801/dipsw.cpp @@ -26,6 +26,7 @@ namespace PC9801 { void DIPSWITCH::initialize() { update_dipswitch(); + update_ports(); } void DIPSWITCH::reset() @@ -40,14 +41,7 @@ void DIPSWITCH::reset() #else port_c3 |= 0x08; // MODSW, 1 = Normal Mode, 0 = Hirezo Mode #endif -#if defined(USE_CPU_TYPE) - #if defined(HAS_V30_SUB_CPU) - if(config.cpu_type & 0x02) {// V30 or V33 - port_c3 |= 0x04; - } - #endif -#endif - pio_mouse->write_signal(SIG_I8255_PORT_C, port_c3, 0x0c); + pio_mouse->write_signal(SIG_I8255_PORT_C, port_c3, 0x08); } @@ -56,16 +50,19 @@ void DIPSWITCH::update_dipswitch() sw1 = 0; sw2 = 0; sw3 = 0; -#if 1 /* HARDWARE DIP SWITCH */ + /* HARDWARE DIP SWITCH */ sw1 |= (((config.dipswitch & (0xff << 8)) >> 8) & 0xff); -#if 1 sw1 &= 0xfe; +#if defined(SUPPORT_HIRESO) sw1 |= ((config.monitor_type == 0) ? 0x01 : 0x00); -#endif + sw3 |= ((config.monitor_type == 0) ? 0x08 : 0x00); +#else + sw1 |= 0x01; + sw3 |= 0x08; +#endif sw2 |= (((config.dipswitch & (0xff << 16)) >> 16) & 0xff); sw2 = (sw2 & 0x0d) | ((~sw2) & 0xf2); - sw3 |= (((config.dipswitch & (0xff << 24)) >> 24) & 0x7f); -#endif + sw3 |= (((config.dipswitch & (0xff << 24)) >> 24) & 0xf7); } void DIPSWITCH::update_ports() @@ -174,14 +171,8 @@ void DIPSWITCH::update_ports() port_c |= (((sw1 & (1 << 5)) != 0) ? 0x02 : 0x00); // SW 1-6 port_c |= (((sw1 & (1 << 4)) != 0) ? 0x01 : 0x00); // SW 1-5 #endif - pio_mouse->write_signal(SIG_I8255_PORT_B, port_c, (0x08 | 0x02 | 0x01)); - #if defined(HAS_V30_SUB_CPU) && defined(USE_CPU_TYPE) - if(config.cpu_type & 0x02) {// V30 or V33 - pio_mouse->write_signal(SIG_I8255_PORT_C, 0x04, 0x04); - } else { - pio_mouse->write_signal(SIG_I8255_PORT_C, 0x00, 0x04); - } - #endif + port_c |= (((sw3 & (1 << 7)) != 0) ? 0x04 : 0x00); // SW 3-8 + pio_mouse->write_signal(SIG_I8255_PORT_B, port_c, (0x08 | 0x04 | 0x02 | 0x01)); #endif } } diff --git a/source/src/vm/pc9801/dipsw.h b/source/src/vm/pc9801/dipsw.h index 551b2a9c0..368cc4538 100644 --- a/source/src/vm/pc9801/dipsw.h +++ b/source/src/vm/pc9801/dipsw.h @@ -39,7 +39,7 @@ class DIPSWITCH : public DEVICE void update_dipswitch(); void update_ports(); public: - DIPSWITCH(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DIPSWITCH(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { sw1 = 0; sw2 = 0; diff --git a/source/src/vm/pc9801/display.cpp b/source/src/vm/pc9801/display.cpp index 972a593fb..0600fda0f 100644 --- a/source/src/vm/pc9801/display.cpp +++ b/source/src/vm/pc9801/display.cpp @@ -19,54 +19,75 @@ #include "display.h" #include "../i8259.h" -#include "../i8255.h" #include "../upd7220.h" -#include "../../config.h" -#if defined(SUPPORT_EGC) -#include "./egc_inline.h" + +#if !defined(SUPPORT_HIRESO) + #define TVRAM_ADDRESS 0xa0000 + #define VRAM_PLANE_SIZE 0x08000 + #define VRAM_PLANE_ADDR_MASK 0x07fff + #define VRAM_PLANE_ADDR_0 0x08000 + #define VRAM_PLANE_ADDR_1 0x10000 + #define VRAM_PLANE_ADDR_2 0x18000 + #define VRAM_PLANE_ADDR_3 0x00000 +#else + #define TVRAM_ADDRESS 0xe0000 + #define VRAM_PLANE_SIZE 0x20000 + #define VRAM_PLANE_ADDR_MASK 0x1ffff + #define VRAM_PLANE_ADDR_0 0x00000 + #define VRAM_PLANE_ADDR_1 0x20000 + #define VRAM_PLANE_ADDR_2 0x40000 + #define VRAM_PLANE_ADDR_3 0x60000 #endif -namespace PC9801 { +#define SCROLL_PL 0 +#define SCROLL_BL 1 +#define SCROLL_CL 2 +#define SCROLL_SSL 3 +#define SCROLL_SUR 4 +#define SCROLL_SDR 5 + +#define MODE1_ATRSEL 0 +#define MODE1_GRAPHIC 1 +#define MODE1_COLUMN 2 +#define MODE1_FONTSEL 3 +#define MODE1_200LINE 4 +#define MODE1_KAC 5 +#define MODE1_MEMSW 6 +#define MODE1_DISP 7 +#define MODE2_16COLOR 0x00 +#define MODE2_EGC 0x02 +#define MDOE2_TXTSHIFT 0x20 + +#define GRCG_PLANE_0 0x01 +#define GRCG_PLANE_1 0x02 +#define GRCG_PLANE_2 0x04 +#define GRCG_PLANE_3 0x08 +#define GRCG_RW_MODE 0x40 +#define GRCG_CG_MODE 0x80 + +#define ATTR_ST 0x01 +#define ATTR_BL 0x02 +#define ATTR_RV 0x04 +#define ATTR_UL 0x08 +#define ATTR_VL 0x10 +#define ATTR_COL 0xe0 + +namespace PC9801 { static const uint8_t memsw_default[] = { 0xe1, 0x48, 0xe1, 0x05, 0xe1, 0x04, 0xe1, 0x00, 0xe1, 0x01, 0xe1, 0x00, 0xe1, 0x00, 0xe1, 0x00, }; -void DISPLAY::save_memsw() -{ - FILEIO *fio = new FILEIO(); - if(fio == NULL) return; - if(fio->Fopen(create_local_path(_T("MEMSW.BIN")), FILEIO_WRITE_BINARY)) { - if(fio->IsOpened()) { - for(int i = 0; i < 16; i++) { - fio->FputUint8(tvram[0x3fe0 + (i << 1)]); - } - fio->Fclose(); - } - } - delete fio; -} - -void DISPLAY::init_memsw() -{ - for(int i = 0; i < 16; i++) { - tvram[0x3fe0 + (i << 1)] = memsw_default[i]; -// tvram[0x3fe0 + (i << 1)] = 0x00; - } -} - void DISPLAY::initialize() { // load font data - memset(font, 0xff, sizeof(font)); +// memset(font, 0xff, sizeof(font)); + memset(font, 0x00, sizeof(font)); FILEIO* fio = new FILEIO(); - b_gfx_ff = false; // Q: Is latched beyond resetting? -#if defined(SUPPORT_EGC) - is_use_egc = true; -#endif + #if !defined(SUPPORT_HIRESO) uint8_t *p = font + 0x81000; uint8_t *q = font + 0x83000; @@ -79,10 +100,16 @@ void DISPLAY::initialize() if(i & (0x10 << j)) { bit |= 0x0f0f0f0f; } - *(uint32_t *)p = bit; - p += 4; - *(uint16_t *)q = (uint16_t)bit; - q += 2; +// *(uint32_t *)p = bit; +// p += 4; + *p++ = (bit >> 0); + *p++ = (bit >> 8); + *p++ = (bit >> 16); + *p++ = (bit >> 24); +// *(uint16_t *)q = (uint16_t)bit; +// q += 2; + *q++ = (bit >> 0); + *q++ = (bit >> 8); } q += 8; } @@ -153,6 +180,34 @@ void DISPLAY::initialize() } } #endif + for(int code = 0x20; code <= 0x7f; code++) { + for(int line = 0; line < 24; line++) { +// uint16_t pattern = (*(uint16_t *)(&font[ANK_FONT_OFS + FONT_SIZE * code + line * 2])) & 0x3fff; +// *(uint16_t *)(&font[FONT_SIZE * (0x09 | (code << 8)) + line * 2 ]) = pattern << 2; +// *(uint16_t *)(&font[FONT_SIZE * (0x09 | (code << 8)) + line * 2 + KANJI_2ND_OFS]) = 0; + uint16_t pattern; + pattern = (font[ANK_FONT_OFS + FONT_SIZE * code + line * 2 + 0] ); + pattern |= (font[ANK_FONT_OFS + FONT_SIZE * code + line * 2 + 1] & 0x3f) << 8; + font[FONT_SIZE * (0x09 | (code << 8)) + line * 2 + 0] = pattern << 2; + font[FONT_SIZE * (0x09 | (code << 8)) + line * 2 + 1] = pattern >> 6; + font[FONT_SIZE * (0x09 | (code << 8)) + line * 2 + KANJI_2ND_OFS + 0] = 0; + font[FONT_SIZE * (0x09 | (code << 8)) + line * 2 + KANJI_2ND_OFS + 1] = 0; + } + } + for(int code = 0xa0; code <= 0xff; code++) { + for(int line = 0; line < 24; line++) { +// uint16_t pattern = (*(uint16_t *)(&font[ANK_FONT_OFS + FONT_SIZE * code + line * 2])) & 0x3fff; +// *(uint16_t *)(&font[FONT_SIZE * (0x0a | (code << 8)) + line * 2 ]) = pattern << 2; +// *(uint16_t *)(&font[FONT_SIZE * (0x0a | (code << 8)) + line * 2 + KANJI_2ND_OFS]) = 0; + uint16_t pattern; + pattern = (font[ANK_FONT_OFS + FONT_SIZE * code + line * 2 + 0] ); + pattern |= (font[ANK_FONT_OFS + FONT_SIZE * code + line * 2 + 1] & 0x3f) << 8; + font[FONT_SIZE * (0x0a | (code << 8)) + line * 2 + 0] = pattern << 2; + font[FONT_SIZE * (0x0a | (code << 8)) + line * 2 + 1] = pattern >> 6; + font[FONT_SIZE * (0x0a | (code << 8)) + line * 2 + KANJI_2ND_OFS + 0] = 0; + font[FONT_SIZE * (0x0a | (code << 8)) + line * 2 + KANJI_2ND_OFS + 1] = 0; + } + } memcpy(font + ANK_FONT_OFS + FONT_SIZE * 0x100, font + ANK_FONT_OFS, FONT_SIZE * 0x100); memcpy(font + ANK_FONT_OFS + FONT_SIZE * 0x200, font + ANK_FONT_OFS, FONT_SIZE * 0x100); memcpy(font + ANK_FONT_OFS + FONT_SIZE * 0x300, font + ANK_FONT_OFS, FONT_SIZE * 0x100); @@ -175,8 +230,7 @@ void DISPLAY::initialize() // memset(tvram, 0, sizeof(tvram)); memset(vram, 0, sizeof(vram)); - vram_draw = vram + 0x00000; -// WIP: MEMSW + bool memsw_stat = false; if((config.dipswitch & (1 << DIPSWITCH_POSITION_NOINIT_MEMSW)) != 0) { if(fio->Fopen(create_local_path(_T("MEMSW.BIN")), FILEIO_READ_BINARY)) { @@ -192,8 +246,6 @@ void DISPLAY::initialize() if(!memsw_stat) { init_memsw(); } - delete fio; - #ifndef HAS_UPD4990A cur_time_t cur_time; get_host_time(&cur_time); @@ -203,15 +255,44 @@ void DISPLAY::initialize() // set vram pointer to gdc d_gdc_chr->set_vram_ptr(tvram, 0x2000); d_gdc_chr->set_screen_width(80); - d_gdc_chr->set_screen_height(25); +#if !defined(SUPPORT_HIRESO) + #if !defined(SUPPORT_2ND_VRAM) d_gdc_gfx->set_vram_bus_ptr(this, 0x20000); + #else + d_gdc_gfx->set_vram_bus_ptr(this, 0x40000); + #endif +#else + d_gdc_gfx->set_vram_bus_ptr(this, 0x80000); +#endif d_gdc_gfx->set_screen_width(SCREEN_WIDTH >> 3); - d_gdc_gfx->set_screen_height(SCREEN_HEIGHT); // ToDo: 200 lines mode. // register event register_frame_event(this); } +void DISPLAY::save_memsw() +{ + FILEIO *fio = new FILEIO(); + if(fio == NULL) return; + if(fio->Fopen(create_local_path(_T("MEMSW.BIN")), FILEIO_WRITE_BINARY)) { + if(fio->IsOpened()) { + for(int i = 0; i < 16; i++) { + fio->FputUint8(tvram[0x3fe0 + (i << 1)]); + } + fio->Fclose(); + } + } + delete fio; +} + +void DISPLAY::init_memsw() +{ + for(int i = 0; i < 16; i++) { + tvram[0x3fe0 + (i << 1)] = memsw_default[i]; +// tvram[0x3fe0 + (i << 1)] = 0x00; + } +} + void DISPLAY::release() { if((config.dipswitch & (1 << DIPSWITCH_POSITION_NOINIT_MEMSW)) == 0) { @@ -290,10 +371,9 @@ void DISPLAY::reset() memset(modereg1, 0, sizeof(modereg1)); #if defined(SUPPORT_16_COLORS) memset(modereg2, 0, sizeof(modereg2)); - enable_egc = false; if((config.dipswitch & (1 << DIPSWITCH_POSITION_GDC_FAST)) != 0) { -// modereg2[0x82 >> 1] = 1; -// modereg2[0x84 >> 1] = 1; + modereg2[0x82 >> 1] = 1; + modereg2[0x84 >> 1] = 1; d_gdc_chr->set_clock_freq(5000 * 1000); d_gdc_gfx->set_clock_freq(5000 * 1000); // write_signals(&output_gdc_freq, 0xff); @@ -301,7 +381,7 @@ void DISPLAY::reset() d_gdc_chr->set_clock_freq(2500 * 1000); d_gdc_gfx->set_clock_freq(2500 * 1000); // write_signals(&output_gdc_freq, 0x00); - } + } #endif #if defined(SUPPORT_GRCG) grcg_mode = grcg_tile_ptr = 0; @@ -313,13 +393,7 @@ void DISPLAY::reset() #endif #if defined(SUPPORT_EGC) is_use_egc = ((config.dipswitch & (1 << DIPSWITCH_POSITION_EGC)) != 0); - - #if defined(SUPPORT_EGC) enable_egc = false; - //if(modereg2[MODE2_EGC_WP] != 0) { - //enable_egc = ((is_use_egc) && (modereg2[MODE2_EGC] != 0)) ? true : false; - // } - #endif egc_access = 0xfff0; egc_fgbg = 0x00ff; egc_ope = 0; @@ -353,6 +427,7 @@ void DISPLAY::reset() save_memsw(); font_code = 0; font_line = 0; +// font_lr = 0; for(int i = 0x00; i < 0x08; i++) { bank_table[i] = 0x80000000; // Disable } @@ -373,7 +448,6 @@ void DISPLAY::reset() bank_table[0x0e] = 0x80000000; // ToDo: Hi Reso #endif bank_table[0x0f] = 0x80000000; // ToDo: Hi Reso -// font_lr = 0; } void DISPLAY::event_frame() @@ -421,7 +495,6 @@ void DISPLAY::write_signal(int ch, uint32_t data, uint32_t mask) break; } } - void DISPLAY::write_io8(uint32_t addr, uint32_t data) { uint8_t m_bak; @@ -453,9 +526,11 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) modereg1[(data >> 1) & 7] = data & 1; break; } + modereg1[(data >> 1) & 7] = data & 1; break; #if defined(SUPPORT_16_COLORS) case 0x006a: +// modereg2[(data >> 1) & 127] = data & 1; #if !defined(PC9821_VARIANTS) if((data & 0xf0) != 0) { // From MAME 0.208. Disable pages . m_bak = 0; @@ -499,15 +574,20 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) } break; #endif +#if !defined(SUPPORT_HIRESO) case 0x006c: border = (data >> 3) & 7; border_color = RGB_COLOR((border & 2) ? 0xff : 0, (border & 4) ? 0xff : 0, (border & 1) ? 0xff : 0); +// border = (data >> 3) & 7; break; case 0x006e: #if defined(_PC9801) border = (data >> 3) & 7; border_color = RGB_COLOR((border & 2) ? 0xff : 0, (border & 4) ? 0xff : 0, (border & 1) ? 0xff : 0); #else +// border = (data >> 3) & 7; +#endif +#if !defined(_PC9801) if(data & 1) { d_gdc_chr->set_horiz_freq(24830); d_gdc_gfx->set_horiz_freq(24830); @@ -517,6 +597,7 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) } #endif break; +#endif case 0x0070: case 0x0072: case 0x0074: @@ -525,7 +606,6 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) case 0x007a: scroll[(addr >> 1) & 7] = data; break; - // ToDo: Modify value by DIPSW. #if defined(SUPPORT_GRCG) #if !defined(SUPPORT_HIRESO) case 0x007c: @@ -539,14 +619,12 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) grcg_plane_enabled[i] = ((grcg_mode & (1 << i)) == 0) ? true : false; } grcg_tile_ptr = 0; - //out_debug_log("GRCG MODEREG=%02x CG_MODE=%s RW_MODE=%s PLANE=%s%s%s%s\n", data, (grcg_cg_mode) ? "Yes" : "No", (grcg_rw_mode) ? "Yes" : "No", (grcg_plane_enabled[0]) ? "B" : " ", (grcg_plane_enabled[1]) ? "R" : " ", (grcg_plane_enabled[2]) ? "G" : " ", (grcg_plane_enabled[3]) ? "W" : " "); break; #if !defined(SUPPORT_HIRESO) case 0x007e: #else case 0x00a6: #endif - //out_debug_log("SET TILE #%d to %02X\n", grcg_tile_ptr, data); grcg_tile[grcg_tile_ptr] = data; grcg_tile_word[grcg_tile_ptr] = ((uint16_t)grcg_tile[grcg_tile_ptr]) | ((uint16_t)grcg_tile[grcg_tile_ptr] << 8); grcg_tile_ptr = (grcg_tile_ptr + 1) & 3; @@ -571,7 +649,6 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) #endif } vram_disp_sel = data; - //out_debug_log("SET DISPLAY PAGE=%d\n", (data & 1)); break; case 0x00a6: if(data & 1) { @@ -580,11 +657,10 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) vram_draw = vram + 0x00000; } vram_draw_sel = data; - //out_debug_log("SET DRAW PAGE=%d\n", (data & 1)); break; #endif // palette - case 0xa8: + case 0x00a8: #if defined(SUPPORT_16_COLORS) if(modereg2[MODE2_16COLOR]) { anapal_sel = data & 0x0f; @@ -595,9 +671,8 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) palette_gfx8[7] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); data >>= 4; palette_gfx8[3] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); - //out_debug_log("SET DIGITAL PALETTE #3 %d %d\n", data & 7, (data >> 4) & 7); break; - case 0xaa: + case 0x00aa: #if defined(SUPPORT_16_COLORS) if(modereg2[MODE2_16COLOR]) { anapal[anapal_sel][0] = (data & 0x0f) << 4; @@ -609,9 +684,8 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) palette_gfx8[5] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); data >>= 4; palette_gfx8[1] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); - //out_debug_log("SET DIGITAL PALETTE #1 %d %d\n", data & 7, (data >> 4) & 7); break; - case 0xac: + case 0x00ac: #if defined(SUPPORT_16_COLORS) if(modereg2[MODE2_16COLOR]) { anapal[anapal_sel][1] = (data & 0x0f) << 4; @@ -623,9 +697,8 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) palette_gfx8[6] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); data >>= 4; palette_gfx8[2] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); - //out_debug_log("SET DIGITAL PALETTE #2 %d %d\n", data & 7, (data >> 4) & 7); break; - case 0xae: + case 0x00ae: #if defined(SUPPORT_16_COLORS) if(modereg2[MODE2_16COLOR]) { anapal[anapal_sel][2] = (data & 0x0f) << 4; @@ -637,21 +710,20 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) palette_gfx8[4] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); data >>= 4; palette_gfx8[0] = RGB_COLOR((data & 2) ? 0xff : 0, (data & 4) ? 0xff : 0, (data & 1) ? 0xff : 0); - //out_debug_log("SET DIGITAL PALETTE #0 %d %d\n", data & 7, (data >> 4) & 7); break; // cg window - case 0xa1: + case 0x00a1: font_code = (data << 8) | (font_code & 0xff); break; - case 0xa3: + case 0x00a3: font_code = (font_code & 0xff00) | data; break; - case 0xa5: + case 0x00a5: // font_line = data & 0x1f; // font_lr = ((~data) & 0x20) << 6; font_line = data; break; - case 0xa9: + case 0x00a9: if((font_code & 0x7e) == 0x56) { uint16_t font_lr = ((~font_line) & 0x20) << 6; font[((font_code & 0x7f7f) << 4) + font_lr + (font_line & 0x0f)] = data; @@ -661,56 +733,67 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) // egc case 0x04a0: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_access &= 0xff00; egc_access |= data; } break; case 0x04a1: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_access &= 0x00ff; egc_access |= data << 8; } break; case 0x04a2: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_fgbg &= 0xff00; egc_fgbg |= data; } break; case 0x04a3: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_fgbg &= 0x00ff; egc_fgbg |= data << 8; } break; case 0x04a4: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_ope &= 0xff00; egc_ope |= data; } break; case 0x04a5: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_ope &= 0x00ff; egc_ope |= data << 8; } break; case 0x04a6: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_fg &= 0xff00; egc_fg |= data; - egc_fgc.d[0] = *(uint32_t *)(egc_maskword[data & 0x0f] + 0); - egc_fgc.d[1] = *(uint32_t *)(egc_maskword[data & 0x0f] + 2); +// egc_fgc.d[0] = *(uint32_t *)(&egc_maskword[data & 0x0f][0]); +// egc_fgc.d[1] = *(uint32_t *)(&egc_maskword[data & 0x0f][2]); + egc_fgc.d[0] = egc_maskdword[data & 0x0f][0]; + egc_fgc.d[1] = egc_maskdword[data & 0x0f][1]; } break; case 0x04a7: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_fg &= 0x00ff; egc_fg |= data << 8; } break; case 0x04a8: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { if(!(egc_fgbg & 0x6000)) { egc_mask.b[0] = data; } @@ -718,6 +801,7 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) break; case 0x04a9: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { if(!(egc_fgbg & 0x6000)) { egc_mask.b[1] = data; } @@ -725,20 +809,25 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) break; case 0x04aa: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_bg &= 0xff00; egc_bg |= data; - egc_bgc.d[0] = *(uint32_t *)(egc_maskword[data & 0x0f] + 0); - egc_bgc.d[1] = *(uint32_t *)(egc_maskword[data & 0x0f] + 2); +// egc_bgc.d[0] = *(uint32_t *)(&egc_maskword[data & 0x0f][0]); +// egc_bgc.d[1] = *(uint32_t *)(&egc_maskword[data & 0x0f][2]); + egc_bgc.d[0] = egc_maskdword[data & 0x0f][0]; + egc_bgc.d[1] = egc_maskdword[data & 0x0f][1]; } break; case 0x04ab: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_bg &= 0x00ff; egc_bg |= data << 8; } break; case 0x04ac: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_sft &= 0xff00; egc_sft |= data; egc_shift(); @@ -747,6 +836,7 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) break; case 0x04ad: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_sft &= 0x00ff; egc_sft |= data << 8; egc_shift(); @@ -755,6 +845,7 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) break; case 0x04ae: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_leng &= 0xff00; egc_leng |= data; egc_shift(); @@ -763,8 +854,9 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) break; case 0x04af: if((grcg_cg_mode) && enable_egc) { +// if((grcg_mode & GRCG_CG_MODE) && modereg2[MODE2_EGC]) { egc_leng &= 0x00ff; - egc_leng |= (data & 0x0f) << 8; + egc_leng |= data << 8; egc_shift(); egc_srcmask.w = 0xffff; } @@ -839,80 +931,116 @@ void DISPLAY::write_memory_mapped_io8(uint32_t addr, uint32_t data) if(bank_table[idx] >= 0x80000000) return; addr = bank_table[idx] | (addr & 0x0000ffff); - addr = addr & 0x000fffff; // For 32bit - uint32_t naddr = (addr & 0xf8000) >> 12; - bool is_tvram = false; - switch(naddr) { -#if !defined(SUPPORT_HIRESO) - case 0xa0: // TVRAM_ADDRESS >> 12 - is_tvram = true; - break; - case 0xa8: - case 0xb0: - case 0xb8: - write_dma_io8(addr - 0xa0000, data); - return; - break; - #if defined(SUPPORT_16_COLORS) - case 0xe0: - write_dma_io8(addr - 0xe0000, data); - return; - break; - #endif -#else - case 0xc0: - case 0xc8: - case 0xd0: - case 0xd8: - write_dma_io8(addr - 0xc0000, data); - return; - break; - case 0xe0: - is_tvram = true; - break; -#endif - } - if(is_tvram) { - if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x3fe2)) { + if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x3fe2)) { + tvram[addr - TVRAM_ADDRESS] = data; + } else if((TVRAM_ADDRESS + 0x3fe2) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) { + // memory switch + if(modereg1[MODE1_MEMSW]) { tvram[addr - TVRAM_ADDRESS] = data; - } else if((TVRAM_ADDRESS + 0x3fe2) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) { - // memory switch - if(modereg1[MODE1_MEMSW]) { - tvram[addr - TVRAM_ADDRESS] = data; - } - } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { - if((font_code & 0x7e) == 0x56) { - /* FIXME: need to fix for hireso */ - uint32_t low = 0x7fff0, high; - uint8_t code = font_code & 0x7f; - uint16_t lr = ((~font_line) & 0x20) << 6; - if(!(font_code & 0xff00)) { - high = 0x80000 + (font_code << 4); - if(!modereg1[MODE1_FONTSEL]) { - high += 0x2000; + } + } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { + if((font_code & 0x7e) == 0x56) { +#if !defined(SUPPORT_HIRESO) + uint32_t low = 0x7fff0, high; + uint8_t code = font_code & 0x7f; + uint16_t lr = ((~font_line) & 0x20) << 6; + if(!(font_code & 0xff00)) { + high = 0x80000 + (font_code << 4); + if(!modereg1[MODE1_FONTSEL]) { + high += 0x2000; + } + } else { + high = (font_code & 0x7f7f) << 4; + if(code >= 0x56 && code < 0x58) { + high += lr; + } else if(code >= 0x09 && code < 0x0c) { + if(lr) { + high = low; } + } else if((code >= 0x0c && code < 0x10) || (code >= 0x58 && code < 0x60)) { + high += lr; } else { - high = (font_code & 0x7f7f) << 4; - if(code >= 0x56 && code < 0x58) { - high += lr; - } else if(code >= 0x09 && code < 0x0c) { - if(lr) { - high = low; - } - } else if((code >= 0x0c && code < 0x10) || (code >= 0x58 && code < 0x60)) { - high += lr; - } else { - low = high; - high += 0x800; - } + low = high; + high += 0x800; + } + } + if(addr & 1) { + font[high + ((addr >> 1) & 0x0f)] = data; + } else { + font[low + ((addr >> 1) & 0x0f)] = data; + } +#else + int line = (addr >> 1) & 31, shift = 0; + bool is_kanji = false; + uint32_t offset, pattern; + + if(!(font_code & 0xff00)) { + if((addr & 0x30) == 0x30 || (addr & 0x40)) { + return; + } + offset = ANK_FONT_OFS + FONT_SIZE * (font_code & 0xff) + line * 2; +// pattern = (*(uint16_t *)(&font[offset])) & 0x3fff; + pattern = (font[offset + 0] ); + pattern |= (font[offset + 1] & 0x3f) << 8; + } else { +// if((addr & 0x30) == 0x30 || ((addr & 0x40) && !(addr & 1))) { + if((addr & 0x30) == 0x30) { + return; } - if(addr & 1) { - font[high + ((addr >> 1) & 0x0f)] = data; + uint16_t lo = font_code & 0x7f; + uint16_t hi = (font_code >> 8) & 0x7f; + + offset = FONT_SIZE * (lo | (hi << 8)) + line * 2; +// pattern = (*(uint16_t *)(&font[offset])) & 0x3fff; + pattern = (font[offset + 0] ); + pattern |= (font[offset + 1] & 0x3f) << 8; + + if(lo == 0x56 || lo == 0x57) { + is_kanji = true; } else { - font[low + ((addr >> 1) & 0x0f)] = data; + uint16_t lo = font_code & 0xff; + if(lo < 0x09 || lo >= 0x0c) { + is_kanji = true; + } } + if(is_kanji) { + pattern <<= 14; +// pattern |= (*(uint16_t *)(&font[offset + KANJI_2ND_OFS])) & 0x3fff; + pattern |= (font[offset + KANJI_2ND_OFS + 0] ); + pattern |= (font[offset + KANJI_2ND_OFS + 1] & 0x3f) << 8; + } + shift += 2; + if(addr & 0x40) shift += 16; + } + if(!(addr & 1)) shift += 8; + pattern &= ~(0xff << shift); + pattern |= data << shift; + + if(is_kanji) { +// *(uint16_t *)(&font[offset ]) = (pattern >> 14) & 0x3fff; +// *(uint16_t *)(&font[offset + KANJI_2ND_OFS]) = (pattern >> 0) & 0x3fff; + font[offset + 0] = (pattern >> 14); + font[offset + 1] = (pattern >> 22) & 0x3f; + font[offset + KANJI_2ND_OFS + 0] = (pattern >> 0); + font[offset + KANJI_2ND_OFS + 1] = (pattern >> 8) & 0x3f; + } else { +// *(uint16_t *)(&font[offset]) = pattern & 0x3fff; + font[offset + 0] = (pattern >> 0); + font[offset + 1] = (pattern >> 8) & 0x3f; } +#endif } +#if !defined(SUPPORT_HIRESO) + } else if(0xa8000 <= addr && addr < 0xc0000) { + write_dma_io8(addr - 0xa0000, data); +#if defined(SUPPORT_16_COLORS) + } else if(0xe0000 <= addr && addr < 0xe8000) { + write_dma_io8(addr - 0xe0000, data); +#endif +#else + } else if(0xc0000 <= addr && addr < 0xe0000) { + write_dma_io8(addr - 0xc0000, data); +#endif } } @@ -923,51 +1051,23 @@ void DISPLAY::write_memory_mapped_io16(uint32_t addr, uint32_t data) addr = bank_table[idx] | (addr & 0x0000ffff); addr = addr & 0x000fffff; // For 32bit - uint32_t naddr = (addr & 0xf8000) >> 12; - bool is_tvram = false; - switch(naddr) { +// uint32_t naddr = (addr & 0xf8000) >> 12; +// bool is_tvram = false; + if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { + write_memory_mapped_io8(addr + 0, (data >> 0) & 0xff); + write_memory_mapped_io8(addr + 1, (data >> 8) & 0xff); #if !defined(SUPPORT_HIRESO) - case 0xa0: // TVRAM_ADDRESS >> 12 - is_tvram = true; - break; - case 0xa8: - case 0xb0: - case 0xb8: + } else if(0xa8000 <= addr && addr < 0xc0000) { write_dma_io16(addr - 0xa0000, data); - return; - break; - #if defined(SUPPORT_16_COLORS) - case 0xe0: +#if defined(SUPPORT_16_COLORS) + } else if(0xe0000 <= addr && addr < 0xe8000) { write_dma_io16(addr - 0xe0000, data); - return; - break; - #endif +#endif #else - case 0xc0: - case 0xc8: - case 0xd0: - case 0xd8: + } else if(0xc0000 <= addr && addr < 0xe0000) { write_dma_io16(addr - 0xc0000, data); - return; - break; - case 0xe0: - is_tvram = true; - break; #endif } - if(is_tvram) { - if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x3fe2)) { - *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]) = data; - } else if((TVRAM_ADDRESS + 0x3fe2) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) { - // memory switch - if(modereg1[MODE1_MEMSW]) { - *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]) = data; - } - } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { - write_memory_mapped_io8(addr + 0, (data >> 0) & 0xff); - write_memory_mapped_io8(addr + 1, (data >> 8) & 0xff); - } - } } uint32_t DISPLAY::read_memory_mapped_io8(uint32_t addr) @@ -976,75 +1076,100 @@ uint32_t DISPLAY::read_memory_mapped_io8(uint32_t addr) if(bank_table[idx] >= 0x80000000) return 0xff; addr = bank_table[idx] | (addr & 0x0000ffff); - addr = addr & 0x000fffff; // For 32bit - uint32_t naddr = (addr & 0xf8000) >> 12; - bool is_tvram = false; - switch(naddr) { + if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x2000)) { + return tvram[addr - TVRAM_ADDRESS]; + } else if((TVRAM_ADDRESS + 0x2000) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) { + if(addr & 1) { + return 0xff; + } + return tvram[addr - TVRAM_ADDRESS]; + } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { #if !defined(SUPPORT_HIRESO) - case 0xa0: // TVRAM_ADDRESS >> 12 - is_tvram = true; - break; - case 0xa8: - case 0xb0: - case 0xb8: - return read_dma_io8(addr - 0xa0000); - break; - #if defined(SUPPORT_16_COLORS) - case 0xe0: - return read_dma_io8(addr - 0xe0000); - break; - #endif -#else - case 0xc0: - case 0xc8: - case 0xd0: - case 0xd8: - return read_dma_io8(addr - 0xc0000); - break; - case 0xe0: - is_tvram = true; - break; -#endif - } - if(is_tvram) { - if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x2000)) { - return tvram[addr - TVRAM_ADDRESS]; - } else if((TVRAM_ADDRESS + 0x2000) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) { - if(addr & 1) { - return 0xff; + uint32_t low = 0x7fff0, high; + uint8_t code = font_code & 0x7f; + uint16_t lr = ((~font_line) & 0x20) << 6; + if(!(font_code & 0xff00)) { + high = 0x80000 + (font_code << 4); + if(!modereg1[MODE1_FONTSEL]) { + high += 0x2000; } - return tvram[addr - TVRAM_ADDRESS]; - } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { - /* FIXME: need to fix for hireso */ - uint32_t low = 0x7fff0, high; - uint8_t code = font_code & 0x7f; - uint16_t lr = ((~font_line) & 0x20) << 6; - if(!(font_code & 0xff00)) { - high = 0x80000 + (font_code << 4); - if(!modereg1[MODE1_FONTSEL]) { - high += 0x2000; + } else { + high = (font_code & 0x7f7f) << 4; + if(code >= 0x56 && code < 0x58) { + high += lr; + } else if(code >= 0x09 && code < 0x0c) { + if(lr) { + high = low; } + } else if((code >= 0x0c && code < 0x10) || (code >= 0x58 && code < 0x60)) { + high += lr; } else { - high = (font_code & 0x7f7f) << 4; - if(code >= 0x56 && code < 0x58) { - high += lr; - } else if(code >= 0x09 && code < 0x0c) { - if(lr) { - high = low; - } - } else if((code >= 0x0c && code < 0x10) || (code >= 0x58 && code < 0x60)) { - high += lr; - } else { - low = high; - high += 0x800; - } + low = high; + high += 0x800; } - if(addr & 1) { - return font[high + ((addr >> 1) & 0x0f)]; + } + if(addr & 1) { + return font[high + ((addr >> 1) & 0x0f)]; + } else { + return font[low + ((addr >> 1) & 0x0f)]; + } +#else + int line = (addr >> 1) & 31, shift = 0; + bool is_kanji = false; + uint32_t offset, pattern; + + if(!(font_code & 0xff00)) { + if((addr & 0x30) == 0x30 || (addr & 0x40)) { + return 0; + } + offset = ANK_FONT_OFS + FONT_SIZE * (font_code & 0xff) + line * 2; +// pattern = (*(uint16_t *)(&font[offset])) & 0x3fff; + pattern = (font[offset + 0] ); + pattern |= (font[offset + 1] & 0x3f) << 8; + } else { +// if((addr & 0x30) == 0x30 || ((addr & 0x40) && !(addr & 1))) { + if((addr & 0x30) == 0x30) { + return 0; + } + uint16_t lo = font_code & 0x7f; + uint16_t hi = (font_code >> 8) & 0x7f; + + offset = FONT_SIZE * (lo | (hi << 8)) + line * 2; +// pattern = (*(uint16_t *)(&font[offset])) & 0x3fff; + pattern = (font[offset + 0] ); + pattern |= (font[offset + 1] & 0x3f) << 8; + + if(lo == 0x56 || lo == 0x57) { + is_kanji = true; } else { - return font[low + ((addr >> 1) & 0x0f)]; + uint16_t lo = font_code & 0xff; + if(lo < 0x09 || lo >= 0x0c) { + is_kanji = true; + } + } + if(is_kanji) { + pattern <<= 14; +// pattern |= (*(uint16_t *)(&font[offset + KANJI_2ND_OFS])) & 0x3fff; + pattern |= (font[offset + KANJI_2ND_OFS + 0] ); + pattern |= (font[offset + KANJI_2ND_OFS + 1] & 0x3f) << 8; } + shift += 2; + if(addr & 0x40) shift += 16; } + if(!(addr & 1)) shift += 8; + return (pattern >> shift) & 0xff; +#endif +#if !defined(SUPPORT_HIRESO) + } else if(0xa8000 <= addr && addr < 0xc0000) { + return read_dma_io8(addr - 0xa0000); +#if defined(SUPPORT_16_COLORS) + } else if(0xe0000 <= addr && addr < 0xe8000) { + return read_dma_io8(addr - 0xe0000); +#endif +#else + } else if(0xc0000 <= addr && addr < 0xe0000) { + return read_dma_io8(addr - 0xc0000); +#endif } return 0xff; } @@ -1055,48 +1180,20 @@ uint32_t DISPLAY::read_memory_mapped_io16(uint32_t addr) if(bank_table[idx] >= 0x80000000) return 0xffff; addr = bank_table[idx] | (addr & 0x0000ffff); - addr = addr & 0x000fffff; // For 32bit - uint32_t naddr = (addr & 0xf8000) >> 12; - bool is_tvram = false; - switch(naddr) { + if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { + return read_memory_mapped_io8(addr) | (read_memory_mapped_io8(addr + 1) << 8); #if !defined(SUPPORT_HIRESO) - case 0xa0: // TVRAM_ADDRESS >> 12 - is_tvram = true; - break; - case 0xa8: - case 0xb0: - case 0xb8: + } else if(0xa8000 <= addr && addr < 0xc0000) { return read_dma_io16(addr - 0xa0000); - break; - #if defined(SUPPORT_16_COLORS) - case 0xe0: +#if defined(SUPPORT_16_COLORS) + } else if(0xe0000 <= addr && addr < 0xe8000) { return read_dma_io16(addr - 0xe0000); - break; - #endif +#endif #else - case 0xc0: - case 0xc8: - case 0xd0: - case 0xd8: + } else if(0xc0000 <= addr && addr < 0xe0000) { return read_dma_io16(addr - 0xc0000); - break; - case 0xe0: - is_tvram = true; - break; #endif } - if(is_tvram) { - if(TVRAM_ADDRESS <= addr && addr < (TVRAM_ADDRESS + 0x2000)) { - return *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]); - } else if((TVRAM_ADDRESS + 0x2000) <= addr && addr < (TVRAM_ADDRESS + 0x4000)) { - if(addr & 1) { - return 0xffff; - } - return *(uint16_t *)(&tvram[addr - TVRAM_ADDRESS]); - } else if((TVRAM_ADDRESS + 0x4000) <= addr && addr < (TVRAM_ADDRESS + 0x5000)) { - return read_memory_mapped_io8(addr) | (read_memory_mapped_io8(addr + 1) << 8); - } - } return 0xffff; } @@ -1106,38 +1203,113 @@ void DISPLAY::write_dma_io8(uint32_t addr, uint32_t data) { #if defined(SUPPORT_GRCG) if(grcg_cg_mode) { +// if(grcg_mode & GRCG_CG_MODE) { #if defined(SUPPORT_EGC) if(enable_egc) { +// if(modereg2[MODE2_EGC]) { +// out_debug_log(_T("ADDR = %08X"), addr); egc_writeb(addr, data); } else #endif +// out_debug_log(_T("ADDR = %08X"), addr); grcg_writeb(addr, data); - } else + return; + } #endif +#if !defined(SUPPORT_HIRESO) vram_draw[addr & 0x1ffff] = data; +#else + if(!(grcg_mode & GRCG_PLANE_0)) { + vram_draw[(addr & 0x1ffff) | VRAM_PLANE_ADDR_0] = data; + } + if(!(grcg_mode & GRCG_PLANE_1)) { + vram_draw[(addr & 0x1ffff) | VRAM_PLANE_ADDR_1] = data; + } + if(!(grcg_mode & GRCG_PLANE_2)) { + vram_draw[(addr & 0x1ffff) | VRAM_PLANE_ADDR_2] = data; + } + if(!(grcg_mode & GRCG_PLANE_3)) { + vram_draw[(addr & 0x1ffff) | VRAM_PLANE_ADDR_3] = data; + } +#endif } void DISPLAY::write_dma_io16(uint32_t addr, uint32_t data) { #if defined(SUPPORT_GRCG) if(grcg_cg_mode) { +// if(grcg_mode & GRCG_CG_MODE) { #if defined(SUPPORT_EGC) if(enable_egc) { +// if(modereg2[MODE2_EGC]) { egc_writew(addr, data); } else #endif grcg_writew(addr, data); - } else -#endif - { - if((addr & 0x1ffff) == 0x1ffff) { // OK? - pair16_t d; - d.w = (uint16_t)data; - vram_draw[0x1ffff] = d.b.l; - vram_draw[0x00000] = d.b.h; - } else { - *(uint16_t *)(&vram_draw[addr & 0x1fffe]) = data; + return; + } +#endif + if((addr &= 0x1ffff) == 0x1ffff) { + pair16_t d; + d.w = (uint16_t)data; +#if !defined(SUPPORT_HIRESO) + vram_draw[0x1ffff] = d.b.l; + vram_draw[0x00000] = d.b.h; +#else + if(!(grcg_mode & GRCG_PLANE_0)) { + vram_draw[0x1ffff | VRAM_PLANE_ADDR_0] = d.b.l; + vram_draw[0x00000 | VRAM_PLANE_ADDR_0] = d.b.h; } + if(!(grcg_mode & GRCG_PLANE_1)) { + vram_draw[0x1ffff | VRAM_PLANE_ADDR_1] = d.b.l; + vram_draw[0x00000 | VRAM_PLANE_ADDR_1] = d.b.h; + } + if(!(grcg_mode & GRCG_PLANE_2)) { + vram_draw[0x1ffff | VRAM_PLANE_ADDR_2] = d.b.l; + vram_draw[0x00000 | VRAM_PLANE_ADDR_2] = d.b.h; + } + if(!(grcg_mode & GRCG_PLANE_3)) { + vram_draw[0x1ffff | VRAM_PLANE_ADDR_3] = d.b.l; + vram_draw[0x00000 | VRAM_PLANE_ADDR_3] = d.b.h; + } +#endif + } else { +#if !defined(SUPPORT_HIRESO) + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr, data); + #else + *(uint16_t *)(&vram_draw[addr]) = data; + #endif +#else + if(!(grcg_mode & GRCG_PLANE_0)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_0, data); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]) = data; + #endif + } + if(!(grcg_mode & GRCG_PLANE_1)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_1, data); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]) = data; + #endif + } + if(!(grcg_mode & GRCG_PLANE_2)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_2, data); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]) = data; + #endif + } + if(!(grcg_mode & GRCG_PLANE_3)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_3, data); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]) = data; + #endif + } +#endif } } @@ -1145,78 +1317,93 @@ uint32_t DISPLAY::read_dma_io8(uint32_t addr) { #if defined(SUPPORT_GRCG) if(grcg_cg_mode) { +// if(grcg_mode & GRCG_CG_MODE) { #if defined(SUPPORT_EGC) if(enable_egc) { +// if(modereg2[MODE2_EGC]) { return egc_readb(addr); } #endif return grcg_readb(addr); } #endif +#if !defined(SUPPORT_HIRESO) return vram_draw[addr & 0x1ffff]; +#else + int plane = (grcg_mode >> 4) & 3; + return vram_draw[(addr & 0x1ffff) | (0x20000 * plane)]; +#endif } uint32_t DISPLAY::read_dma_io16(uint32_t addr) { #if defined(SUPPORT_GRCG) if(grcg_cg_mode) { +// if(grcg_mode & GRCG_CG_MODE) { #if defined(SUPPORT_EGC) if(enable_egc) { +// if(modereg2[MODE2_EGC]) { return egc_readw(addr); } #endif return grcg_readw(addr); } #endif - { - if((addr & 0x1ffff) == 0x1ffff) { - pair16_t d; - d.w = 0; - d.b.l = vram_draw[0x1ffff]; - d.b.h = vram_draw[0x00000]; - return (uint32_t)(d.w); - } - return *(uint16_t *)(&vram_draw[addr & 0x1fffe]); + if((addr &= 0x1ffff) == 0x1ffff) { + pair16_t d; + d.w = 0; +#if !defined(SUPPORT_HIRESO) + d.b.l = vram_draw[0x1ffff]; + d.b.h = vram_draw[0x00000]; +#else + int plane = (grcg_mode >> 4) & 3; + d.b.l = vram_draw[0x1ffff | (0x20000 * plane)]; + d.b.h = vram_draw[0x00000 | (0x20000 * plane)]; +#endif + return (uint32_t)(d.w); + } else { +#if !defined(SUPPORT_HIRESO) + #ifdef __BIG_ENDIAN__ + return vram_draw_readw(addr); + #else + return *(uint16_t *)(&vram_draw[addr]); + #endif +#else + int plane = (grcg_mode >> 4) & 3; + #ifdef __BIG_ENDIAN__ + return vram_draw_readw(addr | (0x20000 * plane)); + #else + return *(uint16_t *)(&vram_draw[addr | (0x20000 * plane)]); + #endif +#endif } } +#ifdef __BIG_ENDIAN__ +inline void DISPLAY::vram_draw_writew(uint32_t addr, uint32_t data) +{ + vram_draw[addr ] = (data ) & 0xff; + vram_draw[addr + 1] = (data >> 8) & 0xff; +} + +inline uint32_t DISPLAY::vram_draw_readw(uint32_t addr) +{ + uint32_t val; + val = vram_draw[addr ]; + val |= vram_draw[addr + 1] << 8; + return val; +} +#endif + // GRCG #if defined(SUPPORT_GRCG) -void __FASTCALL DISPLAY::grcg_writeb(uint32_t addr1, uint32_t data) +void DISPLAY::grcg_writeb(uint32_t addr1, uint32_t data) { uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK; - if(grcg_rw_mode) { + if(grcg_mode & GRCG_RW_MODE) { // RMW -#if 1 - const uint32_t plane_offset[4] = {addr | VRAM_PLANE_ADDR_0, addr | VRAM_PLANE_ADDR_1, addr | VRAM_PLANE_ADDR_2, addr | VRAM_PLANE_ADDR_3}; - __DECL_ALIGNED(4) uint8_t plane_data[4] = {0}; - __DECL_ALIGNED(4) uint8_t mask_data[4]; - __DECL_ALIGNED(4) uint8_t bit_data[4]; - uint8_t* p = vram_draw; - for(int i = 0; i < 4; i++) { - plane_data[i] = p[plane_offset[i]]; - } - - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - mask_data[i] = (grcg_plane_enabled[i]) ? ~data : 0xff; - bit_data[i] = (grcg_plane_enabled[i]) ? grcg_tile[i] & data : 0x00; - } - - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - plane_data[i] = plane_data[i] & mask_data[i]; - plane_data[i] = plane_data[i] | bit_data[i]; - } - for(int i = 0; i < 4; i++) { - if(grcg_plane_enabled[i]) { - p[plane_offset[i]] = plane_data[i]; - } - } -#else - if(!(grcg_mode & GRCG_PLANE_0)) { vram_draw[addr | VRAM_PLANE_ADDR_0] &= ~data; vram_draw[addr | VRAM_PLANE_ADDR_0] |= grcg_tile[0] & data; @@ -1233,19 +1420,8 @@ void __FASTCALL DISPLAY::grcg_writeb(uint32_t addr1, uint32_t data) vram_draw[addr | VRAM_PLANE_ADDR_3] &= ~data; vram_draw[addr | VRAM_PLANE_ADDR_3] |= grcg_tile[3] & data; } -#endif } else { // TDW - const uint32_t plane_offset[4] = {addr | VRAM_PLANE_ADDR_0, addr | VRAM_PLANE_ADDR_1, addr | VRAM_PLANE_ADDR_2, addr | VRAM_PLANE_ADDR_3}; -#if 1 - uint8_t* p = vram_draw; - for(int i = 0; i < 4; i++) { - if(grcg_plane_enabled[i]) { - p[plane_offset[i]] = grcg_tile[i]; - } - } -#else - if(!(grcg_mode & GRCG_PLANE_0)) { vram_draw[addr | VRAM_PLANE_ADDR_0] = grcg_tile[0]; } @@ -1258,62 +1434,104 @@ void __FASTCALL DISPLAY::grcg_writeb(uint32_t addr1, uint32_t data) if(!(grcg_mode & GRCG_PLANE_3)) { vram_draw[addr | VRAM_PLANE_ADDR_3] = grcg_tile[3]; } -#endif } } -void __FASTCALL DISPLAY::grcg_writew(uint32_t addr1, uint32_t data) +void DISPLAY::grcg_writew(uint32_t addr1, uint32_t data) { - - if((addr1 & 1) != 0) { + if(addr1 & 1) { grcg_writeb(addr1 + 0, (data >> 0) & 0xff); grcg_writeb(addr1 + 1, (data >> 8) & 0xff); } else { uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK; - if(grcg_rw_mode) { + + if(grcg_mode & GRCG_RW_MODE) { // RMW - const uint32_t plane_offset[4] = {(addr | VRAM_PLANE_ADDR_0) / 2, (addr | VRAM_PLANE_ADDR_1) / 2, (addr | VRAM_PLANE_ADDR_2) / 2, (addr | VRAM_PLANE_ADDR_3) / 2}; - __DECL_ALIGNED(8) uint16_t plane_data[4] = {0}; - __DECL_ALIGNED(8) uint16_t mask_data[4]; - __DECL_ALIGNED(8) uint16_t bit_data[4]; - uint16_t* p = (uint16_t*)vram_draw; - for(int i = 0; i < 4; i++) { - plane_data[i] = p[plane_offset[i]]; + if(!(grcg_mode & GRCG_PLANE_0)) { + #ifdef __BIG_ENDIAN__ + uint16_t p = vram_draw_readw(addr | VRAM_PLANE_ADDR_0); + p &= ~data; + p |= grcg_tile_word[0] & data; + vram_draw_writew(addr | VRAM_PLANE_ADDR_0, p); + #else + uint16_t *p = (uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); + *p &= ~data; + *p |= grcg_tile_word[0] & data; + #endif } - - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - mask_data[i] = (grcg_plane_enabled[i]) ? ~data : 0xffff; - bit_data[i] = (grcg_plane_enabled[i]) ? grcg_tile_word[i] & data : 0x0000; + if(!(grcg_mode & GRCG_PLANE_1)) { + #ifdef __BIG_ENDIAN__ + uint16_t p = vram_draw_readw(addr | VRAM_PLANE_ADDR_1); + p &= ~data; + p |= grcg_tile_word[1] & data; + vram_draw_writew(addr | VRAM_PLANE_ADDR_1, p); + #else + uint16_t *p = (uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); + *p &= ~data; + *p |= grcg_tile_word[1] & data; + #endif } - - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - plane_data[i] = plane_data[i] & mask_data[i]; - plane_data[i] = plane_data[i] | bit_data[i]; + if(!(grcg_mode & GRCG_PLANE_2)) { + #ifdef __BIG_ENDIAN__ + uint16_t p = vram_draw_readw(addr | VRAM_PLANE_ADDR_2); + p &= ~data; + p |= grcg_tile_word[2] & data; + vram_draw_writew(addr | VRAM_PLANE_ADDR_2, p); + #else + uint16_t *p = (uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); + *p &= ~data; + *p |= grcg_tile_word[2] & data; + #endif } - for(int i = 0; i < 4; i++) { - if(grcg_plane_enabled[i]) { - p[plane_offset[i]] = plane_data[i]; - } + if(!(grcg_mode & GRCG_PLANE_3)) { + #ifdef __BIG_ENDIAN__ + uint16_t p = vram_draw_readw(addr | VRAM_PLANE_ADDR_3); + p &= ~data; + p |= grcg_tile_word[3] & data; + vram_draw_writew(addr | VRAM_PLANE_ADDR_3, p); + #else + uint16_t *p = (uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + *p &= ~data; + *p |= grcg_tile_word[3] & data; + #endif } } else { // TDW - const uint32_t plane_offset[4] = {(addr | VRAM_PLANE_ADDR_0) / 2, (addr | VRAM_PLANE_ADDR_1) / 2, (addr | VRAM_PLANE_ADDR_2) / 2, (addr | VRAM_PLANE_ADDR_3) / 2}; - uint16_t* p = (uint16_t*)vram_draw; - for(int i = 0; i < 4; i++) { - if(grcg_plane_enabled[i]) { - p[plane_offset[i]] = grcg_tile_word[i]; - } + if(!(grcg_mode & GRCG_PLANE_0)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_0, grcg_tile_word[0]); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]) = grcg_tile_word[0]; + #endif + } + if(!(grcg_mode & GRCG_PLANE_1)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_1, grcg_tile_word[1]); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]) = grcg_tile_word[1]; + #endif + } + if(!(grcg_mode & GRCG_PLANE_2)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_2, grcg_tile_word[2]); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]) = grcg_tile_word[2]; + #endif + } + if(!(grcg_mode & GRCG_PLANE_3)) { + #ifdef __BIG_ENDIAN__ + vram_draw_writew(addr | VRAM_PLANE_ADDR_3, grcg_tile_word[3]); + #else + *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]) = grcg_tile_word[3]; + #endif } } - } } -uint32_t __FASTCALL DISPLAY::grcg_readb(uint32_t addr1) +uint32_t DISPLAY::grcg_readb(uint32_t addr1) { - if(grcg_rw_mode) { + if(grcg_mode & GRCG_RW_MODE) { // VRAM #if !defined(SUPPORT_HIRESO) return vram_draw[addr1 & 0x1ffff]; @@ -1324,28 +1542,8 @@ uint32_t __FASTCALL DISPLAY::grcg_readb(uint32_t addr1) } else { // TCR uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK; - const uint32_t plane_offset[4] = {addr | VRAM_PLANE_ADDR_0, addr | VRAM_PLANE_ADDR_1, addr | VRAM_PLANE_ADDR_2, addr | VRAM_PLANE_ADDR_3}; uint8_t data = 0; - __DECL_ALIGNED(4) uint8_t dsum[4]; - uint8_t* p = vram_draw; - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - dsum[i] = (grcg_plane_enabled[i]) ? p[plane_offset[i]] : 0; - //if(grcg_plane_enabled[i]) { - // dsum[i] = p[plane_offset[i]]; - //} - } - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - dsum[i] ^= grcg_tile[i]; - } - - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - data |= (grcg_plane_enabled[i]) ? dsum[i] : 0; - //data |= dsum[i]; - } - /* + if(!(grcg_mode & GRCG_PLANE_0)) { data |= vram_draw[addr | VRAM_PLANE_ADDR_0] ^ grcg_tile[0]; } @@ -1358,50 +1556,63 @@ uint32_t __FASTCALL DISPLAY::grcg_readb(uint32_t addr1) if(!(grcg_mode & GRCG_PLANE_3)) { data |= vram_draw[addr | VRAM_PLANE_ADDR_3] ^ grcg_tile[3]; } - */ return data ^ 0xff; } } -uint32_t __FASTCALL DISPLAY::grcg_readw(uint32_t addr1) +uint32_t DISPLAY::grcg_readw(uint32_t addr1) { - if((addr1 & 1) != 0) { + if(addr1 & 1) { return grcg_readb(addr1) | (grcg_readb(addr1 + 1) << 8); } else { - if(grcg_rw_mode) { - // VRAM - uint16_t* p = (uint16_t*)(&(vram[addr1 & 0x1ffff])); + if(grcg_mode & GRCG_RW_MODE) { + // VRAM #if !defined(SUPPORT_HIRESO) - return *p; + #ifdef __BIG_ENDIAN__ + return vram_draw_readw(addr1 & 0x1ffff); + #else + return *(uint16_t *)(&vram_draw[addr1 & 0x1ffff]); + #endif #else int plane = (grcg_mode >> 4) & 3; - return p[(0x10000 * plane)]; + #ifdef __BIG_ENDIAN__ + return vram_draw_readw((addr1 & 0x1ffff) | (0x20000 * plane)); + #else + return *(uint16_t *)(&vram_draw[(addr1 & 0x1ffff) | (0x20000 * plane)]); + #endif #endif } else { // TCR uint32_t addr = addr1 & VRAM_PLANE_ADDR_MASK; - const uint32_t plane_offset[4] = {(addr | VRAM_PLANE_ADDR_0) / 2, (addr | VRAM_PLANE_ADDR_1) / 2, (addr | VRAM_PLANE_ADDR_2) / 2, (addr | VRAM_PLANE_ADDR_3) / 2}; uint16_t data = 0; - __DECL_ALIGNED(8) uint16_t dsum[4] /*= {0}*/; - uint16_t* p = (uint16_t*)vram_draw; - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - dsum[i] = (grcg_plane_enabled[i]) ? p[plane_offset[i]] : 0; - // if(grcg_plane_enabled[i]) { - // dsum[i] = p[plane_offset[i]]; - //} + + if(!(grcg_mode & GRCG_PLANE_0)) { + #ifdef __BIG_ENDIAN__ + data |= vram_draw_readw(addr | VRAM_PLANE_ADDR_0) ^ grcg_tile_word[0]; + #else + data |= *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]) ^ grcg_tile_word[0]; + #endif } - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - dsum[i] ^= grcg_tile_word[i]; + if(!(grcg_mode & GRCG_PLANE_1)) { + #ifdef __BIG_ENDIAN__ + data |= vram_draw_readw(addr | VRAM_PLANE_ADDR_1) ^ grcg_tile_word[1]; + #else + data |= *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]) ^ grcg_tile_word[1]; + #endif } - - __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - data |= (grcg_plane_enabled[i]) ? dsum[i] : 0; - //if(grcg_plane_enabled[i]) { - // data |= dsum[i]; - //} + if(!(grcg_mode & GRCG_PLANE_2)) { + #ifdef __BIG_ENDIAN__ + data |= vram_draw_readw(addr | VRAM_PLANE_ADDR_2) ^ grcg_tile_word[2]; + #else + data |= *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]) ^ grcg_tile_word[2]; + #endif + } + if(!(grcg_mode & GRCG_PLANE_3)) { + #ifdef __BIG_ENDIAN__ + data |= vram_draw_readw(addr | VRAM_PLANE_ADDR_3) ^ grcg_tile_word[3]; + #else + data |= *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]) ^ grcg_tile_word[3]; + #endif } return data ^ 0xffff; } @@ -1409,10 +1620,11 @@ uint32_t __FASTCALL DISPLAY::grcg_readw(uint32_t addr1) } #endif +// EGC based on Neko Project 2 and QEMU/9821 +// -> moved to egc.cpp and egc_inline.h . void DISPLAY::draw_screen() { - // render screen bool gdc_chr_start = d_gdc_chr->get_start(); bool gdc_gfx_start = d_gdc_gfx->get_start(); int _height = d_gdc_chr->read_signal(SIG_UPD7220_DISP_HEIGHT) << 4; @@ -1493,7 +1705,6 @@ void DISPLAY::draw_screen() emu->set_vm_screen_lines(SCREEN_HEIGHT); emu->screen_skip_line(false); } - void DISPLAY::draw_chr_screen() { // scroll registers @@ -1586,7 +1797,7 @@ void DISPLAY::draw_chr_screen() ysdr = _height; } for(int x = 0, cx = 0; x < _width && cx < 80; x += xofs, cx++) { - uint16_t code = *(uint16_t *)(tvram + (*addr)); + uint16_t code = tvram[(*addr)] | (tvram[(*addr) + 1] << 8); uint8_t attr = tvram[(*addr) | 0x2000]; uint8_t color = (attr & ATTR_COL) ? (attr >> 5) : 8; bool cursor = ((*addr) == cursor_addr); @@ -1635,8 +1846,7 @@ void DISPLAY::draw_chr_screen() #endif pattern = (l < cl && l < FONT_HEIGHT) ? font[offset + l] : 0; #else - uint16_t pattern; - pattern = (l < cl && l < FONT_HEIGHT) ? *(uint16_t *)(&font[offset + l * 2]) : 0; + uint16_t pattern = (l < cl && l < FONT_HEIGHT) ? (font[offset + l * 2] | (font[offset + l * 2 + 1] << 8)) : 0; #endif if(!(attr & ATTR_ST)) { pattern = 0; @@ -1725,7 +1935,7 @@ void DISPLAY::draw_chr_screen() void DISPLAY::draw_gfx_screen() { // address from gdc - int _height = d_gdc_gfx->read_signal(SIG_UPD7220_HEIGHT); + int _height = d_gdc_gfx->read_signal(SIG_UPD7220_HEIGHT) << 4; int _width = d_gdc_gfx->read_signal(SIG_UPD7220_PITCH); uint32_t gdc_addr[480][SCREEN_WIDTH >> 3] = {0}; // Dragon Buster. @@ -1738,7 +1948,8 @@ void DISPLAY::draw_gfx_screen() if(_width > SCREEN_WIDTH) _width = SCREEN_WIDTH; if(_width2 < 0) _width2 = 0; //out_debug_log("WxH: %dx%d", _width, _height); - for(int i = 0, ytop = 0; i < 4; i++) { + int ytop = 0; + for(int i = 0; i < 4; i++) { uint32_t ra = ra_gfx[i * 4]; ra |= ra_gfx[i * 4 + 1] << 8; ra |= ra_gfx[i * 4 + 2] << 16; @@ -1746,8 +1957,6 @@ void DISPLAY::draw_gfx_screen() uint32_t sad = (ra << 1) & VRAM_PLANE_ADDR_MASK; int len = (ra >> 20) & 0x3ff; - if(!len) len = SCREEN_HEIGHT; // Madou Monogatari 1-2-3 - for(int y = ytop; y < (ytop + len) && y < _height; y++) { for(int x = 0; x < (_width >> 3); x++) { gdc_addr[y][x] = sad; @@ -1759,6 +1968,21 @@ void DISPLAY::draw_gfx_screen() } if((ytop += len) >= _height) break; } + if(ytop < SCREEN_HEIGHT) { + // Madou Monogatari 1-2-3 + uint32_t ra = ra_gfx[0]; + ra |= ra_gfx[1] << 8; + ra |= ra_gfx[2] << 16; + ra |= ra_gfx[3] << 24; + uint32_t sad = (ra << 1) & VRAM_PLANE_ADDR_MASK; + + for(int y = 0; y < SCREEN_HEIGHT; y++) { + for(int x = 0; x < (SCREEN_WIDTH >> 3); x++) { + gdc_addr[y][x] = sad; + sad = (sad + 1) & VRAM_PLANE_ADDR_MASK; + } + } + } uint32_t *addr = &gdc_addr[0][0]; uint8_t *dest = &screen_gfx[0][0]; @@ -1824,41 +2048,40 @@ void DISPLAY::draw_gfx_screen() } } -#define STATE_VERSION 8 +#define STATE_VERSION 4 bool DISPLAY::process_state(FILEIO* state_fio, bool loading) { if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } + return false; + } if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } + return false; + } state_fio->StateArray(tvram, sizeof(tvram), 1); state_fio->StateArray(vram, sizeof(vram), 1); - #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO) +#if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO) state_fio->StateValue(vram_disp_sel); state_fio->StateValue(vram_draw_sel); - #endif - state_fio->StateArrayScrnType_t(palette_gfx8, sizeof(palette_gfx8), 1); +#endif + state_fio->StateArray(palette_gfx8, sizeof(palette_gfx8), 1); state_fio->StateArray(digipal, sizeof(digipal), 1); - #if defined(SUPPORT_16_COLORS) - state_fio->StateArrayScrnType_t(palette_gfx16, sizeof(palette_gfx16), 1); +#if defined(SUPPORT_16_COLORS) + state_fio->StateArray(palette_gfx16, sizeof(palette_gfx16), 1); state_fio->StateArray(&anapal[0][0], sizeof(anapal), 1); state_fio->StateValue(anapal_sel); - #endif +#endif state_fio->StateValue(crtv); state_fio->StateArray(scroll, sizeof(scroll), 1); state_fio->StateArray(modereg1, sizeof(modereg1), 1); - state_fio->StateValue(border); - #if defined(SUPPORT_16_COLORS) +#if defined(SUPPORT_16_COLORS) state_fio->StateArray(modereg2, sizeof(modereg2), 1); - #endif - #if defined(SUPPORT_GRCG) +#endif +#if defined(SUPPORT_GRCG) state_fio->StateValue(grcg_mode); state_fio->StateValue(grcg_tile_ptr); state_fio->StateArray(grcg_tile, sizeof(grcg_tile), 1); - #endif +#endif #if defined(SUPPORT_EGC) state_fio->StateValue(egc_access); state_fio->StateValue(egc_fgbg); @@ -1881,8 +2104,8 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading) egc_inptr = egc_buf + inptr_ofs; egc_outptr = egc_buf + outptr_ofs; } else { - int inptr_ofs = egc_inptr - egc_buf; - int outptr_ofs = egc_outptr - egc_buf; + int inptr_ofs = (int)(egc_inptr - egc_buf); + int outptr_ofs = (int)(egc_outptr - egc_buf); state_fio->FputInt32_LE(inptr_ofs); state_fio->FputInt32_LE(outptr_ofs); } @@ -1895,21 +2118,19 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading) state_fio->StateArray(egc_buf, sizeof(egc_buf), 1); state_fio->StateValue(egc_vram_src.q); state_fio->StateValue(egc_vram_data.q); - - state_fio->StateValue(is_use_egc); - state_fio->StateValue(enable_egc); #endif state_fio->StateValue(font_code); state_fio->StateValue(font_line); // state_fio->StateValue(font_lr); - state_fio->StateValue(b_gfx_ff); -// state_fio->StateValue(vram_bank); - state_fio->StateArray(bank_table, sizeof(bank_table), 1); - // post process + // post process if(loading) { - border_color = RGB_COLOR((border & 2) ? 0xff : 0, (border & 4) ? 0xff : 0, (border & 1) ? 0xff : 0); + +#if defined(SUPPORT_16_COLORS) && defined(SUPPORT_EGC) + is_use_egc = ((config.dipswitch & (1 << DIPSWITCH_POSITION_EGC)) != 0); + enable_egc = ((is_use_egc) && (modereg2[MODE2_EGC] != 0)) ? true : false; +#endif #if defined(SUPPORT_2ND_VRAM) && !defined(SUPPORT_HIRESO) if(vram_disp_sel & 1) { vram_disp_b = vram + 0x28000; @@ -1931,19 +2152,15 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading) } else { vram_draw = vram + 0x00000; } - #if defined(SUPPORT_GRCG) +#endif +#if defined(SUPPORT_GRCG) grcg_cg_mode = ((grcg_mode & GRCG_CG_MODE) != 0) ? true : false; grcg_rw_mode = ((grcg_mode & GRCG_RW_MODE) != 0) ? true : false; - for(int i = 0; i < 4; i++) { - grcg_plane_enabled[i] = ((grcg_mode & (1 << i)) == 0) ? true : false;; - } for(int i = 0; i < 4; i++) { grcg_tile_word[i] = ((uint16_t)grcg_tile[i]) | ((uint16_t)grcg_tile[i] << 8); } - #endif #endif - } - return true; + } + return true; } - } diff --git a/source/src/vm/pc9801/display.h b/source/src/vm/pc9801/display.h index b89e3cca2..6e0af0093 100644 --- a/source/src/vm/pc9801/display.h +++ b/source/src/vm/pc9801/display.h @@ -23,6 +23,7 @@ #include "../vm.h" #include "../../emu.h" #include "../device.h" + #include "./display_consts.h" #define SIG_DISPLAY98_SET_PAGE_80 1 @@ -33,26 +34,24 @@ class UPD7220; namespace PC9801 { - - class DISPLAY : public DEVICE { private: DEVICE *d_pic; DEVICE *d_pio_prn; - outputs_t output_gdc_freq; - UPD7220 *d_gdc_chr, *d_gdc_gfx; + + outputs_t output_gdc_freq; uint8_t *ra_chr; uint8_t *ra_gfx, *cs_gfx; uint8_t tvram[0x4000]; uint32_t vram_bank; #if !defined(SUPPORT_HIRESO) -#if defined(SUPPORT_2ND_VRAM) - __DECL_ALIGNED(4) uint8_t vram[0x40000]; -#else +#if !defined(SUPPORT_2ND_VRAM) __DECL_ALIGNED(4) uint8_t vram[0x20000]; +#else + __DECL_ALIGNED(4) uint8_t vram[0x40000]; #endif #else __DECL_ALIGNED(4) uint8_t vram[0x80000]; @@ -123,7 +122,7 @@ class DISPLAY : public DEVICE uint32_t egc_stack; uint8_t* egc_inptr; uint8_t* egc_outptr; - + int tmp_inptr_ofs; int tmp_outptr_ofs; @@ -141,9 +140,10 @@ class DISPLAY : public DEVICE __DECL_ALIGNED(16) static const uint8_t egc_bytemask_u1[8]; __DECL_ALIGNED(16) static const uint8_t egc_bytemask_d0[64]; __DECL_ALIGNED(16) static const uint8_t egc_bytemask_d1[8]; - __DECL_ALIGNED(16) static const uint16_t egc_maskword[16][4]; + __DECL_ALIGNED(16) static const uint32_t egc_maskdword[16][2]; #endif bool display_high; + #if !defined(SUPPORT_HIRESO) #define FONT_SIZE 16 #define FONT_WIDTH 8 @@ -165,15 +165,17 @@ class DISPLAY : public DEVICE uint8_t screen_chr[SCREEN_HEIGHT][SCREEN_WIDTH + 1]; uint8_t screen_gfx[SCREEN_HEIGHT][SCREEN_WIDTH]; - uint32_t bank_table[0x10]; - #if !defined(SUPPORT_HIRESO) - void kanji_copy(uint8_t *dst, uint8_t *src, int from, int to); + void __FASTCALL kanji_copy(uint8_t *dst, uint8_t *src, int from, int to); #else - void ank_copy(int code, uint8_t *pattern); - void kanji_copy(int first, int second, uint8_t *pattern); + void __FASTCALL ank_copy(int code, uint8_t *pattern); + void __FASTCALL kanji_copy(int first, int second, uint8_t *pattern); +#endif +#ifdef __BIG_ENDIAN__ + inline void vram_draw_writew(uint32_t addr, uint32_t data); + inline uint32_t vram_draw_readw(uint32_t addr); #endif #if defined(SUPPORT_GRCG) void __FASTCALL grcg_writeb(uint32_t addr1, uint32_t data); @@ -182,38 +184,38 @@ class DISPLAY : public DEVICE uint32_t __FASTCALL grcg_readw(uint32_t addr1); #endif #if defined(SUPPORT_EGC) - inline void __FASTCALL egc_shift(); + void __FASTCALL egc_shift(); void __FASTCALL egc_sftb_upn_sub(uint32_t ext); void __FASTCALL egc_sftb_dnn_sub(uint32_t ext); void __FASTCALL egc_sftb_upr_sub(uint32_t ext); void __FASTCALL egc_sftb_dnr_sub(uint32_t ext); void __FASTCALL egc_sftb_upl_sub(uint32_t ext); void __FASTCALL egc_sftb_dnl_sub(uint32_t ext); - inline void __FASTCALL egc_sftb_upn0(uint32_t ext); - inline void __FASTCALL egc_sftw_upn0(); - inline void __FASTCALL egc_sftb_dnn0(uint32_t ext); - inline void __FASTCALL egc_sftw_dnn0(); - inline void __FASTCALL egc_sftb_upr0(uint32_t ext); - inline void __FASTCALL egc_sftw_upr0(); - inline void __FASTCALL egc_sftb_dnr0(uint32_t ext); - inline void __FASTCALL egc_sftw_dnr0(); - inline void __FASTCALL egc_sftb_upl0(uint32_t ext); - inline void __FASTCALL egc_sftw_upl0(); - inline void __FASTCALL egc_sftb_dnl0(uint32_t ext); - inline void __FASTCALL egc_sftw_dnl0(); - inline void __FASTCALL egc_sftb(int func, uint32_t ext); - inline void __FASTCALL egc_sftw(int func); - inline void __FASTCALL egc_shiftinput_byte(uint32_t ext); - inline void __FASTCALL egc_shiftinput_incw(); - inline void __FASTCALL egc_shiftinput_decw(); - inline uint64_t __FASTCALL egc_ope_00(uint8_t ope, uint32_t addr); - inline uint64_t __FASTCALL egc_ope_0f(uint8_t ope, uint32_t addr); - inline uint64_t __FASTCALL egc_ope_c0(uint8_t ope, uint32_t addr); - inline uint64_t __FASTCALL egc_ope_f0(uint8_t ope, uint32_t addr); - inline uint64_t __FASTCALL egc_ope_fc(uint8_t ope, uint32_t addr); - inline uint64_t __FASTCALL egc_ope_ff(uint8_t ope, uint32_t addr); - inline uint64_t __FASTCALL egc_ope_nd(uint8_t ope, uint32_t addr); - inline uint64_t __FASTCALL egc_ope_np(uint8_t ope, uint32_t addr); + void __FASTCALL egc_sftb_upn0(uint32_t ext); + void __FASTCALL egc_sftw_upn0(); + void __FASTCALL egc_sftb_dnn0(uint32_t ext); + void __FASTCALL egc_sftw_dnn0(); + void __FASTCALL egc_sftb_upr0(uint32_t ext); + void __FASTCALL egc_sftw_upr0(); + void __FASTCALL egc_sftb_dnr0(uint32_t ext); + void __FASTCALL egc_sftw_dnr0(); + void __FASTCALL egc_sftb_upl0(uint32_t ext); + void __FASTCALL egc_sftw_upl0(); + void __FASTCALL egc_sftb_dnl0(uint32_t ext); + void __FASTCALL egc_sftw_dnl0(); + void __FASTCALL egc_sftb(int func, uint32_t ext); + void __FASTCALL egc_sftw(int func); + void __FASTCALL egc_shiftinput_byte(uint32_t ext); + void __FASTCALL egc_shiftinput_incw(); + void __FASTCALL egc_shiftinput_decw(); + uint64_t __FASTCALL egc_ope_00(uint8_t ope, uint32_t addr); + uint64_t __FASTCALL egc_ope_0f(uint8_t ope, uint32_t addr); + uint64_t __FASTCALL egc_ope_c0(uint8_t ope, uint32_t addr); + uint64_t __FASTCALL egc_ope_f0(uint8_t ope, uint32_t addr); + uint64_t __FASTCALL egc_ope_fc(uint8_t ope, uint32_t addr); + uint64_t __FASTCALL egc_ope_ff(uint8_t ope, uint32_t addr); + uint64_t __FASTCALL egc_ope_nd(uint8_t ope, uint32_t addr); + uint64_t __FASTCALL egc_ope_np(uint8_t ope, uint32_t addr); uint64_t __FASTCALL egc_ope_xx(uint8_t ope, uint32_t addr); uint64_t __FASTCALL egc_opefn(uint32_t func, uint8_t ope, uint32_t addr); uint64_t __FASTCALL egc_opeb(uint32_t addr, uint8_t value); @@ -223,16 +225,20 @@ class DISPLAY : public DEVICE void __FASTCALL egc_writeb(uint32_t addr1, uint8_t value); void __FASTCALL egc_writew(uint32_t addr1, uint16_t value); #endif - void draw_chr_screen(); void draw_gfx_screen(); + void init_memsw(); void save_memsw(); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&output_gdc_freq); memset(tvram, 0, sizeof(tvram)); + d_pic = NULL; + d_pio_prn = NULL; + d_gdc_chr = NULL; + d_gdc_gfx = NULL; set_device_name(_T("Display")); } ~DISPLAY() {} @@ -256,6 +262,10 @@ class DISPLAY : public DEVICE bool process_state(FILEIO* state_fio, bool loading); // unique functions + void set_context_gdc_freq(DEVICE *device, int id, int mask) + { + register_output_signal(&output_gdc_freq, device, id, mask); + } void set_context_pic(DEVICE *device) { d_pic = device; @@ -265,10 +275,6 @@ class DISPLAY : public DEVICE d_gdc_chr = device; ra_chr = ra; } - void set_context_gdc_freq(DEVICE *device, int id, int mask) - { - register_output_signal(&output_gdc_freq, device, id, mask); - } void set_context_gdc_gfx(UPD7220 *device, uint8_t *ra, uint8_t *cs) { d_gdc_gfx = device; @@ -288,7 +294,6 @@ class DISPLAY : public DEVICE } void draw_screen(); }; - } #endif diff --git a/source/src/vm/pc9801/dmareg.h b/source/src/vm/pc9801/dmareg.h index dd4170d29..ab57ad749 100644 --- a/source/src/vm/pc9801/dmareg.h +++ b/source/src/vm/pc9801/dmareg.h @@ -26,7 +26,7 @@ class DMAREG : public DEVICE DEVICE *d_dma; public: - DMAREG(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DMAREG(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("DMA I/O")); } diff --git a/source/src/vm/pc9801/egc.cpp b/source/src/vm/pc9801/egc.cpp index 828f22f44..6ce1e015a 100644 --- a/source/src/vm/pc9801/egc.cpp +++ b/source/src/vm/pc9801/egc.cpp @@ -60,18 +60,46 @@ __DECL_ALIGNED(16) const uint8_t DISPLAY::egc_bytemask_d1[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, }; +/* __DECL_ALIGNED(16) const uint16_t DISPLAY::egc_maskword[16][4] = { - {0x0000, 0x0000, 0x0000, 0x0000}, {0xffff, 0x0000, 0x0000, 0x0000}, - {0x0000, 0xffff, 0x0000, 0x0000}, {0xffff, 0xffff, 0x0000, 0x0000}, - {0x0000, 0x0000, 0xffff, 0x0000}, {0xffff, 0x0000, 0xffff, 0x0000}, - {0x0000, 0xffff, 0xffff, 0x0000}, {0xffff, 0xffff, 0xffff, 0x0000}, - {0x0000, 0x0000, 0x0000, 0xffff}, {0xffff, 0x0000, 0x0000, 0xffff}, - {0x0000, 0xffff, 0x0000, 0xffff}, {0xffff, 0xffff, 0x0000, 0xffff}, - {0x0000, 0x0000, 0xffff, 0xffff}, {0xffff, 0x0000, 0xffff, 0xffff}, - {0x0000, 0xffff, 0xffff, 0xffff}, {0xffff, 0xffff, 0xffff, 0xffff} + {0x0000, 0x0000, 0x0000, 0x0000}, + {0xffff, 0x0000, 0x0000, 0x0000}, + {0x0000, 0xffff, 0x0000, 0x0000}, + {0xffff, 0xffff, 0x0000, 0x0000}, + {0x0000, 0x0000, 0xffff, 0x0000}, + {0xffff, 0x0000, 0xffff, 0x0000}, + {0x0000, 0xffff, 0xffff, 0x0000}, + {0xffff, 0xffff, 0xffff, 0x0000}, + {0x0000, 0x0000, 0x0000, 0xffff}, + {0xffff, 0x0000, 0x0000, 0xffff}, + {0x0000, 0xffff, 0x0000, 0xffff}, + {0xffff, 0xffff, 0x0000, 0xffff}, + {0x0000, 0x0000, 0xffff, 0xffff}, + {0xffff, 0x0000, 0xffff, 0xffff}, + {0x0000, 0xffff, 0xffff, 0xffff}, + {0xffff, 0xffff, 0xffff, 0xffff}, +}; +*/ +__DECL_ALIGNED(16) const uint32_t DISPLAY::egc_maskdword[16][2] = { + {0x00000000, 0x00000000}, + {0x0000ffff, 0x00000000}, + {0xffff0000, 0x00000000}, + {0xffffffff, 0x00000000}, + {0x00000000, 0x0000ffff}, + {0x0000ffff, 0x0000ffff}, + {0xffff0000, 0x0000ffff}, + {0xffffffff, 0x0000ffff}, + {0x00000000, 0xffff0000}, + {0x0000ffff, 0xffff0000}, + {0xffff0000, 0xffff0000}, + {0xffffffff, 0xffff0000}, + {0x00000000, 0xffffffff}, + {0x0000ffff, 0xffffffff}, + {0xffff0000, 0xffffffff}, + {0xffffffff, 0xffffffff}, }; -// SUBROUTINES are moved to display,h due to making inline. 20190514 K.O +// SUBROUTINES are moved to display.h due to making inline. 20190514 K.O void __FASTCALL DISPLAY::egc_sftb_upn_sub(uint32_t ext) { if(egc_dstbit >= 8) { @@ -545,10 +573,17 @@ uint64_t __FASTCALL DISPLAY::egc_ope_xx(uint8_t ope, uint32_t addr) } break; } - dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); - dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); - dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); - dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + #ifdef __BIG_ENDIAN__ + dst.w[0] = vram_draw_readw(addr | VRAM_PLANE_ADDR_0); + dst.w[1] = vram_draw_readw(addr | VRAM_PLANE_ADDR_1); + dst.w[2] = vram_draw_readw(addr | VRAM_PLANE_ADDR_2); + dst.w[3] = vram_draw_readw(addr | VRAM_PLANE_ADDR_3); + #else + dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); + dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); + dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); + dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + #endif //egc_vram_data.d[0] = 0; //egc_vram_data.d[1] = 0; @@ -1005,10 +1040,17 @@ __DECL_VECTORIZED_LOOP realaddr[i] = addr | vram_base[i]; } if(!(addr & 1)) { + #ifdef __BIG_ENDIAN__ + egc_lastvram.w[0] = vram_draw_readw(addr | VRAM_PLANE_ADDR_0); + egc_lastvram.w[1] = vram_draw_readw(addr | VRAM_PLANE_ADDR_1); + egc_lastvram.w[2] = vram_draw_readw(addr | VRAM_PLANE_ADDR_2); + egc_lastvram.w[3] = vram_draw_readw(addr | VRAM_PLANE_ADDR_3); + #else __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - egc_lastvram.w[i] = *(uint16_t *)(&vram_draw[realaddr[i]]); - } + for(int i = 0; i < 4; i++) { + egc_lastvram.w[i] = *(uint16_t *)(&vram_draw[realaddr[i]]); + } + #endif // egc_lastvram.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); // egc_lastvram.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); // egc_lastvram.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); @@ -1058,10 +1100,18 @@ __DECL_VECTORIZED_LOOP if(!(egc_ope & 0x400)) { return egc_vram_src.w[pl]; } else { - return *(uint16_t *)(&vram_draw[addr | (VRAM_PLANE_SIZE * pl)]); + #ifdef __BIG_ENDIAN__ + return vram_draw_readw(addr | (VRAM_PLANE_SIZE * pl)); + #else + return *(uint16_t *)(&vram_draw[addr | (VRAM_PLANE_SIZE * pl)]); + #endif } } - return *(uint16_t *)(&vram_draw[addr1]); + #ifdef __BIG_ENDIAN__ + return vram_draw_readw(addr1); + #else + return *(uint16_t *)(&vram_draw[addr1]); + #endif } else if(!(egc_sft & 0x1000)) { uint16_t value = egc_readb(addr1); value |= egc_readb(addr1 + 1) << 8; @@ -1167,14 +1217,17 @@ __DECL_VECTORIZED_LOOP if(!(addr & 1)) { if((egc_ope & 0x0300) == 0x0200) { + #ifdef __BIG_ENDIAN__ + egc_patreg.w[0] = vram_draw_readw(addr | VRAM_PLANE_ADDR_0); + egc_patreg.w[1] = vram_draw_readw(addr | VRAM_PLANE_ADDR_1); + egc_patreg.w[2] = vram_draw_readw(addr | VRAM_PLANE_ADDR_2); + egc_patreg.w[3] = vram_draw_readw(addr | VRAM_PLANE_ADDR_3); + #else __DECL_VECTORIZED_LOOP - for(int i = 0; i < 4; i++) { - egc_patreg.w[i] = *(uint16_t *)(&vram_draw[realaddr[i]]); - } - //egc_patreg.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); - //egc_patreg.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); - //egc_patreg.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); - //egc_patreg.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + for(int i = 0; i < 4; i++) { + egc_patreg.w[i] = *(uint16_t *)(&vram_draw[realaddr[i]]); + } + #endif } data.q = egc_opew(addr, value); uint32_t bit; diff --git a/source/src/vm/pc9801/egc_inline.h b/source/src/vm/pc9801/egc_inline.h index 5e434e640..938731dd8 100644 --- a/source/src/vm/pc9801/egc_inline.h +++ b/source/src/vm/pc9801/egc_inline.h @@ -4,7 +4,7 @@ namespace PC9801 { #if defined(SUPPORT_EGC) -inline void __FASTCALL DISPLAY::egc_shift() +void __FASTCALL DISPLAY::egc_shift() { uint8_t src8, dst8; @@ -36,7 +36,7 @@ inline void __FASTCALL DISPLAY::egc_shift() } -inline void __FASTCALL DISPLAY::egc_sftb_upn0(uint32_t ext) +void __FASTCALL DISPLAY::egc_sftb_upn0(uint32_t ext) { if(egc_stack < (uint32_t)(8 - egc_dstbit)) { egc_srcmask.b[ext] = 0; @@ -49,7 +49,7 @@ inline void __FASTCALL DISPLAY::egc_sftb_upn0(uint32_t ext) } } -inline void __FASTCALL DISPLAY::egc_sftw_upn0() +void __FASTCALL DISPLAY::egc_sftw_upn0() { if(egc_stack < (uint32_t)(16 - egc_dstbit)) { egc_srcmask.w = 0; @@ -68,7 +68,7 @@ inline void __FASTCALL DISPLAY::egc_sftw_upn0() egc_shift(); } -inline void __FASTCALL DISPLAY::egc_sftb_dnn0(uint32_t ext) +void __FASTCALL DISPLAY::egc_sftb_dnn0(uint32_t ext) { if(egc_stack < (uint32_t)(8 - egc_dstbit)) { egc_srcmask.b[ext] = 0; @@ -81,7 +81,7 @@ inline void __FASTCALL DISPLAY::egc_sftb_dnn0(uint32_t ext) } } -inline void __FASTCALL DISPLAY::egc_sftw_dnn0() +void __FASTCALL DISPLAY::egc_sftw_dnn0() { if(egc_stack < (uint32_t)(16 - egc_dstbit)) { egc_srcmask.w = 0; @@ -100,7 +100,7 @@ inline void __FASTCALL DISPLAY::egc_sftw_dnn0() egc_shift(); } -inline void __FASTCALL DISPLAY::egc_sftb_upr0(uint32_t ext) +void __FASTCALL DISPLAY::egc_sftb_upr0(uint32_t ext) { if(egc_stack < (uint32_t)(8 - egc_dstbit)) { egc_srcmask.b[ext] = 0; @@ -113,7 +113,7 @@ inline void __FASTCALL DISPLAY::egc_sftb_upr0(uint32_t ext) } } -inline void __FASTCALL DISPLAY::egc_sftw_upr0() +void __FASTCALL DISPLAY::egc_sftw_upr0() { if(egc_stack < (uint32_t)(16 - egc_dstbit)) { egc_srcmask.w = 0; @@ -132,7 +132,7 @@ inline void __FASTCALL DISPLAY::egc_sftw_upr0() egc_shift(); } -inline void __FASTCALL DISPLAY::egc_sftb_dnr0(uint32_t ext) +void __FASTCALL DISPLAY::egc_sftb_dnr0(uint32_t ext) { if(egc_stack < (uint32_t)(8 - egc_dstbit)) { egc_srcmask.b[ext] = 0; @@ -145,7 +145,7 @@ inline void __FASTCALL DISPLAY::egc_sftb_dnr0(uint32_t ext) } } -inline void __FASTCALL DISPLAY::egc_sftw_dnr0() +void __FASTCALL DISPLAY::egc_sftw_dnr0() { if(egc_stack < (uint32_t)(16 - egc_dstbit)) { egc_srcmask.w = 0; @@ -164,7 +164,7 @@ inline void __FASTCALL DISPLAY::egc_sftw_dnr0() egc_shift(); } -inline void __FASTCALL DISPLAY::egc_sftb_upl0(uint32_t ext) +void __FASTCALL DISPLAY::egc_sftb_upl0(uint32_t ext) { if(egc_stack < (uint32_t)(8 - egc_dstbit)) { egc_srcmask.b[ext] = 0; @@ -177,7 +177,7 @@ inline void __FASTCALL DISPLAY::egc_sftb_upl0(uint32_t ext) } } -inline void __FASTCALL DISPLAY::egc_sftw_upl0() +void __FASTCALL DISPLAY::egc_sftw_upl0() { if(egc_stack < (uint32_t)(16 - egc_dstbit)) { egc_srcmask.w = 0; @@ -196,7 +196,7 @@ inline void __FASTCALL DISPLAY::egc_sftw_upl0() egc_shift(); } -inline void __FASTCALL DISPLAY::egc_sftb_dnl0(uint32_t ext) +void __FASTCALL DISPLAY::egc_sftb_dnl0(uint32_t ext) { if(egc_stack < (uint32_t)(8 - egc_dstbit)) { egc_srcmask.b[ext] = 0; @@ -209,7 +209,7 @@ inline void __FASTCALL DISPLAY::egc_sftb_dnl0(uint32_t ext) } } -inline void __FASTCALL DISPLAY::egc_sftw_dnl0() +void __FASTCALL DISPLAY::egc_sftw_dnl0() { if(egc_stack < (uint32_t)(16 - egc_dstbit)) { egc_srcmask.w = 0; @@ -228,7 +228,7 @@ inline void __FASTCALL DISPLAY::egc_sftw_dnl0() egc_shift(); } -inline void __FASTCALL DISPLAY::egc_sftb(int func, uint32_t ext) +void __FASTCALL DISPLAY::egc_sftb(int func, uint32_t ext) { switch(func) { case 0: egc_sftb_upn0(ext); break; @@ -240,7 +240,7 @@ inline void __FASTCALL DISPLAY::egc_sftb(int func, uint32_t ext) } } -inline void __FASTCALL DISPLAY::egc_sftw(int func) +void __FASTCALL DISPLAY::egc_sftw(int func) { switch(func) { case 0: egc_sftw_upn0(); break; @@ -252,7 +252,7 @@ inline void __FASTCALL DISPLAY::egc_sftw(int func) } } -inline void __FASTCALL DISPLAY::egc_shiftinput_byte(uint32_t ext) +void __FASTCALL DISPLAY::egc_shiftinput_byte(uint32_t ext) { if(egc_stack <= 16) { if(egc_srcbit >= 8) { @@ -271,7 +271,7 @@ inline void __FASTCALL DISPLAY::egc_shiftinput_byte(uint32_t ext) egc_sftb(egc_func, ext); } -inline void __FASTCALL DISPLAY::egc_shiftinput_incw() +void __FASTCALL DISPLAY::egc_shiftinput_incw() { if(egc_stack <= 16) { egc_inptr += 2; @@ -285,7 +285,7 @@ inline void __FASTCALL DISPLAY::egc_shiftinput_incw() egc_sftw(egc_func); } -inline void __FASTCALL DISPLAY::egc_shiftinput_decw() +void __FASTCALL DISPLAY::egc_shiftinput_decw() { if(egc_stack <= 16) { egc_inptr -= 2; @@ -302,12 +302,12 @@ inline void __FASTCALL DISPLAY::egc_shiftinput_decw() -inline uint64_t __FASTCALL DISPLAY::egc_ope_00(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_00(uint8_t ope, uint32_t addr) { return 0; } -inline uint64_t __FASTCALL DISPLAY::egc_ope_0f(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_0f(uint8_t ope, uint32_t addr) { egc_vram_data.q = ~egc_vram_src.q; // egc_vram_data.d[0] = ~egc_vram_src.d[0]; @@ -315,34 +315,47 @@ inline uint64_t __FASTCALL DISPLAY::egc_ope_0f(uint8_t ope, uint32_t addr) return egc_vram_data.q; } -inline uint64_t __FASTCALL DISPLAY::egc_ope_c0(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_c0(uint8_t ope, uint32_t addr) { __DECL_ALIGNED(16) egcquad_t dst; - - dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); - dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); - dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); - dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + #ifdef __BIG_ENDIAN__ + dst.w[0] = vram_draw_readw(addr | VRAM_PLANE_ADDR_0); + dst.w[1] = vram_draw_readw(addr | VRAM_PLANE_ADDR_1); + dst.w[2] = vram_draw_readw(addr | VRAM_PLANE_ADDR_2); + dst.w[3] = vram_draw_readw(addr | VRAM_PLANE_ADDR_3); + #else + dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); + dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); + dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); + dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + #endif // egc_vram_data.d[0] = (egc_vram_src.d[0] & dst.d[0]); // egc_vram_data.d[1] = (egc_vram_src.d[1] & dst.d[1]); egc_vram_data.q = egc_vram_src.q & dst.q; return egc_vram_data.q; } -inline uint64_t __FASTCALL DISPLAY::egc_ope_f0(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_f0(uint8_t ope, uint32_t addr) { return egc_vram_src.q; } -inline uint64_t __FASTCALL DISPLAY::egc_ope_fc(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_fc(uint8_t ope, uint32_t addr) { __DECL_ALIGNED(16) egcquad_t dst; - dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); - dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); - dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); - dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + #ifdef __BIG_ENDIAN__ + dst.w[0] = vram_draw_readw(addr | VRAM_PLANE_ADDR_0); + dst.w[1] = vram_draw_readw(addr | VRAM_PLANE_ADDR_1); + dst.w[2] = vram_draw_readw(addr | VRAM_PLANE_ADDR_2); + dst.w[3] = vram_draw_readw(addr | VRAM_PLANE_ADDR_3); + #else + dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); + dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); + dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); + dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + #endif egc_vram_data.q = egc_vram_src.q; egc_vram_data.q |= ((~egc_vram_src.q) & dst.q); // egc_vram_data.d[0] = egc_vram_src.d[0]; @@ -352,13 +365,13 @@ inline uint64_t __FASTCALL DISPLAY::egc_ope_fc(uint8_t ope, uint32_t addr) return egc_vram_data.q; } -inline uint64_t __FASTCALL DISPLAY::egc_ope_ff(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_ff(uint8_t ope, uint32_t addr) { return ~0; } -inline uint64_t __FASTCALL DISPLAY::egc_ope_nd(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_nd(uint8_t ope, uint32_t addr) { __DECL_ALIGNED(16) egcquad_t pat; __DECL_ALIGNED(16) egcquad_t tmp; @@ -420,16 +433,22 @@ inline uint64_t __FASTCALL DISPLAY::egc_ope_nd(uint8_t ope, uint32_t addr) return tmp.q; } -inline uint64_t __FASTCALL DISPLAY::egc_ope_np(uint8_t ope, uint32_t addr) +uint64_t __FASTCALL DISPLAY::egc_ope_np(uint8_t ope, uint32_t addr) { __DECL_ALIGNED(16) egcquad_t dst; __DECL_ALIGNED(16) egcquad_t tmp; - dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); - dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); - dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); - dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); - + #ifdef __BIG_ENDIAN__ + dst.w[0] = vram_draw_readw(addr | VRAM_PLANE_ADDR_0); + dst.w[1] = vram_draw_readw(addr | VRAM_PLANE_ADDR_1); + dst.w[2] = vram_draw_readw(addr | VRAM_PLANE_ADDR_2); + dst.w[3] = vram_draw_readw(addr | VRAM_PLANE_ADDR_3); + #else + dst.w[0] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_0]); + dst.w[1] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_1]); + dst.w[2] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_2]); + dst.w[3] = *(uint16_t *)(&vram_draw[addr | VRAM_PLANE_ADDR_3]); + #endif tmp.q = (ope & 0x80) ? (dst.q & egc_vram_src.q) : 0; tmp.q |= (ope & 0x20) ? ((~dst.q) & egc_vram_src.q) : 0; diff --git a/source/src/vm/pc9801/floppy.cpp b/source/src/vm/pc9801/floppy.cpp index f21b83e8c..85f61f332 100644 --- a/source/src/vm/pc9801/floppy.cpp +++ b/source/src/vm/pc9801/floppy.cpp @@ -30,14 +30,18 @@ namespace PC9801 { void FLOPPY::reset() { #if defined(SUPPORT_2HD_FDD_IF) - for(int i = 0; i < MAX_DRIVE; i++) { - d_fdc_2hd->set_drive_type(i, DRIVE_TYPE_2HD); + if(d_fdc_2hd) { + for(int i = 0; i < MAX_DRIVE; i++) { + d_fdc_2hd->set_drive_type(i, DRIVE_TYPE_2HD); + } } ctrlreg_2hd = 0x80; #endif #if defined(SUPPORT_2DD_FDD_IF) - for(int i = 0; i < MAX_DRIVE; i++) { - d_fdc_2dd->set_drive_type(i, DRIVE_TYPE_2DD); + if(d_fdc_2dd) { + for(int i = 0; i < MAX_DRIVE; i++) { + d_fdc_2dd->set_drive_type(i, DRIVE_TYPE_2DD); + } } ctrlreg_2dd = 0x80; #endif @@ -56,39 +60,51 @@ void FLOPPY::write_io8(uint32_t addr, uint32_t data) switch(addr) { #if defined(SUPPORT_2HD_FDD_IF) case 0x0090: - d_fdc_2hd->write_io8(0, data); + if(d_fdc_2hd) { + d_fdc_2hd->write_io8(0, data); + } break; case 0x0092: - d_fdc_2hd->write_io8(1, data); + if(d_fdc_2hd) { + d_fdc_2hd->write_io8(1, data); + } break; case 0x0094: case 0x0096: - if(!(ctrlreg_2hd & 0x80) && (data & 0x80)) { - d_fdc_2hd->reset(); + if(d_fdc_2hd) { + if(!(ctrlreg_2hd & 0x80) && (data & 0x80)) { + d_fdc_2hd->reset(); + } + d_fdc_2hd->write_signal(SIG_UPD765A_FREADY, data, 0x40); } - d_fdc_2hd->write_signal(SIG_UPD765A_FREADY, data, 0x40); ctrlreg_2hd = data; break; #endif #if defined(SUPPORT_2DD_FDD_IF) case 0x00c8: - d_fdc_2dd->write_io8(0, data); + if(d_fdc_2dd) { + d_fdc_2dd->write_io8(0, data); + } break; case 0x00ca: - d_fdc_2dd->write_io8(1, data); + if(d_fdc_2dd) { + d_fdc_2dd->write_io8(1, data); + } break; case 0x00cc: case 0x00ce: - if(!(ctrlreg_2dd & 0x80) && (data & 0x80)) { - d_fdc_2dd->reset(); - } - if(data & 1) { - if(timer_id != -1) { - cancel_event(this, timer_id); + if(d_fdc_2dd) { + if(!(ctrlreg_2dd & 0x80) && (data & 0x80)) { + d_fdc_2dd->reset(); } - register_event(this, EVENT_TIMER, 100000, false, &timer_id); + if(data & 1) { + if(timer_id != -1) { + cancel_event(this, timer_id); + } + register_event(this, EVENT_TIMER, 100000, false, &timer_id); + } + d_fdc_2dd->write_signal(SIG_UPD765A_MOTOR, data, 0x08); } - d_fdc_2dd->write_signal(SIG_UPD765A_MOTOR, data, 0x08); ctrlreg_2dd = data; break; #endif @@ -186,30 +202,48 @@ uint32_t FLOPPY::read_io8(uint32_t addr) switch(addr) { #if defined(SUPPORT_2HD_FDD_IF) case 0x0090: - return d_fdc_2hd->read_io8(0); + if(d_fdc_2hd) { + return d_fdc_2hd->read_io8(0); + } + break; case 0x0092: - return d_fdc_2hd->read_io8(1); + if(d_fdc_2hd) { + return d_fdc_2hd->read_io8(1); + } + break; case 0x0094: case 0x0096: -// value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON - value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON -// value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON - return value; + if(d_fdc_2hd) { +// value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON + value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON +// value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON + return value; + } + break; #endif #if defined(SUPPORT_2DD_FDD_IF) case 0x00c8: - return d_fdc_2dd->read_io8(0); + if(d_fdc_2dd) { + return d_fdc_2dd->read_io8(0); + } + break; case 0x00ca: - return d_fdc_2dd->read_io8(1); + if(d_fdc_2dd) { + return d_fdc_2dd->read_io8(1); + } + break; case 0x00cc: case 0x00ce: -// value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON - value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON - value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON - if(d_fdc_2dd->is_disk_inserted()) { - value |= 0x10; // RDY + if(d_fdc_2dd) { +// value |= 0x80; // FINT1 (DIP SW 1-7), 1 = OFF, 0 = ON + value |= 0x40; // FINT0 (DIP SW 1-6), 1 = OFF, 0 = ON + value |= 0x20; // DMACH (DIP SW 1-3), 1 = OFF, 0 = ON + if(d_fdc_2dd->is_disk_inserted()) { + value |= 0x10; // RDY + } + return value; } - return value; + break; #endif #if defined(SUPPORT_2HD_2DD_FDD_IF) case 0x0090: diff --git a/source/src/vm/pc9801/floppy.h b/source/src/vm/pc9801/floppy.h index f8d8a2677..cd5742a1b 100644 --- a/source/src/vm/pc9801/floppy.h +++ b/source/src/vm/pc9801/floppy.h @@ -61,7 +61,7 @@ class FLOPPY : public DEVICE int timer_id; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } @@ -72,7 +72,7 @@ class FLOPPY : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/pc9801/fmsound.cpp b/source/src/vm/pc9801/fmsound.cpp index 831c551c9..bbb6532d3 100644 --- a/source/src/vm/pc9801/fmsound.cpp +++ b/source/src/vm/pc9801/fmsound.cpp @@ -14,13 +14,12 @@ Author : Takeda.Toshiya Date : 2012.02.03- - [ PC-9801-26 ] + [ PC-9801-26/86 ] */ #include "fmsound.h" -#ifdef _PC98_HAVE_86PCM -#include "fifo.h" -#endif +#include "../i8259.h" +#include "../../fifo.h" // From http://www.webtech.co.jp/company/doc/undocumented_mem/io_sound.txt . // bit 7-4: @@ -35,71 +34,61 @@ // 1000 : PC-9821Cf/Cx/Cb/Cx2/Cb2/Cx3/Cb3/Na7/Nx // 1xx0 : Unknown // 1111 : NO Sound or PC-9801-26. -// PC-98DO+ -#if defined(_PC98DOPLUS) -#define BOARD_ID 0x00 -#elif defined(_PC98GS) -#define BOARD_ID 0x10 -#elif defined(SUPPORT_PC98_OPNA) -#define BOARD_ID 0x40 -//#define BOARD_ID 0x50 + +//#if defined(SUPPORT_PC98_OPNA) +#if defined(SUPPORT_PC98_86PCM) +#define BOARD_ID 4 #else -#define BOARD_ID 0xf0 +#define BOARD_ID 0 #endif -#define EVENT_PCM 1 - namespace PC9801 { +#if defined(SUPPORT_PC98_86PCM) +#define EVENT_SAMPLE 0 +//#define _PCM_DEBUG_LOG + +static const uint32_t sample_rate_x8[] = { + 352800, 264600, 176400, 132300, 88200, 66150, 44010, 33075 +}; +static const int bytes_per_sample[] = { + 0, 2, 2, 4, 0, 1, 1, 2 +}; +#endif void FMSOUND::initialize() { -#ifdef _PC98_HAVE_86PCM - pcm_fifo = new FIFO(32768); - play_bufsize = sizeof(play_pool) / sizeof(int32_t); - play_w_remain = 0; - play_rptr = 0; - play_wptr = 0; - memset(play_pool, 0x00, sizeof(int32_t) * play_bufsize); - - event_pcm = -1; +#if defined(SUPPORT_PC98_86PCM) + pcm_clocks = 0; + pcm_prev_clock = 0; + pcm_fifo = new FIFO(0x8000); + pcm_register_id = -1; #endif } void FMSOUND::release() { -#ifdef _PC98_HAVE_86PCM +#if defined(SUPPORT_PC98_86PCM) if(pcm_fifo != NULL) pcm_fifo->release(); + delete pcm_fifo; + pcm_fifo = NULL; #endif } void FMSOUND::reset() { - mask = (BOARD_ID & 0xf0) | 0; -#ifdef _PC98_HAVE_86PCM - // Will move to initialize()? - fifo_enabled = false; - pcm_freq = 44100; - pcm_da_intleft = 128; - // Q: Is clear FIFO? - lrclock = false; - fifo_direction = true; // PLAY - fifo_int_status = false; - fifo_int_flag = false; - pcm_is_16bit = false; - pcm_l_enabled = true; - pcm_r_enabled = true; - play_bufsize = sizeof(play_pool) / sizeof(int32_t); - - play_w_remain = 0; - play_rptr = 0; - play_wptr = 0; - memset(play_pool, 0x00, sizeof(int32_t) * play_bufsize); - - mix_mod = 0; - if(event_pcm >= 0) { - cancel_event(this, event_pcm); - event_pcm = -1; +#if defined(SUPPORT_PC98_OPNA) + opna_mask = 0; + pcm_vol_ctrl = pcm_fifo_ctrl = 0; + pcm_dac_ctrl = 0x32; + pcm_fifo_size = 0x80; + pcm_mute_ctrl = 0x00; + pcm_fifo_written = pcm_overflow = pcm_irq_raised = false; + pcm_fifo->clear(); + if(pcm_register_id != -1) { + cancel_event(this, pcm_register_id); + pcm_register_id = -1; } + pcm_sample_l = pcm_sample_r = 0; #endif } @@ -120,376 +109,200 @@ void FMSOUND::check_fifo_position() void FMSOUND::mix(int32_t* buffer, int cnt) { - int ncount = 0; - int32_t sample_l, sample_r; - int32_t lastvol_l, lastvol_r; -#ifdef _PC98_HAVE_86PCM - int lptr = play_rptr; - if(lptr >= play_bufsize) lptr = 0; - int rptr; - - if(((pcm_l_enabled) || (pcm_r_enabled)) && (play_w_remain > 0) && (fifo_direction) && (fifo_enabled)) { // Play - if(pcm_freq == sample_rate) { - int32_t* p = buffer; - if((pcm_l_enabled) && (pcm_r_enabled)) { - rptr = lptr + 1; - if(rptr >= play_bufsize) rptr = 0; - sample_l = play_pool[lptr]; - sample_r = play_pool[rptr]; - } else if(pcm_l_enabled) { - rptr = lptr; - sample_l = play_pool[lptr]; - sample_r = 0; - } else if(pcm_r_enabled) { - rptr = lptr; - sample_r = play_pool[rptr]; - sample_l = 0; - } - lastvol_l = apply_volume(sample_l, volume_l); - lastvol_r = apply_volume(sample_r, volume_r); - for(int i = 0; i < cnt; i++) { - p[0] += lastvol_l; - p[1] += lastvol_r; - play_w_remain -= (((pcm_l_enabled) && (pcm_r_enabled)) ? 2 : 1); - if(play_w_remain > 0) { - if((pcm_l_enabled) && (pcm_r_enabled)) { - lptr += 2; - if(lptr >= play_bufsize) lptr = 0; - rptr = lptr + 1; - if(rptr >= play_bufsize) rptr = 0; - sample_l = play_pool[lptr]; - sample_r = play_pool[rptr]; - } else if(pcm_l_enabled) { - lptr++; - if(lptr >= play_bufsize) lptr = 0; - rptr = lptr; - sample_l = play_pool[lptr]; - sample_r = 0; - } else if(pcm_r_enabled) { - lptr++; - if(lptr >= play_bufsize) lptr = 0; - rptr = lptr; - sample_r = play_pool[rptr]; - sample_l = 0; - } - lastvol_l = apply_volume(sample_l, volume_l); - lastvol_r = apply_volume(sample_r, volume_r); - } else { - play_w_remain = 0; - } - p += 2; - play_rptr = lptr; - } - } else if(pcm_freq < sample_rate) { - int32_t* p = buffer; - if((pcm_l_enabled) && (pcm_r_enabled)) { - rptr = lptr + 1; - if(rptr >= play_bufsize) rptr = 0; - sample_l = play_pool[lptr]; - sample_r = play_pool[rptr]; - } else if(pcm_l_enabled) { - rptr = lptr; - sample_l = play_pool[lptr]; - sample_r = 0; - } else if(pcm_r_enabled) { - rptr = lptr; - sample_r = play_pool[rptr]; - sample_l = 0; - } - lastvol_l = apply_volume(sample_l, volume_l); - lastvol_r = apply_volume(sample_r, volume_r); - for(int i = 0; i < cnt; i++) { - p[0] += lastvol_l; - p[1] += lastvol_r; - mix_mod = mix_mod + pcm_freq; - if(mix_mod >= sample_rate) { - mix_mod -= sample_rate; - //play_w_remain -= (((pcm_l_enabled) && (pcm_r_enabled)) ? 2 : 1); - if(play_w_remain > 0) { - if((pcm_l_enabled) && (pcm_r_enabled)) { - lptr += 2; - if(lptr >= play_bufsize) lptr = 0; - rptr = lptr + 1; - if(rptr >= play_bufsize) rptr = 0; - sample_l = play_pool[lptr]; - sample_r = play_pool[rptr]; - play_w_remain -= 2; - } else if(pcm_r_enabled) { - lptr++; - if(lptr >= play_bufsize) lptr = 0; - rptr = lptr; - sample_r = play_pool[rptr]; - play_w_remain -= 1; - } else if(pcm_l_enabled) { - lptr++; - if(lptr >= play_bufsize) lptr = 0; - rptr = lptr; - sample_l = play_pool[lptr]; - play_w_remain -= 1; - } - lastvol_l = apply_volume(sample_l, volume_l); - lastvol_r = apply_volume(sample_r, volume_r); - } else { - play_w_remain = 0; - } - } - p += 2; - play_rptr = lptr; - } - } else if(pcm_freq > sample_rate) { - int32_t* p = buffer; - int min_skip = pcm_freq / sample_rate; - if((pcm_l_enabled) && (pcm_r_enabled)) { - rptr = lptr + 1; - if(rptr >= play_bufsize) rptr = 0; - sample_l = play_pool[lptr]; - sample_r = play_pool[rptr]; - } else if(pcm_l_enabled) { - rptr = lptr; - sample_l = play_pool[lptr]; - sample_r = 0; - } else if(pcm_r_enabled) { - rptr = lptr; - sample_r = play_pool[rptr]; - sample_l = 0; - } - lastvol_l = apply_volume(sample_l, volume_l); - lastvol_r = apply_volume(sample_r, volume_r); - int inc_factor; - for(int i = 0; i < cnt; i++) { - p[0] += lastvol_l; - p[1] += lastvol_r; - inc_factor = 0; - mix_mod = mix_mod + (sample_rate * min_skip); - if(mix_mod >= pcm_freq) { - mix_mod -= pcm_freq; - inc_factor = 1; - } - play_w_remain -= (((pcm_l_enabled) && (pcm_r_enabled)) ? ((min_skip + inc_factor) * 2) : (min_skip + inc_factor)); - if(play_w_remain > 0) { - if((pcm_l_enabled) && (pcm_r_enabled)) { - lptr += ((min_skip + inc_factor) * 2); - if(lptr >= play_bufsize) lptr = lptr - play_bufsize; - rptr = lptr + 1; - if(rptr >= play_bufsize) rptr = 0; - sample_l = play_pool[lptr]; - sample_r = play_pool[rptr]; - } else if(pcm_l_enabled) { - lptr += (min_skip + inc_factor); - if(lptr >= play_bufsize) lptr = lptr - play_bufsize; - rptr = lptr; - sample_l = play_pool[lptr]; - sample_r = 0; - } else if(pcm_r_enabled) { - lptr += (min_skip + inc_factor); - if(lptr >= play_bufsize) lptr = lptr - play_bufsize; - rptr = lptr; - sample_r = play_pool[rptr]; - sample_l = 0; - } - lastvol_l = apply_volume(sample_l, volume_l); - lastvol_r = apply_volume(sample_r, volume_r); - } else { - play_w_remain = 0; - } - p += 2; - play_rptr = lptr; - } +#if defined(SUPPORT_PC98_86PCM) + if((pcm_fifo_ctrl & 0x80) && !(pcm_fifo_ctrl & 0x40) && !(pcm_mute_ctrl & 1)) { + for(int i = 0; i < cnt; i++) { + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Mix Sample = %d,%d\n"), pcm_sample_l, pcm_sample_r); + #endif + *buffer++ += apply_volume(pcm_sample_l, pcm_volume_l); // L + *buffer++ += apply_volume(pcm_sample_r, pcm_volume_r); // R } } - //* ToDo: Mix PCM #endif } void FMSOUND::event_callback(int id, int err) { - switch(id) { - case EVENT_PCM: -#ifdef _PC98_HAVE_86PCM - lrclock = !lrclock; - if((pcm_fifo != NULL)) { - if(fifo_direction) { // Play - pair16_t data; - data.w = 0; - if(!(pcm_fifo->empty())) { - if(fifo_enabled) { - if(pcm_is_16bit) { - if(((lrclock) && (pcm_l_enabled)) || (!(lrclock) && (pcm_r_enabled))) { - data.b.h = (uint8_t)(pcm_fifo->read()); - data.b.l = (uint8_t)(pcm_fifo->read()); - check_fifo_position(); - } - } else { - if(((lrclock) && (pcm_l_enabled)) || (!(lrclock) && (pcm_r_enabled))) { - data.b.h = (uint8_t)(pcm_fifo->read()); - check_fifo_position(); - data.b.l = 0x00; - } - } - } - if(((lrclock) && (pcm_l_enabled)) || (!(lrclock) && (pcm_r_enabled))) { - pcm_data.sd = (int32_t)(data.sw >> 1); - play_pool[play_wptr++] = pcm_data.sd; - } - if(play_wptr >= play_bufsize) play_wptr = 0; - play_w_remain++; - if(play_w_remain >= play_bufsize) play_w_remain = play_bufsize; - } - } else { // ToDo: Record - pcm_data.sd = 0; - if(pcm_is_16bit) { - pcm_fifo->write(pcm_data.b.h); - check_fifo_position(); - pcm_fifo->write(pcm_data.b.l); - check_fifo_position(); - } else { - pcm_fifo->write(pcm_data.b.h); - check_fifo_position(); - } +#if defined(SUPPORT_PC98_86PCM) + if(pcm_fifo->count() >= bytes_per_sample[(pcm_dac_ctrl >> 4) & 7]) { + pcm_sample_l = pcm_sample_r = 0; + + if(pcm_fifo_ctrl & 0x40) { + // record +// pcm_overflow = pcm_fifo->full(); + } else { + // play + + if(pcm_dac_ctrl & 0x20) pcm_sample_l = (pcm_volume * get_sample()) / 32768; + if(pcm_dac_ctrl & 0x10) pcm_sample_r = (pcm_volume * get_sample()) / 32768; + } +// if(pcm_fifo_written && pcm_fifo->count() <= pcm_fifo_size) { + if(pcm_fifo->count() == pcm_fifo_size) { + pcm_fifo_written = false; + pcm_irq_raised = true; + + if(pcm_fifo_ctrl & 0x20) { + #ifdef SUPPORT_PC98_86PCM_IRQ + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR4, 1, 1); + #endif + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Raise IRQ in Sample Event\n")); + #endif } } + } #endif - break; +} + +#if defined(SUPPORT_PC98_86PCM) +int FMSOUND::get_sample() +{ + if(!(pcm_dac_ctrl & 0x40)) { + uint16_t sample; + sample = pcm_fifo->read() << 8; + sample |= pcm_fifo->read(); + return (int)(int16_t)sample; + } else { + uint8_t sample = pcm_fifo->read(); + return (int)(int8_t)sample * 256; } } +#endif + void FMSOUND::write_io8(uint32_t addr, uint32_t data) { switch(addr) { case 0x0188: - if((mask & 2) == 0) { +// if((mask & 2) == 0) { d_opn->write_io8(0, data); - } +// } break; case 0x018a: - if((mask & 2) == 0) { +// if((opna_mask & 2) == 0) { d_opn->write_io8(1, data); - } +// } break; -#ifdef SUPPORT_PC98_OPNA +#if defined(SUPPORT_PC98_OPNA) case 0x018c: - if((mask & 2) == 0) { - if(mask & 1) { +// if((opna_mask & 2) == 0) { + if(opna_mask & 1) { d_opn->write_io8(2, data); } - } +// } break; case 0x018e: - if((mask & 2) == 0) { - if(mask & 1) { +// if((opna_mask & 2) == 0) { + if(opna_mask & 1) { d_opn->write_io8(3, data); } - } +// } break; case 0xa460: // bit 7-2: Unused // bit 1: Mask OPNA='1' (If set release OPNA). // bit 0: Using YM2608='1' - mask = data; + opna_mask = data; break; #endif -#ifdef _PC98_HAVE_86PCM +#if defined(SUPPORT_PC98_86PCM) case 0xa466: - pcm_volume_reg = data; - // ToDo: Implement volumes + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("OUT\tA466, %02X\tVOLUME\n"), data); + #endif + pcm_vol_ctrl = data; break; case 0xa468: - { - if((pcm_ctrl_reg & 0x80) != (data & 0x80)) { - fifo_enabled = ((data & 0x80) != 0); - //out_debug_log("FIFO : %s\n", (fifo_enabled) ? "ENABLED" : "DISABLED"); - } - if((pcm_ctrl_reg & 0x40) != (data & 0x40)) { - fifo_direction = ((data & 0x40) == 0); // '1' = recording, '0' = playing. - //out_debug_log("Update PCM FIFO TYPE : %s\n", (fifo_direction) ? "PLAY" : "REC"); - } - if((pcm_ctrl_reg & 0x20) != (data & 0x20)) { - fifo_int_flag = ((data & 0x20) != 0); - //out_debug_log("Update PCM FIFO INT-MASK : %s\n", (fifo_int_flag) ? "YES" : "NO"); + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("OUT\tA468, %02X\tFIFO\n"), data); + #endif + if((pcm_fifo_ctrl & 0x87) != (data & 0x87)) { + if(pcm_register_id != -1) { + cancel_event(this, pcm_register_id); + pcm_register_id = -1; } - if(((pcm_ctrl_reg & 0x10) != 0) && ((data & 0x10) == 0)) { - //out_debug_log("PCM CLEAR INTr\n"); - write_signals(&outputs_int_pcm, 0x00000000); - fifo_int_status = false; - } - if((pcm_ctrl_reg & 0x08) != (data & 0x08)) { - if((data & 0x08) != 0) { - //out_debug_log("PCM RESET \n"); - play_w_remain = 0; - play_rptr = 0; - play_wptr = 0; - memset(play_pool, 0x00, sizeof(int32_t) * play_bufsize); - mix_mod = 0; - pcm_fifo->clear(); - } + if(data & 0x80) { + register_event(this, EVENT_SAMPLE, 8000000.0 / sample_rate_x8[data & 7], true, &pcm_register_id); + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Start Event\n")); + #endif + } else { + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Cancel Event\n")); + #endif + pcm_sample_l = pcm_sample_r = 0; } - uint32_t freq; - switch(data & 0x07) { - case 0: - freq = 44100; - break; - case 1: - freq = 33080; - break; - case 2: - freq = 22050; - break; - case 3: - freq = 16540; - break; - case 4: - freq = 11030; - break; - case 5: - freq = 8270; - break; - case 6: - freq = 5520; - break; - case 7: - freq = 4130; - break; + } + if(/*(pcm_fifo_ctrl & 0x10) &&*/ !(data & 0x10)) { + if(pcm_irq_raised) { + pcm_irq_raised = false; + #ifdef SUPPORT_PC98_86PCM_IRQ + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR4, 0, 0); + #endif + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Clear IRQ in A468\n")); + #endif } - if(freq != pcm_freq) { - if(event_pcm >= 0) { - cancel_event(this, event_pcm); - event_pcm = -1; - } - //out_debug_log("Update PCM FREQ=%d\n", freq); - lrclock = false; - pcm_freq = freq; - mix_mod = 0; + } + if((pcm_fifo_ctrl & 0x08) != (data & 0x08)) { + pcm_fifo->clear(); + pcm_fifo_written = false; + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Clear Buffer\n")); + #endif + } + if(!(pcm_fifo_ctrl & 0x20) && (data & 0x20)) { + if(pcm_irq_raised) { + #ifdef SUPPORT_PC98_86PCM_IRQ + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR4, 1, 1); + #endif + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Raise IRQ in A468\n")); + #endif } - if(event_pcm < 0) { - register_event(this, EVENT_PCM, 1.0e6 / (double)(freq * 2), true, &event_pcm); + } else if((pcm_fifo_ctrl & 0x20) && !(data & 0x20)) { + if(pcm_irq_raised) { + #ifdef SUPPORT_PC98_86PCM_IRQ + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR4, 0, 0); + #endif + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("Drop IRQ in A468\n")); + #endif } } - pcm_ctrl_reg = data; + pcm_fifo_ctrl = data; break; case 0xa46a: - if(!fifo_int_flag) { - pcm_is_16bit = ((data & 0x40) == 0); - pcm_l_enabled = ((data & 0x20) != 0); - pcm_r_enabled = ((data & 0x10) != 0); - pcm_da_reg = data; - //out_debug_log("Update PCM TYPE: %s / %s%s\n", (pcm_is_16bit) ? "16bit" : "8bit", (pcm_l_enabled) ? "L" : " ", (pcm_r_enabled) ? "R" : " "); - } else { - if((data & 0xff) == 0xff) { - pcm_da_intleft = 0x7ffc; + if(pcm_fifo_ctrl & 0x20) { + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("OUT\tA46A, %02X\tIRQ\n"), data); + #endif + if(data != 0xff) { + pcm_fifo_size = (data + 1) * 128; } else { - pcm_da_intleft = (int)(((uint32_t)((data & 0xff) + 1)) << 7); + pcm_fifo_size = 0x7ffc; } + } else { + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("OUT\tA46A, %02X\tDAC\n"), data); + #endif + pcm_dac_ctrl = data; } + break; case 0xa46c: - if(pcm_fifo != NULL) { - //out_debug_log("FIFO DATA OUT %02x", data); - //if((fifo_enabled) && (fifo_direction)) { - pcm_fifo->write(data); - //out_debug_log("FIFO DATA OUT %02x", data); - //check_fifo_position(); - //} - } + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("OUT\tA46C, %02X\tBUFFER COUNT=%d\n"), data, pcm_fifo->count() + 1); + #endif + pcm_fifo->write(data); + pcm_fifo_written = true; break; + case 0xa66e: + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("OUT\tA66E, %02X\tMUTE\n"), data); + #endif + pcm_mute_ctrl = data; + break; #endif } } @@ -498,64 +311,89 @@ uint32_t FMSOUND::read_io8(uint32_t addr) { switch(addr) { case 0x0188: - if((mask & 2) == 0) { + //if((opna_mask & 2) == 0) { return d_opn->read_io8(0); - } + //} break; case 0x018a: - if((mask & 2) == 0) { + //if((opna_mask & 2) == 0) { return d_opn->read_io8(1); - } + //} break; -#ifdef SUPPORT_PC98_OPNA +#if defined(SUPPORT_PC98_OPNA) case 0x018c: - if((mask & 2) == 0) { - if(mask & 1) { +// if((mask & 2) == 0) { + if(opna_mask & 1) { return d_opn->read_io8(2); } - } +// } break; case 0x018e: - if((mask & 2) == 0) { - if(mask & 1) { +// if((mask & 2) == 0) { + if(opna_mask & 1) { return d_opn->read_io8(3); } - } +// } break; case 0xa460: // bit 3,2 :(Unused) // bit 1 : YM2608 Masking '1' = masked. // bit 0 : Having OPNA - return BOARD_ID | (mask & 0x0f); + return (BOARD_ID << 4) | (opna_mask & 0x0f); #endif -#ifdef _PC98_HAVE_86PCM +#if defined(SUPPORT_PC98_86PCM) + case 0xa462: + case 0xa464: + return 0; // dummy case 0xa466: { - uint8_t data = 0x00; - if(pcm_fifo != NULL) { - data = data | ((pcm_fifo->full()) ? 0x80 : 0x00); - data = data | ((pcm_fifo->empty()) ? 0x40 : 0x00); - //data = data | ((pcm_fifo->full()) ? 0x80 : 0x00); // WIP: recording - } - data = data | ((lrclock) ? 0x01 : 0x00); - return data; + pcm_clocks += get_passed_clock(pcm_prev_clock); + pcm_prev_clock = get_current_clock(); + pcm_clocks %= get_event_clocks(); + uint32_t passed_samples_x8 = muldiv_u32(sample_rate_x8[pcm_fifo_ctrl & 7], (uint32_t)pcm_clocks, get_event_clocks()); + uint32_t val = (pcm_fifo->full() ? 0x80 : 0) | (pcm_fifo->empty() ? 0x40 : 0) | (pcm_overflow ? 0x20 : 0) | ((passed_samples_x8 & 7) < 4 ? 0 : 0x01); + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("IN\tA466 = %02X\tSTATUS\n"), val); + #endif + return val; } - break; case 0xa468: - pcm_ctrl_reg = pcm_ctrl_reg & (uint8_t)(~0x10); - pcm_ctrl_reg = pcm_ctrl_reg | ((fifo_int_status) ? 0x10 : 0x00); - return pcm_ctrl_reg; - break; + { + uint32_t val = pcm_fifo_ctrl & ~0x10; +/* + if(!pcm_irq_raised) { + if(pcm_fifo_ctrl & 0x20) { + if(pcm_fifo_written && pcm_fifo->count() <= pcm_fifo_size) { + pcm_fifo_written = false; + pcm_irq_raised = true; + } + } + } +*/ + if(pcm_irq_raised) val |= 0x10; + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("IN\tA468 = %02X\tFIFO\n"), val); + #endif + return val; + } case 0xa46a: - return pcm_da_reg; - break; + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("IN\tA46A = %02X\tDAC\n"), pcm_dac_ctrl); + #endif + return pcm_dac_ctrl; case 0xa46c: - //if((fifo_enabled) && !(fifo_direction)) { - uint8_t data = pcm_fifo->read(); - // check_fifo_position(); - return (uint32_t)data; - //} - break; + { + uint32_t val = /*0;*/ pcm_fifo->read(); + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("IN\tA46C = %02X\tBUFFER COUNT = %d\n"), val, pcm_fifo->count()); + #endif + return val; + } + case 0xa66e: + #ifdef _PCM_DEBUG_LOG + this->out_debug_log(_T("IN\tA66E = %02X\tMUTE\n"), pcm_mute_ctrl); + #endif + return pcm_mute_ctrl; #endif } return 0xff; @@ -563,8 +401,10 @@ uint32_t FMSOUND::read_io8(uint32_t addr) void FMSOUND::set_volume(int ch, int decibel_l, int decibel_r) { - volume_l = decibel_to_volume(decibel_l); - volume_r = decibel_to_volume(decibel_r); +#if defined(SUPPORT_PC98_86PCM) + pcm_volume_l = decibel_to_volume(decibel_l); + pcm_volume_r = decibel_to_volume(decibel_r); +#endif } void FMSOUND::initialize_sound(int rate, int samples) @@ -572,7 +412,8 @@ void FMSOUND::initialize_sound(int rate, int samples) sample_rate = rate; sample_samples = samples; } - + +#if defined(SUPPORT_PC98_OPNA) #define STATE_VERSION 2 bool FMSOUND::process_state(FILEIO* state_fio, bool loading) @@ -583,39 +424,29 @@ bool FMSOUND::process_state(FILEIO* state_fio, bool loading) if(!state_fio->StateCheckInt32(this_device_id)) { return false; } -#ifdef _PC98_HAVE_86PCM - if(!(pcm_fifo->process_state(state_fio, loading))) { +#if defined(SUPPORT_PC98_OPNA) + state_fio->StateValue(opna_mask); +#if defined(SUPPORT_PC98_86PCM) + state_fio->StateValue(pcm_clocks); + state_fio->StateValue(pcm_prev_clock); + state_fio->StateValue(pcm_vol_ctrl); + state_fio->StateValue(pcm_fifo_ctrl); + state_fio->StateValue(pcm_dac_ctrl); + state_fio->StateValue(pcm_fifo_size); + state_fio->StateValue(pcm_mute_ctrl); + state_fio->StateValue(pcm_fifo_written); + state_fio->StateValue(pcm_overflow); + state_fio->StateValue(pcm_irq_raised); + if(!pcm_fifo->process_state((void *)state_fio, loading)) { return false; } + state_fio->StateValue(pcm_register_id); + state_fio->StateValue(pcm_sample_l); + state_fio->StateValue(pcm_sample_r); #endif - state_fio->StateValue(mask); -#ifdef _PC98_HAVE_86PCM - state_fio->StateValue(pcm_ctrl_reg); - state_fio->StateValue(pcm_da_reg); - state_fio->StateValue(pcm_volume_reg); - state_fio->StateValue(pcm_data); - state_fio->StateValue(pcm_freq); - - state_fio->StateValue(fifo_enabled); - state_fio->StateValue(fifo_direction); - state_fio->StateValue(fifo_int_flag); - state_fio->StateValue(fifo_int_status); - - state_fio->StateValue(lrclock); - state_fio->StateValue(pcm_is_16bit); - state_fio->StateValue(pcm_l_enabled); - state_fio->StateValue(pcm_r_enabled); - state_fio->StateValue(pcm_da_intleft); - - state_fio->StateValue(play_w_remain); - state_fio->StateValue(play_rptr); - state_fio->StateValue(play_wptr); - state_fio->StateValue(mix_mod); - state_fio->StateValue(event_pcm); - - state_fio->StateArray(play_pool, sizeof(play_pool), 1); #endif return true; } +#endif } diff --git a/source/src/vm/pc9801/fmsound.h b/source/src/vm/pc9801/fmsound.h index 433f9f6bb..9f64f00e5 100644 --- a/source/src/vm/pc9801/fmsound.h +++ b/source/src/vm/pc9801/fmsound.h @@ -14,7 +14,7 @@ Author : Takeda.Toshiya Date : 2012.02.03- - [ PC-9801-26 ] + [ PC-9801-26/86 ] */ #ifndef _FMSOUND_H_ @@ -24,14 +24,10 @@ #include "../../emu.h" #include "../device.h" -#if defined(_PC98DOPLUS) || defined(_PC98GS) || defined(SUPPORT_PC98_OPNA) -#define _PC98_SUPPORT_EXTRA_SOUND -#define _PC98_HAVE_86PCM -#endif - -#ifdef _PC98_HAVE_86PCM +#ifdef SUPPORT_PC98_OPNA class FIFO; #endif + namespace PC9801 { class FMSOUND : public DEVICE @@ -40,40 +36,23 @@ class FMSOUND : public DEVICE DEVICE* d_opn; outputs_t outputs_int_pcm; - uint8_t mask; -#ifdef _PC98_HAVE_86PCM - FIFO* pcm_fifo; - - // ToDo: Implement volumes - uint8_t pcm_volume_reg; - uint8_t pcm_ctrl_reg; - uint8_t pcm_da_reg; - pair32_t pcm_data; +#if defined(SUPPORT_PC98_OPNA) + uint8_t opna_mask; +#if defined(SUPPORT_PC98_86PCM) + DEVICE *d_pic; + uint64_t pcm_clocks; + uint32_t pcm_prev_clock; + uint8_t pcm_vol_ctrl, pcm_fifo_ctrl, pcm_dac_ctrl, pcm_mute_ctrl; + int pcm_fifo_size; + bool pcm_fifo_written, pcm_overflow, pcm_irq_raised; + FIFO *pcm_fifo; + int pcm_register_id; + int pcm_sample_l, pcm_sample_r; + int pcm_volume, pcm_volume_l, pcm_volume_r; - bool fifo_enabled; - bool fifo_direction; - bool fifo_int_flag; - bool fifo_int_status; - bool fifo_reset_req; - - uint32_t pcm_freq; - bool lrclock; - bool pcm_is_16bit; - bool pcm_l_enabled; - bool pcm_r_enabled; - int pcm_da_intleft; - - int mix_mod; - - int play_bufsize; - int play_w_remain; - int play_rptr; - int play_wptr; - int32_t play_pool[65536]; // Internal buffer - - int event_pcm; + int get_sample(); +#endif #endif - int sample_rate; int sample_samples; int volume_r; @@ -81,10 +60,10 @@ class FMSOUND : public DEVICE void check_fifo_position(); public: - FMSOUND(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FMSOUND(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_int_pcm); -#ifdef SUPPORT_PC98_OPNA +#if defined(SUPPORT_PC98_OPNA) set_device_name(_T("PC-9801-86 (FM Sound)")); #else set_device_name(_T("PC-9801-26 (FM Sound)")); @@ -98,12 +77,13 @@ class FMSOUND : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - bool process_state(FILEIO* state_fio, bool loading); - void mix(int32_t* buffer, int cnt); - void event_callback(int id, int err); + void __FASTCALL mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int id, int err); void set_volume(int ch, int decibel_l, int decibel_r); void initialize_sound(int rate, int samples); - +#if defined(SUPPORT_PC98_OPNA) + bool process_state(FILEIO* state_fio, bool loading); +#endif // unique function void set_context_opn(DEVICE* device) { @@ -113,6 +93,17 @@ class FMSOUND : public DEVICE { register_output_signal(&outputs_int_pcm, device, id, mask); } +#if defined(SUPPORT_PC98_OPNA) && defined(SUPPORT_PC98_86PCM) + void set_context_pic(DEVICE* device) + { + d_pic = device; + } + void initialize_sound(int rate, int frequency, int volume) + { + pcm_volume = volume; + initialize_sound(rate, frequency); + } +#endif }; } diff --git a/source/src/vm/pc9801/joystick.h b/source/src/vm/pc9801/joystick.h index f1687152f..89aeaacb8 100644 --- a/source/src/vm/pc9801/joystick.h +++ b/source/src/vm/pc9801/joystick.h @@ -37,7 +37,7 @@ class JOYSTICK : public DEVICE uint8_t select; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/pc9801/keyboard.h b/source/src/vm/pc9801/keyboard.h index e3e6d3dbb..83cf10609 100644 --- a/source/src/vm/pc9801/keyboard.h +++ b/source/src/vm/pc9801/keyboard.h @@ -37,7 +37,7 @@ class KEYBOARD : public DEVICE uint8_t flag[256]; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/pc9801/membus.cpp b/source/src/vm/pc9801/membus.cpp index 1ea8a36c3..c8105f699 100644 --- a/source/src/vm/pc9801/membus.cpp +++ b/source/src/vm/pc9801/membus.cpp @@ -140,10 +140,19 @@ void MEMBUS::initialize() // EXT BIOS #if defined(_PC9801) || defined(_PC9801E) memset(fd_bios_2hd, 0xff, sizeof(fd_bios_2hd)); - read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd)); + if(config.dipswitch & 1) { + read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd)); + } +// read_bios(_T("2HDIF.ROM"), fd_bios_2hd, sizeof(fd_bios_2hd)); memset(fd_bios_2dd, 0xff, sizeof(fd_bios_2dd)); - read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd)); + if(config.dipswitch & 2) { + read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd)); + } +// read_bios(_T("2DDIF.ROM"), fd_bios_2dd, sizeof(fd_bios_2dd)); + + set_memory_r(0xd6000, 0xd6fff, fd_bios_2dd); + set_memory_r(0xd7000, 0xd7fff, fd_bios_2hd); #endif memset(sound_bios, 0xff, sizeof(sound_bios)); // memset(sound_bios_ram, 0x00, sizeof(sound_bios_ram)); diff --git a/source/src/vm/pc9801/membus.h b/source/src/vm/pc9801/membus.h index 831ff02fd..56a90608d 100644 --- a/source/src/vm/pc9801/membus.h +++ b/source/src/vm/pc9801/membus.h @@ -20,6 +20,7 @@ #ifndef _MEMBUS_H_ #define _MEMBUS_H_ +#include "../vm.h" #include "../memory.h" namespace PC9801 { @@ -140,6 +141,7 @@ class MEMBUS : public MEMORY uint32_t window_80000h; uint32_t window_a0000h; #endif +// inline bool __FASTCALL get_memory_addr(uint32_t *addr); void config_intram(); void update_bios_mainmem(); void update_bios_ipl_and_itf(); @@ -147,7 +149,7 @@ class MEMBUS : public MEMORY void __FASTCALL update_bios_window(uint32_t window_addr, uint32_t begin); public: - MEMBUS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu) + MEMBUS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MEMORY(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } @@ -161,6 +163,13 @@ class MEMBUS : public MEMORY void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) + // ToDo: Re-Implement. +// uint32_t __FASTCALL read_data8(uint32_t addr); +// void __FASTCALL write_data8(uint32_t addr, uint32_t data); +// uint32_t __FASTCALL read_data16(uint32_t addr); +// void __FASTCALL write_data16(uint32_t addr, uint32_t data); +// uint32_t __FASTCALL read_data32(uint32_t addr); +// void __FASTCALL write_data32(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_dma_data8(uint32_t addr); void __FASTCALL write_dma_data8(uint32_t addr, uint32_t data); #endif diff --git a/source/src/vm/pc9801/mouse.cpp b/source/src/vm/pc9801/mouse.cpp index a2f2c2200..59dfe3ed0 100644 --- a/source/src/vm/pc9801/mouse.cpp +++ b/source/src/vm/pc9801/mouse.cpp @@ -75,7 +75,11 @@ uint32_t MOUSE::read_io8(uint32_t addr) void MOUSE::event_callback(int event_id, int err) { if(!(ctrlreg & 0x10)) { - d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR5, 1, 1); + #if !defined(SUPPORT_HIRESO) + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR5, 1, 1); + #else + d_pic->write_signal(SIG_I8259_CHIP0 | SIG_I8259_IR6, 1, 1); + #endif } if(cur_freq != (freq & 3)) { cancel_event(this, register_id); diff --git a/source/src/vm/pc9801/mouse.h b/source/src/vm/pc9801/mouse.h index c5d04c2a3..cd0710a73 100644 --- a/source/src/vm/pc9801/mouse.h +++ b/source/src/vm/pc9801/mouse.h @@ -41,7 +41,7 @@ class MOUSE : public DEVICE void update_mouse(); public: - MOUSE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MOUSE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Mouse I/F")); } @@ -54,7 +54,7 @@ class MOUSE : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); #endif - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_frame(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc9801/pc9801.cpp b/source/src/vm/pc9801/pc9801.cpp index d1ffde4cf..2c1ac0965 100644 --- a/source/src/vm/pc9801/pc9801.cpp +++ b/source/src/vm/pc9801/pc9801.cpp @@ -21,18 +21,17 @@ #include "../../emu.h" #include "../device.h" - -#if defined(UPPER_I386) -#include "../i386.h" -#elif defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) -#include "../i86.h" -#elif defined(HAS_V30) -#include "../v30.h" -#else +#if defined(HAS_I386) || defined(HAS_I486SX) || defined(HAS_I486DX) || defined(UPPER_I386) +#include "../i386_np21.h" +//#include "../i386.h" +#elif defined(HAS_I286) +//#include "../i286_np21.h" #include "../i286.h" +#else +#include "../i86.h" #endif -#if defined(HAS_V30_SUB_CPU) -#include "../v30.h" +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) +#include "../i86.h" #endif #include "../event.h" @@ -143,7 +142,7 @@ using PC88DEV::PC88; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // check configs #if defined(_PC98DO) || defined(_PC98DOPLUS) @@ -196,41 +195,40 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pio_prn = new I8255(this, emu); // for printer pio_prn->set_device_name(_T("8255 PIO (Printer)")); pic = new I8259(this, emu); -#if defined(UPPER_I386) - cpu = new I386(this, emu); // 80386, 80486 -#elif defined(HAS_V30) - cpu = new V30(this, emu); // Secondary CPU -// subcpu = NULL; -#elif defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) - cpu = new I8086(this, emu);// 8086, V30, 80286 -// subcpu = NULL; -#else - cpu = new I80286(this, emu); -#endif -#if defined(HAS_V30_SUB_CPU) - v30cpu = new V30(this, emu); // Secondary CPU -#endif #if defined(HAS_I86) - cpu->set_device_name(_T("CPU(i8086)")); -#elif defined(HAS_I386) - cpu->set_device_name(_T("CPU(i386)")); -#elif defined(HAS_I486) - cpu->set_device_name(_T("CPU(i486)")); -#elif defined(HAS_PENTIUM) - cpu->set_device_name(_T("CPU(Pentium)")); -#elif defined(HAS_V33A) - cpu->set_device_name(_T("CPU(V33A)")); + cpu = new I86(this, emu); + cpu->device_model = INTEL_8086; #elif defined(HAS_V30) - cpu->set_device_name(_T("CPU(V30)")); -#else - cpu->set_device_name(_T("CPU(i286)")); -#endif + cpu = new I86(this, emu); + cpu->device_model = NEC_V30; +#elif defined(HAS_I286) + cpu = new I286(this, emu); +// cpu->device_model = INTEL_80286; +#elif defined(HAS_I386) + cpu = new I386(this, emu); + cpu->device_model = INTEL_80386; +#elif defined(HAS_I486SX) + cpu = new I386(this, emu); + cpu->device_model = INTEL_I486SX; +#elif defined(HAS_I486DX) + cpu = new I386(this, emu); + cpu->device_model = INTEL_I486DX; +#endif +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) + if((config.dipswitch & (1 << DIPSWITCH_POSITION_USE_V30)) != 0) { // You should add manual + v30 = new I86(this, emu); + v30->device_model = NEC_V30; + } else { + v30 = NULL; + } +#endif io = new IO(this, emu); rtcreg = new LS244(this, emu); rtcreg->set_device_name(_T("74LS244 (RTC)")); //memory = new MEMORY(this, emu); memory = new MEMBUS(this, emu); + not_busy = new NOT(this, emu); not_busy->set_device_name(_T("NOT Gate (Printer Busy)")); #if defined(HAS_I86) || defined(HAS_V30) @@ -239,12 +237,28 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #endif rtc = new UPD1990A(this, emu); #if defined(SUPPORT_2HD_FDD_IF) - fdc_2hd = new UPD765A(this, emu); - fdc_2hd->set_device_name(_T("uPD765A FDC (2HD I/F)")); +#if defined(_PC9801) || defined(_PC9801E) + if((config.dipswitch & 1) && FILEIO::IsFileExisting(create_local_path(_T("2HDIF.ROM")))) { +#endif + fdc_2hd = new UPD765A(this, emu); + fdc_2hd->set_device_name(_T("uPD765A FDC (2HD I/F)")); +#if defined(_PC9801) || defined(_PC9801E) + } else { + fdc_2hd = NULL; + } +#endif #endif #if defined(SUPPORT_2DD_FDD_IF) - fdc_2dd = new UPD765A(this, emu); - fdc_2dd->set_device_name(_T("uPD765A FDC (2DD I/F)")); +#if defined(_PC9801) || defined(_PC9801E) + if((config.dipswitch & 2) && FILEIO::IsFileExisting(create_local_path(_T("2DDIF.ROM")))) { +#endif + fdc_2dd = new UPD765A(this, emu); + fdc_2dd->set_device_name(_T("uPD765A FDC (2DD I/F)")); +#if defined(_PC9801) || defined(_PC9801E) + } else { + fdc_2dd = NULL; + } +#endif #endif #if defined(SUPPORT_2HD_2DD_FDD_IF) fdc = new UPD765A(this, emu); @@ -337,14 +351,21 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #if defined(SUPPORT_320KB_FDD_IF) // 320kb fdd drives - pio_sub = new I8255(this, emu); - pio_sub->set_device_name(_T("8255 PIO (320KB FDD)")); - pc80s31k = new PC80S31K(this, emu); - pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)")); - fdc_sub = new UPD765A(this, emu); - fdc_sub->set_device_name(_T("uPD765A FDC (320KB FDD)")); - cpu_sub = new Z80(this, emu); - cpu_sub->set_device_name(_T("Z80 CPU (320KB FDD)")); + if((config.dipswitch & 4) && (FILEIO::IsFileExisting(create_local_path(_T("DISK.ROM"))) || FILEIO::IsFileExisting(create_local_path(_T("PC88.ROM"))))) { + pio_sub = new I8255(this, emu); + pio_sub->set_device_name(_T("8255 PIO (320KB FDD)")); + pc80s31k = new PC80S31K(this, emu); + pc80s31k->set_device_name(_T("PC-80S31K (320KB FDD)")); + fdc_sub = new UPD765A(this, emu); + fdc_sub->set_device_name(_T("uPD765A FDC (320KB FDD)")); + cpu_sub = new Z80(this, emu); + cpu_sub->set_device_name(_T("Z80 CPU (320KB FDD)")); + } else { + pio_sub = NULL; + pc80s31k = NULL; + fdc_sub = NULL; + cpu_sub = NULL; + } #endif /* IRQ 0 PIT @@ -353,14 +374,14 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) 3 (INT0) 4 RS-232C 5 (INT1) - 6 (INT2) + 6 (INT2) MOUSE (HIRESO) 7 SLAVE PIC - 8 PRINTER + 8 PRINTER (8086,V30) or FPU 9 (INT3) PC-9801-27 (SASI), PC-9801-55 (SCSI), or IDE 10 (INT41) FDC (640KB I/F) 11 (INT42) FDC (1MB I/F) - 12 (INT5) PC-9801-26(K) or PC-9801-14 - 13 (INT6) MOUSE + 12 (INT5) PC-9801-26(K)/86 or PC-9801-14 + 13 (INT6) MOUSE (STANDARD) 14 15 (RESERVED) */ @@ -368,21 +389,28 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // set contexts #if defined(UPPER_I386) + // ToDo: Implement cpu->set_context_extreset(cpureg, SIG_CPUREG_RESET, 0xffffffff); #endif event->set_context_cpu(cpu, cpu_clocks); -#if defined(HAS_V30_SUB_CPU) - if((config.dipswitch & (1 << DIPSWITCH_POSITION_CPU_MODE)) != 0) { // You should add manually. - event->set_context_cpu(v30cpu, 7987248); +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) + if((config.dipswitch & (1 << DIPSWITCH_POSITION_USE_V30)) != 0) { // You should add manually. + if(v30 != NULL) { + event->set_context_cpu(v30, 9984060); + } } #endif #if defined(SUPPORT_320KB_FDD_IF) - event->set_context_cpu(cpu_sub, 4000000); + if(cpu_sub) { + event->set_context_cpu(cpu_sub, 4000000); + } #endif event->set_context_sound(beep); if(sound_type == 0 || sound_type == 1) { event->set_context_sound(opn); +#if defined(SUPPORT_PC98_OPNA) && defined(SUPPORT_PC98_86PCM) event->set_context_sound(fmsound); +#endif } else if(sound_type == 2 || sound_type == 3) { event->set_context_sound(tms3631); } @@ -394,12 +422,16 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) // dma ch.0: sasi // dma ch.1: memory refresh #if defined(SUPPORT_2HD_FDD_IF) - dma->set_context_ch2(fdc_2hd); - dma->set_context_tc2(fdc_2hd, SIG_UPD765A_TC, 1); + if(fdc_2hd) { + dma->set_context_ch2(fdc_2hd); + dma->set_context_tc2(fdc_2hd, SIG_UPD765A_TC, 1); + } #endif #if defined(SUPPORT_2DD_FDD_IF) - dma->set_context_ch3(fdc_2dd); - dma->set_context_tc3(fdc_2dd, SIG_UPD765A_TC, 1); + if(fdc_2dd) { + dma->set_context_ch3(fdc_2dd); + dma->set_context_tc3(fdc_2dd, SIG_UPD765A_TC, 1); + } #endif #if defined(SUPPORT_2HD_2DD_FDD_IF) #if !defined(SUPPORT_HIRESO) @@ -428,6 +460,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pio_mouse->set_context_port_c(mouse, SIG_MOUSE_PORT_C, 0xf0, 0); #if defined(SUPPORT_HIRESO) // sysport port.c bit7,5: sysport port.b bit4,3 +// pio_sys->set_context_port_b(pio_sys, SIG_I8255_PORT_C, 0x10, +3); // SHUT0 +// pio_sys->set_context_port_b(pio_sys, SIG_I8255_PORT_C, 0x08, +2); // SHUT1 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x80, -3); // SHUT0 pio_sys->set_context_port_c(pio_sys, SIG_I8255_PORT_B, 0x20, -2); // SHUT1 #endif @@ -462,7 +496,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) rtcreg->set_context_output(rtc, SIG_UPD1990A_DIN, 0x20, 0); rtcreg->set_context_output(rtc, SIG_UPD1990A_STB, 0x08, 0); rtcreg->set_context_output(rtc, SIG_UPD1990A_CLK, 0x10, 0); -#if defined(HAS_V30_SUB_CPU) +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) pic->set_context_cpu(cpureg); #else pic->set_context_cpu(cpu); @@ -473,7 +507,10 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) opn->set_context_irq(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1); opn->set_context_port_b(joystick, SIG_JOYSTICK_SELECT, 0xc0, 0); fmsound->set_context_opn(opn); - fmsound->set_context_pcm_int(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1); // OK? +#if defined(SUPPORT_PC98_OPNA) && defined(SUPPORT_PC98_86PCM) + fmsound->set_context_pic(pic); +#endif +// fmsound->set_context_pcm_int(pic, SIG_I8259_CHIP1 | SIG_I8259_IR4, 1); // OK? joystick->set_context_opn(opn); } else if(sound_type == 2 || sound_type == 3) { @@ -487,19 +524,27 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) cpureg->set_context_cpu(cpu); - cpureg->set_context_membus(memory); - cpureg->set_context_piosys(pio_sys); +#if !defined(SUPPORT_HIRESO) + cpureg->set_context_v30(v30); + cpureg->set_context_pio(pio_prn); + cpureg->cpu_mode = ((config.dipswitch & (1 << DIPSWITCH_POSITION_CPU_MODE)) != 0); +#endif +// cpureg->set_context_membus(memory); +// cpureg->set_context_piosys(pio_sys); #if defined(HAS_V30_SUB_CPU) - cpureg->set_context_v30(v30cpu); - cpureg->set_context_cputype(pio_prn, SIG_I8255_PORT_B, 0x02, 0); +// if((config.dipswitch & ((0x1) << DIPSWITCH_POSITION_USE_V30)) != 0) { +// cpureg->set_context_v30(v30); +// cpureg->set_context_cputype(pio_prn, SIG_I8255_PORT_B, 0x02, 0); +// } #endif #endif display->set_context_pic(pic); display->set_context_gdc_chr(gdc_chr, gdc_chr->get_ra()); display->set_context_gdc_gfx(gdc_gfx, gdc_gfx->get_ra(), gdc_gfx->get_cs()); display->set_context_gdc_freq(pio_sys, SIG_I8255_PORT_A, 0x80); + //pio_sys->set_context_port_b(display, SIG_DISPLAY98_HIGH_RESOLUTION, 0x08, 0); // SHUT1 - //display->set_context_pio_prn(pio_prn); + display->set_context_pio_prn(pio_prn); dmareg->set_context_dma(dma); keyboard->set_context_sio(sio_kbd); @@ -508,21 +553,25 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) mouse->set_context_pio(pio_mouse); #if defined(SUPPORT_2HD_FDD_IF) - fdc_2hd->set_context_irq(floppy, SIG_FLOPPY_2HD_IRQ, 1); - fdc_2hd->set_context_drq(floppy, SIG_FLOPPY_2HD_DRQ, 1); - fdc_2hd->set_context_noise_seek(noise_seek); - fdc_2hd->set_context_noise_head_down(noise_head_down); - fdc_2hd->set_context_noise_head_up(noise_head_up); - fdc_2hd->raise_irq_when_media_changed = true; + if(fdc_2hd) { + fdc_2hd->set_context_irq(floppy, SIG_FLOPPY_2HD_IRQ, 1); + fdc_2hd->set_context_drq(floppy, SIG_FLOPPY_2HD_DRQ, 1); + fdc_2hd->set_context_noise_seek(noise_seek); + fdc_2hd->set_context_noise_head_down(noise_head_down); + fdc_2hd->set_context_noise_head_up(noise_head_up); + fdc_2hd->raise_irq_when_media_changed = true; + } floppy->set_context_fdc_2hd(fdc_2hd); #endif #if defined(SUPPORT_2DD_FDD_IF) - fdc_2dd->set_context_irq(floppy, SIG_FLOPPY_2DD_IRQ, 1); - fdc_2dd->set_context_drq(floppy, SIG_FLOPPY_2DD_DRQ, 1); - fdc_2dd->set_context_noise_seek(noise_seek); - fdc_2dd->set_context_noise_head_down(noise_head_down); - fdc_2dd->set_context_noise_head_up(noise_head_up); - fdc_2dd->raise_irq_when_media_changed = true; + if(fdc_2dd) { + fdc_2dd->set_context_irq(floppy, SIG_FLOPPY_2DD_IRQ, 1); + fdc_2dd->set_context_drq(floppy, SIG_FLOPPY_2DD_DRQ, 1); + fdc_2dd->set_context_noise_seek(noise_seek); + fdc_2dd->set_context_noise_head_down(noise_head_down); + fdc_2dd->set_context_noise_head_up(noise_head_up); + fdc_2dd->raise_irq_when_media_changed = true; + } floppy->set_context_fdc_2dd(fdc_2dd); #endif #if defined(SUPPORT_2HD_2DD_FDD_IF) @@ -541,31 +590,42 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #if !defined(SUPPORT_HIRESO) sasi_host->set_context_irq(pio_sys, SIG_I8255_PORT_B, 0x10); #endif - sasi_host->set_context_irq(sasi, SIG_SASI_IRQ, 1); - sasi_host->set_context_drq(sasi, SIG_SASI_DRQ, 1); +// sasi_host->set_context_irq(sasi, SIG_SASI_IRQ, 1); +// sasi_host->set_context_drq(sasi, SIG_SASI_DRQ, 1); + sasi_host->set_context_bsy(sasi, SIG_SASI_BSY, 1); + sasi_host->set_context_cd (sasi, SIG_SASI_CXD, 1); + sasi_host->set_context_io (sasi, SIG_SASI_IXO, 1); + sasi_host->set_context_msg(sasi, SIG_SASI_MSG, 1); + sasi_host->set_context_req(sasi, SIG_SASI_REQ, 1); + sasi_host->set_context_ack(sasi, SIG_SASI_ACK, 1); #ifdef _PC98XA - dma->set_context_ch3(sasi_host); - dma->set_context_tc3(sasi, SIG_SASI_TC, 1); +// dma->set_context_ch3(sasi_host); +// dma->set_context_tc3(sasi, SIG_SASI_TC, 1); + dma->set_context_ch3(sasi); + dma->set_context_tc3(sasi, SIG_SASI_TC, 1); #else - dma->set_context_ch0(sasi_host); - dma->set_context_tc0(sasi, SIG_SASI_TC, 1); +// dma->set_context_ch0(sasi_host); + dma->set_context_ch0(sasi); + dma->set_context_tc0(sasi, SIG_SASI_TC, 1); #endif sasi->set_context_host(sasi_host); sasi->set_context_hdd(sasi_hdd); sasi->set_context_dma(dma); sasi->set_context_pic(pic); + #if !defined(SUPPORT_HIRESO) + sasi->set_context_pio(pio_sys); + #endif sasi_bios->set_context_sasi(sasi); sasi_bios->set_context_memory(memory); sasi_bios->set_context_cpu(cpu); - #if defined(HAS_V30_SUB_CPU) - sasi_bios->set_context_v30cpu(v30cpu); - #endif sasi_bios->set_context_pic(pic); sasi_bios->set_context_cpureg(cpureg); cpu->set_context_bios(sasi_bios); - #if defined(HAS_V30_SUB_CPU) - v30cpu->set_context_bios(sasi_bios); + #if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) + if(v30 != NULL) { + v30->set_context_bios(sasi_bios); + } #endif #endif @@ -579,6 +639,19 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) ide->set_context_dma(dma); ide->set_context_pic(pic); #endif +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) + if(v30 != NULL) { + v30->set_context_mem(memory); + v30->set_context_io(io); + v30->set_context_intr(pic); +#ifdef SINGLE_MODE_DMA + v30->set_context_dma(dma); +#endif +#ifdef USE_DEBUGGER + v30->set_context_debugger(new DEBUGGER(this, emu)); +#endif + } +#endif #if defined(SUPPORT_CMT_IF) sio_cmt->set_context_out(cmt, SIG_CMT_OUT); @@ -592,6 +665,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) cpu->set_context_mem(memory); cpu->set_context_io(io); cpu->set_context_intr(pic); + #ifdef SINGLE_MODE_DMA cpu->set_context_dma(dma); #endif @@ -599,44 +673,34 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) cpu->set_context_debugger(new DEBUGGER(this, emu)); #endif -#if defined(HAS_V30_SUB_CPU) - // cpu bus - v30cpu->set_context_mem(memory); - v30cpu->set_context_io(io); - v30cpu->set_context_intr(pic); - #ifdef SINGLE_MODE_DMA - //v30cpu->set_context_dma(dma); // DMA may be within MAIN CPU. - #endif - #ifdef USE_DEBUGGER - v30cpu->set_context_debugger(new DEBUGGER(this, emu)); - #endif -#endif #if defined(SUPPORT_320KB_FDD_IF) // 320kb fdd drives - pc80s31k->set_context_cpu(cpu_sub); - pc80s31k->set_context_fdc(fdc_sub); - pc80s31k->set_context_pio(pio_sub); - pio_fdd->set_context_port_a(pio_sub, SIG_I8255_PORT_A, 0xff, 0); - pio_fdd->set_context_port_b(pio_sub, SIG_I8255_PORT_A, 0xff, 0); - pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0x0f, 4); - pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0xf0, -4); - pio_fdd->clear_ports_by_cmdreg = true; - pio_sub->set_context_port_a(pio_fdd, SIG_I8255_PORT_B, 0xff, 0); - pio_sub->set_context_port_b(pio_fdd, SIG_I8255_PORT_A, 0xff, 0); - pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0x0f, 4); - pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4); - pio_sub->clear_ports_by_cmdreg = true; - fdc_sub->set_context_irq(cpu_sub, SIG_CPU_IRQ, 1); - fdc_sub->set_context_noise_seek(noise_seek); - fdc_sub->set_context_noise_head_down(noise_head_down); - fdc_sub->set_context_noise_head_up(noise_head_up); - cpu_sub->set_context_mem(pc80s31k); - cpu_sub->set_context_io(pc80s31k); - cpu_sub->set_context_intr(pc80s31k); + if(pc80s31k && pio_sub && fdc_sub && cpu_sub) { + pc80s31k->set_context_cpu(cpu_sub); + pc80s31k->set_context_fdc(fdc_sub); + pc80s31k->set_context_pio(pio_sub); + pio_fdd->set_context_port_a(pio_sub, SIG_I8255_PORT_B, 0xff, 0); + pio_fdd->set_context_port_b(pio_sub, SIG_I8255_PORT_A, 0xff, 0); + pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0x0f, 4); + pio_fdd->set_context_port_c(pio_sub, SIG_I8255_PORT_C, 0xf0, -4); + pio_fdd->clear_ports_by_cmdreg = true; + pio_sub->set_context_port_a(pio_fdd, SIG_I8255_PORT_B, 0xff, 0); + pio_sub->set_context_port_b(pio_fdd, SIG_I8255_PORT_A, 0xff, 0); + pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0x0f, 4); + pio_sub->set_context_port_c(pio_fdd, SIG_I8255_PORT_C, 0xf0, -4); + pio_sub->clear_ports_by_cmdreg = true; + fdc_sub->set_context_irq(cpu_sub, SIG_CPU_IRQ, 1); + fdc_sub->set_context_noise_seek(noise_seek); + fdc_sub->set_context_noise_head_down(noise_head_down); + fdc_sub->set_context_noise_head_up(noise_head_up); + cpu_sub->set_context_mem(pc80s31k); + cpu_sub->set_context_io(pc80s31k); + cpu_sub->set_context_intr(pc80s31k); #ifdef USE_DEBUGGER - cpu_sub->set_context_debugger(new DEBUGGER(this, emu)); + cpu_sub->set_context_debugger(new DEBUGGER(this, emu)); #endif + } #endif // i/o bus @@ -709,7 +773,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io->set_iomap_single_r(0x005d, cpureg); io->set_iomap_single_r(0x005e, cpureg); io->set_iomap_single_rw(0x005f, cpureg); - #endif #if defined(SUPPORT_320KB_FDD_IF) @@ -718,9 +781,6 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io->set_iomap_alias_rw(0x0055, pio_fdd, 2); io->set_iomap_alias_w (0x0057, pio_fdd, 3); #endif -#if defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS) - io->set_iomap_range_r(0x005c, 0x005f, cpureg); // TimeStamp -#endif io->set_iomap_alias_rw(0x0060, gdc_chr, 0); io->set_iomap_alias_rw(0x0062, gdc_chr, 1); @@ -798,10 +858,16 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io->set_iomap_alias_rw(0x0075, pit, 2); io->set_iomap_alias_w (0x0077, pit, 3); - io->set_iomap_single_rw(0x0090, floppy); - io->set_iomap_single_rw(0x0092, floppy); - io->set_iomap_single_rw(0x0094, floppy); - io->set_iomap_single_rw(0x0096, floppy); +#if defined(SUPPORT_2HD_FDD_IF) + if(fdc_2hd) { +#endif + io->set_iomap_single_rw(0x0090, floppy); + io->set_iomap_single_rw(0x0092, floppy); + io->set_iomap_single_rw(0x0094, floppy); + io->set_iomap_single_rw(0x0096, floppy); +#if defined(SUPPORT_2HD_FDD_IF) + } +#endif #if defined(SUPPORT_2HD_2DD_FDD_IF) #if !defined(SUPPORT_HIRESO) io->set_iomap_single_rw(0x00bc, floppy); @@ -813,10 +879,16 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) #endif #endif #if !defined(SUPPORT_HIRESO) - io->set_iomap_single_rw(0x00c8, floppy); - io->set_iomap_single_rw(0x00ca, floppy); - io->set_iomap_single_rw(0x00cc, floppy); -// io->set_iomap_single_rw(0x00ce, floppy); // OK? 20190516 K.O +#if defined(SUPPORT_2DD_FDD_IF) + if(fdc_2dd) { +#endif + io->set_iomap_single_rw(0x00c8, floppy); + io->set_iomap_single_rw(0x00ca, floppy); + io->set_iomap_single_rw(0x00cc, floppy); + io->set_iomap_single_rw(0x00ce, floppy); // OK? 20190516 K.O +#if defined(SUPPORT_2DD_FDD_IF) + } +#endif #endif #if defined(SUPPORT_CMT_IF) @@ -837,16 +909,18 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) if(sound_type == 0 || sound_type == 1) { io->set_iomap_single_rw(0x0188, fmsound); io->set_iomap_single_rw(0x018a, fmsound); -#ifdef SUPPORT_PC98_OPNA +#if defined(SUPPORT_PC98_OPNA) io->set_iomap_single_rw(0x018c, fmsound); io->set_iomap_single_rw(0x018e, fmsound); +#if defined(SUPPORT_PC98_86PCM) io->set_iomap_single_rw(0xa460, fmsound); - io->set_iomap_single_rw(0xa460, fmsound); + io->set_iomap_single_rw(0xa462, fmsound); io->set_iomap_single_rw(0xa466, fmsound); io->set_iomap_single_rw(0xa468, fmsound); io->set_iomap_single_rw(0xa46a, fmsound); io->set_iomap_single_rw(0xa46c, fmsound); - //io->set_iomap_single_rw(0xa46e, fmsound); + io->set_iomap_single_rw(0xa66e, fmsound); +#endif #endif } else if(sound_type == 2 || sound_type == 3) { io->set_iomap_alias_rw(0x0088, pio_14, 0); @@ -1041,15 +1115,23 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) set_cpu_clock_with_switch(config.cpu_type); #if defined(_PC9801) || defined(_PC9801E) - fdc_2hd->get_disk_handler(0)->drive_num = 0; - fdc_2hd->get_disk_handler(1)->drive_num = 1; - fdc_2dd->get_disk_handler(0)->drive_num = 2; - fdc_2dd->get_disk_handler(1)->drive_num = 3; - fdc_sub->get_disk_handler(0)->drive_num = 4; - fdc_sub->get_disk_handler(1)->drive_num = 5; + if(fdc_2hd) { + fdc_2hd->get_disk_handler(0)->drive_num = 0; + fdc_2hd->get_disk_handler(1)->drive_num = 1; + } + if(fdc_2dd) { + fdc_2dd->get_disk_handler(0)->drive_num = 2; + fdc_2dd->get_disk_handler(1)->drive_num = 3; + } + if(fdc_sub) { + fdc_sub->get_disk_handler(0)->drive_num = 4; + fdc_sub->get_disk_handler(1)->drive_num = 5; + } #elif defined(_PC9801VF) || defined(_PC9801U) - fdc_2dd->get_disk_handler(0)->drive_num = 0; - fdc_2dd->get_disk_handler(1)->drive_num = 1; + if(fdc_2dd) { + fdc_2dd->get_disk_handler(0)->drive_num = 0; + fdc_2dd->get_disk_handler(1)->drive_num = 1; + } #elif defined(_PC98DO) || defined(_PC98DOPLUS) fdc->get_disk_handler(0)->drive_num = 0; fdc->get_disk_handler(1)->drive_num = 1; @@ -1103,6 +1185,7 @@ DEVICE* VM::get_device(int id) void VM::set_cpu_clock_with_switch(int speed_type) { uint32_t cpu_clocks = CPU_CLOCKS; + uint32_t v30sub_clocks = 9984060; #if defined(_PC9801E) if(speed_type != 0) { // 8MHz -> 5MHz @@ -1114,6 +1197,7 @@ void VM::set_cpu_clock_with_switch(int speed_type) #elif defined(_PC9801VM) || defined(_PC98DO) || defined(_PC98DOPLUS) || defined(_PC9801VX) || defined(_PC98XL) if(speed_type != 0) { // This also include V30CPU/8MHz. // 10MHz/16MHz -> 8MHz + v30sub_clocks = 7987248; cpu_clocks = 7987248; pit_clock_8mhz = true; } else { @@ -1122,12 +1206,10 @@ void VM::set_cpu_clock_with_switch(int speed_type) #elif defined(_PC9801RA) || defined(_PC98RL) if(speed_type == 1) { // 20MHz -> 16MHz + v30sub_clocks = 7987248; cpu_clocks = 15974496; pit_clock_8mhz = true; - } else if(speed_type == 2) { // V30 8MHz... - cpu_clocks = 7987248; - pit_clock_8mhz = true; - } else { + } else { pit_clock_8mhz = false; } #endif @@ -1140,8 +1222,17 @@ void VM::set_cpu_clock_with_switch(int speed_type) // out_debug_log(_T("CLOCK=%d WAIT FACTOR=%d"), cpu_clocks, waitfactor); } cpu->write_signal(SIG_CPU_WAIT_FACTOR, waitfactor, 0xffffffff); -#if defined(HAS_V30_SUB_CPU) - v30cpu->write_signal(SIG_CPU_WAIT_FACTOR, 0, 0xffffffff); +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) + if(9984060 > v30sub_clocks) { +// waitfactor = (uint32_t)(65536.0 * ((1.0 - (double)cpu_clocks / (double)CPU_CLOCKS))); + waitfactor = (uint32_t)(65536.0 * ((double)9984060 / (double)v30sub_clocks)); + } else { + waitfactor = 65536; +// out_debug_log(_T("CLOCK=%d WAIT FACTOR=%d"), cpu_clocks, waitfactor); + } + if(v30 != NULL) { + v30->write_signal(SIG_CPU_WAIT_FACTOR, waitfactor, 0xffffffff); + } #endif uint8_t prn_port_b = 0x00; if(pit_clock_8mhz) { @@ -1482,7 +1573,9 @@ void VM::reset() pio_fdd->write_signal(SIG_I8255_PORT_C, 0xff, 0xff); #endif #if defined(SUPPORT_2DD_FDD_IF) - fdc_2dd->write_signal(SIG_UPD765A_FREADY, 1, 1); // 2DD FDC RDY is pulluped + if(fdc_2dd) { + fdc_2dd->write_signal(SIG_UPD765A_FREADY, 1, 1); // 2DD FDC RDY is pulluped + } #endif if(sound_type == 0 || sound_type == 1) { @@ -1542,17 +1635,13 @@ DEVICE *VM::get_cpu(int index) } else if(index == 2 && boot_mode != 0) { return pc88cpu_sub; } -#elif defined(HAS_V30_SUB_CPU) - if(index == 0) { - return cpu; - } else if(index == 1) { - return v30cpu; - } #else if(index == 0) { return cpu; -#if defined(SUPPORT_320KB_FDD_IF) } else if(index == 1) { +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) + return v30; +#elif defined(SUPPORT_320KB_FDD_IF) return cpu_sub; #endif } @@ -1593,10 +1682,16 @@ void VM::initialize_sound(int rate, int samples) if(sound_type == 0 || sound_type == 1) { if(opn->is_ym2608) { opn->initialize_sound(rate, 7987248, samples, 0, 0); +#if defined(SUPPORT_PC98_OPNA) && defined(SUPPORT_PC98_86PCM) + fmsound->initialize_sound(rate, samples, 14000); +#else + fmsound->initialize_sound(rate, samples); +#endif } else { opn->initialize_sound(rate, 3993624, samples, 0, 0); + fmsound->initialize_sound(rate, samples); } - fmsound->initialize_sound(rate, samples); + } else if(sound_type == 2 || sound_type == 3) { tms3631->initialize_sound(rate, 8000); } @@ -1659,6 +1754,12 @@ void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r) if(sound_type == 0 || sound_type == 1) { fmsound->set_volume(0, decibel_l, decibel_r); } +#if defined(SUPPORT_PC98_86PCM) + } else if(ch-- == 0) { + if(sound_type == 0 || sound_type == 1) { + fmsound->set_volume(0, decibel_l, decibel_r); + } +#endif #endif } else if(ch-- == 0) { if(sound_type == 2 || sound_type == 3) { @@ -1759,6 +1860,15 @@ void VM::close_floppy_disk(int drv) } } +#if defined(_PC9801) || defined(_PC9801E) +bool VM::is_floppy_disk_connected(int drv) +{ + DISK *handler = get_floppy_disk_handler(drv); + + return (handler != NULL); +} +#endif + bool VM::is_floppy_disk_inserted(int drv) { DISK *handler = get_floppy_disk_handler(drv); @@ -1972,9 +2082,7 @@ bool VM::is_frame_skippable() void VM::update_config() { - if((config.cpu_type & 2) == 0) { // This don't change if using V30CPU. - set_cpu_clock_with_switch(config.cpu_type); - } + set_cpu_clock_with_switch(config.cpu_type); #if defined(USE_MONITOR_TYPE) set_wait(config.monitor_type, config.cpu_type); #else @@ -1992,7 +2100,19 @@ void VM::update_config() } } -#define STATE_VERSION 17 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 18 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -2004,7 +2124,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { printf("Class name len Error: DEVID=%d EXPECT=%s\n", device->this_device_id, name); diff --git a/source/src/vm/pc9801/pc9801.h b/source/src/vm/pc9801/pc9801.h index e45ce8f02..69acedd96 100644 --- a/source/src/vm/pc9801/pc9801.h +++ b/source/src/vm/pc9801/pc9801.h @@ -140,6 +140,7 @@ // unknown machines #endif +#define DIPSWITCH_POSITION_USE_V30 (0 + 8 - 1) // DIPSW POSITION // DIPSW1: 8-15 #define DIPSWITCH_POSITION_HIGH_RESO (8 + 1 - 1) @@ -222,6 +223,8 @@ #define SUPPORT_EGC // PC-9801-86 #define SUPPORT_PC98_OPNA + #define SUPPORT_PC98_86PCM + #define SUPPORT_PC98_86PCM_IRQ #endif #if defined(SUPPORT_24BIT_ADDRESS) #define MEMORY_ADDR_MAX 0x01000000 // 16MB @@ -280,8 +283,13 @@ #define PC80S31K_NO_WAIT #endif -#define UPD7220_MSB_FIRST +#if !defined(SUPPORT_HIRESO) #define UPD7220_HORIZ_FREQ 24830 +#else +#define UPD7220_HORIZ_FREQ 32860 +#endif +#define UPD7220_MSB_FIRST + #define UPD7220_A_VERSION 3 #if defined(_PC98DO) || defined(_PC98DOPLUS) #define Z80_MEMORY_WAIT @@ -294,6 +302,8 @@ #define USE_DIPSWITCH #if defined(_PC9801) || defined(_PC9801E) #define USE_FLOPPY_DISK 6 +#define USE_DIPSWITCH +#define DIPSWITCH_DEFAULT (1 + 2 + 4) #elif defined(_PC98DO) || defined(_PC98DOPLUS) #define USE_BOOT_MODE 5 #define DIPSWITCH_MEMWAIT 0x01 @@ -306,11 +316,7 @@ #endif #if defined(SUPPORT_SASI_IF) || defined(SUPPORT_SCSI_IF) || defined(SUPPORT_IDE_IF) #define USE_HARD_DISK 2 - #if defined(HAS_I286) - #define I86_PSEUDO_BIOS - #else - #define I386_PSEUDO_BIOS - #endif +#define I86_PSEUDO_BIOS #endif #if defined(SUPPORT_CMT_IF) || defined(_PC98DO) || defined(_PC98DOPLUS) #define USE_TAPE 1 @@ -318,7 +324,7 @@ #endif #define USE_KEY_LOCKED #if defined(_PC98DO) || defined(_PC98DOPLUS) -// slow enough for N88-{BASIC +// slow enough for N88-日本語BASIC #define USE_AUTO_KEY 8 #define USE_AUTO_KEY_RELEASE 10 #else @@ -358,7 +364,7 @@ #if defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) #define USE_CPU_I86 #elif defined(HAS_V30) -#define USE_CPU_V30 +#define USE_CPU_I86 #elif defined(UPPER_I386) #define USE_CPU_I386 #else @@ -413,19 +419,15 @@ class I8251; class I8253; class I8255; class I8259; -#if defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) -class I8086; -#elif defined(HAS_V30) -class V30; -#elif defined(HAS_I286) -class I80286; +#if defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) || defined(HAS_V30) +class I86; #elif defined(UPPER_I386) class I386; #else class I286; #endif #if defined(HAS_V30_SUB_CPU) -class V30; +class I86; #endif class IO; @@ -524,15 +526,13 @@ class VM : public VM_TEMPLATE I8259* pic; #if defined(UPPER_I386) I386* cpu; -#elif defined(HAS_V30) - V30* cpu; -#elif defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) - I8086 *cpu; +#elif defined(HAS_V30) || defined(HAS_I86) || defined(HAS_I186) || defined(HAS_I88) + I86* cpu; #else - I80286* cpu; + I286* cpu; #endif -#if defined(HAS_V30_SUB_CPU) - V30* v30cpu; +#if (defined(SUPPORT_24BIT_ADDRESS) || defined(SUPPORT_32BIT_ADDRESS)) && !defined(SUPPORT_HIRESO) + I86* v30; #endif IO* io; LS244* rtcreg; @@ -642,7 +642,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -679,6 +679,9 @@ class VM : public VM_TEMPLATE // user interface void open_floppy_disk(int drv, const _TCHAR* file_path, int bank); void close_floppy_disk(int drv); +#if defined(_PC9801) || defined(_PC9801E) + bool is_floppy_disk_connected(int drv); +#endif bool is_floppy_disk_inserted(int drv); void is_floppy_disk_protected(int drv, bool value); bool is_floppy_disk_protected(int drv); @@ -697,6 +700,9 @@ class VM : public VM_TEMPLATE #endif bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pc9801/sasi.cpp b/source/src/vm/pc9801/sasi.cpp index 92135ec98..2c9fa5c04 100644 --- a/source/src/vm/pc9801/sasi.cpp +++ b/source/src/vm/pc9801/sasi.cpp @@ -14,30 +14,39 @@ #include "sasi.h" #include "../harddisk.h" #include "../i8237.h" +#if !defined(SUPPORT_HIRESO) +#include "../i8255.h" +#endif #include "../i8259.h" #include "../scsi_host.h" #include "../scsi_hdd.h" -#define OCR_CHEN 0x80 -#define OCR_NRDSW 0x40 -#define OCR_SEL 0x20 -#define OCR_RST 0x08 -#define OCR_DMAE 0x02 -#define OCR_INTE 0x01 - -#define ISR_REQ 0x80 -#define ISR_ACK 0x40 -#define ISR_BSY 0x20 -#define ISR_MSG 0x10 -#define ISR_CXD 0x08 -#define ISR_IXO 0x04 -#define ISR_INT 0x01 +#define CONTROL_CHEN 0x80 +#define CONTROL_NRDSW 0x40 +#define CONTROL_SEL 0x20 +#define CONTROL_RST 0x08 +#define CONTROL_DMAE 0x02 +#define CONTROL_INTE 0x01 + +#define STATUS_REQ 0x80 +#define STATUS_ACK 0x40 +#define STATUS_BSY 0x20 +#define STATUS_MSG 0x10 +#define STATUS_CXD 0x08 +#define STATUS_IXO 0x04 +#define STATUS_INT 0x01 namespace PC9801 { void SASI::reset() { - ocr = 0; + control = 0; + bsy_status = prev_bsy_status = true; + cxd_status = prev_cxd_status = true; + ixo_status = prev_ixo_status = true; + msg_status = prev_msg_status = true; + req_status = prev_req_status = true; + ack_status = prev_ack_status = true; irq_status = drq_status = false; } @@ -48,7 +57,7 @@ void SASI::write_io8(uint32_t addr, uint32_t data) #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data); #endif -// if(ocr & OCR_CHEN) { +// if(control & CONTROL_CHEN) { d_host->write_dma_io8(addr, data); // } break; @@ -57,9 +66,17 @@ void SASI::write_io8(uint32_t addr, uint32_t data) #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SASI] out %04X %02X\n"), addr, data); #endif - d_host->write_signal(SIG_SCSI_RST, data, OCR_RST); - d_host->write_signal(SIG_SCSI_SEL, data, OCR_SEL); - ocr = data; + control = data; + if((prev_control & CONTROL_RST) != (control & CONTROL_RST)) { + d_host->write_signal(SIG_SCSI_RST, data, CONTROL_RST); + } + if((prev_control & CONTROL_SEL) != (control & CONTROL_SEL)) { + d_host->write_signal(SIG_SCSI_SEL, data, CONTROL_SEL); + } + if((prev_control & (CONTROL_DMAE | CONTROL_INTE)) != (control & (CONTROL_DMAE | CONTROL_INTE))) { + update_signal(); + } + prev_control = control; break; } } @@ -70,7 +87,7 @@ uint32_t SASI::read_io8(uint32_t addr) switch(addr) { case 0x0080: -// if(ocr & OCR_CHEN) { +// if(control & CONTROL_CHEN) { value = d_host->read_dma_io8(addr); // } // #ifdef _SCSI_DEBUG_LOG @@ -79,22 +96,22 @@ uint32_t SASI::read_io8(uint32_t addr) return value; case 0x0082: - if(ocr & OCR_NRDSW) { - value = (d_host->read_signal(SIG_SCSI_REQ) ? ISR_REQ : 0) | -// (d_host->read_signal(SIG_SCSI_ACK) ? ISR_ACK : 0) | - (d_host->read_signal(SIG_SCSI_BSY) ? ISR_BSY : 0) | - (d_host->read_signal(SIG_SCSI_MSG) ? ISR_MSG : 0) | - (d_host->read_signal(SIG_SCSI_CD ) ? ISR_CXD : 0) | - (d_host->read_signal(SIG_SCSI_IO ) ? ISR_IXO : 0) | - (irq_status ? ISR_INT : 0); + if(control & CONTROL_NRDSW) { + value = (d_host->read_signal(SIG_SCSI_REQ) ? STATUS_REQ : 0) | +// (d_host->read_signal(SIG_SCSI_ACK) ? STATUS_ACK : 0) | + (d_host->read_signal(SIG_SCSI_BSY) ? STATUS_BSY : 0) | + (d_host->read_signal(SIG_SCSI_MSG) ? STATUS_MSG : 0) | + (d_host->read_signal(SIG_SCSI_CD ) ? STATUS_CXD : 0) | + (d_host->read_signal(SIG_SCSI_IO ) ? STATUS_IXO : 0) | + (irq_status ? STATUS_INT : 0); // irq_status = false; #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SASI] in %04X %02X (REQ=%d,BSY=%d,MSG=%d,CxD=%d,IxO=%d,DH=%02X,DL=%02X)\n"), addr, value, - (value & ISR_REQ) ? 1 : 0, - (value & ISR_BSY) ? 1 : 0, - (value & ISR_MSG) ? 1 : 0, - (value & ISR_CXD) ? 1 : 0, - (value & ISR_IXO) ? 1 : 0, + (value & STATUS_REQ) ? 1 : 0, + (value & STATUS_BSY) ? 1 : 0, + (value & STATUS_MSG) ? 1 : 0, + (value & STATUS_CXD) ? 1 : 0, + (value & STATUS_IXO) ? 1 : 0, vm->get_cpu(0)->read_debug_reg(_T("DH")), vm->get_cpu(0)->read_debug_reg(_T("DL"))); #endif } else { @@ -140,64 +157,120 @@ uint32_t SASI::read_io8(uint32_t addr) return 0xff; } -/* void SASI::write_dma_io8(uint32_t addr, uint32_t data) { - write_io8(0x0080, data); + #ifdef _SCSI_DEBUG_LOG + this->out_debug_log(_T("[SASI] DMA out %02X\n"), data); + #endif + d_host->write_dma_io8(addr, data); } uint32_t SASI::read_dma_io8(uint32_t addr) { - return read_io8(0x0080); + uint32_t val = d_host->read_dma_io8(addr); + #ifdef _SCSI_DEBUG_LOG + this->out_debug_log(_T("[SASI] DMA in %02X\n"), val); + #endif + return val; } -*/ void SASI::write_signal(int id, uint32_t data, uint32_t mask) { switch(id) { - case SIG_SASI_IRQ: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SASI] IRQ=%d\n"), (data & mask) ? 1 : 0); - #endif - if(ocr & OCR_INTE) { - d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR1, data, mask); - } - irq_status = ((data & mask) != 0); + case SIG_SASI_BSY: + bsy_status = ((data & mask) == 0); + update_signal(); + prev_bsy_status = bsy_status; break; - - case SIG_SASI_DRQ: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SASI] DRQ=%d\n"), (data & mask) ? 1 : 0); - #endif - if(ocr & OCR_DMAE) { - #ifdef _PC98XA - d_dma->write_signal(SIG_I8237_CH3, data, mask); - #else - d_dma->write_signal(SIG_I8237_CH0, data, mask); - #endif -// } else { -// if(data & mask) { -// #ifdef _SCSI_DEBUG_LOG -// this->out_debug_log(_T("[SASI] DMAE=0, change IRQ\n")); -// #endif -// write_signal(SIG_SASI_IRQ, data, mask); -// } - } - drq_status = ((data & mask) != 0); + case SIG_SASI_CXD: + cxd_status = ((data & mask) == 0); + update_signal(); + prev_cxd_status = cxd_status; + break; + case SIG_SASI_IXO: + ixo_status = ((data & mask) == 0); + update_signal(); + prev_ixo_status = ixo_status; + break; + case SIG_SASI_MSG: + msg_status = ((data & mask) == 0); + update_signal(); + prev_msg_status = msg_status; + break; + case SIG_SASI_REQ: + req_status = ((data & mask) == 0); + update_signal(); + prev_req_status = req_status; + break; + case SIG_SASI_ACK: + ack_status = ((data & mask) == 0); + update_signal(); + prev_ack_status = ack_status; break; - case SIG_SASI_TC: #ifdef _SCSI_DEBUG_LOG this->out_debug_log(_T("[SASI] TC=%d\n"), (data & mask) ? 1 : 0); #endif if(data & mask) { - ocr &= ~OCR_DMAE; + control &= ~CONTROL_DMAE; + update_signal(); + prev_control = control; } break; } } -#define STATE_VERSION 2 +void SASI::update_signal() +{ + // http://retropc.net/ohishi/museum/mz1e30.htm + bool prev_ic20_o11 = (!prev_req_status) && prev_cxd_status; + bool prev_ic10_o8 = !(!prev_req_status && !prev_ixo_status && prev_msg_status && !prev_cxd_status); + bool prev_ic18_o11 = !(!(prev_control & CONTROL_DMAE) && prev_ic20_o11); + bool prev_ic18_o8 = !(prev_ic10_o8 && prev_ic18_o11); + + bool ic20_o11 = (!req_status) && cxd_status; + bool ic10_o8 = !(!req_status && !ixo_status && msg_status && !cxd_status); + bool ic18_o11 = !(!(control & CONTROL_DMAE) && ic20_o11); + bool ic18_o8 = !(ic10_o8 && ic18_o11); + + bool prev_irq_status = irq_status; + bool prev_drq_status = drq_status; + + if(!prev_ic18_o8 && ic18_o8) { + irq_status = ((control & CONTROL_INTE) != 0); + } + if(!prev_ic20_o11 && ic20_o11) { + drq_status = ((control & CONTROL_DMAE) != 0); + } + if((prev_control & CONTROL_INTE) && !(control & CONTROL_INTE)) { + irq_status = false; + } + if((prev_control & CONTROL_DMAE) && !(control & CONTROL_DMAE)) { + drq_status = false; + } + if(prev_ack_status && !ack_status) { + drq_status = false; + } +#ifdef _SCSI_DEBUG_LOG + if(prev_irq_status != irq_status) { + this->out_debug_log(_T("[SASI] irq_status=%d\n"), irq_status ? 1 : 0); + } + if(prev_drq_status != drq_status) { + this->out_debug_log(_T("[SASI] drq_status=%d\n"), drq_status ? 1 : 0); + } +#endif +#if !defined(SUPPORT_HIRESO) + d_pio->write_signal(SIG_I8255_PORT_B, (irq_status ? 0x10 : 0), 0x10); +#endif + d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR1, (irq_status ? 1 : 0), 1); +#ifdef _PC98XA + d_dma->write_signal(SIG_I8237_CH3, (drq_status ? 1 : 0), 1); +#else + d_dma->write_signal(SIG_I8237_CH0, (drq_status ? 1 : 0), 1); +#endif +} + +#define STATE_VERSION 3 bool SASI::process_state(FILEIO* state_fio, bool loading) { @@ -207,7 +280,20 @@ bool SASI::process_state(FILEIO* state_fio, bool loading) if(!state_fio->StateCheckInt32(this_device_id)) { return false; } - state_fio->StateValue(ocr); + state_fio->StateValue(control); + state_fio->StateValue(prev_control); + state_fio->StateValue(bsy_status); + state_fio->StateValue(prev_bsy_status); + state_fio->StateValue(cxd_status); + state_fio->StateValue(prev_cxd_status); + state_fio->StateValue(ixo_status); + state_fio->StateValue(prev_ixo_status); + state_fio->StateValue(msg_status); + state_fio->StateValue(prev_msg_status); + state_fio->StateValue(req_status); + state_fio->StateValue(prev_req_status); + state_fio->StateValue(ack_status); + state_fio->StateValue(prev_ack_status); state_fio->StateValue(irq_status); state_fio->StateValue(drq_status); return true; diff --git a/source/src/vm/pc9801/sasi.h b/source/src/vm/pc9801/sasi.h index b3f7f38c5..af8b62abd 100644 --- a/source/src/vm/pc9801/sasi.h +++ b/source/src/vm/pc9801/sasi.h @@ -18,9 +18,13 @@ #include "../../emu.h" #include "../device.h" -#define SIG_SASI_IRQ 0 -#define SIG_SASI_DRQ 1 -#define SIG_SASI_TC 2 +#define SIG_SASI_BSY 0 +#define SIG_SASI_CXD 1 +#define SIG_SASI_IXO 2 +#define SIG_SASI_MSG 3 +#define SIG_SASI_REQ 4 +#define SIG_SASI_ACK 5 +#define SIG_SASI_TC 6 class SASI_HDD; @@ -32,14 +36,32 @@ class SASI : public DEVICE DEVICE *d_host; SASI_HDD *d_hdd; DEVICE *d_dma, *d_pic; +#if !defined(SUPPORT_HIRESO) + DEVICE *d_pio; +#endif + + uint8_t control, prev_control; + bool bsy_status, prev_bsy_status; + bool cxd_status, prev_cxd_status; + bool ixo_status, prev_ixo_status; + bool msg_status, prev_msg_status; + bool req_status, prev_req_status; + bool ack_status, prev_ack_status; + bool irq_status, drq_status; - uint8_t ocr; - bool irq_status; - bool drq_status; + void update_signal(); public: - SASI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SASI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { + control = 0x00; + bsy_status = prev_bsy_status = false; + cxd_status = prev_cxd_status = false; + ixo_status = prev_ixo_status = false; + msg_status = prev_msg_status = false; + req_status = prev_req_status = false; + ack_status = prev_ack_status = false; + irq_status = drq_status = false; set_device_name(_T("SASI I/F")); d_hdd = NULL; d_dma = NULL; @@ -51,8 +73,8 @@ class SASI : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); -// void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); -// uint32_t __FASTCALL read_dma_io8(uint32_t addr); + void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_dma_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); @@ -77,6 +99,12 @@ class SASI : public DEVICE { return d_hdd; } +#if !defined(SUPPORT_HIRESO) + void set_context_pio(DEVICE* device) + { + d_pio = device; + } +#endif }; } diff --git a/source/src/vm/pc9801/sasi_bios.cpp b/source/src/vm/pc9801/sasi_bios.cpp index 0579234f8..33c581701 100644 --- a/source/src/vm/pc9801/sasi_bios.cpp +++ b/source/src/vm/pc9801/sasi_bios.cpp @@ -23,16 +23,14 @@ #include "../i8259.h" #if defined(UPPER_I386) -#include "../i386.h" -#elif defined(HAS_I86) || defined(HAS_I186) +#include "../i386_np21.h" +#elif defined(HAS_I86) || defined(HAS_I186) || defined(HAS_V30) #include "../i86.h" -#elif defined(HAS_V30) -#include "../v30.h" #else #include "../i286.h" #endif #if defined(HAS_V30_SUB_CPU) -#include "../v30.h" +#include "../i86.h" #endif #define EVENT_HALT_HOST 97 @@ -120,7 +118,7 @@ void BIOS::reset() event_irq = -1; } -bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { // SASI switch(intnum) { @@ -135,7 +133,7 @@ bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* return false; } -bool BIOS::bios_int_ia32(int intnum, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_int_ia32(int intnum, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { // SASI switch(intnum) { @@ -150,7 +148,7 @@ bool BIOS::bios_int_ia32(int intnum, uint32_t regs[], uint16_t sregs[], int32_t* return false; } -bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { uint32_t reg32[10]; for(int i = 0; i < 10; i++) { @@ -164,7 +162,7 @@ bool BIOS::bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int } return false; } -bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) +bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles) { pair32_t *regpair = (pair32_t *)regs; bool need_retcall = false; @@ -218,10 +216,10 @@ bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], in sp = sp - 18; LOAD_SP(sp); LOAD_BP(sp); - DS = 0x0000; +// DS = 0x0000; LOAD_BX(0x04b0); LOAD_AX(((uint16_t)seg) << 8); - CS = ((uint16_t)seg) << 8; +// CS = ((uint16_t)seg) << 8; IP_L = 0x0018; IP_H = 0x0000; if(cycles != NULL) { @@ -254,7 +252,7 @@ bool BIOS::bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], in case 0x00: case 0x80: if(!(d_mem->is_sasi_bios_load())) { - if(sasi_bios(PC, regs, sregs, ZeroFlag, CarryFlag)) { + if(sasi_bios(PC, regs, (uint16_t*)sregs, ZeroFlag, CarryFlag)) { #ifdef _PSEUDO_BIOS_DEBUG out_debug_log(_T("SASI BIOS CALL SUCCESS:\n From AX=%04x BX=%04x CX=%04x DX=%04x\n To AX=%04x BX=%04x CX=%04x DX=%04x\n"), backup_ax, backup_bx, backup_cx, backup_dx, AX, BX, CX, DX); #endif diff --git a/source/src/vm/pc9801/sasi_bios.h b/source/src/vm/pc9801/sasi_bios.h index fcf1052ff..bf32f888a 100644 --- a/source/src/vm/pc9801/sasi_bios.h +++ b/source/src/vm/pc9801/sasi_bios.h @@ -23,7 +23,6 @@ class SASI_HDD; class HARDDISK; class I386; class I8086; -class V30; class I80286; namespace PC9801 { @@ -38,32 +37,31 @@ class BIOS : public DEVICE MEMBUS *d_mem; SASI *d_sasi; DEVICE *d_cpu; - DEVICE *d_v30cpu; DEVICE *d_pic; DEVICE *d_cpureg; int event_halt; int event_irq; - void halt_host_cpu(double usec); - void interrupt_to_host(double usec); + void __FASTCALL halt_host_cpu(double usec); + void __FASTCALL interrupt_to_host(double usec); - int sxsi_get_drive(uint8_t al); - long sasi_get_position(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + int __FASTCALL sxsi_get_drive(uint8_t al); + long __FASTCALL sasi_get_position(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_verify(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_retract(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_illegal(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_initialize(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_sense(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_read(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_write(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); - void sasi_command_format(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_verify(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_retract(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_illegal(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_initialize(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_sense(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_read(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_write(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + void __FASTCALL sasi_command_format(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); bool sasi_bios(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); public: - BIOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + BIOS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("SASI PSEUDO BIOS")); } @@ -72,11 +70,11 @@ class BIOS : public DEVICE // common functions void reset(); void initialize(); - bool bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); - bool bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); - bool bios_int_ia32(int intnum, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); - bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); - void event_callback(int event_id, int err); + bool bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + bool bios_call_far_i86(uint32_t PC, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + bool bios_int_ia32(int intnum, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + bool bios_call_far_ia32(uint32_t PC, uint32_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag, int* cycles, uint64_t* total_cycles); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions @@ -92,10 +90,6 @@ class BIOS : public DEVICE { d_cpu = device; } - void set_context_v30cpu(DEVICE* device) - { - d_v30cpu = device; - } void set_context_pic(DEVICE* device) { d_pic = device; diff --git a/source/src/vm/pc98ha/CMakeLists.txt b/source/src/vm/pc98ha/CMakeLists.txt index ac3afa94a..427d93058 100644 --- a/source/src/vm/pc98ha/CMakeLists.txt +++ b/source/src/vm/pc98ha/CMakeLists.txt @@ -1,16 +1,18 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pc98ha") +message("* vm/${EXE_NAME}") -set(BASIC_VM_FILES - pc98ha.cpp - bios.cpp - calendar.cpp - floppy.cpp - keyboard.cpp - memory.cpp - note.cpp - ) +set(BASIC_VM_FILES_PC98HA + + bios.cpp + calendar.cpp + floppy.cpp + keyboard.cpp + ./memory.cpp + note.cpp + + pc98ha.cpp +) -add_library(vm_pc98ha ${BASIC_VM_FILES}) +add_library(vm_${EXE_NAME} ${BASIC_VM_FILES_PC98HA}) diff --git a/source/src/vm/pc98ha/bios.cpp b/source/src/vm/pc98ha/bios.cpp index 62621e2c3..c93b44105 100644 --- a/source/src/vm/pc98ha/bios.cpp +++ b/source/src/vm/pc98ha/bios.cpp @@ -18,7 +18,7 @@ namespace PC98HA { #define AL regs8[0] #define AH regs8[1] -bool BIOS::bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag) +bool BIOS::bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag) { static const int check_cmds[16] = {1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0}; uint8_t *regs8 = (uint8_t *)regs; diff --git a/source/src/vm/pc98ha/bios.h b/source/src/vm/pc98ha/bios.h index b334cce93..b32fff1a5 100644 --- a/source/src/vm/pc98ha/bios.h +++ b/source/src/vm/pc98ha/bios.h @@ -25,14 +25,14 @@ class BIOS : public DEVICE UPD765A *d_fdc; public: - BIOS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + BIOS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Pseudo BIOS")); } ~BIOS() {} // common function - bool bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); + bool bios_int_i86(int intnum, uint16_t regs[], const uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag); // unique function void set_context_fdc(UPD765A* device) diff --git a/source/src/vm/pc98ha/calendar.h b/source/src/vm/pc98ha/calendar.h index 60a22a39d..469417543 100644 --- a/source/src/vm/pc98ha/calendar.h +++ b/source/src/vm/pc98ha/calendar.h @@ -26,7 +26,7 @@ class CALENDAR : public DEVICE #endif public: - CALENDAR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CALENDAR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RTC I/F")); } diff --git a/source/src/vm/pc98ha/floppy.h b/source/src/vm/pc98ha/floppy.h index 051dfffb1..baf8bd5e9 100644 --- a/source/src/vm/pc98ha/floppy.h +++ b/source/src/vm/pc98ha/floppy.h @@ -29,7 +29,7 @@ class FLOPPY : public DEVICE uint8_t ctrlreg, modereg; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/pc98ha/keyboard.h b/source/src/vm/pc98ha/keyboard.h index 75bdddef5..021352e28 100644 --- a/source/src/vm/pc98ha/keyboard.h +++ b/source/src/vm/pc98ha/keyboard.h @@ -28,7 +28,7 @@ class KEYBOARD : public DEVICE uint8_t flag[256]; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/pc98ha/memory.h b/source/src/vm/pc98ha/memory.h index ddcdc2b92..7cd803f9c 100644 --- a/source/src/vm/pc98ha/memory.h +++ b/source/src/vm/pc98ha/memory.h @@ -59,7 +59,7 @@ class MEMORY : public DEVICE #endif public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/pc98ha/note.h b/source/src/vm/pc98ha/note.h index d4649a255..a5f9562cd 100644 --- a/source/src/vm/pc98ha/note.h +++ b/source/src/vm/pc98ha/note.h @@ -24,7 +24,7 @@ class NOTE : public DEVICE uint8_t ch, regs[16]; public: - NOTE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + NOTE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("98NOTE I/O")); } diff --git a/source/src/vm/pc98ha/pc98ha.cpp b/source/src/vm/pc98ha/pc98ha.cpp index 64627cc5a..315941e93 100644 --- a/source/src/vm/pc98ha/pc98ha.cpp +++ b/source/src/vm/pc98ha/pc98ha.cpp @@ -18,13 +18,7 @@ #include "../i8253.h" #include "../i8255.h" #include "../i8259.h" -#if defined(HAS_V30) -# include "../v30.h" -#elif defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186) # include "../i86.h" -#else -# include "../i286.h" -#endif #include "../io.h" #include "../noise.h" #include "../not.h" @@ -60,7 +54,7 @@ using PC98HA::NOTE; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -82,13 +76,8 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) pio_prn = new I8255(this, emu); // for printer pio_prn->set_device_name(_T("8251 PIO (Printer)")); pic = new I8259(this, emu); // V50 internal -#if defined(HAS_V30) - cpu = new V30(this, emu); // V50 -#elif defined(HAS_I86) || defined(HAS_I88) || defined(HAS_I186) - cpu = new I8086(this, emu); // V50 -#else - cpu = new I80286(this, emu); // V50 -#endif + cpu = new I86(this, emu); // V50 + cpu->device_model = NEC_V30; io = new IO(this, emu); not_busy = new NOT(this, emu); #ifdef _PC98HA @@ -420,7 +409,19 @@ void VM::update_config() } } -#define STATE_VERSION 7 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 8 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -432,7 +433,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pc98ha/pc98ha.h b/source/src/vm/pc98ha/pc98ha.h index ff11bc7a9..b34d78028 100644 --- a/source/src/vm/pc98ha/pc98ha.h +++ b/source/src/vm/pc98ha/pc98ha.h @@ -74,13 +74,7 @@ class I8251; class I8253; class I8255; class I8259; -#if defined(HAS_I86) -class I8086; -#elif defined(HAS_V30) -class V30; -#else -class I80286; -#endif +class I86; class IO; class NOT; #ifdef _PC98HA @@ -117,13 +111,7 @@ class VM : public VM_TEMPLATE I8255* pio_sys; I8255* pio_prn; I8259* pic; -#if defined(HAS_V30) - V30* cpu; -#elif defined(HAS_I86) - I8086* cpu; -#else - I80286* cpu; -#endif + I86* cpu; IO* io; NOT* not_busy; #ifdef _PC98HA @@ -146,7 +134,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -192,6 +180,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pcengine/CMakeLists.txt b/source/src/vm/pcengine/CMakeLists.txt index 2a950773b..35332df54 100644 --- a/source/src/vm/pcengine/CMakeLists.txt +++ b/source/src/vm/pcengine/CMakeLists.txt @@ -1,16 +1,13 @@ cmake_minimum_required (VERSION 2.8) -message("* vm/pce") +message("* vm/emupcengine") -if(BUILD_X1TWIN) -add_library(vm_pcengine - pce.cpp - +add_library(vm_emupcengine + ../scsi_host.cpp + ../huc6280.cpp + + pce.cpp + adpcm.cpp + pcengine.cpp ) -else() -add_library(vm_pcengine - pce.cpp - adpcm.cpp - pcengine.cpp -) -endif() + diff --git a/source/src/vm/pcengine/adpcm.cpp b/source/src/vm/pcengine/adpcm.cpp index 404907bd7..bad197909 100644 --- a/source/src/vm/pcengine/adpcm.cpp +++ b/source/src/vm/pcengine/adpcm.cpp @@ -124,7 +124,7 @@ void ADPCM::reset_adpcm() dma_connected = false; play_in_progress = false; adpcm_paused = false; - + if(event_fader != -1) { cancel_event(this, event_fader); } @@ -137,6 +137,8 @@ void ADPCM::reset_adpcm() reg_0c |= ADPCM_STOP_FLAG; reg_0c &= ~ADPCM_PLAY_FLAG; reg_0c &= ~(ADPCM_REMAIN_READ_BUF | ADPCM_REMAIN_WRITE_BUF); + d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff); + d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff); do_stop(true); set_dma_status(false); //d_msm->reset(); @@ -148,17 +150,18 @@ void ADPCM::reset_adpcm() //memset(ram, 0x00, sizeof(ram)); out_debug_log(_T("RESET ADPCM\n")); - d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00, 0xffffffff); - d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00, 0xffffffff); } void ADPCM::do_play() { - reg_0c &= ~ADPCM_STOP_FLAG; + // From Ootake v2.86 + reg_0c &= ~(ADPCM_REMAIN_READ_BUF | ADPCM_REMAIN_WRITE_BUF | ADPCM_STOP_FLAG); reg_0c |= ADPCM_PLAY_FLAG; play_in_progress = true; adpcm_paused = false; + d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff); + d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff); } void ADPCM::do_pause(bool pause) @@ -189,7 +192,10 @@ void ADPCM::do_stop(bool do_notify) reg_0c &= ~ADPCM_PLAY_FLAG; msm_last_cmd &= ~0x60; play_in_progress = false; - if(do_notify) set_dma_status(false); + if(do_notify) { + set_dma_status(false); +// d_pce->write_signal(SIG_PCE_ADPCM_DMA, 0x00000000, 0xffffffff); + } out_debug_log(_T("ADPCM STOP PLAY PTR=%04x DMA CLEAR=%s\n"), msm_ptr, (do_notify) ? _T("YES") : _T("NO")); } @@ -211,6 +217,7 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask) case SIG_ADPCM_DMACTRL: if((data & 0x03) != 0) { set_dma_status(true); + //d_pce->write_signal(SIG_PCE_ADPCM_DMA, 0xffffffff, 0xffffffff); //reg_0b |= 0x02; } reg_0b = data; @@ -244,7 +251,7 @@ void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask) do_dma(data); break; case SIG_ADPCM_DO_DMA_TRANSFER: - //set_dma_status(true); + set_dma_status(true); dma_connected = true; do_dma(d_pce->read_signal(SIG_PCE_CDROM_RAW_DATA)); break; @@ -397,7 +404,8 @@ void ADPCM::do_cmd(uint8_t cmd) } else { if(adpcm_stream) { if(written_size > 0x8000) { - //req_play = false; +// if(msm_length > 0x8000) { +// req_play = false; } else { msm_last_cmd = cmd; return; // Exit from command. 20190212 K.O @@ -405,7 +413,7 @@ void ADPCM::do_cmd(uint8_t cmd) } } if(req_play) { -// msm_start_addr = (adpcm_read_ptr) & 0xffff; +// msm_ptr = read_ptr; if(/*((cmd & 0x40) != 0) && */!(play_in_progress)) { // ADPCM play half_addr = (read_ptr + ((adpcm_length + 1) >> 1)) & 0xffff; @@ -419,38 +427,41 @@ void ADPCM::do_cmd(uint8_t cmd) d_msm->reset_w(0); written_size = 0; // OK? out_debug_log(_T("ADPCM START PLAY(%s) START=%04x LENGTH=%04x HALF=%04x STREAM=%s\n"), (dma_enabled) ? _T("DMA") : _T("PIO"), msm_ptr, msm_length, half_addr, (adpcm_stream) ? _T("YES") : _T("NO")); + msm_last_cmd = cmd; } else { - //msm_length = adpcm_length; - //write_ptr &= 0xffff; - //read_ptr &= 0xffff; // 20181213 K.O: Import from Ootake v2.83.Thanks to developers of Ootake. - if(((adpcm_length & 0xffff) >= 0x8000) && ((adpcm_length & 0xffff) <= 0x80ff)) { + if((adpcm_repeat) + && ((adpcm_length & 0xffff) >= 0x8000) + && ((adpcm_length & 0xffff) <= 0x80ff)) { half_addr = (read_ptr + 0x85) & 0xffff; } else { half_addr = (read_ptr + ((adpcm_length + 1) >> 1)) & 0xffff; } out_debug_log(_T("ADPCM UPDATE HALF ADDRESS HALF=%04x\n"), half_addr); } - - } else { - //set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_HALF_PLAY, CLEAR_LINE); - // set_cdrom_irq_line(PCE_CD_IRQ_SAMPLE_FULL_PLAY, ASSERT_LINE); + } else { + if(play_in_progress) { - d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff); - d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff); if((msm_last_cmd & 0x40) != 0) { + adpcm_stream = false; + adpcm_repeat = false; + msm_last_cmd = cmd; + d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff); + d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff); do_stop(true); // true? d_msm->reset_w(1); return; } } - //d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff); - //d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff); - adpcm_stream = false; - adpcm_repeat = false; + + msm_last_cmd = cmd; +// adpcm_stream = false; +// adpcm_repeat = false; + d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff); + d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0x00000000, 0xffffffff); + out_debug_log(_T("ADPCM STATUS UPDATE / STOP\n")); } - msm_last_cmd = cmd; } @@ -496,7 +507,7 @@ void ADPCM::do_vclk(bool flag) { d_pce->write_signal(SIG_PCE_ADPCM_HALF, 0x00000000, 0xffffffff); d_pce->write_signal(SIG_PCE_ADPCM_FULL, 0xffffffff, 0xffffffff); - if((msm_last_cmd & 0x40) != 0) { + if(((msm_last_cmd & 0x40) != 0)){ do_stop(false); // true? d_msm->reset_w(1); } diff --git a/source/src/vm/pcengine/adpcm.h b/source/src/vm/pcengine/adpcm.h index 98de506c8..d7d275fbf 100644 --- a/source/src/vm/pcengine/adpcm.h +++ b/source/src/vm/pcengine/adpcm.h @@ -92,17 +92,17 @@ class ADPCM : public DEVICE bool __FASTCALL do_dma(uint8_t data); void do_cmd(uint8_t cmd); void do_play(); - void do_pause(bool pause); - void do_stop(bool do_notify); + void __FASTCALL do_pause(bool pause); + void __FASTCALL do_stop(bool do_notify); void update_length(); - void set_ack(int clocks); - void clear_ack(int clocks); + void __FASTCALL set_ack(int clocks); + void __FASTCALL clear_ack(int clocks); void set_dma_status(bool flag); void fade_in(int usec); void fade_out(int usec); void reset_adpcm(); public: - ADPCM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + ADPCM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("PC-Engine CD-ROM^2 around ADPCM")); } @@ -114,8 +114,8 @@ class ADPCM : public DEVICE uint32_t __FASTCALL read_signal(int ch); void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); - void event_callback(int id, int err); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int id, int err); + void __FASTCALL mix(int32_t* buffer, int cnt); bool process_state(FILEIO* state_fio, bool loading); void set_context_msm(MSM5205* dev) diff --git a/source/src/vm/pcengine/pce.cpp b/source/src/vm/pcengine/pce.cpp index 2e1ff2c72..1c65324f4 100644 --- a/source/src/vm/pcengine/pce.cpp +++ b/source/src/vm/pcengine/pce.cpp @@ -134,10 +134,8 @@ void PCE::reset() joy_reset(); #ifdef SUPPORT_CDROM adpcm_dma_enabled = false; - cdrom_reset(); #endif - prev_width = -1; } @@ -157,7 +155,7 @@ void PCE::write_data8(uint32_t addr, uint32_t data) uint16_t ofs = addr & 0x1fff; #ifdef SUPPORT_CDROM - if(support_cdrom && mpr >= 0x68 && mpr <= 0x87) { + if(support_cdrom && mpr >= 0x68 && mpr <= 0x87) { // 0xd0000-0xfffff cdrom_ram[addr & 0x3ffff] = data; return; } @@ -253,7 +251,7 @@ uint32_t PCE::read_data8(uint32_t addr) return cart[addr & 0x7ffff]; } #ifdef SUPPORT_CDROM - if(support_cdrom && mpr >= 0x68 && mpr <= 0x87) { + if(support_cdrom && mpr >= 0x68 && mpr <= 0x87) { // 0xd0000-0xfffff return cdrom_ram[addr & 0x3ffff]; } #endif @@ -1893,9 +1891,8 @@ void PCE::cdrom_reset() check_read6_status_flag = true; irq_status = drq_status = false; - adpcm_dma_enabled = false; d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0x00, 0x03); - + adpcm_dma_enabled = false; if(event_cdda_fader != -1) { cancel_event(this, event_cdda_fader); } @@ -1915,12 +1912,12 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) // Reset req? d_scsi_host->write_signal(SIG_SCSI_SEL, 1, 1); d_scsi_host->write_signal(SIG_SCSI_SEL, 0, 1); - - adpcm_dma_enabled = false; - d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0x00, 0xff); // From Ootake v2.38 + d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0x00000000, 0xffffffff); + //adpcm_dma_enabled = false; cdrom_regs[0x03] = 0x00; // Reset IRQ status at al. set_cdrom_irq_line(0x0, 0x0); // Update IRQ + out_debug_log(_T("CMD=$00 CDC STATUS\n")); break; case 0x01: /* CDC command / status / data */ @@ -1956,9 +1953,9 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) // Reset ADPCM hardware d_adpcm->write_signal(SIG_ADPCM_RESET, 0xff, 0xff); - adpcm_dma_enabled = false; + d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0x00000000, 0xffffffff); - //out_debug_log(_T("CMD=$04 ADPCM RESET\n")); + out_debug_log(_T("CMD=$04 ADPCM RESET\n")); cdrom_regs[0x03] = 0x00; // Reset IRQ status at al. set_cdrom_irq_line(0x0, 0x0); // Update IRQ } @@ -1992,10 +1989,7 @@ void PCE::cdrom_write(uint16_t addr, uint8_t data) /* Start CD to ADPCM transfer */ adpcm_dma_enabled = true; d_adpcm->write_signal(SIG_ADPCM_DMA_ENABLED, 0xffffffff, 0xffffffff); - } else { - //adpcm_dma_enabled = false; } - break; case 0x0c: /* ADPCM status */ @@ -2071,6 +2065,7 @@ uint8_t PCE::cdrom_read(uint16_t addr) (d_scsi_host->read_signal(SIG_SCSI_IO) != 0)) { // STATUS PHASE: Porting from Ootake v2.83. // // busy = false; cdrom_regs[0x02] = cdrom_regs[0x02] & ~(0x80 | PCE_CD_IRQ_TRANSFER_READY | PCE_CD_IRQ_TRANSFER_DONE); + cdrom_regs[0x03] &= ~0x20; // SIGNAL_DONE : From Ootake v2.83. set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, CLEAR_LINE); } return data & ~0x40; // Clear REQ @@ -2129,7 +2124,6 @@ uint8_t PCE::cdrom_read(uint16_t addr) set_cdrom_irq_line(PCE_CD_IRQ_TRANSFER_DONE, ASSERT_LINE); d_adpcm->write_signal(SIG_ADPCM_DMA_RELEASED, 0xff, 0xff); } - } break; diff --git a/source/src/vm/pcengine/pce.h b/source/src/vm/pcengine/pce.h index a561f76be..0b7df49c0 100644 --- a/source/src/vm/pcengine/pce.h +++ b/source/src/vm/pcengine/pce.h @@ -227,7 +227,7 @@ class PCE : public DEVICE #endif public: - PCE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PCE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("PC-Engine Core")); @@ -246,9 +246,9 @@ class PCE : public DEVICE #ifdef SUPPORT_CDROM uint32_t __FASTCALL read_signal(int id); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); #endif - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pcengine/pcengine.cpp b/source/src/vm/pcengine/pcengine.cpp index 75b75e417..504a2c1cf 100644 --- a/source/src/vm/pcengine/pcengine.cpp +++ b/source/src/vm/pcengine/pcengine.cpp @@ -30,7 +30,7 @@ using PCEDEV::PCE; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -252,6 +252,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(pceevent == NULL) return 0.0; + return pceevent->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(pceevent == NULL) return (uint64_t)0; + return pceevent->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -264,7 +276,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pcengine/pcengine.h b/source/src/vm/pcengine/pcengine.h index aed9cec1b..7e2b1d9bb 100644 --- a/source/src/vm/pcengine/pcengine.h +++ b/source/src/vm/pcengine/pcengine.h @@ -24,6 +24,8 @@ #define SUPPORT_SUPER_GFX #define SUPPORT_BACKUP_RAM #define SUPPORT_CDROM +#define _SCSI_DEBUG_LOG +#define _CDROM_DEBUG_LOG //#define SCSI_HOST_AUTO_ACK #define SCSI_DEV_IMMEDIATE_SELECT @@ -101,7 +103,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -141,6 +143,10 @@ class VM : public VM_TEMPLATE { return false; } + + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pcm1bit.cpp b/source/src/vm/pcm1bit.cpp index ed7a54eff..943e1431f 100644 --- a/source/src/vm/pcm1bit.cpp +++ b/source/src/vm/pcm1bit.cpp @@ -172,8 +172,8 @@ void PCM1BIT::calc_low_pass_filter(int32_t* dst, int32_t* src, int samples, int memset(dst, 0x00, sizeof(int32_t) * samples * 2); return; } - __DECL_ALIGNED(16) float tval[(samples + 1) * 2]; - __DECL_ALIGNED(16) float oval[(samples + 1) * 2]; + __DECL_ALIGNED(16) float tval[(samples + 1) * 2 + 2]; + __DECL_ALIGNED(16) float oval[(samples + 1) * 2 + 2]; int __begin = 0; tval[0] = before_filter_l; @@ -230,8 +230,8 @@ void PCM1BIT::calc_high_pass_filter(int32_t* dst, int32_t* src, int samples, int memset(dst, 0x00, sizeof(int32_t) * samples * 2); return; } - __DECL_ALIGNED(16) float tval[(samples + 1) * 2]; - __DECL_ALIGNED(16) float oval[(samples + 1) * 2]; + __DECL_ALIGNED(16) float tval[(samples + 1) * 2 + 2]; + __DECL_ALIGNED(16) float oval[(samples + 1) * 2 + 2]; int __begin = 0; tval[0] = before_filter_l; diff --git a/source/src/vm/pcm1bit.h b/source/src/vm/pcm1bit.h index 10ac009b4..78cb0359b 100644 --- a/source/src/vm/pcm1bit.h +++ b/source/src/vm/pcm1bit.h @@ -18,9 +18,7 @@ #define SIG_PCM1BIT_ON 1 #define SIG_PCM1BIT_MUTE 2 -class VM; -class EMU; -class PCM1BIT : public DEVICE +class DLL_PREFIX PCM1BIT : public DEVICE { private: bool signal, on, mute; @@ -48,7 +46,7 @@ class PCM1BIT : public DEVICE void calc_high_pass_filter(int32_t* dst, int32_t* src, int samples, int is_set_val); public: - PCM1BIT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PCM1BIT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("1BIT PCM SOUND")); @@ -60,7 +58,7 @@ class PCM1BIT : public DEVICE void reset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_frame(); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); void set_high_pass_filter_freq(int freq, double quality = 1.0); void set_low_pass_filter_freq(int freq, double quality = 1.0); diff --git a/source/src/vm/phc20/CMakeLists.txt b/source/src/vm/phc20/CMakeLists.txt index d0a487f18..3427de903 100644 --- a/source/src/vm/phc20/CMakeLists.txt +++ b/source/src/vm/phc20/CMakeLists.txt @@ -1,13 +1,15 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/phc20") +message("* vm/${EXE_NAME}") set(VM_PHC20_LIB_SRCS + ../mc6847.cpp + + ./memory.cpp phc20.cpp - memory.cpp ) -add_library(vm_phc20 +add_library(vm_${EXE_NAME} ${VM_PHC20_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/phc20/memory.h b/source/src/vm/phc20/memory.h index 285045111..1dfcdc70d 100644 --- a/source/src/vm/phc20/memory.h +++ b/source/src/vm/phc20/memory.h @@ -37,7 +37,7 @@ class MEMORY : public DEVICE uint8_t sysport; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/phc20/phc20.cpp b/source/src/vm/phc20/phc20.cpp index 729e7dc15..9e2815850 100644 --- a/source/src/vm/phc20/phc20.cpp +++ b/source/src/vm/phc20/phc20.cpp @@ -29,7 +29,7 @@ using PHC20::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -270,6 +270,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -282,7 +294,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/phc20/phc20.h b/source/src/vm/phc20/phc20.h index 3b961e66f..9a38dd0eb 100644 --- a/source/src/vm/phc20/phc20.h +++ b/source/src/vm/phc20/phc20.h @@ -75,7 +75,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -123,6 +123,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/phc25/CMakeLists.txt b/source/src/vm/phc25/CMakeLists.txt index cc2882037..bac190ad0 100644 --- a/source/src/vm/phc25/CMakeLists.txt +++ b/source/src/vm/phc25/CMakeLists.txt @@ -1,16 +1,19 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/phc25") +message("* vm/${EXE_NAME}") set(VM_PHC25_LIB_SRCS - phc25.cpp - memory.cpp + ../mc6847.cpp + + ./memory.cpp joystick.cpp keyboard.cpp system.cpp + + phc25.cpp ) -add_library(vm_phc25 +add_library(vm_${EXE_NAME} ${VM_PHC25_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/phc25/joystick.h b/source/src/vm/phc25/joystick.h index a7d5d04bc..0614ef258 100644 --- a/source/src/vm/phc25/joystick.h +++ b/source/src/vm/phc25/joystick.h @@ -24,7 +24,7 @@ class JOYSTICK : public DEVICE const uint32_t *joy_stat; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/phc25/keyboard.cpp b/source/src/vm/phc25/keyboard.cpp index bb8113b4b..58fc247c5 100644 --- a/source/src/vm/phc25/keyboard.cpp +++ b/source/src/vm/phc25/keyboard.cpp @@ -77,10 +77,18 @@ uint32_t KEYBOARD::read_io8(uint32_t addr) return key_stat[key_map[addr - 0x7800]] ? 0 : 1; } else if(addr == 0x7850) { // LSHIFT +#if 0 return key_stat[0x10] ? 0 : 1; +#else + return key_stat[VK_LSHIFT] ? 0 : 1; +#endif } else if(addr == 0x7851) { // RSHIFT +#if 0 return 1; +#else + return key_stat[VK_RSHIFT] ? 0 : 1; +#endif } else if(addr == 0x7852) { // CTRL return key_stat[0x11] ? 0 : 1; diff --git a/source/src/vm/phc25/keyboard.h b/source/src/vm/phc25/keyboard.h index 20285211b..a5038e7a8 100644 --- a/source/src/vm/phc25/keyboard.h +++ b/source/src/vm/phc25/keyboard.h @@ -29,7 +29,7 @@ class KEYBOARD : public DEVICE #endif public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/phc25/memory.h b/source/src/vm/phc25/memory.h index c955569bd..6db1e2183 100644 --- a/source/src/vm/phc25/memory.h +++ b/source/src/vm/phc25/memory.h @@ -36,7 +36,7 @@ class MEMORY : public DEVICE uint8_t* rbank[32]; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/phc25/phc25.cpp b/source/src/vm/phc25/phc25.cpp index 13fd28178..720831fe5 100644 --- a/source/src/vm/phc25/phc25.cpp +++ b/source/src/vm/phc25/phc25.cpp @@ -40,7 +40,7 @@ using PHC25::SYSTEM; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -313,6 +313,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 5 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -325,7 +337,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/phc25/phc25.h b/source/src/vm/phc25/phc25.h index 31520e6af..be17e657a 100644 --- a/source/src/vm/phc25/phc25.h +++ b/source/src/vm/phc25/phc25.h @@ -99,7 +99,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -147,6 +147,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/phc25/system.h b/source/src/vm/phc25/system.h index 37826cc77..ac2d5a213 100644 --- a/source/src/vm/phc25/system.h +++ b/source/src/vm/phc25/system.h @@ -27,7 +27,7 @@ class SYSTEM : public DEVICE uint8_t sysport; public: - SYSTEM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SYSTEM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("System I/O")); } diff --git a/source/src/vm/prnfile.h b/source/src/vm/prnfile.h index 90a10d738..f01abb195 100644 --- a/source/src/vm/prnfile.h +++ b/source/src/vm/prnfile.h @@ -16,7 +16,7 @@ class FILEIO; -class PRNFILE : public DEVICE +class DLL_PREFIX PRNFILE : public DEVICE { private: outputs_t outputs_busy; @@ -29,13 +29,13 @@ class PRNFILE : public DEVICE bool _PRINTER_STROBE_RISING_EDGE; - void set_busy(bool value); - void set_ack(bool value); + void __FASTCALL set_busy(bool value); + void __FASTCALL set_ack(bool value); void open_file(); void close_file(); public: - PRNFILE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PRNFILE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_busy); initialize_output_signals(&outputs_ack); @@ -51,7 +51,7 @@ class PRNFILE : public DEVICE void event_frame(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/ptf20.h b/source/src/vm/ptf20.h index ecb706095..338bbb7cd 100644 --- a/source/src/vm/ptf20.h +++ b/source/src/vm/ptf20.h @@ -18,7 +18,7 @@ class DISK; -class PTF20 : public DEVICE +class DLL_PREFIX PTF20 : public DEVICE { private: outputs_t outputs_sio; @@ -34,7 +34,7 @@ class PTF20 : public DEVICE uint8_t* get_sector(int drv, int trk, int sec); public: - PTF20(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PTF20(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_sio); set_device_name(_T("Pseudo TF-20 FDD")); diff --git a/source/src/vm/pv1000/CMakeLists.txt b/source/src/vm/pv1000/CMakeLists.txt index 04e31da19..e6287690e 100644 --- a/source/src/vm/pv1000/CMakeLists.txt +++ b/source/src/vm/pv1000/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pv1000") +message("* vm/${EXE_NAME}") set(VM_PV1000_LIB_SRCS pv1000.cpp @@ -11,6 +11,6 @@ set(VM_PV1000_LIB_SRCS ) -add_library(vm_pv1000 +add_library(vm_${EXE_NAME} ${VM_PV1000_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/pv1000/joystick.h b/source/src/vm/pv1000/joystick.h index a8b47a862..86c785566 100644 --- a/source/src/vm/pv1000/joystick.h +++ b/source/src/vm/pv1000/joystick.h @@ -25,7 +25,7 @@ class JOYSTICK : public DEVICE uint8_t status; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/pv1000/psg.h b/source/src/vm/pv1000/psg.h index a39b7aba0..0508a91dd 100644 --- a/source/src/vm/pv1000/psg.h +++ b/source/src/vm/pv1000/psg.h @@ -28,7 +28,7 @@ class PSG : public DEVICE int volume_l, volume_r; public: - PSG(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PSG(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("PSG")); @@ -38,7 +38,7 @@ class PSG : public DEVICE // common functions void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pv1000/pv1000.cpp b/source/src/vm/pv1000/pv1000.cpp index da567678c..c8599e38f 100644 --- a/source/src/vm/pv1000/pv1000.cpp +++ b/source/src/vm/pv1000/pv1000.cpp @@ -32,7 +32,7 @@ using PV1000::VDP; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -42,6 +42,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io = new IO(this, emu); memory = new MEMORY(this, emu); + cpu = new Z80(this, emu); joystick = new JOYSTICK(this, emu); @@ -221,8 +222,19 @@ void VM::update_config() } } -#define STATE_VERSION 2 +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + +#define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) { @@ -234,7 +246,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pv1000/pv1000.h b/source/src/vm/pv1000/pv1000.h index e00914ae5..4a0c46145 100644 --- a/source/src/vm/pv1000/pv1000.h +++ b/source/src/vm/pv1000/pv1000.h @@ -97,7 +97,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -130,6 +130,9 @@ class VM : public VM_TEMPLATE bool is_cart_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pv1000/vdp.h b/source/src/vm/pv1000/vdp.h index ba44f804b..009b068e1 100644 --- a/source/src/vm/pv1000/vdp.h +++ b/source/src/vm/pv1000/vdp.h @@ -11,7 +11,7 @@ #define _VDP_H_ #include "../vm.h" -#include "../../emu.h" +#include "../../emu_template.h" #include "../device.h" namespace PV1000 { @@ -32,11 +32,11 @@ class VDP : public DEVICE int tmp_pcg_size; int tmp_pattern_size; - void draw_pattern(int x8, int y8, uint16_t top); - void draw_pcg(int x8, int y8, uint16_t top); + void __FASTCALL draw_pattern(int x8, int y8, uint16_t top); + void __FASTCALL draw_pcg(int x8, int y8, uint16_t top); public: - VDP(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + VDP(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("VDP")); } @@ -46,7 +46,7 @@ class VDP : public DEVICE void initialize(); void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_vline(int v, int clock); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pv2000/CMakeLists.txt b/source/src/vm/pv2000/CMakeLists.txt index 01237a07d..81dfb295b 100644 --- a/source/src/vm/pv2000/CMakeLists.txt +++ b/source/src/vm/pv2000/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pv2000") +message("* vm/${EXE_NAME}") set(VM_PV2000_LIB_SRCS pv2000.cpp @@ -11,6 +11,6 @@ set(VM_PV2000_LIB_SRCS ) -add_library(vm_pv2000 +add_library(vm_${EXE_NAME} ${VM_PV2000_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/pv2000/cmt.h b/source/src/vm/pv2000/cmt.h index 93ede1dfa..38641d648 100644 --- a/source/src/vm/pv2000/cmt.h +++ b/source/src/vm/pv2000/cmt.h @@ -11,7 +11,7 @@ #define _CMT_H_ #include "../vm.h" -#include "../../emu.h" +#include "../../emu_template.h" #include "../device.h" class FILEIO; @@ -30,7 +30,7 @@ class CMT : public DEVICE uint8_t start, bit; public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } diff --git a/source/src/vm/pv2000/keyboard.h b/source/src/vm/pv2000/keyboard.h index 237c15a5c..caccab6df 100644 --- a/source/src/vm/pv2000/keyboard.h +++ b/source/src/vm/pv2000/keyboard.h @@ -11,7 +11,7 @@ #define _KEYBOARD_H_ #include "../vm.h" -#include "../../emu.h" +#include "../../emu_template.h" #include "../device.h" namespace PV2000 { @@ -27,7 +27,7 @@ class KEYBOARD : public DEVICE bool intr_enb; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/pv2000/printer.h b/source/src/vm/pv2000/printer.h index 586e27753..d91d66262 100644 --- a/source/src/vm/pv2000/printer.h +++ b/source/src/vm/pv2000/printer.h @@ -11,7 +11,7 @@ #define _PRINTER_H_ #include "../vm.h" -#include "../../emu.h" +#include "../../emu_template.h" #include "../device.h" namespace PV2000 { @@ -23,7 +23,7 @@ class PRINTER : public DEVICE bool busy; public: - PRINTER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PRINTER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Printer I/F")); } diff --git a/source/src/vm/pv2000/pv2000.cpp b/source/src/vm/pv2000/pv2000.cpp index 38e72fd12..39f1cc6cc 100644 --- a/source/src/vm/pv2000/pv2000.cpp +++ b/source/src/vm/pv2000/pv2000.cpp @@ -34,7 +34,7 @@ using PV2000::PRINTER; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -44,6 +44,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io = new IO(this, emu); memory = new MEMORY(this, emu); + psg = new SN76489AN(this, emu); vdp = new TMS9918A(this, emu); #ifdef USE_DEBUGGER @@ -275,6 +276,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -287,7 +300,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pv2000/pv2000.h b/source/src/vm/pv2000/pv2000.h index 5d0dbc2f9..563f60489 100644 --- a/source/src/vm/pv2000/pv2000.h +++ b/source/src/vm/pv2000/pv2000.h @@ -95,7 +95,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -140,6 +140,9 @@ class VM : public VM_TEMPLATE bool is_tape_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/pyuta/CMakeLists.txt b/source/src/vm/pyuta/CMakeLists.txt index 0b125fd9f..c0d840c09 100644 --- a/source/src/vm/pyuta/CMakeLists.txt +++ b/source/src/vm/pyuta/CMakeLists.txt @@ -1,8 +1,10 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/pyuta") +message("* vm/emupyuta") - add_library(vm_pyuta - memory.cpp +add_library(vm_emupyuta + ../tms9995.cpp + ./memory.cpp + pyuta.cpp - ) +) diff --git a/source/src/vm/pyuta/memory.cpp b/source/src/vm/pyuta/memory.cpp index 81bf7e1a7..8cfd0cce0 100644 --- a/source/src/vm/pyuta/memory.cpp +++ b/source/src/vm/pyuta/memory.cpp @@ -296,12 +296,12 @@ void MEMORY::open_cart(const _TCHAR* file_path) if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { // 8kb - ctype = fio->Fread(cart, 0x2000, 1); + ctype = (int)fio->Fread(cart, 0x2000, 1); memcpy(cart + 0x2000, cart, 0x2000); // 16kb - ctype += fio->Fread(cart + 0x2000, 0x2000, 1); + ctype += (int)fio->Fread(cart + 0x2000, 0x2000, 1); // 32kb - ctype += fio->Fread(cart + 0x4000, 0x4000, 1); + ctype += (int)fio->Fread(cart + 0x4000, 0x4000, 1); fio->Fclose(); ENABLE_CART(); diff --git a/source/src/vm/pyuta/memory.h b/source/src/vm/pyuta/memory.h index b3e950663..e8e08af38 100644 --- a/source/src/vm/pyuta/memory.h +++ b/source/src/vm/pyuta/memory.h @@ -11,7 +11,7 @@ #define _PYUTA_MEMORY_H_ #include "../vm.h" -#include "../../emu.h" +#include "../../emu_template.h" #include "../device.h" namespace PYUTA { @@ -38,7 +38,7 @@ class MEMORY : public DEVICE const uint32_t *joy; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/pyuta/pyuta.cpp b/source/src/vm/pyuta/pyuta.cpp index 232688d7c..670c57800 100644 --- a/source/src/vm/pyuta/pyuta.cpp +++ b/source/src/vm/pyuta/pyuta.cpp @@ -29,7 +29,7 @@ using PYUTA::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -300,6 +300,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 5 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -312,7 +324,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/pyuta/pyuta.h b/source/src/vm/pyuta/pyuta.h index 371c1c8b7..93150be9b 100644 --- a/source/src/vm/pyuta/pyuta.h +++ b/source/src/vm/pyuta/pyuta.h @@ -78,7 +78,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -129,6 +129,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/qc10/CMakeLists.txt b/source/src/vm/qc10/CMakeLists.txt index f31d599b7..471bbc754 100644 --- a/source/src/vm/qc10/CMakeLists.txt +++ b/source/src/vm/qc10/CMakeLists.txt @@ -1,12 +1,14 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/qc10") +message("* vm/${EXE_NAME}") -add_library(vm_qc10 - qc10.cpp +add_library(vm_${EXE_NAME} + ../i8237.cpp + display.cpp floppy.cpp keyboard.cpp - memory.cpp mfont.cpp + ./memory.cpp + qc10.cpp ) diff --git a/source/src/vm/qc10/display.h b/source/src/vm/qc10/display.h index d33a1761f..36527d5c3 100644 --- a/source/src/vm/qc10/display.h +++ b/source/src/vm/qc10/display.h @@ -10,8 +10,8 @@ #ifndef _DISPLAY_H_ #define _DISPLAY_H_ -#include "../vm.h" -#include "../../emu.h" +#include "../vm_template.h" +#include "../../emu_template.h" #include "../device.h" #define VRAM_SIZE 0x20000 @@ -44,7 +44,7 @@ class DISPLAY : public DEVICE int blink; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/qc10/floppy.h b/source/src/vm/qc10/floppy.h index 7fc9700e9..35cdbf7c8 100644 --- a/source/src/vm/qc10/floppy.h +++ b/source/src/vm/qc10/floppy.h @@ -22,7 +22,7 @@ class FLOPPY : public DEVICE DEVICE *d_fdc, *d_mem; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/qc10/keyboard.h b/source/src/vm/qc10/keyboard.h index 2f3c30f51..7a9b0acc9 100644 --- a/source/src/vm/qc10/keyboard.h +++ b/source/src/vm/qc10/keyboard.h @@ -29,7 +29,7 @@ class KEYBOARD : public DEVICE const uint8_t* key_stat; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/qc10/memory.h b/source/src/vm/qc10/memory.h index 623a14424..f21d1286f 100644 --- a/source/src/vm/qc10/memory.h +++ b/source/src/vm/qc10/memory.h @@ -45,7 +45,7 @@ class MEMORY : public DEVICE bool fdc_irq, motor; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/qc10/mfont.h b/source/src/vm/qc10/mfont.h index ba3fede13..5e520a6da 100644 --- a/source/src/vm/qc10/mfont.h +++ b/source/src/vm/qc10/mfont.h @@ -29,7 +29,7 @@ class MFONT : public DEVICE FIFO *res; public: - MFONT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MFONT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Multi FONT ROM Card")); } diff --git a/source/src/vm/qc10/qc10.cpp b/source/src/vm/qc10/qc10.cpp index c17590275..d0e98c6ef 100644 --- a/source/src/vm/qc10/qc10.cpp +++ b/source/src/vm/qc10/qc10.cpp @@ -46,7 +46,7 @@ using QC10::MFONT; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -99,7 +99,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) event->set_context_sound(fdc->get_context_noise_head_down()); event->set_context_sound(fdc->get_context_noise_head_up()); - rtc->set_context_intr(pic, SIG_I8259_IR2 | SIG_I8259_CHIP1, 1); + rtc->set_context_intr_line(pic, SIG_I8259_IR2 | SIG_I8259_CHIP1, 1); dma0->set_context_memory(memory); dma0->set_context_ch0(fdc); dma0->set_context_ch1(gdc); @@ -360,6 +360,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -372,7 +384,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/qc10/qc10.h b/source/src/vm/qc10/qc10.h index c5b9592dc..8f4f70ef8 100644 --- a/source/src/vm/qc10/qc10.h +++ b/source/src/vm/qc10/qc10.h @@ -119,7 +119,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -160,6 +160,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/rp5c01.h b/source/src/vm/rp5c01.h index a41b1210b..b710af7be 100644 --- a/source/src/vm/rp5c01.h +++ b/source/src/vm/rp5c01.h @@ -14,9 +14,7 @@ //#include "../emu.h" #include "device.h" -class VM; -class EMU; -class RP5C01 : public DEVICE +class DLL_PREFIX RP5C01 : public DEVICE { private: // output signals @@ -42,7 +40,7 @@ class RP5C01 : public DEVICE void __FASTCALL write_to_cur_time(); public: - RP5C01(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + RP5C01(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_alarm); initialize_output_signals(&outputs_pulse); @@ -55,7 +53,7 @@ class RP5C01 : public DEVICE void release(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/rx78/CMakeLists.txt b/source/src/vm/rx78/CMakeLists.txt index 0db0411b7..12835ce04 100644 --- a/source/src/vm/rx78/CMakeLists.txt +++ b/source/src/vm/rx78/CMakeLists.txt @@ -1,12 +1,14 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/rx78") +message("* vm/emurx78") + +add_library(vm_emurx78 -add_library(vm_rx78 - rx78.cpp cmt.cpp keyboard.cpp memory.cpp printer.cpp vdp.cpp + + rx78.cpp ) diff --git a/source/src/vm/rx78/cmt.h b/source/src/vm/rx78/cmt.h index a1de2cdfb..3248b5d94 100644 --- a/source/src/vm/rx78/cmt.h +++ b/source/src/vm/rx78/cmt.h @@ -28,7 +28,7 @@ class CMT : public DEVICE int framecnt; public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } diff --git a/source/src/vm/rx78/keyboard.h b/source/src/vm/rx78/keyboard.h index bd381b0fa..d7a769953 100644 --- a/source/src/vm/rx78/keyboard.h +++ b/source/src/vm/rx78/keyboard.h @@ -24,7 +24,7 @@ class KEYBOARD : public DEVICE uint8_t status[16]; uint8_t column; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/rx78/memory.h b/source/src/vm/rx78/memory.h index af5ebedad..ef33ed8b2 100644 --- a/source/src/vm/rx78/memory.h +++ b/source/src/vm/rx78/memory.h @@ -36,7 +36,7 @@ class MEMORY : public DEVICE bool inserted; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/rx78/printer.h b/source/src/vm/rx78/printer.h index b66276f41..7e5429613 100644 --- a/source/src/vm/rx78/printer.h +++ b/source/src/vm/rx78/printer.h @@ -25,7 +25,7 @@ class PRINTER : public DEVICE uint8_t out; public: - PRINTER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PRINTER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Printer I/F")); } diff --git a/source/src/vm/rx78/rx78.cpp b/source/src/vm/rx78/rx78.cpp index 16ff4922a..678fc25fa 100644 --- a/source/src/vm/rx78/rx78.cpp +++ b/source/src/vm/rx78/rx78.cpp @@ -38,7 +38,7 @@ using RX78::VDP; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -321,6 +321,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -333,7 +345,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/rx78/rx78.h b/source/src/vm/rx78/rx78.h index ae078b257..3b0e59245 100644 --- a/source/src/vm/rx78/rx78.h +++ b/source/src/vm/rx78/rx78.h @@ -83,7 +83,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -134,6 +134,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/rx78/vdp.h b/source/src/vm/rx78/vdp.h index d0ba22452..3d2ec5ff7 100644 --- a/source/src/vm/rx78/vdp.h +++ b/source/src/vm/rx78/vdp.h @@ -32,7 +32,7 @@ class VDP : public DEVICE void create_bg(); public: - VDP(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + VDP(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("VDP")); } diff --git a/source/src/vm/sc3000/CMakeLists.txt b/source/src/vm/sc3000/CMakeLists.txt index de93e6da0..874c57a0e 100644 --- a/source/src/vm/sc3000/CMakeLists.txt +++ b/source/src/vm/sc3000/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/sc3000") +message("* vm/${EXE_NAME}") set(VM_SC3000_LIB_SRCS sc3000.cpp @@ -9,6 +9,6 @@ set(VM_SC3000_LIB_SRCS ) -add_library(vm_sc3000 +add_library(vm_${EXE_NAME} ${VM_SC3000_LIB_SRCS} -) \ No newline at end of file +) diff --git a/source/src/vm/sc3000/keyboard.h b/source/src/vm/sc3000/keyboard.h index fa8160558..0ad5a6b08 100644 --- a/source/src/vm/sc3000/keyboard.h +++ b/source/src/vm/sc3000/keyboard.h @@ -31,7 +31,7 @@ class KEYBOARD : public DEVICE void update_keyboard(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/sc3000/memory.h b/source/src/vm/sc3000/memory.h index 691d28675..79debea4d 100644 --- a/source/src/vm/sc3000/memory.h +++ b/source/src/vm/sc3000/memory.h @@ -38,7 +38,7 @@ class MEMORY : public DEVICE void update_bank(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/sc3000/sc3000.cpp b/source/src/vm/sc3000/sc3000.cpp index 931406325..23d9aade6 100644 --- a/source/src/vm/sc3000/sc3000.cpp +++ b/source/src/vm/sc3000/sc3000.cpp @@ -37,7 +37,7 @@ using SC3000::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -380,6 +380,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -392,7 +404,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/sc3000/sc3000.h b/source/src/vm/sc3000/sc3000.h index d60c544d5..f17a42ffd 100644 --- a/source/src/vm/sc3000/sc3000.h +++ b/source/src/vm/sc3000/sc3000.h @@ -47,7 +47,7 @@ static const _TCHAR *sound_device_caption[] = { }; #endif -class EMU; +class EMU_TEMPLATE; class DEVICE; class EVENT; @@ -91,7 +91,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -148,6 +148,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/scsi_cdrom.cpp b/source/src/vm/scsi_cdrom.cpp index 141256f07..dad6482f9 100644 --- a/source/src/vm/scsi_cdrom.cpp +++ b/source/src/vm/scsi_cdrom.cpp @@ -17,9 +17,6 @@ #define CDDA_PLAYING 1 #define CDDA_PAUSED 2 -#define _SCSI_DEBUG_LOG -#define _CDROM_DEBUG_LOG - // 0-99 is reserved for SCSI_DEV class #define EVENT_CDDA 100 #define EVENT_CDDA_DELAY_PLAY 101 @@ -32,6 +29,7 @@ void SCSI_CDROM::initialize() { SCSI_DEV::initialize(); fio_img = new FILEIO(); + __CDROM_DEBUG_LOG = osd->check_feature(_T("_CDROM_DEBUG_LOG")); if(44100 % emu->get_sound_rate() == 0) { mix_loop_num = 44100 / emu->get_sound_rate(); @@ -50,6 +48,19 @@ void SCSI_CDROM::initialize() } } +void SCSI_CDROM::out_debug_log(const _TCHAR *format, ...) +{ + if(!(__CDROM_DEBUG_LOG) && !(_OUT_DEBUG_LOG)) return; + va_list args; + _TCHAR _tmps[4096] = {0}; + _TCHAR _domain[256] = {0}; + my_sprintf_s(_domain, sizeof(_domain) / sizeof(_TCHAR), _T("[SCSI_CDROM:ID=%d]"), scsi_id); + va_start(args, format); + vsnprintf(_tmps, sizeof(_tmps) / sizeof(_TCHAR), format, args); + va_end(args); + DEVICE::out_debug_log(_T("%s %s"), _domain, _tmps); +} + void SCSI_CDROM::release() { if(fio_img->IsOpened()) { @@ -148,32 +159,61 @@ void SCSI_CDROM::event_callback(int event_id, int err) // ToDo: CLEAR IRQ Line (for PCE) if((cdda_buffer_ptr += 4) % 2352 == 0) { // one frame finished - if(++cdda_playing_frame == cdda_end_frame) { + cdda_playing_frame++; + if((is_cue) && (cdda_playing_frame != cdda_end_frame)) { + if((cdda_playing_frame >= toc_table[current_track + 1].index0) && (track_num > (current_track + 1))) { + get_track_by_track_num(current_track + 1); // Note: Increment current track + if(fio_img->IsOpened()) { + //fio_img->Fseek(0, FILEIO_SEEK_SET); + read_sectors = fio_img->Fread(cdda_buffer, 2352 * sizeof(uint8_t), array_length(cdda_buffer) / 2352); + } else { + // Seek error (maybe end of disc) + read_sectors = 0; + memset(cdda_buffer, 0x00, sizeof(cdda_buffer)); + } + cdda_buffer_ptr = 0; + access = false; + } + } + if(cdda_playing_frame == cdda_end_frame) { + out_debug_log(_T("Reaches to the end of track.(FRAME %d). START_FRAME=%d END_FRAME=%d REPEAT=%s INTERRUPT=%s\n"), + cdda_playing_frame, cdda_start_frame, cdda_end_frame, + (cdda_repeat) ? _T("YES") : _T("NO"), + (cdda_interrupt) ? _T("YES") : _T("NO")); // reached to end frame - #ifdef _CDROM_DEBUG_LOG - this->out_debug_log(_T("Reaches to the end of track.(FRAME %d). START_FRAME=%d END_FRAME=%d REPEAT=%s INTERRUPT=%s\n"), - cdda_playing_frame, cdda_start_frame, cdda_end_frame, - (cdda_repeat) ? _T("YES") : _T("NO"), (cdda_interrupt) ? _T("YES") : _T("NO")); - #endif if(cdda_repeat) { // reload buffer + // Restart. if(is_cue) { - fio_img->Fclose(); + int trk = get_track(cdda_start_frame); + if(fio_img->IsOpened()) { + fio_img->Fseek((cdda_start_frame - toc_table[trk].lba_offset) * 2352, FILEIO_SEEK_SET); + } +// fio_img->Fclose(); //current_track = 0; //int trk = get_track(cdda_start_frame); - int trk = current_track; - fio_img->Fseek((cdda_start_frame - toc_table[trk].lba_offset) * 2352, FILEIO_SEEK_SET); +// int trk = current_track; +// fio_img->Fseek((cdda_start_frame - toc_table[trk].lba_offset) * 2352, FILEIO_SEEK_SET); } else { fio_img->Fseek(cdda_start_frame * 2352, FILEIO_SEEK_SET); } - read_sectors = fio_img->Fread(cdda_buffer, 2352 * sizeof(uint8_t) , array_length(cdda_buffer) / 2352); + if(fio_img->IsOpened()) { + read_sectors = fio_img->Fread(cdda_buffer, 2352 * sizeof(uint8_t) , array_length(cdda_buffer) / 2352); + } else { + read_sectors = 0; + memset(cdda_buffer, 0x00, sizeof(cdda_buffer)); + } +// read_sectors = fio_img->Fread(cdda_buffer, 2352 * sizeof(uint8_t) , array_length(cdda_buffer) / 2352); cdda_buffer_ptr = 0; cdda_playing_frame = cdda_start_frame; access = true; } else { // Stop - //if(event_cdda_delay_play >= 0) cancel_event(this, event_cdda_delay_play); - set_cdda_status(CDDA_OFF); + if(event_cdda_delay_play >= 0) cancel_event(this, event_cdda_delay_play); + memset(cdda_buffer, 0x00, sizeof(cdda_buffer)); + register_event(this, EVENT_CDDA_DELAY_STOP, 1000.0, false, &event_cdda_delay_play); + + //set_cdda_status(CDDA_OFF); //register_event(this, EVENT_CDDA_DELAY_STOP, 1000.0, false, &event_cdda_delay_play); access = false; } @@ -181,7 +221,13 @@ void SCSI_CDROM::event_callback(int event_id, int err) // refresh buffer read_sectors--; if(read_sectors <= 0) { - read_sectors = fio_img->Fread(cdda_buffer, 2352 * sizeof(uint8_t), array_length(cdda_buffer) / 2352); + if(fio_img->IsOpened()) { + read_sectors = fio_img->Fread(cdda_buffer, 2352 * sizeof(uint8_t), array_length(cdda_buffer) / 2352); + } else { + read_sectors = 0; + memset(cdda_buffer, 0x00, sizeof(cdda_buffer)); + } +// read_sectors = fio_img->Fread(cdda_buffer, 2352 * sizeof(uint8_t), array_length(cdda_buffer) / 2352); cdda_buffer_ptr = 0; access = false; } else { @@ -226,9 +272,7 @@ void SCSI_CDROM::set_cdda_status(uint8_t status) } touch_sound(); set_realtime_render(this, true); - #ifdef _CDROM_DEBUG_LOG - this->out_debug_log(_T("Play CDDA from %s.\n"), (cdda_status == CDDA_PAUSED) ? _T("PAUSED") : _T("STOPPED")); - #endif + out_debug_log(_T("Play CDDA from %s.\n"), (cdda_status == CDDA_PAUSED) ? _T("PAUSED") : _T("STOPPED")); } } else { if(event_cdda != -1) { @@ -252,9 +296,7 @@ void SCSI_CDROM::set_cdda_status(uint8_t status) } touch_sound(); set_realtime_render(this, false); - #ifdef _CDROM_DEBUG_LOG - this->out_debug_log(_T("%s playing CDDA.\n"), (status == CDDA_PAUSED) ? _T("PAUSE") : _T("STOP")); - #endif + out_debug_log(_T("%s playing CDDA.\n"), (status == CDDA_PAUSED) ? _T("PAUSE") : _T("STOP")); } } cdda_status = status; @@ -301,9 +343,7 @@ void SCSI_CDROM::get_track_by_track_num(int track) if(fio_img->IsOpened()) { fio_img->Fclose(); } - #ifdef _CDROM_DEBUG_LOG - this->out_debug_log(_T("LOAD TRK #%02d from %s\n"), track, track_data_path[track - 1]); - #endif + out_debug_log(_T("LOAD TRK #%02d from %s\n"), track, track_data_path[track - 1]); if((track > 0) && (track < 100) && (track < track_num)) { if((strlen(track_data_path[track - 1]) <= 0) || @@ -396,12 +436,9 @@ uint32_t SCSI_CDROM::lba_to_msf_alt(uint32_t lba) void SCSI_CDROM::start_command() { touch_sound(); - #ifdef _SCSI_DEBUG_LOG - //this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: #%02x %02x %02x %02x %02x %02x\n"), scsi_id, command[0], command[1], command[2], command[3], command[4], command[5]); - #endif + //out_debug_log(_T("Command: #%02x %02x %02x %02x %02x %02x\n"), command[0], command[1], command[2], command[3], command[4], command[5]); switch(command[0]) { case SCSI_CMD_READ6: - //seek_time = 10;//get_seek_time((command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]); seek_time = get_seek_time((command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]); set_cdda_status(CDDA_OFF); if(seek_time > 10.0) { @@ -417,7 +454,7 @@ void SCSI_CDROM::start_command() break; case SCSI_CMD_READ10: case SCSI_CMD_READ12: - seek_time = get_seek_time((command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]); + seek_time = get_seek_time(command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5]); set_cdda_status(CDDA_OFF); if(seek_time > 10.0) { if(event_cdda_delay_play >= 0) { @@ -432,9 +469,7 @@ void SCSI_CDROM::start_command() break; case SCSI_CMD_MODE_SEL6: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Read Mode Select 6-byte\n"), scsi_id); - #endif + out_debug_log(_T("Command: NEC Read Mode Select 6-byte\n"), scsi_id); // start position set_cdda_status(CDDA_OFF); // position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; @@ -457,9 +492,7 @@ void SCSI_CDROM::start_command() return; case 0xd8: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Set Audio Playback Start Position CMD=%02x ARG=%02x %02x %02x %02x %02x\n"), scsi_id, command[9], command[1], command[2], command[3], command[4], command[5]); - #endif + out_debug_log(_T("Command: NEC Set Audio Playback Start Position CMD=%02x ARG=%02x %02x %02x %02x %02x\n"), command[9], command[1], command[2], command[3], command[4], command[5]); if(is_device_ready()) { bool req_play = false; if(command[2] == 0 && command[3] == 0 && command[4] == 0) { @@ -527,9 +560,7 @@ void SCSI_CDROM::start_command() } #if 1 if(is_cue) { -// if(cdda_start_frame >= (toc_table[current_track].index0 + toc_table[current_track].pregap)) cdda_start_frame = cdda_start_frame - toc_table[current_track].pregap; fio_img->Fseek((cdda_start_frame - toc_table[current_track].index0) * 2352, FILEIO_SEEK_SET); - //fio_img->Fseek((cdda_start_frame - toc_table[current_track].lba_offset) * 2352, FILEIO_SEEK_SET); } else { fio_img->Fseek(cdda_start_frame * 2352, FILEIO_SEEK_SET); } @@ -591,9 +622,7 @@ void SCSI_CDROM::start_command() return; case 0xd9: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Set Audio Playback End Position CMD=%02x ARG=%02x %02x %02x %02x %02x\n"), scsi_id, command[9], command[1], command[2], command[3], command[4], command[5]); - #endif + out_debug_log(_T("Command: NEC Set Audio Playback End Position CMD=%02x ARG=%02x %02x %02x %02x %02x\n"), scsi_id, command[9], command[1], command[2], command[3], command[4], command[5]); if(is_device_ready()) { switch(command[9] & 0xc0) { @@ -677,9 +706,7 @@ void SCSI_CDROM::start_command() return; case 0xda: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Pause\n"), scsi_id); - #endif + out_debug_log(_T("Command: NEC Pause\n")); if(is_device_ready()) { if(cdda_status == CDDA_PLAYING) { set_cdda_status(CDDA_PAUSED); @@ -692,9 +719,7 @@ void SCSI_CDROM::start_command() return; case 0xdd: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Read Sub Channel Q\n"), scsi_id); - #endif + out_debug_log(_T("Command: NEC Read Sub Channel Q\n")); if(is_device_ready()) { // create track info uint32_t frame = (cdda_status == CDDA_OFF) ? cdda_start_frame : cdda_playing_frame; @@ -738,14 +763,10 @@ void SCSI_CDROM::start_command() return; case 0xde: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: NEC Get Dir Info\n"), scsi_id); - #endif + out_debug_log(_T("Command: NEC Get Dir Info\n")); if(is_device_ready()) { buffer->clear(); - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] CMD=%02x ARG=%02x \n"), scsi_id, command[1], command[2]); - #endif + out_debug_log(_T("CMD=%02x ARG=%02x \n"), command[1], command[2]); switch(command[1]) { case 0x00: /* Get first and last track numbers */ buffer->write(TO_BCD(1)); @@ -820,22 +841,16 @@ bool SCSI_CDROM::read_buffer(int length) if(is_cue) { // ToDo: Need seek wait. - #ifdef _CDROM_DEBUG_LOG - this->out_debug_log(_T("Seek to LBA %d LENGTH=%d\n"), position / 2352, length); - #endif + out_debug_log(_T("Seek to LBA %d LENGTH=%d\n"), position / 2352, length); if(fio_img->Fseek(((long)position - (long)(toc_table[current_track].lba_offset * 2352)), FILEIO_SEEK_SET) != 0) { set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_SEEKERR - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Error on reading (ILLGLBLKADDR) at line %d\n"), scsi_id, __LINE__); - #endif + out_debug_log(_T("Error on reading (ILLGLBLKADDR) at line %d\n"), __LINE__); return false; } } else { if(fio_img->Fseek((long)position, FILEIO_SEEK_SET) != 0) { set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_SEEKERR - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Error on reading (ILLGLBLKADDR) at line %d\n"), scsi_id, __LINE__); - #endif + out_debug_log(_T("Error on reading (ILLGLBLKADDR) at line %d\n"), __LINE__); return false; } } @@ -845,10 +860,7 @@ bool SCSI_CDROM::read_buffer(int length) int tmp_length = 2352 - offset; if(fio_img->Fread(tmp_buffer, tmp_length, 1) != 1) { - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Error on reading (ILLGLBLKADDR) at line %d\n"), scsi_id, __LINE__); - #endif - + out_debug_log(_T("Error on reading (ILLGLBLKADDR) at line %d\n"), __LINE__); set_sense_code(SCSI_SENSE_ILLGLBLKADDR); //SCSI_SENSE_NORECORDFND return false; } @@ -860,9 +872,15 @@ bool SCSI_CDROM::read_buffer(int length) } position++; offset = (offset + 1) % 2352; +// if(offset == 0) { +// if(length > 0) { +// write_signals(&outputs_next_sector, 0xffffffff); +// } +// } } access = true; } +// write_signals(&outputs_completed, 0xffffffff); // Is This right? 20181120 K.O //write_signals(&outputs_done, 0xffffffff); // Maybe don't need "DONE SIGNAL" with reading DATA TRACK. 20181207 K.O set_sense_code(SCSI_SENSE_NOSENSE); @@ -875,14 +893,10 @@ bool SCSI_CDROM::write_buffer(int length) int value = buffer->read(); if(command[0] == SCSI_CMD_MODE_SEL6) { if(i == 4) { - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Read Mode = %02X\n"), scsi_id, value); - #endif + out_debug_log(_T("NEC Read Mode = %02X\n"), value); read_mode = (value != 0); } else if(i == 10) { - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] NEC Retry Count = %02X\n"), scsi_id, value); - #endif + out_debug_log(_T("NEC Retry Count = %02X\n"), value); } } position++; @@ -1030,9 +1044,7 @@ bool SCSI_CDROM::open_cue_file(const _TCHAR* file_path) image_tmp_data_path = std::string(parent_dir); image_tmp_data_path.append(_arg2); - #ifdef _CDROM_DEBUG_LOG - this->out_debug_log(_T("**FILE %s\n"), image_tmp_data_path.c_str()); - #endif + out_debug_log(_T("**FILE %s\n"), image_tmp_data_path.c_str()); goto _n_continue; // ToDo: Check ARG2 (BINARY etc..) 20181118 K.O } else if(_arg1 == "TRACK") { _arg2_ptr_s = _arg2.find_first_of((const char *)" \t"); @@ -1171,7 +1183,7 @@ bool SCSI_CDROM::open_cue_file(const _TCHAR* file_path) //#ifdef _CDROM_DEBUG_LOG - this->out_debug_log(_T("TRACK#%02d TYPE=%s PREGAP=%d INDEX0=%d INDEX1=%d LBA_SIZE=%d LBA_OFFSET=%d PATH=%s\n"), + out_debug_log(_T("TRACK#%02d TYPE=%s PREGAP=%d INDEX0=%d INDEX1=%d LBA_SIZE=%d LBA_OFFSET=%d PATH=%s\n"), i, (toc_table[i].is_audio) ? _T("AUDIO") : _T("MODE1/2352"), toc_table[i].pregap, toc_table[i].index0, toc_table[i].index1, toc_table[i].lba_size, toc_table[i].lba_offset, track_data_path[i - 1]); @@ -1270,8 +1282,8 @@ void SCSI_CDROM::open(const _TCHAR* file_path) } } } -#ifdef _SCSI_DEBUG_LOG - if(mounted()) { + + if(mounted() && (__SCSI_DEBUG_LOG)) { for(int i = 0; i < track_num + 1; i++) { uint32_t idx0_msf = lba_to_msf(toc_table[i].index0); uint32_t idx1_msf = lba_to_msf(toc_table[i].index1); @@ -1282,7 +1294,6 @@ void SCSI_CDROM::open(const _TCHAR* file_path) (pgap_msf >> 16) & 0xff, (pgap_msf >> 8) & 0xff, pgap_msf & 0xff); } } -#endif } void SCSI_CDROM::close() diff --git a/source/src/vm/scsi_cdrom.h b/source/src/vm/scsi_cdrom.h index a9c195a13..3b46c57c1 100644 --- a/source/src/vm/scsi_cdrom.h +++ b/source/src/vm/scsi_cdrom.h @@ -21,7 +21,7 @@ class FILEIO; -class SCSI_CDROM : public SCSI_DEV +class DLL_PREFIX SCSI_CDROM : public SCSI_DEV { protected: outputs_t outputs_done; @@ -54,23 +54,24 @@ class SCSI_CDROM : public SCSI_DEV bool read_mode; - void set_cdda_status(uint8_t status); + void __FASTCALL set_cdda_status(uint8_t status); int get_track(uint32_t lba); - double get_seek_time(uint32_t lba); + double __FASTCALL get_seek_time(uint32_t lba); int volume_m; int volume_l, volume_r; bool open_cue_file(const _TCHAR *file_path); - void get_track_by_track_num(int track); - int get_track_noop(uint32_t lba); - uint32_t lba_to_msf(uint32_t lba); - uint32_t lba_to_msf_alt(uint32_t lba); + void __FASTCALL get_track_by_track_num(int track); + int __FASTCALL get_track_noop(uint32_t lba); + uint32_t __FASTCALL lba_to_msf(uint32_t lba); + uint32_t __FASTCALL lba_to_msf_alt(uint32_t lba); + bool __CDROM_DEBUG_LOG; public: - SCSI_CDROM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : SCSI_DEV(parent_vm, parent_emu) + SCSI_CDROM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : SCSI_DEV(parent_vm, parent_emu) { initialize_output_signals(&outputs_done); - + __CDROM_DEBUG_LOG = false; volume_m = 1024; volume_l = volume_r = 1024; @@ -82,6 +83,7 @@ class SCSI_CDROM : public SCSI_DEV // seek_time = 400000; // 400msec (temporary) seek_time = 10.0; bytes_per_sec = 2048 * 75; // speed x1 + data_req_delay = 0.1; max_logical_block = 0; access = false; @@ -95,10 +97,11 @@ class SCSI_CDROM : public SCSI_DEV virtual void reset(); virtual uint32_t __FASTCALL read_signal(int id); virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - virtual void event_callback(int event_id, int err); - virtual void mix(int32_t* buffer, int cnt); + virtual void __FASTCALL event_callback(int event_id, int err); + virtual void __FASTCALL mix(int32_t* buffer, int cnt); virtual void set_volume(int ch, int decibel_l, int decibel_r); virtual bool process_state(FILEIO* state_fio, bool loading); + virtual void out_debug_log(const _TCHAR *format, ...); // virtual scsi functions virtual void reset_device(); diff --git a/source/src/vm/scsi_dev.cpp b/source/src/vm/scsi_dev.cpp index 9230a3f2a..043ca085a 100644 --- a/source/src/vm/scsi_dev.cpp +++ b/source/src/vm/scsi_dev.cpp @@ -20,6 +20,26 @@ void SCSI_DEV::initialize() DEVICE::initialize(); buffer = new FIFO(SCSI_BUFFER_SIZE); phase = SCSI_PHASE_BUS_FREE; + _SCSI_DEV_IMMEDIATE_SELECT = osd->check_feature(_T("SCSI_DEV_IMMEDIATE_SELECT")); + __SCSI_DEBUG_LOG = osd->check_feature(_T("_SCSI_DEBUG_LOG")); + _SCSI_HOST_WIDE = osd->check_feature(_T("SCSI_HOST_WIDE")); + _OUT_DEBUG_LOG = false; // Temporally. + if(_SCSI_HOST_WIDE) { + update_signal_mask(&outputs_dat, NULL, 0xffff); // Update to 16bit wide. + } +} + +void SCSI_DEV::out_debug_log(const _TCHAR *format, ...) +{ + if(!(__SCSI_DEBUG_LOG) && !(_OUT_DEBUG_LOG)) return; + va_list args; + _TCHAR _tmps[4096] = {0}; + _TCHAR _domain[256] = {0}; + my_sprintf_s(_domain, sizeof(_domain) / sizeof(_TCHAR), _T("[SCSI_DEV:ID=%d]"), scsi_id); + va_start(args, format); + vsnprintf(_tmps, sizeof(_tmps) / sizeof(_TCHAR), format, args); + va_end(args); + DEVICE::out_debug_log(_T("%s %s"), _domain, _tmps); } void SCSI_DEV::release() @@ -44,6 +64,7 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) switch(id) { case SIG_SCSI_DAT: data_bus = data & mask; +// out_debug_log(_T("DATA=%04X"), data_bus); break; case SIG_SCSI_SEL: @@ -55,14 +76,14 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) // this device is already selected } else if(!prev_status && sel_status) { // L -> H -#ifdef SCSI_DEV_IMMEDIATE_SELECT - event_callback(EVENT_SEL, 0); -#else - if(event_sel != -1) { - cancel_event(this, event_sel); + if(_SCSI_DEV_IMMEDIATE_SELECT) { + event_callback(EVENT_SEL, 0); + } else { + if(event_sel != -1) { + cancel_event(this, event_sel); + } + register_event(this, EVENT_SEL, 20.0, false, &event_sel); } - register_event(this, EVENT_SEL, 20.0, false, &event_sel); -#endif } else if(prev_status && !sel_status) { // H -> L if(event_sel != -1) { @@ -96,9 +117,7 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) // this device is not selected } else if(!prev_status && atn_status) { // L -> H - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] ATN signal raised\n"), scsi_id); - #endif + out_debug_log(_T("ATN signal raised\n")); if(ack_status) { // wait until ack=off atn_pending = true; @@ -143,7 +162,7 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) */ bool prev_status = ack_status; ack_status = ((data & mask) != 0); - +// out_debug_log(_T("ACK=%s"), (ack_status) ? _T("ON") : _T("OFF")); if(phase == SCSI_PHASE_BUS_FREE) { // this device is not selected } else if(!prev_status & ack_status) { @@ -168,7 +187,7 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) buffer->write(data_bus); break; } - set_req_delay(0, 0.1); + set_req_delay(0, data_req_delay); // thanks Mr.Sato } else if(prev_status && !ack_status) { // H -> L if(atn_pending) { @@ -198,7 +217,13 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) { next_req_usec += 1000000.0 / bytes_per_sec; double usec = next_req_usec - get_passed_usec(first_req_clock); - set_req_delay(1, (usec > 1.0) ? usec : 1.0); + set_req_delay(1, (usec > 0.2) ? usec : 0.2); + if(logical_block_size() > 0) { + local_data_pos = (local_data_pos + 1) % logical_block_size(); + if(local_data_pos == 0) { + write_signals(&outputs_next_sector, 0xffffffff); + } + } } break; default: @@ -218,6 +243,13 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) buffer->clear(); // just in case } // change to status phase + switch(command[0]) { + case SCSI_CMD_WRITE6: + case SCSI_CMD_WRITE10: + case SCSI_CMD_WRITE12: + write_signals(&outputs_completed, 0xffffffff); + break; + } set_dat(SCSI_STATUS_GOOD); set_sense_code(SCSI_SENSE_NOSENSE); set_phase_delay(SCSI_PHASE_STATUS, 10.0); @@ -229,6 +261,7 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) // update buffer if(buffer->count() == 0) { int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain; + out_debug_log(_T("LOAD BUFFER to %d bytes"), length); if(!read_buffer(length)) { // change to status phase set_dat(SCSI_STATUS_CHKCOND); @@ -245,16 +278,30 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) { next_req_usec += 1000000.0 / bytes_per_sec; double usec = next_req_usec - get_passed_usec(first_req_clock); - set_req_delay(1, (usec > 1.0) ? usec : 1.0); + set_req_delay(1, (usec > 0.2) ? usec : 0.2); //set_req_delay(1, usec); + if(logical_block_size() > 0) { + local_data_pos = (local_data_pos + 1) % logical_block_size(); + if(local_data_pos == 0) { + write_signals(&outputs_next_sector, 0xffffffff); + } + } } break; default: - set_req_delay(1, 1.0); + set_req_delay(1, 10.0); break; } } else { // change to status phase + switch(command[0]) { + case SCSI_CMD_READ6: + case SCSI_CMD_READ10: + case SCSI_CMD_READ12: + case SCSI_CMD_INQUIRY: + write_signals(&outputs_completed, 0xffffffff); + break; + } set_dat(SCSI_STATUS_GOOD); set_sense_code(SCSI_SENSE_NOSENSE); set_phase_delay(SCSI_PHASE_STATUS, 10.0); @@ -264,7 +311,9 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) case SCSI_PHASE_COMMAND: if(command_index < get_command_length(command[0])) { // request next command - set_req_delay(1, 1.0); +// set_req_delay(1, 1.0); + // Q:Command wait may be longet than 1.0us? 20200316 K.O + set_req_delay(1, 10.0); } else { // start command start_command(); @@ -316,9 +365,8 @@ void SCSI_DEV::write_signal(int id, uint32_t data, uint32_t mask) if(!prev_status & rst_status) { // L -> H - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] RST signal raised\n"), scsi_id); - #endif + out_debug_log(_T("RST signal raised\n")); + local_data_pos = 0; reset_device(); set_phase(SCSI_PHASE_BUS_FREE); } @@ -335,15 +383,12 @@ void SCSI_DEV::event_callback(int event_id, int err) if((data_bus & 0x7f) == (1 << scsi_id)) { if(is_device_existing()) { // this device is selected! - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] This device is selected\n"), scsi_id); - #endif + out_debug_log(_T("This device is selected\n")); set_bsy(true); selected = true; } } break; - case EVENT_PHASE: event_phase = -1; set_phase(next_phase); @@ -358,9 +403,7 @@ void SCSI_DEV::event_callback(int event_id, int err) void SCSI_DEV::set_phase(int value) { - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Phase %s -> %s\n"), scsi_id, scsi_phase_name[phase], scsi_phase_name[value]); - #endif + out_debug_log(_T("Phase %s -> %s\n"), scsi_phase_name[phase], scsi_phase_name[value]); if(event_phase != -1) { cancel_event(this, event_phase); event_phase = -1; @@ -370,13 +413,20 @@ void SCSI_DEV::set_phase(int value) set_cd (value & 4); if(value == SCSI_PHASE_BUS_FREE) { + if(phase != value) { + write_signals(&outputs_clrq, 0xffffffff); + } set_bsy(false); set_req(0); selected = false; } else { + if(phase != value) { + write_signals(&outputs_clrq, 0xffffffff); + } first_req_clock = 0; // set_bsy(true); set_req_delay(1, 10.0); + } phase = value; } @@ -397,49 +447,39 @@ void SCSI_DEV::set_phase_delay(int value, double usec) void SCSI_DEV::set_dat(int value) { - #ifdef _SCSI_DEBUG_LOG + if(__SCSI_DEBUG_LOG) { // emu->force_out_debug_log(_T("[SCSI_DEV:ID=%d] DATA = %02x\n"), scsi_id, value); - #endif + } write_signals(&outputs_dat, value); } void SCSI_DEV::set_bsy(int value) { - #ifdef _SCSI_DEBUG_LOG -// this->out_debug_log(_T("[SCSI_DEV:ID=%d] BUSY = %d\n"), scsi_id, value ? 1 : 0); - #endif +// out_debug_log(_T("BUSY = %d\n"), value ? 1 : 0); write_signals(&outputs_bsy, value ? 0xffffffff : 0); } void SCSI_DEV::set_cd(int value) { - #ifdef _SCSI_DEBUG_LOG -// this->out_debug_log(_T("[SCSI_DEV:ID=%d] C/D = %d\n"), scsi_id, value ? 1 : 0); - #endif +// out_debug_log(_T("C/D = %d\n"), value ? 1 : 0); write_signals(&outputs_cd, value ? 0xffffffff : 0); } void SCSI_DEV::set_io(int value) { - #ifdef _SCSI_DEBUG_LOG -// this->out_debug_log(_T("[SCSI_DEV:ID=%d] I/O = %d\n"), scsi_id, value ? 1 : 0); - #endif +// out_debug_log(_T("I/O = %d\n"), value ? 1 : 0); write_signals(&outputs_io, value ? 0xffffffff : 0); } void SCSI_DEV::set_msg(int value) { - #ifdef _SCSI_DEBUG_LOG -// this->out_debug_log(_T("[SCSI_DEV:ID=%d] MSG = %d\n"), scsi_id, value ? 1 : 0); - #endif +// out_debug_log(_T("MSG = %d\n"), value ? 1 : 0); write_signals(&outputs_msg, value ? 0xffffffff : 0); } void SCSI_DEV::set_req(int value) { - #ifdef _SCSI_DEBUG_LOG -// this->out_debug_log(_T("[SCSI_DEV:ID=%d] REQ = %d\n"), scsi_id, value ? 1 : 0); - #endif +// out_debug_log(_T("REQ = %d\n"), value ? 1 : 0); if(event_req != -1) { cancel_event(this, event_req); event_req = -1; @@ -484,11 +524,11 @@ int SCSI_DEV::get_command_length(int value) void SCSI_DEV::start_command() { + local_data_pos = 0; + double delay; switch(command[0]) { case SCSI_CMD_TST_U_RDY: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Test Unit Ready\n"), scsi_id); - #endif + out_debug_log(_T("Command: Test Unit Ready\n")); // change to status phase if(!is_device_ready()) { set_dat(SCSI_STATUS_CHKCOND); @@ -497,13 +537,11 @@ void SCSI_DEV::start_command() set_dat(SCSI_STATUS_GOOD); set_sense_code(SCSI_SENSE_NOSENSE); } - set_phase_delay(SCSI_PHASE_STATUS, 10.0); + set_phase_delay(SCSI_PHASE_STATUS, 1000.0); break; case SCSI_CMD_REQ_SENSE: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Request Sense\n"), scsi_id); - #endif + out_debug_log(_T("Command: Request Sense\n")); // start position position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; position *= physical_block_size(); @@ -523,18 +561,15 @@ void SCSI_DEV::start_command() } // change to data in phase set_dat(buffer->read()); - set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); + set_phase_delay(SCSI_PHASE_DATA_IN, 1000.0); break; case SCSI_CMD_INQUIRY: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Inquiry\n"), scsi_id); - #endif + out_debug_log(_T("Command: Inquiry\n")); // start position position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; position *= physical_block_size(); // transfer length - remain = 32; // create inquiry data table buffer->clear(); buffer->write(device_type); @@ -548,24 +583,23 @@ void SCSI_DEV::start_command() for(int i = 0; i < (int)strlen(vendor_id) && i < 8; i++) { buffer->write(vendor_id[i]); } - for(int i = strlen(vendor_id); i < 8; i++) { + for(int i = (int)strlen(vendor_id); i < 8; i++) { buffer->write(0x20); } for(int i = 0; i < (int)strlen(product_id) && i < 16; i++) { buffer->write(vendor_id[i]); } - for(int i = strlen(product_id); i < 16; i++) { + for(int i = (int)strlen(product_id); i < 16; i++) { buffer->write(0x20); } // change to data in phase set_dat(buffer->read()); - set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); + remain = buffer->count(); + set_phase_delay(SCSI_PHASE_DATA_IN, 1000.0); break; case SCSI_CMD_RD_CAPAC: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Capacity\n"), scsi_id); - #endif + out_debug_log(_T("Command: Read Capacity\n")); // start position position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5]; position *= physical_block_size(); @@ -583,13 +617,12 @@ void SCSI_DEV::start_command() buffer->write(( logical_block_size() >> 0) & 0xff); // change to data in phase set_dat(buffer->read()); - set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); +// set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); + set_phase_delay(SCSI_PHASE_DATA_IN, 1000.0); break; case SCSI_CMD_FORMAT: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Format Unit\n"), scsi_id); - #endif + out_debug_log(_T("Command: Format Unit\n")); if(command[1] & 0x10) { // change to data out phase for extra bytes remain = 4; @@ -597,14 +630,12 @@ void SCSI_DEV::start_command() } else { // no extra bytes, change to status phase set_dat(SCSI_STATUS_GOOD); - set_phase_delay(SCSI_PHASE_STATUS, 10.0); + set_phase_delay(SCSI_PHASE_STATUS, 1000.0); } break; case SCSI_CMD_RD_DEFECT: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read Defect Data\n"), scsi_id); - #endif + out_debug_log(_T("Command: Read Defect Data\n")); // transfer length remain = 4; // create detect data table @@ -615,18 +646,18 @@ void SCSI_DEV::start_command() buffer->write(0x00); // lsb of defect list length // change to data in phase set_dat(buffer->read()); - set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); + set_phase_delay(SCSI_PHASE_DATA_IN, 1000.0); break; case SCSI_CMD_READ6: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 6-byte\n"), scsi_id); - #endif // start position position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; + out_debug_log(_T("Command: Read 6-byte LBA=%d BLOCKS=%d\n"), position, command[4]); position *= physical_block_size(); // transfer length - remain = command[4] * logical_block_size(); + remain = (command[4] > 0 ? command[4] : 0x100) * logical_block_size(); // thanks Mr.Sato + // seek time + delay = get_seek_time(position, remain); if(remain != 0) { // read data buffer buffer->clear(); @@ -639,7 +670,7 @@ void SCSI_DEV::start_command() } // change to data in phase set_dat(buffer->read()); - set_phase_delay(SCSI_PHASE_DATA_IN, seek_time); + set_phase_delay(SCSI_PHASE_DATA_IN, delay); } else { // transfer length is zero, change to status phase set_dat(SCSI_STATUS_GOOD); @@ -649,19 +680,19 @@ void SCSI_DEV::start_command() break; case SCSI_CMD_WRITE6: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 6-Byte\n"), scsi_id); - #endif // start position position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; + out_debug_log(_T("Command: Write 6-byte LBA=%d BLOCKS=%d\n"), position, command[4]); position *= physical_block_size(); // transfer length - remain = command[4] * logical_block_size(); + remain = (command[4] > 0 ? command[4] : 0x100) * logical_block_size(); // thanks Mr.Sato + // seek time + delay = get_seek_time(position, remain); if(remain != 0) { // clear data buffer buffer->clear(); // change to data in phase - set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time); + set_phase_delay(SCSI_PHASE_DATA_OUT, delay); } else { // transfer length is zero, change to status phase set_dat(SCSI_STATUS_GOOD); @@ -671,15 +702,15 @@ void SCSI_DEV::start_command() break; case SCSI_CMD_READ10: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 10-byte\n"), scsi_id); - #endif // start position position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5]; + out_debug_log(_T("Command: Read 10-byte LBA=%d BLOCKS=%d\n"), position, command[7] * 0x100 + command[8]); position *= physical_block_size(); // transfer length remain = command[7] * 0x100 + command[8]; remain *= logical_block_size(); + // seek time + delay = get_seek_time(position, remain); if(remain != 0) { // read data buffer buffer->clear(); @@ -692,7 +723,7 @@ void SCSI_DEV::start_command() } // change to data in phase set_dat(buffer->read()); - set_phase_delay(SCSI_PHASE_DATA_IN, seek_time); + set_phase_delay(SCSI_PHASE_DATA_IN, delay); } else { // transfer length is zero, change to status phase set_dat(SCSI_STATUS_GOOD); @@ -702,26 +733,23 @@ void SCSI_DEV::start_command() break; case SCSI_CMD_WRITE10: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 10-Byte\n"), scsi_id); - #endif goto WRITE10; case SCSI_CMD_WRT_VERIFY: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write and Verify\n"), scsi_id); - #endif WRITE10: // start position position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5]; + out_debug_log(_T("Command: %s LBA=%d BLOCKS=%d\n"), (command[0] == SCSI_CMD_WRT_VERIFY) ? _T("Write and Verify") : _T("Write 10-byte"), position, command[7] * 0x100 + command[8]); position *= physical_block_size(); // transfer length remain = command[7] * 0x100 + command[8]; remain *= logical_block_size(); + // seek time + delay = get_seek_time(position, remain); if(remain != 0) { // clear data buffer buffer->clear(); // change to data in phase - set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time); + set_phase_delay(SCSI_PHASE_DATA_OUT, delay); } else { // transfer length is zero, change to status phase set_dat(SCSI_STATUS_GOOD); @@ -731,19 +759,20 @@ void SCSI_DEV::start_command() break; case SCSI_CMD_READ12: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Read 12-byte\n"), scsi_id); - #endif // start position position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5]; - position *= physical_block_size(); // transfer length remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9]; + out_debug_log(_T("Command: Read 12-byte LBA=%d BLOCKS=%d PBS=%d LBS=%d\n"), position, remain, physical_block_size(), logical_block_size()); + position *= physical_block_size(); remain *= logical_block_size(); + // seek time + delay = get_seek_time(position, remain); if(remain != 0) { // read data buffer buffer->clear(); int length = remain > SCSI_BUFFER_SIZE ? SCSI_BUFFER_SIZE : (int)remain; + out_debug_log(_T("LOAD BUFFER to %d bytes"), length); if(!read_buffer(length)) { // change to status phase set_dat(SCSI_STATUS_CHKCOND); @@ -752,7 +781,7 @@ void SCSI_DEV::start_command() } // change to data in phase set_dat(buffer->read()); - set_phase_delay(SCSI_PHASE_DATA_IN, seek_time); + set_phase_delay(SCSI_PHASE_DATA_IN, delay); } else { // transfer length is zero, change to status phase set_dat(SCSI_STATUS_GOOD); @@ -762,20 +791,20 @@ void SCSI_DEV::start_command() break; case SCSI_CMD_WRITE12: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Write 12-Byte\n"), scsi_id); - #endif // start position position = command[2] * 0x1000000 + command[3] * 0x10000 + command[4] * 0x100 + command[5]; + out_debug_log(_T("Command: Write 12-byte LBA=%d BLOCKS=%d\n"), position, command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9]); position *= physical_block_size(); // transfer length remain = command[6] * 0x1000000 + command[7] * 0x10000 + command[8] * 0x100 + command[9]; remain *= logical_block_size(); + // seek time + delay = get_seek_time(position, remain); if(remain != 0) { // clear data buffer buffer->clear(); // change to data in phase - set_phase_delay(SCSI_PHASE_DATA_OUT, seek_time); + set_phase_delay(SCSI_PHASE_DATA_OUT, delay); } else { // transfer length is zero, change to status phase set_dat(SCSI_STATUS_GOOD); @@ -785,9 +814,7 @@ void SCSI_DEV::start_command() break; default: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_DEV:ID=%d] Command: Unknown %02X\n"), scsi_id, command[0]); - #endif + out_debug_log(_T("Command: Unknown %02X\n"), command[0]); set_dat(SCSI_STATUS_GOOD); set_phase_delay(SCSI_PHASE_STATUS, 10.0); } @@ -813,7 +840,7 @@ bool SCSI_DEV::write_buffer(int length) return true; } -#define STATE_VERSION 2 +#define STATE_VERSION 3 bool SCSI_DEV::process_state(FILEIO* state_fio, bool loading) { @@ -845,6 +872,7 @@ bool SCSI_DEV::process_state(FILEIO* state_fio, bool loading) } state_fio->StateValue(position); state_fio->StateValue(remain); + state_fio->StateValue(local_data_pos); state_fio->StateValue(sense_code); return true; } diff --git a/source/src/vm/scsi_dev.h b/source/src/vm/scsi_dev.h index d3fea68ac..936c40b0a 100644 --- a/source/src/vm/scsi_dev.h +++ b/source/src/vm/scsi_dev.h @@ -10,8 +10,8 @@ #ifndef _SCSI_DEV_H_ #define _SCSI_DEV_H_ -#include "vm.h" -#include "../emu.h" +//#include "vm.h" +//#include "../emu.h" #include "device.h" #define SCSI_BUFFER_SIZE 0x10000 @@ -95,6 +95,8 @@ static const _TCHAR* scsi_phase_name[9] = { #define SCSI_CMD_SUBCHANNEL 0x42 // Read Subchannel (O) #define SCSI_CMD_READ_TOC 0x43 // Read TOC (O) +#define SASI_CMD_SPECIFY 0xC2 // Winchester Drive Parameters + #define SCSI_STATUS_GOOD 0x00 // Status Good #define SCSI_STATUS_CHKCOND 0x02 // Check Condition #define SCSI_STATUS_CONDMET 0x04 // Condition Met @@ -134,15 +136,18 @@ static const _TCHAR* scsi_phase_name[9] = { class FIFO; -class SCSI_DEV : public DEVICE +class DLL_PREFIX SCSI_DEV : public DEVICE { -private: +protected: outputs_t outputs_dat; outputs_t outputs_bsy; outputs_t outputs_cd; outputs_t outputs_io; outputs_t outputs_msg; outputs_t outputs_req; + outputs_t outputs_clrq; // Request host to clear data queue. + outputs_t outputs_next_sector; // Signal for boundary of sector(s). + outputs_t outputs_completed; // Signal for transfer completed of CD-ROM. uint32_t data_bus; bool sel_status, atn_status, ack_status, rst_status; @@ -150,13 +155,19 @@ class SCSI_DEV : public DEVICE int phase, next_phase, next_req; int event_sel, event_phase, event_req; + int local_data_pos; + uint32_t first_req_clock; double next_req_usec; uint8_t sense_code; + bool _SCSI_HOST_WIDE; + bool _SCSI_DEV_IMMEDIATE_SELECT; + bool __SCSI_DEBUG_LOG; + bool _OUT_DEBUG_LOG; public: - SCSI_DEV(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SCSI_DEV(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_dat); initialize_output_signals(&outputs_bsy); @@ -164,6 +175,13 @@ class SCSI_DEV : public DEVICE initialize_output_signals(&outputs_io); initialize_output_signals(&outputs_msg); initialize_output_signals(&outputs_req); + initialize_output_signals(&outputs_clrq); + initialize_output_signals(&outputs_next_sector); + initialize_output_signals(&outputs_completed); + _SCSI_HOST_WIDE = false; + _SCSI_DEV_IMMEDIATE_SELECT = false; + __SCSI_DEBUG_LOG = false; + _OUT_DEBUG_LOG = false; set_device_name(_T("SCSI DEVICE")); } @@ -174,23 +192,35 @@ class SCSI_DEV : public DEVICE void release(); void reset(); virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); + virtual void out_debug_log(const char *fmt, ...); // unique functions void set_context_interface(DEVICE* device) { -#ifdef SCSI_HOST_WIDE - register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xffff); -#else + // Will update mask of SIG_SCSI_DAT at initialize(), when set SCSI_HOST_WIDE. +//#ifdef SCSI_HOST_WIDE +// register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xffff); +//#else register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 0xff); -#endif - register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 1 << scsi_id); +//#endif +// register_output_signal(&outputs_dat, device, SIG_SCSI_DAT, 1 << scsi_id); register_output_signal(&outputs_bsy, device, SIG_SCSI_BSY, 1 << scsi_id); register_output_signal(&outputs_cd, device, SIG_SCSI_CD, 1 << scsi_id); register_output_signal(&outputs_io, device, SIG_SCSI_IO, 1 << scsi_id); register_output_signal(&outputs_msg, device, SIG_SCSI_MSG, 1 << scsi_id); register_output_signal(&outputs_req, device, SIG_SCSI_REQ, 1 << scsi_id); + register_output_signal(&outputs_clrq, device, SIG_SCSI_CLEAR_QUEUE, 1 << scsi_id); + + } + void set_context_completed(DEVICE* device, int id, uint32_t mask) + { + register_output_signal(&outputs_completed, device, id, mask); + } + void set_context_next_sector(DEVICE* device, int id, uint32_t mask) + { + register_output_signal(&outputs_next_sector, device, id, mask); } uint8_t get_sense_code() { @@ -231,6 +261,10 @@ class SCSI_DEV : public DEVICE { return 0; } + virtual double get_seek_time(uint64_t new_position, uint64_t length) + { + return seek_time; + } virtual int get_command_length(int value); virtual void start_command(); virtual bool read_buffer(int length); @@ -257,6 +291,7 @@ class SCSI_DEV : public DEVICE bool is_hot_swappable; double seek_time; int bytes_per_sec; + double data_req_delay; int scsi_id; }; diff --git a/source/src/vm/scsi_hdd.cpp b/source/src/vm/scsi_hdd.cpp index faf03bd3d..0986cecf1 100644 --- a/source/src/vm/scsi_hdd.cpp +++ b/source/src/vm/scsi_hdd.cpp @@ -22,6 +22,124 @@ void SCSI_HDD::release() SCSI_DEV::release(); } +void SCSI_HDD::out_debug_log(const _TCHAR *format, ...) +{ + if(!(__SCSI_DEBUG_LOG) && !(_OUT_DEBUG_LOG)) return; + va_list args; + _TCHAR _tmps[4096] = {0}; + _TCHAR _domain[256] = {0}; + my_sprintf_s(_domain, sizeof(_domain) / sizeof(_TCHAR), _T("[SCSI_HDD:ID=%d]"), scsi_id); + va_start(args, format); + vsnprintf(_tmps, sizeof(_tmps) / sizeof(_TCHAR), format, args); + va_end(args); + DEVICE::out_debug_log(_T("%s %s"), _domain, _tmps); +} + +void SCSI_HDD::start_command() +{ + switch(command[0]) { +#if 0 + // ToDo: Implement dummy write + case SCSI_CMD_SEND_DIAG: + { + pair16_t len; + len.b.h = command[3]; + len.b.l = command[4]; + remain = len.w; +// remain *= logical_block_size(); + set_phase_delay(SCSI_PHASE_DATA_OUT, 10.0); + } + return; + break; +#endif + case SCSI_CMD_RCV_DIAG: + { + // ToDo: Implement dummy read + } + break; + case SCSI_CMD_START_STP: // Start/Stop + buffer->clear(); + out_debug_log(_T("START/STOP Unit \n")); + set_dat(SCSI_STATUS_GOOD); + set_sense_code(SCSI_SENSE_NOSENSE); + set_phase_delay(SCSI_PHASE_STATUS, 10.0); + return; + break; + case SCSI_CMD_REZERO: // Recaliblate + { + double usec = 10.0; + for(int drv = 0; drv < 8; drv++) { + long pos = 0; + if(disk[drv] != NULL) { + pos = disk[drv]->get_cur_position(); + long distance = pos / (disk[drv]->get_headers() * disk[drv]->get_sectors_per_cylinder()); + if(distance > 0) { + usec += ((double)seek_time * (double)distance); + } else { + usec += 10.0; + } + } + } + buffer->clear(); + if(usec < (double)seek_time) usec = (double)seek_time; + out_debug_log(_T("RECALIBRATE Total Seek time=%fus\n"), usec); + set_dat(SCSI_STATUS_GOOD); + set_sense_code(SCSI_SENSE_NOSENSE); + set_phase_delay(SCSI_PHASE_STATUS, usec); + } + return; + break; +#if 0 + case SCSI_CMD_REQ_SENSE: + // From t10spc.cpp , mame 0.216. + out_debug_log(_T("Command: Request Sense\n")); + // start position +// position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; +// position *= physical_block_size(); + // transfer length + remain = command[4]; + if(remain == 0) { + remain = 4; + // create sense data table + buffer->clear(); + buffer->write(get_sense_code() & 0x7f); + buffer->write(((max_logical_block_addr() >> 16) & 0x1f) | (get_logical_unit_number() << 5)); + buffer->write(((max_logical_block_addr() >> 8) & 0xff)); + buffer->write(((max_logical_block_addr() >> 0) & 0xff)); + } else { + remain = 18; // From MAME 0.216 + buffer->clear(); + buffer->write(0x70); // SCSI_SERROR_CURRENT? + buffer->write(0x00); + buffer->write(is_device_ready() ? SCSI_KEY_NOSENSE : SCSI_KEY_UNITATT); // OK? ToDo: Will implement code. + buffer->write(((max_logical_block_addr() >> 24) & 0xff)); + buffer->write(((max_logical_block_addr() >> 16) & 0xff)); + buffer->write(((max_logical_block_addr() >> 8) & 0xff)); + buffer->write(((max_logical_block_addr() >> 0) & 0xff)); + buffer->write(0x0a); + + buffer->write(0x00); + buffer->write(0x00); + buffer->write(0x00); + buffer->write(0x00); + buffer->write(get_sense_code() & 0x7f); + buffer->write(get_sense_code() & 0x0f); + + buffer->write(0x00); + buffer->write(0x00); + buffer->write(0x00); + buffer->write(0x00); + } + // change to data in phase +// set_sense_code(SCSI_SENSE_NOSENSE); + set_phase_delay(SCSI_PHASE_DATA_IN, 10.0); + return; + break; +#endif + } + SCSI_DEV::start_command(); +} + void SCSI_HDD::reset() { if(!is_hot_swappable) { @@ -29,6 +147,7 @@ void SCSI_HDD::reset() if(disk[drv] != NULL) { if(image_path[drv][0] != _T('\0') && FILEIO::IsFileExisting(image_path[drv])) { disk[drv]->open(image_path[drv], sector_size[drv]); + cur_position[drv] = 0; } else { disk[drv]->close(); } @@ -46,6 +165,7 @@ void SCSI_HDD::open(int drv, const _TCHAR* file_path, int default_sector_size) sector_size[drv] = default_sector_size; } else { disk[drv]->open(file_path, default_sector_size); + cur_position[drv] = 0; } } } @@ -131,7 +251,8 @@ bool SCSI_HDD::read_buffer(int length) set_sense_code(SCSI_SENSE_NOSENSE); return true; } - HARDDISK *unit = disk[get_logical_unit_number()]; + uint8_t drv = get_logical_unit_number(); + HARDDISK *unit = disk[drv]; if(!(unit != NULL && unit->mounted())) { set_sense_code(SCSI_SENSE_NOTREADY); @@ -150,6 +271,7 @@ bool SCSI_HDD::read_buffer(int length) } length -= tmp_length; position += tmp_length; + cur_position[drv] = position - 1; } set_sense_code(SCSI_SENSE_NOSENSE); return true; @@ -165,7 +287,8 @@ bool SCSI_HDD::write_buffer(int length) set_sense_code(SCSI_SENSE_NOSENSE); return true; } - HARDDISK *unit = disk[get_logical_unit_number()]; + uint8_t drv = get_logical_unit_number(); + HARDDISK *unit = disk[drv]; if(!(unit != NULL && unit->mounted())) { set_sense_code(SCSI_SENSE_NOTREADY); @@ -184,12 +307,32 @@ bool SCSI_HDD::write_buffer(int length) } length -= tmp_length; position += tmp_length; + cur_position[drv] = position - 1; } set_sense_code(SCSI_SENSE_NOSENSE); return true; } -#define STATE_VERSION 3 +double SCSI_HDD::get_seek_time(uint64_t new_position, uint64_t length) +{ + uint8_t drv = get_logical_unit_number(); + HARDDISK *unit = disk[drv]; + + if(unit != NULL && unit->mounted()) { + // thanks Mr.Sato + int bytes_per_cylinder = unit->sector_size * unit->sectors * unit->surfaces; + int cur_cylinder = (int)(cur_position[drv] / bytes_per_cylinder); + int start_cylinder = (int)(new_position / bytes_per_cylinder); + int end_cylinder = (int)((new_position + length - 1) / bytes_per_cylinder); + int cylinders = abs(start_cylinder - cur_cylinder) + (end_cylinder - start_cylinder); + double rot_per_sec = bytes_per_sec / unit->sector_size / unit->sectors; + + return step_period * cylinders + 1000000.0 / rot_per_sec / 2; + } + return seek_time; +} + +#define STATE_VERSION 4 bool SCSI_HDD::process_state(FILEIO* state_fio, bool loading) { @@ -210,18 +353,29 @@ bool SCSI_HDD::process_state(FILEIO* state_fio, bool loading) */ state_fio->StateArray(&image_path[0][0], sizeof(image_path), 1); state_fio->StateArray(sector_size, sizeof(sector_size), 1); + state_fio->StateArray(cur_position, sizeof(cur_position), 1); return SCSI_DEV::process_state(state_fio, loading); } // SASI hard disk drive +void SASI_HDD::out_debug_log(const _TCHAR *format, ...) +{ + if(!(__SCSI_DEBUG_LOG) && !(_OUT_DEBUG_LOG)) return; + va_list args; + _TCHAR _tmps[4096] = {0}; + _TCHAR _domain[256] = {0}; + my_sprintf_s(_domain, sizeof(_domain) / sizeof(_TCHAR), _T("[SASI_HDD:ID=%d]"), scsi_id); + va_start(args, format); + vsnprintf(_tmps, sizeof(_tmps) / sizeof(_TCHAR), format, args); + va_end(args); + DEVICE::out_debug_log(_T("%s %s"), _domain, _tmps); +} void SASI_HDD::start_command() { switch(command[0]) { case SCSI_CMD_REQ_SENSE: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SASI_HDD:ID=%d] Command: Request Sense\n"), scsi_id); - #endif + out_debug_log(_T("Command: Request Sense\n")); // start position position = (command[1] & 0x1f) * 0x10000 + command[2] * 0x100 + command[3]; position *= physical_block_size(); @@ -239,12 +393,10 @@ void SASI_HDD::start_command() set_sense_code(SCSI_SENSE_NOSENSE); return; - case 0xc2: - #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SASI_HDD:ID=%d] Command: SASI Command 0xC2\n"), scsi_id); - #endif + case SASI_CMD_SPECIFY: + this->out_debug_log(_T("[SASI_HDD:ID=%d] Command: Winchester Drive Parameters\n"), scsi_id); // transfer length - remain = 10; // DTCn (gWX^ZpSPECIAL No.27, P.88) + remain = 10; // DTC-510B (トランジスタ技術SPECIAL No.27, P.88) // clear data buffer buffer->clear(); // change to data in phase @@ -254,3 +406,26 @@ void SASI_HDD::start_command() // start standard command SCSI_HDD::start_command(); } + +bool SASI_HDD::write_buffer(int length) +{ + if(command[0] == SASI_CMD_SPECIFY) { + // DTC-510B + int params[10]; + for(int i = 0; i < 10; i++) { + params[i] = buffer->read(); + position++; + } + if(params[2] == 0) { + // MZ-2500 specifies 1, but 50ms is too short + if(params[1] >= 20) { + step_period = params[1] * 50; + } + } else { +// step_period = 13; + } + set_sense_code(SCSI_SENSE_NOSENSE); + return true; + } + return SCSI_HDD::write_buffer(length); +} diff --git a/source/src/vm/scsi_hdd.h b/source/src/vm/scsi_hdd.h index 9280e1004..3c8744927 100644 --- a/source/src/vm/scsi_hdd.h +++ b/source/src/vm/scsi_hdd.h @@ -14,7 +14,7 @@ class HARDDISK; -class SCSI_HDD : public SCSI_DEV +class DLL_PREFIX SCSI_HDD : public SCSI_DEV { private: HARDDISK* disk[8]; @@ -24,8 +24,9 @@ class SCSI_HDD : public SCSI_DEV _TCHAR image_path[8][_MAX_PATH]; int sector_size[8]; + uint64_t cur_position[8]; public: - SCSI_HDD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : SCSI_DEV(parent_vm, parent_emu) + SCSI_HDD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : SCSI_DEV(parent_vm, parent_emu) { for(int i = 0; i < 8; i++) { disk[i] = NULL; @@ -34,10 +35,13 @@ class SCSI_HDD : public SCSI_DEV my_sprintf_s(vendor_id, 9, "NECITSU"); my_sprintf_s(product_id, 17, "SCSI-HDD"); device_type = 0x00; - is_removable = is_hot_swappable = false; + is_removable = false; + is_hot_swappable = true; //false; seek_time = 10000; // 10msec bytes_per_sec = 0x500000; // 5MB/sec + data_req_delay = 0.1; + step_period = 3000; // 3ms // default_drive_size = 0x2800000; // 40MB set_device_name(_T("SCSI HDD")); @@ -56,6 +60,7 @@ class SCSI_HDD : public SCSI_DEV uint32_t max_logical_block_addr(); bool read_buffer(int length); bool write_buffer(int length); + double get_seek_time(uint64_t new_position, uint64_t length); // unique functions void set_disk_handler(int drv, HARDDISK* device) @@ -75,19 +80,27 @@ class SCSI_HDD : public SCSI_DEV void close(int drv); bool mounted(int drv); bool accessed(int drv); + + int step_period; + + // virtual scsi functions + virtual void out_debug_log(const _TCHAR *format, ...); + virtual void start_command(); }; -class SASI_HDD : public SCSI_HDD +class DLL_PREFIX SASI_HDD : public SCSI_HDD { public: - SASI_HDD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : SCSI_HDD(parent_vm, parent_emu) + SASI_HDD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : SCSI_HDD(parent_vm, parent_emu) { set_device_name(_T("SASI Hard Disk Drive")); } ~SASI_HDD() {} // virtual scsi functions + virtual void out_debug_log(const _TCHAR *format, ...); void start_command(); + bool write_buffer(int length); }; #endif diff --git a/source/src/vm/scsi_host.cpp b/source/src/vm/scsi_host.cpp index 7a512212b..aefef9cb1 100644 --- a/source/src/vm/scsi_host.cpp +++ b/source/src/vm/scsi_host.cpp @@ -8,7 +8,25 @@ */ #include "scsi_host.h" +#include "../fifo.h" +#define EVENT_DELAY_READ_ACK 1 +#define EVENT_DELAY_WRITE_ACK 2 + +void SCSI_HOST::initialize() +{ + data_queue = new FIFO(2048); + is_16bit = false; +} + +void SCSI_HOST::release() +{ + if(data_queue != NULL) { + data_queue->release(); + delete data_queue; + data_queue = NULL; + } +} void SCSI_HOST::reset() { data_reg = 0; @@ -17,8 +35,10 @@ void SCSI_HOST::reset() set_irq(false); set_drq(false); + if(data_queue != NULL) data_queue->clear(); + is_dma = false; } - +/* #ifdef SCSI_HOST_WIDE void SCSI_HOST::write_dma_io16(uint32_t addr, uint32_t data) #else @@ -26,7 +46,7 @@ void SCSI_HOST::write_dma_io8(uint32_t addr, uint32_t data) #endif { #ifdef _SCSI_DEBUG_LOG - this->force_out_debug_log(_T("[SCSI_HOST] Write %02X\n"), data); +// this->force_out_debug_log(_T("[SCSI_HOST] Write %02X\n"), data); #endif write_signals(&outputs_dat, data); @@ -38,6 +58,7 @@ void SCSI_HOST::write_dma_io8(uint32_t addr, uint32_t data) #endif } + #ifdef SCSI_HOST_WIDE uint32_t SCSI_HOST::read_dma_io16(uint32_t addr) #else @@ -46,7 +67,7 @@ uint32_t SCSI_HOST::read_dma_io8(uint32_t addr) { uint32_t value = data_reg; #ifdef _SCSI_DEBUG_LOG - this->force_out_debug_log(_T("[SCSI_HOST] Read %02X\n"), value); +// this->force_out_debug_log(_T("[SCSI_HOST] Read %02X\n"), value); #endif #ifdef SCSI_HOST_AUTO_ACK // set ack to clear req signal immediately @@ -56,6 +77,120 @@ uint32_t SCSI_HOST::read_dma_io8(uint32_t addr) #endif return value; } +*/ +void SCSI_HOST::write_dma_io8(uint32_t addr, uint32_t data) +{ +#if defined(USE_QUEUED_SCSI_TRANSFER) + if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) { + // Data IN/OUT + data_queue->write(data & 0xff); + return; + } +#endif + write_signals(&outputs_dat, data); + #ifdef SCSI_HOST_AUTO_ACK + // set ack to clear req signal immediately + if((bsy_status) && !(io_status)) { + this->write_signal(SIG_SCSI_ACK, 1, 1); + } + #endif +} +void SCSI_HOST::write_dma_io16(uint32_t addr, uint32_t data) +{ + if(!(is_16bit)) { + write_dma_io8(addr, data); + return; + } +#if defined(USE_QUEUED_SCSI_TRANSFER) + if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) { + // Data IN/OUT +#if !defined(SCSI_HOST_WIDE) + data_queue->write(data & 0xff); + data_queue->write((data >> 8) & 0xff); +#else + data_queue->write(data & 0xffff); +#endif + return; + } +#endif + write_signals(&outputs_dat, data); + #ifdef SCSI_HOST_AUTO_ACK + // set ack to clear req signal immediately + if((bsy_status) && !(io_status)) { + this->write_signal(SIG_SCSI_ACK, 1, 1); + } + #endif +} +uint32_t SCSI_HOST::read_dma_io16(uint32_t addr) +{ + if(!(is_16bit)) { + return read_dma_io8(addr); + } + uint32_t val; +#if defined(USE_QUEUED_SCSI_TRANSFER) + if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) { + // Data IN/OUT +#if !defined(SCSI_HOST_WIDE) + val = data_queue->read() & 0xff; + val = val << 8; + val = val | (data_queue->read() & 0xff); +#else + val = data_queue->read() & 0xffff; +#endif + return val; + } +#endif + val = data_reg; + #ifdef SCSI_HOST_AUTO_ACK + // set ack to clear req signal immediately + if((bsy_status) && (io_status)) { + this->write_signal(SIG_SCSI_ACK, 1, 1); + } + #endif + return val; +} + +uint32_t SCSI_HOST::read_dma_io8(uint32_t addr) +{ + uint32_t val; +#if defined(USE_QUEUED_SCSI_TRANSFER) + if(!(cd_status) && !(msg_status) && (is_dma) && (req_status)) { +// if(!(data_queue->empty())) { + // Data IN/OUT + val = data_queue->read() & 0xff; + return val; + } +#endif + val = data_reg; + #ifdef SCSI_HOST_AUTO_ACK + // set ack to clear req signal immediately + if((bsy_status) && (io_status)) { + this->write_signal(SIG_SCSI_ACK, 1, 1); + } + #endif + return val; +} + + +void SCSI_HOST::event_callback(int id, int err) +{ +#ifdef SCSI_HOST_AUTO_ACK + switch(id) { + case EVENT_DELAY_READ_ACK: + // set ack to clear req signal immediately + if(bsy_status && io_status) { + this->write_signal(SIG_SCSI_ACK, 1, 1); + } + break; + case EVENT_DELAY_WRITE_ACK: + // set ack to clear req signal immediately + if(bsy_status && !io_status) { + this->write_signal(SIG_SCSI_ACK, 1, 1); + } + break; + } +#endif +} void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask) { @@ -63,7 +198,7 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask) // from initiator case SIG_SCSI_SEL: #ifdef _SCSI_DEBUG_LOG - this->out_debug_log(_T("[SCSI_HOST] SEL = %d\n"), (data & mask) ? 1 : 0); +// this->out_debug_log(_T("[SCSI_HOST] SEL = %d\n"), (data & mask) ? 1 : 0); #endif write_signals(&outputs_sel, (data & mask) ? 0xffffffff : 0); break; @@ -88,6 +223,9 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask) this->out_debug_log(_T("[SCSI_HOST] RST = %d\n"), (data & mask) ? 1 : 0); #endif write_signals(&outputs_rst, (data & mask) ? 0xffffffff : 0); + if((data_queue != NULL) && ((data & mask) != 0)) { + data_queue->clear(); + } break; // from target @@ -129,14 +267,52 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask) if(!prev_status && req_status) { // L -> H // if(bsy_status) { - if(!cd_status && !msg_status) { - // data phase - set_drq(true); - access = true; - } else if(cd_status) { - // command/status/message phase - set_irq(true); + if(!cd_status && !msg_status) { + // data phase + +#if defined(USE_QUEUED_SCSI_TRANSFER) + if((bsy_status) && (io_status) && (is_dma)) { + data_queue->write(data_reg); +// out_debug_log(_T("READ DATA=%02X"), data_reg, data_queue->count()); + #ifdef SCSI_HOST_AUTO_ACK + this->write_signal(SIG_SCSI_ACK, 1, 1); + #endif + } +#endif + + #if !defined(SCSI_HOST_WIDE) && defined(USE_QUEUED_SCSI_TRANSFER) + bool do_drq = false; + if((io_status)) { + // READ FROM TARGET + if(!(data_queue->empty())) { + do_drq = true; + } + } else { + // WRITE TO TARGET + if((data_queue->empty())) { + do_drq = true; + } } + if(do_drq) set_drq(true); + #else + set_drq(true); + #endif + access = true; +#if defined(USE_QUEUED_SCSI_TRANSFER) + if((bsy_status) && !(io_status) && (is_dma)) { + if(!(data_queue->empty())) { + write_signals(&outputs_dat, data_queue->read()); + #ifdef SCSI_HOST_AUTO_ACK + this->write_signal(SIG_SCSI_ACK, 1, 1); + #endif + } + } +#endif + } else if(cd_status) { + // command/status/message phase + if(!(data_queue->empty())) data_queue->clear(); + set_irq(true); + } // } } else if(prev_status && !req_status) { // H -> L @@ -145,10 +321,27 @@ void SCSI_HOST::write_signal(int id, uint32_t data, uint32_t mask) #ifdef SCSI_HOST_AUTO_ACK this->write_signal(SIG_SCSI_ACK, 0, 0); #endif + //if(delay_ack) { + //delay_ack = false; + // register_event(this, EVENT_DELAY_READ_ACK, 0.5, false, NULL); + //} } write_signals(&outputs_req, req_status ? 0xffffffff : 0); } break; + case SIG_SCSI_HOST_DMAE: + is_dma = ((data & mask) != 0) ? true : false; + break; + case SIG_SCSI_16BIT_BUS: + is_16bit = ((data & mask) != 0) ? true : false; + break; + case SIG_SCSI_CLEAR_QUEUE: + if(data_queue != NULL) { + if((data & mask) != 0) { + data_queue->clear(); + } + } + break; } } @@ -191,7 +384,7 @@ void SCSI_HOST::set_drq(bool value) write_signals(&outputs_drq, value ? 0xffffffff : 0); } -#define STATE_VERSION 2 +#define STATE_VERSION 3 bool SCSI_HOST::process_state(FILEIO* state_fio, bool loading) { @@ -208,6 +401,12 @@ bool SCSI_HOST::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(msg_status); state_fio->StateValue(req_status); state_fio->StateValue(ack_status); + + state_fio->StateValue(is_16bit); + if(!data_queue->process_state((void *)state_fio, loading)) { + return false; + } + state_fio->StateValue(is_dma); return true; } diff --git a/source/src/vm/scsi_host.h b/source/src/vm/scsi_host.h index fa58dd9b9..e326dd04c 100644 --- a/source/src/vm/scsi_host.h +++ b/source/src/vm/scsi_host.h @@ -10,14 +10,17 @@ #ifndef _SCSI_HOST_H_ #define _SCSI_HOST_H_ +// Wip host wide or narron. #include "vm.h" -#include "../emu.h" +#include "../emu_template.h" #include "device.h" -//class EMU; -//class VM; + +#define SIG_SCSI_HOST_DMAE 1 + +class FIFO; class SCSI_HOST : public DEVICE { -private: +protected: // Make pcotected because TOWNS's DMAC may transfer 16bit around SCSI. outputs_t outputs_irq; // to adaptor outputs_t outputs_drq; @@ -32,16 +35,19 @@ class SCSI_HOST : public DEVICE outputs_t outputs_atn; outputs_t outputs_ack; outputs_t outputs_rst; + FIFO* data_queue; uint32_t data_reg; uint32_t bsy_status, cd_status, io_status, msg_status, req_status, ack_status; bool access; + bool is_16bit; + bool is_dma; - void __FASTCALL set_irq(bool value); - void __FASTCALL set_drq(bool value); + virtual void __FASTCALL set_irq(bool value); + virtual void __FASTCALL set_drq(bool value); public: - SCSI_HOST(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SCSI_HOST(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_irq); initialize_output_signals(&outputs_drq); @@ -57,22 +63,34 @@ class SCSI_HOST : public DEVICE initialize_output_signals(&outputs_atn); initialize_output_signals(&outputs_ack); initialize_output_signals(&outputs_rst); + + data_queue = NULL; set_device_name(_T("SCSI HOST")); } ~SCSI_HOST() {} // common functions - void reset(); + virtual void reset(); + virtual void initialize(); + virtual void release(); + virtual void __FASTCALL event_callback(int id, int err); +/* #ifdef SCSI_HOST_WIDE - void __FASTCALL write_dma_io16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_dma_io16(uint32_t addr); + virtual void __FASTCALL write_dma_io16(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_io16(uint32_t addr); #else - void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_dma_io8(uint32_t addr); + virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr); #endif - void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - uint32_t __FASTCALL read_signal(int id); - bool process_state(FILEIO* state_fio, bool loading); +*/ + virtual void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data); + virtual void __FASTCALL write_dma_io16(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_dma_io8(uint32_t addr); + virtual uint32_t __FASTCALL read_dma_io16(uint32_t addr); + + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + virtual uint32_t __FASTCALL read_signal(int id); + virtual bool process_state(FILEIO* state_fio, bool loading); // unique functions void set_context_irq(DEVICE* device, int id, uint32_t mask) diff --git a/source/src/vm/scv/CMakeLists.txt b/source/src/vm/scv/CMakeLists.txt index cd6bea029..cc66bf095 100644 --- a/source/src/vm/scv/CMakeLists.txt +++ b/source/src/vm/scv/CMakeLists.txt @@ -1,12 +1,14 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/scv") +message("* vm/emuscv") -add_library(vm_scv - scv.cpp +add_library(vm_emuscv + ../upd7801.cpp io.cpp memory.cpp sound.cpp vdp.cpp + + scv.cpp ) diff --git a/source/src/vm/scv/io.h b/source/src/vm/scv/io.h index e69571b32..5b7032d72 100644 --- a/source/src/vm/scv/io.h +++ b/source/src/vm/scv/io.h @@ -10,8 +10,8 @@ #ifndef _IO_H_ #define _IO_H_ -#include "../vm.h" -#include "../../emu.h" +#include "../vm_template.h" +#include "../../emu_template.h" #include "../device.h" namespace SCV { @@ -27,7 +27,7 @@ class IO : public DEVICE uint8_t pa, pb, pc; public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } diff --git a/source/src/vm/scv/memory.h b/source/src/vm/scv/memory.h index f77ff19aa..a3501c53d 100644 --- a/source/src/vm/scv/memory.h +++ b/source/src/vm/scv/memory.h @@ -51,7 +51,7 @@ class MEMORY : public DEVICE void __FASTCALL set_bank(uint8_t bank); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/scv/scv.cpp b/source/src/vm/scv/scv.cpp index e57792711..cec9065e2 100644 --- a/source/src/vm/scv/scv.cpp +++ b/source/src/vm/scv/scv.cpp @@ -32,7 +32,7 @@ using SCV::VDP; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -206,6 +206,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -218,7 +230,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/scv/scv.h b/source/src/vm/scv/scv.h index cf3f64fcf..22d9f6c06 100644 --- a/source/src/vm/scv/scv.h +++ b/source/src/vm/scv/scv.h @@ -77,7 +77,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -110,6 +110,9 @@ class VM : public VM_TEMPLATE bool is_cart_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/scv/sound.h b/source/src/vm/scv/sound.h index e08b369c3..f9f2cd52d 100644 --- a/source/src/vm/scv/sound.h +++ b/source/src/vm/scv/sound.h @@ -71,7 +71,7 @@ class SOUND : public DEVICE void process_cmd(); public: - SOUND(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SOUND(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Sound")); } @@ -81,8 +81,8 @@ class SOUND : public DEVICE void reset(); void __FASTCALL write_data8(uint32_t addr, uint32_t data); void __FASTCALL write_io8(uint32_t addr, uint32_t data); - void event_callback(int event_id, int err); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int event_id, int err); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/scv/vdp.h b/source/src/vm/scv/vdp.h index 7ad508ebd..dc751c597 100644 --- a/source/src/vm/scv/vdp.h +++ b/source/src/vm/scv/vdp.h @@ -38,7 +38,7 @@ class VDP : public DEVICE void draw_sprite(int dx, int dy, int sx, int ex, int sy, int ey, int no, uint8_t col); public: - VDP(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + VDP(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("VDP")); } diff --git a/source/src/vm/sio_redirector.h b/source/src/vm/sio_redirector.h index d46b01812..3bbca2890 100644 --- a/source/src/vm/sio_redirector.h +++ b/source/src/vm/sio_redirector.h @@ -21,9 +21,9 @@ #define SIG_SIO_REMAIN_SEND 5 #define SIG_SIO_REMAIN_RECEIVE 6 -class SIO_REDIRECTOR : public MIDI_REDIRECTOR { +class DLL_PREFIX SIO_REDIRECTOR : public MIDI_REDIRECTOR { public: - SIO_REDIRECTOR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MIDI_REDIRECTOR(parent_vm, parent_emu) + SIO_REDIRECTOR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MIDI_REDIRECTOR(parent_vm, parent_emu) { set_device_name(_T("SERIAL I/O REDIRECTOR")); } diff --git a/source/src/vm/smb80te/CMakeLists.txt b/source/src/vm/smb80te/CMakeLists.txt index 6b3f68207..10a6fd58c 100644 --- a/source/src/vm/smb80te/CMakeLists.txt +++ b/source/src/vm/smb80te/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 2.6) message("* vm/smb80te") -add_library(vm_smb80te +add_library(vm_emusmb80te smb80te.cpp memory.cpp ) diff --git a/source/src/vm/smb80te/memory.h b/source/src/vm/smb80te/memory.h index b99779e32..1286c2711 100644 --- a/source/src/vm/smb80te/memory.h +++ b/source/src/vm/smb80te/memory.h @@ -44,7 +44,7 @@ class MEMORY : public DEVICE void update_kb(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/smb80te/smb80te.cpp b/source/src/vm/smb80te/smb80te.cpp index 01b6f6a11..8d30dbe02 100644 --- a/source/src/vm/smb80te/smb80te.cpp +++ b/source/src/vm/smb80te/smb80te.cpp @@ -31,7 +31,7 @@ using SMB80TE::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -324,6 +324,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 3 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -336,7 +348,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/smb80te/smb80te.h b/source/src/vm/smb80te/smb80te.h index 08779196b..40826634b 100644 --- a/source/src/vm/smb80te/smb80te.h +++ b/source/src/vm/smb80te/smb80te.h @@ -128,7 +128,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -179,6 +179,9 @@ class VM : public VM_TEMPLATE void save_binary(int drv, const _TCHAR* file_path); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/smc777/CMakeLists.txt b/source/src/vm/smc777/CMakeLists.txt index 82d87224c..ee50b2283 100644 --- a/source/src/vm/smc777/CMakeLists.txt +++ b/source/src/vm/smc777/CMakeLists.txt @@ -1,8 +1,19 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/smc777") +message("* vm/${EXE_NAME}") -add_library(vm_smc777 +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +if("${U_EXE_NAME}" STREQUAL "EMUSMC70") +add_library(vm_${EXE_NAME} + ../msm58321.cpp + + ./memory.cpp + smc777.cpp + ) +elseif("${U_EXE_NAME}" STREQUAL "EMUSMC777") +add_library(vm_${EXE_NAME} + ./memory.cpp smc777.cpp - memory.cpp ) +endif() diff --git a/source/src/vm/smc777/memory.h b/source/src/vm/smc777/memory.h index 8d3fe5cfb..2aa93305d 100644 --- a/source/src/vm/smc777/memory.h +++ b/source/src/vm/smc777/memory.h @@ -102,12 +102,12 @@ class MEMORY : public DEVICE scrntype_t palette_line_graph_pc[200][16]; #endif - void draw_text_80x25(int v); - void draw_text_40x25(int v); - void draw_graph_640x400(int v); - void draw_graph_640x200(int v); - void draw_graph_320x200(int v); - void draw_graph_160x100(int v); + void __FASTCALL draw_text_80x25(int v); + void __FASTCALL draw_text_40x25(int v); + void __FASTCALL draw_graph_640x400(int v); + void __FASTCALL draw_graph_640x200(int v); + void __FASTCALL draw_graph_320x200(int v); + void __FASTCALL draw_graph_160x100(int v); // kanji rom uint8_t kanji[0x23400]; @@ -127,7 +127,7 @@ class MEMORY : public DEVICE #endif public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } @@ -145,7 +145,7 @@ class MEMORY : public DEVICE uint32_t __FASTCALL read_io8_debug(uint32_t addr); #endif void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_frame(); void event_vline(int v, int clock); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/smc777/smc777.cpp b/source/src/vm/smc777/smc777.cpp index f0e5ec6a5..09944645c 100644 --- a/source/src/vm/smc777/smc777.cpp +++ b/source/src/vm/smc777/smc777.cpp @@ -39,7 +39,7 @@ using SMC777::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -170,7 +170,7 @@ void VM::reset() memory->warm_start = false; } -void VM::special_reset() +void VM::special_reset(int num) { // reset all devices for(DEVICE* device = first_device; device; device = device->next_device) { @@ -413,6 +413,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -425,7 +437,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/smc777/smc777.h b/source/src/vm/smc777/smc777.h index 222be4fe0..3dfb37a45 100644 --- a/source/src/vm/smc777/smc777.h +++ b/source/src/vm/smc777/smc777.h @@ -38,7 +38,7 @@ #define USE_BOOT_MODE 3 #define BOOT_MODE_DEFAULT 1 #endif -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_FLOPPY_DISK 2 #define USE_TAPE 1 #define USE_KEY_LOCKED @@ -187,7 +187,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -196,7 +196,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -245,6 +245,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/sn76489an.h b/source/src/vm/sn76489an.h index e2b1ac1e2..8c0ada921 100644 --- a/source/src/vm/sn76489an.h +++ b/source/src/vm/sn76489an.h @@ -19,7 +19,7 @@ #define SIG_SN76489AN_CS 2 #define SIG_SN76489AN_WE 3 -class SN76489AN : public DEVICE +class DLL_PREFIX SN76489AN : public DEVICE { private: // register @@ -44,7 +44,7 @@ class SN76489AN : public DEVICE uint32_t _NOISE_DST_TAP; uint32_t _NOISE_SRC_TAP; public: - SN76489AN(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SN76489AN(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; //#ifdef HAS_SN76489 @@ -60,7 +60,7 @@ class SN76489AN : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/svi3x8/CMakeLists.txt b/source/src/vm/svi3x8/CMakeLists.txt new file mode 100644 index 000000000..c81d48347 --- /dev/null +++ b/source/src/vm/svi3x8/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required (VERSION 2.6) + +message("* vm/${EXE_NAME}") + +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +set(SVI3X8_BASE_SRCS + ./joystick.cpp + ./keyboard.cpp + ./memory_ex.cpp + +# ../msx/printer.cpp +# ../msx/slot_cart.cpp +# ../msx/slot_mainrom.cpp + + ./msx_ex.cpp +) + +if("${U_EXE_NAME}" STREQUAL "EMUSVI3X8") + add_library(vm_${EXE_NAME} + ${SVI3X8_BASE_SRCS} + ) + target_compile_definitions(vm_${EXE_NAME} PRIVATE -D_MSX_VDP_MESS) +endif() diff --git a/source/src/vm/svi3x8/joystick.cpp b/source/src/vm/svi3x8/joystick.cpp new file mode 100644 index 000000000..1fc475fec --- /dev/null +++ b/source/src/vm/svi3x8/joystick.cpp @@ -0,0 +1,53 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/joystick.cpp + + modified by tanam + Date : 2018.12.09- + + [ joystick ] +*/ + +#include "joystick.h" +#include "memory_ex.h" +#include "../ay_3_891x.h" + +namespace SVI_3X8 { +#if defined(MSX_KEYBOARD_50ON) +#define PSG14_MASK 0x3f +#else +#define PSG14_MASK 0x7f +#endif + +void JOYSTICK::initialize() +{ + joy_stat = emu->get_joy_buffer(); + select = 0; + + // register event to update the key status + register_frame_event(this); +} + +void JOYSTICK::event_frame() +{ +/// d_psg->write_signal(SIG_AY_3_891X_PORT_A, PSG14_MASK & ~(joy_stat[select] & 0x3f), 0x7f); + d_psg->write_signal(SIG_AY_3_891X_PORT_A, ~((joy_stat[0] & 0x0f)|(joy_stat[1] & 0x0f)<<4), 0xff); + d_memory->write_io8(select, ~((joy_stat[0] & 0x10)|(joy_stat[1] & 0x10)<<1)); +} + +#define STATE_VERSION 1 + +bool JOYSTICK::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(select); + return true; +} +} diff --git a/source/src/vm/svi3x8/joystick.h b/source/src/vm/svi3x8/joystick.h new file mode 100644 index 000000000..801853461 --- /dev/null +++ b/source/src/vm/svi3x8/joystick.h @@ -0,0 +1,55 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/joystick.h + + modified by tanam + Date : 2018.12.09- + + [ joystick ] +*/ + +#ifndef _JOYSTICK_H_ +#define _JOYSTICK_H_ + +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" + +#define SIG_JOYSTICK_SEL 0 + +namespace SVI_3X8 { +class JOYSTICK : public DEVICE +{ +private: + DEVICE *d_psg; + DEVICE *d_memory; + const uint32_t *joy_stat; + int select; + +public: + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + set_device_name(_T("Joystick I/F")); + } + ~JOYSTICK() {} + + // common functions + void initialize(); + void event_frame(); +// void write_signal(int id, uint32_t data, uint32_t mask); + bool process_state(FILEIO* state_fio, bool loading); + + // unique function + void set_context_psg(DEVICE* device) + { + d_psg = device; + } + void set_context_memory(DEVICE* device) + { + d_memory = device; + } +}; +} +#endif diff --git a/source/src/vm/svi3x8/keyboard.cpp b/source/src/vm/svi3x8/keyboard.cpp new file mode 100644 index 000000000..bd63b1388 --- /dev/null +++ b/source/src/vm/svi3x8/keyboard.cpp @@ -0,0 +1,88 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/keyboard.cpp + + modified by tanam + Date : 2018.12.09- + + [ keyboard ] +*/ + +#include "keyboard.h" +#include "../i8255.h" + +namespace SVI_3X8 { +static const uint8_t key_map[11][8] = { + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0xbb, 0xba, 0xbc, 0xde, 0xbe, 0xbf, + 0xbd, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0xdb, 0xdc, 0xdd, 0x08, 0x26, + 0x10, 0x11, 0xa4, 0xa5, 0x1b, 0x75, 0x0d, 0x25, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x24, 0x2d, 0x28, + 0x20, 0x09, 0x2e, 0x14, 0x76, 0x77, 0x00, 0x27, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6b, 0x6d, 0x6a, 0x6f, 0x6e, 0x6c +}; + +void KEYBOARD::initialize() +{ + key_stat = emu->get_key_buffer(); + column = 0; +// break_pressed = false; + + // register event to update the key status + register_frame_event(this); +} + +void KEYBOARD::event_frame() +{ +// bool new_pressed = (key_stat[0x13] != 0); +// if(new_pressed && !break_pressed) { +// d_cpu->write_signal(SIG_CPU_NMI, 1, 1); +// } +// break_pressed = new_pressed; + + update_keyboard(); +} + +void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask) +{ + if(column != (data & mask)) { + column = data & mask; + update_keyboard(); + } +} + +void KEYBOARD::update_keyboard() +{ + uint8_t val = 0; + + if(column < 11) { + for(int i = 0; i < 8; i++) { + if(key_stat[key_map[column][i]] != 0) { + val |= 1 << i; + } + } + } + d_pio->write_signal(SIG_I8255_PORT_B, ~val, 0xff); +} + +#define STATE_VERSION 2 + +bool KEYBOARD::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(column); +// state_fio->StateValue(break_pressed); + return true; +} +} diff --git a/source/src/vm/svi3x8/keyboard.h b/source/src/vm/svi3x8/keyboard.h new file mode 100644 index 000000000..486c6d054 --- /dev/null +++ b/source/src/vm/svi3x8/keyboard.h @@ -0,0 +1,59 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/keyboard.h + + modified by tanam + Date : 2018.12.09- + + [ keyboard ] +*/ + +#ifndef _KEYBOARD_H_ +#define _KEYBOARD_H_ + +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" + +#define SIG_KEYBOARD_COLUMN 0 + +namespace SVI_3X8 { +class KEYBOARD : public DEVICE +{ +private: +// DEVICE *d_cpu, *d_pio; + DEVICE *d_pio; + + const uint8_t* key_stat; + uint8_t column; +// bool break_pressed; + + void update_keyboard(); + +public: + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + set_device_name(_T("Keyboard")); + } + ~KEYBOARD() {} + + // common functions + void initialize(); + void event_frame(); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + bool process_state(FILEIO* state_fio, bool loading); + + // unique functions +// void set_context_cpu(DEVICE* device) +// { +// d_cpu = device; +// } + void set_context_pio(DEVICE* device) + { + d_pio = device; + } +}; +} +#endif diff --git a/source/src/vm/svi3x8/memory_ex.cpp b/source/src/vm/svi3x8/memory_ex.cpp new file mode 100644 index 000000000..e383d68ea --- /dev/null +++ b/source/src/vm/svi3x8/memory_ex.cpp @@ -0,0 +1,1588 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/memory_ex.cpp + + modified by tanam + Date : 2018.12.09- + + [ memory ] +*/ + +#include "./memory_ex.h" +#if defined(FDD_PATCH_SLOT) +#include "../disk.h" +#define MSX_SECTOR_SIZE 512 +namespace SVI_3X8 { +char dskPath[64]=""; /* Disk image path */ +/** Floppy drive *********/ +unsigned char fdc_drive = 0; +unsigned char fdc_head = 0; +unsigned char fdc_density = 0; +unsigned char fdc_status = 0; +unsigned char svi_disk_heads[2]; +unsigned char svi_disk_tracks=40; +unsigned char svi_UseDisk = 0; +} +#ifndef UINT16 +#define UINT16 unsigned short int +#endif + +#ifndef UINT8 +#define UINT8 unsigned char +#endif + +#define MAX_DRIVES 2 /* we support 'only' four drives in MESS */ + +#define WD179X_IRQ_CLR 0 +#define WD179X_IRQ_SET 1 +#define WD179X_DRQ_CLR 2 +#define WD179X_DRQ_SET 3 + +#define DEN_FM_LO 0 /* this is used by TRS-80 (but not working) */ +#define DEN_FM_HI 1 +#define DEN_MFM_LO 2 /* and this one is the one that works */ +#define DEN_MFM_HI 3 /* There were no HD disks back then ;) */ + +#define REAL_FDD ((void*)-1) + +#define FDC_STEP_RATE 0x03 /* Type I additional flags */ +#define FDC_STEP_VERIFY 0x04 /* verify track number */ +#define FDC_STEP_HDLOAD 0x08 /* load head */ +#define FDC_STEP_UPDATE 0x10 /* update track register */ + +#define FDC_RESTORE 0x00 /* Type I commands */ +#define FDC_SEEK 0x10 +#define FDC_STEP 0x20 +#define FDC_STEP_IN 0x40 +#define FDC_STEP_OUT 0x60 + +#define FDC_MASK_TYPE_I (FDC_STEP_HDLOAD|FDC_STEP_VERIFY|FDC_STEP_RATE) + +/* Type I commands status */ +#define STA_1_BUSY 0x01 /* controller is busy */ +#define STA_1_IPL 0x02 /* index pulse */ +#define STA_1_TRACK0 0x04 /* track 0 detected */ +#define STA_1_CRC_ERR 0x08 /* CRC error */ +#define STA_1_SEEK_ERR 0x10 /* seek error */ +#define STA_1_HD_LOADED 0x20 /* head loaded */ +#define STA_1_WRITE_PRO 0x40 /* floppy is write protected */ +#define STA_1_NOT_READY 0x80 /* controller not ready */ + +/* Type II and III additional flags */ +#define FDC_DELETED_AM 0x01 /* read/write deleted address mark */ +#define FDC_SIDE_CMP_T 0x02 /* side compare track data */ +#define FDC_15MS_DELAY 0x04 /* delay 15ms before command */ +#define FDC_SIDE_CMP_S 0x08 /* side compare sector data */ +#define FDC_MULTI_REC 0x10 /* only for type II commands */ + +/* Type II commands */ +#define FDC_READ_SEC 0x80 /* read sector */ +#define FDC_WRITE_SEC 0xA0 /* write sector */ + +#define FDC_MASK_TYPE_II (FDC_MULTI_REC|FDC_SIDE_CMP_S|FDC_15MS_DELAY|FDC_SIDE_CMP_T|FDC_DELETED_AM) + +/* Type II commands status */ +#define STA_2_BUSY 0x01 +#define STA_2_DRQ 0x02 +#define STA_2_LOST_DAT 0x04 +#define STA_2_CRC_ERR 0x08 +#define STA_2_REC_N_FND 0x10 +#define STA_2_REC_TYPE 0x20 +#define STA_2_WRITE_PRO 0x40 +#define STA_2_NOT_READY 0x80 + +#define FDC_MASK_TYPE_III (FDC_SIDE_CMP_S|FDC_15MS_DELAY|FDC_SIDE_CMP_T|FDC_DELETED_AM) + +/* Type III commands */ +#define FDC_READ_DAM 0xc0 /* read data address mark */ +#define FDC_READ_TRK 0xe0 /* read track */ +#define FDC_WRITE_TRK 0xf0 /* write track (format) */ + +/* Type IV additional flags */ +#define FDC_IM0 0x01 /* interrupt mode 0 */ +#define FDC_IM1 0x02 /* interrupt mode 1 */ +#define FDC_IM2 0x04 /* interrupt mode 2 */ +#define FDC_IM3 0x08 /* interrupt mode 3 */ + +#define FDC_MASK_TYPE_IV (FDC_IM3|FDC_IM2|FDC_IM1|FDC_IM0) + +/* Type IV commands */ +#define FDC_FORCE_INT 0xd0 /* force interrupt */ + +namespace SVI_3X8 { +typedef struct { + UINT8 track; + UINT8 sector; + UINT8 status; +} SECMAP; + +typedef struct { + void (* callback)(int event); /* callback for IRQ status */ + UINT8 unit; /* unit number if image_file == REAL_FDD */ + UINT8 tracks; /* maximum # of tracks */ + UINT8 heads; /* maximum # of heads */ + UINT8 density; /* FM/MFM, single / double density */ + UINT16 offset; /* track 0 offset */ + UINT8 first_sector_id; /* id of first sector */ + UINT8 sec_per_track; /* sectors per track */ + UINT16 sector_length; /* sector length (byte) */ + + UINT8 head; /* current head # */ + UINT8 track; /* current track # */ + UINT8 track_reg; /* value of track register */ + UINT8 direction; /* last step direction */ + UINT8 sector; /* current sector # */ + UINT8 sector_dam; /* current sector # to fake read DAM command */ + UINT8 data; /* value of data register */ + UINT8 command; /* last command written */ + + UINT8 read_cmd; /* last read command issued */ + UINT8 write_cmd; /* last write command issued */ + + UINT8 status; /* status register */ + UINT8 status_drq; /* status register data request bit */ + UINT8 status_ipl; /* status register toggle index pulse bit */ + UINT8 busy_count; /* how long to keep busy bit set */ + + UINT8 buffer[6144]; /* I/O buffer (holds up to a whole track) */ + UINT8 dam_list[256][4]; /* list of data address marks while formatting */ + int dam_data[256]; /* offset to data inside buffer while formatting */ + int dam_cnt; /* valid number of entries in the dam_list */ + UINT8 *fmt_sector_data[256]; /* pointer to data after formatting a track */ + int data_offset; /* offset into I/O buffer */ + int data_count; /* transfer count from/into I/O buffer */ + + const char *image_name; /* file name for disc image */ + void *image_file; /* file handle for disc image */ + int mode; /* open mode == 0 read only, != 0 read/write */ + unsigned long image_size; /* size of image file */ + + UINT16 dir_sector; /* directory track for deleted DAM */ + UINT16 dir_length; /* directory length for deleted DAM */ + + SECMAP *secmap; + +} WD179X; + +/* structure describing a double density track */ +#define TRKSIZE_DD 6144 +static UINT8 track_DD[][2] = { + {16, 0x4e}, /* 16 * 4E (track lead in) */ + { 8, 0x00}, /* 8 * 00 (pre DAM) */ + { 3, 0xf5}, /* 3 * F5 (clear CRC) */ + + { 1, 0xfe}, /* *** sector *** FE (DAM) */ + { 1, 0x80}, /* 4 bytes track,head,sector,seclen */ + { 1, 0xf7}, /* 1 * F7 (CRC) */ + {22, 0x4e}, /* 22 * 4E (sector lead in) */ + {12, 0x00}, /* 12 * 00 (pre AM) */ + { 3, 0xf5}, /* 3 * F5 (clear CRC) */ + { 1, 0xfb}, /* 1 * FB (AM) */ + { 1, 0x81}, /* x bytes sector data */ + { 1, 0xf7}, /* 1 * F7 (CRC) */ + {16, 0x4e}, /* 16 * 4E (sector lead out) */ + { 8, 0x00}, /* 8 * 00 (post sector) */ + { 0, 0x00}, /* end of data */ +}; + +/* structure describing a single density track */ +#define TRKSIZE_SD 3172 +static UINT8 track_SD[][2] = { + {16, 0xff}, /* 16 * FF (track lead in) */ + { 8, 0x00}, /* 8 * 00 (pre DAM) */ + { 1, 0xfc}, /* 1 * FC (clear CRC) */ + + {11, 0xff}, /* *** sector *** 11 * FF */ + { 6, 0x00}, /* 6 * 00 (pre DAM) */ + { 1, 0xfe}, /* 1 * FE (DAM) */ + { 1, 0x80}, /* 4 bytes track,head,sector,seclen */ + { 1, 0xf7}, /* 1 * F7 (CRC) */ + {10, 0xff}, /* 10 * FF (sector lead in) */ + { 4, 0x00}, /* 4 * 00 (pre AM) */ + { 1, 0xfb}, /* 1 * FB (AM) */ + { 1, 0x81}, /* x bytes sector data */ + { 1, 0xf7}, /* 1 * F7 (CRC) */ + { 0, 0x00}, /* end of data */ +}; + +WD179X *wd[MAX_DRIVES]; +static UINT8 drv = 0; + +void wd179x_CloseDiskImage(unsigned char DriveNumber) +{ + WD179X *w = wd[DriveNumber]; + + fclose((FILE *)w->image_file); + w->image_file = NULL; + w->image_name = NULL; +} +void wd179x_InitDiskImage(unsigned char DriveNumber, const char *DriveImageFileName) +{ + + WD179X *w = wd[DriveNumber]; + + w->image_name = DriveImageFileName; + + // Open file images + w->mode = 1; + + // Open Read/Write + w->image_file = fopen(w->image_name, "r+b"); + if( !w->image_file ) + { + w->mode = 0; + // Open Read Only + w->image_file = fopen(w->image_name,"rb"); + } + + w->track = 0; + w->head = 0; + w->sector = 0; +} + +void wd179x_init(int active) +{ + int i; + + for (i = 0; i < MAX_DRIVES; i++) + { + wd[i] = (WD179X *)malloc(sizeof(WD179X)); + if (!wd[i]) + { + while (--i >= 0) + { + free(wd[i]); + wd[i] = 0; + } + return; + } + memset(wd[i], 0, sizeof(WD179X)); + wd[i]->unit = 0; + wd[i]->tracks = 40; + wd[i]->heads = 1; + wd[i]->density = DEN_MFM_LO; + wd[i]->offset = 0; + wd[i]->first_sector_id = 0; + wd[i]->sec_per_track = 17; + wd[i]->sector_length = 256; + wd[i]->head = 0; + wd[i]->track = 0; + wd[i]->track_reg = 0; + wd[i]->direction = 1; + wd[i]->sector = 0; + wd[i]->data = 0; + wd[i]->status = (active) ? STA_1_TRACK0 : 0; + wd[i]->status_drq = 0; + wd[i]->status_ipl = 0; + wd[i]->busy_count = 0; + wd[i]->data_offset = 0; + wd[i]->data_count = 0; + wd[i]->image_name = 0; + wd[i]->image_size = 0; + wd[i]->dir_sector = 0; + wd[i]->dir_length = 0; + wd[i]->secmap = 0; + } +} + +void wd179x_select_drive(UINT8 drive, UINT8 head, void (*callback) (int)) +{ +WD179X *w = wd[drive]; + + if (drive < MAX_DRIVES) + { + drv = drive; + w->head = head; + w->status_ipl = STA_1_IPL; + w->callback = callback; + + if (w->image_file) + { + return; + } + } + w->status = STA_1_NOT_READY; +} + +void wd179x_stop_drive(void) +{ + int i; + + for (i = 0; i < MAX_DRIVES; i++) + { + WD179X *w = wd[i]; + w->busy_count = 0; + w->status = 0; + w->status_drq = 0; + if (w->callback) + (*w->callback) (WD179X_DRQ_CLR); + w->status_ipl = 0; + } +} + +void wd179x_read_sectormap(UINT8 drive, UINT8 * tracks, UINT8 * heads, UINT8 * sec_per_track) +{ +WD179X *w = wd[drive]; +SECMAP *p; +UINT8 head; + + if (!w->secmap) + w->secmap = (SECMAP *)malloc(0x2200); + if (!w->secmap) return; + fseek((FILE *)w->image_file, 0, SEEK_SET); + fread(w->secmap, 1, 0x2200, (FILE *)w->image_file); + w->offset = 0x2200; + w->tracks = 0; + w->heads = 0; + w->sec_per_track = 0; + w->first_sector_id = 0x0ff; + for (p = w->secmap; p->track != 0xff; p++) + { + if (p->track > w->tracks) + w->tracks = p->track; + + if (p->sector < w->first_sector_id) + w->first_sector_id = p->sector; + + if (p->sector > w->sec_per_track) + w->sec_per_track = p->sector; + head = (p->status >> 4) & 1; + if (head > w->heads) + w->heads = head; + } + *tracks = w->tracks++; + *heads = w->heads++; + *sec_per_track = w->sec_per_track++; +} + +void wd179x_set_geometry(UINT8 density, UINT8 drive, UINT8 tracks, UINT8 heads, UINT8 sec_per_track, UINT16 sector_length, UINT16 dir_sector, UINT16 dir_length, UINT8 first_sector_id) +{ +WD179X *w = wd[drive]; + + if (drive >= MAX_DRIVES) + { + return; + } + + w->density = density; + w->tracks = tracks; + w->heads = heads; + w->first_sector_id = first_sector_id; + w->sec_per_track = sec_per_track; + w->sector_length = sector_length; + w->dir_sector = dir_sector; + w->dir_length = dir_length; + + w->image_size = w->tracks * w->heads * w->sec_per_track * w->sector_length; + + /* calculate greatest power of 2 */ + if (w->image_file == REAL_FDD) + { + unsigned long N = 0; + unsigned long ShiftCount = 0; + + if (N==0) + { + N = (w->sector_length); + + while ((N & 0x080000000)==0) + { + N = N<<1; + ShiftCount++; + } + + /* get left-shift required to shift 1 to this + power of 2 */ + + /* N = 0 for 128, N = 1 for 256, N = 2 for 512 ... */ + N = (31 - ShiftCount)-7; + } + else + { + N = 1; + } + } +} + +/* seek to track/head/sector relative position in image file */ +static int seek(WD179X * w, UINT8 t, UINT8 h, UINT8 s) +{ +unsigned long offset; +SECMAP *p; +UINT8 head; + + if (w->secmap) + { + offset = 0x2200; + for (p = w->secmap; p->track != 0xff; p++) + { + if (p->track == t && p->sector == s) + { + head = (p->status & 0x10) >> 4; + if (head == h) + { + if (fseek((FILE *)w->image_file, offset, SEEK_SET) < 0) + { + return STA_1_SEEK_ERR; + } + return 0; + } + } + //offset += 0x100; + if (p->track==0 && head==0) + offset += 0x80; + else + offset += 0x100; + } + return STA_1_SEEK_ERR; + } + + /* allow two additional tracks */ + if (t >= w->tracks + 2) + { + return STA_1_SEEK_ERR; + } + + if (h >= w->heads) + { + return STA_1_SEEK_ERR; + } + + if (s >= (w->first_sector_id + w->sec_per_track)) + { + return STA_2_REC_N_FND; + } + + if ((t==0) && (h==0)) + offset = (s-w->first_sector_id)*128; + else + offset = ((t*w->heads+h)*17+s-w->first_sector_id)*256-2048; // (17*256)-(18*128)=2048 + + if (offset > w->image_size) + { + return STA_1_SEEK_ERR; + } + + if (fseek((FILE *)w->image_file, offset, SEEK_SET) < 0) + { + return STA_1_SEEK_ERR; + } + + return 0; +} + +/* return STA_2_REC_TYPE depending on relative sector */ +static int deleted_dam(WD179X * w) +{ +unsigned rel_sector = (w->track * w->heads + w->head) * w->sec_per_track + (w->sector-w->first_sector_id); +SECMAP *p; +UINT8 head; + + if (w->secmap) + { + for (p = w->secmap; p->track != 0xff; p++) + { + if (p->track == w->track && p->sector == w->sector) + { + head = (p->status >> 4) & 1; + if (w->head == head) + return p->status & STA_2_REC_TYPE; + } + } + return STA_2_REC_N_FND; + } + if (rel_sector >= w->dir_sector && rel_sector < w->dir_sector + w->dir_length) + { + return STA_2_REC_TYPE; + } + return 0; +} + +/* calculate CRC for data address marks or sector data */ +static void calc_crc(UINT16 * crc, UINT8 value) +{ +UINT8 l, h; + + l = value ^ (*crc >> 8); + *crc = (*crc & 0xff) | (l << 8); + l >>= 4; + l ^= (*crc >> 8); + *crc <<= 8; + *crc = (*crc & 0xff00) | l; + l = (l << 4) | (l >> 4); + h = l; + l = (l << 2) | (l >> 6); + l &= 0x1f; + *crc = *crc ^ (l << 8); + l = h & 0xf0; + *crc = *crc ^ (l << 8); + l = (h << 1) | (h >> 7); + l &= 0xe0; + *crc = *crc ^ l; +} + +/* read the next data address mark */ +static void read_dam(WD179X * w) +{ +UINT16 crc = 0xffff; + + w->data_offset = 0; + w->data_count = 6; + w->buffer[0] = w->track; + w->buffer[1] = w->head; + w->buffer[2] = w->sector_dam; + w->buffer[3] = w->sector_length >> 8; + calc_crc(&crc, w->buffer[0]); + calc_crc(&crc, w->buffer[1]); + calc_crc(&crc, w->buffer[2]); + calc_crc(&crc, w->buffer[3]); + w->buffer[4] = crc & 255; + w->buffer[5] = crc / 256; + if (++w->sector_dam == w->sec_per_track) + w->sector_dam = w->first_sector_id; + w->status_drq = STA_2_DRQ; + if (w->callback) + (*w->callback) (WD179X_DRQ_SET); + w->status = STA_2_DRQ | STA_2_BUSY; + w->busy_count = 50; +} + +/* read a sector */ +static void read_sector(WD179X * w) +{ + w->data_offset = 0; + w->data_count = w->sector_length; + + /* if a track was just formatted */ + if (w->dam_cnt) + { + int i; + for (i = 0; i < w->dam_cnt; i++) + { + if (w->track == w->dam_list[i][0] && + w->head == w->dam_list[i][1] && + w->sector == w->dam_list[i][2]) + { + w->data_offset = w->dam_data[i]; + return; + } + } + /* sector not found, now the track buffer is invalid */ + w->dam_cnt = 0; + } + + /* if this is the real thing */ + if (w->image_file == REAL_FDD) + { + int tries = 3; + do { + //w->status = osd_fdc_get_sector(w->track, w->head, w->head, w->sector, w->buffer); + tries--; + } while (tries && (w->status & (STA_2_REC_N_FND | STA_2_CRC_ERR | STA_2_LOST_DAT))); + /* no error bits set ? */ + if ((w->status & (STA_2_REC_N_FND | STA_2_CRC_ERR | STA_2_LOST_DAT)) == 0) + { + /* start transferring data to the emulation now */ + w->status_drq = STA_2_DRQ; + if (w->callback) + (*w->callback) (WD179X_DRQ_SET); + w->status |= STA_2_DRQ | STA_2_BUSY; + } + return; + } + else + if (fread(w->buffer, 1, w->sector_length, (FILE *)w->image_file) != w->sector_length) + { + w->status = STA_2_LOST_DAT; + return; + } + + w->status_drq = STA_2_DRQ; + if (w->callback) + (*w->callback) (WD179X_DRQ_SET); + w->status = STA_2_DRQ | STA_2_BUSY; + w->busy_count = 0; +} + +/* read an entire track */ +static void read_track(WD179X * w) +{ +UINT8 *psrc; /* pointer to track format structure */ +UINT8 *pdst; /* pointer to track buffer */ +int cnt; /* number of bytes to fill in */ +UINT16 crc; /* id or data CRC */ +UINT8 d; /* data */ +UINT8 t = w->track; /* track of DAM */ +UINT8 h = w->head; /* head of DAM */ +UINT8 s = w->sector_dam; /* sector of DAM */ +UINT16 l = w->sector_length; /* sector length of DAM */ +int i; + + for (i = 0; i < w->sec_per_track; i++) + { + w->dam_list[i][0] = t; + w->dam_list[i][1] = h; + w->dam_list[i][2] = i; + w->dam_list[i][3] = l >> 8; + } + + pdst = w->buffer; + + if (w->density) + { + psrc = track_DD[0]; /* double density track format */ + cnt = TRKSIZE_DD; + } + else + { + psrc = track_SD[0]; /* single density track format */ + cnt = TRKSIZE_SD; + } + + while (cnt > 0) + { + if (psrc[0] == 0) /* no more track format info ? */ + { + if (w->dam_cnt < w->sec_per_track) /* but more DAM info ? */ + { + if (w->density)/* DD track ? */ + psrc = track_DD[3]; + else + psrc = track_SD[3]; + } + } + + if (psrc[0] != 0) /* more track format info ? */ + { + cnt -= psrc[0]; /* subtract size */ + d = psrc[1]; + + if (d == 0xf5) /* clear CRC ? */ + { + crc = 0xffff; + d = 0xa1; /* store A1 */ + } + + for (i = 0; i < *psrc; i++) + *pdst++ = d; /* fill data */ + + if (d == 0xf7) /* store CRC ? */ + { + pdst--; /* go back one byte */ + *pdst++ = crc & 255; /* put CRC low */ + *pdst++ = crc / 256; /* put CRC high */ + cnt -= 1; /* count one more byte */ + } + else if (d == 0xfe)/* address mark ? */ + { + crc = 0xffff; /* reset CRC */ + } + else if (d == 0x80)/* sector ID ? */ + { + pdst--; /* go back one byte */ + t = *pdst++ = w->dam_list[w->dam_cnt][0]; /* track number */ + h = *pdst++ = w->dam_list[w->dam_cnt][1]; /* head number */ + s = *pdst++ = w->dam_list[w->dam_cnt][2]; /* sector number */ + l = *pdst++ = w->dam_list[w->dam_cnt][3]; /* sector length code */ + w->dam_cnt++; + calc_crc(&crc, t); /* build CRC */ + calc_crc(&crc, h); /* build CRC */ + calc_crc(&crc, s); /* build CRC */ + calc_crc(&crc, l); /* build CRC */ + l = (l == 0) ? 128 : l << 8; + } + else if (d == 0xfb)// data address mark ? + { + crc = 0xffff; // reset CRC + } + else if (d == 0x81)// sector DATA ? + { + pdst--; /* go back one byte */ + if (seek(w, t, h, s) == 0) + { + if (fread(pdst, 1, l, (FILE *)w->image_file) != l) + { + w->status = STA_2_CRC_ERR; + return; + } + } + else + { + w->status = STA_2_REC_N_FND; + return; + } + for (i = 0; i < l; i++) // build CRC of all data + calc_crc(&crc, *pdst++); + cnt -= l; + } + psrc += 2; + } + else + { + *pdst++ = 0xff; /* fill track */ + cnt--; /* until end */ + } + } + + w->data_offset = 0; + w->data_count = (w->density) ? TRKSIZE_DD : TRKSIZE_SD; + + w->status_drq = STA_2_DRQ; + if (w->callback) + (*w->callback) (WD179X_DRQ_SET); + w->status |= STA_2_DRQ | STA_2_BUSY; + w->busy_count = 0; +} + +/* write a sector */ +static void write_sector(WD179X * w) +{ + if (w->image_file == REAL_FDD) + { + return; + } + if (w->mode == 0) + { + w->status = STA_2_WRITE_PRO; + } + else + { + w->status = seek(w, w->track, w->head, w->sector); + if (w->status == 0) + { + if (fwrite(w->buffer, 1, w->data_offset, (FILE *)w->image_file) != w->data_offset) + w->status = STA_2_LOST_DAT; + } + } +} + +/* write an entire track by extracting the sectors */ +static void write_track(WD179X * w) +{ +UINT8 *f; +int cnt; + + w->dam_cnt = 0; + if (w->image_file != REAL_FDD && w->mode == 0) + { + w->status = STA_2_WRITE_PRO; + return; + } + + memset(w->dam_list, 0xff, sizeof(w->dam_list)); + memset(w->dam_data, 0x00, sizeof(w->dam_data)); + + f = w->buffer; + cnt = (w->density) ? TRKSIZE_DD : TRKSIZE_SD; + + do + { + while ((--cnt > 0) && (*f != 0xfe)) /* start of DAM ?? */ + f++; + + if (cnt > 4) + { + int seclen; + cnt -= 5; + f++; /* skip FE */ + w->dam_list[w->dam_cnt][0] = *f++; /* copy track number */ + w->dam_list[w->dam_cnt][1] = *f++; /* copy head number */ + w->dam_list[w->dam_cnt][2] = *f++; /* copy sector number */ + w->dam_list[w->dam_cnt][3] = *f++; /* copy sector length */ + /* sector length in bytes */ + seclen = 128 << w->dam_list[w->dam_cnt][3]; + /* search start of DATA */ + while ((--cnt > 0) && (*f != 0xf9) && (*f != 0xfa) && (*f != 0xfb)) + f++; + if (cnt > seclen) + { + cnt--; + /* skip data address mark */ + f++; + /* set pointer to DATA to later write the sectors contents */ + w->dam_data[w->dam_cnt] = (int)(f - w->buffer); + w->dam_cnt++; + f += seclen; + cnt -= seclen; + } + } + } while (cnt > 0); + + if (w->image_file == REAL_FDD) + { + w->status = 0; + } + else + { + /* now put all sectors contained in the format buffer */ + for (cnt = 0; cnt < w->dam_cnt; cnt++) + { + w->status = seek(w, w->track, w->head, w->dam_list[cnt][2]); + if (w->status == 0) + { + if (fwrite(&w->buffer[w->dam_data[cnt]],1, w->sector_length, (FILE *)w->image_file) != w->sector_length) + { + w->status = STA_2_LOST_DAT; + return; + } + } + } + } +} + + +/* read the FDC status register. This clears IRQ line too */ +UINT8 wd179x_status_r(void) +{ +WD179X *w = wd[drv]; +int result = w->status; + + if (w->callback) + (*w->callback) (WD179X_IRQ_CLR); + if (w->busy_count) + { + if (!--w->busy_count) + w->status &= ~STA_1_BUSY; + } +/* eventually toggle index pulse bit */ + w->status ^= w->status_ipl; +/* eventually set data request bit */ + w->status |= w->status_drq; + + return result; +} + +/* read the FDC track register */ +UINT8 wd179x_track_r(void) +{ +WD179X *w = wd[drv]; + + return w->track_reg; +} + +/* read the FDC sector register */ +UINT8 wd179x_sector_r(void) +{ +WD179X *w = wd[drv]; + + return w->sector; +} + +/* read the FDC data register */ +UINT8 wd179x_data_r(void) +{ +WD179X *w = wd[drv]; + + if (w->data_count > 0) + { + w->status &= ~STA_2_DRQ; + if (--w->data_count <= 0) + { + /* clear busy bit */ + w->status &= ~STA_2_BUSY; + /* no more setting of data request bit */ + w->status_drq = 0; + if (w->callback) + (*w->callback) (WD179X_DRQ_CLR); + if (w->image_file != REAL_FDD) + { + /* read normal or deleted data address mark ? */ + w->status |= deleted_dam(w); + } + /* generate an IRQ */ + if (w->callback) + (*w->callback) (WD179X_IRQ_SET); + } + w->data = w->buffer[w->data_offset++]; + } + return w->data; +} + +/* write the FDC command register */ +void wd179x_command_w(UINT8 data) +{ +WD179X *w = wd[drv]; + + if ((data | 1) == 0xff) /* change single/double density ? */ + { + /* only supports FM/LO and MFM/LO */ + w->density = (data & 1) ? DEN_MFM_LO : DEN_FM_LO; + return; + } + + if ((data & ~FDC_MASK_TYPE_IV) == FDC_FORCE_INT) + { + w->data_count = 0; + w->data_offset = 0; + w->status &= ~(STA_2_DRQ | STA_2_BUSY); + w->status_drq = 0; + if (w->callback) + (*w->callback) (WD179X_DRQ_CLR); + w->status_ipl = 0; + if (w->callback) + (*w->callback) (WD179X_IRQ_CLR); + w->busy_count = 0; + return; + } + + if (data & 0x80) + { + w->status_ipl = 0; + + if ((data & ~FDC_MASK_TYPE_II) == FDC_READ_SEC) + { + w->read_cmd = data; + w->command = data & ~FDC_MASK_TYPE_II; + w->status = seek(w, w->track, w->head, w->sector); + if (w->status == 0) + read_sector(w); + return; + } + + if ((data & ~FDC_MASK_TYPE_II) == FDC_WRITE_SEC) + { + w->write_cmd = data; + w->command = data & ~FDC_MASK_TYPE_II; + w->data_offset = 0; + w->data_count = w->sector_length; + w->status_drq = STA_2_DRQ; + if (w->callback) + (*w->callback) (WD179X_DRQ_SET); + w->status = STA_2_DRQ | STA_2_BUSY; + w->busy_count = 0; + return; + } + + if ((data & ~FDC_MASK_TYPE_III) == FDC_READ_TRK) + { + w->command = data & ~FDC_MASK_TYPE_III; + w->status = seek(w, w->track, w->head, w->sector); + if (w->status == 0) + read_track(w); + return; + } + + if ((data & ~FDC_MASK_TYPE_III) == FDC_WRITE_TRK) + { + w->command = data & ~FDC_MASK_TYPE_III; + w->data_offset = 0; + w->data_count = (w->density) ? TRKSIZE_DD : TRKSIZE_SD; + w->status_drq = STA_2_DRQ; + if (w->callback) + (*w->callback) (WD179X_DRQ_SET); + w->status = STA_2_DRQ | STA_2_BUSY; + w->busy_count = 0; + return; + } + + if ((data & ~FDC_MASK_TYPE_III) == FDC_READ_DAM) + { + w->status = seek(w, w->track, w->head, w->sector); + if (w->status == 0) + read_dam(w); + return; + } + + return; + } + + + if ((data & ~FDC_MASK_TYPE_I) == FDC_RESTORE) + { + /* simulate seek time busy signal */ + w->busy_count = w->track * ((data & FDC_STEP_RATE) + 1); + /* if it is a real floppy, issue a recal command */ + if (w->image_file == REAL_FDD) + { + w->track = 0;//osd_fdc_recal(&w->track); + } + else + { + w->track = 0; /* set track number 0 */ + } + w->track_reg = w->track; + } + + if ((data & ~FDC_MASK_TYPE_I) == FDC_SEEK) + { + UINT8 newtrack = w->data; + /* if it is a real floppy, issue a seek command */ + /* simulate seek time busy signal */ + w->busy_count = abs(newtrack - w->track) * ((data & FDC_STEP_RATE) + 1); + if (w->image_file == REAL_FDD) + w->track = newtrack;//osd_fdc_seek(newtrack, &w->track); + else + w->track = newtrack; /* get track number from data register */ + w->track_reg = w->track; + } + + if ((data & ~(FDC_STEP_UPDATE | FDC_MASK_TYPE_I)) == FDC_STEP) + { + /* if it is a real floppy, issue a step command */ + /* simulate seek time busy signal */ + w->busy_count = ((data & FDC_STEP_RATE) + 1); + if (w->image_file == REAL_FDD) + w->track += w->direction;//osd_fdc_step(w->direction, &w->track); + else + w->track += w->direction; /* adjust track number */ + } + + if ((data & ~(FDC_STEP_UPDATE | FDC_MASK_TYPE_I)) == FDC_STEP_IN) + { + w->direction = +1; + /* simulate seek time busy signal */ + w->busy_count = ((data & FDC_STEP_RATE) + 1); + /* if it is a real floppy, issue a step command */ + if (w->image_file == REAL_FDD) + w->track += w->direction;//osd_fdc_step(w->direction, &w->track); + else + w->track += w->direction; /* adjust track number */ + } + + if ((data & ~(FDC_STEP_UPDATE | FDC_MASK_TYPE_I)) == FDC_STEP_OUT) + { + w->direction = -1; + /* simulate seek time busy signal */ + w->busy_count = ((data & FDC_STEP_RATE) + 1); + /* if it is a real floppy, issue a step command */ + if (w->image_file == REAL_FDD) + w->track += w->direction;//osd_fdc_step(w->direction, &w->track); + else + w->track += w->direction; /* adjust track number */ + } + + if (w->busy_count) + w->status = STA_1_BUSY; + +/* toggle index pulse at read */ + w->status_ipl = STA_1_IPL; + + if (w->track >= w->tracks) + w->status |= STA_1_SEEK_ERR; + + if (w->track == 0) + w->status |= STA_1_TRACK0; + + if (w->mode == 0) + w->status |= STA_1_WRITE_PRO; + + if (data & FDC_STEP_UPDATE) + w->track_reg = w->track; + + if (data & FDC_STEP_HDLOAD) + w->status |= STA_1_HD_LOADED; + + if (data & FDC_STEP_VERIFY) + if (w->track_reg != w->track) + w->status |= STA_1_SEEK_ERR; +} + +/* write the FDC track register */ +void wd179x_track_w(UINT8 data) +{ +WD179X *w = wd[drv]; + w->track = w->track_reg = data; +} + +/* write the FDC sector register */ +void wd179x_sector_w(UINT8 data) +{ +WD179X *w = wd[drv]; + + w->sector = data; +} + +/* write the FDC data register */ +void wd179x_data_w(UINT8 data) +{ +WD179X *w = wd[drv]; + + if (w->data_count > 0) + { + w->buffer[w->data_offset++] = data; + if (--w->data_count <= 0) + { + w->status_drq = 0; + if (w->callback) + (*w->callback) (WD179X_DRQ_CLR); + if (w->command == FDC_WRITE_TRK) + write_track(w); + else + write_sector(w); + w->data_offset = 0; + if (w->callback) + (*w->callback) (WD179X_IRQ_SET); + } + } + w->data = data; +} + +/*************************************************************/ +/* Function: svi_LoadDisk */ +/* Purpose: Try to load a disk image */ +/*************************************************************/ +unsigned char svi_LoadDisk(unsigned char disk, char *filename) +{ + unsigned char status = 0; + char s[256]; + FILE *f; + int fsize; + + if (strstr(filename,".\\")!=filename) + { + strcpy(s,dskPath); + strcat(s,filename); + if (f=fopen(s,"rb")) + { + strcpy(filename,s); + fclose(f); + } + } + if (!(f=fopen(filename,"rb"))) + return 0; + fseek(f,0,SEEK_END); + fsize=ftell(f); + switch (fsize) + { + case 346112 : svi_disk_heads[disk] = 2; + status=1; + break; + case 172032 : svi_disk_heads[disk] = 1; + status=1; + break; + } + fclose(f); + return status; +} + +/*************************************************************/ +/* Function: svi_fdc_callback */ +/* Purpose: Callback routine for the FDC. */ +/*************************************************************/ +void svi_fdc_callback(int param) +{ + switch( param ) + { + case WD179X_IRQ_CLR: + fdc_status &= ~0x80; + break; + case WD179X_IRQ_SET: + fdc_status |= 0x80; + break; + case WD179X_DRQ_CLR: + fdc_status &= ~0x40; + break; + case WD179X_DRQ_SET: + fdc_status |= 0x40; + break; + } +} + +/*************************************************************/ +/* Function: svi_fdc_disk_motor */ +/* Purpose: Floppy disk and motor select. */ +/*************************************************************/ +void svi_fdc_disk_motor(unsigned char data) +{ + unsigned char seldrive = 255; + + if (data == 0) + { + wd179x_stop_drive(); + return; + } + if (data & 2) + { + seldrive=1; + } + if (data & 1) + { + seldrive=0; + } + if (seldrive > 3) return; + fdc_drive = seldrive; + wd179x_select_drive(fdc_drive, fdc_head, svi_fdc_callback); +} + + +/*************************************************************/ +/* Function: svi_fdc_density_side */ +/* Purpose: Floppy density and head select. */ +/*************************************************************/ +void svi_fdc_density_side(unsigned char data) +{ + unsigned char sectors_track; + unsigned short int sector_size; + + if (data & 2) + fdc_head = 1; + else + fdc_head = 0; + + if (data & 1) + { + fdc_density = DEN_FM_LO; + sectors_track = 18; + sector_size = 128; + } + else + { + fdc_density = DEN_MFM_LO; + sectors_track = 17; + sector_size = 256; + } + wd179x_set_geometry(fdc_density, fdc_drive, svi_disk_tracks, svi_disk_heads[fdc_drive], sectors_track, sector_size, 0, 0, 1); +} + +#endif + +#define EVENT_CLOCK 0 + +#define SET_BANK(s, e, w, r) { \ + int sb = (s) >> 13, eb = (e) >> 13; \ + for(int i = sb; i <= eb; i++) { \ + if((w) == wdmy) { \ + wbank[i] = wdmy; \ + } else { \ + wbank[i] = (w) + 0x2000 * (i - sb); \ + } \ + if((r) == rdmy) { \ + rbank[i] = rdmy; \ + } else { \ + rbank[i] = (r) + 0x2000 * (i - sb); \ + } \ + } \ +} + +bool MEMORY_EX::load_cart(const _TCHAR *file_path) +{ + bool result = false; + FILEIO* fio = new FILEIO(); + if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { + memset(rom, 0xff, sizeof(rom)); + fio->Fread(rom, sizeof(rom), 1); + fio->Fread(r12, sizeof(r12), 1); + SET_BANK(0x0000, 0x7fff, wdmy, rom); + SET_BANK(0x8000, 0xffff, ram, ram); + fio->Fclose(); + result = true; + } + delete fio; + return result; +} + +void MEMORY_EX::open_cart(const _TCHAR *file_path) +{ + if(load_cart(file_path)) { + inserted = true; + } +} + +void MEMORY_EX::close_cart() +{ + SET_BANK(0x0000, 0x7fff, wdmy, bio); + SET_BANK(0x8000, 0xffff, ram, ram); + inserted = false; +} + +// memory bus +void MEMORY_EX::initialize() +{ + svi_UseDisk = 0; + memset(bio, 0xff, sizeof(bio)); + memset(rdmy, 0xff, sizeof(rdmy)); + memset(wdmy, 0xff, sizeof(wdmy)); + FILEIO* fio = new FILEIO(); + if((fio->Fopen(create_local_path(_T("SVI318.ROM")), FILEIO_READ_BINARY)) || + (fio->Fopen(create_local_path(_T("SVI328.ROM")), FILEIO_READ_BINARY)) || + (fio->Fopen(create_local_path(_T("SVI328a.ROM")), FILEIO_READ_BINARY))) { + fio->Fread(bio, sizeof(bio), 1); + fio->Fclose(); + } + delete fio; +#if defined(FDD_PATCH_SLOT) + wd179x_init(1); + for(int i = 0; i < MAX_DRIVE; i++) { + disk[i] = new DISK(emu); + disk[i]->set_device_name(_T("%s/Disk #%d"), this_device_name, i + 1); + disk[i]->drive_type = DRIVE_TYPE_2DD; + } +#endif + close_cart(); + close_tape(); +} + +#if defined(FDD_PATCH_SLOT) +void MEMORY_EX::release() +{ + for(int i = 0; i < MAX_DRIVE; i++) { + if(disk[i]) { + disk[i]->close(); + delete disk[i]; + } + } +} +#endif + +void MEMORY_EX::reset() +{ + if (!inserted) { + memset(rom, 0xff, sizeof(rom)); + memset(r12, 0xff, sizeof(r12)); + } + memset(ram, 0, sizeof(ram)); + memset(r21, 0, sizeof(r21)); + memset(r22, 0, sizeof(r22)); + memset(r31, 0, sizeof(r31)); + memset(r32, 0, sizeof(r32)); + memset(tapedata, 0, sizeof(tapedata)); +} + +void MEMORY_EX::write_data8(uint32_t addr, uint32_t data) +{ + wbank[addr >> 13][addr & 0x1fff] = data; +} + +uint32_t MEMORY_EX::read_io8(uint32_t addr) +{ + unsigned char port = addr; + uint32_t ret=0xff; + switch (port) + { + case 0x30 : if (svi_UseDisk == 1) + ret=wd179x_status_r(); + break; + + case 0x31 : if (svi_UseDisk == 1) + ret=wd179x_track_r(); + break; + + case 0x32 : if (svi_UseDisk == 1) + ret=wd179x_sector_r(); + break; + + case 0x33 : if (svi_UseDisk == 1) + ret=wd179x_data_r(); + break; + + case 0x34 : if (svi_UseDisk == 1) + ret=fdc_status; + break; + default: + ret=strig; + } + + return ret; +} + +void MEMORY_EX::write_io8(uint32_t addr, uint32_t data) +{ + // Write the value to the appropriate port + unsigned char port = addr; + unsigned char value = data; + switch (port) + { + case 0x30 : if (svi_UseDisk == 1) + { + wd179x_command_w(value); + if ((value & ~FDC_MASK_TYPE_I) == FDC_RESTORE) + fdc_status |= 0x80; + } + break; + + case 0x31 : if (svi_UseDisk == 1) + wd179x_track_w(value); + break; + + case 0x32 : if (svi_UseDisk == 1) + wd179x_sector_w(value); + break; + + case 0x33 : if (svi_UseDisk == 1) + wd179x_data_w(value); + break; + + case 0x34 : if (svi_UseDisk == 1) + svi_fdc_disk_motor(value); + break; + + case 0x38 : if (svi_UseDisk == 1) + svi_fdc_density_side(value); + break; + default: + strig &= 0xE0; + data &= 0x1F; + strig |= data; + } +} + +uint32_t MEMORY_EX::read_data8(uint32_t addr) +{ + addr &= 0xffff; + if (!play) + return rbank[addr >> 13][addr & 0x1fff]; + if (addr==0x210a) { + count=0; + done=0; + return 0xAF; + } + if (addr==0x210b) { + strig &= 0x7F; + return 0x00; + } + if (addr==0x210c) + return 0xc9; + if (addr==0x21a9) + return 0x3e; + if (addr==0x21aa) { + while ((tapePos=10; break; + case 0x55 : count++; break; + default : count=0; break; + } + } + return tapedata[tapePos++]; + } + if (addr==0x21ab) + return 0xc9; + return rbank[addr >> 13][addr & 0x1fff]; +} + +void MEMORY_EX::write_signal(int id, uint32_t data, uint32_t mask) { + if (data & 16) { + if (data & 4) { + SET_BANK(0x8000, 0xffff, ram, ram); + } else { + if (data % 2 == 1) { + SET_BANK(0x8000, 0xffff, r22, r22); + } else { + SET_BANK(0x8000, 0xffff, wdmy,r12); + } + } + } else { + SET_BANK(0x8000, 0xffff, r32, r32); + } + data &= 0x0f; + if (data==3 || data==7) { + SET_BANK(0x0000, 0x7fff, r31, r31); + } else if (data==13) { + SET_BANK(0x0000, 0x7fff, r21, r21); + } else { + if (data % 2 == 1) { + SET_BANK(0x0000, 0x7fff, wdmy,bio); + } else { + SET_BANK(0x0000, 0x7fff, wdmy,rom); + } + } + return; +} + +uint32_t MEMORY_EX::fetch_op(uint32_t addr, int* wait) +{ + *wait = 1; + return read_data8(addr); +} + +bool MEMORY_EX::play_tape(const _TCHAR* file_path) +{ + FILEIO* fio = new FILEIO(); + if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { + fio->Fread(tapedata, sizeof(tapedata), 1); + tapeLen = fio->Ftell(); + fio->Fclose(); + play = true; + } + delete fio; + strig = 0xBF; + tapePos=0; + return true; +} + +void MEMORY_EX::close_tape() +{ + memset(tapedata, 0, sizeof(tapedata)); + strig = 0xFF; + tapePos=0; + play = false; +} + + +#if defined(FDD_PATCH_SLOT) + +void MEMORY_EX::open_disk(int drv, const _TCHAR* file_path, int bank) +{ + if(drv < MAX_DRIVE) { +// disk[drv]->open(file_path, bank); + if (svi_LoadDisk(drv, (char *)file_path) > 0) + { + wd179x_InitDiskImage(drv, file_path); + disk[drv]->inserted = true; + svi_UseDisk = 1; + } + } +} + +void MEMORY_EX::close_disk(int drv) +{ + if(drv < MAX_DRIVE && disk[drv]->inserted) { +// disk[drv]->close(); + wd179x_CloseDiskImage(drv); + disk[drv]->inserted = false; + svi_UseDisk = 0; + } +} + +bool MEMORY_EX::is_disk_inserted(int drv) +{ + if(drv < MAX_DRIVE) { + return disk[drv]->inserted; + } + return false; +} + +void MEMORY_EX::is_disk_protected(int drv, bool value) +{ + if(drv < MAX_DRIVE) { + disk[drv]->write_protected = value; + } +} + +bool MEMORY_EX::is_disk_protected(int drv) +{ + if(drv < MAX_DRIVE) { + return disk[drv]->write_protected; + } + return false; +} + +#endif + +#define STATE_VERSION 1 + +bool MEMORY_EX::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(inserted); + // post process + if(loading) { + if(inserted) { + SET_BANK(0x0000, 0x7fff, wdmy, rom); + SET_BANK(0x8000, 0xffff, ram, ram); + } else { + SET_BANK(0x0000, 0x7fff, wdmy, bio); + SET_BANK(0x8000, 0xffff, ram, ram); + } + } + return true; +} +} diff --git a/source/src/vm/svi3x8/memory_ex.h b/source/src/vm/svi3x8/memory_ex.h new file mode 100644 index 000000000..38bf4570f --- /dev/null +++ b/source/src/vm/svi3x8/memory_ex.h @@ -0,0 +1,110 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/memory.h + + modified by tanam + Date : 2018.12.09- + + [ memory ] +*/ + +#ifndef _MEMORY_EX_SVI3X8_H_ +#define _MEMORY_EX_SVI3X8_H_ + +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" + +#define SIG_MEMORY_SEL 0 + +#if defined(FDD_PATCH_SLOT) +class DISK; +#endif + +#define MAX_TAPE_LEN 524288 + +namespace SVI_3X8 { +// memory bus +class MEMORY_EX : public DEVICE +{ +private: + uint8_t* wbank[8]; + uint8_t* rbank[8]; + uint8_t wdmy[0x2000]; + uint8_t rdmy[0x2000]; + uint8_t bio[0x8000]; /* BANK01 */ + uint8_t ram[0x8000]; /* BANK02 */ + uint8_t rom[0x8000]; /* BANK11 */ + uint8_t r12[0x8000]; /* BANK12 */ + uint8_t r21[0x8000]; /* BANK21 */ + uint8_t r22[0x8000]; /* BANK22 */ + uint8_t r31[0x8000]; /* BANK31 */ + uint8_t r32[0x8000]; /* BANK32 */ + bool inserted; + bool play; + uint8_t strig; +#if defined(FDD_PATCH_SLOT) + DISK* disk[MAX_DRIVE]; + DEVICE *d_fdpat; + bool access[MAX_DRIVE]; +#endif + int count; + int done; + int tapePos; + int tapeLen; + uint8_t tapedata[MAX_TAPE_LEN]; + +public: + MEMORY_EX(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + set_device_name(_T("Memory Bus")); + } + ~MEMORY_EX() {} + + // common functions + void initialize(); + void reset(); + void __FASTCALL write_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_data8(uint32_t addr); + uint32_t __FASTCALL fetch_op(uint32_t addr, int* wait); + bool process_state(FILEIO* state_fio, bool loading); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_io8(uint32_t addr); + void __FASTCALL write_io8(uint32_t addr, uint32_t data); + // unique functions + void open_cart(const _TCHAR *file_path); + void close_cart(); + bool load_cart(const _TCHAR *file_path/*, uint8_t *rom*/); + bool is_cart_inserted() + { + return inserted; + } + bool play_tape(const _TCHAR* file_path); +// bool rec_tape(const _TCHAR* file_path); + void close_tape(); +#if defined(FDD_PATCH_SLOT) + void release(); + void set_context_fdd_patch(DEVICE *device) + { + d_fdpat = device; + } + void open_disk(int drv, const _TCHAR* file_path, int bank); + void close_disk(int drv); + bool is_disk_inserted(int drv); + void is_disk_protected(int drv, bool value); + bool is_disk_protected(int drv); +#endif + bool is_tape_inserted() + { + return play; + } + const _TCHAR* get_message() + { + if (play) return "Play"; + else return "Stop"; + } +}; +} +#endif diff --git a/source/src/vm/svi3x8/msx_ex.cpp b/source/src/vm/svi3x8/msx_ex.cpp new file mode 100644 index 000000000..defe13313 --- /dev/null +++ b/source/src/vm/svi3x8/msx_ex.cpp @@ -0,0 +1,421 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/msx_ex.cpp + + modified by tanam + Date : 2018.12.09- + + [ virtual machine ] +*/ + +#include "msx_ex.h" +#include "../../emu.h" +#include "../device.h" +#include "../event.h" + +//#include "../datarec.h" +#include "../i8255.h" +#include "../io.h" +#include "../noise.h" +#include "../not.h" +#include "../ay_3_891x.h" +#include "../pcm1bit.h" +#include "../tms9918a.h" +#include "../z80.h" + +#ifdef USE_DEBUGGER +#include "../debugger.h" +#endif + +#include "joystick.h" +#include "keyboard.h" +#include "memory_ex.h" +#ifdef USE_PRINTER +#include "../msx/printer.h" +#include "../prnfile.h" +#endif + +using SVI_3X8::JOYSTICK; +using SVI_3X8::KEYBOARD; +using SVI_3X8::MEMORY_EX; +#ifdef USE_PRINTER +using MSX::PRINTER; +#endif +//using MSX::SLOT_MAINROM; +//using MSX::SLOT_CART; +// ---------------------------------------------------------------------------- +// initialize +// ---------------------------------------------------------------------------- + +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) +{ + // create devices + first_device = last_device = NULL; + dummy = new DEVICE(this, emu); // must be 1st device + event = new EVENT(this, emu); // must be 2nd device + +// drec = new DATAREC(this, emu); +// drec->set_context_noise_play(new NOISE(this, emu)); +// drec->set_context_noise_stop(new NOISE(this, emu)); +// drec->set_context_noise_fast(new NOISE(this, emu)); + pio = new I8255(this, emu); + io = new IO(this, emu); + not_remote = new NOT(this, emu); + psg = new AY_3_891X(this, emu); + pcm = new PCM1BIT(this, emu); + vdp = new TMS9918A(this, emu); + cpu = new Z80(this, emu); + + joystick = new JOYSTICK(this, emu); + keyboard = new KEYBOARD(this, emu); + memory = new MEMORY_EX(this, emu); +#ifdef USE_PRINTER + printer = new PRINTER(this, emu); +#endif + + // set contexts + event->set_context_cpu(cpu); + event->set_context_sound(psg); + event->set_context_sound(pcm); +// event->set_context_sound(drec); +// event->set_context_sound(drec->get_context_noise_play()); +// event->set_context_sound(drec->get_context_noise_stop()); +// event->set_context_sound(drec->get_context_noise_fast()); +// drec->set_context_ear(psg, SIG_AY_3_891X_PORT_A, 0x80); + pio->set_context_port_c(keyboard, SIG_KEYBOARD_COLUMN, 0x0f, 0); + pio->set_context_port_c(not_remote, SIG_NOT_INPUT, 0x10, 0); +// not_remote->set_context_out(drec, SIG_DATAREC_REMOTE, 1); +// pio->set_context_port_c(drec, SIG_DATAREC_MIC, 0x20, 0); + pio->set_context_port_c(pcm, SIG_PCM1BIT_SIGNAL, 0x80, 0); + psg->set_context_port_b(memory, SIG_MEMORY_SEL, 0x0f, 0); + vdp->set_context_irq(cpu, SIG_CPU_IRQ, 1); + + joystick->set_context_psg(psg); + joystick->set_context_memory(memory); + keyboard->set_context_pio(pio); + +#ifdef USE_PRINTER + if(config.printer_type == 0) { + printer->set_context_prn(new PRNFILE(this, emu)); + } else { + printer->set_context_prn(printer); + } +#endif + + // cpu bus + cpu->set_context_mem(memory); + cpu->set_context_io(io); + cpu->set_context_intr(dummy); +#ifdef USE_DEBUGGER + cpu->set_context_debugger(new DEBUGGER(this, emu)); +#endif + + // i/o bus + io->set_iomap_range_rw(0x30, 0x38, memory); + io->set_iomap_range_w(0x80, 0x81, vdp); + io->set_iomap_range_r(0x84, 0x85, vdp); + io->set_iomap_range_w(0x94, 0x97, pio); + io->set_iomap_range_r(0x99, 0x9a, pio); + io->set_iomap_alias_w(0x88, psg, 0); // PSG ch + io->set_iomap_alias_w(0x8c, psg, 1); // PSG data + io->set_iomap_alias_r(0x90, psg, 1); // STICK + io->set_iomap_alias_r(0x98, memory, 1); // STRIG +#ifdef USE_PRINTER + io->set_iomap_range_rw(0x10, 0x11, printer); +#endif + + // initialize all devices + for(DEVICE* device = first_device; device; device = device->next_device) { + device->initialize(); + } +} + +VM::~VM() +{ + // delete all devices + for(DEVICE* device = first_device; device;) { + DEVICE *next_device = device->next_device; + device->release(); + delete device; + device = next_device; + } +} + +DEVICE* VM::get_device(int id) +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + if(device->this_device_id == id) { + return device; + } + } + return NULL; +} + +// ---------------------------------------------------------------------------- +// drive virtual machine +// ---------------------------------------------------------------------------- + +void VM::reset() +{ + // reset all devices + for(DEVICE* device = first_device; device; device = device->next_device) { + device->reset(); + } +} + +void VM::run() +{ + event->drive(); +} + +// ---------------------------------------------------------------------------- +// debugger +// ---------------------------------------------------------------------------- + +#ifdef USE_DEBUGGER +DEVICE *VM::get_cpu(int index) +{ + if(index == 0) { + return cpu; + } + return NULL; +} +#endif + +// ---------------------------------------------------------------------------- +// draw screen +// ---------------------------------------------------------------------------- + +void VM::draw_screen() +{ + vdp->draw_screen(); +} + +// ---------------------------------------------------------------------------- +// soud manager +// ---------------------------------------------------------------------------- + +void VM::initialize_sound(int rate, int samples) +{ + // init sound manager + event->initialize_sound(rate, samples); + + // init sound gen + psg->initialize_sound(rate, 3579545, samples, 0, 0); + pcm->initialize_sound(rate, 8000); +} + +uint16_t* VM::create_sound(int* extra_frames) +{ + return event->create_sound(extra_frames); +} + +int VM::get_sound_buffer_ptr() +{ + return event->get_sound_buffer_ptr(); +} + +#ifdef USE_SOUND_VOLUME +void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r) +{ + if(ch == 0) { + psg->set_volume(1, decibel_l, decibel_r); + } else if(ch == 1) { + pcm->set_volume(0, decibel_l, decibel_r); +// } else if(ch == 2) { +// drec->set_volume(0, decibel_l, decibel_r); +// } else if(ch == 6) { +// drec->get_context_noise_play()->set_volume(0, decibel_l, decibel_r); +// drec->get_context_noise_stop()->set_volume(0, decibel_l, decibel_r); +// drec->get_context_noise_fast()->set_volume(0, decibel_l, decibel_r); + } +} +#endif + +// ---------------------------------------------------------------------------- +// user interface +// ---------------------------------------------------------------------------- + +void VM::open_cart(int drv, const _TCHAR* file_path) +{ + if(drv == 0) { +// slot_cart[drv]->open_cart(file_path); +// memory->set_context_slot(MAINROM_SLOT, slot_cart[0]); + memory->open_cart(file_path); + } + + reset(); +} + +void VM::close_cart(int drv) +{ + if(drv == 0) { +// slot_cart[drv]->close_cart(); +// memory->set_context_slot(MAINROM_SLOT, slot_mainrom); + memory->close_cart(); + } + reset(); +} + +bool VM::is_cart_inserted(int drv) +{ + if(drv == 0) { +// return slot_cart[drv]->is_cart_inserted(); + return memory->is_cart_inserted(); + } else { + return false; + } +} + +void VM::play_tape(int drv, const _TCHAR* file_path) +{ + memory->play_tape(file_path); +// bool remote = drec->get_remote(); + +// if(drec->play_tape(file_path) && remote) { +// // if machine already sets remote on, start playing now +// push_play(drv); +// } +} + +void VM::rec_tape(int drv, const _TCHAR* file_path) +{ +// bool remote = drec->get_remote(); + +// if(drec->rec_tape(file_path) && remote) { +// // if machine already sets remote on, start recording now +// push_play(drv); +// } +} + +void VM::close_tape(int drv) +{ + emu->lock_vm(); + memory->close_tape(); + emu->unlock_vm(); +// drec->set_remote(false); +} + +bool VM::is_tape_inserted(int drv) +{ + return memory->is_tape_inserted(); +} + +bool VM::is_tape_playing(int drv) +{ + return false; +// return drec->is_tape_playing(); +} + +bool VM::is_tape_recording(int drv) +{ + return false; +// return drec->is_tape_recording(); +} + +int VM::get_tape_position(int drv) +{ + return 0; +// return drec->get_tape_position(); +} + +const _TCHAR* VM::get_tape_message(int drv) +{ + return memory->get_message(); +} + +void VM::push_play(int drv) +{ +// drec->set_remote(false); +// drec->set_ff_rew(0); +// drec->set_remote(true); +} + +void VM::push_stop(int drv) +{ +// drec->set_remote(false); +} + +void VM::push_fast_forward(int drv) +{ +// drec->set_remote(false); +// drec->set_ff_rew(1); +// drec->set_remote(true); +} + +void VM::push_fast_rewind(int drv) +{ +// drec->set_remote(false); +// drec->set_ff_rew(-1); +// drec->set_remote(true); +} + +#if defined(FDD_PATCH_SLOT) +void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank) +{ + memory->open_disk(drv, file_path, bank); +} + +void VM::close_floppy_disk(int drv) +{ + memory->close_disk(drv); +} + +bool VM::is_floppy_disk_inserted(int drv) +{ + return memory->is_disk_inserted(drv); +} + +void VM::is_floppy_disk_protected(int drv, bool value) +{ + memory->is_disk_protected(drv, value); +} + +bool VM::is_floppy_disk_protected(int drv) +{ + return memory->is_disk_protected(drv); +} + +uint32_t VM::is_floppy_disk_accessed() +{ + return memory->read_signal(0); +} +#endif + +bool VM::is_frame_skippable() +{ + return event->is_frame_skippable(); +} + +void VM::update_config() +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + device->update_config(); + } +} + +#define STATE_VERSION 5 + +bool VM::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + for(DEVICE* device = first_device; device; device = device->next_device) { + const char *name = typeid(*device).name() + 6; // skip "class " + int len = (int)strlen(name); + + if(!state_fio->StateCheckInt32(len)) { + return false; + } + if(!state_fio->StateCheckBuffer(name, len, 1)) { + return false; + } + if(!device->process_state(state_fio, loading)) { + return false; + } + } + return true; +} diff --git a/source/src/vm/svi3x8/msx_ex.h b/source/src/vm/svi3x8/msx_ex.h new file mode 100644 index 000000000..a1d9bac5f --- /dev/null +++ b/source/src/vm/svi3x8/msx_ex.h @@ -0,0 +1,210 @@ +/* + Common Source Code Project + SVI-3x8 + + Origin : src/vm/msx/msx.h + + modified by tanam + Date : 2018.12.09- + + [ virtual machine ] +*/ + +#ifndef _MSX_EX_SVI3X8_H_ +#define _MSX_EX_SVI3X8_H_ + +#if defined(_SVI3X8) +#define DEVICE_NAME "SPECTRAVIDEO SVI-3x8" +#define CONFIG_NAME "svi3x8" +#endif + +#if defined(_SVI3X8) +#define _MSX1_VARIANTS +#define MAINROM_SLOT 0x00 +#define CART1_SLOT 0x01 +#define FDD_PATCH_SLOT 0x8B + +#endif + +// device informations for virtual machine +#define FRAMES_PER_SEC 60 +#define LINES_PER_FRAME 262 +#define CPU_CLOCKS 3579545 +#if defined(_MSX1_VARIANTS) +#define SCREEN_WIDTH 512 +#define SCREEN_HEIGHT 384 +#define WINDOW_WIDTH_ASPECT 576 +#endif +#define TMS9918A_VRAM_SIZE 0x4000 +#define TMS9918A_LIMIT_SPRITES +//#if defined(FDD_PATCH_SLOT) +#define MAX_DRIVE 2 +//#define SUPPORT_MEDIA_TYPE_1DD +//#define Z80_PSEUDO_BIOS +//#endif +#define HAS_AY_3_8910 +// for Flappy Limited '85 +#define AY_3_891X_PORT_MODE 0x80 + +// device informations for win32 +#define USE_CART 2 +#define USE_TAPE 1 +//#if defined(FDD_PATCH_SLOT) +#define USE_FLOPPY_DISK 2 +//#endif +#define USE_AUTO_KEY 6 +#define USE_AUTO_KEY_RELEASE 10 +#define USE_SOUND_VOLUME 7 +#define USE_JOYSTICK +#define USE_DEBUGGER +#define USE_STATE +//#define USE_PRINTER +//#define USE_PRINTER_TYPE 4 + +#include "../../common.h" +#include "../../fileio.h" +#include "../vm_template.h" + +#ifdef USE_SOUND_VOLUME +static const _TCHAR *sound_device_caption[] = { + _T("PSG"), _T("Beep"), _T("CMT (Signal)"), + _T("Cart#1"), _T("Cart#2"), _T("MSX-MUSIC"), _T("Noise (CMT)"), +}; +#endif + +class EMU; +class DEVICE; +class EVENT; + +//class DATAREC; +class I8255; +class IO; +class NOT; +class AY_3_891X; +class PCM1BIT; +class TMS9918A; +class Z80; + +namespace SVI_3X8 { + class JOYSTICK; + class KEYBOARD; + class MEMORY_EX; +} +namespace MSX { + class SLOT_MAINROM; + class SLOT_CART; +#if defined(USE_PRINTER) + class PRINTER; +#endif +} +//#if defined(FDD_PATCH_SLOT) +//class SLOT_FDD_PATCH; +//#endif + +class VM : public VM_TEMPLATE +{ +protected: +// EMU* emu; + + // devices + EVENT* event; + +// DATAREC* drec; + I8255* pio; + IO* io; + NOT* not_remote; + AY_3_891X* psg; + PCM1BIT* pcm; + TMS9918A* vdp; + Z80* cpu; + + SVI_3X8::JOYSTICK* joystick; + SVI_3X8::KEYBOARD* keyboard; + SVI_3X8::MEMORY_EX* memory; + MSX::SLOT_MAINROM *slot_mainrom; + MSX::SLOT_CART *slot_cart[1]; +//#ifdef USE_PRINTER +// MSX::PRINTER* printer; +//#endif + +public: + // ---------------------------------------- + // initialize + // ---------------------------------------- + + VM(EMU_TEMPLATE* parent_emu); + ~VM(); + + // ---------------------------------------- + // for emulation class + // ---------------------------------------- + + // drive virtual machine + void reset(); + void run(); + double get_frame_rate() + { + return FRAMES_PER_SEC; + } + +#ifdef USE_DEBUGGER + // debugger + DEVICE *get_cpu(int index); +#endif + + // draw screen + void draw_screen(); + + // sound generation + void initialize_sound(int rate, int samples); + uint16_t* create_sound(int* extra_frames); + int get_sound_buffer_ptr(); +#ifdef USE_SOUND_VOLUME + void set_sound_device_volume(int ch, int decibel_l, int decibel_r); +#endif + + // user interface + void open_cart(int drv, const _TCHAR* file_path); + void close_cart(int drv); + bool is_cart_inserted(int drv); + void play_tape(int drv, const _TCHAR* file_path); + void rec_tape(int drv, const _TCHAR* file_path); + void close_tape(int drv); + bool is_tape_inserted(int drv); + bool is_tape_playing(int drv); + bool is_tape_recording(int drv); + int get_tape_position(int drv); + const _TCHAR* get_tape_message(int drv); + void push_play(int drv); + void push_stop(int drv); + void push_fast_forward(int drv); + void push_fast_rewind(int drv); + void push_apss_forward(int drv) {} + void push_apss_rewind(int drv) {} + +#if defined(FDD_PATCH_SLOT) + void open_floppy_disk(int drv, const _TCHAR* file_path, int bank); + void close_floppy_disk(int drv); + bool is_floppy_disk_inserted(int drv); + void is_floppy_disk_protected(int drv, bool value); + bool is_floppy_disk_protected(int drv); + uint32_t is_floppy_disk_accessed(); +#endif + + bool is_frame_skippable(); + + void update_config(); + bool process_state(FILEIO* state_fio, bool loading); + + // ---------------------------------------- + // for each device + // ---------------------------------------- + + // devices + DEVICE* get_device(int id); +// DEVICE* dummy; +// DEVICE* first_device; +// DEVICE* last_device; +}; + +#endif diff --git a/source/src/vm/sy6522.h b/source/src/vm/sy6522.h index b7d36c22c..8289fc428 100644 --- a/source/src/vm/sy6522.h +++ b/source/src/vm/sy6522.h @@ -26,8 +26,8 @@ #ifndef _SY6522_H_ #define _SY6522_H_ -//#include "vm.h" -//#include "../emu.h" +#include "vm.h" +#include "../emu.h" #include "device.h" #define SIG_SY6522_PORT_A 0 @@ -37,8 +37,6 @@ #define SIG_SY6522_PORT_CB1 4 #define SIG_SY6522_PORT_CB2 5 -class VM; -class EMU; class SY6522 : public DEVICE { private: @@ -53,8 +51,8 @@ class SY6522 : public DEVICE uint16_t get_counter1_value(); - void set_int(int data); - void clear_int(int data); + void __FASTCALL set_int(int data); + void __FASTCALL clear_int(int data); void shift_out(); void shift_in(); @@ -109,7 +107,7 @@ class SY6522 : public DEVICE uint8_t m_shift_counter; public: - SY6522(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SY6522(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_a); initialize_output_signals(&outputs_b); @@ -127,7 +125,7 @@ class SY6522 : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/t3444a.h b/source/src/vm/t3444a.h index a429a65eb..c067e830a 100644 --- a/source/src/vm/t3444a.h +++ b/source/src/vm/t3444a.h @@ -32,7 +32,7 @@ class DISK; class NOISE; -class T3444A : public DEVICE +class DLL_PREFIX T3444A : public DEVICE { private: // output signals @@ -109,13 +109,13 @@ class T3444A : public DEVICE void cmd_read_write(); void cmd_write_id(); void cmd_sence(); - void update_head_flag(int drv, bool head_load); + void __FASTCALL update_head_flag(int drv, bool head_load); // rqm - void set_rqm(bool val); + void __FASTCALL set_rqm(bool val); public: - T3444A(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + T3444A(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_rqm); d_noise_seek = NULL; @@ -140,7 +140,7 @@ class T3444A : public DEVICE uint32_t __FASTCALL read_dma_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/tf20.h b/source/src/vm/tf20.h index b1efea63b..84d684c25 100644 --- a/source/src/vm/tf20.h +++ b/source/src/vm/tf20.h @@ -13,9 +13,8 @@ //#include "vm.h" //#include "../emu.h" #include "device.h" -class VM; -class EMU; -class TF20 : public DEVICE + +class DLL_PREFIX TF20 : public DEVICE { private: DEVICE *d_cpu, *d_fdc, *d_pio, *d_sio; @@ -30,7 +29,7 @@ class TF20 : public DEVICE uint8_t* rbank[32]; public: - TF20(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TF20(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { drive_no = 0; set_device_name(_T("TF-20 FDD")); diff --git a/source/src/vm/tk80bs/CMakeLists.txt b/source/src/vm/tk80bs/CMakeLists.txt index d71754106..37a7ef77f 100644 --- a/source/src/vm/tk80bs/CMakeLists.txt +++ b/source/src/vm/tk80bs/CMakeLists.txt @@ -1,18 +1,28 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/tk80bs") +message("* vm/${EXE_NAME}") set(VMFILES_TK display.cpp keyboard.cpp membus.cpp -# memory.cpp +# ./memory.cpp + ../i8080.cpp + tk80bs.cpp ) -if(BUILD_TK80BS) - set(VMFILES_TK ${VMFILES_TK} cmt.cpp) +if(${EXE_NAME} STREQUAL emutk80bs) + add_library(vm_emutk80bs + cmt.cpp + ${VMFILES_TK} + ) +elseif(${EXE_NAME} STREQUAL emutk80) + add_library(vm_emutk80 + cmt.cpp + ${VMFILES_TK} + ) +else() + add_library(vm_${EXE_NAME} + ${VMFILES_TK} + ) endif() -add_library(vm_tk80bs - ${VMFILES_TK} - tk80bs.cpp -) \ No newline at end of file diff --git a/source/src/vm/tk80bs/cmt.h b/source/src/vm/tk80bs/cmt.h index 0c2214154..f757f593d 100644 --- a/source/src/vm/tk80bs/cmt.h +++ b/source/src/vm/tk80bs/cmt.h @@ -49,7 +49,7 @@ class CMT : public DEVICE #endif public: - CMT(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CMT(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("CMT I/F")); } @@ -62,7 +62,7 @@ class CMT : public DEVICE void reset(); #endif void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/tk80bs/display.h b/source/src/vm/tk80bs/display.h index a55c0f027..928fe88df 100644 --- a/source/src/vm/tk80bs/display.h +++ b/source/src/vm/tk80bs/display.h @@ -33,7 +33,7 @@ class DISPLAY : public DEVICE bool dma; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/tk80bs/keyboard.h b/source/src/vm/tk80bs/keyboard.h index e68ec2c04..c4d456dcd 100644 --- a/source/src/vm/tk80bs/keyboard.h +++ b/source/src/vm/tk80bs/keyboard.h @@ -39,7 +39,7 @@ class KEYBOARD : public DEVICE void update_tk80(); public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/tk80bs/membus.h b/source/src/vm/tk80bs/membus.h index 527a965ca..688dc3784 100644 --- a/source/src/vm/tk80bs/membus.h +++ b/source/src/vm/tk80bs/membus.h @@ -12,6 +12,7 @@ #ifndef _MEMBUS_H_ #define _MEMBUS_H_ +#include "../vm.h" #include "../memory.h" #if defined(_TK85) @@ -30,7 +31,7 @@ class MEMBUS : public MEMORY #endif public: - MEMBUS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : MEMORY(parent_vm, parent_emu) + MEMBUS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : MEMORY(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/tk80bs/memory.h b/source/src/vm/tk80bs/memory.h index ec22364f9..aeb5a188f 100644 --- a/source/src/vm/tk80bs/memory.h +++ b/source/src/vm/tk80bs/memory.h @@ -36,7 +36,7 @@ class MEMORY : public DEVICE int boot_mode; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/tk80bs/tk80bs.cpp b/source/src/vm/tk80bs/tk80bs.cpp index 640e56d25..b70e76151 100644 --- a/source/src/vm/tk80bs/tk80bs.cpp +++ b/source/src/vm/tk80bs/tk80bs.cpp @@ -47,7 +47,7 @@ using TK80::MEMBUS; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { #if defined(_TK80BS) // check configs @@ -95,6 +95,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) display = new DISPLAY(this, emu); keyboard = new KEYBOARD(this, emu); memory = new MEMBUS(this, emu); + #if defined(_TK80BS) pio_t->set_device_name(_T("i8255 PIO (TK-80/SOUND/KEYBOARD/DISPLAY)")); #else @@ -566,6 +567,18 @@ void VM::update_config() #endif } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 6 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -578,7 +591,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/tk80bs/tk80bs.h b/source/src/vm/tk80bs/tk80bs.h index d163c7e2c..d65ca6a4e 100644 --- a/source/src/vm/tk80bs/tk80bs.h +++ b/source/src/vm/tk80bs/tk80bs.h @@ -193,7 +193,7 @@ class I8255; class PCM1BIT; namespace TK80 { -#if defined(_TK80BS) +#if defined(_TK80BS) || defined(_TK80) class CMT; #endif //class MEMORY; @@ -222,7 +222,7 @@ class VM : public VM_TEMPLATE PCM1BIT* pcm0; PCM1BIT* pcm1; -#if defined(_TK80BS) +#if defined(_TK80BS) || defined(_TK80) TK80::CMT* cmt; #endif TK80::DISPLAY* display; @@ -246,7 +246,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -305,6 +305,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/tms3631.h b/source/src/vm/tms3631.h index 378e036dc..c2d5d57ca 100644 --- a/source/src/vm/tms3631.h +++ b/source/src/vm/tms3631.h @@ -20,9 +20,7 @@ #define SIG_TMS3631_DATAREG 2 #define SIG_TMS3631_MASKREG 3 -class VM; -class EMU; -class TMS3631 : public DEVICE +class DLL_PREFIX TMS3631 : public DEVICE { private: uint8_t envelop1, envelop2, datareg, maskreg; @@ -39,7 +37,7 @@ class TMS3631 : public DEVICE int volume_l, volume_r; public: - TMS3631(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TMS3631(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("TMS3631 SSG")); @@ -49,7 +47,7 @@ class TMS3631 : public DEVICE // common functions void reset(); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/tms9918a.h b/source/src/vm/tms9918a.h index 7cf7579d2..4f1108e97 100644 --- a/source/src/vm/tms9918a.h +++ b/source/src/vm/tms9918a.h @@ -19,7 +19,7 @@ #define SIG_TMS9918A_SUPER_IMPOSE 0 class DEBUGGER; -class TMS9918A : public DEVICE +class DLL_PREFIX TMS9918A : public DEVICE { private: DEBUGGER *d_debugger; @@ -64,7 +64,7 @@ class TMS9918A : public DEVICE inline void draw_screen_256_nonimpose(); public: - TMS9918A(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TMS9918A(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_irq); vram = NULL; diff --git a/source/src/vm/tms9995.cpp b/source/src/vm/tms9995.cpp index 1bcb813ae..980d7cce5 100644 --- a/source/src/vm/tms9995.cpp +++ b/source/src/vm/tms9995.cpp @@ -1665,7 +1665,7 @@ typedef UINT32 offs_t; #endif #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) +#define CPU_DISASSEMBLE(name) int DLL_PREFIX CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, symbol_t *first_symbol) #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, pc, oprom, opram, d_debugger->first_symbol) const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported? diff --git a/source/src/vm/tms9995.h b/source/src/vm/tms9995.h index fd8937407..3a8ba8ec4 100644 --- a/source/src/vm/tms9995.h +++ b/source/src/vm/tms9995.h @@ -115,7 +115,7 @@ class TMS9995 : public DEVICE inline uint16_t setst_sla_laeco(uint16_t a, uint16_t c); public: - TMS9995(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + TMS9995(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { // init registers #ifdef USE_DEBUGGER diff --git a/source/src/vm/tvboy/CMakeLists.txt b/source/src/vm/tvboy/CMakeLists.txt new file mode 100644 index 000000000..cdcc87586 --- /dev/null +++ b/source/src/vm/tvboy/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required (VERSION 2.6) + +message("* vm/${EXE_NAME}") + +string(TOUPPER "${EXE_NAME}" U_EXE_NAME) + +add_library(vm_${EXE_NAME} + ../mc6847.cpp + + ./memory.cpp + + ./tvboy.cpp + ) diff --git a/source/src/vm/tvboy/memory.cpp b/source/src/vm/tvboy/memory.cpp new file mode 100644 index 000000000..5f9330f89 --- /dev/null +++ b/source/src/vm/tvboy/memory.cpp @@ -0,0 +1,198 @@ +/* + GAKKEN TV BOY Emulator 'yaTVBOY' + + Author : tanam + Date : 2020.06.13 + + [ memory ] +*/ + +#include "./memory.h" +#include "../mc6847.h" +#include "../mc6801.h" + +namespace TVBOY { + +#define SET_BANK(s, e, w, r) { \ + int sb = (s) >> 10, eb = (e) >> 10; \ + for(int i = sb; i <= eb; i++) { \ + if((w) == wdmy) { \ + wbank[i] = wdmy; \ + } else { \ + wbank[i] = (w) + 0x400 * (i - sb); \ + } \ + if((r) == rdmy) { \ + rbank[i] = rdmy; \ + } else { \ + rbank[i] = (r) + 0x400 * (i - sb); \ + } \ + } \ +} + +void MEMORY::initialize() +{ + memset(rom, 0xff, sizeof(rom)); + memset(rdmy, 0xff, sizeof(rdmy)); + // set memory map + SET_BANK(0x0000, 0x0fff, ram, ram ); + SET_BANK(0x1000, 0x1fff, vram, vram); + SET_BANK(0x2000, 0xefff, wdmy, rdmy); + SET_BANK(0xf000, 0xffff, wdmy, rom ); + // register event + register_event_by_clock(this, 0, 256, true, NULL); + event = false; + inserted = false; +} + +void MEMORY::reset() +{ + memset(ram, 0, sizeof(ram)); + for (int i=0; iwrite_signal(SIG_MC6847_AS, 0x00, 0x08); + d_vdp->write_signal(SIG_MC6847_AG, 0x10, 0x10); + d_vdp->write_signal(SIG_MC6847_CSS, 0x20, 0x20); + d_vdp->write_signal(SIG_MC6847_GM, 0x00, 0x02); + d_vdp->write_signal(SIG_MC6847_GM, 0x01, 0x01); + d_vdp->write_signal(SIG_MC6847_INTEXT, 0x00, 0x04); + shot1 = shot2 = up = down = left = right = 0; +} + +void MEMORY::write_data8(uint32_t addr, uint32_t data) +{ + addr &= 0xffff; + if(addr >= 0x80 && addr < 0x100) { + d_cpu->ram[addr-0x80]=data; + } + if(addr == 0x2000) { + d_vdp->write_signal(SIG_MC6847_AS, data, 0x08); + d_vdp->write_signal(SIG_MC6847_AG, data, 0x10); + d_vdp->write_signal(SIG_MC6847_CSS, data, 0x20); + d_vdp->write_signal(SIG_MC6847_GM, data << 1, 0x02); + d_vdp->write_signal(SIG_MC6847_GM, data >> 1, 0x01); + d_vdp->write_signal(SIG_MC6847_INTEXT, data, 0x04); + return; + } + wbank[addr >> 10][addr & 0x3ff] = data; +} + +uint32_t MEMORY::read_data8(uint32_t addr) +{ + addr &= 0xffff; + if(addr >= 0x80 && addr < 0x100) { + return d_cpu->ram[addr-0x80]; + } + return rbank[addr >> 10][addr & 0x3ff]; +} + +void MEMORY::write_signal(int id, uint32_t data, uint32_t mask) +{ + d_cpu->write_signal(SIG_MC6801_PORT_2, 0x1E, 0x1E); + if (shot2==1 && d_cpu->port[0].wreg==1) { + d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x04); + } + if (down==1 && d_cpu->port[0].wreg==2) { + d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x04); + } + if (shot1==1 && d_cpu->port[0].wreg==1) { + d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x02); + } + if (up==1 && d_cpu->port[0].wreg==2) { + d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x02); + } + if (left==1 && d_cpu->port[0].wreg==2) { + d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x08); + } + if (right==1 && d_cpu->port[0].wreg==2) { + d_cpu->write_signal(SIG_MC6801_PORT_2, 0x00, 0x10); + } +} + +void MEMORY::event_callback(int event_id, int err) +{ + if (event) { + d_cpu->write_signal(SIG_CPU_IRQ, 1, 1); + event = false; + } else { + d_cpu->write_signal(SIG_CPU_IRQ, 0, 1); + event = true; + } +} + +void MEMORY::key_down(int code) +{ + if (code==0x20) { + shot1 =1; + } + if (code==0x11) { + shot2 =1; + } + if (code==0x25) { + left =1; + } + if (code==0x26) { + up =1; + } + if (code==0x27) { + right =1; + } + if (code==0x28) { + down =1; + } +} + +void MEMORY::key_up(int code) +{ + if (code==0x20) { + shot1 =0; + } + if (code==0x11) { + shot2 =0; + } + if (code==0x25) { + left =0; + } + if (code==0x26) { + up =0; + } + if (code==0x27) { + right =0; + } + if (code==0x28) { + down =0; + } +} + +void MEMORY::open_cart(const _TCHAR* file_path) +{ + FILEIO* fio = new FILEIO(); + if(fio->Fopen(file_path, FILEIO_READ_BINARY)) { + fio->Fread(rom, sizeof(rom), 1); + fio->Fclose(); + inserted = true; + } + delete fio; +} + +void MEMORY::close_cart() +{ + memset(rom, 0xff, sizeof(rom)); + inserted = false; +} + +#define STATE_VERSION 1 + +bool MEMORY::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateArray(ram, sizeof(ram), 1); + state_fio->StateArray(vram, sizeof(vram), 1); + return true; +} +} diff --git a/source/src/vm/tvboy/memory.h b/source/src/vm/tvboy/memory.h new file mode 100644 index 000000000..f9290b3fd --- /dev/null +++ b/source/src/vm/tvboy/memory.h @@ -0,0 +1,85 @@ +/* + GAKKEN TV BOY Emulator 'yaTVBOY' + + Author : tanam + Date : 2020.06.13 + + [ memory ] +*/ + +#ifndef _MEMORY_H_ +#define _MEMORY_H_ + +#include "../vm.h" +#include "../../emu.h" +#include "../device.h" +#include "../mc6800.h" +#include "../mc6847.h" + +#define SIG_MEMORY_PORT_1 0 + +namespace TVBOY { +class MEMORY : public DEVICE +{ +private: + MC6800 *d_cpu; + MC6847 *d_vdp; + + uint8_t rom[0x1000]; + uint8_t ram[0x1000]; + uint8_t vram[0x1000]; + + uint8_t wdmy[0x400]; + uint8_t rdmy[0x400]; + uint8_t* wbank[64]; + uint8_t* rbank[64]; + + int shot1; + int shot2; + int up; + int down; + int left; + int right; + bool event; + bool inserted; + +public: + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) + { + set_device_name(_T("Memory Bus")); + } + ~MEMORY() {} + + // common functions + void initialize(); + void reset(); + void __FASTCALL write_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_data8(uint32_t addr); + void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); + void __FASTCALL event_callback(int event_id, int err); + bool process_state(FILEIO* state_fio, bool loading); + // unique functions + void key_down(int code); + void key_up(int code); + void set_context_cpu(MC6800* device) + { + d_cpu = device; + } + void set_context_vdp(MC6847* device) + { + d_vdp = device; + } + void open_cart(const _TCHAR* file_path); + void close_cart(); + bool is_cart_inserted() + { + return inserted; + } + uint8_t* get_vram() + { + return vram; + } +}; +} + +#endif diff --git a/source/src/vm/tvboy/tvboy.cpp b/source/src/vm/tvboy/tvboy.cpp new file mode 100644 index 000000000..c53fe8e01 --- /dev/null +++ b/source/src/vm/tvboy/tvboy.cpp @@ -0,0 +1,238 @@ +/* + GAKKEN TV BOY Emulator 'yaTVBOY' + + Author : tanam + Date : 2020.06.13 + + [ virtual machine ] +*/ + +#include "tvboy.h" +#include "../../emu.h" +#include "../device.h" +#include "../event.h" + +#include "../mc6847.h" +#include "../mc6801.h" +#include "../pcm1bit.h" + +#ifdef USE_DEBUGGER +#include "../debugger.h" +#endif + +#include "./memory.h" + +// ---------------------------------------------------------------------------- +// initialize +// ---------------------------------------------------------------------------- +using TVBOY::MEMORY; + +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) +{ + // create devices + first_device = last_device = NULL; + dummy = new DEVICE(this, emu); // must be 1st device + event = new EVENT(this, emu); // must be 2nd device + + vdp = new MC6847(this, emu); + cpu = new MC6801(this, emu); + + memory = new MEMORY(this, emu); + memory->set_context_cpu(cpu); + memory->set_context_vdp(vdp); + + pcm = new PCM1BIT(this, emu); + + cpu->set_context_port1(pcm, SIG_PCM1BIT_SIGNAL, 0x20, 0); + cpu->set_context_port1(pcm, SIG_PCM1BIT_SIGNAL, 0x40, 0); + cpu->set_context_port1(memory, SIG_MEMORY_PORT_1, 0x0F, 0); + + // set contexts + event->set_context_cpu(cpu); + event->set_context_sound(pcm); + + vdp->set_vram_ptr(memory->get_vram(), 0x800); + vdp->set_context_cpu(cpu); + + // cpu bus + cpu->set_context_mem(memory); +#ifdef USE_DEBUGGER + cpu->set_context_debugger(new DEBUGGER(this, emu)); +#endif + pcm = new PCM1BIT(this, emu); + + // initialize all devices + for(DEVICE* device = first_device; device; device = device->next_device) { + device->initialize(); + } +} + +VM::~VM() +{ + // delete all devices + for(DEVICE* device = first_device; device;) { + DEVICE *next_device = device->next_device; + device->release(); + delete device; + device = next_device; + } +} + +DEVICE* VM::get_device(int id) +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + if(device->this_device_id == id) { + return device; + } + } + return NULL; +} + +// ---------------------------------------------------------------------------- +// drive virtual machine +// ---------------------------------------------------------------------------- + +void VM::reset() +{ + // reset all devices + for(DEVICE* device = first_device; device; device = device->next_device) { + device->reset(); + } +} + +void VM::run() +{ + event->drive(); +} + +// ---------------------------------------------------------------------------- +// debugger +// ---------------------------------------------------------------------------- + +#ifdef USE_DEBUGGER +DEVICE *VM::get_cpu(int index) +{ + if(index == 0) { + return cpu; + } + return NULL; +} +#endif + +// ---------------------------------------------------------------------------- +// draw screen +// ---------------------------------------------------------------------------- + +void VM::draw_screen() +{ + vdp->draw_screen(); +} + +// ---------------------------------------------------------------------------- +// notify key +// ---------------------------------------------------------------------------- + +void VM::key_down(int code, bool repeat) +{ + memory->key_down(code); +} + +void VM::key_up(int code) +{ + memory->key_up(code); +} + +// ---------------------------------------------------------------------------- +// soud manager +// ---------------------------------------------------------------------------- + +void VM::initialize_sound(int rate, int samples) +{ + // init sound manager + event->initialize_sound(rate, samples); + pcm->initialize_sound(rate, 8000); +} + +uint16_t* VM::create_sound(int* extra_frames) +{ + return event->create_sound(extra_frames); +} + +int VM::get_sound_buffer_ptr() +{ + return event->get_sound_buffer_ptr(); +} + +#ifdef USE_SOUND_VOLUME +void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r) +{ + if(ch == 0) { + pcm->set_volume(0, decibel_l, decibel_r); + } +} +#endif + +// ---------------------------------------------------------------------------- +// user interface +// ---------------------------------------------------------------------------- + +void VM::open_cart(int drv, const _TCHAR* file_path) +{ + if(drv == 0) { + memory->open_cart(file_path); + reset(); + } +} + +void VM::close_cart(int drv) +{ + if(drv == 0) { + memory->close_cart(); + reset(); + } +} + +bool VM::is_cart_inserted(int drv) +{ + if(drv == 0) { + return memory->is_cart_inserted(); + } else { + return false; + } +} + +bool VM::is_frame_skippable() +{ + return event->is_frame_skippable(); +} + +void VM::update_config() +{ + for(DEVICE* device = first_device; device; device = device->next_device) { + device->update_config(); + } +} + +#define STATE_VERSION 3 + +bool VM::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + for(DEVICE* device = first_device; device; device = device->next_device) { + const char *name = typeid(*device).name() + 6; // skip "class " + int len = (int)strlen(name); + + if(!state_fio->StateCheckInt32(len)) { + return false; + } + if(!state_fio->StateCheckBuffer(name, len, 1)) { + return false; + } + if(!device->process_state(state_fio, loading)) { + return false; + } + } + return true; +} diff --git a/source/src/vm/tvboy/tvboy.h b/source/src/vm/tvboy/tvboy.h new file mode 100644 index 000000000..b555dbfd4 --- /dev/null +++ b/source/src/vm/tvboy/tvboy.h @@ -0,0 +1,128 @@ +/* + GAKKEN TV BOY Emulator 'yaTVBOY' + + Author : tanam + Date : 2020.06.13 + + [ virtual machine ] +*/ + +#ifndef _TVBOY_H_ +#define _TVBOY_H_ + +#define DEVICE_NAME "GAKKEN TV BOY" +#define CONFIG_NAME "tvboy" + +// device informations for virtual machine +#define FRAMES_PER_SEC 60 +#define LINES_PER_FRAME 262 +#define CPU_CLOCKS 3579545 / 4 +#define SCREEN_WIDTH 256 +#define SCREEN_HEIGHT 192 + +#define HAS_MC6801 +#define MC6847_VRAM_INV 0x40 + +// device informations for win32 +#define USE_CART 1 +#define USE_SOUND_VOLUME 2 +#define USE_DEBUGGER +#define USE_STATE + +#include "../../common.h" +#include "../../fileio.h" +#include "../vm_template.h" + +#ifdef USE_SOUND_VOLUME +static const _TCHAR *sound_device_caption[] = { + _T("PCM"), +}; +#endif + +class EMU; +class DEVICE; +class EVENT; + +class MC6847; +class MC6801; +class PCM1BIT; + +namespace TVBOY { + class MEMORY; +} +class VM : public VM_TEMPLATE +{ +protected: +// EMU* emu; + + // devices + EVENT* event; + + MC6847* vdp; + MC6801* cpu; + PCM1BIT* pcm; + + TVBOY::MEMORY* memory; + +public: + // ---------------------------------------- + // initialize + // ---------------------------------------- + + VM(EMU_TEMPLATE* parent_emu); + ~VM(); + + // ---------------------------------------- + // for emulation class + // ---------------------------------------- + + // drive virtual machine + void reset(); + void run(); + double get_frame_rate() + { + return FRAMES_PER_SEC; + } + +#ifdef USE_DEBUGGER + // debugger + DEVICE *get_cpu(int index); +#endif + + // draw screen + void draw_screen(); + + // sound generation + void initialize_sound(int rate, int samples); + uint16_t* create_sound(int* extra_frames); + int get_sound_buffer_ptr(); +#ifdef USE_SOUND_VOLUME + void set_sound_device_volume(int ch, int decibel_l, int decibel_r); +#endif + + // user interface + void open_cart(int drv, const _TCHAR* file_path); + void close_cart(int drv); + bool is_cart_inserted(int drv); + + // notify key + void key_down(int code, bool repeat); + void key_up(int code); + + bool is_frame_skippable(); + + void update_config(); + bool process_state(FILEIO* state_fio, bool loading); + + // ---------------------------------------- + // for each device + // ---------------------------------------- + + // devices + DEVICE* get_device(int id); +// DEVICE* dummy; +// DEVICE* first_device; +// DEVICE* last_device; +}; + +#endif diff --git a/source/src/vm/upd16434.h b/source/src/vm/upd16434.h index feab42ce5..378806311 100644 --- a/source/src/vm/upd16434.h +++ b/source/src/vm/upd16434.h @@ -15,9 +15,7 @@ //#include "../emu.h" #include "device.h" -class VM; -class EMU; -class UPD16434 : public DEVICE +class DLL_PREFIX UPD16434 : public DEVICE { private: uint8_t pointer; @@ -30,7 +28,7 @@ class UPD16434 : public DEVICE void update_pointer(uint8_t mode); public: - UPD16434(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + UPD16434(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("uPD16434 LCD Controller")); } ~UPD16434() {} diff --git a/source/src/vm/upd1990a.h b/source/src/vm/upd1990a.h index 8deadc210..016600056 100644 --- a/source/src/vm/upd1990a.h +++ b/source/src/vm/upd1990a.h @@ -22,7 +22,7 @@ //#include "../emu.h" #include "device.h" -class UPD1990A : public DEVICE +class DLL_PREFIX UPD1990A : public DEVICE { private: // output signals @@ -44,7 +44,7 @@ class UPD1990A : public DEVICE //#endif bool __HAS_UPD4990A; public: - UPD1990A(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD1990A(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_dout); initialize_output_signals(&outputs_tp); @@ -71,7 +71,7 @@ class UPD1990A : public DEVICE { return dout; } - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions void set_context_dout(DEVICE* device, int id, uint32_t mask) diff --git a/source/src/vm/upd4991a.h b/source/src/vm/upd4991a.h index f6aac6723..9968dc59b 100644 --- a/source/src/vm/upd4991a.h +++ b/source/src/vm/upd4991a.h @@ -14,9 +14,7 @@ //#include "../emu.h" #include "device.h" -class VM; -class EMU; -class UPD4991A : public DEVICE +class DLL_PREFIX UPD4991A : public DEVICE { private: dll_cur_time_t cur_time; @@ -29,7 +27,7 @@ class UPD4991A : public DEVICE void __FASTCALL write_to_cur_time(); public: - UPD4991A(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + UPD4991A(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("uPD4991A RTC")); } ~UPD4991A() {} @@ -38,7 +36,7 @@ class UPD4991A : public DEVICE void initialize(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); }; diff --git a/source/src/vm/upd71071.cpp b/source/src/vm/upd71071.cpp index 547861344..f65f62d65 100644 --- a/source/src/vm/upd71071.cpp +++ b/source/src/vm/upd71071.cpp @@ -26,32 +26,77 @@ void UPD71071::initialize() d_debugger->set_context_io(vm->dummy); } } + for(int i = 0; i < 4; i++) { + inputs_ube[i] = false; // This is input, maybe not initialize at reset(). + } } void UPD71071::reset() { for(int i = 0; i < 4; i++) { dma[i].mode = 0x04; + dma[i].is_16bit = false; + dma[i].end = false; + dma[i].endreq = false; + reset_ube(i); } b16 = selch = base = 0; cmd = tmp = 0; - req = sreq = tc = 0; + req = sreq = 0; mask = 0x0f; +// mask = 0x00; + reset_all_tc(); +} + +void UPD71071::reset_all_tc() +{ + for(int i = 0; i < 4; i++) { + tc = 0; + write_signals(&(outputs_tc[i]), 0); + } +} + +void UPD71071::reset_tc(int ch) +{ + if((ch < 0) || (ch > 3)) return; + uint8_t bit = (1 << ch); + uint8_t tc_bak = tc; + tc &= ~bit; + /*if(tc != tc_bak) */ write_signals(&(outputs_tc[ch]), 0); +} + +void UPD71071::set_tc(int ch) +{ + if((ch < 0) || (ch > 3)) return; + uint8_t bit = (1 << ch); + uint8_t tc_bak = tc; + tc |= bit; + /*if(tc != tc_bak) */write_signals(&(outputs_tc[ch]), 0xffffffff); } void UPD71071::write_io8(uint32_t addr, uint32_t data) { + pair32_t _d; + pair32_t _bd; + _d.d = 0; + _bd.d = 0; switch(addr & 0x0f) { case 0x00: if(data & 1) { // dma reset for(int i = 0; i < 4; i++) { dma[i].mode = 0x04; + dma[i].is_16bit = false; + dma[i].end = false; + dma[i].endreq = false; + reset_ube(i); } selch = base = 0; cmd = tmp = 0; - sreq = tc = 0; + sreq = 0; mask = 0x0f; +// mask = 0x00; + reset_all_tc(); } b16 = data & 2; break; @@ -60,34 +105,50 @@ void UPD71071::write_io8(uint32_t addr, uint32_t data) base = data & 4; break; case 0x02: - dma[selch].bcreg = (dma[selch].bcreg & 0xff00) | data; -// if(!base) { - dma[selch].creg = (dma[selch].creg & 0xff00) | data; -// } - break; case 0x03: - dma[selch].bcreg = (dma[selch].bcreg & 0x00ff) | (data << 8); -// if(!base) { - dma[selch].creg = (dma[selch].creg & 0x00ff) | (data << 8); -// } + _d.w.l = dma[selch].creg; + _bd.w.l = dma[selch].bcreg; + switch(addr & 0x0f) { + case 0x02: + _d.b.l = data; + _bd.b.l = data; + break; + case 0x03: + _d.b.h = data; + _bd.b.h = data; + break; + } + if(base == 0) { + dma[selch].creg = _d.w.l; + } + dma[selch].bcreg = _bd.w.l; + dma[selch].end = false; // OK? + dma[selch].endreq = false; // OK? + reset_tc(selch); break; case 0x04: - dma[selch].bareg = (dma[selch].bareg & 0xffff00) | data; -// if(!base) { - dma[selch].areg = (dma[selch].areg & 0xffff00) | data; -// } - break; case 0x05: - dma[selch].bareg = (dma[selch].bareg & 0xff00ff) | (data << 8); -// if(!base) { - dma[selch].areg = (dma[selch].areg & 0xff00ff) | (data << 8); -// } - break; case 0x06: - dma[selch].bareg = (dma[selch].bareg & 0x00ffff) | (data << 16); -// if(!base) { - dma[selch].areg = (dma[selch].areg & 0x00ffff) | (data << 16); -// } + _d.d = dma[selch].areg; + _bd.d = dma[selch].bareg; + switch(addr & 0x0f) { + case 0x04: + _d.b.l = data; + _bd.b.l = data; + break; + case 0x05: + _d.b.h = data; + _bd.b.h = data; + break; + case 0x06: + _d.b.h2 = data; + _bd.b.h2 = data; + break; + } + if(base == 0) { + dma[selch].areg = _d.d; + } + dma[selch].bareg = _bd.d; break; case 0x08: cmd = (cmd & 0xff00) | data; @@ -97,16 +158,33 @@ void UPD71071::write_io8(uint32_t addr, uint32_t data) break; case 0x0a: dma[selch].mode = data; + dma[selch].is_16bit = ((data & 1) != 0) ? true : false; + if((data & 0x04) == 0) { + dma[selch].end = false; + dma[selch].endreq = false; + } + set_ube(selch); break; case 0x0e: - if(((sreq = data) != 0) && !(_SINGLE_MODE_DMA)) { -//#ifndef SINGLE_MODE_DMA - do_dma(); -//#endif + sreq = data; + for(int _ch = 0; _ch < 4; _ch++) { + if((sreq & (1 << _ch)) != 0) { + //if((dma[_ch].mode & 0xc0) == 0x40) { // Single + do_dma_per_channel(_ch); + //} + } } break; case 0x0f: mask = data; + for(int _ch = 0; _ch < 4; _ch++) { + if(((sreq | req) & (1 << _ch)) != 0) { + if((mask & (1 << _ch)) == 0) { + do_dma_per_channel(_ch); + } + } + } + set_ube(selch); break; } } @@ -114,11 +192,15 @@ void UPD71071::write_io8(uint32_t addr, uint32_t data) uint32_t UPD71071::read_io8(uint32_t addr) { uint32_t val; - +// pair32_t _d; +// pair32_t _bd; +// _d.d = 0; +// _bd.d = 0; switch(addr & 0x0f) { case 0x00: return b16; case 0x01: + // Q: Should be right BIT shift of BASE bit? 20200315 K.O return (base << 2) | (1 << selch); case 0x02: if(base) { @@ -158,7 +240,7 @@ uint32_t UPD71071::read_io8(uint32_t addr) return dma[selch].mode; case 0x0b: val = (req << 4) | tc; - tc = 0; + reset_all_tc(); return val; case 0x0c: return tmp & 0xff; @@ -172,19 +254,61 @@ uint32_t UPD71071::read_io8(uint32_t addr) return 0xff; } -void UPD71071::write_signal(int id, uint32_t data, uint32_t mask) +void UPD71071::write_signal(int id, uint32_t data, uint32_t _mask) { - uint8_t bit = 1 << (id & 3); - - if(data & mask) { - if(!(req & bit)) { - req |= bit; -//#ifndef SINGLE_MODE_DMA - if(!_SINGLE_MODE_DMA) do_dma(); -//#endif + int ch = id & 3; + uint8_t bit = 1 << ch; + if((id >= SIG_UPD71071_CH0) && (id <= SIG_UPD71071_CH3)) { +// out_debug_log(_T("DRQ#%d %s"), ch, ((data & _mask) != 0) ? _T("ON ") : _T("OFF")); + if(data & _mask) { + if(!(req & bit)) { + req |= bit; + if(!(_SINGLE_MODE_DMA)) { + if((mask & (1 << ch)) == 0) { // MASK register MASKS DRQ.20200918 K.O + // Without #define SINGLE_MODE_DMA , + // DMA trasfer is triggerd by SIGNAL or writing I/O 0Eh. + do_dma_per_channel(ch); + req &= ~bit; + } + } + } + } else { + req &= ~bit; } - } else { - req &= ~bit; + } else if((id >= SIG_UPD71071_UBE_CH0) && (id <= SIG_UPD71071_UBE_CH3)) { + inputs_ube[ch] = ((data & _mask) != 0) ? true : false; + } else if((id >= SIG_UPD71071_EOT_CH0) && (id <= SIG_UPD71071_EOT_CH3)) { + if((cmd & 0x04) == 0) { + switch(dma[ch].mode & 0xc0) { + case 0x00: // Demand + dma[ch].endreq = true; + break; + case 0x40: // Single -> Noop + break; + case 0x80: // Demand + dma[ch].endreq = true; + break; + default: + break; + } + } + } +} + +void UPD71071::set_ube(int ch) +{ + bool stat = inputs_ube[ch & 3]; + stat &= dma[ch & 3].is_16bit; + if(stats_ube[ch & 3] != stat) { + write_signals(&outputs_ube[ch & 3], (stat) ? 0xffffffff : 0x00000000); + stats_ube[ch & 3] = stat; + } +} +void UPD71071::reset_ube(int ch) +{ + if(stats_ube[ch &3]) { + write_signals(&outputs_ube[ch & 3], 0x00000000); + stats_ube[ch & 3] = false; } } @@ -213,17 +337,269 @@ uint32_t UPD71071::read_via_debugger_data16(uint32_t addr) uint32_t UPD71071::read_signal(int ch) { if((ch >= (SIG_UPD71071_IS_TRANSFERING + 0)) && (ch < (SIG_UPD71071_IS_TRANSFERING + 4))) { - bool _nch = ch - SIG_UPD71071_IS_TRANSFERING; + int _nch = ch - SIG_UPD71071_IS_TRANSFERING; if((cmd & 0x04) != 0) return 0x00; // Not transfering - if((dma[_nch].creg == 0)) return 0x00; // + if((dma[_nch].creg == 0xffffffff)) return 0x00; // return 0xffffffff; } else if((ch >= (SIG_UPD71071_IS_16BITS_TRANSFER + 0)) && (ch < (SIG_UPD71071_IS_16BITS_TRANSFER + 4))) { - bool _nch = ch - SIG_UPD71071_IS_16BITS_TRANSFER; - return ((dma[_nch].mode & 1) != 0) ? 0xffffffff : 0; + int _nch = ch - SIG_UPD71071_IS_16BITS_TRANSFER; + bool stat = stats_ube[_nch]; + return (stat) ? 0xffffffff : 0; + } else if((ch >= SIG_UPD71071_UBE_CH0) && (ch <= SIG_UPD71071_UBE_CH3)) { + return (inputs_ube[ch - SIG_UPD71071_UBE_CH0]) ? 0xffffffff : 0x00000000; + } else if((ch >= (SIG_UPD71071_CREG + 0)) && (ch < (SIG_UPD71071_CREG + 4))) { + return dma[ch - SIG_UPD71071_CREG].creg; + } else if((ch >= (SIG_UPD71071_BCREG + 0)) && (ch < (SIG_UPD71071_BCREG + 4))) { + return dma[ch - SIG_UPD71071_BCREG].creg; + } else if((ch >= (SIG_UPD71071_AREG + 0)) && (ch < (SIG_UPD71071_AREG + 4))) { + return dma[ch - SIG_UPD71071_AREG].creg; + } else if((ch >= (SIG_UPD71071_BAREG + 0)) && (ch < (SIG_UPD71071_BAREG + 4))) { + return dma[ch - SIG_UPD71071_BAREG].creg; } return 0; } - + +void UPD71071::do_dma_verify_8bit(int c) +{ + // verify + uint32_t val = dma[c].dev->read_dma_io8(0); + // update temporary register + reset_ube(c); + tmp = (tmp >> 8) | (val << 8); + +} +void UPD71071::do_dma_dev_to_mem_8bit(int c) +{ + // io -> memory + uint32_t val; + reset_ube(c); + val = dma[c].dev->read_dma_io8(0); + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data8(dma[c].areg, val); + } else { + write_via_debugger_data8(dma[c].areg, val); + } + } else { + write_via_debugger_data8(dma[c].areg, val); + } + // update temporary register + tmp = (tmp >> 8) | (val << 8); + +} + +void UPD71071::do_dma_mem_to_dev_8bit(int c) +{ + // memory -> io + uint32_t val; + reset_ube(c); + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + val = d_debugger->read_via_debugger_data8(dma[c].areg); + } else { + val = read_via_debugger_data8(dma[c].areg); + } + } else { + val = read_via_debugger_data8(dma[c].areg); + } + dma[c].dev->write_dma_io8(0, val); + // update temporary register + tmp = (tmp >> 8) | (val << 8); +} + +void UPD71071::do_dma_inc_dec_ptr_8bit(int c) +{ + // Note: FM-Towns may extend to 32bit. + if(dma[c].mode & 0x20) { + dma[c].areg = (dma[c].areg - 1) & 0xffffff; + } else { + dma[c].areg = (dma[c].areg + 1) & 0xffffff; + } +} + +void UPD71071::do_dma_verify_16bit(int c) +{ + // verify + uint32_t val = dma[c].dev->read_dma_io16(0); + set_ube(c); + // update temporary register + tmp = val; + +} +void UPD71071::do_dma_dev_to_mem_16bit(int c) +{ + // io -> memory + uint32_t val; + set_ube(c); + val = dma[c].dev->read_dma_io16(0); + if((dma[c].areg & 1) != 0) { + // If odd address, write a byte. + uint32_t tval = (val >> 8) & 0xff; + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data8(dma[c].areg, tval); + } else { + this->write_via_debugger_data8(dma[c].areg, tval); + } + } else { + this->write_via_debugger_data8(dma[c].areg, tval); + } + } else { + // 16bit + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + d_debugger->write_via_debugger_data16(dma[c].areg, val); + } else { + this->write_via_debugger_data16(dma[c].areg, val); + } + } else { + this->write_via_debugger_data16(dma[c].areg, val); + } + } + // update temporary register + tmp = val; +} + +void UPD71071::do_dma_mem_to_dev_16bit(int c) +{ + // memory -> io + uint32_t val; + set_ube(c); + if(_USE_DEBUGGER) { + if(d_debugger != NULL && d_debugger->now_device_debugging) { + val = d_debugger->read_via_debugger_data16(dma[c].areg); + } else { + val = this->read_via_debugger_data16(dma[c].areg); + } + } else { + val = this->read_via_debugger_data16(dma[c].areg); + } + if((dma[c].areg & 1) != 0) { + // If odd address, read a high byte. + val = (val >> 8) & 0xff; + } + dma[c].dev->write_dma_io16(0, val); + // update temporary register + tmp = val; +} + +void UPD71071::do_dma_inc_dec_ptr_16bit(int c) +{ + // Note: FM-Towns may extend to 32bit. + if(dma[c].mode & 0x20) { + dma[c].areg = (dma[c].areg - 2) & 0xffffff; + } else { + dma[c].areg = (dma[c].areg + 2) & 0xffffff; + } +} + +bool UPD71071::do_dma_epilogue(int c) +{ + uint8_t bit = 1 << c; +// if(dma[c].end) return true; // OK? + if((dma[c].creg == 0) || ((dma[c].endreq) && !(dma[c].end) && ((dma[c].mode & 0xc0) != 0x40))) { // OK? + if(dma[c].endreq) dma[c].end = true; + bool is_tc = false; + dma[c].creg--; + if(dma[c].end) is_tc = true; + // TC + if(dma[c].bcreg < dma[c].creg) { + is_tc = true; + } + if(dma[c].mode & 0x10) { + // auto initialize + dma[c].areg = dma[c].bareg; + dma[c].creg = dma[c].bcreg; + } else { + mask |= bit; + } + req &= ~bit; + sreq &= ~bit; + if(is_tc) { + set_tc(c); + } + if((dma[c].mode & 0xc0) == 0x40) { + // Single mode + return true; + } else { + return false; + } + } + dma[c].creg--; + // Note: At FM-Towns, SCSI's DMAC will be set after + // SCSI bus phase become DATA IN/DATA OUT. + // Before bus phase became DATA IN/DATA OUT, + // DMAC mode and state was unstable (and ASSERTED + // DRQ came from SCSI before this state change). + // ToDo: Stop correctly before setting. + // -- 20200316 K.O + if((dma[c].mode & 0xc0) == 0x40){ + // single mode + req &= ~bit; + sreq &= ~bit; + return true; + } else if((dma[c].mode & 0xc0) == 0x00){ + // demand mode + req &= ~bit; + sreq &= ~bit; + return false; + } + return false; +} + +bool UPD71071::do_dma_per_channel(int c) +{ + if(cmd & 4) { + return true; + } + if(dma[c].end) { + if((dma[c].mode & 0xc0) != 0x40) { // Without Single + return true; + } + } + uint8_t bit = 1 << c; + if(((req | sreq) & bit) /*&& !(mask & bit)*/) { + // execute dma + { // SINGLE + // Will check WORD transfer mode for FM-Towns.(mode.bit0 = '1). + // Note: At FM-Towns, may set bit0 of mode register (B/W), + // but transferring per 8bit from/to SCSI HOST... + /// I wonder this... + // 2020-03-16 K.O + if((dma[c].is_16bit) && (inputs_ube[c]) && (b16)) { + // This channel transferr makes 16bit. + if((dma[c].mode & 0x0c) == 0x00) { + do_dma_verify_16bit(c); + } else if((dma[c].mode & 0x0c) == 0x04) { + do_dma_dev_to_mem_16bit(c); + } else if((dma[c].mode & 0x0c) == 0x08) { + do_dma_mem_to_dev_16bit(c); + } + if((dma[c].areg & 1) != 0) { + // If odd address, align next word to 2n. + do_dma_inc_dec_ptr_8bit(c); + } else { + do_dma_inc_dec_ptr_16bit(c); + } + } else { + // 8bit transfer mode + if((dma[c].mode & 0x0c) == 0x00) { + do_dma_verify_8bit(c); + } else if((dma[c].mode & 0x0c) == 0x04) { + do_dma_dev_to_mem_8bit(c); + } else if((dma[c].mode & 0x0c) == 0x08) { + do_dma_mem_to_dev_8bit(c); + } + do_dma_inc_dec_ptr_8bit(c); + } + if(do_dma_epilogue(c)) { +// //break; + return true; + } + } + } + return false; +} void UPD71071::do_dma() { // check DDMA @@ -233,143 +609,15 @@ void UPD71071::do_dma() // run dma for(int c = 0; c < 4; c++) { - uint8_t bit = 1 << c; - if(((req | sreq) & bit) && !(mask & bit)) { - // execute dma - while((req | sreq) & bit) { - // Will check WORD transfer mode for FM-Towns.(mode.bit0 = '1). - if((dma[c].mode & 0x01) == 1) { - // 8bit transfer mode - if((dma[c].mode & 0x0c) == 0x00) { - // verify - uint32_t val = dma[c].dev->read_dma_io16(0); - // update temporary register - tmp = val; - } else if((dma[c].mode & 0x0c) == 0x04) { - // io -> memory - uint32_t val; - val = dma[c].dev->read_dma_io16(0); - write_signals(&outputs_wrote_mem_word, dma[c].areg); - if(_USE_DEBUGGER) { - if(d_debugger != NULL && d_debugger->now_device_debugging) { - d_debugger->write_via_debugger_data16(dma[c].areg, val); - } else { - this->write_via_debugger_data16(dma[c].areg, val); - } - } else { - this->write_via_debugger_data16(dma[c].areg, val); - } - - // update temporary register - tmp = val; - } else if((dma[c].mode & 0x0c) == 0x08) { - // memory -> io - uint32_t val; - if(_USE_DEBUGGER) { - if(d_debugger != NULL && d_debugger->now_device_debugging) { - val = d_debugger->read_via_debugger_data16(dma[c].areg); - } else { - val = this->read_via_debugger_data16(dma[c].areg); - } - } else { - val = this->read_via_debugger_data16(dma[c].areg); - } - dma[c].dev->write_dma_io16(0, val); - // update temporary register - tmp = val; - } - if(dma[c].mode & 0x20) { - dma[c].areg = (dma[c].areg - 2) & 0xffffff; - } else { - dma[c].areg = (dma[c].areg + 2) & 0xffffff; - } - if(dma[c].creg-- == 0) { // OK? - // TC - if(dma[c].mode & 0x10) { - // auto initialize - dma[c].areg = dma[c].bareg; - dma[c].creg = dma[c].bcreg; - } else { - mask |= bit; - } - req &= ~bit; - sreq &= ~bit; - tc |= bit; - - write_signals(&outputs_tc, 0xffffffff); - } else if(_SINGLE_MODE_DMA) { - if((dma[c].mode & 0xc0) == 0x40) { - // single mode - break; - } - } - } else { - // 8bit transfer mode - if((dma[c].mode & 0x0c) == 0x00) { - // verify - uint32_t val = dma[c].dev->read_dma_io8(0); - // update temporary register - tmp = (tmp >> 8) | (val << 8); - } else if((dma[c].mode & 0x0c) == 0x04) { - // io -> memory - uint32_t val; - val = dma[c].dev->read_dma_io8(0); - write_signals(&outputs_wrote_mem_byte, dma[c].areg); - if(_USE_DEBUGGER) { - if(d_debugger != NULL && d_debugger->now_device_debugging) { - d_debugger->write_via_debugger_data8(dma[c].areg, val); - } else { - this->write_via_debugger_data8(dma[c].areg, val); - } - } else { - this->write_via_debugger_data8(dma[c].areg, val); - } - // update temporary register - tmp = (tmp >> 8) | (val << 8); - } else if((dma[c].mode & 0x0c) == 0x08) { - // memory -> io - uint32_t val; - if(_USE_DEBUGGER) { - if(d_debugger != NULL && d_debugger->now_device_debugging) { - val = d_debugger->read_via_debugger_data8(dma[c].areg); - } else { - val = this->read_via_debugger_data8(dma[c].areg); - } - } else { - val = this->read_via_debugger_data8(dma[c].areg); - } - dma[c].dev->write_dma_io8(0, val); - // update temporary register - tmp = (tmp >> 8) | (val << 8); - } - if(dma[c].mode & 0x20) { - dma[c].areg = (dma[c].areg - 1) & 0xffffff; - } else { - dma[c].areg = (dma[c].areg + 1) & 0xffffff; - } - } - if(dma[c].creg-- == 0) { - // TC - if(dma[c].mode & 0x10) { - // auto initialize - dma[c].areg = dma[c].bareg; - dma[c].creg = dma[c].bcreg; - } else { - mask |= bit; - } - req &= ~bit; - sreq &= ~bit; - tc |= bit; - - write_signals(&outputs_tc, 0xffffffff); -//#ifdef SINGLE_MODE_DMA - } else if(_SINGLE_MODE_DMA) { - if((dma[c].mode & 0xc0) == 0x40) { - // single mode - break; - } -//#endif + if((mask & (1 << c)) == 0) { // MASK + if((dma[c].mode & 0xc0) == 0x00) { // Demand + if(!(dma[c].end)) { + do_dma_per_channel(c); } + } else if((dma[c].mode & 0xc0) == 0x40) { // Single + if(do_dma_per_channel(c)) break; + } else if((dma[c].mode & 0xc0) == 0xc0) { // Block (ToDo) + if(do_dma_per_channel(c)) break; } } } @@ -394,10 +642,16 @@ CH3 AREG=FFFF CREG=FFFF BAREG=FFFF BCREG=FFFF REQ=1 MASK=1 MODE=FF INVALID _T("VERIFY"), _T("I/O->MEM"), _T("MEM->I/O"), _T("INVALID") }; my_stprintf_s(buffer, buffer_len, + _T("16Bit=%s\n") + _T("SELECT CH=%d BASE=%02X REQ=%02X SREQ=%02X MASK=%02X TC=%02X ") + _T("CMD=%04X TMP=%04X\n") _T("CH0 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n") _T("CH1 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n") _T("CH2 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n") _T("CH3 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s"), + (b16) ? _T("YES") : _T("NO"), + selch, base, req, sreq, mask, tc, + cmd, tmp, dma[0].areg, dma[0].creg, dma[0].bareg, dma[0].bcreg, ((req | sreq) >> 0) & 1, (mask >> 0) & 1, dma[0].mode, dir[(dma[0].mode >> 2) & 3], dma[1].areg, dma[1].creg, dma[1].bareg, dma[1].bcreg, ((req | sreq) >> 1) & 1, (mask >> 1) & 1, dma[1].mode, dir[(dma[1].mode >> 2) & 3], dma[2].areg, dma[2].creg, dma[2].bareg, dma[2].bcreg, ((req | sreq) >> 2) & 1, (mask >> 2) & 1, dma[2].mode, dir[(dma[2].mode >> 2) & 3], @@ -405,7 +659,7 @@ CH3 AREG=FFFF CREG=FFFF BAREG=FFFF BCREG=FFFF REQ=1 MASK=1 MODE=FF INVALID return true; } -#define STATE_VERSION 1 +#define STATE_VERSION 4 bool UPD71071::process_state(FILEIO* state_fio, bool loading) { @@ -421,6 +675,9 @@ bool UPD71071::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(dma[i].creg); state_fio->StateValue(dma[i].bcreg); state_fio->StateValue(dma[i].mode); + state_fio->StateValue(dma[i].is_16bit); + state_fio->StateValue(dma[i].endreq); + state_fio->StateValue(dma[i].end); } state_fio->StateValue(b16); state_fio->StateValue(selch); @@ -431,6 +688,9 @@ bool UPD71071::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(sreq); state_fio->StateValue(mask); state_fio->StateValue(tc); + state_fio->StateArray(inputs_ube, sizeof(inputs_ube), 1); + state_fio->StateArray(stats_ube, sizeof(stats_ube), 1); + return true; } diff --git a/source/src/vm/upd71071.h b/source/src/vm/upd71071.h index 4b8b0fb0d..9dcd4fd58 100644 --- a/source/src/vm/upd71071.h +++ b/source/src/vm/upd71071.h @@ -14,41 +14,76 @@ //#include "../emu.h" #include "device.h" -#define SIG_UPD71071_CH0 0 -#define SIG_UPD71071_CH1 1 -#define SIG_UPD71071_CH2 2 -#define SIG_UPD71071_CH3 3 -#define SIG_UPD71071_IS_TRANSFERING 4 /* 4 - 7 */ -#define SIG_UPD71071_IS_16BITS_TRANSFER 8 /* 8 - 11 */ +#define SIG_UPD71071_CH0 0 +#define SIG_UPD71071_CH1 1 +#define SIG_UPD71071_CH2 2 +#define SIG_UPD71071_CH3 3 + /* UBE: INDICATE TARGET DEVICE HAS 16bit capability YES=1 NO=0*/ +#define SIG_UPD71071_UBE_CH0 4 +#define SIG_UPD71071_UBE_CH1 5 +#define SIG_UPD71071_UBE_CH2 6 +#define SIG_UPD71071_UBE_CH3 7 +#define SIG_UPD71071_EOT_CH0 8 +#define SIG_UPD71071_EOT_CH1 9 +#define SIG_UPD71071_EOT_CH2 10 +#define SIG_UPD71071_EOT_CH3 11 +#define SIG_UPD71071_IS_TRANSFERING 16 /* 16 - 19 */ +#define SIG_UPD71071_IS_16BITS_TRANSFER 20 /* 20 - 23 */ +#define SIG_UPD71071_CREG 24 /* 24 - 27 */ +#define SIG_UPD71071_BCREG 28 /* 28 - 31 */ +#define SIG_UPD71071_AREG 32 /* 32 - 35 */ +#define SIG_UPD71071_BAREG 36 /* 36 - 39 */ class DEBUGGER; -class UPD71071 : public DEVICE +class DLL_PREFIX UPD71071 : public DEVICE { -private: +protected: DEVICE* d_mem; //#ifdef SINGLE_MODE_DMA DEVICE* d_dma; //#endif DEBUGGER *d_debugger; - outputs_t outputs_tc; - outputs_t outputs_wrote_mem_byte; - outputs_t outputs_wrote_mem_word; + outputs_t outputs_tc[4]; + outputs_t outputs_ube[4]; // If "1" word transfer, "0" byte transfer (OUT) struct { DEVICE* dev; uint32_t areg, bareg; - uint16_t creg, bcreg; + uint32_t creg, bcreg; // 20200318 K.O (Temporally workaround for Towns) uint8_t mode; + bool is_16bit; + bool endreq; + bool end; } dma[4]; uint8_t b16, selch, base; uint16_t cmd, tmp; uint8_t req, sreq, mask, tc; + bool inputs_ube[4]; + bool stats_ube[4]; + bool _SINGLE_MODE_DMA; bool _USE_DEBUGGER; + + virtual void __FASTCALL set_ube(int ch); + virtual void __FASTCALL reset_ube(int ch); + virtual void __FASTCALL do_dma_verify_8bit(int c); + virtual void __FASTCALL do_dma_dev_to_mem_8bit(int c); + virtual void __FASTCALL do_dma_mem_to_dev_8bit(int c); + virtual void __FASTCALL do_dma_inc_dec_ptr_8bit(int c); + virtual void __FASTCALL do_dma_verify_16bit(int c); + virtual void __FASTCALL do_dma_dev_to_mem_16bit(int c); + virtual void __FASTCALL do_dma_mem_to_dev_16bit(int c); + virtual void __FASTCALL do_dma_inc_dec_ptr_16bit(int c); + virtual bool __FASTCALL do_dma_epilogue(int c); + virtual bool __FASTCALL do_dma_per_channel(int c); + virtual void __FASTCALL reset_tc(int ch); + virtual void __FASTCALL set_tc(int ch); + virtual void reset_all_tc(); + public: - UPD71071(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD71071(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { // TIP: if((DEVICE::prev_device == NULL) || (DEVICE::this_device_id == 0)) DEVICE must be DUMMY. // And, at this device, should not be FIRST DEVICE. 20170613 Ohta. @@ -67,26 +102,27 @@ class UPD71071 : public DEVICE d_debugger = NULL; _SINGLE_MODE_DMA = false; _USE_DEBUGGER = false; - initialize_output_signals(&outputs_tc); - initialize_output_signals(&outputs_wrote_mem_word); - initialize_output_signals(&outputs_wrote_mem_byte); + for(int i = 0; i < 4; i++) { + initialize_output_signals(&outputs_tc[i]); + initialize_output_signals(&outputs_ube[i]); + } set_device_name(_T("uPD71071 DMAC")); } ~UPD71071() {} // common functions - void initialize(); - void reset(); - void __FASTCALL write_io8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_io8(uint32_t addr); - void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - uint32_t __FASTCALL read_signal(int id); - void __FASTCALL do_dma(); + virtual void initialize(); + virtual void reset(); + virtual void __FASTCALL write_io8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_io8(uint32_t addr); + virtual void __FASTCALL write_signal(int id, uint32_t data, uint32_t _mask); + virtual uint32_t __FASTCALL read_signal(int id); + virtual void __FASTCALL do_dma(); // for debug - void __FASTCALL write_via_debugger_data8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_via_debugger_data8(uint32_t addr); - void __FASTCALL write_via_debugger_data16(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_via_debugger_data16(uint32_t addr); + virtual void __FASTCALL write_via_debugger_data8(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_via_debugger_data8(uint32_t addr); + virtual void __FASTCALL write_via_debugger_data16(uint32_t addr, uint32_t data); + virtual uint32_t __FASTCALL read_via_debugger_data16(uint32_t addr); bool is_debugger_available() { return true; @@ -95,8 +131,8 @@ class UPD71071 : public DEVICE { return d_debugger; } - bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); - bool process_state(FILEIO* state_fio, bool loading); + virtual bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); + virtual bool process_state(FILEIO* state_fio, bool loading); // unique functions void set_context_memory(DEVICE* device) { @@ -128,14 +164,37 @@ class UPD71071 : public DEVICE { d_debugger = device; } - void set_context_tc(DEVICE* device, int id, uint32_t mask) + void set_context_tc0(DEVICE* device, int id, uint32_t _mask) + { + register_output_signal(&outputs_tc[0], device, id, _mask); + } + void set_context_tc1(DEVICE* device, int id, uint32_t _mask) + { + register_output_signal(&outputs_tc[1], device, id, _mask); + } + void set_context_tc2(DEVICE* device, int id, uint32_t _mask) + { + register_output_signal(&outputs_tc[2], device, id, _mask); + } + void set_context_tc3(DEVICE* device, int id, uint32_t _mask) + { + register_output_signal(&outputs_tc[3], device, id, _mask); + } + void set_context_ube0(DEVICE* device, int id, uint32_t _mask) + { + register_output_signal(&outputs_ube[0], device, id, _mask); + } + void set_context_ube1(DEVICE* device, int id, uint32_t _mask) + { + register_output_signal(&outputs_ube[1], device, id, _mask); + } + void set_context_ube2(DEVICE* device, int id, uint32_t _mask) { - register_output_signal(&outputs_tc, device, id, mask); + register_output_signal(&outputs_ube[2], device, id, _mask); } - void set_context_wrote_mem(DEVICE* device, int id) + void set_context_ube3(DEVICE* device, int id, uint32_t _mask) { - register_output_signal(&outputs_wrote_mem_byte, device, id, 1); - register_output_signal(&outputs_wrote_mem_word, device, id, 2); + register_output_signal(&outputs_ube[3], device, id, _mask); } }; diff --git a/source/src/vm/upd7220.cpp b/source/src/vm/upd7220.cpp index 2b539dafb..faadef4d8 100644 --- a/source/src/vm/upd7220.cpp +++ b/source/src/vm/upd7220.cpp @@ -10,7 +10,7 @@ #include #include "upd7220.h" -#include "../ringbuffer.h" +#include "../fifo.h" #define EVENT_HSYNC_HFP 0 #define EVENT_HSYNC_HS 1 @@ -18,44 +18,38 @@ #define EVENT_CMD_READY 3 enum { - CMD_RESET1 = 0x00, - CMD_RESET2 = 0x01, -// CMD_STOP2 = 0x05, // Define later -// CMD_START2 = 0x04, - CMD_RESET3 = 0x09, - - CMD_BCTRL = 0x0c, // 0C/0D - CMD_SYNC = 0x0e, // 0E/0F - - CMD_WRITE = 0x20, // 20-3F - CMD_DMAW = 0x24, - + CMD_RESET = 0x00, + CMD_SYNC_OFF = 0x0e, + CMD_SYNC_ON = 0x0f, + CMD_MASTER = 0x6f, + CMD_SLAVE = 0x6e, + + CMD_START_ = 0x6b, + CMD_START = 0x0d, + CMD_STOP_ = 0x05, + CMD_STOP = 0x0c, + CMD_ZOOM = 0x46, - CMD_PITCH = 0x47, + CMD_SCROLL = 0x70, CMD_CSRW = 0x49, - CMD_MASK = 0x4a, CMD_CSRFORM = 0x4b, + CMD_PITCH = 0x47, + CMD_LPEN = 0xc0, CMD_VECTW = 0x4c, - - CMD_TEXTE = 0x68, - CMD_START = 0x6b, CMD_VECTE = 0x6c, - CMD_SLAVE = 0x6e, - CMD_MASTER = 0x6f, - - CMD_SCROLL = 0x70, // 70-7F CMD_TEXTW = 0x78, - - CMD_READ = 0xa0, // A9-BF - CMD_DMAR = 0xa4, - - CMD_LPEN = 0xc0, + CMD_TEXTE = 0x68, CMD_CSRR = 0xe0, + CMD_MASK = 0x4a, + + CMD_WRITE = 0x20, + CMD_READ = 0xa0, + CMD_DMAR = 0xa4, + CMD_DMAW = 0x24, /* unknown command (3 params) */ CMD_UNK_5A = 0x5a, - CMD_STOP2 = 0x05, - CMD_START2 = 0x04, }; + enum { STAT_DRDY = 0x01, STAT_FULL = 0x02, @@ -67,6 +61,13 @@ enum { STAT_LPEN = 0x80, }; +static const int vectdir[16][4] = { + { 0, 1, 1, 0}, { 1, 1, 1,-1}, { 1, 0, 0,-1}, { 1,-1,-1,-1}, + { 0,-1,-1, 0}, {-1,-1,-1, 1}, {-1, 0, 0, 1}, {-1, 1, 1, 1}, + { 0, 1, 1, 1}, { 1, 1, 1, 0}, { 1, 0, 1,-1}, { 1,-1, 0,-1}, + { 0,-1,-1,-1}, {-1,-1,-1, 0}, {-1, 0,-1, 1}, {-1, 1, 0, 1} +}; + void UPD7220::initialize() { DEVICE::initialize(); @@ -76,15 +77,25 @@ void UPD7220::initialize() _LINES_PER_FRAME = 0; } _UPD7220_UGLY_PC98_HACK = osd->check_feature(_T("UPD7220_UGLY_PC98_HACK")); + for(int i = 0; i <= RT_TABLEMAX; i++) { + rt[i] = (int)((double)(1 << RT_MULBIT) * (1 - sqrt(1 - pow((0.70710678118654 * i) / RT_TABLEMAX, 2)))); + } + fo = new FIFO(0x10000); + hsync = hblank = false; + vsync = vblank = false; + master = false; + pitch = 40; // 640dot + event_cmdready = -1; + + // initial settings for 1st frame vtotal = 0; //LINES_PER_FRAME; v1 = v2 = v3 = 16; v4 = _LINES_PER_FRAME - v1 - v2 - v3; - if(osd->check_feature(_T("CHARS_PER_LINE"))) { - h4 = (int)(osd->get_feature_int_value(_T("CHARS_PER_LINE"))); + _CHARS_PER_LINE = (int)(osd->get_feature_int_value(_T("CHARS_PER_LINE"))); } else { - h4 = width; + _CHARS_PER_LINE = 0; } if(osd->check_feature(_T("UPD7220_HORIZ_FREQ"))) { _UPD7220_HORIZ_FREQ = (int)(osd->get_feature_int_value(_T("UPD7220_HORIZ_FREQ"))); @@ -105,29 +116,23 @@ void UPD7220::initialize() } __QC10 = osd->check_feature(_T("_QC10")); _UPD7220_MSB_FIRST = osd->check_feature(_T("UPD7220_MSB_FIRST")); + h1 = h2 = h3 = 8; + if(_CHARS_PER_LINE != 0) { + h4 = _CHARS_PER_LINE - v1 - v2 - v3; + } else { + h4 = width; + } sync_changed = false; - sync_mask = false; vs = hs = 0; - for(int i = 0; i <= RT_TABLEMAX; i++) { - rt[i] = (int)((double)(1 << RT_MULBIT) * (1 - sqrt(1 - pow((0.70710678118654 * i) / RT_TABLEMAX, 2)))); + +//#ifdef UPD7220_HORIZ_FREQ + if(_UPD7220_HORIZ_FREQ != 0) { + horiz_freq = 0; + next_horiz_freq = _UPD7220_HORIZ_FREQ; } - // Design manual p.104 "because FIFO is implemented as a ring buffer". - fo = new RINGBUFFER(0x10000); - cmd_fifo = new RINGBUFFER(32); // OK? +//#endif - vsync = vblank = false; - hsync = hblank = false; - master = false; - pitch = 40; // 640dot - - event_cmdready = -1; - wrote_bytes = 0; - cmd_drawing = false; - - first_load = true; - before_addr = 0xffffffff; - cache_val = 0; // register events register_frame_event(this); register_vline_event(this); @@ -137,8 +142,124 @@ void UPD7220::release() { fo->release(); delete fo; - cmd_fifo->release(); - delete cmd_fifo; +} + +void UPD7220::reset() +{ + cmd_reset(); +} + +void UPD7220::write_dma_io8(uint32_t addr, uint32_t data) +{ + // for dma access + switch(cmdreg & 0x18) { + case 0x00: // low and high + if(low_high) { + cmd_write_sub(ead * 2 + 1, data & maskh); + ead += dif; + } else { + cmd_write_sub(ead * 2 + 0, data & maskl); + } + low_high = !low_high; + break; + case 0x10: // low byte + cmd_write_sub(ead * 2 + 0, data & maskl); + ead += dif; + break; + case 0x18: // high byte + cmd_write_sub(ead * 2 + 1, data & maskh); + ead += dif; + break; + } +} + +uint32_t UPD7220::read_dma_io8(uint32_t addr) +{ + uint32_t val = 0xff; + + // for dma access + switch(cmdreg & 0x18) { + case 0x00: // low and high + if(low_high) { + val = read_vram(ead * 2 + 1); + ead += dif; + } else { + val = read_vram(ead * 2 + 0); + } + low_high = !low_high; + break; + case 0x10: // low byte + val = read_vram(ead * 2 + 0); + ead += dif; + break; + case 0x18: // high byte + val = read_vram(ead * 2 + 1); + ead += dif; + break; + } + return val; +} + +void UPD7220::write_io8(uint32_t addr, uint32_t data) +{ + switch(addr & 3) { + case 0: // set parameter +// this->out_debug_log(_T("\tPARAM = %2x\n"), data); + if(cmdreg != -1) { + if(params_count < 16) { + params[params_count++] = (uint8_t)(data & 0xff); + } + check_cmd(); + if(cmdreg == -1) { + params_count = 0; + } + } + break; + case 1: // process prev command if not finished + if(cmdreg != -1) { + process_cmd(); + } + // set new command + cmdreg = (uint8_t)(data & 0xff); +// this->out_debug_log(_T("CMDREG = %2x\n"), cmdreg); + params_count = 0; + check_cmd(); + break; + case 2: // set zoom + zoom = data; + break; + case 3: // light pen request + break; + } +} + +uint32_t UPD7220::read_io8(uint32_t addr) +{ + uint32_t val; + + switch(addr & 3) { + case 0: // status + val = statreg; + if(sync[5] & 0x80) { + val |= vblank ? STAT_BLANK : 0; + } else { + val |= hblank ? STAT_BLANK : 0; + } + val |= vsync ? STAT_VSYNC : 0; +// val |= (params_count == 0) ? STAT_EMPTY : 0; + val |= STAT_EMPTY; + val |= (params_count == 16) ? STAT_FULL : 0; + val |= fo->count() ? STAT_DRDY : 0; + // clear busy stat + statreg &= ~(STAT_DMA | STAT_DRAW); + return val; + case 1: // data + if(fo->count()) { + return fo->read(); + } + return 0xff; + } + return 0xff; } void UPD7220::event_pre_frame() @@ -160,14 +281,11 @@ void UPD7220::event_pre_frame() sync_changed = false; vs = hs = 0; vtotal = 0; - if(_UPD7220_HORIZ_FREQ != 0) { horiz_freq = 0; } - out_debug_log("HTOTAL=%d HFP=%d HS=%d HBP=%d C/R=%d\n", h1 + h2 + h3 + h4, h1, h2, h3, h4); - out_debug_log("VTOTAL=%d VFP=%d VS=%d VBP=%d L/F=%d\n", v1 + v2 + v3 + v4, v1, v2, v3, v4); } - if((master) || (sync_mask)) { + if(master) { if(vtotal != v1 + v2 + v3 + v4) { vtotal = v1 + v2 + v3 + v4; set_lines_per_frame(vtotal); @@ -175,60 +293,174 @@ void UPD7220::event_pre_frame() if(_UPD7220_HORIZ_FREQ != 0) { if(horiz_freq != next_horiz_freq && vtotal != 0) { horiz_freq = next_horiz_freq; - out_debug_log("Set lines to %d ,freq to %f \n", vtotal, (double)horiz_freq / (double)vtotal); set_frames_per_sec((double)horiz_freq / (double)vtotal); } } } } -void UPD7220::reset() +void UPD7220::update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) +{ + cpu_clocks = new_clocks; + frames_per_sec = new_frames_per_sec; // note: refer these params given from the event manager + lines_per_frame = new_lines_per_frame; // because this device may be slave gdc + + // update event clocks + vs = hs = 0; +} + +void UPD7220::event_frame() +{ + if(vs == 0) { + vfp = (int)((double)lines_per_frame * (double)(v1 ) / (double)(v1 + v2 + v3 + v4) + 0.5); + vs = (int)((double)lines_per_frame * (double)(v1 + v2 ) / (double)(v1 + v2 + v3 + v4) + 0.5); + vbp = (int)((double)lines_per_frame * (double)(v1 + v2 + v3) / (double)(v1 + v2 + v3 + v4) + 0.5); + hfp = (int)((double)cpu_clocks * (double)(h1 ) / frames_per_sec / (double)lines_per_frame / (double)(h1 + h2 + h3 + h4) + 0.5); + hs = (int)((double)cpu_clocks * (double)(h1 + h2 ) / frames_per_sec / (double)lines_per_frame / (double)(h1 + h2 + h3 + h4) + 0.5); + hbp = (int)((double)cpu_clocks * (double)(h1 + h2 + h3) / frames_per_sec / (double)lines_per_frame / (double)(h1 + h2 + h3 + h4) + 0.5); + } + if(++blink_cursor >= blink_rate * 4) { + blink_cursor = 0; + } + if(++blink_attr >= blink_rate * 2) { + blink_attr = 0; + } +} + +void UPD7220::event_vline(int v, int clock) +{ + if(v == 0) { + vblank = true; + } else if(v == vfp) { + write_signals(&outputs_vsync, 0xffffffff); + vsync = true; + } else if(v == vs) { + write_signals(&outputs_vsync, 0); + vsync = false; + } else if(v == vbp) { + vblank = false; + } + hblank = true; + register_event_by_clock(this, EVENT_HSYNC_HFP, hfp, false, NULL); + register_event_by_clock(this, EVENT_HSYNC_HS, hs, false, NULL); + register_event_by_clock(this, EVENT_HSYNC_HBP, hbp, false, NULL); +} + +void UPD7220::event_callback(int event_id, int err) +{ + if(event_id == EVENT_HSYNC_HFP) { + hsync = true; + } else if(event_id == EVENT_HSYNC_HS) { + hsync = false; + } else if(event_id == EVENT_HSYNC_HBP) { + hblank = false; + } else if(event_id == EVENT_CMD_READY) { + event_cmdready = -1; + cmd_drawing = false; + } +} + + +void UPD7220::register_event_wait_cmd(uint32_t bytes) { if(event_cmdready >= 0) cancel_event(this, event_cmdready); event_cmdready = -1; - cmd_reset(); + // BY uPD7220 GDC Design manual; Clock divided by 2 at internal logic. + double usec = (1.0e6 * 2.0 * (double)bytes) / (double)clock_freq; +// if(usec < 1.0) { +// cmd_drawing = false; +// } else { + register_event(this, EVENT_CMD_READY, usec, false, &event_cmdready); +// } } -void UPD7220::check_cmd() +void UPD7220::write_signal(int ch, uint32_t data, uint32_t mask) { - // check fifo buffer and process command if enough params in fifo - switch(cmdreg) { - case CMD_RESET1: - cmd_reset(); + switch(ch) { + case SIG_UPD7220_CLOCK_FREQ: + clock_freq = data; // Must be Hz. break; - case CMD_RESET2: - cmd_reset2(); + case SIG_UPD7220_EXT_VSYNC: + //ToDo:Implement this."0" makes reset some paramaters. break; - case CMD_RESET3: - cmd_reset3(); + } +} + +uint32_t UPD7220::read_signal(int ch) +{ + switch(ch) { + case SIG_UPD7220_CLOCK_FREQ: + return clock_freq; break; - case CMD_SYNC + 0: - case CMD_SYNC + 1: - //if(cmd_fifo->count() > 7) { - cmd_sync(); - //} + case SIG_UPD7220_WIDTH_BYTES: + return (width < 0) ? 0 : width; break; - case CMD_MASTER: - cmd_master(); + case SIG_UPD7220_HEIGHT: + return (height < 0) ? 0 : height; + break; + case SIG_UPD7220_PITCH: + return (pitch < 0) ? 0 : pitch; + break; + case SIG_UPD7220_DISP_WIDTH: + return (h4 < 0) ? 0 : h4; + break; + case SIG_UPD7220_DISP_HEIGHT: + return (v4 < 0) ? 0 : v4; + break; + } + return 0; +} + +uint32_t UPD7220::cursor_addr(uint32_t mask) +{ + if((cs[0] & 0x80) && ((cs[1] & 0x20) || (blink_cursor < blink_rate * 2))) { + return (ead << 1) & mask; + } + return -1; +} + +int UPD7220::cursor_top() +{ + return cs[1] & 0x1f; +} + +int UPD7220::cursor_bottom() +{ + return cs[2] >> 3; +} + +// command process + +void UPD7220::check_cmd() +{ + // check fifo buffer and process command if enough params in fifo + switch(cmdreg) { + case CMD_RESET: + cmd_reset(); + break; + case CMD_SYNC_OFF: + if(params_count > 7) { + cmd_sync(false); + } + break; + case CMD_SYNC_ON: + if(params_count > 7) { + cmd_sync(true); + } + break; + case CMD_MASTER: + cmd_master(); break; case CMD_SLAVE: cmd_slave(); break; + case CMD_START_: case CMD_START: cmd_start(); break; - case CMD_STOP2: + case CMD_STOP_: + case CMD_STOP: cmd_stop(); - sync_mask = true; - break; - case CMD_BCTRL + 0: - cmd_stop(); - sync_mask = false; - break; - case CMD_START2: - case CMD_BCTRL + 1: - cmd_start(); - sync_mask = true; break; case CMD_ZOOM: cmd_zoom(); @@ -261,27 +493,22 @@ void UPD7220::check_cmd() cmd_lpen(); break; case CMD_VECTW: - //if(cmd_fifo->count() > 10) { + if(params_count > 10) { cmd_vectw(); - //} + } break; case CMD_VECTE: - cmd_drawing = true; cmd_vecte(); if(cmdreg < 0) register_event_wait_cmd(wrote_bytes); // OK? break; case CMD_TEXTE: - cmd_drawing = true; cmd_texte(); if(cmdreg < 0) register_event_wait_cmd(wrote_bytes); // OK? break; case CMD_CSRW: - //if(cmd_fifo->count() > 2) { - cmd_csrw(); - //} + cmd_csrw(); break; case CMD_CSRR: - cmd_drawing = true; cmd_csrr(); register_event_wait_cmd(wrote_bytes); // OK? break; @@ -304,9 +531,7 @@ void UPD7220::check_cmd() case CMD_WRITE + 0x19: case CMD_WRITE + 0x1a: case CMD_WRITE + 0x1b: - cmd_drawing = true; cmd_write(); - register_event_wait_cmd(wrote_bytes); break; case CMD_READ + 0x00: case CMD_READ + 0x01: @@ -324,9 +549,7 @@ void UPD7220::check_cmd() case CMD_READ + 0x19: case CMD_READ + 0x1a: case CMD_READ + 0x1b: - cmd_drawing = true; cmd_read(); - register_event_wait_cmd(wrote_bytes); break; case CMD_DMAW + 0x00: case CMD_DMAW + 0x01: @@ -344,502 +567,103 @@ void UPD7220::check_cmd() case CMD_DMAW + 0x19: case CMD_DMAW + 0x1a: case CMD_DMAW + 0x1b: - // ToDo: Wait for DMA cycle cmd_dmaw(); break; case CMD_DMAR + 0x00: case CMD_DMAR + 0x01: case CMD_DMAR + 0x02: - case CMD_DMAR + 0x03: - case CMD_DMAR + 0x08: - case CMD_DMAR + 0x09: - case CMD_DMAR + 0x0a: - case CMD_DMAR + 0x0b: - case CMD_DMAR + 0x10: - case CMD_DMAR + 0x11: - case CMD_DMAR + 0x12: - case CMD_DMAR + 0x13: - case CMD_DMAR + 0x18: - case CMD_DMAR + 0x19: - case CMD_DMAR + 0x1a: - case CMD_DMAR + 0x1b: - cmd_dmar(); - break; - case CMD_UNK_5A: - cmd_drawing = true; - cmd_unk_5a(); - register_event_wait_cmd(wrote_bytes); // OK? - break; - } -} - -void UPD7220::process_cmd() -{ - switch(cmdreg) { - case CMD_RESET1: - cmd_reset(); - break; - case CMD_RESET2: - cmd_reset2(); - break; - case CMD_RESET3: - cmd_reset3(); - break; - case CMD_SYNC + 0: - case CMD_SYNC + 1: - cmd_sync(); - break; - case CMD_CSRFORM: - cmd_csrform(); - break; - case CMD_SCROLL + 0: - case CMD_SCROLL + 1: - case CMD_SCROLL + 2: - case CMD_SCROLL + 3: - case CMD_SCROLL + 4: - case CMD_SCROLL + 5: - case CMD_SCROLL + 6: - case CMD_SCROLL + 7: - case CMD_TEXTW + 0: - case CMD_TEXTW + 1: - case CMD_TEXTW + 2: - case CMD_TEXTW + 3: - case CMD_TEXTW + 4: - case CMD_TEXTW + 5: - case CMD_TEXTW + 6: - case CMD_TEXTW + 7: - cmd_scroll(); - break; - case CMD_VECTW: - cmd_vectw(); - update_vect(); - break; - case CMD_CSRW: - cmd_csrw(); - break; - case CMD_WRITE + 0x00: - case CMD_WRITE + 0x01: - case CMD_WRITE + 0x02: - case CMD_WRITE + 0x03: - case CMD_WRITE + 0x08: - case CMD_WRITE + 0x09: - case CMD_WRITE + 0x0a: - case CMD_WRITE + 0x0b: - case CMD_WRITE + 0x10: - case CMD_WRITE + 0x11: - case CMD_WRITE + 0x12: - case CMD_WRITE + 0x13: - case CMD_WRITE + 0x18: - case CMD_WRITE + 0x19: - case CMD_WRITE + 0x1a: - case CMD_WRITE + 0x1b: - if(cmd_write_done) { - //reset_vect(); - } - cmdreg = -1; - cmd_write_done = false; - break; - } -} - -void UPD7220::cmd_vecte() -{ - dx = ((ead % pitch) << 4) | (dad & 0x0f); - dy = ead / pitch; - wrote_bytes = 1; - - // execute command -// pattern = ra[8] | (ra[9] << 8); - if(!(vect[0] & 0x78)) { - pattern = ra[8] | (ra[9] << 8); - draw_pset(dx, dy); - } - if(vect[0] & 0x08) { - draw_vectl(); - } - if(vect[0] & 0x10) { - draw_vectt(); - } - if(vect[0] & 0x20) { - draw_vectc(); - } - if(vect[0] & 0x40) { - draw_vectr(); - } - reset_vect(); - statreg |= STAT_DRAW; - cmdreg = -1; -} - -void UPD7220::cmd_texte() -{ - if(_UPD7220_UGLY_PC98_HACK) { - dx = (((ead & 0x3fff)% pitch) << 4) | (dad & 0x0f); - dy = (ead & 0x3fff) / pitch; - } else { - dx = ((ead % pitch) << 4) | (dad & 0x0f); - dy = ead / pitch; - } - - wrote_bytes = 1; - // execute command - if(!(vect[0] & 0x78)) { - pattern = ra[8] | (ra[9] << 8); - draw_pset(dx, dy); - } - if(vect[0] & 0x08) { - draw_vectl(); - } - if(vect[0] & 0x10) { - draw_text(); - } - if(vect[0] & 0x20) { - draw_vectc(); - } - if(vect[0] & 0x40) { - draw_vectr(); - } - reset_vect(); - statreg |= STAT_DRAW; - cmdreg = -1; -} - -void UPD7220::cmd_pitch() -{ - if(!(cmd_fifo->empty())) { - wrote_bytes = 1; - uint8_t tmp = (uint8_t)(cmd_fifo->read() & 0xff); - if(_UPD7220_FIXED_PITCH == 0) { - pitch = ((sync[4] & 0x40) != 0) ? tmp + 256 : tmp; - } - cmdreg = -1; - } -} - -void UPD7220::draw_text() -{ - int dir2 = dir + (sl ? 8 : 0); - int vx1 = vectdir[dir2][0]; - int vy1 = vectdir[dir2][1]; - int vx2 = vectdir[dir2][2]; - int vy2 = vectdir[dir2][3]; - int sx = d; - int sy = dc + 1; - if(__QC10) { - if(dir == 0 && sy == 40) { - sy = 640; // ugly patch - } - } -// this->out_debug_log(_T("\tTEXT: dx=%d,dy=%d,sx=%d,sy=%d\n"), dx, dy, sx, sy); - int index = 15; - int ead_bak = ead; - int dad_bak = dad; - - while(sy--) { - int muly = zw + 1; - while(muly--) { - int cx = dx; - int cy = dy; - uint8_t bit = ra[index]; - int xrem = sx; - while(xrem--) { - pattern = (bit & 1) ? 0xffff : 0; - bit = (bit >> 1) | ((bit & 1) ? 0x80 : 0); - int mulx = zw + 1; - start_pset(); - while(mulx--) { - draw_pset(cx, cy); - cx += vx1; - cy += vy1; - } - finish_pset(); - } - dx += vx2; - dy += vy2; - } - index = ((index - 1) & 7) | 8; - } -// ead = ead_bak; -// dad = dad_bak; -// ead = (dx >> 4) + dy * pitch; -// dad = dx & 0x0f; -} - - -void UPD7220::write_dma_io8(uint32_t addr, uint32_t data) -{ - // for dma access - switch(cmdreg & 0x18) { - case 0x00: // low and high - if(low_high) { - cmd_write_sub(ead * 2 + 1, data & maskh); - ead += dif; - } else { - cmd_write_sub(ead * 2 + 0, data & maskl); - } - low_high = !low_high; - break; - case 0x10: // low byte - cmd_write_sub(ead * 2 + 0, data & maskl); - ead += dif; - break; - case 0x18: // high byte - cmd_write_sub(ead * 2 + 1, data & maskh); - ead += dif; - break; - } -} - -uint32_t UPD7220::read_dma_io8(uint32_t addr) -{ - uint32_t val = 0xff; - - // for dma access - switch(cmdreg & 0x18) { - case 0x00: // low and high - if(low_high) { - val = read_vram(ead * 2 + 1); - ead += dif; - } else { - val = read_vram(ead * 2 + 0); - } - low_high = !low_high; - break; - case 0x10: // low byte - val = read_vram(ead * 2 + 0); - ead += dif; - break; - case 0x18: // high byte - val = read_vram(ead * 2 + 1); - ead += dif; - break; - } - return val; -} - -void UPD7220::write_io8(uint32_t addr, uint32_t data) -{ - switch(addr & 3) { - case 0: // set parameter - //this->out_debug_log(_T("\tPARAM = %2x\n"), data); - //if(cmd_ready) { // OK? - if(cmdreg != -1) { - cmd_fifo->write(data & 0xff); - check_cmd(); - if(cmdreg == -1) { - cmd_fifo->clear(); // OK? - } - // } - } - break; - case 1: // process prev command if not finished - //if(cmd_ready) { - if(cmdreg != -1) { - process_cmd(); - } - // set new command - // reset pointers, then enqueue command. - cs_ptr = 0; - sync_ptr = 0; - vectw_ptr = 0; - csrw_ptr = 0; - cmdreg = (int)data & 0xff; - //this->out_debug_log(_T("CMDREG = %2x\n"), cmdreg); -// params_count = 0; - cmd_fifo->clear(); // OK? - check_cmd(); - if(cmdreg == -1) { -// cmd_fifo->clear(); // OK? - } -// } - break; - case 2: // set zoom - zoom = data; - break; - case 3: // light pen request - break; - } -} - -uint32_t UPD7220::read_io8(uint32_t addr) -{ - uint32_t val; - - switch(addr & 3) { - case 0: // status - val = statreg; - if(sync[5] & 0x80) { - val |= vblank ? STAT_BLANK : 0; - } else { - val |= hblank ? STAT_BLANK : 0; - } - val |= vsync ? STAT_VSYNC : 0; - val |= (cmd_drawing) ? STAT_DRAW : 0; - val |= (cmd_fifo->empty()) ? STAT_EMPTY : 0; - //val |= STAT_EMPTY; - val |= (cmd_fifo->full()) ? STAT_FULL : 0; - val |= (!(fo->empty())) ? STAT_DRDY : 0; - // clear busy stat - statreg &= ~(STAT_DMA | STAT_DRAW); - return val; - case 1: // data - if(!(fo->empty())) { - return fo->read(); - } - return 0xff; - } - return 0xff; -} - -void UPD7220::update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) -{ - cpu_clocks = new_clocks; - frames_per_sec = new_frames_per_sec; // note: refer these params given from the event manager - lines_per_frame = new_lines_per_frame; // because this device may be slave gdc - - // update event clocks - vs = hs = 0; -} - -void UPD7220::event_frame() -{ - if(vs == 0) { - vfp = (int)((double)lines_per_frame * (double)(v1 ) / (double)(v1 + v2 + v3 + v4) + 0.5); - vs = (int)((double)lines_per_frame * (double)(v1 + v2 ) / (double)(v1 + v2 + v3 + v4) + 0.5); - vbp = (int)((double)lines_per_frame * (double)(v1 + v2 + v3) / (double)(v1 + v2 + v3 + v4) + 0.5); - hfp = (int)((double)cpu_clocks * (double)(h1 ) / frames_per_sec / (double)lines_per_frame / (double)(h1 + h2 + h3 + h4) + 0.5); - hs = (int)((double)cpu_clocks * (double)(h1 + h2 ) / frames_per_sec / (double)lines_per_frame / (double)(h1 + h2 + h3 + h4) + 0.5); - hbp = (int)((double)cpu_clocks * (double)(h1 + h2 + h3) / frames_per_sec / (double)lines_per_frame / (double)(h1 + h2 + h3 + h4) + 0.5); - } - if(++blink_cursor >= blink_rate * 4) { - blink_cursor = 0; - } - if(++blink_attr >= blink_rate * 2) { - blink_attr = 0; - } -} - -void UPD7220::write_signal(int ch, uint32_t data, uint32_t mask) -{ - switch(ch) { - case SIG_UPD7220_CLOCK_FREQ: - clock_freq = data; // Must be Hz. - break; - case SIG_UPD7220_EXT_VSYNC: - //ToDo:Implement this."0" makes reset some paramaters. - break; - } -} - -uint32_t UPD7220::read_signal(int ch) -{ - switch(ch) { - case SIG_UPD7220_CLOCK_FREQ: - return clock_freq; - break; - case SIG_UPD7220_WIDTH_BYTES: - return (width < 0) ? 0 : width; - break; - case SIG_UPD7220_HEIGHT: - return (height < 0) ? 0 : height; - break; - case SIG_UPD7220_PITCH: - return (pitch < 0) ? 0 : pitch; - break; - case SIG_UPD7220_DISP_WIDTH: - return (h4 < 0) ? 0 : h4; - break; - case SIG_UPD7220_DISP_HEIGHT: - return (v4 < 0) ? 0 : v4; - break; - } - return 0; -} - - -void UPD7220::event_vline(int v, int clock) -{ - if(v == 0) { - vblank = true; - write_signals(&outputs_vblank, 0xffffffff); - } else if(v == vfp) { - write_signals(&outputs_vsync, 0xffffffff); - vsync = true; - } else if(v == vs) { - write_signals(&outputs_vsync, 0); - vsync = false; - } else if(v == vbp) { - vblank = false; - write_signals(&outputs_vblank, 0x00000000); - } - hblank = true; - register_event_by_clock(this, EVENT_HSYNC_HFP, hfp, false, NULL); - register_event_by_clock(this, EVENT_HSYNC_HS, hs, false, NULL); - register_event_by_clock(this, EVENT_HSYNC_HBP, hbp, false, NULL); -} - -void UPD7220::register_event_wait_cmd(uint32_t bytes) -{ - if(event_cmdready >= 0) cancel_event(this, event_cmdready); - event_cmdready = -1; - // BY uPD7220 GDC Design manual; Clock divided by 2 at internal logic. - double usec = (1.0e6 * 2.0 * (double)bytes) / (double)clock_freq; - if(usec < 1.0) { - cmd_drawing = false; - } else { - register_event(this, EVENT_CMD_READY, usec, false, &event_cmdready); - } -} - - -void UPD7220::event_callback(int event_id, int err) -{ - if(event_id == EVENT_HSYNC_HFP) { - hsync = true; - } else if(event_id == EVENT_HSYNC_HS) { - hsync = false; - } else if(event_id == EVENT_HSYNC_HBP) { - hblank = false; - } else if(event_id == EVENT_CMD_READY) { - event_cmdready = -1; - cmd_drawing = false; + case CMD_DMAR + 0x03: + case CMD_DMAR + 0x08: + case CMD_DMAR + 0x09: + case CMD_DMAR + 0x0a: + case CMD_DMAR + 0x0b: + case CMD_DMAR + 0x10: + case CMD_DMAR + 0x11: + case CMD_DMAR + 0x12: + case CMD_DMAR + 0x13: + case CMD_DMAR + 0x18: + case CMD_DMAR + 0x19: + case CMD_DMAR + 0x1a: + case CMD_DMAR + 0x1b: + cmd_dmar(); + break; + case CMD_UNK_5A: + cmd_unk_5a(); + break; } } -uint32_t UPD7220::cursor_addr(uint32_t mask) +void UPD7220::process_cmd() { - if((cs[0] & 0x80) && ((cs[1] & 0x20) || (blink_cursor < blink_rate * 2))) { - return (ead << 1) & mask; + switch(cmdreg) { + case CMD_RESET: + cmd_reset(); + break; + case CMD_SYNC_OFF: + cmd_sync(false); + break; + case CMD_SYNC_ON: + cmd_sync(true); + break; + case CMD_SCROLL + 0: + case CMD_SCROLL + 1: + case CMD_SCROLL + 2: + case CMD_SCROLL + 3: + case CMD_SCROLL + 4: + case CMD_SCROLL + 5: + case CMD_SCROLL + 6: + case CMD_SCROLL + 7: + case CMD_TEXTW + 0: + case CMD_TEXTW + 1: + case CMD_TEXTW + 2: + case CMD_TEXTW + 3: + case CMD_TEXTW + 4: + case CMD_TEXTW + 5: + case CMD_TEXTW + 6: + case CMD_TEXTW + 7: + cmd_scroll(); + break; + case CMD_VECTW: + cmd_vectw(); + break; + case CMD_CSRW: + cmd_csrw(); + break; + case CMD_WRITE + 0x00: + case CMD_WRITE + 0x01: + case CMD_WRITE + 0x02: + case CMD_WRITE + 0x03: + case CMD_WRITE + 0x08: + case CMD_WRITE + 0x09: + case CMD_WRITE + 0x0a: + case CMD_WRITE + 0x0b: + case CMD_WRITE + 0x10: + case CMD_WRITE + 0x11: + case CMD_WRITE + 0x12: + case CMD_WRITE + 0x13: + case CMD_WRITE + 0x18: + case CMD_WRITE + 0x19: + case CMD_WRITE + 0x1a: + case CMD_WRITE + 0x1b: + if(cmd_write_done) { + reset_vect(); + } + cmdreg = -1; + cmd_write_done = false; + break; } - return -1; -} - -int UPD7220::cursor_top() -{ - return cs[1] & 0x1f; -} - -int UPD7220::cursor_bottom() -{ - return cs[2] >> 3; } -// command process - void UPD7220::cmd_reset() { - finish_pset(); // init gdc params sync[6] = 0x90; sync[7] = 0x01; - sync_ptr = 0; zoom = zr = zw = 0; ra[0] = ra[1] = ra[2] = 0; ra[3] = 0x1e; /*0x19;*/ cs[0] = cs[1] = cs[2] = 0; - cs_ptr = 0; ead = dad = 0; - wg = false; maskl = maskh = 0xff; mod = 0; blink_cursor = 0; @@ -848,55 +672,34 @@ void UPD7220::cmd_reset() // init fifo cmd_drawing = false; + params_count = 0; fo->clear(); - cmd_fifo->clear(); // stop display and drawing start = false; statreg = 0; cmdreg = -1; cmd_write_done = false; - cmd_drawing = false; - sync_mask = false; +// sync_mask = false; + if(event_cmdready >= 0) cancel_event(this, event_cmdready); + event_cmdready = -1; + wrote_bytes = 0; + write_signals(&outputs_vsync, 0x00000000); write_signals(&outputs_vblank, 0xffffffff); } -void UPD7220::cmd_reset2() -{ - cmd_reset(); - if(_UPD7220_A_VERSION > 0) { - sync_mask = true; - } -} - -void UPD7220::cmd_reset3() -{ - cmd_reset(); - if(_UPD7220_A_VERSION > 0) { - sync_mask = true; - start = true; - } -} -void UPD7220::cmd_sync() +void UPD7220::cmd_sync(bool flag) { - start = ((cmdreg & 1) != 0); - int len = cmd_fifo->count(); - wrote_bytes = (len >= 8) ? 8 : len; - if(sync_ptr >= 8) sync_ptr = 0; - for(int i = 0; i < 8 && i < len; i++) { - uint8_t dat = (uint8_t)(cmd_fifo->read() & 0xff); - if(sync[sync_ptr] != dat) { - sync[sync_ptr] = dat; + wrote_bytes = (params_count > 8) ? 8 : params_count; + for(int i = 0; i < 8 && i < params_count; i++) { + if(sync[i] != params[i]) { + sync[i] = params[i]; sync_changed = true; } - sync_ptr++; - if(sync_ptr >= 8) { - sync_ptr = 0; - cmdreg = -1; - } } - //cmdreg = -1; + start = flag; + cmdreg = -1; } void UPD7220::cmd_master() @@ -914,7 +717,6 @@ void UPD7220::cmd_slave() void UPD7220::cmd_start() { start = true; - sync_mask = true; cmdreg = -1; } @@ -927,9 +729,9 @@ void UPD7220::cmd_stop() void UPD7220::cmd_zoom() { wrote_bytes = 0; - if(cmd_fifo->count() >= 1) { + if(params_count > 0) { wrote_bytes = 1; - uint8_t tmp = (uint8_t)(cmd_fifo->read() & 0xff); + uint8_t tmp = params[0]; zr = tmp >> 4; zw = tmp & 0x0f; cmdreg = -1; @@ -938,12 +740,12 @@ void UPD7220::cmd_zoom() void UPD7220::cmd_scroll() { - if(cmd_fifo->count() >= 1) { - ra[cmdreg & 0x0f] = (uint8_t)(cmd_fifo->read() & 0xff); + if(params_count > 0) { + ra[cmdreg & 0x0f] = params[0]; wrote_bytes = 1; if(cmdreg < 0x7f) { cmdreg++; - //cmd_fifo->clear(); // OK? + params_count = 0; } else { cmdreg = -1; } @@ -952,20 +754,26 @@ void UPD7220::cmd_scroll() void UPD7220::cmd_csrform() { - int len = cmd_fifo->count(); - if(len > 3) len = 3; - wrote_bytes = len; - cs_ptr = cs_ptr % 3; - for(int i = 0; i < len; i++) { - cs[cs_ptr++] = (uint8_t)(cmd_fifo->read() & 0xff); - if(cs_ptr > 2) { - cmdreg = -1; - cs_ptr = 0; - } + for(int i = 0; i < params_count; i++) { + cs[i] = params[i]; + } + if(params_count > 2) { + cmdreg = -1; } blink_rate = (cs[1] >> 6) | ((cs[2] & 7) << 2); } +void UPD7220::cmd_pitch() +{ + if(params_count > 0) { + wrote_bytes = 1; + if(!(_UPD7220_FIXED_PITCH)) { + pitch = params[0]; + } + cmdreg = -1; + } +} + void UPD7220::cmd_lpen() { wrote_bytes = 3; @@ -977,78 +785,95 @@ void UPD7220::cmd_lpen() void UPD7220::cmd_vectw() { - int len = cmd_fifo->count(); - if(len > 11) len = 11; - wrote_bytes += len; - for(int i = 0; i < 11 && i < len; i++) { - vect[vectw_ptr++] = (uint8_t)(cmd_fifo->read() & 0xff); - if(vectw_ptr >= 11) { - vectw_ptr = 0; - cmdreg = -1; - update_vect(); - break; - } + wrote_bytes += params_count; + for(int i = 0; i < 11 && i < params_count; i++) { + vect[i] = params[i]; // this->out_debug_log(_T("\tVECT[%d] = %2x\n"), i, vect[i]); } update_vect(); + cmdreg = -1; +} -// cmdreg = -1; +void UPD7220::cmd_vecte() +{ + cmd_drawing = true; + dx = ((ead % pitch) << 4) | (dad & 0x0f); + dy = (ead << 16) / pitch; + wrote_bytes = 1; + + // execute command + if(!(vect[0] & 0x78)) { // R, C, T, L + pattern = ra[8] | (ra[9] << 8); + draw_pset(dx, dy >> 16); + } + if(vect[0] & 0x08) { // L (Line) + draw_vectl(); + } + if(vect[0] & 0x10) { // T (Text) + draw_vectt(); + } + if(vect[0] & 0x20) { // C (Circle) + draw_vectc(); + } + if(vect[0] & 0x40) { // R (Rect) + draw_vectr(); + } + reset_vect(); + statreg |= STAT_DRAW; + cmdreg = -1; } +void UPD7220::cmd_texte() +{ + cmd_drawing = true; + dx = ((ead % pitch) << 4) | (dad & 0x0f); + dy = (ead << 16) / pitch; + wrote_bytes = 1; + + // execute command + if(!(vect[0] & 0x78)) { + pattern = ra[8] | (ra[9] << 8); + draw_pset(dx, dy >> 16); + } + if(vect[0] & 0x08) { + draw_vectl(); + } + if(vect[0] & 0x10) { + draw_text(); + } + if(vect[0] & 0x20) { + draw_vectc(); + } + if(vect[0] & 0x40) { + draw_vectr(); + } + reset_vect(); + statreg |= STAT_DRAW; + cmdreg = -1; +} void UPD7220::cmd_csrw() { -#if 0 - if(!(cmd_fifo->empty())) { - - ead = cmd_fifo->read() & 0xff; - wrote_bytes = 1; - if(!(cmd_fifo->empty())) { - ead |= (cmd_fifo->read() & 0xff) << 8; - wrote_bytes = 2; - if(!(cmd_fifo->empty())) { - ead |= (cmd_fifo->read() & 0xff) << 16; - wrote_bytes = 3; - cmdreg = -1; - } - } - dad = (ead >> 20) & 0x0f; - ead &= 0x3ffff; - } -#else - csrw_ptr = csrw_ptr % 3; - if(!(cmd_fifo->empty())) { - if(csrw_ptr == 0) { - ead = 0; - dad = 0; - wg = false; - } - int len = cmd_fifo->count(); - if(len > 3) len = 3; - for(int i = 0; i < len; i++) { - int nmask = ~(0xff << (csrw_ptr * 8)); - int val = cmd_fifo->read() & 0xff; - val = val << (csrw_ptr * 8); - - ead = ead & nmask; - ead = ead | val; - csrw_ptr++; - if(csrw_ptr >= 3) { - csrw_ptr = 0; + wrote_bytes = params_count; + if(wrote_bytes > 3) wrote_bytes = 3; + if(params_count > 0) { + ead = params[0]; + if(params_count > 1) { + ead |= params[1] << 8; + if(params_count > 2) { + ead |= params[2] << 16; cmdreg = -1; - break; } } dad = (ead >> 20) & 0x0f; - wg = ((ead & 0x080000) != 0) ? true : false; ead &= 0x3ffff; } -#endif } void UPD7220::cmd_csrr() { wrote_bytes = 5; + cmd_drawing = true; fo->write(ead & 0xff); fo->write((ead >> 8) & 0xff); fo->write((ead >> 16) & 0x03); @@ -1059,67 +884,57 @@ void UPD7220::cmd_csrr() void UPD7220::cmd_mask() { - if(cmd_fifo->count() > 2) { - maskl = (cmd_fifo->read() & 0xff); - maskh = (cmd_fifo->read() & 0xff); + if(params_count > 1) { + maskl = params[0]; + maskh = params[1]; cmdreg = -1; } } void UPD7220::cmd_write() { - mod = cmdreg & 3; wrote_bytes = 0; + mod = cmdreg & 3; switch(cmdreg & 0x18) { case 0x00: // low and high - if(cmd_fifo->count() > 1) { - uint8_t l = (uint8_t)(cmd_fifo->read()) & maskl; - uint8_t h = (uint8_t)(cmd_fifo->read()) & maskh; + if(params_count > 1) { + uint8_t l = params[0] & maskl; + uint8_t h = params[1] & maskh; wrote_bytes = 2; for(int i = 0; i < dc + 1; i++) { cmd_write_sub(ead * 2 + 0, l); cmd_write_sub(ead * 2 + 1, h); ead += dif; - if(!(cmd_fifo->empty())) { - l = (uint8_t)(cmd_fifo->read()) & maskl; - h = (uint8_t)(cmd_fifo->read()) & maskh; - } } wrote_bytes += ((dc + 1) * 2 * 2); cmd_write_done = true; - //cmd_fifo->clear(); // OK? + params_count = 0; } break; case 0x10: // low byte - if(cmd_fifo->count() > 0) { + if(params_count > 0) { wrote_bytes = 1; - uint8_t l = (uint8_t)(cmd_fifo->read()) & maskl; + uint8_t l = params[0] & maskl; for(int i = 0; i < dc + 1; i++) { cmd_write_sub(ead * 2 + 0, l); ead += dif; - if(!(cmd_fifo->empty())) { - l = (uint8_t)(cmd_fifo->read()) & maskl; - } } wrote_bytes += ((dc + 1) * 2); cmd_write_done = true; - //cmd_fifo->clear(); // OK? + params_count = 0; } break; case 0x18: // high byte - if(cmd_fifo->count() > 0) { + if(params_count > 0) { wrote_bytes = 1; - uint8_t h = (uint8_t)(cmd_fifo->read()) & maskh; + uint8_t h = params[0] & maskh; for(int i = 0; i < dc + 1; i++) { cmd_write_sub(ead * 2 + 1, h); - if(!(cmd_fifo->empty())) { - h = (uint8_t)(cmd_fifo->read()) & maskh; - } ead += dif; } wrote_bytes += ((dc + 1) * 2); cmd_write_done = true; - //cmd_fifo->clear(); // OK? + params_count = 0; } break; default: // invalid @@ -1158,7 +973,7 @@ void UPD7220::cmd_read() default: // invalid break; } -// reset_vect(); + reset_vect(); cmdreg = -1; } @@ -1167,8 +982,8 @@ void UPD7220::cmd_dmaw() mod = cmdreg & 3; low_high = false; write_signals(&outputs_drq, 0xffffffff); -// reset_vect(); - statreg |= STAT_DMA; + reset_vect(); +// statreg |= STAT_DMA; cmdreg = -1; } @@ -1177,19 +992,16 @@ void UPD7220::cmd_dmar() mod = cmdreg & 3; low_high = false; write_signals(&outputs_drq, 0xffffffff); -// reset_vect(); - statreg |= STAT_DMA; + reset_vect(); +// statreg |= STAT_DMA; cmdreg = -1; } void UPD7220::cmd_unk_5a() { - wrote_bytes = 0; - int len = cmd_fifo->count(); - if(len > 2) { - wrote_bytes = len; + if(params_count > 2) { cmdreg = -1; - cmd_fifo->clear(); + wrote_bytes = params_count; } } @@ -1227,14 +1039,13 @@ void UPD7220::write_vram(uint32_t addr, uint8_t data) uint8_t UPD7220::read_vram(uint32_t addr) { if(addr < vram_size) { -// uint8_t mask = (addr & 1) ? (vram_data_mask >> 8) : (vram_data_mask & 0xff); - uint8_t mask = 0xff; + uint8_t mask = (addr & 1) ? (vram_data_mask >> 8) : (vram_data_mask & 0xff); if(vram != NULL) { return (vram[addr] & mask) | ~mask; } else if(d_vram_bus != NULL) { return (d_vram_bus->read_dma_io8(addr) & mask) | ~mask; } - } + } return 0xff; } @@ -1248,13 +1059,6 @@ void UPD7220::update_vect() d2 = (vect[5] | (vect[ 6] << 8)) & 0x3fff; d1 = (vect[7] | (vect[ 8] << 8)) & 0x3fff; dm = (vect[9] | (vect[10] << 8)) & 0x3fff; - dgd = ((vect[2] & 0x40) != 0) ? true : false; -// if(dc & 0x2000) dc = -(dc & 0x1fff); -// if(d & 0x2000) d = -(d & 0x1fff); -// if(d2 & 0x2000) d2 = -(d2 & 0x1fff); -// if(d1 & 0x2000) d1 = -(d1 & 0x1fff); -// if(dc & 0x2000) dc = -(dc & 0x1fff); -// if(dm & 0x2000) dm = -(dm & 0x1fff); } void UPD7220::reset_vect() @@ -1265,98 +1069,76 @@ void UPD7220::reset_vect() vect[ 4] = 0x00; vect[ 5] = 0x08; vect[ 6] = 0x00; - vect[ 7] = 0xff; - vect[ 8] = 0xff; - vect[ 9] = 0xff; - vect[10] = 0xff; - vectw_ptr = 0; + vect[ 7] = 0x00; + vect[ 8] = 0x00; + vect[ 9] = 0x00; + vect[10] = 0x00; update_vect(); } - +// draw void UPD7220::draw_vectl() { pattern = ra[8] | (ra[9] << 8); - //out_debug_log(_T("DRAW VECTL: X=%d Y=%d to DC=%d D1=%d DIR=%d PATTERN=%04x MODE=%d\n"), dx, dy, dc, d1, dir, pattern, mod); - dc = dc & 0x3fff; if(dc) { int x = dx; - int y = dy; - int step; - int stepx = 0; - int stepy = 0; - int stepn = 0; + int y = dy >> 16; - step = (((d1 << 12) / dc)) >> 1; - //stepn = step & ((1 << 14) - 1); - start_pset(); switch(dir) { case 0: for(int i = 0; i <= dc; i++) { - //stepx = (int)((((d1 * i) / dc) + 1) >> 1); - stepx += step; - draw_pset_diff(x + (stepx >> 12), y++); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x + step, y++); } break; case 1: for(int i = 0; i <= dc; i++) { - //stepy = (int)((((d1 * i) / dc) + 1) >> 1); - stepy += step; - draw_pset_diff(x++, y + (stepy >> 12)); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x++, y + step); } break; case 2: for(int i = 0; i <= dc; i++) { - //stepy = (int)((((d1 * i) / dc) + 1) >> 1); - stepy += step; - draw_pset_diff(x++, y - (stepy >> 12)); - //draw_pset_diff(x++, y - step); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x++, y - step); } break; case 3: for(int i = 0; i <= dc; i++) { - //stepx = (int)((((d1 * i) / dc) + 1) >> 1); - stepx += step; - draw_pset_diff(x + (stepx >> 12), y--); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x + step, y--); } break; case 4: for(int i = 0; i <= dc; i++) { - //stepx = (int)((((d1 * i) / dc) + 1) >> 1); - stepx += step; - draw_pset_diff(x - (stepx >> 12), y--); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x - step, y--); } break; case 5: for(int i = 0; i <= dc; i++) { -// stepy = (int)((((d1 * i) / dc) + 1) >> 1); - stepy += step; - draw_pset_diff(x--, y - (stepy >> 12)); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x--, y - step); } break; case 6: for(int i = 0; i <= dc; i++) { -// stepy = (int)((((d1 * i) / dc) + 1) >> 1); - stepy += step; - draw_pset_diff(x--, y + (stepy >> 12)); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x--, y + step); } break; case 7: for(int i = 0; i <= dc; i++) { - //stepx = (int)((((d1 * i) / dc) + 1) >> 1); - stepx += step; - draw_pset_diff(x - (stepx >> 12), y++); + int step = (int)((((d1 * i) / dc) + 1) >> 1); + draw_pset(x - step, y++); } break; } - finish_pset(); } else { - start_pset(); - draw_pset_diff(dx, dy); - finish_pset(); wrote_bytes++; + draw_pset(dx, dy >> 16); } } @@ -1375,51 +1157,39 @@ void UPD7220::draw_vectt() (draw & 0x8000 ? 0x0002 : 0) | (draw & 0x8000 ? 0x0001 : 0); } int vx1 = vectdir[dir][0]; - int vy1 = vectdir[dir][1]; + int vy1 = (vectdir[dir][1] << 16); int vx2 = vectdir[dir][2]; - int vy2 = vectdir[dir][3]; + int vy2 = (vectdir[dir][3] << 16); int muly = zw + 1; - int nwidth = width << 3; pattern = 0xffff; - int ead_bak = ead; - int dad_bak = dad; while(muly--) { int cx = dx; - int cy = dy; + int64_t cy = dy; int xrem = d; while(xrem--) { int mulx = zw + 1; if(draw & 1) { draw >>= 1; draw |= 0x8000; - start_pset(); while(mulx--) { - draw_pset(cx, cy); + draw_pset(cx, cy >> 16); cx += vx1; cy += vy1; } - cx += (vx1 * mulx); - cy += (vy1 * mulx); - mulx = 0; - finish_pset(); } else { draw >>= 1; - //while(mulx--) { - // cx += vx1; - // cy += vy1; - //} - cx += (vx1 * mulx); - cy += (vy1 * mulx); - mulx = 0; + while(mulx--) { + cx += vx1; + cy += vy1; + } } } - _abort: dx += vx2; dy += vy2; } -// ead = (dx >> 4) + dy * pitch; -// dad = dx & 0x0f; + ead = (dx >> 4) + (dy >> 16) * pitch; + dad = dx & 0x0f; } void UPD7220::draw_vectc() @@ -1427,130 +1197,192 @@ void UPD7220::draw_vectc() int m = (d * 10000 + 14141) / 14142; int t = (dc > m) ? m : dc; pattern = ra[8] | (ra[9] << 8); - int xbak = dx; - int ybak = dy; + if(m) { - start_pset(); switch(dir) { case 0: for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - draw_pset_diff((dx + s), (dy + i)); + draw_pset((dx + s), ((dy >> 16) + i)); } break; case 1: for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - draw_pset_diff((dx + i), (dy + s)); + draw_pset((dx + i), ((dy >> 16) + s)); } break; case 2: for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - draw_pset_diff((dx + i), (dy - s)); + draw_pset((dx + i), ((dy >> 16) - s)); } break; case 3: for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - draw_pset_diff((dx + s), (dy - i)); + draw_pset((dx + s), ((dy >> 16) - i)); } break; case 4: for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - draw_pset_diff((dx - s), (dy - i)); + draw_pset((dx - s), ((dy >> 16) - i)); } break; case 5: for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - - draw_pset_diff((dx - i), (dy - s)); + draw_pset((dx - i), ((dy >> 16) - s)); } break; case 6: - start_pset(); for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - draw_pset_diff((dx - i), (dy + s)); + draw_pset((dx - i), ((dy >> 16) + s)); } break; case 7: for(int i = dm; i <= t; i++) { int s = (rt[(i << RT_TABLEBIT) / m] * d); s = (s + (1 << (RT_MULBIT - 1))) >> RT_MULBIT; - draw_pset_diff((dx - s), (dy + i)); + draw_pset((dx - s), ((dy >> 16) + i)); } break; } - finish_pset(); } else { - start_pset(); - draw_pset_diff(dx, dy); - finish_pset(); - //wrote_bytes++; + draw_pset(dx, dy >> 16); } } void UPD7220::draw_vectr() { int vx1 = vectdir[dir][0]; - int vy1 = vectdir[dir][1]; + int vy1 = vectdir[dir][1] << 16; int vx2 = vectdir[dir][2]; - int vy2 = vectdir[dir][3]; - int nwidth = width <<3; - int xbak = dx; - int ybak = dy; + int vy2 = vectdir[dir][3] << 16; pattern = ra[8] | (ra[9] << 8); -// out_debug_log(_T("DRAW VECTR: X=%d Y=%d to DC=%d DIR=%d PATTERN=%04x MODE=%d VX1=%d VY1=%d VX2=%d VY2=%d\n"), dx, dy, dc, dir, pattern, mod, vx1, vy1, vx2, vy2); - start_pset(); - for(int c = 0; c < d; c++) { - draw_pset_diff(dx, dy); + +// out_debug_log(_T("VECTR D=%d D2=%d START=%d,%d VX1,VY1,VX2,VY2 = %d,%d,%d,%d"), +// d, d1, dx, dy, vx1, vy1, vx2,vy2); + for(int i = 0; i < d; i++) { + draw_pset(dx, dy >> 16); dx += vx1; dy += vy1; } - for(int c = 0; c < d2; c++) { - draw_pset_diff(dx, dy); + for(int i = 0; i < d2; i++) { + draw_pset(dx, dy >> 16); dx += vx2; dy += vy2; } - for(int c = 0; c < d; c++) { - draw_pset_diff(dx, dy); + for(int i = 0; i < d; i++) { + draw_pset(dx, dy >> 16); dx -= vx1; dy -= vy1; } - for(int c = 0; c < d2; c++) { - draw_pset_diff(dx, dy); + for(int i = 0; i < d2; i++) { + draw_pset(dx, dy >> 16); dx -= vx2; dy -= vy2; } + ead = (dx >> 4) + (dy >> 16) * pitch; + dad = dx & 0x0f; +} + +void UPD7220::draw_text() +{ + int dir2 = dir + (sl ? 8 : 0); + int vx1 = vectdir[dir2][0]; + int vy1 = vectdir[dir2][1] << 16; + int vx2 = vectdir[dir2][2]; + int vy2 = vectdir[dir2][3] << 16; + int sx = d; + int sy = dc + 1; + if(__QC10) { + if(dir == 0 && sy == 40) { + sy = 640; // ugly patch + } + } +// this->out_debug_log(_T("\tTEXT: dx=%d,dy=%d,sx=%d,sy=%d\n"), dx, dy, sx, sy); + int index = 15; - finish_pset(); -// dx = xbak; -// dy = ybak; + while(sy--) { + int muly = zw + 1; + while(muly--) { + int cx = dx; + int64_t cy = dy; + uint8_t bit = ra[index]; + int xrem = sx; + while(xrem--) { + pattern = (bit & 1) ? 0xffff : 0; + bit = (bit >> 1) | ((bit & 1) ? 0x80 : 0); + int mulx = zw + 1; + while(mulx--) { + draw_pset(cx, cy >> 16); + cx += vx1; + cy += vy1; + } + } + dx += vx2; + dy += vy2; + } + index = ((index - 1) & 7) | 8; + } + ead = (dx >> 4) + (dy >> 16) * pitch; + dad = dx & 0x0f; +} -// ead = (dx >> 4) + dy * pitch; -// dad = dx & 0x0f; +void UPD7220::draw_pset(int x, int y) +{ + uint16_t dot = pattern & 1; + pattern = (pattern >> 1) | (dot << 15); + int32_t addr = y * width + (x >> 3); + + uint8_t bit; + if(_UPD7220_MSB_FIRST) { + bit = 0x80 >> (x & 7); + } else { + bit = 1 << (x & 7); + } + //if(addr < 0) return; // Dummy; + //if(addr >= vram_plane_size) return; // Dummy + addr = addr & vram_plane_addr_mask; + wrote_bytes++; + uint8_t cur = read_vram(addr); + + switch(mod) { + case 0: // replace + write_vram(addr, (cur & ~bit) | (dot ? bit : 0)); + break; + case 1: // complement + write_vram(addr, (cur & ~bit) | ((cur ^ (dot ? 0xff : 0)) & bit)); + break; + case 2: // reset + write_vram(addr, cur & (dot ? ~bit : 0xff)); + break; + case 3: // set + write_vram(addr, cur | (dot ? bit : 0)); + break; + } } -#define STATE_VERSION 9 +#define STATE_VERSION 3 /* Change mean of DY 20200808 K.O */ bool UPD7220::process_state(FILEIO* state_fio, bool loading) { if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } + return false; + } if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } + return false; + } state_fio->StateValue(cmdreg); state_fio->StateValue(statreg); state_fio->StateArray(sync, sizeof(sync), 1); @@ -1581,8 +1413,6 @@ bool UPD7220::process_state(FILEIO* state_fio, bool loading) state_fio->StateArray(vect, sizeof(vect), 1); state_fio->StateValue(ead); state_fio->StateValue(dad); - state_fio->StateValue(wg); - state_fio->StateValue(maskl); state_fio->StateValue(maskh); state_fio->StateValue(mod); @@ -1591,23 +1421,23 @@ bool UPD7220::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(vsync); state_fio->StateValue(vblank); state_fio->StateValue(start); - state_fio->StateValue(sync_mask); - state_fio->StateValue(blink_cursor); state_fio->StateValue(blink_attr); state_fio->StateValue(blink_rate); state_fio->StateValue(low_high); state_fio->StateValue(cmd_write_done); state_fio->StateValue(cpu_clocks); - if(_UPD7220_HORIZ_FREQ != 0) { + if(_UPD7220_HORIZ_FREQ) { state_fio->StateValue(horiz_freq); state_fio->StateValue(next_horiz_freq); } state_fio->StateValue(frames_per_sec); state_fio->StateValue(lines_per_frame); + state_fio->StateArray(params, sizeof(params), 1); + state_fio->StateValue(params_count); if(!fo->process_state((void *)state_fio, loading)) { - return false; - } + return false; + } state_fio->StateArray(rt, sizeof(rt), 1); state_fio->StateValue(dx); state_fio->StateValue(dy); @@ -1620,26 +1450,18 @@ bool UPD7220::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(d1); state_fio->StateValue(dm); state_fio->StateValue(pattern); - state_fio->StateValue(dgd); - + state_fio->StateValue(clock_freq); state_fio->StateValue(wrote_bytes); state_fio->StateValue(cmd_drawing); state_fio->StateValue(event_cmdready); - if(!cmd_fifo->process_state((void *)state_fio, loading)) { - return false; - } - state_fio->StateValue(first_load); - state_fio->StateValue(before_addr); - state_fio->StateValue(cache_val); - state_fio->StateValue(cs_ptr); - state_fio->StateValue(sync_ptr); - state_fio->StateValue(vectw_ptr); - state_fio->StateValue(csrw_ptr); - // post process + + state_fio->StateValue(width); + state_fio->StateValue(height); + // post process if(loading && master) { - // force update timing - vtotal = 0; + // force update timing + vtotal = 0; if(_UPD7220_HORIZ_FREQ != 0) { horiz_freq = 0; } @@ -1647,6 +1469,3 @@ bool UPD7220::process_state(FILEIO* state_fio, bool loading) return true; } - - - diff --git a/source/src/vm/upd7220.h b/source/src/vm/upd7220.h index 002c7409e..ecce0f5be 100644 --- a/source/src/vm/upd7220.h +++ b/source/src/vm/upd7220.h @@ -23,17 +23,17 @@ #define RT_TABLEBIT 12 #define RT_TABLEMAX (1 << RT_TABLEBIT) -#define SIG_UPD7220_CLOCK_FREQ 1 -#define SIG_UPD7220_EXT_VSYNC 2 -#define SIG_UPD7220_WIDTH_BYTES 3 -#define SIG_UPD7220_HEIGHT 4 -#define SIG_UPD7220_PITCH 5 -#define SIG_UPD7220_DISP_HEIGHT 6 -#define SIG_UPD7220_DISP_WIDTH 7 +#define SIG_UPD7220_CLOCK_FREQ 1 +#define SIG_UPD7220_EXT_VSYNC 2 +#define SIG_UPD7220_WIDTH_BYTES 3 +#define SIG_UPD7220_HEIGHT 4 +#define SIG_UPD7220_PITCH 5 +#define SIG_UPD7220_DISP_WIDTH 6 +#define SIG_UPD7220_DISP_HEIGHT 7 -class RINGBUFFER; class FIFO; -class UPD7220 : public DEVICE + +class DLL_PREFIX UPD7220 : public DEVICE { protected: // output signals @@ -45,8 +45,9 @@ class UPD7220 : public DEVICE DEVICE* d_vram_bus; uint8_t* vram; uint32_t vram_size; + uint32_t vram_plane_addr_mask; // Normally 32KB uint16_t vram_data_mask; - + // feature flags bool __QC10; bool _UPD7220_MSB_FIRST; @@ -55,7 +56,8 @@ class UPD7220 : public DEVICE int _UPD7220_HORIZ_FREQ; int _UPD7220_A_VERSION; int _LINES_PER_FRAME; - + int _CHARS_PER_LINE; + // regs int cmdreg; uint8_t statreg; @@ -69,16 +71,10 @@ class UPD7220 : public DEVICE uint8_t zoom, zr, zw; uint8_t ra[16]; uint8_t cs[3]; - uint8_t cs_ptr; - uint8_t csrw_ptr; - uint8_t sync_ptr; uint8_t pitch; uint32_t lad; uint8_t vect[11]; - uint8_t vectw_ptr; int ead, dad; - bool wg; - uint8_t maskl, maskh; uint8_t mod; bool hsync, hblank; @@ -93,43 +89,37 @@ class UPD7220 : public DEVICE int height; int cpu_clocks; + +//#ifdef UPD7220_HORIZ_FREQ + int horiz_freq, next_horiz_freq; +//#endif double frames_per_sec; int lines_per_frame; - // ring buffers - RINGBUFFER *fo; - RINGBUFFER *cmd_fifo; - // waiting int event_cmdready; uint32_t wrote_bytes; bool cmd_drawing; uint32_t clock_freq; + + // fifo buffers + uint8_t params[16]; + int params_count; + FIFO *fo; + // draw int rt[RT_TABLEMAX + 1]; - int dx, dy; // from ead, dad + int dx; + int64_t dy; // from ead, dad int dir, dif, sl, dc, d, d2, d1, dm; - bool dgd; uint16_t pattern; - const int vectdir[16][4] = { - { 0, 1, 1, 0}, { 1, 1, 1,-1}, { 1, 0, 0,-1}, { 1,-1,-1,-1}, - { 0,-1,-1, 0}, {-1,-1,-1, 1}, {-1, 0, 0, 1}, {-1, 1, 1, 1}, - { 0, 1, 1, 1}, { 1, 1, 1, 0}, { 1, 0, 1,-1}, { 1,-1, 0,-1}, - { 0,-1,-1,-1}, {-1,-1,-1, 0}, {-1, 0,-1, 1}, {-1, 1, 0, 1} - }; - int horiz_freq, next_horiz_freq; + // command - //void check_cmd(); - //void process_cmd(); - uint32_t before_addr; - uint8_t cache_val; - bool first_load; - bool sync_mask; + void check_cmd(); + void process_cmd(); void cmd_reset(); - void cmd_reset2(); - void cmd_reset3(); - void cmd_sync(); + void __FASTCALL cmd_sync(bool flag); void cmd_master(); void cmd_slave(); void cmd_start(); @@ -137,11 +127,11 @@ class UPD7220 : public DEVICE void cmd_zoom(); void cmd_scroll(); void cmd_csrform(); - //void cmd_pitch(); + void cmd_pitch(); void cmd_lpen(); void cmd_vectw(); - //void cmd_vecte(); - //void cmd_texte(); + void cmd_vecte(); + void cmd_texte(); void cmd_csrw(); void cmd_csrr(); void cmd_mask(); @@ -157,29 +147,16 @@ class UPD7220 : public DEVICE void update_vect(); void reset_vect(); - void __FASTCALL register_event_wait_cmd(uint32_t bytes); - - void check_cmd(); - void process_cmd(); - void draw_vectl(); void draw_vectt(); void draw_vectc(); void draw_vectr(); - - void cmd_vecte(); - void cmd_texte(); - void cmd_pitch(); - void draw_text(); - inline void __FASTCALL draw_pset(int x, int y); - inline void __FASTCALL start_pset(); - inline void __FASTCALL finish_pset(); - inline bool __FASTCALL draw_pset_diff(int x, int y); - inline void __FASTCALL shift_pattern(int shift); + void __FASTCALL draw_pset(int x, int y); + void __FASTCALL register_event_wait_cmd(uint32_t bytes); public: - UPD7220(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD7220(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_drq); initialize_output_signals(&outputs_vsync); @@ -190,6 +167,7 @@ class UPD7220 : public DEVICE width = 80; height = 25; // ToDo clock_freq = 2500 * 1000; // Hz + vram_plane_addr_mask = 0x7fff; // Normally 32KB/plane set_device_name(_T("uPD7220 GDC")); } ~UPD7220() {} @@ -202,19 +180,22 @@ class UPD7220 : public DEVICE uint32_t __FASTCALL read_dma_io8(uint32_t addr); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); + + void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); + uint32_t __FASTCALL read_signal(int ch); + void event_pre_frame(); void event_frame(); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); - - uint32_t __FASTCALL read_signal(int ch); - void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask); - bool process_state(FILEIO* state_fio, bool loading); - // unique functions + void set_clock_freq(uint32_t val) + { + clock_freq = val; + } void set_context_drq(DEVICE* device, int id, uint32_t mask) { register_output_signal(&outputs_drq, device, id, mask); @@ -223,11 +204,7 @@ class UPD7220 : public DEVICE { register_output_signal(&outputs_vsync, device, id, mask); } - void set_context_vblank(DEVICE* device, int id, uint32_t mask) - { - register_output_signal(&outputs_vblank, device, id, mask); - } - void set_vram_ptr(uint8_t* ptr, uint32_t size) + void set_vram_ptr(uint8_t* ptr, uint32_t size) { vram = ptr; vram_size = size; @@ -242,23 +219,29 @@ class UPD7220 : public DEVICE d_vram_bus = device; vram_size = size; } + void set_context_vblank(DEVICE* device, int id, uint32_t mask) + { + register_output_signal(&outputs_vblank, device, id, mask); + } void set_vram_bus_ptr(DEVICE* device, uint32_t size, uint16_t mask) { set_vram_bus_ptr(device, size); - vram_data_mask = mask; + vram_data_mask = mask; } void set_screen_width(int value) { width = value; } - void set_screen_height(int value) + void set_screen_height(int val) { - height = value; + height = val; } - void set_clock_freq(uint32_t hz) +//#ifdef UPD7220_HORIZ_FREQ + void set_horiz_freq(int freq) { - clock_freq = hz; + next_horiz_freq = freq; } +//#endif uint8_t* get_sync() { return sync; @@ -284,161 +267,13 @@ class UPD7220 : public DEVICE return start; } uint32_t __FASTCALL cursor_addr(uint32_t mask); - int __FASTCALL cursor_top(); - int __FASTCALL cursor_bottom(); - bool __FASTCALL attr_blink() + int cursor_top(); + int cursor_bottom(); + bool attr_blink() { return (blink_attr < (blink_rate * 3 / 4)); } - void __FASTCALL set_horiz_freq(int freq) - { - next_horiz_freq = freq; - } }; - -inline void UPD7220::draw_pset(int x, int y) -{ - uint32_t addr = y * width + (x >> 3); - if(_UPD7220_UGLY_PC98_HACK) { -// if(addr >= 0x8000) return; -// if((y == 409) && (x >= 384)) return; -// if(y > 409) return; -// if((x < 0) || (y < 0) || (x >= (width << 3))) return; -// addr = addr & 0x7fff; - } else { - if((x < 0) || (y < 0) || (x >= (width << 3)) || (y >= height)) return; - } - uint16_t dot = pattern & 1; - pattern = (pattern >> 1) | (dot << 15); - uint8_t bit; - if(_UPD7220_MSB_FIRST) { - bit = 0x80 >> (x & 7); - } else { - bit = 1 << (x & 7); - } - uint8_t cur = read_vram(addr); -// ead = addr; -// dad = x & 0x0f; - - switch(mod) { - case 0: // replace - write_vram(addr, (cur & ~bit) | (dot ? bit : 0)); - break; - case 1: // complement - write_vram(addr, (cur & ~bit) | ((cur ^ (dot ? 0xff : 0)) & bit)); - break; - case 2: // reset - write_vram(addr, cur & (dot ? ~bit : 0xff)); - break; - case 3: // set - write_vram(addr, cur | (dot ? bit : 0)); - break; - } -} - -inline void UPD7220::start_pset() -{ - before_addr = 0xffffffff; - first_load = true; - cache_val = 0; -} - -inline void UPD7220::finish_pset() -{ - if(!first_load) { - write_vram(before_addr, cache_val); - //wrote_bytes++; - } - first_load = true; - before_addr = 0xffffffff; - cache_val = 0; -} - -inline void UPD7220::shift_pattern(int shift) -{ - int bits; - uint16_t dot; - if(shift == 0) { - return; - } else if(shift < 0) { - // Left shift - bits = (-shift) % 16; - if(bits == 0) return; - dot = pattern; - dot <<= bits; - pattern >>= (16 - bits); - pattern = (pattern | dot) & 0xffff; - } else if(shift > 0) { - // Right shift - bits = shift % 16; - if(bits == 0) return; - dot = pattern; - dot >>= bits; - pattern <<= (16 - bits); - pattern = (pattern | dot) & 0xffff; - } -} - - -inline bool UPD7220::draw_pset_diff(int x, int y) -{ - uint16_t dot = pattern & 1; - pattern = (pattern >> 1) | (dot << 15); - uint32_t addr = y * width + (x >> 3); - uint8_t bit; - -// if(_UPD7220_UGLY_PC98_HACK) { -// if(addr >= 0x8000) { -// if((y > 409) || ((y == 409) && x >= 384)){ -// finish_pset(); -// return false; -// } -// else if((x < 0) || (y < 0) || (x >= (width << 3))) { -// finish_pset(); -// return false; -// } -// } else if((x < 0) || (y < 0) || (x >= (width << 3)) || (y >= height)) { -// finish_pset(); -// return false; -// } - if((first_load) || (addr != before_addr)) { - if(!(first_load)) { - write_vram(before_addr, cache_val); - //wrote_bytes++; - } - cache_val = read_vram(addr); - } - - first_load = false; - before_addr = addr; -// ead = addr; -// dad = x & 0x0f; - - if(_UPD7220_MSB_FIRST) { - bit = 0x80 >> (x & 7); - } else { - bit = 1 << (x & 7); - } - uint8_t cur = cache_val; - wrote_bytes++; // OK? - - switch(mod) { - case 0: // replace - cache_val = (cur & ~bit) | (dot ? bit : 0); - break; - case 1: // complement - cache_val = (cur & ~bit) | ((cur ^ (dot ? 0xff : 0)) & bit); - break; - case 2: // reset - cache_val = cur & (dot ? ~bit : 0xff); - break; - case 3: // set - cache_val = cur | (dot ? bit : 0); - break; - } - return true; -} - #endif diff --git a/source/src/vm/upd765a.h b/source/src/vm/upd765a.h index 429103e4c..101b8152f 100644 --- a/source/src/vm/upd765a.h +++ b/source/src/vm/upd765a.h @@ -27,7 +27,7 @@ class DISK; class NOISE; -class UPD765A : public DEVICE +class DLL_PREFIX UPD765A : public DEVICE { private: // output signals @@ -117,22 +117,22 @@ class UPD765A : public DEVICE void process_cmd(int cmd); void cmd_sence_devstat(); void cmd_sence_intstat(); - uint8_t get_devstat(int drv); + uint8_t __FASTCALL get_devstat(int drv); void cmd_seek(); void cmd_recalib(); - void seek(int drv, int trk); - void seek_event(int drv); + void __FASTCALL seek(int drv, int trk); + void __FASTCALL seek_event(int drv); void cmd_read_data(); void cmd_write_data(); void cmd_scan(); void cmd_read_diagnostic(); - void read_data(bool deleted, bool scan); - void write_data(bool deleted); + void __FASTCALL read_data(bool deleted, bool scan); + void __FASTCALL write_data(bool deleted); void read_diagnostic(); uint32_t read_sector(); - uint32_t write_sector(bool deleted); + uint32_t __FASTCALL write_sector(bool deleted); uint32_t find_id(); - uint32_t check_cond(bool write); + uint32_t __FASTCALL check_cond(bool write); void get_sector_params(); bool id_incr(); void cmd_read_id(); @@ -141,11 +141,11 @@ class UPD765A : public DEVICE uint32_t write_id(); void cmd_specify(); void cmd_invalid(); - void update_head_flag(int drv, bool head_load); + void __FASTCALL update_head_flag(int drv, bool head_load); void process_state_fdc(int ch, FILEIO* state_fio, bool loading); public: - UPD765A(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD765A(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_irq); initialize_output_signals(&outputs_drq); @@ -176,7 +176,7 @@ class UPD765A : public DEVICE uint32_t __FASTCALL read_dma_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int ch); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_config(); //#ifdef USE_DEBUGGER bool is_debugger_available() diff --git a/source/src/vm/upd7752.h b/source/src/vm/upd7752.h index be2f57daf..1e1c64c67 100644 --- a/source/src/vm/upd7752.h +++ b/source/src/vm/upd7752.h @@ -58,9 +58,7 @@ typedef int D7752_FIXED; #define D7752E_ERR (0x10) // b4 ERR - 1 when error #define D7752E_IDL (0x00) // waiting -class VM; -class EMU; -class UPD7752 : public DEVICE +class DLL_PREFIX UPD7752 : public DEVICE { private: bool mute; @@ -89,9 +87,9 @@ class UPD7752 : public DEVICE void AbortVoice(void); void CancelVoice(void); int VoiceOn(void); - void VSetMode(uint8_t mode); - void VSetCommand(uint8_t comm); - void VSetData(uint8_t data); + void __FASTCALL VSetMode(uint8_t mode); + void __FASTCALL VSetCommand(uint8_t comm); + void __FASTCALL VSetData(uint8_t data); int VGetStatus(void); // filter coefficients @@ -111,12 +109,12 @@ class UPD7752 : public DEVICE int UPD7752_Start(int mode); int GetFrameSize(void); - int Synth(uint8_t *param, D7752_SAMPLE *frame); + int __FASTCALL Synth(uint8_t *param, D7752_SAMPLE *frame); int volume_l, volume_r; public: - UPD7752(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD7752(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; set_device_name(_T("uPD7752 Voice Synthesizer")); @@ -130,7 +128,7 @@ class UPD7752 : public DEVICE void reset(); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/upd7801.h b/source/src/vm/upd7801.h index 8c16b7747..f035add4e 100644 --- a/source/src/vm/upd7801.h +++ b/source/src/vm/upd7801.h @@ -31,7 +31,7 @@ class DEBUGGER; //#endif -class UPD7801 : public DEVICE +class DLL_PREFIX UPD7801 : public DEVICE { private: /* --------------------------------------------------------------------------- @@ -108,7 +108,7 @@ class UPD7801 : public DEVICE void __FASTCALL OP74(); public: - UPD7801(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD7801(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { total_count = prev_total_count = 0; diff --git a/source/src/vm/upd7810.h b/source/src/vm/upd7810.h index 57297e196..1e278945c 100644 --- a/source/src/vm/upd7810.h +++ b/source/src/vm/upd7810.h @@ -11,8 +11,8 @@ #ifndef _UPD7810_H_ #define _UPD7810_H_ -#include "vm.h" -#include "../emu.h" +//#include "vm.h" +//#include "../emu.h" #include "device.h" #define SIG_UPD7810_INTF1 0 @@ -23,7 +23,7 @@ class DEBUGGER; -class UPD7810 : public DEVICE +class DLL_PREFIX UPD7810 : public DEVICE { private: DEVICE *d_mem, *d_io; @@ -40,7 +40,7 @@ class UPD7810 : public DEVICE void process_state_cpustate(FILEIO* state_fio, bool loading); public: - UPD7810(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD7810(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { total_icount = prev_total_icount = 0; d_debugger = NULL; diff --git a/source/src/vm/upd7907.h b/source/src/vm/upd7907.h index 4343bb795..66606aae9 100644 --- a/source/src/vm/upd7907.h +++ b/source/src/vm/upd7907.h @@ -23,7 +23,7 @@ class DEBUGGER; -class UPD7907 : public DEVICE +class DLL_PREFIX UPD7907 : public DEVICE { private: DEVICE *d_mem, *d_io; @@ -40,7 +40,7 @@ class UPD7907 : public DEVICE void process_state_cpustate(FILEIO* state_fio, bool loading); public: - UPD7907(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + UPD7907(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { total_icount = prev_total_icount = 0; d_debugger = NULL; diff --git a/source/src/vm/v30.h b/source/src/vm/v30.h index 869fb0081..dff74729d 100644 --- a/source/src/vm/v30.h +++ b/source/src/vm/v30.h @@ -4,7 +4,7 @@ class V30 : public I8086 { public: - V30(VM_TEMPLATE* parent_vm, EMU* parent_emu) : I8086(parent_vm, parent_emu) + V30(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : I8086(parent_vm, parent_emu) { set_device_name(_T("NEC V30 CPU")); } diff --git a/source/src/vm/v30_dasm.cpp b/source/src/vm/v30_dasm.cpp new file mode 100644 index 000000000..0ca582b4e --- /dev/null +++ b/source/src/vm/v30_dasm.cpp @@ -0,0 +1,327 @@ +/* + Skelton for retropc emulator + + Origin : MAME V30 core + Author : Takeda.Toshiya + Date : 2020.02.02- + + [ V30 disassembler ] +*/ + +#include "i386_dasm.h" +#include "debugger.h" + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning( disable : 4146 ) +#endif + +/*****************************************************************************/ +/* src/emu/devcpu.h */ + +// CPU interface functions +#define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name +#define CPU_DISASSEMBLE(name) int CPU_DISASSEMBLE_NAME(name)(_TCHAR *buffer, offs_t eip, const UINT8 *oprom) +#define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(buffer, eip, oprom) + +/*****************************************************************************/ +/* src/emu/didisasm.h */ + +// Disassembler constants +const UINT32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported? +const UINT32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence +const UINT32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards +const UINT32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over +const UINT32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value +const UINT32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length + +// offsets and addresses are 32-bit (for now...) +typedef UINT32 offs_t; + +/*****************************************************************************/ +/* src/osd/osdcomm.h */ + +/* Highly useful macro for compile-time knowledge of an array size */ +#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0])) + +#ifndef INLINE +#define INLINE inline +#endif + +#include "mame/emu/cpu/nec/necdasm.c" + +int v30_dasm(DEBUGGER *debugger, uint8_t *oprom, uint32_t eip, bool emulation_mode, _TCHAR *buffer, size_t buffer_len) +{ + if(!emulation_mode) { + return CPU_DISASSEMBLE_CALL(nec_generic) & DASMFLAG_LENGTHMASK; + } + int ptr = 0; + + switch(oprom[ptr++]) { + case 0x00: my_stprintf_s(buffer, buffer_len, _T("nop")); break; + case 0x01: my_stprintf_s(buffer, buffer_len, _T("lxi b,%s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x02: my_stprintf_s(buffer, buffer_len, _T("stax b")); break; + case 0x03: my_stprintf_s(buffer, buffer_len, _T("inx b")); break; + case 0x04: my_stprintf_s(buffer, buffer_len, _T("inr b")); break; + case 0x05: my_stprintf_s(buffer, buffer_len, _T("dcr b")); break; + case 0x06: my_stprintf_s(buffer, buffer_len, _T("mvi b,$%02x"), oprom[ptr++]); break; + case 0x07: my_stprintf_s(buffer, buffer_len, _T("rlc")); break; + case 0x08: my_stprintf_s(buffer, buffer_len, _T("nop")); break; + case 0x09: my_stprintf_s(buffer, buffer_len, _T("dad b")); break; + case 0x0a: my_stprintf_s(buffer, buffer_len, _T("ldax b")); break; + case 0x0b: my_stprintf_s(buffer, buffer_len, _T("dcx b")); break; + case 0x0c: my_stprintf_s(buffer, buffer_len, _T("inr c")); break; + case 0x0d: my_stprintf_s(buffer, buffer_len, _T("dcr c")); break; + case 0x0e: my_stprintf_s(buffer, buffer_len, _T("mvi c,$%02x"), oprom[ptr++]); break; + case 0x0f: my_stprintf_s(buffer, buffer_len, _T("rrc")); break; + case 0x10: my_stprintf_s(buffer, buffer_len, _T("nop")); break; + case 0x11: my_stprintf_s(buffer, buffer_len, _T("lxi d,%s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x12: my_stprintf_s(buffer, buffer_len, _T("stax d")); break; + case 0x13: my_stprintf_s(buffer, buffer_len, _T("inx d")); break; + case 0x14: my_stprintf_s(buffer, buffer_len, _T("inr d")); break; + case 0x15: my_stprintf_s(buffer, buffer_len, _T("dcr d")); break; + case 0x16: my_stprintf_s(buffer, buffer_len, _T("mvi d,$%02x"), oprom[ptr++]); break; + case 0x17: my_stprintf_s(buffer, buffer_len, _T("ral")); break; + case 0x18: my_stprintf_s(buffer, buffer_len, _T("nop")); break; + case 0x19: my_stprintf_s(buffer, buffer_len, _T("dad d")); break; + case 0x1a: my_stprintf_s(buffer, buffer_len, _T("ldax d")); break; + case 0x1b: my_stprintf_s(buffer, buffer_len, _T("dcx d")); break; + case 0x1c: my_stprintf_s(buffer, buffer_len, _T("inr e")); break; + case 0x1d: my_stprintf_s(buffer, buffer_len, _T("dcr e")); break; + case 0x1e: my_stprintf_s(buffer, buffer_len, _T("mvi e,$%02x"), oprom[ptr++]); break; + case 0x1f: my_stprintf_s(buffer, buffer_len, _T("rar")); break; + case 0x20: my_stprintf_s(buffer, buffer_len, _T("rim")); break; + case 0x21: my_stprintf_s(buffer, buffer_len, _T("lxi h,%s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x22: my_stprintf_s(buffer, buffer_len, _T("shld %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x23: my_stprintf_s(buffer, buffer_len, _T("inx h")); break; + case 0x24: my_stprintf_s(buffer, buffer_len, _T("inr h")); break; + case 0x25: my_stprintf_s(buffer, buffer_len, _T("dcr h")); break; + case 0x26: my_stprintf_s(buffer, buffer_len, _T("mvi h,$%02x"), oprom[ptr++]); break; + case 0x27: my_stprintf_s(buffer, buffer_len, _T("daa")); break; + case 0x28: my_stprintf_s(buffer, buffer_len, _T("nop")); break; + case 0x29: my_stprintf_s(buffer, buffer_len, _T("dad h")); break; + case 0x2a: my_stprintf_s(buffer, buffer_len, _T("lhld %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x2b: my_stprintf_s(buffer, buffer_len, _T("dcx h")); break; + case 0x2c: my_stprintf_s(buffer, buffer_len, _T("inr l")); break; + case 0x2d: my_stprintf_s(buffer, buffer_len, _T("dcr l")); break; + case 0x2e: my_stprintf_s(buffer, buffer_len, _T("mvi l,$%02x"), oprom[ptr++]); break; + case 0x2f: my_stprintf_s(buffer, buffer_len, _T("cma")); break; + case 0x30: my_stprintf_s(buffer, buffer_len, _T("sim")); break; + case 0x31: my_stprintf_s(buffer, buffer_len, _T("lxi sp,%s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x32: my_stprintf_s(buffer, buffer_len, _T("stax %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x33: my_stprintf_s(buffer, buffer_len, _T("inx sp")); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("inr m")); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("dcr m")); break; + case 0x36: my_stprintf_s(buffer, buffer_len, _T("mvi m,$%02x"), oprom[ptr++]); break; + case 0x37: my_stprintf_s(buffer, buffer_len, _T("stc")); break; + case 0x38: my_stprintf_s(buffer, buffer_len, _T("ldes $%02x"), oprom[ptr++]); break; + case 0x39: my_stprintf_s(buffer, buffer_len, _T("dad sp")); break; + case 0x3a: my_stprintf_s(buffer, buffer_len, _T("ldax %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0x3b: my_stprintf_s(buffer, buffer_len, _T("dcx sp")); break; + case 0x3c: my_stprintf_s(buffer, buffer_len, _T("inr a")); break; + case 0x3d: my_stprintf_s(buffer, buffer_len, _T("dcr a")); break; + case 0x3e: my_stprintf_s(buffer, buffer_len, _T("mvi a,$%02x"), oprom[ptr++]); break; + case 0x3f: my_stprintf_s(buffer, buffer_len, _T("cmf")); break; + case 0x40: my_stprintf_s(buffer, buffer_len, _T("mov b,b")); break; + case 0x41: my_stprintf_s(buffer, buffer_len, _T("mov b,c")); break; + case 0x42: my_stprintf_s(buffer, buffer_len, _T("mov b,d")); break; + case 0x43: my_stprintf_s(buffer, buffer_len, _T("mov b,e")); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("mov b,h")); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("mov b,l")); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("mov b,m")); break; + case 0x47: my_stprintf_s(buffer, buffer_len, _T("mov b,a")); break; + case 0x48: my_stprintf_s(buffer, buffer_len, _T("mov c,b")); break; + case 0x49: my_stprintf_s(buffer, buffer_len, _T("mov c,c")); break; + case 0x4a: my_stprintf_s(buffer, buffer_len, _T("mov c,d")); break; + case 0x4b: my_stprintf_s(buffer, buffer_len, _T("mov c,e")); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("mov c,h")); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("mov c,l")); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("mov c,m")); break; + case 0x4f: my_stprintf_s(buffer, buffer_len, _T("mov c,a")); break; + case 0x50: my_stprintf_s(buffer, buffer_len, _T("mov d,b")); break; + case 0x51: my_stprintf_s(buffer, buffer_len, _T("mov d,c")); break; + case 0x52: my_stprintf_s(buffer, buffer_len, _T("mov d,d")); break; + case 0x53: my_stprintf_s(buffer, buffer_len, _T("mov d,e")); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("mov d,h")); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("mov d,l")); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("mov d,m")); break; + case 0x57: my_stprintf_s(buffer, buffer_len, _T("mov d,a")); break; + case 0x58: my_stprintf_s(buffer, buffer_len, _T("mov e,b")); break; + case 0x59: my_stprintf_s(buffer, buffer_len, _T("mov e,c")); break; + case 0x5a: my_stprintf_s(buffer, buffer_len, _T("mov e,d")); break; + case 0x5b: my_stprintf_s(buffer, buffer_len, _T("mov e,e")); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("mov e,h")); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("mov e,l")); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("mov e,m")); break; + case 0x5f: my_stprintf_s(buffer, buffer_len, _T("mov e,a")); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("mov h,b")); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("mov h,c")); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("mov h,d")); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("mov h,e")); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("mov h,h")); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("mov h,l")); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("mov h,m")); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("mov h,a")); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("mov l,b")); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("mov l,c")); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("mov l,d")); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("mov l,e")); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("mov l,h")); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("mov l,l")); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("mov l,m")); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("mov l,a")); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("mov m,b")); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("mov m,c")); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("mov m,d")); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("mov m,e")); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("mov m,h")); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("mov m,l")); break; + case 0x76: my_stprintf_s(buffer, buffer_len, _T("hlt")); break; + case 0x77: my_stprintf_s(buffer, buffer_len, _T("mov m,a")); break; + case 0x78: my_stprintf_s(buffer, buffer_len, _T("mov a,b")); break; + case 0x79: my_stprintf_s(buffer, buffer_len, _T("mov a,c")); break; + case 0x7a: my_stprintf_s(buffer, buffer_len, _T("mov a,d")); break; + case 0x7b: my_stprintf_s(buffer, buffer_len, _T("mov a,e")); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("mov a,h")); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("mov a,l")); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("mov a,m")); break; + case 0x7f: my_stprintf_s(buffer, buffer_len, _T("mov a,a")); break; + case 0x80: my_stprintf_s(buffer, buffer_len, _T("add b")); break; + case 0x81: my_stprintf_s(buffer, buffer_len, _T("add c")); break; + case 0x82: my_stprintf_s(buffer, buffer_len, _T("add d")); break; + case 0x83: my_stprintf_s(buffer, buffer_len, _T("add e")); break; + case 0x84: my_stprintf_s(buffer, buffer_len, _T("add h")); break; + case 0x85: my_stprintf_s(buffer, buffer_len, _T("add l")); break; + case 0x86: my_stprintf_s(buffer, buffer_len, _T("add m")); break; + case 0x87: my_stprintf_s(buffer, buffer_len, _T("add a")); break; + case 0x88: my_stprintf_s(buffer, buffer_len, _T("adc b")); break; + case 0x89: my_stprintf_s(buffer, buffer_len, _T("adc c")); break; + case 0x8a: my_stprintf_s(buffer, buffer_len, _T("adc d")); break; + case 0x8b: my_stprintf_s(buffer, buffer_len, _T("adc e")); break; + case 0x8c: my_stprintf_s(buffer, buffer_len, _T("adc h")); break; + case 0x8d: my_stprintf_s(buffer, buffer_len, _T("adc l")); break; + case 0x8e: my_stprintf_s(buffer, buffer_len, _T("adc m")); break; + case 0x8f: my_stprintf_s(buffer, buffer_len, _T("adc a")); break; + case 0x90: my_stprintf_s(buffer, buffer_len, _T("sub b")); break; + case 0x91: my_stprintf_s(buffer, buffer_len, _T("sub c")); break; + case 0x92: my_stprintf_s(buffer, buffer_len, _T("sub d")); break; + case 0x93: my_stprintf_s(buffer, buffer_len, _T("sub e")); break; + case 0x94: my_stprintf_s(buffer, buffer_len, _T("sub h")); break; + case 0x95: my_stprintf_s(buffer, buffer_len, _T("sub l")); break; + case 0x96: my_stprintf_s(buffer, buffer_len, _T("sub m")); break; + case 0x97: my_stprintf_s(buffer, buffer_len, _T("sub a")); break; + case 0x98: my_stprintf_s(buffer, buffer_len, _T("sbb b")); break; + case 0x99: my_stprintf_s(buffer, buffer_len, _T("sbb c")); break; + case 0x9a: my_stprintf_s(buffer, buffer_len, _T("sbb d")); break; + case 0x9b: my_stprintf_s(buffer, buffer_len, _T("sbb e")); break; + case 0x9c: my_stprintf_s(buffer, buffer_len, _T("sbb h")); break; + case 0x9d: my_stprintf_s(buffer, buffer_len, _T("sbb l")); break; + case 0x9e: my_stprintf_s(buffer, buffer_len, _T("sbb m")); break; + case 0x9f: my_stprintf_s(buffer, buffer_len, _T("sbb a")); break; + case 0xa0: my_stprintf_s(buffer, buffer_len, _T("ana b")); break; + case 0xa1: my_stprintf_s(buffer, buffer_len, _T("ana c")); break; + case 0xa2: my_stprintf_s(buffer, buffer_len, _T("ana d")); break; + case 0xa3: my_stprintf_s(buffer, buffer_len, _T("ana e")); break; + case 0xa4: my_stprintf_s(buffer, buffer_len, _T("ana h")); break; + case 0xa5: my_stprintf_s(buffer, buffer_len, _T("ana l")); break; + case 0xa6: my_stprintf_s(buffer, buffer_len, _T("ana m")); break; + case 0xa7: my_stprintf_s(buffer, buffer_len, _T("ana a")); break; + case 0xa8: my_stprintf_s(buffer, buffer_len, _T("xra b")); break; + case 0xa9: my_stprintf_s(buffer, buffer_len, _T("xra c")); break; + case 0xaa: my_stprintf_s(buffer, buffer_len, _T("xra d")); break; + case 0xab: my_stprintf_s(buffer, buffer_len, _T("xra e")); break; + case 0xac: my_stprintf_s(buffer, buffer_len, _T("xra h")); break; + case 0xad: my_stprintf_s(buffer, buffer_len, _T("xra l")); break; + case 0xae: my_stprintf_s(buffer, buffer_len, _T("xra m")); break; + case 0xaf: my_stprintf_s(buffer, buffer_len, _T("xra a")); break; + case 0xb0: my_stprintf_s(buffer, buffer_len, _T("ora b")); break; + case 0xb1: my_stprintf_s(buffer, buffer_len, _T("ora c")); break; + case 0xb2: my_stprintf_s(buffer, buffer_len, _T("ora d")); break; + case 0xb3: my_stprintf_s(buffer, buffer_len, _T("ora e")); break; + case 0xb4: my_stprintf_s(buffer, buffer_len, _T("ora h")); break; + case 0xb5: my_stprintf_s(buffer, buffer_len, _T("ora l")); break; + case 0xb6: my_stprintf_s(buffer, buffer_len, _T("ora m")); break; + case 0xb7: my_stprintf_s(buffer, buffer_len, _T("ora a")); break; + case 0xb8: my_stprintf_s(buffer, buffer_len, _T("cmp b")); break; + case 0xb9: my_stprintf_s(buffer, buffer_len, _T("cmp c")); break; + case 0xba: my_stprintf_s(buffer, buffer_len, _T("cmp d")); break; + case 0xbb: my_stprintf_s(buffer, buffer_len, _T("cmp e")); break; + case 0xbc: my_stprintf_s(buffer, buffer_len, _T("cmp h")); break; + case 0xbd: my_stprintf_s(buffer, buffer_len, _T("cmp l")); break; + case 0xbe: my_stprintf_s(buffer, buffer_len, _T("cmp m")); break; + case 0xbf: my_stprintf_s(buffer, buffer_len, _T("cmp a")); break; + case 0xc0: my_stprintf_s(buffer, buffer_len, _T("rnz")); break; + case 0xc1: my_stprintf_s(buffer, buffer_len, _T("pop b")); break; + case 0xc2: my_stprintf_s(buffer, buffer_len, _T("jnz %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xc3: my_stprintf_s(buffer, buffer_len, _T("jmp %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xc4: my_stprintf_s(buffer, buffer_len, _T("cnz %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xc5: my_stprintf_s(buffer, buffer_len, _T("push b")); break; + case 0xc6: my_stprintf_s(buffer, buffer_len, _T("adi $%02x"), oprom[ptr++]); break; + case 0xc7: my_stprintf_s(buffer, buffer_len, _T("rst 0")); break; + case 0xc8: my_stprintf_s(buffer, buffer_len, _T("rz")); break; + case 0xc9: my_stprintf_s(buffer, buffer_len, _T("ret")); break; + case 0xca: my_stprintf_s(buffer, buffer_len, _T("jz %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xcb: my_stprintf_s(buffer, buffer_len, _T("jmp %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xcc: my_stprintf_s(buffer, buffer_len, _T("cz %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xcd: my_stprintf_s(buffer, buffer_len, _T("call %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xce: my_stprintf_s(buffer, buffer_len, _T("aci $%02x"), oprom[ptr++]); break; + case 0xcf: my_stprintf_s(buffer, buffer_len, _T("rst 1")); break; + case 0xd0: my_stprintf_s(buffer, buffer_len, _T("rnc")); break; + case 0xd1: my_stprintf_s(buffer, buffer_len, _T("pop d")); break; + case 0xd2: my_stprintf_s(buffer, buffer_len, _T("jnc %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xd3: my_stprintf_s(buffer, buffer_len, _T("out $%02x"), oprom[ptr++]); break; + case 0xd4: my_stprintf_s(buffer, buffer_len, _T("cnc %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xd5: my_stprintf_s(buffer, buffer_len, _T("push d")); break; + case 0xd6: my_stprintf_s(buffer, buffer_len, _T("sui $%02x"), oprom[ptr++]); break; + case 0xd7: my_stprintf_s(buffer, buffer_len, _T("rst 2")); break; + case 0xd8: my_stprintf_s(buffer, buffer_len, _T("rc")); break; + case 0xd9: my_stprintf_s(buffer, buffer_len, _T("ret")); break; + case 0xda: my_stprintf_s(buffer, buffer_len, _T("jc %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xdb: my_stprintf_s(buffer, buffer_len, _T("in $%02x"), oprom[ptr++]); break; + case 0xdc: my_stprintf_s(buffer, buffer_len, _T("cc %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xdd: my_stprintf_s(buffer, buffer_len, _T("call %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xde: my_stprintf_s(buffer, buffer_len, _T("sbi $%02x"), oprom[ptr++]); break; + case 0xdf: my_stprintf_s(buffer, buffer_len, _T("rst 3")); break; + case 0xe0: my_stprintf_s(buffer, buffer_len, _T("rpo")); break; + case 0xe1: my_stprintf_s(buffer, buffer_len, _T("pop h")); break; + case 0xe2: my_stprintf_s(buffer, buffer_len, _T("jpo %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xe3: my_stprintf_s(buffer, buffer_len, _T("xthl")); break; + case 0xe4: my_stprintf_s(buffer, buffer_len, _T("cpo %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xe5: my_stprintf_s(buffer, buffer_len, _T("push h")); break; + case 0xe6: my_stprintf_s(buffer, buffer_len, _T("ani $%02x"), oprom[ptr++]); break; + case 0xe7: my_stprintf_s(buffer, buffer_len, _T("rst 4")); break; + case 0xe8: my_stprintf_s(buffer, buffer_len, _T("rpe")); break; + case 0xe9: my_stprintf_s(buffer, buffer_len, _T("PChl")); break; + case 0xea: my_stprintf_s(buffer, buffer_len, _T("jpe %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xeb: my_stprintf_s(buffer, buffer_len, _T("xchg")); break; + case 0xec: my_stprintf_s(buffer, buffer_len, _T("cpe %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xed: + if(oprom[ptr] == 0xed) { + my_stprintf_s(buffer, buffer_len, _T("calln $%02x"), oprom[ptr + 1]); + } else if(oprom[ptr] == 0xfd) { + my_stprintf_s(buffer, buffer_len, _T("retem")); + } else { + my_stprintf_s(buffer, buffer_len, _T("call %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); + } + ptr += 2; + break; + case 0xee: my_stprintf_s(buffer, buffer_len, _T("xri $%02x"), oprom[ptr++]); break; + case 0xef: my_stprintf_s(buffer, buffer_len, _T("rst 5")); break; + case 0xf0: my_stprintf_s(buffer, buffer_len, _T("rp")); break; + case 0xf1: my_stprintf_s(buffer, buffer_len, _T("pop a")); break; + case 0xf2: my_stprintf_s(buffer, buffer_len, _T("jp %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xf3: my_stprintf_s(buffer, buffer_len, _T("di")); break; + case 0xf4: my_stprintf_s(buffer, buffer_len, _T("cp %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xf5: my_stprintf_s(buffer, buffer_len, _T("push a")); break; + case 0xf6: my_stprintf_s(buffer, buffer_len, _T("ori $%02x"), oprom[ptr++]); break; + case 0xf7: my_stprintf_s(buffer, buffer_len, _T("rst 6")); break; + case 0xf8: my_stprintf_s(buffer, buffer_len, _T("rm")); break; + case 0xf9: my_stprintf_s(buffer, buffer_len, _T("sphl")); break; + case 0xfa: my_stprintf_s(buffer, buffer_len, _T("jm %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xfb: my_stprintf_s(buffer, buffer_len, _T("ei")); break; + case 0xfc: my_stprintf_s(buffer, buffer_len, _T("cm %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xfd: my_stprintf_s(buffer, buffer_len, _T("cm %s"), get_value_or_symbol(debugger->first_symbol, _T("$%04x"), oprom[ptr] | (oprom[ptr + 1] << 8))); ptr += 2; break; + case 0xfe: my_stprintf_s(buffer, buffer_len, _T("cpi $%02x"), oprom[ptr++]); break; + case 0xff: my_stprintf_s(buffer, buffer_len, _T("rst 7")); break; + } + return ptr; +} diff --git a/source/src/vm/v30_dasm.h b/source/src/vm/v30_dasm.h new file mode 100644 index 000000000..f5a3b9d06 --- /dev/null +++ b/source/src/vm/v30_dasm.h @@ -0,0 +1,20 @@ +/* + Skelton for retropc emulator + + Origin : MAME V30 core + Author : Takeda.Toshiya + Date : 2020.02.02- + + [ V30 disassembler ] +*/ + +#ifndef _V30_DASM_H_ +#define _V30_DASM_H_ + +#include "../common.h" + +class DEBUGGER; + +int DLL_PREFIX v30_dasm(DEBUGGER *debugger, uint8_t *oprom, uint32_t eip, bool emulation_mode, _TCHAR *buffer, size_t buffer_len); + +#endif diff --git a/source/src/vm/v9938.cpp b/source/src/vm/v9938.cpp index cf3869f44..222b776b3 100644 --- a/source/src/vm/v9938.cpp +++ b/source/src/vm/v9938.cpp @@ -94,7 +94,7 @@ at most 192 KiB RAM (128 KiB base, 64 KiB expansion). //v99x8_device::v99x8_device(const machine_config &mconfig, device_type type, const char *name, const char *shortname, const char *tag, device_t *owner, UINT32 clock) //: device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__), -v99x8_device::v99x8_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) +v99x8_device::v99x8_device(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu), // device_memory_interface(mconfig, *this), // device_video_interface(mconfig, *this), @@ -132,7 +132,7 @@ v99x8_device::v99x8_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) //v9938_device::v9938_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) //: v99x8_device(mconfig, V9938, "V9938 VDP", "v9938", tag, owner, clock) -v9938_device::v9938_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) +v9938_device::v9938_device(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : v99x8_device(parent_vm, parent_emu) { m_model = MODEL_V9938; @@ -142,7 +142,7 @@ v9938_device::v9938_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) //v9958_device::v9958_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) //: v99x8_device(mconfig, V9938, "V9958 VDP", "v9958", tag, owner, clock) -v9958_device::v9958_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) +v9958_device::v9958_device(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : v99x8_device(parent_vm, parent_emu) { m_model = MODEL_V9958; diff --git a/source/src/vm/v9938.h b/source/src/vm/v9938.h index cbaab0c4a..81f267c56 100644 --- a/source/src/vm/v9938.h +++ b/source/src/vm/v9938.h @@ -74,14 +74,14 @@ // ======================> v99x8_device -class v99x8_device : public DEVICE +class DLL_PREFIX v99x8_device : public DEVICE { protected: int __SCREEN_WIDTH; int __SCREEN_HEIGHT; // construction/destruction //v99x8_device(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu){} - v99x8_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); + v99x8_device(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); public: //template void set_interrupt_callback(_irq irq) { @@ -324,10 +324,10 @@ class v99x8_device : public DEVICE }; -class v9938_device : public v99x8_device +class DLL_PREFIX v9938_device : public v99x8_device { public: - v9938_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); + v9938_device(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); //DECLARE_PALETTE_INIT(v9938); protected: @@ -335,10 +335,10 @@ class v9938_device : public v99x8_device void init_palette(); }; -class v9958_device : public v99x8_device +class DLL_PREFIX v9958_device : public v99x8_device { public: - v9958_device(VM_TEMPLATE* parent_vm, EMU* parent_emu); + v9958_device(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu); //DECLARE_PALETTE_INIT(v9958); diff --git a/source/src/vm/v99x8.h b/source/src/vm/v99x8.h index 2b106432c..eca6262e1 100644 --- a/source/src/vm/v99x8.h +++ b/source/src/vm/v99x8.h @@ -161,7 +161,7 @@ class V99X8 : public DEVICE void __FASTCALL v99x8_refresh_scx(int y, int h); public: - V99X8(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + V99X8(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_irq); set_device_name(_T("V99x8 VDP")); diff --git a/source/src/vm/vm.h b/source/src/vm/vm.h index 10726ad12..dc9b617af 100644 --- a/source/src/vm/vm.h +++ b/source/src/vm/vm.h @@ -150,6 +150,13 @@ #include "fmtowns/fmtowns.h" #endif +#if defined(_FMTOWNS2_HG20) || defined(_FMTOWNS2_HG40) || defined(_FMTOWNS2_HG100) +#include "fmtowns/fmtowns.h" +#endif + +#if defined(_FMTOWNS2_HR20) || defined(_FMTOWNS2_HR100) || defined(_FMTOWNS2_HR200) +#include "fmtowns/fmtowns.h" +#endif // CASIO FP-200 #ifdef _FP200 #include "fp200/fp200.h" @@ -235,6 +242,11 @@ #include "gamegear/mastersystem.h" #endif +// Nippon Mail Service MICOM MAHJONG +#ifdef _MICOM_MAHJONG +#include "micom_mahjong/micom_mahjong.h" +#endif + // ASCII MSX #ifdef _MSX1 //#include "msx/msx.h" @@ -558,6 +570,11 @@ #include "smc777/smc777.h" #endif +// SPECTRAVIDEO SVI-3x8 +#ifdef _SVI3X8 +#include "svi3x8/msx_ex.h" +#endif + // NEC TK-80BS (COMPO BS/80) #ifdef _TK80BS #include "tk80bs/tk80bs.h" @@ -573,6 +590,11 @@ #include "tk80bs/tk80bs.h" #endif +// GAKKEN TV BOY +#ifdef _TVBOY +#include "tvboy/tvboy.h" +#endif + // CANON X-07 #ifdef _X07 #include "x07/x07.h" diff --git a/source/src/vm/vm_template.h b/source/src/vm/vm_template.h index f7001e6ef..61e036964 100644 --- a/source/src/vm/vm_template.h +++ b/source/src/vm/vm_template.h @@ -3,19 +3,20 @@ #include "common.h" -class EMU; +class EMU_TEMPLATE; class EVENT; class DEVICE; +class FILEIO; class DLL_PREFIX VM_TEMPLATE { protected: - EMU* emu; + EMU_TEMPLATE* emu; // devices EVENT* event; #if defined(__GIT_REPO_VERSION) _TCHAR _git_revision[256]; #endif public: - VM_TEMPLATE(EMU* parent_emu) : emu(parent_emu) + VM_TEMPLATE(EMU_TEMPLATE* parent_emu) : emu(parent_emu) { emu = parent_emu; #if defined(__GIT_REPO_VERSION) @@ -25,7 +26,7 @@ class DLL_PREFIX VM_TEMPLATE { virtual ~VM_TEMPLATE() {} // OK? // drive virtual machine virtual void reset() { } - virtual void special_reset() { } + virtual void special_reset(int num) { } virtual void run() { } virtual void notify_power_off() { } @@ -37,7 +38,6 @@ class DLL_PREFIX VM_TEMPLATE { // debugger virtual DEVICE *get_cpu(int num) { return NULL; } - virtual uint32_t get_cpu_pc() { return 0; } virtual void initialize(void) { } virtual void update_dipswitch(void) { } @@ -93,7 +93,7 @@ class DLL_PREFIX VM_TEMPLATE { virtual void close_floppy_disk(int drv) { } virtual void close_quick_disk(int drv) { } virtual void close_hard_disk(int drv) { } - virtual void close_compact_disc() { } + virtual void close_compact_disc(int drv) { } virtual void close_laser_disc(int drv) { } virtual void close_bubble_casette(int drv) { } virtual void close_cart(int drv) { } @@ -105,6 +105,9 @@ class DLL_PREFIX VM_TEMPLATE { virtual uint32_t is_compact_disc_accessed() { return 0; } virtual uint32_t is_laser_disc_accessed() { return 0; } + virtual bool is_floppy_disk_connected(int drv) { return true; } + virtual bool is_quick_disk_connected(int drv) { return true; } + virtual bool is_floppy_disk_inserted(int drv) { return false; } virtual bool is_quick_disk_inserted(int drv) { return false; } virtual bool is_hard_disk_inserted(int drv) { return false; } @@ -160,6 +163,13 @@ class DLL_PREFIX VM_TEMPLATE { virtual uint32_t get_vk_by_scancode(uint32_t scancode) { return 0xffffffff; } + virtual double get_current_usec() { + return 0.0; + } + virtual uint64_t get_current_clock_uint64() { + return (uint64_t)0; + } + DEVICE* dummy; DEVICE* first_device; DEVICE* last_device; diff --git a/source/src/vm/w3100a.h b/source/src/vm/w3100a.h index a8f63849d..8cfede5f8 100644 --- a/source/src/vm/w3100a.h +++ b/source/src/vm/w3100a.h @@ -29,7 +29,7 @@ class W3100A : public DEVICE void process_status(uint16_t addr); public: - W3100A(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) { + W3100A(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("W3100A TCP/IP")); } ~W3100A() {} diff --git a/source/src/vm/x07/CMakeLists.txt b/source/src/vm/x07/CMakeLists.txt index ee34d5a59..2d3caff7f 100644 --- a/source/src/vm/x07/CMakeLists.txt +++ b/source/src/vm/x07/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/x07") +message("* vm/emux07") -add_library(vm_x07 +add_library(vm_emux07 x07.cpp io.cpp ) diff --git a/source/src/vm/x07/io.h b/source/src/vm/x07/io.h index 4a877db5f..08add3707 100644 --- a/source/src/vm/x07/io.h +++ b/source/src/vm/x07/io.h @@ -90,7 +90,7 @@ class IO : public DEVICE int register_id_beep; public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } @@ -102,7 +102,7 @@ class IO : public DEVICE void reset(); void event_frame(); void event_vline(int v, int clock); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/x07/x07.cpp b/source/src/vm/x07/x07.cpp index 6b5c432b9..2461c404d 100644 --- a/source/src/vm/x07/x07.cpp +++ b/source/src/vm/x07/x07.cpp @@ -27,7 +27,7 @@ using X07::IO; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -37,6 +37,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) beep = new BEEP(this, emu); memory = new MEMORY(this, emu); + cpu = new Z80(this, emu); io = new IO(this, emu); @@ -235,6 +236,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -247,7 +260,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/x07/x07.h b/source/src/vm/x07/x07.h index 1a2f9252f..f298c071a 100644 --- a/source/src/vm/x07/x07.h +++ b/source/src/vm/x07/x07.h @@ -91,7 +91,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -135,6 +135,9 @@ class VM : public VM_TEMPLATE bool is_tape_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/x1/CMakeLists.txt b/source/src/vm/x1/CMakeLists.txt index e527064ba..e573ca459 100644 --- a/source/src/vm/x1/CMakeLists.txt +++ b/source/src/vm/x1/CMakeLists.txt @@ -1,20 +1,45 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/x1") +message("* vm/${EXE_NAME}") -add_library(vm_x1 - display.cpp - emm.cpp - floppy.cpp -# io.cpp - iobus.cpp - joystick.cpp - keyboard.cpp - memory.cpp - mouse.cpp - psub.cpp - sasi.cpp - sub.cpp - - x1.cpp -) +if(${EXE_NAME} STREQUAL emux1twin) + add_library(vm_${EXE_NAME} + display.cpp + emm.cpp + floppy.cpp + iobus.cpp + joystick.cpp + keyboard.cpp + memory.cpp + mouse.cpp + psub.cpp + sasi.cpp + sub.cpp + + ../mcs48.cpp + ../mz1p17.cpp + ../scsi_host.cpp + + ../pcengine/pce.cpp + ../huc6280.cpp + x1.cpp + ) +else() + add_library(vm_${EXE_NAME} + display.cpp + emm.cpp + floppy.cpp + iobus.cpp + joystick.cpp + keyboard.cpp + memory.cpp + mouse.cpp + psub.cpp + sasi.cpp + sub.cpp + ../mcs48.cpp + ../mz1p17.cpp + ../scsi_host.cpp + x1.cpp + ) +endif() diff --git a/source/src/vm/x1/display.cpp b/source/src/vm/x1/display.cpp index e61ba5b83..668fa24f3 100644 --- a/source/src/vm/x1/display.cpp +++ b/source/src/vm/x1/display.cpp @@ -84,8 +84,8 @@ void DISPLAY::initialize() #ifdef _X1TURBOZ for(int i = 0; i < 8; i++) { ztpal[i] = ((i & 1) ? 0x03 : 0) | ((i & 2) ? 0x0c : 0) | ((i & 4) ? 0x30 : 0); - zpalette_pc[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text - zpalette_pc[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // digital + zpalette_tmp[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text + zpalette_tmp[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // digital } for(int g = 0; g < 16; g++) { for(int r = 0; r < 16; r++) { @@ -94,10 +94,11 @@ void DISPLAY::initialize() zpal[num].b = b; zpal[num].r = r; zpal[num].g = g; - zpalette_pc[num + 16] = RGB_COLOR((r * 255) / 15, (g * 255) / 15, (b * 255) / 15); + zpalette_tmp[num + 16] = RGB_COLOR((r * 255) / 15, (g * 255) / 15, (b * 255) / 15); } } } + zpalette_changed = true; #endif // initialize regs @@ -158,6 +159,9 @@ void DISPLAY::reset() mode1 = 0;//3; mode2 = 0; hireso = true; + emu->set_vm_screen_lines(400); +#else + emu->set_vm_screen_lines(200); #endif #ifdef _X1TURBOZ zmode1 = 0; @@ -214,8 +218,11 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); } int num = get_zpal_num(addr, data); - zpal[num].b = data & 0x0f; - zpalette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15); + if(zpal[num].b != data & 0x0f) { + zpal[num].b = data & 0x0f; + zpalette_tmp[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15); + zpalette_changed = true; + } } else if(APEN && APRD) { zpal_num = get_zpal_num(addr, data); } @@ -235,8 +242,11 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); } int num = get_zpal_num(addr, data); - zpal[num].r = data & 0x0f; - zpalette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15); + if(zpal[num].r != data & 0x0f) { + zpal[num].r = data & 0x0f; + zpalette_tmp[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15); + zpalette_changed = true; + } } else if(APEN && APRD) { // zpal_num = get_zpal_num(addr, data); } @@ -256,8 +266,11 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) d_cpu->write_signal(SIG_CPU_BUSREQ, 1, 1); } int num = get_zpal_num(addr, data); - zpal[num].g = data & 0x0f; - zpalette_pc[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15); + if(zpal[num].g != data & 0x0f) { + zpal[num].g = data & 0x0f; + zpalette_tmp[num + 16] = RGB_COLOR((zpal[num].r * 255) / 15, (zpal[num].g * 255) / 15, (zpal[num].b * 255) / 15); + zpalette_changed = true; + } } else if(APEN && APRD) { // zpal_num = get_zpal_num(addr, data); } @@ -309,8 +322,11 @@ void DISPLAY::write_io8(uint32_t addr, uint32_t data) case 0x1fbe: case 0x1fbf: if(AEN) { - ztpal[addr & 7] = data; - zpalette_pc[addr & 7] = RGB_COLOR((((data >> 2) & 3) * 255) / 3, (((data >> 4) & 3) * 255) / 3, (((data >> 0) & 3) * 255) / 3); + if(ztpal[addr & 7] != data) { + ztpal[addr & 7] = data; + zpalette_tmp[addr & 7] = RGB_COLOR((((data >> 2) & 3) * 255) / 3, (((data >> 4) & 3) * 255) / 3, (((data >> 0) & 3) * 255) / 3); + zpalette_changed = true; + } } break; case 0x1fc0: @@ -584,14 +600,17 @@ void DISPLAY::event_frame() hz_disp = regs[1]; vt_disp = regs[6] & 0x7f; st_addr = (regs[12] << 8) | regs[13]; - #ifdef _X1TURBO_FEATURE int vt_total = ((regs[4] & 0x7f) + 1) * ch_height + (regs[5] & 0x1f); - hireso = (vt_total > 400); + bool hireso_old = hireso; + hireso = (vt_total >= 400); #endif int vlen; #ifdef _X1TURBO_FEATURE vlen = (hireso) ? 400 : 200; +// if(hireso_old != hireso) { +// emu->set_vm_screen_lines(vlen); +// } #else vlen = 200; #endif @@ -634,6 +653,12 @@ void DISPLAY::event_frame() void DISPLAY::event_vline(int v, int clock) { +#ifdef _X1TURBOZ + if(zpalette_changed && v == (hireso ? 400 : 200)) { + update_zpalette(); + zpalette_changed = false; + } +#endif cur_vline = v; #if 0 @@ -816,9 +841,7 @@ void DISPLAY::get_cur_code_line() int addr = (hz_total * (clock % ht_clock)) / ht_clock; addr += hz_disp * (int)(vt_line / ch_height); - if(addr > 0x7ff) { - addr = 0x7ff; - } + addr &= 0x7ff; // thanks Mr.YAT addr += st_addr; cur_code = vram_t[addr & 0x7ff]; @@ -857,23 +880,20 @@ void DISPLAY::draw_screen() #endif draw_line(v); } - } - - // copy to real screen #ifdef _X1TURBOZ - dr_zpalette_pc[8 + 0] = dr_zpalette_pc[16 + 0x000]; - dr_zpalette_pc[8 + 1] = dr_zpalette_pc[16 + 0x00f]; - dr_zpalette_pc[8 + 2] = dr_zpalette_pc[16 + 0x0f0]; - dr_zpalette_pc[8 + 3] = dr_zpalette_pc[16 + 0x0ff]; - dr_zpalette_pc[8 + 4] = dr_zpalette_pc[16 + 0xf00]; - dr_zpalette_pc[8 + 5] = dr_zpalette_pc[16 + 0xf0f]; - dr_zpalette_pc[8 + 6] = dr_zpalette_pc[16 + 0xff0]; - dr_zpalette_pc[8 + 7] = dr_zpalette_pc[16 + 0xfff]; + if(zpalette_changed && cur_vline < (hireso ? 400 : 200)) { + update_zpalette(); + zpalette_changed = false; + } #endif + } + + // copy to real screen + __DECL_ALIGNED(16) scrntype_t dbuf[640]; #ifdef _X1TURBO_FEATURE if(hireso) { // 400 lines - emu->set_vm_screen_lines(400); +// emu->set_vm_screen_lines(400); if(column40) { // 40 columns for(int y = 0; y < 400; y++) { @@ -886,7 +906,7 @@ void DISPLAY::draw_screen() for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) { uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2); - dest[x2] = dest[x2 + 1] = get_zpriority(src_text[x], cg00, cg00); + dbuf[x2] = dbuf[x2 + 1] = get_zpriority(src_text[x], cg00, cg00); } } else { #endif @@ -894,14 +914,18 @@ void DISPLAY::draw_screen() for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) { #ifdef _X1TURBOZ - dest[x2] = dest[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x2] = dbuf[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #else - dest[x2] = dest[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x2] = dbuf[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #endif } #ifdef _X1TURBOZ } #endif +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 640; xx++) { + dest[xx] = dbuf[xx]; + } } } else { // 80 columns @@ -915,7 +939,7 @@ void DISPLAY::draw_screen() for(int x = 0; x < 640; x++) { uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2); - dest[x] = get_zpriority(src_text[x], cg00, cg00); + dbuf[x] = get_zpriority(src_text[x], cg00, cg00); } } else { #endif @@ -923,29 +947,33 @@ void DISPLAY::draw_screen() for(int x = 0; x < 640; x++) { #ifdef _X1TURBOZ - dest[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #else - dest[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #endif } #ifdef _X1TURBOZ } #endif +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 640; xx++) { + dest[xx] = dbuf[xx]; + } } } emu->screen_skip_line(false); } else { #endif - emu->set_vm_screen_lines(200); +// emu->set_vm_screen_lines(200); // 200 lines - emu->set_vm_screen_lines(200); +// emu->set_vm_screen_lines(200); if(column40) { // 40 columns for(int y = 0; y < 200; y++) { + uint8_t* src_text = dr_text[y]; scrntype_t* dest0 = emu->get_screen_buffer(y * 2 + 0); scrntype_t* dest1 = emu->get_screen_buffer(y * 2 + 1); - uint8_t* src_text = dr_text[y]; #ifdef _X1TURBOZ if(dr_aen_line[y]) { uint16_t* src_cg0 = dr_zcg[0][y]; @@ -956,32 +984,40 @@ void DISPLAY::draw_screen() uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2); uint16_t cg11 = src_cg1[x] | (src_cg1[x] >> 2); - dest0[x2] = dest0[x2 + 1] = get_zpriority(src_text[x], cg00, cg11); + dbuf[x2] = dbuf[x2 + 1] = get_zpriority(src_text[x], cg00, cg11); } } else { for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) { uint16_t cg01 = src_cg0[x] | (src_cg1[x] >> 2); - dest0[x2] = dest0[x2 + 1] = get_zpriority(src_text[x], cg01, cg01); + dbuf[x2] = dbuf[x2 + 1] = get_zpriority(src_text[x], cg01, cg01); } + } } else { #endif - scrntype_t* dest = emu->get_screen_buffer(y); +// scrntype_t* dest = emu->get_screen_buffer(y); uint8_t* src_cg = dr_cg[y]; for(int x = 0, x2 = 0; x < 320; x++, x2 += 2) { #ifdef _X1TURBOZ - dest0[x2] = dest0[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x2] = dbuf[x2 + 1] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #else - dest0[x2] = dest0[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x2] = dbuf[x2 + 1] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #endif } #ifdef _X1TURBOZ } #endif +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 640; xx++) { + dest0[xx] = dbuf[xx]; + } if(!config.scan_line) { - my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t)); +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 640; xx++) { + dest1[xx] = dbuf[xx]; + } } else { memset(dest1, 0, 640 * sizeof(scrntype_t)); } @@ -999,34 +1035,40 @@ void DISPLAY::draw_screen() for(int x = 0; x < 640; x++) { uint16_t cg00 = src_cg0[x] | (src_cg0[x] >> 2); - dest0[x] = get_zpriority(src_text[x], cg00, cg00); + dbuf[x] = get_zpriority(src_text[x], cg00, cg00); } } else { #endif uint8_t* src_cg = dr_cg[y]; - +__DECL_VECTORIZED_LOOP for(int x = 0; x < 640; x++) { #ifdef _X1TURBOZ - dest0[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x] = dr_zpalette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #else - dest0[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; + dbuf[x] = dr_palette_pc[dr_pri_line[y][src_cg[x]][src_text[x]]]; #endif } +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 640; xx++) { + dest0[xx] = dbuf[xx]; + } + if(!config.scan_line) { +__DECL_VECTORIZED_LOOP + for(int xx = 0; xx < 640; xx++) { + dest1[xx] = dbuf[xx]; + } + } else { + memset(dest1, 0, 640 * sizeof(scrntype_t)); + } #ifdef _X1TURBOZ } #endif - if(!config.scan_line) { - my_memcpy(dest1, dest0, 640 * sizeof(scrntype_t)); - } else { - memset(dest1, 0, 640 * sizeof(scrntype_t)); - } } } emu->screen_skip_line(true); #ifdef _X1TURBO_FEATURE } #endif - } void DISPLAY::draw_text(int y) @@ -1337,6 +1379,29 @@ int DISPLAY::get_zpal_num(uint32_t addr, uint32_t data) return num; } +void DISPLAY::update_zpalette() +{ + memcpy(zpalette_pc, zpalette_tmp, sizeof(zpalette_pc)); + zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000]; + zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f]; + zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0]; + zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff]; + zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00]; + zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f]; + zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0]; + zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff]; + + dr_zpalette_pc[8 + 0] = dr_zpalette_pc[16 + 0x000]; + dr_zpalette_pc[8 + 1] = dr_zpalette_pc[16 + 0x00f]; + dr_zpalette_pc[8 + 2] = dr_zpalette_pc[16 + 0x0f0]; + dr_zpalette_pc[8 + 3] = dr_zpalette_pc[16 + 0x0ff]; + dr_zpalette_pc[8 + 4] = dr_zpalette_pc[16 + 0xf00]; + dr_zpalette_pc[8 + 5] = dr_zpalette_pc[16 + 0xf0f]; + dr_zpalette_pc[8 + 6] = dr_zpalette_pc[16 + 0xff0]; + dr_zpalette_pc[8 + 7] = dr_zpalette_pc[16 + 0xfff]; + +} + scrntype_t DISPLAY::get_zpriority(uint8_t text, uint16_t cg0, uint16_t cg1) { if((mode2 & 8) && (text == (mode2 & 7))) { @@ -1618,7 +1683,7 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading) state_fio->StateValue(zpal[i].b); } state_fio->StateValue(zpal_num); - state_fio->StateArrayScrnType_t(zpalette_pc, sizeof(zpalette_pc), 1); + state_fio->StateArrayScrnType_t(zpalette_tmp, sizeof(zpalette_tmp), 1); #endif state_fio->StateValue(prev_vert_double); state_fio->StateValue(raster); @@ -1633,6 +1698,9 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading) // post process if(loading) { +#ifdef _X1TURBOZ + zpalette_changed = true; +#endif for(int i = 0; i < 8; i++) { palette_pc[i ] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // text palette_pc[i + 8] = RGB_COLOR((i & 2) ? 255 : 0, (i & 4) ? 255 : 0, (i & 1) ? 255 : 0); // cg @@ -1653,18 +1721,11 @@ bool DISPLAY::process_state(FILEIO* state_fio, bool loading) my_memcpy(dr_palette_pc, palette_pc, sizeof(dr_palette_pc)); dr_priority = priority; #ifdef _X1TURBOZ + // ToDo: Chack save/load. dr_zpriority = zpriority; my_memcpy(dr_zcg, zcg, sizeof(dr_zcg)); my_memcpy(dr_aen_line, aen_line, sizeof(dr_aen_line)); - my_memcpy(dr_zpalette_pc, zpalette_pc, sizeof(zpalette_pc)); - zpalette_pc[8 + 0] = zpalette_pc[16 + 0x000]; - zpalette_pc[8 + 1] = zpalette_pc[16 + 0x00f]; - zpalette_pc[8 + 2] = zpalette_pc[16 + 0x0f0]; - zpalette_pc[8 + 3] = zpalette_pc[16 + 0x0ff]; - zpalette_pc[8 + 4] = zpalette_pc[16 + 0xf00]; - zpalette_pc[8 + 5] = zpalette_pc[16 + 0xf0f]; - zpalette_pc[8 + 6] = zpalette_pc[16 + 0xff0]; - zpalette_pc[8 + 7] = zpalette_pc[16 + 0xfff]; + my_memcpy(dr_zpalette_pc, zpalette_tmp, sizeof(zpalette_tmp)); #endif update_crtc(); // force update timing } diff --git a/source/src/vm/x1/display.h b/source/src/vm/x1/display.h index 960fa3326..1c56d2d41 100644 --- a/source/src/vm/x1/display.h +++ b/source/src/vm/x1/display.h @@ -34,22 +34,22 @@ class DISPLAY : public DEVICE #endif HD46505 *d_crtc; uint8_t* regs; - uint8_t vram_t[0x800]; - uint8_t vram_a[0x800]; + __DECL_ALIGNED(16) uint8_t vram_t[0x800]; + __DECL_ALIGNED(16) uint8_t vram_a[0x800]; #ifdef _X1TURBO_FEATURE - uint8_t vram_k[0x800]; + __DECL_ALIGNED(16) uint8_t vram_k[0x800]; #endif uint8_t* vram_ptr; - uint8_t pcg_b[256][8]; - uint8_t pcg_r[256][8]; - uint8_t pcg_g[256][8]; + __DECL_ALIGNED(8) uint8_t pcg_b[256][8]; + __DECL_ALIGNED(8) uint8_t pcg_r[256][8]; + __DECL_ALIGNED(8) uint8_t pcg_g[256][8]; #ifdef _X1TURBO_FEATURE - uint8_t gaiji_b[128][16]; - uint8_t gaiji_r[128][16]; - uint8_t gaiji_g[128][16]; + __DECL_ALIGNED(16) uint8_t gaiji_b[128][16]; + __DECL_ALIGNED(16) uint8_t gaiji_r[128][16]; + __DECL_ALIGNED(16) uint8_t gaiji_g[128][16]; #endif - uint8_t font[0x800]; - uint8_t kanji[0x4bc00]; + __DECL_ALIGNED(16) uint8_t font[0x800]; + __DECL_ALIGNED(16) uint8_t kanji[0x4bc00]; uint8_t cur_code, cur_line; @@ -57,7 +57,8 @@ class DISPLAY : public DEVICE uint8_t* kanji_ptr; uint8_t pal[3]; - uint8_t priority, pri[8][8]; // pri[cg][txt] + uint8_t priority; + __DECL_ALIGNED(32) uint8_t pri[8][8]; // pri[cg][txt] uint8_t dr_priority; bool column40; @@ -76,41 +77,42 @@ class DISPLAY : public DEVICE uint8_t ztpal[8]; uint8_t dr_zpriority; - struct { + __DECL_ALIGNED(32) struct { uint8_t b, r, g; } zpal[4096]; int zpal_num; #endif #ifdef _X1TURBO_FEATURE - uint8_t text[400][640]; - uint8_t cg[400][640]; - uint8_t pri_line[400][8][8]; + __DECL_ALIGNED(32) uint8_t text[400][640]; + __DECL_ALIGNED(32) uint8_t cg[400][640]; + __DECL_ALIGNED(32) uint8_t pri_line[400][8][8]; - - uint8_t dr_text[400][640]; - uint8_t dr_cg[400][640]; - uint8_t dr_pri_line[400][8][8]; + __DECL_ALIGNED(32) uint8_t dr_text[400][640]; + __DECL_ALIGNED(32) uint8_t dr_cg[400][640]; + __DECL_ALIGNED(32) uint8_t dr_pri_line[400][8][8]; #else - uint8_t text[200][640+8]; - uint8_t cg[200][640]; - uint8_t pri_line[200][8][8]; + __DECL_ALIGNED(32) uint8_t text[200][640+8]; + __DECL_ALIGNED(32) uint8_t cg[200][640]; + __DECL_ALIGNED(32) uint8_t pri_line[200][8][8]; - uint8_t dr_text[200][640+8]; - uint8_t dr_cg[200][640]; - uint8_t dr_pri_line[200][8][8]; + __DECL_ALIGNED(32) uint8_t dr_text[200][640+8]; + __DECL_ALIGNED(32) uint8_t dr_cg[200][640]; + __DECL_ALIGNED(32) uint8_t dr_pri_line[200][8][8]; #endif #ifdef _X1TURBOZ - uint16_t zcg[2][400][640]; - bool aen_line[400]; - scrntype_t zpalette_pc[8+8+4096]; // 0-7:text, 8-15:cg, 16-:4096cg - - uint16_t dr_zcg[2][400][640]; - bool dr_aen_line[400]; - scrntype_t dr_zpalette_pc[8+8+4096]; // 0-7:text, 8-15:cg, 16-:4096cg + bool zpalette_changed; + __DECL_ALIGNED(32) uint16_t zcg[2][400][640]; + __DECL_ALIGNED(16) bool aen_line[400]; + __DECL_ALIGNED(32) scrntype_t zpalette_tmp[8+8+4096]; + __DECL_ALIGNED(32) scrntype_t zpalette_pc[8+8+4096]; // 0-7:text, 8-15:cg, 16-:4096cg + + __DECL_ALIGNED(32) uint16_t dr_zcg[2][400][640]; + __DECL_ALIGNED(16) bool dr_aen_line[400]; + __DECL_ALIGNED(32) scrntype_t dr_zpalette_pc[8+8+4096]; // 0-7:text, 8-15:cg, 16-:4096cg #endif - scrntype_t palette_pc[8+8]; // 0-7:text, 8-15:cg - scrntype_t dr_palette_pc[8+8]; // 0-7:text, 8-15:cg + __DECL_ALIGNED(16) scrntype_t palette_pc[8+8]; // 0-7:text, 8-15:cg + __DECL_ALIGNED(16) scrntype_t dr_palette_pc[8+8]; // 0-7:text, 8-15:cg bool prev_vert_double; int raster, cblink; @@ -127,12 +129,13 @@ class DISPLAY : public DEVICE void __FASTCALL get_cur_pcg(uint32_t addr); void __FASTCALL get_cur_code_line(); - void draw_line(int v); - void draw_text(int y); - void draw_cg(int line, int plane); + void __FASTCALL draw_line(int v); + void __FASTCALL draw_text(int y); + void __FASTCALL draw_cg(int line, int plane); #ifdef _X1TURBOZ int __FASTCALL get_zpal_num(uint32_t addr, uint32_t data); + void update_zpalette(); scrntype_t __FASTCALL get_zpriority(uint8_t text, uint16_t cg0, uint16_t cg1); #endif @@ -150,11 +153,11 @@ class DISPLAY : public DEVICE int tmp_kanji_ptr; - _bit_trans_table_t bit_trans_table_b0; - _bit_trans_table_t bit_trans_table_r0; - _bit_trans_table_t bit_trans_table_g0; + __DECL_ALIGNED(16) _bit_trans_table_t bit_trans_table_b0; + __DECL_ALIGNED(16) _bit_trans_table_t bit_trans_table_r0; + __DECL_ALIGNED(16) _bit_trans_table_t bit_trans_table_g0; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } @@ -169,7 +172,7 @@ class DISPLAY : public DEVICE void event_frame(); void event_vline(int v, int clock); #ifdef _X1TURBO_FEATURE - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); #endif bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/x1/emm.h b/source/src/vm/x1/emm.h index d20622951..ba59a9026 100644 --- a/source/src/vm/x1/emm.h +++ b/source/src/vm/x1/emm.h @@ -28,7 +28,7 @@ class EMM : public DEVICE uint32_t data_addr; public: - EMM(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + EMM(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("EMM")); } diff --git a/source/src/vm/x1/floppy.h b/source/src/vm/x1/floppy.h index c0e144dc1..cbd8f3ddf 100644 --- a/source/src/vm/x1/floppy.h +++ b/source/src/vm/x1/floppy.h @@ -33,7 +33,7 @@ class FLOPPY : public DEVICE int register_id; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { prev = 0; motor_on = false; @@ -47,7 +47,7 @@ class FLOPPY : public DEVICE #ifdef _X1TURBO_FEATURE uint32_t __FASTCALL read_io8(uint32_t addr); #endif - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // unique functions diff --git a/source/src/vm/x1/iobus.cpp b/source/src/vm/x1/iobus.cpp index 4c5ba85a3..958b584bd 100644 --- a/source/src/vm/x1/iobus.cpp +++ b/source/src/vm/x1/iobus.cpp @@ -32,6 +32,7 @@ void IOBUS::initialize() { prev_clock = vram_wait_index = 0; column40 = true; + memset(vram, 0, sizeof(vram)); #ifdef USE_DEBUGGER d_debugger->set_device_name(_T("Debugger (I/O Bus)")); d_debugger->set_context_mem(this); @@ -41,7 +42,6 @@ void IOBUS::initialize() void IOBUS::reset() { - memset(vram, 0, sizeof(vram)); vram_ofs_b = 0x0000; vram_ofs_r = 0x4000; vram_ofs_g = 0x8000; diff --git a/source/src/vm/x1/iobus.h b/source/src/vm/x1/iobus.h index 5564eb7ce..004369c61 100644 --- a/source/src/vm/x1/iobus.h +++ b/source/src/vm/x1/iobus.h @@ -64,7 +64,7 @@ class IOBUS : public DEVICE int get_vram_wait(); public: - IOBUS(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IOBUS(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { #ifdef USE_DEBUGGER d_debugger = NULL; diff --git a/source/src/vm/x1/joystick.h b/source/src/vm/x1/joystick.h index 43355e9de..4df0a8419 100644 --- a/source/src/vm/x1/joystick.h +++ b/source/src/vm/x1/joystick.h @@ -26,7 +26,7 @@ class JOYSTICK : public DEVICE const uint32_t* joy_stat; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/x1/keyboard.h b/source/src/vm/x1/keyboard.h index 844a18cbb..88b4658f3 100644 --- a/source/src/vm/x1/keyboard.h +++ b/source/src/vm/x1/keyboard.h @@ -28,7 +28,7 @@ class KEYBOARD : public DEVICE uint16_t column; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/x1/memory.h b/source/src/vm/x1/memory.h index 7863d9ec9..636867a14 100644 --- a/source/src/vm/x1/memory.h +++ b/source/src/vm/x1/memory.h @@ -41,7 +41,7 @@ class MEMORY : public DEVICE void __FASTCALL update_map(); public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/x1/mouse.h b/source/src/vm/x1/mouse.h index c75916b5a..0ed85bda9 100644 --- a/source/src/vm/x1/mouse.h +++ b/source/src/vm/x1/mouse.h @@ -30,7 +30,7 @@ class MOUSE : public DEVICE const int32_t* stat; public: - MOUSE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MOUSE(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Mouse I/F")); } diff --git a/source/src/vm/x1/psub.cpp b/source/src/vm/x1/psub.cpp index 2db5af5df..f2cb20281 100644 --- a/source/src/vm/x1/psub.cpp +++ b/source/src/vm/x1/psub.cpp @@ -669,6 +669,7 @@ void PSUB::process_cmd() if(play) { new_status = CMT_STOP; } else if(rec) { + d_drec->set_ff_rew(0); d_drec->set_remote(true); } else { new_status = CMT_EJECT; @@ -690,7 +691,8 @@ void PSUB::process_cmd() break; case 0xeb: // CMT sensor (bit2=WP, bit1=SET, bit0=END) - databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | (play && eot ? 1 : 0); +// databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | (play && eot ? 1 : 0); + databuf[0x1b][0] = (play ? 2 : rec ? 6 : 0) | ((play || rec) && !eot ? 1 : 0); datalen = 1; break; case 0xec: diff --git a/source/src/vm/x1/psub.h b/source/src/vm/x1/psub.h index 0cc94fa40..b6fe5e1b7 100644 --- a/source/src/vm/x1/psub.h +++ b/source/src/vm/x1/psub.h @@ -53,13 +53,13 @@ class PSUB : public DEVICE int tmp_datap; void update_intr(); void process_cmd(); - void set_ibf(bool val); - void set_obf(bool val); + void __FASTCALL set_ibf(bool val); + void __FASTCALL set_obf(bool val); uint8_t get_key_low(); - uint16_t get_key(int code, bool repeat); + uint16_t __FASTCALL get_key(int code, bool repeat); public: - PSUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + PSUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Pseudo Sub System")); } @@ -72,7 +72,7 @@ class PSUB : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // interrupt common functions @@ -81,7 +81,7 @@ class PSUB : public DEVICE d_cpu = device; intr_bit = bit; } - void set_intr_iei(bool val); + void __FASTCALL set_intr_iei(bool val); uint32_t get_intr_ack(); void notify_intr_reti(); diff --git a/source/src/vm/x1/sasi.h b/source/src/vm/x1/sasi.h index 5497c98b3..fd1c4e7e0 100644 --- a/source/src/vm/x1/sasi.h +++ b/source/src/vm/x1/sasi.h @@ -34,7 +34,7 @@ class SASI : public DEVICE bool drq_status; public: - SASI(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SASI(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("SASI I/F")); } diff --git a/source/src/vm/x1/sub.cpp b/source/src/vm/x1/sub.cpp index 23577c019..c5871618a 100644 --- a/source/src/vm/x1/sub.cpp +++ b/source/src/vm/x1/sub.cpp @@ -114,6 +114,11 @@ void SUB::write_io8(uint32_t addr, uint32_t data) d_drec->set_ff_rew(0); d_drec->set_remote(true); } + if(!(p2_out & 0x02) && (data & 0x02)) { + if(rom_crc32 == CRC32_MSM80C49_262) { + d_drec->set_remote(false); + } + } if((p2_out & 0x04) && !(data & 0x04)) { d_drec->set_ff_rew(1); d_drec->set_remote(true); @@ -122,7 +127,7 @@ void SUB::write_io8(uint32_t addr, uint32_t data) d_drec->set_ff_rew(-1); d_drec->set_remote(true); } - if((p2_out & 0x10) && !(data & 0x10)) { + if(!(p2_out & 0x10) && (data & 0x10)) { d_drec->set_remote(false); } intr = ((data & 0x40) == 0); @@ -214,18 +219,19 @@ void SUB::update_tape() { if(rom_crc32 != CRC32_MSM80C49_277) { uint32_t value = 0x10; - if(!(tape_play && tape_eot)) { +// if(!(tape_play && tape_eot)) { + if((tape_play || tape_rec) && !tape_eot) { value |= 0x01; // tape end } if(tape_play || tape_rec) { value |= 0x02; // cassette inserted } - if(rom_crc32 == CRC32_MSM80C49_262) { - value ^= 0x02; // X1F/G or X1turbo - } - if(tape_play) { + if(tape_rec) { value |= 0x04; // rec protected } + if(rom_crc32 == CRC32_MSM80C49_262) { + value ^= 0x06; // X1F/G or X1turbo + } if(tape_play && tape_apss) { value |= 0x20; } diff --git a/source/src/vm/x1/sub.h b/source/src/vm/x1/sub.h index 51023ea21..1cdf124a1 100644 --- a/source/src/vm/x1/sub.h +++ b/source/src/vm/x1/sub.h @@ -46,7 +46,7 @@ class SUB : public DEVICE void update_intr(); public: - SUB(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SUB(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Sub System")); } @@ -65,7 +65,7 @@ class SUB : public DEVICE d_cpu = device; intr_bit = bit; } - void set_intr_iei(bool val); + void __FASTCALL set_intr_iei(bool val); uint32_t get_intr_ack(); void notify_intr_reti(); diff --git a/source/src/vm/x1/x1.cpp b/source/src/vm/x1/x1.cpp index 7dbe1216b..07bc53945 100644 --- a/source/src/vm/x1/x1.cpp +++ b/source/src/vm/x1/x1.cpp @@ -83,7 +83,7 @@ using PCEDEV::PCE; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { pseudo_sub_cpu = !(FILEIO::IsFileExisting(create_local_path(SUB_ROM_FILE_NAME)) && FILEIO::IsFileExisting(create_local_path(KBD_ROM_FILE_NAME))); @@ -111,7 +111,9 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) sasi_hdd[i] = new SASI_HDD(this, emu); sasi_hdd[i]->set_device_name(_T("SASI Hard Disk Drive #%d"), i + 1); sasi_hdd[i]->scsi_id = i; - sasi_hdd[i]->bytes_per_sec = 32 * 1024; // 32KB/s +// sasi_hdd[i]->bytes_per_sec = 32 * 1024; // 32KB/s + sasi_hdd[i]->bytes_per_sec = 3600 / 60 * 256 * 33; // 3600rpm, 256bytes x 33sectors in track (thanks Mr.Sato) + sasi_hdd[i]->data_req_delay = 0; // thanks Mr.Sato sasi_hdd[i]->set_context_interface(sasi_host); sasi_host->set_context_target(sasi_hdd[i]); } @@ -547,7 +549,7 @@ void VM::reset() psg->set_reg(0x2e, 0); // set prescaler } -void VM::special_reset() +void VM::special_reset(int num) { // nmi reset cpu->write_signal(SIG_CPU_NMI, 1, 1); @@ -1004,6 +1006,18 @@ void VM::update_dipswitch() } #endif +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 12 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -1016,7 +1030,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { return false; } diff --git a/source/src/vm/x1/x1.h b/source/src/vm/x1/x1.h index 3f05f2835..2feb4f2d6 100644 --- a/source/src/vm/x1/x1.h +++ b/source/src/vm/x1/x1.h @@ -84,7 +84,7 @@ #endif // device informations for win32 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #ifdef _X1TURBO_FEATURE #define USE_KEYBOARD_TYPE 2 // Keyboard mode B @@ -355,7 +355,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -364,7 +364,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate(); @@ -426,6 +426,10 @@ class VM : public VM_TEMPLATE #ifdef _X1TURBO_FEATURE void update_dipswitch(); #endif + + double get_current_usec(); + uint64_t get_current_clock_uint64(); + bool process_state(FILEIO* state_fio, bool loading); // ---------------------------------------- diff --git a/source/src/vm/yalky/CMakeLists.txt b/source/src/vm/yalky/CMakeLists.txt index 38fe53950..f12262df6 100644 --- a/source/src/vm/yalky/CMakeLists.txt +++ b/source/src/vm/yalky/CMakeLists.txt @@ -2,7 +2,8 @@ cmake_minimum_required (VERSION 2.6) message("* vm/yalky") -add_library(vm_yalky +add_library(vm_emuyalky + ../i8080.cpp io.cpp yalky.cpp -) \ No newline at end of file +) diff --git a/source/src/vm/yalky/io.h b/source/src/vm/yalky/io.h index 8cf0e97cd..21ef038e3 100644 --- a/source/src/vm/yalky/io.h +++ b/source/src/vm/yalky/io.h @@ -42,7 +42,7 @@ class IO : public DEVICE void update_key(); public: - IO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + IO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("I/O Bus")); } @@ -54,7 +54,7 @@ class IO : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void event_frame(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/yalky/yalky.cpp b/source/src/vm/yalky/yalky.cpp index db4d77243..1ce0f6c40 100644 --- a/source/src/vm/yalky/yalky.cpp +++ b/source/src/vm/yalky/yalky.cpp @@ -29,7 +29,7 @@ using YALKY::IO; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { config.sound_play_tape = false; config.wave_shaper[0] = false; @@ -131,7 +131,7 @@ void VM::reset() memset(vram, 0, sizeof(vram)); } -void VM::special_reset() +void VM::special_reset(int num) { cpu->reset(); } @@ -298,6 +298,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 4 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -310,7 +322,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/yalky/yalky.h b/source/src/vm/yalky/yalky.h index 42b594e01..c33c26a7a 100644 --- a/source/src/vm/yalky/yalky.h +++ b/source/src/vm/yalky/yalky.h @@ -29,7 +29,7 @@ #define MEMORY_BANK_SIZE 0x100 // device informations for win32 -#define USE_SPECIAL_RESET +#define USE_SPECIAL_RESET 1 #define USE_TAPE 1 #define USE_AUTO_KEY 5 #define USE_AUTO_KEY_RELEASE 6 @@ -86,7 +86,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -95,7 +95,7 @@ class VM : public VM_TEMPLATE // drive virtual machine void reset(); - void special_reset(); + void special_reset(int num); void run(); double get_frame_rate() { @@ -135,6 +135,9 @@ class VM : public VM_TEMPLATE void push_apss_rewind(int drv) {} bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/yis/CMakeLists.txt b/source/src/vm/yis/CMakeLists.txt index 76df745bc..5eeebd196 100644 --- a/source/src/vm/yis/CMakeLists.txt +++ b/source/src/vm/yis/CMakeLists.txt @@ -1,13 +1,17 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/yis") +message("* vm/emuyis") -add_library(vm_yis +add_library(vm_emuyis + ../m6502.cpp + ../msm58321.cpp + calendar.cpp display.cpp floppy.cpp keyboard.cpp mapper.cpp sound.cpp + yis.cpp -) \ No newline at end of file +) diff --git a/source/src/vm/yis/calendar.h b/source/src/vm/yis/calendar.h index 071aac472..d50f8b58e 100644 --- a/source/src/vm/yis/calendar.h +++ b/source/src/vm/yis/calendar.h @@ -22,7 +22,7 @@ class CALENDAR : public DEVICE DEVICE* d_rtc; public: - CALENDAR(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + CALENDAR(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("RTC I/F")); } diff --git a/source/src/vm/yis/display.h b/source/src/vm/yis/display.h index d854a09ec..e16c1c5cb 100644 --- a/source/src/vm/yis/display.h +++ b/source/src/vm/yis/display.h @@ -80,7 +80,7 @@ class DISPLAY : public DEVICE void __FASTCALL draw_char(int x, int y, int pow, int rot, int code); public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Display")); } diff --git a/source/src/vm/yis/floppy.h b/source/src/vm/yis/floppy.h index 831ef5acf..4f7f6c4df 100644 --- a/source/src/vm/yis/floppy.h +++ b/source/src/vm/yis/floppy.h @@ -22,7 +22,7 @@ class FLOPPY : public DEVICE DEVICE* d_fdc; public: - FLOPPY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + FLOPPY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Floppy I/F")); } diff --git a/source/src/vm/yis/keyboard.h b/source/src/vm/yis/keyboard.h index b2ae8d792..9aeeb3638 100644 --- a/source/src/vm/yis/keyboard.h +++ b/source/src/vm/yis/keyboard.h @@ -28,7 +28,7 @@ class KEYBOARD : public DEVICE bool kana_locked; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/yis/mapper.h b/source/src/vm/yis/mapper.h index 274a146f5..6acd0990e 100644 --- a/source/src/vm/yis/mapper.h +++ b/source/src/vm/yis/mapper.h @@ -31,7 +31,7 @@ class MAPPER : public DEVICE void __FASTCALL update_bank(int num); public: - MAPPER(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MAPPER(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Mapper")); } diff --git a/source/src/vm/yis/sound.h b/source/src/vm/yis/sound.h index 7bcfa65cc..f28f41f48 100644 --- a/source/src/vm/yis/sound.h +++ b/source/src/vm/yis/sound.h @@ -24,7 +24,7 @@ class SOUND : public DEVICE BEEP* d_beep; public: - SOUND(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + SOUND(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Sound I/F")); } diff --git a/source/src/vm/yis/yis.cpp b/source/src/vm/yis/yis.cpp index 6833fc3db..fc5a910e4 100644 --- a/source/src/vm/yis/yis.cpp +++ b/source/src/vm/yis/yis.cpp @@ -46,7 +46,7 @@ using YIS::SOUND; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -56,6 +56,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) cpu = new M6502(this, emu); // YM-2002 io = new IO(this, emu); memory = new MEMORY(this, emu); + apu = new AM9511(this, emu); beep = new BEEP(this, emu); #ifdef USE_DEBUGGER @@ -308,6 +309,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -320,7 +333,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/yis/yis.h b/source/src/vm/yis/yis.h index 4bf8585b9..5b3c8db63 100644 --- a/source/src/vm/yis/yis.h +++ b/source/src/vm/yis/yis.h @@ -127,7 +127,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -173,6 +173,9 @@ class VM : public VM_TEMPLATE uint32_t is_floppy_disk_accessed(); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/ym2151.h b/source/src/vm/ym2151.h index 6455c7c53..0676072be 100644 --- a/source/src/vm/ym2151.h +++ b/source/src/vm/ym2151.h @@ -22,10 +22,8 @@ #define SIG_YM2151_MUTE 0 -class VM; -class EMU; class DEBUGGER; -class YM2151 : public DEVICE +class DLL_PREFIX YM2151 : public DEVICE { private: // output signals @@ -60,7 +58,7 @@ class YM2151 : public DEVICE void update_interrupt(); public: - YM2151(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + YM2151(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { initialize_output_signals(&outputs_irq); base_decibel = 0; @@ -77,8 +75,8 @@ class YM2151 : public DEVICE uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); void event_vline(int v, int clock); - void event_callback(int event_id, int error); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int event_id, int error); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); // for debugging diff --git a/source/src/vm/ym2203.h b/source/src/vm/ym2203.h index f715a8aa8..c09281b7f 100644 --- a/source/src/vm/ym2203.h +++ b/source/src/vm/ym2203.h @@ -39,7 +39,7 @@ class DEBUGGER; -class YM2203 : public DEVICE +class DLL_PREFIX YM2203 : public DEVICE { private: DEBUGGER *d_debugger; @@ -100,7 +100,7 @@ class YM2203 : public DEVICE void update_interrupt(); //#endif public: - YM2203(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + YM2203(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { base_decibel_fm = base_decibel_psg = 0; decibel_vol = 0 + 5; @@ -128,8 +128,8 @@ class YM2203 : public DEVICE void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int id); void event_vline(int v, int clock); - void event_callback(int event_id, int error); - void mix(int32_t* buffer, int cnt); + void __FASTCALL event_callback(int event_id, int error); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int _ch, int decibel_l, int decibel_r); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame); // for debugging diff --git a/source/src/vm/ym2413.h b/source/src/vm/ym2413.h index 8737b83de..29d2fcab9 100644 --- a/source/src/vm/ym2413.h +++ b/source/src/vm/ym2413.h @@ -20,9 +20,7 @@ typedef INT16 SAMP; typedef void (*OPLL_UPDATEHANDLER)(int param,int min_interval_us); void YM2413SetUpdateHandler(int which, OPLL_UPDATEHANDLER UpdateHandler, int param); -class VM; -class EMU; -class YM2413 : public DEVICE +class DLL_PREFIX YM2413 : public DEVICE { private: uint8_t latch; @@ -34,7 +32,7 @@ class YM2413 : public DEVICE bool __MSX; public: - YM2413(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + YM2413(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { volume_l = volume_r = 1024; __MSX = false; @@ -49,7 +47,7 @@ class YM2413 : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void mix(int32_t* buffer, int cnt); + void __FASTCALL mix(int32_t* buffer, int cnt); void set_volume(int ch, int decibel_l, int decibel_r); // unique functions void initialize_sound(int rate, int clock, int samples); diff --git a/source/src/vm/ys6464a/CMakeLists.txt b/source/src/vm/ys6464a/CMakeLists.txt index a456d3099..d5edbcad5 100644 --- a/source/src/vm/ys6464a/CMakeLists.txt +++ b/source/src/vm/ys6464a/CMakeLists.txt @@ -2,8 +2,8 @@ cmake_minimum_required (VERSION 2.6) message("* vm/ys6464a") -add_library(vm_ys6464a +add_library(vm_emuys6464a display.cpp keyboard.cpp ys6464a.cpp -) \ No newline at end of file +) diff --git a/source/src/vm/ys6464a/display.h b/source/src/vm/ys6464a/display.h index 3461bafb1..6767688a0 100644 --- a/source/src/vm/ys6464a/display.h +++ b/source/src/vm/ys6464a/display.h @@ -26,7 +26,7 @@ class DISPLAY : public DEVICE uint8_t pb, pc; public: - DISPLAY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + DISPLAY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("7-Segment LEDs")); } diff --git a/source/src/vm/ys6464a/keyboard.h b/source/src/vm/ys6464a/keyboard.h index c87c02bc9..d96aaff84 100644 --- a/source/src/vm/ys6464a/keyboard.h +++ b/source/src/vm/ys6464a/keyboard.h @@ -25,7 +25,7 @@ class KEYBOARD : public DEVICE const uint8_t* key_stat; public: - KEYBOARD(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + KEYBOARD(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Keyboard")); } diff --git a/source/src/vm/ys6464a/ys6464a.cpp b/source/src/vm/ys6464a/ys6464a.cpp index 07a0e321a..cdcef85ee 100644 --- a/source/src/vm/ys6464a/ys6464a.cpp +++ b/source/src/vm/ys6464a/ys6464a.cpp @@ -32,7 +32,7 @@ using YS6464A::KEYBOARD; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -42,6 +42,7 @@ VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) io = new IO(this, emu); pio = new I8255(this, emu); memory = new MEMORY(this, emu); + // pcm = new PCM1BIT(this, emu); cpu = new Z80(this, emu); @@ -208,6 +209,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -220,7 +233,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/ys6464a/ys6464a.h b/source/src/vm/ys6464a/ys6464a.h index a0c9d845a..3d760707b 100644 --- a/source/src/vm/ys6464a/ys6464a.h +++ b/source/src/vm/ys6464a/ys6464a.h @@ -115,7 +115,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -144,6 +144,9 @@ class VM : public VM_TEMPLATE void save_binary(int drv, const _TCHAR* file_path); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/vm/z80.cpp b/source/src/vm/z80.cpp index f8d5980cf..47a548bb8 100644 --- a/source/src/vm/z80.cpp +++ b/source/src/vm/z80.cpp @@ -8,16 +8,16 @@ [ Z80 ] */ -#include "vm.h" -#include "../emu.h" +#include "vm_template.h" +#include "../emu_template.h" #include "z80.h" -#ifdef USE_DEBUGGER +//#ifdef USE_DEBUGGER #include "debugger.h" -#endif +//#endif -#ifndef CPU_START_ADDR -#define CPU_START_ADDR 0 -#endif +//#ifndef CPU_START_ADDR +//#define CPU_START_ADDR 0 +//#endif #define NMI_REQ_BIT 0x80000000 @@ -102,6 +102,28 @@ } \ } while(0) +// opecode definitions + +#define ENTER_HALT() do { \ + PC--; \ + after_halt = true; \ +} while(0) + +#define LEAVE_HALT() do { \ + if(after_halt) { \ + after_halt = false; \ + PC++; \ + } \ +} while(0) + +#define UPDATE_EXTRA_EVENT(clock) do { \ + if(is_primary) { \ + if(busreq) { \ + busreq_icount += (clock); \ + } \ + update_extra_event(clock); \ + } \ +} while(0) #define POP(DR) do { \ RM16(SPD, &DR); \ @@ -113,47 +135,1933 @@ WM16(SPD, &SR); \ } while(0) -// main -Z80::Z80(VM_TEMPLATE* parent_vm, EMU* parent_emu) : Z80_BASE(parent_vm, parent_emu) +Z80_INLINE uint8_t __FASTCALL Z80::RM8(uint32_t addr) { -#ifdef HAS_NSC800 - has_nsc800 = true; -#endif -#ifdef Z80_PSEUDO_BIOS - has_pseudo_bios = true; -#endif -#ifdef SINGLE_MODE_DMA - has_single_mode_dma = true; -#endif -#ifdef Z80_MEMORY_WAIT - has_memory_wait = true; -#endif -#ifdef Z80_IO_WAIT - has_io_wait = true; +//#ifdef Z80_MEMORY_WAIT + UPDATE_EXTRA_EVENT(1); + if(has_memory_wait) { + int wait; + uint8_t val = d_mem->read_data8w(addr, &wait); + icount -= wait; + UPDATE_EXTRA_EVENT(2 + wait); + return val; + } else { +//#else + uint8_t val = d_mem->read_data8(addr); + UPDATE_EXTRA_EVENT(2); + return val; + } +//#endif +} + +Z80_INLINE void __FASTCALL Z80::WM8(uint32_t addr, uint8_t val) +{ +//#ifdef Z80_MEMORY_WAIT + UPDATE_EXTRA_EVENT(1); + if(has_memory_wait) { + int wait; + d_mem->write_data8w(addr, val, &wait); + icount -= wait; + UPDATE_EXTRA_EVENT(2 + wait); + } else { +//#else + d_mem->write_data8(addr, val); + UPDATE_EXTRA_EVENT(2); + } +//#endif +} + +Z80_INLINE void __FASTCALL Z80::RM16(uint32_t addr, pair32_t *r) +{ + r->b.l = RM8(addr); + r->b.h = RM8((addr + 1) & 0xffff); +} + +Z80_INLINE void __FASTCALL Z80::WM16(uint32_t addr, pair32_t *r) +{ + WM8(addr, r->b.l); + WM8((addr + 1) & 0xffff, r->b.h); +} + +Z80_INLINE uint8_t __FASTCALL Z80::FETCHOP() +{ + unsigned pctmp = PCD; + PC++; + R++; + + // consider m1 cycle wait + UPDATE_EXTRA_EVENT(1); + int wait; + uint8_t val = d_mem->fetch_op(pctmp, &wait); + icount -= wait; + UPDATE_EXTRA_EVENT(3 + wait); + return val; +} + +Z80_INLINE uint8_t __FASTCALL Z80::FETCH8() +{ + unsigned pctmp = PCD; + PC++; + return RM8(pctmp); +} + +Z80_INLINE uint32_t __FASTCALL Z80::FETCH16() +{ + unsigned pctmp = PCD; + PC += 2; + return RM8(pctmp) | ((uint32_t)RM8((pctmp + 1) & 0xffff) << 8); +} + +Z80_INLINE uint8_t __FASTCALL Z80::IN8(uint32_t addr) +{ +//#ifdef Z80_IO_WAIT + UPDATE_EXTRA_EVENT(2); + if(has_io_wait) { + int wait; + uint8_t val = d_io->read_io8w(addr, &wait); + icount -= wait; + UPDATE_EXTRA_EVENT(2 + wait); + return val; + } else { +//#else + uint8_t val = d_io->read_io8(addr); + UPDATE_EXTRA_EVENT(2); + return val; + } +//#endif +} + +Z80_INLINE void __FASTCALL Z80::OUT8(uint32_t addr, uint8_t val) +{ +//#ifdef HAS_NSC800 + UPDATE_EXTRA_EVENT(2); + if(has_nsc800) { + if((addr & 0xff) == 0xbb) { + icr = val; + UPDATE_EXTRA_EVENT(2); + return; + } + } +//#endif +//#ifdef Z80_IO_WAIT + if(has_io_wait) { + int wait; + d_io->write_io8w(addr, val, &wait); + icount -= wait; + UPDATE_EXTRA_EVENT(2 + wait); + } else { +//#else + d_io->write_io8(addr, val); + UPDATE_EXTRA_EVENT(2); + } +//#endif +} + +#define EAX() do { \ + ea = (uint32_t)(uint16_t)(IX + (int8_t)FETCH8()); \ + WZ = ea; \ +} while(0) + +#define EAY() do { \ + ea = (uint32_t)(uint16_t)(IY + (int8_t)FETCH8()); \ + WZ = ea; \ +} while(0) + +#define POP(DR) do { \ + RM16(SPD, &DR); \ + SP += 2; \ +} while(0) + +#define PUSH(SR) do { \ + SP -= 2; \ + WM16(SPD, &SR); \ +} while(0) + +#define JP() do { \ + PCD = FETCH16(); \ + WZ = PCD; \ +} while(0) + +#define JP_COND(cond) do { \ + if(cond) { \ + PCD = FETCH16(); \ + WZ = PCD; \ + } else { \ + WZ = FETCH16(); /* implicit do PC += 2 */ \ + } \ +} while(0) + +#define JR() do { \ + int8_t arg = (int8_t)FETCH8(); /* FETCH8() also increments PC */ \ + PC += arg; /* so don't do PC += FETCH8() */ \ + WZ = PC; \ +} while(0) + +#define JR_COND(cond, opcode) do { \ + if(cond) { \ + JR(); \ + icount -= cc_ex[opcode]; \ + } else FETCH8(); \ +} while(0) + +#define CALL() do { \ + ea = FETCH16(); \ + WZ = ea; \ + PUSH(pc); \ + PCD = ea; \ +} while(0) + +#define CALL_COND(cond, opcode) do { \ + if(cond) { \ + ea = FETCH16(); \ + WZ = ea; \ + PUSH(pc); \ + PCD = ea; \ + icount -= cc_ex[opcode]; \ + } else { \ + WZ = FETCH16(); /* implicit call PC+=2; */ \ + } \ +} while(0) + +#define RET_COND(cond, opcode) do { \ + if(cond) { \ + POP(pc); \ + WZ = PC; \ + icount -= cc_ex[opcode]; \ + } \ +} while(0) + +#define RETN() do { \ + POP(pc); \ + WZ = PC; \ + iff1 = iff2; \ +} while(0) + +#define RETI() do { \ + POP(pc); \ + WZ = PC; \ + iff1 = iff2; \ + if(d_pic != NULL) d_pic->notify_intr_reti(); \ +} while(0) + +#define LD_R_A() do { \ + R = A; \ + R2 = A & 0x80; /* keep bit 7 of r */ \ +} while(0) + +#define LD_A_R() do { \ + A = (R & 0x7f) | R2; \ + F = (F & CF) | SZ[A] | (iff2 << 2); \ + after_ldair = true; \ +} while(0) + +#define LD_I_A() do { \ + I = A; \ +} while(0) + +#define LD_A_I() do { \ + A = I; \ + F = (F & CF) | SZ[A] | (iff2 << 2); \ + after_ldair = true; \ +} while(0) + +#define RST(addr) do { \ + PUSH(pc); \ + PCD = addr; \ + WZ = PC; \ +} while(0) + +Z80_INLINE uint8_t __FASTCALL Z80::INC(uint8_t value) +{ + uint8_t res = value + 1; + F = (F & CF) | SZHV_inc[res]; + return (uint8_t)res; +} + +Z80_INLINE uint8_t Z80::DEC(uint8_t value) +{ + uint8_t res = value - 1; + F = (F & CF) | SZHV_dec[res]; + return res; +} + +#define RLCA() do { \ + A = (A << 1) | (A >> 7); \ + F = (F & (SF | ZF | PF)) | (A & (YF | XF | CF)); \ +} while(0) + +#define RRCA() do { \ + F = (F & (SF | ZF | PF)) | (A & CF); \ + A = (A >> 1) | (A << 7); \ + F |= (A & (YF | XF)); \ +} while(0) + +#define RLA() do { \ + uint8_t res = (A << 1) | (F & CF); \ + uint8_t c = (A & 0x80) ? CF : 0; \ + F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ + A = res; \ +} while(0) + +#define RRA() do { \ + uint8_t res = (A >> 1) | (F << 7); \ + uint8_t c = (A & 0x01) ? CF : 0; \ + F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ + A = res; \ +} while(0) + +#define RRD() do { \ + uint8_t n = RM8(HL); \ + WZ = HL + 1; \ + WM8(HL, (n >> 4) | (A << 4)); \ + A = (A & 0xf0) | (n & 0x0f); \ + F = (F & CF) | SZP[A]; \ +} while(0) + +#define RLD() do { \ + uint8_t n = RM8(HL); \ + WZ = HL + 1; \ + WM8(HL, (n << 4) | (A & 0x0f)); \ + A = (A & 0xf0) | (n >> 4); \ + F = (F & CF) | SZP[A]; \ +} while(0) + +#define ADD(value) do { \ + uint32_t ah = AFD & 0xff00; \ + uint32_t res = (uint8_t)((ah >> 8) + value); \ + F = SZHVC_add[ah | res]; \ + A = res; \ +} while(0) + +#define ADC(value) do { \ + uint32_t ah = AFD & 0xff00, c = AFD & 1; \ + uint32_t res = (uint8_t)((ah >> 8) + value + c); \ + F = SZHVC_add[(c << 16) | ah | res]; \ + A = res; \ +} while(0) + +#define SUB(value) do { \ + uint32_t ah = AFD & 0xff00; \ + uint32_t res = (uint8_t)((ah >> 8) - value); \ + F = SZHVC_sub[ah | res]; \ + A = res; \ +} while(0) + +#define SBC(value) do { \ + uint32_t ah = AFD & 0xff00, c = AFD & 1; \ + uint32_t res = (uint8_t)((ah >> 8) - value - c); \ + F = SZHVC_sub[(c << 16) | ah | res]; \ + A = res; \ +} while(0) + +#define NEG() do { \ + uint8_t value = A; \ + A = 0; \ + SUB(value); \ +} while(0) + +#define DAA() do { \ + uint8_t a = A; \ + if(F & NF) { \ + if((F & HF) | ((A & 0xf) > 9)) a -= 6; \ + if((F & CF) | (A > 0x99)) a -= 0x60; \ + } else { \ + if((F & HF) | ((A & 0xf) > 9)) a += 6; \ + if((F & CF) | (A > 0x99)) a += 0x60; \ + } \ + F = (F & (CF | NF)) | (A > 0x99) | ((A ^ a) & HF) | SZP[a]; \ + A = a; \ +} while(0) + +#define AND(value) do { \ + A &= value; \ + F = SZP[A] | HF; \ +} while(0) + +#define OR(value) do { \ + A |= value; \ + F = SZP[A]; \ +} while(0) + +#define XOR(value) do { \ + A ^= value; \ + F = SZP[A]; \ +} while(0) + +#define CP(value) do { \ + unsigned val = value; \ + uint32_t ah = AFD & 0xff00; \ + uint32_t res = (uint8_t)((ah >> 8) - val); \ + F = (SZHVC_sub[ah | res] & ~(YF | XF)) | (val & (YF | XF)); \ +} while(0) + +#define EX_AF() do { \ + pair32_t tmp; \ + tmp = af; af = af2; af2 = tmp; \ +} while(0) + +#define EX_DE_HL() do { \ + pair32_t tmp; \ + tmp = de; de = hl; hl = tmp; \ +} while(0) + +#define EXX() do { \ + pair32_t tmp; \ + tmp = bc; bc = bc2; bc2 = tmp; \ + tmp = de; de = de2; de2 = tmp; \ + tmp = hl; hl = hl2; hl2 = tmp; \ +} while(0) + +#define EXSP(DR) do { \ + pair32_t tmp; \ + tmp.d = 0; \ + RM16(SPD, &tmp); \ + WM16(SPD, &DR); \ + DR = tmp; \ + WZ = DR.d; \ +} while(0) + +#define ADD16(DR, SR) do { \ + uint32_t res = DR.d + SR.d; \ + WZ = DR.d + 1; \ + F = (F & (SF | ZF | VF)) | (((DR.d ^ res ^ SR.d) >> 8) & HF) | ((res >> 16) & CF) | ((res >> 8) & (YF | XF)); \ + DR.w.l = (uint16_t)res; \ +} while(0) + +#define ADC16(Reg) do { \ + uint32_t res = HLD + Reg.d + (F & CF); \ + WZ = HL + 1; \ + F = (((HLD ^ res ^ Reg.d) >> 8) & HF) | ((res >> 16) & CF) | ((res >> 8) & (SF | YF | XF)) | ((res & 0xffff) ? 0 : ZF) | (((Reg.d ^ HLD ^ 0x8000) & (Reg.d ^ res) & 0x8000) >> 13); \ + HL = (uint16_t)res; \ +} while(0) + +#define SBC16(Reg) do { \ + uint32_t res = HLD - Reg.d - (F & CF); \ + WZ = HL + 1; \ + F = (((HLD ^ res ^ Reg.d) >> 8) & HF) | NF | ((res >> 16) & CF) | ((res >> 8) & (SF | YF | XF)) | ((res & 0xffff) ? 0 : ZF) | (((Reg.d ^ HLD) & (HLD ^ res) &0x8000) >> 13); \ + HL = (uint16_t)res; \ +} while(0) + +Z80_INLINE uint8_t __FASTCALL Z80::RLC(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | (res >> 7)) & 0xff; + F = SZP[res] | c; + return res; +} + +Z80_INLINE uint8_t __FASTCALL Z80::RRC(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (res << 7)) & 0xff; + F = SZP[res] | c; + return res; +} + +Z80_INLINE uint8_t __FASTCALL Z80::RL(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | (F & CF)) & 0xff; + F = SZP[res] | c; + return res; +} + +Z80_INLINE uint8_t __FASTCALL Z80::RR(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (F << 7)) & 0xff; + F = SZP[res] | c; + return res; +} + +Z80_INLINE uint8_t __FASTCALL Z80::SLA(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = (res << 1) & 0xff; + F = SZP[res] | c; + return res; +} + +Z80_INLINE uint8_t __FASTCALL Z80::SRA(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = ((res >> 1) | (res & 0x80)) & 0xff; + F = SZP[res] | c; + return res; +} + +Z80_INLINE uint8_t __FASTCALL Z80::SLL(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x80) ? CF : 0; + res = ((res << 1) | 0x01) & 0xff; + F = SZP[res] | c; + return res; +} + +Z80_INLINE uint8_t __FASTCALL Z80::SRL(uint8_t value) +{ + unsigned res = value; + unsigned c = (res & 0x01) ? CF : 0; + res = (res >> 1) & 0xff; + F = SZP[res] | c; + return res; +} + +#define BIT(bit, reg) do { \ + F = (F & CF) | HF | (SZ_BIT[reg & (1 << bit)] & ~(YF | XF)) | (reg & (YF | XF)); \ +} while(0) + +#define BIT_HL(bit, reg) do { \ + F = (F & CF) | HF | (SZ_BIT[reg & (1 << bit)] & ~(YF | XF)) | (WZ_H & (YF | XF)); \ +} while(0) + +#define BIT_XY(bit, reg) do { \ + F = (F & CF) | HF | (SZ_BIT[reg & (1 << bit)] & ~(YF | XF)) | ((ea >> 8) & (YF | XF)); \ +} while(0) + +Z80_INLINE uint8_t __FASTCALL Z80::RES(uint8_t bit, uint8_t value) +{ + return value & ~(1 << bit); +} + +Z80_INLINE uint8_t __FASTCALL Z80::SET(uint8_t bit, uint8_t value) +{ + return value | (1 << bit); +} + +#define LDI() do { \ + uint8_t io = RM8(HL); \ + WM8(DE, io); \ + F &= SF | ZF | CF; \ + if((A + io) & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ + if((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ + HL++; DE++; BC--; \ + if(BC) F |= VF; \ +} while(0) + +#define CPI() do { \ + uint8_t val = RM8(HL); \ + uint8_t res = A - val; \ + WZ++; \ + HL++; BC--; \ + F = (F & CF) | (SZ[res] & ~(YF | XF)) | ((A ^ val ^ res) & HF) | NF; \ + if(F & HF) res -= 1; \ + if(res & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ + if(res & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ + if(BC) F |= VF; \ +} while(0) + +#define INI() do { \ + unsigned t; \ + uint8_t io = IN8(BC); \ + WZ = BC + 1; \ + B--; \ + WM8(HL, io); \ + HL++; \ + F = SZ[B]; \ + t = (unsigned)((C + 1) & 0xff) + (unsigned)io; \ + if(io & SF) F |= NF; \ + if(t & 0x100) F |= HF | CF; \ + F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ +} while(0) + +#define OUTI() do { \ + unsigned t; \ + uint8_t io = RM8(HL); \ + B--; \ + WZ = BC + 1; \ + OUT8(BC, io); \ + HL++; \ + F = SZ[B]; \ + t = (unsigned)L + (unsigned)io; \ + if(io & SF) F |= NF; \ + if(t & 0x100) F |= HF | CF; \ + F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ +} while(0) + +#define LDD() do { \ + uint8_t io = RM8(HL); \ + WM8(DE, io); \ + F &= SF | ZF | CF; \ + if((A + io) & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ + if((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ + HL--; DE--; BC--; \ + if(BC) F |= VF; \ +} while(0) + +#define CPD() do { \ + uint8_t val = RM8(HL); \ + uint8_t res = A - val; \ + WZ--; \ + HL--; BC--; \ + F = (F & CF) | (SZ[res] & ~(YF | XF)) | ((A ^ val ^ res) & HF) | NF; \ + if(F & HF) res -= 1; \ + if(res & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ + if(res & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ + if(BC) F |= VF; \ +} while(0) + +#define IND() do { \ + unsigned t; \ + uint8_t io = IN8(BC); \ + WZ = BC - 1; \ + B--; \ + WM8(HL, io); \ + HL--; \ + F = SZ[B]; \ + t = ((unsigned)(C - 1) & 0xff) + (unsigned)io; \ + if(io & SF) F |= NF; \ + if(t & 0x100) F |= HF | CF; \ + F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ +} while(0) + +#define OUTD() do { \ + unsigned t; \ + uint8_t io = RM8(HL); \ + B--; \ + WZ = BC - 1; \ + OUT8(BC, io); \ + HL--; \ + F = SZ[B]; \ + t = (unsigned)L + (unsigned)io; \ + if(io & SF) F |= NF; \ + if(t & 0x100) F |= HF | CF; \ + F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ +} while(0) + +#define LDIR() do { \ + LDI(); \ + if(BC != 0) { \ + PC -= 2; \ + WZ = PC + 1; \ + icount -= cc_ex[0xb0]; \ + } \ +} while(0) + +#define CPIR() do { \ + CPI(); \ + if(BC != 0 && !(F & ZF)) { \ + PC -= 2; \ + WZ = PC + 1; \ + icount -= cc_ex[0xb1]; \ + } \ +} while(0) + +#define INIR() do { \ + INI(); \ + if(B != 0) { \ + PC -= 2; \ + icount -= cc_ex[0xb2]; \ + } \ +} while(0) + +#define OTIR() do { \ + OUTI(); \ + if(B != 0) { \ + PC -= 2; \ + icount -= cc_ex[0xb3]; \ + } \ +} while(0) + +#define LDDR() do { \ + LDD(); \ + if(BC != 0) { \ + PC -= 2; \ + WZ = PC + 1; \ + icount -= cc_ex[0xb8]; \ + } \ +} while(0) + +#define CPDR() do { \ + CPD(); \ + if(BC != 0 && !(F & ZF)) { \ + PC -= 2; \ + WZ = PC + 1; \ + icount -= cc_ex[0xb9]; \ + } \ +} while(0) + +#define INDR() do { \ + IND(); \ + if(B != 0) { \ + PC -= 2; \ + icount -= cc_ex[0xba]; \ + } \ +} while(0) + +#define OTDR() do { \ + OUTD(); \ + if(B != 0) { \ + PC -= 2; \ + icount -= cc_ex[0xbb]; \ + } \ +} while(0) + +#define EI() do { \ + iff1 = iff2 = 1; \ + after_ei = true; \ +} while(0) + +void Z80::OP_CB(uint8_t code) +{ + icount -= cc_cb[code]; + + switch(code) { + case 0x00: B = RLC(B); break; /* RLC B */ + case 0x01: C = RLC(C); break; /* RLC C */ + case 0x02: D = RLC(D); break; /* RLC D */ + case 0x03: E = RLC(E); break; /* RLC E */ + case 0x04: H = RLC(H); break; /* RLC H */ + case 0x05: L = RLC(L); break; /* RLC L */ + case 0x06: WM8(HL, RLC(RM8(HL))); break; /* RLC (HL) */ + case 0x07: A = RLC(A); break; /* RLC A */ + case 0x08: B = RRC(B); break; /* RRC B */ + case 0x09: C = RRC(C); break; /* RRC C */ + case 0x0a: D = RRC(D); break; /* RRC D */ + case 0x0b: E = RRC(E); break; /* RRC E */ + case 0x0c: H = RRC(H); break; /* RRC H */ + case 0x0d: L = RRC(L); break; /* RRC L */ + case 0x0e: WM8(HL, RRC(RM8(HL))); break; /* RRC (HL) */ + case 0x0f: A = RRC(A); break; /* RRC A */ + case 0x10: B = RL(B); break; /* RL B */ + case 0x11: C = RL(C); break; /* RL C */ + case 0x12: D = RL(D); break; /* RL D */ + case 0x13: E = RL(E); break; /* RL E */ + case 0x14: H = RL(H); break; /* RL H */ + case 0x15: L = RL(L); break; /* RL L */ + case 0x16: WM8(HL, RL(RM8(HL))); break; /* RL (HL) */ + case 0x17: A = RL(A); break; /* RL A */ + case 0x18: B = RR(B); break; /* RR B */ + case 0x19: C = RR(C); break; /* RR C */ + case 0x1a: D = RR(D); break; /* RR D */ + case 0x1b: E = RR(E); break; /* RR E */ + case 0x1c: H = RR(H); break; /* RR H */ + case 0x1d: L = RR(L); break; /* RR L */ + case 0x1e: WM8(HL, RR(RM8(HL))); break; /* RR (HL) */ + case 0x1f: A = RR(A); break; /* RR A */ + case 0x20: B = SLA(B); break; /* SLA B */ + case 0x21: C = SLA(C); break; /* SLA C */ + case 0x22: D = SLA(D); break; /* SLA D */ + case 0x23: E = SLA(E); break; /* SLA E */ + case 0x24: H = SLA(H); break; /* SLA H */ + case 0x25: L = SLA(L); break; /* SLA L */ + case 0x26: WM8(HL, SLA(RM8(HL))); break; /* SLA (HL) */ + case 0x27: A = SLA(A); break; /* SLA A */ + case 0x28: B = SRA(B); break; /* SRA B */ + case 0x29: C = SRA(C); break; /* SRA C */ + case 0x2a: D = SRA(D); break; /* SRA D */ + case 0x2b: E = SRA(E); break; /* SRA E */ + case 0x2c: H = SRA(H); break; /* SRA H */ + case 0x2d: L = SRA(L); break; /* SRA L */ + case 0x2e: WM8(HL, SRA(RM8(HL))); break; /* SRA (HL) */ + case 0x2f: A = SRA(A); break; /* SRA A */ + case 0x30: B = SLL(B); break; /* SLL B */ + case 0x31: C = SLL(C); break; /* SLL C */ + case 0x32: D = SLL(D); break; /* SLL D */ + case 0x33: E = SLL(E); break; /* SLL E */ + case 0x34: H = SLL(H); break; /* SLL H */ + case 0x35: L = SLL(L); break; /* SLL L */ + case 0x36: WM8(HL, SLL(RM8(HL))); break; /* SLL (HL) */ + case 0x37: A = SLL(A); break; /* SLL A */ + case 0x38: B = SRL(B); break; /* SRL B */ + case 0x39: C = SRL(C); break; /* SRL C */ + case 0x3a: D = SRL(D); break; /* SRL D */ + case 0x3b: E = SRL(E); break; /* SRL E */ + case 0x3c: H = SRL(H); break; /* SRL H */ + case 0x3d: L = SRL(L); break; /* SRL L */ + case 0x3e: WM8(HL, SRL(RM8(HL))); break; /* SRL (HL) */ + case 0x3f: A = SRL(A); break; /* SRL A */ + case 0x40: BIT(0, B); break; /* BIT 0,B */ + case 0x41: BIT(0, C); break; /* BIT 0,C */ + case 0x42: BIT(0, D); break; /* BIT 0,D */ + case 0x43: BIT(0, E); break; /* BIT 0,E */ + case 0x44: BIT(0, H); break; /* BIT 0,H */ + case 0x45: BIT(0, L); break; /* BIT 0,L */ + case 0x46: BIT_HL(0, RM8(HL)); break; /* BIT 0,(HL) */ + case 0x47: BIT(0, A); break; /* BIT 0,A */ + case 0x48: BIT(1, B); break; /* BIT 1,B */ + case 0x49: BIT(1, C); break; /* BIT 1,C */ + case 0x4a: BIT(1, D); break; /* BIT 1,D */ + case 0x4b: BIT(1, E); break; /* BIT 1,E */ + case 0x4c: BIT(1, H); break; /* BIT 1,H */ + case 0x4d: BIT(1, L); break; /* BIT 1,L */ + case 0x4e: BIT_HL(1, RM8(HL)); break; /* BIT 1,(HL) */ + case 0x4f: BIT(1, A); break; /* BIT 1,A */ + case 0x50: BIT(2, B); break; /* BIT 2,B */ + case 0x51: BIT(2, C); break; /* BIT 2,C */ + case 0x52: BIT(2, D); break; /* BIT 2,D */ + case 0x53: BIT(2, E); break; /* BIT 2,E */ + case 0x54: BIT(2, H); break; /* BIT 2,H */ + case 0x55: BIT(2, L); break; /* BIT 2,L */ + case 0x56: BIT_HL(2, RM8(HL)); break; /* BIT 2,(HL) */ + case 0x57: BIT(2, A); break; /* BIT 2,A */ + case 0x58: BIT(3, B); break; /* BIT 3,B */ + case 0x59: BIT(3, C); break; /* BIT 3,C */ + case 0x5a: BIT(3, D); break; /* BIT 3,D */ + case 0x5b: BIT(3, E); break; /* BIT 3,E */ + case 0x5c: BIT(3, H); break; /* BIT 3,H */ + case 0x5d: BIT(3, L); break; /* BIT 3,L */ + case 0x5e: BIT_HL(3, RM8(HL)); break; /* BIT 3,(HL) */ + case 0x5f: BIT(3, A); break; /* BIT 3,A */ + case 0x60: BIT(4, B); break; /* BIT 4,B */ + case 0x61: BIT(4, C); break; /* BIT 4,C */ + case 0x62: BIT(4, D); break; /* BIT 4,D */ + case 0x63: BIT(4, E); break; /* BIT 4,E */ + case 0x64: BIT(4, H); break; /* BIT 4,H */ + case 0x65: BIT(4, L); break; /* BIT 4,L */ + case 0x66: BIT_HL(4, RM8(HL)); break; /* BIT 4,(HL) */ + case 0x67: BIT(4, A); break; /* BIT 4,A */ + case 0x68: BIT(5, B); break; /* BIT 5,B */ + case 0x69: BIT(5, C); break; /* BIT 5,C */ + case 0x6a: BIT(5, D); break; /* BIT 5,D */ + case 0x6b: BIT(5, E); break; /* BIT 5,E */ + case 0x6c: BIT(5, H); break; /* BIT 5,H */ + case 0x6d: BIT(5, L); break; /* BIT 5,L */ + case 0x6e: BIT_HL(5, RM8(HL)); break; /* BIT 5,(HL) */ + case 0x6f: BIT(5, A); break; /* BIT 5,A */ + case 0x70: BIT(6, B); break; /* BIT 6,B */ + case 0x71: BIT(6, C); break; /* BIT 6,C */ + case 0x72: BIT(6, D); break; /* BIT 6,D */ + case 0x73: BIT(6, E); break; /* BIT 6,E */ + case 0x74: BIT(6, H); break; /* BIT 6,H */ + case 0x75: BIT(6, L); break; /* BIT 6,L */ + case 0x76: BIT_HL(6, RM8(HL)); break; /* BIT 6,(HL) */ + case 0x77: BIT(6, A); break; /* BIT 6,A */ + case 0x78: BIT(7, B); break; /* BIT 7,B */ + case 0x79: BIT(7, C); break; /* BIT 7,C */ + case 0x7a: BIT(7, D); break; /* BIT 7,D */ + case 0x7b: BIT(7, E); break; /* BIT 7,E */ + case 0x7c: BIT(7, H); break; /* BIT 7,H */ + case 0x7d: BIT(7, L); break; /* BIT 7,L */ + case 0x7e: BIT_HL(7, RM8(HL)); break; /* BIT 7,(HL) */ + case 0x7f: BIT(7, A); break; /* BIT 7,A */ + case 0x80: B = RES(0, B); break; /* RES 0,B */ + case 0x81: C = RES(0, C); break; /* RES 0,C */ + case 0x82: D = RES(0, D); break; /* RES 0,D */ + case 0x83: E = RES(0, E); break; /* RES 0,E */ + case 0x84: H = RES(0, H); break; /* RES 0,H */ + case 0x85: L = RES(0, L); break; /* RES 0,L */ + case 0x86: WM8(HL, RES(0, RM8(HL))); break; /* RES 0,(HL) */ + case 0x87: A = RES(0, A); break; /* RES 0,A */ + case 0x88: B = RES(1, B); break; /* RES 1,B */ + case 0x89: C = RES(1, C); break; /* RES 1,C */ + case 0x8a: D = RES(1, D); break; /* RES 1,D */ + case 0x8b: E = RES(1, E); break; /* RES 1,E */ + case 0x8c: H = RES(1, H); break; /* RES 1,H */ + case 0x8d: L = RES(1, L); break; /* RES 1,L */ + case 0x8e: WM8(HL, RES(1, RM8(HL))); break; /* RES 1,(HL) */ + case 0x8f: A = RES(1, A); break; /* RES 1,A */ + case 0x90: B = RES(2, B); break; /* RES 2,B */ + case 0x91: C = RES(2, C); break; /* RES 2,C */ + case 0x92: D = RES(2, D); break; /* RES 2,D */ + case 0x93: E = RES(2, E); break; /* RES 2,E */ + case 0x94: H = RES(2, H); break; /* RES 2,H */ + case 0x95: L = RES(2, L); break; /* RES 2,L */ + case 0x96: WM8(HL, RES(2, RM8(HL))); break; /* RES 2,(HL) */ + case 0x97: A = RES(2, A); break; /* RES 2,A */ + case 0x98: B = RES(3, B); break; /* RES 3,B */ + case 0x99: C = RES(3, C); break; /* RES 3,C */ + case 0x9a: D = RES(3, D); break; /* RES 3,D */ + case 0x9b: E = RES(3, E); break; /* RES 3,E */ + case 0x9c: H = RES(3, H); break; /* RES 3,H */ + case 0x9d: L = RES(3, L); break; /* RES 3,L */ + case 0x9e: WM8(HL, RES(3, RM8(HL))); break; /* RES 3,(HL) */ + case 0x9f: A = RES(3, A); break; /* RES 3,A */ + case 0xa0: B = RES(4, B); break; /* RES 4,B */ + case 0xa1: C = RES(4, C); break; /* RES 4,C */ + case 0xa2: D = RES(4, D); break; /* RES 4,D */ + case 0xa3: E = RES(4, E); break; /* RES 4,E */ + case 0xa4: H = RES(4, H); break; /* RES 4,H */ + case 0xa5: L = RES(4, L); break; /* RES 4,L */ + case 0xa6: WM8(HL, RES(4, RM8(HL))); break; /* RES 4,(HL) */ + case 0xa7: A = RES(4, A); break; /* RES 4,A */ + case 0xa8: B = RES(5, B); break; /* RES 5,B */ + case 0xa9: C = RES(5, C); break; /* RES 5,C */ + case 0xaa: D = RES(5, D); break; /* RES 5,D */ + case 0xab: E = RES(5, E); break; /* RES 5,E */ + case 0xac: H = RES(5, H); break; /* RES 5,H */ + case 0xad: L = RES(5, L); break; /* RES 5,L */ + case 0xae: WM8(HL, RES(5, RM8(HL))); break; /* RES 5,(HL) */ + case 0xaf: A = RES(5, A); break; /* RES 5,A */ + case 0xb0: B = RES(6, B); break; /* RES 6,B */ + case 0xb1: C = RES(6, C); break; /* RES 6,C */ + case 0xb2: D = RES(6, D); break; /* RES 6,D */ + case 0xb3: E = RES(6, E); break; /* RES 6,E */ + case 0xb4: H = RES(6, H); break; /* RES 6,H */ + case 0xb5: L = RES(6, L); break; /* RES 6,L */ + case 0xb6: WM8(HL, RES(6, RM8(HL))); break; /* RES 6,(HL) */ + case 0xb7: A = RES(6, A); break; /* RES 6,A */ + case 0xb8: B = RES(7, B); break; /* RES 7,B */ + case 0xb9: C = RES(7, C); break; /* RES 7,C */ + case 0xba: D = RES(7, D); break; /* RES 7,D */ + case 0xbb: E = RES(7, E); break; /* RES 7,E */ + case 0xbc: H = RES(7, H); break; /* RES 7,H */ + case 0xbd: L = RES(7, L); break; /* RES 7,L */ + case 0xbe: WM8(HL, RES(7, RM8(HL))); break; /* RES 7,(HL) */ + case 0xbf: A = RES(7, A); break; /* RES 7,A */ + case 0xc0: B = SET(0, B); break; /* SET 0,B */ + case 0xc1: C = SET(0, C); break; /* SET 0,C */ + case 0xc2: D = SET(0, D); break; /* SET 0,D */ + case 0xc3: E = SET(0, E); break; /* SET 0,E */ + case 0xc4: H = SET(0, H); break; /* SET 0,H */ + case 0xc5: L = SET(0, L); break; /* SET 0,L */ + case 0xc6: WM8(HL, SET(0, RM8(HL))); break; /* SET 0,(HL) */ + case 0xc7: A = SET(0, A); break; /* SET 0,A */ + case 0xc8: B = SET(1, B); break; /* SET 1,B */ + case 0xc9: C = SET(1, C); break; /* SET 1,C */ + case 0xca: D = SET(1, D); break; /* SET 1,D */ + case 0xcb: E = SET(1, E); break; /* SET 1,E */ + case 0xcc: H = SET(1, H); break; /* SET 1,H */ + case 0xcd: L = SET(1, L); break; /* SET 1,L */ + case 0xce: WM8(HL, SET(1, RM8(HL))); break; /* SET 1,(HL) */ + case 0xcf: A = SET(1, A); break; /* SET 1,A */ + case 0xd0: B = SET(2, B); break; /* SET 2,B */ + case 0xd1: C = SET(2, C); break; /* SET 2,C */ + case 0xd2: D = SET(2, D); break; /* SET 2,D */ + case 0xd3: E = SET(2, E); break; /* SET 2,E */ + case 0xd4: H = SET(2, H); break; /* SET 2,H */ + case 0xd5: L = SET(2, L); break; /* SET 2,L */ + case 0xd6: WM8(HL, SET(2, RM8(HL))); break; /* SET 2,(HL) */ + case 0xd7: A = SET(2, A); break; /* SET 2,A */ + case 0xd8: B = SET(3, B); break; /* SET 3,B */ + case 0xd9: C = SET(3, C); break; /* SET 3,C */ + case 0xda: D = SET(3, D); break; /* SET 3,D */ + case 0xdb: E = SET(3, E); break; /* SET 3,E */ + case 0xdc: H = SET(3, H); break; /* SET 3,H */ + case 0xdd: L = SET(3, L); break; /* SET 3,L */ + case 0xde: WM8(HL, SET(3, RM8(HL))); break; /* SET 3,(HL) */ + case 0xdf: A = SET(3, A); break; /* SET 3,A */ + case 0xe0: B = SET(4, B); break; /* SET 4,B */ + case 0xe1: C = SET(4, C); break; /* SET 4,C */ + case 0xe2: D = SET(4, D); break; /* SET 4,D */ + case 0xe3: E = SET(4, E); break; /* SET 4,E */ + case 0xe4: H = SET(4, H); break; /* SET 4,H */ + case 0xe5: L = SET(4, L); break; /* SET 4,L */ + case 0xe6: WM8(HL, SET(4, RM8(HL))); break; /* SET 4,(HL) */ + case 0xe7: A = SET(4, A); break; /* SET 4,A */ + case 0xe8: B = SET(5, B); break; /* SET 5,B */ + case 0xe9: C = SET(5, C); break; /* SET 5,C */ + case 0xea: D = SET(5, D); break; /* SET 5,D */ + case 0xeb: E = SET(5, E); break; /* SET 5,E */ + case 0xec: H = SET(5, H); break; /* SET 5,H */ + case 0xed: L = SET(5, L); break; /* SET 5,L */ + case 0xee: WM8(HL, SET(5, RM8(HL))); break; /* SET 5,(HL) */ + case 0xef: A = SET(5, A); break; /* SET 5,A */ + case 0xf0: B = SET(6, B); break; /* SET 6,B */ + case 0xf1: C = SET(6, C); break; /* SET 6,C */ + case 0xf2: D = SET(6, D); break; /* SET 6,D */ + case 0xf3: E = SET(6, E); break; /* SET 6,E */ + case 0xf4: H = SET(6, H); break; /* SET 6,H */ + case 0xf5: L = SET(6, L); break; /* SET 6,L */ + case 0xf6: WM8(HL, SET(6, RM8(HL))); break; /* SET 6,(HL) */ + case 0xf7: A = SET(6, A); break; /* SET 6,A */ + case 0xf8: B = SET(7, B); break; /* SET 7,B */ + case 0xf9: C = SET(7, C); break; /* SET 7,C */ + case 0xfa: D = SET(7, D); break; /* SET 7,D */ + case 0xfb: E = SET(7, E); break; /* SET 7,E */ + case 0xfc: H = SET(7, H); break; /* SET 7,H */ + case 0xfd: L = SET(7, L); break; /* SET 7,L */ + case 0xfe: WM8(HL, SET(7, RM8(HL))); break; /* SET 7,(HL) */ + case 0xff: A = SET(7, A); break; /* SET 7,A */ +#if defined(_MSC_VER) && (_MSC_VER >= 1200) + default: __assume(0); #endif -#ifdef HAS_LDAIR_QUIRK - has_ldair_quirk = true; + } +} + +void Z80::OP_XY(uint8_t code) +{ + icount -= cc_xycb[code]; + + switch(code) { + case 0x00: B = RLC(RM8(ea)); WM8(ea, B); break; /* RLC B=(XY+o) */ + case 0x01: C = RLC(RM8(ea)); WM8(ea, C); break; /* RLC C=(XY+o) */ + case 0x02: D = RLC(RM8(ea)); WM8(ea, D); break; /* RLC D=(XY+o) */ + case 0x03: E = RLC(RM8(ea)); WM8(ea, E); break; /* RLC E=(XY+o) */ + case 0x04: H = RLC(RM8(ea)); WM8(ea, H); break; /* RLC H=(XY+o) */ + case 0x05: L = RLC(RM8(ea)); WM8(ea, L); break; /* RLC L=(XY+o) */ + case 0x06: WM8(ea, RLC(RM8(ea))); break; /* RLC (XY+o) */ + case 0x07: A = RLC(RM8(ea)); WM8(ea, A); break; /* RLC A=(XY+o) */ + case 0x08: B = RRC(RM8(ea)); WM8(ea, B); break; /* RRC B=(XY+o) */ + case 0x09: C = RRC(RM8(ea)); WM8(ea, C); break; /* RRC C=(XY+o) */ + case 0x0a: D = RRC(RM8(ea)); WM8(ea, D); break; /* RRC D=(XY+o) */ + case 0x0b: E = RRC(RM8(ea)); WM8(ea, E); break; /* RRC E=(XY+o) */ + case 0x0c: H = RRC(RM8(ea)); WM8(ea, H); break; /* RRC H=(XY+o) */ + case 0x0d: L = RRC(RM8(ea)); WM8(ea, L); break; /* RRC L=(XY+o) */ + case 0x0e: WM8(ea, RRC(RM8(ea))); break; /* RRC (XY+o) */ + case 0x0f: A = RRC(RM8(ea)); WM8(ea, A); break; /* RRC A=(XY+o) */ + case 0x10: B = RL(RM8(ea)); WM8(ea, B); break; /* RL B=(XY+o) */ + case 0x11: C = RL(RM8(ea)); WM8(ea, C); break; /* RL C=(XY+o) */ + case 0x12: D = RL(RM8(ea)); WM8(ea, D); break; /* RL D=(XY+o) */ + case 0x13: E = RL(RM8(ea)); WM8(ea, E); break; /* RL E=(XY+o) */ + case 0x14: H = RL(RM8(ea)); WM8(ea, H); break; /* RL H=(XY+o) */ + case 0x15: L = RL(RM8(ea)); WM8(ea, L); break; /* RL L=(XY+o) */ + case 0x16: WM8(ea, RL(RM8(ea))); break; /* RL (XY+o) */ + case 0x17: A = RL(RM8(ea)); WM8(ea, A); break; /* RL A=(XY+o) */ + case 0x18: B = RR(RM8(ea)); WM8(ea, B); break; /* RR B=(XY+o) */ + case 0x19: C = RR(RM8(ea)); WM8(ea, C); break; /* RR C=(XY+o) */ + case 0x1a: D = RR(RM8(ea)); WM8(ea, D); break; /* RR D=(XY+o) */ + case 0x1b: E = RR(RM8(ea)); WM8(ea, E); break; /* RR E=(XY+o) */ + case 0x1c: H = RR(RM8(ea)); WM8(ea, H); break; /* RR H=(XY+o) */ + case 0x1d: L = RR(RM8(ea)); WM8(ea, L); break; /* RR L=(XY+o) */ + case 0x1e: WM8(ea, RR(RM8(ea))); break; /* RR (XY+o) */ + case 0x1f: A = RR(RM8(ea)); WM8(ea, A); break; /* RR A=(XY+o) */ + case 0x20: B = SLA(RM8(ea)); WM8(ea, B); break; /* SLA B=(XY+o) */ + case 0x21: C = SLA(RM8(ea)); WM8(ea, C); break; /* SLA C=(XY+o) */ + case 0x22: D = SLA(RM8(ea)); WM8(ea, D); break; /* SLA D=(XY+o) */ + case 0x23: E = SLA(RM8(ea)); WM8(ea, E); break; /* SLA E=(XY+o) */ + case 0x24: H = SLA(RM8(ea)); WM8(ea, H); break; /* SLA H=(XY+o) */ + case 0x25: L = SLA(RM8(ea)); WM8(ea, L); break; /* SLA L=(XY+o) */ + case 0x26: WM8(ea, SLA(RM8(ea))); break; /* SLA (XY+o) */ + case 0x27: A = SLA(RM8(ea)); WM8(ea, A); break; /* SLA A=(XY+o) */ + case 0x28: B = SRA(RM8(ea)); WM8(ea, B); break; /* SRA B=(XY+o) */ + case 0x29: C = SRA(RM8(ea)); WM8(ea, C); break; /* SRA C=(XY+o) */ + case 0x2a: D = SRA(RM8(ea)); WM8(ea, D); break; /* SRA D=(XY+o) */ + case 0x2b: E = SRA(RM8(ea)); WM8(ea, E); break; /* SRA E=(XY+o) */ + case 0x2c: H = SRA(RM8(ea)); WM8(ea, H); break; /* SRA H=(XY+o) */ + case 0x2d: L = SRA(RM8(ea)); WM8(ea, L); break; /* SRA L=(XY+o) */ + case 0x2e: WM8(ea, SRA(RM8(ea))); break; /* SRA (XY+o) */ + case 0x2f: A = SRA(RM8(ea)); WM8(ea, A); break; /* SRA A=(XY+o) */ + case 0x30: B = SLL(RM8(ea)); WM8(ea, B); break; /* SLL B=(XY+o) */ + case 0x31: C = SLL(RM8(ea)); WM8(ea, C); break; /* SLL C=(XY+o) */ + case 0x32: D = SLL(RM8(ea)); WM8(ea, D); break; /* SLL D=(XY+o) */ + case 0x33: E = SLL(RM8(ea)); WM8(ea, E); break; /* SLL E=(XY+o) */ + case 0x34: H = SLL(RM8(ea)); WM8(ea, H); break; /* SLL H=(XY+o) */ + case 0x35: L = SLL(RM8(ea)); WM8(ea, L); break; /* SLL L=(XY+o) */ + case 0x36: WM8(ea, SLL(RM8(ea))); break; /* SLL (XY+o) */ + case 0x37: A = SLL(RM8(ea)); WM8(ea, A); break; /* SLL A=(XY+o) */ + case 0x38: B = SRL(RM8(ea)); WM8(ea, B); break; /* SRL B=(XY+o) */ + case 0x39: C = SRL(RM8(ea)); WM8(ea, C); break; /* SRL C=(XY+o) */ + case 0x3a: D = SRL(RM8(ea)); WM8(ea, D); break; /* SRL D=(XY+o) */ + case 0x3b: E = SRL(RM8(ea)); WM8(ea, E); break; /* SRL E=(XY+o) */ + case 0x3c: H = SRL(RM8(ea)); WM8(ea, H); break; /* SRL H=(XY+o) */ + case 0x3d: L = SRL(RM8(ea)); WM8(ea, L); break; /* SRL L=(XY+o) */ + case 0x3e: WM8(ea, SRL(RM8(ea))); break; /* SRL (XY+o) */ + case 0x3f: A = SRL(RM8(ea)); WM8(ea, A); break; /* SRL A=(XY+o) */ + case 0x40: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x41: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x42: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x43: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x44: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x45: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x46: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x47: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ + case 0x48: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x49: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x4a: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x4b: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x4c: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x4d: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x4e: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x4f: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ + case 0x50: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x51: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x52: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x53: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x54: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x55: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x56: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x57: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ + case 0x58: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x59: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x5a: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x5b: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x5c: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x5d: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x5e: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x5f: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ + case 0x60: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x61: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x62: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x63: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x64: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x65: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x66: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x67: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ + case 0x68: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x69: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x6a: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x6b: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x6c: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x6d: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x6e: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x6f: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ + case 0x70: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x71: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x72: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x73: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x74: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x75: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x76: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x77: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ + case 0x78: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x79: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x7a: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x7b: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x7c: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x7d: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x7e: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x7f: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ + case 0x80: B = RES(0, RM8(ea)); WM8(ea, B); break; /* RES 0,B=(XY+o) */ + case 0x81: C = RES(0, RM8(ea)); WM8(ea, C); break; /* RES 0,C=(XY+o) */ + case 0x82: D = RES(0, RM8(ea)); WM8(ea, D); break; /* RES 0,D=(XY+o) */ + case 0x83: E = RES(0, RM8(ea)); WM8(ea, E); break; /* RES 0,E=(XY+o) */ + case 0x84: H = RES(0, RM8(ea)); WM8(ea, H); break; /* RES 0,H=(XY+o) */ + case 0x85: L = RES(0, RM8(ea)); WM8(ea, L); break; /* RES 0,L=(XY+o) */ + case 0x86: WM8(ea, RES(0, RM8(ea))); break; /* RES 0,(XY+o) */ + case 0x87: A = RES(0, RM8(ea)); WM8(ea, A); break; /* RES 0,A=(XY+o) */ + case 0x88: B = RES(1, RM8(ea)); WM8(ea, B); break; /* RES 1,B=(XY+o) */ + case 0x89: C = RES(1, RM8(ea)); WM8(ea, C); break; /* RES 1,C=(XY+o) */ + case 0x8a: D = RES(1, RM8(ea)); WM8(ea, D); break; /* RES 1,D=(XY+o) */ + case 0x8b: E = RES(1, RM8(ea)); WM8(ea, E); break; /* RES 1,E=(XY+o) */ + case 0x8c: H = RES(1, RM8(ea)); WM8(ea, H); break; /* RES 1,H=(XY+o) */ + case 0x8d: L = RES(1, RM8(ea)); WM8(ea, L); break; /* RES 1,L=(XY+o) */ + case 0x8e: WM8(ea, RES(1, RM8(ea))); break; /* RES 1,(XY+o) */ + case 0x8f: A = RES(1, RM8(ea)); WM8(ea, A); break; /* RES 1,A=(XY+o) */ + case 0x90: B = RES(2, RM8(ea)); WM8(ea, B); break; /* RES 2,B=(XY+o) */ + case 0x91: C = RES(2, RM8(ea)); WM8(ea, C); break; /* RES 2,C=(XY+o) */ + case 0x92: D = RES(2, RM8(ea)); WM8(ea, D); break; /* RES 2,D=(XY+o) */ + case 0x93: E = RES(2, RM8(ea)); WM8(ea, E); break; /* RES 2,E=(XY+o) */ + case 0x94: H = RES(2, RM8(ea)); WM8(ea, H); break; /* RES 2,H=(XY+o) */ + case 0x95: L = RES(2, RM8(ea)); WM8(ea, L); break; /* RES 2,L=(XY+o) */ + case 0x96: WM8(ea, RES(2, RM8(ea))); break; /* RES 2,(XY+o) */ + case 0x97: A = RES(2, RM8(ea)); WM8(ea, A); break; /* RES 2,A=(XY+o) */ + case 0x98: B = RES(3, RM8(ea)); WM8(ea, B); break; /* RES 3,B=(XY+o) */ + case 0x99: C = RES(3, RM8(ea)); WM8(ea, C); break; /* RES 3,C=(XY+o) */ + case 0x9a: D = RES(3, RM8(ea)); WM8(ea, D); break; /* RES 3,D=(XY+o) */ + case 0x9b: E = RES(3, RM8(ea)); WM8(ea, E); break; /* RES 3,E=(XY+o) */ + case 0x9c: H = RES(3, RM8(ea)); WM8(ea, H); break; /* RES 3,H=(XY+o) */ + case 0x9d: L = RES(3, RM8(ea)); WM8(ea, L); break; /* RES 3,L=(XY+o) */ + case 0x9e: WM8(ea, RES(3, RM8(ea))); break; /* RES 3,(XY+o) */ + case 0x9f: A = RES(3, RM8(ea)); WM8(ea, A); break; /* RES 3,A=(XY+o) */ + case 0xa0: B = RES(4, RM8(ea)); WM8(ea, B); break; /* RES 4,B=(XY+o) */ + case 0xa1: C = RES(4, RM8(ea)); WM8(ea, C); break; /* RES 4,C=(XY+o) */ + case 0xa2: D = RES(4, RM8(ea)); WM8(ea, D); break; /* RES 4,D=(XY+o) */ + case 0xa3: E = RES(4, RM8(ea)); WM8(ea, E); break; /* RES 4,E=(XY+o) */ + case 0xa4: H = RES(4, RM8(ea)); WM8(ea, H); break; /* RES 4,H=(XY+o) */ + case 0xa5: L = RES(4, RM8(ea)); WM8(ea, L); break; /* RES 4,L=(XY+o) */ + case 0xa6: WM8(ea, RES(4, RM8(ea))); break; /* RES 4,(XY+o) */ + case 0xa7: A = RES(4, RM8(ea)); WM8(ea, A); break; /* RES 4,A=(XY+o) */ + case 0xa8: B = RES(5, RM8(ea)); WM8(ea, B); break; /* RES 5,B=(XY+o) */ + case 0xa9: C = RES(5, RM8(ea)); WM8(ea, C); break; /* RES 5,C=(XY+o) */ + case 0xaa: D = RES(5, RM8(ea)); WM8(ea, D); break; /* RES 5,D=(XY+o) */ + case 0xab: E = RES(5, RM8(ea)); WM8(ea, E); break; /* RES 5,E=(XY+o) */ + case 0xac: H = RES(5, RM8(ea)); WM8(ea, H); break; /* RES 5,H=(XY+o) */ + case 0xad: L = RES(5, RM8(ea)); WM8(ea, L); break; /* RES 5,L=(XY+o) */ + case 0xae: WM8(ea, RES(5, RM8(ea))); break; /* RES 5,(XY+o) */ + case 0xaf: A = RES(5, RM8(ea)); WM8(ea, A); break; /* RES 5,A=(XY+o) */ + case 0xb0: B = RES(6, RM8(ea)); WM8(ea, B); break; /* RES 6,B=(XY+o) */ + case 0xb1: C = RES(6, RM8(ea)); WM8(ea, C); break; /* RES 6,C=(XY+o) */ + case 0xb2: D = RES(6, RM8(ea)); WM8(ea, D); break; /* RES 6,D=(XY+o) */ + case 0xb3: E = RES(6, RM8(ea)); WM8(ea, E); break; /* RES 6,E=(XY+o) */ + case 0xb4: H = RES(6, RM8(ea)); WM8(ea, H); break; /* RES 6,H=(XY+o) */ + case 0xb5: L = RES(6, RM8(ea)); WM8(ea, L); break; /* RES 6,L=(XY+o) */ + case 0xb6: WM8(ea, RES(6, RM8(ea))); break; /* RES 6,(XY+o) */ + case 0xb7: A = RES(6, RM8(ea)); WM8(ea, A); break; /* RES 6,A=(XY+o) */ + case 0xb8: B = RES(7, RM8(ea)); WM8(ea, B); break; /* RES 7,B=(XY+o) */ + case 0xb9: C = RES(7, RM8(ea)); WM8(ea, C); break; /* RES 7,C=(XY+o) */ + case 0xba: D = RES(7, RM8(ea)); WM8(ea, D); break; /* RES 7,D=(XY+o) */ + case 0xbb: E = RES(7, RM8(ea)); WM8(ea, E); break; /* RES 7,E=(XY+o) */ + case 0xbc: H = RES(7, RM8(ea)); WM8(ea, H); break; /* RES 7,H=(XY+o) */ + case 0xbd: L = RES(7, RM8(ea)); WM8(ea, L); break; /* RES 7,L=(XY+o) */ + case 0xbe: WM8(ea, RES(7, RM8(ea))); break; /* RES 7,(XY+o) */ + case 0xbf: A = RES(7, RM8(ea)); WM8(ea, A); break; /* RES 7,A=(XY+o) */ + case 0xc0: B = SET(0, RM8(ea)); WM8(ea, B); break; /* SET 0,B=(XY+o) */ + case 0xc1: C = SET(0, RM8(ea)); WM8(ea, C); break; /* SET 0,C=(XY+o) */ + case 0xc2: D = SET(0, RM8(ea)); WM8(ea, D); break; /* SET 0,D=(XY+o) */ + case 0xc3: E = SET(0, RM8(ea)); WM8(ea, E); break; /* SET 0,E=(XY+o) */ + case 0xc4: H = SET(0, RM8(ea)); WM8(ea, H); break; /* SET 0,H=(XY+o) */ + case 0xc5: L = SET(0, RM8(ea)); WM8(ea, L); break; /* SET 0,L=(XY+o) */ + case 0xc6: WM8(ea, SET(0, RM8(ea))); break; /* SET 0,(XY+o) */ + case 0xc7: A = SET(0, RM8(ea)); WM8(ea, A); break; /* SET 0,A=(XY+o) */ + case 0xc8: B = SET(1, RM8(ea)); WM8(ea, B); break; /* SET 1,B=(XY+o) */ + case 0xc9: C = SET(1, RM8(ea)); WM8(ea, C); break; /* SET 1,C=(XY+o) */ + case 0xca: D = SET(1, RM8(ea)); WM8(ea, D); break; /* SET 1,D=(XY+o) */ + case 0xcb: E = SET(1, RM8(ea)); WM8(ea, E); break; /* SET 1,E=(XY+o) */ + case 0xcc: H = SET(1, RM8(ea)); WM8(ea, H); break; /* SET 1,H=(XY+o) */ + case 0xcd: L = SET(1, RM8(ea)); WM8(ea, L); break; /* SET 1,L=(XY+o) */ + case 0xce: WM8(ea, SET(1, RM8(ea))); break; /* SET 1,(XY+o) */ + case 0xcf: A = SET(1, RM8(ea)); WM8(ea, A); break; /* SET 1,A=(XY+o) */ + case 0xd0: B = SET(2, RM8(ea)); WM8(ea, B); break; /* SET 2,B=(XY+o) */ + case 0xd1: C = SET(2, RM8(ea)); WM8(ea, C); break; /* SET 2,C=(XY+o) */ + case 0xd2: D = SET(2, RM8(ea)); WM8(ea, D); break; /* SET 2,D=(XY+o) */ + case 0xd3: E = SET(2, RM8(ea)); WM8(ea, E); break; /* SET 2,E=(XY+o) */ + case 0xd4: H = SET(2, RM8(ea)); WM8(ea, H); break; /* SET 2,H=(XY+o) */ + case 0xd5: L = SET(2, RM8(ea)); WM8(ea, L); break; /* SET 2,L=(XY+o) */ + case 0xd6: WM8(ea, SET(2, RM8(ea))); break; /* SET 2,(XY+o) */ + case 0xd7: A = SET(2, RM8(ea)); WM8(ea, A); break; /* SET 2,A=(XY+o) */ + case 0xd8: B = SET(3, RM8(ea)); WM8(ea, B); break; /* SET 3,B=(XY+o) */ + case 0xd9: C = SET(3, RM8(ea)); WM8(ea, C); break; /* SET 3,C=(XY+o) */ + case 0xda: D = SET(3, RM8(ea)); WM8(ea, D); break; /* SET 3,D=(XY+o) */ + case 0xdb: E = SET(3, RM8(ea)); WM8(ea, E); break; /* SET 3,E=(XY+o) */ + case 0xdc: H = SET(3, RM8(ea)); WM8(ea, H); break; /* SET 3,H=(XY+o) */ + case 0xdd: L = SET(3, RM8(ea)); WM8(ea, L); break; /* SET 3,L=(XY+o) */ + case 0xde: WM8(ea, SET(3, RM8(ea))); break; /* SET 3,(XY+o) */ + case 0xdf: A = SET(3, RM8(ea)); WM8(ea, A); break; /* SET 3,A=(XY+o) */ + case 0xe0: B = SET(4, RM8(ea)); WM8(ea, B); break; /* SET 4,B=(XY+o) */ + case 0xe1: C = SET(4, RM8(ea)); WM8(ea, C); break; /* SET 4,C=(XY+o) */ + case 0xe2: D = SET(4, RM8(ea)); WM8(ea, D); break; /* SET 4,D=(XY+o) */ + case 0xe3: E = SET(4, RM8(ea)); WM8(ea, E); break; /* SET 4,E=(XY+o) */ + case 0xe4: H = SET(4, RM8(ea)); WM8(ea, H); break; /* SET 4,H=(XY+o) */ + case 0xe5: L = SET(4, RM8(ea)); WM8(ea, L); break; /* SET 4,L=(XY+o) */ + case 0xe6: WM8(ea, SET(4, RM8(ea))); break; /* SET 4,(XY+o) */ + case 0xe7: A = SET(4, RM8(ea)); WM8(ea, A); break; /* SET 4,A=(XY+o) */ + case 0xe8: B = SET(5, RM8(ea)); WM8(ea, B); break; /* SET 5,B=(XY+o) */ + case 0xe9: C = SET(5, RM8(ea)); WM8(ea, C); break; /* SET 5,C=(XY+o) */ + case 0xea: D = SET(5, RM8(ea)); WM8(ea, D); break; /* SET 5,D=(XY+o) */ + case 0xeb: E = SET(5, RM8(ea)); WM8(ea, E); break; /* SET 5,E=(XY+o) */ + case 0xec: H = SET(5, RM8(ea)); WM8(ea, H); break; /* SET 5,H=(XY+o) */ + case 0xed: L = SET(5, RM8(ea)); WM8(ea, L); break; /* SET 5,L=(XY+o) */ + case 0xee: WM8(ea, SET(5, RM8(ea))); break; /* SET 5,(XY+o) */ + case 0xef: A = SET(5, RM8(ea)); WM8(ea, A); break; /* SET 5,A=(XY+o) */ + case 0xf0: B = SET(6, RM8(ea)); WM8(ea, B); break; /* SET 6,B=(XY+o) */ + case 0xf1: C = SET(6, RM8(ea)); WM8(ea, C); break; /* SET 6,C=(XY+o) */ + case 0xf2: D = SET(6, RM8(ea)); WM8(ea, D); break; /* SET 6,D=(XY+o) */ + case 0xf3: E = SET(6, RM8(ea)); WM8(ea, E); break; /* SET 6,E=(XY+o) */ + case 0xf4: H = SET(6, RM8(ea)); WM8(ea, H); break; /* SET 6,H=(XY+o) */ + case 0xf5: L = SET(6, RM8(ea)); WM8(ea, L); break; /* SET 6,L=(XY+o) */ + case 0xf6: WM8(ea, SET(6, RM8(ea))); break; /* SET 6,(XY+o) */ + case 0xf7: A = SET(6, RM8(ea)); WM8(ea, A); break; /* SET 6,A=(XY+o) */ + case 0xf8: B = SET(7, RM8(ea)); WM8(ea, B); break; /* SET 7,B=(XY+o) */ + case 0xf9: C = SET(7, RM8(ea)); WM8(ea, C); break; /* SET 7,C=(XY+o) */ + case 0xfa: D = SET(7, RM8(ea)); WM8(ea, D); break; /* SET 7,D=(XY+o) */ + case 0xfb: E = SET(7, RM8(ea)); WM8(ea, E); break; /* SET 7,E=(XY+o) */ + case 0xfc: H = SET(7, RM8(ea)); WM8(ea, H); break; /* SET 7,H=(XY+o) */ + case 0xfd: L = SET(7, RM8(ea)); WM8(ea, L); break; /* SET 7,L=(XY+o) */ + case 0xfe: WM8(ea, SET(7, RM8(ea))); break; /* SET 7,(XY+o) */ + case 0xff: A = SET(7, RM8(ea)); WM8(ea, A); break; /* SET 7,A=(XY+o) */ +#if defined(_MSC_VER) && (_MSC_VER >= 1200) + default: __assume(0); #endif + } } -Z80::~Z80() +void Z80::OP_DD(uint8_t code) { + icount -= cc_xy[code]; + + switch(code) { + case 0x09: ADD16(ix, bc); break; /* ADD IX,BC */ + case 0x19: ADD16(ix, de); break; /* ADD IX,DE */ + case 0x21: IX = FETCH16(); break; /* LD IX,w */ + case 0x22: ea = FETCH16(); WM16(ea, &ix); WZ = ea + 1; break; /* LD (w),IX */ + case 0x23: IX++; break; /* INC IX */ + case 0x24: HX = INC(HX); break; /* INC HX */ + case 0x25: HX = DEC(HX); break; /* DEC HX */ + case 0x26: HX = FETCH8(); break; /* LD HX,n */ + case 0x29: ADD16(ix, ix); break; /* ADD IX,IX */ + case 0x2a: ea = FETCH16(); RM16(ea, &ix); WZ = ea + 1; break; /* LD IX,(w) */ + case 0x2b: IX--; break; /* DEC IX */ + case 0x2c: LX = INC(LX); break; /* INC LX */ + case 0x2d: LX = DEC(LX); break; /* DEC LX */ + case 0x2e: LX = FETCH8(); break; /* LD LX,n */ + case 0x34: EAX(); WM8(ea, INC(RM8(ea))); break; /* INC (IX+o) */ + case 0x35: EAX(); WM8(ea, DEC(RM8(ea))); break; /* DEC (IX+o) */ + case 0x36: EAX(); WM8(ea, FETCH8()); break; /* LD (IX+o),n */ + case 0x39: ADD16(ix, sp); break; /* ADD IX,SP */ + case 0x44: B = HX; break; /* LD B,HX */ + case 0x45: B = LX; break; /* LD B,LX */ + case 0x46: EAX(); B = RM8(ea); break; /* LD B,(IX+o) */ + case 0x4c: C = HX; break; /* LD C,HX */ + case 0x4d: C = LX; break; /* LD C,LX */ + case 0x4e: EAX(); C = RM8(ea); break; /* LD C,(IX+o) */ + case 0x54: D = HX; break; /* LD D,HX */ + case 0x55: D = LX; break; /* LD D,LX */ + case 0x56: EAX(); D = RM8(ea); break; /* LD D,(IX+o) */ + case 0x5c: E = HX; break; /* LD E,HX */ + case 0x5d: E = LX; break; /* LD E,LX */ + case 0x5e: EAX(); E = RM8(ea); break; /* LD E,(IX+o) */ + case 0x60: HX = B; break; /* LD HX,B */ + case 0x61: HX = C; break; /* LD HX,C */ + case 0x62: HX = D; break; /* LD HX,D */ + case 0x63: HX = E; break; /* LD HX,E */ + case 0x64: break; /* LD HX,HX */ + case 0x65: HX = LX; break; /* LD HX,LX */ + case 0x66: EAX(); H = RM8(ea); break; /* LD H,(IX+o) */ + case 0x67: HX = A; break; /* LD HX,A */ + case 0x68: LX = B; break; /* LD LX,B */ + case 0x69: LX = C; break; /* LD LX,C */ + case 0x6a: LX = D; break; /* LD LX,D */ + case 0x6b: LX = E; break; /* LD LX,E */ + case 0x6c: LX = HX; break; /* LD LX,HX */ + case 0x6d: break; /* LD LX,LX */ + case 0x6e: EAX(); L = RM8(ea); break; /* LD L,(IX+o) */ + case 0x6f: LX = A; break; /* LD LX,A */ + case 0x70: EAX(); WM8(ea, B); break; /* LD (IX+o),B */ + case 0x71: EAX(); WM8(ea, C); break; /* LD (IX+o),C */ + case 0x72: EAX(); WM8(ea, D); break; /* LD (IX+o),D */ + case 0x73: EAX(); WM8(ea, E); break; /* LD (IX+o),E */ + case 0x74: EAX(); WM8(ea, H); break; /* LD (IX+o),H */ + case 0x75: EAX(); WM8(ea, L); break; /* LD (IX+o),L */ + case 0x77: EAX(); WM8(ea, A); break; /* LD (IX+o),A */ + case 0x7c: A = HX; break; /* LD A,HX */ + case 0x7d: A = LX; break; /* LD A,LX */ + case 0x7e: EAX(); A = RM8(ea); break; /* LD A,(IX+o) */ + case 0x84: ADD(HX); break; /* ADD A,HX */ + case 0x85: ADD(LX); break; /* ADD A,LX */ + case 0x86: EAX(); ADD(RM8(ea)); break; /* ADD A,(IX+o) */ + case 0x8c: ADC(HX); break; /* ADC A,HX */ + case 0x8d: ADC(LX); break; /* ADC A,LX */ + case 0x8e: EAX(); ADC(RM8(ea)); break; /* ADC A,(IX+o) */ + case 0x94: SUB(HX); break; /* SUB HX */ + case 0x95: SUB(LX); break; /* SUB LX */ + case 0x96: EAX(); SUB(RM8(ea)); break; /* SUB (IX+o) */ + case 0x9c: SBC(HX); break; /* SBC A,HX */ + case 0x9d: SBC(LX); break; /* SBC A,LX */ + case 0x9e: EAX(); SBC(RM8(ea)); break; /* SBC A,(IX+o) */ + case 0xa4: AND(HX); break; /* AND HX */ + case 0xa5: AND(LX); break; /* AND LX */ + case 0xa6: EAX(); AND(RM8(ea)); break; /* AND (IX+o) */ + case 0xac: XOR(HX); break; /* XOR HX */ + case 0xad: XOR(LX); break; /* XOR LX */ + case 0xae: EAX(); XOR(RM8(ea)); break; /* XOR (IX+o) */ + case 0xb4: OR(HX); break; /* OR HX */ + case 0xb5: OR(LX); break; /* OR LX */ + case 0xb6: EAX(); OR(RM8(ea)); break; /* OR (IX+o) */ + case 0xbc: CP(HX); break; /* CP HX */ + case 0xbd: CP(LX); break; /* CP LX */ + case 0xbe: EAX(); CP(RM8(ea)); break; /* CP (IX+o) */ + case 0xcb: EAX(); OP_XY(FETCH8()); break; /* ** DD CB xx */ + case 0xe1: POP(ix); break; /* POP IX */ + case 0xe3: EXSP(ix); break; /* EX (SP),IX */ + case 0xe5: PUSH(ix); break; /* PUSH IX */ + case 0xe9: PC = IX; break; /* JP (IX) */ + case 0xf9: SP = IX; break; /* LD SP,IX */ + default: OP(code); break; + } } -void Z80::initialize() +void Z80::OP_FD(uint8_t code) +{ + icount -= cc_xy[code]; + + switch(code) { + case 0x09: ADD16(iy, bc); break; /* ADD IY,BC */ + case 0x19: ADD16(iy, de); break; /* ADD IY,DE */ + case 0x21: IY = FETCH16(); break; /* LD IY,w */ + case 0x22: ea = FETCH16(); WM16(ea, &iy); WZ = ea + 1; break; /* LD (w),IY */ + case 0x23: IY++; break; /* INC IY */ + case 0x24: HY = INC(HY); break; /* INC HY */ + case 0x25: HY = DEC(HY); break; /* DEC HY */ + case 0x26: HY = FETCH8(); break; /* LD HY,n */ + case 0x29: ADD16(iy, iy); break; /* ADD IY,IY */ + case 0x2a: ea = FETCH16(); RM16(ea, &iy); WZ = ea + 1; break; /* LD IY,(w) */ + case 0x2b: IY--; break; /* DEC IY */ + case 0x2c: LY = INC(LY); break; /* INC LY */ + case 0x2d: LY = DEC(LY); break; /* DEC LY */ + case 0x2e: LY = FETCH8(); break; /* LD LY,n */ + case 0x34: EAY(); WM8(ea, INC(RM8(ea))); break; /* INC (IY+o) */ + case 0x35: EAY(); WM8(ea, DEC(RM8(ea))); break; /* DEC (IY+o) */ + case 0x36: EAY(); WM8(ea, FETCH8()); break; /* LD (IY+o),n */ + case 0x39: ADD16(iy, sp); break; /* ADD IY,SP */ + case 0x44: B = HY; break; /* LD B,HY */ + case 0x45: B = LY; break; /* LD B,LY */ + case 0x46: EAY(); B = RM8(ea); break; /* LD B,(IY+o) */ + case 0x4c: C = HY; break; /* LD C,HY */ + case 0x4d: C = LY; break; /* LD C,LY */ + case 0x4e: EAY(); C = RM8(ea); break; /* LD C,(IY+o) */ + case 0x54: D = HY; break; /* LD D,HY */ + case 0x55: D = LY; break; /* LD D,LY */ + case 0x56: EAY(); D = RM8(ea); break; /* LD D,(IY+o) */ + case 0x5c: E = HY; break; /* LD E,HY */ + case 0x5d: E = LY; break; /* LD E,LY */ + case 0x5e: EAY(); E = RM8(ea); break; /* LD E,(IY+o) */ + case 0x60: HY = B; break; /* LD HY,B */ + case 0x61: HY = C; break; /* LD HY,C */ + case 0x62: HY = D; break; /* LD HY,D */ + case 0x63: HY = E; break; /* LD HY,E */ + case 0x64: break; /* LD HY,HY */ + case 0x65: HY = LY; break; /* LD HY,LY */ + case 0x66: EAY(); H = RM8(ea); break; /* LD H,(IY+o) */ + case 0x67: HY = A; break; /* LD HY,A */ + case 0x68: LY = B; break; /* LD LY,B */ + case 0x69: LY = C; break; /* LD LY,C */ + case 0x6a: LY = D; break; /* LD LY,D */ + case 0x6b: LY = E; break; /* LD LY,E */ + case 0x6c: LY = HY; break; /* LD LY,HY */ + case 0x6d: break; /* LD LY,LY */ + case 0x6e: EAY(); L = RM8(ea); break; /* LD L,(IY+o) */ + case 0x6f: LY = A; break; /* LD LY,A */ + case 0x70: EAY(); WM8(ea, B); break; /* LD (IY+o),B */ + case 0x71: EAY(); WM8(ea, C); break; /* LD (IY+o),C */ + case 0x72: EAY(); WM8(ea, D); break; /* LD (IY+o),D */ + case 0x73: EAY(); WM8(ea, E); break; /* LD (IY+o),E */ + case 0x74: EAY(); WM8(ea, H); break; /* LD (IY+o),H */ + case 0x75: EAY(); WM8(ea, L); break; /* LD (IY+o),L */ + case 0x77: EAY(); WM8(ea, A); break; /* LD (IY+o),A */ + case 0x7c: A = HY; break; /* LD A,HY */ + case 0x7d: A = LY; break; /* LD A,LY */ + case 0x7e: EAY(); A = RM8(ea); break; /* LD A,(IY+o) */ + case 0x84: ADD(HY); break; /* ADD A,HY */ + case 0x85: ADD(LY); break; /* ADD A,LY */ + case 0x86: EAY(); ADD(RM8(ea)); break; /* ADD A,(IY+o) */ + case 0x8c: ADC(HY); break; /* ADC A,HY */ + case 0x8d: ADC(LY); break; /* ADC A,LY */ + case 0x8e: EAY(); ADC(RM8(ea)); break; /* ADC A,(IY+o) */ + case 0x94: SUB(HY); break; /* SUB HY */ + case 0x95: SUB(LY); break; /* SUB LY */ + case 0x96: EAY(); SUB(RM8(ea)); break; /* SUB (IY+o) */ + case 0x9c: SBC(HY); break; /* SBC A,HY */ + case 0x9d: SBC(LY); break; /* SBC A,LY */ + case 0x9e: EAY(); SBC(RM8(ea)); break; /* SBC A,(IY+o) */ + case 0xa4: AND(HY); break; /* AND HY */ + case 0xa5: AND(LY); break; /* AND LY */ + case 0xa6: EAY(); AND(RM8(ea)); break; /* AND (IY+o) */ + case 0xac: XOR(HY); break; /* XOR HY */ + case 0xad: XOR(LY); break; /* XOR LY */ + case 0xae: EAY(); XOR(RM8(ea)); break; /* XOR (IY+o) */ + case 0xb4: OR(HY); break; /* OR HY */ + case 0xb5: OR(LY); break; /* OR LY */ + case 0xb6: EAY(); OR(RM8(ea)); break; /* OR (IY+o) */ + case 0xbc: CP(HY); break; /* CP HY */ + case 0xbd: CP(LY); break; /* CP LY */ + case 0xbe: EAY(); CP(RM8(ea)); break; /* CP (IY+o) */ + case 0xcb: EAY(); OP_XY(FETCH8()); break; /* ** FD CB xx */ + case 0xe1: POP(iy); break; /* POP IY */ + case 0xe3: EXSP(iy); break; /* EX (SP),IY */ + case 0xe5: PUSH(iy); break; /* PUSH IY */ + case 0xe9: PC = IY; break; /* JP (IY) */ + case 0xf9: SP = IY; break; /* LD SP,IY */ + default: OP(code); break; + } +} + +void Z80::OP_ED(uint8_t code) +{ + icount -= cc_ed[code]; + + switch(code) { + case 0x40: B = IN8(BC); F = (F & CF) | SZP[B]; break; /* IN B,(C) */ + case 0x41: OUT8(BC, B); break; /* OUT (C),B */ + case 0x42: SBC16(bc); break; /* SBC HL,BC */ + case 0x43: ea = FETCH16(); WM16(ea, &bc); WZ = ea + 1; break; /* LD (w),BC */ + case 0x44: NEG(); break; /* NEG */ + case 0x45: RETN(); break; /* RETN */ + case 0x46: im = 0; break; /* im 0 */ + case 0x47: LD_I_A(); break; /* LD i,A */ + case 0x48: C = IN8(BC); F = (F & CF) | SZP[C]; break; /* IN C,(C) */ + case 0x49: OUT8(BC, C); break; /* OUT (C),C */ + case 0x4a: ADC16(bc); break; /* ADC HL,BC */ + case 0x4b: ea = FETCH16(); RM16(ea, &bc); WZ = ea + 1; break; /* LD BC,(w) */ + case 0x4c: NEG(); break; /* NEG */ + case 0x4d: RETI(); break; /* RETI */ + case 0x4e: im = 0; break; /* im 0 */ + case 0x4f: LD_R_A(); break; /* LD r,A */ + case 0x50: D = IN8(BC); F = (F & CF) | SZP[D]; break; /* IN D,(C) */ + case 0x51: OUT8(BC, D); break; /* OUT (C),D */ + case 0x52: SBC16(de); break; /* SBC HL,DE */ + case 0x53: ea = FETCH16(); WM16(ea, &de); WZ = ea + 1; break; /* LD (w),DE */ + case 0x54: NEG(); break; /* NEG */ + case 0x55: RETN(); break; /* RETN */ + case 0x56: im = 1; break; /* im 1 */ + case 0x57: LD_A_I(); break; /* LD A,i */ + case 0x58: E = IN8(BC); F = (F & CF) | SZP[E]; break; /* IN E,(C) */ + case 0x59: OUT8(BC, E); break; /* OUT (C),E */ + case 0x5a: ADC16(de); break; /* ADC HL,DE */ + case 0x5b: ea = FETCH16(); RM16(ea, &de); WZ = ea + 1; break; /* LD DE,(w) */ + case 0x5c: NEG(); break; /* NEG */ + case 0x5d: RETI(); break; /* RETI */ + case 0x5e: im = 2; break; /* im 2 */ + case 0x5f: LD_A_R(); break; /* LD A,r */ + case 0x60: H = IN8(BC); F = (F & CF) | SZP[H]; break; /* IN H,(C) */ + case 0x61: OUT8(BC, H); break; /* OUT (C),H */ + case 0x62: SBC16(hl); break; /* SBC HL,HL */ + case 0x63: ea = FETCH16(); WM16(ea, &hl); WZ = ea + 1; break; /* LD (w),HL */ + case 0x64: NEG(); break; /* NEG */ + case 0x65: RETN(); break; /* RETN */ + case 0x66: im = 0; break; /* im 0 */ + case 0x67: RRD(); break; /* RRD (HL) */ + case 0x68: L = IN8(BC); F = (F & CF) | SZP[L]; break; /* IN L,(C) */ + case 0x69: OUT8(BC, L); break; /* OUT (C),L */ + case 0x6a: ADC16(hl); break; /* ADC HL,HL */ + case 0x6b: ea = FETCH16(); RM16(ea, &hl); WZ = ea + 1; break; /* LD HL,(w) */ + case 0x6c: NEG(); break; /* NEG */ + case 0x6d: RETI(); break; /* RETI */ + case 0x6e: im = 0; break; /* im 0 */ + case 0x6f: RLD(); break; /* RLD (HL) */ + case 0x70: {uint8_t res = IN8(BC); F = (F & CF) | SZP[res];} break; /* IN F,(C) */ + case 0x71: OUT8(BC, 0); break; /* OUT (C),0 */ + case 0x72: SBC16(sp); break; /* SBC HL,SP */ + case 0x73: ea = FETCH16(); WM16(ea, &sp); WZ = ea + 1; break; /* LD (w),SP */ + case 0x74: NEG(); break; /* NEG */ + case 0x75: RETN(); break; /* RETN */ + case 0x76: im = 1; break; /* im 1 */ + case 0x78: A = IN8(BC); F = (F & CF) | SZP[A]; WZ = BC + 1; break; /* IN A,(C) */ + case 0x79: OUT8(BC, A); WZ = BC + 1; break; /* OUT (C),A */ + case 0x7a: ADC16(sp); break; /* ADC HL,SP */ + case 0x7b: ea = FETCH16(); RM16(ea, &sp); WZ = ea + 1; break; /* LD SP,(w) */ + case 0x7c: NEG(); break; /* NEG */ + case 0x7d: RETI(); break; /* RETI */ + case 0x7e: im = 2; break; /* im 2 */ + case 0xa0: LDI(); break; /* LDI */ + case 0xa1: CPI(); break; /* CPI */ + case 0xa2: INI(); break; /* INI */ + case 0xa3: OUTI(); break; /* OUTI */ + case 0xa8: LDD(); break; /* LDD */ + case 0xa9: CPD(); break; /* CPD */ + case 0xaa: IND(); break; /* IND */ + case 0xab: OUTD(); break; /* OUTD */ + case 0xb0: LDIR(); break; /* LDIR */ + case 0xb1: CPIR(); break; /* CPIR */ + case 0xb2: INIR(); break; /* INIR */ + case 0xb3: OTIR(); break; /* OTIR */ + case 0xb8: LDDR(); break; /* LDDR */ + case 0xb9: CPDR(); break; /* CPDR */ + case 0xba: INDR(); break; /* INDR */ + case 0xbb: OTDR(); break; /* OTDR */ + default: OP(code); break; + } +} + +void Z80::OP(uint8_t code) { - Z80_BASE::initialize(); -#ifdef USE_DEBUGGER - d_mem_stored = d_mem; - d_io_stored = d_io; - d_debugger->set_context_mem(d_mem); - d_debugger->set_context_io(d_io); + prevpc = PC - 1; + icount -= cc_op[code]; + + switch(code) { + case 0x00: break; /* NOP */ + case 0x01: BC = FETCH16(); break; /* LD BC,w */ + case 0x02: WM8(BC, A); WZ_L = (BC + 1) & 0xff; WZ_H = A; break; /* LD (BC),A */ + case 0x03: BC++; break; /* INC BC */ + case 0x04: B = INC(B); break; /* INC B */ + case 0x05: B = DEC(B); break; /* DEC B */ + case 0x06: B = FETCH8(); break; /* LD B,n */ + case 0x07: RLCA(); break; /* RLCA */ + case 0x08: EX_AF(); break; /* EX AF,AF' */ + case 0x09: ADD16(hl, bc); break; /* ADD HL,BC */ + case 0x0a: A = RM8(BC); WZ = BC+1; break; /* LD A,(BC) */ + case 0x0b: BC--; break; /* DEC BC */ + case 0x0c: C = INC(C); break; /* INC C */ + case 0x0d: C = DEC(C); break; /* DEC C */ + case 0x0e: C = FETCH8(); break; /* LD C,n */ + case 0x0f: RRCA(); break; /* RRCA */ + case 0x10: B--; JR_COND(B, 0x10); break; /* DJNZ o */ + case 0x11: DE = FETCH16(); break; /* LD DE,w */ + case 0x12: WM8(DE, A); WZ_L = (DE + 1) & 0xff; WZ_H = A; break; /* LD (DE),A */ + case 0x13: DE++; break; /* INC DE */ + case 0x14: D = INC(D); break; /* INC D */ + case 0x15: D = DEC(D); break; /* DEC D */ + case 0x16: D = FETCH8(); break; /* LD D,n */ + case 0x17: RLA(); break; /* RLA */ + case 0x18: JR(); break; /* JR o */ + case 0x19: ADD16(hl, de); break; /* ADD HL,DE */ + case 0x1a: A = RM8(DE); WZ = DE + 1; break; /* LD A,(DE) */ + case 0x1b: DE--; break; /* DEC DE */ + case 0x1c: E = INC(E); break; /* INC E */ + case 0x1d: E = DEC(E); break; /* DEC E */ + case 0x1e: E = FETCH8(); break; /* LD E,n */ + case 0x1f: RRA(); break; /* RRA */ + case 0x20: JR_COND(!(F & ZF), 0x20); break; /* JR NZ,o */ + case 0x21: HL = FETCH16(); break; /* LD HL,w */ + case 0x22: ea = FETCH16(); WM16(ea, &hl); WZ = ea + 1; break; /* LD (w),HL */ + case 0x23: HL++; break; /* INC HL */ + case 0x24: H = INC(H); break; /* INC H */ + case 0x25: H = DEC(H); break; /* DEC H */ + case 0x26: H = FETCH8(); break; /* LD H,n */ + case 0x27: DAA(); break; /* DAA */ + case 0x28: JR_COND(F & ZF, 0x28); break; /* JR Z,o */ + case 0x29: ADD16(hl, hl); break; /* ADD HL,HL */ + case 0x2a: ea = FETCH16(); RM16(ea, &hl); WZ = ea + 1; break; /* LD HL,(w) */ + case 0x2b: HL--; break; /* DEC HL */ + case 0x2c: L = INC(L); break; /* INC L */ + case 0x2d: L = DEC(L); break; /* DEC L */ + case 0x2e: L = FETCH8(); break; /* LD L,n */ + case 0x2f: A ^= 0xff; F = (F & (SF | ZF | PF | CF)) | HF | NF | (A & (YF | XF)); break; /* CPL */ + case 0x30: JR_COND(!(F & CF), 0x30); break; /* JR NC,o */ + case 0x31: SP = FETCH16(); break; /* LD SP,w */ + case 0x32: ea = FETCH16(); WM8(ea, A); WZ_L = (ea + 1) & 0xff; WZ_H = A; break; /* LD (w),A */ + case 0x33: SP++; break; /* INC SP */ + case 0x34: WM8(HL, INC(RM8(HL))); break; /* INC (HL) */ + case 0x35: WM8(HL, DEC(RM8(HL))); break; /* DEC (HL) */ + case 0x36: WM8(HL, FETCH8()); break; /* LD (HL),n */ + case 0x37: F = (F & (SF | ZF | YF | XF | PF)) | CF | (A & (YF | XF)); break; /* SCF */ + case 0x38: JR_COND(F & CF, 0x38); break; /* JR C,o */ + case 0x39: ADD16(hl, sp); break; /* ADD HL,SP */ + case 0x3a: ea = FETCH16(); A = RM8(ea); WZ = ea + 1; break; /* LD A,(w) */ + case 0x3b: SP--; break; /* DEC SP */ + case 0x3c: A = INC(A); break; /* INC A */ + case 0x3d: A = DEC(A); break; /* DEC A */ + case 0x3e: A = FETCH8(); break; /* LD A,n */ + case 0x3f: F = ((F & (SF | ZF | YF | XF | PF | CF)) | ((F & CF) << 4) | (A & (YF | XF))) ^ CF; break; /* CCF */ + case 0x40: break; /* LD B,B */ + case 0x41: B = C; break; /* LD B,C */ + case 0x42: B = D; break; /* LD B,D */ + case 0x43: B = E; break; /* LD B,E */ + case 0x44: B = H; break; /* LD B,H */ + case 0x45: B = L; break; /* LD B,L */ + case 0x46: B = RM8(HL); break; /* LD B,(HL) */ + case 0x47: B = A; break; /* LD B,A */ + case 0x48: C = B; break; /* LD C,B */ + case 0x49: break; /* LD C,C */ + case 0x4a: C = D; break; /* LD C,D */ + case 0x4b: C = E; break; /* LD C,E */ + case 0x4c: C = H; break; /* LD C,H */ + case 0x4d: C = L; break; /* LD C,L */ + case 0x4e: C = RM8(HL); break; /* LD C,(HL) */ + case 0x4f: C = A; break; /* LD C,A */ + case 0x50: D = B; break; /* LD D,B */ + case 0x51: D = C; break; /* LD D,C */ + case 0x52: break; /* LD D,D */ + case 0x53: D = E; break; /* LD D,E */ + case 0x54: D = H; break; /* LD D,H */ + case 0x55: D = L; break; /* LD D,L */ + case 0x56: D = RM8(HL); break; /* LD D,(HL) */ + case 0x57: D = A; break; /* LD D,A */ + case 0x58: E = B; break; /* LD E,B */ + case 0x59: E = C; break; /* LD E,C */ + case 0x5a: E = D; break; /* LD E,D */ + case 0x5b: break; /* LD E,E */ + case 0x5c: E = H; break; /* LD E,H */ + case 0x5d: E = L; break; /* LD E,L */ + case 0x5e: E = RM8(HL); break; /* LD E,(HL) */ + case 0x5f: E = A; break; /* LD E,A */ + case 0x60: H = B; break; /* LD H,B */ + case 0x61: H = C; break; /* LD H,C */ + case 0x62: H = D; break; /* LD H,D */ + case 0x63: H = E; break; /* LD H,E */ + case 0x64: break; /* LD H,H */ + case 0x65: H = L; break; /* LD H,L */ + case 0x66: H = RM8(HL); break; /* LD H,(HL) */ + case 0x67: H = A; break; /* LD H,A */ + case 0x68: L = B; break; /* LD L,B */ + case 0x69: L = C; break; /* LD L,C */ + case 0x6a: L = D; break; /* LD L,D */ + case 0x6b: L = E; break; /* LD L,E */ + case 0x6c: L = H; break; /* LD L,H */ + case 0x6d: break; /* LD L,L */ + case 0x6e: L = RM8(HL); break; /* LD L,(HL) */ + case 0x6f: L = A; break; /* LD L,A */ + case 0x70: WM8(HL, B); break; /* LD (HL),B */ + case 0x71: WM8(HL, C); break; /* LD (HL),C */ + case 0x72: WM8(HL, D); break; /* LD (HL),D */ + case 0x73: WM8(HL, E); break; /* LD (HL),E */ + case 0x74: WM8(HL, H); break; /* LD (HL),H */ + case 0x75: WM8(HL, L); break; /* LD (HL),L */ + case 0x76: ENTER_HALT(); break; /* halt */ + case 0x77: WM8(HL, A); break; /* LD (HL),A */ + case 0x78: A = B; break; /* LD A,B */ + case 0x79: A = C; break; /* LD A,C */ + case 0x7a: A = D; break; /* LD A,D */ + case 0x7b: A = E; break; /* LD A,E */ + case 0x7c: A = H; break; /* LD A,H */ + case 0x7d: A = L; break; /* LD A,L */ + case 0x7e: A = RM8(HL); break; /* LD A,(HL) */ + case 0x7f: break; /* LD A,A */ + case 0x80: ADD(B); break; /* ADD A,B */ + case 0x81: ADD(C); break; /* ADD A,C */ + case 0x82: ADD(D); break; /* ADD A,D */ + case 0x83: ADD(E); break; /* ADD A,E */ + case 0x84: ADD(H); break; /* ADD A,H */ + case 0x85: ADD(L); break; /* ADD A,L */ + case 0x86: ADD(RM8(HL)); break; /* ADD A,(HL) */ + case 0x87: ADD(A); break; /* ADD A,A */ + case 0x88: ADC(B); break; /* ADC A,B */ + case 0x89: ADC(C); break; /* ADC A,C */ + case 0x8a: ADC(D); break; /* ADC A,D */ + case 0x8b: ADC(E); break; /* ADC A,E */ + case 0x8c: ADC(H); break; /* ADC A,H */ + case 0x8d: ADC(L); break; /* ADC A,L */ + case 0x8e: ADC(RM8(HL)); break; /* ADC A,(HL) */ + case 0x8f: ADC(A); break; /* ADC A,A */ + case 0x90: SUB(B); break; /* SUB B */ + case 0x91: SUB(C); break; /* SUB C */ + case 0x92: SUB(D); break; /* SUB D */ + case 0x93: SUB(E); break; /* SUB E */ + case 0x94: SUB(H); break; /* SUB H */ + case 0x95: SUB(L); break; /* SUB L */ + case 0x96: SUB(RM8(HL)); break; /* SUB (HL) */ + case 0x97: SUB(A); break; /* SUB A */ + case 0x98: SBC(B); break; /* SBC A,B */ + case 0x99: SBC(C); break; /* SBC A,C */ + case 0x9a: SBC(D); break; /* SBC A,D */ + case 0x9b: SBC(E); break; /* SBC A,E */ + case 0x9c: SBC(H); break; /* SBC A,H */ + case 0x9d: SBC(L); break; /* SBC A,L */ + case 0x9e: SBC(RM8(HL)); break; /* SBC A,(HL) */ + case 0x9f: SBC(A); break; /* SBC A,A */ + case 0xa0: AND(B); break; /* AND B */ + case 0xa1: AND(C); break; /* AND C */ + case 0xa2: AND(D); break; /* AND D */ + case 0xa3: AND(E); break; /* AND E */ + case 0xa4: AND(H); break; /* AND H */ + case 0xa5: AND(L); break; /* AND L */ + case 0xa6: AND(RM8(HL)); break; /* AND (HL) */ + case 0xa7: AND(A); break; /* AND A */ + case 0xa8: XOR(B); break; /* XOR B */ + case 0xa9: XOR(C); break; /* XOR C */ + case 0xaa: XOR(D); break; /* XOR D */ + case 0xab: XOR(E); break; /* XOR E */ + case 0xac: XOR(H); break; /* XOR H */ + case 0xad: XOR(L); break; /* XOR L */ + case 0xae: XOR(RM8(HL)); break; /* XOR (HL) */ + case 0xaf: XOR(A); break; /* XOR A */ + case 0xb0: OR(B); break; /* OR B */ + case 0xb1: OR(C); break; /* OR C */ + case 0xb2: OR(D); break; /* OR D */ + case 0xb3: OR(E); break; /* OR E */ + case 0xb4: OR(H); break; /* OR H */ + case 0xb5: OR(L); break; /* OR L */ + case 0xb6: OR(RM8(HL)); break; /* OR (HL) */ + case 0xb7: OR(A); break; /* OR A */ + case 0xb8: CP(B); break; /* CP B */ + case 0xb9: CP(C); break; /* CP C */ + case 0xba: CP(D); break; /* CP D */ + case 0xbb: CP(E); break; /* CP E */ + case 0xbc: CP(H); break; /* CP H */ + case 0xbd: CP(L); break; /* CP L */ + case 0xbe: CP(RM8(HL)); break; /* CP (HL) */ + case 0xbf: CP(A); break; /* CP A */ + case 0xc0: RET_COND(!(F & ZF), 0xc0); break; /* RET NZ */ + case 0xc1: POP(bc); break; /* POP BC */ + case 0xc2: JP_COND(!(F & ZF)); break; /* JP NZ,a */ + case 0xc3: JP(); break; /* JP a */ + case 0xc4: CALL_COND(!(F & ZF), 0xc4); break; /* CALL NZ,a */ + case 0xc5: PUSH(bc); break; /* PUSH BC */ + case 0xc6: ADD(FETCH8()); break; /* ADD A,n */ + case 0xc7: RST(0x00); break; /* RST 0 */ + case 0xc8: RET_COND(F & ZF, 0xc8); break; /* RET Z */ +//#ifdef Z80_PSEUDO_BIOS + case 0xc9: + if(has_pseudo_bios) { + if(d_bios != NULL) { + d_bios->bios_ret_z80(prevpc, &af, &bc, &de, &hl, &ix, &iy, &iff1); + } + } + POP(pc); WZ = PCD; break; /* RET */ +//#else +// case 0xc9: POP(pc); WZ = PCD; break; /* RET */ +//#endif + case 0xca: JP_COND(F & ZF); break; /* JP Z,a */ + case 0xcb: OP_CB(FETCHOP()); break; /* **** CB xx */ + case 0xcc: CALL_COND(F & ZF, 0xcc); break; /* CALL Z,a */ + case 0xcd: CALL(); break; /* CALL a */ + case 0xce: ADC(FETCH8()); break; /* ADC A,n */ + case 0xcf: RST(0x08); break; /* RST 1 */ + case 0xd0: RET_COND(!(F & CF), 0xd0); break; /* RET NC */ + case 0xd1: POP(de); break; /* POP DE */ + case 0xd2: JP_COND(!(F & CF)); break; /* JP NC,a */ + case 0xd3: {unsigned n = FETCH8() | (A << 8); OUT8(n, A); WZ_L = ((n & 0xff) + 1) & 0xff; WZ_H = A;} break; /* OUT (n),A */ + case 0xd4: CALL_COND(!(F & CF), 0xd4); break; /* CALL NC,a */ + case 0xd5: PUSH(de); break; /* PUSH DE */ + case 0xd6: SUB(FETCH8()); break; /* SUB n */ + case 0xd7: RST(0x10); break; /* RST 2 */ + case 0xd8: RET_COND(F & CF, 0xd8); break; /* RET C */ + case 0xd9: EXX(); break; /* EXX */ + case 0xda: JP_COND(F & CF); break; /* JP C,a */ + case 0xdb: {unsigned n = FETCH8() | (A << 8); A = IN8(n); WZ = n + 1;} break; /* IN A,(n) */ + case 0xdc: CALL_COND(F & CF, 0xdc); break; /* CALL C,a */ + case 0xdd: OP_DD(FETCHOP()); break; /* **** DD xx */ + case 0xde: SBC(FETCH8()); break; /* SBC A,n */ + case 0xdf: RST(0x18); break; /* RST 3 */ + case 0xe0: RET_COND(!(F & PF), 0xe0); break; /* RET PO */ + case 0xe1: POP(hl); break; /* POP HL */ + case 0xe2: JP_COND(!(F & PF)); break; /* JP PO,a */ + case 0xe3: EXSP(hl); break; /* EX HL,(SP) */ + case 0xe4: CALL_COND(!(F & PF), 0xe4); break; /* CALL PO,a */ + case 0xe5: PUSH(hl); break; /* PUSH HL */ + case 0xe6: AND(FETCH8()); break; /* AND n */ + case 0xe7: RST(0x20); break; /* RST 4 */ + case 0xe8: RET_COND(F & PF, 0xe8); break; /* RET PE */ + case 0xe9: PC = HL; break; /* JP (HL) */ + case 0xea: JP_COND(F & PF); break; /* JP PE,a */ + case 0xeb: EX_DE_HL(); break; /* EX DE,HL */ + case 0xec: CALL_COND(F & PF, 0xec); break; /* CALL PE,a */ + case 0xed: OP_ED(FETCHOP()); break; /* **** ED xx */ + case 0xee: XOR(FETCH8()); break; /* XOR n */ + case 0xef: RST(0x28); break; /* RST 5 */ + case 0xf0: RET_COND(!(F & SF), 0xf0); break; /* RET P */ + case 0xf1: POP(af); break; /* POP AF */ + case 0xf2: JP_COND(!(F & SF)); break; /* JP P,a */ + case 0xf3: iff1 = iff2 = 0; break; /* DI */ + case 0xf4: CALL_COND(!(F & SF), 0xf4); break; /* CALL P,a */ + case 0xf5: PUSH(af); break; /* PUSH AF */ + case 0xf6: OR(FETCH8()); break; /* OR n */ + case 0xf7: RST(0x30); break; /* RST 6 */ + case 0xf8: RET_COND(F & SF, 0xf8); break; /* RET M */ + case 0xf9: SP = HL; break; /* LD SP,HL */ + case 0xfa: JP_COND(F & SF); break; /* JP M,a */ + case 0xfb: EI(); break; /* EI */ + case 0xfc: CALL_COND(F & SF, 0xfc); break; /* CALL M,a */ + case 0xfd: OP_FD(FETCHOP()); break; /* **** FD xx */ + case 0xfe: CP(FETCH8()); break; /* CP n */ + case 0xff: RST(0x38); break; /* RST 7 */ +#if defined(_MSC_VER) && (_MSC_VER >= 1200) + default: __assume(0); #endif + } +} + + +void Z80::initialize() +{ + DEVICE::initialize(); + if(!flags_initialized) { + uint8_t *padd = SZHVC_add; + uint8_t *padc = SZHVC_add + 256 * 256; + uint8_t *psub = SZHVC_sub; + uint8_t *psbc = SZHVC_sub + 256 * 256; + + for(int oldval = 0; oldval < 256; oldval++) { + for(int newval = 0; newval < 256; newval++) { + /* add or adc w/o carry set */ + int val = newval - oldval; + *padd = (newval) ? ((newval & 0x80) ? SF : 0) : ZF; + *padd |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if((newval & 0x0f) < (oldval & 0x0f)) *padd |= HF; + if(newval < oldval) *padd |= CF; + if((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padd |= VF; + padd++; + + /* adc with carry set */ + val = newval - oldval - 1; + *padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF; + *padc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if((newval & 0x0f) <= (oldval & 0x0f)) *padc |= HF; + if(newval <= oldval) *padc |= CF; + if((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padc |= VF; + padc++; + + /* cp, sub or sbc w/o carry set */ + val = oldval - newval; + *psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF); + *psub |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if((newval & 0x0f) > (oldval & 0x0f)) *psub |= HF; + if(newval > oldval) *psub |= CF; + if((val ^ oldval) & (oldval ^ newval) & 0x80) *psub |= VF; + psub++; + + /* sbc with carry set */ + val = oldval - newval - 1; + *psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF); + *psbc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + if((newval & 0x0f) >= (oldval & 0x0f)) *psbc |= HF; + if(newval >= oldval) *psbc |= CF; + if((val ^ oldval) & (oldval ^ newval) & 0x80) *psbc |= VF; + psbc++; + } + } + for(int i = 0; i < 256; i++) { + int p = 0; + if(i & 0x01) ++p; + if(i & 0x02) ++p; + if(i & 0x04) ++p; + if(i & 0x08) ++p; + if(i & 0x10) ++p; + if(i & 0x20) ++p; + if(i & 0x40) ++p; + if(i & 0x80) ++p; + SZ[i] = i ? i & SF : ZF; + SZ[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ + SZ_BIT[i] = i ? i & SF : ZF | PF; + SZ_BIT[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ + SZP[i] = SZ[i] | ((p & 1) ? 0 : PF); + SZHV_inc[i] = SZ[i]; + if(i == 0x80) SZHV_inc[i] |= VF; + if((i & 0x0f) == 0x00) SZHV_inc[i] |= HF; + SZHV_dec[i] = SZ[i] | NF; + if(i == 0x7f) SZHV_dec[i] |= VF; + if((i & 0x0f) == 0x0f) SZHV_dec[i] |= HF; + } + flags_initialized = true; + } + is_primary = is_primary_cpu(this); + + // Collecting stateus. + cycles_tmp_count = 0; + extra_tmp_count = 0; + insns_count = 0; + frames_count = 0; + nmi_count = 0; + irq_count = 0; + nsc800_int_count = 0; + nsc800_rsta_count = 0; + nsc800_rsta_count = 0; + nsc800_rsta_count = 0; + register_frame_event(this); + +//#ifdef USE_DEBUGGER + __USE_DEBUGGER = osd->check_feature(_T("USE_DEBUGGER")); + if((__USE_DEBUGGER) && (d_debugger != NULL)) { + d_mem_stored = d_mem; + d_io_stored = d_io; + d_debugger->set_context_mem(d_mem); + d_debugger->set_context_io(d_io); + } + if(osd->check_feature(_T("CPU_START_ADDR"))) { + __CPU_START_ADDR = osd->get_feature_uint32_value(_T("CPU_START_ADDR")); + } else { + __CPU_START_ADDR = 0; + } +//#endif +//#ifdef HAS_NSC800 + has_nsc800 = osd->check_feature(_T("HAS_NSC800")); +//#endif +//#ifdef Z80_PSEUDO_BIOS + has_pseudo_bios = osd->check_feature(_T("Z80_PSEUDO_BIOS")); +//#endif +//#ifdef SINGLE_MODE_DMA + has_single_mode_dma = osd->check_feature(_T("SINGLE_MODE_DMA")); +//#endif +//#ifdef Z80_MEMORY_WAIT + has_memory_wait = osd->check_feature(_T("Z80_MEMORY_WAIT")); +//#endif +//#ifdef Z80_IO_WAIT + has_io_wait = osd->check_feature(_T("Z80_IO_WAIT")); +//#endif +//#ifdef HAS_LDAIR_QUIRK + has_ldair_quirk = osd->check_feature(_T("HAS_LDAIR_QUIRK")); +//#endif +} +void Z80::event_frame() +{ + if(frames_count < 0) { + cycles_tmp_count = total_icount; + extra_tmp_count = 0; + insns_count = 0; + frames_count = 0; + nmi_count = 0; + irq_count = 0; + nsc800_int_count = 0; + nsc800_rsta_count = 0; + nsc800_rstb_count = 0; + nsc800_rstc_count = 0; + } else if(frames_count >= 16) { + uint64_t _icount = total_icount - cycles_tmp_count; + if(config.print_statistics) { + if(has_nsc800) { + out_debug_log(_T("INFO: 16 frames done.\nINFO: CLOCKS = %ld INSNS = %d EXTRA_ICOUNT = %d \nINFO: NMI# = %d IRQ# = %d NSC800_INT# = %d RSTA# = %d RSTB# = %d RSTC# = %d"), + _icount, insns_count, extra_tmp_count, nmi_count, irq_count, + nsc800_int_count, nsc800_rsta_count, nsc800_rstb_count, nsc800_rstc_count); + } else { + out_debug_log(_T("INFO: 16 frames done.\nINFO: CLOCKS = %ld INSNS = %d EXTRA_ICOUNT = %d \nINFO: NMI# = %d IRQ# = %d"), _icount, insns_count, extra_tmp_count, nmi_count, irq_count); + } + } + cycles_tmp_count = total_icount; + insns_count = 0; + extra_tmp_count = 0; + frames_count = 0; + nmi_count = 0; + irq_count = 0; + nsc800_int_count = 0; + nsc800_rsta_count = 0; + nsc800_rstb_count = 0; + nsc800_rstc_count = 0; + } else { + frames_count++; + } + } void Z80::reset() { - PCD = CPU_START_ADDR; + PCD = __CPU_START_ADDR; SPD = 0; AFD = BCD = DED = HLD = 0; IXD = IYD = 0xffff; /* IX and IY are FFFF after a reset! */ @@ -170,38 +2078,79 @@ void Z80::reset() icount = extra_icount = busreq_icount = 0; } +void __FASTCALL Z80::write_signal(int id, uint32_t data, uint32_t mask) +{ + if(id == SIG_CPU_IRQ) { + intr_req_bit = (intr_req_bit & ~mask) | (data & mask); + // always pending (temporary) + intr_pend_bit = (intr_pend_bit & ~mask) | (0xffffffff & mask); + irq_count++; + } else if(id == SIG_CPU_NMI) { + intr_req_bit = (data & mask) ? (intr_req_bit | NMI_REQ_BIT) : (intr_req_bit & ~NMI_REQ_BIT); + nmi_count++; + } else if(id == SIG_CPU_BUSREQ) { + busreq = ((data & mask) != 0); + write_signals(&outputs_busack, busreq ? 0xffffffff : 0); + } else if(has_nsc800) { +//#ifdef HAS_NSC800 + if(id == SIG_NSC800_INT) { + intr_req_bit = (data & mask) ? (intr_req_bit | 1) : (intr_req_bit & ~1); + nsc800_int_count++; + } else if(id == SIG_NSC800_RSTA) { + intr_req_bit = (data & mask) ? (intr_req_bit | 8) : (intr_req_bit & ~8); + nsc800_rsta_count++; + } else if(id == SIG_NSC800_RSTB) { + intr_req_bit = (data & mask) ? (intr_req_bit | 4) : (intr_req_bit & ~4); + nsc800_rstb_count++; + } else if(id == SIG_NSC800_RSTC) { + intr_req_bit = (data & mask) ? (intr_req_bit | 2) : (intr_req_bit & ~2); + nsc800_rstc_count++; + } + } +//#endif +} + +uint32_t __FASTCALL Z80::read_signal(int id) +{ + if(id == SIG_CPU_IRQ) { + return intr_req_bit; + } + return 0; +} void __FASTCALL Z80::debugger_hook(void) { -#ifdef USE_DEBUGGER - bool now_debugging = d_debugger->now_debugging; - if(now_debugging) { - d_debugger->check_break_points(PC); - if(d_debugger->now_suspended) { - osd->mute_sound(); - d_debugger->now_waiting = true; - while(d_debugger->now_debugging && d_debugger->now_suspended) { - osd->sleep(10); +//#ifdef USE_DEBUGGER + if((__USE_DEBUGGER) && (d_debugger != NULL)) { + bool now_debugging = d_debugger->now_debugging; + if(now_debugging) { + d_debugger->check_break_points(PC); + if(d_debugger->now_suspended) { + osd->mute_sound(); + d_debugger->now_waiting = true; + while(d_debugger->now_debugging && d_debugger->now_suspended) { + osd->sleep(10); + } + d_debugger->now_waiting = false; + } + if(d_debugger->now_debugging) { + d_mem = d_debugger; + } else { + now_debugging = false; } - d_debugger->now_waiting = false; - } - if(d_debugger->now_debugging) { - d_mem = d_debugger; - } else { - now_debugging = false; - } - //d_debugger->add_cpu_trace(PC); - int first_icount = icount; - //pPPC = pPC; - if(now_debugging) { - if(!d_debugger->now_going) { - d_debugger->now_suspended = true; + //d_debugger->add_cpu_trace(PC); + int first_icount = icount; + //pPPC = pPC; + if(now_debugging) { + if(!d_debugger->now_going) { + d_debugger->now_suspended = true; + } + d_mem = d_mem_stored; } - d_mem = d_mem_stored; } } -#endif +//#endif } @@ -215,19 +2164,19 @@ int Z80::run(int clock) // this is primary cpu if(busreq) { // run dma once - #ifdef SINGLE_MODE_DMA - if(d_dma) { + //#ifdef SINGLE_MODE_DMA + if((d_dma != NULL) && (has_single_mode_dma)) { d_dma->do_dma(); - } - #endif + } + //#endif // don't run cpu! int passed_icount = max(1, extra_icount); // this is main cpu, icount is not used /*icount = */extra_icount = 0; total_icount += passed_icount; - #ifdef USE_DEBUGGER + //#ifdef USE_DEBUGGER debugger_hook(); - #endif + //#endif return passed_icount; } else { // run only one opcode @@ -247,21 +2196,21 @@ int Z80::run(int clock) icount += clock; int first_icount = icount; //#ifdef USE_DEBUGGER - total_icount += extra_icount; + total_icount += extra_icount; //#endif icount -= extra_icount; extra_icount = 0; if(busreq) { // run dma once - #ifdef USE_DEBUGGER - debugger_hook(); - #endif - #ifdef SINGLE_MODE_DMA - if(d_dma) { - d_dma->do_dma(); - } - #endif + //#ifdef USE_DEBUGGER + debugger_hook(); + //#endif + //#ifdef SINGLE_MODE_DMA + if((d_dma != NULL) && (has_single_mode_dma)) { + d_dma->do_dma(); + } + //#endif } else { // run cpu while given clocks while(icount > 0 && !busreq) { @@ -272,7 +2221,7 @@ int Z80::run(int clock) // if busreq is raised, spin cpu while remained clock if(icount > 0 && busreq) { //#ifdef USE_DEBUGGER - total_icount += icount; + total_icount += icount; //#endif icount = 0; } @@ -284,8 +2233,11 @@ int Z80::run(int clock) void __FASTCALL Z80::run_one_opecode() { // rune one opecode -#ifdef USE_DEBUGGER - bool now_debugging = d_debugger->now_debugging; +//#ifdef USE_DEBUGGER + bool now_debugging = false; + if((__USE_DEBUGGER) && (d_debugger != NULL)) { + now_debugging = d_debugger->now_debugging; + } if(now_debugging) { d_debugger->check_break_points(PC); if(d_debugger->now_suspended) { @@ -304,20 +2256,22 @@ void __FASTCALL Z80::run_one_opecode() } after_halt = after_ei = false; -#if HAS_LDAIR_QUIRK - after_ldair = false; -#endif +//#if HAS_LDAIR_QUIRK + if(has_ldair_quirk) { + after_ldair = false; + } +//#endif OP(FETCHOP()); -#if HAS_LDAIR_QUIRK - if(after_ldair) { +//#if HAS_LDAIR_QUIRK + if((has_ldair_quirk) && (after_ldair)) { F &= ~PF; // reset parity flag after LD A,I or LD A,R } -#endif -#ifdef SINGLE_MODE_DMA - if(d_dma) { +//#endif +//#ifdef SINGLE_MODE_DMA + if((d_dma != NULL) && (has_single_mode_dma)) { d_dma->do_dma(); } -#endif +//#endif if(!after_ei) { check_interrupt(); } @@ -330,38 +2284,43 @@ void __FASTCALL Z80::run_one_opecode() d_io = d_io_stored; } } else { -#endif +//#endif after_halt = after_ei = false; -#if HAS_LDAIR_QUIRK - after_ldair = false; -#endif +//#if HAS_LDAIR_QUIRK + if(has_ldair_quirk) { + after_ldair = false; + } +//#endif d_debugger->add_cpu_trace(PC); int first_icount = icount; OP(FETCHOP()); icount -= extra_icount; extra_icount = 0; total_icount += first_icount - icount; -#if HAS_LDAIR_QUIRK - if(after_ldair) { +//#if HAS_LDAIR_QUIRK + if((has_ldair_quirk) && (after_ldair)) { F &= ~PF; // reset parity flag after LD A,I or LD A,R } -#endif -#ifdef SINGLE_MODE_DMA - if(d_dma) { +//#endif +//#ifdef SINGLE_MODE_DMA + if((d_dma != NULL) && (has_single_mode_dma)) { d_dma->do_dma(); } -#endif +//#endif if(!after_ei) { check_interrupt(); } -#ifdef USE_DEBUGGER +//#ifdef USE_DEBUGGER } -#endif +//#endif // ei: run next opecode + now_debugging = false; if(after_ei) { -#ifdef USE_DEBUGGER - bool now_debugging = d_debugger->now_debugging; +//#ifdef USE_DEBUGGER + if((__USE_DEBUGGER) && (d_debugger != NULL)) { + now_debugging = d_debugger->now_debugging; + } if(now_debugging) { d_debugger->check_break_points(PC); if(d_debugger->now_suspended) { @@ -380,20 +2339,22 @@ void __FASTCALL Z80::run_one_opecode() } after_halt = false; -#if HAS_LDAIR_QUIRK +//#if HAS_LDAIR_QUIRK + if(has_ldair_quirk) { after_ldair = false; -#endif + } +//#endif OP(FETCHOP()); -#if HAS_LDAIR_QUIRK - if(after_ldair) { +//#if HAS_LDAIR_QUIRK + if((has_ldair_quirk) && (after_ldair)) { F &= ~PF; // reset parity flag after LD A,I or LD A,R } -#endif -#ifdef SINGLE_MODE_DMA - if(d_dma) { +//#endif +//#ifdef SINGLE_MODE_DMA + if((d_dma != NULL) && (has_single_mode_dma)) { d_dma->do_dma(); } -#endif +//#endif if(d_pic != NULL) d_pic->notify_intr_ei(); check_interrupt(); @@ -405,44 +2366,48 @@ void __FASTCALL Z80::run_one_opecode() d_io = d_io_stored; } } else { -#endif +//#endif after_halt = false; -#if HAS_LDAIR_QUIRK - after_ldair = false; -#endif +//#if HAS_LDAIR_QUIRK + if(has_ldair_quirk) { + after_ldair = false; + } +//#endif d_debugger->add_cpu_trace(PC); int first_icount = icount; OP(FETCHOP()); icount -= extra_icount; extra_icount = 0; total_icount += first_icount - icount; -#if HAS_LDAIR_QUIRK - if(after_ldair) { +//#if HAS_LDAIR_QUIRK + if((has_ldair_quirk) &&(after_ldair)) { F &= ~PF; // reset parity flag after LD A,I or LD A,R } -#endif -#ifdef SINGLE_MODE_DMA - if(d_dma) { +//#endif +//#ifdef SINGLE_MODE_DMA + if((d_dma != NULL) && (has_single_mode_dma)) { d_dma->do_dma(); } -#endif +//#endif if(d_pic != NULL) d_pic->notify_intr_ei(); check_interrupt(); -#ifdef USE_DEBUGGER +//#ifdef USE_DEBUGGER } -#endif +//#endif } -#ifndef USE_DEBUGGER - icount -= extra_icount; - extra_icount = 0; -#endif +//#ifndef USE_DEBUGGER + if(!(__USE_DEBUGGER)) { // OK? + icount -= extra_icount; + extra_icount = 0; + } +//#endif } void Z80::check_interrupt() { -#ifdef USE_DEBUGGER +//#ifdef USE_DEBUGGER int first_icount = icount; -#endif +//#endif // check interrupt if(intr_req_bit) { if(intr_req_bit & NMI_REQ_BIT) { @@ -541,7 +2506,7 @@ void Z80::check_interrupt() //#endif } -#ifdef USE_DEBUGGER +//#ifdef USE_DEBUGGER void __FASTCALL Z80::write_debug_data8(uint32_t addr, uint32_t data) { int wait; @@ -566,14 +2531,1507 @@ uint32_t __FASTCALL Z80::read_debug_io8(uint32_t addr) return d_io_stored->read_io8w(addr, &wait); } +bool Z80::write_debug_reg(const _TCHAR *reg, uint32_t data) +{ + if(_tcsicmp(reg, _T("PC")) == 0) { + PC = data; + } else if(_tcsicmp(reg, _T("SP")) == 0) { + SP = data; + } else if(_tcsicmp(reg, _T("AF")) == 0) { + AF = data; + } else if(_tcsicmp(reg, _T("BC")) == 0) { + BC = data; + } else if(_tcsicmp(reg, _T("DE")) == 0) { + DE = data; + } else if(_tcsicmp(reg, _T("HL")) == 0) { + HL = data; + } else if(_tcsicmp(reg, _T("IX")) == 0) { + IX = data; + } else if(_tcsicmp(reg, _T("IY")) == 0) { + IY = data; + } else if(_tcsicmp(reg, _T("A")) == 0) { + A = data; + } else if(_tcsicmp(reg, _T("F")) == 0) { + F = data; + } else if(_tcsicmp(reg, _T("B")) == 0) { + B = data; + } else if(_tcsicmp(reg, _T("C")) == 0) { + C = data; + } else if(_tcsicmp(reg, _T("D")) == 0) { + D = data; + } else if(_tcsicmp(reg, _T("E")) == 0) { + E = data; + } else if(_tcsicmp(reg, _T("H")) == 0) { + H = data; + } else if(_tcsicmp(reg, _T("L")) == 0) { + L = data; + } else if(_tcsicmp(reg, _T("HX")) == 0 || _tcsicmp(reg, _T("XH")) == 0 || _tcsicmp(reg, _T("IXH")) == 0) { + HX = data; + } else if(_tcsicmp(reg, _T("LX")) == 0 || _tcsicmp(reg, _T("XL")) == 0 || _tcsicmp(reg, _T("IXL")) == 0) { + LX = data; + } else if(_tcsicmp(reg, _T("HY")) == 0 || _tcsicmp(reg, _T("YH")) == 0 || _tcsicmp(reg, _T("IYH")) == 0) { + HY = data; + } else if(_tcsicmp(reg, _T("LX")) == 0 || _tcsicmp(reg, _T("YL")) == 0 || _tcsicmp(reg, _T("IYL")) == 0) { + LY = data; + } else if(_tcsicmp(reg, _T("I")) == 0) { + I = data; + } else if(_tcsicmp(reg, _T("R")) == 0) { + R = data; + } else if(_tcsicmp(reg, _T("AF'")) == 0) { + AF2 = data; + } else if(_tcsicmp(reg, _T("BC'")) == 0) { + BC2 = data; + } else if(_tcsicmp(reg, _T("DE'")) == 0) { + DE2 = data; + } else if(_tcsicmp(reg, _T("HL'")) == 0) { + HL2 = data; + } else if(_tcsicmp(reg, _T("A'")) == 0) { + A2 = data; + } else if(_tcsicmp(reg, _T("F'")) == 0) { + F2 = data; + } else if(_tcsicmp(reg, _T("B'")) == 0) { + B2 = data; + } else if(_tcsicmp(reg, _T("C'")) == 0) { + C2 = data; + } else if(_tcsicmp(reg, _T("D'")) == 0) { + D2 = data; + } else if(_tcsicmp(reg, _T("E'")) == 0) { + E2 = data; + } else if(_tcsicmp(reg, _T("H'")) == 0) { + H2 = data; + } else if(_tcsicmp(reg, _T("L'")) == 0) { + L2 = data; + } else { + return false; + } + return true; +} + +bool Z80::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) +{ +/* +F = [--------] A = 00 BC = 0000 DE = 0000 HL = 0000 IX = 0000 IY = 0000 +F'= [--------] A'= 00 BC'= 0000 DE'= 0000 HL'= 0000 SP = 0000 PC = 0000 + I = 00 R = 00 (BC)= 0000 (DE)= 0000 (HL)= 0000 (SP)= 0000 EI:IFF2=0 +Total CPU Clocks = 0 (0) Since Scanline = 0/0 (0/0) +*/ + int wait; + my_stprintf_s(buffer, buffer_len, + _T("F = [%c%c%c%c%c%c%c%c] A = %02X BC = %04X DE = %04X HL = %04X IX = %04X IY = %04X\n") + _T("F'= [%c%c%c%c%c%c%c%c] A'= %02X BC'= %04X DE'= %04X HL'= %04X SP = %04X PC = %04X\n") + _T(" I = %02X R = %02X (BC)= %04X (DE)= %04X (HL)= %04X (SP)= %04X %cI:IFF2=%d\n") + _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), + + (F & CF) ? _T('C') : _T('-'), (F & NF) ? _T('N') : _T('-'), (F & PF) ? _T('P') : _T('-'), (F & XF) ? _T('X') : _T('-'), + (F & HF) ? _T('H') : _T('-'), (F & YF) ? _T('Y') : _T('-'), (F & ZF) ? _T('Z') : _T('-'), (F & SF) ? _T('S') : _T('-'), + A, BC, DE, HL, IX, IY, + (F2 & CF) ? _T('C') : _T('-'), (F2 & NF) ? _T('N') : _T('-'), (F2 & PF) ? _T('P') : _T('-'), (F2 & XF) ? _T('X') : _T('-'), + (F2 & HF) ? _T('H') : _T('-'), (F2 & YF) ? _T('Y') : _T('-'), (F2 & ZF) ? _T('Z') : _T('-'), (F2 & SF) ? _T('S') : _T('-'), + A2, BC2, DE2, HL2, SP, PC, + I, R, + d_mem_stored->read_data16w(BC, &wait), d_mem_stored->read_data16w(DE, &wait), d_mem_stored->read_data16w(HL, &wait), d_mem_stored->read_data16w(SP, &wait), + iff1 ? _T('E') : _T('D'), iff2, + total_icount, total_icount - prev_total_icount, + get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); + prev_total_icount = total_icount; + return true; +} + // disassembler extern "C" { extern int z80_dasm_main(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); +static void dasm_cb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); +static void dasm_dd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); +static void dasm_ed(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); +static void dasm_fd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); +static void dasm_ddcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); +static void dasm_fdcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); + +uint8_t z80_dasm_ops[4]; +int z80_dasm_ptr; -extern uint8_t z80_dasm_ops[4]; -extern int z80_dasm_ptr; +inline uint8_t dasm_fetchop() +{ + return z80_dasm_ops[z80_dasm_ptr++]; +} + +inline uint8_t debug_fetch8() +{ + return z80_dasm_ops[z80_dasm_ptr++]; +} + +inline uint16_t debug_fetch16() +{ + uint16_t val = z80_dasm_ops[z80_dasm_ptr] | (z80_dasm_ops[z80_dasm_ptr + 1] << 8); + z80_dasm_ptr += 2; + return val; +} + +inline int8_t debug_fetch8_rel() +{ + return (int8_t)z80_dasm_ops[z80_dasm_ptr++]; +} + +inline uint16_t debug_fetch8_relpc(uint32_t pc) +{ + int8_t res = (int8_t)z80_dasm_ops[z80_dasm_ptr++]; + return pc + z80_dasm_ptr + res; +} + +int z80_dasm_main(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) +{ + buffer[0] = _T('\0'); + z80_dasm_ptr = 0; + uint8_t code = dasm_fetchop(); + + switch(code) { + case 0x00: my_stprintf_s(buffer, buffer_len, _T("NOP")); break; + case 0x01: my_stprintf_s(buffer, buffer_len, _T("LD BC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x02: my_stprintf_s(buffer, buffer_len, _T("LD (BC), A")); break; + case 0x03: my_stprintf_s(buffer, buffer_len, _T("INC BC")); break; + case 0x04: my_stprintf_s(buffer, buffer_len, _T("INC B")); break; + case 0x05: my_stprintf_s(buffer, buffer_len, _T("DEC B")); break; + case 0x06: my_stprintf_s(buffer, buffer_len, _T("LD B, %02x"), debug_fetch8()); break; + case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLCA")); break; + case 0x08: my_stprintf_s(buffer, buffer_len, _T("EX AF, AF'")); break; + case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD HL, BC")); break; + case 0x0a: my_stprintf_s(buffer, buffer_len, _T("LD A, (BC)")); break; + case 0x0b: my_stprintf_s(buffer, buffer_len, _T("DEC BC")); break; + case 0x0c: my_stprintf_s(buffer, buffer_len, _T("INC C")); break; + case 0x0d: my_stprintf_s(buffer, buffer_len, _T("DEC C")); break; + case 0x0e: my_stprintf_s(buffer, buffer_len, _T("LD C, %02x"), debug_fetch8()); break; + case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRCA")); break; + case 0x10: my_stprintf_s(buffer, buffer_len, _T("DJNZ %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; + case 0x11: my_stprintf_s(buffer, buffer_len, _T("LD DE, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x12: my_stprintf_s(buffer, buffer_len, _T("LD (DE), A")); break; + case 0x13: my_stprintf_s(buffer, buffer_len, _T("INC DE")); break; + case 0x14: my_stprintf_s(buffer, buffer_len, _T("INC D")); break; + case 0x15: my_stprintf_s(buffer, buffer_len, _T("DEC D")); break; + case 0x16: my_stprintf_s(buffer, buffer_len, _T("LD D, %02x"), debug_fetch8()); break; + case 0x17: my_stprintf_s(buffer, buffer_len, _T("RLA")); break; + case 0x18: my_stprintf_s(buffer, buffer_len, _T("JR %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; + case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD HL, DE")); break; + case 0x1a: my_stprintf_s(buffer, buffer_len, _T("LD A, (DE)")); break; + case 0x1b: my_stprintf_s(buffer, buffer_len, _T("DEC DE")); break; + case 0x1c: my_stprintf_s(buffer, buffer_len, _T("INC E")); break; + case 0x1d: my_stprintf_s(buffer, buffer_len, _T("DEC E")); break; + case 0x1e: my_stprintf_s(buffer, buffer_len, _T("LD E, %02x"), debug_fetch8()); break; + case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RRA")); break; + case 0x20: my_stprintf_s(buffer, buffer_len, _T("JR NZ, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; + case 0x21: my_stprintf_s(buffer, buffer_len, _T("LD HL, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x22: my_stprintf_s(buffer, buffer_len, _T("LD (%s), HL"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x23: my_stprintf_s(buffer, buffer_len, _T("INC HL")); break; + case 0x24: my_stprintf_s(buffer, buffer_len, _T("INC H")); break; + case 0x25: my_stprintf_s(buffer, buffer_len, _T("DEC H")); break; + case 0x26: my_stprintf_s(buffer, buffer_len, _T("LD H, %02x"), debug_fetch8()); break; + case 0x27: my_stprintf_s(buffer, buffer_len, _T("DAA")); break; + case 0x28: my_stprintf_s(buffer, buffer_len, _T("JR Z, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; + case 0x29: my_stprintf_s(buffer, buffer_len, _T("ADD HL, HL")); break; + case 0x2a: my_stprintf_s(buffer, buffer_len, _T("LD HL, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x2b: my_stprintf_s(buffer, buffer_len, _T("DEC HL")); break; + case 0x2c: my_stprintf_s(buffer, buffer_len, _T("INC L")); break; + case 0x2d: my_stprintf_s(buffer, buffer_len, _T("DEC L")); break; + case 0x2e: my_stprintf_s(buffer, buffer_len, _T("LD L, %02x"), debug_fetch8()); break; + case 0x2f: my_stprintf_s(buffer, buffer_len, _T("CPL")); break; + case 0x30: my_stprintf_s(buffer, buffer_len, _T("JR NC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; + case 0x31: my_stprintf_s(buffer, buffer_len, _T("LD SP, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x32: my_stprintf_s(buffer, buffer_len, _T("LD (%s), A"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x33: my_stprintf_s(buffer, buffer_len, _T("INC SP")); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("INC (HL)")); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("DEC (HL)")); break; + case 0x36: my_stprintf_s(buffer, buffer_len, _T("LD (HL), %02x"), debug_fetch8()); break; + case 0x37: my_stprintf_s(buffer, buffer_len, _T("SCF")); break; + case 0x38: my_stprintf_s(buffer, buffer_len, _T("JR C, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; + case 0x39: my_stprintf_s(buffer, buffer_len, _T("ADD HL, SP")); break; + case 0x3a: my_stprintf_s(buffer, buffer_len, _T("LD A, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x3b: my_stprintf_s(buffer, buffer_len, _T("DEC SP")); break; + case 0x3c: my_stprintf_s(buffer, buffer_len, _T("INC A")); break; + case 0x3d: my_stprintf_s(buffer, buffer_len, _T("DEC A")); break; + case 0x3e: my_stprintf_s(buffer, buffer_len, _T("LD A, %02x"), debug_fetch8()); break; + case 0x3f: my_stprintf_s(buffer, buffer_len, _T("CCF")); break; + case 0x40: my_stprintf_s(buffer, buffer_len, _T("LD B, B")); break; + case 0x41: my_stprintf_s(buffer, buffer_len, _T("LD B, C")); break; + case 0x42: my_stprintf_s(buffer, buffer_len, _T("LD B, D")); break; + case 0x43: my_stprintf_s(buffer, buffer_len, _T("LD B, E")); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("LD B, H")); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("LD B, L")); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("LD B, (HL)")); break; + case 0x47: my_stprintf_s(buffer, buffer_len, _T("LD B, A")); break; + case 0x48: my_stprintf_s(buffer, buffer_len, _T("LD C, B")); break; + case 0x49: my_stprintf_s(buffer, buffer_len, _T("LD C, C")); break; + case 0x4a: my_stprintf_s(buffer, buffer_len, _T("LD C, D")); break; + case 0x4b: my_stprintf_s(buffer, buffer_len, _T("LD C, E")); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("LD C, H")); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("LD C, L")); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("LD C, (HL)")); break; + case 0x4f: my_stprintf_s(buffer, buffer_len, _T("LD C, A")); break; + case 0x50: my_stprintf_s(buffer, buffer_len, _T("LD D, B")); break; + case 0x51: my_stprintf_s(buffer, buffer_len, _T("LD D, C")); break; + case 0x52: my_stprintf_s(buffer, buffer_len, _T("LD D, D")); break; + case 0x53: my_stprintf_s(buffer, buffer_len, _T("LD D, E")); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("LD D, H")); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("LD D, L")); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("LD D, (HL)")); break; + case 0x57: my_stprintf_s(buffer, buffer_len, _T("LD D, A")); break; + case 0x58: my_stprintf_s(buffer, buffer_len, _T("LD E, B")); break; + case 0x59: my_stprintf_s(buffer, buffer_len, _T("LD E, C")); break; + case 0x5a: my_stprintf_s(buffer, buffer_len, _T("LD E, D")); break; + case 0x5b: my_stprintf_s(buffer, buffer_len, _T("LD E, E")); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("LD E, H")); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("LD E, L")); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("LD E, (HL)")); break; + case 0x5f: my_stprintf_s(buffer, buffer_len, _T("LD E, A")); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("LD H, B")); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("LD H, C")); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("LD H, D")); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD H, E")); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("LD H, H")); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("LD H, L")); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("LD H, (HL)")); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("LD H, A")); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("LD L, B")); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("LD L, C")); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("LD L, D")); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD L, E")); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("LD L, H")); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("LD L, L")); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("LD L, (HL)")); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("LD L, A")); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("LD (HL), B")); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("LD (HL), C")); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("LD (HL), D")); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (HL), E")); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("LD (HL), H")); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("LD (HL), L")); break; + case 0x76: my_stprintf_s(buffer, buffer_len, _T("HALT")); break; + case 0x77: my_stprintf_s(buffer, buffer_len, _T("LD (HL), A")); break; + case 0x78: my_stprintf_s(buffer, buffer_len, _T("LD A, B")); break; + case 0x79: my_stprintf_s(buffer, buffer_len, _T("LD A, C")); break; + case 0x7a: my_stprintf_s(buffer, buffer_len, _T("LD A, D")); break; + case 0x7b: my_stprintf_s(buffer, buffer_len, _T("LD A, E")); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("LD A, H")); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("LD A, L")); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("LD A, (HL)")); break; + case 0x7f: my_stprintf_s(buffer, buffer_len, _T("LD A, A")); break; + case 0x80: my_stprintf_s(buffer, buffer_len, _T("ADD A, B")); break; + case 0x81: my_stprintf_s(buffer, buffer_len, _T("ADD A, C")); break; + case 0x82: my_stprintf_s(buffer, buffer_len, _T("ADD A, D")); break; + case 0x83: my_stprintf_s(buffer, buffer_len, _T("ADD A, E")); break; + case 0x84: my_stprintf_s(buffer, buffer_len, _T("ADD A, H")); break; + case 0x85: my_stprintf_s(buffer, buffer_len, _T("ADD A, L")); break; + case 0x86: my_stprintf_s(buffer, buffer_len, _T("ADD A, (HL)")); break; + case 0x87: my_stprintf_s(buffer, buffer_len, _T("ADD A, A")); break; + case 0x88: my_stprintf_s(buffer, buffer_len, _T("ADC A, B")); break; + case 0x89: my_stprintf_s(buffer, buffer_len, _T("ADC A, C")); break; + case 0x8a: my_stprintf_s(buffer, buffer_len, _T("ADC A, D")); break; + case 0x8b: my_stprintf_s(buffer, buffer_len, _T("ADC A, E")); break; + case 0x8c: my_stprintf_s(buffer, buffer_len, _T("ADC A, H")); break; + case 0x8d: my_stprintf_s(buffer, buffer_len, _T("ADC A, L")); break; + case 0x8e: my_stprintf_s(buffer, buffer_len, _T("ADC A, (HL)")); break; + case 0x8f: my_stprintf_s(buffer, buffer_len, _T("ADC A, A")); break; + case 0x90: my_stprintf_s(buffer, buffer_len, _T("SUB B")); break; + case 0x91: my_stprintf_s(buffer, buffer_len, _T("SUB C")); break; + case 0x92: my_stprintf_s(buffer, buffer_len, _T("SUB D")); break; + case 0x93: my_stprintf_s(buffer, buffer_len, _T("SUB E")); break; + case 0x94: my_stprintf_s(buffer, buffer_len, _T("SUB H")); break; + case 0x95: my_stprintf_s(buffer, buffer_len, _T("SUB L")); break; + case 0x96: my_stprintf_s(buffer, buffer_len, _T("SUB (HL)")); break; + case 0x97: my_stprintf_s(buffer, buffer_len, _T("SUB A")); break; + case 0x98: my_stprintf_s(buffer, buffer_len, _T("SBC A, B")); break; + case 0x99: my_stprintf_s(buffer, buffer_len, _T("SBC A, C")); break; + case 0x9a: my_stprintf_s(buffer, buffer_len, _T("SBC A, D")); break; + case 0x9b: my_stprintf_s(buffer, buffer_len, _T("SBC A, E")); break; + case 0x9c: my_stprintf_s(buffer, buffer_len, _T("SBC A, H")); break; + case 0x9d: my_stprintf_s(buffer, buffer_len, _T("SBC A, L")); break; + case 0x9e: my_stprintf_s(buffer, buffer_len, _T("SBC A, (HL)")); break; + case 0x9f: my_stprintf_s(buffer, buffer_len, _T("SBC A, A")); break; + case 0xa0: my_stprintf_s(buffer, buffer_len, _T("AND B")); break; + case 0xa1: my_stprintf_s(buffer, buffer_len, _T("AND C")); break; + case 0xa2: my_stprintf_s(buffer, buffer_len, _T("AND D")); break; + case 0xa3: my_stprintf_s(buffer, buffer_len, _T("AND E")); break; + case 0xa4: my_stprintf_s(buffer, buffer_len, _T("AND H")); break; + case 0xa5: my_stprintf_s(buffer, buffer_len, _T("AND L")); break; + case 0xa6: my_stprintf_s(buffer, buffer_len, _T("AND (HL)")); break; + case 0xa7: my_stprintf_s(buffer, buffer_len, _T("AND A")); break; + case 0xa8: my_stprintf_s(buffer, buffer_len, _T("XOR B")); break; + case 0xa9: my_stprintf_s(buffer, buffer_len, _T("XOR C")); break; + case 0xaa: my_stprintf_s(buffer, buffer_len, _T("XOR D")); break; + case 0xab: my_stprintf_s(buffer, buffer_len, _T("XOR E")); break; + case 0xac: my_stprintf_s(buffer, buffer_len, _T("XOR H")); break; + case 0xad: my_stprintf_s(buffer, buffer_len, _T("XOR L")); break; + case 0xae: my_stprintf_s(buffer, buffer_len, _T("XOR (HL)")); break; + case 0xaf: my_stprintf_s(buffer, buffer_len, _T("XOR A")); break; + case 0xb0: my_stprintf_s(buffer, buffer_len, _T("OR B")); break; + case 0xb1: my_stprintf_s(buffer, buffer_len, _T("OR C")); break; + case 0xb2: my_stprintf_s(buffer, buffer_len, _T("OR D")); break; + case 0xb3: my_stprintf_s(buffer, buffer_len, _T("OR E")); break; + case 0xb4: my_stprintf_s(buffer, buffer_len, _T("OR H")); break; + case 0xb5: my_stprintf_s(buffer, buffer_len, _T("OR L")); break; + case 0xb6: my_stprintf_s(buffer, buffer_len, _T("OR (HL)")); break; + case 0xb7: my_stprintf_s(buffer, buffer_len, _T("OR A")); break; + case 0xb8: my_stprintf_s(buffer, buffer_len, _T("CP B")); break; + case 0xb9: my_stprintf_s(buffer, buffer_len, _T("CP C")); break; + case 0xba: my_stprintf_s(buffer, buffer_len, _T("CP D")); break; + case 0xbb: my_stprintf_s(buffer, buffer_len, _T("CP E")); break; + case 0xbc: my_stprintf_s(buffer, buffer_len, _T("CP H")); break; + case 0xbd: my_stprintf_s(buffer, buffer_len, _T("CP L")); break; + case 0xbe: my_stprintf_s(buffer, buffer_len, _T("CP (HL)")); break; + case 0xbf: my_stprintf_s(buffer, buffer_len, _T("CP A")); break; + case 0xc0: my_stprintf_s(buffer, buffer_len, _T("RET NZ")); break; + case 0xc1: my_stprintf_s(buffer, buffer_len, _T("POP BC")); break; + case 0xc2: my_stprintf_s(buffer, buffer_len, _T("JP NZ, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xc3: my_stprintf_s(buffer, buffer_len, _T("JP %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xc4: my_stprintf_s(buffer, buffer_len, _T("CALL NZ, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xc5: my_stprintf_s(buffer, buffer_len, _T("PUSH BC")); break; + case 0xc6: my_stprintf_s(buffer, buffer_len, _T("ADD A, %02x"), debug_fetch8()); break; + case 0xc7: my_stprintf_s(buffer, buffer_len, _T("RST 00H")); break; + case 0xc8: my_stprintf_s(buffer, buffer_len, _T("RET Z")); break; + case 0xc9: my_stprintf_s(buffer, buffer_len, _T("RET")); break; + case 0xca: my_stprintf_s(buffer, buffer_len, _T("JP Z, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xcb: dasm_cb(pc, buffer, buffer_len, first_symbol); break; + case 0xcc: my_stprintf_s(buffer, buffer_len, _T("CALL Z, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xcd: my_stprintf_s(buffer, buffer_len, _T("CALL %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xce: my_stprintf_s(buffer, buffer_len, _T("ADC A, %02x"), debug_fetch8()); break; + case 0xcf: my_stprintf_s(buffer, buffer_len, _T("RST 08H")); break; + case 0xd0: my_stprintf_s(buffer, buffer_len, _T("RET NC")); break; + case 0xd1: my_stprintf_s(buffer, buffer_len, _T("POP DE")); break; + case 0xd2: my_stprintf_s(buffer, buffer_len, _T("JP NC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xd3: my_stprintf_s(buffer, buffer_len, _T("OUT (%02x), A"), debug_fetch8()); break; + case 0xd4: my_stprintf_s(buffer, buffer_len, _T("CALL NC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xd5: my_stprintf_s(buffer, buffer_len, _T("PUSH DE")); break; + case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SUB %02x"), debug_fetch8()); break; + case 0xd7: my_stprintf_s(buffer, buffer_len, _T("RST 10H")); break; + case 0xd8: my_stprintf_s(buffer, buffer_len, _T("RET C")); break; + case 0xd9: my_stprintf_s(buffer, buffer_len, _T("EXX")); break; + case 0xda: my_stprintf_s(buffer, buffer_len, _T("JP C, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xdb: my_stprintf_s(buffer, buffer_len, _T("IN A, (%02x)"), debug_fetch8()); break; + case 0xdc: my_stprintf_s(buffer, buffer_len, _T("CALL C, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xdd: dasm_dd(pc, buffer, buffer_len, first_symbol); break; + case 0xde: my_stprintf_s(buffer, buffer_len, _T("SBC A, %02x"), debug_fetch8()); break; + case 0xdf: my_stprintf_s(buffer, buffer_len, _T("RST 18H")); break; + case 0xe0: my_stprintf_s(buffer, buffer_len, _T("RET PO")); break; + case 0xe1: my_stprintf_s(buffer, buffer_len, _T("POP HL")); break; + case 0xe2: my_stprintf_s(buffer, buffer_len, _T("JP PO, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xe3: my_stprintf_s(buffer, buffer_len, _T("EX HL, (SP)")); break; + case 0xe4: my_stprintf_s(buffer, buffer_len, _T("CALL PO, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xe5: my_stprintf_s(buffer, buffer_len, _T("PUSH HL")); break; + case 0xe6: my_stprintf_s(buffer, buffer_len, _T("AND %02x"), debug_fetch8()); break; + case 0xe7: my_stprintf_s(buffer, buffer_len, _T("RST 20H")); break; + case 0xe8: my_stprintf_s(buffer, buffer_len, _T("RET PE")); break; + case 0xe9: my_stprintf_s(buffer, buffer_len, _T("JP (HL)")); break; + case 0xea: my_stprintf_s(buffer, buffer_len, _T("JP PE, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xeb: my_stprintf_s(buffer, buffer_len, _T("EX DE, HL")); break; + case 0xec: my_stprintf_s(buffer, buffer_len, _T("CALL PE, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xed: dasm_ed(pc, buffer, buffer_len, first_symbol); break; + case 0xee: my_stprintf_s(buffer, buffer_len, _T("XOR %02x"), debug_fetch8()); break; + case 0xef: my_stprintf_s(buffer, buffer_len, _T("RST 28H")); break; + case 0xf0: my_stprintf_s(buffer, buffer_len, _T("RET P")); break; + case 0xf1: my_stprintf_s(buffer, buffer_len, _T("POP AF")); break; + case 0xf2: my_stprintf_s(buffer, buffer_len, _T("JP P, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xf3: my_stprintf_s(buffer, buffer_len, _T("DI")); break; + case 0xf4: my_stprintf_s(buffer, buffer_len, _T("CALL P, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xf5: my_stprintf_s(buffer, buffer_len, _T("PUSH AF")); break; + case 0xf6: my_stprintf_s(buffer, buffer_len, _T("OR %02x"), debug_fetch8()); break; + case 0xf7: my_stprintf_s(buffer, buffer_len, _T("RST 30H")); break; + case 0xf8: my_stprintf_s(buffer, buffer_len, _T("RET M")); break; + case 0xf9: my_stprintf_s(buffer, buffer_len, _T("LD SP, HL")); break; + case 0xfa: my_stprintf_s(buffer, buffer_len, _T("JP M, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xfb: my_stprintf_s(buffer, buffer_len, _T("EI")); break; + case 0xfc: my_stprintf_s(buffer, buffer_len, _T("CALL M, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0xfd: dasm_fd(pc, buffer, buffer_len, first_symbol); break; + case 0xfe: my_stprintf_s(buffer, buffer_len, _T("CP %02x"), debug_fetch8()); break; + case 0xff: my_stprintf_s(buffer, buffer_len, _T("RST 38H")); break; +#if defined(_MSC_VER) && (_MSC_VER >= 1200) + default: __assume(0); +#endif + } + return z80_dasm_ptr; +} + +static void dasm_cb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) +{ + uint8_t code = dasm_fetchop(); + + switch(code) { + case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B")); break; + case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C")); break; + case 0x02: my_stprintf_s(buffer, buffer_len, _T("RLC D")); break; + case 0x03: my_stprintf_s(buffer, buffer_len, _T("RLC E")); break; + case 0x04: my_stprintf_s(buffer, buffer_len, _T("RLC H")); break; + case 0x05: my_stprintf_s(buffer, buffer_len, _T("RLC L")); break; + case 0x06: my_stprintf_s(buffer, buffer_len, _T("RLC (HL)")); break; + case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLC A")); break; + case 0x08: my_stprintf_s(buffer, buffer_len, _T("RRC B")); break; + case 0x09: my_stprintf_s(buffer, buffer_len, _T("RRC C")); break; + case 0x0a: my_stprintf_s(buffer, buffer_len, _T("RRC D")); break; + case 0x0b: my_stprintf_s(buffer, buffer_len, _T("RRC E")); break; + case 0x0c: my_stprintf_s(buffer, buffer_len, _T("RRC H")); break; + case 0x0d: my_stprintf_s(buffer, buffer_len, _T("RRC L")); break; + case 0x0e: my_stprintf_s(buffer, buffer_len, _T("RRC (HL)")); break; + case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRC A")); break; + case 0x10: my_stprintf_s(buffer, buffer_len, _T("RL B")); break; + case 0x11: my_stprintf_s(buffer, buffer_len, _T("RL C")); break; + case 0x12: my_stprintf_s(buffer, buffer_len, _T("RL D")); break; + case 0x13: my_stprintf_s(buffer, buffer_len, _T("RL E")); break; + case 0x14: my_stprintf_s(buffer, buffer_len, _T("RL H")); break; + case 0x15: my_stprintf_s(buffer, buffer_len, _T("RL L")); break; + case 0x16: my_stprintf_s(buffer, buffer_len, _T("RL (HL)")); break; + case 0x17: my_stprintf_s(buffer, buffer_len, _T("RL A")); break; + case 0x18: my_stprintf_s(buffer, buffer_len, _T("RR B")); break; + case 0x19: my_stprintf_s(buffer, buffer_len, _T("RR C")); break; + case 0x1a: my_stprintf_s(buffer, buffer_len, _T("RR D")); break; + case 0x1b: my_stprintf_s(buffer, buffer_len, _T("RR E")); break; + case 0x1c: my_stprintf_s(buffer, buffer_len, _T("RR H")); break; + case 0x1d: my_stprintf_s(buffer, buffer_len, _T("RR L")); break; + case 0x1e: my_stprintf_s(buffer, buffer_len, _T("RR (HL)")); break; + case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RR A")); break; + case 0x20: my_stprintf_s(buffer, buffer_len, _T("SLA B")); break; + case 0x21: my_stprintf_s(buffer, buffer_len, _T("SLA C")); break; + case 0x22: my_stprintf_s(buffer, buffer_len, _T("SLA D")); break; + case 0x23: my_stprintf_s(buffer, buffer_len, _T("SLA E")); break; + case 0x24: my_stprintf_s(buffer, buffer_len, _T("SLA H")); break; + case 0x25: my_stprintf_s(buffer, buffer_len, _T("SLA L")); break; + case 0x26: my_stprintf_s(buffer, buffer_len, _T("SLA (HL)")); break; + case 0x27: my_stprintf_s(buffer, buffer_len, _T("SLA A")); break; + case 0x28: my_stprintf_s(buffer, buffer_len, _T("SRA B")); break; + case 0x29: my_stprintf_s(buffer, buffer_len, _T("SRA C")); break; + case 0x2a: my_stprintf_s(buffer, buffer_len, _T("SRA D")); break; + case 0x2b: my_stprintf_s(buffer, buffer_len, _T("SRA E")); break; + case 0x2c: my_stprintf_s(buffer, buffer_len, _T("SRA H")); break; + case 0x2d: my_stprintf_s(buffer, buffer_len, _T("SRA L")); break; + case 0x2e: my_stprintf_s(buffer, buffer_len, _T("SRA (HL)")); break; + case 0x2f: my_stprintf_s(buffer, buffer_len, _T("SRA A")); break; + case 0x30: my_stprintf_s(buffer, buffer_len, _T("SLL B")); break; + case 0x31: my_stprintf_s(buffer, buffer_len, _T("SLL C")); break; + case 0x32: my_stprintf_s(buffer, buffer_len, _T("SLL D")); break; + case 0x33: my_stprintf_s(buffer, buffer_len, _T("SLL E")); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("SLL H")); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("SLL L")); break; + case 0x36: my_stprintf_s(buffer, buffer_len, _T("SLL (HL)")); break; + case 0x37: my_stprintf_s(buffer, buffer_len, _T("SLL A")); break; + case 0x38: my_stprintf_s(buffer, buffer_len, _T("SRL B")); break; + case 0x39: my_stprintf_s(buffer, buffer_len, _T("SRL C")); break; + case 0x3a: my_stprintf_s(buffer, buffer_len, _T("SRL D")); break; + case 0x3b: my_stprintf_s(buffer, buffer_len, _T("SRL E")); break; + case 0x3c: my_stprintf_s(buffer, buffer_len, _T("SRL H")); break; + case 0x3d: my_stprintf_s(buffer, buffer_len, _T("SRL L")); break; + case 0x3e: my_stprintf_s(buffer, buffer_len, _T("SRL (HL)")); break; + case 0x3f: my_stprintf_s(buffer, buffer_len, _T("SRL A")); break; + case 0x40: my_stprintf_s(buffer, buffer_len, _T("BIT 0, B")); break; + case 0x41: my_stprintf_s(buffer, buffer_len, _T("BIT 0, C")); break; + case 0x42: my_stprintf_s(buffer, buffer_len, _T("BIT 0, D")); break; + case 0x43: my_stprintf_s(buffer, buffer_len, _T("BIT 0, E")); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("BIT 0, H")); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("BIT 0, L")); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("BIT 0, (HL)")); break; + case 0x47: my_stprintf_s(buffer, buffer_len, _T("BIT 0, A")); break; + case 0x48: my_stprintf_s(buffer, buffer_len, _T("BIT 1, B")); break; + case 0x49: my_stprintf_s(buffer, buffer_len, _T("BIT 1, C")); break; + case 0x4a: my_stprintf_s(buffer, buffer_len, _T("BIT 1, D")); break; + case 0x4b: my_stprintf_s(buffer, buffer_len, _T("BIT 1, E")); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("BIT 1, H")); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("BIT 1, L")); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("BIT 1, (HL)")); break; + case 0x4f: my_stprintf_s(buffer, buffer_len, _T("BIT 1, A")); break; + case 0x50: my_stprintf_s(buffer, buffer_len, _T("BIT 2, B")); break; + case 0x51: my_stprintf_s(buffer, buffer_len, _T("BIT 2, C")); break; + case 0x52: my_stprintf_s(buffer, buffer_len, _T("BIT 2, D")); break; + case 0x53: my_stprintf_s(buffer, buffer_len, _T("BIT 2, E")); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("BIT 2, H")); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("BIT 2, L")); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("BIT 2, (HL)")); break; + case 0x57: my_stprintf_s(buffer, buffer_len, _T("BIT 2, A")); break; + case 0x58: my_stprintf_s(buffer, buffer_len, _T("BIT 3, B")); break; + case 0x59: my_stprintf_s(buffer, buffer_len, _T("BIT 3, C")); break; + case 0x5a: my_stprintf_s(buffer, buffer_len, _T("BIT 3, D")); break; + case 0x5b: my_stprintf_s(buffer, buffer_len, _T("BIT 3, E")); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("BIT 3, H")); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("BIT 3, L")); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("BIT 3, (HL)")); break; + case 0x5f: my_stprintf_s(buffer, buffer_len, _T("BIT 3, A")); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("BIT 4, B")); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("BIT 4, C")); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("BIT 4, D")); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("BIT 4, E")); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("BIT 4, H")); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("BIT 4, L")); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("BIT 4, (HL)")); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("BIT 4, A")); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("BIT 5, B")); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("BIT 5, C")); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("BIT 5, D")); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("BIT 5, E")); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("BIT 5, H")); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("BIT 5, L")); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("BIT 5, (HL)")); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("BIT 5, A")); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("BIT 6, B")); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("BIT 6, C")); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("BIT 6, D")); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("BIT 6, E")); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("BIT 6, H")); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("BIT 6, L")); break; + case 0x76: my_stprintf_s(buffer, buffer_len, _T("BIT 6, (HL)")); break; + case 0x77: my_stprintf_s(buffer, buffer_len, _T("BIT 6, A")); break; + case 0x78: my_stprintf_s(buffer, buffer_len, _T("BIT 7, B")); break; + case 0x79: my_stprintf_s(buffer, buffer_len, _T("BIT 7, C")); break; + case 0x7a: my_stprintf_s(buffer, buffer_len, _T("BIT 7, D")); break; + case 0x7b: my_stprintf_s(buffer, buffer_len, _T("BIT 7, E")); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("BIT 7, H")); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("BIT 7, L")); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("BIT 7, (HL)")); break; + case 0x7f: my_stprintf_s(buffer, buffer_len, _T("BIT 7, A")); break; + case 0x80: my_stprintf_s(buffer, buffer_len, _T("RES 0, B")); break; + case 0x81: my_stprintf_s(buffer, buffer_len, _T("RES 0, C")); break; + case 0x82: my_stprintf_s(buffer, buffer_len, _T("RES 0, D")); break; + case 0x83: my_stprintf_s(buffer, buffer_len, _T("RES 0, E")); break; + case 0x84: my_stprintf_s(buffer, buffer_len, _T("RES 0, H")); break; + case 0x85: my_stprintf_s(buffer, buffer_len, _T("RES 0, L")); break; + case 0x86: my_stprintf_s(buffer, buffer_len, _T("RES 0, (HL)")); break; + case 0x87: my_stprintf_s(buffer, buffer_len, _T("RES 0, A")); break; + case 0x88: my_stprintf_s(buffer, buffer_len, _T("RES 1, B")); break; + case 0x89: my_stprintf_s(buffer, buffer_len, _T("RES 1, C")); break; + case 0x8a: my_stprintf_s(buffer, buffer_len, _T("RES 1, D")); break; + case 0x8b: my_stprintf_s(buffer, buffer_len, _T("RES 1, E")); break; + case 0x8c: my_stprintf_s(buffer, buffer_len, _T("RES 1, H")); break; + case 0x8d: my_stprintf_s(buffer, buffer_len, _T("RES 1, L")); break; + case 0x8e: my_stprintf_s(buffer, buffer_len, _T("RES 1, (HL)")); break; + case 0x8f: my_stprintf_s(buffer, buffer_len, _T("RES 1, A")); break; + case 0x90: my_stprintf_s(buffer, buffer_len, _T("RES 2, B")); break; + case 0x91: my_stprintf_s(buffer, buffer_len, _T("RES 2, C")); break; + case 0x92: my_stprintf_s(buffer, buffer_len, _T("RES 2, D")); break; + case 0x93: my_stprintf_s(buffer, buffer_len, _T("RES 2, E")); break; + case 0x94: my_stprintf_s(buffer, buffer_len, _T("RES 2, H")); break; + case 0x95: my_stprintf_s(buffer, buffer_len, _T("RES 2, L")); break; + case 0x96: my_stprintf_s(buffer, buffer_len, _T("RES 2, (HL)")); break; + case 0x97: my_stprintf_s(buffer, buffer_len, _T("RES 2, A")); break; + case 0x98: my_stprintf_s(buffer, buffer_len, _T("RES 3, B")); break; + case 0x99: my_stprintf_s(buffer, buffer_len, _T("RES 3, C")); break; + case 0x9a: my_stprintf_s(buffer, buffer_len, _T("RES 3, D")); break; + case 0x9b: my_stprintf_s(buffer, buffer_len, _T("RES 3, E")); break; + case 0x9c: my_stprintf_s(buffer, buffer_len, _T("RES 3, H")); break; + case 0x9d: my_stprintf_s(buffer, buffer_len, _T("RES 3, L")); break; + case 0x9e: my_stprintf_s(buffer, buffer_len, _T("RES 3, (HL)")); break; + case 0x9f: my_stprintf_s(buffer, buffer_len, _T("RES 3, A")); break; + case 0xa0: my_stprintf_s(buffer, buffer_len, _T("RES 4, B")); break; + case 0xa1: my_stprintf_s(buffer, buffer_len, _T("RES 4, C")); break; + case 0xa2: my_stprintf_s(buffer, buffer_len, _T("RES 4, D")); break; + case 0xa3: my_stprintf_s(buffer, buffer_len, _T("RES 4, E")); break; + case 0xa4: my_stprintf_s(buffer, buffer_len, _T("RES 4, H")); break; + case 0xa5: my_stprintf_s(buffer, buffer_len, _T("RES 4, L")); break; + case 0xa6: my_stprintf_s(buffer, buffer_len, _T("RES 4, (HL)")); break; + case 0xa7: my_stprintf_s(buffer, buffer_len, _T("RES 4, A")); break; + case 0xa8: my_stprintf_s(buffer, buffer_len, _T("RES 5, B")); break; + case 0xa9: my_stprintf_s(buffer, buffer_len, _T("RES 5, C")); break; + case 0xaa: my_stprintf_s(buffer, buffer_len, _T("RES 5, D")); break; + case 0xab: my_stprintf_s(buffer, buffer_len, _T("RES 5, E")); break; + case 0xac: my_stprintf_s(buffer, buffer_len, _T("RES 5, H")); break; + case 0xad: my_stprintf_s(buffer, buffer_len, _T("RES 5, L")); break; + case 0xae: my_stprintf_s(buffer, buffer_len, _T("RES 5, (HL)")); break; + case 0xaf: my_stprintf_s(buffer, buffer_len, _T("RES 5, A")); break; + case 0xb0: my_stprintf_s(buffer, buffer_len, _T("RES 6, B")); break; + case 0xb1: my_stprintf_s(buffer, buffer_len, _T("RES 6, C")); break; + case 0xb2: my_stprintf_s(buffer, buffer_len, _T("RES 6, D")); break; + case 0xb3: my_stprintf_s(buffer, buffer_len, _T("RES 6, E")); break; + case 0xb4: my_stprintf_s(buffer, buffer_len, _T("RES 6, H")); break; + case 0xb5: my_stprintf_s(buffer, buffer_len, _T("RES 6, L")); break; + case 0xb6: my_stprintf_s(buffer, buffer_len, _T("RES 6, (HL)")); break; + case 0xb7: my_stprintf_s(buffer, buffer_len, _T("RES 6, A")); break; + case 0xb8: my_stprintf_s(buffer, buffer_len, _T("RES 7, B")); break; + case 0xb9: my_stprintf_s(buffer, buffer_len, _T("RES 7, C")); break; + case 0xba: my_stprintf_s(buffer, buffer_len, _T("RES 7, D")); break; + case 0xbb: my_stprintf_s(buffer, buffer_len, _T("RES 7, E")); break; + case 0xbc: my_stprintf_s(buffer, buffer_len, _T("RES 7, H")); break; + case 0xbd: my_stprintf_s(buffer, buffer_len, _T("RES 7, L")); break; + case 0xbe: my_stprintf_s(buffer, buffer_len, _T("RES 7, (HL)")); break; + case 0xbf: my_stprintf_s(buffer, buffer_len, _T("RES 7, A")); break; + case 0xc0: my_stprintf_s(buffer, buffer_len, _T("SET 0, B")); break; + case 0xc1: my_stprintf_s(buffer, buffer_len, _T("SET 0, C")); break; + case 0xc2: my_stprintf_s(buffer, buffer_len, _T("SET 0, D")); break; + case 0xc3: my_stprintf_s(buffer, buffer_len, _T("SET 0, E")); break; + case 0xc4: my_stprintf_s(buffer, buffer_len, _T("SET 0, H")); break; + case 0xc5: my_stprintf_s(buffer, buffer_len, _T("SET 0, L")); break; + case 0xc6: my_stprintf_s(buffer, buffer_len, _T("SET 0, (HL)")); break; + case 0xc7: my_stprintf_s(buffer, buffer_len, _T("SET 0, A")); break; + case 0xc8: my_stprintf_s(buffer, buffer_len, _T("SET 1, B")); break; + case 0xc9: my_stprintf_s(buffer, buffer_len, _T("SET 1, C")); break; + case 0xca: my_stprintf_s(buffer, buffer_len, _T("SET 1, D")); break; + case 0xcb: my_stprintf_s(buffer, buffer_len, _T("SET 1, E")); break; + case 0xcc: my_stprintf_s(buffer, buffer_len, _T("SET 1, H")); break; + case 0xcd: my_stprintf_s(buffer, buffer_len, _T("SET 1, L")); break; + case 0xce: my_stprintf_s(buffer, buffer_len, _T("SET 1, (HL)")); break; + case 0xcf: my_stprintf_s(buffer, buffer_len, _T("SET 1, A")); break; + case 0xd0: my_stprintf_s(buffer, buffer_len, _T("SET 2, B")); break; + case 0xd1: my_stprintf_s(buffer, buffer_len, _T("SET 2, C")); break; + case 0xd2: my_stprintf_s(buffer, buffer_len, _T("SET 2, D")); break; + case 0xd3: my_stprintf_s(buffer, buffer_len, _T("SET 2, E")); break; + case 0xd4: my_stprintf_s(buffer, buffer_len, _T("SET 2, H")); break; + case 0xd5: my_stprintf_s(buffer, buffer_len, _T("SET 2, L")); break; + case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SET 2, (HL)")); break; + case 0xd7: my_stprintf_s(buffer, buffer_len, _T("SET 2, A")); break; + case 0xd8: my_stprintf_s(buffer, buffer_len, _T("SET 3, B")); break; + case 0xd9: my_stprintf_s(buffer, buffer_len, _T("SET 3, C")); break; + case 0xda: my_stprintf_s(buffer, buffer_len, _T("SET 3, D")); break; + case 0xdb: my_stprintf_s(buffer, buffer_len, _T("SET 3, E")); break; + case 0xdc: my_stprintf_s(buffer, buffer_len, _T("SET 3, H")); break; + case 0xdd: my_stprintf_s(buffer, buffer_len, _T("SET 3, L")); break; + case 0xde: my_stprintf_s(buffer, buffer_len, _T("SET 3, (HL)")); break; + case 0xdf: my_stprintf_s(buffer, buffer_len, _T("SET 3, A")); break; + case 0xe0: my_stprintf_s(buffer, buffer_len, _T("SET 4, B")); break; + case 0xe1: my_stprintf_s(buffer, buffer_len, _T("SET 4, C")); break; + case 0xe2: my_stprintf_s(buffer, buffer_len, _T("SET 4, D")); break; + case 0xe3: my_stprintf_s(buffer, buffer_len, _T("SET 4, E")); break; + case 0xe4: my_stprintf_s(buffer, buffer_len, _T("SET 4, H")); break; + case 0xe5: my_stprintf_s(buffer, buffer_len, _T("SET 4, L")); break; + case 0xe6: my_stprintf_s(buffer, buffer_len, _T("SET 4, (HL)")); break; + case 0xe7: my_stprintf_s(buffer, buffer_len, _T("SET 4, A")); break; + case 0xe8: my_stprintf_s(buffer, buffer_len, _T("SET 5, B")); break; + case 0xe9: my_stprintf_s(buffer, buffer_len, _T("SET 5, C")); break; + case 0xea: my_stprintf_s(buffer, buffer_len, _T("SET 5, D")); break; + case 0xeb: my_stprintf_s(buffer, buffer_len, _T("SET 5, E")); break; + case 0xec: my_stprintf_s(buffer, buffer_len, _T("SET 5, H")); break; + case 0xed: my_stprintf_s(buffer, buffer_len, _T("SET 5, L")); break; + case 0xee: my_stprintf_s(buffer, buffer_len, _T("SET 5, (HL)")); break; + case 0xef: my_stprintf_s(buffer, buffer_len, _T("SET 5, A")); break; + case 0xf0: my_stprintf_s(buffer, buffer_len, _T("SET 6, B")); break; + case 0xf1: my_stprintf_s(buffer, buffer_len, _T("SET 6, C")); break; + case 0xf2: my_stprintf_s(buffer, buffer_len, _T("SET 6, D")); break; + case 0xf3: my_stprintf_s(buffer, buffer_len, _T("SET 6, E")); break; + case 0xf4: my_stprintf_s(buffer, buffer_len, _T("SET 6, H")); break; + case 0xf5: my_stprintf_s(buffer, buffer_len, _T("SET 6, L")); break; + case 0xf6: my_stprintf_s(buffer, buffer_len, _T("SET 6, (HL)")); break; + case 0xf7: my_stprintf_s(buffer, buffer_len, _T("SET 6, A")); break; + case 0xf8: my_stprintf_s(buffer, buffer_len, _T("SET 7, B")); break; + case 0xf9: my_stprintf_s(buffer, buffer_len, _T("SET 7, C")); break; + case 0xfa: my_stprintf_s(buffer, buffer_len, _T("SET 7, D")); break; + case 0xfb: my_stprintf_s(buffer, buffer_len, _T("SET 7, E")); break; + case 0xfc: my_stprintf_s(buffer, buffer_len, _T("SET 7, H")); break; + case 0xfd: my_stprintf_s(buffer, buffer_len, _T("SET 7, L")); break; + case 0xfe: my_stprintf_s(buffer, buffer_len, _T("SET 7, (HL)")); break; + case 0xff: my_stprintf_s(buffer, buffer_len, _T("SET 7, A")); break; +#if defined(_MSC_VER) && (_MSC_VER >= 1200) + default: __assume(0); +#endif + } +} + +static void dasm_dd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) +{ + uint8_t code = dasm_fetchop(); + int8_t ofs; + + switch(code) { + case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD IX, BC")); break; + case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD IX, DE")); break; + case 0x21: my_stprintf_s(buffer, buffer_len, _T("LD IX, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x22: my_stprintf_s(buffer, buffer_len, _T("LD (%s), IX"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x23: my_stprintf_s(buffer, buffer_len, _T("INC IX")); break; + case 0x24: my_stprintf_s(buffer, buffer_len, _T("INC HX")); break; + case 0x25: my_stprintf_s(buffer, buffer_len, _T("DEC HX")); break; + case 0x26: my_stprintf_s(buffer, buffer_len, _T("LD HX, %02x"), debug_fetch8()); break; + case 0x29: my_stprintf_s(buffer, buffer_len, _T("ADD IX, IX")); break; + case 0x2a: my_stprintf_s(buffer, buffer_len, _T("LD IX, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x2b: my_stprintf_s(buffer, buffer_len, _T("DEC IX")); break; + case 0x2c: my_stprintf_s(buffer, buffer_len, _T("INC LX")); break; + case 0x2d: my_stprintf_s(buffer, buffer_len, _T("DEC LX")); break; + case 0x2e: my_stprintf_s(buffer, buffer_len, _T("LD LX, %02x"), debug_fetch8()); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("INC (IX+(%d))"), debug_fetch8_rel()); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("DEC (IX+(%d))"), debug_fetch8_rel()); break; + case 0x36: ofs = debug_fetch8_rel(); my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), %02x"), ofs, debug_fetch8()); break; + case 0x39: my_stprintf_s(buffer, buffer_len, _T("ADD IX, SP")); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("LD B, HX")); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("LD B, LX")); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("LD B, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("LD C, HX")); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("LD C, LX")); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("LD C, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("LD D, HX")); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("LD D, LX")); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("LD D, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("LD E, HX")); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("LD E, LX")); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("LD E, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("LD HX, B")); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("LD HX, C")); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("LD HX, D")); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD HX, E")); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("LD HX, HX")); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("LD HX, LX")); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("LD H, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("LD HX, A")); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("LD LX, B")); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("LD LX, C")); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("LD LX, D")); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD LX, E")); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("LD LX, HX")); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("LD LX, LX")); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("LD L, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("LD LX, A")); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), B"), debug_fetch8_rel()); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), C"), debug_fetch8_rel()); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), D"), debug_fetch8_rel()); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), E"), debug_fetch8_rel()); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), H"), debug_fetch8_rel()); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), L"), debug_fetch8_rel()); break; + case 0x77: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), A"), debug_fetch8_rel()); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("LD A, HX")); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("LD A, LX")); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("LD A, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x84: my_stprintf_s(buffer, buffer_len, _T("ADD A, HX")); break; + case 0x85: my_stprintf_s(buffer, buffer_len, _T("ADD A, LX")); break; + case 0x86: my_stprintf_s(buffer, buffer_len, _T("ADD A, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x8c: my_stprintf_s(buffer, buffer_len, _T("ADC A, HX")); break; + case 0x8d: my_stprintf_s(buffer, buffer_len, _T("ADC A, LX")); break; + case 0x8e: my_stprintf_s(buffer, buffer_len, _T("ADC A, (IX+(%d))"), debug_fetch8_rel()); break; + case 0x94: my_stprintf_s(buffer, buffer_len, _T("SUB HX")); break; + case 0x95: my_stprintf_s(buffer, buffer_len, _T("SUB LX")); break; + case 0x96: my_stprintf_s(buffer, buffer_len, _T("SUB (IX+(%d))"), debug_fetch8_rel()); break; + case 0x9c: my_stprintf_s(buffer, buffer_len, _T("SBC A, HX")); break; + case 0x9d: my_stprintf_s(buffer, buffer_len, _T("SBC A, LX")); break; + case 0x9e: my_stprintf_s(buffer, buffer_len, _T("SBC A, (IX+(%d))"), debug_fetch8_rel()); break; + case 0xa4: my_stprintf_s(buffer, buffer_len, _T("AND HX")); break; + case 0xa5: my_stprintf_s(buffer, buffer_len, _T("AND LX")); break; + case 0xa6: my_stprintf_s(buffer, buffer_len, _T("AND (IX+(%d))"), debug_fetch8_rel()); break; + case 0xac: my_stprintf_s(buffer, buffer_len, _T("XOR HX")); break; + case 0xad: my_stprintf_s(buffer, buffer_len, _T("XOR LX")); break; + case 0xae: my_stprintf_s(buffer, buffer_len, _T("XOR (IX+(%d))"), debug_fetch8_rel()); break; + case 0xb4: my_stprintf_s(buffer, buffer_len, _T("OR HX")); break; + case 0xb5: my_stprintf_s(buffer, buffer_len, _T("OR LX")); break; + case 0xb6: my_stprintf_s(buffer, buffer_len, _T("OR (IX+(%d))"), debug_fetch8_rel()); break; + case 0xbc: my_stprintf_s(buffer, buffer_len, _T("CP HX")); break; + case 0xbd: my_stprintf_s(buffer, buffer_len, _T("CP LX")); break; + case 0xbe: my_stprintf_s(buffer, buffer_len, _T("CP (IX+(%d))"), debug_fetch8_rel()); break; + case 0xcb: dasm_ddcb(pc, buffer, buffer_len, first_symbol); break; + case 0xe1: my_stprintf_s(buffer, buffer_len, _T("POP IX")); break; + case 0xe3: my_stprintf_s(buffer, buffer_len, _T("EX (SP), IX")); break; + case 0xe5: my_stprintf_s(buffer, buffer_len, _T("PUSH IX")); break; + case 0xe9: my_stprintf_s(buffer, buffer_len, _T("JP (IX)")); break; + case 0xf9: my_stprintf_s(buffer, buffer_len, _T("LD SP, IX")); break; + default: my_stprintf_s(buffer, buffer_len, _T("DB dd")); z80_dasm_ptr--; break; + } +} + +void dasm_ed(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) +{ + uint8_t code = dasm_fetchop(); + + switch(code) { + case 0x40: my_stprintf_s(buffer, buffer_len, _T("IN B, (C)")); break; + case 0x41: my_stprintf_s(buffer, buffer_len, _T("OUT (C), B")); break; + case 0x42: my_stprintf_s(buffer, buffer_len, _T("SBC HL, BC")); break; + case 0x43: my_stprintf_s(buffer, buffer_len, _T("LD (%s), BC"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; + case 0x47: my_stprintf_s(buffer, buffer_len, _T("LD I, A")); break; + case 0x48: my_stprintf_s(buffer, buffer_len, _T("IN C, (C)")); break; + case 0x49: my_stprintf_s(buffer, buffer_len, _T("OUT (C), C")); break; + case 0x4a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, BC")); break; + case 0x4b: my_stprintf_s(buffer, buffer_len, _T("LD BC, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; + case 0x4f: my_stprintf_s(buffer, buffer_len, _T("LD R, A")); break; + case 0x50: my_stprintf_s(buffer, buffer_len, _T("IN D, (C)")); break; + case 0x51: my_stprintf_s(buffer, buffer_len, _T("OUT (C), D")); break; + case 0x52: my_stprintf_s(buffer, buffer_len, _T("SBC HL, DE")); break; + case 0x53: my_stprintf_s(buffer, buffer_len, _T("LD (%s), DE"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("IM 1")); break; + case 0x57: my_stprintf_s(buffer, buffer_len, _T("LD A, I")); break; + case 0x58: my_stprintf_s(buffer, buffer_len, _T("IN E, (C)")); break; + case 0x59: my_stprintf_s(buffer, buffer_len, _T("OUT (C), E")); break; + case 0x5a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, DE")); break; + case 0x5b: my_stprintf_s(buffer, buffer_len, _T("LD DE, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("IM 2")); break; + case 0x5f: my_stprintf_s(buffer, buffer_len, _T("LD A, R")); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("IN H, (C)")); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("OUT (C), H")); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("SBC HL, HL")); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD (%s), HL"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("RRD (HL)")); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("IN L, (C)")); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("OUT (C), L")); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, HL")); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD HL, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("RLD (HL)")); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("IN F, (C)")); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("OUT (C), 0")); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("SBC HL, SP")); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (%s), SP"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; + case 0x76: my_stprintf_s(buffer, buffer_len, _T("IM 1")); break; + case 0x78: my_stprintf_s(buffer, buffer_len, _T("IN A, (C)")); break; + case 0x79: my_stprintf_s(buffer, buffer_len, _T("OUT (C), A")); break; + case 0x7a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, SP")); break; + case 0x7b: my_stprintf_s(buffer, buffer_len, _T("LD SP, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("IM 2")); break; + case 0xa0: my_stprintf_s(buffer, buffer_len, _T("LDI")); break; + case 0xa1: my_stprintf_s(buffer, buffer_len, _T("CPI")); break; + case 0xa2: my_stprintf_s(buffer, buffer_len, _T("INI")); break; + case 0xa3: my_stprintf_s(buffer, buffer_len, _T("OUTI")); break; + case 0xa8: my_stprintf_s(buffer, buffer_len, _T("LDD")); break; + case 0xa9: my_stprintf_s(buffer, buffer_len, _T("CPD")); break; + case 0xaa: my_stprintf_s(buffer, buffer_len, _T("IND")); break; + case 0xab: my_stprintf_s(buffer, buffer_len, _T("OUTD")); break; + case 0xb0: my_stprintf_s(buffer, buffer_len, _T("LDIR")); break; + case 0xb1: my_stprintf_s(buffer, buffer_len, _T("CPIR")); break; + case 0xb2: my_stprintf_s(buffer, buffer_len, _T("INIR")); break; + case 0xb3: my_stprintf_s(buffer, buffer_len, _T("OTIR")); break; + case 0xb8: my_stprintf_s(buffer, buffer_len, _T("LDDR")); break; + case 0xb9: my_stprintf_s(buffer, buffer_len, _T("CPDR")); break; + case 0xba: my_stprintf_s(buffer, buffer_len, _T("INDR")); break; + case 0xbb: my_stprintf_s(buffer, buffer_len, _T("OTDR")); break; + default: my_stprintf_s(buffer, buffer_len, _T("DB ed")); z80_dasm_ptr--; break; + } +} + +void dasm_fd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) +{ + uint8_t code = dasm_fetchop(); + int8_t ofs; + + switch(code) { + case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD IY, BC")); break; + case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD IY, DE")); break; + case 0x21: my_stprintf_s(buffer, buffer_len, _T("LD IY, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x22: my_stprintf_s(buffer, buffer_len, _T("LD (%s), IY"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x23: my_stprintf_s(buffer, buffer_len, _T("INC IY")); break; + case 0x24: my_stprintf_s(buffer, buffer_len, _T("INC HY")); break; + case 0x25: my_stprintf_s(buffer, buffer_len, _T("DEC HY")); break; + case 0x26: my_stprintf_s(buffer, buffer_len, _T("LD HY, %02x"), debug_fetch8()); break; + case 0x29: my_stprintf_s(buffer, buffer_len, _T("ADD IY, IY")); break; + case 0x2a: my_stprintf_s(buffer, buffer_len, _T("LD IY, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; + case 0x2b: my_stprintf_s(buffer, buffer_len, _T("DEC IY")); break; + case 0x2c: my_stprintf_s(buffer, buffer_len, _T("INC LY")); break; + case 0x2d: my_stprintf_s(buffer, buffer_len, _T("DEC LY")); break; + case 0x2e: my_stprintf_s(buffer, buffer_len, _T("LD LY, %02x"), debug_fetch8()); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("INC (IY+(%d))"), debug_fetch8_rel()); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("DEC (IY+(%d))"), debug_fetch8_rel()); break; + case 0x36: ofs = debug_fetch8_rel(); my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), %02x"), ofs, debug_fetch8()); break; + case 0x39: my_stprintf_s(buffer, buffer_len, _T("ADD IY, SP")); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("LD B, HY")); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("LD B, LY")); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("LD B, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("LD C, HY")); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("LD C, LY")); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("LD C, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("LD D, HY")); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("LD D, LY")); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("LD D, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("LD E, HY")); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("LD E, LY")); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("LD E, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("LD HY, B")); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("LD HY, C")); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("LD HY, D")); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD HY, E")); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("LD HY, HY")); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("LD HY, LY")); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("LD H, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("LD HY, A")); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("LD LY, B")); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("LD LY, C")); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("LD LY, D")); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD LY, E")); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("LD LY, HY")); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("LD LY, LY")); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("LD L, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("LD LY, A")); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), B"), debug_fetch8_rel()); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), C"), debug_fetch8_rel()); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), D"), debug_fetch8_rel()); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), E"), debug_fetch8_rel()); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), H"), debug_fetch8_rel()); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), L"), debug_fetch8_rel()); break; + case 0x77: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), A"), debug_fetch8_rel()); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("LD A, HY")); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("LD A, LY")); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("LD A, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x84: my_stprintf_s(buffer, buffer_len, _T("ADD A, HY")); break; + case 0x85: my_stprintf_s(buffer, buffer_len, _T("ADD A, LY")); break; + case 0x86: my_stprintf_s(buffer, buffer_len, _T("ADD A, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x8c: my_stprintf_s(buffer, buffer_len, _T("ADC A, HY")); break; + case 0x8d: my_stprintf_s(buffer, buffer_len, _T("ADC A, LY")); break; + case 0x8e: my_stprintf_s(buffer, buffer_len, _T("ADC A, (IY+(%d))"), debug_fetch8_rel()); break; + case 0x94: my_stprintf_s(buffer, buffer_len, _T("SUB HY")); break; + case 0x95: my_stprintf_s(buffer, buffer_len, _T("SUB LY")); break; + case 0x96: my_stprintf_s(buffer, buffer_len, _T("SUB (IY+(%d))"), debug_fetch8_rel()); break; + case 0x9c: my_stprintf_s(buffer, buffer_len, _T("SBC A, HY")); break; + case 0x9d: my_stprintf_s(buffer, buffer_len, _T("SBC A, LY")); break; + case 0x9e: my_stprintf_s(buffer, buffer_len, _T("SBC A, (IY+(%d))"), debug_fetch8_rel()); break; + case 0xa4: my_stprintf_s(buffer, buffer_len, _T("AND HY")); break; + case 0xa5: my_stprintf_s(buffer, buffer_len, _T("AND LY")); break; + case 0xa6: my_stprintf_s(buffer, buffer_len, _T("AND (IY+(%d))"), debug_fetch8_rel()); break; + case 0xac: my_stprintf_s(buffer, buffer_len, _T("XOR HY")); break; + case 0xad: my_stprintf_s(buffer, buffer_len, _T("XOR LY")); break; + case 0xae: my_stprintf_s(buffer, buffer_len, _T("XOR (IY+(%d))"), debug_fetch8_rel()); break; + case 0xb4: my_stprintf_s(buffer, buffer_len, _T("OR HY")); break; + case 0xb5: my_stprintf_s(buffer, buffer_len, _T("OR LY")); break; + case 0xb6: my_stprintf_s(buffer, buffer_len, _T("OR (IY+(%d))"), debug_fetch8_rel()); break; + case 0xbc: my_stprintf_s(buffer, buffer_len, _T("CP HY")); break; + case 0xbd: my_stprintf_s(buffer, buffer_len, _T("CP LY")); break; + case 0xbe: my_stprintf_s(buffer, buffer_len, _T("CP (IY+(%d))"), debug_fetch8_rel()); break; + case 0xcb: dasm_fdcb(pc, buffer, buffer_len, first_symbol); break; + case 0xe1: my_stprintf_s(buffer, buffer_len, _T("POP IY")); break; + case 0xe3: my_stprintf_s(buffer, buffer_len, _T("EX (SP), IY")); break; + case 0xe5: my_stprintf_s(buffer, buffer_len, _T("PUSH IY")); break; + case 0xe9: my_stprintf_s(buffer, buffer_len, _T("JP (IY)")); break; + case 0xf9: my_stprintf_s(buffer, buffer_len, _T("LD SP, IY")); break; + default: my_stprintf_s(buffer, buffer_len, _T("DB fd")); z80_dasm_ptr--; break; + } +} + +static void dasm_ddcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) +{ + int8_t ofs = debug_fetch8_rel(); + uint8_t code = debug_fetch8(); + + switch(code) { + case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B=(IX+(%d))"), ofs); break; + case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C=(IX+(%d))"), ofs); break; + case 0x02: my_stprintf_s(buffer, buffer_len, _T("RLC D=(IX+(%d))"), ofs); break; + case 0x03: my_stprintf_s(buffer, buffer_len, _T("RLC E=(IX+(%d))"), ofs); break; + case 0x04: my_stprintf_s(buffer, buffer_len, _T("RLC H=(IX+(%d))"), ofs); break; + case 0x05: my_stprintf_s(buffer, buffer_len, _T("RLC L=(IX+(%d))"), ofs); break; + case 0x06: my_stprintf_s(buffer, buffer_len, _T("RLC (IX+(%d))"), ofs); break; + case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLC A=(IX+(%d))"), ofs); break; + case 0x08: my_stprintf_s(buffer, buffer_len, _T("RRC B=(IX+(%d))"), ofs); break; + case 0x09: my_stprintf_s(buffer, buffer_len, _T("RRC C=(IX+(%d))"), ofs); break; + case 0x0a: my_stprintf_s(buffer, buffer_len, _T("RRC D=(IX+(%d))"), ofs); break; + case 0x0b: my_stprintf_s(buffer, buffer_len, _T("RRC E=(IX+(%d))"), ofs); break; + case 0x0c: my_stprintf_s(buffer, buffer_len, _T("RRC H=(IX+(%d))"), ofs); break; + case 0x0d: my_stprintf_s(buffer, buffer_len, _T("RRC L=(IX+(%d))"), ofs); break; + case 0x0e: my_stprintf_s(buffer, buffer_len, _T("RRC (IX+(%d))"), ofs); break; + case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRC A=(IX+(%d))"), ofs); break; + case 0x10: my_stprintf_s(buffer, buffer_len, _T("RL B=(IX+(%d))"), ofs); break; + case 0x11: my_stprintf_s(buffer, buffer_len, _T("RL C=(IX+(%d))"), ofs); break; + case 0x12: my_stprintf_s(buffer, buffer_len, _T("RL D=(IX+(%d))"), ofs); break; + case 0x13: my_stprintf_s(buffer, buffer_len, _T("RL E=(IX+(%d))"), ofs); break; + case 0x14: my_stprintf_s(buffer, buffer_len, _T("RL H=(IX+(%d))"), ofs); break; + case 0x15: my_stprintf_s(buffer, buffer_len, _T("RL L=(IX+(%d))"), ofs); break; + case 0x16: my_stprintf_s(buffer, buffer_len, _T("RL (IX+(%d))"), ofs); break; + case 0x17: my_stprintf_s(buffer, buffer_len, _T("RL A=(IX+(%d))"), ofs); break; + case 0x18: my_stprintf_s(buffer, buffer_len, _T("RR B=(IX+(%d))"), ofs); break; + case 0x19: my_stprintf_s(buffer, buffer_len, _T("RR C=(IX+(%d))"), ofs); break; + case 0x1a: my_stprintf_s(buffer, buffer_len, _T("RR D=(IX+(%d))"), ofs); break; + case 0x1b: my_stprintf_s(buffer, buffer_len, _T("RR E=(IX+(%d))"), ofs); break; + case 0x1c: my_stprintf_s(buffer, buffer_len, _T("RR H=(IX+(%d))"), ofs); break; + case 0x1d: my_stprintf_s(buffer, buffer_len, _T("RR L=(IX+(%d))"), ofs); break; + case 0x1e: my_stprintf_s(buffer, buffer_len, _T("RR (IX+(%d))"), ofs); break; + case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RR A=(IX+(%d))"), ofs); break; + case 0x20: my_stprintf_s(buffer, buffer_len, _T("SLA B=(IX+(%d))"), ofs); break; + case 0x21: my_stprintf_s(buffer, buffer_len, _T("SLA C=(IX+(%d))"), ofs); break; + case 0x22: my_stprintf_s(buffer, buffer_len, _T("SLA D=(IX+(%d))"), ofs); break; + case 0x23: my_stprintf_s(buffer, buffer_len, _T("SLA E=(IX+(%d))"), ofs); break; + case 0x24: my_stprintf_s(buffer, buffer_len, _T("SLA H=(IX+(%d))"), ofs); break; + case 0x25: my_stprintf_s(buffer, buffer_len, _T("SLA L=(IX+(%d))"), ofs); break; + case 0x26: my_stprintf_s(buffer, buffer_len, _T("SLA (IX+(%d))"), ofs); break; + case 0x27: my_stprintf_s(buffer, buffer_len, _T("SLA A=(IX+(%d))"), ofs); break; + case 0x28: my_stprintf_s(buffer, buffer_len, _T("SRA B=(IX+(%d))"), ofs); break; + case 0x29: my_stprintf_s(buffer, buffer_len, _T("SRA C=(IX+(%d))"), ofs); break; + case 0x2a: my_stprintf_s(buffer, buffer_len, _T("SRA D=(IX+(%d))"), ofs); break; + case 0x2b: my_stprintf_s(buffer, buffer_len, _T("SRA E=(IX+(%d))"), ofs); break; + case 0x2c: my_stprintf_s(buffer, buffer_len, _T("SRA H=(IX+(%d))"), ofs); break; + case 0x2d: my_stprintf_s(buffer, buffer_len, _T("SRA L=(IX+(%d))"), ofs); break; + case 0x2e: my_stprintf_s(buffer, buffer_len, _T("SRA (IX+(%d))"), ofs); break; + case 0x2f: my_stprintf_s(buffer, buffer_len, _T("SRA A=(IX+(%d))"), ofs); break; + case 0x30: my_stprintf_s(buffer, buffer_len, _T("SLL B=(IX+(%d))"), ofs); break; + case 0x31: my_stprintf_s(buffer, buffer_len, _T("SLL C=(IX+(%d))"), ofs); break; + case 0x32: my_stprintf_s(buffer, buffer_len, _T("SLL D=(IX+(%d))"), ofs); break; + case 0x33: my_stprintf_s(buffer, buffer_len, _T("SLL E=(IX+(%d))"), ofs); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("SLL H=(IX+(%d))"), ofs); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("SLL L=(IX+(%d))"), ofs); break; + case 0x36: my_stprintf_s(buffer, buffer_len, _T("SLL (IX+(%d))"), ofs); break; + case 0x37: my_stprintf_s(buffer, buffer_len, _T("SLL A=(IX+(%d))"), ofs); break; + case 0x38: my_stprintf_s(buffer, buffer_len, _T("SRL B=(IX+(%d))"), ofs); break; + case 0x39: my_stprintf_s(buffer, buffer_len, _T("SRL C=(IX+(%d))"), ofs); break; + case 0x3a: my_stprintf_s(buffer, buffer_len, _T("SRL D=(IX+(%d))"), ofs); break; + case 0x3b: my_stprintf_s(buffer, buffer_len, _T("SRL E=(IX+(%d))"), ofs); break; + case 0x3c: my_stprintf_s(buffer, buffer_len, _T("SRL H=(IX+(%d))"), ofs); break; + case 0x3d: my_stprintf_s(buffer, buffer_len, _T("SRL L=(IX+(%d))"), ofs); break; + case 0x3e: my_stprintf_s(buffer, buffer_len, _T("SRL (IX+(%d))"), ofs); break; + case 0x3f: my_stprintf_s(buffer, buffer_len, _T("SRL A=(IX+(%d))"), ofs); break; + case 0x40: my_stprintf_s(buffer, buffer_len, _T("BIT 0, B=(IX+(%d))"), ofs); break; + case 0x41: my_stprintf_s(buffer, buffer_len, _T("BIT 0, C=(IX+(%d))"), ofs); break; + case 0x42: my_stprintf_s(buffer, buffer_len, _T("BIT 0, D=(IX+(%d))"), ofs); break; + case 0x43: my_stprintf_s(buffer, buffer_len, _T("BIT 0, E=(IX+(%d))"), ofs); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("BIT 0, H=(IX+(%d))"), ofs); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("BIT 0, L=(IX+(%d))"), ofs); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("BIT 0, (IX+(%d))"), ofs); break; + case 0x47: my_stprintf_s(buffer, buffer_len, _T("BIT 0, A=(IX+(%d))"), ofs); break; + case 0x48: my_stprintf_s(buffer, buffer_len, _T("BIT 1, B=(IX+(%d))"), ofs); break; + case 0x49: my_stprintf_s(buffer, buffer_len, _T("BIT 1, C=(IX+(%d))"), ofs); break; + case 0x4a: my_stprintf_s(buffer, buffer_len, _T("BIT 1, D=(IX+(%d))"), ofs); break; + case 0x4b: my_stprintf_s(buffer, buffer_len, _T("BIT 1, E=(IX+(%d))"), ofs); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("BIT 1, H=(IX+(%d))"), ofs); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("BIT 1, L=(IX+(%d))"), ofs); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("BIT 1, (IX+(%d))"), ofs); break; + case 0x4f: my_stprintf_s(buffer, buffer_len, _T("BIT 1, A=(IX+(%d))"), ofs); break; + case 0x50: my_stprintf_s(buffer, buffer_len, _T("BIT 2, B=(IX+(%d))"), ofs); break; + case 0x51: my_stprintf_s(buffer, buffer_len, _T("BIT 2, C=(IX+(%d))"), ofs); break; + case 0x52: my_stprintf_s(buffer, buffer_len, _T("BIT 2, D=(IX+(%d))"), ofs); break; + case 0x53: my_stprintf_s(buffer, buffer_len, _T("BIT 2, E=(IX+(%d))"), ofs); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("BIT 2, H=(IX+(%d))"), ofs); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("BIT 2, L=(IX+(%d))"), ofs); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("BIT 2, (IX+(%d))"), ofs); break; + case 0x57: my_stprintf_s(buffer, buffer_len, _T("BIT 2, A=(IX+(%d))"), ofs); break; + case 0x58: my_stprintf_s(buffer, buffer_len, _T("BIT 3, B=(IX+(%d))"), ofs); break; + case 0x59: my_stprintf_s(buffer, buffer_len, _T("BIT 3, C=(IX+(%d))"), ofs); break; + case 0x5a: my_stprintf_s(buffer, buffer_len, _T("BIT 3, D=(IX+(%d))"), ofs); break; + case 0x5b: my_stprintf_s(buffer, buffer_len, _T("BIT 3, E=(IX+(%d))"), ofs); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("BIT 3, H=(IX+(%d))"), ofs); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("BIT 3, L=(IX+(%d))"), ofs); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("BIT 3, (IX+(%d))"), ofs); break; + case 0x5f: my_stprintf_s(buffer, buffer_len, _T("BIT 3, A=(IX+(%d))"), ofs); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("BIT 4, B=(IX+(%d))"), ofs); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("BIT 4, C=(IX+(%d))"), ofs); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("BIT 4, D=(IX+(%d))"), ofs); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("BIT 4, E=(IX+(%d))"), ofs); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("BIT 4, H=(IX+(%d))"), ofs); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("BIT 4, L=(IX+(%d))"), ofs); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("BIT 4, (IX+(%d))"), ofs); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("BIT 4, A=(IX+(%d))"), ofs); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("BIT 5, B=(IX+(%d))"), ofs); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("BIT 5, C=(IX+(%d))"), ofs); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("BIT 5, D=(IX+(%d))"), ofs); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("BIT 5, E=(IX+(%d))"), ofs); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("BIT 5, H=(IX+(%d))"), ofs); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("BIT 5, L=(IX+(%d))"), ofs); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("BIT 5, (IX+(%d))"), ofs); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("BIT 5, A=(IX+(%d))"), ofs); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("BIT 6, B=(IX+(%d))"), ofs); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("BIT 6, C=(IX+(%d))"), ofs); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("BIT 6, D=(IX+(%d))"), ofs); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("BIT 6, E=(IX+(%d))"), ofs); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("BIT 6, H=(IX+(%d))"), ofs); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("BIT 6, L=(IX+(%d))"), ofs); break; + case 0x76: my_stprintf_s(buffer, buffer_len, _T("BIT 6, (IX+(%d))"), ofs); break; + case 0x77: my_stprintf_s(buffer, buffer_len, _T("BIT 6, A=(IX+(%d))"), ofs); break; + case 0x78: my_stprintf_s(buffer, buffer_len, _T("BIT 7, B=(IX+(%d))"), ofs); break; + case 0x79: my_stprintf_s(buffer, buffer_len, _T("BIT 7, C=(IX+(%d))"), ofs); break; + case 0x7a: my_stprintf_s(buffer, buffer_len, _T("BIT 7, D=(IX+(%d))"), ofs); break; + case 0x7b: my_stprintf_s(buffer, buffer_len, _T("BIT 7, E=(IX+(%d))"), ofs); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("BIT 7, H=(IX+(%d))"), ofs); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("BIT 7, L=(IX+(%d))"), ofs); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("BIT 7, (IX+(%d))"), ofs); break; + case 0x7f: my_stprintf_s(buffer, buffer_len, _T("BIT 7, A=(IX+(%d))"), ofs); break; + case 0x80: my_stprintf_s(buffer, buffer_len, _T("RES 0, B=(IX+(%d))"), ofs); break; + case 0x81: my_stprintf_s(buffer, buffer_len, _T("RES 0, C=(IX+(%d))"), ofs); break; + case 0x82: my_stprintf_s(buffer, buffer_len, _T("RES 0, D=(IX+(%d))"), ofs); break; + case 0x83: my_stprintf_s(buffer, buffer_len, _T("RES 0, E=(IX+(%d))"), ofs); break; + case 0x84: my_stprintf_s(buffer, buffer_len, _T("RES 0, H=(IX+(%d))"), ofs); break; + case 0x85: my_stprintf_s(buffer, buffer_len, _T("RES 0, L=(IX+(%d))"), ofs); break; + case 0x86: my_stprintf_s(buffer, buffer_len, _T("RES 0, (IX+(%d))"), ofs); break; + case 0x87: my_stprintf_s(buffer, buffer_len, _T("RES 0, A=(IX+(%d))"), ofs); break; + case 0x88: my_stprintf_s(buffer, buffer_len, _T("RES 1, B=(IX+(%d))"), ofs); break; + case 0x89: my_stprintf_s(buffer, buffer_len, _T("RES 1, C=(IX+(%d))"), ofs); break; + case 0x8a: my_stprintf_s(buffer, buffer_len, _T("RES 1, D=(IX+(%d))"), ofs); break; + case 0x8b: my_stprintf_s(buffer, buffer_len, _T("RES 1, E=(IX+(%d))"), ofs); break; + case 0x8c: my_stprintf_s(buffer, buffer_len, _T("RES 1, H=(IX+(%d))"), ofs); break; + case 0x8d: my_stprintf_s(buffer, buffer_len, _T("RES 1, L=(IX+(%d))"), ofs); break; + case 0x8e: my_stprintf_s(buffer, buffer_len, _T("RES 1, (IX+(%d))"), ofs); break; + case 0x8f: my_stprintf_s(buffer, buffer_len, _T("RES 1, A=(IX+(%d))"), ofs); break; + case 0x90: my_stprintf_s(buffer, buffer_len, _T("RES 2, B=(IX+(%d))"), ofs); break; + case 0x91: my_stprintf_s(buffer, buffer_len, _T("RES 2, C=(IX+(%d))"), ofs); break; + case 0x92: my_stprintf_s(buffer, buffer_len, _T("RES 2, D=(IX+(%d))"), ofs); break; + case 0x93: my_stprintf_s(buffer, buffer_len, _T("RES 2, E=(IX+(%d))"), ofs); break; + case 0x94: my_stprintf_s(buffer, buffer_len, _T("RES 2, H=(IX+(%d))"), ofs); break; + case 0x95: my_stprintf_s(buffer, buffer_len, _T("RES 2, L=(IX+(%d))"), ofs); break; + case 0x96: my_stprintf_s(buffer, buffer_len, _T("RES 2, (IX+(%d))"), ofs); break; + case 0x97: my_stprintf_s(buffer, buffer_len, _T("RES 2, A=(IX+(%d))"), ofs); break; + case 0x98: my_stprintf_s(buffer, buffer_len, _T("RES 3, B=(IX+(%d))"), ofs); break; + case 0x99: my_stprintf_s(buffer, buffer_len, _T("RES 3, C=(IX+(%d))"), ofs); break; + case 0x9a: my_stprintf_s(buffer, buffer_len, _T("RES 3, D=(IX+(%d))"), ofs); break; + case 0x9b: my_stprintf_s(buffer, buffer_len, _T("RES 3, E=(IX+(%d))"), ofs); break; + case 0x9c: my_stprintf_s(buffer, buffer_len, _T("RES 3, H=(IX+(%d))"), ofs); break; + case 0x9d: my_stprintf_s(buffer, buffer_len, _T("RES 3, L=(IX+(%d))"), ofs); break; + case 0x9e: my_stprintf_s(buffer, buffer_len, _T("RES 3, (IX+(%d))"), ofs); break; + case 0x9f: my_stprintf_s(buffer, buffer_len, _T("RES 3, A=(IX+(%d))"), ofs); break; + case 0xa0: my_stprintf_s(buffer, buffer_len, _T("RES 4, B=(IX+(%d))"), ofs); break; + case 0xa1: my_stprintf_s(buffer, buffer_len, _T("RES 4, C=(IX+(%d))"), ofs); break; + case 0xa2: my_stprintf_s(buffer, buffer_len, _T("RES 4, D=(IX+(%d))"), ofs); break; + case 0xa3: my_stprintf_s(buffer, buffer_len, _T("RES 4, E=(IX+(%d))"), ofs); break; + case 0xa4: my_stprintf_s(buffer, buffer_len, _T("RES 4, H=(IX+(%d))"), ofs); break; + case 0xa5: my_stprintf_s(buffer, buffer_len, _T("RES 4, L=(IX+(%d))"), ofs); break; + case 0xa6: my_stprintf_s(buffer, buffer_len, _T("RES 4, (IX+(%d))"), ofs); break; + case 0xa7: my_stprintf_s(buffer, buffer_len, _T("RES 4, A=(IX+(%d))"), ofs); break; + case 0xa8: my_stprintf_s(buffer, buffer_len, _T("RES 5, B=(IX+(%d))"), ofs); break; + case 0xa9: my_stprintf_s(buffer, buffer_len, _T("RES 5, C=(IX+(%d))"), ofs); break; + case 0xaa: my_stprintf_s(buffer, buffer_len, _T("RES 5, D=(IX+(%d))"), ofs); break; + case 0xab: my_stprintf_s(buffer, buffer_len, _T("RES 5, E=(IX+(%d))"), ofs); break; + case 0xac: my_stprintf_s(buffer, buffer_len, _T("RES 5, H=(IX+(%d))"), ofs); break; + case 0xad: my_stprintf_s(buffer, buffer_len, _T("RES 5, L=(IX+(%d))"), ofs); break; + case 0xae: my_stprintf_s(buffer, buffer_len, _T("RES 5, (IX+(%d))"), ofs); break; + case 0xaf: my_stprintf_s(buffer, buffer_len, _T("RES 5, A=(IX+(%d))"), ofs); break; + case 0xb0: my_stprintf_s(buffer, buffer_len, _T("RES 6, B=(IX+(%d))"), ofs); break; + case 0xb1: my_stprintf_s(buffer, buffer_len, _T("RES 6, C=(IX+(%d))"), ofs); break; + case 0xb2: my_stprintf_s(buffer, buffer_len, _T("RES 6, D=(IX+(%d))"), ofs); break; + case 0xb3: my_stprintf_s(buffer, buffer_len, _T("RES 6, E=(IX+(%d))"), ofs); break; + case 0xb4: my_stprintf_s(buffer, buffer_len, _T("RES 6, H=(IX+(%d))"), ofs); break; + case 0xb5: my_stprintf_s(buffer, buffer_len, _T("RES 6, L=(IX+(%d))"), ofs); break; + case 0xb6: my_stprintf_s(buffer, buffer_len, _T("RES 6, (IX+(%d))"), ofs); break; + case 0xb7: my_stprintf_s(buffer, buffer_len, _T("RES 6, A=(IX+(%d))"), ofs); break; + case 0xb8: my_stprintf_s(buffer, buffer_len, _T("RES 7, B=(IX+(%d))"), ofs); break; + case 0xb9: my_stprintf_s(buffer, buffer_len, _T("RES 7, C=(IX+(%d))"), ofs); break; + case 0xba: my_stprintf_s(buffer, buffer_len, _T("RES 7, D=(IX+(%d))"), ofs); break; + case 0xbb: my_stprintf_s(buffer, buffer_len, _T("RES 7, E=(IX+(%d))"), ofs); break; + case 0xbc: my_stprintf_s(buffer, buffer_len, _T("RES 7, H=(IX+(%d))"), ofs); break; + case 0xbd: my_stprintf_s(buffer, buffer_len, _T("RES 7, L=(IX+(%d))"), ofs); break; + case 0xbe: my_stprintf_s(buffer, buffer_len, _T("RES 7, (IX+(%d))"), ofs); break; + case 0xbf: my_stprintf_s(buffer, buffer_len, _T("RES 7, A=(IX+(%d))"), ofs); break; + case 0xc0: my_stprintf_s(buffer, buffer_len, _T("SET 0, B=(IX+(%d))"), ofs); break; + case 0xc1: my_stprintf_s(buffer, buffer_len, _T("SET 0, C=(IX+(%d))"), ofs); break; + case 0xc2: my_stprintf_s(buffer, buffer_len, _T("SET 0, D=(IX+(%d))"), ofs); break; + case 0xc3: my_stprintf_s(buffer, buffer_len, _T("SET 0, E=(IX+(%d))"), ofs); break; + case 0xc4: my_stprintf_s(buffer, buffer_len, _T("SET 0, H=(IX+(%d))"), ofs); break; + case 0xc5: my_stprintf_s(buffer, buffer_len, _T("SET 0, L=(IX+(%d))"), ofs); break; + case 0xc6: my_stprintf_s(buffer, buffer_len, _T("SET 0, (IX+(%d))"), ofs); break; + case 0xc7: my_stprintf_s(buffer, buffer_len, _T("SET 0, A=(IX+(%d))"), ofs); break; + case 0xc8: my_stprintf_s(buffer, buffer_len, _T("SET 1, B=(IX+(%d))"), ofs); break; + case 0xc9: my_stprintf_s(buffer, buffer_len, _T("SET 1, C=(IX+(%d))"), ofs); break; + case 0xca: my_stprintf_s(buffer, buffer_len, _T("SET 1, D=(IX+(%d))"), ofs); break; + case 0xcb: my_stprintf_s(buffer, buffer_len, _T("SET 1, E=(IX+(%d))"), ofs); break; + case 0xcc: my_stprintf_s(buffer, buffer_len, _T("SET 1, H=(IX+(%d))"), ofs); break; + case 0xcd: my_stprintf_s(buffer, buffer_len, _T("SET 1, L=(IX+(%d))"), ofs); break; + case 0xce: my_stprintf_s(buffer, buffer_len, _T("SET 1, (IX+(%d))"), ofs); break; + case 0xcf: my_stprintf_s(buffer, buffer_len, _T("SET 1, A=(IX+(%d))"), ofs); break; + case 0xd0: my_stprintf_s(buffer, buffer_len, _T("SET 2, B=(IX+(%d))"), ofs); break; + case 0xd1: my_stprintf_s(buffer, buffer_len, _T("SET 2, C=(IX+(%d))"), ofs); break; + case 0xd2: my_stprintf_s(buffer, buffer_len, _T("SET 2, D=(IX+(%d))"), ofs); break; + case 0xd3: my_stprintf_s(buffer, buffer_len, _T("SET 2, E=(IX+(%d))"), ofs); break; + case 0xd4: my_stprintf_s(buffer, buffer_len, _T("SET 2, H=(IX+(%d))"), ofs); break; + case 0xd5: my_stprintf_s(buffer, buffer_len, _T("SET 2, L=(IX+(%d))"), ofs); break; + case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SET 2, (IX+(%d))"), ofs); break; + case 0xd7: my_stprintf_s(buffer, buffer_len, _T("SET 2, A=(IX+(%d))"), ofs); break; + case 0xd8: my_stprintf_s(buffer, buffer_len, _T("SET 3, B=(IX+(%d))"), ofs); break; + case 0xd9: my_stprintf_s(buffer, buffer_len, _T("SET 3, C=(IX+(%d))"), ofs); break; + case 0xda: my_stprintf_s(buffer, buffer_len, _T("SET 3, D=(IX+(%d))"), ofs); break; + case 0xdb: my_stprintf_s(buffer, buffer_len, _T("SET 3, E=(IX+(%d))"), ofs); break; + case 0xdc: my_stprintf_s(buffer, buffer_len, _T("SET 3, H=(IX+(%d))"), ofs); break; + case 0xdd: my_stprintf_s(buffer, buffer_len, _T("SET 3, L=(IX+(%d))"), ofs); break; + case 0xde: my_stprintf_s(buffer, buffer_len, _T("SET 3, (IX+(%d))"), ofs); break; + case 0xdf: my_stprintf_s(buffer, buffer_len, _T("SET 3, A=(IX+(%d))"), ofs); break; + case 0xe0: my_stprintf_s(buffer, buffer_len, _T("SET 4, B=(IX+(%d))"), ofs); break; + case 0xe1: my_stprintf_s(buffer, buffer_len, _T("SET 4, C=(IX+(%d))"), ofs); break; + case 0xe2: my_stprintf_s(buffer, buffer_len, _T("SET 4, D=(IX+(%d))"), ofs); break; + case 0xe3: my_stprintf_s(buffer, buffer_len, _T("SET 4, E=(IX+(%d))"), ofs); break; + case 0xe4: my_stprintf_s(buffer, buffer_len, _T("SET 4, H=(IX+(%d))"), ofs); break; + case 0xe5: my_stprintf_s(buffer, buffer_len, _T("SET 4, L=(IX+(%d))"), ofs); break; + case 0xe6: my_stprintf_s(buffer, buffer_len, _T("SET 4, (IX+(%d))"), ofs); break; + case 0xe7: my_stprintf_s(buffer, buffer_len, _T("SET 4, A=(IX+(%d))"), ofs); break; + case 0xe8: my_stprintf_s(buffer, buffer_len, _T("SET 5, B=(IX+(%d))"), ofs); break; + case 0xe9: my_stprintf_s(buffer, buffer_len, _T("SET 5, C=(IX+(%d))"), ofs); break; + case 0xea: my_stprintf_s(buffer, buffer_len, _T("SET 5, D=(IX+(%d))"), ofs); break; + case 0xeb: my_stprintf_s(buffer, buffer_len, _T("SET 5, E=(IX+(%d))"), ofs); break; + case 0xec: my_stprintf_s(buffer, buffer_len, _T("SET 5, H=(IX+(%d))"), ofs); break; + case 0xed: my_stprintf_s(buffer, buffer_len, _T("SET 5, L=(IX+(%d))"), ofs); break; + case 0xee: my_stprintf_s(buffer, buffer_len, _T("SET 5, (IX+(%d))"), ofs); break; + case 0xef: my_stprintf_s(buffer, buffer_len, _T("SET 5, A=(IX+(%d))"), ofs); break; + case 0xf0: my_stprintf_s(buffer, buffer_len, _T("SET 6, B=(IX+(%d))"), ofs); break; + case 0xf1: my_stprintf_s(buffer, buffer_len, _T("SET 6, C=(IX+(%d))"), ofs); break; + case 0xf2: my_stprintf_s(buffer, buffer_len, _T("SET 6, D=(IX+(%d))"), ofs); break; + case 0xf3: my_stprintf_s(buffer, buffer_len, _T("SET 6, E=(IX+(%d))"), ofs); break; + case 0xf4: my_stprintf_s(buffer, buffer_len, _T("SET 6, H=(IX+(%d))"), ofs); break; + case 0xf5: my_stprintf_s(buffer, buffer_len, _T("SET 6, L=(IX+(%d))"), ofs); break; + case 0xf6: my_stprintf_s(buffer, buffer_len, _T("SET 6, (IX+(%d))"), ofs); break; + case 0xf7: my_stprintf_s(buffer, buffer_len, _T("SET 6, A=(IX+(%d))"), ofs); break; + case 0xf8: my_stprintf_s(buffer, buffer_len, _T("SET 7, B=(IX+(%d))"), ofs); break; + case 0xf9: my_stprintf_s(buffer, buffer_len, _T("SET 7, C=(IX+(%d))"), ofs); break; + case 0xfa: my_stprintf_s(buffer, buffer_len, _T("SET 7, D=(IX+(%d))"), ofs); break; + case 0xfb: my_stprintf_s(buffer, buffer_len, _T("SET 7, E=(IX+(%d))"), ofs); break; + case 0xfc: my_stprintf_s(buffer, buffer_len, _T("SET 7, H=(IX+(%d))"), ofs); break; + case 0xfd: my_stprintf_s(buffer, buffer_len, _T("SET 7, L=(IX+(%d))"), ofs); break; + case 0xfe: my_stprintf_s(buffer, buffer_len, _T("SET 7, (IX+(%d))"), ofs); break; + case 0xff: my_stprintf_s(buffer, buffer_len, _T("SET 7, A=(IX+(%d))"), ofs); break; +#if defined(_MSC_VER) && (_MSC_VER >= 1200) + default: __assume(0); +#endif + } } +static void dasm_fdcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) +{ + int8_t ofs = debug_fetch8_rel(); + uint8_t code = debug_fetch8(); + + switch(code) { + case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B=(IY+(%d))"), ofs); break; + case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C=(IY+(%d))"), ofs); break; + case 0x02: my_stprintf_s(buffer, buffer_len, _T("RLC D=(IY+(%d))"), ofs); break; + case 0x03: my_stprintf_s(buffer, buffer_len, _T("RLC E=(IY+(%d))"), ofs); break; + case 0x04: my_stprintf_s(buffer, buffer_len, _T("RLC H=(IY+(%d))"), ofs); break; + case 0x05: my_stprintf_s(buffer, buffer_len, _T("RLC L=(IY+(%d))"), ofs); break; + case 0x06: my_stprintf_s(buffer, buffer_len, _T("RLC (IY+(%d))"), ofs); break; + case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLC A=(IY+(%d))"), ofs); break; + case 0x08: my_stprintf_s(buffer, buffer_len, _T("RRC B=(IY+(%d))"), ofs); break; + case 0x09: my_stprintf_s(buffer, buffer_len, _T("RRC C=(IY+(%d))"), ofs); break; + case 0x0a: my_stprintf_s(buffer, buffer_len, _T("RRC D=(IY+(%d))"), ofs); break; + case 0x0b: my_stprintf_s(buffer, buffer_len, _T("RRC E=(IY+(%d))"), ofs); break; + case 0x0c: my_stprintf_s(buffer, buffer_len, _T("RRC H=(IY+(%d))"), ofs); break; + case 0x0d: my_stprintf_s(buffer, buffer_len, _T("RRC L=(IY+(%d))"), ofs); break; + case 0x0e: my_stprintf_s(buffer, buffer_len, _T("RRC (IY+(%d))"), ofs); break; + case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRC A=(IY+(%d))"), ofs); break; + case 0x10: my_stprintf_s(buffer, buffer_len, _T("RL B=(IY+(%d))"), ofs); break; + case 0x11: my_stprintf_s(buffer, buffer_len, _T("RL C=(IY+(%d))"), ofs); break; + case 0x12: my_stprintf_s(buffer, buffer_len, _T("RL D=(IY+(%d))"), ofs); break; + case 0x13: my_stprintf_s(buffer, buffer_len, _T("RL E=(IY+(%d))"), ofs); break; + case 0x14: my_stprintf_s(buffer, buffer_len, _T("RL H=(IY+(%d))"), ofs); break; + case 0x15: my_stprintf_s(buffer, buffer_len, _T("RL L=(IY+(%d))"), ofs); break; + case 0x16: my_stprintf_s(buffer, buffer_len, _T("RL (IY+(%d))"), ofs); break; + case 0x17: my_stprintf_s(buffer, buffer_len, _T("RL A=(IY+(%d))"), ofs); break; + case 0x18: my_stprintf_s(buffer, buffer_len, _T("RR B=(IY+(%d))"), ofs); break; + case 0x19: my_stprintf_s(buffer, buffer_len, _T("RR C=(IY+(%d))"), ofs); break; + case 0x1a: my_stprintf_s(buffer, buffer_len, _T("RR D=(IY+(%d))"), ofs); break; + case 0x1b: my_stprintf_s(buffer, buffer_len, _T("RR E=(IY+(%d))"), ofs); break; + case 0x1c: my_stprintf_s(buffer, buffer_len, _T("RR H=(IY+(%d))"), ofs); break; + case 0x1d: my_stprintf_s(buffer, buffer_len, _T("RR L=(IY+(%d))"), ofs); break; + case 0x1e: my_stprintf_s(buffer, buffer_len, _T("RR (IY+(%d))"), ofs); break; + case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RR A=(IY+(%d))"), ofs); break; + case 0x20: my_stprintf_s(buffer, buffer_len, _T("SLA B=(IY+(%d))"), ofs); break; + case 0x21: my_stprintf_s(buffer, buffer_len, _T("SLA C=(IY+(%d))"), ofs); break; + case 0x22: my_stprintf_s(buffer, buffer_len, _T("SLA D=(IY+(%d))"), ofs); break; + case 0x23: my_stprintf_s(buffer, buffer_len, _T("SLA E=(IY+(%d))"), ofs); break; + case 0x24: my_stprintf_s(buffer, buffer_len, _T("SLA H=(IY+(%d))"), ofs); break; + case 0x25: my_stprintf_s(buffer, buffer_len, _T("SLA L=(IY+(%d))"), ofs); break; + case 0x26: my_stprintf_s(buffer, buffer_len, _T("SLA (IY+(%d))"), ofs); break; + case 0x27: my_stprintf_s(buffer, buffer_len, _T("SLA A=(IY+(%d))"), ofs); break; + case 0x28: my_stprintf_s(buffer, buffer_len, _T("SRA B=(IY+(%d))"), ofs); break; + case 0x29: my_stprintf_s(buffer, buffer_len, _T("SRA C=(IY+(%d))"), ofs); break; + case 0x2a: my_stprintf_s(buffer, buffer_len, _T("SRA D=(IY+(%d))"), ofs); break; + case 0x2b: my_stprintf_s(buffer, buffer_len, _T("SRA E=(IY+(%d))"), ofs); break; + case 0x2c: my_stprintf_s(buffer, buffer_len, _T("SRA H=(IY+(%d))"), ofs); break; + case 0x2d: my_stprintf_s(buffer, buffer_len, _T("SRA L=(IY+(%d))"), ofs); break; + case 0x2e: my_stprintf_s(buffer, buffer_len, _T("SRA (IY+(%d))"), ofs); break; + case 0x2f: my_stprintf_s(buffer, buffer_len, _T("SRA A=(IY+(%d))"), ofs); break; + case 0x30: my_stprintf_s(buffer, buffer_len, _T("SLL B=(IY+(%d))"), ofs); break; + case 0x31: my_stprintf_s(buffer, buffer_len, _T("SLL C=(IY+(%d))"), ofs); break; + case 0x32: my_stprintf_s(buffer, buffer_len, _T("SLL D=(IY+(%d))"), ofs); break; + case 0x33: my_stprintf_s(buffer, buffer_len, _T("SLL E=(IY+(%d))"), ofs); break; + case 0x34: my_stprintf_s(buffer, buffer_len, _T("SLL H=(IY+(%d))"), ofs); break; + case 0x35: my_stprintf_s(buffer, buffer_len, _T("SLL L=(IY+(%d))"), ofs); break; + case 0x36: my_stprintf_s(buffer, buffer_len, _T("SLL (IY+(%d))"), ofs); break; + case 0x37: my_stprintf_s(buffer, buffer_len, _T("SLL A=(IY+(%d))"), ofs); break; + case 0x38: my_stprintf_s(buffer, buffer_len, _T("SRL B=(IY+(%d))"), ofs); break; + case 0x39: my_stprintf_s(buffer, buffer_len, _T("SRL C=(IY+(%d))"), ofs); break; + case 0x3a: my_stprintf_s(buffer, buffer_len, _T("SRL D=(IY+(%d))"), ofs); break; + case 0x3b: my_stprintf_s(buffer, buffer_len, _T("SRL E=(IY+(%d))"), ofs); break; + case 0x3c: my_stprintf_s(buffer, buffer_len, _T("SRL H=(IY+(%d))"), ofs); break; + case 0x3d: my_stprintf_s(buffer, buffer_len, _T("SRL L=(IY+(%d))"), ofs); break; + case 0x3e: my_stprintf_s(buffer, buffer_len, _T("SRL (IY+(%d))"), ofs); break; + case 0x3f: my_stprintf_s(buffer, buffer_len, _T("SRL A=(IY+(%d))"), ofs); break; + case 0x40: my_stprintf_s(buffer, buffer_len, _T("BIT 0, B=(IY+(%d))"), ofs); break; + case 0x41: my_stprintf_s(buffer, buffer_len, _T("BIT 0, C=(IY+(%d))"), ofs); break; + case 0x42: my_stprintf_s(buffer, buffer_len, _T("BIT 0, D=(IY+(%d))"), ofs); break; + case 0x43: my_stprintf_s(buffer, buffer_len, _T("BIT 0, E=(IY+(%d))"), ofs); break; + case 0x44: my_stprintf_s(buffer, buffer_len, _T("BIT 0, H=(IY+(%d))"), ofs); break; + case 0x45: my_stprintf_s(buffer, buffer_len, _T("BIT 0, L=(IY+(%d))"), ofs); break; + case 0x46: my_stprintf_s(buffer, buffer_len, _T("BIT 0, (IY+(%d))"), ofs); break; + case 0x47: my_stprintf_s(buffer, buffer_len, _T("BIT 0, A=(IY+(%d))"), ofs); break; + case 0x48: my_stprintf_s(buffer, buffer_len, _T("BIT 1, B=(IY+(%d))"), ofs); break; + case 0x49: my_stprintf_s(buffer, buffer_len, _T("BIT 1, C=(IY+(%d))"), ofs); break; + case 0x4a: my_stprintf_s(buffer, buffer_len, _T("BIT 1, D=(IY+(%d))"), ofs); break; + case 0x4b: my_stprintf_s(buffer, buffer_len, _T("BIT 1, E=(IY+(%d))"), ofs); break; + case 0x4c: my_stprintf_s(buffer, buffer_len, _T("BIT 1, H=(IY+(%d))"), ofs); break; + case 0x4d: my_stprintf_s(buffer, buffer_len, _T("BIT 1, L=(IY+(%d))"), ofs); break; + case 0x4e: my_stprintf_s(buffer, buffer_len, _T("BIT 1, (IY+(%d))"), ofs); break; + case 0x4f: my_stprintf_s(buffer, buffer_len, _T("BIT 1, A=(IY+(%d))"), ofs); break; + case 0x50: my_stprintf_s(buffer, buffer_len, _T("BIT 2, B=(IY+(%d))"), ofs); break; + case 0x51: my_stprintf_s(buffer, buffer_len, _T("BIT 2, C=(IY+(%d))"), ofs); break; + case 0x52: my_stprintf_s(buffer, buffer_len, _T("BIT 2, D=(IY+(%d))"), ofs); break; + case 0x53: my_stprintf_s(buffer, buffer_len, _T("BIT 2, E=(IY+(%d))"), ofs); break; + case 0x54: my_stprintf_s(buffer, buffer_len, _T("BIT 2, H=(IY+(%d))"), ofs); break; + case 0x55: my_stprintf_s(buffer, buffer_len, _T("BIT 2, L=(IY+(%d))"), ofs); break; + case 0x56: my_stprintf_s(buffer, buffer_len, _T("BIT 2, (IY+(%d))"), ofs); break; + case 0x57: my_stprintf_s(buffer, buffer_len, _T("BIT 2, A=(IY+(%d))"), ofs); break; + case 0x58: my_stprintf_s(buffer, buffer_len, _T("BIT 3, B=(IY+(%d))"), ofs); break; + case 0x59: my_stprintf_s(buffer, buffer_len, _T("BIT 3, C=(IY+(%d))"), ofs); break; + case 0x5a: my_stprintf_s(buffer, buffer_len, _T("BIT 3, D=(IY+(%d))"), ofs); break; + case 0x5b: my_stprintf_s(buffer, buffer_len, _T("BIT 3, E=(IY+(%d))"), ofs); break; + case 0x5c: my_stprintf_s(buffer, buffer_len, _T("BIT 3, H=(IY+(%d))"), ofs); break; + case 0x5d: my_stprintf_s(buffer, buffer_len, _T("BIT 3, L=(IY+(%d))"), ofs); break; + case 0x5e: my_stprintf_s(buffer, buffer_len, _T("BIT 3, (IY+(%d))"), ofs); break; + case 0x5f: my_stprintf_s(buffer, buffer_len, _T("BIT 3, A=(IY+(%d))"), ofs); break; + case 0x60: my_stprintf_s(buffer, buffer_len, _T("BIT 4, B=(IY+(%d))"), ofs); break; + case 0x61: my_stprintf_s(buffer, buffer_len, _T("BIT 4, C=(IY+(%d))"), ofs); break; + case 0x62: my_stprintf_s(buffer, buffer_len, _T("BIT 4, D=(IY+(%d))"), ofs); break; + case 0x63: my_stprintf_s(buffer, buffer_len, _T("BIT 4, E=(IY+(%d))"), ofs); break; + case 0x64: my_stprintf_s(buffer, buffer_len, _T("BIT 4, H=(IY+(%d))"), ofs); break; + case 0x65: my_stprintf_s(buffer, buffer_len, _T("BIT 4, L=(IY+(%d))"), ofs); break; + case 0x66: my_stprintf_s(buffer, buffer_len, _T("BIT 4, (IY+(%d))"), ofs); break; + case 0x67: my_stprintf_s(buffer, buffer_len, _T("BIT 4, A=(IY+(%d))"), ofs); break; + case 0x68: my_stprintf_s(buffer, buffer_len, _T("BIT 5, B=(IY+(%d))"), ofs); break; + case 0x69: my_stprintf_s(buffer, buffer_len, _T("BIT 5, C=(IY+(%d))"), ofs); break; + case 0x6a: my_stprintf_s(buffer, buffer_len, _T("BIT 5, D=(IY+(%d))"), ofs); break; + case 0x6b: my_stprintf_s(buffer, buffer_len, _T("BIT 5, E=(IY+(%d))"), ofs); break; + case 0x6c: my_stprintf_s(buffer, buffer_len, _T("BIT 5, H=(IY+(%d))"), ofs); break; + case 0x6d: my_stprintf_s(buffer, buffer_len, _T("BIT 5, L=(IY+(%d))"), ofs); break; + case 0x6e: my_stprintf_s(buffer, buffer_len, _T("BIT 5, (IY+(%d))"), ofs); break; + case 0x6f: my_stprintf_s(buffer, buffer_len, _T("BIT 5, A=(IY+(%d))"), ofs); break; + case 0x70: my_stprintf_s(buffer, buffer_len, _T("BIT 6, B=(IY+(%d))"), ofs); break; + case 0x71: my_stprintf_s(buffer, buffer_len, _T("BIT 6, C=(IY+(%d))"), ofs); break; + case 0x72: my_stprintf_s(buffer, buffer_len, _T("BIT 6, D=(IY+(%d))"), ofs); break; + case 0x73: my_stprintf_s(buffer, buffer_len, _T("BIT 6, E=(IY+(%d))"), ofs); break; + case 0x74: my_stprintf_s(buffer, buffer_len, _T("BIT 6, H=(IY+(%d))"), ofs); break; + case 0x75: my_stprintf_s(buffer, buffer_len, _T("BIT 6, L=(IY+(%d))"), ofs); break; + case 0x76: my_stprintf_s(buffer, buffer_len, _T("BIT 6, (IY+(%d))"), ofs); break; + case 0x77: my_stprintf_s(buffer, buffer_len, _T("BIT 6, A=(IY+(%d))"), ofs); break; + case 0x78: my_stprintf_s(buffer, buffer_len, _T("BIT 7, B=(IY+(%d))"), ofs); break; + case 0x79: my_stprintf_s(buffer, buffer_len, _T("BIT 7, C=(IY+(%d))"), ofs); break; + case 0x7a: my_stprintf_s(buffer, buffer_len, _T("BIT 7, D=(IY+(%d))"), ofs); break; + case 0x7b: my_stprintf_s(buffer, buffer_len, _T("BIT 7, E=(IY+(%d))"), ofs); break; + case 0x7c: my_stprintf_s(buffer, buffer_len, _T("BIT 7, H=(IY+(%d))"), ofs); break; + case 0x7d: my_stprintf_s(buffer, buffer_len, _T("BIT 7, L=(IY+(%d))"), ofs); break; + case 0x7e: my_stprintf_s(buffer, buffer_len, _T("BIT 7, (IY+(%d))"), ofs); break; + case 0x7f: my_stprintf_s(buffer, buffer_len, _T("BIT 7, A=(IY+(%d))"), ofs); break; + case 0x80: my_stprintf_s(buffer, buffer_len, _T("RES 0, B=(IY+(%d))"), ofs); break; + case 0x81: my_stprintf_s(buffer, buffer_len, _T("RES 0, C=(IY+(%d))"), ofs); break; + case 0x82: my_stprintf_s(buffer, buffer_len, _T("RES 0, D=(IY+(%d))"), ofs); break; + case 0x83: my_stprintf_s(buffer, buffer_len, _T("RES 0, E=(IY+(%d))"), ofs); break; + case 0x84: my_stprintf_s(buffer, buffer_len, _T("RES 0, H=(IY+(%d))"), ofs); break; + case 0x85: my_stprintf_s(buffer, buffer_len, _T("RES 0, L=(IY+(%d))"), ofs); break; + case 0x86: my_stprintf_s(buffer, buffer_len, _T("RES 0, (IY+(%d))"), ofs); break; + case 0x87: my_stprintf_s(buffer, buffer_len, _T("RES 0, A=(IY+(%d))"), ofs); break; + case 0x88: my_stprintf_s(buffer, buffer_len, _T("RES 1, B=(IY+(%d))"), ofs); break; + case 0x89: my_stprintf_s(buffer, buffer_len, _T("RES 1, C=(IY+(%d))"), ofs); break; + case 0x8a: my_stprintf_s(buffer, buffer_len, _T("RES 1, D=(IY+(%d))"), ofs); break; + case 0x8b: my_stprintf_s(buffer, buffer_len, _T("RES 1, E=(IY+(%d))"), ofs); break; + case 0x8c: my_stprintf_s(buffer, buffer_len, _T("RES 1, H=(IY+(%d))"), ofs); break; + case 0x8d: my_stprintf_s(buffer, buffer_len, _T("RES 1, L=(IY+(%d))"), ofs); break; + case 0x8e: my_stprintf_s(buffer, buffer_len, _T("RES 1, (IY+(%d))"), ofs); break; + case 0x8f: my_stprintf_s(buffer, buffer_len, _T("RES 1, A=(IY+(%d))"), ofs); break; + case 0x90: my_stprintf_s(buffer, buffer_len, _T("RES 2, B=(IY+(%d))"), ofs); break; + case 0x91: my_stprintf_s(buffer, buffer_len, _T("RES 2, C=(IY+(%d))"), ofs); break; + case 0x92: my_stprintf_s(buffer, buffer_len, _T("RES 2, D=(IY+(%d))"), ofs); break; + case 0x93: my_stprintf_s(buffer, buffer_len, _T("RES 2, E=(IY+(%d))"), ofs); break; + case 0x94: my_stprintf_s(buffer, buffer_len, _T("RES 2, H=(IY+(%d))"), ofs); break; + case 0x95: my_stprintf_s(buffer, buffer_len, _T("RES 2, L=(IY+(%d))"), ofs); break; + case 0x96: my_stprintf_s(buffer, buffer_len, _T("RES 2, (IY+(%d))"), ofs); break; + case 0x97: my_stprintf_s(buffer, buffer_len, _T("RES 2, A=(IY+(%d))"), ofs); break; + case 0x98: my_stprintf_s(buffer, buffer_len, _T("RES 3, B=(IY+(%d))"), ofs); break; + case 0x99: my_stprintf_s(buffer, buffer_len, _T("RES 3, C=(IY+(%d))"), ofs); break; + case 0x9a: my_stprintf_s(buffer, buffer_len, _T("RES 3, D=(IY+(%d))"), ofs); break; + case 0x9b: my_stprintf_s(buffer, buffer_len, _T("RES 3, E=(IY+(%d))"), ofs); break; + case 0x9c: my_stprintf_s(buffer, buffer_len, _T("RES 3, H=(IY+(%d))"), ofs); break; + case 0x9d: my_stprintf_s(buffer, buffer_len, _T("RES 3, L=(IY+(%d))"), ofs); break; + case 0x9e: my_stprintf_s(buffer, buffer_len, _T("RES 3, (IY+(%d))"), ofs); break; + case 0x9f: my_stprintf_s(buffer, buffer_len, _T("RES 3, A=(IY+(%d))"), ofs); break; + case 0xa0: my_stprintf_s(buffer, buffer_len, _T("RES 4, B=(IY+(%d))"), ofs); break; + case 0xa1: my_stprintf_s(buffer, buffer_len, _T("RES 4, C=(IY+(%d))"), ofs); break; + case 0xa2: my_stprintf_s(buffer, buffer_len, _T("RES 4, D=(IY+(%d))"), ofs); break; + case 0xa3: my_stprintf_s(buffer, buffer_len, _T("RES 4, E=(IY+(%d))"), ofs); break; + case 0xa4: my_stprintf_s(buffer, buffer_len, _T("RES 4, H=(IY+(%d))"), ofs); break; + case 0xa5: my_stprintf_s(buffer, buffer_len, _T("RES 4, L=(IY+(%d))"), ofs); break; + case 0xa6: my_stprintf_s(buffer, buffer_len, _T("RES 4, (IY+(%d))"), ofs); break; + case 0xa7: my_stprintf_s(buffer, buffer_len, _T("RES 4, A=(IY+(%d))"), ofs); break; + case 0xa8: my_stprintf_s(buffer, buffer_len, _T("RES 5, B=(IY+(%d))"), ofs); break; + case 0xa9: my_stprintf_s(buffer, buffer_len, _T("RES 5, C=(IY+(%d))"), ofs); break; + case 0xaa: my_stprintf_s(buffer, buffer_len, _T("RES 5, D=(IY+(%d))"), ofs); break; + case 0xab: my_stprintf_s(buffer, buffer_len, _T("RES 5, E=(IY+(%d))"), ofs); break; + case 0xac: my_stprintf_s(buffer, buffer_len, _T("RES 5, H=(IY+(%d))"), ofs); break; + case 0xad: my_stprintf_s(buffer, buffer_len, _T("RES 5, L=(IY+(%d))"), ofs); break; + case 0xae: my_stprintf_s(buffer, buffer_len, _T("RES 5, (IY+(%d))"), ofs); break; + case 0xaf: my_stprintf_s(buffer, buffer_len, _T("RES 5, A=(IY+(%d))"), ofs); break; + case 0xb0: my_stprintf_s(buffer, buffer_len, _T("RES 6, B=(IY+(%d))"), ofs); break; + case 0xb1: my_stprintf_s(buffer, buffer_len, _T("RES 6, C=(IY+(%d))"), ofs); break; + case 0xb2: my_stprintf_s(buffer, buffer_len, _T("RES 6, D=(IY+(%d))"), ofs); break; + case 0xb3: my_stprintf_s(buffer, buffer_len, _T("RES 6, E=(IY+(%d))"), ofs); break; + case 0xb4: my_stprintf_s(buffer, buffer_len, _T("RES 6, H=(IY+(%d))"), ofs); break; + case 0xb5: my_stprintf_s(buffer, buffer_len, _T("RES 6, L=(IY+(%d))"), ofs); break; + case 0xb6: my_stprintf_s(buffer, buffer_len, _T("RES 6, (IY+(%d))"), ofs); break; + case 0xb7: my_stprintf_s(buffer, buffer_len, _T("RES 6, A=(IY+(%d))"), ofs); break; + case 0xb8: my_stprintf_s(buffer, buffer_len, _T("RES 7, B=(IY+(%d))"), ofs); break; + case 0xb9: my_stprintf_s(buffer, buffer_len, _T("RES 7, C=(IY+(%d))"), ofs); break; + case 0xba: my_stprintf_s(buffer, buffer_len, _T("RES 7, D=(IY+(%d))"), ofs); break; + case 0xbb: my_stprintf_s(buffer, buffer_len, _T("RES 7, E=(IY+(%d))"), ofs); break; + case 0xbc: my_stprintf_s(buffer, buffer_len, _T("RES 7, H=(IY+(%d))"), ofs); break; + case 0xbd: my_stprintf_s(buffer, buffer_len, _T("RES 7, L=(IY+(%d))"), ofs); break; + case 0xbe: my_stprintf_s(buffer, buffer_len, _T("RES 7, (IY+(%d))"), ofs); break; + case 0xbf: my_stprintf_s(buffer, buffer_len, _T("RES 7, A=(IY+(%d))"), ofs); break; + case 0xc0: my_stprintf_s(buffer, buffer_len, _T("SET 0, B=(IY+(%d))"), ofs); break; + case 0xc1: my_stprintf_s(buffer, buffer_len, _T("SET 0, C=(IY+(%d))"), ofs); break; + case 0xc2: my_stprintf_s(buffer, buffer_len, _T("SET 0, D=(IY+(%d))"), ofs); break; + case 0xc3: my_stprintf_s(buffer, buffer_len, _T("SET 0, E=(IY+(%d))"), ofs); break; + case 0xc4: my_stprintf_s(buffer, buffer_len, _T("SET 0, H=(IY+(%d))"), ofs); break; + case 0xc5: my_stprintf_s(buffer, buffer_len, _T("SET 0, L=(IY+(%d))"), ofs); break; + case 0xc6: my_stprintf_s(buffer, buffer_len, _T("SET 0, (IY+(%d))"), ofs); break; + case 0xc7: my_stprintf_s(buffer, buffer_len, _T("SET 0, A=(IY+(%d))"), ofs); break; + case 0xc8: my_stprintf_s(buffer, buffer_len, _T("SET 1, B=(IY+(%d))"), ofs); break; + case 0xc9: my_stprintf_s(buffer, buffer_len, _T("SET 1, C=(IY+(%d))"), ofs); break; + case 0xca: my_stprintf_s(buffer, buffer_len, _T("SET 1, D=(IY+(%d))"), ofs); break; + case 0xcb: my_stprintf_s(buffer, buffer_len, _T("SET 1, E=(IY+(%d))"), ofs); break; + case 0xcc: my_stprintf_s(buffer, buffer_len, _T("SET 1, H=(IY+(%d))"), ofs); break; + case 0xcd: my_stprintf_s(buffer, buffer_len, _T("SET 1, L=(IY+(%d))"), ofs); break; + case 0xce: my_stprintf_s(buffer, buffer_len, _T("SET 1, (IY+(%d))"), ofs); break; + case 0xcf: my_stprintf_s(buffer, buffer_len, _T("SET 1, A=(IY+(%d))"), ofs); break; + case 0xd0: my_stprintf_s(buffer, buffer_len, _T("SET 2, B=(IY+(%d))"), ofs); break; + case 0xd1: my_stprintf_s(buffer, buffer_len, _T("SET 2, C=(IY+(%d))"), ofs); break; + case 0xd2: my_stprintf_s(buffer, buffer_len, _T("SET 2, D=(IY+(%d))"), ofs); break; + case 0xd3: my_stprintf_s(buffer, buffer_len, _T("SET 2, E=(IY+(%d))"), ofs); break; + case 0xd4: my_stprintf_s(buffer, buffer_len, _T("SET 2, H=(IY+(%d))"), ofs); break; + case 0xd5: my_stprintf_s(buffer, buffer_len, _T("SET 2, L=(IY+(%d))"), ofs); break; + case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SET 2, (IY+(%d))"), ofs); break; + case 0xd7: my_stprintf_s(buffer, buffer_len, _T("SET 2, A=(IY+(%d))"), ofs); break; + case 0xd8: my_stprintf_s(buffer, buffer_len, _T("SET 3, B=(IY+(%d))"), ofs); break; + case 0xd9: my_stprintf_s(buffer, buffer_len, _T("SET 3, C=(IY+(%d))"), ofs); break; + case 0xda: my_stprintf_s(buffer, buffer_len, _T("SET 3, D=(IY+(%d))"), ofs); break; + case 0xdb: my_stprintf_s(buffer, buffer_len, _T("SET 3, E=(IY+(%d))"), ofs); break; + case 0xdc: my_stprintf_s(buffer, buffer_len, _T("SET 3, H=(IY+(%d))"), ofs); break; + case 0xdd: my_stprintf_s(buffer, buffer_len, _T("SET 3, L=(IY+(%d))"), ofs); break; + case 0xde: my_stprintf_s(buffer, buffer_len, _T("SET 3, (IY+(%d))"), ofs); break; + case 0xdf: my_stprintf_s(buffer, buffer_len, _T("SET 3, A=(IY+(%d))"), ofs); break; + case 0xe0: my_stprintf_s(buffer, buffer_len, _T("SET 4, B=(IY+(%d))"), ofs); break; + case 0xe1: my_stprintf_s(buffer, buffer_len, _T("SET 4, C=(IY+(%d))"), ofs); break; + case 0xe2: my_stprintf_s(buffer, buffer_len, _T("SET 4, D=(IY+(%d))"), ofs); break; + case 0xe3: my_stprintf_s(buffer, buffer_len, _T("SET 4, E=(IY+(%d))"), ofs); break; + case 0xe4: my_stprintf_s(buffer, buffer_len, _T("SET 4, H=(IY+(%d))"), ofs); break; + case 0xe5: my_stprintf_s(buffer, buffer_len, _T("SET 4, L=(IY+(%d))"), ofs); break; + case 0xe6: my_stprintf_s(buffer, buffer_len, _T("SET 4, (IY+(%d))"), ofs); break; + case 0xe7: my_stprintf_s(buffer, buffer_len, _T("SET 4, A=(IY+(%d))"), ofs); break; + case 0xe8: my_stprintf_s(buffer, buffer_len, _T("SET 5, B=(IY+(%d))"), ofs); break; + case 0xe9: my_stprintf_s(buffer, buffer_len, _T("SET 5, C=(IY+(%d))"), ofs); break; + case 0xea: my_stprintf_s(buffer, buffer_len, _T("SET 5, D=(IY+(%d))"), ofs); break; + case 0xeb: my_stprintf_s(buffer, buffer_len, _T("SET 5, E=(IY+(%d))"), ofs); break; + case 0xec: my_stprintf_s(buffer, buffer_len, _T("SET 5, H=(IY+(%d))"), ofs); break; + case 0xed: my_stprintf_s(buffer, buffer_len, _T("SET 5, L=(IY+(%d))"), ofs); break; + case 0xee: my_stprintf_s(buffer, buffer_len, _T("SET 5, (IY+(%d))"), ofs); break; + case 0xef: my_stprintf_s(buffer, buffer_len, _T("SET 5, A=(IY+(%d))"), ofs); break; + case 0xf0: my_stprintf_s(buffer, buffer_len, _T("SET 6, B=(IY+(%d))"), ofs); break; + case 0xf1: my_stprintf_s(buffer, buffer_len, _T("SET 6, C=(IY+(%d))"), ofs); break; + case 0xf2: my_stprintf_s(buffer, buffer_len, _T("SET 6, D=(IY+(%d))"), ofs); break; + case 0xf3: my_stprintf_s(buffer, buffer_len, _T("SET 6, E=(IY+(%d))"), ofs); break; + case 0xf4: my_stprintf_s(buffer, buffer_len, _T("SET 6, H=(IY+(%d))"), ofs); break; + case 0xf5: my_stprintf_s(buffer, buffer_len, _T("SET 6, L=(IY+(%d))"), ofs); break; + case 0xf6: my_stprintf_s(buffer, buffer_len, _T("SET 6, (IY+(%d))"), ofs); break; + case 0xf7: my_stprintf_s(buffer, buffer_len, _T("SET 6, A=(IY+(%d))"), ofs); break; + case 0xf8: my_stprintf_s(buffer, buffer_len, _T("SET 7, B=(IY+(%d))"), ofs); break; + case 0xf9: my_stprintf_s(buffer, buffer_len, _T("SET 7, C=(IY+(%d))"), ofs); break; + case 0xfa: my_stprintf_s(buffer, buffer_len, _T("SET 7, D=(IY+(%d))"), ofs); break; + case 0xfb: my_stprintf_s(buffer, buffer_len, _T("SET 7, E=(IY+(%d))"), ofs); break; + case 0xfc: my_stprintf_s(buffer, buffer_len, _T("SET 7, H=(IY+(%d))"), ofs); break; + case 0xfd: my_stprintf_s(buffer, buffer_len, _T("SET 7, L=(IY+(%d))"), ofs); break; + case 0xfe: my_stprintf_s(buffer, buffer_len, _T("SET 7, (IY+(%d))"), ofs); break; + case 0xff: my_stprintf_s(buffer, buffer_len, _T("SET 7, A=(IY+(%d))"), ofs); break; +#if defined(_MSC_VER) && (_MSC_VER >= 1200) + default: __assume(0); +#endif + } +} + +} // extern "C" + int Z80::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata ) { for(int i = 0; i < 4; i++) { @@ -583,6 +4041,69 @@ int Z80::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len return z80_dasm_main(pc, buffer, buffer_len, d_debugger->first_symbol); } +#define STATE_VERSION 4 -#endif +bool Z80::process_state(FILEIO* state_fio, bool loading) +{ + if(!state_fio->StateCheckUint32(STATE_VERSION)) { + return false; + } + + if(!state_fio->StateCheckInt32(this_device_id)) { + return false; + } + state_fio->StateValue(total_icount); + + state_fio->StateValue(icount); + state_fio->StateValue(extra_icount); + state_fio->StateValue(busreq_icount); + state_fio->StateValue(prevpc); + state_fio->StateValue(pc.d); + state_fio->StateValue(sp.d); + state_fio->StateValue(af.d); + state_fio->StateValue(bc.d); + state_fio->StateValue(de.d); + state_fio->StateValue(hl.d); + state_fio->StateValue(ix.d); + state_fio->StateValue(iy.d); + state_fio->StateValue(wz.d); + state_fio->StateValue(af2.d); + state_fio->StateValue(bc2.d); + state_fio->StateValue(de2.d); + state_fio->StateValue(hl2.d); + state_fio->StateValue(I); + state_fio->StateValue(R); + state_fio->StateValue(R2); + state_fio->StateValue(ea); + state_fio->StateValue(busreq); + state_fio->StateValue(after_halt); + state_fio->StateValue(im); + state_fio->StateValue(iff1); + state_fio->StateValue(iff2); + state_fio->StateValue(icr); + state_fio->StateValue(after_ei); + state_fio->StateValue(after_ldair); + state_fio->StateValue(intr_req_bit); + state_fio->StateValue(intr_pend_bit); + + // post process + if(loading) { + prev_total_icount = total_icount; + // Post process for collecting statistics. + cycles_tmp_count = total_icount; + extra_tmp_count = 0; + insns_count = 0; + frames_count = 0; + nmi_count = 0; + irq_count = 0; + nsc800_int_count = 0; + nsc800_rsta_count = 0; + nsc800_rsta_count = 0; + nsc800_rsta_count = 0; + } + return true; +} + + +//#endif diff --git a/source/src/vm/z80.h b/source/src/vm/z80.h index e479d6647..b6ece69cd 100644 --- a/source/src/vm/z80.h +++ b/source/src/vm/z80.h @@ -27,7 +27,7 @@ //#ifdef USE_DEBUGGER class DEBUGGER; //#endif -class Z80_BASE : public DEVICE +class DLL_PREFIX Z80 : public DEVICE { protected: /* --------------------------------------------------------------------------- @@ -47,6 +47,8 @@ class Z80_BASE : public DEVICE //#endif outputs_t outputs_busack; + uint32_t __CPU_START_ADDR; + bool __USE_DEBUGGER; bool has_nsc800; bool has_memory_wait; bool has_io_wait; @@ -249,8 +251,10 @@ class Z80_BASE : public DEVICE int nsc800_rstb_count; int nsc800_rstc_count; + void check_interrupt(); + public: - Z80_BASE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + Z80(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { flags_initialized = false; busreq = false; @@ -276,7 +280,7 @@ class Z80_BASE : public DEVICE set_device_name(_T("Z80 CPU")); } - ~Z80_BASE() {} + ~Z80() {} // common functions virtual void initialize(); @@ -288,14 +292,15 @@ class Z80_BASE : public DEVICE void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); uint32_t __FASTCALL read_signal(int id); - void set_intr_line(bool line, bool pending, uint32_t bit) + + void __FASTCALL set_intr_line(bool line, bool pending, uint32_t bit) { uint32_t mask = 1 << bit; intr_req_bit = line ? (intr_req_bit | mask) : (intr_req_bit & ~mask); intr_pend_bit = pending ? (intr_pend_bit | mask) : (intr_pend_bit & ~mask); if(line) irq_count++; } - void set_extra_clock(int clock) + void __FASTCALL set_extra_clock(int clock) { extra_icount += clock; } @@ -332,6 +337,12 @@ class Z80_BASE : public DEVICE { return 0xffff; } + + void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_data8(uint32_t addr); + void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); + uint32_t __FASTCALL read_debug_io8(uint32_t addr); + bool write_debug_reg(const _TCHAR *reg, uint32_t data); bool get_debug_regs_info(_TCHAR *buffer, size_t buffer_len); virtual int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); @@ -345,11 +356,23 @@ class Z80_BASE : public DEVICE { d_io = device; } + void set_context_bios(DEVICE* device) + { + d_bios = device; + } + void set_context_dma(DEVICE* device) + { + d_dma = device; + } + void set_context_debugger(DEBUGGER* device) + { + d_debugger = device; + } DEVICE *get_context_child() { return d_pic; } - void set_context_intr(DEVICE* device) + void set_context_intr(DEVICE* device, uint32_t bit = 0xffffffff) { d_pic = device; } @@ -367,46 +390,6 @@ class Z80_BASE : public DEVICE } }; -class Z80 : public Z80_BASE -{ -protected: - void check_interrupt(); - void __FASTCALL run_one_opecode() override; - void __FASTCALL debugger_hook(void) override; -public: - Z80(VM_TEMPLATE* parent_vm, EMU* parent_emu); - ~Z80(); - void initialize(); - void reset(); - int __FASTCALL run(int clock) override; - - int debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata = 0); -#ifdef USE_DEBUGGER - void __FASTCALL write_debug_data8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_data8(uint32_t addr); - void __FASTCALL write_debug_io8(uint32_t addr, uint32_t data); - uint32_t __FASTCALL read_debug_io8(uint32_t addr); -#endif -#ifdef Z80_PSEUDO_BIOS - void set_context_bios(DEVICE* device) - { - d_bios = device; - } -#endif -#ifdef SINGLE_MODE_DMA - void set_context_dma(DEVICE* device) - { - d_dma = device; - } -#endif -#ifdef USE_DEBUGGER - void set_context_debugger(DEBUGGER* device) - { - d_debugger = device; - } -#endif -}; - #endif diff --git a/source/src/vm/z80_base.cpp b/source/src/vm/z80_base.cpp deleted file mode 100644 index f98633747..000000000 --- a/source/src/vm/z80_base.cpp +++ /dev/null @@ -1,3828 +0,0 @@ -/* - Skelton for retropc emulator - - Origin : MAME 0.145 - Author : Takeda.Toshiya - Date : 2012.02.15- - - [ Z80 ] -*/ - -#include "./z80.h" -//#ifdef USE_DEBUGGER -//#include "debugger.h" -//#endif - -//#ifndef CPU_START_ADDR -//#define CPU_START_ADDR 0 -//#endif - -#define NMI_REQ_BIT 0x80000000 - -#define CF 0x01 -#define NF 0x02 -#define PF 0x04 -#define VF PF -#define XF 0x08 -#define HF 0x10 -#define YF 0x20 -#define ZF 0x40 -#define SF 0x80 - -#define PCD pc.d -#define PC pc.w.l - -#define SPD sp.d -#define SP sp.w.l - -#define AFD af.d -#define AF af.w.l -#define A af.b.h -#define F af.b.l - -#define BCD bc.d -#define BC bc.w.l -#define B bc.b.h -#define C bc.b.l - -#define DED de.d -#define DE de.w.l -#define D de.b.h -#define E de.b.l - -#define HLD hl.d -#define HL hl.w.l -#define H hl.b.h -#define L hl.b.l - -#define IXD ix.d -#define IX ix.w.l -#define HX ix.b.h -#define LX ix.b.l - -#define IYD iy.d -#define IY iy.w.l -#define HY iy.b.h -#define LY iy.b.l - -#define AF2 af2.w.l -#define A2 af2.b.h -#define F2 af2.b.l - -#define BC2 bc2.w.l -#define B2 bc2.b.h -#define C2 bc2.b.l - -#define DE2 de2.w.l -#define D2 de2.b.h -#define E2 de2.b.l - -#define HL2 hl2.w.l -#define H2 hl2.b.h -#define L2 hl2.b.l - -#define WZD wz.d -#define WZ wz.w.l -#define WZ_H wz.b.h -#define WZ_L wz.b.l - - -// opecode definitions - -#define ENTER_HALT() do { \ - PC--; \ - after_halt = true; \ -} while(0) - -#define LEAVE_HALT() do { \ - if(after_halt) { \ - after_halt = false; \ - PC++; \ - } \ -} while(0) - -#define UPDATE_EXTRA_EVENT(clock) do { \ - if(is_primary) { \ - if(busreq) { \ - busreq_icount += (clock); \ - } \ - update_extra_event(clock); \ - } \ -} while(0) - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::RM8(uint32_t addr) -{ -//#ifdef Z80_MEMORY_WAIT - UPDATE_EXTRA_EVENT(1); - if(has_memory_wait) { - int wait; - uint8_t val = d_mem->read_data8w(addr, &wait); - icount -= wait; - UPDATE_EXTRA_EVENT(2 + wait); - return val; - } else { -//#else - uint8_t val = d_mem->read_data8(addr); - UPDATE_EXTRA_EVENT(2); - return val; - } -//#endif -} - -Z80_INLINE void __FASTCALL Z80_BASE::WM8(uint32_t addr, uint8_t val) -{ -//#ifdef Z80_MEMORY_WAIT - UPDATE_EXTRA_EVENT(1); - if(has_memory_wait) { - int wait; - d_mem->write_data8w(addr, val, &wait); - icount -= wait; - UPDATE_EXTRA_EVENT(2 + wait); - } else { -//#else - d_mem->write_data8(addr, val); - UPDATE_EXTRA_EVENT(2); - } -//#endif -} - -Z80_INLINE void __FASTCALL Z80_BASE::RM16(uint32_t addr, pair32_t *r) -{ - r->b.l = RM8(addr); - r->b.h = RM8((addr + 1) & 0xffff); -} - -Z80_INLINE void __FASTCALL Z80_BASE::WM16(uint32_t addr, pair32_t *r) -{ - WM8(addr, r->b.l); - WM8((addr + 1) & 0xffff, r->b.h); -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::FETCHOP() -{ - unsigned pctmp = PCD; - PC++; - R++; - - // consider m1 cycle wait - UPDATE_EXTRA_EVENT(1); - int wait; - uint8_t val = d_mem->fetch_op(pctmp, &wait); - icount -= wait; - UPDATE_EXTRA_EVENT(3 + wait); - return val; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::FETCH8() -{ - unsigned pctmp = PCD; - PC++; - return RM8(pctmp); -} - -Z80_INLINE uint32_t __FASTCALL Z80_BASE::FETCH16() -{ - unsigned pctmp = PCD; - PC += 2; - return RM8(pctmp) | ((uint32_t)RM8((pctmp + 1) & 0xffff) << 8); -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::IN8(uint32_t addr) -{ -//#ifdef Z80_IO_WAIT - UPDATE_EXTRA_EVENT(2); - if(has_io_wait) { - int wait; - uint8_t val = d_io->read_io8w(addr, &wait); - icount -= wait; - UPDATE_EXTRA_EVENT(2 + wait); - return val; - } else { -//#else - uint8_t val = d_io->read_io8(addr); - UPDATE_EXTRA_EVENT(2); - return val; - } -//#endif -} - -Z80_INLINE void __FASTCALL Z80_BASE::OUT8(uint32_t addr, uint8_t val) -{ -//#ifdef HAS_NSC800 - UPDATE_EXTRA_EVENT(2); - if(has_nsc800) { - if((addr & 0xff) == 0xbb) { - icr = val; - UPDATE_EXTRA_EVENT(2); - return; - } - } -//#endif -//#ifdef Z80_IO_WAIT - if(has_io_wait) { - int wait; - d_io->write_io8w(addr, val, &wait); - icount -= wait; - UPDATE_EXTRA_EVENT(2 + wait); - } else { -//#else - d_io->write_io8(addr, val); - UPDATE_EXTRA_EVENT(2); - } -//#endif -} - -#define EAX() do { \ - ea = (uint32_t)(uint16_t)(IX + (int8_t)FETCH8()); \ - WZ = ea; \ -} while(0) - -#define EAY() do { \ - ea = (uint32_t)(uint16_t)(IY + (int8_t)FETCH8()); \ - WZ = ea; \ -} while(0) - -#define POP(DR) do { \ - RM16(SPD, &DR); \ - SP += 2; \ -} while(0) - -#define PUSH(SR) do { \ - SP -= 2; \ - WM16(SPD, &SR); \ -} while(0) - -#define JP() do { \ - PCD = FETCH16(); \ - WZ = PCD; \ -} while(0) - -#define JP_COND(cond) do { \ - if(cond) { \ - PCD = FETCH16(); \ - WZ = PCD; \ - } else { \ - WZ = FETCH16(); /* implicit do PC += 2 */ \ - } \ -} while(0) - -#define JR() do { \ - int8_t arg = (int8_t)FETCH8(); /* FETCH8() also increments PC */ \ - PC += arg; /* so don't do PC += FETCH8() */ \ - WZ = PC; \ -} while(0) - -#define JR_COND(cond, opcode) do { \ - if(cond) { \ - JR(); \ - icount -= cc_ex[opcode]; \ - } else FETCH8(); \ -} while(0) - -#define CALL() do { \ - ea = FETCH16(); \ - WZ = ea; \ - PUSH(pc); \ - PCD = ea; \ -} while(0) - -#define CALL_COND(cond, opcode) do { \ - if(cond) { \ - ea = FETCH16(); \ - WZ = ea; \ - PUSH(pc); \ - PCD = ea; \ - icount -= cc_ex[opcode]; \ - } else { \ - WZ = FETCH16(); /* implicit call PC+=2; */ \ - } \ -} while(0) - -#define RET_COND(cond, opcode) do { \ - if(cond) { \ - POP(pc); \ - WZ = PC; \ - icount -= cc_ex[opcode]; \ - } \ -} while(0) - -#define RETN() do { \ - POP(pc); \ - WZ = PC; \ - iff1 = iff2; \ -} while(0) - -#define RETI() do { \ - POP(pc); \ - WZ = PC; \ - iff1 = iff2; \ - if(d_pic != NULL) d_pic->notify_intr_reti(); \ -} while(0) - -#define LD_R_A() do { \ - R = A; \ - R2 = A & 0x80; /* keep bit 7 of r */ \ -} while(0) - -#define LD_A_R() do { \ - A = (R & 0x7f) | R2; \ - F = (F & CF) | SZ[A] | (iff2 << 2); \ - after_ldair = true; \ -} while(0) - -#define LD_I_A() do { \ - I = A; \ -} while(0) - -#define LD_A_I() do { \ - A = I; \ - F = (F & CF) | SZ[A] | (iff2 << 2); \ - after_ldair = true; \ -} while(0) - -#define RST(addr) do { \ - PUSH(pc); \ - PCD = addr; \ - WZ = PC; \ -} while(0) - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::INC(uint8_t value) -{ - uint8_t res = value + 1; - F = (F & CF) | SZHV_inc[res]; - return (uint8_t)res; -} - -Z80_INLINE uint8_t Z80_BASE::DEC(uint8_t value) -{ - uint8_t res = value - 1; - F = (F & CF) | SZHV_dec[res]; - return res; -} - -#define RLCA() do { \ - A = (A << 1) | (A >> 7); \ - F = (F & (SF | ZF | PF)) | (A & (YF | XF | CF)); \ -} while(0) - -#define RRCA() do { \ - F = (F & (SF | ZF | PF)) | (A & CF); \ - A = (A >> 1) | (A << 7); \ - F |= (A & (YF | XF)); \ -} while(0) - -#define RLA() do { \ - uint8_t res = (A << 1) | (F & CF); \ - uint8_t c = (A & 0x80) ? CF : 0; \ - F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ - A = res; \ -} while(0) - -#define RRA() do { \ - uint8_t res = (A >> 1) | (F << 7); \ - uint8_t c = (A & 0x01) ? CF : 0; \ - F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); \ - A = res; \ -} while(0) - -#define RRD() do { \ - uint8_t n = RM8(HL); \ - WZ = HL + 1; \ - WM8(HL, (n >> 4) | (A << 4)); \ - A = (A & 0xf0) | (n & 0x0f); \ - F = (F & CF) | SZP[A]; \ -} while(0) - -#define RLD() do { \ - uint8_t n = RM8(HL); \ - WZ = HL + 1; \ - WM8(HL, (n << 4) | (A & 0x0f)); \ - A = (A & 0xf0) | (n >> 4); \ - F = (F & CF) | SZP[A]; \ -} while(0) - -#define ADD(value) do { \ - uint32_t ah = AFD & 0xff00; \ - uint32_t res = (uint8_t)((ah >> 8) + value); \ - F = SZHVC_add[ah | res]; \ - A = res; \ -} while(0) - -#define ADC(value) do { \ - uint32_t ah = AFD & 0xff00, c = AFD & 1; \ - uint32_t res = (uint8_t)((ah >> 8) + value + c); \ - F = SZHVC_add[(c << 16) | ah | res]; \ - A = res; \ -} while(0) - -#define SUB(value) do { \ - uint32_t ah = AFD & 0xff00; \ - uint32_t res = (uint8_t)((ah >> 8) - value); \ - F = SZHVC_sub[ah | res]; \ - A = res; \ -} while(0) - -#define SBC(value) do { \ - uint32_t ah = AFD & 0xff00, c = AFD & 1; \ - uint32_t res = (uint8_t)((ah >> 8) - value - c); \ - F = SZHVC_sub[(c << 16) | ah | res]; \ - A = res; \ -} while(0) - -#define NEG() do { \ - uint8_t value = A; \ - A = 0; \ - SUB(value); \ -} while(0) - -#define DAA() do { \ - uint8_t a = A; \ - if(F & NF) { \ - if((F & HF) | ((A & 0xf) > 9)) a -= 6; \ - if((F & CF) | (A > 0x99)) a -= 0x60; \ - } else { \ - if((F & HF) | ((A & 0xf) > 9)) a += 6; \ - if((F & CF) | (A > 0x99)) a += 0x60; \ - } \ - F = (F & (CF | NF)) | (A > 0x99) | ((A ^ a) & HF) | SZP[a]; \ - A = a; \ -} while(0) - -#define AND(value) do { \ - A &= value; \ - F = SZP[A] | HF; \ -} while(0) - -#define OR(value) do { \ - A |= value; \ - F = SZP[A]; \ -} while(0) - -#define XOR(value) do { \ - A ^= value; \ - F = SZP[A]; \ -} while(0) - -#define CP(value) do { \ - unsigned val = value; \ - uint32_t ah = AFD & 0xff00; \ - uint32_t res = (uint8_t)((ah >> 8) - val); \ - F = (SZHVC_sub[ah | res] & ~(YF | XF)) | (val & (YF | XF)); \ -} while(0) - -#define EX_AF() do { \ - pair32_t tmp; \ - tmp = af; af = af2; af2 = tmp; \ -} while(0) - -#define EX_DE_HL() do { \ - pair32_t tmp; \ - tmp = de; de = hl; hl = tmp; \ -} while(0) - -#define EXX() do { \ - pair32_t tmp; \ - tmp = bc; bc = bc2; bc2 = tmp; \ - tmp = de; de = de2; de2 = tmp; \ - tmp = hl; hl = hl2; hl2 = tmp; \ -} while(0) - -#define EXSP(DR) do { \ - pair32_t tmp; \ - tmp.d = 0; \ - RM16(SPD, &tmp); \ - WM16(SPD, &DR); \ - DR = tmp; \ - WZ = DR.d; \ -} while(0) - -#define ADD16(DR, SR) do { \ - uint32_t res = DR.d + SR.d; \ - WZ = DR.d + 1; \ - F = (F & (SF | ZF | VF)) | (((DR.d ^ res ^ SR.d) >> 8) & HF) | ((res >> 16) & CF) | ((res >> 8) & (YF | XF)); \ - DR.w.l = (uint16_t)res; \ -} while(0) - -#define ADC16(Reg) do { \ - uint32_t res = HLD + Reg.d + (F & CF); \ - WZ = HL + 1; \ - F = (((HLD ^ res ^ Reg.d) >> 8) & HF) | ((res >> 16) & CF) | ((res >> 8) & (SF | YF | XF)) | ((res & 0xffff) ? 0 : ZF) | (((Reg.d ^ HLD ^ 0x8000) & (Reg.d ^ res) & 0x8000) >> 13); \ - HL = (uint16_t)res; \ -} while(0) - -#define SBC16(Reg) do { \ - uint32_t res = HLD - Reg.d - (F & CF); \ - WZ = HL + 1; \ - F = (((HLD ^ res ^ Reg.d) >> 8) & HF) | NF | ((res >> 16) & CF) | ((res >> 8) & (SF | YF | XF)) | ((res & 0xffff) ? 0 : ZF) | (((Reg.d ^ HLD) & (HLD ^ res) &0x8000) >> 13); \ - HL = (uint16_t)res; \ -} while(0) - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::RLC(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x80) ? CF : 0; - res = ((res << 1) | (res >> 7)) & 0xff; - F = SZP[res] | c; - return res; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::RRC(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x01) ? CF : 0; - res = ((res >> 1) | (res << 7)) & 0xff; - F = SZP[res] | c; - return res; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::RL(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x80) ? CF : 0; - res = ((res << 1) | (F & CF)) & 0xff; - F = SZP[res] | c; - return res; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::RR(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x01) ? CF : 0; - res = ((res >> 1) | (F << 7)) & 0xff; - F = SZP[res] | c; - return res; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::SLA(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x80) ? CF : 0; - res = (res << 1) & 0xff; - F = SZP[res] | c; - return res; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::SRA(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x01) ? CF : 0; - res = ((res >> 1) | (res & 0x80)) & 0xff; - F = SZP[res] | c; - return res; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::SLL(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x80) ? CF : 0; - res = ((res << 1) | 0x01) & 0xff; - F = SZP[res] | c; - return res; -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::SRL(uint8_t value) -{ - unsigned res = value; - unsigned c = (res & 0x01) ? CF : 0; - res = (res >> 1) & 0xff; - F = SZP[res] | c; - return res; -} - -#define BIT(bit, reg) do { \ - F = (F & CF) | HF | (SZ_BIT[reg & (1 << bit)] & ~(YF | XF)) | (reg & (YF | XF)); \ -} while(0) - -#define BIT_HL(bit, reg) do { \ - F = (F & CF) | HF | (SZ_BIT[reg & (1 << bit)] & ~(YF | XF)) | (WZ_H & (YF | XF)); \ -} while(0) - -#define BIT_XY(bit, reg) do { \ - F = (F & CF) | HF | (SZ_BIT[reg & (1 << bit)] & ~(YF | XF)) | ((ea >> 8) & (YF | XF)); \ -} while(0) - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::RES(uint8_t bit, uint8_t value) -{ - return value & ~(1 << bit); -} - -Z80_INLINE uint8_t __FASTCALL Z80_BASE::SET(uint8_t bit, uint8_t value) -{ - return value | (1 << bit); -} - -#define LDI() do { \ - uint8_t io = RM8(HL); \ - WM8(DE, io); \ - F &= SF | ZF | CF; \ - if((A + io) & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ - if((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ - HL++; DE++; BC--; \ - if(BC) F |= VF; \ -} while(0) - -#define CPI() do { \ - uint8_t val = RM8(HL); \ - uint8_t res = A - val; \ - WZ++; \ - HL++; BC--; \ - F = (F & CF) | (SZ[res] & ~(YF | XF)) | ((A ^ val ^ res) & HF) | NF; \ - if(F & HF) res -= 1; \ - if(res & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ - if(res & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ - if(BC) F |= VF; \ -} while(0) - -#define INI() do { \ - unsigned t; \ - uint8_t io = IN8(BC); \ - WZ = BC + 1; \ - B--; \ - WM8(HL, io); \ - HL++; \ - F = SZ[B]; \ - t = (unsigned)((C + 1) & 0xff) + (unsigned)io; \ - if(io & SF) F |= NF; \ - if(t & 0x100) F |= HF | CF; \ - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ -} while(0) - -#define OUTI() do { \ - unsigned t; \ - uint8_t io = RM8(HL); \ - B--; \ - WZ = BC + 1; \ - OUT8(BC, io); \ - HL++; \ - F = SZ[B]; \ - t = (unsigned)L + (unsigned)io; \ - if(io & SF) F |= NF; \ - if(t & 0x100) F |= HF | CF; \ - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ -} while(0) - -#define LDD() do { \ - uint8_t io = RM8(HL); \ - WM8(DE, io); \ - F &= SF | ZF | CF; \ - if((A + io) & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ - if((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ - HL--; DE--; BC--; \ - if(BC) F |= VF; \ -} while(0) - -#define CPD() do { \ - uint8_t val = RM8(HL); \ - uint8_t res = A - val; \ - WZ--; \ - HL--; BC--; \ - F = (F & CF) | (SZ[res] & ~(YF | XF)) | ((A ^ val ^ res) & HF) | NF; \ - if(F & HF) res -= 1; \ - if(res & 0x02) F |= YF; /* bit 1 -> flag 5 */ \ - if(res & 0x08) F |= XF; /* bit 3 -> flag 3 */ \ - if(BC) F |= VF; \ -} while(0) - -#define IND() do { \ - unsigned t; \ - uint8_t io = IN8(BC); \ - WZ = BC - 1; \ - B--; \ - WM8(HL, io); \ - HL--; \ - F = SZ[B]; \ - t = ((unsigned)(C - 1) & 0xff) + (unsigned)io; \ - if(io & SF) F |= NF; \ - if(t & 0x100) F |= HF | CF; \ - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ -} while(0) - -#define OUTD() do { \ - unsigned t; \ - uint8_t io = RM8(HL); \ - B--; \ - WZ = BC - 1; \ - OUT8(BC, io); \ - HL--; \ - F = SZ[B]; \ - t = (unsigned)L + (unsigned)io; \ - if(io & SF) F |= NF; \ - if(t & 0x100) F |= HF | CF; \ - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; \ -} while(0) - -#define LDIR() do { \ - LDI(); \ - if(BC != 0) { \ - PC -= 2; \ - WZ = PC + 1; \ - icount -= cc_ex[0xb0]; \ - } \ -} while(0) - -#define CPIR() do { \ - CPI(); \ - if(BC != 0 && !(F & ZF)) { \ - PC -= 2; \ - WZ = PC + 1; \ - icount -= cc_ex[0xb1]; \ - } \ -} while(0) - -#define INIR() do { \ - INI(); \ - if(B != 0) { \ - PC -= 2; \ - icount -= cc_ex[0xb2]; \ - } \ -} while(0) - -#define OTIR() do { \ - OUTI(); \ - if(B != 0) { \ - PC -= 2; \ - icount -= cc_ex[0xb3]; \ - } \ -} while(0) - -#define LDDR() do { \ - LDD(); \ - if(BC != 0) { \ - PC -= 2; \ - WZ = PC + 1; \ - icount -= cc_ex[0xb8]; \ - } \ -} while(0) - -#define CPDR() do { \ - CPD(); \ - if(BC != 0 && !(F & ZF)) { \ - PC -= 2; \ - WZ = PC + 1; \ - icount -= cc_ex[0xb9]; \ - } \ -} while(0) - -#define INDR() do { \ - IND(); \ - if(B != 0) { \ - PC -= 2; \ - icount -= cc_ex[0xba]; \ - } \ -} while(0) - -#define OTDR() do { \ - OUTD(); \ - if(B != 0) { \ - PC -= 2; \ - icount -= cc_ex[0xbb]; \ - } \ -} while(0) - -#define EI() do { \ - iff1 = iff2 = 1; \ - after_ei = true; \ -} while(0) - -void Z80_BASE::OP_CB(uint8_t code) -{ - icount -= cc_cb[code]; - - switch(code) { - case 0x00: B = RLC(B); break; /* RLC B */ - case 0x01: C = RLC(C); break; /* RLC C */ - case 0x02: D = RLC(D); break; /* RLC D */ - case 0x03: E = RLC(E); break; /* RLC E */ - case 0x04: H = RLC(H); break; /* RLC H */ - case 0x05: L = RLC(L); break; /* RLC L */ - case 0x06: WM8(HL, RLC(RM8(HL))); break; /* RLC (HL) */ - case 0x07: A = RLC(A); break; /* RLC A */ - case 0x08: B = RRC(B); break; /* RRC B */ - case 0x09: C = RRC(C); break; /* RRC C */ - case 0x0a: D = RRC(D); break; /* RRC D */ - case 0x0b: E = RRC(E); break; /* RRC E */ - case 0x0c: H = RRC(H); break; /* RRC H */ - case 0x0d: L = RRC(L); break; /* RRC L */ - case 0x0e: WM8(HL, RRC(RM8(HL))); break; /* RRC (HL) */ - case 0x0f: A = RRC(A); break; /* RRC A */ - case 0x10: B = RL(B); break; /* RL B */ - case 0x11: C = RL(C); break; /* RL C */ - case 0x12: D = RL(D); break; /* RL D */ - case 0x13: E = RL(E); break; /* RL E */ - case 0x14: H = RL(H); break; /* RL H */ - case 0x15: L = RL(L); break; /* RL L */ - case 0x16: WM8(HL, RL(RM8(HL))); break; /* RL (HL) */ - case 0x17: A = RL(A); break; /* RL A */ - case 0x18: B = RR(B); break; /* RR B */ - case 0x19: C = RR(C); break; /* RR C */ - case 0x1a: D = RR(D); break; /* RR D */ - case 0x1b: E = RR(E); break; /* RR E */ - case 0x1c: H = RR(H); break; /* RR H */ - case 0x1d: L = RR(L); break; /* RR L */ - case 0x1e: WM8(HL, RR(RM8(HL))); break; /* RR (HL) */ - case 0x1f: A = RR(A); break; /* RR A */ - case 0x20: B = SLA(B); break; /* SLA B */ - case 0x21: C = SLA(C); break; /* SLA C */ - case 0x22: D = SLA(D); break; /* SLA D */ - case 0x23: E = SLA(E); break; /* SLA E */ - case 0x24: H = SLA(H); break; /* SLA H */ - case 0x25: L = SLA(L); break; /* SLA L */ - case 0x26: WM8(HL, SLA(RM8(HL))); break; /* SLA (HL) */ - case 0x27: A = SLA(A); break; /* SLA A */ - case 0x28: B = SRA(B); break; /* SRA B */ - case 0x29: C = SRA(C); break; /* SRA C */ - case 0x2a: D = SRA(D); break; /* SRA D */ - case 0x2b: E = SRA(E); break; /* SRA E */ - case 0x2c: H = SRA(H); break; /* SRA H */ - case 0x2d: L = SRA(L); break; /* SRA L */ - case 0x2e: WM8(HL, SRA(RM8(HL))); break; /* SRA (HL) */ - case 0x2f: A = SRA(A); break; /* SRA A */ - case 0x30: B = SLL(B); break; /* SLL B */ - case 0x31: C = SLL(C); break; /* SLL C */ - case 0x32: D = SLL(D); break; /* SLL D */ - case 0x33: E = SLL(E); break; /* SLL E */ - case 0x34: H = SLL(H); break; /* SLL H */ - case 0x35: L = SLL(L); break; /* SLL L */ - case 0x36: WM8(HL, SLL(RM8(HL))); break; /* SLL (HL) */ - case 0x37: A = SLL(A); break; /* SLL A */ - case 0x38: B = SRL(B); break; /* SRL B */ - case 0x39: C = SRL(C); break; /* SRL C */ - case 0x3a: D = SRL(D); break; /* SRL D */ - case 0x3b: E = SRL(E); break; /* SRL E */ - case 0x3c: H = SRL(H); break; /* SRL H */ - case 0x3d: L = SRL(L); break; /* SRL L */ - case 0x3e: WM8(HL, SRL(RM8(HL))); break; /* SRL (HL) */ - case 0x3f: A = SRL(A); break; /* SRL A */ - case 0x40: BIT(0, B); break; /* BIT 0,B */ - case 0x41: BIT(0, C); break; /* BIT 0,C */ - case 0x42: BIT(0, D); break; /* BIT 0,D */ - case 0x43: BIT(0, E); break; /* BIT 0,E */ - case 0x44: BIT(0, H); break; /* BIT 0,H */ - case 0x45: BIT(0, L); break; /* BIT 0,L */ - case 0x46: BIT_HL(0, RM8(HL)); break; /* BIT 0,(HL) */ - case 0x47: BIT(0, A); break; /* BIT 0,A */ - case 0x48: BIT(1, B); break; /* BIT 1,B */ - case 0x49: BIT(1, C); break; /* BIT 1,C */ - case 0x4a: BIT(1, D); break; /* BIT 1,D */ - case 0x4b: BIT(1, E); break; /* BIT 1,E */ - case 0x4c: BIT(1, H); break; /* BIT 1,H */ - case 0x4d: BIT(1, L); break; /* BIT 1,L */ - case 0x4e: BIT_HL(1, RM8(HL)); break; /* BIT 1,(HL) */ - case 0x4f: BIT(1, A); break; /* BIT 1,A */ - case 0x50: BIT(2, B); break; /* BIT 2,B */ - case 0x51: BIT(2, C); break; /* BIT 2,C */ - case 0x52: BIT(2, D); break; /* BIT 2,D */ - case 0x53: BIT(2, E); break; /* BIT 2,E */ - case 0x54: BIT(2, H); break; /* BIT 2,H */ - case 0x55: BIT(2, L); break; /* BIT 2,L */ - case 0x56: BIT_HL(2, RM8(HL)); break; /* BIT 2,(HL) */ - case 0x57: BIT(2, A); break; /* BIT 2,A */ - case 0x58: BIT(3, B); break; /* BIT 3,B */ - case 0x59: BIT(3, C); break; /* BIT 3,C */ - case 0x5a: BIT(3, D); break; /* BIT 3,D */ - case 0x5b: BIT(3, E); break; /* BIT 3,E */ - case 0x5c: BIT(3, H); break; /* BIT 3,H */ - case 0x5d: BIT(3, L); break; /* BIT 3,L */ - case 0x5e: BIT_HL(3, RM8(HL)); break; /* BIT 3,(HL) */ - case 0x5f: BIT(3, A); break; /* BIT 3,A */ - case 0x60: BIT(4, B); break; /* BIT 4,B */ - case 0x61: BIT(4, C); break; /* BIT 4,C */ - case 0x62: BIT(4, D); break; /* BIT 4,D */ - case 0x63: BIT(4, E); break; /* BIT 4,E */ - case 0x64: BIT(4, H); break; /* BIT 4,H */ - case 0x65: BIT(4, L); break; /* BIT 4,L */ - case 0x66: BIT_HL(4, RM8(HL)); break; /* BIT 4,(HL) */ - case 0x67: BIT(4, A); break; /* BIT 4,A */ - case 0x68: BIT(5, B); break; /* BIT 5,B */ - case 0x69: BIT(5, C); break; /* BIT 5,C */ - case 0x6a: BIT(5, D); break; /* BIT 5,D */ - case 0x6b: BIT(5, E); break; /* BIT 5,E */ - case 0x6c: BIT(5, H); break; /* BIT 5,H */ - case 0x6d: BIT(5, L); break; /* BIT 5,L */ - case 0x6e: BIT_HL(5, RM8(HL)); break; /* BIT 5,(HL) */ - case 0x6f: BIT(5, A); break; /* BIT 5,A */ - case 0x70: BIT(6, B); break; /* BIT 6,B */ - case 0x71: BIT(6, C); break; /* BIT 6,C */ - case 0x72: BIT(6, D); break; /* BIT 6,D */ - case 0x73: BIT(6, E); break; /* BIT 6,E */ - case 0x74: BIT(6, H); break; /* BIT 6,H */ - case 0x75: BIT(6, L); break; /* BIT 6,L */ - case 0x76: BIT_HL(6, RM8(HL)); break; /* BIT 6,(HL) */ - case 0x77: BIT(6, A); break; /* BIT 6,A */ - case 0x78: BIT(7, B); break; /* BIT 7,B */ - case 0x79: BIT(7, C); break; /* BIT 7,C */ - case 0x7a: BIT(7, D); break; /* BIT 7,D */ - case 0x7b: BIT(7, E); break; /* BIT 7,E */ - case 0x7c: BIT(7, H); break; /* BIT 7,H */ - case 0x7d: BIT(7, L); break; /* BIT 7,L */ - case 0x7e: BIT_HL(7, RM8(HL)); break; /* BIT 7,(HL) */ - case 0x7f: BIT(7, A); break; /* BIT 7,A */ - case 0x80: B = RES(0, B); break; /* RES 0,B */ - case 0x81: C = RES(0, C); break; /* RES 0,C */ - case 0x82: D = RES(0, D); break; /* RES 0,D */ - case 0x83: E = RES(0, E); break; /* RES 0,E */ - case 0x84: H = RES(0, H); break; /* RES 0,H */ - case 0x85: L = RES(0, L); break; /* RES 0,L */ - case 0x86: WM8(HL, RES(0, RM8(HL))); break; /* RES 0,(HL) */ - case 0x87: A = RES(0, A); break; /* RES 0,A */ - case 0x88: B = RES(1, B); break; /* RES 1,B */ - case 0x89: C = RES(1, C); break; /* RES 1,C */ - case 0x8a: D = RES(1, D); break; /* RES 1,D */ - case 0x8b: E = RES(1, E); break; /* RES 1,E */ - case 0x8c: H = RES(1, H); break; /* RES 1,H */ - case 0x8d: L = RES(1, L); break; /* RES 1,L */ - case 0x8e: WM8(HL, RES(1, RM8(HL))); break; /* RES 1,(HL) */ - case 0x8f: A = RES(1, A); break; /* RES 1,A */ - case 0x90: B = RES(2, B); break; /* RES 2,B */ - case 0x91: C = RES(2, C); break; /* RES 2,C */ - case 0x92: D = RES(2, D); break; /* RES 2,D */ - case 0x93: E = RES(2, E); break; /* RES 2,E */ - case 0x94: H = RES(2, H); break; /* RES 2,H */ - case 0x95: L = RES(2, L); break; /* RES 2,L */ - case 0x96: WM8(HL, RES(2, RM8(HL))); break; /* RES 2,(HL) */ - case 0x97: A = RES(2, A); break; /* RES 2,A */ - case 0x98: B = RES(3, B); break; /* RES 3,B */ - case 0x99: C = RES(3, C); break; /* RES 3,C */ - case 0x9a: D = RES(3, D); break; /* RES 3,D */ - case 0x9b: E = RES(3, E); break; /* RES 3,E */ - case 0x9c: H = RES(3, H); break; /* RES 3,H */ - case 0x9d: L = RES(3, L); break; /* RES 3,L */ - case 0x9e: WM8(HL, RES(3, RM8(HL))); break; /* RES 3,(HL) */ - case 0x9f: A = RES(3, A); break; /* RES 3,A */ - case 0xa0: B = RES(4, B); break; /* RES 4,B */ - case 0xa1: C = RES(4, C); break; /* RES 4,C */ - case 0xa2: D = RES(4, D); break; /* RES 4,D */ - case 0xa3: E = RES(4, E); break; /* RES 4,E */ - case 0xa4: H = RES(4, H); break; /* RES 4,H */ - case 0xa5: L = RES(4, L); break; /* RES 4,L */ - case 0xa6: WM8(HL, RES(4, RM8(HL))); break; /* RES 4,(HL) */ - case 0xa7: A = RES(4, A); break; /* RES 4,A */ - case 0xa8: B = RES(5, B); break; /* RES 5,B */ - case 0xa9: C = RES(5, C); break; /* RES 5,C */ - case 0xaa: D = RES(5, D); break; /* RES 5,D */ - case 0xab: E = RES(5, E); break; /* RES 5,E */ - case 0xac: H = RES(5, H); break; /* RES 5,H */ - case 0xad: L = RES(5, L); break; /* RES 5,L */ - case 0xae: WM8(HL, RES(5, RM8(HL))); break; /* RES 5,(HL) */ - case 0xaf: A = RES(5, A); break; /* RES 5,A */ - case 0xb0: B = RES(6, B); break; /* RES 6,B */ - case 0xb1: C = RES(6, C); break; /* RES 6,C */ - case 0xb2: D = RES(6, D); break; /* RES 6,D */ - case 0xb3: E = RES(6, E); break; /* RES 6,E */ - case 0xb4: H = RES(6, H); break; /* RES 6,H */ - case 0xb5: L = RES(6, L); break; /* RES 6,L */ - case 0xb6: WM8(HL, RES(6, RM8(HL))); break; /* RES 6,(HL) */ - case 0xb7: A = RES(6, A); break; /* RES 6,A */ - case 0xb8: B = RES(7, B); break; /* RES 7,B */ - case 0xb9: C = RES(7, C); break; /* RES 7,C */ - case 0xba: D = RES(7, D); break; /* RES 7,D */ - case 0xbb: E = RES(7, E); break; /* RES 7,E */ - case 0xbc: H = RES(7, H); break; /* RES 7,H */ - case 0xbd: L = RES(7, L); break; /* RES 7,L */ - case 0xbe: WM8(HL, RES(7, RM8(HL))); break; /* RES 7,(HL) */ - case 0xbf: A = RES(7, A); break; /* RES 7,A */ - case 0xc0: B = SET(0, B); break; /* SET 0,B */ - case 0xc1: C = SET(0, C); break; /* SET 0,C */ - case 0xc2: D = SET(0, D); break; /* SET 0,D */ - case 0xc3: E = SET(0, E); break; /* SET 0,E */ - case 0xc4: H = SET(0, H); break; /* SET 0,H */ - case 0xc5: L = SET(0, L); break; /* SET 0,L */ - case 0xc6: WM8(HL, SET(0, RM8(HL))); break; /* SET 0,(HL) */ - case 0xc7: A = SET(0, A); break; /* SET 0,A */ - case 0xc8: B = SET(1, B); break; /* SET 1,B */ - case 0xc9: C = SET(1, C); break; /* SET 1,C */ - case 0xca: D = SET(1, D); break; /* SET 1,D */ - case 0xcb: E = SET(1, E); break; /* SET 1,E */ - case 0xcc: H = SET(1, H); break; /* SET 1,H */ - case 0xcd: L = SET(1, L); break; /* SET 1,L */ - case 0xce: WM8(HL, SET(1, RM8(HL))); break; /* SET 1,(HL) */ - case 0xcf: A = SET(1, A); break; /* SET 1,A */ - case 0xd0: B = SET(2, B); break; /* SET 2,B */ - case 0xd1: C = SET(2, C); break; /* SET 2,C */ - case 0xd2: D = SET(2, D); break; /* SET 2,D */ - case 0xd3: E = SET(2, E); break; /* SET 2,E */ - case 0xd4: H = SET(2, H); break; /* SET 2,H */ - case 0xd5: L = SET(2, L); break; /* SET 2,L */ - case 0xd6: WM8(HL, SET(2, RM8(HL))); break; /* SET 2,(HL) */ - case 0xd7: A = SET(2, A); break; /* SET 2,A */ - case 0xd8: B = SET(3, B); break; /* SET 3,B */ - case 0xd9: C = SET(3, C); break; /* SET 3,C */ - case 0xda: D = SET(3, D); break; /* SET 3,D */ - case 0xdb: E = SET(3, E); break; /* SET 3,E */ - case 0xdc: H = SET(3, H); break; /* SET 3,H */ - case 0xdd: L = SET(3, L); break; /* SET 3,L */ - case 0xde: WM8(HL, SET(3, RM8(HL))); break; /* SET 3,(HL) */ - case 0xdf: A = SET(3, A); break; /* SET 3,A */ - case 0xe0: B = SET(4, B); break; /* SET 4,B */ - case 0xe1: C = SET(4, C); break; /* SET 4,C */ - case 0xe2: D = SET(4, D); break; /* SET 4,D */ - case 0xe3: E = SET(4, E); break; /* SET 4,E */ - case 0xe4: H = SET(4, H); break; /* SET 4,H */ - case 0xe5: L = SET(4, L); break; /* SET 4,L */ - case 0xe6: WM8(HL, SET(4, RM8(HL))); break; /* SET 4,(HL) */ - case 0xe7: A = SET(4, A); break; /* SET 4,A */ - case 0xe8: B = SET(5, B); break; /* SET 5,B */ - case 0xe9: C = SET(5, C); break; /* SET 5,C */ - case 0xea: D = SET(5, D); break; /* SET 5,D */ - case 0xeb: E = SET(5, E); break; /* SET 5,E */ - case 0xec: H = SET(5, H); break; /* SET 5,H */ - case 0xed: L = SET(5, L); break; /* SET 5,L */ - case 0xee: WM8(HL, SET(5, RM8(HL))); break; /* SET 5,(HL) */ - case 0xef: A = SET(5, A); break; /* SET 5,A */ - case 0xf0: B = SET(6, B); break; /* SET 6,B */ - case 0xf1: C = SET(6, C); break; /* SET 6,C */ - case 0xf2: D = SET(6, D); break; /* SET 6,D */ - case 0xf3: E = SET(6, E); break; /* SET 6,E */ - case 0xf4: H = SET(6, H); break; /* SET 6,H */ - case 0xf5: L = SET(6, L); break; /* SET 6,L */ - case 0xf6: WM8(HL, SET(6, RM8(HL))); break; /* SET 6,(HL) */ - case 0xf7: A = SET(6, A); break; /* SET 6,A */ - case 0xf8: B = SET(7, B); break; /* SET 7,B */ - case 0xf9: C = SET(7, C); break; /* SET 7,C */ - case 0xfa: D = SET(7, D); break; /* SET 7,D */ - case 0xfb: E = SET(7, E); break; /* SET 7,E */ - case 0xfc: H = SET(7, H); break; /* SET 7,H */ - case 0xfd: L = SET(7, L); break; /* SET 7,L */ - case 0xfe: WM8(HL, SET(7, RM8(HL))); break; /* SET 7,(HL) */ - case 0xff: A = SET(7, A); break; /* SET 7,A */ -#if defined(_MSC_VER) && (_MSC_VER >= 1200) - default: __assume(0); -#endif - } -} - -void Z80_BASE::OP_XY(uint8_t code) -{ - icount -= cc_xycb[code]; - - switch(code) { - case 0x00: B = RLC(RM8(ea)); WM8(ea, B); break; /* RLC B=(XY+o) */ - case 0x01: C = RLC(RM8(ea)); WM8(ea, C); break; /* RLC C=(XY+o) */ - case 0x02: D = RLC(RM8(ea)); WM8(ea, D); break; /* RLC D=(XY+o) */ - case 0x03: E = RLC(RM8(ea)); WM8(ea, E); break; /* RLC E=(XY+o) */ - case 0x04: H = RLC(RM8(ea)); WM8(ea, H); break; /* RLC H=(XY+o) */ - case 0x05: L = RLC(RM8(ea)); WM8(ea, L); break; /* RLC L=(XY+o) */ - case 0x06: WM8(ea, RLC(RM8(ea))); break; /* RLC (XY+o) */ - case 0x07: A = RLC(RM8(ea)); WM8(ea, A); break; /* RLC A=(XY+o) */ - case 0x08: B = RRC(RM8(ea)); WM8(ea, B); break; /* RRC B=(XY+o) */ - case 0x09: C = RRC(RM8(ea)); WM8(ea, C); break; /* RRC C=(XY+o) */ - case 0x0a: D = RRC(RM8(ea)); WM8(ea, D); break; /* RRC D=(XY+o) */ - case 0x0b: E = RRC(RM8(ea)); WM8(ea, E); break; /* RRC E=(XY+o) */ - case 0x0c: H = RRC(RM8(ea)); WM8(ea, H); break; /* RRC H=(XY+o) */ - case 0x0d: L = RRC(RM8(ea)); WM8(ea, L); break; /* RRC L=(XY+o) */ - case 0x0e: WM8(ea, RRC(RM8(ea))); break; /* RRC (XY+o) */ - case 0x0f: A = RRC(RM8(ea)); WM8(ea, A); break; /* RRC A=(XY+o) */ - case 0x10: B = RL(RM8(ea)); WM8(ea, B); break; /* RL B=(XY+o) */ - case 0x11: C = RL(RM8(ea)); WM8(ea, C); break; /* RL C=(XY+o) */ - case 0x12: D = RL(RM8(ea)); WM8(ea, D); break; /* RL D=(XY+o) */ - case 0x13: E = RL(RM8(ea)); WM8(ea, E); break; /* RL E=(XY+o) */ - case 0x14: H = RL(RM8(ea)); WM8(ea, H); break; /* RL H=(XY+o) */ - case 0x15: L = RL(RM8(ea)); WM8(ea, L); break; /* RL L=(XY+o) */ - case 0x16: WM8(ea, RL(RM8(ea))); break; /* RL (XY+o) */ - case 0x17: A = RL(RM8(ea)); WM8(ea, A); break; /* RL A=(XY+o) */ - case 0x18: B = RR(RM8(ea)); WM8(ea, B); break; /* RR B=(XY+o) */ - case 0x19: C = RR(RM8(ea)); WM8(ea, C); break; /* RR C=(XY+o) */ - case 0x1a: D = RR(RM8(ea)); WM8(ea, D); break; /* RR D=(XY+o) */ - case 0x1b: E = RR(RM8(ea)); WM8(ea, E); break; /* RR E=(XY+o) */ - case 0x1c: H = RR(RM8(ea)); WM8(ea, H); break; /* RR H=(XY+o) */ - case 0x1d: L = RR(RM8(ea)); WM8(ea, L); break; /* RR L=(XY+o) */ - case 0x1e: WM8(ea, RR(RM8(ea))); break; /* RR (XY+o) */ - case 0x1f: A = RR(RM8(ea)); WM8(ea, A); break; /* RR A=(XY+o) */ - case 0x20: B = SLA(RM8(ea)); WM8(ea, B); break; /* SLA B=(XY+o) */ - case 0x21: C = SLA(RM8(ea)); WM8(ea, C); break; /* SLA C=(XY+o) */ - case 0x22: D = SLA(RM8(ea)); WM8(ea, D); break; /* SLA D=(XY+o) */ - case 0x23: E = SLA(RM8(ea)); WM8(ea, E); break; /* SLA E=(XY+o) */ - case 0x24: H = SLA(RM8(ea)); WM8(ea, H); break; /* SLA H=(XY+o) */ - case 0x25: L = SLA(RM8(ea)); WM8(ea, L); break; /* SLA L=(XY+o) */ - case 0x26: WM8(ea, SLA(RM8(ea))); break; /* SLA (XY+o) */ - case 0x27: A = SLA(RM8(ea)); WM8(ea, A); break; /* SLA A=(XY+o) */ - case 0x28: B = SRA(RM8(ea)); WM8(ea, B); break; /* SRA B=(XY+o) */ - case 0x29: C = SRA(RM8(ea)); WM8(ea, C); break; /* SRA C=(XY+o) */ - case 0x2a: D = SRA(RM8(ea)); WM8(ea, D); break; /* SRA D=(XY+o) */ - case 0x2b: E = SRA(RM8(ea)); WM8(ea, E); break; /* SRA E=(XY+o) */ - case 0x2c: H = SRA(RM8(ea)); WM8(ea, H); break; /* SRA H=(XY+o) */ - case 0x2d: L = SRA(RM8(ea)); WM8(ea, L); break; /* SRA L=(XY+o) */ - case 0x2e: WM8(ea, SRA(RM8(ea))); break; /* SRA (XY+o) */ - case 0x2f: A = SRA(RM8(ea)); WM8(ea, A); break; /* SRA A=(XY+o) */ - case 0x30: B = SLL(RM8(ea)); WM8(ea, B); break; /* SLL B=(XY+o) */ - case 0x31: C = SLL(RM8(ea)); WM8(ea, C); break; /* SLL C=(XY+o) */ - case 0x32: D = SLL(RM8(ea)); WM8(ea, D); break; /* SLL D=(XY+o) */ - case 0x33: E = SLL(RM8(ea)); WM8(ea, E); break; /* SLL E=(XY+o) */ - case 0x34: H = SLL(RM8(ea)); WM8(ea, H); break; /* SLL H=(XY+o) */ - case 0x35: L = SLL(RM8(ea)); WM8(ea, L); break; /* SLL L=(XY+o) */ - case 0x36: WM8(ea, SLL(RM8(ea))); break; /* SLL (XY+o) */ - case 0x37: A = SLL(RM8(ea)); WM8(ea, A); break; /* SLL A=(XY+o) */ - case 0x38: B = SRL(RM8(ea)); WM8(ea, B); break; /* SRL B=(XY+o) */ - case 0x39: C = SRL(RM8(ea)); WM8(ea, C); break; /* SRL C=(XY+o) */ - case 0x3a: D = SRL(RM8(ea)); WM8(ea, D); break; /* SRL D=(XY+o) */ - case 0x3b: E = SRL(RM8(ea)); WM8(ea, E); break; /* SRL E=(XY+o) */ - case 0x3c: H = SRL(RM8(ea)); WM8(ea, H); break; /* SRL H=(XY+o) */ - case 0x3d: L = SRL(RM8(ea)); WM8(ea, L); break; /* SRL L=(XY+o) */ - case 0x3e: WM8(ea, SRL(RM8(ea))); break; /* SRL (XY+o) */ - case 0x3f: A = SRL(RM8(ea)); WM8(ea, A); break; /* SRL A=(XY+o) */ - case 0x40: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x41: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x42: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x43: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x44: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x45: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x46: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x47: BIT_XY(0, RM8(ea)); break; /* BIT 0,(XY+o) */ - case 0x48: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x49: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x4a: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x4b: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x4c: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x4d: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x4e: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x4f: BIT_XY(1, RM8(ea)); break; /* BIT 1,(XY+o) */ - case 0x50: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x51: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x52: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x53: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x54: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x55: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x56: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x57: BIT_XY(2, RM8(ea)); break; /* BIT 2,(XY+o) */ - case 0x58: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x59: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x5a: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x5b: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x5c: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x5d: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x5e: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x5f: BIT_XY(3, RM8(ea)); break; /* BIT 3,(XY+o) */ - case 0x60: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x61: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x62: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x63: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x64: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x65: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x66: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x67: BIT_XY(4, RM8(ea)); break; /* BIT 4,(XY+o) */ - case 0x68: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x69: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x6a: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x6b: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x6c: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x6d: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x6e: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x6f: BIT_XY(5, RM8(ea)); break; /* BIT 5,(XY+o) */ - case 0x70: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x71: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x72: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x73: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x74: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x75: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x76: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x77: BIT_XY(6, RM8(ea)); break; /* BIT 6,(XY+o) */ - case 0x78: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x79: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x7a: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x7b: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x7c: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x7d: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x7e: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x7f: BIT_XY(7, RM8(ea)); break; /* BIT 7,(XY+o) */ - case 0x80: B = RES(0, RM8(ea)); WM8(ea, B); break; /* RES 0,B=(XY+o) */ - case 0x81: C = RES(0, RM8(ea)); WM8(ea, C); break; /* RES 0,C=(XY+o) */ - case 0x82: D = RES(0, RM8(ea)); WM8(ea, D); break; /* RES 0,D=(XY+o) */ - case 0x83: E = RES(0, RM8(ea)); WM8(ea, E); break; /* RES 0,E=(XY+o) */ - case 0x84: H = RES(0, RM8(ea)); WM8(ea, H); break; /* RES 0,H=(XY+o) */ - case 0x85: L = RES(0, RM8(ea)); WM8(ea, L); break; /* RES 0,L=(XY+o) */ - case 0x86: WM8(ea, RES(0, RM8(ea))); break; /* RES 0,(XY+o) */ - case 0x87: A = RES(0, RM8(ea)); WM8(ea, A); break; /* RES 0,A=(XY+o) */ - case 0x88: B = RES(1, RM8(ea)); WM8(ea, B); break; /* RES 1,B=(XY+o) */ - case 0x89: C = RES(1, RM8(ea)); WM8(ea, C); break; /* RES 1,C=(XY+o) */ - case 0x8a: D = RES(1, RM8(ea)); WM8(ea, D); break; /* RES 1,D=(XY+o) */ - case 0x8b: E = RES(1, RM8(ea)); WM8(ea, E); break; /* RES 1,E=(XY+o) */ - case 0x8c: H = RES(1, RM8(ea)); WM8(ea, H); break; /* RES 1,H=(XY+o) */ - case 0x8d: L = RES(1, RM8(ea)); WM8(ea, L); break; /* RES 1,L=(XY+o) */ - case 0x8e: WM8(ea, RES(1, RM8(ea))); break; /* RES 1,(XY+o) */ - case 0x8f: A = RES(1, RM8(ea)); WM8(ea, A); break; /* RES 1,A=(XY+o) */ - case 0x90: B = RES(2, RM8(ea)); WM8(ea, B); break; /* RES 2,B=(XY+o) */ - case 0x91: C = RES(2, RM8(ea)); WM8(ea, C); break; /* RES 2,C=(XY+o) */ - case 0x92: D = RES(2, RM8(ea)); WM8(ea, D); break; /* RES 2,D=(XY+o) */ - case 0x93: E = RES(2, RM8(ea)); WM8(ea, E); break; /* RES 2,E=(XY+o) */ - case 0x94: H = RES(2, RM8(ea)); WM8(ea, H); break; /* RES 2,H=(XY+o) */ - case 0x95: L = RES(2, RM8(ea)); WM8(ea, L); break; /* RES 2,L=(XY+o) */ - case 0x96: WM8(ea, RES(2, RM8(ea))); break; /* RES 2,(XY+o) */ - case 0x97: A = RES(2, RM8(ea)); WM8(ea, A); break; /* RES 2,A=(XY+o) */ - case 0x98: B = RES(3, RM8(ea)); WM8(ea, B); break; /* RES 3,B=(XY+o) */ - case 0x99: C = RES(3, RM8(ea)); WM8(ea, C); break; /* RES 3,C=(XY+o) */ - case 0x9a: D = RES(3, RM8(ea)); WM8(ea, D); break; /* RES 3,D=(XY+o) */ - case 0x9b: E = RES(3, RM8(ea)); WM8(ea, E); break; /* RES 3,E=(XY+o) */ - case 0x9c: H = RES(3, RM8(ea)); WM8(ea, H); break; /* RES 3,H=(XY+o) */ - case 0x9d: L = RES(3, RM8(ea)); WM8(ea, L); break; /* RES 3,L=(XY+o) */ - case 0x9e: WM8(ea, RES(3, RM8(ea))); break; /* RES 3,(XY+o) */ - case 0x9f: A = RES(3, RM8(ea)); WM8(ea, A); break; /* RES 3,A=(XY+o) */ - case 0xa0: B = RES(4, RM8(ea)); WM8(ea, B); break; /* RES 4,B=(XY+o) */ - case 0xa1: C = RES(4, RM8(ea)); WM8(ea, C); break; /* RES 4,C=(XY+o) */ - case 0xa2: D = RES(4, RM8(ea)); WM8(ea, D); break; /* RES 4,D=(XY+o) */ - case 0xa3: E = RES(4, RM8(ea)); WM8(ea, E); break; /* RES 4,E=(XY+o) */ - case 0xa4: H = RES(4, RM8(ea)); WM8(ea, H); break; /* RES 4,H=(XY+o) */ - case 0xa5: L = RES(4, RM8(ea)); WM8(ea, L); break; /* RES 4,L=(XY+o) */ - case 0xa6: WM8(ea, RES(4, RM8(ea))); break; /* RES 4,(XY+o) */ - case 0xa7: A = RES(4, RM8(ea)); WM8(ea, A); break; /* RES 4,A=(XY+o) */ - case 0xa8: B = RES(5, RM8(ea)); WM8(ea, B); break; /* RES 5,B=(XY+o) */ - case 0xa9: C = RES(5, RM8(ea)); WM8(ea, C); break; /* RES 5,C=(XY+o) */ - case 0xaa: D = RES(5, RM8(ea)); WM8(ea, D); break; /* RES 5,D=(XY+o) */ - case 0xab: E = RES(5, RM8(ea)); WM8(ea, E); break; /* RES 5,E=(XY+o) */ - case 0xac: H = RES(5, RM8(ea)); WM8(ea, H); break; /* RES 5,H=(XY+o) */ - case 0xad: L = RES(5, RM8(ea)); WM8(ea, L); break; /* RES 5,L=(XY+o) */ - case 0xae: WM8(ea, RES(5, RM8(ea))); break; /* RES 5,(XY+o) */ - case 0xaf: A = RES(5, RM8(ea)); WM8(ea, A); break; /* RES 5,A=(XY+o) */ - case 0xb0: B = RES(6, RM8(ea)); WM8(ea, B); break; /* RES 6,B=(XY+o) */ - case 0xb1: C = RES(6, RM8(ea)); WM8(ea, C); break; /* RES 6,C=(XY+o) */ - case 0xb2: D = RES(6, RM8(ea)); WM8(ea, D); break; /* RES 6,D=(XY+o) */ - case 0xb3: E = RES(6, RM8(ea)); WM8(ea, E); break; /* RES 6,E=(XY+o) */ - case 0xb4: H = RES(6, RM8(ea)); WM8(ea, H); break; /* RES 6,H=(XY+o) */ - case 0xb5: L = RES(6, RM8(ea)); WM8(ea, L); break; /* RES 6,L=(XY+o) */ - case 0xb6: WM8(ea, RES(6, RM8(ea))); break; /* RES 6,(XY+o) */ - case 0xb7: A = RES(6, RM8(ea)); WM8(ea, A); break; /* RES 6,A=(XY+o) */ - case 0xb8: B = RES(7, RM8(ea)); WM8(ea, B); break; /* RES 7,B=(XY+o) */ - case 0xb9: C = RES(7, RM8(ea)); WM8(ea, C); break; /* RES 7,C=(XY+o) */ - case 0xba: D = RES(7, RM8(ea)); WM8(ea, D); break; /* RES 7,D=(XY+o) */ - case 0xbb: E = RES(7, RM8(ea)); WM8(ea, E); break; /* RES 7,E=(XY+o) */ - case 0xbc: H = RES(7, RM8(ea)); WM8(ea, H); break; /* RES 7,H=(XY+o) */ - case 0xbd: L = RES(7, RM8(ea)); WM8(ea, L); break; /* RES 7,L=(XY+o) */ - case 0xbe: WM8(ea, RES(7, RM8(ea))); break; /* RES 7,(XY+o) */ - case 0xbf: A = RES(7, RM8(ea)); WM8(ea, A); break; /* RES 7,A=(XY+o) */ - case 0xc0: B = SET(0, RM8(ea)); WM8(ea, B); break; /* SET 0,B=(XY+o) */ - case 0xc1: C = SET(0, RM8(ea)); WM8(ea, C); break; /* SET 0,C=(XY+o) */ - case 0xc2: D = SET(0, RM8(ea)); WM8(ea, D); break; /* SET 0,D=(XY+o) */ - case 0xc3: E = SET(0, RM8(ea)); WM8(ea, E); break; /* SET 0,E=(XY+o) */ - case 0xc4: H = SET(0, RM8(ea)); WM8(ea, H); break; /* SET 0,H=(XY+o) */ - case 0xc5: L = SET(0, RM8(ea)); WM8(ea, L); break; /* SET 0,L=(XY+o) */ - case 0xc6: WM8(ea, SET(0, RM8(ea))); break; /* SET 0,(XY+o) */ - case 0xc7: A = SET(0, RM8(ea)); WM8(ea, A); break; /* SET 0,A=(XY+o) */ - case 0xc8: B = SET(1, RM8(ea)); WM8(ea, B); break; /* SET 1,B=(XY+o) */ - case 0xc9: C = SET(1, RM8(ea)); WM8(ea, C); break; /* SET 1,C=(XY+o) */ - case 0xca: D = SET(1, RM8(ea)); WM8(ea, D); break; /* SET 1,D=(XY+o) */ - case 0xcb: E = SET(1, RM8(ea)); WM8(ea, E); break; /* SET 1,E=(XY+o) */ - case 0xcc: H = SET(1, RM8(ea)); WM8(ea, H); break; /* SET 1,H=(XY+o) */ - case 0xcd: L = SET(1, RM8(ea)); WM8(ea, L); break; /* SET 1,L=(XY+o) */ - case 0xce: WM8(ea, SET(1, RM8(ea))); break; /* SET 1,(XY+o) */ - case 0xcf: A = SET(1, RM8(ea)); WM8(ea, A); break; /* SET 1,A=(XY+o) */ - case 0xd0: B = SET(2, RM8(ea)); WM8(ea, B); break; /* SET 2,B=(XY+o) */ - case 0xd1: C = SET(2, RM8(ea)); WM8(ea, C); break; /* SET 2,C=(XY+o) */ - case 0xd2: D = SET(2, RM8(ea)); WM8(ea, D); break; /* SET 2,D=(XY+o) */ - case 0xd3: E = SET(2, RM8(ea)); WM8(ea, E); break; /* SET 2,E=(XY+o) */ - case 0xd4: H = SET(2, RM8(ea)); WM8(ea, H); break; /* SET 2,H=(XY+o) */ - case 0xd5: L = SET(2, RM8(ea)); WM8(ea, L); break; /* SET 2,L=(XY+o) */ - case 0xd6: WM8(ea, SET(2, RM8(ea))); break; /* SET 2,(XY+o) */ - case 0xd7: A = SET(2, RM8(ea)); WM8(ea, A); break; /* SET 2,A=(XY+o) */ - case 0xd8: B = SET(3, RM8(ea)); WM8(ea, B); break; /* SET 3,B=(XY+o) */ - case 0xd9: C = SET(3, RM8(ea)); WM8(ea, C); break; /* SET 3,C=(XY+o) */ - case 0xda: D = SET(3, RM8(ea)); WM8(ea, D); break; /* SET 3,D=(XY+o) */ - case 0xdb: E = SET(3, RM8(ea)); WM8(ea, E); break; /* SET 3,E=(XY+o) */ - case 0xdc: H = SET(3, RM8(ea)); WM8(ea, H); break; /* SET 3,H=(XY+o) */ - case 0xdd: L = SET(3, RM8(ea)); WM8(ea, L); break; /* SET 3,L=(XY+o) */ - case 0xde: WM8(ea, SET(3, RM8(ea))); break; /* SET 3,(XY+o) */ - case 0xdf: A = SET(3, RM8(ea)); WM8(ea, A); break; /* SET 3,A=(XY+o) */ - case 0xe0: B = SET(4, RM8(ea)); WM8(ea, B); break; /* SET 4,B=(XY+o) */ - case 0xe1: C = SET(4, RM8(ea)); WM8(ea, C); break; /* SET 4,C=(XY+o) */ - case 0xe2: D = SET(4, RM8(ea)); WM8(ea, D); break; /* SET 4,D=(XY+o) */ - case 0xe3: E = SET(4, RM8(ea)); WM8(ea, E); break; /* SET 4,E=(XY+o) */ - case 0xe4: H = SET(4, RM8(ea)); WM8(ea, H); break; /* SET 4,H=(XY+o) */ - case 0xe5: L = SET(4, RM8(ea)); WM8(ea, L); break; /* SET 4,L=(XY+o) */ - case 0xe6: WM8(ea, SET(4, RM8(ea))); break; /* SET 4,(XY+o) */ - case 0xe7: A = SET(4, RM8(ea)); WM8(ea, A); break; /* SET 4,A=(XY+o) */ - case 0xe8: B = SET(5, RM8(ea)); WM8(ea, B); break; /* SET 5,B=(XY+o) */ - case 0xe9: C = SET(5, RM8(ea)); WM8(ea, C); break; /* SET 5,C=(XY+o) */ - case 0xea: D = SET(5, RM8(ea)); WM8(ea, D); break; /* SET 5,D=(XY+o) */ - case 0xeb: E = SET(5, RM8(ea)); WM8(ea, E); break; /* SET 5,E=(XY+o) */ - case 0xec: H = SET(5, RM8(ea)); WM8(ea, H); break; /* SET 5,H=(XY+o) */ - case 0xed: L = SET(5, RM8(ea)); WM8(ea, L); break; /* SET 5,L=(XY+o) */ - case 0xee: WM8(ea, SET(5, RM8(ea))); break; /* SET 5,(XY+o) */ - case 0xef: A = SET(5, RM8(ea)); WM8(ea, A); break; /* SET 5,A=(XY+o) */ - case 0xf0: B = SET(6, RM8(ea)); WM8(ea, B); break; /* SET 6,B=(XY+o) */ - case 0xf1: C = SET(6, RM8(ea)); WM8(ea, C); break; /* SET 6,C=(XY+o) */ - case 0xf2: D = SET(6, RM8(ea)); WM8(ea, D); break; /* SET 6,D=(XY+o) */ - case 0xf3: E = SET(6, RM8(ea)); WM8(ea, E); break; /* SET 6,E=(XY+o) */ - case 0xf4: H = SET(6, RM8(ea)); WM8(ea, H); break; /* SET 6,H=(XY+o) */ - case 0xf5: L = SET(6, RM8(ea)); WM8(ea, L); break; /* SET 6,L=(XY+o) */ - case 0xf6: WM8(ea, SET(6, RM8(ea))); break; /* SET 6,(XY+o) */ - case 0xf7: A = SET(6, RM8(ea)); WM8(ea, A); break; /* SET 6,A=(XY+o) */ - case 0xf8: B = SET(7, RM8(ea)); WM8(ea, B); break; /* SET 7,B=(XY+o) */ - case 0xf9: C = SET(7, RM8(ea)); WM8(ea, C); break; /* SET 7,C=(XY+o) */ - case 0xfa: D = SET(7, RM8(ea)); WM8(ea, D); break; /* SET 7,D=(XY+o) */ - case 0xfb: E = SET(7, RM8(ea)); WM8(ea, E); break; /* SET 7,E=(XY+o) */ - case 0xfc: H = SET(7, RM8(ea)); WM8(ea, H); break; /* SET 7,H=(XY+o) */ - case 0xfd: L = SET(7, RM8(ea)); WM8(ea, L); break; /* SET 7,L=(XY+o) */ - case 0xfe: WM8(ea, SET(7, RM8(ea))); break; /* SET 7,(XY+o) */ - case 0xff: A = SET(7, RM8(ea)); WM8(ea, A); break; /* SET 7,A=(XY+o) */ -#if defined(_MSC_VER) && (_MSC_VER >= 1200) - default: __assume(0); -#endif - } -} - -void Z80_BASE::OP_DD(uint8_t code) -{ - icount -= cc_xy[code]; - - switch(code) { - case 0x09: ADD16(ix, bc); break; /* ADD IX,BC */ - case 0x19: ADD16(ix, de); break; /* ADD IX,DE */ - case 0x21: IX = FETCH16(); break; /* LD IX,w */ - case 0x22: ea = FETCH16(); WM16(ea, &ix); WZ = ea + 1; break; /* LD (w),IX */ - case 0x23: IX++; break; /* INC IX */ - case 0x24: HX = INC(HX); break; /* INC HX */ - case 0x25: HX = DEC(HX); break; /* DEC HX */ - case 0x26: HX = FETCH8(); break; /* LD HX,n */ - case 0x29: ADD16(ix, ix); break; /* ADD IX,IX */ - case 0x2a: ea = FETCH16(); RM16(ea, &ix); WZ = ea + 1; break; /* LD IX,(w) */ - case 0x2b: IX--; break; /* DEC IX */ - case 0x2c: LX = INC(LX); break; /* INC LX */ - case 0x2d: LX = DEC(LX); break; /* DEC LX */ - case 0x2e: LX = FETCH8(); break; /* LD LX,n */ - case 0x34: EAX(); WM8(ea, INC(RM8(ea))); break; /* INC (IX+o) */ - case 0x35: EAX(); WM8(ea, DEC(RM8(ea))); break; /* DEC (IX+o) */ - case 0x36: EAX(); WM8(ea, FETCH8()); break; /* LD (IX+o),n */ - case 0x39: ADD16(ix, sp); break; /* ADD IX,SP */ - case 0x44: B = HX; break; /* LD B,HX */ - case 0x45: B = LX; break; /* LD B,LX */ - case 0x46: EAX(); B = RM8(ea); break; /* LD B,(IX+o) */ - case 0x4c: C = HX; break; /* LD C,HX */ - case 0x4d: C = LX; break; /* LD C,LX */ - case 0x4e: EAX(); C = RM8(ea); break; /* LD C,(IX+o) */ - case 0x54: D = HX; break; /* LD D,HX */ - case 0x55: D = LX; break; /* LD D,LX */ - case 0x56: EAX(); D = RM8(ea); break; /* LD D,(IX+o) */ - case 0x5c: E = HX; break; /* LD E,HX */ - case 0x5d: E = LX; break; /* LD E,LX */ - case 0x5e: EAX(); E = RM8(ea); break; /* LD E,(IX+o) */ - case 0x60: HX = B; break; /* LD HX,B */ - case 0x61: HX = C; break; /* LD HX,C */ - case 0x62: HX = D; break; /* LD HX,D */ - case 0x63: HX = E; break; /* LD HX,E */ - case 0x64: break; /* LD HX,HX */ - case 0x65: HX = LX; break; /* LD HX,LX */ - case 0x66: EAX(); H = RM8(ea); break; /* LD H,(IX+o) */ - case 0x67: HX = A; break; /* LD HX,A */ - case 0x68: LX = B; break; /* LD LX,B */ - case 0x69: LX = C; break; /* LD LX,C */ - case 0x6a: LX = D; break; /* LD LX,D */ - case 0x6b: LX = E; break; /* LD LX,E */ - case 0x6c: LX = HX; break; /* LD LX,HX */ - case 0x6d: break; /* LD LX,LX */ - case 0x6e: EAX(); L = RM8(ea); break; /* LD L,(IX+o) */ - case 0x6f: LX = A; break; /* LD LX,A */ - case 0x70: EAX(); WM8(ea, B); break; /* LD (IX+o),B */ - case 0x71: EAX(); WM8(ea, C); break; /* LD (IX+o),C */ - case 0x72: EAX(); WM8(ea, D); break; /* LD (IX+o),D */ - case 0x73: EAX(); WM8(ea, E); break; /* LD (IX+o),E */ - case 0x74: EAX(); WM8(ea, H); break; /* LD (IX+o),H */ - case 0x75: EAX(); WM8(ea, L); break; /* LD (IX+o),L */ - case 0x77: EAX(); WM8(ea, A); break; /* LD (IX+o),A */ - case 0x7c: A = HX; break; /* LD A,HX */ - case 0x7d: A = LX; break; /* LD A,LX */ - case 0x7e: EAX(); A = RM8(ea); break; /* LD A,(IX+o) */ - case 0x84: ADD(HX); break; /* ADD A,HX */ - case 0x85: ADD(LX); break; /* ADD A,LX */ - case 0x86: EAX(); ADD(RM8(ea)); break; /* ADD A,(IX+o) */ - case 0x8c: ADC(HX); break; /* ADC A,HX */ - case 0x8d: ADC(LX); break; /* ADC A,LX */ - case 0x8e: EAX(); ADC(RM8(ea)); break; /* ADC A,(IX+o) */ - case 0x94: SUB(HX); break; /* SUB HX */ - case 0x95: SUB(LX); break; /* SUB LX */ - case 0x96: EAX(); SUB(RM8(ea)); break; /* SUB (IX+o) */ - case 0x9c: SBC(HX); break; /* SBC A,HX */ - case 0x9d: SBC(LX); break; /* SBC A,LX */ - case 0x9e: EAX(); SBC(RM8(ea)); break; /* SBC A,(IX+o) */ - case 0xa4: AND(HX); break; /* AND HX */ - case 0xa5: AND(LX); break; /* AND LX */ - case 0xa6: EAX(); AND(RM8(ea)); break; /* AND (IX+o) */ - case 0xac: XOR(HX); break; /* XOR HX */ - case 0xad: XOR(LX); break; /* XOR LX */ - case 0xae: EAX(); XOR(RM8(ea)); break; /* XOR (IX+o) */ - case 0xb4: OR(HX); break; /* OR HX */ - case 0xb5: OR(LX); break; /* OR LX */ - case 0xb6: EAX(); OR(RM8(ea)); break; /* OR (IX+o) */ - case 0xbc: CP(HX); break; /* CP HX */ - case 0xbd: CP(LX); break; /* CP LX */ - case 0xbe: EAX(); CP(RM8(ea)); break; /* CP (IX+o) */ - case 0xcb: EAX(); OP_XY(FETCH8()); break; /* ** DD CB xx */ - case 0xe1: POP(ix); break; /* POP IX */ - case 0xe3: EXSP(ix); break; /* EX (SP),IX */ - case 0xe5: PUSH(ix); break; /* PUSH IX */ - case 0xe9: PC = IX; break; /* JP (IX) */ - case 0xf9: SP = IX; break; /* LD SP,IX */ - default: OP(code); break; - } -} - -void Z80_BASE::OP_FD(uint8_t code) -{ - icount -= cc_xy[code]; - - switch(code) { - case 0x09: ADD16(iy, bc); break; /* ADD IY,BC */ - case 0x19: ADD16(iy, de); break; /* ADD IY,DE */ - case 0x21: IY = FETCH16(); break; /* LD IY,w */ - case 0x22: ea = FETCH16(); WM16(ea, &iy); WZ = ea + 1; break; /* LD (w),IY */ - case 0x23: IY++; break; /* INC IY */ - case 0x24: HY = INC(HY); break; /* INC HY */ - case 0x25: HY = DEC(HY); break; /* DEC HY */ - case 0x26: HY = FETCH8(); break; /* LD HY,n */ - case 0x29: ADD16(iy, iy); break; /* ADD IY,IY */ - case 0x2a: ea = FETCH16(); RM16(ea, &iy); WZ = ea + 1; break; /* LD IY,(w) */ - case 0x2b: IY--; break; /* DEC IY */ - case 0x2c: LY = INC(LY); break; /* INC LY */ - case 0x2d: LY = DEC(LY); break; /* DEC LY */ - case 0x2e: LY = FETCH8(); break; /* LD LY,n */ - case 0x34: EAY(); WM8(ea, INC(RM8(ea))); break; /* INC (IY+o) */ - case 0x35: EAY(); WM8(ea, DEC(RM8(ea))); break; /* DEC (IY+o) */ - case 0x36: EAY(); WM8(ea, FETCH8()); break; /* LD (IY+o),n */ - case 0x39: ADD16(iy, sp); break; /* ADD IY,SP */ - case 0x44: B = HY; break; /* LD B,HY */ - case 0x45: B = LY; break; /* LD B,LY */ - case 0x46: EAY(); B = RM8(ea); break; /* LD B,(IY+o) */ - case 0x4c: C = HY; break; /* LD C,HY */ - case 0x4d: C = LY; break; /* LD C,LY */ - case 0x4e: EAY(); C = RM8(ea); break; /* LD C,(IY+o) */ - case 0x54: D = HY; break; /* LD D,HY */ - case 0x55: D = LY; break; /* LD D,LY */ - case 0x56: EAY(); D = RM8(ea); break; /* LD D,(IY+o) */ - case 0x5c: E = HY; break; /* LD E,HY */ - case 0x5d: E = LY; break; /* LD E,LY */ - case 0x5e: EAY(); E = RM8(ea); break; /* LD E,(IY+o) */ - case 0x60: HY = B; break; /* LD HY,B */ - case 0x61: HY = C; break; /* LD HY,C */ - case 0x62: HY = D; break; /* LD HY,D */ - case 0x63: HY = E; break; /* LD HY,E */ - case 0x64: break; /* LD HY,HY */ - case 0x65: HY = LY; break; /* LD HY,LY */ - case 0x66: EAY(); H = RM8(ea); break; /* LD H,(IY+o) */ - case 0x67: HY = A; break; /* LD HY,A */ - case 0x68: LY = B; break; /* LD LY,B */ - case 0x69: LY = C; break; /* LD LY,C */ - case 0x6a: LY = D; break; /* LD LY,D */ - case 0x6b: LY = E; break; /* LD LY,E */ - case 0x6c: LY = HY; break; /* LD LY,HY */ - case 0x6d: break; /* LD LY,LY */ - case 0x6e: EAY(); L = RM8(ea); break; /* LD L,(IY+o) */ - case 0x6f: LY = A; break; /* LD LY,A */ - case 0x70: EAY(); WM8(ea, B); break; /* LD (IY+o),B */ - case 0x71: EAY(); WM8(ea, C); break; /* LD (IY+o),C */ - case 0x72: EAY(); WM8(ea, D); break; /* LD (IY+o),D */ - case 0x73: EAY(); WM8(ea, E); break; /* LD (IY+o),E */ - case 0x74: EAY(); WM8(ea, H); break; /* LD (IY+o),H */ - case 0x75: EAY(); WM8(ea, L); break; /* LD (IY+o),L */ - case 0x77: EAY(); WM8(ea, A); break; /* LD (IY+o),A */ - case 0x7c: A = HY; break; /* LD A,HY */ - case 0x7d: A = LY; break; /* LD A,LY */ - case 0x7e: EAY(); A = RM8(ea); break; /* LD A,(IY+o) */ - case 0x84: ADD(HY); break; /* ADD A,HY */ - case 0x85: ADD(LY); break; /* ADD A,LY */ - case 0x86: EAY(); ADD(RM8(ea)); break; /* ADD A,(IY+o) */ - case 0x8c: ADC(HY); break; /* ADC A,HY */ - case 0x8d: ADC(LY); break; /* ADC A,LY */ - case 0x8e: EAY(); ADC(RM8(ea)); break; /* ADC A,(IY+o) */ - case 0x94: SUB(HY); break; /* SUB HY */ - case 0x95: SUB(LY); break; /* SUB LY */ - case 0x96: EAY(); SUB(RM8(ea)); break; /* SUB (IY+o) */ - case 0x9c: SBC(HY); break; /* SBC A,HY */ - case 0x9d: SBC(LY); break; /* SBC A,LY */ - case 0x9e: EAY(); SBC(RM8(ea)); break; /* SBC A,(IY+o) */ - case 0xa4: AND(HY); break; /* AND HY */ - case 0xa5: AND(LY); break; /* AND LY */ - case 0xa6: EAY(); AND(RM8(ea)); break; /* AND (IY+o) */ - case 0xac: XOR(HY); break; /* XOR HY */ - case 0xad: XOR(LY); break; /* XOR LY */ - case 0xae: EAY(); XOR(RM8(ea)); break; /* XOR (IY+o) */ - case 0xb4: OR(HY); break; /* OR HY */ - case 0xb5: OR(LY); break; /* OR LY */ - case 0xb6: EAY(); OR(RM8(ea)); break; /* OR (IY+o) */ - case 0xbc: CP(HY); break; /* CP HY */ - case 0xbd: CP(LY); break; /* CP LY */ - case 0xbe: EAY(); CP(RM8(ea)); break; /* CP (IY+o) */ - case 0xcb: EAY(); OP_XY(FETCH8()); break; /* ** FD CB xx */ - case 0xe1: POP(iy); break; /* POP IY */ - case 0xe3: EXSP(iy); break; /* EX (SP),IY */ - case 0xe5: PUSH(iy); break; /* PUSH IY */ - case 0xe9: PC = IY; break; /* JP (IY) */ - case 0xf9: SP = IY; break; /* LD SP,IY */ - default: OP(code); break; - } -} - -void Z80_BASE::OP_ED(uint8_t code) -{ - icount -= cc_ed[code]; - - switch(code) { - case 0x40: B = IN8(BC); F = (F & CF) | SZP[B]; break; /* IN B,(C) */ - case 0x41: OUT8(BC, B); break; /* OUT (C),B */ - case 0x42: SBC16(bc); break; /* SBC HL,BC */ - case 0x43: ea = FETCH16(); WM16(ea, &bc); WZ = ea + 1; break; /* LD (w),BC */ - case 0x44: NEG(); break; /* NEG */ - case 0x45: RETN(); break; /* RETN */ - case 0x46: im = 0; break; /* im 0 */ - case 0x47: LD_I_A(); break; /* LD i,A */ - case 0x48: C = IN8(BC); F = (F & CF) | SZP[C]; break; /* IN C,(C) */ - case 0x49: OUT8(BC, C); break; /* OUT (C),C */ - case 0x4a: ADC16(bc); break; /* ADC HL,BC */ - case 0x4b: ea = FETCH16(); RM16(ea, &bc); WZ = ea + 1; break; /* LD BC,(w) */ - case 0x4c: NEG(); break; /* NEG */ - case 0x4d: RETI(); break; /* RETI */ - case 0x4e: im = 0; break; /* im 0 */ - case 0x4f: LD_R_A(); break; /* LD r,A */ - case 0x50: D = IN8(BC); F = (F & CF) | SZP[D]; break; /* IN D,(C) */ - case 0x51: OUT8(BC, D); break; /* OUT (C),D */ - case 0x52: SBC16(de); break; /* SBC HL,DE */ - case 0x53: ea = FETCH16(); WM16(ea, &de); WZ = ea + 1; break; /* LD (w),DE */ - case 0x54: NEG(); break; /* NEG */ - case 0x55: RETN(); break; /* RETN */ - case 0x56: im = 1; break; /* im 1 */ - case 0x57: LD_A_I(); break; /* LD A,i */ - case 0x58: E = IN8(BC); F = (F & CF) | SZP[E]; break; /* IN E,(C) */ - case 0x59: OUT8(BC, E); break; /* OUT (C),E */ - case 0x5a: ADC16(de); break; /* ADC HL,DE */ - case 0x5b: ea = FETCH16(); RM16(ea, &de); WZ = ea + 1; break; /* LD DE,(w) */ - case 0x5c: NEG(); break; /* NEG */ - case 0x5d: RETI(); break; /* RETI */ - case 0x5e: im = 2; break; /* im 2 */ - case 0x5f: LD_A_R(); break; /* LD A,r */ - case 0x60: H = IN8(BC); F = (F & CF) | SZP[H]; break; /* IN H,(C) */ - case 0x61: OUT8(BC, H); break; /* OUT (C),H */ - case 0x62: SBC16(hl); break; /* SBC HL,HL */ - case 0x63: ea = FETCH16(); WM16(ea, &hl); WZ = ea + 1; break; /* LD (w),HL */ - case 0x64: NEG(); break; /* NEG */ - case 0x65: RETN(); break; /* RETN */ - case 0x66: im = 0; break; /* im 0 */ - case 0x67: RRD(); break; /* RRD (HL) */ - case 0x68: L = IN8(BC); F = (F & CF) | SZP[L]; break; /* IN L,(C) */ - case 0x69: OUT8(BC, L); break; /* OUT (C),L */ - case 0x6a: ADC16(hl); break; /* ADC HL,HL */ - case 0x6b: ea = FETCH16(); RM16(ea, &hl); WZ = ea + 1; break; /* LD HL,(w) */ - case 0x6c: NEG(); break; /* NEG */ - case 0x6d: RETI(); break; /* RETI */ - case 0x6e: im = 0; break; /* im 0 */ - case 0x6f: RLD(); break; /* RLD (HL) */ - case 0x70: {uint8_t res = IN8(BC); F = (F & CF) | SZP[res];} break; /* IN F,(C) */ - case 0x71: OUT8(BC, 0); break; /* OUT (C),0 */ - case 0x72: SBC16(sp); break; /* SBC HL,SP */ - case 0x73: ea = FETCH16(); WM16(ea, &sp); WZ = ea + 1; break; /* LD (w),SP */ - case 0x74: NEG(); break; /* NEG */ - case 0x75: RETN(); break; /* RETN */ - case 0x76: im = 1; break; /* im 1 */ - case 0x78: A = IN8(BC); F = (F & CF) | SZP[A]; WZ = BC + 1; break; /* IN A,(C) */ - case 0x79: OUT8(BC, A); WZ = BC + 1; break; /* OUT (C),A */ - case 0x7a: ADC16(sp); break; /* ADC HL,SP */ - case 0x7b: ea = FETCH16(); RM16(ea, &sp); WZ = ea + 1; break; /* LD SP,(w) */ - case 0x7c: NEG(); break; /* NEG */ - case 0x7d: RETI(); break; /* RETI */ - case 0x7e: im = 2; break; /* im 2 */ - case 0xa0: LDI(); break; /* LDI */ - case 0xa1: CPI(); break; /* CPI */ - case 0xa2: INI(); break; /* INI */ - case 0xa3: OUTI(); break; /* OUTI */ - case 0xa8: LDD(); break; /* LDD */ - case 0xa9: CPD(); break; /* CPD */ - case 0xaa: IND(); break; /* IND */ - case 0xab: OUTD(); break; /* OUTD */ - case 0xb0: LDIR(); break; /* LDIR */ - case 0xb1: CPIR(); break; /* CPIR */ - case 0xb2: INIR(); break; /* INIR */ - case 0xb3: OTIR(); break; /* OTIR */ - case 0xb8: LDDR(); break; /* LDDR */ - case 0xb9: CPDR(); break; /* CPDR */ - case 0xba: INDR(); break; /* INDR */ - case 0xbb: OTDR(); break; /* OTDR */ - default: OP(code); break; - } -} - -void Z80_BASE::OP(uint8_t code) -{ - prevpc = PC - 1; - icount -= cc_op[code]; - - switch(code) { - case 0x00: break; /* NOP */ - case 0x01: BC = FETCH16(); break; /* LD BC,w */ - case 0x02: WM8(BC, A); WZ_L = (BC + 1) & 0xff; WZ_H = A; break; /* LD (BC),A */ - case 0x03: BC++; break; /* INC BC */ - case 0x04: B = INC(B); break; /* INC B */ - case 0x05: B = DEC(B); break; /* DEC B */ - case 0x06: B = FETCH8(); break; /* LD B,n */ - case 0x07: RLCA(); break; /* RLCA */ - case 0x08: EX_AF(); break; /* EX AF,AF' */ - case 0x09: ADD16(hl, bc); break; /* ADD HL,BC */ - case 0x0a: A = RM8(BC); WZ = BC+1; break; /* LD A,(BC) */ - case 0x0b: BC--; break; /* DEC BC */ - case 0x0c: C = INC(C); break; /* INC C */ - case 0x0d: C = DEC(C); break; /* DEC C */ - case 0x0e: C = FETCH8(); break; /* LD C,n */ - case 0x0f: RRCA(); break; /* RRCA */ - case 0x10: B--; JR_COND(B, 0x10); break; /* DJNZ o */ - case 0x11: DE = FETCH16(); break; /* LD DE,w */ - case 0x12: WM8(DE, A); WZ_L = (DE + 1) & 0xff; WZ_H = A; break; /* LD (DE),A */ - case 0x13: DE++; break; /* INC DE */ - case 0x14: D = INC(D); break; /* INC D */ - case 0x15: D = DEC(D); break; /* DEC D */ - case 0x16: D = FETCH8(); break; /* LD D,n */ - case 0x17: RLA(); break; /* RLA */ - case 0x18: JR(); break; /* JR o */ - case 0x19: ADD16(hl, de); break; /* ADD HL,DE */ - case 0x1a: A = RM8(DE); WZ = DE + 1; break; /* LD A,(DE) */ - case 0x1b: DE--; break; /* DEC DE */ - case 0x1c: E = INC(E); break; /* INC E */ - case 0x1d: E = DEC(E); break; /* DEC E */ - case 0x1e: E = FETCH8(); break; /* LD E,n */ - case 0x1f: RRA(); break; /* RRA */ - case 0x20: JR_COND(!(F & ZF), 0x20); break; /* JR NZ,o */ - case 0x21: HL = FETCH16(); break; /* LD HL,w */ - case 0x22: ea = FETCH16(); WM16(ea, &hl); WZ = ea + 1; break; /* LD (w),HL */ - case 0x23: HL++; break; /* INC HL */ - case 0x24: H = INC(H); break; /* INC H */ - case 0x25: H = DEC(H); break; /* DEC H */ - case 0x26: H = FETCH8(); break; /* LD H,n */ - case 0x27: DAA(); break; /* DAA */ - case 0x28: JR_COND(F & ZF, 0x28); break; /* JR Z,o */ - case 0x29: ADD16(hl, hl); break; /* ADD HL,HL */ - case 0x2a: ea = FETCH16(); RM16(ea, &hl); WZ = ea + 1; break; /* LD HL,(w) */ - case 0x2b: HL--; break; /* DEC HL */ - case 0x2c: L = INC(L); break; /* INC L */ - case 0x2d: L = DEC(L); break; /* DEC L */ - case 0x2e: L = FETCH8(); break; /* LD L,n */ - case 0x2f: A ^= 0xff; F = (F & (SF | ZF | PF | CF)) | HF | NF | (A & (YF | XF)); break; /* CPL */ - case 0x30: JR_COND(!(F & CF), 0x30); break; /* JR NC,o */ - case 0x31: SP = FETCH16(); break; /* LD SP,w */ - case 0x32: ea = FETCH16(); WM8(ea, A); WZ_L = (ea + 1) & 0xff; WZ_H = A; break; /* LD (w),A */ - case 0x33: SP++; break; /* INC SP */ - case 0x34: WM8(HL, INC(RM8(HL))); break; /* INC (HL) */ - case 0x35: WM8(HL, DEC(RM8(HL))); break; /* DEC (HL) */ - case 0x36: WM8(HL, FETCH8()); break; /* LD (HL),n */ - case 0x37: F = (F & (SF | ZF | YF | XF | PF)) | CF | (A & (YF | XF)); break; /* SCF */ - case 0x38: JR_COND(F & CF, 0x38); break; /* JR C,o */ - case 0x39: ADD16(hl, sp); break; /* ADD HL,SP */ - case 0x3a: ea = FETCH16(); A = RM8(ea); WZ = ea + 1; break; /* LD A,(w) */ - case 0x3b: SP--; break; /* DEC SP */ - case 0x3c: A = INC(A); break; /* INC A */ - case 0x3d: A = DEC(A); break; /* DEC A */ - case 0x3e: A = FETCH8(); break; /* LD A,n */ - case 0x3f: F = ((F & (SF | ZF | YF | XF | PF | CF)) | ((F & CF) << 4) | (A & (YF | XF))) ^ CF; break; /* CCF */ - case 0x40: break; /* LD B,B */ - case 0x41: B = C; break; /* LD B,C */ - case 0x42: B = D; break; /* LD B,D */ - case 0x43: B = E; break; /* LD B,E */ - case 0x44: B = H; break; /* LD B,H */ - case 0x45: B = L; break; /* LD B,L */ - case 0x46: B = RM8(HL); break; /* LD B,(HL) */ - case 0x47: B = A; break; /* LD B,A */ - case 0x48: C = B; break; /* LD C,B */ - case 0x49: break; /* LD C,C */ - case 0x4a: C = D; break; /* LD C,D */ - case 0x4b: C = E; break; /* LD C,E */ - case 0x4c: C = H; break; /* LD C,H */ - case 0x4d: C = L; break; /* LD C,L */ - case 0x4e: C = RM8(HL); break; /* LD C,(HL) */ - case 0x4f: C = A; break; /* LD C,A */ - case 0x50: D = B; break; /* LD D,B */ - case 0x51: D = C; break; /* LD D,C */ - case 0x52: break; /* LD D,D */ - case 0x53: D = E; break; /* LD D,E */ - case 0x54: D = H; break; /* LD D,H */ - case 0x55: D = L; break; /* LD D,L */ - case 0x56: D = RM8(HL); break; /* LD D,(HL) */ - case 0x57: D = A; break; /* LD D,A */ - case 0x58: E = B; break; /* LD E,B */ - case 0x59: E = C; break; /* LD E,C */ - case 0x5a: E = D; break; /* LD E,D */ - case 0x5b: break; /* LD E,E */ - case 0x5c: E = H; break; /* LD E,H */ - case 0x5d: E = L; break; /* LD E,L */ - case 0x5e: E = RM8(HL); break; /* LD E,(HL) */ - case 0x5f: E = A; break; /* LD E,A */ - case 0x60: H = B; break; /* LD H,B */ - case 0x61: H = C; break; /* LD H,C */ - case 0x62: H = D; break; /* LD H,D */ - case 0x63: H = E; break; /* LD H,E */ - case 0x64: break; /* LD H,H */ - case 0x65: H = L; break; /* LD H,L */ - case 0x66: H = RM8(HL); break; /* LD H,(HL) */ - case 0x67: H = A; break; /* LD H,A */ - case 0x68: L = B; break; /* LD L,B */ - case 0x69: L = C; break; /* LD L,C */ - case 0x6a: L = D; break; /* LD L,D */ - case 0x6b: L = E; break; /* LD L,E */ - case 0x6c: L = H; break; /* LD L,H */ - case 0x6d: break; /* LD L,L */ - case 0x6e: L = RM8(HL); break; /* LD L,(HL) */ - case 0x6f: L = A; break; /* LD L,A */ - case 0x70: WM8(HL, B); break; /* LD (HL),B */ - case 0x71: WM8(HL, C); break; /* LD (HL),C */ - case 0x72: WM8(HL, D); break; /* LD (HL),D */ - case 0x73: WM8(HL, E); break; /* LD (HL),E */ - case 0x74: WM8(HL, H); break; /* LD (HL),H */ - case 0x75: WM8(HL, L); break; /* LD (HL),L */ - case 0x76: ENTER_HALT(); break; /* halt */ - case 0x77: WM8(HL, A); break; /* LD (HL),A */ - case 0x78: A = B; break; /* LD A,B */ - case 0x79: A = C; break; /* LD A,C */ - case 0x7a: A = D; break; /* LD A,D */ - case 0x7b: A = E; break; /* LD A,E */ - case 0x7c: A = H; break; /* LD A,H */ - case 0x7d: A = L; break; /* LD A,L */ - case 0x7e: A = RM8(HL); break; /* LD A,(HL) */ - case 0x7f: break; /* LD A,A */ - case 0x80: ADD(B); break; /* ADD A,B */ - case 0x81: ADD(C); break; /* ADD A,C */ - case 0x82: ADD(D); break; /* ADD A,D */ - case 0x83: ADD(E); break; /* ADD A,E */ - case 0x84: ADD(H); break; /* ADD A,H */ - case 0x85: ADD(L); break; /* ADD A,L */ - case 0x86: ADD(RM8(HL)); break; /* ADD A,(HL) */ - case 0x87: ADD(A); break; /* ADD A,A */ - case 0x88: ADC(B); break; /* ADC A,B */ - case 0x89: ADC(C); break; /* ADC A,C */ - case 0x8a: ADC(D); break; /* ADC A,D */ - case 0x8b: ADC(E); break; /* ADC A,E */ - case 0x8c: ADC(H); break; /* ADC A,H */ - case 0x8d: ADC(L); break; /* ADC A,L */ - case 0x8e: ADC(RM8(HL)); break; /* ADC A,(HL) */ - case 0x8f: ADC(A); break; /* ADC A,A */ - case 0x90: SUB(B); break; /* SUB B */ - case 0x91: SUB(C); break; /* SUB C */ - case 0x92: SUB(D); break; /* SUB D */ - case 0x93: SUB(E); break; /* SUB E */ - case 0x94: SUB(H); break; /* SUB H */ - case 0x95: SUB(L); break; /* SUB L */ - case 0x96: SUB(RM8(HL)); break; /* SUB (HL) */ - case 0x97: SUB(A); break; /* SUB A */ - case 0x98: SBC(B); break; /* SBC A,B */ - case 0x99: SBC(C); break; /* SBC A,C */ - case 0x9a: SBC(D); break; /* SBC A,D */ - case 0x9b: SBC(E); break; /* SBC A,E */ - case 0x9c: SBC(H); break; /* SBC A,H */ - case 0x9d: SBC(L); break; /* SBC A,L */ - case 0x9e: SBC(RM8(HL)); break; /* SBC A,(HL) */ - case 0x9f: SBC(A); break; /* SBC A,A */ - case 0xa0: AND(B); break; /* AND B */ - case 0xa1: AND(C); break; /* AND C */ - case 0xa2: AND(D); break; /* AND D */ - case 0xa3: AND(E); break; /* AND E */ - case 0xa4: AND(H); break; /* AND H */ - case 0xa5: AND(L); break; /* AND L */ - case 0xa6: AND(RM8(HL)); break; /* AND (HL) */ - case 0xa7: AND(A); break; /* AND A */ - case 0xa8: XOR(B); break; /* XOR B */ - case 0xa9: XOR(C); break; /* XOR C */ - case 0xaa: XOR(D); break; /* XOR D */ - case 0xab: XOR(E); break; /* XOR E */ - case 0xac: XOR(H); break; /* XOR H */ - case 0xad: XOR(L); break; /* XOR L */ - case 0xae: XOR(RM8(HL)); break; /* XOR (HL) */ - case 0xaf: XOR(A); break; /* XOR A */ - case 0xb0: OR(B); break; /* OR B */ - case 0xb1: OR(C); break; /* OR C */ - case 0xb2: OR(D); break; /* OR D */ - case 0xb3: OR(E); break; /* OR E */ - case 0xb4: OR(H); break; /* OR H */ - case 0xb5: OR(L); break; /* OR L */ - case 0xb6: OR(RM8(HL)); break; /* OR (HL) */ - case 0xb7: OR(A); break; /* OR A */ - case 0xb8: CP(B); break; /* CP B */ - case 0xb9: CP(C); break; /* CP C */ - case 0xba: CP(D); break; /* CP D */ - case 0xbb: CP(E); break; /* CP E */ - case 0xbc: CP(H); break; /* CP H */ - case 0xbd: CP(L); break; /* CP L */ - case 0xbe: CP(RM8(HL)); break; /* CP (HL) */ - case 0xbf: CP(A); break; /* CP A */ - case 0xc0: RET_COND(!(F & ZF), 0xc0); break; /* RET NZ */ - case 0xc1: POP(bc); break; /* POP BC */ - case 0xc2: JP_COND(!(F & ZF)); break; /* JP NZ,a */ - case 0xc3: JP(); break; /* JP a */ - case 0xc4: CALL_COND(!(F & ZF), 0xc4); break; /* CALL NZ,a */ - case 0xc5: PUSH(bc); break; /* PUSH BC */ - case 0xc6: ADD(FETCH8()); break; /* ADD A,n */ - case 0xc7: RST(0x00); break; /* RST 0 */ - case 0xc8: RET_COND(F & ZF, 0xc8); break; /* RET Z */ -//#ifdef Z80_PSEUDO_BIOS - case 0xc9: - if(has_pseudo_bios) { - if(d_bios != NULL) { - d_bios->bios_ret_z80(prevpc, &af, &bc, &de, &hl, &ix, &iy, &iff1); - } - } - POP(pc); WZ = PCD; break; /* RET */ -//#else -// case 0xc9: POP(pc); WZ = PCD; break; /* RET */ -//#endif - case 0xca: JP_COND(F & ZF); break; /* JP Z,a */ - case 0xcb: OP_CB(FETCHOP()); break; /* **** CB xx */ - case 0xcc: CALL_COND(F & ZF, 0xcc); break; /* CALL Z,a */ - case 0xcd: CALL(); break; /* CALL a */ - case 0xce: ADC(FETCH8()); break; /* ADC A,n */ - case 0xcf: RST(0x08); break; /* RST 1 */ - case 0xd0: RET_COND(!(F & CF), 0xd0); break; /* RET NC */ - case 0xd1: POP(de); break; /* POP DE */ - case 0xd2: JP_COND(!(F & CF)); break; /* JP NC,a */ - case 0xd3: {unsigned n = FETCH8() | (A << 8); OUT8(n, A); WZ_L = ((n & 0xff) + 1) & 0xff; WZ_H = A;} break; /* OUT (n),A */ - case 0xd4: CALL_COND(!(F & CF), 0xd4); break; /* CALL NC,a */ - case 0xd5: PUSH(de); break; /* PUSH DE */ - case 0xd6: SUB(FETCH8()); break; /* SUB n */ - case 0xd7: RST(0x10); break; /* RST 2 */ - case 0xd8: RET_COND(F & CF, 0xd8); break; /* RET C */ - case 0xd9: EXX(); break; /* EXX */ - case 0xda: JP_COND(F & CF); break; /* JP C,a */ - case 0xdb: {unsigned n = FETCH8() | (A << 8); A = IN8(n); WZ = n + 1;} break; /* IN A,(n) */ - case 0xdc: CALL_COND(F & CF, 0xdc); break; /* CALL C,a */ - case 0xdd: OP_DD(FETCHOP()); break; /* **** DD xx */ - case 0xde: SBC(FETCH8()); break; /* SBC A,n */ - case 0xdf: RST(0x18); break; /* RST 3 */ - case 0xe0: RET_COND(!(F & PF), 0xe0); break; /* RET PO */ - case 0xe1: POP(hl); break; /* POP HL */ - case 0xe2: JP_COND(!(F & PF)); break; /* JP PO,a */ - case 0xe3: EXSP(hl); break; /* EX HL,(SP) */ - case 0xe4: CALL_COND(!(F & PF), 0xe4); break; /* CALL PO,a */ - case 0xe5: PUSH(hl); break; /* PUSH HL */ - case 0xe6: AND(FETCH8()); break; /* AND n */ - case 0xe7: RST(0x20); break; /* RST 4 */ - case 0xe8: RET_COND(F & PF, 0xe8); break; /* RET PE */ - case 0xe9: PC = HL; break; /* JP (HL) */ - case 0xea: JP_COND(F & PF); break; /* JP PE,a */ - case 0xeb: EX_DE_HL(); break; /* EX DE,HL */ - case 0xec: CALL_COND(F & PF, 0xec); break; /* CALL PE,a */ - case 0xed: OP_ED(FETCHOP()); break; /* **** ED xx */ - case 0xee: XOR(FETCH8()); break; /* XOR n */ - case 0xef: RST(0x28); break; /* RST 5 */ - case 0xf0: RET_COND(!(F & SF), 0xf0); break; /* RET P */ - case 0xf1: POP(af); break; /* POP AF */ - case 0xf2: JP_COND(!(F & SF)); break; /* JP P,a */ - case 0xf3: iff1 = iff2 = 0; break; /* DI */ - case 0xf4: CALL_COND(!(F & SF), 0xf4); break; /* CALL P,a */ - case 0xf5: PUSH(af); break; /* PUSH AF */ - case 0xf6: OR(FETCH8()); break; /* OR n */ - case 0xf7: RST(0x30); break; /* RST 6 */ - case 0xf8: RET_COND(F & SF, 0xf8); break; /* RET M */ - case 0xf9: SP = HL; break; /* LD SP,HL */ - case 0xfa: JP_COND(F & SF); break; /* JP M,a */ - case 0xfb: EI(); break; /* EI */ - case 0xfc: CALL_COND(F & SF, 0xfc); break; /* CALL M,a */ - case 0xfd: OP_FD(FETCHOP()); break; /* **** FD xx */ - case 0xfe: CP(FETCH8()); break; /* CP n */ - case 0xff: RST(0x38); break; /* RST 7 */ -#if defined(_MSC_VER) && (_MSC_VER >= 1200) - default: __assume(0); -#endif - } -} - -// main - -void Z80_BASE::initialize() -{ - DEVICE::initialize(); - if(!flags_initialized) { - uint8_t *padd = SZHVC_add; - uint8_t *padc = SZHVC_add + 256 * 256; - uint8_t *psub = SZHVC_sub; - uint8_t *psbc = SZHVC_sub + 256 * 256; - - for(int oldval = 0; oldval < 256; oldval++) { - for(int newval = 0; newval < 256; newval++) { - /* add or adc w/o carry set */ - int val = newval - oldval; - *padd = (newval) ? ((newval & 0x80) ? SF : 0) : ZF; - *padd |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ - if((newval & 0x0f) < (oldval & 0x0f)) *padd |= HF; - if(newval < oldval) *padd |= CF; - if((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padd |= VF; - padd++; - - /* adc with carry set */ - val = newval - oldval - 1; - *padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF; - *padc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ - if((newval & 0x0f) <= (oldval & 0x0f)) *padc |= HF; - if(newval <= oldval) *padc |= CF; - if((val ^ oldval ^ 0x80) & (val ^ newval) & 0x80) *padc |= VF; - padc++; - - /* cp, sub or sbc w/o carry set */ - val = oldval - newval; - *psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF); - *psub |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ - if((newval & 0x0f) > (oldval & 0x0f)) *psub |= HF; - if(newval > oldval) *psub |= CF; - if((val ^ oldval) & (oldval ^ newval) & 0x80) *psub |= VF; - psub++; - - /* sbc with carry set */ - val = oldval - newval - 1; - *psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF); - *psbc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ - if((newval & 0x0f) >= (oldval & 0x0f)) *psbc |= HF; - if(newval >= oldval) *psbc |= CF; - if((val ^ oldval) & (oldval ^ newval) & 0x80) *psbc |= VF; - psbc++; - } - } - for(int i = 0; i < 256; i++) { - int p = 0; - if(i & 0x01) ++p; - if(i & 0x02) ++p; - if(i & 0x04) ++p; - if(i & 0x08) ++p; - if(i & 0x10) ++p; - if(i & 0x20) ++p; - if(i & 0x40) ++p; - if(i & 0x80) ++p; - SZ[i] = i ? i & SF : ZF; - SZ[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ - SZ_BIT[i] = i ? i & SF : ZF | PF; - SZ_BIT[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ - SZP[i] = SZ[i] | ((p & 1) ? 0 : PF); - SZHV_inc[i] = SZ[i]; - if(i == 0x80) SZHV_inc[i] |= VF; - if((i & 0x0f) == 0x00) SZHV_inc[i] |= HF; - SZHV_dec[i] = SZ[i] | NF; - if(i == 0x7f) SZHV_dec[i] |= VF; - if((i & 0x0f) == 0x0f) SZHV_dec[i] |= HF; - } - flags_initialized = true; - } - is_primary = is_primary_cpu(this); - - // Collecting stateus. - cycles_tmp_count = 0; - extra_tmp_count = 0; - insns_count = 0; - frames_count = 0; - nmi_count = 0; - irq_count = 0; - nsc800_int_count = 0; - nsc800_rsta_count = 0; - nsc800_rsta_count = 0; - nsc800_rsta_count = 0; - register_frame_event(this); - -} - -void Z80_BASE::event_frame() -{ - if(frames_count < 0) { - cycles_tmp_count = total_icount; - extra_tmp_count = 0; - insns_count = 0; - frames_count = 0; - nmi_count = 0; - irq_count = 0; - nsc800_int_count = 0; - nsc800_rsta_count = 0; - nsc800_rstb_count = 0; - nsc800_rstc_count = 0; - } else if(frames_count >= 16) { - uint64_t _icount = total_icount - cycles_tmp_count; - if(config.print_statistics) { - if(has_nsc800) { - out_debug_log(_T("INFO: 16 frames done.\nINFO: CLOCKS = %ld INSNS = %d EXTRA_ICOUNT = %d \nINFO: NMI# = %d IRQ# = %d NSC800_INT# = %d RSTA# = %d RSTB# = %d RSTC# = %d"), - _icount, insns_count, extra_tmp_count, nmi_count, irq_count, - nsc800_int_count, nsc800_rsta_count, nsc800_rstb_count, nsc800_rstc_count); - } else { - out_debug_log(_T("INFO: 16 frames done.\nINFO: CLOCKS = %ld INSNS = %d EXTRA_ICOUNT = %d \nINFO: NMI# = %d IRQ# = %d"), _icount, insns_count, extra_tmp_count, nmi_count, irq_count); - } - } - cycles_tmp_count = total_icount; - insns_count = 0; - extra_tmp_count = 0; - frames_count = 0; - nmi_count = 0; - irq_count = 0; - nsc800_int_count = 0; - nsc800_rsta_count = 0; - nsc800_rstb_count = 0; - nsc800_rstc_count = 0; - } else { - frames_count++; - } - -} -void Z80_BASE::reset() -{ - //PCD = CPU_START_ADDR; - PCD = 0; - SPD = 0; - AFD = BCD = DED = HLD = 0; - IXD = IYD = 0xffff; /* IX and IY are FFFF after a reset! */ - F = ZF; /* Zero flag is set */ - I = R = R2 = 0; - WZD = PCD; - af2.d = bc2.d = de2.d = hl2.d = 0; - ea = 0; - - im = iff1 = iff2 = icr = 0; - after_halt = false; - after_ei = after_ldair = false; - intr_req_bit = intr_pend_bit = 0; - - icount = extra_icount = busreq_icount = 0; -} - -void __FASTCALL Z80_BASE::write_signal(int id, uint32_t data, uint32_t mask) -{ - if(id == SIG_CPU_IRQ) { - intr_req_bit = (intr_req_bit & ~mask) | (data & mask); - // always pending (temporary) - intr_pend_bit = (intr_pend_bit & ~mask) | (0xffffffff & mask); - irq_count++; - } else if(id == SIG_CPU_NMI) { - intr_req_bit = (data & mask) ? (intr_req_bit | NMI_REQ_BIT) : (intr_req_bit & ~NMI_REQ_BIT); - nmi_count++; - } else if(id == SIG_CPU_BUSREQ) { - busreq = ((data & mask) != 0); - write_signals(&outputs_busack, busreq ? 0xffffffff : 0); - } else if(has_nsc800) { -//#ifdef HAS_NSC800 - if(id == SIG_NSC800_INT) { - intr_req_bit = (data & mask) ? (intr_req_bit | 1) : (intr_req_bit & ~1); - nsc800_int_count++; - } else if(id == SIG_NSC800_RSTA) { - intr_req_bit = (data & mask) ? (intr_req_bit | 8) : (intr_req_bit & ~8); - nsc800_rsta_count++; - } else if(id == SIG_NSC800_RSTB) { - intr_req_bit = (data & mask) ? (intr_req_bit | 4) : (intr_req_bit & ~4); - nsc800_rstb_count++; - } else if(id == SIG_NSC800_RSTC) { - intr_req_bit = (data & mask) ? (intr_req_bit | 2) : (intr_req_bit & ~2); - nsc800_rstc_count++; - } - } -//#endif -} - -uint32_t __FASTCALL Z80_BASE::read_signal(int id) -{ - if(id == SIG_CPU_IRQ) { - return intr_req_bit; - } - return 0; -} - - -int Z80_BASE::run(int clock) -{ - if(extra_icount > 0) { - extra_tmp_count += extra_icount; - } - if(clock == -1) { - // this is primary cpu - if(busreq) { - // run dma once - //#ifdef SINGLE_MODE_DMA - if(d_dma) { - d_dma->do_dma(); - } - //#endif - // don't run cpu! - int passed_icount = max(1, extra_icount); - // this is main cpu, icount is not used - /*icount = */extra_icount = 0; - return passed_icount; - } else { - // run only one opcode - if((extra_icount += busreq_icount) > 0) { - if(is_primary) { - update_extra_event(extra_icount); - } - total_icount += extra_icount; - } - icount = -extra_icount; - extra_icount = busreq_icount = 0; - run_one_opecode(); - insns_count++; - return -icount; - } - } else { - icount += clock; - int first_icount = icount; - icount -= extra_icount; - extra_icount = 0; - - if(busreq) { - // run dma once - // run dma once - //#ifdef USE_DEBUGGER - debugger_hook(); - //#endif - //#ifdef SINGLE_MODE_DMA - if(d_dma) { - d_dma->do_dma(); - } - //#endif - } else { - // run cpu while given clocks - while(icount > 0 && !busreq) { - run_one_opecode(); - insns_count++; - } - } - // if busreq is raised, spin cpu while remained clock - if(icount > 0 && busreq) { - icount = 0; - } - return first_icount - icount; - } -} - -void __FASTCALL Z80_BASE::debugger_hook(void) -{ -} - -void __FASTCALL Z80_BASE::run_one_opecode() -{ - // rune one opecode - after_ei = after_ldair = false; - OP(FETCHOP()); -#if HAS_LDAIR_QUIRK - if(after_ldair) F &= ~PF; // reset parity flag after LD A,I or LD A,R -#endif - // ei: run next opecode - if(after_ei) { - after_ldair = false; - OP(FETCHOP()); -#if HAS_LDAIR_QUIRK - if(after_ldair) F &= ~PF; // reset parity flag after LD A,I or LD A,R -#endif - if(d_pic != NULL) d_pic->notify_intr_ei(); - } - - // check interrupt - if(intr_req_bit) { - if(intr_req_bit & NMI_REQ_BIT) { - // nmi - LEAVE_HALT(); - PUSH(pc); - PCD = WZD = 0x0066; - icount -= 11; - iff1 = 0; - intr_req_bit &= ~NMI_REQ_BIT; -//#ifdef HAS_NSC800 - } else if(has_nsc800) { - if((intr_req_bit & 1) && (icr & 1)) { - // INTR - LEAVE_HALT(); - PUSH(pc); - if(d_pic != NULL) { // OK? - PCD = WZ = d_pic->get_intr_ack() & 0xffff; - } else { - PCD = WZ = (PCD & 0xff00) | 0xcd; - } - icount -= cc_op[0xcd] + cc_ex[0xff]; - iff1 = iff2 = 0; - intr_req_bit &= ~1; - } else if((intr_req_bit & 8) && (icr & 8)) { - // RSTA - LEAVE_HALT(); - PUSH(pc); - PCD = WZ = 0x003c; - icount -= cc_op[0xff] + cc_ex[0xff]; - iff1 = iff2 = 0; - intr_req_bit &= ~8; - } else if((intr_req_bit & 4) && (icr & 4)) { - // RSTB - LEAVE_HALT(); - PUSH(pc); - PCD = WZ = 0x0034; - icount -= cc_op[0xff] + cc_ex[0xff]; - iff1 = iff2 = 0; - intr_req_bit &= ~4; - } else if((intr_req_bit & 2) && (icr & 2)) { - // RSTC - LEAVE_HALT(); - PUSH(pc); - PCD = WZ = 0x002c; - icount -= cc_op[0xff] + cc_ex[0xff]; - iff1 = iff2 = 0; - intr_req_bit &= ~2; - } - } else { // Normal Z80 - if(iff1) { - // interrupt - LEAVE_HALT(); - - uint32_t vector = 0xcd; // Default - if(d_pic != NULL) vector = d_pic->get_intr_ack(); - if(im == 0) { - // mode 0 (support NOP/JMP/CALL/RST only) - switch(vector & 0xff) { - case 0x00: break; // NOP - case 0xc3: PCD = vector >> 8; break; // JMP - case 0xcd: PUSH(pc); PCD = vector >> 8; break; // CALL - case 0xc7: PUSH(pc); PCD = 0x0000; break; // RST 00H - case 0xcf: PUSH(pc); PCD = 0x0008; break; // RST 08H - case 0xd7: PUSH(pc); PCD = 0x0010; break; // RST 10H - case 0xdf: PUSH(pc); PCD = 0x0018; break; // RST 18H - case 0xe7: PUSH(pc); PCD = 0x0020; break; // RST 20H - case 0xef: PUSH(pc); PCD = 0x0028; break; // RST 28H - case 0xf7: PUSH(pc); PCD = 0x0030; break; // RST 30H - case 0xff: PUSH(pc); PCD = 0x0038; break; // RST 38H - } - icount -= cc_op[vector & 0xff] + cc_ex[0xff]; - } else if(im == 1) { - // mode 1 - PUSH(pc); - PCD = 0x0038; - icount -= cc_op[0xff] + cc_ex[0xff]; - } else { - // mode 2 - PUSH(pc); - RM16((vector & 0xff) | (I << 8), &pc); - icount -= cc_op[0xcd] + cc_ex[0xff]; - } - iff1 = iff2 = 0; - intr_req_bit = 0; - WZ = PCD; - } else { - intr_req_bit &= intr_pend_bit; -//#endif - } -//#else - } - } -//#ifdef SINGLE_MODE_DMA - if(d_dma) { - d_dma->do_dma(); - } -//#endif - icount -= extra_icount; - extra_icount = 0; -} - -//#ifdef USE_DEBUGGER - -bool Z80_BASE::write_debug_reg(const _TCHAR *reg, uint32_t data) -{ - if(_tcsicmp(reg, _T("PC")) == 0) { - PC = data; - } else if(_tcsicmp(reg, _T("SP")) == 0) { - SP = data; - } else if(_tcsicmp(reg, _T("AF")) == 0) { - AF = data; - } else if(_tcsicmp(reg, _T("BC")) == 0) { - BC = data; - } else if(_tcsicmp(reg, _T("DE")) == 0) { - DE = data; - } else if(_tcsicmp(reg, _T("HL")) == 0) { - HL = data; - } else if(_tcsicmp(reg, _T("IX")) == 0) { - IX = data; - } else if(_tcsicmp(reg, _T("IY")) == 0) { - IY = data; - } else if(_tcsicmp(reg, _T("A")) == 0) { - A = data; - } else if(_tcsicmp(reg, _T("F")) == 0) { - F = data; - } else if(_tcsicmp(reg, _T("B")) == 0) { - B = data; - } else if(_tcsicmp(reg, _T("C")) == 0) { - C = data; - } else if(_tcsicmp(reg, _T("D")) == 0) { - D = data; - } else if(_tcsicmp(reg, _T("E")) == 0) { - E = data; - } else if(_tcsicmp(reg, _T("H")) == 0) { - H = data; - } else if(_tcsicmp(reg, _T("L")) == 0) { - L = data; - } else if(_tcsicmp(reg, _T("HX")) == 0 || _tcsicmp(reg, _T("XH")) == 0 || _tcsicmp(reg, _T("IXH")) == 0) { - HX = data; - } else if(_tcsicmp(reg, _T("LX")) == 0 || _tcsicmp(reg, _T("XL")) == 0 || _tcsicmp(reg, _T("IXL")) == 0) { - LX = data; - } else if(_tcsicmp(reg, _T("HY")) == 0 || _tcsicmp(reg, _T("YH")) == 0 || _tcsicmp(reg, _T("IYH")) == 0) { - HY = data; - } else if(_tcsicmp(reg, _T("LX")) == 0 || _tcsicmp(reg, _T("YL")) == 0 || _tcsicmp(reg, _T("IYL")) == 0) { - LY = data; - } else if(_tcsicmp(reg, _T("I")) == 0) { - I = data; - } else if(_tcsicmp(reg, _T("R")) == 0) { - R = data; - } else if(_tcsicmp(reg, _T("AF'")) == 0) { - AF2 = data; - } else if(_tcsicmp(reg, _T("BC'")) == 0) { - BC2 = data; - } else if(_tcsicmp(reg, _T("DE'")) == 0) { - DE2 = data; - } else if(_tcsicmp(reg, _T("HL'")) == 0) { - HL2 = data; - } else if(_tcsicmp(reg, _T("A'")) == 0) { - A2 = data; - } else if(_tcsicmp(reg, _T("F'")) == 0) { - F2 = data; - } else if(_tcsicmp(reg, _T("B'")) == 0) { - B2 = data; - } else if(_tcsicmp(reg, _T("C'")) == 0) { - C2 = data; - } else if(_tcsicmp(reg, _T("D'")) == 0) { - D2 = data; - } else if(_tcsicmp(reg, _T("E'")) == 0) { - E2 = data; - } else if(_tcsicmp(reg, _T("H'")) == 0) { - H2 = data; - } else if(_tcsicmp(reg, _T("L'")) == 0) { - L2 = data; - } else { - return false; - } - return true; -} - -bool Z80_BASE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) -{ -/* -F = [--------] A = 00 BC = 0000 DE = 0000 HL = 0000 IX = 0000 IY = 0000 -F'= [--------] A'= 00 BC'= 0000 DE'= 0000 HL'= 0000 SP = 0000 PC = 0000 - I = 00 R = 00 (BC)= 0000 (DE)= 0000 (HL)= 0000 (SP)= 0000 EI:IFF2=0 -Total CPU Clocks = 0 (0) Since Scanline = 0/0 (0/0) -*/ - int wait; - my_stprintf_s(buffer, buffer_len, - _T("F = [%c%c%c%c%c%c%c%c] A = %02X BC = %04X DE = %04X HL = %04X IX = %04X IY = %04X\n") - _T("F'= [%c%c%c%c%c%c%c%c] A'= %02X BC'= %04X DE'= %04X HL'= %04X SP = %04X PC = %04X\n") - _T(" I = %02X R = %02X (BC)= %04X (DE)= %04X (HL)= %04X (SP)= %04X %cI:IFF2=%d\n") - _T("Clocks = %llu (%llu) Since Scanline = %d/%d (%d/%d)"), - - (F & CF) ? _T('C') : _T('-'), (F & NF) ? _T('N') : _T('-'), (F & PF) ? _T('P') : _T('-'), (F & XF) ? _T('X') : _T('-'), - (F & HF) ? _T('H') : _T('-'), (F & YF) ? _T('Y') : _T('-'), (F & ZF) ? _T('Z') : _T('-'), (F & SF) ? _T('S') : _T('-'), - A, BC, DE, HL, IX, IY, - (F2 & CF) ? _T('C') : _T('-'), (F2 & NF) ? _T('N') : _T('-'), (F2 & PF) ? _T('P') : _T('-'), (F2 & XF) ? _T('X') : _T('-'), - (F2 & HF) ? _T('H') : _T('-'), (F2 & YF) ? _T('Y') : _T('-'), (F2 & ZF) ? _T('Z') : _T('-'), (F2 & SF) ? _T('S') : _T('-'), - A2, BC2, DE2, HL2, SP, PC, - I, R, - d_mem_stored->read_data16w(BC, &wait), d_mem_stored->read_data16w(DE, &wait), d_mem_stored->read_data16w(HL, &wait), d_mem_stored->read_data16w(SP, &wait), - iff1 ? _T('E') : _T('D'), iff2, - total_icount, total_icount - prev_total_icount, - get_passed_clock_since_vline(), get_cur_vline_clocks(), get_cur_vline(), get_lines_per_frame()); - prev_total_icount = total_icount; - return true; -} - -// disassembler - -int Z80_BASE::debug_dasm_with_userdata(uint32_t pc, _TCHAR *buffer, size_t buffer_len, uint32_t userdata ) -{ - return -1; -} - - -extern "C" { -int z80_dasm_main(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); -static void dasm_cb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); -static void dasm_dd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); -static void dasm_ed(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); -static void dasm_fd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); -static void dasm_ddcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); -static void dasm_fdcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol); - -uint8_t z80_dasm_ops[4]; -int z80_dasm_ptr; - -inline uint8_t dasm_fetchop() -{ - return z80_dasm_ops[z80_dasm_ptr++]; -} - -inline uint8_t debug_fetch8() -{ - return z80_dasm_ops[z80_dasm_ptr++]; -} - -inline uint16_t debug_fetch16() -{ - uint16_t val = z80_dasm_ops[z80_dasm_ptr] | (z80_dasm_ops[z80_dasm_ptr + 1] << 8); - z80_dasm_ptr += 2; - return val; -} - -inline int8_t debug_fetch8_rel() -{ - return (int8_t)z80_dasm_ops[z80_dasm_ptr++]; -} - -inline uint16_t debug_fetch8_relpc(uint32_t pc) -{ - int8_t res = (int8_t)z80_dasm_ops[z80_dasm_ptr++]; - return pc + z80_dasm_ptr + res; -} - -int z80_dasm_main(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) -{ - buffer[0] = _T('\0'); - z80_dasm_ptr = 0; - uint8_t code = dasm_fetchop(); - - switch(code) { - case 0x00: my_stprintf_s(buffer, buffer_len, _T("NOP")); break; - case 0x01: my_stprintf_s(buffer, buffer_len, _T("LD BC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x02: my_stprintf_s(buffer, buffer_len, _T("LD (BC), A")); break; - case 0x03: my_stprintf_s(buffer, buffer_len, _T("INC BC")); break; - case 0x04: my_stprintf_s(buffer, buffer_len, _T("INC B")); break; - case 0x05: my_stprintf_s(buffer, buffer_len, _T("DEC B")); break; - case 0x06: my_stprintf_s(buffer, buffer_len, _T("LD B, %02x"), debug_fetch8()); break; - case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLCA")); break; - case 0x08: my_stprintf_s(buffer, buffer_len, _T("EX AF, AF'")); break; - case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD HL, BC")); break; - case 0x0a: my_stprintf_s(buffer, buffer_len, _T("LD A, (BC)")); break; - case 0x0b: my_stprintf_s(buffer, buffer_len, _T("DEC BC")); break; - case 0x0c: my_stprintf_s(buffer, buffer_len, _T("INC C")); break; - case 0x0d: my_stprintf_s(buffer, buffer_len, _T("DEC C")); break; - case 0x0e: my_stprintf_s(buffer, buffer_len, _T("LD C, %02x"), debug_fetch8()); break; - case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRCA")); break; - case 0x10: my_stprintf_s(buffer, buffer_len, _T("DJNZ %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; - case 0x11: my_stprintf_s(buffer, buffer_len, _T("LD DE, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x12: my_stprintf_s(buffer, buffer_len, _T("LD (DE), A")); break; - case 0x13: my_stprintf_s(buffer, buffer_len, _T("INC DE")); break; - case 0x14: my_stprintf_s(buffer, buffer_len, _T("INC D")); break; - case 0x15: my_stprintf_s(buffer, buffer_len, _T("DEC D")); break; - case 0x16: my_stprintf_s(buffer, buffer_len, _T("LD D, %02x"), debug_fetch8()); break; - case 0x17: my_stprintf_s(buffer, buffer_len, _T("RLA")); break; - case 0x18: my_stprintf_s(buffer, buffer_len, _T("JR %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; - case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD HL, DE")); break; - case 0x1a: my_stprintf_s(buffer, buffer_len, _T("LD A, (DE)")); break; - case 0x1b: my_stprintf_s(buffer, buffer_len, _T("DEC DE")); break; - case 0x1c: my_stprintf_s(buffer, buffer_len, _T("INC E")); break; - case 0x1d: my_stprintf_s(buffer, buffer_len, _T("DEC E")); break; - case 0x1e: my_stprintf_s(buffer, buffer_len, _T("LD E, %02x"), debug_fetch8()); break; - case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RRA")); break; - case 0x20: my_stprintf_s(buffer, buffer_len, _T("JR NZ, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; - case 0x21: my_stprintf_s(buffer, buffer_len, _T("LD HL, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x22: my_stprintf_s(buffer, buffer_len, _T("LD (%s), HL"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x23: my_stprintf_s(buffer, buffer_len, _T("INC HL")); break; - case 0x24: my_stprintf_s(buffer, buffer_len, _T("INC H")); break; - case 0x25: my_stprintf_s(buffer, buffer_len, _T("DEC H")); break; - case 0x26: my_stprintf_s(buffer, buffer_len, _T("LD H, %02x"), debug_fetch8()); break; - case 0x27: my_stprintf_s(buffer, buffer_len, _T("DAA")); break; - case 0x28: my_stprintf_s(buffer, buffer_len, _T("JR Z, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; - case 0x29: my_stprintf_s(buffer, buffer_len, _T("ADD HL, HL")); break; - case 0x2a: my_stprintf_s(buffer, buffer_len, _T("LD HL, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x2b: my_stprintf_s(buffer, buffer_len, _T("DEC HL")); break; - case 0x2c: my_stprintf_s(buffer, buffer_len, _T("INC L")); break; - case 0x2d: my_stprintf_s(buffer, buffer_len, _T("DEC L")); break; - case 0x2e: my_stprintf_s(buffer, buffer_len, _T("LD L, %02x"), debug_fetch8()); break; - case 0x2f: my_stprintf_s(buffer, buffer_len, _T("CPL")); break; - case 0x30: my_stprintf_s(buffer, buffer_len, _T("JR NC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; - case 0x31: my_stprintf_s(buffer, buffer_len, _T("LD SP, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x32: my_stprintf_s(buffer, buffer_len, _T("LD (%s), A"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x33: my_stprintf_s(buffer, buffer_len, _T("INC SP")); break; - case 0x34: my_stprintf_s(buffer, buffer_len, _T("INC (HL)")); break; - case 0x35: my_stprintf_s(buffer, buffer_len, _T("DEC (HL)")); break; - case 0x36: my_stprintf_s(buffer, buffer_len, _T("LD (HL), %02x"), debug_fetch8()); break; - case 0x37: my_stprintf_s(buffer, buffer_len, _T("SCF")); break; - case 0x38: my_stprintf_s(buffer, buffer_len, _T("JR C, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch8_relpc(pc))); break; - case 0x39: my_stprintf_s(buffer, buffer_len, _T("ADD HL, SP")); break; - case 0x3a: my_stprintf_s(buffer, buffer_len, _T("LD A, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x3b: my_stprintf_s(buffer, buffer_len, _T("DEC SP")); break; - case 0x3c: my_stprintf_s(buffer, buffer_len, _T("INC A")); break; - case 0x3d: my_stprintf_s(buffer, buffer_len, _T("DEC A")); break; - case 0x3e: my_stprintf_s(buffer, buffer_len, _T("LD A, %02x"), debug_fetch8()); break; - case 0x3f: my_stprintf_s(buffer, buffer_len, _T("CCF")); break; - case 0x40: my_stprintf_s(buffer, buffer_len, _T("LD B, B")); break; - case 0x41: my_stprintf_s(buffer, buffer_len, _T("LD B, C")); break; - case 0x42: my_stprintf_s(buffer, buffer_len, _T("LD B, D")); break; - case 0x43: my_stprintf_s(buffer, buffer_len, _T("LD B, E")); break; - case 0x44: my_stprintf_s(buffer, buffer_len, _T("LD B, H")); break; - case 0x45: my_stprintf_s(buffer, buffer_len, _T("LD B, L")); break; - case 0x46: my_stprintf_s(buffer, buffer_len, _T("LD B, (HL)")); break; - case 0x47: my_stprintf_s(buffer, buffer_len, _T("LD B, A")); break; - case 0x48: my_stprintf_s(buffer, buffer_len, _T("LD C, B")); break; - case 0x49: my_stprintf_s(buffer, buffer_len, _T("LD C, C")); break; - case 0x4a: my_stprintf_s(buffer, buffer_len, _T("LD C, D")); break; - case 0x4b: my_stprintf_s(buffer, buffer_len, _T("LD C, E")); break; - case 0x4c: my_stprintf_s(buffer, buffer_len, _T("LD C, H")); break; - case 0x4d: my_stprintf_s(buffer, buffer_len, _T("LD C, L")); break; - case 0x4e: my_stprintf_s(buffer, buffer_len, _T("LD C, (HL)")); break; - case 0x4f: my_stprintf_s(buffer, buffer_len, _T("LD C, A")); break; - case 0x50: my_stprintf_s(buffer, buffer_len, _T("LD D, B")); break; - case 0x51: my_stprintf_s(buffer, buffer_len, _T("LD D, C")); break; - case 0x52: my_stprintf_s(buffer, buffer_len, _T("LD D, D")); break; - case 0x53: my_stprintf_s(buffer, buffer_len, _T("LD D, E")); break; - case 0x54: my_stprintf_s(buffer, buffer_len, _T("LD D, H")); break; - case 0x55: my_stprintf_s(buffer, buffer_len, _T("LD D, L")); break; - case 0x56: my_stprintf_s(buffer, buffer_len, _T("LD D, (HL)")); break; - case 0x57: my_stprintf_s(buffer, buffer_len, _T("LD D, A")); break; - case 0x58: my_stprintf_s(buffer, buffer_len, _T("LD E, B")); break; - case 0x59: my_stprintf_s(buffer, buffer_len, _T("LD E, C")); break; - case 0x5a: my_stprintf_s(buffer, buffer_len, _T("LD E, D")); break; - case 0x5b: my_stprintf_s(buffer, buffer_len, _T("LD E, E")); break; - case 0x5c: my_stprintf_s(buffer, buffer_len, _T("LD E, H")); break; - case 0x5d: my_stprintf_s(buffer, buffer_len, _T("LD E, L")); break; - case 0x5e: my_stprintf_s(buffer, buffer_len, _T("LD E, (HL)")); break; - case 0x5f: my_stprintf_s(buffer, buffer_len, _T("LD E, A")); break; - case 0x60: my_stprintf_s(buffer, buffer_len, _T("LD H, B")); break; - case 0x61: my_stprintf_s(buffer, buffer_len, _T("LD H, C")); break; - case 0x62: my_stprintf_s(buffer, buffer_len, _T("LD H, D")); break; - case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD H, E")); break; - case 0x64: my_stprintf_s(buffer, buffer_len, _T("LD H, H")); break; - case 0x65: my_stprintf_s(buffer, buffer_len, _T("LD H, L")); break; - case 0x66: my_stprintf_s(buffer, buffer_len, _T("LD H, (HL)")); break; - case 0x67: my_stprintf_s(buffer, buffer_len, _T("LD H, A")); break; - case 0x68: my_stprintf_s(buffer, buffer_len, _T("LD L, B")); break; - case 0x69: my_stprintf_s(buffer, buffer_len, _T("LD L, C")); break; - case 0x6a: my_stprintf_s(buffer, buffer_len, _T("LD L, D")); break; - case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD L, E")); break; - case 0x6c: my_stprintf_s(buffer, buffer_len, _T("LD L, H")); break; - case 0x6d: my_stprintf_s(buffer, buffer_len, _T("LD L, L")); break; - case 0x6e: my_stprintf_s(buffer, buffer_len, _T("LD L, (HL)")); break; - case 0x6f: my_stprintf_s(buffer, buffer_len, _T("LD L, A")); break; - case 0x70: my_stprintf_s(buffer, buffer_len, _T("LD (HL), B")); break; - case 0x71: my_stprintf_s(buffer, buffer_len, _T("LD (HL), C")); break; - case 0x72: my_stprintf_s(buffer, buffer_len, _T("LD (HL), D")); break; - case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (HL), E")); break; - case 0x74: my_stprintf_s(buffer, buffer_len, _T("LD (HL), H")); break; - case 0x75: my_stprintf_s(buffer, buffer_len, _T("LD (HL), L")); break; - case 0x76: my_stprintf_s(buffer, buffer_len, _T("HALT")); break; - case 0x77: my_stprintf_s(buffer, buffer_len, _T("LD (HL), A")); break; - case 0x78: my_stprintf_s(buffer, buffer_len, _T("LD A, B")); break; - case 0x79: my_stprintf_s(buffer, buffer_len, _T("LD A, C")); break; - case 0x7a: my_stprintf_s(buffer, buffer_len, _T("LD A, D")); break; - case 0x7b: my_stprintf_s(buffer, buffer_len, _T("LD A, E")); break; - case 0x7c: my_stprintf_s(buffer, buffer_len, _T("LD A, H")); break; - case 0x7d: my_stprintf_s(buffer, buffer_len, _T("LD A, L")); break; - case 0x7e: my_stprintf_s(buffer, buffer_len, _T("LD A, (HL)")); break; - case 0x7f: my_stprintf_s(buffer, buffer_len, _T("LD A, A")); break; - case 0x80: my_stprintf_s(buffer, buffer_len, _T("ADD A, B")); break; - case 0x81: my_stprintf_s(buffer, buffer_len, _T("ADD A, C")); break; - case 0x82: my_stprintf_s(buffer, buffer_len, _T("ADD A, D")); break; - case 0x83: my_stprintf_s(buffer, buffer_len, _T("ADD A, E")); break; - case 0x84: my_stprintf_s(buffer, buffer_len, _T("ADD A, H")); break; - case 0x85: my_stprintf_s(buffer, buffer_len, _T("ADD A, L")); break; - case 0x86: my_stprintf_s(buffer, buffer_len, _T("ADD A, (HL)")); break; - case 0x87: my_stprintf_s(buffer, buffer_len, _T("ADD A, A")); break; - case 0x88: my_stprintf_s(buffer, buffer_len, _T("ADC A, B")); break; - case 0x89: my_stprintf_s(buffer, buffer_len, _T("ADC A, C")); break; - case 0x8a: my_stprintf_s(buffer, buffer_len, _T("ADC A, D")); break; - case 0x8b: my_stprintf_s(buffer, buffer_len, _T("ADC A, E")); break; - case 0x8c: my_stprintf_s(buffer, buffer_len, _T("ADC A, H")); break; - case 0x8d: my_stprintf_s(buffer, buffer_len, _T("ADC A, L")); break; - case 0x8e: my_stprintf_s(buffer, buffer_len, _T("ADC A, (HL)")); break; - case 0x8f: my_stprintf_s(buffer, buffer_len, _T("ADC A, A")); break; - case 0x90: my_stprintf_s(buffer, buffer_len, _T("SUB B")); break; - case 0x91: my_stprintf_s(buffer, buffer_len, _T("SUB C")); break; - case 0x92: my_stprintf_s(buffer, buffer_len, _T("SUB D")); break; - case 0x93: my_stprintf_s(buffer, buffer_len, _T("SUB E")); break; - case 0x94: my_stprintf_s(buffer, buffer_len, _T("SUB H")); break; - case 0x95: my_stprintf_s(buffer, buffer_len, _T("SUB L")); break; - case 0x96: my_stprintf_s(buffer, buffer_len, _T("SUB (HL)")); break; - case 0x97: my_stprintf_s(buffer, buffer_len, _T("SUB A")); break; - case 0x98: my_stprintf_s(buffer, buffer_len, _T("SBC A, B")); break; - case 0x99: my_stprintf_s(buffer, buffer_len, _T("SBC A, C")); break; - case 0x9a: my_stprintf_s(buffer, buffer_len, _T("SBC A, D")); break; - case 0x9b: my_stprintf_s(buffer, buffer_len, _T("SBC A, E")); break; - case 0x9c: my_stprintf_s(buffer, buffer_len, _T("SBC A, H")); break; - case 0x9d: my_stprintf_s(buffer, buffer_len, _T("SBC A, L")); break; - case 0x9e: my_stprintf_s(buffer, buffer_len, _T("SBC A, (HL)")); break; - case 0x9f: my_stprintf_s(buffer, buffer_len, _T("SBC A, A")); break; - case 0xa0: my_stprintf_s(buffer, buffer_len, _T("AND B")); break; - case 0xa1: my_stprintf_s(buffer, buffer_len, _T("AND C")); break; - case 0xa2: my_stprintf_s(buffer, buffer_len, _T("AND D")); break; - case 0xa3: my_stprintf_s(buffer, buffer_len, _T("AND E")); break; - case 0xa4: my_stprintf_s(buffer, buffer_len, _T("AND H")); break; - case 0xa5: my_stprintf_s(buffer, buffer_len, _T("AND L")); break; - case 0xa6: my_stprintf_s(buffer, buffer_len, _T("AND (HL)")); break; - case 0xa7: my_stprintf_s(buffer, buffer_len, _T("AND A")); break; - case 0xa8: my_stprintf_s(buffer, buffer_len, _T("XOR B")); break; - case 0xa9: my_stprintf_s(buffer, buffer_len, _T("XOR C")); break; - case 0xaa: my_stprintf_s(buffer, buffer_len, _T("XOR D")); break; - case 0xab: my_stprintf_s(buffer, buffer_len, _T("XOR E")); break; - case 0xac: my_stprintf_s(buffer, buffer_len, _T("XOR H")); break; - case 0xad: my_stprintf_s(buffer, buffer_len, _T("XOR L")); break; - case 0xae: my_stprintf_s(buffer, buffer_len, _T("XOR (HL)")); break; - case 0xaf: my_stprintf_s(buffer, buffer_len, _T("XOR A")); break; - case 0xb0: my_stprintf_s(buffer, buffer_len, _T("OR B")); break; - case 0xb1: my_stprintf_s(buffer, buffer_len, _T("OR C")); break; - case 0xb2: my_stprintf_s(buffer, buffer_len, _T("OR D")); break; - case 0xb3: my_stprintf_s(buffer, buffer_len, _T("OR E")); break; - case 0xb4: my_stprintf_s(buffer, buffer_len, _T("OR H")); break; - case 0xb5: my_stprintf_s(buffer, buffer_len, _T("OR L")); break; - case 0xb6: my_stprintf_s(buffer, buffer_len, _T("OR (HL)")); break; - case 0xb7: my_stprintf_s(buffer, buffer_len, _T("OR A")); break; - case 0xb8: my_stprintf_s(buffer, buffer_len, _T("CP B")); break; - case 0xb9: my_stprintf_s(buffer, buffer_len, _T("CP C")); break; - case 0xba: my_stprintf_s(buffer, buffer_len, _T("CP D")); break; - case 0xbb: my_stprintf_s(buffer, buffer_len, _T("CP E")); break; - case 0xbc: my_stprintf_s(buffer, buffer_len, _T("CP H")); break; - case 0xbd: my_stprintf_s(buffer, buffer_len, _T("CP L")); break; - case 0xbe: my_stprintf_s(buffer, buffer_len, _T("CP (HL)")); break; - case 0xbf: my_stprintf_s(buffer, buffer_len, _T("CP A")); break; - case 0xc0: my_stprintf_s(buffer, buffer_len, _T("RET NZ")); break; - case 0xc1: my_stprintf_s(buffer, buffer_len, _T("POP BC")); break; - case 0xc2: my_stprintf_s(buffer, buffer_len, _T("JP NZ, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xc3: my_stprintf_s(buffer, buffer_len, _T("JP %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xc4: my_stprintf_s(buffer, buffer_len, _T("CALL NZ, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xc5: my_stprintf_s(buffer, buffer_len, _T("PUSH BC")); break; - case 0xc6: my_stprintf_s(buffer, buffer_len, _T("ADD A, %02x"), debug_fetch8()); break; - case 0xc7: my_stprintf_s(buffer, buffer_len, _T("RST 00H")); break; - case 0xc8: my_stprintf_s(buffer, buffer_len, _T("RET Z")); break; - case 0xc9: my_stprintf_s(buffer, buffer_len, _T("RET")); break; - case 0xca: my_stprintf_s(buffer, buffer_len, _T("JP Z, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xcb: dasm_cb(pc, buffer, buffer_len, first_symbol); break; - case 0xcc: my_stprintf_s(buffer, buffer_len, _T("CALL Z, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xcd: my_stprintf_s(buffer, buffer_len, _T("CALL %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xce: my_stprintf_s(buffer, buffer_len, _T("ADC A, %02x"), debug_fetch8()); break; - case 0xcf: my_stprintf_s(buffer, buffer_len, _T("RST 08H")); break; - case 0xd0: my_stprintf_s(buffer, buffer_len, _T("RET NC")); break; - case 0xd1: my_stprintf_s(buffer, buffer_len, _T("POP DE")); break; - case 0xd2: my_stprintf_s(buffer, buffer_len, _T("JP NC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xd3: my_stprintf_s(buffer, buffer_len, _T("OUT (%02x), A"), debug_fetch8()); break; - case 0xd4: my_stprintf_s(buffer, buffer_len, _T("CALL NC, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xd5: my_stprintf_s(buffer, buffer_len, _T("PUSH DE")); break; - case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SUB %02x"), debug_fetch8()); break; - case 0xd7: my_stprintf_s(buffer, buffer_len, _T("RST 10H")); break; - case 0xd8: my_stprintf_s(buffer, buffer_len, _T("RET C")); break; - case 0xd9: my_stprintf_s(buffer, buffer_len, _T("EXX")); break; - case 0xda: my_stprintf_s(buffer, buffer_len, _T("JP C, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xdb: my_stprintf_s(buffer, buffer_len, _T("IN A, (%02x)"), debug_fetch8()); break; - case 0xdc: my_stprintf_s(buffer, buffer_len, _T("CALL C, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xdd: dasm_dd(pc, buffer, buffer_len, first_symbol); break; - case 0xde: my_stprintf_s(buffer, buffer_len, _T("SBC A, %02x"), debug_fetch8()); break; - case 0xdf: my_stprintf_s(buffer, buffer_len, _T("RST 18H")); break; - case 0xe0: my_stprintf_s(buffer, buffer_len, _T("RET PO")); break; - case 0xe1: my_stprintf_s(buffer, buffer_len, _T("POP HL")); break; - case 0xe2: my_stprintf_s(buffer, buffer_len, _T("JP PO, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xe3: my_stprintf_s(buffer, buffer_len, _T("EX HL, (SP)")); break; - case 0xe4: my_stprintf_s(buffer, buffer_len, _T("CALL PO, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xe5: my_stprintf_s(buffer, buffer_len, _T("PUSH HL")); break; - case 0xe6: my_stprintf_s(buffer, buffer_len, _T("AND %02x"), debug_fetch8()); break; - case 0xe7: my_stprintf_s(buffer, buffer_len, _T("RST 20H")); break; - case 0xe8: my_stprintf_s(buffer, buffer_len, _T("RET PE")); break; - case 0xe9: my_stprintf_s(buffer, buffer_len, _T("JP (HL)")); break; - case 0xea: my_stprintf_s(buffer, buffer_len, _T("JP PE, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xeb: my_stprintf_s(buffer, buffer_len, _T("EX DE, HL")); break; - case 0xec: my_stprintf_s(buffer, buffer_len, _T("CALL PE, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xed: dasm_ed(pc, buffer, buffer_len, first_symbol); break; - case 0xee: my_stprintf_s(buffer, buffer_len, _T("XOR %02x"), debug_fetch8()); break; - case 0xef: my_stprintf_s(buffer, buffer_len, _T("RST 28H")); break; - case 0xf0: my_stprintf_s(buffer, buffer_len, _T("RET P")); break; - case 0xf1: my_stprintf_s(buffer, buffer_len, _T("POP AF")); break; - case 0xf2: my_stprintf_s(buffer, buffer_len, _T("JP P, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xf3: my_stprintf_s(buffer, buffer_len, _T("DI")); break; - case 0xf4: my_stprintf_s(buffer, buffer_len, _T("CALL P, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xf5: my_stprintf_s(buffer, buffer_len, _T("PUSH AF")); break; - case 0xf6: my_stprintf_s(buffer, buffer_len, _T("OR %02x"), debug_fetch8()); break; - case 0xf7: my_stprintf_s(buffer, buffer_len, _T("RST 30H")); break; - case 0xf8: my_stprintf_s(buffer, buffer_len, _T("RET M")); break; - case 0xf9: my_stprintf_s(buffer, buffer_len, _T("LD SP, HL")); break; - case 0xfa: my_stprintf_s(buffer, buffer_len, _T("JP M, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xfb: my_stprintf_s(buffer, buffer_len, _T("EI")); break; - case 0xfc: my_stprintf_s(buffer, buffer_len, _T("CALL M, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0xfd: dasm_fd(pc, buffer, buffer_len, first_symbol); break; - case 0xfe: my_stprintf_s(buffer, buffer_len, _T("CP %02x"), debug_fetch8()); break; - case 0xff: my_stprintf_s(buffer, buffer_len, _T("RST 38H")); break; -#if defined(_MSC_VER) && (_MSC_VER >= 1200) - default: __assume(0); -#endif - } - return z80_dasm_ptr; -} - -static void dasm_cb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) -{ - uint8_t code = dasm_fetchop(); - - switch(code) { - case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B")); break; - case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C")); break; - case 0x02: my_stprintf_s(buffer, buffer_len, _T("RLC D")); break; - case 0x03: my_stprintf_s(buffer, buffer_len, _T("RLC E")); break; - case 0x04: my_stprintf_s(buffer, buffer_len, _T("RLC H")); break; - case 0x05: my_stprintf_s(buffer, buffer_len, _T("RLC L")); break; - case 0x06: my_stprintf_s(buffer, buffer_len, _T("RLC (HL)")); break; - case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLC A")); break; - case 0x08: my_stprintf_s(buffer, buffer_len, _T("RRC B")); break; - case 0x09: my_stprintf_s(buffer, buffer_len, _T("RRC C")); break; - case 0x0a: my_stprintf_s(buffer, buffer_len, _T("RRC D")); break; - case 0x0b: my_stprintf_s(buffer, buffer_len, _T("RRC E")); break; - case 0x0c: my_stprintf_s(buffer, buffer_len, _T("RRC H")); break; - case 0x0d: my_stprintf_s(buffer, buffer_len, _T("RRC L")); break; - case 0x0e: my_stprintf_s(buffer, buffer_len, _T("RRC (HL)")); break; - case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRC A")); break; - case 0x10: my_stprintf_s(buffer, buffer_len, _T("RL B")); break; - case 0x11: my_stprintf_s(buffer, buffer_len, _T("RL C")); break; - case 0x12: my_stprintf_s(buffer, buffer_len, _T("RL D")); break; - case 0x13: my_stprintf_s(buffer, buffer_len, _T("RL E")); break; - case 0x14: my_stprintf_s(buffer, buffer_len, _T("RL H")); break; - case 0x15: my_stprintf_s(buffer, buffer_len, _T("RL L")); break; - case 0x16: my_stprintf_s(buffer, buffer_len, _T("RL (HL)")); break; - case 0x17: my_stprintf_s(buffer, buffer_len, _T("RL A")); break; - case 0x18: my_stprintf_s(buffer, buffer_len, _T("RR B")); break; - case 0x19: my_stprintf_s(buffer, buffer_len, _T("RR C")); break; - case 0x1a: my_stprintf_s(buffer, buffer_len, _T("RR D")); break; - case 0x1b: my_stprintf_s(buffer, buffer_len, _T("RR E")); break; - case 0x1c: my_stprintf_s(buffer, buffer_len, _T("RR H")); break; - case 0x1d: my_stprintf_s(buffer, buffer_len, _T("RR L")); break; - case 0x1e: my_stprintf_s(buffer, buffer_len, _T("RR (HL)")); break; - case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RR A")); break; - case 0x20: my_stprintf_s(buffer, buffer_len, _T("SLA B")); break; - case 0x21: my_stprintf_s(buffer, buffer_len, _T("SLA C")); break; - case 0x22: my_stprintf_s(buffer, buffer_len, _T("SLA D")); break; - case 0x23: my_stprintf_s(buffer, buffer_len, _T("SLA E")); break; - case 0x24: my_stprintf_s(buffer, buffer_len, _T("SLA H")); break; - case 0x25: my_stprintf_s(buffer, buffer_len, _T("SLA L")); break; - case 0x26: my_stprintf_s(buffer, buffer_len, _T("SLA (HL)")); break; - case 0x27: my_stprintf_s(buffer, buffer_len, _T("SLA A")); break; - case 0x28: my_stprintf_s(buffer, buffer_len, _T("SRA B")); break; - case 0x29: my_stprintf_s(buffer, buffer_len, _T("SRA C")); break; - case 0x2a: my_stprintf_s(buffer, buffer_len, _T("SRA D")); break; - case 0x2b: my_stprintf_s(buffer, buffer_len, _T("SRA E")); break; - case 0x2c: my_stprintf_s(buffer, buffer_len, _T("SRA H")); break; - case 0x2d: my_stprintf_s(buffer, buffer_len, _T("SRA L")); break; - case 0x2e: my_stprintf_s(buffer, buffer_len, _T("SRA (HL)")); break; - case 0x2f: my_stprintf_s(buffer, buffer_len, _T("SRA A")); break; - case 0x30: my_stprintf_s(buffer, buffer_len, _T("SLL B")); break; - case 0x31: my_stprintf_s(buffer, buffer_len, _T("SLL C")); break; - case 0x32: my_stprintf_s(buffer, buffer_len, _T("SLL D")); break; - case 0x33: my_stprintf_s(buffer, buffer_len, _T("SLL E")); break; - case 0x34: my_stprintf_s(buffer, buffer_len, _T("SLL H")); break; - case 0x35: my_stprintf_s(buffer, buffer_len, _T("SLL L")); break; - case 0x36: my_stprintf_s(buffer, buffer_len, _T("SLL (HL)")); break; - case 0x37: my_stprintf_s(buffer, buffer_len, _T("SLL A")); break; - case 0x38: my_stprintf_s(buffer, buffer_len, _T("SRL B")); break; - case 0x39: my_stprintf_s(buffer, buffer_len, _T("SRL C")); break; - case 0x3a: my_stprintf_s(buffer, buffer_len, _T("SRL D")); break; - case 0x3b: my_stprintf_s(buffer, buffer_len, _T("SRL E")); break; - case 0x3c: my_stprintf_s(buffer, buffer_len, _T("SRL H")); break; - case 0x3d: my_stprintf_s(buffer, buffer_len, _T("SRL L")); break; - case 0x3e: my_stprintf_s(buffer, buffer_len, _T("SRL (HL)")); break; - case 0x3f: my_stprintf_s(buffer, buffer_len, _T("SRL A")); break; - case 0x40: my_stprintf_s(buffer, buffer_len, _T("BIT 0, B")); break; - case 0x41: my_stprintf_s(buffer, buffer_len, _T("BIT 0, C")); break; - case 0x42: my_stprintf_s(buffer, buffer_len, _T("BIT 0, D")); break; - case 0x43: my_stprintf_s(buffer, buffer_len, _T("BIT 0, E")); break; - case 0x44: my_stprintf_s(buffer, buffer_len, _T("BIT 0, H")); break; - case 0x45: my_stprintf_s(buffer, buffer_len, _T("BIT 0, L")); break; - case 0x46: my_stprintf_s(buffer, buffer_len, _T("BIT 0, (HL)")); break; - case 0x47: my_stprintf_s(buffer, buffer_len, _T("BIT 0, A")); break; - case 0x48: my_stprintf_s(buffer, buffer_len, _T("BIT 1, B")); break; - case 0x49: my_stprintf_s(buffer, buffer_len, _T("BIT 1, C")); break; - case 0x4a: my_stprintf_s(buffer, buffer_len, _T("BIT 1, D")); break; - case 0x4b: my_stprintf_s(buffer, buffer_len, _T("BIT 1, E")); break; - case 0x4c: my_stprintf_s(buffer, buffer_len, _T("BIT 1, H")); break; - case 0x4d: my_stprintf_s(buffer, buffer_len, _T("BIT 1, L")); break; - case 0x4e: my_stprintf_s(buffer, buffer_len, _T("BIT 1, (HL)")); break; - case 0x4f: my_stprintf_s(buffer, buffer_len, _T("BIT 1, A")); break; - case 0x50: my_stprintf_s(buffer, buffer_len, _T("BIT 2, B")); break; - case 0x51: my_stprintf_s(buffer, buffer_len, _T("BIT 2, C")); break; - case 0x52: my_stprintf_s(buffer, buffer_len, _T("BIT 2, D")); break; - case 0x53: my_stprintf_s(buffer, buffer_len, _T("BIT 2, E")); break; - case 0x54: my_stprintf_s(buffer, buffer_len, _T("BIT 2, H")); break; - case 0x55: my_stprintf_s(buffer, buffer_len, _T("BIT 2, L")); break; - case 0x56: my_stprintf_s(buffer, buffer_len, _T("BIT 2, (HL)")); break; - case 0x57: my_stprintf_s(buffer, buffer_len, _T("BIT 2, A")); break; - case 0x58: my_stprintf_s(buffer, buffer_len, _T("BIT 3, B")); break; - case 0x59: my_stprintf_s(buffer, buffer_len, _T("BIT 3, C")); break; - case 0x5a: my_stprintf_s(buffer, buffer_len, _T("BIT 3, D")); break; - case 0x5b: my_stprintf_s(buffer, buffer_len, _T("BIT 3, E")); break; - case 0x5c: my_stprintf_s(buffer, buffer_len, _T("BIT 3, H")); break; - case 0x5d: my_stprintf_s(buffer, buffer_len, _T("BIT 3, L")); break; - case 0x5e: my_stprintf_s(buffer, buffer_len, _T("BIT 3, (HL)")); break; - case 0x5f: my_stprintf_s(buffer, buffer_len, _T("BIT 3, A")); break; - case 0x60: my_stprintf_s(buffer, buffer_len, _T("BIT 4, B")); break; - case 0x61: my_stprintf_s(buffer, buffer_len, _T("BIT 4, C")); break; - case 0x62: my_stprintf_s(buffer, buffer_len, _T("BIT 4, D")); break; - case 0x63: my_stprintf_s(buffer, buffer_len, _T("BIT 4, E")); break; - case 0x64: my_stprintf_s(buffer, buffer_len, _T("BIT 4, H")); break; - case 0x65: my_stprintf_s(buffer, buffer_len, _T("BIT 4, L")); break; - case 0x66: my_stprintf_s(buffer, buffer_len, _T("BIT 4, (HL)")); break; - case 0x67: my_stprintf_s(buffer, buffer_len, _T("BIT 4, A")); break; - case 0x68: my_stprintf_s(buffer, buffer_len, _T("BIT 5, B")); break; - case 0x69: my_stprintf_s(buffer, buffer_len, _T("BIT 5, C")); break; - case 0x6a: my_stprintf_s(buffer, buffer_len, _T("BIT 5, D")); break; - case 0x6b: my_stprintf_s(buffer, buffer_len, _T("BIT 5, E")); break; - case 0x6c: my_stprintf_s(buffer, buffer_len, _T("BIT 5, H")); break; - case 0x6d: my_stprintf_s(buffer, buffer_len, _T("BIT 5, L")); break; - case 0x6e: my_stprintf_s(buffer, buffer_len, _T("BIT 5, (HL)")); break; - case 0x6f: my_stprintf_s(buffer, buffer_len, _T("BIT 5, A")); break; - case 0x70: my_stprintf_s(buffer, buffer_len, _T("BIT 6, B")); break; - case 0x71: my_stprintf_s(buffer, buffer_len, _T("BIT 6, C")); break; - case 0x72: my_stprintf_s(buffer, buffer_len, _T("BIT 6, D")); break; - case 0x73: my_stprintf_s(buffer, buffer_len, _T("BIT 6, E")); break; - case 0x74: my_stprintf_s(buffer, buffer_len, _T("BIT 6, H")); break; - case 0x75: my_stprintf_s(buffer, buffer_len, _T("BIT 6, L")); break; - case 0x76: my_stprintf_s(buffer, buffer_len, _T("BIT 6, (HL)")); break; - case 0x77: my_stprintf_s(buffer, buffer_len, _T("BIT 6, A")); break; - case 0x78: my_stprintf_s(buffer, buffer_len, _T("BIT 7, B")); break; - case 0x79: my_stprintf_s(buffer, buffer_len, _T("BIT 7, C")); break; - case 0x7a: my_stprintf_s(buffer, buffer_len, _T("BIT 7, D")); break; - case 0x7b: my_stprintf_s(buffer, buffer_len, _T("BIT 7, E")); break; - case 0x7c: my_stprintf_s(buffer, buffer_len, _T("BIT 7, H")); break; - case 0x7d: my_stprintf_s(buffer, buffer_len, _T("BIT 7, L")); break; - case 0x7e: my_stprintf_s(buffer, buffer_len, _T("BIT 7, (HL)")); break; - case 0x7f: my_stprintf_s(buffer, buffer_len, _T("BIT 7, A")); break; - case 0x80: my_stprintf_s(buffer, buffer_len, _T("RES 0, B")); break; - case 0x81: my_stprintf_s(buffer, buffer_len, _T("RES 0, C")); break; - case 0x82: my_stprintf_s(buffer, buffer_len, _T("RES 0, D")); break; - case 0x83: my_stprintf_s(buffer, buffer_len, _T("RES 0, E")); break; - case 0x84: my_stprintf_s(buffer, buffer_len, _T("RES 0, H")); break; - case 0x85: my_stprintf_s(buffer, buffer_len, _T("RES 0, L")); break; - case 0x86: my_stprintf_s(buffer, buffer_len, _T("RES 0, (HL)")); break; - case 0x87: my_stprintf_s(buffer, buffer_len, _T("RES 0, A")); break; - case 0x88: my_stprintf_s(buffer, buffer_len, _T("RES 1, B")); break; - case 0x89: my_stprintf_s(buffer, buffer_len, _T("RES 1, C")); break; - case 0x8a: my_stprintf_s(buffer, buffer_len, _T("RES 1, D")); break; - case 0x8b: my_stprintf_s(buffer, buffer_len, _T("RES 1, E")); break; - case 0x8c: my_stprintf_s(buffer, buffer_len, _T("RES 1, H")); break; - case 0x8d: my_stprintf_s(buffer, buffer_len, _T("RES 1, L")); break; - case 0x8e: my_stprintf_s(buffer, buffer_len, _T("RES 1, (HL)")); break; - case 0x8f: my_stprintf_s(buffer, buffer_len, _T("RES 1, A")); break; - case 0x90: my_stprintf_s(buffer, buffer_len, _T("RES 2, B")); break; - case 0x91: my_stprintf_s(buffer, buffer_len, _T("RES 2, C")); break; - case 0x92: my_stprintf_s(buffer, buffer_len, _T("RES 2, D")); break; - case 0x93: my_stprintf_s(buffer, buffer_len, _T("RES 2, E")); break; - case 0x94: my_stprintf_s(buffer, buffer_len, _T("RES 2, H")); break; - case 0x95: my_stprintf_s(buffer, buffer_len, _T("RES 2, L")); break; - case 0x96: my_stprintf_s(buffer, buffer_len, _T("RES 2, (HL)")); break; - case 0x97: my_stprintf_s(buffer, buffer_len, _T("RES 2, A")); break; - case 0x98: my_stprintf_s(buffer, buffer_len, _T("RES 3, B")); break; - case 0x99: my_stprintf_s(buffer, buffer_len, _T("RES 3, C")); break; - case 0x9a: my_stprintf_s(buffer, buffer_len, _T("RES 3, D")); break; - case 0x9b: my_stprintf_s(buffer, buffer_len, _T("RES 3, E")); break; - case 0x9c: my_stprintf_s(buffer, buffer_len, _T("RES 3, H")); break; - case 0x9d: my_stprintf_s(buffer, buffer_len, _T("RES 3, L")); break; - case 0x9e: my_stprintf_s(buffer, buffer_len, _T("RES 3, (HL)")); break; - case 0x9f: my_stprintf_s(buffer, buffer_len, _T("RES 3, A")); break; - case 0xa0: my_stprintf_s(buffer, buffer_len, _T("RES 4, B")); break; - case 0xa1: my_stprintf_s(buffer, buffer_len, _T("RES 4, C")); break; - case 0xa2: my_stprintf_s(buffer, buffer_len, _T("RES 4, D")); break; - case 0xa3: my_stprintf_s(buffer, buffer_len, _T("RES 4, E")); break; - case 0xa4: my_stprintf_s(buffer, buffer_len, _T("RES 4, H")); break; - case 0xa5: my_stprintf_s(buffer, buffer_len, _T("RES 4, L")); break; - case 0xa6: my_stprintf_s(buffer, buffer_len, _T("RES 4, (HL)")); break; - case 0xa7: my_stprintf_s(buffer, buffer_len, _T("RES 4, A")); break; - case 0xa8: my_stprintf_s(buffer, buffer_len, _T("RES 5, B")); break; - case 0xa9: my_stprintf_s(buffer, buffer_len, _T("RES 5, C")); break; - case 0xaa: my_stprintf_s(buffer, buffer_len, _T("RES 5, D")); break; - case 0xab: my_stprintf_s(buffer, buffer_len, _T("RES 5, E")); break; - case 0xac: my_stprintf_s(buffer, buffer_len, _T("RES 5, H")); break; - case 0xad: my_stprintf_s(buffer, buffer_len, _T("RES 5, L")); break; - case 0xae: my_stprintf_s(buffer, buffer_len, _T("RES 5, (HL)")); break; - case 0xaf: my_stprintf_s(buffer, buffer_len, _T("RES 5, A")); break; - case 0xb0: my_stprintf_s(buffer, buffer_len, _T("RES 6, B")); break; - case 0xb1: my_stprintf_s(buffer, buffer_len, _T("RES 6, C")); break; - case 0xb2: my_stprintf_s(buffer, buffer_len, _T("RES 6, D")); break; - case 0xb3: my_stprintf_s(buffer, buffer_len, _T("RES 6, E")); break; - case 0xb4: my_stprintf_s(buffer, buffer_len, _T("RES 6, H")); break; - case 0xb5: my_stprintf_s(buffer, buffer_len, _T("RES 6, L")); break; - case 0xb6: my_stprintf_s(buffer, buffer_len, _T("RES 6, (HL)")); break; - case 0xb7: my_stprintf_s(buffer, buffer_len, _T("RES 6, A")); break; - case 0xb8: my_stprintf_s(buffer, buffer_len, _T("RES 7, B")); break; - case 0xb9: my_stprintf_s(buffer, buffer_len, _T("RES 7, C")); break; - case 0xba: my_stprintf_s(buffer, buffer_len, _T("RES 7, D")); break; - case 0xbb: my_stprintf_s(buffer, buffer_len, _T("RES 7, E")); break; - case 0xbc: my_stprintf_s(buffer, buffer_len, _T("RES 7, H")); break; - case 0xbd: my_stprintf_s(buffer, buffer_len, _T("RES 7, L")); break; - case 0xbe: my_stprintf_s(buffer, buffer_len, _T("RES 7, (HL)")); break; - case 0xbf: my_stprintf_s(buffer, buffer_len, _T("RES 7, A")); break; - case 0xc0: my_stprintf_s(buffer, buffer_len, _T("SET 0, B")); break; - case 0xc1: my_stprintf_s(buffer, buffer_len, _T("SET 0, C")); break; - case 0xc2: my_stprintf_s(buffer, buffer_len, _T("SET 0, D")); break; - case 0xc3: my_stprintf_s(buffer, buffer_len, _T("SET 0, E")); break; - case 0xc4: my_stprintf_s(buffer, buffer_len, _T("SET 0, H")); break; - case 0xc5: my_stprintf_s(buffer, buffer_len, _T("SET 0, L")); break; - case 0xc6: my_stprintf_s(buffer, buffer_len, _T("SET 0, (HL)")); break; - case 0xc7: my_stprintf_s(buffer, buffer_len, _T("SET 0, A")); break; - case 0xc8: my_stprintf_s(buffer, buffer_len, _T("SET 1, B")); break; - case 0xc9: my_stprintf_s(buffer, buffer_len, _T("SET 1, C")); break; - case 0xca: my_stprintf_s(buffer, buffer_len, _T("SET 1, D")); break; - case 0xcb: my_stprintf_s(buffer, buffer_len, _T("SET 1, E")); break; - case 0xcc: my_stprintf_s(buffer, buffer_len, _T("SET 1, H")); break; - case 0xcd: my_stprintf_s(buffer, buffer_len, _T("SET 1, L")); break; - case 0xce: my_stprintf_s(buffer, buffer_len, _T("SET 1, (HL)")); break; - case 0xcf: my_stprintf_s(buffer, buffer_len, _T("SET 1, A")); break; - case 0xd0: my_stprintf_s(buffer, buffer_len, _T("SET 2, B")); break; - case 0xd1: my_stprintf_s(buffer, buffer_len, _T("SET 2, C")); break; - case 0xd2: my_stprintf_s(buffer, buffer_len, _T("SET 2, D")); break; - case 0xd3: my_stprintf_s(buffer, buffer_len, _T("SET 2, E")); break; - case 0xd4: my_stprintf_s(buffer, buffer_len, _T("SET 2, H")); break; - case 0xd5: my_stprintf_s(buffer, buffer_len, _T("SET 2, L")); break; - case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SET 2, (HL)")); break; - case 0xd7: my_stprintf_s(buffer, buffer_len, _T("SET 2, A")); break; - case 0xd8: my_stprintf_s(buffer, buffer_len, _T("SET 3, B")); break; - case 0xd9: my_stprintf_s(buffer, buffer_len, _T("SET 3, C")); break; - case 0xda: my_stprintf_s(buffer, buffer_len, _T("SET 3, D")); break; - case 0xdb: my_stprintf_s(buffer, buffer_len, _T("SET 3, E")); break; - case 0xdc: my_stprintf_s(buffer, buffer_len, _T("SET 3, H")); break; - case 0xdd: my_stprintf_s(buffer, buffer_len, _T("SET 3, L")); break; - case 0xde: my_stprintf_s(buffer, buffer_len, _T("SET 3, (HL)")); break; - case 0xdf: my_stprintf_s(buffer, buffer_len, _T("SET 3, A")); break; - case 0xe0: my_stprintf_s(buffer, buffer_len, _T("SET 4, B")); break; - case 0xe1: my_stprintf_s(buffer, buffer_len, _T("SET 4, C")); break; - case 0xe2: my_stprintf_s(buffer, buffer_len, _T("SET 4, D")); break; - case 0xe3: my_stprintf_s(buffer, buffer_len, _T("SET 4, E")); break; - case 0xe4: my_stprintf_s(buffer, buffer_len, _T("SET 4, H")); break; - case 0xe5: my_stprintf_s(buffer, buffer_len, _T("SET 4, L")); break; - case 0xe6: my_stprintf_s(buffer, buffer_len, _T("SET 4, (HL)")); break; - case 0xe7: my_stprintf_s(buffer, buffer_len, _T("SET 4, A")); break; - case 0xe8: my_stprintf_s(buffer, buffer_len, _T("SET 5, B")); break; - case 0xe9: my_stprintf_s(buffer, buffer_len, _T("SET 5, C")); break; - case 0xea: my_stprintf_s(buffer, buffer_len, _T("SET 5, D")); break; - case 0xeb: my_stprintf_s(buffer, buffer_len, _T("SET 5, E")); break; - case 0xec: my_stprintf_s(buffer, buffer_len, _T("SET 5, H")); break; - case 0xed: my_stprintf_s(buffer, buffer_len, _T("SET 5, L")); break; - case 0xee: my_stprintf_s(buffer, buffer_len, _T("SET 5, (HL)")); break; - case 0xef: my_stprintf_s(buffer, buffer_len, _T("SET 5, A")); break; - case 0xf0: my_stprintf_s(buffer, buffer_len, _T("SET 6, B")); break; - case 0xf1: my_stprintf_s(buffer, buffer_len, _T("SET 6, C")); break; - case 0xf2: my_stprintf_s(buffer, buffer_len, _T("SET 6, D")); break; - case 0xf3: my_stprintf_s(buffer, buffer_len, _T("SET 6, E")); break; - case 0xf4: my_stprintf_s(buffer, buffer_len, _T("SET 6, H")); break; - case 0xf5: my_stprintf_s(buffer, buffer_len, _T("SET 6, L")); break; - case 0xf6: my_stprintf_s(buffer, buffer_len, _T("SET 6, (HL)")); break; - case 0xf7: my_stprintf_s(buffer, buffer_len, _T("SET 6, A")); break; - case 0xf8: my_stprintf_s(buffer, buffer_len, _T("SET 7, B")); break; - case 0xf9: my_stprintf_s(buffer, buffer_len, _T("SET 7, C")); break; - case 0xfa: my_stprintf_s(buffer, buffer_len, _T("SET 7, D")); break; - case 0xfb: my_stprintf_s(buffer, buffer_len, _T("SET 7, E")); break; - case 0xfc: my_stprintf_s(buffer, buffer_len, _T("SET 7, H")); break; - case 0xfd: my_stprintf_s(buffer, buffer_len, _T("SET 7, L")); break; - case 0xfe: my_stprintf_s(buffer, buffer_len, _T("SET 7, (HL)")); break; - case 0xff: my_stprintf_s(buffer, buffer_len, _T("SET 7, A")); break; -#if defined(_MSC_VER) && (_MSC_VER >= 1200) - default: __assume(0); -#endif - } -} - -static void dasm_dd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) -{ - uint8_t code = dasm_fetchop(); - int8_t ofs; - - switch(code) { - case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD IX, BC")); break; - case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD IX, DE")); break; - case 0x21: my_stprintf_s(buffer, buffer_len, _T("LD IX, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x22: my_stprintf_s(buffer, buffer_len, _T("LD (%s), IX"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x23: my_stprintf_s(buffer, buffer_len, _T("INC IX")); break; - case 0x24: my_stprintf_s(buffer, buffer_len, _T("INC HX")); break; - case 0x25: my_stprintf_s(buffer, buffer_len, _T("DEC HX")); break; - case 0x26: my_stprintf_s(buffer, buffer_len, _T("LD HX, %02x"), debug_fetch8()); break; - case 0x29: my_stprintf_s(buffer, buffer_len, _T("ADD IX, IX")); break; - case 0x2a: my_stprintf_s(buffer, buffer_len, _T("LD IX, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x2b: my_stprintf_s(buffer, buffer_len, _T("DEC IX")); break; - case 0x2c: my_stprintf_s(buffer, buffer_len, _T("INC LX")); break; - case 0x2d: my_stprintf_s(buffer, buffer_len, _T("DEC LX")); break; - case 0x2e: my_stprintf_s(buffer, buffer_len, _T("LD LX, %02x"), debug_fetch8()); break; - case 0x34: my_stprintf_s(buffer, buffer_len, _T("INC (IX+(%d))"), debug_fetch8_rel()); break; - case 0x35: my_stprintf_s(buffer, buffer_len, _T("DEC (IX+(%d))"), debug_fetch8_rel()); break; - case 0x36: ofs = debug_fetch8_rel(); my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), %02x"), ofs, debug_fetch8()); break; - case 0x39: my_stprintf_s(buffer, buffer_len, _T("ADD IX, SP")); break; - case 0x44: my_stprintf_s(buffer, buffer_len, _T("LD B, HX")); break; - case 0x45: my_stprintf_s(buffer, buffer_len, _T("LD B, LX")); break; - case 0x46: my_stprintf_s(buffer, buffer_len, _T("LD B, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x4c: my_stprintf_s(buffer, buffer_len, _T("LD C, HX")); break; - case 0x4d: my_stprintf_s(buffer, buffer_len, _T("LD C, LX")); break; - case 0x4e: my_stprintf_s(buffer, buffer_len, _T("LD C, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x54: my_stprintf_s(buffer, buffer_len, _T("LD D, HX")); break; - case 0x55: my_stprintf_s(buffer, buffer_len, _T("LD D, LX")); break; - case 0x56: my_stprintf_s(buffer, buffer_len, _T("LD D, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x5c: my_stprintf_s(buffer, buffer_len, _T("LD E, HX")); break; - case 0x5d: my_stprintf_s(buffer, buffer_len, _T("LD E, LX")); break; - case 0x5e: my_stprintf_s(buffer, buffer_len, _T("LD E, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x60: my_stprintf_s(buffer, buffer_len, _T("LD HX, B")); break; - case 0x61: my_stprintf_s(buffer, buffer_len, _T("LD HX, C")); break; - case 0x62: my_stprintf_s(buffer, buffer_len, _T("LD HX, D")); break; - case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD HX, E")); break; - case 0x64: my_stprintf_s(buffer, buffer_len, _T("LD HX, HX")); break; - case 0x65: my_stprintf_s(buffer, buffer_len, _T("LD HX, LX")); break; - case 0x66: my_stprintf_s(buffer, buffer_len, _T("LD H, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x67: my_stprintf_s(buffer, buffer_len, _T("LD HX, A")); break; - case 0x68: my_stprintf_s(buffer, buffer_len, _T("LD LX, B")); break; - case 0x69: my_stprintf_s(buffer, buffer_len, _T("LD LX, C")); break; - case 0x6a: my_stprintf_s(buffer, buffer_len, _T("LD LX, D")); break; - case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD LX, E")); break; - case 0x6c: my_stprintf_s(buffer, buffer_len, _T("LD LX, HX")); break; - case 0x6d: my_stprintf_s(buffer, buffer_len, _T("LD LX, LX")); break; - case 0x6e: my_stprintf_s(buffer, buffer_len, _T("LD L, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x6f: my_stprintf_s(buffer, buffer_len, _T("LD LX, A")); break; - case 0x70: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), B"), debug_fetch8_rel()); break; - case 0x71: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), C"), debug_fetch8_rel()); break; - case 0x72: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), D"), debug_fetch8_rel()); break; - case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), E"), debug_fetch8_rel()); break; - case 0x74: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), H"), debug_fetch8_rel()); break; - case 0x75: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), L"), debug_fetch8_rel()); break; - case 0x77: my_stprintf_s(buffer, buffer_len, _T("LD (IX+(%d)), A"), debug_fetch8_rel()); break; - case 0x7c: my_stprintf_s(buffer, buffer_len, _T("LD A, HX")); break; - case 0x7d: my_stprintf_s(buffer, buffer_len, _T("LD A, LX")); break; - case 0x7e: my_stprintf_s(buffer, buffer_len, _T("LD A, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x84: my_stprintf_s(buffer, buffer_len, _T("ADD A, HX")); break; - case 0x85: my_stprintf_s(buffer, buffer_len, _T("ADD A, LX")); break; - case 0x86: my_stprintf_s(buffer, buffer_len, _T("ADD A, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x8c: my_stprintf_s(buffer, buffer_len, _T("ADC A, HX")); break; - case 0x8d: my_stprintf_s(buffer, buffer_len, _T("ADC A, LX")); break; - case 0x8e: my_stprintf_s(buffer, buffer_len, _T("ADC A, (IX+(%d))"), debug_fetch8_rel()); break; - case 0x94: my_stprintf_s(buffer, buffer_len, _T("SUB HX")); break; - case 0x95: my_stprintf_s(buffer, buffer_len, _T("SUB LX")); break; - case 0x96: my_stprintf_s(buffer, buffer_len, _T("SUB (IX+(%d))"), debug_fetch8_rel()); break; - case 0x9c: my_stprintf_s(buffer, buffer_len, _T("SBC A, HX")); break; - case 0x9d: my_stprintf_s(buffer, buffer_len, _T("SBC A, LX")); break; - case 0x9e: my_stprintf_s(buffer, buffer_len, _T("SBC A, (IX+(%d))"), debug_fetch8_rel()); break; - case 0xa4: my_stprintf_s(buffer, buffer_len, _T("AND HX")); break; - case 0xa5: my_stprintf_s(buffer, buffer_len, _T("AND LX")); break; - case 0xa6: my_stprintf_s(buffer, buffer_len, _T("AND (IX+(%d))"), debug_fetch8_rel()); break; - case 0xac: my_stprintf_s(buffer, buffer_len, _T("XOR HX")); break; - case 0xad: my_stprintf_s(buffer, buffer_len, _T("XOR LX")); break; - case 0xae: my_stprintf_s(buffer, buffer_len, _T("XOR (IX+(%d))"), debug_fetch8_rel()); break; - case 0xb4: my_stprintf_s(buffer, buffer_len, _T("OR HX")); break; - case 0xb5: my_stprintf_s(buffer, buffer_len, _T("OR LX")); break; - case 0xb6: my_stprintf_s(buffer, buffer_len, _T("OR (IX+(%d))"), debug_fetch8_rel()); break; - case 0xbc: my_stprintf_s(buffer, buffer_len, _T("CP HX")); break; - case 0xbd: my_stprintf_s(buffer, buffer_len, _T("CP LX")); break; - case 0xbe: my_stprintf_s(buffer, buffer_len, _T("CP (IX+(%d))"), debug_fetch8_rel()); break; - case 0xcb: dasm_ddcb(pc, buffer, buffer_len, first_symbol); break; - case 0xe1: my_stprintf_s(buffer, buffer_len, _T("POP IX")); break; - case 0xe3: my_stprintf_s(buffer, buffer_len, _T("EX (SP), IX")); break; - case 0xe5: my_stprintf_s(buffer, buffer_len, _T("PUSH IX")); break; - case 0xe9: my_stprintf_s(buffer, buffer_len, _T("JP (IX)")); break; - case 0xf9: my_stprintf_s(buffer, buffer_len, _T("LD SP, IX")); break; - default: my_stprintf_s(buffer, buffer_len, _T("DB dd")); z80_dasm_ptr--; break; - } -} - -void dasm_ed(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) -{ - uint8_t code = dasm_fetchop(); - - switch(code) { - case 0x40: my_stprintf_s(buffer, buffer_len, _T("IN B, (C)")); break; - case 0x41: my_stprintf_s(buffer, buffer_len, _T("OUT (C), B")); break; - case 0x42: my_stprintf_s(buffer, buffer_len, _T("SBC HL, BC")); break; - case 0x43: my_stprintf_s(buffer, buffer_len, _T("LD (%s), BC"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x44: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x45: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; - case 0x46: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; - case 0x47: my_stprintf_s(buffer, buffer_len, _T("LD I, A")); break; - case 0x48: my_stprintf_s(buffer, buffer_len, _T("IN C, (C)")); break; - case 0x49: my_stprintf_s(buffer, buffer_len, _T("OUT (C), C")); break; - case 0x4a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, BC")); break; - case 0x4b: my_stprintf_s(buffer, buffer_len, _T("LD BC, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x4c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x4d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; - case 0x4e: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; - case 0x4f: my_stprintf_s(buffer, buffer_len, _T("LD R, A")); break; - case 0x50: my_stprintf_s(buffer, buffer_len, _T("IN D, (C)")); break; - case 0x51: my_stprintf_s(buffer, buffer_len, _T("OUT (C), D")); break; - case 0x52: my_stprintf_s(buffer, buffer_len, _T("SBC HL, DE")); break; - case 0x53: my_stprintf_s(buffer, buffer_len, _T("LD (%s), DE"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x54: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x55: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; - case 0x56: my_stprintf_s(buffer, buffer_len, _T("IM 1")); break; - case 0x57: my_stprintf_s(buffer, buffer_len, _T("LD A, I")); break; - case 0x58: my_stprintf_s(buffer, buffer_len, _T("IN E, (C)")); break; - case 0x59: my_stprintf_s(buffer, buffer_len, _T("OUT (C), E")); break; - case 0x5a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, DE")); break; - case 0x5b: my_stprintf_s(buffer, buffer_len, _T("LD DE, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x5c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x5d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; - case 0x5e: my_stprintf_s(buffer, buffer_len, _T("IM 2")); break; - case 0x5f: my_stprintf_s(buffer, buffer_len, _T("LD A, R")); break; - case 0x60: my_stprintf_s(buffer, buffer_len, _T("IN H, (C)")); break; - case 0x61: my_stprintf_s(buffer, buffer_len, _T("OUT (C), H")); break; - case 0x62: my_stprintf_s(buffer, buffer_len, _T("SBC HL, HL")); break; - case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD (%s), HL"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x64: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x65: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; - case 0x66: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; - case 0x67: my_stprintf_s(buffer, buffer_len, _T("RRD (HL)")); break; - case 0x68: my_stprintf_s(buffer, buffer_len, _T("IN L, (C)")); break; - case 0x69: my_stprintf_s(buffer, buffer_len, _T("OUT (C), L")); break; - case 0x6a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, HL")); break; - case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD HL, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x6c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x6d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; - case 0x6e: my_stprintf_s(buffer, buffer_len, _T("IM 0")); break; - case 0x6f: my_stprintf_s(buffer, buffer_len, _T("RLD (HL)")); break; - case 0x70: my_stprintf_s(buffer, buffer_len, _T("IN F, (C)")); break; - case 0x71: my_stprintf_s(buffer, buffer_len, _T("OUT (C), 0")); break; - case 0x72: my_stprintf_s(buffer, buffer_len, _T("SBC HL, SP")); break; - case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (%s), SP"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x74: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x75: my_stprintf_s(buffer, buffer_len, _T("RETN")); break; - case 0x76: my_stprintf_s(buffer, buffer_len, _T("IM 1")); break; - case 0x78: my_stprintf_s(buffer, buffer_len, _T("IN A, (C)")); break; - case 0x79: my_stprintf_s(buffer, buffer_len, _T("OUT (C), A")); break; - case 0x7a: my_stprintf_s(buffer, buffer_len, _T("ADC HL, SP")); break; - case 0x7b: my_stprintf_s(buffer, buffer_len, _T("LD SP, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x7c: my_stprintf_s(buffer, buffer_len, _T("NEG")); break; - case 0x7d: my_stprintf_s(buffer, buffer_len, _T("RETI")); break; - case 0x7e: my_stprintf_s(buffer, buffer_len, _T("IM 2")); break; - case 0xa0: my_stprintf_s(buffer, buffer_len, _T("LDI")); break; - case 0xa1: my_stprintf_s(buffer, buffer_len, _T("CPI")); break; - case 0xa2: my_stprintf_s(buffer, buffer_len, _T("INI")); break; - case 0xa3: my_stprintf_s(buffer, buffer_len, _T("OUTI")); break; - case 0xa8: my_stprintf_s(buffer, buffer_len, _T("LDD")); break; - case 0xa9: my_stprintf_s(buffer, buffer_len, _T("CPD")); break; - case 0xaa: my_stprintf_s(buffer, buffer_len, _T("IND")); break; - case 0xab: my_stprintf_s(buffer, buffer_len, _T("OUTD")); break; - case 0xb0: my_stprintf_s(buffer, buffer_len, _T("LDIR")); break; - case 0xb1: my_stprintf_s(buffer, buffer_len, _T("CPIR")); break; - case 0xb2: my_stprintf_s(buffer, buffer_len, _T("INIR")); break; - case 0xb3: my_stprintf_s(buffer, buffer_len, _T("OTIR")); break; - case 0xb8: my_stprintf_s(buffer, buffer_len, _T("LDDR")); break; - case 0xb9: my_stprintf_s(buffer, buffer_len, _T("CPDR")); break; - case 0xba: my_stprintf_s(buffer, buffer_len, _T("INDR")); break; - case 0xbb: my_stprintf_s(buffer, buffer_len, _T("OTDR")); break; - default: my_stprintf_s(buffer, buffer_len, _T("DB ed")); z80_dasm_ptr--; break; - } -} - -void dasm_fd(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) -{ - uint8_t code = dasm_fetchop(); - int8_t ofs; - - switch(code) { - case 0x09: my_stprintf_s(buffer, buffer_len, _T("ADD IY, BC")); break; - case 0x19: my_stprintf_s(buffer, buffer_len, _T("ADD IY, DE")); break; - case 0x21: my_stprintf_s(buffer, buffer_len, _T("LD IY, %s"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x22: my_stprintf_s(buffer, buffer_len, _T("LD (%s), IY"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x23: my_stprintf_s(buffer, buffer_len, _T("INC IY")); break; - case 0x24: my_stprintf_s(buffer, buffer_len, _T("INC HY")); break; - case 0x25: my_stprintf_s(buffer, buffer_len, _T("DEC HY")); break; - case 0x26: my_stprintf_s(buffer, buffer_len, _T("LD HY, %02x"), debug_fetch8()); break; - case 0x29: my_stprintf_s(buffer, buffer_len, _T("ADD IY, IY")); break; - case 0x2a: my_stprintf_s(buffer, buffer_len, _T("LD IY, (%s)"), get_value_or_symbol(first_symbol, _T("%04x"), debug_fetch16())); break; - case 0x2b: my_stprintf_s(buffer, buffer_len, _T("DEC IY")); break; - case 0x2c: my_stprintf_s(buffer, buffer_len, _T("INC LY")); break; - case 0x2d: my_stprintf_s(buffer, buffer_len, _T("DEC LY")); break; - case 0x2e: my_stprintf_s(buffer, buffer_len, _T("LD LY, %02x"), debug_fetch8()); break; - case 0x34: my_stprintf_s(buffer, buffer_len, _T("INC (IY+(%d))"), debug_fetch8_rel()); break; - case 0x35: my_stprintf_s(buffer, buffer_len, _T("DEC (IY+(%d))"), debug_fetch8_rel()); break; - case 0x36: ofs = debug_fetch8_rel(); my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), %02x"), ofs, debug_fetch8()); break; - case 0x39: my_stprintf_s(buffer, buffer_len, _T("ADD IY, SP")); break; - case 0x44: my_stprintf_s(buffer, buffer_len, _T("LD B, HY")); break; - case 0x45: my_stprintf_s(buffer, buffer_len, _T("LD B, LY")); break; - case 0x46: my_stprintf_s(buffer, buffer_len, _T("LD B, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x4c: my_stprintf_s(buffer, buffer_len, _T("LD C, HY")); break; - case 0x4d: my_stprintf_s(buffer, buffer_len, _T("LD C, LY")); break; - case 0x4e: my_stprintf_s(buffer, buffer_len, _T("LD C, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x54: my_stprintf_s(buffer, buffer_len, _T("LD D, HY")); break; - case 0x55: my_stprintf_s(buffer, buffer_len, _T("LD D, LY")); break; - case 0x56: my_stprintf_s(buffer, buffer_len, _T("LD D, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x5c: my_stprintf_s(buffer, buffer_len, _T("LD E, HY")); break; - case 0x5d: my_stprintf_s(buffer, buffer_len, _T("LD E, LY")); break; - case 0x5e: my_stprintf_s(buffer, buffer_len, _T("LD E, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x60: my_stprintf_s(buffer, buffer_len, _T("LD HY, B")); break; - case 0x61: my_stprintf_s(buffer, buffer_len, _T("LD HY, C")); break; - case 0x62: my_stprintf_s(buffer, buffer_len, _T("LD HY, D")); break; - case 0x63: my_stprintf_s(buffer, buffer_len, _T("LD HY, E")); break; - case 0x64: my_stprintf_s(buffer, buffer_len, _T("LD HY, HY")); break; - case 0x65: my_stprintf_s(buffer, buffer_len, _T("LD HY, LY")); break; - case 0x66: my_stprintf_s(buffer, buffer_len, _T("LD H, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x67: my_stprintf_s(buffer, buffer_len, _T("LD HY, A")); break; - case 0x68: my_stprintf_s(buffer, buffer_len, _T("LD LY, B")); break; - case 0x69: my_stprintf_s(buffer, buffer_len, _T("LD LY, C")); break; - case 0x6a: my_stprintf_s(buffer, buffer_len, _T("LD LY, D")); break; - case 0x6b: my_stprintf_s(buffer, buffer_len, _T("LD LY, E")); break; - case 0x6c: my_stprintf_s(buffer, buffer_len, _T("LD LY, HY")); break; - case 0x6d: my_stprintf_s(buffer, buffer_len, _T("LD LY, LY")); break; - case 0x6e: my_stprintf_s(buffer, buffer_len, _T("LD L, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x6f: my_stprintf_s(buffer, buffer_len, _T("LD LY, A")); break; - case 0x70: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), B"), debug_fetch8_rel()); break; - case 0x71: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), C"), debug_fetch8_rel()); break; - case 0x72: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), D"), debug_fetch8_rel()); break; - case 0x73: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), E"), debug_fetch8_rel()); break; - case 0x74: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), H"), debug_fetch8_rel()); break; - case 0x75: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), L"), debug_fetch8_rel()); break; - case 0x77: my_stprintf_s(buffer, buffer_len, _T("LD (IY+(%d)), A"), debug_fetch8_rel()); break; - case 0x7c: my_stprintf_s(buffer, buffer_len, _T("LD A, HY")); break; - case 0x7d: my_stprintf_s(buffer, buffer_len, _T("LD A, LY")); break; - case 0x7e: my_stprintf_s(buffer, buffer_len, _T("LD A, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x84: my_stprintf_s(buffer, buffer_len, _T("ADD A, HY")); break; - case 0x85: my_stprintf_s(buffer, buffer_len, _T("ADD A, LY")); break; - case 0x86: my_stprintf_s(buffer, buffer_len, _T("ADD A, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x8c: my_stprintf_s(buffer, buffer_len, _T("ADC A, HY")); break; - case 0x8d: my_stprintf_s(buffer, buffer_len, _T("ADC A, LY")); break; - case 0x8e: my_stprintf_s(buffer, buffer_len, _T("ADC A, (IY+(%d))"), debug_fetch8_rel()); break; - case 0x94: my_stprintf_s(buffer, buffer_len, _T("SUB HY")); break; - case 0x95: my_stprintf_s(buffer, buffer_len, _T("SUB LY")); break; - case 0x96: my_stprintf_s(buffer, buffer_len, _T("SUB (IY+(%d))"), debug_fetch8_rel()); break; - case 0x9c: my_stprintf_s(buffer, buffer_len, _T("SBC A, HY")); break; - case 0x9d: my_stprintf_s(buffer, buffer_len, _T("SBC A, LY")); break; - case 0x9e: my_stprintf_s(buffer, buffer_len, _T("SBC A, (IY+(%d))"), debug_fetch8_rel()); break; - case 0xa4: my_stprintf_s(buffer, buffer_len, _T("AND HY")); break; - case 0xa5: my_stprintf_s(buffer, buffer_len, _T("AND LY")); break; - case 0xa6: my_stprintf_s(buffer, buffer_len, _T("AND (IY+(%d))"), debug_fetch8_rel()); break; - case 0xac: my_stprintf_s(buffer, buffer_len, _T("XOR HY")); break; - case 0xad: my_stprintf_s(buffer, buffer_len, _T("XOR LY")); break; - case 0xae: my_stprintf_s(buffer, buffer_len, _T("XOR (IY+(%d))"), debug_fetch8_rel()); break; - case 0xb4: my_stprintf_s(buffer, buffer_len, _T("OR HY")); break; - case 0xb5: my_stprintf_s(buffer, buffer_len, _T("OR LY")); break; - case 0xb6: my_stprintf_s(buffer, buffer_len, _T("OR (IY+(%d))"), debug_fetch8_rel()); break; - case 0xbc: my_stprintf_s(buffer, buffer_len, _T("CP HY")); break; - case 0xbd: my_stprintf_s(buffer, buffer_len, _T("CP LY")); break; - case 0xbe: my_stprintf_s(buffer, buffer_len, _T("CP (IY+(%d))"), debug_fetch8_rel()); break; - case 0xcb: dasm_fdcb(pc, buffer, buffer_len, first_symbol); break; - case 0xe1: my_stprintf_s(buffer, buffer_len, _T("POP IY")); break; - case 0xe3: my_stprintf_s(buffer, buffer_len, _T("EX (SP), IY")); break; - case 0xe5: my_stprintf_s(buffer, buffer_len, _T("PUSH IY")); break; - case 0xe9: my_stprintf_s(buffer, buffer_len, _T("JP (IY)")); break; - case 0xf9: my_stprintf_s(buffer, buffer_len, _T("LD SP, IY")); break; - default: my_stprintf_s(buffer, buffer_len, _T("DB fd")); z80_dasm_ptr--; break; - } -} - -static void dasm_ddcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) -{ - int8_t ofs = debug_fetch8_rel(); - uint8_t code = debug_fetch8(); - - switch(code) { - case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B=(IX+(%d))"), ofs); break; - case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C=(IX+(%d))"), ofs); break; - case 0x02: my_stprintf_s(buffer, buffer_len, _T("RLC D=(IX+(%d))"), ofs); break; - case 0x03: my_stprintf_s(buffer, buffer_len, _T("RLC E=(IX+(%d))"), ofs); break; - case 0x04: my_stprintf_s(buffer, buffer_len, _T("RLC H=(IX+(%d))"), ofs); break; - case 0x05: my_stprintf_s(buffer, buffer_len, _T("RLC L=(IX+(%d))"), ofs); break; - case 0x06: my_stprintf_s(buffer, buffer_len, _T("RLC (IX+(%d))"), ofs); break; - case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLC A=(IX+(%d))"), ofs); break; - case 0x08: my_stprintf_s(buffer, buffer_len, _T("RRC B=(IX+(%d))"), ofs); break; - case 0x09: my_stprintf_s(buffer, buffer_len, _T("RRC C=(IX+(%d))"), ofs); break; - case 0x0a: my_stprintf_s(buffer, buffer_len, _T("RRC D=(IX+(%d))"), ofs); break; - case 0x0b: my_stprintf_s(buffer, buffer_len, _T("RRC E=(IX+(%d))"), ofs); break; - case 0x0c: my_stprintf_s(buffer, buffer_len, _T("RRC H=(IX+(%d))"), ofs); break; - case 0x0d: my_stprintf_s(buffer, buffer_len, _T("RRC L=(IX+(%d))"), ofs); break; - case 0x0e: my_stprintf_s(buffer, buffer_len, _T("RRC (IX+(%d))"), ofs); break; - case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRC A=(IX+(%d))"), ofs); break; - case 0x10: my_stprintf_s(buffer, buffer_len, _T("RL B=(IX+(%d))"), ofs); break; - case 0x11: my_stprintf_s(buffer, buffer_len, _T("RL C=(IX+(%d))"), ofs); break; - case 0x12: my_stprintf_s(buffer, buffer_len, _T("RL D=(IX+(%d))"), ofs); break; - case 0x13: my_stprintf_s(buffer, buffer_len, _T("RL E=(IX+(%d))"), ofs); break; - case 0x14: my_stprintf_s(buffer, buffer_len, _T("RL H=(IX+(%d))"), ofs); break; - case 0x15: my_stprintf_s(buffer, buffer_len, _T("RL L=(IX+(%d))"), ofs); break; - case 0x16: my_stprintf_s(buffer, buffer_len, _T("RL (IX+(%d))"), ofs); break; - case 0x17: my_stprintf_s(buffer, buffer_len, _T("RL A=(IX+(%d))"), ofs); break; - case 0x18: my_stprintf_s(buffer, buffer_len, _T("RR B=(IX+(%d))"), ofs); break; - case 0x19: my_stprintf_s(buffer, buffer_len, _T("RR C=(IX+(%d))"), ofs); break; - case 0x1a: my_stprintf_s(buffer, buffer_len, _T("RR D=(IX+(%d))"), ofs); break; - case 0x1b: my_stprintf_s(buffer, buffer_len, _T("RR E=(IX+(%d))"), ofs); break; - case 0x1c: my_stprintf_s(buffer, buffer_len, _T("RR H=(IX+(%d))"), ofs); break; - case 0x1d: my_stprintf_s(buffer, buffer_len, _T("RR L=(IX+(%d))"), ofs); break; - case 0x1e: my_stprintf_s(buffer, buffer_len, _T("RR (IX+(%d))"), ofs); break; - case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RR A=(IX+(%d))"), ofs); break; - case 0x20: my_stprintf_s(buffer, buffer_len, _T("SLA B=(IX+(%d))"), ofs); break; - case 0x21: my_stprintf_s(buffer, buffer_len, _T("SLA C=(IX+(%d))"), ofs); break; - case 0x22: my_stprintf_s(buffer, buffer_len, _T("SLA D=(IX+(%d))"), ofs); break; - case 0x23: my_stprintf_s(buffer, buffer_len, _T("SLA E=(IX+(%d))"), ofs); break; - case 0x24: my_stprintf_s(buffer, buffer_len, _T("SLA H=(IX+(%d))"), ofs); break; - case 0x25: my_stprintf_s(buffer, buffer_len, _T("SLA L=(IX+(%d))"), ofs); break; - case 0x26: my_stprintf_s(buffer, buffer_len, _T("SLA (IX+(%d))"), ofs); break; - case 0x27: my_stprintf_s(buffer, buffer_len, _T("SLA A=(IX+(%d))"), ofs); break; - case 0x28: my_stprintf_s(buffer, buffer_len, _T("SRA B=(IX+(%d))"), ofs); break; - case 0x29: my_stprintf_s(buffer, buffer_len, _T("SRA C=(IX+(%d))"), ofs); break; - case 0x2a: my_stprintf_s(buffer, buffer_len, _T("SRA D=(IX+(%d))"), ofs); break; - case 0x2b: my_stprintf_s(buffer, buffer_len, _T("SRA E=(IX+(%d))"), ofs); break; - case 0x2c: my_stprintf_s(buffer, buffer_len, _T("SRA H=(IX+(%d))"), ofs); break; - case 0x2d: my_stprintf_s(buffer, buffer_len, _T("SRA L=(IX+(%d))"), ofs); break; - case 0x2e: my_stprintf_s(buffer, buffer_len, _T("SRA (IX+(%d))"), ofs); break; - case 0x2f: my_stprintf_s(buffer, buffer_len, _T("SRA A=(IX+(%d))"), ofs); break; - case 0x30: my_stprintf_s(buffer, buffer_len, _T("SLL B=(IX+(%d))"), ofs); break; - case 0x31: my_stprintf_s(buffer, buffer_len, _T("SLL C=(IX+(%d))"), ofs); break; - case 0x32: my_stprintf_s(buffer, buffer_len, _T("SLL D=(IX+(%d))"), ofs); break; - case 0x33: my_stprintf_s(buffer, buffer_len, _T("SLL E=(IX+(%d))"), ofs); break; - case 0x34: my_stprintf_s(buffer, buffer_len, _T("SLL H=(IX+(%d))"), ofs); break; - case 0x35: my_stprintf_s(buffer, buffer_len, _T("SLL L=(IX+(%d))"), ofs); break; - case 0x36: my_stprintf_s(buffer, buffer_len, _T("SLL (IX+(%d))"), ofs); break; - case 0x37: my_stprintf_s(buffer, buffer_len, _T("SLL A=(IX+(%d))"), ofs); break; - case 0x38: my_stprintf_s(buffer, buffer_len, _T("SRL B=(IX+(%d))"), ofs); break; - case 0x39: my_stprintf_s(buffer, buffer_len, _T("SRL C=(IX+(%d))"), ofs); break; - case 0x3a: my_stprintf_s(buffer, buffer_len, _T("SRL D=(IX+(%d))"), ofs); break; - case 0x3b: my_stprintf_s(buffer, buffer_len, _T("SRL E=(IX+(%d))"), ofs); break; - case 0x3c: my_stprintf_s(buffer, buffer_len, _T("SRL H=(IX+(%d))"), ofs); break; - case 0x3d: my_stprintf_s(buffer, buffer_len, _T("SRL L=(IX+(%d))"), ofs); break; - case 0x3e: my_stprintf_s(buffer, buffer_len, _T("SRL (IX+(%d))"), ofs); break; - case 0x3f: my_stprintf_s(buffer, buffer_len, _T("SRL A=(IX+(%d))"), ofs); break; - case 0x40: my_stprintf_s(buffer, buffer_len, _T("BIT 0, B=(IX+(%d))"), ofs); break; - case 0x41: my_stprintf_s(buffer, buffer_len, _T("BIT 0, C=(IX+(%d))"), ofs); break; - case 0x42: my_stprintf_s(buffer, buffer_len, _T("BIT 0, D=(IX+(%d))"), ofs); break; - case 0x43: my_stprintf_s(buffer, buffer_len, _T("BIT 0, E=(IX+(%d))"), ofs); break; - case 0x44: my_stprintf_s(buffer, buffer_len, _T("BIT 0, H=(IX+(%d))"), ofs); break; - case 0x45: my_stprintf_s(buffer, buffer_len, _T("BIT 0, L=(IX+(%d))"), ofs); break; - case 0x46: my_stprintf_s(buffer, buffer_len, _T("BIT 0, (IX+(%d))"), ofs); break; - case 0x47: my_stprintf_s(buffer, buffer_len, _T("BIT 0, A=(IX+(%d))"), ofs); break; - case 0x48: my_stprintf_s(buffer, buffer_len, _T("BIT 1, B=(IX+(%d))"), ofs); break; - case 0x49: my_stprintf_s(buffer, buffer_len, _T("BIT 1, C=(IX+(%d))"), ofs); break; - case 0x4a: my_stprintf_s(buffer, buffer_len, _T("BIT 1, D=(IX+(%d))"), ofs); break; - case 0x4b: my_stprintf_s(buffer, buffer_len, _T("BIT 1, E=(IX+(%d))"), ofs); break; - case 0x4c: my_stprintf_s(buffer, buffer_len, _T("BIT 1, H=(IX+(%d))"), ofs); break; - case 0x4d: my_stprintf_s(buffer, buffer_len, _T("BIT 1, L=(IX+(%d))"), ofs); break; - case 0x4e: my_stprintf_s(buffer, buffer_len, _T("BIT 1, (IX+(%d))"), ofs); break; - case 0x4f: my_stprintf_s(buffer, buffer_len, _T("BIT 1, A=(IX+(%d))"), ofs); break; - case 0x50: my_stprintf_s(buffer, buffer_len, _T("BIT 2, B=(IX+(%d))"), ofs); break; - case 0x51: my_stprintf_s(buffer, buffer_len, _T("BIT 2, C=(IX+(%d))"), ofs); break; - case 0x52: my_stprintf_s(buffer, buffer_len, _T("BIT 2, D=(IX+(%d))"), ofs); break; - case 0x53: my_stprintf_s(buffer, buffer_len, _T("BIT 2, E=(IX+(%d))"), ofs); break; - case 0x54: my_stprintf_s(buffer, buffer_len, _T("BIT 2, H=(IX+(%d))"), ofs); break; - case 0x55: my_stprintf_s(buffer, buffer_len, _T("BIT 2, L=(IX+(%d))"), ofs); break; - case 0x56: my_stprintf_s(buffer, buffer_len, _T("BIT 2, (IX+(%d))"), ofs); break; - case 0x57: my_stprintf_s(buffer, buffer_len, _T("BIT 2, A=(IX+(%d))"), ofs); break; - case 0x58: my_stprintf_s(buffer, buffer_len, _T("BIT 3, B=(IX+(%d))"), ofs); break; - case 0x59: my_stprintf_s(buffer, buffer_len, _T("BIT 3, C=(IX+(%d))"), ofs); break; - case 0x5a: my_stprintf_s(buffer, buffer_len, _T("BIT 3, D=(IX+(%d))"), ofs); break; - case 0x5b: my_stprintf_s(buffer, buffer_len, _T("BIT 3, E=(IX+(%d))"), ofs); break; - case 0x5c: my_stprintf_s(buffer, buffer_len, _T("BIT 3, H=(IX+(%d))"), ofs); break; - case 0x5d: my_stprintf_s(buffer, buffer_len, _T("BIT 3, L=(IX+(%d))"), ofs); break; - case 0x5e: my_stprintf_s(buffer, buffer_len, _T("BIT 3, (IX+(%d))"), ofs); break; - case 0x5f: my_stprintf_s(buffer, buffer_len, _T("BIT 3, A=(IX+(%d))"), ofs); break; - case 0x60: my_stprintf_s(buffer, buffer_len, _T("BIT 4, B=(IX+(%d))"), ofs); break; - case 0x61: my_stprintf_s(buffer, buffer_len, _T("BIT 4, C=(IX+(%d))"), ofs); break; - case 0x62: my_stprintf_s(buffer, buffer_len, _T("BIT 4, D=(IX+(%d))"), ofs); break; - case 0x63: my_stprintf_s(buffer, buffer_len, _T("BIT 4, E=(IX+(%d))"), ofs); break; - case 0x64: my_stprintf_s(buffer, buffer_len, _T("BIT 4, H=(IX+(%d))"), ofs); break; - case 0x65: my_stprintf_s(buffer, buffer_len, _T("BIT 4, L=(IX+(%d))"), ofs); break; - case 0x66: my_stprintf_s(buffer, buffer_len, _T("BIT 4, (IX+(%d))"), ofs); break; - case 0x67: my_stprintf_s(buffer, buffer_len, _T("BIT 4, A=(IX+(%d))"), ofs); break; - case 0x68: my_stprintf_s(buffer, buffer_len, _T("BIT 5, B=(IX+(%d))"), ofs); break; - case 0x69: my_stprintf_s(buffer, buffer_len, _T("BIT 5, C=(IX+(%d))"), ofs); break; - case 0x6a: my_stprintf_s(buffer, buffer_len, _T("BIT 5, D=(IX+(%d))"), ofs); break; - case 0x6b: my_stprintf_s(buffer, buffer_len, _T("BIT 5, E=(IX+(%d))"), ofs); break; - case 0x6c: my_stprintf_s(buffer, buffer_len, _T("BIT 5, H=(IX+(%d))"), ofs); break; - case 0x6d: my_stprintf_s(buffer, buffer_len, _T("BIT 5, L=(IX+(%d))"), ofs); break; - case 0x6e: my_stprintf_s(buffer, buffer_len, _T("BIT 5, (IX+(%d))"), ofs); break; - case 0x6f: my_stprintf_s(buffer, buffer_len, _T("BIT 5, A=(IX+(%d))"), ofs); break; - case 0x70: my_stprintf_s(buffer, buffer_len, _T("BIT 6, B=(IX+(%d))"), ofs); break; - case 0x71: my_stprintf_s(buffer, buffer_len, _T("BIT 6, C=(IX+(%d))"), ofs); break; - case 0x72: my_stprintf_s(buffer, buffer_len, _T("BIT 6, D=(IX+(%d))"), ofs); break; - case 0x73: my_stprintf_s(buffer, buffer_len, _T("BIT 6, E=(IX+(%d))"), ofs); break; - case 0x74: my_stprintf_s(buffer, buffer_len, _T("BIT 6, H=(IX+(%d))"), ofs); break; - case 0x75: my_stprintf_s(buffer, buffer_len, _T("BIT 6, L=(IX+(%d))"), ofs); break; - case 0x76: my_stprintf_s(buffer, buffer_len, _T("BIT 6, (IX+(%d))"), ofs); break; - case 0x77: my_stprintf_s(buffer, buffer_len, _T("BIT 6, A=(IX+(%d))"), ofs); break; - case 0x78: my_stprintf_s(buffer, buffer_len, _T("BIT 7, B=(IX+(%d))"), ofs); break; - case 0x79: my_stprintf_s(buffer, buffer_len, _T("BIT 7, C=(IX+(%d))"), ofs); break; - case 0x7a: my_stprintf_s(buffer, buffer_len, _T("BIT 7, D=(IX+(%d))"), ofs); break; - case 0x7b: my_stprintf_s(buffer, buffer_len, _T("BIT 7, E=(IX+(%d))"), ofs); break; - case 0x7c: my_stprintf_s(buffer, buffer_len, _T("BIT 7, H=(IX+(%d))"), ofs); break; - case 0x7d: my_stprintf_s(buffer, buffer_len, _T("BIT 7, L=(IX+(%d))"), ofs); break; - case 0x7e: my_stprintf_s(buffer, buffer_len, _T("BIT 7, (IX+(%d))"), ofs); break; - case 0x7f: my_stprintf_s(buffer, buffer_len, _T("BIT 7, A=(IX+(%d))"), ofs); break; - case 0x80: my_stprintf_s(buffer, buffer_len, _T("RES 0, B=(IX+(%d))"), ofs); break; - case 0x81: my_stprintf_s(buffer, buffer_len, _T("RES 0, C=(IX+(%d))"), ofs); break; - case 0x82: my_stprintf_s(buffer, buffer_len, _T("RES 0, D=(IX+(%d))"), ofs); break; - case 0x83: my_stprintf_s(buffer, buffer_len, _T("RES 0, E=(IX+(%d))"), ofs); break; - case 0x84: my_stprintf_s(buffer, buffer_len, _T("RES 0, H=(IX+(%d))"), ofs); break; - case 0x85: my_stprintf_s(buffer, buffer_len, _T("RES 0, L=(IX+(%d))"), ofs); break; - case 0x86: my_stprintf_s(buffer, buffer_len, _T("RES 0, (IX+(%d))"), ofs); break; - case 0x87: my_stprintf_s(buffer, buffer_len, _T("RES 0, A=(IX+(%d))"), ofs); break; - case 0x88: my_stprintf_s(buffer, buffer_len, _T("RES 1, B=(IX+(%d))"), ofs); break; - case 0x89: my_stprintf_s(buffer, buffer_len, _T("RES 1, C=(IX+(%d))"), ofs); break; - case 0x8a: my_stprintf_s(buffer, buffer_len, _T("RES 1, D=(IX+(%d))"), ofs); break; - case 0x8b: my_stprintf_s(buffer, buffer_len, _T("RES 1, E=(IX+(%d))"), ofs); break; - case 0x8c: my_stprintf_s(buffer, buffer_len, _T("RES 1, H=(IX+(%d))"), ofs); break; - case 0x8d: my_stprintf_s(buffer, buffer_len, _T("RES 1, L=(IX+(%d))"), ofs); break; - case 0x8e: my_stprintf_s(buffer, buffer_len, _T("RES 1, (IX+(%d))"), ofs); break; - case 0x8f: my_stprintf_s(buffer, buffer_len, _T("RES 1, A=(IX+(%d))"), ofs); break; - case 0x90: my_stprintf_s(buffer, buffer_len, _T("RES 2, B=(IX+(%d))"), ofs); break; - case 0x91: my_stprintf_s(buffer, buffer_len, _T("RES 2, C=(IX+(%d))"), ofs); break; - case 0x92: my_stprintf_s(buffer, buffer_len, _T("RES 2, D=(IX+(%d))"), ofs); break; - case 0x93: my_stprintf_s(buffer, buffer_len, _T("RES 2, E=(IX+(%d))"), ofs); break; - case 0x94: my_stprintf_s(buffer, buffer_len, _T("RES 2, H=(IX+(%d))"), ofs); break; - case 0x95: my_stprintf_s(buffer, buffer_len, _T("RES 2, L=(IX+(%d))"), ofs); break; - case 0x96: my_stprintf_s(buffer, buffer_len, _T("RES 2, (IX+(%d))"), ofs); break; - case 0x97: my_stprintf_s(buffer, buffer_len, _T("RES 2, A=(IX+(%d))"), ofs); break; - case 0x98: my_stprintf_s(buffer, buffer_len, _T("RES 3, B=(IX+(%d))"), ofs); break; - case 0x99: my_stprintf_s(buffer, buffer_len, _T("RES 3, C=(IX+(%d))"), ofs); break; - case 0x9a: my_stprintf_s(buffer, buffer_len, _T("RES 3, D=(IX+(%d))"), ofs); break; - case 0x9b: my_stprintf_s(buffer, buffer_len, _T("RES 3, E=(IX+(%d))"), ofs); break; - case 0x9c: my_stprintf_s(buffer, buffer_len, _T("RES 3, H=(IX+(%d))"), ofs); break; - case 0x9d: my_stprintf_s(buffer, buffer_len, _T("RES 3, L=(IX+(%d))"), ofs); break; - case 0x9e: my_stprintf_s(buffer, buffer_len, _T("RES 3, (IX+(%d))"), ofs); break; - case 0x9f: my_stprintf_s(buffer, buffer_len, _T("RES 3, A=(IX+(%d))"), ofs); break; - case 0xa0: my_stprintf_s(buffer, buffer_len, _T("RES 4, B=(IX+(%d))"), ofs); break; - case 0xa1: my_stprintf_s(buffer, buffer_len, _T("RES 4, C=(IX+(%d))"), ofs); break; - case 0xa2: my_stprintf_s(buffer, buffer_len, _T("RES 4, D=(IX+(%d))"), ofs); break; - case 0xa3: my_stprintf_s(buffer, buffer_len, _T("RES 4, E=(IX+(%d))"), ofs); break; - case 0xa4: my_stprintf_s(buffer, buffer_len, _T("RES 4, H=(IX+(%d))"), ofs); break; - case 0xa5: my_stprintf_s(buffer, buffer_len, _T("RES 4, L=(IX+(%d))"), ofs); break; - case 0xa6: my_stprintf_s(buffer, buffer_len, _T("RES 4, (IX+(%d))"), ofs); break; - case 0xa7: my_stprintf_s(buffer, buffer_len, _T("RES 4, A=(IX+(%d))"), ofs); break; - case 0xa8: my_stprintf_s(buffer, buffer_len, _T("RES 5, B=(IX+(%d))"), ofs); break; - case 0xa9: my_stprintf_s(buffer, buffer_len, _T("RES 5, C=(IX+(%d))"), ofs); break; - case 0xaa: my_stprintf_s(buffer, buffer_len, _T("RES 5, D=(IX+(%d))"), ofs); break; - case 0xab: my_stprintf_s(buffer, buffer_len, _T("RES 5, E=(IX+(%d))"), ofs); break; - case 0xac: my_stprintf_s(buffer, buffer_len, _T("RES 5, H=(IX+(%d))"), ofs); break; - case 0xad: my_stprintf_s(buffer, buffer_len, _T("RES 5, L=(IX+(%d))"), ofs); break; - case 0xae: my_stprintf_s(buffer, buffer_len, _T("RES 5, (IX+(%d))"), ofs); break; - case 0xaf: my_stprintf_s(buffer, buffer_len, _T("RES 5, A=(IX+(%d))"), ofs); break; - case 0xb0: my_stprintf_s(buffer, buffer_len, _T("RES 6, B=(IX+(%d))"), ofs); break; - case 0xb1: my_stprintf_s(buffer, buffer_len, _T("RES 6, C=(IX+(%d))"), ofs); break; - case 0xb2: my_stprintf_s(buffer, buffer_len, _T("RES 6, D=(IX+(%d))"), ofs); break; - case 0xb3: my_stprintf_s(buffer, buffer_len, _T("RES 6, E=(IX+(%d))"), ofs); break; - case 0xb4: my_stprintf_s(buffer, buffer_len, _T("RES 6, H=(IX+(%d))"), ofs); break; - case 0xb5: my_stprintf_s(buffer, buffer_len, _T("RES 6, L=(IX+(%d))"), ofs); break; - case 0xb6: my_stprintf_s(buffer, buffer_len, _T("RES 6, (IX+(%d))"), ofs); break; - case 0xb7: my_stprintf_s(buffer, buffer_len, _T("RES 6, A=(IX+(%d))"), ofs); break; - case 0xb8: my_stprintf_s(buffer, buffer_len, _T("RES 7, B=(IX+(%d))"), ofs); break; - case 0xb9: my_stprintf_s(buffer, buffer_len, _T("RES 7, C=(IX+(%d))"), ofs); break; - case 0xba: my_stprintf_s(buffer, buffer_len, _T("RES 7, D=(IX+(%d))"), ofs); break; - case 0xbb: my_stprintf_s(buffer, buffer_len, _T("RES 7, E=(IX+(%d))"), ofs); break; - case 0xbc: my_stprintf_s(buffer, buffer_len, _T("RES 7, H=(IX+(%d))"), ofs); break; - case 0xbd: my_stprintf_s(buffer, buffer_len, _T("RES 7, L=(IX+(%d))"), ofs); break; - case 0xbe: my_stprintf_s(buffer, buffer_len, _T("RES 7, (IX+(%d))"), ofs); break; - case 0xbf: my_stprintf_s(buffer, buffer_len, _T("RES 7, A=(IX+(%d))"), ofs); break; - case 0xc0: my_stprintf_s(buffer, buffer_len, _T("SET 0, B=(IX+(%d))"), ofs); break; - case 0xc1: my_stprintf_s(buffer, buffer_len, _T("SET 0, C=(IX+(%d))"), ofs); break; - case 0xc2: my_stprintf_s(buffer, buffer_len, _T("SET 0, D=(IX+(%d))"), ofs); break; - case 0xc3: my_stprintf_s(buffer, buffer_len, _T("SET 0, E=(IX+(%d))"), ofs); break; - case 0xc4: my_stprintf_s(buffer, buffer_len, _T("SET 0, H=(IX+(%d))"), ofs); break; - case 0xc5: my_stprintf_s(buffer, buffer_len, _T("SET 0, L=(IX+(%d))"), ofs); break; - case 0xc6: my_stprintf_s(buffer, buffer_len, _T("SET 0, (IX+(%d))"), ofs); break; - case 0xc7: my_stprintf_s(buffer, buffer_len, _T("SET 0, A=(IX+(%d))"), ofs); break; - case 0xc8: my_stprintf_s(buffer, buffer_len, _T("SET 1, B=(IX+(%d))"), ofs); break; - case 0xc9: my_stprintf_s(buffer, buffer_len, _T("SET 1, C=(IX+(%d))"), ofs); break; - case 0xca: my_stprintf_s(buffer, buffer_len, _T("SET 1, D=(IX+(%d))"), ofs); break; - case 0xcb: my_stprintf_s(buffer, buffer_len, _T("SET 1, E=(IX+(%d))"), ofs); break; - case 0xcc: my_stprintf_s(buffer, buffer_len, _T("SET 1, H=(IX+(%d))"), ofs); break; - case 0xcd: my_stprintf_s(buffer, buffer_len, _T("SET 1, L=(IX+(%d))"), ofs); break; - case 0xce: my_stprintf_s(buffer, buffer_len, _T("SET 1, (IX+(%d))"), ofs); break; - case 0xcf: my_stprintf_s(buffer, buffer_len, _T("SET 1, A=(IX+(%d))"), ofs); break; - case 0xd0: my_stprintf_s(buffer, buffer_len, _T("SET 2, B=(IX+(%d))"), ofs); break; - case 0xd1: my_stprintf_s(buffer, buffer_len, _T("SET 2, C=(IX+(%d))"), ofs); break; - case 0xd2: my_stprintf_s(buffer, buffer_len, _T("SET 2, D=(IX+(%d))"), ofs); break; - case 0xd3: my_stprintf_s(buffer, buffer_len, _T("SET 2, E=(IX+(%d))"), ofs); break; - case 0xd4: my_stprintf_s(buffer, buffer_len, _T("SET 2, H=(IX+(%d))"), ofs); break; - case 0xd5: my_stprintf_s(buffer, buffer_len, _T("SET 2, L=(IX+(%d))"), ofs); break; - case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SET 2, (IX+(%d))"), ofs); break; - case 0xd7: my_stprintf_s(buffer, buffer_len, _T("SET 2, A=(IX+(%d))"), ofs); break; - case 0xd8: my_stprintf_s(buffer, buffer_len, _T("SET 3, B=(IX+(%d))"), ofs); break; - case 0xd9: my_stprintf_s(buffer, buffer_len, _T("SET 3, C=(IX+(%d))"), ofs); break; - case 0xda: my_stprintf_s(buffer, buffer_len, _T("SET 3, D=(IX+(%d))"), ofs); break; - case 0xdb: my_stprintf_s(buffer, buffer_len, _T("SET 3, E=(IX+(%d))"), ofs); break; - case 0xdc: my_stprintf_s(buffer, buffer_len, _T("SET 3, H=(IX+(%d))"), ofs); break; - case 0xdd: my_stprintf_s(buffer, buffer_len, _T("SET 3, L=(IX+(%d))"), ofs); break; - case 0xde: my_stprintf_s(buffer, buffer_len, _T("SET 3, (IX+(%d))"), ofs); break; - case 0xdf: my_stprintf_s(buffer, buffer_len, _T("SET 3, A=(IX+(%d))"), ofs); break; - case 0xe0: my_stprintf_s(buffer, buffer_len, _T("SET 4, B=(IX+(%d))"), ofs); break; - case 0xe1: my_stprintf_s(buffer, buffer_len, _T("SET 4, C=(IX+(%d))"), ofs); break; - case 0xe2: my_stprintf_s(buffer, buffer_len, _T("SET 4, D=(IX+(%d))"), ofs); break; - case 0xe3: my_stprintf_s(buffer, buffer_len, _T("SET 4, E=(IX+(%d))"), ofs); break; - case 0xe4: my_stprintf_s(buffer, buffer_len, _T("SET 4, H=(IX+(%d))"), ofs); break; - case 0xe5: my_stprintf_s(buffer, buffer_len, _T("SET 4, L=(IX+(%d))"), ofs); break; - case 0xe6: my_stprintf_s(buffer, buffer_len, _T("SET 4, (IX+(%d))"), ofs); break; - case 0xe7: my_stprintf_s(buffer, buffer_len, _T("SET 4, A=(IX+(%d))"), ofs); break; - case 0xe8: my_stprintf_s(buffer, buffer_len, _T("SET 5, B=(IX+(%d))"), ofs); break; - case 0xe9: my_stprintf_s(buffer, buffer_len, _T("SET 5, C=(IX+(%d))"), ofs); break; - case 0xea: my_stprintf_s(buffer, buffer_len, _T("SET 5, D=(IX+(%d))"), ofs); break; - case 0xeb: my_stprintf_s(buffer, buffer_len, _T("SET 5, E=(IX+(%d))"), ofs); break; - case 0xec: my_stprintf_s(buffer, buffer_len, _T("SET 5, H=(IX+(%d))"), ofs); break; - case 0xed: my_stprintf_s(buffer, buffer_len, _T("SET 5, L=(IX+(%d))"), ofs); break; - case 0xee: my_stprintf_s(buffer, buffer_len, _T("SET 5, (IX+(%d))"), ofs); break; - case 0xef: my_stprintf_s(buffer, buffer_len, _T("SET 5, A=(IX+(%d))"), ofs); break; - case 0xf0: my_stprintf_s(buffer, buffer_len, _T("SET 6, B=(IX+(%d))"), ofs); break; - case 0xf1: my_stprintf_s(buffer, buffer_len, _T("SET 6, C=(IX+(%d))"), ofs); break; - case 0xf2: my_stprintf_s(buffer, buffer_len, _T("SET 6, D=(IX+(%d))"), ofs); break; - case 0xf3: my_stprintf_s(buffer, buffer_len, _T("SET 6, E=(IX+(%d))"), ofs); break; - case 0xf4: my_stprintf_s(buffer, buffer_len, _T("SET 6, H=(IX+(%d))"), ofs); break; - case 0xf5: my_stprintf_s(buffer, buffer_len, _T("SET 6, L=(IX+(%d))"), ofs); break; - case 0xf6: my_stprintf_s(buffer, buffer_len, _T("SET 6, (IX+(%d))"), ofs); break; - case 0xf7: my_stprintf_s(buffer, buffer_len, _T("SET 6, A=(IX+(%d))"), ofs); break; - case 0xf8: my_stprintf_s(buffer, buffer_len, _T("SET 7, B=(IX+(%d))"), ofs); break; - case 0xf9: my_stprintf_s(buffer, buffer_len, _T("SET 7, C=(IX+(%d))"), ofs); break; - case 0xfa: my_stprintf_s(buffer, buffer_len, _T("SET 7, D=(IX+(%d))"), ofs); break; - case 0xfb: my_stprintf_s(buffer, buffer_len, _T("SET 7, E=(IX+(%d))"), ofs); break; - case 0xfc: my_stprintf_s(buffer, buffer_len, _T("SET 7, H=(IX+(%d))"), ofs); break; - case 0xfd: my_stprintf_s(buffer, buffer_len, _T("SET 7, L=(IX+(%d))"), ofs); break; - case 0xfe: my_stprintf_s(buffer, buffer_len, _T("SET 7, (IX+(%d))"), ofs); break; - case 0xff: my_stprintf_s(buffer, buffer_len, _T("SET 7, A=(IX+(%d))"), ofs); break; -#if defined(_MSC_VER) && (_MSC_VER >= 1200) - default: __assume(0); -#endif - } -} - -static void dasm_fdcb(uint32_t pc, _TCHAR *buffer, size_t buffer_len, symbol_t *first_symbol) -{ - int8_t ofs = debug_fetch8_rel(); - uint8_t code = debug_fetch8(); - - switch(code) { - case 0x00: my_stprintf_s(buffer, buffer_len, _T("RLC B=(IY+(%d))"), ofs); break; - case 0x01: my_stprintf_s(buffer, buffer_len, _T("RLC C=(IY+(%d))"), ofs); break; - case 0x02: my_stprintf_s(buffer, buffer_len, _T("RLC D=(IY+(%d))"), ofs); break; - case 0x03: my_stprintf_s(buffer, buffer_len, _T("RLC E=(IY+(%d))"), ofs); break; - case 0x04: my_stprintf_s(buffer, buffer_len, _T("RLC H=(IY+(%d))"), ofs); break; - case 0x05: my_stprintf_s(buffer, buffer_len, _T("RLC L=(IY+(%d))"), ofs); break; - case 0x06: my_stprintf_s(buffer, buffer_len, _T("RLC (IY+(%d))"), ofs); break; - case 0x07: my_stprintf_s(buffer, buffer_len, _T("RLC A=(IY+(%d))"), ofs); break; - case 0x08: my_stprintf_s(buffer, buffer_len, _T("RRC B=(IY+(%d))"), ofs); break; - case 0x09: my_stprintf_s(buffer, buffer_len, _T("RRC C=(IY+(%d))"), ofs); break; - case 0x0a: my_stprintf_s(buffer, buffer_len, _T("RRC D=(IY+(%d))"), ofs); break; - case 0x0b: my_stprintf_s(buffer, buffer_len, _T("RRC E=(IY+(%d))"), ofs); break; - case 0x0c: my_stprintf_s(buffer, buffer_len, _T("RRC H=(IY+(%d))"), ofs); break; - case 0x0d: my_stprintf_s(buffer, buffer_len, _T("RRC L=(IY+(%d))"), ofs); break; - case 0x0e: my_stprintf_s(buffer, buffer_len, _T("RRC (IY+(%d))"), ofs); break; - case 0x0f: my_stprintf_s(buffer, buffer_len, _T("RRC A=(IY+(%d))"), ofs); break; - case 0x10: my_stprintf_s(buffer, buffer_len, _T("RL B=(IY+(%d))"), ofs); break; - case 0x11: my_stprintf_s(buffer, buffer_len, _T("RL C=(IY+(%d))"), ofs); break; - case 0x12: my_stprintf_s(buffer, buffer_len, _T("RL D=(IY+(%d))"), ofs); break; - case 0x13: my_stprintf_s(buffer, buffer_len, _T("RL E=(IY+(%d))"), ofs); break; - case 0x14: my_stprintf_s(buffer, buffer_len, _T("RL H=(IY+(%d))"), ofs); break; - case 0x15: my_stprintf_s(buffer, buffer_len, _T("RL L=(IY+(%d))"), ofs); break; - case 0x16: my_stprintf_s(buffer, buffer_len, _T("RL (IY+(%d))"), ofs); break; - case 0x17: my_stprintf_s(buffer, buffer_len, _T("RL A=(IY+(%d))"), ofs); break; - case 0x18: my_stprintf_s(buffer, buffer_len, _T("RR B=(IY+(%d))"), ofs); break; - case 0x19: my_stprintf_s(buffer, buffer_len, _T("RR C=(IY+(%d))"), ofs); break; - case 0x1a: my_stprintf_s(buffer, buffer_len, _T("RR D=(IY+(%d))"), ofs); break; - case 0x1b: my_stprintf_s(buffer, buffer_len, _T("RR E=(IY+(%d))"), ofs); break; - case 0x1c: my_stprintf_s(buffer, buffer_len, _T("RR H=(IY+(%d))"), ofs); break; - case 0x1d: my_stprintf_s(buffer, buffer_len, _T("RR L=(IY+(%d))"), ofs); break; - case 0x1e: my_stprintf_s(buffer, buffer_len, _T("RR (IY+(%d))"), ofs); break; - case 0x1f: my_stprintf_s(buffer, buffer_len, _T("RR A=(IY+(%d))"), ofs); break; - case 0x20: my_stprintf_s(buffer, buffer_len, _T("SLA B=(IY+(%d))"), ofs); break; - case 0x21: my_stprintf_s(buffer, buffer_len, _T("SLA C=(IY+(%d))"), ofs); break; - case 0x22: my_stprintf_s(buffer, buffer_len, _T("SLA D=(IY+(%d))"), ofs); break; - case 0x23: my_stprintf_s(buffer, buffer_len, _T("SLA E=(IY+(%d))"), ofs); break; - case 0x24: my_stprintf_s(buffer, buffer_len, _T("SLA H=(IY+(%d))"), ofs); break; - case 0x25: my_stprintf_s(buffer, buffer_len, _T("SLA L=(IY+(%d))"), ofs); break; - case 0x26: my_stprintf_s(buffer, buffer_len, _T("SLA (IY+(%d))"), ofs); break; - case 0x27: my_stprintf_s(buffer, buffer_len, _T("SLA A=(IY+(%d))"), ofs); break; - case 0x28: my_stprintf_s(buffer, buffer_len, _T("SRA B=(IY+(%d))"), ofs); break; - case 0x29: my_stprintf_s(buffer, buffer_len, _T("SRA C=(IY+(%d))"), ofs); break; - case 0x2a: my_stprintf_s(buffer, buffer_len, _T("SRA D=(IY+(%d))"), ofs); break; - case 0x2b: my_stprintf_s(buffer, buffer_len, _T("SRA E=(IY+(%d))"), ofs); break; - case 0x2c: my_stprintf_s(buffer, buffer_len, _T("SRA H=(IY+(%d))"), ofs); break; - case 0x2d: my_stprintf_s(buffer, buffer_len, _T("SRA L=(IY+(%d))"), ofs); break; - case 0x2e: my_stprintf_s(buffer, buffer_len, _T("SRA (IY+(%d))"), ofs); break; - case 0x2f: my_stprintf_s(buffer, buffer_len, _T("SRA A=(IY+(%d))"), ofs); break; - case 0x30: my_stprintf_s(buffer, buffer_len, _T("SLL B=(IY+(%d))"), ofs); break; - case 0x31: my_stprintf_s(buffer, buffer_len, _T("SLL C=(IY+(%d))"), ofs); break; - case 0x32: my_stprintf_s(buffer, buffer_len, _T("SLL D=(IY+(%d))"), ofs); break; - case 0x33: my_stprintf_s(buffer, buffer_len, _T("SLL E=(IY+(%d))"), ofs); break; - case 0x34: my_stprintf_s(buffer, buffer_len, _T("SLL H=(IY+(%d))"), ofs); break; - case 0x35: my_stprintf_s(buffer, buffer_len, _T("SLL L=(IY+(%d))"), ofs); break; - case 0x36: my_stprintf_s(buffer, buffer_len, _T("SLL (IY+(%d))"), ofs); break; - case 0x37: my_stprintf_s(buffer, buffer_len, _T("SLL A=(IY+(%d))"), ofs); break; - case 0x38: my_stprintf_s(buffer, buffer_len, _T("SRL B=(IY+(%d))"), ofs); break; - case 0x39: my_stprintf_s(buffer, buffer_len, _T("SRL C=(IY+(%d))"), ofs); break; - case 0x3a: my_stprintf_s(buffer, buffer_len, _T("SRL D=(IY+(%d))"), ofs); break; - case 0x3b: my_stprintf_s(buffer, buffer_len, _T("SRL E=(IY+(%d))"), ofs); break; - case 0x3c: my_stprintf_s(buffer, buffer_len, _T("SRL H=(IY+(%d))"), ofs); break; - case 0x3d: my_stprintf_s(buffer, buffer_len, _T("SRL L=(IY+(%d))"), ofs); break; - case 0x3e: my_stprintf_s(buffer, buffer_len, _T("SRL (IY+(%d))"), ofs); break; - case 0x3f: my_stprintf_s(buffer, buffer_len, _T("SRL A=(IY+(%d))"), ofs); break; - case 0x40: my_stprintf_s(buffer, buffer_len, _T("BIT 0, B=(IY+(%d))"), ofs); break; - case 0x41: my_stprintf_s(buffer, buffer_len, _T("BIT 0, C=(IY+(%d))"), ofs); break; - case 0x42: my_stprintf_s(buffer, buffer_len, _T("BIT 0, D=(IY+(%d))"), ofs); break; - case 0x43: my_stprintf_s(buffer, buffer_len, _T("BIT 0, E=(IY+(%d))"), ofs); break; - case 0x44: my_stprintf_s(buffer, buffer_len, _T("BIT 0, H=(IY+(%d))"), ofs); break; - case 0x45: my_stprintf_s(buffer, buffer_len, _T("BIT 0, L=(IY+(%d))"), ofs); break; - case 0x46: my_stprintf_s(buffer, buffer_len, _T("BIT 0, (IY+(%d))"), ofs); break; - case 0x47: my_stprintf_s(buffer, buffer_len, _T("BIT 0, A=(IY+(%d))"), ofs); break; - case 0x48: my_stprintf_s(buffer, buffer_len, _T("BIT 1, B=(IY+(%d))"), ofs); break; - case 0x49: my_stprintf_s(buffer, buffer_len, _T("BIT 1, C=(IY+(%d))"), ofs); break; - case 0x4a: my_stprintf_s(buffer, buffer_len, _T("BIT 1, D=(IY+(%d))"), ofs); break; - case 0x4b: my_stprintf_s(buffer, buffer_len, _T("BIT 1, E=(IY+(%d))"), ofs); break; - case 0x4c: my_stprintf_s(buffer, buffer_len, _T("BIT 1, H=(IY+(%d))"), ofs); break; - case 0x4d: my_stprintf_s(buffer, buffer_len, _T("BIT 1, L=(IY+(%d))"), ofs); break; - case 0x4e: my_stprintf_s(buffer, buffer_len, _T("BIT 1, (IY+(%d))"), ofs); break; - case 0x4f: my_stprintf_s(buffer, buffer_len, _T("BIT 1, A=(IY+(%d))"), ofs); break; - case 0x50: my_stprintf_s(buffer, buffer_len, _T("BIT 2, B=(IY+(%d))"), ofs); break; - case 0x51: my_stprintf_s(buffer, buffer_len, _T("BIT 2, C=(IY+(%d))"), ofs); break; - case 0x52: my_stprintf_s(buffer, buffer_len, _T("BIT 2, D=(IY+(%d))"), ofs); break; - case 0x53: my_stprintf_s(buffer, buffer_len, _T("BIT 2, E=(IY+(%d))"), ofs); break; - case 0x54: my_stprintf_s(buffer, buffer_len, _T("BIT 2, H=(IY+(%d))"), ofs); break; - case 0x55: my_stprintf_s(buffer, buffer_len, _T("BIT 2, L=(IY+(%d))"), ofs); break; - case 0x56: my_stprintf_s(buffer, buffer_len, _T("BIT 2, (IY+(%d))"), ofs); break; - case 0x57: my_stprintf_s(buffer, buffer_len, _T("BIT 2, A=(IY+(%d))"), ofs); break; - case 0x58: my_stprintf_s(buffer, buffer_len, _T("BIT 3, B=(IY+(%d))"), ofs); break; - case 0x59: my_stprintf_s(buffer, buffer_len, _T("BIT 3, C=(IY+(%d))"), ofs); break; - case 0x5a: my_stprintf_s(buffer, buffer_len, _T("BIT 3, D=(IY+(%d))"), ofs); break; - case 0x5b: my_stprintf_s(buffer, buffer_len, _T("BIT 3, E=(IY+(%d))"), ofs); break; - case 0x5c: my_stprintf_s(buffer, buffer_len, _T("BIT 3, H=(IY+(%d))"), ofs); break; - case 0x5d: my_stprintf_s(buffer, buffer_len, _T("BIT 3, L=(IY+(%d))"), ofs); break; - case 0x5e: my_stprintf_s(buffer, buffer_len, _T("BIT 3, (IY+(%d))"), ofs); break; - case 0x5f: my_stprintf_s(buffer, buffer_len, _T("BIT 3, A=(IY+(%d))"), ofs); break; - case 0x60: my_stprintf_s(buffer, buffer_len, _T("BIT 4, B=(IY+(%d))"), ofs); break; - case 0x61: my_stprintf_s(buffer, buffer_len, _T("BIT 4, C=(IY+(%d))"), ofs); break; - case 0x62: my_stprintf_s(buffer, buffer_len, _T("BIT 4, D=(IY+(%d))"), ofs); break; - case 0x63: my_stprintf_s(buffer, buffer_len, _T("BIT 4, E=(IY+(%d))"), ofs); break; - case 0x64: my_stprintf_s(buffer, buffer_len, _T("BIT 4, H=(IY+(%d))"), ofs); break; - case 0x65: my_stprintf_s(buffer, buffer_len, _T("BIT 4, L=(IY+(%d))"), ofs); break; - case 0x66: my_stprintf_s(buffer, buffer_len, _T("BIT 4, (IY+(%d))"), ofs); break; - case 0x67: my_stprintf_s(buffer, buffer_len, _T("BIT 4, A=(IY+(%d))"), ofs); break; - case 0x68: my_stprintf_s(buffer, buffer_len, _T("BIT 5, B=(IY+(%d))"), ofs); break; - case 0x69: my_stprintf_s(buffer, buffer_len, _T("BIT 5, C=(IY+(%d))"), ofs); break; - case 0x6a: my_stprintf_s(buffer, buffer_len, _T("BIT 5, D=(IY+(%d))"), ofs); break; - case 0x6b: my_stprintf_s(buffer, buffer_len, _T("BIT 5, E=(IY+(%d))"), ofs); break; - case 0x6c: my_stprintf_s(buffer, buffer_len, _T("BIT 5, H=(IY+(%d))"), ofs); break; - case 0x6d: my_stprintf_s(buffer, buffer_len, _T("BIT 5, L=(IY+(%d))"), ofs); break; - case 0x6e: my_stprintf_s(buffer, buffer_len, _T("BIT 5, (IY+(%d))"), ofs); break; - case 0x6f: my_stprintf_s(buffer, buffer_len, _T("BIT 5, A=(IY+(%d))"), ofs); break; - case 0x70: my_stprintf_s(buffer, buffer_len, _T("BIT 6, B=(IY+(%d))"), ofs); break; - case 0x71: my_stprintf_s(buffer, buffer_len, _T("BIT 6, C=(IY+(%d))"), ofs); break; - case 0x72: my_stprintf_s(buffer, buffer_len, _T("BIT 6, D=(IY+(%d))"), ofs); break; - case 0x73: my_stprintf_s(buffer, buffer_len, _T("BIT 6, E=(IY+(%d))"), ofs); break; - case 0x74: my_stprintf_s(buffer, buffer_len, _T("BIT 6, H=(IY+(%d))"), ofs); break; - case 0x75: my_stprintf_s(buffer, buffer_len, _T("BIT 6, L=(IY+(%d))"), ofs); break; - case 0x76: my_stprintf_s(buffer, buffer_len, _T("BIT 6, (IY+(%d))"), ofs); break; - case 0x77: my_stprintf_s(buffer, buffer_len, _T("BIT 6, A=(IY+(%d))"), ofs); break; - case 0x78: my_stprintf_s(buffer, buffer_len, _T("BIT 7, B=(IY+(%d))"), ofs); break; - case 0x79: my_stprintf_s(buffer, buffer_len, _T("BIT 7, C=(IY+(%d))"), ofs); break; - case 0x7a: my_stprintf_s(buffer, buffer_len, _T("BIT 7, D=(IY+(%d))"), ofs); break; - case 0x7b: my_stprintf_s(buffer, buffer_len, _T("BIT 7, E=(IY+(%d))"), ofs); break; - case 0x7c: my_stprintf_s(buffer, buffer_len, _T("BIT 7, H=(IY+(%d))"), ofs); break; - case 0x7d: my_stprintf_s(buffer, buffer_len, _T("BIT 7, L=(IY+(%d))"), ofs); break; - case 0x7e: my_stprintf_s(buffer, buffer_len, _T("BIT 7, (IY+(%d))"), ofs); break; - case 0x7f: my_stprintf_s(buffer, buffer_len, _T("BIT 7, A=(IY+(%d))"), ofs); break; - case 0x80: my_stprintf_s(buffer, buffer_len, _T("RES 0, B=(IY+(%d))"), ofs); break; - case 0x81: my_stprintf_s(buffer, buffer_len, _T("RES 0, C=(IY+(%d))"), ofs); break; - case 0x82: my_stprintf_s(buffer, buffer_len, _T("RES 0, D=(IY+(%d))"), ofs); break; - case 0x83: my_stprintf_s(buffer, buffer_len, _T("RES 0, E=(IY+(%d))"), ofs); break; - case 0x84: my_stprintf_s(buffer, buffer_len, _T("RES 0, H=(IY+(%d))"), ofs); break; - case 0x85: my_stprintf_s(buffer, buffer_len, _T("RES 0, L=(IY+(%d))"), ofs); break; - case 0x86: my_stprintf_s(buffer, buffer_len, _T("RES 0, (IY+(%d))"), ofs); break; - case 0x87: my_stprintf_s(buffer, buffer_len, _T("RES 0, A=(IY+(%d))"), ofs); break; - case 0x88: my_stprintf_s(buffer, buffer_len, _T("RES 1, B=(IY+(%d))"), ofs); break; - case 0x89: my_stprintf_s(buffer, buffer_len, _T("RES 1, C=(IY+(%d))"), ofs); break; - case 0x8a: my_stprintf_s(buffer, buffer_len, _T("RES 1, D=(IY+(%d))"), ofs); break; - case 0x8b: my_stprintf_s(buffer, buffer_len, _T("RES 1, E=(IY+(%d))"), ofs); break; - case 0x8c: my_stprintf_s(buffer, buffer_len, _T("RES 1, H=(IY+(%d))"), ofs); break; - case 0x8d: my_stprintf_s(buffer, buffer_len, _T("RES 1, L=(IY+(%d))"), ofs); break; - case 0x8e: my_stprintf_s(buffer, buffer_len, _T("RES 1, (IY+(%d))"), ofs); break; - case 0x8f: my_stprintf_s(buffer, buffer_len, _T("RES 1, A=(IY+(%d))"), ofs); break; - case 0x90: my_stprintf_s(buffer, buffer_len, _T("RES 2, B=(IY+(%d))"), ofs); break; - case 0x91: my_stprintf_s(buffer, buffer_len, _T("RES 2, C=(IY+(%d))"), ofs); break; - case 0x92: my_stprintf_s(buffer, buffer_len, _T("RES 2, D=(IY+(%d))"), ofs); break; - case 0x93: my_stprintf_s(buffer, buffer_len, _T("RES 2, E=(IY+(%d))"), ofs); break; - case 0x94: my_stprintf_s(buffer, buffer_len, _T("RES 2, H=(IY+(%d))"), ofs); break; - case 0x95: my_stprintf_s(buffer, buffer_len, _T("RES 2, L=(IY+(%d))"), ofs); break; - case 0x96: my_stprintf_s(buffer, buffer_len, _T("RES 2, (IY+(%d))"), ofs); break; - case 0x97: my_stprintf_s(buffer, buffer_len, _T("RES 2, A=(IY+(%d))"), ofs); break; - case 0x98: my_stprintf_s(buffer, buffer_len, _T("RES 3, B=(IY+(%d))"), ofs); break; - case 0x99: my_stprintf_s(buffer, buffer_len, _T("RES 3, C=(IY+(%d))"), ofs); break; - case 0x9a: my_stprintf_s(buffer, buffer_len, _T("RES 3, D=(IY+(%d))"), ofs); break; - case 0x9b: my_stprintf_s(buffer, buffer_len, _T("RES 3, E=(IY+(%d))"), ofs); break; - case 0x9c: my_stprintf_s(buffer, buffer_len, _T("RES 3, H=(IY+(%d))"), ofs); break; - case 0x9d: my_stprintf_s(buffer, buffer_len, _T("RES 3, L=(IY+(%d))"), ofs); break; - case 0x9e: my_stprintf_s(buffer, buffer_len, _T("RES 3, (IY+(%d))"), ofs); break; - case 0x9f: my_stprintf_s(buffer, buffer_len, _T("RES 3, A=(IY+(%d))"), ofs); break; - case 0xa0: my_stprintf_s(buffer, buffer_len, _T("RES 4, B=(IY+(%d))"), ofs); break; - case 0xa1: my_stprintf_s(buffer, buffer_len, _T("RES 4, C=(IY+(%d))"), ofs); break; - case 0xa2: my_stprintf_s(buffer, buffer_len, _T("RES 4, D=(IY+(%d))"), ofs); break; - case 0xa3: my_stprintf_s(buffer, buffer_len, _T("RES 4, E=(IY+(%d))"), ofs); break; - case 0xa4: my_stprintf_s(buffer, buffer_len, _T("RES 4, H=(IY+(%d))"), ofs); break; - case 0xa5: my_stprintf_s(buffer, buffer_len, _T("RES 4, L=(IY+(%d))"), ofs); break; - case 0xa6: my_stprintf_s(buffer, buffer_len, _T("RES 4, (IY+(%d))"), ofs); break; - case 0xa7: my_stprintf_s(buffer, buffer_len, _T("RES 4, A=(IY+(%d))"), ofs); break; - case 0xa8: my_stprintf_s(buffer, buffer_len, _T("RES 5, B=(IY+(%d))"), ofs); break; - case 0xa9: my_stprintf_s(buffer, buffer_len, _T("RES 5, C=(IY+(%d))"), ofs); break; - case 0xaa: my_stprintf_s(buffer, buffer_len, _T("RES 5, D=(IY+(%d))"), ofs); break; - case 0xab: my_stprintf_s(buffer, buffer_len, _T("RES 5, E=(IY+(%d))"), ofs); break; - case 0xac: my_stprintf_s(buffer, buffer_len, _T("RES 5, H=(IY+(%d))"), ofs); break; - case 0xad: my_stprintf_s(buffer, buffer_len, _T("RES 5, L=(IY+(%d))"), ofs); break; - case 0xae: my_stprintf_s(buffer, buffer_len, _T("RES 5, (IY+(%d))"), ofs); break; - case 0xaf: my_stprintf_s(buffer, buffer_len, _T("RES 5, A=(IY+(%d))"), ofs); break; - case 0xb0: my_stprintf_s(buffer, buffer_len, _T("RES 6, B=(IY+(%d))"), ofs); break; - case 0xb1: my_stprintf_s(buffer, buffer_len, _T("RES 6, C=(IY+(%d))"), ofs); break; - case 0xb2: my_stprintf_s(buffer, buffer_len, _T("RES 6, D=(IY+(%d))"), ofs); break; - case 0xb3: my_stprintf_s(buffer, buffer_len, _T("RES 6, E=(IY+(%d))"), ofs); break; - case 0xb4: my_stprintf_s(buffer, buffer_len, _T("RES 6, H=(IY+(%d))"), ofs); break; - case 0xb5: my_stprintf_s(buffer, buffer_len, _T("RES 6, L=(IY+(%d))"), ofs); break; - case 0xb6: my_stprintf_s(buffer, buffer_len, _T("RES 6, (IY+(%d))"), ofs); break; - case 0xb7: my_stprintf_s(buffer, buffer_len, _T("RES 6, A=(IY+(%d))"), ofs); break; - case 0xb8: my_stprintf_s(buffer, buffer_len, _T("RES 7, B=(IY+(%d))"), ofs); break; - case 0xb9: my_stprintf_s(buffer, buffer_len, _T("RES 7, C=(IY+(%d))"), ofs); break; - case 0xba: my_stprintf_s(buffer, buffer_len, _T("RES 7, D=(IY+(%d))"), ofs); break; - case 0xbb: my_stprintf_s(buffer, buffer_len, _T("RES 7, E=(IY+(%d))"), ofs); break; - case 0xbc: my_stprintf_s(buffer, buffer_len, _T("RES 7, H=(IY+(%d))"), ofs); break; - case 0xbd: my_stprintf_s(buffer, buffer_len, _T("RES 7, L=(IY+(%d))"), ofs); break; - case 0xbe: my_stprintf_s(buffer, buffer_len, _T("RES 7, (IY+(%d))"), ofs); break; - case 0xbf: my_stprintf_s(buffer, buffer_len, _T("RES 7, A=(IY+(%d))"), ofs); break; - case 0xc0: my_stprintf_s(buffer, buffer_len, _T("SET 0, B=(IY+(%d))"), ofs); break; - case 0xc1: my_stprintf_s(buffer, buffer_len, _T("SET 0, C=(IY+(%d))"), ofs); break; - case 0xc2: my_stprintf_s(buffer, buffer_len, _T("SET 0, D=(IY+(%d))"), ofs); break; - case 0xc3: my_stprintf_s(buffer, buffer_len, _T("SET 0, E=(IY+(%d))"), ofs); break; - case 0xc4: my_stprintf_s(buffer, buffer_len, _T("SET 0, H=(IY+(%d))"), ofs); break; - case 0xc5: my_stprintf_s(buffer, buffer_len, _T("SET 0, L=(IY+(%d))"), ofs); break; - case 0xc6: my_stprintf_s(buffer, buffer_len, _T("SET 0, (IY+(%d))"), ofs); break; - case 0xc7: my_stprintf_s(buffer, buffer_len, _T("SET 0, A=(IY+(%d))"), ofs); break; - case 0xc8: my_stprintf_s(buffer, buffer_len, _T("SET 1, B=(IY+(%d))"), ofs); break; - case 0xc9: my_stprintf_s(buffer, buffer_len, _T("SET 1, C=(IY+(%d))"), ofs); break; - case 0xca: my_stprintf_s(buffer, buffer_len, _T("SET 1, D=(IY+(%d))"), ofs); break; - case 0xcb: my_stprintf_s(buffer, buffer_len, _T("SET 1, E=(IY+(%d))"), ofs); break; - case 0xcc: my_stprintf_s(buffer, buffer_len, _T("SET 1, H=(IY+(%d))"), ofs); break; - case 0xcd: my_stprintf_s(buffer, buffer_len, _T("SET 1, L=(IY+(%d))"), ofs); break; - case 0xce: my_stprintf_s(buffer, buffer_len, _T("SET 1, (IY+(%d))"), ofs); break; - case 0xcf: my_stprintf_s(buffer, buffer_len, _T("SET 1, A=(IY+(%d))"), ofs); break; - case 0xd0: my_stprintf_s(buffer, buffer_len, _T("SET 2, B=(IY+(%d))"), ofs); break; - case 0xd1: my_stprintf_s(buffer, buffer_len, _T("SET 2, C=(IY+(%d))"), ofs); break; - case 0xd2: my_stprintf_s(buffer, buffer_len, _T("SET 2, D=(IY+(%d))"), ofs); break; - case 0xd3: my_stprintf_s(buffer, buffer_len, _T("SET 2, E=(IY+(%d))"), ofs); break; - case 0xd4: my_stprintf_s(buffer, buffer_len, _T("SET 2, H=(IY+(%d))"), ofs); break; - case 0xd5: my_stprintf_s(buffer, buffer_len, _T("SET 2, L=(IY+(%d))"), ofs); break; - case 0xd6: my_stprintf_s(buffer, buffer_len, _T("SET 2, (IY+(%d))"), ofs); break; - case 0xd7: my_stprintf_s(buffer, buffer_len, _T("SET 2, A=(IY+(%d))"), ofs); break; - case 0xd8: my_stprintf_s(buffer, buffer_len, _T("SET 3, B=(IY+(%d))"), ofs); break; - case 0xd9: my_stprintf_s(buffer, buffer_len, _T("SET 3, C=(IY+(%d))"), ofs); break; - case 0xda: my_stprintf_s(buffer, buffer_len, _T("SET 3, D=(IY+(%d))"), ofs); break; - case 0xdb: my_stprintf_s(buffer, buffer_len, _T("SET 3, E=(IY+(%d))"), ofs); break; - case 0xdc: my_stprintf_s(buffer, buffer_len, _T("SET 3, H=(IY+(%d))"), ofs); break; - case 0xdd: my_stprintf_s(buffer, buffer_len, _T("SET 3, L=(IY+(%d))"), ofs); break; - case 0xde: my_stprintf_s(buffer, buffer_len, _T("SET 3, (IY+(%d))"), ofs); break; - case 0xdf: my_stprintf_s(buffer, buffer_len, _T("SET 3, A=(IY+(%d))"), ofs); break; - case 0xe0: my_stprintf_s(buffer, buffer_len, _T("SET 4, B=(IY+(%d))"), ofs); break; - case 0xe1: my_stprintf_s(buffer, buffer_len, _T("SET 4, C=(IY+(%d))"), ofs); break; - case 0xe2: my_stprintf_s(buffer, buffer_len, _T("SET 4, D=(IY+(%d))"), ofs); break; - case 0xe3: my_stprintf_s(buffer, buffer_len, _T("SET 4, E=(IY+(%d))"), ofs); break; - case 0xe4: my_stprintf_s(buffer, buffer_len, _T("SET 4, H=(IY+(%d))"), ofs); break; - case 0xe5: my_stprintf_s(buffer, buffer_len, _T("SET 4, L=(IY+(%d))"), ofs); break; - case 0xe6: my_stprintf_s(buffer, buffer_len, _T("SET 4, (IY+(%d))"), ofs); break; - case 0xe7: my_stprintf_s(buffer, buffer_len, _T("SET 4, A=(IY+(%d))"), ofs); break; - case 0xe8: my_stprintf_s(buffer, buffer_len, _T("SET 5, B=(IY+(%d))"), ofs); break; - case 0xe9: my_stprintf_s(buffer, buffer_len, _T("SET 5, C=(IY+(%d))"), ofs); break; - case 0xea: my_stprintf_s(buffer, buffer_len, _T("SET 5, D=(IY+(%d))"), ofs); break; - case 0xeb: my_stprintf_s(buffer, buffer_len, _T("SET 5, E=(IY+(%d))"), ofs); break; - case 0xec: my_stprintf_s(buffer, buffer_len, _T("SET 5, H=(IY+(%d))"), ofs); break; - case 0xed: my_stprintf_s(buffer, buffer_len, _T("SET 5, L=(IY+(%d))"), ofs); break; - case 0xee: my_stprintf_s(buffer, buffer_len, _T("SET 5, (IY+(%d))"), ofs); break; - case 0xef: my_stprintf_s(buffer, buffer_len, _T("SET 5, A=(IY+(%d))"), ofs); break; - case 0xf0: my_stprintf_s(buffer, buffer_len, _T("SET 6, B=(IY+(%d))"), ofs); break; - case 0xf1: my_stprintf_s(buffer, buffer_len, _T("SET 6, C=(IY+(%d))"), ofs); break; - case 0xf2: my_stprintf_s(buffer, buffer_len, _T("SET 6, D=(IY+(%d))"), ofs); break; - case 0xf3: my_stprintf_s(buffer, buffer_len, _T("SET 6, E=(IY+(%d))"), ofs); break; - case 0xf4: my_stprintf_s(buffer, buffer_len, _T("SET 6, H=(IY+(%d))"), ofs); break; - case 0xf5: my_stprintf_s(buffer, buffer_len, _T("SET 6, L=(IY+(%d))"), ofs); break; - case 0xf6: my_stprintf_s(buffer, buffer_len, _T("SET 6, (IY+(%d))"), ofs); break; - case 0xf7: my_stprintf_s(buffer, buffer_len, _T("SET 6, A=(IY+(%d))"), ofs); break; - case 0xf8: my_stprintf_s(buffer, buffer_len, _T("SET 7, B=(IY+(%d))"), ofs); break; - case 0xf9: my_stprintf_s(buffer, buffer_len, _T("SET 7, C=(IY+(%d))"), ofs); break; - case 0xfa: my_stprintf_s(buffer, buffer_len, _T("SET 7, D=(IY+(%d))"), ofs); break; - case 0xfb: my_stprintf_s(buffer, buffer_len, _T("SET 7, E=(IY+(%d))"), ofs); break; - case 0xfc: my_stprintf_s(buffer, buffer_len, _T("SET 7, H=(IY+(%d))"), ofs); break; - case 0xfd: my_stprintf_s(buffer, buffer_len, _T("SET 7, L=(IY+(%d))"), ofs); break; - case 0xfe: my_stprintf_s(buffer, buffer_len, _T("SET 7, (IY+(%d))"), ofs); break; - case 0xff: my_stprintf_s(buffer, buffer_len, _T("SET 7, A=(IY+(%d))"), ofs); break; -#if defined(_MSC_VER) && (_MSC_VER >= 1200) - default: __assume(0); -#endif - } -} -//#endif -} -#define STATE_VERSION 4 - -bool Z80_BASE::process_state(FILEIO* state_fio, bool loading) -{ - if(!state_fio->StateCheckUint32(STATE_VERSION)) { - return false; - } - - if(!state_fio->StateCheckInt32(this_device_id)) { - return false; - } - state_fio->StateValue(total_icount); - - state_fio->StateValue(icount); - state_fio->StateValue(extra_icount); - state_fio->StateValue(busreq_icount); - state_fio->StateValue(prevpc); - state_fio->StateValue(pc.d); - state_fio->StateValue(sp.d); - state_fio->StateValue(af.d); - state_fio->StateValue(bc.d); - state_fio->StateValue(de.d); - state_fio->StateValue(hl.d); - state_fio->StateValue(ix.d); - state_fio->StateValue(iy.d); - state_fio->StateValue(wz.d); - state_fio->StateValue(af2.d); - state_fio->StateValue(bc2.d); - state_fio->StateValue(de2.d); - state_fio->StateValue(hl2.d); - state_fio->StateValue(I); - state_fio->StateValue(R); - state_fio->StateValue(R2); - state_fio->StateValue(ea); - state_fio->StateValue(busreq); - state_fio->StateValue(after_halt); - state_fio->StateValue(im); - state_fio->StateValue(iff1); - state_fio->StateValue(iff2); - state_fio->StateValue(icr); - state_fio->StateValue(after_ei); - state_fio->StateValue(after_ldair); - state_fio->StateValue(intr_req_bit); - state_fio->StateValue(intr_pend_bit); - - // post process - if(loading) { - prev_total_icount = total_icount; - // Post process for collecting statistics. - cycles_tmp_count = total_icount; - extra_tmp_count = 0; - insns_count = 0; - frames_count = 0; - nmi_count = 0; - irq_count = 0; - nsc800_int_count = 0; - nsc800_rsta_count = 0; - nsc800_rsta_count = 0; - nsc800_rsta_count = 0; - } - return true; -} - diff --git a/source/src/vm/z80ctc.h b/source/src/vm/z80ctc.h index 9c84c8dfb..e9b6a6211 100644 --- a/source/src/vm/z80ctc.h +++ b/source/src/vm/z80ctc.h @@ -19,7 +19,7 @@ #define SIG_Z80CTC_TRIG_2 2 #define SIG_Z80CTC_TRIG_3 3 -class Z80CTC : public DEVICE +class DLL_PREFIX Z80CTC : public DEVICE { private: struct { @@ -64,7 +64,7 @@ class Z80CTC : public DEVICE void update_intr(); public: - Z80CTC(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + Z80CTC(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { memset(counter, 0, sizeof(counter)); for(int i = 0; i < 4; i++) { @@ -85,7 +85,7 @@ class Z80CTC : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) { cpu_clocks = new_clocks; @@ -105,7 +105,7 @@ class Z80CTC : public DEVICE { return d_child; } - void set_intr_iei(bool val); + void __FASTCALL set_intr_iei(bool val); uint32_t get_intr_ack(); void notify_intr_reti(); diff --git a/source/src/vm/z80dma.cpp b/source/src/vm/z80dma.cpp index e1d6adc8a..5f42a1f69 100644 --- a/source/src/vm/z80dma.cpp +++ b/source/src/vm/z80dma.cpp @@ -43,7 +43,7 @@ #define INT_MATCH 1 #define INT_END_OF_BLOCK 2 -#define GET_REGNUM(r) (&(r) - &(WR0)) +#define GET_REGNUM(r) (int)(&(r) - &(WR0)) #define WR0 regs.m[0][0] #define WR1 regs.m[1][0] @@ -216,6 +216,10 @@ void Z80DMA::write_io8(uint32_t addr, uint32_t data) if(_DMA_DEBUG) this->out_debug_log(_T("Z80DMA: WR5=%2x\n"), data); //#endif WR5 = data; + // RDY signal sense is a LEVEL, not an EDDGE (thanks Mr.Sato) + if(now_ready() && INT_ON_READY) { + request_intr(INT_RDY); + } } else if((data & 0x83) == 0x83) { //#ifdef DMA_DEBUG if(_DMA_DEBUG) this->out_debug_log(_T("Z80DMA: WR6=%2x\n"), data); @@ -305,12 +309,20 @@ void Z80DMA::write_io8(uint32_t addr, uint32_t data) break; case CMD_FORCE_READY: force_ready = true; + // RDY signal sense is a LEVEL, not an EDDGE (thanks Mr.Sato) + if(now_ready() && INT_ON_READY) { + request_intr(INT_RDY); + } //#ifndef SINGLE_MODE_DMA if(!_SINGLE_MODE_DMA) do_dma(); //#endif break; case CMD_ENABLE_INTERRUPTS: WR3 |= 0x20; + // RDY signal sense is a LEVEL, not an EDDGE (thanks Mr.Sato) + if(now_ready() && INT_ON_READY) { + request_intr(INT_RDY); + } break; case CMD_DISABLE_INTERRUPTS: WR3 &= ~0x20; @@ -342,9 +354,15 @@ void Z80DMA::write_io8(uint32_t addr, uint32_t data) wr_tmp[wr_num++] = GET_REGNUM(INTERRUPT_VECTOR); } wr_ptr = 0; + // RDY signal sense is a LEVEL, not an EDDGE (thanks Mr.Sato) + if(now_ready() && INT_ON_READY) { + request_intr(INT_RDY); + } } else if(wr_tmp[wr_num] == GET_REGNUM(READ_MASK)) { // from Xmillenium + upcount--; update_read_buffer(); + upcount++; } } } diff --git a/source/src/vm/z80dma.h b/source/src/vm/z80dma.h index 7f86b9471..c7ef4e10d 100644 --- a/source/src/vm/z80dma.h +++ b/source/src/vm/z80dma.h @@ -19,7 +19,7 @@ class DEBUGGER; -class Z80DMA : public DEVICE +class DLL_PREFIX Z80DMA : public DEVICE { private: DEVICE *d_mem, *d_io; @@ -71,10 +71,10 @@ class Z80DMA : public DEVICE DEVICE *d_cpu, *d_child; bool iei, oei; uint32_t intr_bit; - void __FASTCALL update_intr(); + void update_intr(); public: - Z80DMA(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + Z80DMA(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { for(int i = 0; i < 6 * 8 + 1 + 1; i++) { regs.t[i] = 0; @@ -123,7 +123,7 @@ class Z80DMA : public DEVICE { return d_child; } - void set_intr_iei(bool val); + void __FASTCALL set_intr_iei(bool val); uint32_t get_intr_ack(); void notify_intr_reti(); diff --git a/source/src/vm/z80pio.h b/source/src/vm/z80pio.h index ac68bf51d..e1473eb39 100644 --- a/source/src/vm/z80pio.h +++ b/source/src/vm/z80pio.h @@ -19,9 +19,7 @@ #define SIG_Z80PIO_STROBE_A 2 #define SIG_Z80PIO_STROBE_B 3 -class VM; -class EMU; -class Z80PIO : public DEVICE +class DLL_PREFIX Z80PIO : public DEVICE { private: struct { @@ -57,10 +55,10 @@ class Z80PIO : public DEVICE DEVICE *d_cpu, *d_child; bool iei, oei; uint32_t intr_bit; - void __FASTCALL update_intr(); + void update_intr(); public: - Z80PIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + Z80PIO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { memset(port, 0, sizeof(port)); for(int i = 0; i < 2; i++) { @@ -94,7 +92,7 @@ class Z80PIO : public DEVICE { return d_child; } - void set_intr_iei(bool val); + void __FASTCALL set_intr_iei(bool val); uint32_t get_intr_ack(); void notify_intr_reti(); diff --git a/source/src/vm/z80sio.h b/source/src/vm/z80sio.h index 5814dfba2..0a014675a 100644 --- a/source/src/vm/z80sio.h +++ b/source/src/vm/z80sio.h @@ -34,7 +34,7 @@ class FIFO; -class Z80SIO : public DEVICE +class DLL_PREFIX Z80SIO : public DEVICE { private: struct { @@ -97,10 +97,10 @@ class Z80SIO : public DEVICE bool __HAS_UPD7201; bool __SIO_DEBUG; - void __FASTCALL update_intr(); + void update_intr(); public: - Z80SIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + Z80SIO(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { memset(port, 0, sizeof(port)); for(int i = 0; i < 2; i++) { @@ -129,7 +129,7 @@ class Z80SIO : public DEVICE void __FASTCALL write_io8(uint32_t addr, uint32_t data); uint32_t __FASTCALL read_io8(uint32_t addr); void __FASTCALL write_signal(int id, uint32_t data, uint32_t mask); - void event_callback(int event_id, int err); + void __FASTCALL event_callback(int event_id, int err); bool process_state(FILEIO* state_fio, bool loading); // interrupt common functions void set_context_intr(DEVICE* device, uint32_t bit) @@ -145,7 +145,7 @@ class Z80SIO : public DEVICE { return d_child; } - void set_intr_iei(bool val); + void __FASTCALL set_intr_iei(bool val); uint32_t get_intr_ack(); void notify_intr_reti(); diff --git a/source/src/vm/z80tvgame/CMakeLists.txt b/source/src/vm/z80tvgame/CMakeLists.txt index 4c4a7f600..fea6d720c 100644 --- a/source/src/vm/z80tvgame/CMakeLists.txt +++ b/source/src/vm/z80tvgame/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required (VERSION 2.6) -message("* vm/z80tvgame") +message("* vm/${EXE_NAME}") -add_library(vm_z80tvgame +add_library(vm_${EXE_NAME} z80tvgame.cpp joystick.cpp memory.cpp -) \ No newline at end of file +) diff --git a/source/src/vm/z80tvgame/joystick.h b/source/src/vm/z80tvgame/joystick.h index 5ef5da186..9e3596810 100644 --- a/source/src/vm/z80tvgame/joystick.h +++ b/source/src/vm/z80tvgame/joystick.h @@ -25,7 +25,7 @@ class JOYSTICK : public DEVICE const uint32_t* joy_stat; public: - JOYSTICK(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + JOYSTICK(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Joystick I/F")); } diff --git a/source/src/vm/z80tvgame/memory.h b/source/src/vm/z80tvgame/memory.h index c72ab45e5..0b7f1c3ec 100644 --- a/source/src/vm/z80tvgame/memory.h +++ b/source/src/vm/z80tvgame/memory.h @@ -33,7 +33,7 @@ class MEMORY : public DEVICE __DECL_ALIGNED(32) _bit_trans_table_scrn_t pixel_trans_table; public: - MEMORY(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu) + MEMORY(VM_TEMPLATE* parent_vm, EMU_TEMPLATE* parent_emu) : DEVICE(parent_vm, parent_emu) { set_device_name(_T("Memory Bus")); } diff --git a/source/src/vm/z80tvgame/z80tvgame.cpp b/source/src/vm/z80tvgame/z80tvgame.cpp index d5e1ab196..dcf01cdaa 100644 --- a/source/src/vm/z80tvgame/z80tvgame.cpp +++ b/source/src/vm/z80tvgame/z80tvgame.cpp @@ -35,7 +35,7 @@ using Z80TVGAME::MEMORY; // initialize // ---------------------------------------------------------------------------- -VM::VM(EMU* parent_emu) : VM_TEMPLATE(parent_emu) +VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu) { // create devices first_device = last_device = NULL; @@ -220,6 +220,18 @@ void VM::update_config() } } +double VM::get_current_usec() +{ + if(event == NULL) return 0.0; + return event->get_current_usec(); +} + +uint64_t VM::get_current_clock_uint64() +{ + if(event == NULL) return (uint64_t)0; + return event->get_current_clock_uint64(); +} + #define STATE_VERSION 2 bool VM::process_state(FILEIO* state_fio, bool loading) @@ -232,7 +244,7 @@ bool VM::process_state(FILEIO* state_fio, bool loading) // const char *name = typeid(*device).name(); // But, using get_device_name() instead of typeid(foo).name() 20181008 K.O const char *name = device->get_device_name(); - int len = strlen(name); + int len = (int)strlen(name); if(!state_fio->StateCheckInt32(len)) { if(loading) { diff --git a/source/src/vm/z80tvgame/z80tvgame.h b/source/src/vm/z80tvgame/z80tvgame.h index a33b7a3b3..a3302ae20 100644 --- a/source/src/vm/z80tvgame/z80tvgame.h +++ b/source/src/vm/z80tvgame/z80tvgame.h @@ -89,7 +89,7 @@ class VM : public VM_TEMPLATE // initialize // ---------------------------------------- - VM(EMU* parent_emu); + VM(EMU_TEMPLATE* parent_emu); ~VM(); // ---------------------------------------- @@ -122,6 +122,9 @@ class VM : public VM_TEMPLATE bool is_cart_inserted(int drv); bool is_frame_skippable(); + double get_current_usec(); + uint64_t get_current_clock_uint64(); + void update_config(); bool process_state(FILEIO* state_fio, bool loading); diff --git a/source/src/win32/osd.cpp b/source/src/win32/osd.cpp index 9085f4311..26fc43403 100644 --- a/source/src/win32/osd.cpp +++ b/source/src/win32/osd.cpp @@ -127,8 +127,14 @@ void OSD::start_waiting_in_debugger() } } } +#ifdef _M_AMD64 + // thanks Marukun (64bit) + hWndProc = (FARPROC)GetWindowLongPtr(main_window_handle, GWLP_WNDPROC); + SetWindowLongPtr(main_window_handle, GWLP_WNDPROC, (LONG_PTR)MyWndProc); +#else hWndProc = (FARPROC)GetWindowLong(main_window_handle, GWL_WNDPROC); SetWindowLong(main_window_handle, GWL_WNDPROC, (LONG)MyWndProc); +#endif my_osd = this; } @@ -143,7 +149,12 @@ void OSD::finish_waiting_in_debugger() } } } +#ifdef _M_AMD64 + // thanks Marukun (64bit) + SetWindowLongPtr(main_window_handle, GWLP_WNDPROC, (LONG_PTR)hWndProc); +#else SetWindowLong(main_window_handle, GWL_WNDPROC, (LONG)hWndProc); +#endif my_osd = NULL; } diff --git a/source/src/win32/osd.h b/source/src/win32/osd.h index 55b5fb2d6..34cb90e6f 100644 --- a/source/src/win32/osd.h +++ b/source/src/win32/osd.h @@ -20,6 +20,11 @@ //#define DIRECTINPUT_VERSION 0x500 #define DIRECTINPUT_VERSION 0x800 +#if defined(_MSC_VER) && (_MSC_VER >= 1910) +#define SUPPORT_D2D1 +#endif +#define SUPPORT_D3D9 + #include #include #include @@ -27,9 +32,14 @@ #include #include #include +#ifdef SUPPORT_D2D1 +#include +#endif +#ifdef SUPPORT_D3D9 #include -#include +//#include #include +#endif #include #include #include @@ -39,8 +49,23 @@ #include "../config.h" #ifdef USE_ZLIB -// relative path from *.vcproj/*.vcxproj, not from this directory :-( - #if defined(_MSC_VER) && (_MSC_VER >= 1800) + // relative path from *.vcproj/*.vcxproj, not from this directory :-( + #if defined(_MSC_VER) && (_MSC_VER >= 1910) + // thanks Marukun + #ifdef _M_AMD64 + #ifdef _DEBUG + #pragma comment(lib, "../src/zlib-1.2.11/vc++2017/debug/x64/zlibstat.lib") + #else + #pragma comment(lib, "../src/zlib-1.2.11/vc++2017/release/x64/zlibstat.lib") + #endif + #else + #ifdef _DEBUG + #pragma comment(lib, "../src/zlib-1.2.11/vc++2017/debug/zlibstat.lib") + #else + #pragma comment(lib, "../src/zlib-1.2.11/vc++2017/release/zlibstat.lib") + #endif + #endif + #elif defined(_MSC_VER) && (_MSC_VER >= 1800) #ifdef _DEBUG #pragma comment(lib, "../src/zlib-1.2.11/vc++2013/debug/zlibstat.lib") #else @@ -63,8 +88,13 @@ #pragma comment(lib, "msimg32.lib") #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus; +#ifdef SUPPORT_D2D1 +#pragma comment(lib, "d2d1.lib") +#endif +#ifdef SUPPORT_D3D9 #pragma comment(lib, "d3d9.lib") -#pragma comment(lib, "d3dx9.lib") +//#pragma comment(lib, "d3dx9.lib") +#endif #pragma comment(lib, "vfw32.lib") #pragma comment(lib, "dsound.lib") #if DIRECTINPUT_VERSION >= 0x0800 @@ -152,7 +182,9 @@ class CMySampleGrabberCB : public ISampleGrabberCB { #define MAX_CAPTURE_DEVS 8 #endif +#ifndef _M_AMD64 #define SUPPORT_WIN32_DLL +#endif #define SCREEN_FILTER_NONE 0 #define SCREEN_FILTER_RGB 1 @@ -311,11 +343,22 @@ class OSD void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest); //#endif void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest); +#ifdef SUPPORT_D2D1 + bool initialize_d2d1(); + bool initialize_d2d1_surface(bitmap_t *buffer); + void release_d2d1(); + void release_d2d1_surface(); + void copy_to_d2d1_surface(bitmap_t *buffer); + void update_d2d1_screen(int dest_x, int dest_y); +#endif +#ifdef SUPPORT_D3D9 bool initialize_d3d9(); bool initialize_d3d9_surface(bitmap_t *buffer); void release_d3d9(); void release_d3d9_surface(); void copy_to_d3d9_surface(bitmap_t *buffer); + void update_d3d9_screen(int dest_x, int dest_y); +#endif int add_video_frames(); bitmap_t vm_screen_buffer; @@ -328,6 +371,7 @@ class OSD //#endif bitmap_t stretched_screen_buffer; bitmap_t shrinked_screen_buffer; + bitmap_t reversed_screen_buffer; bitmap_t video_screen_buffer; bitmap_t* draw_screen_buffer; @@ -342,10 +386,18 @@ class OSD Gdiplus::GdiplusStartupInput gdiSI; ULONG_PTR gdiToken; +#ifdef SUPPORT_D2D1 + ID2D1Factory* pD2d1Factory; + ID2D1DCRenderTarget *pD2d1DCRenderTarget; + ID2D1HwndRenderTarget* pD2d1HwndRenderTarget; + ID2D1Bitmap* pD2d1Bitmap; +#endif +#ifdef SUPPORT_D3D9 LPDIRECT3D9 lpd3d9; LPDIRECT3DDEVICE9 lpd3d9Device; LPDIRECT3DSURFACE9 lpd3d9Surface; LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface; +#endif _TCHAR video_file_path[_MAX_PATH]; int rec_video_fps; @@ -426,7 +478,7 @@ class OSD void initialize_socket(); void release_socket(); - int soc[SOCKET_MAX]; + SOCKET soc[SOCKET_MAX]; bool is_tcp[SOCKET_MAX]; struct sockaddr_in udpaddr[SOCKET_MAX]; int socket_delay[SOCKET_MAX]; @@ -629,7 +681,7 @@ class OSD // common socket #ifdef USE_SOCKET - int get_socket(int ch) + SOCKET get_socket(int ch) { return soc[ch]; } diff --git a/source/src/win32/osd_screen.cpp b/source/src/win32/osd_screen.cpp index 43125be3b..c02dda42d 100644 --- a/source/src/win32/osd_screen.cpp +++ b/source/src/win32/osd_screen.cpp @@ -36,13 +36,21 @@ void OSD::initialize_screen() //#endif memset(&stretched_screen_buffer, 0, sizeof(bitmap_t)); memset(&shrinked_screen_buffer, 0, sizeof(bitmap_t)); + memset(&reversed_screen_buffer, 0, sizeof(bitmap_t)); memset(&video_screen_buffer, 0, sizeof(bitmap_t)); +#ifdef SUPPORT_D2D1 + pD2d1Factory = NULL; + pD2d1DCRenderTarget = NULL; + pD2d1HwndRenderTarget = NULL; + pD2d1Bitmap = NULL; +#endif +#ifdef SUPPORT_D3D9 lpd3d9 = NULL; lpd3d9Device = NULL; lpd3d9Surface = NULL; lpd3d9OffscreenSurface = NULL; - +#endif now_record_video = false; pAVIStream = NULL; pAVICompressed = NULL; @@ -57,7 +65,12 @@ void OSD::release_screen() { stop_record_video(); +#ifdef SUPPORT_D2D1 + release_d2d1(); +#endif +#ifdef SUPPORT_D3D9 release_d3d9(); +#endif release_screen_buffer(&vm_screen_buffer); #ifdef USE_SCREEN_FILTER release_screen_buffer(&filtered_screen_buffer); @@ -68,6 +81,7 @@ void OSD::release_screen() //#endif release_screen_buffer(&stretched_screen_buffer); release_screen_buffer(&shrinked_screen_buffer); + release_screen_buffer(&reversed_screen_buffer); release_screen_buffer(&video_screen_buffer); } @@ -292,13 +306,37 @@ int OSD::draw_screen() draw_screen_buffer = &stretched_screen_buffer; } - // initialize d3d9 surface + // initialize d2d1/d3d9 surface +#ifdef SUPPORT_D2D1 + static bool prev_use_d2d1 = config.use_d2d1; + static bool prev_use_dcrender = (host_window_mode && config.show_status_bar); +#endif +#ifdef SUPPORT_D3D9 static bool prev_use_d3d9 = config.use_d3d9; static bool prev_wait_vsync = config.wait_vsync; +#endif static int prev_window_width = 0, prev_window_height = 0; static int prev_screen_width = 0, prev_screen_height = 0; - if(prev_use_d3d9 != config.use_d3d9 || prev_wait_vsync != config.wait_vsync || prev_window_width != host_window_width || prev_window_height != host_window_height) { + if( +#ifdef SUPPORT_D2D1 + prev_use_d2d1 != config.use_d2d1 || prev_use_dcrender != (host_window_mode && config.show_status_bar) || +#endif +#ifdef SUPPORT_D3D9 + prev_use_d3d9 != config.use_d3d9 || prev_wait_vsync != config.wait_vsync || +#endif + prev_window_width != host_window_width || prev_window_height != host_window_height + ) { +#ifdef SUPPORT_D2D1 + if(config.use_d2d1) { + config.use_d2d1 = initialize_d2d1(); + } else { + release_d2d1(); + } + prev_use_d2d1 = config.use_d2d1; + prev_use_dcrender = (host_window_mode && config.show_status_bar); +#endif +#ifdef SUPPORT_D3D9 if(config.use_d3d9) { config.use_d3d9 = initialize_d3d9(); } else { @@ -306,22 +344,39 @@ int OSD::draw_screen() } prev_use_d3d9 = config.use_d3d9; prev_wait_vsync = config.wait_vsync; +#endif prev_window_width = host_window_width; prev_window_height = host_window_height; prev_screen_width = prev_screen_height = 0; } if(prev_screen_width != draw_screen_buffer->width || prev_screen_height != draw_screen_buffer->height) { +#ifdef SUPPORT_D2D1 + if(config.use_d2d1) { + config.use_d2d1 = initialize_d2d1_surface(draw_screen_buffer); + } +#endif +#ifdef SUPPORT_D3D9 if(config.use_d3d9) { config.use_d3d9 = initialize_d3d9_surface(draw_screen_buffer); } +#endif prev_screen_width = draw_screen_buffer->width; prev_screen_height = draw_screen_buffer->height; } +#ifdef SUPPORT_D2D1 + if(config.use_d2d1) { + // copy screen to d2d1 offscreen surface + copy_to_d2d1_surface(draw_screen_buffer); + } else +#endif +#ifdef SUPPORT_D3D9 if(config.use_d3d9) { // copy screen to d3d9 offscreen surface copy_to_d3d9_surface(draw_screen_buffer); - } else { + } else +#endif + { if(draw_screen_buffer->width != draw_screen_width || draw_screen_buffer->height != draw_screen_height) { if(shrinked_screen_buffer.width != draw_screen_width || shrinked_screen_buffer.height != draw_screen_height) { initialize_screen_buffer(&shrinked_screen_buffer, draw_screen_width, draw_screen_height, HALFTONE); @@ -447,20 +502,17 @@ void OSD::update_screen(HDC hdc) int dest_x = (host_window_width - draw_screen_width) / 2; int dest_y = (host_window_height - draw_screen_height) / 2; +#ifdef SUPPORT_D2D1 + if(config.use_d2d1) { + update_d2d1_screen(dest_x, dest_y); + } else +#endif +#ifdef SUPPORT_D3D9 if(config.use_d3d9) { - LPDIRECT3DSURFACE9 lpd3d9BackSurface = NULL; - if(lpd3d9Device != NULL && lpd3d9Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &lpd3d9BackSurface) == D3D_OK && lpd3d9BackSurface != NULL) { - RECT rectSrc = { 0, 0, draw_screen_buffer->width, draw_screen_buffer->height }; - RECT rectDst = { dest_x, dest_y, dest_x + draw_screen_width, dest_y + draw_screen_height }; - RECT rectWin = { 0, 0, host_window_width, host_window_height }; - bool stretch_screen = !(draw_screen_buffer->width == draw_screen_width && draw_screen_buffer->height == draw_screen_height); - - lpd3d9Device->UpdateSurface(lpd3d9OffscreenSurface, NULL, lpd3d9Surface, NULL); - lpd3d9Device->StretchRect(lpd3d9Surface, &rectSrc, lpd3d9BackSurface, &rectDst, stretch_screen ? D3DTEXF_LINEAR : D3DTEXF_POINT); - lpd3d9BackSurface->Release(); - lpd3d9Device->Present(&rectWin, &rectWin, NULL, NULL); - } - } else { + update_d3d9_screen(dest_x, dest_y); + } else +#endif + { BitBlt(hdc, dest_x, dest_y, draw_screen_width, draw_screen_height, draw_screen_buffer->hdcDib, 0, 0, SRCCOPY); } first_invalidate = self_invalidate = false; @@ -1034,13 +1086,144 @@ void OSD::stretch_screen_buffer(bitmap_t *source, bitmap_t *dest) } #if defined(_RGB555) + #define DXGI_FORMAT_TMP DXGI_FORMAT_B5G5R5A1_UNORM #define D3DFMT_TMP D3DFMT_X1R5G5B5 #elif defined(_RGB565) + #define DXGI_FORMAT_TMP DXGI_FORMAT_B5G6R5_UNORM #define D3DFMT_TMP D3DFMT_R5G6B5 #elif defined(_RGB888) + #define DXGI_FORMAT_TMP DXGI_FORMAT_B8G8R8A8_UNORM #define D3DFMT_TMP D3DFMT_X8R8G8B8 #endif +#ifdef SUPPORT_D2D1 +bool OSD::initialize_d2d1() +{ + release_d2d1(); + + if(!FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &pD2d1Factory))) { + if(host_window_mode && config.show_status_bar) { + D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties( + D2D1_RENDER_TARGET_TYPE_DEFAULT, + D2D1::PixelFormat(DXGI_FORMAT_TMP, D2D1_ALPHA_MODE_IGNORE), + 0, 0, + D2D1_RENDER_TARGET_USAGE_NONE, + D2D1_FEATURE_LEVEL_DEFAULT + ); + if(!FAILED(pD2d1Factory->CreateDCRenderTarget(&props, &pD2d1DCRenderTarget))) { + int dest_x = (host_window_width - draw_screen_width) / 2; + int dest_y = (host_window_height - draw_screen_height) / 2; + RECT rect = { dest_x, dest_y, dest_x + draw_screen_width, dest_y + draw_screen_height }; + if(!FAILED(pD2d1DCRenderTarget->BindDC(GetDC(main_window_handle), &rect))) { + return true; + } + } + } else { + if(!FAILED(pD2d1Factory->CreateHwndRenderTarget( + D2D1::RenderTargetProperties(), + D2D1::HwndRenderTargetProperties(main_window_handle, D2D1::SizeU(host_window_width, host_window_height)), + &pD2d1HwndRenderTarget + ))) { + return true; + } + } + } + return false; +} + +bool OSD::initialize_d2d1_surface(bitmap_t *buffer) +{ + if(host_window_mode && config.show_status_bar) { + if(pD2d1DCRenderTarget != NULL) { + if(!FAILED(pD2d1DCRenderTarget->CreateBitmap( + D2D1::SizeU(buffer->width, buffer->height), + D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_TMP, D2D1_ALPHA_MODE_IGNORE)), + &pD2d1Bitmap + ))) { + return true; + } + } + } else { + if(pD2d1HwndRenderTarget != NULL) { + if(!FAILED(pD2d1HwndRenderTarget->CreateBitmap( + D2D1::SizeU(buffer->width, buffer->height), + D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_TMP, D2D1_ALPHA_MODE_IGNORE)), + &pD2d1Bitmap + ))) { + return true; + } + } + } + return false; +} + +void OSD::release_d2d1() +{ + release_d2d1_surface(); + + if(pD2d1DCRenderTarget != NULL) { + pD2d1DCRenderTarget->Release(); + pD2d1DCRenderTarget = NULL; + } + if(pD2d1HwndRenderTarget != NULL) { + pD2d1HwndRenderTarget->Release(); + pD2d1HwndRenderTarget = NULL; + } + if(pD2d1Factory != NULL) { + pD2d1Factory->Release(); + pD2d1Factory = NULL; + } +} + +void OSD::release_d2d1_surface() +{ + if(pD2d1Bitmap != NULL) { + pD2d1Bitmap->Release(); + pD2d1Bitmap = NULL; + } +} + +void OSD::copy_to_d2d1_surface(bitmap_t *buffer) +{ + if(reversed_screen_buffer.width != buffer->width || reversed_screen_buffer.height != buffer->height) { + initialize_screen_buffer(&reversed_screen_buffer, buffer->width, buffer->height, HALFTONE); + } + for(int y = 0; y < buffer->height; y++) { + scrntype_t* source_buffer = buffer->get_buffer(buffer->height - y - 1); + scrntype_t* dest_buffer = reversed_screen_buffer.get_buffer(y); + + for(int x = 0; x < buffer->width; x++) { + dest_buffer[x] = source_buffer[x]; + } + } + pD2d1Bitmap->CopyFromMemory(nullptr, reinterpret_cast< const void* >(reversed_screen_buffer.lpBmp), sizeof(scrntype_t) * reversed_screen_buffer.width); +} + +void OSD::update_d2d1_screen(int dest_x, int dest_y) +{ + D2D1_RECT_F rect = { (FLOAT)dest_x, (FLOAT)dest_y, (FLOAT)(dest_x + draw_screen_width), (FLOAT)(dest_y + draw_screen_height) }; + HRESULT hr = 0; + + if(host_window_mode && config.show_status_bar) { + if(pD2d1DCRenderTarget != NULL) { + pD2d1DCRenderTarget->BeginDraw(); + pD2d1DCRenderTarget->DrawBitmap(pD2d1Bitmap, &rect, 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR); + hr = pD2d1DCRenderTarget->EndDraw(); + } + } else { + if(pD2d1HwndRenderTarget != NULL) { + pD2d1HwndRenderTarget->BeginDraw(); + pD2d1HwndRenderTarget->DrawBitmap(pD2d1Bitmap, &rect, 1.0f, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR); + hr = pD2d1HwndRenderTarget->EndDraw(); + } + } + if(hr == D2DERR_RECREATE_TARGET) { + set_host_window_size(-1, -1, host_window_mode); + } +} +#endif + +#ifdef SUPPORT_D3D9 bool OSD::initialize_d3d9() { release_d3d9(); @@ -1145,6 +1328,24 @@ void OSD::copy_to_d3d9_surface(bitmap_t *buffer) } +void OSD::update_d3d9_screen(int dest_x, int dest_y) +{ + LPDIRECT3DSURFACE9 lpd3d9BackSurface = NULL; + + if(lpd3d9Device != NULL && lpd3d9Device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &lpd3d9BackSurface) == D3D_OK && lpd3d9BackSurface != NULL) { + RECT rectSrc = { 0, 0, draw_screen_buffer->width, draw_screen_buffer->height }; + RECT rectDst = { dest_x, dest_y, dest_x + draw_screen_width, dest_y + draw_screen_height }; + RECT rectWin = { 0, 0, host_window_width, host_window_height }; + bool stretch_screen = !(draw_screen_buffer->width == draw_screen_width && draw_screen_buffer->height == draw_screen_height); + + lpd3d9Device->UpdateSurface(lpd3d9OffscreenSurface, NULL, lpd3d9Surface, NULL); + lpd3d9Device->StretchRect(lpd3d9Surface, &rectSrc, lpd3d9BackSurface, &rectDst, stretch_screen ? D3DTEXF_LINEAR : D3DTEXF_POINT); + lpd3d9BackSurface->Release(); + lpd3d9Device->Present(&rectWin, &rectWin, NULL, NULL); + } +} +#endif + void OSD::capture_screen() { // write_bitmap_to_file(&vm_screen_buffer, create_date_file_path(_T("bmp"))); @@ -1422,9 +1623,9 @@ int OSD::get_text_width(bitmap_t *bitmap, font_t *font, const char *text) #ifdef _UNICODE _TCHAR unicode[1024]; MultiByteToWideChar(CP_ACP, 0, text, -1, unicode, 1024); - GetTextExtentPoint32(bitmap->hdcDib, unicode, wcslen(unicode), &size); + GetTextExtentPoint32(bitmap->hdcDib, unicode, (int)wcslen(unicode), &size); #else - GetTextExtentPoint32(bitmap->hdcDib, text, strlen(text), &size); + GetTextExtentPoint32(bitmap->hdcDib, text, (int)strlen(text), &size); #endif SelectObject(bitmap->hdcDib, hFontOld); return (int)size.cx; @@ -1438,9 +1639,9 @@ void OSD::draw_text_to_bitmap(bitmap_t *bitmap, font_t *font, int x, int y, cons #ifdef _UNICODE _TCHAR unicode[1024]; MultiByteToWideChar(CP_ACP, 0, text, -1, unicode, 1024); - ExtTextOut(bitmap->hdcDib, x, y, NULL, NULL, unicode, wcslen(unicode), NULL); + ExtTextOut(bitmap->hdcDib, x, y, NULL, NULL, unicode, (UINT)wcslen(unicode), NULL); #else - ExtTextOut(bitmap->hdcDib, x, y, NULL, NULL, text, strlen(text), NULL); + ExtTextOut(bitmap->hdcDib, x, y, NULL, NULL, text, (UINT)strlen(text), NULL); #endif SelectObject(bitmap->hdcDib, hFontOld); } diff --git a/source/src/win32/winmain.cpp b/source/src/win32/winmain.cpp index 0711253e9..419475acc 100644 --- a/source/src/win32/winmain.cpp +++ b/source/src/win32/winmain.cpp @@ -27,7 +27,8 @@ EMU* emu; HMENU hMenu = NULL; bool now_menuloop = false; -void update_menu(HWND hWnd, HMENU hMenu); +void update_toplevel_menu(HWND hWnd, HMENU hMenu); +void update_popup_menu(HWND hWnd, HMENU hMenu); void show_menu_bar(HWND hWnd); void hide_menu_bar(HWND hWnd); @@ -80,6 +81,7 @@ void open_recent_quick_disk(int drv, int index); #ifdef USE_HARD_DISK void open_hard_disk_dialog(HWND hWnd, int drv); void open_recent_hard_disk(int drv, int index); +void open_blank_hard_disk_dialog(HWND hWnd, int drv, int sector_size, int sectors, int surfaces, int cylinders); #endif #ifdef USE_TAPE void open_tape_dialog(HWND hWnd, int drv, bool play); @@ -134,12 +136,13 @@ void start_auto_key(); #endif // dialog +// thanks Marukun (64bit) #ifdef USE_SOUND_VOLUME -BOOL CALLBACK VolumeWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK VolumeWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); #endif #ifdef USE_JOYSTICK -BOOL CALLBACK JoyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); -BOOL CALLBACK JoyToKeyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK JoyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK JoyToKeyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam); #endif // buttons @@ -290,11 +293,14 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR szCmdL emu = new EMU(hWnd, hInstance); emu->set_host_window_size(WINDOW_WIDTH, WINDOW_HEIGHT, true); + // update top-level menu for emulator settings + update_toplevel_menu(hWnd, hMenu); + #ifdef SUPPORT_DRAG_DROP // open command line path if(szCmdLine[0]) { if(szCmdLine[0] == _T('"')) { - int len = _tcslen(szCmdLine); + int len = (int)_tcslen(szCmdLine); szCmdLine[len - 1] = _T('\0'); szCmdLine++; } @@ -324,7 +330,7 @@ int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR szCmdL _CrtDumpMemoryLeaks(); #endif ExitProcess(0); // trick - return msg.wParam; + return (int)msg.wParam; } if(!TranslateAccelerator(hWnd, hAccel, &msg)) { TranslateMessage(&msg); @@ -440,7 +446,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) #ifdef SUPPORT_DRAG_DROP DragAcceptFiles(hWnd, TRUE); #endif +#ifdef _M_AMD64 + // thanks Marukun (64bit) + hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE); +#else hInstance = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); +#endif timeBeginPeriod(1); break; case WM_CLOSE: @@ -577,7 +588,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) if(emu) { emu->suspend(); } - update_menu(hWnd, (HMENU)wParam); + update_popup_menu(hWnd, (HMENU)wParam); break; case WM_ENTERMENULOOP: now_menuloop = true; @@ -626,12 +637,14 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) case ID_RESET: if(emu) { emu->reset(); + update_toplevel_menu(hWnd, hMenu); } break; #ifdef USE_SPECIAL_RESET case ID_SPECIAL_RESET: if(emu) { emu->special_reset(); + update_toplevel_menu(hWnd, hMenu); } break; #endif @@ -850,7 +863,22 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) emu->capture_screen(); } break; +#ifdef SUPPORT_D2D1 + case ID_HOST_USE_D2D1: + config.use_d2d1 = !config.use_d2d1; + #ifdef SUPPORT_D3D9 + config.use_d3d9 = 0; + #endif + if(emu) { + emu->set_host_window_size(-1, -1, !now_fullscreen); + } + break; +#endif +#ifdef SUPPORT_D3D9 case ID_HOST_USE_D3D9: + #ifdef SUPPORT_D2D1 + config.use_d2d1 = 0; + #endif config.use_d3d9 = !config.use_d3d9; if(emu) { emu->set_host_window_size(-1, -1, !now_fullscreen); @@ -862,6 +890,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) emu->set_host_window_size(-1, -1, !now_fullscreen); } break; +#endif case ID_HOST_USE_DINPUT: config.use_dinput = !config.use_dinput; break; @@ -874,6 +903,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) if(!now_fullscreen) { set_window(hWnd, prev_window_mode); } + #ifdef SUPPORT_D2D1 + emu->set_host_window_size(-1, -1, !now_fullscreen); + #endif } break; case ID_SCREEN_WINDOW + 0: case ID_SCREEN_WINDOW + 1: case ID_SCREEN_WINDOW + 2: case ID_SCREEN_WINDOW + 3: case ID_SCREEN_WINDOW + 4: @@ -960,21 +992,24 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) break; #ifdef USE_SOUND_VOLUME case ID_SOUND_VOLUME: - DialogBoxParam((HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDD_VOLUME), hWnd, VolumeWndProc, 0); + // thanks Marukun (64bit) + DialogBoxParam((HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDD_VOLUME), hWnd, reinterpret_cast(VolumeWndProc), 0); break; #endif #ifdef USE_JOYSTICK case ID_INPUT_JOYSTICK0: case ID_INPUT_JOYSTICK1: case ID_INPUT_JOYSTICK2: case ID_INPUT_JOYSTICK3: case ID_INPUT_JOYSTICK4: case ID_INPUT_JOYSTICK5: case ID_INPUT_JOYSTICK6: case ID_INPUT_JOYSTICK7: { + // thanks Marukun (64bit) LONG index = LOWORD(wParam) - ID_INPUT_JOYSTICK0; - DialogBoxParam((HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDD_JOYSTICK), hWnd, JoyWndProc, (LPARAM)&index); + DialogBoxParam((HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDD_JOYSTICK), hWnd, reinterpret_cast(JoyWndProc), (LPARAM)&index); } break; case ID_INPUT_JOYTOKEY: { + // thanks Marukun (64bit) LONG index = 0; - DialogBoxParam((HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDD_JOYTOKEY), hWnd, JoyToKeyWndProc, (LPARAM)&index); + DialogBoxParam((HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDD_JOYTOKEY), hWnd, reinterpret_cast(JoyToKeyWndProc), (LPARAM)&index); } break; #endif @@ -1152,7 +1187,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) #endif #ifdef USE_HARD_DISK #if USE_HARD_DISK >= 1 - #define HD_MENU_ITEMS(drv, ID_OPEN_HD, ID_CLOSE_HD, ID_RECENT_HD) \ + #define HD_MENU_ITEMS(drv, ID_OPEN_HD, ID_CLOSE_HD, ID_OPEN_BLANK_20MB_HD, ID_OPEN_BLANK_20MB_1024_HD, ID_OPEN_BLANK_40MB_HD, ID_RECENT_HD) \ case ID_OPEN_HD: \ if(emu) { \ open_hard_disk_dialog(hWnd, drv); \ @@ -1163,34 +1198,49 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) emu->close_hard_disk(drv); \ } \ break; \ + case ID_OPEN_BLANK_20MB_HD: \ + if(emu) { \ + open_blank_hard_disk_dialog(hWnd, drv, 256, 33, 4, 615); \ + } \ + break; \ + case ID_OPEN_BLANK_20MB_1024_HD: \ + if(emu) { \ + open_blank_hard_disk_dialog(hWnd, drv, 1024, 8, 4, 615); \ + } \ + break; \ + case ID_OPEN_BLANK_40MB_HD: \ + if(emu) { \ + open_blank_hard_disk_dialog(hWnd, drv, 256, 33, 8, 615); \ + } \ + break; \ case ID_RECENT_HD + 0: case ID_RECENT_HD + 1: case ID_RECENT_HD + 2: case ID_RECENT_HD + 3: \ case ID_RECENT_HD + 4: case ID_RECENT_HD + 5: case ID_RECENT_HD + 6: case ID_RECENT_HD + 7: \ if(emu) { \ open_recent_hard_disk(drv, LOWORD(wParam) - ID_RECENT_HD); \ } \ break; - HD_MENU_ITEMS(0, ID_OPEN_HD1, ID_CLOSE_HD1, ID_RECENT_HD1) + HD_MENU_ITEMS(0, ID_OPEN_HD1, ID_CLOSE_HD1, ID_OPEN_BLANK_20MB_HD1, ID_OPEN_BLANK_20MB_1024_HD1, ID_OPEN_BLANK_40MB_HD1, ID_RECENT_HD1) #endif #if USE_HARD_DISK >= 2 - HD_MENU_ITEMS(1, ID_OPEN_HD2, ID_CLOSE_HD2, ID_RECENT_HD2) + HD_MENU_ITEMS(1, ID_OPEN_HD2, ID_CLOSE_HD2, ID_OPEN_BLANK_20MB_HD2, ID_OPEN_BLANK_20MB_1024_HD2, ID_OPEN_BLANK_40MB_HD2, ID_RECENT_HD2) #endif #if USE_HARD_DISK >= 3 - HD_MENU_ITEMS(2, ID_OPEN_HD3, ID_CLOSE_HD3, ID_RECENT_HD3) + HD_MENU_ITEMS(2, ID_OPEN_HD3, ID_CLOSE_HD3, ID_OPEN_BLANK_20MB_HD3, ID_OPEN_BLANK_20MB_1024_HD3, ID_OPEN_BLANK_40MB_HD3, ID_RECENT_HD3) #endif #if USE_HARD_DISK >= 4 - HD_MENU_ITEMS(3, ID_OPEN_HD4, ID_CLOSE_HD4, ID_RECENT_HD4) + HD_MENU_ITEMS(3, ID_OPEN_HD4, ID_CLOSE_HD4, ID_OPEN_BLANK_20MB_HD4, ID_OPEN_BLANK_20MB_1024_HD4, ID_OPEN_BLANK_40MB_HD4, ID_RECENT_HD4) #endif #if USE_HARD_DISK >= 5 - HD_MENU_ITEMS(4, ID_OPEN_HD5, ID_CLOSE_HD5, ID_RECENT_HD5) + HD_MENU_ITEMS(4, ID_OPEN_HD5, ID_CLOSE_HD5, ID_OPEN_BLANK_20MB_HD5, ID_OPEN_BLANK_20MB_1024_HD5, ID_OPEN_BLANK_40MB_HD5, ID_RECENT_HD5) #endif #if USE_HARD_DISK >= 6 - HD_MENU_ITEMS(5, ID_OPEN_HD6, ID_CLOSE_HD6, ID_RECENT_HD6) + HD_MENU_ITEMS(5, ID_OPEN_HD6, ID_CLOSE_HD6, ID_OPEN_BLANK_20MB_HD6, ID_OPEN_BLANK_20MB_1024_HD6, ID_OPEN_BLANK_40MB_HD6, ID_RECENT_HD6) #endif #if USE_HARD_DISK >= 7 - HD_MENU_ITEMS(6, ID_OPEN_HD7, ID_CLOSE_HD7, ID_RECENT_HD7) + HD_MENU_ITEMS(6, ID_OPEN_HD7, ID_CLOSE_HD7, ID_OPEN_BLANK_20MB_HD7, ID_OPEN_BLANK_20MB_1024_HD7, ID_OPEN_BLANK_40MB_HD7, ID_RECENT_HD7) #endif #if USE_HARD_DISK >= 8 - HD_MENU_ITEMS(7, ID_OPEN_HD8, ID_CLOSE_HD8, ID_RECENT_HD8) + HD_MENU_ITEMS(7, ID_OPEN_HD8, ID_CLOSE_HD8, ID_OPEN_BLANK_20MB_HD8, ID_OPEN_BLANK_20MB_1024_HD8, ID_OPEN_BLANK_40MB_HD8, ID_RECENT_HD8) #endif #endif #ifdef USE_TAPE @@ -1850,9 +1900,19 @@ void update_host_menu(HMENU hMenu) EnableMenuItem(hMenu, ID_HOST_REC_SOUND, now_rec ? MF_GRAYED : MF_ENABLED); EnableMenuItem(hMenu, ID_HOST_REC_STOP, now_stop ? MF_GRAYED : MF_ENABLED); +#ifdef SUPPORT_D2D1 + CheckMenuItem(hMenu, ID_HOST_USE_D2D1, config.use_d2d1 ? MF_CHECKED : MF_UNCHECKED); +#else + EnableMenuItem(hMenu, ID_HOST_USE_D2D1, MF_GRAYED); +#endif +#ifdef SUPPORT_D3D9 CheckMenuItem(hMenu, ID_HOST_USE_D3D9, config.use_d3d9 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(hMenu, ID_HOST_WAIT_VSYNC, config.wait_vsync ? MF_CHECKED : MF_UNCHECKED); EnableMenuItem(hMenu, ID_HOST_WAIT_VSYNC, config.use_d3d9 ? MF_ENABLED : MF_GRAYED); +#else + EnableMenuItem(hMenu, ID_HOST_USE_D3D9, MF_GRAYED); + EnableMenuItem(hMenu, ID_HOST_WAIT_VSYNC, MF_GRAYED); +#endif CheckMenuItem(hMenu, ID_HOST_USE_DINPUT, config.use_dinput ? MF_CHECKED : MF_UNCHECKED); @@ -1989,7 +2049,83 @@ void update_host_capture_menu(HMENU hMenu) } #endif -void update_menu(HWND hWnd, HMENU hMenu) +void update_toplevel_menu(HWND hWnd, HMENU hMenu) +{ + int count = GetMenuItemCount(hMenu); + for(int pos = 0; pos < count; pos++) { + HMENU hMenuSub = GetSubMenu(hMenu, pos); + if(hMenuSub) { + int count_sub = GetMenuItemCount(hMenuSub); + UINT id = -1; + for(int pos_sub = 0; pos_sub < count_sub; pos_sub++) { + if((id = GetMenuItemID(hMenuSub, pos_sub)) != -1) { + break; + } + } + if(id >= ID_CONTROL_MENU_START && id <= ID_CONTROL_MENU_END) { + + } +#ifdef USE_FLOPPY_DISK +#if USE_FLOPPY_DISK >= 1 + else if(id >= ID_FD1_MENU_START && id <= ID_FD1_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(0) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_FLOPPY_DISK >= 2 + else if(id >= ID_FD2_MENU_START && id <= ID_FD2_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(1) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_FLOPPY_DISK >= 3 + else if(id >= ID_FD3_MENU_START && id <= ID_FD3_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(2) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_FLOPPY_DISK >= 4 + else if(id >= ID_FD4_MENU_START && id <= ID_FD4_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(3) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_FLOPPY_DISK >= 5 + else if(id >= ID_FD5_MENU_START && id <= ID_FD5_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(4) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_FLOPPY_DISK >= 6 + else if(id >= ID_FD6_MENU_START && id <= ID_FD6_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(5) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_FLOPPY_DISK >= 7 + else if(id >= ID_FD7_MENU_START && id <= ID_FD7_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(6) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_FLOPPY_DISK >= 8 + else if(id >= ID_FD8_MENU_START && id <= ID_FD8_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_floppy_disk_connected(7) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#endif +#ifdef USE_QUICK_DISK +#if USE_QUICK_DISK >= 1 + else if(id >= ID_QD1_MENU_START && id <= ID_QD1_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_quick_disk_connected(0) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#if USE_QUICK_DISK >= 2 + else if(id >= ID_QD2_MENU_START && id <= ID_QD2_MENU_END) { + EnableMenuItem(hMenu, pos, (emu->is_quick_disk_connected(1) ? MF_ENABLED : MF_GRAYED) | MF_BYPOSITION); + } +#endif +#endif + } + } + // redraw menu bar + DrawMenuBar(hWnd); +} + +void update_popup_menu(HWND hWnd, HMENU hMenu) { int count = GetMenuItemCount(hMenu); UINT id = -1; @@ -2000,225 +2136,274 @@ void update_menu(HWND hWnd, HMENU hMenu) } if(id >= ID_CONTROL_MENU_START && id <= ID_CONTROL_MENU_END) { update_control_menu(hMenu); + } #ifdef USE_STATE - } else if(id >= ID_SAVE_MENU_START && id <= ID_SAVE_MENU_END) { + else if(id >= ID_SAVE_MENU_START && id <= ID_SAVE_MENU_END) { update_save_state_menu(hMenu); - } else if(id >= ID_LOAD_MENU_START && id <= ID_LOAD_MENU_END) { + } + else if(id >= ID_LOAD_MENU_START && id <= ID_LOAD_MENU_END) { update_load_state_menu(hMenu); + } #endif #ifdef USE_CART #if USE_CART >= 1 - } else if(id >= ID_CART1_MENU_START && id <= ID_CART1_MENU_END) { + else if(id >= ID_CART1_MENU_START && id <= ID_CART1_MENU_END) { update_cart_menu(hMenu, 0, ID_RECENT_CART1, ID_CLOSE_CART1); + } #endif #if USE_CART >= 2 - } else if(id >= ID_CART2_MENU_START && id <= ID_CART2_MENU_END) { + else if(id >= ID_CART2_MENU_START && id <= ID_CART2_MENU_END) { update_cart_menu(hMenu, 1, ID_RECENT_CART2, ID_CLOSE_CART2); + } #endif #endif #ifdef USE_FLOPPY_DISK #if USE_FLOPPY_DISK >= 1 - } else if(id >= ID_FD1_MENU_START && id <= ID_FD1_MENU_END) { + else if(id >= ID_FD1_MENU_START && id <= ID_FD1_MENU_END) { update_floppy_disk_menu(hMenu, 0, ID_RECENT_FD1, ID_D88_FILE_PATH1, ID_SELECT_D88_BANK1, ID_EJECT_D88_BANK1, ID_CLOSE_FD1, ID_WRITE_PROTECT_FD1, ID_CORRECT_TIMING_FD1, ID_IGNORE_CRC_FD1); + } #endif #if USE_FLOPPY_DISK >= 2 - } else if(id >= ID_FD2_MENU_START && id <= ID_FD2_MENU_END) { + else if(id >= ID_FD2_MENU_START && id <= ID_FD2_MENU_END) { update_floppy_disk_menu(hMenu, 1, ID_RECENT_FD2, ID_D88_FILE_PATH2, ID_SELECT_D88_BANK2, ID_EJECT_D88_BANK2, ID_CLOSE_FD2, ID_WRITE_PROTECT_FD2, ID_CORRECT_TIMING_FD2, ID_IGNORE_CRC_FD2); + } #endif #if USE_FLOPPY_DISK >= 3 - } else if(id >= ID_FD3_MENU_START && id <= ID_FD3_MENU_END) { + else if(id >= ID_FD3_MENU_START && id <= ID_FD3_MENU_END) { update_floppy_disk_menu(hMenu, 2, ID_RECENT_FD3, ID_D88_FILE_PATH3, ID_SELECT_D88_BANK3, ID_EJECT_D88_BANK3, ID_CLOSE_FD3, ID_WRITE_PROTECT_FD3, ID_CORRECT_TIMING_FD3, ID_IGNORE_CRC_FD3); + } #endif #if USE_FLOPPY_DISK >= 4 - } else if(id >= ID_FD4_MENU_START && id <= ID_FD4_MENU_END) { + else if(id >= ID_FD4_MENU_START && id <= ID_FD4_MENU_END) { update_floppy_disk_menu(hMenu, 3, ID_RECENT_FD4, ID_D88_FILE_PATH4, ID_SELECT_D88_BANK4, ID_EJECT_D88_BANK4, ID_CLOSE_FD4, ID_WRITE_PROTECT_FD4, ID_CORRECT_TIMING_FD4, ID_IGNORE_CRC_FD4); + } #endif #if USE_FLOPPY_DISK >= 5 - } else if(id >= ID_FD5_MENU_START && id <= ID_FD5_MENU_END) { + else if(id >= ID_FD5_MENU_START && id <= ID_FD5_MENU_END) { update_floppy_disk_menu(hMenu, 4, ID_RECENT_FD5, ID_D88_FILE_PATH5, ID_SELECT_D88_BANK5, ID_EJECT_D88_BANK5, ID_CLOSE_FD5, ID_WRITE_PROTECT_FD5, ID_CORRECT_TIMING_FD5, ID_IGNORE_CRC_FD5); + } #endif #if USE_FLOPPY_DISK >= 6 - } else if(id >= ID_FD6_MENU_START && id <= ID_FD6_MENU_END) { + else if(id >= ID_FD6_MENU_START && id <= ID_FD6_MENU_END) { update_floppy_disk_menu(hMenu, 5, ID_RECENT_FD6, ID_D88_FILE_PATH6, ID_SELECT_D88_BANK6, ID_EJECT_D88_BANK6, ID_CLOSE_FD6, ID_WRITE_PROTECT_FD6, ID_CORRECT_TIMING_FD6, ID_IGNORE_CRC_FD6); + } #endif #if USE_FLOPPY_DISK >= 7 - } else if(id >= ID_FD7_MENU_START && id <= ID_FD7_MENU_END) { + else if(id >= ID_FD7_MENU_START && id <= ID_FD7_MENU_END) { update_floppy_disk_menu(hMenu, 6, ID_RECENT_FD7, ID_D88_FILE_PATH7, ID_SELECT_D88_BANK7, ID_EJECT_D88_BANK7, ID_CLOSE_FD7, ID_WRITE_PROTECT_FD7, ID_CORRECT_TIMING_FD7, ID_IGNORE_CRC_FD7); + } #endif #if USE_FLOPPY_DISK >= 8 - } else if(id >= ID_FD8_MENU_START && id <= ID_FD8_MENU_END) { + else if(id >= ID_FD8_MENU_START && id <= ID_FD8_MENU_END) { update_floppy_disk_menu(hMenu, 7, ID_RECENT_FD8, ID_D88_FILE_PATH8, ID_SELECT_D88_BANK8, ID_EJECT_D88_BANK8, ID_CLOSE_FD8, ID_WRITE_PROTECT_FD8, ID_CORRECT_TIMING_FD8, ID_IGNORE_CRC_FD8); + } #endif #endif #ifdef USE_QUICK_DISK #if USE_QUICK_DISK >= 1 - } else if(id >= ID_QD1_MENU_START && id <= ID_QD1_MENU_END) { + else if(id >= ID_QD1_MENU_START && id <= ID_QD1_MENU_END) { update_quick_disk_menu(hMenu, 0, ID_RECENT_QD1, ID_CLOSE_QD1); + } #endif #if USE_QUICK_DISK >= 2 - } else if(id >= ID_QD2_MENU_START && id <= ID_QD2_MENU_END) { + else if(id >= ID_QD2_MENU_START && id <= ID_QD2_MENU_END) { update_quick_disk_menu(hMenu, 1, ID_RECENT_QD2, ID_CLOSE_QD2); + } #endif #endif #ifdef USE_HARD_DISK #if USE_HARD_DISK >= 1 - } else if(id >= ID_HD1_MENU_START && id <= ID_HD1_MENU_END) { + else if(id >= ID_HD1_MENU_START && id <= ID_HD1_MENU_END) { update_hard_disk_menu(hMenu, 0, ID_RECENT_HD1, ID_CLOSE_HD1); + } #endif #if USE_HARD_DISK >= 2 - } else if(id >= ID_HD2_MENU_START && id <= ID_HD2_MENU_END) { + else if(id >= ID_HD2_MENU_START && id <= ID_HD2_MENU_END) { update_hard_disk_menu(hMenu, 1, ID_RECENT_HD2, ID_CLOSE_HD2); + } #endif #if USE_HARD_DISK >= 3 - } else if(id >= ID_HD3_MENU_START && id <= ID_HD3_MENU_END) { + else if(id >= ID_HD3_MENU_START && id <= ID_HD3_MENU_END) { update_hard_disk_menu(hMenu, 2, ID_RECENT_HD3, ID_CLOSE_HD3); + } #endif #if USE_HARD_DISK >= 4 - } else if(id >= ID_HD4_MENU_START && id <= ID_HD4_MENU_END) { + else if(id >= ID_HD4_MENU_START && id <= ID_HD4_MENU_END) { update_hard_disk_menu(hMenu, 3, ID_RECENT_HD4, ID_CLOSE_HD4); + } #endif #if USE_HARD_DISK >= 5 - } else if(id >= ID_HD5_MENU_START && id <= ID_HD5_MENU_END) { + else if(id >= ID_HD5_MENU_START && id <= ID_HD5_MENU_END) { update_hard_disk_menu(hMenu, 4, ID_RECENT_HD5, ID_CLOSE_HD5); + } #endif #if USE_HARD_DISK >= 6 - } else if(id >= ID_HD6_MENU_START && id <= ID_HD6_MENU_END) { + else if(id >= ID_HD6_MENU_START && id <= ID_HD6_MENU_END) { update_hard_disk_menu(hMenu, 5, ID_RECENT_HD6, ID_CLOSE_HD6); + } #endif #if USE_HARD_DISK >= 7 - } else if(id >= ID_HD7_MENU_START && id <= ID_HD7_MENU_END) { + else if(id >= ID_HD7_MENU_START && id <= ID_HD7_MENU_END) { update_hard_disk_menu(hMenu, 6, ID_RECENT_HD7, ID_CLOSE_HD7); + } #endif #if USE_HARD_DISK >= 8 - } else if(id >= ID_HD8_MENU_START && id <= ID_HD8_MENU_END) { + else if(id >= ID_HD8_MENU_START && id <= ID_HD8_MENU_END) { update_hard_disk_menu(hMenu, 7, ID_RECENT_HD8, ID_CLOSE_HD8); + } #endif #endif #ifdef USE_TAPE #if USE_TAPE >= 1 - } else if(id >= ID_TAPE1_MENU_START && id <= ID_TAPE1_MENU_END) { + else if(id >= ID_TAPE1_MENU_START && id <= ID_TAPE1_MENU_END) { update_tape_menu(hMenu, 0, ID_RECENT_TAPE1, ID_CLOSE_TAPE1, ID_PLAY_BUTTON1, ID_STOP_BUTTON1, ID_FAST_FORWARD1, ID_FAST_REWIND1, ID_APSS_FORWARD1, ID_APSS_REWIND1, ID_USE_WAVE_SHAPER1, ID_DIRECT_LOAD_MZT1, ID_TAPE_BAUD_LOW1, ID_TAPE_BAUD_HIGH1); + } #endif #if USE_TAPE >= 2 - } else if(id >= ID_TAPE2_MENU_START && id <= ID_TAPE2_MENU_END) { + else if(id >= ID_TAPE2_MENU_START && id <= ID_TAPE2_MENU_END) { update_tape_menu(hMenu, 1, ID_RECENT_TAPE2, ID_CLOSE_TAPE2, ID_PLAY_BUTTON2, ID_STOP_BUTTON2, ID_FAST_FORWARD2, ID_FAST_REWIND2, ID_APSS_FORWARD2, ID_APSS_REWIND2, ID_USE_WAVE_SHAPER2, ID_DIRECT_LOAD_MZT2, ID_TAPE_BAUD_LOW2, ID_TAPE_BAUD_HIGH2); + } #endif #endif #ifdef USE_COMPACT_DISC #if USE_COMPACT_DISC >= 1 - } else if(id >= ID_COMPACT_DISC1_MENU_START && id <= ID_COMPACT_DISC1_MENU_END) { + else if(id >= ID_COMPACT_DISC1_MENU_START && id <= ID_COMPACT_DISC1_MENU_END) { update_compact_disc_menu(hMenu, 0, ID_RECENT_COMPACT_DISC1, ID_CLOSE_COMPACT_DISC1); + } #endif #if USE_COMPACT_DISC >= 2 - } else if(id >= ID_COMPACT_DISC2_MENU_START && id <= ID_COMPACT_DISC2_MENU_END) { + else if(id >= ID_COMPACT_DISC2_MENU_START && id <= ID_COMPACT_DISC2_MENU_END) { update_compact_disc_menu(hMenu, 1, ID_RECENT_COMPACT_DISC2, ID_CLOSE_COMPACT_DISC2); + } #endif #endif #ifdef USE_LASER_DISC #if USE_LASER_DISC >= 1 - } else if(id >= ID_LASER_DISC1_MENU_START && id <= ID_LASER_DISC1_MENU_END) { + else if(id >= ID_LASER_DISC1_MENU_START && id <= ID_LASER_DISC1_MENU_END) { update_laser_disc_menu(hMenu, 0, ID_RECENT_LASER_DISC1, ID_CLOSE_LASER_DISC1); + } #endif #if USE_LASER_DISC >= 2 - } else if(id >= ID_LASER_DISC2_MENU_START && id <= ID_LASER_DISC2_MENU_END) { + else if(id >= ID_LASER_DISC2_MENU_START && id <= ID_LASER_DISC2_MENU_END) { update_laser_disc_menu(hMenu, 1, ID_RECENT_LASER_DISC2, ID_CLOSE_LASER_DISC2); + } #endif #endif #ifdef USE_BINARY_FILE #if USE_BINARY_FILE >= 1 - } else if(id >= ID_BINARY1_MENU_START && id <= ID_BINARY1_MENU_END) { + else if(id >= ID_BINARY1_MENU_START && id <= ID_BINARY1_MENU_END) { update_binary_menu(hMenu, 0, ID_RECENT_BINARY1); + } #endif #if USE_BINARY_FILE >= 2 - } else if(id >= ID_BINARY2_MENU_START && id <= ID_BINARY2_MENU_END) { + else if(id >= ID_BINARY2_MENU_START && id <= ID_BINARY2_MENU_END) { update_binary_menu(hMenu, 1, ID_RECENT_BINARY2); + } #endif #endif #ifdef USE_BUBBLE #if USE_BUBBLE >= 1 - } else if(id >= ID_BUBBLE1_MENU_START && id <= ID_BUBBLE1_MENU_END) { + else if(id >= ID_BUBBLE1_MENU_START && id <= ID_BUBBLE1_MENU_END) { update_bubble_casette_menu(hMenu, 0, ID_RECENT_BUBBLE1); + } #endif #if USE_BUBBLE >= 2 - } else if(id >= ID_BUBBLE2_MENU_START && id <= ID_BUBBLE2_MENU_END) { + else if(id >= ID_BUBBLE2_MENU_START && id <= ID_BUBBLE2_MENU_END) { update_bubble_casette_menu(hMenu, 1, ID_RECENT_BUBBLE2); + } #endif #endif #ifdef USE_BOOT_MODE - } else if(id >= ID_VM_BOOT_MENU_START && id <= ID_VM_BOOT_MENU_END) { - update_vm_boot_menu(hMenu); + else if(id >= ID_VM_BOOT_MENU_START && id <= ID_VM_BOOT_MENU_END) { + update_vm_boot_menu(hMenu); + } #endif #ifdef USE_CPU_TYPE - } else if(id >= ID_VM_CPU_MENU_START && id <= ID_VM_CPU_MENU_END) { - update_vm_cpu_menu(hMenu); + else if(id >= ID_VM_CPU_MENU_START && id <= ID_VM_CPU_MENU_END) { + update_vm_cpu_menu(hMenu); + } #endif #ifdef USE_DIPSWITCH - } else if(id >= ID_VM_DIPSWITCH_MENU_START && id <= ID_VM_DIPSWITCH_MENU_END) { - update_vm_dipswitch_menu(hMenu); + else if(id >= ID_VM_DIPSWITCH_MENU_START && id <= ID_VM_DIPSWITCH_MENU_END) { + update_vm_dipswitch_menu(hMenu); + } #endif #ifdef USE_DEVICE_TYPE - } else if(id >= ID_VM_DEVICE_MENU_START && id <= ID_VM_DEVICE_MENU_END) { - update_vm_device_menu(hMenu); + else if(id >= ID_VM_DEVICE_MENU_START && id <= ID_VM_DEVICE_MENU_END) { + update_vm_device_menu(hMenu); + } #endif #ifdef USE_DRIVE_TYPE - } else if(id >= ID_VM_DRIVE_MENU_START && id <= ID_VM_DRIVE_MENU_END) { - update_vm_drive_menu(hMenu); + else if(id >= ID_VM_DRIVE_MENU_START && id <= ID_VM_DRIVE_MENU_END) { + update_vm_drive_menu(hMenu); + } #endif #ifdef USE_KEYBOARD_TYPE - } else if(id >= ID_VM_KEYBOARD_MENU_START && id <= ID_VM_KEYBOARD_MENU_END) { - update_vm_keyboard_menu(hMenu); + else if(id >= ID_VM_KEYBOARD_MENU_START && id <= ID_VM_KEYBOARD_MENU_END) { + update_vm_keyboard_menu(hMenu); + } #endif #ifdef USE_MOUSE_TYPE - } else if(id >= ID_VM_MOUSE_MENU_START && id <= ID_VM_MOUSE_MENU_END) { - update_vm_mouse_menu(hMenu); + else if(id >= ID_VM_MOUSE_MENU_START && id <= ID_VM_MOUSE_MENU_END) { + update_vm_mouse_menu(hMenu); + } #endif #ifdef USE_JOYSTICK_TYPE - } else if(id >= ID_VM_JOYSTICK_MENU_START && id <= ID_VM_JOYSTICK_MENU_END) { - update_vm_joystick_menu(hMenu); + else if(id >= ID_VM_JOYSTICK_MENU_START && id <= ID_VM_JOYSTICK_MENU_END) { + update_vm_joystick_menu(hMenu); + } #endif #if defined(USE_SOUND_TYPE) || defined(USE_FLOPPY_DISK) || defined(USE_TAPE) || defined(USE_DIPSWITCH) - } else if(id >= ID_VM_SOUND_MENU_START && id <= ID_VM_SOUND_MENU_END) { -#if defined(USE_SOUND_TYPE) || defined(USE_FLOPPY_DISK) || defined(USE_TAPE) - update_vm_sound_menu(hMenu); -#endif -#ifdef USE_DIPSWITCH - // dipswitch may be in sound menu - update_vm_dipswitch_menu(hMenu); -#endif + else if(id >= ID_VM_SOUND_MENU_START && id <= ID_VM_SOUND_MENU_END) { + #if defined(USE_SOUND_TYPE) || defined(USE_FLOPPY_DISK) || defined(USE_TAPE) + update_vm_sound_menu(hMenu); + #endif + #ifdef USE_DIPSWITCH + // dipswitch may be in sound menu + update_vm_dipswitch_menu(hMenu); + #endif + } #endif #if defined(USE_MONITOR_TYPE) || defined(USE_SCANLINE) || defined(USE_DIPSWITCH) - } else if(id >= ID_VM_MONITOR_MENU_START && id <= ID_VM_MONITOR_MENU_END) { -#if defined(USE_MONITOR_TYPE) || defined(USE_SCANLINE) - update_vm_monitor_menu(hMenu); -#endif -#ifdef USE_DIPSWITCH - // dipswitch may be in monitor menu - update_vm_dipswitch_menu(hMenu); -#endif + else if(id >= ID_VM_MONITOR_MENU_START && id <= ID_VM_MONITOR_MENU_END) { + #if defined(USE_MONITOR_TYPE) || defined(USE_SCANLINE) + update_vm_monitor_menu(hMenu); + #endif + #ifdef USE_DIPSWITCH + // dipswitch may be in monitor menu + update_vm_dipswitch_menu(hMenu); + #endif + } #endif #ifdef USE_PRINTER_TYPE - } else if(id >= ID_VM_PRINTER_MENU_START && id <= ID_VM_PRINTER_MENU_START) { - update_vm_printer_menu(hMenu); + else if(id >= ID_VM_PRINTER_MENU_START && id <= ID_VM_PRINTER_MENU_START) { + update_vm_printer_menu(hMenu); + } #endif - } else if(id >= ID_HOST_MENU_START && id <= ID_HOST_MENU_END) { + else if(id >= ID_HOST_MENU_START && id <= ID_HOST_MENU_END) { update_host_menu(hMenu); + } #ifndef ONE_BOARD_MICRO_COMPUTER - } else if(id >= ID_SCREEN_MENU_START && id <= ID_SCREEN_MENU_END) { + else if(id >= ID_SCREEN_MENU_START && id <= ID_SCREEN_MENU_END) { update_host_screen_menu(hMenu); + } #endif #ifdef USE_SCREEN_FILTER - } else if(id >= ID_FILTER_MENU_START && id <= ID_FILTER_MENU_END) { + else if(id >= ID_FILTER_MENU_START && id <= ID_FILTER_MENU_END) { update_host_filter_menu(hMenu); + } #endif - } else if(id >= ID_SOUND_MENU_START && id <= ID_SOUND_MENU_END) { + else if(id >= ID_SOUND_MENU_START && id <= ID_SOUND_MENU_END) { update_host_sound_menu(hMenu); - } else if(id >= ID_INPUT_MENU_START && id <= ID_INPUT_MENU_END) { + } + else if(id >= ID_INPUT_MENU_START && id <= ID_INPUT_MENU_END) { update_host_input_menu(hMenu); + } #ifdef USE_VIDEO_CAPTURE - } else if(id >= ID_CAPTURE_MENU_START && id <= ID_CAPTURE_MENU_END) { + else if(id >= ID_CAPTURE_MENU_START && id <= ID_CAPTURE_MENU_END) { update_host_capture_menu(hMenu); -#endif } +#endif DrawMenuBar(hWnd); } @@ -2439,7 +2624,7 @@ void update_status_bar(HINSTANCE hInstance, LPDRAWITEMSTRUCT lpDrawItem) TextOut(lpDrawItem->hDC, draw_left, text_top, _T("CMT:"), 4); GetTextExtentPoint32(lpDrawItem->hDC, _T("CMT:"), 4, &size); draw_left += size.cx + 4; - TextOut(lpDrawItem->hDC, draw_left, text_top, tape_status, _tcslen(tape_status)); + TextOut(lpDrawItem->hDC, draw_left, text_top, tape_status, (int)_tcslen(tape_status)); } #endif } @@ -2538,10 +2723,14 @@ void open_blank_floppy_disk_dialog(HWND hWnd, int drv, uint8_t type) config.initial_floppy_disk_dir, _MAX_PATH ); if(path) { - UPDATE_HISTORY(path, config.recent_floppy_disk_path[drv]); - my_tcscpy_s(config.initial_floppy_disk_dir, _MAX_PATH, get_parent_dir(path)); - emu->create_bank_floppy_disk(path, type); - open_floppy_disk(drv, path, 0); + if(!check_file_extension(path, _T(".d88")) && !check_file_extension(path, _T(".d77"))) { + my_tcscat_s(path, _MAX_PATH, _T(".d88")); + } + if(emu->create_blank_floppy_disk(path, type)) { + UPDATE_HISTORY(path, config.recent_floppy_disk_path[drv]); + my_tcscpy_s(config.initial_floppy_disk_dir, _MAX_PATH, get_parent_dir(path)); + open_floppy_disk(drv, path, 0); + } } } @@ -2672,6 +2861,27 @@ void open_recent_hard_disk(int drv, int index) my_tcscpy_s(config.recent_hard_disk_path[drv][0], _MAX_PATH, path); emu->open_hard_disk(drv, path); } + +void open_blank_hard_disk_dialog(HWND hWnd, int drv, int sector_size, int sectors, int surfaces, int cylinders) +{ + _TCHAR* path = get_open_file_name( + hWnd, + _T("Supported Files (*.hdi;*.nhd)\0*.hdi;*.nhd\0All Files (*.*)\0*.*\0\0"), + _T("Hard Disk"), + create_date_file_name(_T("hdi")), + config.initial_hard_disk_dir, _MAX_PATH + ); + if(path) { + if(!check_file_extension(path, _T(".hdi")) && !check_file_extension(path, _T(".nhd"))) { + my_tcscat_s(path, _MAX_PATH, _T(".hdi")); + } + if(emu->create_blank_hard_disk(path, sector_size, sectors, surfaces, cylinders)) { + UPDATE_HISTORY(path, config.recent_hard_disk_path[drv]); + my_tcscpy_s(config.initial_hard_disk_dir, _MAX_PATH, get_parent_dir(path)); + emu->open_hard_disk(drv, path); + } + } +} #endif #ifdef USE_TAPE @@ -3189,7 +3399,7 @@ void start_auto_key() HANDLE hClip = GetClipboardData(CF_TEXT); if(hClip) { char* buf = (char*)GlobalLock(hClip); - int size = strlen(buf); + int size = (int)strlen(buf); if(size > 0) { emu->stop_auto_key(); @@ -3208,7 +3418,7 @@ void start_auto_key() // ---------------------------------------------------------------------------- #ifdef USE_SOUND_VOLUME -BOOL CALLBACK VolumeWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) +INT_PTR CALLBACK VolumeWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) { case WM_CLOSE: @@ -3232,8 +3442,8 @@ BOOL CALLBACK VolumeWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) switch(LOWORD(wParam)) { case IDOK: for(int i = 0; i < USE_SOUND_VOLUME; i++) { - config.sound_volume_l[i] = SendDlgItemMessage(hDlg, IDC_VOLUME_PARAM_L0 + i, TBM_GETPOS, 0, 0); - config.sound_volume_r[i] = SendDlgItemMessage(hDlg, IDC_VOLUME_PARAM_R0 + i, TBM_GETPOS, 0, 0); + config.sound_volume_l[i] = (int)SendDlgItemMessage(hDlg, IDC_VOLUME_PARAM_L0 + i, TBM_GETPOS, 0, 0); + config.sound_volume_r[i] = (int)SendDlgItemMessage(hDlg, IDC_VOLUME_PARAM_R0 + i, TBM_GETPOS, 0, 0); emu->set_sound_device_volume(i, config.sound_volume_l[i], config.sound_volume_r[i]); } EndDialog(hDlg, IDOK); @@ -3493,7 +3703,7 @@ LRESULT CALLBACK JoySubProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) return CallWindowProc(JoyOldProc[index], hWnd, iMsg, wParam, lParam); } -BOOL CALLBACK JoyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) +INT_PTR CALLBACK JoyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) { case WM_CLOSE: @@ -3513,8 +3723,14 @@ BOOL CALLBACK JoyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) #endif SetDlgItemText(hDlg, IDC_JOYSTICK_CAPTION0 + i, joy_button_names[i]); set_joy_button_text(i); +#ifdef _M_AMD64 + // thanks Marukun (64bit) + JoyOldProc[i] = (WNDPROC)GetWindowLongPtr(hJoyEdit[i], GWLP_WNDPROC); + SetWindowLongPtr(hJoyEdit[i], GWLP_WNDPROC, (LONG_PTR)JoySubProc); +#else JoyOldProc[i] = (WNDPROC)GetWindowLong(hJoyEdit[i], GWL_WNDPROC); SetWindowLong(hJoyEdit[i], GWL_WNDPROC, (LONG)JoySubProc); +#endif } } memset(joy_status, 0, sizeof(joy_status)); @@ -3557,12 +3773,12 @@ BOOL CALLBACK JoyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) } break; default: - return FALSE; + return (INT_PTR)FALSE; } - return TRUE; + return (INT_PTR)TRUE; } -BOOL CALLBACK JoyToKeyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) +INT_PTR CALLBACK JoyToKeyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch(iMsg) { case WM_CLOSE: @@ -3581,8 +3797,14 @@ BOOL CALLBACK JoyToKeyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam joy_button_params[i] = config.joy_to_key_buttons[i]; if((hJoyEdit[i] = GetDlgItem(hDlg, IDC_JOYSTICK_PARAM0 + i)) != NULL) { set_joy_button_text(i); +#ifdef _M_AMD64 + // thanks Marukun (64bit) + JoyOldProc[i] = (WNDPROC)GetWindowLongPtr(hJoyEdit[i], GWLP_WNDPROC); + SetWindowLongPtr(hJoyEdit[i], GWLP_WNDPROC, (LONG_PTR)JoySubProc); +#else JoyOldProc[i] = (WNDPROC)GetWindowLong(hJoyEdit[i], GWL_WNDPROC); SetWindowLong(hJoyEdit[i], GWL_WNDPROC, (LONG)JoySubProc); +#endif } } memset(joy_status, 0, sizeof(joy_status)); @@ -3617,7 +3839,7 @@ BOOL CALLBACK JoyToKeyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam } break; default: - return FALSE; + return (INT_PTR)FALSE; } break; case WM_TIMER: @@ -3637,9 +3859,9 @@ BOOL CALLBACK JoyToKeyWndProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam } break; default: - return FALSE; + return (INT_PTR)FALSE; } - return TRUE; + return (INT_PTR)TRUE; } #endif @@ -3703,8 +3925,13 @@ void create_buttons(HWND hWnd) vm_buttons[i].x, vm_buttons[i].y, vm_buttons[i].width, vm_buttons[i].height, hWnd, (HMENU)(ID_BUTTON + i), (HINSTANCE)GetModuleHandle(0), NULL); +#ifdef _M_AMD64 + ButtonOldProc[i] = (WNDPROC)GetWindowLongPtr(hButton[i], GWLP_WNDPROC); + SetWindowLongPtr(hButton[i], GWLP_WNDPROC, (LONG_PTR)ButtonSubProc); +#else ButtonOldProc[i] = (WNDPROC)(LONG_PTR)GetWindowLong(hButton[i], GWL_WNDPROC); SetWindowLong(hButton[i], GWL_WNDPROC, (LONG)(LONG_PTR)ButtonSubProc); +#endif } } diff --git a/source/tool/cross-build/Qt5.15/config_sample.5.15.sh b/source/tool/cross-build/Qt5.15/config_sample.5.15.sh new file mode 100755 index 000000000..4dd17c49e --- /dev/null +++ b/source/tool/cross-build/Qt5.15/config_sample.5.15.sh @@ -0,0 +1,98 @@ +#!/bin/sh + +DIRECTX_ARCH=x86 +#DIRECCX_ARCH=x64 + +SDK_PREFIX="/usr/local/i586-mingw-msvc" +SDK_PREFIX_DIRECTX="/usr/local/i586-mingw-msvc/DirectX_June_2010" + +VULKAN_SDK="${SDK_PREFIX}/Vulkan" +LLVM_INSTALL_DIR="/opt/llvm-mingw-11" + +ADDITIONAL_FLAGS="" +BUILD_WITH_VULKAN=1 + +#export PATH="$PATH:~/src/fxc2" +export PATH="/opt/llvm-mingw/bin:$PATH:$SDK_PREFIX" +export PATH="$PATH:$SDK_PREFIX/icu/bin" +export PATH="$PATH:$SDK_PREFIX/icu/lib" +export PATH="$PATH:$SDK_PREFIX/Angle/bin" +export PATH="$PATH:$SDK_PREFIX/SDL/i686-w64-mingw32/bin" +export PATH="$PATH:$SDK_PREFIX_DIRECTX/Utilities/bin/${DIRECTX_ARCH}" +export PATH="$PATH:$SDK_PREFIX_DIRECTX/Developer Runtime/${DIRECTX_ARCH}" +export PATH="$PATH:$VULKAN_SDK/bin" + +export PKG_CONFIG_LIBDIR=${SDK_PREFIX}/pkgconfig/lib +export PKG_CONFIG_PATH=${SDK_PREFIX}/pkgconfig/lib/pkgconfig +export PKG_CONFIG_SYSROOT_DIR=${SDK_PREFIX}/pkgconfig +#export QMAKE_DXSDK_DIR=${SDK_PREFIX}/DirectX_June_2010/ + +if [ ${BUILD_WITH_VULKAN} -ne 0 ] ; then + ADDITIONAL_FLAGS="${ADDITIONAL_FLAGS} \ + -device-option VULKAN_PREFIX=$VULKAN_SDK \ + -device-option QMAKE_INCDIR_VULKAN=$VULKAN_SDK/include \ + -device-option QMAKE_LIBDIR_VULKAN=$VULKAN_SDK/lib \ + -I $VULKAN_SDK/include \ + -I $VULKAN_SDK/include/vulkan \ + -L $VULKAN_SDK/lib \ + -L $VULKAN_SDK/bin \ + -vulkan " +fi + +#wine ./qtbase/configure.exe \ +./configure \ + -release \ + -opensource -confirm-license \ + -device-option CROSS_COMPILE=i686-w64-mingw32- \ + -optimized-tools \ + -platform linux-g++ \ + -prefix ${SDK_PREFIX}/Qt5.15/mingw_82x \ + -xplatform win32-clang-g++ \ + -qt-libpng \ + -qt-libjpeg \ + -qt-freetype \ + -device-option LLVM_INSTALL_DIR="${LLVM_INSTALL_DIR}" \ + -I ${SDK_PREFIX}/Angle/include \ + -L ${SDK_PREFIX}/Angle/lib \ + -L ${SDK_PREFIX}/Angle/bin \ + -I $SDK_PREFIX/SDL/i686-w64-mingw32/include/SDL2 \ + -I $SDK_PREFIX/SDL/i686-w64-mingw32/include \ + -L $SDK_PREFIX/SDL/i686-w64-mingw32/lib \ + -I ${SDK_PREFIX_DIRECTX}/Include \ + -L ${SDK_PREFIX_DIRECTX}/Lib/${DIRECTX_ARCH} \ + -I $SDK_PREFIX/icu/include \ + -L $SDK_PREFIX/icu/lib \ + -device-option SDL_PREFIX=$SDK_PREFIX/SDL/i686-w64-mingw32 \ + -device-option SDL2_PREFIX=$SDK_PREFIX/SDL/i686-w64-mingw32 \ + -device-option LIBS_SDL2+=SDLmain \ + -device-option ICU_PREFIX=$SDK_PREFIX/icu \ + -device-option LIBS_OPENGL_ES2+=GLESv2 \ + -device-option LIBS_OPENGL_ES2+=EGL \ + -device-option LIBEGL_NAME=EGL.dll \ + -device-option LIBGLESV2_NAME=GLESv2.dll \ + -device-option OPENGL_ES2_PREFIX=$SDK_PREFIX/Angle \ + -device-option QMAKE_DXSDK_DIR=${SDK_PREFIX_DIRECTX} \ + -device-option DXSDK_DIR=${SDK_PREFIX_DIRECTX} \ + -device-option QSG_RHI=1 \ + -opengl dynamic \ + -no-eglfs \ + -no-evr \ + -feature-direct3d9 \ + -feature-dxguid \ + -feature-direct3d11 \ + -pkg-config \ + -icu \ + -skip qtactiveqt \ + -skip qtlocation \ + -skip qtwebglplugin \ + -skip qtwebengine \ + -skip qtwebview \ + -skip qtconnectivity \ + -nomake tests \ + -c++std c++17 \ + ${ADDITIONAL_FLAGS} \ + $@ + +# -angle \ +# -device-option QMAKE_INCDIR_OPENGL_ES2="${SDK_PREFIX}/Angle/include" \ +# -device-option QMAKE_LIBDIR_OPENGL_ES2="${SDK_PREFIX}/Angle/lib" \ diff --git a/source/tool/cross-build/Qt5.15/make_cross.sh b/source/tool/cross-build/Qt5.15/make_cross.sh new file mode 100755 index 000000000..0e79a0ad8 --- /dev/null +++ b/source/tool/cross-build/Qt5.15/make_cross.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +export LLVM_INSTALL_DIR="/opt/llvm-mingw-11" +export __QT_SDK_PREFIX="/usr/local/i586-mingw-msvc" +export __CROSS_ARCH=i686-w64-mingw32- +export __QT_SDK_PREFIX_DIRECTX="/usr/local/i586-mingw-msvc/DirectX_June_2010" + +export PATH="${LLVM_INSTALL_DIR}/bin:\ + $PATH:\ + ${__QT_SDK_PREFIX}/icu/bin:\ + ${__QT_SDK_PREFIX}/Angle/bin:\ + ${__QT_SDK_PREFIX}/SDL/i686-w64-mingw32/bin: \ + ${__QT_SDK_PREFIX_DIRECTX}/Developer Runtime/x86 \ + " + +export PKG_CONFIG_LIBDIR=${__QT_SDK_PREFIX}/pkgconfig/lib + +#taskset 0xfbe make CROSS_COMPILE=i686-w64-mingw32- PKG_CONFIG_LIBDIR=/usr/i686-w64-mingw32/lib $@ 2>&1 +make \ + CROSS_COMPILE=${__CROSS_ARCH} \ + PKG_CONFIG_LIBDIR=${PKG_CONFIG_LIBDIR} \ + $@ 2>&1 \ No newline at end of file diff --git a/source/tool/cross-build/Qt5.15/patches/000_qtgamepad_config.test.mingw32.patch b/source/tool/cross-build/Qt5.15/patches/000_qtgamepad_config.test.mingw32.patch new file mode 100644 index 000000000..9ea113a69 --- /dev/null +++ b/source/tool/cross-build/Qt5.15/patches/000_qtgamepad_config.test.mingw32.patch @@ -0,0 +1,24 @@ +--- main.cpp.orig 2019-08-26 22:51:44.229281866 +0900 ++++ main.cpp 2019-08-26 22:56:32.169706856 +0900 +@@ -34,6 +34,8 @@ + ** + ****************************************************************************/ + ++#include ++#include + #include + #include + +@@ -43,3 +45,12 @@ + SDL_Quit(); + return 0; + } ++ ++int WINAPI WinMain( ++ HINSTANCE hCurInst, ++ HINSTANCE hPrevInst, ++ LPSTR lpsCmdLine, ++ int nCmdShow) ++{ ++ return main(0, NULL); ++} diff --git a/source/tool/cross-build/bootstrap-build-ogg.sh b/source/tool/cross-build/bootstrap-build-ogg.sh new file mode 100644 index 000000000..131292c33 --- /dev/null +++ b/source/tool/cross-build/bootstrap-build-ogg.sh @@ -0,0 +1,17 @@ +#!/bin/sh +export PATH="/opt/llvm-mingw/bin:/usr/local/i586-mingw-msvc/lame-3.100/bin:$PATH" +export CC=i686-w64-mingw32-clang +export CXX=i686-w64-mingw32-clang++ +#export LD=/usr/bin/i686-w64-mingw32-ld +export PKG_CONFIG_PATH=/usr/local/i586-mingw-msvc/pkgconfig/lib/pkgconfig + +./configure --host=i686-w64-mingw32 \ + --prefix=/usr/local/i586-mingw-msvc/ogg \ + --disable-static --enable-shared \ + +# -I/usr/local/i586-mingw-msvc/libx264-158/include \ +# -I/usr/local/i586-mingw-msvc/libvorbis/include \ +# -I/usr/local/i586-mingw-msvc/libogg/include \ +# -L/usr/local/i586-mingw-msvc/libvorbis/lib \ +# -L/usr/local/i586-mingw-msvc/libogg/lib \ +# -L/usr/local/i586-mingw-msvc/libx264-158/lib \ diff --git a/source/tool/cross-build/bootstrap-build-vorbis.sh b/source/tool/cross-build/bootstrap-build-vorbis.sh new file mode 100644 index 000000000..0f0d7113a --- /dev/null +++ b/source/tool/cross-build/bootstrap-build-vorbis.sh @@ -0,0 +1,18 @@ +#!/bin/sh +export PATH="/opt/llvm-mingw/bin:/usr/local/i586-mingw-msvc/lame-3.100/bin:$PATH" +export CC=i686-w64-mingw32-clang +export CXX=i686-w64-mingw32-clang++ +#export LD=/usr/bin/i686-w64-mingw32-ld +export PKG_CONFIG_PATH=/usr/local/i586-mingw-msvc/pkgconfig/lib/pkgconfig + +./configure --host=i686-w64-mingw32 \ + --prefix=/usr/local/i586-mingw-msvc/vorbis \ + --disable-static --enable-shared \ + --with-ogg=/usr/local/i586-mingw-msvc/libogg + +# -I/usr/local/i586-mingw-msvc/libx264-158/include \ +# -I/usr/local/i586-mingw-msvc/libvorbis/include \ +# -I/usr/local/i586-mingw-msvc/libogg/include \ +# -L/usr/local/i586-mingw-msvc/libvorbis/lib \ +# -L/usr/local/i586-mingw-msvc/libogg/lib \ +# -L/usr/local/i586-mingw-msvc/libx264-158/lib \ diff --git a/source/tool/cross-build/bootstrap_pcre.sh b/source/tool/cross-build/bootstrap_pcre.sh new file mode 100644 index 000000000..d68b179ce --- /dev/null +++ b/source/tool/cross-build/bootstrap_pcre.sh @@ -0,0 +1,11 @@ +#!/bin/sh +PATH=/opt/llvm-mingw/bin:$PATH +CFLAGS="-I/usr/i686-w64-mingw32/include" +LDFLAGS="-L/usr/i686-w64-mingw32/lib" +./configure --host=i686-w64-mingw32 \ + --enable-pcre2-16 --enable-pcre2-32 \ + --enable-pic --enable-shared \ + --prefix=/usr/local/i586-mingw-msvc/pcre2 + + #--enable-static + diff --git a/source/tool/cross-build/ffmpeg/bootstrap-build_ffmpeg4.2_cross.sh b/source/tool/cross-build/ffmpeg/bootstrap-build_ffmpeg4.2_cross.sh new file mode 100644 index 000000000..a7d28426f --- /dev/null +++ b/source/tool/cross-build/ffmpeg/bootstrap-build_ffmpeg4.2_cross.sh @@ -0,0 +1,37 @@ +#!/bin/sh +PATH="/opt/llvm-mingw/bin:/usr/local/i586-mingw-msvc/lame-3.100/bin:$PATH" +CC=clang +CXX=clang++ +#export LD=/usr/bin/i686-w64-mingw32-ld +export PKG_CONFIG_PATH=/usr/local/i586-mingw-msvc/pkgconfig/lib/pkgconfig + +./configure --cross-prefix=i686-w64-mingw32- \ + --prefix=/usr/local/i586-mingw-msvc/ffmpeg-4.2 \ + --pkgconfigdir=/usr/local/i586-mingw-msvc/pkgconfig/lib/pkgconfig \ + --disable-static --enable-shared \ + --target-os=mingw32 --arch=i686 \ + --disable-inline-asm \ + --disable-sse4 \ + --disable-ssse3 \ + --host-cc=gcc \ + --enable-gpl \ + --enable-libx264 \ + --enable-libvorbis \ + --enable-libmp3lame \ + --enable-dxva2 \ + --extra-cflags=" \ + -I/opt/llvm-mingw/include \ + -I/usr/local/i586-mingw-msvc/lame-3.100/include \ + -m32" \ + --extra-ldflags=" \ + -L/opt/llvm-mingw/lib \ + -L/opt/llvm-mingw/i686-w64-mingw32/lib \ + -L/usr/i686-w64-mingw32/lib \ + -L/usr/local/i586-mingw-msvc/lame-3.100/lib \ + " +# -I/usr/local/i586-mingw-msvc/libx264-158/include \ +# -I/usr/local/i586-mingw-msvc/libvorbis/include \ +# -I/usr/local/i586-mingw-msvc/libogg/include \ +# -L/usr/local/i586-mingw-msvc/libvorbis/lib \ +# -L/usr/local/i586-mingw-msvc/libogg/lib \ +# -L/usr/local/i586-mingw-msvc/libx264-158/lib \ diff --git a/source/tool/cross-build/ffmpeg/bootstrap-build_ffmpeg4.3_cross.sh b/source/tool/cross-build/ffmpeg/bootstrap-build_ffmpeg4.3_cross.sh new file mode 100644 index 000000000..33629d667 --- /dev/null +++ b/source/tool/cross-build/ffmpeg/bootstrap-build_ffmpeg4.3_cross.sh @@ -0,0 +1,57 @@ +#!/bin/sh +TOOLCHAIN_ROOT="/opt/llvm-mingw" +INSTALL_ROOT="/usr/local/i586-mingw-msvc" +TOOLCHAIN_PREFIX="i686-w64-mingw32" +export PATH="${TOOLCHAIN_ROOT}/bin:${INSTALL_ROOT}/lame/bin:$PATH" +export CC=clang +export CXX=clang++ +export LD=${TOOLCHAIN_ROOT}/bin/${TOOLCHAIN_PREFIX}-ld +export PKG_CONFIG_PATH=${INSTALL_ROOT}/pkgconfig/lib/pkgconfig + +sudo ln -s -f /usr/bin/pkg-config ${TOOLCHAIN_ROOT}/bin/${TOOLCHAIN_PREFIX}-pkg-config + +./configure \ + --cross-prefix=${TOOLCHAIN_PREFIX}- \ + --prefix=${INSTALL_ROOT}/ffmpeg-4.3 \ + --pkgconfigdir=${INSTALL_ROOT}/pkgconfig/lib/pkgconfig \ + --disable-static --enable-shared \ + --target-os=mingw32 \ + --arch=i686 \ + --host-cc=${TOOLCHAIN_PREFIX}-gcc \ + --disable-mediafoundation \ + --disable-mediacodec \ + --disable-inline-asm \ + --disable-amf \ + --enable-gpl \ + --enable-libx264 \ + --enable-libmp3lame \ + --enable-dxva2 \ + --enable-libvorbis \ + --enable-cross-compile \ + --disable-doc \ + --extra-cflags=" \ + -I${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}/include \ + -I${INSTALL_ROOT}/libx264/include \ + -I${INSTALL_ROOT}/lame/include \ + -I${INSTALL_ROOT}/vorbis/include \ + -I${INSTALL_ROOT}/ogg/include\ + " \ + --extra-cxxflags=" \ + -I${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}/include \ + -I${INSTALL_ROOT}/libx264/include \ + -I${INSTALL_ROOT}/lame/include \ + -I${INSTALL_ROOT}/vorbis/include \ + -I${INSTALL_ROOT}/ogg/include \ + " \ + --extra-ldflags=" \ + -L${TOOLCHAIN_ROOT}/lib \ + -L${TOOLCHAIN_ROOT}/${TOOLCHAIN_PREFIX}/lib \ + -L/usr/${TOOLCHAIN_PREFIX}/lib \ + -L${INSTALL_ROOT}/libx264/lib \ + -L${INSTALL_ROOT}/lame/lib \ + -L${INSTALL_ROOT}/vorbis/lin \ + -L${INSTALL_ROOT}/ogg/lib \ + "\ + +# + diff --git a/source/tool/cross-build/lame/000_libmp3lame_lame.c.diff b/source/tool/cross-build/lame/000_libmp3lame_lame.c.diff new file mode 100644 index 000000000..084d97157 --- /dev/null +++ b/source/tool/cross-build/lame/000_libmp3lame_lame.c.diff @@ -0,0 +1,17 @@ +--- lame.c.orig 2019-09-24 18:52:27.674563658 +0000 ++++ lame.c 2019-09-24 18:52:39.572621949 +0000 +@@ -2376,10 +2376,10 @@ + } + + /* initialize mp3 encoder */ +-#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED +-static +-#else +-#endif ++//#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED ++//static ++//#else ++//#endif + int + lame_init_old(lame_global_flags * gfp) + { diff --git a/source/tool/cross-build/lame/bootstrap_lame.sh b/source/tool/cross-build/lame/bootstrap_lame.sh new file mode 100644 index 000000000..9a9e000fb --- /dev/null +++ b/source/tool/cross-build/lame/bootstrap_lame.sh @@ -0,0 +1,13 @@ +#!/bin/sh +PATH="/opt/llvm-mingw/bin:$PATH" +export CC=i686-w64-mingw32-clang +export CXX=i686-w64-mingw32-clang++ +export CFLAGS="--stdlib=libc++ -msse2" +export LDFLAGS="-L/opt/llvm-mingw/lib -lc++" + +./configure \ + --host=i686-w64-mingw32 \ + --enable-pic \ + --enable-shared \ + --enable-static \ + --prefix=/usr/local/i586-mingw-msvc/lame diff --git a/source/tool/cross-build/llvm-mingw/README.md b/source/tool/cross-build/llvm-mingw/README.md new file mode 100644 index 000000000..a69996c93 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/README.md @@ -0,0 +1,38 @@ +**Sorry still not writing in English, this written only Japanese.** + +

Scripts for LLVM cross toolchain for Windows (ix86, x86_64, armv7 aarch64)

+
+

Oct 21, 2020
+K.Ohta

+
+ + +## About + + このディレクトリは、MinGW-w64用のクロスツールチェインをビルドするスクリプトです。 + + LLVM CLANGベースのGNU/Linux上で動くものが、ビルド可能です(BSD他は未確認) + +## How to build + + 依存するファイルは以下のとおりです(ToDo): + + + これらをインストールした後、 + + $ cp -ar . foo/ + + $ cd foo + + $ sudo ./bootstrap.sh + + **現在、sudo(又はfakerootなど)が必要になります**。 + + で、 /opt/llvm-mingw-11/ 以下に自動的にインストールされます。 + + +## TIPS + + buildvars.dat である程度の設定が可能です。 + + 詳しくは、bootstrap.shをお読みください。 \ No newline at end of file diff --git a/source/tool/cross-build/llvm-mingw/bootstrap.sh b/source/tool/cross-build/llvm-mingw/bootstrap.sh new file mode 100755 index 000000000..43f18f731 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/bootstrap.sh @@ -0,0 +1,165 @@ +#!/usr/bin/bash + +TOOLCHAIN_PREFIX=/opt/llvm-mingw-11 +TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" +TOOLCHAIN_TARGET_OSES="mingw32 mings32uwp" +WORKDIR=$PWD/build +LLVM_VERSION=llvmorg-11.0.0 +FORCE_THREADS=8 + +typeset -i CLEANING +CLEANING=0 + +if [ -e ./buildvars.dat ] ; then + . ./buildvars.dat +fi + +export TOOLCHAIN_ARCHS +export TOOLCHAIN_PREFIX +export TOOLCHAIN_TARGET_OSES +#export WORKDIR + +typeset -i ncount +ncount=1 + +THREAD_PARAM="" +if [ -n "${FORCE_THREADS}" ] ; then + THREAD_PARAM="--build-threads ${FORCE_THREADS}" +fi + +mkdir -p "${WORKDIR}/" +mkdir -p "${WORKDIR}/scripts" +mkdir -p "${WORKDIR}/scripts/wrappers" +mkdir -p "${WORKDIR}/build" + +cp -ar scripts/ "${WORKDIR}/" +cp -ar ${WORKDIR}/scripts/wrappers/* ${WORKDIR}/build/scripts/wrappers +cp -ar ${WORKDIR}/scripts/test/* ${WORKDIR}/build/test/ +pushd . + +cd "${WORKDIR}/build" +echo "BUILD LLVM Toolchain for Win32/64 to ${WORKDIR}/build/" + +${WORKDIR}/scripts/build-llvm.sh \ + --llvm-version ${LLVM_VERSION} \ + ${THREAD_PARAM} \ + ${TOOLCHAIN_PREFIX} + +#if [ $? -ne 0 ] ; then +# echo "PHASE ${ncount}: script: ${_sc} failed. Abort building" +# exit $? +#fi + +#${WORKDIR}/scripts/strip-llvm.sh \ +# ${TOOLCHAIN_PREFIX} + +#if [ $? -ne 0 ] ; then +# echo "PHASE ${ncount}: script: ${_sc} failed. Abort building" +# exit $? +#fi + +ncount=$((${ncount}+1)) + +${WORKDIR}/scripts/install-wrappers.sh \ + ${WORKDIR} \ + ${TOOLCHAIN_PREFIX} \ + +if [ $? -ne 0 ] ; then + echo "PHASE ${ncount}: script: ${_sc} failed. Abort building" + exit $? +fi +ncount=$((${ncount}+1)) + +export PATH="${TOOLCHAIN_PREFIX}/bin:${PATH}" + +mkdir -p "${WORKDIR}/build/build" +cd "${WORKDIR}/build/build" +${WORKDIR}/scripts/build-mingw-w64.sh \ + ${THREAD_PARAM} \ + ${TOOLCHAIN_PREFIX} + +cd "${WORKDIR}/build" +${WORKDIR}/scripts/build-compiler-rt.sh \ + ${TOOLCHAIN_PREFIX} + + +cd "${WORKDIR}/build/build" +${WORKDIR}/scripts/build-mingw-w64-libraries.sh \ + ${THREAD_PARAM} \ + ${TOOLCHAIN_PREFIX} + + + +cd "${WORKDIR}/build" +${WORKDIR}/scripts/build-libcxx.sh \ + ${THREAD_PARAM} \ + ${TOOLCHAIN_PREFIX} + + +#cd "${WORKDIR}/build/test" +#for arch in $TOOLCHAIN_ARCHS; do +# mkdir -p $arch +# for test in hello hello-tls crt-test setjmp; do +# $arch-w64-mingw32-clang $test.c -o $arch/$test.exe || exit 1; +# done; +# for test in autoimport-lib; do +# $arch-w64-mingw32-clang $test.c -shared -o $arch/$test.dll -Wl,--out-implib,$arch/lib$test.dll.a || exit 1; \ +# done; +# for test in autoimport-main; do +# $arch-w64-mingw32-clang $test.c -o $arch/$test.exe -L$arch -l${test%-main}-lib || exit 1; +# done; +#done + +# Build sanitizers. Ubsan includes from the C++ headers, so +# we need to build this after libcxx. +# Sanitizers on windows only support x86. +cd "${WORKDIR}/build" +${WORKDIR}/scripts/build-compiler-rt.sh \ + ${TOOLCHAIN_PREFIX} \ + --build-sanitizers + + +#cd "${WORKDIR}/build/test" +#for arch in $TOOLCHAIN_ARCHS; do +# case $arch in +# i686|x86_64) +# ;; +# *) +# continue +# ;; +# esac +# for test in stacksmash; do +# $arch-w64-mingw32-clang $test.c -o $arch/$test-asan.exe -fsanitize=address -g -gcodeview -Wl,-pdb,$arch/$test-asan.pdb || exit 1; +# done +# for test in ubsan; do +# $arch-w64-mingw32-clang $test.c -o $arch/$test.exe -fsanitize=undefined || exit 1; +# done +#done + +# Build libssp + +cd "${WORKDIR}/build" +cp "${WORKDIR}/scripts/libssp-Makefile" "${WORKDIR}/build" +_sc="" +${WORKDIR}/scripts/build-libssp.sh \ + ${THREAD_PARAM} \ + ${TOOLCHAIN_PREFIX} \ + #--build-sanitizers + + +#cd "${WORKDIR}/build/test" +#for arch in $TOOLCHAIN_ARCHS; do +# mkdir -p $arch +# for test in stacksmash; do +# $arch-w64-mingw32-clang $test.c -o $arch/$test.exe -fstack-protector-strong || exit 1 +# done +#done +#cd "${WORKDIR}/build/test" +#for arch in $TOOLCHAIN_ARCHS; do +# cp $TOOLCHAIN_PREFIX/$arch-w64-mingw32/bin/*.dll $arch || exit 1 +#done + +# Clear build data +if [ ${CLEANING} -ne 0 ] ; then + rm -rf ./build/* +fi diff --git a/source/tool/cross-build/llvm-mingw/docker/.dockerignore b/source/tool/cross-build/llvm-mingw/docker/.dockerignore new file mode 100644 index 000000000..783d2c2a7 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/.dockerignore @@ -0,0 +1,16 @@ +.git +llvm +llvm-project +mingw-w64 +compiler-rt +libunwind +libcxxabi +libcxx +libssp +**/*.exe +**/*.dll +**/*.lib +**/*.pdb +**/*.a +*.tar.xz +*.zip diff --git a/source/tool/cross-build/llvm-mingw/docker/.gitignore b/source/tool/cross-build/llvm-mingw/docker/.gitignore new file mode 100644 index 000000000..0ef0aca1d --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/.gitignore @@ -0,0 +1,7 @@ +/llvm +/mingw-w64 +/compiler-rt +/libunwind +/libcxxabi +/libcxx +/libssp diff --git a/source/tool/cross-build/llvm-mingw/docker/Dockerfile b/source/tool/cross-build/llvm-mingw/docker/Dockerfile new file mode 100644 index 000000000..98872b6bd --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/Dockerfile @@ -0,0 +1,49 @@ +FROM ubuntu:20.04 +#FROM ubuntu:16.04 + +ENV FORCE_THREADS=4 + +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update -qq && apt-get install -qqy --no-install-recommends \ + git wget bzip2 file unzip libtool pkg-config cmake build-essential \ + automake yasm gettext autopoint vim python ninja-build subversion \ + cmake cmake-curses-gui mingw-w64-tools binutils-mingw-w64 \ + pkg-config sudo openssh-client openssh-server p7zip-full pixz \ + lftp ncftp nano jed locales mc less lv \ + wget yasm nasm \ + libz-mingw-w64 libz-mingw-w64-dev win-iconv-mingw-w64-dev \ + ccache aptitude vim emacs \ + ca-certificates && \ + apt-get clean -y && \ + rm -rf /var/lib/apt/lists/* + + +RUN git config --global user.name "LLVM MinGW" && \ + git config --global user.email root@localhost + +WORKDIR /build + +ENV TOOLCHAIN_PREFIX=/opt/llvm-mingw + +ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" + +# Build everything that uses the llvm monorepo. We need to build the mingw runtime before the compiler-rt/libunwind/libcxxabi/libcxx runtimes. +COPY build-llvm.sh strip-llvm.sh install-wrappers.sh build-mingw-w64.sh build-compiler-rt.sh build-mingw-w64-libraries.sh build-libcxx.sh ./ +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ + +RUN ./build-llvm.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX && \ + ./strip-llvm.sh $TOOLCHAIN_PREFIX && \ + ./install-wrappers.sh $TOOLCHAIN_PREFIX && \ + ./build-mingw-w64.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX && \ + ./build-compiler-rt.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX && \ + ./build-mingw-w64-libraries.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX && \ + ./build-libcxx.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX && \ + ./build-compiler-rt.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX --build-sanitizers && \ + rm -rf /build/* + +# Build libssp +COPY build-libssp.sh libssp-Makefile ./ +RUN ./build-libssp.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX && \ + rm -rf /build/* + +ENV PATH=$TOOLCHAIN_PREFIX/bin:$PATH diff --git a/source/tool/cross-build/llvm-mingw/docker/Dockerfile.cross b/source/tool/cross-build/llvm-mingw/docker/Dockerfile.cross new file mode 100644 index 000000000..2e3f56287 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/Dockerfile.cross @@ -0,0 +1,47 @@ +# Cross compile an llvm-mingw toolchain for windows. +# +# This needs to be built with --build-arg BASE=, where image is the name +# of a docker image that contains a working llvm-mingw cross compiler +# from a similar enough version. +# +# This builds LLVM and all other build tools that need to run on the target +# platform, but just copies over the runtime libraries from the existing +# toolchain in the base docker image. + +ARG BASE=mstorsjo/llvm-mingw:dev +FROM $BASE + +RUN apt-get update -qq && \ + apt-get install -qqy zip && \ + apt-get clean -y && \ + rm -rf /var/lib/apt/lists/* + +ARG CROSS_ARCH=x86_64 +ENV CROSS_TOOLCHAIN_PREFIX=/opt/llvm-mingw-$CROSS_ARCH +ENV FORCE_THREADS=4 +ENV EXEEXT=.exe +ENV HOST=$CROSS_ARCH-w64-mingw32 + +ARG FULL_LLVM + +COPY build-llvm.sh . +RUN ./build-llvm.sh $CROSS_TOOLCHAIN_PREFIX +COPY strip-llvm.sh . +RUN ./strip-llvm.sh $CROSS_TOOLCHAIN_PREFIX + +ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" + +COPY build-mingw-w64.sh ./ +RUN ./build-mingw-w64.sh $CROSS_TOOLCHAIN_PREFIX --skip-include-triplet-prefix --build-threads $FORCE_THREADS + +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ +COPY install-wrappers.sh . +RUN ./install-wrappers.sh $CROSS_TOOLCHAIN_PREFIX + +COPY prepare-cross-toolchain.sh . +RUN ./prepare-cross-toolchain.sh $TOOLCHAIN_PREFIX $CROSS_TOOLCHAIN_PREFIX $CROSS_ARCH + +ARG TAG +RUN ln -s $CROSS_TOOLCHAIN_PREFIX llvm-mingw && \ + zip -9r /llvm-mingw-$TAG$CROSS_ARCH.zip llvm-mingw && \ + ls -lh /llvm-mingw-$TAG$CROSS_ARCH.zip diff --git a/source/tool/cross-build/llvm-mingw/docker/Dockerfile.dev b/source/tool/cross-build/llvm-mingw/docker/Dockerfile.dev new file mode 100644 index 000000000..71ade53df --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/Dockerfile.dev @@ -0,0 +1,128 @@ +FROM ubuntu:18.10 + +ENV FORCE_THREADS=4 + +RUN apt-get update -qq && apt-get install -qqy --no-install-recommends \ + git wget bzip2 file unzip libtool pkg-config cmake build-essential \ + automake yasm gettext autopoint vim python ninja-build subversion \ + cmake cmake-curses-gui mingw-w64-tools binutils-mingw-w64 \ + pkg-config sudo openssh-client openssh-server p7zip-full pixz \ + nano jed locales mc wget yasm nasm \ + ca-certificates && \ + apt-get clean -y && \ + rm -rf /var/lib/apt/lists/* + + +RUN git config --global user.name "LLVM MinGW" && \ + git config --global user.email root@localhost + +WORKDIR /build + +ENV TOOLCHAIN_PREFIX=/opt/llvm-mingw + +ARG FULL_LLVM + +# Build LLVM +COPY build-llvm.sh ./ +RUN ./build-llvm.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX + +# Strip the LLVM install output immediately. (This doesn't reduce the +# total docker image size as long as it is in a separate RUN layer though, +# but reduces build times if tweaking the contents of strip-llvm.sh.) +# Most of the size of the docker image comes from the build directory that +# we keep in any case. +COPY strip-llvm.sh ./ +RUN ./strip-llvm.sh $TOOLCHAIN_PREFIX + +ARG TOOLCHAIN_ARCHS="i686 x86_64 armv7 aarch64" + +# Install the usual $TUPLE-clang binaries +COPY wrappers/*.sh wrappers/*.c wrappers/*.h ./wrappers/ +COPY install-wrappers.sh ./ +RUN ./install-wrappers.sh $TOOLCHAIN_PREFIX + +# Build MinGW-w64 +COPY build-mingw-w64.sh ./ +RUN ./build-mingw-w64.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX + +# Build compiler-rt +COPY build-compiler-rt.sh ./ +RUN ./build-compiler-rt.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX + +# Build mingw-w64's extra libraries +COPY build-mingw-w64-libraries.sh ./ +RUN ./build-mingw-w64-libraries.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX + +# Build C test applications +ENV PATH=$TOOLCHAIN_PREFIX/bin:$PATH + +COPY test/*.c test/*.h ./test/ +RUN cd test && \ + for arch in $TOOLCHAIN_ARCHS; do \ + mkdir -p $arch && \ + for test in hello hello-tls crt-test setjmp; do \ + $arch-w64-mingw32-clang $test.c -o $arch/$test.exe || exit 1; \ + done; \ + for test in autoimport-lib; do \ + $arch-w64-mingw32-clang $test.c -shared -o $arch/$test.dll -Wl,--out-implib,$arch/lib$test.dll.a || exit 1; \ + done; \ + for test in autoimport-main; do \ + $arch-w64-mingw32-clang $test.c -o $arch/$test.exe -L$arch -l${test%-main}-lib || exit 1; \ + done; \ + done + +# Build libunwind/libcxxabi/libcxx +COPY build-libcxx.sh ./ +RUN ./build-libcxx.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX + +# Build C++ test applications +COPY test/*.cpp ./test/ +RUN cd test && \ + for arch in $TOOLCHAIN_ARCHS; do \ + mkdir -p $arch && \ + for test in hello-cpp hello-exception tlstest-main exception-locale exception-reduced; do \ + $arch-w64-mingw32-clang++ $test.cpp -o $arch/$test.exe || exit 1; \ + done; \ + for test in tlstest-lib; do \ + $arch-w64-mingw32-clang++ $test.cpp -shared -o $arch/$test.dll || exit 1; \ + done; \ + done + +# Build sanitizers. Ubsan includes from the C++ headers, so +# we need to build this after libcxx. +RUN ./build-compiler-rt.sh $TOOLCHAIN_PREFIX --build-sanitizers + +# Sanitizers on windows only support x86. +RUN cd test && \ + for arch in $TOOLCHAIN_ARCHS; do \ + case $arch in \ + i686|x86_64) \ + ;; \ + *) \ + continue \ + ;; \ + esac && \ + for test in stacksmash; do \ + $arch-w64-mingw32-clang $test.c -o $arch/$test-asan.exe -fsanitize=address -g -gcodeview -Wl,-pdb,$arch/$test-asan.pdb || exit 1; \ + done; \ + for test in ubsan; do \ + $arch-w64-mingw32-clang $test.c -o $arch/$test.exe -fsanitize=undefined || exit 1; \ + done; \ + done + +# Build libssp +COPY build-libssp.sh libssp-Makefile ./ +RUN ./build-libssp.sh --build-threads $FORCE_THREADS $TOOLCHAIN_PREFIX + +RUN cd test && \ + for arch in $TOOLCHAIN_ARCHS; do \ + mkdir -p $arch && \ + for test in stacksmash; do \ + $arch-w64-mingw32-clang $test.c -o $arch/$test.exe -fstack-protector-strong || exit 1; \ + done; \ + done + +RUN cd test && \ + for arch in $TOOLCHAIN_ARCHS; do \ + cp $TOOLCHAIN_PREFIX/$arch-w64-mingw32/bin/*.dll $arch || exit 1; \ + done diff --git a/source/tool/cross-build/llvm-mingw/docker/README.md b/source/tool/cross-build/llvm-mingw/docker/README.md new file mode 100644 index 000000000..0a6c89f67 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/README.md @@ -0,0 +1,181 @@ +LLVM MinGW +========== + +This is a recipe for reproducibly building a +[LLVM](https://llvm.org)/[Clang](https://clang.llvm.org/)/[LLD](https://lld.llvm.org/) +based mingw-w64 toolchain. + +Benefits of a LLVM based MinGW toolchain are: +- Support for targeting ARM/ARM64 (while GCC obviously does support + these architectures, it doesn't support Windows on ARM) +- A single toolchain targeting all four architectures (i686, x86_64, + armv7 and arm64) instead of separate compiler binaries for each + architecture +- Support for generating debug info in PDB format +- Support for Address Sanitizer and Undefined Behaviour Sanitizer + +Clang on its own can also be used as compiler in the normal GNU binutils +based environments though, so the main difference lies in replacing +binutils with LLVM based tools. + +Artanejp's additional comment +----------------------------- + +This is based on Ubuntu 19.10 "Eoan". + +And, some tools also installed. + +DockeHub's repository is below: + +https://cloud.docker.com/u/artanejp/repository/docker/artanejp/mingw-w64-llvm-ubuntu19.10 + +-- Oct 26, 2019 K.Ohta. + + +Installation +------------ + +Prebuilt docker linux images containing llvm-mingw are available from +[Docker Hub](https://hub.docker.com/r/mstorsjo/llvm-mingw/), and +prebuilt toolchains (both for use as cross compiler from linux, and +for use on windows) are available for download on GitHub. The toolchains +for windows come in 4 versions, one for each of the 4 supported +architectures, but each one of them can target all 4 architectures. + +Building from source +-------------------- + +The toolchain can be reproducibly built into a Docker image, or be +built and installed in the host environment. + +To build and install all components, just do: + + ./build-all.sh + +To reduce the size of the installation, removing some files that +aren't necessary after building, run: + + ./strip-llvm.sh + +To build a Docker image with the toolchain, run: + + docker build . + +Individual components of the toolchain can be (re)built by running +the standalone shellscripts listed within `build-all.sh`. However, if +the source already is checked out, no effort is made to check out a +different version (if the build scripts have been updated to prefer +a different version) - and likewise, if configure flags in the build-\*.sh +scripts have changed, you might need to wipe the build directory under +each project for the new configure options to be taken into use. + + +Building in MSYS2 +----------------- + +To build in MSYS2, install the following set of packages with `pacman -S`: + + git subversion mingw-w64-x86_64-gcc mingw-w64-x86_64-ninja mingw-w64-x86_64-cmake make mingw-w64-x86_64-python2 + +Do note that this installs python2, not python3. python3 on windows +seems to have a bug in running subprocesses the way it's done by a +script in libcxx, a bug that only seems to be +[fixed in python 3.8](https://github.com/python/cpython/commit/9e3c4526394856d6376eed4968d27d53e1d69b7d). + + +Status +------ + +The toolchain currently does support both C and C++, including support +for exception handling. + +It is in practice new and hasn't been tested with quite as many projects +as the regular GCC/binutils based toolchains yet. You might run into issues +building non-trivial projects. + + +Known issues +------------ + +LLD, the LLVM linker, is what causes most of the major differences to the +normal GCC/binutils based MinGW. + +- The windres replacement, llvm-rc, isn't very mature and doesn't support + everything that GNU windres does. +- The toolchain defaults to using the Universal CRT (which is only available + out of the box since Windows 10, but can be installed on Vista or newer) + and defaults to targeting Vista. These defaults can be changed in + `build-mingw-w64.sh` though. +- The toolchain uses Windows native TLS support, which doesn't work properly + until Windows Vista. This has no effect on code not using thread local + variables. +- The runtime libraries libunwind, libcxxabi and libcxx also assume that the + target is Vista or newer. +- Address Sanitizer doesn't produce working backtraces for i686. Address + Sanitizer requires using a PDB file for symbolizing the error location and + backtraces. +- The sanitizers are only supported on x86. +- LLD doesn't support linker script (in the COFF part of LLD). Linker script can be used for + reprogramming how the linker lays out the output, but is in most cases + in MinGW setups only used for passing lists of object files to link. + Passing lists of files can also be done with response files, which LLD does support. + (This was fixed in qmake in [v5.12.0](https://code.qt.io/cgit/qt/qtbase.git/commit/?id=d92c25b1b4ac0423a824715a08b2db2def4b6e25), to use response + files instead of linker script.) +- Libtool based projects fail to link with llvm-mingw if the project contains + C++. (This often manifests with undefined symbols like `___chkstk_ms`, + `__alloca` or `___divdi3`.) + For such targets, libtool tries to detect which libraries to link + by invoking the compiler with `$CC -v` and picking up the libraries that + are linked by default, and then invoking the linker driver with `-nostdlib` + and specifying the default libraries manually. In doing so, libtool fails + to detect when clang is using compiler_rt instead of libgcc, because + clang refers to it as an absolute path to a static library, instead of + specifying a library path with `-L` and linking the library with `-l`. + Clang is [reluctant to changing this behaviour](https://reviews.llvm.org/D51440). + A [bug](https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27866) has been filed + with libtool, but no fix has been committed, and as libtool files are + shipped with the projects that use them (bundled within the configure + script), one has to update the configure script in each project to avoid + the issue. This can either be done by installing libtool, patching it + and running `autoreconf -fi` in the project, or by manually applying the + fix on the shipped `configure` script. A patched version of libtool is + [shipped in MSYS2](https://github.com/msys2/MINGW-packages/blob/95b093e888/mingw-w64-libtool/0011-Pick-up-clang_rt-static-archives-compiler-internal-l.patch) + at least. +- Libtool, when running on Windows, prefers using linker script over + response files, to pass long lists of object files to the linker driver, + but LLD doesn't support linker script (as described above). This issue + produces errors like `lld-link: error: .libs\libfoobar.la.lnkscript: unknown file type`. + To fix this, the bundled libtool scripts has to be fixed like explained + above, but this fix requires changes both to `configure` and a separate + file named `ltmain.{in,sh}`. A fix for this is also + [shipped in MSYS2](https://github.com/msys2/MINGW-packages/blob/95b093e888/mingw-w64-libtool/0012-Prefer-response-files-over-linker-scripts-for-mingw-.patch). + +Additionally, one may run into other minor differences between GCC and clang. + +PDB support +----------- + +LLVM does [support](http://blog.llvm.org/2017/08/llvm-on-windows-now-supports-pdb-debug.html) +generating debug info in the PDB format. Since GNU binutils based mingw +environments don't support this, there's no predecent for what command +line parameters to use for this, and llvm-mingw produces debug info in +DWARF format by default. + +To produce debug info in PDB format, you currently need to do the following +changes: + +- Add `-gcodeview` to the compilation commands (e.g. in + `wrappers/clang-target-wrapper.sh`), together with using `-g` as usual to + enable debug info in general. +- Add `-Wl,-pdb=` to linking commands. This creates a PDB file at the same + location as the output EXE/DLL, but with a PDB extension. (By passing + `-Wl,-pdb=module.pdb` or `-Wl,-pdb,module.pdb` one can explicitly specify + the name of the output PDB file.) + +Even though LLVM supports this, there are a few caveats with using it when +building in MinGW mode: + +- Microsoft debuggers might have assumptions about the C++ ABI used, which + doesn't hold up with the Itanium ABI used in MinGW. +- This is unimplemented for the armv7 target, and while implemented for aarch64, + it doesn't seem to work properly there yet. diff --git a/source/tool/cross-build/llvm-mingw/docker/appendix-docs/000_README_FIRST.en.txt b/source/tool/cross-build/llvm-mingw/docker/appendix-docs/000_README_FIRST.en.txt new file mode 100644 index 000000000..92c9518bc --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/appendix-docs/000_README_FIRST.en.txt @@ -0,0 +1,16 @@ +This docker image is for building Windows variants of Common Source +Code Project for Qt (*). +This based on Ubuntu 18.10 "Cosmic Cuttlefish",AMD64. + +Needed toolchains are exists below /opt/llvm-mingw/ (*2). +Needed libraries are placed at /usr/local/i586-mingw-msvc/ , +but, you need to install M$ Direct X SDK to re-build Qt. +Also, Angle Project (OpenGL ES) is imported from Google's chromium. + +Have Fun! +Sep 26, 2019 K.Ohta + +(*1) https://github.com/Artanejp/common_source_project-fm7 +(*2) https://github.com/Artanejp/llvm-mingw + https://github.com/mstorsjo/llvm-mingw + \ No newline at end of file diff --git a/source/tool/cross-build/llvm-mingw/docker/appendix-docs/000_README_FIRST.ja.txt b/source/tool/cross-build/llvm-mingw/docker/appendix-docs/000_README_FIRST.ja.txt new file mode 100644 index 000000000..972785538 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/appendix-docs/000_README_FIRST.ja.txt @@ -0,0 +1,20 @@ +*** UTF-8 *** +このDockerイメージは、Common Source Code Project for Qt (*1) +のWindowsビルドを作成するための物です。 +Ubuntu 18.10 "Cosmic Cuttlefish"のAMD64ベースです。 + +必要なツールチェインは/opt/llvm-mingw/ にあります(*2)。 +ライブラリなどは、/usr/local/i586-mingw-msvc/ に揃えてありま +すが、Qtの再ビルドに関しては、DirectX SDKを別途インストールする +必要があります。 +又、Angleproject(OpenGL ES)に関しては、Google chromiumから +持ち込んでいます。 + +お楽しみあれ。 + +Sep 26, 2019 K.Ohta + +(*1) https://github.com/Artanejp/common_source_project-fm7 +(*2) https://github.com/Artanejp/llvm-mingw + https://github.com/mstorsjo/llvm-mingw + \ No newline at end of file diff --git a/source/tool/cross-build/llvm-mingw/docker/scripts/docker_mingw-w64-llvm.sh b/source/tool/cross-build/llvm-mingw/docker/scripts/docker_mingw-w64-llvm.sh new file mode 100755 index 000000000..e27f24ac0 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/docker/scripts/docker_mingw-w64-llvm.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +#CIDFILE=`mktemp` +CONTAINER_NAME=`uuidgen` +CONTAINER_TAG='artanejp/mingw-w64-llvm10-ubuntu20.04:using' +CONTAINER_CMD='/bin/bash -i' +#CONTAINER_HOME="/Please_Modify_This/home/" +BEGIN_DATE=`date` + +echo BEGIN ${CONTAINER_NAME} for ${CONTAINER_TAG} at ${BEGIN_DATE} +docker run --name=${CONTAINER_NAME} \ + -v ${CONTAINER_HOME}:/home/ \ + -v /tmp/.X11-unix/:/tmp/.X11-unix/ \ + -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ + --device /dev/snd \ + -e DISPLAY=unix$DISPLAY \ + -ti \ + ${CONTAINER_TAG} \ + ${CONTAINER_CMD} \ + $@ + +END_DATE=`date` +echo COMMIT ${CONTAINER_NAME} for ${CONTAINER_TAG} at ${END_DATE} +echo "Please input committing message:" +read COMMIT_MESSAGE +docker commit -m "${COMMIT_MESSAGE}" ${CONTAINER_NAME} ${CONTAINER_TAG} +echo END ${CONTAINER_NAME} for ${CONTAINER_TAG} diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-all.sh b/source/tool/cross-build/llvm-mingw/scripts/build-all.sh new file mode 100755 index 000000000..f4b4a5f41 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-all.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +set -e + +if [ $# -lt 1 ]; then + echo $0 dest + exit 1 +fi + +FORCE_THREADS=OFF +__NARG="" +while [ $# -gt 0 ]; do + if [ "$1" = "--build-threads" ]; then + ${CORES:="$2"} + __NARG="--build-threads $2" + shift + else + PREFIX="$1" + break + fi + shift +done + +./build-llvm.sh ${__NARG} $PREFIX +./install-wrappers.sh $PREFIX +./build-mingw-w64.sh ${__NARG} $PREFIX +./build-compiler-rt.sh ${__NARG} $PREFIX +./build-mingw-w64-libraries.sh ${__NARG} $PREFIX +./build-libcxx.sh ${__NARG} $PREFIX +./build-compiler-rt.sh ${__NARG} $PREFIX --build-sanitizers +./build-libssp.sh ${__NARG} $PREFIX diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-compiler-rt.sh b/source/tool/cross-build/llvm-mingw/scripts/build-compiler-rt.sh new file mode 100755 index 000000000..95548aac9 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-compiler-rt.sh @@ -0,0 +1,113 @@ +#!/bin/sh + +set -e + +SRC_DIR=../lib/builtins +BUILD_SUFFIX= + +while [ $# -gt 0 ]; do + if [ "$1" = "--build-sanitizers" ]; then + SRC_DIR=.. + BUILD_SUFFIX=-sanitizers + SANITIZERS=1 + elif [ "$1" = "--build-threads" ]; then + : ${CORES:=$2} + shift + else + PREFIX="$1" + fi + shift +done +if [ -z "$PREFIX" ]; then + echo $0 [--build-sanitizers] dest + exit 1 +fi + + mkdir -p "$PREFIX" +PREFIX="$(cd $PREFIX && pwd)" +export PATH=$PREFIX/bin:$PATH + +: ${CORES:=$(nproc 2>/dev/null)} +: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)} +: ${CORES:=4} +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} + +CLANG_VERSION=$(basename $(dirname $(dirname $(dirname $($PREFIX/bin/clang --print-libgcc-file-name -rtlib=compiler-rt))))) + +if [ ! -d llvm-project/compiler-rt ] || [ -n "$SYNC" ]; then + CHECKOUT_ONLY=1 ./build-llvm.sh +fi + +# Add a symlink for i386 -> i686; we normally name the toolchain +# i686-w64-mingw32, but due to the compiler-rt cmake peculiarities, we +# need to refer to it as i386 at this stage. +if [ ! -e $PREFIX/i386-w64-mingw32 ]; then + ln -sfn i686-w64-mingw32 $PREFIX/i386-w64-mingw32 || true +fi + +cd llvm-project/compiler-rt + +for arch in $ARCHS; do + buildarchname=$arch + libarchname=$arch + if [ -n "$SANITIZERS" ]; then + case $arch in + i686|x86_64) + # Sanitizers on windows only support x86. + ;; + *) + continue + ;; + esac + fi + case $arch in + armv7) + libarchname=arm + ;; + i686) + buildarchname=i386 + libarchname=i386 + ;; + esac + + case $(uname) in + MINGW*) + CMAKE_GENERATOR="MSYS Makefiles" + ;; + *) + ;; + esac + + mkdir -p build-$arch$BUILD_SUFFIX + cd build-$arch$BUILD_SUFFIX + cmake \ + ${CMAKE_GENERATOR+-G} "$CMAKE_GENERATOR" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$PREFIX/$arch-w64-mingw32 \ + -DCMAKE_C_COMPILER=$arch-w64-mingw32-clang \ + -DCMAKE_CXX_COMPILER=$arch-w64-mingw32-clang++ \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_AR=$PREFIX/bin/llvm-ar \ + -DCMAKE_RANLIB=$PREFIX/bin/llvm-ranlib \ + -DCMAKE_C_COMPILER_WORKS=1 \ + -DCMAKE_CXX_COMPILER_WORKS=1 \ + -DCMAKE_C_COMPILER_TARGET=$buildarchname-windows-gnu \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=TRUE \ + -DCOMPILER_RT_USE_BUILTINS_LIBRARY=TRUE \ + $SRC_DIR + make -j$CORES + mkdir -p $PREFIX/lib/clang/$CLANG_VERSION/lib/windows + mkdir -p $PREFIX/$arch-w64-mingw32/bin + for i in lib/windows/libclang_rt.*-$buildarchname*.a; do + cp $i $PREFIX/lib/clang/$CLANG_VERSION/lib/windows/$(basename $i | sed s/$buildarchname/$libarchname/) + done + for i in lib/windows/libclang_rt.*-$buildarchname*.dll; do + if [ -f $i ]; then + cp $i $PREFIX/$arch-w64-mingw32/bin + fi + done + if [ -n "$SANITIZERS" ]; then + make install-compiler-rt-headers + fi + cd .. +done diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-cross-tools.sh b/source/tool/cross-build/llvm-mingw/scripts/build-cross-tools.sh new file mode 100755 index 000000000..1ae883dc5 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-cross-tools.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +set -e + +if [ $# -lt 3 ]; then + echo $0 native prefix arch + exit 1 +fi +NATIVE="$1" +PREFIX="$2" +CROSS_ARCH="$3" +__NARG="" + +if [ "$4" = "--build-threads" ]; then + : ${CORES:="$5"} + __NARG="--build-threads $5" +fi + +export PATH=$NATIVE/bin:$PATH +export EXEEXT=.exe +export HOST=$CROSS_ARCH-w64-mingw32 + +./build-llvm.sh $__NARG $PREFIX +./strip-llvm.sh $PREFIX +./build-mingw-w64.sh $PREFIX $__NARG --skip-include-triplet-prefix +./install-wrappers.sh $PREFIX +./prepare-cross-toolchain.sh $NATIVE $PREFIX $CROSS_ARCH diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-libcxx.sh b/source/tool/cross-build/llvm-mingw/scripts/build-libcxx.sh new file mode 100755 index 000000000..8d8fd847c --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-libcxx.sh @@ -0,0 +1,217 @@ +#!/bin/sh + +set -e + +BUILD_STATIC=1 +BUILD_SHARED=1 + +while [ $# -gt 0 ]; do + if [ "$1" = "--disable-shared" ]; then + BUILD_SHARED= + elif [ "$1" = "--enable-shared" ]; then + BUILD_SHARED=1 + elif [ "$1" = "--disable-static" ]; then + BUILD_STATIC= + elif [ "$1" = "--enable-static" ]; then + BUILD_STATIC=1 + elif [ "$1" = "--build-threads" ]; then + : ${CORES:=$2} + shift + else + PREFIX="$1" + fi + shift +done + +if [ -z "$PREFIX" ]; then + echo $0 [--disable-shared] [--disable-static] dest + exit 1 +fi + + mkdir -p "$PREFIX" +PREFIX="$(cd "$PREFIX" && pwd)" + +export PATH=$PREFIX/bin:$PATH + +: ${CORES:=$(nproc 2>/dev/null)} +: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)} +: ${CORES:=4} +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} + +if [ ! -d llvm-project/libunwind ] || [ -n "$SYNC" ]; then + CHECKOUT_ONLY=1 ./build-llvm.sh +fi + +cd llvm-project + +LIBCXX=$(pwd)/libcxx + +case $(uname) in +MINGW*) + CMAKE_GENERATOR="MSYS Makefiles" + ;; +*) + ;; +esac + +build_all() { + type="$1" + if [ "$type" = "shared" ]; then + SHARED=TRUE + STATIC=FALSE + else + SHARED=FALSE + STATIC=TRUE + fi + + cd libunwind + for arch in $ARCHS; do + mkdir -p build-$arch-$type + cd build-$arch-$type + # CXX_SUPPORTS_CXX11 is not strictly necessary here. But if building + # with a stripped llvm install, and the system happens to have an older + # llvm-config in /usr/bin, it can end up including older cmake files, + # and then CXX_SUPPORTS_CXX11 needs to be set. + cmake \ + ${CMAKE_GENERATOR+-G} "$CMAKE_GENERATOR" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$PREFIX/$arch-w64-mingw32 \ + -DCMAKE_C_COMPILER=$arch-w64-mingw32-clang \ + -DCMAKE_CXX_COMPILER=$arch-w64-mingw32-clang++ \ + -DCMAKE_CROSSCOMPILING=TRUE \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_C_COMPILER_WORKS=TRUE \ + -DCMAKE_CXX_COMPILER_WORKS=TRUE \ + -DLLVM_COMPILER_CHECKED=TRUE \ + -DCMAKE_AR=$PREFIX/bin/llvm-ar \ + -DCMAKE_RANLIB=$PREFIX/bin/llvm-ranlib \ + -DCXX_SUPPORTS_CXX11=TRUE \ + -DCXX_SUPPORTS_CXX_STD=TRUE \ + -DLIBUNWIND_USE_COMPILER_RT=TRUE \ + -DLIBUNWIND_ENABLE_THREADS=TRUE \ + -DLIBUNWIND_ENABLE_SHARED=$SHARED \ + -DLIBUNWIND_ENABLE_STATIC=$STATIC \ + -DLIBUNWIND_ENABLE_CROSS_UNWINDING=FALSE \ + -DCMAKE_CXX_FLAGS="-Wno-dll-attribute-on-redeclaration" \ + -DCMAKE_C_FLAGS="-Wno-dll-attribute-on-redeclaration" \ + -DCMAKE_SHARED_LINKER_FLAGS="-lpsapi" \ + .. + make -j$CORES + make install + if [ "$type" = "shared" ]; then + mkdir -p $PREFIX/$arch-w64-mingw32/bin + cp lib/libunwind.dll $PREFIX/$arch-w64-mingw32/bin + else + # Merge libpsapi.a into the static library libunwind.a, to + # avoid having to specify -lpsapi when linking to it. + llvm-ar qcsL \ + $PREFIX/$arch-w64-mingw32/lib/libunwind.a \ + $PREFIX/$arch-w64-mingw32/lib/libpsapi.a + fi + cd .. + done + cd .. + + cd libcxxabi + for arch in $ARCHS; do + mkdir -p build-$arch-$type + cd build-$arch-$type + if [ "$type" = "shared" ]; then + LIBCXXABI_VISIBILITY_FLAGS="-D_LIBCPP_BUILDING_LIBRARY= -U_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS" + else + LIBCXXABI_VISIBILITY_FLAGS="-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS" + fi + cmake \ + ${CMAKE_GENERATOR+-G} "$CMAKE_GENERATOR" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$PREFIX/$arch-w64-mingw32 \ + -DCMAKE_C_COMPILER=$arch-w64-mingw32-clang \ + -DCMAKE_CXX_COMPILER=$arch-w64-mingw32-clang++ \ + -DCMAKE_CROSSCOMPILING=TRUE \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_C_COMPILER_WORKS=TRUE \ + -DCMAKE_CXX_COMPILER_WORKS=TRUE \ + -DLLVM_COMPILER_CHECKED=TRUE \ + -DCMAKE_AR=$PREFIX/bin/llvm-ar \ + -DCMAKE_RANLIB=$PREFIX/bin/llvm-ranlib \ + -DLIBCXXABI_USE_COMPILER_RT=ON \ + -DLIBCXXABI_ENABLE_EXCEPTIONS=ON \ + -DLIBCXXABI_ENABLE_THREADS=ON \ + -DLIBCXXABI_TARGET_TRIPLE=$arch-w64-mingw32 \ + -DLIBCXXABI_ENABLE_SHARED=OFF \ + -DLIBCXXABI_LIBCXX_INCLUDES=../../libcxx/include \ + -DLIBCXXABI_LIBDIR_SUFFIX="" \ + -DLIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS=OFF \ + -DCXX_SUPPORTS_CXX_STD=TRUE \ + -DCMAKE_CXX_FLAGS="$LIBCXXABI_VISIBILITY_FLAGS -D_LIBCPP_HAS_THREAD_API_WIN32" \ + .. + make -j$CORES + cd .. + done + cd .. + + cd libcxx + for arch in $ARCHS; do + mkdir -p build-$arch-$type + cd build-$arch-$type + if [ "$type" = "shared" ]; then + LIBCXX_VISIBILITY_FLAGS="-D_LIBCXXABI_BUILDING_LIBRARY" + else + LIBCXX_VISIBILITY_FLAGS="-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS" + fi + cmake \ + ${CMAKE_GENERATOR+-G} "$CMAKE_GENERATOR" \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$PREFIX/$arch-w64-mingw32 \ + -DCMAKE_C_COMPILER=$arch-w64-mingw32-clang \ + -DCMAKE_CXX_COMPILER=$arch-w64-mingw32-clang++ \ + -DCMAKE_CROSSCOMPILING=TRUE \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_C_COMPILER_WORKS=TRUE \ + -DCMAKE_CXX_COMPILER_WORKS=TRUE \ + -DLLVM_COMPILER_CHECKED=TRUE \ + -DCMAKE_AR=$PREFIX/bin/llvm-ar \ + -DCMAKE_RANLIB=$PREFIX/bin/llvm-ranlib \ + -DLIBCXX_USE_COMPILER_RT=ON \ + -DLIBCXX_INSTALL_HEADERS=ON \ + -DLIBCXX_ENABLE_EXCEPTIONS=ON \ + -DLIBCXX_ENABLE_THREADS=ON \ + -DLIBCXX_HAS_WIN32_THREAD_API=ON \ + -DLIBCXX_ENABLE_MONOTONIC_CLOCK=ON \ + -DLIBCXX_ENABLE_SHARED=$SHARED \ + -DLIBCXX_ENABLE_STATIC=$STATIC \ + -DLIBCXX_SUPPORTS_STD_EQ_CXX11_FLAG=TRUE \ + -DLIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB=TRUE \ + -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \ + -DLIBCXX_ENABLE_FILESYSTEM=OFF \ + -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=TRUE \ + -DLIBCXX_CXX_ABI=libcxxabi \ + -DLIBCXX_CXX_ABI_INCLUDE_PATHS=../../libcxxabi/include \ + -DLIBCXX_CXX_ABI_LIBRARY_PATH=../../libcxxabi/build-$arch-$type/lib \ + -DLIBCXX_LIBDIR_SUFFIX="" \ + -DLIBCXX_INCLUDE_TESTS=FALSE \ + -DCMAKE_CXX_FLAGS="$LIBCXX_VISIBILITY_FLAGS" \ + -DCMAKE_SHARED_LINKER_FLAGS="-lunwind" \ + -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=FALSE \ + .. + make -j$CORES + make install + if [ "$type" = "shared" ]; then + llvm-ar qcsL \ + $PREFIX/$arch-w64-mingw32/lib/libc++.dll.a \ + $PREFIX/$arch-w64-mingw32/lib/libunwind.dll.a + cp lib/libc++.dll $PREFIX/$arch-w64-mingw32/bin + else + llvm-ar qcsL \ + $PREFIX/$arch-w64-mingw32/lib/libc++.a \ + $PREFIX/$arch-w64-mingw32/lib/libunwind.a + fi + cd .. + done + cd .. +} + +# Build shared first and static afterwards; the headers for static linking also +# work when linking against the DLL, but not vice versa. +[ -z "$BUILD_SHARED" ] || build_all shared +[ -z "$BUILD_STATIC" ] || build_all static diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-libssp.sh b/source/tool/cross-build/llvm-mingw/scripts/build-libssp.sh new file mode 100755 index 000000000..bdc17b73a --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-libssp.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +set -e + +if [ $# -lt 1 ]; then + echo $0 dest + exit 1 +fi +while [ $# -gt 0 ]; do + if [ "$1" = "--build-threads" ]; then + : ${CORES:=$2} + shift + else + PREFIX="$1" + break + fi + shift +done + mkdir -p "$PREFIX" +PREFIX="$(cd "$PREFIX" && pwd)" +export PATH=$PREFIX/bin:$PATH + +: ${CORES:=$(nproc 2>/dev/null)} +: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)} +: ${CORES:=4} +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} + +if [ ! -d libssp ]; then + svn checkout -q svn://gcc.gnu.org/svn/gcc/tags/gcc_7_3_0_release/libssp +fi + +cp libssp-Makefile libssp/Makefile + +cd libssp + +# gcc/libssp's configure script runs checks for flags that clang doesn't +# implement. We actually just need to set a few HAVE defines and compile +# the .c sources. +cp config.h.in config.h +for i in HAVE_FCNTL_H HAVE_INTTYPES_H HAVE_LIMITS_H HAVE_MALLOC_H \ + HAVE_MEMMOVE HAVE_MEMORY_H HAVE_MEMPCPY HAVE_STDINT_H HAVE_STDIO_H \ + HAVE_STDLIB_H HAVE_STRINGS_H HAVE_STRING_H HAVE_STRNCAT HAVE_STRNCPY \ + HAVE_SYS_STAT_H HAVE_SYS_TYPES_H HAVE_UNISTD_H HAVE_USABLE_VSNPRINTF \ + HAVE_HIDDEN_VISIBILITY; do + cat config.h | sed 's/^#undef '$i'$/#define '$i' 1/' > tmp + mv tmp config.h +done +cat ssp/ssp.h.in | sed 's/@ssp_have_usable_vsnprintf@/define/' > ssp/ssp.h + +for arch in $ARCHS; do + mkdir -p build-$arch + cd build-$arch + make -f ../Makefile -j$CORES CROSS=$arch-w64-mingw32- + mkdir -p $PREFIX/$arch-w64-mingw32/bin + cp libssp.a $PREFIX/$arch-w64-mingw32/lib + cp libssp_nonshared.a $PREFIX/$arch-w64-mingw32/lib + cp libssp.dll.a $PREFIX/$arch-w64-mingw32/lib + cp libssp-0.dll $PREFIX/$arch-w64-mingw32/bin + cd .. +done diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-llvm.sh b/source/tool/cross-build/llvm-mingw/scripts/build-llvm.sh new file mode 100755 index 000000000..c15ff89be --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-llvm.sh @@ -0,0 +1,166 @@ +#!/bin/sh + +set -e + +ASSERTS=OFF +BUILDDIR=build +FORCE_THREADS=OFF +OVERRIDE_THREADS=0 +LLVM_VERSION=llvmorg-11.0.0 + +while [ $# -gt 0 ]; do + if [ "$1" = "--disable-asserts" ]; then + ASSERTS=OFF + BUILDDIR=build + elif [ "$1" = "--enable-asserts" ]; then + ASSERTS=ON + BUILDDIR=build-asserts + elif [ "$1" = "--full-llvm" ]; then + FULL_LLVM=1 + elif [ "$1" = "--build-threads" ]; then + FORCE_THREADS=ON + OVERRIDE_THREADS="$2" + : ${CORES:="$2"} + shift + elif [ "$1" = "--llvm-version" ]; then + LLVM_VERSION="$2" + shift + else + PREFIX="$1" + fi + shift +done + + mkdir -p "$PREFIX" +PREFIX="$(cd "$PREFIX" && pwd)" + +if [ -z "$PREFIX" ]; then + echo $0 [--enable-asserts] [--full-llvm] dest + exit 1 +fi + +: ${CORES:=$(nproc 2>/dev/null)} +: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)} +: ${CORES:=4} + +if [ ! -d llvm-project ]; then + # When cloning master and checking out a pinned old hash, we can't use --depth=1. + git clone https://github.com/llvm/llvm-project.git + CHECKOUT=1 +fi + +if [ -n "$SYNC" ] || [ -n "$CHECKOUT" ]; then + cd llvm-project + [ -z "$SYNC" ] || git fetch + git checkout ${LLVM_VERSION} + cd .. +fi + +[ -z "$CHECKOUT_ONLY" ] || exit 0 + +#if [ -n "$(which ninja)" ]; then +# CMAKE_GENERATOR="Ninja" +# NINJA=1 +#else + case $(uname) in + MINGW*) + CMAKE_GENERATOR="MSYS Makefiles" + ;; + *) + ;; + esac +#fi + +if [ -n "$HOST" ]; then + find_native_tools() { + if [ -d llvm-project/llvm/build/bin ]; then + echo $(pwd)/llvm-project/llvm/build/bin + elif [ -d llvm-project/llvm/build-asserts/bin ]; then + echo $(pwd)/llvm-project/llvm/build-asserts/bin + elif [ -d llvm-project/llvm/build-noasserts/bin ]; then + echo $(pwd)/llvm-project/llvm/build-noasserts/bin + elif [ -n "$(which llvm-tblgen)" ]; then + echo $(dirname $(which llvm-tblgen)) + fi + } + + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_SYSTEM_NAME=Windows" + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_CROSSCOMPILING=TRUE" + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_C_COMPILER=$HOST-gcc" + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_CXX_COMPILER=$HOST-g++" + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_RC_COMPILER=$HOST-windres" + CMAKEFLAGS="$CMAKEFLAGS -DCROSS_TOOLCHAIN_FLAGS_NATIVE=" + + native=$(find_native_tools) + if [ -n "$native" ]; then + CMAKEFLAGS="$CMAKEFLAGS -DLLVM_TABLEGEN=$native/llvm-tblgen" + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_TABLEGEN=$native/clang-tblgen" + CMAKEFLAGS="$CMAKEFLAGS -DLLVM_CONFIG_PATH=$native/llvm-config" + fi + CROSS_ROOT=$(cd $(dirname $(which $HOST-gcc))/../$HOST && pwd) + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_FIND_ROOT_PATH=$CROSS_ROOT" + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER" + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY" + CMAKEFLAGS="$CMAKEFLAGS -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY" + + # Custom, llvm-mingw specific defaults. We normally set these in + # the frontend wrappers, but this makes sure they are enabled by + # default if that wrapper is bypassed as well. + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_DEFAULT_RTLIB=compiler-rt" + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_DEFAULT_CXX_STDLIB=libc++" + CMAKEFLAGS="$CMAKEFLAGS -DCLANG_DEFAULT_LINKER=lld" + BUILDDIR=$BUILDDIR-$HOST +fi + +TOOLCHAIN_ONLY=ON +if [ -n "$FULL_LLVM" ]; then + TOOLCHAIN_ONLY=OFF +fi + +cd llvm-project/llvm + +case $(uname) in +MINGW*) + EXPLICIT_PROJECTS=1 + ;; +*) + # If we have working symlinks, hook up other tools by symlinking them + # into tools, instead of using LLVM_ENABLE_PROJECTS. This way, all + # source code is under the directory tree of the toplevel cmake file + # (llvm-project/llvm), which makes cmake use relative paths to all source + # files. Using relative paths makes for identical compiler output from + # different source trees in different locations (for cases where e.g. + # path names are included, in assert messages), allowing ccache to speed + # up compilation. + cd tools + for p in clang lld; do + if [ ! -e $p ]; then + ln -s ../../$p . + fi + done + cd .. + ;; +esac + +mkdir -p $BUILDDIR +cd $BUILDDIR +cmake \ + ${CMAKE_GENERATOR+-G} "$CMAKE_GENERATOR" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_ASSERTIONS=$ASSERTS \ + ${EXPLICIT_PROJECTS+-DLLVM_ENABLE_PROJECTS="clang;lld"} \ + -DLLVM_TARGETS_TO_BUILD="ARM;AArch64;X86" \ + -DLLVM_INSTALL_TOOLCHAIN_ONLY=$TOOLCHAIN_ONLY \ + -DLLVM_TOOLCHAIN_TOOLS="llvm-ar;llvm-ranlib;llvm-objdump;llvm-rc;llvm-cvtres;llvm-nm;llvm-strings;llvm-readobj;llvm-dlltool;llvm-pdbutil;llvm-objcopy;llvm-strip;llvm-cov;llvm-profdata;llvm-addr2line" \ + ${HOST+-DLLVM_HOST_TRIPLE=$HOST} \ + $CMAKEFLAGS \ + .. + +#if [ -n "$NINJA" ]; then +# ninja -j$CORES +# ninja -j$CORES install/strip +#else +# make -j$CORES + make -j$CORES install/strip +#fi diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-mingw-w64-libraries.sh b/source/tool/cross-build/llvm-mingw/scripts/build-mingw-w64-libraries.sh new file mode 100755 index 000000000..1e28b77b3 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-mingw-w64-libraries.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +set -e + +if [ $# -lt 1 ]; then + echo $0 dest + exit 1 +fi +while [ $# -gt 0 ]; do + if [ "$1" = "--build-threads" ]; then + : ${CORES:=$2} + shift + else + PREFIX="$1" + fi + shift +done +mkdir -p "$PREFIX" +PREFIX="$(cd "$PREFIX" && pwd)" +export PATH=$PREFIX/bin:$PATH + +: ${CORES:=$(nproc 2>/dev/null)} +: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)} +: ${CORES:=4} +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} + +cd mingw-w64/mingw-w64-libraries +for lib in winpthreads winstorecompat; do + cd $lib + for arch in $ARCHS; do + mkdir -p build-$arch + cd build-$arch + ../configure --host=$arch-w64-mingw32 --prefix=$PREFIX/$arch-w64-mingw32 + make -j$CORES + make install + cd .. + done + cd .. +done diff --git a/source/tool/cross-build/llvm-mingw/scripts/build-mingw-w64.sh b/source/tool/cross-build/llvm-mingw/scripts/build-mingw-w64.sh new file mode 100755 index 000000000..5ff5fe18e --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/build-mingw-w64.sh @@ -0,0 +1,164 @@ +#!/bin/sh + +set -e + +DEFAULT_WIN32_WINNT=0x600 +DEFAULT_MSVCRT=ucrt + +while [ $# -gt 0 ]; do + case "$1" in + --build-threads) + : ${CORES:="$2"} + __NARG="--build-threads $2" + shift + ;; + --skip-include-triplet-prefix) + SKIP_INCLUDE_TRIPLET_PREFIX=1 + ;; + --with-default-win32-winnt=*) + DEFAULT_WIN32_WINNT="${1#*=}" + ;; + --with-default-msvcrt=*) + DEFAULT_MSVCRT="${1#*=}" + ;; + *) + PREFIX="$1" + ;; + esac + shift +done +if [ -z "$PREFIX" ]; then + echo $0 [--skip-include-triplet-prefix] [--with-default-win32-winnt=0x600] [--with-default-msvcrt=ucrt] dest + exit 1 +fi + +mkdir -p "$PREFIX" +PREFIX="$(cd "$PREFIX" && pwd)" + +ORIGPATH="$PATH" +if [ -z "$HOST" ]; then + # The newly built toolchain isn't crosscompiled; add it to the path. + export PATH=$PREFIX/bin:$PATH +else + # Crosscompiling the toolchain itself; the cross compiler is + # expected to already be in $PATH. + true +fi + +: ${CORES:=$(nproc 2>/dev/null)} +: ${CORES:=$(sysctl -n hw.ncpu 2>/dev/null)} +: ${CORES:=4} +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} + +if [ ! -d mingw-w64 ]; then + git clone git://git.code.sf.net/p/mingw-w64/mingw-w64 + CHECKOUT=1 +fi + +cd mingw-w64 + +if [ -n "$SYNC" ] || [ -n "$CHECKOUT" ]; then + [ -z "$SYNC" ] || git fetch + git checkout 0a1d495478d8ed1a94fc77b9dbb428b7e0372588 +fi + +# If crosscompiling the toolchain itself, we already have a mingw-w64 +# runtime and don't need to rebuild it. +if [ -z "$HOST" ]; then + if [ -z "$SKIP_INCLUDE_TRIPLET_PREFIX" ]; then + HEADER_ROOT=$PREFIX/generic-w64-mingw32 + else + HEADER_ROOT=$PREFIX + fi + + cd mingw-w64-headers + mkdir -p build + cd build + ../configure --prefix=$HEADER_ROOT \ + --enable-idl --with-default-win32-winnt=$DEFAULT_WIN32_WINNT --with-default-msvcrt=$DEFAULT_MSVCRT INSTALL="install -C" + make install + cd ../.. + if [ -z "$SKIP_INCLUDE_TRIPLET_PREFIX" ]; then + for arch in $ARCHS; do + mkdir -p $PREFIX/$arch-w64-mingw32 + if [ ! -e $PREFIX/$arch-w64-mingw32/include ]; then + ln -sfn ../generic-w64-mingw32/include $PREFIX/$arch-w64-mingw32/include + fi + done + fi + + cd mingw-w64-crt + for arch in $ARCHS; do + mkdir -p build-$arch + cd build-$arch + case $arch in + armv7) + FLAGS="--disable-lib32 --disable-lib64 --enable-libarm32" + ;; + aarch64) + FLAGS="--disable-lib32 --disable-lib64 --enable-libarm64" + ;; + i686) + FLAGS="--enable-lib32 --disable-lib64" + ;; + x86_64) + FLAGS="--disable-lib32 --enable-lib64" + ;; + esac + FLAGS="$FLAGS --with-default-msvcrt=$DEFAULT_MSVCRT" + ../configure --host=$arch-w64-mingw32 --prefix=$PREFIX/$arch-w64-mingw32 $FLAGS + make -j$CORES + make install + cd .. + done + cd .. +fi + +if [ -n "$HOST" ]; then + CONFIGFLAGS="$CONFIGFLAGS --host=$HOST" + CROSS_NAME=$HOST- + EXEEXT=.exe +else + case $(uname) in + MINGW*) + EXEEXT=.exe + ;; + *) + ;; + esac +fi +if [ -n "$SKIP_INCLUDE_TRIPLET_PREFIX" ]; then + CONFIGFLAGS="$CONFIGFLAGS --with-widl-includedir=$PREFIX/include" + # If using the same includedir for all archs, it's enough to + # build one single binary. + ALL_ARCHS="$ARCHS" + ARCHS=x86_64 +fi + +# If building on windows, we've installed prefixless wrappers - these break +# building widl, as the toolchain isn't functional yet. Restore the original +# path. +export PATH=$ORIGPATH +cd mingw-w64-tools/widl +for arch in $ARCHS; do + mkdir -p build-$CROSS_NAME$arch + cd build-$CROSS_NAME$arch + ../configure --prefix=$PREFIX --target=$arch-w64-mingw32 $CONFIGFLAGS LDFLAGS="-Wl,-s" + make -j$CORES + make install + cd .. +done +cd $PREFIX/bin +if [ -n "$SKIP_INCLUDE_TRIPLET_PREFIX" ]; then + for arch in $ALL_ARCHS; do + if [ "$arch" != "$ARCHS" ]; then + ln -sf $ARCHS-w64-mingw32-widl$EXEEXT $arch-w64-mingw32-widl$EXEEXT + fi + done +fi +if [ -n "$EXEEXT" ]; then + if [ -z "$HOST" ]; then + HOST=$(./clang -dumpmachine | sed 's/-.*//')-w64-mingw32 + fi + ln -sf $HOST-widl$EXEEXT widl$EXEEXT +fi diff --git a/source/tool/cross-build/llvm-mingw/scripts/extract-docker.sh b/source/tool/cross-build/llvm-mingw/scripts/extract-docker.sh new file mode 100755 index 000000000..f4c10ea33 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/extract-docker.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +if [ $# -lt 2 ]; then + echo $0 image dir + echo + echo This extracts \'dir\' from the docker image named \'image\' into the + echo current directory. NOTE: This removes the existing directory named + echo \'dir\' first. + exit 1 +fi + +image=$1 +dir=$2 + +rm -rf $(echo $dir | sed 's,^/,,') +docker run --rm $image tar -cf - $dir | tar -xvf - diff --git a/source/tool/cross-build/llvm-mingw/scripts/install-wrappers.sh b/source/tool/cross-build/llvm-mingw/scripts/install-wrappers.sh new file mode 100755 index 000000000..d9a1d884d --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/install-wrappers.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +set -e + +if [ $# -lt 1 ]; then + echo $0 dest + exit 1 +fi + +WORKDIR="$1" +PREFIX="$2" + + mkdir -p "$PREFIX" +PREFIX="$(cd "$PREFIX" && pwd)" + +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} +: ${TARGET_OSES:=${TOOLCHAIN_TARGET_OSES-mingw32 mingw32uwp}} + +if [ -n "$HOST" ] && [ -z "$CC" ]; then + CC=$HOST-gcc +fi +: ${CC:=cc} + +case $(uname) in +MINGW*) + EXEEXT=.exe + ;; +esac + +if [ -n "$EXEEXT" ]; then + CLANG_MAJOR=$(basename $(echo $PREFIX/lib/clang/* | awk '{print $NF}') | cut -f 1 -d .) + WRAPPER_FLAGS="$WRAPPER_FLAGS -municode -DCLANG=\"clang-$CLANG_MAJOR\"" +fi + + mkdir -p $PREFIX/bin + install ${WORKDIR}/scripts/wrappers/*-wrapper.sh $PREFIX/bin +if [ -n "$HOST" ]; then + # TODO: If building natively on msys, pick up the default HOST value from there. + WRAPPER_FLAGS="$WRAPPER_FLAGS -DDEFAULT_TARGET=\"$HOST\"" + for i in ${WORKDIR}/scripts/wrappers/*-wrapper.sh ; do + cat $i | sed 's/^DEFAULT_TARGET=.*/DEFAULT_TARGET='$HOST/ > $PREFIX/bin/$(basename $i) + chmod ugo+rx $PREFIX/bin/$(basename $i) + done +fi +$CC ${WORKDIR}/scripts/wrappers/clang-target-wrapper.c -o $PREFIX/bin/clang-target-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS +$CC ${WORKDIR}/scripts/wrappers/windres-wrapper.c -o $PREFIX/bin/windres-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS +$CC ${WORKDIR}/scripts/wrappers/llvm-wrapper.c -o $PREFIX/bin/llvm-wrapper$EXEEXT -O2 -Wl,-s $WRAPPER_FLAGS +if [ -n "$EXEEXT" ]; then + # For Windows, we should prefer the executable wrapper, which also works + # when invoked from outside of MSYS. + CTW_SUFFIX=$EXEEXT + CTW_LINK_SUFFIX=$EXEEXT +else + CTW_SUFFIX=.sh +fi +cd $PREFIX/bin +for arch in $ARCHS; do + for target_os in $TARGET_OSES; do + for exec in clang clang++ gcc g++ cc c99 c11 c++; do + ln -sf clang-target-wrapper$CTW_SUFFIX $arch-w64-$target_os-$exec$CTW_LINK_SUFFIX + done + for exec in addr2line ar ranlib nm objcopy strings strip; do + if [ -n "$HOST" ]; then + link_target=llvm-wrapper + else + link_target=llvm-$exec + fi + ln -sf $link_target$EXEEXT $arch-w64-$target_os-$exec$EXEEXT || true + done + for exec in windres; do + ln -sf $exec-wrapper$EXEEXT $arch-w64-$target_os-$exec$EXEEXT + done + for exec in ld objdump dlltool; do + ln -sf $exec-wrapper.sh $arch-w64-$target_os-$exec + done + done +done +if [ -n "$EXEEXT" ]; then + if [ ! -L clang$EXEEXT ] && [ -f clang$EXEEXT ] && [ ! -f clang-$CLANG_MAJOR$EXEEXT ]; then + mv clang$EXEEXT clang-$CLANG_MAJOR$EXEEXT + fi + if [ -z "$HOST" ]; then + HOST=$(./clang-$CLANG_MAJOR -dumpmachine | sed 's/-.*//')-w64-mingw32 + fi + for exec in clang clang++ gcc g++ cc c99 c11 c++ addr2line ar ranlib nm objcopy strings strip windres; do + ln -sf $HOST-$exec$EXEEXT $exec$EXEEXT + done + for exec in ld objdump dlltool; do + ln -sf $HOST-$exec $exec + done +fi diff --git a/source/tool/cross-build/llvm-mingw/scripts/libssp-Makefile b/source/tool/cross-build/llvm-mingw/scripts/libssp-Makefile new file mode 100644 index 000000000..97c1914ae --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/libssp-Makefile @@ -0,0 +1,24 @@ +SRC_PATH=$(word 1, $(dir $(MAKEFILE_LIST))) +vpath %.c $(SRC_PATH) + +CC = $(CROSS)gcc +AR = $(CROSS)ar + +CFLAGS = -O2 -Wall -Wundef -I$(SRC_PATH) -D_FORTIFY_SOURCE=0 -D__SSP_FORTIFY_LEVEL=0 + +SOURCES = $(filter-out ssp-local.c, $(patsubst $(SRC_PATH)%,%,$(wildcard $(SRC_PATH)*.c))) +OBJS = $(SOURCES:%.c=%.o) + +all: libssp.a libssp_nonshared.a libssp-0.dll + +libssp.a: $(OBJS) + $(AR) rcs $@ $+ + +libssp-0.dll: $(OBJS) + $(CC) -shared -o $@ $+ -Wl,--out-implib,libssp.dll.a + +libssp_nonshared.a: ssp-local.o + $(AR) rcs $@ $+ + +clean: + rm -f *.a *.o *.dll diff --git a/source/tool/cross-build/llvm-mingw/scripts/prepare-cross-toolchain.sh b/source/tool/cross-build/llvm-mingw/scripts/prepare-cross-toolchain.sh new file mode 100755 index 000000000..5fcb4a626 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/prepare-cross-toolchain.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +set -e + +if [ $# -lt 3 ]; then + echo $0 src dest arch + exit 1 +fi +SRC="$1" +DEST="$2" +CROSS_ARCH="$3" + +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} + +CLANG_VERSION=$(basename $(dirname $(dirname $(dirname $($SRC/bin/clang --print-libgcc-file-name -rtlib=compiler-rt))))) + +# If linked to a shared libc++/libunwind, we need to bundle those DLLs +# in the bin directory. +for i in libc++ libunwind; do + if [ -f $SRC/$CROSS_ARCH-w64-mingw32/bin/$i.dll ]; then + cp $SRC/$CROSS_ARCH-w64-mingw32/bin/$i.dll $DEST/bin + fi +done + +cp -a $SRC/lib/clang/$CLANG_VERSION/lib $DEST/lib/clang/$CLANG_VERSION +rm -rf $DEST/include +cp -a $SRC/generic-w64-mingw32/include $DEST/include +for arch in $ARCHS; do + mkdir -p $DEST/$arch-w64-mingw32 + for subdir in bin lib; do + cp -a $SRC/$arch-w64-mingw32/$subdir $DEST/$arch-w64-mingw32 + done +done diff --git a/source/tool/cross-build/llvm-mingw/scripts/release.sh b/source/tool/cross-build/llvm-mingw/scripts/release.sh new file mode 100755 index 000000000..ac5e33bad --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/release.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +set -ex + +if [ $# -lt 1 ]; then + echo $0 tag + exit 1 +fi + +TAG=$1 + +time docker build -f Dockerfile . -t mstorsjo/llvm-mingw:latest -t mstorsjo/llvm-mingw:$TAG +time docker build -f Dockerfile.dev . -t mstorsjo/llvm-mingw:dev -t mstorsjo/llvm-mingw:dev-$TAG + +DISTRO=ubuntu-16.04 +docker run --rm mstorsjo/llvm-mingw:latest sh -c "cd /opt && mv llvm-mingw llvm-mingw-$TAG-$DISTRO && tar -Jcvf - llvm-mingw-$TAG-$DISTRO" > llvm-mingw-$TAG-$DISTRO.tar.xz + +cleanup() { + for i in $temp_images; do + docker rmi --no-prune $i || true + done +} + +trap cleanup EXIT INT TERM + +for arch in i686 x86_64 armv7 aarch64; do + temp=$(uuidgen) + temp_images="$temp_images $temp" + time docker build -f Dockerfile.cross --build-arg BASE=mstorsjo/llvm-mingw:dev --build-arg CROSS_ARCH=$arch --build-arg TAG=$TAG- -t $temp . + ./extract-docker.sh $temp /llvm-mingw-$TAG-$arch.zip +done diff --git a/source/tool/cross-build/llvm-mingw/scripts/run-tests.sh b/source/tool/cross-build/llvm-mingw/scripts/run-tests.sh new file mode 100755 index 000000000..e9a678888 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/run-tests.sh @@ -0,0 +1,198 @@ +#!/bin/sh + +set -ex + +if [ $# -lt 1 ]; then + echo $0 dest + exit 1 +fi +PREFIX="$1" +export PATH=$PREFIX/bin:$PATH + +: ${ARCHS:=${TOOLCHAIN_ARCHS-i686 x86_64 armv7 aarch64}} + +cd test + +DEFAULT_OSES="mingw32 mingw32uwp" +cat< is-ucrt.c +#include +#if __MSVCRT_VERSION__ < 0x1400 && !defined(_UCRT) +#error not ucrt +#endif +EOF +ANY_ARCH=$(echo $ARCHS | awk '{print $1}') +if ! $ANY_ARCH-w64-mingw32-gcc -E is-ucrt.c > /dev/null 2>&1; then + # If the default CRT isn't UCRT, we can't build for mingw32uwp. + DEFAULT_OSES="mingw32" +fi + +: ${TARGET_OSES:=${TOOLCHAIN_TARGET_OSES-$DEFAULT_OSES}} + +if [ -z "$RUN_X86" ]; then + case $(uname) in + MINGW*|MSYS*) + # A non-empty string to trigger running, even if no wrapper is needed. + NATIVE_X86=1 + RUN_X86=" " + export PATH=.:$PATH + ;; + *) + RUN_X86=wine + ;; + esac +fi + + +TESTS_C="hello hello-tls crt-test setjmp" +TESTS_C_DLL="autoimport-lib" +TESTS_C_LINK_DLL="autoimport-main" +TESTS_C_NO_BUILTIN="crt-test" +TESTS_CPP="hello-cpp" +TESTS_CPP_LOAD_DLL="tlstest-main" +TESTS_CPP_EXCEPTIONS="hello-exception exception-locale exception-reduced" +TESTS_CPP_DLL="tlstest-lib" +TESTS_SSP="stacksmash" +TESTS_ASAN="stacksmash" +TESTS_UBSAN="ubsan" +TESTS_UWP="uwp-error" +for arch in $ARCHS; do + case $arch in + i686|x86_64) + RUN="$RUN_X86" + COPY= + NATIVE="$NATIVE_X86" + ;; + armv7) + RUN="$RUN_ARMV7" + COPY="$COPY_ARMV7" + NATIVE="$NATIVE_ARMV7" + ;; + aarch64) + RUN="$RUN_AARCH64" + COPY="$COPY_AARCH64" + NATIVE="$NATIVE_AARCH64" + ;; + esac + + for target_os in $TARGET_OSES; do + TEST_DIR="$arch-$target_os" + mkdir -p $TEST_DIR + for test in $TESTS_C; do + $arch-w64-$target_os-clang $test.c -o $TEST_DIR/$test.exe + done + for test in $TESTS_C_DLL; do + $arch-w64-$target_os-clang $test.c -shared -o $TEST_DIR/$test.dll -Wl,--out-implib,$TEST_DIR/lib$test.dll.a + done + for test in $TESTS_C_LINK_DLL; do + $arch-w64-$target_os-clang $test.c -o $TEST_DIR/$test.exe -L$TEST_DIR -l${test%-main}-lib + done + TESTS_EXTRA="" + for test in $TESTS_C_NO_BUILTIN; do + $arch-w64-$target_os-clang $test.c -o $TEST_DIR/$test-no-builtin.exe -fno-builtin + TESTS_EXTRA="$TESTS_EXTRA $test-no-builtin" + done + for test in $TESTS_CPP $TESTS_CPP_EXCEPTIONS; do + $arch-w64-$target_os-clang++ $test.cpp -o $TEST_DIR/$test.exe + done + for test in $TESTS_CPP_EXCEPTIONS; do + $arch-w64-$target_os-clang++ $test.cpp -O2 -o $TEST_DIR/$test-opt.exe + done + if [ "$arch" != "aarch64" ] || [ -n "$NATIVE_AARCH64" ]; then + for test in $TESTS_CPP_EXCEPTIONS; do + TESTS_EXTRA="$TESTS_EXTRA $test $test-opt" + done + fi + for test in $TESTS_CPP_LOAD_DLL; do + case $target_os in + # DLLs can't be loaded without a Windows package + mingw32uwp) continue ;; + *) ;; + esac + $arch-w64-$target_os-clang++ $test.cpp -o $TEST_DIR/$test.exe + TESTS_EXTRA="$TESTS_EXTRA $test" + done + for test in $TESTS_CPP_DLL; do + $arch-w64-$target_os-clang++ $test.cpp -shared -o $TEST_DIR/$test.dll + done + for test in $TESTS_SSP; do + $arch-w64-$target_os-clang $test.c -o $TEST_DIR/$test.exe -fstack-protector-strong + done + for test in $TESTS_UWP; do + set +e + # compilation should fail for UWP and WinRT + $arch-w64-$target_os-clang $test.c -o $TEST_DIR/$test.exe -Wimplicit-function-declaration -Werror + UWP_ERROR=$? + set -e + case $target_os in + mingw32uwp) + if [ $UWP_ERROR -eq 0 ]; then + echo "UWP compilation should have failed for test $test!" + exit 1 + fi + ;; + *) + if [ $UWP_ERROR -eq 0 ]; then + TESTS_EXTRA="$TESTS_EXTRA $test" + else + echo "$test failed to compile for non-UWP target!" + exit 1 + fi + ;; + esac + done + for test in $TESTS_ASAN; do + case $arch in + # Sanitizers on windows only support x86. + i686|x86_64) ;; + *) continue ;; + esac + $arch-w64-$target_os-clang $test.c -o $TEST_DIR/$test-asan.exe -fsanitize=address -g -gcodeview -Wl,-pdb,$TEST_DIR/$test-asan.pdb + # Only run these tests on native windows; asan doesn't run in wine. + if [ -n "$NATIVE" ]; then + TESTS_EXTRA="$TESTS_EXTRA $test" + fi + done + for test in $TESTS_UBSAN; do + case $arch in + # Ubsan might not require anything too x86 specific, but we don't + # build any of the sanitizer libs for anything else than x86. + i686|x86_64) ;; + *) continue ;; + esac + $arch-w64-$target_os-clang $test.c -o $TEST_DIR/$test.exe -fsanitize=undefined + TESTS_EXTRA="$TESTS_EXTRA $test" + done + DLL="$TESTS_C_DLL $TESTS_CPP_DLL" + compiler_rt_arch=$arch + if [ "$arch" = "i686" ]; then + compiler_rt_arch=i386 + fi + if [ "$target_os" != "mingw32" ]; then + # The Windows Store specific CRT DLL is usually not available + # outside of such contexts, so skip trying to run those tests. + continue + fi + for i in libc++ libunwind libssp-0 libclang_rt.asan_dynamic-$compiler_rt_arch; do + if [ -f $PREFIX/$arch-w64-mingw32/bin/$i.dll ]; then + cp $PREFIX/$arch-w64-mingw32/bin/$i.dll $TEST_DIR + DLL="$DLL $i" + fi + done + cd $TEST_DIR + if [ -n "$COPY" ]; then + for i in $DLL; do + $COPY $i.dll + done + fi + for test in $TESTS_C $TESTS_C_LINK_DLL $TESTS_CPP $TESTS_EXTRA $TESTS_SSP; do + file=$test.exe + if [ -n "$COPY" ]; then + $COPY $file + fi + if [ -n "$RUN" ]; then + $RUN $file + fi + done + cd .. + done +done diff --git a/source/tool/cross-build/llvm-mingw/scripts/strip-llvm.sh b/source/tool/cross-build/llvm-mingw/scripts/strip-llvm.sh new file mode 100755 index 000000000..69a5d1d19 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/strip-llvm.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +set -e + +if [ $# -lt 1 ]; then + echo $0 dir + exit 1 +fi +PREFIX="$1" +cd "$PREFIX" + +if [ -n "$FULL_LLVM" ]; then + exit 0 +fi + +case $(uname) in +MINGW*) + EXEEXT=.exe + ;; +*) + ;; +esac + +cd bin +for i in bugpoint c-index-test clang-* diagtool dsymutil git-clang-format hmaptool ld64.lld llc lli llvm-* obj2yaml opt sancov sanstats scan-build scan-view verify-uselistorder wasm-ld yaml2obj libclang.dll LTO.dll *Remarks.dll *.bat; do + basename=$i + if [ -n "$EXEEXT" ]; then + # Some in the list are expanded globs, some are plain names we list. + case $i in + *$EXEEXT) + basename=$(echo $i | sed s/$EXEEXT//) + ;; + esac + i=$basename + if [ -e $basename$EXEEXT ]; then + i=$basename$EXEEXT + fi + fi + # Basename has got $EXEEXT stripped, but any other suffix kept intact. + case $basename in + *.sh) + ;; + clang++|clang-*.*|clang-cpp) + ;; + clang-*) + suffix="${basename#*-}" + # Test removing all numbers from the suffix; if it is empty, the suffix + # was a plain number (as if the original name was clang-7); if it wasn't + # empty, remove the tool. + if [ "$(echo $suffix | tr -d '[0-9]')" != "" ]; then + rm -f $i + fi + ;; + llvm-ar|llvm-cvtres|llvm-dlltool|llvm-nm|llvm-objdump|llvm-ranlib|llvm-rc|llvm-readobj|llvm-strings|llvm-pdbutil|llvm-objcopy|llvm-strip|llvm-cov|llvm-profdata|llvm-addr2line|llvm-wrapper) + ;; + ld64.lld|wasm-ld) + if [ -e $i ]; then + rm $i + fi + ;; + *) + if [ -f $i ]; then + rm $i + elif [ -L $i ] && [ ! -e $(readlink $i) ]; then + # Remove dangling symlinks + rm $i + fi + ;; + esac +done +if [ -n "$EXEEXT" ]; then + # Convert ld.lld from a symlink to a regular file, so we can remove + # the one it points to. On MSYS, and if packaging built toolchains + # in a zip file, symlinks are converted into copies. + if [ -L ld.lld$EXEEXT ]; then + cp ld.lld$EXEEXT tmp + rm ld.lld$EXEEXT + mv tmp ld.lld$EXEEXT + fi + # lld-link isn't used normally, but can be useful for debugging/testing, + # and is kept in unix setups. Removing it when packaging for windows, + # to conserve space. + rm -f lld$EXEEXT lld-link$EXEEXT + # Remove superfluous frontends; these aren't really used. + rm -f clang-cpp* clang++* +fi +cd .. +rm -rf share libexec +cd include +rm -rf clang clang-c lld llvm llvm-c +cd .. +cd lib +rm -rf lib*.a *.so* *.dylib* cmake +cd .. diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/.gitignore b/source/tool/cross-build/llvm-mingw/scripts/test/.gitignore new file mode 100644 index 000000000..36cff277e --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/.gitignore @@ -0,0 +1,5 @@ +*.exe +*.dll +*.lib +*.dll.a +*.pdb diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-lib.c b/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-lib.c new file mode 100644 index 000000000..a3bf1aba6 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-lib.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "autoimport-lib.h" + +int var; + +int array[10]; + +int getVar(void) { + return var; +} + +void setVar(int val) { + var = val; +} + +int getArray(int index) { + return array[index]; +} + +void setArray(int index, int val) { + array[index] = val; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-lib.h b/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-lib.h new file mode 100644 index 000000000..576179c2a --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-lib.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef AUTOIMPORT_LIB_H +#define AUTOIMPORT_LIB_H + +extern int var; +extern int array[10]; +int getVar(void); +void setVar(int val); +int getArray(int index); +void setArray(int index, int val); + +#endif diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-main.c b/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-main.c new file mode 100644 index 000000000..7cd58f59d --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/autoimport-main.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "autoimport-lib.h" + +int *ptr = &var; + +int *arrayptr = &array[3]; + +int main(int argc, char *argv[]) { + setVar(42); + if (var != 42) return 1; + var++; + if (getVar() != 43) return 1; + (*ptr)++; + if (getVar() != 44) return 1; + + setArray(3, 100); + if (array[3] != 100) return 1; + if (*arrayptr != 100) return 1; + array[3]++; + if (*arrayptr != 101) return 1; + if (getArray(3) != 101) return 1; + (*arrayptr)++; + if (getArray(3) != 102) return 1; + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/crt-test.c b/source/tool/cross-build/llvm-mingw/scripts/test/crt-test.c new file mode 100644 index 000000000..771083542 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/crt-test.c @@ -0,0 +1,1657 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef __linux__ +#define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif + +#ifndef _WIN32 +extern char **environ; +#endif + +#ifdef _WIN32 +static void invalid_parameter(const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t pReserved) { +} +#endif + +int tests = 0, fails = 0; +const char *context = ""; + +#define TEST(x) do { \ + tests++; \ + if (!(x)) { \ + fails++; \ + printf("%s:%d: %s\"%s\" failed\n", __FILE__, __LINE__, context, #x); \ + } \ + } while (0) + +#define TEST_STR(x, expect) do { \ + tests++; \ + if (strcmp((x), (expect))) { \ + fails++; \ + printf("%s:%d: %sexpected \"%s\", got \"%s\"\n", __FILE__, __LINE__, context, (expect), (x)); \ + } \ + } while (0) + +#define TEST_FLT(x, expect) do { \ + tests++; \ + if ((x) != (expect)) { \ + fails++; \ + printf("%s:%d: %s%s failed, expected %f, got %f\n", __FILE__, __LINE__, context, #x, (double)(expect), (double)(x)); \ + } \ + } while (0) + +#define TEST_FLT_EXPR(x, expr) do { \ + tests++; \ + if (!(expr)) { \ + fails++; \ + printf("%s:%d: %s%s failed, got %f\n", __FILE__, __LINE__, context, #expr, (double)(x)); \ + } \ + } while (0) + +#define TEST_FLT_NAN_ANY(x) do { \ + tests++; \ + if (!isnan(x)) { \ + fails++; \ + printf("%s:%d: %s%s failed, expected any NAN, got %f\n", __FILE__, __LINE__, context, #x, (double)(x)); \ + } \ + } while (0) + +// Use TEST_FLT_NAN with F(NAN) or -F(NAN) as the expect parameter. +// On Glibc, F(-NAN), i.e. strtod("-NAN", NULL), returns a positive NAN. +// On MSVC, the NAN literal is negative, but strtod("NAN", NULL) returns a +// positive one. +#define TEST_FLT_NAN(x, expect) do { \ + tests++; \ + long double val = (x); \ + long double expval = (expect); \ + if (!isnan(val) || !!signbit(val) != !!signbit(expval)) { \ + fails++; \ + printf("%s:%d: %s%s failed, expected %f, got %f\n", __FILE__, __LINE__, context, #x, (double)expval, (double)val); \ + } \ + } while (0) + +#define TEST_FLT_ACCURACY(x, expect, accuracy) do { \ + long double val = (x); \ + long double diff = fabsl(val - (expect)); \ + tests++; \ + if (diff <= (accuracy)) { \ + /* All ok, not NAN */ \ + } else { \ + fails++; \ + printf("%s:%d: %s%s failed, expected %f, got %f (diff %f > %f)\n", __FILE__, __LINE__, context, #x, (double)(expect), (double)val, (double)diff, (double)(accuracy)); \ + } \ + } while (0) + +#define TEST_FLT_SIGN(x, expect) do { \ + tests++; \ + long double val = (x); \ + long double expval = (expect); \ + if (val != expval || !!signbit(val) != !!signbit(expval)) { \ + fails++; \ + printf("%s:%d: %s%s failed, expected %f, got %f\n", __FILE__, __LINE__, context, #x, (double)expval, (double)val); \ + } \ + } while (0) + +#define TEST_INT(x, expect) do { \ + tests++; \ + if ((x) != (expect)) { \ + fails++; \ + printf("%s:%d: %s%s failed, expected %lld, got %lld\n", __FILE__, __LINE__, context, #x, (long long)(expect), (long long)(x)); \ + } \ + } while (0) + +#define TEST_PTR(x, expect) do { \ + tests++; \ + if ((x) != (expect)) { \ + fails++; \ + printf("%s:%d: %s%s failed, expected %p, got %p\n", __FILE__, __LINE__, context, #x, (expect), (x)); \ + } \ + } while (0) + +#define F(x) strtod(#x, NULL) +#define L(x) strtol(#x, NULL, 0) +#define UL(x) strtoul(#x, NULL, 0) +#define LL(x) strtoll(#x, NULL, 0) +#define ULL(x) strtoull(#x, NULL, 0) + +int vsscanf_wrap(const char* str, const char* fmt, ...) { + va_list ap; + int ret; + va_start(ap, fmt); + ret = vsscanf(str, fmt, ap); + va_end(ap); + return ret; +} + +int main(int argc, char* argv[]) { + char buf[200]; + int i; + uint64_t myconst = 0xbaadf00dcafe; + + snprintf(buf, sizeof(buf), "%f", 3.141592654); + TEST_STR(buf, "3.141593"); + snprintf(buf, sizeof(buf), "%"PRIx64" %"PRIx64" %"PRIx64" %"PRIx64" %"PRIx64" %"PRIx64" %"PRIx64" %"PRIx64" %"PRIx64" %"PRIx64, myconst + 0, myconst + 1, myconst + 2, myconst + 3, myconst + 4, myconst + 5, myconst + 6, myconst + 7, myconst + 8, myconst + 9); + TEST_STR(buf, "baadf00dcafe baadf00dcaff baadf00dcb00 baadf00dcb01 baadf00dcb02 baadf00dcb03 baadf00dcb04 baadf00dcb05 baadf00dcb06 baadf00dcb07"); + + uint64_t val0, val1, val2, val3, val4, val5, val6, val7, val8, val9; + if (sscanf("baadf00dcafe baadf00dcaff baadf00dcb00 baadf00dcb01 baadf00dcb02 baadf00dcb03 baadf00dcb04 baadf00dcb05 baadf00dcb06 baadf00dcb07", "%"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64, &val0, &val1, &val2, &val3, &val4, &val5, &val6, &val7, &val8, &val9) != 10) { + fails++; + printf("sscanf failed\n"); + } else { + int64_t diff = 0; + diff += llabs((int64_t)(val0 - 0 - myconst)); + diff += llabs((int64_t)(val1 - 1 - myconst)); + diff += llabs((int64_t)(val2 - 2 - myconst)); + diff += llabs((int64_t)(val3 - 3 - myconst)); + diff += llabs((int64_t)(val4 - 4 - myconst)); + diff += llabs((int64_t)(val5 - 5 - myconst)); + diff += llabs((int64_t)(val6 - 6 - myconst)); + diff += llabs((int64_t)(val7 - 7 - myconst)); + diff += llabs((int64_t)(val8 - 8 - myconst)); + diff += llabs((int64_t)(val9 - 9 - myconst)); + if (diff != 0) { + fails++; + printf("sscanf output failed\n"); + } + } + tests++; + + val0 = val1 = val2 = val3 = val4 = val5 = val6 = val7 = val8 = val9 = 0xff; + if (vsscanf_wrap("baadf00dcafe baadf00dcaff baadf00dcb00 baadf00dcb01 baadf00dcb02 baadf00dcb03 baadf00dcb04 baadf00dcb05 baadf00dcb06 baadf00dcb07", "%"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64" %"SCNx64, &val0, &val1, &val2, &val3, &val4, &val5, &val6, &val7, &val8, &val9) != 10) { + fails++; + printf("vsscanf failed\n"); + } else { + int64_t diff = 0; + diff += llabs((int64_t)(val0 - 0 - myconst)); + diff += llabs((int64_t)(val1 - 1 - myconst)); + diff += llabs((int64_t)(val2 - 2 - myconst)); + diff += llabs((int64_t)(val3 - 3 - myconst)); + diff += llabs((int64_t)(val4 - 4 - myconst)); + diff += llabs((int64_t)(val5 - 5 - myconst)); + diff += llabs((int64_t)(val6 - 6 - myconst)); + diff += llabs((int64_t)(val7 - 7 - myconst)); + diff += llabs((int64_t)(val8 - 8 - myconst)); + diff += llabs((int64_t)(val9 - 9 - myconst)); + if (diff != 0) { + fails++; + printf("vsscanf output failed\n"); + } + } + tests++; + +#ifdef _WIN32 + _set_invalid_parameter_handler(invalid_parameter); +#endif + errno = 0; + TEST_INT(strtol("foo", NULL, 100), 0); + TEST_INT(errno, EINVAL); + + int env_ok = 0; + putenv("CRT_TEST_VAR=1"); + for (char **ptr = environ; *ptr; ptr++) + if (!strcmp(*ptr, "CRT_TEST_VAR=1")) + env_ok = 1; + if (!env_ok) { + fails++; + printf("Variable set by putenv not found found in environ\n"); + } + tests++; + env_ok = 0; + putenv("CRT_TEST_VAR=2"); + for (char **ptr = environ; *ptr; ptr++) + if (!strcmp(*ptr, "CRT_TEST_VAR=2")) + env_ok = 1; + if (!env_ok) { + fails++; + printf("Variable updated by putenv not found found in environ\n"); + } + tests++; + +#define TEST_FLOOR(floor) \ + TEST_FLT(floor(F(3.9)), 3.0); \ + TEST_FLT(floor(F(-3.3)), -4.0); \ + TEST_FLT(floor(F(-3.9)), -4.0); \ + TEST_FLT(floor(F(INFINITY)), INFINITY); \ + TEST_FLT(floor(F(-INFINITY)), -INFINITY); \ + TEST_FLT_NAN(floor(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(floor(-F(NAN)), -F(NAN)) + + TEST_FLOOR(floor); + TEST_FLOOR(floorf); + TEST_FLOOR(floorl); + TEST_FLT(floor(F(17179869184.0)), 17179869184.0); + +#define TEST_CEIL(ceil) \ + TEST_FLT(ceil(F(3.9)), 4.0); \ + TEST_FLT(ceil(F(-3.3)), -3.0); \ + TEST_FLT(ceil(F(-3.9)), -3.0); \ + TEST_FLT(ceil(F(INFINITY)), INFINITY); \ + TEST_FLT(ceil(F(-INFINITY)), -INFINITY); \ + TEST_FLT_NAN(ceil(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(ceil(-F(NAN)), -F(NAN)) + + TEST_CEIL(ceil); + TEST_CEIL(ceilf); + TEST_CEIL(ceill); + +#define TEST_TRUNC(trunc) \ + TEST_FLT(trunc(F(3.9)), 3.0); \ + TEST_FLT(trunc(F(-3.3)), -3.0); \ + TEST_FLT(trunc(F(-3.9)), -3.0); \ + TEST_FLT(trunc(F(INFINITY)), INFINITY); \ + TEST_FLT(trunc(F(-INFINITY)), -INFINITY); \ + TEST_FLT_NAN(trunc(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(trunc(-F(NAN)), -F(NAN)) + + TEST_TRUNC(trunc); + TEST_TRUNC(truncf); + TEST_TRUNC(truncl); + +#define TEST_SQRT(sqrt) \ + TEST_FLT(sqrt(F(9)), 3.0); \ + TEST_FLT(sqrt(F(0.25)), 0.5); \ + TEST_FLT(sqrt(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN_ANY(sqrt(F(-1.0))); \ + TEST_FLT_NAN_ANY(sqrt(F(-INFINITY))); \ + TEST_FLT_NAN(sqrt(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(sqrt(-F(NAN)), -F(NAN)) + + TEST_SQRT(sqrt); + TEST_SQRT(sqrtf); + TEST_SQRT(sqrtl); + +#define TEST_CBRT(cbrt) \ + TEST_FLT_ACCURACY(cbrt(F(27)), 3.0, 0.001); \ + TEST_FLT_ACCURACY(cbrt(F(-27)), -3.0, 0.001); \ + TEST_FLT_ACCURACY(cbrt(F(0.125)), 0.5, 0.001); \ + TEST_FLT_ACCURACY(cbrt(F(-0.125)), -0.5, 0.001); \ + TEST_FLT(cbrt(F(INFINITY)), INFINITY); \ + TEST_FLT(cbrt(F(-INFINITY)), -INFINITY); \ + TEST_FLT_NAN(cbrt(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(cbrt(-F(NAN)), -F(NAN)) + + TEST_CBRT(cbrt); + TEST_CBRT(cbrtf); + TEST_CBRT(cbrtl); + +#define TEST_HYPOT(hypot) \ + TEST_FLT_ACCURACY(hypot(F(1.0), F(1.0)), 1.414214, 0.001); \ + TEST_FLT_ACCURACY(hypot(F(-1.0), F(1.0)), 1.414214, 0.001); \ + TEST_FLT_ACCURACY(hypot(F(1.0), F(-1.0)), 1.414214, 0.001); \ + TEST_FLT_ACCURACY(hypot(F(-1.0), F(-1.0)), 1.414214, 0.001); \ + TEST_FLT(hypot(F(INFINITY), F(0.0)), INFINITY); \ + TEST_FLT(hypot(F(-INFINITY), F(0.0)), INFINITY); \ + TEST_FLT(hypot(F(0.0), F(INFINITY)), INFINITY); \ + TEST_FLT(hypot(F(0.0), F(-INFINITY)), INFINITY); \ + TEST_FLT_NAN_ANY(hypot(F(NAN), F(0.0))); \ + TEST_FLT_NAN_ANY(hypot(F(0.0), F(NAN))) + + TEST_HYPOT(hypot); + TEST_HYPOT(hypotf); + TEST_HYPOT(hypotl); + +#define TEST_FMA(fma) \ + TEST_FLT(fma(F(2), F(3), F(4)), 10); \ + TEST_FLT_NAN(fma(F(NAN), F(3), F(4)), F(NAN)); \ + TEST_FLT_NAN(fma(F(2), F(NAN), F(4)), F(NAN)); \ + TEST_FLT_NAN(fma(F(2), F(3), F(NAN)), F(NAN)) + + TEST_FMA(fma); + TEST_FMA(fmaf); + TEST_FMA(fmal); + + double retd; + float retf; + long double retl; +#define TEST_MODF(modf, retd) \ + TEST_FLT_ACCURACY(modf(F(2.1), &retd), 0.1, 0.001); \ + TEST_FLT(retd, 2); \ + TEST_FLT_ACCURACY(modf(F(-2.1), &retd), -0.1, 0.001); \ + TEST_FLT(retd, -2); \ + TEST_FLT(modf(F(INFINITY), &retd), 0); \ + TEST_FLT(retd, INFINITY); \ + TEST_FLT(modf(F(-INFINITY), &retd), 0); \ + TEST_FLT(retd, -INFINITY); \ + TEST_FLT_NAN(modf(F(NAN), &retd), F(NAN)); \ + TEST_FLT_NAN(retd, F(NAN)); \ + TEST_FLT_NAN(modf(-F(NAN), &retd), -F(NAN)); \ + TEST_FLT_NAN(retd, -F(NAN)) + + TEST_MODF(modf, retd); + TEST_MODF(modff, retf); + TEST_MODF(modfl, retl); + +#define TEST_FMOD(fmod) \ + TEST_FLT_ACCURACY(fmod(F(3.9), F(4.0)), 3.9, 0.001); \ + TEST_FLT_ACCURACY(fmod(F(7.9), F(4.0)), 3.9, 0.001); \ + TEST_FLT_ACCURACY(fmod(F(-3.9), F(4.0)), -3.9, 0.001); \ + TEST_FLT_ACCURACY(fmod(F(3.9), F(-4.0)), 3.9, 0.001); \ + TEST_FLT_ACCURACY(fmod(F(7.9), F(-4.0)), 3.9, 0.001); \ + TEST_FLT_ACCURACY(fmod(F(-3.9), F(-4.0)), -3.9, 0.001); \ + TEST_FLT_NAN_ANY(fmod(F(INFINITY), F(4.0))); \ + TEST_FLT_NAN_ANY(fmod(F(-INFINITY), F(4.0))); \ + TEST_FLT_NAN(fmod(F(0), F(NAN)), F(NAN)); \ + TEST_FLT_NAN(fmod(F(0), -F(NAN)), -F(NAN)); \ + TEST_FLT_NAN(fmod(F(NAN), F(1)), F(NAN)); \ + TEST_FLT_NAN(fmod(-F(NAN), F(1)), -F(NAN)); \ + TEST_FLT_NAN_ANY(fmod(F(3.9), F(0))); \ + TEST_FLT_ACCURACY(fmod(F(3.9), F(INFINITY)), 3.9, 0.001); \ + TEST_FLT_ACCURACY(fmod(F(3.9), F(-INFINITY)), 3.9, 0.001) + + TEST_FMOD(fmod); + TEST_FMOD(fmodf); + TEST_FMOD(fmodl); + +#define TEST_REMAINDER(remainder) \ + TEST_FLT_ACCURACY(remainder(F(1.9), F(4.0)), 1.9, 0.001); \ + TEST_FLT(remainder(F(2.0), F(4.0)), 2.0); \ + TEST_FLT(remainder(F(6.0), F(4.0)), -2.0); \ + TEST_FLT(remainder(F(-6.0), F(4.0)), 2.0); \ + TEST_FLT_ACCURACY(remainder(F(3.9), F(4.0)), -0.1, 0.001); \ + TEST_FLT_ACCURACY(remainder(F(-2.0), F(4.0)), -2.0, 0.001); \ + TEST_FLT_ACCURACY(remainder(F(-3.9), F(4.0)), 0.1, 0.001); \ + TEST_FLT_ACCURACY(remainder(F(-4.1), F(4.0)), -0.1, 0.001); \ + TEST_FLT_ACCURACY(remainder(F(3.9), F(-4.0)), -0.1, 0.001); \ + TEST_FLT_ACCURACY(remainder(F(-3.9), F(-4.0)), 0.1, 0.001); \ + TEST_FLT_NAN_ANY(remainder(F(INFINITY), F(4.0))); \ + TEST_FLT_NAN_ANY(remainder(F(-INFINITY), F(4.0))); \ + TEST_FLT_NAN(remainder(F(0), F(NAN)), F(NAN)); \ + TEST_FLT_NAN(remainder(F(0), -F(NAN)), -F(NAN)); \ + TEST_FLT_NAN(remainder(F(NAN), F(1)), F(NAN)); \ + TEST_FLT_NAN(remainder(-F(NAN), F(1)), -F(NAN)); \ + TEST_FLT_NAN_ANY(remainder(F(1.9), F(0))) + + TEST_REMAINDER(remainder); + TEST_REMAINDER(remainderf); + TEST_REMAINDER(remainderl); + + int quo = 42; +#define TEST_REMQUO(remquo) \ + TEST_FLT_ACCURACY(remquo(F(1.9), F(4.0), &quo), 1.9, 0.001); \ + TEST_INT(quo, 0); \ + TEST_FLT(remquo(F(2.0), F(4.0), &quo), 2.0); \ + TEST_INT(quo, 0); \ + TEST_FLT(remquo(F(6.0), F(4.0), &quo), -2.0); \ + TEST_INT(quo, 2); \ + TEST_FLT(remquo(F(-6.0), F(4.0), &quo), 2.0); \ + TEST_INT(quo, -2); \ + TEST_FLT_ACCURACY(remquo(F(3.9), F(4.0), &quo), -0.1, 0.001); \ + TEST_INT(quo, 1); \ + TEST_FLT_ACCURACY(remquo(F(-2.0), F(4.0), &quo), -2.0, 0.001); \ + TEST_INT(quo, 0); \ + TEST_FLT_ACCURACY(remquo(F(-3.9), F(4.0), &quo), 0.1, 0.001); \ + TEST_INT(quo, -1); \ + TEST_FLT_ACCURACY(remquo(F(-4.1), F(4.0), &quo), -0.1, 0.001); \ + TEST_INT(quo, -1); \ + TEST_FLT_ACCURACY(remquo(F(3.9), F(-4.0), &quo), -0.1, 0.001); \ + TEST_INT(quo, -1); \ + TEST_FLT_ACCURACY(remquo(F(-3.9), F(-4.0), &quo), 0.1, 0.001); \ + TEST_INT(quo, 1); \ + TEST_FLT_NAN_ANY(remquo(F(INFINITY), F(4.0), &quo)); \ + TEST_FLT_NAN_ANY(remquo(F(-INFINITY), F(4.0), &quo)); \ + TEST_FLT_NAN(remquo(F(0), F(NAN), &quo), F(NAN)); \ + TEST_FLT_NAN(remquo(F(0), -F(NAN), &quo), -F(NAN)); \ + TEST_FLT_NAN(remquo(F(NAN), F(0), &quo), F(NAN)); \ + TEST_FLT_NAN(remquo(-F(NAN), F(0), &quo), -F(NAN)); \ + TEST_FLT_NAN_ANY(remquo(F(1.9), F(0), &quo)); + + TEST_REMQUO(remquo); + TEST_REMQUO(remquof); + TEST_REMQUO(remquol); + + for (i = 0; i < 2; i++) { + if (i == 0) { + // Use the default env in the first round here + context = "FE_DFL_ENV "; + } else { + fesetround(FE_TONEAREST); // Only set it on the second round + context = "FE_TONEAREST "; + } + +#define TEST_LRINT_NEAREST(lrint) \ + TEST_INT(lrint(F(3.3)), 3); \ + TEST_INT(lrint(F(3.6)), 4); \ + TEST_INT(lrint(F(3.5)), 4); \ + TEST_INT(lrint(F(4.5)), 4); \ + TEST_INT(lrint(F(-3.3)), -3); \ + TEST_INT(lrint(F(-3.6)), -4); \ + TEST_INT(lrint(F(-3.5)), -4); \ + TEST_INT(lrint(F(-4.5)), -4) + + TEST_LRINT_NEAREST(llrint); + TEST_LRINT_NEAREST(llrintf); + TEST_LRINT_NEAREST(llrintl); + TEST_LRINT_NEAREST(lrint); + TEST_LRINT_NEAREST(lrintf); + TEST_LRINT_NEAREST(lrintl); + +#define TEST_RINT_NEAREST(rint) \ + TEST_FLT(rint(F(3.3)), 3.0); \ + TEST_FLT(rint(F(3.6)), 4.0); \ + TEST_FLT(rint(F(3.5)), 4.0); \ + TEST_FLT(rint(F(4.5)), 4.0); \ + TEST_FLT_NAN(rint(F(NAN)), F(NAN)); \ + TEST_FLT(rint(F(-3.3)), -3.0); \ + TEST_FLT(rint(F(-3.6)), -4.0); \ + TEST_FLT(rint(F(-3.5)), -4.0); \ + TEST_FLT(rint(F(-4.5)), -4.0); \ + TEST_FLT_NAN(rint(-F(NAN)), -F(NAN)) + + TEST_RINT_NEAREST(rint); + TEST_RINT_NEAREST(rintf); + TEST_RINT_NEAREST(rintl); + TEST_RINT_NEAREST(nearbyint); + TEST_RINT_NEAREST(nearbyintf); + TEST_RINT_NEAREST(nearbyintl); + } + + fesetround(FE_TOWARDZERO); + context = "FE_TOWARDZERO "; + +#define TEST_LRINT_TOWARDZERO(lrint) \ + TEST_INT(lrint(F(3.3)), 3); \ + TEST_INT(lrint(F(3.6)), 3); \ + TEST_INT(lrint(F(-3.3)), -3); \ + TEST_INT(lrint(F(-3.6)), -3) + + TEST_LRINT_TOWARDZERO(llrint); + TEST_LRINT_TOWARDZERO(llrintf); + TEST_LRINT_TOWARDZERO(llrintl); + TEST_LRINT_TOWARDZERO(lrint); + TEST_LRINT_TOWARDZERO(lrintf); + TEST_LRINT_TOWARDZERO(lrintl); + +#define TEST_RINT_TOWARDZERO(rint) \ + TEST_FLT(rint(F(3.3)), 3.0); \ + TEST_FLT(rint(F(3.6)), 3.0); \ + TEST_FLT(rint(F(-3.3)), -3.0); \ + TEST_FLT(rint(F(-3.6)), -3.0) + + TEST_RINT_TOWARDZERO(rint); + TEST_RINT_TOWARDZERO(rintf); + TEST_RINT_TOWARDZERO(rintl); + TEST_RINT_TOWARDZERO(nearbyint); + TEST_RINT_TOWARDZERO(nearbyintf); + TEST_RINT_TOWARDZERO(nearbyintl); + + fesetround(FE_DOWNWARD); + context = "FE_DOWNWARD "; + +#define TEST_LRINT_DOWNWARD(lrint) \ + TEST_INT(lrint(F(3.3)), 3); \ + TEST_INT(lrint(F(3.6)), 3); \ + TEST_INT(lrint(F(-3.3)), -4); \ + TEST_INT(lrint(F(-3.6)), -4) + + TEST_LRINT_DOWNWARD(llrint); + TEST_LRINT_DOWNWARD(llrintf); + TEST_LRINT_DOWNWARD(llrintl); + TEST_LRINT_DOWNWARD(lrint); + TEST_LRINT_DOWNWARD(lrintf); + TEST_LRINT_DOWNWARD(lrintl); + +#define TEST_RINT_DOWNWARD(rint) \ + TEST_FLT(rint(F(3.3)), 3.0); \ + TEST_FLT(rint(F(3.6)), 3.0); \ + TEST_FLT(rint(F(-3.3)), -4.0); \ + TEST_FLT(rint(F(-3.6)), -4.0) + + TEST_RINT_DOWNWARD(rint); + TEST_RINT_DOWNWARD(rintf); + TEST_RINT_DOWNWARD(rintl); + TEST_RINT_DOWNWARD(nearbyint); + TEST_RINT_DOWNWARD(nearbyintf); + TEST_RINT_DOWNWARD(nearbyintl); + + fesetround(FE_UPWARD); + context = "FE_UPWARD "; + +#define TEST_LRINT_UPWARD(lrint) \ + TEST_INT(lrint(F(3.3)), 4); \ + TEST_INT(lrint(F(3.6)), 4); \ + TEST_INT(lrint(F(-3.3)), -3); \ + TEST_INT(lrint(F(-3.6)), -3) + + TEST_LRINT_UPWARD(llrint); + TEST_LRINT_UPWARD(llrintf); + TEST_LRINT_UPWARD(llrintl); + TEST_LRINT_UPWARD(lrint); + TEST_LRINT_UPWARD(lrintf); + TEST_LRINT_UPWARD(lrintl); + +#define TEST_RINT_UPWARD(rint) \ + TEST_FLT(rint(F(3.3)), 4.0); \ + TEST_FLT(rint(F(3.6)), 4.0); \ + TEST_FLT(rint(F(-3.3)), -3.0); \ + TEST_FLT(rint(F(-3.6)), -3.0) + + TEST_RINT_UPWARD(rint); + TEST_RINT_UPWARD(rintf); + TEST_RINT_UPWARD(rintl); + TEST_RINT_UPWARD(nearbyint); + TEST_RINT_UPWARD(nearbyintf); + TEST_RINT_UPWARD(nearbyintl); + + context = ""; + fesetround(FE_TONEAREST); + +#define TEST_LOG(log, HUGE_VAL) \ + TEST_FLT_ACCURACY(log(F(1.0)), 0.0, 0.001); \ + TEST_FLT_ACCURACY(log(F(2.7182818)), 1.0, 0.001); \ + TEST_FLT_ACCURACY(log(F(7.3890561)), 2.0, 0.001); \ + TEST_FLT_ACCURACY(log(F(0.3678794)), -1.0, 0.001); \ + TEST_FLT(log(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN(log(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(log(-F(NAN)), -F(NAN)); \ + TEST_FLT(log(F(0)), -HUGE_VAL); \ + TEST_FLT_NAN_ANY(log(F(-1.0))); \ + TEST_FLT_NAN_ANY(log(F(-INFINITY))) + + TEST_LOG(log, HUGE_VAL); + TEST_LOG(logf, HUGE_VALF); + TEST_LOG(logl, HUGE_VALL); + +#define TEST_LOG2(log2, HUGE_VAL) \ + TEST_FLT_ACCURACY(log2(F(1.0)), 0.0, 0.001); \ + TEST_FLT_ACCURACY(log2(F(8.0)), 3.0, 0.001); \ + TEST_FLT_ACCURACY(log2(F(1024.0)), 10.0, 0.001); \ + TEST_FLT_ACCURACY(log2(F(1048576.0)), 20.0, 0.001); \ + TEST_FLT_ACCURACY(log2(F(4294967296.0)), 32.0, 0.001); \ + TEST_FLT_ACCURACY(log2(F(9.7656e-04)), -10, 0.001); \ + TEST_FLT_ACCURACY(log2(F(9.5367e-07)), -20, 0.001); \ + TEST_FLT_ACCURACY(log2(F(3.5527e-15)), -48, 0.001); \ + TEST_FLT_ACCURACY(log2(F(7.8886e-31)), -100, 0.001); \ + TEST_FLT_ACCURACY(log2(F(7.3468e-40)), -130, 0.001); \ + TEST_FLT_ACCURACY(log2(F(1.225000)), 0.292782, 0.001); /* This, with log2f, crashes the mingw-w64 softfloat implementation */ \ + TEST_FLT(log2(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN(log2(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(log2(-F(NAN)), -F(NAN)); \ + TEST_FLT(log2(F(0)), -HUGE_VAL); \ + TEST_FLT_NAN_ANY(log2(F(-1.0))); \ + TEST_FLT_NAN_ANY(log2(F(-INFINITY))) + + TEST_LOG2(log2, HUGE_VAL); + TEST_LOG2(log2f, HUGE_VALF); + TEST_LOG2(log2l, HUGE_VALL); + +#if !defined(__MINGW32__) || !defined(__arm__) + // In Wine on arm, the strtod() in the F() macro returns 0 instead of + // the actual denormal value. + TEST_FLT_ACCURACY(log2(F(9.8813e-324)), -1073, 0.001); +#endif + TEST_FLT_ACCURACY(log2f(F(7.1746e-43)), -140, 0.001); + TEST_FLT_ACCURACY(log2l(F(7.1746e-43)), -140, 0.001); + +#define TEST_LOG10(log10, HUGE_VAL) \ + TEST_FLT_ACCURACY(log10(F(1.0)), 0.0, 0.001); \ + TEST_FLT_ACCURACY(log10(F(10.0)), 1.0, 0.001); \ + TEST_FLT_ACCURACY(log10(F(100.0)), 2.0, 0.001); \ + TEST_FLT_ACCURACY(log10(F(0.1)), -1.0, 0.001); \ + TEST_FLT(log10(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN(log10(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(log10(-F(NAN)), -F(NAN)); \ + TEST_FLT(log10(F(0)), -HUGE_VAL); \ + TEST_FLT_NAN_ANY(log10(F(-1.0))); \ + TEST_FLT_NAN_ANY(log10(F(-INFINITY))) + + TEST_LOG10(log10, HUGE_VAL); + TEST_LOG10(log10f, HUGE_VALF); + TEST_LOG10(log10l, HUGE_VALL); + +#define TEST_LOG1P(log1p, HUGE_VAL) \ + TEST_FLT_ACCURACY(log1p(F(0.0)), 0.0, 0.001); \ + TEST_FLT_ACCURACY(log1p(F(1.718282)), 1.0, 0.001); \ + TEST_FLT_ACCURACY(log1p(F(-0.632120)), -1.0, 0.001); \ + TEST_FLT(log1p(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN(log1p(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(log1p(-F(NAN)), -F(NAN)); \ + TEST_FLT(log1p(F(-1.0)), -HUGE_VAL); \ + TEST_FLT_NAN_ANY(log1p(F(-2.0))); \ + TEST_FLT_NAN_ANY(log1p(F(-INFINITY))) + + TEST_LOG1P(log1p, HUGE_VAL); + TEST_LOG1P(log1pf, HUGE_VALF); + TEST_LOG1P(log1pl, HUGE_VALL); + +#define TEST_EXP(exp) \ + TEST_FLT_ACCURACY(exp(F(0.0)), 1.0, 0.001); \ + TEST_FLT_ACCURACY(exp(F(1.0)), 2.7182818, 0.001); \ + TEST_FLT_ACCURACY(exp(F(2.0)), 7.3890561, 0.001); \ + TEST_FLT_ACCURACY(exp(F(-1.0)), 0.3678794, 0.001); \ + TEST_FLT(exp(F(INFINITY)), INFINITY); \ + TEST_FLT(exp(F(-INFINITY)), 0); \ + TEST_FLT_NAN(exp(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(exp(-F(NAN)), -F(NAN)) + + TEST_EXP(exp); + TEST_EXP(expf); + TEST_EXP(expl); + +#define TEST_EXP2(exp2) \ + TEST_FLT_ACCURACY(exp2(F(0.0)), 1.0, 0.001); \ + TEST_FLT_ACCURACY(exp2(F(3.0)), 8.0, 0.001); \ + TEST_FLT_ACCURACY(exp2(F(10.0)), 1024.0, 0.001); \ + TEST_FLT_ACCURACY(exp2(F(20.0)), 1048576.0, 0.001); \ + TEST_FLT_ACCURACY(exp2(F(32.0)), 4294967296.0, 0.001); \ + TEST_FLT_ACCURACY(exp2(F(-2.0)), 0.25, 0.001); \ + TEST_FLT(exp2(F(INFINITY)), INFINITY); \ + TEST_FLT(exp2(F(-INFINITY)), 0); \ + TEST_FLT_NAN(exp2(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(exp2(-F(NAN)), -F(NAN)) + + TEST_EXP2(exp2); + TEST_EXP2(exp2f); + TEST_EXP2(exp2l); + +#define TEST_EXPM1(expm1) \ + TEST_FLT_ACCURACY(expm1(F(0.0)), 0.0, 0.001); \ + TEST_FLT_ACCURACY(expm1(F(1.0)), 1.718282, 0.001); \ + TEST_FLT_ACCURACY(expm1(F(-1.0)), -0.632120, 0.001); \ + TEST_FLT(expm1(F(INFINITY)), INFINITY); \ + TEST_FLT(expm1(F(-INFINITY)), -1.0); \ + TEST_FLT_NAN(expm1(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(expm1(-F(NAN)), -F(NAN)) + + TEST_EXPM1(expm1); + TEST_EXPM1(expm1f); + TEST_EXPM1(expm1l); + +#define TEST_LDEXP(ldexp) \ + TEST_FLT_ACCURACY(ldexp(F(0.0), 1), 0.0, 0.001); \ + TEST_FLT_ACCURACY(ldexp(F(2.0), 2), 8.0, 0.001); \ + TEST_FLT_ACCURACY(ldexp(F(2.0), -2), 0.5, 0.001); \ + TEST_FLT(ldexp(F(INFINITY), -42), INFINITY); \ + TEST_FLT(ldexp(F(-INFINITY), 42), -INFINITY); \ + TEST_FLT_NAN(ldexp(F(NAN), 42), F(NAN)); \ + TEST_FLT_NAN(ldexp(-F(NAN), 42), -F(NAN)) + + TEST_LDEXP(ldexp); + TEST_LDEXP(ldexpf); + TEST_LDEXP(ldexpl); + +#define TEST_SCALBN(scalbn) \ + TEST_FLT_ACCURACY(scalbn(F(0.0), 1), 0.0, 0.001); \ + TEST_FLT_ACCURACY(scalbn(F(2.0), 2), 8.0, 0.001); \ + TEST_FLT_ACCURACY(scalbn(F(2.0), -2), 0.5, 0.001); \ + TEST_FLT(scalbn(F(INFINITY), -42), INFINITY); \ + TEST_FLT(scalbn(F(-INFINITY), 42), -INFINITY); \ + TEST_FLT_NAN(scalbn(F(NAN), 42), F(NAN)); \ + TEST_FLT_NAN(scalbn(-F(NAN), 42), -F(NAN)) + + TEST_SCALBN(scalbn); + TEST_SCALBN(scalbnf); + TEST_SCALBN(scalbnf); + TEST_SCALBN(scalbln); + TEST_SCALBN(scalblnf); + TEST_SCALBN(scalblnf); + + int iret; +#define TEST_FREXP(frexp) \ + TEST_FLT(frexp(F(INFINITY), &iret), INFINITY); \ + TEST_FLT(frexp(F(-INFINITY), &iret), -INFINITY); \ + TEST_FLT_NAN(frexp(F(NAN), &iret), F(NAN)); \ + TEST_FLT_NAN(frexp(-F(NAN), &iret), -F(NAN)); \ + TEST_FLT(frexp(F(0x1.4p+42), &iret), 0.625); \ + TEST_INT(iret, 43) + + TEST_FREXP(frexp); + TEST_FREXP(frexpf); + TEST_FREXP(frexpl); + +#define TEST_ILOGB(ilogb) \ + TEST_INT(ilogb(F(1.0)), 0); \ + TEST_INT(ilogb(F(0.25)), -2); \ + TEST_INT(ilogb(F(-0.25)), -2); \ + TEST_INT(ilogb(F(0.0)), FP_ILOGB0); \ + TEST_INT(ilogb(F(INFINITY)), INT_MAX); \ + TEST_INT(ilogb(F(-INFINITY)), INT_MAX); \ + TEST_INT(ilogb(F(NAN)), FP_ILOGBNAN); \ + TEST_INT(ilogb(-F(NAN)), FP_ILOGBNAN) + + TEST_ILOGB(ilogb); + TEST_ILOGB(ilogbf); + TEST_ILOGB(ilogbl); + + TEST_INT(ilogb(3.49514e-308), -1022); + TEST_INT(ilogb(1.74757e-308), -1023); + TEST_INT(ilogb(9.8813e-324), -1073); + + TEST_INT(ilogbf(F(3.69292e-38)), -125); + TEST_INT(ilogbf(F(4.61616e-39)), -128); + TEST_INT(ilogbf(F(1.4013e-45)), -149); + + TEST_INT(ilogbl(3.49514e-308), -1022); + TEST_INT(ilogbl(1.74757e-308), -1023); + TEST_INT(ilogbl(9.8813e-324), -1073); + +#define TEST_LOGB(logb) \ + TEST_FLT(logb(F(1.0)), 0.0); \ + TEST_FLT(logb(F(0.25)), -2.0); \ + TEST_FLT(logb(F(-0.25)), -2.0); \ + TEST_FLT(logb(F(0.0)), -INFINITY); \ + TEST_FLT(logb(F(INFINITY)), INFINITY); \ + TEST_FLT(logb(F(-INFINITY)), INFINITY); \ + TEST_FLT_NAN(logb(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(logb(-F(NAN)), -F(NAN)) + + TEST_LOGB(logb); + TEST_LOGB(logbf); + TEST_LOGB(logbl); + + TEST_FLT(logb(3.49514e-308), -1022.0); + TEST_FLT(logb(1.74757e-308), -1023.0); + TEST_FLT(logb(9.8813e-324), -1073.0); + TEST_FLT(logbf(F(3.69292e-38)), -125.0); + TEST_FLT(logbf(F(4.61616e-39)), -128.0); + TEST_FLT(logbf(F(1.4013e-45)), -149.0); + TEST_FLT(logbl(3.49514e-308), -1022.0); + TEST_FLT(logbl(1.74757e-308), -1023.0); + TEST_FLT(logbl(9.8813e-324), -1073.0); + +#define TEST_LROUND(lround) \ + TEST_INT(lround(F(3.3)), 3); \ + TEST_INT(lround(F(3.6)), 4); \ + TEST_INT(lround(F(3.5)), 4); \ + TEST_INT(lround(F(4.5)), 5); \ + TEST_INT(lround(F(-3.3)), -3); \ + TEST_INT(lround(F(-3.6)), -4); \ + TEST_INT(lround(F(-3.5)), -4); \ + TEST_INT(lround(F(-4.5)), -5) + + TEST_LROUND(llround); + TEST_LROUND(llroundf); + TEST_LROUND(llroundl); + TEST_LROUND(lround); + TEST_LROUND(lroundf); + TEST_LROUND(lroundl); + +#define TEST_ROUND(round) \ + TEST_FLT(round(F(3.3)), 3.0); \ + TEST_FLT(round(F(3.6)), 4.0); \ + TEST_FLT(round(F(3.5)), 4.0); \ + TEST_FLT(round(F(4.5)), 5.0); \ + TEST_FLT(round(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN(round(F(NAN)), F(NAN)); \ + TEST_FLT(round(F(-3.3)), -3.0); \ + TEST_FLT(round(F(-3.6)), -4.0); \ + TEST_FLT(round(F(-3.5)), -4.0); \ + TEST_FLT(round(F(-4.5)), -5.0); \ + TEST_FLT(round(F(-INFINITY)), -INFINITY); \ + TEST_FLT_NAN(round(-F(NAN)), -F(NAN)) + + TEST_ROUND(round); + TEST_ROUND(roundf); + TEST_ROUND(roundl); + +#define TEST_POW(pow) \ + TEST_FLT(pow(F(2.0), F(0.0)), 1.0); \ + TEST_FLT(pow(F(2.0), F(0.0)), 1.0); \ + TEST_FLT(pow(F(10.0), F(0.0)), 1.0); \ + TEST_FLT(pow(F(10.0), F(1.0)), 10.0); \ + TEST_FLT_ACCURACY(pow(F(10.0), F(0.5)), 3.162278, 0.01); \ + TEST_FLT_NAN_ANY(pow(F(-1.0), F(1.5))); \ + TEST_FLT_SIGN(pow(F(0.0), F(3.0)), 0.0); \ + TEST_FLT_SIGN(pow(F(-0.0), F(3.0)), -0.0); \ + TEST_FLT_SIGN(pow(F(0.0), F(4.2)), 0.0); \ + TEST_FLT_SIGN(pow(F(-0.0), F(4.2)), 0.0); \ + TEST_FLT_SIGN(pow(F(INFINITY), F(-0.5)), 0.0); \ + TEST_FLT(pow(F(INFINITY), F(0.5)), INFINITY); \ + TEST_FLT_SIGN(pow(F(-INFINITY), F(-3)), -0.0); \ + TEST_FLT_SIGN(pow(F(-INFINITY), F(-0.5)), 0.0); \ + TEST_FLT(pow(F(-INFINITY), F(3.0)), -INFINITY); \ + TEST_FLT(pow(F(-INFINITY), F(2.5)), INFINITY); \ + TEST_FLT(pow(F(2.0), F(INFINITY)), INFINITY); \ + TEST_FLT(pow(F(1.0), F(INFINITY)), 1.0); \ + TEST_FLT_SIGN(pow(F(0.5), F(INFINITY)), 0.0); \ + TEST_FLT_SIGN(pow(F(2.0), F(-INFINITY)), 0.0); \ + TEST_FLT(pow(F(1.0), F(-INFINITY)), 1.0); \ + TEST_FLT(pow(F(0.5), F(-INFINITY)), INFINITY); \ + TEST_FLT(pow(F(-2.0), F(INFINITY)), INFINITY); \ + TEST_FLT(pow(F(-1.0), F(INFINITY)), 1.0); \ + TEST_FLT_SIGN(pow(F(-0.5), F(INFINITY)), 0.0); \ + TEST_FLT_SIGN(pow(F(-2.0), F(-INFINITY)), 0.0); \ + TEST_FLT(pow(F(-1.0), F(-INFINITY)), 1.0); \ + TEST_FLT(pow(F(-0.5), F(-INFINITY)), INFINITY); \ + TEST_FLT_NAN(pow(F(NAN), F(2.0)), F(NAN)); \ + TEST_FLT_NAN(pow(-F(NAN), F(2.0)), -F(NAN)); \ + TEST_FLT_NAN(pow(F(2.0), F(NAN)), F(NAN)); \ + TEST_FLT_NAN(pow(F(2.0), -F(NAN)), -F(NAN)); \ + TEST_FLT(pow(F(1.0), F(NAN)), 1.0); \ + TEST_FLT(pow(F(1.0), F(INFINITY)), 1.0); \ + TEST_FLT(pow(F(1.0), F(-INFINITY)), 1.0); \ + TEST_FLT(pow(F(NAN), F(0.0)), 1.0); \ + TEST_FLT(pow(F(INFINITY), F(0.0)), 1.0); \ + TEST_FLT(pow(F(-INFINITY), F(0.0)), 1.0) + + TEST_POW(pow); + TEST_POW(powf); + TEST_POW(powl); + +#define TEST_COS(cos) \ + TEST_FLT_ACCURACY(cos(F(0.0)), 1.0, 0.01); \ + TEST_FLT_ACCURACY(cos(F(3.141592654)/2), 0.0, 0.01); \ + TEST_FLT_ACCURACY(cos(F(3.141592654)), -1.0, 0.01); \ + TEST_FLT_ACCURACY(cos(3*F(3.141592654)/2), 0.0, 0.01); \ + TEST_FLT_ACCURACY(cos(2*F(3.141592654)), 1.0, 0.01); \ + TEST_FLT_NAN_ANY(cos(F(INFINITY))); \ + TEST_FLT_NAN_ANY(cos(F(-INFINITY))); \ + TEST_FLT_NAN(cos(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(cos(-F(NAN)), -F(NAN)) + + TEST_COS(cos); + TEST_COS(cosf); + TEST_COS(cosl); + +#define TEST_SIN(sin) \ + TEST_FLT_ACCURACY(sin(F(0.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(sin(F(3.141592654)/2), 1.0, 0.01); \ + TEST_FLT_ACCURACY(sin(F(3.141592654)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(sin(3*F(3.141592654)/2), -1.0, 0.01); \ + TEST_FLT_ACCURACY(sin(2*F(3.141592654)), 0.0, 0.01); \ + TEST_FLT_NAN_ANY(sin(F(INFINITY))); \ + TEST_FLT_NAN_ANY(sin(F(-INFINITY))); \ + TEST_FLT_NAN(sin(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(sin(-F(NAN)), -F(NAN)) + + TEST_SIN(sin); + TEST_SIN(sinf); + TEST_SIN(sinl); + +#define TEST_TAN(tan) \ + TEST_FLT_ACCURACY(tan(F(0.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(tan(F(1.0)), 1.557408, 0.01); \ + TEST_FLT_ACCURACY(tan(F(3.141592654)/4), 1.0, 0.01); \ + TEST_FLT_ACCURACY(tan(3*F(3.141592654)/4), -1.0, 0.01); \ + TEST_FLT_ACCURACY(tan(5*F(3.141592654)/4), 1.0, 0.01); \ + TEST_FLT_ACCURACY(tan(7*F(3.141592654)/4), -1.0, 0.01); \ + TEST_FLT_NAN_ANY(tan(F(INFINITY))); \ + TEST_FLT_NAN_ANY(tan(F(-INFINITY))); \ + TEST_FLT_NAN(tan(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(tan(-F(NAN)), -F(NAN)) + + TEST_TAN(tan); + TEST_TAN(tanf); + TEST_TAN(tanl); + +#define TEST_ACOS(acos) \ + TEST_FLT_ACCURACY(acos(F(1.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(acos(F(0.0)), 3.141592654/2, 0.01); \ + TEST_FLT_ACCURACY(acos(F(-1.0)), 3.141592654, 0.01); \ + TEST_FLT_NAN_ANY(acos(F(1.1))); \ + TEST_FLT_NAN_ANY(acos(F(-1.1))); \ + TEST_FLT_NAN_ANY(acos(F(INFINITY))); \ + TEST_FLT_NAN_ANY(acos(F(-INFINITY))); \ + TEST_FLT_NAN(acos(F(NAN)), F(NAN)); \ + /* TEST_FLT_NAN(acos(-F(NAN)), -F(NAN)) - This fails on glibc/x86_64 for acosl */ + + TEST_ACOS(acos); + TEST_ACOS(acosf); + TEST_ACOS(acosl); + +#define TEST_ASIN(asin) \ + TEST_FLT_ACCURACY(asin(F(0.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(asin(F(1.0)), 3.141592654/2, 0.01); \ + TEST_FLT_ACCURACY(asin(F(-1.0)), -3.141592654/2, 0.01); \ + TEST_FLT_NAN_ANY(asin(F(1.1))); \ + TEST_FLT_NAN_ANY(asin(F(-1.1))); \ + TEST_FLT_NAN_ANY(asin(F(INFINITY))); \ + TEST_FLT_NAN_ANY(asin(F(-INFINITY))); \ + TEST_FLT_NAN(asin(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(asin(-F(NAN)), -F(NAN)) + + TEST_ASIN(asin); + TEST_ASIN(asinf); + TEST_ASIN(asinl); + +#define TEST_ATAN(atan) \ + TEST_FLT_ACCURACY(atan(F(0.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(atan(F(1.0)), 3.141592654/4, 0.01); \ + TEST_FLT_ACCURACY(atan(F(-1.0)), -3.141592654/4, 0.01); \ + TEST_FLT_ACCURACY(atan(F(INFINITY)), 3.141592654/2, 0.01); \ + TEST_FLT_ACCURACY(atan(F(-INFINITY)), -3.141592654/2, 0.01); \ + TEST_FLT_NAN(atan(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(atan(-F(NAN)), -F(NAN)) + + TEST_ATAN(atan); + TEST_ATAN(atanf); + TEST_ATAN(atanl); + +#define TEST_ATAN2(atan2) \ + TEST_FLT_ACCURACY(atan2(F(0.0), F(-1.0)), 3.141592654, 0.01); \ + TEST_FLT_SIGN(atan2(F(0.0), F(1.0)), 0.0); \ + TEST_FLT_SIGN(atan2(F(-0.0), F(1.0)), -0.0); \ + TEST_FLT_ACCURACY(atan2(F(-1.0), F(0.0)), -3.141592654/2, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(1.0), F(0.0)), 3.141592654/2, 0.01); \ + TEST_FLT_SIGN(atan2(F(0.0), F(0.0)), 0.0); \ + TEST_FLT_ACCURACY(atan2(F(0.0), F(-0.0)), 3.141592654, 0.01); \ + TEST_FLT_SIGN(atan2(F(-0.0), F(0.0)), -0.0); \ + TEST_FLT_ACCURACY(atan2(F(-0.0), F(-0.0)), -3.141592654, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(1.0), F(-INFINITY)), 3.141592654, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(-1.0), F(-INFINITY)), -3.141592654, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(1.0), F(INFINITY)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(INFINITY), F(1.0)), 3.141592654/2, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(-INFINITY), F(1.0)), -3.141592654/2, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(INFINITY), F(-INFINITY)), 3*3.141592654/4, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(-INFINITY), F(-INFINITY)), -3*3.141592654/4, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(INFINITY), F(INFINITY)), 3.141592654/4, 0.01); \ + TEST_FLT_ACCURACY(atan2(F(-INFINITY), F(INFINITY)), -3.141592654/4, 0.01); \ + TEST_FLT_NAN_ANY(atan2(F(NAN), F(1.0))); \ + TEST_FLT_NAN_ANY(atan2(F(1.0), F(NAN))) + + TEST_ATAN2(atan2); + TEST_ATAN2(atan2f); + TEST_ATAN2(atan2l); + +#if defined(__linux__) || defined(__MINGW32__) + double outSin = 42.0, outCos = 42.0; + float outSinf = 42.0, outCosf = 42.0; + long double outSinl = 42.0, outCosl = 42.0; +#define TEST_SINCOS(sincos, outSin, outCos) \ + sincos(F(0.0), &outSin, &outCos); \ + TEST_FLT_ACCURACY(outSin, 0.0, 0.01); \ + TEST_FLT_ACCURACY(outCos, 1.0, 0.01) + + TEST_SINCOS(sincos, outSin, outCos); + TEST_SINCOS(sincosf, outSinf, outCosf); + TEST_SINCOS(sincosl, outSinl, outCosl); +#endif + +#define TEST_ACOSH(acosh) \ + TEST_FLT_ACCURACY(acosh(F(1.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(acosh(F(2.0)), 1.316958, 0.01); \ + TEST_FLT_NAN_ANY(acosh(F(0.0))); \ + TEST_FLT_NAN_ANY(acosh(F(-4.0))); \ + TEST_FLT_NAN_ANY(acosh(F(-INFINITY))); \ + TEST_FLT(acosh(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN(acosh(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(acosh(-F(NAN)), -F(NAN)) + + TEST_ACOSH(acosh); + TEST_ACOSH(acoshf); + TEST_ACOSH(acoshl); + +#define TEST_ASINH(asinh) \ + TEST_FLT_ACCURACY(asinh(F(0.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(asinh(F(1.0)), 0.881374, 0.01); \ + TEST_FLT_ACCURACY(asinh(F(2.0)), 1.443636, 0.01); \ + TEST_FLT_ACCURACY(asinh(F(-1.0)), -0.881374, 0.01); \ + TEST_FLT_ACCURACY(asinh(F(-2.0)), -1.443636, 0.01); \ + TEST_FLT(asinh(F(INFINITY)), INFINITY); \ + TEST_FLT(asinh(F(-INFINITY)), -INFINITY); \ + TEST_FLT_NAN(asinh(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(asinh(-F(NAN)), -F(NAN)) + + TEST_ASINH(asinh); + TEST_ASINH(asinhf); + TEST_ASINH(asinhl); + +#define TEST_ATANH(atanh) \ + TEST_FLT_ACCURACY(atanh(F(0.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(atanh(F(0.5)), 0.549307, 0.01); \ + TEST_FLT_ACCURACY(atanh(F(-0.5)), -0.549307, 0.01); \ + TEST_FLT(atanh(F(1.0)), INFINITY); \ + TEST_FLT(atanh(F(-1.0)), -INFINITY); \ + TEST_FLT_NAN_ANY(atanh(F(2.0))); \ + TEST_FLT_NAN_ANY(atanh(F(-2.0))); \ + TEST_FLT_NAN(atanh(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(atanh(-F(NAN)), -F(NAN)) + + TEST_ATANH(atanh); + TEST_ATANH(atanhf); + TEST_ATANH(atanhl); + +#define TEST_COSH(cosh) \ + TEST_FLT_ACCURACY(cosh(F(0.0)), 1.0, 0.01); \ + TEST_FLT_ACCURACY(cosh(F(1.316958)), 2.0, 0.01); \ + TEST_FLT_ACCURACY(cosh(F(-1.316958)), 2.0, 0.01); \ + TEST_FLT(cosh(F(INFINITY)), INFINITY); \ + TEST_FLT(cosh(F(-INFINITY)), INFINITY); \ + TEST_FLT_NAN(cosh(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(cosh(-F(NAN)), -F(NAN)) + + TEST_COSH(cosh); + TEST_COSH(coshf); + TEST_COSH(coshl); + +#define TEST_SINH(sinh) \ + TEST_FLT_ACCURACY(sinh(F(0.0)), 0.0, 0.01); \ + TEST_FLT_ACCURACY(sinh(F(0.881374)), 1.0, 0.01); \ + TEST_FLT_ACCURACY(sinh(F(1.443636)), 2.0, 0.01); \ + TEST_FLT_ACCURACY(sinh(F(-0.881374)), -1.0, 0.01); \ + TEST_FLT_ACCURACY(sinh(F(-1.443636)), -2.0, 0.01); \ + TEST_FLT(sinh(F(INFINITY)), INFINITY); \ + TEST_FLT(sinh(F(-INFINITY)), -INFINITY); \ + TEST_FLT_NAN(sinh(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(sinh(-F(NAN)), -F(NAN)) + + TEST_SINH(sinh); + TEST_SINH(sinhf); + TEST_SINH(sinhl); + +#define TEST_TANH(tanh) \ + TEST_FLT(tanh(F(0.0)), 0.0); \ + TEST_FLT_ACCURACY(tanh(F(0.549307)), 0.5, 0.01); \ + TEST_FLT_ACCURACY(tanh(F(-0.549307)), -0.5, 0.01); \ + TEST_FLT(tanh(F(INFINITY)), 1.0); \ + TEST_FLT(tanh(F(-INFINITY)), -1.0); \ + TEST_FLT_NAN(tanh(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(tanh(-F(NAN)), -F(NAN)) + + TEST_TANH(tanh); + TEST_TANH(tanhf); + TEST_TANH(tanhl); + +#define TEST_FABS(fabs, double) \ + TEST_FLT_SIGN(fabs((double)F(0.0)), 0.0); \ + TEST_FLT_SIGN(fabs((double)F(-0.0)), 0.0); \ + TEST_FLT(fabs((double)F(3.125)), 3.125); \ + TEST_FLT(fabs((double)F(-3.125)), 3.125); \ + TEST_FLT(fabs((double)F(INFINITY)), INFINITY); \ + TEST_FLT(fabs((double)F(-INFINITY)), INFINITY); \ + TEST_FLT_NAN(fabs((double)F(NAN)), F(NAN)); \ + TEST_FLT_NAN(fabs((double)-F(NAN)), F(NAN)) + + TEST_FABS(fabs, double); + TEST_FABS(fabsf, float); + TEST_FABS(fabsl, long double); + +#define TEST_ERF(erf) \ + TEST_FLT(erf(F(0.0)), 0.0); \ + TEST_FLT_ACCURACY(erf(F(1.0)), 0.842701, 0.001); \ + TEST_FLT_ACCURACY(erf(F(-1.0)), -0.842701, 0.001); \ + TEST_FLT_ACCURACY(erf(F(2.0)), 0.995322, 0.001); \ + TEST_FLT_ACCURACY(erf(F(-2.0)), -0.995322, 0.001); \ + TEST_FLT(erf(F(INFINITY)), 1.0); \ + TEST_FLT(erf(F(-INFINITY)), -1.0); \ + TEST_FLT_NAN(erf(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(erf(-F(NAN)), -F(NAN)) + + TEST_ERF(erf); + TEST_ERF(erff); + TEST_ERF(erfl); + +#define TEST_ERFC(erfc) \ + TEST_FLT(erfc(F(0.0)), 1.0); \ + TEST_FLT_ACCURACY(erfc(F(1.0)), 0.157299, 0.001); \ + TEST_FLT_ACCURACY(erfc(F(-1.0)), 1.842701, 0.001); \ + TEST_FLT_ACCURACY(erfc(F(2.0)), 0.004678, 0.001); \ + TEST_FLT_ACCURACY(erfc(F(-2.0)), 1.995322, 0.001); \ + TEST_FLT(erfc(F(INFINITY)), 0.0); \ + TEST_FLT(erfc(F(-INFINITY)), 2.0); \ + TEST_FLT_NAN(erfc(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(erfc(-F(NAN)), -F(NAN)) + + TEST_ERFC(erfc); + TEST_ERFC(erfcf); + TEST_ERFC(erfcl); + +#define TEST_TGAMMA(tgamma, HUGE_VAL) \ + TEST_FLT(tgamma(F(0.0)), HUGE_VAL); \ + TEST_FLT(tgamma(F(-0.0)), -HUGE_VAL); \ + TEST_FLT_ACCURACY(tgamma(F(0.5)), 1.772454, 0.001); \ + TEST_FLT(tgamma(F(1.0)), 1.0); \ + TEST_FLT_ACCURACY(tgamma(F(1.5)), 0.886227, 0.001); \ + TEST_FLT(tgamma(F(2.0)), 1.0); \ + TEST_FLT_ACCURACY(tgamma(F(3.3)), 2.683437, 0.001); \ + TEST_FLT(tgamma(F(5.0)), 24.0); \ + TEST_FLT_ACCURACY(tgamma(F(-0.5)), -3.544908, 0.001); \ + TEST_FLT_NAN_ANY(tgamma(F(-1.0))); \ + TEST_FLT_ACCURACY(tgamma(F(-1.5)), 2.363272, 0.001); \ + TEST_FLT(tgamma(F(INFINITY)), INFINITY); \ + TEST_FLT_NAN_ANY(tgamma(F(-INFINITY))); \ + TEST_FLT_NAN(tgamma(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(tgamma(-F(NAN)), -F(NAN)) + + TEST_TGAMMA(tgamma, HUGE_VAL); + TEST_TGAMMA(tgammaf, HUGE_VALF); + TEST_TGAMMA(tgammal, HUGE_VALL); + +#ifdef _MSC_VER +#define TEST_SIGNGAM(x) do { } while (0) +#else +#define TEST_SIGNGAM(x) do { x; signgam = 42; } while (0) + signgam = 42; +#endif + +#define TEST_LGAMMA(lgamma, HUGE_VAL) \ + TEST_FLT(lgamma(F(0.0)), INFINITY); \ + TEST_FLT(lgamma(F(-0.0)), INFINITY); \ + TEST_FLT_ACCURACY(lgamma(F(0.5)), 0.572365, 0.001); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT(lgamma(F(1.0)), 0.0); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT_ACCURACY(lgamma(F(1.5)), -0.120782, 0.001); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT(lgamma(F(2.0)), 0.0); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT_ACCURACY(lgamma(F(3.3)), 0.987099, 0.001); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT_ACCURACY(lgamma(F(5.0)), 3.178054, 0.001); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT_ACCURACY(lgamma(F(-0.5)), 1.265512, 0.001); \ + TEST_SIGNGAM(TEST_INT(signgam, -1)); \ + TEST_FLT(lgamma(F(-1.0)), HUGE_VAL); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT_ACCURACY(lgamma(F(-1.5)), 0.860047, 0.001); \ + TEST_SIGNGAM(TEST_INT(signgam, 1)); \ + TEST_FLT(lgamma(F(INFINITY)), INFINITY); \ + TEST_FLT(lgamma(F(-INFINITY)), INFINITY); \ + TEST_FLT_NAN(lgamma(F(NAN)), F(NAN)); \ + TEST_FLT_NAN(lgamma(-F(NAN)), -F(NAN)) + + TEST_LGAMMA(lgamma, HUGE_VAL); + TEST_LGAMMA(lgammaf, HUGE_VALF); + TEST_LGAMMA(lgammal, HUGE_VALL); + + TEST_FLT_NAN_ANY(nan("foo")); + TEST_FLT_NAN_ANY(nanf("foo")); + TEST_FLT_NAN_ANY(nanl("foo")); + +#define TEST_NEXTAFTER(nextafter, DBL_MAX, DBL_EPSILON) \ + TEST_FLT(nextafter(F(1.0), F(2.0)), 1.0 + DBL_EPSILON); \ + TEST_FLT(nextafter(F(INFINITY), F(INFINITY)), INFINITY); \ + TEST_FLT(nextafter(F(INFINITY), F(-INFINITY)), DBL_MAX); \ + TEST_FLT(nextafter(F(-INFINITY), F(-INFINITY)), -INFINITY); \ + TEST_FLT(nextafter(F(-INFINITY), F(INFINITY)), -DBL_MAX); \ + TEST_FLT_NAN(nextafter(F(NAN), F(0.0)), F(NAN)); \ + TEST_FLT_NAN(nextafter(F(0.0), F(NAN)), F(NAN)); \ + TEST_FLT_NAN(nextafter(-F(NAN), F(0.0)), -F(NAN)); \ + TEST_FLT_NAN(nextafter(F(0.0), -F(NAN)), -F(NAN)) + + TEST_NEXTAFTER(nextafter, DBL_MAX, DBL_EPSILON); + TEST_NEXTAFTER(nextafterf, FLT_MAX, FLT_EPSILON); + TEST_NEXTAFTER(nextafterl, LDBL_MAX, LDBL_EPSILON); + TEST_NEXTAFTER(nexttoward, DBL_MAX, DBL_EPSILON); + TEST_NEXTAFTER(nexttowardf, FLT_MAX, FLT_EPSILON); + TEST_NEXTAFTER(nexttowardl, LDBL_MAX, LDBL_EPSILON); + +#define TEST_FDIM(fdim) \ + TEST_FLT(fdim(F(2.0), F(1.0)), 1.0); \ + TEST_FLT(fdim(F(1.0), F(2.0)), 0.0); \ + TEST_FLT(fdim(F(INFINITY), F(1.0)), INFINITY); \ + TEST_FLT(fdim(F(1.0), F(-INFINITY)), INFINITY); \ + TEST_FLT(fdim(F(-1.0), F(INFINITY)), 0.0); \ + TEST_FLT(fdim(F(-INFINITY), F(1.0)), 0.0); \ + TEST_FLT(fdim(F(-INFINITY), F(INFINITY)), 0.0); \ + TEST_FLT(fdim(F(INFINITY), F(-INFINITY)), INFINITY); \ + TEST_FLT_NAN(fdim(F(NAN), F(0.0)), F(NAN)); \ + TEST_FLT_NAN(fdim(F(0.0), F(NAN)), F(NAN)); \ + TEST_FLT_NAN(fdim(-F(NAN), F(0.0)), -F(NAN)); \ + TEST_FLT_NAN(fdim(F(0.0), -F(NAN)), -F(NAN)) + + TEST_FDIM(fdim); + TEST_FDIM(fdimf); + TEST_FDIM(fdiml); + +#define TEST_FMAX(fmax) \ + TEST_FLT(fmax(F(1.0), F(0.0)), 1.0); \ + TEST_FLT(fmax(F(0.0), F(1.0)), 1.0); \ + TEST_FLT(fmax(F(INFINITY), F(1.0)), INFINITY); \ + TEST_FLT(fmax(F(-INFINITY), F(1.0)), 1.0); \ + TEST_FLT(fmax(F(1.0), F(INFINITY)), INFINITY); \ + TEST_FLT(fmax(F(1.0), F(-INFINITY)), 1.0); \ + TEST_FLT(fmax(F(1.0), F(NAN)), 1.0); \ + TEST_FLT(fmax(F(NAN), F(1.0)), 1.0); \ + TEST_FLT_NAN_ANY(fmax(F(NAN), -F(NAN))) + + TEST_FMAX(fmax); + TEST_FMAX(fmaxf); + TEST_FMAX(fmaxl); + +#define TEST_FMIN(fmin) \ + TEST_FLT(fmin(F(1.0), F(0.0)), 0.0); \ + TEST_FLT(fmin(F(0.0), F(1.0)), 0.0); \ + TEST_FLT(fmin(F(0.0), F(-1.0)), -1.0); \ + TEST_FLT(fmin(F(-1.0), F(0.0)), -1.0); \ + TEST_FLT(fmin(F(INFINITY), F(1.0)), 1.0); \ + TEST_FLT(fmin(F(-INFINITY), F(1.0)), -INFINITY); \ + TEST_FLT(fmin(F(1.0), F(INFINITY)), 1.0); \ + TEST_FLT(fmin(F(1.0), F(-INFINITY)), -INFINITY); \ + TEST_FLT(fmin(F(1.0), F(NAN)), 1.0); \ + TEST_FLT(fmin(F(NAN), F(1.0)), 1.0); \ + TEST_FLT_NAN_ANY(fmin(F(NAN), -F(NAN))) + + TEST_FMIN(fmin); + TEST_FMIN(fminf); + TEST_FMIN(fminl); + + TEST_INT(isgreater(F(0.0), F(0.0)), 0); + TEST_INT(isgreater(F(1.0), F(0.0)), 1); + TEST_INT(isgreater(F(0.0), F(1.0)), 0); + TEST_INT(isgreater(F(INFINITY), F(0.0)), 1); + TEST_INT(isgreater(F(-INFINITY), F(0.0)), 0); + TEST_INT(isgreater(F(0.0), F(INFINITY)), 0); + TEST_INT(isgreater(F(0.0), F(-INFINITY)), 1); + TEST_INT(isgreater(F(0.0), F(NAN)), 0); + TEST_INT(isgreater(F(NAN), F(0.0)), 0); + TEST_INT(isgreater(F(NAN), F(NAN)), 0); + + TEST_INT(isgreaterequal(F(0.0), F(0.0)), 1); + TEST_INT(isgreaterequal(F(1.0), F(0.0)), 1); + TEST_INT(isgreaterequal(F(0.0), F(1.0)), 0); + TEST_INT(isgreaterequal(F(INFINITY), F(0.0)), 1); + TEST_INT(isgreaterequal(F(-INFINITY), F(0.0)), 0); + TEST_INT(isgreaterequal(F(0.0), F(INFINITY)), 0); + TEST_INT(isgreaterequal(F(0.0), F(-INFINITY)), 1); + TEST_INT(isgreaterequal(F(0.0), F(NAN)), 0); + TEST_INT(isgreaterequal(F(NAN), F(0.0)), 0); + TEST_INT(isgreaterequal(F(NAN), F(NAN)), 0); + + TEST_INT(isless(F(0.0), F(0.0)), 0); + TEST_INT(isless(F(1.0), F(0.0)), 0); + TEST_INT(isless(F(0.0), F(1.0)), 1); + TEST_INT(isless(F(INFINITY), F(0.0)), 0); + TEST_INT(isless(F(-INFINITY), F(0.0)), 1); + TEST_INT(isless(F(0.0), F(INFINITY)), 1); + TEST_INT(isless(F(0.0), F(-INFINITY)), 0); + TEST_INT(isless(F(0.0), F(NAN)), 0); + TEST_INT(isless(F(NAN), F(0.0)), 0); + TEST_INT(isless(F(NAN), F(NAN)), 0); + + TEST_INT(islessequal(F(0.0), F(0.0)), 1); + TEST_INT(islessequal(F(1.0), F(0.0)), 0); + TEST_INT(islessequal(F(0.0), F(1.0)), 1); + TEST_INT(islessequal(F(INFINITY), F(0.0)), 0); + TEST_INT(islessequal(F(-INFINITY), F(0.0)), 1); + TEST_INT(islessequal(F(0.0), F(INFINITY)), 1); + TEST_INT(islessequal(F(0.0), F(-INFINITY)), 0); + TEST_INT(islessequal(F(0.0), F(NAN)), 0); + TEST_INT(islessequal(F(NAN), F(0.0)), 0); + TEST_INT(islessequal(F(NAN), F(NAN)), 0); + + TEST_INT(islessgreater(F(0.0), F(0.0)), 0); + TEST_INT(islessgreater(F(1.0), F(0.0)), 1); + TEST_INT(islessgreater(F(0.0), F(1.0)), 1); + TEST_INT(islessgreater(F(INFINITY), F(0.0)), 1); + TEST_INT(islessgreater(F(-INFINITY), F(0.0)), 1); + TEST_INT(islessgreater(F(0.0), F(INFINITY)), 1); + TEST_INT(islessgreater(F(0.0), F(-INFINITY)), 1); + TEST_INT(islessgreater(F(0.0), F(NAN)), 0); + TEST_INT(islessgreater(F(NAN), F(0.0)), 0); + TEST_INT(islessgreater(F(NAN), F(NAN)), 0); + + TEST_INT(isunordered(F(0.0), F(0.0)), 0); + TEST_INT(isunordered(F(1.0), F(0.0)), 0); + TEST_INT(isunordered(F(0.0), F(1.0)), 0); + TEST_INT(isunordered(F(INFINITY), F(0.0)), 0); + TEST_INT(isunordered(F(-INFINITY), F(0.0)), 0); + TEST_INT(isunordered(F(0.0), F(INFINITY)), 0); + TEST_INT(isunordered(F(0.0), F(-INFINITY)), 0); + TEST_INT(isunordered(F(0.0), F(NAN)), 1); + TEST_INT(isunordered(F(NAN), F(0.0)), 1); + TEST_INT(isunordered(F(NAN), F(NAN)), 1); + +#define TEST_COPYSIGN(copysign) \ + TEST_FLT_ACCURACY(copysign(F(3.125), F(1)), 3.125, 0.0001); \ + TEST_FLT_ACCURACY(copysign(F(3.125), F(-1)), -3.125, 0.0001); \ + TEST_FLT_ACCURACY(copysign(F(-3.125), F(-1)), -3.125, 0.0001); \ + TEST_FLT_ACCURACY(copysign(F(-3.125), F(1)), 3.125, 0.0001); \ + TEST_FLT_ACCURACY(copysign(F(3.125), -F(NAN)), -3.125, 0.0001); \ + TEST_FLT(copysign(F(INFINITY), F(1)), INFINITY); \ + TEST_FLT(copysign(F(INFINITY), F(-1)), -INFINITY); \ + TEST_FLT(copysign(F(-INFINITY), F(-1)), -INFINITY); \ + TEST_FLT(copysign(F(-INFINITY), F(1)), INFINITY); \ + TEST_FLT_NAN(copysign(F(NAN), F(-1)), -F(NAN)); \ + TEST_FLT_NAN(copysign(-F(NAN), F(NAN)), F(NAN)) + + TEST_COPYSIGN(copysign); + TEST_COPYSIGN(copysignf); + TEST_COPYSIGN(copysignl); + +#ifdef _WIN32 + TEST_COPYSIGN(_copysign); + TEST_COPYSIGN(_copysignf); + TEST_COPYSIGN(_copysignl); + + TEST_FLT_ACCURACY(_chgsignl(F(3.125)), -3.125, 0.0001); + TEST_FLT_ACCURACY(_chgsignl(F(-3.125)), 3.125, 0.0001); + TEST_FLT(_chgsignl(F(INFINITY)), -INFINITY); + TEST_FLT(_chgsignl(F(-INFINITY)), INFINITY); + TEST_FLT_NAN(_chgsignl(F(NAN)), -F(NAN)); + TEST_FLT_NAN(_chgsignl(-F(NAN)), F(NAN)); +#endif + + TEST_INT(L(7) / L(7), 1); // __rt_sdiv + TEST_INT(L(-7) / L(7), -1); // __rt_sdiv + TEST_INT(L(-7) / L(-7), 1); // __rt_sdiv + TEST_INT(L(7) / L(-7), -1); // __rt_sdiv + TEST_INT(L(1073741824) / L(3), 357913941); // __rt_sdiv + TEST_INT(L(0) / L(3), 0); // __rt_sdiv + TEST_INT(L(0) / L(-3), 0); // __rt_sdiv + TEST_INT(L(1024) / L(357913941), 0); // __rt_sdiv + TEST_INT(L(1073741824) / L(357913941), 3); // __rt_sdiv + TEST_INT(L(2147483647) / L(1), 2147483647); // __rt_sdiv + TEST_INT(L(2147483647) / L(-1), -2147483647); // __rt_sdiv + TEST_INT(L(-2147483648) / L(1), (long) -2147483648LL); // __rt_sdiv + + TEST_INT(UL(7) / L(7), 1); // __rt_udiv + TEST_INT(UL(4294967289) / L(7), 613566755); // __rt_udiv + TEST_INT(UL(4294967289) / L(1), 4294967289UL); // __rt_udiv + TEST_INT(UL(1073741824) / L(3), 357913941); // __rt_udiv + TEST_INT(UL(0) / L(3), 0); // __rt_udiv + TEST_INT(UL(1024) / L(357913941), 0); // __rt_udiv + TEST_INT(UL(1073741824) / L(357913941), 3); // __rt_udiv + TEST_INT(UL(2147483647) / L(1), 2147483647); // __rt_udiv + + TEST_INT(LL(7) / 7, 1); // __rt_sdiv64 + TEST_INT(LL(-7) / 7, -1); // __rt_sdiv64 + TEST_INT(LL(-7) / -7, 1); // __rt_sdiv64 + TEST_INT(LL(7) / -7, -1); // __rt_sdiv64 + TEST_INT(LL(1073741824) / 3, 357913941); // __rt_sdiv64 + TEST_INT(LL(0) / 3, 0); // __rt_sdiv64 + TEST_INT(LL(0) / -3, 0); // __rt_sdiv64 + TEST_INT(LL(1024) / 357913941, 0); // __rt_sdiv64 + TEST_INT(LL(1073741824) / 357913941, 3); // __rt_sdiv64 + TEST_INT(LL(2147483647) / LL(1), 2147483647); // __rt_sdiv64 + TEST_INT(LL(2147483647) / LL(-1), -2147483647); // __rt_sdiv64 + TEST_INT(LL(-2147483648) / LL(1), -2147483648LL); // __rt_sdiv64 + TEST_INT(LL(0) / LL(2305843009213693952), 0); // __rt_sdiv64 + TEST_INT(LL(0) / LL(2305843009213693953), 0); // __rt_sdiv64 + TEST_INT(LL(0) / LL(2147483648), 0); // __rt_sdiv64 + TEST_INT(LL(0) / LL(4294967296), 0); // __rt_sdiv64 + TEST_INT(LL(4294967296) / LL(4294967296), 1); // __rt_sdiv64 + TEST_INT(LL(4294967295) / LL(4294967296), 0); // __rt_sdiv64 + + TEST_INT(ULL(7) / 7, 1); // __rt_udiv64 + TEST_INT(ULL(4294967289) / LL(7), 613566755); // __rt_udiv64 + TEST_INT(ULL(4294967289) / LL(1), 4294967289ULL); // __rt_udiv64 + TEST_INT(ULL(1073741824) / LL(3), 357913941); // __rt_udiv64 + TEST_INT(ULL(0) / LL(3), 0); // __rt_udiv64 + TEST_INT(ULL(1024) / LL(357913941), 0); // __rt_udiv64 + TEST_INT(ULL(1073741824) / LL(357913941), 3); // __rt_udiv64 + TEST_INT(ULL(2147483647) / LL(1), 2147483647); // __rt_udiv64 + TEST_INT(ULL(18446744073709551615) / LL(1), 18446744073709551615ULL); // __rt_udiv64 + TEST_INT(ULL(0) / ULL(2305843009213693952), 0); // __rt_udiv64 + TEST_INT(ULL(0) / ULL(2305843009213693953), 0); // __rt_udiv64 + TEST_INT(ULL(0) / ULL(2147483648), 0); // __rt_udiv64 + TEST_INT(ULL(0) / ULL(4294967296), 0); // __rt_udiv64 + TEST_INT(ULL(4294967296) / ULL(4294967296), 1); // __rt_udiv64 + TEST_INT(ULL(4294967297) / ULL(8589934593), 0); // __rt_udiv64 + + + TEST_INT(L(7) % L(7), 0); // __rt_sdiv + TEST_INT(L(-7) % L(7), 0); // __rt_sdiv + TEST_INT(L(-7) % L(-7), 0); // __rt_sdiv + TEST_INT(L(7) % L(-7), 0); // __rt_sdiv + TEST_INT(L(1073741824) % L(3), 1); // __rt_sdiv + TEST_INT(L(0) % L(3), 0); // __rt_sdiv + TEST_INT(L(0) % L(-3), 0); // __rt_sdiv + TEST_INT(L(1024) % L(357913941), 1024); // __rt_sdiv + TEST_INT(L(1073741824) % L(357913941), 1); // __rt_sdiv + TEST_INT(L(2147483647) % L(1), 0); // __rt_sdiv + TEST_INT(L(2147483647) % L(-1), 0); // __rt_sdiv + TEST_INT(L(-2147483648) % L(1), 0); // __rt_sdiv + + TEST_INT(UL(7) % L(7), 0); // __rt_udiv + TEST_INT(UL(4294967289) % L(7), 4); // __rt_udiv + TEST_INT(UL(4294967289) % L(1), 0); // __rt_udiv + TEST_INT(UL(1073741824) % L(3), 1); // __rt_udiv + TEST_INT(UL(0) % L(3), 0); // __rt_udiv + TEST_INT(UL(1024) % L(357913941), 1024); // __rt_udiv + TEST_INT(UL(1073741824) % L(357913941), 1); // __rt_udiv + TEST_INT(UL(2147483647) % L(1), 0); // __rt_udiv + + TEST_INT(LL(7) % 7, 0); // __rt_sdiv64 + TEST_INT(LL(-7) % 7, 0); // __rt_sdiv64 + TEST_INT(LL(-7) % -7, 0); // __rt_sdiv64 + TEST_INT(LL(7) % -7, 0); // __rt_sdiv64 + TEST_INT(LL(1073741824) % 3, 1); // __rt_sdiv64 + TEST_INT(LL(0) % 3, 0); // __rt_sdiv64 + TEST_INT(LL(0) % -3, 0); // __rt_sdiv64 + TEST_INT(LL(1024) % 357913941, 1024); // __rt_sdiv64 + TEST_INT(LL(1073741824) % 357913941, 1); // __rt_sdiv64 + TEST_INT(LL(2147483647) % LL(1), 0); // __rt_sdiv64 + TEST_INT(LL(2147483647) % LL(-1), 0); // __rt_sdiv64 + TEST_INT(LL(-2147483648) % LL(1), 0); // __rt_sdiv64 + TEST_INT(LL(0) % LL(2305843009213693952), 0); // __rt_sdiv64 + TEST_INT(LL(0) % LL(2305843009213693953), 0); // __rt_sdiv64 + TEST_INT(LL(0) % LL(2147483648), 0); // __rt_sdiv64 + TEST_INT(LL(0) % LL(4294967296), 0); // __rt_sdiv64 + TEST_INT(LL(4294967296) % LL(4294967296), 0); // __rt_sdiv64 + TEST_INT(LL(4294967295) % LL(4294967296), 4294967295LL); // __rt_sdiv64 + + TEST_INT(ULL(7) % 7, 0); // __rt_udiv64 + TEST_INT(ULL(4294967289) % LL(7), 4); // __rt_udiv64 + TEST_INT(ULL(4294967289) % LL(1), 0); // __rt_udiv64 + TEST_INT(ULL(1073741824) % LL(3), 1); // __rt_udiv64 + TEST_INT(ULL(0) % LL(3), 0); // __rt_udiv64 + TEST_INT(ULL(1024) % LL(357913941), 1024); // __rt_udiv64 + TEST_INT(ULL(1073741824) % LL(357913941), 1); // __rt_udiv64 + TEST_INT(ULL(2147483647) % LL(1), 0); // __rt_udiv64 + TEST_INT(ULL(18446744073709551615) % LL(1), 0); // __rt_udiv64 + TEST_INT(ULL(0) % ULL(2305843009213693952), 0); // __rt_udiv64 + TEST_INT(ULL(0) % ULL(2305843009213693953), 0); // __rt_udiv64 + TEST_INT(ULL(0) % ULL(2147483648), 0); // __rt_udiv64 + TEST_INT(ULL(0) % ULL(4294967296), 0); // __rt_udiv64 + TEST_INT(ULL(4294967296) % ULL(4294967296), 0); // __rt_udiv64 + TEST_INT(ULL(4294967297) % ULL(8589934593), 4294967297ULL); // __rt_udiv64 + + TEST_INT((unsigned long long)F(4.2), 4); + TEST_INT((signed long long)F(4.2), 4); + TEST_INT((unsigned long long)F(123456789012345678), 123456789012345680ULL); + TEST_INT((signed long long)F(123456789012345678), 123456789012345680ULL); + TEST_INT((signed long long)F(-123456789012345), -123456789012345LL); + + TEST_INT((unsigned long long)(float)F(4.2), 4); + TEST_INT((signed long long)(float)F(4.2), 4); + TEST_INT((unsigned long long)(float)F(274877906944), 274877906944ULL); + TEST_INT((signed long long)(float)F(274877906944), 274877906944ULL); + TEST_INT((signed long long)(float)F(-274877906944), -274877906944LL); + + TEST_FLT((double)LL(4), 4.0); + TEST_FLT((float)LL(4), 4.0); + TEST_FLT((double)LL(123456789012345), 123456789012345.0); + TEST_FLT((double)LL(-123456789012345), -123456789012345.0); + TEST_FLT((float)LL(274877906944), 274877906944.0); + TEST_FLT((float)LL(-274877906944), -274877906944.0); + + TEST_FLT((double)ULL(4), 4.0); + TEST_FLT((float)ULL(4), 4.0); + TEST_FLT((double)ULL(17293822569102704640), 17293822569102704640.0); + TEST_FLT((float)ULL(17293822569102704640), 17293822569102704640.0); + +#ifdef _WIN32 + long value = 0; + __int64 ret; + __int64 value64 = 0; + void *ptr = NULL; + void *ptr1 = &value; + void *ptr2 = &value64; + void *ret_ptr; +#define TEST_FUNC(expr, var, expected, expected_ret) do { \ + ret = expr; \ + TEST_INT(var, expected); \ + TEST_INT(ret, expected_ret); \ + var = expected; \ + } while (0) +#define TEST_FUNC_PTR(expr, var, expected, expected_ret) do { \ + ret_ptr = expr; \ + TEST_PTR(var, expected); \ + TEST_PTR(ret_ptr, expected_ret); \ + var = expected; \ + } while (0) + TEST_FUNC(InterlockedBitTestAndSet(&value, 0), value, 1, 0); + TEST_FUNC(InterlockedBitTestAndSet(&value, 2), value, 5, 0); + TEST_FUNC(InterlockedBitTestAndSet(&value, 2), value, 5, 1); + TEST_FUNC(InterlockedBitTestAndReset(&value, 2), value, 1, 1); + TEST_FUNC(InterlockedBitTestAndReset(&value, 2), value, 1, 0); + TEST_FUNC(InterlockedBitTestAndReset(&value, 0), value, 0, 1); +#ifdef _WIN64 + TEST_FUNC(InterlockedBitTestAndSet64(&value64, 0), value64, 1, 0); + TEST_FUNC(InterlockedBitTestAndSet64(&value64, 2), value64, 5, 0); + TEST_FUNC(InterlockedBitTestAndSet64(&value64, 2), value64, 5, 1); + TEST_FUNC(InterlockedBitTestAndSet64(&value64, 40), value64, 0x10000000005, 0); + TEST_FUNC(InterlockedBitTestAndReset64(&value64, 40), value64, 5, 1); + TEST_FUNC(InterlockedBitTestAndReset64(&value64, 2), value64, 1, 1); + TEST_FUNC(InterlockedBitTestAndReset64(&value64, 2), value64, 1, 0); + TEST_FUNC(InterlockedBitTestAndReset64(&value64, 0), value64, 0, 1); +#endif + TEST_FUNC(InterlockedIncrement(&value), value, 1, 1); + TEST_FUNC(InterlockedDecrement(&value), value, 0, 0); + TEST_FUNC(InterlockedAdd(&value, 7), value, 7, 7); + TEST_FUNC(InterlockedAdd(&value, -2), value, 5, 5); + TEST_FUNC(InterlockedAdd64(&value64, 7), value64, 7, 7); + TEST_FUNC(InterlockedAdd64(&value64, 0x10000000000), value64, 0x10000000007, 0x10000000007); + TEST_FUNC(InterlockedIncrement64(&value64), value64, 0x10000000008, 0x10000000008); + TEST_FUNC(InterlockedDecrement64(&value64), value64, 0x10000000007, 0x10000000007); + TEST_FUNC(InterlockedAdd64(&value64, -0x10000000002), value64, 5, 5); + // Exchange functions return the previous value + TEST_FUNC(InterlockedExchangeAdd(&value, 1), value, 6, 5); + TEST_FUNC(InterlockedExchange(&value, 2), value, 2, 6); + TEST_FUNC(InterlockedCompareExchange(&value, 7, 1), value, 2, 2); + TEST_FUNC(InterlockedCompareExchange(&value, 5, 2), value, 5, 2); + TEST_FUNC_PTR(InterlockedExchangePointer(&ptr, ptr1), ptr, ptr1, NULL); + TEST_FUNC_PTR(InterlockedExchangePointer(&ptr, ptr2), ptr, ptr2, ptr1); + TEST_FUNC_PTR(InterlockedCompareExchangePointer(&ptr, NULL, ptr1), ptr, ptr2, ptr2); + TEST_FUNC_PTR(InterlockedCompareExchangePointer(&ptr, NULL, ptr2), ptr, NULL, ptr2); + TEST_FUNC(InterlockedExchangeAdd64(&value64, 0x10000000000), value64, 0x10000000005, 5); + TEST_FUNC(InterlockedExchange64(&value64, 0x10000000000), value64, 0x10000000000, 0x10000000005); + TEST_FUNC(InterlockedCompareExchange64(&value64, 7, 1), value64, 0x10000000000, 0x10000000000); + TEST_FUNC(InterlockedCompareExchange64(&value64, 0x20000000005, 0x10000000000), value64, 0x20000000005, 0x10000000000); + // Logical operations returns the previous value + TEST_FUNC(InterlockedOr(&value, 2), value, 7, 5); + TEST_FUNC(InterlockedOr(&value, 2), value, 7, 7); + TEST_FUNC(InterlockedAnd(&value, 2), value, 2, 7); + TEST_FUNC(InterlockedAnd(&value, 2), value, 2, 2); + TEST_FUNC(InterlockedXor(&value, 2), value, 0, 2); + TEST_FUNC(InterlockedXor(&value, 2), value, 2, 0); + TEST_FUNC(InterlockedXor(&value, 2), value, 0, 2); + TEST_FUNC(InterlockedOr64(&value64, 2), value64, 0x20000000007, 0x20000000005); + TEST_FUNC(InterlockedOr64(&value64, 0x10000000000), value64, 0x30000000007, 0x20000000007); + TEST_FUNC(InterlockedAnd64(&value64, 0x20000000000), value64, 0x20000000000, 0x30000000007); + TEST_FUNC(InterlockedAnd64(&value64, 0x20000000000), value64, 0x20000000000, 0x20000000000); + TEST_FUNC(InterlockedXor64(&value64, 0x20000000000), value64, 0, 0x20000000000); + TEST_FUNC(InterlockedXor64(&value64, 0x20000000000), value64, 0x20000000000, 0); + TEST_FUNC(InterlockedXor64(&value64, 0x20000000000), value64, 0, 0x20000000000); + + unsigned long idx = 42; + // If no bit is set, idx is set to an undefined value. + TEST_INT(BitScanForward(&idx, UL(0)), 0); + TEST_FUNC(BitScanForward(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(BitScanForward(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(BitScanForward(&idx, UL(0x80000001)), idx, 0, 1); + TEST_INT(BitScanReverse(&idx, UL(0)), 0); + TEST_FUNC(BitScanReverse(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(BitScanReverse(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(BitScanReverse(&idx, UL(0x80000001)), idx, 31, 1); +#if !defined(_M_ARM) && !defined(__arm__) && !defined(__i386__) + // These seem to be unavailable on 32 bit arm even in MSVC. They're also missing + // on i386 mingw. + TEST_INT(BitScanForward64(&idx, UL(0)), 0); + TEST_FUNC(BitScanForward64(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(BitScanForward64(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(BitScanForward64(&idx, UL(0x80000001)), idx, 0, 1); + TEST_FUNC(BitScanForward64(&idx, ULL(0x8000000000000000)), idx, 63, 1); + TEST_INT(BitScanReverse64(&idx, UL(0)), 0); + TEST_FUNC(BitScanReverse64(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(BitScanReverse64(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(BitScanReverse64(&idx, UL(0x80000001)), idx, 31, 1); + TEST_FUNC(BitScanReverse64(&idx, ULL(0x8000000000000000)), idx, 63, 1); +#endif + + // Test intrinsics versions. Not all combinations are available. + TEST_FUNC(_interlockedbittestandset(&value, 0), value, 1, 0); + TEST_FUNC(_interlockedbittestandset(&value, 2), value, 5, 0); + TEST_FUNC(_interlockedbittestandset(&value, 2), value, 5, 1); + TEST_FUNC(_interlockedbittestandreset(&value, 2), value, 1, 1); + TEST_FUNC(_interlockedbittestandreset(&value, 2), value, 1, 0); + TEST_FUNC(_interlockedbittestandreset(&value, 0), value, 0, 1); + TEST_FUNC(_InterlockedIncrement(&value), value, 1, 1); + TEST_FUNC(_InterlockedDecrement(&value), value, 0, 0); +#ifdef _WIN64 + TEST_FUNC(_interlockedbittestandset64(&value64, 0), value64, 1, 0); + TEST_FUNC(_interlockedbittestandset64(&value64, 2), value64, 5, 0); + TEST_FUNC(_interlockedbittestandset64(&value64, 2), value64, 5, 1); + TEST_FUNC(_interlockedbittestandset64(&value64, 40), value64, 0x10000000005, 0); + TEST_FUNC(_interlockedbittestandset64(&value64, 41), value64, 0x30000000005, 0); + TEST_FUNC(_interlockedbittestandreset64(&value64, 40), value64, 0x20000000005, 1); + TEST_FUNC(_interlockedbittestandreset64(&value64, 2), value64, 0x20000000001, 1); + TEST_FUNC(_interlockedbittestandreset64(&value64, 2), value64, 0x20000000001, 0); + TEST_FUNC(_interlockedbittestandreset64(&value64, 0), value64, 0x20000000000, 1); + TEST_FUNC(_InterlockedIncrement64(&value64), value64, 0x20000000001, 0x20000000001); + TEST_FUNC(_InterlockedDecrement64(&value64), value64, 0x20000000000, 0x20000000000); + TEST_FUNC(_interlockedbittestandreset64(&value64, 41), value64, 0, 1); +#endif + TEST_FUNC(_InterlockedExchangeAdd(&value, 1), value, 1, 0); + TEST_FUNC(_InterlockedExchange(&value, 2), value, 2, 1); + TEST_FUNC(_InterlockedCompareExchange(&value, 7, 1), value, 2, 2); + TEST_FUNC(_InterlockedCompareExchange(&value, 0, 2), value, 0, 2); + TEST_FUNC_PTR(_InterlockedExchangePointer(&ptr, ptr1), ptr, ptr1, NULL); + TEST_FUNC_PTR(_InterlockedExchangePointer(&ptr, ptr2), ptr, ptr2, ptr1); + TEST_FUNC_PTR(_InterlockedCompareExchangePointer(&ptr, NULL, ptr1), ptr, ptr2, ptr2); + TEST_FUNC_PTR(_InterlockedCompareExchangePointer(&ptr, NULL, ptr2), ptr, NULL, ptr2); +#ifdef _WIN64 + TEST_FUNC(_InterlockedExchangeAdd64(&value64, 0x20000000000), value64, 0x20000000000, 0); + TEST_FUNC(_InterlockedExchange64(&value64, 0x10000000000), value64, 0x10000000000, 0x20000000000); + TEST_FUNC(_InterlockedCompareExchange64(&value64, 7, 1), value64, 0x10000000000, 0x10000000000); + TEST_FUNC(_InterlockedCompareExchange64(&value64, 0x20000000000, 0x10000000000), value64, 0x20000000000, 0x10000000000); +#endif + TEST_FUNC(_InterlockedOr(&value, 2), value, 2, 0); + TEST_FUNC(_InterlockedOr(&value, 5), value, 7, 2); + TEST_FUNC(_InterlockedAnd(&value, 2), value, 2, 7); + TEST_FUNC(_InterlockedAnd(&value, 2), value, 2, 2); + TEST_FUNC(_InterlockedXor(&value, 2), value, 0, 2); + TEST_FUNC(_InterlockedXor(&value, 2), value, 2, 0); + TEST_FUNC(_InterlockedXor(&value, 2), value, 0, 2); +#ifdef _WIN64 + TEST_FUNC(_InterlockedOr64(&value64, 0x10000000000), value64, 0x30000000000, 0x20000000000); + TEST_FUNC(_InterlockedAnd64(&value64, 0x10000000000), value64, 0x10000000000, 0x30000000000); + TEST_FUNC(_InterlockedXor64(&value64, 0x10000000000), value64, 0, 0x10000000000); + TEST_FUNC(_InterlockedXor64(&value64, 0x10000000000), value64, 0x10000000000, 0); + TEST_FUNC(_InterlockedXor64(&value64, 0x10000000000), value64, 0, 0x10000000000); +#endif + + TEST_INT(_BitScanForward(&idx, UL(0)), 0); + TEST_FUNC(_BitScanForward(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(_BitScanForward(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(_BitScanForward(&idx, UL(0x80000001)), idx, 0, 1); + TEST_INT(_BitScanReverse(&idx, UL(0)), 0); + TEST_FUNC(_BitScanReverse(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(_BitScanReverse(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(_BitScanReverse(&idx, UL(0x80000001)), idx, 31, 1); +#ifdef _WIN64 + TEST_INT(_BitScanForward64(&idx, UL(0)), 0); + TEST_FUNC(_BitScanForward64(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(_BitScanForward64(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(_BitScanForward64(&idx, UL(0x80000001)), idx, 0, 1); + TEST_FUNC(_BitScanForward64(&idx, ULL(0x8000000000000000)), idx, 63, 1); + TEST_INT(_BitScanReverse64(&idx, UL(0)), 0); + TEST_FUNC(_BitScanReverse64(&idx, UL(1)), idx, 0, 1); + TEST_FUNC(_BitScanReverse64(&idx, UL(0x80000000)), idx, 31, 1); + TEST_FUNC(_BitScanReverse64(&idx, UL(0x80000001)), idx, 31, 1); + TEST_FUNC(_BitScanReverse64(&idx, ULL(0x8000000000000000)), idx, 63, 1); +#endif +#endif + + printf("%d tests, %d failures\n", tests, fails); + return fails > 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/exception-locale.cpp b/source/tool/cross-build/llvm-mingw/scripts/test/exception-locale.cpp new file mode 100644 index 000000000..d9a0bea9f --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/exception-locale.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018 SquallATF + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +int main(int argc, char *argv[]) { + try { + std::locale loc("test"); + } catch (std::runtime_error& e) { + std::cerr << "Caught \"" << e.what() << "\"" << std::endl; + std::cerr << "Type " << typeid(e).name() << std::endl; + std::cerr << "Test succeeded." << std::endl; + } catch (...) { + std::cerr << "catch all" << std::endl; + } + + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/exception-reduced.cpp b/source/tool/cross-build/llvm-mingw/scripts/test/exception-reduced.cpp new file mode 100644 index 000000000..2d53b5db9 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/exception-reduced.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 Marc Aldorasi + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +typedef void (*func_ptr)(int); +struct h { + func_ptr z; +}; +struct c { + h* e; +}; +struct as { + as() { at = static_cast(operator new(sizeof(int))); } + ~as() { operator delete(at); } + int *at; +}; +void am(int) { + static as au; + as av; + throw 0; +} +int main(int argc, char* argv[]) { + h hh{am}; + c *u = new c{&hh}; + try { + u->e->z(0); + } catch (...) { + } + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/hello-cpp.cpp b/source/tool/cross-build/llvm-mingw/scripts/test/hello-cpp.cpp new file mode 100644 index 000000000..915cf5ca3 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/hello-cpp.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +class Hello { +public: + Hello() { + printf("Hello ctor\n"); + } + ~Hello() { + printf("Hello dtor\n"); + } +}; + +Hello global_h; + +__attribute__((constructor)) static void attr_ctor(void) { + printf("attr_ctor\n"); +} + +__attribute__((destructor)) static void attr_dtor(void) { + printf("attr_dtor\n"); +} + +int main(int argc, char* argv[]) { + std::cout<<"Hello world C++"< +#include + +class Hello { +public: + Hello() { + printf("Hello ctor\n"); + } + ~Hello() { + printf("Hello dtor\n"); + } +}; + +Hello global_h; + +class RecurseClass { +public: + RecurseClass(int v) : val(v) { + printf("ctor %d\n", val); + } + ~RecurseClass() { + printf("dtor %d\n", val); + } +private: + int val; +}; + +void recurse(int val) { + RecurseClass obj(val); + if (val == 0) { + throw std::exception(); + } + if (val == 5) { + try { + recurse(val - 1); + } catch (std::exception& e) { + printf("caught exception at %d\n", val); + } + } else { + recurse(val - 1); + } + printf("finishing function recurse %d\n", val); +} + +int main(int argc, char* argv[]) { + std::cout<<"Hello world C++"< +#include +#include + +#if defined(_MSC_VER) +static __declspec(thread) int tlsvar = 1; +#else +static __thread int tlsvar = 1; +#endif + +static unsigned __stdcall threadfunc(void* arg) { + int id = (int)arg; + printf("thread %d, tlsvar %p initially %d\n", id, &tlsvar, tlsvar); + tlsvar = id + 100; + for (int i = 0; i < 4; i++) { + printf("thread %d, tlsvar %p %d\n", id, &tlsvar, tlsvar); + tlsvar += 10; + Sleep(500); + } + return 0; +} + +int main(int argc, char* argv[]) { + HANDLE threads[3]; + + for (int i = 0; i < 3; i++) { + printf("mainthread, tlsvar %p %d\n", &tlsvar, tlsvar); + tlsvar += 10; + threads[i] = (HANDLE)_beginthreadex(NULL, 0, threadfunc, (void*)(intptr_t) (i + 1), 0, NULL); + Sleep(350); + } + for (int i = 0; i < 3; i++) { + WaitForSingleObject(threads[i], INFINITE); + CloseHandle(threads[i]); + } + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/hello.c b/source/tool/cross-build/llvm-mingw/scripts/test/hello.c new file mode 100644 index 000000000..1958ea9c5 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/hello.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define __USE_MINGW_ANSI_STDIO 1 +#include + +int main(int argc, char* argv[]) { + printf("hello world! %f\n", 42.0); + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/setjmp.c b/source/tool/cross-build/llvm-mingw/scripts/test/setjmp.c new file mode 100644 index 000000000..a4cf5ff8b --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/setjmp.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +jmp_buf jmp; + +int fibonacci(int val) { + char buf[100]; + if (val <= 1) { + longjmp(jmp, 1); + return val; + } + snprintf(buf, sizeof(buf), "fibonacci(%d)", val); + printf("%s\n", buf); + return fibonacci(val - 1) + fibonacci(val - 2); +} + +double check_d, check_cos; + +int main(int argc, char* argv[]) { + int val = 10, ret; + double val2 = 3.14; + if (argc > 1) + val = atoi(argv[1]); + if (argc > 2) + val2 = atof(argv[2]); + double d = sin(val2); + printf("d = %f\n", d); + printf("cos = %f\n", cos(val2)); + printf("size = %d, %p\n", (int) sizeof(jmp), jmp); + check_d = d; + check_cos = cos(val2); + if ((ret = setjmp(jmp)) != 0) { + printf("setjmp returned %d\n", ret); + printf("d = %f\n", d); + printf("cos = %f\n", cos(val2)); + if (d != check_d || cos(val2) != check_cos) { + printf("local variables were clobbered\n"); + return 1; + } + return 0; + } + printf("fibonacci(%d) = %d\n", val, fibonacci(val)); + return 1; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/stacksmash.c b/source/tool/cross-build/llvm-mingw/scripts/test/stacksmash.c new file mode 100644 index 000000000..019b1c370 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/stacksmash.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +__attribute__((noinline)) +void func(char *ptr, int idx) { + ptr[idx] = 0; +} + +int main(int argc, char *argv[]) { + char buf[10]; + if (argc > 1) { + fprintf(stderr, "smashing stack\n"); + fflush(stderr); + func(buf, 10); + } else { + func(buf, 9); + fprintf(stderr, "%s: A test tool for detecting stack smashing.\n" + "Run this with a command line argument to trigger an " + "error.\n", argv[0]); + } + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/tlstest-lib.cpp b/source/tool/cross-build/llvm-mingw/scripts/test/tlstest-lib.cpp new file mode 100644 index 000000000..9ba2dccc9 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/tlstest-lib.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +class Hello { +public: + Hello(const char* s) { + str = s; + thread = GetCurrentThreadId(); + fprintf(stderr, "%s ctor on thread %d\n", str, thread); + } + ~Hello() { + fprintf(stderr, "%s dtor from thread %d, now on %d\n", str, thread, (int) GetCurrentThreadId()); + } + const char* str; + int thread; +}; + +Hello lib_h("lib global"); +static thread_local Hello lib_tls_h("lib global tls"); + +static void lib_atexit(void) { + fprintf(stderr, "lib_atexit\n"); +} + +static class SetAtexit { +public: + SetAtexit() { + atexit(lib_atexit); + } +} sa; + +extern "C" void __declspec(dllexport) func(void) { + fprintf(stderr, "func\n"); + static thread_local Hello h2("lib local tls"); + fprintf(stderr, "func end, thread %d\n", lib_tls_h.thread); +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/tlstest-main.cpp b/source/tool/cross-build/llvm-mingw/scripts/test/tlstest-main.cpp new file mode 100644 index 000000000..5e5387361 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/tlstest-main.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +HANDLE event1, event2, event3; +void (*func)(void); + +DWORD fls_key = FLS_OUT_OF_INDEXES; + +class Hello { +public: + Hello(const char* s) { + str = s; + thread = GetCurrentThreadId(); + fprintf(stderr, "%s ctor on thread %d\n", str, thread); + } + ~Hello() { + fprintf(stderr, "%s dtor from thread %d, now on %d\n", str, thread, (int) GetCurrentThreadId()); + } + const char* str; + int thread; +}; + +unsigned __stdcall threadfunc(void *arg) { + HANDLE event = (HANDLE) arg; + int threadId = GetCurrentThreadId(); + fprintf(stderr, "threadfunc thread %d\n", threadId); + static thread_local Hello main_h("main local tls"); + SetEvent(event3); + WaitForSingleObject(event, INFINITE); + fprintf(stderr, "thread %d calling func\n", threadId); + if (func) + func(); + SetEvent(event3); + WaitForSingleObject(event, INFINITE); + + fprintf(stderr, "thread %d finishing\n", threadId); + return 0; +} + +static Hello main_h("main global"); + +static void atexit_func(void) { + fprintf(stderr, "main atexit_func\n"); +} + +int main(int argc, char* argv[]) { + atexit(atexit_func); + fprintf(stderr, "main\n"); + event1 = CreateEvent(NULL, FALSE, FALSE, NULL); + event2 = CreateEvent(NULL, FALSE, FALSE, NULL); + event3 = CreateEvent(NULL, FALSE, FALSE, NULL); + fprintf(stderr, "main, starting thread1\n"); + HANDLE thread1 = (HANDLE)_beginthreadex(NULL, 0, threadfunc, event1, 0, NULL); + WaitForSingleObject(event3, INFINITE); + fprintf(stderr, "main, thread1 started\n"); + fprintf(stderr, "LoadLibrary tlstest-lib.dll\n"); + HMODULE h = LoadLibrary("tlstest-lib.dll"); + fprintf(stderr, "LoadLibrary tlstest-lib.dll ret %p\n", h); + if (!h) { + fprintf(stderr, "Unable to load tlstest-lib.dll\n"); + return 1; + } + func = (void (*)(void)) GetProcAddress(h, "func"); + fprintf(stderr, "main, got func address, calling it\n"); + if (func) + func(); + + fprintf(stderr, "main, starting thread2\n"); + HANDLE thread2 = (HANDLE)_beginthreadex(NULL, 0, threadfunc, event2, 0, NULL); + WaitForSingleObject(event3, INFINITE); + fprintf(stderr, "main, thread2 started\n"); + + SetEvent(event1); + WaitForSingleObject(event3, INFINITE); + fprintf(stderr, "main, thread1 work done\n"); + + SetEvent(event2); + WaitForSingleObject(event3, INFINITE); + fprintf(stderr, "main, thread2 work done\n"); + + SetEvent(event1); + WaitForSingleObject(thread1, INFINITE); + fprintf(stderr, "main, thread1 joined\n"); + + fprintf(stderr, "FreeLibrary\n"); + FreeLibrary(h); + fprintf(stderr, "FreeLibrary done\n"); + + SetEvent(event2); + WaitForSingleObject(thread2, INFINITE); + fprintf(stderr, "main, thread2 joined\n"); + static thread_local Hello main_h("main local tls"); + atexit(atexit_func); + fprintf(stderr, "main done\n"); + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/ubsan.c b/source/tool/cross-build/llvm-mingw/scripts/test/ubsan.c new file mode 100644 index 000000000..4ad008a87 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/ubsan.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +int32_t var = INT32_MAX; + +int main(int argc, char *argv[]) { + char buf[10]; + if (argc > 1) { + fprintf(stderr, "triggering undefined behaviour\n"); + fflush(stderr); + var++; + } else { + var--; + fprintf(stderr, "%s: A test tool for undefined behaviour sanitizer. \n" + "Run this with a command line argument to trigger " + "undefined behaviour.\n", argv[0]); + } + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/test/uwp-error.c b/source/tool/cross-build/llvm-mingw/scripts/test/uwp-error.c new file mode 100644 index 000000000..364dd362c --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/test/uwp-error.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019 Steve Lhomme + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +int main(int argc, char *argv[]) { + UINT res = GetOEMCP(); + fprintf(stderr, "Windows OEM CP is %u\n", res); + return 0; +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/clang-target-wrapper.c b/source/tool/cross-build/llvm-mingw/scripts/wrappers/clang-target-wrapper.c new file mode 100644 index 000000000..ecb040f12 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/clang-target-wrapper.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "native-wrapper.h" + +#ifndef CLANG +#define CLANG "clang" +#endif +#ifndef DEFAULT_TARGET +#define DEFAULT_TARGET "x86_64-w64-mingw32" +#endif + +#ifdef _WIN32 +static int filter_line = 0, last_char = '\n'; +static void filter_stderr(char *buf, int n) { + // Filter the stderr output from "-v" to rewrite paths from backslash + // to forward slash form. libtool parses the output of "-v" and can't + // handle the backslash form of paths. A proper upstream solution has + // been discussed at https://reviews.llvm.org/D53066 but hasn't been + // finished yet. + int out = 0; + int last = last_char; + for (int i = 0; i < n; i++) { + TCHAR cur = buf[i]; + // All lines that contain command lines or paths currently start + // with a space. + if (last == '\n') { + filter_line = cur == ' '; +} + if (filter_line) { + if (cur == '"') { + // Do nothing; skip the quotes. This assumes that after + // converting backslashes to forward slashes, there's nothing + // else (e.g. spaces) that needs quoting. libtool would + // probably not handle that anyway, but this would break + // a more capable caller which also parses the output of "-v". + } else if (cur == '\\') { + // Convert backslashes to forward slashes. Quoted backslashes + // are doubled, so just output every other one. We don't really + // keep track of whether we're in a quoted context though. + if (last != '\\') { + buf[out++] = '/'; + } else { + // Last output char was a backslash converted into a + // forward slash. Ignore this one, but handle the next + // one in case there's more. + last = ' '; + } + } else { + buf[out++] = cur; + } + } else { + buf[out++] = cur; + } + + last = cur; + } + last_char = last; + fwrite(buf, 1, out, stderr); +} + +static int exec_filtered(const TCHAR **argv) { + for (int i = 0; argv[i]; i++) + argv[i] = escape(argv[i]); + int len = 1; + for (int i = 0; argv[i]; i++) + len += _tcslen(argv[i]) + 1; + TCHAR *cmdline = malloc(len * sizeof(*cmdline)); + int pos = 0; + for (int i = 0; argv[i]; i++) { + _tcscpy(&cmdline[pos], argv[i]); + pos += _tcslen(argv[i]); + cmdline[pos++] = ' '; + } + if (pos > 0) + pos--; + cmdline[pos] = '\0'; + + STARTUPINFO si = { 0 }; + PROCESS_INFORMATION pi = { 0 }; + HANDLE pipe_read = NULL, pipe_write = NULL; + SECURITY_ATTRIBUTES sa = { 0 }; + sa.nLength = sizeof(sa); + sa.bInheritHandle = TRUE; + CreatePipe(&pipe_read, &pipe_write, &sa, 0); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); + si.hStdError = pipe_write; + if (!CreateProcess(NULL, cmdline, NULL, NULL, /* bInheritHandles */ TRUE, + 0, NULL, NULL, &si, &pi)) { + DWORD err = GetLastError(); + TCHAR *errbuf; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &errbuf, 0, NULL); + _ftprintf(stderr, _T("Unable to execute: "TS": "TS"\n"), cmdline, errbuf); + LocalFree(errbuf); + CloseHandle(pipe_read); + CloseHandle(pipe_write); + free(cmdline); + return 1; + } + + CloseHandle(pipe_write); + char stderr_buf[8192]; + DWORD n; + while (ReadFile(pipe_read, stderr_buf, sizeof(stderr_buf), &n, NULL)) + filter_stderr(stderr_buf, n); + CloseHandle(pipe_read); + + WaitForSingleObject(pi.hProcess, INFINITE); + DWORD exit_code = 1; + GetExitCodeProcess(pi.hProcess, &exit_code); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + free(cmdline); + return exit_code; +} +#endif + +int _tmain(int argc, TCHAR* argv[]) { + const TCHAR *dir; + const TCHAR *target; + const TCHAR *exe; + split_argv(argv[0], &dir, NULL, &target, &exe); + if (!target) + target = _T(DEFAULT_TARGET); + TCHAR *arch = _tcsdup(target); + TCHAR *dash = _tcschr(arch, '-'); + if (dash) + *dash = '\0'; + TCHAR *target_os = _tcsrchr(target, '-'); + if (target_os) + target_os++; + + // Check if trying to compile Ada; if we try to do this, invoking clang + // would end up invoking -gcc with the same arguments, which ends + // up in an infinite recursion. + for (int i = 1; i < argc - 1; i++) { + if (!_tcscmp(argv[i], _T("-x")) && !_tcscmp(argv[i + 1], _T("ada"))) { + fprintf(stderr, "Ada is not supported\n"); + return 1; + } + } + + int max_arg = argc + 20; + const TCHAR **exec_argv = malloc((max_arg + 1) * sizeof(*exec_argv)); + int arg = 0; + if (getenv("CCACHE")) + exec_argv[arg++] = _T("ccache"); + exec_argv[arg++] = concat(dir, _T(CLANG)); + + // If changing this wrapper, change clang-target-wrapper.sh accordingly. + if (!_tcscmp(exe, _T("clang++")) || !_tcscmp(exe, _T("g++")) || !_tcscmp(exe, _T("c++"))) + exec_argv[arg++] = _T("--driver-mode=g++"); + + if (!_tcscmp(arch, _T("i686"))) { + // Dwarf is the default for i686. + } else if (!_tcscmp(arch, _T("x86_64"))) { + // SEH is the default for x86_64. + } else if (!_tcscmp(arch, _T("armv7"))) { + // Dwarf is the default for armv7. + } else if (!_tcscmp(arch, _T("aarch64"))) { + // SEH is the default for aarch64. + } + + if (target_os && !_tcscmp(target_os, _T("mingw32uwp"))) { + // the UWP target is for Windows 10 + exec_argv[arg++] = _T("-D_WIN32_WINNT=0x0A00"); + exec_argv[arg++] = _T("-DWINVER=0x0A00"); + // the UWP target can only use Windows Store APIs + exec_argv[arg++] = _T("-DWINAPI_FAMILY=WINAPI_FAMILY_APP"); + // the Windows Store API only supports Windows Unicode (some rare ANSI ones are available) + exec_argv[arg++] = _T("-DUNICODE"); + // add the minimum runtime to use for UWP targets + exec_argv[arg++] = _T("-Wl,-lmincore"); + // This requires that the default crt is ucrt. + exec_argv[arg++] = _T("-Wl,-lvcruntime140_app"); + } + + exec_argv[arg++] = _T("-target"); + exec_argv[arg++] = target; + exec_argv[arg++] = _T("-rtlib=compiler-rt"); + exec_argv[arg++] = _T("-stdlib=libc++"); + exec_argv[arg++] = _T("-fuse-ld=lld"); + exec_argv[arg++] = _T("-fuse-cxa-atexit"); + exec_argv[arg++] = _T("-Qunused-arguments"); + + for (int i = 1; i < argc; i++) + exec_argv[arg++] = argv[i]; + + exec_argv[arg] = NULL; + if (arg > max_arg) { + fprintf(stderr, "Too many options added\n"); + abort(); + } + +#ifdef _WIN32 + // If the command line contains the "-v" argument, filter the stderr + // output to rewrite paths from backslash to forward slash form. + // libtool parses the output of "-v" and can't handle the backslash + // form of paths. A proper upstream solution has been discussed at + // https://reviews.llvm.org/D53066 but hasn't been finished yet. + for (int i = 1; i < argc; i++) + if (!_tcscmp(argv[i], _T("-v"))) + return exec_filtered(exec_argv); +#endif + + return run_final(exec_argv[0], exec_argv); +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/clang-target-wrapper.sh b/source/tool/cross-build/llvm-mingw/scripts/wrappers/clang-target-wrapper.sh new file mode 100644 index 000000000..f6b6ea968 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/clang-target-wrapper.sh @@ -0,0 +1,74 @@ +#!/bin/sh +DIR="$(cd "$(dirname "$0")" && pwd)" +BASENAME="$(basename "$0")" +TARGET="${BASENAME%-*}" +EXE="${BASENAME##*-}" +DEFAULT_TARGET=x86_64-w64-mingw32 +if [ "$TARGET" = "$BASENAME" ]; then + TARGET=$DEFAULT_TARGET +fi +ARCH="${TARGET%%-*}" +TARGET_OS="${TARGET##*-}" + +# Check if trying to compile Ada; if we try to do this, invoking clang +# would end up invoking -gcc with the same arguments, which ends +# up in an infinite recursion. +case "$*" in +*-x\ ada*) + echo "Ada is not supported" >&2 + exit 1 + ;; +*) + ;; +esac + +# Allow setting e.g. CCACHE=1 to wrap all building in ccache. +if [ -n "$CCACHE" ]; then + CCACHE=ccache +fi + +# If changing this wrapper, change clang-target-wrapper.c accordingly. +CLANG="$DIR/clang" +FLAGS="" +case $EXE in +clang++|g++|c++) + FLAGS="$FLAGS --driver-mode=g++" + ;; +esac +case $ARCH in +i686) + # Dwarf is the default for i686. + ;; +x86_64) + # SEH is the default for x86_64. + ;; +armv7) + # Dwarf is the default for armv7. + ;; +aarch64) + # SEH is the default for aarch64. + ;; +esac +case $TARGET_OS in +mingw32uwp) + # the UWP target is for Windows 10 + FLAGS="$FLAGS -D_WIN32_WINNT=0x0A00 -DWINVER=0x0A00" + # the UWP target can only use Windows Store APIs + FLAGS="$FLAGS -DWINAPI_FAMILY=WINAPI_FAMILY_APP" + # the Windows Store API only supports Windows Unicode (some rare ANSI ones are available) + FLAGS="$FLAGS -DUNICODE" + # add the minimum runtime to use for UWP targets + FLAGS="$FLAGS -Wl,-lmincore" + # This requires that the default crt is ucrt. + FLAGS="$FLAGS -Wl,-lvcruntime140_app" + ;; +esac + +FLAGS="$FLAGS -target $TARGET" +FLAGS="$FLAGS -rtlib=compiler-rt" +FLAGS="$FLAGS -stdlib=libc++" +FLAGS="$FLAGS -fuse-ld=lld" +FLAGS="$FLAGS -fuse-cxa-atexit" +FLAGS="$FLAGS -Qunused-arguments" + +$CCACHE $CLANG $FLAGS "$@" diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/dlltool-wrapper.sh b/source/tool/cross-build/llvm-mingw/scripts/wrappers/dlltool-wrapper.sh new file mode 100644 index 000000000..7ead20249 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/dlltool-wrapper.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +export PATH="$DIR":"$PATH" + +BASENAME="$(basename "$0")" +TARGET="${BASENAME%-*}" +DEFAULT_TARGET=x86_64-w64-mingw32 +if [ "$TARGET" = "$BASENAME" ]; then + TARGET=$DEFAULT_TARGET +fi +ARCH="${TARGET%%-*}" +case $ARCH in +i686) M=i386 ;; +x86_64) M=i386:x86-64 ;; +armv7) M=arm ;; +aarch64) M=arm64 ;; +esac +llvm-dlltool -m $M "$@" diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/ld-wrapper.sh b/source/tool/cross-build/llvm-mingw/scripts/wrappers/ld-wrapper.sh new file mode 100644 index 000000000..8470ec0f9 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/ld-wrapper.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +export PATH="$DIR":"$PATH" + +BASENAME="$(basename "$0")" +TARGET="${BASENAME%-*}" +DEFAULT_TARGET=x86_64-w64-mingw32 +if [ "$TARGET" = "$BASENAME" ]; then + TARGET=$DEFAULT_TARGET +fi +ARCH="${TARGET%%-*}" +TARGET_OS="${TARGET##*-}" +case $ARCH in +i686) M=i386pe ;; +x86_64) M=i386pep ;; +armv7) M=thumb2pe ;; +aarch64) M=arm64pe ;; +esac +FLAGS="-m $M" +case $TARGET_OS in +mingw32uwp) + FLAGS="$FLAGS -lmincore -lvcruntime140_app" + ;; +esac +ld.lld $FLAGS "$@" diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/llvm-wrapper.c b/source/tool/cross-build/llvm-mingw/scripts/wrappers/llvm-wrapper.c new file mode 100644 index 000000000..de7918af1 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/llvm-wrapper.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "native-wrapper.h" + +int _tmain(int argc, TCHAR* argv[]) { + const TCHAR *dir; + const TCHAR *exe; + split_argv(argv[0], &dir, NULL, NULL, &exe); + TCHAR *exe_path = concat(dir, concat(_T("llvm-"), exe)); + + return run_final(exe_path, (const TCHAR *const *) argv); +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/native-wrapper.h b/source/tool/cross-build/llvm-mingw/scripts/wrappers/native-wrapper.h new file mode 100644 index 000000000..a9c2bc593 --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/native-wrapper.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2018 Martin Storsjo + * + * This file is part of llvm-mingw. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef UNICODE +#define _UNICODE +#endif + +#include +#include +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#define EXECVP_CAST +#else +#include +typedef char TCHAR; +#define _T(x) x +#define _tcsrchr strrchr +#define _tcschr strchr +#define _tcsdup strdup +#define _tcscpy strcpy +#define _tcslen strlen +#define _tcscmp strcmp +#define _tcsncmp strncmp +#define _tperror perror +#define _texecvp execvp +#define _tmain main +#define _ftprintf fprintf +#define _vftprintf vfprintf +#define _tunlink unlink +#define EXECVP_CAST (char **) +#endif + +#ifdef _UNICODE +#define TS "%ls" +#else +#define TS "%s" +#endif + +#ifdef _WIN32 +static TCHAR *escape(const TCHAR *str) { + TCHAR *out = malloc((_tcslen(str) * 2 + 3) * sizeof(*out)); + TCHAR *ptr = out; + int i; + *ptr++ = '"'; + for (i = 0; str[i]; i++) { + if (str[i] == '"') { + int j = i - 1; + // Before all double quotes, backslashes need to be escaped, but + // not elsewhere. + while (j >= 0 && str[j--] == '\\') + *ptr++ = '\\'; + // Escape the next double quote. + *ptr++ = '\\'; + } + *ptr++ = str[i]; + } + // Any final backslashes, before the quote around the whole argument, + // need to be doubled. + int j = i - 1; + while (j >= 0 && str[j--] == '\\') + *ptr++ = '\\'; + *ptr++ = '"'; + *ptr++ = '\0'; + return out; +} + +static int _tspawnvp_escape(int mode, const TCHAR *filename, const TCHAR * const *argv) { + int num_args = 0; + while (argv[num_args]) + num_args++; + const TCHAR **escaped_argv = malloc((num_args + 1) * sizeof(*escaped_argv)); + for (int i = 0; argv[i]; i++) + escaped_argv[i] = escape(argv[i]); + escaped_argv[num_args] = NULL; + return _tspawnvp(mode, filename, escaped_argv); +} +#endif + +static TCHAR *concat(const TCHAR *prefix, const TCHAR *suffix) { + int prefixlen = _tcslen(prefix); + int suffixlen = _tcslen(suffix); + TCHAR *buf = malloc((prefixlen + suffixlen + 1) * sizeof(*buf)); + _tcscpy(buf, prefix); + _tcscpy(buf + prefixlen, suffix); + return buf; +} + +static TCHAR *_tcsrchrs(const TCHAR *str, TCHAR char1, TCHAR char2) { + TCHAR *ptr1 = _tcsrchr(str, char1); + TCHAR *ptr2 = _tcsrchr(str, char2); + if (!ptr1) + return ptr2; + if (!ptr2) + return ptr1; + if (ptr1 < ptr2) + return ptr2; + return ptr1; +} + +static void split_argv(const TCHAR *argv0, const TCHAR **dir_ptr, const TCHAR **basename_ptr, const TCHAR **target_ptr, const TCHAR **exe_ptr) { + const TCHAR *sep = _tcsrchrs(argv0, '/', '\\'); + TCHAR *dir = _tcsdup(_T("")); + const TCHAR *basename = argv0; + if (sep) { + dir = _tcsdup(argv0); + dir[sep + 1 - argv0] = '\0'; + basename = sep + 1; + } +#ifdef _WIN32 + TCHAR module_path[8192]; + GetModuleFileName(NULL, module_path, sizeof(module_path)/sizeof(module_path[0])); + TCHAR *sep2 = _tcsrchr(module_path, '\\'); + if (sep2) { + sep2[1] = '\0'; + dir = _tcsdup(module_path); + } +#endif + basename = _tcsdup(basename); + TCHAR *period = _tcschr(basename, '.'); + if (period) + *period = '\0'; + TCHAR *target = _tcsdup(basename); + TCHAR *dash = _tcsrchr(target, '-'); + const TCHAR *exe = basename; + if (dash) { + *dash = '\0'; + exe = dash + 1; + } else { + target = NULL; + } + + if (dir_ptr) + *dir_ptr = dir; + if (basename_ptr) + *basename_ptr = basename; + if (target_ptr) + *target_ptr = target; + if (exe_ptr) + *exe_ptr = exe; +} + +static int run_final(const TCHAR *executable, const TCHAR *const *argv) { +#ifdef _WIN32 + int ret = _tspawnvp_escape(_P_WAIT, executable, argv); + if (ret == -1) { + _tperror(executable); + return 1; + } + return ret; +#else + // On unix, exec() runs the target executable within this same process, + // making the return code propagate implicitly. + // Windows doesn't have such mechanisms, and the exec() family of functions + // makes the calling process exit immediately and always returning + // a zero return. This doesn't work for our case where we need the + // return code propagated. + _texecvp(executable, EXECVP_CAST argv); + + _tperror(executable); + return 1; +#endif +} diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/objdump-wrapper.sh b/source/tool/cross-build/llvm-mingw/scripts/wrappers/objdump-wrapper.sh new file mode 100644 index 000000000..1b5c0029b --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/objdump-wrapper.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +DIR="$(cd "$(dirname "$0")" && pwd)" +export PATH="$DIR":"$PATH" + +if [ "$1" = "-f" ]; then + # libtool can try to run objdump -f and wants to see certain strings in + # the output, to accept it being a windows (import) library + llvm-readobj $2 | while read -r line; do + case $line in + File:*) + file=$(echo $line | awk '{print $2}') + ;; + Format:*) + format=$(echo $line | awk '{print $2}') + case $format in + COFF-i386) + format=pe-i386 + ;; + COFF-x86-64) + format=pe-x86-64 + ;; + COFF-ARM*) + # This is wrong; modern COFF armv7 isn't pe-arm-wince, and + # arm64 definitely isn't, but libtool wants to see this + # string (or some of the others) in order to accept it. + format=pe-arm-wince + ;; + esac + echo $file: file format $format + ;; + esac + done +else + llvm-objdump "$@" +fi diff --git a/source/tool/cross-build/llvm-mingw/scripts/wrappers/windres-wrapper.c b/source/tool/cross-build/llvm-mingw/scripts/wrappers/windres-wrapper.c new file mode 100644 index 000000000..36222893e --- /dev/null +++ b/source/tool/cross-build/llvm-mingw/scripts/wrappers/windres-wrapper.c @@ -0,0 +1,392 @@ +/* + * author: Josh de Kock , Martin Storsjo + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to + */ + +#include "native-wrapper.h" + +#ifndef DEFAULT_TARGET +#define DEFAULT_TARGET "x86_64-w64-mingw32" +#endif + +#include + +#ifdef _WIN32 +#else +#define _tspawnvp_escape _spawnvp + +#include +#include + +#define _P_WAIT 0 +static int _spawnvp(int mode, const char *filename, const char * const *argv) { + pid_t pid; + if (!(pid = fork())) { + execvp(filename, (char **) argv); + perror(filename); + exit(1); + } + int stat = 0; + if (waitpid(pid, &stat, 0) == -1) + return -1; + if (WIFEXITED(stat)) + return WEXITSTATUS(stat); + errno = EIO; + return -1; +} +#endif + +// GNU binutils windres seem to require an extra level of escaping of +// -D options to the preprocessor, which we need to undo here. +// For defines that produce quoted strings, this windres frontend is +// called with parameters like this: -DSTRING=\\\"1.2.3\\\" +static const TCHAR *unescape_cpp(const TCHAR *str) { + TCHAR *out = _tcsdup(str); + int len = _tcslen(str); + int i, outpos = 0; + for (i = 0; i < len - 1; i++) { + if (str[i] == '\\' && str[i + 1] == '"') + continue; + out[outpos++] = str[i]; + } + while (i < len) + out[outpos++] = str[i++]; + out[outpos++] = '\0'; + return out; +} + +static void print_version(void) { + printf( +"version: LLVM windres (GNU windres compatible) 0.1\n" + ); + exit(1); +} + +static void print_help(void) { + printf( +"usage: llvm-windres